From b6326c4c849f2436036f71c09efb295516afd9cc Mon Sep 17 00:00:00 2001 From: AntonioTorres-SrvUbuntuLocal Date: Sun, 13 Dec 2020 20:58:06 +0000 Subject: [PATCH] Creamos Proyecto y VirtualEnv --- .venv/bin/Activate.ps1 | 241 + .venv/bin/activate | 76 + .venv/bin/activate.csh | 37 + .venv/bin/activate.fish | 75 + .venv/bin/easy_install | 8 + .venv/bin/easy_install-3.8 | 8 + .venv/bin/epylint | 8 + .venv/bin/iptest | 8 + .venv/bin/iptest3 | 8 + .venv/bin/ipython | 8 + .venv/bin/ipython3 | 8 + .venv/bin/isort | 8 + .venv/bin/jupyter | 8 + .venv/bin/jupyter-kernel | 8 + .venv/bin/jupyter-kernelspec | 8 + .venv/bin/jupyter-migrate | 8 + .venv/bin/jupyter-run | 8 + .venv/bin/jupyter-troubleshoot | 8 + .venv/bin/pip | 8 + .venv/bin/pip3 | 8 + .venv/bin/pip3.8 | 8 + .venv/bin/pygmentize | 8 + .venv/bin/pylint | 8 + .venv/bin/pyreverse | 8 + .venv/bin/python | 1 + .venv/bin/python3 | 1 + .venv/bin/symilar | 8 + .../site-packages/IPython/__init__.py | 152 + .../site-packages/IPython/__main__.py | 14 + .../__pycache__/__init__.cpython-38.pyc | Bin 0 -> 4659 bytes .../__pycache__/__main__.cpython-38.pyc | Bin 0 -> 249 bytes .../IPython/__pycache__/config.cpython-38.pyc | Bin 0 -> 575 bytes .../__pycache__/conftest.cpython-38.pyc | Bin 0 -> 1919 bytes .../__pycache__/consoleapp.cpython-38.pyc | Bin 0 -> 487 bytes .../__pycache__/display.cpython-38.pyc | Bin 0 -> 268 bytes .../__pycache__/frontend.cpython-38.pyc | Bin 0 -> 1003 bytes .../IPython/__pycache__/html.cpython-38.pyc | Bin 0 -> 821 bytes .../__pycache__/nbconvert.cpython-38.pyc | Bin 0 -> 582 bytes .../__pycache__/nbformat.cpython-38.pyc | Bin 0 -> 576 bytes .../__pycache__/parallel.cpython-38.pyc | Bin 0 -> 582 bytes .../IPython/__pycache__/paths.cpython-38.pyc | Bin 0 -> 3784 bytes .../IPython/__pycache__/qt.cpython-38.pyc | Bin 0 -> 636 bytes .../python3.8/site-packages/IPython/config.py | 19 + .../site-packages/IPython/conftest.py | 69 + .../site-packages/IPython/consoleapp.py | 12 + .../site-packages/IPython/core/__init__.py | 0 .../core/__pycache__/__init__.cpython-38.pyc | Bin 0 -> 148 bytes .../core/__pycache__/alias.cpython-38.pyc | Bin 0 -> 7058 bytes .../__pycache__/application.cpython-38.pyc | Bin 0 -> 14128 bytes .../__pycache__/async_helpers.cpython-38.pyc | Bin 0 -> 5451 bytes .../core/__pycache__/autocall.cpython-38.pyc | Bin 0 -> 2081 bytes .../__pycache__/builtin_trap.cpython-38.pyc | Bin 0 -> 2854 bytes .../__pycache__/compilerop.cpython-38.pyc | Bin 0 -> 3973 bytes .../core/__pycache__/completer.cpython-38.pyc | Bin 0 -> 59615 bytes .../__pycache__/completerlib.cpython-38.pyc | Bin 0 -> 8881 bytes .../__pycache__/crashhandler.cpython-38.pyc | Bin 0 -> 6419 bytes .../core/__pycache__/debugger.cpython-38.pyc | Bin 0 -> 21885 bytes .../core/__pycache__/display.cpython-38.pyc | Bin 0 -> 47961 bytes .../__pycache__/display_trap.cpython-38.pyc | Bin 0 -> 1716 bytes .../__pycache__/displayhook.cpython-38.pyc | Bin 0 -> 9505 bytes .../__pycache__/displaypub.cpython-38.pyc | Bin 0 -> 5045 bytes .../core/__pycache__/error.cpython-38.pyc | Bin 0 -> 1664 bytes .../core/__pycache__/events.cpython-38.pyc | Bin 0 -> 5596 bytes .../core/__pycache__/excolors.cpython-38.pyc | Bin 0 -> 2665 bytes .../__pycache__/extensions.cpython-38.pyc | Bin 0 -> 5834 bytes .../__pycache__/formatters.cpython-38.pyc | Bin 0 -> 30538 bytes .../__pycache__/getipython.cpython-38.pyc | Bin 0 -> 567 bytes .../core/__pycache__/history.cpython-38.pyc | Bin 0 -> 27816 bytes .../__pycache__/historyapp.cpython-38.pyc | Bin 0 -> 5055 bytes .../core/__pycache__/hooks.cpython-38.pyc | Bin 0 -> 5740 bytes .../__pycache__/inputsplitter.cpython-38.pyc | Bin 0 -> 19244 bytes .../inputtransformer.cpython-38.pyc | Bin 0 -> 15699 bytes .../inputtransformer2.cpython-38.pyc | Bin 0 -> 22027 bytes .../interactiveshell.cpython-38.pyc | Bin 0 -> 105154 bytes .../__pycache__/latex_symbols.cpython-38.pyc | Bin 0 -> 29400 bytes .../core/__pycache__/logger.cpython-38.pyc | Bin 0 -> 5308 bytes .../core/__pycache__/macro.cpython-38.pyc | Bin 0 -> 1757 bytes .../core/__pycache__/magic.cpython-38.pyc | Bin 0 -> 19887 bytes .../magic_arguments.cpython-38.pyc | Bin 0 -> 8576 bytes .../core/__pycache__/oinspect.cpython-38.pyc | Bin 0 -> 24630 bytes .../core/__pycache__/page.cpython-38.pyc | Bin 0 -> 8106 bytes .../core/__pycache__/payload.cpython-38.pyc | Bin 0 -> 1410 bytes .../__pycache__/payloadpage.cpython-38.pyc | Bin 0 -> 1411 bytes .../core/__pycache__/prefilter.cpython-38.pyc | Bin 0 -> 20258 bytes .../__pycache__/profileapp.cpython-38.pyc | Bin 0 -> 9530 bytes .../__pycache__/profiledir.cpython-38.pyc | Bin 0 -> 7387 bytes .../core/__pycache__/prompts.cpython-38.pyc | Bin 0 -> 1129 bytes .../__pycache__/pylabtools.cpython-38.pyc | Bin 0 -> 9966 bytes .../core/__pycache__/release.cpython-38.pyc | Bin 0 -> 3094 bytes .../core/__pycache__/shellapp.cpython-38.pyc | Bin 0 -> 14461 bytes .../__pycache__/splitinput.cpython-38.pyc | Bin 0 -> 3568 bytes .../core/__pycache__/ultratb.cpython-38.pyc | Bin 0 -> 38533 bytes .../core/__pycache__/usage.cpython-38.pyc | Bin 0 -> 13257 bytes .../site-packages/IPython/core/alias.py | 258 + .../site-packages/IPython/core/application.py | 462 ++ .../IPython/core/async_helpers.py | 173 + .../site-packages/IPython/core/autocall.py | 70 + .../IPython/core/builtin_trap.py | 86 + .../site-packages/IPython/core/compilerop.py | 160 + .../site-packages/IPython/core/completer.py | 2092 ++++++ .../IPython/core/completerlib.py | 354 + .../IPython/core/crashhandler.py | 228 + .../site-packages/IPython/core/debugger.py | 833 +++ .../site-packages/IPython/core/display.py | 1527 +++++ .../IPython/core/display_trap.py | 70 + .../site-packages/IPython/core/displayhook.py | 325 + .../site-packages/IPython/core/displaypub.py | 138 + .../site-packages/IPython/core/error.py | 60 + .../site-packages/IPython/core/events.py | 161 + .../site-packages/IPython/core/excolors.py | 184 + .../site-packages/IPython/core/extensions.py | 150 + .../site-packages/IPython/core/formatters.py | 1024 +++ .../site-packages/IPython/core/getipython.py | 24 + .../site-packages/IPython/core/history.py | 906 +++ .../site-packages/IPython/core/historyapp.py | 161 + .../site-packages/IPython/core/hooks.py | 190 + .../IPython/core/inputsplitter.py | 772 +++ .../IPython/core/inputtransformer.py | 536 ++ .../IPython/core/inputtransformer2.py | 726 +++ .../IPython/core/interactiveshell.py | 3800 +++++++++++ .../IPython/core/latex_symbols.py | 1301 ++++ .../site-packages/IPython/core/logger.py | 218 + .../site-packages/IPython/core/macro.py | 53 + .../site-packages/IPython/core/magic.py | 703 ++ .../IPython/core/magic_arguments.py | 278 + .../IPython/core/magics/__init__.py | 42 + .../__pycache__/__init__.cpython-38.pyc | Bin 0 -> 1375 bytes .../magics/__pycache__/auto.cpython-38.pyc | Bin 0 -> 3611 bytes .../magics/__pycache__/basic.cpython-38.pyc | Bin 0 -> 20589 bytes .../magics/__pycache__/code.cpython-38.pyc | Bin 0 -> 20624 bytes .../magics/__pycache__/config.cpython-38.pyc | Bin 0 -> 4977 bytes .../magics/__pycache__/display.cpython-38.pyc | Bin 0 -> 2590 bytes .../__pycache__/execution.cpython-38.pyc | Bin 0 -> 44411 bytes .../__pycache__/extension.cpython-38.pyc | Bin 0 -> 1936 bytes .../magics/__pycache__/history.cpython-38.pyc | Bin 0 -> 9129 bytes .../magics/__pycache__/logging.cpython-38.pyc | Bin 0 -> 5266 bytes .../__pycache__/namespace.cpython-38.pyc | Bin 0 -> 20279 bytes .../magics/__pycache__/osm.cpython-38.pyc | Bin 0 -> 24357 bytes .../__pycache__/packaging.cpython-38.pyc | Bin 0 -> 2933 bytes .../magics/__pycache__/pylab.cpython-38.pyc | Bin 0 -> 5545 bytes .../magics/__pycache__/script.cpython-38.pyc | Bin 0 -> 8378 bytes .../site-packages/IPython/core/magics/auto.py | 128 + .../IPython/core/magics/basic.py | 663 ++ .../site-packages/IPython/core/magics/code.py | 730 +++ .../IPython/core/magics/config.py | 158 + .../IPython/core/magics/display.py | 82 + .../IPython/core/magics/execution.py | 1512 +++++ .../IPython/core/magics/extension.py | 63 + .../IPython/core/magics/history.py | 318 + .../IPython/core/magics/logging.py | 195 + .../IPython/core/magics/namespace.py | 708 ++ .../site-packages/IPython/core/magics/osm.py | 857 +++ .../IPython/core/magics/packaging.py | 103 + .../IPython/core/magics/pylab.py | 166 + .../IPython/core/magics/script.py | 294 + .../site-packages/IPython/core/oinspect.py | 1031 +++ .../site-packages/IPython/core/page.py | 343 + .../site-packages/IPython/core/payload.py | 55 + .../site-packages/IPython/core/payloadpage.py | 52 + .../site-packages/IPython/core/prefilter.py | 709 ++ .../IPython/core/profile/README_STARTUP | 11 + .../site-packages/IPython/core/profileapp.py | 311 + .../site-packages/IPython/core/profiledir.py | 223 + .../site-packages/IPython/core/prompts.py | 21 + .../site-packages/IPython/core/pylabtools.py | 419 ++ .../site-packages/IPython/core/release.py | 119 + .../site-packages/IPython/core/shellapp.py | 469 ++ .../site-packages/IPython/core/splitinput.py | 137 + .../site-packages/IPython/core/tests/2x2.jpg | Bin 0 -> 331 bytes .../site-packages/IPython/core/tests/2x2.png | Bin 0 -> 71 bytes .../IPython/core/tests/__init__.py | 0 .../tests/__pycache__/__init__.cpython-38.pyc | Bin 0 -> 154 bytes .../tests/__pycache__/bad_all.cpython-38.pyc | Bin 0 -> 471 bytes .../tests/__pycache__/nonascii.cpython-38.pyc | Bin 0 -> 172 bytes .../__pycache__/nonascii2.cpython-38.pyc | Bin 0 -> 188 bytes .../__pycache__/print_argv.cpython-38.pyc | Bin 0 -> 209 bytes .../tests/__pycache__/refbug.cpython-38.pyc | Bin 0 -> 1220 bytes .../__pycache__/simpleerr.cpython-38.pyc | Bin 0 -> 935 bytes .../tests/__pycache__/tclass.cpython-38.pyc | Bin 0 -> 967 bytes .../__pycache__/test_alias.cpython-38.pyc | Bin 0 -> 2227 bytes .../test_application.cpython-38.pyc | Bin 0 -> 2157 bytes .../test_async_helpers.cpython-38.pyc | Bin 0 -> 8068 bytes .../__pycache__/test_autocall.cpython-38.pyc | Bin 0 -> 1763 bytes .../test_compilerop.cpython-38.pyc | Bin 0 -> 1751 bytes .../__pycache__/test_completer.cpython-38.pyc | Bin 0 -> 34479 bytes .../test_completerlib.cpython-38.pyc | Bin 0 -> 6116 bytes .../__pycache__/test_debugger.cpython-38.pyc | Bin 0 -> 8633 bytes .../__pycache__/test_display.cpython-38.pyc | Bin 0 -> 13415 bytes .../test_displayhook.cpython-38.pyc | Bin 0 -> 3329 bytes .../__pycache__/test_events.cpython-38.pyc | Bin 0 -> 4046 bytes .../__pycache__/test_extension.cpython-38.pyc | Bin 0 -> 2416 bytes .../test_formatters.cpython-38.pyc | Bin 0 -> 18746 bytes .../__pycache__/test_handlers.cpython-38.pyc | Bin 0 -> 2172 bytes .../__pycache__/test_history.cpython-38.pyc | Bin 0 -> 5572 bytes .../__pycache__/test_hooks.cpython-38.pyc | Bin 0 -> 2300 bytes .../__pycache__/test_imports.cpython-38.pyc | Bin 0 -> 2725 bytes .../test_inputsplitter.cpython-38.pyc | Bin 0 -> 21010 bytes .../test_inputtransformer.cpython-38.pyc | Bin 0 -> 11476 bytes .../test_inputtransformer2.cpython-38.pyc | Bin 0 -> 9721 bytes ...test_inputtransformer2_line.cpython-38.pyc | Bin 0 -> 2688 bytes .../test_interactiveshell.cpython-38.pyc | Bin 0 -> 39230 bytes .../__pycache__/test_iplib.cpython-38.pyc | Bin 0 -> 5720 bytes .../__pycache__/test_logger.cpython-38.pyc | Bin 0 -> 946 bytes .../__pycache__/test_magic.cpython-38.pyc | Bin 0 -> 39143 bytes .../test_magic_arguments.cpython-38.pyc | Bin 0 -> 3336 bytes .../test_magic_terminal.cpython-38.pyc | Bin 0 -> 6135 bytes .../__pycache__/test_oinspect.cpython-38.pyc | Bin 0 -> 15865 bytes .../__pycache__/test_page.cpython-38.pyc | Bin 0 -> 493 bytes .../__pycache__/test_paths.cpython-38.pyc | Bin 0 -> 6688 bytes .../__pycache__/test_prefilter.cpython-38.pyc | Bin 0 -> 3758 bytes .../__pycache__/test_profile.cpython-38.pyc | Bin 0 -> 4745 bytes .../__pycache__/test_prompts.cpython-38.pyc | Bin 0 -> 1646 bytes .../test_pylabtools.cpython-38.pyc | Bin 0 -> 8013 bytes .../tests/__pycache__/test_run.cpython-38.pyc | Bin 0 -> 20205 bytes .../__pycache__/test_shellapp.cpython-38.pyc | Bin 0 -> 1992 bytes .../test_splitinput.cpython-38.pyc | Bin 0 -> 1516 bytes .../__pycache__/test_ultratb.cpython-38.pyc | Bin 0 -> 14938 bytes .../IPython/core/tests/bad_all.py | 14 + .../__pycache__/daft_extension.cpython-38.pyc | Bin 0 -> 569 bytes .../tests/daft_extension/daft_extension.py | 12 + .../IPython/core/tests/nonascii.py | 4 + .../IPython/core/tests/nonascii2.py | 4 + .../IPython/core/tests/print_argv.py | 2 + .../IPython/core/tests/refbug.py | 46 + .../IPython/core/tests/simpleerr.py | 32 + .../IPython/core/tests/tclass.py | 34 + .../IPython/core/tests/test_alias.py | 65 + .../IPython/core/tests/test_application.py | 73 + .../IPython/core/tests/test_async_helpers.py | 316 + .../IPython/core/tests/test_autocall.py | 66 + .../IPython/core/tests/test_compilerop.py | 73 + .../IPython/core/tests/test_completer.py | 1111 ++++ .../IPython/core/tests/test_completerlib.py | 178 + .../IPython/core/tests/test_debugger.py | 326 + .../IPython/core/tests/test_display.py | 459 ++ .../IPython/core/tests/test_displayhook.py | 112 + .../IPython/core/tests/test_events.py | 92 + .../IPython/core/tests/test_extension.py | 96 + .../IPython/core/tests/test_formatters.py | 533 ++ .../IPython/core/tests/test_handlers.py | 94 + .../IPython/core/tests/test_history.py | 214 + .../IPython/core/tests/test_hooks.py | 80 + .../IPython/core/tests/test_imports.py | 52 + .../IPython/core/tests/test_inputsplitter.py | 639 ++ .../core/tests/test_inputtransformer.py | 495 ++ .../core/tests/test_inputtransformer2.py | 337 + .../core/tests/test_inputtransformer2_line.py | 126 + .../core/tests/test_interactiveshell.py | 1042 +++ .../IPython/core/tests/test_iplib.py | 246 + .../IPython/core/tests/test_logger.py | 30 + .../IPython/core/tests/test_magic.py | 1238 ++++ .../core/tests/test_magic_arguments.py | 118 + .../IPython/core/tests/test_magic_terminal.py | 192 + .../IPython/core/tests/test_oinspect.py | 447 ++ .../IPython/core/tests/test_page.py | 20 + .../IPython/core/tests/test_paths.py | 200 + .../IPython/core/tests/test_prefilter.py | 127 + .../IPython/core/tests/test_profile.py | 161 + .../IPython/core/tests/test_prompts.py | 30 + .../IPython/core/tests/test_pylabtools.py | 256 + .../IPython/core/tests/test_run.py | 607 ++ .../IPython/core/tests/test_shellapp.py | 60 + .../IPython/core/tests/test_splitinput.py | 38 + .../IPython/core/tests/test_ultratb.py | 470 ++ .../site-packages/IPython/core/ultratb.py | 1525 +++++ .../site-packages/IPython/core/usage.py | 341 + .../site-packages/IPython/display.py | 16 + .../IPython/extensions/__init__.py | 2 + .../__pycache__/__init__.cpython-38.pyc | Bin 0 -> 213 bytes .../__pycache__/autoreload.cpython-38.pyc | Bin 0 -> 14302 bytes .../__pycache__/cythonmagic.cpython-38.pyc | Bin 0 -> 627 bytes .../__pycache__/rmagic.cpython-38.pyc | Bin 0 -> 435 bytes .../__pycache__/storemagic.cpython-38.pyc | Bin 0 -> 6560 bytes .../__pycache__/sympyprinting.cpython-38.pyc | Bin 0 -> 943 bytes .../IPython/extensions/autoreload.py | 550 ++ .../IPython/extensions/cythonmagic.py | 21 + .../IPython/extensions/rmagic.py | 12 + .../IPython/extensions/storemagic.py | 233 + .../IPython/extensions/sympyprinting.py | 32 + .../IPython/extensions/tests/__init__.py | 0 .../tests/__pycache__/__init__.cpython-38.pyc | Bin 0 -> 160 bytes .../test_autoreload.cpython-38.pyc | Bin 0 -> 11432 bytes .../test_storemagic.cpython-38.pyc | Bin 0 -> 2072 bytes .../extensions/tests/test_autoreload.py | 447 ++ .../extensions/tests/test_storemagic.py | 66 + .../IPython/external/__init__.py | 5 + .../__pycache__/__init__.cpython-38.pyc | Bin 0 -> 248 bytes .../__pycache__/mathjax.cpython-38.pyc | Bin 0 -> 456 bytes .../__pycache__/qt_for_kernel.cpython-38.pyc | Bin 0 -> 2406 bytes .../__pycache__/qt_loaders.cpython-38.pyc | Bin 0 -> 8330 bytes .../IPython/external/decorators/__init__.py | 8 + .../__pycache__/__init__.cpython-38.pyc | Bin 0 -> 401 bytes .../__pycache__/_decorators.cpython-38.pyc | Bin 0 -> 4565 bytes .../_numpy_testing_noseclasses.cpython-38.pyc | Bin 0 -> 1691 bytes .../external/decorators/_decorators.py | 143 + .../decorators/_numpy_testing_noseclasses.py | 41 + .../site-packages/IPython/external/mathjax.py | 13 + .../IPython/external/qt_for_kernel.py | 95 + .../IPython/external/qt_loaders.py | 329 + .../site-packages/IPython/frontend.py | 29 + .../python3.8/site-packages/IPython/html.py | 28 + .../site-packages/IPython/kernel/__init__.py | 35 + .../site-packages/IPython/kernel/__main__.py | 3 + .../__pycache__/__init__.cpython-38.pyc | Bin 0 -> 992 bytes .../__pycache__/__main__.cpython-38.pyc | Bin 0 -> 259 bytes .../kernel/__pycache__/adapter.cpython-38.pyc | Bin 0 -> 188 bytes .../__pycache__/channels.cpython-38.pyc | Bin 0 -> 190 bytes .../__pycache__/channelsabc.cpython-38.pyc | Bin 0 -> 196 bytes .../kernel/__pycache__/client.cpython-38.pyc | Bin 0 -> 186 bytes .../__pycache__/clientabc.cpython-38.pyc | Bin 0 -> 192 bytes .../kernel/__pycache__/connect.cpython-38.pyc | Bin 0 -> 217 bytes .../__pycache__/kernelspec.cpython-38.pyc | Bin 0 -> 194 bytes .../__pycache__/kernelspecapp.cpython-38.pyc | Bin 0 -> 200 bytes .../__pycache__/launcher.cpython-38.pyc | Bin 0 -> 190 bytes .../kernel/__pycache__/manager.cpython-38.pyc | Bin 0 -> 188 bytes .../__pycache__/managerabc.cpython-38.pyc | Bin 0 -> 194 bytes .../multikernelmanager.cpython-38.pyc | Bin 0 -> 210 bytes .../__pycache__/restarter.cpython-38.pyc | Bin 0 -> 192 bytes .../__pycache__/threaded.cpython-38.pyc | Bin 0 -> 190 bytes .../site-packages/IPython/kernel/adapter.py | 1 + .../site-packages/IPython/kernel/channels.py | 1 + .../IPython/kernel/channelsabc.py | 1 + .../site-packages/IPython/kernel/client.py | 1 + .../site-packages/IPython/kernel/clientabc.py | 1 + .../site-packages/IPython/kernel/connect.py | 2 + .../IPython/kernel/kernelspec.py | 1 + .../IPython/kernel/kernelspecapp.py | 1 + .../site-packages/IPython/kernel/launcher.py | 1 + .../site-packages/IPython/kernel/manager.py | 1 + .../IPython/kernel/managerabc.py | 1 + .../IPython/kernel/multikernelmanager.py | 1 + .../site-packages/IPython/kernel/restarter.py | 1 + .../site-packages/IPython/kernel/threaded.py | 1 + .../site-packages/IPython/lib/__init__.py | 21 + .../lib/__pycache__/__init__.cpython-38.pyc | Bin 0 -> 247 bytes .../__pycache__/backgroundjobs.cpython-38.pyc | Bin 0 -> 16020 bytes .../lib/__pycache__/clipboard.cpython-38.pyc | Bin 0 -> 2274 bytes .../lib/__pycache__/deepreload.cpython-38.pyc | Bin 0 -> 6600 bytes .../lib/__pycache__/demo.cpython-38.pyc | Bin 0 -> 21628 bytes .../lib/__pycache__/display.cpython-38.pyc | Bin 0 -> 21941 bytes .../__pycache__/editorhooks.cpython-38.pyc | Bin 0 -> 4038 bytes .../lib/__pycache__/guisupport.cpython-38.pyc | Bin 0 -> 5047 bytes .../lib/__pycache__/inputhook.cpython-38.pyc | Bin 0 -> 22464 bytes .../__pycache__/inputhookglut.cpython-38.pyc | Bin 0 -> 2741 bytes .../__pycache__/inputhookgtk.cpython-38.pyc | Bin 0 -> 639 bytes .../__pycache__/inputhookgtk3.cpython-38.pyc | Bin 0 -> 672 bytes .../inputhookpyglet.cpython-38.pyc | Bin 0 -> 1909 bytes .../__pycache__/inputhookqt4.cpython-38.pyc | Bin 0 -> 3526 bytes .../__pycache__/inputhookwx.cpython-38.pyc | Bin 0 -> 3929 bytes .../lib/__pycache__/kernel.cpython-38.pyc | Bin 0 -> 446 bytes .../lib/__pycache__/latextools.cpython-38.pyc | Bin 0 -> 6321 bytes .../lib/__pycache__/lexers.cpython-38.pyc | Bin 0 -> 12572 bytes .../lib/__pycache__/pretty.cpython-38.pyc | Bin 0 -> 24451 bytes .../lib/__pycache__/security.cpython-38.pyc | Bin 0 -> 2725 bytes .../IPython/lib/backgroundjobs.py | 491 ++ .../site-packages/IPython/lib/clipboard.py | 69 + .../site-packages/IPython/lib/deepreload.py | 341 + .../site-packages/IPython/lib/demo.py | 671 ++ .../site-packages/IPython/lib/display.py | 654 ++ .../site-packages/IPython/lib/editorhooks.py | 128 + .../site-packages/IPython/lib/guisupport.py | 155 + .../site-packages/IPython/lib/inputhook.py | 666 ++ .../IPython/lib/inputhookglut.py | 172 + .../site-packages/IPython/lib/inputhookgtk.py | 35 + .../IPython/lib/inputhookgtk3.py | 34 + .../IPython/lib/inputhookpyglet.py | 111 + .../site-packages/IPython/lib/inputhookqt4.py | 180 + .../site-packages/IPython/lib/inputhookwx.py | 167 + .../site-packages/IPython/lib/kernel.py | 13 + .../site-packages/IPython/lib/latextools.py | 220 + .../site-packages/IPython/lib/lexers.py | 532 ++ .../site-packages/IPython/lib/pretty.py | 873 +++ .../site-packages/IPython/lib/security.py | 114 + .../IPython/lib/tests/__init__.py | 0 .../tests/__pycache__/__init__.cpython-38.pyc | Bin 0 -> 153 bytes .../test_backgroundjobs.cpython-38.pyc | Bin 0 -> 1925 bytes .../__pycache__/test_clipboard.cpython-38.pyc | Bin 0 -> 642 bytes .../test_deepreload.cpython-38.pyc | Bin 0 -> 1080 bytes .../__pycache__/test_display.cpython-38.pyc | Bin 0 -> 10019 bytes .../test_editorhooks.cpython-38.pyc | Bin 0 -> 1205 bytes .../__pycache__/test_imports.cpython-38.pyc | Bin 0 -> 681 bytes .../test_latextools.cpython-38.pyc | Bin 0 -> 5791 bytes .../__pycache__/test_lexers.cpython-38.pyc | Bin 0 -> 2998 bytes .../__pycache__/test_pretty.cpython-38.pyc | Bin 0 -> 17144 bytes .../__pycache__/test_security.cpython-38.pyc | Bin 0 -> 1190 bytes .../site-packages/IPython/lib/tests/test.wav | Bin 0 -> 44144 bytes .../IPython/lib/tests/test_backgroundjobs.py | 88 + .../IPython/lib/tests/test_clipboard.py | 21 + .../IPython/lib/tests/test_deepreload.py | 34 + .../IPython/lib/tests/test_display.py | 266 + .../IPython/lib/tests/test_editorhooks.py | 34 + .../IPython/lib/tests/test_imports.py | 11 + .../IPython/lib/tests/test_latextools.py | 181 + .../IPython/lib/tests/test_lexers.py | 176 + .../IPython/lib/tests/test_pretty.py | 472 ++ .../IPython/lib/tests/test_security.py | 26 + .../site-packages/IPython/nbconvert.py | 19 + .../site-packages/IPython/nbformat.py | 19 + .../site-packages/IPython/parallel.py | 20 + .../python3.8/site-packages/IPython/paths.py | 119 + .../lib/python3.8/site-packages/IPython/qt.py | 24 + .../IPython/sphinxext/__init__.py | 0 .../__pycache__/__init__.cpython-38.pyc | Bin 0 -> 153 bytes .../custom_doctests.cpython-38.pyc | Bin 0 -> 3885 bytes ...python_console_highlighting.cpython-38.pyc | Bin 0 -> 674 bytes .../ipython_directive.cpython-38.pyc | Bin 0 -> 25965 bytes .../IPython/sphinxext/custom_doctests.py | 155 + .../sphinxext/ipython_console_highlighting.py | 28 + .../IPython/sphinxext/ipython_directive.py | 1251 ++++ .../IPython/terminal/__init__.py | 0 .../__pycache__/__init__.cpython-38.pyc | Bin 0 -> 152 bytes .../__pycache__/console.cpython-38.pyc | Bin 0 -> 622 bytes .../__pycache__/debugger.cpython-38.pyc | Bin 0 -> 5255 bytes .../terminal/__pycache__/embed.cpython-38.pyc | Bin 0 -> 11573 bytes .../interactiveshell.cpython-38.pyc | Bin 0 -> 19654 bytes .../terminal/__pycache__/ipapp.cpython-38.pyc | Bin 0 -> 11697 bytes .../__pycache__/magics.cpython-38.pyc | Bin 0 -> 7128 bytes .../__pycache__/prompts.cpython-38.pyc | Bin 0 -> 4209 bytes .../__pycache__/ptshell.cpython-38.pyc | Bin 0 -> 444 bytes .../__pycache__/ptutils.cpython-38.pyc | Bin 0 -> 5788 bytes .../__pycache__/shortcuts.cpython-38.pyc | Bin 0 -> 8008 bytes .../site-packages/IPython/terminal/console.py | 19 + .../IPython/terminal/debugger.py | 161 + .../site-packages/IPython/terminal/embed.py | 399 ++ .../IPython/terminal/interactiveshell.py | 646 ++ .../site-packages/IPython/terminal/ipapp.py | 380 ++ .../site-packages/IPython/terminal/magics.py | 203 + .../site-packages/IPython/terminal/prompts.py | 108 + .../terminal/pt_inputhooks/__init__.py | 50 + .../__pycache__/__init__.cpython-38.pyc | Bin 0 -> 1528 bytes .../__pycache__/asyncio.cpython-38.pyc | Bin 0 -> 1620 bytes .../__pycache__/glut.cpython-38.pyc | Bin 0 -> 2762 bytes .../__pycache__/gtk.cpython-38.pyc | Bin 0 -> 973 bytes .../__pycache__/gtk3.cpython-38.pyc | Bin 0 -> 620 bytes .../__pycache__/osx.cpython-38.pyc | Bin 0 -> 3185 bytes .../__pycache__/pyglet.cpython-38.pyc | Bin 0 -> 1475 bytes .../__pycache__/qt.cpython-38.pyc | Bin 0 -> 1385 bytes .../__pycache__/tk.cpython-38.pyc | Bin 0 -> 1962 bytes .../__pycache__/wx.cpython-38.pyc | Bin 0 -> 5571 bytes .../IPython/terminal/pt_inputhooks/asyncio.py | 64 + .../IPython/terminal/pt_inputhooks/glut.py | 140 + .../IPython/terminal/pt_inputhooks/gtk.py | 58 + .../IPython/terminal/pt_inputhooks/gtk3.py | 12 + .../IPython/terminal/pt_inputhooks/osx.py | 137 + .../IPython/terminal/pt_inputhooks/pyglet.py | 66 + .../IPython/terminal/pt_inputhooks/qt.py | 54 + .../IPython/terminal/pt_inputhooks/tk.py | 90 + .../IPython/terminal/pt_inputhooks/wx.py | 219 + .../site-packages/IPython/terminal/ptshell.py | 8 + .../site-packages/IPython/terminal/ptutils.py | 195 + .../IPython/terminal/shortcuts.py | 276 + .../IPython/terminal/tests/__init__.py | 0 .../tests/__pycache__/__init__.cpython-38.pyc | Bin 0 -> 158 bytes .../test_debug_magic.cpython-38.pyc | Bin 0 -> 1524 bytes .../__pycache__/test_embed.cpython-38.pyc | Bin 0 -> 3034 bytes .../__pycache__/test_help.cpython-38.pyc | Bin 0 -> 1249 bytes .../test_interactivshell.cpython-38.pyc | Bin 0 -> 8019 bytes .../terminal/tests/test_debug_magic.py | 78 + .../IPython/terminal/tests/test_embed.py | 136 + .../IPython/terminal/tests/test_help.py | 28 + .../terminal/tests/test_interactivshell.py | 193 + .../site-packages/IPython/testing/__init__.py | 49 + .../site-packages/IPython/testing/__main__.py | 3 + .../__pycache__/__init__.cpython-38.pyc | Bin 0 -> 906 bytes .../__pycache__/__main__.cpython-38.pyc | Bin 0 -> 253 bytes .../__pycache__/decorators.cpython-38.pyc | Bin 0 -> 11553 bytes .../__pycache__/globalipapp.cpython-38.pyc | Bin 0 -> 3463 bytes .../testing/__pycache__/iptest.cpython-38.pyc | Bin 0 -> 13216 bytes .../iptestcontroller.cpython-38.pyc | Bin 0 -> 14726 bytes .../__pycache__/ipunittest.cpython-38.pyc | Bin 0 -> 5133 bytes .../__pycache__/skipdoctest.cpython-38.pyc | Bin 0 -> 820 bytes .../testing/__pycache__/tools.cpython-38.pyc | Bin 0 -> 12680 bytes .../IPython/testing/decorators.py | 383 ++ .../IPython/testing/globalipapp.py | 137 + .../site-packages/IPython/testing/iptest.py | 460 ++ .../IPython/testing/iptestcontroller.py | 491 ++ .../IPython/testing/ipunittest.py | 178 + .../IPython/testing/plugin/README.txt | 34 + .../IPython/testing/plugin/__init__.py | 0 .../__pycache__/__init__.cpython-38.pyc | Bin 0 -> 158 bytes .../__pycache__/dtexample.cpython-38.pyc | Bin 0 -> 3378 bytes .../__pycache__/ipdoctest.cpython-38.pyc | Bin 0 -> 19288 bytes .../plugin/__pycache__/iptest.cpython-38.pyc | Bin 0 -> 708 bytes .../plugin/__pycache__/setup.cpython-38.pyc | Bin 0 -> 593 bytes .../__pycache__/show_refs.cpython-38.pyc | Bin 0 -> 707 bytes .../plugin/__pycache__/simple.cpython-38.pyc | Bin 0 -> 797 bytes .../__pycache__/simplevars.cpython-38.pyc | Bin 0 -> 195 bytes .../__pycache__/test_ipdoctest.cpython-38.pyc | Bin 0 -> 2083 bytes .../__pycache__/test_refs.cpython-38.pyc | Bin 0 -> 1280 bytes .../IPython/testing/plugin/dtexample.py | 157 + .../IPython/testing/plugin/ipdoctest.py | 761 +++ .../IPython/testing/plugin/iptest.py | 18 + .../IPython/testing/plugin/setup.py | 18 + .../IPython/testing/plugin/show_refs.py | 19 + .../IPython/testing/plugin/simple.py | 33 + .../IPython/testing/plugin/simplevars.py | 2 + .../IPython/testing/plugin/test_combo.txt | 36 + .../IPython/testing/plugin/test_example.txt | 24 + .../IPython/testing/plugin/test_exampleip.txt | 30 + .../IPython/testing/plugin/test_ipdoctest.py | 76 + .../IPython/testing/plugin/test_refs.py | 46 + .../IPython/testing/skipdoctest.py | 19 + .../IPython/testing/tests/__init__.py | 10 + .../tests/__pycache__/__init__.cpython-38.pyc | Bin 0 -> 194 bytes .../test_decorators.cpython-38.pyc | Bin 0 -> 4389 bytes .../test_ipunittest.cpython-38.pyc | Bin 0 -> 3296 bytes .../__pycache__/test_tools.cpython-38.pyc | Bin 0 -> 4022 bytes .../IPython/testing/tests/test_decorators.py | 164 + .../IPython/testing/tests/test_ipunittest.py | 131 + .../IPython/testing/tests/test_tools.py | 135 + .../site-packages/IPython/testing/tools.py | 471 ++ .../site-packages/IPython/utils/PyColorize.py | 331 + .../site-packages/IPython/utils/__init__.py | 0 .../__pycache__/PyColorize.cpython-38.pyc | Bin 0 -> 6079 bytes .../utils/__pycache__/__init__.cpython-38.pyc | Bin 0 -> 149 bytes .../__pycache__/_process_cli.cpython-38.pyc | Bin 0 -> 2336 bytes .../_process_common.cpython-38.pyc | Bin 0 -> 5519 bytes .../__pycache__/_process_posix.cpython-38.pyc | Bin 0 -> 4223 bytes .../__pycache__/_process_win32.cpython-38.pyc | Bin 0 -> 5808 bytes .../_process_win32_controller.cpython-38.pyc | Bin 0 -> 13074 bytes .../utils/__pycache__/_sysinfo.cpython-38.pyc | Bin 0 -> 169 bytes .../utils/__pycache__/capture.cpython-38.pyc | Bin 0 -> 5822 bytes .../__pycache__/colorable.cpython-38.pyc | Bin 0 -> 965 bytes .../__pycache__/coloransi.cpython-38.pyc | Bin 0 -> 6048 bytes .../utils/__pycache__/contexts.cpython-38.pyc | Bin 0 -> 2499 bytes .../__pycache__/daemonize.cpython-38.pyc | Bin 0 -> 385 bytes .../utils/__pycache__/data.cpython-38.pyc | Bin 0 -> 1169 bytes .../__pycache__/decorators.cpython-38.pyc | Bin 0 -> 1591 bytes .../utils/__pycache__/dir2.cpython-38.pyc | Bin 0 -> 2029 bytes .../utils/__pycache__/encoding.cpython-38.pyc | Bin 0 -> 1765 bytes .../utils/__pycache__/eventful.cpython-38.pyc | Bin 0 -> 310 bytes .../utils/__pycache__/frame.cpython-38.pyc | Bin 0 -> 2884 bytes .../utils/__pycache__/generics.cpython-38.pyc | Bin 0 -> 974 bytes .../__pycache__/importstring.cpython-38.pyc | Bin 0 -> 999 bytes .../utils/__pycache__/io.cpython-38.pyc | Bin 0 -> 7582 bytes .../utils/__pycache__/ipstruct.cpython-38.pyc | Bin 0 -> 10895 bytes .../utils/__pycache__/jsonutil.cpython-38.pyc | Bin 0 -> 320 bytes .../localinterfaces.cpython-38.pyc | Bin 0 -> 348 bytes .../utils/__pycache__/log.cpython-38.pyc | Bin 0 -> 290 bytes .../__pycache__/module_paths.cpython-38.pyc | Bin 0 -> 1327 bytes .../utils/__pycache__/openpy.cpython-38.pyc | Bin 0 -> 3348 bytes .../utils/__pycache__/path.cpython-38.pyc | Bin 0 -> 12752 bytes .../__pycache__/pickleutil.cpython-38.pyc | Bin 0 -> 318 bytes .../utils/__pycache__/process.cpython-38.pyc | Bin 0 -> 2065 bytes .../__pycache__/py3compat.cpython-38.pyc | Bin 0 -> 4912 bytes .../utils/__pycache__/sentinel.cpython-38.pyc | Bin 0 -> 710 bytes .../__pycache__/shimmodule.cpython-38.pyc | Bin 0 -> 3554 bytes .../__pycache__/signatures.cpython-38.pyc | Bin 0 -> 684 bytes .../__pycache__/strdispatch.cpython-38.pyc | Bin 0 -> 2293 bytes .../utils/__pycache__/sysinfo.cpython-38.pyc | Bin 0 -> 4431 bytes .../__pycache__/syspathcontext.cpython-38.pyc | Bin 0 -> 1831 bytes .../utils/__pycache__/tempdir.cpython-38.pyc | Bin 0 -> 2667 bytes .../utils/__pycache__/terminal.cpython-38.pyc | Bin 0 -> 3501 bytes .../utils/__pycache__/text.cpython-38.pyc | Bin 0 -> 23462 bytes .../utils/__pycache__/timing.cpython-38.pyc | Bin 0 -> 3487 bytes .../__pycache__/tokenutil.cpython-38.pyc | Bin 0 -> 2719 bytes .../__pycache__/traitlets.cpython-38.pyc | Bin 0 -> 315 bytes .../utils/__pycache__/tz.cpython-38.pyc | Bin 0 -> 1148 bytes .../__pycache__/ulinecache.cpython-38.pyc | Bin 0 -> 785 bytes .../utils/__pycache__/version.cpython-38.pyc | Bin 0 -> 727 bytes .../utils/__pycache__/wildcard.cpython-38.pyc | Bin 0 -> 3349 bytes .../IPython/utils/_process_cli.py | 78 + .../IPython/utils/_process_common.py | 212 + .../IPython/utils/_process_posix.py | 225 + .../IPython/utils/_process_win32.py | 205 + .../utils/_process_win32_controller.py | 573 ++ .../site-packages/IPython/utils/_sysinfo.py | 2 + .../site-packages/IPython/utils/capture.py | 170 + .../site-packages/IPython/utils/colorable.py | 25 + .../site-packages/IPython/utils/coloransi.py | 187 + .../site-packages/IPython/utils/contexts.py | 74 + .../site-packages/IPython/utils/daemonize.py | 4 + .../site-packages/IPython/utils/data.py | 30 + .../site-packages/IPython/utils/decorators.py | 58 + .../site-packages/IPython/utils/dir2.py | 84 + .../site-packages/IPython/utils/encoding.py | 71 + .../site-packages/IPython/utils/eventful.py | 6 + .../site-packages/IPython/utils/frame.py | 94 + .../site-packages/IPython/utils/generics.py | 30 + .../IPython/utils/importstring.py | 39 + .../site-packages/IPython/utils/io.py | 248 + .../site-packages/IPython/utils/ipstruct.py | 391 ++ .../site-packages/IPython/utils/jsonutil.py | 5 + .../IPython/utils/localinterfaces.py | 5 + .../site-packages/IPython/utils/log.py | 6 + .../IPython/utils/module_paths.py | 70 + .../site-packages/IPython/utils/openpy.py | 103 + .../site-packages/IPython/utils/path.py | 436 ++ .../site-packages/IPython/utils/pickleutil.py | 5 + .../site-packages/IPython/utils/process.py | 69 + .../site-packages/IPython/utils/py3compat.py | 191 + .../site-packages/IPython/utils/sentinel.py | 17 + .../site-packages/IPython/utils/shimmodule.py | 94 + .../site-packages/IPython/utils/signatures.py | 12 + .../IPython/utils/strdispatch.py | 68 + .../site-packages/IPython/utils/sysinfo.py | 166 + .../IPython/utils/syspathcontext.py | 62 + .../site-packages/IPython/utils/tempdir.py | 57 + .../site-packages/IPython/utils/terminal.py | 129 + .../IPython/utils/tests/__init__.py | 0 .../tests/__pycache__/__init__.cpython-38.pyc | Bin 0 -> 155 bytes .../__pycache__/test_capture.cpython-38.pyc | Bin 0 -> 4160 bytes .../test_decorators.cpython-38.pyc | Bin 0 -> 512 bytes .../__pycache__/test_dir2.cpython-38.pyc | Bin 0 -> 2711 bytes .../__pycache__/test_imports.cpython-38.pyc | Bin 0 -> 1082 bytes .../test_importstring.cpython-38.pyc | Bin 0 -> 997 bytes .../tests/__pycache__/test_io.cpython-38.pyc | Bin 0 -> 3226 bytes .../test_module_paths.cpython-38.pyc | Bin 0 -> 3126 bytes .../__pycache__/test_openpy.cpython-38.pyc | Bin 0 -> 1427 bytes .../__pycache__/test_path.cpython-38.pyc | Bin 0 -> 15774 bytes .../__pycache__/test_process.cpython-38.pyc | Bin 0 -> 6440 bytes .../test_pycolorize.cpython-38.pyc | Bin 0 -> 1741 bytes .../test_shimmodule.cpython-38.pyc | Bin 0 -> 645 bytes .../__pycache__/test_sysinfo.cpython-38.pyc | Bin 0 -> 546 bytes .../__pycache__/test_tempdir.cpython-38.pyc | Bin 0 -> 902 bytes .../__pycache__/test_text.cpython-38.pyc | Bin 0 -> 7914 bytes .../__pycache__/test_tokenutil.cpython-38.pyc | Bin 0 -> 3570 bytes .../__pycache__/test_wildcard.cpython-38.pyc | Bin 0 -> 3980 bytes .../IPython/utils/tests/test_capture.py | 159 + .../IPython/utils/tests/test_decorators.py | 10 + .../IPython/utils/tests/test_dir2.py | 58 + .../IPython/utils/tests/test_imports.py | 20 + .../IPython/utils/tests/test_importstring.py | 39 + .../IPython/utils/tests/test_io.py | 89 + .../IPython/utils/tests/test_module_paths.py | 114 + .../IPython/utils/tests/test_openpy.py | 39 + .../IPython/utils/tests/test_path.py | 492 ++ .../IPython/utils/tests/test_process.py | 195 + .../IPython/utils/tests/test_pycolorize.py | 78 + .../IPython/utils/tests/test_shimmodule.py | 13 + .../IPython/utils/tests/test_sysinfo.py | 17 + .../IPython/utils/tests/test_tempdir.py | 28 + .../IPython/utils/tests/test_text.py | 213 + .../IPython/utils/tests/test_tokenutil.py | 133 + .../IPython/utils/tests/test_wildcard.py | 143 + .../site-packages/IPython/utils/text.py | 772 +++ .../site-packages/IPython/utils/timing.py | 116 + .../site-packages/IPython/utils/tokenutil.py | 130 + .../site-packages/IPython/utils/traitlets.py | 6 + .../site-packages/IPython/utils/tz.py | 46 + .../site-packages/IPython/utils/ulinecache.py | 21 + .../site-packages/IPython/utils/version.py | 36 + .../site-packages/IPython/utils/wildcard.py | 111 + .../Pygments-2.7.3.dist-info/AUTHORS | 238 + .../Pygments-2.7.3.dist-info/INSTALLER | 1 + .../Pygments-2.7.3.dist-info/LICENSE | 25 + .../Pygments-2.7.3.dist-info/METADATA | 49 + .../Pygments-2.7.3.dist-info/RECORD | 481 ++ .../Pygments-2.7.3.dist-info/WHEEL | 5 + .../Pygments-2.7.3.dist-info/entry_points.txt | 3 + .../Pygments-2.7.3.dist-info/top_level.txt | 1 + .../__pycache__/decorator.cpython-38.pyc | Bin 0 -> 12845 bytes .../__pycache__/easy_install.cpython-38.pyc | Bin 0 -> 281 bytes .../ipykernel_launcher.cpython-38.pyc | Bin 0 -> 484 bytes .../__pycache__/jupyter.cpython-38.pyc | Bin 0 -> 269 bytes .../__pycache__/mccabe.cpython-38.pyc | Bin 0 -> 11251 bytes .../__pycache__/pickleshare.cpython-38.pyc | Bin 0 -> 10118 bytes .../__pycache__/six.cpython-38.pyc | Bin 0 -> 26875 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 0 -> 4433 bytes .../__pycache__/__pkginfo__.cpython-38.pyc | Bin 0 -> 1381 bytes .../astroid/__pycache__/_ast.cpython-38.pyc | Bin 0 -> 3061 bytes .../__pycache__/arguments.cpython-38.pyc | Bin 0 -> 7623 bytes .../__pycache__/as_string.cpython-38.pyc | Bin 0 -> 26051 bytes .../astroid/__pycache__/bases.cpython-38.pyc | Bin 0 -> 15894 bytes .../__pycache__/builder.cpython-38.pyc | Bin 0 -> 12859 bytes .../__pycache__/context.cpython-38.pyc | Bin 0 -> 4301 bytes .../__pycache__/decorators.cpython-38.pyc | Bin 0 -> 3555 bytes .../__pycache__/exceptions.cpython-38.pyc | Bin 0 -> 9165 bytes .../__pycache__/helpers.cpython-38.pyc | Bin 0 -> 7371 bytes .../__pycache__/inference.cpython-38.pyc | Bin 0 -> 22321 bytes .../__pycache__/manager.cpython-38.pyc | Bin 0 -> 9759 bytes .../astroid/__pycache__/mixins.cpython-38.pyc | Bin 0 -> 5845 bytes .../__pycache__/modutils.cpython-38.pyc | Bin 0 -> 17058 bytes .../__pycache__/node_classes.cpython-38.pyc | Bin 0 -> 115670 bytes .../astroid/__pycache__/nodes.cpython-38.pyc | Bin 0 -> 2053 bytes .../__pycache__/objects.cpython-38.pyc | Bin 0 -> 9673 bytes .../__pycache__/protocols.cpython-38.pyc | Bin 0 -> 16975 bytes .../__pycache__/raw_building.cpython-38.pyc | Bin 0 -> 11627 bytes .../__pycache__/rebuilder.cpython-38.pyc | Bin 0 -> 35531 bytes .../__pycache__/scoped_nodes.cpython-38.pyc | Bin 0 -> 69426 bytes .../__pycache__/test_utils.cpython-38.pyc | Bin 0 -> 2512 bytes .../__pycache__/transforms.cpython-38.pyc | Bin 0 -> 3412 bytes .../astroid/__pycache__/util.cpython-38.pyc | Bin 0 -> 5780 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 0 -> 1059 bytes .../__pycache__/brain_attrs.cpython-38.pyc | Bin 0 -> 1556 bytes .../__pycache__/brain_boto3.cpython-38.pyc | Bin 0 -> 887 bytes .../brain_builtin_inference.cpython-38.pyc | Bin 0 -> 20630 bytes .../brain_collections.cpython-38.pyc | Bin 0 -> 2485 bytes .../__pycache__/brain_crypt.cpython-38.pyc | Bin 0 -> 827 bytes .../__pycache__/brain_curses.cpython-38.pyc | Bin 0 -> 3343 bytes .../brain_dataclasses.cpython-38.pyc | Bin 0 -> 1259 bytes .../__pycache__/brain_dateutil.cpython-38.pyc | Bin 0 -> 661 bytes .../__pycache__/brain_fstrings.cpython-38.pyc | Bin 0 -> 1541 bytes .../brain_functools.cpython-38.pyc | Bin 0 -> 4637 bytes .../brain/__pycache__/brain_gi.cpython-38.pyc | Bin 0 -> 4397 bytes .../__pycache__/brain_hashlib.cpython-38.pyc | Bin 0 -> 1921 bytes .../__pycache__/brain_http.cpython-38.pyc | Bin 0 -> 10478 bytes .../brain/__pycache__/brain_io.cpython-38.pyc | Bin 0 -> 1293 bytes .../brain_mechanize.cpython-38.pyc | Bin 0 -> 695 bytes .../brain_multiprocessing.cpython-38.pyc | Bin 0 -> 2513 bytes .../brain_namedtuple_enum.cpython-38.pyc | Bin 0 -> 11644 bytes .../__pycache__/brain_nose.cpython-38.pyc | Bin 0 -> 2048 bytes ...rain_numpy_core_fromnumeric.cpython-38.pyc | Bin 0 -> 606 bytes ...in_numpy_core_function_base.cpython-38.pyc | Bin 0 -> 1000 bytes ...brain_numpy_core_multiarray.cpython-38.pyc | Bin 0 -> 3212 bytes .../brain_numpy_core_numeric.cpython-38.pyc | Bin 0 -> 1244 bytes ...ain_numpy_core_numerictypes.cpython-38.pyc | Bin 0 -> 7708 bytes .../brain_numpy_core_umath.cpython-38.pyc | Bin 0 -> 4350 bytes .../brain_numpy_ndarray.cpython-38.pyc | Bin 0 -> 8345 bytes .../brain_numpy_random_mtrand.cpython-38.pyc | Bin 0 -> 3214 bytes .../brain_numpy_utils.cpython-38.pyc | Bin 0 -> 1839 bytes .../brain_pkg_resources.cpython-38.pyc | Bin 0 -> 2164 bytes .../__pycache__/brain_pytest.cpython-38.pyc | Bin 0 -> 2136 bytes .../brain/__pycache__/brain_qt.cpython-38.pyc | Bin 0 -> 2074 bytes .../__pycache__/brain_random.cpython-38.pyc | Bin 0 -> 2164 bytes .../brain/__pycache__/brain_re.cpython-38.pyc | Bin 0 -> 1043 bytes .../brain_responses.cpython-38.pyc | Bin 0 -> 1748 bytes .../brain_scipy_signal.cpython-38.pyc | Bin 0 -> 2161 bytes .../__pycache__/brain_six.cpython-38.pyc | Bin 0 -> 5543 bytes .../__pycache__/brain_ssl.cpython-38.pyc | Bin 0 -> 3575 bytes .../brain_subprocess.cpython-38.pyc | Bin 0 -> 4171 bytes .../brain_threading.cpython-38.pyc | Bin 0 -> 722 bytes .../__pycache__/brain_typing.cpython-38.pyc | Bin 0 -> 2330 bytes .../__pycache__/brain_uuid.cpython-38.pyc | Bin 0 -> 612 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 0 -> 155 bytes .../__pycache__/dunder_lookup.cpython-38.pyc | Bin 0 -> 2110 bytes .../__pycache__/objectmodel.cpython-38.pyc | Bin 0 -> 26911 bytes .../astroid/interpreter/_import/__init__.py | 0 .../__pycache__/__init__.cpython-38.pyc | Bin 0 -> 163 bytes .../_import/__pycache__/spec.cpython-38.pyc | Bin 0 -> 9365 bytes .../_import/__pycache__/util.cpython-38.pyc | Bin 0 -> 383 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 + .../backcall-0.2.0.dist-info/INSTALLER | 1 + .../backcall-0.2.0.dist-info/LICENSE | 27 + .../backcall-0.2.0.dist-info/METADATA | 55 + .../backcall-0.2.0.dist-info/RECORD | 11 + .../backcall-0.2.0.dist-info/WHEEL | 5 + .../site-packages/backcall/__init__.py | 7 + .../__pycache__/__init__.cpython-38.pyc | Bin 0 -> 364 bytes .../__pycache__/_signatures.cpython-38.pyc | Bin 0 -> 17693 bytes .../__pycache__/backcall.cpython-38.pyc | Bin 0 -> 2683 bytes .../site-packages/backcall/_signatures.py | 819 +++ .../site-packages/backcall/backcall.py | 109 + .../site-packages/dateutil/__init__.py | 8 + .../__pycache__/__init__.cpython-38.pyc | Bin 0 -> 349 bytes .../__pycache__/_common.cpython-38.pyc | Bin 0 -> 1395 bytes .../__pycache__/_version.cpython-38.pyc | Bin 0 -> 161 bytes .../__pycache__/easter.cpython-38.pyc | Bin 0 -> 2166 bytes .../__pycache__/relativedelta.cpython-38.pyc | Bin 0 -> 14873 bytes .../dateutil/__pycache__/rrule.cpython-38.pyc | Bin 0 -> 43478 bytes .../dateutil/__pycache__/tzwin.cpython-38.pyc | Bin 0 -> 164 bytes .../dateutil/__pycache__/utils.cpython-38.pyc | Bin 0 -> 2226 bytes .../site-packages/dateutil/_common.py | 43 + .../site-packages/dateutil/_version.py | 4 + .../site-packages/dateutil/easter.py | 89 + .../site-packages/dateutil/parser/__init__.py | 61 + .../__pycache__/__init__.cpython-38.pyc | Bin 0 -> 2047 bytes .../parser/__pycache__/_parser.cpython-38.pyc | Bin 0 -> 40422 bytes .../__pycache__/isoparser.cpython-38.pyc | Bin 0 -> 11154 bytes .../site-packages/dateutil/parser/_parser.py | 1609 +++++ .../dateutil/parser/isoparser.py | 411 ++ .../site-packages/dateutil/relativedelta.py | 599 ++ .../python3.8/site-packages/dateutil/rrule.py | 1735 +++++ .../site-packages/dateutil/tz/__init__.py | 12 + .../tz/__pycache__/__init__.cpython-38.pyc | Bin 0 -> 680 bytes .../tz/__pycache__/_common.cpython-38.pyc | Bin 0 -> 10723 bytes .../tz/__pycache__/_factories.cpython-38.pyc | Bin 0 -> 2834 bytes .../dateutil/tz/__pycache__/tz.cpython-38.pyc | Bin 0 -> 44848 bytes .../tz/__pycache__/win.cpython-38.pyc | Bin 0 -> 11228 bytes .../site-packages/dateutil/tz/_common.py | 419 ++ .../site-packages/dateutil/tz/_factories.py | 80 + .../python3.8/site-packages/dateutil/tz/tz.py | 1849 ++++++ .../site-packages/dateutil/tz/win.py | 370 ++ .../python3.8/site-packages/dateutil/tzwin.py | 2 + .../python3.8/site-packages/dateutil/utils.py | 71 + .../dateutil/zoneinfo/__init__.py | 167 + .../__pycache__/__init__.cpython-38.pyc | Bin 0 -> 5662 bytes .../__pycache__/rebuild.cpython-38.pyc | Bin 0 -> 1871 bytes .../zoneinfo/dateutil-zoneinfo.tar.gz | Bin 0 -> 153315 bytes .../dateutil/zoneinfo/rebuild.py | 53 + .../decorator-4.4.2.dist-info/INSTALLER | 1 + .../decorator-4.4.2.dist-info/LICENSE.txt | 26 + .../decorator-4.4.2.dist-info/METADATA | 131 + .../decorator-4.4.2.dist-info/RECORD | 9 + .../decorator-4.4.2.dist-info/WHEEL | 6 + .../decorator-4.4.2.dist-info/pbr.json | 1 + .../decorator-4.4.2.dist-info/top_level.txt | 1 + .../lib/python3.8/site-packages/decorator.py | 454 ++ .../python3.8/site-packages/easy_install.py | 5 + .../ipykernel-5.4.2.dist-info/COPYING.md | 59 + .../ipykernel-5.4.2.dist-info/INSTALLER | 1 + .../ipykernel-5.4.2.dist-info/METADATA | 33 + .../ipykernel-5.4.2.dist-info/RECORD | 133 + .../ipykernel-5.4.2.dist-info/WHEEL | 5 + .../ipykernel-5.4.2.dist-info/top_level.txt | 2 + .../site-packages/ipykernel/__init__.py | 2 + .../site-packages/ipykernel/__main__.py | 3 + .../__pycache__/__init__.cpython-38.pyc | Bin 0 -> 309 bytes .../__pycache__/__main__.cpython-38.pyc | Bin 0 -> 254 bytes .../_eventloop_macos.cpython-38.pyc | Bin 0 -> 2976 bytes .../__pycache__/_version.cpython-38.pyc | Bin 0 -> 474 bytes .../__pycache__/codeutil.cpython-38.pyc | Bin 0 -> 1517 bytes .../__pycache__/connect.cpython-38.pyc | Bin 0 -> 5218 bytes .../__pycache__/datapub.cpython-38.pyc | Bin 0 -> 2288 bytes .../__pycache__/displayhook.cpython-38.pyc | Bin 0 -> 3385 bytes .../__pycache__/embed.cpython-38.pyc | Bin 0 -> 1407 bytes .../__pycache__/eventloops.cpython-38.pyc | Bin 0 -> 11961 bytes .../__pycache__/heartbeat.cpython-38.pyc | Bin 0 -> 2600 bytes .../__pycache__/iostream.cpython-38.pyc | Bin 0 -> 13479 bytes .../__pycache__/ipkernel.cpython-38.pyc | Bin 0 -> 13813 bytes .../__pycache__/jsonutil.cpython-38.pyc | Bin 0 -> 3105 bytes .../__pycache__/kernelapp.cpython-38.pyc | Bin 0 -> 18217 bytes .../__pycache__/kernelbase.cpython-38.pyc | Bin 0 -> 23925 bytes .../__pycache__/kernelspec.cpython-38.pyc | Bin 0 -> 6358 bytes .../ipykernel/__pycache__/log.cpython-38.pyc | Bin 0 -> 1221 bytes .../__pycache__/parentpoller.cpython-38.pyc | Bin 0 -> 3505 bytes .../__pycache__/pickleutil.cpython-38.pyc | Bin 0 -> 12584 bytes .../__pycache__/serialize.cpython-38.pyc | Bin 0 -> 5283 bytes .../__pycache__/trio_runner.cpython-38.pyc | Bin 0 -> 2639 bytes .../__pycache__/zmqshell.cpython-38.pyc | Bin 0 -> 20227 bytes .../ipykernel/_eventloop_macos.py | 153 + .../site-packages/ipykernel/_version.py | 16 + .../site-packages/ipykernel/codeutil.py | 38 + .../site-packages/ipykernel/comm/__init__.py | 2 + .../comm/__pycache__/__init__.cpython-38.pyc | Bin 0 -> 190 bytes .../comm/__pycache__/comm.cpython-38.pyc | Bin 0 -> 5021 bytes .../comm/__pycache__/manager.cpython-38.pyc | Bin 0 -> 3922 bytes .../site-packages/ipykernel/comm/comm.py | 166 + .../site-packages/ipykernel/comm/manager.py | 130 + .../site-packages/ipykernel/connect.py | 187 + .../site-packages/ipykernel/datapub.py | 73 + .../site-packages/ipykernel/displayhook.py | 80 + .../site-packages/ipykernel/embed.py | 57 + .../site-packages/ipykernel/eventloops.py | 431 ++ .../site-packages/ipykernel/gui/__init__.py | 15 + .../gui/__pycache__/__init__.cpython-38.pyc | Bin 0 -> 373 bytes .../gui/__pycache__/gtk3embed.cpython-38.pyc | Bin 0 -> 2776 bytes .../gui/__pycache__/gtkembed.cpython-38.pyc | Bin 0 -> 2676 bytes .../site-packages/ipykernel/gui/gtk3embed.py | 88 + .../site-packages/ipykernel/gui/gtkembed.py | 86 + .../site-packages/ipykernel/heartbeat.py | 120 + .../ipykernel/inprocess/__init__.py | 8 + .../__pycache__/__init__.cpython-38.pyc | Bin 0 -> 401 bytes .../__pycache__/blocking.cpython-38.pyc | Bin 0 -> 3077 bytes .../__pycache__/channels.cpython-38.pyc | Bin 0 -> 3894 bytes .../__pycache__/client.cpython-38.pyc | Bin 0 -> 6050 bytes .../__pycache__/constants.cpython-38.pyc | Bin 0 -> 221 bytes .../__pycache__/ipkernel.cpython-38.pyc | Bin 0 -> 6026 bytes .../__pycache__/manager.cpython-38.pyc | Bin 0 -> 3382 bytes .../__pycache__/socket.cpython-38.pyc | Bin 0 -> 2365 bytes .../ipykernel/inprocess/blocking.py | 90 + .../ipykernel/inprocess/channels.py | 97 + .../ipykernel/inprocess/client.py | 187 + .../ipykernel/inprocess/constants.py | 8 + .../ipykernel/inprocess/ipkernel.py | 192 + .../ipykernel/inprocess/manager.py | 81 + .../ipykernel/inprocess/socket.py | 64 + .../ipykernel/inprocess/tests/__init__.py | 0 .../tests/__pycache__/__init__.cpython-38.pyc | Bin 0 -> 161 bytes .../__pycache__/test_kernel.cpython-38.pyc | Bin 0 -> 3948 bytes .../test_kernelmanager.cpython-38.pyc | Bin 0 -> 3683 bytes .../ipykernel/inprocess/tests/test_kernel.py | 108 + .../inprocess/tests/test_kernelmanager.py | 113 + .../site-packages/ipykernel/iostream.py | 438 ++ .../site-packages/ipykernel/ipkernel.py | 533 ++ .../site-packages/ipykernel/jsonutil.py | 151 + .../site-packages/ipykernel/kernelapp.py | 628 ++ .../site-packages/ipykernel/kernelbase.py | 921 +++ .../site-packages/ipykernel/kernelspec.py | 196 + .../python3.8/site-packages/ipykernel/log.py | 26 + .../site-packages/ipykernel/parentpoller.py | 114 + .../site-packages/ipykernel/pickleutil.py | 441 ++ .../site-packages/ipykernel/pylab/__init__.py | 0 .../pylab/__pycache__/__init__.cpython-38.pyc | Bin 0 -> 151 bytes .../__pycache__/backend_inline.cpython-38.pyc | Bin 0 -> 5384 bytes .../pylab/__pycache__/config.cpython-38.pyc | Bin 0 -> 3690 bytes .../ipykernel/pylab/backend_inline.py | 198 + .../site-packages/ipykernel/pylab/config.py | 110 + .../ipykernel/resources/logo-32x32.png | Bin 0 -> 1084 bytes .../ipykernel/resources/logo-64x64.png | Bin 0 -> 2180 bytes .../site-packages/ipykernel/serialize.py | 187 + .../site-packages/ipykernel/tests/__init__.py | 45 + .../tests/__pycache__/__init__.cpython-38.pyc | Bin 0 -> 999 bytes .../__pycache__/_asyncio_utils.cpython-38.pyc | Bin 0 -> 708 bytes .../__pycache__/test_async.cpython-38.pyc | Bin 0 -> 2419 bytes .../__pycache__/test_connect.cpython-38.pyc | Bin 0 -> 4335 bytes .../test_embed_kernel.cpython-38.pyc | Bin 0 -> 3886 bytes .../__pycache__/test_eventloop.cpython-38.pyc | Bin 0 -> 1353 bytes .../__pycache__/test_heartbeat.cpython-38.pyc | Bin 0 -> 1739 bytes .../tests/__pycache__/test_io.cpython-38.pyc | Bin 0 -> 1140 bytes .../__pycache__/test_jsonutil.cpython-38.pyc | Bin 0 -> 3259 bytes .../__pycache__/test_kernel.cpython-38.pyc | Bin 0 -> 10902 bytes .../test_kernelspec.cpython-38.pyc | Bin 0 -> 4759 bytes .../test_message_spec.cpython-38.pyc | Bin 0 -> 16288 bytes .../test_pickleutil.cpython-38.pyc | Bin 0 -> 2543 bytes .../__pycache__/test_serialize.cpython-38.pyc | Bin 0 -> 12775 bytes .../test_start_kernel.cpython-38.pyc | Bin 0 -> 1394 bytes .../__pycache__/test_zmq_shell.cpython-38.pyc | Bin 0 -> 6506 bytes .../tests/__pycache__/utils.cpython-38.pyc | Bin 0 -> 4357 bytes .../ipykernel/tests/_asyncio_utils.py | 17 + .../ipykernel/tests/test_async.py | 74 + .../ipykernel/tests/test_connect.py | 123 + .../ipykernel/tests/test_embed_kernel.py | 180 + .../ipykernel/tests/test_eventloop.py | 46 + .../ipykernel/tests/test_heartbeat.py | 59 + .../site-packages/ipykernel/tests/test_io.py | 40 + .../ipykernel/tests/test_jsonutil.py | 109 + .../ipykernel/tests/test_kernel.py | 393 ++ .../ipykernel/tests/test_kernelspec.py | 168 + .../ipykernel/tests/test_message_spec.py | 545 ++ .../ipykernel/tests/test_pickleutil.py | 65 + .../ipykernel/tests/test_serialize.py | 201 + .../ipykernel/tests/test_start_kernel.py | 51 + .../ipykernel/tests/test_zmq_shell.py | 202 + .../site-packages/ipykernel/tests/utils.py | 167 + .../site-packages/ipykernel/trio_runner.py | 60 + .../site-packages/ipykernel/zmqshell.py | 644 ++ .../site-packages/ipykernel_launcher.py | 16 + .../ipython-7.19.0.dist-info/INSTALLER | 1 + .../ipython-7.19.0.dist-info/LICENSE | 33 + .../ipython-7.19.0.dist-info/METADATA | 115 + .../ipython-7.19.0.dist-info/RECORD | 628 ++ .../ipython-7.19.0.dist-info/WHEEL | 5 + .../ipython-7.19.0.dist-info/entry_points.txt | 11 + .../ipython-7.19.0.dist-info/top_level.txt | 1 + .../DESCRIPTION.rst | 3 + .../INSTALLER | 1 + .../ipython_genutils-0.2.0.dist-info/METADATA | 24 + .../ipython_genutils-0.2.0.dist-info/RECORD | 39 + .../ipython_genutils-0.2.0.dist-info/WHEEL | 6 + .../metadata.json | 1 + .../top_level.txt | 1 + .../ipython_genutils/__init__.py | 1 + .../__pycache__/__init__.cpython-38.pyc | Bin 0 -> 219 bytes .../__pycache__/_version.cpython-38.pyc | Bin 0 -> 234 bytes .../__pycache__/encoding.cpython-38.pyc | Bin 0 -> 1786 bytes .../__pycache__/importstring.cpython-38.pyc | Bin 0 -> 1002 bytes .../__pycache__/ipstruct.cpython-38.pyc | Bin 0 -> 10877 bytes .../__pycache__/path.cpython-38.pyc | Bin 0 -> 4457 bytes .../__pycache__/py3compat.cpython-38.pyc | Bin 0 -> 8843 bytes .../__pycache__/tempdir.cpython-38.pyc | Bin 0 -> 4863 bytes .../__pycache__/text.cpython-38.pyc | Bin 0 -> 7193 bytes .../ipython_genutils/_version.py | 2 + .../ipython_genutils/encoding.py | 71 + .../ipython_genutils/importstring.py | 39 + .../ipython_genutils/ipstruct.py | 376 ++ .../site-packages/ipython_genutils/path.py | 172 + .../ipython_genutils/py3compat.py | 333 + .../site-packages/ipython_genutils/tempdir.py | 150 + .../ipython_genutils/testing/__init__.py | 0 .../__pycache__/__init__.cpython-38.pyc | Bin 0 -> 160 bytes .../__pycache__/decorators.cpython-38.pyc | Bin 0 -> 10048 bytes .../ipython_genutils/testing/decorators.py | 342 + .../ipython_genutils/tests/__init__.py | 0 .../tests/__pycache__/__init__.cpython-38.pyc | Bin 0 -> 158 bytes .../test_importstring.cpython-38.pyc | Bin 0 -> 991 bytes .../__pycache__/test_path.cpython-38.pyc | Bin 0 -> 4170 bytes .../__pycache__/test_tempdir.cpython-38.pyc | Bin 0 -> 896 bytes .../__pycache__/test_text.cpython-38.pyc | Bin 0 -> 2927 bytes .../tests/test_importstring.py | 27 + .../ipython_genutils/tests/test_path.py | 108 + .../ipython_genutils/tests/test_tempdir.py | 22 + .../ipython_genutils/tests/test_text.py | 59 + .../site-packages/ipython_genutils/text.py | 244 + .../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 0 -> 594 bytes .../isort/__pycache__/__main__.cpython-38.pyc | Bin 0 -> 188 bytes .../isort/__pycache__/_version.cpython-38.pyc | Bin 0 -> 162 bytes .../isort/__pycache__/api.cpython-38.pyc | Bin 0 -> 11133 bytes .../isort/__pycache__/comments.cpython-38.pyc | Bin 0 -> 1027 bytes .../isort/__pycache__/core.cpython-38.pyc | Bin 0 -> 7558 bytes .../__pycache__/exceptions.cpython-38.pyc | Bin 0 -> 8192 bytes .../isort/__pycache__/format.cpython-38.pyc | Bin 0 -> 5255 bytes .../isort/__pycache__/hooks.cpython-38.pyc | Bin 0 -> 3146 bytes .../isort/__pycache__/io.cpython-38.pyc | Bin 0 -> 2632 bytes .../isort/__pycache__/literal.cpython-38.pyc | Bin 0 -> 4073 bytes .../isort/__pycache__/logo.cpython-38.pyc | Bin 0 -> 537 bytes .../isort/__pycache__/main.cpython-38.pyc | Bin 0 -> 24774 bytes .../isort/__pycache__/output.cpython-38.pyc | Bin 0 -> 11967 bytes .../isort/__pycache__/parse.cpython-38.pyc | Bin 0 -> 10809 bytes .../isort/__pycache__/place.cpython-38.pyc | Bin 0 -> 4875 bytes .../isort/__pycache__/profiles.cpython-38.pyc | Bin 0 -> 1229 bytes .../__pycache__/pylama_isort.cpython-38.pyc | Bin 0 -> 1459 bytes .../isort/__pycache__/sections.cpython-38.pyc | Bin 0 -> 455 bytes .../isort/__pycache__/settings.cpython-38.pyc | Bin 0 -> 19697 bytes .../setuptools_commands.cpython-38.pyc | Bin 0 -> 2298 bytes .../isort/__pycache__/sorting.cpython-38.pyc | Bin 0 -> 2912 bytes .../isort/__pycache__/utils.cpython-38.pyc | Bin 0 -> 832 bytes .../isort/__pycache__/wrap.cpython-38.pyc | Bin 0 -> 3148 bytes .../__pycache__/wrap_modes.cpython-38.pyc | Bin 0 -> 7199 bytes .../site-packages/isort/_future/__init__.py | 12 + .../__pycache__/__init__.cpython-38.pyc | Bin 0 -> 365 bytes .../__pycache__/_dataclasses.cpython-38.pyc | Bin 0 -> 21748 bytes .../isort/_future/_dataclasses.py | 1209 ++++ .../isort/_vendored/toml/LICENSE | 27 + .../isort/_vendored/toml/__init__.py | 23 + .../toml/__pycache__/__init__.cpython-38.pyc | Bin 0 -> 672 bytes .../toml/__pycache__/decoder.cpython-38.pyc | Bin 0 -> 23037 bytes .../toml/__pycache__/encoder.cpython-38.pyc | Bin 0 -> 9344 bytes .../toml/__pycache__/ordered.cpython-38.pyc | Bin 0 -> 916 bytes .../toml/__pycache__/tz.cpython-38.pyc | Bin 0 -> 1089 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 + .../lib/python3.8/site-packages/isort/api.py | 389 ++ .../python3.8/site-packages/isort/comments.py | 32 + .../lib/python3.8/site-packages/isort/core.py | 420 ++ .../isort/deprecated/__init__.py | 0 .../__pycache__/__init__.cpython-38.pyc | Bin 0 -> 152 bytes .../__pycache__/finders.cpython-38.pyc | Bin 0 -> 13505 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 + .venv/lib/python3.8/site-packages/isort/io.py | 69 + .../python3.8/site-packages/isort/literal.py | 109 + .../lib/python3.8/site-packages/isort/logo.py | 19 + .../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 0 -> 295 bytes .../stdlibs/__pycache__/all.cpython-38.pyc | Bin 0 -> 208 bytes .../stdlibs/__pycache__/py2.cpython-38.pyc | Bin 0 -> 189 bytes .../stdlibs/__pycache__/py27.cpython-38.pyc | Bin 0 -> 4143 bytes .../stdlibs/__pycache__/py3.cpython-38.pyc | Bin 0 -> 273 bytes .../stdlibs/__pycache__/py35.cpython-38.pyc | Bin 0 -> 3009 bytes .../stdlibs/__pycache__/py36.cpython-38.pyc | Bin 0 -> 3022 bytes .../stdlibs/__pycache__/py37.cpython-38.pyc | Bin 0 -> 3044 bytes .../stdlibs/__pycache__/py38.cpython-38.pyc | Bin 0 -> 3031 bytes .../stdlibs/__pycache__/py39.cpython-38.pyc | Bin 0 -> 3019 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 + .../lib/python3.8/site-packages/isort/wrap.py | 131 + .../site-packages/isort/wrap_modes.py | 325 + .../jedi-0.17.2.dist-info/AUTHORS.txt | 66 + .../jedi-0.17.2.dist-info/INSTALLER | 1 + .../jedi-0.17.2.dist-info/LICENSE.txt | 24 + .../jedi-0.17.2.dist-info/METADATA | 536 ++ .../jedi-0.17.2.dist-info/RECORD | 1763 +++++ .../site-packages/jedi-0.17.2.dist-info/WHEEL | 6 + .../jedi-0.17.2.dist-info/top_level.txt | 1 + .../python3.8/site-packages/jedi/__init__.py | 43 + .../python3.8/site-packages/jedi/__main__.py | 72 + .../jedi/__pycache__/__init__.cpython-38.pyc | Bin 0 -> 1740 bytes .../jedi/__pycache__/__main__.cpython-38.pyc | Bin 0 -> 1762 bytes .../__pycache__/_compatibility.cpython-38.pyc | Bin 0 -> 16426 bytes .../jedi/__pycache__/cache.cpython-38.pyc | Bin 0 -> 3745 bytes .../jedi/__pycache__/common.cpython-38.pyc | Bin 0 -> 1165 bytes .../jedi/__pycache__/debug.cpython-38.pyc | Bin 0 -> 3740 bytes .../jedi/__pycache__/file_io.cpython-38.pyc | Bin 0 -> 3903 bytes .../__pycache__/parser_utils.cpython-38.pyc | Bin 0 -> 8242 bytes .../jedi/__pycache__/settings.cpython-38.pyc | Bin 0 -> 1641 bytes .../jedi/__pycache__/utils.cpython-38.pyc | Bin 0 -> 4521 bytes .../site-packages/jedi/_compatibility.py | 631 ++ .../site-packages/jedi/api/__init__.py | 917 +++ .../api/__pycache__/__init__.cpython-38.pyc | Bin 0 -> 31124 bytes .../api/__pycache__/classes.cpython-38.pyc | Bin 0 -> 31270 bytes .../api/__pycache__/completion.cpython-38.pyc | Bin 0 -> 18249 bytes .../completion_cache.cpython-38.pyc | Bin 0 -> 872 bytes .../__pycache__/environment.cpython-38.pyc | Bin 0 -> 13113 bytes .../api/__pycache__/errors.cpython-38.pyc | Bin 0 -> 2096 bytes .../api/__pycache__/exceptions.cpython-38.pyc | Bin 0 -> 1558 bytes .../api/__pycache__/file_name.cpython-38.pyc | Bin 0 -> 4030 bytes .../api/__pycache__/helpers.cpython-38.pyc | Bin 0 -> 13066 bytes .../__pycache__/interpreter.cpython-38.pyc | Bin 0 -> 3342 bytes .../api/__pycache__/keywords.cpython-38.pyc | Bin 0 -> 1456 bytes .../api/__pycache__/project.cpython-38.pyc | Bin 0 -> 13403 bytes .../__pycache__/replstartup.cpython-38.pyc | Bin 0 -> 1017 bytes .../api/__pycache__/strings.cpython-38.pyc | Bin 0 -> 3333 bytes .../site-packages/jedi/api/classes.py | 925 +++ .../site-packages/jedi/api/completion.py | 665 ++ .../jedi/api/completion_cache.py | 25 + .../site-packages/jedi/api/environment.py | 489 ++ .../site-packages/jedi/api/errors.py | 46 + .../site-packages/jedi/api/exceptions.py | 31 + .../site-packages/jedi/api/file_name.py | 156 + .../site-packages/jedi/api/helpers.py | 522 ++ .../site-packages/jedi/api/interpreter.py | 75 + .../site-packages/jedi/api/keywords.py | 57 + .../site-packages/jedi/api/project.py | 427 ++ .../jedi/api/refactoring/__init__.py | 249 + .../__pycache__/__init__.cpython-38.pyc | Bin 0 -> 7738 bytes .../__pycache__/extract.cpython-38.pyc | Bin 0 -> 9513 bytes .../jedi/api/refactoring/extract.py | 387 ++ .../site-packages/jedi/api/replstartup.py | 29 + .../site-packages/jedi/api/strings.py | 109 + .../lib/python3.8/site-packages/jedi/cache.py | 114 + .../python3.8/site-packages/jedi/common.py | 36 + .../lib/python3.8/site-packages/jedi/debug.py | 143 + .../python3.8/site-packages/jedi/file_io.py | 83 + .../site-packages/jedi/inference/__init__.py | 197 + .../__pycache__/__init__.cpython-38.pyc | Bin 0 -> 7746 bytes .../__pycache__/analysis.cpython-38.pyc | Bin 0 -> 6989 bytes .../__pycache__/arguments.cpython-38.pyc | Bin 0 -> 10608 bytes .../__pycache__/base_value.cpython-38.pyc | Bin 0 -> 23719 bytes .../__pycache__/cache.cpython-38.pyc | Bin 0 -> 4250 bytes .../__pycache__/context.cpython-38.pyc | Bin 0 -> 17762 bytes .../__pycache__/docstrings.cpython-38.pyc | Bin 0 -> 9018 bytes .../__pycache__/dynamic_params.cpython-38.pyc | Bin 0 -> 5802 bytes .../__pycache__/filters.cpython-38.pyc | Bin 0 -> 15370 bytes .../__pycache__/finder.cpython-38.pyc | Bin 0 -> 4388 bytes .../__pycache__/flow_analysis.cpython-38.pyc | Bin 0 -> 3223 bytes .../__pycache__/helpers.cpython-38.pyc | Bin 0 -> 5295 bytes .../__pycache__/imports.cpython-38.pyc | Bin 0 -> 14112 bytes .../__pycache__/lazy_value.cpython-38.pyc | Bin 0 -> 3250 bytes .../__pycache__/names.cpython-38.pyc | Bin 0 -> 23118 bytes .../__pycache__/param.cpython-38.pyc | Bin 0 -> 7031 bytes .../__pycache__/parser_cache.cpython-38.pyc | Bin 0 -> 399 bytes .../__pycache__/recursion.cpython-38.pyc | Bin 0 -> 4397 bytes .../__pycache__/references.cpython-38.pyc | Bin 0 -> 7806 bytes .../__pycache__/signature.cpython-38.pyc | Bin 0 -> 5899 bytes .../__pycache__/star_args.cpython-38.pyc | Bin 0 -> 4998 bytes .../__pycache__/syntax_tree.cpython-38.pyc | Bin 0 -> 21143 bytes .../__pycache__/sys_path.cpython-38.pyc | Bin 0 -> 7257 bytes .../__pycache__/utils.cpython-38.pyc | Bin 0 -> 4740 bytes .../site-packages/jedi/inference/analysis.py | 217 + .../site-packages/jedi/inference/arguments.py | 343 + .../jedi/inference/base_value.py | 556 ++ .../site-packages/jedi/inference/cache.py | 126 + .../jedi/inference/compiled/__init__.py | 68 + .../__pycache__/__init__.cpython-38.pyc | Bin 0 -> 2820 bytes .../__pycache__/access.cpython-38.pyc | Bin 0 -> 17210 bytes .../__pycache__/getattr_static.cpython-38.pyc | Bin 0 -> 5357 bytes .../compiled/__pycache__/mixed.cpython-38.pyc | Bin 0 -> 9179 bytes .../compiled/__pycache__/value.cpython-38.pyc | Bin 0 -> 21828 bytes .../jedi/inference/compiled/access.py | 564 ++ .../jedi/inference/compiled/getattr_static.py | 184 + .../jedi/inference/compiled/mixed.py | 304 + .../inference/compiled/subprocess/__init__.py | 404 ++ .../inference/compiled/subprocess/__main__.py | 55 + .../__pycache__/__init__.cpython-38.pyc | Bin 0 -> 13283 bytes .../__pycache__/__main__.cpython-38.pyc | Bin 0 -> 1834 bytes .../__pycache__/functions.cpython-38.pyc | Bin 0 -> 3406 bytes .../compiled/subprocess/functions.py | 115 + .../jedi/inference/compiled/value.py | 629 ++ .../site-packages/jedi/inference/context.py | 500 ++ .../jedi/inference/docstrings.py | 307 + .../jedi/inference/dynamic_params.py | 226 + .../site-packages/jedi/inference/filters.py | 353 + .../site-packages/jedi/inference/finder.py | 146 + .../jedi/inference/flow_analysis.py | 123 + .../jedi/inference/gradual/__init__.py | 4 + .../__pycache__/__init__.cpython-38.pyc | Bin 0 -> 306 bytes .../__pycache__/annotation.cpython-38.pyc | Bin 0 -> 11742 bytes .../gradual/__pycache__/base.cpython-38.pyc | Bin 0 -> 15671 bytes .../__pycache__/conversion.cpython-38.pyc | Bin 0 -> 5113 bytes .../__pycache__/generics.cpython-38.pyc | Bin 0 -> 5239 bytes .../__pycache__/stub_value.cpython-38.pyc | Bin 0 -> 4281 bytes .../__pycache__/type_var.cpython-38.pyc | Bin 0 -> 4829 bytes .../__pycache__/typeshed.cpython-38.pyc | Bin 0 -> 7125 bytes .../gradual/__pycache__/typing.cpython-38.pyc | Bin 0 -> 15956 bytes .../gradual/__pycache__/utils.cpython-38.pyc | Bin 0 -> 938 bytes .../jedi/inference/gradual/annotation.py | 439 ++ .../jedi/inference/gradual/base.py | 430 ++ .../jedi/inference/gradual/conversion.py | 210 + .../jedi/inference/gradual/generics.py | 101 + .../jedi/inference/gradual/stub_value.py | 105 + .../jedi/inference/gradual/type_var.py | 131 + .../jedi/inference/gradual/typeshed.py | 312 + .../jedi/inference/gradual/typing.py | 485 ++ .../jedi/inference/gradual/utils.py | 30 + .../site-packages/jedi/inference/helpers.py | 207 + .../site-packages/jedi/inference/imports.py | 563 ++ .../jedi/inference/lazy_value.py | 61 + .../site-packages/jedi/inference/names.py | 660 ++ .../site-packages/jedi/inference/param.py | 258 + .../jedi/inference/parser_cache.py | 6 + .../site-packages/jedi/inference/recursion.py | 153 + .../jedi/inference/references.py | 299 + .../site-packages/jedi/inference/signature.py | 151 + .../site-packages/jedi/inference/star_args.py | 217 + .../jedi/inference/syntax_tree.py | 884 +++ .../site-packages/jedi/inference/sys_path.py | 271 + .../site-packages/jedi/inference/utils.py | 115 + .../jedi/inference/value/__init__.py | 6 + .../value/__pycache__/__init__.cpython-38.pyc | Bin 0 -> 544 bytes .../__pycache__/decorator.cpython-38.pyc | Bin 0 -> 1269 bytes .../__pycache__/dynamic_arrays.cpython-38.pyc | Bin 0 -> 7371 bytes .../value/__pycache__/function.cpython-38.pyc | Bin 0 -> 17488 bytes .../value/__pycache__/instance.cpython-38.pyc | Bin 0 -> 25273 bytes .../value/__pycache__/iterable.cpython-38.pyc | Bin 0 -> 24901 bytes .../value/__pycache__/klass.cpython-38.pyc | Bin 0 -> 13798 bytes .../value/__pycache__/module.cpython-38.pyc | Bin 0 -> 7438 bytes .../__pycache__/namespace.cpython-38.pyc | Bin 0 -> 3484 bytes .../jedi/inference/value/decorator.py | 21 + .../jedi/inference/value/dynamic_arrays.py | 204 + .../jedi/inference/value/function.py | 470 ++ .../jedi/inference/value/instance.py | 625 ++ .../jedi/inference/value/iterable.py | 673 ++ .../jedi/inference/value/klass.py | 392 ++ .../jedi/inference/value/module.py | 229 + .../jedi/inference/value/namespace.py | 74 + .../site-packages/jedi/parser_utils.py | 333 + .../site-packages/jedi/plugins/__init__.py | 47 + .../__pycache__/__init__.cpython-38.pyc | Bin 0 -> 1760 bytes .../plugins/__pycache__/django.cpython-38.pyc | Bin 0 -> 11774 bytes .../plugins/__pycache__/flask.cpython-38.pyc | Bin 0 -> 818 bytes .../plugins/__pycache__/pytest.cpython-38.pyc | Bin 0 -> 5350 bytes .../__pycache__/registry.cpython-38.pyc | Bin 0 -> 434 bytes .../plugins/__pycache__/stdlib.cpython-38.pyc | Bin 0 -> 30460 bytes .../site-packages/jedi/plugins/django.py | 295 + .../site-packages/jedi/plugins/flask.py | 21 + .../site-packages/jedi/plugins/pytest.py | 164 + .../site-packages/jedi/plugins/registry.py | 12 + .../site-packages/jedi/plugins/stdlib.py | 863 +++ .../python3.8/site-packages/jedi/settings.py | 151 + .../jedi/third_party/django-stubs/LICENSE.txt | 8 + .../django-stubs/django-stubs/__init__.pyi | 12 + .../django-stubs/apps/__init__.pyi | 3 + .../django-stubs/django-stubs/apps/config.pyi | 23 + .../django-stubs/apps/registry.pyi | 40 + .../django-stubs/conf/__init__.pyi | 29 + .../django-stubs/conf/global_settings.pyi | 504 ++ .../django-stubs/conf/locale/__init__.pyi | 3 + .../django-stubs/conf/urls/__init__.pyi | 25 + .../django-stubs/conf/urls/i18n.pyi | 8 + .../django-stubs/conf/urls/static.pyi | 5 + .../django-stubs/contrib/__init__.pyi | 0 .../django-stubs/contrib/admin/__init__.pyi | 24 + .../django-stubs/contrib/admin/actions.pyi | 8 + .../django-stubs/contrib/admin/apps.pyi | 6 + .../django-stubs/contrib/admin/checks.pyi | 21 + .../django-stubs/contrib/admin/decorators.pyi | 5 + .../django-stubs/contrib/admin/filters.pyi | 110 + .../django-stubs/contrib/admin/forms.pyi | 7 + .../django-stubs/contrib/admin/helpers.pyi | 155 + .../django-stubs/contrib/admin/models.pyi | 39 + .../django-stubs/contrib/admin/options.pyi | 275 + .../django-stubs/contrib/admin/sites.pyi | 75 + .../contrib/admin/templatetags/__init__.pyi | 0 .../contrib/admin/templatetags/admin_list.pyi | 42 + .../admin/templatetags/admin_modify.pyi | 16 + .../admin/templatetags/admin_static.pyi | 5 + .../contrib/admin/templatetags/admin_urls.pyi | 17 + .../contrib/admin/templatetags/base.pyi | 17 + .../contrib/admin/templatetags/log.pyi | 16 + .../django-stubs/contrib/admin/tests.pyi | 23 + .../django-stubs/contrib/admin/utils.pyi | 68 + .../contrib/admin/views/__init__.pyi | 0 .../contrib/admin/views/autocomplete.pyi | 10 + .../contrib/admin/views/decorators.pyi | 7 + .../django-stubs/contrib/admin/views/main.pyi | 89 + .../django-stubs/contrib/admin/widgets.pyi | 102 + .../contrib/admindocs/__init__.pyi | 0 .../contrib/admindocs/middleware.pyi | 10 + .../django-stubs/contrib/admindocs/urls.pyi | 3 + .../django-stubs/contrib/admindocs/utils.pyi | 27 + .../django-stubs/contrib/admindocs/views.pyi | 21 + .../django-stubs/contrib/auth/__init__.pyi | 34 + .../django-stubs/contrib/auth/admin.pyi | 18 + .../django-stubs/contrib/auth/apps.pyi | 3 + .../django-stubs/contrib/auth/backends.pyi | 40 + .../django-stubs/contrib/auth/base_user.pyi | 44 + .../django-stubs/contrib/auth/checks.pyi | 8 + .../contrib/auth/context_processors.pyi | 20 + .../django-stubs/contrib/auth/decorators.pyi | 21 + .../django-stubs/contrib/auth/forms.pyi | 91 + .../contrib/auth/handlers/__init__.pyi | 0 .../contrib/auth/handlers/modwsgi.pyi | 6 + .../django-stubs/contrib/auth/hashers.pyi | 45 + .../contrib/auth/management/__init__.pyi | 15 + .../auth/management/commands/__init__.pyi | 0 .../management/commands/changepassword.pyi | 7 + .../management/commands/createsuperuser.pyi | 9 + .../django-stubs/contrib/auth/middleware.pyi | 20 + .../django-stubs/contrib/auth/mixins.pyi | 28 + .../django-stubs/contrib/auth/models.pyi | 117 + .../contrib/auth/password_validation.pyi | 46 + .../django-stubs/contrib/auth/signals.pyi | 5 + .../django-stubs/contrib/auth/tokens.pyi | 11 + .../django-stubs/contrib/auth/urls.pyi | 3 + .../django-stubs/contrib/auth/validators.pyi | 4 + .../django-stubs/contrib/auth/views.pyi | 72 + .../contrib/contenttypes/__init__.pyi | 0 .../contrib/contenttypes/admin.pyi | 14 + .../contrib/contenttypes/apps.pyi | 3 + .../contrib/contenttypes/checks.pyi | 6 + .../contrib/contenttypes/fields.pyi | 95 + .../contrib/contenttypes/forms.pyi | 41 + .../contenttypes/management/__init__.pyi | 33 + .../management/commands/__init__.pyi | 0 .../commands/remove_stale_contenttypes.pyi | 15 + .../contrib/contenttypes/models.pyi | 24 + .../contrib/contenttypes/views.pyi | 8 + .../contrib/flatpages/__init__.pyi | 0 .../django-stubs/contrib/flatpages/forms.pyi | 7 + .../contrib/flatpages/middleware.pyi | 6 + .../django-stubs/contrib/flatpages/models.pyi | 13 + .../contrib/flatpages/sitemaps.pyi | 3 + .../flatpages/templatetags/__init__.pyi | 0 .../flatpages/templatetags/flatpages.pyi | 16 + .../django-stubs/contrib/flatpages/urls.pyi | 3 + .../django-stubs/contrib/flatpages/views.pyi | 8 + .../django-stubs/contrib/gis/__init__.pyi | 0 .../django-stubs/contrib/gis/db/__init__.pyi | 0 .../contrib/gis/db/models/__init__.pyi | 13 + .../contrib/gis/db/models/fields.pyi | 91 + .../contrib/humanize/__init__.pyi | 0 .../humanize/templatetags/__init__.pyi | 0 .../humanize/templatetags/humanize.pyi | 14 + .../contrib/messages/__init__.pyi | 24 + .../django-stubs/contrib/messages/api.pyi | 26 + .../contrib/messages/constants.pyi | 11 + .../contrib/messages/context_processors.pyi | 6 + .../contrib/messages/middleware.pyi | 7 + .../contrib/messages/storage/__init__.pyi | 6 + .../contrib/messages/storage/base.pyi | 28 + .../contrib/messages/storage/cookie.pyi | 20 + .../contrib/messages/storage/fallback.pyi | 8 + .../contrib/messages/storage/session.pyi | 10 + .../django-stubs/contrib/messages/utils.pyi | 3 + .../django-stubs/contrib/messages/views.pyi | 9 + .../contrib/postgres/__init__.pyi | 0 .../contrib/postgres/aggregates/__init__.pyi | 24 + .../contrib/postgres/aggregates/general.pyi | 11 + .../contrib/postgres/aggregates/mixins.pyi | 1 + .../postgres/aggregates/statistics.pyi | 14 + .../contrib/postgres/constraints.pyi | 18 + .../contrib/postgres/fields/__init__.pyi | 20 + .../contrib/postgres/fields/array.pyi | 51 + .../contrib/postgres/fields/citext.pyi | 6 + .../contrib/postgres/fields/hstore.pyi | 17 + .../contrib/postgres/fields/jsonb.pyi | 32 + .../contrib/postgres/fields/mixins.pyi | 4 + .../contrib/postgres/fields/ranges.pyi | 48 + .../contrib/postgres/functions.pyi | 4 + .../django-stubs/contrib/postgres/indexes.pyi | 82 + .../django-stubs/contrib/postgres/lookups.pyi | 18 + .../contrib/postgres/operations.pyi | 27 + .../django-stubs/contrib/postgres/search.pyi | 63 + .../django-stubs/contrib/postgres/signals.pyi | 5 + .../contrib/postgres/validators.pyi | 17 + .../contrib/redirects/__init__.pyi | 0 .../contrib/redirects/middleware.pyi | 10 + .../django-stubs/contrib/redirects/models.pyi | 6 + .../contrib/sessions/__init__.pyi | 0 .../contrib/sessions/backends/__init__.pyi | 0 .../contrib/sessions/backends/base.pyi | 40 + .../contrib/sessions/backends/cache.pyi | 11 + .../contrib/sessions/backends/cached_db.pyi | 11 + .../contrib/sessions/backends/db.pyi | 13 + .../contrib/sessions/backends/file.pyi | 9 + .../sessions/backends/signed_cookies.pyi | 3 + .../contrib/sessions/base_session.pyi | 19 + .../contrib/sessions/exceptions.pyi | 4 + .../contrib/sessions/management/__init__.pyi | 0 .../sessions/management/commands/__init__.pyi | 0 .../management/commands/clearsessions.pyi | 3 + .../contrib/sessions/middleware.pyi | 11 + .../django-stubs/contrib/sessions/models.pyi | 4 + .../contrib/sessions/serializers.pyi | 10 + .../contrib/sitemaps/__init__.pyi | 50 + .../contrib/sitemaps/management/__init__.pyi | 0 .../sitemaps/management/commands/__init__.pyi | 0 .../management/commands/ping_google.pyi | 3 + .../django-stubs/contrib/sitemaps/views.pyi | 23 + .../django-stubs/contrib/sites/__init__.pyi | 0 .../django-stubs/contrib/sites/apps.pyi | 3 + .../django-stubs/contrib/sites/management.pyi | 13 + .../django-stubs/contrib/sites/managers.pyi | 6 + .../django-stubs/contrib/sites/middleware.pyi | 5 + .../django-stubs/contrib/sites/models.pyi | 21 + .../django-stubs/contrib/sites/requests.pyi | 10 + .../django-stubs/contrib/sites/shortcuts.pyi | 7 + .../contrib/staticfiles/__init__.pyi | 0 .../django-stubs/contrib/staticfiles/apps.pyi | 6 + .../contrib/staticfiles/checks.pyi | 7 + .../contrib/staticfiles/finders.pyi | 43 + .../contrib/staticfiles/handlers.pyi | 12 + .../staticfiles/management/__init__.pyi | 0 .../management/commands/__init__.pyi | 0 .../management/commands/collectstatic.pyi | 28 + .../management/commands/findstatic.pyi | 3 + .../management/commands/runserver.pyi | 3 + .../contrib/staticfiles/storage.pyi | 55 + .../staticfiles/templatetags/__init__.pyi | 0 .../staticfiles/templatetags/staticfiles.pyi | 9 + .../contrib/staticfiles/testing.pyi | 3 + .../django-stubs/contrib/staticfiles/urls.pyi | 7 + .../contrib/staticfiles/utils.pyi | 8 + .../contrib/staticfiles/views.pyi | 6 + .../contrib/syndication/__init__.pyi | 0 .../contrib/syndication/views.pyi | 27 + .../django-stubs/core/__init__.pyi | 0 .../django-stubs/core/cache/__init__.pyi | 24 + .../core/cache/backends/__init__.pyi | 0 .../django-stubs/core/cache/backends/base.pyi | 41 + .../django-stubs/core/cache/backends/db.pyi | 22 + .../core/cache/backends/dummy.pyi | 6 + .../core/cache/backends/filebased.pyi | 7 + .../core/cache/backends/locmem.pyi | 6 + .../core/cache/backends/memcached.pyi | 10 + .../django-stubs/core/cache/utils.pyi | 5 + .../django-stubs/core/checks/__init__.pyi | 17 + .../django-stubs/core/checks/caches.pyi | 9 + .../django-stubs/core/checks/database.pyi | 3 + .../django-stubs/core/checks/messages.pyi | 34 + .../django-stubs/core/checks/model_checks.pyi | 8 + .../django-stubs/core/checks/registry.pyi | 36 + .../core/checks/security/__init__.pyi | 0 .../core/checks/security/base.pyi | 33 + .../core/checks/security/csrf.pyi | 11 + .../core/checks/security/sessions.pyi | 20 + .../django-stubs/core/checks/templates.pyi | 11 + .../django-stubs/core/checks/translation.pyi | 7 + .../django-stubs/core/checks/urls.pyi | 13 + .../django-stubs/core/exceptions.pyi | 43 + .../django-stubs/core/files/__init__.pyi | 3 + .../django-stubs/core/files/base.pyi | 41 + .../django-stubs/core/files/images.pyi | 13 + .../django-stubs/core/files/locks.pyi | 15 + .../django-stubs/core/files/move.pyi | 3 + .../django-stubs/core/files/storage.pyi | 47 + .../django-stubs/core/files/temp.pyi | 5 + .../django-stubs/core/files/uploadedfile.pyi | 46 + .../django-stubs/core/files/uploadhandler.pyi | 86 + .../django-stubs/core/files/utils.pyi | 23 + .../django-stubs/core/handlers/__init__.pyi | 0 .../django-stubs/core/handlers/base.pyi | 13 + .../django-stubs/core/handlers/exception.pyi | 12 + .../django-stubs/core/handlers/wsgi.pyi | 35 + .../django-stubs/core/mail/__init__.pyi | 48 + .../core/mail/backends/__init__.pyi | 0 .../django-stubs/core/mail/backends/base.pyi | 16 + .../core/mail/backends/console.pyi | 3 + .../django-stubs/core/mail/backends/dummy.pyi | 3 + .../core/mail/backends/filebased.pyi | 3 + .../core/mail/backends/locmem.pyi | 3 + .../django-stubs/core/mail/backends/smtp.pyi | 18 + .../django-stubs/core/mail/message.pyi | 110 + .../django-stubs/core/mail/utils.pyi | 6 + .../django-stubs/core/management/__init__.pyi | 20 + .../django-stubs/core/management/base.pyi | 78 + .../django-stubs/core/management/color.pyi | 25 + .../core/management/commands/__init__.pyi | 0 .../core/management/commands/dumpdata.pyi | 4 + .../core/management/commands/loaddata.pyi | 19 + .../core/management/commands/makemessages.pyi | 38 + .../core/management/commands/runserver.pyi | 7 + .../core/management/commands/testserver.pyi | 3 + .../django-stubs/core/management/sql.pyi | 9 + .../core/management/templates.pyi | 17 + .../django-stubs/core/management/utils.pyi | 10 + .../django-stubs/core/paginator.pyi | 62 + .../core/serializers/__init__.pyi | 31 + .../django-stubs/core/serializers/base.pyi | 87 + .../django-stubs/core/serializers/json.pyi | 17 + .../django-stubs/core/serializers/python.pyi | 15 + .../django-stubs/core/servers/__init__.pyi | 0 .../django-stubs/core/servers/basehttp.pyi | 36 + .../django-stubs/core/signals.pyi | 6 + .../django-stubs/core/signing.pyi | 42 + .../django-stubs/core/validators.pyi | 121 + .../django-stubs/django-stubs/core/wsgi.pyi | 3 + .../django-stubs/django-stubs/db/__init__.pyi | 31 + .../django-stubs/db/backends/__init__.pyi | 0 .../db/backends/base/__init__.pyi | 0 .../django-stubs/db/backends/base/base.pyi | 102 + .../django-stubs/db/backends/base/client.pyi | 9 + .../db/backends/base/creation.pyi | 24 + .../db/backends/base/features.pyi | 100 + .../db/backends/base/introspection.pyi | 27 + .../db/backends/base/operations.pyi | 104 + .../django-stubs/db/backends/base/schema.pyi | 77 + .../db/backends/base/validation.pyi | 11 + .../db/backends/ddl_references.pyi | 66 + .../db/backends/dummy/__init__.pyi | 0 .../django-stubs/db/backends/dummy/base.pyi | 31 + .../db/backends/mysql/__init__.pyi | 0 .../django-stubs/db/backends/mysql/client.pyi | 11 + .../db/backends/postgresql/__init__.pyi | 0 .../db/backends/postgresql/base.pyi | 17 + .../db/backends/postgresql/client.pyi | 9 + .../db/backends/postgresql/creation.pyi | 3 + .../db/backends/postgresql/operations.pyi | 3 + .../django-stubs/db/backends/signals.pyi | 3 + .../db/backends/sqlite3/__init__.pyi | 0 .../django-stubs/db/backends/sqlite3/base.pyi | 14 + .../db/backends/sqlite3/creation.pyi | 3 + .../db/backends/sqlite3/features.pyi | 3 + .../db/backends/sqlite3/introspection.pyi | 13 + .../db/backends/sqlite3/operations.pyi | 3 + .../db/backends/sqlite3/schema.pyi | 3 + .../django-stubs/db/backends/utils.pyi | 47 + .../django-stubs/db/migrations/__init__.pyi | 6 + .../db/migrations/autodetector.pyi | 67 + .../django-stubs/db/migrations/exceptions.pyi | 20 + .../django-stubs/db/migrations/executor.pyi | 40 + .../django-stubs/db/migrations/graph.pyi | 54 + .../django-stubs/db/migrations/loader.pyi | 31 + .../django-stubs/db/migrations/migration.pyi | 28 + .../db/migrations/operations/__init__.pyi | 22 + .../db/migrations/operations/base.pyi | 17 + .../db/migrations/operations/fields.pyi | 32 + .../db/migrations/operations/models.pyi | 87 + .../db/migrations/operations/special.pyi | 43 + .../db/migrations/operations/utils.pyi | 5 + .../django-stubs/db/migrations/optimizer.pyi | 7 + .../django-stubs/db/migrations/questioner.pyi | 26 + .../django-stubs/db/migrations/recorder.pyi | 22 + .../django-stubs/db/migrations/serializer.pyi | 46 + .../django-stubs/db/migrations/state.pyi | 68 + .../db/migrations/topological_sort.pyi | 8 + .../django-stubs/db/migrations/utils.pyi | 10 + .../django-stubs/db/migrations/writer.pyi | 40 + .../django-stubs/db/models/__init__.pyi | 136 + .../django-stubs/db/models/aggregates.pyi | 17 + .../django-stubs/db/models/base.pyi | 60 + .../django-stubs/db/models/constraints.pyi | 27 + .../django-stubs/db/models/deletion.pyi | 30 + .../django-stubs/db/models/enums.pyi | 30 + .../django-stubs/db/models/expressions.pyi | 219 + .../db/models/fields/__init__.pyi | 409 ++ .../django-stubs/db/models/fields/files.pyi | 101 + .../django-stubs/db/models/fields/mixins.pyi | 12 + .../django-stubs/db/models/fields/proxy.pyi | 6 + .../django-stubs/db/models/fields/related.pyi | 243 + .../db/models/fields/related_descriptors.pyi | 70 + .../db/models/fields/related_lookups.pyi | 48 + .../db/models/fields/reverse_related.pyi | 110 + .../db/models/functions/__init__.pyi | 93 + .../db/models/functions/comparison.pyi | 12 + .../db/models/functions/datetime.pyi | 32 + .../django-stubs/db/models/functions/math.pyi | 26 + .../db/models/functions/mixins.pyi | 3 + .../django-stubs/db/models/functions/text.pyi | 65 + .../db/models/functions/window.pyi | 26 + .../django-stubs/db/models/indexes.pyi | 34 + .../django-stubs/db/models/lookups.pyi | 104 + .../django-stubs/db/models/manager.pyi | 45 + .../django-stubs/db/models/options.pyi | 123 + .../django-stubs/db/models/query.pyi | 213 + .../django-stubs/db/models/query_utils.pyi | 79 + .../django-stubs/db/models/signals.pyi | 34 + .../django-stubs/db/models/sql/__init__.pyi | 8 + .../django-stubs/db/models/sql/compiler.pyi | 109 + .../django-stubs/db/models/sql/constants.pyi | 14 + .../db/models/sql/datastructures.pyi | 49 + .../django-stubs/db/models/sql/query.pyi | 194 + .../django-stubs/db/models/sql/subqueries.pyi | 45 + .../django-stubs/db/models/sql/where.pyi | 46 + .../django-stubs/db/models/utils.pyi | 5 + .../django-stubs/db/transaction.pyi | 49 + .../django-stubs/django-stubs/db/utils.pyi | 35 + .../django-stubs/dispatch/__init__.pyi | 1 + .../django-stubs/dispatch/dispatcher.pyi | 23 + .../django-stubs/forms/__init__.pyi | 86 + .../django-stubs/forms/boundfield.pyi | 60 + .../django-stubs/forms/fields.pyi | 394 ++ .../django-stubs/django-stubs/forms/forms.pyi | 78 + .../django-stubs/forms/formsets.pyi | 89 + .../django-stubs/forms/models.pyi | 289 + .../django-stubs/forms/renderers.pyi | 26 + .../django-stubs/django-stubs/forms/utils.pyi | 33 + .../django-stubs/forms/widgets.pyi | 172 + .../django-stubs/http/__init__.pyi | 26 + .../django-stubs/django-stubs/http/cookie.pyi | 5 + .../django-stubs/http/multipartparser.pyi | 54 + .../django-stubs/http/request.pyi | 111 + .../django-stubs/http/response.pyi | 137 + .../django-stubs/middleware/__init__.pyi | 0 .../django-stubs/middleware/cache.pyi | 31 + .../django-stubs/middleware/clickjacking.pyi | 7 + .../django-stubs/middleware/common.pyi | 17 + .../django-stubs/middleware/csrf.pyi | 33 + .../django-stubs/middleware/gzip.pyi | 10 + .../django-stubs/middleware/http.pyi | 7 + .../django-stubs/middleware/locale.pyi | 10 + .../django-stubs/middleware/security.pyi | 17 + .../django-stubs/django-stubs/shortcuts.pyi | 54 + .../django-stubs/template/__init__.pyi | 16 + .../template/backends/__init__.pyi | 0 .../django-stubs/template/backends/base.pyi | 16 + .../django-stubs/template/backends/django.pyi | 16 + .../django-stubs/template/backends/dummy.pyi | 14 + .../django-stubs/template/backends/jinja2.pyi | 18 + .../django-stubs/template/backends/utils.pyi | 9 + .../django-stubs/template/base.pyi | 174 + .../django-stubs/template/context.pyi | 76 + .../template/context_processors.pyi | 13 + .../django-stubs/template/defaultfilters.pyi | 66 + .../django-stubs/template/defaulttags.pyi | 204 + .../django-stubs/template/engine.pyi | 53 + .../django-stubs/template/exceptions.pyi | 18 + .../django-stubs/template/library.pyi | 97 + .../django-stubs/template/loader.pyi | 14 + .../django-stubs/template/loader_tags.pyi | 68 + .../template/loaders/__init__.pyi | 0 .../template/loaders/app_directories.pyi | 3 + .../django-stubs/template/loaders/base.pyi | 12 + .../django-stubs/template/loaders/cached.pyi | 14 + .../template/loaders/filesystem.pyi | 12 + .../django-stubs/template/loaders/locmem.pyi | 11 + .../django-stubs/template/response.pyi | 68 + .../django-stubs/template/smartif.pyi | 43 + .../django-stubs/template/utils.pyi | 16 + .../django-stubs/templatetags/__init__.pyi | 0 .../django-stubs/templatetags/cache.pyi | 24 + .../django-stubs/templatetags/i18n.pyi | 83 + .../django-stubs/templatetags/l10n.pyi | 17 + .../django-stubs/templatetags/static.pyi | 33 + .../django-stubs/templatetags/tz.pyi | 33 + .../django-stubs/test/__init__.pyi | 20 + .../django-stubs/django-stubs/test/client.pyi | 132 + .../django-stubs/django-stubs/test/html.pyi | 38 + .../django-stubs/django-stubs/test/runner.pyi | 133 + .../django-stubs/test/selenium.pyi | 14 + .../django-stubs/test/signals.pyi | 21 + .../django-stubs/test/testcases.pyi | 229 + .../django-stubs/django-stubs/test/utils.pyi | 155 + .../django-stubs/urls/__init__.pyi | 36 + .../django-stubs/django-stubs/urls/base.pyi | 23 + .../django-stubs/django-stubs/urls/conf.pyi | 8 + .../django-stubs/urls/converters.pyi | 27 + .../django-stubs/urls/exceptions.pyi | 4 + .../django-stubs/urls/resolvers.pyi | 110 + .../django-stubs/django-stubs/urls/utils.pyi | 4 + .../django-stubs/utils/__init__.pyi | 0 .../django-stubs/django-stubs/utils/_os.pyi | 11 + .../django-stubs/utils/archive.pyi | 30 + .../django-stubs/utils/autoreload.pyi | 67 + .../django-stubs/utils/baseconv.pyi | 24 + .../django-stubs/django-stubs/utils/cache.pyi | 31 + .../django-stubs/utils/crypto.pyi | 15 + .../django-stubs/utils/datastructures.pyi | 75 + .../django-stubs/utils/dateformat.pyi | 63 + .../django-stubs/utils/dateparse.pyi | 14 + .../django-stubs/django-stubs/utils/dates.pyi | 8 + .../django-stubs/utils/datetime_safe.pyi | 10 + .../django-stubs/utils/deconstruct.pyi | 3 + .../django-stubs/utils/decorators.pyi | 20 + .../django-stubs/utils/deprecation.pyi | 35 + .../django-stubs/utils/duration.pyi | 5 + .../django-stubs/utils/encoding.pyi | 59 + .../django-stubs/utils/feedgenerator.pyi | 76 + .../django-stubs/utils/formats.pyi | 31 + .../django-stubs/utils/functional.pyi | 59 + .../django-stubs/utils/hashable.pyi | 3 + .../django-stubs/django-stubs/utils/html.pyi | 37 + .../django-stubs/django-stubs/utils/http.pyi | 37 + .../django-stubs/utils/inspect.pyi | 8 + .../django-stubs/django-stubs/utils/ipv6.pyi | 4 + .../django-stubs/utils/itercompat.pyi | 3 + .../django-stubs/django-stubs/utils/jslex.pyi | 26 + .../django-stubs/django-stubs/utils/log.pyi | 45 + .../django-stubs/utils/lorem_ipsum.pyi | 10 + .../django-stubs/utils/module_loading.pyi | 6 + .../django-stubs/utils/numberformat.pyi | 12 + .../django-stubs/utils/regex_helper.pyi | 16 + .../django-stubs/utils/safestring.pyi | 26 + .../django-stubs/django-stubs/utils/six.pyi | 106 + .../django-stubs/utils/termcolors.pyi | 18 + .../django-stubs/django-stubs/utils/text.pyi | 47 + .../django-stubs/utils/timesince.pyi | 10 + .../django-stubs/utils/timezone.pyi | 62 + .../django-stubs/utils/topological_sort.pyi | 6 + .../utils/translation/__init__.pyi | 72 + .../utils/translation/reloader.pyi | 7 + .../utils/translation/template.pyi | 14 + .../utils/translation/trans_null.pyi | 25 + .../utils/translation/trans_real.pyi | 42 + .../django-stubs/django-stubs/utils/tree.pyi | 21 + .../django-stubs/utils/version.pyi | 13 + .../django-stubs/utils/xmlutils.pyi | 11 + .../django-stubs/views/__init__.pyi | 1 + .../django-stubs/django-stubs/views/csrf.pyi | 7 + .../django-stubs/django-stubs/views/debug.pyi | 66 + .../views/decorators/__init__.pyi | 0 .../django-stubs/views/decorators/cache.pyi | 7 + .../views/decorators/clickjacking.pyi | 7 + .../django-stubs/views/decorators/csrf.pyi | 19 + .../django-stubs/views/decorators/debug.pyi | 4 + .../django-stubs/views/decorators/gzip.pyi | 5 + .../django-stubs/views/decorators/http.pyi | 12 + .../django-stubs/views/decorators/vary.pyi | 6 + .../django-stubs/views/defaults.pyi | 23 + .../django-stubs/views/generic/__init__.pyi | 15 + .../django-stubs/views/generic/base.pyi | 44 + .../django-stubs/views/generic/dates.pyi | 82 + .../django-stubs/views/generic/detail.pyi | 28 + .../django-stubs/views/generic/edit.pyi | 46 + .../django-stubs/views/generic/list.pyi | 37 + .../django-stubs/django-stubs/views/i18n.pyi | 31 + .../django-stubs/views/static.pyi | 12 + .../jedi/third_party/typeshed/LICENSE | 238 + .../typeshed/stdlib/2/BaseHTTPServer.pyi | 47 + .../typeshed/stdlib/2/CGIHTTPServer.pyi | 8 + .../typeshed/stdlib/2/ConfigParser.pyi | 99 + .../third_party/typeshed/stdlib/2/Cookie.pyi | 40 + .../typeshed/stdlib/2/HTMLParser.pyi | 31 + .../third_party/typeshed/stdlib/2/Queue.pyi | 31 + .../typeshed/stdlib/2/SimpleHTTPServer.pyi | 16 + .../typeshed/stdlib/2/SocketServer.pyi | 99 + .../typeshed/stdlib/2/StringIO.pyi | 30 + .../typeshed/stdlib/2/UserDict.pyi | 44 + .../typeshed/stdlib/2/UserList.pyi | 19 + .../typeshed/stdlib/2/UserString.pyi | 75 + .../typeshed/stdlib/2/__builtin__.pyi | 1650 +++++ .../third_party/typeshed/stdlib/2/_ast.pyi | 330 + .../typeshed/stdlib/2/_collections.pyi | 38 + .../typeshed/stdlib/2/_functools.pyi | 20 + .../typeshed/stdlib/2/_hotshot.pyi | 24 + .../third_party/typeshed/stdlib/2/_io.pyi | 186 + .../third_party/typeshed/stdlib/2/_json.pyi | 7 + .../third_party/typeshed/stdlib/2/_md5.pyi | 13 + .../third_party/typeshed/stdlib/2/_sha.pyi | 15 + .../third_party/typeshed/stdlib/2/_sha256.pyi | 23 + .../third_party/typeshed/stdlib/2/_sha512.pyi | 23 + .../third_party/typeshed/stdlib/2/_socket.pyi | 283 + .../third_party/typeshed/stdlib/2/_sre.pyi | 55 + .../third_party/typeshed/stdlib/2/_struct.pyi | 22 + .../typeshed/stdlib/2/_symtable.pyi | 39 + .../typeshed/stdlib/2/_threading_local.pyi | 12 + .../third_party/typeshed/stdlib/2/abc.pyi | 31 + .../third_party/typeshed/stdlib/2/ast.pyi | 28 + .../third_party/typeshed/stdlib/2/atexit.pyi | 5 + .../third_party/typeshed/stdlib/2/cPickle.pyi | 32 + .../typeshed/stdlib/2/cStringIO.pyi | 54 + .../typeshed/stdlib/2/collections.pyi | 120 + .../typeshed/stdlib/2/commands.pyi | 12 + .../typeshed/stdlib/2/compileall.pyi | 19 + .../typeshed/stdlib/2/cookielib.pyi | 112 + .../typeshed/stdlib/2/copy_reg.pyi | 14 + .../typeshed/stdlib/2/dircache.pyi | 10 + .../typeshed/stdlib/2/distutils/__init__.pyi | 0 .../stdlib/2/distutils/emxccompiler.pyi | 5 + .../typeshed/stdlib/2/dummy_thread.pyi | 21 + .../typeshed/stdlib/2/email/MIMEText.pyi | 4 + .../typeshed/stdlib/2/email/__init__.pyi | 6 + .../typeshed/stdlib/2/email/_parseaddr.pyi | 40 + .../typeshed/stdlib/2/email/base64mime.pyi | 8 + .../typeshed/stdlib/2/email/charset.pyi | 26 + .../typeshed/stdlib/2/email/encoders.pyi | 4 + .../typeshed/stdlib/2/email/feedparser.pyi | 18 + .../typeshed/stdlib/2/email/generator.pyi | 9 + .../typeshed/stdlib/2/email/header.pyi | 11 + .../typeshed/stdlib/2/email/iterators.pyi | 5 + .../typeshed/stdlib/2/email/message.pyi | 45 + .../typeshed/stdlib/2/email/mime/__init__.pyi | 0 .../stdlib/2/email/mime/application.pyi | 11 + .../typeshed/stdlib/2/email/mime/audio.pyi | 5 + .../typeshed/stdlib/2/email/mime/base.pyi | 4 + .../typeshed/stdlib/2/email/mime/image.pyi | 5 + .../typeshed/stdlib/2/email/mime/message.pyi | 5 + .../stdlib/2/email/mime/multipart.pyi | 4 + .../stdlib/2/email/mime/nonmultipart.pyi | 4 + .../typeshed/stdlib/2/email/mime/text.pyi | 4 + .../typeshed/stdlib/2/email/parser.pyi | 10 + .../typeshed/stdlib/2/email/quoprimime.pyi | 18 + .../typeshed/stdlib/2/email/utils.pyi | 19 + .../typeshed/stdlib/2/encodings/__init__.pyi | 6 + .../typeshed/stdlib/2/encodings/utf_8.pyi | 15 + .../typeshed/stdlib/2/exceptions.pyi | 48 + .../third_party/typeshed/stdlib/2/fcntl.pyi | 87 + .../third_party/typeshed/stdlib/2/fnmatch.pyi | 8 + .../typeshed/stdlib/2/functools.pyi | 33 + .../typeshed/stdlib/2/future_builtins.pyi | 14 + .../jedi/third_party/typeshed/stdlib/2/gc.pyi | 29 + .../third_party/typeshed/stdlib/2/getopt.pyi | 12 + .../third_party/typeshed/stdlib/2/getpass.pyi | 8 + .../third_party/typeshed/stdlib/2/gettext.pyi | 41 + .../third_party/typeshed/stdlib/2/glob.pyi | 7 + .../third_party/typeshed/stdlib/2/gzip.pyi | 37 + .../third_party/typeshed/stdlib/2/hashlib.pyi | 31 + .../third_party/typeshed/stdlib/2/heapq.pyi | 18 + .../typeshed/stdlib/2/htmlentitydefs.pyi | 5 + .../third_party/typeshed/stdlib/2/httplib.pyi | 205 + .../third_party/typeshed/stdlib/2/imp.pyi | 35 + .../typeshed/stdlib/2/importlib.pyi | 4 + .../third_party/typeshed/stdlib/2/inspect.pyi | 129 + .../jedi/third_party/typeshed/stdlib/2/io.pyi | 42 + .../typeshed/stdlib/2/itertools.pyi | 163 + .../third_party/typeshed/stdlib/2/json.pyi | 96 + .../typeshed/stdlib/2/markupbase.pyi | 9 + .../third_party/typeshed/stdlib/2/md5.pyi | 6 + .../typeshed/stdlib/2/mimetools.pyi | 27 + .../stdlib/2/multiprocessing/__init__.pyi | 50 + .../2/multiprocessing/dummy/__init__.pyi | 51 + .../2/multiprocessing/dummy/connection.pyi | 26 + .../stdlib/2/multiprocessing/pool.pyi | 59 + .../stdlib/2/multiprocessing/process.pyi | 36 + .../stdlib/2/multiprocessing/util.pyi | 29 + .../third_party/typeshed/stdlib/2/mutex.pyi | 14 + .../typeshed/stdlib/2/nturl2path.pyi | 4 + .../typeshed/stdlib/2/os/__init__.pyi | 358 + .../third_party/typeshed/stdlib/2/os/path.pyi | 177 + .../typeshed/stdlib/2/os2emxpath.pyi | 177 + .../third_party/typeshed/stdlib/2/pipes.pyi | 13 + .../typeshed/stdlib/2/platform.pyi | 45 + .../third_party/typeshed/stdlib/2/popen2.pyi | 28 + .../third_party/typeshed/stdlib/2/posix.pyi | 201 + .../third_party/typeshed/stdlib/2/random.pyi | 77 + .../jedi/third_party/typeshed/stdlib/2/re.pyi | 100 + .../third_party/typeshed/stdlib/2/repr.pyi | 33 + .../typeshed/stdlib/2/resource.pyi | 45 + .../third_party/typeshed/stdlib/2/rfc822.pyi | 79 + .../typeshed/stdlib/2/robotparser.pyi | 7 + .../third_party/typeshed/stdlib/2/runpy.pyi | 17 + .../third_party/typeshed/stdlib/2/sets.pyi | 61 + .../third_party/typeshed/stdlib/2/sha.pyi | 11 + .../third_party/typeshed/stdlib/2/shelve.pyi | 33 + .../third_party/typeshed/stdlib/2/shlex.pyi | 31 + .../third_party/typeshed/stdlib/2/signal.pyi | 68 + .../third_party/typeshed/stdlib/2/smtplib.pyi | 86 + .../third_party/typeshed/stdlib/2/spwd.pyi | 15 + .../typeshed/stdlib/2/sre_constants.pyi | 94 + .../typeshed/stdlib/2/sre_parse.pyi | 63 + .../third_party/typeshed/stdlib/2/stat.pyi | 59 + .../third_party/typeshed/stdlib/2/string.pyi | 75 + .../typeshed/stdlib/2/stringold.pyi | 46 + .../third_party/typeshed/stdlib/2/strop.pyi | 29 + .../typeshed/stdlib/2/subprocess.pyi | 120 + .../third_party/typeshed/stdlib/2/symbol.pyi | 91 + .../third_party/typeshed/stdlib/2/sys.pyi | 136 + .../typeshed/stdlib/2/tempfile.pyi | 111 + .../typeshed/stdlib/2/textwrap.pyi | 61 + .../third_party/typeshed/stdlib/2/thread.pyi | 28 + .../third_party/typeshed/stdlib/2/toaiff.pyi | 14 + .../typeshed/stdlib/2/tokenize.pyi | 136 + .../third_party/typeshed/stdlib/2/types.pyi | 185 + .../third_party/typeshed/stdlib/2/typing.pyi | 494 ++ .../typeshed/stdlib/2/unittest.pyi | 282 + .../third_party/typeshed/stdlib/2/urllib.pyi | 134 + .../third_party/typeshed/stdlib/2/urllib2.pyi | 182 + .../typeshed/stdlib/2/urlparse.pyi | 66 + .../third_party/typeshed/stdlib/2/user.pyi | 9 + .../third_party/typeshed/stdlib/2/whichdb.pyi | 5 + .../typeshed/stdlib/2/xmlrpclib.pyi | 231 + .../typeshed/stdlib/2and3/__future__.pyi | 25 + .../typeshed/stdlib/2and3/_bisect.pyi | 11 + .../typeshed/stdlib/2and3/_codecs.pyi | 75 + .../typeshed/stdlib/2and3/_csv.pyi | 49 + .../typeshed/stdlib/2and3/_curses.pyi | 461 ++ .../typeshed/stdlib/2and3/_heapq.pyi | 15 + .../typeshed/stdlib/2and3/_random.pyi | 17 + .../typeshed/stdlib/2and3/_warnings.pyi | 34 + .../typeshed/stdlib/2and3/_weakref.pyi | 28 + .../typeshed/stdlib/2and3/_weakrefset.pyi | 43 + .../typeshed/stdlib/2and3/aifc.pyi | 85 + .../typeshed/stdlib/2and3/argparse.pyi | 402 ++ .../typeshed/stdlib/2and3/array.pyi | 73 + .../typeshed/stdlib/2and3/asynchat.pyi | 41 + .../typeshed/stdlib/2and3/asyncore.pyi | 145 + .../typeshed/stdlib/2and3/audioop.pyi | 42 + .../typeshed/stdlib/2and3/base64.pyi | 38 + .../third_party/typeshed/stdlib/2and3/bdb.pyi | 94 + .../typeshed/stdlib/2and3/binascii.pyi | 42 + .../typeshed/stdlib/2and3/binhex.pyi | 48 + .../typeshed/stdlib/2and3/bisect.pyi | 13 + .../typeshed/stdlib/2and3/builtins.pyi | 1650 +++++ .../third_party/typeshed/stdlib/2and3/bz2.pyi | 48 + .../typeshed/stdlib/2and3/cProfile.pyi | 27 + .../typeshed/stdlib/2and3/calendar.pyi | 122 + .../third_party/typeshed/stdlib/2and3/cgi.pyi | 122 + .../typeshed/stdlib/2and3/cgitb.pyi | 33 + .../typeshed/stdlib/2and3/chunk.pyi | 23 + .../typeshed/stdlib/2and3/cmath.pyi | 42 + .../third_party/typeshed/stdlib/2and3/cmd.pyi | 41 + .../typeshed/stdlib/2and3/code.pyi | 38 + .../typeshed/stdlib/2and3/codecs.pyi | 244 + .../typeshed/stdlib/2and3/codeop.pyi | 17 + .../typeshed/stdlib/2and3/colorsys.pyi | 15 + .../typeshed/stdlib/2and3/contextlib.pyi | 111 + .../typeshed/stdlib/2and3/copy.pyi | 14 + .../typeshed/stdlib/2and3/crypt.pyi | 22 + .../third_party/typeshed/stdlib/2and3/csv.pyi | 105 + .../typeshed/stdlib/2and3/ctypes/__init__.pyi | 292 + .../typeshed/stdlib/2and3/ctypes/util.pyi | 8 + .../typeshed/stdlib/2and3/ctypes/wintypes.pyi | 209 + .../typeshed/stdlib/2and3/curses/__init__.pyi | 15 + .../typeshed/stdlib/2and3/curses/ascii.pyi | 62 + .../typeshed/stdlib/2and3/curses/panel.pyi | 20 + .../typeshed/stdlib/2and3/curses/textpad.pyi | 11 + .../typeshed/stdlib/2and3/datetime.pyi | 315 + .../typeshed/stdlib/2and3/decimal.pyi | 315 + .../typeshed/stdlib/2and3/difflib.pyi | 86 + .../third_party/typeshed/stdlib/2and3/dis.pyi | 73 + .../stdlib/2and3/distutils/__init__.pyi | 0 .../stdlib/2and3/distutils/archive_util.pyi | 12 + .../stdlib/2and3/distutils/bcppcompiler.pyi | 6 + .../stdlib/2and3/distutils/ccompiler.pyi | 119 + .../typeshed/stdlib/2and3/distutils/cmd.pyi | 40 + .../2and3/distutils/command/__init__.pyi | 0 .../stdlib/2and3/distutils/command/bdist.pyi | 0 .../2and3/distutils/command/bdist_dumb.pyi | 0 .../2and3/distutils/command/bdist_msi.pyi | 6 + .../distutils/command/bdist_packager.pyi | 0 .../2and3/distutils/command/bdist_rpm.pyi | 0 .../2and3/distutils/command/bdist_wininst.pyi | 0 .../stdlib/2and3/distutils/command/build.pyi | 0 .../2and3/distutils/command/build_clib.pyi | 0 .../2and3/distutils/command/build_ext.pyi | 0 .../2and3/distutils/command/build_py.pyi | 10 + .../2and3/distutils/command/build_scripts.pyi | 0 .../stdlib/2and3/distutils/command/check.pyi | 0 .../stdlib/2and3/distutils/command/clean.pyi | 0 .../stdlib/2and3/distutils/command/config.pyi | 0 .../2and3/distutils/command/install.pyi | 14 + .../2and3/distutils/command/install_data.pyi | 0 .../distutils/command/install_headers.pyi | 0 .../2and3/distutils/command/install_lib.pyi | 0 .../distutils/command/install_scripts.pyi | 0 .../2and3/distutils/command/register.pyi | 0 .../stdlib/2and3/distutils/command/sdist.pyi | 0 .../typeshed/stdlib/2and3/distutils/core.pyi | 50 + .../2and3/distutils/cygwinccompiler.pyi | 7 + .../typeshed/stdlib/2and3/distutils/debug.pyi | 3 + .../stdlib/2and3/distutils/dep_util.pyi | 8 + .../stdlib/2and3/distutils/dir_util.pyi | 15 + .../typeshed/stdlib/2and3/distutils/dist.pyi | 11 + .../stdlib/2and3/distutils/errors.pyi | 19 + .../stdlib/2and3/distutils/extension.pyi | 39 + .../stdlib/2and3/distutils/fancy_getopt.pyi | 27 + .../stdlib/2and3/distutils/file_util.pyi | 12 + .../stdlib/2and3/distutils/filelist.pyi | 3 + .../typeshed/stdlib/2and3/distutils/log.pyi | 28 + .../stdlib/2and3/distutils/msvccompiler.pyi | 6 + .../typeshed/stdlib/2and3/distutils/spawn.pyi | 8 + .../stdlib/2and3/distutils/sysconfig.pyi | 19 + .../stdlib/2and3/distutils/text_file.pyi | 18 + .../stdlib/2and3/distutils/unixccompiler.pyi | 6 + .../typeshed/stdlib/2and3/distutils/util.pyi | 20 + .../stdlib/2and3/distutils/version.pyi | 54 + .../typeshed/stdlib/2and3/doctest.pyi | 160 + .../stdlib/2and3/ensurepip/__init__.pyi | 10 + .../typeshed/stdlib/2and3/errno.pyi | 140 + .../typeshed/stdlib/2and3/filecmp.pyi | 48 + .../typeshed/stdlib/2and3/fileinput.pyi | 82 + .../typeshed/stdlib/2and3/formatter.pyi | 105 + .../typeshed/stdlib/2and3/fractions.pyi | 98 + .../typeshed/stdlib/2and3/ftplib.pyi | 174 + .../typeshed/stdlib/2and3/genericpath.pyi | 21 + .../third_party/typeshed/stdlib/2and3/grp.pyi | 11 + .../typeshed/stdlib/2and3/hmac.pyi | 38 + .../typeshed/stdlib/2and3/imaplib.pyi | 140 + .../typeshed/stdlib/2and3/imghdr.pyi | 16 + .../typeshed/stdlib/2and3/keyword.pyi | 6 + .../stdlib/2and3/lib2to3/__init__.pyi | 1 + .../stdlib/2and3/lib2to3/pgen2/__init__.pyi | 10 + .../stdlib/2and3/lib2to3/pgen2/driver.pyi | 24 + .../stdlib/2and3/lib2to3/pgen2/grammar.pyi | 29 + .../stdlib/2and3/lib2to3/pgen2/literals.pyi | 9 + .../stdlib/2and3/lib2to3/pgen2/parse.pyi | 29 + .../stdlib/2and3/lib2to3/pgen2/pgen.pyi | 50 + .../stdlib/2and3/lib2to3/pgen2/token.pyi | 73 + .../stdlib/2and3/lib2to3/pgen2/tokenize.pyi | 30 + .../typeshed/stdlib/2and3/lib2to3/pygram.pyi | 116 + .../typeshed/stdlib/2and3/lib2to3/pytree.pyi | 86 + .../typeshed/stdlib/2and3/linecache.pyi | 12 + .../typeshed/stdlib/2and3/locale.pyi | 113 + .../stdlib/2and3/logging/__init__.pyi | 438 ++ .../typeshed/stdlib/2and3/logging/config.pyi | 33 + .../stdlib/2and3/logging/handlers.pyi | 215 + .../typeshed/stdlib/2and3/macpath.pyi | 171 + .../typeshed/stdlib/2and3/mailbox.pyi | 199 + .../typeshed/stdlib/2and3/mailcap.pyi | 7 + .../typeshed/stdlib/2and3/marshal.pyi | 8 + .../typeshed/stdlib/2and3/math.pyi | 83 + .../typeshed/stdlib/2and3/mimetypes.pyi | 38 + .../typeshed/stdlib/2and3/mmap.pyi | 102 + .../typeshed/stdlib/2and3/modulefinder.pyi | 48 + .../typeshed/stdlib/2and3/netrc.pyi | 19 + .../third_party/typeshed/stdlib/2and3/nis.pyi | 10 + .../typeshed/stdlib/2and3/ntpath.pyi | 177 + .../typeshed/stdlib/2and3/numbers.pyi | 144 + .../typeshed/stdlib/2and3/opcode.pyi | 23 + .../typeshed/stdlib/2and3/operator.pyi | 227 + .../typeshed/stdlib/2and3/optparse.pyi | 228 + .../third_party/typeshed/stdlib/2and3/pdb.pyi | 62 + .../typeshed/stdlib/2and3/pickle.pyi | 141 + .../typeshed/stdlib/2and3/pickletools.pyi | 145 + .../typeshed/stdlib/2and3/pkgutil.pyi | 38 + .../typeshed/stdlib/2and3/plistlib.pyi | 65 + .../typeshed/stdlib/2and3/poplib.pyi | 77 + .../typeshed/stdlib/2and3/posixpath.pyi | 177 + .../typeshed/stdlib/2and3/pprint.pyi | 40 + .../typeshed/stdlib/2and3/profile.pyi | 27 + .../typeshed/stdlib/2and3/pstats.pyi | 39 + .../third_party/typeshed/stdlib/2and3/pty.pyi | 20 + .../third_party/typeshed/stdlib/2and3/pwd.pyi | 14 + .../typeshed/stdlib/2and3/py_compile.pyi | 28 + .../typeshed/stdlib/2and3/pyclbr.pyi | 40 + .../typeshed/stdlib/2and3/pydoc.pyi | 180 + .../stdlib/2and3/pyexpat/__init__.pyi | 75 + .../typeshed/stdlib/2and3/pyexpat/errors.pyi | 44 + .../typeshed/stdlib/2and3/pyexpat/model.pyi | 11 + .../typeshed/stdlib/2and3/quopri.pyi | 8 + .../typeshed/stdlib/2and3/readline.pyi | 41 + .../typeshed/stdlib/2and3/rlcompleter.pyi | 14 + .../typeshed/stdlib/2and3/sched.pyi | 26 + .../typeshed/stdlib/2and3/select.pyi | 138 + .../typeshed/stdlib/2and3/shutil.pyi | 148 + .../typeshed/stdlib/2and3/site.pyi | 17 + .../typeshed/stdlib/2and3/smtpd.pyi | 78 + .../typeshed/stdlib/2and3/sndhdr.pyi | 24 + .../typeshed/stdlib/2and3/socket.pyi | 767 +++ .../stdlib/2and3/sqlite3/__init__.pyi | 1 + .../typeshed/stdlib/2and3/sqlite3/dbapi2.pyi | 291 + .../typeshed/stdlib/2and3/sre_compile.pyi | 18 + .../third_party/typeshed/stdlib/2and3/ssl.pyi | 345 + .../typeshed/stdlib/2and3/stringprep.pyi | 23 + .../typeshed/stdlib/2and3/struct.pyi | 44 + .../typeshed/stdlib/2and3/sunau.pyi | 86 + .../typeshed/stdlib/2and3/symtable.pyi | 45 + .../typeshed/stdlib/2and3/sysconfig.pyi | 19 + .../typeshed/stdlib/2and3/syslog.pyi | 44 + .../typeshed/stdlib/2and3/tabnanny.pyi | 22 + .../typeshed/stdlib/2and3/tarfile.pyi | 186 + .../typeshed/stdlib/2and3/telnetlib.pyi | 115 + .../typeshed/stdlib/2and3/termios.pyi | 248 + .../typeshed/stdlib/2and3/threading.pyi | 196 + .../typeshed/stdlib/2and3/time.pyi | 113 + .../typeshed/stdlib/2and3/timeit.pyi | 34 + .../typeshed/stdlib/2and3/token.pyi | 75 + .../typeshed/stdlib/2and3/trace.pyi | 35 + .../typeshed/stdlib/2and3/traceback.pyi | 120 + .../third_party/typeshed/stdlib/2and3/tty.pyi | 17 + .../typeshed/stdlib/2and3/turtle.pyi | 501 ++ .../typeshed/stdlib/2and3/unicodedata.pyi | 40 + .../third_party/typeshed/stdlib/2and3/uu.pyi | 13 + .../typeshed/stdlib/2and3/uuid.pyi | 90 + .../typeshed/stdlib/2and3/warnings.pyi | 41 + .../typeshed/stdlib/2and3/wave.pyi | 75 + .../typeshed/stdlib/2and3/weakref.pyi | 110 + .../typeshed/stdlib/2and3/webbrowser.pyi | 98 + .../stdlib/2and3/wsgiref/__init__.pyi | 0 .../stdlib/2and3/wsgiref/handlers.pyi | 87 + .../typeshed/stdlib/2and3/wsgiref/headers.pyi | 31 + .../stdlib/2and3/wsgiref/simple_server.pyi | 40 + .../typeshed/stdlib/2and3/wsgiref/types.pyi | 44 + .../typeshed/stdlib/2and3/wsgiref/util.pyi | 23 + .../stdlib/2and3/wsgiref/validate.pyi | 53 + .../typeshed/stdlib/2and3/xdrlib.pyi | 56 + .../typeshed/stdlib/2and3/xml/__init__.pyi | 1 + .../stdlib/2and3/xml/etree/ElementInclude.pyi | 17 + .../stdlib/2and3/xml/etree/ElementPath.pyi | 33 + .../stdlib/2and3/xml/etree/ElementTree.pyi | 259 + .../stdlib/2and3/xml/etree/__init__.pyi | 0 .../stdlib/2and3/xml/etree/cElementTree.pyi | 3 + .../stdlib/2and3/xml/parsers/__init__.pyi | 1 + .../2and3/xml/parsers/expat/__init__.pyi | 1 + .../stdlib/2and3/xml/parsers/expat/errors.pyi | 1 + .../stdlib/2and3/xml/parsers/expat/model.pyi | 1 + .../stdlib/2and3/xml/sax/__init__.pyi | 34 + .../typeshed/stdlib/2and3/xml/sax/handler.pyi | 46 + .../stdlib/2and3/xml/sax/saxutils.pyi | 58 + .../stdlib/2and3/xml/sax/xmlreader.pyi | 71 + .../typeshed/stdlib/2and3/zipfile.pyi | 146 + .../typeshed/stdlib/2and3/zipimport.pyi | 18 + .../typeshed/stdlib/2and3/zlib.pyi | 55 + .../typeshed/stdlib/3.6/secrets.pyi | 14 + .../typeshed/stdlib/3.7/contextvars.pyi | 30 + .../typeshed/stdlib/3.7/dataclasses.pyi | 71 + .../third_party/typeshed/stdlib/3/_ast.pyi | 415 ++ .../typeshed/stdlib/3/_compression.pyi | 16 + .../typeshed/stdlib/3/_dummy_thread.pyi | 21 + .../third_party/typeshed/stdlib/3/_imp.pyi | 20 + .../stdlib/3/_importlib_modulespec.pyi | 44 + .../third_party/typeshed/stdlib/3/_json.pyi | 30 + .../typeshed/stdlib/3/_markupbase.pyi | 9 + .../typeshed/stdlib/3/_operator.pyi | 63 + .../typeshed/stdlib/3/_posixsubprocess.pyi | 14 + .../third_party/typeshed/stdlib/3/_stat.pyi | 69 + .../typeshed/stdlib/3/_subprocess.pyi | 38 + .../third_party/typeshed/stdlib/3/_thread.pyi | 44 + .../typeshed/stdlib/3/_threading_local.pyi | 17 + .../typeshed/stdlib/3/_tracemalloc.pyi | 16 + .../third_party/typeshed/stdlib/3/_winapi.pyi | 103 + .../third_party/typeshed/stdlib/3/abc.pyi | 19 + .../third_party/typeshed/stdlib/3/ast.pyi | 61 + .../typeshed/stdlib/3/asyncio/__init__.pyi | 139 + .../typeshed/stdlib/3/asyncio/base_events.pyi | 212 + .../typeshed/stdlib/3/asyncio/constants.pyi | 13 + .../typeshed/stdlib/3/asyncio/coroutines.pyi | 7 + .../typeshed/stdlib/3/asyncio/events.pyi | 340 + .../typeshed/stdlib/3/asyncio/exceptions.pyi | 15 + .../typeshed/stdlib/3/asyncio/futures.pyi | 62 + .../typeshed/stdlib/3/asyncio/locks.pyi | 51 + .../stdlib/3/asyncio/proactor_events.pyi | 80 + .../typeshed/stdlib/3/asyncio/protocols.pyi | 25 + .../typeshed/stdlib/3/asyncio/queues.pyi | 35 + .../typeshed/stdlib/3/asyncio/runners.pyi | 9 + .../stdlib/3/asyncio/selector_events.pyi | 44 + .../typeshed/stdlib/3/asyncio/streams.pyi | 108 + .../typeshed/stdlib/3/asyncio/subprocess.pyi | 60 + .../typeshed/stdlib/3/asyncio/tasks.pyi | 128 + .../typeshed/stdlib/3/asyncio/transports.pyi | 48 + .../stdlib/3/asyncio/windows_events.pyi | 58 + .../stdlib/3/asyncio/windows_utils.pyi | 21 + .../third_party/typeshed/stdlib/3/atexit.pyi | 9 + .../stdlib/3/collections/__init__.pyi | 338 + .../typeshed/stdlib/3/collections/abc.pyi | 36 + .../typeshed/stdlib/3/compileall.pyi | 77 + .../typeshed/stdlib/3/concurrent/__init__.pyi | 0 .../stdlib/3/concurrent/futures/__init__.pyi | 3 + .../stdlib/3/concurrent/futures/_base.pyi | 100 + .../stdlib/3/concurrent/futures/process.pyi | 20 + .../stdlib/3/concurrent/futures/thread.pyi | 30 + .../typeshed/stdlib/3/configparser.pyi | 235 + .../third_party/typeshed/stdlib/3/copyreg.pyi | 14 + .../typeshed/stdlib/3/email/__init__.pyi | 25 + .../typeshed/stdlib/3/email/charset.pyi | 31 + .../stdlib/3/email/contentmanager.pyi | 15 + .../typeshed/stdlib/3/email/encoders.pyi | 8 + .../typeshed/stdlib/3/email/errors.pyi | 19 + .../typeshed/stdlib/3/email/feedparser.pyi | 17 + .../typeshed/stdlib/3/email/generator.pyi | 27 + .../typeshed/stdlib/3/email/header.pyi | 25 + .../stdlib/3/email/headerregistry.pyi | 97 + .../typeshed/stdlib/3/email/iterators.pyi | 8 + .../typeshed/stdlib/3/email/message.pyi | 103 + .../typeshed/stdlib/3/email/mime/__init__.pyi | 0 .../stdlib/3/email/mime/application.pyi | 11 + .../typeshed/stdlib/3/email/mime/audio.pyi | 11 + .../typeshed/stdlib/3/email/mime/base.pyi | 10 + .../typeshed/stdlib/3/email/mime/image.pyi | 11 + .../typeshed/stdlib/3/email/mime/message.pyi | 7 + .../stdlib/3/email/mime/multipart.pyi | 12 + .../stdlib/3/email/mime/nonmultipart.pyi | 5 + .../typeshed/stdlib/3/email/mime/text.pyi | 8 + .../typeshed/stdlib/3/email/parser.pyi | 33 + .../typeshed/stdlib/3/email/policy.pyi | 62 + .../typeshed/stdlib/3/email/utils.pyi | 33 + .../typeshed/stdlib/3/encodings/__init__.pyi | 3 + .../typeshed/stdlib/3/encodings/utf_8.pyi | 15 + .../third_party/typeshed/stdlib/3/enum.pyi | 75 + .../typeshed/stdlib/3/faulthandler.pyi | 17 + .../third_party/typeshed/stdlib/3/fcntl.pyi | 96 + .../third_party/typeshed/stdlib/3/fnmatch.pyi | 11 + .../typeshed/stdlib/3/functools.pyi | 89 + .../jedi/third_party/typeshed/stdlib/3/gc.pyi | 32 + .../third_party/typeshed/stdlib/3/getopt.pyi | 14 + .../third_party/typeshed/stdlib/3/getpass.pyi | 12 + .../third_party/typeshed/stdlib/3/gettext.pyi | 62 + .../third_party/typeshed/stdlib/3/glob.pyi | 19 + .../third_party/typeshed/stdlib/3/gzip.pyi | 53 + .../third_party/typeshed/stdlib/3/hashlib.pyi | 69 + .../third_party/typeshed/stdlib/3/heapq.pyi | 18 + .../typeshed/stdlib/3/html/__init__.pyi | 4 + .../typeshed/stdlib/3/html/entities.pyi | 6 + .../typeshed/stdlib/3/html/parser.pyi | 23 + .../typeshed/stdlib/3/http/__init__.pyi | 67 + .../typeshed/stdlib/3/http/client.pyi | 200 + .../typeshed/stdlib/3/http/cookiejar.pyi | 116 + .../typeshed/stdlib/3/http/cookies.pyi | 31 + .../typeshed/stdlib/3/http/server.pyi | 78 + .../third_party/typeshed/stdlib/3/imp.pyi | 54 + .../typeshed/stdlib/3/importlib/__init__.pyi | 16 + .../typeshed/stdlib/3/importlib/abc.pyi | 92 + .../typeshed/stdlib/3/importlib/machinery.pyi | 115 + .../typeshed/stdlib/3/importlib/metadata.pyi | 86 + .../typeshed/stdlib/3/importlib/resources.pyi | 25 + .../typeshed/stdlib/3/importlib/util.pyi | 53 + .../third_party/typeshed/stdlib/3/inspect.pyi | 313 + .../jedi/third_party/typeshed/stdlib/3/io.pyi | 211 + .../typeshed/stdlib/3/ipaddress.pyi | 149 + .../typeshed/stdlib/3/itertools.pyi | 117 + .../typeshed/stdlib/3/json/__init__.pyi | 57 + .../typeshed/stdlib/3/json/decoder.pyi | 26 + .../typeshed/stdlib/3/json/encoder.pyi | 21 + .../third_party/typeshed/stdlib/3/lzma.pyi | 106 + .../third_party/typeshed/stdlib/3/msvcrt.pyi | 6 + .../stdlib/3/multiprocessing/__init__.pyi | 84 + .../stdlib/3/multiprocessing/connection.pyi | 48 + .../stdlib/3/multiprocessing/context.pyi | 162 + .../3/multiprocessing/dummy/__init__.pyi | 44 + .../3/multiprocessing/dummy/connection.pyi | 35 + .../stdlib/3/multiprocessing/managers.pyi | 80 + .../stdlib/3/multiprocessing/pool.pyi | 83 + .../stdlib/3/multiprocessing/process.pyi | 38 + .../stdlib/3/multiprocessing/queues.pyi | 30 + .../3/multiprocessing/shared_memory.pyi | 29 + .../stdlib/3/multiprocessing/spawn.pyi | 18 + .../stdlib/3/multiprocessing/synchronize.pyi | 63 + .../third_party/typeshed/stdlib/3/nntplib.pyi | 100 + .../typeshed/stdlib/3/nturl2path.pyi | 2 + .../typeshed/stdlib/3/os/__init__.pyi | 666 ++ .../third_party/typeshed/stdlib/3/os/path.pyi | 177 + .../third_party/typeshed/stdlib/3/pathlib.pyi | 135 + .../third_party/typeshed/stdlib/3/pipes.pyi | 19 + .../typeshed/stdlib/3/platform.pyi | 39 + .../third_party/typeshed/stdlib/3/posix.pyi | 126 + .../third_party/typeshed/stdlib/3/queue.pyi | 50 + .../third_party/typeshed/stdlib/3/random.pyi | 69 + .../jedi/third_party/typeshed/stdlib/3/re.pyi | 160 + .../third_party/typeshed/stdlib/3/reprlib.pyi | 37 + .../typeshed/stdlib/3/resource.pyi | 53 + .../third_party/typeshed/stdlib/3/runpy.pyi | 23 + .../typeshed/stdlib/3/selectors.pyi | 84 + .../third_party/typeshed/stdlib/3/shelve.pyi | 31 + .../third_party/typeshed/stdlib/3/shlex.pyi | 45 + .../third_party/typeshed/stdlib/3/signal.pyi | 148 + .../third_party/typeshed/stdlib/3/smtplib.pyi | 136 + .../typeshed/stdlib/3/socketserver.pyi | 99 + .../third_party/typeshed/stdlib/3/spwd.pyi | 15 + .../typeshed/stdlib/3/sre_constants.pyi | 114 + .../typeshed/stdlib/3/sre_parse.pyi | 97 + .../third_party/typeshed/stdlib/3/stat.pyi | 97 + .../typeshed/stdlib/3/statistics.pyi | 64 + .../third_party/typeshed/stdlib/3/string.pyi | 39 + .../typeshed/stdlib/3/subprocess.pyi | 1208 ++++ .../third_party/typeshed/stdlib/3/symbol.pyi | 94 + .../third_party/typeshed/stdlib/3/sys.pyi | 213 + .../typeshed/stdlib/3/tempfile.pyi | 180 + .../typeshed/stdlib/3/textwrap.pyi | 113 + .../typeshed/stdlib/3/tkinter/__init__.pyi | 674 ++ .../stdlib/3/tkinter/commondialog.pyi | 8 + .../typeshed/stdlib/3/tkinter/constants.pyi | 79 + .../typeshed/stdlib/3/tkinter/dialog.pyi | 10 + .../typeshed/stdlib/3/tkinter/filedialog.pyi | 65 + .../typeshed/stdlib/3/tkinter/messagebox.pyi | 31 + .../typeshed/stdlib/3/tkinter/ttk.pyi | 163 + .../typeshed/stdlib/3/tokenize.pyi | 114 + .../typeshed/stdlib/3/tracemalloc.pyi | 70 + .../third_party/typeshed/stdlib/3/types.pyi | 288 + .../third_party/typeshed/stdlib/3/typing.pyi | 645 ++ .../typeshed/stdlib/3/unittest/__init__.pyi | 32 + .../typeshed/stdlib/3/unittest/async_case.pyi | 9 + .../typeshed/stdlib/3/unittest/case.pyi | 248 + .../typeshed/stdlib/3/unittest/loader.pyi | 25 + .../typeshed/stdlib/3/unittest/mock.pyi | 150 + .../typeshed/stdlib/3/unittest/result.pyi | 36 + .../typeshed/stdlib/3/unittest/runner.pyi | 37 + .../typeshed/stdlib/3/unittest/signals.pyi | 14 + .../typeshed/stdlib/3/unittest/suite.pyi | 22 + .../typeshed/stdlib/3/unittest/util.pyi | 22 + .../typeshed/stdlib/3/urllib/__init__.pyi | 0 .../typeshed/stdlib/3/urllib/error.pyi | 11 + .../typeshed/stdlib/3/urllib/parse.pyi | 144 + .../typeshed/stdlib/3/urllib/request.pyi | 226 + .../typeshed/stdlib/3/urllib/response.pyi | 42 + .../typeshed/stdlib/3/urllib/robotparser.pyi | 20 + .../third_party/typeshed/stdlib/3/zipapp.pyi | 16 + .../third_party/2/OpenSSL/__init__.pyi | 0 .../typeshed/third_party/2/OpenSSL/crypto.pyi | 191 + .../third_party/2/concurrent/__init__.pyi | 0 .../2/concurrent/futures/__init__.pyi | 3 + .../2/concurrent/futures/_base.pyi | 100 + .../2/concurrent/futures/process.pyi | 20 + .../2/concurrent/futures/thread.pyi | 30 + .../typeshed/third_party/2/enum.pyi | 75 + .../third_party/2/fb303/FacebookService.pyi | 297 + .../typeshed/third_party/2/fb303/__init__.pyi | 0 .../typeshed/third_party/2/gflags.pyi | 242 + .../typeshed/third_party/2/ipaddress.pyi | 149 + .../typeshed/third_party/2/kazoo/__init__.pyi | 0 .../typeshed/third_party/2/kazoo/client.pyi | 97 + .../third_party/2/kazoo/exceptions.pyi | 58 + .../third_party/2/kazoo/recipe/__init__.pyi | 0 .../third_party/2/kazoo/recipe/watchers.pyi | 21 + .../typeshed/third_party/2/pathlib2.pyi | 135 + .../typeshed/third_party/2/pymssql.pyi | 48 + .../third_party/2/routes/__init__.pyi | 15 + .../typeshed/third_party/2/routes/mapper.pyi | 67 + .../typeshed/third_party/2/routes/util.pyi | 20 + .../third_party/2/scribe/__init__.pyi | 0 .../typeshed/third_party/2/scribe/scribe.pyi | 39 + .../typeshed/third_party/2/scribe/ttypes.pyi | 18 + .../typeshed/third_party/2/six/__init__.pyi | 96 + .../2/six/moves/BaseHTTPServer.pyi | 1 + .../third_party/2/six/moves/CGIHTTPServer.pyi | 1 + .../2/six/moves/SimpleHTTPServer.pyi | 1 + .../third_party/2/six/moves/__init__.pyi | 66 + .../third_party/2/six/moves/_dummy_thread.pyi | 1 + .../third_party/2/six/moves/_thread.pyi | 1 + .../third_party/2/six/moves/cPickle.pyi | 1 + .../third_party/2/six/moves/configparser.pyi | 1 + .../2/six/moves/email_mime_base.pyi | 1 + .../2/six/moves/email_mime_multipart.pyi | 1 + .../2/six/moves/email_mime_nonmultipart.pyi | 1 + .../2/six/moves/email_mime_text.pyi | 1 + .../third_party/2/six/moves/html_entities.pyi | 1 + .../third_party/2/six/moves/html_parser.pyi | 1 + .../third_party/2/six/moves/http_client.pyi | 1 + .../2/six/moves/http_cookiejar.pyi | 1 + .../third_party/2/six/moves/http_cookies.pyi | 1 + .../third_party/2/six/moves/queue.pyi | 1 + .../third_party/2/six/moves/reprlib.pyi | 1 + .../third_party/2/six/moves/socketserver.pyi | 1 + .../2/six/moves/urllib/__init__.pyi | 5 + .../third_party/2/six/moves/urllib/error.pyi | 3 + .../third_party/2/six/moves/urllib/parse.pyi | 24 + .../2/six/moves/urllib/request.pyi | 36 + .../2/six/moves/urllib/response.pyi | 5 + .../2/six/moves/urllib/robotparser.pyi | 1 + .../third_party/2/six/moves/urllib_error.pyi | 1 + .../third_party/2/six/moves/urllib_parse.pyi | 1 + .../2/six/moves/urllib_request.pyi | 1 + .../2/six/moves/urllib_response.pyi | 1 + .../2/six/moves/urllib_robotparser.pyi | 1 + .../third_party/2/six/moves/xmlrpc_client.pyi | 1 + .../third_party/2/tornado/__init__.pyi | 0 .../third_party/2/tornado/concurrent.pyi | 43 + .../typeshed/third_party/2/tornado/gen.pyi | 110 + .../third_party/2/tornado/httpclient.pyi | 96 + .../third_party/2/tornado/httpserver.pyi | 43 + .../third_party/2/tornado/httputil.pyi | 96 + .../typeshed/third_party/2/tornado/ioloop.pyi | 84 + .../typeshed/third_party/2/tornado/locks.pyi | 45 + .../third_party/2/tornado/netutil.pyi | 45 + .../third_party/2/tornado/process.pyi | 24 + .../third_party/2/tornado/tcpserver.pyi | 17 + .../third_party/2/tornado/testing.pyi | 63 + .../typeshed/third_party/2/tornado/util.pyi | 46 + .../typeshed/third_party/2/tornado/web.pyi | 257 + .../third_party/2and3/Crypto/Cipher/AES.pyi | 19 + .../third_party/2and3/Crypto/Cipher/ARC2.pyi | 19 + .../third_party/2and3/Crypto/Cipher/ARC4.pyi | 15 + .../2and3/Crypto/Cipher/Blowfish.pyi | 19 + .../third_party/2and3/Crypto/Cipher/CAST.pyi | 19 + .../third_party/2and3/Crypto/Cipher/DES.pyi | 19 + .../third_party/2and3/Crypto/Cipher/DES3.pyi | 20 + .../2and3/Crypto/Cipher/PKCS1_OAEP.pyi | 13 + .../2and3/Crypto/Cipher/PKCS1_v1_5.pyi | 13 + .../third_party/2and3/Crypto/Cipher/XOR.pyi | 16 + .../2and3/Crypto/Cipher/__init__.pyi | 11 + .../2and3/Crypto/Cipher/blockalgo.pyi | 17 + .../third_party/2and3/Crypto/Hash/HMAC.pyi | 16 + .../third_party/2and3/Crypto/Hash/MD2.pyi | 13 + .../third_party/2and3/Crypto/Hash/MD4.pyi | 13 + .../third_party/2and3/Crypto/Hash/MD5.pyi | 13 + .../third_party/2and3/Crypto/Hash/RIPEMD.pyi | 13 + .../third_party/2and3/Crypto/Hash/SHA.pyi | 13 + .../third_party/2and3/Crypto/Hash/SHA224.pyi | 13 + .../third_party/2and3/Crypto/Hash/SHA256.pyi | 13 + .../third_party/2and3/Crypto/Hash/SHA384.pyi | 13 + .../third_party/2and3/Crypto/Hash/SHA512.pyi | 13 + .../2and3/Crypto/Hash/__init__.pyi | 11 + .../2and3/Crypto/Hash/hashalgo.pyi | 11 + .../2and3/Crypto/Protocol/AllOrNothing.pyi | 10 + .../2and3/Crypto/Protocol/Chaffing.pyi | 5 + .../third_party/2and3/Crypto/Protocol/KDF.pyi | 7 + .../2and3/Crypto/Protocol/__init__.pyi | 4 + .../2and3/Crypto/PublicKey/DSA.pyi | 27 + .../2and3/Crypto/PublicKey/ElGamal.pyi | 19 + .../2and3/Crypto/PublicKey/RSA.pyi | 32 + .../2and3/Crypto/PublicKey/__init__.pyi | 4 + .../2and3/Crypto/PublicKey/pubkey.pyi | 21 + .../Random/Fortuna/FortunaAccumulator.pyi | 25 + .../Random/Fortuna/FortunaGenerator.pyi | 16 + .../2and3/Crypto/Random/Fortuna/SHAd256.pyi | 13 + .../2and3/Crypto/Random/Fortuna/__init__.pyi | 0 .../2and3/Crypto/Random/OSRNG/__init__.pyi | 1 + .../2and3/Crypto/Random/OSRNG/fallback.pyi | 5 + .../2and3/Crypto/Random/OSRNG/posix.pyi | 6 + .../2and3/Crypto/Random/OSRNG/rng_base.pyi | 11 + .../2and3/Crypto/Random/__init__.pyi | 1 + .../2and3/Crypto/Random/random.pyi | 17 + .../2and3/Crypto/Signature/PKCS1_PSS.pyi | 9 + .../2and3/Crypto/Signature/PKCS1_v1_5.pyi | 7 + .../2and3/Crypto/Signature/__init__.pyi | 3 + .../third_party/2and3/Crypto/Util/Counter.pyi | 3 + .../third_party/2and3/Crypto/Util/RFC1751.pyi | 9 + .../2and3/Crypto/Util/__init__.pyi | 6 + .../third_party/2and3/Crypto/Util/asn1.pyi | 45 + .../third_party/2and3/Crypto/Util/number.pyi | 22 + .../2and3/Crypto/Util/randpool.pyi | 16 + .../third_party/2and3/Crypto/Util/strxor.pyi | 2 + .../third_party/2and3/Crypto/__init__.pyi | 7 + .../third_party/2and3/Crypto/pct_warnings.pyi | 7 + .../2and3/atomicwrites/__init__.pyi | 15 + .../third_party/2and3/attr/__init__.pyi | 255 + .../third_party/2and3/attr/converters.pyi | 12 + .../third_party/2and3/attr/exceptions.pyi | 7 + .../third_party/2and3/attr/filters.pyi | 5 + .../third_party/2and3/attr/validators.pyi | 24 + .../third_party/2and3/backports/__init__.pyi | 0 .../2and3/backports/ssl_match_hostname.pyi | 3 + .../third_party/2and3/backports_abc.pyi | 15 + .../third_party/2and3/bleach/__init__.pyi | 32 + .../third_party/2and3/bleach/callbacks.pyi | 6 + .../third_party/2and3/bleach/linkifier.pyi | 31 + .../third_party/2and3/bleach/sanitizer.pyi | 34 + .../third_party/2and3/bleach/utils.pyi | 8 + .../third_party/2and3/boto/__init__.pyi | 76 + .../typeshed/third_party/2and3/boto/auth.pyi | 108 + .../third_party/2and3/boto/auth_handler.pyi | 9 + .../third_party/2and3/boto/compat.pyi | 17 + .../third_party/2and3/boto/connection.pyi | 115 + .../third_party/2and3/boto/ec2/__init__.pyi | 7 + .../third_party/2and3/boto/elb/__init__.pyi | 39 + .../third_party/2and3/boto/exception.pyi | 146 + .../third_party/2and3/boto/kms/__init__.pyi | 5 + .../third_party/2and3/boto/kms/exceptions.pyi | 17 + .../third_party/2and3/boto/kms/layer1.pyi | 37 + .../third_party/2and3/boto/plugin.pyi | 9 + .../third_party/2and3/boto/regioninfo.pyi | 16 + .../third_party/2and3/boto/s3/__init__.pyi | 14 + .../third_party/2and3/boto/s3/acl.pyi | 39 + .../third_party/2and3/boto/s3/bucket.pyi | 94 + .../2and3/boto/s3/bucketlistresultset.pyi | 40 + .../2and3/boto/s3/bucketlogging.pyi | 11 + .../third_party/2and3/boto/s3/connection.pyi | 67 + .../third_party/2and3/boto/s3/cors.pyi | 19 + .../2and3/boto/s3/deletemarker.pyi | 12 + .../third_party/2and3/boto/s3/key.pyi | 232 + .../third_party/2and3/boto/s3/keyfile.pyi | 29 + .../third_party/2and3/boto/s3/lifecycle.pyi | 51 + .../third_party/2and3/boto/s3/multidelete.pyi | 27 + .../third_party/2and3/boto/s3/multipart.pyi | 49 + .../third_party/2and3/boto/s3/prefix.pyi | 10 + .../third_party/2and3/boto/s3/tagging.pyi | 22 + .../third_party/2and3/boto/s3/user.pyi | 10 + .../third_party/2and3/boto/s3/website.pyi | 62 + .../typeshed/third_party/2and3/boto/utils.pyi | 239 + .../typeshed/third_party/2and3/certifi.pyi | 1 + .../2and3/characteristic/__init__.pyi | 34 + .../third_party/2and3/click/__init__.pyi | 118 + .../third_party/2and3/click/_termui_impl.pyi | 14 + .../typeshed/third_party/2and3/click/core.pyi | 480 ++ .../third_party/2and3/click/decorators.pyi | 332 + .../third_party/2and3/click/exceptions.pyi | 93 + .../third_party/2and3/click/formatting.pyi | 86 + .../third_party/2and3/click/globals.pyi | 18 + .../third_party/2and3/click/parser.pyi | 104 + .../third_party/2and3/click/termui.pyi | 174 + .../third_party/2and3/click/testing.pyi | 74 + .../third_party/2and3/click/types.pyi | 255 + .../third_party/2and3/click/utils.pyi | 88 + .../typeshed/third_party/2and3/croniter.pyi | 41 + .../2and3/cryptography/__init__.pyi | 0 .../2and3/cryptography/exceptions.pyi | 7 + .../third_party/2and3/cryptography/fernet.pyi | 17 + .../2and3/cryptography/hazmat/__init__.pyi | 3 + .../cryptography/hazmat/backends/__init__.pyi | 3 + .../hazmat/backends/interfaces.pyi | 196 + .../cryptography/hazmat/bindings/__init__.pyi | 0 .../hazmat/bindings/openssl/__init__.pyi | 0 .../hazmat/bindings/openssl/binding.pyi | 6 + .../hazmat/primitives/__init__.pyi | 3 + .../hazmat/primitives/asymmetric/__init__.pyi | 3 + .../hazmat/primitives/asymmetric/dh.pyi | 77 + .../hazmat/primitives/asymmetric/dsa.pyi | 79 + .../hazmat/primitives/asymmetric/ec.pyi | 230 + .../hazmat/primitives/asymmetric/ed25519.pyi | 25 + .../hazmat/primitives/asymmetric/ed448.pyi | 25 + .../hazmat/primitives/asymmetric/padding.pyi | 27 + .../hazmat/primitives/asymmetric/rsa.pyi | 79 + .../hazmat/primitives/asymmetric/utils.pyi | 6 + .../hazmat/primitives/asymmetric/x25519.pyi | 23 + .../hazmat/primitives/asymmetric/x448.pyi | 23 + .../hazmat/primitives/ciphers/__init__.pyi | 43 + .../hazmat/primitives/ciphers/aead.pyi | 22 + .../hazmat/primitives/ciphers/algorithms.pyi | 79 + .../hazmat/primitives/ciphers/modes.pyi | 94 + .../cryptography/hazmat/primitives/cmac.pyi | 9 + .../hazmat/primitives/constant_time.pyi | 1 + .../cryptography/hazmat/primitives/hashes.pyi | 43 + .../cryptography/hazmat/primitives/hmac.pyi | 9 + .../hazmat/primitives/kdf/__init__.pyi | 7 + .../hazmat/primitives/kdf/concatkdf.pyi | 17 + .../hazmat/primitives/kdf/hkdf.pyi | 17 + .../hazmat/primitives/kdf/kbkdf.pyi | 30 + .../hazmat/primitives/kdf/pbkdf2.pyi | 8 + .../hazmat/primitives/kdf/scrypt.pyi | 7 + .../hazmat/primitives/kdf/x963kdf.pyi | 10 + .../hazmat/primitives/keywrap.pyi | 8 + .../hazmat/primitives/padding.pyi | 17 + .../hazmat/primitives/poly1305.pyi | 12 + .../primitives/serialization/__init__.pyi | 40 + .../primitives/serialization/pkcs12.pyi | 3 + .../hazmat/primitives/twofactor/__init__.pyi | 1 + .../hazmat/primitives/twofactor/hotp.pyi | 12 + .../hazmat/primitives/twofactor/totp.pyi | 18 + .../third_party/2and3/cryptography/x509.pyi | 299 + .../third_party/2and3/dateutil/__init__.pyi | 0 .../third_party/2and3/dateutil/_common.pyi | 17 + .../third_party/2and3/dateutil/parser.pyi | 46 + .../2and3/dateutil/relativedelta.pyi | 91 + .../third_party/2and3/dateutil/rrule.pyi | 103 + .../2and3/dateutil/tz/__init__.pyi | 15 + .../third_party/2and3/dateutil/tz/_common.pyi | 24 + .../third_party/2and3/dateutil/tz/tz.pyi | 96 + .../third_party/2and3/dateutil/utils.pyi | 7 + .../typeshed/third_party/2and3/decorator.pyi | 84 + .../typeshed/third_party/2and3/emoji.pyi | 18 + .../typeshed/third_party/2and3/first.pyi | 13 + .../third_party/2and3/flask/__init__.pyi | 45 + .../typeshed/third_party/2and3/flask/app.pyi | 186 + .../third_party/2and3/flask/blueprints.pyi | 66 + .../typeshed/third_party/2and3/flask/cli.pyi | 64 + .../third_party/2and3/flask/config.pyi | 22 + .../typeshed/third_party/2and3/flask/ctx.pyi | 46 + .../third_party/2and3/flask/debughelpers.pyi | 21 + .../third_party/2and3/flask/globals.pyi | 18 + .../third_party/2and3/flask/helpers.pyi | 48 + .../third_party/2and3/flask/json/__init__.pyi | 19 + .../third_party/2and3/flask/json/tag.pyi | 71 + .../third_party/2and3/flask/logging.pyi | 13 + .../third_party/2and3/flask/sessions.pyi | 60 + .../third_party/2and3/flask/signals.pyi | 33 + .../third_party/2and3/flask/templating.pyi | 24 + .../third_party/2and3/flask/testing.pyi | 38 + .../third_party/2and3/flask/views.pyi | 22 + .../third_party/2and3/flask/wrappers.pyi | 35 + .../third_party/2and3/geoip2/__init__.pyi | 0 .../third_party/2and3/geoip2/database.pyi | 22 + .../third_party/2and3/geoip2/errors.pyi | 18 + .../third_party/2and3/geoip2/mixins.pyi | 3 + .../third_party/2and3/geoip2/models.pyi | 65 + .../third_party/2and3/geoip2/records.pyi | 83 + .../third_party/2and3/google/__init__.pyi | 0 .../2and3/google/protobuf/__init__.pyi | 1 + .../2and3/google/protobuf/any_pb2.pyi | 9 + .../2and3/google/protobuf/any_test_pb2.pyi | 14 + .../2and3/google/protobuf/api_pb2.pyi | 53 + .../google/protobuf/compiler/__init__.pyi | 0 .../google/protobuf/compiler/plugin_pb2.pyi | 41 + .../2and3/google/protobuf/descriptor.pyi | 286 + .../2and3/google/protobuf/descriptor_pb2.pyi | 471 ++ .../2and3/google/protobuf/descriptor_pool.pyi | 18 + .../2and3/google/protobuf/duration_pb2.pyi | 9 + .../2and3/google/protobuf/empty_pb2.pyi | 4 + .../2and3/google/protobuf/field_mask_pb2.pyi | 9 + .../google/protobuf/internal/__init__.pyi | 0 .../google/protobuf/internal/containers.pyi | 56 + .../google/protobuf/internal/decoder.pyi | 30 + .../google/protobuf/internal/encoder.pyi | 34 + .../protobuf/internal/enum_type_wrapper.pyi | 10 + .../protobuf/internal/message_listener.pyi | 5 + .../protobuf/internal/well_known_types.pyi | 94 + .../google/protobuf/internal/wire_format.pyi | 50 + .../2and3/google/protobuf/json_format.pyi | 26 + .../protobuf/map_proto2_unittest_pb2.pyi | 198 + .../google/protobuf/map_unittest_pb2.pyi | 375 ++ .../2and3/google/protobuf/message.pyi | 52 + .../2and3/google/protobuf/message_factory.pyi | 13 + .../2and3/google/protobuf/reflection.pyi | 6 + .../2and3/google/protobuf/service.pyi | 39 + .../google/protobuf/source_context_pb2.pyi | 6 + .../2and3/google/protobuf/struct_pb2.pyi | 55 + .../2and3/google/protobuf/symbol_database.pyi | 14 + .../protobuf/test_messages_proto2_pb2.pyi | 345 + .../protobuf/test_messages_proto3_pb2.pyi | 435 ++ .../2and3/google/protobuf/timestamp_pb2.pyi | 9 + .../2and3/google/protobuf/type_pb2.pyi | 144 + .../google/protobuf/unittest_arena_pb2.pyi | 19 + .../protobuf/unittest_custom_options_pb2.pyi | 226 + .../google/protobuf/unittest_import_pb2.pyi | 38 + .../protobuf/unittest_import_public_pb2.pyi | 6 + .../google/protobuf/unittest_mset_pb2.pyi | 27 + .../unittest_mset_wire_format_pb2.pyi | 10 + .../protobuf/unittest_no_arena_import_pb2.pyi | 6 + .../google/protobuf/unittest_no_arena_pb2.pyi | 225 + .../unittest_no_generic_services_pb2.pyi | 20 + .../2and3/google/protobuf/unittest_pb2.pyi | 1083 ++++ .../protobuf/unittest_proto3_arena_pb2.pyi | 248 + .../2and3/google/protobuf/util/__init__.pyi | 0 .../protobuf/util/json_format_proto3_pb2.pyi | 341 + .../2and3/google/protobuf/wrappers_pb2.pyi | 38 + .../third_party/2and3/itsdangerous.pyi | 153 + .../third_party/2and3/jinja2/__init__.pyi | 7 + .../third_party/2and3/jinja2/_compat.pyi | 34 + .../third_party/2and3/jinja2/_stringdefs.pyi | 40 + .../third_party/2and3/jinja2/bccache.pyi | 44 + .../third_party/2and3/jinja2/compiler.pyi | 176 + .../third_party/2and3/jinja2/constants.pyi | 1 + .../third_party/2and3/jinja2/debug.pyi | 37 + .../third_party/2and3/jinja2/defaults.pyi | 21 + .../third_party/2and3/jinja2/environment.pyi | 169 + .../third_party/2and3/jinja2/exceptions.pyi | 31 + .../typeshed/third_party/2and3/jinja2/ext.pyi | 58 + .../third_party/2and3/jinja2/filters.pyi | 56 + .../third_party/2and3/jinja2/lexer.pyi | 117 + .../third_party/2and3/jinja2/loaders.pyi | 72 + .../third_party/2and3/jinja2/meta.pyi | 11 + .../third_party/2and3/jinja2/nodes.pyi | 250 + .../third_party/2and3/jinja2/optimizer.pyi | 29 + .../third_party/2and3/jinja2/parser.pyi | 60 + .../third_party/2and3/jinja2/runtime.pyi | 130 + .../third_party/2and3/jinja2/sandbox.pyi | 34 + .../third_party/2and3/jinja2/tests.pyi | 24 + .../third_party/2and3/jinja2/utils.pyi | 61 + .../third_party/2and3/jinja2/visitor.pyi | 8 + .../third_party/2and3/markupsafe/__init__.pyi | 53 + .../third_party/2and3/markupsafe/_compat.pyi | 19 + .../2and3/markupsafe/_constants.pyi | 3 + .../third_party/2and3/markupsafe/_native.pyi | 7 + .../2and3/markupsafe/_speedups.pyi | 7 + .../third_party/2and3/maxminddb/__init__.pyi | 7 + .../third_party/2and3/maxminddb/compat.pyi | 8 + .../third_party/2and3/maxminddb/const.pyi | 6 + .../third_party/2and3/maxminddb/decoder.pyi | 5 + .../third_party/2and3/maxminddb/errors.pyi | 1 + .../third_party/2and3/maxminddb/extension.pyi | 33 + .../third_party/2and3/maxminddb/reader.pyi | 30 + .../typeshed/third_party/2and3/mock.pyi | 150 + .../third_party/2and3/mypy_extensions.pyi | 47 + .../typeshed/third_party/2and3/pycurl.pyi | 604 ++ .../third_party/2and3/pymysql/__init__.pyi | 61 + .../third_party/2and3/pymysql/charset.pyi | 16 + .../third_party/2and3/pymysql/connections.pyi | 145 + .../2and3/pymysql/constants/CLIENT.pyi | 18 + .../2and3/pymysql/constants/COMMAND.pyi | 22 + .../2and3/pymysql/constants/ER.pyi | 471 ++ .../2and3/pymysql/constants/FIELD_TYPE.pyi | 29 + .../2and3/pymysql/constants/FLAG.pyi | 17 + .../2and3/pymysql/constants/SERVER_STATUS.pyi | 10 + .../2and3/pymysql/constants/__init__.pyi | 0 .../third_party/2and3/pymysql/converters.pyi | 46 + .../third_party/2and3/pymysql/cursors.pyi | 50 + .../third_party/2and3/pymysql/err.pyi | 18 + .../third_party/2and3/pymysql/times.pyi | 10 + .../third_party/2and3/pymysql/util.pyi | 3 + .../third_party/2and3/pynamodb/__init__.pyi | 1 + .../third_party/2and3/pynamodb/attributes.pyi | 96 + .../2and3/pynamodb/connection/__init__.pyi | 2 + .../2and3/pynamodb/connection/base.pyi | 78 + .../2and3/pynamodb/connection/table.pyi | 18 + .../2and3/pynamodb/connection/util.pyi | 3 + .../third_party/2and3/pynamodb/constants.pyi | 166 + .../third_party/2and3/pynamodb/exceptions.pyi | 23 + .../third_party/2and3/pynamodb/indexes.pyi | 30 + .../third_party/2and3/pynamodb/models.pyi | 107 + .../third_party/2and3/pynamodb/settings.pyi | 8 + .../third_party/2and3/pynamodb/throttle.pyi | 19 + .../third_party/2and3/pynamodb/types.pyi | 5 + .../third_party/2and3/pyre_extensions.pyi | 7 + .../third_party/2and3/pytz/__init__.pyi | 42 + .../third_party/2and3/redis/__init__.pyi | 24 + .../third_party/2and3/redis/client.pyi | 363 ++ .../third_party/2and3/redis/connection.pyi | 134 + .../third_party/2and3/redis/exceptions.pyi | 17 + .../third_party/2and3/redis/utils.pyi | 8 + .../third_party/2and3/requests/__init__.pyi | 40 + .../third_party/2and3/requests/adapters.pyi | 79 + .../third_party/2and3/requests/api.pyi | 32 + .../third_party/2and3/requests/auth.pyi | 44 + .../third_party/2and3/requests/compat.pyi | 6 + .../third_party/2and3/requests/cookies.pyi | 67 + .../third_party/2and3/requests/exceptions.pyi | 26 + .../third_party/2and3/requests/hooks.pyi | 8 + .../third_party/2and3/requests/models.pyi | 144 + .../2and3/requests/packages/__init__.pyi | 4 + .../requests/packages/urllib3/__init__.pyi | 31 + .../packages/urllib3/_collections.pyi | 52 + .../requests/packages/urllib3/connection.pyi | 71 + .../packages/urllib3/connectionpool.pyi | 85 + .../packages/urllib3/contrib/__init__.pyi | 0 .../requests/packages/urllib3/exceptions.pyi | 50 + .../requests/packages/urllib3/fields.pyi | 16 + .../requests/packages/urllib3/filepost.pyi | 15 + .../packages/urllib3/packages/__init__.pyi | 0 .../packages/ssl_match_hostname/__init__.pyi | 4 + .../ssl_match_hostname/_implementation.pyi | 3 + .../requests/packages/urllib3/poolmanager.pyi | 27 + .../requests/packages/urllib3/request.pyi | 9 + .../requests/packages/urllib3/response.pyi | 53 + .../packages/urllib3/util/__init__.pyi | 25 + .../packages/urllib3/util/connection.pyi | 8 + .../packages/urllib3/util/request.pyi | 8 + .../packages/urllib3/util/response.pyi | 1 + .../requests/packages/urllib3/util/retry.pyi | 32 + .../requests/packages/urllib3/util/ssl_.pyi | 20 + .../packages/urllib3/util/timeout.pyi | 20 + .../requests/packages/urllib3/util/url.pyi | 22 + .../third_party/2and3/requests/sessions.pyi | 113 + .../2and3/requests/status_codes.pyi | 4 + .../third_party/2and3/requests/structures.pyi | 20 + .../third_party/2and3/requests/utils.pyi | 53 + .../third_party/2and3/simplejson/__init__.pyi | 13 + .../third_party/2and3/simplejson/decoder.pyi | 6 + .../third_party/2and3/simplejson/encoder.pyi | 9 + .../third_party/2and3/simplejson/scanner.pyi | 11 + .../third_party/2and3/singledispatch.pyi | 17 + .../typeshed/third_party/2and3/tabulate.pyi | 44 + .../typeshed/third_party/2and3/termcolor.pyi | 21 + .../typeshed/third_party/2and3/toml.pyi | 24 + .../third_party/2and3/typing_extensions.pyi | 69 + .../typeshed/third_party/2and3/ujson.pyi | 51 + .../third_party/2and3/werkzeug/__init__.pyi | 150 + .../third_party/2and3/werkzeug/_compat.pyi | 48 + .../third_party/2and3/werkzeug/_internal.pyi | 19 + .../third_party/2and3/werkzeug/_reloader.pyi | 29 + .../2and3/werkzeug/contrib/__init__.pyi | 0 .../2and3/werkzeug/contrib/atom.pyi | 50 + .../2and3/werkzeug/contrib/cache.pyi | 84 + .../2and3/werkzeug/contrib/fixers.pyi | 35 + .../2and3/werkzeug/contrib/iterio.pyi | 39 + .../2and3/werkzeug/contrib/jsrouting.pyi | 10 + .../2and3/werkzeug/contrib/limiter.pyi | 7 + .../2and3/werkzeug/contrib/lint.pyi | 1 + .../2and3/werkzeug/contrib/profiler.pyi | 14 + .../2and3/werkzeug/contrib/securecookie.pyi | 28 + .../2and3/werkzeug/contrib/sessions.pyi | 60 + .../2and3/werkzeug/contrib/testtools.pyi | 9 + .../2and3/werkzeug/contrib/wrappers.pyi | 27 + .../2and3/werkzeug/datastructures.pyi | 461 ++ .../2and3/werkzeug/debug/__init__.pyi | 41 + .../2and3/werkzeug/debug/console.pyi | 44 + .../third_party/2and3/werkzeug/debug/repr.pyi | 33 + .../2and3/werkzeug/debug/tbtools.pyi | 63 + .../third_party/2and3/werkzeug/exceptions.pyi | 170 + .../third_party/2and3/werkzeug/filesystem.pyi | 7 + .../third_party/2and3/werkzeug/formparser.pyi | 87 + .../third_party/2and3/werkzeug/http.pyi | 92 + .../third_party/2and3/werkzeug/local.pyi | 100 + .../2and3/werkzeug/middleware/__init__.pyi | 0 .../2and3/werkzeug/middleware/dispatcher.pyi | 8 + .../2and3/werkzeug/middleware/http_proxy.pyi | 18 + .../2and3/werkzeug/middleware/lint.pyi | 67 + .../2and3/werkzeug/middleware/profiler.pyi | 14 + .../2and3/werkzeug/middleware/proxy_fix.pyi | 23 + .../2and3/werkzeug/middleware/shared_data.pyi | 29 + .../2and3/werkzeug/posixemulation.pyi | 7 + .../third_party/2and3/werkzeug/routing.pyi | 189 + .../third_party/2and3/werkzeug/script.pyi | 14 + .../third_party/2and3/werkzeug/security.pyi | 12 + .../third_party/2and3/werkzeug/serving.pyi | 93 + .../third_party/2and3/werkzeug/test.pyi | 154 + .../third_party/2and3/werkzeug/testapp.pyi | 9 + .../third_party/2and3/werkzeug/urls.pyi | 71 + .../third_party/2and3/werkzeug/useragents.pyi | 14 + .../third_party/2and3/werkzeug/utils.pyi | 58 + .../third_party/2and3/werkzeug/wrappers.pyi | 266 + .../third_party/2and3/werkzeug/wsgi.pyi | 74 + .../third_party/2and3/yaml/__init__.pyi | 82 + .../third_party/2and3/yaml/composer.pyi | 17 + .../third_party/2and3/yaml/constructor.pyi | 85 + .../typeshed/third_party/2and3/yaml/cyaml.pyi | 47 + .../third_party/2and3/yaml/dumper.pyi | 13 + .../third_party/2and3/yaml/emitter.pyi | 106 + .../typeshed/third_party/2and3/yaml/error.pyi | 21 + .../third_party/2and3/yaml/events.pyi | 62 + .../third_party/2and3/yaml/loader.pyi | 18 + .../typeshed/third_party/2and3/yaml/nodes.pyi | 31 + .../third_party/2and3/yaml/parser.pyi | 44 + .../third_party/2and3/yaml/reader.pyi | 34 + .../third_party/2and3/yaml/representer.pyi | 55 + .../third_party/2and3/yaml/resolver.pyi | 24 + .../third_party/2and3/yaml/scanner.pyi | 96 + .../third_party/2and3/yaml/serializer.pyi | 23 + .../third_party/2and3/yaml/tokens.pyi | 93 + .../typeshed/third_party/3/contextvars.pyi | 30 + .../typeshed/third_party/3/dataclasses.pyi | 71 + .../third_party/3/docutils/__init__.pyi | 3 + .../third_party/3/docutils/examples.pyi | 5 + .../typeshed/third_party/3/docutils/nodes.pyi | 10 + .../3/docutils/parsers/__init__.pyi | 3 + .../3/docutils/parsers/rst/__init__.pyi | 3 + .../3/docutils/parsers/rst/nodes.pyi | 3 + .../3/docutils/parsers/rst/roles.pyi | 13 + .../3/docutils/parsers/rst/states.pyi | 8 + .../typeshed/third_party/3/jwt/__init__.pyi | 43 + .../typeshed/third_party/3/jwt/algorithms.pyi | 82 + .../third_party/3/jwt/contrib/__init__.pyi | 0 .../3/jwt/contrib/algorithms/__init__.pyi | 1 + .../3/jwt/contrib/algorithms/py_ecdsa.pyi | 10 + .../3/jwt/contrib/algorithms/pycrypto.pyi | 10 + .../typeshed/third_party/3/orjson.pyi | 20 + .../third_party/3/pkg_resources/__init__.pyi | 265 + .../3/pkg_resources/py31compat.pyi | 7 + .../typeshed/third_party/3/six/__init__.pyi | 108 + .../3/six/moves/BaseHTTPServer.pyi | 1 + .../third_party/3/six/moves/CGIHTTPServer.pyi | 1 + .../3/six/moves/SimpleHTTPServer.pyi | 1 + .../third_party/3/six/moves/__init__.pyi | 69 + .../third_party/3/six/moves/_dummy_thread.pyi | 1 + .../third_party/3/six/moves/_thread.pyi | 1 + .../third_party/3/six/moves/builtins.pyi | 1 + .../third_party/3/six/moves/cPickle.pyi | 1 + .../third_party/3/six/moves/configparser.pyi | 1 + .../3/six/moves/email_mime_base.pyi | 1 + .../3/six/moves/email_mime_multipart.pyi | 1 + .../3/six/moves/email_mime_nonmultipart.pyi | 1 + .../3/six/moves/email_mime_text.pyi | 1 + .../third_party/3/six/moves/html_entities.pyi | 1 + .../third_party/3/six/moves/html_parser.pyi | 1 + .../third_party/3/six/moves/http_client.pyi | 1 + .../3/six/moves/http_cookiejar.pyi | 1 + .../third_party/3/six/moves/http_cookies.pyi | 1 + .../third_party/3/six/moves/queue.pyi | 1 + .../third_party/3/six/moves/reprlib.pyi | 1 + .../third_party/3/six/moves/socketserver.pyi | 1 + .../third_party/3/six/moves/tkinter.pyi | 1 + .../3/six/moves/tkinter_commondialog.pyi | 1 + .../3/six/moves/tkinter_constants.pyi | 1 + .../3/six/moves/tkinter_dialog.pyi | 1 + .../3/six/moves/tkinter_filedialog.pyi | 1 + .../3/six/moves/tkinter_tkfiledialog.pyi | 1 + .../third_party/3/six/moves/tkinter_ttk.pyi | 1 + .../3/six/moves/urllib/__init__.pyi | 5 + .../third_party/3/six/moves/urllib/error.pyi | 3 + .../third_party/3/six/moves/urllib/parse.pyi | 28 + .../3/six/moves/urllib/request.pyi | 39 + .../3/six/moves/urllib/response.pyi | 8 + .../3/six/moves/urllib/robotparser.pyi | 1 + .../third_party/3/six/moves/urllib_error.pyi | 1 + .../third_party/3/six/moves/urllib_parse.pyi | 1 + .../3/six/moves/urllib_request.pyi | 1 + .../3/six/moves/urllib_response.pyi | 1 + .../3/six/moves/urllib_robotparser.pyi | 1 + .../third_party/3/typed_ast/__init__.pyi | 2 + .../third_party/3/typed_ast/ast27.pyi | 361 ++ .../typeshed/third_party/3/typed_ast/ast3.pyi | 413 ++ .../third_party/3/typed_ast/conversions.pyi | 4 + .../lib/python3.8/site-packages/jedi/utils.py | 135 + .venv/lib/python3.8/site-packages/jupyter.py | 4 + .../jupyter_client-6.1.7.dist-info/COPYING.md | 60 + .../jupyter_client-6.1.7.dist-info/INSTALLER | 1 + .../jupyter_client-6.1.7.dist-info/METADATA | 92 + .../jupyter_client-6.1.7.dist-info/RECORD | 112 + .../jupyter_client-6.1.7.dist-info/WHEEL | 5 + .../entry_points.txt | 5 + .../top_level.txt | 1 + .../site-packages/jupyter_client/__init__.py | 10 + .../__pycache__/__init__.cpython-38.pyc | Bin 0 -> 728 bytes .../__pycache__/_version.cpython-38.pyc | Bin 0 -> 308 bytes .../__pycache__/adapter.cpython-38.pyc | Bin 0 -> 10272 bytes .../__pycache__/channels.cpython-38.pyc | Bin 0 -> 5373 bytes .../__pycache__/channelsabc.cpython-38.pyc | Bin 0 -> 1711 bytes .../__pycache__/client.cpython-38.pyc | Bin 0 -> 14149 bytes .../__pycache__/clientabc.cpython-38.pyc | Bin 0 -> 2725 bytes .../__pycache__/connect.cpython-38.pyc | Bin 0 -> 16737 bytes .../__pycache__/consoleapp.cpython-38.pyc | Bin 0 -> 9521 bytes .../__pycache__/jsonutil.cpython-38.pyc | Bin 0 -> 2571 bytes .../__pycache__/kernelapp.cpython-38.pyc | Bin 0 -> 3248 bytes .../__pycache__/kernelspec.cpython-38.pyc | Bin 0 -> 11594 bytes .../__pycache__/kernelspecapp.cpython-38.pyc | Bin 0 -> 8901 bytes .../__pycache__/launcher.cpython-38.pyc | Bin 0 -> 3244 bytes .../localinterfaces.cpython-38.pyc | Bin 0 -> 7147 bytes .../__pycache__/manager.cpython-38.pyc | Bin 0 -> 21722 bytes .../__pycache__/managerabc.cpython-38.pyc | Bin 0 -> 1821 bytes .../multikernelmanager.cpython-38.pyc | Bin 0 -> 16551 bytes .../__pycache__/restarter.cpython-38.pyc | Bin 0 -> 3927 bytes .../__pycache__/runapp.cpython-38.pyc | Bin 0 -> 3728 bytes .../__pycache__/session.cpython-38.pyc | Bin 0 -> 30263 bytes .../__pycache__/threaded.cpython-38.pyc | Bin 0 -> 8732 bytes .../__pycache__/win_interrupt.cpython-38.pyc | Bin 0 -> 1472 bytes .../site-packages/jupyter_client/_version.py | 5 + .../site-packages/jupyter_client/adapter.py | 405 ++ .../jupyter_client/asynchronous/__init__.py | 1 + .../__pycache__/__init__.cpython-38.pyc | Bin 0 -> 211 bytes .../__pycache__/channels.cpython-38.pyc | Bin 0 -> 2753 bytes .../__pycache__/client.cpython-38.pyc | Bin 0 -> 10835 bytes .../jupyter_client/asynchronous/channels.py | 82 + .../jupyter_client/asynchronous/client.py | 388 ++ .../jupyter_client/blocking/__init__.py | 1 + .../__pycache__/__init__.cpython-38.pyc | Bin 0 -> 210 bytes .../__pycache__/channels.cpython-38.pyc | Bin 0 -> 2835 bytes .../__pycache__/client.cpython-38.pyc | Bin 0 -> 9089 bytes .../jupyter_client/blocking/channels.py | 88 + .../jupyter_client/blocking/client.py | 337 + .../site-packages/jupyter_client/channels.py | 213 + .../jupyter_client/channelsabc.py | 47 + .../site-packages/jupyter_client/client.py | 445 ++ .../site-packages/jupyter_client/clientabc.py | 87 + .../site-packages/jupyter_client/connect.py | 580 ++ .../jupyter_client/consoleapp.py | 347 + .../jupyter_client/ioloop/__init__.py | 2 + .../__pycache__/__init__.cpython-38.pyc | Bin 0 -> 335 bytes .../ioloop/__pycache__/manager.cpython-38.pyc | Bin 0 -> 3220 bytes .../__pycache__/restarter.cpython-38.pyc | Bin 0 -> 2539 bytes .../jupyter_client/ioloop/manager.py | 102 + .../jupyter_client/ioloop/restarter.py | 81 + .../site-packages/jupyter_client/jsonutil.py | 91 + .../site-packages/jupyter_client/kernelapp.py | 83 + .../jupyter_client/kernelspec.py | 378 ++ .../jupyter_client/kernelspecapp.py | 270 + .../site-packages/jupyter_client/launcher.py | 158 + .../jupyter_client/localinterfaces.py | 274 + .../site-packages/jupyter_client/manager.py | 827 +++ .../jupyter_client/managerabc.py | 51 + .../jupyter_client/multikernelmanager.py | 554 ++ .../site-packages/jupyter_client/restarter.py | 120 + .../site-packages/jupyter_client/runapp.py | 120 + .../site-packages/jupyter_client/session.py | 972 +++ .../jupyter_client/ssh/__init__.py | 1 + .../ssh/__pycache__/__init__.cpython-38.pyc | Bin 0 -> 196 bytes .../ssh/__pycache__/forward.cpython-38.pyc | Bin 0 -> 2220 bytes .../ssh/__pycache__/tunnel.cpython-38.pyc | Bin 0 -> 10672 bytes .../jupyter_client/ssh/forward.py | 87 + .../jupyter_client/ssh/tunnel.py | 372 ++ .../jupyter_client/tests/__init__.py | 0 .../tests/__pycache__/__init__.cpython-38.pyc | Bin 0 -> 156 bytes .../__pycache__/signalkernel.cpython-38.pyc | Bin 0 -> 2675 bytes .../__pycache__/test_adapter.cpython-38.pyc | Bin 0 -> 11926 bytes .../__pycache__/test_client.cpython-38.pyc | Bin 0 -> 3365 bytes .../__pycache__/test_connect.cpython-38.pyc | Bin 0 -> 8110 bytes .../__pycache__/test_jsonutil.cpython-38.pyc | Bin 0 -> 2831 bytes .../__pycache__/test_kernelapp.cpython-38.pyc | Bin 0 -> 1432 bytes .../test_kernelmanager.cpython-38.pyc | Bin 0 -> 12295 bytes .../test_kernelspec.cpython-38.pyc | Bin 0 -> 6701 bytes .../test_localinterfaces.cpython-38.pyc | Bin 0 -> 383 bytes .../__pycache__/test_manager.cpython-38.pyc | Bin 0 -> 1110 bytes .../test_multikernelmanager.cpython-38.pyc | Bin 0 -> 9325 bytes .../test_public_api.cpython-38.pyc | Bin 0 -> 987 bytes .../__pycache__/test_session.cpython-38.pyc | Bin 0 -> 11726 bytes .../tests/__pycache__/test_ssh.cpython-38.pyc | Bin 0 -> 473 bytes .../tests/__pycache__/utils.cpython-38.pyc | Bin 0 -> 3974 bytes .../jupyter_client/tests/signalkernel.py | 77 + .../jupyter_client/tests/test_adapter.py | 404 ++ .../jupyter_client/tests/test_client.py | 87 + .../jupyter_client/tests/test_connect.py | 259 + .../jupyter_client/tests/test_jsonutil.py | 85 + .../jupyter_client/tests/test_kernelapp.py | 50 + .../tests/test_kernelmanager.py | 414 ++ .../jupyter_client/tests/test_kernelspec.py | 193 + .../tests/test_localinterfaces.py | 15 + .../jupyter_client/tests/test_manager.py | 38 + .../tests/test_multikernelmanager.py | 286 + .../jupyter_client/tests/test_public_api.py | 27 + .../jupyter_client/tests/test_session.py | 346 + .../jupyter_client/tests/test_ssh.py | 8 + .../jupyter_client/tests/utils.py | 89 + .../site-packages/jupyter_client/threaded.py | 257 + .../jupyter_client/win_interrupt.py | 39 + .../jupyter_core-4.7.0.dist-info/COPYING.md | 61 + .../jupyter_core-4.7.0.dist-info/INSTALLER | 1 + .../jupyter_core-4.7.0.dist-info/METADATA | 23 + .../jupyter_core-4.7.0.dist-info/RECORD | 67 + .../jupyter_core-4.7.0.dist-info/WHEEL | 5 + .../entry_points.txt | 5 + .../top_level.txt | 2 + .../site-packages/jupyter_core/__init__.py | 1 + .../site-packages/jupyter_core/__main__.py | 3 + .../__pycache__/__init__.cpython-38.pyc | Bin 0 -> 214 bytes .../__pycache__/__main__.cpython-38.pyc | Bin 0 -> 240 bytes .../__pycache__/application.cpython-38.pyc | Bin 0 -> 7533 bytes .../__pycache__/command.cpython-38.pyc | Bin 0 -> 8086 bytes .../__pycache__/migrate.cpython-38.pyc | Bin 0 -> 6984 bytes .../__pycache__/paths.cpython-38.pyc | Bin 0 -> 11763 bytes .../__pycache__/troubleshoot.cpython-38.pyc | Bin 0 -> 2211 bytes .../__pycache__/version.cpython-38.pyc | Bin 0 -> 580 bytes .../site-packages/jupyter_core/application.py | 259 + .../site-packages/jupyter_core/command.py | 294 + .../site-packages/jupyter_core/migrate.py | 280 + .../site-packages/jupyter_core/paths.py | 484 ++ .../jupyter_core/tests/__init__.py | 0 .../tests/__pycache__/__init__.cpython-38.pyc | Bin 0 -> 154 bytes .../tests/__pycache__/mocking.cpython-38.pyc | Bin 0 -> 1080 bytes .../test_application.cpython-38.pyc | Bin 0 -> 3696 bytes .../__pycache__/test_command.cpython-38.pyc | Bin 0 -> 6007 bytes .../__pycache__/test_migrate.cpython-38.pyc | Bin 0 -> 5849 bytes .../__pycache__/test_paths.cpython-38.pyc | Bin 0 -> 10339 bytes .../tests/dotipython/nbextensions/myext.js | 1 + .../__pycache__/ipython_config.cpython-38.pyc | Bin 0 -> 205 bytes .../ipython_console_config.cpython-38.pyc | Bin 0 -> 213 bytes .../ipython_kernel_config.cpython-38.pyc | Bin 0 -> 212 bytes .../ipython_nbconvert_config.cpython-38.pyc | Bin 0 -> 236 bytes .../ipython_notebook_config.cpython-38.pyc | Bin 0 -> 232 bytes .../profile_default/ipython_config.py | 549 ++ .../profile_default/ipython_console_config.py | 531 ++ .../profile_default/ipython_kernel_config.py | 408 ++ .../ipython_nbconvert_config.py | 1 + .../ipython_notebook_config.py | 1 + .../profile_default/static/custom/custom.css | 7 + .../profile_default/static/custom/custom.js | 82 + .../__pycache__/ipython_config.cpython-38.pyc | Bin 0 -> 211 bytes .../ipython_console_config.cpython-38.pyc | Bin 0 -> 219 bytes .../ipython_kernel_config.cpython-38.pyc | Bin 0 -> 218 bytes .../ipython_nbconvert_config.cpython-38.pyc | Bin 0 -> 221 bytes .../ipython_notebook_config.cpython-38.pyc | Bin 0 -> 220 bytes .../profile_default/ipython_config.py | 549 ++ .../profile_default/ipython_console_config.py | 531 ++ .../profile_default/ipython_kernel_config.py | 408 ++ .../ipython_nbconvert_config.py | 971 +++ .../ipython_notebook_config.py | 548 ++ .../profile_default/static/custom/custom.css | 7 + .../profile_default/static/custom/custom.js | 82 + .../jupyter_core/tests/mocking.py | 36 + .../jupyter_core/tests/test_application.py | 113 + .../jupyter_core/tests/test_command.py | 192 + .../jupyter_core/tests/test_migrate.py | 208 + .../jupyter_core/tests/test_paths.py | 336 + .../jupyter_core/troubleshoot.py | 101 + .../jupyter_core/utils/__init__.py | 16 + .../utils/__pycache__/__init__.cpython-38.pyc | Bin 0 -> 746 bytes .../site-packages/jupyter_core/version.py | 25 + .../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 0 -> 525 bytes .../__pycache__/_version.cpython-38.pyc | Bin 0 -> 170 bytes .../__pycache__/compat.cpython-38.pyc | Bin 0 -> 406 bytes .../__pycache__/simple.cpython-38.pyc | Bin 0 -> 7773 bytes .../__pycache__/slots.cpython-38.pyc | Bin 0 -> 15221 bytes .../__pycache__/utils.cpython-38.pyc | Bin 0 -> 765 bytes .../lazy_object_proxy/_version.py | 4 + .../cext.cpython-38-x86_64-linux-gnu.so | Bin 0 -> 170352 bytes .../site-packages/lazy_object_proxy/compat.py | 9 + .../site-packages/lazy_object_proxy/simple.py | 246 + .../site-packages/lazy_object_proxy/slots.py | 414 ++ .../site-packages/lazy_object_proxy/utils.py | 13 + .../mccabe-0.6.1.dist-info/DESCRIPTION.rst | 152 + .../mccabe-0.6.1.dist-info/INSTALLER | 1 + .../mccabe-0.6.1.dist-info/METADATA | 178 + .../mccabe-0.6.1.dist-info/RECORD | 10 + .../mccabe-0.6.1.dist-info/WHEEL | 6 + .../mccabe-0.6.1.dist-info/entry_points.txt | 3 + .../mccabe-0.6.1.dist-info/metadata.json | 1 + .../mccabe-0.6.1.dist-info/top_level.txt | 1 + .venv/lib/python3.8/site-packages/mccabe.py | 347 + .../parso-0.7.1.dist-info/AUTHORS.txt | 57 + .../parso-0.7.1.dist-info/INSTALLER | 1 + .../parso-0.7.1.dist-info/LICENSE.txt | 86 + .../parso-0.7.1.dist-info/METADATA | 253 + .../parso-0.7.1.dist-info/RECORD | 67 + .../site-packages/parso-0.7.1.dist-info/WHEEL | 6 + .../parso-0.7.1.dist-info/top_level.txt | 1 + .../python3.8/site-packages/parso/__init__.py | 58 + .../site-packages/parso/__init__.pyi | 19 + .../parso/__pycache__/__init__.cpython-38.pyc | Bin 0 -> 1836 bytes .../__pycache__/_compatibility.cpython-38.pyc | Bin 0 -> 2819 bytes .../parso/__pycache__/cache.cpython-38.pyc | Bin 0 -> 5794 bytes .../parso/__pycache__/file_io.cpython-38.pyc | Bin 0 -> 1878 bytes .../parso/__pycache__/grammar.cpython-38.pyc | Bin 0 -> 9227 bytes .../__pycache__/normalizer.cpython-38.pyc | Bin 0 -> 7408 bytes .../parso/__pycache__/parser.cpython-38.pyc | Bin 0 -> 6877 bytes .../parso/__pycache__/tree.cpython-38.pyc | Bin 0 -> 12177 bytes .../parso/__pycache__/utils.cpython-38.pyc | Bin 0 -> 5104 bytes .../site-packages/parso/_compatibility.py | 101 + .../python3.8/site-packages/parso/cache.py | 276 + .../python3.8/site-packages/parso/file_io.py | 47 + .../python3.8/site-packages/parso/grammar.py | 260 + .../python3.8/site-packages/parso/grammar.pyi | 38 + .../site-packages/parso/normalizer.py | 203 + .../python3.8/site-packages/parso/parser.py | 211 + .../site-packages/parso/pgen2/__init__.py | 10 + .../site-packages/parso/pgen2/__init__.pyi | 1 + .../pgen2/__pycache__/__init__.cpython-38.pyc | Bin 0 -> 209 bytes .../__pycache__/generator.cpython-38.pyc | Bin 0 -> 9746 bytes .../__pycache__/grammar_parser.cpython-38.pyc | Bin 0 -> 4441 bytes .../site-packages/parso/pgen2/generator.py | 378 ++ .../site-packages/parso/pgen2/generator.pyi | 38 + .../parso/pgen2/grammar_parser.py | 159 + .../parso/pgen2/grammar_parser.pyi | 20 + .../python3.8/site-packages/parso/py.typed | 0 .../site-packages/parso/python/__init__.py | 0 .../__pycache__/__init__.cpython-38.pyc | Bin 0 -> 148 bytes .../python/__pycache__/diff.cpython-38.pyc | Bin 0 -> 20359 bytes .../python/__pycache__/errors.cpython-38.pyc | Bin 0 -> 37133 bytes .../python/__pycache__/parser.cpython-38.pyc | Bin 0 -> 5393 bytes .../python/__pycache__/pep8.cpython-38.pyc | Bin 0 -> 18210 bytes .../python/__pycache__/prefix.cpython-38.pyc | Bin 0 -> 2342 bytes .../python/__pycache__/token.cpython-38.pyc | Bin 0 -> 1302 bytes .../__pycache__/tokenize.cpython-38.pyc | Bin 0 -> 15021 bytes .../python/__pycache__/tree.cpython-38.pyc | Bin 0 -> 40766 bytes .../site-packages/parso/python/diff.py | 886 +++ .../site-packages/parso/python/errors.py | 1277 ++++ .../site-packages/parso/python/grammar27.txt | 143 + .../site-packages/parso/python/grammar310.txt | 171 + .../site-packages/parso/python/grammar33.txt | 134 + .../site-packages/parso/python/grammar34.txt | 134 + .../site-packages/parso/python/grammar35.txt | 153 + .../site-packages/parso/python/grammar36.txt | 158 + .../site-packages/parso/python/grammar37.txt | 156 + .../site-packages/parso/python/grammar38.txt | 171 + .../site-packages/parso/python/grammar39.txt | 171 + .../site-packages/parso/python/parser.py | 217 + .../site-packages/parso/python/pep8.py | 727 +++ .../site-packages/parso/python/prefix.py | 97 + .../site-packages/parso/python/token.py | 27 + .../site-packages/parso/python/token.pyi | 30 + .../site-packages/parso/python/tokenize.py | 722 +++ .../site-packages/parso/python/tokenize.pyi | 24 + .../site-packages/parso/python/tree.py | 1270 ++++ .../lib/python3.8/site-packages/parso/tree.py | 381 ++ .../python3.8/site-packages/parso/utils.py | 185 + .../python3.8/site-packages/parso/utils.pyi | 29 + .../pexpect-4.8.0.dist-info/INSTALLER | 1 + .../pexpect-4.8.0.dist-info/LICENSE | 20 + .../pexpect-4.8.0.dist-info/METADATA | 49 + .../pexpect-4.8.0.dist-info/RECORD | 37 + .../pexpect-4.8.0.dist-info/WHEEL | 6 + .../pexpect-4.8.0.dist-info/top_level.txt | 1 + .../python3.8/site-packages/pexpect/ANSI.py | 351 + .../python3.8/site-packages/pexpect/FSM.py | 334 + .../site-packages/pexpect/__init__.py | 85 + .../pexpect/__pycache__/ANSI.cpython-38.pyc | Bin 0 -> 10179 bytes .../pexpect/__pycache__/FSM.cpython-38.pyc | Bin 0 -> 12749 bytes .../__pycache__/__init__.cpython-38.pyc | Bin 0 -> 3973 bytes .../pexpect/__pycache__/_async.cpython-38.pyc | Bin 0 -> 3301 bytes .../__pycache__/exceptions.cpython-38.pyc | Bin 0 -> 1860 bytes .../pexpect/__pycache__/expect.cpython-38.pyc | Bin 0 -> 9096 bytes .../__pycache__/fdpexpect.cpython-38.pyc | Bin 0 -> 5805 bytes .../__pycache__/popen_spawn.cpython-38.pyc | Bin 0 -> 5118 bytes .../__pycache__/pty_spawn.cpython-38.pyc | Bin 0 -> 32038 bytes .../pexpect/__pycache__/pxssh.cpython-38.pyc | Bin 0 -> 16762 bytes .../__pycache__/replwrap.cpython-38.pyc | Bin 0 -> 4587 bytes .../pexpect/__pycache__/run.cpython-38.pyc | Bin 0 -> 5827 bytes .../pexpect/__pycache__/screen.cpython-38.pyc | Bin 0 -> 14613 bytes .../__pycache__/spawnbase.cpython-38.pyc | Bin 0 -> 17577 bytes .../pexpect/__pycache__/utils.cpython-38.pyc | Bin 0 -> 3756 bytes .../python3.8/site-packages/pexpect/_async.py | 103 + .../python3.8/site-packages/pexpect/bashrc.sh | 16 + .../site-packages/pexpect/exceptions.py | 35 + .../python3.8/site-packages/pexpect/expect.py | 371 ++ .../site-packages/pexpect/fdpexpect.py | 148 + .../site-packages/pexpect/popen_spawn.py | 188 + .../site-packages/pexpect/pty_spawn.py | 860 +++ .../python3.8/site-packages/pexpect/pxssh.py | 537 ++ .../site-packages/pexpect/replwrap.py | 130 + .../python3.8/site-packages/pexpect/run.py | 157 + .../python3.8/site-packages/pexpect/screen.py | 431 ++ .../site-packages/pexpect/spawnbase.py | 525 ++ .../python3.8/site-packages/pexpect/utils.py | 187 + .../DESCRIPTION.rst | 27 + .../pickleshare-0.7.5.dist-info/INSTALLER | 1 + .../pickleshare-0.7.5.dist-info/METADATA | 43 + .../pickleshare-0.7.5.dist-info/RECORD | 9 + .../pickleshare-0.7.5.dist-info/WHEEL | 6 + .../pickleshare-0.7.5.dist-info/metadata.json | 1 + .../pickleshare-0.7.5.dist-info/top_level.txt | 1 + .../python3.8/site-packages/pickleshare.py | 352 + .../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 0 -> 629 bytes .../pip/__pycache__/__main__.cpython-38.pyc | Bin 0 -> 473 bytes .../site-packages/pip/_internal/__init__.py | 17 + .../__pycache__/__init__.cpython-38.pyc | Bin 0 -> 678 bytes .../__pycache__/build_env.cpython-38.pyc | Bin 0 -> 7391 bytes .../__pycache__/cache.cpython-38.pyc | Bin 0 -> 9090 bytes .../__pycache__/configuration.cpython-38.pyc | Bin 0 -> 10808 bytes .../__pycache__/exceptions.cpython-38.pyc | Bin 0 -> 12536 bytes .../__pycache__/locations.cpython-38.pyc | Bin 0 -> 4579 bytes .../_internal/__pycache__/main.cpython-38.pyc | Bin 0 -> 615 bytes .../__pycache__/pyproject.cpython-38.pyc | Bin 0 -> 3732 bytes .../self_outdated_check.cpython-38.pyc | Bin 0 -> 5493 bytes .../__pycache__/wheel_builder.cpython-38.pyc | Bin 0 -> 6800 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 0 -> 236 bytes .../__pycache__/autocompletion.cpython-38.pyc | Bin 0 -> 4953 bytes .../__pycache__/base_command.cpython-38.pyc | Bin 0 -> 5760 bytes .../cli/__pycache__/cmdoptions.cpython-38.pyc | Bin 0 -> 20537 bytes .../command_context.cpython-38.pyc | Bin 0 -> 1311 bytes .../cli/__pycache__/main.cpython-38.pyc | Bin 0 -> 1416 bytes .../__pycache__/main_parser.cpython-38.pyc | Bin 0 -> 2199 bytes .../cli/__pycache__/parser.cpython-38.pyc | Bin 0 -> 8966 bytes .../__pycache__/progress_bars.cpython-38.pyc | Bin 0 -> 7661 bytes .../__pycache__/req_command.cpython-38.pyc | Bin 0 -> 9918 bytes .../cli/__pycache__/spinners.cpython-38.pyc | Bin 0 -> 4756 bytes .../__pycache__/status_codes.cpython-38.pyc | Bin 0 -> 365 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 0 -> 2966 bytes .../commands/__pycache__/cache.cpython-38.pyc | Bin 0 -> 4394 bytes .../commands/__pycache__/check.cpython-38.pyc | Bin 0 -> 1564 bytes .../__pycache__/completion.cpython-38.pyc | Bin 0 -> 3017 bytes .../__pycache__/configuration.cpython-38.pyc | Bin 0 -> 6555 bytes .../commands/__pycache__/debug.cpython-38.pyc | Bin 0 -> 7322 bytes .../__pycache__/download.cpython-38.pyc | Bin 0 -> 3890 bytes .../__pycache__/freeze.cpython-38.pyc | Bin 0 -> 2867 bytes .../commands/__pycache__/hash.cpython-38.pyc | Bin 0 -> 2000 bytes .../commands/__pycache__/help.cpython-38.pyc | Bin 0 -> 1198 bytes .../__pycache__/install.cpython-38.pyc | Bin 0 -> 16474 bytes .../commands/__pycache__/list.cpython-38.pyc | Bin 0 -> 8470 bytes .../__pycache__/search.cpython-38.pyc | Bin 0 -> 4573 bytes .../commands/__pycache__/show.cpython-38.pyc | Bin 0 -> 6324 bytes .../__pycache__/uninstall.cpython-38.pyc | Bin 0 -> 2786 bytes .../commands/__pycache__/wheel.cpython-38.pyc | Bin 0 -> 5072 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 0 -> 812 bytes .../__pycache__/base.cpython-38.pyc | Bin 0 -> 1928 bytes .../__pycache__/installed.cpython-38.pyc | Bin 0 -> 1208 bytes .../__pycache__/sdist.cpython-38.pyc | Bin 0 -> 3471 bytes .../__pycache__/wheel.cpython-38.pyc | Bin 0 -> 1560 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 0 -> 190 bytes .../__pycache__/collector.cpython-38.pyc | Bin 0 -> 17512 bytes .../__pycache__/package_finder.cpython-38.pyc | Bin 0 -> 25793 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 0 -> 224 bytes .../__pycache__/candidate.cpython-38.pyc | Bin 0 -> 1421 bytes .../__pycache__/direct_url.cpython-38.pyc | Bin 0 -> 6498 bytes .../__pycache__/format_control.cpython-38.pyc | Bin 0 -> 2416 bytes .../models/__pycache__/index.cpython-38.pyc | Bin 0 -> 1146 bytes .../models/__pycache__/link.cpython-38.pyc | Bin 0 -> 7088 bytes .../models/__pycache__/scheme.cpython-38.pyc | Bin 0 -> 862 bytes .../__pycache__/search_scope.cpython-38.pyc | Bin 0 -> 3386 bytes .../selection_prefs.cpython-38.pyc | Bin 0 -> 1596 bytes .../__pycache__/target_python.cpython-38.pyc | Bin 0 -> 3249 bytes .../models/__pycache__/wheel.cpython-38.pyc | Bin 0 -> 3192 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 0 -> 212 bytes .../network/__pycache__/auth.cpython-38.pyc | Bin 0 -> 6985 bytes .../network/__pycache__/cache.cpython-38.pyc | Bin 0 -> 2691 bytes .../__pycache__/download.cpython-38.pyc | Bin 0 -> 4379 bytes .../__pycache__/session.cpython-38.pyc | Bin 0 -> 9217 bytes .../network/__pycache__/utils.cpython-38.pyc | Bin 0 -> 706 bytes .../network/__pycache__/xmlrpc.cpython-38.pyc | Bin 0 -> 1574 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 0 -> 160 bytes .../__pycache__/check.cpython-38.pyc | Bin 0 -> 3656 bytes .../__pycache__/freeze.cpython-38.pyc | Bin 0 -> 5895 bytes .../__pycache__/prepare.cpython-38.pyc | Bin 0 -> 10893 bytes .../_internal/operations/build/__init__.py | 0 .../build/__pycache__/__init__.cpython-38.pyc | Bin 0 -> 166 bytes .../build/__pycache__/metadata.cpython-38.pyc | Bin 0 -> 1208 bytes .../metadata_legacy.cpython-38.pyc | Bin 0 -> 1950 bytes .../build/__pycache__/wheel.cpython-38.pyc | Bin 0 -> 1306 bytes .../__pycache__/wheel_legacy.cpython-38.pyc | Bin 0 -> 2576 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 0 -> 224 bytes .../editable_legacy.cpython-38.pyc | Bin 0 -> 1302 bytes .../install/__pycache__/legacy.cpython-38.pyc | Bin 0 -> 3322 bytes .../install/__pycache__/wheel.cpython-38.pyc | Bin 0 -> 15071 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 0 -> 2194 bytes .../__pycache__/constructors.cpython-38.pyc | Bin 0 -> 10847 bytes .../req/__pycache__/req_file.cpython-38.pyc | Bin 0 -> 12809 bytes .../__pycache__/req_install.cpython-38.pyc | Bin 0 -> 20418 bytes .../req/__pycache__/req_set.cpython-38.pyc | Bin 0 -> 5840 bytes .../__pycache__/req_tracker.cpython-38.pyc | Bin 0 -> 4055 bytes .../__pycache__/req_uninstall.cpython-38.pyc | Bin 0 -> 17460 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 0 -> 160 bytes .../__pycache__/base.cpython-38.pyc | Bin 0 -> 992 bytes .../pip/_internal/resolution/base.py | 20 + .../_internal/resolution/legacy/__init__.py | 0 .../__pycache__/__init__.cpython-38.pyc | Bin 0 -> 167 bytes .../__pycache__/resolver.cpython-38.pyc | Bin 0 -> 11138 bytes .../_internal/resolution/legacy/resolver.py | 459 ++ .../resolution/resolvelib/__init__.py | 0 .../__pycache__/__init__.cpython-38.pyc | Bin 0 -> 171 bytes .../__pycache__/base.cpython-38.pyc | Bin 0 -> 2229 bytes .../__pycache__/candidates.cpython-38.pyc | Bin 0 -> 13326 bytes .../__pycache__/factory.cpython-38.pyc | Bin 0 -> 5261 bytes .../__pycache__/provider.cpython-38.pyc | Bin 0 -> 1915 bytes .../__pycache__/requirements.cpython-38.pyc | Bin 0 -> 4325 bytes .../__pycache__/resolver.cpython-38.pyc | Bin 0 -> 5497 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 0 -> 155 bytes .../utils/__pycache__/appdirs.cpython-38.pyc | Bin 0 -> 1345 bytes .../utils/__pycache__/compat.cpython-38.pyc | Bin 0 -> 6038 bytes .../compatibility_tags.cpython-38.pyc | Bin 0 -> 3599 bytes .../__pycache__/deprecation.cpython-38.pyc | Bin 0 -> 2826 bytes .../direct_url_helpers.cpython-38.pyc | Bin 0 -> 2676 bytes .../__pycache__/distutils_args.cpython-38.pyc | Bin 0 -> 1139 bytes .../utils/__pycache__/encoding.cpython-38.pyc | Bin 0 -> 1247 bytes .../__pycache__/entrypoints.cpython-38.pyc | Bin 0 -> 1299 bytes .../__pycache__/filesystem.cpython-38.pyc | Bin 0 -> 5603 bytes .../__pycache__/filetypes.cpython-38.pyc | Bin 0 -> 556 bytes .../utils/__pycache__/glibc.cpython-38.pyc | Bin 0 -> 1708 bytes .../utils/__pycache__/hashes.cpython-38.pyc | Bin 0 -> 4158 bytes .../inject_securetransport.cpython-38.pyc | Bin 0 -> 932 bytes .../utils/__pycache__/logging.cpython-38.pyc | Bin 0 -> 9179 bytes .../utils/__pycache__/misc.cpython-38.pyc | Bin 0 -> 24827 bytes .../utils/__pycache__/models.cpython-38.pyc | Bin 0 -> 1924 bytes .../__pycache__/packaging.cpython-38.pyc | Bin 0 -> 2608 bytes .../__pycache__/pkg_resources.cpython-38.pyc | Bin 0 -> 1822 bytes .../setuptools_build.cpython-38.pyc | Bin 0 -> 2921 bytes .../__pycache__/subprocess.cpython-38.pyc | Bin 0 -> 5590 bytes .../utils/__pycache__/temp_dir.cpython-38.pyc | Bin 0 -> 7037 bytes .../utils/__pycache__/typing.cpython-38.pyc | Bin 0 -> 1437 bytes .../__pycache__/unpacking.cpython-38.pyc | Bin 0 -> 6075 bytes .../utils/__pycache__/urls.cpython-38.pyc | Bin 0 -> 1507 bytes .../__pycache__/virtualenv.cpython-38.pyc | Bin 0 -> 3280 bytes .../utils/__pycache__/wheel.cpython-38.pyc | Bin 0 -> 6332 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 0 -> 448 bytes .../vcs/__pycache__/bazaar.cpython-38.pyc | Bin 0 -> 3747 bytes .../vcs/__pycache__/git.cpython-38.pyc | Bin 0 -> 9634 bytes .../vcs/__pycache__/mercurial.cpython-38.pyc | Bin 0 -> 5071 bytes .../vcs/__pycache__/subversion.cpython-38.pyc | Bin 0 -> 8519 bytes .../__pycache__/versioncontrol.cpython-38.pyc | Bin 0 -> 19646 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 0 -> 3281 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 0 -> 100356 bytes .../__pycache__/py31compat.cpython-38.pyc | Bin 0 -> 600 bytes .../pkg_resources/_vendor/__init__.py | 0 .../__pycache__/__init__.cpython-38.pyc | Bin 0 -> 157 bytes .../__pycache__/appdirs.cpython-38.pyc | Bin 0 -> 20510 bytes .../__pycache__/pyparsing.cpython-38.pyc | Bin 0 -> 201634 bytes .../_vendor/__pycache__/six.cpython-38.pyc | Bin 0 -> 24430 bytes .../pkg_resources/_vendor/appdirs.py | 608 ++ .../_vendor/packaging/__about__.py | 21 + .../_vendor/packaging/__init__.py | 14 + .../__pycache__/__about__.cpython-38.pyc | Bin 0 -> 707 bytes .../__pycache__/__init__.cpython-38.pyc | Bin 0 -> 545 bytes .../__pycache__/_compat.cpython-38.pyc | Bin 0 -> 981 bytes .../__pycache__/_structures.cpython-38.pyc | Bin 0 -> 2763 bytes .../__pycache__/markers.cpython-38.pyc | Bin 0 -> 8919 bytes .../__pycache__/requirements.cpython-38.pyc | Bin 0 -> 3878 bytes .../__pycache__/specifiers.cpython-38.pyc | Bin 0 -> 19787 bytes .../__pycache__/utils.cpython-38.pyc | Bin 0 -> 466 bytes .../__pycache__/version.cpython-38.pyc | Bin 0 -> 10634 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 0 -> 2406 bytes .../site-packages/pkg_resources/py31compat.py | 23 + .../AUTHORS.rst | 11 + .../prompt_toolkit-3.0.8.dist-info/INSTALLER | 1 + .../prompt_toolkit-3.0.8.dist-info/LICENSE | 27 + .../prompt_toolkit-3.0.8.dist-info/METADATA | 182 + .../prompt_toolkit-3.0.8.dist-info/RECORD | 290 + .../prompt_toolkit-3.0.8.dist-info/WHEEL | 5 + .../top_level.txt | 1 + .../site-packages/prompt_toolkit/__init__.py | 40 + .../__pycache__/__init__.cpython-38.pyc | Bin 0 -> 942 bytes .../__pycache__/auto_suggest.cpython-38.pyc | Bin 0 -> 7110 bytes .../__pycache__/buffer.cpython-38.pyc | Bin 0 -> 47307 bytes .../__pycache__/cache.cpython-38.pyc | Bin 0 -> 3918 bytes .../data_structures.cpython-38.pyc | Bin 0 -> 318 bytes .../__pycache__/document.cpython-38.pyc | Bin 0 -> 31700 bytes .../__pycache__/enums.cpython-38.pyc | Bin 0 -> 450 bytes .../__pycache__/history.cpython-38.pyc | Bin 0 -> 8469 bytes .../__pycache__/keys.cpython-38.pyc | Bin 0 -> 4700 bytes .../__pycache__/log.cpython-38.pyc | Bin 0 -> 273 bytes .../__pycache__/mouse_events.cpython-38.pyc | Bin 0 -> 1852 bytes .../__pycache__/patch_stdout.cpython-38.pyc | Bin 0 -> 5149 bytes .../__pycache__/renderer.cpython-38.pyc | Bin 0 -> 17971 bytes .../__pycache__/search.cpython-38.pyc | Bin 0 -> 5414 bytes .../__pycache__/selection.cpython-38.pyc | Bin 0 -> 1654 bytes .../__pycache__/token.cpython-38.pyc | Bin 0 -> 226 bytes .../__pycache__/utils.cpython-38.pyc | Bin 0 -> 8453 bytes .../__pycache__/validation.cpython-38.pyc | Bin 0 -> 7479 bytes .../__pycache__/win32_types.cpython-38.pyc | Bin 0 -> 4692 bytes .../prompt_toolkit/application/__init__.py | 28 + .../__pycache__/__init__.cpython-38.pyc | Bin 0 -> 579 bytes .../__pycache__/application.cpython-38.pyc | Bin 0 -> 33477 bytes .../__pycache__/current.cpython-38.pyc | Bin 0 -> 5158 bytes .../__pycache__/dummy.cpython-38.pyc | Bin 0 -> 1985 bytes .../run_in_terminal.cpython-38.pyc | Bin 0 -> 3155 bytes .../prompt_toolkit/application/application.py | 1224 ++++ .../prompt_toolkit/application/current.py | 170 + .../prompt_toolkit/application/dummy.py | 47 + .../application/run_in_terminal.py | 116 + .../prompt_toolkit/auto_suggest.py | 187 + .../site-packages/prompt_toolkit/buffer.py | 1959 ++++++ .../site-packages/prompt_toolkit/cache.py | 125 + .../prompt_toolkit/clipboard/__init__.py | 15 + .../__pycache__/__init__.cpython-38.pyc | Bin 0 -> 385 bytes .../clipboard/__pycache__/base.cpython-38.pyc | Bin 0 -> 4147 bytes .../__pycache__/in_memory.cpython-38.pyc | Bin 0 -> 1544 bytes .../__pycache__/pyperclip.cpython-38.pyc | Bin 0 -> 1286 bytes .../prompt_toolkit/clipboard/base.py | 107 + .../prompt_toolkit/clipboard/in_memory.py | 46 + .../prompt_toolkit/clipboard/pyperclip.py | 42 + .../prompt_toolkit/completion/__init__.py | 36 + .../__pycache__/__init__.cpython-38.pyc | Bin 0 -> 788 bytes .../__pycache__/base.cpython-38.pyc | Bin 0 -> 12250 bytes .../__pycache__/filesystem.cpython-38.pyc | Bin 0 -> 3677 bytes .../fuzzy_completer.cpython-38.pyc | Bin 0 -> 6257 bytes .../__pycache__/nested.cpython-38.pyc | Bin 0 -> 3640 bytes .../__pycache__/word_completer.cpython-38.pyc | Bin 0 -> 3023 bytes .../prompt_toolkit/completion/base.py | 349 + .../prompt_toolkit/completion/filesystem.py | 113 + .../completion/fuzzy_completer.py | 199 + .../prompt_toolkit/completion/nested.py | 109 + .../completion/word_completer.py | 84 + .../prompt_toolkit/contrib/__init__.py | 0 .../__pycache__/__init__.cpython-38.pyc | Bin 0 -> 158 bytes .../contrib/completers/__init__.py | 3 + .../__pycache__/__init__.cpython-38.pyc | Bin 0 -> 237 bytes .../__pycache__/system.cpython-38.pyc | Bin 0 -> 2120 bytes .../contrib/completers/system.py | 62 + .../contrib/regular_languages/__init__.py | 77 + .../__pycache__/__init__.cpython-38.pyc | Bin 0 -> 3440 bytes .../__pycache__/compiler.cpython-38.pyc | Bin 0 -> 18288 bytes .../__pycache__/completion.cpython-38.pyc | Bin 0 -> 2964 bytes .../__pycache__/lexer.cpython-38.pyc | Bin 0 -> 3274 bytes .../__pycache__/regex_parser.cpython-38.pyc | Bin 0 -> 8858 bytes .../__pycache__/validation.cpython-38.pyc | Bin 0 -> 1819 bytes .../contrib/regular_languages/compiler.py | 573 ++ .../contrib/regular_languages/completion.py | 94 + .../contrib/regular_languages/lexer.py | 92 + .../contrib/regular_languages/regex_parser.py | 281 + .../contrib/regular_languages/validation.py | 60 + .../prompt_toolkit/contrib/ssh/__init__.py | 6 + .../ssh/__pycache__/__init__.cpython-38.pyc | Bin 0 -> 282 bytes .../ssh/__pycache__/server.cpython-38.pyc | Bin 0 -> 5929 bytes .../prompt_toolkit/contrib/ssh/server.py | 151 + .../prompt_toolkit/contrib/telnet/__init__.py | 5 + .../__pycache__/__init__.cpython-38.pyc | Bin 0 -> 232 bytes .../telnet/__pycache__/log.cpython-38.pyc | Bin 0 -> 302 bytes .../__pycache__/protocol.cpython-38.pyc | Bin 0 -> 5307 bytes .../telnet/__pycache__/server.cpython-38.pyc | Bin 0 -> 10659 bytes .../prompt_toolkit/contrib/telnet/log.py | 10 + .../prompt_toolkit/contrib/telnet/protocol.py | 207 + .../prompt_toolkit/contrib/telnet/server.py | 349 + .../prompt_toolkit/data_structures.py | 10 + .../site-packages/prompt_toolkit/document.py | 1180 ++++ .../site-packages/prompt_toolkit/enums.py | 17 + .../prompt_toolkit/eventloop/__init__.py | 26 + .../__pycache__/__init__.cpython-38.pyc | Bin 0 -> 597 bytes .../async_context_manager.cpython-38.pyc | Bin 0 -> 3739 bytes .../async_generator.cpython-38.pyc | Bin 0 -> 1620 bytes .../dummy_contextvars.cpython-38.pyc | Bin 0 -> 2180 bytes .../__pycache__/inputhook.cpython-38.pyc | Bin 0 -> 5097 bytes .../__pycache__/utils.cpython-38.pyc | Bin 0 -> 2775 bytes .../__pycache__/win32.cpython-38.pyc | Bin 0 -> 2107 bytes .../eventloop/async_context_manager.py | 124 + .../eventloop/async_generator.py | 67 + .../eventloop/dummy_contextvars.py | 46 + .../prompt_toolkit/eventloop/inputhook.py | 170 + .../prompt_toolkit/eventloop/utils.py | 100 + .../prompt_toolkit/eventloop/win32.py | 61 + .../prompt_toolkit/filters/__init__.py | 22 + .../__pycache__/__init__.cpython-38.pyc | Bin 0 -> 1261 bytes .../filters/__pycache__/app.cpython-38.pyc | Bin 0 -> 9619 bytes .../filters/__pycache__/base.cpython-38.pyc | Bin 0 -> 8364 bytes .../filters/__pycache__/cli.cpython-38.pyc | Bin 0 -> 3320 bytes .../filters/__pycache__/utils.cpython-38.pyc | Bin 0 -> 1038 bytes .../prompt_toolkit/filters/app.py | 402 ++ .../prompt_toolkit/filters/base.py | 217 + .../prompt_toolkit/filters/cli.py | 62 + .../prompt_toolkit/filters/utils.py | 41 + .../prompt_toolkit/formatted_text/__init__.py | 52 + .../__pycache__/__init__.cpython-38.pyc | Bin 0 -> 1383 bytes .../__pycache__/ansi.cpython-38.pyc | Bin 0 -> 5457 bytes .../__pycache__/base.cpython-38.pyc | Bin 0 -> 5067 bytes .../__pycache__/html.cpython-38.pyc | Bin 0 -> 4145 bytes .../__pycache__/pygments.cpython-38.pyc | Bin 0 -> 1198 bytes .../__pycache__/utils.cpython-38.pyc | Bin 0 -> 2816 bytes .../prompt_toolkit/formatted_text/ansi.py | 246 + .../prompt_toolkit/formatted_text/base.py | 175 + .../prompt_toolkit/formatted_text/html.py | 137 + .../prompt_toolkit/formatted_text/pygments.py | 30 + .../prompt_toolkit/formatted_text/utils.py | 85 + .../site-packages/prompt_toolkit/history.py | 232 + .../prompt_toolkit/input/__init__.py | 11 + .../input/__pycache__/__init__.cpython-38.pyc | Bin 0 -> 335 bytes .../ansi_escape_sequences.cpython-38.pyc | Bin 0 -> 6205 bytes .../input/__pycache__/base.cpython-38.pyc | Bin 0 -> 5281 bytes .../input/__pycache__/defaults.cpython-38.pyc | Bin 0 -> 1554 bytes .../__pycache__/posix_pipe.cpython-38.pyc | Bin 0 -> 2810 bytes .../__pycache__/posix_utils.cpython-38.pyc | Bin 0 -> 2433 bytes .../__pycache__/typeahead.cpython-38.pyc | Bin 0 -> 2770 bytes .../input/__pycache__/vt100.cpython-38.pyc | Bin 0 -> 7692 bytes .../__pycache__/vt100_parser.cpython-38.pyc | Bin 0 -> 6057 bytes .../input/__pycache__/win32.cpython-38.pyc | Bin 0 -> 16196 bytes .../__pycache__/win32_pipe.cpython-38.pyc | Bin 0 -> 4580 bytes .../input/ansi_escape_sequences.py | 331 + .../prompt_toolkit/input/base.py | 137 + .../prompt_toolkit/input/defaults.py | 58 + .../prompt_toolkit/input/posix_pipe.py | 72 + .../prompt_toolkit/input/posix_utils.py | 95 + .../prompt_toolkit/input/typeahead.py | 76 + .../prompt_toolkit/input/vt100.py | 308 + .../prompt_toolkit/input/vt100_parser.py | 247 + .../prompt_toolkit/input/win32.py | 655 ++ .../prompt_toolkit/input/win32_pipe.py | 134 + .../prompt_toolkit/key_binding/__init__.py | 20 + .../__pycache__/__init__.cpython-38.pyc | Bin 0 -> 475 bytes .../__pycache__/defaults.cpython-38.pyc | Bin 0 -> 1397 bytes .../__pycache__/digraphs.cpython-38.pyc | Bin 0 -> 30754 bytes .../__pycache__/emacs_state.cpython-38.pyc | Bin 0 -> 1358 bytes .../__pycache__/key_bindings.cpython-38.pyc | Bin 0 -> 18349 bytes .../__pycache__/key_processor.cpython-38.pyc | Bin 0 -> 14947 bytes .../__pycache__/vi_state.cpython-38.pyc | Bin 0 -> 2540 bytes .../key_binding/bindings/__init__.py | 0 .../__pycache__/__init__.cpython-38.pyc | Bin 0 -> 171 bytes .../__pycache__/auto_suggest.cpython-38.pyc | Bin 0 -> 2223 bytes .../bindings/__pycache__/basic.cpython-38.pyc | Bin 0 -> 6714 bytes .../__pycache__/completion.cpython-38.pyc | Bin 0 -> 6058 bytes .../bindings/__pycache__/cpr.cpython-38.pyc | Bin 0 -> 1043 bytes .../bindings/__pycache__/emacs.cpython-38.pyc | Bin 0 -> 16423 bytes .../bindings/__pycache__/focus.cpython-38.pyc | Bin 0 -> 742 bytes .../bindings/__pycache__/mouse.cpython-38.pyc | Bin 0 -> 3356 bytes .../__pycache__/named_commands.cpython-38.pyc | Bin 0 -> 18689 bytes .../__pycache__/open_in_editor.cpython-38.pyc | Bin 0 -> 1388 bytes .../page_navigation.cpython-38.pyc | Bin 0 -> 1912 bytes .../__pycache__/scroll.cpython-38.pyc | Bin 0 -> 3846 bytes .../__pycache__/search.cpython-38.pyc | Bin 0 -> 2903 bytes .../bindings/__pycache__/vi.cpython-38.pyc | Bin 0 -> 62708 bytes .../key_binding/bindings/auto_suggest.py | 63 + .../key_binding/bindings/basic.py | 252 + .../key_binding/bindings/completion.py | 203 + .../key_binding/bindings/cpr.py | 28 + .../key_binding/bindings/emacs.py | 556 ++ .../key_binding/bindings/focus.py | 24 + .../key_binding/bindings/mouse.py | 146 + .../key_binding/bindings/named_commands.py | 687 ++ .../key_binding/bindings/open_in_editor.py | 49 + .../key_binding/bindings/page_navigation.py | 82 + .../key_binding/bindings/scroll.py | 187 + .../key_binding/bindings/search.py | 93 + .../prompt_toolkit/key_binding/bindings/vi.py | 2221 +++++++ .../prompt_toolkit/key_binding/defaults.py | 60 + .../prompt_toolkit/key_binding/digraphs.py | 1378 ++++ .../prompt_toolkit/key_binding/emacs_state.py | 36 + .../key_binding/key_bindings.py | 635 ++ .../key_binding/key_processor.py | 530 ++ .../prompt_toolkit/key_binding/vi_state.py | 107 + .../site-packages/prompt_toolkit/keys.py | 219 + .../prompt_toolkit/layout/__init__.py | 142 + .../__pycache__/__init__.cpython-38.pyc | Bin 0 -> 3319 bytes .../__pycache__/containers.cpython-38.pyc | Bin 0 -> 67630 bytes .../__pycache__/controls.cpython-38.pyc | Bin 0 -> 27178 bytes .../__pycache__/dimension.cpython-38.pyc | Bin 0 -> 5885 bytes .../layout/__pycache__/dummy.cpython-38.pyc | Bin 0 -> 1381 bytes .../layout/__pycache__/layout.cpython-38.pyc | Bin 0 -> 10959 bytes .../layout/__pycache__/margins.cpython-38.pyc | Bin 0 -> 8853 bytes .../layout/__pycache__/menus.cpython-38.pyc | Bin 0 -> 20772 bytes .../__pycache__/mouse_handlers.cpython-38.pyc | Bin 0 -> 1606 bytes .../__pycache__/processors.cpython-38.pyc | Bin 0 -> 28628 bytes .../layout/__pycache__/screen.cpython-38.pyc | Bin 0 -> 7893 bytes .../layout/__pycache__/utils.cpython-38.pyc | Bin 0 -> 2621 bytes .../prompt_toolkit/layout/containers.py | 2702 ++++++++ .../prompt_toolkit/layout/controls.py | 947 +++ .../prompt_toolkit/layout/dimension.py | 214 + .../prompt_toolkit/layout/dummy.py | 37 + .../prompt_toolkit/layout/layout.py | 417 ++ .../prompt_toolkit/layout/margins.py | 305 + .../prompt_toolkit/layout/menus.py | 720 +++ .../prompt_toolkit/layout/mouse_handlers.py | 40 + .../prompt_toolkit/layout/processors.py | 1029 +++ .../prompt_toolkit/layout/screen.py | 316 + .../prompt_toolkit/layout/utils.py | 76 + .../prompt_toolkit/lexers/__init__.py | 18 + .../__pycache__/__init__.cpython-38.pyc | Bin 0 -> 510 bytes .../lexers/__pycache__/base.cpython-38.pyc | Bin 0 -> 3375 bytes .../__pycache__/pygments.cpython-38.pyc | Bin 0 -> 9422 bytes .../prompt_toolkit/lexers/base.py | 82 + .../prompt_toolkit/lexers/pygments.py | 335 + .../site-packages/prompt_toolkit/log.py | 10 + .../prompt_toolkit/mouse_events.py | 45 + .../prompt_toolkit/output/__init__.py | 13 + .../__pycache__/__init__.cpython-38.pyc | Bin 0 -> 357 bytes .../output/__pycache__/base.cpython-38.pyc | Bin 0 -> 13029 bytes .../__pycache__/color_depth.cpython-38.pyc | Bin 0 -> 1646 bytes .../output/__pycache__/conemu.cpython-38.pyc | Bin 0 -> 2250 bytes .../__pycache__/defaults.cpython-38.pyc | Bin 0 -> 1749 bytes .../output/__pycache__/vt100.cpython-38.pyc | Bin 0 -> 18063 bytes .../output/__pycache__/win32.cpython-38.pyc | Bin 0 -> 17676 bytes .../__pycache__/windows10.cpython-38.pyc | Bin 0 -> 3043 bytes .../prompt_toolkit/output/base.py | 303 + .../prompt_toolkit/output/color_depth.py | 58 + .../prompt_toolkit/output/conemu.py | 59 + .../prompt_toolkit/output/defaults.py | 76 + .../prompt_toolkit/output/vt100.py | 738 +++ .../prompt_toolkit/output/win32.py | 656 ++ .../prompt_toolkit/output/windows10.py | 104 + .../prompt_toolkit/patch_stdout.py | 167 + .../site-packages/prompt_toolkit/py.typed | 0 .../site-packages/prompt_toolkit/renderer.py | 783 +++ .../site-packages/prompt_toolkit/search.py | 229 + .../site-packages/prompt_toolkit/selection.py | 60 + .../prompt_toolkit/shortcuts/__init__.py | 44 + .../__pycache__/__init__.cpython-38.pyc | Bin 0 -> 885 bytes .../__pycache__/dialogs.cpython-38.pyc | Bin 0 -> 8650 bytes .../__pycache__/prompt.cpython-38.pyc | Bin 0 -> 38664 bytes .../__pycache__/utils.cpython-38.pyc | Bin 0 -> 5590 bytes .../prompt_toolkit/shortcuts/dialogs.py | 324 + .../shortcuts/progress_bar/__init__.py | 31 + .../__pycache__/__init__.cpython-38.pyc | Bin 0 -> 616 bytes .../__pycache__/base.cpython-38.pyc | Bin 0 -> 13381 bytes .../__pycache__/formatters.cpython-38.pyc | Bin 0 -> 12568 bytes .../shortcuts/progress_bar/base.py | 451 ++ .../shortcuts/progress_bar/formatters.py | 436 ++ .../prompt_toolkit/shortcuts/prompt.py | 1467 +++++ .../prompt_toolkit/shortcuts/utils.py | 198 + .../prompt_toolkit/styles/__init__.py | 64 + .../__pycache__/__init__.cpython-38.pyc | Bin 0 -> 1353 bytes .../styles/__pycache__/base.cpython-38.pyc | Bin 0 -> 4633 bytes .../__pycache__/defaults.cpython-38.pyc | Bin 0 -> 6163 bytes .../__pycache__/named_colors.cpython-38.pyc | Bin 0 -> 3882 bytes .../__pycache__/pygments.cpython-38.pyc | Bin 0 -> 2103 bytes .../styles/__pycache__/style.cpython-38.pyc | Bin 0 -> 11011 bytes .../style_transformation.cpython-38.pyc | Bin 0 -> 12944 bytes .../prompt_toolkit/styles/base.py | 181 + .../prompt_toolkit/styles/defaults.py | 227 + .../prompt_toolkit/styles/named_colors.py | 161 + .../prompt_toolkit/styles/pygments.py | 67 + .../prompt_toolkit/styles/style.py | 398 ++ .../styles/style_transformation.py | 375 ++ .../site-packages/prompt_toolkit/token.py | 8 + .../site-packages/prompt_toolkit/utils.py | 312 + .../prompt_toolkit/validation.py | 194 + .../prompt_toolkit/widgets/__init__.py | 60 + .../__pycache__/__init__.cpython-38.pyc | Bin 0 -> 1211 bytes .../widgets/__pycache__/base.cpython-38.pyc | Bin 0 -> 27184 bytes .../__pycache__/dialogs.cpython-38.pyc | Bin 0 -> 3051 bytes .../widgets/__pycache__/menus.cpython-38.pyc | Bin 0 -> 10791 bytes .../__pycache__/toolbars.cpython-38.pyc | Bin 0 -> 11109 bytes .../prompt_toolkit/widgets/base.py | 916 +++ .../prompt_toolkit/widgets/dialogs.py | 106 + .../prompt_toolkit/widgets/menus.py | 360 ++ .../prompt_toolkit/widgets/toolbars.py | 374 ++ .../prompt_toolkit/win32_types.py | 166 + .../ptyprocess-0.6.0.dist-info/INSTALLER | 1 + .../ptyprocess-0.6.0.dist-info/LICENSE | 16 + .../ptyprocess-0.6.0.dist-info/METADATA | 37 + .../ptyprocess-0.6.0.dist-info/RECORD | 13 + .../ptyprocess-0.6.0.dist-info/WHEEL | 5 + .../site-packages/ptyprocess/__init__.py | 4 + .../__pycache__/__init__.cpython-38.pyc | Bin 0 -> 325 bytes .../__pycache__/_fork_pty.cpython-38.pyc | Bin 0 -> 1972 bytes .../__pycache__/ptyprocess.cpython-38.pyc | Bin 0 -> 22693 bytes .../__pycache__/util.cpython-38.pyc | Bin 0 -> 1982 bytes .../site-packages/ptyprocess/_fork_pty.py | 78 + .../site-packages/ptyprocess/ptyprocess.py | 836 +++ .../site-packages/ptyprocess/util.py | 71 + .../site-packages/pygments/__init__.py | 85 + .../site-packages/pygments/__main__.py | 18 + .../__pycache__/__init__.cpython-38.pyc | Bin 0 -> 2972 bytes .../__pycache__/__main__.cpython-38.pyc | Bin 0 -> 540 bytes .../__pycache__/cmdline.cpython-38.pyc | Bin 0 -> 12630 bytes .../__pycache__/console.cpython-38.pyc | Bin 0 -> 1866 bytes .../__pycache__/filter.cpython-38.pyc | Bin 0 -> 2592 bytes .../__pycache__/formatter.cpython-38.pyc | Bin 0 -> 2936 bytes .../pygments/__pycache__/lexer.cpython-38.pyc | Bin 0 -> 24308 bytes .../__pycache__/modeline.cpython-38.pyc | Bin 0 -> 1138 bytes .../__pycache__/plugin.cpython-38.pyc | Bin 0 -> 2036 bytes .../__pycache__/regexopt.cpython-38.pyc | Bin 0 -> 2902 bytes .../__pycache__/scanner.cpython-38.pyc | Bin 0 -> 3505 bytes .../__pycache__/sphinxext.cpython-38.pyc | Bin 0 -> 4474 bytes .../pygments/__pycache__/style.cpython-38.pyc | Bin 0 -> 4373 bytes .../pygments/__pycache__/token.cpython-38.pyc | Bin 0 -> 4465 bytes .../__pycache__/unistring.cpython-38.pyc | Bin 0 -> 31202 bytes .../pygments/__pycache__/util.cpython-38.pyc | Bin 0 -> 9191 bytes .../site-packages/pygments/cmdline.py | 582 ++ .../site-packages/pygments/console.py | 71 + .../site-packages/pygments/filter.py | 72 + .../pygments/filters/__init__.py | 938 +++ .../__pycache__/__init__.cpython-38.pyc | Bin 0 -> 23268 bytes .../site-packages/pygments/formatter.py | 95 + .../pygments/formatters/__init__.py | 154 + .../__pycache__/__init__.cpython-38.pyc | Bin 0 -> 4527 bytes .../__pycache__/_mapping.cpython-38.pyc | Bin 0 -> 4988 bytes .../__pycache__/bbcode.cpython-38.pyc | Bin 0 -> 2989 bytes .../__pycache__/html.cpython-38.pyc | Bin 0 -> 27960 bytes .../formatters/__pycache__/img.cpython-38.pyc | Bin 0 -> 16962 bytes .../formatters/__pycache__/irc.cpython-38.pyc | Bin 0 -> 4381 bytes .../__pycache__/latex.cpython-38.pyc | Bin 0 -> 13422 bytes .../__pycache__/other.cpython-38.pyc | Bin 0 -> 4880 bytes .../formatters/__pycache__/rtf.cpython-38.pyc | Bin 0 -> 4052 bytes .../formatters/__pycache__/svg.cpython-38.pyc | Bin 0 -> 6250 bytes .../__pycache__/terminal.cpython-38.pyc | Bin 0 -> 3874 bytes .../__pycache__/terminal256.cpython-38.pyc | Bin 0 -> 8649 bytes .../pygments/formatters/_mapping.py | 83 + .../pygments/formatters/bbcode.py | 109 + .../site-packages/pygments/formatters/html.py | 939 +++ .../site-packages/pygments/formatters/img.py | 627 ++ .../site-packages/pygments/formatters/irc.py | 182 + .../pygments/formatters/latex.py | 512 ++ .../pygments/formatters/other.py | 164 + .../site-packages/pygments/formatters/rtf.py | 147 + .../site-packages/pygments/formatters/svg.py | 187 + .../pygments/formatters/terminal.py | 130 + .../pygments/formatters/terminal256.py | 319 + .../python3.8/site-packages/pygments/lexer.py | 873 +++ .../site-packages/pygments/lexers/__init__.py | 342 + .../__pycache__/__init__.cpython-38.pyc | Bin 0 -> 8959 bytes .../__pycache__/_asy_builtins.cpython-38.pyc | Bin 0 -> 26611 bytes .../__pycache__/_cl_builtins.cpython-38.pyc | Bin 0 -> 16159 bytes .../_cocoa_builtins.cpython-38.pyc | Bin 0 -> 42489 bytes .../_csound_builtins.cpython-38.pyc | Bin 0 -> 15625 bytes .../_lasso_builtins.cpython-38.pyc | Bin 0 -> 76798 bytes .../__pycache__/_lua_builtins.cpython-38.pyc | Bin 0 -> 6557 bytes .../__pycache__/_mapping.cpython-38.pyc | Bin 0 -> 45660 bytes .../__pycache__/_mql_builtins.cpython-38.pyc | Bin 0 -> 17954 bytes .../_mysql_builtins.cpython-38.pyc | Bin 0 -> 16260 bytes .../_openedge_builtins.cpython-38.pyc | Bin 0 -> 33306 bytes .../__pycache__/_php_builtins.cpython-38.pyc | Bin 0 -> 88963 bytes .../_postgres_builtins.cpython-38.pyc | Bin 0 -> 8221 bytes .../_scilab_builtins.cpython-38.pyc | Bin 0 -> 34102 bytes .../_sourcemod_builtins.cpython-38.pyc | Bin 0 -> 20682 bytes .../__pycache__/_stan_builtins.cpython-38.pyc | Bin 0 -> 7430 bytes .../_stata_builtins.cpython-38.pyc | Bin 0 -> 19535 bytes .../__pycache__/_tsql_builtins.cpython-38.pyc | Bin 0 -> 8742 bytes .../__pycache__/_usd_builtins.cpython-38.pyc | Bin 0 -> 1646 bytes .../_vbscript_builtins.cpython-38.pyc | Bin 0 -> 3789 bytes .../__pycache__/_vim_builtins.cpython-38.pyc | Bin 0 -> 30647 bytes .../__pycache__/actionscript.cpython-38.pyc | Bin 0 -> 8693 bytes .../lexers/__pycache__/agile.cpython-38.pyc | Bin 0 -> 1237 bytes .../lexers/__pycache__/algebra.cpython-38.pyc | Bin 0 -> 6901 bytes .../lexers/__pycache__/ambient.cpython-38.pyc | Bin 0 -> 2219 bytes .../lexers/__pycache__/ampl.cpython-38.pyc | Bin 0 -> 3205 bytes .../lexers/__pycache__/apl.cpython-38.pyc | Bin 0 -> 1883 bytes .../__pycache__/archetype.cpython-38.pyc | Bin 0 -> 6345 bytes .../lexers/__pycache__/arrow.cpython-38.pyc | Bin 0 -> 2315 bytes .../lexers/__pycache__/asm.cpython-38.pyc | Bin 0 -> 25295 bytes .../__pycache__/automation.cpython-38.pyc | Bin 0 -> 16025 bytes .../lexers/__pycache__/bare.cpython-38.pyc | Bin 0 -> 2166 bytes .../lexers/__pycache__/basic.cpython-38.pyc | Bin 0 -> 17608 bytes .../lexers/__pycache__/bibtex.cpython-38.pyc | Bin 0 -> 3546 bytes .../lexers/__pycache__/boa.cpython-38.pyc | Bin 0 -> 2962 bytes .../__pycache__/business.cpython-38.pyc | Bin 0 -> 18666 bytes .../lexers/__pycache__/c_cpp.cpython-38.pyc | Bin 0 -> 10774 bytes .../lexers/__pycache__/c_like.cpython-38.pyc | Bin 0 -> 20939 bytes .../__pycache__/capnproto.cpython-38.pyc | Bin 0 -> 1721 bytes .../lexers/__pycache__/chapel.cpython-38.pyc | Bin 0 -> 2790 bytes .../lexers/__pycache__/clean.cpython-38.pyc | Bin 0 -> 3835 bytes .../__pycache__/compiled.cpython-38.pyc | Bin 0 -> 1853 bytes .../lexers/__pycache__/configs.cpython-38.pyc | Bin 0 -> 23354 bytes .../lexers/__pycache__/console.cpython-38.pyc | Bin 0 -> 3460 bytes .../lexers/__pycache__/crystal.cpython-38.pyc | Bin 0 -> 9654 bytes .../lexers/__pycache__/csound.cpython-38.pyc | Bin 0 -> 8646 bytes .../lexers/__pycache__/css.cpython-38.pyc | Bin 0 -> 20750 bytes .../lexers/__pycache__/d.cpython-38.pyc | Bin 0 -> 5846 bytes .../lexers/__pycache__/dalvik.cpython-38.pyc | Bin 0 -> 3320 bytes .../lexers/__pycache__/data.cpython-38.pyc | Bin 0 -> 12121 bytes .../__pycache__/devicetree.cpython-38.pyc | Bin 0 -> 2628 bytes .../lexers/__pycache__/diff.cpython-38.pyc | Bin 0 -> 3685 bytes .../lexers/__pycache__/dotnet.cpython-38.pyc | Bin 0 -> 19471 bytes .../lexers/__pycache__/dsls.cpython-38.pyc | Bin 0 -> 23743 bytes .../lexers/__pycache__/dylan.cpython-38.pyc | Bin 0 -> 8092 bytes .../lexers/__pycache__/ecl.cpython-38.pyc | Bin 0 -> 4742 bytes .../lexers/__pycache__/eiffel.cpython-38.pyc | Bin 0 -> 2213 bytes .../lexers/__pycache__/elm.cpython-38.pyc | Bin 0 -> 2127 bytes .../lexers/__pycache__/email.cpython-38.pyc | Bin 0 -> 4302 bytes .../lexers/__pycache__/erlang.cpython-38.pyc | Bin 0 -> 12705 bytes .../__pycache__/esoteric.cpython-38.pyc | Bin 0 -> 7596 bytes .../lexers/__pycache__/ezhil.cpython-38.pyc | Bin 0 -> 3277 bytes .../lexers/__pycache__/factor.cpython-38.pyc | Bin 0 -> 12300 bytes .../lexers/__pycache__/fantom.cpython-38.pyc | Bin 0 -> 4842 bytes .../lexers/__pycache__/felix.cpython-38.pyc | Bin 0 -> 5511 bytes .../__pycache__/floscript.cpython-38.pyc | Bin 0 -> 2286 bytes .../lexers/__pycache__/forth.cpython-38.pyc | Bin 0 -> 4638 bytes .../lexers/__pycache__/fortran.cpython-38.pyc | Bin 0 -> 7043 bytes .../lexers/__pycache__/foxpro.cpython-38.pyc | Bin 0 -> 20057 bytes .../lexers/__pycache__/freefem.cpython-38.pyc | Bin 0 -> 16899 bytes .../__pycache__/functional.cpython-38.pyc | Bin 0 -> 973 bytes .../__pycache__/gdscript.cpython-38.pyc | Bin 0 -> 5083 bytes .../lexers/__pycache__/go.cpython-38.pyc | Bin 0 -> 2621 bytes .../grammar_notation.cpython-38.pyc | Bin 0 -> 5876 bytes .../lexers/__pycache__/graph.cpython-38.pyc | Bin 0 -> 2370 bytes .../__pycache__/graphics.cpython-38.pyc | Bin 0 -> 24806 bytes .../lexers/__pycache__/haskell.cpython-38.pyc | Bin 0 -> 18763 bytes .../lexers/__pycache__/haxe.cpython-38.pyc | Bin 0 -> 12035 bytes .../lexers/__pycache__/hdl.cpython-38.pyc | Bin 0 -> 13239 bytes .../lexers/__pycache__/hexdump.cpython-38.pyc | Bin 0 -> 2627 bytes .../lexers/__pycache__/html.cpython-38.pyc | Bin 0 -> 11818 bytes .../lexers/__pycache__/idl.cpython-38.pyc | Bin 0 -> 11677 bytes .../lexers/__pycache__/igor.cpython-38.pyc | Bin 0 -> 24567 bytes .../lexers/__pycache__/inferno.cpython-38.pyc | Bin 0 -> 2542 bytes .../__pycache__/installers.cpython-38.pyc | Bin 0 -> 9517 bytes .../__pycache__/int_fiction.cpython-38.pyc | Bin 0 -> 27355 bytes .../lexers/__pycache__/iolang.cpython-38.pyc | Bin 0 -> 1681 bytes .../lexers/__pycache__/j.cpython-38.pyc | Bin 0 -> 2931 bytes .../__pycache__/javascript.cpython-38.pyc | Bin 0 -> 34176 bytes .../lexers/__pycache__/julia.cpython-38.pyc | Bin 0 -> 9733 bytes .../lexers/__pycache__/jvm.cpython-38.pyc | Bin 0 -> 41154 bytes .../lexers/__pycache__/lisp.cpython-38.pyc | Bin 0 -> 105650 bytes .../lexers/__pycache__/make.cpython-38.pyc | Bin 0 -> 4536 bytes .../lexers/__pycache__/markup.cpython-38.pyc | Bin 0 -> 17360 bytes .../lexers/__pycache__/math.cpython-38.pyc | Bin 0 -> 976 bytes .../lexers/__pycache__/matlab.cpython-38.pyc | Bin 0 -> 18959 bytes .../lexers/__pycache__/mime.cpython-38.pyc | Bin 0 -> 6346 bytes .../lexers/__pycache__/ml.cpython-38.pyc | Bin 0 -> 15023 bytes .../__pycache__/modeling.cpython-38.pyc | Bin 0 -> 8440 bytes .../lexers/__pycache__/modula2.cpython-38.pyc | Bin 0 -> 19838 bytes .../lexers/__pycache__/monte.cpython-38.pyc | Bin 0 -> 4144 bytes .../lexers/__pycache__/mosel.cpython-38.pyc | Bin 0 -> 6172 bytes .../lexers/__pycache__/ncl.cpython-38.pyc | Bin 0 -> 45347 bytes .../lexers/__pycache__/nimrod.cpython-38.pyc | Bin 0 -> 3906 bytes .../lexers/__pycache__/nit.cpython-38.pyc | Bin 0 -> 2299 bytes .../lexers/__pycache__/nix.cpython-38.pyc | Bin 0 -> 3321 bytes .../lexers/__pycache__/oberon.cpython-38.pyc | Bin 0 -> 2945 bytes .../__pycache__/objective.cpython-38.pyc | Bin 0 -> 14445 bytes .../lexers/__pycache__/ooc.cpython-38.pyc | Bin 0 -> 2366 bytes .../lexers/__pycache__/other.cpython-38.pyc | Bin 0 -> 2341 bytes .../__pycache__/parasail.cpython-38.pyc | Bin 0 -> 2287 bytes .../lexers/__pycache__/parsers.cpython-38.pyc | Bin 0 -> 17911 bytes .../lexers/__pycache__/pascal.cpython-38.pyc | Bin 0 -> 21430 bytes .../lexers/__pycache__/pawn.cpython-38.pyc | Bin 0 -> 5838 bytes .../lexers/__pycache__/perl.cpython-38.pyc | Bin 0 -> 27115 bytes .../lexers/__pycache__/php.cpython-38.pyc | Bin 0 -> 9475 bytes .../__pycache__/pointless.cpython-38.pyc | Bin 0 -> 1949 bytes .../lexers/__pycache__/pony.cpython-38.pyc | Bin 0 -> 2499 bytes .../lexers/__pycache__/praat.cpython-38.pyc | Bin 0 -> 7934 bytes .../lexers/__pycache__/prolog.cpython-38.pyc | Bin 0 -> 7343 bytes .../lexers/__pycache__/promql.cpython-38.pyc | Bin 0 -> 2698 bytes .../lexers/__pycache__/python.cpython-38.pyc | Bin 0 -> 30197 bytes .../lexers/__pycache__/qvt.cpython-38.pyc | Bin 0 -> 4135 bytes .../lexers/__pycache__/r.cpython-38.pyc | Bin 0 -> 4267 bytes .../lexers/__pycache__/rdf.cpython-38.pyc | Bin 0 -> 8152 bytes .../lexers/__pycache__/rebol.cpython-38.pyc | Bin 0 -> 11478 bytes .../__pycache__/resource.cpython-38.pyc | Bin 0 -> 2339 bytes .../lexers/__pycache__/ride.cpython-38.pyc | Bin 0 -> 3725 bytes .../lexers/__pycache__/rnc.cpython-38.pyc | Bin 0 -> 1513 bytes .../__pycache__/roboconf.cpython-38.pyc | Bin 0 -> 1906 bytes .../__pycache__/robotframework.cpython-38.pyc | Bin 0 -> 19127 bytes .../lexers/__pycache__/ruby.cpython-38.pyc | Bin 0 -> 13108 bytes .../lexers/__pycache__/rust.cpython-38.pyc | Bin 0 -> 4836 bytes .../lexers/__pycache__/sas.cpython-38.pyc | Bin 0 -> 5957 bytes .../lexers/__pycache__/scdoc.cpython-38.pyc | Bin 0 -> 1934 bytes .../__pycache__/scripting.cpython-38.pyc | Bin 0 -> 49776 bytes .../lexers/__pycache__/sgf.cpython-38.pyc | Bin 0 -> 1782 bytes .../lexers/__pycache__/shell.cpython-38.pyc | Bin 0 -> 23853 bytes .../lexers/__pycache__/sieve.cpython-38.pyc | Bin 0 -> 2178 bytes .../lexers/__pycache__/slash.cpython-38.pyc | Bin 0 -> 4551 bytes .../__pycache__/smalltalk.cpython-38.pyc | Bin 0 -> 4479 bytes .../lexers/__pycache__/smv.cpython-38.pyc | Bin 0 -> 2149 bytes .../lexers/__pycache__/snobol.cpython-38.pyc | Bin 0 -> 1995 bytes .../__pycache__/solidity.cpython-38.pyc | Bin 0 -> 2608 bytes .../lexers/__pycache__/special.cpython-38.pyc | Bin 0 -> 3227 bytes .../lexers/__pycache__/sql.cpython-38.pyc | Bin 0 -> 22640 bytes .../lexers/__pycache__/stata.cpython-38.pyc | Bin 0 -> 2971 bytes .../__pycache__/supercollider.cpython-38.pyc | Bin 0 -> 3055 bytes .../lexers/__pycache__/tcl.cpython-38.pyc | Bin 0 -> 3627 bytes .../__pycache__/templates.cpython-38.pyc | Bin 0 -> 59267 bytes .../__pycache__/teraterm.cpython-38.pyc | Bin 0 -> 4520 bytes .../lexers/__pycache__/testing.cpython-38.pyc | Bin 0 -> 7911 bytes .../lexers/__pycache__/text.cpython-38.pyc | Bin 0 -> 1416 bytes .../__pycache__/textedit.cpython-38.pyc | Bin 0 -> 5025 bytes .../__pycache__/textfmts.cpython-38.pyc | Bin 0 -> 10423 bytes .../lexers/__pycache__/theorem.cpython-38.pyc | Bin 0 -> 12630 bytes .../lexers/__pycache__/tnt.cpython-38.pyc | Bin 0 -> 6613 bytes .../__pycache__/trafficscript.cpython-38.pyc | Bin 0 -> 1571 bytes .../__pycache__/typoscript.cpython-38.pyc | Bin 0 -> 5347 bytes .../lexers/__pycache__/unicon.cpython-38.pyc | Bin 0 -> 10087 bytes .../lexers/__pycache__/urbi.cpython-38.pyc | Bin 0 -> 4237 bytes .../lexers/__pycache__/usd.cpython-38.pyc | Bin 0 -> 2818 bytes .../lexers/__pycache__/varnish.cpython-38.pyc | Bin 0 -> 5026 bytes .../__pycache__/verification.cpython-38.pyc | Bin 0 -> 2954 bytes .../lexers/__pycache__/web.cpython-38.pyc | Bin 0 -> 1226 bytes .../lexers/__pycache__/webidl.cpython-38.pyc | Bin 0 -> 4959 bytes .../lexers/__pycache__/webmisc.cpython-38.pyc | Bin 0 -> 24296 bytes .../lexers/__pycache__/whiley.cpython-38.pyc | Bin 0 -> 2507 bytes .../lexers/__pycache__/x10.cpython-38.pyc | Bin 0 -> 1848 bytes .../lexers/__pycache__/xorg.cpython-38.pyc | Bin 0 -> 1054 bytes .../lexers/__pycache__/yang.cpython-38.pyc | Bin 0 -> 3123 bytes .../lexers/__pycache__/zig.cpython-38.pyc | Bin 0 -> 2944 bytes .../pygments/lexers/_asy_builtins.py | 1645 +++++ .../pygments/lexers/_cl_builtins.py | 232 + .../pygments/lexers/_cocoa_builtins.py | 71 + .../pygments/lexers/_csound_builtins.py | 1725 +++++ .../pygments/lexers/_lasso_builtins.py | 5327 +++++++++++++++ .../pygments/lexers/_lua_builtins.py | 293 + .../site-packages/pygments/lexers/_mapping.py | 551 ++ .../pygments/lexers/_mql_builtins.py | 1172 ++++ .../pygments/lexers/_mysql_builtins.py | 1282 ++++ .../pygments/lexers/_openedge_builtins.py | 2547 ++++++++ .../pygments/lexers/_php_builtins.py | 4753 ++++++++++++++ .../pygments/lexers/_postgres_builtins.py | 678 ++ .../pygments/lexers/_scilab_builtins.py | 3094 +++++++++ .../pygments/lexers/_sourcemod_builtins.py | 1161 ++++ .../pygments/lexers/_stan_builtins.py | 558 ++ .../pygments/lexers/_stata_builtins.py | 421 ++ .../pygments/lexers/_tsql_builtins.py | 1004 +++ .../pygments/lexers/_usd_builtins.py | 113 + .../pygments/lexers/_vbscript_builtins.py | 280 + .../pygments/lexers/_vim_builtins.py | 1939 ++++++ .../pygments/lexers/actionscript.py | 245 + .../site-packages/pygments/lexers/agile.py | 24 + .../site-packages/pygments/lexers/algebra.py | 240 + .../site-packages/pygments/lexers/ambient.py | 76 + .../site-packages/pygments/lexers/ampl.py | 87 + .../site-packages/pygments/lexers/apl.py | 101 + .../pygments/lexers/archetype.py | 318 + .../site-packages/pygments/lexers/arrow.py | 117 + .../site-packages/pygments/lexers/asm.py | 1005 +++ .../pygments/lexers/automation.py | 374 ++ .../site-packages/pygments/lexers/bare.py | 104 + .../site-packages/pygments/lexers/basic.py | 662 ++ .../site-packages/pygments/lexers/bibtex.py | 160 + .../site-packages/pygments/lexers/boa.py | 102 + .../site-packages/pygments/lexers/business.py | 627 ++ .../site-packages/pygments/lexers/c_cpp.py | 344 + .../site-packages/pygments/lexers/c_like.py | 566 ++ .../pygments/lexers/capnproto.py | 78 + .../site-packages/pygments/lexers/chapel.py | 112 + .../site-packages/pygments/lexers/clean.py | 179 + .../site-packages/pygments/lexers/compiled.py | 34 + .../site-packages/pygments/lexers/configs.py | 984 +++ .../site-packages/pygments/lexers/console.py | 114 + .../site-packages/pygments/lexers/crystal.py | 392 ++ .../site-packages/pygments/lexers/csound.py | 467 ++ .../site-packages/pygments/lexers/css.py | 691 ++ .../site-packages/pygments/lexers/d.py | 256 + .../site-packages/pygments/lexers/dalvik.py | 125 + .../site-packages/pygments/lexers/data.py | 698 ++ .../pygments/lexers/devicetree.py | 109 + .../site-packages/pygments/lexers/diff.py | 165 + .../site-packages/pygments/lexers/dotnet.py | 707 ++ .../site-packages/pygments/lexers/dsls.py | 960 +++ .../site-packages/pygments/lexers/dylan.py | 287 + .../site-packages/pygments/lexers/ecl.py | 139 + .../site-packages/pygments/lexers/eiffel.py | 65 + .../site-packages/pygments/lexers/elm.py | 121 + .../site-packages/pygments/lexers/email.py | 151 + .../site-packages/pygments/lexers/erlang.py | 530 ++ .../site-packages/pygments/lexers/esoteric.py | 304 + .../site-packages/pygments/lexers/ezhil.py | 77 + .../site-packages/pygments/lexers/factor.py | 344 + .../site-packages/pygments/lexers/fantom.py | 250 + .../site-packages/pygments/lexers/felix.py | 273 + .../pygments/lexers/floscript.py | 83 + .../site-packages/pygments/lexers/forth.py | 178 + .../site-packages/pygments/lexers/fortran.py | 206 + .../site-packages/pygments/lexers/foxpro.py | 428 ++ .../site-packages/pygments/lexers/freefem.py | 898 +++ .../pygments/lexers/functional.py | 21 + .../site-packages/pygments/lexers/gdscript.py | 346 + .../site-packages/pygments/lexers/go.py | 101 + .../pygments/lexers/grammar_notation.py | 270 + .../site-packages/pygments/lexers/graph.py | 85 + .../site-packages/pygments/lexers/graphics.py | 800 +++ .../site-packages/pygments/lexers/haskell.py | 870 +++ .../site-packages/pygments/lexers/haxe.py | 936 +++ .../site-packages/pygments/lexers/hdl.py | 472 ++ .../site-packages/pygments/lexers/hexdump.py | 103 + .../site-packages/pygments/lexers/html.py | 614 ++ .../site-packages/pygments/lexers/idl.py | 281 + .../site-packages/pygments/lexers/igor.py | 420 ++ .../site-packages/pygments/lexers/inferno.py | 96 + .../pygments/lexers/installers.py | 322 + .../pygments/lexers/int_fiction.py | 1368 ++++ .../site-packages/pygments/lexers/iolang.py | 63 + .../site-packages/pygments/lexers/j.py | 146 + .../pygments/lexers/javascript.py | 1540 +++++ .../site-packages/pygments/lexers/julia.py | 331 + .../site-packages/pygments/lexers/jvm.py | 1673 +++++ .../site-packages/pygments/lexers/lisp.py | 2699 ++++++++ .../site-packages/pygments/lexers/make.py | 206 + .../site-packages/pygments/lexers/markup.py | 765 +++ .../site-packages/pygments/lexers/math.py | 21 + .../site-packages/pygments/lexers/matlab.py | 720 +++ .../site-packages/pygments/lexers/mime.py | 226 + .../site-packages/pygments/lexers/ml.py | 958 +++ .../site-packages/pygments/lexers/modeling.py | 366 ++ .../site-packages/pygments/lexers/modula2.py | 1580 +++++ .../site-packages/pygments/lexers/monte.py | 204 + .../site-packages/pygments/lexers/mosel.py | 448 ++ .../site-packages/pygments/lexers/ncl.py | 894 +++ .../site-packages/pygments/lexers/nimrod.py | 159 + .../site-packages/pygments/lexers/nit.py | 64 + .../site-packages/pygments/lexers/nix.py | 136 + .../site-packages/pygments/lexers/oberon.py | 121 + .../pygments/lexers/objective.py | 504 ++ .../site-packages/pygments/lexers/ooc.py | 85 + .../site-packages/pygments/lexers/other.py | 41 + .../site-packages/pygments/lexers/parasail.py | 79 + .../site-packages/pygments/lexers/parsers.py | 800 +++ .../site-packages/pygments/lexers/pascal.py | 644 ++ .../site-packages/pygments/lexers/pawn.py | 205 + .../site-packages/pygments/lexers/perl.py | 732 +++ .../site-packages/pygments/lexers/php.py | 321 + .../pygments/lexers/pointless.py | 71 + .../site-packages/pygments/lexers/pony.py | 94 + .../site-packages/pygments/lexers/praat.py | 302 + .../site-packages/pygments/lexers/prolog.py | 306 + .../site-packages/pygments/lexers/promql.py | 183 + .../site-packages/pygments/lexers/python.py | 1151 ++++ .../site-packages/pygments/lexers/qvt.py | 152 + .../site-packages/pygments/lexers/r.py | 191 + .../site-packages/pygments/lexers/rdf.py | 463 ++ .../site-packages/pygments/lexers/rebol.py | 431 ++ .../site-packages/pygments/lexers/resource.py | 85 + .../site-packages/pygments/lexers/ride.py | 139 + .../site-packages/pygments/lexers/rnc.py | 67 + .../site-packages/pygments/lexers/roboconf.py | 82 + .../pygments/lexers/robotframework.py | 552 ++ .../site-packages/pygments/lexers/ruby.py | 517 ++ .../site-packages/pygments/lexers/rust.py | 224 + .../site-packages/pygments/lexers/sas.py | 228 + .../site-packages/pygments/lexers/scdoc.py | 83 + .../pygments/lexers/scripting.py | 1284 ++++ .../site-packages/pygments/lexers/sgf.py | 61 + .../site-packages/pygments/lexers/shell.py | 914 +++ .../site-packages/pygments/lexers/sieve.py | 69 + .../site-packages/pygments/lexers/slash.py | 185 + .../pygments/lexers/smalltalk.py | 195 + .../site-packages/pygments/lexers/smv.py | 79 + .../site-packages/pygments/lexers/snobol.py | 83 + .../site-packages/pygments/lexers/solidity.py | 92 + .../site-packages/pygments/lexers/special.py | 105 + .../site-packages/pygments/lexers/sql.py | 837 +++ .../site-packages/pygments/lexers/stata.py | 171 + .../pygments/lexers/supercollider.py | 95 + .../site-packages/pygments/lexers/tcl.py | 145 + .../pygments/lexers/templates.py | 2264 +++++++ .../site-packages/pygments/lexers/teraterm.py | 335 + .../site-packages/pygments/lexers/testing.py | 207 + .../site-packages/pygments/lexers/text.py | 26 + .../site-packages/pygments/lexers/textedit.py | 169 + .../site-packages/pygments/lexers/textfmts.py | 430 ++ .../site-packages/pygments/lexers/theorem.py | 474 ++ .../site-packages/pygments/lexers/tnt.py | 263 + .../pygments/lexers/trafficscript.py | 54 + .../pygments/lexers/typoscript.py | 219 + .../site-packages/pygments/lexers/unicon.py | 412 ++ .../site-packages/pygments/lexers/urbi.py | 146 + .../site-packages/pygments/lexers/usd.py | 90 + .../site-packages/pygments/lexers/varnish.py | 190 + .../pygments/lexers/verification.py | 114 + .../site-packages/pygments/lexers/web.py | 24 + .../site-packages/pygments/lexers/webidl.py | 299 + .../site-packages/pygments/lexers/webmisc.py | 991 +++ .../site-packages/pygments/lexers/whiley.py | 116 + .../site-packages/pygments/lexers/x10.py | 69 + .../site-packages/pygments/lexers/xorg.py | 37 + .../site-packages/pygments/lexers/yang.py | 104 + .../site-packages/pygments/lexers/zig.py | 124 + .../site-packages/pygments/modeline.py | 44 + .../site-packages/pygments/plugin.py | 70 + .../site-packages/pygments/regexopt.py | 92 + .../site-packages/pygments/scanner.py | 105 + .../site-packages/pygments/sphinxext.py | 156 + .../python3.8/site-packages/pygments/style.py | 192 + .../site-packages/pygments/styles/__init__.py | 86 + .../__pycache__/__init__.cpython-38.pyc | Bin 0 -> 2591 bytes .../styles/__pycache__/abap.cpython-38.pyc | Bin 0 -> 915 bytes .../styles/__pycache__/algol.cpython-38.pyc | Bin 0 -> 2199 bytes .../__pycache__/algol_nu.cpython-38.pyc | Bin 0 -> 2211 bytes .../styles/__pycache__/arduino.cpython-38.pyc | Bin 0 -> 2160 bytes .../styles/__pycache__/autumn.cpython-38.pyc | Bin 0 -> 1746 bytes .../styles/__pycache__/borland.cpython-38.pyc | Bin 0 -> 1498 bytes .../styles/__pycache__/bw.cpython-38.pyc | Bin 0 -> 1193 bytes .../__pycache__/colorful.cpython-38.pyc | Bin 0 -> 2165 bytes .../styles/__pycache__/default.cpython-38.pyc | Bin 0 -> 1939 bytes .../styles/__pycache__/emacs.cpython-38.pyc | Bin 0 -> 1968 bytes .../__pycache__/friendly.cpython-38.pyc | Bin 0 -> 2027 bytes .../styles/__pycache__/fruity.cpython-38.pyc | Bin 0 -> 1371 bytes .../styles/__pycache__/igor.cpython-38.pyc | Bin 0 -> 943 bytes .../styles/__pycache__/inkpot.cpython-38.pyc | Bin 0 -> 1803 bytes .../__pycache__/lovelace.cpython-38.pyc | Bin 0 -> 2460 bytes .../styles/__pycache__/manni.cpython-38.pyc | Bin 0 -> 2173 bytes .../styles/__pycache__/monokai.cpython-38.pyc | Bin 0 -> 2330 bytes .../styles/__pycache__/murphy.cpython-38.pyc | Bin 0 -> 2132 bytes .../styles/__pycache__/native.cpython-38.pyc | Bin 0 -> 1804 bytes .../__pycache__/paraiso_dark.cpython-38.pyc | Bin 0 -> 2647 bytes .../__pycache__/paraiso_light.cpython-38.pyc | Bin 0 -> 2652 bytes .../styles/__pycache__/pastie.cpython-38.pyc | Bin 0 -> 2053 bytes .../styles/__pycache__/perldoc.cpython-38.pyc | Bin 0 -> 1867 bytes .../__pycache__/rainbow_dash.cpython-38.pyc | Bin 0 -> 2305 bytes .../styles/__pycache__/rrt.cpython-38.pyc | Bin 0 -> 1054 bytes .../styles/__pycache__/sas.cpython-38.pyc | Bin 0 -> 1508 bytes .../__pycache__/solarized.cpython-38.pyc | Bin 0 -> 2998 bytes .../__pycache__/stata_dark.cpython-38.pyc | Bin 0 -> 1366 bytes .../__pycache__/stata_light.cpython-38.pyc | Bin 0 -> 1392 bytes .../styles/__pycache__/tango.cpython-38.pyc | Bin 0 -> 3695 bytes .../styles/__pycache__/trac.cpython-38.pyc | Bin 0 -> 1689 bytes .../styles/__pycache__/vim.cpython-38.pyc | Bin 0 -> 1631 bytes .../styles/__pycache__/vs.cpython-38.pyc | Bin 0 -> 1094 bytes .../styles/__pycache__/xcode.cpython-38.pyc | Bin 0 -> 1260 bytes .../site-packages/pygments/styles/abap.py | 29 + .../site-packages/pygments/styles/algol.py | 63 + .../site-packages/pygments/styles/algol_nu.py | 63 + .../site-packages/pygments/styles/arduino.py | 98 + .../site-packages/pygments/styles/autumn.py | 65 + .../site-packages/pygments/styles/borland.py | 51 + .../site-packages/pygments/styles/bw.py | 49 + .../site-packages/pygments/styles/colorful.py | 81 + .../site-packages/pygments/styles/default.py | 73 + .../site-packages/pygments/styles/emacs.py | 72 + .../site-packages/pygments/styles/friendly.py | 72 + .../site-packages/pygments/styles/fruity.py | 42 + .../site-packages/pygments/styles/igor.py | 29 + .../site-packages/pygments/styles/inkpot.py | 67 + .../site-packages/pygments/styles/lovelace.py | 97 + .../site-packages/pygments/styles/manni.py | 75 + .../site-packages/pygments/styles/monokai.py | 107 + .../site-packages/pygments/styles/murphy.py | 80 + .../site-packages/pygments/styles/native.py | 65 + .../pygments/styles/paraiso_dark.py | 125 + .../pygments/styles/paraiso_light.py | 125 + .../site-packages/pygments/styles/pastie.py | 75 + .../site-packages/pygments/styles/perldoc.py | 69 + .../pygments/styles/rainbow_dash.py | 89 + .../site-packages/pygments/styles/rrt.py | 33 + .../site-packages/pygments/styles/sas.py | 44 + .../pygments/styles/solarized.py | 134 + .../pygments/styles/stata_dark.py | 41 + .../pygments/styles/stata_light.py | 39 + .../site-packages/pygments/styles/tango.py | 141 + .../site-packages/pygments/styles/trac.py | 63 + .../site-packages/pygments/styles/vim.py | 63 + .../site-packages/pygments/styles/vs.py | 38 + .../site-packages/pygments/styles/xcode.py | 51 + .../python3.8/site-packages/pygments/token.py | 213 + .../site-packages/pygments/unistring.py | 156 + .../python3.8/site-packages/pygments/util.py | 311 + .../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 0 -> 1066 bytes .../__pycache__/__main__.cpython-38.pyc | Bin 0 -> 280 bytes .../__pycache__/__pkginfo__.cpython-38.pyc | Bin 0 -> 2769 bytes .../__pycache__/constants.cpython-38.pyc | Bin 0 -> 1209 bytes .../pylint/__pycache__/epylint.cpython-38.pyc | Bin 0 -> 4969 bytes .../__pycache__/exceptions.cpython-38.pyc | Bin 0 -> 1285 bytes .../pylint/__pycache__/graph.cpython-38.pyc | Bin 0 -> 5046 bytes .../__pycache__/interfaces.cpython-38.pyc | Bin 0 -> 3695 bytes .../__pycache__/testutils.cpython-38.pyc | Bin 0 -> 20756 bytes .../site-packages/pylint/checkers/__init__.py | 67 + .../__pycache__/__init__.cpython-38.pyc | Bin 0 -> 1556 bytes .../checkers/__pycache__/async.cpython-38.pyc | Bin 0 -> 2683 bytes .../checkers/__pycache__/base.cpython-38.pyc | Bin 0 -> 63682 bytes .../__pycache__/base_checker.cpython-38.pyc | Bin 0 -> 6543 bytes .../__pycache__/classes.cpython-38.pyc | Bin 0 -> 50481 bytes .../design_analysis.cpython-38.pyc | Bin 0 -> 11284 bytes .../__pycache__/exceptions.cpython-38.pyc | Bin 0 -> 16243 bytes .../__pycache__/format.cpython-38.pyc | Bin 0 -> 15959 bytes .../__pycache__/imports.cpython-38.pyc | Bin 0 -> 25282 bytes .../__pycache__/logging.cpython-38.pyc | Bin 0 -> 11628 bytes .../checkers/__pycache__/misc.cpython-38.pyc | Bin 0 -> 5082 bytes .../__pycache__/newstyle.cpython-38.pyc | Bin 0 -> 2412 bytes .../__pycache__/python3.cpython-38.pyc | Bin 0 -> 34909 bytes .../__pycache__/raw_metrics.cpython-38.pyc | Bin 0 -> 3245 bytes .../__pycache__/refactoring.cpython-38.pyc | Bin 0 -> 45653 bytes .../__pycache__/similar.cpython-38.pyc | Bin 0 -> 12255 bytes .../__pycache__/spelling.cpython-38.pyc | Bin 0 -> 9668 bytes .../__pycache__/stdlib.cpython-38.pyc | Bin 0 -> 12411 bytes .../__pycache__/strings.cpython-38.pyc | Bin 0 -> 22060 bytes .../__pycache__/typecheck.cpython-38.pyc | Bin 0 -> 41842 bytes .../checkers/__pycache__/utils.cpython-38.pyc | Bin 0 -> 33062 bytes .../__pycache__/variables.cpython-38.pyc | Bin 0 -> 45258 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 0 -> 2591 bytes .../configuration_mixin.cpython-38.pyc | Bin 0 -> 1083 bytes .../find_default_config_files.cpython-38.pyc | Bin 0 -> 1758 bytes .../man_help_formatter.cpython-38.pyc | Bin 0 -> 4069 bytes .../config/__pycache__/option.cpython-38.pyc | Bin 0 -> 4595 bytes .../option_manager_mixin.cpython-38.pyc | Bin 0 -> 11043 bytes .../__pycache__/option_parser.cpython-38.pyc | Bin 0 -> 1784 bytes .../options_provider_mixin.cpython-38.pyc | Bin 0 -> 3735 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 0 -> 153 bytes .../_check_docs_utils.cpython-38.pyc | Bin 0 -> 19420 bytes .../__pycache__/bad_builtin.cpython-38.pyc | Bin 0 -> 1945 bytes .../broad_try_clause.cpython-38.pyc | Bin 0 -> 2232 bytes .../__pycache__/check_docs.cpython-38.pyc | Bin 0 -> 663 bytes .../__pycache__/check_elif.cpython-38.pyc | Bin 0 -> 2634 bytes .../__pycache__/comparetozero.cpython-38.pyc | Bin 0 -> 1921 bytes .../__pycache__/docparams.cpython-38.pyc | Bin 0 -> 14626 bytes .../__pycache__/docstyle.cpython-38.pyc | Bin 0 -> 2418 bytes .../__pycache__/emptystring.cpython-38.pyc | Bin 0 -> 1981 bytes .../__pycache__/mccabe.cpython-38.pyc | Bin 0 -> 5616 bytes .../overlapping_exceptions.cpython-38.pyc | Bin 0 -> 2555 bytes .../redefined_variable_type.cpython-38.pyc | Bin 0 -> 3210 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 0 -> 977 bytes .../__pycache__/check_parallel.cpython-38.pyc | Bin 0 -> 2561 bytes .../lint/__pycache__/pylinter.cpython-38.pyc | Bin 0 -> 31772 bytes .../report_functions.cpython-38.pyc | Bin 0 -> 2370 bytes .../lint/__pycache__/run.cpython-38.pyc | Bin 0 -> 11390 bytes .../lint/__pycache__/utils.cpython-38.pyc | Bin 0 -> 2123 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 0 -> 638 bytes .../__pycache__/message.cpython-38.pyc | Bin 0 -> 1218 bytes .../message_definition.cpython-38.pyc | Bin 0 -> 2988 bytes .../message_definition_store.cpython-38.pyc | Bin 0 -> 4087 bytes .../message_handler_mix_in.cpython-38.pyc | Bin 0 -> 11113 bytes .../message_id_store.cpython-38.pyc | Bin 0 -> 4961 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 0 -> 213 bytes .../__pycache__/diadefslib.cpython-38.pyc | Bin 0 -> 7615 bytes .../__pycache__/diagrams.cpython-38.pyc | Bin 0 -> 8723 bytes .../__pycache__/inspector.cpython-38.pyc | Bin 0 -> 10247 bytes .../pyreverse/__pycache__/main.cpython-38.pyc | Bin 0 -> 4567 bytes .../__pycache__/utils.cpython-38.pyc | Bin 0 -> 5665 bytes .../__pycache__/vcgutils.cpython-38.pyc | Bin 0 -> 4740 bytes .../__pycache__/writer.cpython-38.pyc | Bin 0 -> 7117 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 0 -> 799 bytes .../__pycache__/base_reporter.cpython-38.pyc | Bin 0 -> 2758 bytes .../collecting_reporter.cpython-38.pyc | Bin 0 -> 803 bytes .../__pycache__/json_reporter.cpython-38.pyc | Bin 0 -> 1950 bytes .../reports_handler_mix_in.cpython-38.pyc | Bin 0 -> 2972 bytes .../reporters/__pycache__/text.cpython-38.pyc | Bin 0 -> 7284 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 0 -> 3048 bytes .../ureports/__pycache__/nodes.cpython-38.pyc | Bin 0 -> 5949 bytes .../__pycache__/text_writer.cpython-38.pyc | Bin 0 -> 3644 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 0 -> 885 bytes .../__pycache__/ast_walker.cpython-38.pyc | Bin 0 -> 2048 bytes .../__pycache__/file_state.cpython-38.pyc | Bin 0 -> 3820 bytes .../__pycache__/pragma_parser.cpython-38.pyc | Bin 0 -> 3650 bytes .../utils/__pycache__/utils.cpython-38.pyc | Bin 0 -> 11777 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 ++ .../python_dateutil-2.8.1.dist-info/INSTALLER | 1 + .../python_dateutil-2.8.1.dist-info/LICENSE | 54 + .../python_dateutil-2.8.1.dist-info/METADATA | 200 + .../python_dateutil-2.8.1.dist-info/RECORD | 44 + .../python_dateutil-2.8.1.dist-info/WHEEL | 6 + .../top_level.txt | 1 + .../python_dateutil-2.8.1.dist-info/zip-safe | 1 + .../pyzmq-20.0.0.dist-info/AUTHORS.md | 110 + .../pyzmq-20.0.0.dist-info/COPYING.BSD | 32 + .../pyzmq-20.0.0.dist-info/COPYING.LESSER | 181 + .../pyzmq-20.0.0.dist-info/INSTALLER | 1 + .../pyzmq-20.0.0.dist-info/METADATA | 129 + .../pyzmq-20.0.0.dist-info/RECORD | 272 + .../pyzmq-20.0.0.dist-info/WHEEL | 5 + .../pyzmq-20.0.0.dist-info/top_level.txt | 1 + .../pyzmq.libs/libsodium-bcf9f097.so.23.3.0 | Bin 0 -> 1196672 bytes .../pyzmq.libs/libzmq-f3e05bef.so.5.2.3 | Bin 0 -> 975632 bytes .../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 0 -> 7768 bytes .../_deprecation_warning.cpython-38.pyc | Bin 0 -> 516 bytes .../__pycache__/_imp.cpython-38.pyc | Bin 0 -> 1890 bytes .../__pycache__/archive_util.cpython-38.pyc | Bin 0 -> 5128 bytes .../__pycache__/build_meta.cpython-38.pyc | Bin 0 -> 8495 bytes .../__pycache__/config.cpython-38.pyc | Bin 0 -> 17896 bytes .../__pycache__/dep_util.cpython-38.pyc | Bin 0 -> 819 bytes .../__pycache__/depends.cpython-38.pyc | Bin 0 -> 5216 bytes .../__pycache__/dist.cpython-38.pyc | Bin 0 -> 42326 bytes .../__pycache__/errors.cpython-38.pyc | Bin 0 -> 816 bytes .../__pycache__/extension.cpython-38.pyc | Bin 0 -> 1961 bytes .../__pycache__/glob.cpython-38.pyc | Bin 0 -> 3733 bytes .../__pycache__/installer.cpython-38.pyc | Bin 0 -> 4102 bytes .../__pycache__/launch.cpython-38.pyc | Bin 0 -> 824 bytes .../__pycache__/lib2to3_ex.cpython-38.pyc | Bin 0 -> 2411 bytes .../__pycache__/monkey.cpython-38.pyc | Bin 0 -> 4644 bytes .../__pycache__/msvc.cpython-38.pyc | Bin 0 -> 39631 bytes .../__pycache__/namespaces.cpython-38.pyc | Bin 0 -> 3616 bytes .../__pycache__/package_index.cpython-38.pyc | Bin 0 -> 32970 bytes .../__pycache__/py27compat.cpython-38.pyc | Bin 0 -> 1749 bytes .../__pycache__/py31compat.cpython-38.pyc | Bin 0 -> 1191 bytes .../__pycache__/py33compat.cpython-38.pyc | Bin 0 -> 1408 bytes .../__pycache__/py34compat.cpython-38.pyc | Bin 0 -> 450 bytes .../__pycache__/sandbox.cpython-38.pyc | Bin 0 -> 15536 bytes .../__pycache__/site-patch.cpython-38.pyc | Bin 0 -> 1474 bytes .../__pycache__/ssl_support.cpython-38.pyc | Bin 0 -> 6855 bytes .../__pycache__/unicode_utils.cpython-38.pyc | Bin 0 -> 1151 bytes .../__pycache__/version.cpython-38.pyc | Bin 0 -> 292 bytes .../__pycache__/wheel.cpython-38.pyc | Bin 0 -> 7383 bytes .../windows_support.cpython-38.pyc | Bin 0 -> 989 bytes .../setuptools/_deprecation_warning.py | 7 + .../site-packages/setuptools/_imp.py | 73 + .../setuptools/_vendor/__init__.py | 0 .../__pycache__/__init__.cpython-38.pyc | Bin 0 -> 154 bytes .../__pycache__/ordered_set.cpython-38.pyc | Bin 0 -> 16412 bytes .../__pycache__/pyparsing.cpython-38.pyc | Bin 0 -> 201631 bytes .../_vendor/__pycache__/six.cpython-38.pyc | Bin 0 -> 24427 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 0 -> 704 bytes .../__pycache__/__init__.cpython-38.pyc | Bin 0 -> 542 bytes .../__pycache__/_compat.cpython-38.pyc | Bin 0 -> 978 bytes .../__pycache__/_structures.cpython-38.pyc | Bin 0 -> 2760 bytes .../__pycache__/markers.cpython-38.pyc | Bin 0 -> 8927 bytes .../__pycache__/requirements.cpython-38.pyc | Bin 0 -> 3995 bytes .../__pycache__/specifiers.cpython-38.pyc | Bin 0 -> 19734 bytes .../packaging/__pycache__/tags.cpython-38.pyc | Bin 0 -> 10811 bytes .../__pycache__/utils.cpython-38.pyc | Bin 0 -> 1435 bytes .../__pycache__/version.cpython-38.pyc | Bin 0 -> 12065 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 + .../site-packages/setuptools/cli-32.exe | Bin 0 -> 65536 bytes .../site-packages/setuptools/cli-64.exe | Bin 0 -> 74752 bytes .../site-packages/setuptools/cli.exe | Bin 0 -> 65536 bytes .../setuptools/command/__init__.py | 17 + .../__pycache__/__init__.cpython-38.pyc | Bin 0 -> 712 bytes .../command/__pycache__/alias.cpython-38.pyc | Bin 0 -> 2392 bytes .../__pycache__/bdist_egg.cpython-38.pyc | Bin 0 -> 14182 bytes .../__pycache__/bdist_rpm.cpython-38.pyc | Bin 0 -> 1784 bytes .../__pycache__/bdist_wininst.cpython-38.pyc | Bin 0 -> 954 bytes .../__pycache__/build_clib.cpython-38.pyc | Bin 0 -> 2437 bytes .../__pycache__/build_ext.cpython-38.pyc | Bin 0 -> 9895 bytes .../__pycache__/build_py.cpython-38.pyc | Bin 0 -> 8641 bytes .../__pycache__/develop.cpython-38.pyc | Bin 0 -> 6501 bytes .../__pycache__/dist_info.cpython-38.pyc | Bin 0 -> 1361 bytes .../__pycache__/easy_install.cpython-38.pyc | Bin 0 -> 66694 bytes .../__pycache__/egg_info.cpython-38.pyc | Bin 0 -> 21773 bytes .../__pycache__/install.cpython-38.pyc | Bin 0 -> 4016 bytes .../install_egg_info.cpython-38.pyc | Bin 0 -> 2900 bytes .../__pycache__/install_lib.cpython-38.pyc | Bin 0 -> 5083 bytes .../install_scripts.cpython-38.pyc | Bin 0 -> 2273 bytes .../__pycache__/py36compat.cpython-38.pyc | Bin 0 -> 4610 bytes .../__pycache__/register.cpython-38.pyc | Bin 0 -> 811 bytes .../command/__pycache__/rotate.cpython-38.pyc | Bin 0 -> 2520 bytes .../__pycache__/saveopts.cpython-38.pyc | Bin 0 -> 889 bytes .../command/__pycache__/sdist.cpython-38.pyc | Bin 0 -> 7859 bytes .../command/__pycache__/setopt.cpython-38.pyc | Bin 0 -> 4537 bytes .../command/__pycache__/test.cpython-38.pyc | Bin 0 -> 8475 bytes .../command/__pycache__/upload.cpython-38.pyc | Bin 0 -> 784 bytes .../__pycache__/upload_docs.cpython-38.pyc | Bin 0 -> 6140 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 0 -> 2420 bytes .../site-packages/setuptools/glob.py | 174 + .../site-packages/setuptools/gui-32.exe | Bin 0 -> 65536 bytes .../site-packages/setuptools/gui-64.exe | Bin 0 -> 75264 bytes .../site-packages/setuptools/gui.exe | Bin 0 -> 65536 bytes .../site-packages/setuptools/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 + .venv/lib/python3.8/site-packages/six.py | 982 +++ .../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 0 -> 672 bytes .../toml/__pycache__/decoder.cpython-38.pyc | Bin 0 -> 23235 bytes .../toml/__pycache__/encoder.cpython-38.pyc | Bin 0 -> 9373 bytes .../toml/__pycache__/ordered.cpython-38.pyc | Bin 0 -> 911 bytes .../toml/__pycache__/tz.cpython-38.pyc | Bin 0 -> 1225 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 + .venv/lib/python3.8/site-packages/toml/tz.py | 24 + .../tornado-6.1.dist-info/INSTALLER | 1 + .../tornado-6.1.dist-info/LICENSE | 202 + .../tornado-6.1.dist-info/METADATA | 70 + .../tornado-6.1.dist-info/RECORD | 165 + .../site-packages/tornado-6.1.dist-info/WHEEL | 5 + .../tornado-6.1.dist-info/top_level.txt | 1 + .../site-packages/tornado/__init__.py | 26 + .../__pycache__/__init__.cpython-38.pyc | Bin 0 -> 250 bytes .../__pycache__/_locale_data.cpython-38.pyc | Bin 0 -> 2866 bytes .../tornado/__pycache__/auth.cpython-38.pyc | Bin 0 -> 38748 bytes .../__pycache__/autoreload.cpython-38.pyc | Bin 0 -> 7653 bytes .../__pycache__/concurrent.cpython-38.pyc | Bin 0 -> 7945 bytes .../curl_httpclient.cpython-38.pyc | Bin 0 -> 13771 bytes .../tornado/__pycache__/escape.cpython-38.pyc | Bin 0 -> 10691 bytes .../tornado/__pycache__/gen.cpython-38.pyc | Bin 0 -> 26121 bytes .../http1connection.cpython-38.pyc | Bin 0 -> 21865 bytes .../__pycache__/httpclient.cpython-38.pyc | Bin 0 -> 28365 bytes .../__pycache__/httpserver.cpython-38.pyc | Bin 0 -> 13570 bytes .../__pycache__/httputil.cpython-38.pyc | Bin 0 -> 32053 bytes .../tornado/__pycache__/ioloop.cpython-38.pyc | Bin 0 -> 31286 bytes .../__pycache__/iostream.cpython-38.pyc | Bin 0 -> 45810 bytes .../tornado/__pycache__/locale.cpython-38.pyc | Bin 0 -> 16186 bytes .../tornado/__pycache__/locks.cpython-38.pyc | Bin 0 -> 18465 bytes .../tornado/__pycache__/log.cpython-38.pyc | Bin 0 -> 8407 bytes .../__pycache__/netutil.cpython-38.pyc | Bin 0 -> 17501 bytes .../__pycache__/options.cpython-38.pyc | Bin 0 -> 23367 bytes .../__pycache__/process.cpython-38.pyc | Bin 0 -> 10340 bytes .../tornado/__pycache__/queues.cpython-38.pyc | Bin 0 -> 13252 bytes .../__pycache__/routing.cpython-38.pyc | Bin 0 -> 24277 bytes .../simple_httpclient.cpython-38.pyc | Bin 0 -> 18865 bytes .../__pycache__/tcpclient.cpython-38.pyc | Bin 0 -> 9113 bytes .../__pycache__/tcpserver.cpython-38.pyc | Bin 0 -> 10970 bytes .../__pycache__/template.cpython-38.pyc | Bin 0 -> 34090 bytes .../__pycache__/testing.cpython-38.pyc | Bin 0 -> 26899 bytes .../tornado/__pycache__/util.cpython-38.pyc | Bin 0 -> 14526 bytes .../tornado/__pycache__/web.cpython-38.pyc | Bin 0 -> 113526 bytes .../__pycache__/websocket.cpython-38.pyc | Bin 0 -> 51457 bytes .../tornado/__pycache__/wsgi.cpython-38.pyc | Bin 0 -> 6432 bytes .../site-packages/tornado/_locale_data.py | 80 + .../python3.8/site-packages/tornado/auth.py | 1187 ++++ .../site-packages/tornado/autoreload.py | 363 ++ .../site-packages/tornado/concurrent.py | 263 + .../site-packages/tornado/curl_httpclient.py | 583 ++ .../python3.8/site-packages/tornado/escape.py | 402 ++ .../python3.8/site-packages/tornado/gen.py | 872 +++ .../site-packages/tornado/http1connection.py | 842 +++ .../site-packages/tornado/httpclient.py | 790 +++ .../site-packages/tornado/httpserver.py | 398 ++ .../site-packages/tornado/httputil.py | 1133 ++++ .../python3.8/site-packages/tornado/ioloop.py | 944 +++ .../site-packages/tornado/iostream.py | 1660 +++++ .../python3.8/site-packages/tornado/locale.py | 581 ++ .../python3.8/site-packages/tornado/locks.py | 571 ++ .../python3.8/site-packages/tornado/log.py | 339 + .../site-packages/tornado/netutil.py | 617 ++ .../site-packages/tornado/options.py | 735 +++ .../tornado/platform/__init__.py | 0 .../__pycache__/__init__.cpython-38.pyc | Bin 0 -> 152 bytes .../__pycache__/asyncio.cpython-38.pyc | Bin 0 -> 17264 bytes .../__pycache__/caresresolver.cpython-38.pyc | Bin 0 -> 3267 bytes .../__pycache__/twisted.cpython-38.pyc | Bin 0 -> 4429 bytes .../site-packages/tornado/platform/asyncio.py | 611 ++ .../tornado/platform/caresresolver.py | 89 + .../site-packages/tornado/platform/twisted.py | 146 + .../site-packages/tornado/process.py | 373 ++ .../python3.8/site-packages/tornado/py.typed | 0 .../python3.8/site-packages/tornado/queues.py | 414 ++ .../site-packages/tornado/routing.py | 717 ++ .../tornado/simple_httpclient.py | 699 ++ .../speedups.cpython-38-x86_64-linux-gnu.so | Bin 0 -> 29256 bytes .../site-packages/tornado/tcpclient.py | 328 + .../site-packages/tornado/tcpserver.py | 334 + .../site-packages/tornado/template.py | 1048 +++ .../site-packages/tornado/test/__main__.py | 12 + .../test/__pycache__/__main__.cpython-38.pyc | Bin 0 -> 314 bytes .../__pycache__/asyncio_test.cpython-38.pyc | Bin 0 -> 6775 bytes .../test/__pycache__/auth_test.cpython-38.pyc | Bin 0 -> 21373 bytes .../autoreload_test.cpython-38.pyc | Bin 0 -> 3167 bytes .../concurrent_test.cpython-38.pyc | Bin 0 -> 8412 bytes .../curl_httpclient_test.cpython-38.pyc | Bin 0 -> 4841 bytes .../__pycache__/escape_test.cpython-38.pyc | Bin 0 -> 9552 bytes .../test/__pycache__/gen_test.cpython-38.pyc | Bin 0 -> 37623 bytes .../http1connection_test.cpython-38.pyc | Bin 0 -> 2877 bytes .../httpclient_test.cpython-38.pyc | Bin 0 -> 29885 bytes .../httpserver_test.cpython-38.pyc | Bin 0 -> 55718 bytes .../__pycache__/httputil_test.cpython-38.pyc | Bin 0 -> 17163 bytes .../__pycache__/import_test.cpython-38.pyc | Bin 0 -> 2016 bytes .../__pycache__/ioloop_test.cpython-38.pyc | Bin 0 -> 27601 bytes .../__pycache__/iostream_test.cpython-38.pyc | Bin 0 -> 42253 bytes .../__pycache__/locale_test.cpython-38.pyc | Bin 0 -> 5320 bytes .../__pycache__/locks_test.cpython-38.pyc | Bin 0 -> 17249 bytes .../test/__pycache__/log_test.cpython-38.pyc | Bin 0 -> 8223 bytes .../__pycache__/netutil_test.cpython-38.pyc | Bin 0 -> 8592 bytes .../__pycache__/options_test.cpython-38.pyc | Bin 0 -> 10685 bytes .../__pycache__/process_test.cpython-38.pyc | Bin 0 -> 8061 bytes .../__pycache__/queues_test.cpython-38.pyc | Bin 0 -> 14281 bytes .../resolve_test_helper.cpython-38.pyc | Bin 0 -> 438 bytes .../__pycache__/routing_test.cpython-38.pyc | Bin 0 -> 10439 bytes .../test/__pycache__/runtests.cpython-38.pyc | Bin 0 -> 6897 bytes .../simple_httpclient_test.cpython-38.pyc | Bin 0 -> 37865 bytes .../__pycache__/tcpclient_test.cpython-38.pyc | Bin 0 -> 16428 bytes .../__pycache__/tcpserver_test.cpython-38.pyc | Bin 0 -> 6766 bytes .../__pycache__/template_test.cpython-38.pyc | Bin 0 -> 18117 bytes .../__pycache__/testing_test.cpython-38.pyc | Bin 0 -> 14984 bytes .../__pycache__/twisted_test.cpython-38.pyc | Bin 0 -> 8801 bytes .../test/__pycache__/util.cpython-38.pyc | Bin 0 -> 2878 bytes .../test/__pycache__/util_test.cpython-38.pyc | Bin 0 -> 11289 bytes .../test/__pycache__/web_test.cpython-38.pyc | Bin 0 -> 125352 bytes .../__pycache__/websocket_test.cpython-38.pyc | Bin 0 -> 33723 bytes .../test/__pycache__/wsgi_test.cpython-38.pyc | Bin 0 -> 1080 bytes .../tornado/test/asyncio_test.py | 190 + .../site-packages/tornado/test/auth_test.py | 609 ++ .../tornado/test/autoreload_test.py | 127 + .../tornado/test/concurrent_test.py | 212 + .../tornado/test/csv_translations/fr_FR.csv | 1 + .../tornado/test/curl_httpclient_test.py | 129 + .../site-packages/tornado/test/escape_test.py | 322 + .../site-packages/tornado/test/gen_test.py | 1119 ++++ .../fr_FR/LC_MESSAGES/tornado_test.mo | Bin 0 -> 665 bytes .../fr_FR/LC_MESSAGES/tornado_test.po | 47 + .../tornado/test/http1connection_test.py | 61 + .../tornado/test/httpclient_test.py | 898 +++ .../tornado/test/httpserver_test.py | 1339 ++++ .../tornado/test/httputil_test.py | 521 ++ .../site-packages/tornado/test/import_test.py | 66 + .../site-packages/tornado/test/ioloop_test.py | 725 +++ .../tornado/test/iostream_test.py | 1282 ++++ .../site-packages/tornado/test/locale_test.py | 151 + .../site-packages/tornado/test/locks_test.py | 535 ++ .../site-packages/tornado/test/log_test.py | 245 + .../tornado/test/netutil_test.py | 233 + .../tornado/test/options_test.cfg | 7 + .../tornado/test/options_test.py | 328 + .../tornado/test/options_test_types.cfg | 11 + .../tornado/test/options_test_types_str.cfg | 8 + .../tornado/test/process_test.py | 274 + .../site-packages/tornado/test/queues_test.py | 431 ++ .../tornado/test/resolve_test_helper.py | 10 + .../tornado/test/routing_test.py | 276 + .../site-packages/tornado/test/runtests.py | 241 + .../tornado/test/simple_httpclient_test.py | 834 +++ .../tornado/test/static/dir/index.html | 1 + .../tornado/test/static/robots.txt | 2 + .../tornado/test/static/sample.xml | 23 + .../tornado/test/static/sample.xml.bz2 | Bin 0 -> 285 bytes .../tornado/test/static/sample.xml.gz | Bin 0 -> 264 bytes .../site-packages/tornado/test/static_foo.txt | 2 + .../tornado/test/tcpclient_test.py | 438 ++ .../tornado/test/tcpserver_test.py | 192 + .../tornado/test/template_test.py | 536 ++ .../tornado/test/templates/utf8.html | 1 + .../site-packages/tornado/test/test.crt | 20 + .../site-packages/tornado/test/test.key | 28 + .../tornado/test/testing_test.py | 353 + .../tornado/test/twisted_test.py | 247 + .../site-packages/tornado/test/util.py | 114 + .../site-packages/tornado/test/util_test.py | 308 + .../site-packages/tornado/test/web_test.py | 3156 +++++++++ .../tornado/test/websocket_test.py | 840 +++ .../site-packages/tornado/test/wsgi_test.py | 20 + .../site-packages/tornado/testing.py | 818 +++ .../python3.8/site-packages/tornado/util.py | 474 ++ .../python3.8/site-packages/tornado/web.py | 3588 ++++++++++ .../site-packages/tornado/websocket.py | 1666 +++++ .../python3.8/site-packages/tornado/wsgi.py | 199 + .../traitlets-5.0.5.dist-info/COPYING.md | 62 + .../traitlets-5.0.5.dist-info/INSTALLER | 1 + .../traitlets-5.0.5.dist-info/METADATA | 192 + .../traitlets-5.0.5.dist-info/RECORD | 66 + .../traitlets-5.0.5.dist-info/WHEEL | 5 + .../traitlets-5.0.5.dist-info/top_level.txt | 1 + .../site-packages/traitlets/__init__.py | 21 + .../__pycache__/__init__.cpython-38.pyc | Bin 0 -> 1034 bytes .../__pycache__/_version.cpython-38.pyc | Bin 0 -> 361 bytes .../traitlets/__pycache__/log.cpython-38.pyc | Bin 0 -> 658 bytes .../__pycache__/traitlets.cpython-38.pyc | Bin 0 -> 102088 bytes .../site-packages/traitlets/_version.py | 14 + .../traitlets/config/__init__.py | 8 + .../__pycache__/__init__.cpython-38.pyc | Bin 0 -> 241 bytes .../__pycache__/application.cpython-38.pyc | Bin 0 -> 26032 bytes .../__pycache__/configurable.cpython-38.pyc | Bin 0 -> 15549 bytes .../config/__pycache__/loader.cpython-38.pyc | Bin 0 -> 32630 bytes .../config/__pycache__/manager.cpython-38.pyc | Bin 0 -> 2632 bytes .../__pycache__/sphinxdoc.cpython-38.pyc | Bin 0 -> 4524 bytes .../traitlets/config/application.py | 897 +++ .../traitlets/config/configurable.py | 557 ++ .../site-packages/traitlets/config/loader.py | 1086 ++++ .../site-packages/traitlets/config/manager.py | 84 + .../traitlets/config/sphinxdoc.py | 158 + .../traitlets/config/tests/__init__.py | 0 .../tests/__pycache__/__init__.cpython-38.pyc | Bin 0 -> 158 bytes .../test_application.cpython-38.pyc | Bin 0 -> 24025 bytes .../test_configurable.cpython-38.pyc | Bin 0 -> 22311 bytes .../__pycache__/test_loader.cpython-38.pyc | Bin 0 -> 23795 bytes .../config/tests/test_application.py | 764 +++ .../config/tests/test_configurable.py | 680 ++ .../traitlets/config/tests/test_loader.py | 747 +++ .../python3.8/site-packages/traitlets/log.py | 27 + .../site-packages/traitlets/tests/__init__.py | 0 .../tests/__pycache__/__init__.cpython-38.pyc | Bin 0 -> 151 bytes .../__pycache__/_warnings.cpython-38.pyc | Bin 0 -> 3446 bytes .../__pycache__/test_traitlets.cpython-38.pyc | Bin 0 -> 109170 bytes .../test_traitlets_enum.cpython-38.pyc | Bin 0 -> 13588 bytes .../tests/__pycache__/utils.cpython-38.pyc | Bin 0 -> 1291 bytes .../traitlets/tests/_warnings.py | 110 + .../traitlets/tests/test_traitlets.py | 2933 +++++++++ .../traitlets/tests/test_traitlets_enum.py | 380 ++ .../site-packages/traitlets/tests/utils.py | 39 + .../site-packages/traitlets/traitlets.py | 3244 ++++++++++ .../site-packages/traitlets/utils/__init__.py | 6 + .../utils/__pycache__/__init__.cpython-38.pyc | Bin 0 -> 338 bytes .../utils/__pycache__/bunch.cpython-38.pyc | Bin 0 -> 968 bytes .../__pycache__/decorators.cpython-38.pyc | Bin 0 -> 1995 bytes .../__pycache__/descriptions.cpython-38.pyc | Bin 0 -> 4525 bytes .../__pycache__/getargspec.cpython-38.pyc | Bin 0 -> 1367 bytes .../__pycache__/importstring.cpython-38.pyc | Bin 0 -> 1108 bytes .../utils/__pycache__/sentinel.cpython-38.pyc | Bin 0 -> 966 bytes .../site-packages/traitlets/utils/bunch.py | 25 + .../traitlets/utils/decorators.py | 80 + .../traitlets/utils/descriptions.py | 169 + .../traitlets/utils/getargspec.py | 50 + .../traitlets/utils/importstring.py | 38 + .../site-packages/traitlets/utils/sentinel.py | 22 + .../traitlets/utils/tests/__init__.py | 0 .../tests/__pycache__/__init__.cpython-38.pyc | Bin 0 -> 157 bytes .../__pycache__/test_bunch.cpython-38.pyc | Bin 0 -> 639 bytes .../test_decorators.cpython-38.pyc | Bin 0 -> 5018 bytes .../test_importstring.cpython-38.pyc | Bin 0 -> 1212 bytes .../traitlets/utils/tests/test_bunch.py | 14 + .../traitlets/utils/tests/test_decorators.py | 139 + .../utils/tests/test_importstring.py | 29 + .../wcwidth-0.2.5.dist-info/INSTALLER | 1 + .../wcwidth-0.2.5.dist-info/LICENSE | 27 + .../wcwidth-0.2.5.dist-info/METADATA | 309 + .../wcwidth-0.2.5.dist-info/RECORD | 22 + .../wcwidth-0.2.5.dist-info/WHEEL | 6 + .../wcwidth-0.2.5.dist-info/top_level.txt | 1 + .../wcwidth-0.2.5.dist-info/zip-safe | 1 + .../site-packages/wcwidth/__init__.py | 37 + .../__pycache__/__init__.cpython-38.pyc | Bin 0 -> 475 bytes .../__pycache__/table_wide.cpython-38.pyc | Bin 0 -> 6137 bytes .../__pycache__/table_zero.cpython-38.pyc | Bin 0 -> 19632 bytes .../unicode_versions.cpython-38.pyc | Bin 0 -> 849 bytes .../__pycache__/wcwidth.cpython-38.pyc | Bin 0 -> 10835 bytes .../site-packages/wcwidth/table_wide.py | 1102 ++++ .../site-packages/wcwidth/table_zero.py | 3910 +++++++++++ .../site-packages/wcwidth/tests/__init__.py | 1 + .../tests/__pycache__/__init__.cpython-38.pyc | Bin 0 -> 196 bytes .../__pycache__/test_core.cpython-38.pyc | Bin 0 -> 3087 bytes .../site-packages/wcwidth/tests/test_core.py | 138 + .../site-packages/wcwidth/unicode_versions.py | 35 + .../site-packages/wcwidth/version.json | 1 + .../site-packages/wcwidth/wcwidth.py | 375 ++ .../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 0 -> 953 bytes .../__pycache__/decorators.cpython-38.pyc | Bin 0 -> 9225 bytes .../wrapt/__pycache__/importer.cpython-38.pyc | Bin 0 -> 4233 bytes .../wrapt/__pycache__/wrappers.cpython-38.pyc | Bin 0 -> 24358 bytes .../_wrappers.cpython-38-x86_64-linux-gnu.so | Bin 0 -> 198056 bytes .../site-packages/wrapt/decorators.py | 516 ++ .../python3.8/site-packages/wrapt/importer.py | 230 + .../python3.8/site-packages/wrapt/wrappers.py | 947 +++ .../python3.8/site-packages/zmq/__init__.pxd | 4 + .../python3.8/site-packages/zmq/__init__.py | 78 + .../zmq/__pycache__/__init__.cpython-38.pyc | Bin 0 -> 2133 bytes .../zmq/__pycache__/_future.cpython-38.pyc | Bin 0 -> 13768 bytes .../zmq/__pycache__/asyncio.cpython-38.pyc | Bin 0 -> 3919 bytes .../zmq/__pycache__/decorators.cpython-38.pyc | Bin 0 -> 5559 bytes .../zmq/__pycache__/error.cpython-38.pyc | Bin 0 -> 6112 bytes .../python3.8/site-packages/zmq/_future.py | 545 ++ .../python3.8/site-packages/zmq/asyncio.py | 119 + .../site-packages/zmq/auth/__init__.py | 11 + .../auth/__pycache__/__init__.cpython-38.pyc | Bin 0 -> 481 bytes .../auth/__pycache__/asyncio.cpython-38.pyc | Bin 0 -> 1783 bytes .../zmq/auth/__pycache__/base.cpython-38.pyc | Bin 0 -> 11193 bytes .../zmq/auth/__pycache__/certs.cpython-38.pyc | Bin 0 -> 3354 bytes .../auth/__pycache__/ioloop.cpython-38.pyc | Bin 0 -> 1424 bytes .../auth/__pycache__/thread.cpython-38.pyc | Bin 0 -> 7370 bytes .../site-packages/zmq/auth/asyncio.py | 49 + .../python3.8/site-packages/zmq/auth/base.py | 379 ++ .../python3.8/site-packages/zmq/auth/certs.py | 126 + .../site-packages/zmq/auth/ioloop.py | 35 + .../site-packages/zmq/auth/thread.py | 225 + .../site-packages/zmq/backend/__init__.py | 44 + .../__pycache__/__init__.cpython-38.pyc | Bin 0 -> 882 bytes .../backend/__pycache__/select.cpython-38.pyc | Bin 0 -> 965 bytes .../zmq/backend/cffi/__init__.py | 22 + .../cffi/__pycache__/__init__.cpython-38.pyc | Bin 0 -> 592 bytes .../cffi/__pycache__/_cffi.cpython-38.pyc | Bin 0 -> 3918 bytes .../cffi/__pycache__/_poll.cpython-38.pyc | Bin 0 -> 2012 bytes .../cffi/__pycache__/constants.cpython-38.pyc | Bin 0 -> 493 bytes .../cffi/__pycache__/context.cpython-38.pyc | Bin 0 -> 2100 bytes .../cffi/__pycache__/devices.cpython-38.pyc | Bin 0 -> 1511 bytes .../cffi/__pycache__/error.cpython-38.pyc | Bin 0 -> 477 bytes .../cffi/__pycache__/message.cpython-38.pyc | Bin 0 -> 1849 bytes .../cffi/__pycache__/socket.cpython-38.pyc | Bin 0 -> 7631 bytes .../cffi/__pycache__/utils.cpython-38.pyc | Bin 0 -> 2319 bytes .../site-packages/zmq/backend/cffi/_cdefs.h | 70 + .../site-packages/zmq/backend/cffi/_cffi.py | 127 + .../site-packages/zmq/backend/cffi/_poll.py | 80 + .../site-packages/zmq/backend/cffi/_verify.c | 7 + .../zmq/backend/cffi/constants.py | 16 + .../site-packages/zmq/backend/cffi/context.py | 77 + .../site-packages/zmq/backend/cffi/devices.py | 68 + .../site-packages/zmq/backend/cffi/error.py | 17 + .../site-packages/zmq/backend/cffi/message.py | 64 + .../site-packages/zmq/backend/cffi/socket.py | 279 + .../site-packages/zmq/backend/cffi/utils.py | 81 + .../zmq/backend/cython/__init__.pxd | 3 + .../zmq/backend/cython/__init__.py | 26 + .../__pycache__/__init__.cpython-38.pyc | Bin 0 -> 603 bytes .../_device.cpython-38-x86_64-linux-gnu.so | Bin 0 -> 59896 bytes .../_poll.cpython-38-x86_64-linux-gnu.so | Bin 0 -> 76576 bytes ...y_steerable.cpython-38-x86_64-linux-gnu.so | Bin 0 -> 55744 bytes .../_version.cpython-38-x86_64-linux-gnu.so | Bin 0 -> 34744 bytes .../zmq/backend/cython/checkrc.pxd | 29 + .../zmq/backend/cython/constant_enums.pxi | 222 + .../constants.cpython-38-x86_64-linux-gnu.so | Bin 0 -> 79600 bytes .../zmq/backend/cython/constants.pxi | 453 ++ .../context.cpython-38-x86_64-linux-gnu.so | Bin 0 -> 76552 bytes .../zmq/backend/cython/context.pxd | 35 + .../error.cpython-38-x86_64-linux-gnu.so | Bin 0 -> 38944 bytes .../zmq/backend/cython/libzmq.pxd | 117 + .../message.cpython-38-x86_64-linux-gnu.so | Bin 0 -> 106216 bytes .../zmq/backend/cython/message.pxd | 63 + .../socket.cpython-38-x86_64-linux-gnu.so | Bin 0 -> 154968 bytes .../zmq/backend/cython/socket.pxd | 49 + .../utils.cpython-38-x86_64-linux-gnu.so | Bin 0 -> 55616 bytes .../site-packages/zmq/backend/select.py | 40 + .../python3.8/site-packages/zmq/decorators.py | 188 + .../site-packages/zmq/devices/__init__.py | 29 + .../__pycache__/__init__.cpython-38.pyc | Bin 0 -> 703 bytes .../__pycache__/basedevice.cpython-38.pyc | Bin 0 -> 8400 bytes .../__pycache__/monitoredqueue.cpython-38.pyc | Bin 0 -> 988 bytes .../monitoredqueuedevice.cpython-38.pyc | Bin 0 -> 2378 bytes .../__pycache__/proxydevice.cpython-38.pyc | Bin 0 -> 3501 bytes .../proxysteerabledevice.cpython-38.pyc | Bin 0 -> 3992 bytes .../site-packages/zmq/devices/basedevice.py | 281 + ...itoredqueue.cpython-38-x86_64-linux-gnu.so | Bin 0 -> 72392 bytes .../zmq/devices/monitoredqueue.pxd | 177 + .../zmq/devices/monitoredqueue.py | 37 + .../zmq/devices/monitoredqueuedevice.py | 66 + .../site-packages/zmq/devices/proxydevice.py | 104 + .../zmq/devices/proxysteerabledevice.py | 112 + .../lib/python3.8/site-packages/zmq/error.py | 198 + .../site-packages/zmq/eventloop/__init__.py | 5 + .../__pycache__/__init__.cpython-38.pyc | Bin 0 -> 278 bytes .../__pycache__/_deprecated.cpython-38.pyc | Bin 0 -> 7217 bytes .../__pycache__/future.cpython-38.pyc | Bin 0 -> 3034 bytes .../__pycache__/ioloop.cpython-38.pyc | Bin 0 -> 4049 bytes .../__pycache__/zmqstream.cpython-38.pyc | Bin 0 -> 16905 bytes .../zmq/eventloop/_deprecated.py | 214 + .../site-packages/zmq/eventloop/future.py | 73 + .../site-packages/zmq/eventloop/ioloop.py | 136 + .../zmq/eventloop/minitornado/__init__.py | 11 + .../__pycache__/__init__.cpython-38.pyc | Bin 0 -> 621 bytes .../__pycache__/concurrent.cpython-38.pyc | Bin 0 -> 894 bytes .../__pycache__/ioloop.cpython-38.pyc | Bin 0 -> 33605 bytes .../__pycache__/log.cpython-38.pyc | Bin 0 -> 342 bytes .../__pycache__/stack_context.cpython-38.pyc | Bin 0 -> 10705 bytes .../__pycache__/util.cpython-38.pyc | Bin 0 -> 7265 bytes .../zmq/eventloop/minitornado/concurrent.py | 14 + .../zmq/eventloop/minitornado/ioloop.py | 1056 +++ .../zmq/eventloop/minitornado/log.py | 6 + .../minitornado/platform/__init__.py | 0 .../__pycache__/__init__.cpython-38.pyc | Bin 0 -> 170 bytes .../platform/__pycache__/auto.cpython-38.pyc | Bin 0 -> 937 bytes .../__pycache__/common.cpython-38.pyc | Bin 0 -> 2335 bytes .../__pycache__/interface.cpython-38.pyc | Bin 0 -> 2302 bytes .../platform/__pycache__/posix.cpython-38.pyc | Bin 0 -> 1998 bytes .../__pycache__/windows.cpython-38.pyc | Bin 0 -> 683 bytes .../eventloop/minitornado/platform/auto.py | 45 + .../eventloop/minitornado/platform/common.py | 91 + .../minitornado/platform/interface.py | 63 + .../eventloop/minitornado/platform/posix.py | 70 + .../eventloop/minitornado/platform/windows.py | 20 + .../eventloop/minitornado/stack_context.py | 388 ++ .../zmq/eventloop/minitornado/util.py | 216 + .../site-packages/zmq/eventloop/zmqstream.py | 553 ++ .../site-packages/zmq/green/__init__.py | 40 + .../green/__pycache__/__init__.cpython-38.pyc | Bin 0 -> 828 bytes .../zmq/green/__pycache__/core.cpython-38.pyc | Bin 0 -> 7540 bytes .../green/__pycache__/device.cpython-38.pyc | Bin 0 -> 929 bytes .../zmq/green/__pycache__/poll.cpython-38.pyc | Bin 0 -> 2162 bytes .../python3.8/site-packages/zmq/green/core.py | 290 + .../site-packages/zmq/green/device.py | 32 + .../zmq/green/eventloop/__init__.py | 3 + .../__pycache__/__init__.cpython-38.pyc | Bin 0 -> 234 bytes .../__pycache__/ioloop.cpython-38.pyc | Bin 0 -> 190 bytes .../__pycache__/zmqstream.cpython-38.pyc | Bin 0 -> 674 bytes .../zmq/green/eventloop/ioloop.py | 1 + .../zmq/green/eventloop/zmqstream.py | 11 + .../python3.8/site-packages/zmq/green/poll.py | 97 + .../site-packages/zmq/log/__init__.py | 0 .../site-packages/zmq/log/__main__.py | 108 + .../log/__pycache__/__init__.cpython-38.pyc | Bin 0 -> 143 bytes .../log/__pycache__/__main__.cpython-38.pyc | Bin 0 -> 3222 bytes .../log/__pycache__/handlers.cpython-38.pyc | Bin 0 -> 6003 bytes .../site-packages/zmq/log/handlers.py | 182 + .../site-packages/zmq/ssh/__init__.py | 1 + .../ssh/__pycache__/__init__.cpython-38.pyc | Bin 0 -> 174 bytes .../ssh/__pycache__/forward.cpython-38.pyc | Bin 0 -> 2325 bytes .../zmq/ssh/__pycache__/tunnel.cpython-38.pyc | Bin 0 -> 10776 bytes .../site-packages/zmq/ssh/forward.py | 91 + .../python3.8/site-packages/zmq/ssh/tunnel.py | 368 ++ .../site-packages/zmq/sugar/__init__.py | 29 + .../sugar/__pycache__/__init__.cpython-38.pyc | Bin 0 -> 787 bytes .../__pycache__/attrsettr.cpython-38.pyc | Bin 0 -> 1883 bytes .../__pycache__/constants.cpython-38.pyc | Bin 0 -> 1668 bytes .../sugar/__pycache__/context.cpython-38.pyc | Bin 0 -> 8638 bytes .../sugar/__pycache__/frame.cpython-38.pyc | Bin 0 -> 3324 bytes .../zmq/sugar/__pycache__/poll.cpython-38.pyc | Bin 0 -> 4944 bytes .../sugar/__pycache__/socket.cpython-38.pyc | Bin 0 -> 25789 bytes .../__pycache__/stopwatch.cpython-38.pyc | Bin 0 -> 1248 bytes .../sugar/__pycache__/tracker.cpython-38.pyc | Bin 0 -> 3406 bytes .../sugar/__pycache__/version.cpython-38.pyc | Bin 0 -> 1168 bytes .../site-packages/zmq/sugar/attrsettr.py | 66 + .../site-packages/zmq/sugar/constants.py | 108 + .../site-packages/zmq/sugar/context.py | 282 + .../site-packages/zmq/sugar/frame.py | 88 + .../python3.8/site-packages/zmq/sugar/poll.py | 162 + .../site-packages/zmq/sugar/socket.py | 849 +++ .../site-packages/zmq/sugar/stopwatch.py | 31 + .../site-packages/zmq/sugar/tracker.py | 122 + .../site-packages/zmq/sugar/version.py | 48 + .../site-packages/zmq/tests/__init__.py | 192 + .../tests/__pycache__/__init__.cpython-38.pyc | Bin 0 -> 6477 bytes .../tests/__pycache__/conftest.cpython-38.pyc | Bin 0 -> 607 bytes .../__pycache__/test_asyncio.cpython-38.pyc | Bin 0 -> 16523 bytes .../__pycache__/test_auth.cpython-38.pyc | Bin 0 -> 15755 bytes .../test_cffi_backend.cpython-38.pyc | Bin 0 -> 7981 bytes .../__pycache__/test_constants.cpython-38.pyc | Bin 0 -> 4013 bytes .../__pycache__/test_context.cpython-38.pyc | Bin 0 -> 14224 bytes .../__pycache__/test_cython.cpython-38.pyc | Bin 0 -> 1191 bytes .../test_decorators.cpython-38.pyc | Bin 0 -> 12765 bytes .../__pycache__/test_device.cpython-38.pyc | Bin 0 -> 5388 bytes .../__pycache__/test_draft.cpython-38.pyc | Bin 0 -> 1722 bytes .../__pycache__/test_error.cpython-38.pyc | Bin 0 -> 1718 bytes .../tests/__pycache__/test_etc.cpython-38.pyc | Bin 0 -> 761 bytes .../__pycache__/test_future.cpython-38.pyc | Bin 0 -> 12155 bytes .../__pycache__/test_imports.cpython-38.pyc | Bin 0 -> 2725 bytes .../__pycache__/test_includes.cpython-38.pyc | Bin 0 -> 1219 bytes .../__pycache__/test_ioloop.cpython-38.pyc | Bin 0 -> 4810 bytes .../tests/__pycache__/test_log.cpython-38.pyc | Bin 0 -> 5878 bytes .../__pycache__/test_message.cpython-38.pyc | Bin 0 -> 9855 bytes .../__pycache__/test_monitor.cpython-38.pyc | Bin 0 -> 2316 bytes .../__pycache__/test_monqueue.cpython-38.pyc | Bin 0 -> 5665 bytes .../__pycache__/test_multipart.cpython-38.pyc | Bin 0 -> 1289 bytes .../__pycache__/test_pair.cpython-38.pyc | Bin 0 -> 1684 bytes .../__pycache__/test_poll.cpython-38.pyc | Bin 0 -> 6068 bytes .../test_proxy_steerable.cpython-38.pyc | Bin 0 -> 3291 bytes .../__pycache__/test_pubsub.cpython-38.pyc | Bin 0 -> 1379 bytes .../__pycache__/test_reqrep.cpython-38.pyc | Bin 0 -> 2282 bytes .../test_retry_eintr.cpython-38.pyc | Bin 0 -> 3527 bytes .../__pycache__/test_security.cpython-38.pyc | Bin 0 -> 6651 bytes .../__pycache__/test_socket.cpython-38.pyc | Bin 0 -> 19756 bytes .../tests/__pycache__/test_ssh.cpython-38.pyc | Bin 0 -> 451 bytes .../__pycache__/test_version.cpython-38.pyc | Bin 0 -> 1633 bytes .../test_win32_shim.cpython-38.pyc | Bin 0 -> 1935 bytes .../tests/__pycache__/test_z85.cpython-38.pyc | Bin 0 -> 1746 bytes .../__pycache__/test_zmqstream.cpython-38.pyc | Bin 0 -> 3740 bytes .../site-packages/zmq/tests/conftest.py | 14 + .../site-packages/zmq/tests/test_asyncio.py | 481 ++ .../site-packages/zmq/tests/test_auth.py | 557 ++ .../zmq/tests/test_cffi_backend.py | 297 + .../site-packages/zmq/tests/test_constants.py | 121 + .../site-packages/zmq/tests/test_context.py | 392 ++ .../site-packages/zmq/tests/test_cython.py | 41 + .../zmq/tests/test_decorators.py | 375 ++ .../site-packages/zmq/tests/test_device.py | 167 + .../site-packages/zmq/tests/test_draft.py | 52 + .../site-packages/zmq/tests/test_error.py | 43 + .../site-packages/zmq/tests/test_etc.py | 20 + .../site-packages/zmq/tests/test_future.py | 341 + .../site-packages/zmq/tests/test_imports.py | 68 + .../site-packages/zmq/tests/test_includes.py | 33 + .../site-packages/zmq/tests/test_ioloop.py | 141 + .../site-packages/zmq/tests/test_log.py | 178 + .../site-packages/zmq/tests/test_message.py | 347 + .../site-packages/zmq/tests/test_monitor.py | 83 + .../site-packages/zmq/tests/test_monqueue.py | 221 + .../site-packages/zmq/tests/test_multipart.py | 35 + .../site-packages/zmq/tests/test_pair.py | 53 + .../site-packages/zmq/tests/test_poll.py | 238 + .../zmq/tests/test_proxy_steerable.py | 109 + .../site-packages/zmq/tests/test_pubsub.py | 42 + .../site-packages/zmq/tests/test_reqrep.py | 62 + .../zmq/tests/test_retry_eintr.py | 95 + .../site-packages/zmq/tests/test_security.py | 236 + .../site-packages/zmq/tests/test_socket.py | 649 ++ .../site-packages/zmq/tests/test_ssh.py | 8 + .../site-packages/zmq/tests/test_version.py | 44 + .../zmq/tests/test_win32_shim.py | 63 + .../site-packages/zmq/tests/test_z85.py | 63 + .../site-packages/zmq/tests/test_zmqstream.py | 79 + .../site-packages/zmq/utils/__init__.py | 0 .../utils/__pycache__/__init__.cpython-38.pyc | Bin 0 -> 145 bytes .../__pycache__/constant_names.cpython-38.pyc | Bin 0 -> 5992 bytes .../utils/__pycache__/garbage.cpython-38.pyc | Bin 0 -> 5707 bytes .../utils/__pycache__/interop.cpython-38.pyc | Bin 0 -> 741 bytes .../utils/__pycache__/jsonapi.cpython-38.pyc | Bin 0 -> 1445 bytes .../utils/__pycache__/monitor.cpython-38.pyc | Bin 0 -> 2112 bytes .../utils/__pycache__/sixcerpt.cpython-38.pyc | Bin 0 -> 833 bytes .../utils/__pycache__/strtypes.cpython-38.pyc | Bin 0 -> 1027 bytes .../utils/__pycache__/win32.cpython-38.pyc | Bin 0 -> 4828 bytes .../zmq/utils/__pycache__/z85.cpython-38.pyc | Bin 0 -> 1959 bytes .../site-packages/zmq/utils/buffers.pxd | 313 + .../site-packages/zmq/utils/compiler.json | 22 + .../site-packages/zmq/utils/config.json | 16 + .../site-packages/zmq/utils/constant_names.py | 550 ++ .../site-packages/zmq/utils/garbage.py | 200 + .../site-packages/zmq/utils/getpid_compat.h | 6 + .../site-packages/zmq/utils/interop.py | 33 + .../site-packages/zmq/utils/ipcmaxlen.h | 21 + .../site-packages/zmq/utils/jsonapi.py | 59 + .../site-packages/zmq/utils/monitor.py | 68 + .../python3.8/site-packages/zmq/utils/mutex.h | 82 + .../zmq/utils/pyversion_compat.h | 25 + .../site-packages/zmq/utils/sixcerpt.py | 52 + .../site-packages/zmq/utils/strtypes.py | 45 + .../site-packages/zmq/utils/win32.py | 132 + .../python3.8/site-packages/zmq/utils/z85.py | 62 + .../site-packages/zmq/utils/zmq_compat.h | 113 + .../site-packages/zmq/utils/zmq_constants.h | 893 +++ .venv/lib64 | 1 + .venv/pyvenv.cfg | 3 + .../share/jupyter/kernels/python3/kernel.json | 11 + .../jupyter/kernels/python3/logo-32x32.png | Bin 0 -> 1084 bytes .../jupyter/kernels/python3/logo-64x64.png | Bin 0 -> 2180 bytes .venv/share/man/man1/ipython.1.gz | Bin 0 -> 1039 bytes .../CacheControl-0.12.6-py2.py3-none-any.whl | Bin 0 -> 23290 bytes .../appdirs-1.4.4-py2.py3-none-any.whl | Bin 0 -> 14131 bytes .../certifi-2020.4.5.1-py2.py3-none-any.whl | Bin 0 -> 161630 bytes .../chardet-3.0.4-py2.py3-none-any.whl | Bin 0 -> 136755 bytes .../colorama-0.4.3-py2.py3-none-any.whl | Bin 0 -> 20362 bytes .../contextlib2-0.6.0-py2.py3-none-any.whl | Bin 0 -> 12457 bytes .../distlib-0.3.0-py2.py3-none-any.whl | Bin 0 -> 147296 bytes .../distro-1.5.0-py2.py3-none-any.whl | Bin 0 -> 19272 bytes .../html5lib-1.0.1-py2.py3-none-any.whl | Bin 0 -> 115285 bytes .../idna-2.9-py2.py3-none-any.whl | Bin 0 -> 62768 bytes .../ipaddr-2.2.0-py2.py3-none-any.whl | Bin 0 -> 19552 bytes .../lockfile-0.12.2-py2.py3-none-any.whl | Bin 0 -> 17238 bytes .../msgpack-0.6.2-py2.py3-none-any.whl | Bin 0 -> 88193 bytes .../packaging-20.3-py2.py3-none-any.whl | Bin 0 -> 37509 bytes .../pep517-0.8.2-py2.py3-none-any.whl | Bin 0 -> 21951 bytes .../pip-20.1.1-py2.py3-none-any.whl | Bin 0 -> 285469 bytes .../pkg_resources-0.0.0-py2.py3-none-any.whl | Bin 0 -> 122578 bytes .../progress-1.5-py2.py3-none-any.whl | Bin 0 -> 12812 bytes .../pyparsing-2.4.7-py2.py3-none-any.whl | Bin 0 -> 72474 bytes .../requests-2.23.0-py2.py3-none-any.whl | Bin 0 -> 63192 bytes .../resolvelib-0.3.0-py2.py3-none-any.whl | Bin 0 -> 15663 bytes .../retrying-1.3.3-py2.py3-none-any.whl | Bin 0 -> 11621 bytes .../setuptools-44.0.0-py2.py3-none-any.whl | Bin 0 -> 472710 bytes .../six-1.15.0-py2.py3-none-any.whl | Bin 0 -> 15549 bytes .../toml-0.10.1-py2.py3-none-any.whl | Bin 0 -> 20955 bytes .../urllib3-1.25.9-py2.py3-none-any.whl | Bin 0 -> 123228 bytes .../webencodings-0.5.1-py2.py3-none-any.whl | Bin 0 -> 15749 bytes .../wheel-0.34.2-py2.py3-none-any.whl | Bin 0 -> 30875 bytes .vscode/settings.json | 4 + Prueba.py | 1 + prueba2.py | 4 + 5237 files changed, 581823 insertions(+) create mode 100644 .venv/bin/Activate.ps1 create mode 100644 .venv/bin/activate create mode 100644 .venv/bin/activate.csh create mode 100644 .venv/bin/activate.fish create mode 100755 .venv/bin/easy_install create mode 100755 .venv/bin/easy_install-3.8 create mode 100755 .venv/bin/epylint create mode 100755 .venv/bin/iptest create mode 100755 .venv/bin/iptest3 create mode 100755 .venv/bin/ipython create mode 100755 .venv/bin/ipython3 create mode 100755 .venv/bin/isort create mode 100755 .venv/bin/jupyter create mode 100755 .venv/bin/jupyter-kernel create mode 100755 .venv/bin/jupyter-kernelspec create mode 100755 .venv/bin/jupyter-migrate create mode 100755 .venv/bin/jupyter-run create mode 100755 .venv/bin/jupyter-troubleshoot create mode 100755 .venv/bin/pip create mode 100755 .venv/bin/pip3 create mode 100755 .venv/bin/pip3.8 create mode 100755 .venv/bin/pygmentize create mode 100755 .venv/bin/pylint create mode 100755 .venv/bin/pyreverse create mode 120000 .venv/bin/python create mode 120000 .venv/bin/python3 create mode 100755 .venv/bin/symilar create mode 100644 .venv/lib/python3.8/site-packages/IPython/__init__.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/__main__.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/__pycache__/__init__.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/__pycache__/__main__.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/__pycache__/config.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/__pycache__/conftest.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/__pycache__/consoleapp.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/__pycache__/display.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/__pycache__/frontend.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/__pycache__/html.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/__pycache__/nbconvert.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/__pycache__/nbformat.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/__pycache__/parallel.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/__pycache__/paths.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/__pycache__/qt.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/config.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/conftest.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/consoleapp.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/__init__.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/__pycache__/__init__.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/__pycache__/alias.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/__pycache__/application.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/__pycache__/async_helpers.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/__pycache__/autocall.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/__pycache__/builtin_trap.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/__pycache__/compilerop.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/__pycache__/completer.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/__pycache__/completerlib.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/__pycache__/crashhandler.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/__pycache__/debugger.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/__pycache__/display.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/__pycache__/display_trap.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/__pycache__/displayhook.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/__pycache__/displaypub.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/__pycache__/error.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/__pycache__/events.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/__pycache__/excolors.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/__pycache__/extensions.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/__pycache__/formatters.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/__pycache__/getipython.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/__pycache__/history.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/__pycache__/historyapp.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/__pycache__/hooks.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/__pycache__/inputsplitter.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/__pycache__/inputtransformer.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/__pycache__/inputtransformer2.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/__pycache__/interactiveshell.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/__pycache__/latex_symbols.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/__pycache__/logger.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/__pycache__/macro.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/__pycache__/magic.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/__pycache__/magic_arguments.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/__pycache__/oinspect.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/__pycache__/page.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/__pycache__/payload.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/__pycache__/payloadpage.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/__pycache__/prefilter.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/__pycache__/profileapp.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/__pycache__/profiledir.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/__pycache__/prompts.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/__pycache__/pylabtools.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/__pycache__/release.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/__pycache__/shellapp.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/__pycache__/splitinput.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/__pycache__/ultratb.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/__pycache__/usage.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/alias.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/application.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/async_helpers.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/autocall.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/builtin_trap.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/compilerop.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/completer.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/completerlib.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/crashhandler.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/debugger.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/display.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/display_trap.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/displayhook.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/displaypub.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/error.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/events.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/excolors.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/extensions.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/formatters.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/getipython.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/history.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/historyapp.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/hooks.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/inputsplitter.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/inputtransformer.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/inputtransformer2.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/interactiveshell.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/latex_symbols.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/logger.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/macro.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/magic.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/magic_arguments.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/magics/__init__.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/magics/__pycache__/__init__.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/magics/__pycache__/auto.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/magics/__pycache__/basic.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/magics/__pycache__/code.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/magics/__pycache__/config.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/magics/__pycache__/display.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/magics/__pycache__/execution.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/magics/__pycache__/extension.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/magics/__pycache__/history.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/magics/__pycache__/logging.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/magics/__pycache__/namespace.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/magics/__pycache__/osm.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/magics/__pycache__/packaging.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/magics/__pycache__/pylab.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/magics/__pycache__/script.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/magics/auto.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/magics/basic.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/magics/code.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/magics/config.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/magics/display.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/magics/execution.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/magics/extension.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/magics/history.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/magics/logging.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/magics/namespace.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/magics/osm.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/magics/packaging.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/magics/pylab.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/magics/script.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/oinspect.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/page.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/payload.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/payloadpage.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/prefilter.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/profile/README_STARTUP create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/profileapp.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/profiledir.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/prompts.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/pylabtools.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/release.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/shellapp.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/splitinput.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/tests/2x2.jpg create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/tests/2x2.png create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/tests/__init__.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/tests/__pycache__/__init__.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/tests/__pycache__/bad_all.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/tests/__pycache__/nonascii.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/tests/__pycache__/nonascii2.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/tests/__pycache__/print_argv.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/tests/__pycache__/refbug.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/tests/__pycache__/simpleerr.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/tests/__pycache__/tclass.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/tests/__pycache__/test_alias.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/tests/__pycache__/test_application.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/tests/__pycache__/test_async_helpers.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/tests/__pycache__/test_autocall.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/tests/__pycache__/test_compilerop.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/tests/__pycache__/test_completer.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/tests/__pycache__/test_completerlib.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/tests/__pycache__/test_debugger.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/tests/__pycache__/test_display.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/tests/__pycache__/test_displayhook.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/tests/__pycache__/test_events.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/tests/__pycache__/test_extension.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/tests/__pycache__/test_formatters.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/tests/__pycache__/test_handlers.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/tests/__pycache__/test_history.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/tests/__pycache__/test_hooks.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/tests/__pycache__/test_imports.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/tests/__pycache__/test_inputsplitter.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/tests/__pycache__/test_inputtransformer.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/tests/__pycache__/test_inputtransformer2.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/tests/__pycache__/test_inputtransformer2_line.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/tests/__pycache__/test_interactiveshell.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/tests/__pycache__/test_iplib.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/tests/__pycache__/test_logger.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/tests/__pycache__/test_magic.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/tests/__pycache__/test_magic_arguments.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/tests/__pycache__/test_magic_terminal.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/tests/__pycache__/test_oinspect.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/tests/__pycache__/test_page.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/tests/__pycache__/test_paths.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/tests/__pycache__/test_prefilter.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/tests/__pycache__/test_profile.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/tests/__pycache__/test_prompts.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/tests/__pycache__/test_pylabtools.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/tests/__pycache__/test_run.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/tests/__pycache__/test_shellapp.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/tests/__pycache__/test_splitinput.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/tests/__pycache__/test_ultratb.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/tests/bad_all.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/tests/daft_extension/__pycache__/daft_extension.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/tests/daft_extension/daft_extension.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/tests/nonascii.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/tests/nonascii2.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/tests/print_argv.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/tests/refbug.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/tests/simpleerr.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/tests/tclass.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/tests/test_alias.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/tests/test_application.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/tests/test_async_helpers.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/tests/test_autocall.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/tests/test_compilerop.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/tests/test_completer.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/tests/test_completerlib.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/tests/test_debugger.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/tests/test_display.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/tests/test_displayhook.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/tests/test_events.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/tests/test_extension.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/tests/test_formatters.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/tests/test_handlers.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/tests/test_history.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/tests/test_hooks.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/tests/test_imports.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/tests/test_inputsplitter.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/tests/test_inputtransformer.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/tests/test_inputtransformer2.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/tests/test_inputtransformer2_line.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/tests/test_interactiveshell.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/tests/test_iplib.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/tests/test_logger.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/tests/test_magic.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/tests/test_magic_arguments.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/tests/test_magic_terminal.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/tests/test_oinspect.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/tests/test_page.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/tests/test_paths.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/tests/test_prefilter.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/tests/test_profile.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/tests/test_prompts.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/tests/test_pylabtools.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/tests/test_run.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/tests/test_shellapp.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/tests/test_splitinput.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/tests/test_ultratb.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/ultratb.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/core/usage.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/display.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/extensions/__init__.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/extensions/__pycache__/__init__.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/extensions/__pycache__/autoreload.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/extensions/__pycache__/cythonmagic.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/extensions/__pycache__/rmagic.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/extensions/__pycache__/storemagic.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/extensions/__pycache__/sympyprinting.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/extensions/autoreload.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/extensions/cythonmagic.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/extensions/rmagic.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/extensions/storemagic.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/extensions/sympyprinting.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/extensions/tests/__init__.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/extensions/tests/__pycache__/__init__.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/extensions/tests/__pycache__/test_autoreload.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/extensions/tests/__pycache__/test_storemagic.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/extensions/tests/test_autoreload.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/extensions/tests/test_storemagic.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/external/__init__.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/external/__pycache__/__init__.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/external/__pycache__/mathjax.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/external/__pycache__/qt_for_kernel.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/external/__pycache__/qt_loaders.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/external/decorators/__init__.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/external/decorators/__pycache__/__init__.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/external/decorators/__pycache__/_decorators.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/external/decorators/__pycache__/_numpy_testing_noseclasses.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/external/decorators/_decorators.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/external/decorators/_numpy_testing_noseclasses.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/external/mathjax.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/external/qt_for_kernel.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/external/qt_loaders.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/frontend.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/html.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/kernel/__init__.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/kernel/__main__.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/kernel/__pycache__/__init__.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/kernel/__pycache__/__main__.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/kernel/__pycache__/adapter.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/kernel/__pycache__/channels.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/kernel/__pycache__/channelsabc.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/kernel/__pycache__/client.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/kernel/__pycache__/clientabc.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/kernel/__pycache__/connect.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/kernel/__pycache__/kernelspec.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/kernel/__pycache__/kernelspecapp.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/kernel/__pycache__/launcher.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/kernel/__pycache__/manager.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/kernel/__pycache__/managerabc.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/kernel/__pycache__/multikernelmanager.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/kernel/__pycache__/restarter.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/kernel/__pycache__/threaded.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/kernel/adapter.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/kernel/channels.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/kernel/channelsabc.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/kernel/client.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/kernel/clientabc.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/kernel/connect.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/kernel/kernelspec.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/kernel/kernelspecapp.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/kernel/launcher.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/kernel/manager.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/kernel/managerabc.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/kernel/multikernelmanager.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/kernel/restarter.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/kernel/threaded.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/lib/__init__.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/lib/__pycache__/__init__.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/lib/__pycache__/backgroundjobs.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/lib/__pycache__/clipboard.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/lib/__pycache__/deepreload.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/lib/__pycache__/demo.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/lib/__pycache__/display.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/lib/__pycache__/editorhooks.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/lib/__pycache__/guisupport.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/lib/__pycache__/inputhook.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/lib/__pycache__/inputhookglut.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/lib/__pycache__/inputhookgtk.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/lib/__pycache__/inputhookgtk3.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/lib/__pycache__/inputhookpyglet.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/lib/__pycache__/inputhookqt4.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/lib/__pycache__/inputhookwx.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/lib/__pycache__/kernel.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/lib/__pycache__/latextools.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/lib/__pycache__/lexers.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/lib/__pycache__/pretty.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/lib/__pycache__/security.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/lib/backgroundjobs.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/lib/clipboard.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/lib/deepreload.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/lib/demo.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/lib/display.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/lib/editorhooks.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/lib/guisupport.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/lib/inputhook.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/lib/inputhookglut.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/lib/inputhookgtk.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/lib/inputhookgtk3.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/lib/inputhookpyglet.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/lib/inputhookqt4.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/lib/inputhookwx.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/lib/kernel.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/lib/latextools.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/lib/lexers.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/lib/pretty.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/lib/security.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/lib/tests/__init__.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/lib/tests/__pycache__/__init__.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/lib/tests/__pycache__/test_backgroundjobs.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/lib/tests/__pycache__/test_clipboard.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/lib/tests/__pycache__/test_deepreload.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/lib/tests/__pycache__/test_display.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/lib/tests/__pycache__/test_editorhooks.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/lib/tests/__pycache__/test_imports.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/lib/tests/__pycache__/test_latextools.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/lib/tests/__pycache__/test_lexers.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/lib/tests/__pycache__/test_pretty.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/lib/tests/__pycache__/test_security.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/lib/tests/test.wav create mode 100644 .venv/lib/python3.8/site-packages/IPython/lib/tests/test_backgroundjobs.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/lib/tests/test_clipboard.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/lib/tests/test_deepreload.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/lib/tests/test_display.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/lib/tests/test_editorhooks.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/lib/tests/test_imports.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/lib/tests/test_latextools.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/lib/tests/test_lexers.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/lib/tests/test_pretty.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/lib/tests/test_security.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/nbconvert.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/nbformat.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/parallel.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/paths.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/qt.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/sphinxext/__init__.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/sphinxext/__pycache__/__init__.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/sphinxext/__pycache__/custom_doctests.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/sphinxext/__pycache__/ipython_console_highlighting.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/sphinxext/__pycache__/ipython_directive.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/sphinxext/custom_doctests.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/sphinxext/ipython_console_highlighting.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/sphinxext/ipython_directive.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/terminal/__init__.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/terminal/__pycache__/__init__.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/terminal/__pycache__/console.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/terminal/__pycache__/debugger.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/terminal/__pycache__/embed.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/terminal/__pycache__/interactiveshell.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/terminal/__pycache__/ipapp.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/terminal/__pycache__/magics.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/terminal/__pycache__/prompts.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/terminal/__pycache__/ptshell.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/terminal/__pycache__/ptutils.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/terminal/__pycache__/shortcuts.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/terminal/console.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/terminal/debugger.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/terminal/embed.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/terminal/interactiveshell.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/terminal/ipapp.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/terminal/magics.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/terminal/prompts.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/terminal/pt_inputhooks/__init__.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/terminal/pt_inputhooks/__pycache__/__init__.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/terminal/pt_inputhooks/__pycache__/asyncio.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/terminal/pt_inputhooks/__pycache__/glut.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/terminal/pt_inputhooks/__pycache__/gtk.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/terminal/pt_inputhooks/__pycache__/gtk3.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/terminal/pt_inputhooks/__pycache__/osx.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/terminal/pt_inputhooks/__pycache__/pyglet.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/terminal/pt_inputhooks/__pycache__/qt.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/terminal/pt_inputhooks/__pycache__/tk.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/terminal/pt_inputhooks/__pycache__/wx.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/terminal/pt_inputhooks/asyncio.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/terminal/pt_inputhooks/glut.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/terminal/pt_inputhooks/gtk.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/terminal/pt_inputhooks/gtk3.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/terminal/pt_inputhooks/osx.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/terminal/pt_inputhooks/pyglet.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/terminal/pt_inputhooks/qt.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/terminal/pt_inputhooks/tk.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/terminal/pt_inputhooks/wx.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/terminal/ptshell.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/terminal/ptutils.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/terminal/shortcuts.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/terminal/tests/__init__.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/terminal/tests/__pycache__/__init__.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/terminal/tests/__pycache__/test_debug_magic.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/terminal/tests/__pycache__/test_embed.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/terminal/tests/__pycache__/test_help.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/terminal/tests/__pycache__/test_interactivshell.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/terminal/tests/test_debug_magic.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/terminal/tests/test_embed.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/terminal/tests/test_help.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/terminal/tests/test_interactivshell.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/testing/__init__.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/testing/__main__.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/testing/__pycache__/__init__.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/testing/__pycache__/__main__.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/testing/__pycache__/decorators.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/testing/__pycache__/globalipapp.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/testing/__pycache__/iptest.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/testing/__pycache__/iptestcontroller.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/testing/__pycache__/ipunittest.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/testing/__pycache__/skipdoctest.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/testing/__pycache__/tools.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/testing/decorators.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/testing/globalipapp.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/testing/iptest.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/testing/iptestcontroller.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/testing/ipunittest.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/testing/plugin/README.txt create mode 100644 .venv/lib/python3.8/site-packages/IPython/testing/plugin/__init__.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/testing/plugin/__pycache__/__init__.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/testing/plugin/__pycache__/dtexample.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/testing/plugin/__pycache__/ipdoctest.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/testing/plugin/__pycache__/iptest.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/testing/plugin/__pycache__/setup.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/testing/plugin/__pycache__/show_refs.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/testing/plugin/__pycache__/simple.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/testing/plugin/__pycache__/simplevars.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/testing/plugin/__pycache__/test_ipdoctest.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/testing/plugin/__pycache__/test_refs.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/testing/plugin/dtexample.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/testing/plugin/ipdoctest.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/testing/plugin/iptest.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/testing/plugin/setup.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/testing/plugin/show_refs.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/testing/plugin/simple.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/testing/plugin/simplevars.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/testing/plugin/test_combo.txt create mode 100644 .venv/lib/python3.8/site-packages/IPython/testing/plugin/test_example.txt create mode 100644 .venv/lib/python3.8/site-packages/IPython/testing/plugin/test_exampleip.txt create mode 100644 .venv/lib/python3.8/site-packages/IPython/testing/plugin/test_ipdoctest.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/testing/plugin/test_refs.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/testing/skipdoctest.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/testing/tests/__init__.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/testing/tests/__pycache__/__init__.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/testing/tests/__pycache__/test_decorators.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/testing/tests/__pycache__/test_ipunittest.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/testing/tests/__pycache__/test_tools.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/testing/tests/test_decorators.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/testing/tests/test_ipunittest.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/testing/tests/test_tools.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/testing/tools.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/utils/PyColorize.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/utils/__init__.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/utils/__pycache__/PyColorize.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/utils/__pycache__/__init__.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/utils/__pycache__/_process_cli.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/utils/__pycache__/_process_common.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/utils/__pycache__/_process_posix.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/utils/__pycache__/_process_win32.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/utils/__pycache__/_process_win32_controller.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/utils/__pycache__/_sysinfo.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/utils/__pycache__/capture.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/utils/__pycache__/colorable.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/utils/__pycache__/coloransi.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/utils/__pycache__/contexts.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/utils/__pycache__/daemonize.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/utils/__pycache__/data.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/utils/__pycache__/decorators.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/utils/__pycache__/dir2.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/utils/__pycache__/encoding.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/utils/__pycache__/eventful.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/utils/__pycache__/frame.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/utils/__pycache__/generics.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/utils/__pycache__/importstring.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/utils/__pycache__/io.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/utils/__pycache__/ipstruct.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/utils/__pycache__/jsonutil.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/utils/__pycache__/localinterfaces.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/utils/__pycache__/log.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/utils/__pycache__/module_paths.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/utils/__pycache__/openpy.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/utils/__pycache__/path.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/utils/__pycache__/pickleutil.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/utils/__pycache__/process.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/utils/__pycache__/py3compat.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/utils/__pycache__/sentinel.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/utils/__pycache__/shimmodule.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/utils/__pycache__/signatures.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/utils/__pycache__/strdispatch.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/utils/__pycache__/sysinfo.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/utils/__pycache__/syspathcontext.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/utils/__pycache__/tempdir.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/utils/__pycache__/terminal.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/utils/__pycache__/text.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/utils/__pycache__/timing.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/utils/__pycache__/tokenutil.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/utils/__pycache__/traitlets.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/utils/__pycache__/tz.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/utils/__pycache__/ulinecache.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/utils/__pycache__/version.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/utils/__pycache__/wildcard.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/utils/_process_cli.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/utils/_process_common.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/utils/_process_posix.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/utils/_process_win32.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/utils/_process_win32_controller.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/utils/_sysinfo.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/utils/capture.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/utils/colorable.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/utils/coloransi.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/utils/contexts.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/utils/daemonize.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/utils/data.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/utils/decorators.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/utils/dir2.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/utils/encoding.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/utils/eventful.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/utils/frame.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/utils/generics.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/utils/importstring.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/utils/io.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/utils/ipstruct.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/utils/jsonutil.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/utils/localinterfaces.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/utils/log.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/utils/module_paths.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/utils/openpy.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/utils/path.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/utils/pickleutil.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/utils/process.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/utils/py3compat.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/utils/sentinel.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/utils/shimmodule.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/utils/signatures.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/utils/strdispatch.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/utils/sysinfo.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/utils/syspathcontext.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/utils/tempdir.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/utils/terminal.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/utils/tests/__init__.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/utils/tests/__pycache__/__init__.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/utils/tests/__pycache__/test_capture.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/utils/tests/__pycache__/test_decorators.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/utils/tests/__pycache__/test_dir2.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/utils/tests/__pycache__/test_imports.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/utils/tests/__pycache__/test_importstring.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/utils/tests/__pycache__/test_io.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/utils/tests/__pycache__/test_module_paths.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/utils/tests/__pycache__/test_openpy.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/utils/tests/__pycache__/test_path.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/utils/tests/__pycache__/test_process.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/utils/tests/__pycache__/test_pycolorize.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/utils/tests/__pycache__/test_shimmodule.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/utils/tests/__pycache__/test_sysinfo.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/utils/tests/__pycache__/test_tempdir.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/utils/tests/__pycache__/test_text.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/utils/tests/__pycache__/test_tokenutil.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/utils/tests/__pycache__/test_wildcard.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/IPython/utils/tests/test_capture.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/utils/tests/test_decorators.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/utils/tests/test_dir2.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/utils/tests/test_imports.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/utils/tests/test_importstring.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/utils/tests/test_io.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/utils/tests/test_module_paths.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/utils/tests/test_openpy.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/utils/tests/test_path.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/utils/tests/test_process.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/utils/tests/test_pycolorize.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/utils/tests/test_shimmodule.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/utils/tests/test_sysinfo.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/utils/tests/test_tempdir.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/utils/tests/test_text.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/utils/tests/test_tokenutil.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/utils/tests/test_wildcard.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/utils/text.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/utils/timing.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/utils/tokenutil.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/utils/traitlets.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/utils/tz.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/utils/ulinecache.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/utils/version.py create mode 100644 .venv/lib/python3.8/site-packages/IPython/utils/wildcard.py create mode 100644 .venv/lib/python3.8/site-packages/Pygments-2.7.3.dist-info/AUTHORS create mode 100644 .venv/lib/python3.8/site-packages/Pygments-2.7.3.dist-info/INSTALLER create mode 100644 .venv/lib/python3.8/site-packages/Pygments-2.7.3.dist-info/LICENSE create mode 100644 .venv/lib/python3.8/site-packages/Pygments-2.7.3.dist-info/METADATA create mode 100644 .venv/lib/python3.8/site-packages/Pygments-2.7.3.dist-info/RECORD create mode 100644 .venv/lib/python3.8/site-packages/Pygments-2.7.3.dist-info/WHEEL create mode 100644 .venv/lib/python3.8/site-packages/Pygments-2.7.3.dist-info/entry_points.txt create mode 100644 .venv/lib/python3.8/site-packages/Pygments-2.7.3.dist-info/top_level.txt create mode 100644 .venv/lib/python3.8/site-packages/__pycache__/decorator.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/__pycache__/easy_install.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/__pycache__/ipykernel_launcher.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/__pycache__/jupyter.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/__pycache__/mccabe.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/__pycache__/pickleshare.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/__pycache__/six.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/astroid-2.4.2.dist-info/COPYING create mode 100644 .venv/lib/python3.8/site-packages/astroid-2.4.2.dist-info/COPYING.LESSER create mode 100644 .venv/lib/python3.8/site-packages/astroid-2.4.2.dist-info/INSTALLER create mode 100644 .venv/lib/python3.8/site-packages/astroid-2.4.2.dist-info/METADATA create mode 100644 .venv/lib/python3.8/site-packages/astroid-2.4.2.dist-info/RECORD create mode 100644 .venv/lib/python3.8/site-packages/astroid-2.4.2.dist-info/WHEEL create mode 100644 .venv/lib/python3.8/site-packages/astroid-2.4.2.dist-info/top_level.txt create mode 100644 .venv/lib/python3.8/site-packages/astroid/__init__.py create mode 100644 .venv/lib/python3.8/site-packages/astroid/__pkginfo__.py create mode 100644 .venv/lib/python3.8/site-packages/astroid/__pycache__/__init__.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/astroid/__pycache__/__pkginfo__.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/astroid/__pycache__/_ast.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/astroid/__pycache__/arguments.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/astroid/__pycache__/as_string.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/astroid/__pycache__/bases.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/astroid/__pycache__/builder.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/astroid/__pycache__/context.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/astroid/__pycache__/decorators.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/astroid/__pycache__/exceptions.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/astroid/__pycache__/helpers.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/astroid/__pycache__/inference.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/astroid/__pycache__/manager.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/astroid/__pycache__/mixins.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/astroid/__pycache__/modutils.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/astroid/__pycache__/node_classes.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/astroid/__pycache__/nodes.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/astroid/__pycache__/objects.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/astroid/__pycache__/protocols.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/astroid/__pycache__/raw_building.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/astroid/__pycache__/rebuilder.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/astroid/__pycache__/scoped_nodes.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/astroid/__pycache__/test_utils.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/astroid/__pycache__/transforms.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/astroid/__pycache__/util.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/astroid/_ast.py create mode 100644 .venv/lib/python3.8/site-packages/astroid/arguments.py create mode 100644 .venv/lib/python3.8/site-packages/astroid/as_string.py create mode 100644 .venv/lib/python3.8/site-packages/astroid/bases.py create mode 100644 .venv/lib/python3.8/site-packages/astroid/brain/__pycache__/brain_argparse.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/astroid/brain/__pycache__/brain_attrs.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/astroid/brain/__pycache__/brain_boto3.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/astroid/brain/__pycache__/brain_builtin_inference.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/astroid/brain/__pycache__/brain_collections.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/astroid/brain/__pycache__/brain_crypt.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/astroid/brain/__pycache__/brain_curses.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/astroid/brain/__pycache__/brain_dataclasses.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/astroid/brain/__pycache__/brain_dateutil.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/astroid/brain/__pycache__/brain_fstrings.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/astroid/brain/__pycache__/brain_functools.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/astroid/brain/__pycache__/brain_gi.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/astroid/brain/__pycache__/brain_hashlib.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/astroid/brain/__pycache__/brain_http.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/astroid/brain/__pycache__/brain_io.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/astroid/brain/__pycache__/brain_mechanize.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/astroid/brain/__pycache__/brain_multiprocessing.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/astroid/brain/__pycache__/brain_namedtuple_enum.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/astroid/brain/__pycache__/brain_nose.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/astroid/brain/__pycache__/brain_numpy_core_fromnumeric.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/astroid/brain/__pycache__/brain_numpy_core_function_base.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/astroid/brain/__pycache__/brain_numpy_core_multiarray.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/astroid/brain/__pycache__/brain_numpy_core_numeric.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/astroid/brain/__pycache__/brain_numpy_core_numerictypes.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/astroid/brain/__pycache__/brain_numpy_core_umath.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/astroid/brain/__pycache__/brain_numpy_ndarray.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/astroid/brain/__pycache__/brain_numpy_random_mtrand.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/astroid/brain/__pycache__/brain_numpy_utils.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/astroid/brain/__pycache__/brain_pkg_resources.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/astroid/brain/__pycache__/brain_pytest.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/astroid/brain/__pycache__/brain_qt.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/astroid/brain/__pycache__/brain_random.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/astroid/brain/__pycache__/brain_re.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/astroid/brain/__pycache__/brain_responses.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/astroid/brain/__pycache__/brain_scipy_signal.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/astroid/brain/__pycache__/brain_six.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/astroid/brain/__pycache__/brain_ssl.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/astroid/brain/__pycache__/brain_subprocess.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/astroid/brain/__pycache__/brain_threading.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/astroid/brain/__pycache__/brain_typing.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/astroid/brain/__pycache__/brain_uuid.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/astroid/brain/brain_argparse.py create mode 100644 .venv/lib/python3.8/site-packages/astroid/brain/brain_attrs.py create mode 100644 .venv/lib/python3.8/site-packages/astroid/brain/brain_boto3.py create mode 100644 .venv/lib/python3.8/site-packages/astroid/brain/brain_builtin_inference.py create mode 100644 .venv/lib/python3.8/site-packages/astroid/brain/brain_collections.py create mode 100644 .venv/lib/python3.8/site-packages/astroid/brain/brain_crypt.py create mode 100644 .venv/lib/python3.8/site-packages/astroid/brain/brain_curses.py create mode 100644 .venv/lib/python3.8/site-packages/astroid/brain/brain_dataclasses.py create mode 100644 .venv/lib/python3.8/site-packages/astroid/brain/brain_dateutil.py create mode 100644 .venv/lib/python3.8/site-packages/astroid/brain/brain_fstrings.py create mode 100644 .venv/lib/python3.8/site-packages/astroid/brain/brain_functools.py create mode 100644 .venv/lib/python3.8/site-packages/astroid/brain/brain_gi.py create mode 100644 .venv/lib/python3.8/site-packages/astroid/brain/brain_hashlib.py create mode 100644 .venv/lib/python3.8/site-packages/astroid/brain/brain_http.py create mode 100644 .venv/lib/python3.8/site-packages/astroid/brain/brain_io.py create mode 100644 .venv/lib/python3.8/site-packages/astroid/brain/brain_mechanize.py create mode 100644 .venv/lib/python3.8/site-packages/astroid/brain/brain_multiprocessing.py create mode 100644 .venv/lib/python3.8/site-packages/astroid/brain/brain_namedtuple_enum.py create mode 100644 .venv/lib/python3.8/site-packages/astroid/brain/brain_nose.py create mode 100644 .venv/lib/python3.8/site-packages/astroid/brain/brain_numpy_core_fromnumeric.py create mode 100644 .venv/lib/python3.8/site-packages/astroid/brain/brain_numpy_core_function_base.py create mode 100644 .venv/lib/python3.8/site-packages/astroid/brain/brain_numpy_core_multiarray.py create mode 100644 .venv/lib/python3.8/site-packages/astroid/brain/brain_numpy_core_numeric.py create mode 100644 .venv/lib/python3.8/site-packages/astroid/brain/brain_numpy_core_numerictypes.py create mode 100644 .venv/lib/python3.8/site-packages/astroid/brain/brain_numpy_core_umath.py create mode 100644 .venv/lib/python3.8/site-packages/astroid/brain/brain_numpy_ndarray.py create mode 100644 .venv/lib/python3.8/site-packages/astroid/brain/brain_numpy_random_mtrand.py create mode 100644 .venv/lib/python3.8/site-packages/astroid/brain/brain_numpy_utils.py create mode 100644 .venv/lib/python3.8/site-packages/astroid/brain/brain_pkg_resources.py create mode 100644 .venv/lib/python3.8/site-packages/astroid/brain/brain_pytest.py create mode 100644 .venv/lib/python3.8/site-packages/astroid/brain/brain_qt.py create mode 100644 .venv/lib/python3.8/site-packages/astroid/brain/brain_random.py create mode 100644 .venv/lib/python3.8/site-packages/astroid/brain/brain_re.py create mode 100644 .venv/lib/python3.8/site-packages/astroid/brain/brain_responses.py create mode 100644 .venv/lib/python3.8/site-packages/astroid/brain/brain_scipy_signal.py create mode 100644 .venv/lib/python3.8/site-packages/astroid/brain/brain_six.py create mode 100644 .venv/lib/python3.8/site-packages/astroid/brain/brain_ssl.py create mode 100644 .venv/lib/python3.8/site-packages/astroid/brain/brain_subprocess.py create mode 100644 .venv/lib/python3.8/site-packages/astroid/brain/brain_threading.py create mode 100644 .venv/lib/python3.8/site-packages/astroid/brain/brain_typing.py create mode 100644 .venv/lib/python3.8/site-packages/astroid/brain/brain_uuid.py create mode 100644 .venv/lib/python3.8/site-packages/astroid/builder.py create mode 100644 .venv/lib/python3.8/site-packages/astroid/context.py create mode 100644 .venv/lib/python3.8/site-packages/astroid/decorators.py create mode 100644 .venv/lib/python3.8/site-packages/astroid/exceptions.py create mode 100644 .venv/lib/python3.8/site-packages/astroid/helpers.py create mode 100644 .venv/lib/python3.8/site-packages/astroid/inference.py create mode 100644 .venv/lib/python3.8/site-packages/astroid/interpreter/__init__.py create mode 100644 .venv/lib/python3.8/site-packages/astroid/interpreter/__pycache__/__init__.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/astroid/interpreter/__pycache__/dunder_lookup.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/astroid/interpreter/__pycache__/objectmodel.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/astroid/interpreter/_import/__init__.py create mode 100644 .venv/lib/python3.8/site-packages/astroid/interpreter/_import/__pycache__/__init__.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/astroid/interpreter/_import/__pycache__/spec.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/astroid/interpreter/_import/__pycache__/util.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/astroid/interpreter/_import/spec.py create mode 100644 .venv/lib/python3.8/site-packages/astroid/interpreter/_import/util.py create mode 100644 .venv/lib/python3.8/site-packages/astroid/interpreter/dunder_lookup.py create mode 100644 .venv/lib/python3.8/site-packages/astroid/interpreter/objectmodel.py create mode 100644 .venv/lib/python3.8/site-packages/astroid/manager.py create mode 100644 .venv/lib/python3.8/site-packages/astroid/mixins.py create mode 100644 .venv/lib/python3.8/site-packages/astroid/modutils.py create mode 100644 .venv/lib/python3.8/site-packages/astroid/node_classes.py create mode 100644 .venv/lib/python3.8/site-packages/astroid/nodes.py create mode 100644 .venv/lib/python3.8/site-packages/astroid/objects.py create mode 100644 .venv/lib/python3.8/site-packages/astroid/protocols.py create mode 100644 .venv/lib/python3.8/site-packages/astroid/raw_building.py create mode 100644 .venv/lib/python3.8/site-packages/astroid/rebuilder.py create mode 100644 .venv/lib/python3.8/site-packages/astroid/scoped_nodes.py create mode 100644 .venv/lib/python3.8/site-packages/astroid/test_utils.py create mode 100644 .venv/lib/python3.8/site-packages/astroid/transforms.py create mode 100644 .venv/lib/python3.8/site-packages/astroid/util.py create mode 100644 .venv/lib/python3.8/site-packages/backcall-0.2.0.dist-info/INSTALLER create mode 100644 .venv/lib/python3.8/site-packages/backcall-0.2.0.dist-info/LICENSE create mode 100644 .venv/lib/python3.8/site-packages/backcall-0.2.0.dist-info/METADATA create mode 100644 .venv/lib/python3.8/site-packages/backcall-0.2.0.dist-info/RECORD create mode 100644 .venv/lib/python3.8/site-packages/backcall-0.2.0.dist-info/WHEEL create mode 100644 .venv/lib/python3.8/site-packages/backcall/__init__.py create mode 100644 .venv/lib/python3.8/site-packages/backcall/__pycache__/__init__.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/backcall/__pycache__/_signatures.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/backcall/__pycache__/backcall.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/backcall/_signatures.py create mode 100644 .venv/lib/python3.8/site-packages/backcall/backcall.py create mode 100644 .venv/lib/python3.8/site-packages/dateutil/__init__.py create mode 100644 .venv/lib/python3.8/site-packages/dateutil/__pycache__/__init__.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/dateutil/__pycache__/_common.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/dateutil/__pycache__/_version.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/dateutil/__pycache__/easter.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/dateutil/__pycache__/relativedelta.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/dateutil/__pycache__/rrule.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/dateutil/__pycache__/tzwin.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/dateutil/__pycache__/utils.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/dateutil/_common.py create mode 100644 .venv/lib/python3.8/site-packages/dateutil/_version.py create mode 100644 .venv/lib/python3.8/site-packages/dateutil/easter.py create mode 100644 .venv/lib/python3.8/site-packages/dateutil/parser/__init__.py create mode 100644 .venv/lib/python3.8/site-packages/dateutil/parser/__pycache__/__init__.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/dateutil/parser/__pycache__/_parser.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/dateutil/parser/__pycache__/isoparser.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/dateutil/parser/_parser.py create mode 100644 .venv/lib/python3.8/site-packages/dateutil/parser/isoparser.py create mode 100644 .venv/lib/python3.8/site-packages/dateutil/relativedelta.py create mode 100644 .venv/lib/python3.8/site-packages/dateutil/rrule.py create mode 100644 .venv/lib/python3.8/site-packages/dateutil/tz/__init__.py create mode 100644 .venv/lib/python3.8/site-packages/dateutil/tz/__pycache__/__init__.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/dateutil/tz/__pycache__/_common.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/dateutil/tz/__pycache__/_factories.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/dateutil/tz/__pycache__/tz.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/dateutil/tz/__pycache__/win.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/dateutil/tz/_common.py create mode 100644 .venv/lib/python3.8/site-packages/dateutil/tz/_factories.py create mode 100644 .venv/lib/python3.8/site-packages/dateutil/tz/tz.py create mode 100644 .venv/lib/python3.8/site-packages/dateutil/tz/win.py create mode 100644 .venv/lib/python3.8/site-packages/dateutil/tzwin.py create mode 100644 .venv/lib/python3.8/site-packages/dateutil/utils.py create mode 100644 .venv/lib/python3.8/site-packages/dateutil/zoneinfo/__init__.py create mode 100644 .venv/lib/python3.8/site-packages/dateutil/zoneinfo/__pycache__/__init__.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/dateutil/zoneinfo/__pycache__/rebuild.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/dateutil/zoneinfo/dateutil-zoneinfo.tar.gz create mode 100644 .venv/lib/python3.8/site-packages/dateutil/zoneinfo/rebuild.py create mode 100644 .venv/lib/python3.8/site-packages/decorator-4.4.2.dist-info/INSTALLER create mode 100644 .venv/lib/python3.8/site-packages/decorator-4.4.2.dist-info/LICENSE.txt create mode 100644 .venv/lib/python3.8/site-packages/decorator-4.4.2.dist-info/METADATA create mode 100644 .venv/lib/python3.8/site-packages/decorator-4.4.2.dist-info/RECORD create mode 100644 .venv/lib/python3.8/site-packages/decorator-4.4.2.dist-info/WHEEL create mode 100644 .venv/lib/python3.8/site-packages/decorator-4.4.2.dist-info/pbr.json create mode 100644 .venv/lib/python3.8/site-packages/decorator-4.4.2.dist-info/top_level.txt create mode 100644 .venv/lib/python3.8/site-packages/decorator.py create mode 100644 .venv/lib/python3.8/site-packages/easy_install.py create mode 100644 .venv/lib/python3.8/site-packages/ipykernel-5.4.2.dist-info/COPYING.md create mode 100644 .venv/lib/python3.8/site-packages/ipykernel-5.4.2.dist-info/INSTALLER create mode 100644 .venv/lib/python3.8/site-packages/ipykernel-5.4.2.dist-info/METADATA create mode 100644 .venv/lib/python3.8/site-packages/ipykernel-5.4.2.dist-info/RECORD create mode 100644 .venv/lib/python3.8/site-packages/ipykernel-5.4.2.dist-info/WHEEL create mode 100644 .venv/lib/python3.8/site-packages/ipykernel-5.4.2.dist-info/top_level.txt create mode 100644 .venv/lib/python3.8/site-packages/ipykernel/__init__.py create mode 100644 .venv/lib/python3.8/site-packages/ipykernel/__main__.py create mode 100644 .venv/lib/python3.8/site-packages/ipykernel/__pycache__/__init__.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/ipykernel/__pycache__/__main__.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/ipykernel/__pycache__/_eventloop_macos.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/ipykernel/__pycache__/_version.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/ipykernel/__pycache__/codeutil.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/ipykernel/__pycache__/connect.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/ipykernel/__pycache__/datapub.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/ipykernel/__pycache__/displayhook.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/ipykernel/__pycache__/embed.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/ipykernel/__pycache__/eventloops.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/ipykernel/__pycache__/heartbeat.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/ipykernel/__pycache__/iostream.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/ipykernel/__pycache__/ipkernel.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/ipykernel/__pycache__/jsonutil.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/ipykernel/__pycache__/kernelapp.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/ipykernel/__pycache__/kernelbase.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/ipykernel/__pycache__/kernelspec.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/ipykernel/__pycache__/log.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/ipykernel/__pycache__/parentpoller.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/ipykernel/__pycache__/pickleutil.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/ipykernel/__pycache__/serialize.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/ipykernel/__pycache__/trio_runner.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/ipykernel/__pycache__/zmqshell.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/ipykernel/_eventloop_macos.py create mode 100644 .venv/lib/python3.8/site-packages/ipykernel/_version.py create mode 100644 .venv/lib/python3.8/site-packages/ipykernel/codeutil.py create mode 100644 .venv/lib/python3.8/site-packages/ipykernel/comm/__init__.py create mode 100644 .venv/lib/python3.8/site-packages/ipykernel/comm/__pycache__/__init__.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/ipykernel/comm/__pycache__/comm.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/ipykernel/comm/__pycache__/manager.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/ipykernel/comm/comm.py create mode 100644 .venv/lib/python3.8/site-packages/ipykernel/comm/manager.py create mode 100644 .venv/lib/python3.8/site-packages/ipykernel/connect.py create mode 100644 .venv/lib/python3.8/site-packages/ipykernel/datapub.py create mode 100644 .venv/lib/python3.8/site-packages/ipykernel/displayhook.py create mode 100644 .venv/lib/python3.8/site-packages/ipykernel/embed.py create mode 100644 .venv/lib/python3.8/site-packages/ipykernel/eventloops.py create mode 100644 .venv/lib/python3.8/site-packages/ipykernel/gui/__init__.py create mode 100644 .venv/lib/python3.8/site-packages/ipykernel/gui/__pycache__/__init__.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/ipykernel/gui/__pycache__/gtk3embed.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/ipykernel/gui/__pycache__/gtkembed.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/ipykernel/gui/gtk3embed.py create mode 100644 .venv/lib/python3.8/site-packages/ipykernel/gui/gtkembed.py create mode 100644 .venv/lib/python3.8/site-packages/ipykernel/heartbeat.py create mode 100644 .venv/lib/python3.8/site-packages/ipykernel/inprocess/__init__.py create mode 100644 .venv/lib/python3.8/site-packages/ipykernel/inprocess/__pycache__/__init__.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/ipykernel/inprocess/__pycache__/blocking.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/ipykernel/inprocess/__pycache__/channels.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/ipykernel/inprocess/__pycache__/client.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/ipykernel/inprocess/__pycache__/constants.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/ipykernel/inprocess/__pycache__/ipkernel.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/ipykernel/inprocess/__pycache__/manager.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/ipykernel/inprocess/__pycache__/socket.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/ipykernel/inprocess/blocking.py create mode 100644 .venv/lib/python3.8/site-packages/ipykernel/inprocess/channels.py create mode 100644 .venv/lib/python3.8/site-packages/ipykernel/inprocess/client.py create mode 100644 .venv/lib/python3.8/site-packages/ipykernel/inprocess/constants.py create mode 100644 .venv/lib/python3.8/site-packages/ipykernel/inprocess/ipkernel.py create mode 100644 .venv/lib/python3.8/site-packages/ipykernel/inprocess/manager.py create mode 100644 .venv/lib/python3.8/site-packages/ipykernel/inprocess/socket.py create mode 100644 .venv/lib/python3.8/site-packages/ipykernel/inprocess/tests/__init__.py create mode 100644 .venv/lib/python3.8/site-packages/ipykernel/inprocess/tests/__pycache__/__init__.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/ipykernel/inprocess/tests/__pycache__/test_kernel.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/ipykernel/inprocess/tests/__pycache__/test_kernelmanager.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/ipykernel/inprocess/tests/test_kernel.py create mode 100644 .venv/lib/python3.8/site-packages/ipykernel/inprocess/tests/test_kernelmanager.py create mode 100644 .venv/lib/python3.8/site-packages/ipykernel/iostream.py create mode 100644 .venv/lib/python3.8/site-packages/ipykernel/ipkernel.py create mode 100644 .venv/lib/python3.8/site-packages/ipykernel/jsonutil.py create mode 100644 .venv/lib/python3.8/site-packages/ipykernel/kernelapp.py create mode 100644 .venv/lib/python3.8/site-packages/ipykernel/kernelbase.py create mode 100644 .venv/lib/python3.8/site-packages/ipykernel/kernelspec.py create mode 100644 .venv/lib/python3.8/site-packages/ipykernel/log.py create mode 100644 .venv/lib/python3.8/site-packages/ipykernel/parentpoller.py create mode 100644 .venv/lib/python3.8/site-packages/ipykernel/pickleutil.py create mode 100644 .venv/lib/python3.8/site-packages/ipykernel/pylab/__init__.py create mode 100644 .venv/lib/python3.8/site-packages/ipykernel/pylab/__pycache__/__init__.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/ipykernel/pylab/__pycache__/backend_inline.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/ipykernel/pylab/__pycache__/config.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/ipykernel/pylab/backend_inline.py create mode 100644 .venv/lib/python3.8/site-packages/ipykernel/pylab/config.py create mode 100644 .venv/lib/python3.8/site-packages/ipykernel/resources/logo-32x32.png create mode 100644 .venv/lib/python3.8/site-packages/ipykernel/resources/logo-64x64.png create mode 100644 .venv/lib/python3.8/site-packages/ipykernel/serialize.py create mode 100644 .venv/lib/python3.8/site-packages/ipykernel/tests/__init__.py create mode 100644 .venv/lib/python3.8/site-packages/ipykernel/tests/__pycache__/__init__.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/ipykernel/tests/__pycache__/_asyncio_utils.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/ipykernel/tests/__pycache__/test_async.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/ipykernel/tests/__pycache__/test_connect.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/ipykernel/tests/__pycache__/test_embed_kernel.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/ipykernel/tests/__pycache__/test_eventloop.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/ipykernel/tests/__pycache__/test_heartbeat.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/ipykernel/tests/__pycache__/test_io.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/ipykernel/tests/__pycache__/test_jsonutil.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/ipykernel/tests/__pycache__/test_kernel.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/ipykernel/tests/__pycache__/test_kernelspec.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/ipykernel/tests/__pycache__/test_message_spec.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/ipykernel/tests/__pycache__/test_pickleutil.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/ipykernel/tests/__pycache__/test_serialize.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/ipykernel/tests/__pycache__/test_start_kernel.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/ipykernel/tests/__pycache__/test_zmq_shell.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/ipykernel/tests/__pycache__/utils.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/ipykernel/tests/_asyncio_utils.py create mode 100644 .venv/lib/python3.8/site-packages/ipykernel/tests/test_async.py create mode 100644 .venv/lib/python3.8/site-packages/ipykernel/tests/test_connect.py create mode 100644 .venv/lib/python3.8/site-packages/ipykernel/tests/test_embed_kernel.py create mode 100644 .venv/lib/python3.8/site-packages/ipykernel/tests/test_eventloop.py create mode 100644 .venv/lib/python3.8/site-packages/ipykernel/tests/test_heartbeat.py create mode 100644 .venv/lib/python3.8/site-packages/ipykernel/tests/test_io.py create mode 100644 .venv/lib/python3.8/site-packages/ipykernel/tests/test_jsonutil.py create mode 100644 .venv/lib/python3.8/site-packages/ipykernel/tests/test_kernel.py create mode 100644 .venv/lib/python3.8/site-packages/ipykernel/tests/test_kernelspec.py create mode 100644 .venv/lib/python3.8/site-packages/ipykernel/tests/test_message_spec.py create mode 100644 .venv/lib/python3.8/site-packages/ipykernel/tests/test_pickleutil.py create mode 100644 .venv/lib/python3.8/site-packages/ipykernel/tests/test_serialize.py create mode 100644 .venv/lib/python3.8/site-packages/ipykernel/tests/test_start_kernel.py create mode 100644 .venv/lib/python3.8/site-packages/ipykernel/tests/test_zmq_shell.py create mode 100644 .venv/lib/python3.8/site-packages/ipykernel/tests/utils.py create mode 100644 .venv/lib/python3.8/site-packages/ipykernel/trio_runner.py create mode 100644 .venv/lib/python3.8/site-packages/ipykernel/zmqshell.py create mode 100644 .venv/lib/python3.8/site-packages/ipykernel_launcher.py create mode 100644 .venv/lib/python3.8/site-packages/ipython-7.19.0.dist-info/INSTALLER create mode 100644 .venv/lib/python3.8/site-packages/ipython-7.19.0.dist-info/LICENSE create mode 100644 .venv/lib/python3.8/site-packages/ipython-7.19.0.dist-info/METADATA create mode 100644 .venv/lib/python3.8/site-packages/ipython-7.19.0.dist-info/RECORD create mode 100644 .venv/lib/python3.8/site-packages/ipython-7.19.0.dist-info/WHEEL create mode 100644 .venv/lib/python3.8/site-packages/ipython-7.19.0.dist-info/entry_points.txt create mode 100644 .venv/lib/python3.8/site-packages/ipython-7.19.0.dist-info/top_level.txt create mode 100644 .venv/lib/python3.8/site-packages/ipython_genutils-0.2.0.dist-info/DESCRIPTION.rst create mode 100644 .venv/lib/python3.8/site-packages/ipython_genutils-0.2.0.dist-info/INSTALLER create mode 100644 .venv/lib/python3.8/site-packages/ipython_genutils-0.2.0.dist-info/METADATA create mode 100644 .venv/lib/python3.8/site-packages/ipython_genutils-0.2.0.dist-info/RECORD create mode 100644 .venv/lib/python3.8/site-packages/ipython_genutils-0.2.0.dist-info/WHEEL create mode 100644 .venv/lib/python3.8/site-packages/ipython_genutils-0.2.0.dist-info/metadata.json create mode 100644 .venv/lib/python3.8/site-packages/ipython_genutils-0.2.0.dist-info/top_level.txt create mode 100644 .venv/lib/python3.8/site-packages/ipython_genutils/__init__.py create mode 100644 .venv/lib/python3.8/site-packages/ipython_genutils/__pycache__/__init__.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/ipython_genutils/__pycache__/_version.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/ipython_genutils/__pycache__/encoding.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/ipython_genutils/__pycache__/importstring.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/ipython_genutils/__pycache__/ipstruct.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/ipython_genutils/__pycache__/path.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/ipython_genutils/__pycache__/py3compat.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/ipython_genutils/__pycache__/tempdir.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/ipython_genutils/__pycache__/text.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/ipython_genutils/_version.py create mode 100644 .venv/lib/python3.8/site-packages/ipython_genutils/encoding.py create mode 100644 .venv/lib/python3.8/site-packages/ipython_genutils/importstring.py create mode 100644 .venv/lib/python3.8/site-packages/ipython_genutils/ipstruct.py create mode 100644 .venv/lib/python3.8/site-packages/ipython_genutils/path.py create mode 100644 .venv/lib/python3.8/site-packages/ipython_genutils/py3compat.py create mode 100644 .venv/lib/python3.8/site-packages/ipython_genutils/tempdir.py create mode 100644 .venv/lib/python3.8/site-packages/ipython_genutils/testing/__init__.py create mode 100644 .venv/lib/python3.8/site-packages/ipython_genutils/testing/__pycache__/__init__.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/ipython_genutils/testing/__pycache__/decorators.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/ipython_genutils/testing/decorators.py create mode 100644 .venv/lib/python3.8/site-packages/ipython_genutils/tests/__init__.py create mode 100644 .venv/lib/python3.8/site-packages/ipython_genutils/tests/__pycache__/__init__.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/ipython_genutils/tests/__pycache__/test_importstring.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/ipython_genutils/tests/__pycache__/test_path.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/ipython_genutils/tests/__pycache__/test_tempdir.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/ipython_genutils/tests/__pycache__/test_text.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/ipython_genutils/tests/test_importstring.py create mode 100644 .venv/lib/python3.8/site-packages/ipython_genutils/tests/test_path.py create mode 100644 .venv/lib/python3.8/site-packages/ipython_genutils/tests/test_tempdir.py create mode 100644 .venv/lib/python3.8/site-packages/ipython_genutils/tests/test_text.py create mode 100644 .venv/lib/python3.8/site-packages/ipython_genutils/text.py create mode 100644 .venv/lib/python3.8/site-packages/isort-5.6.4.dist-info/INSTALLER create mode 100644 .venv/lib/python3.8/site-packages/isort-5.6.4.dist-info/LICENSE create mode 100644 .venv/lib/python3.8/site-packages/isort-5.6.4.dist-info/METADATA create mode 100644 .venv/lib/python3.8/site-packages/isort-5.6.4.dist-info/RECORD create mode 100644 .venv/lib/python3.8/site-packages/isort-5.6.4.dist-info/WHEEL create mode 100644 .venv/lib/python3.8/site-packages/isort-5.6.4.dist-info/entry_points.txt create mode 100644 .venv/lib/python3.8/site-packages/isort/__init__.py create mode 100644 .venv/lib/python3.8/site-packages/isort/__main__.py create mode 100644 .venv/lib/python3.8/site-packages/isort/__pycache__/__init__.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/isort/__pycache__/__main__.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/isort/__pycache__/_version.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/isort/__pycache__/api.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/isort/__pycache__/comments.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/isort/__pycache__/core.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/isort/__pycache__/exceptions.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/isort/__pycache__/format.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/isort/__pycache__/hooks.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/isort/__pycache__/io.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/isort/__pycache__/literal.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/isort/__pycache__/logo.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/isort/__pycache__/main.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/isort/__pycache__/output.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/isort/__pycache__/parse.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/isort/__pycache__/place.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/isort/__pycache__/profiles.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/isort/__pycache__/pylama_isort.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/isort/__pycache__/sections.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/isort/__pycache__/settings.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/isort/__pycache__/setuptools_commands.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/isort/__pycache__/sorting.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/isort/__pycache__/utils.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/isort/__pycache__/wrap.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/isort/__pycache__/wrap_modes.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/isort/_future/__init__.py create mode 100644 .venv/lib/python3.8/site-packages/isort/_future/__pycache__/__init__.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/isort/_future/__pycache__/_dataclasses.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/isort/_future/_dataclasses.py create mode 100644 .venv/lib/python3.8/site-packages/isort/_vendored/toml/LICENSE create mode 100644 .venv/lib/python3.8/site-packages/isort/_vendored/toml/__init__.py create mode 100644 .venv/lib/python3.8/site-packages/isort/_vendored/toml/__pycache__/__init__.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/isort/_vendored/toml/__pycache__/decoder.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/isort/_vendored/toml/__pycache__/encoder.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/isort/_vendored/toml/__pycache__/ordered.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/isort/_vendored/toml/__pycache__/tz.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/isort/_vendored/toml/decoder.py create mode 100644 .venv/lib/python3.8/site-packages/isort/_vendored/toml/encoder.py create mode 100644 .venv/lib/python3.8/site-packages/isort/_vendored/toml/ordered.py create mode 100644 .venv/lib/python3.8/site-packages/isort/_vendored/toml/tz.py create mode 100644 .venv/lib/python3.8/site-packages/isort/_version.py create mode 100644 .venv/lib/python3.8/site-packages/isort/api.py create mode 100644 .venv/lib/python3.8/site-packages/isort/comments.py create mode 100644 .venv/lib/python3.8/site-packages/isort/core.py create mode 100644 .venv/lib/python3.8/site-packages/isort/deprecated/__init__.py create mode 100644 .venv/lib/python3.8/site-packages/isort/deprecated/__pycache__/__init__.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/isort/deprecated/__pycache__/finders.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/isort/deprecated/finders.py create mode 100644 .venv/lib/python3.8/site-packages/isort/exceptions.py create mode 100644 .venv/lib/python3.8/site-packages/isort/format.py create mode 100644 .venv/lib/python3.8/site-packages/isort/hooks.py create mode 100644 .venv/lib/python3.8/site-packages/isort/io.py create mode 100644 .venv/lib/python3.8/site-packages/isort/literal.py create mode 100644 .venv/lib/python3.8/site-packages/isort/logo.py create mode 100644 .venv/lib/python3.8/site-packages/isort/main.py create mode 100644 .venv/lib/python3.8/site-packages/isort/output.py create mode 100644 .venv/lib/python3.8/site-packages/isort/parse.py create mode 100644 .venv/lib/python3.8/site-packages/isort/place.py create mode 100644 .venv/lib/python3.8/site-packages/isort/profiles.py create mode 100644 .venv/lib/python3.8/site-packages/isort/pylama_isort.py create mode 100644 .venv/lib/python3.8/site-packages/isort/sections.py create mode 100644 .venv/lib/python3.8/site-packages/isort/settings.py create mode 100644 .venv/lib/python3.8/site-packages/isort/setuptools_commands.py create mode 100644 .venv/lib/python3.8/site-packages/isort/sorting.py create mode 100644 .venv/lib/python3.8/site-packages/isort/stdlibs/__init__.py create mode 100644 .venv/lib/python3.8/site-packages/isort/stdlibs/__pycache__/__init__.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/isort/stdlibs/__pycache__/all.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/isort/stdlibs/__pycache__/py2.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/isort/stdlibs/__pycache__/py27.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/isort/stdlibs/__pycache__/py3.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/isort/stdlibs/__pycache__/py35.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/isort/stdlibs/__pycache__/py36.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/isort/stdlibs/__pycache__/py37.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/isort/stdlibs/__pycache__/py38.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/isort/stdlibs/__pycache__/py39.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/isort/stdlibs/all.py create mode 100644 .venv/lib/python3.8/site-packages/isort/stdlibs/py2.py create mode 100644 .venv/lib/python3.8/site-packages/isort/stdlibs/py27.py create mode 100644 .venv/lib/python3.8/site-packages/isort/stdlibs/py3.py create mode 100644 .venv/lib/python3.8/site-packages/isort/stdlibs/py35.py create mode 100644 .venv/lib/python3.8/site-packages/isort/stdlibs/py36.py create mode 100644 .venv/lib/python3.8/site-packages/isort/stdlibs/py37.py create mode 100644 .venv/lib/python3.8/site-packages/isort/stdlibs/py38.py create mode 100644 .venv/lib/python3.8/site-packages/isort/stdlibs/py39.py create mode 100644 .venv/lib/python3.8/site-packages/isort/utils.py create mode 100644 .venv/lib/python3.8/site-packages/isort/wrap.py create mode 100644 .venv/lib/python3.8/site-packages/isort/wrap_modes.py create mode 100644 .venv/lib/python3.8/site-packages/jedi-0.17.2.dist-info/AUTHORS.txt create mode 100644 .venv/lib/python3.8/site-packages/jedi-0.17.2.dist-info/INSTALLER create mode 100644 .venv/lib/python3.8/site-packages/jedi-0.17.2.dist-info/LICENSE.txt create mode 100644 .venv/lib/python3.8/site-packages/jedi-0.17.2.dist-info/METADATA create mode 100644 .venv/lib/python3.8/site-packages/jedi-0.17.2.dist-info/RECORD create mode 100644 .venv/lib/python3.8/site-packages/jedi-0.17.2.dist-info/WHEEL create mode 100644 .venv/lib/python3.8/site-packages/jedi-0.17.2.dist-info/top_level.txt create mode 100644 .venv/lib/python3.8/site-packages/jedi/__init__.py create mode 100644 .venv/lib/python3.8/site-packages/jedi/__main__.py create mode 100644 .venv/lib/python3.8/site-packages/jedi/__pycache__/__init__.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/jedi/__pycache__/__main__.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/jedi/__pycache__/_compatibility.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/jedi/__pycache__/cache.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/jedi/__pycache__/common.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/jedi/__pycache__/debug.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/jedi/__pycache__/file_io.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/jedi/__pycache__/parser_utils.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/jedi/__pycache__/settings.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/jedi/__pycache__/utils.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/jedi/_compatibility.py create mode 100644 .venv/lib/python3.8/site-packages/jedi/api/__init__.py create mode 100644 .venv/lib/python3.8/site-packages/jedi/api/__pycache__/__init__.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/jedi/api/__pycache__/classes.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/jedi/api/__pycache__/completion.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/jedi/api/__pycache__/completion_cache.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/jedi/api/__pycache__/environment.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/jedi/api/__pycache__/errors.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/jedi/api/__pycache__/exceptions.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/jedi/api/__pycache__/file_name.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/jedi/api/__pycache__/helpers.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/jedi/api/__pycache__/interpreter.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/jedi/api/__pycache__/keywords.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/jedi/api/__pycache__/project.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/jedi/api/__pycache__/replstartup.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/jedi/api/__pycache__/strings.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/jedi/api/classes.py create mode 100644 .venv/lib/python3.8/site-packages/jedi/api/completion.py create mode 100644 .venv/lib/python3.8/site-packages/jedi/api/completion_cache.py create mode 100644 .venv/lib/python3.8/site-packages/jedi/api/environment.py create mode 100644 .venv/lib/python3.8/site-packages/jedi/api/errors.py create mode 100644 .venv/lib/python3.8/site-packages/jedi/api/exceptions.py create mode 100644 .venv/lib/python3.8/site-packages/jedi/api/file_name.py create mode 100644 .venv/lib/python3.8/site-packages/jedi/api/helpers.py create mode 100644 .venv/lib/python3.8/site-packages/jedi/api/interpreter.py create mode 100644 .venv/lib/python3.8/site-packages/jedi/api/keywords.py create mode 100644 .venv/lib/python3.8/site-packages/jedi/api/project.py create mode 100644 .venv/lib/python3.8/site-packages/jedi/api/refactoring/__init__.py create mode 100644 .venv/lib/python3.8/site-packages/jedi/api/refactoring/__pycache__/__init__.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/jedi/api/refactoring/__pycache__/extract.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/jedi/api/refactoring/extract.py create mode 100644 .venv/lib/python3.8/site-packages/jedi/api/replstartup.py create mode 100644 .venv/lib/python3.8/site-packages/jedi/api/strings.py create mode 100644 .venv/lib/python3.8/site-packages/jedi/cache.py create mode 100644 .venv/lib/python3.8/site-packages/jedi/common.py create mode 100644 .venv/lib/python3.8/site-packages/jedi/debug.py create mode 100644 .venv/lib/python3.8/site-packages/jedi/file_io.py create mode 100644 .venv/lib/python3.8/site-packages/jedi/inference/__init__.py create mode 100644 .venv/lib/python3.8/site-packages/jedi/inference/__pycache__/__init__.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/jedi/inference/__pycache__/analysis.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/jedi/inference/__pycache__/arguments.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/jedi/inference/__pycache__/base_value.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/jedi/inference/__pycache__/cache.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/jedi/inference/__pycache__/context.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/jedi/inference/__pycache__/docstrings.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/jedi/inference/__pycache__/dynamic_params.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/jedi/inference/__pycache__/filters.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/jedi/inference/__pycache__/finder.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/jedi/inference/__pycache__/flow_analysis.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/jedi/inference/__pycache__/helpers.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/jedi/inference/__pycache__/imports.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/jedi/inference/__pycache__/lazy_value.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/jedi/inference/__pycache__/names.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/jedi/inference/__pycache__/param.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/jedi/inference/__pycache__/parser_cache.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/jedi/inference/__pycache__/recursion.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/jedi/inference/__pycache__/references.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/jedi/inference/__pycache__/signature.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/jedi/inference/__pycache__/star_args.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/jedi/inference/__pycache__/syntax_tree.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/jedi/inference/__pycache__/sys_path.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/jedi/inference/__pycache__/utils.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/jedi/inference/analysis.py create mode 100644 .venv/lib/python3.8/site-packages/jedi/inference/arguments.py create mode 100644 .venv/lib/python3.8/site-packages/jedi/inference/base_value.py create mode 100644 .venv/lib/python3.8/site-packages/jedi/inference/cache.py create mode 100644 .venv/lib/python3.8/site-packages/jedi/inference/compiled/__init__.py create mode 100644 .venv/lib/python3.8/site-packages/jedi/inference/compiled/__pycache__/__init__.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/jedi/inference/compiled/__pycache__/access.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/jedi/inference/compiled/__pycache__/getattr_static.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/jedi/inference/compiled/__pycache__/mixed.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/jedi/inference/compiled/__pycache__/value.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/jedi/inference/compiled/access.py create mode 100644 .venv/lib/python3.8/site-packages/jedi/inference/compiled/getattr_static.py create mode 100644 .venv/lib/python3.8/site-packages/jedi/inference/compiled/mixed.py create mode 100644 .venv/lib/python3.8/site-packages/jedi/inference/compiled/subprocess/__init__.py create mode 100644 .venv/lib/python3.8/site-packages/jedi/inference/compiled/subprocess/__main__.py create mode 100644 .venv/lib/python3.8/site-packages/jedi/inference/compiled/subprocess/__pycache__/__init__.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/jedi/inference/compiled/subprocess/__pycache__/__main__.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/jedi/inference/compiled/subprocess/__pycache__/functions.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/jedi/inference/compiled/subprocess/functions.py create mode 100644 .venv/lib/python3.8/site-packages/jedi/inference/compiled/value.py create mode 100644 .venv/lib/python3.8/site-packages/jedi/inference/context.py create mode 100644 .venv/lib/python3.8/site-packages/jedi/inference/docstrings.py create mode 100644 .venv/lib/python3.8/site-packages/jedi/inference/dynamic_params.py create mode 100644 .venv/lib/python3.8/site-packages/jedi/inference/filters.py create mode 100644 .venv/lib/python3.8/site-packages/jedi/inference/finder.py create mode 100644 .venv/lib/python3.8/site-packages/jedi/inference/flow_analysis.py create mode 100644 .venv/lib/python3.8/site-packages/jedi/inference/gradual/__init__.py create mode 100644 .venv/lib/python3.8/site-packages/jedi/inference/gradual/__pycache__/__init__.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/jedi/inference/gradual/__pycache__/annotation.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/jedi/inference/gradual/__pycache__/base.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/jedi/inference/gradual/__pycache__/conversion.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/jedi/inference/gradual/__pycache__/generics.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/jedi/inference/gradual/__pycache__/stub_value.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/jedi/inference/gradual/__pycache__/type_var.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/jedi/inference/gradual/__pycache__/typeshed.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/jedi/inference/gradual/__pycache__/typing.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/jedi/inference/gradual/__pycache__/utils.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/jedi/inference/gradual/annotation.py create mode 100644 .venv/lib/python3.8/site-packages/jedi/inference/gradual/base.py create mode 100644 .venv/lib/python3.8/site-packages/jedi/inference/gradual/conversion.py create mode 100644 .venv/lib/python3.8/site-packages/jedi/inference/gradual/generics.py create mode 100644 .venv/lib/python3.8/site-packages/jedi/inference/gradual/stub_value.py create mode 100644 .venv/lib/python3.8/site-packages/jedi/inference/gradual/type_var.py create mode 100644 .venv/lib/python3.8/site-packages/jedi/inference/gradual/typeshed.py create mode 100644 .venv/lib/python3.8/site-packages/jedi/inference/gradual/typing.py create mode 100644 .venv/lib/python3.8/site-packages/jedi/inference/gradual/utils.py create mode 100644 .venv/lib/python3.8/site-packages/jedi/inference/helpers.py create mode 100644 .venv/lib/python3.8/site-packages/jedi/inference/imports.py create mode 100644 .venv/lib/python3.8/site-packages/jedi/inference/lazy_value.py create mode 100644 .venv/lib/python3.8/site-packages/jedi/inference/names.py create mode 100644 .venv/lib/python3.8/site-packages/jedi/inference/param.py create mode 100644 .venv/lib/python3.8/site-packages/jedi/inference/parser_cache.py create mode 100644 .venv/lib/python3.8/site-packages/jedi/inference/recursion.py create mode 100644 .venv/lib/python3.8/site-packages/jedi/inference/references.py create mode 100644 .venv/lib/python3.8/site-packages/jedi/inference/signature.py create mode 100644 .venv/lib/python3.8/site-packages/jedi/inference/star_args.py create mode 100644 .venv/lib/python3.8/site-packages/jedi/inference/syntax_tree.py create mode 100644 .venv/lib/python3.8/site-packages/jedi/inference/sys_path.py create mode 100644 .venv/lib/python3.8/site-packages/jedi/inference/utils.py create mode 100644 .venv/lib/python3.8/site-packages/jedi/inference/value/__init__.py create mode 100644 .venv/lib/python3.8/site-packages/jedi/inference/value/__pycache__/__init__.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/jedi/inference/value/__pycache__/decorator.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/jedi/inference/value/__pycache__/dynamic_arrays.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/jedi/inference/value/__pycache__/function.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/jedi/inference/value/__pycache__/instance.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/jedi/inference/value/__pycache__/iterable.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/jedi/inference/value/__pycache__/klass.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/jedi/inference/value/__pycache__/module.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/jedi/inference/value/__pycache__/namespace.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/jedi/inference/value/decorator.py create mode 100644 .venv/lib/python3.8/site-packages/jedi/inference/value/dynamic_arrays.py create mode 100644 .venv/lib/python3.8/site-packages/jedi/inference/value/function.py create mode 100644 .venv/lib/python3.8/site-packages/jedi/inference/value/instance.py create mode 100644 .venv/lib/python3.8/site-packages/jedi/inference/value/iterable.py create mode 100644 .venv/lib/python3.8/site-packages/jedi/inference/value/klass.py create mode 100644 .venv/lib/python3.8/site-packages/jedi/inference/value/module.py create mode 100644 .venv/lib/python3.8/site-packages/jedi/inference/value/namespace.py create mode 100644 .venv/lib/python3.8/site-packages/jedi/parser_utils.py create mode 100644 .venv/lib/python3.8/site-packages/jedi/plugins/__init__.py create mode 100644 .venv/lib/python3.8/site-packages/jedi/plugins/__pycache__/__init__.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/jedi/plugins/__pycache__/django.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/jedi/plugins/__pycache__/flask.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/jedi/plugins/__pycache__/pytest.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/jedi/plugins/__pycache__/registry.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/jedi/plugins/__pycache__/stdlib.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/jedi/plugins/django.py create mode 100644 .venv/lib/python3.8/site-packages/jedi/plugins/flask.py create mode 100644 .venv/lib/python3.8/site-packages/jedi/plugins/pytest.py create mode 100644 .venv/lib/python3.8/site-packages/jedi/plugins/registry.py create mode 100644 .venv/lib/python3.8/site-packages/jedi/plugins/stdlib.py create mode 100644 .venv/lib/python3.8/site-packages/jedi/settings.py create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/LICENSE.txt create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/apps/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/apps/config.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/apps/registry.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/conf/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/conf/global_settings.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/conf/locale/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/conf/urls/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/conf/urls/i18n.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/conf/urls/static.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/contrib/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/contrib/admin/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/contrib/admin/actions.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/contrib/admin/apps.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/contrib/admin/checks.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/contrib/admin/decorators.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/contrib/admin/filters.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/contrib/admin/forms.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/contrib/admin/helpers.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/contrib/admin/models.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/contrib/admin/options.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/contrib/admin/sites.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/contrib/admin/templatetags/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/contrib/admin/templatetags/admin_list.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/contrib/admin/templatetags/admin_modify.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/contrib/admin/templatetags/admin_static.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/contrib/admin/templatetags/admin_urls.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/contrib/admin/templatetags/base.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/contrib/admin/templatetags/log.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/contrib/admin/tests.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/contrib/admin/utils.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/contrib/admin/views/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/contrib/admin/views/autocomplete.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/contrib/admin/views/decorators.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/contrib/admin/views/main.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/contrib/admin/widgets.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/contrib/admindocs/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/contrib/admindocs/middleware.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/contrib/admindocs/urls.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/contrib/admindocs/utils.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/contrib/admindocs/views.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/contrib/auth/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/contrib/auth/admin.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/contrib/auth/apps.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/contrib/auth/backends.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/contrib/auth/base_user.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/contrib/auth/checks.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/contrib/auth/context_processors.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/contrib/auth/decorators.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/contrib/auth/forms.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/contrib/auth/handlers/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/contrib/auth/handlers/modwsgi.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/contrib/auth/hashers.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/contrib/auth/management/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/contrib/auth/management/commands/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/contrib/auth/management/commands/changepassword.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/contrib/auth/management/commands/createsuperuser.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/contrib/auth/middleware.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/contrib/auth/mixins.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/contrib/auth/models.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/contrib/auth/password_validation.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/contrib/auth/signals.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/contrib/auth/tokens.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/contrib/auth/urls.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/contrib/auth/validators.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/contrib/auth/views.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/contrib/contenttypes/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/contrib/contenttypes/admin.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/contrib/contenttypes/apps.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/contrib/contenttypes/checks.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/contrib/contenttypes/fields.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/contrib/contenttypes/forms.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/contrib/contenttypes/management/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/contrib/contenttypes/management/commands/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/contrib/contenttypes/management/commands/remove_stale_contenttypes.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/contrib/contenttypes/models.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/contrib/contenttypes/views.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/contrib/flatpages/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/contrib/flatpages/forms.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/contrib/flatpages/middleware.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/contrib/flatpages/models.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/contrib/flatpages/sitemaps.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/contrib/flatpages/templatetags/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/contrib/flatpages/templatetags/flatpages.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/contrib/flatpages/urls.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/contrib/flatpages/views.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/contrib/gis/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/contrib/gis/db/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/contrib/gis/db/models/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/contrib/gis/db/models/fields.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/contrib/humanize/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/contrib/humanize/templatetags/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/contrib/humanize/templatetags/humanize.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/contrib/messages/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/contrib/messages/api.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/contrib/messages/constants.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/contrib/messages/context_processors.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/contrib/messages/middleware.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/contrib/messages/storage/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/contrib/messages/storage/base.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/contrib/messages/storage/cookie.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/contrib/messages/storage/fallback.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/contrib/messages/storage/session.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/contrib/messages/utils.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/contrib/messages/views.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/contrib/postgres/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/contrib/postgres/aggregates/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/contrib/postgres/aggregates/general.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/contrib/postgres/aggregates/mixins.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/contrib/postgres/aggregates/statistics.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/contrib/postgres/constraints.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/contrib/postgres/fields/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/contrib/postgres/fields/array.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/contrib/postgres/fields/citext.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/contrib/postgres/fields/hstore.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/contrib/postgres/fields/jsonb.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/contrib/postgres/fields/mixins.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/contrib/postgres/fields/ranges.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/contrib/postgres/functions.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/contrib/postgres/indexes.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/contrib/postgres/lookups.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/contrib/postgres/operations.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/contrib/postgres/search.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/contrib/postgres/signals.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/contrib/postgres/validators.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/contrib/redirects/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/contrib/redirects/middleware.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/contrib/redirects/models.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/contrib/sessions/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/contrib/sessions/backends/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/contrib/sessions/backends/base.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/contrib/sessions/backends/cache.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/contrib/sessions/backends/cached_db.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/contrib/sessions/backends/db.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/contrib/sessions/backends/file.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/contrib/sessions/backends/signed_cookies.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/contrib/sessions/base_session.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/contrib/sessions/exceptions.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/contrib/sessions/management/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/contrib/sessions/management/commands/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/contrib/sessions/management/commands/clearsessions.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/contrib/sessions/middleware.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/contrib/sessions/models.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/contrib/sessions/serializers.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/contrib/sitemaps/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/contrib/sitemaps/management/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/contrib/sitemaps/management/commands/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/contrib/sitemaps/management/commands/ping_google.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/contrib/sitemaps/views.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/contrib/sites/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/contrib/sites/apps.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/contrib/sites/management.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/contrib/sites/managers.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/contrib/sites/middleware.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/contrib/sites/models.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/contrib/sites/requests.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/contrib/sites/shortcuts.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/contrib/staticfiles/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/contrib/staticfiles/apps.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/contrib/staticfiles/checks.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/contrib/staticfiles/finders.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/contrib/staticfiles/handlers.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/contrib/staticfiles/management/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/contrib/staticfiles/management/commands/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/contrib/staticfiles/management/commands/collectstatic.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/contrib/staticfiles/management/commands/findstatic.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/contrib/staticfiles/management/commands/runserver.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/contrib/staticfiles/storage.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/contrib/staticfiles/templatetags/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/contrib/staticfiles/templatetags/staticfiles.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/contrib/staticfiles/testing.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/contrib/staticfiles/urls.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/contrib/staticfiles/utils.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/contrib/staticfiles/views.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/contrib/syndication/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/contrib/syndication/views.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/core/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/core/cache/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/core/cache/backends/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/core/cache/backends/base.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/core/cache/backends/db.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/core/cache/backends/dummy.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/core/cache/backends/filebased.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/core/cache/backends/locmem.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/core/cache/backends/memcached.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/core/cache/utils.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/core/checks/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/core/checks/caches.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/core/checks/database.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/core/checks/messages.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/core/checks/model_checks.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/core/checks/registry.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/core/checks/security/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/core/checks/security/base.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/core/checks/security/csrf.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/core/checks/security/sessions.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/core/checks/templates.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/core/checks/translation.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/core/checks/urls.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/core/exceptions.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/core/files/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/core/files/base.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/core/files/images.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/core/files/locks.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/core/files/move.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/core/files/storage.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/core/files/temp.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/core/files/uploadedfile.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/core/files/uploadhandler.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/core/files/utils.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/core/handlers/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/core/handlers/base.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/core/handlers/exception.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/core/handlers/wsgi.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/core/mail/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/core/mail/backends/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/core/mail/backends/base.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/core/mail/backends/console.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/core/mail/backends/dummy.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/core/mail/backends/filebased.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/core/mail/backends/locmem.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/core/mail/backends/smtp.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/core/mail/message.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/core/mail/utils.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/core/management/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/core/management/base.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/core/management/color.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/core/management/commands/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/core/management/commands/dumpdata.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/core/management/commands/loaddata.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/core/management/commands/makemessages.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/core/management/commands/runserver.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/core/management/commands/testserver.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/core/management/sql.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/core/management/templates.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/core/management/utils.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/core/paginator.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/core/serializers/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/core/serializers/base.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/core/serializers/json.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/core/serializers/python.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/core/servers/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/core/servers/basehttp.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/core/signals.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/core/signing.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/core/validators.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/core/wsgi.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/db/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/db/backends/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/db/backends/base/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/db/backends/base/base.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/db/backends/base/client.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/db/backends/base/creation.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/db/backends/base/features.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/db/backends/base/introspection.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/db/backends/base/operations.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/db/backends/base/schema.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/db/backends/base/validation.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/db/backends/ddl_references.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/db/backends/dummy/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/db/backends/dummy/base.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/db/backends/mysql/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/db/backends/mysql/client.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/db/backends/postgresql/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/db/backends/postgresql/base.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/db/backends/postgresql/client.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/db/backends/postgresql/creation.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/db/backends/postgresql/operations.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/db/backends/signals.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/db/backends/sqlite3/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/db/backends/sqlite3/base.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/db/backends/sqlite3/creation.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/db/backends/sqlite3/features.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/db/backends/sqlite3/introspection.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/db/backends/sqlite3/operations.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/db/backends/sqlite3/schema.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/db/backends/utils.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/db/migrations/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/db/migrations/autodetector.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/db/migrations/exceptions.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/db/migrations/executor.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/db/migrations/graph.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/db/migrations/loader.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/db/migrations/migration.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/db/migrations/operations/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/db/migrations/operations/base.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/db/migrations/operations/fields.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/db/migrations/operations/models.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/db/migrations/operations/special.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/db/migrations/operations/utils.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/db/migrations/optimizer.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/db/migrations/questioner.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/db/migrations/recorder.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/db/migrations/serializer.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/db/migrations/state.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/db/migrations/topological_sort.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/db/migrations/utils.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/db/migrations/writer.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/db/models/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/db/models/aggregates.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/db/models/base.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/db/models/constraints.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/db/models/deletion.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/db/models/enums.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/db/models/expressions.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/db/models/fields/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/db/models/fields/files.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/db/models/fields/mixins.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/db/models/fields/proxy.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/db/models/fields/related.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/db/models/fields/related_descriptors.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/db/models/fields/related_lookups.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/db/models/fields/reverse_related.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/db/models/functions/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/db/models/functions/comparison.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/db/models/functions/datetime.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/db/models/functions/math.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/db/models/functions/mixins.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/db/models/functions/text.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/db/models/functions/window.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/db/models/indexes.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/db/models/lookups.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/db/models/manager.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/db/models/options.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/db/models/query.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/db/models/query_utils.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/db/models/signals.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/db/models/sql/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/db/models/sql/compiler.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/db/models/sql/constants.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/db/models/sql/datastructures.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/db/models/sql/query.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/db/models/sql/subqueries.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/db/models/sql/where.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/db/models/utils.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/db/transaction.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/db/utils.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/dispatch/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/dispatch/dispatcher.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/forms/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/forms/boundfield.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/forms/fields.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/forms/forms.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/forms/formsets.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/forms/models.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/forms/renderers.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/forms/utils.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/forms/widgets.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/http/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/http/cookie.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/http/multipartparser.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/http/request.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/http/response.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/middleware/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/middleware/cache.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/middleware/clickjacking.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/middleware/common.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/middleware/csrf.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/middleware/gzip.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/middleware/http.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/middleware/locale.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/middleware/security.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/shortcuts.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/template/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/template/backends/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/template/backends/base.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/template/backends/django.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/template/backends/dummy.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/template/backends/jinja2.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/template/backends/utils.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/template/base.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/template/context.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/template/context_processors.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/template/defaultfilters.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/template/defaulttags.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/template/engine.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/template/exceptions.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/template/library.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/template/loader.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/template/loader_tags.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/template/loaders/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/template/loaders/app_directories.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/template/loaders/base.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/template/loaders/cached.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/template/loaders/filesystem.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/template/loaders/locmem.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/template/response.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/template/smartif.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/template/utils.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/templatetags/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/templatetags/cache.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/templatetags/i18n.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/templatetags/l10n.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/templatetags/static.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/templatetags/tz.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/test/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/test/client.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/test/html.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/test/runner.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/test/selenium.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/test/signals.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/test/testcases.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/test/utils.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/urls/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/urls/base.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/urls/conf.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/urls/converters.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/urls/exceptions.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/urls/resolvers.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/urls/utils.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/utils/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/utils/_os.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/utils/archive.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/utils/autoreload.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/utils/baseconv.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/utils/cache.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/utils/crypto.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/utils/datastructures.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/utils/dateformat.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/utils/dateparse.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/utils/dates.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/utils/datetime_safe.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/utils/deconstruct.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/utils/decorators.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/utils/deprecation.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/utils/duration.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/utils/encoding.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/utils/feedgenerator.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/utils/formats.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/utils/functional.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/utils/hashable.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/utils/html.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/utils/http.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/utils/inspect.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/utils/ipv6.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/utils/itercompat.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/utils/jslex.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/utils/log.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/utils/lorem_ipsum.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/utils/module_loading.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/utils/numberformat.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/utils/regex_helper.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/utils/safestring.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/utils/six.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/utils/termcolors.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/utils/text.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/utils/timesince.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/utils/timezone.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/utils/topological_sort.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/utils/translation/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/utils/translation/reloader.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/utils/translation/template.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/utils/translation/trans_null.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/utils/translation/trans_real.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/utils/tree.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/utils/version.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/utils/xmlutils.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/views/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/views/csrf.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/views/debug.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/views/decorators/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/views/decorators/cache.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/views/decorators/clickjacking.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/views/decorators/csrf.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/views/decorators/debug.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/views/decorators/gzip.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/views/decorators/http.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/views/decorators/vary.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/views/defaults.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/views/generic/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/views/generic/base.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/views/generic/dates.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/views/generic/detail.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/views/generic/edit.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/views/generic/list.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/views/i18n.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/django-stubs/django-stubs/views/static.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/LICENSE create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2/BaseHTTPServer.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2/CGIHTTPServer.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2/ConfigParser.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2/Cookie.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2/HTMLParser.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2/Queue.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2/SimpleHTTPServer.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2/SocketServer.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2/StringIO.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2/UserDict.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2/UserList.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2/UserString.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2/__builtin__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2/_ast.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2/_collections.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2/_functools.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2/_hotshot.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2/_io.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2/_json.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2/_md5.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2/_sha.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2/_sha256.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2/_sha512.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2/_socket.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2/_sre.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2/_struct.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2/_symtable.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2/_threading_local.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2/abc.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2/ast.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2/atexit.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2/cPickle.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2/cStringIO.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2/collections.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2/commands.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2/compileall.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2/cookielib.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2/copy_reg.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2/dircache.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2/distutils/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2/distutils/emxccompiler.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2/dummy_thread.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2/email/MIMEText.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2/email/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2/email/_parseaddr.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2/email/base64mime.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2/email/charset.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2/email/encoders.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2/email/feedparser.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2/email/generator.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2/email/header.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2/email/iterators.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2/email/message.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2/email/mime/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2/email/mime/application.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2/email/mime/audio.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2/email/mime/base.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2/email/mime/image.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2/email/mime/message.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2/email/mime/multipart.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2/email/mime/nonmultipart.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2/email/mime/text.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2/email/parser.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2/email/quoprimime.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2/email/utils.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2/encodings/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2/encodings/utf_8.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2/exceptions.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2/fcntl.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2/fnmatch.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2/functools.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2/future_builtins.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2/gc.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2/getopt.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2/getpass.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2/gettext.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2/glob.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2/gzip.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2/hashlib.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2/heapq.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2/htmlentitydefs.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2/httplib.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2/imp.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2/importlib.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2/inspect.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2/io.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2/itertools.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2/json.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2/markupbase.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2/md5.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2/mimetools.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2/multiprocessing/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2/multiprocessing/dummy/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2/multiprocessing/dummy/connection.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2/multiprocessing/pool.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2/multiprocessing/process.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2/multiprocessing/util.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2/mutex.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2/nturl2path.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2/os/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2/os/path.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2/os2emxpath.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2/pipes.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2/platform.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2/popen2.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2/posix.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2/random.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2/re.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2/repr.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2/resource.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2/rfc822.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2/robotparser.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2/runpy.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2/sets.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2/sha.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2/shelve.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2/shlex.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2/signal.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2/smtplib.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2/spwd.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2/sre_constants.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2/sre_parse.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2/stat.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2/string.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2/stringold.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2/strop.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2/subprocess.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2/symbol.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2/sys.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2/tempfile.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2/textwrap.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2/thread.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2/toaiff.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2/tokenize.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2/types.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2/typing.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2/unittest.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2/urllib.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2/urllib2.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2/urlparse.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2/user.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2/whichdb.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2/xmlrpclib.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/__future__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/_bisect.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/_codecs.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/_csv.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/_curses.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/_heapq.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/_random.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/_warnings.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/_weakref.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/_weakrefset.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/aifc.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/argparse.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/array.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/asynchat.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/asyncore.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/audioop.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/base64.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/bdb.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/binascii.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/binhex.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/bisect.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/builtins.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/bz2.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/cProfile.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/calendar.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/cgi.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/cgitb.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/chunk.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/cmath.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/cmd.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/code.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/codecs.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/codeop.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/colorsys.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/contextlib.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/copy.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/crypt.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/csv.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/ctypes/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/ctypes/util.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/ctypes/wintypes.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/curses/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/curses/ascii.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/curses/panel.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/curses/textpad.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/datetime.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/decimal.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/difflib.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/dis.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/distutils/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/distutils/archive_util.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/distutils/bcppcompiler.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/distutils/ccompiler.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/distutils/cmd.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/distutils/command/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/distutils/command/bdist.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/distutils/command/bdist_dumb.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/distutils/command/bdist_msi.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/distutils/command/bdist_packager.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/distutils/command/bdist_rpm.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/distutils/command/bdist_wininst.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/distutils/command/build.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/distutils/command/build_clib.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/distutils/command/build_ext.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/distutils/command/build_py.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/distutils/command/build_scripts.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/distutils/command/check.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/distutils/command/clean.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/distutils/command/config.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/distutils/command/install.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/distutils/command/install_data.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/distutils/command/install_headers.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/distutils/command/install_lib.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/distutils/command/install_scripts.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/distutils/command/register.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/distutils/command/sdist.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/distutils/core.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/distutils/cygwinccompiler.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/distutils/debug.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/distutils/dep_util.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/distutils/dir_util.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/distutils/dist.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/distutils/errors.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/distutils/extension.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/distutils/fancy_getopt.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/distutils/file_util.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/distutils/filelist.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/distutils/log.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/distutils/msvccompiler.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/distutils/spawn.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/distutils/sysconfig.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/distutils/text_file.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/distutils/unixccompiler.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/distutils/util.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/distutils/version.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/doctest.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/ensurepip/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/errno.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/filecmp.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/fileinput.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/formatter.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/fractions.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/ftplib.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/genericpath.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/grp.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/hmac.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/imaplib.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/imghdr.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/keyword.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/lib2to3/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/lib2to3/pgen2/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/lib2to3/pgen2/driver.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/lib2to3/pgen2/grammar.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/lib2to3/pgen2/literals.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/lib2to3/pgen2/parse.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/lib2to3/pgen2/pgen.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/lib2to3/pgen2/token.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/lib2to3/pgen2/tokenize.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/lib2to3/pygram.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/lib2to3/pytree.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/linecache.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/locale.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/logging/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/logging/config.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/logging/handlers.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/macpath.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/mailbox.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/mailcap.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/marshal.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/math.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/mimetypes.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/mmap.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/modulefinder.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/netrc.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/nis.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/ntpath.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/numbers.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/opcode.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/operator.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/optparse.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/pdb.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/pickle.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/pickletools.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/pkgutil.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/plistlib.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/poplib.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/posixpath.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/pprint.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/profile.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/pstats.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/pty.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/pwd.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/py_compile.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/pyclbr.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/pydoc.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/pyexpat/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/pyexpat/errors.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/pyexpat/model.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/quopri.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/readline.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/rlcompleter.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/sched.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/select.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/shutil.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/site.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/smtpd.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/sndhdr.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/socket.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/sqlite3/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/sqlite3/dbapi2.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/sre_compile.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/ssl.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/stringprep.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/struct.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/sunau.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/symtable.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/sysconfig.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/syslog.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/tabnanny.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/tarfile.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/telnetlib.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/termios.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/threading.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/time.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/timeit.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/token.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/trace.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/traceback.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/tty.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/turtle.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/unicodedata.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/uu.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/uuid.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/warnings.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/wave.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/weakref.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/webbrowser.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/wsgiref/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/wsgiref/handlers.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/wsgiref/headers.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/wsgiref/simple_server.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/wsgiref/types.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/wsgiref/util.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/wsgiref/validate.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/xdrlib.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/xml/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/xml/etree/ElementInclude.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/xml/etree/ElementPath.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/xml/etree/ElementTree.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/xml/etree/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/xml/etree/cElementTree.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/xml/parsers/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/xml/parsers/expat/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/xml/parsers/expat/errors.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/xml/parsers/expat/model.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/xml/sax/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/xml/sax/handler.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/xml/sax/saxutils.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/xml/sax/xmlreader.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/zipfile.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/zipimport.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/zlib.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/3.6/secrets.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/3.7/contextvars.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/3.7/dataclasses.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/3/_ast.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/3/_compression.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/3/_dummy_thread.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/3/_imp.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/3/_importlib_modulespec.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/3/_json.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/3/_markupbase.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/3/_operator.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/3/_posixsubprocess.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/3/_stat.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/3/_subprocess.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/3/_thread.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/3/_threading_local.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/3/_tracemalloc.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/3/_winapi.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/3/abc.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/3/ast.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/3/asyncio/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/3/asyncio/base_events.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/3/asyncio/constants.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/3/asyncio/coroutines.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/3/asyncio/events.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/3/asyncio/exceptions.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/3/asyncio/futures.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/3/asyncio/locks.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/3/asyncio/proactor_events.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/3/asyncio/protocols.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/3/asyncio/queues.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/3/asyncio/runners.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/3/asyncio/selector_events.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/3/asyncio/streams.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/3/asyncio/subprocess.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/3/asyncio/tasks.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/3/asyncio/transports.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/3/asyncio/windows_events.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/3/asyncio/windows_utils.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/3/atexit.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/3/collections/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/3/collections/abc.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/3/compileall.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/3/concurrent/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/3/concurrent/futures/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/3/concurrent/futures/_base.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/3/concurrent/futures/process.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/3/concurrent/futures/thread.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/3/configparser.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/3/copyreg.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/3/email/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/3/email/charset.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/3/email/contentmanager.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/3/email/encoders.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/3/email/errors.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/3/email/feedparser.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/3/email/generator.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/3/email/header.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/3/email/headerregistry.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/3/email/iterators.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/3/email/message.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/3/email/mime/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/3/email/mime/application.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/3/email/mime/audio.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/3/email/mime/base.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/3/email/mime/image.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/3/email/mime/message.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/3/email/mime/multipart.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/3/email/mime/nonmultipart.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/3/email/mime/text.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/3/email/parser.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/3/email/policy.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/3/email/utils.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/3/encodings/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/3/encodings/utf_8.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/3/enum.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/3/faulthandler.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/3/fcntl.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/3/fnmatch.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/3/functools.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/3/gc.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/3/getopt.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/3/getpass.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/3/gettext.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/3/glob.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/3/gzip.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/3/hashlib.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/3/heapq.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/3/html/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/3/html/entities.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/3/html/parser.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/3/http/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/3/http/client.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/3/http/cookiejar.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/3/http/cookies.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/3/http/server.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/3/imp.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/3/importlib/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/3/importlib/abc.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/3/importlib/machinery.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/3/importlib/metadata.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/3/importlib/resources.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/3/importlib/util.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/3/inspect.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/3/io.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/3/ipaddress.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/3/itertools.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/3/json/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/3/json/decoder.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/3/json/encoder.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/3/lzma.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/3/msvcrt.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/3/multiprocessing/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/3/multiprocessing/connection.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/3/multiprocessing/context.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/3/multiprocessing/dummy/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/3/multiprocessing/dummy/connection.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/3/multiprocessing/managers.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/3/multiprocessing/pool.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/3/multiprocessing/process.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/3/multiprocessing/queues.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/3/multiprocessing/shared_memory.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/3/multiprocessing/spawn.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/3/multiprocessing/synchronize.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/3/nntplib.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/3/nturl2path.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/3/os/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/3/os/path.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/3/pathlib.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/3/pipes.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/3/platform.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/3/posix.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/3/queue.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/3/random.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/3/re.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/3/reprlib.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/3/resource.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/3/runpy.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/3/selectors.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/3/shelve.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/3/shlex.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/3/signal.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/3/smtplib.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/3/socketserver.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/3/spwd.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/3/sre_constants.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/3/sre_parse.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/3/stat.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/3/statistics.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/3/string.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/3/subprocess.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/3/symbol.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/3/sys.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/3/tempfile.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/3/textwrap.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/3/tkinter/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/3/tkinter/commondialog.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/3/tkinter/constants.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/3/tkinter/dialog.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/3/tkinter/filedialog.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/3/tkinter/messagebox.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/3/tkinter/ttk.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/3/tokenize.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/3/tracemalloc.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/3/types.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/3/typing.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/3/unittest/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/3/unittest/async_case.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/3/unittest/case.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/3/unittest/loader.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/3/unittest/mock.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/3/unittest/result.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/3/unittest/runner.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/3/unittest/signals.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/3/unittest/suite.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/3/unittest/util.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/3/urllib/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/3/urllib/error.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/3/urllib/parse.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/3/urllib/request.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/3/urllib/response.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/3/urllib/robotparser.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/3/zipapp.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2/OpenSSL/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2/OpenSSL/crypto.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2/concurrent/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2/concurrent/futures/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2/concurrent/futures/_base.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2/concurrent/futures/process.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2/concurrent/futures/thread.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2/enum.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2/fb303/FacebookService.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2/fb303/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2/gflags.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2/ipaddress.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2/kazoo/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2/kazoo/client.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2/kazoo/exceptions.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2/kazoo/recipe/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2/kazoo/recipe/watchers.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2/pathlib2.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2/pymssql.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2/routes/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2/routes/mapper.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2/routes/util.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2/scribe/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2/scribe/scribe.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2/scribe/ttypes.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2/six/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2/six/moves/BaseHTTPServer.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2/six/moves/CGIHTTPServer.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2/six/moves/SimpleHTTPServer.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2/six/moves/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2/six/moves/_dummy_thread.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2/six/moves/_thread.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2/six/moves/cPickle.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2/six/moves/configparser.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2/six/moves/email_mime_base.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2/six/moves/email_mime_multipart.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2/six/moves/email_mime_nonmultipart.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2/six/moves/email_mime_text.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2/six/moves/html_entities.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2/six/moves/html_parser.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2/six/moves/http_client.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2/six/moves/http_cookiejar.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2/six/moves/http_cookies.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2/six/moves/queue.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2/six/moves/reprlib.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2/six/moves/socketserver.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2/six/moves/urllib/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2/six/moves/urllib/error.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2/six/moves/urllib/parse.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2/six/moves/urllib/request.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2/six/moves/urllib/response.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2/six/moves/urllib/robotparser.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2/six/moves/urllib_error.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2/six/moves/urllib_parse.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2/six/moves/urllib_request.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2/six/moves/urllib_response.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2/six/moves/urllib_robotparser.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2/six/moves/xmlrpc_client.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2/tornado/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2/tornado/concurrent.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2/tornado/gen.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2/tornado/httpclient.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2/tornado/httpserver.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2/tornado/httputil.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2/tornado/ioloop.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2/tornado/locks.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2/tornado/netutil.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2/tornado/process.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2/tornado/tcpserver.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2/tornado/testing.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2/tornado/util.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2/tornado/web.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/Crypto/Cipher/AES.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/Crypto/Cipher/ARC2.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/Crypto/Cipher/ARC4.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/Crypto/Cipher/Blowfish.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/Crypto/Cipher/CAST.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/Crypto/Cipher/DES.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/Crypto/Cipher/DES3.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/Crypto/Cipher/PKCS1_OAEP.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/Crypto/Cipher/PKCS1_v1_5.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/Crypto/Cipher/XOR.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/Crypto/Cipher/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/Crypto/Cipher/blockalgo.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/Crypto/Hash/HMAC.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/Crypto/Hash/MD2.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/Crypto/Hash/MD4.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/Crypto/Hash/MD5.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/Crypto/Hash/RIPEMD.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/Crypto/Hash/SHA.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/Crypto/Hash/SHA224.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/Crypto/Hash/SHA256.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/Crypto/Hash/SHA384.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/Crypto/Hash/SHA512.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/Crypto/Hash/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/Crypto/Hash/hashalgo.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/Crypto/Protocol/AllOrNothing.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/Crypto/Protocol/Chaffing.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/Crypto/Protocol/KDF.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/Crypto/Protocol/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/Crypto/PublicKey/DSA.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/Crypto/PublicKey/ElGamal.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/Crypto/PublicKey/RSA.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/Crypto/PublicKey/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/Crypto/PublicKey/pubkey.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/Crypto/Random/Fortuna/FortunaAccumulator.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/Crypto/Random/Fortuna/FortunaGenerator.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/Crypto/Random/Fortuna/SHAd256.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/Crypto/Random/Fortuna/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/Crypto/Random/OSRNG/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/Crypto/Random/OSRNG/fallback.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/Crypto/Random/OSRNG/posix.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/Crypto/Random/OSRNG/rng_base.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/Crypto/Random/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/Crypto/Random/random.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/Crypto/Signature/PKCS1_PSS.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/Crypto/Signature/PKCS1_v1_5.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/Crypto/Signature/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/Crypto/Util/Counter.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/Crypto/Util/RFC1751.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/Crypto/Util/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/Crypto/Util/asn1.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/Crypto/Util/number.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/Crypto/Util/randpool.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/Crypto/Util/strxor.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/Crypto/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/Crypto/pct_warnings.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/atomicwrites/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/attr/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/attr/converters.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/attr/exceptions.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/attr/filters.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/attr/validators.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/backports/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/backports/ssl_match_hostname.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/backports_abc.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/bleach/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/bleach/callbacks.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/bleach/linkifier.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/bleach/sanitizer.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/bleach/utils.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/boto/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/boto/auth.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/boto/auth_handler.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/boto/compat.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/boto/connection.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/boto/ec2/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/boto/elb/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/boto/exception.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/boto/kms/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/boto/kms/exceptions.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/boto/kms/layer1.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/boto/plugin.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/boto/regioninfo.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/boto/s3/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/boto/s3/acl.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/boto/s3/bucket.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/boto/s3/bucketlistresultset.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/boto/s3/bucketlogging.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/boto/s3/connection.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/boto/s3/cors.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/boto/s3/deletemarker.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/boto/s3/key.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/boto/s3/keyfile.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/boto/s3/lifecycle.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/boto/s3/multidelete.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/boto/s3/multipart.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/boto/s3/prefix.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/boto/s3/tagging.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/boto/s3/user.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/boto/s3/website.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/boto/utils.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/certifi.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/characteristic/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/click/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/click/_termui_impl.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/click/core.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/click/decorators.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/click/exceptions.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/click/formatting.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/click/globals.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/click/parser.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/click/termui.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/click/testing.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/click/types.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/click/utils.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/croniter.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/cryptography/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/cryptography/exceptions.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/cryptography/fernet.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/cryptography/hazmat/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/cryptography/hazmat/backends/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/cryptography/hazmat/backends/interfaces.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/cryptography/hazmat/bindings/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/cryptography/hazmat/bindings/openssl/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/cryptography/hazmat/bindings/openssl/binding.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/cryptography/hazmat/primitives/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/cryptography/hazmat/primitives/asymmetric/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/cryptography/hazmat/primitives/asymmetric/dh.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/cryptography/hazmat/primitives/asymmetric/dsa.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/cryptography/hazmat/primitives/asymmetric/ec.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/cryptography/hazmat/primitives/asymmetric/ed25519.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/cryptography/hazmat/primitives/asymmetric/ed448.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/cryptography/hazmat/primitives/asymmetric/padding.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/cryptography/hazmat/primitives/asymmetric/rsa.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/cryptography/hazmat/primitives/asymmetric/utils.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/cryptography/hazmat/primitives/asymmetric/x25519.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/cryptography/hazmat/primitives/asymmetric/x448.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/cryptography/hazmat/primitives/ciphers/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/cryptography/hazmat/primitives/ciphers/aead.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/cryptography/hazmat/primitives/ciphers/algorithms.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/cryptography/hazmat/primitives/ciphers/modes.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/cryptography/hazmat/primitives/cmac.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/cryptography/hazmat/primitives/constant_time.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/cryptography/hazmat/primitives/hashes.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/cryptography/hazmat/primitives/hmac.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/cryptography/hazmat/primitives/kdf/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/cryptography/hazmat/primitives/kdf/concatkdf.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/cryptography/hazmat/primitives/kdf/hkdf.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/cryptography/hazmat/primitives/kdf/kbkdf.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/cryptography/hazmat/primitives/kdf/pbkdf2.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/cryptography/hazmat/primitives/kdf/scrypt.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/cryptography/hazmat/primitives/kdf/x963kdf.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/cryptography/hazmat/primitives/keywrap.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/cryptography/hazmat/primitives/padding.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/cryptography/hazmat/primitives/poly1305.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/cryptography/hazmat/primitives/serialization/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/cryptography/hazmat/primitives/serialization/pkcs12.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/cryptography/hazmat/primitives/twofactor/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/cryptography/hazmat/primitives/twofactor/hotp.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/cryptography/hazmat/primitives/twofactor/totp.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/cryptography/x509.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/dateutil/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/dateutil/_common.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/dateutil/parser.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/dateutil/relativedelta.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/dateutil/rrule.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/dateutil/tz/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/dateutil/tz/_common.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/dateutil/tz/tz.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/dateutil/utils.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/decorator.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/emoji.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/first.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/flask/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/flask/app.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/flask/blueprints.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/flask/cli.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/flask/config.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/flask/ctx.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/flask/debughelpers.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/flask/globals.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/flask/helpers.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/flask/json/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/flask/json/tag.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/flask/logging.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/flask/sessions.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/flask/signals.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/flask/templating.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/flask/testing.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/flask/views.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/flask/wrappers.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/geoip2/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/geoip2/database.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/geoip2/errors.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/geoip2/mixins.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/geoip2/models.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/geoip2/records.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/google/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/google/protobuf/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/google/protobuf/any_pb2.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/google/protobuf/any_test_pb2.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/google/protobuf/api_pb2.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/google/protobuf/compiler/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/google/protobuf/compiler/plugin_pb2.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/google/protobuf/descriptor.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/google/protobuf/descriptor_pb2.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/google/protobuf/descriptor_pool.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/google/protobuf/duration_pb2.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/google/protobuf/empty_pb2.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/google/protobuf/field_mask_pb2.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/google/protobuf/internal/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/google/protobuf/internal/containers.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/google/protobuf/internal/decoder.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/google/protobuf/internal/encoder.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/google/protobuf/internal/enum_type_wrapper.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/google/protobuf/internal/message_listener.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/google/protobuf/internal/well_known_types.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/google/protobuf/internal/wire_format.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/google/protobuf/json_format.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/google/protobuf/map_proto2_unittest_pb2.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/google/protobuf/map_unittest_pb2.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/google/protobuf/message.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/google/protobuf/message_factory.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/google/protobuf/reflection.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/google/protobuf/service.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/google/protobuf/source_context_pb2.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/google/protobuf/struct_pb2.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/google/protobuf/symbol_database.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/google/protobuf/test_messages_proto2_pb2.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/google/protobuf/test_messages_proto3_pb2.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/google/protobuf/timestamp_pb2.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/google/protobuf/type_pb2.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/google/protobuf/unittest_arena_pb2.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/google/protobuf/unittest_custom_options_pb2.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/google/protobuf/unittest_import_pb2.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/google/protobuf/unittest_import_public_pb2.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/google/protobuf/unittest_mset_pb2.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/google/protobuf/unittest_mset_wire_format_pb2.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/google/protobuf/unittest_no_arena_import_pb2.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/google/protobuf/unittest_no_arena_pb2.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/google/protobuf/unittest_no_generic_services_pb2.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/google/protobuf/unittest_pb2.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/google/protobuf/unittest_proto3_arena_pb2.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/google/protobuf/util/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/google/protobuf/util/json_format_proto3_pb2.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/google/protobuf/wrappers_pb2.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/itsdangerous.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/jinja2/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/jinja2/_compat.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/jinja2/_stringdefs.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/jinja2/bccache.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/jinja2/compiler.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/jinja2/constants.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/jinja2/debug.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/jinja2/defaults.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/jinja2/environment.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/jinja2/exceptions.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/jinja2/ext.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/jinja2/filters.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/jinja2/lexer.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/jinja2/loaders.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/jinja2/meta.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/jinja2/nodes.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/jinja2/optimizer.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/jinja2/parser.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/jinja2/runtime.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/jinja2/sandbox.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/jinja2/tests.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/jinja2/utils.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/jinja2/visitor.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/markupsafe/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/markupsafe/_compat.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/markupsafe/_constants.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/markupsafe/_native.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/markupsafe/_speedups.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/maxminddb/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/maxminddb/compat.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/maxminddb/const.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/maxminddb/decoder.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/maxminddb/errors.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/maxminddb/extension.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/maxminddb/reader.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/mock.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/mypy_extensions.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/pycurl.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/pymysql/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/pymysql/charset.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/pymysql/connections.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/pymysql/constants/CLIENT.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/pymysql/constants/COMMAND.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/pymysql/constants/ER.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/pymysql/constants/FIELD_TYPE.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/pymysql/constants/FLAG.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/pymysql/constants/SERVER_STATUS.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/pymysql/constants/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/pymysql/converters.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/pymysql/cursors.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/pymysql/err.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/pymysql/times.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/pymysql/util.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/pynamodb/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/pynamodb/attributes.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/pynamodb/connection/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/pynamodb/connection/base.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/pynamodb/connection/table.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/pynamodb/connection/util.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/pynamodb/constants.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/pynamodb/exceptions.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/pynamodb/indexes.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/pynamodb/models.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/pynamodb/settings.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/pynamodb/throttle.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/pynamodb/types.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/pyre_extensions.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/pytz/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/redis/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/redis/client.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/redis/connection.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/redis/exceptions.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/redis/utils.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/requests/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/requests/adapters.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/requests/api.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/requests/auth.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/requests/compat.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/requests/cookies.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/requests/exceptions.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/requests/hooks.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/requests/models.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/requests/packages/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/requests/packages/urllib3/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/requests/packages/urllib3/_collections.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/requests/packages/urllib3/connection.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/requests/packages/urllib3/connectionpool.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/requests/packages/urllib3/contrib/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/requests/packages/urllib3/exceptions.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/requests/packages/urllib3/fields.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/requests/packages/urllib3/filepost.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/requests/packages/urllib3/packages/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/requests/packages/urllib3/packages/ssl_match_hostname/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/requests/packages/urllib3/packages/ssl_match_hostname/_implementation.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/requests/packages/urllib3/poolmanager.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/requests/packages/urllib3/request.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/requests/packages/urllib3/response.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/requests/packages/urllib3/util/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/requests/packages/urllib3/util/connection.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/requests/packages/urllib3/util/request.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/requests/packages/urllib3/util/response.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/requests/packages/urllib3/util/retry.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/requests/packages/urllib3/util/ssl_.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/requests/packages/urllib3/util/timeout.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/requests/packages/urllib3/util/url.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/requests/sessions.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/requests/status_codes.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/requests/structures.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/requests/utils.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/simplejson/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/simplejson/decoder.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/simplejson/encoder.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/simplejson/scanner.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/singledispatch.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/tabulate.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/termcolor.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/toml.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/typing_extensions.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/ujson.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/werkzeug/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/werkzeug/_compat.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/werkzeug/_internal.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/werkzeug/_reloader.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/werkzeug/contrib/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/werkzeug/contrib/atom.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/werkzeug/contrib/cache.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/werkzeug/contrib/fixers.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/werkzeug/contrib/iterio.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/werkzeug/contrib/jsrouting.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/werkzeug/contrib/limiter.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/werkzeug/contrib/lint.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/werkzeug/contrib/profiler.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/werkzeug/contrib/securecookie.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/werkzeug/contrib/sessions.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/werkzeug/contrib/testtools.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/werkzeug/contrib/wrappers.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/werkzeug/datastructures.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/werkzeug/debug/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/werkzeug/debug/console.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/werkzeug/debug/repr.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/werkzeug/debug/tbtools.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/werkzeug/exceptions.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/werkzeug/filesystem.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/werkzeug/formparser.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/werkzeug/http.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/werkzeug/local.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/werkzeug/middleware/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/werkzeug/middleware/dispatcher.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/werkzeug/middleware/http_proxy.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/werkzeug/middleware/lint.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/werkzeug/middleware/profiler.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/werkzeug/middleware/proxy_fix.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/werkzeug/middleware/shared_data.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/werkzeug/posixemulation.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/werkzeug/routing.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/werkzeug/script.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/werkzeug/security.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/werkzeug/serving.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/werkzeug/test.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/werkzeug/testapp.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/werkzeug/urls.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/werkzeug/useragents.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/werkzeug/utils.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/werkzeug/wrappers.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/werkzeug/wsgi.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/yaml/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/yaml/composer.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/yaml/constructor.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/yaml/cyaml.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/yaml/dumper.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/yaml/emitter.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/yaml/error.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/yaml/events.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/yaml/loader.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/yaml/nodes.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/yaml/parser.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/yaml/reader.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/yaml/representer.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/yaml/resolver.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/yaml/scanner.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/yaml/serializer.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/2and3/yaml/tokens.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/3/contextvars.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/3/dataclasses.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/3/docutils/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/3/docutils/examples.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/3/docutils/nodes.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/3/docutils/parsers/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/3/docutils/parsers/rst/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/3/docutils/parsers/rst/nodes.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/3/docutils/parsers/rst/roles.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/3/docutils/parsers/rst/states.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/3/jwt/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/3/jwt/algorithms.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/3/jwt/contrib/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/3/jwt/contrib/algorithms/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/3/jwt/contrib/algorithms/py_ecdsa.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/3/jwt/contrib/algorithms/pycrypto.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/3/orjson.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/3/pkg_resources/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/3/pkg_resources/py31compat.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/3/six/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/3/six/moves/BaseHTTPServer.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/3/six/moves/CGIHTTPServer.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/3/six/moves/SimpleHTTPServer.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/3/six/moves/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/3/six/moves/_dummy_thread.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/3/six/moves/_thread.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/3/six/moves/builtins.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/3/six/moves/cPickle.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/3/six/moves/configparser.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/3/six/moves/email_mime_base.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/3/six/moves/email_mime_multipart.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/3/six/moves/email_mime_nonmultipart.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/3/six/moves/email_mime_text.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/3/six/moves/html_entities.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/3/six/moves/html_parser.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/3/six/moves/http_client.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/3/six/moves/http_cookiejar.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/3/six/moves/http_cookies.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/3/six/moves/queue.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/3/six/moves/reprlib.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/3/six/moves/socketserver.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/3/six/moves/tkinter.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/3/six/moves/tkinter_commondialog.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/3/six/moves/tkinter_constants.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/3/six/moves/tkinter_dialog.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/3/six/moves/tkinter_filedialog.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/3/six/moves/tkinter_tkfiledialog.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/3/six/moves/tkinter_ttk.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/3/six/moves/urllib/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/3/six/moves/urllib/error.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/3/six/moves/urllib/parse.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/3/six/moves/urllib/request.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/3/six/moves/urllib/response.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/3/six/moves/urllib/robotparser.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/3/six/moves/urllib_error.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/3/six/moves/urllib_parse.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/3/six/moves/urllib_request.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/3/six/moves/urllib_response.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/3/six/moves/urllib_robotparser.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/3/typed_ast/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/3/typed_ast/ast27.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/3/typed_ast/ast3.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/third_party/typeshed/third_party/3/typed_ast/conversions.pyi create mode 100644 .venv/lib/python3.8/site-packages/jedi/utils.py create mode 100644 .venv/lib/python3.8/site-packages/jupyter.py create mode 100644 .venv/lib/python3.8/site-packages/jupyter_client-6.1.7.dist-info/COPYING.md create mode 100644 .venv/lib/python3.8/site-packages/jupyter_client-6.1.7.dist-info/INSTALLER create mode 100644 .venv/lib/python3.8/site-packages/jupyter_client-6.1.7.dist-info/METADATA create mode 100644 .venv/lib/python3.8/site-packages/jupyter_client-6.1.7.dist-info/RECORD create mode 100644 .venv/lib/python3.8/site-packages/jupyter_client-6.1.7.dist-info/WHEEL create mode 100644 .venv/lib/python3.8/site-packages/jupyter_client-6.1.7.dist-info/entry_points.txt create mode 100644 .venv/lib/python3.8/site-packages/jupyter_client-6.1.7.dist-info/top_level.txt create mode 100644 .venv/lib/python3.8/site-packages/jupyter_client/__init__.py create mode 100644 .venv/lib/python3.8/site-packages/jupyter_client/__pycache__/__init__.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/jupyter_client/__pycache__/_version.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/jupyter_client/__pycache__/adapter.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/jupyter_client/__pycache__/channels.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/jupyter_client/__pycache__/channelsabc.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/jupyter_client/__pycache__/client.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/jupyter_client/__pycache__/clientabc.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/jupyter_client/__pycache__/connect.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/jupyter_client/__pycache__/consoleapp.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/jupyter_client/__pycache__/jsonutil.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/jupyter_client/__pycache__/kernelapp.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/jupyter_client/__pycache__/kernelspec.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/jupyter_client/__pycache__/kernelspecapp.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/jupyter_client/__pycache__/launcher.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/jupyter_client/__pycache__/localinterfaces.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/jupyter_client/__pycache__/manager.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/jupyter_client/__pycache__/managerabc.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/jupyter_client/__pycache__/multikernelmanager.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/jupyter_client/__pycache__/restarter.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/jupyter_client/__pycache__/runapp.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/jupyter_client/__pycache__/session.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/jupyter_client/__pycache__/threaded.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/jupyter_client/__pycache__/win_interrupt.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/jupyter_client/_version.py create mode 100644 .venv/lib/python3.8/site-packages/jupyter_client/adapter.py create mode 100644 .venv/lib/python3.8/site-packages/jupyter_client/asynchronous/__init__.py create mode 100644 .venv/lib/python3.8/site-packages/jupyter_client/asynchronous/__pycache__/__init__.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/jupyter_client/asynchronous/__pycache__/channels.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/jupyter_client/asynchronous/__pycache__/client.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/jupyter_client/asynchronous/channels.py create mode 100644 .venv/lib/python3.8/site-packages/jupyter_client/asynchronous/client.py create mode 100644 .venv/lib/python3.8/site-packages/jupyter_client/blocking/__init__.py create mode 100644 .venv/lib/python3.8/site-packages/jupyter_client/blocking/__pycache__/__init__.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/jupyter_client/blocking/__pycache__/channels.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/jupyter_client/blocking/__pycache__/client.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/jupyter_client/blocking/channels.py create mode 100644 .venv/lib/python3.8/site-packages/jupyter_client/blocking/client.py create mode 100644 .venv/lib/python3.8/site-packages/jupyter_client/channels.py create mode 100644 .venv/lib/python3.8/site-packages/jupyter_client/channelsabc.py create mode 100644 .venv/lib/python3.8/site-packages/jupyter_client/client.py create mode 100644 .venv/lib/python3.8/site-packages/jupyter_client/clientabc.py create mode 100644 .venv/lib/python3.8/site-packages/jupyter_client/connect.py create mode 100644 .venv/lib/python3.8/site-packages/jupyter_client/consoleapp.py create mode 100644 .venv/lib/python3.8/site-packages/jupyter_client/ioloop/__init__.py create mode 100644 .venv/lib/python3.8/site-packages/jupyter_client/ioloop/__pycache__/__init__.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/jupyter_client/ioloop/__pycache__/manager.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/jupyter_client/ioloop/__pycache__/restarter.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/jupyter_client/ioloop/manager.py create mode 100644 .venv/lib/python3.8/site-packages/jupyter_client/ioloop/restarter.py create mode 100644 .venv/lib/python3.8/site-packages/jupyter_client/jsonutil.py create mode 100644 .venv/lib/python3.8/site-packages/jupyter_client/kernelapp.py create mode 100644 .venv/lib/python3.8/site-packages/jupyter_client/kernelspec.py create mode 100644 .venv/lib/python3.8/site-packages/jupyter_client/kernelspecapp.py create mode 100644 .venv/lib/python3.8/site-packages/jupyter_client/launcher.py create mode 100644 .venv/lib/python3.8/site-packages/jupyter_client/localinterfaces.py create mode 100644 .venv/lib/python3.8/site-packages/jupyter_client/manager.py create mode 100644 .venv/lib/python3.8/site-packages/jupyter_client/managerabc.py create mode 100644 .venv/lib/python3.8/site-packages/jupyter_client/multikernelmanager.py create mode 100644 .venv/lib/python3.8/site-packages/jupyter_client/restarter.py create mode 100644 .venv/lib/python3.8/site-packages/jupyter_client/runapp.py create mode 100644 .venv/lib/python3.8/site-packages/jupyter_client/session.py create mode 100644 .venv/lib/python3.8/site-packages/jupyter_client/ssh/__init__.py create mode 100644 .venv/lib/python3.8/site-packages/jupyter_client/ssh/__pycache__/__init__.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/jupyter_client/ssh/__pycache__/forward.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/jupyter_client/ssh/__pycache__/tunnel.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/jupyter_client/ssh/forward.py create mode 100644 .venv/lib/python3.8/site-packages/jupyter_client/ssh/tunnel.py create mode 100644 .venv/lib/python3.8/site-packages/jupyter_client/tests/__init__.py create mode 100644 .venv/lib/python3.8/site-packages/jupyter_client/tests/__pycache__/__init__.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/jupyter_client/tests/__pycache__/signalkernel.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/jupyter_client/tests/__pycache__/test_adapter.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/jupyter_client/tests/__pycache__/test_client.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/jupyter_client/tests/__pycache__/test_connect.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/jupyter_client/tests/__pycache__/test_jsonutil.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/jupyter_client/tests/__pycache__/test_kernelapp.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/jupyter_client/tests/__pycache__/test_kernelmanager.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/jupyter_client/tests/__pycache__/test_kernelspec.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/jupyter_client/tests/__pycache__/test_localinterfaces.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/jupyter_client/tests/__pycache__/test_manager.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/jupyter_client/tests/__pycache__/test_multikernelmanager.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/jupyter_client/tests/__pycache__/test_public_api.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/jupyter_client/tests/__pycache__/test_session.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/jupyter_client/tests/__pycache__/test_ssh.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/jupyter_client/tests/__pycache__/utils.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/jupyter_client/tests/signalkernel.py create mode 100644 .venv/lib/python3.8/site-packages/jupyter_client/tests/test_adapter.py create mode 100644 .venv/lib/python3.8/site-packages/jupyter_client/tests/test_client.py create mode 100644 .venv/lib/python3.8/site-packages/jupyter_client/tests/test_connect.py create mode 100644 .venv/lib/python3.8/site-packages/jupyter_client/tests/test_jsonutil.py create mode 100644 .venv/lib/python3.8/site-packages/jupyter_client/tests/test_kernelapp.py create mode 100644 .venv/lib/python3.8/site-packages/jupyter_client/tests/test_kernelmanager.py create mode 100644 .venv/lib/python3.8/site-packages/jupyter_client/tests/test_kernelspec.py create mode 100644 .venv/lib/python3.8/site-packages/jupyter_client/tests/test_localinterfaces.py create mode 100644 .venv/lib/python3.8/site-packages/jupyter_client/tests/test_manager.py create mode 100644 .venv/lib/python3.8/site-packages/jupyter_client/tests/test_multikernelmanager.py create mode 100644 .venv/lib/python3.8/site-packages/jupyter_client/tests/test_public_api.py create mode 100644 .venv/lib/python3.8/site-packages/jupyter_client/tests/test_session.py create mode 100644 .venv/lib/python3.8/site-packages/jupyter_client/tests/test_ssh.py create mode 100644 .venv/lib/python3.8/site-packages/jupyter_client/tests/utils.py create mode 100644 .venv/lib/python3.8/site-packages/jupyter_client/threaded.py create mode 100644 .venv/lib/python3.8/site-packages/jupyter_client/win_interrupt.py create mode 100644 .venv/lib/python3.8/site-packages/jupyter_core-4.7.0.dist-info/COPYING.md create mode 100644 .venv/lib/python3.8/site-packages/jupyter_core-4.7.0.dist-info/INSTALLER create mode 100644 .venv/lib/python3.8/site-packages/jupyter_core-4.7.0.dist-info/METADATA create mode 100644 .venv/lib/python3.8/site-packages/jupyter_core-4.7.0.dist-info/RECORD create mode 100644 .venv/lib/python3.8/site-packages/jupyter_core-4.7.0.dist-info/WHEEL create mode 100644 .venv/lib/python3.8/site-packages/jupyter_core-4.7.0.dist-info/entry_points.txt create mode 100644 .venv/lib/python3.8/site-packages/jupyter_core-4.7.0.dist-info/top_level.txt create mode 100644 .venv/lib/python3.8/site-packages/jupyter_core/__init__.py create mode 100644 .venv/lib/python3.8/site-packages/jupyter_core/__main__.py create mode 100644 .venv/lib/python3.8/site-packages/jupyter_core/__pycache__/__init__.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/jupyter_core/__pycache__/__main__.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/jupyter_core/__pycache__/application.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/jupyter_core/__pycache__/command.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/jupyter_core/__pycache__/migrate.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/jupyter_core/__pycache__/paths.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/jupyter_core/__pycache__/troubleshoot.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/jupyter_core/__pycache__/version.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/jupyter_core/application.py create mode 100644 .venv/lib/python3.8/site-packages/jupyter_core/command.py create mode 100644 .venv/lib/python3.8/site-packages/jupyter_core/migrate.py create mode 100644 .venv/lib/python3.8/site-packages/jupyter_core/paths.py create mode 100644 .venv/lib/python3.8/site-packages/jupyter_core/tests/__init__.py create mode 100644 .venv/lib/python3.8/site-packages/jupyter_core/tests/__pycache__/__init__.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/jupyter_core/tests/__pycache__/mocking.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/jupyter_core/tests/__pycache__/test_application.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/jupyter_core/tests/__pycache__/test_command.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/jupyter_core/tests/__pycache__/test_migrate.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/jupyter_core/tests/__pycache__/test_paths.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/jupyter_core/tests/dotipython/nbextensions/myext.js create mode 100644 .venv/lib/python3.8/site-packages/jupyter_core/tests/dotipython/profile_default/__pycache__/ipython_config.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/jupyter_core/tests/dotipython/profile_default/__pycache__/ipython_console_config.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/jupyter_core/tests/dotipython/profile_default/__pycache__/ipython_kernel_config.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/jupyter_core/tests/dotipython/profile_default/__pycache__/ipython_nbconvert_config.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/jupyter_core/tests/dotipython/profile_default/__pycache__/ipython_notebook_config.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/jupyter_core/tests/dotipython/profile_default/ipython_config.py create mode 100644 .venv/lib/python3.8/site-packages/jupyter_core/tests/dotipython/profile_default/ipython_console_config.py create mode 100644 .venv/lib/python3.8/site-packages/jupyter_core/tests/dotipython/profile_default/ipython_kernel_config.py create mode 100644 .venv/lib/python3.8/site-packages/jupyter_core/tests/dotipython/profile_default/ipython_nbconvert_config.py create mode 100644 .venv/lib/python3.8/site-packages/jupyter_core/tests/dotipython/profile_default/ipython_notebook_config.py create mode 100644 .venv/lib/python3.8/site-packages/jupyter_core/tests/dotipython/profile_default/static/custom/custom.css create mode 100644 .venv/lib/python3.8/site-packages/jupyter_core/tests/dotipython/profile_default/static/custom/custom.js create mode 100644 .venv/lib/python3.8/site-packages/jupyter_core/tests/dotipython_empty/profile_default/__pycache__/ipython_config.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/jupyter_core/tests/dotipython_empty/profile_default/__pycache__/ipython_console_config.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/jupyter_core/tests/dotipython_empty/profile_default/__pycache__/ipython_kernel_config.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/jupyter_core/tests/dotipython_empty/profile_default/__pycache__/ipython_nbconvert_config.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/jupyter_core/tests/dotipython_empty/profile_default/__pycache__/ipython_notebook_config.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/jupyter_core/tests/dotipython_empty/profile_default/ipython_config.py create mode 100644 .venv/lib/python3.8/site-packages/jupyter_core/tests/dotipython_empty/profile_default/ipython_console_config.py create mode 100644 .venv/lib/python3.8/site-packages/jupyter_core/tests/dotipython_empty/profile_default/ipython_kernel_config.py create mode 100644 .venv/lib/python3.8/site-packages/jupyter_core/tests/dotipython_empty/profile_default/ipython_nbconvert_config.py create mode 100644 .venv/lib/python3.8/site-packages/jupyter_core/tests/dotipython_empty/profile_default/ipython_notebook_config.py create mode 100644 .venv/lib/python3.8/site-packages/jupyter_core/tests/dotipython_empty/profile_default/static/custom/custom.css create mode 100644 .venv/lib/python3.8/site-packages/jupyter_core/tests/dotipython_empty/profile_default/static/custom/custom.js create mode 100644 .venv/lib/python3.8/site-packages/jupyter_core/tests/mocking.py create mode 100644 .venv/lib/python3.8/site-packages/jupyter_core/tests/test_application.py create mode 100644 .venv/lib/python3.8/site-packages/jupyter_core/tests/test_command.py create mode 100644 .venv/lib/python3.8/site-packages/jupyter_core/tests/test_migrate.py create mode 100644 .venv/lib/python3.8/site-packages/jupyter_core/tests/test_paths.py create mode 100644 .venv/lib/python3.8/site-packages/jupyter_core/troubleshoot.py create mode 100644 .venv/lib/python3.8/site-packages/jupyter_core/utils/__init__.py create mode 100644 .venv/lib/python3.8/site-packages/jupyter_core/utils/__pycache__/__init__.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/jupyter_core/version.py create mode 100644 .venv/lib/python3.8/site-packages/lazy_object_proxy-1.4.3.dist-info/INSTALLER create mode 100644 .venv/lib/python3.8/site-packages/lazy_object_proxy-1.4.3.dist-info/METADATA create mode 100644 .venv/lib/python3.8/site-packages/lazy_object_proxy-1.4.3.dist-info/RECORD create mode 100644 .venv/lib/python3.8/site-packages/lazy_object_proxy-1.4.3.dist-info/WHEEL create mode 100644 .venv/lib/python3.8/site-packages/lazy_object_proxy-1.4.3.dist-info/top_level.txt create mode 100644 .venv/lib/python3.8/site-packages/lazy_object_proxy/__init__.py create mode 100644 .venv/lib/python3.8/site-packages/lazy_object_proxy/__pycache__/__init__.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/lazy_object_proxy/__pycache__/_version.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/lazy_object_proxy/__pycache__/compat.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/lazy_object_proxy/__pycache__/simple.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/lazy_object_proxy/__pycache__/slots.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/lazy_object_proxy/__pycache__/utils.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/lazy_object_proxy/_version.py create mode 100755 .venv/lib/python3.8/site-packages/lazy_object_proxy/cext.cpython-38-x86_64-linux-gnu.so create mode 100644 .venv/lib/python3.8/site-packages/lazy_object_proxy/compat.py create mode 100644 .venv/lib/python3.8/site-packages/lazy_object_proxy/simple.py create mode 100644 .venv/lib/python3.8/site-packages/lazy_object_proxy/slots.py create mode 100644 .venv/lib/python3.8/site-packages/lazy_object_proxy/utils.py create mode 100644 .venv/lib/python3.8/site-packages/mccabe-0.6.1.dist-info/DESCRIPTION.rst create mode 100644 .venv/lib/python3.8/site-packages/mccabe-0.6.1.dist-info/INSTALLER create mode 100644 .venv/lib/python3.8/site-packages/mccabe-0.6.1.dist-info/METADATA create mode 100644 .venv/lib/python3.8/site-packages/mccabe-0.6.1.dist-info/RECORD create mode 100644 .venv/lib/python3.8/site-packages/mccabe-0.6.1.dist-info/WHEEL create mode 100644 .venv/lib/python3.8/site-packages/mccabe-0.6.1.dist-info/entry_points.txt create mode 100644 .venv/lib/python3.8/site-packages/mccabe-0.6.1.dist-info/metadata.json create mode 100644 .venv/lib/python3.8/site-packages/mccabe-0.6.1.dist-info/top_level.txt create mode 100644 .venv/lib/python3.8/site-packages/mccabe.py create mode 100644 .venv/lib/python3.8/site-packages/parso-0.7.1.dist-info/AUTHORS.txt create mode 100644 .venv/lib/python3.8/site-packages/parso-0.7.1.dist-info/INSTALLER create mode 100644 .venv/lib/python3.8/site-packages/parso-0.7.1.dist-info/LICENSE.txt create mode 100644 .venv/lib/python3.8/site-packages/parso-0.7.1.dist-info/METADATA create mode 100644 .venv/lib/python3.8/site-packages/parso-0.7.1.dist-info/RECORD create mode 100644 .venv/lib/python3.8/site-packages/parso-0.7.1.dist-info/WHEEL create mode 100644 .venv/lib/python3.8/site-packages/parso-0.7.1.dist-info/top_level.txt create mode 100644 .venv/lib/python3.8/site-packages/parso/__init__.py create mode 100644 .venv/lib/python3.8/site-packages/parso/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/parso/__pycache__/__init__.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/parso/__pycache__/_compatibility.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/parso/__pycache__/cache.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/parso/__pycache__/file_io.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/parso/__pycache__/grammar.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/parso/__pycache__/normalizer.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/parso/__pycache__/parser.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/parso/__pycache__/tree.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/parso/__pycache__/utils.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/parso/_compatibility.py create mode 100644 .venv/lib/python3.8/site-packages/parso/cache.py create mode 100644 .venv/lib/python3.8/site-packages/parso/file_io.py create mode 100644 .venv/lib/python3.8/site-packages/parso/grammar.py create mode 100644 .venv/lib/python3.8/site-packages/parso/grammar.pyi create mode 100644 .venv/lib/python3.8/site-packages/parso/normalizer.py create mode 100644 .venv/lib/python3.8/site-packages/parso/parser.py create mode 100644 .venv/lib/python3.8/site-packages/parso/pgen2/__init__.py create mode 100644 .venv/lib/python3.8/site-packages/parso/pgen2/__init__.pyi create mode 100644 .venv/lib/python3.8/site-packages/parso/pgen2/__pycache__/__init__.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/parso/pgen2/__pycache__/generator.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/parso/pgen2/__pycache__/grammar_parser.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/parso/pgen2/generator.py create mode 100644 .venv/lib/python3.8/site-packages/parso/pgen2/generator.pyi create mode 100644 .venv/lib/python3.8/site-packages/parso/pgen2/grammar_parser.py create mode 100644 .venv/lib/python3.8/site-packages/parso/pgen2/grammar_parser.pyi create mode 100644 .venv/lib/python3.8/site-packages/parso/py.typed create mode 100644 .venv/lib/python3.8/site-packages/parso/python/__init__.py create mode 100644 .venv/lib/python3.8/site-packages/parso/python/__pycache__/__init__.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/parso/python/__pycache__/diff.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/parso/python/__pycache__/errors.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/parso/python/__pycache__/parser.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/parso/python/__pycache__/pep8.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/parso/python/__pycache__/prefix.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/parso/python/__pycache__/token.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/parso/python/__pycache__/tokenize.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/parso/python/__pycache__/tree.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/parso/python/diff.py create mode 100644 .venv/lib/python3.8/site-packages/parso/python/errors.py create mode 100644 .venv/lib/python3.8/site-packages/parso/python/grammar27.txt create mode 100644 .venv/lib/python3.8/site-packages/parso/python/grammar310.txt create mode 100644 .venv/lib/python3.8/site-packages/parso/python/grammar33.txt create mode 100644 .venv/lib/python3.8/site-packages/parso/python/grammar34.txt create mode 100644 .venv/lib/python3.8/site-packages/parso/python/grammar35.txt create mode 100644 .venv/lib/python3.8/site-packages/parso/python/grammar36.txt create mode 100644 .venv/lib/python3.8/site-packages/parso/python/grammar37.txt create mode 100644 .venv/lib/python3.8/site-packages/parso/python/grammar38.txt create mode 100644 .venv/lib/python3.8/site-packages/parso/python/grammar39.txt create mode 100644 .venv/lib/python3.8/site-packages/parso/python/parser.py create mode 100644 .venv/lib/python3.8/site-packages/parso/python/pep8.py create mode 100644 .venv/lib/python3.8/site-packages/parso/python/prefix.py create mode 100644 .venv/lib/python3.8/site-packages/parso/python/token.py create mode 100644 .venv/lib/python3.8/site-packages/parso/python/token.pyi create mode 100644 .venv/lib/python3.8/site-packages/parso/python/tokenize.py create mode 100644 .venv/lib/python3.8/site-packages/parso/python/tokenize.pyi create mode 100644 .venv/lib/python3.8/site-packages/parso/python/tree.py create mode 100644 .venv/lib/python3.8/site-packages/parso/tree.py create mode 100644 .venv/lib/python3.8/site-packages/parso/utils.py create mode 100644 .venv/lib/python3.8/site-packages/parso/utils.pyi create mode 100644 .venv/lib/python3.8/site-packages/pexpect-4.8.0.dist-info/INSTALLER create mode 100644 .venv/lib/python3.8/site-packages/pexpect-4.8.0.dist-info/LICENSE create mode 100644 .venv/lib/python3.8/site-packages/pexpect-4.8.0.dist-info/METADATA create mode 100644 .venv/lib/python3.8/site-packages/pexpect-4.8.0.dist-info/RECORD create mode 100644 .venv/lib/python3.8/site-packages/pexpect-4.8.0.dist-info/WHEEL create mode 100644 .venv/lib/python3.8/site-packages/pexpect-4.8.0.dist-info/top_level.txt create mode 100644 .venv/lib/python3.8/site-packages/pexpect/ANSI.py create mode 100644 .venv/lib/python3.8/site-packages/pexpect/FSM.py create mode 100644 .venv/lib/python3.8/site-packages/pexpect/__init__.py create mode 100644 .venv/lib/python3.8/site-packages/pexpect/__pycache__/ANSI.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pexpect/__pycache__/FSM.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pexpect/__pycache__/__init__.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pexpect/__pycache__/_async.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pexpect/__pycache__/exceptions.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pexpect/__pycache__/expect.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pexpect/__pycache__/fdpexpect.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pexpect/__pycache__/popen_spawn.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pexpect/__pycache__/pty_spawn.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pexpect/__pycache__/pxssh.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pexpect/__pycache__/replwrap.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pexpect/__pycache__/run.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pexpect/__pycache__/screen.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pexpect/__pycache__/spawnbase.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pexpect/__pycache__/utils.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pexpect/_async.py create mode 100644 .venv/lib/python3.8/site-packages/pexpect/bashrc.sh create mode 100644 .venv/lib/python3.8/site-packages/pexpect/exceptions.py create mode 100644 .venv/lib/python3.8/site-packages/pexpect/expect.py create mode 100644 .venv/lib/python3.8/site-packages/pexpect/fdpexpect.py create mode 100644 .venv/lib/python3.8/site-packages/pexpect/popen_spawn.py create mode 100644 .venv/lib/python3.8/site-packages/pexpect/pty_spawn.py create mode 100644 .venv/lib/python3.8/site-packages/pexpect/pxssh.py create mode 100644 .venv/lib/python3.8/site-packages/pexpect/replwrap.py create mode 100644 .venv/lib/python3.8/site-packages/pexpect/run.py create mode 100644 .venv/lib/python3.8/site-packages/pexpect/screen.py create mode 100644 .venv/lib/python3.8/site-packages/pexpect/spawnbase.py create mode 100644 .venv/lib/python3.8/site-packages/pexpect/utils.py create mode 100644 .venv/lib/python3.8/site-packages/pickleshare-0.7.5.dist-info/DESCRIPTION.rst create mode 100644 .venv/lib/python3.8/site-packages/pickleshare-0.7.5.dist-info/INSTALLER create mode 100644 .venv/lib/python3.8/site-packages/pickleshare-0.7.5.dist-info/METADATA create mode 100644 .venv/lib/python3.8/site-packages/pickleshare-0.7.5.dist-info/RECORD create mode 100644 .venv/lib/python3.8/site-packages/pickleshare-0.7.5.dist-info/WHEEL create mode 100644 .venv/lib/python3.8/site-packages/pickleshare-0.7.5.dist-info/metadata.json create mode 100644 .venv/lib/python3.8/site-packages/pickleshare-0.7.5.dist-info/top_level.txt create mode 100644 .venv/lib/python3.8/site-packages/pickleshare.py create mode 100644 .venv/lib/python3.8/site-packages/pip-20.1.1.dist-info/INSTALLER create mode 100644 .venv/lib/python3.8/site-packages/pip-20.1.1.dist-info/LICENSE.txt create mode 100644 .venv/lib/python3.8/site-packages/pip-20.1.1.dist-info/METADATA create mode 100644 .venv/lib/python3.8/site-packages/pip-20.1.1.dist-info/RECORD create mode 100644 .venv/lib/python3.8/site-packages/pip-20.1.1.dist-info/WHEEL create mode 100644 .venv/lib/python3.8/site-packages/pip-20.1.1.dist-info/entry_points.txt create mode 100644 .venv/lib/python3.8/site-packages/pip-20.1.1.dist-info/top_level.txt create mode 100644 .venv/lib/python3.8/site-packages/pip/__init__.py create mode 100644 .venv/lib/python3.8/site-packages/pip/__main__.py create mode 100644 .venv/lib/python3.8/site-packages/pip/__pycache__/__init__.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pip/__pycache__/__main__.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/__init__.py create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/__pycache__/__init__.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/__pycache__/build_env.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/__pycache__/cache.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/__pycache__/configuration.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/__pycache__/exceptions.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/__pycache__/locations.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/__pycache__/main.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/__pycache__/pyproject.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/__pycache__/self_outdated_check.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/__pycache__/wheel_builder.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/build_env.py create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/cache.py create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/cli/__init__.py create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/cli/__pycache__/__init__.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/cli/__pycache__/autocompletion.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/cli/__pycache__/base_command.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/cli/__pycache__/cmdoptions.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/cli/__pycache__/command_context.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/cli/__pycache__/main.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/cli/__pycache__/main_parser.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/cli/__pycache__/parser.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/cli/__pycache__/progress_bars.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/cli/__pycache__/req_command.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/cli/__pycache__/spinners.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/cli/__pycache__/status_codes.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/cli/autocompletion.py create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/cli/base_command.py create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/cli/cmdoptions.py create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/cli/command_context.py create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/cli/main.py create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/cli/main_parser.py create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/cli/parser.py create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/cli/progress_bars.py create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/cli/req_command.py create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/cli/spinners.py create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/cli/status_codes.py create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/commands/__init__.py create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/commands/__pycache__/__init__.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/commands/__pycache__/cache.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/commands/__pycache__/check.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/commands/__pycache__/completion.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/commands/__pycache__/configuration.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/commands/__pycache__/debug.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/commands/__pycache__/download.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/commands/__pycache__/freeze.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/commands/__pycache__/hash.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/commands/__pycache__/help.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/commands/__pycache__/install.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/commands/__pycache__/list.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/commands/__pycache__/search.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/commands/__pycache__/show.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/commands/__pycache__/uninstall.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/commands/__pycache__/wheel.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/commands/cache.py create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/commands/check.py create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/commands/completion.py create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/commands/configuration.py create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/commands/debug.py create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/commands/download.py create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/commands/freeze.py create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/commands/hash.py create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/commands/help.py create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/commands/install.py create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/commands/list.py create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/commands/search.py create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/commands/show.py create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/commands/uninstall.py create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/commands/wheel.py create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/configuration.py create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/distributions/__init__.py create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/distributions/__pycache__/__init__.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/distributions/__pycache__/base.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/distributions/__pycache__/installed.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/distributions/__pycache__/sdist.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/distributions/__pycache__/wheel.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/distributions/base.py create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/distributions/installed.py create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/distributions/sdist.py create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/distributions/wheel.py create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/exceptions.py create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/index/__init__.py create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/index/__pycache__/__init__.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/index/__pycache__/collector.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/index/__pycache__/package_finder.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/index/collector.py create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/index/package_finder.py create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/locations.py create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/main.py create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/models/__init__.py create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/models/__pycache__/__init__.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/models/__pycache__/candidate.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/models/__pycache__/direct_url.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/models/__pycache__/format_control.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/models/__pycache__/index.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/models/__pycache__/link.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/models/__pycache__/scheme.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/models/__pycache__/search_scope.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/models/__pycache__/selection_prefs.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/models/__pycache__/target_python.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/models/__pycache__/wheel.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/models/candidate.py create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/models/direct_url.py create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/models/format_control.py create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/models/index.py create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/models/link.py create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/models/scheme.py create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/models/search_scope.py create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/models/selection_prefs.py create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/models/target_python.py create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/models/wheel.py create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/network/__init__.py create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/network/__pycache__/__init__.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/network/__pycache__/auth.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/network/__pycache__/cache.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/network/__pycache__/download.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/network/__pycache__/session.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/network/__pycache__/utils.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/network/__pycache__/xmlrpc.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/network/auth.py create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/network/cache.py create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/network/download.py create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/network/session.py create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/network/utils.py create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/network/xmlrpc.py create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/operations/__init__.py create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/operations/__pycache__/__init__.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/operations/__pycache__/check.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/operations/__pycache__/freeze.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/operations/__pycache__/prepare.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/operations/build/__init__.py create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/operations/build/__pycache__/__init__.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/operations/build/__pycache__/metadata.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/operations/build/__pycache__/metadata_legacy.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/operations/build/__pycache__/wheel.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/operations/build/__pycache__/wheel_legacy.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/operations/build/metadata.py create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/operations/build/metadata_legacy.py create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/operations/build/wheel.py create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/operations/build/wheel_legacy.py create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/operations/check.py create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/operations/freeze.py create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/operations/install/__init__.py create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/operations/install/__pycache__/__init__.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/operations/install/__pycache__/editable_legacy.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/operations/install/__pycache__/legacy.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/operations/install/__pycache__/wheel.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/operations/install/editable_legacy.py create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/operations/install/legacy.py create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/operations/install/wheel.py create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/operations/prepare.py create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/pyproject.py create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/req/__init__.py create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/req/__pycache__/__init__.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/req/__pycache__/constructors.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/req/__pycache__/req_file.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/req/__pycache__/req_install.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/req/__pycache__/req_set.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/req/__pycache__/req_tracker.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/req/__pycache__/req_uninstall.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/req/constructors.py create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/req/req_file.py create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/req/req_install.py create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/req/req_set.py create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/req/req_tracker.py create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/req/req_uninstall.py create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/resolution/__init__.py create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/resolution/__pycache__/__init__.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/resolution/__pycache__/base.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/resolution/base.py create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/resolution/legacy/__init__.py create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/resolution/legacy/__pycache__/__init__.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/resolution/legacy/__pycache__/resolver.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/resolution/legacy/resolver.py create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/resolution/resolvelib/__init__.py create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/resolution/resolvelib/__pycache__/__init__.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/resolution/resolvelib/__pycache__/base.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/resolution/resolvelib/__pycache__/candidates.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/resolution/resolvelib/__pycache__/factory.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/resolution/resolvelib/__pycache__/provider.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/resolution/resolvelib/__pycache__/requirements.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/resolution/resolvelib/__pycache__/resolver.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/resolution/resolvelib/base.py create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/resolution/resolvelib/candidates.py create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/resolution/resolvelib/factory.py create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/resolution/resolvelib/provider.py create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/resolution/resolvelib/requirements.py create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/resolution/resolvelib/resolver.py create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/self_outdated_check.py create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/utils/__init__.py create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/utils/__pycache__/__init__.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/utils/__pycache__/appdirs.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/utils/__pycache__/compat.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/utils/__pycache__/compatibility_tags.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/utils/__pycache__/deprecation.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/utils/__pycache__/direct_url_helpers.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/utils/__pycache__/distutils_args.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/utils/__pycache__/encoding.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/utils/__pycache__/entrypoints.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/utils/__pycache__/filesystem.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/utils/__pycache__/filetypes.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/utils/__pycache__/glibc.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/utils/__pycache__/hashes.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/utils/__pycache__/inject_securetransport.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/utils/__pycache__/logging.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/utils/__pycache__/misc.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/utils/__pycache__/models.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/utils/__pycache__/packaging.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/utils/__pycache__/pkg_resources.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/utils/__pycache__/setuptools_build.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/utils/__pycache__/subprocess.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/utils/__pycache__/temp_dir.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/utils/__pycache__/typing.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/utils/__pycache__/unpacking.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/utils/__pycache__/urls.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/utils/__pycache__/virtualenv.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/utils/__pycache__/wheel.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/utils/appdirs.py create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/utils/compat.py create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/utils/compatibility_tags.py create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/utils/deprecation.py create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/utils/direct_url_helpers.py create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/utils/distutils_args.py create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/utils/encoding.py create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/utils/entrypoints.py create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/utils/filesystem.py create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/utils/filetypes.py create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/utils/glibc.py create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/utils/hashes.py create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/utils/inject_securetransport.py create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/utils/logging.py create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/utils/misc.py create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/utils/models.py create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/utils/packaging.py create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/utils/pkg_resources.py create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/utils/setuptools_build.py create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/utils/subprocess.py create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/utils/temp_dir.py create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/utils/typing.py create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/utils/unpacking.py create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/utils/urls.py create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/utils/virtualenv.py create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/utils/wheel.py create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/vcs/__init__.py create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/vcs/__pycache__/__init__.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/vcs/__pycache__/bazaar.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/vcs/__pycache__/git.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/vcs/__pycache__/mercurial.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/vcs/__pycache__/subversion.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/vcs/__pycache__/versioncontrol.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/vcs/bazaar.py create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/vcs/git.py create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/vcs/mercurial.py create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/vcs/subversion.py create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/vcs/versioncontrol.py create mode 100644 .venv/lib/python3.8/site-packages/pip/_internal/wheel_builder.py create mode 100644 .venv/lib/python3.8/site-packages/pip/_vendor/__init__.py create mode 100644 .venv/lib/python3.8/site-packages/pip/_vendor/__pycache__/__init__.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pkg_resources-0.0.0.dist-info/AUTHORS.txt create mode 100644 .venv/lib/python3.8/site-packages/pkg_resources-0.0.0.dist-info/INSTALLER create mode 100644 .venv/lib/python3.8/site-packages/pkg_resources-0.0.0.dist-info/LICENSE.txt create mode 100644 .venv/lib/python3.8/site-packages/pkg_resources-0.0.0.dist-info/METADATA create mode 100644 .venv/lib/python3.8/site-packages/pkg_resources-0.0.0.dist-info/RECORD create mode 100644 .venv/lib/python3.8/site-packages/pkg_resources-0.0.0.dist-info/WHEEL create mode 100644 .venv/lib/python3.8/site-packages/pkg_resources/__init__.py create mode 100644 .venv/lib/python3.8/site-packages/pkg_resources/__pycache__/__init__.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pkg_resources/__pycache__/py31compat.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pkg_resources/_vendor/__init__.py create mode 100644 .venv/lib/python3.8/site-packages/pkg_resources/_vendor/__pycache__/__init__.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pkg_resources/_vendor/__pycache__/appdirs.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pkg_resources/_vendor/__pycache__/pyparsing.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pkg_resources/_vendor/__pycache__/six.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pkg_resources/_vendor/appdirs.py create mode 100644 .venv/lib/python3.8/site-packages/pkg_resources/_vendor/packaging/__about__.py create mode 100644 .venv/lib/python3.8/site-packages/pkg_resources/_vendor/packaging/__init__.py create mode 100644 .venv/lib/python3.8/site-packages/pkg_resources/_vendor/packaging/__pycache__/__about__.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pkg_resources/_vendor/packaging/__pycache__/__init__.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pkg_resources/_vendor/packaging/__pycache__/_compat.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pkg_resources/_vendor/packaging/__pycache__/_structures.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pkg_resources/_vendor/packaging/__pycache__/markers.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pkg_resources/_vendor/packaging/__pycache__/requirements.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pkg_resources/_vendor/packaging/__pycache__/specifiers.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pkg_resources/_vendor/packaging/__pycache__/utils.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pkg_resources/_vendor/packaging/__pycache__/version.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pkg_resources/_vendor/packaging/_compat.py create mode 100644 .venv/lib/python3.8/site-packages/pkg_resources/_vendor/packaging/_structures.py create mode 100644 .venv/lib/python3.8/site-packages/pkg_resources/_vendor/packaging/markers.py create mode 100644 .venv/lib/python3.8/site-packages/pkg_resources/_vendor/packaging/requirements.py create mode 100644 .venv/lib/python3.8/site-packages/pkg_resources/_vendor/packaging/specifiers.py create mode 100644 .venv/lib/python3.8/site-packages/pkg_resources/_vendor/packaging/utils.py create mode 100644 .venv/lib/python3.8/site-packages/pkg_resources/_vendor/packaging/version.py create mode 100644 .venv/lib/python3.8/site-packages/pkg_resources/_vendor/pyparsing.py create mode 100644 .venv/lib/python3.8/site-packages/pkg_resources/_vendor/six.py create mode 100644 .venv/lib/python3.8/site-packages/pkg_resources/extern/__init__.py create mode 100644 .venv/lib/python3.8/site-packages/pkg_resources/extern/__pycache__/__init__.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pkg_resources/py31compat.py create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit-3.0.8.dist-info/AUTHORS.rst create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit-3.0.8.dist-info/INSTALLER create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit-3.0.8.dist-info/LICENSE create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit-3.0.8.dist-info/METADATA create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit-3.0.8.dist-info/RECORD create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit-3.0.8.dist-info/WHEEL create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit-3.0.8.dist-info/top_level.txt create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/__init__.py create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/__pycache__/__init__.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/__pycache__/auto_suggest.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/__pycache__/buffer.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/__pycache__/cache.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/__pycache__/data_structures.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/__pycache__/document.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/__pycache__/enums.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/__pycache__/history.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/__pycache__/keys.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/__pycache__/log.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/__pycache__/mouse_events.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/__pycache__/patch_stdout.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/__pycache__/renderer.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/__pycache__/search.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/__pycache__/selection.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/__pycache__/token.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/__pycache__/utils.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/__pycache__/validation.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/__pycache__/win32_types.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/application/__init__.py create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/application/__pycache__/__init__.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/application/__pycache__/application.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/application/__pycache__/current.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/application/__pycache__/dummy.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/application/__pycache__/run_in_terminal.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/application/application.py create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/application/current.py create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/application/dummy.py create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/application/run_in_terminal.py create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/auto_suggest.py create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/buffer.py create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/cache.py create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/clipboard/__init__.py create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/clipboard/__pycache__/__init__.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/clipboard/__pycache__/base.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/clipboard/__pycache__/in_memory.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/clipboard/__pycache__/pyperclip.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/clipboard/base.py create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/clipboard/in_memory.py create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/clipboard/pyperclip.py create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/completion/__init__.py create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/completion/__pycache__/__init__.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/completion/__pycache__/base.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/completion/__pycache__/filesystem.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/completion/__pycache__/fuzzy_completer.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/completion/__pycache__/nested.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/completion/__pycache__/word_completer.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/completion/base.py create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/completion/filesystem.py create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/completion/fuzzy_completer.py create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/completion/nested.py create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/completion/word_completer.py create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/contrib/__init__.py create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/contrib/__pycache__/__init__.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/contrib/completers/__init__.py create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/contrib/completers/__pycache__/__init__.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/contrib/completers/__pycache__/system.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/contrib/completers/system.py create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/contrib/regular_languages/__init__.py create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/contrib/regular_languages/__pycache__/__init__.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/contrib/regular_languages/__pycache__/compiler.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/contrib/regular_languages/__pycache__/completion.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/contrib/regular_languages/__pycache__/lexer.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/contrib/regular_languages/__pycache__/regex_parser.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/contrib/regular_languages/__pycache__/validation.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/contrib/regular_languages/compiler.py create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/contrib/regular_languages/completion.py create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/contrib/regular_languages/lexer.py create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/contrib/regular_languages/regex_parser.py create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/contrib/regular_languages/validation.py create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/contrib/ssh/__init__.py create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/contrib/ssh/__pycache__/__init__.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/contrib/ssh/__pycache__/server.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/contrib/ssh/server.py create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/contrib/telnet/__init__.py create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/contrib/telnet/__pycache__/__init__.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/contrib/telnet/__pycache__/log.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/contrib/telnet/__pycache__/protocol.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/contrib/telnet/__pycache__/server.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/contrib/telnet/log.py create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/contrib/telnet/protocol.py create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/contrib/telnet/server.py create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/data_structures.py create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/document.py create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/enums.py create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/eventloop/__init__.py create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/eventloop/__pycache__/__init__.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/eventloop/__pycache__/async_context_manager.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/eventloop/__pycache__/async_generator.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/eventloop/__pycache__/dummy_contextvars.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/eventloop/__pycache__/inputhook.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/eventloop/__pycache__/utils.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/eventloop/__pycache__/win32.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/eventloop/async_context_manager.py create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/eventloop/async_generator.py create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/eventloop/dummy_contextvars.py create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/eventloop/inputhook.py create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/eventloop/utils.py create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/eventloop/win32.py create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/filters/__init__.py create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/filters/__pycache__/__init__.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/filters/__pycache__/app.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/filters/__pycache__/base.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/filters/__pycache__/cli.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/filters/__pycache__/utils.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/filters/app.py create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/filters/base.py create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/filters/cli.py create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/filters/utils.py create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/formatted_text/__init__.py create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/formatted_text/__pycache__/__init__.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/formatted_text/__pycache__/ansi.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/formatted_text/__pycache__/base.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/formatted_text/__pycache__/html.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/formatted_text/__pycache__/pygments.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/formatted_text/__pycache__/utils.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/formatted_text/ansi.py create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/formatted_text/base.py create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/formatted_text/html.py create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/formatted_text/pygments.py create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/formatted_text/utils.py create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/history.py create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/input/__init__.py create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/input/__pycache__/__init__.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/input/__pycache__/ansi_escape_sequences.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/input/__pycache__/base.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/input/__pycache__/defaults.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/input/__pycache__/posix_pipe.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/input/__pycache__/posix_utils.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/input/__pycache__/typeahead.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/input/__pycache__/vt100.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/input/__pycache__/vt100_parser.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/input/__pycache__/win32.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/input/__pycache__/win32_pipe.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/input/ansi_escape_sequences.py create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/input/base.py create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/input/defaults.py create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/input/posix_pipe.py create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/input/posix_utils.py create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/input/typeahead.py create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/input/vt100.py create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/input/vt100_parser.py create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/input/win32.py create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/input/win32_pipe.py create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/key_binding/__init__.py create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/key_binding/__pycache__/__init__.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/key_binding/__pycache__/defaults.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/key_binding/__pycache__/digraphs.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/key_binding/__pycache__/emacs_state.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/key_binding/__pycache__/key_bindings.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/key_binding/__pycache__/key_processor.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/key_binding/__pycache__/vi_state.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/key_binding/bindings/__init__.py create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/key_binding/bindings/__pycache__/__init__.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/key_binding/bindings/__pycache__/auto_suggest.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/key_binding/bindings/__pycache__/basic.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/key_binding/bindings/__pycache__/completion.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/key_binding/bindings/__pycache__/cpr.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/key_binding/bindings/__pycache__/emacs.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/key_binding/bindings/__pycache__/focus.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/key_binding/bindings/__pycache__/mouse.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/key_binding/bindings/__pycache__/named_commands.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/key_binding/bindings/__pycache__/open_in_editor.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/key_binding/bindings/__pycache__/page_navigation.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/key_binding/bindings/__pycache__/scroll.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/key_binding/bindings/__pycache__/search.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/key_binding/bindings/__pycache__/vi.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/key_binding/bindings/auto_suggest.py create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/key_binding/bindings/basic.py create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/key_binding/bindings/completion.py create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/key_binding/bindings/cpr.py create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/key_binding/bindings/emacs.py create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/key_binding/bindings/focus.py create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/key_binding/bindings/mouse.py create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/key_binding/bindings/named_commands.py create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/key_binding/bindings/open_in_editor.py create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/key_binding/bindings/page_navigation.py create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/key_binding/bindings/scroll.py create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/key_binding/bindings/search.py create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/key_binding/bindings/vi.py create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/key_binding/defaults.py create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/key_binding/digraphs.py create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/key_binding/emacs_state.py create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/key_binding/key_bindings.py create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/key_binding/key_processor.py create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/key_binding/vi_state.py create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/keys.py create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/layout/__init__.py create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/layout/__pycache__/__init__.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/layout/__pycache__/containers.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/layout/__pycache__/controls.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/layout/__pycache__/dimension.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/layout/__pycache__/dummy.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/layout/__pycache__/layout.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/layout/__pycache__/margins.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/layout/__pycache__/menus.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/layout/__pycache__/mouse_handlers.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/layout/__pycache__/processors.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/layout/__pycache__/screen.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/layout/__pycache__/utils.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/layout/containers.py create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/layout/controls.py create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/layout/dimension.py create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/layout/dummy.py create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/layout/layout.py create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/layout/margins.py create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/layout/menus.py create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/layout/mouse_handlers.py create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/layout/processors.py create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/layout/screen.py create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/layout/utils.py create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/lexers/__init__.py create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/lexers/__pycache__/__init__.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/lexers/__pycache__/base.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/lexers/__pycache__/pygments.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/lexers/base.py create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/lexers/pygments.py create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/log.py create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/mouse_events.py create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/output/__init__.py create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/output/__pycache__/__init__.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/output/__pycache__/base.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/output/__pycache__/color_depth.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/output/__pycache__/conemu.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/output/__pycache__/defaults.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/output/__pycache__/vt100.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/output/__pycache__/win32.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/output/__pycache__/windows10.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/output/base.py create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/output/color_depth.py create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/output/conemu.py create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/output/defaults.py create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/output/vt100.py create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/output/win32.py create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/output/windows10.py create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/patch_stdout.py create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/py.typed create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/renderer.py create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/search.py create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/selection.py create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/shortcuts/__init__.py create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/shortcuts/__pycache__/__init__.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/shortcuts/__pycache__/dialogs.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/shortcuts/__pycache__/prompt.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/shortcuts/__pycache__/utils.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/shortcuts/dialogs.py create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/shortcuts/progress_bar/__init__.py create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/shortcuts/progress_bar/__pycache__/__init__.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/shortcuts/progress_bar/__pycache__/base.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/shortcuts/progress_bar/__pycache__/formatters.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/shortcuts/progress_bar/base.py create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/shortcuts/progress_bar/formatters.py create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/shortcuts/prompt.py create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/shortcuts/utils.py create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/styles/__init__.py create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/styles/__pycache__/__init__.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/styles/__pycache__/base.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/styles/__pycache__/defaults.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/styles/__pycache__/named_colors.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/styles/__pycache__/pygments.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/styles/__pycache__/style.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/styles/__pycache__/style_transformation.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/styles/base.py create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/styles/defaults.py create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/styles/named_colors.py create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/styles/pygments.py create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/styles/style.py create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/styles/style_transformation.py create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/token.py create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/utils.py create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/validation.py create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/widgets/__init__.py create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/widgets/__pycache__/__init__.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/widgets/__pycache__/base.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/widgets/__pycache__/dialogs.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/widgets/__pycache__/menus.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/widgets/__pycache__/toolbars.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/widgets/base.py create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/widgets/dialogs.py create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/widgets/menus.py create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/widgets/toolbars.py create mode 100644 .venv/lib/python3.8/site-packages/prompt_toolkit/win32_types.py create mode 100644 .venv/lib/python3.8/site-packages/ptyprocess-0.6.0.dist-info/INSTALLER create mode 100644 .venv/lib/python3.8/site-packages/ptyprocess-0.6.0.dist-info/LICENSE create mode 100644 .venv/lib/python3.8/site-packages/ptyprocess-0.6.0.dist-info/METADATA create mode 100644 .venv/lib/python3.8/site-packages/ptyprocess-0.6.0.dist-info/RECORD create mode 100644 .venv/lib/python3.8/site-packages/ptyprocess-0.6.0.dist-info/WHEEL create mode 100644 .venv/lib/python3.8/site-packages/ptyprocess/__init__.py create mode 100644 .venv/lib/python3.8/site-packages/ptyprocess/__pycache__/__init__.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/ptyprocess/__pycache__/_fork_pty.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/ptyprocess/__pycache__/ptyprocess.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/ptyprocess/__pycache__/util.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/ptyprocess/_fork_pty.py create mode 100644 .venv/lib/python3.8/site-packages/ptyprocess/ptyprocess.py create mode 100644 .venv/lib/python3.8/site-packages/ptyprocess/util.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/__init__.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/__main__.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/__pycache__/__init__.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/__pycache__/__main__.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/__pycache__/cmdline.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/__pycache__/console.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/__pycache__/filter.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/__pycache__/formatter.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/__pycache__/lexer.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/__pycache__/modeline.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/__pycache__/plugin.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/__pycache__/regexopt.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/__pycache__/scanner.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/__pycache__/sphinxext.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/__pycache__/style.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/__pycache__/token.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/__pycache__/unistring.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/__pycache__/util.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/cmdline.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/console.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/filter.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/filters/__init__.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/filters/__pycache__/__init__.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/formatter.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/formatters/__init__.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/formatters/__pycache__/__init__.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/formatters/__pycache__/_mapping.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/formatters/__pycache__/bbcode.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/formatters/__pycache__/html.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/formatters/__pycache__/img.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/formatters/__pycache__/irc.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/formatters/__pycache__/latex.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/formatters/__pycache__/other.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/formatters/__pycache__/rtf.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/formatters/__pycache__/svg.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/formatters/__pycache__/terminal.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/formatters/__pycache__/terminal256.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/formatters/_mapping.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/formatters/bbcode.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/formatters/html.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/formatters/img.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/formatters/irc.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/formatters/latex.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/formatters/other.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/formatters/rtf.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/formatters/svg.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/formatters/terminal.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/formatters/terminal256.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexer.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/__init__.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/__pycache__/__init__.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/__pycache__/_asy_builtins.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/__pycache__/_cl_builtins.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/__pycache__/_cocoa_builtins.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/__pycache__/_csound_builtins.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/__pycache__/_lasso_builtins.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/__pycache__/_lua_builtins.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/__pycache__/_mapping.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/__pycache__/_mql_builtins.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/__pycache__/_mysql_builtins.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/__pycache__/_openedge_builtins.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/__pycache__/_php_builtins.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/__pycache__/_postgres_builtins.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/__pycache__/_scilab_builtins.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/__pycache__/_sourcemod_builtins.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/__pycache__/_stan_builtins.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/__pycache__/_stata_builtins.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/__pycache__/_tsql_builtins.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/__pycache__/_usd_builtins.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/__pycache__/_vbscript_builtins.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/__pycache__/_vim_builtins.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/__pycache__/actionscript.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/__pycache__/agile.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/__pycache__/algebra.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/__pycache__/ambient.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/__pycache__/ampl.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/__pycache__/apl.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/__pycache__/archetype.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/__pycache__/arrow.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/__pycache__/asm.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/__pycache__/automation.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/__pycache__/bare.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/__pycache__/basic.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/__pycache__/bibtex.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/__pycache__/boa.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/__pycache__/business.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/__pycache__/c_cpp.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/__pycache__/c_like.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/__pycache__/capnproto.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/__pycache__/chapel.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/__pycache__/clean.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/__pycache__/compiled.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/__pycache__/configs.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/__pycache__/console.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/__pycache__/crystal.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/__pycache__/csound.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/__pycache__/css.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/__pycache__/d.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/__pycache__/dalvik.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/__pycache__/data.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/__pycache__/devicetree.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/__pycache__/diff.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/__pycache__/dotnet.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/__pycache__/dsls.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/__pycache__/dylan.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/__pycache__/ecl.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/__pycache__/eiffel.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/__pycache__/elm.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/__pycache__/email.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/__pycache__/erlang.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/__pycache__/esoteric.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/__pycache__/ezhil.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/__pycache__/factor.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/__pycache__/fantom.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/__pycache__/felix.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/__pycache__/floscript.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/__pycache__/forth.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/__pycache__/fortran.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/__pycache__/foxpro.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/__pycache__/freefem.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/__pycache__/functional.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/__pycache__/gdscript.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/__pycache__/go.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/__pycache__/grammar_notation.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/__pycache__/graph.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/__pycache__/graphics.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/__pycache__/haskell.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/__pycache__/haxe.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/__pycache__/hdl.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/__pycache__/hexdump.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/__pycache__/html.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/__pycache__/idl.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/__pycache__/igor.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/__pycache__/inferno.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/__pycache__/installers.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/__pycache__/int_fiction.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/__pycache__/iolang.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/__pycache__/j.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/__pycache__/javascript.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/__pycache__/julia.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/__pycache__/jvm.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/__pycache__/lisp.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/__pycache__/make.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/__pycache__/markup.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/__pycache__/math.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/__pycache__/matlab.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/__pycache__/mime.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/__pycache__/ml.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/__pycache__/modeling.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/__pycache__/modula2.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/__pycache__/monte.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/__pycache__/mosel.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/__pycache__/ncl.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/__pycache__/nimrod.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/__pycache__/nit.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/__pycache__/nix.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/__pycache__/oberon.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/__pycache__/objective.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/__pycache__/ooc.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/__pycache__/other.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/__pycache__/parasail.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/__pycache__/parsers.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/__pycache__/pascal.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/__pycache__/pawn.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/__pycache__/perl.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/__pycache__/php.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/__pycache__/pointless.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/__pycache__/pony.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/__pycache__/praat.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/__pycache__/prolog.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/__pycache__/promql.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/__pycache__/python.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/__pycache__/qvt.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/__pycache__/r.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/__pycache__/rdf.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/__pycache__/rebol.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/__pycache__/resource.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/__pycache__/ride.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/__pycache__/rnc.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/__pycache__/roboconf.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/__pycache__/robotframework.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/__pycache__/ruby.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/__pycache__/rust.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/__pycache__/sas.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/__pycache__/scdoc.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/__pycache__/scripting.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/__pycache__/sgf.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/__pycache__/shell.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/__pycache__/sieve.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/__pycache__/slash.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/__pycache__/smalltalk.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/__pycache__/smv.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/__pycache__/snobol.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/__pycache__/solidity.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/__pycache__/special.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/__pycache__/sql.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/__pycache__/stata.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/__pycache__/supercollider.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/__pycache__/tcl.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/__pycache__/templates.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/__pycache__/teraterm.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/__pycache__/testing.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/__pycache__/text.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/__pycache__/textedit.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/__pycache__/textfmts.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/__pycache__/theorem.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/__pycache__/tnt.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/__pycache__/trafficscript.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/__pycache__/typoscript.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/__pycache__/unicon.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/__pycache__/urbi.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/__pycache__/usd.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/__pycache__/varnish.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/__pycache__/verification.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/__pycache__/web.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/__pycache__/webidl.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/__pycache__/webmisc.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/__pycache__/whiley.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/__pycache__/x10.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/__pycache__/xorg.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/__pycache__/yang.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/__pycache__/zig.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/_asy_builtins.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/_cl_builtins.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/_cocoa_builtins.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/_csound_builtins.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/_lasso_builtins.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/_lua_builtins.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/_mapping.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/_mql_builtins.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/_mysql_builtins.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/_openedge_builtins.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/_php_builtins.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/_postgres_builtins.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/_scilab_builtins.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/_sourcemod_builtins.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/_stan_builtins.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/_stata_builtins.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/_tsql_builtins.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/_usd_builtins.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/_vbscript_builtins.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/_vim_builtins.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/actionscript.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/agile.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/algebra.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/ambient.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/ampl.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/apl.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/archetype.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/arrow.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/asm.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/automation.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/bare.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/basic.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/bibtex.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/boa.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/business.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/c_cpp.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/c_like.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/capnproto.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/chapel.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/clean.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/compiled.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/configs.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/console.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/crystal.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/csound.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/css.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/d.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/dalvik.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/data.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/devicetree.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/diff.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/dotnet.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/dsls.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/dylan.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/ecl.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/eiffel.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/elm.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/email.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/erlang.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/esoteric.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/ezhil.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/factor.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/fantom.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/felix.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/floscript.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/forth.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/fortran.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/foxpro.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/freefem.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/functional.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/gdscript.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/go.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/grammar_notation.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/graph.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/graphics.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/haskell.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/haxe.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/hdl.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/hexdump.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/html.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/idl.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/igor.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/inferno.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/installers.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/int_fiction.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/iolang.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/j.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/javascript.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/julia.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/jvm.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/lisp.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/make.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/markup.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/math.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/matlab.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/mime.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/ml.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/modeling.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/modula2.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/monte.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/mosel.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/ncl.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/nimrod.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/nit.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/nix.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/oberon.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/objective.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/ooc.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/other.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/parasail.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/parsers.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/pascal.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/pawn.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/perl.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/php.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/pointless.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/pony.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/praat.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/prolog.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/promql.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/python.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/qvt.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/r.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/rdf.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/rebol.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/resource.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/ride.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/rnc.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/roboconf.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/robotframework.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/ruby.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/rust.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/sas.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/scdoc.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/scripting.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/sgf.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/shell.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/sieve.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/slash.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/smalltalk.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/smv.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/snobol.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/solidity.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/special.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/sql.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/stata.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/supercollider.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/tcl.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/templates.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/teraterm.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/testing.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/text.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/textedit.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/textfmts.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/theorem.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/tnt.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/trafficscript.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/typoscript.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/unicon.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/urbi.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/usd.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/varnish.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/verification.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/web.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/webidl.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/webmisc.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/whiley.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/x10.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/xorg.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/yang.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/lexers/zig.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/modeline.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/plugin.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/regexopt.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/scanner.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/sphinxext.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/style.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/styles/__init__.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/styles/__pycache__/__init__.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/styles/__pycache__/abap.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/styles/__pycache__/algol.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/styles/__pycache__/algol_nu.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/styles/__pycache__/arduino.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/styles/__pycache__/autumn.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/styles/__pycache__/borland.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/styles/__pycache__/bw.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/styles/__pycache__/colorful.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/styles/__pycache__/default.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/styles/__pycache__/emacs.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/styles/__pycache__/friendly.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/styles/__pycache__/fruity.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/styles/__pycache__/igor.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/styles/__pycache__/inkpot.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/styles/__pycache__/lovelace.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/styles/__pycache__/manni.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/styles/__pycache__/monokai.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/styles/__pycache__/murphy.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/styles/__pycache__/native.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/styles/__pycache__/paraiso_dark.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/styles/__pycache__/paraiso_light.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/styles/__pycache__/pastie.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/styles/__pycache__/perldoc.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/styles/__pycache__/rainbow_dash.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/styles/__pycache__/rrt.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/styles/__pycache__/sas.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/styles/__pycache__/solarized.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/styles/__pycache__/stata_dark.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/styles/__pycache__/stata_light.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/styles/__pycache__/tango.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/styles/__pycache__/trac.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/styles/__pycache__/vim.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/styles/__pycache__/vs.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/styles/__pycache__/xcode.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pygments/styles/abap.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/styles/algol.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/styles/algol_nu.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/styles/arduino.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/styles/autumn.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/styles/borland.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/styles/bw.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/styles/colorful.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/styles/default.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/styles/emacs.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/styles/friendly.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/styles/fruity.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/styles/igor.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/styles/inkpot.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/styles/lovelace.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/styles/manni.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/styles/monokai.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/styles/murphy.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/styles/native.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/styles/paraiso_dark.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/styles/paraiso_light.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/styles/pastie.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/styles/perldoc.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/styles/rainbow_dash.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/styles/rrt.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/styles/sas.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/styles/solarized.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/styles/stata_dark.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/styles/stata_light.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/styles/tango.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/styles/trac.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/styles/vim.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/styles/vs.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/styles/xcode.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/token.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/unistring.py create mode 100644 .venv/lib/python3.8/site-packages/pygments/util.py create mode 100644 .venv/lib/python3.8/site-packages/pylint-2.6.0.dist-info/COPYING create mode 100644 .venv/lib/python3.8/site-packages/pylint-2.6.0.dist-info/INSTALLER create mode 100644 .venv/lib/python3.8/site-packages/pylint-2.6.0.dist-info/METADATA create mode 100644 .venv/lib/python3.8/site-packages/pylint-2.6.0.dist-info/RECORD create mode 100644 .venv/lib/python3.8/site-packages/pylint-2.6.0.dist-info/WHEEL create mode 100644 .venv/lib/python3.8/site-packages/pylint-2.6.0.dist-info/entry_points.txt create mode 100644 .venv/lib/python3.8/site-packages/pylint-2.6.0.dist-info/top_level.txt create mode 100644 .venv/lib/python3.8/site-packages/pylint/__init__.py create mode 100644 .venv/lib/python3.8/site-packages/pylint/__main__.py create mode 100644 .venv/lib/python3.8/site-packages/pylint/__pkginfo__.py create mode 100644 .venv/lib/python3.8/site-packages/pylint/__pycache__/__init__.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pylint/__pycache__/__main__.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pylint/__pycache__/__pkginfo__.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pylint/__pycache__/constants.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pylint/__pycache__/epylint.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pylint/__pycache__/exceptions.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pylint/__pycache__/graph.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pylint/__pycache__/interfaces.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pylint/__pycache__/testutils.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pylint/checkers/__init__.py create mode 100644 .venv/lib/python3.8/site-packages/pylint/checkers/__pycache__/__init__.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pylint/checkers/__pycache__/async.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pylint/checkers/__pycache__/base.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pylint/checkers/__pycache__/base_checker.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pylint/checkers/__pycache__/classes.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pylint/checkers/__pycache__/design_analysis.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pylint/checkers/__pycache__/exceptions.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pylint/checkers/__pycache__/format.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pylint/checkers/__pycache__/imports.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pylint/checkers/__pycache__/logging.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pylint/checkers/__pycache__/misc.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pylint/checkers/__pycache__/newstyle.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pylint/checkers/__pycache__/python3.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pylint/checkers/__pycache__/raw_metrics.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pylint/checkers/__pycache__/refactoring.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pylint/checkers/__pycache__/similar.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pylint/checkers/__pycache__/spelling.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pylint/checkers/__pycache__/stdlib.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pylint/checkers/__pycache__/strings.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pylint/checkers/__pycache__/typecheck.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pylint/checkers/__pycache__/utils.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pylint/checkers/__pycache__/variables.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pylint/checkers/async.py create mode 100644 .venv/lib/python3.8/site-packages/pylint/checkers/base.py create mode 100644 .venv/lib/python3.8/site-packages/pylint/checkers/base_checker.py create mode 100644 .venv/lib/python3.8/site-packages/pylint/checkers/classes.py create mode 100644 .venv/lib/python3.8/site-packages/pylint/checkers/design_analysis.py create mode 100644 .venv/lib/python3.8/site-packages/pylint/checkers/exceptions.py create mode 100644 .venv/lib/python3.8/site-packages/pylint/checkers/format.py create mode 100644 .venv/lib/python3.8/site-packages/pylint/checkers/imports.py create mode 100644 .venv/lib/python3.8/site-packages/pylint/checkers/logging.py create mode 100644 .venv/lib/python3.8/site-packages/pylint/checkers/misc.py create mode 100644 .venv/lib/python3.8/site-packages/pylint/checkers/newstyle.py create mode 100644 .venv/lib/python3.8/site-packages/pylint/checkers/python3.py create mode 100644 .venv/lib/python3.8/site-packages/pylint/checkers/raw_metrics.py create mode 100644 .venv/lib/python3.8/site-packages/pylint/checkers/refactoring.py create mode 100644 .venv/lib/python3.8/site-packages/pylint/checkers/similar.py create mode 100644 .venv/lib/python3.8/site-packages/pylint/checkers/spelling.py create mode 100644 .venv/lib/python3.8/site-packages/pylint/checkers/stdlib.py create mode 100644 .venv/lib/python3.8/site-packages/pylint/checkers/strings.py create mode 100644 .venv/lib/python3.8/site-packages/pylint/checkers/typecheck.py create mode 100644 .venv/lib/python3.8/site-packages/pylint/checkers/utils.py create mode 100644 .venv/lib/python3.8/site-packages/pylint/checkers/variables.py create mode 100644 .venv/lib/python3.8/site-packages/pylint/config/__init__.py create mode 100644 .venv/lib/python3.8/site-packages/pylint/config/__pycache__/__init__.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pylint/config/__pycache__/configuration_mixin.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pylint/config/__pycache__/find_default_config_files.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pylint/config/__pycache__/man_help_formatter.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pylint/config/__pycache__/option.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pylint/config/__pycache__/option_manager_mixin.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pylint/config/__pycache__/option_parser.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pylint/config/__pycache__/options_provider_mixin.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pylint/config/configuration_mixin.py create mode 100644 .venv/lib/python3.8/site-packages/pylint/config/find_default_config_files.py create mode 100644 .venv/lib/python3.8/site-packages/pylint/config/man_help_formatter.py create mode 100644 .venv/lib/python3.8/site-packages/pylint/config/option.py create mode 100644 .venv/lib/python3.8/site-packages/pylint/config/option_manager_mixin.py create mode 100644 .venv/lib/python3.8/site-packages/pylint/config/option_parser.py create mode 100644 .venv/lib/python3.8/site-packages/pylint/config/options_provider_mixin.py create mode 100644 .venv/lib/python3.8/site-packages/pylint/constants.py create mode 100644 .venv/lib/python3.8/site-packages/pylint/epylint.py create mode 100644 .venv/lib/python3.8/site-packages/pylint/exceptions.py create mode 100644 .venv/lib/python3.8/site-packages/pylint/extensions/__init__.py create mode 100644 .venv/lib/python3.8/site-packages/pylint/extensions/__pycache__/__init__.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pylint/extensions/__pycache__/_check_docs_utils.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pylint/extensions/__pycache__/bad_builtin.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pylint/extensions/__pycache__/broad_try_clause.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pylint/extensions/__pycache__/check_docs.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pylint/extensions/__pycache__/check_elif.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pylint/extensions/__pycache__/comparetozero.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pylint/extensions/__pycache__/docparams.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pylint/extensions/__pycache__/docstyle.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pylint/extensions/__pycache__/emptystring.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pylint/extensions/__pycache__/mccabe.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pylint/extensions/__pycache__/overlapping_exceptions.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pylint/extensions/__pycache__/redefined_variable_type.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pylint/extensions/_check_docs_utils.py create mode 100644 .venv/lib/python3.8/site-packages/pylint/extensions/bad_builtin.py create mode 100644 .venv/lib/python3.8/site-packages/pylint/extensions/broad_try_clause.py create mode 100644 .venv/lib/python3.8/site-packages/pylint/extensions/check_docs.py create mode 100644 .venv/lib/python3.8/site-packages/pylint/extensions/check_elif.py create mode 100644 .venv/lib/python3.8/site-packages/pylint/extensions/comparetozero.py create mode 100644 .venv/lib/python3.8/site-packages/pylint/extensions/docparams.py create mode 100644 .venv/lib/python3.8/site-packages/pylint/extensions/docstyle.py create mode 100644 .venv/lib/python3.8/site-packages/pylint/extensions/emptystring.py create mode 100644 .venv/lib/python3.8/site-packages/pylint/extensions/mccabe.py create mode 100644 .venv/lib/python3.8/site-packages/pylint/extensions/overlapping_exceptions.py create mode 100644 .venv/lib/python3.8/site-packages/pylint/extensions/redefined_variable_type.py create mode 100644 .venv/lib/python3.8/site-packages/pylint/graph.py create mode 100644 .venv/lib/python3.8/site-packages/pylint/interfaces.py create mode 100644 .venv/lib/python3.8/site-packages/pylint/lint/__init__.py create mode 100644 .venv/lib/python3.8/site-packages/pylint/lint/__pycache__/__init__.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pylint/lint/__pycache__/check_parallel.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pylint/lint/__pycache__/pylinter.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pylint/lint/__pycache__/report_functions.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pylint/lint/__pycache__/run.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pylint/lint/__pycache__/utils.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pylint/lint/check_parallel.py create mode 100644 .venv/lib/python3.8/site-packages/pylint/lint/pylinter.py create mode 100644 .venv/lib/python3.8/site-packages/pylint/lint/report_functions.py create mode 100644 .venv/lib/python3.8/site-packages/pylint/lint/run.py create mode 100644 .venv/lib/python3.8/site-packages/pylint/lint/utils.py create mode 100644 .venv/lib/python3.8/site-packages/pylint/message/__init__.py create mode 100644 .venv/lib/python3.8/site-packages/pylint/message/__pycache__/__init__.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pylint/message/__pycache__/message.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pylint/message/__pycache__/message_definition.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pylint/message/__pycache__/message_definition_store.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pylint/message/__pycache__/message_handler_mix_in.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pylint/message/__pycache__/message_id_store.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pylint/message/message.py create mode 100644 .venv/lib/python3.8/site-packages/pylint/message/message_definition.py create mode 100644 .venv/lib/python3.8/site-packages/pylint/message/message_definition_store.py create mode 100644 .venv/lib/python3.8/site-packages/pylint/message/message_handler_mix_in.py create mode 100644 .venv/lib/python3.8/site-packages/pylint/message/message_id_store.py create mode 100644 .venv/lib/python3.8/site-packages/pylint/pyreverse/__init__.py create mode 100644 .venv/lib/python3.8/site-packages/pylint/pyreverse/__pycache__/__init__.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pylint/pyreverse/__pycache__/diadefslib.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pylint/pyreverse/__pycache__/diagrams.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pylint/pyreverse/__pycache__/inspector.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pylint/pyreverse/__pycache__/main.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pylint/pyreverse/__pycache__/utils.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pylint/pyreverse/__pycache__/vcgutils.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pylint/pyreverse/__pycache__/writer.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pylint/pyreverse/diadefslib.py create mode 100644 .venv/lib/python3.8/site-packages/pylint/pyreverse/diagrams.py create mode 100644 .venv/lib/python3.8/site-packages/pylint/pyreverse/inspector.py create mode 100644 .venv/lib/python3.8/site-packages/pylint/pyreverse/main.py create mode 100644 .venv/lib/python3.8/site-packages/pylint/pyreverse/utils.py create mode 100644 .venv/lib/python3.8/site-packages/pylint/pyreverse/vcgutils.py create mode 100644 .venv/lib/python3.8/site-packages/pylint/pyreverse/writer.py create mode 100644 .venv/lib/python3.8/site-packages/pylint/reporters/__init__.py create mode 100644 .venv/lib/python3.8/site-packages/pylint/reporters/__pycache__/__init__.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pylint/reporters/__pycache__/base_reporter.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pylint/reporters/__pycache__/collecting_reporter.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pylint/reporters/__pycache__/json_reporter.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pylint/reporters/__pycache__/reports_handler_mix_in.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pylint/reporters/__pycache__/text.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pylint/reporters/base_reporter.py create mode 100644 .venv/lib/python3.8/site-packages/pylint/reporters/collecting_reporter.py create mode 100644 .venv/lib/python3.8/site-packages/pylint/reporters/json_reporter.py create mode 100644 .venv/lib/python3.8/site-packages/pylint/reporters/reports_handler_mix_in.py create mode 100644 .venv/lib/python3.8/site-packages/pylint/reporters/text.py create mode 100644 .venv/lib/python3.8/site-packages/pylint/reporters/ureports/__init__.py create mode 100644 .venv/lib/python3.8/site-packages/pylint/reporters/ureports/__pycache__/__init__.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pylint/reporters/ureports/__pycache__/nodes.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pylint/reporters/ureports/__pycache__/text_writer.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pylint/reporters/ureports/nodes.py create mode 100644 .venv/lib/python3.8/site-packages/pylint/reporters/ureports/text_writer.py create mode 100644 .venv/lib/python3.8/site-packages/pylint/testutils.py create mode 100644 .venv/lib/python3.8/site-packages/pylint/utils/__init__.py create mode 100644 .venv/lib/python3.8/site-packages/pylint/utils/__pycache__/__init__.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pylint/utils/__pycache__/ast_walker.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pylint/utils/__pycache__/file_state.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pylint/utils/__pycache__/pragma_parser.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pylint/utils/__pycache__/utils.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/pylint/utils/ast_walker.py create mode 100644 .venv/lib/python3.8/site-packages/pylint/utils/file_state.py create mode 100644 .venv/lib/python3.8/site-packages/pylint/utils/pragma_parser.py create mode 100644 .venv/lib/python3.8/site-packages/pylint/utils/utils.py create mode 100644 .venv/lib/python3.8/site-packages/python_dateutil-2.8.1.dist-info/INSTALLER create mode 100644 .venv/lib/python3.8/site-packages/python_dateutil-2.8.1.dist-info/LICENSE create mode 100644 .venv/lib/python3.8/site-packages/python_dateutil-2.8.1.dist-info/METADATA create mode 100644 .venv/lib/python3.8/site-packages/python_dateutil-2.8.1.dist-info/RECORD create mode 100644 .venv/lib/python3.8/site-packages/python_dateutil-2.8.1.dist-info/WHEEL create mode 100644 .venv/lib/python3.8/site-packages/python_dateutil-2.8.1.dist-info/top_level.txt create mode 100644 .venv/lib/python3.8/site-packages/python_dateutil-2.8.1.dist-info/zip-safe create mode 100644 .venv/lib/python3.8/site-packages/pyzmq-20.0.0.dist-info/AUTHORS.md create mode 100644 .venv/lib/python3.8/site-packages/pyzmq-20.0.0.dist-info/COPYING.BSD create mode 100644 .venv/lib/python3.8/site-packages/pyzmq-20.0.0.dist-info/COPYING.LESSER create mode 100644 .venv/lib/python3.8/site-packages/pyzmq-20.0.0.dist-info/INSTALLER create mode 100644 .venv/lib/python3.8/site-packages/pyzmq-20.0.0.dist-info/METADATA create mode 100644 .venv/lib/python3.8/site-packages/pyzmq-20.0.0.dist-info/RECORD create mode 100644 .venv/lib/python3.8/site-packages/pyzmq-20.0.0.dist-info/WHEEL create mode 100644 .venv/lib/python3.8/site-packages/pyzmq-20.0.0.dist-info/top_level.txt create mode 100755 .venv/lib/python3.8/site-packages/pyzmq.libs/libsodium-bcf9f097.so.23.3.0 create mode 100755 .venv/lib/python3.8/site-packages/pyzmq.libs/libzmq-f3e05bef.so.5.2.3 create mode 100644 .venv/lib/python3.8/site-packages/setuptools-44.0.0.dist-info/AUTHORS.txt create mode 100644 .venv/lib/python3.8/site-packages/setuptools-44.0.0.dist-info/INSTALLER create mode 100644 .venv/lib/python3.8/site-packages/setuptools-44.0.0.dist-info/LICENSE.txt create mode 100644 .venv/lib/python3.8/site-packages/setuptools-44.0.0.dist-info/METADATA create mode 100644 .venv/lib/python3.8/site-packages/setuptools-44.0.0.dist-info/RECORD create mode 100644 .venv/lib/python3.8/site-packages/setuptools-44.0.0.dist-info/WHEEL create mode 100644 .venv/lib/python3.8/site-packages/setuptools-44.0.0.dist-info/dependency_links.txt create mode 100644 .venv/lib/python3.8/site-packages/setuptools-44.0.0.dist-info/entry_points.txt create mode 100644 .venv/lib/python3.8/site-packages/setuptools-44.0.0.dist-info/top_level.txt create mode 100644 .venv/lib/python3.8/site-packages/setuptools-44.0.0.dist-info/zip-safe create mode 100644 .venv/lib/python3.8/site-packages/setuptools/__init__.py create mode 100644 .venv/lib/python3.8/site-packages/setuptools/__pycache__/__init__.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/setuptools/__pycache__/_deprecation_warning.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/setuptools/__pycache__/_imp.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/setuptools/__pycache__/archive_util.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/setuptools/__pycache__/build_meta.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/setuptools/__pycache__/config.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/setuptools/__pycache__/dep_util.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/setuptools/__pycache__/depends.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/setuptools/__pycache__/dist.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/setuptools/__pycache__/errors.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/setuptools/__pycache__/extension.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/setuptools/__pycache__/glob.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/setuptools/__pycache__/installer.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/setuptools/__pycache__/launch.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/setuptools/__pycache__/lib2to3_ex.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/setuptools/__pycache__/monkey.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/setuptools/__pycache__/msvc.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/setuptools/__pycache__/namespaces.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/setuptools/__pycache__/package_index.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/setuptools/__pycache__/py27compat.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/setuptools/__pycache__/py31compat.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/setuptools/__pycache__/py33compat.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/setuptools/__pycache__/py34compat.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/setuptools/__pycache__/sandbox.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/setuptools/__pycache__/site-patch.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/setuptools/__pycache__/ssl_support.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/setuptools/__pycache__/unicode_utils.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/setuptools/__pycache__/version.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/setuptools/__pycache__/wheel.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/setuptools/__pycache__/windows_support.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/setuptools/_deprecation_warning.py create mode 100644 .venv/lib/python3.8/site-packages/setuptools/_imp.py create mode 100644 .venv/lib/python3.8/site-packages/setuptools/_vendor/__init__.py create mode 100644 .venv/lib/python3.8/site-packages/setuptools/_vendor/__pycache__/__init__.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/setuptools/_vendor/__pycache__/ordered_set.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/setuptools/_vendor/__pycache__/pyparsing.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/setuptools/_vendor/__pycache__/six.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/setuptools/_vendor/ordered_set.py create mode 100644 .venv/lib/python3.8/site-packages/setuptools/_vendor/packaging/__about__.py create mode 100644 .venv/lib/python3.8/site-packages/setuptools/_vendor/packaging/__init__.py create mode 100644 .venv/lib/python3.8/site-packages/setuptools/_vendor/packaging/__pycache__/__about__.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/setuptools/_vendor/packaging/__pycache__/__init__.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/setuptools/_vendor/packaging/__pycache__/_compat.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/setuptools/_vendor/packaging/__pycache__/_structures.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/setuptools/_vendor/packaging/__pycache__/markers.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/setuptools/_vendor/packaging/__pycache__/requirements.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/setuptools/_vendor/packaging/__pycache__/specifiers.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/setuptools/_vendor/packaging/__pycache__/tags.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/setuptools/_vendor/packaging/__pycache__/utils.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/setuptools/_vendor/packaging/__pycache__/version.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/setuptools/_vendor/packaging/_compat.py create mode 100644 .venv/lib/python3.8/site-packages/setuptools/_vendor/packaging/_structures.py create mode 100644 .venv/lib/python3.8/site-packages/setuptools/_vendor/packaging/markers.py create mode 100644 .venv/lib/python3.8/site-packages/setuptools/_vendor/packaging/requirements.py create mode 100644 .venv/lib/python3.8/site-packages/setuptools/_vendor/packaging/specifiers.py create mode 100644 .venv/lib/python3.8/site-packages/setuptools/_vendor/packaging/tags.py create mode 100644 .venv/lib/python3.8/site-packages/setuptools/_vendor/packaging/utils.py create mode 100644 .venv/lib/python3.8/site-packages/setuptools/_vendor/packaging/version.py create mode 100644 .venv/lib/python3.8/site-packages/setuptools/_vendor/pyparsing.py create mode 100644 .venv/lib/python3.8/site-packages/setuptools/_vendor/six.py create mode 100644 .venv/lib/python3.8/site-packages/setuptools/archive_util.py create mode 100644 .venv/lib/python3.8/site-packages/setuptools/build_meta.py create mode 100644 .venv/lib/python3.8/site-packages/setuptools/cli-32.exe create mode 100644 .venv/lib/python3.8/site-packages/setuptools/cli-64.exe create mode 100644 .venv/lib/python3.8/site-packages/setuptools/cli.exe create mode 100644 .venv/lib/python3.8/site-packages/setuptools/command/__init__.py create mode 100644 .venv/lib/python3.8/site-packages/setuptools/command/__pycache__/__init__.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/setuptools/command/__pycache__/alias.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/setuptools/command/__pycache__/bdist_egg.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/setuptools/command/__pycache__/bdist_rpm.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/setuptools/command/__pycache__/bdist_wininst.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/setuptools/command/__pycache__/build_clib.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/setuptools/command/__pycache__/build_ext.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/setuptools/command/__pycache__/build_py.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/setuptools/command/__pycache__/develop.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/setuptools/command/__pycache__/dist_info.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/setuptools/command/__pycache__/easy_install.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/setuptools/command/__pycache__/egg_info.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/setuptools/command/__pycache__/install.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/setuptools/command/__pycache__/install_egg_info.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/setuptools/command/__pycache__/install_lib.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/setuptools/command/__pycache__/install_scripts.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/setuptools/command/__pycache__/py36compat.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/setuptools/command/__pycache__/register.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/setuptools/command/__pycache__/rotate.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/setuptools/command/__pycache__/saveopts.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/setuptools/command/__pycache__/sdist.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/setuptools/command/__pycache__/setopt.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/setuptools/command/__pycache__/test.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/setuptools/command/__pycache__/upload.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/setuptools/command/__pycache__/upload_docs.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/setuptools/command/alias.py create mode 100644 .venv/lib/python3.8/site-packages/setuptools/command/bdist_egg.py create mode 100644 .venv/lib/python3.8/site-packages/setuptools/command/bdist_rpm.py create mode 100644 .venv/lib/python3.8/site-packages/setuptools/command/bdist_wininst.py create mode 100644 .venv/lib/python3.8/site-packages/setuptools/command/build_clib.py create mode 100644 .venv/lib/python3.8/site-packages/setuptools/command/build_ext.py create mode 100644 .venv/lib/python3.8/site-packages/setuptools/command/build_py.py create mode 100644 .venv/lib/python3.8/site-packages/setuptools/command/develop.py create mode 100644 .venv/lib/python3.8/site-packages/setuptools/command/dist_info.py create mode 100644 .venv/lib/python3.8/site-packages/setuptools/command/easy_install.py create mode 100644 .venv/lib/python3.8/site-packages/setuptools/command/egg_info.py create mode 100644 .venv/lib/python3.8/site-packages/setuptools/command/install.py create mode 100644 .venv/lib/python3.8/site-packages/setuptools/command/install_egg_info.py create mode 100644 .venv/lib/python3.8/site-packages/setuptools/command/install_lib.py create mode 100644 .venv/lib/python3.8/site-packages/setuptools/command/install_scripts.py create mode 100644 .venv/lib/python3.8/site-packages/setuptools/command/launcher manifest.xml create mode 100644 .venv/lib/python3.8/site-packages/setuptools/command/py36compat.py create mode 100644 .venv/lib/python3.8/site-packages/setuptools/command/register.py create mode 100644 .venv/lib/python3.8/site-packages/setuptools/command/rotate.py create mode 100644 .venv/lib/python3.8/site-packages/setuptools/command/saveopts.py create mode 100644 .venv/lib/python3.8/site-packages/setuptools/command/sdist.py create mode 100644 .venv/lib/python3.8/site-packages/setuptools/command/setopt.py create mode 100644 .venv/lib/python3.8/site-packages/setuptools/command/test.py create mode 100644 .venv/lib/python3.8/site-packages/setuptools/command/upload.py create mode 100644 .venv/lib/python3.8/site-packages/setuptools/command/upload_docs.py create mode 100644 .venv/lib/python3.8/site-packages/setuptools/config.py create mode 100644 .venv/lib/python3.8/site-packages/setuptools/dep_util.py create mode 100644 .venv/lib/python3.8/site-packages/setuptools/depends.py create mode 100644 .venv/lib/python3.8/site-packages/setuptools/dist.py create mode 100644 .venv/lib/python3.8/site-packages/setuptools/errors.py create mode 100644 .venv/lib/python3.8/site-packages/setuptools/extension.py create mode 100644 .venv/lib/python3.8/site-packages/setuptools/extern/__init__.py create mode 100644 .venv/lib/python3.8/site-packages/setuptools/extern/__pycache__/__init__.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/setuptools/glob.py create mode 100644 .venv/lib/python3.8/site-packages/setuptools/gui-32.exe create mode 100644 .venv/lib/python3.8/site-packages/setuptools/gui-64.exe create mode 100644 .venv/lib/python3.8/site-packages/setuptools/gui.exe create mode 100644 .venv/lib/python3.8/site-packages/setuptools/installer.py create mode 100644 .venv/lib/python3.8/site-packages/setuptools/launch.py create mode 100644 .venv/lib/python3.8/site-packages/setuptools/lib2to3_ex.py create mode 100644 .venv/lib/python3.8/site-packages/setuptools/monkey.py create mode 100644 .venv/lib/python3.8/site-packages/setuptools/msvc.py create mode 100644 .venv/lib/python3.8/site-packages/setuptools/namespaces.py create mode 100644 .venv/lib/python3.8/site-packages/setuptools/package_index.py create mode 100644 .venv/lib/python3.8/site-packages/setuptools/py27compat.py create mode 100644 .venv/lib/python3.8/site-packages/setuptools/py31compat.py create mode 100644 .venv/lib/python3.8/site-packages/setuptools/py33compat.py create mode 100644 .venv/lib/python3.8/site-packages/setuptools/py34compat.py create mode 100644 .venv/lib/python3.8/site-packages/setuptools/sandbox.py create mode 100644 .venv/lib/python3.8/site-packages/setuptools/script (dev).tmpl create mode 100644 .venv/lib/python3.8/site-packages/setuptools/script.tmpl create mode 100644 .venv/lib/python3.8/site-packages/setuptools/site-patch.py create mode 100644 .venv/lib/python3.8/site-packages/setuptools/ssl_support.py create mode 100644 .venv/lib/python3.8/site-packages/setuptools/unicode_utils.py create mode 100644 .venv/lib/python3.8/site-packages/setuptools/version.py create mode 100644 .venv/lib/python3.8/site-packages/setuptools/wheel.py create mode 100644 .venv/lib/python3.8/site-packages/setuptools/windows_support.py create mode 100644 .venv/lib/python3.8/site-packages/six-1.15.0.dist-info/INSTALLER create mode 100644 .venv/lib/python3.8/site-packages/six-1.15.0.dist-info/LICENSE create mode 100644 .venv/lib/python3.8/site-packages/six-1.15.0.dist-info/METADATA create mode 100644 .venv/lib/python3.8/site-packages/six-1.15.0.dist-info/RECORD create mode 100644 .venv/lib/python3.8/site-packages/six-1.15.0.dist-info/WHEEL create mode 100644 .venv/lib/python3.8/site-packages/six-1.15.0.dist-info/top_level.txt create mode 100644 .venv/lib/python3.8/site-packages/six.py create mode 100644 .venv/lib/python3.8/site-packages/toml-0.10.2.dist-info/INSTALLER create mode 100644 .venv/lib/python3.8/site-packages/toml-0.10.2.dist-info/LICENSE create mode 100644 .venv/lib/python3.8/site-packages/toml-0.10.2.dist-info/METADATA create mode 100644 .venv/lib/python3.8/site-packages/toml-0.10.2.dist-info/RECORD create mode 100644 .venv/lib/python3.8/site-packages/toml-0.10.2.dist-info/WHEEL create mode 100644 .venv/lib/python3.8/site-packages/toml-0.10.2.dist-info/top_level.txt create mode 100644 .venv/lib/python3.8/site-packages/toml/__init__.py create mode 100644 .venv/lib/python3.8/site-packages/toml/__pycache__/__init__.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/toml/__pycache__/decoder.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/toml/__pycache__/encoder.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/toml/__pycache__/ordered.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/toml/__pycache__/tz.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/toml/decoder.py create mode 100644 .venv/lib/python3.8/site-packages/toml/encoder.py create mode 100644 .venv/lib/python3.8/site-packages/toml/ordered.py create mode 100644 .venv/lib/python3.8/site-packages/toml/tz.py create mode 100644 .venv/lib/python3.8/site-packages/tornado-6.1.dist-info/INSTALLER create mode 100644 .venv/lib/python3.8/site-packages/tornado-6.1.dist-info/LICENSE create mode 100644 .venv/lib/python3.8/site-packages/tornado-6.1.dist-info/METADATA create mode 100644 .venv/lib/python3.8/site-packages/tornado-6.1.dist-info/RECORD create mode 100644 .venv/lib/python3.8/site-packages/tornado-6.1.dist-info/WHEEL create mode 100644 .venv/lib/python3.8/site-packages/tornado-6.1.dist-info/top_level.txt create mode 100644 .venv/lib/python3.8/site-packages/tornado/__init__.py create mode 100644 .venv/lib/python3.8/site-packages/tornado/__pycache__/__init__.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/tornado/__pycache__/_locale_data.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/tornado/__pycache__/auth.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/tornado/__pycache__/autoreload.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/tornado/__pycache__/concurrent.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/tornado/__pycache__/curl_httpclient.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/tornado/__pycache__/escape.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/tornado/__pycache__/gen.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/tornado/__pycache__/http1connection.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/tornado/__pycache__/httpclient.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/tornado/__pycache__/httpserver.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/tornado/__pycache__/httputil.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/tornado/__pycache__/ioloop.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/tornado/__pycache__/iostream.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/tornado/__pycache__/locale.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/tornado/__pycache__/locks.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/tornado/__pycache__/log.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/tornado/__pycache__/netutil.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/tornado/__pycache__/options.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/tornado/__pycache__/process.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/tornado/__pycache__/queues.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/tornado/__pycache__/routing.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/tornado/__pycache__/simple_httpclient.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/tornado/__pycache__/tcpclient.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/tornado/__pycache__/tcpserver.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/tornado/__pycache__/template.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/tornado/__pycache__/testing.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/tornado/__pycache__/util.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/tornado/__pycache__/web.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/tornado/__pycache__/websocket.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/tornado/__pycache__/wsgi.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/tornado/_locale_data.py create mode 100644 .venv/lib/python3.8/site-packages/tornado/auth.py create mode 100644 .venv/lib/python3.8/site-packages/tornado/autoreload.py create mode 100644 .venv/lib/python3.8/site-packages/tornado/concurrent.py create mode 100644 .venv/lib/python3.8/site-packages/tornado/curl_httpclient.py create mode 100644 .venv/lib/python3.8/site-packages/tornado/escape.py create mode 100644 .venv/lib/python3.8/site-packages/tornado/gen.py create mode 100644 .venv/lib/python3.8/site-packages/tornado/http1connection.py create mode 100644 .venv/lib/python3.8/site-packages/tornado/httpclient.py create mode 100644 .venv/lib/python3.8/site-packages/tornado/httpserver.py create mode 100644 .venv/lib/python3.8/site-packages/tornado/httputil.py create mode 100644 .venv/lib/python3.8/site-packages/tornado/ioloop.py create mode 100644 .venv/lib/python3.8/site-packages/tornado/iostream.py create mode 100644 .venv/lib/python3.8/site-packages/tornado/locale.py create mode 100644 .venv/lib/python3.8/site-packages/tornado/locks.py create mode 100644 .venv/lib/python3.8/site-packages/tornado/log.py create mode 100644 .venv/lib/python3.8/site-packages/tornado/netutil.py create mode 100644 .venv/lib/python3.8/site-packages/tornado/options.py create mode 100644 .venv/lib/python3.8/site-packages/tornado/platform/__init__.py create mode 100644 .venv/lib/python3.8/site-packages/tornado/platform/__pycache__/__init__.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/tornado/platform/__pycache__/asyncio.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/tornado/platform/__pycache__/caresresolver.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/tornado/platform/__pycache__/twisted.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/tornado/platform/asyncio.py create mode 100644 .venv/lib/python3.8/site-packages/tornado/platform/caresresolver.py create mode 100644 .venv/lib/python3.8/site-packages/tornado/platform/twisted.py create mode 100644 .venv/lib/python3.8/site-packages/tornado/process.py create mode 100644 .venv/lib/python3.8/site-packages/tornado/py.typed create mode 100644 .venv/lib/python3.8/site-packages/tornado/queues.py create mode 100644 .venv/lib/python3.8/site-packages/tornado/routing.py create mode 100644 .venv/lib/python3.8/site-packages/tornado/simple_httpclient.py create mode 100755 .venv/lib/python3.8/site-packages/tornado/speedups.cpython-38-x86_64-linux-gnu.so create mode 100644 .venv/lib/python3.8/site-packages/tornado/tcpclient.py create mode 100644 .venv/lib/python3.8/site-packages/tornado/tcpserver.py create mode 100644 .venv/lib/python3.8/site-packages/tornado/template.py create mode 100644 .venv/lib/python3.8/site-packages/tornado/test/__main__.py create mode 100644 .venv/lib/python3.8/site-packages/tornado/test/__pycache__/__main__.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/tornado/test/__pycache__/asyncio_test.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/tornado/test/__pycache__/auth_test.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/tornado/test/__pycache__/autoreload_test.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/tornado/test/__pycache__/concurrent_test.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/tornado/test/__pycache__/curl_httpclient_test.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/tornado/test/__pycache__/escape_test.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/tornado/test/__pycache__/gen_test.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/tornado/test/__pycache__/http1connection_test.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/tornado/test/__pycache__/httpclient_test.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/tornado/test/__pycache__/httpserver_test.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/tornado/test/__pycache__/httputil_test.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/tornado/test/__pycache__/import_test.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/tornado/test/__pycache__/ioloop_test.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/tornado/test/__pycache__/iostream_test.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/tornado/test/__pycache__/locale_test.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/tornado/test/__pycache__/locks_test.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/tornado/test/__pycache__/log_test.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/tornado/test/__pycache__/netutil_test.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/tornado/test/__pycache__/options_test.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/tornado/test/__pycache__/process_test.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/tornado/test/__pycache__/queues_test.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/tornado/test/__pycache__/resolve_test_helper.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/tornado/test/__pycache__/routing_test.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/tornado/test/__pycache__/runtests.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/tornado/test/__pycache__/simple_httpclient_test.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/tornado/test/__pycache__/tcpclient_test.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/tornado/test/__pycache__/tcpserver_test.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/tornado/test/__pycache__/template_test.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/tornado/test/__pycache__/testing_test.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/tornado/test/__pycache__/twisted_test.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/tornado/test/__pycache__/util.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/tornado/test/__pycache__/util_test.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/tornado/test/__pycache__/web_test.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/tornado/test/__pycache__/websocket_test.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/tornado/test/__pycache__/wsgi_test.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/tornado/test/asyncio_test.py create mode 100644 .venv/lib/python3.8/site-packages/tornado/test/auth_test.py create mode 100644 .venv/lib/python3.8/site-packages/tornado/test/autoreload_test.py create mode 100644 .venv/lib/python3.8/site-packages/tornado/test/concurrent_test.py create mode 100644 .venv/lib/python3.8/site-packages/tornado/test/csv_translations/fr_FR.csv create mode 100644 .venv/lib/python3.8/site-packages/tornado/test/curl_httpclient_test.py create mode 100644 .venv/lib/python3.8/site-packages/tornado/test/escape_test.py create mode 100644 .venv/lib/python3.8/site-packages/tornado/test/gen_test.py create mode 100644 .venv/lib/python3.8/site-packages/tornado/test/gettext_translations/fr_FR/LC_MESSAGES/tornado_test.mo create mode 100644 .venv/lib/python3.8/site-packages/tornado/test/gettext_translations/fr_FR/LC_MESSAGES/tornado_test.po create mode 100644 .venv/lib/python3.8/site-packages/tornado/test/http1connection_test.py create mode 100644 .venv/lib/python3.8/site-packages/tornado/test/httpclient_test.py create mode 100644 .venv/lib/python3.8/site-packages/tornado/test/httpserver_test.py create mode 100644 .venv/lib/python3.8/site-packages/tornado/test/httputil_test.py create mode 100644 .venv/lib/python3.8/site-packages/tornado/test/import_test.py create mode 100644 .venv/lib/python3.8/site-packages/tornado/test/ioloop_test.py create mode 100644 .venv/lib/python3.8/site-packages/tornado/test/iostream_test.py create mode 100644 .venv/lib/python3.8/site-packages/tornado/test/locale_test.py create mode 100644 .venv/lib/python3.8/site-packages/tornado/test/locks_test.py create mode 100644 .venv/lib/python3.8/site-packages/tornado/test/log_test.py create mode 100644 .venv/lib/python3.8/site-packages/tornado/test/netutil_test.py create mode 100644 .venv/lib/python3.8/site-packages/tornado/test/options_test.cfg create mode 100644 .venv/lib/python3.8/site-packages/tornado/test/options_test.py create mode 100644 .venv/lib/python3.8/site-packages/tornado/test/options_test_types.cfg create mode 100644 .venv/lib/python3.8/site-packages/tornado/test/options_test_types_str.cfg create mode 100644 .venv/lib/python3.8/site-packages/tornado/test/process_test.py create mode 100644 .venv/lib/python3.8/site-packages/tornado/test/queues_test.py create mode 100644 .venv/lib/python3.8/site-packages/tornado/test/resolve_test_helper.py create mode 100644 .venv/lib/python3.8/site-packages/tornado/test/routing_test.py create mode 100644 .venv/lib/python3.8/site-packages/tornado/test/runtests.py create mode 100644 .venv/lib/python3.8/site-packages/tornado/test/simple_httpclient_test.py create mode 100644 .venv/lib/python3.8/site-packages/tornado/test/static/dir/index.html create mode 100644 .venv/lib/python3.8/site-packages/tornado/test/static/robots.txt create mode 100644 .venv/lib/python3.8/site-packages/tornado/test/static/sample.xml create mode 100644 .venv/lib/python3.8/site-packages/tornado/test/static/sample.xml.bz2 create mode 100644 .venv/lib/python3.8/site-packages/tornado/test/static/sample.xml.gz create mode 100644 .venv/lib/python3.8/site-packages/tornado/test/static_foo.txt create mode 100644 .venv/lib/python3.8/site-packages/tornado/test/tcpclient_test.py create mode 100644 .venv/lib/python3.8/site-packages/tornado/test/tcpserver_test.py create mode 100644 .venv/lib/python3.8/site-packages/tornado/test/template_test.py create mode 100644 .venv/lib/python3.8/site-packages/tornado/test/templates/utf8.html create mode 100644 .venv/lib/python3.8/site-packages/tornado/test/test.crt create mode 100644 .venv/lib/python3.8/site-packages/tornado/test/test.key create mode 100644 .venv/lib/python3.8/site-packages/tornado/test/testing_test.py create mode 100644 .venv/lib/python3.8/site-packages/tornado/test/twisted_test.py create mode 100644 .venv/lib/python3.8/site-packages/tornado/test/util.py create mode 100644 .venv/lib/python3.8/site-packages/tornado/test/util_test.py create mode 100644 .venv/lib/python3.8/site-packages/tornado/test/web_test.py create mode 100644 .venv/lib/python3.8/site-packages/tornado/test/websocket_test.py create mode 100644 .venv/lib/python3.8/site-packages/tornado/test/wsgi_test.py create mode 100644 .venv/lib/python3.8/site-packages/tornado/testing.py create mode 100644 .venv/lib/python3.8/site-packages/tornado/util.py create mode 100644 .venv/lib/python3.8/site-packages/tornado/web.py create mode 100644 .venv/lib/python3.8/site-packages/tornado/websocket.py create mode 100644 .venv/lib/python3.8/site-packages/tornado/wsgi.py create mode 100644 .venv/lib/python3.8/site-packages/traitlets-5.0.5.dist-info/COPYING.md create mode 100644 .venv/lib/python3.8/site-packages/traitlets-5.0.5.dist-info/INSTALLER create mode 100644 .venv/lib/python3.8/site-packages/traitlets-5.0.5.dist-info/METADATA create mode 100644 .venv/lib/python3.8/site-packages/traitlets-5.0.5.dist-info/RECORD create mode 100644 .venv/lib/python3.8/site-packages/traitlets-5.0.5.dist-info/WHEEL create mode 100644 .venv/lib/python3.8/site-packages/traitlets-5.0.5.dist-info/top_level.txt create mode 100644 .venv/lib/python3.8/site-packages/traitlets/__init__.py create mode 100644 .venv/lib/python3.8/site-packages/traitlets/__pycache__/__init__.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/traitlets/__pycache__/_version.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/traitlets/__pycache__/log.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/traitlets/__pycache__/traitlets.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/traitlets/_version.py create mode 100644 .venv/lib/python3.8/site-packages/traitlets/config/__init__.py create mode 100644 .venv/lib/python3.8/site-packages/traitlets/config/__pycache__/__init__.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/traitlets/config/__pycache__/application.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/traitlets/config/__pycache__/configurable.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/traitlets/config/__pycache__/loader.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/traitlets/config/__pycache__/manager.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/traitlets/config/__pycache__/sphinxdoc.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/traitlets/config/application.py create mode 100644 .venv/lib/python3.8/site-packages/traitlets/config/configurable.py create mode 100644 .venv/lib/python3.8/site-packages/traitlets/config/loader.py create mode 100644 .venv/lib/python3.8/site-packages/traitlets/config/manager.py create mode 100644 .venv/lib/python3.8/site-packages/traitlets/config/sphinxdoc.py create mode 100644 .venv/lib/python3.8/site-packages/traitlets/config/tests/__init__.py create mode 100644 .venv/lib/python3.8/site-packages/traitlets/config/tests/__pycache__/__init__.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/traitlets/config/tests/__pycache__/test_application.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/traitlets/config/tests/__pycache__/test_configurable.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/traitlets/config/tests/__pycache__/test_loader.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/traitlets/config/tests/test_application.py create mode 100644 .venv/lib/python3.8/site-packages/traitlets/config/tests/test_configurable.py create mode 100644 .venv/lib/python3.8/site-packages/traitlets/config/tests/test_loader.py create mode 100644 .venv/lib/python3.8/site-packages/traitlets/log.py create mode 100644 .venv/lib/python3.8/site-packages/traitlets/tests/__init__.py create mode 100644 .venv/lib/python3.8/site-packages/traitlets/tests/__pycache__/__init__.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/traitlets/tests/__pycache__/_warnings.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/traitlets/tests/__pycache__/test_traitlets.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/traitlets/tests/__pycache__/test_traitlets_enum.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/traitlets/tests/__pycache__/utils.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/traitlets/tests/_warnings.py create mode 100644 .venv/lib/python3.8/site-packages/traitlets/tests/test_traitlets.py create mode 100644 .venv/lib/python3.8/site-packages/traitlets/tests/test_traitlets_enum.py create mode 100644 .venv/lib/python3.8/site-packages/traitlets/tests/utils.py create mode 100644 .venv/lib/python3.8/site-packages/traitlets/traitlets.py create mode 100644 .venv/lib/python3.8/site-packages/traitlets/utils/__init__.py create mode 100644 .venv/lib/python3.8/site-packages/traitlets/utils/__pycache__/__init__.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/traitlets/utils/__pycache__/bunch.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/traitlets/utils/__pycache__/decorators.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/traitlets/utils/__pycache__/descriptions.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/traitlets/utils/__pycache__/getargspec.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/traitlets/utils/__pycache__/importstring.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/traitlets/utils/__pycache__/sentinel.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/traitlets/utils/bunch.py create mode 100644 .venv/lib/python3.8/site-packages/traitlets/utils/decorators.py create mode 100644 .venv/lib/python3.8/site-packages/traitlets/utils/descriptions.py create mode 100644 .venv/lib/python3.8/site-packages/traitlets/utils/getargspec.py create mode 100644 .venv/lib/python3.8/site-packages/traitlets/utils/importstring.py create mode 100644 .venv/lib/python3.8/site-packages/traitlets/utils/sentinel.py create mode 100644 .venv/lib/python3.8/site-packages/traitlets/utils/tests/__init__.py create mode 100644 .venv/lib/python3.8/site-packages/traitlets/utils/tests/__pycache__/__init__.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/traitlets/utils/tests/__pycache__/test_bunch.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/traitlets/utils/tests/__pycache__/test_decorators.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/traitlets/utils/tests/__pycache__/test_importstring.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/traitlets/utils/tests/test_bunch.py create mode 100644 .venv/lib/python3.8/site-packages/traitlets/utils/tests/test_decorators.py create mode 100644 .venv/lib/python3.8/site-packages/traitlets/utils/tests/test_importstring.py create mode 100644 .venv/lib/python3.8/site-packages/wcwidth-0.2.5.dist-info/INSTALLER create mode 100644 .venv/lib/python3.8/site-packages/wcwidth-0.2.5.dist-info/LICENSE create mode 100644 .venv/lib/python3.8/site-packages/wcwidth-0.2.5.dist-info/METADATA create mode 100644 .venv/lib/python3.8/site-packages/wcwidth-0.2.5.dist-info/RECORD create mode 100644 .venv/lib/python3.8/site-packages/wcwidth-0.2.5.dist-info/WHEEL create mode 100644 .venv/lib/python3.8/site-packages/wcwidth-0.2.5.dist-info/top_level.txt create mode 100644 .venv/lib/python3.8/site-packages/wcwidth-0.2.5.dist-info/zip-safe create mode 100644 .venv/lib/python3.8/site-packages/wcwidth/__init__.py create mode 100644 .venv/lib/python3.8/site-packages/wcwidth/__pycache__/__init__.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/wcwidth/__pycache__/table_wide.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/wcwidth/__pycache__/table_zero.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/wcwidth/__pycache__/unicode_versions.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/wcwidth/__pycache__/wcwidth.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/wcwidth/table_wide.py create mode 100644 .venv/lib/python3.8/site-packages/wcwidth/table_zero.py create mode 100644 .venv/lib/python3.8/site-packages/wcwidth/tests/__init__.py create mode 100644 .venv/lib/python3.8/site-packages/wcwidth/tests/__pycache__/__init__.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/wcwidth/tests/__pycache__/test_core.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/wcwidth/tests/test_core.py create mode 100644 .venv/lib/python3.8/site-packages/wcwidth/unicode_versions.py create mode 100644 .venv/lib/python3.8/site-packages/wcwidth/version.json create mode 100644 .venv/lib/python3.8/site-packages/wcwidth/wcwidth.py create mode 100644 .venv/lib/python3.8/site-packages/wrapt-1.12.1.dist-info/INSTALLER create mode 100644 .venv/lib/python3.8/site-packages/wrapt-1.12.1.dist-info/LICENSE create mode 100644 .venv/lib/python3.8/site-packages/wrapt-1.12.1.dist-info/METADATA create mode 100644 .venv/lib/python3.8/site-packages/wrapt-1.12.1.dist-info/RECORD create mode 100644 .venv/lib/python3.8/site-packages/wrapt-1.12.1.dist-info/WHEEL create mode 100644 .venv/lib/python3.8/site-packages/wrapt-1.12.1.dist-info/top_level.txt create mode 100644 .venv/lib/python3.8/site-packages/wrapt/__init__.py create mode 100644 .venv/lib/python3.8/site-packages/wrapt/__pycache__/__init__.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/wrapt/__pycache__/decorators.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/wrapt/__pycache__/importer.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/wrapt/__pycache__/wrappers.cpython-38.pyc create mode 100755 .venv/lib/python3.8/site-packages/wrapt/_wrappers.cpython-38-x86_64-linux-gnu.so create mode 100644 .venv/lib/python3.8/site-packages/wrapt/decorators.py create mode 100644 .venv/lib/python3.8/site-packages/wrapt/importer.py create mode 100644 .venv/lib/python3.8/site-packages/wrapt/wrappers.py create mode 100644 .venv/lib/python3.8/site-packages/zmq/__init__.pxd create mode 100644 .venv/lib/python3.8/site-packages/zmq/__init__.py create mode 100644 .venv/lib/python3.8/site-packages/zmq/__pycache__/__init__.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/zmq/__pycache__/_future.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/zmq/__pycache__/asyncio.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/zmq/__pycache__/decorators.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/zmq/__pycache__/error.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/zmq/_future.py create mode 100644 .venv/lib/python3.8/site-packages/zmq/asyncio.py create mode 100644 .venv/lib/python3.8/site-packages/zmq/auth/__init__.py create mode 100644 .venv/lib/python3.8/site-packages/zmq/auth/__pycache__/__init__.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/zmq/auth/__pycache__/asyncio.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/zmq/auth/__pycache__/base.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/zmq/auth/__pycache__/certs.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/zmq/auth/__pycache__/ioloop.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/zmq/auth/__pycache__/thread.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/zmq/auth/asyncio.py create mode 100644 .venv/lib/python3.8/site-packages/zmq/auth/base.py create mode 100644 .venv/lib/python3.8/site-packages/zmq/auth/certs.py create mode 100644 .venv/lib/python3.8/site-packages/zmq/auth/ioloop.py create mode 100644 .venv/lib/python3.8/site-packages/zmq/auth/thread.py create mode 100644 .venv/lib/python3.8/site-packages/zmq/backend/__init__.py create mode 100644 .venv/lib/python3.8/site-packages/zmq/backend/__pycache__/__init__.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/zmq/backend/__pycache__/select.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/zmq/backend/cffi/__init__.py create mode 100644 .venv/lib/python3.8/site-packages/zmq/backend/cffi/__pycache__/__init__.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/zmq/backend/cffi/__pycache__/_cffi.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/zmq/backend/cffi/__pycache__/_poll.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/zmq/backend/cffi/__pycache__/constants.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/zmq/backend/cffi/__pycache__/context.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/zmq/backend/cffi/__pycache__/devices.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/zmq/backend/cffi/__pycache__/error.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/zmq/backend/cffi/__pycache__/message.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/zmq/backend/cffi/__pycache__/socket.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/zmq/backend/cffi/__pycache__/utils.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/zmq/backend/cffi/_cdefs.h create mode 100644 .venv/lib/python3.8/site-packages/zmq/backend/cffi/_cffi.py create mode 100644 .venv/lib/python3.8/site-packages/zmq/backend/cffi/_poll.py create mode 100644 .venv/lib/python3.8/site-packages/zmq/backend/cffi/_verify.c create mode 100644 .venv/lib/python3.8/site-packages/zmq/backend/cffi/constants.py create mode 100644 .venv/lib/python3.8/site-packages/zmq/backend/cffi/context.py create mode 100644 .venv/lib/python3.8/site-packages/zmq/backend/cffi/devices.py create mode 100644 .venv/lib/python3.8/site-packages/zmq/backend/cffi/error.py create mode 100644 .venv/lib/python3.8/site-packages/zmq/backend/cffi/message.py create mode 100644 .venv/lib/python3.8/site-packages/zmq/backend/cffi/socket.py create mode 100644 .venv/lib/python3.8/site-packages/zmq/backend/cffi/utils.py create mode 100644 .venv/lib/python3.8/site-packages/zmq/backend/cython/__init__.pxd create mode 100644 .venv/lib/python3.8/site-packages/zmq/backend/cython/__init__.py create mode 100644 .venv/lib/python3.8/site-packages/zmq/backend/cython/__pycache__/__init__.cpython-38.pyc create mode 100755 .venv/lib/python3.8/site-packages/zmq/backend/cython/_device.cpython-38-x86_64-linux-gnu.so create mode 100755 .venv/lib/python3.8/site-packages/zmq/backend/cython/_poll.cpython-38-x86_64-linux-gnu.so create mode 100755 .venv/lib/python3.8/site-packages/zmq/backend/cython/_proxy_steerable.cpython-38-x86_64-linux-gnu.so create mode 100755 .venv/lib/python3.8/site-packages/zmq/backend/cython/_version.cpython-38-x86_64-linux-gnu.so create mode 100644 .venv/lib/python3.8/site-packages/zmq/backend/cython/checkrc.pxd create mode 100644 .venv/lib/python3.8/site-packages/zmq/backend/cython/constant_enums.pxi create mode 100755 .venv/lib/python3.8/site-packages/zmq/backend/cython/constants.cpython-38-x86_64-linux-gnu.so create mode 100644 .venv/lib/python3.8/site-packages/zmq/backend/cython/constants.pxi create mode 100755 .venv/lib/python3.8/site-packages/zmq/backend/cython/context.cpython-38-x86_64-linux-gnu.so create mode 100644 .venv/lib/python3.8/site-packages/zmq/backend/cython/context.pxd create mode 100755 .venv/lib/python3.8/site-packages/zmq/backend/cython/error.cpython-38-x86_64-linux-gnu.so create mode 100644 .venv/lib/python3.8/site-packages/zmq/backend/cython/libzmq.pxd create mode 100755 .venv/lib/python3.8/site-packages/zmq/backend/cython/message.cpython-38-x86_64-linux-gnu.so create mode 100644 .venv/lib/python3.8/site-packages/zmq/backend/cython/message.pxd create mode 100755 .venv/lib/python3.8/site-packages/zmq/backend/cython/socket.cpython-38-x86_64-linux-gnu.so create mode 100644 .venv/lib/python3.8/site-packages/zmq/backend/cython/socket.pxd create mode 100755 .venv/lib/python3.8/site-packages/zmq/backend/cython/utils.cpython-38-x86_64-linux-gnu.so create mode 100644 .venv/lib/python3.8/site-packages/zmq/backend/select.py create mode 100644 .venv/lib/python3.8/site-packages/zmq/decorators.py create mode 100644 .venv/lib/python3.8/site-packages/zmq/devices/__init__.py create mode 100644 .venv/lib/python3.8/site-packages/zmq/devices/__pycache__/__init__.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/zmq/devices/__pycache__/basedevice.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/zmq/devices/__pycache__/monitoredqueue.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/zmq/devices/__pycache__/monitoredqueuedevice.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/zmq/devices/__pycache__/proxydevice.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/zmq/devices/__pycache__/proxysteerabledevice.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/zmq/devices/basedevice.py create mode 100755 .venv/lib/python3.8/site-packages/zmq/devices/monitoredqueue.cpython-38-x86_64-linux-gnu.so create mode 100644 .venv/lib/python3.8/site-packages/zmq/devices/monitoredqueue.pxd create mode 100644 .venv/lib/python3.8/site-packages/zmq/devices/monitoredqueue.py create mode 100644 .venv/lib/python3.8/site-packages/zmq/devices/monitoredqueuedevice.py create mode 100644 .venv/lib/python3.8/site-packages/zmq/devices/proxydevice.py create mode 100644 .venv/lib/python3.8/site-packages/zmq/devices/proxysteerabledevice.py create mode 100644 .venv/lib/python3.8/site-packages/zmq/error.py create mode 100644 .venv/lib/python3.8/site-packages/zmq/eventloop/__init__.py create mode 100644 .venv/lib/python3.8/site-packages/zmq/eventloop/__pycache__/__init__.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/zmq/eventloop/__pycache__/_deprecated.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/zmq/eventloop/__pycache__/future.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/zmq/eventloop/__pycache__/ioloop.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/zmq/eventloop/__pycache__/zmqstream.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/zmq/eventloop/_deprecated.py create mode 100644 .venv/lib/python3.8/site-packages/zmq/eventloop/future.py create mode 100644 .venv/lib/python3.8/site-packages/zmq/eventloop/ioloop.py create mode 100644 .venv/lib/python3.8/site-packages/zmq/eventloop/minitornado/__init__.py create mode 100644 .venv/lib/python3.8/site-packages/zmq/eventloop/minitornado/__pycache__/__init__.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/zmq/eventloop/minitornado/__pycache__/concurrent.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/zmq/eventloop/minitornado/__pycache__/ioloop.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/zmq/eventloop/minitornado/__pycache__/log.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/zmq/eventloop/minitornado/__pycache__/stack_context.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/zmq/eventloop/minitornado/__pycache__/util.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/zmq/eventloop/minitornado/concurrent.py create mode 100644 .venv/lib/python3.8/site-packages/zmq/eventloop/minitornado/ioloop.py create mode 100644 .venv/lib/python3.8/site-packages/zmq/eventloop/minitornado/log.py create mode 100644 .venv/lib/python3.8/site-packages/zmq/eventloop/minitornado/platform/__init__.py create mode 100644 .venv/lib/python3.8/site-packages/zmq/eventloop/minitornado/platform/__pycache__/__init__.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/zmq/eventloop/minitornado/platform/__pycache__/auto.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/zmq/eventloop/minitornado/platform/__pycache__/common.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/zmq/eventloop/minitornado/platform/__pycache__/interface.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/zmq/eventloop/minitornado/platform/__pycache__/posix.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/zmq/eventloop/minitornado/platform/__pycache__/windows.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/zmq/eventloop/minitornado/platform/auto.py create mode 100644 .venv/lib/python3.8/site-packages/zmq/eventloop/minitornado/platform/common.py create mode 100644 .venv/lib/python3.8/site-packages/zmq/eventloop/minitornado/platform/interface.py create mode 100644 .venv/lib/python3.8/site-packages/zmq/eventloop/minitornado/platform/posix.py create mode 100644 .venv/lib/python3.8/site-packages/zmq/eventloop/minitornado/platform/windows.py create mode 100644 .venv/lib/python3.8/site-packages/zmq/eventloop/minitornado/stack_context.py create mode 100644 .venv/lib/python3.8/site-packages/zmq/eventloop/minitornado/util.py create mode 100644 .venv/lib/python3.8/site-packages/zmq/eventloop/zmqstream.py create mode 100644 .venv/lib/python3.8/site-packages/zmq/green/__init__.py create mode 100644 .venv/lib/python3.8/site-packages/zmq/green/__pycache__/__init__.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/zmq/green/__pycache__/core.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/zmq/green/__pycache__/device.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/zmq/green/__pycache__/poll.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/zmq/green/core.py create mode 100644 .venv/lib/python3.8/site-packages/zmq/green/device.py create mode 100644 .venv/lib/python3.8/site-packages/zmq/green/eventloop/__init__.py create mode 100644 .venv/lib/python3.8/site-packages/zmq/green/eventloop/__pycache__/__init__.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/zmq/green/eventloop/__pycache__/ioloop.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/zmq/green/eventloop/__pycache__/zmqstream.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/zmq/green/eventloop/ioloop.py create mode 100644 .venv/lib/python3.8/site-packages/zmq/green/eventloop/zmqstream.py create mode 100644 .venv/lib/python3.8/site-packages/zmq/green/poll.py create mode 100644 .venv/lib/python3.8/site-packages/zmq/log/__init__.py create mode 100644 .venv/lib/python3.8/site-packages/zmq/log/__main__.py create mode 100644 .venv/lib/python3.8/site-packages/zmq/log/__pycache__/__init__.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/zmq/log/__pycache__/__main__.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/zmq/log/__pycache__/handlers.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/zmq/log/handlers.py create mode 100644 .venv/lib/python3.8/site-packages/zmq/ssh/__init__.py create mode 100644 .venv/lib/python3.8/site-packages/zmq/ssh/__pycache__/__init__.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/zmq/ssh/__pycache__/forward.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/zmq/ssh/__pycache__/tunnel.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/zmq/ssh/forward.py create mode 100644 .venv/lib/python3.8/site-packages/zmq/ssh/tunnel.py create mode 100644 .venv/lib/python3.8/site-packages/zmq/sugar/__init__.py create mode 100644 .venv/lib/python3.8/site-packages/zmq/sugar/__pycache__/__init__.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/zmq/sugar/__pycache__/attrsettr.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/zmq/sugar/__pycache__/constants.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/zmq/sugar/__pycache__/context.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/zmq/sugar/__pycache__/frame.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/zmq/sugar/__pycache__/poll.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/zmq/sugar/__pycache__/socket.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/zmq/sugar/__pycache__/stopwatch.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/zmq/sugar/__pycache__/tracker.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/zmq/sugar/__pycache__/version.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/zmq/sugar/attrsettr.py create mode 100644 .venv/lib/python3.8/site-packages/zmq/sugar/constants.py create mode 100644 .venv/lib/python3.8/site-packages/zmq/sugar/context.py create mode 100644 .venv/lib/python3.8/site-packages/zmq/sugar/frame.py create mode 100644 .venv/lib/python3.8/site-packages/zmq/sugar/poll.py create mode 100644 .venv/lib/python3.8/site-packages/zmq/sugar/socket.py create mode 100644 .venv/lib/python3.8/site-packages/zmq/sugar/stopwatch.py create mode 100644 .venv/lib/python3.8/site-packages/zmq/sugar/tracker.py create mode 100644 .venv/lib/python3.8/site-packages/zmq/sugar/version.py create mode 100644 .venv/lib/python3.8/site-packages/zmq/tests/__init__.py create mode 100644 .venv/lib/python3.8/site-packages/zmq/tests/__pycache__/__init__.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/zmq/tests/__pycache__/conftest.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/zmq/tests/__pycache__/test_asyncio.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/zmq/tests/__pycache__/test_auth.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/zmq/tests/__pycache__/test_cffi_backend.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/zmq/tests/__pycache__/test_constants.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/zmq/tests/__pycache__/test_context.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/zmq/tests/__pycache__/test_cython.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/zmq/tests/__pycache__/test_decorators.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/zmq/tests/__pycache__/test_device.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/zmq/tests/__pycache__/test_draft.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/zmq/tests/__pycache__/test_error.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/zmq/tests/__pycache__/test_etc.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/zmq/tests/__pycache__/test_future.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/zmq/tests/__pycache__/test_imports.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/zmq/tests/__pycache__/test_includes.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/zmq/tests/__pycache__/test_ioloop.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/zmq/tests/__pycache__/test_log.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/zmq/tests/__pycache__/test_message.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/zmq/tests/__pycache__/test_monitor.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/zmq/tests/__pycache__/test_monqueue.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/zmq/tests/__pycache__/test_multipart.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/zmq/tests/__pycache__/test_pair.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/zmq/tests/__pycache__/test_poll.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/zmq/tests/__pycache__/test_proxy_steerable.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/zmq/tests/__pycache__/test_pubsub.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/zmq/tests/__pycache__/test_reqrep.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/zmq/tests/__pycache__/test_retry_eintr.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/zmq/tests/__pycache__/test_security.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/zmq/tests/__pycache__/test_socket.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/zmq/tests/__pycache__/test_ssh.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/zmq/tests/__pycache__/test_version.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/zmq/tests/__pycache__/test_win32_shim.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/zmq/tests/__pycache__/test_z85.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/zmq/tests/__pycache__/test_zmqstream.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/zmq/tests/conftest.py create mode 100644 .venv/lib/python3.8/site-packages/zmq/tests/test_asyncio.py create mode 100644 .venv/lib/python3.8/site-packages/zmq/tests/test_auth.py create mode 100644 .venv/lib/python3.8/site-packages/zmq/tests/test_cffi_backend.py create mode 100644 .venv/lib/python3.8/site-packages/zmq/tests/test_constants.py create mode 100644 .venv/lib/python3.8/site-packages/zmq/tests/test_context.py create mode 100644 .venv/lib/python3.8/site-packages/zmq/tests/test_cython.py create mode 100644 .venv/lib/python3.8/site-packages/zmq/tests/test_decorators.py create mode 100644 .venv/lib/python3.8/site-packages/zmq/tests/test_device.py create mode 100644 .venv/lib/python3.8/site-packages/zmq/tests/test_draft.py create mode 100644 .venv/lib/python3.8/site-packages/zmq/tests/test_error.py create mode 100644 .venv/lib/python3.8/site-packages/zmq/tests/test_etc.py create mode 100644 .venv/lib/python3.8/site-packages/zmq/tests/test_future.py create mode 100644 .venv/lib/python3.8/site-packages/zmq/tests/test_imports.py create mode 100644 .venv/lib/python3.8/site-packages/zmq/tests/test_includes.py create mode 100644 .venv/lib/python3.8/site-packages/zmq/tests/test_ioloop.py create mode 100644 .venv/lib/python3.8/site-packages/zmq/tests/test_log.py create mode 100644 .venv/lib/python3.8/site-packages/zmq/tests/test_message.py create mode 100644 .venv/lib/python3.8/site-packages/zmq/tests/test_monitor.py create mode 100644 .venv/lib/python3.8/site-packages/zmq/tests/test_monqueue.py create mode 100644 .venv/lib/python3.8/site-packages/zmq/tests/test_multipart.py create mode 100644 .venv/lib/python3.8/site-packages/zmq/tests/test_pair.py create mode 100644 .venv/lib/python3.8/site-packages/zmq/tests/test_poll.py create mode 100644 .venv/lib/python3.8/site-packages/zmq/tests/test_proxy_steerable.py create mode 100644 .venv/lib/python3.8/site-packages/zmq/tests/test_pubsub.py create mode 100644 .venv/lib/python3.8/site-packages/zmq/tests/test_reqrep.py create mode 100644 .venv/lib/python3.8/site-packages/zmq/tests/test_retry_eintr.py create mode 100644 .venv/lib/python3.8/site-packages/zmq/tests/test_security.py create mode 100644 .venv/lib/python3.8/site-packages/zmq/tests/test_socket.py create mode 100644 .venv/lib/python3.8/site-packages/zmq/tests/test_ssh.py create mode 100644 .venv/lib/python3.8/site-packages/zmq/tests/test_version.py create mode 100644 .venv/lib/python3.8/site-packages/zmq/tests/test_win32_shim.py create mode 100644 .venv/lib/python3.8/site-packages/zmq/tests/test_z85.py create mode 100644 .venv/lib/python3.8/site-packages/zmq/tests/test_zmqstream.py create mode 100644 .venv/lib/python3.8/site-packages/zmq/utils/__init__.py create mode 100644 .venv/lib/python3.8/site-packages/zmq/utils/__pycache__/__init__.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/zmq/utils/__pycache__/constant_names.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/zmq/utils/__pycache__/garbage.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/zmq/utils/__pycache__/interop.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/zmq/utils/__pycache__/jsonapi.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/zmq/utils/__pycache__/monitor.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/zmq/utils/__pycache__/sixcerpt.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/zmq/utils/__pycache__/strtypes.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/zmq/utils/__pycache__/win32.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/zmq/utils/__pycache__/z85.cpython-38.pyc create mode 100644 .venv/lib/python3.8/site-packages/zmq/utils/buffers.pxd create mode 100644 .venv/lib/python3.8/site-packages/zmq/utils/compiler.json create mode 100644 .venv/lib/python3.8/site-packages/zmq/utils/config.json create mode 100644 .venv/lib/python3.8/site-packages/zmq/utils/constant_names.py create mode 100644 .venv/lib/python3.8/site-packages/zmq/utils/garbage.py create mode 100644 .venv/lib/python3.8/site-packages/zmq/utils/getpid_compat.h create mode 100644 .venv/lib/python3.8/site-packages/zmq/utils/interop.py create mode 100644 .venv/lib/python3.8/site-packages/zmq/utils/ipcmaxlen.h create mode 100644 .venv/lib/python3.8/site-packages/zmq/utils/jsonapi.py create mode 100644 .venv/lib/python3.8/site-packages/zmq/utils/monitor.py create mode 100644 .venv/lib/python3.8/site-packages/zmq/utils/mutex.h create mode 100644 .venv/lib/python3.8/site-packages/zmq/utils/pyversion_compat.h create mode 100644 .venv/lib/python3.8/site-packages/zmq/utils/sixcerpt.py create mode 100644 .venv/lib/python3.8/site-packages/zmq/utils/strtypes.py create mode 100644 .venv/lib/python3.8/site-packages/zmq/utils/win32.py create mode 100644 .venv/lib/python3.8/site-packages/zmq/utils/z85.py create mode 100644 .venv/lib/python3.8/site-packages/zmq/utils/zmq_compat.h create mode 100644 .venv/lib/python3.8/site-packages/zmq/utils/zmq_constants.h create mode 120000 .venv/lib64 create mode 100644 .venv/pyvenv.cfg create mode 100644 .venv/share/jupyter/kernels/python3/kernel.json create mode 100644 .venv/share/jupyter/kernels/python3/logo-32x32.png create mode 100644 .venv/share/jupyter/kernels/python3/logo-64x64.png create mode 100644 .venv/share/man/man1/ipython.1.gz create mode 100644 .venv/share/python-wheels/CacheControl-0.12.6-py2.py3-none-any.whl create mode 100644 .venv/share/python-wheels/appdirs-1.4.4-py2.py3-none-any.whl create mode 100644 .venv/share/python-wheels/certifi-2020.4.5.1-py2.py3-none-any.whl create mode 100644 .venv/share/python-wheels/chardet-3.0.4-py2.py3-none-any.whl create mode 100644 .venv/share/python-wheels/colorama-0.4.3-py2.py3-none-any.whl create mode 100644 .venv/share/python-wheels/contextlib2-0.6.0-py2.py3-none-any.whl create mode 100644 .venv/share/python-wheels/distlib-0.3.0-py2.py3-none-any.whl create mode 100644 .venv/share/python-wheels/distro-1.5.0-py2.py3-none-any.whl create mode 100644 .venv/share/python-wheels/html5lib-1.0.1-py2.py3-none-any.whl create mode 100644 .venv/share/python-wheels/idna-2.9-py2.py3-none-any.whl create mode 100644 .venv/share/python-wheels/ipaddr-2.2.0-py2.py3-none-any.whl create mode 100644 .venv/share/python-wheels/lockfile-0.12.2-py2.py3-none-any.whl create mode 100644 .venv/share/python-wheels/msgpack-0.6.2-py2.py3-none-any.whl create mode 100644 .venv/share/python-wheels/packaging-20.3-py2.py3-none-any.whl create mode 100644 .venv/share/python-wheels/pep517-0.8.2-py2.py3-none-any.whl create mode 100644 .venv/share/python-wheels/pip-20.1.1-py2.py3-none-any.whl create mode 100644 .venv/share/python-wheels/pkg_resources-0.0.0-py2.py3-none-any.whl create mode 100644 .venv/share/python-wheels/progress-1.5-py2.py3-none-any.whl create mode 100644 .venv/share/python-wheels/pyparsing-2.4.7-py2.py3-none-any.whl create mode 100644 .venv/share/python-wheels/requests-2.23.0-py2.py3-none-any.whl create mode 100644 .venv/share/python-wheels/resolvelib-0.3.0-py2.py3-none-any.whl create mode 100644 .venv/share/python-wheels/retrying-1.3.3-py2.py3-none-any.whl create mode 100644 .venv/share/python-wheels/setuptools-44.0.0-py2.py3-none-any.whl create mode 100644 .venv/share/python-wheels/six-1.15.0-py2.py3-none-any.whl create mode 100644 .venv/share/python-wheels/toml-0.10.1-py2.py3-none-any.whl create mode 100644 .venv/share/python-wheels/urllib3-1.25.9-py2.py3-none-any.whl create mode 100644 .venv/share/python-wheels/webencodings-0.5.1-py2.py3-none-any.whl create mode 100644 .venv/share/python-wheels/wheel-0.34.2-py2.py3-none-any.whl create mode 100644 .vscode/settings.json create mode 100644 Prueba.py create mode 100644 prueba2.py diff --git a/.venv/bin/Activate.ps1 b/.venv/bin/Activate.ps1 new file mode 100644 index 00000000..2fb3852c --- /dev/null +++ b/.venv/bin/Activate.ps1 @@ -0,0 +1,241 @@ +<# +.Synopsis +Activate a Python virtual environment for the current PowerShell session. + +.Description +Pushes the python executable for a virtual environment to the front of the +$Env:PATH environment variable and sets the prompt to signify that you are +in a Python virtual environment. Makes use of the command line switches as +well as the `pyvenv.cfg` file values present in the virtual environment. + +.Parameter VenvDir +Path to the directory that contains the virtual environment to activate. The +default value for this is the parent of the directory that the Activate.ps1 +script is located within. + +.Parameter Prompt +The prompt prefix to display when this virtual environment is activated. By +default, this prompt is the name of the virtual environment folder (VenvDir) +surrounded by parentheses and followed by a single space (ie. '(.venv) '). + +.Example +Activate.ps1 +Activates the Python virtual environment that contains the Activate.ps1 script. + +.Example +Activate.ps1 -Verbose +Activates the Python virtual environment that contains the Activate.ps1 script, +and shows extra information about the activation as it executes. + +.Example +Activate.ps1 -VenvDir C:\Users\MyUser\Common\.venv +Activates the Python virtual environment located in the specified location. + +.Example +Activate.ps1 -Prompt "MyPython" +Activates the Python virtual environment that contains the Activate.ps1 script, +and prefixes the current prompt with the specified string (surrounded in +parentheses) while the virtual environment is active. + +.Notes +On Windows, it may be required to enable this Activate.ps1 script by setting the +execution policy for the user. You can do this by issuing the following PowerShell +command: + +PS C:\> 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/.venv/bin/activate b/.venv/bin/activate new file mode 100644 index 00000000..1c97ebd5 --- /dev/null +++ b/.venv/bin/activate @@ -0,0 +1,76 @@ +# 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/antonio/bin/CursoPythonDavidBombal/.venv" +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(.venv) " != x ] ; then + PS1="(.venv) ${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/.venv/bin/activate.csh b/.venv/bin/activate.csh new file mode 100644 index 00000000..09ae5b60 --- /dev/null +++ b/.venv/bin/activate.csh @@ -0,0 +1,37 @@ +# 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/antonio/bin/CursoPythonDavidBombal/.venv" + +set _OLD_VIRTUAL_PATH="$PATH" +setenv PATH "$VIRTUAL_ENV/bin:$PATH" + + +set _OLD_VIRTUAL_PROMPT="$prompt" + +if (! "$?VIRTUAL_ENV_DISABLE_PROMPT") then + if (".venv" != "") then + set env_name = ".venv" + else + if (`basename "VIRTUAL_ENV"` == "__") then + # special case for Aspen magic directories + # see 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/.venv/bin/activate.fish b/.venv/bin/activate.fish new file mode 100644 index 00000000..a82e75cf --- /dev/null +++ b/.venv/bin/activate.fish @@ -0,0 +1,75 @@ +# This file must be used with ". bin/activate.fish" *from fish* (http://fishshell.org) +# you cannot run it directly + +function deactivate -d "Exit virtualenv and return to normal shell environment" + # reset old environment variables + if test -n "$_OLD_VIRTUAL_PATH" + set -gx PATH $_OLD_VIRTUAL_PATH + set -e _OLD_VIRTUAL_PATH + end + if test -n "$_OLD_VIRTUAL_PYTHONHOME" + set -gx PYTHONHOME $_OLD_VIRTUAL_PYTHONHOME + set -e _OLD_VIRTUAL_PYTHONHOME + end + + if test -n "$_OLD_FISH_PROMPT_OVERRIDE" + functions -e fish_prompt + set -e _OLD_FISH_PROMPT_OVERRIDE + functions -c _old_fish_prompt fish_prompt + functions -e _old_fish_prompt + end + + set -e VIRTUAL_ENV + if test "$argv[1]" != "nondestructive" + # Self destruct! + functions -e deactivate + end +end + +# unset irrelevant variables +deactivate nondestructive + +set -gx VIRTUAL_ENV "/home/antonio/bin/CursoPythonDavidBombal/.venv" + +set -gx _OLD_VIRTUAL_PATH $PATH +set -gx PATH "$VIRTUAL_ENV/bin" $PATH + +# unset PYTHONHOME if set +if set -q PYTHONHOME + set -gx _OLD_VIRTUAL_PYTHONHOME $PYTHONHOME + set -e PYTHONHOME +end + +if test -z "$VIRTUAL_ENV_DISABLE_PROMPT" + # fish uses a function instead of an env var to generate the prompt. + + # save the current fish_prompt function as the function _old_fish_prompt + functions -c fish_prompt _old_fish_prompt + + # with the original prompt function renamed, we can override with our own. + function fish_prompt + # Save the return status of the last command + set -l old_status $status + + # Prompt override? + if test -n "(.venv) " + printf "%s%s" "(.venv) " (set_color normal) + else + # ...Otherwise, prepend env + set -l _checkbase (basename "$VIRTUAL_ENV") + if test $_checkbase = "__" + # special case for Aspen magic directories + # see 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/.venv/bin/easy_install b/.venv/bin/easy_install new file mode 100755 index 00000000..19616dc6 --- /dev/null +++ b/.venv/bin/easy_install @@ -0,0 +1,8 @@ +#!/home/antonio/bin/CursoPythonDavidBombal/.venv/bin/python3 +# -*- coding: utf-8 -*- +import re +import sys +from setuptools.command.easy_install import main +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/.venv/bin/easy_install-3.8 b/.venv/bin/easy_install-3.8 new file mode 100755 index 00000000..19616dc6 --- /dev/null +++ b/.venv/bin/easy_install-3.8 @@ -0,0 +1,8 @@ +#!/home/antonio/bin/CursoPythonDavidBombal/.venv/bin/python3 +# -*- coding: utf-8 -*- +import re +import sys +from setuptools.command.easy_install import main +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/.venv/bin/epylint b/.venv/bin/epylint new file mode 100755 index 00000000..d2e22854 --- /dev/null +++ b/.venv/bin/epylint @@ -0,0 +1,8 @@ +#!/home/antonio/bin/CursoPythonDavidBombal/.venv/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/.venv/bin/iptest b/.venv/bin/iptest new file mode 100755 index 00000000..ee04e805 --- /dev/null +++ b/.venv/bin/iptest @@ -0,0 +1,8 @@ +#!/home/antonio/bin/CursoPythonDavidBombal/.venv/bin/python +# -*- coding: utf-8 -*- +import re +import sys +from IPython.testing.iptestcontroller import main +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/.venv/bin/iptest3 b/.venv/bin/iptest3 new file mode 100755 index 00000000..ee04e805 --- /dev/null +++ b/.venv/bin/iptest3 @@ -0,0 +1,8 @@ +#!/home/antonio/bin/CursoPythonDavidBombal/.venv/bin/python +# -*- coding: utf-8 -*- +import re +import sys +from IPython.testing.iptestcontroller import main +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/.venv/bin/ipython b/.venv/bin/ipython new file mode 100755 index 00000000..ed3ccbf8 --- /dev/null +++ b/.venv/bin/ipython @@ -0,0 +1,8 @@ +#!/home/antonio/bin/CursoPythonDavidBombal/.venv/bin/python +# -*- coding: utf-8 -*- +import re +import sys +from IPython import start_ipython +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(start_ipython()) diff --git a/.venv/bin/ipython3 b/.venv/bin/ipython3 new file mode 100755 index 00000000..ed3ccbf8 --- /dev/null +++ b/.venv/bin/ipython3 @@ -0,0 +1,8 @@ +#!/home/antonio/bin/CursoPythonDavidBombal/.venv/bin/python +# -*- coding: utf-8 -*- +import re +import sys +from IPython import start_ipython +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(start_ipython()) diff --git a/.venv/bin/isort b/.venv/bin/isort new file mode 100755 index 00000000..31003f44 --- /dev/null +++ b/.venv/bin/isort @@ -0,0 +1,8 @@ +#!/home/antonio/bin/CursoPythonDavidBombal/.venv/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/.venv/bin/jupyter b/.venv/bin/jupyter new file mode 100755 index 00000000..a764bc19 --- /dev/null +++ b/.venv/bin/jupyter @@ -0,0 +1,8 @@ +#!/home/antonio/bin/CursoPythonDavidBombal/.venv/bin/python +# -*- coding: utf-8 -*- +import re +import sys +from jupyter_core.command import main +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/.venv/bin/jupyter-kernel b/.venv/bin/jupyter-kernel new file mode 100755 index 00000000..ef83da4e --- /dev/null +++ b/.venv/bin/jupyter-kernel @@ -0,0 +1,8 @@ +#!/home/antonio/bin/CursoPythonDavidBombal/.venv/bin/python +# -*- coding: utf-8 -*- +import re +import sys +from jupyter_client.kernelapp import main +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/.venv/bin/jupyter-kernelspec b/.venv/bin/jupyter-kernelspec new file mode 100755 index 00000000..d1e4bdad --- /dev/null +++ b/.venv/bin/jupyter-kernelspec @@ -0,0 +1,8 @@ +#!/home/antonio/bin/CursoPythonDavidBombal/.venv/bin/python +# -*- coding: utf-8 -*- +import re +import sys +from jupyter_client.kernelspecapp import KernelSpecApp +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(KernelSpecApp.launch_instance()) diff --git a/.venv/bin/jupyter-migrate b/.venv/bin/jupyter-migrate new file mode 100755 index 00000000..b67e6f25 --- /dev/null +++ b/.venv/bin/jupyter-migrate @@ -0,0 +1,8 @@ +#!/home/antonio/bin/CursoPythonDavidBombal/.venv/bin/python +# -*- coding: utf-8 -*- +import re +import sys +from jupyter_core.migrate import main +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/.venv/bin/jupyter-run b/.venv/bin/jupyter-run new file mode 100755 index 00000000..48b3df0a --- /dev/null +++ b/.venv/bin/jupyter-run @@ -0,0 +1,8 @@ +#!/home/antonio/bin/CursoPythonDavidBombal/.venv/bin/python +# -*- coding: utf-8 -*- +import re +import sys +from jupyter_client.runapp import RunApp +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(RunApp.launch_instance()) diff --git a/.venv/bin/jupyter-troubleshoot b/.venv/bin/jupyter-troubleshoot new file mode 100755 index 00000000..a9d59bce --- /dev/null +++ b/.venv/bin/jupyter-troubleshoot @@ -0,0 +1,8 @@ +#!/home/antonio/bin/CursoPythonDavidBombal/.venv/bin/python +# -*- coding: utf-8 -*- +import re +import sys +from jupyter_core.troubleshoot import main +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/.venv/bin/pip b/.venv/bin/pip new file mode 100755 index 00000000..3a931e15 --- /dev/null +++ b/.venv/bin/pip @@ -0,0 +1,8 @@ +#!/home/antonio/bin/CursoPythonDavidBombal/.venv/bin/python3 +# -*- 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/.venv/bin/pip3 b/.venv/bin/pip3 new file mode 100755 index 00000000..3a931e15 --- /dev/null +++ b/.venv/bin/pip3 @@ -0,0 +1,8 @@ +#!/home/antonio/bin/CursoPythonDavidBombal/.venv/bin/python3 +# -*- 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/.venv/bin/pip3.8 b/.venv/bin/pip3.8 new file mode 100755 index 00000000..3a931e15 --- /dev/null +++ b/.venv/bin/pip3.8 @@ -0,0 +1,8 @@ +#!/home/antonio/bin/CursoPythonDavidBombal/.venv/bin/python3 +# -*- 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/.venv/bin/pygmentize b/.venv/bin/pygmentize new file mode 100755 index 00000000..c9efa388 --- /dev/null +++ b/.venv/bin/pygmentize @@ -0,0 +1,8 @@ +#!/home/antonio/bin/CursoPythonDavidBombal/.venv/bin/python +# -*- coding: utf-8 -*- +import re +import sys +from pygments.cmdline import main +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/.venv/bin/pylint b/.venv/bin/pylint new file mode 100755 index 00000000..9620c70b --- /dev/null +++ b/.venv/bin/pylint @@ -0,0 +1,8 @@ +#!/home/antonio/bin/CursoPythonDavidBombal/.venv/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/.venv/bin/pyreverse b/.venv/bin/pyreverse new file mode 100755 index 00000000..3423935e --- /dev/null +++ b/.venv/bin/pyreverse @@ -0,0 +1,8 @@ +#!/home/antonio/bin/CursoPythonDavidBombal/.venv/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/.venv/bin/python b/.venv/bin/python new file mode 120000 index 00000000..b8a0adbb --- /dev/null +++ b/.venv/bin/python @@ -0,0 +1 @@ +python3 \ No newline at end of file diff --git a/.venv/bin/python3 b/.venv/bin/python3 new file mode 120000 index 00000000..ae65fdaa --- /dev/null +++ b/.venv/bin/python3 @@ -0,0 +1 @@ +/usr/bin/python3 \ No newline at end of file diff --git a/.venv/bin/symilar b/.venv/bin/symilar new file mode 100755 index 00000000..3c920228 --- /dev/null +++ b/.venv/bin/symilar @@ -0,0 +1,8 @@ +#!/home/antonio/bin/CursoPythonDavidBombal/.venv/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/.venv/lib/python3.8/site-packages/IPython/__init__.py b/.venv/lib/python3.8/site-packages/IPython/__init__.py new file mode 100644 index 00000000..4fb77107 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/IPython/__init__.py @@ -0,0 +1,152 @@ +# encoding: utf-8 +""" +IPython: tools for interactive and parallel computing in Python. + +https://ipython.org +""" +#----------------------------------------------------------------------------- +# Copyright (c) 2008-2011, IPython Development Team. +# Copyright (c) 2001-2007, Fernando Perez +# Copyright (c) 2001, Janko Hauser +# Copyright (c) 2001, Nathaniel Gray +# +# Distributed under the terms of the Modified BSD License. +# +# The full license is in the file COPYING.txt, distributed with this software. +#----------------------------------------------------------------------------- + +#----------------------------------------------------------------------------- +# Imports +#----------------------------------------------------------------------------- + +import os +import sys + +#----------------------------------------------------------------------------- +# Setup everything +#----------------------------------------------------------------------------- + +# Don't forget to also update setup.py when this changes! +if sys.version_info < (3, 6): + raise ImportError( +""" +IPython 7.10+ supports Python 3.6 and above. +When using Python 2.7, please install IPython 5.x LTS Long Term Support version. +Python 3.3 and 3.4 were supported up to IPython 6.x. +Python 3.5 was supported with IPython 7.0 to 7.9. + +See IPython `README.rst` file for more information: + + https://github.com/ipython/ipython/blob/master/README.rst + +""") + +# Make it easy to import extensions - they are always directly on pythonpath. +# Therefore, non-IPython modules can be added to extensions directory. +# This should probably be in ipapp.py. +sys.path.append(os.path.join(os.path.dirname(__file__), "extensions")) + +#----------------------------------------------------------------------------- +# Setup the top level names +#----------------------------------------------------------------------------- + +from .core.getipython import get_ipython +from .core import release +from .core.application import Application +from .terminal.embed import embed + +from .core.interactiveshell import InteractiveShell +from .testing import test +from .utils.sysinfo import sys_info +from .utils.frame import extract_module_locals + +# Release data +__author__ = '%s <%s>' % (release.author, release.author_email) +__license__ = release.license +__version__ = release.version +version_info = release.version_info + +def embed_kernel(module=None, local_ns=None, **kwargs): + """Embed and start an IPython kernel in a given scope. + + If you don't want the kernel to initialize the namespace + from the scope of the surrounding function, + and/or you want to load full IPython configuration, + you probably want `IPython.start_kernel()` instead. + + Parameters + ---------- + module : types.ModuleType, optional + The module to load into IPython globals (default: caller) + local_ns : dict, optional + The namespace to load into IPython user namespace (default: caller) + + kwargs : various, optional + Further keyword args are relayed to the IPKernelApp constructor, + allowing configuration of the Kernel. Will only have an effect + on the first embed_kernel call for a given process. + """ + + (caller_module, caller_locals) = extract_module_locals(1) + if module is None: + module = caller_module + if local_ns is None: + local_ns = caller_locals + + # Only import .zmq when we really need it + from ipykernel.embed import embed_kernel as real_embed_kernel + real_embed_kernel(module=module, local_ns=local_ns, **kwargs) + +def start_ipython(argv=None, **kwargs): + """Launch a normal IPython instance (as opposed to embedded) + + `IPython.embed()` puts a shell in a particular calling scope, + such as a function or method for debugging purposes, + which is often not desirable. + + `start_ipython()` does full, regular IPython initialization, + including loading startup files, configuration, etc. + much of which is skipped by `embed()`. + + This is a public API method, and will survive implementation changes. + + Parameters + ---------- + + argv : list or None, optional + If unspecified or None, IPython will parse command-line options from sys.argv. + To prevent any command-line parsing, pass an empty list: `argv=[]`. + user_ns : dict, optional + specify this dictionary to initialize the IPython user namespace with particular values. + kwargs : various, optional + Any other kwargs will be passed to the Application constructor, + such as `config`. + """ + from IPython.terminal.ipapp import launch_new_instance + return launch_new_instance(argv=argv, **kwargs) + +def start_kernel(argv=None, **kwargs): + """Launch a normal IPython kernel instance (as opposed to embedded) + + `IPython.embed_kernel()` puts a shell in a particular calling scope, + such as a function or method for debugging purposes, + which is often not desirable. + + `start_kernel()` does full, regular IPython initialization, + including loading startup files, configuration, etc. + much of which is skipped by `embed()`. + + Parameters + ---------- + + argv : list or None, optional + If unspecified or None, IPython will parse command-line options from sys.argv. + To prevent any command-line parsing, pass an empty list: `argv=[]`. + user_ns : dict, optional + specify this dictionary to initialize the IPython user namespace with particular values. + kwargs : various, optional + Any other kwargs will be passed to the Application constructor, + such as `config`. + """ + from IPython.kernel.zmq.kernelapp import launch_new_instance + return launch_new_instance(argv=argv, **kwargs) diff --git a/.venv/lib/python3.8/site-packages/IPython/__main__.py b/.venv/lib/python3.8/site-packages/IPython/__main__.py new file mode 100644 index 00000000..d5123f33 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/IPython/__main__.py @@ -0,0 +1,14 @@ +# encoding: utf-8 +"""Terminal-based IPython entry point. +""" +#----------------------------------------------------------------------------- +# Copyright (c) 2012, IPython Development Team. +# +# Distributed under the terms of the Modified BSD License. +# +# The full license is in the file COPYING.txt, distributed with this software. +#----------------------------------------------------------------------------- + +from IPython import start_ipython + +start_ipython() diff --git a/.venv/lib/python3.8/site-packages/IPython/__pycache__/__init__.cpython-38.pyc b/.venv/lib/python3.8/site-packages/IPython/__pycache__/__init__.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b5732f06a5483b5c3025929efd630f81667e2837 GIT binary patch literal 4659 zcmeHLPjB4D6(_kX?Rq6yl4VI&>pIgmX}zdKrEwCWLK@USRaA&07?lbGObd$3ncbyD za@ZMC>op`GsC(|Ummcb)ze4Z*3O(@JOZ^pcX@B#`U9D>;Xwgf6mb)Cz4Cl>z^Zxwa z41c+_)Uj~cpa0eW^M+;p%`|4O78*ant^baKTb{*j?!>ld)6?-B;XH2e#+jwQCz`zZ z%>J#7p1D8G3mavN%C@-n+~#x7o#(b~@p;~gJIR8#K=pRKm@IiqRKFHqPnNx9s(0d* zWYt@x`a*moS@YJYz8K$3*1dJAFU1?lrngD;>+!8*%iBVISu8#N2JUb6oej&ojoP=o zJ1F1s7|Mp%;2V5}ul~;VzRfrJ4Zeojcla%Sldq%pUG5xP-L0pOI)@L(`B0|&ESECY ztS=Rd(p;z@%%gL`f|Ro?P(d7vn1wRQiabgO7{V$#x6>Ksd8YSwccYAEa-|w{UP6u5 zQP+9d!1Luiir_QbvL@Wvp8Lahf53E+Wm4t3o{QacKO}}hPo4|6^JpkiR%pYoV#eNc z_qJIUi$DvApmT`D>IJY5+$Ze8$uWB%G5$oTgdJDYvvZ+zBvZFj&vMVbM{Mr7@3WCm zVj_p&tjM5;>69P3PiBZdV530Kj2%V!a5{9)eb-R#xj%wNj)j=MIQ_-J{hxk%;3}P; zvVIf`QgI@|HcFxGB*-D#ey785O;kC+)J4yQz9(9pK6|n3?IwYSiFU81?sUqIc#@0M zEL6XQs;#bFE(}EO*JeSpr39(Yyt$ucaTF47H0MOp6C9P5!zs0=pFrW=sBO?(;uoev!N z*MX6p3<`%(Icihop9z)1Z{e*08^E1YrbC&*wT!ZOB(|$B46xpVtGX$BEy`UG5E6UT_>s?y1U&(v7drDCu0zR|Chlt)pz+E)S zurs}=S=o;v{KuKl?x$qV6V$hv%#7qgOyi8gPN123JTya+11heqh_!Mj=^SmJ~_AG4W%#LnySa?5s?99jQ9% z7iTHEPB~xMtZYv#&~2zC5O~XghRSnXB2m}T+nra-c&HT=<$R?@Z>ch59qrR*74_b# z5<%?Ga(!W`8=(K<{oOptcC#qkDN;nunczF4p%C%TUdTu9?VUZ@t^Ih{2eL%D@4MNU z#5e%CHu6~Oi+0;?n!B-R)4R|tbaI&l)5J~aat9U4*j8d+IzSGmZ}G;371{x-cRbk_k*OpaWucD1iy6a?vXW14ES+%E+QC!qG4SWdsTP zfPAbW$50(9;KMAoomSvbCjcWMmjWpsXtNC;ACO#=^f?8(8Qh7|FfItkOeB)@24RsT zO(H``z2fiNOyptZkcn9t;BYFaK8vyps_c!~=|o>M7r#U?T z`^bcjF4Vc%lSB!&0EtL*5|xF+ARPd^u1xdQkVoSX>*oN6I6|aB(?>FW6XGE|6sgWc z81*AaKOHzx8i@rXV>^OeodDl=;wTk0bVAi8K_G3qhFv8f0jUI>3#22Htj4dBn%SUf zY;yt)g`~iNEFY7g`|Q-r^W)EceOk?B(C{k}wGw>{RDp60>KZ^-Xup=&CM)_EfTcao zj2E8=aWPT#zk#s#u{v2{Yz4=pu%4jBT>i|26l+()L>g5yQy|Bx*n4;NF z#Rw<@r$+#nO{1!=<89O{bCCg)2$4nnP}SVOa1dL@E5 zy0pO>YYRwp3(x-&iJmpS9EmDmrhIPJ^B)7!%%0$Dic8fBzs|7qe;hGrh3kI+N7PNk zGr<8sh00f#w7SmGQP-yb+hxo5 zxeR^3bfhjD$PwjYeNLq_R=IGPn6vQ#&JwC@W_NLtNMB%MqsqnViTz>_#bw9$>$YFE zAQeuqqFnI(x(fZYYPFc&iH3aI2NDF6W@ijRCL!={e^hOJKQ@O^y^W%Ivu(Fq9ow;; ae>7L_%rDyXbLwYf#hy1mr}I|l_CEmt;EEpr literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/IPython/__pycache__/__main__.cpython-38.pyc b/.venv/lib/python3.8/site-packages/IPython/__pycache__/__main__.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e1f8147e0cc2709626ba00f7e6889257c62b338b GIT binary patch literal 249 zcmWIL<>g`k0>*}G@fR2w7#@Q-$bbpRaRB0CDIk%;5XF$fn8K99n9CH!#K@4!)Xc!h zkis0ypvh9D5|Ub!o0*rGqnngioSLHG8Bkf0k)NlKnpaX(sZfxgnOCC6^%7_bgC^rG z-r|zPqLTQ`0`;wGAgfn06tMs)F!9Soza+OnzaX{bYB9)uU7 zn3gK9Km%v8L?T%7vCr}4|9<=Z@$rmcqo02?Ul<`jr{v$3V)7h&c!2>(O@IQ^w5B*F znwg|dD1j6*otmu9OkU@d$OLkke`Pq!pnwt{ePfb-Dxf$gz%IyQwtqFd=#=5naU+zC z*!fzt*IVHs@Yb1LM7360#U0qRb9XR-vcj(6p6}3dFdq^9i6j1F?9t!T~|8GU)B>1+@jq=|4ML8Bt z1Fmfvtnb2DPUet5c>E_)&xfdVr~(=@cP9PxRX)Qo7KcjsPW;hSoWifuRW$voSN(FZ ylUWJNZ6~E(p0%(&J-fbH{Uux-(5rqomgk3?o=tBWPB5f-NguO0ODX%E7JmSIDy)D2 literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/IPython/__pycache__/conftest.cpython-38.pyc b/.venv/lib/python3.8/site-packages/IPython/__pycache__/conftest.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..53881f030f0ff319c5cbeea1a0d201e4b82cfb18 GIT binary patch literal 1919 zcmZuxTZJGYPP4lsjA-H zSvDYU@NNIY%wztL5B2I({(<=9S2eRSh}HC|Q|Hv>T)uOj4F-vWL4N%s|0{BwKh5IZ z;bZYVe)&5HbttKvY%`OL*tMIvcJ?yQ&VJ_GImiM#hgnEn>Q&Jq&SK(Fp9Zg-tjGL$ zLPHwS_{ya{n!Iu@Nw!1ZqdTQq7<{=wiIyg<9I-^@}V2d+(LqJDF z2dZf*SsK~(@W7b=2mJCI5K5?9IScXL`B|teuyHdKY9)@(@~Z z)W0Gx-3u451ry=o20ZlPArlK;7u9~Pm?%ocPuSBLtExjN!?LNT{Ad(qx1qG#cKN^i zq}eA-G_zjLYpII5WIDd)gt0aoQZ_BRO68lovVr7_wqkiJnnkNdo;@!DY}J9i@UcWK!~`J{-AOAj_s@SyXhY=_D)7k?Ua+VyrVlc>toE z6`^E}uq$^H@Jpinc|hF zLS=nf!ks#=c+F(iYl|Z$@^V4{>rYrWM)x_)k|Bsg62MQS;7U_;*Te8eZ=Ki$W1N^1 z)G5rT-j%m<*XS(Do1?p2d4LZ%Q`c}P1Z<-7M^6}>DOsv!EZvq_Dwh(NNXw$C(o=3A z0lrlod^$>-nx)f5q_in*!6YfhqfIYx;b>cN_)l4jG~IzoBUgK@rrI|+oQy*8F@(B@ zC^emGJB1`8M!W@9mJ*p)6mlI*t4_{v)|afBYVUu7_I8-c zdz{O_{wX4Y7%OgYQ@v3J7Wm;si*fA|q^)H-!U@Oksw7=ID zkwa9ceBym0iAQzvXlPfl aZ_WGiBalsLZmHY%;z6GzNfO4xc<>Lji{hUE literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/IPython/__pycache__/consoleapp.cpython-38.pyc b/.venv/lib/python3.8/site-packages/IPython/__pycache__/consoleapp.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8d7b6284ca2bb7f8fa785a41efd275c9063e882d GIT binary patch literal 487 zcmZ{hu};G<5Qd#Jv{6JKfbB+#)D$5^7lc?@0I6l5OX|i)W9rye>`>aNFTgV}^Fj<+ znfeMW;7|}C#7TF$vrhN@=eugRBjU_kJtvPIAuo0D(*jqVIybv6Fft;{W4`cmf8=`v zeb!(B+j?-hdvA)ykg(Q(bi(CDG{|@kRzXg=w9a8d)7hLB%s{GgO)Z~r!R-R(+-9Hz zgR{$p&6JE&C5;kDwFaJRRag^8YlkNtuL|4*xm*o1gz?}0F=z*&Q-q8fm>^1Es0&P~ zMFxh;6u&5N81Ki|ssxj%(!n<*xG7W)x20ZKERs}kl=hb%X)IC}ul^*?0%pE|shR literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/IPython/__pycache__/display.cpython-38.pyc b/.venv/lib/python3.8/site-packages/IPython/__pycache__/display.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9bba0c1ea308c593894e891e16d81d264d647c96 GIT binary patch literal 268 zcmWIL<>g`k0>*}G@pViL439w^WB?RnZ~)?B2_TWe5XF$fn8K997y_Z0fHZS3gC1^NY<1-hkq z1&PVosVTbU8L6o`y5`9#V+5L03^I&`kAo2a DUu;Mz literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/IPython/__pycache__/frontend.cpython-38.pyc b/.venv/lib/python3.8/site-packages/IPython/__pycache__/frontend.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..1e61e4a7f256f2495b50dc793c4be35d93e89d08 GIT binary patch literal 1003 zcmZWoO>fjN5OuQIkESi^kpn_=WTkEv5E7RP!I1+9sYR7?*?41bu<9To9J^ADDaZKazhGveEaD2iHS3IP;MM7Vjem zXM~04WPC_}1cb!rg;3x$C@M;aFU)DaTv5X;*YyBB#K`+1+ye-VS$_#8huaJjcaX?y)4OA1!Z@7%_G8Ud> zg;O#+h3u2dfFfn)xKW~{G8><^frX?FiICN^l-lvR*2@+&zOJoU&D{4`%r6{k!&!nK^*h3{r207~BMJ$~t zYaXw(@fD{Cq3f#xD8iW1W3&u&4wXSII7{L`=sbBp4w}dx8HY{l(mTy+$(uv(*yXl# z^X&qs-iz0E(|VIZCvSnh&N(lE@yhU=A^})Y=Dcefo+VEcc!NUrS- zmToUzhRUF8$>#BY5_rA$YHp6Yybt3=DZP16rff`QQ!Qin@V21n0~&C| zafK*?Ijpb>X^4C*sv^~+Jr&a!1tR1<5r4q2>hYNOdGZNI0qqO)HsSGwj}Cb1qjVtp zV!%={*yje28}i`_n;XC!RUxtO1drCNLLbFadP#1>q=c`rBfA=s?o;TEd2?W3Z6|-8$oeB#qA#XspjiS zv_sGG3gWU}?moXL1(_eC%t-^J`BIQFw`3tiO}J=`C~_w_v9c~i$4VY$XBl~|*Tj~3 z4QdVo$Qz>-nb+Ehh1RP%k+pRq=h^>6*+%lEaCW{YQu-ah!`;(1ckftQS3%Q% zXW(+7H3f~8G)9}<=(wOwIuUKcn0J*iaAnv<^QM`ew0*|7E*Jx#t!)!;8CYWt1{3N1 z4sY#bWit!jslAT|zExoSKcWe{72Ng@IZJ!YzXy7n(4`01t;qB=b<_~zmH>iz6i;mk8;&9+T0 l4k|7Y)Y}IzL~(*f_yk87|BfPzaDe}ugoinfVw7UYqrX9}_bLDY literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/IPython/__pycache__/nbconvert.cpython-38.pyc b/.venv/lib/python3.8/site-packages/IPython/__pycache__/nbconvert.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e773f60e67ddbd0d6238fad14586cea4c92cb966 GIT binary patch literal 582 zcmZWmJ#W-N5Zzt-e9l26kSHjpz2bZbfzm{X5(*-ufDmpRpJ$1ect5ne&T&^EQ6hc_ ze~7{@6@P&yjPFPkDI?A7&fC?S_cZSh4`+;mfBjW`7mWQLo7<66^O7>WqJpes$We5> z;S}>9Lh{d3%#Im~Q#L=?p3F{Lr6F3- zwK9atwZ6-unW3hdBXIOb~^Npk?!8c{5mG{=q^I=+5Xq&1c zd=rLz^h3IXr|q!v@ikW;RTqjt#`MmlPw3f?+Zv{OB>ZH4-0iOXeZGv^EuC_U-i%Hq zF4nD--QuXh_0yw^FU$YT%NuEh+YI^fp6mrDrtpYLn&teycpy?PuF_0!!Nk=+H|wv7 literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/IPython/__pycache__/nbformat.cpython-38.pyc b/.venv/lib/python3.8/site-packages/IPython/__pycache__/nbformat.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..72a3d5da70555387f79c075d80e9af8b03d9f7f4 GIT binary patch literal 576 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 kYp(ZyQ=|D^%4Kl_jg8Vte{Haps5c zhdAWQiNCOyWzu#jmS*gE^E_|H{&0St5nS}!ui}mo@_P*aUm*rB(OivA5KaUYtf8FZ z9yCk`JfI^MHld#IiH>+gi44RiHMdXnjTP|%2=jFCewW` zT@t~r$Sm8v%C2gq!5h$}YCRgP%IbDgTH&BFx+}d}sYdxNY?QCTGy-0~+xptH`Pzfh zow45K*&l41yq(b@#H;O$4g0!pjOZIVOh=86h^zKyr{32Ru1__tp+mv)MnYXWSV`G} zke!uP>7@Xt+Dbks!t?xT4xda9t~Nb(a*&75)@WG!%Cycj5>)HFEJeP1bW+KWNuK`W zVUvNg6_2#C*4SNkV$Y^STol4oMS+~H8g`k0>*}G@gVv!h(HF6K#l_t7qb9~6oz01O-8?!3`HPe1o6vKza+OnzaXPO2Tq$j?B`005(vA?*MF literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/IPython/core/__pycache__/alias.cpython-38.pyc b/.venv/lib/python3.8/site-packages/IPython/core/__pycache__/alias.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..23f8bef3e27839ca8af5addaa8deb73eea1b0adb GIT binary patch literal 7058 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 literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/IPython/core/__pycache__/async_helpers.cpython-38.pyc b/.venv/lib/python3.8/site-packages/IPython/core/__pycache__/async_helpers.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f9497c6f9b7705046065ff21b393ca08a628fcbf GIT binary patch literal 5451 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 literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/IPython/core/__pycache__/autocall.cpython-38.pyc b/.venv/lib/python3.8/site-packages/IPython/core/__pycache__/autocall.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ba2bcfe110baf76920857de881ed925efa6c37bb GIT binary patch literal 2081 zcma)6-EJF26y9C`)=6jx0U-op?owBYEx|>hAe8cxDnhtHO@-u}(Rk;$JMnmDJF|{s zD;G%Q0eAtV_A)Po&`MnK7F==8tZf|9N{lqeb7qfc&YbW2&az?ptywHGF;H6N3LG06%Z^WGd1BH|Y%FwI6qp$69=2Nd+1FNyls&d0eGV4=Be1DR zrC}#vVU8Q8i5UyWzSoo4IYzX4CI{C#pwWsks5;QY zBEofGn;7=@=iPjqbu*P6OwvrmBajEv1VA4=h~@N?2cwJb0=q6@*ImA$lg)}I=PFe> z=X-Ri&nBGju9dN~4ESHEh6qD6|Bd~mkU;}r69fQE|ei3jl?bC4zb4(X@=7=8$Dbe1pXn zxkn1{=zT`^UVERtn5dj#%b?$T?SDwwd;11 zj@TkY_u9K;w#mFh=5>(0jUPV6>F9QZEUHG9_HMyN%sa&CK0tE=uDb8fAvQPyt5MwT z|M25_hVwtkTQy;}#F3!eCn)e^3Lr@bC_K2xw2D=(XI@PpOCflyPJ~4ak%!K^z6+PF zm~=7%$oL2wIB52e4UAbz@p#Bi?F28=AkImJfU!OdVLitV_yo7?R5=XE5zzGrgq!d| z*vsa~*gXkDG0}OuOzh~*?d3fz6?MY1fP4Egx=DhHCqaLQ5-$_tCiQf%JNQ>538B*8 zSbNwSh+c98?6)`_=`;wN;r#volz)vN;ZeKxT8_Mt9=mwx7t7<39!*O-Jv@fERn$x6 gd4YS{_|I!Ou6je!{IcvcUlIL1+o~UJ?`}8$0iG%I!vFvP literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/IPython/core/__pycache__/builtin_trap.cpython-38.pyc b/.venv/lib/python3.8/site-packages/IPython/core/__pycache__/builtin_trap.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..78edd1817ea65fc177d1a4a11bd9b6930666c9a2 GIT binary patch literal 2854 zcmb7G&5qne5bm};UeDiVSwaGcfDu73KxP2}iBN(PfuEryGK|BLv! z&DgK>uzY!VxQtOq2+1NQxpXofIk>x-JMib2%}JV>G%xP-Tff0#Ht6xPb9Iz&rP~u7Z)OV5!Hv8y zah|AzRxDo}50^2D4uoP6hsW>~RypOm5T8~rznx39mF7wgp15ToL>>>75M@gUm@vs` z-Vx&NB+jaTo-p0S`>go=(uNt1H^%As+$0~z$)1wu4tA8v&Ye%>!Taa;?rq%o>d@?r z@{MGq)yCW(VRSt1j}JA)qe~V#5COB#|I3Z85Z6;iHp{s}>YQU6BB$4hzC-UU8Ke8=uDbb7?6$v803VXC7+p_Zmivrn|tGGAi3Au)Q zOFkplac}>~JQj5T|H-mFxA+!-n7%j1s81O65q_oP#H9PG*il*5zwuOYlN47zy?P6A zZ^cD5yCLTXY7Hq>&!p_$sanLrEJE8D;-F0hJQuF_{N{H z-Nx>UbboT82_%E9-T-WASW8MDJO=eN5v%8xp1PNs(z`o>Y;P+g(y@(ouZazlvC^7| zN1RIY)PP5;Vx-e;F=s(hc15lVP+nweUuAlgR=1bpsnAJdad;P-3e5^}1(Xio55#VF1~02lzb z=jinrd&D0z4vj}T=R9+mz!RWy2Ns#%EIf`rg?(jUBN-cHswRt$@si9}6kj3UptAx9 z##=n#tIqVfqjt{MB{fTFX&vW(HyM#aElUX1`l4hd2dwd5U}D%Vzwgf6M6q;N6g?7)HegF^xvK3M zwU<}0r0^k_1OJ@qi_5+pU3w(AAbZCY1OQRqYgdmGP(5W%lg$`4M_$EQ- zq&ggHwV#eAMQCe7(Z4o8CcF(7Y*y%ZFe@8LreYnPSezj&>uOBxY6@-X;w8rseFcAf ziBV7~XBN>85@dR6nLtYwiw}BTO+?cxBmxqYAGSkiY6bdb60ec4VYcT};540uHdM8c z1kJT>BbM7Q(h{=5HZposK_YNG?)>SytE<5ZejSo_MXy_~pni-Jl#gJZVTH}0=nP6| zYBFUCba`r`^IP>9r>SR0RA#F+*8b8TZPF*9{VJ-Gk-l203PhcC2{>ymSy~1ctIxJi Us0-OD<23@O<8<6L?mHOnU%uU&2mk;8 literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/IPython/core/__pycache__/compilerop.cpython-38.pyc b/.venv/lib/python3.8/site-packages/IPython/core/__pycache__/compilerop.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..1f82bb003192f4d66a93022947de6adec61cc1c0 GIT binary patch literal 3973 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 literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/IPython/core/__pycache__/completer.cpython-38.pyc b/.venv/lib/python3.8/site-packages/IPython/core/__pycache__/completer.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f83bc43b5b43013e46a2920ee226944954fa61fb GIT binary patch literal 59615 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 literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/IPython/core/__pycache__/debugger.cpython-38.pyc b/.venv/lib/python3.8/site-packages/IPython/core/__pycache__/debugger.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0a638031b10785f9a8864cc7bc5cbfe36e6dbf68 GIT binary patch literal 21885 zcmb_^d5|2}d0$_1?(AZBu~;k)f(?)$b|_#WLKG>1Bt#Mi1qoUr0C;FbX)rt8yF0V9 zGlSPXI3_c)El?5d5@p(P4m%~+t`o;*l5(ozI8NoN#Bn8#U6r_!D*e%wRFaCT66R2x z(+T2``Tf4vJ;wqxWH)oAoXIhqMt*am zG$HjA>V;BabFwrk*XhR8=C0B%sb?C~n=_>u)U%~o^vgANZ_btW;5zS3ylIr?y+dBX zn|#wO?e!k^ro3IKExcrS)85RRhBxEyyK9&B`Y}>ty-huuK2EhyN$PD0k>))2HV8w zH~me&83ryYO1dXY%5zEi{56@S=i}9S#MN2@7lFH3sWlsSF!R+A1GYLLCtcn2mfCmN z_VS%@9Sb?Nbn3W%+h(oVQu*q7rMcz@OYWsw)o%ubOt9YSG(5gr`KvAEbD|y0a(p_; zfT6E8(cQg(!8|{#)Ebz(Uijs!7u?18y;obS;jIb=yU@Z|6#}(5+^vSZoO|K>r}O#s zFl+~>PoDHz)d17y#FtuX?c}MGal@tcaI=wrk94zKG^2?%KP=aDLtN%B-#OcAv{bF@ z7p*8)Wxay6MY;B!PjOQ#AzDrQx2t}e6DdoJ0QU;PMy*}OYePQ>yXhK0e#XUp8>mzT zJr4d@xA8fPPq2uh2O8T*sRhqsZNZo`JbSNkmG_+uOFinPt{Pq%_?+oJyXH52RSAhT zzS{sE66zJDTDQ1Sz~!dwU8pKmf2C60a9e7C`|p7mjCb*Hx#U`IjhzszJ z@|%?nzbrHQG{y^rV_8{q+RU1csb+DnN%h z;1H%f=dNiQ%}0B-m)gjw(>=Rq^vs@h7wwu;VR|d0ueWhcs1?)QZ=O%K%3W`@He%WX z=6Vf3aIe4Ut^AQrExZnLig%RE!NuPTATv$3!$*L$Pcp9hK>$MO2+ngSuIn~@!*%K1 zu7J{gAo!A8cAre%R32$b()0Yb@~hZU&&6m}-v#XkWE-DedP3y@k9UETpyTRB!@ub_ z?#-OPT?@JC=VFewv|P+aSZ~QA3hyojGDnr)j}4XTJAnO0Aq}RBlEug1A$ZR#%t6b6h%kPv%Z(b0*eE@ zn~I#kZ>*|^c;^s{hf$Pr;Yzu+x*GW5j#Wqd6A<1%rI*n&D4;Na`xe3Re%e+?a9!oi z(Z7N0ehhbg12Ws7ye`?k<7GU6;Z5_d2}zyu(vXR1k#E^3eT{^!DxasEBi5cffBDM! zvoBmbe@bfqEEvik zNPu;}>0+#g?;Qt!U$5K*C#r3LFd$?Gqu@~|)T98xR1-cG1L#=b`b|(^6*yn5v@0vM z22dJ;L{IsemWLE+4H0N)RtelnERVJD-0TD)g-fl8u9XJZH3hVLr`1tz>lWtM@_cza zC33SB>JhX&Y_uStS3AwBi02hhUnlV0TfW=$F$%x|S>#vIC3ID%8P+!SNLV-Jnj5cz z*j8y!6}aP8FchEwDC1QSXxE?<#G{auN#=Z~h+REcwFU61PBm<)MDmwLg&*P1KZDBsBzo8ATRjW1DyyCfoq8%vhnafT zOTBG{nR3=k_wD9<&#LG8cF)?%hZFU}su@mhLrLvHw?wbkdv@RK&I8Z0)F%55xOcAS zl&4=ang>mT|M1Ld%=A;e)Yj}auD@(Ft=ElkcMnw2Gs<(G0|t?=yllsG@E}^?y|dUb zNYBa`Ibc(3F}BAz$flPQ79I$UdF#aBPopaDX$8PN4UGg_*%Gaw(in7MlWUL=O^5?c zNmLG@Rk%TQ9q3Jb1Nt2Y_}v7li7VKU0lAC~b`#hRx)~WF0LEQh6)ax^8aAme4zU6I z4oT+utCdaz$kiGfj18+DrJyz@uS@17WS(Ffz(XvFXLQ^pRqYt+*mCPECv{9q&0Dp= z9|7k1+ZB@Y{h%C7=QNZz0xS6wy*z&564i{QM9m;)XsOWEyzd#!)5=si-RI()i^bt! zm$2d7V9gxJ7~{Kd*X}+TB{9C*J%ql2QL>2MbU0SevYj0WeRV?bJ&tx z0WS}Z^VMK=7z~UCoKurq07GJ}LlzvH4#6l)gV5)jmC!C{O$`@34+y*=@5ZoxSjFC7 z_4SLvf5B&}9U1{b;sbaNY@Ar5PV55k?G;r~cSJyR0@xnpTGYceE8t#qzjj>%`XlA* zao4LsmkGghxX$Yj+&o%VLn*OXye>+PNM)$w$_0msGBGMCDyh&;Q3o3FPMgzEq@9dq7NAk39q3e6cbDFrrDTlz zObsd)!n~>M^o+W(1?76n-Ztvawh6{+f^k~iU%nawY>;S>R!z`LEYXsMQ5F)n1@Wi> zfY!7MFhT)|;2u#dq|f+<55&}{!G@0xmJ?uR^AQ7-=ix&o?*=qV_jnpGEk4; zW)=e9tb?vXliv{3)?TA$m+`@T?e0JP5==!XUAM}sO;^;&R>MOb`XRtbc?!B)g7k#` zg#SX8tVGb-&Se!4*P(Q!}|2 zyh@wqmoP~wplZU>UuwX;5xWq8_yMgh;ixNj+;h+#K`Jk{U?DD5vFO1ck%*w6(ICd} zTOhig`5lniyXLY099!g66l^tX;})#Dw1$A*3)zOuEmdi^ef76EhG3=HJ?i-of{-Qv zP?@?QQElm2(dvUUOL32)rB0)hY!&RA7f~;zHB?KxDxL>rxz(&R%AtQdRA<>zF!BY~ zevy`}}>S{a(>~9Q6aK-k#X!GWx)$HTEUr`4`>6H<_6uuD++A!?WG}d@om@@8!MRKBGQe-aB@+ zFm|;MSNqX2KWKSiaK)Af2Ul$Q5UwW1TI#E$rM^m97RFlYtE8pA+7}+GKa6!wzD=vi z?HOB#dnVO@a4)X+dQ&Kmcx2DJD!+$K8kkGqQHl0HP;iGjqHH>3wtHIqUfMb-YXj#r zJXMK{i`Xo<49pz%9&{3yxxeAxISu1WJZ!OVf;!{QcLX7P3O`^&Sh+t)OBm&3jHlh@ z&gKei2H0Q}mf`^k;8}ozPemMsw4><;hxaY;HGQmxs!UCLalt*wVIzEsLA`yBwdK|>)3?=<{t z#YZ9=6O1zPMn(BoD~*nS9&U0K<*wan$JO-94G*ZLH8sjv48ZAXEi$9Eyr6VAF=Pgu zlB72hk_ESwhs0Y%LuO2e}e_$o?+Soxh7i-@*+ z5KTxFW4-1<11wI6(p)Nx&NZ5dLtCU%0vuErrSSzCQ}o|QX^qRJTma9YAcqq0m}g6N z6-wPu8x}?Q3H13bd;*$x#(- z;@|ycYRb&xdAC5;F|dt9m*Q*i$2!4r7N3CbUodj$)0!P3s9@BsG6JR4th>)#U5CSg zK?8BD!J`^0lL8r6wlDFUzV&+229VDxtA z+%>jRT=7*y(Qyy^l?Igh6pJTOM3b?DwXDslRM3H5s!p+OJmr);fgYPHmnA|8`)6q8 zu;mfXoC=PCFaQi!vpbp0UKr!pf&6TFCvZ<&cX(KFA%i0C6OmxCwS;S>5Lv4N@Xw+F26C3?uTnd|wt!N-I@3YUg*g=lLNo?zGs@ECA5? zm27F+vEE-mjHi2)TdMhn#+6`boDBPoEuGs;guaST!03-GeeMn5r#O@i1V5dg87~bQ zJ?K~mYRfCFkp3HuX+>K#&^t0~Y7^f(iKmHspW%GTc+>coHSU`R)m7O6l8a2^U_1@N z9{aH2sDnMLiHJ-*9ZMj6OoCS)b_YkrZj~|^fLo@=x6}c6Xks8ITg_}^EsfFd z#vIRv=CT9Hq5_Thq~Tdkhc7YA?ldPd`tZYNaztjr9Duu)ng@tQ2-WSf69U+JeiTQ` z(QcabbX>)<7{ChPqspvT0ur?9VI&RF+*yz-5>b2w`+vNH-lGgAeFG72b%%Y%WpgwU zPn-=da8Y8>K_(aAcpO<6pWnAGqL)B;4i#7$SQn86H4(BRSl_sUWC@T7RBB0{S#mFG zhMcI_j7w>n2cOn{ApbUmC|p2v<^g$BagTOKsgGK4dzf8ywpA0*1c4tT65;qtF z4Sj<&gatH+WQpEU7mf$X43C+}>Vu>-1jP=9;D8W%6bCerpF$GEsDYdgQ(_>$9vjH< zQ%#ZGZ+m9n31JLx(S*%y6QOc*N{ErCjlOdu>^bVMh7$n!dPB`cbY6)aKAf+)RA zi>o0`6kQMMODvXAM0U5m7O3gCoKX7aZemN@0^B-hwFu*-T!_oQ6xc8hqf?HKVR*sIpF?{?n+(2>-wMDoB z>PFuN2AVw^7--`@F>o<)!t8L-eBr?^8sHu@Ob@-ck*rfsdk!(CX9E8mgmWD@R!X={=UBp4OH@MTRBI4FWI)V1F`tX>xRI=gU#tcf6u|o|$jn&$1Jq-${D6Kaa z+Eg<3_%^F=p;f?*rL|$eo*CcN1)Cdu|HcX8-Lp=QZyPZ+kB_jCI)u%RZKKnDblaA= zZ2+^4tSW2(Ht#VIBqWQlk5`AAH*6C#kpgs2qmk}A=yMQ#G9cm~*6rm+kAK^&Bv_UE8LY-)n$@P4!Y+yL(fyq?tp@J@xr*vp?O- zhI_Xbdehq`-aI4s_hGCTb*(?!bi9fFEZ(%cH|rHPY&`phH_122JC(eL@15KSrKdlK z_EY`2UamLWo0IkJ?iH~5{To^I{29)|!>r&v%u5~b1={oOOmC()+1pJB$UV5T7r1-7 z_ZtgFe@}Q|>mX;@pAR4E?FkR{=HVl?7mT|Wo;}>#L+zlyr#Ii*gMY{q{H6ss%!e-9 zfw8|1!rI$kK)YE4TlV5JxncG94d!MApX}{>$5K!ACf>2ypXufM`vqb~{cvx8Z+fKP zLT{fp_jZbNe8;+x_Oe??dbk2v?inS^9|sb4Ge?7?_#bo&aYe4~P01GuS8m^%9=|>s zNI0p4h?+LN@J*iH%|6?xY_52fGxyBT(ZfXFSh?J_7K@60m4Z0kWFp&u>N!YpTwhX~u4vUMYhJ5m-r8{UnF`<1A=qz@1VF!g2>s$c*5l zlE9)`XWtx$saD_wh_cXyc@;nzfs4fkze25YTPZf2DTBWwVk{0t5i5~XM@B;NfR;^U zRZ*rf%A{n;HUO>O!bA0=C`#F|-C*wxU1PvAO74MC#!vmSzo`{)uDVo+Hw%F1_>rY< zsz1fI5d<4x&j^i04o6a-<82x=DvVOH7BP|3&vBGIU8g!xw3OjPyljVHR6l`+-z3Mp zjfxh9S`5xY%b$a=D~R{U5nehant$Fz$|3wl4xZ($S$KiyAEFn@!9DRT@tISA4x2aU ztZCdsD}>gkAwXx*+p(u?&a$l2;(&PQWj(9>$#wfdY-(tKM8g2&-W(73A6+6zl&UAC}mLEz*nZcR9NUu z-8Jn0=+UWq%SUNz*0x~un2y!~Q=%D2N1#{k7u(Uls zHp-YLM%G3nR#52Qqtg9tA`ff>XyLF8pc&!Y?m=WjgdqhKSA2q`I1#5A2;eMrE%;3? zVKbq5TDb75{Pk8REY*??pLG_4zd1LDl6BS8-%{1j@F zKmxQt5DIbIw^RLmb58C;^Ow6>eHX#Bsa{@$8Tyy)8zltKa$69&VsXrP`B>$k4KNG! z;djPtfC(U1p?gtc8%(UBy1xiBuGL1kL1$#r)}yzYkMJ!y?iKeK{ZYpT_FrN{s-Fhz z6mu0JNOTs#nP>`r1;0Af`wDn`O??;T1rb7ua%{P{dju~j0W^kfvqr9^`Yir7iYSG1 z0f>P7JnQtN5xq1Mr#lT7(DVNSTmM-WB7^=SYg9$G8KK?lnt7&HYbprALm?Z6{8 zVQy$J42K!BT%lx&*Ie+Ej@_QQWo(O28J0m>A7Ch3NcJ4ww{d?7YM@cJ;)MK-!G4{U z^CNVYioX>ubB4K*hZ~^J^;tlA@S96UkNWf2#lIBoI|ww{_s5b9hSt^1t^e7p0HKmNEY zx*WawNp$hF5cYd{?kxas6lb6ofyi*WDRO+MFu)K51hsSEUA7WZ-C|8hl`4E@z%d^+_}}5Vit&igH8r zl7Cj-ng7ItPPM;}m**9TjnN!U+d_f~N^rz`ku$ z9Y=N+GqsqCeH=S%u40GqR3by_%*dUz$Ph6(z}evs*lVyYbI-_6>4Jn4t&R9s1kJhW z>7Y4o20G%9TP?3OS}UMIttw}0fex~Yw!4BL#0H{ehcQ%Sw^r)vS5VWS+X1yHFkC%2 zIc;#7z~c-I@VR+tg9MQF#Emx`gAbjV#0!BBwQ5b3UC21PgX>VrG^Akoo`U4EA-OJ@ zpaRp7HjurPd9Q(veh%s#4r#%s@pb3**dN}r!xSkMbOL&y1GjF`+X0m?HJ}5#yZVQv zgOQ9&ge7m`^d1BF0tfg+k(H*!q9hItL;9sG@`KidaEdwgkFi=6u~a*X+)KedVU(vm8o}xAKafmRNeLP7rt{1U za4QHUf`bLjlt|K5xi^R?BC8wG<2bFGY7P0`pnJl#+{O5esAS|;)CwH*%+to9PxzGO zd>F(fm?N?n;U8i+dSy5YH66%72}{Z=;tYSkd9w!Z7JC$jm;phk-T-vfS6PtfbyKvg z-R=S8j-J1Aarq?|XNq3Aa`ob?=W)R3#aCW>>HL-M{!8ayc=f^0iZeQcf+noE9iuEl z)l$=(^m}+ov?~cj#=%Fm%J+}Yq*Oq7wX7<)YRxwC3tnN1f5griL{yot9>JPMSc79j zH;il?SPlhAV zo)rDy#`u5>OQJ#2X$*~R^d&16G+shQ!e?Nd;*T@y$Z%VuBA`QSHW(`sWwo0$R+&ng zMaWiSwMda!YgTwLSn_u&%{!8d&Fl{sToc@PghgBfiVaXu0%EH;F-C+r+D3AEl)j`v zkaMhQ|ez~;=|3;!KGc~@uF|S>RPK+-_a{!ElHU_}p z2(NtHAUQP(lQE#A1t_OJ3Po~65ia}GkKYFtNg^6N|Cr(O%tw;YXhJB^X9Q(N2qDwf z%|2?Kd9Fh@{prC%5f2h#kX)}}gRzxTuncrq%1+pmm%9a|Krw1;#hR-L&GkiSuCUHT zbES)MsJTL$fuqv?x;@Zb#SO_8Onv5Aq2!!Ub8bp20J^%v;y3 z26Gw78;}>rKA~XAJ+=}aBZ~uROD3j>0Ldvx{6@nggV&fRP;s?mP>v2KxvD&f+;kU{ zW1hvN4e}I{S5p&*d>u@wO*@xafM2A1kofaIXYFkiv9+Tm<|W=0g?fh&A#aeBvTfpq zDAL))KomvV8Zb<0b{~e&3Zxnmlu(2Qvi>9mBM?m%iU++6umO?TL%o_;(5KGN1|eWeRmpe9KG&gy>O2WVUB*q|{q*3x5xHIr~g9d-TDn3c8IE zd6-}<1J5V4IoxC9bPlnGe0>rq0&^E-t~Y@)A19FTe8EKb&vh2tMfWRJ{HRO#)d979 z2|r#VbU#M+ATG3W7oi=>F=m{QF5>4;@Pilu59sPF&cPVkX(WsYr{D4WJy3BP{1F;q zAuxRgEnnl=Xz??SCYOxlYKqUOTR@^Xa(#4v?d!O=aIp#R5sqSOrWQ{Sc9Z&5Y<_ny z6?J(8jl)1enH1gsFz16nW_3Q)^lY9Mr4w@DlcY862OKhKwjD6i*}IA4*rw^f9kYoP_!44@>$;ltmMrB}A7RA-dlr0jb{vshK3T8(YkJK@E`{A-XLP z-S=^qYe^?-K_7T!h3Fx9@yW;sn}AWH@pr?jk>Lp}NKFL;YcQvNu| zPLiEJitu>4^Z$?T$Vt0}Wpp3X-T%ZrO^^#C)U|>W8#sic$xHnn+YAY6m-=74@rx{k zcpgMmA4X6^3R3?Y10d;$u1PJd@3HoOSo}VV|I30j^#cN~jL_n($;^Fr})^)zSv85W;q zahk;wET||*n!jGpOsXjbs~pU{RpqA)JUR}#O`$f?ALkkw^;mB z6w8lnZ@t2_%AH}D~tce;=iMi?zcortM_^HgXAX8xR4Kl z3+i(S_|+7g>>e@5MbL|kr-=Uh_yku_fIVdxlfmBy`77DfR64sSo6g$V4368U^M~;4 zgZym%3;Bn$hqC$X5x_l{okTf@t9*7s%4~KP5w*$eQua80<%;7|bs77^J{!;D6SyeG zj>jU@gJYoxym%>mBTxhRn2Dw@3KK@6bPb*zu*B{cUX6bn3fkttr=!mr+?QMpS78n3 z`Kdt@e>i-{`RgorEOu;pGd( zY@9J2HPepy9agf0($}%Id%#D#4=F5j~8^RX2XgtifF>V0Dwz3n7_wECpgXd@Q3HGCiEh3{m`+#4@ z*c4^)s${8aN@5a%1S+qK>U2HUC-D z9Aoj%So}N-dBr?xNaXTMnfR!q;%KGGC9NBA_Y{gU#d7*t9(+jJ^E z!{^VjAl}RFYG6G8AENBDI=*;@>ydiK z4{jdEFZj_!Eat^#VqV-!l;bOjnZ!zRCb^QDNyYgrSx(QS<(!$x$hl{xN6y)qteksi zdgYv($>E$T_pS8L^vk#D^0t+MnE|=Zl((-8&J3>XnAsusJ>{X5oijV-I$IuI*)_8Z z*S%iO>+|}(ZQg*l-5d0FcthS!Z`j-A?e_L~d%Zinecqkke(x^tZtot?@jl>Ib7WWQ$_r02&+2^9FFf&pYOA$N7HmxHpLN1KtU52hOA3hrJ=3$GpeAoj8vp z|C8P@@*kG`58(ckw+r{X`~xWOLENAAcH@4x{~+!U;{J@c2lspAeggMry}h{KEBATa zpY!g({T*^YiTfwKeYoEz_lI!*q<1Io@09!xS z-qSN5^q!e{81JUNyYcRB{~^@n5!^rP-GlpkB=1MP3o{?`J~}hyJ?C9S+aB{SdC%i~ z%zMFm5$EGb|1r-&dPnj;f%}hpqqrZH`wx4w-i-GF^ws13F7G98p}hv4vFz(vuEyzTUhk3HFLa}a|8e3qs<;XD3|8frpM#Wtmpf+ zVzsu$YZO?j``7B@iDv48TVHHuFRUt`S9sfBbc1?fwNffpJ)if%a;aAEs>Qk=)SEq~ zy3GM|QK%`uUSDhW+xx}(O1U{`?^ay3>{YK;ntk?3aAhI7sZ|!DFPCcmLUWr#?~+O z3;~gTT1rh`eBp^^-vw1&P<{}ca#b_+)Wv6~n>|nXRk_GL6;&X8e#Kqz0k^X6szPIo$EQSgrCl)A$7kaA*wFV@vTHiS^jc_=~ZNu~e*{T+XTc;xYbz z90c-W>|-%60i;Ye4xC=}i_1<8fH>&Pt=1i{S{bc7WxwwD*NT2kW2bUUfq!m#Jk?B8 zgJz1Un;HLFDX0g{-m^B{cw9Y*@?VdsJWg*uI$2+-P1Z`aiPcKYEiU`s#MMRLFHbyD z^sXLxWck|U`3r0H#cE};SXKU{0Ykn9yeb6lykF1-jIdp7U@Vb{58z)N!gUcdK=_x! zRT@75!6{tSW9#vH{FQ_n##M}0!QOQ=dmUi889NhudH=U1HWC}jdU8E>BekBm8DCGn z0)VY2j>RrJ>j2t#ys_|fY1wyle`wgO_-erqoM3fs!YdW)0mf%g_g&Aa&O7MTxjA2P z@Va%UzUVvkY7KD2aL?y*4*s5(o(&xDFut3>_%HhMd_3LEl>%nvR*HTz#jKlY4AzyP znJGw_&E$e#C-l9;GYRiVGr8=qHPctz@~SVe)`v;7Tph(>9KS%O(#&u?6(5Z6j?43N zMMBE{@j8QF62D*yhxMfD{|t_$_(pO)p+-I(n~!65OuU+1kDmcu+lUjc>xuQ`XJQMO zWnW8vK92b>1!$$+Bs!#2sr#zpmYvc{t?aLWXt~56g2yd~R1f2#>a6(ac`wkAx!@`n z4}28}KqkUJxm_vY-CE6erktRzzNcOWGOcqX|qM&*ywxBSTFIKkU5Z z`Sb2-xjyBbbIXDMvU~zCx>CXv5@L24tIF_p%NjTYz%w?92B;eZ)nWWfn8 zpyn4#^QB@0d`7rFo_T5%PQ)7bTY_1zU*(ULt3|Z^1TO41m^72<4rFbb z+3YD*ise<$pME{A`jF#zN*%+gnIfjB6S!0#=79uFJ;nnES#!sx;y#GSddLl?;@NmA zF%(xMN0>}|>&mSJC5(n5hZ_G#vwQF((fSB}0So0&E5}yi8|ip#JxxNjl-$T*P>!r8 z*Hd2dSZqDBl$r+!*TJ&BmRL{yKtcv!8UrxnUIQ>L=qW`b7G?|%Gu`FrPY%I(RmB*s zc!8lw7k!P1v$L(U(CjQe3<8WDav;Q1eM{m7reHN1*}yuDT7rEjtW*vhcMceV&q_g< z4acu3@+1CQz_BNo*jC4)Tj3~nD{F#V6D=RznnJW7bvQOo3XX&NxN6N=bg!`Ppqc^d zg~8-vuz-A)Jm;D7&zyBwQs9i0LGZ&2Mme-6L8eQUQI32=Ou))Kcx|OTI*xjJ%wrW_ zhIxjg+5(1yO5TR$~2w_&%%($lhwP4t6c?JX5NG zsFllWnxc~M1dG+xvd1>+zHF;F^Enu1bak;*TyzYaO^=g$=-eXYaL%Jv>{3)+BY?mm z%txpmx_6;;#jhN6O5juj%#BFp+z7(x-iVgRdXc_NFW8U;h^q7usv^-^)Q z>?)@nR2a7eQczu0MKd8DbUZ?{NEn1!KVM-Td%1<{Z9hWQpv>Eig?-f$7zPdT)wD-pS+Rq;y1Cj zyOH$3J8DMy3BQ7-*FnE9RbRz)Uh%3cnm+)Uk?C_)KYU{lc{S5m%#=!)a5zgUGVaYD zlc1ULe6GY=YAzFy%so8?WDn?nk`>~&v4pya<9J#Iv7A+pmSW@< z<@yY+F)gW2V7kiS-3#^fE3u8#dJ1WKIDOs7c-fnAb(P+zI{ulKJfUP;7b@@?OGf5*3}?~SXW z`nL7dE9hBSyKi%^?~29Fm_@tW&Yp3Icbi&Itzlpa6DF@a#xW2A(=lc{GBc|rUz|=z z5<7{g8S>}s%q^q@_z_ao4iX`x7=vFjT&!L-)9!iDabK;J$ex?w2NDG$X)6+xR!Sr| zLX1hkrYN15nyq0?Q=dI35(<(-G*@93@%6+Xk;?$A#8a!aHI(91s&yY6?=seqE|&r< z1?(fgv-HC$R~Je}Q@LAD@8reaG1snXV8n!ji#J?vMEMLmZaHy4038!ek8W9Ek*Apw zatafmpMbAk0)kR9bCX(#eKg-Ggo8bd=`940`BbJcwmDDkKu`zRgL0h%oJS7uo7Q5u zI+pyRSxGX+N345@cXj~ijxxmS&!>SlbKO8w*|42kH&BLm1i)y_*t$nOjv^p5Vb*|$ zW&ku0G*r=eOisc;>-L5dznz=A^dW(67+LgW_yy23T%YOj#U5x~jB#r2U{7opwB%_C zK$uy}Vy{&3N>@tWsv9j{+XM-EsUQe7I~894}lDpY+ya&I%H#&bEV`Op_5%?Mww#Z3Cm4BY?d+z(B*}8 zzGF6O!>pjTW{0L6*Yiq(M&*$IBcIfbYIIF0NK5nuJkciv=Ax>uE@4_ZqtOW*ZG{h~N`YtIv87F6^*J>=U9I@D#OO-3`v+ky$IKiL1d?ZG&4ed6R*t1# zoj7pweY`7+OU&T&by zIU5dCBdND})oKTw;u?h3T{48suBz&r^I~DOTAoY3F_xG2R#$3)R8Gpr$gg`CSUdk_x!Np%!Hr<`RL;Ln8%f*AGt}Ip{nzX{Or88I>rj+!KGje!@pV+&HaChC@;N?-=e$d=*$hkE~^ch$rBkso#9^;B; z!3Xu&3f>l;qvuBtn8dA3q09j-hRnB60z(B6`Pg{gj%z&~qnLbn6};5C=GVeLVw)`5 znXEvzh1FtbwbWEY>zGwTIR%X~0!xaq4_!lNo{$DJKMT7@CO)XYJb%6gu+VGi0$CUk zj}247OE^U}+LXf)odM-gC(D5rp|%g3?qgbiHVr@kk-8J_!ThIV0P##8kHCP|R&-vGCpk5GUkyip40XOan#|>Vg zdKJ%2$)JsJCU{KV0)UdaCdnc>G7uS! zCbM7-bM1;Dh?gimBt8p-bncjg6*xe*R#R0MO9H@8WMpgARU^iN$i=Dl#+ zfONGZ3!t-P@s6NFj_O)VhB6+weYo54&bNIi1jh@A^K|F!?!CQQkB z&mqUM-% zOqI4&J;1@$*@Ti?d-42mt2*$F6vid5p>Qu+8pPSfD?t=nhj{*~0=JF1L?{xBAv9I; z!EcjXaa91t3|5NBafM_`Dq_hSDsLwm$mZv(oKtLDb!S-GnRiY>*Mjsl5xW)vK}*}J z^U(B!YC{Nomo<|t3pC~?%&65~m|8*i@4G<>4Opqd^u)IDIfYks61Qp~Qgm_!oOIT^acFAIF3bmP< zZ7Hp2cjT)Kj>h*aSnHFJLQUpNb9lC$b5uqWh_k zmLHE9{D$gi%SSXcN--v**R+g`$#h{94=uT`PIIcej@Q3T9zu(TikGWS4+ahJzL4 z)EZ6D5#7^*a;6CR*!E4yn+nAqZE7!O2&^&8o~>P&p|0WEFHg*eTI6y`y#N47$4;x0 zxExPPKkBZQUKV{$sMJxTNOTTh7K?`1U^ZUFgSJ1y|8e|+BRKf6nYb5&DNuYS3ER`8 zmx2W%^fF!sHj8Pm$IIfJp=B!0J!0zBFDU3{QOL;_i3++#AlE8X(QQ6Wspo87!~^Wq5H2v}VoR{?!!a?R z*iAFF#B^im*!>|OK>&~6ADn=pOK+hd^LwGdN^lW_#Vm;?EL~p4se^hjkrvfdSW^Nb z7T;V;oumzJtYJtP_Th#`Vl*5>En7)~wm1Br&$uwE)7W59Ne1!?=>et`QVjAB-7tVX z%s&~~yy&1Dd}M_O6BA*o@B$baQ4%KB=-YzUVbTK!jNCMQ!t|SEsG&GN2&JOo7zsZW zxD#neqID-EbtjOzYqH;tIFj;m*b{w?UG4Z{K=&>>;`g4{v^j*c$j%a9}K z@zv}p&}bSX=@TqwjtA*-nGT{-D3#PEXEaDWjlO<8(ZU)=7$nHkkN2Mq@pj-HAk9ADRx8qo80zg2 zg<{t!uH)IAVqhw38?yU`qIy-VD=ASBt28%~W4330kO~$l)G8ri%yzY6_=#^dK1xMo zb^pFCFK4?qdj%gUuAEkjKsHt4p#uwPMD&9p7VdZlSon`3(nUeA?^p+o_aM!(zAah` z^gf;tPa4|`? zLv&p4J?scoZ&vh6D(h*1fgVv*(Eb18RP<&}qX(TuZ-E~>fFHmAuJGe0JMcs63*UPP zB6`jD2}ndh8hYs@aJdDBaP|DB?+Qb{(t#oL*tw1Qg)1how$O=iQ3UNXw0faIcd%L$ z(p_!xc2Q7^Cs#o$$Rs(?OUnoH_SC!i3fjb6QDF zKFVroZ`0$#8j673qSE!x#c8^+y%k|<-ux{v1&&Cu2e-f!yb@Im&%rbfZF<54G=xcL z2UE}tZWmo)e5OZy{HZTwWE`z8>}50?=nZp>XoGX#r;+JQKa@>_YBw@%95`tO$9hV; zs@xhhP&C4ag0R(fCf|&!bJIoon%O^IQ(bf#zu-$aP+e4y*P+ltyoTNIHj6XT0F-a> zq&&vY}j zSg+T{`_*9#dBxZVDvLui2_QFf2z{dJ0rkKV+@+ZWl$u%F&Q?!fIC}%O&AtLW5R1zN zb{QOBMWOv9Gri1%;vtILAOdUAm{2YEB#9^WZn0ehaQhvCF-!{o8H7pUIR!`HOezC| zm~1>3=Q-4ZKP#5g-F5Y#3!-qRc?P$7aKFe?S7d8Z7E5bis^LH9Qu~ZSN zm}q?PSs2(UntFn~SPB3I5EOnu4dufslqTjNfuImT8R@(HwALiJ$gESRP{*_HU?uT` zRYv2EGkRRx9*8=BQ~lThQa=Y5>;$!&olwUNuoQbGJ`Ygy9-h6V=!rK^0l=zWgxw!W zlqSopW{B-#oe(U#2tZS+XyyTA8pIbNEX3&Cn+Dhg+XMqS!Kp5dY7Pmu7C@`epW62I zyVypt3IWy)CK}ci%C?i}-S$CSbJ>Hv_(^l`M#r#;GOZn|i=_zeF{ysfAg9wC$(wjz zNWB>QAiUq7Ljq&mMfyolC*l^=s z$}VTr7kTzlcf@Y=!WA5$fnGj{I3*cQm~!s(GIa9BlU}dqX57mnCEp>g$>lFzzUK9s zeBSbMl2h*;G35FdY7j5?Z@^s1>thhU4cIEJ_rTf(ll3cb?m~+~ky>s$^t>NBz;++uywZIUyfHSVICXR)|8mfdC-EKujVz zBDcUFzg(^Pl}119jp5@YaUR}`Ki2FiF1iZ7uW!bWzwveaH3n@8zXH#FAW$>4&?wcI z$tlhs=bvpRR2{e3FhLJS7=u88ts=of%o!8~%0_47!hG3XK%^~RYw}0JhUj3bjL2en z+BhOIn_A~XgnYwfr~*&}#(2XC{=GF-!#njIOpqv5)pzplIUL4wnnc9s_19T24>cHS z`?{D{`9Tt6SU#1{nu+;Z=Ku|m?6X8(lDZh|1sP+iAC`tWkkk~8!$LlXKwWa6F4=fL z-lyV289{SvU}4Z))AaGwH2z>CIg1=Mjq`am&%>vASmi+mT4Y{9N}(D&uu9Es#_Fkv z*b^|r5V9wSYfK_@09n|RtU853G>-($r^(~t{%kgt?J44E+aHp~9>-5?!rB>XFA4S- z0TF;(X|)Gw8Y3?-s0`Ud5%!pgP;(YwY^Wz|8^T1ikQ=ts2F%WS)j>Uk>lnbn!8&+a z49V0ICXJ;SClN+XpfMV!jXjt$z(B(8T$eztdfmBSjc0V99!4Rm%EJr~G9k?J%H<(~ zk${H){Rx7H)rz6l8h2ent+yn=i09F@$E0JTyyZ#?Ae?^O7C^Jptsy>)q!Gjsh%5$k zM+Q?&DH`a7;goP4PQF46X&C{MCzPJ?In=k|0S)!o0Rj{|QzmM)W?Eb#I{*Pxk{M9j z(G-4`HO7xtal;qHwkF?}0KxG(;qV2dZpk$Q0W1I0Hp6UU695GCNE7gr5CB4z<4?y8#>Cn{hW`#igAYWbKf&C1eGO&_dh}UaOE+dH4@8{W&EG}a4{(cbIcw<{zGd58fcGYS8&*T8c@SilgJ6Up1F`7mm^%k}HZiaxn`|4Rcq(SikK-)yi$Z$B$c_;~ z-G}$L*NH+*)eWTY+UD(=ELv-j!f%C5k2m(R-?)A^v@=Z9g?j!C77(>K9LS0_{Y{%` z7wU;uvB&YdRcr6W`?l8dqi`ZVh#PHd4JrkZ6V_~;eiQ0Gh^jyw!By*p1gMsf#U!k- z@B210+XwYENCEB-?t3$SA0`DML!U*Cnswpw0G7bAOp6CC4P{| z(L}M9U$K<|MHzaUzMAcAQ-2GIx;BN?_#^vum!>4~{&D;yu4#nvm^Y0S)X(S{6!DpR z{2nZ4GMrC&XS^qRh0*9$cOjR?Upc!nN59C5Lwh55oV7)~Frq%u@nKa+U#umD^s~;z zS4xNn<~lSA5QnInRsoXt+|%lU_miA zy{RwQAJP}32jmt*D&I`Y0<_zp6(oJj!V?SbEZUjp>a)$loVZKKO8ze}f9)bM! zLqQ^lAtJk8M&5ul_oiM(LiUU+!~#=iD0>BCkOpHAuf*yZEAh2?fFy=1Fa)eBA&wfB zBv%#?^X*G0wAq9Bi+Ma$f17uGHLk=iN=&1fVZ=;0t3%HQr`9gH3)A2rX43U4K2cmN zTVc`P!L|NAer=|Ao}Rx26w!igLR~p{6KJx~k{EXbd>{=!9m3oGy~D8p zgK`=5D8I0ag`p!j$quj+qE}eC&Ek2>NT27eER6&%S-8_f98_PE?gS?U3vjSXKgLwu z=mAmtPuS^$xBw@fNhRt2l}lm)H&n#4wm(!%52-m^v=1q}4ic6WPDsL%BGeng($oD2 z;qh_K`n?R2FM}-S=a%{qF5lci9l?O}{S2Lt^EPiMxWQp{HwtPzZXaV5zkhuvjZcp@FuhzkAOp&yNUs5K#;$ADQtgaw-LjxjK z5vO%6PR7ej>fuBFwKtBTS#NOKP#18R9`9`e|B*dhf^1EjIblAomOKRV7SoA>Tr0vx zViBs3@`?fj@PKAwgL9FYxztbcZG=-HTY4w3MDy2KN*4LgB9Z@lbW-XR!v6=vy-x zh=|H?3WZDt0+x=pb4-l0?G!42C5KR%V&y~(-juP_Tb(eF;l5e6O8P1=;KJ97-w+s} zt!z-6j1parkMcrdQOMn{9< zymEQyXwXeOI}&y#B_tR(sjoNov~}h!_<#1Pw1p6%k0|@oi+>K{MI*NW<1GGY#x3e+ zS&ME}p$E;wtO^G&$l}h{Dj3vkLno5qHc&>zdx_5_O$CzEmw?Tzf%ew?GOxOo&x!6s zE#(ijmamwUW0!2z9oHaG$;#zc;cJ4;c$_t0=fxnB-qf!4(qddi0-U6c_z8ZhZ^x%7MEst%YODA~Vs0uF z&ayZH$@oQf5(`PRsT%l5H~IiB)`6Lndp`m`v_LcyR9lWIhu0S&(0C;VVVSr|HI6=~ zqmd!pfRbG`WTc4u3jFnz1g#IJ7Y0T~6q)=R>`qGgWw?;`HMd=aWBYm3PRxS3;f=Um zLflj+JjFH&9}iJzKXgj%T?_9_Nj42f^jYNHIl)K5&YOH2Ih6f4Z>36qpI85whhN|! z8q0De)R~j%URGo;E-3cQ4rF^F@JwctX39@x(?z^%`;(r*li*`Gv`_jFd=82niC)LO zk=L=0n6C6Y1}~lUv(T#d**iV`!>$1PY%xYo}^XuhJg&xo1s=B@pOL!V=pv45J(x?XH~CT+8^8=3qo!m z9EcdXSWuG%v46TqCc^5+6rFdl=((MKu$l1u?z*FmJ=&^kSPT|VXwG|0(XQi$VJ)ex zw|%$L)}Uu>P#kJWp>tA*J_(gNwWy9B5Ek@!jeva>1`LK`!DhQzqpy3kt&oedg99UV zBHCu8=tPkSyux5vW_hbELAB=9AX$_@F&~Y<_-V_VrV(PBV3<`&X8CdROfadg5Y#IC z6aw6=ZG-w}7&fmbJ0z*pGl=eolb9Bul4xiFYPPEY^`G;-e8U{IoAotbMO2Zr^(9h8 zE`egZ7y&$+LOcvGJpB-LQ>1iMs@9VHn(P}fr)?Vh}hj{ow9GWSP4r(J@ zFA%YWWvnPN=mwhaAZP~gGDd|c1PH^B+UIV;Vu=z9fJduE+NkBOPcZv#;HM1#vmyB7 zjXeVX%{B*{n5mGbjHTRrOx#9xoH{GTj+KvyU-5v zbzTWqBR~|chRss{nuqV_A;LKs$%1&K1JAJ%TsDEV>49kG?rh4iHMwlE@t3b){x6p* z%g*s|1CuSP>o3_J`h)KQX*&Qwp*_m+P1aloSbhe4#TAuC& zf5CkkJB?|J)%P|tS3pcr*vp`@!gYXa54i`jdr$lBJa?_T1mno3-8Jw_VohnjnQ~}; zI5jzm{rZ?}DZt(%E0Y+p+*`5e=P3`n7cAq1EhWqx`!r&qssooZ00tT4@MZUsP2$@t zw2lf(858ESF!T2&2WxHDxzfpCpi^(e&xNcq(Yl*PD*p>Wlk%UAsR zB@F-dz-Eu)6wv@4h%Ws29UIAgq=lI@$O`L4@q?eAi8)hmp{jX{%p z_az!bamQogfqYVszn--wwoY~diL z%hY@7S>f2QuoN*|QZR#DTgu&uYKB}}i*u%(fAp9#+jLkP;}*PsPdfu4q!S0Nhyvfv z4=1EEkw1=z(UC!`AI>J?LNf{O4W<2i3@=SZu9XtmP*70-T<&&a-nMM!K|`*kk75U0 z1Y0(nX@#F4;4=*OXtK>H^H_R8;s&W!n2Y@)Y{V7pz{`CXjenHhMTb)1R!6RHNRWDa zZbU5@WH$BV#&3~R5h`urOLs5w7?BL_y~!ZLKppd!4xx{AYlndFBz7)=@j7E8Lmb%B ze0(O`GJQ)M|x>m4de|5X_5{mc&|@42|ef z7gB<6iuP`6%WBTIyTPE6$P?($y?#1;Hv^#CPb4~hTV`6K6!jG(1yi>T79tA^-`eshOXJsPtDbkl)-nygY0IoAT9(eHh6)zTXiPWuX~hi&n(bih zO;p7W#P=)pFF?^@z9OQ_Dz4Qp;sCP*?!znsOeo$@V~EzvZC| zi}1&sw5acj-3@mH{L>*ppQ(Qn9UKi4c1FG1or9p5G89!_!VMfxD9Vk&WgG&i{4x1+!2`0_+5$a@@QcQ#AX;?dn`QWg8#XZTP({FN8WNWbBH$YIR zE4B~OBmtB{{jfIYF?UDQ&*7ahPY@rkX1v&pms=!bhIi0HxX}B&a3`9g<=g_00RV-+ zp?G6|DQgUvVpV5B^Yf?N0q%FflV^ROig!EXFR_6DH{x;N2UPw$i+un;FrHT(;arfN|Nn9-JJx zx0zIF5l(m=Tw11p^~SZeae|jw!5t={ehcTehLOVw8%D;LxFlBh(j+tojiQ14P4J?3 z&?ykOwTD!+ zFst#dHFIlhmc7ul}hZ#s2!$%PBNEp z;_AQPX&X%ActE%cvQYRdPyoa{SaE4sl4pB+)Oh0jIfELFjfYLW zzEGOKwswm3C2X(@>l-*0dD;4xGdIEa;v(db8MnK|AKy>;X+N`&ge_{?OZ(V8751q; zr6hdv_X{sg6T03RV?Z~PlV{YTXJ`7nL2ri`&)ww>c{>pYe4BT-H|*`g)quC#+keXhvG zi~ZxEA*?XOW5HL^9bmA#IrGyczgHc=ScVTF#&TcfIdS6eRnY0+8EmZa>;%x6O#Fp< z+JkA=cg8CRB|p0VUxS}Wh9;yzxegb8IQn0cFG(5tD$uZP^qB?1SJwNav|qwGwVViE z!rE$bbSUO+Uk;Vn7xs^t2pXPs1xQ!It9rcBI>mr!U|v&rIrU2_l!veWH~L_I z7#?Ap`)9!RaB&2BJ4sS9$jkbu#%QGIP# z0C3aYtUKOG_ybn-Jk9UHc5_b>?9#+Y4m1ifz_fL3sfOMVwtFRn1=k78%A*AaV<54U zB(^v#OoFP8%N{PeP;ES+wHH`|i&0M-Lryn!?S^g_vFKr_F=WdVR-O3$Kgb1Qfz&Y~zcx?Is**rE7j!7Lws!DF77sTW-o1jZWN92Nvd`nddGUKPg=G zyT}>NvrsE^L%@@5yC4DDQa{~7N_$M50I5Z{Ja6scSFm9f)FM$d7&gE2qX_-^R>-7? zvbimm-f7B?a80cOAY9R|bQDLCS0^tOXW!zp>O!b?$xuj*=8{$x`GVhXp=cRs%-?p zdqqa2r)k*)OwZdIODNNdK9b-hr3y?(%xr3GPzjUsoVdnDjUMgl)vNi1Y8Aq({Jff! z9D>O})zoCUx=?-SDwSiSk&?)KJXv$=i<9-L{veNeX;YfH(dSOSSO8O3ICJvSNhth~ zq6M%<_seSQJjn|n)p+D=D-CNQIplO&VTq9@W76(u4N5B0#w_Oz3_Z{@Zp{fR9-u5o zqn7uz0~91xq`~AdWY0T8zL7ERx ze+>znX&Jc9j3!RwcXhL5g9{KSgI54o(99uJ#j4rItj6LFF_+%Lxo0jF$hO0NotNlv za|JeD{Z%PRB4WXvkjccOq?wlLHFp4cXU?3Te&Qk=+!$i) z(#J2Hy=eAOE7+YY)gQC$uQ1~ulK;gn^`~q6SVLb-_Dn?kq6$Oh4tVSOYpJc?yfv5)x&B`(Jj;r2NB5;h}Ip!T# zyq}<&Ybkn%RW$O2f^;9(fxX<`O|GQ8@nqv6p=82OOnB8*s7t&}^K9otI4xKVyGrQ_ z>6AY~J48OFyX?R7mZBZ?KX{-JCF(MxB~|~KPk*0>b}@|lDxUos`)fBY=(0k?-9h_H zQu5o_X&|i8OJmI@ITAt5pAkADZqx{)5^@>MKtr;4PN@+rc;UB7pBG3^66!j>plDQD zcLg_Eo)Yj%u#NT8=9(Rd#w5Sbif3`biVsjE-LI>vBjU8x5lJIi7iH1tx>#_*i>DwX z#4mwhO+X1XBHnS4%lZ+~bW7MVyiclQUJCwl=_SNHL^K(#-^_dt{&HeC+cT~H9rAv& zPj~F`k^8-oH~S6aC3lUTdf(9FBhe@wX^fFjJ1`zRK5`w@ZDZuRP@|3Oni_3fU*^X5 z8V8}>xEZ`{fC2gkIU@dH z;vG+XwXq|_2^-#`Et-rKYRSMmgS-fBb(9bmI755`=L`-wk*z|glUz^3njp=1DcA=w zO<5};PuwX1S9Fk|#)5V~YMBIO(`OPxZ3hrdsVBjD&_dJ_%Fq%i(%*!8WMd%GMkboi zE+NuXpI*8a<`7FmEujqzvLJ~1e{iE?eh^>)y%5mH`IMNYj`2W&_ZC(Oq9TauT=*(M zK7jPGG>IGo>49J-8hcuS+>*Y{iH(TOF(9D+0xlZEkh=lUaJ&VWA>T{97^{q=V)f*5 zPCXn)zr*UAN`0i!^0AM{Dv6K9N^k_lv$UE<)H14Bw2w_}sYiVRcRdh_Cyz1btfC|> zi~E$^_o`3g9#P4>H13nZcdy6Q=c)LYU~%k7ar;$ksGRuJHtxYxAFRStLc|1MC^Q>h zRcliYr{{=(2^vpB_eI*GVfq}eW^ickI0q>M)`jQjetuSV6cziB7nmZ#bk0~7|Kq^= zne5!dN5!yvCb8mmQbbM@ImqRM`*0D1Kld<5O9Jy&4wCft5g}T!L}Rb%CbA=2N1H>z z(Oh&lZUD2G+J~c^hj2}F2fVDafJL~7?z48?%-5|CJh;=sJ*+*^B1YxZU@H>wbsJfH z*R_)AXUkeK8XE`%g*AnH+p5(@K;-=*eiZw-735f}#hd$NPMf!r?m zE~bj+b$F82 zB>V_2L_4rKa4~2W4Uyz6H5bRAxzK@&aU}tZU3p3rD1>oOcb zD3`y2K%Ld@PJ?21QlSk%%c}e~ESA2RLU~=i_l!_pSLa;`<)4FWUowz|so9@eR2N(p zY7t+jkQ+=CBxK#>+d51zrNCSQOZCDnz(c_~7vJBwAU@(B>{@k;I&_t>bJRel$Tmea z3)jb#RJ>@+v_xXdz1DoQ)Zphc~Fx3jMNdx6wsY&1V9P{^;;j<(8$Ec4nOm5t0u z(8Z<{NtcEnYNtWl4k0VOw?=;p2!+ax>_zG(3|Xl35I9Fhfgx11jPuG-HF}9x>2Ct4!gIln<;;b$|1jk zHExHlY_t3CNn`m=MVg^d5_E6YjHOve%t6{KWjb`qnH{k+?+9dmRR_VGGzJJ3az<|d z@L51p!7I##V~`K?y6AfhArKej!dl3+$w;J#wve+Si0ipt7>7=8h}n-EP+7>%~^nn z*rH!J1^Hdj^Yq(vIu$Y^kiOrvq&QdQG7Lshi;MQAOFsD7ta zB8~Ae(NM0qYw#dKL@A-W7}cUplvQ8gEUqs29O@>J z)lr%cfSXhg@^BCb7~;S;NBuY6%Sv3@;L{~6$<2rJ$tmk7U(ju&6w1Wnt<>P%Kn87hA{`K?%PgW?tq97}Uz)xKDBZwTV zh*Gq;5!q-DL^0ZLyjR^=PY0hAKXE*{Nuf=8BU7irCb(?GM<3YeS?>{>pKKIO95ysd%920g?$zp(>$LWpsWI+z-ONAJCv*0mVVYGIms z3yoD@$DvWtWY7r84sDD$*AH(v*N@=$(8dWv8^8fTovx}^vDAx{C)N**6UZ^zh@X&g zaBNbpt?|63kH_?6d_wHHw8WxeO1^#wW$7|e-Z5h_ErL4^sVUUsF)lJ6K6>!_QPhvV zXOQVVv@wF@Z(lR1lc@QTxv9nYP>U=>(2xSX7AZZ^P%ypOYq@}+nUiU~!1C31GyP|H zc#?<1Jct=FSJ;a36zC3Ua9uOe&07j&S5r{BqfX~Ncjg~uZU~N{)ZBH&iDNPS}N7p@d7El ziRULnc#|N5t6Ui#6n=z46kRPBk2)*J75JA}LFxz)wXt6pVdAN0vDQC_pXx!ro85q9 zALe_OS;!zRvWaj>{`G;6W*=y40&BsVOA{!=qL8#4TY;e~#OILa-HfRR zaE6R%iQ_iL_zke}gI%AvUqOseM<~u4y%ex_Jk9B+CIH_roQ5B-UH}I0|lH5qfDSUX_0&?&JP_gYyw+QvKqyNg#ymW<_|&6+SjPPnFzF&3ez5P%d}#r;9c1IM z4^hNa8ddn5TU-XP^3Jn0u7|+$=mn8;dDX>M2-sv1>>st1rt8n)*076I_@i^Mkq-1& zff$F=WPphcx`0m?jk7$m83NBfbm;z8=IwmNdFk-WV1@lU+(hfOa?d zI-?X3;%xFc{-Hxgdk&^V8-AcNSWXC|0ge*wHf#oMP)PJcf9KZ1i}~|n6mZG_LW9c| z?i_cnx0N5c=XQQrLl~?&l*5E}VHwfN7lOQwZ8vs()Kq#D+Gfn2LKrq}VW(|$Ix@rXfLW`yWHS(F91G2;OXo{*EKLw38lqbi?#|P=&}SSh znME)z;dMoSGF-vdtU^mLR~y@Lu*#CJeZpenL_#8%$^v#EsFEFbP zEG%qzXf80MY6wk${MZ=8_0oltBmsgIpf63jXpDx}+WwKX3rxL$$zrZlWK=M?-Ypt) zxVg1fYH_|hsS*Gg0hb=z-&~?3`J2HLfF_A3?RJQW?zs+mpRrOU_H^k>%Gla)N%8QvE3Y7 zw=N;EXYRC=3ZWigSF?~0mP<9n zFXFA@vJIYS1;85{>d;0=9p!-(K|R33MIPuCqDFB5uPspp)EJ-8K}2oifsBUQ&I9>K zwSxyzAhnYRI`61mJnZIS4-b2JxPym%Jlx5{eje`Pff`5&8>xPUSHH@`ukqmU@BtiV zQZ!yt|BLs(#e*1`yuqsx9>~~gR*EE1vAivI!?6s@F1$pa!fguD>D$eS*Ub1t*ZGTiq4jHT50oX6y0V&R%59x z`%dZ-W?$+&E!hK|mf$9O0m#TGrgi^*RZjBrrB266!rVVAR~atuHzb73d;>-jAVLyP z(8QO)B}rQ1;5nH9H4$8O0lcGbPM)h)4I!frcz@# zzb1d)8`@$qT;z+BWw`*(Qk*=SN~umxGx6-s>HK22RdR?_hugH`7D6*vtTf~~iJ_Y| z7($O}+g~5=g>SG!mm&0B!!c@cAG*_HLuR1D+|xHVdaGI{lG;0}g*3Z}GL3B_NCghp-OpY9Z^^(^M^G-31LZiFx)aatNusz>t0duJ(a@ zuWH+D`UWzl_i=6shnEL*_0|UuB@`H>vwJQ^aR9omOx@c? z8~?iG(OvMTZ=!iwY<&a%-Gkobf!7C_*GKyzg9`r*vkxaR1uW(8emF=+k5RaNP=0g! z+j#psXkLfo7#19JSAO35#y*B77IYN%v1&?qE1+s3&WlPc6^{FyKUt<~yVBuYR2k>m z$J?-YT)OL9IC={WvetMdR9sV2nN$i+{G$$1)0mI0S{V!sE`~H{x4pwo*bbq)wYa0- z$9+gJc@L5!w@O+AFBq2o_R~Db8rdb7K+T>8A!h8}%?^XBgz&S5;pceFkVC;jYdJ7 z&4!7y9u_-R!%}Ii5tcgTM!7T7m=V{7u+o`r%&N*y6lSvGQ-u|M>xtf&!?ndqxGwqg zxL#n|s!}cY-D^S84c(n)9JlR_nAiVRW83ACM-wK0#3TA8|AEF=8Y=h%{xo#oU>ehz@f)pCK);apO~1&@Cu+lD)n6+c zDl4(_(^8}4m)Q)fJXP>yhRw3Mr%I#3=Gg+yvuu$q;XKD)W6L?F>I*bmt|?9@}WahRQEKfs+M z>GxkB)nEQmR}>G&=x3rwxS7F` zJVTQzsX9=eXf166dNWW1b)f%?_FENNqwN|4;Ha(gi%cIVj?VO5EqZsL4UD$JAB^v% z1~Uf6Axt|k_A`S~jX`r;wZ=v5RG3%MWTR_ijmG@=_ zh3E8k1$Zdcvw~pKOZo<`qUryw=XxYTd)tK?1_@~mv(I*dNHSgM8;t=dg1%3JJe^c) z#8Ie~*AD$he)y6|z0fm-&kKH}|?e=fttha-1LvQaqexv9r+& zLr1)V7wBnO^c{K~FA=>3Y8I(kqUS|Ih!Z85+3PYl^{ZxPB!0Ld2Opv#W*aKLnKb6c zq#S%wqnyT0KKq55l^jQ)*>PSd-(0?scDfh3LHB$w>f*zEc7D6*`{DWbJ+^)E{r2Mv zIchEt?k-FyPOZDcm+{t9IFcWrQPg9qp<1emf7BZIr+us8uyj*1aV+RdYJYh`Icr0X zc*M%#kNR|6#gSNOAXKHLt|~9odQ}tOo6Y+}xH?|ki_#Y=KZ=q3_^3I7URLSyxYJGL zm=AF$(aaX_=fczyXi)(CXi8w{AbpCL6`=S(}@|Oiv=FgB>{05s}%z?>!<$C3gJ&E#<|A(Y z4j26;DcKer4sj8@Is{(n;MLh7uZWvpD5%zkD3cl|f^@IEM z>OziKc>FZxI}ZGZyXo`BVi0wEsYAD&uFDgjW#t=S`ePw17?2>&tksmmOx?JX86n1H zRvNec2qq$%-}EE6fYf)ytt7L!@3Ii_1oa+4bf8ySsb9PO$-SSh+{?83t*lsId3fta zeI+Yiy>t8aO8tJO-ML#W2vlT-2e*;w3EpbvBn#raA0vgWUf`$q@qNh=G>W0AOX{3v zX=QamtEg`RBF9uy>n~1%L(G{%!<3ejH(}85s@AWqrY@K0&v{L(K4+8Z4BRm2liB8e z68E_0C$+j<-rFFsf1!&o)jWk(jDoNLqlOmX_~i0l89B97G6Up0gc1w84>1VqUc6#0+xF#xRu7Ld7yz<1Hpz*VWA5TYzLig z=y&`mb;&IQg}C0aw}}RY7=At*5sU~CX!@Fn5tEdG{u<&#x<|i$=}s^G+1I;YU9#&{ z3sT;JACbedf}kis+NdNxph&0!fy{&*=(s7j@yYykG(!tgqU8(Ax}WE-31T#xur0@Q zFjLrZrMLjAVXFPNCV79r3{O~TOrzfv_sPjhqXGVdw}6c5>aZ+VVdr~bu3WMW59yLx z5}V@nmhS;kvAquFN;LRvAJZr2iLg!T7w{&zpVPXu(TluGYls;68qs&7ocx&AHzH{$ z4wfP<=#_U}5)S#&8X0gRJCa-5-^l}#t{ZS0u9-{x-~l2;T)>P6%)Wi&_KKbEbSasL zn0UXi@5zV~jlH>gr+!Ab62YD%XJ z#y1N{%0*$(t_@E4Zf9Z%ccCO$0j%tZ()rPEbPHCB^!QQ^k>~3+ z5Q-O)42GPM#&5eBgLC<(Z3kfpC{K~gSuly}doqt04a?Uzx;`t(iKyY6-C?3r#cBzK zqfxZhiGebunZ~PJ-1j3=qLC0gMR|crMqKs9Zn3OZ{Kn4YA zQ@k(%XvVr~6U(OF3-UmfD-;1}h&@sOgdjBEM>b+hyE^^i5rwKQBaOuzI~2yjd;_KY zW0=hsGW^R-3CmY3cMhR^mP3o!!8GYFPfXkF1IAuQas<+pyG|vGR5%r57u+RykcT7Bn=6svF(G}Za6=n5q2$CIZ|FB6HHie^R+6 z@>*5qXYCT*Nl}1l<#(P?sH?OK{0hznwR?rtn^GrQL#)#q(DJdh_%tm8ECZT4=E@TsRLtBxJ+M3bB*EX$*-lcmlak) zfH~WL|8r4t5k)$bV5C8&ygcqv&;ju#b{MpM+c{@Dbi8-Y_EWEhBra~=esTM z)FB$CtVcA8sAY9vU>jxVBlLtKto@vs8%~uKvp;}bauJPU97B3)nTC1-U?7Mk6r9qUW&>=L4m<0Tw{0J;B2~;T#1iY&7x9|uO zouTs8aP{=LoF?x7j)e_Gdd|d9D)$RHD_CFu&B?XxANtDbNWfxspQ1D6gRxT5KIwgt z*y;n}m6`q=8YKJlH7)pBoK0v2ZEqO;`CGBf7xJit{{)olnJF);MH!8lVZ4cQM^?r; z&kGwR>I;*^tC-VR%=1N23nAN=NIb}hh2O=PeZ1ie_x^+&TCirj3M$LQOU?kjtGel{q*{<*fR!Dhp*(-r0^duHC#IKx#D<#~w{g{pG-n3C`U zl5xMkOIa1AmLiPJt61!6Tx#x7Lx|)XXkJJc&#%!9f!)8O9vO4lh|)CbwY2N!IDf(YgiMBFlF1>1 zMCOPL5|vu_7tH0PDKt;H@24On)D;yfrUuG$ZC8cUredj<8fk&{Q(ERS95U0MK)7j< z>DWPm7-_GMg6Fh^qAJDb^jFLUZMtS~5Gzs8hig7#cwf9ocd zQ>(@P`8%@8C1nkX(w@gTY{o%>ND6Vt{3Nv@eGcW}4t&Ck7{|XD>U!uwM zj{7*%0k>>cP}>kYZgC{`YeY(wmHepJ5oK7E(_)TfEz`SkH+N*27B_i|=(VZ&oQSH? zJ|OT0ZqLCW$!aQ8+)|fOB-0eyI9bM(f$M3jHukksIG_-&h(lPle@BNTmCU73_9yDE z)Kp`lX34a}*sDW0b`DVoQYex&(k-n|VHDD-fkxXFTPIW)3QDE6PJDqwKHDoYgAt|> z$O-orA`P>Ix);RWTpq9?Ow;o)?ceg5L|p`EIL|Qi8A3f&MvF`d=XZ^Cp|!}Yw$6V) zF!q)NJ-K(+zxid{%d?>9Oo|SsFQ5>QC`X6sm@2^w7FD%6r)<26tu*|9gSL$#R3)$}S$1e2 zsTWee;y7EViRDj<*jkD`>@1PXl&Z2uJ%bub>BUAMJ`FWHpQk&5S>J6pZ_*55GRGE_ z(LFMryh#n|g!tNQHs7tJ-3hE<%#b%|2w76Gxk};?F&@+f@tyXqiGYAwOPf2Ysb$NW zvtG9ht75%vXbV;A6#8YWP+qd;#e5I*r+)OQALB@DG^4+ZFzIh1@Ye^FVBl{e&@;rg zg_SK|b-Sp20Cf}oxjt11A(CX?uHs1EL_?9GqhNbnX8ABCie3YQV zBX&6j0)GVx6Z{aYpk(j^0tm@i00h>ffBc}ejrU$@O~W6Fl+1`&BW-mcQlQmUD0+qB zB2tuv_hDqv()X~z4`ZM{6W(8Jxog;`%?!%7Gi#Wo1Lk7cpMt0`o}4})Gg0bAcFi~G z_E@^&YX}OTjK78~AvTb|>uaQA%z<6tUlYLrHM`UhXC$`9FA+WQrhmlKOY|oCegyv} zr#sa}{tq~1R=&@gNUi>m?rA~He~1pRp=lgXxf`S*{;s2jS~~s^CqK!*$Kk}`Mrkxg z>Jhyvv*?d<0GdQP74qZ=pv8uTSi%HLMyt)N%TiIV5M2>E7#4*M_=gR+1+`)>{6hJK Ha{B)O!;7~r literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/IPython/core/__pycache__/displaypub.cpython-38.pyc b/.venv/lib/python3.8/site-packages/IPython/core/__pycache__/displaypub.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a7eea2057097dd912c30c4f20640f826f2288f74 GIT binary patch literal 5045 zcmbtYOLN=E5e7i;X<4gv630&VF{yH*rI(@-$5opskBZBWjk9aTRr2nEdB7uJC_(}O z?#w_ES#&D3a%E4+FYv*x%Efdv)9T&rTwVSPR+bzF_@C zvQfGpg=!GS2TX?kfCXH0rW4ke3FgIt>b6=>20{wPaq5$V`N?pU#3I&;C4Hs`f(4-( zMSRTESZOibX|-;$d&Lk`47r9v)nO+CQlR+}WU>mnWGad&1*Ps7K15K4n9p6hDA##v}4iZg{RLKs=4MhlNM;xlq$mBjI;jUjb0oZrje* z?j~_RJV+(qj|86Gk3*%u0wydxe6w(jx2V~tPZy7B@t}6`kFbDFtLFrEuM(_(VfBI3 zz%Cg=X0R4q#*F$GmTUDIz~_~0qX5n0 z9Fjs#{(gsP$wQ3@`4Ly-R;+y%LpAs9EJllq5p8|o2Pd~aI6B=fR<-RXQfwFTg%7)< zv81B3NtTk?mR++a*H?qko!R8mvStVUPv>2n>L<8pEEJ1$)Kv{cOzo@InfYwvkJ!RFP&G`J?jsh-#gD5&zjT5)IO@o8`CDz zq;VZ6d0Ck@0{fM7=GYc>yglo)8-y6l>T7q38gm`U%HOnI{;!&474;$yEOnBZYpAUA zC|c@e6lgm3L=LwLYi&_h=jD_IiJuPV4G9>SBW#GoLgm*yj1=ShNvZ)4>In;FdjZNh z7^5gTp|1Pr;iLPeu;WuIOR1Dl5{+3n97Tc@iU2J&x0&f$+mX zC^W(aNe1h@Y>Omdw)_HcrDIi+N-+N&26S~09xMY%zoPz=m`HK?(YzJp(ddw~P7)bx zC2=%f3hTMp%s*XemSp5TlM#e6M5t`Ytblf$m_7<#q(D>=R;~~lsfo*}Jk8CQD7T|j zm)4T#`=^|$r-CQ_CR(Pw$q_5F8v#Ozl9C9{VsTOkDy`k^trLDc^oIcKQ>sa; ztXl1A&K2ti0H4+}tAaKURaU`sRvk%zw%sxWLVgQPT3*E^tL1Qz*J11qC$J{q{#K2#^&yOH2IG0Q_R+cf%M*x1$iA~e0Bz{{li z-QV5%=yFE8p9(y>3lF{v%~=K8Sa?PUn3z@jQK|;!QAqjPDJa+pHYKaxSo2B0my17! zBt_)ia@OFIHGA^*IY%tcZ(}!rKW7)W2kj>91Y)GQ=VdL=%lDS}f6engOLFTV|4@&;YDaLFzgdjwiMrj#Ucou&{|l%P%)!)fSY!**-yZtKdmpPF$W<4ebk z@~IsRFK+#WduCyyhaVYe`-hDlZT%|P;lYzREq4$#o9t>lVikX?SV;85dBa{T8w^Oz&zj^+G!^1Ta}+Px?XDiA`adIuK` z>`$#T=cO~XX%$#o<)urRKs!iD>jr9@xXB;Wg(5F+PTqSMfb*!7sW0A4MS4Z=+QBkC#<=i)=8FN=;ji2YK X^-KB{M6KcCUTGj<*D7oEjX(Ym2~KgB literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/IPython/core/__pycache__/error.cpython-38.pyc b/.venv/lib/python3.8/site-packages/IPython/core/__pycache__/error.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d12b6dcca2c1e6263fb718fe2aa1a36e47277b5b GIT binary patch literal 1664 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 literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/IPython/core/__pycache__/excolors.cpython-38.pyc b/.venv/lib/python3.8/site-packages/IPython/core/__pycache__/excolors.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..90558b94d8152af457c110e4654685974dd230f1 GIT binary patch literal 2665 zcmb_eOK%)S5bk;G%y{j@o5UeR3R2%TE0HzgK$HlqD8`DA%qq%55rfcZJl*z=JuiBC zy|(2DBA_P<{uYc?f}&z7#Il&vzVP(p`~X#v|)BKCwD_P?}VM)3q6Z4mvx?z(7#8R z$NXo6`8+sr!Uev-{S$Ixggg^)zkV9wfduYE90vBh>KjW)@pHXH$j#5v4Ob^v<_4k z79o$EViZJNc5afZpJarz@Zks{9e@6-NfT1*ZMvon@=@AUzg z(f+8^fadLu&dqXlJIylAG;j);s+o<0IIl8Z-!`vnYipDz^pn$6k8}j;>jN!r_J?sI z(|sNpr=udyxpB8Y6RJd7$m=|5MGcAp8I=V$=0@d|PC3_`xw*kIALj#e!AZUNzSTk7r#wD0Q?kl~f{N{v%Ug$S^Drj9( zo-wLiG!%9;nsNX@**p(}qA?nFTa67^Z5<6g;~wat#n6XBi0&vCCBlvljq*&aRA&=2 zHS{-Aou{GSB(bs!Ik+sazzGM2unWoFgU0oJua1(1L^DE^aHktVIB8%1z4Za9~3t zIA}6nS?fO%aS1m6ytOLxYPCwM8DSOHxXL{VC#GKzjeIBmx|S~g~f?cQtl zG4(Lfw0#PUghsdvP4&cnYD;?;8mx4g&79{Bv`G9Ia7Rat44_=|4aMCVxg=8<|`#c+Tl)uAeETs@v zU{?jxSQKEhRxWbtqB&EHpC3=m*1!?(f~Zblv49+A>s)Xaqo~1*qMu=_#`GuF5@sE- z|MHxp1{EST6C8mn5LNugN0I7AQC_l1hWt_#eLaaYvm>seEsDdbRn6hO2>4(lKLFME z#}4ek(JO;R8LzN0-i_>7cQT< fkTGl2wU9z(> literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/IPython/core/__pycache__/extensions.cpython-38.pyc b/.venv/lib/python3.8/site-packages/IPython/core/__pycache__/extensions.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..bf60b6f838ad199cf391e8222e2a9b9fe1fa3a2b GIT binary patch literal 5834 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 TOwCSBA*@V2i^HI{|Cjwgelm5> literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/IPython/core/__pycache__/getipython.cpython-38.pyc b/.venv/lib/python3.8/site-packages/IPython/core/__pycache__/getipython.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..858f3520715e666b3cd06ae5d23cd145058c04fe GIT binary patch literal 567 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 ba+P*X=1^ER6saz!^H8T%w%nOdW-j~}JAiGR literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/IPython/core/__pycache__/hooks.cpython-38.pyc b/.venv/lib/python3.8/site-packages/IPython/core/__pycache__/hooks.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..1ab3a40fda2325d211b918d352e3312b308c185c GIT binary patch literal 5740 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 Y)o^V)|M6>$OM$oC3K~H@@G;i@2LiVX@c;k- literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/IPython/core/__pycache__/inputsplitter.cpython-38.pyc b/.venv/lib/python3.8/site-packages/IPython/core/__pycache__/inputsplitter.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e64d0bd3d1aead004647ebb0a5dcdd8114a4f7bd GIT binary patch literal 19244 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 CkSgZ@ literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/IPython/core/__pycache__/inputtransformer2.cpython-38.pyc b/.venv/lib/python3.8/site-packages/IPython/core/__pycache__/inputtransformer2.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b1b0e91c7ac65921ea118cc9740b0ba5d45a3cc0 GIT binary patch literal 22027 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ⅈ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 tNrTJlZ${!%FQBwo+m`o#EEFFW_Iyo$1bU&F+h? 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 a%k;SK+OlwOm*>4ht7}Qxi)GI5R{sa6R!D;Y literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/IPython/core/__pycache__/macro.cpython-38.pyc b/.venv/lib/python3.8/site-packages/IPython/core/__pycache__/macro.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..46ab7203df29aa95df33f7b164e6787581b05dbd GIT binary patch literal 1757 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 literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/IPython/core/__pycache__/oinspect.cpython-38.pyc b/.venv/lib/python3.8/site-packages/IPython/core/__pycache__/oinspect.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..4fa45a0c0ba844dcfe0ec3df539db11d861f4f1e GIT binary patch literal 24630 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%0AWv^=sCEdXn&awD zEVrS<)lcu3E_6j1z*;wlvPh@5M7D#~j1pjrGtF@Aw!nrpV+%J@ShHrqC{IK4KNz_# zGBRAEN`7TgR%N){u;F|JI>O=6<^Wa%7LZ+7Ibgv!4x|VR2l!&j)3ATQHqp0>IBFSb zIoLjshN(dD!>o{2+84PnlS6Y~ z?(Tab)zi~h+Q%*BWvyMm=PW%Y1`^xo>r2J%o*|||Zy0qG6Q{m{fI7W?h3YRcmAV#1 zC3ZYpNmoK|AN4ED`znK9L;yX_7(V$jU(128bU<51fgC1TbmQl^+Vdy{t0>^ywrrZZ zpaplh^3!R1Wfraxtot8oWzu#3T|96T?%1$-Wi`r%B`c#I!0P3$LlVLk$YGUXqf+O4 zSwI4;VAsWZ#V6>HQHo?T67x5pu}=!86;wu4gXoA1#Gi>2j; zT6jd7z<}Sgg-6m?-@A!Hxo)x3fO_Xd1Y2cyR^utmqo(&u!o)3iXE^WyKrM;cpgVJx zoYkPPH#M>V$^!~0O{rhSkC@5TpJwbQ8O$(9(U_L1$uDYqgrF}n-Kv71R2aiy@G0qg zvBfsArTQq#ejEXPyy!s%)iqHjBDcYD?b=s};~qqL<8TfXjlLg3*&vSfEMZQww#uWC~GVR^&KJ`M5y&uvP{0 z9v2bRHYF}LP4zJp(NsgGT}X#LHtnj;LWj~oEJFE??!a$zM#Vt_o;2i0;SFU8#TepC zld>aIM}m<~9kuO(r2&yMUyrD3m$cNJe6z`Z8^;87bp=T$Y(^8b( zNE{{R1$Bi6#PC@#LiW?IkHe?;(0)cj%{RR=d$PR_>$&2gltHMLT#t(JYAFA_M zRwYi#X#`#OJT+iPz#hPb6*^zFeO%0i!b5&;{0swO4xVO=td}~+AYD)KsPZQ1Kvn5%i$~V2+`-TB z6-v0{>zwUy8h)RvEWAO6ya9ZrEC;&uX}ZK@i6z7|*H&dI4Kc?iT2U{e!dn(SgG6>S zdYGV_Uu7|CDv(6KOW?`(MKO`;3)Y^`6%- z@UmVbM+s4$=H6Q>OZ#xUArS2JFo4&aRQp0<3x>BZ6GM^T3OVYe=Cm?*XqpfOgHm;e z1`qSNwh+Rzys-uNCQ2F^KZN9=%5;_<_Rz(3YP2VXkAM#;YezON0;*} zH?YU(?F$r}L%!XEy9)f(UPPHZd1fG8+Aka+R%bJ(UiP!_QOoT>rA5jGZalvaz8<|? zl*f`7To9LYgOSfpkGsp?~UElx` z|8CNNmqB2!SgAZuITy~>Sb}?5*DixGYE?KzJq(OR{a#QTW(kF7;NI869#N z?!P8HjfiINm`kNxY}3g<&UEV?NYT}6)YGYYN3%Tt5Ve9J?rxjfxx)fKVv{~3g7@*&iTh96JmV!P3v>U z=b-*26}>UFlSkb29lvnH*>OHECUW&^FAv=)RKV9Epub_Z-az`)0jOF~>on}8*CZbb z;huBdhG0J}&rk}(DH6}}1hsJT_DgvCjsr&ct7NFIn{YsUKuRq5`}F(r1Xc0S)1WTh z;tx>AEPC(*DLdXW4kF#!vXq3nnZ1xW4i_=r`j$M6wvIzbL#+?Lb)TLEw0{^1^ZPe5 z=zkpB?8c#;9=L)62q5IC5yf@za!B{!#IPNqwmeG;n7?jTYya}N@CyrT* z)vsaUK`d1r4n<@lsov18GE{5oUE$V;N#mGJkA&;V^fN%n5NIINwzh|`zU#iA)g>Sw zbP%JSHQ5UDQ)VljIj5y&D?l$xMi(O z|2x>zR5fR#dIazL%x17XqORed=XWo@A!Rk}cbId;9ho}RmjNFj1`s{ywgT?>fM`^S z6Al=w;GD4|fETg`AR5RV$Q=wBa#2Sg(PxZP+RBkj5d7aoGhO@C`opJ5OYu|GQlh1P z4LKqk!Z`Mi82_gX{uu+3&NwTKlQ+{}G@dB{C-s)4{t3&7mP@d`h$WNSBUP9A7%?PC zp#h$iTE2M(Vv2<6~i>%off6Rpt6&!Y~rFeFK`;vQNBKLp@og9O$l*FLy`Wh&fvVp`zLyndK>Z8E z)pr>PnEi9c1l9^E0DXXq_dGI;J#!h@Uct2O&rjyyUW~Q8fRKIcwL?YdFWc-JvpYK0xAlAWJ1{H21hQN1NgEmz&T2i9Fb|Q(6)l}E2UcO7(pj}l#UZ6!7 znwwtAwah3aTc3xuwiS%vU7nl$*5CLtl>-PjL@(&e?brl{SR^v=~w!=n$fqR|` zEMs8~>OvS|ht(h~F~V&3iSAjvAR0(fa~0Hn@nW^K3`UCiJ5*L{I*Yw}mwX!QrXf#oXz9e^dZmE?_m6}7*nnraw7iMOwEn!9YlU>lI4CKiK&MQeQQ$e96xb z(qOyFLJV?XSwc)CVh46j@${pNEsD=C`Gp+^b}P#-;uIJCa3)^Q?iBpVonqwlivAR2 z>*+hebnHy@vg$YenO?!4J!P~Gp@+Za?@6AfaViWw*(mDg?gCnz*qKCMCgDO+@aIk$ z&`OVZ90KBujmga{M2%nSM!MHKQ~uta>7McV>IDoKw{FU;N_E zOsm|R-QDZodDDEuQV>>=f)YqMBq_80T|2YUd~a6TxEneO8|8Y@9lHyn(_f1A;V|cZ zoPx8$)4dslE71Y&Rh;G9)7yiV3MlXO_Us20U@J^l6Ep&@m_j`Bt4wcF%sJ!`yQu8SF5x4-($t-2m<4N6n)4DmwtUIF~)oOR?jHs}CnB$Ri<#%93 z?*Q}sz@~wcU-FOc&h!8oI}5G-Iu6)>Kp^bc8uk=(dJCwnbc$+)LqoH$ueT31{L9`x z=I{n!g-?7J^M3%s zI%5Y==W)#XA@0+Sdxu7CtEV~Yp}DpD-oMG*^6cY0YH9UnA$kBkS_A~y>U+^q!sr`z z_&q(6jbk$F2YUyR`;Fc~fr$rin$iz>_RD|>_Tm_NacA$&sD!z<)pyVuo>*rOkmR30 zsRvh~d!tUgbh7#-V97r^(MY+5{};LcOrMV=U7_#d2&W*tX4=jlkI+v_ur#DapccH8 zwn@r(hHMhu>W|4y268T0I2*dpyV`TU^q#!VNOia2dv4F|^r`Z&BriIIL2plv_7sk4 z19icBut8~mv^8X4o=DU+1D<}cKAfkas~qI?X`hvoQz@5OLJQd8<+6+O9im@P+tPe5 z4(2760IKr`yfCMIz@IIj*M2hhp5a9mgbm?pyf;+@%cc2&^(HCIHX}v0bhxFID?*X?3jOnkT8~7HACHm{w zyfV(|{5o>Y3@QSMK4rj6XMYJ&Q?q zR*H-`Zmc!F+Tq163nTp45T-HWS4m zR@`K13y6!bJOGe+pg4Vgd{Ym&9m4i-C8=ukgL;GyTIq`smdcnYh5?F}z?ydrkD!Lh*E^GEmuIh@WEN z{pqn|j&RUiICh*gp4aD+wF5@KPPrMSbZDHnPX(^QM0>fm=z7GVL%o5fJ)Cug58he@ zCKfLnu2&nYu$YK;$+O$Y^Be@?9U4z)tGn2@)z9K(aa-VJF8XF291B|6knyUoaa38t zTt&6h}G8J#_V_&k9eqvD87l0k1v0#nbCW{L(5^v>0Owj{~56)-2z7 zDxs|XP(QJ!P7deikdmVx2g~6N)`j<}%0gZ2(E>^=plzm7_;svd@mFxth(Qutb|7|% z!vy?ZcX5cE+S8lnM&^@p&JKn|dS;lL7CpSddS>A=^Zq{LNk0v;_h4!=-S4La=PZ3% zc=}0HFhW2?>FGX*y8s^So6135Ao8Y^!F>?X2ZvM*{j*UJa@T_fc5;dkNtWo50jh|7 zTis4f<3n{pErH6@4kfNR1H*yX>T%f`oIR?qwd-;>53Jq+6!i4qg&0kmn%u)SppNHp zU?k4q`Y-tHidVnTs(*~B^rqnHJ=lqYN#NC6N0z$5d>+`XwBQ>w4z>RYxqp@jlqk_~ z2s`lEfoIVW8vT(72F@vQQLZ;5CJ0jn2RFbTR)_Cde8YDTfGN#G6muY!-jB70t$^!| zyKu1HqJ@NN1N6{_s8oQ_n68;ch_~5I3vQtW9@yP+T6ZHQkCaz?1sI|oh~|?~j^Z=D zetrtBALoouxe$aWde&xMts}3%_-_6tEET%UmG#KMg=Y9##?B-JPQG&vLao)CMjJB_ zlxHCDO~I)B%`0z0JT2-J_7T^k%s>QnL>W_r7(UyZgd6BA^RB!(7!`%;!Kg|T)vp6F zTnwtJwl0cL!E4EF1kjN9HC%+FeIzs<9#&JHNiNO{N3^QAGzmJg&K zn6Rt;x&gDi5eS+^!E?NcE`?7Q+#|aN_X_GT`*)Gx{ASe^C8a1;SHU3&c%mw3B30rW zrC-IK7^*HA1OYh`6)K=(XlpIHtx%s)S<;*(%CT3Ar_;Xa$Vxw%{j+*|?<%)&jE!4&mZaSY%36+Cbpry48bP<+>c1&MiN9vGARIIKx)_)t(%Go%bIZvV%UC!7fxNu{++XXw*# zke>L`vVOWWmYLC+0wkrog!PS!m5RO_v{J!UKb0$6)dmL-UXmh_KBG2$X8GcUvmj1q zZA1PxW1{EhtrFTgOdbt) zchcXlmfWO60;r(j<7={l!S00mbhXIjyAj> zYzMx;Fxklwrke)H)GBY6*Z|Sout5ZmBR50cv^otEhnt0kjM8ORm&u{bi>Sp0+0-c{ zoh^N%1SFK!=6X z5Porx58?;id27zcNeSeVNP>}L8b&jP{!c?Uio3(240L=*fi92kDpM$(ziGlV45vZB z)=hW6B1le{F`mAr;_y-opkUsBTTX4&I7&z%prTRP^Kh0W+J@4B=#B`S zdIb1Qra!vRe-C4aHIerF`zlaV} zssH|4&JGSd7g7hex1Ym%-TbF_juk(>Q<5EeOGjCwbaX!==;$o&xd4Yo#q4l5yACPO zr+1DQi6?#$Wt9V19oi|fN!Zc@hF1)aO=K0DC%g=v8+(P1+%FAb78p^`HeeRi0yz;_J=X9Zq z?3a)P=na~>n>;=c@6lemm1+xKufod2xeD(-+>U28w>`)yIo=fI!_+@Pi;IG{aTBCq zcBj)0D+C=czj;+6!k1T@yq%IXJHSn7ta5yU-b8PHhZ977iIJn6$nyo1wnP%t5+Wok z+Y;F@b2sET>)lD4E(35Az`cEVFGbatN|)64kw8rZXf{ySf5nqNRl$|jIs~q-dYZ)? zx~cM_Bz+-UR+s@0%C>rj**QFe6A%RKO(yodGT9Fy!rojz3DF+V6_))o{o8=If%hKeXPx77LXYjiW{yT$B2HZz+7EaQrw}H5qOUQGEdtRvb z63acwV3~o-pvs`d;3@;2<{*VFgnm|-0p8)r(!4JPtGR59!w?)7nFfvf)91khQ=c=ED{7k{E>?55FXdb m-#d2E$vgWN?%4l92j{Dc^uPuUpS;hRn?CHgpz8fU>;D3fdNXwZ literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/IPython/core/__pycache__/page.cpython-38.pyc b/.venv/lib/python3.8/site-packages/IPython/core/__pycache__/page.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..40a39a6b6c80348c9f8d1bd26eb869c2d115ab0c GIT binary patch literal 8106 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 M^UgFwYj@(m0lv~Ong9R* literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/IPython/core/__pycache__/payload.cpython-38.pyc b/.venv/lib/python3.8/site-packages/IPython/core/__pycache__/payload.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..dd3fd1dd9ecb097b2645618dfebe8394113df5b4 GIT binary patch literal 1410 zcmZuxL2u+V6tDwoB29Me>EitlAj_D;BL*Xkl5FN>Ej5xkRAUjo-|eW|FM! z?CgwE3DN!#IQHLg;*bLuPW%N5YYqY+>Ls|KP1Ec>YD?;Omi-n zUTOn#Hpvy+J6M`oo{hrrixLM)KMunO>}yaN&qU4+K*0(pzEqND?1kdl6jb;(;*%k* z2hZ|sBB!O|Cn=!seJiy|?Bez2qVp8H9-#peQKasGJ0<5d^2CO4gnL1eWJ5Xfg)jOS zB^^_v^R6JTB2n=sA_ z1+QdY>Z`1UG_$rYpJVa7R0%M6jf!iAXT^@S%%&+EGpX5;Dq-iUo-}MB)0CYc!&jgd zN*V(h&UFPdSg<^U(N)6g!E>I>-XLQFuz9JCEy0S(+&pF<|4ql*mCF zo+VIwHmcq@S{CqJsa(|?kd<>#s7@WkofNgtivlu%xt@k}f?23ky89>*i;o|jz8-fsdYt46#vRV6Sk{|%->^nz zSWMqRL;4{dI0G8cJM=CMY2d8x-#VEai3znyU9)4`oBL-kBi;^jNG|FAB~|uk#?Jsh z4foc(gKj-gz{Q%%Cpe=WG=#3+zXg3g?mx&jr$M$zQ^bz(RX8MS3te^Bns=?Sx?RKG zOj6)#4gM)EuEB5b`$pjYkRA;KJi0i;`xnP`7{~Kml&KvL;`n9B({@F<7SM81R$#Sl z&3o3oVbYAO6w3a-_p$2$P2dDhxD~j~ti4hFI2L&l$I%ByacNR8dXzMePWNfw9%ZG7 dHm+h?3byqBVb;Numigy4O*fCo)_@NDe*ymIXifkC literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/IPython/core/__pycache__/payloadpage.cpython-38.pyc b/.venv/lib/python3.8/site-packages/IPython/core/__pycache__/payloadpage.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..56187b1bea9509c7a3b82e110c452337a3980e78 GIT binary patch literal 1411 zcmZuxO^X{h7?$SCj^phIl=iAyI&^JAFM$$D!e$G(EK8GI<}y)7ibvh~LXzY4Vnbnb z?Y+nJ*gw?6Tzl$YC=~igGub+&GLlAmU%l_6=Y8atCnqz4Mt}M}|0O2m54SjOAr_C( z%@Ttk84*+j70oE-unOuh3n>v(5sCOM%_5PA$y<`eB6v>HdpGO}>-er}xnMtVBL#aS zwNY)u+Sf3wHNB^N2}@2{oJRkyQc+Z2)89oqymfRQtF^Bo2Y2zz=P9H^zYo*QOYc;D?Ef+!+ z)*As=UR!2c59ZW4@WI9II?1l&4&`v(t`@w~NV;RMTU~Q&orPOIf-shAi!@+rjQrf~ zIG)^%8Mka(s-pC{Dqcv>iBP7i_-^TsXi!aVW)_H6*i}s*IbzeWPfWYfh3q4ju#bJN zi!|xOnqTVxr}~*PjuhT_F96Oy9yOKMym95pPPSTEnUCA)BtslfqZ6FZ=Ev2^?)iec z(jZwWt4cd@^^@`JZ$!_r{_D}o*4+wfSZtb(7gtg&wxyKS;$b1SUq8IMUX2x86;Q!y zJnbdj?R1C`_tDMg7|5qHngp&-X)yf$PGavp( zhK)B`x*IKrt02lyz?;U`psL=J>@zR~60*~>;LyzA`4T8zscvcTo?ZSgAAEobPs|17 zW-xw091Lmt>R-X6)U$MvM*VclH6W}_AGxn=ehk)or8Jv5QC^MhF+N^I literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/IPython/core/__pycache__/prefilter.cpython-38.pyc b/.venv/lib/python3.8/site-packages/IPython/core/__pycache__/prefilter.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..57dc76f979ce735b72dbd64bfdd8b60e3b5b6be5 GIT binary patch literal 20258 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 literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/IPython/core/__pycache__/profileapp.cpython-38.pyc b/.venv/lib/python3.8/site-packages/IPython/core/__pycache__/profileapp.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..6d385775f3c6fc98e8598ff3d54f72e2d3a1029b GIT binary patch literal 9530 zcmdT~TW{P*cIK_w6xEVi7t5B%7y34KPo(x_HoLR&dY$oYc8rV`P&Y_-9OxOy3>d*hl`(;Z}{*@}jKLeFdaK&?~qAzb}9>$R}nwOmU+o8eg3c5V4w568O=x6z$&CuH3UC%aSbRJZ9iyVLG; zcgCGT`wAn>F#@| zpJDT;&vPC13xVQZ?Z%yMD*@e5*cCl!?B-<|D zRY31DI|q8_Bz*^Uhh0Jaill#qY0s3_)%2x(zvuYS|psV-}Bdl-n#ST z>29)t#=eNwf{@2;+g^#BRqh16?P!ZL$B&(4gF7#R{>Z==PCQucL|qVKm~(#sDk8pP z+aEYz20iDepWF7gv{TD1H5rh@vnv9tE8wt4FIb z7u(!_UsIHag8K<~{N8bCIIFu(&+l^EJ{odN4h~+zJ4qyVX>gFla)J{HyO8M6fWDt> zw4GvIReQi=rxW!OKj_)GuLbJ^AvbE#38Qsz#hjRT1|mpy9l=9z${e{>vdb4-zLD93 znD&$Q3RJdvPww^2f(!31t>fO!w)0@uVSLRWgb9t^bwI!lBd7+*V&itBfpE$-R%>fJ zU-dd5ECt0DX_T`QgrVJm&^QYuEqd<}_XUq2Nh}p?*cC-5iK_9ulzZFxGKv#tfUSuo z{o;*|e~L7Vy;-!6t7bW=yIZ{V#iFyb5p*_klKnx>ZN-WW9$(xY(x!X2OQ{`^Xxr(( ze-VH=f7=g2e>JR_F4q>@c0M2shXxgt;zd%AqJn+RkK!U^<0lS;Xye4KMFZ@0Auw#X zz#cj~k=UYr&AAPCp;_gSg5x8Zo~~P!hCr?-HN-yBkb*lXiR~}pSbRw~;cE-G*Th- z=7qGYuu@K(_<{~wd0K|7@S+pL&S8^T1WS7TUUd*l#mQN>Z88d_<)(93a!W_8Jl*9S zDAei7T?|~bcQ!bz2%YKbIG3j(XR_VjrSmE|KaFoVfV5Q_jq<&;YR9?e$h!|7i;g(` z);>PA*pjsfE_qEidORw=%zt-qMobF~oii#uE#GLYD#>rr<=|TsXy{ z`|afVzQAgD2#S6fOR0cp)jCYoPXFy)w3aqVHt|NZBUNgHhkeLbkTQ^emS#M6OGke8 z1T86AqVzw~k|T#GRitv$U+xXw9f7Sr_{fbUxh&dxsaTb#BM!@Lxrr$^?GEr)^&?bP z$Mq0b{27XMWnWE{19eY1RQI(#?UC}c5BK#w{XjcZ#LS+)sUH|jJyh|m9@J#rWE#^C zHD)Yej;efv9-x_8dQ+~XR3$QnzOx>{-8mwPlFB6Qx>hm9%T(`M;_ln;@N3mGEsC>x z3{8hg&CDQ{_`x9enAuXpV>-o|3CP5IEUU#pP6=>?L9)n7vT;_EPB>H7-YVif(Erts zZYSOT?S9Z-8uSQ)aJGb##lxkKJ8b8pkGEdlE{^Q&P9%8gWAGXrudGSy^2&92LC+`Q zHBcy;q1&pZ&Z*~BaS`0g!7uR;3P zA#IcCTRNW9gF4luyitR^jdXET-qK%@M_Glh3Sq^h#Vgj;&J0>vRxg&3jeA~yx8rv< zxaYMj(FA+qEQ-w7jDnu9s6I`_3>C9foI%kt`PQg`&-sAV&-K>*MNDEGpk2aV=06XAQlSdXO; z-)fl=^KdOQ(6s$l&Bi>h6Z&!Nc}JoZ#L7Od*hHbIP1RJ>61V0nZl8SDhzTI}XmwI8 zY2OoCi@K@3!m8vN)a90*)ui0A@$#(Fk+e#5^i~y!`A+P6O&-!eLr*Masiw0do6(m2 zEzqxLmgmvI_PosYyl%t>Aw4%d@0)=i7CqyP#~l&$2`|f)i;qA%nQB6G)#zl40;F>Z02bdJ?! z5NNGwZ0wDSo^jsb6FAs58-Js1PO=7@c%!;gY?4huKbx${rg2C3$!2k%VRO*cGue14 z9$1)PO%<+psStU3cBr>qx_#_JdS)m#Ya@d=&0Pg9HG*jgYU#`08NYzXVmX;o#(N1^9-x&572e zODZuCILU*swzIMk#7AzxK?UIiA||*j(5INUqL#brBHD6pB^x3dtZ$T_Ep9D3pd~{) zDghl99iDXP6%~l6Xvz0LsQ})tfA-avk8hWU68N=fIsf@POuh$yW-Uq zHFCGSw;hP6*QF?6+ZRC*b9}w>*;mVtp8T|34aO-p2tTag!OYh*Vr9s}kfoDn@jM>( zR5;+~zLvm6>}m4~oyl(unJ&=NE4e9?W*<^6)CBQM&|_eQvvz9IUfhTg+KV>GweE=m09_nxFsvt8e2{;-LE3bQrHA*3e~=o{*a_iDz_F0AZo$C834#ih4w2q zT+A$j<_LH_NYWcL6M~Nj+l!Lo(BZgs14^D=reUKoKxY7r$EidbC~2n)r*n8CzLPGU z-c?4g)wy)&Rd>?wuS9elk-0!1n;&6+70`P~&7}3NcqMpoC%qsSQY4_3O4Ie@JT`09 zrE{06DE-!}xDVS4qniI6(uKrP{Kb zR4vVxEt9IPHRMwhPc#BreQ{W;Pf#7v>k(f`h!6Us92OcPme7EM_5e5WyHt#_ES=Tg zqP=v6)59;8!d!06ito|P-=pIDR1nn4#w1&0Im8dBJ_*PG49Z{nh(URrS>=-$r|!BR z21wAwnZYQ7R+EW3F-GJF>}NWHEAa_cX%ljW$&(H-ELoSX^M~m8b6oK)6mXsNr)etw zeq$L1M67+MeP@{_?q*&4FVnVa)&)VcG9%~(Nd>?j${;BlqxfwHIWoSIelHLBh66D= zPzgDP@|=_*O`Zvh+gVLc0=zGxyY$(UUMC!|JmMdrC8M7*2n5=KzasAiARjxo0t5|k zGH?|^AF~n>AyyQ*<7k}#2GR(U82$pqyMO^f0trPGSHc3g_Hh7)I^XJ@l+Q_!y8zQP zFFprT;`dRkoX}U&S?Nz`1&l%kZ8@F);~TfgJGbJWIX7-~c^t!Mw&Gj?PSM?L)+4k4 zd3OE8E5h=B1i@05uN1nRZ*u#T(f=#PR^H9QdBElVE(*$AdNQIb8TscSMs6KrFYY;XgIJ1 zMSLLR=_VpNWs_oTUB++oJx8{mr$~=_woK8MBeY^fTRNZ`wryBb3sE2>O=n779%`G# z*bvTvi=)O&@9`ag`NpsmWgwTCf_HH;5zrBmcg@a*-&^PIWGRqb;+fW28?q8Ix|{Z@ zG5I9+FQ5?5p->7#VHjj-o4^pZnqEG(L&s;22$hh8UR?i&xJz8eoK{WTz%4%<6ex+C zR7l)I#!Sfg;Kv1Pc-?hnlKNBu|wn0ttOne|4O zW3)d~_UHrBSUQ`3d!g?muyKwI7nd`&EhfQ>m_m_$_%IrTtameUim^8U7>86m$0dNg z{G~h*EWP-=$6o^fQYI7uEYNvAlPu|tcm?<$?x%x1$XbLr&J;2WBPh_y#-GSPL~Q$Qkf3;6L%2m~s-x zy&(G4)CN)rltwtGrVGau?P%7BEh4{2VIQek{0}IOLVM}j={u#~HTG3(kGhU+V>&>& zL#LQBV91jhdkFTo#*mlM4$M8H$jT_2b@6lgMbqkz?biS!RaOh_?)ZNGWz!7t^>V)s zs@lQiUTx3ZtFKFoAg#ft`_`TX&;}- z6_j9-X4a+bdTA!w7!+eHbhdEWG;0-O@tyYMu-wPfkPZ#Gc*>B%Owt&JF`0=>4DyNM zo~#V|3}4)Yi;AGEojZNPrQ}%ZHac5lIbx+nxCU`5{*)$qR1lAn3;7yXzmFFlGeI0f zaPXCw;FzLL0<8k2%A_JaHRPW`;7iqhZPqNb0o~%Sz_Q0|>j|lkC_W(rx}>!t(?!Z6 zQS7_D@B(lueXq^Y*zk@z#5S30MNMyxp1gO?X`Me6?vCdl8N4IF+w_X23g|w@iv<14 zfjjOGlBnnxUs3Z@DxOe5Zdedd7tg7XPC!EBMnNx!#-C9q*?_DrZ6=R%4W#W58&rHu z#gQG7+a}@h=jix*T+%re@R)W)w{+~&cc!NO#xzXTo@khsW@=WWafuXhheh6o>px{3X8oV)5pWqY2b*8^TsO(NMxD%koDMsngdiAj$%9oZI zrV?xCsY)HGi5#jM6lJ(({^8+->X61r)uB@X%LDbxt(!X8=%#wkG$xF?F=J?kX*8^cHPLJ|?;%`9CW1m{%1EHB HHJ|@CS3E`V literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/IPython/core/__pycache__/profiledir.cpython-38.pyc b/.venv/lib/python3.8/site-packages/IPython/core/__pycache__/profiledir.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e21eed7cceb859c50fb34b4f741f5f2143a56208 GIT binary patch literal 7387 zcmbVROK%(36`mJ|6iGd;*m7*g6UR=>M53FdNm?aM?D!ElO%&Ib5r;rajpq)0v$9+3)m!!6bZfdd)0&Z`k0e%MQ;#J!WzRlRTXSev zSq<%)T|#@FDR-nsee~uP&+zYW*;Z(Dd~Wni&)jspP2=XRov`bBMxXl~$F&XSaLno_idsjlp)R8?p{}6TQBR>Rqpl`(Evf5CJ)P7u zRFg(LQMP7D6Q0PeIeVVfv39{e#-<<1Y=+G~me5{g%WR%4JeFI}VdNM_R@fqY?y-!q zv{G%dy$<32ofqS0(0Y@-%w7?#7ts14yT}@%br!9+*sJU{(K6T^r2BSM&82Hz2J3P)4*gh* zZ6oa3hxB*HfaV!a7#Q3R`~kP1&(*4d-};fWoxm6bHZ$&Hq3dR5VfOp3W0|4jd%?1i zeNqszQfr{mWy6haM0_`}tpRt!o$Qk!pIG0v=MMv;>ko-q$MM**VR73GZLv_;r8rSA zX^Ysl6Nt|SU4P(WqjtVwZ^s}j0wc`O7@8hV4dPvJ02ZAnD~?a6k1FZjA{9Gsm4nda z;h-O>eTTJlv_i**{Y4ksAv`Y{_4gm8D7VoQeqz~to>0M)V7 zmc{_llhUpdDq|RwEQRWpwpSWsY)jv#8RbGxMf6M+da9zQR_LjVp6No*jOdviOM7$s z65v>ZifU`4*RGnL=Z8iBmL;bIBNBG?02m|~z^`Z7&Gkt2>|tX*nr)|3+D?F#QT_J7 z3!R=VK#c1+Wu*8)qzUxYwtUBn=2O`bzzT$m>cy_84*ut3<)jtOB|^@JYK5Mt4$$Y7RP&CgYISXEo5l#owZL{ekRpz`Y4auQJqK4lOGlZ{j~mZo@1Q$4jzUs& zxgyh3Q5WR&-{^F1`OQO%*DTVB^hdfuC@l2jPk0HXEqPBF%lk6FH&*z1DDA1#+S10# zw#wH>bLc6J<*~A_$kOMMcTST+eY?tU%aE%~`c>YmFd1tw{)OZz_at(pBLmc2ter~N zdeykK4~+wz)r8I;WNBBGrP1lJx>XIUTeWS4?|lwRzpE0RhnV}8#ME8&YxQ1AUxPN4 z%-@oK5U$cNGjF_O#4gi-eVfLn^T3A3hF6Udjm(SS!N7mhfISAVFT?K`e$eb~LqyBQ z&@G=~5FEG~mz&4x?Ff;)uCJ2C>2oQFbjT@#5 zl=5NaeCPzZsjnE$rU$hTjO*9$-Mq8DOjZ$M6@Av+G#xJp4Q^UCP|IVE09OP4mggjl z^jpCA9U$2Q8-RyH$507i_s|Z9)J3o(l#u{5gPWLum=0!S-793Ifzh{l4_1c}Fs*|l ze>t#&5b#eY|RypWTTqeu3tehbH&Hrl=$Y7nK06o*(HkBO4lTWMnl#MYa!Gn%)*m zKf=V|WfW4aE-%W8JSWe<$P`)mS5?zcYx0aTgWkGaRTh=ee9_zl1^yxyPv9_NvWn*_ zo?s3IkdSNzmKCGnQ+chSaI$Q%_^A@__f_i1qOBMZregp}Aj%<%0`is7Qeh_(llV)R zHL)Qwd_qdGA&!^ghC*da-P34$3}#G@f!bl|5loq>OxxFXRne!9)qOemI5GMXS}^*2 zgnP-mf>~ZTwO1XhF>nY6ps%&`+t;sL`}BIGQFIuUq3sk)w`St*_MP=Bx7Y998hw&0 zj^+1vjLBhg*$FC>`ZbL^B5Xm704IJSFqjX6BBc}R)NIsZJ`+!JW#eb4No?WERFG2f z*HJ`z&>e)1OMC3^q>4m>Y3ZcqJv&kZZXJ};d@O)uUj+9(ED1=Kl2TXZ_LypaHl70Llh92SxDkvm!!}vFP?hx0&*1#f} zr9ZN~%=&(TM&fp*EpoQXt|r>rSc4lrKURbDl(CH!rfgUE<#?{JM%W@N!5WohJvnY= zw-oAo<#7qCNgs4L$MWd!SIKVR7wwKYaN(Fl2p*e=05}b03-nYk7_Z$+G2|EO;Z%U50R?C{8z z&H%|8MM4GP-ZD9I{}5qN#@3bWmvtqaC$KP90lYjLiDe4urL`hONGKRwoXM|Y>V$!p&_Ry?pttdo7%2RGuoU9jYAheeMZ!ZlF?7nr zloJw}KIEy5Ri+AgYUT&PvP`4}K2pA&HtAkQ1YrN4JfQ>-Ib&T5quEdbAPbeg=-2Zmq1cQ`4=f&AnseuR5$2j zDQsj)ioA^iJ0a0!&{(xxGYD2U@(+s?VFO#Y;F-wH5X2C8a1)sqE1(}~Uc9YX=S_DL zx4B`rhwN}Q`{L_OV`Bs9AueyNA-mYv*vN+7prQ0a7rVt!Hun9XwXit1NCUUdN1<$b z0gW%ko{uaOS8=)GPa5E}=p12f-^UKKqY>(-O#Mzf&4)e7w6Kci9d1MvI~r!z(+K{b;5{3xScqASHB zs;4IVM-YkQ_G1;8Y(+Ti1!eS7u4K(;t$nuZrX(YTsXmf-=fm;*V_)P(<(1`a^=+(F6xg`_Rw`5H<4KxlSw zb^~d9@xQWmgW8IS2=W?TFY+3Fo+36rjUpxBMg(Q&hZ0g}6x&Nz7$xikyam5s|a-n|MP^OIV3`uj@0u zMq{_B_?!xIDg{;vrcs>4>F$E!-+(NxB5PA|(lb#inyma=SCwz|65UQ#XRGIQxvt`= zC$(D9t8Hklp+htjRpP%eMMXWi6Hz;=iYHcqobA zrGf(ER+X~#ph;@Qg)UI0)tbs^#0(cqBYs6w*HhmRdwV+KQD=`T?;)wdAH?3L4+fNa SYd9eOA(O8ooL|)ED*pkbgOPLq literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/IPython/core/__pycache__/prompts.cpython-38.pyc b/.venv/lib/python3.8/site-packages/IPython/core/__pycache__/prompts.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a3d59fd2af7a896a9eff3cfbe73b8f97e425eb50 GIT binary patch literal 1129 zcmZuvOK;Oa5Z<*N$4yfNQh6LW?9~!!5SMa52!Rknpn_Dmv44nzulx&6%-9J{3v2JpuIKg5=lQs|*CVj#m!F(Fg#5zG_VVEJ47RxkLXr`A zMI@EZIgyT{D|h5b_n3s<^2T!&XQxc7G(S_aC&2s4g4}JMhj372L?M?W>ByCk;hc;- z>B$c0j`U?0v@Zj>1G+1Fkbk%Czm1lQmuFE@MpiAqewf6D!CM+7**Mp@)5u!HV5|mZ z*gUoqh7rmzJBcjI6gb9qSRVtUQ7IKC6cd*SJ5EZQmCzS(|RxU_Kl4Ei~k3zTh#$_gIFVd%`_Gfd{ zp;voGC1dSEtj27*1LA_{E~wv+hc+#SMO+NZtcb)+$-#W0R5Caea{lOW_IddF{lZT2 zY$$TAhK0`4!kU9(Q3ssIS!_8EAdm4u5bDFTyuHop!NyBa^jI%!2=TmuZSI4p$dr7i z75zaeo}sxZv^FK*=rPgg9eNGy+HXm|>?U+H)^4m#ORYdq2vI~y!ucND4E9cF|6hQu z&lP|O7R$bXZE%<^z*>>jUpTaOVI)G@7Dp<#>UKE?Bj>j;8q*NE+`q<3<8b9qZ%Aos z_93XPS<#iVA%WI@JCp0K>)rOsO`*i~?t7fCt$cqA$lYr|Ha`7HCf9f^)qCN%bxYq*vcWaY;mT!oQ%AOB}g|$AEfH&pF literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/IPython/core/__pycache__/pylabtools.cpython-38.pyc b/.venv/lib/python3.8/site-packages/IPython/core/__pycache__/pylabtools.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..4e6aed05a48e78844e401f9b01e4e675a4f75f69 GIT binary patch literal 9966 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 X#+j|uotpEqQ*pjidC9q0dEtKnJSHNr literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/IPython/core/__pycache__/release.cpython-38.pyc b/.venv/lib/python3.8/site-packages/IPython/core/__pycache__/release.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..92462cb36944b2fa3c69b484070934c133002d3e GIT binary patch literal 3094 zcma)8O>-N!8K(FlN|a>FmSV?^nxIV-N3KQAw1;FgnT+Jb@kjijG3m6$g$5Vk65=kf z1MHIKo;uUN(L;OevG@Lt9`@Rk|3Rmh_5pTjQ)${MceslMUc4XA`@Apq<<3s0hTq!n z{x$QvxBu7{ z8)8$e|GxgGHQEs^b5G!YvxaepZk3XvHEz;vzCm~Rrr5brqgQx`UgcYKmv7T+e1~7* zSNSf##;@}|zR%y|H~z3muk)L9kH1g%`7Qb${|WzqAHd=b{!{)T|A>>YNpJF>@t^aL z`6v94f68z3&%zD*K0oT$j_%}#FGM7m6@;^tk+C);oe1*ie34GHB8kx#B1pTmEfYWU zrj3x_?718MwY=HoVpi0OweC^=nVfc$t-k{()o^j zXDC{933-%S?2?KEu&R|%cxOhObUJs)8AfV>DbVJZ;(l2DZ^@1!LY28>+}$2yAi+~MJa9t)OcMpz%N!`+C9P}XHc zk6eWdm*jIe5lJ$WXtXIS)69ogQsXRe z!VV?}auuO+!14gIF4O2;=%BzP@zel-uAqp7xoFN7 zc+8lLyklqv@sbUVbe5dLea}1H_ zbq@?%N^n0}A8D|LQ-CJ_xrmyBJ#hk{h(zSE5kv3z<6p4iaLK?~jDKU??Foy(D>UFhOUr0$(nyUK;L_mrjS#8K#8X0ZX`oBUw(c8qrB zmsiYe(v2nPwB=!?>m_uw<-wsXA3tp%Ji1;>PfP-Xz{@*7pQ zk3pu>vemg0Dc@TjQ`NegELu;b%3kN~rz{}P`@bpLzm}lH+|n(_>gsH+UT{ocinjXh z2&9|$eVw3s^Zjp86vCfzCnrnC@{gPb#ZeV!8JDhw6RcM5g4_Awj|%hyFWY+|tY9XX zs7$Km{6lzvS#kNt|9jo3`&Isn z|3k=0K3CBqzctW_4BTtKJOSLufn%Q?-74C{A=klhSTx;HLaz*~f*!^U)LMO)>e73{ z(3)4)(X$LInr?s5ywFk=jhH1x18gj|hHupli*{w9*j}2FYOLu&`5iI@Y^e@(^md0| zz4>2Oi!FS01x6PO9beeDO=Ki0RJbzIo7-T2|!zX6)p8bSa7 literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/IPython/core/__pycache__/shellapp.cpython-38.pyc b/.venv/lib/python3.8/site-packages/IPython/core/__pycache__/shellapp.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..bfe351f5809e7ead0ffc14b219f5f4868cb6e613 GIT binary patch literal 14461 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 literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/IPython/core/__pycache__/ultratb.cpython-38.pyc b/.venv/lib/python3.8/site-packages/IPython/core/__pycache__/ultratb.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..29685bf1424e6512b3033c0bc1708283cb938c1b GIT binary patch literal 38533 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 literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/IPython/core/alias.py b/.venv/lib/python3.8/site-packages/IPython/core/alias.py new file mode 100644 index 00000000..2ad99023 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/IPython/core/alias.py @@ -0,0 +1,258 @@ +# encoding: utf-8 +""" +System command aliases. + +Authors: + +* Fernando Perez +* Brian Granger +""" + +#----------------------------------------------------------------------------- +# Copyright (C) 2008-2011 The IPython Development Team +# +# Distributed under the terms of the BSD License. +# +# The full license is in the file COPYING.txt, distributed with this software. +#----------------------------------------------------------------------------- + +#----------------------------------------------------------------------------- +# Imports +#----------------------------------------------------------------------------- + +import os +import re +import sys + +from traitlets.config.configurable import Configurable +from .error import UsageError + +from traitlets import List, Instance +from logging import error + +#----------------------------------------------------------------------------- +# Utilities +#----------------------------------------------------------------------------- + +# This is used as the pattern for calls to split_user_input. +shell_line_split = re.compile(r'^(\s*)()(\S+)(.*$)') + +def default_aliases(): + """Return list of shell aliases to auto-define. + """ + # Note: the aliases defined here should be safe to use on a kernel + # regardless of what frontend it is attached to. Frontends that use a + # kernel in-process can define additional aliases that will only work in + # their case. For example, things like 'less' or 'clear' that manipulate + # the terminal should NOT be declared here, as they will only work if the + # kernel is running inside a true terminal, and not over the network. + + if os.name == 'posix': + default_aliases = [('mkdir', 'mkdir'), ('rmdir', 'rmdir'), + ('mv', 'mv'), ('rm', 'rm'), ('cp', 'cp'), + ('cat', 'cat'), + ] + # Useful set of ls aliases. The GNU and BSD options are a little + # different, so we make aliases that provide as similar as possible + # behavior in ipython, by passing the right flags for each platform + if sys.platform.startswith('linux'): + ls_aliases = [('ls', 'ls -F --color'), + # long ls + ('ll', 'ls -F -o --color'), + # ls normal files only + ('lf', 'ls -F -o --color %l | grep ^-'), + # ls symbolic links + ('lk', 'ls -F -o --color %l | grep ^l'), + # directories or links to directories, + ('ldir', 'ls -F -o --color %l | grep /$'), + # things which are executable + ('lx', 'ls -F -o --color %l | grep ^-..x'), + ] + elif sys.platform.startswith('openbsd') or sys.platform.startswith('netbsd'): + # OpenBSD, NetBSD. The ls implementation on these platforms do not support + # the -G switch and lack the ability to use colorized output. + ls_aliases = [('ls', 'ls -F'), + # long ls + ('ll', 'ls -F -l'), + # ls normal files only + ('lf', 'ls -F -l %l | grep ^-'), + # ls symbolic links + ('lk', 'ls -F -l %l | grep ^l'), + # directories or links to directories, + ('ldir', 'ls -F -l %l | grep /$'), + # things which are executable + ('lx', 'ls -F -l %l | grep ^-..x'), + ] + else: + # BSD, OSX, etc. + ls_aliases = [('ls', 'ls -F -G'), + # long ls + ('ll', 'ls -F -l -G'), + # ls normal files only + ('lf', 'ls -F -l -G %l | grep ^-'), + # ls symbolic links + ('lk', 'ls -F -l -G %l | grep ^l'), + # directories or links to directories, + ('ldir', 'ls -F -G -l %l | grep /$'), + # things which are executable + ('lx', 'ls -F -l -G %l | grep ^-..x'), + ] + default_aliases = default_aliases + ls_aliases + elif os.name in ['nt', 'dos']: + default_aliases = [('ls', 'dir /on'), + ('ddir', 'dir /ad /on'), ('ldir', 'dir /ad /on'), + ('mkdir', 'mkdir'), ('rmdir', 'rmdir'), + ('echo', 'echo'), ('ren', 'ren'), ('copy', 'copy'), + ] + else: + default_aliases = [] + + return default_aliases + + +class AliasError(Exception): + pass + + +class InvalidAliasError(AliasError): + pass + +class Alias(object): + """Callable object storing the details of one alias. + + Instances are registered as magic functions to allow use of aliases. + """ + + # Prepare blacklist + blacklist = {'cd','popd','pushd','dhist','alias','unalias'} + + def __init__(self, shell, name, cmd): + self.shell = shell + self.name = name + self.cmd = cmd + self.__doc__ = "Alias for `!{}`".format(cmd) + self.nargs = self.validate() + + def validate(self): + """Validate the alias, and return the number of arguments.""" + if self.name in self.blacklist: + raise InvalidAliasError("The name %s can't be aliased " + "because it is a keyword or builtin." % self.name) + try: + caller = self.shell.magics_manager.magics['line'][self.name] + except KeyError: + pass + else: + if not isinstance(caller, Alias): + raise InvalidAliasError("The name %s can't be aliased " + "because it is another magic command." % self.name) + + if not (isinstance(self.cmd, str)): + raise InvalidAliasError("An alias command must be a string, " + "got: %r" % self.cmd) + + nargs = self.cmd.count('%s') - self.cmd.count('%%s') + + if (nargs > 0) and (self.cmd.find('%l') >= 0): + raise InvalidAliasError('The %s and %l specifiers are mutually ' + 'exclusive in alias definitions.') + + return nargs + + def __repr__(self): + return "".format(self.name, self.cmd) + + def __call__(self, rest=''): + cmd = self.cmd + nargs = self.nargs + # Expand the %l special to be the user's input line + if cmd.find('%l') >= 0: + cmd = cmd.replace('%l', rest) + rest = '' + + if nargs==0: + if cmd.find('%%s') >= 1: + cmd = cmd.replace('%%s', '%s') + # Simple, argument-less aliases + cmd = '%s %s' % (cmd, rest) + else: + # Handle aliases with positional arguments + args = rest.split(None, nargs) + if len(args) < nargs: + raise UsageError('Alias <%s> requires %s arguments, %s given.' % + (self.name, nargs, len(args))) + cmd = '%s %s' % (cmd % tuple(args[:nargs]),' '.join(args[nargs:])) + + self.shell.system(cmd) + +#----------------------------------------------------------------------------- +# Main AliasManager class +#----------------------------------------------------------------------------- + +class AliasManager(Configurable): + + default_aliases = List(default_aliases()).tag(config=True) + user_aliases = List(default_value=[]).tag(config=True) + shell = Instance('IPython.core.interactiveshell.InteractiveShellABC', allow_none=True) + + def __init__(self, shell=None, **kwargs): + super(AliasManager, self).__init__(shell=shell, **kwargs) + # For convenient access + self.linemagics = self.shell.magics_manager.magics['line'] + self.init_aliases() + + def init_aliases(self): + # Load default & user aliases + for name, cmd in self.default_aliases + self.user_aliases: + if cmd.startswith('ls ') and self.shell.colors == 'NoColor': + cmd = cmd.replace(' --color', '') + self.soft_define_alias(name, cmd) + + @property + def aliases(self): + return [(n, func.cmd) for (n, func) in self.linemagics.items() + if isinstance(func, Alias)] + + def soft_define_alias(self, name, cmd): + """Define an alias, but don't raise on an AliasError.""" + try: + self.define_alias(name, cmd) + except AliasError as e: + error("Invalid alias: %s" % e) + + def define_alias(self, name, cmd): + """Define a new alias after validating it. + + This will raise an :exc:`AliasError` if there are validation + problems. + """ + caller = Alias(shell=self.shell, name=name, cmd=cmd) + self.shell.magics_manager.register_function(caller, magic_kind='line', + magic_name=name) + + def get_alias(self, name): + """Return an alias, or None if no alias by that name exists.""" + aname = self.linemagics.get(name, None) + return aname if isinstance(aname, Alias) else None + + def is_alias(self, name): + """Return whether or not a given name has been defined as an alias""" + return self.get_alias(name) is not None + + def undefine_alias(self, name): + if self.is_alias(name): + del self.linemagics[name] + else: + raise ValueError('%s is not an alias' % name) + + def clear_aliases(self): + for name, cmd in self.aliases: + self.undefine_alias(name) + + def retrieve_alias(self, name): + """Retrieve the command to which an alias expands.""" + caller = self.get_alias(name) + if caller: + return caller.cmd + else: + raise ValueError('%s is not an alias' % name) diff --git a/.venv/lib/python3.8/site-packages/IPython/core/application.py b/.venv/lib/python3.8/site-packages/IPython/core/application.py new file mode 100644 index 00000000..93639d88 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/IPython/core/application.py @@ -0,0 +1,462 @@ +# encoding: utf-8 +""" +An application for IPython. + +All top-level applications should use the classes in this module for +handling configuration and creating configurables. + +The job of an :class:`Application` is to create the master configuration +object and then create the configurable objects, passing the config to them. +""" + +# Copyright (c) IPython Development Team. +# Distributed under the terms of the Modified BSD License. + +import atexit +from copy import deepcopy +import glob +import logging +import os +import shutil +import sys + +from traitlets.config.application import Application, catch_config_error +from traitlets.config.loader import ConfigFileNotFound, PyFileConfigLoader +from IPython.core import release, crashhandler +from IPython.core.profiledir import ProfileDir, ProfileDirError +from IPython.paths import get_ipython_dir, get_ipython_package_dir +from IPython.utils.path import ensure_dir_exists +from traitlets import ( + List, Unicode, Type, Bool, Set, Instance, Undefined, + default, observe, +) + +if os.name == 'nt': + programdata = os.environ.get('PROGRAMDATA', None) + if programdata: + SYSTEM_CONFIG_DIRS = [os.path.join(programdata, 'ipython')] + else: # PROGRAMDATA is not defined by default on XP. + SYSTEM_CONFIG_DIRS = [] +else: + SYSTEM_CONFIG_DIRS = [ + "/usr/local/etc/ipython", + "/etc/ipython", + ] + + +ENV_CONFIG_DIRS = [] +_env_config_dir = os.path.join(sys.prefix, 'etc', 'ipython') +if _env_config_dir not in SYSTEM_CONFIG_DIRS: + # only add ENV_CONFIG if sys.prefix is not already included + ENV_CONFIG_DIRS.append(_env_config_dir) + + +_envvar = os.environ.get('IPYTHON_SUPPRESS_CONFIG_ERRORS') +if _envvar in {None, ''}: + IPYTHON_SUPPRESS_CONFIG_ERRORS = None +else: + if _envvar.lower() in {'1','true'}: + IPYTHON_SUPPRESS_CONFIG_ERRORS = True + elif _envvar.lower() in {'0','false'} : + IPYTHON_SUPPRESS_CONFIG_ERRORS = False + else: + sys.exit("Unsupported value for environment variable: 'IPYTHON_SUPPRESS_CONFIG_ERRORS' is set to '%s' which is none of {'0', '1', 'false', 'true', ''}."% _envvar ) + +# aliases and flags + +base_aliases = { + 'profile-dir' : 'ProfileDir.location', + 'profile' : 'BaseIPythonApplication.profile', + 'ipython-dir' : 'BaseIPythonApplication.ipython_dir', + 'log-level' : 'Application.log_level', + 'config' : 'BaseIPythonApplication.extra_config_file', +} + +base_flags = dict( + debug = ({'Application' : {'log_level' : logging.DEBUG}}, + "set log level to logging.DEBUG (maximize logging output)"), + quiet = ({'Application' : {'log_level' : logging.CRITICAL}}, + "set log level to logging.CRITICAL (minimize logging output)"), + init = ({'BaseIPythonApplication' : { + 'copy_config_files' : True, + 'auto_create' : True} + }, """Initialize profile with default config files. This is equivalent + to running `ipython profile create ` prior to startup. + """) +) + +class ProfileAwareConfigLoader(PyFileConfigLoader): + """A Python file config loader that is aware of IPython profiles.""" + def load_subconfig(self, fname, path=None, profile=None): + if profile is not None: + try: + profile_dir = ProfileDir.find_profile_dir_by_name( + get_ipython_dir(), + profile, + ) + except ProfileDirError: + return + path = profile_dir.location + return super(ProfileAwareConfigLoader, self).load_subconfig(fname, path=path) + +class BaseIPythonApplication(Application): + + name = u'ipython' + description = Unicode(u'IPython: an enhanced interactive Python shell.') + version = Unicode(release.version) + + aliases = base_aliases + flags = base_flags + classes = List([ProfileDir]) + + # enable `load_subconfig('cfg.py', profile='name')` + python_config_loader_class = ProfileAwareConfigLoader + + # Track whether the config_file has changed, + # because some logic happens only if we aren't using the default. + config_file_specified = Set() + + config_file_name = Unicode() + @default('config_file_name') + def _config_file_name_default(self): + return self.name.replace('-','_') + u'_config.py' + @observe('config_file_name') + def _config_file_name_changed(self, change): + if change['new'] != change['old']: + self.config_file_specified.add(change['new']) + + # The directory that contains IPython's builtin profiles. + builtin_profile_dir = Unicode( + os.path.join(get_ipython_package_dir(), u'config', u'profile', u'default') + ) + + config_file_paths = List(Unicode()) + @default('config_file_paths') + def _config_file_paths_default(self): + return [os.getcwd()] + + extra_config_file = Unicode( + help="""Path to an extra config file to load. + + If specified, load this config file in addition to any other IPython config. + """).tag(config=True) + @observe('extra_config_file') + def _extra_config_file_changed(self, change): + old = change['old'] + new = change['new'] + try: + self.config_files.remove(old) + except ValueError: + pass + self.config_file_specified.add(new) + self.config_files.append(new) + + profile = Unicode(u'default', + help="""The IPython profile to use.""" + ).tag(config=True) + + @observe('profile') + def _profile_changed(self, change): + self.builtin_profile_dir = os.path.join( + get_ipython_package_dir(), u'config', u'profile', change['new'] + ) + + ipython_dir = Unicode( + help=""" + The name of the IPython directory. This directory is used for logging + configuration (through profiles), history storage, etc. The default + is usually $HOME/.ipython. This option can also be specified through + the environment variable IPYTHONDIR. + """ + ).tag(config=True) + @default('ipython_dir') + def _ipython_dir_default(self): + d = get_ipython_dir() + self._ipython_dir_changed({ + 'name': 'ipython_dir', + 'old': d, + 'new': d, + }) + return d + + _in_init_profile_dir = False + profile_dir = Instance(ProfileDir, allow_none=True) + @default('profile_dir') + def _profile_dir_default(self): + # avoid recursion + if self._in_init_profile_dir: + return + # profile_dir requested early, force initialization + self.init_profile_dir() + return self.profile_dir + + overwrite = Bool(False, + help="""Whether to overwrite existing config files when copying""" + ).tag(config=True) + auto_create = Bool(False, + help="""Whether to create profile dir if it doesn't exist""" + ).tag(config=True) + + config_files = List(Unicode()) + @default('config_files') + def _config_files_default(self): + return [self.config_file_name] + + copy_config_files = Bool(False, + help="""Whether to install the default config files into the profile dir. + If a new profile is being created, and IPython contains config files for that + profile, then they will be staged into the new directory. Otherwise, + default config files will be automatically generated. + """).tag(config=True) + + verbose_crash = Bool(False, + help="""Create a massive crash report when IPython encounters what may be an + internal error. The default is to append a short message to the + usual traceback""").tag(config=True) + + # The class to use as the crash handler. + crash_handler_class = Type(crashhandler.CrashHandler) + + @catch_config_error + def __init__(self, **kwargs): + super(BaseIPythonApplication, self).__init__(**kwargs) + # ensure current working directory exists + try: + os.getcwd() + except: + # exit if cwd doesn't exist + self.log.error("Current working directory doesn't exist.") + self.exit(1) + + #------------------------------------------------------------------------- + # Various stages of Application creation + #------------------------------------------------------------------------- + + deprecated_subcommands = {} + + def initialize_subcommand(self, subc, argv=None): + if subc in self.deprecated_subcommands: + self.log.warning("Subcommand `ipython {sub}` is deprecated and will be removed " + "in future versions.".format(sub=subc)) + self.log.warning("You likely want to use `jupyter {sub}` in the " + "future".format(sub=subc)) + return super(BaseIPythonApplication, self).initialize_subcommand(subc, argv) + + def init_crash_handler(self): + """Create a crash handler, typically setting sys.excepthook to it.""" + self.crash_handler = self.crash_handler_class(self) + sys.excepthook = self.excepthook + def unset_crashhandler(): + sys.excepthook = sys.__excepthook__ + atexit.register(unset_crashhandler) + + def excepthook(self, etype, evalue, tb): + """this is sys.excepthook after init_crashhandler + + set self.verbose_crash=True to use our full crashhandler, instead of + a regular traceback with a short message (crash_handler_lite) + """ + + if self.verbose_crash: + return self.crash_handler(etype, evalue, tb) + else: + return crashhandler.crash_handler_lite(etype, evalue, tb) + + @observe('ipython_dir') + def _ipython_dir_changed(self, change): + old = change['old'] + new = change['new'] + if old is not Undefined: + str_old = os.path.abspath(old) + if str_old in sys.path: + sys.path.remove(str_old) + str_path = os.path.abspath(new) + sys.path.append(str_path) + ensure_dir_exists(new) + readme = os.path.join(new, 'README') + readme_src = os.path.join(get_ipython_package_dir(), u'config', u'profile', 'README') + if not os.path.exists(readme) and os.path.exists(readme_src): + shutil.copy(readme_src, readme) + for d in ('extensions', 'nbextensions'): + path = os.path.join(new, d) + try: + ensure_dir_exists(path) + except OSError as e: + # this will not be EEXIST + self.log.error("couldn't create path %s: %s", path, e) + self.log.debug("IPYTHONDIR set to: %s" % new) + + def load_config_file(self, suppress_errors=IPYTHON_SUPPRESS_CONFIG_ERRORS): + """Load the config file. + + By default, errors in loading config are handled, and a warning + printed on screen. For testing, the suppress_errors option is set + to False, so errors will make tests fail. + + `suppress_errors` default value is to be `None` in which case the + behavior default to the one of `traitlets.Application`. + + The default value can be set : + - to `False` by setting 'IPYTHON_SUPPRESS_CONFIG_ERRORS' environment variable to '0', or 'false' (case insensitive). + - to `True` by setting 'IPYTHON_SUPPRESS_CONFIG_ERRORS' environment variable to '1' or 'true' (case insensitive). + - to `None` by setting 'IPYTHON_SUPPRESS_CONFIG_ERRORS' environment variable to '' (empty string) or leaving it unset. + + Any other value are invalid, and will make IPython exit with a non-zero return code. + """ + + + self.log.debug("Searching path %s for config files", self.config_file_paths) + base_config = 'ipython_config.py' + self.log.debug("Attempting to load config file: %s" % + base_config) + try: + if suppress_errors is not None: + old_value = Application.raise_config_file_errors + Application.raise_config_file_errors = not suppress_errors; + Application.load_config_file( + self, + base_config, + path=self.config_file_paths + ) + except ConfigFileNotFound: + # ignore errors loading parent + self.log.debug("Config file %s not found", base_config) + pass + if suppress_errors is not None: + Application.raise_config_file_errors = old_value + + for config_file_name in self.config_files: + if not config_file_name or config_file_name == base_config: + continue + self.log.debug("Attempting to load config file: %s" % + self.config_file_name) + try: + Application.load_config_file( + self, + config_file_name, + path=self.config_file_paths + ) + except ConfigFileNotFound: + # Only warn if the default config file was NOT being used. + if config_file_name in self.config_file_specified: + msg = self.log.warning + else: + msg = self.log.debug + msg("Config file not found, skipping: %s", config_file_name) + except Exception: + # For testing purposes. + if not suppress_errors: + raise + self.log.warning("Error loading config file: %s" % + self.config_file_name, exc_info=True) + + def init_profile_dir(self): + """initialize the profile dir""" + self._in_init_profile_dir = True + if self.profile_dir is not None: + # already ran + return + if 'ProfileDir.location' not in self.config: + # location not specified, find by profile name + try: + p = ProfileDir.find_profile_dir_by_name(self.ipython_dir, self.profile, self.config) + except ProfileDirError: + # not found, maybe create it (always create default profile) + if self.auto_create or self.profile == 'default': + try: + p = ProfileDir.create_profile_dir_by_name(self.ipython_dir, self.profile, self.config) + except ProfileDirError: + self.log.fatal("Could not create profile: %r"%self.profile) + self.exit(1) + else: + self.log.info("Created profile dir: %r"%p.location) + else: + self.log.fatal("Profile %r not found."%self.profile) + self.exit(1) + else: + self.log.debug("Using existing profile dir: %r"%p.location) + else: + location = self.config.ProfileDir.location + # location is fully specified + try: + p = ProfileDir.find_profile_dir(location, self.config) + except ProfileDirError: + # not found, maybe create it + if self.auto_create: + try: + p = ProfileDir.create_profile_dir(location, self.config) + except ProfileDirError: + self.log.fatal("Could not create profile directory: %r"%location) + self.exit(1) + else: + self.log.debug("Creating new profile dir: %r"%location) + else: + self.log.fatal("Profile directory %r not found."%location) + self.exit(1) + else: + self.log.info("Using existing profile dir: %r"%location) + # if profile_dir is specified explicitly, set profile name + dir_name = os.path.basename(p.location) + if dir_name.startswith('profile_'): + self.profile = dir_name[8:] + + self.profile_dir = p + self.config_file_paths.append(p.location) + self._in_init_profile_dir = False + + def init_config_files(self): + """[optionally] copy default config files into profile dir.""" + self.config_file_paths.extend(ENV_CONFIG_DIRS) + self.config_file_paths.extend(SYSTEM_CONFIG_DIRS) + # copy config files + path = self.builtin_profile_dir + if self.copy_config_files: + src = self.profile + + cfg = self.config_file_name + if path and os.path.exists(os.path.join(path, cfg)): + self.log.warning("Staging %r from %s into %r [overwrite=%s]"%( + cfg, src, self.profile_dir.location, self.overwrite) + ) + self.profile_dir.copy_config_file(cfg, path=path, overwrite=self.overwrite) + else: + self.stage_default_config_file() + else: + # Still stage *bundled* config files, but not generated ones + # This is necessary for `ipython profile=sympy` to load the profile + # on the first go + files = glob.glob(os.path.join(path, '*.py')) + for fullpath in files: + cfg = os.path.basename(fullpath) + if self.profile_dir.copy_config_file(cfg, path=path, overwrite=False): + # file was copied + self.log.warning("Staging bundled %s from %s into %r"%( + cfg, self.profile, self.profile_dir.location) + ) + + + def stage_default_config_file(self): + """auto generate default config file, and stage it into the profile.""" + s = self.generate_config_file() + fname = os.path.join(self.profile_dir.location, self.config_file_name) + if self.overwrite or not os.path.exists(fname): + self.log.warning("Generating default config file: %r"%(fname)) + with open(fname, 'w') as f: + f.write(s) + + @catch_config_error + def initialize(self, argv=None): + # don't hook up crash handler before parsing command-line + self.parse_command_line(argv) + self.init_crash_handler() + if self.subapp is not None: + # stop here if subapp is taking over + return + # save a copy of CLI config to re-load after config files + # so that it has highest priority + cl_config = deepcopy(self.config) + self.init_profile_dir() + self.init_config_files() + self.load_config_file() + # enforce cl-opts override configfile opts: + self.update_config(cl_config) diff --git a/.venv/lib/python3.8/site-packages/IPython/core/async_helpers.py b/.venv/lib/python3.8/site-packages/IPython/core/async_helpers.py new file mode 100644 index 00000000..fb4cc193 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/IPython/core/async_helpers.py @@ -0,0 +1,173 @@ +""" +Async helper function that are invalid syntax on Python 3.5 and below. + +This code is best effort, and may have edge cases not behaving as expected. In +particular it contain a number of heuristics to detect whether code is +effectively async and need to run in an event loop or not. + +Some constructs (like top-level `return`, or `yield`) are taken care of +explicitly to actually raise a SyntaxError and stay as close as possible to +Python semantics. +""" + + +import ast +import sys +import inspect +from textwrap import dedent, indent + + +class _AsyncIORunner: + + def __call__(self, coro): + """ + Handler for asyncio autoawait + """ + import asyncio + + return asyncio.get_event_loop().run_until_complete(coro) + + def __str__(self): + return 'asyncio' + +_asyncio_runner = _AsyncIORunner() + + +def _curio_runner(coroutine): + """ + handler for curio autoawait + """ + import curio + + return curio.run(coroutine) + + +def _trio_runner(async_fn): + import trio + + async def loc(coro): + """ + We need the dummy no-op async def to protect from + trio's internal. See https://github.com/python-trio/trio/issues/89 + """ + return await coro + + return trio.run(loc, async_fn) + + +def _pseudo_sync_runner(coro): + """ + A runner that does not really allow async execution, and just advance the coroutine. + + See discussion in https://github.com/python-trio/trio/issues/608, + + Credit to Nathaniel Smith + + """ + try: + coro.send(None) + except StopIteration as exc: + return exc.value + else: + # TODO: do not raise but return an execution result with the right info. + raise RuntimeError( + "{coro_name!r} needs a real async loop".format(coro_name=coro.__name__) + ) + + +def _asyncify(code: str) -> str: + """wrap code in async def definition. + + And setup a bit of context to run it later. + """ + res = dedent( + """ + async def __wrapper__(): + try: + {usercode} + finally: + locals() + """ + ).format(usercode=indent(code, " " * 8)) + return res + + +class _AsyncSyntaxErrorVisitor(ast.NodeVisitor): + """ + Find syntax errors that would be an error in an async repl, but because + the implementation involves wrapping the repl in an async function, it + is erroneously allowed (e.g. yield or return at the top level) + """ + def __init__(self): + if sys.version_info >= (3,8): + raise ValueError('DEPRECATED in Python 3.8+') + self.depth = 0 + super().__init__() + + def generic_visit(self, node): + func_types = (ast.FunctionDef, ast.AsyncFunctionDef) + invalid_types_by_depth = { + 0: (ast.Return, ast.Yield, ast.YieldFrom), + 1: (ast.Nonlocal,) + } + + should_traverse = self.depth < max(invalid_types_by_depth.keys()) + if isinstance(node, func_types) and should_traverse: + self.depth += 1 + super().generic_visit(node) + self.depth -= 1 + elif isinstance(node, invalid_types_by_depth[self.depth]): + raise SyntaxError() + else: + super().generic_visit(node) + + +def _async_parse_cell(cell: str) -> ast.AST: + """ + This is a compatibility shim for pre-3.7 when async outside of a function + is a syntax error at the parse stage. + + It will return an abstract syntax tree parsed as if async and await outside + of a function were not a syntax error. + """ + if sys.version_info < (3, 7): + # Prior to 3.7 you need to asyncify before parse + wrapped_parse_tree = ast.parse(_asyncify(cell)) + return wrapped_parse_tree.body[0].body[0] + else: + return ast.parse(cell) + + +def _should_be_async(cell: str) -> bool: + """Detect if a block of code need to be wrapped in an `async def` + + Attempt to parse the block of code, it it compile we're fine. + Otherwise we wrap if and try to compile. + + If it works, assume it should be async. Otherwise Return False. + + Not handled yet: If the block of code has a return statement as the top + level, it will be seen as async. This is a know limitation. + """ + if sys.version_info > (3, 8): + try: + code = compile(cell, "<>", "exec", flags=getattr(ast,'PyCF_ALLOW_TOP_LEVEL_AWAIT', 0x0)) + return inspect.CO_COROUTINE & code.co_flags == inspect.CO_COROUTINE + except (SyntaxError, MemoryError): + return False + try: + # we can't limit ourself to ast.parse, as it __accepts__ to parse on + # 3.7+, but just does not _compile_ + code = compile(cell, "<>", "exec") + except (SyntaxError, MemoryError): + try: + parse_tree = _async_parse_cell(cell) + + # Raise a SyntaxError if there are top-level return or yields + v = _AsyncSyntaxErrorVisitor() + v.visit(parse_tree) + + except (SyntaxError, MemoryError): + return False + return True + return False diff --git a/.venv/lib/python3.8/site-packages/IPython/core/autocall.py b/.venv/lib/python3.8/site-packages/IPython/core/autocall.py new file mode 100644 index 00000000..bab7f859 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/IPython/core/autocall.py @@ -0,0 +1,70 @@ +# encoding: utf-8 +""" +Autocall capabilities for IPython.core. + +Authors: + +* Brian Granger +* Fernando Perez +* Thomas Kluyver + +Notes +----- +""" + +#----------------------------------------------------------------------------- +# Copyright (C) 2008-2011 The IPython Development Team +# +# Distributed under the terms of the BSD License. The full license is in +# the file COPYING, distributed as part of this software. +#----------------------------------------------------------------------------- + +#----------------------------------------------------------------------------- +# Imports +#----------------------------------------------------------------------------- + + +#----------------------------------------------------------------------------- +# Code +#----------------------------------------------------------------------------- + +class IPyAutocall(object): + """ Instances of this class are always autocalled + + This happens regardless of 'autocall' variable state. Use this to + develop macro-like mechanisms. + """ + _ip = None + rewrite = True + def __init__(self, ip=None): + self._ip = ip + + def set_ip(self, ip): + """ Will be used to set _ip point to current ipython instance b/f call + + Override this method if you don't want this to happen. + + """ + self._ip = ip + + +class ExitAutocall(IPyAutocall): + """An autocallable object which will be added to the user namespace so that + exit, exit(), quit or quit() are all valid ways to close the shell.""" + rewrite = False + + def __call__(self): + self._ip.ask_exit() + +class ZMQExitAutocall(ExitAutocall): + """Exit IPython. Autocallable, so it needn't be explicitly called. + + Parameters + ---------- + keep_kernel : bool + If True, leave the kernel alive. Otherwise, tell the kernel to exit too + (default). + """ + def __call__(self, keep_kernel=False): + self._ip.keepkernel_on_exit = keep_kernel + self._ip.ask_exit() diff --git a/.venv/lib/python3.8/site-packages/IPython/core/builtin_trap.py b/.venv/lib/python3.8/site-packages/IPython/core/builtin_trap.py new file mode 100644 index 00000000..a8ea4abc --- /dev/null +++ b/.venv/lib/python3.8/site-packages/IPython/core/builtin_trap.py @@ -0,0 +1,86 @@ +""" +A context manager for managing things injected into :mod:`builtins`. +""" +# Copyright (c) IPython Development Team. +# Distributed under the terms of the Modified BSD License. +import builtins as builtin_mod + +from traitlets.config.configurable import Configurable + +from traitlets import Instance + + +class __BuiltinUndefined(object): pass +BuiltinUndefined = __BuiltinUndefined() + +class __HideBuiltin(object): pass +HideBuiltin = __HideBuiltin() + + +class BuiltinTrap(Configurable): + + shell = Instance('IPython.core.interactiveshell.InteractiveShellABC', + allow_none=True) + + def __init__(self, shell=None): + super(BuiltinTrap, self).__init__(shell=shell, config=None) + self._orig_builtins = {} + # We define this to track if a single BuiltinTrap is nested. + # Only turn off the trap when the outermost call to __exit__ is made. + self._nested_level = 0 + self.shell = shell + # builtins we always add - if set to HideBuiltin, they will just + # be removed instead of being replaced by something else + self.auto_builtins = {'exit': HideBuiltin, + 'quit': HideBuiltin, + 'get_ipython': self.shell.get_ipython, + } + + def __enter__(self): + if self._nested_level == 0: + self.activate() + self._nested_level += 1 + # I return self, so callers can use add_builtin in a with clause. + return self + + def __exit__(self, type, value, traceback): + if self._nested_level == 1: + self.deactivate() + self._nested_level -= 1 + # Returning False will cause exceptions to propagate + return False + + def add_builtin(self, key, value): + """Add a builtin and save the original.""" + bdict = builtin_mod.__dict__ + orig = bdict.get(key, BuiltinUndefined) + if value is HideBuiltin: + if orig is not BuiltinUndefined: #same as 'key in bdict' + self._orig_builtins[key] = orig + del bdict[key] + else: + self._orig_builtins[key] = orig + bdict[key] = value + + def remove_builtin(self, key, orig): + """Remove an added builtin and re-set the original.""" + if orig is BuiltinUndefined: + del builtin_mod.__dict__[key] + else: + builtin_mod.__dict__[key] = orig + + def activate(self): + """Store ipython references in the __builtin__ namespace.""" + + add_builtin = self.add_builtin + for name, func in self.auto_builtins.items(): + add_builtin(name, func) + + def deactivate(self): + """Remove any builtins which might have been added by add_builtins, or + restore overwritten ones to their previous values.""" + remove_builtin = self.remove_builtin + for key, val in self._orig_builtins.items(): + remove_builtin(key, val) + self._orig_builtins.clear() + self._builtins_added = False diff --git a/.venv/lib/python3.8/site-packages/IPython/core/compilerop.py b/.venv/lib/python3.8/site-packages/IPython/core/compilerop.py new file mode 100644 index 00000000..c4771af7 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/IPython/core/compilerop.py @@ -0,0 +1,160 @@ +"""Compiler tools with improved interactive support. + +Provides compilation machinery similar to codeop, but with caching support so +we can provide interactive tracebacks. + +Authors +------- +* Robert Kern +* Fernando Perez +* Thomas Kluyver +""" + +# Note: though it might be more natural to name this module 'compiler', that +# name is in the stdlib and name collisions with the stdlib tend to produce +# weird problems (often with third-party tools). + +#----------------------------------------------------------------------------- +# Copyright (C) 2010-2011 The IPython Development Team. +# +# Distributed under the terms of the BSD License. +# +# The full license is in the file COPYING.txt, distributed with this software. +#----------------------------------------------------------------------------- + +#----------------------------------------------------------------------------- +# Imports +#----------------------------------------------------------------------------- + +# Stdlib imports +import __future__ +from ast import PyCF_ONLY_AST +import codeop +import functools +import hashlib +import linecache +import operator +import time +from contextlib import contextmanager + +#----------------------------------------------------------------------------- +# Constants +#----------------------------------------------------------------------------- + +# Roughly equal to PyCF_MASK | PyCF_MASK_OBSOLETE as defined in pythonrun.h, +# this is used as a bitmask to extract future-related code flags. +PyCF_MASK = functools.reduce(operator.or_, + (getattr(__future__, fname).compiler_flag + for fname in __future__.all_feature_names)) + +#----------------------------------------------------------------------------- +# Local utilities +#----------------------------------------------------------------------------- + +def code_name(code, number=0): + """ Compute a (probably) unique name for code for caching. + + This now expects code to be unicode. + """ + hash_digest = hashlib.sha1(code.encode("utf-8")).hexdigest() + # Include the number and 12 characters of the hash in the name. It's + # pretty much impossible that in a single session we'll have collisions + # even with truncated hashes, and the full one makes tracebacks too long + return ''.format(number, hash_digest[:12]) + +#----------------------------------------------------------------------------- +# Classes and functions +#----------------------------------------------------------------------------- + +class CachingCompiler(codeop.Compile): + """A compiler that caches code compiled from interactive statements. + """ + + def __init__(self): + codeop.Compile.__init__(self) + + # This is ugly, but it must be done this way to allow multiple + # simultaneous ipython instances to coexist. Since Python itself + # directly accesses the data structures in the linecache module, and + # the cache therein is global, we must work with that data structure. + # We must hold a reference to the original checkcache routine and call + # that in our own check_cache() below, but the special IPython cache + # must also be shared by all IPython instances. If we were to hold + # separate caches (one in each CachingCompiler instance), any call made + # by Python itself to linecache.checkcache() would obliterate the + # cached data from the other IPython instances. + if not hasattr(linecache, '_ipython_cache'): + linecache._ipython_cache = {} + if not hasattr(linecache, '_checkcache_ori'): + linecache._checkcache_ori = linecache.checkcache + # Now, we must monkeypatch the linecache directly so that parts of the + # stdlib that call it outside our control go through our codepath + # (otherwise we'd lose our tracebacks). + linecache.checkcache = check_linecache_ipython + + + def ast_parse(self, source, filename='', symbol='exec'): + """Parse code to an AST with the current compiler flags active. + + Arguments are exactly the same as ast.parse (in the standard library), + and are passed to the built-in compile function.""" + return compile(source, filename, symbol, self.flags | PyCF_ONLY_AST, 1) + + def reset_compiler_flags(self): + """Reset compiler flags to default state.""" + # This value is copied from codeop.Compile.__init__, so if that ever + # changes, it will need to be updated. + self.flags = codeop.PyCF_DONT_IMPLY_DEDENT + + @property + def compiler_flags(self): + """Flags currently active in the compilation process. + """ + return self.flags + + def cache(self, code, number=0): + """Make a name for a block of code, and cache the code. + + Parameters + ---------- + code : str + The Python source code to cache. + number : int + A number which forms part of the code's name. Used for the execution + counter. + + Returns + ------- + The name of the cached code (as a string). Pass this as the filename + argument to compilation, so that tracebacks are correctly hooked up. + """ + name = code_name(code, number) + entry = (len(code), time.time(), + [line+'\n' for line in code.splitlines()], name) + linecache.cache[name] = entry + linecache._ipython_cache[name] = entry + return name + + @contextmanager + def extra_flags(self, flags): + ## bits that we'll set to 1 + turn_on_bits = ~self.flags & flags + + + self.flags = self.flags | flags + try: + yield + finally: + # turn off only the bits we turned on so that something like + # __future__ that set flags stays. + self.flags &= ~turn_on_bits + + +def check_linecache_ipython(*args): + """Call linecache.checkcache() safely protecting our cached values. + """ + # First call the original checkcache as intended + linecache._checkcache_ori(*args) + # Then, update back the cache with our data, so that tracebacks related + # to our compiled codes can be produced. + linecache.cache.update(linecache._ipython_cache) diff --git a/.venv/lib/python3.8/site-packages/IPython/core/completer.py b/.venv/lib/python3.8/site-packages/IPython/core/completer.py new file mode 100644 index 00000000..bc114f0f --- /dev/null +++ b/.venv/lib/python3.8/site-packages/IPython/core/completer.py @@ -0,0 +1,2092 @@ +"""Completion for IPython. + +This module started as fork of the rlcompleter module in the Python standard +library. The original enhancements made to rlcompleter have been sent +upstream and were accepted as of Python 2.3, + +This module now support a wide variety of completion mechanism both available +for normal classic Python code, as well as completer for IPython specific +Syntax like magics. + +Latex and Unicode completion +============================ + +IPython and compatible frontends not only can complete your code, but can help +you to input a wide range of characters. In particular we allow you to insert +a unicode character using the tab completion mechanism. + +Forward latex/unicode completion +-------------------------------- + +Forward completion allows you to easily type a unicode character using its latex +name, or unicode long description. To do so type a backslash follow by the +relevant name and press tab: + + +Using latex completion: + +.. code:: + + \\alpha + α + +or using unicode completion: + + +.. code:: + + \\greek small letter alpha + α + + +Only valid Python identifiers will complete. Combining characters (like arrow or +dots) are also available, unlike latex they need to be put after the their +counterpart that is to say, `F\\\\vec` is correct, not `\\\\vecF`. + +Some browsers are known to display combining characters incorrectly. + +Backward latex completion +------------------------- + +It is sometime challenging to know how to type a character, if you are using +IPython, or any compatible frontend you can prepend backslash to the character +and press `` to expand it to its latex form. + +.. code:: + + \\α + \\alpha + + +Both forward and backward completions can be deactivated by setting the +``Completer.backslash_combining_completions`` option to ``False``. + + +Experimental +============ + +Starting with IPython 6.0, this module can make use of the Jedi library to +generate completions both using static analysis of the code, and dynamically +inspecting multiple namespaces. Jedi is an autocompletion and static analysis +for Python. The APIs attached to this new mechanism is unstable and will +raise unless use in an :any:`provisionalcompleter` context manager. + +You will find that the following are experimental: + + - :any:`provisionalcompleter` + - :any:`IPCompleter.completions` + - :any:`Completion` + - :any:`rectify_completions` + +.. note:: + + better name for :any:`rectify_completions` ? + +We welcome any feedback on these new API, and we also encourage you to try this +module in debug mode (start IPython with ``--Completer.debug=True``) in order +to have extra logging information if :any:`jedi` is crashing, or if current +IPython completer pending deprecations are returning results not yet handled +by :any:`jedi` + +Using Jedi for tab completion allow snippets like the following to work without +having to execute any code: + + >>> myvar = ['hello', 42] + ... myvar[1].bi + +Tab completion will be able to infer that ``myvar[1]`` is a real number without +executing any code unlike the previously available ``IPCompleter.greedy`` +option. + +Be sure to update :any:`jedi` to the latest stable version or to try the +current development version to get better completions. +""" + + +# Copyright (c) IPython Development Team. +# Distributed under the terms of the Modified BSD License. +# +# Some of this code originated from rlcompleter in the Python standard library +# Copyright (C) 2001 Python Software Foundation, www.python.org + + +import __main__ +import builtins as builtin_mod +import glob +import time +import inspect +import itertools +import keyword +import os +import re +import sys +import unicodedata +import string +import warnings + +from contextlib import contextmanager +from importlib import import_module +from typing import Iterator, List, Tuple, Iterable +from types import SimpleNamespace + +from traitlets.config.configurable import Configurable +from IPython.core.error import TryNext +from IPython.core.inputtransformer2 import ESC_MAGIC +from IPython.core.latex_symbols import latex_symbols, reverse_latex_symbol +from IPython.core.oinspect import InspectColors +from IPython.utils import generics +from IPython.utils.dir2 import dir2, get_real_method +from IPython.utils.process import arg_split +from traitlets import Bool, Enum, observe, Int + +# skip module docstests +skip_doctest = True + +try: + import jedi + jedi.settings.case_insensitive_completion = False + import jedi.api.helpers + import jedi.api.classes + JEDI_INSTALLED = True +except ImportError: + JEDI_INSTALLED = False +#----------------------------------------------------------------------------- +# Globals +#----------------------------------------------------------------------------- + +# Public API +__all__ = ['Completer','IPCompleter'] + +if sys.platform == 'win32': + PROTECTABLES = ' ' +else: + PROTECTABLES = ' ()[]{}?=\\|;:\'#*"^&' + +# Protect against returning an enormous number of completions which the frontend +# may have trouble processing. +MATCHES_LIMIT = 500 + +_deprecation_readline_sentinel = object() + + +class ProvisionalCompleterWarning(FutureWarning): + """ + Exception raise by an experimental feature in this module. + + Wrap code in :any:`provisionalcompleter` context manager if you + are certain you want to use an unstable feature. + """ + pass + +warnings.filterwarnings('error', category=ProvisionalCompleterWarning) + +@contextmanager +def provisionalcompleter(action='ignore'): + """ + + + This context manager has to be used in any place where unstable completer + behavior and API may be called. + + >>> with provisionalcompleter(): + ... completer.do_experimental_things() # works + + >>> completer.do_experimental_things() # raises. + + .. note:: Unstable + + By using this context manager you agree that the API in use may change + without warning, and that you won't complain if they do so. + + You also understand that, if the API is not to your liking, you should report + a bug to explain your use case upstream. + + We'll be happy to get your feedback, feature requests, and improvements on + any of the unstable APIs! + """ + with warnings.catch_warnings(): + warnings.filterwarnings(action, category=ProvisionalCompleterWarning) + yield + + +def has_open_quotes(s): + """Return whether a string has open quotes. + + This simply counts whether the number of quote characters of either type in + the string is odd. + + Returns + ------- + If there is an open quote, the quote character is returned. Else, return + False. + """ + # We check " first, then ', so complex cases with nested quotes will get + # the " to take precedence. + if s.count('"') % 2: + return '"' + elif s.count("'") % 2: + return "'" + else: + return False + + +def protect_filename(s, protectables=PROTECTABLES): + """Escape a string to protect certain characters.""" + if set(s) & set(protectables): + if sys.platform == "win32": + return '"' + s + '"' + else: + return "".join(("\\" + c if c in protectables else c) for c in s) + else: + return s + + +def expand_user(path:str) -> Tuple[str, bool, str]: + """Expand ``~``-style usernames in strings. + + This is similar to :func:`os.path.expanduser`, but it computes and returns + extra information that will be useful if the input was being used in + computing completions, and you wish to return the completions with the + original '~' instead of its expanded value. + + Parameters + ---------- + path : str + String to be expanded. If no ~ is present, the output is the same as the + input. + + Returns + ------- + newpath : str + Result of ~ expansion in the input path. + tilde_expand : bool + Whether any expansion was performed or not. + tilde_val : str + The value that ~ was replaced with. + """ + # Default values + tilde_expand = False + tilde_val = '' + newpath = path + + if path.startswith('~'): + tilde_expand = True + rest = len(path)-1 + newpath = os.path.expanduser(path) + if rest: + tilde_val = newpath[:-rest] + else: + tilde_val = newpath + + return newpath, tilde_expand, tilde_val + + +def compress_user(path:str, tilde_expand:bool, tilde_val:str) -> str: + """Does the opposite of expand_user, with its outputs. + """ + if tilde_expand: + return path.replace(tilde_val, '~') + else: + return path + + +def completions_sorting_key(word): + """key for sorting completions + + This does several things: + + - Demote any completions starting with underscores to the end + - Insert any %magic and %%cellmagic completions in the alphabetical order + by their name + """ + prio1, prio2 = 0, 0 + + if word.startswith('__'): + prio1 = 2 + elif word.startswith('_'): + prio1 = 1 + + if word.endswith('='): + prio1 = -1 + + if word.startswith('%%'): + # If there's another % in there, this is something else, so leave it alone + if not "%" in word[2:]: + word = word[2:] + prio2 = 2 + elif word.startswith('%'): + if not "%" in word[1:]: + word = word[1:] + prio2 = 1 + + return prio1, word, prio2 + + +class _FakeJediCompletion: + """ + This is a workaround to communicate to the UI that Jedi has crashed and to + report a bug. Will be used only id :any:`IPCompleter.debug` is set to true. + + Added in IPython 6.0 so should likely be removed for 7.0 + + """ + + def __init__(self, name): + + self.name = name + self.complete = name + self.type = 'crashed' + self.name_with_symbols = name + self.signature = '' + self._origin = 'fake' + + def __repr__(self): + return '' + + +class Completion: + """ + Completion object used and return by IPython completers. + + .. warning:: Unstable + + This function is unstable, API may change without warning. + It will also raise unless use in proper context manager. + + This act as a middle ground :any:`Completion` object between the + :any:`jedi.api.classes.Completion` object and the Prompt Toolkit completion + object. While Jedi need a lot of information about evaluator and how the + code should be ran/inspected, PromptToolkit (and other frontend) mostly + need user facing information. + + - Which range should be replaced replaced by what. + - Some metadata (like completion type), or meta information to displayed to + the use user. + + For debugging purpose we can also store the origin of the completion (``jedi``, + ``IPython.python_matches``, ``IPython.magics_matches``...). + """ + + __slots__ = ['start', 'end', 'text', 'type', 'signature', '_origin'] + + def __init__(self, start: int, end: int, text: str, *, type: str=None, _origin='', signature='') -> None: + warnings.warn("``Completion`` is a provisional API (as of IPython 6.0). " + "It may change without warnings. " + "Use in corresponding context manager.", + category=ProvisionalCompleterWarning, stacklevel=2) + + self.start = start + self.end = end + self.text = text + self.type = type + self.signature = signature + self._origin = _origin + + def __repr__(self): + return '' % \ + (self.start, self.end, self.text, self.type or '?', self.signature or '?') + + def __eq__(self, other)->Bool: + """ + Equality and hash do not hash the type (as some completer may not be + able to infer the type), but are use to (partially) de-duplicate + completion. + + Completely de-duplicating completion is a bit tricker that just + comparing as it depends on surrounding text, which Completions are not + aware of. + """ + return self.start == other.start and \ + self.end == other.end and \ + self.text == other.text + + def __hash__(self): + return hash((self.start, self.end, self.text)) + + +_IC = Iterable[Completion] + + +def _deduplicate_completions(text: str, completions: _IC)-> _IC: + """ + Deduplicate a set of completions. + + .. warning:: Unstable + + This function is unstable, API may change without warning. + + Parameters + ---------- + text: str + text that should be completed. + completions: Iterator[Completion] + iterator over the completions to deduplicate + + Yields + ------ + `Completions` objects + + + Completions coming from multiple sources, may be different but end up having + the same effect when applied to ``text``. If this is the case, this will + consider completions as equal and only emit the first encountered. + + Not folded in `completions()` yet for debugging purpose, and to detect when + the IPython completer does return things that Jedi does not, but should be + at some point. + """ + completions = list(completions) + if not completions: + return + + new_start = min(c.start for c in completions) + new_end = max(c.end for c in completions) + + seen = set() + for c in completions: + new_text = text[new_start:c.start] + c.text + text[c.end:new_end] + if new_text not in seen: + yield c + seen.add(new_text) + + +def rectify_completions(text: str, completions: _IC, *, _debug=False)->_IC: + """ + Rectify a set of completions to all have the same ``start`` and ``end`` + + .. warning:: Unstable + + This function is unstable, API may change without warning. + It will also raise unless use in proper context manager. + + Parameters + ---------- + text: str + text that should be completed. + completions: Iterator[Completion] + iterator over the completions to rectify + + + :any:`jedi.api.classes.Completion` s returned by Jedi may not have the same start and end, though + the Jupyter Protocol requires them to behave like so. This will readjust + the completion to have the same ``start`` and ``end`` by padding both + extremities with surrounding text. + + During stabilisation should support a ``_debug`` option to log which + completion are return by the IPython completer and not found in Jedi in + order to make upstream bug report. + """ + warnings.warn("`rectify_completions` is a provisional API (as of IPython 6.0). " + "It may change without warnings. " + "Use in corresponding context manager.", + category=ProvisionalCompleterWarning, stacklevel=2) + + completions = list(completions) + if not completions: + return + starts = (c.start for c in completions) + ends = (c.end for c in completions) + + new_start = min(starts) + new_end = max(ends) + + seen_jedi = set() + seen_python_matches = set() + for c in completions: + new_text = text[new_start:c.start] + c.text + text[c.end:new_end] + if c._origin == 'jedi': + seen_jedi.add(new_text) + elif c._origin == 'IPCompleter.python_matches': + seen_python_matches.add(new_text) + yield Completion(new_start, new_end, new_text, type=c.type, _origin=c._origin, signature=c.signature) + diff = seen_python_matches.difference(seen_jedi) + if diff and _debug: + print('IPython.python matches have extras:', diff) + + +if sys.platform == 'win32': + DELIMS = ' \t\n`!@#$^&*()=+[{]}|;\'",<>?' +else: + DELIMS = ' \t\n`!@#$^&*()=+[{]}\\|;:\'",<>?' + +GREEDY_DELIMS = ' =\r\n' + + +class CompletionSplitter(object): + """An object to split an input line in a manner similar to readline. + + By having our own implementation, we can expose readline-like completion in + a uniform manner to all frontends. This object only needs to be given the + line of text to be split and the cursor position on said line, and it + returns the 'word' to be completed on at the cursor after splitting the + entire line. + + What characters are used as splitting delimiters can be controlled by + setting the ``delims`` attribute (this is a property that internally + automatically builds the necessary regular expression)""" + + # Private interface + + # A string of delimiter characters. The default value makes sense for + # IPython's most typical usage patterns. + _delims = DELIMS + + # The expression (a normal string) to be compiled into a regular expression + # for actual splitting. We store it as an attribute mostly for ease of + # debugging, since this type of code can be so tricky to debug. + _delim_expr = None + + # The regular expression that does the actual splitting + _delim_re = None + + def __init__(self, delims=None): + delims = CompletionSplitter._delims if delims is None else delims + self.delims = delims + + @property + def delims(self): + """Return the string of delimiter characters.""" + return self._delims + + @delims.setter + def delims(self, delims): + """Set the delimiters for line splitting.""" + expr = '[' + ''.join('\\'+ c for c in delims) + ']' + self._delim_re = re.compile(expr) + self._delims = delims + self._delim_expr = expr + + def split_line(self, line, cursor_pos=None): + """Split a line of text with a cursor at the given position. + """ + l = line if cursor_pos is None else line[:cursor_pos] + return self._delim_re.split(l)[-1] + + + +class Completer(Configurable): + + greedy = Bool(False, + help="""Activate greedy completion + PENDING DEPRECTION. this is now mostly taken care of with Jedi. + + This will enable completion on elements of lists, results of function calls, etc., + but can be unsafe because the code is actually evaluated on TAB. + """ + ).tag(config=True) + + use_jedi = Bool(default_value=JEDI_INSTALLED, + help="Experimental: Use Jedi to generate autocompletions. " + "Default to True if jedi is installed.").tag(config=True) + + jedi_compute_type_timeout = Int(default_value=400, + help="""Experimental: restrict time (in milliseconds) during which Jedi can compute types. + Set to 0 to stop computing types. Non-zero value lower than 100ms may hurt + performance by preventing jedi to build its cache. + """).tag(config=True) + + debug = Bool(default_value=False, + help='Enable debug for the Completer. Mostly print extra ' + 'information for experimental jedi integration.')\ + .tag(config=True) + + backslash_combining_completions = Bool(True, + help="Enable unicode completions, e.g. \\alpha . " + "Includes completion of latex commands, unicode names, and expanding " + "unicode characters back to latex commands.").tag(config=True) + + + + def __init__(self, namespace=None, global_namespace=None, **kwargs): + """Create a new completer for the command line. + + Completer(namespace=ns, global_namespace=ns2) -> completer instance. + + If unspecified, the default namespace where completions are performed + is __main__ (technically, __main__.__dict__). Namespaces should be + given as dictionaries. + + An optional second namespace can be given. This allows the completer + to handle cases where both the local and global scopes need to be + distinguished. + """ + + # Don't bind to namespace quite yet, but flag whether the user wants a + # specific namespace or to use __main__.__dict__. This will allow us + # to bind to __main__.__dict__ at completion time, not now. + if namespace is None: + self.use_main_ns = True + else: + self.use_main_ns = False + self.namespace = namespace + + # The global namespace, if given, can be bound directly + if global_namespace is None: + self.global_namespace = {} + else: + self.global_namespace = global_namespace + + self.custom_matchers = [] + + super(Completer, self).__init__(**kwargs) + + def complete(self, text, state): + """Return the next possible completion for 'text'. + + This is called successively with state == 0, 1, 2, ... until it + returns None. The completion should begin with 'text'. + + """ + if self.use_main_ns: + self.namespace = __main__.__dict__ + + if state == 0: + if "." in text: + self.matches = self.attr_matches(text) + else: + self.matches = self.global_matches(text) + try: + return self.matches[state] + except IndexError: + return None + + def global_matches(self, text): + """Compute matches when text is a simple name. + + Return a list of all keywords, built-in functions and names currently + defined in self.namespace or self.global_namespace that match. + + """ + matches = [] + match_append = matches.append + n = len(text) + for lst in [keyword.kwlist, + builtin_mod.__dict__.keys(), + self.namespace.keys(), + self.global_namespace.keys()]: + for word in lst: + if word[:n] == text and word != "__builtins__": + match_append(word) + + snake_case_re = re.compile(r"[^_]+(_[^_]+)+?\Z") + for lst in [self.namespace.keys(), + self.global_namespace.keys()]: + shortened = {"_".join([sub[0] for sub in word.split('_')]) : word + for word in lst if snake_case_re.match(word)} + for word in shortened.keys(): + if word[:n] == text and word != "__builtins__": + match_append(shortened[word]) + return matches + + def attr_matches(self, text): + """Compute matches when text contains a dot. + + Assuming the text is of the form NAME.NAME....[NAME], and is + evaluatable in self.namespace or self.global_namespace, it will be + evaluated and its attributes (as revealed by dir()) are used as + possible completions. (For class instances, class members are + also considered.) + + WARNING: this can still invoke arbitrary C code, if an object + with a __getattr__ hook is evaluated. + + """ + + # Another option, seems to work great. Catches things like ''. + m = re.match(r"(\S+(\.\w+)*)\.(\w*)$", text) + + if m: + expr, attr = m.group(1, 3) + elif self.greedy: + m2 = re.match(r"(.+)\.(\w*)$", self.line_buffer) + if not m2: + return [] + expr, attr = m2.group(1,2) + else: + return [] + + try: + obj = eval(expr, self.namespace) + except: + try: + obj = eval(expr, self.global_namespace) + except: + return [] + + if self.limit_to__all__ and hasattr(obj, '__all__'): + words = get__all__entries(obj) + else: + words = dir2(obj) + + try: + words = generics.complete_object(obj, words) + except TryNext: + pass + except AssertionError: + raise + except Exception: + # Silence errors from completion function + #raise # dbg + pass + # Build match list to return + n = len(attr) + return [u"%s.%s" % (expr, w) for w in words if w[:n] == attr ] + + +def get__all__entries(obj): + """returns the strings in the __all__ attribute""" + try: + words = getattr(obj, '__all__') + except: + return [] + + return [w for w in words if isinstance(w, str)] + + +def match_dict_keys(keys: List[str], prefix: str, delims: str): + """Used by dict_key_matches, matching the prefix to a list of keys + + Parameters + ========== + keys: + list of keys in dictionary currently being completed. + prefix: + Part of the text already typed by the user. e.g. `mydict[b'fo` + delims: + String of delimiters to consider when finding the current key. + + Returns + ======= + + A tuple of three elements: ``quote``, ``token_start``, ``matched``, with + ``quote`` being the quote that need to be used to close current string. + ``token_start`` the position where the replacement should start occurring, + ``matches`` a list of replacement/completion + + """ + if not prefix: + return None, 0, [repr(k) for k in keys + if isinstance(k, (str, bytes))] + quote_match = re.search('["\']', prefix) + quote = quote_match.group() + try: + prefix_str = eval(prefix + quote, {}) + except Exception: + return None, 0, [] + + pattern = '[^' + ''.join('\\' + c for c in delims) + ']*$' + token_match = re.search(pattern, prefix, re.UNICODE) + token_start = token_match.start() + token_prefix = token_match.group() + + matched = [] + for key in keys: + try: + if not key.startswith(prefix_str): + continue + except (AttributeError, TypeError, UnicodeError): + # Python 3+ TypeError on b'a'.startswith('a') or vice-versa + continue + + # reformat remainder of key to begin with prefix + rem = key[len(prefix_str):] + # force repr wrapped in ' + rem_repr = repr(rem + '"') if isinstance(rem, str) else repr(rem + b'"') + if rem_repr.startswith('u') and prefix[0] not in 'uU': + # Found key is unicode, but prefix is Py2 string. + # Therefore attempt to interpret key as string. + try: + rem_repr = repr(rem.encode('ascii') + '"') + except UnicodeEncodeError: + continue + + rem_repr = rem_repr[1 + rem_repr.index("'"):-2] + if quote == '"': + # The entered prefix is quoted with ", + # but the match is quoted with '. + # A contained " hence needs escaping for comparison: + rem_repr = rem_repr.replace('"', '\\"') + + # then reinsert prefix from start of token + matched.append('%s%s' % (token_prefix, rem_repr)) + return quote, token_start, matched + + +def cursor_to_position(text:str, line:int, column:int)->int: + """ + + Convert the (line,column) position of the cursor in text to an offset in a + string. + + Parameters + ---------- + + text : str + The text in which to calculate the cursor offset + line : int + Line of the cursor; 0-indexed + column : int + Column of the cursor 0-indexed + + Return + ------ + Position of the cursor in ``text``, 0-indexed. + + See Also + -------- + position_to_cursor: reciprocal of this function + + """ + lines = text.split('\n') + assert line <= len(lines), '{} <= {}'.format(str(line), str(len(lines))) + + return sum(len(l) + 1 for l in lines[:line]) + column + +def position_to_cursor(text:str, offset:int)->Tuple[int, int]: + """ + Convert the position of the cursor in text (0 indexed) to a line + number(0-indexed) and a column number (0-indexed) pair + + Position should be a valid position in ``text``. + + Parameters + ---------- + + text : str + The text in which to calculate the cursor offset + offset : int + Position of the cursor in ``text``, 0-indexed. + + Return + ------ + (line, column) : (int, int) + Line of the cursor; 0-indexed, column of the cursor 0-indexed + + + See Also + -------- + cursor_to_position : reciprocal of this function + + + """ + + assert 0 <= offset <= len(text) , "0 <= %s <= %s" % (offset , len(text)) + + before = text[:offset] + blines = before.split('\n') # ! splitnes trim trailing \n + line = before.count('\n') + col = len(blines[-1]) + return line, col + + +def _safe_isinstance(obj, module, class_name): + """Checks if obj is an instance of module.class_name if loaded + """ + return (module in sys.modules and + isinstance(obj, getattr(import_module(module), class_name))) + + +def back_unicode_name_matches(text): + u"""Match unicode characters back to unicode name + + This does ``☃`` -> ``\\snowman`` + + Note that snowman is not a valid python3 combining character but will be expanded. + Though it will not recombine back to the snowman character by the completion machinery. + + This will not either back-complete standard sequences like \\n, \\b ... + + Used on Python 3 only. + """ + if len(text)<2: + return u'', () + maybe_slash = text[-2] + if maybe_slash != '\\': + return u'', () + + char = text[-1] + # no expand on quote for completion in strings. + # nor backcomplete standard ascii keys + if char in string.ascii_letters or char in ['"',"'"]: + return u'', () + try : + unic = unicodedata.name(char) + return '\\'+char,['\\'+unic] + except KeyError: + pass + return u'', () + +def back_latex_name_matches(text:str): + """Match latex characters back to unicode name + + This does ``\\ℵ`` -> ``\\aleph`` + + Used on Python 3 only. + """ + if len(text)<2: + return u'', () + maybe_slash = text[-2] + if maybe_slash != '\\': + return u'', () + + + char = text[-1] + # no expand on quote for completion in strings. + # nor backcomplete standard ascii keys + if char in string.ascii_letters or char in ['"',"'"]: + return u'', () + try : + latex = reverse_latex_symbol[char] + # '\\' replace the \ as well + return '\\'+char,[latex] + except KeyError: + pass + return u'', () + + +def _formatparamchildren(parameter) -> str: + """ + Get parameter name and value from Jedi Private API + + Jedi does not expose a simple way to get `param=value` from its API. + + Parameter + ========= + + parameter: + Jedi's function `Param` + + Returns + ======= + + A string like 'a', 'b=1', '*args', '**kwargs' + + + """ + description = parameter.description + if not description.startswith('param '): + raise ValueError('Jedi function parameter description have change format.' + 'Expected "param ...", found %r".' % description) + return description[6:] + +def _make_signature(completion)-> str: + """ + Make the signature from a jedi completion + + Parameter + ========= + + completion: jedi.Completion + object does not complete a function type + + Returns + ======= + + a string consisting of the function signature, with the parenthesis but + without the function name. example: + `(a, *args, b=1, **kwargs)` + + """ + + return '(%s)'% ', '.join([f for f in (_formatparamchildren(p) for p in completion.params) if f]) + +class IPCompleter(Completer): + """Extension of the completer class with IPython-specific features""" + + _names = None + + @observe('greedy') + def _greedy_changed(self, change): + """update the splitter and readline delims when greedy is changed""" + if change['new']: + self.splitter.delims = GREEDY_DELIMS + else: + self.splitter.delims = DELIMS + + dict_keys_only = Bool(False, + help="""Whether to show dict key matches only""") + + merge_completions = Bool(True, + help="""Whether to merge completion results into a single list + + If False, only the completion results from the first non-empty + completer will be returned. + """ + ).tag(config=True) + omit__names = Enum((0,1,2), default_value=2, + help="""Instruct the completer to omit private method names + + Specifically, when completing on ``object.``. + + When 2 [default]: all names that start with '_' will be excluded. + + When 1: all 'magic' names (``__foo__``) will be excluded. + + When 0: nothing will be excluded. + """ + ).tag(config=True) + limit_to__all__ = Bool(False, + help=""" + DEPRECATED as of version 5.0. + + Instruct the completer to use __all__ for the completion + + Specifically, when completing on ``object.``. + + When True: only those names in obj.__all__ will be included. + + When False [default]: the __all__ attribute is ignored + """, + ).tag(config=True) + + @observe('limit_to__all__') + def _limit_to_all_changed(self, change): + warnings.warn('`IPython.core.IPCompleter.limit_to__all__` configuration ' + 'value has been deprecated since IPython 5.0, will be made to have ' + 'no effects and then removed in future version of IPython.', + UserWarning) + + def __init__(self, shell=None, namespace=None, global_namespace=None, + use_readline=_deprecation_readline_sentinel, config=None, **kwargs): + """IPCompleter() -> completer + + Return a completer object. + + Parameters + ---------- + + shell + a pointer to the ipython shell itself. This is needed + because this completer knows about magic functions, and those can + only be accessed via the ipython instance. + + namespace : dict, optional + an optional dict where completions are performed. + + global_namespace : dict, optional + secondary optional dict for completions, to + handle cases (such as IPython embedded inside functions) where + both Python scopes are visible. + + use_readline : bool, optional + DEPRECATED, ignored since IPython 6.0, will have no effects + """ + + self.magic_escape = ESC_MAGIC + self.splitter = CompletionSplitter() + + if use_readline is not _deprecation_readline_sentinel: + warnings.warn('The `use_readline` parameter is deprecated and ignored since IPython 6.0.', + DeprecationWarning, stacklevel=2) + + # _greedy_changed() depends on splitter and readline being defined: + Completer.__init__(self, namespace=namespace, global_namespace=global_namespace, + config=config, **kwargs) + + # List where completion matches will be stored + self.matches = [] + self.shell = shell + # Regexp to split filenames with spaces in them + self.space_name_re = re.compile(r'([^\\] )') + # Hold a local ref. to glob.glob for speed + self.glob = glob.glob + + # Determine if we are running on 'dumb' terminals, like (X)Emacs + # buffers, to avoid completion problems. + term = os.environ.get('TERM','xterm') + self.dumb_terminal = term in ['dumb','emacs'] + + # Special handling of backslashes needed in win32 platforms + if sys.platform == "win32": + self.clean_glob = self._clean_glob_win32 + else: + self.clean_glob = self._clean_glob + + #regexp to parse docstring for function signature + self.docstring_sig_re = re.compile(r'^[\w|\s.]+\(([^)]*)\).*') + self.docstring_kwd_re = re.compile(r'[\s|\[]*(\w+)(?:\s*=\s*.*)') + #use this if positional argument name is also needed + #= re.compile(r'[\s|\[]*(\w+)(?:\s*=?\s*.*)') + + self.magic_arg_matchers = [ + self.magic_config_matches, + self.magic_color_matches, + ] + + # This is set externally by InteractiveShell + self.custom_completers = None + + @property + def matchers(self): + """All active matcher routines for completion""" + if self.dict_keys_only: + return [self.dict_key_matches] + + if self.use_jedi: + return [ + *self.custom_matchers, + self.file_matches, + self.magic_matches, + self.dict_key_matches, + ] + else: + return [ + *self.custom_matchers, + self.python_matches, + self.file_matches, + self.magic_matches, + self.python_func_kw_matches, + self.dict_key_matches, + ] + + def all_completions(self, text) -> List[str]: + """ + Wrapper around the completion methods for the benefit of emacs. + """ + prefix = text.rpartition('.')[0] + with provisionalcompleter(): + return ['.'.join([prefix, c.text]) if prefix and self.use_jedi else c.text + for c in self.completions(text, len(text))] + + return self.complete(text)[1] + + def _clean_glob(self, text): + return self.glob("%s*" % text) + + def _clean_glob_win32(self,text): + return [f.replace("\\","/") + for f in self.glob("%s*" % text)] + + def file_matches(self, text): + """Match filenames, expanding ~USER type strings. + + Most of the seemingly convoluted logic in this completer is an + attempt to handle filenames with spaces in them. And yet it's not + quite perfect, because Python's readline doesn't expose all of the + GNU readline details needed for this to be done correctly. + + For a filename with a space in it, the printed completions will be + only the parts after what's already been typed (instead of the + full completions, as is normally done). I don't think with the + current (as of Python 2.3) Python readline it's possible to do + better.""" + + # chars that require escaping with backslash - i.e. chars + # that readline treats incorrectly as delimiters, but we + # don't want to treat as delimiters in filename matching + # when escaped with backslash + if text.startswith('!'): + text = text[1:] + text_prefix = u'!' + else: + text_prefix = u'' + + text_until_cursor = self.text_until_cursor + # track strings with open quotes + open_quotes = has_open_quotes(text_until_cursor) + + if '(' in text_until_cursor or '[' in text_until_cursor: + lsplit = text + else: + try: + # arg_split ~ shlex.split, but with unicode bugs fixed by us + lsplit = arg_split(text_until_cursor)[-1] + except ValueError: + # typically an unmatched ", or backslash without escaped char. + if open_quotes: + lsplit = text_until_cursor.split(open_quotes)[-1] + else: + return [] + except IndexError: + # tab pressed on empty line + lsplit = "" + + if not open_quotes and lsplit != protect_filename(lsplit): + # if protectables are found, do matching on the whole escaped name + has_protectables = True + text0,text = text,lsplit + else: + has_protectables = False + text = os.path.expanduser(text) + + if text == "": + return [text_prefix + protect_filename(f) for f in self.glob("*")] + + # Compute the matches from the filesystem + if sys.platform == 'win32': + m0 = self.clean_glob(text) + else: + m0 = self.clean_glob(text.replace('\\', '')) + + if has_protectables: + # If we had protectables, we need to revert our changes to the + # beginning of filename so that we don't double-write the part + # of the filename we have so far + len_lsplit = len(lsplit) + matches = [text_prefix + text0 + + protect_filename(f[len_lsplit:]) for f in m0] + else: + if open_quotes: + # if we have a string with an open quote, we don't need to + # protect the names beyond the quote (and we _shouldn't_, as + # it would cause bugs when the filesystem call is made). + matches = m0 if sys.platform == "win32" else\ + [protect_filename(f, open_quotes) for f in m0] + else: + matches = [text_prefix + + protect_filename(f) for f in m0] + + # Mark directories in input list by appending '/' to their names. + return [x+'/' if os.path.isdir(x) else x for x in matches] + + def magic_matches(self, text): + """Match magics""" + # Get all shell magics now rather than statically, so magics loaded at + # runtime show up too. + lsm = self.shell.magics_manager.lsmagic() + line_magics = lsm['line'] + cell_magics = lsm['cell'] + pre = self.magic_escape + pre2 = pre+pre + + explicit_magic = text.startswith(pre) + + # Completion logic: + # - user gives %%: only do cell magics + # - user gives %: do both line and cell magics + # - no prefix: do both + # In other words, line magics are skipped if the user gives %% explicitly + # + # We also exclude magics that match any currently visible names: + # https://github.com/ipython/ipython/issues/4877, unless the user has + # typed a %: + # https://github.com/ipython/ipython/issues/10754 + bare_text = text.lstrip(pre) + global_matches = self.global_matches(bare_text) + if not explicit_magic: + def matches(magic): + """ + Filter magics, in particular remove magics that match + a name present in global namespace. + """ + return ( magic.startswith(bare_text) and + magic not in global_matches ) + else: + def matches(magic): + return magic.startswith(bare_text) + + comp = [ pre2+m for m in cell_magics if matches(m)] + if not text.startswith(pre2): + comp += [ pre+m for m in line_magics if matches(m)] + + return comp + + def magic_config_matches(self, text:str) -> List[str]: + """ Match class names and attributes for %config magic """ + texts = text.strip().split() + + if len(texts) > 0 and (texts[0] == 'config' or texts[0] == '%config'): + # get all configuration classes + classes = sorted(set([ c for c in self.shell.configurables + if c.__class__.class_traits(config=True) + ]), key=lambda x: x.__class__.__name__) + classnames = [ c.__class__.__name__ for c in classes ] + + # return all classnames if config or %config is given + if len(texts) == 1: + return classnames + + # match classname + classname_texts = texts[1].split('.') + classname = classname_texts[0] + classname_matches = [ c for c in classnames + if c.startswith(classname) ] + + # return matched classes or the matched class with attributes + if texts[1].find('.') < 0: + return classname_matches + elif len(classname_matches) == 1 and \ + classname_matches[0] == classname: + cls = classes[classnames.index(classname)].__class__ + help = cls.class_get_help() + # strip leading '--' from cl-args: + help = re.sub(re.compile(r'^--', re.MULTILINE), '', help) + return [ attr.split('=')[0] + for attr in help.strip().splitlines() + if attr.startswith(texts[1]) ] + return [] + + def magic_color_matches(self, text:str) -> List[str] : + """ Match color schemes for %colors magic""" + texts = text.split() + if text.endswith(' '): + # .split() strips off the trailing whitespace. Add '' back + # so that: '%colors ' -> ['%colors', ''] + texts.append('') + + if len(texts) == 2 and (texts[0] == 'colors' or texts[0] == '%colors'): + prefix = texts[1] + return [ color for color in InspectColors.keys() + if color.startswith(prefix) ] + return [] + + def _jedi_matches(self, cursor_column:int, cursor_line:int, text:str): + """ + + Return a list of :any:`jedi.api.Completions` object from a ``text`` and + cursor position. + + Parameters + ---------- + cursor_column : int + column position of the cursor in ``text``, 0-indexed. + cursor_line : int + line position of the cursor in ``text``, 0-indexed + text : str + text to complete + + Debugging + --------- + + If ``IPCompleter.debug`` is ``True`` may return a :any:`_FakeJediCompletion` + object containing a string with the Jedi debug information attached. + """ + namespaces = [self.namespace] + if self.global_namespace is not None: + namespaces.append(self.global_namespace) + + completion_filter = lambda x:x + offset = cursor_to_position(text, cursor_line, cursor_column) + # filter output if we are completing for object members + if offset: + pre = text[offset-1] + if pre == '.': + if self.omit__names == 2: + completion_filter = lambda c:not c.name.startswith('_') + elif self.omit__names == 1: + completion_filter = lambda c:not (c.name.startswith('__') and c.name.endswith('__')) + elif self.omit__names == 0: + completion_filter = lambda x:x + else: + raise ValueError("Don't understand self.omit__names == {}".format(self.omit__names)) + + interpreter = jedi.Interpreter( + text[:offset], namespaces, column=cursor_column, line=cursor_line + 1) + try_jedi = True + + try: + # find the first token in the current tree -- if it is a ' or " then we are in a string + completing_string = False + try: + first_child = next(c for c in interpreter._get_module().tree_node.children if hasattr(c, 'value')) + except StopIteration: + pass + else: + # note the value may be ', ", or it may also be ''' or """, or + # in some cases, """what/you/typed..., but all of these are + # strings. + completing_string = len(first_child.value) > 0 and first_child.value[0] in {"'", '"'} + + # if we are in a string jedi is likely not the right candidate for + # now. Skip it. + try_jedi = not completing_string + except Exception as e: + # many of things can go wrong, we are using private API just don't crash. + if self.debug: + print("Error detecting if completing a non-finished string :", e, '|') + + if not try_jedi: + return [] + try: + return filter(completion_filter, interpreter.completions()) + except Exception as e: + if self.debug: + return [_FakeJediCompletion('Oops Jedi has crashed, please report a bug with the following:\n"""\n%s\ns"""' % (e))] + else: + return [] + + def python_matches(self, text): + """Match attributes or global python names""" + if "." in text: + try: + matches = self.attr_matches(text) + if text.endswith('.') and self.omit__names: + if self.omit__names == 1: + # true if txt is _not_ a __ name, false otherwise: + no__name = (lambda txt: + re.match(r'.*\.__.*?__',txt) is None) + else: + # true if txt is _not_ a _ name, false otherwise: + no__name = (lambda txt: + re.match(r'\._.*?',txt[txt.rindex('.'):]) is None) + matches = filter(no__name, matches) + except NameError: + # catches . + matches = [] + else: + matches = self.global_matches(text) + return matches + + def _default_arguments_from_docstring(self, doc): + """Parse the first line of docstring for call signature. + + Docstring should be of the form 'min(iterable[, key=func])\n'. + It can also parse cython docstring of the form + 'Minuit.migrad(self, int ncall=10000, resume=True, int nsplit=1)'. + """ + if doc is None: + return [] + + #care only the firstline + line = doc.lstrip().splitlines()[0] + + #p = re.compile(r'^[\w|\s.]+\(([^)]*)\).*') + #'min(iterable[, key=func])\n' -> 'iterable[, key=func]' + sig = self.docstring_sig_re.search(line) + if sig is None: + return [] + # iterable[, key=func]' -> ['iterable[' ,' key=func]'] + sig = sig.groups()[0].split(',') + ret = [] + for s in sig: + #re.compile(r'[\s|\[]*(\w+)(?:\s*=\s*.*)') + ret += self.docstring_kwd_re.findall(s) + return ret + + def _default_arguments(self, obj): + """Return the list of default arguments of obj if it is callable, + or empty list otherwise.""" + call_obj = obj + ret = [] + if inspect.isbuiltin(obj): + pass + elif not (inspect.isfunction(obj) or inspect.ismethod(obj)): + if inspect.isclass(obj): + #for cython embedsignature=True the constructor docstring + #belongs to the object itself not __init__ + ret += self._default_arguments_from_docstring( + getattr(obj, '__doc__', '')) + # for classes, check for __init__,__new__ + call_obj = (getattr(obj, '__init__', None) or + getattr(obj, '__new__', None)) + # for all others, check if they are __call__able + elif hasattr(obj, '__call__'): + call_obj = obj.__call__ + ret += self._default_arguments_from_docstring( + getattr(call_obj, '__doc__', '')) + + _keeps = (inspect.Parameter.KEYWORD_ONLY, + inspect.Parameter.POSITIONAL_OR_KEYWORD) + + try: + sig = inspect.signature(call_obj) + ret.extend(k for k, v in sig.parameters.items() if + v.kind in _keeps) + except ValueError: + pass + + return list(set(ret)) + + def python_func_kw_matches(self,text): + """Match named parameters (kwargs) of the last open function""" + + if "." in text: # a parameter cannot be dotted + return [] + try: regexp = self.__funcParamsRegex + except AttributeError: + regexp = self.__funcParamsRegex = re.compile(r''' + '.*?(?,a=1)", the candidate is "foo" + tokens = regexp.findall(self.text_until_cursor) + iterTokens = reversed(tokens); openPar = 0 + + for token in iterTokens: + if token == ')': + openPar -= 1 + elif token == '(': + openPar += 1 + if openPar > 0: + # found the last unclosed parenthesis + break + else: + return [] + # 2. Concatenate dotted names ("foo.bar" for "foo.bar(x, pa" ) + ids = [] + isId = re.compile(r'\w+$').match + + while True: + try: + ids.append(next(iterTokens)) + if not isId(ids[-1]): + ids.pop(); break + if not next(iterTokens) == '.': + break + except StopIteration: + break + + # Find all named arguments already assigned to, as to avoid suggesting + # them again + usedNamedArgs = set() + par_level = -1 + for token, next_token in zip(tokens, tokens[1:]): + if token == '(': + par_level += 1 + elif token == ')': + par_level -= 1 + + if par_level != 0: + continue + + if next_token != '=': + continue + + usedNamedArgs.add(token) + + argMatches = [] + try: + callableObj = '.'.join(ids[::-1]) + namedArgs = self._default_arguments(eval(callableObj, + self.namespace)) + + # Remove used named arguments from the list, no need to show twice + for namedArg in set(namedArgs) - usedNamedArgs: + if namedArg.startswith(text): + argMatches.append(u"%s=" %namedArg) + except: + pass + + return argMatches + + def dict_key_matches(self, text): + "Match string keys in a dictionary, after e.g. 'foo[' " + def get_keys(obj): + # Objects can define their own completions by defining an + # _ipy_key_completions_() method. + method = get_real_method(obj, '_ipython_key_completions_') + if method is not None: + return method() + + # Special case some common in-memory dict-like types + if isinstance(obj, dict) or\ + _safe_isinstance(obj, 'pandas', 'DataFrame'): + try: + return list(obj.keys()) + except Exception: + return [] + elif _safe_isinstance(obj, 'numpy', 'ndarray') or\ + _safe_isinstance(obj, 'numpy', 'void'): + return obj.dtype.names or [] + return [] + + try: + regexps = self.__dict_key_regexps + except AttributeError: + dict_key_re_fmt = r'''(?x) + ( # match dict-referring expression wrt greedy setting + %s + ) + \[ # open bracket + \s* # and optional whitespace + ([uUbB]? # string prefix (r not handled) + (?: # unclosed string + '(?:[^']|(? key_start: + leading = '' + else: + leading = text[text_start:completion_start] + + # the index of the `[` character + bracket_idx = match.end(1) + + # append closing quote and bracket as appropriate + # this is *not* appropriate if the opening quote or bracket is outside + # the text given to this method + suf = '' + continuation = self.line_buffer[len(self.text_until_cursor):] + if key_start > text_start and closing_quote: + # quotes were opened inside text, maybe close them + if continuation.startswith(closing_quote): + continuation = continuation[len(closing_quote):] + else: + suf += closing_quote + if bracket_idx > text_start: + # brackets were opened inside text, maybe close them + if not continuation.startswith(']'): + suf += ']' + + return [leading + k + suf for k in matches] + + def unicode_name_matches(self, text): + u"""Match Latex-like syntax for unicode characters base + on the name of the character. + + This does ``\\GREEK SMALL LETTER ETA`` -> ``η`` + + Works only on valid python 3 identifier, or on combining characters that + will combine to form a valid identifier. + + Used on Python 3 only. + """ + slashpos = text.rfind('\\') + if slashpos > -1: + s = text[slashpos+1:] + try : + unic = unicodedata.lookup(s) + # allow combining chars + if ('a'+unic).isidentifier(): + return '\\'+s,[unic] + except KeyError: + pass + return u'', [] + + + def latex_matches(self, text): + u"""Match Latex syntax for unicode characters. + + This does both ``\\alp`` -> ``\\alpha`` and ``\\alpha`` -> ``α`` + """ + slashpos = text.rfind('\\') + if slashpos > -1: + s = text[slashpos:] + if s in latex_symbols: + # Try to complete a full latex symbol to unicode + # \\alpha -> α + return s, [latex_symbols[s]] + else: + # If a user has partially typed a latex symbol, give them + # a full list of options \al -> [\aleph, \alpha] + matches = [k for k in latex_symbols if k.startswith(s)] + if matches: + return s, matches + return u'', [] + + def dispatch_custom_completer(self, text): + if not self.custom_completers: + return + + line = self.line_buffer + if not line.strip(): + return None + + # Create a little structure to pass all the relevant information about + # the current completion to any custom completer. + event = SimpleNamespace() + event.line = line + event.symbol = text + cmd = line.split(None,1)[0] + event.command = cmd + event.text_until_cursor = self.text_until_cursor + + # for foo etc, try also to find completer for %foo + if not cmd.startswith(self.magic_escape): + try_magic = self.custom_completers.s_matches( + self.magic_escape + cmd) + else: + try_magic = [] + + for c in itertools.chain(self.custom_completers.s_matches(cmd), + try_magic, + self.custom_completers.flat_matches(self.text_until_cursor)): + try: + res = c(event) + if res: + # first, try case sensitive match + withcase = [r for r in res if r.startswith(text)] + if withcase: + return withcase + # if none, then case insensitive ones are ok too + text_low = text.lower() + return [r for r in res if r.lower().startswith(text_low)] + except TryNext: + pass + except KeyboardInterrupt: + """ + If custom completer take too long, + let keyboard interrupt abort and return nothing. + """ + break + + return None + + def completions(self, text: str, offset: int)->Iterator[Completion]: + """ + Returns an iterator over the possible completions + + .. warning:: Unstable + + This function is unstable, API may change without warning. + It will also raise unless use in proper context manager. + + Parameters + ---------- + + text:str + Full text of the current input, multi line string. + offset:int + Integer representing the position of the cursor in ``text``. Offset + is 0-based indexed. + + Yields + ------ + :any:`Completion` object + + + The cursor on a text can either be seen as being "in between" + characters or "On" a character depending on the interface visible to + the user. For consistency the cursor being on "in between" characters X + and Y is equivalent to the cursor being "on" character Y, that is to say + the character the cursor is on is considered as being after the cursor. + + Combining characters may span more that one position in the + text. + + + .. note:: + + If ``IPCompleter.debug`` is :any:`True` will yield a ``--jedi/ipython--`` + fake Completion token to distinguish completion returned by Jedi + and usual IPython completion. + + .. note:: + + Completions are not completely deduplicated yet. If identical + completions are coming from different sources this function does not + ensure that each completion object will only be present once. + """ + warnings.warn("_complete is a provisional API (as of IPython 6.0). " + "It may change without warnings. " + "Use in corresponding context manager.", + category=ProvisionalCompleterWarning, stacklevel=2) + + seen = set() + try: + for c in self._completions(text, offset, _timeout=self.jedi_compute_type_timeout/1000): + if c and (c in seen): + continue + yield c + seen.add(c) + except KeyboardInterrupt: + """if completions take too long and users send keyboard interrupt, + do not crash and return ASAP. """ + pass + + def _completions(self, full_text: str, offset: int, *, _timeout)->Iterator[Completion]: + """ + Core completion module.Same signature as :any:`completions`, with the + extra `timeout` parameter (in seconds). + + + Computing jedi's completion ``.type`` can be quite expensive (it is a + lazy property) and can require some warm-up, more warm up than just + computing the ``name`` of a completion. The warm-up can be : + + - Long warm-up the first time a module is encountered after + install/update: actually build parse/inference tree. + + - first time the module is encountered in a session: load tree from + disk. + + We don't want to block completions for tens of seconds so we give the + completer a "budget" of ``_timeout`` seconds per invocation to compute + completions types, the completions that have not yet been computed will + be marked as "unknown" an will have a chance to be computed next round + are things get cached. + + Keep in mind that Jedi is not the only thing treating the completion so + keep the timeout short-ish as if we take more than 0.3 second we still + have lots of processing to do. + + """ + deadline = time.monotonic() + _timeout + + + before = full_text[:offset] + cursor_line, cursor_column = position_to_cursor(full_text, offset) + + matched_text, matches, matches_origin, jedi_matches = self._complete( + full_text=full_text, cursor_line=cursor_line, cursor_pos=cursor_column) + + iter_jm = iter(jedi_matches) + if _timeout: + for jm in iter_jm: + try: + type_ = jm.type + except Exception: + if self.debug: + print("Error in Jedi getting type of ", jm) + type_ = None + delta = len(jm.name_with_symbols) - len(jm.complete) + if type_ == 'function': + signature = _make_signature(jm) + else: + signature = '' + yield Completion(start=offset - delta, + end=offset, + text=jm.name_with_symbols, + type=type_, + signature=signature, + _origin='jedi') + + if time.monotonic() > deadline: + break + + for jm in iter_jm: + delta = len(jm.name_with_symbols) - len(jm.complete) + yield Completion(start=offset - delta, + end=offset, + text=jm.name_with_symbols, + type='', # don't compute type for speed + _origin='jedi', + signature='') + + + start_offset = before.rfind(matched_text) + + # TODO: + # Suppress this, right now just for debug. + if jedi_matches and matches and self.debug: + yield Completion(start=start_offset, end=offset, text='--jedi/ipython--', + _origin='debug', type='none', signature='') + + # I'm unsure if this is always true, so let's assert and see if it + # crash + assert before.endswith(matched_text) + for m, t in zip(matches, matches_origin): + yield Completion(start=start_offset, end=offset, text=m, _origin=t, signature='', type='') + + + def complete(self, text=None, line_buffer=None, cursor_pos=None): + """Find completions for the given text and line context. + + Note that both the text and the line_buffer are optional, but at least + one of them must be given. + + Parameters + ---------- + text : string, optional + Text to perform the completion on. If not given, the line buffer + is split using the instance's CompletionSplitter object. + + line_buffer : string, optional + If not given, the completer attempts to obtain the current line + buffer via readline. This keyword allows clients which are + requesting for text completions in non-readline contexts to inform + the completer of the entire text. + + cursor_pos : int, optional + Index of the cursor in the full line buffer. Should be provided by + remote frontends where kernel has no access to frontend state. + + Returns + ------- + text : str + Text that was actually used in the completion. + + matches : list + A list of completion matches. + + + .. note:: + + This API is likely to be deprecated and replaced by + :any:`IPCompleter.completions` in the future. + + + """ + warnings.warn('`Completer.complete` is pending deprecation since ' + 'IPython 6.0 and will be replaced by `Completer.completions`.', + PendingDeprecationWarning) + # potential todo, FOLD the 3rd throw away argument of _complete + # into the first 2 one. + return self._complete(line_buffer=line_buffer, cursor_pos=cursor_pos, text=text, cursor_line=0)[:2] + + def _complete(self, *, cursor_line, cursor_pos, line_buffer=None, text=None, + full_text=None) -> Tuple[str, List[str], List[str], Iterable[_FakeJediCompletion]]: + """ + + Like complete but can also returns raw jedi completions as well as the + origin of the completion text. This could (and should) be made much + cleaner but that will be simpler once we drop the old (and stateful) + :any:`complete` API. + + + With current provisional API, cursor_pos act both (depending on the + caller) as the offset in the ``text`` or ``line_buffer``, or as the + ``column`` when passing multiline strings this could/should be renamed + but would add extra noise. + """ + + # if the cursor position isn't given, the only sane assumption we can + # make is that it's at the end of the line (the common case) + if cursor_pos is None: + cursor_pos = len(line_buffer) if text is None else len(text) + + if self.use_main_ns: + self.namespace = __main__.__dict__ + + # if text is either None or an empty string, rely on the line buffer + if (not line_buffer) and full_text: + line_buffer = full_text.split('\n')[cursor_line] + if not text: # issue #11508: check line_buffer before calling split_line + text = self.splitter.split_line(line_buffer, cursor_pos) if line_buffer else '' + + if self.backslash_combining_completions: + # allow deactivation of these on windows. + base_text = text if not line_buffer else line_buffer[:cursor_pos] + latex_text, latex_matches = self.latex_matches(base_text) + if latex_matches: + return latex_text, latex_matches, ['latex_matches']*len(latex_matches), () + name_text = '' + name_matches = [] + # need to add self.fwd_unicode_match() function here when done + for meth in (self.unicode_name_matches, back_latex_name_matches, back_unicode_name_matches, self.fwd_unicode_match): + name_text, name_matches = meth(base_text) + if name_text: + return name_text, name_matches[:MATCHES_LIMIT], \ + [meth.__qualname__]*min(len(name_matches), MATCHES_LIMIT), () + + + # If no line buffer is given, assume the input text is all there was + if line_buffer is None: + line_buffer = text + + self.line_buffer = line_buffer + self.text_until_cursor = self.line_buffer[:cursor_pos] + + # Do magic arg matches + for matcher in self.magic_arg_matchers: + matches = list(matcher(line_buffer))[:MATCHES_LIMIT] + if matches: + origins = [matcher.__qualname__] * len(matches) + return text, matches, origins, () + + # Start with a clean slate of completions + matches = [] + + # FIXME: we should extend our api to return a dict with completions for + # different types of objects. The rlcomplete() method could then + # simply collapse the dict into a list for readline, but we'd have + # richer completion semantics in other environments. + completions = () + if self.use_jedi: + if not full_text: + full_text = line_buffer + completions = self._jedi_matches( + cursor_pos, cursor_line, full_text) + + if self.merge_completions: + matches = [] + for matcher in self.matchers: + try: + matches.extend([(m, matcher.__qualname__) + for m in matcher(text)]) + except: + # Show the ugly traceback if the matcher causes an + # exception, but do NOT crash the kernel! + sys.excepthook(*sys.exc_info()) + else: + for matcher in self.matchers: + matches = [(m, matcher.__qualname__) + for m in matcher(text)] + if matches: + break + + seen = set() + filtered_matches = set() + for m in matches: + t, c = m + if t not in seen: + filtered_matches.add(m) + seen.add(t) + + _filtered_matches = sorted(filtered_matches, key=lambda x: completions_sorting_key(x[0])) + + custom_res = [(m, 'custom') for m in self.dispatch_custom_completer(text) or []] + + _filtered_matches = custom_res or _filtered_matches + + _filtered_matches = _filtered_matches[:MATCHES_LIMIT] + _matches = [m[0] for m in _filtered_matches] + origins = [m[1] for m in _filtered_matches] + + self.matches = _matches + + return text, _matches, origins, completions + + def fwd_unicode_match(self, text:str) -> Tuple[str, list]: + if self._names is None: + self._names = [] + for c in range(0,0x10FFFF + 1): + try: + self._names.append(unicodedata.name(chr(c))) + except ValueError: + pass + + slashpos = text.rfind('\\') + # if text starts with slash + if slashpos > -1: + s = text[slashpos+1:] + candidates = [x for x in self._names if x.startswith(s)] + if candidates: + return s, candidates + else: + return '', () + + # if text does not start with slash + else: + return u'', () diff --git a/.venv/lib/python3.8/site-packages/IPython/core/completerlib.py b/.venv/lib/python3.8/site-packages/IPython/core/completerlib.py new file mode 100644 index 00000000..7860cb67 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/IPython/core/completerlib.py @@ -0,0 +1,354 @@ +# encoding: utf-8 +"""Implementations for various useful completers. + +These are all loaded by default by IPython. +""" +#----------------------------------------------------------------------------- +# Copyright (C) 2010-2011 The IPython Development Team. +# +# Distributed under the terms of the BSD License. +# +# The full license is in the file COPYING.txt, distributed with this software. +#----------------------------------------------------------------------------- + +#----------------------------------------------------------------------------- +# Imports +#----------------------------------------------------------------------------- + +# Stdlib imports +import glob +import inspect +import os +import re +import sys +from importlib import import_module +from importlib.machinery import all_suffixes + + +# Third-party imports +from time import time +from zipimport import zipimporter + +# Our own imports +from .completer import expand_user, compress_user +from .error import TryNext +from ..utils._process_common import arg_split + +# FIXME: this should be pulled in with the right call via the component system +from IPython import get_ipython + +from typing import List + +#----------------------------------------------------------------------------- +# Globals and constants +#----------------------------------------------------------------------------- +_suffixes = all_suffixes() + +# Time in seconds after which the rootmodules will be stored permanently in the +# ipython ip.db database (kept in the user's .ipython dir). +TIMEOUT_STORAGE = 2 + +# Time in seconds after which we give up +TIMEOUT_GIVEUP = 20 + +# Regular expression for the python import statement +import_re = re.compile(r'(?P[^\W\d]\w*?)' + r'(?P[/\\]__init__)?' + r'(?P%s)$' % + r'|'.join(re.escape(s) for s in _suffixes)) + +# RE for the ipython %run command (python + ipython scripts) +magic_run_re = re.compile(r'.*(\.ipy|\.ipynb|\.py[w]?)$') + +#----------------------------------------------------------------------------- +# Local utilities +#----------------------------------------------------------------------------- + +def module_list(path): + """ + Return the list containing the names of the modules available in the given + folder. + """ + # sys.path has the cwd as an empty string, but isdir/listdir need it as '.' + if path == '': + path = '.' + + # A few local constants to be used in loops below + pjoin = os.path.join + + if os.path.isdir(path): + # Build a list of all files in the directory and all files + # in its subdirectories. For performance reasons, do not + # recurse more than one level into subdirectories. + files = [] + for root, dirs, nondirs in os.walk(path, followlinks=True): + subdir = root[len(path)+1:] + if subdir: + files.extend(pjoin(subdir, f) for f in nondirs) + dirs[:] = [] # Do not recurse into additional subdirectories. + else: + files.extend(nondirs) + + else: + try: + files = list(zipimporter(path)._files.keys()) + except: + files = [] + + # Build a list of modules which match the import_re regex. + modules = [] + for f in files: + m = import_re.match(f) + if m: + modules.append(m.group('name')) + return list(set(modules)) + + +def get_root_modules(): + """ + Returns a list containing the names of all the modules available in the + folders of the pythonpath. + + ip.db['rootmodules_cache'] maps sys.path entries to list of modules. + """ + ip = get_ipython() + if ip is None: + # No global shell instance to store cached list of modules. + # Don't try to scan for modules every time. + return list(sys.builtin_module_names) + + rootmodules_cache = ip.db.get('rootmodules_cache', {}) + rootmodules = list(sys.builtin_module_names) + start_time = time() + store = False + for path in sys.path: + try: + modules = rootmodules_cache[path] + except KeyError: + modules = module_list(path) + try: + modules.remove('__init__') + except ValueError: + pass + if path not in ('', '.'): # cwd modules should not be cached + rootmodules_cache[path] = modules + if time() - start_time > TIMEOUT_STORAGE and not store: + store = True + print("\nCaching the list of root modules, please wait!") + print("(This will only be done once - type '%rehashx' to " + "reset cache!)\n") + sys.stdout.flush() + if time() - start_time > TIMEOUT_GIVEUP: + print("This is taking too long, we give up.\n") + return [] + rootmodules.extend(modules) + if store: + ip.db['rootmodules_cache'] = rootmodules_cache + rootmodules = list(set(rootmodules)) + return rootmodules + + +def is_importable(module, attr, only_modules): + if only_modules: + return inspect.ismodule(getattr(module, attr)) + else: + return not(attr[:2] == '__' and attr[-2:] == '__') + + +def try_import(mod: str, only_modules=False) -> List[str]: + """ + Try to import given module and return list of potential completions. + """ + mod = mod.rstrip('.') + try: + m = import_module(mod) + except: + return [] + + m_is_init = '__init__' in (getattr(m, '__file__', '') or '') + + completions = [] + if (not hasattr(m, '__file__')) or (not only_modules) or m_is_init: + completions.extend( [attr for attr in dir(m) if + is_importable(m, attr, only_modules)]) + + completions.extend(getattr(m, '__all__', [])) + if m_is_init: + completions.extend(module_list(os.path.dirname(m.__file__))) + completions_set = {c for c in completions if isinstance(c, str)} + completions_set.discard('__init__') + return list(completions_set) + + +#----------------------------------------------------------------------------- +# Completion-related functions. +#----------------------------------------------------------------------------- + +def quick_completer(cmd, completions): + r""" Easily create a trivial completer for a command. + + Takes either a list of completions, or all completions in string (that will + be split on whitespace). + + Example:: + + [d:\ipython]|1> import ipy_completers + [d:\ipython]|2> ipy_completers.quick_completer('foo', ['bar','baz']) + [d:\ipython]|3> foo b + bar baz + [d:\ipython]|3> foo ba + """ + + if isinstance(completions, str): + completions = completions.split() + + def do_complete(self, event): + return completions + + get_ipython().set_hook('complete_command',do_complete, str_key = cmd) + +def module_completion(line): + """ + Returns a list containing the completion possibilities for an import line. + + The line looks like this : + 'import xml.d' + 'from xml.dom import' + """ + + words = line.split(' ') + nwords = len(words) + + # from whatever -> 'import ' + if nwords == 3 and words[0] == 'from': + return ['import '] + + # 'from xy' or 'import xy' + if nwords < 3 and (words[0] in {'%aimport', 'import', 'from'}) : + if nwords == 1: + return get_root_modules() + mod = words[1].split('.') + if len(mod) < 2: + return get_root_modules() + completion_list = try_import('.'.join(mod[:-1]), True) + return ['.'.join(mod[:-1] + [el]) for el in completion_list] + + # 'from xyz import abc' + if nwords >= 3 and words[0] == 'from': + mod = words[1] + return try_import(mod) + +#----------------------------------------------------------------------------- +# Completers +#----------------------------------------------------------------------------- +# These all have the func(self, event) signature to be used as custom +# completers + +def module_completer(self,event): + """Give completions after user has typed 'import ...' or 'from ...'""" + + # This works in all versions of python. While 2.5 has + # pkgutil.walk_packages(), that particular routine is fairly dangerous, + # since it imports *EVERYTHING* on sys.path. That is: a) very slow b) full + # of possibly problematic side effects. + # This search the folders in the sys.path for available modules. + + return module_completion(event.line) + +# FIXME: there's a lot of logic common to the run, cd and builtin file +# completers, that is currently reimplemented in each. + +def magic_run_completer(self, event): + """Complete files that end in .py or .ipy or .ipynb for the %run command. + """ + comps = arg_split(event.line, strict=False) + # relpath should be the current token that we need to complete. + if (len(comps) > 1) and (not event.line.endswith(' ')): + relpath = comps[-1].strip("'\"") + else: + relpath = '' + + #print("\nev=", event) # dbg + #print("rp=", relpath) # dbg + #print('comps=', comps) # dbg + + lglob = glob.glob + isdir = os.path.isdir + relpath, tilde_expand, tilde_val = expand_user(relpath) + + # Find if the user has already typed the first filename, after which we + # should complete on all files, since after the first one other files may + # be arguments to the input script. + + if any(magic_run_re.match(c) for c in comps): + matches = [f.replace('\\','/') + ('/' if isdir(f) else '') + for f in lglob(relpath+'*')] + else: + dirs = [f.replace('\\','/') + "/" for f in lglob(relpath+'*') if isdir(f)] + pys = [f.replace('\\','/') + for f in lglob(relpath+'*.py') + lglob(relpath+'*.ipy') + + lglob(relpath+'*.ipynb') + lglob(relpath + '*.pyw')] + + matches = dirs + pys + + #print('run comp:', dirs+pys) # dbg + return [compress_user(p, tilde_expand, tilde_val) for p in matches] + + +def cd_completer(self, event): + """Completer function for cd, which only returns directories.""" + ip = get_ipython() + relpath = event.symbol + + #print(event) # dbg + if event.line.endswith('-b') or ' -b ' in event.line: + # return only bookmark completions + bkms = self.db.get('bookmarks', None) + if bkms: + return bkms.keys() + else: + return [] + + if event.symbol == '-': + width_dh = str(len(str(len(ip.user_ns['_dh']) + 1))) + # jump in directory history by number + fmt = '-%0' + width_dh +'d [%s]' + ents = [ fmt % (i,s) for i,s in enumerate(ip.user_ns['_dh'])] + if len(ents) > 1: + return ents + return [] + + if event.symbol.startswith('--'): + return ["--" + os.path.basename(d) for d in ip.user_ns['_dh']] + + # Expand ~ in path and normalize directory separators. + relpath, tilde_expand, tilde_val = expand_user(relpath) + relpath = relpath.replace('\\','/') + + found = [] + for d in [f.replace('\\','/') + '/' for f in glob.glob(relpath+'*') + if os.path.isdir(f)]: + if ' ' in d: + # we don't want to deal with any of that, complex code + # for this is elsewhere + raise TryNext + + found.append(d) + + if not found: + if os.path.isdir(relpath): + return [compress_user(relpath, tilde_expand, tilde_val)] + + # if no completions so far, try bookmarks + bks = self.db.get('bookmarks',{}) + bkmatches = [s for s in bks if s.startswith(event.symbol)] + if bkmatches: + return bkmatches + + raise TryNext + + return [compress_user(p, tilde_expand, tilde_val) for p in found] + +def reset_completer(self, event): + "A completer for %reset magic" + return '-f -s in out array dhist'.split() diff --git a/.venv/lib/python3.8/site-packages/IPython/core/crashhandler.py b/.venv/lib/python3.8/site-packages/IPython/core/crashhandler.py new file mode 100644 index 00000000..1e0b429d --- /dev/null +++ b/.venv/lib/python3.8/site-packages/IPython/core/crashhandler.py @@ -0,0 +1,228 @@ +# encoding: utf-8 +"""sys.excepthook for IPython itself, leaves a detailed report on disk. + +Authors: + +* Fernando Perez +* Brian E. Granger +""" + +#----------------------------------------------------------------------------- +# Copyright (C) 2001-2007 Fernando Perez. +# Copyright (C) 2008-2011 The IPython Development Team +# +# Distributed under the terms of the BSD License. The full license is in +# the file COPYING, distributed as part of this software. +#----------------------------------------------------------------------------- + +#----------------------------------------------------------------------------- +# Imports +#----------------------------------------------------------------------------- + +import os +import sys +import traceback +from pprint import pformat + +from IPython.core import ultratb +from IPython.core.release import author_email +from IPython.utils.sysinfo import sys_info +from IPython.utils.py3compat import input + +from IPython.core.release import __version__ as version + +#----------------------------------------------------------------------------- +# Code +#----------------------------------------------------------------------------- + +# Template for the user message. +_default_message_template = """\ +Oops, {app_name} crashed. We do our best to make it stable, but... + +A crash report was automatically generated with the following information: + - A verbatim copy of the crash traceback. + - A copy of your input history during this session. + - Data on your current {app_name} configuration. + +It was left in the file named: +\t'{crash_report_fname}' +If you can email this file to the developers, the information in it will help +them in understanding and correcting the problem. + +You can mail it to: {contact_name} at {contact_email} +with the subject '{app_name} Crash Report'. + +If you want to do it now, the following command will work (under Unix): +mail -s '{app_name} Crash Report' {contact_email} < {crash_report_fname} + +In your email, please also include information about: +- The operating system under which the crash happened: Linux, macOS, Windows, + other, and which exact version (for example: Ubuntu 16.04.3, macOS 10.13.2, + Windows 10 Pro), and whether it is 32-bit or 64-bit; +- How {app_name} was installed: using pip or conda, from GitHub, as part of + a Docker container, or other, providing more detail if possible; +- How to reproduce the crash: what exact sequence of instructions can one + input to get the same crash? Ideally, find a minimal yet complete sequence + of instructions that yields the crash. + +To ensure accurate tracking of this issue, please file a report about it at: +{bug_tracker} +""" + +_lite_message_template = """ +If you suspect this is an IPython {version} bug, please report it at: + https://github.com/ipython/ipython/issues +or send an email to the mailing list at {email} + +You can print a more detailed traceback right now with "%tb", or use "%debug" +to interactively debug it. + +Extra-detailed tracebacks for bug-reporting purposes can be enabled via: + {config}Application.verbose_crash=True +""" + + +class CrashHandler(object): + """Customizable crash handlers for IPython applications. + + Instances of this class provide a :meth:`__call__` method which can be + used as a ``sys.excepthook``. The :meth:`__call__` signature is:: + + def __call__(self, etype, evalue, etb) + """ + + message_template = _default_message_template + section_sep = '\n\n'+'*'*75+'\n\n' + + def __init__(self, app, contact_name=None, contact_email=None, + bug_tracker=None, show_crash_traceback=True, call_pdb=False): + """Create a new crash handler + + Parameters + ---------- + app : Application + A running :class:`Application` instance, which will be queried at + crash time for internal information. + + contact_name : str + A string with the name of the person to contact. + + contact_email : str + A string with the email address of the contact. + + bug_tracker : str + A string with the URL for your project's bug tracker. + + show_crash_traceback : bool + If false, don't print the crash traceback on stderr, only generate + the on-disk report + + Non-argument instance attributes: + + These instances contain some non-argument attributes which allow for + further customization of the crash handler's behavior. Please see the + source for further details. + """ + self.crash_report_fname = "Crash_report_%s.txt" % app.name + self.app = app + self.call_pdb = call_pdb + #self.call_pdb = True # dbg + self.show_crash_traceback = show_crash_traceback + self.info = dict(app_name = app.name, + contact_name = contact_name, + contact_email = contact_email, + bug_tracker = bug_tracker, + crash_report_fname = self.crash_report_fname) + + + def __call__(self, etype, evalue, etb): + """Handle an exception, call for compatible with sys.excepthook""" + + # do not allow the crash handler to be called twice without reinstalling it + # this prevents unlikely errors in the crash handling from entering an + # infinite loop. + sys.excepthook = sys.__excepthook__ + + # Report tracebacks shouldn't use color in general (safer for users) + color_scheme = 'NoColor' + + # Use this ONLY for developer debugging (keep commented out for release) + #color_scheme = 'Linux' # dbg + try: + rptdir = self.app.ipython_dir + except: + rptdir = os.getcwd() + if rptdir is None or not os.path.isdir(rptdir): + rptdir = os.getcwd() + report_name = os.path.join(rptdir,self.crash_report_fname) + # write the report filename into the instance dict so it can get + # properly expanded out in the user message template + self.crash_report_fname = report_name + self.info['crash_report_fname'] = report_name + TBhandler = ultratb.VerboseTB( + color_scheme=color_scheme, + long_header=1, + call_pdb=self.call_pdb, + ) + if self.call_pdb: + TBhandler(etype,evalue,etb) + return + else: + traceback = TBhandler.text(etype,evalue,etb,context=31) + + # print traceback to screen + if self.show_crash_traceback: + print(traceback, file=sys.stderr) + + # and generate a complete report on disk + try: + report = open(report_name,'w') + except: + print('Could not create crash report on disk.', file=sys.stderr) + return + + with report: + # Inform user on stderr of what happened + print('\n'+'*'*70+'\n', file=sys.stderr) + print(self.message_template.format(**self.info), file=sys.stderr) + + # Construct report on disk + report.write(self.make_report(traceback)) + + input("Hit to quit (your terminal may close):") + + def make_report(self,traceback): + """Return a string containing a crash report.""" + + sec_sep = self.section_sep + + report = ['*'*75+'\n\n'+'IPython post-mortem report\n\n'] + rpt_add = report.append + rpt_add(sys_info()) + + try: + config = pformat(self.app.config) + rpt_add(sec_sep) + rpt_add('Application name: %s\n\n' % self.app_name) + rpt_add('Current user configuration structure:\n\n') + rpt_add(config) + except: + pass + rpt_add(sec_sep+'Crash traceback:\n\n' + traceback) + + return ''.join(report) + + +def crash_handler_lite(etype, evalue, tb): + """a light excepthook, adding a small message to the usual traceback""" + traceback.print_exception(etype, evalue, tb) + + from IPython.core.interactiveshell import InteractiveShell + if InteractiveShell.initialized(): + # we are in a Shell environment, give %magic example + config = "%config " + else: + # we are not in a shell, show generic config + config = "c." + print(_lite_message_template.format(email=author_email, config=config, version=version), file=sys.stderr) + diff --git a/.venv/lib/python3.8/site-packages/IPython/core/debugger.py b/.venv/lib/python3.8/site-packages/IPython/core/debugger.py new file mode 100644 index 00000000..ff838562 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/IPython/core/debugger.py @@ -0,0 +1,833 @@ +# -*- coding: utf-8 -*- +""" +Pdb debugger class. + +Modified from the standard pdb.Pdb class to avoid including readline, so that +the command line completion of other programs which include this isn't +damaged. + +In the future, this class will be expanded with improvements over the standard +pdb. + +The code in this file is mainly lifted out of cmd.py in Python 2.2, with minor +changes. Licensing should therefore be under the standard Python terms. For +details on the PSF (Python Software Foundation) standard license, see: + +https://docs.python.org/2/license.html +""" + +#***************************************************************************** +# +# This file is licensed under the PSF license. +# +# Copyright (C) 2001 Python Software Foundation, www.python.org +# Copyright (C) 2005-2006 Fernando Perez. +# +# +#***************************************************************************** + +import bdb +import functools +import inspect +import linecache +import sys +import warnings +import re + +from IPython import get_ipython +from IPython.utils import PyColorize +from IPython.utils import coloransi, py3compat +from IPython.core.excolors import exception_colors +from IPython.testing.skipdoctest import skip_doctest + + +prompt = 'ipdb> ' + +#We have to check this directly from sys.argv, config struct not yet available +from pdb import Pdb as OldPdb + +# Allow the set_trace code to operate outside of an ipython instance, even if +# it does so with some limitations. The rest of this support is implemented in +# the Tracer constructor. + +def make_arrow(pad): + """generate the leading arrow in front of traceback or debugger""" + if pad >= 2: + return '-'*(pad-2) + '> ' + elif pad == 1: + return '>' + return '' + + +def BdbQuit_excepthook(et, ev, tb, excepthook=None): + """Exception hook which handles `BdbQuit` exceptions. + + All other exceptions are processed using the `excepthook` + parameter. + """ + warnings.warn("`BdbQuit_excepthook` is deprecated since version 5.1", + DeprecationWarning, stacklevel=2) + if et==bdb.BdbQuit: + print('Exiting Debugger.') + elif excepthook is not None: + excepthook(et, ev, tb) + else: + # Backwards compatibility. Raise deprecation warning? + BdbQuit_excepthook.excepthook_ori(et,ev,tb) + + +def BdbQuit_IPython_excepthook(self,et,ev,tb,tb_offset=None): + warnings.warn( + "`BdbQuit_IPython_excepthook` is deprecated since version 5.1", + DeprecationWarning, stacklevel=2) + print('Exiting Debugger.') + + +class Tracer(object): + """ + DEPRECATED + + Class for local debugging, similar to pdb.set_trace. + + Instances of this class, when called, behave like pdb.set_trace, but + providing IPython's enhanced capabilities. + + This is implemented as a class which must be initialized in your own code + and not as a standalone function because we need to detect at runtime + whether IPython is already active or not. That detection is done in the + constructor, ensuring that this code plays nicely with a running IPython, + while functioning acceptably (though with limitations) if outside of it. + """ + + @skip_doctest + def __init__(self, colors=None): + """ + DEPRECATED + + Create a local debugger instance. + + Parameters + ---------- + + colors : str, optional + The name of the color scheme to use, it must be one of IPython's + valid color schemes. If not given, the function will default to + the current IPython scheme when running inside IPython, and to + 'NoColor' otherwise. + + Examples + -------- + :: + + from IPython.core.debugger import Tracer; debug_here = Tracer() + + Later in your code:: + + debug_here() # -> will open up the debugger at that point. + + Once the debugger activates, you can use all of its regular commands to + step through code, set breakpoints, etc. See the pdb documentation + from the Python standard library for usage details. + """ + warnings.warn("`Tracer` is deprecated since version 5.1, directly use " + "`IPython.core.debugger.Pdb.set_trace()`", + DeprecationWarning, stacklevel=2) + + ip = get_ipython() + if ip is None: + # Outside of ipython, we set our own exception hook manually + sys.excepthook = functools.partial(BdbQuit_excepthook, + excepthook=sys.excepthook) + def_colors = 'NoColor' + else: + # In ipython, we use its custom exception handler mechanism + def_colors = ip.colors + ip.set_custom_exc((bdb.BdbQuit,), BdbQuit_IPython_excepthook) + + if colors is None: + colors = def_colors + + # The stdlib debugger internally uses a modified repr from the `repr` + # module, that limits the length of printed strings to a hardcoded + # limit of 30 characters. That much trimming is too aggressive, let's + # at least raise that limit to 80 chars, which should be enough for + # most interactive uses. + try: + from reprlib import aRepr + aRepr.maxstring = 80 + except: + # This is only a user-facing convenience, so any error we encounter + # here can be warned about but can be otherwise ignored. These + # printouts will tell us about problems if this API changes + import traceback + traceback.print_exc() + + self.debugger = Pdb(colors) + + def __call__(self): + """Starts an interactive debugger at the point where called. + + This is similar to the pdb.set_trace() function from the std lib, but + using IPython's enhanced debugger.""" + + self.debugger.set_trace(sys._getframe().f_back) + + +RGX_EXTRA_INDENT = re.compile(r'(?<=\n)\s+') + + +def strip_indentation(multiline_string): + return RGX_EXTRA_INDENT.sub('', multiline_string) + + +def decorate_fn_with_doc(new_fn, old_fn, additional_text=""): + """Make new_fn have old_fn's doc string. This is particularly useful + for the ``do_...`` commands that hook into the help system. + Adapted from from a comp.lang.python posting + by Duncan Booth.""" + def wrapper(*args, **kw): + return new_fn(*args, **kw) + if old_fn.__doc__: + wrapper.__doc__ = strip_indentation(old_fn.__doc__) + additional_text + return wrapper + + +class Pdb(OldPdb): + """Modified Pdb class, does not load readline. + + for a standalone version that uses prompt_toolkit, see + `IPython.terminal.debugger.TerminalPdb` and + `IPython.terminal.debugger.set_trace()` + """ + + def __init__(self, color_scheme=None, completekey=None, + stdin=None, stdout=None, context=5, **kwargs): + """Create a new IPython debugger. + + :param color_scheme: Deprecated, do not use. + :param completekey: Passed to pdb.Pdb. + :param stdin: Passed to pdb.Pdb. + :param stdout: Passed to pdb.Pdb. + :param context: Number of lines of source code context to show when + displaying stacktrace information. + :param kwargs: Passed to pdb.Pdb. + The possibilities are python version dependent, see the python + docs for more info. + """ + + # Parent constructor: + try: + self.context = int(context) + if self.context <= 0: + raise ValueError("Context must be a positive integer") + except (TypeError, ValueError): + raise ValueError("Context must be a positive integer") + + # `kwargs` ensures full compatibility with stdlib's `pdb.Pdb`. + OldPdb.__init__(self, completekey, stdin, stdout, **kwargs) + + # IPython changes... + self.shell = get_ipython() + + if self.shell is None: + save_main = sys.modules['__main__'] + # No IPython instance running, we must create one + from IPython.terminal.interactiveshell import \ + TerminalInteractiveShell + self.shell = TerminalInteractiveShell.instance() + # needed by any code which calls __import__("__main__") after + # the debugger was entered. See also #9941. + sys.modules['__main__'] = save_main + + if color_scheme is not None: + warnings.warn( + "The `color_scheme` argument is deprecated since version 5.1", + DeprecationWarning, stacklevel=2) + else: + color_scheme = self.shell.colors + + self.aliases = {} + + # Create color table: we copy the default one from the traceback + # module and add a few attributes needed for debugging + self.color_scheme_table = exception_colors() + + # shorthands + C = coloransi.TermColors + cst = self.color_scheme_table + + cst['NoColor'].colors.prompt = C.NoColor + cst['NoColor'].colors.breakpoint_enabled = C.NoColor + cst['NoColor'].colors.breakpoint_disabled = C.NoColor + + cst['Linux'].colors.prompt = C.Green + cst['Linux'].colors.breakpoint_enabled = C.LightRed + cst['Linux'].colors.breakpoint_disabled = C.Red + + cst['LightBG'].colors.prompt = C.Blue + cst['LightBG'].colors.breakpoint_enabled = C.LightRed + cst['LightBG'].colors.breakpoint_disabled = C.Red + + cst['Neutral'].colors.prompt = C.Blue + cst['Neutral'].colors.breakpoint_enabled = C.LightRed + cst['Neutral'].colors.breakpoint_disabled = C.Red + + + # Add a python parser so we can syntax highlight source while + # debugging. + self.parser = PyColorize.Parser(style=color_scheme) + self.set_colors(color_scheme) + + # Set the prompt - the default prompt is '(Pdb)' + self.prompt = prompt + self.skip_hidden = True + + def set_colors(self, scheme): + """Shorthand access to the color table scheme selector method.""" + self.color_scheme_table.set_active_scheme(scheme) + self.parser.style = scheme + + def set_trace(self, frame=None): + if frame is None: + frame = sys._getframe().f_back + self.initial_frame = frame + return super().set_trace(frame) + + def hidden_frames(self, stack): + """ + Given an index in the stack return wether it should be skipped. + + This is used in up/down and where to skip frames. + """ + # The f_locals dictionary is updated from the actual frame + # locals whenever the .f_locals accessor is called, so we + # avoid calling it here to preserve self.curframe_locals. + # Futhermore, there is no good reason to hide the current frame. + ip_hide = [ + False + if s[0] in (self.curframe, getattr(self, "initial_frame", None)) + else s[0].f_locals.get("__tracebackhide__", False) + for s in stack + ] + ip_start = [i for i, s in enumerate(ip_hide) if s == "__ipython_bottom__"] + if ip_start: + ip_hide = [h if i > ip_start[0] else True for (i, h) in enumerate(ip_hide)] + return ip_hide + + def interaction(self, frame, traceback): + try: + OldPdb.interaction(self, frame, traceback) + except KeyboardInterrupt: + self.stdout.write("\n" + self.shell.get_exception_only()) + + def new_do_frame(self, arg): + OldPdb.do_frame(self, arg) + + def new_do_quit(self, arg): + + if hasattr(self, 'old_all_completions'): + self.shell.Completer.all_completions=self.old_all_completions + + return OldPdb.do_quit(self, arg) + + do_q = do_quit = decorate_fn_with_doc(new_do_quit, OldPdb.do_quit) + + def new_do_restart(self, arg): + """Restart command. In the context of ipython this is exactly the same + thing as 'quit'.""" + self.msg("Restart doesn't make sense here. Using 'quit' instead.") + return self.do_quit(arg) + + def print_stack_trace(self, context=None): + Colors = self.color_scheme_table.active_colors + ColorsNormal = Colors.Normal + if context is None: + context = self.context + try: + context=int(context) + if context <= 0: + raise ValueError("Context must be a positive integer") + except (TypeError, ValueError): + raise ValueError("Context must be a positive integer") + try: + skipped = 0 + for hidden, frame_lineno in zip(self.hidden_frames(self.stack), self.stack): + if hidden and self.skip_hidden: + skipped += 1 + continue + if skipped: + print( + f"{Colors.excName} [... skipping {skipped} hidden frame(s)]{ColorsNormal}\n" + ) + skipped = 0 + self.print_stack_entry(frame_lineno, context=context) + if skipped: + print( + f"{Colors.excName} [... skipping {skipped} hidden frame(s)]{ColorsNormal}\n" + ) + except KeyboardInterrupt: + pass + + def print_stack_entry(self, frame_lineno, prompt_prefix='\n-> ', + context=None): + if context is None: + context = self.context + try: + context=int(context) + if context <= 0: + raise ValueError("Context must be a positive integer") + except (TypeError, ValueError): + raise ValueError("Context must be a positive integer") + print(self.format_stack_entry(frame_lineno, '', context), file=self.stdout) + + # vds: >> + frame, lineno = frame_lineno + filename = frame.f_code.co_filename + self.shell.hooks.synchronize_with_editor(filename, lineno, 0) + # vds: << + + def format_stack_entry(self, frame_lineno, lprefix=': ', context=None): + if context is None: + context = self.context + try: + context=int(context) + if context <= 0: + print("Context must be a positive integer", file=self.stdout) + except (TypeError, ValueError): + print("Context must be a positive integer", file=self.stdout) + try: + import reprlib # Py 3 + except ImportError: + import repr as reprlib # Py 2 + + ret = [] + + Colors = self.color_scheme_table.active_colors + ColorsNormal = Colors.Normal + tpl_link = u'%s%%s%s' % (Colors.filenameEm, ColorsNormal) + tpl_call = u'%s%%s%s%%s%s' % (Colors.vName, Colors.valEm, ColorsNormal) + tpl_line = u'%%s%s%%s %s%%s' % (Colors.lineno, ColorsNormal) + tpl_line_em = u'%%s%s%%s %s%%s%s' % (Colors.linenoEm, Colors.line, + ColorsNormal) + + frame, lineno = frame_lineno + + return_value = '' + if '__return__' in frame.f_locals: + rv = frame.f_locals['__return__'] + #return_value += '->' + return_value += reprlib.repr(rv) + '\n' + ret.append(return_value) + + #s = filename + '(' + `lineno` + ')' + filename = self.canonic(frame.f_code.co_filename) + link = tpl_link % py3compat.cast_unicode(filename) + + if frame.f_code.co_name: + func = frame.f_code.co_name + else: + func = "" + + call = '' + if func != '?': + if '__args__' in frame.f_locals: + args = reprlib.repr(frame.f_locals['__args__']) + else: + args = '()' + call = tpl_call % (func, args) + + # The level info should be generated in the same format pdb uses, to + # avoid breaking the pdbtrack functionality of python-mode in *emacs. + if frame is self.curframe: + ret.append('> ') + else: + ret.append(' ') + ret.append(u'%s(%s)%s\n' % (link,lineno,call)) + + start = lineno - 1 - context//2 + lines = linecache.getlines(filename) + start = min(start, len(lines) - context) + start = max(start, 0) + lines = lines[start : start + context] + + for i,line in enumerate(lines): + show_arrow = (start + 1 + i == lineno) + linetpl = (frame is self.curframe or show_arrow) \ + and tpl_line_em \ + or tpl_line + ret.append(self.__format_line(linetpl, filename, + start + 1 + i, line, + arrow = show_arrow) ) + return ''.join(ret) + + def __format_line(self, tpl_line, filename, lineno, line, arrow = False): + bp_mark = "" + bp_mark_color = "" + + new_line, err = self.parser.format2(line, 'str') + if not err: + line = new_line + + bp = None + if lineno in self.get_file_breaks(filename): + bps = self.get_breaks(filename, lineno) + bp = bps[-1] + + if bp: + Colors = self.color_scheme_table.active_colors + bp_mark = str(bp.number) + bp_mark_color = Colors.breakpoint_enabled + if not bp.enabled: + bp_mark_color = Colors.breakpoint_disabled + + numbers_width = 7 + if arrow: + # This is the line with the error + pad = numbers_width - len(str(lineno)) - len(bp_mark) + num = '%s%s' % (make_arrow(pad), str(lineno)) + else: + num = '%*s' % (numbers_width - len(bp_mark), str(lineno)) + + return tpl_line % (bp_mark_color + bp_mark, num, line) + + + def print_list_lines(self, filename, first, last): + """The printing (as opposed to the parsing part of a 'list' + command.""" + try: + Colors = self.color_scheme_table.active_colors + ColorsNormal = Colors.Normal + tpl_line = '%%s%s%%s %s%%s' % (Colors.lineno, ColorsNormal) + tpl_line_em = '%%s%s%%s %s%%s%s' % (Colors.linenoEm, Colors.line, ColorsNormal) + src = [] + if filename == "" and hasattr(self, "_exec_filename"): + filename = self._exec_filename + + for lineno in range(first, last+1): + line = linecache.getline(filename, lineno) + if not line: + break + + if lineno == self.curframe.f_lineno: + line = self.__format_line(tpl_line_em, filename, lineno, line, arrow = True) + else: + line = self.__format_line(tpl_line, filename, lineno, line, arrow = False) + + src.append(line) + self.lineno = lineno + + print(''.join(src), file=self.stdout) + + except KeyboardInterrupt: + pass + + def do_skip_hidden(self, arg): + """ + Change whether or not we should skip frames with the + __tracebackhide__ attribute. + """ + if arg.strip().lower() in ("true", "yes"): + self.skip_hidden = True + elif arg.strip().lower() in ("false", "no"): + self.skip_hidden = False + + def do_list(self, arg): + """Print lines of code from the current stack frame + """ + self.lastcmd = 'list' + last = None + if arg: + try: + x = eval(arg, {}, {}) + if type(x) == type(()): + first, last = x + first = int(first) + last = int(last) + if last < first: + # Assume it's a count + last = first + last + else: + first = max(1, int(x) - 5) + except: + print('*** Error in argument:', repr(arg), file=self.stdout) + return + elif self.lineno is None: + first = max(1, self.curframe.f_lineno - 5) + else: + first = self.lineno + 1 + if last is None: + last = first + 10 + self.print_list_lines(self.curframe.f_code.co_filename, first, last) + + # vds: >> + lineno = first + filename = self.curframe.f_code.co_filename + self.shell.hooks.synchronize_with_editor(filename, lineno, 0) + # vds: << + + do_l = do_list + + def getsourcelines(self, obj): + lines, lineno = inspect.findsource(obj) + if inspect.isframe(obj) and obj.f_globals is obj.f_locals: + # must be a module frame: do not try to cut a block out of it + return lines, 1 + elif inspect.ismodule(obj): + return lines, 1 + return inspect.getblock(lines[lineno:]), lineno+1 + + def do_longlist(self, arg): + """Print lines of code from the current stack frame. + + Shows more lines than 'list' does. + """ + self.lastcmd = 'longlist' + try: + lines, lineno = self.getsourcelines(self.curframe) + except OSError as err: + self.error(err) + return + last = lineno + len(lines) + self.print_list_lines(self.curframe.f_code.co_filename, lineno, last) + do_ll = do_longlist + + def do_debug(self, arg): + """debug code + Enter a recursive debugger that steps through the code + argument (which is an arbitrary expression or statement to be + executed in the current environment). + """ + trace_function = sys.gettrace() + sys.settrace(None) + globals = self.curframe.f_globals + locals = self.curframe_locals + p = self.__class__(completekey=self.completekey, + stdin=self.stdin, stdout=self.stdout) + p.use_rawinput = self.use_rawinput + p.prompt = "(%s) " % self.prompt.strip() + self.message("ENTERING RECURSIVE DEBUGGER") + sys.call_tracing(p.run, (arg, globals, locals)) + self.message("LEAVING RECURSIVE DEBUGGER") + sys.settrace(trace_function) + self.lastcmd = p.lastcmd + + def do_pdef(self, arg): + """Print the call signature for any callable object. + + The debugger interface to %pdef""" + namespaces = [ + ("Locals", self.curframe_locals), + ("Globals", self.curframe.f_globals), + ] + self.shell.find_line_magic("pdef")(arg, namespaces=namespaces) + + def do_pdoc(self, arg): + """Print the docstring for an object. + + The debugger interface to %pdoc.""" + namespaces = [ + ("Locals", self.curframe_locals), + ("Globals", self.curframe.f_globals), + ] + self.shell.find_line_magic("pdoc")(arg, namespaces=namespaces) + + def do_pfile(self, arg): + """Print (or run through pager) the file where an object is defined. + + The debugger interface to %pfile. + """ + namespaces = [ + ("Locals", self.curframe_locals), + ("Globals", self.curframe.f_globals), + ] + self.shell.find_line_magic("pfile")(arg, namespaces=namespaces) + + def do_pinfo(self, arg): + """Provide detailed information about an object. + + The debugger interface to %pinfo, i.e., obj?.""" + namespaces = [ + ("Locals", self.curframe_locals), + ("Globals", self.curframe.f_globals), + ] + self.shell.find_line_magic("pinfo")(arg, namespaces=namespaces) + + def do_pinfo2(self, arg): + """Provide extra detailed information about an object. + + The debugger interface to %pinfo2, i.e., obj??.""" + namespaces = [ + ("Locals", self.curframe_locals), + ("Globals", self.curframe.f_globals), + ] + self.shell.find_line_magic("pinfo2")(arg, namespaces=namespaces) + + def do_psource(self, arg): + """Print (or run through pager) the source code for an object.""" + namespaces = [ + ("Locals", self.curframe_locals), + ("Globals", self.curframe.f_globals), + ] + self.shell.find_line_magic("psource")(arg, namespaces=namespaces) + + def do_where(self, arg): + """w(here) + Print a stack trace, with the most recent frame at the bottom. + An arrow indicates the "current frame", which determines the + context of most commands. 'bt' is an alias for this command. + + Take a number as argument as an (optional) number of context line to + print""" + if arg: + try: + context = int(arg) + except ValueError as err: + self.error(err) + return + self.print_stack_trace(context) + else: + self.print_stack_trace() + + do_w = do_where + + def stop_here(self, frame): + """Check if pdb should stop here""" + if not super().stop_here(frame): + return False + if self.skip_hidden and frame.f_locals.get("__tracebackhide__", False): + if self._wait_for_mainpyfile: + return False + Colors = self.color_scheme_table.active_colors + ColorsNormal = Colors.Normal + print(f"{Colors.excName} [... skipped 1 hidden frame]{ColorsNormal}\n") + return False + return True + + def do_up(self, arg): + """u(p) [count] + Move the current frame count (default one) levels up in the + stack trace (to an older frame). + + Will skip hidden frames. + """ + ## modified version of upstream that skips + # frames with __tracebackide__ + if self.curindex == 0: + self.error("Oldest frame") + return + try: + count = int(arg or 1) + except ValueError: + self.error("Invalid frame count (%s)" % arg) + return + skipped = 0 + if count < 0: + _newframe = 0 + else: + _newindex = self.curindex + counter = 0 + hidden_frames = self.hidden_frames(self.stack) + for i in range(self.curindex - 1, -1, -1): + frame = self.stack[i][0] + if hidden_frames[i] and self.skip_hidden: + skipped += 1 + continue + counter += 1 + if counter >= count: + break + else: + # if no break occured. + self.error("all frames above hidden") + return + + Colors = self.color_scheme_table.active_colors + ColorsNormal = Colors.Normal + _newframe = i + self._select_frame(_newframe) + if skipped: + print( + f"{Colors.excName} [... skipped {skipped} hidden frame(s)]{ColorsNormal}\n" + ) + + def do_down(self, arg): + """d(own) [count] + Move the current frame count (default one) levels down in the + stack trace (to a newer frame). + + Will skip hidden frames. + """ + if self.curindex + 1 == len(self.stack): + self.error("Newest frame") + return + try: + count = int(arg or 1) + except ValueError: + self.error("Invalid frame count (%s)" % arg) + return + if count < 0: + _newframe = len(self.stack) - 1 + else: + _newindex = self.curindex + counter = 0 + skipped = 0 + hidden_frames = self.hidden_frames(self.stack) + for i in range(self.curindex + 1, len(self.stack)): + frame = self.stack[i][0] + if hidden_frames[i] and self.skip_hidden: + skipped += 1 + continue + counter += 1 + if counter >= count: + break + else: + self.error("all frames bellow hidden") + return + + Colors = self.color_scheme_table.active_colors + ColorsNormal = Colors.Normal + if skipped: + print( + f"{Colors.excName} [... skipped {skipped} hidden frame(s)]{ColorsNormal}\n" + ) + _newframe = i + + self._select_frame(_newframe) + + do_d = do_down + do_u = do_up + +class InterruptiblePdb(Pdb): + """Version of debugger where KeyboardInterrupt exits the debugger altogether.""" + + def cmdloop(self): + """Wrap cmdloop() such that KeyboardInterrupt stops the debugger.""" + try: + return OldPdb.cmdloop(self) + except KeyboardInterrupt: + self.stop_here = lambda frame: False + self.do_quit("") + sys.settrace(None) + self.quitting = False + raise + + def _cmdloop(self): + while True: + try: + # keyboard interrupts allow for an easy way to cancel + # the current command, so allow them during interactive input + self.allow_kbdint = True + self.cmdloop() + self.allow_kbdint = False + break + except KeyboardInterrupt: + self.message('--KeyboardInterrupt--') + raise + + +def set_trace(frame=None): + """ + Start debugging from `frame`. + + If frame is not specified, debugging starts from caller's frame. + """ + Pdb().set_trace(frame or sys._getframe().f_back) diff --git a/.venv/lib/python3.8/site-packages/IPython/core/display.py b/.venv/lib/python3.8/site-packages/IPython/core/display.py new file mode 100644 index 00000000..424414a6 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/IPython/core/display.py @@ -0,0 +1,1527 @@ +# -*- coding: utf-8 -*- +"""Top-level display functions for displaying object in different formats.""" + +# Copyright (c) IPython Development Team. +# Distributed under the terms of the Modified BSD License. + + +from binascii import b2a_hex, b2a_base64, hexlify +import json +import mimetypes +import os +import struct +import sys +import warnings +from copy import deepcopy +from os.path import splitext +from pathlib import Path, PurePath + +from IPython.utils.py3compat import cast_unicode +from IPython.testing.skipdoctest import skip_doctest + +__all__ = ['display', 'display_pretty', 'display_html', 'display_markdown', +'display_svg', 'display_png', 'display_jpeg', 'display_latex', 'display_json', +'display_javascript', 'display_pdf', 'DisplayObject', 'TextDisplayObject', +'Pretty', 'HTML', 'Markdown', 'Math', 'Latex', 'SVG', 'ProgressBar', 'JSON', +'GeoJSON', 'Javascript', 'Image', 'clear_output', 'set_matplotlib_formats', +'set_matplotlib_close', 'publish_display_data', 'update_display', 'DisplayHandle', +'Video'] + +#----------------------------------------------------------------------------- +# utility functions +#----------------------------------------------------------------------------- + +def _safe_exists(path): + """Check path, but don't let exceptions raise""" + try: + return os.path.exists(path) + except Exception: + return False + +def _merge(d1, d2): + """Like update, but merges sub-dicts instead of clobbering at the top level. + + Updates d1 in-place + """ + + if not isinstance(d2, dict) or not isinstance(d1, dict): + return d2 + for key, value in d2.items(): + d1[key] = _merge(d1.get(key), value) + return d1 + +def _display_mimetype(mimetype, objs, raw=False, metadata=None): + """internal implementation of all display_foo methods + + Parameters + ---------- + mimetype : str + The mimetype to be published (e.g. 'image/png') + objs : tuple of objects + The Python objects to display, or if raw=True raw text data to + display. + raw : bool + Are the data objects raw data or Python objects that need to be + formatted before display? [default: False] + metadata : dict (optional) + Metadata to be associated with the specific mimetype output. + """ + if metadata: + metadata = {mimetype: metadata} + if raw: + # turn list of pngdata into list of { 'image/png': pngdata } + objs = [ {mimetype: obj} for obj in objs ] + display(*objs, raw=raw, metadata=metadata, include=[mimetype]) + +#----------------------------------------------------------------------------- +# Main functions +#----------------------------------------------------------------------------- + +# use * to indicate transient is keyword-only +def publish_display_data(data, metadata=None, source=None, *, transient=None, **kwargs): + """Publish data and metadata to all frontends. + + See the ``display_data`` message in the messaging documentation for + more details about this message type. + + Keys of data and metadata can be any mime-type. + + Parameters + ---------- + data : dict + A dictionary having keys that are valid MIME types (like + 'text/plain' or 'image/svg+xml') and values that are the data for + that MIME type. The data itself must be a JSON'able data + structure. Minimally all data should have the 'text/plain' data, + which can be displayed by all frontends. If more than the plain + text is given, it is up to the frontend to decide which + representation to use. + metadata : dict + A dictionary for metadata related to the data. This can contain + arbitrary key, value pairs that frontends can use to interpret + the data. mime-type keys matching those in data can be used + to specify metadata about particular representations. + source : str, deprecated + Unused. + transient : dict, keyword-only + A dictionary of transient data, such as display_id. + """ + from IPython.core.interactiveshell import InteractiveShell + + display_pub = InteractiveShell.instance().display_pub + + # only pass transient if supplied, + # to avoid errors with older ipykernel. + # TODO: We could check for ipykernel version and provide a detailed upgrade message. + if transient: + kwargs['transient'] = transient + + display_pub.publish( + data=data, + metadata=metadata, + **kwargs + ) + + +def _new_id(): + """Generate a new random text id with urandom""" + return b2a_hex(os.urandom(16)).decode('ascii') + + +def display(*objs, include=None, exclude=None, metadata=None, transient=None, display_id=None, **kwargs): + """Display a Python object in all frontends. + + By default all representations will be computed and sent to the frontends. + Frontends can decide which representation is used and how. + + In terminal IPython this will be similar to using :func:`print`, for use in richer + frontends see Jupyter notebook examples with rich display logic. + + Parameters + ---------- + objs : tuple of objects + The Python objects to display. + raw : bool, optional + Are the objects to be displayed already mimetype-keyed dicts of raw display data, + or Python objects that need to be formatted before display? [default: False] + include : list, tuple or set, optional + A list of format type strings (MIME types) to include in the + format data dict. If this is set *only* the format types included + in this list will be computed. + exclude : list, tuple or set, optional + A list of format type strings (MIME types) to exclude in the format + data dict. If this is set all format types will be computed, + except for those included in this argument. + metadata : dict, optional + A dictionary of metadata to associate with the output. + mime-type keys in this dictionary will be associated with the individual + representation formats, if they exist. + transient : dict, optional + A dictionary of transient data to associate with the output. + Data in this dict should not be persisted to files (e.g. notebooks). + display_id : str, bool optional + Set an id for the display. + This id can be used for updating this display area later via update_display. + If given as `True`, generate a new `display_id` + kwargs: additional keyword-args, optional + Additional keyword-arguments are passed through to the display publisher. + + Returns + ------- + + handle: DisplayHandle + Returns a handle on updatable displays for use with :func:`update_display`, + if `display_id` is given. Returns :any:`None` if no `display_id` is given + (default). + + Examples + -------- + + >>> class Json(object): + ... def __init__(self, json): + ... self.json = json + ... def _repr_pretty_(self, pp, cycle): + ... import json + ... pp.text(json.dumps(self.json, indent=2)) + ... def __repr__(self): + ... return str(self.json) + ... + + >>> d = Json({1:2, 3: {4:5}}) + + >>> print(d) + {1: 2, 3: {4: 5}} + + >>> display(d) + { + "1": 2, + "3": { + "4": 5 + } + } + + >>> def int_formatter(integer, pp, cycle): + ... pp.text('I'*integer) + + >>> plain = get_ipython().display_formatter.formatters['text/plain'] + >>> plain.for_type(int, int_formatter) + + >>> display(7-5) + II + + >>> del plain.type_printers[int] + >>> display(7-5) + 2 + + See Also + -------- + + :func:`update_display` + + Notes + ----- + + In Python, objects can declare their textual representation using the + `__repr__` method. IPython expands on this idea and allows objects to declare + other, rich representations including: + + - HTML + - JSON + - PNG + - JPEG + - SVG + - LaTeX + + A single object can declare some or all of these representations; all are + handled by IPython's display system. + + The main idea of the first approach is that you have to implement special + display methods when you define your class, one for each representation you + want to use. Here is a list of the names of the special methods and the + values they must return: + + - `_repr_html_`: return raw HTML as a string, or a tuple (see below). + - `_repr_json_`: return a JSONable dict, or a tuple (see below). + - `_repr_jpeg_`: return raw JPEG data, or a tuple (see below). + - `_repr_png_`: return raw PNG data, or a tuple (see below). + - `_repr_svg_`: return raw SVG data as a string, or a tuple (see below). + - `_repr_latex_`: return LaTeX commands in a string surrounded by "$", + or a tuple (see below). + - `_repr_mimebundle_`: return a full mimebundle containing the mapping + from all mimetypes to data. + Use this for any mime-type not listed above. + + The above functions may also return the object's metadata alonside the + data. If the metadata is available, the functions will return a tuple + containing the data and metadata, in that order. If there is no metadata + available, then the functions will return the data only. + + When you are directly writing your own classes, you can adapt them for + display in IPython by following the above approach. But in practice, you + often need to work with existing classes that you can't easily modify. + + You can refer to the documentation on integrating with the display system in + order to register custom formatters for already existing types + (:ref:`integrating_rich_display`). + + .. versionadded:: 5.4 display available without import + .. versionadded:: 6.1 display available without import + + Since IPython 5.4 and 6.1 :func:`display` is automatically made available to + the user without import. If you are using display in a document that might + be used in a pure python context or with older version of IPython, use the + following import at the top of your file:: + + from IPython.display import display + + """ + from IPython.core.interactiveshell import InteractiveShell + + if not InteractiveShell.initialized(): + # Directly print objects. + print(*objs) + return + + raw = kwargs.pop('raw', False) + if transient is None: + transient = {} + if metadata is None: + metadata={} + if display_id: + if display_id is True: + display_id = _new_id() + transient['display_id'] = display_id + if kwargs.get('update') and 'display_id' not in transient: + raise TypeError('display_id required for update_display') + if transient: + kwargs['transient'] = transient + + if not objs and display_id: + # if given no objects, but still a request for a display_id, + # we assume the user wants to insert an empty output that + # can be updated later + objs = [{}] + raw = True + + if not raw: + format = InteractiveShell.instance().display_formatter.format + + for obj in objs: + if raw: + publish_display_data(data=obj, metadata=metadata, **kwargs) + else: + format_dict, md_dict = format(obj, include=include, exclude=exclude) + if not format_dict: + # nothing to display (e.g. _ipython_display_ took over) + continue + if metadata: + # kwarg-specified metadata gets precedence + _merge(md_dict, metadata) + publish_display_data(data=format_dict, metadata=md_dict, **kwargs) + if display_id: + return DisplayHandle(display_id) + + +# use * for keyword-only display_id arg +def update_display(obj, *, display_id, **kwargs): + """Update an existing display by id + + Parameters + ---------- + + obj: + The object with which to update the display + display_id: keyword-only + The id of the display to update + + See Also + -------- + + :func:`display` + """ + kwargs['update'] = True + display(obj, display_id=display_id, **kwargs) + + +class DisplayHandle(object): + """A handle on an updatable display + + Call `.update(obj)` to display a new object. + + Call `.display(obj`) to add a new instance of this display, + and update existing instances. + + See Also + -------- + + :func:`display`, :func:`update_display` + + """ + + def __init__(self, display_id=None): + if display_id is None: + display_id = _new_id() + self.display_id = display_id + + def __repr__(self): + return "<%s display_id=%s>" % (self.__class__.__name__, self.display_id) + + def display(self, obj, **kwargs): + """Make a new display with my id, updating existing instances. + + Parameters + ---------- + + obj: + object to display + **kwargs: + additional keyword arguments passed to display + """ + display(obj, display_id=self.display_id, **kwargs) + + def update(self, obj, **kwargs): + """Update existing displays with my id + + Parameters + ---------- + + obj: + object to display + **kwargs: + additional keyword arguments passed to update_display + """ + update_display(obj, display_id=self.display_id, **kwargs) + + +def display_pretty(*objs, **kwargs): + """Display the pretty (default) representation of an object. + + Parameters + ---------- + objs : tuple of objects + The Python objects to display, or if raw=True raw text data to + display. + raw : bool + Are the data objects raw data or Python objects that need to be + formatted before display? [default: False] + metadata : dict (optional) + Metadata to be associated with the specific mimetype output. + """ + _display_mimetype('text/plain', objs, **kwargs) + + +def display_html(*objs, **kwargs): + """Display the HTML representation of an object. + + Note: If raw=False and the object does not have a HTML + representation, no HTML will be shown. + + Parameters + ---------- + objs : tuple of objects + The Python objects to display, or if raw=True raw HTML data to + display. + raw : bool + Are the data objects raw data or Python objects that need to be + formatted before display? [default: False] + metadata : dict (optional) + Metadata to be associated with the specific mimetype output. + """ + _display_mimetype('text/html', objs, **kwargs) + + +def display_markdown(*objs, **kwargs): + """Displays the Markdown representation of an object. + + Parameters + ---------- + objs : tuple of objects + The Python objects to display, or if raw=True raw markdown data to + display. + raw : bool + Are the data objects raw data or Python objects that need to be + formatted before display? [default: False] + metadata : dict (optional) + Metadata to be associated with the specific mimetype output. + """ + + _display_mimetype('text/markdown', objs, **kwargs) + + +def display_svg(*objs, **kwargs): + """Display the SVG representation of an object. + + Parameters + ---------- + objs : tuple of objects + The Python objects to display, or if raw=True raw svg data to + display. + raw : bool + Are the data objects raw data or Python objects that need to be + formatted before display? [default: False] + metadata : dict (optional) + Metadata to be associated with the specific mimetype output. + """ + _display_mimetype('image/svg+xml', objs, **kwargs) + + +def display_png(*objs, **kwargs): + """Display the PNG representation of an object. + + Parameters + ---------- + objs : tuple of objects + The Python objects to display, or if raw=True raw png data to + display. + raw : bool + Are the data objects raw data or Python objects that need to be + formatted before display? [default: False] + metadata : dict (optional) + Metadata to be associated with the specific mimetype output. + """ + _display_mimetype('image/png', objs, **kwargs) + + +def display_jpeg(*objs, **kwargs): + """Display the JPEG representation of an object. + + Parameters + ---------- + objs : tuple of objects + The Python objects to display, or if raw=True raw JPEG data to + display. + raw : bool + Are the data objects raw data or Python objects that need to be + formatted before display? [default: False] + metadata : dict (optional) + Metadata to be associated with the specific mimetype output. + """ + _display_mimetype('image/jpeg', objs, **kwargs) + + +def display_latex(*objs, **kwargs): + """Display the LaTeX representation of an object. + + Parameters + ---------- + objs : tuple of objects + The Python objects to display, or if raw=True raw latex data to + display. + raw : bool + Are the data objects raw data or Python objects that need to be + formatted before display? [default: False] + metadata : dict (optional) + Metadata to be associated with the specific mimetype output. + """ + _display_mimetype('text/latex', objs, **kwargs) + + +def display_json(*objs, **kwargs): + """Display the JSON representation of an object. + + Note that not many frontends support displaying JSON. + + Parameters + ---------- + objs : tuple of objects + The Python objects to display, or if raw=True raw json data to + display. + raw : bool + Are the data objects raw data or Python objects that need to be + formatted before display? [default: False] + metadata : dict (optional) + Metadata to be associated with the specific mimetype output. + """ + _display_mimetype('application/json', objs, **kwargs) + + +def display_javascript(*objs, **kwargs): + """Display the Javascript representation of an object. + + Parameters + ---------- + objs : tuple of objects + The Python objects to display, or if raw=True raw javascript data to + display. + raw : bool + Are the data objects raw data or Python objects that need to be + formatted before display? [default: False] + metadata : dict (optional) + Metadata to be associated with the specific mimetype output. + """ + _display_mimetype('application/javascript', objs, **kwargs) + + +def display_pdf(*objs, **kwargs): + """Display the PDF representation of an object. + + Parameters + ---------- + objs : tuple of objects + The Python objects to display, or if raw=True raw javascript data to + display. + raw : bool + Are the data objects raw data or Python objects that need to be + formatted before display? [default: False] + metadata : dict (optional) + Metadata to be associated with the specific mimetype output. + """ + _display_mimetype('application/pdf', objs, **kwargs) + + +#----------------------------------------------------------------------------- +# Smart classes +#----------------------------------------------------------------------------- + + +class DisplayObject(object): + """An object that wraps data to be displayed.""" + + _read_flags = 'r' + _show_mem_addr = False + metadata = None + + def __init__(self, data=None, url=None, filename=None, metadata=None): + """Create a display object given raw data. + + When this object is returned by an expression or passed to the + display function, it will result in the data being displayed + in the frontend. The MIME type of the data should match the + subclasses used, so the Png subclass should be used for 'image/png' + data. If the data is a URL, the data will first be downloaded + and then displayed. If + + Parameters + ---------- + data : unicode, str or bytes + The raw data or a URL or file to load the data from + url : unicode + A URL to download the data from. + filename : unicode + Path to a local file to load the data from. + metadata : dict + Dict of metadata associated to be the object when displayed + """ + if isinstance(data, (Path, PurePath)): + data = str(data) + + if data is not None and isinstance(data, str): + if data.startswith('http') and url is None: + url = data + filename = None + data = None + elif _safe_exists(data) and filename is None: + url = None + filename = data + data = None + + self.url = url + self.filename = filename + # because of @data.setter methods in + # subclasses ensure url and filename are set + # before assigning to self.data + self.data = data + + if metadata is not None: + self.metadata = metadata + elif self.metadata is None: + self.metadata = {} + + self.reload() + self._check_data() + + def __repr__(self): + if not self._show_mem_addr: + cls = self.__class__ + r = "<%s.%s object>" % (cls.__module__, cls.__name__) + else: + r = super(DisplayObject, self).__repr__() + return r + + def _check_data(self): + """Override in subclasses if there's something to check.""" + pass + + def _data_and_metadata(self): + """shortcut for returning metadata with shape information, if defined""" + if self.metadata: + return self.data, deepcopy(self.metadata) + else: + return self.data + + def reload(self): + """Reload the raw data from file or URL.""" + if self.filename is not None: + with open(self.filename, self._read_flags) as f: + self.data = f.read() + elif self.url is not None: + # Deferred import + from urllib.request import urlopen + response = urlopen(self.url) + data = response.read() + # extract encoding from header, if there is one: + encoding = None + if 'content-type' in response.headers: + for sub in response.headers['content-type'].split(';'): + sub = sub.strip() + if sub.startswith('charset'): + encoding = sub.split('=')[-1].strip() + break + if 'content-encoding' in response.headers: + # TODO: do deflate? + if 'gzip' in response.headers['content-encoding']: + import gzip + from io import BytesIO + with gzip.open(BytesIO(data), 'rt', encoding=encoding) as fp: + encoding = None + data = fp.read() + + # decode data, if an encoding was specified + # We only touch self.data once since + # subclasses such as SVG have @data.setter methods + # that transform self.data into ... well svg. + if encoding: + self.data = data.decode(encoding, 'replace') + else: + self.data = data + + +class TextDisplayObject(DisplayObject): + """Validate that display data is text""" + def _check_data(self): + if self.data is not None and not isinstance(self.data, str): + raise TypeError("%s expects text, not %r" % (self.__class__.__name__, self.data)) + +class Pretty(TextDisplayObject): + + def _repr_pretty_(self, pp, cycle): + return pp.text(self.data) + + +class HTML(TextDisplayObject): + + def __init__(self, data=None, url=None, filename=None, metadata=None): + def warn(): + if not data: + return False + + # + # Avoid calling lower() on the entire data, because it could be a + # long string and we're only interested in its beginning and end. + # + prefix = data[:10].lower() + suffix = data[-10:].lower() + return prefix.startswith("') + m_warn.assert_not_called() + + display.HTML('') + m_warn.assert_called_with('Consider using IPython.display.IFrame instead') + + m_warn.reset_mock() + display.HTML('') + m_warn.assert_called_with('Consider using IPython.display.IFrame instead') + +def test_progress(): + p = display.ProgressBar(10) + nt.assert_in('0/10',repr(p)) + p.html_width = '100%' + p.progress = 5 + nt.assert_equal(p._repr_html_(), "") + +def test_progress_iter(): + with capture_output(display=False) as captured: + for i in display.ProgressBar(5): + out = captured.stdout + nt.assert_in('{0}/5'.format(i), out) + out = captured.stdout + nt.assert_in('5/5', out) + +def test_json(): + d = {'a': 5} + lis = [d] + metadata = [ + {'expanded': False, 'root': 'root'}, + {'expanded': True, 'root': 'root'}, + {'expanded': False, 'root': 'custom'}, + {'expanded': True, 'root': 'custom'}, + ] + json_objs = [ + display.JSON(d), + display.JSON(d, expanded=True), + display.JSON(d, root='custom'), + display.JSON(d, expanded=True, root='custom'), + ] + for j, md in zip(json_objs, metadata): + nt.assert_equal(j._repr_json_(), (d, md)) + + with warnings.catch_warnings(record=True) as w: + warnings.simplefilter("always") + j = display.JSON(json.dumps(d)) + nt.assert_equal(len(w), 1) + nt.assert_equal(j._repr_json_(), (d, metadata[0])) + + json_objs = [ + display.JSON(lis), + display.JSON(lis, expanded=True), + display.JSON(lis, root='custom'), + display.JSON(lis, expanded=True, root='custom'), + ] + for j, md in zip(json_objs, metadata): + nt.assert_equal(j._repr_json_(), (lis, md)) + + with warnings.catch_warnings(record=True) as w: + warnings.simplefilter("always") + j = display.JSON(json.dumps(lis)) + nt.assert_equal(len(w), 1) + nt.assert_equal(j._repr_json_(), (lis, metadata[0])) + +def test_video_embedding(): + """use a tempfile, with dummy-data, to ensure that video embedding doesn't crash""" + v = display.Video("http://ignored") + assert not v.embed + html = v._repr_html_() + nt.assert_not_in('src="data:', html) + nt.assert_in('src="http://ignored"', html) + + with nt.assert_raises(ValueError): + v = display.Video(b'abc') + + with NamedFileInTemporaryDirectory('test.mp4') as f: + f.write(b'abc') + f.close() + + v = display.Video(f.name) + assert not v.embed + html = v._repr_html_() + nt.assert_not_in('src="data:', html) + + v = display.Video(f.name, embed=True) + html = v._repr_html_() + nt.assert_in('src="data:video/mp4;base64,YWJj"',html) + + v = display.Video(f.name, embed=True, mimetype='video/other') + html = v._repr_html_() + nt.assert_in('src="data:video/other;base64,YWJj"',html) + + v = display.Video(b'abc', embed=True, mimetype='video/mp4') + html = v._repr_html_() + nt.assert_in('src="data:video/mp4;base64,YWJj"',html) + + v = display.Video(u'YWJj', embed=True, mimetype='video/xyz') + html = v._repr_html_() + nt.assert_in('src="data:video/xyz;base64,YWJj"',html) + +def test_html_metadata(): + s = "

Test

" + h = display.HTML(s, metadata={"isolated": True}) + nt.assert_equal(h._repr_html_(), (s, {"isolated": True})) + +def test_display_id(): + ip = get_ipython() + with mock.patch.object(ip.display_pub, 'publish') as pub: + handle = display.display('x') + nt.assert_is(handle, None) + handle = display.display('y', display_id='secret') + nt.assert_is_instance(handle, display.DisplayHandle) + handle2 = display.display('z', display_id=True) + nt.assert_is_instance(handle2, display.DisplayHandle) + nt.assert_not_equal(handle.display_id, handle2.display_id) + + nt.assert_equal(pub.call_count, 3) + args, kwargs = pub.call_args_list[0] + nt.assert_equal(args, ()) + nt.assert_equal(kwargs, { + 'data': { + 'text/plain': repr('x') + }, + 'metadata': {}, + }) + args, kwargs = pub.call_args_list[1] + nt.assert_equal(args, ()) + nt.assert_equal(kwargs, { + 'data': { + 'text/plain': repr('y') + }, + 'metadata': {}, + 'transient': { + 'display_id': handle.display_id, + }, + }) + args, kwargs = pub.call_args_list[2] + nt.assert_equal(args, ()) + nt.assert_equal(kwargs, { + 'data': { + 'text/plain': repr('z') + }, + 'metadata': {}, + 'transient': { + 'display_id': handle2.display_id, + }, + }) + + +def test_update_display(): + ip = get_ipython() + with mock.patch.object(ip.display_pub, 'publish') as pub: + with nt.assert_raises(TypeError): + display.update_display('x') + display.update_display('x', display_id='1') + display.update_display('y', display_id='2') + args, kwargs = pub.call_args_list[0] + nt.assert_equal(args, ()) + nt.assert_equal(kwargs, { + 'data': { + 'text/plain': repr('x') + }, + 'metadata': {}, + 'transient': { + 'display_id': '1', + }, + 'update': True, + }) + args, kwargs = pub.call_args_list[1] + nt.assert_equal(args, ()) + nt.assert_equal(kwargs, { + 'data': { + 'text/plain': repr('y') + }, + 'metadata': {}, + 'transient': { + 'display_id': '2', + }, + 'update': True, + }) + + +def test_display_handle(): + ip = get_ipython() + handle = display.DisplayHandle() + nt.assert_is_instance(handle.display_id, str) + handle = display.DisplayHandle('my-id') + nt.assert_equal(handle.display_id, 'my-id') + with mock.patch.object(ip.display_pub, 'publish') as pub: + handle.display('x') + handle.update('y') + + args, kwargs = pub.call_args_list[0] + nt.assert_equal(args, ()) + nt.assert_equal(kwargs, { + 'data': { + 'text/plain': repr('x') + }, + 'metadata': {}, + 'transient': { + 'display_id': handle.display_id, + } + }) + args, kwargs = pub.call_args_list[1] + nt.assert_equal(args, ()) + nt.assert_equal(kwargs, { + 'data': { + 'text/plain': repr('y') + }, + 'metadata': {}, + 'transient': { + 'display_id': handle.display_id, + }, + 'update': True, + }) + diff --git a/.venv/lib/python3.8/site-packages/IPython/core/tests/test_displayhook.py b/.venv/lib/python3.8/site-packages/IPython/core/tests/test_displayhook.py new file mode 100644 index 00000000..6ad89793 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/IPython/core/tests/test_displayhook.py @@ -0,0 +1,112 @@ +import sys +from IPython.testing.tools import AssertPrints, AssertNotPrints +from IPython.core.displayhook import CapturingDisplayHook +from IPython.utils.capture import CapturedIO + +def test_output_displayed(): + """Checking to make sure that output is displayed""" + + with AssertPrints('2'): + ip.run_cell('1+1', store_history=True) + + with AssertPrints('2'): + ip.run_cell('1+1 # comment with a semicolon;', store_history=True) + + with AssertPrints('2'): + ip.run_cell('1+1\n#commented_out_function();', store_history=True) + + +def test_output_quiet(): + """Checking to make sure that output is quiet""" + + with AssertNotPrints('2'): + ip.run_cell('1+1;', store_history=True) + + with AssertNotPrints('2'): + ip.run_cell('1+1; # comment with a semicolon', store_history=True) + + with AssertNotPrints('2'): + ip.run_cell('1+1;\n#commented_out_function()', store_history=True) + +def test_underscore_no_overrite_user(): + ip.run_cell('_ = 42', store_history=True) + ip.run_cell('1+1', store_history=True) + + with AssertPrints('42'): + ip.run_cell('print(_)', store_history=True) + + ip.run_cell('del _', store_history=True) + ip.run_cell('6+6', store_history=True) + with AssertPrints('12'): + ip.run_cell('_', store_history=True) + + +def test_underscore_no_overrite_builtins(): + ip.run_cell("import gettext ; gettext.install('foo')", store_history=True) + ip.run_cell('3+3', store_history=True) + + with AssertPrints('gettext'): + ip.run_cell('print(_)', store_history=True) + + ip.run_cell('_ = "userset"', store_history=True) + + with AssertPrints('userset'): + ip.run_cell('print(_)', store_history=True) + ip.run_cell('import builtins; del builtins._') + + +def test_interactivehooks_ast_modes(): + """ + Test that ast nodes can be triggered with different modes + """ + saved_mode = ip.ast_node_interactivity + ip.ast_node_interactivity = 'last_expr_or_assign' + + try: + with AssertPrints('2'): + ip.run_cell('a = 1+1', store_history=True) + + with AssertPrints('9'): + ip.run_cell('b = 1+8 # comment with a semicolon;', store_history=False) + + with AssertPrints('7'): + ip.run_cell('c = 1+6\n#commented_out_function();', store_history=True) + + ip.run_cell('d = 11', store_history=True) + with AssertPrints('12'): + ip.run_cell('d += 1', store_history=True) + + with AssertNotPrints('42'): + ip.run_cell('(u,v) = (41+1, 43-1)') + + finally: + ip.ast_node_interactivity = saved_mode + +def test_interactivehooks_ast_modes_semi_suppress(): + """ + Test that ast nodes can be triggered with different modes and suppressed + by semicolon + """ + saved_mode = ip.ast_node_interactivity + ip.ast_node_interactivity = 'last_expr_or_assign' + + try: + with AssertNotPrints('2'): + ip.run_cell('x = 1+1;', store_history=True) + + with AssertNotPrints('7'): + ip.run_cell('y = 1+6; # comment with a semicolon', store_history=True) + + with AssertNotPrints('9'): + ip.run_cell('z = 1+8;\n#commented_out_function()', store_history=True) + + finally: + ip.ast_node_interactivity = saved_mode + +def test_capture_display_hook_format(): + """Tests that the capture display hook conforms to the CapturedIO output format""" + hook = CapturingDisplayHook(ip) + hook({"foo": "bar"}) + captured = CapturedIO(sys.stdout, sys.stderr, hook.outputs) + # Should not raise with RichOutput transformation error + captured.outputs diff --git a/.venv/lib/python3.8/site-packages/IPython/core/tests/test_events.py b/.venv/lib/python3.8/site-packages/IPython/core/tests/test_events.py new file mode 100644 index 00000000..a4211ece --- /dev/null +++ b/.venv/lib/python3.8/site-packages/IPython/core/tests/test_events.py @@ -0,0 +1,92 @@ +import unittest +from unittest.mock import Mock +import nose.tools as nt + +from IPython.core import events +import IPython.testing.tools as tt + + +@events._define_event +def ping_received(): + pass + + +@events._define_event +def event_with_argument(argument): + pass + + +class CallbackTests(unittest.TestCase): + def setUp(self): + self.em = events.EventManager(get_ipython(), + {'ping_received': ping_received, + 'event_with_argument': event_with_argument}) + + def test_register_unregister(self): + cb = Mock() + + self.em.register('ping_received', cb) + self.em.trigger('ping_received') + self.assertEqual(cb.call_count, 1) + + self.em.unregister('ping_received', cb) + self.em.trigger('ping_received') + self.assertEqual(cb.call_count, 1) + + def test_bare_function_missed_unregister(self): + def cb1(): + ... + + def cb2(): + ... + + self.em.register('ping_received', cb1) + nt.assert_raises(ValueError, self.em.unregister, 'ping_received', cb2) + self.em.unregister('ping_received', cb1) + + def test_cb_error(self): + cb = Mock(side_effect=ValueError) + self.em.register('ping_received', cb) + with tt.AssertPrints("Error in callback"): + self.em.trigger('ping_received') + + def test_cb_keyboard_interrupt(self): + cb = Mock(side_effect=KeyboardInterrupt) + self.em.register('ping_received', cb) + with tt.AssertPrints("Error in callback"): + self.em.trigger('ping_received') + + def test_unregister_during_callback(self): + invoked = [False] * 3 + + def func1(*_): + invoked[0] = True + self.em.unregister('ping_received', func1) + self.em.register('ping_received', func3) + + def func2(*_): + invoked[1] = True + self.em.unregister('ping_received', func2) + + def func3(*_): + invoked[2] = True + + self.em.register('ping_received', func1) + self.em.register('ping_received', func2) + + self.em.trigger('ping_received') + self.assertEqual([True, True, False], invoked) + self.assertEqual([func3], self.em.callbacks['ping_received']) + + def test_ignore_event_arguments_if_no_argument_required(self): + call_count = [0] + def event_with_no_argument(): + call_count[0] += 1 + + self.em.register('event_with_argument', event_with_no_argument) + self.em.trigger('event_with_argument', 'the argument') + self.assertEqual(call_count[0], 1) + + self.em.unregister('event_with_argument', event_with_no_argument) + self.em.trigger('ping_received') + self.assertEqual(call_count[0], 1) diff --git a/.venv/lib/python3.8/site-packages/IPython/core/tests/test_extension.py b/.venv/lib/python3.8/site-packages/IPython/core/tests/test_extension.py new file mode 100644 index 00000000..b18e6848 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/IPython/core/tests/test_extension.py @@ -0,0 +1,96 @@ +import os.path + +import nose.tools as nt + +import IPython.testing.tools as tt +from IPython.utils.syspathcontext import prepended_to_syspath +from IPython.utils.tempdir import TemporaryDirectory + +ext1_content = """ +def load_ipython_extension(ip): + print("Running ext1 load") + +def unload_ipython_extension(ip): + print("Running ext1 unload") +""" + +ext2_content = """ +def load_ipython_extension(ip): + print("Running ext2 load") +""" + +ext3_content = """ +def load_ipython_extension(ip): + ip2 = get_ipython() + print(ip is ip2) +""" + +def test_extension_loading(): + em = get_ipython().extension_manager + with TemporaryDirectory() as td: + ext1 = os.path.join(td, 'ext1.py') + with open(ext1, 'w') as f: + f.write(ext1_content) + + ext2 = os.path.join(td, 'ext2.py') + with open(ext2, 'w') as f: + f.write(ext2_content) + + with prepended_to_syspath(td): + assert 'ext1' not in em.loaded + assert 'ext2' not in em.loaded + + # Load extension + with tt.AssertPrints("Running ext1 load"): + assert em.load_extension('ext1') is None + assert 'ext1' in em.loaded + + # Should refuse to load it again + with tt.AssertNotPrints("Running ext1 load"): + assert em.load_extension('ext1') == 'already loaded' + + # Reload + with tt.AssertPrints("Running ext1 unload"): + with tt.AssertPrints("Running ext1 load", suppress=False): + em.reload_extension('ext1') + + # Unload + with tt.AssertPrints("Running ext1 unload"): + assert em.unload_extension('ext1') is None + + # Can't unload again + with tt.AssertNotPrints("Running ext1 unload"): + assert em.unload_extension('ext1') == 'not loaded' + assert em.unload_extension('ext2') == 'not loaded' + + # Load extension 2 + with tt.AssertPrints("Running ext2 load"): + assert em.load_extension('ext2') is None + + # Can't unload this + assert em.unload_extension('ext2') == 'no unload function' + + # But can reload it + with tt.AssertPrints("Running ext2 load"): + em.reload_extension('ext2') + + +def test_extension_builtins(): + em = get_ipython().extension_manager + with TemporaryDirectory() as td: + ext3 = os.path.join(td, 'ext3.py') + with open(ext3, 'w') as f: + f.write(ext3_content) + + assert 'ext3' not in em.loaded + + with prepended_to_syspath(td): + # Load extension + with tt.AssertPrints("True"): + assert em.load_extension('ext3') is None + assert 'ext3' in em.loaded + + +def test_non_extension(): + em = get_ipython().extension_manager + nt.assert_equal(em.load_extension('sys'), "no load function") diff --git a/.venv/lib/python3.8/site-packages/IPython/core/tests/test_formatters.py b/.venv/lib/python3.8/site-packages/IPython/core/tests/test_formatters.py new file mode 100644 index 00000000..cde43c94 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/IPython/core/tests/test_formatters.py @@ -0,0 +1,533 @@ +"""Tests for the Formatters.""" + +import warnings +from math import pi + +try: + import numpy +except: + numpy = None +import nose.tools as nt + +from IPython import get_ipython +from traitlets.config import Config +from IPython.core.formatters import ( + PlainTextFormatter, HTMLFormatter, PDFFormatter, _mod_name_key, + DisplayFormatter, JSONFormatter, +) +from IPython.utils.io import capture_output + +class A(object): + def __repr__(self): + return 'A()' + +class B(A): + def __repr__(self): + return 'B()' + +class C: + pass + +class BadRepr(object): + def __repr__(self): + raise ValueError("bad repr") + +class BadPretty(object): + _repr_pretty_ = None + +class GoodPretty(object): + def _repr_pretty_(self, pp, cycle): + pp.text('foo') + + def __repr__(self): + return 'GoodPretty()' + +def foo_printer(obj, pp, cycle): + pp.text('foo') + +def test_pretty(): + f = PlainTextFormatter() + f.for_type(A, foo_printer) + nt.assert_equal(f(A()), 'foo') + nt.assert_equal(f(B()), 'B()') + nt.assert_equal(f(GoodPretty()), 'foo') + # Just don't raise an exception for the following: + f(BadPretty()) + + f.pprint = False + nt.assert_equal(f(A()), 'A()') + nt.assert_equal(f(B()), 'B()') + nt.assert_equal(f(GoodPretty()), 'GoodPretty()') + + +def test_deferred(): + f = PlainTextFormatter() + +def test_precision(): + """test various values for float_precision.""" + f = PlainTextFormatter() + nt.assert_equal(f(pi), repr(pi)) + f.float_precision = 0 + if numpy: + po = numpy.get_printoptions() + nt.assert_equal(po['precision'], 0) + nt.assert_equal(f(pi), '3') + f.float_precision = 2 + if numpy: + po = numpy.get_printoptions() + nt.assert_equal(po['precision'], 2) + nt.assert_equal(f(pi), '3.14') + f.float_precision = '%g' + if numpy: + po = numpy.get_printoptions() + nt.assert_equal(po['precision'], 2) + nt.assert_equal(f(pi), '3.14159') + f.float_precision = '%e' + nt.assert_equal(f(pi), '3.141593e+00') + f.float_precision = '' + if numpy: + po = numpy.get_printoptions() + nt.assert_equal(po['precision'], 8) + nt.assert_equal(f(pi), repr(pi)) + +def test_bad_precision(): + """test various invalid values for float_precision.""" + f = PlainTextFormatter() + def set_fp(p): + f.float_precision=p + nt.assert_raises(ValueError, set_fp, '%') + nt.assert_raises(ValueError, set_fp, '%.3f%i') + nt.assert_raises(ValueError, set_fp, 'foo') + nt.assert_raises(ValueError, set_fp, -1) + +def test_for_type(): + f = PlainTextFormatter() + + # initial return, None + nt.assert_is(f.for_type(C, foo_printer), None) + # no func queries + nt.assert_is(f.for_type(C), foo_printer) + # shouldn't change anything + nt.assert_is(f.for_type(C), foo_printer) + # None should do the same + nt.assert_is(f.for_type(C, None), foo_printer) + nt.assert_is(f.for_type(C, None), foo_printer) + +def test_for_type_string(): + f = PlainTextFormatter() + + type_str = '%s.%s' % (C.__module__, 'C') + + # initial return, None + nt.assert_is(f.for_type(type_str, foo_printer), None) + # no func queries + nt.assert_is(f.for_type(type_str), foo_printer) + nt.assert_in(_mod_name_key(C), f.deferred_printers) + nt.assert_is(f.for_type(C), foo_printer) + nt.assert_not_in(_mod_name_key(C), f.deferred_printers) + nt.assert_in(C, f.type_printers) + +def test_for_type_by_name(): + f = PlainTextFormatter() + + mod = C.__module__ + + # initial return, None + nt.assert_is(f.for_type_by_name(mod, 'C', foo_printer), None) + # no func queries + nt.assert_is(f.for_type_by_name(mod, 'C'), foo_printer) + # shouldn't change anything + nt.assert_is(f.for_type_by_name(mod, 'C'), foo_printer) + # None should do the same + nt.assert_is(f.for_type_by_name(mod, 'C', None), foo_printer) + nt.assert_is(f.for_type_by_name(mod, 'C', None), foo_printer) + +def test_lookup(): + f = PlainTextFormatter() + + f.for_type(C, foo_printer) + nt.assert_is(f.lookup(C()), foo_printer) + with nt.assert_raises(KeyError): + f.lookup(A()) + +def test_lookup_string(): + f = PlainTextFormatter() + type_str = '%s.%s' % (C.__module__, 'C') + + f.for_type(type_str, foo_printer) + nt.assert_is(f.lookup(C()), foo_printer) + # should move from deferred to imported dict + nt.assert_not_in(_mod_name_key(C), f.deferred_printers) + nt.assert_in(C, f.type_printers) + +def test_lookup_by_type(): + f = PlainTextFormatter() + f.for_type(C, foo_printer) + nt.assert_is(f.lookup_by_type(C), foo_printer) + with nt.assert_raises(KeyError): + f.lookup_by_type(A) + +def test_lookup_by_type_string(): + f = PlainTextFormatter() + type_str = '%s.%s' % (C.__module__, 'C') + f.for_type(type_str, foo_printer) + + # verify insertion + nt.assert_in(_mod_name_key(C), f.deferred_printers) + nt.assert_not_in(C, f.type_printers) + + nt.assert_is(f.lookup_by_type(type_str), foo_printer) + # lookup by string doesn't cause import + nt.assert_in(_mod_name_key(C), f.deferred_printers) + nt.assert_not_in(C, f.type_printers) + + nt.assert_is(f.lookup_by_type(C), foo_printer) + # should move from deferred to imported dict + nt.assert_not_in(_mod_name_key(C), f.deferred_printers) + nt.assert_in(C, f.type_printers) + +def test_in_formatter(): + f = PlainTextFormatter() + f.for_type(C, foo_printer) + type_str = '%s.%s' % (C.__module__, 'C') + nt.assert_in(C, f) + nt.assert_in(type_str, f) + +def test_string_in_formatter(): + f = PlainTextFormatter() + type_str = '%s.%s' % (C.__module__, 'C') + f.for_type(type_str, foo_printer) + nt.assert_in(type_str, f) + nt.assert_in(C, f) + +def test_pop(): + f = PlainTextFormatter() + f.for_type(C, foo_printer) + nt.assert_is(f.lookup_by_type(C), foo_printer) + nt.assert_is(f.pop(C, None), foo_printer) + f.for_type(C, foo_printer) + nt.assert_is(f.pop(C), foo_printer) + with nt.assert_raises(KeyError): + f.lookup_by_type(C) + with nt.assert_raises(KeyError): + f.pop(C) + with nt.assert_raises(KeyError): + f.pop(A) + nt.assert_is(f.pop(A, None), None) + +def test_pop_string(): + f = PlainTextFormatter() + type_str = '%s.%s' % (C.__module__, 'C') + + with nt.assert_raises(KeyError): + f.pop(type_str) + + f.for_type(type_str, foo_printer) + f.pop(type_str) + with nt.assert_raises(KeyError): + f.lookup_by_type(C) + with nt.assert_raises(KeyError): + f.pop(type_str) + + f.for_type(C, foo_printer) + nt.assert_is(f.pop(type_str, None), foo_printer) + with nt.assert_raises(KeyError): + f.lookup_by_type(C) + with nt.assert_raises(KeyError): + f.pop(type_str) + nt.assert_is(f.pop(type_str, None), None) + + +def test_error_method(): + f = HTMLFormatter() + class BadHTML(object): + def _repr_html_(self): + raise ValueError("Bad HTML") + bad = BadHTML() + with capture_output() as captured: + result = f(bad) + nt.assert_is(result, None) + nt.assert_in("Traceback", captured.stdout) + nt.assert_in("Bad HTML", captured.stdout) + nt.assert_in("_repr_html_", captured.stdout) + +def test_nowarn_notimplemented(): + f = HTMLFormatter() + class HTMLNotImplemented(object): + def _repr_html_(self): + raise NotImplementedError + h = HTMLNotImplemented() + with capture_output() as captured: + result = f(h) + nt.assert_is(result, None) + nt.assert_equal("", captured.stderr) + nt.assert_equal("", captured.stdout) + +def test_warn_error_for_type(): + f = HTMLFormatter() + f.for_type(int, lambda i: name_error) + with capture_output() as captured: + result = f(5) + nt.assert_is(result, None) + nt.assert_in("Traceback", captured.stdout) + nt.assert_in("NameError", captured.stdout) + nt.assert_in("name_error", captured.stdout) + +def test_error_pretty_method(): + f = PlainTextFormatter() + class BadPretty(object): + def _repr_pretty_(self): + return "hello" + bad = BadPretty() + with capture_output() as captured: + result = f(bad) + nt.assert_is(result, None) + nt.assert_in("Traceback", captured.stdout) + nt.assert_in("_repr_pretty_", captured.stdout) + nt.assert_in("given", captured.stdout) + nt.assert_in("argument", captured.stdout) + + +def test_bad_repr_traceback(): + f = PlainTextFormatter() + bad = BadRepr() + with capture_output() as captured: + result = f(bad) + # catches error, returns None + nt.assert_is(result, None) + nt.assert_in("Traceback", captured.stdout) + nt.assert_in("__repr__", captured.stdout) + nt.assert_in("ValueError", captured.stdout) + + +class MakePDF(object): + def _repr_pdf_(self): + return 'PDF' + +def test_pdf_formatter(): + pdf = MakePDF() + f = PDFFormatter() + nt.assert_equal(f(pdf), 'PDF') + +def test_print_method_bound(): + f = HTMLFormatter() + class MyHTML(object): + def _repr_html_(self): + return "hello" + with capture_output() as captured: + result = f(MyHTML) + nt.assert_is(result, None) + nt.assert_not_in("FormatterWarning", captured.stderr) + + with capture_output() as captured: + result = f(MyHTML()) + nt.assert_equal(result, "hello") + nt.assert_equal(captured.stderr, "") + +def test_print_method_weird(): + + class TextMagicHat(object): + def __getattr__(self, key): + return key + + f = HTMLFormatter() + + text_hat = TextMagicHat() + nt.assert_equal(text_hat._repr_html_, '_repr_html_') + with capture_output() as captured: + result = f(text_hat) + + nt.assert_is(result, None) + nt.assert_not_in("FormatterWarning", captured.stderr) + + class CallableMagicHat(object): + def __getattr__(self, key): + return lambda : key + + call_hat = CallableMagicHat() + with capture_output() as captured: + result = f(call_hat) + + nt.assert_equal(result, None) + + class BadReprArgs(object): + def _repr_html_(self, extra, args): + return "html" + + bad = BadReprArgs() + with capture_output() as captured: + result = f(bad) + + nt.assert_is(result, None) + nt.assert_not_in("FormatterWarning", captured.stderr) + + +def test_format_config(): + """config objects don't pretend to support fancy reprs with lazy attrs""" + f = HTMLFormatter() + cfg = Config() + with capture_output() as captured: + result = f(cfg) + nt.assert_is(result, None) + nt.assert_equal(captured.stderr, "") + + with capture_output() as captured: + result = f(Config) + nt.assert_is(result, None) + nt.assert_equal(captured.stderr, "") + +def test_pretty_max_seq_length(): + f = PlainTextFormatter(max_seq_length=1) + lis = list(range(3)) + text = f(lis) + nt.assert_equal(text, '[0, ...]') + f.max_seq_length = 0 + text = f(lis) + nt.assert_equal(text, '[0, 1, 2]') + text = f(list(range(1024))) + lines = text.splitlines() + nt.assert_equal(len(lines), 1024) + + +def test_ipython_display_formatter(): + """Objects with _ipython_display_ defined bypass other formatters""" + f = get_ipython().display_formatter + catcher = [] + class SelfDisplaying(object): + def _ipython_display_(self): + catcher.append(self) + + class NotSelfDisplaying(object): + def __repr__(self): + return "NotSelfDisplaying" + + def _ipython_display_(self): + raise NotImplementedError + + save_enabled = f.ipython_display_formatter.enabled + f.ipython_display_formatter.enabled = True + + yes = SelfDisplaying() + no = NotSelfDisplaying() + + d, md = f.format(no) + nt.assert_equal(d, {'text/plain': repr(no)}) + nt.assert_equal(md, {}) + nt.assert_equal(catcher, []) + + d, md = f.format(yes) + nt.assert_equal(d, {}) + nt.assert_equal(md, {}) + nt.assert_equal(catcher, [yes]) + + f.ipython_display_formatter.enabled = save_enabled + + +def test_json_as_string_deprecated(): + class JSONString(object): + def _repr_json_(self): + return '{}' + + f = JSONFormatter() + with warnings.catch_warnings(record=True) as w: + d = f(JSONString()) + nt.assert_equal(d, {}) + nt.assert_equal(len(w), 1) + + +def test_repr_mime(): + class HasReprMime(object): + def _repr_mimebundle_(self, include=None, exclude=None): + return { + 'application/json+test.v2': { + 'x': 'y' + }, + 'plain/text' : '', + 'image/png' : 'i-overwrite' + } + + def _repr_png_(self): + return 'should-be-overwritten' + def _repr_html_(self): + return 'hi!' + + f = get_ipython().display_formatter + html_f = f.formatters['text/html'] + save_enabled = html_f.enabled + html_f.enabled = True + obj = HasReprMime() + d, md = f.format(obj) + html_f.enabled = save_enabled + + nt.assert_equal(sorted(d), ['application/json+test.v2', + 'image/png', + 'plain/text', + 'text/html', + 'text/plain']) + nt.assert_equal(md, {}) + + d, md = f.format(obj, include={'image/png'}) + nt.assert_equal(list(d.keys()), ['image/png'], + 'Include should filter out even things from repr_mimebundle') + nt.assert_equal(d['image/png'], 'i-overwrite', '_repr_mimebundle_ take precedence') + + + +def test_pass_correct_include_exclude(): + class Tester(object): + + def __init__(self, include=None, exclude=None): + self.include = include + self.exclude = exclude + + def _repr_mimebundle_(self, include, exclude, **kwargs): + if include and (include != self.include): + raise ValueError('include got modified: display() may be broken.') + if exclude and (exclude != self.exclude): + raise ValueError('exclude got modified: display() may be broken.') + + return None + + include = {'a', 'b', 'c'} + exclude = {'c', 'e' , 'f'} + + f = get_ipython().display_formatter + f.format(Tester(include=include, exclude=exclude), include=include, exclude=exclude) + f.format(Tester(exclude=exclude), exclude=exclude) + f.format(Tester(include=include), include=include) + + +def test_repr_mime_meta(): + class HasReprMimeMeta(object): + def _repr_mimebundle_(self, include=None, exclude=None): + data = { + 'image/png': 'base64-image-data', + } + metadata = { + 'image/png': { + 'width': 5, + 'height': 10, + } + } + return (data, metadata) + + f = get_ipython().display_formatter + obj = HasReprMimeMeta() + d, md = f.format(obj) + nt.assert_equal(sorted(d), ['image/png', 'text/plain']) + nt.assert_equal(md, { + 'image/png': { + 'width': 5, + 'height': 10, + } + }) + +def test_repr_mime_failure(): + class BadReprMime(object): + def _repr_mimebundle_(self, include=None, exclude=None): + raise RuntimeError + + f = get_ipython().display_formatter + obj = BadReprMime() + d, md = f.format(obj) + nt.assert_in('text/plain', d) diff --git a/.venv/lib/python3.8/site-packages/IPython/core/tests/test_handlers.py b/.venv/lib/python3.8/site-packages/IPython/core/tests/test_handlers.py new file mode 100644 index 00000000..19248177 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/IPython/core/tests/test_handlers.py @@ -0,0 +1,94 @@ +"""Tests for input handlers. +""" +#----------------------------------------------------------------------------- +# Module imports +#----------------------------------------------------------------------------- + +# third party +import nose.tools as nt + +# our own packages +from IPython.core import autocall +from IPython.testing import tools as tt + +#----------------------------------------------------------------------------- +# Globals +#----------------------------------------------------------------------------- + +# Get the public instance of IPython + +failures = [] +num_tests = 0 + +#----------------------------------------------------------------------------- +# Test functions +#----------------------------------------------------------------------------- + +class CallableIndexable(object): + def __getitem__(self, idx): return True + def __call__(self, *args, **kws): return True + + +class Autocallable(autocall.IPyAutocall): + def __call__(self): + return "called" + + +def run(tests): + """Loop through a list of (pre, post) inputs, where pre is the string + handed to ipython, and post is how that string looks after it's been + transformed (i.e. ipython's notion of _i)""" + tt.check_pairs(ip.prefilter_manager.prefilter_lines, tests) + + +def test_handlers(): + call_idx = CallableIndexable() + ip.user_ns['call_idx'] = call_idx + + # For many of the below, we're also checking that leading whitespace + # turns off the esc char, which it should unless there is a continuation + # line. + run( + [('"no change"', '"no change"'), # normal + (u"lsmagic", "get_ipython().run_line_magic('lsmagic', '')"), # magic + #("a = b # PYTHON-MODE", '_i'), # emacs -- avoids _in cache + ]) + + # Objects which are instances of IPyAutocall are *always* autocalled + autocallable = Autocallable() + ip.user_ns['autocallable'] = autocallable + + # auto + ip.magic('autocall 0') + # Only explicit escapes or instances of IPyAutocallable should get + # expanded + run([ + ('len "abc"', 'len "abc"'), + ('autocallable', 'autocallable()'), + # Don't add extra brackets (gh-1117) + ('autocallable()', 'autocallable()'), + ]) + ip.magic('autocall 1') + run([ + ('len "abc"', 'len("abc")'), + ('len "abc";', 'len("abc");'), # ; is special -- moves out of parens + # Autocall is turned off if first arg is [] and the object + # is both callable and indexable. Like so: + ('len [1,2]', 'len([1,2])'), # len doesn't support __getitem__... + ('call_idx [1]', 'call_idx [1]'), # call_idx *does*.. + ('call_idx 1', 'call_idx(1)'), + ('len', 'len'), # only at 2 does it auto-call on single args + ]) + ip.magic('autocall 2') + run([ + ('len "abc"', 'len("abc")'), + ('len "abc";', 'len("abc");'), + ('len [1,2]', 'len([1,2])'), + ('call_idx [1]', 'call_idx [1]'), + ('call_idx 1', 'call_idx(1)'), + # This is what's different: + ('len', 'len()'), # only at 2 does it auto-call on single args + ]) + ip.magic('autocall 1') + + nt.assert_equal(failures, []) diff --git a/.venv/lib/python3.8/site-packages/IPython/core/tests/test_history.py b/.venv/lib/python3.8/site-packages/IPython/core/tests/test_history.py new file mode 100644 index 00000000..f4f080dc --- /dev/null +++ b/.venv/lib/python3.8/site-packages/IPython/core/tests/test_history.py @@ -0,0 +1,214 @@ +# coding: utf-8 +"""Tests for the IPython tab-completion machinery. +""" +#----------------------------------------------------------------------------- +# Module imports +#----------------------------------------------------------------------------- + +# stdlib +import io +import os +import sys +import tempfile +from datetime import datetime +import sqlite3 + +# third party +import nose.tools as nt + +# our own packages +from traitlets.config.loader import Config +from IPython.utils.tempdir import TemporaryDirectory +from IPython.core.history import HistoryManager, extract_hist_ranges +from IPython.testing.decorators import skipif + +def test_proper_default_encoding(): + nt.assert_equal(sys.getdefaultencoding(), "utf-8") + +@skipif(sqlite3.sqlite_version_info > (3,24,0)) +def test_history(): + ip = get_ipython() + with TemporaryDirectory() as tmpdir: + hist_manager_ori = ip.history_manager + hist_file = os.path.join(tmpdir, 'history.sqlite') + try: + ip.history_manager = HistoryManager(shell=ip, hist_file=hist_file) + hist = [u'a=1', u'def f():\n test = 1\n return test', u"b='€Æ¾÷ß'"] + for i, h in enumerate(hist, start=1): + ip.history_manager.store_inputs(i, h) + + ip.history_manager.db_log_output = True + # Doesn't match the input, but we'll just check it's stored. + ip.history_manager.output_hist_reprs[3] = "spam" + ip.history_manager.store_output(3) + + nt.assert_equal(ip.history_manager.input_hist_raw, [''] + hist) + + # Detailed tests for _get_range_session + grs = ip.history_manager._get_range_session + nt.assert_equal(list(grs(start=2,stop=-1)), list(zip([0], [2], hist[1:-1]))) + nt.assert_equal(list(grs(start=-2)), list(zip([0,0], [2,3], hist[-2:]))) + nt.assert_equal(list(grs(output=True)), list(zip([0,0,0], [1,2,3], zip(hist, [None,None,'spam'])))) + + # Check whether specifying a range beyond the end of the current + # session results in an error (gh-804) + ip.magic('%hist 2-500') + + # Check that we can write non-ascii characters to a file + ip.magic("%%hist -f %s" % os.path.join(tmpdir, "test1")) + ip.magic("%%hist -pf %s" % os.path.join(tmpdir, "test2")) + ip.magic("%%hist -nf %s" % os.path.join(tmpdir, "test3")) + ip.magic("%%save %s 1-10" % os.path.join(tmpdir, "test4")) + + # New session + ip.history_manager.reset() + newcmds = [u"z=5", + u"class X(object):\n pass", + u"k='p'", + u"z=5"] + for i, cmd in enumerate(newcmds, start=1): + ip.history_manager.store_inputs(i, cmd) + gothist = ip.history_manager.get_range(start=1, stop=4) + nt.assert_equal(list(gothist), list(zip([0,0,0],[1,2,3], newcmds))) + # Previous session: + gothist = ip.history_manager.get_range(-1, 1, 4) + nt.assert_equal(list(gothist), list(zip([1,1,1],[1,2,3], hist))) + + newhist = [(2, i, c) for (i, c) in enumerate(newcmds, 1)] + + # Check get_hist_tail + gothist = ip.history_manager.get_tail(5, output=True, + include_latest=True) + expected = [(1, 3, (hist[-1], "spam"))] \ + + [(s, n, (c, None)) for (s, n, c) in newhist] + nt.assert_equal(list(gothist), expected) + + gothist = ip.history_manager.get_tail(2) + expected = newhist[-3:-1] + nt.assert_equal(list(gothist), expected) + + # Check get_hist_search + + gothist = ip.history_manager.search("*test*") + nt.assert_equal(list(gothist), [(1,2,hist[1])] ) + + gothist = ip.history_manager.search("*=*") + nt.assert_equal(list(gothist), + [(1, 1, hist[0]), + (1, 2, hist[1]), + (1, 3, hist[2]), + newhist[0], + newhist[2], + newhist[3]]) + + gothist = ip.history_manager.search("*=*", n=4) + nt.assert_equal(list(gothist), + [(1, 3, hist[2]), + newhist[0], + newhist[2], + newhist[3]]) + + gothist = ip.history_manager.search("*=*", unique=True) + nt.assert_equal(list(gothist), + [(1, 1, hist[0]), + (1, 2, hist[1]), + (1, 3, hist[2]), + newhist[2], + newhist[3]]) + + gothist = ip.history_manager.search("*=*", unique=True, n=3) + nt.assert_equal(list(gothist), + [(1, 3, hist[2]), + newhist[2], + newhist[3]]) + + gothist = ip.history_manager.search("b*", output=True) + nt.assert_equal(list(gothist), [(1,3,(hist[2],"spam"))] ) + + # Cross testing: check that magic %save can get previous session. + testfilename = os.path.realpath(os.path.join(tmpdir, "test.py")) + ip.magic("save " + testfilename + " ~1/1-3") + with io.open(testfilename, encoding='utf-8') as testfile: + nt.assert_equal(testfile.read(), + u"# coding: utf-8\n" + u"\n".join(hist)+u"\n") + + # Duplicate line numbers - check that it doesn't crash, and + # gets a new session + ip.history_manager.store_inputs(1, "rogue") + ip.history_manager.writeout_cache() + nt.assert_equal(ip.history_manager.session_number, 3) + finally: + # Ensure saving thread is shut down before we try to clean up the files + ip.history_manager.save_thread.stop() + # Forcibly close database rather than relying on garbage collection + ip.history_manager.db.close() + # Restore history manager + ip.history_manager = hist_manager_ori + + +def test_extract_hist_ranges(): + instr = "1 2/3 ~4/5-6 ~4/7-~4/9 ~9/2-~7/5 ~10/" + expected = [(0, 1, 2), # 0 == current session + (2, 3, 4), + (-4, 5, 7), + (-4, 7, 10), + (-9, 2, None), # None == to end + (-8, 1, None), + (-7, 1, 6), + (-10, 1, None)] + actual = list(extract_hist_ranges(instr)) + nt.assert_equal(actual, expected) + +def test_magic_rerun(): + """Simple test for %rerun (no args -> rerun last line)""" + ip = get_ipython() + ip.run_cell("a = 10", store_history=True) + ip.run_cell("a += 1", store_history=True) + nt.assert_equal(ip.user_ns["a"], 11) + ip.run_cell("%rerun", store_history=True) + nt.assert_equal(ip.user_ns["a"], 12) + +def test_timestamp_type(): + ip = get_ipython() + info = ip.history_manager.get_session_info() + nt.assert_true(isinstance(info[1], datetime)) + +def test_hist_file_config(): + cfg = Config() + tfile = tempfile.NamedTemporaryFile(delete=False) + cfg.HistoryManager.hist_file = tfile.name + try: + hm = HistoryManager(shell=get_ipython(), config=cfg) + nt.assert_equal(hm.hist_file, cfg.HistoryManager.hist_file) + finally: + try: + os.remove(tfile.name) + except OSError: + # same catch as in testing.tools.TempFileMixin + # On Windows, even though we close the file, we still can't + # delete it. I have no clue why + pass + +def test_histmanager_disabled(): + """Ensure that disabling the history manager doesn't create a database.""" + cfg = Config() + cfg.HistoryAccessor.enabled = False + + ip = get_ipython() + with TemporaryDirectory() as tmpdir: + hist_manager_ori = ip.history_manager + hist_file = os.path.join(tmpdir, 'history.sqlite') + cfg.HistoryManager.hist_file = hist_file + try: + ip.history_manager = HistoryManager(shell=ip, config=cfg) + hist = [u'a=1', u'def f():\n test = 1\n return test', u"b='€Æ¾÷ß'"] + for i, h in enumerate(hist, start=1): + ip.history_manager.store_inputs(i, h) + nt.assert_equal(ip.history_manager.input_hist_raw, [''] + hist) + ip.history_manager.reset() + ip.history_manager.end_session() + finally: + ip.history_manager = hist_manager_ori + + # hist_file should not be created + nt.assert_false(os.path.exists(hist_file)) diff --git a/.venv/lib/python3.8/site-packages/IPython/core/tests/test_hooks.py b/.venv/lib/python3.8/site-packages/IPython/core/tests/test_hooks.py new file mode 100644 index 00000000..35d3f315 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/IPython/core/tests/test_hooks.py @@ -0,0 +1,80 @@ +# -*- coding: utf-8 -*- +"""Tests for CommandChainDispatcher.""" + + +#----------------------------------------------------------------------------- +# Imports +#----------------------------------------------------------------------------- + +import nose.tools as nt +from IPython.core.error import TryNext +from IPython.core.hooks import CommandChainDispatcher + +#----------------------------------------------------------------------------- +# Local utilities +#----------------------------------------------------------------------------- + +# Define two classes, one which succeeds and one which raises TryNext. Each +# sets the attribute `called` to True when it is called. +class Okay(object): + def __init__(self, message): + self.message = message + self.called = False + def __call__(self): + self.called = True + return self.message + +class Fail(object): + def __init__(self, message): + self.message = message + self.called = False + def __call__(self): + self.called = True + raise TryNext(self.message) + +#----------------------------------------------------------------------------- +# Test functions +#----------------------------------------------------------------------------- + +def test_command_chain_dispatcher_ff(): + """Test two failing hooks""" + fail1 = Fail(u'fail1') + fail2 = Fail(u'fail2') + dp = CommandChainDispatcher([(0, fail1), + (10, fail2)]) + + try: + dp() + except TryNext as e: + nt.assert_equal(str(e), u'fail2') + else: + assert False, "Expected exception was not raised." + + nt.assert_true(fail1.called) + nt.assert_true(fail2.called) + +def test_command_chain_dispatcher_fofo(): + """Test a mixture of failing and succeeding hooks.""" + fail1 = Fail(u'fail1') + fail2 = Fail(u'fail2') + okay1 = Okay(u'okay1') + okay2 = Okay(u'okay2') + + dp = CommandChainDispatcher([(0, fail1), + # (5, okay1), # add this later + (10, fail2), + (15, okay2)]) + dp.add(okay1, 5) + + nt.assert_equal(dp(), u'okay1') + + nt.assert_true(fail1.called) + nt.assert_true(okay1.called) + nt.assert_false(fail2.called) + nt.assert_false(okay2.called) + +def test_command_chain_dispatcher_eq_priority(): + okay1 = Okay(u'okay1') + okay2 = Okay(u'okay2') + dp = CommandChainDispatcher([(1, okay1)]) + dp.add(okay2, 1) diff --git a/.venv/lib/python3.8/site-packages/IPython/core/tests/test_imports.py b/.venv/lib/python3.8/site-packages/IPython/core/tests/test_imports.py new file mode 100644 index 00000000..7aa278fb --- /dev/null +++ b/.venv/lib/python3.8/site-packages/IPython/core/tests/test_imports.py @@ -0,0 +1,52 @@ +# encoding: utf-8 + +def test_import_completer(): + from IPython.core import completer + +def test_import_crashhandler(): + from IPython.core import crashhandler + +def test_import_debugger(): + from IPython.core import debugger + +def test_import_excolors(): + from IPython.core import excolors + +def test_import_history(): + from IPython.core import history + +def test_import_hooks(): + from IPython.core import hooks + +def test_import_getipython(): + from IPython.core import getipython + +def test_import_interactiveshell(): + from IPython.core import interactiveshell + +def test_import_logger(): + from IPython.core import logger + +def test_import_macro(): + from IPython.core import macro + +def test_import_magic(): + from IPython.core import magic + +def test_import_oinspect(): + from IPython.core import oinspect + +def test_import_prefilter(): + from IPython.core import prefilter + +def test_import_prompts(): + from IPython.core import prompts + +def test_import_release(): + from IPython.core import release + +def test_import_ultratb(): + from IPython.core import ultratb + +def test_import_usage(): + from IPython.core import usage diff --git a/.venv/lib/python3.8/site-packages/IPython/core/tests/test_inputsplitter.py b/.venv/lib/python3.8/site-packages/IPython/core/tests/test_inputsplitter.py new file mode 100644 index 00000000..a39943ae --- /dev/null +++ b/.venv/lib/python3.8/site-packages/IPython/core/tests/test_inputsplitter.py @@ -0,0 +1,639 @@ +# -*- coding: utf-8 -*- +"""Tests for the inputsplitter module.""" + + +# Copyright (c) IPython Development Team. +# Distributed under the terms of the Modified BSD License. + +import unittest +import sys + +import nose.tools as nt + +from IPython.core import inputsplitter as isp +from IPython.core.inputtransformer import InputTransformer +from IPython.core.tests.test_inputtransformer import syntax, syntax_ml +from IPython.testing import tools as tt + +#----------------------------------------------------------------------------- +# Semi-complete examples (also used as tests) +#----------------------------------------------------------------------------- + +# Note: at the bottom, there's a slightly more complete version of this that +# can be useful during development of code here. + +def mini_interactive_loop(input_func): + """Minimal example of the logic of an interactive interpreter loop. + + This serves as an example, and it is used by the test system with a fake + raw_input that simulates interactive input.""" + + from IPython.core.inputsplitter import InputSplitter + + isp = InputSplitter() + # In practice, this input loop would be wrapped in an outside loop to read + # input indefinitely, until some exit/quit command was issued. Here we + # only illustrate the basic inner loop. + while isp.push_accepts_more(): + indent = ' '*isp.get_indent_spaces() + prompt = '>>> ' + indent + line = indent + input_func(prompt) + isp.push(line) + + # Here we just return input so we can use it in a test suite, but a real + # interpreter would instead send it for execution somewhere. + src = isp.source_reset() + #print 'Input source was:\n', src # dbg + return src + +#----------------------------------------------------------------------------- +# Test utilities, just for local use +#----------------------------------------------------------------------------- + +def assemble(block): + """Assemble a block into multi-line sub-blocks.""" + return ['\n'.join(sub_block)+'\n' for sub_block in block] + + +def pseudo_input(lines): + """Return a function that acts like raw_input but feeds the input list.""" + ilines = iter(lines) + def raw_in(prompt): + try: + return next(ilines) + except StopIteration: + return '' + return raw_in + +#----------------------------------------------------------------------------- +# Tests +#----------------------------------------------------------------------------- +def test_spaces(): + tests = [('', 0), + (' ', 1), + ('\n', 0), + (' \n', 1), + ('x', 0), + (' x', 1), + (' x',2), + (' x',4), + # Note: tabs are counted as a single whitespace! + ('\tx', 1), + ('\t x', 2), + ] + tt.check_pairs(isp.num_ini_spaces, tests) + + +def test_remove_comments(): + tests = [('text', 'text'), + ('text # comment', 'text '), + ('text # comment\n', 'text \n'), + ('text # comment \n', 'text \n'), + ('line # c \nline\n','line \nline\n'), + ('line # c \nline#c2 \nline\nline #c\n\n', + 'line \nline\nline\nline \n\n'), + ] + tt.check_pairs(isp.remove_comments, tests) + + +def test_get_input_encoding(): + encoding = isp.get_input_encoding() + nt.assert_true(isinstance(encoding, str)) + # simple-minded check that at least encoding a simple string works with the + # encoding we got. + nt.assert_equal(u'test'.encode(encoding), b'test') + + +class NoInputEncodingTestCase(unittest.TestCase): + def setUp(self): + self.old_stdin = sys.stdin + class X: pass + fake_stdin = X() + sys.stdin = fake_stdin + + def test(self): + # Verify that if sys.stdin has no 'encoding' attribute we do the right + # thing + enc = isp.get_input_encoding() + self.assertEqual(enc, 'ascii') + + def tearDown(self): + sys.stdin = self.old_stdin + + +class InputSplitterTestCase(unittest.TestCase): + def setUp(self): + self.isp = isp.InputSplitter() + + def test_reset(self): + isp = self.isp + isp.push('x=1') + isp.reset() + self.assertEqual(isp._buffer, []) + self.assertEqual(isp.get_indent_spaces(), 0) + self.assertEqual(isp.source, '') + self.assertEqual(isp.code, None) + self.assertEqual(isp._is_complete, False) + + def test_source(self): + self.isp._store('1') + self.isp._store('2') + self.assertEqual(self.isp.source, '1\n2\n') + self.assertEqual(len(self.isp._buffer)>0, True) + self.assertEqual(self.isp.source_reset(), '1\n2\n') + self.assertEqual(self.isp._buffer, []) + self.assertEqual(self.isp.source, '') + + def test_indent(self): + isp = self.isp # shorthand + isp.push('x=1') + self.assertEqual(isp.get_indent_spaces(), 0) + isp.push('if 1:\n x=1') + self.assertEqual(isp.get_indent_spaces(), 4) + isp.push('y=2\n') + self.assertEqual(isp.get_indent_spaces(), 0) + + def test_indent2(self): + isp = self.isp + isp.push('if 1:') + self.assertEqual(isp.get_indent_spaces(), 4) + isp.push(' x=1') + self.assertEqual(isp.get_indent_spaces(), 4) + # Blank lines shouldn't change the indent level + isp.push(' '*2) + self.assertEqual(isp.get_indent_spaces(), 4) + + def test_indent3(self): + isp = self.isp + # When a multiline statement contains parens or multiline strings, we + # shouldn't get confused. + isp.push("if 1:") + isp.push(" x = (1+\n 2)") + self.assertEqual(isp.get_indent_spaces(), 4) + + def test_indent4(self): + isp = self.isp + # whitespace after ':' should not screw up indent level + isp.push('if 1: \n x=1') + self.assertEqual(isp.get_indent_spaces(), 4) + isp.push('y=2\n') + self.assertEqual(isp.get_indent_spaces(), 0) + isp.push('if 1:\t\n x=1') + self.assertEqual(isp.get_indent_spaces(), 4) + isp.push('y=2\n') + self.assertEqual(isp.get_indent_spaces(), 0) + + def test_dedent_pass(self): + isp = self.isp # shorthand + # should NOT cause dedent + isp.push('if 1:\n passes = 5') + self.assertEqual(isp.get_indent_spaces(), 4) + isp.push('if 1:\n pass') + self.assertEqual(isp.get_indent_spaces(), 0) + isp.push('if 1:\n pass ') + self.assertEqual(isp.get_indent_spaces(), 0) + + def test_dedent_break(self): + isp = self.isp # shorthand + # should NOT cause dedent + isp.push('while 1:\n breaks = 5') + self.assertEqual(isp.get_indent_spaces(), 4) + isp.push('while 1:\n break') + self.assertEqual(isp.get_indent_spaces(), 0) + isp.push('while 1:\n break ') + self.assertEqual(isp.get_indent_spaces(), 0) + + def test_dedent_continue(self): + isp = self.isp # shorthand + # should NOT cause dedent + isp.push('while 1:\n continues = 5') + self.assertEqual(isp.get_indent_spaces(), 4) + isp.push('while 1:\n continue') + self.assertEqual(isp.get_indent_spaces(), 0) + isp.push('while 1:\n continue ') + self.assertEqual(isp.get_indent_spaces(), 0) + + def test_dedent_raise(self): + isp = self.isp # shorthand + # should NOT cause dedent + isp.push('if 1:\n raised = 4') + self.assertEqual(isp.get_indent_spaces(), 4) + isp.push('if 1:\n raise TypeError()') + self.assertEqual(isp.get_indent_spaces(), 0) + isp.push('if 1:\n raise') + self.assertEqual(isp.get_indent_spaces(), 0) + isp.push('if 1:\n raise ') + self.assertEqual(isp.get_indent_spaces(), 0) + + def test_dedent_return(self): + isp = self.isp # shorthand + # should NOT cause dedent + isp.push('if 1:\n returning = 4') + self.assertEqual(isp.get_indent_spaces(), 4) + isp.push('if 1:\n return 5 + 493') + self.assertEqual(isp.get_indent_spaces(), 0) + isp.push('if 1:\n return') + self.assertEqual(isp.get_indent_spaces(), 0) + isp.push('if 1:\n return ') + self.assertEqual(isp.get_indent_spaces(), 0) + isp.push('if 1:\n return(0)') + self.assertEqual(isp.get_indent_spaces(), 0) + + def test_push(self): + isp = self.isp + self.assertEqual(isp.push('x=1'), True) + + def test_push2(self): + isp = self.isp + self.assertEqual(isp.push('if 1:'), False) + for line in [' x=1', '# a comment', ' y=2']: + print(line) + self.assertEqual(isp.push(line), True) + + def test_push3(self): + isp = self.isp + isp.push('if True:') + isp.push(' a = 1') + self.assertEqual(isp.push('b = [1,'), False) + + def test_push_accepts_more(self): + isp = self.isp + isp.push('x=1') + self.assertEqual(isp.push_accepts_more(), False) + + def test_push_accepts_more2(self): + isp = self.isp + isp.push('if 1:') + self.assertEqual(isp.push_accepts_more(), True) + isp.push(' x=1') + self.assertEqual(isp.push_accepts_more(), True) + isp.push('') + self.assertEqual(isp.push_accepts_more(), False) + + def test_push_accepts_more3(self): + isp = self.isp + isp.push("x = (2+\n3)") + self.assertEqual(isp.push_accepts_more(), False) + + def test_push_accepts_more4(self): + isp = self.isp + # When a multiline statement contains parens or multiline strings, we + # shouldn't get confused. + # FIXME: we should be able to better handle de-dents in statements like + # multiline strings and multiline expressions (continued with \ or + # parens). Right now we aren't handling the indentation tracking quite + # correctly with this, though in practice it may not be too much of a + # problem. We'll need to see. + isp.push("if 1:") + isp.push(" x = (2+") + isp.push(" 3)") + self.assertEqual(isp.push_accepts_more(), True) + isp.push(" y = 3") + self.assertEqual(isp.push_accepts_more(), True) + isp.push('') + self.assertEqual(isp.push_accepts_more(), False) + + def test_push_accepts_more5(self): + isp = self.isp + isp.push('try:') + isp.push(' a = 5') + isp.push('except:') + isp.push(' raise') + # We want to be able to add an else: block at this point, so it should + # wait for a blank line. + self.assertEqual(isp.push_accepts_more(), True) + + def test_continuation(self): + isp = self.isp + isp.push("import os, \\") + self.assertEqual(isp.push_accepts_more(), True) + isp.push("sys") + self.assertEqual(isp.push_accepts_more(), False) + + def test_syntax_error(self): + isp = self.isp + # Syntax errors immediately produce a 'ready' block, so the invalid + # Python can be sent to the kernel for evaluation with possible ipython + # special-syntax conversion. + isp.push('run foo') + self.assertEqual(isp.push_accepts_more(), False) + + def test_unicode(self): + self.isp.push(u"Pérez") + self.isp.push(u'\xc3\xa9') + self.isp.push(u"u'\xc3\xa9'") + + def test_line_continuation(self): + """ Test issue #2108.""" + isp = self.isp + # A blank line after a line continuation should not accept more + isp.push("1 \\\n\n") + self.assertEqual(isp.push_accepts_more(), False) + # Whitespace after a \ is a SyntaxError. The only way to test that + # here is to test that push doesn't accept more (as with + # test_syntax_error() above). + isp.push(r"1 \ ") + self.assertEqual(isp.push_accepts_more(), False) + # Even if the line is continuable (c.f. the regular Python + # interpreter) + isp.push(r"(1 \ ") + self.assertEqual(isp.push_accepts_more(), False) + + def test_check_complete(self): + isp = self.isp + self.assertEqual(isp.check_complete("a = 1"), ('complete', None)) + self.assertEqual(isp.check_complete("for a in range(5):"), ('incomplete', 4)) + self.assertEqual(isp.check_complete("raise = 2"), ('invalid', None)) + self.assertEqual(isp.check_complete("a = [1,\n2,"), ('incomplete', 0)) + self.assertEqual(isp.check_complete("def a():\n x=1\n global x"), ('invalid', None)) + +class InteractiveLoopTestCase(unittest.TestCase): + """Tests for an interactive loop like a python shell. + """ + def check_ns(self, lines, ns): + """Validate that the given input lines produce the resulting namespace. + + Note: the input lines are given exactly as they would be typed in an + auto-indenting environment, as mini_interactive_loop above already does + auto-indenting and prepends spaces to the input. + """ + src = mini_interactive_loop(pseudo_input(lines)) + test_ns = {} + exec(src, test_ns) + # We can't check that the provided ns is identical to the test_ns, + # because Python fills test_ns with extra keys (copyright, etc). But + # we can check that the given dict is *contained* in test_ns + for k,v in ns.items(): + self.assertEqual(test_ns[k], v) + + def test_simple(self): + self.check_ns(['x=1'], dict(x=1)) + + def test_simple2(self): + self.check_ns(['if 1:', 'x=2'], dict(x=2)) + + def test_xy(self): + self.check_ns(['x=1; y=2'], dict(x=1, y=2)) + + def test_abc(self): + self.check_ns(['if 1:','a=1','b=2','c=3'], dict(a=1, b=2, c=3)) + + def test_multi(self): + self.check_ns(['x =(1+','1+','2)'], dict(x=4)) + + +class IPythonInputTestCase(InputSplitterTestCase): + """By just creating a new class whose .isp is a different instance, we + re-run the same test battery on the new input splitter. + + In addition, this runs the tests over the syntax and syntax_ml dicts that + were tested by individual functions, as part of the OO interface. + + It also makes some checks on the raw buffer storage. + """ + + def setUp(self): + self.isp = isp.IPythonInputSplitter() + + def test_syntax(self): + """Call all single-line syntax tests from the main object""" + isp = self.isp + for example in syntax.values(): + for raw, out_t in example: + if raw.startswith(' '): + continue + + isp.push(raw+'\n') + out_raw = isp.source_raw + out = isp.source_reset() + self.assertEqual(out.rstrip(), out_t, + tt.pair_fail_msg.format("inputsplitter",raw, out_t, out)) + self.assertEqual(out_raw.rstrip(), raw.rstrip()) + + def test_syntax_multiline(self): + isp = self.isp + for example in syntax_ml.values(): + for line_pairs in example: + out_t_parts = [] + raw_parts = [] + for lraw, out_t_part in line_pairs: + if out_t_part is not None: + out_t_parts.append(out_t_part) + + if lraw is not None: + isp.push(lraw) + raw_parts.append(lraw) + + out_raw = isp.source_raw + out = isp.source_reset() + out_t = '\n'.join(out_t_parts).rstrip() + raw = '\n'.join(raw_parts).rstrip() + self.assertEqual(out.rstrip(), out_t) + self.assertEqual(out_raw.rstrip(), raw) + + def test_syntax_multiline_cell(self): + isp = self.isp + for example in syntax_ml.values(): + + out_t_parts = [] + for line_pairs in example: + raw = '\n'.join(r for r, _ in line_pairs if r is not None) + out_t = '\n'.join(t for _,t in line_pairs if t is not None) + out = isp.transform_cell(raw) + # Match ignoring trailing whitespace + self.assertEqual(out.rstrip(), out_t.rstrip()) + + def test_cellmagic_preempt(self): + isp = self.isp + for raw, name, line, cell in [ + ("%%cellm a\nIn[1]:", u'cellm', u'a', u'In[1]:'), + ("%%cellm \nline\n>>> hi", u'cellm', u'', u'line\n>>> hi'), + (">>> %%cellm \nline\n>>> hi", u'cellm', u'', u'line\nhi'), + ("%%cellm \n>>> hi", u'cellm', u'', u'>>> hi'), + ("%%cellm \nline1\nline2", u'cellm', u'', u'line1\nline2'), + ("%%cellm \nline1\\\\\nline2", u'cellm', u'', u'line1\\\\\nline2'), + ]: + expected = "get_ipython().run_cell_magic(%r, %r, %r)" % ( + name, line, cell + ) + out = isp.transform_cell(raw) + self.assertEqual(out.rstrip(), expected.rstrip()) + + def test_multiline_passthrough(self): + isp = self.isp + class CommentTransformer(InputTransformer): + def __init__(self): + self._lines = [] + + def push(self, line): + self._lines.append(line + '#') + + def reset(self): + text = '\n'.join(self._lines) + self._lines = [] + return text + + isp.physical_line_transforms.insert(0, CommentTransformer()) + + for raw, expected in [ + ("a=5", "a=5#"), + ("%ls foo", "get_ipython().run_line_magic(%r, %r)" % (u'ls', u'foo#')), + ("!ls foo\n%ls bar", "get_ipython().system(%r)\nget_ipython().run_line_magic(%r, %r)" % ( + u'ls foo#', u'ls', u'bar#' + )), + ("1\n2\n3\n%ls foo\n4\n5", "1#\n2#\n3#\nget_ipython().run_line_magic(%r, %r)\n4#\n5#" % (u'ls', u'foo#')), + ]: + out = isp.transform_cell(raw) + self.assertEqual(out.rstrip(), expected.rstrip()) + +#----------------------------------------------------------------------------- +# Main - use as a script, mostly for developer experiments +#----------------------------------------------------------------------------- + +if __name__ == '__main__': + # A simple demo for interactive experimentation. This code will not get + # picked up by any test suite. + from IPython.core.inputsplitter import IPythonInputSplitter + + # configure here the syntax to use, prompt and whether to autoindent + #isp, start_prompt = InputSplitter(), '>>> ' + isp, start_prompt = IPythonInputSplitter(), 'In> ' + + autoindent = True + #autoindent = False + + try: + while True: + prompt = start_prompt + while isp.push_accepts_more(): + indent = ' '*isp.get_indent_spaces() + if autoindent: + line = indent + input(prompt+indent) + else: + line = input(prompt) + isp.push(line) + prompt = '... ' + + # Here we just return input so we can use it in a test suite, but a + # real interpreter would instead send it for execution somewhere. + #src = isp.source; raise EOFError # dbg + raw = isp.source_raw + src = isp.source_reset() + print('Input source was:\n', src) + print('Raw source was:\n', raw) + except EOFError: + print('Bye') + +# Tests for cell magics support + +def test_last_blank(): + nt.assert_false(isp.last_blank('')) + nt.assert_false(isp.last_blank('abc')) + nt.assert_false(isp.last_blank('abc\n')) + nt.assert_false(isp.last_blank('abc\na')) + + nt.assert_true(isp.last_blank('\n')) + nt.assert_true(isp.last_blank('\n ')) + nt.assert_true(isp.last_blank('abc\n ')) + nt.assert_true(isp.last_blank('abc\n\n')) + nt.assert_true(isp.last_blank('abc\nd\n\n')) + nt.assert_true(isp.last_blank('abc\nd\ne\n\n')) + nt.assert_true(isp.last_blank('abc \n \n \n\n')) + + +def test_last_two_blanks(): + nt.assert_false(isp.last_two_blanks('')) + nt.assert_false(isp.last_two_blanks('abc')) + nt.assert_false(isp.last_two_blanks('abc\n')) + nt.assert_false(isp.last_two_blanks('abc\n\na')) + nt.assert_false(isp.last_two_blanks('abc\n \n')) + nt.assert_false(isp.last_two_blanks('abc\n\n')) + + nt.assert_true(isp.last_two_blanks('\n\n')) + nt.assert_true(isp.last_two_blanks('\n\n ')) + nt.assert_true(isp.last_two_blanks('\n \n')) + nt.assert_true(isp.last_two_blanks('abc\n\n ')) + nt.assert_true(isp.last_two_blanks('abc\n\n\n')) + nt.assert_true(isp.last_two_blanks('abc\n\n \n')) + nt.assert_true(isp.last_two_blanks('abc\n\n \n ')) + nt.assert_true(isp.last_two_blanks('abc\n\n \n \n')) + nt.assert_true(isp.last_two_blanks('abc\nd\n\n\n')) + nt.assert_true(isp.last_two_blanks('abc\nd\ne\nf\n\n\n')) + + +class CellMagicsCommon(object): + + def test_whole_cell(self): + src = "%%cellm line\nbody\n" + out = self.sp.transform_cell(src) + ref = "get_ipython().run_cell_magic('cellm', 'line', 'body')\n" + nt.assert_equal(out, ref) + + def test_cellmagic_help(self): + self.sp.push('%%cellm?') + nt.assert_false(self.sp.push_accepts_more()) + + def tearDown(self): + self.sp.reset() + + +class CellModeCellMagics(CellMagicsCommon, unittest.TestCase): + sp = isp.IPythonInputSplitter(line_input_checker=False) + + def test_incremental(self): + sp = self.sp + sp.push('%%cellm firstline\n') + nt.assert_true(sp.push_accepts_more()) #1 + sp.push('line2\n') + nt.assert_true(sp.push_accepts_more()) #2 + sp.push('\n') + # This should accept a blank line and carry on until the cell is reset + nt.assert_true(sp.push_accepts_more()) #3 + + def test_no_strip_coding(self): + src = '\n'.join([ + '%%writefile foo.py', + '# coding: utf-8', + 'print(u"üñîçø∂é")', + ]) + out = self.sp.transform_cell(src) + nt.assert_in('# coding: utf-8', out) + + +class LineModeCellMagics(CellMagicsCommon, unittest.TestCase): + sp = isp.IPythonInputSplitter(line_input_checker=True) + + def test_incremental(self): + sp = self.sp + sp.push('%%cellm line2\n') + nt.assert_true(sp.push_accepts_more()) #1 + sp.push('\n') + # In this case, a blank line should end the cell magic + nt.assert_false(sp.push_accepts_more()) #2 + +indentation_samples = [ + ('a = 1', 0), + ('for a in b:', 4), + ('def f():', 4), + ('def f(): #comment', 4), + ('a = ":#not a comment"', 0), + ('def f():\n a = 1', 4), + ('def f():\n return 1', 0), + ('for a in b:\n' + ' if a < 0:' + ' continue', 3), + ('a = {', 4), + ('a = {\n' + ' 1,', 5), + ('b = """123', 0), + ('', 0), + ('def f():\n pass', 0), + ('class Bar:\n def f():\n pass', 4), + ('class Bar:\n def f():\n raise', 4), +] + +def test_find_next_indent(): + for code, exp in indentation_samples: + res = isp.find_next_indent(code) + msg = "{!r} != {!r} (expected)\n Code: {!r}".format(res, exp, code) + assert res == exp, msg diff --git a/.venv/lib/python3.8/site-packages/IPython/core/tests/test_inputtransformer.py b/.venv/lib/python3.8/site-packages/IPython/core/tests/test_inputtransformer.py new file mode 100644 index 00000000..0d97fd4d --- /dev/null +++ b/.venv/lib/python3.8/site-packages/IPython/core/tests/test_inputtransformer.py @@ -0,0 +1,495 @@ +import tokenize +import nose.tools as nt + +from IPython.testing import tools as tt +from IPython.utils import py3compat +u_fmt = py3compat.u_format + +from IPython.core import inputtransformer as ipt + +def transform_and_reset(transformer): + transformer = transformer() + def transform(inp): + try: + return transformer.push(inp) + finally: + transformer.reset() + + return transform + +# Transformer tests +def transform_checker(tests, transformer, **kwargs): + """Utility to loop over test inputs""" + transformer = transformer(**kwargs) + try: + for inp, tr in tests: + if inp is None: + out = transformer.reset() + else: + out = transformer.push(inp) + nt.assert_equal(out, tr) + finally: + transformer.reset() + +# Data for all the syntax tests in the form of lists of pairs of +# raw/transformed input. We store it here as a global dict so that we can use +# it both within single-function tests and also to validate the behavior of the +# larger objects + +syntax = \ + dict(assign_system = + [(i,py3compat.u_format(o)) for i,o in \ + [(u'a =! ls', "a = get_ipython().getoutput('ls')"), + (u'b = !ls', "b = get_ipython().getoutput('ls')"), + (u'c= !ls', "c = get_ipython().getoutput('ls')"), + (u'd == !ls', u'd == !ls'), # Invalid syntax, but we leave == alone. + ('x=1', 'x=1'), # normal input is unmodified + (' ',' '), # blank lines are kept intact + # Tuple unpacking + (u"a, b = !echo 'a\\nb'", u"a, b = get_ipython().getoutput(\"echo 'a\\\\nb'\")"), + (u"a,= !echo 'a'", u"a, = get_ipython().getoutput(\"echo 'a'\")"), + (u"a, *bc = !echo 'a\\nb\\nc'", u"a, *bc = get_ipython().getoutput(\"echo 'a\\\\nb\\\\nc'\")"), + # Tuple unpacking with regular Python expressions, not our syntax. + (u"a, b = range(2)", u"a, b = range(2)"), + (u"a, = range(1)", u"a, = range(1)"), + (u"a, *bc = range(3)", u"a, *bc = range(3)"), + ]], + + assign_magic = + [(i,py3compat.u_format(o)) for i,o in \ + [(u'a =% who', "a = get_ipython().run_line_magic('who', '')"), + (u'b = %who', "b = get_ipython().run_line_magic('who', '')"), + (u'c= %ls', "c = get_ipython().run_line_magic('ls', '')"), + (u'd == %ls', u'd == %ls'), # Invalid syntax, but we leave == alone. + ('x=1', 'x=1'), # normal input is unmodified + (' ',' '), # blank lines are kept intact + (u"a, b = %foo", u"a, b = get_ipython().run_line_magic('foo', '')"), + ]], + + classic_prompt = + [('>>> x=1', 'x=1'), + ('x=1', 'x=1'), # normal input is unmodified + (' ', ' '), # blank lines are kept intact + ], + + ipy_prompt = + [('In [1]: x=1', 'x=1'), + ('x=1', 'x=1'), # normal input is unmodified + (' ',' '), # blank lines are kept intact + ], + + # Tests for the escape transformer to leave normal code alone + escaped_noesc = + [ (' ', ' '), + ('x=1', 'x=1'), + ], + + # System calls + escaped_shell = + [(i,py3compat.u_format(o)) for i,o in \ + [ (u'!ls', "get_ipython().system('ls')"), + # Double-escape shell, this means to capture the output of the + # subprocess and return it + (u'!!ls', "get_ipython().getoutput('ls')"), + ]], + + # Help/object info + escaped_help = + [(i,py3compat.u_format(o)) for i,o in \ + [ (u'?', 'get_ipython().show_usage()'), + (u'?x1', "get_ipython().run_line_magic('pinfo', 'x1')"), + (u'??x2', "get_ipython().run_line_magic('pinfo2', 'x2')"), + (u'?a.*s', "get_ipython().run_line_magic('psearch', 'a.*s')"), + (u'?%hist1', "get_ipython().run_line_magic('pinfo', '%hist1')"), + (u'?%%hist2', "get_ipython().run_line_magic('pinfo', '%%hist2')"), + (u'?abc = qwe', "get_ipython().run_line_magic('pinfo', 'abc')"), + ]], + + end_help = + [(i,py3compat.u_format(o)) for i,o in \ + [ (u'x3?', "get_ipython().run_line_magic('pinfo', 'x3')"), + (u'x4??', "get_ipython().run_line_magic('pinfo2', 'x4')"), + (u'%hist1?', "get_ipython().run_line_magic('pinfo', '%hist1')"), + (u'%hist2??', "get_ipython().run_line_magic('pinfo2', '%hist2')"), + (u'%%hist3?', "get_ipython().run_line_magic('pinfo', '%%hist3')"), + (u'%%hist4??', "get_ipython().run_line_magic('pinfo2', '%%hist4')"), + (u'π.foo?', "get_ipython().run_line_magic('pinfo', 'π.foo')"), + (u'f*?', "get_ipython().run_line_magic('psearch', 'f*')"), + (u'ax.*aspe*?', "get_ipython().run_line_magic('psearch', 'ax.*aspe*')"), + (u'a = abc?', "get_ipython().set_next_input('a = abc');" + "get_ipython().run_line_magic('pinfo', 'abc')"), + (u'a = abc.qe??', "get_ipython().set_next_input('a = abc.qe');" + "get_ipython().run_line_magic('pinfo2', 'abc.qe')"), + (u'a = *.items?', "get_ipython().set_next_input('a = *.items');" + "get_ipython().run_line_magic('psearch', '*.items')"), + (u'plot(a?', "get_ipython().set_next_input('plot(a');" + "get_ipython().run_line_magic('pinfo', 'a')"), + (u'a*2 #comment?', 'a*2 #comment?'), + ]], + + # Explicit magic calls + escaped_magic = + [(i,py3compat.u_format(o)) for i,o in \ + [ (u'%cd', "get_ipython().run_line_magic('cd', '')"), + (u'%cd /home', "get_ipython().run_line_magic('cd', '/home')"), + # Backslashes need to be escaped. + (u'%cd C:\\User', "get_ipython().run_line_magic('cd', 'C:\\\\User')"), + (u' %magic', " get_ipython().run_line_magic('magic', '')"), + ]], + + # Quoting with separate arguments + escaped_quote = + [ (',f', 'f("")'), + (',f x', 'f("x")'), + (' ,f y', ' f("y")'), + (',f a b', 'f("a", "b")'), + ], + + # Quoting with single argument + escaped_quote2 = + [ (';f', 'f("")'), + (';f x', 'f("x")'), + (' ;f y', ' f("y")'), + (';f a b', 'f("a b")'), + ], + + # Simply apply parens + escaped_paren = + [ ('/f', 'f()'), + ('/f x', 'f(x)'), + (' /f y', ' f(y)'), + ('/f a b', 'f(a, b)'), + ], + + # Check that we transform prompts before other transforms + mixed = + [(i,py3compat.u_format(o)) for i,o in \ + [ (u'In [1]: %lsmagic', "get_ipython().run_line_magic('lsmagic', '')"), + (u'>>> %lsmagic', "get_ipython().run_line_magic('lsmagic', '')"), + (u'In [2]: !ls', "get_ipython().system('ls')"), + (u'In [3]: abs?', "get_ipython().run_line_magic('pinfo', 'abs')"), + (u'In [4]: b = %who', "b = get_ipython().run_line_magic('who', '')"), + ]], + ) + +# multiline syntax examples. Each of these should be a list of lists, with +# each entry itself having pairs of raw/transformed input. The union (with +# '\n'.join() of the transformed inputs is what the splitter should produce +# when fed the raw lines one at a time via push. +syntax_ml = \ + dict(classic_prompt = + [ [('>>> for i in range(10):','for i in range(10):'), + ('... print i',' print i'), + ('... ', ''), + ], + [('>>> a="""','a="""'), + ('... 123"""','123"""'), + ], + [('a="""','a="""'), + ('... 123','123'), + ('... 456"""','456"""'), + ], + [('a="""','a="""'), + ('>>> 123','123'), + ('... 456"""','456"""'), + ], + [('a="""','a="""'), + ('123','123'), + ('... 456"""','... 456"""'), + ], + [('....__class__','....__class__'), + ], + [('a=5', 'a=5'), + ('...', ''), + ], + [('>>> def f(x):', 'def f(x):'), + ('...', ''), + ('... return x', ' return x'), + ], + [('board = """....', 'board = """....'), + ('....', '....'), + ('...."""', '...."""'), + ], + ], + + ipy_prompt = + [ [('In [24]: for i in range(10):','for i in range(10):'), + (' ....: print i',' print i'), + (' ....: ', ''), + ], + [('In [24]: for i in range(10):','for i in range(10):'), + # Qt console prompts expand with spaces, not dots + (' ...: print i',' print i'), + (' ...: ', ''), + ], + [('In [24]: for i in range(10):','for i in range(10):'), + # Sometimes whitespace preceding '...' has been removed + ('...: print i',' print i'), + ('...: ', ''), + ], + [('In [24]: for i in range(10):','for i in range(10):'), + # Space after last continuation prompt has been removed (issue #6674) + ('...: print i',' print i'), + ('...:', ''), + ], + [('In [2]: a="""','a="""'), + (' ...: 123"""','123"""'), + ], + [('a="""','a="""'), + (' ...: 123','123'), + (' ...: 456"""','456"""'), + ], + [('a="""','a="""'), + ('In [1]: 123','123'), + (' ...: 456"""','456"""'), + ], + [('a="""','a="""'), + ('123','123'), + (' ...: 456"""',' ...: 456"""'), + ], + ], + + multiline_datastructure_prompt = + [ [('>>> a = [1,','a = [1,'), + ('... 2]','2]'), + ], + ], + + multiline_datastructure = + [ [('b = ("%s"', None), + ('# comment', None), + ('%foo )', 'b = ("%s"\n# comment\n%foo )'), + ], + ], + + multiline_string = + [ [("'''foo?", None), + ("bar'''", "'''foo?\nbar'''"), + ], + ], + + leading_indent = + [ [(' print "hi"','print "hi"'), + ], + [(' for a in range(5):','for a in range(5):'), + (' a*2',' a*2'), + ], + [(' a="""','a="""'), + (' 123"""','123"""'), + ], + [('a="""','a="""'), + (' 123"""',' 123"""'), + ], + ], + + cellmagic = + [ [(u'%%foo a', None), + (None, u_fmt("get_ipython().run_cell_magic('foo', 'a', '')")), + ], + [(u'%%bar 123', None), + (u'hello', None), + (None , u_fmt("get_ipython().run_cell_magic('bar', '123', 'hello')")), + ], + [(u'a=5', 'a=5'), + (u'%%cellmagic', '%%cellmagic'), + ], + ], + + escaped = + [ [('%abc def \\', None), + ('ghi', u_fmt("get_ipython().run_line_magic('abc', 'def ghi')")), + ], + [('%abc def \\', None), + ('ghi\\', None), + (None, u_fmt("get_ipython().run_line_magic('abc', 'def ghi')")), + ], + ], + + assign_magic = + [ [(u'a = %bc de \\', None), + (u'fg', u_fmt("a = get_ipython().run_line_magic('bc', 'de fg')")), + ], + [(u'a = %bc de \\', None), + (u'fg\\', None), + (None, u_fmt("a = get_ipython().run_line_magic('bc', 'de fg')")), + ], + ], + + assign_system = + [ [(u'a = !bc de \\', None), + (u'fg', u_fmt("a = get_ipython().getoutput('bc de fg')")), + ], + [(u'a = !bc de \\', None), + (u'fg\\', None), + (None, u_fmt("a = get_ipython().getoutput('bc de fg')")), + ], + ], + ) + + +def test_assign_system(): + tt.check_pairs(transform_and_reset(ipt.assign_from_system), syntax['assign_system']) + +def test_assign_magic(): + tt.check_pairs(transform_and_reset(ipt.assign_from_magic), syntax['assign_magic']) + +def test_classic_prompt(): + tt.check_pairs(transform_and_reset(ipt.classic_prompt), syntax['classic_prompt']) + for example in syntax_ml['classic_prompt']: + transform_checker(example, ipt.classic_prompt) + for example in syntax_ml['multiline_datastructure_prompt']: + transform_checker(example, ipt.classic_prompt) + + # Check that we don't transform the second line if the first is obviously + # IPython syntax + transform_checker([ + (u'%foo', '%foo'), + (u'>>> bar', '>>> bar'), + ], ipt.classic_prompt) + + +def test_ipy_prompt(): + tt.check_pairs(transform_and_reset(ipt.ipy_prompt), syntax['ipy_prompt']) + for example in syntax_ml['ipy_prompt']: + transform_checker(example, ipt.ipy_prompt) + + # Check that we don't transform the second line if we're inside a cell magic + transform_checker([ + (u'%%foo', '%%foo'), + (u'In [1]: bar', 'In [1]: bar'), + ], ipt.ipy_prompt) + +def test_assemble_logical_lines(): + tests = \ + [ [(u"a = \\", None), + (u"123", u"a = 123"), + ], + [(u"a = \\", None), # Test resetting when within a multi-line string + (u"12 *\\", None), + (None, u"a = 12 *"), + ], + [(u"# foo\\", u"# foo\\"), # Comments can't be continued like this + ], + ] + for example in tests: + transform_checker(example, ipt.assemble_logical_lines) + +def test_assemble_python_lines(): + tests = \ + [ [(u"a = '''", None), + (u"abc'''", u"a = '''\nabc'''"), + ], + [(u"a = '''", None), # Test resetting when within a multi-line string + (u"def", None), + (None, u"a = '''\ndef"), + ], + [(u"a = [1,", None), + (u"2]", u"a = [1,\n2]"), + ], + [(u"a = [1,", None), # Test resetting when within a multi-line string + (u"2,", None), + (None, u"a = [1,\n2,"), + ], + [(u"a = '''", None), # Test line continuation within a multi-line string + (u"abc\\", None), + (u"def", None), + (u"'''", u"a = '''\nabc\\\ndef\n'''"), + ], + ] + syntax_ml['multiline_datastructure'] + for example in tests: + transform_checker(example, ipt.assemble_python_lines) + + +def test_help_end(): + tt.check_pairs(transform_and_reset(ipt.help_end), syntax['end_help']) + +def test_escaped_noesc(): + tt.check_pairs(transform_and_reset(ipt.escaped_commands), syntax['escaped_noesc']) + + +def test_escaped_shell(): + tt.check_pairs(transform_and_reset(ipt.escaped_commands), syntax['escaped_shell']) + + +def test_escaped_help(): + tt.check_pairs(transform_and_reset(ipt.escaped_commands), syntax['escaped_help']) + + +def test_escaped_magic(): + tt.check_pairs(transform_and_reset(ipt.escaped_commands), syntax['escaped_magic']) + + +def test_escaped_quote(): + tt.check_pairs(transform_and_reset(ipt.escaped_commands), syntax['escaped_quote']) + + +def test_escaped_quote2(): + tt.check_pairs(transform_and_reset(ipt.escaped_commands), syntax['escaped_quote2']) + + +def test_escaped_paren(): + tt.check_pairs(transform_and_reset(ipt.escaped_commands), syntax['escaped_paren']) + + +def test_cellmagic(): + for example in syntax_ml['cellmagic']: + transform_checker(example, ipt.cellmagic) + + line_example = [(u'%%bar 123', None), + (u'hello', None), + (u'' , u_fmt("get_ipython().run_cell_magic('bar', '123', 'hello')")), + ] + transform_checker(line_example, ipt.cellmagic, end_on_blank_line=True) + +def test_has_comment(): + tests = [('text', False), + ('text #comment', True), + ('text #comment\n', True), + ('#comment', True), + ('#comment\n', True), + ('a = "#string"', False), + ('a = "#string" # comment', True), + ('a #comment not "string"', True), + ] + tt.check_pairs(ipt.has_comment, tests) + +@ipt.TokenInputTransformer.wrap +def decistmt(tokens): + """Substitute Decimals for floats in a string of statements. + + Based on an example from the tokenize module docs. + """ + result = [] + for toknum, tokval, _, _, _ in tokens: + if toknum == tokenize.NUMBER and '.' in tokval: # replace NUMBER tokens + for newtok in [ + (tokenize.NAME, 'Decimal'), + (tokenize.OP, '('), + (tokenize.STRING, repr(tokval)), + (tokenize.OP, ')') + ]: + yield newtok + else: + yield (toknum, tokval) + + + +def test_token_input_transformer(): + tests = [(u'1.2', u_fmt(u"Decimal ('1.2')")), + (u'"1.2"', u'"1.2"'), + ] + tt.check_pairs(transform_and_reset(decistmt), tests) + ml_tests = \ + [ [(u"a = 1.2; b = '''x", None), + (u"y'''", u_fmt(u"a =Decimal ('1.2');b ='''x\ny'''")), + ], + [(u"a = [1.2,", None), + (u"3]", u_fmt(u"a =[Decimal ('1.2'),\n3 ]")), + ], + [(u"a = '''foo", None), # Test resetting when within a multi-line string + (u"bar", None), + (None, u"a = '''foo\nbar"), + ], + ] + for example in ml_tests: + transform_checker(example, decistmt) diff --git a/.venv/lib/python3.8/site-packages/IPython/core/tests/test_inputtransformer2.py b/.venv/lib/python3.8/site-packages/IPython/core/tests/test_inputtransformer2.py new file mode 100644 index 00000000..61f183cb --- /dev/null +++ b/.venv/lib/python3.8/site-packages/IPython/core/tests/test_inputtransformer2.py @@ -0,0 +1,337 @@ +"""Tests for the token-based transformers in IPython.core.inputtransformer2 + +Line-based transformers are the simpler ones; token-based transformers are +more complex. See test_inputtransformer2_line for tests for line-based +transformations. +""" +import nose.tools as nt +import string + +from IPython.core import inputtransformer2 as ipt2 +from IPython.core.inputtransformer2 import make_tokens_by_line, _find_assign_op + +from textwrap import dedent + +MULTILINE_MAGIC = ("""\ +a = f() +%foo \\ +bar +g() +""".splitlines(keepends=True), (2, 0), """\ +a = f() +get_ipython().run_line_magic('foo', ' bar') +g() +""".splitlines(keepends=True)) + +INDENTED_MAGIC = ("""\ +for a in range(5): + %ls +""".splitlines(keepends=True), (2, 4), """\ +for a in range(5): + get_ipython().run_line_magic('ls', '') +""".splitlines(keepends=True)) + +CRLF_MAGIC = ([ + "a = f()\n", + "%ls\r\n", + "g()\n" +], (2, 0), [ + "a = f()\n", + "get_ipython().run_line_magic('ls', '')\n", + "g()\n" +]) + +MULTILINE_MAGIC_ASSIGN = ("""\ +a = f() +b = %foo \\ + bar +g() +""".splitlines(keepends=True), (2, 4), """\ +a = f() +b = get_ipython().run_line_magic('foo', ' bar') +g() +""".splitlines(keepends=True)) + +MULTILINE_SYSTEM_ASSIGN = ("""\ +a = f() +b = !foo \\ + bar +g() +""".splitlines(keepends=True), (2, 4), """\ +a = f() +b = get_ipython().getoutput('foo bar') +g() +""".splitlines(keepends=True)) + +##### + +MULTILINE_SYSTEM_ASSIGN_AFTER_DEDENT = ("""\ +def test(): + for i in range(1): + print(i) + res =! ls +""".splitlines(keepends=True), (4, 7), '''\ +def test(): + for i in range(1): + print(i) + res =get_ipython().getoutput(\' ls\') +'''.splitlines(keepends=True)) + +###### + +AUTOCALL_QUOTE = ( + [",f 1 2 3\n"], (1, 0), + ['f("1", "2", "3")\n'] +) + +AUTOCALL_QUOTE2 = ( + [";f 1 2 3\n"], (1, 0), + ['f("1 2 3")\n'] +) + +AUTOCALL_PAREN = ( + ["/f 1 2 3\n"], (1, 0), + ['f(1, 2, 3)\n'] +) + +SIMPLE_HELP = ( + ["foo?\n"], (1, 0), + ["get_ipython().run_line_magic('pinfo', 'foo')\n"] +) + +DETAILED_HELP = ( + ["foo??\n"], (1, 0), + ["get_ipython().run_line_magic('pinfo2', 'foo')\n"] +) + +MAGIC_HELP = ( + ["%foo?\n"], (1, 0), + ["get_ipython().run_line_magic('pinfo', '%foo')\n"] +) + +HELP_IN_EXPR = ( + ["a = b + c?\n"], (1, 0), + ["get_ipython().set_next_input('a = b + c');" + "get_ipython().run_line_magic('pinfo', 'c')\n"] +) + +HELP_CONTINUED_LINE = ("""\ +a = \\ +zip? +""".splitlines(keepends=True), (1, 0), +[r"get_ipython().set_next_input('a = \\\nzip');get_ipython().run_line_magic('pinfo', 'zip')" + "\n"] +) + +HELP_MULTILINE = ("""\ +(a, +b) = zip? +""".splitlines(keepends=True), (1, 0), +[r"get_ipython().set_next_input('(a,\nb) = zip');get_ipython().run_line_magic('pinfo', 'zip')" + "\n"] +) + +HELP_UNICODE = ( + ["π.foo?\n"], (1, 0), + ["get_ipython().run_line_magic('pinfo', 'π.foo')\n"] +) + + +def null_cleanup_transformer(lines): + """ + A cleanup transform that returns an empty list. + """ + return [] + +def check_make_token_by_line_never_ends_empty(): + """ + Check that not sequence of single or double characters ends up leading to en empty list of tokens + """ + from string import printable + for c in printable: + nt.assert_not_equal(make_tokens_by_line(c)[-1], []) + for k in printable: + nt.assert_not_equal(make_tokens_by_line(c+k)[-1], []) + +def check_find(transformer, case, match=True): + sample, expected_start, _ = case + tbl = make_tokens_by_line(sample) + res = transformer.find(tbl) + if match: + # start_line is stored 0-indexed, expected values are 1-indexed + nt.assert_equal((res.start_line+1, res.start_col), expected_start) + return res + else: + nt.assert_is(res, None) + +def check_transform(transformer_cls, case): + lines, start, expected = case + transformer = transformer_cls(start) + nt.assert_equal(transformer.transform(lines), expected) + +def test_continued_line(): + lines = MULTILINE_MAGIC_ASSIGN[0] + nt.assert_equal(ipt2.find_end_of_continued_line(lines, 1), 2) + + nt.assert_equal(ipt2.assemble_continued_line(lines, (1, 5), 2), "foo bar") + +def test_find_assign_magic(): + check_find(ipt2.MagicAssign, MULTILINE_MAGIC_ASSIGN) + check_find(ipt2.MagicAssign, MULTILINE_SYSTEM_ASSIGN, match=False) + check_find(ipt2.MagicAssign, MULTILINE_SYSTEM_ASSIGN_AFTER_DEDENT, match=False) + +def test_transform_assign_magic(): + check_transform(ipt2.MagicAssign, MULTILINE_MAGIC_ASSIGN) + +def test_find_assign_system(): + check_find(ipt2.SystemAssign, MULTILINE_SYSTEM_ASSIGN) + check_find(ipt2.SystemAssign, MULTILINE_SYSTEM_ASSIGN_AFTER_DEDENT) + check_find(ipt2.SystemAssign, (["a = !ls\n"], (1, 5), None)) + check_find(ipt2.SystemAssign, (["a=!ls\n"], (1, 2), None)) + check_find(ipt2.SystemAssign, MULTILINE_MAGIC_ASSIGN, match=False) + +def test_transform_assign_system(): + check_transform(ipt2.SystemAssign, MULTILINE_SYSTEM_ASSIGN) + check_transform(ipt2.SystemAssign, MULTILINE_SYSTEM_ASSIGN_AFTER_DEDENT) + +def test_find_magic_escape(): + check_find(ipt2.EscapedCommand, MULTILINE_MAGIC) + check_find(ipt2.EscapedCommand, INDENTED_MAGIC) + check_find(ipt2.EscapedCommand, MULTILINE_MAGIC_ASSIGN, match=False) + +def test_transform_magic_escape(): + check_transform(ipt2.EscapedCommand, MULTILINE_MAGIC) + check_transform(ipt2.EscapedCommand, INDENTED_MAGIC) + check_transform(ipt2.EscapedCommand, CRLF_MAGIC) + +def test_find_autocalls(): + for case in [AUTOCALL_QUOTE, AUTOCALL_QUOTE2, AUTOCALL_PAREN]: + print("Testing %r" % case[0]) + check_find(ipt2.EscapedCommand, case) + +def test_transform_autocall(): + for case in [AUTOCALL_QUOTE, AUTOCALL_QUOTE2, AUTOCALL_PAREN]: + print("Testing %r" % case[0]) + check_transform(ipt2.EscapedCommand, case) + +def test_find_help(): + for case in [SIMPLE_HELP, DETAILED_HELP, MAGIC_HELP, HELP_IN_EXPR]: + check_find(ipt2.HelpEnd, case) + + tf = check_find(ipt2.HelpEnd, HELP_CONTINUED_LINE) + nt.assert_equal(tf.q_line, 1) + nt.assert_equal(tf.q_col, 3) + + tf = check_find(ipt2.HelpEnd, HELP_MULTILINE) + nt.assert_equal(tf.q_line, 1) + nt.assert_equal(tf.q_col, 8) + + # ? in a comment does not trigger help + check_find(ipt2.HelpEnd, (["foo # bar?\n"], None, None), match=False) + # Nor in a string + check_find(ipt2.HelpEnd, (["foo = '''bar?\n"], None, None), match=False) + +def test_transform_help(): + tf = ipt2.HelpEnd((1, 0), (1, 9)) + nt.assert_equal(tf.transform(HELP_IN_EXPR[0]), HELP_IN_EXPR[2]) + + tf = ipt2.HelpEnd((1, 0), (2, 3)) + nt.assert_equal(tf.transform(HELP_CONTINUED_LINE[0]), HELP_CONTINUED_LINE[2]) + + tf = ipt2.HelpEnd((1, 0), (2, 8)) + nt.assert_equal(tf.transform(HELP_MULTILINE[0]), HELP_MULTILINE[2]) + + tf = ipt2.HelpEnd((1, 0), (1, 0)) + nt.assert_equal(tf.transform(HELP_UNICODE[0]), HELP_UNICODE[2]) + +def test_find_assign_op_dedent(): + """ + be careful that empty token like dedent are not counted as parens + """ + class Tk: + def __init__(self, s): + self.string = s + + nt.assert_equal(_find_assign_op([Tk(s) for s in ('','a','=','b')]), 2) + nt.assert_equal(_find_assign_op([Tk(s) for s in ('','(', 'a','=','b', ')', '=' ,'5')]), 6) + +def test_check_complete(): + cc = ipt2.TransformerManager().check_complete + nt.assert_equal(cc("a = 1"), ('complete', None)) + nt.assert_equal(cc("for a in range(5):"), ('incomplete', 4)) + nt.assert_equal(cc("for a in range(5):\n if a > 0:"), ('incomplete', 8)) + nt.assert_equal(cc("raise = 2"), ('invalid', None)) + nt.assert_equal(cc("a = [1,\n2,"), ('incomplete', 0)) + nt.assert_equal(cc(")"), ('incomplete', 0)) + nt.assert_equal(cc("\\\r\n"), ('incomplete', 0)) + nt.assert_equal(cc("a = '''\n hi"), ('incomplete', 3)) + nt.assert_equal(cc("def a():\n x=1\n global x"), ('invalid', None)) + nt.assert_equal(cc("a \\ "), ('invalid', None)) # Nothing allowed after backslash + nt.assert_equal(cc("1\\\n+2"), ('complete', None)) + nt.assert_equal(cc("exit"), ('complete', None)) + + example = dedent(""" + if True: + a=1""" ) + + nt.assert_equal(cc(example), ('incomplete', 4)) + nt.assert_equal(cc(example+'\n'), ('complete', None)) + nt.assert_equal(cc(example+'\n '), ('complete', None)) + + # no need to loop on all the letters/numbers. + short = '12abAB'+string.printable[62:] + for c in short: + # test does not raise: + cc(c) + for k in short: + cc(c+k) + + nt.assert_equal(cc("def f():\n x=0\n \\\n "), ('incomplete', 2)) + +def test_check_complete_II(): + """ + Test that multiple line strings are properly handled. + + Separate test function for convenience + + """ + cc = ipt2.TransformerManager().check_complete + nt.assert_equal(cc('''def foo():\n """'''), ('incomplete', 4)) + + +def test_null_cleanup_transformer(): + manager = ipt2.TransformerManager() + manager.cleanup_transforms.insert(0, null_cleanup_transformer) + assert manager.transform_cell("") == "" + + + + +def test_side_effects_I(): + count = 0 + def counter(lines): + nonlocal count + count += 1 + return lines + + counter.has_side_effects = True + + manager = ipt2.TransformerManager() + manager.cleanup_transforms.insert(0, counter) + assert manager.check_complete("a=1\n") == ('complete', None) + assert count == 0 + + + + +def test_side_effects_II(): + count = 0 + def counter(lines): + nonlocal count + count += 1 + return lines + + counter.has_side_effects = True + + manager = ipt2.TransformerManager() + manager.line_transforms.insert(0, counter) + assert manager.check_complete("b=1\n") == ('complete', None) + assert count == 0 diff --git a/.venv/lib/python3.8/site-packages/IPython/core/tests/test_inputtransformer2_line.py b/.venv/lib/python3.8/site-packages/IPython/core/tests/test_inputtransformer2_line.py new file mode 100644 index 00000000..263bbd9e --- /dev/null +++ b/.venv/lib/python3.8/site-packages/IPython/core/tests/test_inputtransformer2_line.py @@ -0,0 +1,126 @@ +"""Tests for the line-based transformers in IPython.core.inputtransformer2 + +Line-based transformers are the simpler ones; token-based transformers are +more complex. See test_inputtransformer2 for tests for token-based transformers. +""" +import nose.tools as nt + +from IPython.core import inputtransformer2 as ipt2 + +CELL_MAGIC = ("""\ +%%foo arg +body 1 +body 2 +""", """\ +get_ipython().run_cell_magic('foo', 'arg', 'body 1\\nbody 2\\n') +""") + +def test_cell_magic(): + for sample, expected in [CELL_MAGIC]: + nt.assert_equal(ipt2.cell_magic(sample.splitlines(keepends=True)), + expected.splitlines(keepends=True)) + +CLASSIC_PROMPT = ("""\ +>>> for a in range(5): +... print(a) +""", """\ +for a in range(5): + print(a) +""") + +CLASSIC_PROMPT_L2 = ("""\ +for a in range(5): +... print(a) +... print(a ** 2) +""", """\ +for a in range(5): + print(a) + print(a ** 2) +""") + +def test_classic_prompt(): + for sample, expected in [CLASSIC_PROMPT, CLASSIC_PROMPT_L2]: + nt.assert_equal(ipt2.classic_prompt(sample.splitlines(keepends=True)), + expected.splitlines(keepends=True)) + +IPYTHON_PROMPT = ("""\ +In [1]: for a in range(5): + ...: print(a) +""", """\ +for a in range(5): + print(a) +""") + +IPYTHON_PROMPT_L2 = ("""\ +for a in range(5): + ...: print(a) + ...: print(a ** 2) +""", """\ +for a in range(5): + print(a) + print(a ** 2) +""") + +def test_ipython_prompt(): + for sample, expected in [IPYTHON_PROMPT, IPYTHON_PROMPT_L2]: + nt.assert_equal(ipt2.ipython_prompt(sample.splitlines(keepends=True)), + expected.splitlines(keepends=True)) + +INDENT_SPACES = ("""\ + if True: + a = 3 +""", """\ +if True: + a = 3 +""") + +INDENT_TABS = ("""\ +\tif True: +\t\tb = 4 +""", """\ +if True: +\tb = 4 +""") + +def test_leading_indent(): + for sample, expected in [INDENT_SPACES, INDENT_TABS]: + nt.assert_equal(ipt2.leading_indent(sample.splitlines(keepends=True)), + expected.splitlines(keepends=True)) + +LEADING_EMPTY_LINES = ("""\ + \t + +if True: + a = 3 + +b = 4 +""", """\ +if True: + a = 3 + +b = 4 +""") + +ONLY_EMPTY_LINES = ("""\ + \t + +""", """\ + \t + +""") + +def test_leading_empty_lines(): + for sample, expected in [LEADING_EMPTY_LINES, ONLY_EMPTY_LINES]: + nt.assert_equal( + ipt2.leading_empty_lines(sample.splitlines(keepends=True)), + expected.splitlines(keepends=True)) + +CRLF_MAGIC = ([ + "%%ls\r\n" +], [ + "get_ipython().run_cell_magic('ls', '', '')\n" +]) + +def test_crlf_magic(): + for sample, expected in [CRLF_MAGIC]: + nt.assert_equal(ipt2.cell_magic(sample), expected) \ No newline at end of file diff --git a/.venv/lib/python3.8/site-packages/IPython/core/tests/test_interactiveshell.py b/.venv/lib/python3.8/site-packages/IPython/core/tests/test_interactiveshell.py new file mode 100644 index 00000000..951b843e --- /dev/null +++ b/.venv/lib/python3.8/site-packages/IPython/core/tests/test_interactiveshell.py @@ -0,0 +1,1042 @@ +# -*- coding: utf-8 -*- +"""Tests for the key interactiveshell module. + +Historically the main classes in interactiveshell have been under-tested. This +module should grow as many single-method tests as possible to trap many of the +recurring bugs we seem to encounter with high-level interaction. +""" + +# Copyright (c) IPython Development Team. +# Distributed under the terms of the Modified BSD License. + +import asyncio +import ast +import os +import signal +import shutil +import sys +import tempfile +import unittest +from unittest import mock + +from os.path import join + +import nose.tools as nt + +from IPython.core.error import InputRejected +from IPython.core.inputtransformer import InputTransformer +from IPython.core import interactiveshell +from IPython.testing.decorators import ( + skipif, skip_win32, onlyif_unicode_paths, onlyif_cmds_exist, +) +from IPython.testing import tools as tt +from IPython.utils.process import find_cmd + +#----------------------------------------------------------------------------- +# Globals +#----------------------------------------------------------------------------- +# This is used by every single test, no point repeating it ad nauseam + +#----------------------------------------------------------------------------- +# Tests +#----------------------------------------------------------------------------- + +class DerivedInterrupt(KeyboardInterrupt): + pass + +class InteractiveShellTestCase(unittest.TestCase): + def test_naked_string_cells(self): + """Test that cells with only naked strings are fully executed""" + # First, single-line inputs + ip.run_cell('"a"\n') + self.assertEqual(ip.user_ns['_'], 'a') + # And also multi-line cells + ip.run_cell('"""a\nb"""\n') + self.assertEqual(ip.user_ns['_'], 'a\nb') + + def test_run_empty_cell(self): + """Just make sure we don't get a horrible error with a blank + cell of input. Yes, I did overlook that.""" + old_xc = ip.execution_count + res = ip.run_cell('') + self.assertEqual(ip.execution_count, old_xc) + self.assertEqual(res.execution_count, None) + + def test_run_cell_multiline(self): + """Multi-block, multi-line cells must execute correctly. + """ + src = '\n'.join(["x=1", + "y=2", + "if 1:", + " x += 1", + " y += 1",]) + res = ip.run_cell(src) + self.assertEqual(ip.user_ns['x'], 2) + self.assertEqual(ip.user_ns['y'], 3) + self.assertEqual(res.success, True) + self.assertEqual(res.result, None) + + def test_multiline_string_cells(self): + "Code sprinkled with multiline strings should execute (GH-306)" + ip.run_cell('tmp=0') + self.assertEqual(ip.user_ns['tmp'], 0) + res = ip.run_cell('tmp=1;"""a\nb"""\n') + self.assertEqual(ip.user_ns['tmp'], 1) + self.assertEqual(res.success, True) + self.assertEqual(res.result, "a\nb") + + def test_dont_cache_with_semicolon(self): + "Ending a line with semicolon should not cache the returned object (GH-307)" + oldlen = len(ip.user_ns['Out']) + for cell in ['1;', '1;1;']: + res = ip.run_cell(cell, store_history=True) + newlen = len(ip.user_ns['Out']) + self.assertEqual(oldlen, newlen) + self.assertIsNone(res.result) + i = 0 + #also test the default caching behavior + for cell in ['1', '1;1']: + ip.run_cell(cell, store_history=True) + newlen = len(ip.user_ns['Out']) + i += 1 + self.assertEqual(oldlen+i, newlen) + + def test_syntax_error(self): + res = ip.run_cell("raise = 3") + self.assertIsInstance(res.error_before_exec, SyntaxError) + + def test_In_variable(self): + "Verify that In variable grows with user input (GH-284)" + oldlen = len(ip.user_ns['In']) + ip.run_cell('1;', store_history=True) + newlen = len(ip.user_ns['In']) + self.assertEqual(oldlen+1, newlen) + self.assertEqual(ip.user_ns['In'][-1],'1;') + + def test_magic_names_in_string(self): + ip.run_cell('a = """\n%exit\n"""') + self.assertEqual(ip.user_ns['a'], '\n%exit\n') + + def test_trailing_newline(self): + """test that running !(command) does not raise a SyntaxError""" + ip.run_cell('!(true)\n', False) + ip.run_cell('!(true)\n\n\n', False) + + def test_gh_597(self): + """Pretty-printing lists of objects with non-ascii reprs may cause + problems.""" + class Spam(object): + def __repr__(self): + return "\xe9"*50 + import IPython.core.formatters + f = IPython.core.formatters.PlainTextFormatter() + f([Spam(),Spam()]) + + + def test_future_flags(self): + """Check that future flags are used for parsing code (gh-777)""" + ip.run_cell('from __future__ import barry_as_FLUFL') + try: + ip.run_cell('prfunc_return_val = 1 <> 2') + assert 'prfunc_return_val' in ip.user_ns + finally: + # Reset compiler flags so we don't mess up other tests. + ip.compile.reset_compiler_flags() + + def test_can_pickle(self): + "Can we pickle objects defined interactively (GH-29)" + ip = get_ipython() + ip.reset() + ip.run_cell(("class Mylist(list):\n" + " def __init__(self,x=[]):\n" + " list.__init__(self,x)")) + ip.run_cell("w=Mylist([1,2,3])") + + from pickle import dumps + + # We need to swap in our main module - this is only necessary + # inside the test framework, because IPython puts the interactive module + # in place (but the test framework undoes this). + _main = sys.modules['__main__'] + sys.modules['__main__'] = ip.user_module + try: + res = dumps(ip.user_ns["w"]) + finally: + sys.modules['__main__'] = _main + self.assertTrue(isinstance(res, bytes)) + + def test_global_ns(self): + "Code in functions must be able to access variables outside them." + ip = get_ipython() + ip.run_cell("a = 10") + ip.run_cell(("def f(x):\n" + " return x + a")) + ip.run_cell("b = f(12)") + self.assertEqual(ip.user_ns["b"], 22) + + def test_bad_custom_tb(self): + """Check that InteractiveShell is protected from bad custom exception handlers""" + ip.set_custom_exc((IOError,), lambda etype,value,tb: 1/0) + self.assertEqual(ip.custom_exceptions, (IOError,)) + with tt.AssertPrints("Custom TB Handler failed", channel='stderr'): + ip.run_cell(u'raise IOError("foo")') + self.assertEqual(ip.custom_exceptions, ()) + + def test_bad_custom_tb_return(self): + """Check that InteractiveShell is protected from bad return types in custom exception handlers""" + ip.set_custom_exc((NameError,),lambda etype,value,tb, tb_offset=None: 1) + self.assertEqual(ip.custom_exceptions, (NameError,)) + with tt.AssertPrints("Custom TB Handler failed", channel='stderr'): + ip.run_cell(u'a=abracadabra') + self.assertEqual(ip.custom_exceptions, ()) + + def test_drop_by_id(self): + myvars = {"a":object(), "b":object(), "c": object()} + ip.push(myvars, interactive=False) + for name in myvars: + assert name in ip.user_ns, name + assert name in ip.user_ns_hidden, name + ip.user_ns['b'] = 12 + ip.drop_by_id(myvars) + for name in ["a", "c"]: + assert name not in ip.user_ns, name + assert name not in ip.user_ns_hidden, name + assert ip.user_ns['b'] == 12 + ip.reset() + + def test_var_expand(self): + ip.user_ns['f'] = u'Ca\xf1o' + self.assertEqual(ip.var_expand(u'echo $f'), u'echo Ca\xf1o') + self.assertEqual(ip.var_expand(u'echo {f}'), u'echo Ca\xf1o') + self.assertEqual(ip.var_expand(u'echo {f[:-1]}'), u'echo Ca\xf1') + self.assertEqual(ip.var_expand(u'echo {1*2}'), u'echo 2') + + self.assertEqual(ip.var_expand(u"grep x | awk '{print $1}'"), u"grep x | awk '{print $1}'") + + ip.user_ns['f'] = b'Ca\xc3\xb1o' + # This should not raise any exception: + ip.var_expand(u'echo $f') + + def test_var_expand_local(self): + """Test local variable expansion in !system and %magic calls""" + # !system + ip.run_cell('def test():\n' + ' lvar = "ttt"\n' + ' ret = !echo {lvar}\n' + ' return ret[0]\n') + res = ip.user_ns['test']() + nt.assert_in('ttt', res) + + # %magic + ip.run_cell('def makemacro():\n' + ' macroname = "macro_var_expand_locals"\n' + ' %macro {macroname} codestr\n') + ip.user_ns['codestr'] = "str(12)" + ip.run_cell('makemacro()') + nt.assert_in('macro_var_expand_locals', ip.user_ns) + + def test_var_expand_self(self): + """Test variable expansion with the name 'self', which was failing. + + See https://github.com/ipython/ipython/issues/1878#issuecomment-7698218 + """ + ip.run_cell('class cTest:\n' + ' classvar="see me"\n' + ' def test(self):\n' + ' res = !echo Variable: {self.classvar}\n' + ' return res[0]\n') + nt.assert_in('see me', ip.user_ns['cTest']().test()) + + def test_bad_var_expand(self): + """var_expand on invalid formats shouldn't raise""" + # SyntaxError + self.assertEqual(ip.var_expand(u"{'a':5}"), u"{'a':5}") + # NameError + self.assertEqual(ip.var_expand(u"{asdf}"), u"{asdf}") + # ZeroDivisionError + self.assertEqual(ip.var_expand(u"{1/0}"), u"{1/0}") + + def test_silent_postexec(self): + """run_cell(silent=True) doesn't invoke pre/post_run_cell callbacks""" + pre_explicit = mock.Mock() + pre_always = mock.Mock() + post_explicit = mock.Mock() + post_always = mock.Mock() + all_mocks = [pre_explicit, pre_always, post_explicit, post_always] + + ip.events.register('pre_run_cell', pre_explicit) + ip.events.register('pre_execute', pre_always) + ip.events.register('post_run_cell', post_explicit) + ip.events.register('post_execute', post_always) + + try: + ip.run_cell("1", silent=True) + assert pre_always.called + assert not pre_explicit.called + assert post_always.called + assert not post_explicit.called + # double-check that non-silent exec did what we expected + # silent to avoid + ip.run_cell("1") + assert pre_explicit.called + assert post_explicit.called + info, = pre_explicit.call_args[0] + result, = post_explicit.call_args[0] + self.assertEqual(info, result.info) + # check that post hooks are always called + [m.reset_mock() for m in all_mocks] + ip.run_cell("syntax error") + assert pre_always.called + assert pre_explicit.called + assert post_always.called + assert post_explicit.called + info, = pre_explicit.call_args[0] + result, = post_explicit.call_args[0] + self.assertEqual(info, result.info) + finally: + # remove post-exec + ip.events.unregister('pre_run_cell', pre_explicit) + ip.events.unregister('pre_execute', pre_always) + ip.events.unregister('post_run_cell', post_explicit) + ip.events.unregister('post_execute', post_always) + + def test_silent_noadvance(self): + """run_cell(silent=True) doesn't advance execution_count""" + ec = ip.execution_count + # silent should force store_history=False + ip.run_cell("1", store_history=True, silent=True) + + self.assertEqual(ec, ip.execution_count) + # double-check that non-silent exec did what we expected + # silent to avoid + ip.run_cell("1", store_history=True) + self.assertEqual(ec+1, ip.execution_count) + + def test_silent_nodisplayhook(self): + """run_cell(silent=True) doesn't trigger displayhook""" + d = dict(called=False) + + trap = ip.display_trap + save_hook = trap.hook + + def failing_hook(*args, **kwargs): + d['called'] = True + + try: + trap.hook = failing_hook + res = ip.run_cell("1", silent=True) + self.assertFalse(d['called']) + self.assertIsNone(res.result) + # double-check that non-silent exec did what we expected + # silent to avoid + ip.run_cell("1") + self.assertTrue(d['called']) + finally: + trap.hook = save_hook + + def test_ofind_line_magic(self): + from IPython.core.magic import register_line_magic + + @register_line_magic + def lmagic(line): + "A line magic" + + # Get info on line magic + lfind = ip._ofind('lmagic') + info = dict(found=True, isalias=False, ismagic=True, + namespace = 'IPython internal', obj= lmagic.__wrapped__, + parent = None) + nt.assert_equal(lfind, info) + + def test_ofind_cell_magic(self): + from IPython.core.magic import register_cell_magic + + @register_cell_magic + def cmagic(line, cell): + "A cell magic" + + # Get info on cell magic + find = ip._ofind('cmagic') + info = dict(found=True, isalias=False, ismagic=True, + namespace = 'IPython internal', obj= cmagic.__wrapped__, + parent = None) + nt.assert_equal(find, info) + + def test_ofind_property_with_error(self): + class A(object): + @property + def foo(self): + raise NotImplementedError() + a = A() + + found = ip._ofind('a.foo', [('locals', locals())]) + info = dict(found=True, isalias=False, ismagic=False, + namespace='locals', obj=A.foo, parent=a) + nt.assert_equal(found, info) + + def test_ofind_multiple_attribute_lookups(self): + class A(object): + @property + def foo(self): + raise NotImplementedError() + + a = A() + a.a = A() + a.a.a = A() + + found = ip._ofind('a.a.a.foo', [('locals', locals())]) + info = dict(found=True, isalias=False, ismagic=False, + namespace='locals', obj=A.foo, parent=a.a.a) + nt.assert_equal(found, info) + + def test_ofind_slotted_attributes(self): + class A(object): + __slots__ = ['foo'] + def __init__(self): + self.foo = 'bar' + + a = A() + found = ip._ofind('a.foo', [('locals', locals())]) + info = dict(found=True, isalias=False, ismagic=False, + namespace='locals', obj=a.foo, parent=a) + nt.assert_equal(found, info) + + found = ip._ofind('a.bar', [('locals', locals())]) + info = dict(found=False, isalias=False, ismagic=False, + namespace=None, obj=None, parent=a) + nt.assert_equal(found, info) + + def test_ofind_prefers_property_to_instance_level_attribute(self): + class A(object): + @property + def foo(self): + return 'bar' + a = A() + a.__dict__['foo'] = 'baz' + nt.assert_equal(a.foo, 'bar') + found = ip._ofind('a.foo', [('locals', locals())]) + nt.assert_is(found['obj'], A.foo) + + def test_custom_syntaxerror_exception(self): + called = [] + def my_handler(shell, etype, value, tb, tb_offset=None): + called.append(etype) + shell.showtraceback((etype, value, tb), tb_offset=tb_offset) + + ip.set_custom_exc((SyntaxError,), my_handler) + try: + ip.run_cell("1f") + # Check that this was called, and only once. + self.assertEqual(called, [SyntaxError]) + finally: + # Reset the custom exception hook + ip.set_custom_exc((), None) + + def test_custom_exception(self): + called = [] + def my_handler(shell, etype, value, tb, tb_offset=None): + called.append(etype) + shell.showtraceback((etype, value, tb), tb_offset=tb_offset) + + ip.set_custom_exc((ValueError,), my_handler) + try: + res = ip.run_cell("raise ValueError('test')") + # Check that this was called, and only once. + self.assertEqual(called, [ValueError]) + # Check that the error is on the result object + self.assertIsInstance(res.error_in_exec, ValueError) + finally: + # Reset the custom exception hook + ip.set_custom_exc((), None) + + def test_mktempfile(self): + filename = ip.mktempfile() + # Check that we can open the file again on Windows + with open(filename, 'w') as f: + f.write('abc') + + filename = ip.mktempfile(data='blah') + with open(filename, 'r') as f: + self.assertEqual(f.read(), 'blah') + + def test_new_main_mod(self): + # Smoketest to check that this accepts a unicode module name + name = u'jiefmw' + mod = ip.new_main_mod(u'%s.py' % name, name) + self.assertEqual(mod.__name__, name) + + def test_get_exception_only(self): + try: + raise KeyboardInterrupt + except KeyboardInterrupt: + msg = ip.get_exception_only() + self.assertEqual(msg, 'KeyboardInterrupt\n') + + try: + raise DerivedInterrupt("foo") + except KeyboardInterrupt: + msg = ip.get_exception_only() + self.assertEqual(msg, 'IPython.core.tests.test_interactiveshell.DerivedInterrupt: foo\n') + + def test_inspect_text(self): + ip.run_cell('a = 5') + text = ip.object_inspect_text('a') + self.assertIsInstance(text, str) + + def test_last_execution_result(self): + """ Check that last execution result gets set correctly (GH-10702) """ + result = ip.run_cell('a = 5; a') + self.assertTrue(ip.last_execution_succeeded) + self.assertEqual(ip.last_execution_result.result, 5) + + result = ip.run_cell('a = x_invalid_id_x') + self.assertFalse(ip.last_execution_succeeded) + self.assertFalse(ip.last_execution_result.success) + self.assertIsInstance(ip.last_execution_result.error_in_exec, NameError) + + def test_reset_aliasing(self): + """ Check that standard posix aliases work after %reset. """ + if os.name != 'posix': + return + + ip.reset() + for cmd in ('clear', 'more', 'less', 'man'): + res = ip.run_cell('%' + cmd) + self.assertEqual(res.success, True) + + +class TestSafeExecfileNonAsciiPath(unittest.TestCase): + + @onlyif_unicode_paths + def setUp(self): + self.BASETESTDIR = tempfile.mkdtemp() + self.TESTDIR = join(self.BASETESTDIR, u"åäö") + os.mkdir(self.TESTDIR) + with open(join(self.TESTDIR, u"åäötestscript.py"), "w") as sfile: + sfile.write("pass\n") + self.oldpath = os.getcwd() + os.chdir(self.TESTDIR) + self.fname = u"åäötestscript.py" + + def tearDown(self): + os.chdir(self.oldpath) + shutil.rmtree(self.BASETESTDIR) + + @onlyif_unicode_paths + def test_1(self): + """Test safe_execfile with non-ascii path + """ + ip.safe_execfile(self.fname, {}, raise_exceptions=True) + +class ExitCodeChecks(tt.TempFileMixin): + + def setUp(self): + self.system = ip.system_raw + + def test_exit_code_ok(self): + self.system('exit 0') + self.assertEqual(ip.user_ns['_exit_code'], 0) + + def test_exit_code_error(self): + self.system('exit 1') + self.assertEqual(ip.user_ns['_exit_code'], 1) + + @skipif(not hasattr(signal, 'SIGALRM')) + def test_exit_code_signal(self): + self.mktmp("import signal, time\n" + "signal.setitimer(signal.ITIMER_REAL, 0.1)\n" + "time.sleep(1)\n") + self.system("%s %s" % (sys.executable, self.fname)) + self.assertEqual(ip.user_ns['_exit_code'], -signal.SIGALRM) + + @onlyif_cmds_exist("csh") + def test_exit_code_signal_csh(self): + SHELL = os.environ.get('SHELL', None) + os.environ['SHELL'] = find_cmd("csh") + try: + self.test_exit_code_signal() + finally: + if SHELL is not None: + os.environ['SHELL'] = SHELL + else: + del os.environ['SHELL'] + + +class TestSystemRaw(ExitCodeChecks): + + def setUp(self): + super().setUp() + self.system = ip.system_raw + + @onlyif_unicode_paths + def test_1(self): + """Test system_raw with non-ascii cmd + """ + cmd = u'''python -c "'åäö'" ''' + ip.system_raw(cmd) + + @mock.patch('subprocess.call', side_effect=KeyboardInterrupt) + @mock.patch('os.system', side_effect=KeyboardInterrupt) + def test_control_c(self, *mocks): + try: + self.system("sleep 1 # wont happen") + except KeyboardInterrupt: + self.fail("system call should intercept " + "keyboard interrupt from subprocess.call") + self.assertEqual(ip.user_ns['_exit_code'], -signal.SIGINT) + +# TODO: Exit codes are currently ignored on Windows. +class TestSystemPipedExitCode(ExitCodeChecks): + + def setUp(self): + super().setUp() + self.system = ip.system_piped + + @skip_win32 + def test_exit_code_ok(self): + ExitCodeChecks.test_exit_code_ok(self) + + @skip_win32 + def test_exit_code_error(self): + ExitCodeChecks.test_exit_code_error(self) + + @skip_win32 + def test_exit_code_signal(self): + ExitCodeChecks.test_exit_code_signal(self) + +class TestModules(tt.TempFileMixin): + def test_extraneous_loads(self): + """Test we're not loading modules on startup that we shouldn't. + """ + self.mktmp("import sys\n" + "print('numpy' in sys.modules)\n" + "print('ipyparallel' in sys.modules)\n" + "print('ipykernel' in sys.modules)\n" + ) + out = "False\nFalse\nFalse\n" + tt.ipexec_validate(self.fname, out) + +class Negator(ast.NodeTransformer): + """Negates all number literals in an AST.""" + + # for python 3.7 and earlier + def visit_Num(self, node): + node.n = -node.n + return node + + # for python 3.8+ + def visit_Constant(self, node): + if isinstance(node.value, int): + return self.visit_Num(node) + return node + +class TestAstTransform(unittest.TestCase): + def setUp(self): + self.negator = Negator() + ip.ast_transformers.append(self.negator) + + def tearDown(self): + ip.ast_transformers.remove(self.negator) + + def test_run_cell(self): + with tt.AssertPrints('-34'): + ip.run_cell('print (12 + 22)') + + # A named reference to a number shouldn't be transformed. + ip.user_ns['n'] = 55 + with tt.AssertNotPrints('-55'): + ip.run_cell('print (n)') + + def test_timeit(self): + called = set() + def f(x): + called.add(x) + ip.push({'f':f}) + + with tt.AssertPrints("std. dev. of"): + ip.run_line_magic("timeit", "-n1 f(1)") + self.assertEqual(called, {-1}) + called.clear() + + with tt.AssertPrints("std. dev. of"): + ip.run_cell_magic("timeit", "-n1 f(2)", "f(3)") + self.assertEqual(called, {-2, -3}) + + def test_time(self): + called = [] + def f(x): + called.append(x) + ip.push({'f':f}) + + # Test with an expression + with tt.AssertPrints("Wall time: "): + ip.run_line_magic("time", "f(5+9)") + self.assertEqual(called, [-14]) + called[:] = [] + + # Test with a statement (different code path) + with tt.AssertPrints("Wall time: "): + ip.run_line_magic("time", "a = f(-3 + -2)") + self.assertEqual(called, [5]) + + def test_macro(self): + ip.push({'a':10}) + # The AST transformation makes this do a+=-1 + ip.define_macro("amacro", "a+=1\nprint(a)") + + with tt.AssertPrints("9"): + ip.run_cell("amacro") + with tt.AssertPrints("8"): + ip.run_cell("amacro") + +class TestMiscTransform(unittest.TestCase): + + + def test_transform_only_once(self): + cleanup = 0 + line_t = 0 + def count_cleanup(lines): + nonlocal cleanup + cleanup += 1 + return lines + + def count_line_t(lines): + nonlocal line_t + line_t += 1 + return lines + + ip.input_transformer_manager.cleanup_transforms.append(count_cleanup) + ip.input_transformer_manager.line_transforms.append(count_line_t) + + ip.run_cell('1') + + assert cleanup == 1 + assert line_t == 1 + +class IntegerWrapper(ast.NodeTransformer): + """Wraps all integers in a call to Integer()""" + + # for Python 3.7 and earlier + + # for Python 3.7 and earlier + def visit_Num(self, node): + if isinstance(node.n, int): + return ast.Call(func=ast.Name(id='Integer', ctx=ast.Load()), + args=[node], keywords=[]) + return node + + # For Python 3.8+ + def visit_Constant(self, node): + if isinstance(node.value, int): + return self.visit_Num(node) + return node + + +class TestAstTransform2(unittest.TestCase): + def setUp(self): + self.intwrapper = IntegerWrapper() + ip.ast_transformers.append(self.intwrapper) + + self.calls = [] + def Integer(*args): + self.calls.append(args) + return args + ip.push({"Integer": Integer}) + + def tearDown(self): + ip.ast_transformers.remove(self.intwrapper) + del ip.user_ns['Integer'] + + def test_run_cell(self): + ip.run_cell("n = 2") + self.assertEqual(self.calls, [(2,)]) + + # This shouldn't throw an error + ip.run_cell("o = 2.0") + self.assertEqual(ip.user_ns['o'], 2.0) + + def test_timeit(self): + called = set() + def f(x): + called.add(x) + ip.push({'f':f}) + + with tt.AssertPrints("std. dev. of"): + ip.run_line_magic("timeit", "-n1 f(1)") + self.assertEqual(called, {(1,)}) + called.clear() + + with tt.AssertPrints("std. dev. of"): + ip.run_cell_magic("timeit", "-n1 f(2)", "f(3)") + self.assertEqual(called, {(2,), (3,)}) + +class ErrorTransformer(ast.NodeTransformer): + """Throws an error when it sees a number.""" + + # for Python 3.7 and earlier + def visit_Num(self, node): + raise ValueError("test") + + # for Python 3.8+ + def visit_Constant(self, node): + if isinstance(node.value, int): + return self.visit_Num(node) + return node + + +class TestAstTransformError(unittest.TestCase): + def test_unregistering(self): + err_transformer = ErrorTransformer() + ip.ast_transformers.append(err_transformer) + + with self.assertWarnsRegex(UserWarning, "It will be unregistered"): + ip.run_cell("1 + 2") + + # This should have been removed. + nt.assert_not_in(err_transformer, ip.ast_transformers) + + +class StringRejector(ast.NodeTransformer): + """Throws an InputRejected when it sees a string literal. + + Used to verify that NodeTransformers can signal that a piece of code should + not be executed by throwing an InputRejected. + """ + + #for python 3.7 and earlier + def visit_Str(self, node): + raise InputRejected("test") + + # 3.8 only + def visit_Constant(self, node): + if isinstance(node.value, str): + raise InputRejected("test") + return node + + +class TestAstTransformInputRejection(unittest.TestCase): + + def setUp(self): + self.transformer = StringRejector() + ip.ast_transformers.append(self.transformer) + + def tearDown(self): + ip.ast_transformers.remove(self.transformer) + + def test_input_rejection(self): + """Check that NodeTransformers can reject input.""" + + expect_exception_tb = tt.AssertPrints("InputRejected: test") + expect_no_cell_output = tt.AssertNotPrints("'unsafe'", suppress=False) + + # Run the same check twice to verify that the transformer is not + # disabled after raising. + with expect_exception_tb, expect_no_cell_output: + ip.run_cell("'unsafe'") + + with expect_exception_tb, expect_no_cell_output: + res = ip.run_cell("'unsafe'") + + self.assertIsInstance(res.error_before_exec, InputRejected) + +def test__IPYTHON__(): + # This shouldn't raise a NameError, that's all + __IPYTHON__ + + +class DummyRepr(object): + def __repr__(self): + return "DummyRepr" + + def _repr_html_(self): + return "dummy" + + def _repr_javascript_(self): + return "console.log('hi');", {'key': 'value'} + + +def test_user_variables(): + # enable all formatters + ip.display_formatter.active_types = ip.display_formatter.format_types + + ip.user_ns['dummy'] = d = DummyRepr() + keys = {'dummy', 'doesnotexist'} + r = ip.user_expressions({ key:key for key in keys}) + + nt.assert_equal(keys, set(r.keys())) + dummy = r['dummy'] + nt.assert_equal({'status', 'data', 'metadata'}, set(dummy.keys())) + nt.assert_equal(dummy['status'], 'ok') + data = dummy['data'] + metadata = dummy['metadata'] + nt.assert_equal(data.get('text/html'), d._repr_html_()) + js, jsmd = d._repr_javascript_() + nt.assert_equal(data.get('application/javascript'), js) + nt.assert_equal(metadata.get('application/javascript'), jsmd) + + dne = r['doesnotexist'] + nt.assert_equal(dne['status'], 'error') + nt.assert_equal(dne['ename'], 'NameError') + + # back to text only + ip.display_formatter.active_types = ['text/plain'] + +def test_user_expression(): + # enable all formatters + ip.display_formatter.active_types = ip.display_formatter.format_types + query = { + 'a' : '1 + 2', + 'b' : '1/0', + } + r = ip.user_expressions(query) + import pprint + pprint.pprint(r) + nt.assert_equal(set(r.keys()), set(query.keys())) + a = r['a'] + nt.assert_equal({'status', 'data', 'metadata'}, set(a.keys())) + nt.assert_equal(a['status'], 'ok') + data = a['data'] + metadata = a['metadata'] + nt.assert_equal(data.get('text/plain'), '3') + + b = r['b'] + nt.assert_equal(b['status'], 'error') + nt.assert_equal(b['ename'], 'ZeroDivisionError') + + # back to text only + ip.display_formatter.active_types = ['text/plain'] + + +class TestSyntaxErrorTransformer(unittest.TestCase): + """Check that SyntaxError raised by an input transformer is handled by run_cell()""" + + @staticmethod + def transformer(lines): + for line in lines: + pos = line.find('syntaxerror') + if pos >= 0: + e = SyntaxError('input contains "syntaxerror"') + e.text = line + e.offset = pos + 1 + raise e + return lines + + def setUp(self): + ip.input_transformers_post.append(self.transformer) + + def tearDown(self): + ip.input_transformers_post.remove(self.transformer) + + def test_syntaxerror_input_transformer(self): + with tt.AssertPrints('1234'): + ip.run_cell('1234') + with tt.AssertPrints('SyntaxError: invalid syntax'): + ip.run_cell('1 2 3') # plain python syntax error + with tt.AssertPrints('SyntaxError: input contains "syntaxerror"'): + ip.run_cell('2345 # syntaxerror') # input transformer syntax error + with tt.AssertPrints('3456'): + ip.run_cell('3456') + + +class TestWarningSuppression(unittest.TestCase): + def test_warning_suppression(self): + ip.run_cell("import warnings") + try: + with self.assertWarnsRegex(UserWarning, "asdf"): + ip.run_cell("warnings.warn('asdf')") + # Here's the real test -- if we run that again, we should get the + # warning again. Traditionally, each warning was only issued once per + # IPython session (approximately), even if the user typed in new and + # different code that should have also triggered the warning, leading + # to much confusion. + with self.assertWarnsRegex(UserWarning, "asdf"): + ip.run_cell("warnings.warn('asdf')") + finally: + ip.run_cell("del warnings") + + + def test_deprecation_warning(self): + ip.run_cell(""" +import warnings +def wrn(): + warnings.warn( + "I AM A WARNING", + DeprecationWarning + ) + """) + try: + with self.assertWarnsRegex(DeprecationWarning, "I AM A WARNING"): + ip.run_cell("wrn()") + finally: + ip.run_cell("del warnings") + ip.run_cell("del wrn") + + +class TestImportNoDeprecate(tt.TempFileMixin): + + def setUp(self): + """Make a valid python temp file.""" + self.mktmp(""" +import warnings +def wrn(): + warnings.warn( + "I AM A WARNING", + DeprecationWarning + ) +""") + super().setUp() + + def test_no_dep(self): + """ + No deprecation warning should be raised from imported functions + """ + ip.run_cell("from {} import wrn".format(self.fname)) + + with tt.AssertNotPrints("I AM A WARNING"): + ip.run_cell("wrn()") + ip.run_cell("del wrn") + + +def test_custom_exc_count(): + hook = mock.Mock(return_value=None) + ip.set_custom_exc((SyntaxError,), hook) + before = ip.execution_count + ip.run_cell("def foo()", store_history=True) + # restore default excepthook + ip.set_custom_exc((), None) + nt.assert_equal(hook.call_count, 1) + nt.assert_equal(ip.execution_count, before + 1) + + +def test_run_cell_async(): + loop = asyncio.get_event_loop() + ip.run_cell("import asyncio") + coro = ip.run_cell_async("await asyncio.sleep(0.01)\n5") + assert asyncio.iscoroutine(coro) + result = loop.run_until_complete(coro) + assert isinstance(result, interactiveshell.ExecutionResult) + assert result.result == 5 + + +def test_should_run_async(): + assert not ip.should_run_async("a = 5") + assert ip.should_run_async("await x") + assert ip.should_run_async("import asyncio; await asyncio.sleep(1)") + + +def test_set_custom_completer(): + num_completers = len(ip.Completer.matchers) + + def foo(*args, **kwargs): + return "I'm a completer!" + + ip.set_custom_completer(foo, 0) + + # check that we've really added a new completer + assert len(ip.Completer.matchers) == num_completers + 1 + + # check that the first completer is the function we defined + assert ip.Completer.matchers[0]() == "I'm a completer!" + + # clean up + ip.Completer.custom_matchers.pop() diff --git a/.venv/lib/python3.8/site-packages/IPython/core/tests/test_iplib.py b/.venv/lib/python3.8/site-packages/IPython/core/tests/test_iplib.py new file mode 100644 index 00000000..adadae56 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/IPython/core/tests/test_iplib.py @@ -0,0 +1,246 @@ +"""Tests for the key interactiveshell module, where the main ipython class is defined. +""" +#----------------------------------------------------------------------------- +# Module imports +#----------------------------------------------------------------------------- + +# third party +import nose.tools as nt + +# our own packages + +#----------------------------------------------------------------------------- +# Test functions +#----------------------------------------------------------------------------- + +def test_reset(): + """reset must clear most namespaces.""" + + # Check that reset runs without error + ip.reset() + + # Once we've reset it (to clear of any junk that might have been there from + # other tests, we can count how many variables are in the user's namespace + nvars_user_ns = len(ip.user_ns) + nvars_hidden = len(ip.user_ns_hidden) + + # Now add a few variables to user_ns, and check that reset clears them + ip.user_ns['x'] = 1 + ip.user_ns['y'] = 1 + ip.reset() + + # Finally, check that all namespaces have only as many variables as we + # expect to find in them: + nt.assert_equal(len(ip.user_ns), nvars_user_ns) + nt.assert_equal(len(ip.user_ns_hidden), nvars_hidden) + + +# Tests for reporting of exceptions in various modes, handling of SystemExit, +# and %tb functionality. This is really a mix of testing ultraTB and interactiveshell. + +def doctest_tb_plain(): + """ +In [18]: xmode plain +Exception reporting mode: Plain + +In [19]: run simpleerr.py +Traceback (most recent call last): + ...line 32, in + bar(mode) + ...line 16, in bar + div0() + ...line 8, in div0 + x/y +ZeroDivisionError: ... + """ + + +def doctest_tb_context(): + """ +In [3]: xmode context +Exception reporting mode: Context + +In [4]: run simpleerr.py +--------------------------------------------------------------------------- +ZeroDivisionError Traceback (most recent call last) + +... in + 30 mode = 'div' + 31 +---> 32 bar(mode) + +... in bar(mode) + 14 "bar" + 15 if mode=='div': +---> 16 div0() + 17 elif mode=='exit': + 18 try: + +... in div0() + 6 x = 1 + 7 y = 0 +----> 8 x/y + 9 + 10 def sysexit(stat, mode): + +ZeroDivisionError: ... +""" + + +def doctest_tb_verbose(): + """ +In [5]: xmode verbose +Exception reporting mode: Verbose + +In [6]: run simpleerr.py +--------------------------------------------------------------------------- +ZeroDivisionError Traceback (most recent call last) + +... in + 30 mode = 'div' + 31 +---> 32 bar(mode) + global bar = + global mode = 'div' + +... in bar(mode='div') + 14 "bar" + 15 if mode=='div': +---> 16 div0() + global div0 = + 17 elif mode=='exit': + 18 try: + +... in div0() + 6 x = 1 + 7 y = 0 +----> 8 x/y + x = 1 + y = 0 + 9 + 10 def sysexit(stat, mode): + +ZeroDivisionError: ... + """ + +def doctest_tb_sysexit(): + """ +In [17]: %xmode plain +Exception reporting mode: Plain + +In [18]: %run simpleerr.py exit +An exception has occurred, use %tb to see the full traceback. +SystemExit: (1, 'Mode = exit') + +In [19]: %run simpleerr.py exit 2 +An exception has occurred, use %tb to see the full traceback. +SystemExit: (2, 'Mode = exit') + +In [20]: %tb +Traceback (most recent call last): + File ... in + bar(mode) + File ... line 22, in bar + sysexit(stat, mode) + File ... line 11, in sysexit + raise SystemExit(stat, 'Mode = %s' % mode) +SystemExit: (2, 'Mode = exit') + +In [21]: %xmode context +Exception reporting mode: Context + +In [22]: %tb +--------------------------------------------------------------------------- +SystemExit Traceback (most recent call last) + +... + 30 mode = 'div' + 31 +---> 32 bar(mode) + +...bar(mode) + 20 except: + 21 stat = 1 +---> 22 sysexit(stat, mode) + 23 else: + 24 raise ValueError('Unknown mode') + +...sysexit(stat, mode) + 9 + 10 def sysexit(stat, mode): +---> 11 raise SystemExit(stat, 'Mode = %s' % mode) + 12 + 13 def bar(mode): + +SystemExit: (2, 'Mode = exit') + +In [23]: %xmode verbose +Exception reporting mode: Verbose + +In [24]: %tb +--------------------------------------------------------------------------- +SystemExit Traceback (most recent call last) + +... in + 30 mode = 'div' + 31 +---> 32 bar(mode) + global bar = + global mode = 'exit' + +... in bar(mode='exit') + 20 except: + 21 stat = 1 +---> 22 sysexit(stat, mode) + global sysexit = + stat = 2 + mode = 'exit' + 23 else: + 24 raise ValueError('Unknown mode') + +... in sysexit(stat=2, mode='exit') + 9 + 10 def sysexit(stat, mode): +---> 11 raise SystemExit(stat, 'Mode = %s' % mode) + global SystemExit = undefined + stat = 2 + mode = 'exit' + 12 + 13 def bar(mode): + +SystemExit: (2, 'Mode = exit') + """ + + +def test_run_cell(): + import textwrap + ip.run_cell('a = 10\na+=1') + ip.run_cell('assert a == 11\nassert 1') + + nt.assert_equal(ip.user_ns['a'], 11) + complex = textwrap.dedent(""" + if 1: + print "hello" + if 1: + print "world" + + if 2: + print "foo" + + if 3: + print "bar" + + if 4: + print "bar" + + """) + # Simply verifies that this kind of input is run + ip.run_cell(complex) + + +def test_db(): + """Test the internal database used for variable persistence.""" + ip.db['__unittest_'] = 12 + nt.assert_equal(ip.db['__unittest_'], 12) + del ip.db['__unittest_'] + assert '__unittest_' not in ip.db diff --git a/.venv/lib/python3.8/site-packages/IPython/core/tests/test_logger.py b/.venv/lib/python3.8/site-packages/IPython/core/tests/test_logger.py new file mode 100644 index 00000000..ebebac16 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/IPython/core/tests/test_logger.py @@ -0,0 +1,30 @@ +# -*- coding: utf-8 -*- +"""Test IPython.core.logger""" + +import os.path + +import nose.tools as nt +from IPython.utils.tempdir import TemporaryDirectory + +def test_logstart_inaccessible_file(): + try: + _ip.logger.logstart(logfname="/") # Opening that filename will fail. + except IOError: + pass + else: + nt.assert_true(False) # The try block should never pass. + + try: + _ip.run_cell("a=1") # Check it doesn't try to log this + finally: + _ip.logger.log_active = False # If this fails, don't let later tests fail + +def test_logstart_unicode(): + with TemporaryDirectory() as tdir: + logfname = os.path.join(tdir, "test_unicode.log") + _ip.run_cell("'abc€'") + try: + _ip.magic("logstart -to %s" % logfname) + _ip.run_cell("'abc€'") + finally: + _ip.logger.logstop() diff --git a/.venv/lib/python3.8/site-packages/IPython/core/tests/test_magic.py b/.venv/lib/python3.8/site-packages/IPython/core/tests/test_magic.py new file mode 100644 index 00000000..d6e5d2f4 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/IPython/core/tests/test_magic.py @@ -0,0 +1,1238 @@ +# -*- coding: utf-8 -*- +"""Tests for various magic functions. + +Needs to be run by nose (to make ipython session available). +""" + +import io +import os +import re +import sys +import warnings +from textwrap import dedent +from unittest import TestCase +from unittest import mock +from importlib import invalidate_caches +from io import StringIO + +import nose.tools as nt + +import shlex + +from IPython import get_ipython +from IPython.core import magic +from IPython.core.error import UsageError +from IPython.core.magic import (Magics, magics_class, line_magic, + cell_magic, + register_line_magic, register_cell_magic) +from IPython.core.magics import execution, script, code, logging, osm +from IPython.testing import decorators as dec +from IPython.testing import tools as tt +from IPython.utils.io import capture_output +from IPython.utils.tempdir import (TemporaryDirectory, + TemporaryWorkingDirectory) +from IPython.utils.process import find_cmd +from .test_debugger import PdbTestInput + + +@magic.magics_class +class DummyMagics(magic.Magics): pass + +def test_extract_code_ranges(): + instr = "1 3 5-6 7-9 10:15 17: :10 10- -13 :" + expected = [(0, 1), + (2, 3), + (4, 6), + (6, 9), + (9, 14), + (16, None), + (None, 9), + (9, None), + (None, 13), + (None, None)] + actual = list(code.extract_code_ranges(instr)) + nt.assert_equal(actual, expected) + +def test_extract_symbols(): + source = """import foo\na = 10\ndef b():\n return 42\n\n\nclass A: pass\n\n\n""" + symbols_args = ["a", "b", "A", "A,b", "A,a", "z"] + expected = [([], ['a']), + (["def b():\n return 42\n"], []), + (["class A: pass\n"], []), + (["class A: pass\n", "def b():\n return 42\n"], []), + (["class A: pass\n"], ['a']), + ([], ['z'])] + for symbols, exp in zip(symbols_args, expected): + nt.assert_equal(code.extract_symbols(source, symbols), exp) + + +def test_extract_symbols_raises_exception_with_non_python_code(): + source = ("=begin A Ruby program :)=end\n" + "def hello\n" + "puts 'Hello world'\n" + "end") + with nt.assert_raises(SyntaxError): + code.extract_symbols(source, "hello") + + +def test_magic_not_found(): + # magic not found raises UsageError + with nt.assert_raises(UsageError): + _ip.magic('doesntexist') + + # ensure result isn't success when a magic isn't found + result = _ip.run_cell('%doesntexist') + assert isinstance(result.error_in_exec, UsageError) + + +def test_cell_magic_not_found(): + # magic not found raises UsageError + with nt.assert_raises(UsageError): + _ip.run_cell_magic('doesntexist', 'line', 'cell') + + # ensure result isn't success when a magic isn't found + result = _ip.run_cell('%%doesntexist') + assert isinstance(result.error_in_exec, UsageError) + + +def test_magic_error_status(): + def fail(shell): + 1/0 + _ip.register_magic_function(fail) + result = _ip.run_cell('%fail') + assert isinstance(result.error_in_exec, ZeroDivisionError) + + +def test_config(): + """ test that config magic does not raise + can happen if Configurable init is moved too early into + Magics.__init__ as then a Config object will be registered as a + magic. + """ + ## should not raise. + _ip.magic('config') + +def test_config_available_configs(): + """ test that config magic prints available configs in unique and + sorted order. """ + with capture_output() as captured: + _ip.magic('config') + + stdout = captured.stdout + config_classes = stdout.strip().split('\n')[1:] + nt.assert_list_equal(config_classes, sorted(set(config_classes))) + +def test_config_print_class(): + """ test that config with a classname prints the class's options. """ + with capture_output() as captured: + _ip.magic('config TerminalInteractiveShell') + + stdout = captured.stdout + if not re.match("TerminalInteractiveShell.* options", stdout.splitlines()[0]): + print(stdout) + raise AssertionError("1st line of stdout not like " + "'TerminalInteractiveShell.* options'") + +def test_rehashx(): + # clear up everything + _ip.alias_manager.clear_aliases() + del _ip.db['syscmdlist'] + + _ip.magic('rehashx') + # Practically ALL ipython development systems will have more than 10 aliases + + nt.assert_true(len(_ip.alias_manager.aliases) > 10) + for name, cmd in _ip.alias_manager.aliases: + # we must strip dots from alias names + nt.assert_not_in('.', name) + + # rehashx must fill up syscmdlist + scoms = _ip.db['syscmdlist'] + nt.assert_true(len(scoms) > 10) + + + +def test_magic_parse_options(): + """Test that we don't mangle paths when parsing magic options.""" + ip = get_ipython() + path = 'c:\\x' + m = DummyMagics(ip) + opts = m.parse_options('-f %s' % path,'f:')[0] + # argv splitting is os-dependent + if os.name == 'posix': + expected = 'c:x' + else: + expected = path + nt.assert_equal(opts['f'], expected) + +def test_magic_parse_long_options(): + """Magic.parse_options can handle --foo=bar long options""" + ip = get_ipython() + m = DummyMagics(ip) + opts, _ = m.parse_options('--foo --bar=bubble', 'a', 'foo', 'bar=') + nt.assert_in('foo', opts) + nt.assert_in('bar', opts) + nt.assert_equal(opts['bar'], "bubble") + + +@dec.skip_without('sqlite3') +def doctest_hist_f(): + """Test %hist -f with temporary filename. + + In [9]: import tempfile + + In [10]: tfile = tempfile.mktemp('.py','tmp-ipython-') + + In [11]: %hist -nl -f $tfile 3 + + In [13]: import os; os.unlink(tfile) + """ + + +@dec.skip_without('sqlite3') +def doctest_hist_r(): + """Test %hist -r + + XXX - This test is not recording the output correctly. For some reason, in + testing mode the raw history isn't getting populated. No idea why. + Disabling the output checking for now, though at least we do run it. + + In [1]: 'hist' in _ip.lsmagic() + Out[1]: True + + In [2]: x=1 + + In [3]: %hist -rl 2 + x=1 # random + %hist -r 2 + """ + + +@dec.skip_without('sqlite3') +def doctest_hist_op(): + """Test %hist -op + + In [1]: class b(float): + ...: pass + ...: + + In [2]: class s(object): + ...: def __str__(self): + ...: return 's' + ...: + + In [3]: + + In [4]: class r(b): + ...: def __repr__(self): + ...: return 'r' + ...: + + In [5]: class sr(s,r): pass + ...: + + In [6]: + + In [7]: bb=b() + + In [8]: ss=s() + + In [9]: rr=r() + + In [10]: ssrr=sr() + + In [11]: 4.5 + Out[11]: 4.5 + + In [12]: str(ss) + Out[12]: 's' + + In [13]: + + In [14]: %hist -op + >>> class b: + ... pass + ... + >>> class s(b): + ... def __str__(self): + ... return 's' + ... + >>> + >>> class r(b): + ... def __repr__(self): + ... return 'r' + ... + >>> class sr(s,r): pass + >>> + >>> bb=b() + >>> ss=s() + >>> rr=r() + >>> ssrr=sr() + >>> 4.5 + 4.5 + >>> str(ss) + 's' + >>> + """ + +def test_hist_pof(): + ip = get_ipython() + ip.run_cell(u"1+2", store_history=True) + #raise Exception(ip.history_manager.session_number) + #raise Exception(list(ip.history_manager._get_range_session())) + with TemporaryDirectory() as td: + tf = os.path.join(td, 'hist.py') + ip.run_line_magic('history', '-pof %s' % tf) + assert os.path.isfile(tf) + + +@dec.skip_without('sqlite3') +def test_macro(): + ip = get_ipython() + ip.history_manager.reset() # Clear any existing history. + cmds = ["a=1", "def b():\n return a**2", "print(a,b())"] + for i, cmd in enumerate(cmds, start=1): + ip.history_manager.store_inputs(i, cmd) + ip.magic("macro test 1-3") + nt.assert_equal(ip.user_ns["test"].value, "\n".join(cmds)+"\n") + + # List macros + nt.assert_in("test", ip.magic("macro")) + + +@dec.skip_without('sqlite3') +def test_macro_run(): + """Test that we can run a multi-line macro successfully.""" + ip = get_ipython() + ip.history_manager.reset() + cmds = ["a=10", "a+=1", "print(a)", "%macro test 2-3"] + for cmd in cmds: + ip.run_cell(cmd, store_history=True) + nt.assert_equal(ip.user_ns["test"].value, "a+=1\nprint(a)\n") + with tt.AssertPrints("12"): + ip.run_cell("test") + with tt.AssertPrints("13"): + ip.run_cell("test") + + +def test_magic_magic(): + """Test %magic""" + ip = get_ipython() + with capture_output() as captured: + ip.magic("magic") + + stdout = captured.stdout + nt.assert_in('%magic', stdout) + nt.assert_in('IPython', stdout) + nt.assert_in('Available', stdout) + + +@dec.skipif_not_numpy +def test_numpy_reset_array_undec(): + "Test '%reset array' functionality" + _ip.ex('import numpy as np') + _ip.ex('a = np.empty(2)') + nt.assert_in('a', _ip.user_ns) + _ip.magic('reset -f array') + nt.assert_not_in('a', _ip.user_ns) + +def test_reset_out(): + "Test '%reset out' magic" + _ip.run_cell("parrot = 'dead'", store_history=True) + # test '%reset -f out', make an Out prompt + _ip.run_cell("parrot", store_history=True) + nt.assert_true('dead' in [_ip.user_ns[x] for x in ('_','__','___')]) + _ip.magic('reset -f out') + nt.assert_false('dead' in [_ip.user_ns[x] for x in ('_','__','___')]) + nt.assert_equal(len(_ip.user_ns['Out']), 0) + +def test_reset_in(): + "Test '%reset in' magic" + # test '%reset -f in' + _ip.run_cell("parrot", store_history=True) + nt.assert_true('parrot' in [_ip.user_ns[x] for x in ('_i','_ii','_iii')]) + _ip.magic('%reset -f in') + nt.assert_false('parrot' in [_ip.user_ns[x] for x in ('_i','_ii','_iii')]) + nt.assert_equal(len(set(_ip.user_ns['In'])), 1) + +def test_reset_dhist(): + "Test '%reset dhist' magic" + _ip.run_cell("tmp = [d for d in _dh]") # copy before clearing + _ip.magic('cd ' + os.path.dirname(nt.__file__)) + _ip.magic('cd -') + nt.assert_true(len(_ip.user_ns['_dh']) > 0) + _ip.magic('reset -f dhist') + nt.assert_equal(len(_ip.user_ns['_dh']), 0) + _ip.run_cell("_dh = [d for d in tmp]") #restore + +def test_reset_in_length(): + "Test that '%reset in' preserves In[] length" + _ip.run_cell("print 'foo'") + _ip.run_cell("reset -f in") + nt.assert_equal(len(_ip.user_ns['In']), _ip.displayhook.prompt_count+1) + +class TestResetErrors(TestCase): + + def test_reset_redefine(self): + + @magics_class + class KernelMagics(Magics): + @line_magic + def less(self, shell): pass + + _ip.register_magics(KernelMagics) + + with self.assertLogs() as cm: + # hack, we want to just capture logs, but assertLogs fails if not + # logs get produce. + # so log one things we ignore. + import logging as log_mod + log = log_mod.getLogger() + log.info('Nothing') + # end hack. + _ip.run_cell("reset -f") + + assert len(cm.output) == 1 + for out in cm.output: + assert "Invalid alias" not in out + +def test_tb_syntaxerror(): + """test %tb after a SyntaxError""" + ip = get_ipython() + ip.run_cell("for") + + # trap and validate stdout + save_stdout = sys.stdout + try: + sys.stdout = StringIO() + ip.run_cell("%tb") + out = sys.stdout.getvalue() + finally: + sys.stdout = save_stdout + # trim output, and only check the last line + last_line = out.rstrip().splitlines()[-1].strip() + nt.assert_equal(last_line, "SyntaxError: invalid syntax") + + +def test_time(): + ip = get_ipython() + + with tt.AssertPrints("Wall time: "): + ip.run_cell("%time None") + + ip.run_cell("def f(kmjy):\n" + " %time print (2*kmjy)") + + with tt.AssertPrints("Wall time: "): + with tt.AssertPrints("hihi", suppress=False): + ip.run_cell("f('hi')") + +def test_time_last_not_expression(): + ip.run_cell("%%time\n" + "var_1 = 1\n" + "var_2 = 2\n") + assert ip.user_ns['var_1'] == 1 + del ip.user_ns['var_1'] + assert ip.user_ns['var_2'] == 2 + del ip.user_ns['var_2'] + + +@dec.skip_win32 +def test_time2(): + ip = get_ipython() + + with tt.AssertPrints("CPU times: user "): + ip.run_cell("%time None") + +def test_time3(): + """Erroneous magic function calls, issue gh-3334""" + ip = get_ipython() + ip.user_ns.pop('run', None) + + with tt.AssertNotPrints("not found", channel='stderr'): + ip.run_cell("%%time\n" + "run = 0\n" + "run += 1") + +def test_multiline_time(): + """Make sure last statement from time return a value.""" + ip = get_ipython() + ip.user_ns.pop('run', None) + + ip.run_cell(dedent("""\ + %%time + a = "ho" + b = "hey" + a+b + """)) + nt.assert_equal(ip.user_ns_hidden['_'], 'hohey') + +def test_time_local_ns(): + """ + Test that local_ns is actually global_ns when running a cell magic + """ + ip = get_ipython() + ip.run_cell("%%time\n" + "myvar = 1") + nt.assert_equal(ip.user_ns['myvar'], 1) + del ip.user_ns['myvar'] + +def test_doctest_mode(): + "Toggle doctest_mode twice, it should be a no-op and run without error" + _ip.magic('doctest_mode') + _ip.magic('doctest_mode') + + +def test_parse_options(): + """Tests for basic options parsing in magics.""" + # These are only the most minimal of tests, more should be added later. At + # the very least we check that basic text/unicode calls work OK. + m = DummyMagics(_ip) + nt.assert_equal(m.parse_options('foo', '')[1], 'foo') + nt.assert_equal(m.parse_options(u'foo', '')[1], u'foo') + + +def test_dirops(): + """Test various directory handling operations.""" + # curpath = lambda :os.path.splitdrive(os.getcwd())[1].replace('\\','/') + curpath = os.getcwd + startdir = os.getcwd() + ipdir = os.path.realpath(_ip.ipython_dir) + try: + _ip.magic('cd "%s"' % ipdir) + nt.assert_equal(curpath(), ipdir) + _ip.magic('cd -') + nt.assert_equal(curpath(), startdir) + _ip.magic('pushd "%s"' % ipdir) + nt.assert_equal(curpath(), ipdir) + _ip.magic('popd') + nt.assert_equal(curpath(), startdir) + finally: + os.chdir(startdir) + + +def test_cd_force_quiet(): + """Test OSMagics.cd_force_quiet option""" + _ip.config.OSMagics.cd_force_quiet = True + osmagics = osm.OSMagics(shell=_ip) + + startdir = os.getcwd() + ipdir = os.path.realpath(_ip.ipython_dir) + + try: + with tt.AssertNotPrints(ipdir): + osmagics.cd('"%s"' % ipdir) + with tt.AssertNotPrints(startdir): + osmagics.cd('-') + finally: + os.chdir(startdir) + + +def test_xmode(): + # Calling xmode three times should be a no-op + xmode = _ip.InteractiveTB.mode + for i in range(4): + _ip.magic("xmode") + nt.assert_equal(_ip.InteractiveTB.mode, xmode) + +def test_reset_hard(): + monitor = [] + class A(object): + def __del__(self): + monitor.append(1) + def __repr__(self): + return "" + + _ip.user_ns["a"] = A() + _ip.run_cell("a") + + nt.assert_equal(monitor, []) + _ip.magic("reset -f") + nt.assert_equal(monitor, [1]) + +class TestXdel(tt.TempFileMixin): + def test_xdel(self): + """Test that references from %run are cleared by xdel.""" + src = ("class A(object):\n" + " monitor = []\n" + " def __del__(self):\n" + " self.monitor.append(1)\n" + "a = A()\n") + self.mktmp(src) + # %run creates some hidden references... + _ip.magic("run %s" % self.fname) + # ... as does the displayhook. + _ip.run_cell("a") + + monitor = _ip.user_ns["A"].monitor + nt.assert_equal(monitor, []) + + _ip.magic("xdel a") + + # Check that a's __del__ method has been called. + nt.assert_equal(monitor, [1]) + +def doctest_who(): + """doctest for %who + + In [1]: %reset -f + + In [2]: alpha = 123 + + In [3]: beta = 'beta' + + In [4]: %who int + alpha + + In [5]: %who str + beta + + In [6]: %whos + Variable Type Data/Info + ---------------------------- + alpha int 123 + beta str beta + + In [7]: %who_ls + Out[7]: ['alpha', 'beta'] + """ + +def test_whos(): + """Check that whos is protected against objects where repr() fails.""" + class A(object): + def __repr__(self): + raise Exception() + _ip.user_ns['a'] = A() + _ip.magic("whos") + +def doctest_precision(): + """doctest for %precision + + In [1]: f = get_ipython().display_formatter.formatters['text/plain'] + + In [2]: %precision 5 + Out[2]: '%.5f' + + In [3]: f.float_format + Out[3]: '%.5f' + + In [4]: %precision %e + Out[4]: '%e' + + In [5]: f(3.1415927) + Out[5]: '3.141593e+00' + """ + +def test_debug_magic(): + """Test debugging a small code with %debug + + In [1]: with PdbTestInput(['c']): + ...: %debug print("a b") #doctest: +ELLIPSIS + ...: + ... + ipdb> c + a b + In [2]: + """ + +def test_psearch(): + with tt.AssertPrints("dict.fromkeys"): + _ip.run_cell("dict.fr*?") + with tt.AssertPrints("π.is_integer"): + _ip.run_cell("π = 3.14;\nπ.is_integ*?") + +def test_timeit_shlex(): + """test shlex issues with timeit (#1109)""" + _ip.ex("def f(*a,**kw): pass") + _ip.magic('timeit -n1 "this is a bug".count(" ")') + _ip.magic('timeit -r1 -n1 f(" ", 1)') + _ip.magic('timeit -r1 -n1 f(" ", 1, " ", 2, " ")') + _ip.magic('timeit -r1 -n1 ("a " + "b")') + _ip.magic('timeit -r1 -n1 f("a " + "b")') + _ip.magic('timeit -r1 -n1 f("a " + "b ")') + + +def test_timeit_special_syntax(): + "Test %%timeit with IPython special syntax" + @register_line_magic + def lmagic(line): + ip = get_ipython() + ip.user_ns['lmagic_out'] = line + + # line mode test + _ip.run_line_magic('timeit', '-n1 -r1 %lmagic my line') + nt.assert_equal(_ip.user_ns['lmagic_out'], 'my line') + # cell mode test + _ip.run_cell_magic('timeit', '-n1 -r1', '%lmagic my line2') + nt.assert_equal(_ip.user_ns['lmagic_out'], 'my line2') + +def test_timeit_return(): + """ + test whether timeit -o return object + """ + + res = _ip.run_line_magic('timeit','-n10 -r10 -o 1') + assert(res is not None) + +def test_timeit_quiet(): + """ + test quiet option of timeit magic + """ + with tt.AssertNotPrints("loops"): + _ip.run_cell("%timeit -n1 -r1 -q 1") + +def test_timeit_return_quiet(): + with tt.AssertNotPrints("loops"): + res = _ip.run_line_magic('timeit', '-n1 -r1 -q -o 1') + assert (res is not None) + +def test_timeit_invalid_return(): + with nt.assert_raises_regex(SyntaxError, "outside function"): + _ip.run_line_magic('timeit', 'return') + +@dec.skipif(execution.profile is None) +def test_prun_special_syntax(): + "Test %%prun with IPython special syntax" + @register_line_magic + def lmagic(line): + ip = get_ipython() + ip.user_ns['lmagic_out'] = line + + # line mode test + _ip.run_line_magic('prun', '-q %lmagic my line') + nt.assert_equal(_ip.user_ns['lmagic_out'], 'my line') + # cell mode test + _ip.run_cell_magic('prun', '-q', '%lmagic my line2') + nt.assert_equal(_ip.user_ns['lmagic_out'], 'my line2') + +@dec.skipif(execution.profile is None) +def test_prun_quotes(): + "Test that prun does not clobber string escapes (GH #1302)" + _ip.magic(r"prun -q x = '\t'") + nt.assert_equal(_ip.user_ns['x'], '\t') + +def test_extension(): + # Debugging information for failures of this test + print('sys.path:') + for p in sys.path: + print(' ', p) + print('CWD', os.getcwd()) + + nt.assert_raises(ImportError, _ip.magic, "load_ext daft_extension") + daft_path = os.path.join(os.path.dirname(__file__), "daft_extension") + sys.path.insert(0, daft_path) + try: + _ip.user_ns.pop('arq', None) + invalidate_caches() # Clear import caches + _ip.magic("load_ext daft_extension") + nt.assert_equal(_ip.user_ns['arq'], 185) + _ip.magic("unload_ext daft_extension") + assert 'arq' not in _ip.user_ns + finally: + sys.path.remove(daft_path) + + +def test_notebook_export_json(): + _ip = get_ipython() + _ip.history_manager.reset() # Clear any existing history. + cmds = [u"a=1", u"def b():\n return a**2", u"print('noël, été', b())"] + for i, cmd in enumerate(cmds, start=1): + _ip.history_manager.store_inputs(i, cmd) + with TemporaryDirectory() as td: + outfile = os.path.join(td, "nb.ipynb") + _ip.magic("notebook -e %s" % outfile) + + +class TestEnv(TestCase): + + def test_env(self): + env = _ip.magic("env") + self.assertTrue(isinstance(env, dict)) + + def test_env_secret(self): + env = _ip.magic("env") + hidden = "" + with mock.patch.dict( + os.environ, + { + "API_KEY": "abc123", + "SECRET_THING": "ssshhh", + "JUPYTER_TOKEN": "", + "VAR": "abc" + } + ): + env = _ip.magic("env") + assert env["API_KEY"] == hidden + assert env["SECRET_THING"] == hidden + assert env["JUPYTER_TOKEN"] == hidden + assert env["VAR"] == "abc" + + def test_env_get_set_simple(self): + env = _ip.magic("env var val1") + self.assertEqual(env, None) + self.assertEqual(os.environ['var'], 'val1') + self.assertEqual(_ip.magic("env var"), 'val1') + env = _ip.magic("env var=val2") + self.assertEqual(env, None) + self.assertEqual(os.environ['var'], 'val2') + + def test_env_get_set_complex(self): + env = _ip.magic("env var 'val1 '' 'val2") + self.assertEqual(env, None) + self.assertEqual(os.environ['var'], "'val1 '' 'val2") + self.assertEqual(_ip.magic("env var"), "'val1 '' 'val2") + env = _ip.magic('env var=val2 val3="val4') + self.assertEqual(env, None) + self.assertEqual(os.environ['var'], 'val2 val3="val4') + + def test_env_set_bad_input(self): + self.assertRaises(UsageError, lambda: _ip.magic("set_env var")) + + def test_env_set_whitespace(self): + self.assertRaises(UsageError, lambda: _ip.magic("env var A=B")) + + +class CellMagicTestCase(TestCase): + + def check_ident(self, magic): + # Manually called, we get the result + out = _ip.run_cell_magic(magic, 'a', 'b') + nt.assert_equal(out, ('a','b')) + # Via run_cell, it goes into the user's namespace via displayhook + _ip.run_cell('%%' + magic +' c\nd\n') + nt.assert_equal(_ip.user_ns['_'], ('c','d\n')) + + def test_cell_magic_func_deco(self): + "Cell magic using simple decorator" + @register_cell_magic + def cellm(line, cell): + return line, cell + + self.check_ident('cellm') + + def test_cell_magic_reg(self): + "Cell magic manually registered" + def cellm(line, cell): + return line, cell + + _ip.register_magic_function(cellm, 'cell', 'cellm2') + self.check_ident('cellm2') + + def test_cell_magic_class(self): + "Cell magics declared via a class" + @magics_class + class MyMagics(Magics): + + @cell_magic + def cellm3(self, line, cell): + return line, cell + + _ip.register_magics(MyMagics) + self.check_ident('cellm3') + + def test_cell_magic_class2(self): + "Cell magics declared via a class, #2" + @magics_class + class MyMagics2(Magics): + + @cell_magic('cellm4') + def cellm33(self, line, cell): + return line, cell + + _ip.register_magics(MyMagics2) + self.check_ident('cellm4') + # Check that nothing is registered as 'cellm33' + c33 = _ip.find_cell_magic('cellm33') + nt.assert_equal(c33, None) + +def test_file(): + """Basic %%writefile""" + ip = get_ipython() + with TemporaryDirectory() as td: + fname = os.path.join(td, 'file1') + ip.run_cell_magic("writefile", fname, u'\n'.join([ + 'line1', + 'line2', + ])) + with open(fname) as f: + s = f.read() + nt.assert_in('line1\n', s) + nt.assert_in('line2', s) + +@dec.skip_win32 +def test_file_single_quote(): + """Basic %%writefile with embedded single quotes""" + ip = get_ipython() + with TemporaryDirectory() as td: + fname = os.path.join(td, '\'file1\'') + ip.run_cell_magic("writefile", fname, u'\n'.join([ + 'line1', + 'line2', + ])) + with open(fname) as f: + s = f.read() + nt.assert_in('line1\n', s) + nt.assert_in('line2', s) + +@dec.skip_win32 +def test_file_double_quote(): + """Basic %%writefile with embedded double quotes""" + ip = get_ipython() + with TemporaryDirectory() as td: + fname = os.path.join(td, '"file1"') + ip.run_cell_magic("writefile", fname, u'\n'.join([ + 'line1', + 'line2', + ])) + with open(fname) as f: + s = f.read() + nt.assert_in('line1\n', s) + nt.assert_in('line2', s) + +def test_file_var_expand(): + """%%writefile $filename""" + ip = get_ipython() + with TemporaryDirectory() as td: + fname = os.path.join(td, 'file1') + ip.user_ns['filename'] = fname + ip.run_cell_magic("writefile", '$filename', u'\n'.join([ + 'line1', + 'line2', + ])) + with open(fname) as f: + s = f.read() + nt.assert_in('line1\n', s) + nt.assert_in('line2', s) + +def test_file_unicode(): + """%%writefile with unicode cell""" + ip = get_ipython() + with TemporaryDirectory() as td: + fname = os.path.join(td, 'file1') + ip.run_cell_magic("writefile", fname, u'\n'.join([ + u'liné1', + u'liné2', + ])) + with io.open(fname, encoding='utf-8') as f: + s = f.read() + nt.assert_in(u'liné1\n', s) + nt.assert_in(u'liné2', s) + +def test_file_amend(): + """%%writefile -a amends files""" + ip = get_ipython() + with TemporaryDirectory() as td: + fname = os.path.join(td, 'file2') + ip.run_cell_magic("writefile", fname, u'\n'.join([ + 'line1', + 'line2', + ])) + ip.run_cell_magic("writefile", "-a %s" % fname, u'\n'.join([ + 'line3', + 'line4', + ])) + with open(fname) as f: + s = f.read() + nt.assert_in('line1\n', s) + nt.assert_in('line3\n', s) + +def test_file_spaces(): + """%%file with spaces in filename""" + ip = get_ipython() + with TemporaryWorkingDirectory() as td: + fname = "file name" + ip.run_cell_magic("file", '"%s"'%fname, u'\n'.join([ + 'line1', + 'line2', + ])) + with open(fname) as f: + s = f.read() + nt.assert_in('line1\n', s) + nt.assert_in('line2', s) + +def test_script_config(): + ip = get_ipython() + ip.config.ScriptMagics.script_magics = ['whoda'] + sm = script.ScriptMagics(shell=ip) + nt.assert_in('whoda', sm.magics['cell']) + +@dec.skip_win32 +def test_script_out(): + ip = get_ipython() + ip.run_cell_magic("script", "--out output sh", "echo 'hi'") + nt.assert_equal(ip.user_ns['output'], 'hi\n') + +@dec.skip_win32 +def test_script_err(): + ip = get_ipython() + ip.run_cell_magic("script", "--err error sh", "echo 'hello' >&2") + nt.assert_equal(ip.user_ns['error'], 'hello\n') + +@dec.skip_win32 +def test_script_out_err(): + ip = get_ipython() + ip.run_cell_magic("script", "--out output --err error sh", "echo 'hi'\necho 'hello' >&2") + nt.assert_equal(ip.user_ns['output'], 'hi\n') + nt.assert_equal(ip.user_ns['error'], 'hello\n') + +@dec.skip_win32 +def test_script_bg_out(): + ip = get_ipython() + ip.run_cell_magic("script", "--bg --out output sh", "echo 'hi'") + + nt.assert_equal(ip.user_ns['output'].read(), b'hi\n') + ip.user_ns['output'].close() + +@dec.skip_win32 +def test_script_bg_err(): + ip = get_ipython() + ip.run_cell_magic("script", "--bg --err error sh", "echo 'hello' >&2") + nt.assert_equal(ip.user_ns['error'].read(), b'hello\n') + ip.user_ns['error'].close() + +@dec.skip_win32 +def test_script_bg_out_err(): + ip = get_ipython() + ip.run_cell_magic("script", "--bg --out output --err error sh", "echo 'hi'\necho 'hello' >&2") + nt.assert_equal(ip.user_ns['output'].read(), b'hi\n') + nt.assert_equal(ip.user_ns['error'].read(), b'hello\n') + ip.user_ns['output'].close() + ip.user_ns['error'].close() + +def test_script_defaults(): + ip = get_ipython() + for cmd in ['sh', 'bash', 'perl', 'ruby']: + try: + find_cmd(cmd) + except Exception: + pass + else: + nt.assert_in(cmd, ip.magics_manager.magics['cell']) + + +@magics_class +class FooFoo(Magics): + """class with both %foo and %%foo magics""" + @line_magic('foo') + def line_foo(self, line): + "I am line foo" + pass + + @cell_magic("foo") + def cell_foo(self, line, cell): + "I am cell foo, not line foo" + pass + +def test_line_cell_info(): + """%%foo and %foo magics are distinguishable to inspect""" + ip = get_ipython() + ip.magics_manager.register(FooFoo) + oinfo = ip.object_inspect('foo') + nt.assert_true(oinfo['found']) + nt.assert_true(oinfo['ismagic']) + + oinfo = ip.object_inspect('%%foo') + nt.assert_true(oinfo['found']) + nt.assert_true(oinfo['ismagic']) + nt.assert_equal(oinfo['docstring'], FooFoo.cell_foo.__doc__) + + oinfo = ip.object_inspect('%foo') + nt.assert_true(oinfo['found']) + nt.assert_true(oinfo['ismagic']) + nt.assert_equal(oinfo['docstring'], FooFoo.line_foo.__doc__) + +def test_multiple_magics(): + ip = get_ipython() + foo1 = FooFoo(ip) + foo2 = FooFoo(ip) + mm = ip.magics_manager + mm.register(foo1) + nt.assert_true(mm.magics['line']['foo'].__self__ is foo1) + mm.register(foo2) + nt.assert_true(mm.magics['line']['foo'].__self__ is foo2) + +def test_alias_magic(): + """Test %alias_magic.""" + ip = get_ipython() + mm = ip.magics_manager + + # Basic operation: both cell and line magics are created, if possible. + ip.run_line_magic('alias_magic', 'timeit_alias timeit') + nt.assert_in('timeit_alias', mm.magics['line']) + nt.assert_in('timeit_alias', mm.magics['cell']) + + # --cell is specified, line magic not created. + ip.run_line_magic('alias_magic', '--cell timeit_cell_alias timeit') + nt.assert_not_in('timeit_cell_alias', mm.magics['line']) + nt.assert_in('timeit_cell_alias', mm.magics['cell']) + + # Test that line alias is created successfully. + ip.run_line_magic('alias_magic', '--line env_alias env') + nt.assert_equal(ip.run_line_magic('env', ''), + ip.run_line_magic('env_alias', '')) + + # Test that line alias with parameters passed in is created successfully. + ip.run_line_magic('alias_magic', '--line history_alias history --params ' + shlex.quote('3')) + nt.assert_in('history_alias', mm.magics['line']) + + +def test_save(): + """Test %save.""" + ip = get_ipython() + ip.history_manager.reset() # Clear any existing history. + cmds = [u"a=1", u"def b():\n return a**2", u"print(a, b())"] + for i, cmd in enumerate(cmds, start=1): + ip.history_manager.store_inputs(i, cmd) + with TemporaryDirectory() as tmpdir: + file = os.path.join(tmpdir, "testsave.py") + ip.run_line_magic("save", "%s 1-10" % file) + with open(file) as f: + content = f.read() + nt.assert_equal(content.count(cmds[0]), 1) + nt.assert_in('coding: utf-8', content) + ip.run_line_magic("save", "-a %s 1-10" % file) + with open(file) as f: + content = f.read() + nt.assert_equal(content.count(cmds[0]), 2) + nt.assert_in('coding: utf-8', content) + + +def test_store(): + """Test %store.""" + ip = get_ipython() + ip.run_line_magic('load_ext', 'storemagic') + + # make sure the storage is empty + ip.run_line_magic('store', '-z') + ip.user_ns['var'] = 42 + ip.run_line_magic('store', 'var') + ip.user_ns['var'] = 39 + ip.run_line_magic('store', '-r') + nt.assert_equal(ip.user_ns['var'], 42) + + ip.run_line_magic('store', '-d var') + ip.user_ns['var'] = 39 + ip.run_line_magic('store' , '-r') + nt.assert_equal(ip.user_ns['var'], 39) + + +def _run_edit_test(arg_s, exp_filename=None, + exp_lineno=-1, + exp_contents=None, + exp_is_temp=None): + ip = get_ipython() + M = code.CodeMagics(ip) + last_call = ['',''] + opts,args = M.parse_options(arg_s,'prxn:') + filename, lineno, is_temp = M._find_edit_target(ip, args, opts, last_call) + + if exp_filename is not None: + nt.assert_equal(exp_filename, filename) + if exp_contents is not None: + with io.open(filename, 'r', encoding='utf-8') as f: + contents = f.read() + nt.assert_equal(exp_contents, contents) + if exp_lineno != -1: + nt.assert_equal(exp_lineno, lineno) + if exp_is_temp is not None: + nt.assert_equal(exp_is_temp, is_temp) + + +def test_edit_interactive(): + """%edit on interactively defined objects""" + ip = get_ipython() + n = ip.execution_count + ip.run_cell(u"def foo(): return 1", store_history=True) + + try: + _run_edit_test("foo") + except code.InteractivelyDefined as e: + nt.assert_equal(e.index, n) + else: + raise AssertionError("Should have raised InteractivelyDefined") + + +def test_edit_cell(): + """%edit [cell id]""" + ip = get_ipython() + + ip.run_cell(u"def foo(): return 1", store_history=True) + + # test + _run_edit_test("1", exp_contents=ip.user_ns['In'][1], exp_is_temp=True) + +def test_bookmark(): + ip = get_ipython() + ip.run_line_magic('bookmark', 'bmname') + with tt.AssertPrints('bmname'): + ip.run_line_magic('bookmark', '-l') + ip.run_line_magic('bookmark', '-d bmname') + +def test_ls_magic(): + ip = get_ipython() + json_formatter = ip.display_formatter.formatters['application/json'] + json_formatter.enabled = True + lsmagic = ip.magic('lsmagic') + with warnings.catch_warnings(record=True) as w: + j = json_formatter(lsmagic) + nt.assert_equal(sorted(j), ['cell', 'line']) + nt.assert_equal(w, []) # no warnings + +def test_strip_initial_indent(): + def sii(s): + lines = s.splitlines() + return '\n'.join(code.strip_initial_indent(lines)) + + nt.assert_equal(sii(" a = 1\nb = 2"), "a = 1\nb = 2") + nt.assert_equal(sii(" a\n b\nc"), "a\n b\nc") + nt.assert_equal(sii("a\n b"), "a\n b") + +def test_logging_magic_quiet_from_arg(): + _ip.config.LoggingMagics.quiet = False + lm = logging.LoggingMagics(shell=_ip) + with TemporaryDirectory() as td: + try: + with tt.AssertNotPrints(re.compile("Activating.*")): + lm.logstart('-q {}'.format( + os.path.join(td, "quiet_from_arg.log"))) + finally: + _ip.logger.logstop() + +def test_logging_magic_quiet_from_config(): + _ip.config.LoggingMagics.quiet = True + lm = logging.LoggingMagics(shell=_ip) + with TemporaryDirectory() as td: + try: + with tt.AssertNotPrints(re.compile("Activating.*")): + lm.logstart(os.path.join(td, "quiet_from_config.log")) + finally: + _ip.logger.logstop() + + +def test_logging_magic_not_quiet(): + _ip.config.LoggingMagics.quiet = False + lm = logging.LoggingMagics(shell=_ip) + with TemporaryDirectory() as td: + try: + with tt.AssertPrints(re.compile("Activating.*")): + lm.logstart(os.path.join(td, "not_quiet.log")) + finally: + _ip.logger.logstop() + + +def test_time_no_var_expand(): + _ip.user_ns['a'] = 5 + _ip.user_ns['b'] = [] + _ip.magic('time b.append("{a}")') + assert _ip.user_ns['b'] == ['{a}'] + + +# this is slow, put at the end for local testing. +def test_timeit_arguments(): + "Test valid timeit arguments, should not cause SyntaxError (GH #1269)" + if sys.version_info < (3,7): + _ip.magic("timeit -n1 -r1 ('#')") + else: + # 3.7 optimize no-op statement like above out, and complain there is + # nothing in the for loop. + _ip.magic("timeit -n1 -r1 a=('#')") diff --git a/.venv/lib/python3.8/site-packages/IPython/core/tests/test_magic_arguments.py b/.venv/lib/python3.8/site-packages/IPython/core/tests/test_magic_arguments.py new file mode 100644 index 00000000..5dea32dd --- /dev/null +++ b/.venv/lib/python3.8/site-packages/IPython/core/tests/test_magic_arguments.py @@ -0,0 +1,118 @@ +#----------------------------------------------------------------------------- +# Copyright (C) 2010-2011, IPython Development Team. +# +# Distributed under the terms of the Modified BSD License. +# +# The full license is in the file COPYING.txt, distributed with this software. +#----------------------------------------------------------------------------- + +import argparse +from nose.tools import assert_equal + +from IPython.core.magic_arguments import (argument, argument_group, kwds, + magic_arguments, parse_argstring, real_name) + + +@magic_arguments() +@argument('-f', '--foo', help="an argument") +def magic_foo1(self, args): + """ A docstring. + """ + return parse_argstring(magic_foo1, args) + + +@magic_arguments() +def magic_foo2(self, args): + """ A docstring. + """ + return parse_argstring(magic_foo2, args) + + +@magic_arguments() +@argument('-f', '--foo', help="an argument") +@argument_group('Group') +@argument('-b', '--bar', help="a grouped argument") +@argument_group('Second Group') +@argument('-z', '--baz', help="another grouped argument") +def magic_foo3(self, args): + """ A docstring. + """ + return parse_argstring(magic_foo3, args) + + +@magic_arguments() +@kwds(argument_default=argparse.SUPPRESS) +@argument('-f', '--foo', help="an argument") +def magic_foo4(self, args): + """ A docstring. + """ + return parse_argstring(magic_foo4, args) + + +@magic_arguments('frobnicate') +@argument('-f', '--foo', help="an argument") +def magic_foo5(self, args): + """ A docstring. + """ + return parse_argstring(magic_foo5, args) + + +@magic_arguments() +@argument('-f', '--foo', help="an argument") +def magic_magic_foo(self, args): + """ A docstring. + """ + return parse_argstring(magic_magic_foo, args) + + +@magic_arguments() +@argument('-f', '--foo', help="an argument") +def foo(self, args): + """ A docstring. + """ + return parse_argstring(foo, args) + + +def test_magic_arguments(): + assert_equal(magic_foo1.__doc__, '::\n\n %foo1 [-f FOO]\n\n A docstring.\n\noptional arguments:\n -f FOO, --foo FOO an argument\n') + assert_equal(getattr(magic_foo1, 'argcmd_name', None), None) + assert_equal(real_name(magic_foo1), 'foo1') + assert_equal(magic_foo1(None, ''), argparse.Namespace(foo=None)) + assert hasattr(magic_foo1, 'has_arguments') + + assert_equal(magic_foo2.__doc__, '::\n\n %foo2\n\n A docstring.\n') + assert_equal(getattr(magic_foo2, 'argcmd_name', None), None) + assert_equal(real_name(magic_foo2), 'foo2') + assert_equal(magic_foo2(None, ''), argparse.Namespace()) + assert hasattr(magic_foo2, 'has_arguments') + + assert_equal(magic_foo3.__doc__, '::\n\n %foo3 [-f FOO] [-b BAR] [-z BAZ]\n\n A docstring.\n\noptional arguments:\n -f FOO, --foo FOO an argument\n\nGroup:\n -b BAR, --bar BAR a grouped argument\n\nSecond Group:\n -z BAZ, --baz BAZ another grouped argument\n') + assert_equal(getattr(magic_foo3, 'argcmd_name', None), None) + assert_equal(real_name(magic_foo3), 'foo3') + assert_equal(magic_foo3(None, ''), + argparse.Namespace(bar=None, baz=None, foo=None)) + assert hasattr(magic_foo3, 'has_arguments') + + assert_equal(magic_foo4.__doc__, '::\n\n %foo4 [-f FOO]\n\n A docstring.\n\noptional arguments:\n -f FOO, --foo FOO an argument\n') + assert_equal(getattr(magic_foo4, 'argcmd_name', None), None) + assert_equal(real_name(magic_foo4), 'foo4') + assert_equal(magic_foo4(None, ''), argparse.Namespace()) + assert hasattr(magic_foo4, 'has_arguments') + + assert_equal(magic_foo5.__doc__, '::\n\n %frobnicate [-f FOO]\n\n A docstring.\n\noptional arguments:\n -f FOO, --foo FOO an argument\n') + assert_equal(getattr(magic_foo5, 'argcmd_name', None), 'frobnicate') + assert_equal(real_name(magic_foo5), 'frobnicate') + assert_equal(magic_foo5(None, ''), argparse.Namespace(foo=None)) + assert hasattr(magic_foo5, 'has_arguments') + + assert_equal(magic_magic_foo.__doc__, '::\n\n %magic_foo [-f FOO]\n\n A docstring.\n\noptional arguments:\n -f FOO, --foo FOO an argument\n') + assert_equal(getattr(magic_magic_foo, 'argcmd_name', None), None) + assert_equal(real_name(magic_magic_foo), 'magic_foo') + assert_equal(magic_magic_foo(None, ''), argparse.Namespace(foo=None)) + assert hasattr(magic_magic_foo, 'has_arguments') + + assert_equal(foo.__doc__, '::\n\n %foo [-f FOO]\n\n A docstring.\n\noptional arguments:\n -f FOO, --foo FOO an argument\n') + assert_equal(getattr(foo, 'argcmd_name', None), None) + assert_equal(real_name(foo), 'foo') + assert_equal(foo(None, ''), argparse.Namespace(foo=None)) + assert hasattr(foo, 'has_arguments') diff --git a/.venv/lib/python3.8/site-packages/IPython/core/tests/test_magic_terminal.py b/.venv/lib/python3.8/site-packages/IPython/core/tests/test_magic_terminal.py new file mode 100644 index 00000000..79e2d3ed --- /dev/null +++ b/.venv/lib/python3.8/site-packages/IPython/core/tests/test_magic_terminal.py @@ -0,0 +1,192 @@ +"""Tests for various magic functions specific to the terminal frontend. + +Needs to be run by nose (to make ipython session available). +""" + +#----------------------------------------------------------------------------- +# Imports +#----------------------------------------------------------------------------- + +import sys +from io import StringIO +from unittest import TestCase + +import nose.tools as nt + +from IPython.testing import tools as tt + +#----------------------------------------------------------------------------- +# Test functions begin +#----------------------------------------------------------------------------- + +def check_cpaste(code, should_fail=False): + """Execute code via 'cpaste' and ensure it was executed, unless + should_fail is set. + """ + ip.user_ns['code_ran'] = False + + src = StringIO() + if not hasattr(src, 'encoding'): + # IPython expects stdin to have an encoding attribute + src.encoding = None + src.write(code) + src.write('\n--\n') + src.seek(0) + + stdin_save = sys.stdin + sys.stdin = src + + try: + context = tt.AssertPrints if should_fail else tt.AssertNotPrints + with context("Traceback (most recent call last)"): + ip.magic('cpaste') + + if not should_fail: + assert ip.user_ns['code_ran'], "%r failed" % code + finally: + sys.stdin = stdin_save + +def test_cpaste(): + """Test cpaste magic""" + + def runf(): + """Marker function: sets a flag when executed. + """ + ip.user_ns['code_ran'] = True + return 'runf' # return string so '+ runf()' doesn't result in success + + tests = {'pass': ["runf()", + "In [1]: runf()", + "In [1]: if 1:\n ...: runf()", + "> > > runf()", + ">>> runf()", + " >>> runf()", + ], + + 'fail': ["1 + runf()", + "++ runf()", + ]} + + ip.user_ns['runf'] = runf + + for code in tests['pass']: + check_cpaste(code) + + for code in tests['fail']: + check_cpaste(code, should_fail=True) + + +class PasteTestCase(TestCase): + """Multiple tests for clipboard pasting""" + + def paste(self, txt, flags='-q'): + """Paste input text, by default in quiet mode""" + ip.hooks.clipboard_get = lambda : txt + ip.magic('paste '+flags) + + def setUp(self): + # Inject fake clipboard hook but save original so we can restore it later + self.original_clip = ip.hooks.clipboard_get + + def tearDown(self): + # Restore original hook + ip.hooks.clipboard_get = self.original_clip + + def test_paste(self): + ip.user_ns.pop('x', None) + self.paste('x = 1') + nt.assert_equal(ip.user_ns['x'], 1) + ip.user_ns.pop('x') + + def test_paste_pyprompt(self): + ip.user_ns.pop('x', None) + self.paste('>>> x=2') + nt.assert_equal(ip.user_ns['x'], 2) + ip.user_ns.pop('x') + + def test_paste_py_multi(self): + self.paste(""" + >>> x = [1,2,3] + >>> y = [] + >>> for i in x: + ... y.append(i**2) + ... + """) + nt.assert_equal(ip.user_ns['x'], [1,2,3]) + nt.assert_equal(ip.user_ns['y'], [1,4,9]) + + def test_paste_py_multi_r(self): + "Now, test that self.paste -r works" + self.test_paste_py_multi() + nt.assert_equal(ip.user_ns.pop('x'), [1,2,3]) + nt.assert_equal(ip.user_ns.pop('y'), [1,4,9]) + nt.assert_false('x' in ip.user_ns) + ip.magic('paste -r') + nt.assert_equal(ip.user_ns['x'], [1,2,3]) + nt.assert_equal(ip.user_ns['y'], [1,4,9]) + + def test_paste_email(self): + "Test pasting of email-quoted contents" + self.paste("""\ + >> def foo(x): + >> return x + 1 + >> xx = foo(1.1)""") + nt.assert_equal(ip.user_ns['xx'], 2.1) + + def test_paste_email2(self): + "Email again; some programs add a space also at each quoting level" + self.paste("""\ + > > def foo(x): + > > return x + 1 + > > yy = foo(2.1) """) + nt.assert_equal(ip.user_ns['yy'], 3.1) + + def test_paste_email_py(self): + "Email quoting of interactive input" + self.paste("""\ + >> >>> def f(x): + >> ... return x+1 + >> ... + >> >>> zz = f(2.5) """) + nt.assert_equal(ip.user_ns['zz'], 3.5) + + def test_paste_echo(self): + "Also test self.paste echoing, by temporarily faking the writer" + w = StringIO() + writer = ip.write + ip.write = w.write + code = """ + a = 100 + b = 200""" + try: + self.paste(code,'') + out = w.getvalue() + finally: + ip.write = writer + nt.assert_equal(ip.user_ns['a'], 100) + nt.assert_equal(ip.user_ns['b'], 200) + assert out == code+"\n## -- End pasted text --\n" + + def test_paste_leading_commas(self): + "Test multiline strings with leading commas" + tm = ip.magics_manager.registry['TerminalMagics'] + s = '''\ +a = """ +,1,2,3 +"""''' + ip.user_ns.pop('foo', None) + tm.store_or_execute(s, 'foo') + nt.assert_in('foo', ip.user_ns) + + + def test_paste_trailing_question(self): + "Test pasting sources with trailing question marks" + tm = ip.magics_manager.registry['TerminalMagics'] + s = '''\ +def funcfoo(): + if True: #am i true? + return 'fooresult' +''' + ip.user_ns.pop('funcfoo', None) + self.paste(s) + nt.assert_equal(ip.user_ns['funcfoo'](), 'fooresult') diff --git a/.venv/lib/python3.8/site-packages/IPython/core/tests/test_oinspect.py b/.venv/lib/python3.8/site-packages/IPython/core/tests/test_oinspect.py new file mode 100644 index 00000000..19c6db7c --- /dev/null +++ b/.venv/lib/python3.8/site-packages/IPython/core/tests/test_oinspect.py @@ -0,0 +1,447 @@ +"""Tests for the object inspection functionality. +""" + +# Copyright (c) IPython Development Team. +# Distributed under the terms of the Modified BSD License. + + +from inspect import signature, Signature, Parameter +import os +import re + +import nose.tools as nt + +from .. import oinspect + +from decorator import decorator + +from IPython.testing.tools import AssertPrints, AssertNotPrints +from IPython.utils.path import compress_user + + +#----------------------------------------------------------------------------- +# Globals and constants +#----------------------------------------------------------------------------- + +inspector = None + +def setup_module(): + global inspector + inspector = oinspect.Inspector() + + +#----------------------------------------------------------------------------- +# Local utilities +#----------------------------------------------------------------------------- + +# WARNING: since this test checks the line number where a function is +# defined, if any code is inserted above, the following line will need to be +# updated. Do NOT insert any whitespace between the next line and the function +# definition below. +THIS_LINE_NUMBER = 41 # Put here the actual number of this line + +from unittest import TestCase + +class Test(TestCase): + + def test_find_source_lines(self): + self.assertEqual(oinspect.find_source_lines(Test.test_find_source_lines), + THIS_LINE_NUMBER+6) + + +# A couple of utilities to ensure these tests work the same from a source or a +# binary install +def pyfile(fname): + return os.path.normcase(re.sub('.py[co]$', '.py', fname)) + + +def match_pyfiles(f1, f2): + nt.assert_equal(pyfile(f1), pyfile(f2)) + + +def test_find_file(): + match_pyfiles(oinspect.find_file(test_find_file), os.path.abspath(__file__)) + + +def test_find_file_decorated1(): + + @decorator + def noop1(f): + def wrapper(*a, **kw): + return f(*a, **kw) + return wrapper + + @noop1 + def f(x): + "My docstring" + + match_pyfiles(oinspect.find_file(f), os.path.abspath(__file__)) + nt.assert_equal(f.__doc__, "My docstring") + + +def test_find_file_decorated2(): + + @decorator + def noop2(f, *a, **kw): + return f(*a, **kw) + + @noop2 + @noop2 + @noop2 + def f(x): + "My docstring 2" + + match_pyfiles(oinspect.find_file(f), os.path.abspath(__file__)) + nt.assert_equal(f.__doc__, "My docstring 2") + + +def test_find_file_magic(): + run = ip.find_line_magic('run') + nt.assert_not_equal(oinspect.find_file(run), None) + + +# A few generic objects we can then inspect in the tests below + +class Call(object): + """This is the class docstring.""" + + def __init__(self, x, y=1): + """This is the constructor docstring.""" + + def __call__(self, *a, **kw): + """This is the call docstring.""" + + def method(self, x, z=2): + """Some method's docstring""" + +class HasSignature(object): + """This is the class docstring.""" + __signature__ = Signature([Parameter('test', Parameter.POSITIONAL_OR_KEYWORD)]) + + def __init__(self, *args): + """This is the init docstring""" + + +class SimpleClass(object): + def method(self, x, z=2): + """Some method's docstring""" + + +class Awkward(object): + def __getattr__(self, name): + raise Exception(name) + +class NoBoolCall: + """ + callable with `__bool__` raising should still be inspect-able. + """ + + def __call__(self): + """does nothing""" + pass + + def __bool__(self): + """just raise NotImplemented""" + raise NotImplementedError('Must be implemented') + + +class SerialLiar(object): + """Attribute accesses always get another copy of the same class. + + unittest.mock.call does something similar, but it's not ideal for testing + as the failure mode is to eat all your RAM. This gives up after 10k levels. + """ + def __init__(self, max_fibbing_twig, lies_told=0): + if lies_told > 10000: + raise RuntimeError('Nose too long, honesty is the best policy') + self.max_fibbing_twig = max_fibbing_twig + self.lies_told = lies_told + max_fibbing_twig[0] = max(max_fibbing_twig[0], lies_told) + + def __getattr__(self, item): + return SerialLiar(self.max_fibbing_twig, self.lies_told + 1) + +#----------------------------------------------------------------------------- +# Tests +#----------------------------------------------------------------------------- + +def test_info(): + "Check that Inspector.info fills out various fields as expected." + i = inspector.info(Call, oname='Call') + nt.assert_equal(i['type_name'], 'type') + expted_class = str(type(type)) # (Python 3) or + nt.assert_equal(i['base_class'], expted_class) + nt.assert_regex(i['string_form'], "") + fname = __file__ + if fname.endswith(".pyc"): + fname = fname[:-1] + # case-insensitive comparison needed on some filesystems + # e.g. Windows: + nt.assert_equal(i['file'].lower(), compress_user(fname).lower()) + nt.assert_equal(i['definition'], None) + nt.assert_equal(i['docstring'], Call.__doc__) + nt.assert_equal(i['source'], None) + nt.assert_true(i['isclass']) + nt.assert_equal(i['init_definition'], "Call(x, y=1)") + nt.assert_equal(i['init_docstring'], Call.__init__.__doc__) + + i = inspector.info(Call, detail_level=1) + nt.assert_not_equal(i['source'], None) + nt.assert_equal(i['docstring'], None) + + c = Call(1) + c.__doc__ = "Modified instance docstring" + i = inspector.info(c) + nt.assert_equal(i['type_name'], 'Call') + nt.assert_equal(i['docstring'], "Modified instance docstring") + nt.assert_equal(i['class_docstring'], Call.__doc__) + nt.assert_equal(i['init_docstring'], Call.__init__.__doc__) + nt.assert_equal(i['call_docstring'], Call.__call__.__doc__) + +def test_class_signature(): + info = inspector.info(HasSignature, 'HasSignature') + nt.assert_equal(info['init_definition'], "HasSignature(test)") + nt.assert_equal(info['init_docstring'], HasSignature.__init__.__doc__) + +def test_info_awkward(): + # Just test that this doesn't throw an error. + inspector.info(Awkward()) + +def test_bool_raise(): + inspector.info(NoBoolCall()) + +def test_info_serialliar(): + fib_tracker = [0] + inspector.info(SerialLiar(fib_tracker)) + + # Nested attribute access should be cut off at 100 levels deep to avoid + # infinite loops: https://github.com/ipython/ipython/issues/9122 + nt.assert_less(fib_tracker[0], 9000) + +def support_function_one(x, y=2, *a, **kw): + """A simple function.""" + +def test_calldef_none(): + # We should ignore __call__ for all of these. + for obj in [support_function_one, SimpleClass().method, any, str.upper]: + i = inspector.info(obj) + nt.assert_is(i['call_def'], None) + +def f_kwarg(pos, *, kwonly): + pass + +def test_definition_kwonlyargs(): + i = inspector.info(f_kwarg, oname='f_kwarg') # analysis:ignore + nt.assert_equal(i['definition'], "f_kwarg(pos, *, kwonly)") + +def test_getdoc(): + class A(object): + """standard docstring""" + pass + + class B(object): + """standard docstring""" + def getdoc(self): + return "custom docstring" + + class C(object): + """standard docstring""" + def getdoc(self): + return None + + a = A() + b = B() + c = C() + + nt.assert_equal(oinspect.getdoc(a), "standard docstring") + nt.assert_equal(oinspect.getdoc(b), "custom docstring") + nt.assert_equal(oinspect.getdoc(c), "standard docstring") + + +def test_empty_property_has_no_source(): + i = inspector.info(property(), detail_level=1) + nt.assert_is(i['source'], None) + + +def test_property_sources(): + import posixpath + # A simple adder whose source and signature stays + # the same across Python distributions + def simple_add(a, b): + "Adds two numbers" + return a + b + + class A(object): + @property + def foo(self): + return 'bar' + + foo = foo.setter(lambda self, v: setattr(self, 'bar', v)) + + dname = property(posixpath.dirname) + adder = property(simple_add) + + i = inspector.info(A.foo, detail_level=1) + nt.assert_in('def foo(self):', i['source']) + nt.assert_in('lambda self, v:', i['source']) + + i = inspector.info(A.dname, detail_level=1) + nt.assert_in('def dirname(p)', i['source']) + + i = inspector.info(A.adder, detail_level=1) + nt.assert_in('def simple_add(a, b)', i['source']) + + +def test_property_docstring_is_in_info_for_detail_level_0(): + class A(object): + @property + def foobar(self): + """This is `foobar` property.""" + pass + + ip.user_ns['a_obj'] = A() + nt.assert_equal( + 'This is `foobar` property.', + ip.object_inspect('a_obj.foobar', detail_level=0)['docstring']) + + ip.user_ns['a_cls'] = A + nt.assert_equal( + 'This is `foobar` property.', + ip.object_inspect('a_cls.foobar', detail_level=0)['docstring']) + + +def test_pdef(): + # See gh-1914 + def foo(): pass + inspector.pdef(foo, 'foo') + + +def test_pinfo_nonascii(): + # See gh-1177 + from . import nonascii2 + ip.user_ns['nonascii2'] = nonascii2 + ip._inspect('pinfo', 'nonascii2', detail_level=1) + +def test_pinfo_type(): + """ + type can fail in various edge case, for example `type.__subclass__()` + """ + ip._inspect('pinfo', 'type') + + +def test_pinfo_docstring_no_source(): + """Docstring should be included with detail_level=1 if there is no source""" + with AssertPrints('Docstring:'): + ip._inspect('pinfo', 'str.format', detail_level=0) + with AssertPrints('Docstring:'): + ip._inspect('pinfo', 'str.format', detail_level=1) + + +def test_pinfo_no_docstring_if_source(): + """Docstring should not be included with detail_level=1 if source is found""" + def foo(): + """foo has a docstring""" + + ip.user_ns['foo'] = foo + + with AssertPrints('Docstring:'): + ip._inspect('pinfo', 'foo', detail_level=0) + with AssertPrints('Source:'): + ip._inspect('pinfo', 'foo', detail_level=1) + with AssertNotPrints('Docstring:'): + ip._inspect('pinfo', 'foo', detail_level=1) + + +def test_pinfo_docstring_if_detail_and_no_source(): + """ Docstring should be displayed if source info not available """ + obj_def = '''class Foo(object): + """ This is a docstring for Foo """ + def bar(self): + """ This is a docstring for Foo.bar """ + pass + ''' + + ip.run_cell(obj_def) + ip.run_cell('foo = Foo()') + + with AssertNotPrints("Source:"): + with AssertPrints('Docstring:'): + ip._inspect('pinfo', 'foo', detail_level=0) + with AssertPrints('Docstring:'): + ip._inspect('pinfo', 'foo', detail_level=1) + with AssertPrints('Docstring:'): + ip._inspect('pinfo', 'foo.bar', detail_level=0) + + with AssertNotPrints('Docstring:'): + with AssertPrints('Source:'): + ip._inspect('pinfo', 'foo.bar', detail_level=1) + + +def test_pinfo_magic(): + with AssertPrints('Docstring:'): + ip._inspect('pinfo', 'lsmagic', detail_level=0) + + with AssertPrints('Source:'): + ip._inspect('pinfo', 'lsmagic', detail_level=1) + + +def test_init_colors(): + # ensure colors are not present in signature info + info = inspector.info(HasSignature) + init_def = info['init_definition'] + nt.assert_not_in('[0m', init_def) + + +def test_builtin_init(): + info = inspector.info(list) + init_def = info['init_definition'] + nt.assert_is_not_none(init_def) + + +def test_render_signature_short(): + def short_fun(a=1): pass + sig = oinspect._render_signature( + signature(short_fun), + short_fun.__name__, + ) + nt.assert_equal(sig, 'short_fun(a=1)') + + +def test_render_signature_long(): + from typing import Optional + + def long_function( + a_really_long_parameter: int, + and_another_long_one: bool = False, + let_us_make_sure_this_is_looong: Optional[str] = None, + ) -> bool: pass + + sig = oinspect._render_signature( + signature(long_function), + long_function.__name__, + ) + nt.assert_in(sig, [ + # Python >=3.9 + '''\ +long_function( + a_really_long_parameter: int, + and_another_long_one: bool = False, + let_us_make_sure_this_is_looong: Optional[str] = None, +) -> bool\ +''', + # Python >=3.7 + '''\ +long_function( + a_really_long_parameter: int, + and_another_long_one: bool = False, + let_us_make_sure_this_is_looong: Union[str, NoneType] = None, +) -> bool\ +''', # Python <=3.6 + '''\ +long_function( + a_really_long_parameter:int, + and_another_long_one:bool=False, + let_us_make_sure_this_is_looong:Union[str, NoneType]=None, +) -> bool\ +''', + ]) diff --git a/.venv/lib/python3.8/site-packages/IPython/core/tests/test_page.py b/.venv/lib/python3.8/site-packages/IPython/core/tests/test_page.py new file mode 100644 index 00000000..9f6a3742 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/IPython/core/tests/test_page.py @@ -0,0 +1,20 @@ +#----------------------------------------------------------------------------- +# Copyright (C) 2010-2011 The IPython Development Team. +# +# Distributed under the terms of the BSD License. +# +# The full license is in the file COPYING.txt, distributed with this software. +#----------------------------------------------------------------------------- +import io + +# N.B. For the test suite, page.page is overridden (see IPython.testing.globalipapp) +from IPython.core import page + +def test_detect_screen_size(): + """Simple smoketest for page._detect_screen_size.""" + try: + page._detect_screen_size(True, 25) + except (TypeError, io.UnsupportedOperation): + # This can happen in the test suite, because stdout may not have a + # fileno. + pass diff --git a/.venv/lib/python3.8/site-packages/IPython/core/tests/test_paths.py b/.venv/lib/python3.8/site-packages/IPython/core/tests/test_paths.py new file mode 100644 index 00000000..ab1c4132 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/IPython/core/tests/test_paths.py @@ -0,0 +1,200 @@ +import errno +import os +import shutil +import sys +import tempfile +import warnings +from unittest.mock import patch + +import nose.tools as nt +from testpath import modified_env, assert_isdir, assert_isfile + +from IPython import paths +from IPython.testing.decorators import skip_win32 +from IPython.utils.tempdir import TemporaryDirectory + +TMP_TEST_DIR = os.path.realpath(tempfile.mkdtemp()) +HOME_TEST_DIR = os.path.join(TMP_TEST_DIR, "home_test_dir") +XDG_TEST_DIR = os.path.join(HOME_TEST_DIR, "xdg_test_dir") +XDG_CACHE_DIR = os.path.join(HOME_TEST_DIR, "xdg_cache_dir") +IP_TEST_DIR = os.path.join(HOME_TEST_DIR,'.ipython') + +def setup_module(): + """Setup testenvironment for the module: + + - Adds dummy home dir tree + """ + # Do not mask exceptions here. In particular, catching WindowsError is a + # problem because that exception is only defined on Windows... + os.makedirs(IP_TEST_DIR) + os.makedirs(os.path.join(XDG_TEST_DIR, 'ipython')) + os.makedirs(os.path.join(XDG_CACHE_DIR, 'ipython')) + + +def teardown_module(): + """Teardown testenvironment for the module: + + - Remove dummy home dir tree + """ + # Note: we remove the parent test dir, which is the root of all test + # subdirs we may have created. Use shutil instead of os.removedirs, so + # that non-empty directories are all recursively removed. + shutil.rmtree(TMP_TEST_DIR) + +def patch_get_home_dir(dirpath): + return patch.object(paths, 'get_home_dir', return_value=dirpath) + + +def test_get_ipython_dir_1(): + """test_get_ipython_dir_1, Testcase to see if we can call get_ipython_dir without Exceptions.""" + env_ipdir = os.path.join("someplace", ".ipython") + with patch.object(paths, '_writable_dir', return_value=True), \ + modified_env({'IPYTHONDIR': env_ipdir}): + ipdir = paths.get_ipython_dir() + + nt.assert_equal(ipdir, env_ipdir) + +def test_get_ipython_dir_2(): + """test_get_ipython_dir_2, Testcase to see if we can call get_ipython_dir without Exceptions.""" + with patch_get_home_dir('someplace'), \ + patch.object(paths, 'get_xdg_dir', return_value=None), \ + patch.object(paths, '_writable_dir', return_value=True), \ + patch('os.name', "posix"), \ + modified_env({'IPYTHON_DIR': None, + 'IPYTHONDIR': None, + 'XDG_CONFIG_HOME': None + }): + ipdir = paths.get_ipython_dir() + + nt.assert_equal(ipdir, os.path.join("someplace", ".ipython")) + +def test_get_ipython_dir_3(): + """test_get_ipython_dir_3, move XDG if defined, and .ipython doesn't exist.""" + tmphome = TemporaryDirectory() + try: + with patch_get_home_dir(tmphome.name), \ + patch('os.name', 'posix'), \ + modified_env({ + 'IPYTHON_DIR': None, + 'IPYTHONDIR': None, + 'XDG_CONFIG_HOME': XDG_TEST_DIR, + }), warnings.catch_warnings(record=True) as w: + ipdir = paths.get_ipython_dir() + + nt.assert_equal(ipdir, os.path.join(tmphome.name, ".ipython")) + if sys.platform != 'darwin': + nt.assert_equal(len(w), 1) + nt.assert_in('Moving', str(w[0])) + finally: + tmphome.cleanup() + +def test_get_ipython_dir_4(): + """test_get_ipython_dir_4, warn if XDG and home both exist.""" + with patch_get_home_dir(HOME_TEST_DIR), \ + patch('os.name', 'posix'): + try: + os.mkdir(os.path.join(XDG_TEST_DIR, 'ipython')) + except OSError as e: + if e.errno != errno.EEXIST: + raise + + + with modified_env({ + 'IPYTHON_DIR': None, + 'IPYTHONDIR': None, + 'XDG_CONFIG_HOME': XDG_TEST_DIR, + }), warnings.catch_warnings(record=True) as w: + ipdir = paths.get_ipython_dir() + + nt.assert_equal(ipdir, os.path.join(HOME_TEST_DIR, ".ipython")) + if sys.platform != 'darwin': + nt.assert_equal(len(w), 1) + nt.assert_in('Ignoring', str(w[0])) + +def test_get_ipython_dir_5(): + """test_get_ipython_dir_5, use .ipython if exists and XDG defined, but doesn't exist.""" + with patch_get_home_dir(HOME_TEST_DIR), \ + patch('os.name', 'posix'): + try: + os.rmdir(os.path.join(XDG_TEST_DIR, 'ipython')) + except OSError as e: + if e.errno != errno.ENOENT: + raise + + with modified_env({ + 'IPYTHON_DIR': None, + 'IPYTHONDIR': None, + 'XDG_CONFIG_HOME': XDG_TEST_DIR, + }): + ipdir = paths.get_ipython_dir() + + nt.assert_equal(ipdir, IP_TEST_DIR) + +def test_get_ipython_dir_6(): + """test_get_ipython_dir_6, use home over XDG if defined and neither exist.""" + xdg = os.path.join(HOME_TEST_DIR, 'somexdg') + os.mkdir(xdg) + shutil.rmtree(os.path.join(HOME_TEST_DIR, '.ipython')) + print(paths._writable_dir) + with patch_get_home_dir(HOME_TEST_DIR), \ + patch.object(paths, 'get_xdg_dir', return_value=xdg), \ + patch('os.name', 'posix'), \ + modified_env({ + 'IPYTHON_DIR': None, + 'IPYTHONDIR': None, + 'XDG_CONFIG_HOME': None, + }), warnings.catch_warnings(record=True) as w: + ipdir = paths.get_ipython_dir() + + nt.assert_equal(ipdir, os.path.join(HOME_TEST_DIR, '.ipython')) + nt.assert_equal(len(w), 0) + +def test_get_ipython_dir_7(): + """test_get_ipython_dir_7, test home directory expansion on IPYTHONDIR""" + home_dir = os.path.normpath(os.path.expanduser('~')) + with modified_env({'IPYTHONDIR': os.path.join('~', 'somewhere')}), \ + patch.object(paths, '_writable_dir', return_value=True): + ipdir = paths.get_ipython_dir() + nt.assert_equal(ipdir, os.path.join(home_dir, 'somewhere')) + +@skip_win32 +def test_get_ipython_dir_8(): + """test_get_ipython_dir_8, test / home directory""" + with patch.object(paths, '_writable_dir', lambda path: bool(path)), \ + patch.object(paths, 'get_xdg_dir', return_value=None), \ + modified_env({ + 'IPYTHON_DIR': None, + 'IPYTHONDIR': None, + 'HOME': '/', + }): + nt.assert_equal(paths.get_ipython_dir(), '/.ipython') + + +def test_get_ipython_cache_dir(): + with modified_env({'HOME': HOME_TEST_DIR}): + if os.name == 'posix' and sys.platform != 'darwin': + # test default + os.makedirs(os.path.join(HOME_TEST_DIR, ".cache")) + with modified_env({'XDG_CACHE_HOME': None}): + ipdir = paths.get_ipython_cache_dir() + nt.assert_equal(os.path.join(HOME_TEST_DIR, ".cache", "ipython"), + ipdir) + assert_isdir(ipdir) + + # test env override + with modified_env({"XDG_CACHE_HOME": XDG_CACHE_DIR}): + ipdir = paths.get_ipython_cache_dir() + assert_isdir(ipdir) + nt.assert_equal(ipdir, os.path.join(XDG_CACHE_DIR, "ipython")) + else: + nt.assert_equal(paths.get_ipython_cache_dir(), + paths.get_ipython_dir()) + +def test_get_ipython_package_dir(): + ipdir = paths.get_ipython_package_dir() + assert_isdir(ipdir) + + +def test_get_ipython_module_path(): + ipapp_path = paths.get_ipython_module_path('IPython.terminal.ipapp') + assert_isfile(ipapp_path) diff --git a/.venv/lib/python3.8/site-packages/IPython/core/tests/test_prefilter.py b/.venv/lib/python3.8/site-packages/IPython/core/tests/test_prefilter.py new file mode 100644 index 00000000..ca447b3d --- /dev/null +++ b/.venv/lib/python3.8/site-packages/IPython/core/tests/test_prefilter.py @@ -0,0 +1,127 @@ +"""Tests for input manipulation machinery.""" + +#----------------------------------------------------------------------------- +# Imports +#----------------------------------------------------------------------------- +import nose.tools as nt + +from IPython.core.prefilter import AutocallChecker + +#----------------------------------------------------------------------------- +# Tests +#----------------------------------------------------------------------------- + +def test_prefilter(): + """Test user input conversions""" + + # pairs of (raw, expected correct) input + pairs = [ ('2+2','2+2'), + ] + + for raw, correct in pairs: + nt.assert_equal(ip.prefilter(raw), correct) + +def test_prefilter_shadowed(): + def dummy_magic(line): pass + + prev_automagic_state = ip.automagic + ip.automagic = True + ip.autocall = 0 + + try: + # These should not be transformed - they are shadowed by other names + for name in ['if', 'zip', 'get_ipython']: # keyword, builtin, global + ip.register_magic_function(dummy_magic, magic_name=name) + res = ip.prefilter(name+' foo') + nt.assert_equal(res, name+' foo') + del ip.magics_manager.magics['line'][name] + + # These should be transformed + for name in ['fi', 'piz', 'nohtypi_teg']: + ip.register_magic_function(dummy_magic, magic_name=name) + res = ip.prefilter(name+' foo') + nt.assert_not_equal(res, name+' foo') + del ip.magics_manager.magics['line'][name] + + finally: + ip.automagic = prev_automagic_state + +def test_autocall_binops(): + """See https://github.com/ipython/ipython/issues/81""" + ip.magic('autocall 2') + f = lambda x: x + ip.user_ns['f'] = f + try: + nt.assert_equal(ip.prefilter('f 1'),'f(1)') + for t in ['f +1', 'f -1']: + nt.assert_equal(ip.prefilter(t), t) + + # Run tests again with a more permissive exclude_regexp, which will + # allow transformation of binary operations ('f -1' -> 'f(-1)'). + pm = ip.prefilter_manager + ac = AutocallChecker(shell=pm.shell, prefilter_manager=pm, + config=pm.config) + try: + ac.priority = 1 + ac.exclude_regexp = r'^[,&^\|\*/]|^is |^not |^in |^and |^or ' + pm.sort_checkers() + + nt.assert_equal(ip.prefilter('f -1'), 'f(-1)') + nt.assert_equal(ip.prefilter('f +1'), 'f(+1)') + finally: + pm.unregister_checker(ac) + finally: + ip.magic('autocall 0') + del ip.user_ns['f'] + + +def test_issue_114(): + """Check that multiline string literals don't expand as magic + see http://github.com/ipython/ipython/issues/114""" + + template = '"""\n%s\n"""' + # Store the current value of multi_line_specials and turn it off before + # running test, since it could be true (case in which the test doesn't make + # sense, as multiline string literals *will* expand as magic in that case). + msp = ip.prefilter_manager.multi_line_specials + ip.prefilter_manager.multi_line_specials = False + try: + for mgk in ip.magics_manager.lsmagic()['line']: + raw = template % mgk + nt.assert_equal(ip.prefilter(raw), raw) + finally: + ip.prefilter_manager.multi_line_specials = msp + + +def test_prefilter_attribute_errors(): + """Capture exceptions thrown by user objects on attribute access. + + See http://github.com/ipython/ipython/issues/988.""" + + class X(object): + def __getattr__(self, k): + raise ValueError('broken object') + def __call__(self, x): + return x + + # Create a callable broken object + ip.user_ns['x'] = X() + ip.magic('autocall 2') + try: + # Even if x throws an attribute error when looking at its rewrite + # attribute, we should not crash. So the test here is simply making + # the prefilter call and not having an exception. + ip.prefilter('x 1') + finally: + del ip.user_ns['x'] + ip.magic('autocall 0') + + +def test_autocall_should_support_unicode(): + ip.magic('autocall 2') + ip.user_ns['π'] = lambda x: x + try: + nt.assert_equal(ip.prefilter('π 3'),'π(3)') + finally: + ip.magic('autocall 0') + del ip.user_ns['π'] diff --git a/.venv/lib/python3.8/site-packages/IPython/core/tests/test_profile.py b/.venv/lib/python3.8/site-packages/IPython/core/tests/test_profile.py new file mode 100644 index 00000000..e63fb3ef --- /dev/null +++ b/.venv/lib/python3.8/site-packages/IPython/core/tests/test_profile.py @@ -0,0 +1,161 @@ +# coding: utf-8 +"""Tests for profile-related functions. + +Currently only the startup-dir functionality is tested, but more tests should +be added for: + + * ipython profile create + * ipython profile list + * ipython profile create --parallel + * security dir permissions + +Authors +------- + +* MinRK + +""" + +#----------------------------------------------------------------------------- +# Imports +#----------------------------------------------------------------------------- + +import os +import shutil +import sys +import tempfile + +from unittest import TestCase + +import nose.tools as nt + +from IPython.core.profileapp import list_profiles_in, list_bundled_profiles +from IPython.core.profiledir import ProfileDir + +from IPython.testing import decorators as dec +from IPython.testing import tools as tt +from IPython.utils.process import getoutput +from IPython.utils.tempdir import TemporaryDirectory + +#----------------------------------------------------------------------------- +# Globals +#----------------------------------------------------------------------------- +TMP_TEST_DIR = tempfile.mkdtemp() +HOME_TEST_DIR = os.path.join(TMP_TEST_DIR, "home_test_dir") +IP_TEST_DIR = os.path.join(HOME_TEST_DIR,'.ipython') + +# +# Setup/teardown functions/decorators +# + +def setup_module(): + """Setup test environment for the module: + + - Adds dummy home dir tree + """ + # Do not mask exceptions here. In particular, catching WindowsError is a + # problem because that exception is only defined on Windows... + os.makedirs(IP_TEST_DIR) + + +def teardown_module(): + """Teardown test environment for the module: + + - Remove dummy home dir tree + """ + # Note: we remove the parent test dir, which is the root of all test + # subdirs we may have created. Use shutil instead of os.removedirs, so + # that non-empty directories are all recursively removed. + shutil.rmtree(TMP_TEST_DIR) + + +#----------------------------------------------------------------------------- +# Test functions +#----------------------------------------------------------------------------- +def win32_without_pywin32(): + if sys.platform == 'win32': + try: + import pywin32 + except ImportError: + return True + return False + + +class ProfileStartupTest(TestCase): + def setUp(self): + # create profile dir + self.pd = ProfileDir.create_profile_dir_by_name(IP_TEST_DIR, 'test') + self.options = ['--ipython-dir', IP_TEST_DIR, '--profile', 'test'] + self.fname = os.path.join(TMP_TEST_DIR, 'test.py') + + def tearDown(self): + # We must remove this profile right away so its presence doesn't + # confuse other tests. + shutil.rmtree(self.pd.location) + + def init(self, startup_file, startup, test): + # write startup python file + with open(os.path.join(self.pd.startup_dir, startup_file), 'w') as f: + f.write(startup) + # write simple test file, to check that the startup file was run + with open(self.fname, 'w') as f: + f.write(test) + + def validate(self, output): + tt.ipexec_validate(self.fname, output, '', options=self.options) + + @dec.skipif(win32_without_pywin32(), "Test requires pywin32 on Windows") + def test_startup_py(self): + self.init('00-start.py', 'zzz=123\n', 'print(zzz)\n') + self.validate('123') + + @dec.skipif(win32_without_pywin32(), "Test requires pywin32 on Windows") + def test_startup_ipy(self): + self.init('00-start.ipy', '%xmode plain\n', '') + self.validate('Exception reporting mode: Plain') + + +def test_list_profiles_in(): + # No need to remove these directories and files, as they will get nuked in + # the module-level teardown. + td = tempfile.mkdtemp(dir=TMP_TEST_DIR) + for name in ('profile_foo', 'profile_hello', 'not_a_profile'): + os.mkdir(os.path.join(td, name)) + if dec.unicode_paths: + os.mkdir(os.path.join(td, u'profile_ünicode')) + + with open(os.path.join(td, 'profile_file'), 'w') as f: + f.write("I am not a profile directory") + profiles = list_profiles_in(td) + + # unicode normalization can turn u'ünicode' into u'u\0308nicode', + # so only check for *nicode, and that creating a ProfileDir from the + # name remains valid + found_unicode = False + for p in list(profiles): + if p.endswith('nicode'): + pd = ProfileDir.find_profile_dir_by_name(td, p) + profiles.remove(p) + found_unicode = True + break + if dec.unicode_paths: + nt.assert_true(found_unicode) + nt.assert_equal(set(profiles), {'foo', 'hello'}) + + +def test_list_bundled_profiles(): + # This variable will need to be updated when a new profile gets bundled + bundled = sorted(list_bundled_profiles()) + nt.assert_equal(bundled, []) + + +def test_profile_create_ipython_dir(): + """ipython profile create respects --ipython-dir""" + with TemporaryDirectory() as td: + getoutput([sys.executable, '-m', 'IPython', 'profile', 'create', + 'foo', '--ipython-dir=%s' % td]) + profile_dir = os.path.join(td, 'profile_foo') + assert os.path.exists(profile_dir) + ipython_config = os.path.join(profile_dir, 'ipython_config.py') + assert os.path.exists(ipython_config) + diff --git a/.venv/lib/python3.8/site-packages/IPython/core/tests/test_prompts.py b/.venv/lib/python3.8/site-packages/IPython/core/tests/test_prompts.py new file mode 100644 index 00000000..95e6163b --- /dev/null +++ b/.venv/lib/python3.8/site-packages/IPython/core/tests/test_prompts.py @@ -0,0 +1,30 @@ +# -*- coding: utf-8 +"""Tests for prompt generation.""" + +import unittest + +from IPython.core.prompts import LazyEvaluate + +class PromptTests(unittest.TestCase): + def test_lazy_eval_unicode(self): + u = u'ünicødé' + lz = LazyEvaluate(lambda : u) + self.assertEqual(str(lz), u) + self.assertEqual(format(lz), u) + + def test_lazy_eval_nonascii_bytes(self): + u = u'ünicødé' + b = u.encode('utf8') + lz = LazyEvaluate(lambda : b) + # unicode(lz) would fail + self.assertEqual(str(lz), str(b)) + self.assertEqual(format(lz), str(b)) + + def test_lazy_eval_float(self): + f = 0.503 + lz = LazyEvaluate(lambda : f) + + self.assertEqual(str(lz), str(f)) + self.assertEqual(format(lz), str(f)) + self.assertEqual(format(lz, '.1'), '0.5') + diff --git a/.venv/lib/python3.8/site-packages/IPython/core/tests/test_pylabtools.py b/.venv/lib/python3.8/site-packages/IPython/core/tests/test_pylabtools.py new file mode 100644 index 00000000..7b64aab1 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/IPython/core/tests/test_pylabtools.py @@ -0,0 +1,256 @@ +"""Tests for pylab tools module. +""" + +# Copyright (c) IPython Development Team. +# Distributed under the terms of the Modified BSD License. + + +from io import UnsupportedOperation, BytesIO + +import matplotlib +matplotlib.use('Agg') +from matplotlib.figure import Figure + +from nose import SkipTest +import nose.tools as nt + +from matplotlib import pyplot as plt +import numpy as np + +from IPython.core.getipython import get_ipython +from IPython.core.interactiveshell import InteractiveShell +from IPython.core.display import _PNG, _JPEG +from .. import pylabtools as pt + +from IPython.testing import decorators as dec + + +def test_figure_to_svg(): + # simple empty-figure test + fig = plt.figure() + nt.assert_equal(pt.print_figure(fig, 'svg'), None) + + plt.close('all') + + # simple check for at least svg-looking output + fig = plt.figure() + ax = fig.add_subplot(1,1,1) + ax.plot([1,2,3]) + plt.draw() + svg = pt.print_figure(fig, 'svg')[:100].lower() + nt.assert_in(u'doctype svg', svg) + +def _check_pil_jpeg_bytes(): + """Skip if PIL can't write JPEGs to BytesIO objects""" + # PIL's JPEG plugin can't write to BytesIO objects + # Pillow fixes this + from PIL import Image + buf = BytesIO() + img = Image.new("RGB", (4,4)) + try: + img.save(buf, 'jpeg') + except Exception as e: + ename = e.__class__.__name__ + raise SkipTest("PIL can't write JPEG to BytesIO: %s: %s" % (ename, e)) + +@dec.skip_without("PIL.Image") +def test_figure_to_jpeg(): + _check_pil_jpeg_bytes() + # simple check for at least jpeg-looking output + fig = plt.figure() + ax = fig.add_subplot(1,1,1) + ax.plot([1,2,3]) + plt.draw() + jpeg = pt.print_figure(fig, 'jpeg', pil_kwargs={'optimize': 50})[:100].lower() + assert jpeg.startswith(_JPEG) + +def test_retina_figure(): + # simple empty-figure test + fig = plt.figure() + nt.assert_equal(pt.retina_figure(fig), None) + plt.close('all') + + fig = plt.figure() + ax = fig.add_subplot(1,1,1) + ax.plot([1,2,3]) + plt.draw() + png, md = pt.retina_figure(fig) + assert png.startswith(_PNG) + nt.assert_in('width', md) + nt.assert_in('height', md) + +_fmt_mime_map = { + 'png': 'image/png', + 'jpeg': 'image/jpeg', + 'pdf': 'application/pdf', + 'retina': 'image/png', + 'svg': 'image/svg+xml', +} + +def test_select_figure_formats_str(): + ip = get_ipython() + for fmt, active_mime in _fmt_mime_map.items(): + pt.select_figure_formats(ip, fmt) + for mime, f in ip.display_formatter.formatters.items(): + if mime == active_mime: + nt.assert_in(Figure, f) + else: + nt.assert_not_in(Figure, f) + +def test_select_figure_formats_kwargs(): + ip = get_ipython() + kwargs = dict(quality=10, bbox_inches='tight') + pt.select_figure_formats(ip, 'png', **kwargs) + formatter = ip.display_formatter.formatters['image/png'] + f = formatter.lookup_by_type(Figure) + cell = f.__closure__[0].cell_contents + nt.assert_equal(cell, kwargs) + + # check that the formatter doesn't raise + fig = plt.figure() + ax = fig.add_subplot(1,1,1) + ax.plot([1,2,3]) + plt.draw() + formatter.enabled = True + png = formatter(fig) + assert png.startswith(_PNG) + +def test_select_figure_formats_set(): + ip = get_ipython() + for fmts in [ + {'png', 'svg'}, + ['png'], + ('jpeg', 'pdf', 'retina'), + {'svg'}, + ]: + active_mimes = {_fmt_mime_map[fmt] for fmt in fmts} + pt.select_figure_formats(ip, fmts) + for mime, f in ip.display_formatter.formatters.items(): + if mime in active_mimes: + nt.assert_in(Figure, f) + else: + nt.assert_not_in(Figure, f) + +def test_select_figure_formats_bad(): + ip = get_ipython() + with nt.assert_raises(ValueError): + pt.select_figure_formats(ip, 'foo') + with nt.assert_raises(ValueError): + pt.select_figure_formats(ip, {'png', 'foo'}) + with nt.assert_raises(ValueError): + pt.select_figure_formats(ip, ['retina', 'pdf', 'bar', 'bad']) + +def test_import_pylab(): + ns = {} + pt.import_pylab(ns, import_all=False) + nt.assert_true('plt' in ns) + nt.assert_equal(ns['np'], np) + +class TestPylabSwitch(object): + class Shell(InteractiveShell): + def enable_gui(self, gui): + pass + + def setup(self): + import matplotlib + def act_mpl(backend): + matplotlib.rcParams['backend'] = backend + + # Save rcParams since they get modified + self._saved_rcParams = matplotlib.rcParams + self._saved_rcParamsOrig = matplotlib.rcParamsOrig + matplotlib.rcParams = dict(backend='Qt4Agg') + matplotlib.rcParamsOrig = dict(backend='Qt4Agg') + + # Mock out functions + self._save_am = pt.activate_matplotlib + pt.activate_matplotlib = act_mpl + self._save_ip = pt.import_pylab + pt.import_pylab = lambda *a,**kw:None + self._save_cis = pt.configure_inline_support + pt.configure_inline_support = lambda *a,**kw:None + + def teardown(self): + pt.activate_matplotlib = self._save_am + pt.import_pylab = self._save_ip + pt.configure_inline_support = self._save_cis + import matplotlib + matplotlib.rcParams = self._saved_rcParams + matplotlib.rcParamsOrig = self._saved_rcParamsOrig + + def test_qt(self): + s = self.Shell() + gui, backend = s.enable_matplotlib(None) + nt.assert_equal(gui, 'qt') + nt.assert_equal(s.pylab_gui_select, 'qt') + + gui, backend = s.enable_matplotlib('inline') + nt.assert_equal(gui, 'inline') + nt.assert_equal(s.pylab_gui_select, 'qt') + + gui, backend = s.enable_matplotlib('qt') + nt.assert_equal(gui, 'qt') + nt.assert_equal(s.pylab_gui_select, 'qt') + + gui, backend = s.enable_matplotlib('inline') + nt.assert_equal(gui, 'inline') + nt.assert_equal(s.pylab_gui_select, 'qt') + + gui, backend = s.enable_matplotlib() + nt.assert_equal(gui, 'qt') + nt.assert_equal(s.pylab_gui_select, 'qt') + + def test_inline(self): + s = self.Shell() + gui, backend = s.enable_matplotlib('inline') + nt.assert_equal(gui, 'inline') + nt.assert_equal(s.pylab_gui_select, None) + + gui, backend = s.enable_matplotlib('inline') + nt.assert_equal(gui, 'inline') + nt.assert_equal(s.pylab_gui_select, None) + + gui, backend = s.enable_matplotlib('qt') + nt.assert_equal(gui, 'qt') + nt.assert_equal(s.pylab_gui_select, 'qt') + + def test_inline_twice(self): + "Using '%matplotlib inline' twice should not reset formatters" + + ip = self.Shell() + gui, backend = ip.enable_matplotlib('inline') + nt.assert_equal(gui, 'inline') + + fmts = {'png'} + active_mimes = {_fmt_mime_map[fmt] for fmt in fmts} + pt.select_figure_formats(ip, fmts) + + gui, backend = ip.enable_matplotlib('inline') + nt.assert_equal(gui, 'inline') + + for mime, f in ip.display_formatter.formatters.items(): + if mime in active_mimes: + nt.assert_in(Figure, f) + else: + nt.assert_not_in(Figure, f) + + def test_qt_gtk(self): + s = self.Shell() + gui, backend = s.enable_matplotlib('qt') + nt.assert_equal(gui, 'qt') + nt.assert_equal(s.pylab_gui_select, 'qt') + + gui, backend = s.enable_matplotlib('gtk') + nt.assert_equal(gui, 'qt') + nt.assert_equal(s.pylab_gui_select, 'qt') + + +def test_no_gui_backends(): + for k in ['agg', 'svg', 'pdf', 'ps']: + assert k not in pt.backend2gui + + +def test_figure_no_canvas(): + fig = Figure() + fig.canvas = None + pt.print_figure(fig) diff --git a/.venv/lib/python3.8/site-packages/IPython/core/tests/test_run.py b/.venv/lib/python3.8/site-packages/IPython/core/tests/test_run.py new file mode 100644 index 00000000..eff832b3 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/IPython/core/tests/test_run.py @@ -0,0 +1,607 @@ +# encoding: utf-8 +"""Tests for code execution (%run and related), which is particularly tricky. + +Because of how %run manages namespaces, and the fact that we are trying here to +verify subtle object deletion and reference counting issues, the %run tests +will be kept in this separate file. This makes it easier to aggregate in one +place the tricks needed to handle it; most other magics are much easier to test +and we do so in a common test_magic file. + +Note that any test using `run -i` should make sure to do a `reset` afterwards, +as otherwise it may influence later tests. +""" + +# Copyright (c) IPython Development Team. +# Distributed under the terms of the Modified BSD License. + + + +import functools +import os +from os.path import join as pjoin +import random +import string +import sys +import textwrap +import unittest +from unittest.mock import patch + +import nose.tools as nt +from nose import SkipTest + +from IPython.testing import decorators as dec +from IPython.testing import tools as tt +from IPython.utils.io import capture_output +from IPython.utils.tempdir import TemporaryDirectory +from IPython.core import debugger + +def doctest_refbug(): + """Very nasty problem with references held by multiple runs of a script. + See: https://github.com/ipython/ipython/issues/141 + + In [1]: _ip.clear_main_mod_cache() + # random + + In [2]: %run refbug + + In [3]: call_f() + lowercased: hello + + In [4]: %run refbug + + In [5]: call_f() + lowercased: hello + lowercased: hello + """ + + +def doctest_run_builtins(): + r"""Check that %run doesn't damage __builtins__. + + In [1]: import tempfile + + In [2]: bid1 = id(__builtins__) + + In [3]: fname = tempfile.mkstemp('.py')[1] + + In [3]: f = open(fname,'w') + + In [4]: dummy= f.write('pass\n') + + In [5]: f.flush() + + In [6]: t1 = type(__builtins__) + + In [7]: %run $fname + + In [7]: f.close() + + In [8]: bid2 = id(__builtins__) + + In [9]: t2 = type(__builtins__) + + In [10]: t1 == t2 + Out[10]: True + + In [10]: bid1 == bid2 + Out[10]: True + + In [12]: try: + ....: os.unlink(fname) + ....: except: + ....: pass + ....: + """ + + +def doctest_run_option_parser(): + r"""Test option parser in %run. + + In [1]: %run print_argv.py + [] + + In [2]: %run print_argv.py print*.py + ['print_argv.py'] + + In [3]: %run -G print_argv.py print*.py + ['print*.py'] + + """ + + +@dec.skip_win32 +def doctest_run_option_parser_for_posix(): + r"""Test option parser in %run (Linux/OSX specific). + + You need double quote to escape glob in POSIX systems: + + In [1]: %run print_argv.py print\\*.py + ['print*.py'] + + You can't use quote to escape glob in POSIX systems: + + In [2]: %run print_argv.py 'print*.py' + ['print_argv.py'] + + """ + + +@dec.skip_if_not_win32 +def doctest_run_option_parser_for_windows(): + r"""Test option parser in %run (Windows specific). + + In Windows, you can't escape ``*` `by backslash: + + In [1]: %run print_argv.py print\\*.py + ['print\\*.py'] + + You can use quote to escape glob: + + In [2]: %run print_argv.py 'print*.py' + ['print*.py'] + + """ + + +def doctest_reset_del(): + """Test that resetting doesn't cause errors in __del__ methods. + + In [2]: class A(object): + ...: def __del__(self): + ...: print(str("Hi")) + ...: + + In [3]: a = A() + + In [4]: get_ipython().reset() + Hi + + In [5]: 1+1 + Out[5]: 2 + """ + +# For some tests, it will be handy to organize them in a class with a common +# setup that makes a temp file + +class TestMagicRunPass(tt.TempFileMixin): + + def setUp(self): + content = "a = [1,2,3]\nb = 1" + self.mktmp(content) + + def run_tmpfile(self): + _ip = get_ipython() + # This fails on Windows if self.tmpfile.name has spaces or "~" in it. + # See below and ticket https://bugs.launchpad.net/bugs/366353 + _ip.magic('run %s' % self.fname) + + def run_tmpfile_p(self): + _ip = get_ipython() + # This fails on Windows if self.tmpfile.name has spaces or "~" in it. + # See below and ticket https://bugs.launchpad.net/bugs/366353 + _ip.magic('run -p %s' % self.fname) + + def test_builtins_id(self): + """Check that %run doesn't damage __builtins__ """ + _ip = get_ipython() + # Test that the id of __builtins__ is not modified by %run + bid1 = id(_ip.user_ns['__builtins__']) + self.run_tmpfile() + bid2 = id(_ip.user_ns['__builtins__']) + nt.assert_equal(bid1, bid2) + + def test_builtins_type(self): + """Check that the type of __builtins__ doesn't change with %run. + + However, the above could pass if __builtins__ was already modified to + be a dict (it should be a module) by a previous use of %run. So we + also check explicitly that it really is a module: + """ + _ip = get_ipython() + self.run_tmpfile() + nt.assert_equal(type(_ip.user_ns['__builtins__']),type(sys)) + + def test_run_profile( self ): + """Test that the option -p, which invokes the profiler, do not + crash by invoking execfile""" + self.run_tmpfile_p() + + def test_run_debug_twice(self): + # https://github.com/ipython/ipython/issues/10028 + _ip = get_ipython() + with tt.fake_input(['c']): + _ip.magic('run -d %s' % self.fname) + with tt.fake_input(['c']): + _ip.magic('run -d %s' % self.fname) + + def test_run_debug_twice_with_breakpoint(self): + """Make a valid python temp file.""" + _ip = get_ipython() + with tt.fake_input(['b 2', 'c', 'c']): + _ip.magic('run -d %s' % self.fname) + + with tt.fake_input(['c']): + with tt.AssertNotPrints('KeyError'): + _ip.magic('run -d %s' % self.fname) + + +class TestMagicRunSimple(tt.TempFileMixin): + + def test_simpledef(self): + """Test that simple class definitions work.""" + src = ("class foo: pass\n" + "def f(): return foo()") + self.mktmp(src) + _ip.magic('run %s' % self.fname) + _ip.run_cell('t = isinstance(f(), foo)') + nt.assert_true(_ip.user_ns['t']) + + def test_obj_del(self): + """Test that object's __del__ methods are called on exit.""" + if sys.platform == 'win32': + try: + import win32api + except ImportError: + raise SkipTest("Test requires pywin32") + src = ("class A(object):\n" + " def __del__(self):\n" + " print('object A deleted')\n" + "a = A()\n") + self.mktmp(src) + if dec.module_not_available('sqlite3'): + err = 'WARNING: IPython History requires SQLite, your history will not be saved\n' + else: + err = None + tt.ipexec_validate(self.fname, 'object A deleted', err) + + def test_aggressive_namespace_cleanup(self): + """Test that namespace cleanup is not too aggressive GH-238 + + Returning from another run magic deletes the namespace""" + # see ticket https://github.com/ipython/ipython/issues/238 + + with tt.TempFileMixin() as empty: + empty.mktmp('') + # On Windows, the filename will have \users in it, so we need to use the + # repr so that the \u becomes \\u. + src = ("ip = get_ipython()\n" + "for i in range(5):\n" + " try:\n" + " ip.magic(%r)\n" + " except NameError as e:\n" + " print(i)\n" + " break\n" % ('run ' + empty.fname)) + self.mktmp(src) + _ip.magic('run %s' % self.fname) + _ip.run_cell('ip == get_ipython()') + nt.assert_equal(_ip.user_ns['i'], 4) + + def test_run_second(self): + """Test that running a second file doesn't clobber the first, gh-3547 + """ + self.mktmp("avar = 1\n" + "def afunc():\n" + " return avar\n") + + with tt.TempFileMixin() as empty: + empty.mktmp("") + + _ip.magic('run %s' % self.fname) + _ip.magic('run %s' % empty.fname) + nt.assert_equal(_ip.user_ns['afunc'](), 1) + + @dec.skip_win32 + def test_tclass(self): + mydir = os.path.dirname(__file__) + tc = os.path.join(mydir, 'tclass') + src = ("%%run '%s' C-first\n" + "%%run '%s' C-second\n" + "%%run '%s' C-third\n") % (tc, tc, tc) + self.mktmp(src, '.ipy') + out = """\ +ARGV 1-: ['C-first'] +ARGV 1-: ['C-second'] +tclass.py: deleting object: C-first +ARGV 1-: ['C-third'] +tclass.py: deleting object: C-second +tclass.py: deleting object: C-third +""" + if dec.module_not_available('sqlite3'): + err = 'WARNING: IPython History requires SQLite, your history will not be saved\n' + else: + err = None + tt.ipexec_validate(self.fname, out, err) + + def test_run_i_after_reset(self): + """Check that %run -i still works after %reset (gh-693)""" + src = "yy = zz\n" + self.mktmp(src) + _ip.run_cell("zz = 23") + try: + _ip.magic('run -i %s' % self.fname) + nt.assert_equal(_ip.user_ns['yy'], 23) + finally: + _ip.magic('reset -f') + + _ip.run_cell("zz = 23") + try: + _ip.magic('run -i %s' % self.fname) + nt.assert_equal(_ip.user_ns['yy'], 23) + finally: + _ip.magic('reset -f') + + def test_unicode(self): + """Check that files in odd encodings are accepted.""" + mydir = os.path.dirname(__file__) + na = os.path.join(mydir, 'nonascii.py') + _ip.magic('run "%s"' % na) + nt.assert_equal(_ip.user_ns['u'], u'Ўт№Ф') + + def test_run_py_file_attribute(self): + """Test handling of `__file__` attribute in `%run .py`.""" + src = "t = __file__\n" + self.mktmp(src) + _missing = object() + file1 = _ip.user_ns.get('__file__', _missing) + _ip.magic('run %s' % self.fname) + file2 = _ip.user_ns.get('__file__', _missing) + + # Check that __file__ was equal to the filename in the script's + # namespace. + nt.assert_equal(_ip.user_ns['t'], self.fname) + + # Check that __file__ was not leaked back into user_ns. + nt.assert_equal(file1, file2) + + def test_run_ipy_file_attribute(self): + """Test handling of `__file__` attribute in `%run `.""" + src = "t = __file__\n" + self.mktmp(src, ext='.ipy') + _missing = object() + file1 = _ip.user_ns.get('__file__', _missing) + _ip.magic('run %s' % self.fname) + file2 = _ip.user_ns.get('__file__', _missing) + + # Check that __file__ was equal to the filename in the script's + # namespace. + nt.assert_equal(_ip.user_ns['t'], self.fname) + + # Check that __file__ was not leaked back into user_ns. + nt.assert_equal(file1, file2) + + def test_run_formatting(self): + """ Test that %run -t -N does not raise a TypeError for N > 1.""" + src = "pass" + self.mktmp(src) + _ip.magic('run -t -N 1 %s' % self.fname) + _ip.magic('run -t -N 10 %s' % self.fname) + + def test_ignore_sys_exit(self): + """Test the -e option to ignore sys.exit()""" + src = "import sys; sys.exit(1)" + self.mktmp(src) + with tt.AssertPrints('SystemExit'): + _ip.magic('run %s' % self.fname) + + with tt.AssertNotPrints('SystemExit'): + _ip.magic('run -e %s' % self.fname) + + def test_run_nb(self): + """Test %run notebook.ipynb""" + from nbformat import v4, writes + nb = v4.new_notebook( + cells=[ + v4.new_markdown_cell("The Ultimate Question of Everything"), + v4.new_code_cell("answer=42") + ] + ) + src = writes(nb, version=4) + self.mktmp(src, ext='.ipynb') + + _ip.magic("run %s" % self.fname) + + nt.assert_equal(_ip.user_ns['answer'], 42) + + def test_run_nb_error(self): + """Test %run notebook.ipynb error""" + from nbformat import v4, writes + # %run when a file name isn't provided + nt.assert_raises(Exception, _ip.magic, "run") + + # %run when a file doesn't exist + nt.assert_raises(Exception, _ip.magic, "run foobar.ipynb") + + # %run on a notebook with an error + nb = v4.new_notebook( + cells=[ + v4.new_code_cell("0/0") + ] + ) + src = writes(nb, version=4) + self.mktmp(src, ext='.ipynb') + nt.assert_raises(Exception, _ip.magic, "run %s" % self.fname) + + def test_file_options(self): + src = ('import sys\n' + 'a = " ".join(sys.argv[1:])\n') + self.mktmp(src) + test_opts = '-x 3 --verbose' + _ip.run_line_magic("run", '{0} {1}'.format(self.fname, test_opts)) + nt.assert_equal(_ip.user_ns['a'], test_opts) + + +class TestMagicRunWithPackage(unittest.TestCase): + + def writefile(self, name, content): + path = os.path.join(self.tempdir.name, name) + d = os.path.dirname(path) + if not os.path.isdir(d): + os.makedirs(d) + with open(path, 'w') as f: + f.write(textwrap.dedent(content)) + + def setUp(self): + self.package = package = 'tmp{0}'.format(''.join([random.choice(string.ascii_letters) for i in range(10)])) + """Temporary (probably) valid python package name.""" + + self.value = int(random.random() * 10000) + + self.tempdir = TemporaryDirectory() + self.__orig_cwd = os.getcwd() + sys.path.insert(0, self.tempdir.name) + + self.writefile(os.path.join(package, '__init__.py'), '') + self.writefile(os.path.join(package, 'sub.py'), """ + x = {0!r} + """.format(self.value)) + self.writefile(os.path.join(package, 'relative.py'), """ + from .sub import x + """) + self.writefile(os.path.join(package, 'absolute.py'), """ + from {0}.sub import x + """.format(package)) + self.writefile(os.path.join(package, 'args.py'), """ + import sys + a = " ".join(sys.argv[1:]) + """.format(package)) + + def tearDown(self): + os.chdir(self.__orig_cwd) + sys.path[:] = [p for p in sys.path if p != self.tempdir.name] + self.tempdir.cleanup() + + def check_run_submodule(self, submodule, opts=''): + _ip.user_ns.pop('x', None) + _ip.magic('run {2} -m {0}.{1}'.format(self.package, submodule, opts)) + self.assertEqual(_ip.user_ns['x'], self.value, + 'Variable `x` is not loaded from module `{0}`.' + .format(submodule)) + + def test_run_submodule_with_absolute_import(self): + self.check_run_submodule('absolute') + + def test_run_submodule_with_relative_import(self): + """Run submodule that has a relative import statement (#2727).""" + self.check_run_submodule('relative') + + def test_prun_submodule_with_absolute_import(self): + self.check_run_submodule('absolute', '-p') + + def test_prun_submodule_with_relative_import(self): + self.check_run_submodule('relative', '-p') + + def with_fake_debugger(func): + @functools.wraps(func) + def wrapper(*args, **kwds): + with patch.object(debugger.Pdb, 'run', staticmethod(eval)): + return func(*args, **kwds) + return wrapper + + @with_fake_debugger + def test_debug_run_submodule_with_absolute_import(self): + self.check_run_submodule('absolute', '-d') + + @with_fake_debugger + def test_debug_run_submodule_with_relative_import(self): + self.check_run_submodule('relative', '-d') + + def test_module_options(self): + _ip.user_ns.pop('a', None) + test_opts = '-x abc -m test' + _ip.run_line_magic('run', '-m {0}.args {1}'.format(self.package, test_opts)) + nt.assert_equal(_ip.user_ns['a'], test_opts) + + def test_module_options_with_separator(self): + _ip.user_ns.pop('a', None) + test_opts = '-x abc -m test' + _ip.run_line_magic('run', '-m {0}.args -- {1}'.format(self.package, test_opts)) + nt.assert_equal(_ip.user_ns['a'], test_opts) + +def test_run__name__(): + with TemporaryDirectory() as td: + path = pjoin(td, 'foo.py') + with open(path, 'w') as f: + f.write("q = __name__") + + _ip.user_ns.pop('q', None) + _ip.magic('run {}'.format(path)) + nt.assert_equal(_ip.user_ns.pop('q'), '__main__') + + _ip.magic('run -n {}'.format(path)) + nt.assert_equal(_ip.user_ns.pop('q'), 'foo') + + try: + _ip.magic('run -i -n {}'.format(path)) + nt.assert_equal(_ip.user_ns.pop('q'), 'foo') + finally: + _ip.magic('reset -f') + + +def test_run_tb(): + """Test traceback offset in %run""" + with TemporaryDirectory() as td: + path = pjoin(td, 'foo.py') + with open(path, 'w') as f: + f.write('\n'.join([ + "def foo():", + " return bar()", + "def bar():", + " raise RuntimeError('hello!')", + "foo()", + ])) + with capture_output() as io: + _ip.magic('run {}'.format(path)) + out = io.stdout + nt.assert_not_in("execfile", out) + nt.assert_in("RuntimeError", out) + nt.assert_equal(out.count("---->"), 3) + del ip.user_ns['bar'] + del ip.user_ns['foo'] + + +def test_multiprocessing_run(): + """Set we can run mutiprocesgin without messing up up main namespace + + Note that import `nose.tools as nt` mdify the value s + sys.module['__mp_main__'] so wee need to temporarily set it to None to test + the issue. + """ + with TemporaryDirectory() as td: + mpm = sys.modules.get('__mp_main__') + assert mpm is not None + sys.modules['__mp_main__'] = None + try: + path = pjoin(td, 'test.py') + with open(path, 'w') as f: + f.write("import multiprocessing\nprint('hoy')") + with capture_output() as io: + _ip.run_line_magic('run', path) + _ip.run_cell("i_m_undefined") + out = io.stdout + nt.assert_in("hoy", out) + nt.assert_not_in("AttributeError", out) + nt.assert_in("NameError", out) + nt.assert_equal(out.count("---->"), 1) + except: + raise + finally: + sys.modules['__mp_main__'] = mpm + +@dec.knownfailureif(sys.platform == 'win32', "writes to io.stdout aren't captured on Windows") +def test_script_tb(): + """Test traceback offset in `ipython script.py`""" + with TemporaryDirectory() as td: + path = pjoin(td, 'foo.py') + with open(path, 'w') as f: + f.write('\n'.join([ + "def foo():", + " return bar()", + "def bar():", + " raise RuntimeError('hello!')", + "foo()", + ])) + out, err = tt.ipexec(path) + nt.assert_not_in("execfile", out) + nt.assert_in("RuntimeError", out) + nt.assert_equal(out.count("---->"), 3) + diff --git a/.venv/lib/python3.8/site-packages/IPython/core/tests/test_shellapp.py b/.venv/lib/python3.8/site-packages/IPython/core/tests/test_shellapp.py new file mode 100644 index 00000000..6808114b --- /dev/null +++ b/.venv/lib/python3.8/site-packages/IPython/core/tests/test_shellapp.py @@ -0,0 +1,60 @@ +# -*- coding: utf-8 -*- +"""Tests for shellapp module. + +Authors +------- +* Bradley Froehle +""" +#----------------------------------------------------------------------------- +# Copyright (C) 2012 The IPython Development Team +# +# Distributed under the terms of the BSD License. The full license is in +# the file COPYING, distributed as part of this software. +#----------------------------------------------------------------------------- + +#----------------------------------------------------------------------------- +# Imports +#----------------------------------------------------------------------------- +import unittest + +from IPython.testing import decorators as dec +from IPython.testing import tools as tt + +sqlite_err_maybe = dec.module_not_available('sqlite3') +SQLITE_NOT_AVAILABLE_ERROR = ('WARNING: IPython History requires SQLite,' + ' your history will not be saved\n') + +class TestFileToRun(tt.TempFileMixin, unittest.TestCase): + """Test the behavior of the file_to_run parameter.""" + + def test_py_script_file_attribute(self): + """Test that `__file__` is set when running `ipython file.py`""" + src = "print(__file__)\n" + self.mktmp(src) + + err = SQLITE_NOT_AVAILABLE_ERROR if sqlite_err_maybe else None + tt.ipexec_validate(self.fname, self.fname, err) + + def test_ipy_script_file_attribute(self): + """Test that `__file__` is set when running `ipython file.ipy`""" + src = "print(__file__)\n" + self.mktmp(src, ext='.ipy') + + err = SQLITE_NOT_AVAILABLE_ERROR if sqlite_err_maybe else None + tt.ipexec_validate(self.fname, self.fname, err) + + # The commands option to ipexec_validate doesn't work on Windows, and it + # doesn't seem worth fixing + @dec.skip_win32 + def test_py_script_file_attribute_interactively(self): + """Test that `__file__` is not set after `ipython -i file.py`""" + src = "True\n" + self.mktmp(src) + + out, err = tt.ipexec(self.fname, options=['-i'], + commands=['"__file__" in globals()', 'print(123)', 'exit()']) + if 'False' not in out: + print("Subprocess stderr:") + print(err) + print('-----') + raise AssertionError("'False' not found in %r" % out) diff --git a/.venv/lib/python3.8/site-packages/IPython/core/tests/test_splitinput.py b/.venv/lib/python3.8/site-packages/IPython/core/tests/test_splitinput.py new file mode 100644 index 00000000..98b4189e --- /dev/null +++ b/.venv/lib/python3.8/site-packages/IPython/core/tests/test_splitinput.py @@ -0,0 +1,38 @@ +# coding: utf-8 +import nose.tools as nt + +from IPython.core.splitinput import split_user_input, LineInfo +from IPython.testing import tools as tt + +tests = [ + ('x=1', ('', '', 'x', '=1')), + ('?', ('', '?', '', '')), + ('??', ('', '??', '', '')), + (' ?', (' ', '?', '', '')), + (' ??', (' ', '??', '', '')), + ('??x', ('', '??', 'x', '')), + ('?x=1', ('', '?', 'x', '=1')), + ('!ls', ('', '!', 'ls', '')), + (' !ls', (' ', '!', 'ls', '')), + ('!!ls', ('', '!!', 'ls', '')), + (' !!ls', (' ', '!!', 'ls', '')), + (',ls', ('', ',', 'ls', '')), + (';ls', ('', ';', 'ls', '')), + (' ;ls', (' ', ';', 'ls', '')), + ('f.g(x)', ('', '', 'f.g', '(x)')), + ('f.g (x)', ('', '', 'f.g', '(x)')), + ('?%hist1', ('', '?', '%hist1', '')), + ('?%%hist2', ('', '?', '%%hist2', '')), + ('??%hist3', ('', '??', '%hist3', '')), + ('??%%hist4', ('', '??', '%%hist4', '')), + ('?x*', ('', '?', 'x*', '')), + ] +tests.append((u"Pérez Fernando", (u'', u'', u'Pérez', u'Fernando'))) + +def test_split_user_input(): + return tt.check_pairs(split_user_input, tests) + +def test_LineInfo(): + """Simple test for LineInfo construction and str()""" + linfo = LineInfo(' %cd /home') + nt.assert_equal(str(linfo), 'LineInfo [ |%|cd|/home]') diff --git a/.venv/lib/python3.8/site-packages/IPython/core/tests/test_ultratb.py b/.venv/lib/python3.8/site-packages/IPython/core/tests/test_ultratb.py new file mode 100644 index 00000000..3751117b --- /dev/null +++ b/.venv/lib/python3.8/site-packages/IPython/core/tests/test_ultratb.py @@ -0,0 +1,470 @@ +# encoding: utf-8 +"""Tests for IPython.core.ultratb +""" +import io +import logging +import sys +import os.path +from textwrap import dedent +import traceback +import unittest +from unittest import mock + +import IPython.core.ultratb as ultratb +from IPython.core.ultratb import ColorTB, VerboseTB, find_recursion + + +from IPython.testing import tools as tt +from IPython.testing.decorators import onlyif_unicode_paths +from IPython.utils.syspathcontext import prepended_to_syspath +from IPython.utils.tempdir import TemporaryDirectory + +file_1 = """1 +2 +3 +def f(): + 1/0 +""" + +file_2 = """def f(): + 1/0 +""" + + +def recursionlimit(frames): + """ + decorator to set the recursion limit temporarily + """ + + def inner(test_function): + def wrapper(*args, **kwargs): + _orig_rec_limit = ultratb._FRAME_RECURSION_LIMIT + ultratb._FRAME_RECURSION_LIMIT = 50 + + rl = sys.getrecursionlimit() + sys.setrecursionlimit(frames) + try: + return test_function(*args, **kwargs) + finally: + sys.setrecursionlimit(rl) + ultratb._FRAME_RECURSION_LIMIT = _orig_rec_limit + + return wrapper + + return inner + + +class ChangedPyFileTest(unittest.TestCase): + def test_changing_py_file(self): + """Traceback produced if the line where the error occurred is missing? + + https://github.com/ipython/ipython/issues/1456 + """ + with TemporaryDirectory() as td: + fname = os.path.join(td, "foo.py") + with open(fname, "w") as f: + f.write(file_1) + + with prepended_to_syspath(td): + ip.run_cell("import foo") + + with tt.AssertPrints("ZeroDivisionError"): + ip.run_cell("foo.f()") + + # Make the file shorter, so the line of the error is missing. + with open(fname, "w") as f: + f.write(file_2) + + # For some reason, this was failing on the *second* call after + # changing the file, so we call f() twice. + with tt.AssertNotPrints("Internal Python error", channel='stderr'): + with tt.AssertPrints("ZeroDivisionError"): + ip.run_cell("foo.f()") + with tt.AssertPrints("ZeroDivisionError"): + ip.run_cell("foo.f()") + +iso_8859_5_file = u'''# coding: iso-8859-5 + +def fail(): + """дбИЖ""" + 1/0 # дбИЖ +''' + +class NonAsciiTest(unittest.TestCase): + @onlyif_unicode_paths + def test_nonascii_path(self): + # Non-ascii directory name as well. + with TemporaryDirectory(suffix=u'é') as td: + fname = os.path.join(td, u"fooé.py") + with open(fname, "w") as f: + f.write(file_1) + + with prepended_to_syspath(td): + ip.run_cell("import foo") + + with tt.AssertPrints("ZeroDivisionError"): + ip.run_cell("foo.f()") + + def test_iso8859_5(self): + with TemporaryDirectory() as td: + fname = os.path.join(td, 'dfghjkl.py') + + with io.open(fname, 'w', encoding='iso-8859-5') as f: + f.write(iso_8859_5_file) + + with prepended_to_syspath(td): + ip.run_cell("from dfghjkl import fail") + + with tt.AssertPrints("ZeroDivisionError"): + with tt.AssertPrints(u'дбИЖ', suppress=False): + ip.run_cell('fail()') + + def test_nonascii_msg(self): + cell = u"raise Exception('é')" + expected = u"Exception('é')" + ip.run_cell("%xmode plain") + with tt.AssertPrints(expected): + ip.run_cell(cell) + + ip.run_cell("%xmode verbose") + with tt.AssertPrints(expected): + ip.run_cell(cell) + + ip.run_cell("%xmode context") + with tt.AssertPrints(expected): + ip.run_cell(cell) + + ip.run_cell("%xmode minimal") + with tt.AssertPrints(u"Exception: é"): + ip.run_cell(cell) + + # Put this back into Context mode for later tests. + ip.run_cell("%xmode context") + +class NestedGenExprTestCase(unittest.TestCase): + """ + Regression test for the following issues: + https://github.com/ipython/ipython/issues/8293 + https://github.com/ipython/ipython/issues/8205 + """ + def test_nested_genexpr(self): + code = dedent( + """\ + class SpecificException(Exception): + pass + + def foo(x): + raise SpecificException("Success!") + + sum(sum(foo(x) for _ in [0]) for x in [0]) + """ + ) + with tt.AssertPrints('SpecificException: Success!', suppress=False): + ip.run_cell(code) + + +indentationerror_file = """if True: +zoon() +""" + +class IndentationErrorTest(unittest.TestCase): + def test_indentationerror_shows_line(self): + # See issue gh-2398 + with tt.AssertPrints("IndentationError"): + with tt.AssertPrints("zoon()", suppress=False): + ip.run_cell(indentationerror_file) + + with TemporaryDirectory() as td: + fname = os.path.join(td, "foo.py") + with open(fname, "w") as f: + f.write(indentationerror_file) + + with tt.AssertPrints("IndentationError"): + with tt.AssertPrints("zoon()", suppress=False): + ip.magic('run %s' % fname) + +se_file_1 = """1 +2 +7/ +""" + +se_file_2 = """7/ +""" + +class SyntaxErrorTest(unittest.TestCase): + def test_syntaxerror_without_lineno(self): + with tt.AssertNotPrints("TypeError"): + with tt.AssertPrints("line unknown"): + ip.run_cell("raise SyntaxError()") + + def test_syntaxerror_no_stacktrace_at_compile_time(self): + syntax_error_at_compile_time = """ +def foo(): + .. +""" + with tt.AssertPrints("SyntaxError"): + ip.run_cell(syntax_error_at_compile_time) + + with tt.AssertNotPrints("foo()"): + ip.run_cell(syntax_error_at_compile_time) + + def test_syntaxerror_stacktrace_when_running_compiled_code(self): + syntax_error_at_runtime = """ +def foo(): + eval("..") + +def bar(): + foo() + +bar() +""" + with tt.AssertPrints("SyntaxError"): + ip.run_cell(syntax_error_at_runtime) + # Assert syntax error during runtime generate stacktrace + with tt.AssertPrints(["foo()", "bar()"]): + ip.run_cell(syntax_error_at_runtime) + del ip.user_ns['bar'] + del ip.user_ns['foo'] + + def test_changing_py_file(self): + with TemporaryDirectory() as td: + fname = os.path.join(td, "foo.py") + with open(fname, 'w') as f: + f.write(se_file_1) + + with tt.AssertPrints(["7/", "SyntaxError"]): + ip.magic("run " + fname) + + # Modify the file + with open(fname, 'w') as f: + f.write(se_file_2) + + # The SyntaxError should point to the correct line + with tt.AssertPrints(["7/", "SyntaxError"]): + ip.magic("run " + fname) + + def test_non_syntaxerror(self): + # SyntaxTB may be called with an error other than a SyntaxError + # See e.g. gh-4361 + try: + raise ValueError('QWERTY') + except ValueError: + with tt.AssertPrints('QWERTY'): + ip.showsyntaxerror() + +import sys +if sys.version_info < (3,9): + """ + New 3.9 Pgen Parser does not raise Memory error, except on failed malloc. + """ + class MemoryErrorTest(unittest.TestCase): + def test_memoryerror(self): + memoryerror_code = "(" * 200 + ")" * 200 + with tt.AssertPrints("MemoryError"): + ip.run_cell(memoryerror_code) + + +class Python3ChainedExceptionsTest(unittest.TestCase): + DIRECT_CAUSE_ERROR_CODE = """ +try: + x = 1 + 2 + print(not_defined_here) +except Exception as e: + x += 55 + x - 1 + y = {} + raise KeyError('uh') from e + """ + + EXCEPTION_DURING_HANDLING_CODE = """ +try: + x = 1 + 2 + print(not_defined_here) +except Exception as e: + x += 55 + x - 1 + y = {} + raise KeyError('uh') + """ + + SUPPRESS_CHAINING_CODE = """ +try: + 1/0 +except Exception: + raise ValueError("Yikes") from None + """ + + def test_direct_cause_error(self): + with tt.AssertPrints(["KeyError", "NameError", "direct cause"]): + ip.run_cell(self.DIRECT_CAUSE_ERROR_CODE) + + def test_exception_during_handling_error(self): + with tt.AssertPrints(["KeyError", "NameError", "During handling"]): + ip.run_cell(self.EXCEPTION_DURING_HANDLING_CODE) + + def test_suppress_exception_chaining(self): + with tt.AssertNotPrints("ZeroDivisionError"), \ + tt.AssertPrints("ValueError", suppress=False): + ip.run_cell(self.SUPPRESS_CHAINING_CODE) + + def test_plain_direct_cause_error(self): + with tt.AssertPrints(["KeyError", "NameError", "direct cause"]): + ip.run_cell("%xmode Plain") + ip.run_cell(self.DIRECT_CAUSE_ERROR_CODE) + ip.run_cell("%xmode Verbose") + + def test_plain_exception_during_handling_error(self): + with tt.AssertPrints(["KeyError", "NameError", "During handling"]): + ip.run_cell("%xmode Plain") + ip.run_cell(self.EXCEPTION_DURING_HANDLING_CODE) + ip.run_cell("%xmode Verbose") + + def test_plain_suppress_exception_chaining(self): + with tt.AssertNotPrints("ZeroDivisionError"), \ + tt.AssertPrints("ValueError", suppress=False): + ip.run_cell("%xmode Plain") + ip.run_cell(self.SUPPRESS_CHAINING_CODE) + ip.run_cell("%xmode Verbose") + + +class RecursionTest(unittest.TestCase): + DEFINITIONS = """ +def non_recurs(): + 1/0 + +def r1(): + r1() + +def r3a(): + r3b() + +def r3b(): + r3c() + +def r3c(): + r3a() + +def r3o1(): + r3a() + +def r3o2(): + r3o1() +""" + def setUp(self): + ip.run_cell(self.DEFINITIONS) + + def test_no_recursion(self): + with tt.AssertNotPrints("frames repeated"): + ip.run_cell("non_recurs()") + + @recursionlimit(150) + def test_recursion_one_frame(self): + with tt.AssertPrints("1 frames repeated"): + ip.run_cell("r1()") + + @recursionlimit(150) + def test_recursion_three_frames(self): + with tt.AssertPrints("3 frames repeated"): + ip.run_cell("r3o2()") + + @recursionlimit(150) + def test_find_recursion(self): + captured = [] + def capture_exc(*args, **kwargs): + captured.append(sys.exc_info()) + with mock.patch.object(ip, 'showtraceback', capture_exc): + ip.run_cell("r3o2()") + + self.assertEqual(len(captured), 1) + etype, evalue, tb = captured[0] + self.assertIn("recursion", str(evalue)) + + records = ip.InteractiveTB.get_records(tb, 3, ip.InteractiveTB.tb_offset) + for r in records[:10]: + print(r[1:4]) + + # The outermost frames should be: + # 0: the 'cell' that was running when the exception came up + # 1: r3o2() + # 2: r3o1() + # 3: r3a() + # Then repeating r3b, r3c, r3a + last_unique, repeat_length = find_recursion(etype, evalue, records) + self.assertEqual(last_unique, 2) + self.assertEqual(repeat_length, 3) + + +#---------------------------------------------------------------------------- + +# module testing (minimal) +def test_handlers(): + def spam(c, d_e): + (d, e) = d_e + x = c + d + y = c * d + foo(x, y) + + def foo(a, b, bar=1): + eggs(a, b + bar) + + def eggs(f, g, z=globals()): + h = f + g + i = f - g + return h / i + + buff = io.StringIO() + + buff.write('') + buff.write('*** Before ***') + try: + buff.write(spam(1, (2, 3))) + except: + traceback.print_exc(file=buff) + + handler = ColorTB(ostream=buff) + buff.write('*** ColorTB ***') + try: + buff.write(spam(1, (2, 3))) + except: + handler(*sys.exc_info()) + buff.write('') + + handler = VerboseTB(ostream=buff) + buff.write('*** VerboseTB ***') + try: + buff.write(spam(1, (2, 3))) + except: + handler(*sys.exc_info()) + buff.write('') + +from IPython.testing.decorators import skipif + +class TokenizeFailureTest(unittest.TestCase): + """Tests related to https://github.com/ipython/ipython/issues/6864.""" + + # that appear to test that we are handling an exception that can be thrown + # by the tokenizer due to a bug that seem to have been fixed in 3.8, though + # I'm unsure if other sequences can make it raise this error. Let's just + # skip in 3.8 for now + @skipif(sys.version_info > (3,8)) + def testLogging(self): + message = "An unexpected error occurred while tokenizing input" + cell = 'raise ValueError("""a\nb""")' + + stream = io.StringIO() + handler = logging.StreamHandler(stream) + logger = logging.getLogger() + loglevel = logger.level + logger.addHandler(handler) + self.addCleanup(lambda: logger.removeHandler(handler)) + self.addCleanup(lambda: logger.setLevel(loglevel)) + + logger.setLevel(logging.INFO) + with tt.AssertNotPrints(message): + ip.run_cell(cell) + self.assertNotIn(message, stream.getvalue()) + + logger.setLevel(logging.DEBUG) + with tt.AssertNotPrints(message): + ip.run_cell(cell) + self.assertIn(message, stream.getvalue()) diff --git a/.venv/lib/python3.8/site-packages/IPython/core/ultratb.py b/.venv/lib/python3.8/site-packages/IPython/core/ultratb.py new file mode 100644 index 00000000..4358ea5b --- /dev/null +++ b/.venv/lib/python3.8/site-packages/IPython/core/ultratb.py @@ -0,0 +1,1525 @@ +# -*- coding: utf-8 -*- +""" +Verbose and colourful traceback formatting. + +**ColorTB** + +I've always found it a bit hard to visually parse tracebacks in Python. The +ColorTB class is a solution to that problem. It colors the different parts of a +traceback in a manner similar to what you would expect from a syntax-highlighting +text editor. + +Installation instructions for ColorTB:: + + import sys,ultratb + sys.excepthook = ultratb.ColorTB() + +**VerboseTB** + +I've also included a port of Ka-Ping Yee's "cgitb.py" that produces all kinds +of useful info when a traceback occurs. Ping originally had it spit out HTML +and intended it for CGI programmers, but why should they have all the fun? I +altered it to spit out colored text to the terminal. It's a bit overwhelming, +but kind of neat, and maybe useful for long-running programs that you believe +are bug-free. If a crash *does* occur in that type of program you want details. +Give it a shot--you'll love it or you'll hate it. + +.. note:: + + The Verbose mode prints the variables currently visible where the exception + happened (shortening their strings if too long). This can potentially be + very slow, if you happen to have a huge data structure whose string + representation is complex to compute. Your computer may appear to freeze for + a while with cpu usage at 100%. If this occurs, you can cancel the traceback + with Ctrl-C (maybe hitting it more than once). + + If you encounter this kind of situation often, you may want to use the + Verbose_novars mode instead of the regular Verbose, which avoids formatting + variables (but otherwise includes the information and context given by + Verbose). + +.. note:: + + The verbose mode print all variables in the stack, which means it can + potentially leak sensitive information like access keys, or unencrypted + password. + +Installation instructions for VerboseTB:: + + import sys,ultratb + sys.excepthook = ultratb.VerboseTB() + +Note: Much of the code in this module was lifted verbatim from the standard +library module 'traceback.py' and Ka-Ping Yee's 'cgitb.py'. + +Color schemes +------------- + +The colors are defined in the class TBTools through the use of the +ColorSchemeTable class. Currently the following exist: + + - NoColor: allows all of this module to be used in any terminal (the color + escapes are just dummy blank strings). + + - Linux: is meant to look good in a terminal like the Linux console (black + or very dark background). + + - LightBG: similar to Linux but swaps dark/light colors to be more readable + in light background terminals. + + - Neutral: a neutral color scheme that should be readable on both light and + dark background + +You can implement other color schemes easily, the syntax is fairly +self-explanatory. Please send back new schemes you develop to the author for +possible inclusion in future releases. + +Inheritance diagram: + +.. inheritance-diagram:: IPython.core.ultratb + :parts: 3 +""" + +#***************************************************************************** +# Copyright (C) 2001 Nathaniel Gray +# Copyright (C) 2001-2004 Fernando Perez +# +# Distributed under the terms of the BSD License. The full license is in +# the file COPYING, distributed as part of this software. +#***************************************************************************** + + +import dis +import inspect +import keyword +import linecache +import os +import pydoc +import re +import sys +import time +import tokenize +import traceback + +from tokenize import generate_tokens + +# For purposes of monkeypatching inspect to fix a bug in it. +from inspect import getsourcefile, getfile, getmodule, \ + ismodule, isclass, ismethod, isfunction, istraceback, isframe, iscode + +# IPython's own modules +from IPython import get_ipython +from IPython.core import debugger +from IPython.core.display_trap import DisplayTrap +from IPython.core.excolors import exception_colors +from IPython.utils import PyColorize +from IPython.utils import path as util_path +from IPython.utils import py3compat +from IPython.utils.data import uniq_stable +from IPython.utils.terminal import get_terminal_size + +from logging import info, error, debug + +from importlib.util import source_from_cache + +import IPython.utils.colorable as colorable + +# Globals +# amount of space to put line numbers before verbose tracebacks +INDENT_SIZE = 8 + +# Default color scheme. This is used, for example, by the traceback +# formatter. When running in an actual IPython instance, the user's rc.colors +# value is used, but having a module global makes this functionality available +# to users of ultratb who are NOT running inside ipython. +DEFAULT_SCHEME = 'NoColor' + + +# Number of frame above which we are likely to have a recursion and will +# **attempt** to detect it. Made modifiable mostly to speedup test suite +# as detecting recursion is one of our slowest test +_FRAME_RECURSION_LIMIT = 500 + +# --------------------------------------------------------------------------- +# Code begins + +# Utility functions +def inspect_error(): + """Print a message about internal inspect errors. + + These are unfortunately quite common.""" + + error('Internal Python error in the inspect module.\n' + 'Below is the traceback from this internal error.\n') + + +# This function is a monkeypatch we apply to the Python inspect module. We have +# now found when it's needed (see discussion on issue gh-1456), and we have a +# test case (IPython.core.tests.test_ultratb.ChangedPyFileTest) that fails if +# the monkeypatch is not applied. TK, Aug 2012. +def findsource(object): + """Return the entire source file and starting line number for an object. + + The argument may be a module, class, method, function, traceback, frame, + or code object. The source code is returned as a list of all the lines + in the file and the line number indexes a line in that list. An IOError + is raised if the source code cannot be retrieved. + + FIXED version with which we monkeypatch the stdlib to work around a bug.""" + + file = getsourcefile(object) or getfile(object) + # If the object is a frame, then trying to get the globals dict from its + # module won't work. Instead, the frame object itself has the globals + # dictionary. + globals_dict = None + if inspect.isframe(object): + # XXX: can this ever be false? + globals_dict = object.f_globals + else: + module = getmodule(object, file) + if module: + globals_dict = module.__dict__ + lines = linecache.getlines(file, globals_dict) + if not lines: + raise IOError('could not get source code') + + if ismodule(object): + return lines, 0 + + if isclass(object): + name = object.__name__ + pat = re.compile(r'^(\s*)class\s*' + name + r'\b') + # make some effort to find the best matching class definition: + # use the one with the least indentation, which is the one + # that's most probably not inside a function definition. + candidates = [] + for i, line in enumerate(lines): + match = pat.match(line) + if match: + # if it's at toplevel, it's already the best one + if line[0] == 'c': + return lines, i + # else add whitespace to candidate list + candidates.append((match.group(1), i)) + if candidates: + # this will sort by whitespace, and by line number, + # less whitespace first + candidates.sort() + return lines, candidates[0][1] + else: + raise IOError('could not find class definition') + + if ismethod(object): + object = object.__func__ + if isfunction(object): + object = object.__code__ + if istraceback(object): + object = object.tb_frame + if isframe(object): + object = object.f_code + if iscode(object): + if not hasattr(object, 'co_firstlineno'): + raise IOError('could not find function definition') + pat = re.compile(r'^(\s*def\s)|(.*(? 0: + if pmatch(lines[lnum]): + break + lnum -= 1 + + return lines, lnum + raise IOError('could not find code object') + + +# This is a patched version of inspect.getargs that applies the (unmerged) +# patch for http://bugs.python.org/issue14611 by Stefano Taschini. This fixes +# https://github.com/ipython/ipython/issues/8205 and +# https://github.com/ipython/ipython/issues/8293 +def getargs(co): + """Get information about the arguments accepted by a code object. + + Three things are returned: (args, varargs, varkw), where 'args' is + a list of argument names (possibly containing nested lists), and + 'varargs' and 'varkw' are the names of the * and ** arguments or None.""" + if not iscode(co): + raise TypeError('{!r} is not a code object'.format(co)) + + nargs = co.co_argcount + names = co.co_varnames + args = list(names[:nargs]) + step = 0 + + # The following acrobatics are for anonymous (tuple) arguments. + for i in range(nargs): + if args[i][:1] in ('', '.'): + stack, remain, count = [], [], [] + while step < len(co.co_code): + op = ord(co.co_code[step]) + step = step + 1 + if op >= dis.HAVE_ARGUMENT: + opname = dis.opname[op] + value = ord(co.co_code[step]) + ord(co.co_code[step+1])*256 + step = step + 2 + if opname in ('UNPACK_TUPLE', 'UNPACK_SEQUENCE'): + remain.append(value) + count.append(value) + elif opname in ('STORE_FAST', 'STORE_DEREF'): + if op in dis.haslocal: + stack.append(co.co_varnames[value]) + elif op in dis.hasfree: + stack.append((co.co_cellvars + co.co_freevars)[value]) + # Special case for sublists of length 1: def foo((bar)) + # doesn't generate the UNPACK_TUPLE bytecode, so if + # `remain` is empty here, we have such a sublist. + if not remain: + stack[0] = [stack[0]] + break + else: + remain[-1] = remain[-1] - 1 + while remain[-1] == 0: + remain.pop() + size = count.pop() + stack[-size:] = [stack[-size:]] + if not remain: + break + remain[-1] = remain[-1] - 1 + if not remain: + break + args[i] = stack[0] + + varargs = None + if co.co_flags & inspect.CO_VARARGS: + varargs = co.co_varnames[nargs] + nargs = nargs + 1 + varkw = None + if co.co_flags & inspect.CO_VARKEYWORDS: + varkw = co.co_varnames[nargs] + return inspect.Arguments(args, varargs, varkw) + + +# Monkeypatch inspect to apply our bugfix. +def with_patch_inspect(f): + """ + Deprecated since IPython 6.0 + decorator for monkeypatching inspect.findsource + """ + + def wrapped(*args, **kwargs): + save_findsource = inspect.findsource + save_getargs = inspect.getargs + inspect.findsource = findsource + inspect.getargs = getargs + try: + return f(*args, **kwargs) + finally: + inspect.findsource = save_findsource + inspect.getargs = save_getargs + + return wrapped + + +def fix_frame_records_filenames(records): + """Try to fix the filenames in each record from inspect.getinnerframes(). + + Particularly, modules loaded from within zip files have useless filenames + attached to their code object, and inspect.getinnerframes() just uses it. + """ + fixed_records = [] + for frame, filename, line_no, func_name, lines, index in records: + # Look inside the frame's globals dictionary for __file__, + # which should be better. However, keep Cython filenames since + # we prefer the source filenames over the compiled .so file. + if not filename.endswith(('.pyx', '.pxd', '.pxi')): + better_fn = frame.f_globals.get('__file__', None) + if isinstance(better_fn, str): + # Check the type just in case someone did something weird with + # __file__. It might also be None if the error occurred during + # import. + filename = better_fn + fixed_records.append((frame, filename, line_no, func_name, lines, index)) + return fixed_records + + +@with_patch_inspect +def _fixed_getinnerframes(etb, context=1, tb_offset=0): + LNUM_POS, LINES_POS, INDEX_POS = 2, 4, 5 + + records = fix_frame_records_filenames(inspect.getinnerframes(etb, context)) + # If the error is at the console, don't build any context, since it would + # otherwise produce 5 blank lines printed out (there is no file at the + # console) + rec_check = records[tb_offset:] + try: + rname = rec_check[0][1] + if rname == '' or rname.endswith(''): + return rec_check + except IndexError: + pass + + aux = traceback.extract_tb(etb) + assert len(records) == len(aux) + for i, (file, lnum, _, _) in enumerate(aux): + maybeStart = lnum - 1 - context // 2 + start = max(maybeStart, 0) + end = start + context + lines = linecache.getlines(file)[start:end] + buf = list(records[i]) + buf[LNUM_POS] = lnum + buf[INDEX_POS] = lnum - 1 - start + buf[LINES_POS] = lines + records[i] = tuple(buf) + return records[tb_offset:] + +# Helper function -- largely belongs to VerboseTB, but we need the same +# functionality to produce a pseudo verbose TB for SyntaxErrors, so that they +# can be recognized properly by ipython.el's py-traceback-line-re +# (SyntaxErrors have to be treated specially because they have no traceback) + + +def _format_traceback_lines(lnum, index, lines, Colors, lvals, _line_format): + """ + Format tracebacks lines with pointing arrow, leading numbers... + + Parameters + ========== + + lnum: int + index: int + lines: list[string] + Colors: + ColorScheme used. + lvals: bytes + Values of local variables, already colored, to inject just after the error line. + _line_format: f (str) -> (str, bool) + return (colorized version of str, failure to do so) + """ + numbers_width = INDENT_SIZE - 1 + res = [] + + for i,line in enumerate(lines, lnum-index): + line = py3compat.cast_unicode(line) + + new_line, err = _line_format(line, 'str') + if not err: + line = new_line + + if i == lnum: + # This is the line with the error + pad = numbers_width - len(str(i)) + num = '%s%s' % (debugger.make_arrow(pad), str(lnum)) + line = '%s%s%s %s%s' % (Colors.linenoEm, num, + Colors.line, line, Colors.Normal) + else: + num = '%*s' % (numbers_width, i) + line = '%s%s%s %s' % (Colors.lineno, num, + Colors.Normal, line) + + res.append(line) + if lvals and i == lnum: + res.append(lvals + '\n') + return res + +def is_recursion_error(etype, value, records): + try: + # RecursionError is new in Python 3.5 + recursion_error_type = RecursionError + except NameError: + recursion_error_type = RuntimeError + + # The default recursion limit is 1000, but some of that will be taken up + # by stack frames in IPython itself. >500 frames probably indicates + # a recursion error. + return (etype is recursion_error_type) \ + and "recursion" in str(value).lower() \ + and len(records) > _FRAME_RECURSION_LIMIT + +def find_recursion(etype, value, records): + """Identify the repeating stack frames from a RecursionError traceback + + 'records' is a list as returned by VerboseTB.get_records() + + Returns (last_unique, repeat_length) + """ + # This involves a bit of guesswork - we want to show enough of the traceback + # to indicate where the recursion is occurring. We guess that the innermost + # quarter of the traceback (250 frames by default) is repeats, and find the + # first frame (from in to out) that looks different. + if not is_recursion_error(etype, value, records): + return len(records), 0 + + # Select filename, lineno, func_name to track frames with + records = [r[1:4] for r in records] + inner_frames = records[-(len(records)//4):] + frames_repeated = set(inner_frames) + + last_seen_at = {} + longest_repeat = 0 + i = len(records) + for frame in reversed(records): + i -= 1 + if frame not in frames_repeated: + last_unique = i + break + + if frame in last_seen_at: + distance = last_seen_at[frame] - i + longest_repeat = max(longest_repeat, distance) + + last_seen_at[frame] = i + else: + last_unique = 0 # The whole traceback was recursion + + return last_unique, longest_repeat + +#--------------------------------------------------------------------------- +# Module classes +class TBTools(colorable.Colorable): + """Basic tools used by all traceback printer classes.""" + + # Number of frames to skip when reporting tracebacks + tb_offset = 0 + + def __init__(self, color_scheme='NoColor', call_pdb=False, ostream=None, parent=None, config=None): + # Whether to call the interactive pdb debugger after printing + # tracebacks or not + super(TBTools, self).__init__(parent=parent, config=config) + self.call_pdb = call_pdb + + # Output stream to write to. Note that we store the original value in + # a private attribute and then make the public ostream a property, so + # that we can delay accessing sys.stdout until runtime. The way + # things are written now, the sys.stdout object is dynamically managed + # so a reference to it should NEVER be stored statically. This + # property approach confines this detail to a single location, and all + # subclasses can simply access self.ostream for writing. + self._ostream = ostream + + # Create color table + self.color_scheme_table = exception_colors() + + self.set_colors(color_scheme) + self.old_scheme = color_scheme # save initial value for toggles + + if call_pdb: + self.pdb = debugger.Pdb() + else: + self.pdb = None + + def _get_ostream(self): + """Output stream that exceptions are written to. + + Valid values are: + + - None: the default, which means that IPython will dynamically resolve + to sys.stdout. This ensures compatibility with most tools, including + Windows (where plain stdout doesn't recognize ANSI escapes). + + - Any object with 'write' and 'flush' attributes. + """ + return sys.stdout if self._ostream is None else self._ostream + + def _set_ostream(self, val): + assert val is None or (hasattr(val, 'write') and hasattr(val, 'flush')) + self._ostream = val + + ostream = property(_get_ostream, _set_ostream) + + def get_parts_of_chained_exception(self, evalue): + def get_chained_exception(exception_value): + cause = getattr(exception_value, '__cause__', None) + if cause: + return cause + if getattr(exception_value, '__suppress_context__', False): + return None + return getattr(exception_value, '__context__', None) + + chained_evalue = get_chained_exception(evalue) + + if chained_evalue: + return chained_evalue.__class__, chained_evalue, chained_evalue.__traceback__ + + def prepare_chained_exception_message(self, cause): + direct_cause = "\nThe above exception was the direct cause of the following exception:\n" + exception_during_handling = "\nDuring handling of the above exception, another exception occurred:\n" + + if cause: + message = [[direct_cause]] + else: + message = [[exception_during_handling]] + return message + + def set_colors(self, *args, **kw): + """Shorthand access to the color table scheme selector method.""" + + # Set own color table + self.color_scheme_table.set_active_scheme(*args, **kw) + # for convenience, set Colors to the active scheme + self.Colors = self.color_scheme_table.active_colors + # Also set colors of debugger + if hasattr(self, 'pdb') and self.pdb is not None: + self.pdb.set_colors(*args, **kw) + + def color_toggle(self): + """Toggle between the currently active color scheme and NoColor.""" + + if self.color_scheme_table.active_scheme_name == 'NoColor': + self.color_scheme_table.set_active_scheme(self.old_scheme) + self.Colors = self.color_scheme_table.active_colors + else: + self.old_scheme = self.color_scheme_table.active_scheme_name + self.color_scheme_table.set_active_scheme('NoColor') + self.Colors = self.color_scheme_table.active_colors + + def stb2text(self, stb): + """Convert a structured traceback (a list) to a string.""" + return '\n'.join(stb) + + def text(self, etype, value, tb, tb_offset=None, context=5): + """Return formatted traceback. + + Subclasses may override this if they add extra arguments. + """ + tb_list = self.structured_traceback(etype, value, tb, + tb_offset, context) + return self.stb2text(tb_list) + + def structured_traceback(self, etype, evalue, tb, tb_offset=None, + context=5, mode=None): + """Return a list of traceback frames. + + Must be implemented by each class. + """ + raise NotImplementedError() + + +#--------------------------------------------------------------------------- +class ListTB(TBTools): + """Print traceback information from a traceback list, with optional color. + + Calling requires 3 arguments: (etype, evalue, elist) + as would be obtained by:: + + etype, evalue, tb = sys.exc_info() + if tb: + elist = traceback.extract_tb(tb) + else: + elist = None + + It can thus be used by programs which need to process the traceback before + printing (such as console replacements based on the code module from the + standard library). + + Because they are meant to be called without a full traceback (only a + list), instances of this class can't call the interactive pdb debugger.""" + + def __init__(self, color_scheme='NoColor', call_pdb=False, ostream=None, parent=None, config=None): + TBTools.__init__(self, color_scheme=color_scheme, call_pdb=call_pdb, + ostream=ostream, parent=parent,config=config) + + def __call__(self, etype, value, elist): + self.ostream.flush() + self.ostream.write(self.text(etype, value, elist)) + self.ostream.write('\n') + + def _extract_tb(self, tb): + if tb: + return traceback.extract_tb(tb) + else: + return None + + def structured_traceback(self, etype, evalue, etb=None, tb_offset=None, + context=5): + """Return a color formatted string with the traceback info. + + Parameters + ---------- + etype : exception type + Type of the exception raised. + + evalue : object + Data stored in the exception + + etb : object + If list: List of frames, see class docstring for details. + If Traceback: Traceback of the exception. + + tb_offset : int, optional + Number of frames in the traceback to skip. If not given, the + instance evalue is used (set in constructor). + + context : int, optional + Number of lines of context information to print. + + Returns + ------- + String with formatted exception. + """ + # This is a workaround to get chained_exc_ids in recursive calls + # etb should not be a tuple if structured_traceback is not recursive + if isinstance(etb, tuple): + etb, chained_exc_ids = etb + else: + chained_exc_ids = set() + + if isinstance(etb, list): + elist = etb + elif etb is not None: + elist = self._extract_tb(etb) + else: + elist = [] + tb_offset = self.tb_offset if tb_offset is None else tb_offset + Colors = self.Colors + out_list = [] + if elist: + + if tb_offset and len(elist) > tb_offset: + elist = elist[tb_offset:] + + out_list.append('Traceback %s(most recent call last)%s:' % + (Colors.normalEm, Colors.Normal) + '\n') + out_list.extend(self._format_list(elist)) + # The exception info should be a single entry in the list. + lines = ''.join(self._format_exception_only(etype, evalue)) + out_list.append(lines) + + exception = self.get_parts_of_chained_exception(evalue) + + if exception and not id(exception[1]) in chained_exc_ids: + chained_exception_message = self.prepare_chained_exception_message( + evalue.__cause__)[0] + etype, evalue, etb = exception + # Trace exception to avoid infinite 'cause' loop + chained_exc_ids.add(id(exception[1])) + chained_exceptions_tb_offset = 0 + out_list = ( + self.structured_traceback( + etype, evalue, (etb, chained_exc_ids), + chained_exceptions_tb_offset, context) + + chained_exception_message + + out_list) + + return out_list + + def _format_list(self, extracted_list): + """Format a list of traceback entry tuples for printing. + + Given a list of tuples as returned by extract_tb() or + extract_stack(), return a list of strings ready for printing. + Each string in the resulting list corresponds to the item with the + same index in the argument list. Each string ends in a newline; + the strings may contain internal newlines as well, for those items + whose source text line is not None. + + Lifted almost verbatim from traceback.py + """ + + Colors = self.Colors + list = [] + for filename, lineno, name, line in extracted_list[:-1]: + item = ' File %s"%s"%s, line %s%d%s, in %s%s%s\n' % \ + (Colors.filename, filename, Colors.Normal, + Colors.lineno, lineno, Colors.Normal, + Colors.name, name, Colors.Normal) + if line: + item += ' %s\n' % line.strip() + list.append(item) + # Emphasize the last entry + filename, lineno, name, line = extracted_list[-1] + item = '%s File %s"%s"%s, line %s%d%s, in %s%s%s%s\n' % \ + (Colors.normalEm, + Colors.filenameEm, filename, Colors.normalEm, + Colors.linenoEm, lineno, Colors.normalEm, + Colors.nameEm, name, Colors.normalEm, + Colors.Normal) + if line: + item += '%s %s%s\n' % (Colors.line, line.strip(), + Colors.Normal) + list.append(item) + return list + + def _format_exception_only(self, etype, value): + """Format the exception part of a traceback. + + The arguments are the exception type and value such as given by + sys.exc_info()[:2]. The return value is a list of strings, each ending + in a newline. Normally, the list contains a single string; however, + for SyntaxError exceptions, it contains several lines that (when + printed) display detailed information about where the syntax error + occurred. The message indicating which exception occurred is the + always last string in the list. + + Also lifted nearly verbatim from traceback.py + """ + have_filedata = False + Colors = self.Colors + list = [] + stype = py3compat.cast_unicode(Colors.excName + etype.__name__ + Colors.Normal) + if value is None: + # Not sure if this can still happen in Python 2.6 and above + list.append(stype + '\n') + else: + if issubclass(etype, SyntaxError): + have_filedata = True + if not value.filename: value.filename = "" + if value.lineno: + lineno = value.lineno + textline = linecache.getline(value.filename, value.lineno) + else: + lineno = 'unknown' + textline = '' + list.append('%s File %s"%s"%s, line %s%s%s\n' % \ + (Colors.normalEm, + Colors.filenameEm, py3compat.cast_unicode(value.filename), Colors.normalEm, + Colors.linenoEm, lineno, Colors.Normal )) + if textline == '': + textline = py3compat.cast_unicode(value.text, "utf-8") + + if textline is not None: + i = 0 + while i < len(textline) and textline[i].isspace(): + i += 1 + list.append('%s %s%s\n' % (Colors.line, + textline.strip(), + Colors.Normal)) + if value.offset is not None: + s = ' ' + for c in textline[i:value.offset - 1]: + if c.isspace(): + s += c + else: + s += ' ' + list.append('%s%s^%s\n' % (Colors.caret, s, + Colors.Normal)) + + try: + s = value.msg + except Exception: + s = self._some_str(value) + if s: + list.append('%s%s:%s %s\n' % (stype, Colors.excName, + Colors.Normal, s)) + else: + list.append('%s\n' % stype) + + # sync with user hooks + if have_filedata: + ipinst = get_ipython() + if ipinst is not None: + ipinst.hooks.synchronize_with_editor(value.filename, value.lineno, 0) + + return list + + def get_exception_only(self, etype, value): + """Only print the exception type and message, without a traceback. + + Parameters + ---------- + etype : exception type + value : exception value + """ + return ListTB.structured_traceback(self, etype, value) + + def show_exception_only(self, etype, evalue): + """Only print the exception type and message, without a traceback. + + Parameters + ---------- + etype : exception type + value : exception value + """ + # This method needs to use __call__ from *this* class, not the one from + # a subclass whose signature or behavior may be different + ostream = self.ostream + ostream.flush() + ostream.write('\n'.join(self.get_exception_only(etype, evalue))) + ostream.flush() + + def _some_str(self, value): + # Lifted from traceback.py + try: + return py3compat.cast_unicode(str(value)) + except: + return u'' % type(value).__name__ + + +#---------------------------------------------------------------------------- +class VerboseTB(TBTools): + """A port of Ka-Ping Yee's cgitb.py module that outputs color text instead + of HTML. Requires inspect and pydoc. Crazy, man. + + Modified version which optionally strips the topmost entries from the + traceback, to be used with alternate interpreters (because their own code + would appear in the traceback).""" + + def __init__(self, color_scheme='Linux', call_pdb=False, ostream=None, + tb_offset=0, long_header=False, include_vars=True, + check_cache=None, debugger_cls = None, + parent=None, config=None): + """Specify traceback offset, headers and color scheme. + + Define how many frames to drop from the tracebacks. Calling it with + tb_offset=1 allows use of this handler in interpreters which will have + their own code at the top of the traceback (VerboseTB will first + remove that frame before printing the traceback info).""" + TBTools.__init__(self, color_scheme=color_scheme, call_pdb=call_pdb, + ostream=ostream, parent=parent, config=config) + self.tb_offset = tb_offset + self.long_header = long_header + self.include_vars = include_vars + # By default we use linecache.checkcache, but the user can provide a + # different check_cache implementation. This is used by the IPython + # kernel to provide tracebacks for interactive code that is cached, + # by a compiler instance that flushes the linecache but preserves its + # own code cache. + if check_cache is None: + check_cache = linecache.checkcache + self.check_cache = check_cache + + self.debugger_cls = debugger_cls or debugger.Pdb + self.skip_hidden = True + + def format_records(self, records, last_unique, recursion_repeat): + """Format the stack frames of the traceback""" + frames = [] + + skipped = 0 + lastrecord = len(records) - 1 + for i, r in enumerate(records[: last_unique + recursion_repeat + 1]): + if self.skip_hidden: + if r[0].f_locals.get("__tracebackhide__", 0) and i != lastrecord: + skipped += 1 + continue + if skipped: + Colors = self.Colors # just a shorthand + quicker name lookup + ColorsNormal = Colors.Normal # used a lot + frames.append( + " %s[... skipping hidden %s frame]%s\n" + % (Colors.excName, skipped, ColorsNormal) + ) + skipped = 0 + + frames.append(self.format_record(*r)) + + if skipped: + Colors = self.Colors # just a shorthand + quicker name lookup + ColorsNormal = Colors.Normal # used a lot + frames.append( + " %s[... skipping hidden %s frame]%s\n" + % (Colors.excName, skipped, ColorsNormal) + ) + + if recursion_repeat: + frames.append('... last %d frames repeated, from the frame below ...\n' % recursion_repeat) + frames.append(self.format_record(*records[last_unique+recursion_repeat+1])) + + return frames + + def format_record(self, frame, file, lnum, func, lines, index): + """Format a single stack frame""" + Colors = self.Colors # just a shorthand + quicker name lookup + ColorsNormal = Colors.Normal # used a lot + col_scheme = self.color_scheme_table.active_scheme_name + indent = ' ' * INDENT_SIZE + em_normal = '%s\n%s%s' % (Colors.valEm, indent, ColorsNormal) + undefined = '%sundefined%s' % (Colors.em, ColorsNormal) + tpl_link = '%s%%s%s' % (Colors.filenameEm, ColorsNormal) + tpl_call = 'in %s%%s%s%%s%s' % (Colors.vName, Colors.valEm, + ColorsNormal) + tpl_call_fail = 'in %s%%s%s(***failed resolving arguments***)%s' % \ + (Colors.vName, Colors.valEm, ColorsNormal) + tpl_local_var = '%s%%s%s' % (Colors.vName, ColorsNormal) + tpl_global_var = '%sglobal%s %s%%s%s' % (Colors.em, ColorsNormal, + Colors.vName, ColorsNormal) + tpl_name_val = '%%s %s= %%s%s' % (Colors.valEm, ColorsNormal) + + if not file: + file = '?' + elif file.startswith(str("<")) and file.endswith(str(">")): + # Not a real filename, no problem... + pass + elif not os.path.isabs(file): + # Try to make the filename absolute by trying all + # sys.path entries (which is also what linecache does) + for dirname in sys.path: + try: + fullname = os.path.join(dirname, file) + if os.path.isfile(fullname): + file = os.path.abspath(fullname) + break + except Exception: + # Just in case that sys.path contains very + # strange entries... + pass + + file = py3compat.cast_unicode(file, util_path.fs_encoding) + link = tpl_link % util_path.compress_user(file) + args, varargs, varkw, locals_ = inspect.getargvalues(frame) + + if func == '?': + call = '' + elif func == '': + call = tpl_call % (func, '') + else: + # Decide whether to include variable details or not + var_repr = eqrepr if self.include_vars else nullrepr + try: + call = tpl_call % (func, inspect.formatargvalues(args, + varargs, varkw, + locals_, formatvalue=var_repr)) + except KeyError: + # This happens in situations like errors inside generator + # expressions, where local variables are listed in the + # line, but can't be extracted from the frame. I'm not + # 100% sure this isn't actually a bug in inspect itself, + # but since there's no info for us to compute with, the + # best we can do is report the failure and move on. Here + # we must *not* call any traceback construction again, + # because that would mess up use of %debug later on. So we + # simply report the failure and move on. The only + # limitation will be that this frame won't have locals + # listed in the call signature. Quite subtle problem... + # I can't think of a good way to validate this in a unit + # test, but running a script consisting of: + # dict( (k,v.strip()) for (k,v) in range(10) ) + # will illustrate the error, if this exception catch is + # disabled. + call = tpl_call_fail % func + + # Don't attempt to tokenize binary files. + if file.endswith(('.so', '.pyd', '.dll')): + return '%s %s\n' % (link, call) + + elif file.endswith(('.pyc', '.pyo')): + # Look up the corresponding source file. + try: + file = source_from_cache(file) + except ValueError: + # Failed to get the source file for some reason + # E.g. https://github.com/ipython/ipython/issues/9486 + return '%s %s\n' % (link, call) + + def linereader(file=file, lnum=[lnum], getline=linecache.getline): + line = getline(file, lnum[0]) + lnum[0] += 1 + return line + + # Build the list of names on this line of code where the exception + # occurred. + try: + names = [] + name_cont = False + + for token_type, token, start, end, line in generate_tokens(linereader): + # build composite names + if token_type == tokenize.NAME and token not in keyword.kwlist: + if name_cont: + # Continuation of a dotted name + try: + names[-1].append(token) + except IndexError: + names.append([token]) + name_cont = False + else: + # Regular new names. We append everything, the caller + # will be responsible for pruning the list later. It's + # very tricky to try to prune as we go, b/c composite + # names can fool us. The pruning at the end is easy + # to do (or the caller can print a list with repeated + # names if so desired. + names.append([token]) + elif token == '.': + name_cont = True + elif token_type == tokenize.NEWLINE: + break + + except (IndexError, UnicodeDecodeError, SyntaxError): + # signals exit of tokenizer + # SyntaxError can occur if the file is not actually Python + # - see gh-6300 + pass + except tokenize.TokenError as msg: + # Tokenizing may fail for various reasons, many of which are + # harmless. (A good example is when the line in question is the + # close of a triple-quoted string, cf gh-6864). We don't want to + # show this to users, but want make it available for debugging + # purposes. + _m = ("An unexpected error occurred while tokenizing input\n" + "The following traceback may be corrupted or invalid\n" + "The error message is: %s\n" % msg) + debug(_m) + + # Join composite names (e.g. "dict.fromkeys") + names = ['.'.join(n) for n in names] + # prune names list of duplicates, but keep the right order + unique_names = uniq_stable(names) + + # Start loop over vars + lvals = '' + lvals_list = [] + if self.include_vars: + for name_full in unique_names: + name_base = name_full.split('.', 1)[0] + if name_base in frame.f_code.co_varnames: + if name_base in locals_: + try: + value = repr(eval(name_full, locals_)) + except: + value = undefined + else: + value = undefined + name = tpl_local_var % name_full + else: + if name_base in frame.f_globals: + try: + value = repr(eval(name_full, frame.f_globals)) + except: + value = undefined + else: + value = undefined + name = tpl_global_var % name_full + lvals_list.append(tpl_name_val % (name, value)) + if lvals_list: + lvals = '%s%s' % (indent, em_normal.join(lvals_list)) + + level = '%s %s\n' % (link, call) + + if index is None: + return level + else: + _line_format = PyColorize.Parser(style=col_scheme, parent=self).format2 + return '%s%s' % (level, ''.join( + _format_traceback_lines(lnum, index, lines, Colors, lvals, + _line_format))) + + def prepare_header(self, etype, long_version=False): + colors = self.Colors # just a shorthand + quicker name lookup + colorsnormal = colors.Normal # used a lot + exc = '%s%s%s' % (colors.excName, etype, colorsnormal) + width = min(75, get_terminal_size()[0]) + if long_version: + # Header with the exception type, python version, and date + pyver = 'Python ' + sys.version.split()[0] + ': ' + sys.executable + date = time.ctime(time.time()) + + head = '%s%s%s\n%s%s%s\n%s' % (colors.topline, '-' * width, colorsnormal, + exc, ' ' * (width - len(str(etype)) - len(pyver)), + pyver, date.rjust(width) ) + head += "\nA problem occurred executing Python code. Here is the sequence of function" \ + "\ncalls leading up to the error, with the most recent (innermost) call last." + else: + # Simplified header + head = '%s%s' % (exc, 'Traceback (most recent call last)'. \ + rjust(width - len(str(etype))) ) + + return head + + def format_exception(self, etype, evalue): + colors = self.Colors # just a shorthand + quicker name lookup + colorsnormal = colors.Normal # used a lot + # Get (safely) a string form of the exception info + try: + etype_str, evalue_str = map(str, (etype, evalue)) + except: + # User exception is improperly defined. + etype, evalue = str, sys.exc_info()[:2] + etype_str, evalue_str = map(str, (etype, evalue)) + # ... and format it + return ['%s%s%s: %s' % (colors.excName, etype_str, + colorsnormal, py3compat.cast_unicode(evalue_str))] + + def format_exception_as_a_whole(self, etype, evalue, etb, number_of_lines_of_context, tb_offset): + """Formats the header, traceback and exception message for a single exception. + + This may be called multiple times by Python 3 exception chaining + (PEP 3134). + """ + # some locals + orig_etype = etype + try: + etype = etype.__name__ + except AttributeError: + pass + + tb_offset = self.tb_offset if tb_offset is None else tb_offset + head = self.prepare_header(etype, self.long_header) + records = self.get_records(etb, number_of_lines_of_context, tb_offset) + + + last_unique, recursion_repeat = find_recursion(orig_etype, evalue, records) + + frames = self.format_records(records, last_unique, recursion_repeat) + + formatted_exception = self.format_exception(etype, evalue) + if records: + filepath, lnum = records[-1][1:3] + filepath = os.path.abspath(filepath) + ipinst = get_ipython() + if ipinst is not None: + ipinst.hooks.synchronize_with_editor(filepath, lnum, 0) + + return [[head] + frames + [''.join(formatted_exception[0])]] + + def get_records(self, etb, number_of_lines_of_context, tb_offset): + try: + # Try the default getinnerframes and Alex's: Alex's fixes some + # problems, but it generates empty tracebacks for console errors + # (5 blanks lines) where none should be returned. + return _fixed_getinnerframes(etb, number_of_lines_of_context, tb_offset) + except UnicodeDecodeError: + # This can occur if a file's encoding magic comment is wrong. + # I can't see a way to recover without duplicating a bunch of code + # from the stdlib traceback module. --TK + error('\nUnicodeDecodeError while processing traceback.\n') + return None + except: + # FIXME: I've been getting many crash reports from python 2.3 + # users, traceable to inspect.py. If I can find a small test-case + # to reproduce this, I should either write a better workaround or + # file a bug report against inspect (if that's the real problem). + # So far, I haven't been able to find an isolated example to + # reproduce the problem. + inspect_error() + traceback.print_exc(file=self.ostream) + info('\nUnfortunately, your original traceback can not be constructed.\n') + return None + + def structured_traceback(self, etype, evalue, etb, tb_offset=None, + number_of_lines_of_context=5): + """Return a nice text document describing the traceback.""" + + formatted_exception = self.format_exception_as_a_whole(etype, evalue, etb, number_of_lines_of_context, + tb_offset) + + colors = self.Colors # just a shorthand + quicker name lookup + colorsnormal = colors.Normal # used a lot + head = '%s%s%s' % (colors.topline, '-' * min(75, get_terminal_size()[0]), colorsnormal) + structured_traceback_parts = [head] + chained_exceptions_tb_offset = 0 + lines_of_context = 3 + formatted_exceptions = formatted_exception + exception = self.get_parts_of_chained_exception(evalue) + if exception: + formatted_exceptions += self.prepare_chained_exception_message(evalue.__cause__) + etype, evalue, etb = exception + else: + evalue = None + chained_exc_ids = set() + while evalue: + formatted_exceptions += self.format_exception_as_a_whole(etype, evalue, etb, lines_of_context, + chained_exceptions_tb_offset) + exception = self.get_parts_of_chained_exception(evalue) + + if exception and not id(exception[1]) in chained_exc_ids: + chained_exc_ids.add(id(exception[1])) # trace exception to avoid infinite 'cause' loop + formatted_exceptions += self.prepare_chained_exception_message(evalue.__cause__) + etype, evalue, etb = exception + else: + evalue = None + + # we want to see exceptions in a reversed order: + # the first exception should be on top + for formatted_exception in reversed(formatted_exceptions): + structured_traceback_parts += formatted_exception + + return structured_traceback_parts + + def debugger(self, force=False): + """Call up the pdb debugger if desired, always clean up the tb + reference. + + Keywords: + + - force(False): by default, this routine checks the instance call_pdb + flag and does not actually invoke the debugger if the flag is false. + The 'force' option forces the debugger to activate even if the flag + is false. + + If the call_pdb flag is set, the pdb interactive debugger is + invoked. In all cases, the self.tb reference to the current traceback + is deleted to prevent lingering references which hamper memory + management. + + Note that each call to pdb() does an 'import readline', so if your app + requires a special setup for the readline completers, you'll have to + fix that by hand after invoking the exception handler.""" + + if force or self.call_pdb: + if self.pdb is None: + self.pdb = self.debugger_cls() + # the system displayhook may have changed, restore the original + # for pdb + display_trap = DisplayTrap(hook=sys.__displayhook__) + with display_trap: + self.pdb.reset() + # Find the right frame so we don't pop up inside ipython itself + if hasattr(self, 'tb') and self.tb is not None: + etb = self.tb + else: + etb = self.tb = sys.last_traceback + while self.tb is not None and self.tb.tb_next is not None: + self.tb = self.tb.tb_next + if etb and etb.tb_next: + etb = etb.tb_next + self.pdb.botframe = etb.tb_frame + self.pdb.interaction(None, etb) + + if hasattr(self, 'tb'): + del self.tb + + def handler(self, info=None): + (etype, evalue, etb) = info or sys.exc_info() + self.tb = etb + ostream = self.ostream + ostream.flush() + ostream.write(self.text(etype, evalue, etb)) + ostream.write('\n') + ostream.flush() + + # Changed so an instance can just be called as VerboseTB_inst() and print + # out the right info on its own. + def __call__(self, etype=None, evalue=None, etb=None): + """This hook can replace sys.excepthook (for Python 2.1 or higher).""" + if etb is None: + self.handler() + else: + self.handler((etype, evalue, etb)) + try: + self.debugger() + except KeyboardInterrupt: + print("\nKeyboardInterrupt") + + +#---------------------------------------------------------------------------- +class FormattedTB(VerboseTB, ListTB): + """Subclass ListTB but allow calling with a traceback. + + It can thus be used as a sys.excepthook for Python > 2.1. + + Also adds 'Context' and 'Verbose' modes, not available in ListTB. + + Allows a tb_offset to be specified. This is useful for situations where + one needs to remove a number of topmost frames from the traceback (such as + occurs with python programs that themselves execute other python code, + like Python shells). """ + + def __init__(self, mode='Plain', color_scheme='Linux', call_pdb=False, + ostream=None, + tb_offset=0, long_header=False, include_vars=False, + check_cache=None, debugger_cls=None, + parent=None, config=None): + + # NEVER change the order of this list. Put new modes at the end: + self.valid_modes = ['Plain', 'Context', 'Verbose', 'Minimal'] + self.verbose_modes = self.valid_modes[1:3] + + VerboseTB.__init__(self, color_scheme=color_scheme, call_pdb=call_pdb, + ostream=ostream, tb_offset=tb_offset, + long_header=long_header, include_vars=include_vars, + check_cache=check_cache, debugger_cls=debugger_cls, + parent=parent, config=config) + + # Different types of tracebacks are joined with different separators to + # form a single string. They are taken from this dict + self._join_chars = dict(Plain='', Context='\n', Verbose='\n', + Minimal='') + # set_mode also sets the tb_join_char attribute + self.set_mode(mode) + + def structured_traceback(self, etype, value, tb, tb_offset=None, number_of_lines_of_context=5): + tb_offset = self.tb_offset if tb_offset is None else tb_offset + mode = self.mode + if mode in self.verbose_modes: + # Verbose modes need a full traceback + return VerboseTB.structured_traceback( + self, etype, value, tb, tb_offset, number_of_lines_of_context + ) + elif mode == 'Minimal': + return ListTB.get_exception_only(self, etype, value) + else: + # We must check the source cache because otherwise we can print + # out-of-date source code. + self.check_cache() + # Now we can extract and format the exception + return ListTB.structured_traceback( + self, etype, value, tb, tb_offset, number_of_lines_of_context + ) + + def stb2text(self, stb): + """Convert a structured traceback (a list) to a string.""" + return self.tb_join_char.join(stb) + + + def set_mode(self, mode=None): + """Switch to the desired mode. + + If mode is not specified, cycles through the available modes.""" + + if not mode: + new_idx = (self.valid_modes.index(self.mode) + 1 ) % \ + len(self.valid_modes) + self.mode = self.valid_modes[new_idx] + elif mode not in self.valid_modes: + raise ValueError('Unrecognized mode in FormattedTB: <' + mode + '>\n' + 'Valid modes: ' + str(self.valid_modes)) + else: + self.mode = mode + # include variable details only in 'Verbose' mode + self.include_vars = (self.mode == self.valid_modes[2]) + # Set the join character for generating text tracebacks + self.tb_join_char = self._join_chars[self.mode] + + # some convenient shortcuts + def plain(self): + self.set_mode(self.valid_modes[0]) + + def context(self): + self.set_mode(self.valid_modes[1]) + + def verbose(self): + self.set_mode(self.valid_modes[2]) + + def minimal(self): + self.set_mode(self.valid_modes[3]) + + +#---------------------------------------------------------------------------- +class AutoFormattedTB(FormattedTB): + """A traceback printer which can be called on the fly. + + It will find out about exceptions by itself. + + A brief example:: + + AutoTB = AutoFormattedTB(mode = 'Verbose',color_scheme='Linux') + try: + ... + except: + AutoTB() # or AutoTB(out=logfile) where logfile is an open file object + """ + + def __call__(self, etype=None, evalue=None, etb=None, + out=None, tb_offset=None): + """Print out a formatted exception traceback. + + Optional arguments: + - out: an open file-like object to direct output to. + + - tb_offset: the number of frames to skip over in the stack, on a + per-call basis (this overrides temporarily the instance's tb_offset + given at initialization time. """ + + if out is None: + out = self.ostream + out.flush() + out.write(self.text(etype, evalue, etb, tb_offset)) + out.write('\n') + out.flush() + # FIXME: we should remove the auto pdb behavior from here and leave + # that to the clients. + try: + self.debugger() + except KeyboardInterrupt: + print("\nKeyboardInterrupt") + + def structured_traceback(self, etype=None, value=None, tb=None, + tb_offset=None, number_of_lines_of_context=5): + if etype is None: + etype, value, tb = sys.exc_info() + if isinstance(tb, tuple): + # tb is a tuple if this is a chained exception. + self.tb = tb[0] + else: + self.tb = tb + return FormattedTB.structured_traceback( + self, etype, value, tb, tb_offset, number_of_lines_of_context) + + +#--------------------------------------------------------------------------- + +# A simple class to preserve Nathan's original functionality. +class ColorTB(FormattedTB): + """Shorthand to initialize a FormattedTB in Linux colors mode.""" + + def __init__(self, color_scheme='Linux', call_pdb=0, **kwargs): + FormattedTB.__init__(self, color_scheme=color_scheme, + call_pdb=call_pdb, **kwargs) + + +class SyntaxTB(ListTB): + """Extension which holds some state: the last exception value""" + + def __init__(self, color_scheme='NoColor', parent=None, config=None): + ListTB.__init__(self, color_scheme, parent=parent, config=config) + self.last_syntax_error = None + + def __call__(self, etype, value, elist): + self.last_syntax_error = value + + ListTB.__call__(self, etype, value, elist) + + def structured_traceback(self, etype, value, elist, tb_offset=None, + context=5): + # If the source file has been edited, the line in the syntax error can + # be wrong (retrieved from an outdated cache). This replaces it with + # the current value. + if isinstance(value, SyntaxError) \ + and isinstance(value.filename, str) \ + and isinstance(value.lineno, int): + linecache.checkcache(value.filename) + newtext = linecache.getline(value.filename, value.lineno) + if newtext: + value.text = newtext + self.last_syntax_error = value + return super(SyntaxTB, self).structured_traceback(etype, value, elist, + tb_offset=tb_offset, context=context) + + def clear_err_state(self): + """Return the current error state and clear it""" + e = self.last_syntax_error + self.last_syntax_error = None + return e + + def stb2text(self, stb): + """Convert a structured traceback (a list) to a string.""" + return ''.join(stb) + + +# some internal-use functions +def text_repr(value): + """Hopefully pretty robust repr equivalent.""" + # this is pretty horrible but should always return *something* + try: + return pydoc.text.repr(value) + except KeyboardInterrupt: + raise + except: + try: + return repr(value) + except KeyboardInterrupt: + raise + except: + try: + # all still in an except block so we catch + # getattr raising + name = getattr(value, '__name__', None) + if name: + # ick, recursion + return text_repr(name) + klass = getattr(value, '__class__', None) + if klass: + return '%s instance' % text_repr(klass) + except KeyboardInterrupt: + raise + except: + return 'UNRECOVERABLE REPR FAILURE' + + +def eqrepr(value, repr=text_repr): + return '=%s' % repr(value) + + +def nullrepr(value, repr=text_repr): + return '' diff --git a/.venv/lib/python3.8/site-packages/IPython/core/usage.py b/.venv/lib/python3.8/site-packages/IPython/core/usage.py new file mode 100644 index 00000000..37024c44 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/IPython/core/usage.py @@ -0,0 +1,341 @@ +# -*- coding: utf-8 -*- +"""Usage information for the main IPython applications. +""" +#----------------------------------------------------------------------------- +# Copyright (C) 2008-2011 The IPython Development Team +# Copyright (C) 2001-2007 Fernando Perez. +# +# Distributed under the terms of the BSD License. The full license is in +# the file COPYING, distributed as part of this software. +#----------------------------------------------------------------------------- + +import sys +from IPython.core import release + +cl_usage = """\ +========= + IPython +========= + +Tools for Interactive Computing in Python +========================================= + + A Python shell with automatic history (input and output), dynamic object + introspection, easier configuration, command completion, access to the + system shell and more. IPython can also be embedded in running programs. + + +Usage + + ipython [subcommand] [options] [-c cmd | -m mod | file] [--] [arg] ... + + If invoked with no options, it executes the file and exits, passing the + remaining arguments to the script, just as if you had specified the same + command with python. You may need to specify `--` before args to be passed + to the script, to prevent IPython from attempting to parse them. If you + specify the option `-i` before the filename, it will enter an interactive + IPython session after running the script, rather than exiting. Files ending + in .py will be treated as normal Python, but files ending in .ipy can + contain special IPython syntax (magic commands, shell expansions, etc.). + + Almost all configuration in IPython is available via the command-line. Do + `ipython --help-all` to see all available options. For persistent + configuration, look into your `ipython_config.py` configuration file for + details. + + This file is typically installed in the `IPYTHONDIR` directory, and there + is a separate configuration directory for each profile. The default profile + directory will be located in $IPYTHONDIR/profile_default. IPYTHONDIR + defaults to to `$HOME/.ipython`. For Windows users, $HOME resolves to + C:\\Users\\YourUserName in most instances. + + To initialize a profile with the default configuration file, do:: + + $> ipython profile create + + and start editing `IPYTHONDIR/profile_default/ipython_config.py` + + In IPython's documentation, we will refer to this directory as + `IPYTHONDIR`, you can change its default location by creating an + environment variable with this name and setting it to the desired path. + + For more information, see the manual available in HTML and PDF in your + installation, or online at https://ipython.org/documentation.html. +""" + +interactive_usage = """ +IPython -- An enhanced Interactive Python +========================================= + +IPython offers a fully compatible replacement for the standard Python +interpreter, with convenient shell features, special commands, command +history mechanism and output results caching. + +At your system command line, type 'ipython -h' to see the command line +options available. This document only describes interactive features. + +GETTING HELP +------------ + +Within IPython you have various way to access help: + + ? -> Introduction and overview of IPython's features (this screen). + object? -> Details about 'object'. + object?? -> More detailed, verbose information about 'object'. + %quickref -> Quick reference of all IPython specific syntax and magics. + help -> Access Python's own help system. + +If you are in terminal IPython you can quit this screen by pressing `q`. + + +MAIN FEATURES +------------- + +* Access to the standard Python help with object docstrings and the Python + manuals. Simply type 'help' (no quotes) to invoke it. + +* Magic commands: type %magic for information on the magic subsystem. + +* System command aliases, via the %alias command or the configuration file(s). + +* Dynamic object information: + + Typing ?word or word? prints detailed information about an object. Certain + long strings (code, etc.) get snipped in the center for brevity. + + Typing ??word or word?? gives access to the full information without + snipping long strings. Strings that are longer than the screen are printed + through the less pager. + + The ?/?? system gives access to the full source code for any object (if + available), shows function prototypes and other useful information. + + If you just want to see an object's docstring, type '%pdoc object' (without + quotes, and without % if you have automagic on). + +* Tab completion in the local namespace: + + At any time, hitting tab will complete any available python commands or + variable names, and show you a list of the possible completions if there's + no unambiguous one. It will also complete filenames in the current directory. + +* Search previous command history in multiple ways: + + - Start typing, and then use arrow keys up/down or (Ctrl-p/Ctrl-n) to search + through the history items that match what you've typed so far. + + - Hit Ctrl-r: opens a search prompt. Begin typing and the system searches + your history for lines that match what you've typed so far, completing as + much as it can. + + - %hist: search history by index. + +* Persistent command history across sessions. + +* Logging of input with the ability to save and restore a working session. + +* System shell with !. Typing !ls will run 'ls' in the current directory. + +* The reload command does a 'deep' reload of a module: changes made to the + module since you imported will actually be available without having to exit. + +* Verbose and colored exception traceback printouts. See the magic xmode and + xcolor functions for details (just type %magic). + +* Input caching system: + + IPython offers numbered prompts (In/Out) with input and output caching. All + input is saved and can be retrieved as variables (besides the usual arrow + key recall). + + The following GLOBAL variables always exist (so don't overwrite them!): + _i: stores previous input. + _ii: next previous. + _iii: next-next previous. + _ih : a list of all input _ih[n] is the input from line n. + + Additionally, global variables named _i are dynamically created ( + being the prompt counter), such that _i == _ih[] + + For example, what you typed at prompt 14 is available as _i14 and _ih[14]. + + You can create macros which contain multiple input lines from this history, + for later re-execution, with the %macro function. + + The history function %hist allows you to see any part of your input history + by printing a range of the _i variables. Note that inputs which contain + magic functions (%) appear in the history with a prepended comment. This is + because they aren't really valid Python code, so you can't exec them. + +* Output caching system: + + For output that is returned from actions, a system similar to the input + cache exists but using _ instead of _i. Only actions that produce a result + (NOT assignments, for example) are cached. If you are familiar with + Mathematica, IPython's _ variables behave exactly like Mathematica's % + variables. + + The following GLOBAL variables always exist (so don't overwrite them!): + _ (one underscore): previous output. + __ (two underscores): next previous. + ___ (three underscores): next-next previous. + + Global variables named _ are dynamically created ( being the prompt + counter), such that the result of output is always available as _. + + Finally, a global dictionary named _oh exists with entries for all lines + which generated output. + +* Directory history: + + Your history of visited directories is kept in the global list _dh, and the + magic %cd command can be used to go to any entry in that list. + +* Auto-parentheses and auto-quotes (adapted from Nathan Gray's LazyPython) + + 1. Auto-parentheses + + Callable objects (i.e. functions, methods, etc) can be invoked like + this (notice the commas between the arguments):: + + In [1]: callable_ob arg1, arg2, arg3 + + and the input will be translated to this:: + + callable_ob(arg1, arg2, arg3) + + This feature is off by default (in rare cases it can produce + undesirable side-effects), but you can activate it at the command-line + by starting IPython with `--autocall 1`, set it permanently in your + configuration file, or turn on at runtime with `%autocall 1`. + + You can force auto-parentheses by using '/' as the first character + of a line. For example:: + + In [1]: /globals # becomes 'globals()' + + Note that the '/' MUST be the first character on the line! This + won't work:: + + In [2]: print /globals # syntax error + + In most cases the automatic algorithm should work, so you should + rarely need to explicitly invoke /. One notable exception is if you + are trying to call a function with a list of tuples as arguments (the + parenthesis will confuse IPython):: + + In [1]: zip (1,2,3),(4,5,6) # won't work + + but this will work:: + + In [2]: /zip (1,2,3),(4,5,6) + ------> zip ((1,2,3),(4,5,6)) + Out[2]= [(1, 4), (2, 5), (3, 6)] + + IPython tells you that it has altered your command line by + displaying the new command line preceded by -->. e.g.:: + + In [18]: callable list + -------> callable (list) + + 2. Auto-Quoting + + You can force auto-quoting of a function's arguments by using ',' as + the first character of a line. For example:: + + In [1]: ,my_function /home/me # becomes my_function("/home/me") + + If you use ';' instead, the whole argument is quoted as a single + string (while ',' splits on whitespace):: + + In [2]: ,my_function a b c # becomes my_function("a","b","c") + In [3]: ;my_function a b c # becomes my_function("a b c") + + Note that the ',' MUST be the first character on the line! This + won't work:: + + In [4]: x = ,my_function /home/me # syntax error +""" + +interactive_usage_min = """\ +An enhanced console for Python. +Some of its features are: +- Tab completion in the local namespace. +- Logging of input, see command-line options. +- System shell escape via ! , eg !ls. +- Magic commands, starting with a % (like %ls, %pwd, %cd, etc.) +- Keeps track of locally defined variables via %who, %whos. +- Show object information with a ? eg ?x or x? (use ?? for more info). +""" + +quick_reference = r""" +IPython -- An enhanced Interactive Python - Quick Reference Card +================================================================ + +obj?, obj?? : Get help, or more help for object (also works as + ?obj, ??obj). +?foo.*abc* : List names in 'foo' containing 'abc' in them. +%magic : Information about IPython's 'magic' % functions. + +Magic functions are prefixed by % or %%, and typically take their arguments +without parentheses, quotes or even commas for convenience. Line magics take a +single % and cell magics are prefixed with two %%. + +Example magic function calls: + +%alias d ls -F : 'd' is now an alias for 'ls -F' +alias d ls -F : Works if 'alias' not a python name +alist = %alias : Get list of aliases to 'alist' +cd /usr/share : Obvious. cd - to choose from visited dirs. +%cd?? : See help AND source for magic %cd +%timeit x=10 : time the 'x=10' statement with high precision. +%%timeit x=2**100 +x**100 : time 'x**100' with a setup of 'x=2**100'; setup code is not + counted. This is an example of a cell magic. + +System commands: + +!cp a.txt b/ : System command escape, calls os.system() +cp a.txt b/ : after %rehashx, most system commands work without ! +cp ${f}.txt $bar : Variable expansion in magics and system commands +files = !ls /usr : Capture system command output +files.s, files.l, files.n: "a b c", ['a','b','c'], 'a\nb\nc' + +History: + +_i, _ii, _iii : Previous, next previous, next next previous input +_i4, _ih[2:5] : Input history line 4, lines 2-4 +exec _i81 : Execute input history line #81 again +%rep 81 : Edit input history line #81 +_, __, ___ : previous, next previous, next next previous output +_dh : Directory history +_oh : Output history +%hist : Command history of current session. +%hist -g foo : Search command history of (almost) all sessions for 'foo'. +%hist -g : Command history of (almost) all sessions. +%hist 1/2-8 : Command history containing lines 2-8 of session 1. +%hist 1/ ~2/ : Command history of session 1 and 2 sessions before current. +%hist ~8/1-~6/5 : Command history from line 1 of 8 sessions ago to + line 5 of 6 sessions ago. +%edit 0/ : Open editor to execute code with history of current session. + +Autocall: + +f 1,2 : f(1,2) # Off by default, enable with %autocall magic. +/f 1,2 : f(1,2) (forced autoparen) +,f 1 2 : f("1","2") +;f 1 2 : f("1 2") + +Remember: TAB completion works in many contexts, not just file names +or python names. + +The following magic functions are currently available: + +""" + +default_banner_parts = ["Python %s\n"%sys.version.split("\n")[0], + "Type 'copyright', 'credits' or 'license' for more information\n" , + "IPython {version} -- An enhanced Interactive Python. Type '?' for help.\n".format(version=release.version), +] + +default_banner = ''.join(default_banner_parts) diff --git a/.venv/lib/python3.8/site-packages/IPython/display.py b/.venv/lib/python3.8/site-packages/IPython/display.py new file mode 100644 index 00000000..7d248ba0 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/IPython/display.py @@ -0,0 +1,16 @@ +"""Public API for display tools in IPython. +""" + +#----------------------------------------------------------------------------- +# Copyright (C) 2012 The IPython Development Team +# +# Distributed under the terms of the BSD License. The full license is in +# the file COPYING, distributed as part of this software. +#----------------------------------------------------------------------------- + +#----------------------------------------------------------------------------- +# Imports +#----------------------------------------------------------------------------- + +from IPython.core.display import * +from IPython.lib.display import * diff --git a/.venv/lib/python3.8/site-packages/IPython/extensions/__init__.py b/.venv/lib/python3.8/site-packages/IPython/extensions/__init__.py new file mode 100644 index 00000000..db7f79fc --- /dev/null +++ b/.venv/lib/python3.8/site-packages/IPython/extensions/__init__.py @@ -0,0 +1,2 @@ +# -*- coding: utf-8 -*- +"""This directory is meant for IPython extensions.""" diff --git a/.venv/lib/python3.8/site-packages/IPython/extensions/__pycache__/__init__.cpython-38.pyc b/.venv/lib/python3.8/site-packages/IPython/extensions/__pycache__/__init__.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e46b82afee46fef65e53b55cd160ae126ed5af99 GIT binary patch literal 213 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 A;{X5v literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/IPython/extensions/__pycache__/cythonmagic.cpython-38.pyc b/.venv/lib/python3.8/site-packages/IPython/extensions/__pycache__/cythonmagic.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9b593a39433774cf901f4af07dc1b758ff178643 GIT binary patch literal 627 zcmZ9K!EVz)5QcZ{ltz}qfdk@%_L?Y(p%Ur^A=)&DN>Ei$F1a|{-HE-bv$l5Eb(<3h z9t4g&1TVpXgRh);1y0OvLa7*O#^c%F<8Ma$VK7Jt8vXbq`xX)M)4$v|tdZB~_6Y__ z7DQ4Rm2^R6EPJ2GB9hU2GThsIPe!AY`T4u~?C4^CG8!exMFC9Qx}wr-&2uGK!7aN4 z&`fCux#13^Pb)Uts+6-(uEs2B3ndDsEYnrX43xlakg{tqR$;$q(}U;JBoQl?D_1m^ zY`JZ*WR=OeR+c-IjsKMm)YX_ZT7qE?xssJC;qP&J+^ABfr**)1>shDu?K1g=6O%JR z{bOf7kI`r7_8|sGK2u4*P)foc;?2`H6_?>3aN|G+T&3CRd1yY}yzpz;4gB9)*3~tR ziTm(`J4wyO70=;p7L%S0q<2_06@e*G;K1GE645iYT|;)Kd*o;J*MP)kALB6Y_Onb@BFl^~hhm_( Y7arh2*MGULWK+T`FS9)iy+J?z13*}^CIA2c literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/IPython/extensions/__pycache__/rmagic.cpython-38.pyc b/.venv/lib/python3.8/site-packages/IPython/extensions/__pycache__/rmagic.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..45171b899becab79832c469ff2a3e2d922ad335d GIT binary patch literal 435 zcmZutJxc>Y5Z&EGjY6!%Qno!XcaSEHieM#35Y#3h$#Og7mfY%Uk=`Zmg zSX^u6U$Aoa5<&_G<}t&YxAS(M+U+BPL0`XypOldA(Ch}o<{HzTAV?xaO=Ed>XN2TF0}gW!+9{*C(){**;WMM- z)sI-f2tZXeFopYOmaKIhFni_Fw(rE$O3y+)Pe#ENQ zOq5#bv8$S)ifF}@{UGHY+Woyud|?x-Y-g&iNGBjWvkV~b^inzN_9pXW<22dYcgfmr xY!}sOj=vjj{0z4vhv6LIqJ)(Ph!HD8SJ(C49oR>rYF!jYPII^l)3vh2{s5lQai0JH literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/IPython/extensions/__pycache__/storemagic.cpython-38.pyc b/.venv/lib/python3.8/site-packages/IPython/extensions/__pycache__/storemagic.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..28a95367c3e1b0054544e50d4e9cf91988c78e32 GIT binary patch literal 6560 zcmbVQ&5s<%b?@r#>6z)Bnf>5$cS%W9QQ~HIXzo&yzk)SMSauYHwzXCyDx$`ghRvy- z-QMl#9#+?W4SJj)tHgi-!bFgRkFz-h*8kvR{(zi(=&Jz(0({Ly3E=!*b-^D-qXEefS8G;EjWG$xOX3NxX zt7Yl8-Lmnv!cxy^IgDWKu-vP(D!po}+H+g39xH`2y;`e={(^8s`7_q4i;AdzX0#f@ z6*G9xikhh7J?B?{V2Fm8{mc-ve&y6UWvzKJC+0D?Aj}Vp=B2@Zx~qwbrO$ibPSD}q zSn@E~*;PkAwY=}kBuJDWb^J}&{eU17e(1@-dmQ@7E$)SZmte??1Tb`DobVvx_uo5F zyK%IZaN#NMF(9z`LCn1a756+9bi6P;;XtK#)~z_l%00ysq=`L0@mt?!-|y*xBr#JmPv{%XK;LY-&p1r6VPqwCi}UyZnJX@ZB#U4r9B? zGWWy8+wtF#GL}s%bMh5gO*12DcS0{oGB*q&zpaO`!v0h*8;gZ{=r)b~33zSub0_5E<;+Z}QA*0=YMZx>>{?H@xS zk|2(f+nO%T8i*j9E!aG!bD21jTS$Xd*qpUs%1apQFf`+bSXaegv#*a1v2VyyMl3vI zU|4HtDpNDdJYz#^P)ot0E5^|N$cWyu4OQBA<)_S`pK^qmT1&<$(|t>oN0l=}*jJ2G zu=8W%$=pLDCDvC{>khs&gG<|A)~A%@_RYaNA4a6$q;zA=87nvNx!iywK(mZW1hU0J~^v-kazBs1eAv-_Uf%_?Lj zk=OIH%8&dLt&v%&k1bSYC4j8>$DMW%b>pmz9c4R8nk88SrW~CGbXj@tAW_t@;>UYh zs(G_O8_r9=i^J@;$0tc%!*D`#26I@$tTB_-SOfnROJ2w51u+rrHvU>nE9j7zNJKl( zRP;?@-pTdV+HREuOjfn5w%Bc2nm|b+mam}soaJPb(oK<9AM1`@`X(k5ZDdToj{a9j zp*c;;%jhT&qb1IYHwdC{EnT(^66iQu^)xm~Cx4zlwFv?6S>FUe;-E30w-qLDpx2?# z>4(@sPx3u9z5%apkVkJ>zAa2)3HzzJR}v-RJY_BC7e<$fvZ#DkX_fs7JT&=g29I3* z1^C)>Vd(X2X3B33-u>~59kF)Ox%)eJnsBfj&wDaH3?vcUSk|6BDy7C*{^iIwRGCI6GBwF}mlA9gHY?~H;GUAJz?N0oFp@yE z+j1SBt$I$vfzAD1o4c?Z>2Wco2d^4=JYPrWdk(1*yo3!sl4w3=4!sQ#+hVXGXO%c>Qz+`wCT84K zSc|}~VNF#>9vRO_x^Vudjb*T*3WP7BBp+BS55oW*fwGm9iD7)3Rn1AxJH{svEq5qd45xT zGDpByMXHenP8r}%_blhrzGpJMY({^(K8wMUO~#!$P#KiG|rkkBNG z$6X{V;nZzMDGP4NK=RIklzyZp$j=d6>>YaHfuBsk&iCX=-|O+mp2X(ZQ)e}F0pBbz z-^8|9N;J^$`Hf5KCipIHcK$_#0yjmLB1rZp@KgKa8YfhA_6`2N--{3Z3p;6D2o$Am zL`PS~J>1-}M6U2cbb|>OC+IFR@BhR=tjHh2paai~{J)qxia`1u5Ol&RaKw8;R)OU! zuL%V{U&nFfkwhXi7A2iCX-;rVb4p$m)|j@W?{|W308=@a4l%w+mCjjq&akhLbUv^y z{LsHh&I_sO#xcL=ZK`9Hi!N84iL%f%q#pT4I=ST<@p5W|6$VH3MG3t0DP}~nX`=L+K-FJ8|hMgmg z3OW;#iZEH7^br$xyoe5&cwHamhumGPiK(66rcK8ZFQCU@Tvs=ev7em^c^^=cs7(&| z_3B((i15P5ZgI*IX<+pr%0cp^c|s^kKyr{diK3*Eg6Li>{EP{mGY-~1hA4VS?sz{B z@Go$Mn40IDgW6PJdwX#8`(Ct0ZdohiSg~~mo3VjhL`0e~*<`Yg-r!mkYkH?_fFpCw z$z4qb>smXXHxL{OE;NWX#N%9&$=1MJ-58V;zHtvs9@OvP$cJ7Kl929gfAJRf`hv2_ zFWJ3;dGB7vyo?BI|qJ(f3ldSvdt^g1dyByAHuib)cz)iot3<2qOyM7W<(TKnJ8>Kg;M`FL4#eAV`2 zT=!t;b^enG=>K1s##^I8Cw(u3y@&%;@i?Le?HN#JKrLx(CPhty4CML4j=u+Ug-T3h z)@-)weNQHSJMJs05Ft71hk??0RbHuZ??=Kv))9oHY*1dN<_a}b8YMMTNGqOe4ORA-WuV`aAV`!aKN*pnOusH?dCaUYJHY9^Tzl700v zJ4P1RGW|n&n^xYXm2QxXnJB+Q10{W=jXD?3NowH z6S6_;%OH@3p09_L$aneg0wfusF>WoQ5aKY$tQ2*khH2^ycnKq@8ksI;X>Ja`yj?L- zRk9rB>Xmb*4ahkSRWomvuCc55%GWgj;~3_jDpn2kCmO4YVG!u124=SLRN0KMcjdB zpo&jsDQ`#KLQg0BlIoN4Q<|t3MS%`t_;F!CR|hr;M3)Gt20_}R%W4(Vwn6xx9NYYF z$Ei6c(>00?Ilu8keX57($^gkDHAbk2P(CIY6@LfUejIx`Qbp`v)Lmij;~M+scGGO3 z?z)4p2^yqtl|*mz!XnpF2xRSX@qB{t57;;_x0zC)-$c>ulJwA%?@^?P{GkEXRy zBpsU_Xvii?FR|37{M>{lM$+jdmC7_HTU8~!K;c44G`Dk`zfRMyQ*(nF;-aQwN+%~} ln5=Rq7vnwh9toMf-QduGMOL%inaXU%u7K4Ge`kE{e*j4zwnzW~ literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/IPython/extensions/__pycache__/sympyprinting.cpython-38.pyc b/.venv/lib/python3.8/site-packages/IPython/extensions/__pycache__/sympyprinting.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7c0cfe620de3360eb6300660656f1f62fba3c421 GIT binary patch literal 943 zcmZ`&O>Yx15cO_TT3ISbgoK3VNTOte${|wu5b1{ymlDzT(#yuNov!Jwy|TSYmlFqm z2psuC9CGEvAK<`=@g@za5SDD&W6!)dZ^jpUdz9daK7CK0wFvnU4x1y!!)u)GAufVk z5)p|wk1ivzC0d`!Wh~+|(%xpjB0^}Vb9^#-e{wWDKRNDnC>=s+mG&^LH22DA@EP-H zlit_MD+jJF${G%tQyk3XgXG>NlpYjDRJml8&x}2QL#vpEH`Ky?VNm)` zbBTc^$Qv)U3oyz-ZkUjw3upg^2WBN;WK%G&ILq^zE-CdIwo)Me(1Do-=TQw$lR>iI zg@R!!QnLVucRoXuzmOSoP?(t%;LXaf(gMjg`6a>CG8ADZ6IIrjm2SY4zUl(gHTnuQ zMK(bu7h*8ZO%=2=7I+pC4`#Zga5}$s|&aq;RHn%$bPt0-iYTSj&Nf=M9DONqBiqcpQN-Lk< z26=w>_@q5<$BSJ|NTbqj(F(hEw1`#tjo58u_WQW+i?Uy;vRCO6lb515&!o(I11{$K zgX^3A+fh@m{<_$%e}{Nd){6(B-_liO)Ah^8L4fduNMv_#ZEr1h(o`6prZ$)xW5Z)( XxrY~v-51L`y$V`7{F$WnXgB@?WsWA= literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/IPython/extensions/autoreload.py b/.venv/lib/python3.8/site-packages/IPython/extensions/autoreload.py new file mode 100644 index 00000000..ada680fc --- /dev/null +++ b/.venv/lib/python3.8/site-packages/IPython/extensions/autoreload.py @@ -0,0 +1,550 @@ +"""IPython extension to reload modules before executing user code. + +``autoreload`` reloads modules automatically before entering the execution of +code typed at the IPython prompt. + +This makes for example the following workflow possible: + +.. sourcecode:: ipython + + In [1]: %load_ext autoreload + + In [2]: %autoreload 2 + + In [3]: from foo import some_function + + In [4]: some_function() + Out[4]: 42 + + In [5]: # open foo.py in an editor and change some_function to return 43 + + In [6]: some_function() + Out[6]: 43 + +The module was reloaded without reloading it explicitly, and the object +imported with ``from foo import ...`` was also updated. + +Usage +===== + +The following magic commands are provided: + +``%autoreload`` + + Reload all modules (except those excluded by ``%aimport``) + automatically now. + +``%autoreload 0`` + + Disable automatic reloading. + +``%autoreload 1`` + + Reload all modules imported with ``%aimport`` every time before + executing the Python code typed. + +``%autoreload 2`` + + Reload all modules (except those excluded by ``%aimport``) every + time before executing the Python code typed. + +``%aimport`` + + List modules which are to be automatically imported or not to be imported. + +``%aimport foo`` + + Import module 'foo' and mark it to be autoreloaded for ``%autoreload 1`` + +``%aimport foo, bar`` + + Import modules 'foo', 'bar' and mark them to be autoreloaded for ``%autoreload 1`` + +``%aimport -foo`` + + Mark module 'foo' to not be autoreloaded. + +Caveats +======= + +Reloading Python modules in a reliable way is in general difficult, +and unexpected things may occur. ``%autoreload`` tries to work around +common pitfalls by replacing function code objects and parts of +classes previously in the module with new versions. This makes the +following things to work: + +- Functions and classes imported via 'from xxx import foo' are upgraded + to new versions when 'xxx' is reloaded. + +- Methods and properties of classes are upgraded on reload, so that + calling 'c.foo()' on an object 'c' created before the reload causes + the new code for 'foo' to be executed. + +Some of the known remaining caveats are: + +- Replacing code objects does not always succeed: changing a @property + in a class to an ordinary method or a method to a member variable + can cause problems (but in old objects only). + +- Functions that are removed (eg. via monkey-patching) from a module + before it is reloaded are not upgraded. + +- C extension modules cannot be reloaded, and so cannot be autoreloaded. +""" + +skip_doctest = True + +#----------------------------------------------------------------------------- +# Copyright (C) 2000 Thomas Heller +# Copyright (C) 2008 Pauli Virtanen +# Copyright (C) 2012 The IPython Development Team +# +# Distributed under the terms of the BSD License. The full license is in +# the file COPYING, distributed as part of this software. +#----------------------------------------------------------------------------- +# +# This IPython module is written by Pauli Virtanen, based on the autoreload +# code by Thomas Heller. + +#----------------------------------------------------------------------------- +# Imports +#----------------------------------------------------------------------------- + +import os +import sys +import traceback +import types +import weakref +import gc +from importlib import import_module +from importlib.util import source_from_cache +from imp import reload + +#------------------------------------------------------------------------------ +# Autoreload functionality +#------------------------------------------------------------------------------ + +class ModuleReloader(object): + enabled = False + """Whether this reloader is enabled""" + + check_all = True + """Autoreload all modules, not just those listed in 'modules'""" + + def __init__(self): + # Modules that failed to reload: {module: mtime-on-failed-reload, ...} + self.failed = {} + # Modules specially marked as autoreloadable. + self.modules = {} + # Modules specially marked as not autoreloadable. + self.skip_modules = {} + # (module-name, name) -> weakref, for replacing old code objects + self.old_objects = {} + # Module modification timestamps + self.modules_mtimes = {} + + # Cache module modification times + self.check(check_all=True, do_reload=False) + + def mark_module_skipped(self, module_name): + """Skip reloading the named module in the future""" + try: + del self.modules[module_name] + except KeyError: + pass + self.skip_modules[module_name] = True + + def mark_module_reloadable(self, module_name): + """Reload the named module in the future (if it is imported)""" + try: + del self.skip_modules[module_name] + except KeyError: + pass + self.modules[module_name] = True + + def aimport_module(self, module_name): + """Import a module, and mark it reloadable + + Returns + ------- + top_module : module + The imported module if it is top-level, or the top-level + top_name : module + Name of top_module + + """ + self.mark_module_reloadable(module_name) + + import_module(module_name) + top_name = module_name.split('.')[0] + top_module = sys.modules[top_name] + return top_module, top_name + + def filename_and_mtime(self, module): + if not hasattr(module, '__file__') or module.__file__ is None: + return None, None + + if getattr(module, '__name__', None) in [None, '__mp_main__', '__main__']: + # we cannot reload(__main__) or reload(__mp_main__) + return None, None + + filename = module.__file__ + path, ext = os.path.splitext(filename) + + if ext.lower() == '.py': + py_filename = filename + else: + try: + py_filename = source_from_cache(filename) + except ValueError: + return None, None + + try: + pymtime = os.stat(py_filename).st_mtime + except OSError: + return None, None + + return py_filename, pymtime + + def check(self, check_all=False, do_reload=True): + """Check whether some modules need to be reloaded.""" + + if not self.enabled and not check_all: + return + + if check_all or self.check_all: + modules = list(sys.modules.keys()) + else: + modules = list(self.modules.keys()) + + for modname in modules: + m = sys.modules.get(modname, None) + + if modname in self.skip_modules: + continue + + py_filename, pymtime = self.filename_and_mtime(m) + if py_filename is None: + continue + + try: + if pymtime <= self.modules_mtimes[modname]: + continue + except KeyError: + self.modules_mtimes[modname] = pymtime + continue + else: + if self.failed.get(py_filename, None) == pymtime: + continue + + self.modules_mtimes[modname] = pymtime + + # If we've reached this point, we should try to reload the module + if do_reload: + try: + superreload(m, reload, self.old_objects) + if py_filename in self.failed: + del self.failed[py_filename] + except: + print("[autoreload of %s failed: %s]" % ( + modname, traceback.format_exc(10)), file=sys.stderr) + self.failed[py_filename] = pymtime + +#------------------------------------------------------------------------------ +# superreload +#------------------------------------------------------------------------------ + + +func_attrs = ['__code__', '__defaults__', '__doc__', + '__closure__', '__globals__', '__dict__'] + + +def update_function(old, new): + """Upgrade the code object of a function""" + for name in func_attrs: + try: + setattr(old, name, getattr(new, name)) + except (AttributeError, TypeError): + pass + + +def update_instances(old, new): + """Use garbage collector to find all instances that refer to the old + class definition and update their __class__ to point to the new class + definition""" + + refs = gc.get_referrers(old) + + for ref in refs: + if type(ref) is old: + ref.__class__ = new + + +def update_class(old, new): + """Replace stuff in the __dict__ of a class, and upgrade + method code objects, and add new methods, if any""" + for key in list(old.__dict__.keys()): + old_obj = getattr(old, key) + try: + new_obj = getattr(new, key) + # explicitly checking that comparison returns True to handle + # cases where `==` doesn't return a boolean. + if (old_obj == new_obj) is True: + continue + except AttributeError: + # obsolete attribute: remove it + try: + delattr(old, key) + except (AttributeError, TypeError): + pass + continue + + if update_generic(old_obj, new_obj): continue + + try: + setattr(old, key, getattr(new, key)) + except (AttributeError, TypeError): + pass # skip non-writable attributes + + for key in list(new.__dict__.keys()): + if key not in list(old.__dict__.keys()): + try: + setattr(old, key, getattr(new, key)) + except (AttributeError, TypeError): + pass # skip non-writable attributes + + # update all instances of class + update_instances(old, new) + + +def update_property(old, new): + """Replace get/set/del functions of a property""" + update_generic(old.fdel, new.fdel) + update_generic(old.fget, new.fget) + update_generic(old.fset, new.fset) + + +def isinstance2(a, b, typ): + return isinstance(a, typ) and isinstance(b, typ) + + +UPDATE_RULES = [ + (lambda a, b: isinstance2(a, b, type), + update_class), + (lambda a, b: isinstance2(a, b, types.FunctionType), + update_function), + (lambda a, b: isinstance2(a, b, property), + update_property), +] +UPDATE_RULES.extend([(lambda a, b: isinstance2(a, b, types.MethodType), + lambda a, b: update_function(a.__func__, b.__func__)), +]) + + +def update_generic(a, b): + for type_check, update in UPDATE_RULES: + if type_check(a, b): + update(a, b) + return True + return False + + +class StrongRef(object): + def __init__(self, obj): + self.obj = obj + def __call__(self): + return self.obj + + +def superreload(module, reload=reload, old_objects=None): + """Enhanced version of the builtin reload function. + + superreload remembers objects previously in the module, and + + - upgrades the class dictionary of every old class in the module + - upgrades the code object of every old function and method + - clears the module's namespace before reloading + + """ + if old_objects is None: + old_objects = {} + + # collect old objects in the module + for name, obj in list(module.__dict__.items()): + if not hasattr(obj, '__module__') or obj.__module__ != module.__name__: + continue + key = (module.__name__, name) + try: + old_objects.setdefault(key, []).append(weakref.ref(obj)) + except TypeError: + pass + + # reload module + try: + # clear namespace first from old cruft + old_dict = module.__dict__.copy() + old_name = module.__name__ + module.__dict__.clear() + module.__dict__['__name__'] = old_name + module.__dict__['__loader__'] = old_dict['__loader__'] + except (TypeError, AttributeError, KeyError): + pass + + try: + module = reload(module) + except: + # restore module dictionary on failed reload + module.__dict__.update(old_dict) + raise + + # iterate over all objects and update functions & classes + for name, new_obj in list(module.__dict__.items()): + key = (module.__name__, name) + if key not in old_objects: continue + + new_refs = [] + for old_ref in old_objects[key]: + old_obj = old_ref() + if old_obj is None: continue + new_refs.append(old_ref) + update_generic(old_obj, new_obj) + + if new_refs: + old_objects[key] = new_refs + else: + del old_objects[key] + + return module + +#------------------------------------------------------------------------------ +# IPython connectivity +#------------------------------------------------------------------------------ + +from IPython.core.magic import Magics, magics_class, line_magic + +@magics_class +class AutoreloadMagics(Magics): + def __init__(self, *a, **kw): + super(AutoreloadMagics, self).__init__(*a, **kw) + self._reloader = ModuleReloader() + self._reloader.check_all = False + self.loaded_modules = set(sys.modules) + + @line_magic + def autoreload(self, parameter_s=''): + r"""%autoreload => Reload modules automatically + + %autoreload + Reload all modules (except those excluded by %aimport) automatically + now. + + %autoreload 0 + Disable automatic reloading. + + %autoreload 1 + Reload all modules imported with %aimport every time before executing + the Python code typed. + + %autoreload 2 + Reload all modules (except those excluded by %aimport) every time + before executing the Python code typed. + + Reloading Python modules in a reliable way is in general + difficult, and unexpected things may occur. %autoreload tries to + work around common pitfalls by replacing function code objects and + parts of classes previously in the module with new versions. This + makes the following things to work: + + - Functions and classes imported via 'from xxx import foo' are upgraded + to new versions when 'xxx' is reloaded. + + - Methods and properties of classes are upgraded on reload, so that + calling 'c.foo()' on an object 'c' created before the reload causes + the new code for 'foo' to be executed. + + Some of the known remaining caveats are: + + - Replacing code objects does not always succeed: changing a @property + in a class to an ordinary method or a method to a member variable + can cause problems (but in old objects only). + + - Functions that are removed (eg. via monkey-patching) from a module + before it is reloaded are not upgraded. + + - C extension modules cannot be reloaded, and so cannot be + autoreloaded. + + """ + if parameter_s == '': + self._reloader.check(True) + elif parameter_s == '0': + self._reloader.enabled = False + elif parameter_s == '1': + self._reloader.check_all = False + self._reloader.enabled = True + elif parameter_s == '2': + self._reloader.check_all = True + self._reloader.enabled = True + + @line_magic + def aimport(self, parameter_s='', stream=None): + """%aimport => Import modules for automatic reloading. + + %aimport + List modules to automatically import and not to import. + + %aimport foo + Import module 'foo' and mark it to be autoreloaded for %autoreload 1 + + %aimport foo, bar + Import modules 'foo', 'bar' and mark them to be autoreloaded for %autoreload 1 + + %aimport -foo + Mark module 'foo' to not be autoreloaded for %autoreload 1 + """ + modname = parameter_s + if not modname: + to_reload = sorted(self._reloader.modules.keys()) + to_skip = sorted(self._reloader.skip_modules.keys()) + if stream is None: + stream = sys.stdout + if self._reloader.check_all: + stream.write("Modules to reload:\nall-except-skipped\n") + else: + stream.write("Modules to reload:\n%s\n" % ' '.join(to_reload)) + stream.write("\nModules to skip:\n%s\n" % ' '.join(to_skip)) + elif modname.startswith('-'): + modname = modname[1:] + self._reloader.mark_module_skipped(modname) + else: + for _module in ([_.strip() for _ in modname.split(',')]): + top_module, top_name = self._reloader.aimport_module(_module) + + # Inject module to user namespace + self.shell.push({top_name: top_module}) + + def pre_run_cell(self): + if self._reloader.enabled: + try: + self._reloader.check() + except: + pass + + def post_execute_hook(self): + """Cache the modification times of any modules imported in this execution + """ + newly_loaded_modules = set(sys.modules) - self.loaded_modules + for modname in newly_loaded_modules: + _, pymtime = self._reloader.filename_and_mtime(sys.modules[modname]) + if pymtime is not None: + self._reloader.modules_mtimes[modname] = pymtime + + self.loaded_modules.update(newly_loaded_modules) + + +def load_ipython_extension(ip): + """Load the extension in IPython.""" + auto_reload = AutoreloadMagics(ip) + ip.register_magics(auto_reload) + ip.events.register('pre_run_cell', auto_reload.pre_run_cell) + ip.events.register('post_execute', auto_reload.post_execute_hook) diff --git a/.venv/lib/python3.8/site-packages/IPython/extensions/cythonmagic.py b/.venv/lib/python3.8/site-packages/IPython/extensions/cythonmagic.py new file mode 100644 index 00000000..3c88e7c2 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/IPython/extensions/cythonmagic.py @@ -0,0 +1,21 @@ +# -*- coding: utf-8 -*- +""" +**DEPRECATED** + +The cython magic has been integrated into Cython itself, +which is now released in version 0.21. + +cf github `Cython` organisation, `Cython` repo, under the +file `Cython/Build/IpythonMagic.py` +""" +#----------------------------------------------------------------------------- +# Copyright (C) 2010-2011, IPython Development Team. +#----------------------------------------------------------------------------- + +import warnings + +## still load the magic in IPython 3.x, remove completely in future versions. +def load_ipython_extension(ip): + """Load the extension in IPython.""" + + warnings.warn("""The Cython magic has been moved to the Cython package""") diff --git a/.venv/lib/python3.8/site-packages/IPython/extensions/rmagic.py b/.venv/lib/python3.8/site-packages/IPython/extensions/rmagic.py new file mode 100644 index 00000000..ec576397 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/IPython/extensions/rmagic.py @@ -0,0 +1,12 @@ +# -*- coding: utf-8 -*- + +#----------------------------------------------------------------------------- +# Copyright (C) 2012 The IPython Development Team +#----------------------------------------------------------------------------- + +import warnings + +def load_ipython_extension(ip): + """Load the extension in IPython.""" + warnings.warn("The rmagic extension in IPython has moved to " + "`rpy2.ipython`, please see `rpy2` documentation.") diff --git a/.venv/lib/python3.8/site-packages/IPython/extensions/storemagic.py b/.venv/lib/python3.8/site-packages/IPython/extensions/storemagic.py new file mode 100644 index 00000000..51b79ad3 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/IPython/extensions/storemagic.py @@ -0,0 +1,233 @@ +# -*- coding: utf-8 -*- +""" +%store magic for lightweight persistence. + +Stores variables, aliases and macros in IPython's database. + +To automatically restore stored variables at startup, add this to your +:file:`ipython_config.py` file:: + + c.StoreMagics.autorestore = True +""" + +# Copyright (c) IPython Development Team. +# Distributed under the terms of the Modified BSD License. + +import inspect, os, sys, textwrap + +from IPython.core.error import UsageError +from IPython.core.magic import Magics, magics_class, line_magic +from traitlets import Bool + + +def restore_aliases(ip, alias=None): + staliases = ip.db.get('stored_aliases', {}) + if alias is None: + for k,v in staliases.items(): + #print "restore alias",k,v # dbg + #self.alias_table[k] = v + ip.alias_manager.define_alias(k,v) + else: + ip.alias_manager.define_alias(alias, staliases[alias]) + + +def refresh_variables(ip): + db = ip.db + for key in db.keys('autorestore/*'): + # strip autorestore + justkey = os.path.basename(key) + try: + obj = db[key] + except KeyError: + print("Unable to restore variable '%s', ignoring (use %%store -d to forget!)" % justkey) + print("The error was:", sys.exc_info()[0]) + else: + #print "restored",justkey,"=",obj #dbg + ip.user_ns[justkey] = obj + + +def restore_dhist(ip): + ip.user_ns['_dh'] = ip.db.get('dhist',[]) + + +def restore_data(ip): + refresh_variables(ip) + restore_aliases(ip) + restore_dhist(ip) + + +@magics_class +class StoreMagics(Magics): + """Lightweight persistence for python variables. + + Provides the %store magic.""" + + autorestore = Bool(False, help= + """If True, any %store-d variables will be automatically restored + when IPython starts. + """ + ).tag(config=True) + + def __init__(self, shell): + super(StoreMagics, self).__init__(shell=shell) + self.shell.configurables.append(self) + if self.autorestore: + restore_data(self.shell) + + @line_magic + def store(self, parameter_s=''): + """Lightweight persistence for python variables. + + Example:: + + In [1]: l = ['hello',10,'world'] + In [2]: %store l + In [3]: exit + + (IPython session is closed and started again...) + + ville@badger:~$ ipython + In [1]: l + NameError: name 'l' is not defined + In [2]: %store -r + In [3]: l + Out[3]: ['hello', 10, 'world'] + + Usage: + + * ``%store`` - Show list of all variables and their current + values + * ``%store spam bar`` - Store the *current* value of the variables spam + and bar to disk + * ``%store -d spam`` - Remove the variable and its value from storage + * ``%store -z`` - Remove all variables from storage + * ``%store -r`` - Refresh all variables, aliases and directory history + from store (overwrite current vals) + * ``%store -r spam bar`` - Refresh specified variables and aliases from store + (delete current val) + * ``%store foo >a.txt`` - Store value of foo to new file a.txt + * ``%store foo >>a.txt`` - Append value of foo to file a.txt + + It should be noted that if you change the value of a variable, you + need to %store it again if you want to persist the new value. + + Note also that the variables will need to be pickleable; most basic + python types can be safely %store'd. + + Also aliases can be %store'd across sessions. + To remove an alias from the storage, use the %unalias magic. + """ + + opts,argsl = self.parse_options(parameter_s,'drz',mode='string') + args = argsl.split() + ip = self.shell + db = ip.db + # delete + if 'd' in opts: + try: + todel = args[0] + except IndexError: + raise UsageError('You must provide the variable to forget') + else: + try: + del db['autorestore/' + todel] + except: + raise UsageError("Can't delete variable '%s'" % todel) + # reset + elif 'z' in opts: + for k in db.keys('autorestore/*'): + del db[k] + + elif 'r' in opts: + if args: + for arg in args: + try: + obj = db['autorestore/' + arg] + except KeyError: + try: + restore_aliases(ip, alias=arg) + except KeyError: + print("no stored variable or alias %s" % arg) + else: + ip.user_ns[arg] = obj + else: + restore_data(ip) + + # run without arguments -> list variables & values + elif not args: + vars = db.keys('autorestore/*') + vars.sort() + if vars: + size = max(map(len, vars)) + else: + size = 0 + + print('Stored variables and their in-db values:') + fmt = '%-'+str(size)+'s -> %s' + get = db.get + for var in vars: + justkey = os.path.basename(var) + # print 30 first characters from every var + print(fmt % (justkey, repr(get(var, ''))[:50])) + + # default action - store the variable + else: + # %store foo >file.txt or >>file.txt + if len(args) > 1 and args[1].startswith('>'): + fnam = os.path.expanduser(args[1].lstrip('>').lstrip()) + if args[1].startswith('>>'): + fil = open(fnam, 'a') + else: + fil = open(fnam, 'w') + with fil: + obj = ip.ev(args[0]) + print("Writing '%s' (%s) to file '%s'." % (args[0], + obj.__class__.__name__, fnam)) + + if not isinstance (obj, str): + from pprint import pprint + pprint(obj, fil) + else: + fil.write(obj) + if not obj.endswith('\n'): + fil.write('\n') + + return + + # %store foo + for arg in args: + try: + obj = ip.user_ns[arg] + except KeyError: + # it might be an alias + name = arg + try: + cmd = ip.alias_manager.retrieve_alias(name) + except ValueError: + raise UsageError("Unknown variable '%s'" % name) + + staliases = db.get('stored_aliases',{}) + staliases[name] = cmd + db['stored_aliases'] = staliases + print("Alias stored: %s (%s)" % (name, cmd)) + return + + else: + modname = getattr(inspect.getmodule(obj), '__name__', '') + if modname == '__main__': + print(textwrap.dedent("""\ + Warning:%s is %s + Proper storage of interactively declared classes (or instances + of those classes) is not possible! Only instances + of classes in real modules on file system can be %%store'd. + """ % (arg, obj) )) + return + #pickled = pickle.dumps(obj) + db[ 'autorestore/' + arg ] = obj + print("Stored '%s' (%s)" % (arg, obj.__class__.__name__)) + + +def load_ipython_extension(ip): + """Load the extension in IPython.""" + ip.register_magics(StoreMagics) + diff --git a/.venv/lib/python3.8/site-packages/IPython/extensions/sympyprinting.py b/.venv/lib/python3.8/site-packages/IPython/extensions/sympyprinting.py new file mode 100644 index 00000000..e6a83cd3 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/IPython/extensions/sympyprinting.py @@ -0,0 +1,32 @@ +""" +**DEPRECATED** + +A print function that pretty prints sympy Basic objects. + +:moduleauthor: Brian Granger + +Usage +===== + +Once the extension is loaded, Sympy Basic objects are automatically +pretty-printed. + +As of SymPy 0.7.2, maintenance of this extension has moved to SymPy under +sympy.interactive.ipythonprinting, any modifications to account for changes to +SymPy should be submitted to SymPy rather than changed here. This module is +maintained here for backwards compatibility with old SymPy versions. + +""" +#----------------------------------------------------------------------------- +# Copyright (C) 2008 The IPython Development Team +#----------------------------------------------------------------------------- + +#----------------------------------------------------------------------------- +# Imports +#----------------------------------------------------------------------------- + +import warnings + +def load_ipython_extension(ip): + warnings.warn("The sympyprinting extension has moved to `sympy`, " + "use `from sympy import init_printing; init_printing()`") diff --git a/.venv/lib/python3.8/site-packages/IPython/extensions/tests/__init__.py b/.venv/lib/python3.8/site-packages/IPython/extensions/tests/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/.venv/lib/python3.8/site-packages/IPython/extensions/tests/__pycache__/__init__.cpython-38.pyc b/.venv/lib/python3.8/site-packages/IPython/extensions/tests/__pycache__/__init__.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..dd5a56bb61fb03b7dd57d22c0b1379d361d57ee5 GIT binary patch literal 160 zcmWIL<>g`k0>*}G@gVv!h(HF6K#l_t7qb9~6oz01O-8?!3`HPe1o6vNza+OnzaXPO2Tq_|HJh004}dCjtNf literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/IPython/extensions/tests/__pycache__/test_autoreload.cpython-38.pyc b/.venv/lib/python3.8/site-packages/IPython/extensions/tests/__pycache__/test_autoreload.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..56bfd341b0bc2df337a172561e44ffc2a405dc03 GIT binary patch literal 11432 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 D3@t^` literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/IPython/external/__pycache__/mathjax.cpython-38.pyc b/.venv/lib/python3.8/site-packages/IPython/external/__pycache__/mathjax.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..78c846e2d89698b2090e9cc58a0ae89a882554b5 GIT binary patch literal 456 zcma)&!Ait15QdYs+EUn8kl=06wjv9AS;VUcMG!B0$!43;)~0D_Q`+vyN73WHkcVD9 z`3jy)-3lrQ4&;ZQ{4?`0x08vFOyS2DI>QLP4(5B=#+;j19U9?ii8$t#z)K7kw==6e z0Q_Wg=NV(fts6Am+id*R#dW8XLWa<4C?ykN&UEs?+7(GF!aMbf=1NJHJi%91xQmG1RIe-HX rngl=u^O!fM^Q?_V=IHBs(RhP204nfY1n3wHAp(LZeDmidx!&BB2mB>46o}X5$Ysyw zjGfwYrK&-kIq(5eZru3*9QX_z_R5K`z@@yIU8k;ugyo&tdHd%5o8SA*vu4vX;D=uR z89Z+o#$Rf&__Ja003PuQ24eUILBx!ZkMwN%Cd`$n5?j87)Hf@t#tF-6(&Z460NUfhy4+|e_3b{nMJ9L*pU{ogh>`gY#K_ICSa_L zVUM$vGda2Ed90@*8iWELQJRzc^G5x3PFTY?|JL!Klc($QYw;L z67tJ*+T%@pd;31#Xn)q;XlZ-e;NGMo@8AdH4bR)9&*dr(#SnK6f`@xMm?mR94mnfh zDFQ9zNeX7EEQ~1qgO-b zl@_f**}G}dWBn0_lAJO*@U*(F3BJAHSA>jU2y6gOTNfrj0Z(sFkI-H?iX_fLIlyb6 zeUy?3mT5#F7FBS)`(m@?6NMCQA?1YfBH?+ss&aU4vW$Hd?@jg@p=yR)y^FKc$?Dpa zwH4t+c;4U8AjWPB<<0JZc85V}rsd{Nl!hcYk-4W{C<(%h<;`Mqu=m~m&f_Qf(mTt| zyneCn9OR9K#n!^k&cS#izq;@-c>Lt6htIw_=pq$N`K!Qe!Se_n@dpeuXyl>G8^qX$ z_haK+HM8;Be1T@r+(VPUETt7KHD{*Q-`4u(x%t{47HI9tN*{rRLQ)0Ep|lnxHb}Uv zDv7j-Gc&InXXq759)K4YzWrW$slDUnmjy2#X#FOg(n5W1L20xaySZ}|c84?}zFnYl zS}z6d6M4tCvx$J?^Q+lJEge0LH>aPEl0le|2tYUvqftQ?3mb8dr||-C@8O$Vc~EFy z^srS}-ugd-TmNOS1>DHHdm#^FkyrXu=G7=YrJPsce7K@y?!b`O3zB)ldCIv9l2#?J z#974a@a|i2b|QZ@_%ba1`Ep&x*?PvZwNa9(!jLr}9U86O?UK{YyTj+}B^|BAecP7S3>{ZV<;)b@($;#; zu?u>Z)>9xw0P3Es&CnUjh_t0A>$1_e6hvin=irPqUoD_RiP3D8k@jmoGJiL%~jl5=BkbJikOJp ziBmF)sNisE8yv1gz)CRZoFLE;%FPrMf%zFv6MYy3ycCYOI)>Z@R#I#v^2XCqB3Vo| z(sJuKWl5{z+XZ3qOQ7uAg|0?hFCceNOumesikhM8|qDgQwQO@Pyv;JP;LGw<-i#o`SpmYX@A`3SCyvfv4ugW g?rs;S@P(pVaUBNhBUk5o+w!0REX%#&zHg&{0d$U*;s5{u literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/IPython/external/__pycache__/qt_loaders.cpython-38.pyc b/.venv/lib/python3.8/site-packages/IPython/external/__pycache__/qt_loaders.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..2f0ea43561cbc8764277f9adecf7da810621562a GIT binary patch literal 8330 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 q*~T(0QXcIR6EsMr7Ln literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/IPython/external/decorators/__pycache__/_decorators.cpython-38.pyc b/.venv/lib/python3.8/site-packages/IPython/external/decorators/__pycache__/_decorators.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..467cb60cbd68d9cc4a23857115b107e6d0df29e7 GIT binary patch literal 4565 zcmdT|O>Y~=8Qz&CDVkDL*LIzcrtZY4Q?r$*A}x?YHQW?63(EAredUxj*f)UX=Y*}3n8Ia;y@c4Cb1JS)FLtA zAdF?y>Su9~x&KjSL6F6eb-?qdH>FOsAz1AM3;CB*Yr((nMrdw>CFhEg|B> z>Q0&@k?oA+zV4~g>)WLnz0!>K?P{^zYK8I46N*9#v#Z55fwjaaZAjJFXsgYEhWn{p zS2C5tX2DQMdv0AUM|w?I1ZM2Qn`*e09LAzlZQZm@1fsN#jk>kFdv5veuFKFUL43j( zkr_z}8&dEU66u|>{PM>!#NC%+lo`E^G<5@xmGbiOP~P?mUQWGJ*5_0`kDHJ9F-KMS z^3T|Uhzaot0#%tNkPoZH)_yo9!9qU_^w?!B>?6s8@Ic2RNMaQhlUAfA)3A*seT1Sx z=oXfx2xNq6ix8496``eUDS-kqS)7I=O;J@xh*?M*kDMUNU73ZDim4;EhxoMkx}QZZ zLR6s8?}|}UC4QcTh*^->bS5VpjT4jFHK#*I*i_gD$4GhPUR|BrEKCt@WF|;6vICy$ zAWOBH`Sz(aNNbAPb{4KzmwUB{SMS{KO|gd>MAcNzyImBc`;kO}!DW&)3S%t}hZLM|v-_)&C-f*&01jP=-CUwl3NL)(LQzVhDPqeji;9^NBqQas?x(2@>nbc=}nME!i z-6Sp(_-oh93m!TZRWrbVvWP3)_sSlFCt)yLBZmM8<8ef209R%8%^Ko?^xMj$N(i>? z>7w{lAz*hgrn{7!ZPeOY(Nn0i=PW6NP#HmSOpQZ{OengCsOniJy9r|I6uTU{r|tQU zN1a+7^-1B(afmw%)1gbve5*bKGP}D@SZUV+Z~*9HJ3_k^cxT0ddt#%aBeHdp@R<`X|&ac?*V=uIuFx@tUT zPZ+_$Y3-Ds`u)0EQcZxu;@lf05nJPCCh^-ifyb?CPF*hTefT* zq@(o@0(JQQ2m22h9PKH2_vg^~Pu$+* zN2E0DckV<9>crmdI3p?%=kw*KFLsM^F@;lx65^~chNbHD5)s=-YRBFK@0j=bb!cnXCqLUFm>A7k-WBHDIU(d;lFgOb zo+cC^H^%_8?&Rh+;ri@dsLX+e!@vr^a@Lw$B_(5b8e;#ZxMgqIHp`p69@TBH*Y@)o zm2&Qn>>&4{axMhqc)m2yX%CCPB=?#aJliz6aFRpg2k<=cZ`Vs2_>qiO!?%da|uXG1gLMRul z9qWQ4cDja$L)$mk@XLG)L(U$W>-0jd80Y44X(2xR470N=lb5S(^5g&1Pe^IAZo6UL zAa%`>H{`VpM|Hj&+RDDX?l@k)x=8ZcHS;cyR?EruJOr@m%Hdfg&307LO*qR5x{rp$?0qq zLcWa&OPJz)XLa4&!tV>gf^u(fV3-zQv7&f^=pcB$s#OH9F8_f}ap%!R1n*e}xk&V0 zPV-()h5DeS&ru;~2N9K*(w~tu`xnq3kZU2uK5^bk4ru}T6}Lf4i50YoY{g0HChh~- zb^E_$O)rj6A(*`RU$7|RPp?X&p0hDcst7$xrxx>4(W#0}xg&r!(I0!{-2WL*>Q3Id z=wx$cBWC5Yz@?~@=yn|CHXaHtHRD3O?-x7@xXB){r`$0f?if$4Yp78J+|@H&=vEC zOErJajm}9hizeM|sD-=jr3``WBPS_fcPD>3IfPOz!4&u{X} z^~n#bJzsBM37eHR(A(eOoAWTHWA$ZQj9umSmB>OYGLJV5nW;>@sVx JM!of`e*^Gx2^#^-GmFC5A$4)Zs#2#!< zFHw+?wy*mi;E}(=58z>5dEzhdfH-H8owO{Ld~!TFKK}fD=lI3eR>y-ue*S~~-tfFX zadCHquy_K~?t>AYAek5Aub+{bAN#W)4v6=yCjt@PdLoqJ%OGyRx*;N1M>2qQB*=5G z+x!bMc%!agb`Ffu=4r;QEqB)bv#gk;D#56`gTUemOuGX{dNC1R>YpZKLMM#<=9xACtIXf=z|HbOp60zmh%5|Zl68+3t)OS--U=RRF=C>t_DsYK&d5I1G(ygeo&63tr@cSK9HZ@qX!bb!{4 za`P^&{0mTFsSnV~9Zi*WJj;;7qtWr{X!!Nv_f(>+w1P~>;JK;nP#AYJRjRL5=~H?- zmFivyYDhskgDQ$gRSHP8-bAm`ETdI!=OEFPP%AGUmS>Ytr;~IsLw#eKg zx_h)s0o-nldzXH8Da{$M-K{h0!sP`7b0z8o>r$%DSK1+lL>I~d2&^Zyq5#q(4yece zN!+dv8ba+iGJYnrxSiTnL=u2buSX>h@t2K%rj*g!nu+zhn?~Y%bu=>RLcCV*&uPSpquk2W;G|8MPWVxYqt;}$~_f2Z~ zSthB?Ws>rYPT}rVTL6c3+^WUaT3Be8h$q-#Whg+ovMJ=41Jh+Vm06DM&V^vQYQi#@ zNC!JYE3 z8G zJnC*5>~IsIX`*SN`2dZN2JafTFYsZj6!*17c$cZsYKiMZ46EO)rH53T4KQ!PtX^7p zVHzPI@qy+j+-_F?cAMrS2#DXox2d0354P=BeP6Zx5&~9q**Y= 4.7, found %s" % + QtCore.PYQT_VERSION_STR) + + # Alias PyQt-specific functions for PySide compatibility. + QtCore.Signal = QtCore.pyqtSignal + QtCore.Slot = QtCore.pyqtSlot + + # query for the API version (in case version == None) + version = sip.getapi('QString') + api = QT_API_PYQTv1 if version == 1 else QT_API_PYQT + return QtCore, QtGui, QtSvg, api + + +def import_pyqt5(): + """ + Import PyQt5 + + ImportErrors rasied within this function are non-recoverable + """ + + from PyQt5 import QtCore, QtSvg, QtWidgets, QtGui + + # Alias PyQt-specific functions for PySide compatibility. + QtCore.Signal = QtCore.pyqtSignal + QtCore.Slot = QtCore.pyqtSlot + + # Join QtGui and QtWidgets for Qt4 compatibility. + QtGuiCompat = types.ModuleType('QtGuiCompat') + QtGuiCompat.__dict__.update(QtGui.__dict__) + QtGuiCompat.__dict__.update(QtWidgets.__dict__) + + api = QT_API_PYQT5 + return QtCore, QtGuiCompat, QtSvg, api + + +def import_pyside(): + """ + Import PySide + + ImportErrors raised within this function are non-recoverable + """ + from PySide import QtGui, QtCore, QtSvg + return QtCore, QtGui, QtSvg, QT_API_PYSIDE + +def import_pyside2(): + """ + Import PySide2 + + ImportErrors raised within this function are non-recoverable + """ + from PySide2 import QtGui, QtCore, QtSvg, QtWidgets, QtPrintSupport + + # Join QtGui and QtWidgets for Qt4 compatibility. + QtGuiCompat = types.ModuleType('QtGuiCompat') + QtGuiCompat.__dict__.update(QtGui.__dict__) + QtGuiCompat.__dict__.update(QtWidgets.__dict__) + QtGuiCompat.__dict__.update(QtPrintSupport.__dict__) + + return QtCore, QtGuiCompat, QtSvg, QT_API_PYSIDE2 + + +def load_qt(api_options): + """ + Attempt to import Qt, given a preference list + of permissible bindings + + It is safe to call this function multiple times. + + Parameters + ---------- + api_options: List of strings + The order of APIs to try. Valid items are 'pyside', 'pyside2', + 'pyqt', 'pyqt5', 'pyqtv1' and 'pyqtdefault' + + Returns + ------- + + A tuple of QtCore, QtGui, QtSvg, QT_API + The first three are the Qt modules. The last is the + string indicating which module was loaded. + + Raises + ------ + ImportError, if it isn't possible to import any requested + bindings (either because they aren't installed, or because + an incompatible library has already been installed) + """ + loaders = { + QT_API_PYSIDE2: import_pyside2, + QT_API_PYSIDE: import_pyside, + QT_API_PYQT: import_pyqt4, + QT_API_PYQT5: import_pyqt5, + QT_API_PYQTv1: partial(import_pyqt4, version=1), + QT_API_PYQT_DEFAULT: partial(import_pyqt4, version=None) + } + + for api in api_options: + + if api not in loaders: + raise RuntimeError( + "Invalid Qt API %r, valid values are: %s" % + (api, ", ".join(["%r" % k for k in loaders.keys()]))) + + if not can_import(api): + continue + + #cannot safely recover from an ImportError during this + result = loaders[api]() + api = result[-1] # changed if api = QT_API_PYQT_DEFAULT + commit_api(api) + return result + else: + raise ImportError(""" + Could not load requested Qt binding. Please ensure that + PyQt4 >= 4.7, PyQt5, PySide >= 1.0.3 or PySide2 is available, + and only one is imported per session. + + Currently-imported Qt library: %r + PyQt4 available (requires QtCore, QtGui, QtSvg): %s + PyQt5 available (requires QtCore, QtGui, QtSvg, QtWidgets): %s + PySide >= 1.0.3 installed: %s + PySide2 installed: %s + Tried to load: %r + """ % (loaded_api(), + has_binding(QT_API_PYQT), + has_binding(QT_API_PYQT5), + has_binding(QT_API_PYSIDE), + has_binding(QT_API_PYSIDE2), + api_options)) diff --git a/.venv/lib/python3.8/site-packages/IPython/frontend.py b/.venv/lib/python3.8/site-packages/IPython/frontend.py new file mode 100644 index 00000000..9cc3eaff --- /dev/null +++ b/.venv/lib/python3.8/site-packages/IPython/frontend.py @@ -0,0 +1,29 @@ +""" +Shim to maintain backwards compatibility with old frontend imports. + +We have moved all contents of the old `frontend` subpackage into top-level +subpackages (`html`, `qt` and `terminal`), and flattened the notebook into +just `IPython.html`, formerly `IPython.frontend.html.notebook`. + +This will let code that was making `from IPython.frontend...` calls continue +working, though a warning will be printed. +""" + +# Copyright (c) IPython Development Team. +# Distributed under the terms of the Modified BSD License. + +import sys +from warnings import warn + +from IPython.utils.shimmodule import ShimModule, ShimWarning + +warn("The top-level `frontend` package has been deprecated since IPython 1.0. " + "All its subpackages have been moved to the top `IPython` level.", ShimWarning) + +# Unconditionally insert the shim into sys.modules so that further import calls +# trigger the custom attribute access above + +sys.modules['IPython.frontend.html.notebook'] = ShimModule( + src='IPython.frontend.html.notebook', mirror='IPython.html') +sys.modules['IPython.frontend'] = ShimModule( + src='IPython.frontend', mirror='IPython') diff --git a/.venv/lib/python3.8/site-packages/IPython/html.py b/.venv/lib/python3.8/site-packages/IPython/html.py new file mode 100644 index 00000000..050be5c5 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/IPython/html.py @@ -0,0 +1,28 @@ +""" +Shim to maintain backwards compatibility with old IPython.html imports. +""" +# Copyright (c) IPython Development Team. +# Distributed under the terms of the Modified BSD License. + +import sys +from warnings import warn + +from IPython.utils.shimmodule import ShimModule, ShimWarning + +warn("The `IPython.html` package has been deprecated since IPython 4.0. " + "You should import from `notebook` instead. " + "`IPython.html.widgets` has moved to `ipywidgets`.", ShimWarning) + +_widgets = sys.modules['IPython.html.widgets'] = ShimModule( + src='IPython.html.widgets', mirror='ipywidgets') + +_html = ShimModule( + src='IPython.html', mirror='notebook') + +# hook up widgets +_html.widgets = _widgets +sys.modules['IPython.html'] = _html + +if __name__ == '__main__': + from notebook import notebookapp as app + app.launch_new_instance() diff --git a/.venv/lib/python3.8/site-packages/IPython/kernel/__init__.py b/.venv/lib/python3.8/site-packages/IPython/kernel/__init__.py new file mode 100644 index 00000000..70a05ed4 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/IPython/kernel/__init__.py @@ -0,0 +1,35 @@ +""" +Shim to maintain backwards compatibility with old IPython.kernel imports. +""" +# Copyright (c) IPython Development Team. +# Distributed under the terms of the Modified BSD License. + +import sys +from warnings import warn + +from IPython.utils.shimmodule import ShimModule, ShimWarning + +warn("The `IPython.kernel` package has been deprecated since IPython 4.0." + "You should import from ipykernel or jupyter_client instead.", ShimWarning) + + +# zmq subdir is gone +sys.modules['IPython.kernel.zmq.session'] = ShimModule( + src='IPython.kernel.zmq.session', mirror='jupyter_client.session') +sys.modules['IPython.kernel.zmq'] = ShimModule( + src='IPython.kernel.zmq', mirror='ipykernel') + +for pkg in ('comm', 'inprocess'): + src = 'IPython.kernel.%s' % pkg + sys.modules[src] = ShimModule(src=src, mirror='ipykernel.%s' % pkg) + +for pkg in ('ioloop', 'blocking'): + src = 'IPython.kernel.%s' % pkg + sys.modules[src] = ShimModule(src=src, mirror='jupyter_client.%s' % pkg) + +# required for `from IPython.kernel import PKG` +from ipykernel import comm, inprocess +from jupyter_client import ioloop, blocking +# public API +from ipykernel.connect import * +from jupyter_client import * diff --git a/.venv/lib/python3.8/site-packages/IPython/kernel/__main__.py b/.venv/lib/python3.8/site-packages/IPython/kernel/__main__.py new file mode 100644 index 00000000..d1f0cf53 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/IPython/kernel/__main__.py @@ -0,0 +1,3 @@ +if __name__ == '__main__': + from ipykernel import kernelapp as app + app.launch_new_instance() diff --git a/.venv/lib/python3.8/site-packages/IPython/kernel/__pycache__/__init__.cpython-38.pyc b/.venv/lib/python3.8/site-packages/IPython/kernel/__pycache__/__init__.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..bb783c8976df6e376c0f6099b5cdeb54e1d9ef30 GIT binary patch literal 992 zcmZuwO>fgM7><)PO+VLim?lmZ(hfyhIw7PTm=Fgp2!W6`gs_CNEH5fHI^AyB}{yp<PetfVRR0$tKkigU0Zdp9g!OZNh0dq0Qo|c+zzo&s{%BY?)0FBw zO+nVe*0C!&I9TID6Ufdw*R15iCKhThmwhk+TpM`vUfo3vL=Kt`VgS>cEE{@`HxVSJ@; zyz13BO}XM_nkL1fjt^JD9wP{4_W{BvMqPj4hseJS8$R+q|FY{}twD@pwBs)^7@z^{ F{s8W2Az1(b literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/IPython/kernel/__pycache__/__main__.cpython-38.pyc b/.venv/lib/python3.8/site-packages/IPython/kernel/__pycache__/__main__.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..5256ff196fec2f248ed680b4707e15cd5826d2e1 GIT binary patch literal 259 zcmYk0KTE_w5XEP*Imn4u*;?49hzmAXC}L|Pg4m=Pmh3=6cK4S2A*S=AXz3TSNNeR+ zuyW4hzz6e&$NMqN^Ja4bB7FTMEBk97{wtAiC(~buF<5Am?%bkH9QveG2&~@HcR;Y} z3G#Hwh`eb6(YNrB+z&Wxd|Dey#1=m!%j z{(x>Jz@PnG>%m7In^=q?nyO`6Of|DBww0Z(w(X0)f1HPU7xdw_KE87q=Ow%GJ3BhQ MMY-3fVi}&|FEG7CTL1t6 literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/IPython/kernel/__pycache__/adapter.cpython-38.pyc b/.venv/lib/python3.8/site-packages/IPython/kernel/__pycache__/adapter.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..af00b18b7326c325cc3894a04d7c84583d6eb982 GIT binary patch literal 188 zcmWIL<>g`k0>*}G@v1=jF^Gc(44TX@fg%i=jJFuI z{4^P(#Ii~YDoav};*)bSQ}asn5>pZjfZUY~Ma)2DVB(jReo1bDenDn|ZfRaYVsdtB zif(yEYHE(Id2&j*k$HB7zGpyXNk)F2es*e6UTTg$)DXRb%3B;Zx%nxjIjMGxK;u4x GtOfuwY%g^H literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/IPython/kernel/__pycache__/channels.cpython-38.pyc b/.venv/lib/python3.8/site-packages/IPython/kernel/__pycache__/channels.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ed60973a5a2e08bd57c32782ad67b9e49b831b3d GIT binary patch literal 190 zcmWIL<>g`k0>*}G@oGT&F^Gc(44TX@fg%i=jJFuI z{4^P(#Is5ZDoav};*)bSQ}asnk~0$X@=|k(S27ea1J!|vU)K61xdr+KnFYF~c?F5d z*{LbIg`k0>*}G@tQ#TF^Gc(44TX@fg%i=jJFuI z{4^P(q_Rp2Doav};*)bSQ}asnk~0$X@=|k(6O)oxG88cbm4b<1cKRi`1^NY<1-hkq z1&PVosVTbU8L6o`y5`9#g`k0>*}G@hU+2F^Gc(44TX@fg%i=jJFuI z{4^P(M6*f@Doav};*)bSQ}asnAk<2RB4(f}F!9S$za+OnzaXg`k0>*}G@#;YOF^Gc(44TX@fg%i=jJFuI z{4^P(B(h2iDoav};*)bSQ}asnAXH*f@=AsxW}rea@ykZPB)34nAhSTXG_N2rIXg8) zw>%>?HAmMxIi=jlJi9{QGoZ30BR@|+JGCe;HAf$Aj9x+IEe@O9{FKt1R69nXfuBLv F0{{pOF#`Yq literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/IPython/kernel/__pycache__/connect.cpython-38.pyc b/.venv/lib/python3.8/site-packages/IPython/kernel/__pycache__/connect.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7e2b550f998ea48c18c7f1aed2d104ac8e2f8477 GIT binary patch literal 217 zcmWIL<>g`k0>*}G@vcDnF^GcEs9Uh$xO{Ffr+nVC}IZc1QWlk z^hg`k0>*}G@ftw-F^Gc(44TX@fg%i=jJFuI z{4^P(B(q8jDoav};*)bSQ}asnvQvxlQgez6Qj=FQ6fpx;f{9g`k0>*}G@!CN8F^Gc(44TX@fg%i=jJFuI z{4^P(WU@*NDoav};*)bSQ}asnvQvxlQgez6Qj-%43RW@{F#{EYiC+%-CAkIq1(^l9 zrFjL3$=RtXy5$+EsX4ml$tmSV=Ghhco&l958Tono5Hp|@)F{1z%3B;Zx%nxjIjMGx KKtn%+oB;skmNcIL literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/IPython/kernel/__pycache__/launcher.cpython-38.pyc b/.venv/lib/python3.8/site-packages/IPython/kernel/__pycache__/launcher.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..1b0e4f49b492c951743321dd65d0de886d0d3498 GIT binary patch literal 190 zcmWIL<>g`k0>*}G@oGT&F^Gc(44TX@fg%i=jJFuI z{4^P(#Is5ZDoav};*)bSQ}asnauQ4Pk~30^Rx%VZ1J!|vU)K61xdr+KnFYF~c?F5d z*{LbIg`k0>*}G@v1=jF^Gc(44TX@fg%i=jJFuI z{4^P(#Ii~YDoav};*)bSQ}asnauf3s(^HF9G88cbm4S(0R{ABm1^NY<1-hkq1&PVo zsVTbU8L6o`y5`9#g`k0>*}G@ftw-F^Gc(44TX@fg%i=jJFuI z{4^P(B(q8jDoav};*)bSQ}asnauf3s(^HEQlag056fpx;f{9g`k0>*}G@diNpF^Gc(44TX@fg%i=jJFuI z{4^P(6thYTDoav};*)bSQ}asna!YecGP6^Q@=|kh6Y~<&Q;SwI6fpyJfQetO`X#vq z`URNg`k0>*}G@#;YOF^Gc(44TX@fg%i=jJFuI z{4^P(B(h2iDoav};*)bSQ}asnic*V95{rNWD;bKIfeOLIFB|=m+yecA%mUrgyn@8! z?9>$9@{H8f99{F|lyW2U>g`k0>*}G@oGT&F^Gc(44TX@fg%i=jJFuI z{4^P(#Is5ZDoav};*)bSQ}asnN-~O46H`)CRx%VZ1J!|vU)K61xdr+KnFYF~c?F5d z*{LbIg`k0>*}G@q)|@439w^WWWUEH~?|62#`o&h+;@#Okv7l%w>vVVq{2R4rb6~ zsZ!u_ttcrPO2Tq%wiD1 G!Vdrue?Xc5 literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/IPython/lib/__pycache__/backgroundjobs.cpython-38.pyc b/.venv/lib/python3.8/site-packages/IPython/lib/__pycache__/backgroundjobs.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e1823af845d5b90a71066e0b5ced8ab6e3146f7f GIT binary patch literal 16020 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 literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/IPython/lib/__pycache__/clipboard.cpython-38.pyc b/.venv/lib/python3.8/site-packages/IPython/lib/__pycache__/clipboard.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..618ac70de3dfa2ef171cd46271c664f96dc74b02 GIT binary patch literal 2274 zcmah~&yU+g6rQo2IB|ZkEk#8Ll|cxVAZ>zLp^B%JguV;4SjqP#A zV{H>6*e={;-(=~B9X2lf)VH8*0Dn|DawP@u9q7`O8 zH{BYoQu_sR>&&6GmzdV6^TKi)v_YFN+N8!K)M?GGlU*4`p$u6@4!9tG5U?x@lS3lM zjHHn-VKly)ksu1weeMg|b$*9!pJ?3oPI!1)J5=Qg}q6AVMJbL1KnLqwx! z-&uL;$ElnSJ7!Vyyu^>0=M|3U#hm7mYBxRaY3@hmm!FWZ!Iw6Fe$tb1+DpT9J5N$S zm@vA1JZ3D~z7f#lYd0p(dV`&*9P^|Xh5Nnr&eN$d!AV{1%m7ovy1%h~HLiAjM@{+} z%&e)?k515Il)P;ri6@Tu07Kd_k_I)OH-G25G;}F>OmzXRE+S1JPs4ekF&1h5O^N4r+Fv<1z-7MLcZ|hm?sowr_$!Phf$XFI0_(vk)Rl4HxD0K=8PXyQ(n}E58~~uQbIjd*U7{nt!=l2JU)P2i<)?IdJ>YTb%c2?hne_4`3^--Q z*4_TS&vw5YdHo^y84T}hRCNrYfL2&4-)ry+U_2^b*C+ALj^Z6MsZf_)0fQ z8#Qd9{zdq|WH?w{fEhr(s$en~$p(0pa;R5>_ZBoHI#Q|uFg-M(ZBXk6<75fc zCjhe(V~!V~8nmiFCo7BU90M55xd}kBXIIxiS{3vhfF3*|dnFiLJKawqC2VGI?+A9l zL{agxAPm($Gf8q}PHf`J4D zOtfHeQKd}fyJHnNb*uYR$udv7heC-hnDNgnU*OrZ%^bf6v$8fAWHzz&SJh}5O$<4G z2S#4Wq^gw8`yi0wNEH5Bgdf}6Au0a*&Ptc zc{B-SM*M`5Y|QhBl6?lm*QKN7Y(FV|#A(E0P$XZ1l$5da3{*$&V(ICez`%WBj3z~G z6hxYov(NueZ?so9?ds|}CqT=rbee@N%eEj;S@Eti>Pjv(q^6EXg@0Vwlx0%zsoUBh zs;0Mwq)<>2uYu`UYhQ&WIG6v5$TyaOH&NLI2iaR-kZl0V74xfDalcdn2S&vEDoCra zJ&*Fh^TcK7yBC-DTsPo?b+ulVXSlrjki+esb=S&O(E}x)oUi>TFU77rl2Vq!gd=M{ j=#b|qrSD&@UbS20CH<-5w5F3~)__PCjV-fwx!w31Ur<+* literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/IPython/lib/__pycache__/deepreload.cpython-38.pyc b/.venv/lib/python3.8/site-packages/IPython/lib/__pycache__/deepreload.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..57dab7b633f77f955c2e2ee2cb5b28a42d551ea7 GIT binary patch literal 6600 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 GvHlC~F1Bg_ literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/IPython/lib/__pycache__/demo.cpython-38.pyc b/.venv/lib/python3.8/site-packages/IPython/lib/__pycache__/demo.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..5c0bf65a4a17410d51d4c06fbef8b9cfe072a8ee GIT binary patch literal 21628 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 b<=7G7_N>HQb4vg>2F%%cm=$?D|9}23he0(o literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/IPython/lib/__pycache__/display.cpython-38.pyc b/.venv/lib/python3.8/site-packages/IPython/lib/__pycache__/display.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..60599e2ebca8835fff4edb5fcbdbd8d7d7979eef GIT binary patch literal 21941 zcmc(HTW}oLnO=8K&jmvO1WAaLD6QRsMH3@~14^PPnkHybq-b$1L5xUC)~vOI#&i!b z;M{b&hag6S>}JVbX%oxw*4`>9XG7*z;U;lyoO@NWdD(|lo>O_~hrHxTTdB%Zs#2=; zD&O~??w$)kaW`>QfSNOXIoJRG|K~sR-I%2u+iTqW1aSMsewrO=wHOtp%YqP(}82U^pW>DEkTrZroc zm1o)J!PZ=5u63w#2=_TJ?-jf$ujn1{roEYsLgnzc4R6-V-NQS7?rx@X1osEMJnr-U zJno;s{hU|8eZhYM_eXJm$eY6bl-wV~{b8?&`=Z=GiTfko0o)&u_D|t{-kZk#wEq;^ zAIJR@-VE+%{6n~Z+B`s+`Hrg^onGL0jiB3fcO2z6-O%@(TGI^zKPVTAmwMr5 zM+MG#=gmg@?e8o(8_M6Px!sO(gU*uUx$X8&5W3x_U;GpRG)iWa^8-}yOF3NKX#`;q zp|BIHzRwi(`ZN8M&LD6DHGY-Zu3@@3H)wUs0W^3>v(?2 zie|3p3BI+y<=4XK&`tC){wRB?=QTP}?%Gx5w)|-Ny-x3DZ{2^V;rX4Y_)eqccl7n_ zjhbq#dsjNOUdwNXQQ<0P_C}+9E1F8Kg2=v%acf-9=wCj*34VkN->8@%7t1p%8PBTN z-Y<9=FZW~fBcpB-;r9+yvT_Z?-z!vdexB&RXWTU_1zgW~vvNI!>x15$To-YD$U7|8 z2Y}G|dq!m%h&zh!8Sj|)B)(_8r@Z6%KIlE|J%jJLj||(W90EGOq-HTK_jeB%#%1LL zjgH%PTtda^2-tv42Y>Hw`fVrNYy|OR2Up4ud#Vk@ukWx`quuR=PR(yNosM$4qy^6j zJ80!g7YVu4d+l1-=(LxdM(AueP+j>!uNk5PNATg)I_*$(nt`+KH`*Hso%x=0gIeg( zsVh|S+n%%7X*YMA?T)$?um`?tcS3)?)45fOCx6`~dP83Y(!;6rPtVH@T~KPf*Xm*& zO1V2rP7@Tk3M$8P=L+0d)u#fRLfaxb=sYhOlG`?7x(EQX%#qV>-cVM)2VHOq5NifqzA{j zu?cosSzNvR`lZz+XZ6OVH?P0(+Kp1#xr%0-1{kpIxe9!%n`4EZudrBO<4aG)aW=!S zdwzMj6?pA(t5H*(pi>XawN7iUn;Ja0e^gg~YaPUY-T{X;eYc&?yk&bRy>NHTK$hA0|m4LDmP?gJkJ2~~#h^5ULuyG_m>{atmNfxo5^ zrYOtLC;XHG<|Y~6Z9$^~l2QlU$C1eb1h{TZVt$KqRrw$Ew6LNA5R7yaY05FRgeHMI zZXmjY0#t@`dtpcH1C8o*3Ig~c%sIFQvBsg(XtjK=f$3v-$S9CEd%=8%QyT^1=%Q0@ zipeV-6Y2}&sPTcu*w0ynyaD<8UMW^uPRqU1X!Tm){vc=o?`dz!ZEyHxXLJ^V%Cc6I zKoz@)(Xr&L5o~Kts|Q&}CiTN@e*}-GUI5%Y=LKi6(XKT?dWM3)D zMyOmDParCYAO2nH0+T+JvgkmfC>{)T!H*(cv1;OkVpcHk2jA4aJK;{3ZR=@w8V``& zPTRi?aHa4}q|9#X+i&|qT`sw=tu;3%+-Qlwij{5Pw7cox zbt-9TwBnpO^TO%V>6_45LB%p?7Uo~gUp&3^^`*4-^IsooPN7e!3rVr~;`3IFtOU~EW$N2Lzc%F`OiB``dyIA5ZR?-nlqbsA<2b)n^f;u5hU??f4)d9?6Jvy`y z*jLl9$I~Alno~-LW<^M=&3$X`Gs#~{dZsNMH+}!nv(_tHh!y$v_I9~l+oT3ByS-(% z)>=My>xHxHjj&s5m7!-BN{;gt=PG1BHA6Z{-3#Q=%4kp9F9o$tNb*1|g3YkiT&C&o zmpdC93nP%ztxqn~eqRnd%R&|$?c{JYDw&Dl61}rB*%IBK+|&K~$+s`PTYdM^JJl}jHreZ%*iOF*+sXN=J03115pP6a`Ou7te$%J#QEhlN zx}W?r@tMLWi%$lh;HM}CmS@~5C})s~zu|H4K7?a>*ZeheV0#ws&&BW0;dw@$v;LI2 zj`uddJ!@c8&34YS`8~*?v<3x~na~ci1LLl>l^d9Y493fT0=IWyY~`hgpMITrE#QUZSNmsIVL^!BL5c>5AT`R)Yj?WTsL)jj zAwXTKCd8u>$}eB-FQFj~n>{V~aGN4g?1vT66E`2iTjT&y2Cv~Q#x`RAJ0f@z5glOE zM!i8BJym-mQAeBvPC*OUdZJdeY%G@!z;~olevM)~%F6grA<>8GNgyf8!ghmLr}q^V zs#SOgVYRA`^S0Q4sGxOT^P{W~ZZuVGxwrf(*rhZT*@54zOI7s@>Z_+&e2Fb>u0nm8 zms6?imhnJ9Q`M??=+){&+vuL^wMmw~cM41Oo2Oo`dD}0(eCy8gwd*@@ z;@dRumt)th+}%;nqH`CYfI}PBlV-u3GYb|!Ig|fKt)qBWF#EH@73E}YH46uUAc{SgD4)+Cl z`@Q&WVdQPj(?n*0$n5@!xBb*8P3#@9abuHSQQnmmC%W375^7x5AfIX>79i?U0IeKU z(YVVY`T?6+FcB3uda&fGtQZxNCW4=mrB1NT5{pF^&$IX%i&H3i_ylt(466Vj&RRut z-o(f1PirvhVQK_e^2ZPrCBbEUfJ1a%H4W4NScf&;R$|`3IJ~pB?~FxXRz3d0^~Lp~bAAa|*~P^iRR+cH03x8OI&Mkh9g4H>xz^tHRaMfoo!$Xr?{!MGZQ=Fm7Xa;9ymzVevtuiW45lU1~eX9nCH% zfpD{O05zd^yQGlHfo+AjmQ)R*0u+Z>@=>;!(Ps5$(rScy8xf@@M|xv-ozRHLj6 z8d>#jCC{}YViRT1iKeX~fjx&tzlKlXpfEDi;8hFcH49z^se#P+KaCIg*6JUO`8JU_ zH9|M}V>FA}Mre)^Ezp_KGdU*-Jb@% znWV5mrcO35tj4rb$$A9yr(|dK5{mxwm&6bj#)fCaa8)AlUFU@>l;|&B(bn>(pZ^LP zSQj=+vj8*0IZ;;3=qM|(iYSBN0)#k&ERlJ$l2w3zQ~d&li862;q6}h{n)aTm0<|g0 zxeN+a>uxRVs7lTaw5$j_Iw(=fYpfIDk=5?1i@caYhgI}Pn(X<}d_umXeW?}HoJ9P~ zc=osO38-=)S*%&08z|2L-ME_r(x=V-VvO*|vdA7vp!A_c3Vw_tp#=Gc3hhvC-j$#Bc=8| z*cj|bC?W&PqX4SkhYit$LmQc!dlpR| zKEioYjmx6v^`bvEz+1*VAgdRTb-#)#5VaY^z|>#C^+Qv=g|86}b`!UMj8D4iD6`(! zP?zusa_kDe5S`x%)N8m>*LXX16RatsR+vP6M;=n(OBAwF5ZS-&cB6dQk?T>`kS^7G z>}{2W&^}p3&*@!WiE8}@uKoz0fQA)SYr&d^>^lxNn1viXE;7$H`(OJ@AZd&XC>!|^ zdFbF`U%_p6YuR zPr%9IpTmV`!ZJ0nY~#KOkz#B?tliJ>iWVwV9;5^i+y7JX*_@HT3$FMy9}bt zAqgB0gKzN!hoPlp5f_$a36s5-Y_PPdMK*^QmqYxFQZ~wId}7~D)v9h7Dzyv{Ml;C@ z|7nugd5xTJuDgMM_RP|U`g<2^tzsfkPTxl`T2vhmv~M9k;MDrrGYC|} zxQ%jpLsPA>20^JEii~zBq#c_~08P1g_TTUc4x=z20Om|OX4dC9_!c=UanBMYjlqm2 z6F&kow#QlxRiykPf6ID7?ne@ot}G;13u*(^A))AmLQ#m*BbKNXB9zzhirc@|H|HLPq;;hwwLQiqnqo&*ZD*vwDEFGpF&mEg;H7ZuCa7=nlUQbu6AN1U2 z{3c(mdYxLeS|L%pUbWtIHv;jh#Se_8p|rzB4PtDw<0%RsMJrBGlZjYY@AJxIK@=-O zQ*pl0Ozhxu3l_12;gZDP6wou=a1fv1t0)Sl{gw@FXnj66KRsia#iQ}(2)?t0BK{8) za_oBSkLvCfd;(5x&xW>`crd-QUJe`0$YKC%6coqoUlPeCq2WeNXA98R)B8c(Ko(aB z3W56warlAKO7?Q4ZU2u`;dnvUPVXtM#K!{C<$HHw?A@l%_$prNi;1`30=z=G`=M-a z1QYLNX6s^_tSp=!?-@2$XS?2OHiMcPjq6{$u&n1e6rD8+qU4Vz7-31%N6avU#f&P< zT$Bu}G2F(`8^Uroz)GtRZAIZ2Wo3C$PA??N=?Ryzn%6{r2B@b(R?gkRRxAi?NDM*; z&*Gg84v!_Nj@O6@3LpB*SNuv#vI>Laj_vau_CG}<3G!5AE4($01?D@0Wo|m_F z3zF0{v`vqYjIiuo^B5#-8_`C1kMIE@VxLV0kjC5>4YZf>>q1345d4c%;tpc}_n^o{9F>*Z5`}e5F{(N+WhQ z2}iOaGI|mRD`#2|v$N)5a}HJqZ4TSCe%3#nz;&piR$Cm1Vse@;%Md~YQ{SVH@TO?okp3%OQ*5h3e(IB9@nqCURz*x2%4_EbowzPU~{q7 zWRZKP*uYl7lGAFmdq`1W8iq`P$pbR;^Afy0&;320ZOSY>zlp8I(P`?* zz*SpJ-!DqnD=(y-uberX_P=uGbg3M6;3-z)5f@7_RNmqiBsMLQiHRMv8YCeFqp2 z#!C}H5`_?F1GLxU_e-G7t*(zScZ%2h8u#( z974tZdqU>>OK-_(OeFG{q4hY~4Z-OQ7hX%|h5-@h8es}rmS6`khOmPff>f|onAx8l zWGk8CLJNfQZ3wlFNPLQzj_`v$!V6rW){ltK?%7Ep+^-U-GCL^X{*hr4XG-j&2n0** zr-lWAkHj4(aVZ&w8u;gcIeJ;{57FrtAWtWurZRVb<*WCvzl+2Xiak*W5VIS;7UYud zq_;P*<*Z**uST#1v2-}Qr&dJk8`Hqy4b2(2S`WgS+4bN$lll}k4`KX!l^D5fF0T2}T_ zyk|d_qr3R>3#ZSVJALjOOR-;Y?)2#;Cw2qQ@OlWFm6w*l6Y=_17C1(1FZ}!|zLW?) zDgeL;X~jbCBL4#t{4z8eQd`5)DB+VnzL@aeNhs1F;UCk)l4LCJOZ@8B+39}LiKG2u z(jO@Nz#aEBSt1uq0l_sM9$spT zPN@5Y?SedG<|vL^oHENQQwd;rUd7iN7;JH2r2Rg|=de+1Z6Qn=8zQgYeDjUe?_F}X zkT*7J;eF8v{jXebolT@UuADppeu80&Xz$9&>Uz^{-#U5mM1W}CMRAcnvoEZxi#0l- z$sezY*30+=XHe)(5X7+&?H!m$u_u814T~EibW6oiwZ&1*ilds-v0wK;CQ^(lW5TTC zqa>Z?)F}}#d_=?{XAk;3eUv_ikf0OESq#M(%{vj5wng!;;V^0*?Jd$$V3}I2LTA1Xt< zVzwjflQKj9&ULc);)O62352hbY(=zBhK?NeDLdD&6^|U%Amn)vFk~zW;cC{H8x4xp znZ~K)mJ~2bWH#Hx=DScgGH5%B@BXCOlS1dCh=8&N@5I4&&$Fwv}S zOUlrn6^|G4g}r70srnUsg4a=unFaF_YBFIQJi&u)_h=j(mD5co%!6Yv84luE9!J;? z!B8mRsM-;HPcfuldQ#1!J9iZm+0RgzFcah)&`1b*uV+IR+0RZOvuUXh4B7DMoVYclNVUx;N@ky>unDDjd%UZ=Le zI&Su}1>ztz_RY9o#w}9V1-94)u|)u<4@r81T=yy@1~M~nH#Nw2Z{n^fcLyY+bXu@% zyZ;F$NGdj%W19rM5>8x`a3uBE+8U8a5U=r!M6Bm=pSE9H+pAR8)+En%{FT-%cr}bh zjU3pJqGsf+EXG2-Kmu;Wq_ zIBmOUK9BAOd;c^T6Y(~*pOZck-5V3?B2RMC^j*bC$8fcemS=&GJIZu#nDacU1DK}$$)V5$E<400Gsdw27H$qf zG(-Y29>w572(AVi*HQkov-lt{ppV%T;`+#;+r;o~#A<-CxGNCJ2*CSS_P7wF;y7%d z2z20V)P3LxiGULC;WKl2wKSs`&(q13hY~VP<#Ci#OrGp&3u@deh`t;rU+PWdy?~95 zKN@Lq<40p9I{pRkrc#QA9d?5A7t>zm_glQBk*{5s-{IBovG{!!Lpv<>WFFE4`x0In z<;0Ug8b_RQpUV_Kx8>76JcMhScR%Xl)6z`bd`SxR?2n9(%#W;(GIb=qc$s@sNU&ur zIqUv5^nYsjID45lCB~tW0w2qfN>FDn);~I(3oOk;qLhH~e!l481bk`lDb-OVj8Z6# zF&}5xc+Smh)NzcHr_O^8_RhAI3kMpqf$lWg=rhrXpQ)X(nZx@mql*~!Lv&N- z5Vo?4q|dQ_D8t9V#%A>fcv?tgtl@rjCpwc|)6r-3?q3Ymgc@hdJy@R9WDpjo$w#|_ zvx>ZJP~dRkjN4$ok0XV2O=I2h$k$`n7jFco4Ohp`fY46ohkjb{Cnz?MQI8LD<*yj; zpTT~l5yC1TWbYyqRZZ)&VZm9%F_2{~hiI%@IXt(K`zEI~K9~;efsJ<-@~N-4yC1`5 zKgvw|3~K089yWUZ-fs3|q^JzCjCAbgKei-??l(TR26^Ol=lgRXn}dA(wh(7|^Tf$d z_3j|vX3?&YoHRk-IJRRNAJhl*_u?E`o#2tv(x0BCqU?%tB)7JwuJTC*1c);R53(iGP?eFl4 z^NWs(;@s2opHdM~8yiRGo>FSKhz+XVYJ8<2PHrsmrmAWdg&=9KR6NDaEY<*+c6>;yq$^6gi>4#|dd-z(FFO zr&ek|qL{EkejCjeI78-|8rj*;t;{@V74(@Y=4@CZ$RlK~Q|T`}^Uo~D8KVd?H$OrV zGz7$o!9i@h;|A~#UV$@Hh<~+IB&IUgBQ>m=V!R}j?B6TnU~Su2WJtrE^u=m5VTe! zvk3E)W@lv63sO`jVyQ-Uo4>ha2gu`BVxfxF$_ZlA`~@-e6s`72C_lR!!; z9y*Hh+B*x>-)5f^@MG-p+k~IQ=MkOHA!iP!NFf7{n*F0ARHTt7VeS9l;Od`_UBR8r zwitugnBA}A!PsKhKpVaDAQ8UR)tk@;AoahG=lFWauj0Nj;%D(nI6{%{6^UI(iys*% zW`Op`R1OQcV4zsS#9G^%#{Vw9X8c+48^-6wSP6F3%~f~LW%D8>TEGm@{!ykh1n z>b&Ad?kh_!3=f#jswdEq`wT#KB~CF2c3{!nIkkyI;3kuSfwlNl1@r7<*HzqXcmjcQ zeP@H`?Ij+Zwh?QO)y2Y>omyIPZ-55wINGy_JDS+|oY?f_&hkWr=qBt)=^1;^?x-Vx z@a9C-^e21jI8LhlDm^EpP>SxV!&!8lS?1w)DCda1*#Ja0=V_)0P6TjyKSC7v* z@3M30w%cgxU+3X0g7eAmR&`@EmOE-=899FV!78b+EPz_wvja{Ilp!I?Ap<60!-Brc zBR?i}k7x3?4&rP+^%N@N2j~h3w3LGfvbmCMRm#x}Im5*M)E}`}WFh>WI{1pLEj+;O z$(hSsQ|iHktDhRiiUixZh$RwbodamSrQ*eOn7rZpMRGIkUv~( zf&UtZB>0UXlC-!T8-g^%j|_1I7lNKR zgHq68wK5tVIAagdh7*rhoCn-3!b5sy|(hV;%jvHaAEpOZ^8H zT^7TEMRbVNpn6;5pmaT;a1YJeIIfc^+NT8uM4bZbpmaq5L1${QJIhPqmZbk{BrCRDh{k>*aU}~5dOzLHI3mYhu~ijpYXlB~48WD;K_S|XWC+W@X%q)i+|X`>pkiUKSOYPmBaS6c3F zXJfUNvy0@FQ?wzKi`$DsT-VUaE z#b(i@Z=9gin{H0)aUm%8W|}h?zsrlf^sU*P<&2m4G)8m$JwD54FsktPd4--u<*Z6(Dz;9r5oj>49d=aA?{2^cFH!)h^EBr_N9gG(FD!;{VW3 zFshG+e`PCz`zn$vtQ$pp3EPPz^P*la3R(UlVXEsY){o>K>x&>@eP4B%9}iSF3d`lK zt{AYS8>InAHa4qfHq#NRHPVM^aZ3(1#eu?bIv#wC#j&ft@GM$By2woqZt9aq zX!z83#&_n9#Vu}sJAGs+J<9pa5!?o4L2N8BAeJ*loT($^>4}SN<@kSMMJx|06K!Rp&$aAtpv8F;b$L+Z* z-JVcFCR%vy?7C?AW7c*Pk=w7|5ayHHfG#L<@yEtH)83-JXn1pu6NID90QfUW;ViK5`_yNw;TP0zP! zyGo|es+Xmq@&hd-O%SiK6bV3Opc!Uu0T0rSR4PNzWc^GW^zXQyANYz$6h>jK9Yo$9 zQRzbF5C<^D@AdEy3qfyp2ZGPV00#=G+-_+iTs;ch@m0Wpf_VXVBGDXL+}JD0S#BO# zuZ>+pna9?ld1B(Z^}TguE1TPg_A3Ooa&`;HQ`|W*<)^B6TspK*OuV1oEg#yvz^Aa< zIdqO^PLPxLY`LvwUm1TfUz;*ibH^24JTZ}#4J3uqrnakUWu>vxGlyJrYCg?u#M~CL zQ9)B>c=tKs$DV2Q`dtw+9w8YLB!K2|bv~QQV_|dV zPSFe7>+#H?uis!xk~4vsazH+LGA-vQmSv3kR)5ARlbX9)t0x==^e=&N$_mPVz7=EP% zvEM&~)BnJRORN^KJhs_+)&OU;y_;`x{cp_776&4?T$@jp%lF3Gb%nFwe$Q9p2S$?D zwUO5*jC@4|rb2HIE9`~mZ#|>B@WT6$4d0otgw;BciXP_{Zp!yb?LBI=73Zcrz_TxL zC%Gx7)1$JpwsvK68f-H!S!-*ot5p2B(HIG<#X*|X6VyJBQcp+JLzKheBCCZzfbeo# zv-y!Yl1BH}=XT2#j5B*z@GG1BkbU*+^L3po1HaQ%eL*b~J=aV8q&q$;oG!4nD;O(R zVbC|{24;@WgNrUE_nz_a2`0osWWjat&HJKKPYd?$H;v345b5znjB_;^Q^>wgzxP!@#-HFzB^4aHerN3}ssfQr%K z5M>dSMJXIadPr%^ZAYm>1q?Y=41LZz5MHY2RFl_&Jn0UL1O`&eaAtzC)ncZfBLiht zlpvY8$dEIk&6f@aY&-x zl`pZzuSaQZf;*S0&MKbtdr1_I3ewASE96fx&YZog@gPT=Je|JP)0bKze+G4bI#*vc zzd*I1Qh<)qFuI3%N4WztqAofj2s-j0I)W12Px6jrR+qD4tA!%hYRPrXH!C!Y5ox>)@*aPc(`^BumV*Y%_?gVdh{-N5%`LpFc*x(&H2TXOqnzuT0zWLsXt z*_I6Dbv$dy+j2+Vz@2S*N8Xel;jAsUPQ1Ol(Z@TU7oL3d! zh>F69D3ik2Nb_CwQe{@8d0v=K7#@9pVMlrPnc>k%X4Oz*cAkkSP4lS{bW2CEOAW0{L>)>f1kRtG^p3Kkw13I-acARNBmhN>@C1`1 z>t>1=F&j}Ro#Zm1iwiO}9jOerMvr85l~P*RREnAIssqUJ6xwAH?NwXJ*Pwv!|^N$SM?91R2H43N|LJs zPV1Byg#7B-5~tGG9SZ&VzSY(eKyKHV&vaBYRk%;V6> zojiBCuClrjSshhrY7to-Rpdvd;mRA{Hzk}$$LRN`=bfj@{;4QBN9Jz`^E*i9?^Thw zzt``R9;WA2!QW#nH|l0$(2Fd!69iL96g8V9qLnQ*ML&pAJj>J&T6l>{dCKJoiULp< z)mQ`gaTTs7dL>B*m3D}}G3qBe2ABX-5NEE(B0^(AtKXn?7}HpDKwc=cY}H4 zje0HNl4O)B0D|W>kMk6o*%v?69mwPpMP*>KsBk8nf4Qzv30~BsjQ|{bD@8kmNhbY1HaLVP!@9I^8TA#+ zX-{;fP;!wY=5EykamDt5>Bb^&0fcH&a9@xL8%1&&t79UH6|t~pK08$v7!Gw}RQeJdA#OOXMlSm^;S6Q1 zY{V)l=EEdjR?C&1%^(va$X)q^`Wx8q~M)?O!w+f6DJKE&v2OEe9 z8I0TdbJ>{r<86IkHfO$UeC5r8=fTXI`Tz214BkVwUOo7h-aD}60CrOpX97#0A=UMk z+d6l3>Z;nuYRB`oRx;7x!IQnlJeZz$TUFKXUjP2$gtyOV0ej7PGtxsdZ;hw)zb3cm z4cLG0={C;)_xR9Gio+r)9+X)T#bYHOU{9mc2Vcf=`smB?`JvmK9Hznt2aIWGi;fg`0|3bU;pj+nqKaXWAeEE1UMn!zQw^Wb=G_1z4if)Kfb0vo%zrG z>KpI{`cnyrW&jsZKC}TwdbWY<=9@r&J@cM7>FL|8cisucFqpqRs;VJiTv3&)LY-qq z;BeTW!DPhkh&2ySTds8UaWSGH74m#6fbC!Sk#?^WOO8K!RC4 z9B&)%JbF8(tE^SsWq6ve4o`SbM3rqFp$}|pj!&QLH5mo=szRV$?9QbC?ceu8# z#yvfc;Prwb6fqs`KobNpj>Tt9S&wnMQr5(OjW>Q$4@JlNYJe19%sjI%n?rx#zrIRa zhilq;VL!i8T-Ba=p)Lr2>j(R^OpfQ?UbB18NuZ<7@%D(<>&^??!)~Kjy&vg2aI(Ae z1N2r`_<0-KOT0A33gB(wv2M{94ZIRCE;FPgI9Oni18N6!X!}hZkkYSke~lDtO8P6F zt|>{7lJa}>{Wg%nJE+5v=8IN^Y zzDog-D4sY4Y5b((%|p(=nI`ysf!x+N>T#NC#3o&SeYHlg@+*usq=rf)w;OFB0*N#< zek)o>V@)DN8yD?u>&d`HTgl{MC5(kkfC0;d<>IQy!=+3%0Qitj7z-8)M@;@PGV?8U zuHv4)MK`GAt`vv6mvn-~{)sUQp-}#vP=15^d;anA-?jO6uP5`k*Xw>YyyU umc>i~0_OQUa%J~rkM*BK08%wdiL^rhze{#cWX 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 literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/IPython/lib/__pycache__/inputhookgtk3.cpython-38.pyc b/.venv/lib/python3.8/site-packages/IPython/lib/__pycache__/inputhookgtk3.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..aecc7566622db0a8fab6428f33d30ac934179018 GIT binary patch literal 672 zcmY+BJ8#rL5XX1@J}Vc6hJpr*&c&S(6p;`hB1j^O=q@@g1>3A_uXWy>U+k_qOhv&5 zNlLyDgCP?$3lQ|1`t#XlM zihs<@K1ll@zU)=e)N|iI>EJ`iXTiE?DjuwORwRN+|0f`zMQ98r6dSDb3!Y|r>z`>> z?MrZZ070P}e2ah$1B48#y@JozCBoaNx$T7m=#ksO9af ztJ@^o=4`er^1PfKXKeT6c>5{(iyM_ZjdjT~KHMo2PK{G4k+EnP;0=JcO3)5BZjkl*nV7M7hgb9fp@P;Og(OsglVlZVd2U{w} zYjSkCikGW+{hq!#Jv+I&SQ9&5(s(gqjH4JV4LWMx3oeu$4)0V^E$bodNll9IeXT^# zH*^P=Qr2XYiV3XAbi?N&ZyU)~Bl@w!$oQwB{$;O=E+)oS-t($qU75esuOs!0ta~0l Hay&2Jnv6u0MVXD6F9g(6iwAPbdBTP2%P4!Hnn)ejK?A!=FyBhYGg?A@L0tY>O_ zy4{dSNI{4rR}hDUTmA(84GtXU%846X5eMG$BvD!r9@&0=etsXndG9@0T#N_|`qi)f zoh3qk!^6el!r=}~{T(cv#Dr7s~2RH)i73!Obr@%C&Wi~-DhF!fDX3^^i(?m8nnA|n9o*!$c)AP4lo*(d4^434`n z2?XhFDGDzhKkT}7phYfHQ@eVuYhN3l$*vpwnH+K*2SsIY_XU8ePl#&4v%fah%(Pr9 zvvRePWs*(=U!9GG$XC}>KD)g>dA_!}J%{+^TAmHoGK6Ieurzq~%6YwD&GeN>`20Hh zAHqWDHR@5%QEi}Wf0oI&Z@&;R$~Z7>#P|XtrpFM^3Ek>CbuiV>Qe|R)G8kvZdU|0& zd8@exghn-l)_$JJ>UoM-oDHN=)*871#9n6~fITLZd_v?E4o89NaA=1vQH9)pIdvX+2X4K8C|fqx$EPjJ}#){sMT0AU^y{f%*U$&rh}1Lf`d_sJJG z4(L8T3XlhT>vRtx-zZ46_vs<*PZ?_2Cszq%pTnJrr-mjvTHr29Jq>~90dLRp{Dx=g zprKEp?f}$3BGBhhw;+4NxXQkdV?NW(71W zWIl)bWH26&GtDMKl=^?;u>n`f^Yb*P!? zaZ%+QTa~G#;8q)yT{RlBVWEJp4LGNOo+dICJu48m3fbo>nT_Dr!?=Ful=x#~^uzZ! zem)~kHb#G+{Q1jAgY6C5Ji3dupXNn6Y3em-syp^fmQG?fDa*Lk8fu0@Ty4F1M#?8{A)#MacL zJ|=X%eBO8ZjcfOTtFhaV$e{sz5mZ|UUqqu$L_-HoZpU4Q3Jj>a3Ub}$y4COVBJKBU zr_jm=p1J}{9H4{HWU!*tE4aK0OYO-7y0wRA+r+{$PYfciuxRT@n?xA|V{GHJMlMvV mjlen|zB4U&m5cY#fPNho?=^HaM3)0}HfrG-h8-FOVe20wpwx{3 literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/IPython/lib/__pycache__/inputhookqt4.cpython-38.pyc b/.venv/lib/python3.8/site-packages/IPython/lib/__pycache__/inputhookqt4.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..eac3ea63daa1845bc7c291ff9aa7abf1f85b008d GIT binary patch literal 3526 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 literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/IPython/lib/__pycache__/kernel.cpython-38.pyc b/.venv/lib/python3.8/site-packages/IPython/lib/__pycache__/kernel.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..118239f6cb8047193acec34f1d53c84a0aa0d5b6 GIT binary patch literal 446 zcmaJ;u};G<5Vg~UR*^cu7kFR^qDf(B7lc5x0|Tfkt&oaPl*U(T)wQj}CA1Tt0wX`f zkd=vFU_dxDmCC|NKHc4WcYdcE*6S`ZhM(U<4`2rq zELwretA&f2&FulA)(!HURsXKj?e)7C=YwwNo(whPOfyKyL?$GbLO`sUcpzGm86*OD z>bh6*5ol4l>@D?F3V)6GCEfirzoYBbWCL?HE-7UGe=A{PGn5?p%|j9iN;1Yd83RdR z-Mz(W`Ay%$IX>{5yc&j7#$lM(vM3QobDG;ll<##wB@joNNpZV|M!QTc|EhjNN!7^y zbziMO&sCt9YAl3`;u+9JHU;2~c1*M5_UtJrcMHsJK{-e*^V-Q=(glZ8a~+fx$FiLo K-m$E2+xY>l7KRuA literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/IPython/lib/__pycache__/latextools.cpython-38.pyc b/.venv/lib/python3.8/site-packages/IPython/lib/__pycache__/latextools.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..71a85611fe610673504b820753ec38b90d47dd30 GIT binary patch literal 6321 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

rKC!B0R*r%ZNqc)J}frO4}&^C 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%0A|jk2Um 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 B>{I{% literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/IPython/lib/backgroundjobs.py b/.venv/lib/python3.8/site-packages/IPython/lib/backgroundjobs.py new file mode 100644 index 00000000..31997e13 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/IPython/lib/backgroundjobs.py @@ -0,0 +1,491 @@ +# -*- coding: utf-8 -*- +"""Manage background (threaded) jobs conveniently from an interactive shell. + +This module provides a BackgroundJobManager class. This is the main class +meant for public usage, it implements an object which can create and manage +new background jobs. + +It also provides the actual job classes managed by these BackgroundJobManager +objects, see their docstrings below. + + +This system was inspired by discussions with B. Granger and the +BackgroundCommand class described in the book Python Scripting for +Computational Science, by H. P. Langtangen: + +http://folk.uio.no/hpl/scripting + +(although ultimately no code from this text was used, as IPython's system is a +separate implementation). + +An example notebook is provided in our documentation illustrating interactive +use of the system. +""" + +#***************************************************************************** +# Copyright (C) 2005-2006 Fernando Perez +# +# Distributed under the terms of the BSD License. The full license is in +# the file COPYING, distributed as part of this software. +#***************************************************************************** + +# Code begins +import sys +import threading + +from IPython import get_ipython +from IPython.core.ultratb import AutoFormattedTB +from logging import error, debug + + +class BackgroundJobManager(object): + """Class to manage a pool of backgrounded threaded jobs. + + Below, we assume that 'jobs' is a BackgroundJobManager instance. + + Usage summary (see the method docstrings for details): + + jobs.new(...) -> start a new job + + jobs() or jobs.status() -> print status summary of all jobs + + jobs[N] -> returns job number N. + + foo = jobs[N].result -> assign to variable foo the result of job N + + jobs[N].traceback() -> print the traceback of dead job N + + jobs.remove(N) -> remove (finished) job N + + jobs.flush() -> remove all finished jobs + + As a convenience feature, BackgroundJobManager instances provide the + utility result and traceback methods which retrieve the corresponding + information from the jobs list: + + jobs.result(N) <--> jobs[N].result + jobs.traceback(N) <--> jobs[N].traceback() + + While this appears minor, it allows you to use tab completion + interactively on the job manager instance. + """ + + def __init__(self): + # Lists for job management, accessed via a property to ensure they're + # up to date.x + self._running = [] + self._completed = [] + self._dead = [] + # A dict of all jobs, so users can easily access any of them + self.all = {} + # For reporting + self._comp_report = [] + self._dead_report = [] + # Store status codes locally for fast lookups + self._s_created = BackgroundJobBase.stat_created_c + self._s_running = BackgroundJobBase.stat_running_c + self._s_completed = BackgroundJobBase.stat_completed_c + self._s_dead = BackgroundJobBase.stat_dead_c + self._current_job_id = 0 + + @property + def running(self): + self._update_status() + return self._running + + @property + def dead(self): + self._update_status() + return self._dead + + @property + def completed(self): + self._update_status() + return self._completed + + def new(self, func_or_exp, *args, **kwargs): + """Add a new background job and start it in a separate thread. + + There are two types of jobs which can be created: + + 1. Jobs based on expressions which can be passed to an eval() call. + The expression must be given as a string. For example: + + job_manager.new('myfunc(x,y,z=1)'[,glob[,loc]]) + + The given expression is passed to eval(), along with the optional + global/local dicts provided. If no dicts are given, they are + extracted automatically from the caller's frame. + + A Python statement is NOT a valid eval() expression. Basically, you + can only use as an eval() argument something which can go on the right + of an '=' sign and be assigned to a variable. + + For example,"print 'hello'" is not valid, but '2+3' is. + + 2. Jobs given a function object, optionally passing additional + positional arguments: + + job_manager.new(myfunc, x, y) + + The function is called with the given arguments. + + If you need to pass keyword arguments to your function, you must + supply them as a dict named kw: + + job_manager.new(myfunc, x, y, kw=dict(z=1)) + + The reason for this assymmetry is that the new() method needs to + maintain access to its own keywords, and this prevents name collisions + between arguments to new() and arguments to your own functions. + + In both cases, the result is stored in the job.result field of the + background job object. + + You can set `daemon` attribute of the thread by giving the keyword + argument `daemon`. + + Notes and caveats: + + 1. All threads running share the same standard output. Thus, if your + background jobs generate output, it will come out on top of whatever + you are currently writing. For this reason, background jobs are best + used with silent functions which simply return their output. + + 2. Threads also all work within the same global namespace, and this + system does not lock interactive variables. So if you send job to the + background which operates on a mutable object for a long time, and + start modifying that same mutable object interactively (or in another + backgrounded job), all sorts of bizarre behaviour will occur. + + 3. If a background job is spending a lot of time inside a C extension + module which does not release the Python Global Interpreter Lock + (GIL), this will block the IPython prompt. This is simply because the + Python interpreter can only switch between threads at Python + bytecodes. While the execution is inside C code, the interpreter must + simply wait unless the extension module releases the GIL. + + 4. There is no way, due to limitations in the Python threads library, + to kill a thread once it has started.""" + + if callable(func_or_exp): + kw = kwargs.get('kw',{}) + job = BackgroundJobFunc(func_or_exp,*args,**kw) + elif isinstance(func_or_exp, str): + if not args: + frame = sys._getframe(1) + glob, loc = frame.f_globals, frame.f_locals + elif len(args)==1: + glob = loc = args[0] + elif len(args)==2: + glob,loc = args + else: + raise ValueError( + 'Expression jobs take at most 2 args (globals,locals)') + job = BackgroundJobExpr(func_or_exp, glob, loc) + else: + raise TypeError('invalid args for new job') + + if kwargs.get('daemon', False): + job.daemon = True + job.num = self._current_job_id + self._current_job_id += 1 + self.running.append(job) + self.all[job.num] = job + debug('Starting job # %s in a separate thread.' % job.num) + job.start() + return job + + def __getitem__(self, job_key): + num = job_key if isinstance(job_key, int) else job_key.num + return self.all[num] + + def __call__(self): + """An alias to self.status(), + + This allows you to simply call a job manager instance much like the + Unix `jobs` shell command.""" + + return self.status() + + def _update_status(self): + """Update the status of the job lists. + + This method moves finished jobs to one of two lists: + - self.completed: jobs which completed successfully + - self.dead: jobs which finished but died. + + It also copies those jobs to corresponding _report lists. These lists + are used to report jobs completed/dead since the last update, and are + then cleared by the reporting function after each call.""" + + # Status codes + srun, scomp, sdead = self._s_running, self._s_completed, self._s_dead + # State lists, use the actual lists b/c the public names are properties + # that call this very function on access + running, completed, dead = self._running, self._completed, self._dead + + # Now, update all state lists + for num, job in enumerate(running): + stat = job.stat_code + if stat == srun: + continue + elif stat == scomp: + completed.append(job) + self._comp_report.append(job) + running[num] = False + elif stat == sdead: + dead.append(job) + self._dead_report.append(job) + running[num] = False + # Remove dead/completed jobs from running list + running[:] = filter(None, running) + + def _group_report(self,group,name): + """Report summary for a given job group. + + Return True if the group had any elements.""" + + if group: + print('%s jobs:' % name) + for job in group: + print('%s : %s' % (job.num,job)) + print() + return True + + def _group_flush(self,group,name): + """Flush a given job group + + Return True if the group had any elements.""" + + njobs = len(group) + if njobs: + plural = {1:''}.setdefault(njobs,'s') + print('Flushing %s %s job%s.' % (njobs,name,plural)) + group[:] = [] + return True + + def _status_new(self): + """Print the status of newly finished jobs. + + Return True if any new jobs are reported. + + This call resets its own state every time, so it only reports jobs + which have finished since the last time it was called.""" + + self._update_status() + new_comp = self._group_report(self._comp_report, 'Completed') + new_dead = self._group_report(self._dead_report, + 'Dead, call jobs.traceback() for details') + self._comp_report[:] = [] + self._dead_report[:] = [] + return new_comp or new_dead + + def status(self,verbose=0): + """Print a status of all jobs currently being managed.""" + + self._update_status() + self._group_report(self.running,'Running') + self._group_report(self.completed,'Completed') + self._group_report(self.dead,'Dead') + # Also flush the report queues + self._comp_report[:] = [] + self._dead_report[:] = [] + + def remove(self,num): + """Remove a finished (completed or dead) job.""" + + try: + job = self.all[num] + except KeyError: + error('Job #%s not found' % num) + else: + stat_code = job.stat_code + if stat_code == self._s_running: + error('Job #%s is still running, it can not be removed.' % num) + return + elif stat_code == self._s_completed: + self.completed.remove(job) + elif stat_code == self._s_dead: + self.dead.remove(job) + + def flush(self): + """Flush all finished jobs (completed and dead) from lists. + + Running jobs are never flushed. + + It first calls _status_new(), to update info. If any jobs have + completed since the last _status_new() call, the flush operation + aborts.""" + + # Remove the finished jobs from the master dict + alljobs = self.all + for job in self.completed+self.dead: + del(alljobs[job.num]) + + # Now flush these lists completely + fl_comp = self._group_flush(self.completed, 'Completed') + fl_dead = self._group_flush(self.dead, 'Dead') + if not (fl_comp or fl_dead): + print('No jobs to flush.') + + def result(self,num): + """result(N) -> return the result of job N.""" + try: + return self.all[num].result + except KeyError: + error('Job #%s not found' % num) + + def _traceback(self, job): + num = job if isinstance(job, int) else job.num + try: + self.all[num].traceback() + except KeyError: + error('Job #%s not found' % num) + + def traceback(self, job=None): + if job is None: + self._update_status() + for deadjob in self.dead: + print("Traceback for: %r" % deadjob) + self._traceback(deadjob) + print() + else: + self._traceback(job) + + +class BackgroundJobBase(threading.Thread): + """Base class to build BackgroundJob classes. + + The derived classes must implement: + + - Their own __init__, since the one here raises NotImplementedError. The + derived constructor must call self._init() at the end, to provide common + initialization. + + - A strform attribute used in calls to __str__. + + - A call() method, which will make the actual execution call and must + return a value to be held in the 'result' field of the job object. + """ + + # Class constants for status, in string and as numerical codes (when + # updating jobs lists, we don't want to do string comparisons). This will + # be done at every user prompt, so it has to be as fast as possible + stat_created = 'Created'; stat_created_c = 0 + stat_running = 'Running'; stat_running_c = 1 + stat_completed = 'Completed'; stat_completed_c = 2 + stat_dead = 'Dead (Exception), call jobs.traceback() for details' + stat_dead_c = -1 + + def __init__(self): + """Must be implemented in subclasses. + + Subclasses must call :meth:`_init` for standard initialisation. + """ + raise NotImplementedError("This class can not be instantiated directly.") + + def _init(self): + """Common initialization for all BackgroundJob objects""" + + for attr in ['call','strform']: + assert hasattr(self,attr), "Missing attribute <%s>" % attr + + # The num tag can be set by an external job manager + self.num = None + + self.status = BackgroundJobBase.stat_created + self.stat_code = BackgroundJobBase.stat_created_c + self.finished = False + self.result = '' + + # reuse the ipython traceback handler if we can get to it, otherwise + # make a new one + try: + make_tb = get_ipython().InteractiveTB.text + except: + make_tb = AutoFormattedTB(mode = 'Context', + color_scheme='NoColor', + tb_offset = 1).text + # Note that the actual API for text() requires the three args to be + # passed in, so we wrap it in a simple lambda. + self._make_tb = lambda : make_tb(None, None, None) + + # Hold a formatted traceback if one is generated. + self._tb = None + + threading.Thread.__init__(self) + + def __str__(self): + return self.strform + + def __repr__(self): + return '' % (self.num, self.strform) + + def traceback(self): + print(self._tb) + + def run(self): + try: + self.status = BackgroundJobBase.stat_running + self.stat_code = BackgroundJobBase.stat_running_c + self.result = self.call() + except: + self.status = BackgroundJobBase.stat_dead + self.stat_code = BackgroundJobBase.stat_dead_c + self.finished = None + self.result = ('') + self._tb = self._make_tb() + else: + self.status = BackgroundJobBase.stat_completed + self.stat_code = BackgroundJobBase.stat_completed_c + self.finished = True + + +class BackgroundJobExpr(BackgroundJobBase): + """Evaluate an expression as a background job (uses a separate thread).""" + + def __init__(self, expression, glob=None, loc=None): + """Create a new job from a string which can be fed to eval(). + + global/locals dicts can be provided, which will be passed to the eval + call.""" + + # fail immediately if the given expression can't be compiled + self.code = compile(expression,'','eval') + + glob = {} if glob is None else glob + loc = {} if loc is None else loc + self.expression = self.strform = expression + self.glob = glob + self.loc = loc + self._init() + + def call(self): + return eval(self.code,self.glob,self.loc) + + +class BackgroundJobFunc(BackgroundJobBase): + """Run a function call as a background job (uses a separate thread).""" + + def __init__(self, func, *args, **kwargs): + """Create a new job from a callable object. + + Any positional arguments and keyword args given to this constructor + after the initial callable are passed directly to it.""" + + if not callable(func): + raise TypeError( + 'first argument to BackgroundJobFunc must be callable') + + self.func = func + self.args = args + self.kwargs = kwargs + # The string form will only include the function passed, because + # generating string representations of the arguments is a potentially + # _very_ expensive operation (e.g. with large arrays). + self.strform = str(func) + self._init() + + def call(self): + return self.func(*self.args, **self.kwargs) diff --git a/.venv/lib/python3.8/site-packages/IPython/lib/clipboard.py b/.venv/lib/python3.8/site-packages/IPython/lib/clipboard.py new file mode 100644 index 00000000..316a8ab1 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/IPython/lib/clipboard.py @@ -0,0 +1,69 @@ +""" Utilities for accessing the platform's clipboard. +""" + +import subprocess + +from IPython.core.error import TryNext +import IPython.utils.py3compat as py3compat + +class ClipboardEmpty(ValueError): + pass + +def win32_clipboard_get(): + """ Get the current clipboard's text on Windows. + + Requires Mark Hammond's pywin32 extensions. + """ + try: + import win32clipboard + except ImportError: + raise TryNext("Getting text from the clipboard requires the pywin32 " + "extensions: http://sourceforge.net/projects/pywin32/") + win32clipboard.OpenClipboard() + try: + text = win32clipboard.GetClipboardData(win32clipboard.CF_UNICODETEXT) + except (TypeError, win32clipboard.error): + try: + text = win32clipboard.GetClipboardData(win32clipboard.CF_TEXT) + text = py3compat.cast_unicode(text, py3compat.DEFAULT_ENCODING) + except (TypeError, win32clipboard.error): + raise ClipboardEmpty + finally: + win32clipboard.CloseClipboard() + return text + +def osx_clipboard_get() -> str: + """ Get the clipboard's text on OS X. + """ + p = subprocess.Popen(['pbpaste', '-Prefer', 'ascii'], + stdout=subprocess.PIPE) + bytes_, stderr = p.communicate() + # Text comes in with old Mac \r line endings. Change them to \n. + bytes_ = bytes_.replace(b'\r', b'\n') + text = py3compat.decode(bytes_) + return text + +def tkinter_clipboard_get(): + """ Get the clipboard's text using Tkinter. + + This is the default on systems that are not Windows or OS X. It may + interfere with other UI toolkits and should be replaced with an + implementation that uses that toolkit. + """ + try: + from tkinter import Tk, TclError + except ImportError: + raise TryNext("Getting text from the clipboard on this platform requires tkinter.") + + root = Tk() + root.withdraw() + try: + text = root.clipboard_get() + except TclError: + raise ClipboardEmpty + finally: + root.destroy() + text = py3compat.cast_unicode(text, py3compat.DEFAULT_ENCODING) + return text + + diff --git a/.venv/lib/python3.8/site-packages/IPython/lib/deepreload.py b/.venv/lib/python3.8/site-packages/IPython/lib/deepreload.py new file mode 100644 index 00000000..bd8c01b2 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/IPython/lib/deepreload.py @@ -0,0 +1,341 @@ +# -*- coding: utf-8 -*- +""" +Provides a reload() function that acts recursively. + +Python's normal :func:`python:reload` function only reloads the module that it's +passed. The :func:`reload` function in this module also reloads everything +imported from that module, which is useful when you're changing files deep +inside a package. + +To use this as your default reload function, type this:: + + import builtins + from IPython.lib import deepreload + builtins.reload = deepreload.reload + +A reference to the original :func:`python:reload` is stored in this module as +:data:`original_reload`, so you can restore it later. + +This code is almost entirely based on knee.py, which is a Python +re-implementation of hierarchical module import. +""" +#***************************************************************************** +# Copyright (C) 2001 Nathaniel Gray +# +# Distributed under the terms of the BSD License. The full license is in +# the file COPYING, distributed as part of this software. +#***************************************************************************** + +import builtins as builtin_mod +from contextlib import contextmanager +import imp +import sys + +from types import ModuleType +from warnings import warn +import types + +original_import = builtin_mod.__import__ + +@contextmanager +def replace_import_hook(new_import): + saved_import = builtin_mod.__import__ + builtin_mod.__import__ = new_import + try: + yield + finally: + builtin_mod.__import__ = saved_import + +def get_parent(globals, level): + """ + parent, name = get_parent(globals, level) + + Return the package that an import is being performed in. If globals comes + from the module foo.bar.bat (not itself a package), this returns the + sys.modules entry for foo.bar. If globals is from a package's __init__.py, + the package's entry in sys.modules is returned. + + If globals doesn't come from a package or a module in a package, or a + corresponding entry is not found in sys.modules, None is returned. + """ + orig_level = level + + if not level or not isinstance(globals, dict): + return None, '' + + pkgname = globals.get('__package__', None) + + if pkgname is not None: + # __package__ is set, so use it + if not hasattr(pkgname, 'rindex'): + raise ValueError('__package__ set to non-string') + if len(pkgname) == 0: + if level > 0: + raise ValueError('Attempted relative import in non-package') + return None, '' + name = pkgname + else: + # __package__ not set, so figure it out and set it + if '__name__' not in globals: + return None, '' + modname = globals['__name__'] + + if '__path__' in globals: + # __path__ is set, so modname is already the package name + globals['__package__'] = name = modname + else: + # Normal module, so work out the package name if any + lastdot = modname.rfind('.') + if lastdot < 0 < level: + raise ValueError("Attempted relative import in non-package") + if lastdot < 0: + globals['__package__'] = None + return None, '' + globals['__package__'] = name = modname[:lastdot] + + dot = len(name) + for x in range(level, 1, -1): + try: + dot = name.rindex('.', 0, dot) + except ValueError: + raise ValueError("attempted relative import beyond top-level " + "package") + name = name[:dot] + + try: + parent = sys.modules[name] + except: + if orig_level < 1: + warn("Parent module '%.200s' not found while handling absolute " + "import" % name) + parent = None + else: + raise SystemError("Parent module '%.200s' not loaded, cannot " + "perform relative import" % name) + + # We expect, but can't guarantee, if parent != None, that: + # - parent.__name__ == name + # - parent.__dict__ is globals + # If this is violated... Who cares? + return parent, name + +def load_next(mod, altmod, name, buf): + """ + mod, name, buf = load_next(mod, altmod, name, buf) + + altmod is either None or same as mod + """ + + if len(name) == 0: + # completely empty module name should only happen in + # 'from . import' (or '__import__("")') + return mod, None, buf + + dot = name.find('.') + if dot == 0: + raise ValueError('Empty module name') + + if dot < 0: + subname = name + next = None + else: + subname = name[:dot] + next = name[dot+1:] + + if buf != '': + buf += '.' + buf += subname + + result = import_submodule(mod, subname, buf) + if result is None and mod != altmod: + result = import_submodule(altmod, subname, subname) + if result is not None: + buf = subname + + if result is None: + raise ImportError("No module named %.200s" % name) + + return result, next, buf + + +# Need to keep track of what we've already reloaded to prevent cyclic evil +found_now = {} + +def import_submodule(mod, subname, fullname): + """m = import_submodule(mod, subname, fullname)""" + # Require: + # if mod == None: subname == fullname + # else: mod.__name__ + "." + subname == fullname + + global found_now + if fullname in found_now and fullname in sys.modules: + m = sys.modules[fullname] + else: + print('Reloading', fullname) + found_now[fullname] = 1 + oldm = sys.modules.get(fullname, None) + + if mod is None: + path = None + elif hasattr(mod, '__path__'): + path = mod.__path__ + else: + return None + + try: + # This appears to be necessary on Python 3, because imp.find_module() + # tries to import standard libraries (like io) itself, and we don't + # want them to be processed by our deep_import_hook. + with replace_import_hook(original_import): + fp, filename, stuff = imp.find_module(subname, path) + except ImportError: + return None + + try: + m = imp.load_module(fullname, fp, filename, stuff) + except: + # load_module probably removed name from modules because of + # the error. Put back the original module object. + if oldm: + sys.modules[fullname] = oldm + raise + finally: + if fp: fp.close() + + add_submodule(mod, m, fullname, subname) + + return m + +def add_submodule(mod, submod, fullname, subname): + """mod.{subname} = submod""" + if mod is None: + return #Nothing to do here. + + if submod is None: + submod = sys.modules[fullname] + + setattr(mod, subname, submod) + + return + +def ensure_fromlist(mod, fromlist, buf, recursive): + """Handle 'from module import a, b, c' imports.""" + if not hasattr(mod, '__path__'): + return + for item in fromlist: + if not hasattr(item, 'rindex'): + raise TypeError("Item in ``from list'' not a string") + if item == '*': + if recursive: + continue # avoid endless recursion + try: + all = mod.__all__ + except AttributeError: + pass + else: + ret = ensure_fromlist(mod, all, buf, 1) + if not ret: + return 0 + elif not hasattr(mod, item): + import_submodule(mod, item, buf + '.' + item) + +def deep_import_hook(name, globals=None, locals=None, fromlist=None, level=-1): + """Replacement for __import__()""" + parent, buf = get_parent(globals, level) + + head, name, buf = load_next(parent, None if level < 0 else parent, name, buf) + + tail = head + while name: + tail, name, buf = load_next(tail, tail, name, buf) + + # If tail is None, both get_parent and load_next found + # an empty module name: someone called __import__("") or + # doctored faulty bytecode + if tail is None: + raise ValueError('Empty module name') + + if not fromlist: + return head + + ensure_fromlist(tail, fromlist, buf, 0) + return tail + +modules_reloading = {} + +def deep_reload_hook(m): + """Replacement for reload().""" + # Hardcode this one as it would raise a NotImplementedError from the + # bowels of Python and screw up the import machinery after. + # unlike other imports the `exclude` list already in place is not enough. + + if m is types: + return m + if not isinstance(m, ModuleType): + raise TypeError("reload() argument must be module") + + name = m.__name__ + + if name not in sys.modules: + raise ImportError("reload(): module %.200s not in sys.modules" % name) + + global modules_reloading + try: + return modules_reloading[name] + except: + modules_reloading[name] = m + + dot = name.rfind('.') + if dot < 0: + subname = name + path = None + else: + try: + parent = sys.modules[name[:dot]] + except KeyError: + modules_reloading.clear() + raise ImportError("reload(): parent %.200s not in sys.modules" % name[:dot]) + subname = name[dot+1:] + path = getattr(parent, "__path__", None) + + try: + # This appears to be necessary on Python 3, because imp.find_module() + # tries to import standard libraries (like io) itself, and we don't + # want them to be processed by our deep_import_hook. + with replace_import_hook(original_import): + fp, filename, stuff = imp.find_module(subname, path) + finally: + modules_reloading.clear() + + try: + newm = imp.load_module(name, fp, filename, stuff) + except: + # load_module probably removed name from modules because of + # the error. Put back the original module object. + sys.modules[name] = m + raise + finally: + if fp: fp.close() + + modules_reloading.clear() + return newm + +# Save the original hooks +original_reload = imp.reload + +# Replacement for reload() +def reload(module, exclude=('sys', 'os.path', 'builtins', '__main__', + 'numpy', 'numpy._globals')): + """Recursively reload all modules used in the given module. Optionally + takes a list of modules to exclude from reloading. The default exclude + list contains sys, __main__, and __builtin__, to prevent, e.g., resetting + display, exception, and io hooks. + """ + global found_now + for i in exclude: + found_now[i] = 1 + try: + with replace_import_hook(deep_import_hook): + return deep_reload_hook(module) + finally: + found_now = {} diff --git a/.venv/lib/python3.8/site-packages/IPython/lib/demo.py b/.venv/lib/python3.8/site-packages/IPython/lib/demo.py new file mode 100644 index 00000000..0b19c413 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/IPython/lib/demo.py @@ -0,0 +1,671 @@ +"""Module for interactive demos using IPython. + +This module implements a few classes for running Python scripts interactively +in IPython for demonstrations. With very simple markup (a few tags in +comments), you can control points where the script stops executing and returns +control to IPython. + + +Provided classes +---------------- + +The classes are (see their docstrings for further details): + + - Demo: pure python demos + + - IPythonDemo: demos with input to be processed by IPython as if it had been + typed interactively (so magics work, as well as any other special syntax you + may have added via input prefilters). + + - LineDemo: single-line version of the Demo class. These demos are executed + one line at a time, and require no markup. + + - IPythonLineDemo: IPython version of the LineDemo class (the demo is + executed a line at a time, but processed via IPython). + + - ClearMixin: mixin to make Demo classes with less visual clutter. It + declares an empty marquee and a pre_cmd that clears the screen before each + block (see Subclassing below). + + - ClearDemo, ClearIPDemo: mixin-enabled versions of the Demo and IPythonDemo + classes. + +Inheritance diagram: + +.. inheritance-diagram:: IPython.lib.demo + :parts: 3 + +Subclassing +----------- + +The classes here all include a few methods meant to make customization by +subclassing more convenient. Their docstrings below have some more details: + + - highlight(): format every block and optionally highlight comments and + docstring content. + + - marquee(): generates a marquee to provide visible on-screen markers at each + block start and end. + + - pre_cmd(): run right before the execution of each block. + + - post_cmd(): run right after the execution of each block. If the block + raises an exception, this is NOT called. + + +Operation +--------- + +The file is run in its own empty namespace (though you can pass it a string of +arguments as if in a command line environment, and it will see those as +sys.argv). But at each stop, the global IPython namespace is updated with the +current internal demo namespace, so you can work interactively with the data +accumulated so far. + +By default, each block of code is printed (with syntax highlighting) before +executing it and you have to confirm execution. This is intended to show the +code to an audience first so you can discuss it, and only proceed with +execution once you agree. There are a few tags which allow you to modify this +behavior. + +The supported tags are: + +# stop + + Defines block boundaries, the points where IPython stops execution of the + file and returns to the interactive prompt. + + You can optionally mark the stop tag with extra dashes before and after the + word 'stop', to help visually distinguish the blocks in a text editor: + + # --- stop --- + + +# silent + + Make a block execute silently (and hence automatically). Typically used in + cases where you have some boilerplate or initialization code which you need + executed but do not want to be seen in the demo. + +# auto + + Make a block execute automatically, but still being printed. Useful for + simple code which does not warrant discussion, since it avoids the extra + manual confirmation. + +# auto_all + + This tag can _only_ be in the first block, and if given it overrides the + individual auto tags to make the whole demo fully automatic (no block asks + for confirmation). It can also be given at creation time (or the attribute + set later) to override what's in the file. + +While _any_ python file can be run as a Demo instance, if there are no stop +tags the whole file will run in a single block (no different that calling +first %pycat and then %run). The minimal markup to make this useful is to +place a set of stop tags; the other tags are only there to let you fine-tune +the execution. + +This is probably best explained with the simple example file below. You can +copy this into a file named ex_demo.py, and try running it via:: + + from IPython.lib.demo import Demo + d = Demo('ex_demo.py') + d() + +Each time you call the demo object, it runs the next block. The demo object +has a few useful methods for navigation, like again(), edit(), jump(), seek() +and back(). It can be reset for a new run via reset() or reloaded from disk +(in case you've edited the source) via reload(). See their docstrings below. + +Note: To make this simpler to explore, a file called "demo-exercizer.py" has +been added to the "docs/examples/core" directory. Just cd to this directory in +an IPython session, and type:: + + %run demo-exercizer.py + +and then follow the directions. + +Example +------- + +The following is a very simple example of a valid demo file. + +:: + + #################### EXAMPLE DEMO ############################### + '''A simple interactive demo to illustrate the use of IPython's Demo class.''' + + print 'Hello, welcome to an interactive IPython demo.' + + # The mark below defines a block boundary, which is a point where IPython will + # stop execution and return to the interactive prompt. The dashes are actually + # optional and used only as a visual aid to clearly separate blocks while + # editing the demo code. + # stop + + x = 1 + y = 2 + + # stop + + # the mark below makes this block as silent + # silent + + print 'This is a silent block, which gets executed but not printed.' + + # stop + # auto + print 'This is an automatic block.' + print 'It is executed without asking for confirmation, but printed.' + z = x+y + + print 'z=',x + + # stop + # This is just another normal block. + print 'z is now:', z + + print 'bye!' + ################### END EXAMPLE DEMO ############################ +""" + + +#***************************************************************************** +# Copyright (C) 2005-2006 Fernando Perez. +# +# Distributed under the terms of the BSD License. The full license is in +# the file COPYING, distributed as part of this software. +# +#***************************************************************************** + +import os +import re +import shlex +import sys +import pygments + +from IPython.utils.text import marquee +from IPython.utils import openpy +from IPython.utils import py3compat +__all__ = ['Demo','IPythonDemo','LineDemo','IPythonLineDemo','DemoError'] + +class DemoError(Exception): pass + +def re_mark(mark): + return re.compile(r'^\s*#\s+\s+%s\s*$' % mark,re.MULTILINE) + +class Demo(object): + + re_stop = re_mark(r'-*\s?stop\s?-*') + re_silent = re_mark('silent') + re_auto = re_mark('auto') + re_auto_all = re_mark('auto_all') + + def __init__(self,src,title='',arg_str='',auto_all=None, format_rst=False, + formatter='terminal', style='default'): + """Make a new demo object. To run the demo, simply call the object. + + See the module docstring for full details and an example (you can use + IPython.Demo? in IPython to see it). + + Inputs: + + - src is either a file, or file-like object, or a + string that can be resolved to a filename. + + Optional inputs: + + - title: a string to use as the demo name. Of most use when the demo + you are making comes from an object that has no filename, or if you + want an alternate denotation distinct from the filename. + + - arg_str(''): a string of arguments, internally converted to a list + just like sys.argv, so the demo script can see a similar + environment. + + - auto_all(None): global flag to run all blocks automatically without + confirmation. This attribute overrides the block-level tags and + applies to the whole demo. It is an attribute of the object, and + can be changed at runtime simply by reassigning it to a boolean + value. + + - format_rst(False): a bool to enable comments and doc strings + formatting with pygments rst lexer + + - formatter('terminal'): a string of pygments formatter name to be + used. Useful values for terminals: terminal, terminal256, + terminal16m + + - style('default'): a string of pygments style name to be used. + """ + if hasattr(src, "read"): + # It seems to be a file or a file-like object + self.fname = "from a file-like object" + if title == '': + self.title = "from a file-like object" + else: + self.title = title + else: + # Assume it's a string or something that can be converted to one + self.fname = src + if title == '': + (filepath, filename) = os.path.split(src) + self.title = filename + else: + self.title = title + self.sys_argv = [src] + shlex.split(arg_str) + self.auto_all = auto_all + self.src = src + + try: + ip = get_ipython() # this is in builtins whenever IPython is running + self.inside_ipython = True + except NameError: + self.inside_ipython = False + + if self.inside_ipython: + # get a few things from ipython. While it's a bit ugly design-wise, + # it ensures that things like color scheme and the like are always in + # sync with the ipython mode being used. This class is only meant to + # be used inside ipython anyways, so it's OK. + self.ip_ns = ip.user_ns + self.ip_colorize = ip.pycolorize + self.ip_showtb = ip.showtraceback + self.ip_run_cell = ip.run_cell + self.shell = ip + + self.formatter = pygments.formatters.get_formatter_by_name(formatter, + style=style) + self.python_lexer = pygments.lexers.get_lexer_by_name("py3") + self.format_rst = format_rst + if format_rst: + self.rst_lexer = pygments.lexers.get_lexer_by_name("rst") + + # load user data and initialize data structures + self.reload() + + def fload(self): + """Load file object.""" + # read data and parse into blocks + if hasattr(self, 'fobj') and self.fobj is not None: + self.fobj.close() + if hasattr(self.src, "read"): + # It seems to be a file or a file-like object + self.fobj = self.src + else: + # Assume it's a string or something that can be converted to one + self.fobj = openpy.open(self.fname) + + def reload(self): + """Reload source from disk and initialize state.""" + self.fload() + + self.src = "".join(openpy.strip_encoding_cookie(self.fobj)) + src_b = [b.strip() for b in self.re_stop.split(self.src) if b] + self._silent = [bool(self.re_silent.findall(b)) for b in src_b] + self._auto = [bool(self.re_auto.findall(b)) for b in src_b] + + # if auto_all is not given (def. None), we read it from the file + if self.auto_all is None: + self.auto_all = bool(self.re_auto_all.findall(src_b[0])) + else: + self.auto_all = bool(self.auto_all) + + # Clean the sources from all markup so it doesn't get displayed when + # running the demo + src_blocks = [] + auto_strip = lambda s: self.re_auto.sub('',s) + for i,b in enumerate(src_b): + if self._auto[i]: + src_blocks.append(auto_strip(b)) + else: + src_blocks.append(b) + # remove the auto_all marker + src_blocks[0] = self.re_auto_all.sub('',src_blocks[0]) + + self.nblocks = len(src_blocks) + self.src_blocks = src_blocks + + # also build syntax-highlighted source + self.src_blocks_colored = list(map(self.highlight,self.src_blocks)) + + # ensure clean namespace and seek offset + self.reset() + + def reset(self): + """Reset the namespace and seek pointer to restart the demo""" + self.user_ns = {} + self.finished = False + self.block_index = 0 + + def _validate_index(self,index): + if index<0 or index>=self.nblocks: + raise ValueError('invalid block index %s' % index) + + def _get_index(self,index): + """Get the current block index, validating and checking status. + + Returns None if the demo is finished""" + + if index is None: + if self.finished: + print('Demo finished. Use .reset() if you want to rerun it.') + return None + index = self.block_index + else: + self._validate_index(index) + return index + + def seek(self,index): + """Move the current seek pointer to the given block. + + You can use negative indices to seek from the end, with identical + semantics to those of Python lists.""" + if index<0: + index = self.nblocks + index + self._validate_index(index) + self.block_index = index + self.finished = False + + def back(self,num=1): + """Move the seek pointer back num blocks (default is 1).""" + self.seek(self.block_index-num) + + def jump(self,num=1): + """Jump a given number of blocks relative to the current one. + + The offset can be positive or negative, defaults to 1.""" + self.seek(self.block_index+num) + + def again(self): + """Move the seek pointer back one block and re-execute.""" + self.back(1) + self() + + def edit(self,index=None): + """Edit a block. + + If no number is given, use the last block executed. + + This edits the in-memory copy of the demo, it does NOT modify the + original source file. If you want to do that, simply open the file in + an editor and use reload() when you make changes to the file. This + method is meant to let you change a block during a demonstration for + explanatory purposes, without damaging your original script.""" + + index = self._get_index(index) + if index is None: + return + # decrease the index by one (unless we're at the very beginning), so + # that the default demo.edit() call opens up the sblock we've last run + if index>0: + index -= 1 + + filename = self.shell.mktempfile(self.src_blocks[index]) + self.shell.hooks.editor(filename,1) + with open(filename, 'r') as f: + new_block = f.read() + # update the source and colored block + self.src_blocks[index] = new_block + self.src_blocks_colored[index] = self.highlight(new_block) + self.block_index = index + # call to run with the newly edited index + self() + + def show(self,index=None): + """Show a single block on screen""" + + index = self._get_index(index) + if index is None: + return + + print(self.marquee('<%s> block # %s (%s remaining)' % + (self.title,index,self.nblocks-index-1))) + print(self.src_blocks_colored[index]) + sys.stdout.flush() + + def show_all(self): + """Show entire demo on screen, block by block""" + + fname = self.title + title = self.title + nblocks = self.nblocks + silent = self._silent + marquee = self.marquee + for index,block in enumerate(self.src_blocks_colored): + if silent[index]: + print(marquee('<%s> SILENT block # %s (%s remaining)' % + (title,index,nblocks-index-1))) + else: + print(marquee('<%s> block # %s (%s remaining)' % + (title,index,nblocks-index-1))) + print(block, end=' ') + sys.stdout.flush() + + def run_cell(self,source): + """Execute a string with one or more lines of code""" + + exec(source, self.user_ns) + + def __call__(self,index=None): + """run a block of the demo. + + If index is given, it should be an integer >=1 and <= nblocks. This + means that the calling convention is one off from typical Python + lists. The reason for the inconsistency is that the demo always + prints 'Block n/N, and N is the total, so it would be very odd to use + zero-indexing here.""" + + index = self._get_index(index) + if index is None: + return + try: + marquee = self.marquee + next_block = self.src_blocks[index] + self.block_index += 1 + if self._silent[index]: + print(marquee('Executing silent block # %s (%s remaining)' % + (index,self.nblocks-index-1))) + else: + self.pre_cmd() + self.show(index) + if self.auto_all or self._auto[index]: + print(marquee('output:')) + else: + print(marquee('Press to quit, to execute...'), end=' ') + ans = py3compat.input().strip() + if ans: + print(marquee('Block NOT executed')) + return + try: + save_argv = sys.argv + sys.argv = self.sys_argv + self.run_cell(next_block) + self.post_cmd() + finally: + sys.argv = save_argv + + except: + if self.inside_ipython: + self.ip_showtb(filename=self.fname) + else: + if self.inside_ipython: + self.ip_ns.update(self.user_ns) + + if self.block_index == self.nblocks: + mq1 = self.marquee('END OF DEMO') + if mq1: + # avoid spurious print if empty marquees are used + print() + print(mq1) + print(self.marquee('Use .reset() if you want to rerun it.')) + self.finished = True + + # These methods are meant to be overridden by subclasses who may wish to + # customize the behavior of of their demos. + def marquee(self,txt='',width=78,mark='*'): + """Return the input string centered in a 'marquee'.""" + return marquee(txt,width,mark) + + def pre_cmd(self): + """Method called before executing each block.""" + pass + + def post_cmd(self): + """Method called after executing each block.""" + pass + + def highlight(self, block): + """Method called on each block to highlight it content""" + tokens = pygments.lex(block, self.python_lexer) + if self.format_rst: + from pygments.token import Token + toks = [] + for token in tokens: + if token[0] == Token.String.Doc and len(token[1]) > 6: + toks += pygments.lex(token[1][:3], self.python_lexer) + # parse doc string content by rst lexer + toks += pygments.lex(token[1][3:-3], self.rst_lexer) + toks += pygments.lex(token[1][-3:], self.python_lexer) + elif token[0] == Token.Comment.Single: + toks.append((Token.Comment.Single, token[1][0])) + # parse comment content by rst lexer + # remove the extrat newline added by rst lexer + toks += list(pygments.lex(token[1][1:], self.rst_lexer))[:-1] + else: + toks.append(token) + tokens = toks + return pygments.format(tokens, self.formatter) + + +class IPythonDemo(Demo): + """Class for interactive demos with IPython's input processing applied. + + This subclasses Demo, but instead of executing each block by the Python + interpreter (via exec), it actually calls IPython on it, so that any input + filters which may be in place are applied to the input block. + + If you have an interactive environment which exposes special input + processing, you can use this class instead to write demo scripts which + operate exactly as if you had typed them interactively. The default Demo + class requires the input to be valid, pure Python code. + """ + + def run_cell(self,source): + """Execute a string with one or more lines of code""" + + self.shell.run_cell(source) + +class LineDemo(Demo): + """Demo where each line is executed as a separate block. + + The input script should be valid Python code. + + This class doesn't require any markup at all, and it's meant for simple + scripts (with no nesting or any kind of indentation) which consist of + multiple lines of input to be executed, one at a time, as if they had been + typed in the interactive prompt. + + Note: the input can not have *any* indentation, which means that only + single-lines of input are accepted, not even function definitions are + valid.""" + + def reload(self): + """Reload source from disk and initialize state.""" + # read data and parse into blocks + self.fload() + lines = self.fobj.readlines() + src_b = [l for l in lines if l.strip()] + nblocks = len(src_b) + self.src = ''.join(lines) + self._silent = [False]*nblocks + self._auto = [True]*nblocks + self.auto_all = True + self.nblocks = nblocks + self.src_blocks = src_b + + # also build syntax-highlighted source + self.src_blocks_colored = list(map(self.highlight,self.src_blocks)) + + # ensure clean namespace and seek offset + self.reset() + + +class IPythonLineDemo(IPythonDemo,LineDemo): + """Variant of the LineDemo class whose input is processed by IPython.""" + pass + + +class ClearMixin(object): + """Use this mixin to make Demo classes with less visual clutter. + + Demos using this mixin will clear the screen before every block and use + blank marquees. + + Note that in order for the methods defined here to actually override those + of the classes it's mixed with, it must go /first/ in the inheritance + tree. For example: + + class ClearIPDemo(ClearMixin,IPythonDemo): pass + + will provide an IPythonDemo class with the mixin's features. + """ + + def marquee(self,txt='',width=78,mark='*'): + """Blank marquee that returns '' no matter what the input.""" + return '' + + def pre_cmd(self): + """Method called before executing each block. + + This one simply clears the screen.""" + from IPython.utils.terminal import _term_clear + _term_clear() + +class ClearDemo(ClearMixin,Demo): + pass + + +class ClearIPDemo(ClearMixin,IPythonDemo): + pass + + +def slide(file_path, noclear=False, format_rst=True, formatter="terminal", + style="native", auto_all=False, delimiter='...'): + if noclear: + demo_class = Demo + else: + demo_class = ClearDemo + demo = demo_class(file_path, format_rst=format_rst, formatter=formatter, + style=style, auto_all=auto_all) + while not demo.finished: + demo() + try: + py3compat.input('\n' + delimiter) + except KeyboardInterrupt: + exit(1) + +if __name__ == '__main__': + import argparse + parser = argparse.ArgumentParser(description='Run python demos') + parser.add_argument('--noclear', '-C', action='store_true', + help='Do not clear terminal on each slide') + parser.add_argument('--rst', '-r', action='store_true', + help='Highlight comments and dostrings as rst') + parser.add_argument('--formatter', '-f', default='terminal', + help='pygments formatter name could be: terminal, ' + 'terminal256, terminal16m') + parser.add_argument('--style', '-s', default='default', + help='pygments style name') + parser.add_argument('--auto', '-a', action='store_true', + help='Run all blocks automatically without' + 'confirmation') + parser.add_argument('--delimiter', '-d', default='...', + help='slides delimiter added after each slide run') + parser.add_argument('file', nargs=1, + help='python demo file') + args = parser.parse_args() + slide(args.file[0], noclear=args.noclear, format_rst=args.rst, + formatter=args.formatter, style=args.style, auto_all=args.auto, + delimiter=args.delimiter) diff --git a/.venv/lib/python3.8/site-packages/IPython/lib/display.py b/.venv/lib/python3.8/site-packages/IPython/lib/display.py new file mode 100644 index 00000000..de31788a --- /dev/null +++ b/.venv/lib/python3.8/site-packages/IPython/lib/display.py @@ -0,0 +1,654 @@ +"""Various display related classes. + +Authors : MinRK, gregcaporaso, dannystaple +""" +from html import escape as html_escape +from os.path import exists, isfile, splitext, abspath, join, isdir +from os import walk, sep, fsdecode + +from IPython.core.display import DisplayObject, TextDisplayObject + +__all__ = ['Audio', 'IFrame', 'YouTubeVideo', 'VimeoVideo', 'ScribdDocument', + 'FileLink', 'FileLinks', 'Code'] + + +class Audio(DisplayObject): + """Create an audio object. + + When this object is returned by an input cell or passed to the + display function, it will result in Audio controls being displayed + in the frontend (only works in the notebook). + + Parameters + ---------- + data : numpy array, list, unicode, str or bytes + Can be one of + + * Numpy 1d array containing the desired waveform (mono) + * Numpy 2d array containing waveforms for each channel. + Shape=(NCHAN, NSAMPLES). For the standard channel order, see + http://msdn.microsoft.com/en-us/library/windows/hardware/dn653308(v=vs.85).aspx + * List of float or integer representing the waveform (mono) + * String containing the filename + * Bytestring containing raw PCM data or + * URL pointing to a file on the web. + + If the array option is used, the waveform will be normalized. + + If a filename or url is used, the format support will be browser + dependent. + url : unicode + A URL to download the data from. + filename : unicode + Path to a local file to load the data from. + embed : boolean + Should the audio data be embedded using a data URI (True) or should + the original source be referenced. Set this to True if you want the + audio to playable later with no internet connection in the notebook. + + Default is `True`, unless the keyword argument `url` is set, then + default value is `False`. + rate : integer + The sampling rate of the raw data. + Only required when data parameter is being used as an array + autoplay : bool + Set to True if the audio should immediately start playing. + Default is `False`. + normalize : bool + Whether audio should be normalized (rescaled) to the maximum possible + range. Default is `True`. When set to `False`, `data` must be between + -1 and 1 (inclusive), otherwise an error is raised. + Applies only when `data` is a list or array of samples; other types of + audio are never normalized. + + Examples + -------- + :: + + # Generate a sound + import numpy as np + framerate = 44100 + t = np.linspace(0,5,framerate*5) + data = np.sin(2*np.pi*220*t) + np.sin(2*np.pi*224*t) + Audio(data,rate=framerate) + + # Can also do stereo or more channels + dataleft = np.sin(2*np.pi*220*t) + dataright = np.sin(2*np.pi*224*t) + Audio([dataleft, dataright],rate=framerate) + + Audio("http://www.nch.com.au/acm/8k16bitpcm.wav") # From URL + Audio(url="http://www.w3schools.com/html/horse.ogg") + + Audio('/path/to/sound.wav') # From file + Audio(filename='/path/to/sound.ogg') + + Audio(b'RAW_WAV_DATA..) # From bytes + Audio(data=b'RAW_WAV_DATA..) + + See Also + -------- + + See also the ``Audio`` widgets form the ``ipywidget`` package for more flexibility and options. + + """ + _read_flags = 'rb' + + def __init__(self, data=None, filename=None, url=None, embed=None, rate=None, autoplay=False, normalize=True, *, + element_id=None): + if filename is None and url is None and data is None: + raise ValueError("No audio data found. Expecting filename, url, or data.") + if embed is False and url is None: + raise ValueError("No url found. Expecting url when embed=False") + + if url is not None and embed is not True: + self.embed = False + else: + self.embed = True + self.autoplay = autoplay + self.element_id = element_id + super(Audio, self).__init__(data=data, url=url, filename=filename) + + if self.data is not None and not isinstance(self.data, bytes): + if rate is None: + raise ValueError("rate must be specified when data is a numpy array or list of audio samples.") + self.data = Audio._make_wav(data, rate, normalize) + + def reload(self): + """Reload the raw data from file or URL.""" + import mimetypes + if self.embed: + super(Audio, self).reload() + + if self.filename is not None: + self.mimetype = mimetypes.guess_type(self.filename)[0] + elif self.url is not None: + self.mimetype = mimetypes.guess_type(self.url)[0] + else: + self.mimetype = "audio/wav" + + @staticmethod + def _make_wav(data, rate, normalize): + """ Transform a numpy array to a PCM bytestring """ + from io import BytesIO + import wave + + try: + scaled, nchan = Audio._validate_and_normalize_with_numpy(data, normalize) + except ImportError: + scaled, nchan = Audio._validate_and_normalize_without_numpy(data, normalize) + + fp = BytesIO() + waveobj = wave.open(fp,mode='wb') + waveobj.setnchannels(nchan) + waveobj.setframerate(rate) + waveobj.setsampwidth(2) + waveobj.setcomptype('NONE','NONE') + waveobj.writeframes(scaled) + val = fp.getvalue() + waveobj.close() + + return val + + @staticmethod + def _validate_and_normalize_with_numpy(data, normalize): + import numpy as np + + data = np.array(data, dtype=float) + if len(data.shape) == 1: + nchan = 1 + elif len(data.shape) == 2: + # In wave files,channels are interleaved. E.g., + # "L1R1L2R2..." for stereo. See + # http://msdn.microsoft.com/en-us/library/windows/hardware/dn653308(v=vs.85).aspx + # for channel ordering + nchan = data.shape[0] + data = data.T.ravel() + else: + raise ValueError('Array audio input must be a 1D or 2D array') + + max_abs_value = np.max(np.abs(data)) + normalization_factor = Audio._get_normalization_factor(max_abs_value, normalize) + scaled = data / normalization_factor * 32767 + return scaled.astype(' 1: + raise ValueError('Audio data must be between -1 and 1 when normalize=False.') + return max_abs_value if normalize else 1 + + def _data_and_metadata(self): + """shortcut for returning metadata with url information, if defined""" + md = {} + if self.url: + md['url'] = self.url + if md: + return self.data, md + else: + return self.data + + def _repr_html_(self): + src = """ + + """ + return src.format(src=self.src_attr(), type=self.mimetype, autoplay=self.autoplay_attr(), + element_id=self.element_id_attr()) + + def src_attr(self): + import base64 + if self.embed and (self.data is not None): + data = base64=base64.b64encode(self.data).decode('ascii') + return """data:{type};base64,{base64}""".format(type=self.mimetype, + base64=data) + elif self.url is not None: + return self.url + else: + return "" + + def autoplay_attr(self): + if(self.autoplay): + return 'autoplay="autoplay"' + else: + return '' + + def element_id_attr(self): + if (self.element_id): + return 'id="{element_id}"'.format(element_id=self.element_id) + else: + return '' + +class IFrame(object): + """ + Generic class to embed an iframe in an IPython notebook + """ + + iframe = """ + + """ + + def __init__(self, src, width, height, **kwargs): + self.src = src + self.width = width + self.height = height + self.params = kwargs + + def _repr_html_(self): + """return the embed iframe""" + if self.params: + try: + from urllib.parse import urlencode # Py 3 + except ImportError: + from urllib import urlencode + params = "?" + urlencode(self.params) + else: + params = "" + return self.iframe.format(src=self.src, + width=self.width, + height=self.height, + params=params) + +class YouTubeVideo(IFrame): + """Class for embedding a YouTube Video in an IPython session, based on its video id. + + e.g. to embed the video from https://www.youtube.com/watch?v=foo , you would + do:: + + vid = YouTubeVideo("foo") + display(vid) + + To start from 30 seconds:: + + vid = YouTubeVideo("abc", start=30) + display(vid) + + To calculate seconds from time as hours, minutes, seconds use + :class:`datetime.timedelta`:: + + start=int(timedelta(hours=1, minutes=46, seconds=40).total_seconds()) + + Other parameters can be provided as documented at + https://developers.google.com/youtube/player_parameters#Parameters + + When converting the notebook using nbconvert, a jpeg representation of the video + will be inserted in the document. + """ + + def __init__(self, id, width=400, height=300, **kwargs): + self.id=id + src = "https://www.youtube.com/embed/{0}".format(id) + super(YouTubeVideo, self).__init__(src, width, height, **kwargs) + + def _repr_jpeg_(self): + # Deferred import + from urllib.request import urlopen + + try: + return urlopen("https://img.youtube.com/vi/{id}/hqdefault.jpg".format(id=self.id)).read() + except IOError: + return None + +class VimeoVideo(IFrame): + """ + Class for embedding a Vimeo video in an IPython session, based on its video id. + """ + + def __init__(self, id, width=400, height=300, **kwargs): + src="https://player.vimeo.com/video/{0}".format(id) + super(VimeoVideo, self).__init__(src, width, height, **kwargs) + +class ScribdDocument(IFrame): + """ + Class for embedding a Scribd document in an IPython session + + Use the start_page params to specify a starting point in the document + Use the view_mode params to specify display type one off scroll | slideshow | book + + e.g to Display Wes' foundational paper about PANDAS in book mode from page 3 + + ScribdDocument(71048089, width=800, height=400, start_page=3, view_mode="book") + """ + + def __init__(self, id, width=400, height=300, **kwargs): + src="https://www.scribd.com/embeds/{0}/content".format(id) + super(ScribdDocument, self).__init__(src, width, height, **kwargs) + +class FileLink(object): + """Class for embedding a local file link in an IPython session, based on path + + e.g. to embed a link that was generated in the IPython notebook as my/data.txt + + you would do:: + + local_file = FileLink("my/data.txt") + display(local_file) + + or in the HTML notebook, just:: + + FileLink("my/data.txt") + """ + + html_link_str = "%s" + + def __init__(self, + path, + url_prefix='', + result_html_prefix='', + result_html_suffix='
'): + """ + Parameters + ---------- + path : str + path to the file or directory that should be formatted + url_prefix : str + prefix to be prepended to all files to form a working link [default: + ''] + result_html_prefix : str + text to append to beginning to link [default: ''] + result_html_suffix : str + text to append at the end of link [default: '
'] + """ + if isdir(path): + raise ValueError("Cannot display a directory using FileLink. " + "Use FileLinks to display '%s'." % path) + self.path = fsdecode(path) + self.url_prefix = url_prefix + self.result_html_prefix = result_html_prefix + self.result_html_suffix = result_html_suffix + + def _format_path(self): + fp = ''.join([self.url_prefix, html_escape(self.path)]) + return ''.join([self.result_html_prefix, + self.html_link_str % \ + (fp, html_escape(self.path, quote=False)), + self.result_html_suffix]) + + def _repr_html_(self): + """return html link to file + """ + if not exists(self.path): + return ("Path (%s) doesn't exist. " + "It may still be in the process of " + "being generated, or you may have the " + "incorrect path." % self.path) + + return self._format_path() + + def __repr__(self): + """return absolute path to file + """ + return abspath(self.path) + +class FileLinks(FileLink): + """Class for embedding local file links in an IPython session, based on path + + e.g. to embed links to files that were generated in the IPython notebook + under ``my/data``, you would do:: + + local_files = FileLinks("my/data") + display(local_files) + + or in the HTML notebook, just:: + + FileLinks("my/data") + """ + def __init__(self, + path, + url_prefix='', + included_suffixes=None, + result_html_prefix='', + result_html_suffix='
', + notebook_display_formatter=None, + terminal_display_formatter=None, + recursive=True): + """ + See :class:`FileLink` for the ``path``, ``url_prefix``, + ``result_html_prefix`` and ``result_html_suffix`` parameters. + + included_suffixes : list + Filename suffixes to include when formatting output [default: include + all files] + + notebook_display_formatter : function + Used to format links for display in the notebook. See discussion of + formatter functions below. + + terminal_display_formatter : function + Used to format links for display in the terminal. See discussion of + formatter functions below. + + Formatter functions must be of the form:: + + f(dirname, fnames, included_suffixes) + + dirname : str + The name of a directory + fnames : list + The files in that directory + included_suffixes : list + The file suffixes that should be included in the output (passing None + meansto include all suffixes in the output in the built-in formatters) + recursive : boolean + Whether to recurse into subdirectories. Default is True. + + The function should return a list of lines that will be printed in the + notebook (if passing notebook_display_formatter) or the terminal (if + passing terminal_display_formatter). This function is iterated over for + each directory in self.path. Default formatters are in place, can be + passed here to support alternative formatting. + + """ + if isfile(path): + raise ValueError("Cannot display a file using FileLinks. " + "Use FileLink to display '%s'." % path) + self.included_suffixes = included_suffixes + # remove trailing slashes for more consistent output formatting + path = path.rstrip('/') + + self.path = path + self.url_prefix = url_prefix + self.result_html_prefix = result_html_prefix + self.result_html_suffix = result_html_suffix + + self.notebook_display_formatter = \ + notebook_display_formatter or self._get_notebook_display_formatter() + self.terminal_display_formatter = \ + terminal_display_formatter or self._get_terminal_display_formatter() + + self.recursive = recursive + + def _get_display_formatter(self, + dirname_output_format, + fname_output_format, + fp_format, + fp_cleaner=None): + """ generate built-in formatter function + + this is used to define both the notebook and terminal built-in + formatters as they only differ by some wrapper text for each entry + + dirname_output_format: string to use for formatting directory + names, dirname will be substituted for a single "%s" which + must appear in this string + fname_output_format: string to use for formatting file names, + if a single "%s" appears in the string, fname will be substituted + if two "%s" appear in the string, the path to fname will be + substituted for the first and fname will be substituted for the + second + fp_format: string to use for formatting filepaths, must contain + exactly two "%s" and the dirname will be substituted for the first + and fname will be substituted for the second + """ + def f(dirname, fnames, included_suffixes=None): + result = [] + # begin by figuring out which filenames, if any, + # are going to be displayed + display_fnames = [] + for fname in fnames: + if (isfile(join(dirname,fname)) and + (included_suffixes is None or + splitext(fname)[1] in included_suffixes)): + display_fnames.append(fname) + + if len(display_fnames) == 0: + # if there are no filenames to display, don't print anything + # (not even the directory name) + pass + else: + # otherwise print the formatted directory name followed by + # the formatted filenames + dirname_output_line = dirname_output_format % dirname + result.append(dirname_output_line) + for fname in display_fnames: + fp = fp_format % (dirname,fname) + if fp_cleaner is not None: + fp = fp_cleaner(fp) + try: + # output can include both a filepath and a filename... + fname_output_line = fname_output_format % (fp, fname) + except TypeError: + # ... or just a single filepath + fname_output_line = fname_output_format % fname + result.append(fname_output_line) + return result + return f + + def _get_notebook_display_formatter(self, + spacer="  "): + """ generate function to use for notebook formatting + """ + dirname_output_format = \ + self.result_html_prefix + "%s/" + self.result_html_suffix + fname_output_format = \ + self.result_html_prefix + spacer + self.html_link_str + self.result_html_suffix + fp_format = self.url_prefix + '%s/%s' + if sep == "\\": + # Working on a platform where the path separator is "\", so + # must convert these to "/" for generating a URI + def fp_cleaner(fp): + # Replace all occurrences of backslash ("\") with a forward + # slash ("/") - this is necessary on windows when a path is + # provided as input, but we must link to a URI + return fp.replace('\\','/') + else: + fp_cleaner = None + + return self._get_display_formatter(dirname_output_format, + fname_output_format, + fp_format, + fp_cleaner) + + def _get_terminal_display_formatter(self, + spacer=" "): + """ generate function to use for terminal formatting + """ + dirname_output_format = "%s/" + fname_output_format = spacer + "%s" + fp_format = '%s/%s' + + return self._get_display_formatter(dirname_output_format, + fname_output_format, + fp_format) + + def _format_path(self): + result_lines = [] + if self.recursive: + walked_dir = list(walk(self.path)) + else: + walked_dir = [next(walk(self.path))] + walked_dir.sort() + for dirname, subdirs, fnames in walked_dir: + result_lines += self.notebook_display_formatter(dirname, fnames, self.included_suffixes) + return '\n'.join(result_lines) + + def __repr__(self): + """return newline-separated absolute paths + """ + result_lines = [] + if self.recursive: + walked_dir = list(walk(self.path)) + else: + walked_dir = [next(walk(self.path))] + walked_dir.sort() + for dirname, subdirs, fnames in walked_dir: + result_lines += self.terminal_display_formatter(dirname, fnames, self.included_suffixes) + return '\n'.join(result_lines) + + +class Code(TextDisplayObject): + """Display syntax-highlighted source code. + + This uses Pygments to highlight the code for HTML and Latex output. + + Parameters + ---------- + data : str + The code as a string + url : str + A URL to fetch the code from + filename : str + A local filename to load the code from + language : str + The short name of a Pygments lexer to use for highlighting. + If not specified, it will guess the lexer based on the filename + or the code. Available lexers: http://pygments.org/docs/lexers/ + """ + def __init__(self, data=None, url=None, filename=None, language=None): + self.language = language + super().__init__(data=data, url=url, filename=filename) + + def _get_lexer(self): + if self.language: + from pygments.lexers import get_lexer_by_name + return get_lexer_by_name(self.language) + elif self.filename: + from pygments.lexers import get_lexer_for_filename + return get_lexer_for_filename(self.filename) + else: + from pygments.lexers import guess_lexer + return guess_lexer(self.data) + + def __repr__(self): + return self.data + + def _repr_html_(self): + from pygments import highlight + from pygments.formatters import HtmlFormatter + fmt = HtmlFormatter() + style = ''.format(fmt.get_style_defs('.output_html')) + return style + highlight(self.data, self._get_lexer(), fmt) + + def _repr_latex_(self): + from pygments import highlight + from pygments.formatters import LatexFormatter + return highlight(self.data, self._get_lexer(), LatexFormatter()) diff --git a/.venv/lib/python3.8/site-packages/IPython/lib/editorhooks.py b/.venv/lib/python3.8/site-packages/IPython/lib/editorhooks.py new file mode 100644 index 00000000..7ce0577a --- /dev/null +++ b/.venv/lib/python3.8/site-packages/IPython/lib/editorhooks.py @@ -0,0 +1,128 @@ +""" 'editor' hooks for common editors that work well with ipython + +They should honor the line number argument, at least. + +Contributions are *very* welcome. +""" + +import os +import pipes +import shlex +import subprocess +import sys + +from IPython import get_ipython +from IPython.core.error import TryNext +from IPython.utils import py3compat + + +def install_editor(template, wait=False): + """Installs the editor that is called by IPython for the %edit magic. + + This overrides the default editor, which is generally set by your EDITOR + environment variable or is notepad (windows) or vi (linux). By supplying a + template string `run_template`, you can control how the editor is invoked + by IPython -- (e.g. the format in which it accepts command line options) + + Parameters + ---------- + template : basestring + run_template acts as a template for how your editor is invoked by + the shell. It should contain '{filename}', which will be replaced on + invocation with the file name, and '{line}', $line by line number + (or 0) to invoke the file with. + wait : bool + If `wait` is true, wait until the user presses enter before returning, + to facilitate non-blocking editors that exit immediately after + the call. + """ + + # not all editors support $line, so we'll leave out this check + # for substitution in ['$file', '$line']: + # if not substitution in run_template: + # raise ValueError(('run_template should contain %s' + # ' for string substitution. You supplied "%s"' % (substitution, + # run_template))) + + def call_editor(self, filename, line=0): + if line is None: + line = 0 + cmd = template.format(filename=pipes.quote(filename), line=line) + print(">", cmd) + # pipes.quote doesn't work right on Windows, but it does after splitting + if sys.platform.startswith('win'): + cmd = shlex.split(cmd) + proc = subprocess.Popen(cmd, shell=True) + if proc.wait() != 0: + raise TryNext() + if wait: + py3compat.input("Press Enter when done editing:") + + get_ipython().set_hook('editor', call_editor) + get_ipython().editor = template + + +# in these, exe is always the path/name of the executable. Useful +# if you don't have the editor directory in your path +def komodo(exe=u'komodo'): + """ Activestate Komodo [Edit] """ + install_editor(exe + u' -l {line} {filename}', wait=True) + + +def scite(exe=u"scite"): + """ SciTE or Sc1 """ + install_editor(exe + u' {filename} -goto:{line}') + + +def notepadplusplus(exe=u'notepad++'): + """ Notepad++ http://notepad-plus.sourceforge.net """ + install_editor(exe + u' -n{line} {filename}') + + +def jed(exe=u'jed'): + """ JED, the lightweight emacsish editor """ + install_editor(exe + u' +{line} {filename}') + + +def idle(exe=u'idle'): + """ Idle, the editor bundled with python + + Parameters + ---------- + exe : str, None + If none, should be pretty smart about finding the executable. + """ + if exe is None: + import idlelib + p = os.path.dirname(idlelib.__filename__) + # i'm not sure if this actually works. Is this idle.py script + # guaranteed to be executable? + exe = os.path.join(p, 'idle.py') + install_editor(exe + u' {filename}') + + +def mate(exe=u'mate'): + """ TextMate, the missing editor""" + # wait=True is not required since we're using the -w flag to mate + install_editor(exe + u' -w -l {line} {filename}') + + +# ########################################## +# these are untested, report any problems +# ########################################## + + +def emacs(exe=u'emacs'): + install_editor(exe + u' +{line} {filename}') + + +def gnuclient(exe=u'gnuclient'): + install_editor(exe + u' -nw +{line} {filename}') + + +def crimson_editor(exe=u'cedt.exe'): + install_editor(exe + u' /L:{line} {filename}') + + +def kate(exe=u'kate'): + install_editor(exe + u' -u -l {line} {filename}') diff --git a/.venv/lib/python3.8/site-packages/IPython/lib/guisupport.py b/.venv/lib/python3.8/site-packages/IPython/lib/guisupport.py new file mode 100644 index 00000000..cfd325e9 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/IPython/lib/guisupport.py @@ -0,0 +1,155 @@ +# coding: utf-8 +""" +Support for creating GUI apps and starting event loops. + +IPython's GUI integration allows interactive plotting and GUI usage in IPython +session. IPython has two different types of GUI integration: + +1. The terminal based IPython supports GUI event loops through Python's + PyOS_InputHook. PyOS_InputHook is a hook that Python calls periodically + whenever raw_input is waiting for a user to type code. We implement GUI + support in the terminal by setting PyOS_InputHook to a function that + iterates the event loop for a short while. It is important to note that + in this situation, the real GUI event loop is NOT run in the normal + manner, so you can't use the normal means to detect that it is running. +2. In the two process IPython kernel/frontend, the GUI event loop is run in + the kernel. In this case, the event loop is run in the normal manner by + calling the function or method of the GUI toolkit that starts the event + loop. + +In addition to starting the GUI event loops in one of these two ways, IPython +will *always* create an appropriate GUI application object when GUi +integration is enabled. + +If you want your GUI apps to run in IPython you need to do two things: + +1. Test to see if there is already an existing main application object. If + there is, you should use it. If there is not an existing application object + you should create one. +2. Test to see if the GUI event loop is running. If it is, you should not + start it. If the event loop is not running you may start it. + +This module contains functions for each toolkit that perform these things +in a consistent manner. Because of how PyOS_InputHook runs the event loop +you cannot detect if the event loop is running using the traditional calls +(such as ``wx.GetApp.IsMainLoopRunning()`` in wxPython). If PyOS_InputHook is +set These methods will return a false negative. That is, they will say the +event loop is not running, when is actually is. To work around this limitation +we proposed the following informal protocol: + +* Whenever someone starts the event loop, they *must* set the ``_in_event_loop`` + attribute of the main application object to ``True``. This should be done + regardless of how the event loop is actually run. +* Whenever someone stops the event loop, they *must* set the ``_in_event_loop`` + attribute of the main application object to ``False``. +* If you want to see if the event loop is running, you *must* use ``hasattr`` + to see if ``_in_event_loop`` attribute has been set. If it is set, you + *must* use its value. If it has not been set, you can query the toolkit + in the normal manner. +* If you want GUI support and no one else has created an application or + started the event loop you *must* do this. We don't want projects to + attempt to defer these things to someone else if they themselves need it. + +The functions below implement this logic for each GUI toolkit. If you need +to create custom application subclasses, you will likely have to modify this +code for your own purposes. This code can be copied into your own project +so you don't have to depend on IPython. + +""" + +# Copyright (c) IPython Development Team. +# Distributed under the terms of the Modified BSD License. + +from IPython.core.getipython import get_ipython + +#----------------------------------------------------------------------------- +# wx +#----------------------------------------------------------------------------- + +def get_app_wx(*args, **kwargs): + """Create a new wx app or return an exiting one.""" + import wx + app = wx.GetApp() + if app is None: + if 'redirect' not in kwargs: + kwargs['redirect'] = False + app = wx.PySimpleApp(*args, **kwargs) + return app + +def is_event_loop_running_wx(app=None): + """Is the wx event loop running.""" + # New way: check attribute on shell instance + ip = get_ipython() + if ip is not None: + if ip.active_eventloop and ip.active_eventloop == 'wx': + return True + # Fall through to checking the application, because Wx has a native way + # to check if the event loop is running, unlike Qt. + + # Old way: check Wx application + if app is None: + app = get_app_wx() + if hasattr(app, '_in_event_loop'): + return app._in_event_loop + else: + return app.IsMainLoopRunning() + +def start_event_loop_wx(app=None): + """Start the wx event loop in a consistent manner.""" + if app is None: + app = get_app_wx() + if not is_event_loop_running_wx(app): + app._in_event_loop = True + app.MainLoop() + app._in_event_loop = False + else: + app._in_event_loop = True + +#----------------------------------------------------------------------------- +# qt4 +#----------------------------------------------------------------------------- + +def get_app_qt4(*args, **kwargs): + """Create a new qt4 app or return an existing one.""" + from IPython.external.qt_for_kernel import QtGui + app = QtGui.QApplication.instance() + if app is None: + if not args: + args = ([''],) + app = QtGui.QApplication(*args, **kwargs) + return app + +def is_event_loop_running_qt4(app=None): + """Is the qt4 event loop running.""" + # New way: check attribute on shell instance + ip = get_ipython() + if ip is not None: + return ip.active_eventloop and ip.active_eventloop.startswith('qt') + + # Old way: check attribute on QApplication singleton + if app is None: + app = get_app_qt4(['']) + if hasattr(app, '_in_event_loop'): + return app._in_event_loop + else: + # Does qt4 provide a other way to detect this? + return False + +def start_event_loop_qt4(app=None): + """Start the qt4 event loop in a consistent manner.""" + if app is None: + app = get_app_qt4(['']) + if not is_event_loop_running_qt4(app): + app._in_event_loop = True + app.exec_() + app._in_event_loop = False + else: + app._in_event_loop = True + +#----------------------------------------------------------------------------- +# Tk +#----------------------------------------------------------------------------- + +#----------------------------------------------------------------------------- +# gtk +#----------------------------------------------------------------------------- diff --git a/.venv/lib/python3.8/site-packages/IPython/lib/inputhook.py b/.venv/lib/python3.8/site-packages/IPython/lib/inputhook.py new file mode 100644 index 00000000..e6e8f2db --- /dev/null +++ b/.venv/lib/python3.8/site-packages/IPython/lib/inputhook.py @@ -0,0 +1,666 @@ +# coding: utf-8 +""" +Deprecated since IPython 5.0 + +Inputhook management for GUI event loop integration. +""" + +# Copyright (c) IPython Development Team. +# Distributed under the terms of the Modified BSD License. + +try: + import ctypes +except ImportError: + ctypes = None +except SystemError: # IronPython issue, 2/8/2014 + ctypes = None +import os +import platform +import sys +from distutils.version import LooseVersion as V + +from warnings import warn + + +warn("`IPython.lib.inputhook` is deprecated since IPython 5.0 and will be removed in future versions.", + DeprecationWarning, stacklevel=2) + + +#----------------------------------------------------------------------------- +# Constants +#----------------------------------------------------------------------------- + +# Constants for identifying the GUI toolkits. +GUI_WX = 'wx' +GUI_QT = 'qt' +GUI_QT4 = 'qt4' +GUI_GTK = 'gtk' +GUI_TK = 'tk' +GUI_OSX = 'osx' +GUI_GLUT = 'glut' +GUI_PYGLET = 'pyglet' +GUI_GTK3 = 'gtk3' +GUI_NONE = 'none' # i.e. disable + +#----------------------------------------------------------------------------- +# Utilities +#----------------------------------------------------------------------------- + +def _stdin_ready_posix(): + """Return True if there's something to read on stdin (posix version).""" + infds, outfds, erfds = select.select([sys.stdin],[],[],0) + return bool(infds) + +def _stdin_ready_nt(): + """Return True if there's something to read on stdin (nt version).""" + return msvcrt.kbhit() + +def _stdin_ready_other(): + """Return True, assuming there's something to read on stdin.""" + return True + +def _use_appnope(): + """Should we use appnope for dealing with OS X app nap? + + Checks if we are on OS X 10.9 or greater. + """ + return sys.platform == 'darwin' and V(platform.mac_ver()[0]) >= V('10.9') + +def _ignore_CTRL_C_posix(): + """Ignore CTRL+C (SIGINT).""" + signal.signal(signal.SIGINT, signal.SIG_IGN) + +def _allow_CTRL_C_posix(): + """Take CTRL+C into account (SIGINT).""" + signal.signal(signal.SIGINT, signal.default_int_handler) + +def _ignore_CTRL_C_other(): + """Ignore CTRL+C (not implemented).""" + pass + +def _allow_CTRL_C_other(): + """Take CTRL+C into account (not implemented).""" + pass + +if os.name == 'posix': + import select + import signal + stdin_ready = _stdin_ready_posix + ignore_CTRL_C = _ignore_CTRL_C_posix + allow_CTRL_C = _allow_CTRL_C_posix +elif os.name == 'nt': + import msvcrt + stdin_ready = _stdin_ready_nt + ignore_CTRL_C = _ignore_CTRL_C_other + allow_CTRL_C = _allow_CTRL_C_other +else: + stdin_ready = _stdin_ready_other + ignore_CTRL_C = _ignore_CTRL_C_other + allow_CTRL_C = _allow_CTRL_C_other + + +#----------------------------------------------------------------------------- +# Main InputHookManager class +#----------------------------------------------------------------------------- + + +class InputHookManager(object): + """DEPRECATED since IPython 5.0 + + Manage PyOS_InputHook for different GUI toolkits. + + This class installs various hooks under ``PyOSInputHook`` to handle + GUI event loop integration. + """ + + def __init__(self): + if ctypes is None: + warn("IPython GUI event loop requires ctypes, %gui will not be available") + else: + self.PYFUNC = ctypes.PYFUNCTYPE(ctypes.c_int) + self.guihooks = {} + self.aliases = {} + self.apps = {} + self._reset() + + def _reset(self): + self._callback_pyfunctype = None + self._callback = None + self._installed = False + self._current_gui = None + + def get_pyos_inputhook(self): + """DEPRECATED since IPython 5.0 + + Return the current PyOS_InputHook as a ctypes.c_void_p.""" + warn("`get_pyos_inputhook` is deprecated since IPython 5.0 and will be removed in future versions.", + DeprecationWarning, stacklevel=2) + return ctypes.c_void_p.in_dll(ctypes.pythonapi,"PyOS_InputHook") + + def get_pyos_inputhook_as_func(self): + """DEPRECATED since IPython 5.0 + + Return the current PyOS_InputHook as a ctypes.PYFUNCYPE.""" + warn("`get_pyos_inputhook_as_func` is deprecated since IPython 5.0 and will be removed in future versions.", + DeprecationWarning, stacklevel=2) + return self.PYFUNC.in_dll(ctypes.pythonapi,"PyOS_InputHook") + + def set_inputhook(self, callback): + """DEPRECATED since IPython 5.0 + + Set PyOS_InputHook to callback and return the previous one.""" + # On platforms with 'readline' support, it's all too likely to + # have a KeyboardInterrupt signal delivered *even before* an + # initial ``try:`` clause in the callback can be executed, so + # we need to disable CTRL+C in this situation. + ignore_CTRL_C() + self._callback = callback + self._callback_pyfunctype = self.PYFUNC(callback) + pyos_inputhook_ptr = self.get_pyos_inputhook() + original = self.get_pyos_inputhook_as_func() + pyos_inputhook_ptr.value = \ + ctypes.cast(self._callback_pyfunctype, ctypes.c_void_p).value + self._installed = True + return original + + def clear_inputhook(self, app=None): + """DEPRECATED since IPython 5.0 + + Set PyOS_InputHook to NULL and return the previous one. + + Parameters + ---------- + app : optional, ignored + This parameter is allowed only so that clear_inputhook() can be + called with a similar interface as all the ``enable_*`` methods. But + the actual value of the parameter is ignored. This uniform interface + makes it easier to have user-level entry points in the main IPython + app like :meth:`enable_gui`.""" + warn("`clear_inputhook` is deprecated since IPython 5.0 and will be removed in future versions.", + DeprecationWarning, stacklevel=2) + pyos_inputhook_ptr = self.get_pyos_inputhook() + original = self.get_pyos_inputhook_as_func() + pyos_inputhook_ptr.value = ctypes.c_void_p(None).value + allow_CTRL_C() + self._reset() + return original + + def clear_app_refs(self, gui=None): + """DEPRECATED since IPython 5.0 + + Clear IPython's internal reference to an application instance. + + Whenever we create an app for a user on qt4 or wx, we hold a + reference to the app. This is needed because in some cases bad things + can happen if a user doesn't hold a reference themselves. This + method is provided to clear the references we are holding. + + Parameters + ---------- + gui : None or str + If None, clear all app references. If ('wx', 'qt4') clear + the app for that toolkit. References are not held for gtk or tk + as those toolkits don't have the notion of an app. + """ + warn("`clear_app_refs` is deprecated since IPython 5.0 and will be removed in future versions.", + DeprecationWarning, stacklevel=2) + if gui is None: + self.apps = {} + elif gui in self.apps: + del self.apps[gui] + + def register(self, toolkitname, *aliases): + """DEPRECATED since IPython 5.0 + + Register a class to provide the event loop for a given GUI. + + This is intended to be used as a class decorator. It should be passed + the names with which to register this GUI integration. The classes + themselves should subclass :class:`InputHookBase`. + + :: + + @inputhook_manager.register('qt') + class QtInputHook(InputHookBase): + def enable(self, app=None): + ... + """ + warn("`register` is deprecated since IPython 5.0 and will be removed in future versions.", + DeprecationWarning, stacklevel=2) + def decorator(cls): + if ctypes is not None: + inst = cls(self) + self.guihooks[toolkitname] = inst + for a in aliases: + self.aliases[a] = toolkitname + return cls + return decorator + + def current_gui(self): + """DEPRECATED since IPython 5.0 + + Return a string indicating the currently active GUI or None.""" + warn("`current_gui` is deprecated since IPython 5.0 and will be removed in future versions.", + DeprecationWarning, stacklevel=2) + return self._current_gui + + def enable_gui(self, gui=None, app=None): + """DEPRECATED since IPython 5.0 + + Switch amongst GUI input hooks by name. + + This is a higher level method than :meth:`set_inputhook` - it uses the + GUI name to look up a registered object which enables the input hook + for that GUI. + + Parameters + ---------- + gui : optional, string or None + If None (or 'none'), clears input hook, otherwise it must be one + of the recognized GUI names (see ``GUI_*`` constants in module). + + app : optional, existing application object. + For toolkits that have the concept of a global app, you can supply an + existing one. If not given, the toolkit will be probed for one, and if + none is found, a new one will be created. Note that GTK does not have + this concept, and passing an app if ``gui=="GTK"`` will raise an error. + + Returns + ------- + The output of the underlying gui switch routine, typically the actual + PyOS_InputHook wrapper object or the GUI toolkit app created, if there was + one. + """ + warn("`enable_gui` is deprecated since IPython 5.0 and will be removed in future versions.", + DeprecationWarning, stacklevel=2) + if gui in (None, GUI_NONE): + return self.disable_gui() + + if gui in self.aliases: + return self.enable_gui(self.aliases[gui], app) + + try: + gui_hook = self.guihooks[gui] + except KeyError: + e = "Invalid GUI request {!r}, valid ones are: {}" + raise ValueError(e.format(gui, ', '.join(self.guihooks))) + self._current_gui = gui + + app = gui_hook.enable(app) + if app is not None: + app._in_event_loop = True + self.apps[gui] = app + return app + + def disable_gui(self): + """DEPRECATED since IPython 5.0 + + Disable GUI event loop integration. + + If an application was registered, this sets its ``_in_event_loop`` + attribute to False. It then calls :meth:`clear_inputhook`. + """ + warn("`disable_gui` is deprecated since IPython 5.0 and will be removed in future versions.", + DeprecationWarning, stacklevel=2) + gui = self._current_gui + if gui in self.apps: + self.apps[gui]._in_event_loop = False + return self.clear_inputhook() + +class InputHookBase(object): + """DEPRECATED since IPython 5.0 + + Base class for input hooks for specific toolkits. + + Subclasses should define an :meth:`enable` method with one argument, ``app``, + which will either be an instance of the toolkit's application class, or None. + They may also define a :meth:`disable` method with no arguments. + """ + def __init__(self, manager): + self.manager = manager + + def disable(self): + pass + +inputhook_manager = InputHookManager() + +@inputhook_manager.register('osx') +class NullInputHook(InputHookBase): + """DEPRECATED since IPython 5.0 + + A null inputhook that doesn't need to do anything""" + def enable(self, app=None): + warn("This function is deprecated since IPython 5.0 and will be removed in future versions.", + DeprecationWarning, stacklevel=2) + +@inputhook_manager.register('wx') +class WxInputHook(InputHookBase): + def enable(self, app=None): + """DEPRECATED since IPython 5.0 + + Enable event loop integration with wxPython. + + Parameters + ---------- + app : WX Application, optional. + Running application to use. If not given, we probe WX for an + existing application object, and create a new one if none is found. + + Notes + ----- + This methods sets the ``PyOS_InputHook`` for wxPython, which allows + the wxPython to integrate with terminal based applications like + IPython. + + If ``app`` is not given we probe for an existing one, and return it if + found. If no existing app is found, we create an :class:`wx.App` as + follows:: + + import wx + app = wx.App(redirect=False, clearSigInt=False) + """ + warn("This function is deprecated since IPython 5.0 and will be removed in future versions.", + DeprecationWarning, stacklevel=2) + import wx + + wx_version = V(wx.__version__).version + + if wx_version < [2, 8]: + raise ValueError("requires wxPython >= 2.8, but you have %s" % wx.__version__) + + from IPython.lib.inputhookwx import inputhook_wx + self.manager.set_inputhook(inputhook_wx) + if _use_appnope(): + from appnope import nope + nope() + + import wx + if app is None: + app = wx.GetApp() + if app is None: + app = wx.App(redirect=False, clearSigInt=False) + + return app + + def disable(self): + """DEPRECATED since IPython 5.0 + + Disable event loop integration with wxPython. + + This restores appnapp on OS X + """ + warn("This function is deprecated since IPython 5.0 and will be removed in future versions.", + DeprecationWarning, stacklevel=2) + if _use_appnope(): + from appnope import nap + nap() + +@inputhook_manager.register('qt', 'qt4') +class Qt4InputHook(InputHookBase): + def enable(self, app=None): + """DEPRECATED since IPython 5.0 + + Enable event loop integration with PyQt4. + + Parameters + ---------- + app : Qt Application, optional. + Running application to use. If not given, we probe Qt for an + existing application object, and create a new one if none is found. + + Notes + ----- + This methods sets the PyOS_InputHook for PyQt4, which allows + the PyQt4 to integrate with terminal based applications like + IPython. + + If ``app`` is not given we probe for an existing one, and return it if + found. If no existing app is found, we create an :class:`QApplication` + as follows:: + + from PyQt4 import QtCore + app = QtGui.QApplication(sys.argv) + """ + warn("This function is deprecated since IPython 5.0 and will be removed in future versions.", + DeprecationWarning, stacklevel=2) + from IPython.lib.inputhookqt4 import create_inputhook_qt4 + app, inputhook_qt4 = create_inputhook_qt4(self.manager, app) + self.manager.set_inputhook(inputhook_qt4) + if _use_appnope(): + from appnope import nope + nope() + + return app + + def disable_qt4(self): + """DEPRECATED since IPython 5.0 + + Disable event loop integration with PyQt4. + + This restores appnapp on OS X + """ + warn("This function is deprecated since IPython 5.0 and will be removed in future versions.", + DeprecationWarning, stacklevel=2) + if _use_appnope(): + from appnope import nap + nap() + + +@inputhook_manager.register('qt5') +class Qt5InputHook(Qt4InputHook): + def enable(self, app=None): + warn("This function is deprecated since IPython 5.0 and will be removed in future versions.", + DeprecationWarning, stacklevel=2) + os.environ['QT_API'] = 'pyqt5' + return Qt4InputHook.enable(self, app) + + +@inputhook_manager.register('gtk') +class GtkInputHook(InputHookBase): + def enable(self, app=None): + """DEPRECATED since IPython 5.0 + + Enable event loop integration with PyGTK. + + Parameters + ---------- + app : ignored + Ignored, it's only a placeholder to keep the call signature of all + gui activation methods consistent, which simplifies the logic of + supporting magics. + + Notes + ----- + This methods sets the PyOS_InputHook for PyGTK, which allows + the PyGTK to integrate with terminal based applications like + IPython. + """ + warn("This function is deprecated since IPython 5.0 and will be removed in future versions.", + DeprecationWarning, stacklevel=2) + import gtk + try: + gtk.set_interactive(True) + except AttributeError: + # For older versions of gtk, use our own ctypes version + from IPython.lib.inputhookgtk import inputhook_gtk + self.manager.set_inputhook(inputhook_gtk) + + +@inputhook_manager.register('tk') +class TkInputHook(InputHookBase): + def enable(self, app=None): + """DEPRECATED since IPython 5.0 + + Enable event loop integration with Tk. + + Parameters + ---------- + app : toplevel :class:`Tkinter.Tk` widget, optional. + Running toplevel widget to use. If not given, we probe Tk for an + existing one, and create a new one if none is found. + + Notes + ----- + If you have already created a :class:`Tkinter.Tk` object, the only + thing done by this method is to register with the + :class:`InputHookManager`, since creating that object automatically + sets ``PyOS_InputHook``. + """ + warn("This function is deprecated since IPython 5.0 and will be removed in future versions.", + DeprecationWarning, stacklevel=2) + if app is None: + try: + from tkinter import Tk # Py 3 + except ImportError: + from Tkinter import Tk # Py 2 + app = Tk() + app.withdraw() + self.manager.apps[GUI_TK] = app + return app + + +@inputhook_manager.register('glut') +class GlutInputHook(InputHookBase): + def enable(self, app=None): + """DEPRECATED since IPython 5.0 + + Enable event loop integration with GLUT. + + Parameters + ---------- + + app : ignored + Ignored, it's only a placeholder to keep the call signature of all + gui activation methods consistent, which simplifies the logic of + supporting magics. + + Notes + ----- + + This methods sets the PyOS_InputHook for GLUT, which allows the GLUT to + integrate with terminal based applications like IPython. Due to GLUT + limitations, it is currently not possible to start the event loop + without first creating a window. You should thus not create another + window but use instead the created one. See 'gui-glut.py' in the + docs/examples/lib directory. + + The default screen mode is set to: + glut.GLUT_DOUBLE | glut.GLUT_RGBA | glut.GLUT_DEPTH + """ + warn("This function is deprecated since IPython 5.0 and will be removed in future versions.", + DeprecationWarning, stacklevel=2) + + import OpenGL.GLUT as glut + from IPython.lib.inputhookglut import glut_display_mode, \ + glut_close, glut_display, \ + glut_idle, inputhook_glut + + if GUI_GLUT not in self.manager.apps: + glut.glutInit( sys.argv ) + glut.glutInitDisplayMode( glut_display_mode ) + # This is specific to freeglut + if bool(glut.glutSetOption): + glut.glutSetOption( glut.GLUT_ACTION_ON_WINDOW_CLOSE, + glut.GLUT_ACTION_GLUTMAINLOOP_RETURNS ) + glut.glutCreateWindow( sys.argv[0] ) + glut.glutReshapeWindow( 1, 1 ) + glut.glutHideWindow( ) + glut.glutWMCloseFunc( glut_close ) + glut.glutDisplayFunc( glut_display ) + glut.glutIdleFunc( glut_idle ) + else: + glut.glutWMCloseFunc( glut_close ) + glut.glutDisplayFunc( glut_display ) + glut.glutIdleFunc( glut_idle) + self.manager.set_inputhook( inputhook_glut ) + + + def disable(self): + """DEPRECATED since IPython 5.0 + + Disable event loop integration with glut. + + This sets PyOS_InputHook to NULL and set the display function to a + dummy one and set the timer to a dummy timer that will be triggered + very far in the future. + """ + warn("This function is deprecated since IPython 5.0 and will be removed in future versions.", + DeprecationWarning, stacklevel=2) + import OpenGL.GLUT as glut + from glut_support import glutMainLoopEvent + + glut.glutHideWindow() # This is an event to be processed below + glutMainLoopEvent() + super(GlutInputHook, self).disable() + +@inputhook_manager.register('pyglet') +class PygletInputHook(InputHookBase): + def enable(self, app=None): + """DEPRECATED since IPython 5.0 + + Enable event loop integration with pyglet. + + Parameters + ---------- + app : ignored + Ignored, it's only a placeholder to keep the call signature of all + gui activation methods consistent, which simplifies the logic of + supporting magics. + + Notes + ----- + This methods sets the ``PyOS_InputHook`` for pyglet, which allows + pyglet to integrate with terminal based applications like + IPython. + + """ + warn("This function is deprecated since IPython 5.0 and will be removed in future versions.", + DeprecationWarning, stacklevel=2) + from IPython.lib.inputhookpyglet import inputhook_pyglet + self.manager.set_inputhook(inputhook_pyglet) + return app + + +@inputhook_manager.register('gtk3') +class Gtk3InputHook(InputHookBase): + def enable(self, app=None): + """DEPRECATED since IPython 5.0 + + Enable event loop integration with Gtk3 (gir bindings). + + Parameters + ---------- + app : ignored + Ignored, it's only a placeholder to keep the call signature of all + gui activation methods consistent, which simplifies the logic of + supporting magics. + + Notes + ----- + This methods sets the PyOS_InputHook for Gtk3, which allows + the Gtk3 to integrate with terminal based applications like + IPython. + """ + warn("This function is deprecated since IPython 5.0 and will be removed in future versions.", + DeprecationWarning, stacklevel=2) + from IPython.lib.inputhookgtk3 import inputhook_gtk3 + self.manager.set_inputhook(inputhook_gtk3) + + +clear_inputhook = inputhook_manager.clear_inputhook +set_inputhook = inputhook_manager.set_inputhook +current_gui = inputhook_manager.current_gui +clear_app_refs = inputhook_manager.clear_app_refs +enable_gui = inputhook_manager.enable_gui +disable_gui = inputhook_manager.disable_gui +register = inputhook_manager.register +guis = inputhook_manager.guihooks + + +def _deprecated_disable(): + warn("This function is deprecated since IPython 4.0 use disable_gui() instead", + DeprecationWarning, stacklevel=2) + inputhook_manager.disable_gui() + +disable_wx = disable_qt4 = disable_gtk = disable_gtk3 = disable_glut = \ + disable_pyglet = disable_osx = _deprecated_disable diff --git a/.venv/lib/python3.8/site-packages/IPython/lib/inputhookglut.py b/.venv/lib/python3.8/site-packages/IPython/lib/inputhookglut.py new file mode 100644 index 00000000..e6f7f125 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/IPython/lib/inputhookglut.py @@ -0,0 +1,172 @@ +# coding: utf-8 +""" +GLUT Inputhook support functions +""" + +#----------------------------------------------------------------------------- +# Copyright (C) 2008-2011 The IPython Development Team +# +# Distributed under the terms of the BSD License. The full license is in +# the file COPYING, distributed as part of this software. +#----------------------------------------------------------------------------- + +# GLUT is quite an old library and it is difficult to ensure proper +# integration within IPython since original GLUT does not allow to handle +# events one by one. Instead, it requires for the mainloop to be entered +# and never returned (there is not even a function to exit he +# mainloop). Fortunately, there are alternatives such as freeglut +# (available for linux and windows) and the OSX implementation gives +# access to a glutCheckLoop() function that blocks itself until a new +# event is received. This means we have to setup the idle callback to +# ensure we got at least one event that will unblock the function. +# +# Furthermore, it is not possible to install these handlers without a window +# being first created. We choose to make this window invisible. This means that +# display mode options are set at this level and user won't be able to change +# them later without modifying the code. This should probably be made available +# via IPython options system. + +#----------------------------------------------------------------------------- +# Imports +#----------------------------------------------------------------------------- +import os +import sys +import time +import signal +import OpenGL.GLUT as glut +import OpenGL.platform as platform +from timeit import default_timer as clock + +#----------------------------------------------------------------------------- +# Constants +#----------------------------------------------------------------------------- + +# Frame per second : 60 +# Should probably be an IPython option +glut_fps = 60 + + +# Display mode : double buffeed + rgba + depth +# Should probably be an IPython option +glut_display_mode = (glut.GLUT_DOUBLE | + glut.GLUT_RGBA | + glut.GLUT_DEPTH) + +glutMainLoopEvent = None +if sys.platform == 'darwin': + try: + glutCheckLoop = platform.createBaseFunction( + 'glutCheckLoop', dll=platform.GLUT, resultType=None, + argTypes=[], + doc='glutCheckLoop( ) -> None', + argNames=(), + ) + except AttributeError: + raise RuntimeError( + '''Your glut implementation does not allow interactive sessions''' + '''Consider installing freeglut.''') + glutMainLoopEvent = glutCheckLoop +elif glut.HAVE_FREEGLUT: + glutMainLoopEvent = glut.glutMainLoopEvent +else: + raise RuntimeError( + '''Your glut implementation does not allow interactive sessions. ''' + '''Consider installing freeglut.''') + + +#----------------------------------------------------------------------------- +# Platform-dependent imports and functions +#----------------------------------------------------------------------------- + +if os.name == 'posix': + import select + + def stdin_ready(): + infds, outfds, erfds = select.select([sys.stdin],[],[],0) + if infds: + return True + else: + return False + +elif sys.platform == 'win32': + import msvcrt + + def stdin_ready(): + return msvcrt.kbhit() + +#----------------------------------------------------------------------------- +# Callback functions +#----------------------------------------------------------------------------- + +def glut_display(): + # Dummy display function + pass + +def glut_idle(): + # Dummy idle function + pass + +def glut_close(): + # Close function only hides the current window + glut.glutHideWindow() + glutMainLoopEvent() + +def glut_int_handler(signum, frame): + # Catch sigint and print the default message + signal.signal(signal.SIGINT, signal.default_int_handler) + print('\nKeyboardInterrupt') + # Need to reprint the prompt at this stage + + + +#----------------------------------------------------------------------------- +# Code +#----------------------------------------------------------------------------- +def inputhook_glut(): + """Run the pyglet event loop by processing pending events only. + + This keeps processing pending events until stdin is ready. After + processing all pending events, a call to time.sleep is inserted. This is + needed, otherwise, CPU usage is at 100%. This sleep time should be tuned + though for best performance. + """ + # We need to protect against a user pressing Control-C when IPython is + # idle and this is running. We trap KeyboardInterrupt and pass. + + signal.signal(signal.SIGINT, glut_int_handler) + + try: + t = clock() + + # Make sure the default window is set after a window has been closed + if glut.glutGetWindow() == 0: + glut.glutSetWindow( 1 ) + glutMainLoopEvent() + return 0 + + while not stdin_ready(): + glutMainLoopEvent() + # We need to sleep at this point to keep the idle CPU load + # low. However, if sleep to long, GUI response is poor. As + # a compromise, we watch how often GUI events are being processed + # and switch between a short and long sleep time. Here are some + # stats useful in helping to tune this. + # time CPU load + # 0.001 13% + # 0.005 3% + # 0.01 1.5% + # 0.05 0.5% + used_time = clock() - t + if used_time > 10.0: + # print 'Sleep for 1 s' # dbg + time.sleep(1.0) + elif used_time > 0.1: + # Few GUI events coming in, so we can sleep longer + # print 'Sleep for 0.05 s' # dbg + time.sleep(0.05) + else: + # Many GUI events coming in, so sleep only very little + time.sleep(0.001) + except KeyboardInterrupt: + pass + return 0 diff --git a/.venv/lib/python3.8/site-packages/IPython/lib/inputhookgtk.py b/.venv/lib/python3.8/site-packages/IPython/lib/inputhookgtk.py new file mode 100644 index 00000000..98569f54 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/IPython/lib/inputhookgtk.py @@ -0,0 +1,35 @@ +# encoding: utf-8 +""" +Enable pygtk to be used interactively by setting PyOS_InputHook. + +Authors: Brian Granger +""" + +#----------------------------------------------------------------------------- +# Copyright (C) 2008-2011 The IPython Development Team +# +# Distributed under the terms of the BSD License. The full license is in +# the file COPYING, distributed as part of this software. +#----------------------------------------------------------------------------- + +#----------------------------------------------------------------------------- +# Imports +#----------------------------------------------------------------------------- + +import sys +import gtk, gobject + +#----------------------------------------------------------------------------- +# Code +#----------------------------------------------------------------------------- + + +def _main_quit(*args, **kwargs): + gtk.main_quit() + return False + +def inputhook_gtk(): + gobject.io_add_watch(sys.stdin, gobject.IO_IN, _main_quit) + gtk.main() + return 0 + diff --git a/.venv/lib/python3.8/site-packages/IPython/lib/inputhookgtk3.py b/.venv/lib/python3.8/site-packages/IPython/lib/inputhookgtk3.py new file mode 100644 index 00000000..b797e862 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/IPython/lib/inputhookgtk3.py @@ -0,0 +1,34 @@ +# encoding: utf-8 +""" +Enable Gtk3 to be used interactively by IPython. + +Authors: Thomi Richards +""" +#----------------------------------------------------------------------------- +# Copyright (c) 2012, the IPython Development Team. +# +# Distributed under the terms of the Modified BSD License. +# +# The full license is in the file COPYING.txt, distributed with this software. +#----------------------------------------------------------------------------- + +#----------------------------------------------------------------------------- +# Imports +#----------------------------------------------------------------------------- + +import sys +from gi.repository import Gtk, GLib + +#----------------------------------------------------------------------------- +# Code +#----------------------------------------------------------------------------- + +def _main_quit(*args, **kwargs): + Gtk.main_quit() + return False + + +def inputhook_gtk3(): + GLib.io_add_watch(sys.stdin, GLib.PRIORITY_DEFAULT, GLib.IO_IN, _main_quit) + Gtk.main() + return 0 diff --git a/.venv/lib/python3.8/site-packages/IPython/lib/inputhookpyglet.py b/.venv/lib/python3.8/site-packages/IPython/lib/inputhookpyglet.py new file mode 100644 index 00000000..fb91ffed --- /dev/null +++ b/.venv/lib/python3.8/site-packages/IPython/lib/inputhookpyglet.py @@ -0,0 +1,111 @@ +# encoding: utf-8 +""" +Enable pyglet to be used interactively by setting PyOS_InputHook. + +Authors +------- + +* Nicolas P. Rougier +* Fernando Perez +""" + +#----------------------------------------------------------------------------- +# Copyright (C) 2008-2011 The IPython Development Team +# +# Distributed under the terms of the BSD License. The full license is in +# the file COPYING, distributed as part of this software. +#----------------------------------------------------------------------------- + +#----------------------------------------------------------------------------- +# Imports +#----------------------------------------------------------------------------- + +import os +import sys +import time +from timeit import default_timer as clock +import pyglet + +#----------------------------------------------------------------------------- +# Platform-dependent imports and functions +#----------------------------------------------------------------------------- + +if os.name == 'posix': + import select + + def stdin_ready(): + infds, outfds, erfds = select.select([sys.stdin],[],[],0) + if infds: + return True + else: + return False + +elif sys.platform == 'win32': + import msvcrt + + def stdin_ready(): + return msvcrt.kbhit() + + +# On linux only, window.flip() has a bug that causes an AttributeError on +# window close. For details, see: +# http://groups.google.com/group/pyglet-users/browse_thread/thread/47c1aab9aa4a3d23/c22f9e819826799e?#c22f9e819826799e + +if sys.platform.startswith('linux'): + def flip(window): + try: + window.flip() + except AttributeError: + pass +else: + def flip(window): + window.flip() + +#----------------------------------------------------------------------------- +# Code +#----------------------------------------------------------------------------- + +def inputhook_pyglet(): + """Run the pyglet event loop by processing pending events only. + + This keeps processing pending events until stdin is ready. After + processing all pending events, a call to time.sleep is inserted. This is + needed, otherwise, CPU usage is at 100%. This sleep time should be tuned + though for best performance. + """ + # We need to protect against a user pressing Control-C when IPython is + # idle and this is running. We trap KeyboardInterrupt and pass. + try: + t = clock() + while not stdin_ready(): + pyglet.clock.tick() + for window in pyglet.app.windows: + window.switch_to() + window.dispatch_events() + window.dispatch_event('on_draw') + flip(window) + + # We need to sleep at this point to keep the idle CPU load + # low. However, if sleep to long, GUI response is poor. As + # a compromise, we watch how often GUI events are being processed + # and switch between a short and long sleep time. Here are some + # stats useful in helping to tune this. + # time CPU load + # 0.001 13% + # 0.005 3% + # 0.01 1.5% + # 0.05 0.5% + used_time = clock() - t + if used_time > 10.0: + # print 'Sleep for 1 s' # dbg + time.sleep(1.0) + elif used_time > 0.1: + # Few GUI events coming in, so we can sleep longer + # print 'Sleep for 0.05 s' # dbg + time.sleep(0.05) + else: + # Many GUI events coming in, so sleep only very little + time.sleep(0.001) + except KeyboardInterrupt: + pass + return 0 diff --git a/.venv/lib/python3.8/site-packages/IPython/lib/inputhookqt4.py b/.venv/lib/python3.8/site-packages/IPython/lib/inputhookqt4.py new file mode 100644 index 00000000..8a83902f --- /dev/null +++ b/.venv/lib/python3.8/site-packages/IPython/lib/inputhookqt4.py @@ -0,0 +1,180 @@ +# -*- coding: utf-8 -*- +""" +Qt4's inputhook support function + +Author: Christian Boos +""" + +#----------------------------------------------------------------------------- +# Copyright (C) 2011 The IPython Development Team +# +# Distributed under the terms of the BSD License. The full license is in +# the file COPYING, distributed as part of this software. +#----------------------------------------------------------------------------- + +#----------------------------------------------------------------------------- +# Imports +#----------------------------------------------------------------------------- + +import os +import signal +import threading + +from IPython.core.interactiveshell import InteractiveShell +from IPython.external.qt_for_kernel import QtCore, QtGui +from IPython.lib.inputhook import allow_CTRL_C, ignore_CTRL_C, stdin_ready + +#----------------------------------------------------------------------------- +# Module Globals +#----------------------------------------------------------------------------- + +got_kbdint = False +sigint_timer = None + +#----------------------------------------------------------------------------- +# Code +#----------------------------------------------------------------------------- + +def create_inputhook_qt4(mgr, app=None): + """Create an input hook for running the Qt4 application event loop. + + Parameters + ---------- + mgr : an InputHookManager + + app : Qt Application, optional. + Running application to use. If not given, we probe Qt for an + existing application object, and create a new one if none is found. + + Returns + ------- + A pair consisting of a Qt Application (either the one given or the + one found or created) and a inputhook. + + Notes + ----- + We use a custom input hook instead of PyQt4's default one, as it + interacts better with the readline packages (issue #481). + + The inputhook function works in tandem with a 'pre_prompt_hook' + which automatically restores the hook as an inputhook in case the + latter has been temporarily disabled after having intercepted a + KeyboardInterrupt. + """ + + if app is None: + app = QtCore.QCoreApplication.instance() + if app is None: + app = QtGui.QApplication([" "]) + + # Re-use previously created inputhook if any + ip = InteractiveShell.instance() + if hasattr(ip, '_inputhook_qt4'): + return app, ip._inputhook_qt4 + + # Otherwise create the inputhook_qt4/preprompthook_qt4 pair of + # hooks (they both share the got_kbdint flag) + + def inputhook_qt4(): + """PyOS_InputHook python hook for Qt4. + + Process pending Qt events and if there's no pending keyboard + input, spend a short slice of time (50ms) running the Qt event + loop. + + As a Python ctypes callback can't raise an exception, we catch + the KeyboardInterrupt and temporarily deactivate the hook, + which will let a *second* CTRL+C be processed normally and go + back to a clean prompt line. + """ + try: + allow_CTRL_C() + app = QtCore.QCoreApplication.instance() + if not app: # shouldn't happen, but safer if it happens anyway... + return 0 + app.processEvents(QtCore.QEventLoop.AllEvents, 300) + if not stdin_ready(): + # Generally a program would run QCoreApplication::exec() + # from main() to enter and process the Qt event loop until + # quit() or exit() is called and the program terminates. + # + # For our input hook integration, we need to repeatedly + # enter and process the Qt event loop for only a short + # amount of time (say 50ms) to ensure that Python stays + # responsive to other user inputs. + # + # A naive approach would be to repeatedly call + # QCoreApplication::exec(), using a timer to quit after a + # short amount of time. Unfortunately, QCoreApplication + # emits an aboutToQuit signal before stopping, which has + # the undesirable effect of closing all modal windows. + # + # To work around this problem, we instead create a + # QEventLoop and call QEventLoop::exec(). Other than + # setting some state variables which do not seem to be + # used anywhere, the only thing QCoreApplication adds is + # the aboutToQuit signal which is precisely what we are + # trying to avoid. + timer = QtCore.QTimer() + event_loop = QtCore.QEventLoop() + timer.timeout.connect(event_loop.quit) + while not stdin_ready(): + timer.start(50) + event_loop.exec_() + timer.stop() + except KeyboardInterrupt: + global got_kbdint, sigint_timer + + ignore_CTRL_C() + got_kbdint = True + mgr.clear_inputhook() + + # This generates a second SIGINT so the user doesn't have to + # press CTRL+C twice to get a clean prompt. + # + # Since we can't catch the resulting KeyboardInterrupt here + # (because this is a ctypes callback), we use a timer to + # generate the SIGINT after we leave this callback. + # + # Unfortunately this doesn't work on Windows (SIGINT kills + # Python and CTRL_C_EVENT doesn't work). + if(os.name == 'posix'): + pid = os.getpid() + if(not sigint_timer): + sigint_timer = threading.Timer(.01, os.kill, + args=[pid, signal.SIGINT] ) + sigint_timer.start() + else: + print("\nKeyboardInterrupt - Ctrl-C again for new prompt") + + + except: # NO exceptions are allowed to escape from a ctypes callback + ignore_CTRL_C() + from traceback import print_exc + print_exc() + print("Got exception from inputhook_qt4, unregistering.") + mgr.clear_inputhook() + finally: + allow_CTRL_C() + return 0 + + def preprompthook_qt4(ishell): + """'pre_prompt_hook' used to restore the Qt4 input hook + + (in case the latter was temporarily deactivated after a + CTRL+C) + """ + global got_kbdint, sigint_timer + + if(sigint_timer): + sigint_timer.cancel() + sigint_timer = None + + if got_kbdint: + mgr.set_inputhook(inputhook_qt4) + got_kbdint = False + + ip._inputhook_qt4 = inputhook_qt4 + ip.set_hook('pre_prompt_hook', preprompthook_qt4) + + return app, inputhook_qt4 diff --git a/.venv/lib/python3.8/site-packages/IPython/lib/inputhookwx.py b/.venv/lib/python3.8/site-packages/IPython/lib/inputhookwx.py new file mode 100644 index 00000000..60520a29 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/IPython/lib/inputhookwx.py @@ -0,0 +1,167 @@ +# encoding: utf-8 + +""" +Enable wxPython to be used interactively by setting PyOS_InputHook. + +Authors: Robin Dunn, Brian Granger, Ondrej Certik +""" + +#----------------------------------------------------------------------------- +# Copyright (C) 2008-2011 The IPython Development Team +# +# Distributed under the terms of the BSD License. The full license is in +# the file COPYING, distributed as part of this software. +#----------------------------------------------------------------------------- + +#----------------------------------------------------------------------------- +# Imports +#----------------------------------------------------------------------------- + +import sys +import signal +import time +from timeit import default_timer as clock +import wx + +from IPython.lib.inputhook import stdin_ready + + +#----------------------------------------------------------------------------- +# Code +#----------------------------------------------------------------------------- + +def inputhook_wx1(): + """Run the wx event loop by processing pending events only. + + This approach seems to work, but its performance is not great as it + relies on having PyOS_InputHook called regularly. + """ + try: + app = wx.GetApp() + if app is not None: + assert wx.Thread_IsMain() + + # Make a temporary event loop and process system events until + # there are no more waiting, then allow idle events (which + # will also deal with pending or posted wx events.) + evtloop = wx.EventLoop() + ea = wx.EventLoopActivator(evtloop) + while evtloop.Pending(): + evtloop.Dispatch() + app.ProcessIdle() + del ea + except KeyboardInterrupt: + pass + return 0 + +class EventLoopTimer(wx.Timer): + + def __init__(self, func): + self.func = func + wx.Timer.__init__(self) + + def Notify(self): + self.func() + +class EventLoopRunner(object): + + def Run(self, time): + self.evtloop = wx.EventLoop() + self.timer = EventLoopTimer(self.check_stdin) + self.timer.Start(time) + self.evtloop.Run() + + def check_stdin(self): + if stdin_ready(): + self.timer.Stop() + self.evtloop.Exit() + +def inputhook_wx2(): + """Run the wx event loop, polling for stdin. + + This version runs the wx eventloop for an undetermined amount of time, + during which it periodically checks to see if anything is ready on + stdin. If anything is ready on stdin, the event loop exits. + + The argument to elr.Run controls how often the event loop looks at stdin. + This determines the responsiveness at the keyboard. A setting of 1000 + enables a user to type at most 1 char per second. I have found that a + setting of 10 gives good keyboard response. We can shorten it further, + but eventually performance would suffer from calling select/kbhit too + often. + """ + try: + app = wx.GetApp() + if app is not None: + assert wx.Thread_IsMain() + elr = EventLoopRunner() + # As this time is made shorter, keyboard response improves, but idle + # CPU load goes up. 10 ms seems like a good compromise. + elr.Run(time=10) # CHANGE time here to control polling interval + except KeyboardInterrupt: + pass + return 0 + +def inputhook_wx3(): + """Run the wx event loop by processing pending events only. + + This is like inputhook_wx1, but it keeps processing pending events + until stdin is ready. After processing all pending events, a call to + time.sleep is inserted. This is needed, otherwise, CPU usage is at 100%. + This sleep time should be tuned though for best performance. + """ + # We need to protect against a user pressing Control-C when IPython is + # idle and this is running. We trap KeyboardInterrupt and pass. + try: + app = wx.GetApp() + if app is not None: + assert wx.Thread_IsMain() + + # The import of wx on Linux sets the handler for signal.SIGINT + # to 0. This is a bug in wx or gtk. We fix by just setting it + # back to the Python default. + if not callable(signal.getsignal(signal.SIGINT)): + signal.signal(signal.SIGINT, signal.default_int_handler) + + evtloop = wx.EventLoop() + ea = wx.EventLoopActivator(evtloop) + t = clock() + while not stdin_ready(): + while evtloop.Pending(): + t = clock() + evtloop.Dispatch() + app.ProcessIdle() + # We need to sleep at this point to keep the idle CPU load + # low. However, if sleep to long, GUI response is poor. As + # a compromise, we watch how often GUI events are being processed + # and switch between a short and long sleep time. Here are some + # stats useful in helping to tune this. + # time CPU load + # 0.001 13% + # 0.005 3% + # 0.01 1.5% + # 0.05 0.5% + used_time = clock() - t + if used_time > 10.0: + # print 'Sleep for 1 s' # dbg + time.sleep(1.0) + elif used_time > 0.1: + # Few GUI events coming in, so we can sleep longer + # print 'Sleep for 0.05 s' # dbg + time.sleep(0.05) + else: + # Many GUI events coming in, so sleep only very little + time.sleep(0.001) + del ea + except KeyboardInterrupt: + pass + return 0 + +if sys.platform == 'darwin': + # On OSX, evtloop.Pending() always returns True, regardless of there being + # any events pending. As such we can't use implementations 1 or 3 of the + # inputhook as those depend on a pending/dispatch loop. + inputhook_wx = inputhook_wx2 +else: + # This is our default implementation + inputhook_wx = inputhook_wx3 diff --git a/.venv/lib/python3.8/site-packages/IPython/lib/kernel.py b/.venv/lib/python3.8/site-packages/IPython/lib/kernel.py new file mode 100644 index 00000000..af982766 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/IPython/lib/kernel.py @@ -0,0 +1,13 @@ +"""[DEPRECATED] Utilities for connecting to kernels + +Moved to IPython.kernel.connect +""" + +import warnings +warnings.warn("IPython.lib.kernel moved to IPython.kernel.connect in IPython 1.0," + " and will be removed in IPython 6.0.", + DeprecationWarning +) + +from ipykernel.connect import * + diff --git a/.venv/lib/python3.8/site-packages/IPython/lib/latextools.py b/.venv/lib/python3.8/site-packages/IPython/lib/latextools.py new file mode 100644 index 00000000..cbcc7d96 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/IPython/lib/latextools.py @@ -0,0 +1,220 @@ +# -*- coding: utf-8 -*- +"""Tools for handling LaTeX.""" + +# Copyright (c) IPython Development Team. +# Distributed under the terms of the Modified BSD License. + +from io import BytesIO, open +import os +import tempfile +import shutil +import subprocess +from base64 import encodebytes +import textwrap + +from IPython.utils.process import find_cmd, FindCmdError +from traitlets.config import get_config +from traitlets.config.configurable import SingletonConfigurable +from traitlets import List, Bool, Unicode +from IPython.utils.py3compat import cast_unicode + + +class LaTeXTool(SingletonConfigurable): + """An object to store configuration of the LaTeX tool.""" + def _config_default(self): + return get_config() + + backends = List( + Unicode(), ["matplotlib", "dvipng"], + help="Preferred backend to draw LaTeX math equations. " + "Backends in the list are checked one by one and the first " + "usable one is used. Note that `matplotlib` backend " + "is usable only for inline style equations. To draw " + "display style equations, `dvipng` backend must be specified. ", + # It is a List instead of Enum, to make configuration more + # flexible. For example, to use matplotlib mainly but dvipng + # for display style, the default ["matplotlib", "dvipng"] can + # be used. To NOT use dvipng so that other repr such as + # unicode pretty printing is used, you can use ["matplotlib"]. + ).tag(config=True) + + use_breqn = Bool( + True, + help="Use breqn.sty to automatically break long equations. " + "This configuration takes effect only for dvipng backend.", + ).tag(config=True) + + packages = List( + ['amsmath', 'amsthm', 'amssymb', 'bm'], + help="A list of packages to use for dvipng backend. " + "'breqn' will be automatically appended when use_breqn=True.", + ).tag(config=True) + + preamble = Unicode( + help="Additional preamble to use when generating LaTeX source " + "for dvipng backend.", + ).tag(config=True) + + +def latex_to_png(s, encode=False, backend=None, wrap=False, color='Black', + scale=1.0): + """Render a LaTeX string to PNG. + + Parameters + ---------- + s : str + The raw string containing valid inline LaTeX. + encode : bool, optional + Should the PNG data base64 encoded to make it JSON'able. + backend : {matplotlib, dvipng} + Backend for producing PNG data. + wrap : bool + If true, Automatically wrap `s` as a LaTeX equation. + color : string + Foreground color name among dvipsnames, e.g. 'Maroon' or on hex RGB + format, e.g. '#AA20FA'. + scale : float + Scale factor for the resulting PNG. + + None is returned when the backend cannot be used. + + """ + s = cast_unicode(s) + allowed_backends = LaTeXTool.instance().backends + if backend is None: + backend = allowed_backends[0] + if backend not in allowed_backends: + return None + if backend == 'matplotlib': + f = latex_to_png_mpl + elif backend == 'dvipng': + f = latex_to_png_dvipng + if color.startswith('#'): + # Convert hex RGB color to LaTeX RGB color. + if len(color) == 7: + try: + color = "RGB {}".format(" ".join([str(int(x, 16)) for x in + textwrap.wrap(color[1:], 2)])) + except ValueError: + raise ValueError('Invalid color specification {}.'.format(color)) + else: + raise ValueError('Invalid color specification {}.'.format(color)) + else: + raise ValueError('No such backend {0}'.format(backend)) + bin_data = f(s, wrap, color, scale) + if encode and bin_data: + bin_data = encodebytes(bin_data) + return bin_data + + +def latex_to_png_mpl(s, wrap, color='Black', scale=1.0): + try: + from matplotlib import mathtext + from pyparsing import ParseFatalException + except ImportError: + return None + + # mpl mathtext doesn't support display math, force inline + s = s.replace('$$', '$') + if wrap: + s = u'${0}$'.format(s) + + try: + mt = mathtext.MathTextParser('bitmap') + f = BytesIO() + dpi = 120*scale + mt.to_png(f, s, fontsize=12, dpi=dpi, color=color) + return f.getvalue() + except (ValueError, RuntimeError, ParseFatalException): + return None + + +def latex_to_png_dvipng(s, wrap, color='Black', scale=1.0): + try: + find_cmd('latex') + find_cmd('dvipng') + except FindCmdError: + return None + try: + workdir = tempfile.mkdtemp() + tmpfile = os.path.join(workdir, "tmp.tex") + dvifile = os.path.join(workdir, "tmp.dvi") + outfile = os.path.join(workdir, "tmp.png") + + with open(tmpfile, "w", encoding='utf8') as f: + f.writelines(genelatex(s, wrap)) + + with open(os.devnull, 'wb') as devnull: + subprocess.check_call( + ["latex", "-halt-on-error", "-interaction", "batchmode", tmpfile], + cwd=workdir, stdout=devnull, stderr=devnull) + + resolution = round(150*scale) + subprocess.check_call( + ["dvipng", "-T", "tight", "-D", str(resolution), "-z", "9", + "-bg", "transparent", "-o", outfile, dvifile, "-fg", color], + cwd=workdir, stdout=devnull, stderr=devnull) + + with open(outfile, "rb") as f: + return f.read() + except subprocess.CalledProcessError: + return None + finally: + shutil.rmtree(workdir) + + +def kpsewhich(filename): + """Invoke kpsewhich command with an argument `filename`.""" + try: + find_cmd("kpsewhich") + proc = subprocess.Popen( + ["kpsewhich", filename], + stdout=subprocess.PIPE, stderr=subprocess.PIPE) + (stdout, stderr) = proc.communicate() + return stdout.strip().decode('utf8', 'replace') + except FindCmdError: + pass + + +def genelatex(body, wrap): + """Generate LaTeX document for dvipng backend.""" + lt = LaTeXTool.instance() + breqn = wrap and lt.use_breqn and kpsewhich("breqn.sty") + yield r'\documentclass{article}' + packages = lt.packages + if breqn: + packages = packages + ['breqn'] + for pack in packages: + yield r'\usepackage{{{0}}}'.format(pack) + yield r'\pagestyle{empty}' + if lt.preamble: + yield lt.preamble + yield r'\begin{document}' + if breqn: + yield r'\begin{dmath*}' + yield body + yield r'\end{dmath*}' + elif wrap: + yield u'$${0}$$'.format(body) + else: + yield body + yield u'\\end{document}' + + +_data_uri_template_png = u"""%s""" + +def latex_to_html(s, alt='image'): + """Render LaTeX to HTML with embedded PNG data using data URIs. + + Parameters + ---------- + s : str + The raw string containing valid inline LateX. + alt : str + The alt text to use for the HTML. + """ + base64_data = latex_to_png(s, encode=True).decode('ascii') + if base64_data: + return _data_uri_template_png % (base64_data, alt) + + diff --git a/.venv/lib/python3.8/site-packages/IPython/lib/lexers.py b/.venv/lib/python3.8/site-packages/IPython/lib/lexers.py new file mode 100644 index 00000000..4494da56 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/IPython/lib/lexers.py @@ -0,0 +1,532 @@ +# -*- coding: utf-8 -*- +""" +Defines a variety of Pygments lexers for highlighting IPython code. + +This includes: + + IPythonLexer, IPython3Lexer + Lexers for pure IPython (python + magic/shell commands) + + IPythonPartialTracebackLexer, IPythonTracebackLexer + Supports 2.x and 3.x via keyword `python3`. The partial traceback + lexer reads everything but the Python code appearing in a traceback. + The full lexer combines the partial lexer with an IPython lexer. + + IPythonConsoleLexer + A lexer for IPython console sessions, with support for tracebacks. + + IPyLexer + A friendly lexer which examines the first line of text and from it, + decides whether to use an IPython lexer or an IPython console lexer. + This is probably the only lexer that needs to be explicitly added + to Pygments. + +""" +#----------------------------------------------------------------------------- +# Copyright (c) 2013, the IPython Development Team. +# +# Distributed under the terms of the Modified BSD License. +# +# The full license is in the file COPYING.txt, distributed with this software. +#----------------------------------------------------------------------------- + +# Standard library +import re + +# Third party +from pygments.lexers import ( + BashLexer, HtmlLexer, JavascriptLexer, RubyLexer, PerlLexer, PythonLexer, + Python3Lexer, TexLexer) +from pygments.lexer import ( + Lexer, DelegatingLexer, RegexLexer, do_insertions, bygroups, using, +) +from pygments.token import ( + Generic, Keyword, Literal, Name, Operator, Other, Text, Error, +) +from pygments.util import get_bool_opt + +# Local + +line_re = re.compile('.*?\n') + +__all__ = ['build_ipy_lexer', 'IPython3Lexer', 'IPythonLexer', + 'IPythonPartialTracebackLexer', 'IPythonTracebackLexer', + 'IPythonConsoleLexer', 'IPyLexer'] + + +def build_ipy_lexer(python3): + """Builds IPython lexers depending on the value of `python3`. + + The lexer inherits from an appropriate Python lexer and then adds + information about IPython specific keywords (i.e. magic commands, + shell commands, etc.) + + Parameters + ---------- + python3 : bool + If `True`, then build an IPython lexer from a Python 3 lexer. + + """ + # It would be nice to have a single IPython lexer class which takes + # a boolean `python3`. But since there are two Python lexer classes, + # we will also have two IPython lexer classes. + if python3: + PyLexer = Python3Lexer + name = 'IPython3' + aliases = ['ipython3'] + doc = """IPython3 Lexer""" + else: + PyLexer = PythonLexer + name = 'IPython' + aliases = ['ipython2', 'ipython'] + doc = """IPython Lexer""" + + ipython_tokens = [ + (r'(?s)(\s*)(%%capture)([^\n]*\n)(.*)', bygroups(Text, Operator, Text, using(PyLexer))), + (r'(?s)(\s*)(%%debug)([^\n]*\n)(.*)', bygroups(Text, Operator, Text, using(PyLexer))), + (r'(?is)(\s*)(%%html)([^\n]*\n)(.*)', bygroups(Text, Operator, Text, using(HtmlLexer))), + (r'(?s)(\s*)(%%javascript)([^\n]*\n)(.*)', bygroups(Text, Operator, Text, using(JavascriptLexer))), + (r'(?s)(\s*)(%%js)([^\n]*\n)(.*)', bygroups(Text, Operator, Text, using(JavascriptLexer))), + (r'(?s)(\s*)(%%latex)([^\n]*\n)(.*)', bygroups(Text, Operator, Text, using(TexLexer))), + (r'(?s)(\s*)(%%perl)([^\n]*\n)(.*)', bygroups(Text, Operator, Text, using(PerlLexer))), + (r'(?s)(\s*)(%%prun)([^\n]*\n)(.*)', bygroups(Text, Operator, Text, using(PyLexer))), + (r'(?s)(\s*)(%%pypy)([^\n]*\n)(.*)', bygroups(Text, Operator, Text, using(PyLexer))), + (r'(?s)(\s*)(%%python)([^\n]*\n)(.*)', bygroups(Text, Operator, Text, using(PyLexer))), + (r'(?s)(\s*)(%%python2)([^\n]*\n)(.*)', bygroups(Text, Operator, Text, using(PythonLexer))), + (r'(?s)(\s*)(%%python3)([^\n]*\n)(.*)', bygroups(Text, Operator, Text, using(Python3Lexer))), + (r'(?s)(\s*)(%%ruby)([^\n]*\n)(.*)', bygroups(Text, Operator, Text, using(RubyLexer))), + (r'(?s)(\s*)(%%time)([^\n]*\n)(.*)', bygroups(Text, Operator, Text, using(PyLexer))), + (r'(?s)(\s*)(%%timeit)([^\n]*\n)(.*)', bygroups(Text, Operator, Text, using(PyLexer))), + (r'(?s)(\s*)(%%writefile)([^\n]*\n)(.*)', bygroups(Text, Operator, Text, using(PyLexer))), + (r'(?s)(\s*)(%%file)([^\n]*\n)(.*)', bygroups(Text, Operator, Text, using(PyLexer))), + (r"(?s)(\s*)(%%)(\w+)(.*)", bygroups(Text, Operator, Keyword, Text)), + (r'(?s)(^\s*)(%%!)([^\n]*\n)(.*)', bygroups(Text, Operator, Text, using(BashLexer))), + (r"(%%?)(\w+)(\?\??)$", bygroups(Operator, Keyword, Operator)), + (r"\b(\?\??)(\s*)$", bygroups(Operator, Text)), + (r'(%)(sx|sc|system)(.*)(\n)', bygroups(Operator, Keyword, + using(BashLexer), Text)), + (r'(%)(\w+)(.*\n)', bygroups(Operator, Keyword, Text)), + (r'^(!!)(.+)(\n)', bygroups(Operator, using(BashLexer), Text)), + (r'(!)(?!=)(.+)(\n)', bygroups(Operator, using(BashLexer), Text)), + (r'^(\s*)(\?\??)(\s*%{0,2}[\w\.\*]*)', bygroups(Text, Operator, Text)), + (r'(\s*%{0,2}[\w\.\*]*)(\?\??)(\s*)$', bygroups(Text, Operator, Text)), + ] + + tokens = PyLexer.tokens.copy() + tokens['root'] = ipython_tokens + tokens['root'] + + attrs = {'name': name, 'aliases': aliases, 'filenames': [], + '__doc__': doc, 'tokens': tokens} + + return type(name, (PyLexer,), attrs) + + +IPython3Lexer = build_ipy_lexer(python3=True) +IPythonLexer = build_ipy_lexer(python3=False) + + +class IPythonPartialTracebackLexer(RegexLexer): + """ + Partial lexer for IPython tracebacks. + + Handles all the non-python output. + + """ + name = 'IPython Partial Traceback' + + tokens = { + 'root': [ + # Tracebacks for syntax errors have a different style. + # For both types of tracebacks, we mark the first line with + # Generic.Traceback. For syntax errors, we mark the filename + # as we mark the filenames for non-syntax tracebacks. + # + # These two regexps define how IPythonConsoleLexer finds a + # traceback. + # + ## Non-syntax traceback + (r'^(\^C)?(-+\n)', bygroups(Error, Generic.Traceback)), + ## Syntax traceback + (r'^( File)(.*)(, line )(\d+\n)', + bygroups(Generic.Traceback, Name.Namespace, + Generic.Traceback, Literal.Number.Integer)), + + # (Exception Identifier)(Whitespace)(Traceback Message) + (r'(?u)(^[^\d\W]\w*)(\s*)(Traceback.*?\n)', + bygroups(Name.Exception, Generic.Whitespace, Text)), + # (Module/Filename)(Text)(Callee)(Function Signature) + # Better options for callee and function signature? + (r'(.*)( in )(.*)(\(.*\)\n)', + bygroups(Name.Namespace, Text, Name.Entity, Name.Tag)), + # Regular line: (Whitespace)(Line Number)(Python Code) + (r'(\s*?)(\d+)(.*?\n)', + bygroups(Generic.Whitespace, Literal.Number.Integer, Other)), + # Emphasized line: (Arrow)(Line Number)(Python Code) + # Using Exception token so arrow color matches the Exception. + (r'(-*>?\s?)(\d+)(.*?\n)', + bygroups(Name.Exception, Literal.Number.Integer, Other)), + # (Exception Identifier)(Message) + (r'(?u)(^[^\d\W]\w*)(:.*?\n)', + bygroups(Name.Exception, Text)), + # Tag everything else as Other, will be handled later. + (r'.*\n', Other), + ], + } + + +class IPythonTracebackLexer(DelegatingLexer): + """ + IPython traceback lexer. + + For doctests, the tracebacks can be snipped as much as desired with the + exception to the lines that designate a traceback. For non-syntax error + tracebacks, this is the line of hyphens. For syntax error tracebacks, + this is the line which lists the File and line number. + + """ + # The lexer inherits from DelegatingLexer. The "root" lexer is an + # appropriate IPython lexer, which depends on the value of the boolean + # `python3`. First, we parse with the partial IPython traceback lexer. + # Then, any code marked with the "Other" token is delegated to the root + # lexer. + # + name = 'IPython Traceback' + aliases = ['ipythontb'] + + def __init__(self, **options): + self.python3 = get_bool_opt(options, 'python3', False) + if self.python3: + self.aliases = ['ipython3tb'] + else: + self.aliases = ['ipython2tb', 'ipythontb'] + + if self.python3: + IPyLexer = IPython3Lexer + else: + IPyLexer = IPythonLexer + + DelegatingLexer.__init__(self, IPyLexer, + IPythonPartialTracebackLexer, **options) + +class IPythonConsoleLexer(Lexer): + """ + An IPython console lexer for IPython code-blocks and doctests, such as: + + .. code-block:: rst + + .. code-block:: ipythonconsole + + In [1]: a = 'foo' + + In [2]: a + Out[2]: 'foo' + + In [3]: print a + foo + + In [4]: 1 / 0 + + + Support is also provided for IPython exceptions: + + .. code-block:: rst + + .. code-block:: ipythonconsole + + In [1]: raise Exception + + --------------------------------------------------------------------------- + Exception Traceback (most recent call last) + in + ----> 1 raise Exception + + Exception: + + """ + name = 'IPython console session' + aliases = ['ipythonconsole'] + mimetypes = ['text/x-ipython-console'] + + # The regexps used to determine what is input and what is output. + # The default prompts for IPython are: + # + # in = 'In [#]: ' + # continuation = ' .D.: ' + # template = 'Out[#]: ' + # + # Where '#' is the 'prompt number' or 'execution count' and 'D' + # D is a number of dots matching the width of the execution count + # + in1_regex = r'In \[[0-9]+\]: ' + in2_regex = r' \.\.+\.: ' + out_regex = r'Out\[[0-9]+\]: ' + + #: The regex to determine when a traceback starts. + ipytb_start = re.compile(r'^(\^C)?(-+\n)|^( File)(.*)(, line )(\d+\n)') + + def __init__(self, **options): + """Initialize the IPython console lexer. + + Parameters + ---------- + python3 : bool + If `True`, then the console inputs are parsed using a Python 3 + lexer. Otherwise, they are parsed using a Python 2 lexer. + in1_regex : RegexObject + The compiled regular expression used to detect the start + of inputs. Although the IPython configuration setting may have a + trailing whitespace, do not include it in the regex. If `None`, + then the default input prompt is assumed. + in2_regex : RegexObject + The compiled regular expression used to detect the continuation + of inputs. Although the IPython configuration setting may have a + trailing whitespace, do not include it in the regex. If `None`, + then the default input prompt is assumed. + out_regex : RegexObject + The compiled regular expression used to detect outputs. If `None`, + then the default output prompt is assumed. + + """ + self.python3 = get_bool_opt(options, 'python3', False) + if self.python3: + self.aliases = ['ipython3console'] + else: + self.aliases = ['ipython2console', 'ipythonconsole'] + + in1_regex = options.get('in1_regex', self.in1_regex) + in2_regex = options.get('in2_regex', self.in2_regex) + out_regex = options.get('out_regex', self.out_regex) + + # So that we can work with input and output prompts which have been + # rstrip'd (possibly by editors) we also need rstrip'd variants. If + # we do not do this, then such prompts will be tagged as 'output'. + # The reason can't just use the rstrip'd variants instead is because + # we want any whitespace associated with the prompt to be inserted + # with the token. This allows formatted code to be modified so as hide + # the appearance of prompts, with the whitespace included. One example + # use of this is in copybutton.js from the standard lib Python docs. + in1_regex_rstrip = in1_regex.rstrip() + '\n' + in2_regex_rstrip = in2_regex.rstrip() + '\n' + out_regex_rstrip = out_regex.rstrip() + '\n' + + # Compile and save them all. + attrs = ['in1_regex', 'in2_regex', 'out_regex', + 'in1_regex_rstrip', 'in2_regex_rstrip', 'out_regex_rstrip'] + for attr in attrs: + self.__setattr__(attr, re.compile(locals()[attr])) + + Lexer.__init__(self, **options) + + if self.python3: + pylexer = IPython3Lexer + tblexer = IPythonTracebackLexer + else: + pylexer = IPythonLexer + tblexer = IPythonTracebackLexer + + self.pylexer = pylexer(**options) + self.tblexer = tblexer(**options) + + self.reset() + + def reset(self): + self.mode = 'output' + self.index = 0 + self.buffer = u'' + self.insertions = [] + + def buffered_tokens(self): + """ + Generator of unprocessed tokens after doing insertions and before + changing to a new state. + + """ + if self.mode == 'output': + tokens = [(0, Generic.Output, self.buffer)] + elif self.mode == 'input': + tokens = self.pylexer.get_tokens_unprocessed(self.buffer) + else: # traceback + tokens = self.tblexer.get_tokens_unprocessed(self.buffer) + + for i, t, v in do_insertions(self.insertions, tokens): + # All token indexes are relative to the buffer. + yield self.index + i, t, v + + # Clear it all + self.index += len(self.buffer) + self.buffer = u'' + self.insertions = [] + + def get_mci(self, line): + """ + Parses the line and returns a 3-tuple: (mode, code, insertion). + + `mode` is the next mode (or state) of the lexer, and is always equal + to 'input', 'output', or 'tb'. + + `code` is a portion of the line that should be added to the buffer + corresponding to the next mode and eventually lexed by another lexer. + For example, `code` could be Python code if `mode` were 'input'. + + `insertion` is a 3-tuple (index, token, text) representing an + unprocessed "token" that will be inserted into the stream of tokens + that are created from the buffer once we change modes. This is usually + the input or output prompt. + + In general, the next mode depends on current mode and on the contents + of `line`. + + """ + # To reduce the number of regex match checks, we have multiple + # 'if' blocks instead of 'if-elif' blocks. + + # Check for possible end of input + in2_match = self.in2_regex.match(line) + in2_match_rstrip = self.in2_regex_rstrip.match(line) + if (in2_match and in2_match.group().rstrip() == line.rstrip()) or \ + in2_match_rstrip: + end_input = True + else: + end_input = False + if end_input and self.mode != 'tb': + # Only look for an end of input when not in tb mode. + # An ellipsis could appear within the traceback. + mode = 'output' + code = u'' + insertion = (0, Generic.Prompt, line) + return mode, code, insertion + + # Check for output prompt + out_match = self.out_regex.match(line) + out_match_rstrip = self.out_regex_rstrip.match(line) + if out_match or out_match_rstrip: + mode = 'output' + if out_match: + idx = out_match.end() + else: + idx = out_match_rstrip.end() + code = line[idx:] + # Use the 'heading' token for output. We cannot use Generic.Error + # since it would conflict with exceptions. + insertion = (0, Generic.Heading, line[:idx]) + return mode, code, insertion + + + # Check for input or continuation prompt (non stripped version) + in1_match = self.in1_regex.match(line) + if in1_match or (in2_match and self.mode != 'tb'): + # New input or when not in tb, continued input. + # We do not check for continued input when in tb since it is + # allowable to replace a long stack with an ellipsis. + mode = 'input' + if in1_match: + idx = in1_match.end() + else: # in2_match + idx = in2_match.end() + code = line[idx:] + insertion = (0, Generic.Prompt, line[:idx]) + return mode, code, insertion + + # Check for input or continuation prompt (stripped version) + in1_match_rstrip = self.in1_regex_rstrip.match(line) + if in1_match_rstrip or (in2_match_rstrip and self.mode != 'tb'): + # New input or when not in tb, continued input. + # We do not check for continued input when in tb since it is + # allowable to replace a long stack with an ellipsis. + mode = 'input' + if in1_match_rstrip: + idx = in1_match_rstrip.end() + else: # in2_match + idx = in2_match_rstrip.end() + code = line[idx:] + insertion = (0, Generic.Prompt, line[:idx]) + return mode, code, insertion + + # Check for traceback + if self.ipytb_start.match(line): + mode = 'tb' + code = line + insertion = None + return mode, code, insertion + + # All other stuff... + if self.mode in ('input', 'output'): + # We assume all other text is output. Multiline input that + # does not use the continuation marker cannot be detected. + # For example, the 3 in the following is clearly output: + # + # In [1]: print 3 + # 3 + # + # But the following second line is part of the input: + # + # In [2]: while True: + # print True + # + # In both cases, the 2nd line will be 'output'. + # + mode = 'output' + else: + mode = 'tb' + + code = line + insertion = None + + return mode, code, insertion + + def get_tokens_unprocessed(self, text): + self.reset() + for match in line_re.finditer(text): + line = match.group() + mode, code, insertion = self.get_mci(line) + + if mode != self.mode: + # Yield buffered tokens before transitioning to new mode. + for token in self.buffered_tokens(): + yield token + self.mode = mode + + if insertion: + self.insertions.append((len(self.buffer), [insertion])) + self.buffer += code + + for token in self.buffered_tokens(): + yield token + +class IPyLexer(Lexer): + r""" + Primary lexer for all IPython-like code. + + This is a simple helper lexer. If the first line of the text begins with + "In \[[0-9]+\]:", then the entire text is parsed with an IPython console + lexer. If not, then the entire text is parsed with an IPython lexer. + + The goal is to reduce the number of lexers that are registered + with Pygments. + + """ + name = 'IPy session' + aliases = ['ipy'] + + def __init__(self, **options): + self.python3 = get_bool_opt(options, 'python3', False) + if self.python3: + self.aliases = ['ipy3'] + else: + self.aliases = ['ipy2', 'ipy'] + + Lexer.__init__(self, **options) + + self.IPythonLexer = IPythonLexer(**options) + self.IPythonConsoleLexer = IPythonConsoleLexer(**options) + + def get_tokens_unprocessed(self, text): + # Search for the input prompt anywhere...this allows code blocks to + # begin with comments as well. + if re.match(r'.*(In \[[0-9]+\]:)', text.strip(), re.DOTALL): + lex = self.IPythonConsoleLexer + else: + lex = self.IPythonLexer + for token in lex.get_tokens_unprocessed(text): + yield token + diff --git a/.venv/lib/python3.8/site-packages/IPython/lib/pretty.py b/.venv/lib/python3.8/site-packages/IPython/lib/pretty.py new file mode 100644 index 00000000..1cb46b14 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/IPython/lib/pretty.py @@ -0,0 +1,873 @@ +# -*- coding: utf-8 -*- +""" +Python advanced pretty printer. This pretty printer is intended to +replace the old `pprint` python module which does not allow developers +to provide their own pretty print callbacks. + +This module is based on ruby's `prettyprint.rb` library by `Tanaka Akira`. + + +Example Usage +------------- + +To directly print the representation of an object use `pprint`:: + + from pretty import pprint + pprint(complex_object) + +To get a string of the output use `pretty`:: + + from pretty import pretty + string = pretty(complex_object) + + +Extending +--------- + +The pretty library allows developers to add pretty printing rules for their +own objects. This process is straightforward. All you have to do is to +add a `_repr_pretty_` method to your object and call the methods on the +pretty printer passed:: + + class MyObject(object): + + def _repr_pretty_(self, p, cycle): + ... + +Here is an example implementation of a `_repr_pretty_` method for a list +subclass:: + + class MyList(list): + + def _repr_pretty_(self, p, cycle): + if cycle: + p.text('MyList(...)') + else: + with p.group(8, 'MyList([', '])'): + for idx, item in enumerate(self): + if idx: + p.text(',') + p.breakable() + p.pretty(item) + +The `cycle` parameter is `True` if pretty detected a cycle. You *have* to +react to that or the result is an infinite loop. `p.text()` just adds +non breaking text to the output, `p.breakable()` either adds a whitespace +or breaks here. If you pass it an argument it's used instead of the +default space. `p.pretty` prettyprints another object using the pretty print +method. + +The first parameter to the `group` function specifies the extra indentation +of the next line. In this example the next item will either be on the same +line (if the items are short enough) or aligned with the right edge of the +opening bracket of `MyList`. + +If you just want to indent something you can use the group function +without open / close parameters. You can also use this code:: + + with p.indent(2): + ... + +Inheritance diagram: + +.. inheritance-diagram:: IPython.lib.pretty + :parts: 3 + +:copyright: 2007 by Armin Ronacher. + Portions (c) 2009 by Robert Kern. +:license: BSD License. +""" + +from contextlib import contextmanager +import datetime +import os +import re +import sys +import types +from collections import deque +from inspect import signature +from io import StringIO +from warnings import warn + +from IPython.utils.decorators import undoc +from IPython.utils.py3compat import PYPY + +__all__ = ['pretty', 'pprint', 'PrettyPrinter', 'RepresentationPrinter', + 'for_type', 'for_type_by_name'] + + +MAX_SEQ_LENGTH = 1000 +_re_pattern_type = type(re.compile('')) + +def _safe_getattr(obj, attr, default=None): + """Safe version of getattr. + + Same as getattr, but will return ``default`` on any Exception, + rather than raising. + """ + try: + return getattr(obj, attr, default) + except Exception: + return default + +@undoc +class CUnicodeIO(StringIO): + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + warn(("CUnicodeIO is deprecated since IPython 6.0. " + "Please use io.StringIO instead."), + DeprecationWarning, stacklevel=2) + +def _sorted_for_pprint(items): + """ + Sort the given items for pretty printing. Since some predictable + sorting is better than no sorting at all, we sort on the string + representation if normal sorting fails. + """ + items = list(items) + try: + return sorted(items) + except Exception: + try: + return sorted(items, key=str) + except Exception: + return items + +def pretty(obj, verbose=False, max_width=79, newline='\n', max_seq_length=MAX_SEQ_LENGTH): + """ + Pretty print the object's representation. + """ + stream = StringIO() + printer = RepresentationPrinter(stream, verbose, max_width, newline, max_seq_length=max_seq_length) + printer.pretty(obj) + printer.flush() + return stream.getvalue() + + +def pprint(obj, verbose=False, max_width=79, newline='\n', max_seq_length=MAX_SEQ_LENGTH): + """ + Like `pretty` but print to stdout. + """ + printer = RepresentationPrinter(sys.stdout, verbose, max_width, newline, max_seq_length=max_seq_length) + printer.pretty(obj) + printer.flush() + sys.stdout.write(newline) + sys.stdout.flush() + +class _PrettyPrinterBase(object): + + @contextmanager + def indent(self, indent): + """with statement support for indenting/dedenting.""" + self.indentation += indent + try: + yield + finally: + self.indentation -= indent + + @contextmanager + def group(self, indent=0, open='', close=''): + """like begin_group / end_group but for the with statement.""" + self.begin_group(indent, open) + try: + yield + finally: + self.end_group(indent, close) + +class PrettyPrinter(_PrettyPrinterBase): + """ + Baseclass for the `RepresentationPrinter` prettyprinter that is used to + generate pretty reprs of objects. Contrary to the `RepresentationPrinter` + this printer knows nothing about the default pprinters or the `_repr_pretty_` + callback method. + """ + + def __init__(self, output, max_width=79, newline='\n', max_seq_length=MAX_SEQ_LENGTH): + self.output = output + self.max_width = max_width + self.newline = newline + self.max_seq_length = max_seq_length + self.output_width = 0 + self.buffer_width = 0 + self.buffer = deque() + + root_group = Group(0) + self.group_stack = [root_group] + self.group_queue = GroupQueue(root_group) + self.indentation = 0 + + def _break_one_group(self, group): + while group.breakables: + x = self.buffer.popleft() + self.output_width = x.output(self.output, self.output_width) + self.buffer_width -= x.width + while self.buffer and isinstance(self.buffer[0], Text): + x = self.buffer.popleft() + self.output_width = x.output(self.output, self.output_width) + self.buffer_width -= x.width + + def _break_outer_groups(self): + while self.max_width < self.output_width + self.buffer_width: + group = self.group_queue.deq() + if not group: + return + self._break_one_group(group) + + def text(self, obj): + """Add literal text to the output.""" + width = len(obj) + if self.buffer: + text = self.buffer[-1] + if not isinstance(text, Text): + text = Text() + self.buffer.append(text) + text.add(obj, width) + self.buffer_width += width + self._break_outer_groups() + else: + self.output.write(obj) + self.output_width += width + + def breakable(self, sep=' '): + """ + Add a breakable separator to the output. This does not mean that it + will automatically break here. If no breaking on this position takes + place the `sep` is inserted which default to one space. + """ + width = len(sep) + group = self.group_stack[-1] + if group.want_break: + self.flush() + self.output.write(self.newline) + self.output.write(' ' * self.indentation) + self.output_width = self.indentation + self.buffer_width = 0 + else: + self.buffer.append(Breakable(sep, width, self)) + self.buffer_width += width + self._break_outer_groups() + + def break_(self): + """ + Explicitly insert a newline into the output, maintaining correct indentation. + """ + group = self.group_queue.deq() + if group: + self._break_one_group(group) + self.flush() + self.output.write(self.newline) + self.output.write(' ' * self.indentation) + self.output_width = self.indentation + self.buffer_width = 0 + + + def begin_group(self, indent=0, open=''): + """ + Begin a group. + The first parameter specifies the indentation for the next line (usually + the width of the opening text), the second the opening text. All + parameters are optional. + """ + if open: + self.text(open) + group = Group(self.group_stack[-1].depth + 1) + self.group_stack.append(group) + self.group_queue.enq(group) + self.indentation += indent + + def _enumerate(self, seq): + """like enumerate, but with an upper limit on the number of items""" + for idx, x in enumerate(seq): + if self.max_seq_length and idx >= self.max_seq_length: + self.text(',') + self.breakable() + self.text('...') + return + yield idx, x + + def end_group(self, dedent=0, close=''): + """End a group. See `begin_group` for more details.""" + self.indentation -= dedent + group = self.group_stack.pop() + if not group.breakables: + self.group_queue.remove(group) + if close: + self.text(close) + + def flush(self): + """Flush data that is left in the buffer.""" + for data in self.buffer: + self.output_width += data.output(self.output, self.output_width) + self.buffer.clear() + self.buffer_width = 0 + + +def _get_mro(obj_class): + """ Get a reasonable method resolution order of a class and its superclasses + for both old-style and new-style classes. + """ + if not hasattr(obj_class, '__mro__'): + # Old-style class. Mix in object to make a fake new-style class. + try: + obj_class = type(obj_class.__name__, (obj_class, object), {}) + except TypeError: + # Old-style extension type that does not descend from object. + # FIXME: try to construct a more thorough MRO. + mro = [obj_class] + else: + mro = obj_class.__mro__[1:-1] + else: + mro = obj_class.__mro__ + return mro + + +class RepresentationPrinter(PrettyPrinter): + """ + Special pretty printer that has a `pretty` method that calls the pretty + printer for a python object. + + This class stores processing data on `self` so you must *never* use + this class in a threaded environment. Always lock it or reinstanciate + it. + + Instances also have a verbose flag callbacks can access to control their + output. For example the default instance repr prints all attributes and + methods that are not prefixed by an underscore if the printer is in + verbose mode. + """ + + def __init__(self, output, verbose=False, max_width=79, newline='\n', + singleton_pprinters=None, type_pprinters=None, deferred_pprinters=None, + max_seq_length=MAX_SEQ_LENGTH): + + PrettyPrinter.__init__(self, output, max_width, newline, max_seq_length=max_seq_length) + self.verbose = verbose + self.stack = [] + if singleton_pprinters is None: + singleton_pprinters = _singleton_pprinters.copy() + self.singleton_pprinters = singleton_pprinters + if type_pprinters is None: + type_pprinters = _type_pprinters.copy() + self.type_pprinters = type_pprinters + if deferred_pprinters is None: + deferred_pprinters = _deferred_type_pprinters.copy() + self.deferred_pprinters = deferred_pprinters + + def pretty(self, obj): + """Pretty print the given object.""" + obj_id = id(obj) + cycle = obj_id in self.stack + self.stack.append(obj_id) + self.begin_group() + try: + obj_class = _safe_getattr(obj, '__class__', None) or type(obj) + # First try to find registered singleton printers for the type. + try: + printer = self.singleton_pprinters[obj_id] + except (TypeError, KeyError): + pass + else: + return printer(obj, self, cycle) + # Next walk the mro and check for either: + # 1) a registered printer + # 2) a _repr_pretty_ method + for cls in _get_mro(obj_class): + if cls in self.type_pprinters: + # printer registered in self.type_pprinters + return self.type_pprinters[cls](obj, self, cycle) + else: + # deferred printer + printer = self._in_deferred_types(cls) + if printer is not None: + return printer(obj, self, cycle) + else: + # Finally look for special method names. + # Some objects automatically create any requested + # attribute. Try to ignore most of them by checking for + # callability. + if '_repr_pretty_' in cls.__dict__: + meth = cls._repr_pretty_ + if callable(meth): + return meth(obj, self, cycle) + if cls is not object \ + and callable(cls.__dict__.get('__repr__')): + return _repr_pprint(obj, self, cycle) + + return _default_pprint(obj, self, cycle) + finally: + self.end_group() + self.stack.pop() + + def _in_deferred_types(self, cls): + """ + Check if the given class is specified in the deferred type registry. + + Returns the printer from the registry if it exists, and None if the + class is not in the registry. Successful matches will be moved to the + regular type registry for future use. + """ + mod = _safe_getattr(cls, '__module__', None) + name = _safe_getattr(cls, '__name__', None) + key = (mod, name) + printer = None + if key in self.deferred_pprinters: + # Move the printer over to the regular registry. + printer = self.deferred_pprinters.pop(key) + self.type_pprinters[cls] = printer + return printer + + +class Printable(object): + + def output(self, stream, output_width): + return output_width + + +class Text(Printable): + + def __init__(self): + self.objs = [] + self.width = 0 + + def output(self, stream, output_width): + for obj in self.objs: + stream.write(obj) + return output_width + self.width + + def add(self, obj, width): + self.objs.append(obj) + self.width += width + + +class Breakable(Printable): + + def __init__(self, seq, width, pretty): + self.obj = seq + self.width = width + self.pretty = pretty + self.indentation = pretty.indentation + self.group = pretty.group_stack[-1] + self.group.breakables.append(self) + + def output(self, stream, output_width): + self.group.breakables.popleft() + if self.group.want_break: + stream.write(self.pretty.newline) + stream.write(' ' * self.indentation) + return self.indentation + if not self.group.breakables: + self.pretty.group_queue.remove(self.group) + stream.write(self.obj) + return output_width + self.width + + +class Group(Printable): + + def __init__(self, depth): + self.depth = depth + self.breakables = deque() + self.want_break = False + + +class GroupQueue(object): + + def __init__(self, *groups): + self.queue = [] + for group in groups: + self.enq(group) + + def enq(self, group): + depth = group.depth + while depth > len(self.queue) - 1: + self.queue.append([]) + self.queue[depth].append(group) + + def deq(self): + for stack in self.queue: + for idx, group in enumerate(reversed(stack)): + if group.breakables: + del stack[idx] + group.want_break = True + return group + for group in stack: + group.want_break = True + del stack[:] + + def remove(self, group): + try: + self.queue[group.depth].remove(group) + except ValueError: + pass + + +def _default_pprint(obj, p, cycle): + """ + The default print function. Used if an object does not provide one and + it's none of the builtin objects. + """ + klass = _safe_getattr(obj, '__class__', None) or type(obj) + if _safe_getattr(klass, '__repr__', None) is not object.__repr__: + # A user-provided repr. Find newlines and replace them with p.break_() + _repr_pprint(obj, p, cycle) + return + p.begin_group(1, '<') + p.pretty(klass) + p.text(' at 0x%x' % id(obj)) + if cycle: + p.text(' ...') + elif p.verbose: + first = True + for key in dir(obj): + if not key.startswith('_'): + try: + value = getattr(obj, key) + except AttributeError: + continue + if isinstance(value, types.MethodType): + continue + if not first: + p.text(',') + p.breakable() + p.text(key) + p.text('=') + step = len(key) + 1 + p.indentation += step + p.pretty(value) + p.indentation -= step + first = False + p.end_group(1, '>') + + +def _seq_pprinter_factory(start, end): + """ + Factory that returns a pprint function useful for sequences. Used by + the default pprint for tuples, dicts, and lists. + """ + def inner(obj, p, cycle): + if cycle: + return p.text(start + '...' + end) + step = len(start) + p.begin_group(step, start) + for idx, x in p._enumerate(obj): + if idx: + p.text(',') + p.breakable() + p.pretty(x) + if len(obj) == 1 and type(obj) is tuple: + # Special case for 1-item tuples. + p.text(',') + p.end_group(step, end) + return inner + + +def _set_pprinter_factory(start, end): + """ + Factory that returns a pprint function useful for sets and frozensets. + """ + def inner(obj, p, cycle): + if cycle: + return p.text(start + '...' + end) + if len(obj) == 0: + # Special case. + p.text(type(obj).__name__ + '()') + else: + step = len(start) + p.begin_group(step, start) + # Like dictionary keys, we will try to sort the items if there aren't too many + if not (p.max_seq_length and len(obj) >= p.max_seq_length): + items = _sorted_for_pprint(obj) + else: + items = obj + for idx, x in p._enumerate(items): + if idx: + p.text(',') + p.breakable() + p.pretty(x) + p.end_group(step, end) + return inner + + +def _dict_pprinter_factory(start, end): + """ + Factory that returns a pprint function used by the default pprint of + dicts and dict proxies. + """ + def inner(obj, p, cycle): + if cycle: + return p.text('{...}') + step = len(start) + p.begin_group(step, start) + keys = obj.keys() + for idx, key in p._enumerate(keys): + if idx: + p.text(',') + p.breakable() + p.pretty(key) + p.text(': ') + p.pretty(obj[key]) + p.end_group(step, end) + return inner + + +def _super_pprint(obj, p, cycle): + """The pprint for the super type.""" + p.begin_group(8, '') + + +def _re_pattern_pprint(obj, p, cycle): + """The pprint function for regular expression patterns.""" + p.text('re.compile(') + pattern = repr(obj.pattern) + if pattern[:1] in 'uU': + pattern = pattern[1:] + prefix = 'ur' + else: + prefix = 'r' + pattern = prefix + pattern.replace('\\\\', '\\') + p.text(pattern) + if obj.flags: + p.text(',') + p.breakable() + done_one = False + for flag in ('TEMPLATE', 'IGNORECASE', 'LOCALE', 'MULTILINE', 'DOTALL', + 'UNICODE', 'VERBOSE', 'DEBUG'): + if obj.flags & getattr(re, flag): + if done_one: + p.text('|') + p.text('re.' + flag) + done_one = True + p.text(')') + + +def _types_simplenamespace_pprint(obj, p, cycle): + """The pprint function for types.SimpleNamespace.""" + name = 'namespace' + with p.group(len(name) + 1, name + '(', ')'): + if cycle: + p.text('...') + else: + for idx, (attr, value) in enumerate(obj.__dict__.items()): + if idx: + p.text(',') + p.breakable() + attr_kwarg = '{}='.format(attr) + with p.group(len(attr_kwarg), attr_kwarg): + p.pretty(value) + + +def _type_pprint(obj, p, cycle): + """The pprint for classes and types.""" + # Heap allocated types might not have the module attribute, + # and others may set it to None. + + # Checks for a __repr__ override in the metaclass. Can't compare the + # type(obj).__repr__ directly because in PyPy the representation function + # inherited from type isn't the same type.__repr__ + if [m for m in _get_mro(type(obj)) if "__repr__" in vars(m)][:1] != [type]: + _repr_pprint(obj, p, cycle) + return + + mod = _safe_getattr(obj, '__module__', None) + try: + name = obj.__qualname__ + if not isinstance(name, str): + # This can happen if the type implements __qualname__ as a property + # or other descriptor in Python 2. + raise Exception("Try __name__") + except Exception: + name = obj.__name__ + if not isinstance(name, str): + name = '' + + if mod in (None, '__builtin__', 'builtins', 'exceptions'): + p.text(name) + else: + p.text(mod + '.' + name) + + +def _repr_pprint(obj, p, cycle): + """A pprint that just redirects to the normal repr function.""" + # Find newlines and replace them with p.break_() + output = repr(obj) + lines = output.splitlines() + with p.group(): + for idx, output_line in enumerate(lines): + if idx: + p.break_() + p.text(output_line) + + +def _function_pprint(obj, p, cycle): + """Base pprint for all functions and builtin functions.""" + name = _safe_getattr(obj, '__qualname__', obj.__name__) + mod = obj.__module__ + if mod and mod not in ('__builtin__', 'builtins', 'exceptions'): + name = mod + '.' + name + try: + func_def = name + str(signature(obj)) + except ValueError: + func_def = name + p.text('' % func_def) + + +def _exception_pprint(obj, p, cycle): + """Base pprint for all exceptions.""" + name = getattr(obj.__class__, '__qualname__', obj.__class__.__name__) + if obj.__class__.__module__ not in ('exceptions', 'builtins'): + name = '%s.%s' % (obj.__class__.__module__, name) + step = len(name) + 1 + p.begin_group(step, name + '(') + for idx, arg in enumerate(getattr(obj, 'args', ())): + if idx: + p.text(',') + p.breakable() + p.pretty(arg) + p.end_group(step, ')') + + +#: the exception base +try: + _exception_base = BaseException +except NameError: + _exception_base = Exception + + +#: printers for builtin types +_type_pprinters = { + int: _repr_pprint, + float: _repr_pprint, + str: _repr_pprint, + tuple: _seq_pprinter_factory('(', ')'), + list: _seq_pprinter_factory('[', ']'), + dict: _dict_pprinter_factory('{', '}'), + set: _set_pprinter_factory('{', '}'), + frozenset: _set_pprinter_factory('frozenset({', '})'), + super: _super_pprint, + _re_pattern_type: _re_pattern_pprint, + type: _type_pprint, + types.FunctionType: _function_pprint, + types.BuiltinFunctionType: _function_pprint, + types.MethodType: _repr_pprint, + types.SimpleNamespace: _types_simplenamespace_pprint, + datetime.datetime: _repr_pprint, + datetime.timedelta: _repr_pprint, + _exception_base: _exception_pprint +} + +# render os.environ like a dict +_env_type = type(os.environ) +# future-proof in case os.environ becomes a plain dict? +if _env_type is not dict: + _type_pprinters[_env_type] = _dict_pprinter_factory('environ{', '}') + +try: + # In PyPy, types.DictProxyType is dict, setting the dictproxy printer + # using dict.setdefault avoids overwriting the dict printer + _type_pprinters.setdefault(types.DictProxyType, + _dict_pprinter_factory('dict_proxy({', '})')) + _type_pprinters[types.ClassType] = _type_pprint + _type_pprinters[types.SliceType] = _repr_pprint +except AttributeError: # Python 3 + _type_pprinters[types.MappingProxyType] = \ + _dict_pprinter_factory('mappingproxy({', '})') + _type_pprinters[slice] = _repr_pprint + +_type_pprinters[range] = _repr_pprint +_type_pprinters[bytes] = _repr_pprint + +#: printers for types specified by name +_deferred_type_pprinters = { +} + +def for_type(typ, func): + """ + Add a pretty printer for a given type. + """ + oldfunc = _type_pprinters.get(typ, None) + if func is not None: + # To support easy restoration of old pprinters, we need to ignore Nones. + _type_pprinters[typ] = func + return oldfunc + +def for_type_by_name(type_module, type_name, func): + """ + Add a pretty printer for a type specified by the module and name of a type + rather than the type object itself. + """ + key = (type_module, type_name) + oldfunc = _deferred_type_pprinters.get(key, None) + if func is not None: + # To support easy restoration of old pprinters, we need to ignore Nones. + _deferred_type_pprinters[key] = func + return oldfunc + + +#: printers for the default singletons +_singleton_pprinters = dict.fromkeys(map(id, [None, True, False, Ellipsis, + NotImplemented]), _repr_pprint) + + +def _defaultdict_pprint(obj, p, cycle): + name = obj.__class__.__name__ + with p.group(len(name) + 1, name + '(', ')'): + if cycle: + p.text('...') + else: + p.pretty(obj.default_factory) + p.text(',') + p.breakable() + p.pretty(dict(obj)) + +def _ordereddict_pprint(obj, p, cycle): + name = obj.__class__.__name__ + with p.group(len(name) + 1, name + '(', ')'): + if cycle: + p.text('...') + elif len(obj): + p.pretty(list(obj.items())) + +def _deque_pprint(obj, p, cycle): + name = obj.__class__.__name__ + with p.group(len(name) + 1, name + '(', ')'): + if cycle: + p.text('...') + else: + p.pretty(list(obj)) + + +def _counter_pprint(obj, p, cycle): + name = obj.__class__.__name__ + with p.group(len(name) + 1, name + '(', ')'): + if cycle: + p.text('...') + elif len(obj): + p.pretty(dict(obj)) + +for_type_by_name('collections', 'defaultdict', _defaultdict_pprint) +for_type_by_name('collections', 'OrderedDict', _ordereddict_pprint) +for_type_by_name('collections', 'deque', _deque_pprint) +for_type_by_name('collections', 'Counter', _counter_pprint) + +if __name__ == '__main__': + from random import randrange + class Foo(object): + def __init__(self): + self.foo = 1 + self.bar = re.compile(r'\s+') + self.blub = dict.fromkeys(range(30), randrange(1, 40)) + self.hehe = 23424.234234 + self.list = ["blub", "blah", self] + + def get_foo(self): + print("foo") + + pprint(Foo(), verbose=True) diff --git a/.venv/lib/python3.8/site-packages/IPython/lib/security.py b/.venv/lib/python3.8/site-packages/IPython/lib/security.py new file mode 100644 index 00000000..91a2344e --- /dev/null +++ b/.venv/lib/python3.8/site-packages/IPython/lib/security.py @@ -0,0 +1,114 @@ +""" +Password generation for the IPython notebook. +""" +#----------------------------------------------------------------------------- +# Imports +#----------------------------------------------------------------------------- +# Stdlib +import getpass +import hashlib +import random + +# Our own +from IPython.core.error import UsageError +from IPython.utils.py3compat import encode + +#----------------------------------------------------------------------------- +# Globals +#----------------------------------------------------------------------------- + +# Length of the salt in nr of hex chars, which implies salt_len * 4 +# bits of randomness. +salt_len = 12 + +#----------------------------------------------------------------------------- +# Functions +#----------------------------------------------------------------------------- + +def passwd(passphrase=None, algorithm='sha1'): + """Generate hashed password and salt for use in notebook configuration. + + In the notebook configuration, set `c.NotebookApp.password` to + the generated string. + + Parameters + ---------- + passphrase : str + Password to hash. If unspecified, the user is asked to input + and verify a password. + algorithm : str + Hashing algorithm to use (e.g, 'sha1' or any argument supported + by :func:`hashlib.new`). + + Returns + ------- + hashed_passphrase : str + Hashed password, in the format 'hash_algorithm:salt:passphrase_hash'. + + Examples + -------- + >>> passwd('mypassword') + 'sha1:7cf3:b7d6da294ea9592a9480c8f52e63cd42cfb9dd12' + + """ + if passphrase is None: + for i in range(3): + p0 = getpass.getpass('Enter password: ') + p1 = getpass.getpass('Verify password: ') + if p0 == p1: + passphrase = p0 + break + else: + print('Passwords do not match.') + else: + raise UsageError('No matching passwords found. Giving up.') + + h = hashlib.new(algorithm) + salt = ('%0' + str(salt_len) + 'x') % random.getrandbits(4 * salt_len) + h.update(encode(passphrase, 'utf-8') + encode(salt, 'ascii')) + + return ':'.join((algorithm, salt, h.hexdigest())) + + +def passwd_check(hashed_passphrase, passphrase): + """Verify that a given passphrase matches its hashed version. + + Parameters + ---------- + hashed_passphrase : str + Hashed password, in the format returned by `passwd`. + passphrase : str + Passphrase to validate. + + Returns + ------- + valid : bool + True if the passphrase matches the hash. + + Examples + -------- + >>> from IPython.lib.security import passwd_check + >>> passwd_check('sha1:0e112c3ddfce:a68df677475c2b47b6e86d0467eec97ac5f4b85a', + ... 'mypassword') + True + + >>> passwd_check('sha1:0e112c3ddfce:a68df677475c2b47b6e86d0467eec97ac5f4b85a', + ... 'anotherpassword') + False + """ + try: + algorithm, salt, pw_digest = hashed_passphrase.split(':', 2) + except (ValueError, TypeError): + return False + + try: + h = hashlib.new(algorithm) + except ValueError: + return False + + if len(pw_digest) == 0: + return False + + h.update(encode(passphrase, 'utf-8') + encode(salt, 'ascii')) + + return h.hexdigest() == pw_digest diff --git a/.venv/lib/python3.8/site-packages/IPython/lib/tests/__init__.py b/.venv/lib/python3.8/site-packages/IPython/lib/tests/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/.venv/lib/python3.8/site-packages/IPython/lib/tests/__pycache__/__init__.cpython-38.pyc b/.venv/lib/python3.8/site-packages/IPython/lib/tests/__pycache__/__init__.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..964ae8e4f3a128894055d45f0a8cbf8c98a6b200 GIT binary patch literal 153 zcmWIL<>g`k0>*}G@gVv!h(HF6K#l_t7qb9~6oz01O-8?!3`HPe1o6vGza+OnzaXTZlX-=vg$lT9B%m4skY$M_T literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/IPython/lib/tests/__pycache__/test_backgroundjobs.cpython-38.pyc b/.venv/lib/python3.8/site-packages/IPython/lib/tests/__pycache__/test_backgroundjobs.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..89de460ab21a0c23785a5fca11cc4a1a65f1728e GIT binary patch literal 1925 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%0DYQYo({wkJFJEIZMqlHH?{T*d-c{^Y0h z`{f%rD@Hz4$(d0m%G@#PfAdD+4eneW>IJ>g4_H*@< zBi6rl$s|K`1g!=ZXP`T|Mvi~#EQNk!S@>5;9)FEXYuBD-^Ib(naXiQfk*f=j7=Dlh z=)Le6cKC~o5qXEQi8T+=zrQv45gz;tJ(K{@I?QXQ=myb2{(!&$C5(+LPsKO;?eU*5 zW5!Rqh2&K3bIZ)i_TB#vlp?rJ;hd4n=6Pw+^BS>e!Lj$!NzbFBmF$U}ppAZy!0!?8 z39J){2_ystXc(Z6)c-GVad6}y%~rI#mx(fut0<|@2px&tNrBy@f!6@qC&B7k*geJ) z2D~W*M=%;N3Lk=@Elt@t+i38COJrwG`FE-ir?eN6dZQJR(alUJo&WMd zXcz`!Hy^|F6AC148;-NDs;h3{j=xf`-ofc|I&quMrxhP_qzCUXi7K(W6}KY6H_Li9 zen10e#S@QP#lPZRndJeWInY?}tA8K&MreWdz^|rIVlTfsJAF-$?qX1Q9+h1#G9i{i zK@(SU4nW~_atpQwsz{&H{s=)F#lC;2)mSw>aC(k$*{ZOe-?cyslhA&1>rCtBu1 zf@tsI{y@BOrZR=IUm3(+QeQznA){iSfd56knSgip-OR9~n|V~Ms3HUhNQ099w+DS~ z`F)z2tyy1(q=ma1&Fpje{z9@d)e*GC%UV+y` zSxMO<@G$|F{6C=DfVsHFNbBIiuW_-IIF_MHy2H-dE{W>P^ci#^lO=T6AY%^k#lwD+|4wLil~sO%~uqtdpP=95*#brwQ3d_fX7gGd(eKDS5#TupLn zy@;SM>eeTzUS0L0C(s^FOpMs3%=GpCq z`;aC6HMlL)bl^>%)rgFd#G1GmFE61&u7iUAfdmawHrpmX#jxm8jO3)Ue*{&{i2->V zJ=^)EL~Vq@RcJUut!v$kMIgU{>fl^2oxaW=PQV@RYO_?Y4zU{x!$CzKlT$tAf(^6LahFG)Js zb)8mJ$FT`8O@1^hX8C|>KLSXNdfX*g6esw^CXU0zwYkV#1j3)(0B|RUK0wM)aIANS zrpHGT3nHlE>mwX^Cz-TS0-C?=;ZJ( f;9qoX)Shz=IMcZD&WvNtTy*l5K3hb8)5-lW^Db@f literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/IPython/lib/tests/__pycache__/test_editorhooks.cpython-38.pyc b/.venv/lib/python3.8/site-packages/IPython/lib/tests/__pycache__/test_editorhooks.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8dc715a6406678318d049954682aeb56d8f3047b GIT binary patch literal 1205 zcmZuwJCEB&5Z+xrL`l?Hw&NI1420c5g(Sf6qcIFuhEw?9Bn}d=A!zPO;%WKt?ke)h z5)i-!axRkeK?+@YMcVw76x*h{zmOux3?;)hkR><|?#z7i;^HJ2TSX8DjqJ&G(TO`C`@Hpr#9hw5 zA%kFb^O?{l%1dohDf4m~37(ruMYF1!>kGglM+0izqRQsLyHjD3ygo6rszh~X+}LJl z`|fxkwBdzHi2f7El)NQBkqKtY-UJ(B$T8&2UGDwNC^2m7aDPqC*sq_0=DsG!-WKxY z!5Q3sNA8fX$k*h1Vp`k4v`@)v%G-EzN_gi6;oTc#L-%qBGDEvH<2`Abk3}ss;RdAe2IK@d70*Bq=Z?hGWj8u3!x~48aUQZ z>spjtAxzwUl1}sN3G`hdY>IkZ=k;(=)@e2ue7KwmA&2)ezPxpB z{&M`~(`H6vnLi&Jn6PeW^1-}D^@;6F(z!_L3Q$A9(7P3MDWmM)z+D}pXR_aoz3=G0 ztRN5lVD#R1_4%Z#qM?jl!3K#kie1+?fe`A_&_7@Y^fT6{ zAq`odg|yFH8c>A>gV45;gjZRTsOzA|!J^C!hTQE;r>wLXnW~aH_8O+Hp;>Fc4o%H* mcdw0LIhr;#v3Hp^={BTEH@II^d?CdH9F4|Lm`lju0s0^0IWw&Q literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/IPython/lib/tests/__pycache__/test_imports.cpython-38.pyc b/.venv/lib/python3.8/site-packages/IPython/lib/tests/__pycache__/test_imports.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..fa1b8ec82ec6ae2bc4dad795714b7873d0a24788 GIT binary patch literal 681 zcmbVKy-veG48BX!HvOd&15ZGPHWEu0gb++D6%u0UQnm4^4NY<6%d?Gu0mhfBW*DlMplJ4OzA zmql+ri&hKN>kOXs+y+k3zPsP%OPvjqc#a-Lq06BH>!iMK!aOyhiOpc08A??!*esPw z2BQcz7o*j4xJwTyJ+%w0(I36GwOcB2fcM9&~_ zutuej-vXNqJjpLK$SO|v`TXVaw~9-f?4!AOpi*72=yLB4!#@`NLl&uKzE%Go+2f!- tIjJ6pgX3(0ysN^cAE8_qGEd~-z3OG3a!~&=)v!*~6=zxYcO2jK-5)Eiif8}; literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/IPython/lib/tests/__pycache__/test_latextools.cpython-38.pyc b/.venv/lib/python3.8/site-packages/IPython/lib/tests/__pycache__/test_latextools.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..143131942f41dbf829114e8ea22ee9106698f4de GIT binary patch literal 5791 zcmcgwOOqQ{74Da$mPRv{U*p)0lTI>FQ4-G#Cbl7QjB%1Fs3O87g9BYAN=x_7s6G9V zZ(n&lvQ$M8SCK4I`~*D9S+Jp4@EiC6EPBg|H9IeW@7!)_q>;yV0!dft>c0B)x#xW6 zb$>ZOU(xXBzx{jj*QYe?A2gVJEDWyUm;4nC(_D?|%n0<*a1EXMW?+VvTTp!~D264s zr22)x4$E#ithg05E(UX9)vcmmV)g^goo8iM!T$m;vpH7%%wY3u;eqyobV;ZN~8QKdfC)ru{JXRN(`H@yX*MD)H zCo*w1V&VMs#*Xa7(Q;4vL9*QSWM{d%^G_U4tLte2<94TkUM27(zbE53Na{v(ED zf1}wBS<>Y9{6wZFlP$lCsVJ7s(39ODmVw{e)6?pjAF+2s_P!9YXcOVlqoZTuN0Z5O zXqf(<_M3&FCbfaKVcgVo?T*C^aBTM1D-NDd6&FnzH@nehlil_4_o zo)t-YP;K@>C15BZeT`P0jfn*kA0bn-Y+W3|f14ybdJJ^R_>rWOt7v|&ZRmvC2lh~x z+CyC$%pB;u<{!@Jnlv9;(s)>47Ax!;Oxp#nKh`d4ztBF^eg(us7sbXDdHNK6;y977 zp&4kOYg>k>O6_;LdO>f9BIY4l(-WIw4t*smL5!#KVGL<+03#$&7+roA-PZfpzk({3 zuLN=13zDnLQv_XmMB25tJHYT=F4pTsK`f`mxOJPir6AFyMkLd!mn2-sCcxqa>G8*4 zppKJaw>U}-DLgw59Yv7uSi~>MoJiHG=?l8?A2ly*+Ch3Cw2vS9GVP|xSttOeQ#c;tmVlbsTvg295)+EzE=+a15%`3_N6nAWR$|Kg#>KrA27{Fp}Fs2ly# z($c+8E-Wpr?HP|u^w!hzctfLZDbd;$_Tz>uP`JNoo(f!T(d|f?zMmg^SbFD7}uAtHk*x=Jz#vVOEAWA8sBHaC&U|F!UyQ`b^$NMHjDPG{Zi5BgOtTbViP691+O9I9Wts z*24l0Rb&NL+%7zrK&SO&)P|5amxCGNX6a;GOx?JPHAc>B%v8ID`Dk zF4C7gj+l+L{_5CxM^PX7hSTB>Tz`P*{%ZbDUd*|_I;z! z6sbP}3kgLmO|QUx_m`D$$0wrDPv<$z?I>8LdZk}(#cao+tZA*kdyB>GUdSWa4xr5Y zo{)Y!;KRzTUcxC&03_~vVFJE7Gn29t&den{VQYG_MVq>y1FswK`#kK*9n7@&rXSrO zeSKINGgZ08BeuWL*egv~jEU3lJMPrF9s7}69?M`)S2leRhKrAv)O#dQike7J5ECuE zrW^kjWM$ttB!Bi~NUn<>S6MJpML;Ow&Ny&U-sne(RJeK?YG>l0N?IF&(wY8IN~%|6 zyfUW!WKa1CUfTDRmk!93pw}dLH#2h6Y0ua^6bi-bASKSBS?~YtTSDLjo)v@71j-Rg z3I4AQD~QuMI`fGGP!(^`xt6J!jx^~DPnMR8S7wp8irH@*i8uZyB$Ai=`e;N}_6!kv zn}jpYxqf(v4YJX+lINEW5TZx2A=|`K{6~#CsLe7+VVwFy<)phX_ zMA|RCvZ@}`W;9Lq}{Jwhr^`l1J&I-Wl?eyep9gPGD$;#{yU*t>>lfZT)kV8N)*9=FDoS5*{GhSY2&- zV$VoRExP21n7DwqQ0>wI1r<9gG$B#CIO=Ej9rl&L3tP;)`e)3mG_$CL*3Sa{lq&KA zk~%ZBOw_s~GGFrq7M(!+fOvar%;4MOp1RMtg5h8Ao8YohH&t5b&gWJjJU`({TDeJ3 zSNZisNLKVzdA~G^v)RM_Y4k14vh)*%pc1BjDlIjeNMD;xcfJ?-k_f3Q9+j=Sl_*A0 zp{~u`g8Iw&n;YG0;+9S6#62^bAqp_lWyagF@FZX(DC!APy?b)BE58pFahoTJDA5MG zTFWkTsGt{A5~{*VrLuxREy(XH@GIsgL@_RgQ~OF7vtGcj(uG4pg_(tWf-0=5rdLhd Ywkx(?SunC+!Ctga+lvM)u=?_U0q>s5cmMzZ literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/IPython/lib/tests/__pycache__/test_lexers.cpython-38.pyc b/.venv/lib/python3.8/site-packages/IPython/lib/tests/__pycache__/test_lexers.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..17eccbec1ce18d70a5ac455b2ca885148d9bc100 GIT binary patch literal 2998 zcma)8TXWk)6xOcR@@nlQrq{IPB0~jnY2p%~g%Br&PKS1A(@sfW^rCUHvg6b@B!$?E zGs8^F|41JBLw(RIPkm*Ep|~w@b|uA5I`vc;@1EOtE_+tdc{nx2G+lP1!NN61N$X9$MI54N(#*6B#{fFRjb^q*9g4K?HJ;`4iN>ji zAM1|E%^$TA6DQWaAheoZ&+`MT)!{o$?-@kUN+_aIb)y=1KxfuFkGwVz=6BU#>y9*k zhGR1$25(B#_#@TV;TKr2c$$MCYs`_ObIkQ8nnO6@8Q395$Rryv8BTc)#Q7VYX4BgY z8=bb*sio8a1FepwNl16K=0&l-|vT8 zowf=TWmN9IJlu$FKxM8HK%FG;nzi3GKL@Jex8<tJWB~o=+Hd%rc7P5Lg1YxJ0~{Kl%}VV7dW;U_J;4KX zR@>8+7b3k3pcgR` z#5k4MorW{dPUzbi<(Kla${z7qwdeS`1b-gzWCH#|a#zyY-c9_xm*8d3C*j{u>N?)z z4-$ObbCX+R{)`Fv6q9<=yOQSd;TV2WJ|C$!i1Lfd9`O{f?k>DhZ+dU+h8=c*HLq;Z6Rj;u*i3$RRHDmGXJD=lH@%UZ0+jPdUlwin2HPXKF`$G2uT~ zJL6xdJ-Ac6ZxXIxz({Q-nw`9CL5ySGx>jA;9^l2re)hjCa`G<9jFK~L3&ojicoKe ztRbq1Oz$%ALv&e~in46I&7t?Yo?i_+eq?yP z&}(zwlwwx*LN}CCL=fem9?uVN{Udu&!g-eI4mDf#@bG6!}Fc&?RMzZJwMXdt9AIu%PA_NHNRSKdF?PV;)o7QCGMg_ zW0||CKJM|7m#~8Ta*xjkCqWvVl9v$?O#dVLc{GbDP#Cj+i9U-9m?HRlg$a8}GD;_T zL|@_zenE^e38F8sfrlh}h>9)c`W&0=Z^C9VL>WmD{fC%ivX|1|p~X>7qK1UNLH|nT zc8DC0kkWsW!cmL7)I2A-6va|Y7+gT}7nu?l#>SW9C%0BIBI>$r=%njL%yr|@66n0^ z%C;w(tn2d5rtA7saLE2uxyXrYY>}Puv#>~uK+bR!5k!fSt(BO+1R{s-v>TyJ!k6Qq zGu`d0{s#-H*YU-iITWfPFNnuJP0fYM+gMbUgt`=TIZk~=UV}hhFOtb4_``Yqe~D?w A`Tzg` literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/IPython/lib/tests/__pycache__/test_pretty.cpython-38.pyc b/.venv/lib/python3.8/site-packages/IPython/lib/tests/__pycache__/test_pretty.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e3976510e2f6b9d3880c3a3686fa964149789056 GIT binary patch literal 17144 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 literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/IPython/lib/tests/test_backgroundjobs.py b/.venv/lib/python3.8/site-packages/IPython/lib/tests/test_backgroundjobs.py new file mode 100644 index 00000000..d7793f50 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/IPython/lib/tests/test_backgroundjobs.py @@ -0,0 +1,88 @@ +"""Tests for pylab tools module. +""" +#----------------------------------------------------------------------------- +# Copyright (c) 2011, the IPython Development Team. +# +# Distributed under the terms of the Modified BSD License. +# +# The full license is in the file COPYING.txt, distributed with this software. +#----------------------------------------------------------------------------- + +#----------------------------------------------------------------------------- +# Imports +#----------------------------------------------------------------------------- + +# Stdlib imports +import time + +# Third-party imports +import nose.tools as nt + +# Our own imports +from IPython.lib import backgroundjobs as bg + +#----------------------------------------------------------------------------- +# Globals and constants +#----------------------------------------------------------------------------- +t_short = 0.0001 # very short interval to wait on jobs + +#----------------------------------------------------------------------------- +# Local utilities +#----------------------------------------------------------------------------- +def sleeper(interval=t_short, *a, **kw): + args = dict(interval=interval, + other_args=a, + kw_args=kw) + time.sleep(interval) + return args + +def crasher(interval=t_short, *a, **kw): + time.sleep(interval) + raise Exception("Dead job with interval %s" % interval) + +#----------------------------------------------------------------------------- +# Classes and functions +#----------------------------------------------------------------------------- + +def test_result(): + """Test job submission and result retrieval""" + jobs = bg.BackgroundJobManager() + j = jobs.new(sleeper) + j.join() + nt.assert_equal(j.result['interval'], t_short) + + +def test_flush(): + """Test job control""" + jobs = bg.BackgroundJobManager() + j = jobs.new(sleeper) + j.join() + nt.assert_equal(len(jobs.completed), 1) + nt.assert_equal(len(jobs.dead), 0) + jobs.flush() + nt.assert_equal(len(jobs.completed), 0) + + +def test_dead(): + """Test control of dead jobs""" + jobs = bg.BackgroundJobManager() + j = jobs.new(crasher) + j.join() + nt.assert_equal(len(jobs.completed), 0) + nt.assert_equal(len(jobs.dead), 1) + jobs.flush() + nt.assert_equal(len(jobs.dead), 0) + + +def test_longer(): + """Test control of longer-running jobs""" + jobs = bg.BackgroundJobManager() + # Sleep for long enough for the following two checks to still report the + # job as running, but not so long that it makes the test suite noticeably + # slower. + j = jobs.new(sleeper, 0.1) + nt.assert_equal(len(jobs.running), 1) + nt.assert_equal(len(jobs.completed), 0) + j.join() + nt.assert_equal(len(jobs.running), 0) + nt.assert_equal(len(jobs.completed), 1) diff --git a/.venv/lib/python3.8/site-packages/IPython/lib/tests/test_clipboard.py b/.venv/lib/python3.8/site-packages/IPython/lib/tests/test_clipboard.py new file mode 100644 index 00000000..f1050bfb --- /dev/null +++ b/.venv/lib/python3.8/site-packages/IPython/lib/tests/test_clipboard.py @@ -0,0 +1,21 @@ +import nose.tools as nt + +from IPython.core.error import TryNext +from IPython.lib.clipboard import ClipboardEmpty +from IPython.testing.decorators import skip_if_no_x11 + +@skip_if_no_x11 +def test_clipboard_get(): + # Smoketest for clipboard access - we can't easily guarantee that the + # clipboard is accessible and has something on it, but this tries to + # exercise the relevant code anyway. + try: + a = get_ipython().hooks.clipboard_get() + except ClipboardEmpty: + # Nothing in clipboard to get + pass + except TryNext: + # No clipboard access API available + pass + else: + nt.assert_is_instance(a, str) diff --git a/.venv/lib/python3.8/site-packages/IPython/lib/tests/test_deepreload.py b/.venv/lib/python3.8/site-packages/IPython/lib/tests/test_deepreload.py new file mode 100644 index 00000000..abc57a38 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/IPython/lib/tests/test_deepreload.py @@ -0,0 +1,34 @@ +# -*- coding: utf-8 -*- +"""Test suite for the deepreload module.""" + +# Copyright (c) IPython Development Team. +# Distributed under the terms of the Modified BSD License. + +import os + +import nose.tools as nt + +from IPython.utils.syspathcontext import prepended_to_syspath +from IPython.utils.tempdir import TemporaryDirectory +from IPython.lib.deepreload import reload as dreload + +def test_deepreload(): + "Test that dreload does deep reloads and skips excluded modules." + with TemporaryDirectory() as tmpdir: + with prepended_to_syspath(tmpdir): + with open(os.path.join(tmpdir, 'A.py'), 'w') as f: + f.write("class Object(object):\n pass\n") + with open(os.path.join(tmpdir, 'B.py'), 'w') as f: + f.write("import A\n") + import A + import B + + # Test that A is not reloaded. + obj = A.Object() + dreload(B, exclude=['A']) + nt.assert_true(isinstance(obj, A.Object)) + + # Test that A is reloaded. + obj = A.Object() + dreload(B) + nt.assert_false(isinstance(obj, A.Object)) diff --git a/.venv/lib/python3.8/site-packages/IPython/lib/tests/test_display.py b/.venv/lib/python3.8/site-packages/IPython/lib/tests/test_display.py new file mode 100644 index 00000000..7e98a185 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/IPython/lib/tests/test_display.py @@ -0,0 +1,266 @@ +"""Tests for IPython.lib.display. + +""" +#----------------------------------------------------------------------------- +# Copyright (c) 2012, the IPython Development Team. +# +# Distributed under the terms of the Modified BSD License. +# +# The full license is in the file COPYING.txt, distributed with this software. +#----------------------------------------------------------------------------- + +#----------------------------------------------------------------------------- +# Imports +#----------------------------------------------------------------------------- +from tempfile import NamedTemporaryFile, mkdtemp +from os.path import split, join as pjoin, dirname +import pathlib +from unittest import TestCase, mock +import struct +import wave +from io import BytesIO + +# Third-party imports +import nose.tools as nt + +try: + import numpy +except ImportError: + pass + +# Our own imports +from IPython.lib import display + +from IPython.testing.decorators import skipif_not_numpy + +#----------------------------------------------------------------------------- +# Classes and functions +#----------------------------------------------------------------------------- + +#-------------------------- +# FileLink tests +#-------------------------- + +def test_instantiation_FileLink(): + """FileLink: Test class can be instantiated""" + fl = display.FileLink('example.txt') + # TODO: remove if when only Python >= 3.6 is supported + fl = display.FileLink(pathlib.PurePath('example.txt')) + +def test_warning_on_non_existent_path_FileLink(): + """FileLink: Calling _repr_html_ on non-existent files returns a warning + """ + fl = display.FileLink('example.txt') + nt.assert_true(fl._repr_html_().startswith('Path (example.txt)')) + +def test_existing_path_FileLink(): + """FileLink: Calling _repr_html_ functions as expected on existing filepath + """ + tf = NamedTemporaryFile() + fl = display.FileLink(tf.name) + actual = fl._repr_html_() + expected = "%s
" % (tf.name,tf.name) + nt.assert_equal(actual,expected) + +def test_existing_path_FileLink_repr(): + """FileLink: Calling repr() functions as expected on existing filepath + """ + tf = NamedTemporaryFile() + fl = display.FileLink(tf.name) + actual = repr(fl) + expected = tf.name + nt.assert_equal(actual,expected) + +def test_error_on_directory_to_FileLink(): + """FileLink: Raises error when passed directory + """ + td = mkdtemp() + nt.assert_raises(ValueError,display.FileLink,td) + +#-------------------------- +# FileLinks tests +#-------------------------- + +def test_instantiation_FileLinks(): + """FileLinks: Test class can be instantiated + """ + fls = display.FileLinks('example') + +def test_warning_on_non_existent_path_FileLinks(): + """FileLinks: Calling _repr_html_ on non-existent files returns a warning + """ + fls = display.FileLinks('example') + nt.assert_true(fls._repr_html_().startswith('Path (example)')) + +def test_existing_path_FileLinks(): + """FileLinks: Calling _repr_html_ functions as expected on existing dir + """ + td = mkdtemp() + tf1 = NamedTemporaryFile(dir=td) + tf2 = NamedTemporaryFile(dir=td) + fl = display.FileLinks(td) + actual = fl._repr_html_() + actual = actual.split('\n') + actual.sort() + # the links should always have forward slashes, even on windows, so replace + # backslashes with forward slashes here + expected = ["%s/
" % td, + "  %s
" %\ + (tf2.name.replace("\\","/"),split(tf2.name)[1]), + "  %s
" %\ + (tf1.name.replace("\\","/"),split(tf1.name)[1])] + expected.sort() + # We compare the sorted list of links here as that's more reliable + nt.assert_equal(actual,expected) + +def test_existing_path_FileLinks_alt_formatter(): + """FileLinks: Calling _repr_html_ functions as expected w/ an alt formatter + """ + td = mkdtemp() + tf1 = NamedTemporaryFile(dir=td) + tf2 = NamedTemporaryFile(dir=td) + def fake_formatter(dirname,fnames,included_suffixes): + return ["hello","world"] + fl = display.FileLinks(td,notebook_display_formatter=fake_formatter) + actual = fl._repr_html_() + actual = actual.split('\n') + actual.sort() + expected = ["hello","world"] + expected.sort() + # We compare the sorted list of links here as that's more reliable + nt.assert_equal(actual,expected) + +def test_existing_path_FileLinks_repr(): + """FileLinks: Calling repr() functions as expected on existing directory """ + td = mkdtemp() + tf1 = NamedTemporaryFile(dir=td) + tf2 = NamedTemporaryFile(dir=td) + fl = display.FileLinks(td) + actual = repr(fl) + actual = actual.split('\n') + actual.sort() + expected = ['%s/' % td, ' %s' % split(tf1.name)[1],' %s' % split(tf2.name)[1]] + expected.sort() + # We compare the sorted list of links here as that's more reliable + nt.assert_equal(actual,expected) + +def test_existing_path_FileLinks_repr_alt_formatter(): + """FileLinks: Calling repr() functions as expected w/ alt formatter + """ + td = mkdtemp() + tf1 = NamedTemporaryFile(dir=td) + tf2 = NamedTemporaryFile(dir=td) + def fake_formatter(dirname,fnames,included_suffixes): + return ["hello","world"] + fl = display.FileLinks(td,terminal_display_formatter=fake_formatter) + actual = repr(fl) + actual = actual.split('\n') + actual.sort() + expected = ["hello","world"] + expected.sort() + # We compare the sorted list of links here as that's more reliable + nt.assert_equal(actual,expected) + +def test_error_on_file_to_FileLinks(): + """FileLinks: Raises error when passed file + """ + td = mkdtemp() + tf1 = NamedTemporaryFile(dir=td) + nt.assert_raises(ValueError,display.FileLinks,tf1.name) + +def test_recursive_FileLinks(): + """FileLinks: Does not recurse when recursive=False + """ + td = mkdtemp() + tf = NamedTemporaryFile(dir=td) + subtd = mkdtemp(dir=td) + subtf = NamedTemporaryFile(dir=subtd) + fl = display.FileLinks(td) + actual = str(fl) + actual = actual.split('\n') + nt.assert_equal(len(actual), 4, actual) + fl = display.FileLinks(td, recursive=False) + actual = str(fl) + actual = actual.split('\n') + nt.assert_equal(len(actual), 2, actual) + +def test_audio_from_file(): + path = pjoin(dirname(__file__), 'test.wav') + display.Audio(filename=path) + +class TestAudioDataWithNumpy(TestCase): + + @skipif_not_numpy + def test_audio_from_numpy_array(self): + test_tone = get_test_tone() + audio = display.Audio(test_tone, rate=44100) + nt.assert_equal(len(read_wav(audio.data)), len(test_tone)) + + @skipif_not_numpy + def test_audio_from_list(self): + test_tone = get_test_tone() + audio = display.Audio(list(test_tone), rate=44100) + nt.assert_equal(len(read_wav(audio.data)), len(test_tone)) + + @skipif_not_numpy + def test_audio_from_numpy_array_without_rate_raises(self): + nt.assert_raises(ValueError, display.Audio, get_test_tone()) + + @skipif_not_numpy + def test_audio_data_normalization(self): + expected_max_value = numpy.iinfo(numpy.int16).max + for scale in [1, 0.5, 2]: + audio = display.Audio(get_test_tone(scale), rate=44100) + actual_max_value = numpy.max(numpy.abs(read_wav(audio.data))) + nt.assert_equal(actual_max_value, expected_max_value) + + @skipif_not_numpy + def test_audio_data_without_normalization(self): + max_int16 = numpy.iinfo(numpy.int16).max + for scale in [1, 0.5, 0.2]: + test_tone = get_test_tone(scale) + test_tone_max_abs = numpy.max(numpy.abs(test_tone)) + expected_max_value = int(max_int16 * test_tone_max_abs) + audio = display.Audio(test_tone, rate=44100, normalize=False) + actual_max_value = numpy.max(numpy.abs(read_wav(audio.data))) + nt.assert_equal(actual_max_value, expected_max_value) + + def test_audio_data_without_normalization_raises_for_invalid_data(self): + nt.assert_raises( + ValueError, + lambda: display.Audio([1.001], rate=44100, normalize=False)) + nt.assert_raises( + ValueError, + lambda: display.Audio([-1.001], rate=44100, normalize=False)) + +def simulate_numpy_not_installed(): + try: + import numpy + return mock.patch('numpy.array', mock.MagicMock(side_effect=ImportError)) + except ModuleNotFoundError: + return lambda x:x + +@simulate_numpy_not_installed() +class TestAudioDataWithoutNumpy(TestAudioDataWithNumpy): + # All tests from `TestAudioDataWithNumpy` are inherited. + + @skipif_not_numpy + def test_audio_raises_for_nested_list(self): + stereo_signal = [list(get_test_tone())] * 2 + nt.assert_raises( + TypeError, + lambda: display.Audio(stereo_signal, rate=44100)) + +@skipif_not_numpy +def get_test_tone(scale=1): + return numpy.sin(2 * numpy.pi * 440 * numpy.linspace(0, 1, 44100)) * scale + +def read_wav(data): + with wave.open(BytesIO(data)) as wave_file: + wave_data = wave_file.readframes(wave_file.getnframes()) + num_samples = wave_file.getnframes() * wave_file.getnchannels() + return struct.unpack('<%sh' % num_samples, wave_data) + +def test_code_from_file(): + c = display.Code(filename=__file__) + assert c._repr_html_().startswith('') + + # Italic, bold and underline. + HTML('...') + HTML('...') + HTML('...') + + All HTML elements become available as a "class" in the style sheet. + E.g. ``...`` can be styled, by setting a style for + ``username``. + """ + + def __init__(self, value: str) -> None: + self.value = value + document = minidom.parseString("%s" % (value,)) + + result: StyleAndTextTuples = [] + name_stack: List[str] = [] + fg_stack: List[str] = [] + bg_stack: List[str] = [] + + def get_current_style() -> str: + " Build style string for current node. " + parts = [] + if name_stack: + parts.append("class:" + ",".join(name_stack)) + + if fg_stack: + parts.append("fg:" + fg_stack[-1]) + if bg_stack: + parts.append("bg:" + bg_stack[-1]) + return " ".join(parts) + + def process_node(node: Any) -> None: + " Process node recursively. " + for child in node.childNodes: + if child.nodeType == child.TEXT_NODE: + result.append((get_current_style(), child.data)) + else: + add_to_name_stack = child.nodeName not in ( + "#document", + "html-root", + "style", + ) + fg = bg = "" + + for k, v in child.attributes.items(): + if k == "fg": + fg = v + if k == "bg": + bg = v + if k == "color": + fg = v # Alias for 'fg'. + + # Check for spaces in attributes. This would result in + # invalid style strings otherwise. + if " " in fg: + raise ValueError('"fg" attribute contains a space.') + if " " in bg: + raise ValueError('"bg" attribute contains a space.') + + if add_to_name_stack: + name_stack.append(child.nodeName) + if fg: + fg_stack.append(fg) + if bg: + bg_stack.append(bg) + + process_node(child) + + if add_to_name_stack: + name_stack.pop() + if fg: + fg_stack.pop() + if bg: + bg_stack.pop() + + process_node(document) + + self.formatted_text = FormattedText(result) + + def __repr__(self) -> str: + return "HTML(%r)" % (self.value,) + + def __pt_formatted_text__(self) -> StyleAndTextTuples: + return self.formatted_text + + def format(self, *args: object, **kwargs: object) -> "HTML": + """ + Like `str.format`, but make sure that the arguments are properly + escaped. + """ + # Escape all the arguments. + escaped_args = [html_escape(a) for a in args] + escaped_kwargs = {k: html_escape(v) for k, v in kwargs.items()} + + return HTML(self.value.format(*escaped_args, **escaped_kwargs)) + + def __mod__(self, value: Union[object, Tuple[object, ...]]) -> "HTML": + """ + HTML('%s') % value + """ + if not isinstance(value, tuple): + value = (value,) + + value = tuple(html_escape(i) for i in value) + return HTML(self.value % value) + + +def html_escape(text: object) -> str: + # The string interpolation functions also take integers and other types. + # Convert to string first. + if not isinstance(text, str): + text = "{}".format(text) + + return ( + text.replace("&", "&") + .replace("<", "<") + .replace(">", ">") + .replace('"', """) + ) diff --git a/.venv/lib/python3.8/site-packages/prompt_toolkit/formatted_text/pygments.py b/.venv/lib/python3.8/site-packages/prompt_toolkit/formatted_text/pygments.py new file mode 100644 index 00000000..dd16f0ef --- /dev/null +++ b/.venv/lib/python3.8/site-packages/prompt_toolkit/formatted_text/pygments.py @@ -0,0 +1,30 @@ +from typing import TYPE_CHECKING, List, Tuple + +from prompt_toolkit.styles.pygments import pygments_token_to_classname + +from .base import StyleAndTextTuples + +if TYPE_CHECKING: + from pygments.token import Token + +__all__ = [ + "PygmentsTokens", +] + + +class PygmentsTokens: + """ + Turn a pygments token list into a list of prompt_toolkit text fragments + (``(style_str, text)`` tuples). + """ + + def __init__(self, token_list: List[Tuple["Token", str]]) -> None: + self.token_list = token_list + + def __pt_formatted_text__(self) -> StyleAndTextTuples: + result: StyleAndTextTuples = [] + + for token, text in self.token_list: + result.append(("class:" + pygments_token_to_classname(token), text)) + + return result diff --git a/.venv/lib/python3.8/site-packages/prompt_toolkit/formatted_text/utils.py b/.venv/lib/python3.8/site-packages/prompt_toolkit/formatted_text/utils.py new file mode 100644 index 00000000..7d48762d --- /dev/null +++ b/.venv/lib/python3.8/site-packages/prompt_toolkit/formatted_text/utils.py @@ -0,0 +1,85 @@ +""" +Utilities for manipulating formatted text. + +When ``to_formatted_text`` has been called, we get a list of ``(style, text)`` +tuples. This file contains functions for manipulating such a list. +""" +from typing import Iterable, cast + +from prompt_toolkit.utils import get_cwidth + +from .base import OneStyleAndTextTuple, StyleAndTextTuples + +__all__ = [ + "fragment_list_len", + "fragment_list_width", + "fragment_list_to_text", + "split_lines", +] + + +def fragment_list_len(fragments: StyleAndTextTuples) -> int: + """ + Return the amount of characters in this text fragment list. + + :param fragments: List of ``(style_str, text)`` or + ``(style_str, text, mouse_handler)`` tuples. + """ + ZeroWidthEscape = "[ZeroWidthEscape]" + return sum(len(item[1]) for item in fragments if ZeroWidthEscape not in item[0]) + + +def fragment_list_width(fragments: StyleAndTextTuples) -> int: + """ + Return the character width of this text fragment list. + (Take double width characters into account.) + + :param fragments: List of ``(style_str, text)`` or + ``(style_str, text, mouse_handler)`` tuples. + """ + ZeroWidthEscape = "[ZeroWidthEscape]" + return sum( + get_cwidth(c) + for item in fragments + for c in item[1] + if ZeroWidthEscape not in item[0] + ) + + +def fragment_list_to_text(fragments: StyleAndTextTuples) -> str: + """ + Concatenate all the text parts again. + + :param fragments: List of ``(style_str, text)`` or + ``(style_str, text, mouse_handler)`` tuples. + """ + ZeroWidthEscape = "[ZeroWidthEscape]" + return "".join(item[1] for item in fragments if ZeroWidthEscape not in item[0]) + + +def split_lines(fragments: StyleAndTextTuples) -> Iterable[StyleAndTextTuples]: + """ + Take a single list of (style_str, text) tuples and yield one such list for each + line. Just like str.split, this will yield at least one item. + + :param fragments: List of (style_str, text) or (style_str, text, mouse_handler) + tuples. + """ + line: StyleAndTextTuples = [] + + for style, string, *mouse_handler in fragments: + parts = string.split("\n") + + for part in parts[:-1]: + if part: + line.append(cast(OneStyleAndTextTuple, (style, part, *mouse_handler))) + yield line + line = [] + + line.append(cast(OneStyleAndTextTuple, (style, parts[-1], *mouse_handler))) + + # Always yield the last line, even when this is an empty line. This ensures + # that when `fragments` ends with a newline character, an additional empty + # line is yielded. (Otherwise, there's no way to differentiate between the + # cases where `fragments` does and doesn't end with a newline.) + yield line diff --git a/.venv/lib/python3.8/site-packages/prompt_toolkit/history.py b/.venv/lib/python3.8/site-packages/prompt_toolkit/history.py new file mode 100644 index 00000000..72acec9d --- /dev/null +++ b/.venv/lib/python3.8/site-packages/prompt_toolkit/history.py @@ -0,0 +1,232 @@ +""" +Implementations for the history of a `Buffer`. + +NOTE: Notice that there is no `DynamicHistory`. This doesn't work well, because + the `Buffer` needs to be able to attach an event handler to the event + when a history entry is loaded. This loading can be done asynchronously + and making the history swappable would probably break this. +""" +import datetime +import os +from abc import ABCMeta, abstractmethod +from threading import Thread +from typing import Callable, Iterable, List, Optional + +__all__ = [ + "History", + "ThreadedHistory", + "DummyHistory", + "FileHistory", + "InMemoryHistory", +] + + +class History(metaclass=ABCMeta): + """ + Base ``History`` class. + + This also includes abstract methods for loading/storing history. + """ + + def __init__(self) -> None: + # In memory storage for strings. + self._loaded = False + self._loaded_strings: List[str] = [] + + # + # Methods expected by `Buffer`. + # + + def load(self, item_loaded_callback: Callable[[str], None]) -> None: + """ + Load the history and call the callback for every entry in the history. + + XXX: The callback can be called from another thread, which happens in + case of `ThreadedHistory`. + + We can't assume that an asyncio event loop is running, and + schedule the insertion into the `Buffer` using the event loop. + + The reason is that the creation of the :class:`.History` object as + well as the start of the loading happens *before* + `Application.run()` is called, and it can continue even after + `Application.run()` terminates. (Which is useful to have a + complete history during the next prompt.) + + Calling `get_event_loop()` right here is also not guaranteed to + return the same event loop which is used in `Application.run`, + because a new event loop can be created during the `run`. This is + useful in Python REPLs, where we want to use one event loop for + the prompt, and have another one active during the `eval` of the + commands. (Otherwise, the user can schedule a while/true loop and + freeze the UI.) + """ + if self._loaded: + for item in self._loaded_strings[::-1]: + item_loaded_callback(item) + return + + try: + for item in self.load_history_strings(): + self._loaded_strings.insert(0, item) + item_loaded_callback(item) + finally: + self._loaded = True + + def get_strings(self) -> List[str]: + """ + Get the strings from the history that are loaded so far. + """ + return self._loaded_strings + + def append_string(self, string: str) -> None: + " Add string to the history. " + self._loaded_strings.append(string) + self.store_string(string) + + # + # Implementation for specific backends. + # + + @abstractmethod + def load_history_strings(self) -> Iterable[str]: + """ + This should be a generator that yields `str` instances. + + It should yield the most recent items first, because they are the most + important. (The history can already be used, even when it's only + partially loaded.) + """ + while False: + yield + + @abstractmethod + def store_string(self, string: str) -> None: + """ + Store the string in persistent storage. + """ + + +class ThreadedHistory(History): + """ + Wrapper that runs the `load_history_strings` generator in a thread. + + Use this to increase the start-up time of prompt_toolkit applications. + History entries are available as soon as they are loaded. We don't have to + wait for everything to be loaded. + """ + + def __init__(self, history: History) -> None: + self.history = history + self._load_thread: Optional[Thread] = None + self._item_loaded_callbacks: List[Callable[[str], None]] = [] + super().__init__() + + def load(self, item_loaded_callback: Callable[[str], None]) -> None: + self._item_loaded_callbacks.append(item_loaded_callback) + + # Start the load thread, if we don't have a thread yet. + if not self._load_thread: + + def call_all_callbacks(item: str) -> None: + for cb in self._item_loaded_callbacks: + cb(item) + + self._load_thread = Thread( + target=self.history.load, args=(call_all_callbacks,) + ) + self._load_thread.daemon = True + self._load_thread.start() + + def get_strings(self) -> List[str]: + return self.history.get_strings() + + def append_string(self, string: str) -> None: + self.history.append_string(string) + + # All of the following are proxied to `self.history`. + + def load_history_strings(self) -> Iterable[str]: + return self.history.load_history_strings() + + def store_string(self, string: str) -> None: + self.history.store_string(string) + + def __repr__(self) -> str: + return "ThreadedHistory(%r)" % (self.history,) + + +class InMemoryHistory(History): + """ + :class:`.History` class that keeps a list of all strings in memory. + """ + + def load_history_strings(self) -> Iterable[str]: + return [] + + def store_string(self, string: str) -> None: + pass + + +class DummyHistory(History): + """ + :class:`.History` object that doesn't remember anything. + """ + + def load_history_strings(self) -> Iterable[str]: + return [] + + def store_string(self, string: str) -> None: + pass + + def append_string(self, string: str) -> None: + # Don't remember this. + pass + + +class FileHistory(History): + """ + :class:`.History` class that stores all strings in a file. + """ + + def __init__(self, filename: str) -> None: + self.filename = filename + super(FileHistory, self).__init__() + + def load_history_strings(self) -> Iterable[str]: + strings: List[str] = [] + lines: List[str] = [] + + def add() -> None: + if lines: + # Join and drop trailing newline. + string = "".join(lines)[:-1] + + strings.append(string) + + if os.path.exists(self.filename): + with open(self.filename, "rb") as f: + for line_bytes in f: + line = line_bytes.decode("utf-8") + + if line.startswith("+"): + lines.append(line[1:]) + else: + add() + lines = [] + + add() + + # Reverse the order, because newest items have to go first. + return reversed(strings) + + def store_string(self, string: str) -> None: + # Save to file. + with open(self.filename, "ab") as f: + + def write(t: str) -> None: + f.write(t.encode("utf-8")) + + write("\n# %s\n" % datetime.datetime.now()) + for line in string.split("\n"): + write("+%s\n" % line) diff --git a/.venv/lib/python3.8/site-packages/prompt_toolkit/input/__init__.py b/.venv/lib/python3.8/site-packages/prompt_toolkit/input/__init__.py new file mode 100644 index 00000000..421d4ccd --- /dev/null +++ b/.venv/lib/python3.8/site-packages/prompt_toolkit/input/__init__.py @@ -0,0 +1,11 @@ +from .base import DummyInput, Input +from .defaults import create_input, create_pipe_input + +__all__ = [ + # Base. + "Input", + "DummyInput", + # Defaults. + "create_input", + "create_pipe_input", +] diff --git a/.venv/lib/python3.8/site-packages/prompt_toolkit/input/__pycache__/__init__.cpython-38.pyc b/.venv/lib/python3.8/site-packages/prompt_toolkit/input/__pycache__/__init__.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ae32a7f6201b49dcac4615b48894c42ee7edc730 GIT binary patch literal 335 zcmYjMu};G<5RDzD2~{hV&&UvhkQk5<0*Qr%1+io~xwRot?Z!B^P$#~J&tYNk%ET{p zfpe%tPr7${Pxo~19_RCEg7x$E2_HDWA~`IEcw=v#@Y#b=gR#tK+p&RAnJu{uzOEyKbr4eEb zn<3nnd0&HA>{0Ya*xl4ln;H*Peq;D*Ek*U(N~x-g yb8zj;Sz8<1YvaK6y;^s!9+TC82|EXHVz!~U)V=UZUd6|T8Nz}r7$uZq?|uQh!c|iM literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/prompt_toolkit/input/__pycache__/ansi_escape_sequences.cpython-38.pyc b/.venv/lib/python3.8/site-packages/prompt_toolkit/input/__pycache__/ansi_escape_sequences.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..1d7b9407daed4d6cbcb38945d1a2c445fcc32675 GIT binary patch literal 6205 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 Ku1Qbr-T6O^d83^G literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/prompt_toolkit/input/__pycache__/base.cpython-38.pyc b/.venv/lib/python3.8/site-packages/prompt_toolkit/input/__pycache__/base.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..70afa10e66f3078daf9738944b7134eaf0bfa0eb GIT binary patch literal 5281 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 GHTC~}#B}=r literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/prompt_toolkit/input/__pycache__/defaults.cpython-38.pyc b/.venv/lib/python3.8/site-packages/prompt_toolkit/input/__pycache__/defaults.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ce9e312dddf015dd7b379ccdade7e79fcfa829fd GIT binary patch literal 1554 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 VMQ!F+6nj^0Ex+ZjhQX_-@h=nAs3iaZ literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/prompt_toolkit/input/__pycache__/typeahead.cpython-38.pyc b/.venv/lib/python3.8/site-packages/prompt_toolkit/input/__pycache__/typeahead.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d1225da0d4a80872c5da80ce6f82e70c38da0745 GIT binary patch literal 2770 zcmZuzU60#D6t$gfHt}XZS_-1557Q?aX*b&z@j$66N=wCxs;pW{r3fiIv2S9tj>nxD zH%+yO2lyEkY9ITDc*rYHYkO^cBSNsWC6j>Tcn_^2O^N%?ns1Ri#98s*<+;*CeK+V@`!ZEn;bE24?uc*R& zrlS$*xwc*LgupiMbAl>k0S9MHSrkg!ki&&#Cy>;q2YG_i#2JVc1DnVk(Zl%^wr~Vi z5DAD5%UqKwRBqB|v}AKaH$oxyDs;?Clt?WjOZsy+Uq}tk-?30}iom%t25F8I8zJ5# z1@EzP8G(9npbMz!sB>h!!xmS9raT5AOeIv-&<+@ek~8hDa)EF;sD&*SQ5ei4YnG5v znnrNwI8DQ08l^}?E}=t^p-=)wAtA#;(~wxKVnc0;g4g0EtvsCt}K!j(J(E$OEFNPOr4XFkxdABo93uiB&Cj$ z)FQP@O-^pEg$#M7MFzPuai~oCT--i9FuPz8RpWv~-Gawunugd4N;0Ji*MERTrt)ljjaaiJ2E=DBV5o&r|*eji*s)GQwRZa}IT&?!4QrR(-JGy<^B#ye_ zTfFAHjz8M~Z?eqLf+O1rX7#)HKdawQjeQ$bJDT6n^bn34$4+ct&~bHDhVA>n)Mjk)i^iBd$;=j1j)bGzWB9&$6Tj+E~GpbnwvY;DkhNoGKo=egBOGM+- z%bV2)5(&o9u_aVEEY&kqO_eV-Jj}MSkfW8lmy7B5ox+Y9&4^Y|at>)GVb;7^^^aSu dxA_pa#^tuZ6SVzyE%5R8cfE0`_Cf1H`(M!zOHKd) literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/prompt_toolkit/input/__pycache__/vt100.cpython-38.pyc b/.venv/lib/python3.8/site-packages/prompt_toolkit/input/__pycache__/vt100.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c8e0f430a16de493ff8e1c6ce5a2c590b276dce4 GIT binary patch literal 7692 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 literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/prompt_toolkit/input/__pycache__/win32.cpython-38.pyc b/.venv/lib/python3.8/site-packages/prompt_toolkit/input/__pycache__/win32.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..5d69ed07c20ca72729721422df7f7c807c7cdf3b GIT binary patch literal 16196 zcmbt*dvF}rnpbyE&qJfp=wVrY#%ae+?1^pp73bmjW^K!|t;CVNk{l;pdl`+VThd7L zkWaU4Yj$*RRh-@U!Y*VNb}1lL*i}H?@T!HsV1ecRs-j?7V1cfJ4Z9Z>S5Xuc#Znd6 z8-Bm9dwOOh`QE!Q_V?+$pWpdj=k)D?fvkq#*Wdp2;<-DT_FIf}|5Aut1bCn6n&xPZ zUe)aIuWsuSH*5ocjcTH1+NRFDL^WAU*(nK|)pRXmXC$1g_SLd>w$^X=OFUK0)duW= zTHek}JY5~E4cSArVSBhXVvp2z*gI;Y_GoRVy|XrEk4c$Kbysb-y<5V4)jhSn_TJh) zd!NL!)%~>>>=z{5Up-KJ(SA|FxvEt=XdjgDK=q~CA^TA6uzk4pvi)-H75kOi5&H=8 z^3GuOXsuuuBs^4owRX%thVZa6;_Prnot@6uV#+>#O>=fRyFbyK-R`kR3Ht=%dz@j! zhuss1k0ZX<89{vHkzt=iY@f3qvHgghax?A;cW4o-xM1wjoEJVfoCD6zPs~TUeVTdB zi=XR`<%~(n8Pq-K>_FWesCyQ%mz+_=M%}aM=QT&4)e486aj&KedXO*O^?X$-`!&~J zYB)?;bp4`x->v(_YNN5rlyal)yASk zXHz%7(1ZPItzN9ui|#|WyyiDl@j=C3Dn`RWrz2(MmV6h<^|NQfK?g$*N)^AjfWk{9 zjLr2hgUoyG`Yq*p44Vk^Z~pzpn&(b(qI2u3ZXp@urlxP*o-58wPH-ke?@fMGocv&N zI!+mR|K{!4$=x8z`%Gph8USZg?L&|hveR$M2HjFf!8R9=dvUy-Ip z9CveCnVa4HOCoX+;JpUqYCMoQjJln03?~6nGM(fnIFxSEO}S}FNjYf}7YHun7$Bfb zFj(x2`Eto~n{Q_={1~*#)sp8~*aB<5Q)u48c0>ucDy!lA=EtSh^cQ-NQm((I>SeB3 z`^T^Wm;iV=AYXf=wX`AzJga@7PlE&o!f{*=_c|B|Ng>*LG;4Zpb>Rz5oj~oc-Z|;l zR!^>0R!^+eS4(9q;t@=g3(WtIe{FAb#C#B8t)%74# z1T})Xim!4&9GRv!cW+vW@phptQ{i-EDkcJ)f;x(T3{4%2Lma6Z2MSW*G?)-}mS~P` z?kp@)=;PSxrJ7qT2H7IXW39??u2{UcR;orh>0;4ol#4}mlFer@*;QBh>xwf`8KP4} zGJ+1`Sk%iv1dn__qnlDv+*ifP_|1?nNN11`u4JdA{9e5x&k#5Q1q(7@je z@;4VGh7u`oxwMl3A@)TneIU)O(~p#_+wbO3hABB`04W1#kuh*%#PaT-J0$TT@L2N6 z;jT8omr-VjJyr^Epq?;Fnu;=9z&qpW1Un=<)IF^IM0Xnn%CD+0MaT*Ui3rvltJ~|I%sGjds z>gos@D+{F|z#qee1i%{u;+c4&Kh<>2H{^6AV$v#@Xl4z2EE}#YlnzFto^saMmpdUHqTbjL)Gk&kv-UN4p*1@7XgZ9frC zLQVv!%E!@e>5s@?^yadxA6d$b@CB>HC88LzA~}TR!*bS2E3SuN#j~Va3$m zy^<;Nd~u48D1r6nPsU^VQ6}iEDL0&O*Hkg*dc%)q95>fHbL%-XK8(?9&vZfoB10Cs z>z!(tyJeP%_AK+!ESL2s##5QAFu6h^Fsl&riWC%>q`GZ;?_*AJ1tR)g6l}BD(XO?Q z3v3y~@0GnK7piOC()(Tg40ZJ*nLnft?xZn&^#^e9a<$>P&aJo)qla$7+~;>fEtl#?xe#pfVA>LGo!Czc2j z-nu93CrB++s&2ip?JTdLV>|A=momd@Tl(##ig3r8{ST;coe+-k{N2m@Pz*~;q{yX` zw^WKd)|-2}X5CwA%K+ku^JuiR<%n5#n6wcdilk7(w$r|fnod{m-E=CowsacLnp}sS zE@S55NesISCH*#9hh!|qo%IrIq-{X++OJNdj5GxJ5uF1H%)3y!)MdsG5|Pk?1ndmOT?c{qN=-6@tI^R`paF)$s_a&)ZGk0H z>n)Ze`xc4JL3#&(sJ!eo_oqkFBMB-oLx~am%ct`aE2BiukHfeK@E&4KyLB1YTuuT~ zfHWWj=mTT{{eT=`0FVa^0)_y?fDynBz$joRU<|Meup6)kuotioupjUO02QJmWcf#v}A>mFOOkBJzlQqBWxX zL=T7_60H+8iGGsE08;xI8X_V~dS(L6(SRG=w2j*LVb!l>JJcICE8A)FykKrLc_s;;jnv~F>aM(6daTwhgkP8 zj-I1$=sv8(NBV~0>n(j$+eow$kF*WbHy&%tiA9}u<u)8W>J0n2RuXxs zR_coO&2MeMV%^BJ(&~HuKr6kR_Xi&t-Y-dLXnAln3}(HC9A&FLA_XAb0hr`Qa=Q=GV1^MWB$LVQKH**_(tv;rFrr#UktP7due~;N(Y*|qCwi*l8eA^K=4+F{bOZBqrjayT` z^`KEdLfe#F5$tgtRz`i%f^(#YN5TeqP!gj4UyZuuG+dAE z-K{ptE8~T1JfJ1tUp;^FWX*Hx9UBZ*@>Ksh;~thzltDBy1oPN~Z-k~u(JA>Qa4KW`RFFWti^zEz zgX{$^FD9}2&VOO+WNj(f=*?r>khv__1*}V{>b*1GsTpX6Jt~cwY8MfQ8LDVxFzP!% z_V5fAySvFdiZfF00KsG@_n_e<>qnyCxlmoL4b2}KA#SVzGmU}Czo1O2KkAb-ihj1Y)PK2PZR(c30?HbzrF*I+d zOA1b=RW}%DI|j-P<#<5`t^pZwkXQs`)K}E!EN-lv=~Bss-?5p00`RCtYH8ER=ovkg z8Pd%}N;hS(Q(v1YXmZA=o=Id9roLa#!9A7J^LoxOb)@Q9)N1bPUO%pLR!{J{V{~Y z-Q-597l62!zU&gXvp9ABG_$z0;j(tb$j>1yiBlu4Rn5dw8aaK)FpcJ+ZI)^Ci70bX z+CNe*iLnguJ^_NKLtlmr29NT=rHxi%5BPM;mTlxAP*0h!S8SuA z0>izpWN$ZV2fv6iJGia1vNSWVXHr>x#2mp{$YO)@dUOAF+uPyje8@m~Hm9~uYa*3l{dNa%FK34Ix(f_Jg(AGhwV`Bnx0 zJqtedySUX_kK3bZao2_TU2S+?1@~bPp`mR8^P-Go7#Nhbkj^qt-jakGpb%=@PSjU* z9rBc3Oa4UUiDq3$cJYF(oc(=xf=#ZLonceV%W?t^Nj?ncb|PhopEvxq;6v}2?t zYVKOU2^Nt7S0!YP?dhm3cY3_mlwu@DVW7VZVNCvj)2@R?M#vz&F+cHfNLl(aI0H4i zCn?8xs)K7JoCM0vplE80`$8PX40ieK!gZUW87i#-i9z6f>BHR)+y2fE|EQz)k?ucL8<- z_5k(*_5t<-UH}{bya=!W2LUft`kowW8Ow(Wuu6;~PEdOspXuJ2o{{`~i+%q*>ap*a z0qpw~0Q)`yVBfHIr0)X$vhP;`?E4sieIEy~?-S4Mn=>_32E75JRF&ptD}-`BNPhWc1)0xus%c~AiAek^t0CatuLMF?Xl^OvJ~7cOcW$yO5O{_NIr zixBg5a}oBTNR@Q+c6!=>>XJ5XU94NMG?Q!o!ihJ((lrtC zfu8+Jw+i1-e+~yn#E1Ix2nG2|9#vB)W0OiXl$~6gSSl&I|8~7n#vL&uLCUQ&Z0A3y zC?6MqU}_V*KZd2c&J0g9gdkIc!Uyi-i6W@}IGVQyBW(~>W+BGhVED%5)w$xt+{}&Q zt(nQ$*~u%x$jsEW>zmRBX0K17T)T*Q!(H(0p{TLhrOJZOlpr}%SzPk%;qDAc3XI#U zw!9U9Dk|k~ui~u$gk^6lB0kOQjhfq=&XgcAS$Eo5{^ zJRmvkZbhLC+B2QSZMqwzCcSbAdj60Q%%vMKF%(jv3iC@OUtIKiYgOM)trg3p+ib}z zS1MsRhi53IPziUP&9dk(p!OxoqW^|~W{yEog;t-YEExWCza2BZ5r9{n+XH;e@Gp+8P^*%euUDj@jGTe@c&E= zu@{cgz$i0cnVDRwJ0**hp==7)OA0f~B$`J-6`S6LjBl$$Zjrmx%|-711On9E;I~MC z?|}nCHh$>Se9@N^3kEd0H#bbjcoOR7G+ffl8A$0c)b~hVOh6tdA(^v&zn_DwNAODr~4e!PBtCAps^M4|BTQ5pfHm*nFkGUC7)0m)Cs1Q5Sxs zXuaFn@G;Jnn|G$|Oc=g>OZ`b?sqYd|2eJp`jnA!yS0T3y^bZ65BlRbkEf)~9nQY$U zI`B1go&$ALtG)l~%+2?ULeQsY=Zcqa&&}POZZkRckJ&<2)XkzO`P-RUe-VX#g>*ZD zfM%Ko_T7N(s_*^UOpF>$YrCBdRlvvs(B}#_x4mx>tB<}l^$&pTwjqBh4qc8z6LIKD z9GZ+nSL4vNICMP@O@)%7-TZrT#trqCy8FdeM7--}9J&>UemoA%#G%4%x9JARF}X{Aj7e&+-06x#G8sh0a7pmDg$uRrg_>bh{4g0+$5}=A1M_ zj;8)9m-g=w{e7apL-eEMizeV(Sf$Y>3w+hAHHm;rqoB^B#yaqT2cpdNt z;7!0=cH-*kQ$(kU&Zxh_M*a~S84ks37Y9{;otgCcs=r2bjY#g;t}>J(5}Fn(k%qmZ z85rc?{i{2ESJrf&|4Va(sCAs3OT^|o`$>bHul6d<(+?K&c zZ4XV%V`&a1G84r_4vU13X<%`$*UObg_u$sxTwJu~S-$8s8g)FU;}E^lf{QnP;artl z!(H5_>54J#!NZ6iphj<+bX0Zv=G-K%_go9^kf@wnUaD8_@v6^jAPFyl;4E;&i@j9B z`yVWMSlE@$X)RmU{4LeM`=EvrzswE10-Cqr7>Fc*TnnO=atXcyEUNh8#1Za6gI|F! zf-kbVn&XaG^Rqbcy={(L;tt1jDz(*yf}5Q#0=Hb^h#G4OTZyMvOL)oI)mRNPD%C4q z%{q!=j&*n4nz{u)e4}1CjzLz};iFe89=69{lHJ&@V`*=C`)eLhaHs~*l&{DYnqYZM z89faMhTE>EHaU1f9&f~C<3!APUEc2w*B~eQO^P`Bif|!iwjU~nT7VbdK*1+@3MGO} zyZzADnqal)$0m5LndW^9=rL3kx&v@6mEpA%FMvMA<=zwHG5q$p%)u4VcW?m&10Jq| z3%J@t+e&3z~7rynOD8&2kD zjp*8|ulYv2O_v-8TMl~ZIbS?JvN)R_mQ8;(I8}#>u+sMEjE6geIraQ_(Ixj12M}mx zALGT3jyE>v;3RpBIXXJW@*%E0=|SdOS(6Xg6!%ehI2QF+8U7bQfl1O0SvwgzT$MP7 z>%Ys*p%X?k40>)(^gNp#-^_+^F%jKRNbNE!wtr|z_C`j01`&)h@mO2rMH=?taRR$^ zm`df7#AB$7SVfHcvHrw-EUIGX-AgjO<>08o3yyw~(jm#%qucQkynv$0RWQT55l&eB zE1)3PO{1OJtAB~iG$>!5t!jy!c(35#KK`T5Usm(i*k?u*%OLv!eZFFO2RpW5X^M2K z{wWdlJ@wCshJi5X;|!DjWxwoP$n%ThMGki|74D>ziD##NomDuM@LllG=I!D`bGg)l z6CX3oK)+1sS=^0e6Jy!k{mlbEc(!=?C> zx5P+=U0~eN>Z2x(BW^Zd3vV_*((3sSqnp^4Y=4t??&)@&J0Ojy#!|ZmTL!TM~{OMg)12(WjG-ncDUrfLDndVkrs@W%;NgW(CL;>895xw zA-d)d_HNZS1cqz2)2P1r>6Ivh+^q1`)xTvZPsCokM$#D$6`Nlp<**i1y}^8X?=ew# za2u8k-^TqavU*5@oSFQp4DjZGu$>yO1D192Xx@F{{2%b~ErD=p8j~~{&6a_?F_@iC z!ONPsp5bKYXe@!Gi$Bl${|KBlzyU{5b4CB`5eg$_#ombYfyPYjQgbJ_56qmt6 z5jaY~9^h7>7|22k2TNt!TW)>gO@0@-vdIv+*kpK5vB_Gr$?)Mr6oa|*bZ;cEv0A*b z33UZIN#6ZM+ZhTlnX>x#XcjC{=GB?}Zy>dcSSi8OVW3G)LhNU7Hkkwl&ncKXDY565 zKVLrrfEw-+?l7<&klrO1IM03M|&Uq|CnkPHpvY5KT-eqj1#_puM*A!H}PKtoj)xnbewRw=xv@XJf>>3oSIo2J7L zC-Aj_tMHu-Cq>4pfnY~LvdxjMsYQjhD(X~zIW(Cdl`Ht`pzvmwT09C!kkt=g_`PPqWwT%FY$DPJfzl^>3+$gWISJlN{T%^IeqE! z4Sei2as6iaeOsJ#V`_RbN*aqw-I}?H@7ZuM5TVF2+I|ImWaBz+$uLVMSvJ^#>@Np_~J{v#@c+xjI!?fv_0ruLE} zKcaFU@&m7j94tHYqlTRvc4WVevP z*=!<{$>*NW(`X{}@U$LBhqx?K@^rcxK94%TnPYXm(SI(}A_H3W+%>0hBIa4b;M$x^ zEL5JPE7JbvVP4HBihW%-s4Po6>-i5LSx7M>ug zE_~g_+Ci#JXR#MP-{R4<2g8(ch>9>P&8Epef)o`-=MQu`+B>!u4{sFh zeVcORIv~8Z@Ipua-c2QBDB?`_!l!V%(Sy8;2_*_&*w{Nub+1x%<+`cpx$pz=C1d#h z$-IkiP!-QffbSjYkSfYoit-hJve+6mU-{-sbPEyia%Q&M_#ks3{F?F|9kslxKzx11 zTPOY-!oS0OHWkJ9XOJqNM)LDW{QJtx4&{g5%70t?wzic2(9rkpg{nW4Kk|P8jzVX+ literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/prompt_toolkit/input/__pycache__/win32_pipe.cpython-38.pyc b/.venv/lib/python3.8/site-packages/prompt_toolkit/input/__pycache__/win32_pipe.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8783a9b726223bdb934792dcb1b4322c4e914e13 GIT binary patch literal 4580 zcmb_gO>^7E8O9eOeoLa{4>^gm`5Kw6MJ0CIB(CepRCU_4jmEX&b_O#Y1mZ45N&rDG zK&xVv=}e@V zT>tsoKm30!8pc2AVfrfI;S=1+-!X85o1qbzo@vtD3a!ZY?8xz)sNfaUnjN~)g13OV z!wX?CDtRR}cf)d2@hX@v@M2hvYF8<|S z;8k8Z#gkYTwG+p?!fQK5v;Gni8BH^D4|{zchD|#wZUtc&?1mz%Z^ivo{3ZQ7=m&d3 zX3p<>NebFVTZ$kRKDOMwIGvqcM+{rY0yo>J7wa z{lSnJRsNWM@c#Rc0+|SjlNbFz5l8j*mq8-3Mv$gKyE{IpN4v5H7jtWMwJ+z~CQQ?p zGk!>Zz(g3H$qmoqre|}@bGXf&@62zEj>!w$J*|2L;fe)XBQ2jgC#F~AC0;%?ypnKv zg;!4vtd&JYRJpxo@Y;74uk*!I$E%H3XzvnV#!6i*iY3s{N`tRpWqE34m0!V1L##lC ztKf2tU&r&RxPs?3Jm282;rZ$m*Vp+QSh+T}a+AM_mFpS>XZ$TZt$_ob_%?qBPdC0X z9K(AJ)_zwmLjl3}utk~S`l8!Q82$%+rj*MDFb+$*LCOwed62NU&!Ac!A0{om0p7r3 z$##!Yk+3%Q?F!Zrf@6OgW2aCoZi6Fd2jYk&sf-WKN#Qq~bz~eVZWHoWF32zuongp& z9d;<#VbD(*xF!P3h;}TajQ3;^MM2tY!&8sc(K)|hFbJ`p_TqkveI6$%2*zAH5PaD0 zfu~5)UVpDuR=c)iFdCyKU&c}KaIedH>3T9jf1Bh18}^JGmWiYtKv9W!Iu!jj;Kk2` z%tat2j(I;x5IFbl>4Qk)8p1D#@7+7O!`^DD%{f7fAo~=0x7O7T9;Cs#CXy6L+Z3@< zq(j+n)AQt_IXSzHJK4sN8Yjk?`P?v#)H*S~HGG?!7@a+u7gATby~XX*;t8!Ud~56% z9b>=5oevGm@JsZ(kI^r20}fQ!{&em&O0`qn>)q}bGvC}3;yn~(?Rxd zVH&`K+gH32{W7r=A?E}F#4!c5x8z2AFPrFa=bT(oLn3%|n%al(Gj$S@C`tM7unA(1H~I#%+w67nR)d{T{6E`>p$749`g(V50ZP z3h0~VtdI-`khD0VlrGjYSEo22X@_wlxLn1mtkJ8g@&|vQGFVpfK@lX0?`O8(E^GIO4$c=c&T>`INVO%C%mtbQ0mQ zNc!t3V!m=fZWKC8tQSCWVH3gz%Rr$0}`SHl7w6=>tkPU2YD^p=Y7tJZ&lJqjo#D_lAs1?{x=EXUU#N(n3E%%Yru_02RSqYoWO0X0S}k~CLFXi5nH3L&?2GX39k2XYBqDuC{h9L87us4>Ig(+R&Kj&l-sdAX zCx0L$q%5#cZArN{D=1>Er4201VlS)r3jCk(T7zFG zBQLw=Xl(}kIV~dBq1t?Tq*9_$etZ>^W8(~VJVWZ_)^m%j%57NH8Qowzlp%FXHEyC* zShm=xFibleA7yTDuOCZ6<+PNy2ARu6JLX~%gLf{2rKlC_1A;}yLE4`MbWTNpsPDKO zkd566(8OI)>P>=@TKo2y0~;3* z39=9A{l%D*RK;T4iR$g`sy*kTxuPz(C>72N#gjUuaq*NTI_R+A-Q@u8tf{9eHEM6Q{`LPR)%)89Fug%`*!IvbBMbV;oLZ12u_lQCp)+ zoGwTSI`VBKm2<;X6wPl`<<=FCf$OEZDySynE0S8-#;Tj6)mgde#5sxSIOSf{Npf_N z`}iokN`0p_`Xo;l>Z7F(zd;F$>H7mcJ^FA}w~@K!5&JT4tiL?Z8>1T4@D1gG8}B73 zVDG#NK|MVhh@eZ^up1=ZuL+8>xiflW2FOLq=Ihiu_Jc^E1uXkyzF|o7s_#D?2I2V4 zg75RV?fY5+ilwZG78k8&dXzc4=yK(IB-=U-w`d?+O46qM5e+}4f&QoG^&mIlCxB7*bTd0*lu1$lSwK`lwg+0m-v=c5iAp588!zbX)K{zSL{h~@+wP;E l0!I4wodT*L6Ht6RXhS`q#E?+aRW(Z6QL+F4 literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/prompt_toolkit/input/ansi_escape_sequences.py b/.venv/lib/python3.8/site-packages/prompt_toolkit/input/ansi_escape_sequences.py new file mode 100644 index 00000000..4589fbf9 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/prompt_toolkit/input/ansi_escape_sequences.py @@ -0,0 +1,331 @@ +""" +Mappings from VT100 (ANSI) escape sequences to the corresponding prompt_toolkit +keys. + +We are not using the terminfo/termcap databases to detect the ANSI escape +sequences for the input. Instead, we recognize 99% of the most common +sequences. This works well, because in practice, every modern terminal is +mostly Xterm compatible. + +Some useful docs: +- Mintty: https://github.com/mintty/mintty/blob/master/wiki/Keycodes.md +""" +from typing import Dict, Tuple, Union + +from ..keys import Keys + +__all__ = [ + "ANSI_SEQUENCES", + "REVERSE_ANSI_SEQUENCES", +] + +# Mapping of vt100 escape codes to Keys. +ANSI_SEQUENCES: Dict[str, Union[Keys, Tuple[Keys, ...]]] = { + # Control keys. + "\x00": Keys.ControlAt, # Control-At (Also for Ctrl-Space) + "\x01": Keys.ControlA, # Control-A (home) + "\x02": Keys.ControlB, # Control-B (emacs cursor left) + "\x03": Keys.ControlC, # Control-C (interrupt) + "\x04": Keys.ControlD, # Control-D (exit) + "\x05": Keys.ControlE, # Control-E (end) + "\x06": Keys.ControlF, # Control-F (cursor forward) + "\x07": Keys.ControlG, # Control-G + "\x08": Keys.ControlH, # Control-H (8) (Identical to '\b') + "\x09": Keys.ControlI, # Control-I (9) (Identical to '\t') + "\x0a": Keys.ControlJ, # Control-J (10) (Identical to '\n') + "\x0b": Keys.ControlK, # Control-K (delete until end of line; vertical tab) + "\x0c": Keys.ControlL, # Control-L (clear; form feed) + "\x0d": Keys.ControlM, # Control-M (13) (Identical to '\r') + "\x0e": Keys.ControlN, # Control-N (14) (history forward) + "\x0f": Keys.ControlO, # Control-O (15) + "\x10": Keys.ControlP, # Control-P (16) (history back) + "\x11": Keys.ControlQ, # Control-Q + "\x12": Keys.ControlR, # Control-R (18) (reverse search) + "\x13": Keys.ControlS, # Control-S (19) (forward search) + "\x14": Keys.ControlT, # Control-T + "\x15": Keys.ControlU, # Control-U + "\x16": Keys.ControlV, # Control-V + "\x17": Keys.ControlW, # Control-W + "\x18": Keys.ControlX, # Control-X + "\x19": Keys.ControlY, # Control-Y (25) + "\x1a": Keys.ControlZ, # Control-Z + "\x1b": Keys.Escape, # Also Control-[ + "\x9b": Keys.ShiftEscape, + "\x1c": Keys.ControlBackslash, # Both Control-\ (also Ctrl-| ) + "\x1d": Keys.ControlSquareClose, # Control-] + "\x1e": Keys.ControlCircumflex, # Control-^ + "\x1f": Keys.ControlUnderscore, # Control-underscore (Also for Ctrl-hyphen.) + # ASCII Delete (0x7f) + # Vt220 (and Linux terminal) send this when pressing backspace. We map this + # to ControlH, because that will make it easier to create key bindings that + # work everywhere, with the trade-off that it's no longer possible to + # handle backspace and control-h individually for the few terminals that + # support it. (Most terminals send ControlH when backspace is pressed.) + # See: http://www.ibb.net/~anne/keyboard.html + "\x7f": Keys.ControlH, + # -- + # Various + "\x1b[1~": Keys.Home, # tmux + "\x1b[2~": Keys.Insert, + "\x1b[3~": Keys.Delete, + "\x1b[4~": Keys.End, # tmux + "\x1b[5~": Keys.PageUp, + "\x1b[6~": Keys.PageDown, + "\x1b[7~": Keys.Home, # xrvt + "\x1b[8~": Keys.End, # xrvt + "\x1b[Z": Keys.BackTab, # shift + tab + # -- + # Function keys. + "\x1bOP": Keys.F1, + "\x1bOQ": Keys.F2, + "\x1bOR": Keys.F3, + "\x1bOS": Keys.F4, + "\x1b[[A": Keys.F1, # Linux console. + "\x1b[[B": Keys.F2, # Linux console. + "\x1b[[C": Keys.F3, # Linux console. + "\x1b[[D": Keys.F4, # Linux console. + "\x1b[[E": Keys.F5, # Linux console. + "\x1b[11~": Keys.F1, # rxvt-unicode + "\x1b[12~": Keys.F2, # rxvt-unicode + "\x1b[13~": Keys.F3, # rxvt-unicode + "\x1b[14~": Keys.F4, # rxvt-unicode + "\x1b[15~": Keys.F5, + "\x1b[17~": Keys.F6, + "\x1b[18~": Keys.F7, + "\x1b[19~": Keys.F8, + "\x1b[20~": Keys.F9, + "\x1b[21~": Keys.F10, + "\x1b[23~": Keys.F11, + "\x1b[24~": Keys.F12, + "\x1b[25~": Keys.F13, + "\x1b[26~": Keys.F14, + "\x1b[28~": Keys.F15, + "\x1b[29~": Keys.F16, + "\x1b[31~": Keys.F17, + "\x1b[32~": Keys.F18, + "\x1b[33~": Keys.F19, + "\x1b[34~": Keys.F20, + # Xterm + "\x1b[1;2P": Keys.F13, + "\x1b[1;2Q": Keys.F14, + # '\x1b[1;2R': Keys.F15, # Conflicts with CPR response. + "\x1b[1;2S": Keys.F16, + "\x1b[15;2~": Keys.F17, + "\x1b[17;2~": Keys.F18, + "\x1b[18;2~": Keys.F19, + "\x1b[19;2~": Keys.F20, + "\x1b[20;2~": Keys.F21, + "\x1b[21;2~": Keys.F22, + "\x1b[23;2~": Keys.F23, + "\x1b[24;2~": Keys.F24, + # -- + # Control + function keys. + "\x1b[1;5P": Keys.ControlF1, + "\x1b[1;5Q": Keys.ControlF2, + # "\x1b[1;5R": Keys.ControlF3, # Conflicts with CPR response. + "\x1b[1;5S": Keys.ControlF4, + "\x1b[15;5~": Keys.ControlF5, + "\x1b[17;5~": Keys.ControlF6, + "\x1b[18;5~": Keys.ControlF7, + "\x1b[19;5~": Keys.ControlF8, + "\x1b[20;5~": Keys.ControlF9, + "\x1b[21;5~": Keys.ControlF10, + "\x1b[23;5~": Keys.ControlF11, + "\x1b[24;5~": Keys.ControlF12, + "\x1b[1;6P": Keys.ControlF13, + "\x1b[1;6Q": Keys.ControlF14, + # "\x1b[1;6R": Keys.ControlF15, # Conflicts with CPR response. + "\x1b[1;6S": Keys.ControlF16, + "\x1b[15;6~": Keys.ControlF17, + "\x1b[17;6~": Keys.ControlF18, + "\x1b[18;6~": Keys.ControlF19, + "\x1b[19;6~": Keys.ControlF20, + "\x1b[20;6~": Keys.ControlF21, + "\x1b[21;6~": Keys.ControlF22, + "\x1b[23;6~": Keys.ControlF23, + "\x1b[24;6~": Keys.ControlF24, + # -- + # Tmux (Win32 subsystem) sends the following scroll events. + "\x1b[62~": Keys.ScrollUp, + "\x1b[63~": Keys.ScrollDown, + "\x1b[200~": Keys.BracketedPaste, # Start of bracketed paste. + # -- + # Sequences generated by numpad 5. Not sure what it means. (It doesn't + # appear in 'infocmp'. Just ignore. + "\x1b[E": Keys.Ignore, # Xterm. + "\x1b[G": Keys.Ignore, # Linux console. + # -- + # Meta/control/escape + pageup/pagedown/insert/delete. + "\x1b[3;2~": Keys.ShiftDelete, # xterm, gnome-terminal. + "\x1b[5;2~": Keys.ShiftPageUp, + "\x1b[6;2~": Keys.ShiftPageDown, + "\x1b[2;3~": (Keys.Escape, Keys.Insert), + "\x1b[3;3~": (Keys.Escape, Keys.Delete), + "\x1b[5;3~": (Keys.Escape, Keys.PageUp), + "\x1b[6;3~": (Keys.Escape, Keys.PageDown), + "\x1b[2;4~": (Keys.Escape, Keys.ShiftInsert), + "\x1b[3;4~": (Keys.Escape, Keys.ShiftDelete), + "\x1b[5;4~": (Keys.Escape, Keys.ShiftPageUp), + "\x1b[6;4~": (Keys.Escape, Keys.ShiftPageDown), + "\x1b[3;5~": Keys.ControlDelete, # xterm, gnome-terminal. + "\x1b[5;5~": Keys.ControlPageUp, + "\x1b[6;5~": Keys.ControlPageDown, + "\x1b[3;6~": Keys.ControlShiftDelete, + "\x1b[5;6~": Keys.ControlShiftPageUp, + "\x1b[6;6~": Keys.ControlShiftPageDown, + "\x1b[2;7~": (Keys.Escape, Keys.ControlInsert), + "\x1b[5;7~": (Keys.Escape, Keys.ControlPageDown), + "\x1b[6;7~": (Keys.Escape, Keys.ControlPageDown), + "\x1b[2;8~": (Keys.Escape, Keys.ControlShiftInsert), + "\x1b[5;8~": (Keys.Escape, Keys.ControlShiftPageDown), + "\x1b[6;8~": (Keys.Escape, Keys.ControlShiftPageDown), + # -- + # Arrows. + "\x1b[A": Keys.Up, + "\x1b[B": Keys.Down, + "\x1b[C": Keys.Right, + "\x1b[D": Keys.Left, + "\x1b[H": Keys.Home, + "\x1b[F": Keys.End, + # Tmux sends following keystrokes when control+arrow is pressed, but for + # Emacs ansi-term sends the same sequences for normal arrow keys. Consider + # it a normal arrow press, because that's more important. + "\x1bOA": Keys.Up, + "\x1bOB": Keys.Down, + "\x1bOC": Keys.Right, + "\x1bOD": Keys.Left, + "\x1bOF": Keys.End, + "\x1bOH": Keys.Home, + # Shift + arrows. + "\x1b[1;2A": Keys.ShiftUp, + "\x1b[1;2B": Keys.ShiftDown, + "\x1b[1;2C": Keys.ShiftRight, + "\x1b[1;2D": Keys.ShiftLeft, + "\x1b[1;2F": Keys.ShiftEnd, + "\x1b[1;2H": Keys.ShiftHome, + # Meta + arrow keys. Several terminals handle this differently. + # The following sequences are for xterm and gnome-terminal. + # (Iterm sends ESC followed by the normal arrow_up/down/left/right + # sequences, and the OSX Terminal sends ESCb and ESCf for "alt + # arrow_left" and "alt arrow_right." We don't handle these + # explicitly, in here, because would could not distinguish between + # pressing ESC (to go to Vi navigation mode), followed by just the + # 'b' or 'f' key. These combinations are handled in + # the input processor.) + "\x1b[1;3A": (Keys.Escape, Keys.Up), + "\x1b[1;3B": (Keys.Escape, Keys.Down), + "\x1b[1;3C": (Keys.Escape, Keys.Right), + "\x1b[1;3D": (Keys.Escape, Keys.Left), + "\x1b[1;3F": (Keys.Escape, Keys.End), + "\x1b[1;3H": (Keys.Escape, Keys.Home), + # Alt+shift+number. + "\x1b[1;4A": (Keys.Escape, Keys.ShiftDown), + "\x1b[1;4B": (Keys.Escape, Keys.ShiftUp), + "\x1b[1;4C": (Keys.Escape, Keys.ShiftRight), + "\x1b[1;4D": (Keys.Escape, Keys.ShiftLeft), + "\x1b[1;4F": (Keys.Escape, Keys.ShiftEnd), + "\x1b[1;4H": (Keys.Escape, Keys.ShiftHome), + # Control + arrows. + "\x1b[1;5A": Keys.ControlUp, # Cursor Mode + "\x1b[1;5B": Keys.ControlDown, # Cursor Mode + "\x1b[1;5C": Keys.ControlRight, # Cursor Mode + "\x1b[1;5D": Keys.ControlLeft, # Cursor Mode + "\x1b[1;5F": Keys.ControlEnd, + "\x1b[1;5H": Keys.ControlHome, + # Tmux sends following keystrokes when control+arrow is pressed, but for + # Emacs ansi-term sends the same sequences for normal arrow keys. Consider + # it a normal arrow press, because that's more important. + "\x1b[5A": Keys.ControlUp, + "\x1b[5B": Keys.ControlDown, + "\x1b[5C": Keys.ControlRight, + "\x1b[5D": Keys.ControlLeft, + "\x1bOc": Keys.ControlRight, # rxvt + "\x1bOd": Keys.ControlLeft, # rxvt + # Control + shift + arrows. + "\x1b[1;6A": Keys.ControlShiftDown, + "\x1b[1;6B": Keys.ControlShiftUp, + "\x1b[1;6C": Keys.ControlShiftRight, + "\x1b[1;6D": Keys.ControlShiftLeft, + "\x1b[1;6F": Keys.ControlShiftEnd, + "\x1b[1;6H": Keys.ControlShiftHome, + # Control + Meta + arrows. + "\x1b[1;7A": (Keys.Escape, Keys.ControlDown), + "\x1b[1;7B": (Keys.Escape, Keys.ControlUp), + "\x1b[1;7C": (Keys.Escape, Keys.ControlRight), + "\x1b[1;7D": (Keys.Escape, Keys.ControlLeft), + "\x1b[1;7F": (Keys.Escape, Keys.ControlEnd), + "\x1b[1;7H": (Keys.Escape, Keys.ControlHome), + # Meta + Shift + arrows. + "\x1b[1;8A": (Keys.Escape, Keys.ControlShiftDown), + "\x1b[1;8B": (Keys.Escape, Keys.ControlShiftUp), + "\x1b[1;8C": (Keys.Escape, Keys.ControlShiftRight), + "\x1b[1;8D": (Keys.Escape, Keys.ControlShiftLeft), + "\x1b[1;8F": (Keys.Escape, Keys.ControlShiftEnd), + "\x1b[1;8H": (Keys.Escape, Keys.ControlShiftHome), + # Meta + arrow on (some?) Macs when using iTerm defaults (see issue #483). + "\x1b[1;9A": (Keys.Escape, Keys.Up), + "\x1b[1;9B": (Keys.Escape, Keys.Down), + "\x1b[1;9C": (Keys.Escape, Keys.Right), + "\x1b[1;9D": (Keys.Escape, Keys.Left), + # -- + # Control/shift/meta + number in mintty. + # (c-2 will actually send c-@ and c-6 will send c-^.) + "\x1b[1;5p": Keys.Control0, + "\x1b[1;5q": Keys.Control1, + "\x1b[1;5r": Keys.Control2, + "\x1b[1;5s": Keys.Control3, + "\x1b[1;5t": Keys.Control4, + "\x1b[1;5u": Keys.Control5, + "\x1b[1;5v": Keys.Control6, + "\x1b[1;5w": Keys.Control7, + "\x1b[1;5x": Keys.Control8, + "\x1b[1;5y": Keys.Control9, + "\x1b[1;6p": Keys.ControlShift0, + "\x1b[1;6q": Keys.ControlShift1, + "\x1b[1;6r": Keys.ControlShift2, + "\x1b[1;6s": Keys.ControlShift3, + "\x1b[1;6t": Keys.ControlShift4, + "\x1b[1;6u": Keys.ControlShift5, + "\x1b[1;6v": Keys.ControlShift6, + "\x1b[1;6w": Keys.ControlShift7, + "\x1b[1;6x": Keys.ControlShift8, + "\x1b[1;6y": Keys.ControlShift9, + "\x1b[1;7p": (Keys.Escape, Keys.Control0), + "\x1b[1;7q": (Keys.Escape, Keys.Control1), + "\x1b[1;7r": (Keys.Escape, Keys.Control2), + "\x1b[1;7s": (Keys.Escape, Keys.Control3), + "\x1b[1;7t": (Keys.Escape, Keys.Control4), + "\x1b[1;7u": (Keys.Escape, Keys.Control5), + "\x1b[1;7v": (Keys.Escape, Keys.Control6), + "\x1b[1;7w": (Keys.Escape, Keys.Control7), + "\x1b[1;7x": (Keys.Escape, Keys.Control8), + "\x1b[1;7y": (Keys.Escape, Keys.Control9), + "\x1b[1;8p": (Keys.Escape, Keys.ControlShift0), + "\x1b[1;8q": (Keys.Escape, Keys.ControlShift1), + "\x1b[1;8r": (Keys.Escape, Keys.ControlShift2), + "\x1b[1;8s": (Keys.Escape, Keys.ControlShift3), + "\x1b[1;8t": (Keys.Escape, Keys.ControlShift4), + "\x1b[1;8u": (Keys.Escape, Keys.ControlShift5), + "\x1b[1;8v": (Keys.Escape, Keys.ControlShift6), + "\x1b[1;8w": (Keys.Escape, Keys.ControlShift7), + "\x1b[1;8x": (Keys.Escape, Keys.ControlShift8), + "\x1b[1;8y": (Keys.Escape, Keys.ControlShift9), +} + + +def _get_reverse_ansi_sequences() -> Dict[Keys, str]: + """ + Create a dictionary that maps prompt_toolkit keys back to the VT100 escape + sequences. + """ + result: Dict[Keys, str] = {} + + for sequence, key in ANSI_SEQUENCES.items(): + if not isinstance(key, tuple): + if key not in result: + result[key] = sequence + + return result + + +REVERSE_ANSI_SEQUENCES = _get_reverse_ansi_sequences() diff --git a/.venv/lib/python3.8/site-packages/prompt_toolkit/input/base.py b/.venv/lib/python3.8/site-packages/prompt_toolkit/input/base.py new file mode 100644 index 00000000..e701aa90 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/prompt_toolkit/input/base.py @@ -0,0 +1,137 @@ +""" +Abstraction of CLI Input. +""" +from abc import ABCMeta, abstractmethod, abstractproperty +from contextlib import contextmanager +from typing import Callable, ContextManager, Generator, List + +from prompt_toolkit.key_binding import KeyPress + +__all__ = [ + "Input", + "DummyInput", +] + + +class Input(metaclass=ABCMeta): + """ + Abstraction for any input. + + An instance of this class can be given to the constructor of a + :class:`~prompt_toolkit.application.Application` and will also be + passed to the :class:`~prompt_toolkit.eventloop.base.EventLoop`. + """ + + @abstractmethod + def fileno(self) -> int: + """ + Fileno for putting this in an event loop. + """ + + @abstractmethod + def typeahead_hash(self) -> str: + """ + Identifier for storing type ahead key presses. + """ + + @abstractmethod + def read_keys(self) -> List[KeyPress]: + """ + Return a list of Key objects which are read/parsed from the input. + """ + + def flush_keys(self) -> List[KeyPress]: + """ + Flush the underlying parser. and return the pending keys. + (Used for vt100 input.) + """ + return [] + + def flush(self) -> None: + " The event loop can call this when the input has to be flushed. " + pass + + @abstractproperty + def closed(self) -> bool: + " Should be true when the input stream is closed. " + return False + + @abstractmethod + def raw_mode(self) -> ContextManager[None]: + """ + Context manager that turns the input into raw mode. + """ + + @abstractmethod + def cooked_mode(self) -> ContextManager[None]: + """ + Context manager that turns the input into cooked mode. + """ + + @abstractmethod + def attach(self, input_ready_callback: Callable[[], None]) -> ContextManager[None]: + """ + Return a context manager that makes this input active in the current + event loop. + """ + + @abstractmethod + def detach(self) -> ContextManager[None]: + """ + Return a context manager that makes sure that this input is not active + in the current event loop. + """ + + def close(self) -> None: + " Close input. " + pass + + +class PipeInput(Input): + """ + Abstraction for pipe input. + """ + + @abstractmethod + def send_bytes(self, data: bytes) -> None: + """Feed byte string into the pipe""" + + @abstractmethod + def send_text(self, data: str) -> None: + """Feed a text string into the pipe""" + + +class DummyInput(Input): + """ + Input for use in a `DummyApplication` + """ + + def fileno(self) -> int: + raise NotImplementedError + + def typeahead_hash(self) -> str: + return "dummy-%s" % id(self) + + def read_keys(self) -> List[KeyPress]: + return [] + + @property + def closed(self) -> bool: + return True + + def raw_mode(self) -> ContextManager[None]: + return _dummy_context_manager() + + def cooked_mode(self) -> ContextManager[None]: + return _dummy_context_manager() + + def attach(self, input_ready_callback: Callable[[], None]) -> ContextManager[None]: + return _dummy_context_manager() + + def detach(self) -> ContextManager[None]: + return _dummy_context_manager() + + +@contextmanager +def _dummy_context_manager() -> Generator[None, None, None]: + yield diff --git a/.venv/lib/python3.8/site-packages/prompt_toolkit/input/defaults.py b/.venv/lib/python3.8/site-packages/prompt_toolkit/input/defaults.py new file mode 100644 index 00000000..27d28f44 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/prompt_toolkit/input/defaults.py @@ -0,0 +1,58 @@ +import sys +from typing import Optional, TextIO + +from prompt_toolkit.utils import is_windows + +from .base import Input, PipeInput + +__all__ = [ + "create_input", + "create_pipe_input", +] + + +def create_input( + stdin: Optional[TextIO] = None, always_prefer_tty: bool = False +) -> Input: + """ + Create the appropriate `Input` object for the current os/environment. + + :param always_prefer_tty: When set, if `sys.stdin` is connected to a Unix + `pipe`, check whether `sys.stdout` or `sys.stderr` are connected to a + pseudo terminal. If so, open the tty for reading instead of reading for + `sys.stdin`. (We can open `stdout` or `stderr` for reading, this is how + a `$PAGER` works.) + """ + if is_windows(): + from .win32 import Win32Input + + return Win32Input(stdin or sys.stdin) + else: + from .vt100 import Vt100Input + + # If no input TextIO is given, use stdin/stdout. + if stdin is None: + stdin = sys.stdin + + if always_prefer_tty: + for io in [sys.stdin, sys.stdout, sys.stderr]: + if io.isatty(): + stdin = io + break + + return Vt100Input(stdin) + + +def create_pipe_input() -> PipeInput: + """ + Create an input pipe. + This is mostly useful for unit testing. + """ + if is_windows(): + from .win32_pipe import Win32PipeInput + + return Win32PipeInput() + else: + from .posix_pipe import PosixPipeInput + + return PosixPipeInput() diff --git a/.venv/lib/python3.8/site-packages/prompt_toolkit/input/posix_pipe.py b/.venv/lib/python3.8/site-packages/prompt_toolkit/input/posix_pipe.py new file mode 100644 index 00000000..e01c4041 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/prompt_toolkit/input/posix_pipe.py @@ -0,0 +1,72 @@ +import os +from typing import ContextManager, TextIO, cast + +from ..utils import DummyContext +from .base import PipeInput +from .vt100 import Vt100Input + +__all__ = [ + "PosixPipeInput", +] + + +class PosixPipeInput(Vt100Input, PipeInput): + """ + Input that is send through a pipe. + This is useful if we want to send the input programmatically into the + application. Mostly useful for unit testing. + + Usage:: + + input = PosixPipeInput() + input.send_text('inputdata') + """ + + _id = 0 + + def __init__(self, text: str = "") -> None: + self._r, self._w = os.pipe() + + class Stdin: + encoding = "utf-8" + + def isatty(stdin) -> bool: + return True + + def fileno(stdin) -> int: + return self._r + + super().__init__(cast(TextIO, Stdin())) + self.send_text(text) + + # Identifier for every PipeInput for the hash. + self.__class__._id += 1 + self._id = self.__class__._id + + def send_bytes(self, data: bytes) -> None: + os.write(self._w, data) + + def send_text(self, data: str) -> None: + " Send text to the input. " + os.write(self._w, data.encode("utf-8")) + + def raw_mode(self) -> ContextManager[None]: + return DummyContext() + + def cooked_mode(self) -> ContextManager[None]: + return DummyContext() + + def close(self) -> None: + " Close pipe fds. " + os.close(self._r) + os.close(self._w) + + # We should assign `None` to 'self._r` and 'self._w', + # The event loop still needs to know the the fileno for this input in order + # to properly remove it from the selectors. + + def typeahead_hash(self) -> str: + """ + This needs to be unique for every `PipeInput`. + """ + return "pipe-input-%s" % (self._id,) diff --git a/.venv/lib/python3.8/site-packages/prompt_toolkit/input/posix_utils.py b/.venv/lib/python3.8/site-packages/prompt_toolkit/input/posix_utils.py new file mode 100644 index 00000000..f32f683f --- /dev/null +++ b/.venv/lib/python3.8/site-packages/prompt_toolkit/input/posix_utils.py @@ -0,0 +1,95 @@ +import os +import select +from codecs import getincrementaldecoder + +__all__ = [ + "PosixStdinReader", +] + + +class PosixStdinReader: + """ + Wrapper around stdin which reads (nonblocking) the next available 1024 + bytes and decodes it. + + Note that you can't be sure that the input file is closed if the ``read`` + function returns an empty string. When ``errors=ignore`` is passed, + ``read`` can return an empty string if all malformed input was replaced by + an empty string. (We can't block here and wait for more input.) So, because + of that, check the ``closed`` attribute, to be sure that the file has been + closed. + + :param stdin_fd: File descriptor from which we read. + :param errors: Can be 'ignore', 'strict' or 'replace'. + On Python3, this can be 'surrogateescape', which is the default. + + 'surrogateescape' is preferred, because this allows us to transfer + unrecognised bytes to the key bindings. Some terminals, like lxterminal + and Guake, use the 'Mxx' notation to send mouse events, where each 'x' + can be any possible byte. + """ + + # By default, we want to 'ignore' errors here. The input stream can be full + # of junk. One occurrence of this that I had was when using iTerm2 on OS X, + # with "Option as Meta" checked (You should choose "Option as +Esc".) + + def __init__( + self, stdin_fd: int, errors: str = "surrogateescape", encoding: str = "utf-8" + ) -> None: + self.stdin_fd = stdin_fd + self.errors = errors + + # Create incremental decoder for decoding stdin. + # We can not just do `os.read(stdin.fileno(), 1024).decode('utf-8')`, because + # it could be that we are in the middle of a utf-8 byte sequence. + self._stdin_decoder_cls = getincrementaldecoder(encoding) + self._stdin_decoder = self._stdin_decoder_cls(errors=errors) + + #: True when there is nothing anymore to read. + self.closed = False + + def read(self, count: int = 1024) -> str: + # By default we choose a rather small chunk size, because reading + # big amounts of input at once, causes the event loop to process + # all these key bindings also at once without going back to the + # loop. This will make the application feel unresponsive. + """ + Read the input and return it as a string. + + Return the text. Note that this can return an empty string, even when + the input stream was not yet closed. This means that something went + wrong during the decoding. + """ + if self.closed: + return "" + + # Check whether there is some input to read. `os.read` would block + # otherwise. + # (Actually, the event loop is responsible to make sure that this + # function is only called when there is something to read, but for some + # reason this happens in certain situations.) + try: + if not select.select([self.stdin_fd], [], [], 0)[0]: + return "" + except IOError: + # Happens for instance when the file descriptor was closed. + # (We had this in ptterm, where the FD became ready, a callback was + # scheduled, but in the meantime another callback closed it already.) + self.closed = True + + # Note: the following works better than wrapping `self.stdin` like + # `codecs.getreader('utf-8')(stdin)` and doing `read(1)`. + # Somehow that causes some latency when the escape + # character is pressed. (Especially on combination with the `select`.) + try: + data = os.read(self.stdin_fd, count) + + # Nothing more to read, stream is closed. + if data == b"": + self.closed = True + return "" + except OSError: + # In case of SIGWINCH + data = b"" + + return self._stdin_decoder.decode(data) diff --git a/.venv/lib/python3.8/site-packages/prompt_toolkit/input/typeahead.py b/.venv/lib/python3.8/site-packages/prompt_toolkit/input/typeahead.py new file mode 100644 index 00000000..a3d78664 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/prompt_toolkit/input/typeahead.py @@ -0,0 +1,76 @@ +r""" +Store input key strokes if we did read more than was required. + +The input classes `Vt100Input` and `Win32Input` read the input text in chunks +of a few kilobytes. This means that if we read input from stdin, it could be +that we read a couple of lines (with newlines in between) at once. + +This creates a problem: potentially, we read too much from stdin. Sometimes +people paste several lines at once because they paste input in a REPL and +expect each input() call to process one line. Or they rely on type ahead +because the application can't keep up with the processing. + +However, we need to read input in bigger chunks. We need this mostly to support +pasting of larger chunks of text. We don't want everything to become +unresponsive because we: + - read one character; + - parse one character; + - call the key binding, which does a string operation with one character; + - and render the user interface. +Doing text operations on single characters is very inefficient in Python, so we +prefer to work on bigger chunks of text. This is why we have to read the input +in bigger chunks. + +Further, line buffering is also not an option, because it doesn't work well in +the architecture. We use lower level Posix APIs, that work better with the +event loop and so on. In fact, there is also nothing that defines that only \n +can accept the input, you could create a key binding for any key to accept the +input. + +To support type ahead, this module will store all the key strokes that were +read too early, so that they can be feed into to the next `prompt()` call or to +the next prompt_toolkit `Application`. +""" +from collections import defaultdict +from typing import Dict, List + +from ..key_binding import KeyPress +from .base import Input + +__all__ = [ + "store_typeahead", + "get_typeahead", + "clear_typeahead", +] + +_buffer: Dict[str, List[KeyPress]] = defaultdict(list) + + +def store_typeahead(input_obj: Input, key_presses: List[KeyPress]) -> None: + """ + Insert typeahead key presses for the given input. + """ + global _buffer + key = input_obj.typeahead_hash() + _buffer[key].extend(key_presses) + + +def get_typeahead(input_obj: Input) -> List[KeyPress]: + """ + Retrieve typeahead and reset the buffer for this input. + """ + global _buffer + + key = input_obj.typeahead_hash() + result = _buffer[key] + _buffer[key] = [] + return result + + +def clear_typeahead(input_obj: Input) -> None: + """ + Clear typeahead buffer. + """ + global _buffer + key = input_obj.typeahead_hash() + _buffer[key] = [] diff --git a/.venv/lib/python3.8/site-packages/prompt_toolkit/input/vt100.py b/.venv/lib/python3.8/site-packages/prompt_toolkit/input/vt100.py new file mode 100644 index 00000000..ca06200a --- /dev/null +++ b/.venv/lib/python3.8/site-packages/prompt_toolkit/input/vt100.py @@ -0,0 +1,308 @@ +import contextlib +import io +import os +import sys +import termios +import tty +from asyncio import AbstractEventLoop, get_event_loop +from typing import ( + Callable, + ContextManager, + Dict, + Generator, + List, + Optional, + Set, + TextIO, + Tuple, + Union, +) + +from ..key_binding import KeyPress +from .base import Input +from .posix_utils import PosixStdinReader +from .vt100_parser import Vt100Parser + +__all__ = [ + "Vt100Input", + "raw_mode", + "cooked_mode", +] + + +class Vt100Input(Input): + """ + Vt100 input for Posix systems. + (This uses a posix file descriptor that can be registered in the event loop.) + """ + + # For the error messages. Only display "Input is not a terminal" once per + # file descriptor. + _fds_not_a_terminal: Set[int] = set() + + def __init__(self, stdin: TextIO) -> None: + # Test whether the given input object has a file descriptor. + # (Idle reports stdin to be a TTY, but fileno() is not implemented.) + try: + # This should not raise, but can return 0. + stdin.fileno() + except io.UnsupportedOperation as e: + if "idlelib.run" in sys.modules: + raise io.UnsupportedOperation( + "Stdin is not a terminal. Running from Idle is not supported." + ) from e + else: + raise io.UnsupportedOperation("Stdin is not a terminal.") from e + + # Even when we have a file descriptor, it doesn't mean it's a TTY. + # Normally, this requires a real TTY device, but people instantiate + # this class often during unit tests as well. They use for instance + # pexpect to pipe data into an application. For convenience, we print + # an error message and go on. + isatty = stdin.isatty() + fd = stdin.fileno() + + if not isatty and fd not in Vt100Input._fds_not_a_terminal: + msg = "Warning: Input is not a terminal (fd=%r).\n" + sys.stderr.write(msg % fd) + sys.stderr.flush() + Vt100Input._fds_not_a_terminal.add(fd) + + # + self.stdin = stdin + + # Create a backup of the fileno(). We want this to work even if the + # underlying file is closed, so that `typeahead_hash()` keeps working. + self._fileno = stdin.fileno() + + self._buffer: List[KeyPress] = [] # Buffer to collect the Key objects. + self.stdin_reader = PosixStdinReader(self._fileno, encoding=stdin.encoding) + self.vt100_parser = Vt100Parser( + lambda key_press: self._buffer.append(key_press) + ) + + def attach(self, input_ready_callback: Callable[[], None]) -> ContextManager[None]: + """ + Return a context manager that makes this input active in the current + event loop. + """ + return _attached_input(self, input_ready_callback) + + def detach(self) -> ContextManager[None]: + """ + Return a context manager that makes sure that this input is not active + in the current event loop. + """ + return _detached_input(self) + + def read_keys(self) -> List[KeyPress]: + " Read list of KeyPress. " + # Read text from stdin. + data = self.stdin_reader.read() + + # Pass it through our vt100 parser. + self.vt100_parser.feed(data) + + # Return result. + result = self._buffer + self._buffer = [] + return result + + def flush_keys(self) -> List[KeyPress]: + """ + Flush pending keys and return them. + (Used for flushing the 'escape' key.) + """ + # Flush all pending keys. (This is most important to flush the vt100 + # 'Escape' key early when nothing else follows.) + self.vt100_parser.flush() + + # Return result. + result = self._buffer + self._buffer = [] + return result + + @property + def closed(self) -> bool: + return self.stdin_reader.closed + + def raw_mode(self) -> ContextManager[None]: + return raw_mode(self.stdin.fileno()) + + def cooked_mode(self) -> ContextManager[None]: + return cooked_mode(self.stdin.fileno()) + + def fileno(self) -> int: + return self.stdin.fileno() + + def typeahead_hash(self) -> str: + return "fd-%s" % (self._fileno,) + + +_current_callbacks: Dict[ + Tuple[AbstractEventLoop, int], Optional[Callable[[], None]] +] = {} # (loop, fd) -> current callback + + +@contextlib.contextmanager +def _attached_input( + input: Vt100Input, callback: Callable[[], None] +) -> Generator[None, None, None]: + """ + Context manager that makes this input active in the current event loop. + + :param input: :class:`~prompt_toolkit.input.Input` object. + :param callback: Called when the input is ready to read. + """ + loop = get_event_loop() + fd = input.fileno() + previous = _current_callbacks.get((loop, fd)) + + def callback_wrapper() -> None: + """Wrapper around the callback that already removes the reader when + the input is closed. Otherwise, we keep continuously calling this + callback, until we leave the context manager (which can happen a bit + later). This fixes issues when piping /dev/null into a prompt_toolkit + application.""" + if input.closed: + loop.remove_reader(fd) + callback() + + loop.add_reader(fd, callback_wrapper) + _current_callbacks[loop, fd] = callback + + try: + yield + finally: + loop.remove_reader(fd) + + if previous: + loop.add_reader(fd, previous) + _current_callbacks[loop, fd] = previous + else: + del _current_callbacks[loop, fd] + + +@contextlib.contextmanager +def _detached_input(input: Vt100Input) -> Generator[None, None, None]: + loop = get_event_loop() + fd = input.fileno() + previous = _current_callbacks.get((loop, fd)) + + if previous: + loop.remove_reader(fd) + _current_callbacks[loop, fd] = None + + try: + yield + finally: + if previous: + loop.add_reader(fd, previous) + _current_callbacks[loop, fd] = previous + + +class raw_mode: + """ + :: + + with raw_mode(stdin): + ''' the pseudo-terminal stdin is now used in raw mode ''' + + We ignore errors when executing `tcgetattr` fails. + """ + + # There are several reasons for ignoring errors: + # 1. To avoid the "Inappropriate ioctl for device" crash if somebody would + # execute this code (In a Python REPL, for instance): + # + # import os; f = open(os.devnull); os.dup2(f.fileno(), 0) + # + # The result is that the eventloop will stop correctly, because it has + # to logic to quit when stdin is closed. However, we should not fail at + # this point. See: + # https://github.com/jonathanslenders/python-prompt-toolkit/pull/393 + # https://github.com/jonathanslenders/python-prompt-toolkit/issues/392 + + # 2. Related, when stdin is an SSH pipe, and no full terminal was allocated. + # See: https://github.com/jonathanslenders/python-prompt-toolkit/pull/165 + def __init__(self, fileno: int) -> None: + self.fileno = fileno + self.attrs_before: Optional[List[Union[int, List[bytes]]]] + try: + self.attrs_before = termios.tcgetattr(fileno) + except termios.error: + # Ignore attribute errors. + self.attrs_before = None + + def __enter__(self) -> None: + # NOTE: On os X systems, using pty.setraw() fails. Therefor we are using this: + try: + newattr = termios.tcgetattr(self.fileno) + except termios.error: + pass + else: + newattr[tty.LFLAG] = self._patch_lflag(newattr[tty.LFLAG]) + newattr[tty.IFLAG] = self._patch_iflag(newattr[tty.IFLAG]) + + # VMIN defines the number of characters read at a time in + # non-canonical mode. It seems to default to 1 on Linux, but on + # Solaris and derived operating systems it defaults to 4. (This is + # because the VMIN slot is the same as the VEOF slot, which + # defaults to ASCII EOT = Ctrl-D = 4.) + newattr[tty.CC][termios.VMIN] = 1 # type: ignore + + termios.tcsetattr(self.fileno, termios.TCSANOW, newattr) + + # Put the terminal in cursor mode. (Instead of application mode.) + os.write(self.fileno, b"\x1b[?1l") + + @classmethod + def _patch_lflag(cls, attrs): + return attrs & ~(termios.ECHO | termios.ICANON | termios.IEXTEN | termios.ISIG) + + @classmethod + def _patch_iflag(cls, attrs): + return attrs & ~( + # Disable XON/XOFF flow control on output and input. + # (Don't capture Ctrl-S and Ctrl-Q.) + # Like executing: "stty -ixon." + termios.IXON + | termios.IXOFF + | + # Don't translate carriage return into newline on input. + termios.ICRNL + | termios.INLCR + | termios.IGNCR + ) + + def __exit__(self, *a: object) -> None: + if self.attrs_before is not None: + try: + termios.tcsetattr(self.fileno, termios.TCSANOW, self.attrs_before) + except termios.error: + pass + + # # Put the terminal in application mode. + # self._stdout.write('\x1b[?1h') + + +class cooked_mode(raw_mode): + """ + The opposite of ``raw_mode``, used when we need cooked mode inside a + `raw_mode` block. Used in `Application.run_in_terminal`.:: + + with cooked_mode(stdin): + ''' the pseudo-terminal stdin is now used in cooked mode. ''' + """ + + @classmethod + def _patch_lflag(cls, attrs): + return attrs | (termios.ECHO | termios.ICANON | termios.IEXTEN | termios.ISIG) + + @classmethod + def _patch_iflag(cls, attrs): + # Turn the ICRNL flag back on. (Without this, calling `input()` in + # run_in_terminal doesn't work and displays ^M instead. Ptpython + # evaluates commands using `run_in_terminal`, so it's important that + # they translate ^M back into ^J.) + return attrs | termios.ICRNL diff --git a/.venv/lib/python3.8/site-packages/prompt_toolkit/input/vt100_parser.py b/.venv/lib/python3.8/site-packages/prompt_toolkit/input/vt100_parser.py new file mode 100644 index 00000000..afca12b2 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/prompt_toolkit/input/vt100_parser.py @@ -0,0 +1,247 @@ +""" +Parser for VT100 input stream. +""" +import re +from typing import Callable, Dict, Generator, Tuple, Union + +from ..key_binding.key_processor import KeyPress +from ..keys import Keys +from .ansi_escape_sequences import ANSI_SEQUENCES + +__all__ = [ + "Vt100Parser", +] + + +# Regex matching any CPR response +# (Note that we use '\Z' instead of '$', because '$' could include a trailing +# newline.) +_cpr_response_re = re.compile("^" + re.escape("\x1b[") + r"\d+;\d+R\Z") + +# Mouse events: +# Typical: "Esc[MaB*" Urxvt: "Esc[96;14;13M" and for Xterm SGR: "Esc[<64;85;12M" +_mouse_event_re = re.compile("^" + re.escape("\x1b[") + r"( bool: + # (hard coded) If this could be a prefix of a CPR response, return + # True. + if _cpr_response_prefix_re.match(prefix) or _mouse_event_prefix_re.match( + prefix + ): + result = True + else: + # If this could be a prefix of anything else, also return True. + result = any( + v + for k, v in ANSI_SEQUENCES.items() + if k.startswith(prefix) and k != prefix + ) + + self[prefix] = result + return result + + +_IS_PREFIX_OF_LONGER_MATCH_CACHE = _IsPrefixOfLongerMatchCache() + + +class Vt100Parser: + """ + Parser for VT100 input stream. + Data can be fed through the `feed` method and the given callback will be + called with KeyPress objects. + + :: + + def callback(key): + pass + i = Vt100Parser(callback) + i.feed('data\x01...') + + :attr feed_key_callback: Function that will be called when a key is parsed. + """ + + # Lookup table of ANSI escape sequences for a VT100 terminal + # Hint: in order to know what sequences your terminal writes to stdin, run + # "od -c" and start typing. + def __init__(self, feed_key_callback: Callable[[KeyPress], None]) -> None: + self.feed_key_callback = feed_key_callback + self.reset() + + def reset(self, request: bool = False) -> None: + self._in_bracketed_paste = False + self._start_parser() + + def _start_parser(self) -> None: + """ + Start the parser coroutine. + """ + self._input_parser = self._input_parser_generator() + self._input_parser.send(None) # type: ignore + + def _get_match(self, prefix: str) -> Union[None, Keys, Tuple[Keys, ...]]: + """ + Return the key (or keys) that maps to this prefix. + """ + # (hard coded) If we match a CPR response, return Keys.CPRResponse. + # (This one doesn't fit in the ANSI_SEQUENCES, because it contains + # integer variables.) + if _cpr_response_re.match(prefix): + return Keys.CPRResponse + + elif _mouse_event_re.match(prefix): + return Keys.Vt100MouseEvent + + # Otherwise, use the mappings. + try: + return ANSI_SEQUENCES[prefix] + except KeyError: + return None + + def _input_parser_generator(self) -> Generator[None, Union[str, _Flush], None]: + """ + Coroutine (state machine) for the input parser. + """ + prefix = "" + retry = False + flush = False + + while True: + flush = False + + if retry: + retry = False + else: + # Get next character. + c = yield + + if isinstance(c, _Flush): + flush = True + else: + prefix += c + + # If we have some data, check for matches. + if prefix: + is_prefix_of_longer_match = _IS_PREFIX_OF_LONGER_MATCH_CACHE[prefix] + match = self._get_match(prefix) + + # Exact matches found, call handlers.. + if (flush or not is_prefix_of_longer_match) and match: + self._call_handler(match, prefix) + prefix = "" + + # No exact match found. + elif (flush or not is_prefix_of_longer_match) and not match: + found = False + retry = True + + # Loop over the input, try the longest match first and + # shift. + for i in range(len(prefix), 0, -1): + match = self._get_match(prefix[:i]) + if match: + self._call_handler(match, prefix[:i]) + prefix = prefix[i:] + found = True + + if not found: + self._call_handler(prefix[0], prefix[0]) + prefix = prefix[1:] + + def _call_handler( + self, key: Union[str, Keys, Tuple[Keys, ...]], insert_text: str + ) -> None: + """ + Callback to handler. + """ + if isinstance(key, tuple): + # Received ANSI sequence that corresponds with multiple keys + # (probably alt+something). Handle keys individually, but only pass + # data payload to first KeyPress (so that we won't insert it + # multiple times). + for i, k in enumerate(key): + self._call_handler(k, insert_text if i == 0 else "") + else: + if key == Keys.BracketedPaste: + self._in_bracketed_paste = True + self._paste_buffer = "" + else: + self.feed_key_callback(KeyPress(key, insert_text)) + + def feed(self, data: str) -> None: + """ + Feed the input stream. + + :param data: Input string (unicode). + """ + # Handle bracketed paste. (We bypass the parser that matches all other + # key presses and keep reading input until we see the end mark.) + # This is much faster then parsing character by character. + if self._in_bracketed_paste: + self._paste_buffer += data + end_mark = "\x1b[201~" + + if end_mark in self._paste_buffer: + end_index = self._paste_buffer.index(end_mark) + + # Feed content to key bindings. + paste_content = self._paste_buffer[:end_index] + self.feed_key_callback(KeyPress(Keys.BracketedPaste, paste_content)) + + # Quit bracketed paste mode and handle remaining input. + self._in_bracketed_paste = False + remaining = self._paste_buffer[end_index + len(end_mark) :] + self._paste_buffer = "" + + self.feed(remaining) + + # Handle normal input character by character. + else: + for i, c in enumerate(data): + if self._in_bracketed_paste: + # Quit loop and process from this position when the parser + # entered bracketed paste. + self.feed(data[i:]) + break + else: + self._input_parser.send(c) + + def flush(self) -> None: + """ + Flush the buffer of the input stream. + + This will allow us to handle the escape key (or maybe meta) sooner. + The input received by the escape key is actually the same as the first + characters of e.g. Arrow-Up, so without knowing what follows the escape + sequence, we don't know whether escape has been pressed, or whether + it's something else. This flush function should be called after a + timeout, and processes everything that's still in the buffer as-is, so + without assuming any characters will follow. + """ + self._input_parser.send(_Flush()) + + def feed_and_flush(self, data: str) -> None: + """ + Wrapper around ``feed`` and ``flush``. + """ + self.feed(data) + self.flush() diff --git a/.venv/lib/python3.8/site-packages/prompt_toolkit/input/win32.py b/.venv/lib/python3.8/site-packages/prompt_toolkit/input/win32.py new file mode 100644 index 00000000..3c557d23 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/prompt_toolkit/input/win32.py @@ -0,0 +1,655 @@ +import msvcrt +import os +import sys +from abc import abstractmethod +from asyncio import get_event_loop +from contextlib import contextmanager +from ctypes import pointer, windll +from ctypes.wintypes import DWORD, HANDLE +from typing import Callable, ContextManager, Dict, Iterable, List, Optional, TextIO + +from prompt_toolkit.eventloop import run_in_executor_with_context +from prompt_toolkit.eventloop.win32 import create_win32_event, wait_for_handles +from prompt_toolkit.key_binding.key_processor import KeyPress +from prompt_toolkit.keys import Keys +from prompt_toolkit.mouse_events import MouseEventType +from prompt_toolkit.win32_types import ( + INPUT_RECORD, + KEY_EVENT_RECORD, + MOUSE_EVENT_RECORD, + STD_INPUT_HANDLE, + EventTypes, +) + +from .ansi_escape_sequences import REVERSE_ANSI_SEQUENCES +from .base import Input + +__all__ = [ + "Win32Input", + "ConsoleInputReader", + "raw_mode", + "cooked_mode", + "attach_win32_input", + "detach_win32_input", +] + + +class _Win32InputBase(Input): + """ + Base class for `Win32Input` and `Win32PipeInput`. + """ + + def __init__(self) -> None: + self.win32_handles = _Win32Handles() + + @property + @abstractmethod + def handle(self) -> HANDLE: + pass + + +class Win32Input(_Win32InputBase): + """ + `Input` class that reads from the Windows console. + """ + + def __init__(self, stdin: Optional[TextIO] = None) -> None: + super().__init__() + self.console_input_reader = ConsoleInputReader() + + def attach(self, input_ready_callback: Callable[[], None]) -> ContextManager[None]: + """ + Return a context manager that makes this input active in the current + event loop. + """ + return attach_win32_input(self, input_ready_callback) + + def detach(self) -> ContextManager[None]: + """ + Return a context manager that makes sure that this input is not active + in the current event loop. + """ + return detach_win32_input(self) + + def read_keys(self) -> List[KeyPress]: + return list(self.console_input_reader.read()) + + def flush(self) -> None: + pass + + @property + def closed(self) -> bool: + return False + + def raw_mode(self) -> ContextManager[None]: + return raw_mode() + + def cooked_mode(self) -> ContextManager[None]: + return cooked_mode() + + def fileno(self) -> int: + # The windows console doesn't depend on the file handle, so + # this is not used for the event loop (which uses the + # handle instead). But it's used in `Application.run_system_command` + # which opens a subprocess with a given stdin/stdout. + return sys.stdin.fileno() + + def typeahead_hash(self) -> str: + return "win32-input" + + def close(self) -> None: + self.console_input_reader.close() + + @property + def handle(self) -> HANDLE: + return self.console_input_reader.handle + + +class ConsoleInputReader: + """ + :param recognize_paste: When True, try to discover paste actions and turn + the event into a BracketedPaste. + """ + + # Keys with character data. + mappings = { + b"\x1b": Keys.Escape, + b"\x00": Keys.ControlSpace, # Control-Space (Also for Ctrl-@) + b"\x01": Keys.ControlA, # Control-A (home) + b"\x02": Keys.ControlB, # Control-B (emacs cursor left) + b"\x03": Keys.ControlC, # Control-C (interrupt) + b"\x04": Keys.ControlD, # Control-D (exit) + b"\x05": Keys.ControlE, # Control-E (end) + b"\x06": Keys.ControlF, # Control-F (cursor forward) + b"\x07": Keys.ControlG, # Control-G + b"\x08": Keys.ControlH, # Control-H (8) (Identical to '\b') + b"\x09": Keys.ControlI, # Control-I (9) (Identical to '\t') + b"\x0a": Keys.ControlJ, # Control-J (10) (Identical to '\n') + b"\x0b": Keys.ControlK, # Control-K (delete until end of line; vertical tab) + b"\x0c": Keys.ControlL, # Control-L (clear; form feed) + b"\x0d": Keys.ControlM, # Control-M (enter) + b"\x0e": Keys.ControlN, # Control-N (14) (history forward) + b"\x0f": Keys.ControlO, # Control-O (15) + b"\x10": Keys.ControlP, # Control-P (16) (history back) + b"\x11": Keys.ControlQ, # Control-Q + b"\x12": Keys.ControlR, # Control-R (18) (reverse search) + b"\x13": Keys.ControlS, # Control-S (19) (forward search) + b"\x14": Keys.ControlT, # Control-T + b"\x15": Keys.ControlU, # Control-U + b"\x16": Keys.ControlV, # Control-V + b"\x17": Keys.ControlW, # Control-W + b"\x18": Keys.ControlX, # Control-X + b"\x19": Keys.ControlY, # Control-Y (25) + b"\x1a": Keys.ControlZ, # Control-Z + b"\x1c": Keys.ControlBackslash, # Both Control-\ and Ctrl-| + b"\x1d": Keys.ControlSquareClose, # Control-] + b"\x1e": Keys.ControlCircumflex, # Control-^ + b"\x1f": Keys.ControlUnderscore, # Control-underscore (Also for Ctrl-hyphen.) + b"\x7f": Keys.Backspace, # (127) Backspace (ASCII Delete.) + } + + # Keys that don't carry character data. + keycodes = { + # Home/End + 33: Keys.PageUp, + 34: Keys.PageDown, + 35: Keys.End, + 36: Keys.Home, + # Arrows + 37: Keys.Left, + 38: Keys.Up, + 39: Keys.Right, + 40: Keys.Down, + 45: Keys.Insert, + 46: Keys.Delete, + # F-keys. + 112: Keys.F1, + 113: Keys.F2, + 114: Keys.F3, + 115: Keys.F4, + 116: Keys.F5, + 117: Keys.F6, + 118: Keys.F7, + 119: Keys.F8, + 120: Keys.F9, + 121: Keys.F10, + 122: Keys.F11, + 123: Keys.F12, + } + + LEFT_ALT_PRESSED = 0x0002 + RIGHT_ALT_PRESSED = 0x0001 + SHIFT_PRESSED = 0x0010 + LEFT_CTRL_PRESSED = 0x0008 + RIGHT_CTRL_PRESSED = 0x0004 + + def __init__(self, recognize_paste: bool = True) -> None: + self._fdcon = None + self.recognize_paste = recognize_paste + + # When stdin is a tty, use that handle, otherwise, create a handle from + # CONIN$. + self.handle: HANDLE + if sys.stdin.isatty(): + self.handle = HANDLE(windll.kernel32.GetStdHandle(STD_INPUT_HANDLE)) + else: + self._fdcon = os.open("CONIN$", os.O_RDWR | os.O_BINARY) + self.handle = HANDLE(msvcrt.get_osfhandle(self._fdcon)) + + def close(self) -> None: + " Close fdcon. " + if self._fdcon is not None: + os.close(self._fdcon) + + def read(self) -> Iterable[KeyPress]: + """ + Return a list of `KeyPress` instances. It won't return anything when + there was nothing to read. (This function doesn't block.) + + http://msdn.microsoft.com/en-us/library/windows/desktop/ms684961(v=vs.85).aspx + """ + max_count = 2048 # Max events to read at the same time. + + read = DWORD(0) + arrtype = INPUT_RECORD * max_count + input_records = arrtype() + + # Check whether there is some input to read. `ReadConsoleInputW` would + # block otherwise. + # (Actually, the event loop is responsible to make sure that this + # function is only called when there is something to read, but for some + # reason this happened in the asyncio_win32 loop, and it's better to be + # safe anyway.) + if not wait_for_handles([self.handle], timeout=0): + return + + # Get next batch of input event. + windll.kernel32.ReadConsoleInputW( + self.handle, pointer(input_records), max_count, pointer(read) + ) + + # First, get all the keys from the input buffer, in order to determine + # whether we should consider this a paste event or not. + all_keys = list(self._get_keys(read, input_records)) + + # Fill in 'data' for key presses. + all_keys = [self._insert_key_data(key) for key in all_keys] + + if self.recognize_paste and self._is_paste(all_keys): + gen = iter(all_keys) + k: Optional[KeyPress] + + for k in gen: + # Pasting: if the current key consists of text or \n, turn it + # into a BracketedPaste. + data = [] + while k and (isinstance(k.key, str) or k.key == Keys.ControlJ): + data.append(k.data) + try: + k = next(gen) + except StopIteration: + k = None + + if data: + yield KeyPress(Keys.BracketedPaste, "".join(data)) + if k is not None: + yield k + else: + for k2 in all_keys: + yield k2 + + def _insert_key_data(self, key_press: KeyPress) -> KeyPress: + """ + Insert KeyPress data, for vt100 compatibility. + """ + if key_press.data: + return key_press + + if isinstance(key_press.key, Keys): + data = REVERSE_ANSI_SEQUENCES.get(key_press.key, "") + else: + data = "" + + return KeyPress(key_press.key, data) + + def _get_keys(self, read, input_records): + """ + Generator that yields `KeyPress` objects from the input records. + """ + for i in range(read.value): + ir = input_records[i] + + # Get the right EventType from the EVENT_RECORD. + # (For some reason the Windows console application 'cmder' + # [http://gooseberrycreative.com/cmder/] can return '0' for + # ir.EventType. -- Just ignore that.) + if ir.EventType in EventTypes: + ev = getattr(ir.Event, EventTypes[ir.EventType]) + + # Process if this is a key event. (We also have mouse, menu and + # focus events.) + if type(ev) == KEY_EVENT_RECORD and ev.KeyDown: + for key_press in self._event_to_key_presses(ev): + yield key_press + + elif type(ev) == MOUSE_EVENT_RECORD: + for key_press in self._handle_mouse(ev): + yield key_press + + @staticmethod + def _is_paste(keys) -> bool: + """ + Return `True` when we should consider this list of keys as a paste + event. Pasted text on windows will be turned into a + `Keys.BracketedPaste` event. (It's not 100% correct, but it is probably + the best possible way to detect pasting of text and handle that + correctly.) + """ + # Consider paste when it contains at least one newline and at least one + # other character. + text_count = 0 + newline_count = 0 + + for k in keys: + if isinstance(k.key, str): + text_count += 1 + if k.key == Keys.ControlM: + newline_count += 1 + + return newline_count >= 1 and text_count > 1 + + def _event_to_key_presses(self, ev): + """ + For this `KEY_EVENT_RECORD`, return a list of `KeyPress` instances. + """ + assert type(ev) == KEY_EVENT_RECORD and ev.KeyDown + + result = None + + u_char = ev.uChar.UnicodeChar + ascii_char = u_char.encode("utf-8") + + # NOTE: We don't use `ev.uChar.AsciiChar`. That appears to be latin-1 + # encoded. See also: + # https://github.com/ipython/ipython/issues/10004 + # https://github.com/jonathanslenders/python-prompt-toolkit/issues/389 + + if u_char == "\x00": + if ev.VirtualKeyCode in self.keycodes: + result = KeyPress(self.keycodes[ev.VirtualKeyCode], "") + else: + if ascii_char in self.mappings: + if self.mappings[ascii_char] == Keys.ControlJ: + u_char = ( + "\n" # Windows sends \n, turn into \r for unix compatibility. + ) + result = KeyPress(self.mappings[ascii_char], u_char) + else: + result = KeyPress(u_char, u_char) + + # First we handle Shift-Control-Arrow/Home/End (need to do this first) + if ( + ( + ev.ControlKeyState & self.LEFT_CTRL_PRESSED + or ev.ControlKeyState & self.RIGHT_CTRL_PRESSED + ) + and ev.ControlKeyState & self.SHIFT_PRESSED + and result + ): + result.key = { + Keys.Left: Keys.ControlShiftLeft, + Keys.Right: Keys.ControlShiftRight, + Keys.Up: Keys.ControlShiftUp, + Keys.Down: Keys.ControlShiftDown, + Keys.Home: Keys.ControlShiftHome, + Keys.End: Keys.ControlShiftEnd, + Keys.Insert: Keys.ControlShiftInsert, + Keys.PageUp: Keys.ControlShiftPageUp, + Keys.PageDown: Keys.ControlShiftPageDown, + }.get(result.key, result.key) + + # Correctly handle Control-Arrow/Home/End and Control-Insert keys. + if ( + ev.ControlKeyState & self.LEFT_CTRL_PRESSED + or ev.ControlKeyState & self.RIGHT_CTRL_PRESSED + ) and result: + result.key = { + Keys.Left: Keys.ControlLeft, + Keys.Right: Keys.ControlRight, + Keys.Up: Keys.ControlUp, + Keys.Down: Keys.ControlDown, + Keys.Home: Keys.ControlHome, + Keys.End: Keys.ControlEnd, + Keys.Insert: Keys.ControlInsert, + Keys.PageUp: Keys.ControlPageUp, + Keys.PageDown: Keys.ControlPageDown, + }.get(result.key, result.key) + + # Turn 'Tab' into 'BackTab' when shift was pressed. + # Also handle other shift-key combination + if ev.ControlKeyState & self.SHIFT_PRESSED and result: + result.key = { + Keys.Tab: Keys.BackTab, + Keys.Left: Keys.ShiftLeft, + Keys.Right: Keys.ShiftRight, + Keys.Up: Keys.ShiftUp, + Keys.Down: Keys.ShiftDown, + Keys.Home: Keys.ShiftHome, + Keys.End: Keys.ShiftEnd, + Keys.Insert: Keys.ShiftInsert, + Keys.PageUp: Keys.ShiftPageUp, + Keys.PageDown: Keys.ShiftPageDown, + }.get(result.key, result.key) + + # Turn 'Space' into 'ControlSpace' when control was pressed. + if ( + ( + ev.ControlKeyState & self.LEFT_CTRL_PRESSED + or ev.ControlKeyState & self.RIGHT_CTRL_PRESSED + ) + and result + and result.data == " " + ): + result = KeyPress(Keys.ControlSpace, " ") + + # Turn Control-Enter into META-Enter. (On a vt100 terminal, we cannot + # detect this combination. But it's really practical on Windows.) + if ( + ( + ev.ControlKeyState & self.LEFT_CTRL_PRESSED + or ev.ControlKeyState & self.RIGHT_CTRL_PRESSED + ) + and result + and result.key == Keys.ControlJ + ): + return [KeyPress(Keys.Escape, ""), result] + + # Return result. If alt was pressed, prefix the result with an + # 'Escape' key, just like unix VT100 terminals do. + + # NOTE: Only replace the left alt with escape. The right alt key often + # acts as altgr and is used in many non US keyboard layouts for + # typing some special characters, like a backslash. We don't want + # all backslashes to be prefixed with escape. (Esc-\ has a + # meaning in E-macs, for instance.) + if result: + meta_pressed = ev.ControlKeyState & self.LEFT_ALT_PRESSED + + if meta_pressed: + return [KeyPress(Keys.Escape, ""), result] + else: + return [result] + + else: + return [] + + def _handle_mouse(self, ev): + """ + Handle mouse events. Return a list of KeyPress instances. + """ + FROM_LEFT_1ST_BUTTON_PRESSED = 0x1 + + result = [] + + # Check event type. + if ev.ButtonState == FROM_LEFT_1ST_BUTTON_PRESSED: + # On a key press, generate both the mouse down and up event. + for event_type in [MouseEventType.MOUSE_DOWN, MouseEventType.MOUSE_UP]: + data = ";".join( + [event_type.value, str(ev.MousePosition.X), str(ev.MousePosition.Y)] + ) + result.append(KeyPress(Keys.WindowsMouseEvent, data)) + + return result + + +class _Win32Handles: + """ + Utility to keep track of which handles are connectod to which callbacks. + + `add_win32_handle` starts a tiny event loop in another thread which waits + for the Win32 handle to become ready. When this happens, the callback will + be called in the current asyncio event loop using `call_soon_threadsafe`. + + `remove_win32_handle` will stop this tiny event loop. + + NOTE: We use this technique, so that we don't have to use the + `ProactorEventLoop` on Windows and we can wait for things like stdin + in a `SelectorEventLoop`. This is important, because our inputhook + mechanism (used by IPython), only works with the `SelectorEventLoop`. + """ + + def __init__(self) -> None: + self._handle_callbacks: Dict[int, Callable[[], None]] = {} + + # Windows Events that are triggered when we have to stop watching this + # handle. + self._remove_events: Dict[int, HANDLE] = {} + + def add_win32_handle(self, handle: HANDLE, callback: Callable[[], None]) -> None: + """ + Add a Win32 handle to the event loop. + """ + handle_value = handle.value + + if handle_value is None: + raise ValueError("Invalid handle.") + + # Make sure to remove a previous registered handler first. + self.remove_win32_handle(handle) + + loop = get_event_loop() + self._handle_callbacks[handle_value] = callback + + # Create remove event. + remove_event = create_win32_event() + self._remove_events[handle_value] = remove_event + + # Add reader. + def ready() -> None: + # Tell the callback that input's ready. + try: + callback() + finally: + run_in_executor_with_context(wait, loop=loop) + + # Wait for the input to become ready. + # (Use an executor for this, the Windows asyncio event loop doesn't + # allow us to wait for handles like stdin.) + def wait() -> None: + # Wait until either the handle becomes ready, or the remove event + # has been set. + result = wait_for_handles([remove_event, handle]) + + if result is remove_event: + windll.kernel32.CloseHandle(remove_event) + return + else: + loop.call_soon_threadsafe(ready) + + run_in_executor_with_context(wait, loop=loop) + + def remove_win32_handle(self, handle: HANDLE) -> Optional[Callable[[], None]]: + """ + Remove a Win32 handle from the event loop. + Return either the registered handler or `None`. + """ + if handle.value is None: + return None # Ignore. + + # Trigger remove events, so that the reader knows to stop. + try: + event = self._remove_events.pop(handle.value) + except KeyError: + pass + else: + windll.kernel32.SetEvent(event) + + try: + return self._handle_callbacks.pop(handle.value) + except KeyError: + return None + + +@contextmanager +def attach_win32_input(input: _Win32InputBase, callback: Callable[[], None]): + """ + Context manager that makes this input active in the current event loop. + + :param input: :class:`~prompt_toolkit.input.Input` object. + :param input_ready_callback: Called when the input is ready to read. + """ + win32_handles = input.win32_handles + handle = input.handle + + if handle.value is None: + raise ValueError("Invalid handle.") + + # Add reader. + previous_callback = win32_handles.remove_win32_handle(handle) + win32_handles.add_win32_handle(handle, callback) + + try: + yield + finally: + win32_handles.remove_win32_handle(handle) + + if previous_callback: + win32_handles.add_win32_handle(handle, previous_callback) + + +@contextmanager +def detach_win32_input(input: _Win32InputBase): + win32_handles = input.win32_handles + handle = input.handle + + if handle.value is None: + raise ValueError("Invalid handle.") + + previous_callback = win32_handles.remove_win32_handle(handle) + + try: + yield + finally: + if previous_callback: + win32_handles.add_win32_handle(handle, previous_callback) + + +class raw_mode: + """ + :: + + with raw_mode(stdin): + ''' the windows terminal is now in 'raw' mode. ''' + + The ``fileno`` attribute is ignored. This is to be compatible with the + `raw_input` method of `.vt100_input`. + """ + + def __init__(self, fileno=None): + self.handle = HANDLE(windll.kernel32.GetStdHandle(STD_INPUT_HANDLE)) + + def __enter__(self): + # Remember original mode. + original_mode = DWORD() + windll.kernel32.GetConsoleMode(self.handle, pointer(original_mode)) + self.original_mode = original_mode + + self._patch() + + def _patch(self) -> None: + # Set raw + ENABLE_ECHO_INPUT = 0x0004 + ENABLE_LINE_INPUT = 0x0002 + ENABLE_PROCESSED_INPUT = 0x0001 + + windll.kernel32.SetConsoleMode( + self.handle, + self.original_mode.value + & ~(ENABLE_ECHO_INPUT | ENABLE_LINE_INPUT | ENABLE_PROCESSED_INPUT), + ) + + def __exit__(self, *a: object) -> None: + # Restore original mode + windll.kernel32.SetConsoleMode(self.handle, self.original_mode) + + +class cooked_mode(raw_mode): + """ + :: + + with cooked_mode(stdin): + ''' The pseudo-terminal stdin is now used in cooked mode. ''' + """ + + def _patch(self) -> None: + # Set cooked. + ENABLE_ECHO_INPUT = 0x0004 + ENABLE_LINE_INPUT = 0x0002 + ENABLE_PROCESSED_INPUT = 0x0001 + + windll.kernel32.SetConsoleMode( + self.handle, + self.original_mode.value + | (ENABLE_ECHO_INPUT | ENABLE_LINE_INPUT | ENABLE_PROCESSED_INPUT), + ) diff --git a/.venv/lib/python3.8/site-packages/prompt_toolkit/input/win32_pipe.py b/.venv/lib/python3.8/site-packages/prompt_toolkit/input/win32_pipe.py new file mode 100644 index 00000000..892af2d1 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/prompt_toolkit/input/win32_pipe.py @@ -0,0 +1,134 @@ +from ctypes import windll +from typing import Callable, ContextManager, List + +from prompt_toolkit.eventloop.win32 import create_win32_event + +from ..key_binding import KeyPress +from ..utils import DummyContext +from .base import PipeInput +from .vt100_parser import Vt100Parser +from .win32 import _Win32InputBase, attach_win32_input, detach_win32_input + +__all__ = ["Win32PipeInput"] + + +class Win32PipeInput(_Win32InputBase, PipeInput): + """ + This is an input pipe that works on Windows. + Text or bytes can be feed into the pipe, and key strokes can be read from + the pipe. This is useful if we want to send the input programmatically into + the application. Mostly useful for unit testing. + + Notice that even though it's Windows, we use vt100 escape sequences over + the pipe. + + Usage:: + + input = Win32PipeInput() + input.send_text('inputdata') + """ + + _id = 0 + + def __init__(self) -> None: + super().__init__() + # Event (handle) for registering this input in the event loop. + # This event is set when there is data available to read from the pipe. + # Note: We use this approach instead of using a regular pipe, like + # returned from `os.pipe()`, because making such a regular pipe + # non-blocking is tricky and this works really well. + self._event = create_win32_event() + + self._closed = False + + # Parser for incoming keys. + self._buffer: List[KeyPress] = [] # Buffer to collect the Key objects. + self.vt100_parser = Vt100Parser(lambda key: self._buffer.append(key)) + + # Identifier for every PipeInput for the hash. + self.__class__._id += 1 + self._id = self.__class__._id + + @property + def closed(self) -> bool: + return self._closed + + def fileno(self): + """ + The windows pipe doesn't depend on the file handle. + """ + raise NotImplementedError + + @property + def handle(self): + " The handle used for registering this pipe in the event loop. " + return self._event + + def attach(self, input_ready_callback: Callable) -> ContextManager[None]: + """ + Return a context manager that makes this input active in the current + event loop. + """ + return attach_win32_input(self, input_ready_callback) + + def detach(self) -> ContextManager[None]: + """ + Return a context manager that makes sure that this input is not active + in the current event loop. + """ + return detach_win32_input(self) + + def read_keys(self) -> List[KeyPress]: + " Read list of KeyPress. " + + # Return result. + result = self._buffer + self._buffer = [] + + # Reset event. + windll.kernel32.ResetEvent(self._event) + + return result + + def flush_keys(self) -> List[KeyPress]: + """ + Flush pending keys and return them. + (Used for flushing the 'escape' key.) + """ + # Flush all pending keys. (This is most important to flush the vt100 + # 'Escape' key early when nothing else follows.) + self.vt100_parser.flush() + + # Return result. + result = self._buffer + self._buffer = [] + return result + + def send_bytes(self, data: bytes) -> None: + " Send bytes to the input. " + self.send_text(data.decode("utf-8", "ignore")) + + def send_text(self, text: str) -> None: + " Send text to the input. " + # Pass it through our vt100 parser. + self.vt100_parser.feed(text) + + # Set event. + windll.kernel32.SetEvent(self._event) + + def raw_mode(self) -> ContextManager[None]: + return DummyContext() + + def cooked_mode(self) -> ContextManager[None]: + return DummyContext() + + def close(self) -> None: + " Close pipe handles. " + windll.kernel32.CloseHandle(self._event) + self._closed = True + + def typeahead_hash(self) -> str: + """ + This needs to be unique for every `PipeInput`. + """ + return "pipe-input-%s" % (self._id,) diff --git a/.venv/lib/python3.8/site-packages/prompt_toolkit/key_binding/__init__.py b/.venv/lib/python3.8/site-packages/prompt_toolkit/key_binding/__init__.py new file mode 100644 index 00000000..be105369 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/prompt_toolkit/key_binding/__init__.py @@ -0,0 +1,20 @@ +from .key_bindings import ( + ConditionalKeyBindings, + DynamicKeyBindings, + KeyBindings, + KeyBindingsBase, + merge_key_bindings, +) +from .key_processor import KeyPress, KeyPressEvent + +__all__ = [ + # key_bindings. + "ConditionalKeyBindings", + "DynamicKeyBindings", + "KeyBindings", + "KeyBindingsBase", + "merge_key_bindings", + # key_processor + "KeyPress", + "KeyPressEvent", +] diff --git a/.venv/lib/python3.8/site-packages/prompt_toolkit/key_binding/__pycache__/__init__.cpython-38.pyc b/.venv/lib/python3.8/site-packages/prompt_toolkit/key_binding/__pycache__/__init__.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0a052c1a617bc2b66c76f2aca65a3040a7d46e4d GIT binary patch literal 475 zcmZ{gKS~5K6vi`|na%93gR+H{7noul5G(`{SrrRG1hGjI#!c7_n}24aGL;AM1YXD@ zt(7MbY&4M-r}2gSk}rArUXq)#9DxvDPp{-T0pKl)exM+ZLvLpR6wpKfnczf13}uQ_ znc+<4I8Wjp6a$Gck_9e;PH9GSI-rOabhtoxNJrP88o!4spvwLBiB^<5u2my0SU2NA zsYUB2r=4mfpZC|seX-dSv!-Q!BAHzDQ97*Z_|h@ zB99nE#HZRK;IbOwjlSK#XK)$QjMei{NZUUPj|gdmAmjzu_`yH;Jg=QJwc%!ZuS_#v zF*pf!H(i*wv&Jzw3WeR J-C!6$z5xA;o1#`A z4(Stc<^^~m4!&~Y2|!%R?2;e1LMUs^rJU~TqOve zfXQ=!*uqwfVw)juV;gC|#7f-3j`1B<<}P-PUuG3v#Z_LzHSS^0a4xI!25uO?!kWB= zTYL*|nYhZ@yn{Qui@SUqZv$5wBiy6i*!zOwdR#kq@U^({+6tOy!h1$XWX6<#Oi%q` zGL4hzSoZh#J)WVj^#1D~ZN4vXAwVA4pI!S2&6V@X6*l1_JvNe9Is@P5G8TLH@3 z!`Wy=MK~cc9Hr4r0=I2$7!sL8t9ya&7&^+tnk+4HDJPL!(fJLN`InTGh-k9jyItIy zBqJ3{%4nqPT_vq*;OR`#HEri@^Y%%y;_~ZD=E_AuDc?CtK}mfwVK3DZs}LL# zN%JnJVoWb-y7<~lqM_UsRL#UR(&8-_0tW`oIs%gq0F!>1lR+j@o~cl!DLYQopdjC1QK#%@r=kU?-2#(00W8NZIktn~ z(fHH8a9Xxo)&4L0;#IJdSHdt(qcFrfm(TBy5~iq-rhFV+*(_Y%U;aLQGu1{Be0P(4 z7%4JVC%WWY2^vVs?c6t@)R{0Ou@127H literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/prompt_toolkit/key_binding/__pycache__/digraphs.cpython-38.pyc b/.venv/lib/python3.8/site-packages/prompt_toolkit/key_binding/__pycache__/digraphs.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b38b2d9e758515b0ca1eff70d5eddd004785fcac GIT binary patch literal 30754 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 literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/prompt_toolkit/key_binding/__pycache__/emacs_state.cpython-38.pyc b/.venv/lib/python3.8/site-packages/prompt_toolkit/key_binding/__pycache__/emacs_state.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..6b783b54ffa658829c539f11464e5cc417722876 GIT binary patch literal 1358 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 literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/prompt_toolkit/key_binding/__pycache__/key_processor.cpython-38.pyc b/.venv/lib/python3.8/site-packages/prompt_toolkit/key_binding/__pycache__/key_processor.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ddcc8f5f99506263ed7e0946eb126adae58e53fb GIT binary patch literal 14947 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 XMbBYg*7~hen0csT&%ABCZ3O=Zj$4dh literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/prompt_toolkit/key_binding/__pycache__/vi_state.cpython-38.pyc b/.venv/lib/python3.8/site-packages/prompt_toolkit/key_binding/__pycache__/vi_state.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..619f36cca0f3789c26066fad9bf2f75b4af03a97 GIT binary patch literal 2540 zcmZuzOK;mo5ayB;NzsyJD`}dvLCdyj3l+7D7U-cs&?azX$A}{vu@j(s=!W91W!ijY zxpHd3Ko7~GKO%o1f2apud&*xZ(8tW`<-}QmqnX|1?#z7i;Nxb~H(>nt`=9Jq(=h%* z;o_))a0j094q+kjn05qqJjJ&4XX|dTir1hP>Bfjxi~Bk?!Z%i14I~J@midfLaK3l&aS1SM8!oS#!Z;Z!qa#dqIF{*L@A0SjKp|#!LOBZHcUjn z<5wPIS(pmODxa}5=c5Gq24l}gVKQB@N+qinV_}x%U>Y1;!X9V4zu$XwKwFc4_VDq} z!S>!xuk!nMpKNd4J=osuQ}?TO14a6W08DD!V0K2nI9kSVRWD7P)yj`MWWE)6j55SKS54muIh6AtBwtfsu ziQ0SQlJD^1JGg!TWbQjcEsmZe+H+67@-JkN$2*C_KjaXFq`PaHKGAgD45hGEjMNlqWn;Mkkx~b;yb8)ySJ||lAgoYw zFh@mo<#`w@h<PDuc}s~k(5x; zU}m~TZzz!#xeVnQl!jR;(f7V45(DEx)aZc0Ncsw%5@Xr09M}BUwjA5BJj)>t$UvR( z%G8i~fL?+Hq0!mm0CR2}>l_)kgDs(gr}KjQv>O1fpTQRSC6aj^nIwt7aMLa<>mW9) zaeH?AVi}Te84u7Qf*~;*$j?Ir4Lc{wI3_2iys6PeY^TY~*}b%mU~m?2aTr49 znPeLtvDufOphc6Or6X9I@UGckz$SSM$@?IzL7x@sS6J4C+^Bh`HXEX8+??U4_jLSs z3S8wf#`B0VUEV4W8VBT^nzRP3O69=WkYw^}ynf;CMg7CtgSeCkh(~ODxnq(Q+a~RL zztgU40UsC=9bP%=tblBi76=l{qQt%;F?{Luw|iDMntfwP7nfTXdRW;#jb$BYn>Y(E zM)0ALONpSPMeykY7Gdq4L=tu*T_WG7f92ht^zolCpL9+($aS*;&9FflmPz3EkL|Yo GW#@myCr42L literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/prompt_toolkit/key_binding/bindings/__init__.py b/.venv/lib/python3.8/site-packages/prompt_toolkit/key_binding/bindings/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/.venv/lib/python3.8/site-packages/prompt_toolkit/key_binding/bindings/__pycache__/__init__.cpython-38.pyc b/.venv/lib/python3.8/site-packages/prompt_toolkit/key_binding/bindings/__pycache__/__init__.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..87e290defe5b6efe8522ce7ee16ceeb180c0ec38 GIT binary patch literal 171 zcmWIL<>g`kg8%i`;z9Id5P=LBfgA@QE@lA|DGb33nv8xc8Hzx{2;x_Oeo1bDenDn| zZfRaYVsdtBif(yEYHE(IrD=RgMxjxLenC-wZb38qN4nl3 zi2~0S#!zp;pxbxI~LQmKPaGNmh{f;w#Hfv31#^nKTKVv-PD=3e@69*(ae09Q%cbmXX zXC}4AFIlbbgaDfBWx$fP`u4zto&sX6Ob*BSEB;Xss8wipv&Y4$iPWVR!RKom35XM z2)+g03c2;omvH0J=Y#E9Rl^#tSCu>{%=UpeK99)l^T^y@jMr{`+-%HEOJ_KJ2=D0* z421ctL)T9k3;rE{{rZ6K-jr1i1mEhuO5NDWw|bC3ey@-aC%6=iXKCJn{PP6nlWN0r zIih&p9GGCYq(m?Qz{v@nP)HXxVd{ekeGdQo&I^i#1Zfywvjk&ke{UmsAriW?qn+4Q zSl84F49!YWYM}r&phT_0PVA@+JfM44z@k4L)^WR)W>)pbu+SJuq~%kexpaK}Z2&sE z-S|T1SuGmcyWq47`mjz|r@w{ClG9%q_8jU2xb41RnD5U$ z)0xjd7E(rarc9B^SAsGQHh1q|-__US3-(|ehFt3Co}hid`~>(0N@QorhHlp(E$ZnX(;7xjB_gL0sut z7E>bCyYNcm!m|b#M@|)bFr}TEWfML7$QK}??N`s6(z-^+@mrf1`wH1>oQ!jY!P~fd zkd6(#r;yp$OF9c_sT+Tgm0Sw-4jiiYaQFxZO!(=5A*bNeOD;pV1dssjVst$SDgLg6 z>-6$Uyas`pLP1GWh3T7Iy;u#pP)THw+fv&-D^IpqC0CXNr%9@<_15U*lO>4-54sC; zZCy_`-yjXgIebJbr7#H4YN+gB^)*;oPZzwmIM}QUZo)@-B*iVP5E{X7od9bS?a+?H JPF>e^{sZW6QV#$C literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/prompt_toolkit/key_binding/bindings/__pycache__/basic.cpython-38.pyc b/.venv/lib/python3.8/site-packages/prompt_toolkit/key_binding/bindings/__pycache__/basic.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..33c8dbb495b648c349c2be56e4e064ab3504eb47 GIT binary patch literal 6714 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 EAH3IZ{{R30 literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/prompt_toolkit/key_binding/bindings/__pycache__/cpr.cpython-38.pyc b/.venv/lib/python3.8/site-packages/prompt_toolkit/key_binding/bindings/__pycache__/cpr.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f5fe71ed1a3e969dde7f63bc12d4d70bcb04ed16 GIT binary patch literal 1043 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 bDnHm=D%mw~JNyZ|g|NjLW#5uC;oE~B;ZL;B literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/prompt_toolkit/key_binding/bindings/__pycache__/mouse.cpython-38.pyc b/.venv/lib/python3.8/site-packages/prompt_toolkit/key_binding/bindings/__pycache__/mouse.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8fcd5e996fca74271cc5759f402939d703312052 GIT binary patch literal 3356 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 X{C#EBEOYht>Km;J{#IJITg(3gQKpmt literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/prompt_toolkit/key_binding/bindings/__pycache__/search.cpython-38.pyc b/.venv/lib/python3.8/site-packages/prompt_toolkit/key_binding/bindings/__pycache__/search.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..73f7ecfb859493774e9437a18971e3a882a3f098 GIT binary patch literal 2903 zcmbVOOK%%D5MHj{@=A96O5&s`n_MEmmVg2|6bOR2j?+U>w}=}A*vn$Iq^z}9%MF+7 zz($H5(p!;#kVAURAL?PRJ>@5~mv)9+sgflJN!J*P9)DU>umWA;cd3UuDrF`Dy#omeofrvInEku zXwC|7YBOinSyOYa%yBl@lIE<=-L}ab%~_k{TxBiIS?5*0!LGd}>^j@hJDVuWHy>Iv zuis#8&ArN24z143^IOeB?#p0EC69c?89m`=v>(PSjE~Z8^8rC?S&;>z=r zq*KZpdjjNCDB^r05V4XX^1{?JqJBT(xieY9b#S=#grEH=d7AE@@>qSa&E-q*rdPa~ zJAPkCRa}y{{2<`TWJy!y15@%-E>rG>aUl5!Zt|n?fkI*+(6RFhXc()!D!IyJ96)4FKAfZBdqAlJgRr1O>bh zr0;sgWUt%NlAy6fmE0w`G$~y9p2$_$dvD1N`1$*wr$$LH36q^HPW<46vz?bi&ZC`g z?s;nX;_G2Akzxc;DIubhQ1zxj?TrJfXDsL@XA+b88c>Q4TeZ(}(QjJo=R+P-@G_S) z!I*;J4Z&aLiEa8K3)Ofvnk4d|M`4pR z=e?pc=H)&V#=L5F-4=94b0;>+4sjjSU@Uy0gygrpv3}!QXO16$7AeAMRhmTJf!{f> zCmjb%(zxS*PwaQ4sorDC%&zXa+AYQ+DiSVzEE{wX%2aJ5FQ%sbX*t~jjaMdVh;`3x z2bq*mqzk>>wNpO|8B|x@Knr&+!h8izKL;x8s*}#OyykgK1fJ)%XM2rlUbkmAyYNqn zF65wgx6s1iwRu6%wCz-)2W16^Dh%%33u03Zt&4MD2hetel=v^G>rC-e*?=w77aFkV zMXDj$WTozqe*s%f;Ftga literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/prompt_toolkit/key_binding/bindings/__pycache__/vi.cpython-38.pyc b/.venv/lib/python3.8/site-packages/prompt_toolkit/key_binding/bindings/__pycache__/vi.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..57b71bf59f6ffc16364f101caccac4096b46baaf GIT binary patch literal 62708 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 KeyBindings: + """ + Key bindings for accepting auto suggestion text. + + (This has to come after the Vi bindings, because they also have an + implementation for the "right arrow", but we really want the suggestion + binding when a suggestion is available.) + """ + key_bindings = KeyBindings() + handle = key_bindings.add + + @Condition + def suggestion_available() -> bool: + app = get_app() + return ( + app.current_buffer.suggestion is not None + and len(app.current_buffer.suggestion.text) > 0 + and app.current_buffer.document.is_cursor_at_the_end + ) + + @handle("c-f", filter=suggestion_available) + @handle("c-e", filter=suggestion_available) + @handle("right", filter=suggestion_available) + def _accept(event: E) -> None: + """ + Accept suggestion. + """ + b = event.current_buffer + suggestion = b.suggestion + + if suggestion: + b.insert_text(suggestion.text) + + @handle("escape", "f", filter=suggestion_available & emacs_mode) + def _fill(event: E) -> None: + """ + Fill partial suggestion. + """ + b = event.current_buffer + suggestion = b.suggestion + + if suggestion: + t = re.split(r"(\S+\s+)", suggestion.text) + b.insert_text(next(x for x in t if x)) + + return key_bindings diff --git a/.venv/lib/python3.8/site-packages/prompt_toolkit/key_binding/bindings/basic.py b/.venv/lib/python3.8/site-packages/prompt_toolkit/key_binding/bindings/basic.py new file mode 100644 index 00000000..56efe5d6 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/prompt_toolkit/key_binding/bindings/basic.py @@ -0,0 +1,252 @@ +# pylint: disable=function-redefined +from prompt_toolkit.application.current import get_app +from prompt_toolkit.filters import ( + Condition, + emacs_insert_mode, + has_selection, + in_paste_mode, + is_multiline, + vi_insert_mode, +) +from prompt_toolkit.key_binding.key_processor import KeyPress, KeyPressEvent +from prompt_toolkit.keys import Keys + +from ..key_bindings import KeyBindings +from .named_commands import get_by_name + +__all__ = [ + "load_basic_bindings", +] + +E = KeyPressEvent + + +def if_no_repeat(event: E) -> bool: + """Callable that returns True when the previous event was delivered to + another handler.""" + return not event.is_repeat + + +def load_basic_bindings() -> KeyBindings: + key_bindings = KeyBindings() + insert_mode = vi_insert_mode | emacs_insert_mode + handle = key_bindings.add + + @handle("c-a") + @handle("c-b") + @handle("c-c") + @handle("c-d") + @handle("c-e") + @handle("c-f") + @handle("c-g") + @handle("c-h") + @handle("c-i") + @handle("c-j") + @handle("c-k") + @handle("c-l") + @handle("c-m") + @handle("c-n") + @handle("c-o") + @handle("c-p") + @handle("c-q") + @handle("c-r") + @handle("c-s") + @handle("c-t") + @handle("c-u") + @handle("c-v") + @handle("c-w") + @handle("c-x") + @handle("c-y") + @handle("c-z") + @handle("f1") + @handle("f2") + @handle("f3") + @handle("f4") + @handle("f5") + @handle("f6") + @handle("f7") + @handle("f8") + @handle("f9") + @handle("f10") + @handle("f11") + @handle("f12") + @handle("f13") + @handle("f14") + @handle("f15") + @handle("f16") + @handle("f17") + @handle("f18") + @handle("f19") + @handle("f20") + @handle("f21") + @handle("f22") + @handle("f23") + @handle("f24") + @handle("c-@") # Also c-space. + @handle("c-\\") + @handle("c-]") + @handle("c-^") + @handle("c-_") + @handle("backspace") + @handle("up") + @handle("down") + @handle("right") + @handle("left") + @handle("s-up") + @handle("s-down") + @handle("s-right") + @handle("s-left") + @handle("home") + @handle("end") + @handle("s-home") + @handle("s-end") + @handle("delete") + @handle("s-delete") + @handle("c-delete") + @handle("pageup") + @handle("pagedown") + @handle("s-tab") + @handle("tab") + @handle("c-s-left") + @handle("c-s-right") + @handle("c-s-home") + @handle("c-s-end") + @handle("c-left") + @handle("c-right") + @handle("c-up") + @handle("c-down") + @handle("c-home") + @handle("c-end") + @handle("insert") + @handle("s-insert") + @handle("c-insert") + @handle(Keys.Ignore) + def _ignore(event: E) -> None: + """ + First, for any of these keys, Don't do anything by default. Also don't + catch them in the 'Any' handler which will insert them as data. + + If people want to insert these characters as a literal, they can always + do by doing a quoted insert. (ControlQ in emacs mode, ControlV in Vi + mode.) + """ + pass + + # Readline-style bindings. + handle("home")(get_by_name("beginning-of-line")) + handle("end")(get_by_name("end-of-line")) + handle("left")(get_by_name("backward-char")) + handle("right")(get_by_name("forward-char")) + handle("c-up")(get_by_name("previous-history")) + handle("c-down")(get_by_name("next-history")) + handle("c-l")(get_by_name("clear-screen")) + + handle("c-k", filter=insert_mode)(get_by_name("kill-line")) + handle("c-u", filter=insert_mode)(get_by_name("unix-line-discard")) + handle("backspace", filter=insert_mode, save_before=if_no_repeat)( + get_by_name("backward-delete-char") + ) + handle("delete", filter=insert_mode, save_before=if_no_repeat)( + get_by_name("delete-char") + ) + handle("c-delete", filter=insert_mode, save_before=if_no_repeat)( + get_by_name("delete-char") + ) + handle(Keys.Any, filter=insert_mode, save_before=if_no_repeat)( + get_by_name("self-insert") + ) + handle("c-t", filter=insert_mode)(get_by_name("transpose-chars")) + handle("c-i", filter=insert_mode)(get_by_name("menu-complete")) + handle("s-tab", filter=insert_mode)(get_by_name("menu-complete-backward")) + + # Control-W should delete, using whitespace as separator, while M-Del + # should delete using [^a-zA-Z0-9] as a boundary. + handle("c-w", filter=insert_mode)(get_by_name("unix-word-rubout")) + + handle("pageup", filter=~has_selection)(get_by_name("previous-history")) + handle("pagedown", filter=~has_selection)(get_by_name("next-history")) + + # CTRL keys. + + @Condition + def has_text_before_cursor() -> bool: + return bool(get_app().current_buffer.text) + + handle("c-d", filter=has_text_before_cursor & insert_mode)( + get_by_name("delete-char") + ) + + @handle("enter", filter=insert_mode & is_multiline) + def _newline(event: E) -> None: + """ + Newline (in case of multiline input. + """ + event.current_buffer.newline(copy_margin=not in_paste_mode()) + + @handle("c-j") + def _newline2(event: E) -> None: + r""" + By default, handle \n as if it were a \r (enter). + (It appears that some terminals send \n instead of \r when pressing + enter. - at least the Linux subsystem for Windows.) + """ + event.key_processor.feed(KeyPress(Keys.ControlM, "\r"), first=True) + + # Delete the word before the cursor. + + @handle("up") + def _go_up(event: E) -> None: + event.current_buffer.auto_up(count=event.arg) + + @handle("down") + def _go_down(event: E) -> None: + event.current_buffer.auto_down(count=event.arg) + + @handle("delete", filter=has_selection) + def _cut(event: E) -> None: + data = event.current_buffer.cut_selection() + event.app.clipboard.set_data(data) + + # Global bindings. + + @handle("c-z") + def _insert_ctrl_z(event: E) -> None: + """ + By default, control-Z should literally insert Ctrl-Z. + (Ansi Ctrl-Z, code 26 in MSDOS means End-Of-File. + In a Python REPL for instance, it's possible to type + Control-Z followed by enter to quit.) + + When the system bindings are loaded and suspend-to-background is + supported, that will override this binding. + """ + event.current_buffer.insert_text(event.data) + + @handle(Keys.BracketedPaste) + def _paste(event: E) -> None: + """ + Pasting from clipboard. + """ + data = event.data + + # Be sure to use \n as line ending. + # Some terminals (Like iTerm2) seem to paste \r\n line endings in a + # bracketed paste. See: https://github.com/ipython/ipython/issues/9737 + data = data.replace("\r\n", "\n") + data = data.replace("\r", "\n") + + event.current_buffer.insert_text(data) + + @Condition + def in_quoted_insert() -> bool: + return get_app().quoted_insert + + @handle(Keys.Any, filter=in_quoted_insert, eager=True) + def _insert_text(event: E) -> None: + """ + Handle quoted insert. + """ + event.current_buffer.insert_text(event.data, overwrite=False) + event.app.quoted_insert = False + + return key_bindings diff --git a/.venv/lib/python3.8/site-packages/prompt_toolkit/key_binding/bindings/completion.py b/.venv/lib/python3.8/site-packages/prompt_toolkit/key_binding/bindings/completion.py new file mode 100644 index 00000000..a9196240 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/prompt_toolkit/key_binding/bindings/completion.py @@ -0,0 +1,203 @@ +""" +Key binding handlers for displaying completions. +""" +import asyncio +import math +from typing import TYPE_CHECKING, List + +from prompt_toolkit.application.run_in_terminal import in_terminal +from prompt_toolkit.completion import ( + CompleteEvent, + Completion, + get_common_complete_suffix, +) +from prompt_toolkit.formatted_text import StyleAndTextTuples +from prompt_toolkit.key_binding.key_bindings import KeyBindings +from prompt_toolkit.key_binding.key_processor import KeyPressEvent +from prompt_toolkit.keys import Keys +from prompt_toolkit.utils import get_cwidth + +if TYPE_CHECKING: + from prompt_toolkit.application import Application + from prompt_toolkit.shortcuts import PromptSession + +__all__ = [ + "generate_completions", + "display_completions_like_readline", +] + +E = KeyPressEvent + + +def generate_completions(event: E) -> None: + r""" + Tab-completion: where the first tab completes the common suffix and the + second tab lists all the completions. + """ + b = event.current_buffer + + # When already navigating through completions, select the next one. + if b.complete_state: + b.complete_next() + else: + b.start_completion(insert_common_part=True) + + +def display_completions_like_readline(event: E) -> None: + """ + Key binding handler for readline-style tab completion. + This is meant to be as similar as possible to the way how readline displays + completions. + + Generate the completions immediately (blocking) and display them above the + prompt in columns. + + Usage:: + + # Call this handler when 'Tab' has been pressed. + key_bindings.add(Keys.ControlI)(display_completions_like_readline) + """ + # Request completions. + b = event.current_buffer + if b.completer is None: + return + complete_event = CompleteEvent(completion_requested=True) + completions = list(b.completer.get_completions(b.document, complete_event)) + + # Calculate the common suffix. + common_suffix = get_common_complete_suffix(b.document, completions) + + # One completion: insert it. + if len(completions) == 1: + b.delete_before_cursor(-completions[0].start_position) + b.insert_text(completions[0].text) + # Multiple completions with common part. + elif common_suffix: + b.insert_text(common_suffix) + # Otherwise: display all completions. + elif completions: + _display_completions_like_readline(event.app, completions) + + +def _display_completions_like_readline( + app: "Application", completions: List[Completion] +) -> "asyncio.Task[None]": + """ + Display the list of completions in columns above the prompt. + This will ask for a confirmation if there are too many completions to fit + on a single page and provide a paginator to walk through them. + """ + from prompt_toolkit.formatted_text import to_formatted_text + from prompt_toolkit.shortcuts.prompt import create_confirm_session + + # Get terminal dimensions. + term_size = app.output.get_size() + term_width = term_size.columns + term_height = term_size.rows + + # Calculate amount of required columns/rows for displaying the + # completions. (Keep in mind that completions are displayed + # alphabetically column-wise.) + max_compl_width = min( + term_width, max(get_cwidth(c.display_text) for c in completions) + 1 + ) + column_count = max(1, term_width // max_compl_width) + completions_per_page = column_count * (term_height - 1) + page_count = int(math.ceil(len(completions) / float(completions_per_page))) + # Note: math.ceil can return float on Python2. + + def display(page: int) -> None: + # Display completions. + page_completions = completions[ + page * completions_per_page : (page + 1) * completions_per_page + ] + + page_row_count = int(math.ceil(len(page_completions) / float(column_count))) + page_columns = [ + page_completions[i * page_row_count : (i + 1) * page_row_count] + for i in range(column_count) + ] + + result: StyleAndTextTuples = [] + + for r in range(page_row_count): + for c in range(column_count): + try: + completion = page_columns[c][r] + style = "class:readline-like-completions.completion " + ( + completion.style or "" + ) + + result.extend(to_formatted_text(completion.display, style=style)) + + # Add padding. + padding = max_compl_width - get_cwidth(completion.display_text) + result.append((completion.style, " " * padding)) + except IndexError: + pass + result.append(("", "\n")) + + app.print_text(to_formatted_text(result, "class:readline-like-completions")) + + # User interaction through an application generator function. + async def run_compl() -> None: + " Coroutine. " + async with in_terminal(render_cli_done=True): + if len(completions) > completions_per_page: + # Ask confirmation if it doesn't fit on the screen. + confirm = await create_confirm_session( + "Display all {} possibilities?".format(len(completions)), + ).prompt_async() + + if confirm: + # Display pages. + for page in range(page_count): + display(page) + + if page != page_count - 1: + # Display --MORE-- and go to the next page. + show_more = await _create_more_session( + "--MORE--" + ).prompt_async() + + if not show_more: + return + else: + app.output.flush() + else: + # Display all completions. + display(0) + + return app.create_background_task(run_compl()) + + +def _create_more_session(message: str = "--MORE--") -> "PromptSession": + """ + Create a `PromptSession` object for displaying the "--MORE--". + """ + from prompt_toolkit.shortcuts import PromptSession + + bindings = KeyBindings() + + @bindings.add(" ") + @bindings.add("y") + @bindings.add("Y") + @bindings.add(Keys.ControlJ) + @bindings.add(Keys.ControlM) + @bindings.add(Keys.ControlI) # Tab. + def _yes(event: E) -> None: + event.app.exit(result=True) + + @bindings.add("n") + @bindings.add("N") + @bindings.add("q") + @bindings.add("Q") + @bindings.add(Keys.ControlC) + def _no(event: E) -> None: + event.app.exit(result=False) + + @bindings.add(Keys.Any) + def _ignore(event: E) -> None: + " Disable inserting of text. " + + return PromptSession(message, key_bindings=bindings, erase_when_done=True) diff --git a/.venv/lib/python3.8/site-packages/prompt_toolkit/key_binding/bindings/cpr.py b/.venv/lib/python3.8/site-packages/prompt_toolkit/key_binding/bindings/cpr.py new file mode 100644 index 00000000..07b0fa75 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/prompt_toolkit/key_binding/bindings/cpr.py @@ -0,0 +1,28 @@ +from prompt_toolkit.key_binding.key_processor import KeyPressEvent +from prompt_toolkit.keys import Keys + +from ..key_bindings import KeyBindings + +__all__ = [ + "load_cpr_bindings", +] + +E = KeyPressEvent + + +def load_cpr_bindings() -> KeyBindings: + key_bindings = KeyBindings() + + @key_bindings.add(Keys.CPRResponse, save_before=lambda e: False) + def _(event: E) -> None: + """ + Handle incoming Cursor-Position-Request response. + """ + # The incoming data looks like u'\x1b[35;1R' + # Parse row/col information. + row, col = map(int, event.data[2:-1].split(";")) + + # Report absolute cursor position to the renderer. + event.app.renderer.report_absolute_cursor_row(row) + + return key_bindings diff --git a/.venv/lib/python3.8/site-packages/prompt_toolkit/key_binding/bindings/emacs.py b/.venv/lib/python3.8/site-packages/prompt_toolkit/key_binding/bindings/emacs.py new file mode 100644 index 00000000..35c8aa4e --- /dev/null +++ b/.venv/lib/python3.8/site-packages/prompt_toolkit/key_binding/bindings/emacs.py @@ -0,0 +1,556 @@ +# pylint: disable=function-redefined +from typing import Dict, Union + +from prompt_toolkit.application.current import get_app +from prompt_toolkit.buffer import Buffer, SelectionType, indent, unindent +from prompt_toolkit.completion import CompleteEvent +from prompt_toolkit.filters import ( + Condition, + emacs_insert_mode, + emacs_mode, + has_arg, + has_selection, + in_paste_mode, + is_multiline, + is_read_only, + shift_selection_mode, + vi_search_direction_reversed, +) +from prompt_toolkit.key_binding.key_bindings import Binding +from prompt_toolkit.key_binding.key_processor import KeyPressEvent +from prompt_toolkit.keys import Keys + +from ..key_bindings import ConditionalKeyBindings, KeyBindings, KeyBindingsBase +from .named_commands import get_by_name + +__all__ = [ + "load_emacs_bindings", + "load_emacs_search_bindings", + "load_emacs_shift_selection_bindings", +] + +E = KeyPressEvent + + +def load_emacs_bindings() -> KeyBindingsBase: + """ + Some e-macs extensions. + """ + # Overview of Readline emacs commands: + # http://www.catonmat.net/download/readline-emacs-editing-mode-cheat-sheet.pdf + key_bindings = KeyBindings() + handle = key_bindings.add + + insert_mode = emacs_insert_mode + + @handle("escape") + def _esc(event: E) -> None: + """ + By default, ignore escape key. + + (If we don't put this here, and Esc is followed by a key which sequence + is not handled, we'll insert an Escape character in the input stream. + Something we don't want and happens to easily in emacs mode. + Further, people can always use ControlQ to do a quoted insert.) + """ + pass + + handle("c-a")(get_by_name("beginning-of-line")) + handle("c-b")(get_by_name("backward-char")) + handle("c-delete", filter=insert_mode)(get_by_name("kill-word")) + handle("c-e")(get_by_name("end-of-line")) + handle("c-f")(get_by_name("forward-char")) + handle("c-left")(get_by_name("backward-word")) + handle("c-right")(get_by_name("forward-word")) + handle("c-x", "r", "y", filter=insert_mode)(get_by_name("yank")) + handle("c-y", filter=insert_mode)(get_by_name("yank")) + handle("escape", "b")(get_by_name("backward-word")) + handle("escape", "c", filter=insert_mode)(get_by_name("capitalize-word")) + handle("escape", "d", filter=insert_mode)(get_by_name("kill-word")) + handle("escape", "f")(get_by_name("forward-word")) + handle("escape", "l", filter=insert_mode)(get_by_name("downcase-word")) + handle("escape", "u", filter=insert_mode)(get_by_name("uppercase-word")) + handle("escape", "y", filter=insert_mode)(get_by_name("yank-pop")) + handle("escape", "backspace", filter=insert_mode)(get_by_name("backward-kill-word")) + handle("escape", "\\", filter=insert_mode)(get_by_name("delete-horizontal-space")) + + handle("c-home")(get_by_name("beginning-of-buffer")) + handle("c-end")(get_by_name("end-of-buffer")) + + handle("c-_", save_before=(lambda e: False), filter=insert_mode)( + get_by_name("undo") + ) + + handle("c-x", "c-u", save_before=(lambda e: False), filter=insert_mode)( + get_by_name("undo") + ) + + handle("escape", "<", filter=~has_selection)(get_by_name("beginning-of-history")) + handle("escape", ">", filter=~has_selection)(get_by_name("end-of-history")) + + handle("escape", ".", filter=insert_mode)(get_by_name("yank-last-arg")) + handle("escape", "_", filter=insert_mode)(get_by_name("yank-last-arg")) + handle("escape", "c-y", filter=insert_mode)(get_by_name("yank-nth-arg")) + handle("escape", "#", filter=insert_mode)(get_by_name("insert-comment")) + handle("c-o")(get_by_name("operate-and-get-next")) + + # ControlQ does a quoted insert. Not that for vt100 terminals, you have to + # disable flow control by running ``stty -ixon``, otherwise Ctrl-Q and + # Ctrl-S are captured by the terminal. + handle("c-q", filter=~has_selection)(get_by_name("quoted-insert")) + + handle("c-x", "(")(get_by_name("start-kbd-macro")) + handle("c-x", ")")(get_by_name("end-kbd-macro")) + handle("c-x", "e")(get_by_name("call-last-kbd-macro")) + + @handle("c-n") + def _next(event: E) -> None: + " Next line. " + event.current_buffer.auto_down() + + @handle("c-p") + def _prev(event: E) -> None: + " Previous line. " + event.current_buffer.auto_up(count=event.arg) + + def handle_digit(c: str) -> None: + """ + Handle input of arguments. + The first number needs to be preceded by escape. + """ + + @handle(c, filter=has_arg) + @handle("escape", c) + def _(event: E) -> None: + event.append_to_arg_count(c) + + for c in "0123456789": + handle_digit(c) + + @handle("escape", "-", filter=~has_arg) + def _meta_dash(event: E) -> None: + """""" + if event._arg is None: + event.append_to_arg_count("-") + + @handle("-", filter=Condition(lambda: get_app().key_processor.arg == "-")) + def _dash(event: E) -> None: + """ + When '-' is typed again, after exactly '-' has been given as an + argument, ignore this. + """ + event.app.key_processor.arg = "-" + + @Condition + def is_returnable() -> bool: + return get_app().current_buffer.is_returnable + + # Meta + Enter: always accept input. + handle("escape", "enter", filter=insert_mode & is_returnable)( + get_by_name("accept-line") + ) + + # Enter: accept input in single line mode. + handle("enter", filter=insert_mode & is_returnable & ~is_multiline)( + get_by_name("accept-line") + ) + + def character_search(buff: Buffer, char: str, count: int) -> None: + if count < 0: + match = buff.document.find_backwards( + char, in_current_line=True, count=-count + ) + else: + match = buff.document.find(char, in_current_line=True, count=count) + + if match is not None: + buff.cursor_position += match + + @handle("c-]", Keys.Any) + def _goto_char(event: E) -> None: + " When Ctl-] + a character is pressed. go to that character. " + # Also named 'character-search' + character_search(event.current_buffer, event.data, event.arg) + + @handle("escape", "c-]", Keys.Any) + def _goto_char_backwards(event: E) -> None: + " Like Ctl-], but backwards. " + # Also named 'character-search-backward' + character_search(event.current_buffer, event.data, -event.arg) + + @handle("escape", "a") + def _prev_sentence(event: E) -> None: + " Previous sentence. " + # TODO: + + @handle("escape", "e") + def _end_of_sentence(event: E) -> None: + " Move to end of sentence. " + # TODO: + + @handle("escape", "t", filter=insert_mode) + def _swap_characters(event: E) -> None: + """ + Swap the last two words before the cursor. + """ + # TODO + + @handle("escape", "*", filter=insert_mode) + def _insert_all_completions(event: E) -> None: + """ + `meta-*`: Insert all possible completions of the preceding text. + """ + buff = event.current_buffer + + # List all completions. + complete_event = CompleteEvent(text_inserted=False, completion_requested=True) + completions = list( + buff.completer.get_completions(buff.document, complete_event) + ) + + # Insert them. + text_to_insert = " ".join(c.text for c in completions) + buff.insert_text(text_to_insert) + + @handle("c-x", "c-x") + def _toggle_start_end(event: E) -> None: + """ + Move cursor back and forth between the start and end of the current + line. + """ + buffer = event.current_buffer + + if buffer.document.is_cursor_at_the_end_of_line: + buffer.cursor_position += buffer.document.get_start_of_line_position( + after_whitespace=False + ) + else: + buffer.cursor_position += buffer.document.get_end_of_line_position() + + @handle("c-@") # Control-space or Control-@ + def _start_selection(event: E) -> None: + """ + Start of the selection (if the current buffer is not empty). + """ + # Take the current cursor position as the start of this selection. + buff = event.current_buffer + if buff.text: + buff.start_selection(selection_type=SelectionType.CHARACTERS) + + @handle("c-g", filter=~has_selection) + def _cancel(event: E) -> None: + """ + Control + G: Cancel completion menu and validation state. + """ + event.current_buffer.complete_state = None + event.current_buffer.validation_error = None + + @handle("c-g", filter=has_selection) + def _cancel_selection(event: E) -> None: + """ + Cancel selection. + """ + event.current_buffer.exit_selection() + + @handle("c-w", filter=has_selection) + @handle("c-x", "r", "k", filter=has_selection) + def _cut(event: E) -> None: + """ + Cut selected text. + """ + data = event.current_buffer.cut_selection() + event.app.clipboard.set_data(data) + + @handle("escape", "w", filter=has_selection) + def _copy(event: E) -> None: + """ + Copy selected text. + """ + data = event.current_buffer.copy_selection() + event.app.clipboard.set_data(data) + + @handle("escape", "left") + def _start_of_word(event: E) -> None: + """ + Cursor to start of previous word. + """ + buffer = event.current_buffer + buffer.cursor_position += ( + buffer.document.find_previous_word_beginning(count=event.arg) or 0 + ) + + @handle("escape", "right") + def _start_next_word(event: E) -> None: + """ + Cursor to start of next word. + """ + buffer = event.current_buffer + buffer.cursor_position += ( + buffer.document.find_next_word_beginning(count=event.arg) + or buffer.document.get_end_of_document_position() + ) + + @handle("escape", "/", filter=insert_mode) + def _complete(event: E) -> None: + """ + M-/: Complete. + """ + b = event.current_buffer + if b.complete_state: + b.complete_next() + else: + b.start_completion(select_first=True) + + @handle("c-c", ">", filter=has_selection) + def _indent(event: E) -> None: + """ + Indent selected text. + """ + buffer = event.current_buffer + + buffer.cursor_position += buffer.document.get_start_of_line_position( + after_whitespace=True + ) + + from_, to = buffer.document.selection_range() + from_, _ = buffer.document.translate_index_to_position(from_) + to, _ = buffer.document.translate_index_to_position(to) + + indent(buffer, from_, to + 1, count=event.arg) + + @handle("c-c", "<", filter=has_selection) + def _unindent(event: E) -> None: + """ + Unindent selected text. + """ + buffer = event.current_buffer + + from_, to = buffer.document.selection_range() + from_, _ = buffer.document.translate_index_to_position(from_) + to, _ = buffer.document.translate_index_to_position(to) + + unindent(buffer, from_, to + 1, count=event.arg) + + return ConditionalKeyBindings(key_bindings, emacs_mode) + + +def load_emacs_search_bindings() -> KeyBindingsBase: + key_bindings = KeyBindings() + handle = key_bindings.add + from . import search + + # NOTE: We don't bind 'Escape' to 'abort_search'. The reason is that we + # want Alt+Enter to accept input directly in incremental search mode. + # Instead, we have double escape. + + handle("c-r")(search.start_reverse_incremental_search) + handle("c-s")(search.start_forward_incremental_search) + + handle("c-c")(search.abort_search) + handle("c-g")(search.abort_search) + handle("c-r")(search.reverse_incremental_search) + handle("c-s")(search.forward_incremental_search) + handle("up")(search.reverse_incremental_search) + handle("down")(search.forward_incremental_search) + handle("enter")(search.accept_search) + + # Handling of escape. + handle("escape", eager=True)(search.accept_search) + + # Like Readline, it's more natural to accept the search when escape has + # been pressed, however instead the following two bindings could be used + # instead. + # #handle('escape', 'escape', eager=True)(search.abort_search) + # #handle('escape', 'enter', eager=True)(search.accept_search_and_accept_input) + + # If Read-only: also include the following key bindings: + + # '/' and '?' key bindings for searching, just like Vi mode. + handle("?", filter=is_read_only & ~vi_search_direction_reversed)( + search.start_reverse_incremental_search + ) + handle("/", filter=is_read_only & ~vi_search_direction_reversed)( + search.start_forward_incremental_search + ) + handle("?", filter=is_read_only & vi_search_direction_reversed)( + search.start_forward_incremental_search + ) + handle("/", filter=is_read_only & vi_search_direction_reversed)( + search.start_reverse_incremental_search + ) + + @handle("n", filter=is_read_only) + def _jump_next(event: E) -> None: + " Jump to next match. " + event.current_buffer.apply_search( + event.app.current_search_state, + include_current_position=False, + count=event.arg, + ) + + @handle("N", filter=is_read_only) + def _jump_prev(event: E) -> None: + " Jump to previous match. " + event.current_buffer.apply_search( + ~event.app.current_search_state, + include_current_position=False, + count=event.arg, + ) + + return ConditionalKeyBindings(key_bindings, emacs_mode) + + +def load_emacs_shift_selection_bindings() -> KeyBindingsBase: + """ + Bindings to select text with shift + cursor movements + """ + + key_bindings = KeyBindings() + handle = key_bindings.add + + def unshift_move(event: E) -> None: + """ + Used for the shift selection mode. When called with + a shift + movement key press event, moves the cursor + as if shift is not pressed. + """ + key = event.key_sequence[0].key + + if key == Keys.ShiftUp: + event.current_buffer.auto_up(count=event.arg) + return + if key == Keys.ShiftDown: + event.current_buffer.auto_down(count=event.arg) + return + + # the other keys are handled through their readline command + key_to_command: Dict[Union[Keys, str], str] = { + Keys.ShiftLeft: "backward-char", + Keys.ShiftRight: "forward-char", + Keys.ShiftHome: "beginning-of-line", + Keys.ShiftEnd: "end-of-line", + Keys.ControlShiftLeft: "backward-word", + Keys.ControlShiftRight: "forward-word", + Keys.ControlShiftHome: "beginning-of-buffer", + Keys.ControlShiftEnd: "end-of-buffer", + } + + try: + # Both the dict lookup and `get_by_name` can raise KeyError. + binding = get_by_name(key_to_command[key]) + except KeyError: + pass + else: # (`else` is not really needed here.) + if isinstance(binding, Binding): + # (It should always be a binding here) + binding.call(event) + + @handle("s-left", filter=~has_selection) + @handle("s-right", filter=~has_selection) + @handle("s-up", filter=~has_selection) + @handle("s-down", filter=~has_selection) + @handle("s-home", filter=~has_selection) + @handle("s-end", filter=~has_selection) + @handle("c-s-left", filter=~has_selection) + @handle("c-s-right", filter=~has_selection) + @handle("c-s-home", filter=~has_selection) + @handle("c-s-end", filter=~has_selection) + def _start_selection(event: E) -> None: + """ + Start selection with shift + movement. + """ + # Take the current cursor position as the start of this selection. + buff = event.current_buffer + if buff.text: + buff.start_selection(selection_type=SelectionType.CHARACTERS) + + if buff.selection_state is not None: + # (`selection_state` should never be `None`, it is created by + # `start_selection`.) + buff.selection_state.enter_shift_mode() + + # Then move the cursor + original_position = buff.cursor_position + unshift_move(event) + if buff.cursor_position == original_position: + # Cursor didn't actually move - so cancel selection + # to avoid having an empty selection + buff.exit_selection() + + @handle("s-left", filter=shift_selection_mode) + @handle("s-right", filter=shift_selection_mode) + @handle("s-up", filter=shift_selection_mode) + @handle("s-down", filter=shift_selection_mode) + @handle("s-home", filter=shift_selection_mode) + @handle("s-end", filter=shift_selection_mode) + @handle("c-s-left", filter=shift_selection_mode) + @handle("c-s-right", filter=shift_selection_mode) + @handle("c-s-home", filter=shift_selection_mode) + @handle("c-s-end", filter=shift_selection_mode) + def _extend_selection(event: E) -> None: + """ + Extend the selection + """ + # Just move the cursor, like shift was not pressed + unshift_move(event) + buff = event.current_buffer + + if buff.selection_state is not None: + if buff.cursor_position == buff.selection_state.original_cursor_position: + # selection is now empty, so cancel selection + buff.exit_selection() + + @handle(Keys.Any, filter=shift_selection_mode) + def _replace_selection(event: E) -> None: + """ + Replace selection by what is typed + """ + event.current_buffer.cut_selection() + get_by_name("self-insert").call(event) + + @handle("enter", filter=shift_selection_mode & is_multiline) + def _newline(event: E) -> None: + """ + A newline replaces the selection + """ + event.current_buffer.cut_selection() + event.current_buffer.newline(copy_margin=not in_paste_mode()) + + @handle("backspace", filter=shift_selection_mode) + def _delete(event: E) -> None: + """ + Delete selection. + """ + event.current_buffer.cut_selection() + + @handle("c-y", filter=shift_selection_mode) + def _yank(event: E) -> None: + """ + In shift selection mode, yanking (pasting) replace the selection. + """ + buff = event.current_buffer + if buff.selection_state: + buff.cut_selection() + get_by_name("yank").call(event) + + # moving the cursor in shift selection mode cancels the selection + @handle("left", filter=shift_selection_mode) + @handle("right", filter=shift_selection_mode) + @handle("up", filter=shift_selection_mode) + @handle("down", filter=shift_selection_mode) + @handle("home", filter=shift_selection_mode) + @handle("end", filter=shift_selection_mode) + @handle("c-left", filter=shift_selection_mode) + @handle("c-right", filter=shift_selection_mode) + @handle("c-home", filter=shift_selection_mode) + @handle("c-end", filter=shift_selection_mode) + def _cancel(event: E) -> None: + """ + Cancel selection. + """ + event.current_buffer.exit_selection() + # we then process the cursor movement + key_press = event.key_sequence[0] + event.key_processor.feed(key_press, first=True) + + return ConditionalKeyBindings(key_bindings, emacs_mode) diff --git a/.venv/lib/python3.8/site-packages/prompt_toolkit/key_binding/bindings/focus.py b/.venv/lib/python3.8/site-packages/prompt_toolkit/key_binding/bindings/focus.py new file mode 100644 index 00000000..40844db6 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/prompt_toolkit/key_binding/bindings/focus.py @@ -0,0 +1,24 @@ +from prompt_toolkit.key_binding.key_processor import KeyPressEvent + +__all__ = [ + "focus_next", + "focus_previous", +] + +E = KeyPressEvent + + +def focus_next(event: E) -> None: + """ + Focus the next visible Window. + (Often bound to the `Tab` key.) + """ + event.app.layout.focus_next() + + +def focus_previous(event: E) -> None: + """ + Focus the previous visible Window. + (Often bound to the `BackTab` key.) + """ + event.app.layout.focus_previous() diff --git a/.venv/lib/python3.8/site-packages/prompt_toolkit/key_binding/bindings/mouse.py b/.venv/lib/python3.8/site-packages/prompt_toolkit/key_binding/bindings/mouse.py new file mode 100644 index 00000000..b82f23f7 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/prompt_toolkit/key_binding/bindings/mouse.py @@ -0,0 +1,146 @@ +from prompt_toolkit.data_structures import Point +from prompt_toolkit.key_binding.key_processor import KeyPress, KeyPressEvent +from prompt_toolkit.keys import Keys +from prompt_toolkit.mouse_events import MouseEvent, MouseEventType +from prompt_toolkit.utils import is_windows + +from ..key_bindings import KeyBindings + +__all__ = [ + "load_mouse_bindings", +] + +E = KeyPressEvent + + +def load_mouse_bindings() -> KeyBindings: + """ + Key bindings, required for mouse support. + (Mouse events enter through the key binding system.) + """ + key_bindings = KeyBindings() + + @key_bindings.add(Keys.Vt100MouseEvent) + def _(event: E) -> None: + """ + Handling of incoming mouse event. + """ + # TypicaL: "eSC[MaB*" + # Urxvt: "Esc[96;14;13M" + # Xterm SGR: "Esc[<64;85;12M" + + # Parse incoming packet. + if event.data[2] == "M": + # Typical. + mouse_event, x, y = map(ord, event.data[3:]) + mouse_event_type = { + 32: MouseEventType.MOUSE_DOWN, + 35: MouseEventType.MOUSE_UP, + 96: MouseEventType.SCROLL_UP, + 97: MouseEventType.SCROLL_DOWN, + }.get(mouse_event) + + # Handle situations where `PosixStdinReader` used surrogateescapes. + if x >= 0xDC00: + x -= 0xDC00 + if y >= 0xDC00: + y -= 0xDC00 + + x -= 32 + y -= 32 + else: + # Urxvt and Xterm SGR. + # When the '<' is not present, we are not using the Xterm SGR mode, + # but Urxvt instead. + data = event.data[2:] + if data[:1] == "<": + sgr = True + data = data[1:] + else: + sgr = False + + # Extract coordinates. + mouse_event, x, y = map(int, data[:-1].split(";")) + m = data[-1] + + # Parse event type. + if sgr: + mouse_event_type = { + (0, "M"): MouseEventType.MOUSE_DOWN, + (0, "m"): MouseEventType.MOUSE_UP, + (64, "M"): MouseEventType.SCROLL_UP, + (65, "M"): MouseEventType.SCROLL_DOWN, + }.get((mouse_event, m)) + else: + mouse_event_type = { + 32: MouseEventType.MOUSE_DOWN, + 35: MouseEventType.MOUSE_UP, + 96: MouseEventType.SCROLL_UP, + 97: MouseEventType.SCROLL_DOWN, + }.get(mouse_event) + + x -= 1 + y -= 1 + + # Only handle mouse events when we know the window height. + if event.app.renderer.height_is_known and mouse_event_type is not None: + # Take region above the layout into account. The reported + # coordinates are absolute to the visible part of the terminal. + from prompt_toolkit.renderer import HeightIsUnknownError + + try: + y -= event.app.renderer.rows_above_layout + except HeightIsUnknownError: + return + + # Call the mouse handler from the renderer. + handler = event.app.renderer.mouse_handlers.mouse_handlers[x, y] + handler(MouseEvent(position=Point(x=x, y=y), event_type=mouse_event_type)) + + @key_bindings.add(Keys.ScrollUp) + def _scroll_up(event: E) -> None: + """ + Scroll up event without cursor position. + """ + # We don't receive a cursor position, so we don't know which window to + # scroll. Just send an 'up' key press instead. + event.key_processor.feed(KeyPress(Keys.Up), first=True) + + @key_bindings.add(Keys.ScrollDown) + def _scroll_down(event: E) -> None: + """ + Scroll down event without cursor position. + """ + event.key_processor.feed(KeyPress(Keys.Down), first=True) + + @key_bindings.add(Keys.WindowsMouseEvent) + def _mouse(event: E) -> None: + """ + Handling of mouse events for Windows. + """ + assert is_windows() # This key binding should only exist for Windows. + + # Parse data. + pieces = event.data.split(";") + + event_type = MouseEventType(pieces[0]) + x = int(pieces[1]) + y = int(pieces[2]) + + # Make coordinates absolute to the visible part of the terminal. + output = event.app.renderer.output + + from prompt_toolkit.output.win32 import Win32Output + + if isinstance(output, Win32Output): + screen_buffer_info = output.get_win32_screen_buffer_info() + rows_above_cursor = ( + screen_buffer_info.dwCursorPosition.Y - event.app.renderer._cursor_pos.y + ) + y -= rows_above_cursor + + # Call the mouse event handler. + handler = event.app.renderer.mouse_handlers.mouse_handlers[x, y] + handler(MouseEvent(position=Point(x=x, y=y), event_type=event_type)) + + return key_bindings diff --git a/.venv/lib/python3.8/site-packages/prompt_toolkit/key_binding/bindings/named_commands.py b/.venv/lib/python3.8/site-packages/prompt_toolkit/key_binding/bindings/named_commands.py new file mode 100644 index 00000000..74c81a03 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/prompt_toolkit/key_binding/bindings/named_commands.py @@ -0,0 +1,687 @@ +""" +Key bindings which are also known by GNU Readline by the given names. + +See: http://www.delorie.com/gnu/docs/readline/rlman_13.html +""" +from typing import Callable, Dict, TypeVar, Union, cast + +from prompt_toolkit.document import Document +from prompt_toolkit.enums import EditingMode +from prompt_toolkit.key_binding.key_bindings import Binding, key_binding +from prompt_toolkit.key_binding.key_processor import KeyPress, KeyPressEvent +from prompt_toolkit.keys import Keys +from prompt_toolkit.layout.controls import BufferControl +from prompt_toolkit.search import SearchDirection +from prompt_toolkit.selection import PasteMode + +from .completion import display_completions_like_readline, generate_completions + +__all__ = [ + "get_by_name", +] + + +# Typing. +_Handler = Callable[[KeyPressEvent], None] +_HandlerOrBinding = Union[_Handler, Binding] +_T = TypeVar("_T", bound=_HandlerOrBinding) +E = KeyPressEvent + + +# Registry that maps the Readline command names to their handlers. +_readline_commands: Dict[str, Binding] = {} + + +def register(name: str) -> Callable[[_T], _T]: + """ + Store handler in the `_readline_commands` dictionary. + """ + + def decorator(handler: _T) -> _T: + " `handler` is a callable or Binding. " + if isinstance(handler, Binding): + _readline_commands[name] = handler + else: + _readline_commands[name] = key_binding()(cast(_Handler, handler)) + + return handler + + return decorator + + +def get_by_name(name: str) -> Binding: + """ + Return the handler for the (Readline) command with the given name. + """ + try: + return _readline_commands[name] + except KeyError as e: + raise KeyError("Unknown Readline command: %r" % name) from e + + +# +# Commands for moving +# See: http://www.delorie.com/gnu/docs/readline/rlman_14.html +# + + +@register("beginning-of-buffer") +def beginning_of_buffer(event: E) -> None: + """ + Move to the start of the buffer. + """ + buff = event.current_buffer + buff.cursor_position = 0 + + +@register("end-of-buffer") +def end_of_buffer(event: E) -> None: + """ + Move to the end of the buffer. + """ + buff = event.current_buffer + buff.cursor_position = len(buff.text) + + +@register("beginning-of-line") +def beginning_of_line(event: E) -> None: + """ + Move to the start of the current line. + """ + buff = event.current_buffer + buff.cursor_position += buff.document.get_start_of_line_position( + after_whitespace=False + ) + + +@register("end-of-line") +def end_of_line(event: E) -> None: + """ + Move to the end of the line. + """ + buff = event.current_buffer + buff.cursor_position += buff.document.get_end_of_line_position() + + +@register("forward-char") +def forward_char(event: E) -> None: + """ + Move forward a character. + """ + buff = event.current_buffer + buff.cursor_position += buff.document.get_cursor_right_position(count=event.arg) + + +@register("backward-char") +def backward_char(event: E) -> None: + " Move back a character. " + buff = event.current_buffer + buff.cursor_position += buff.document.get_cursor_left_position(count=event.arg) + + +@register("forward-word") +def forward_word(event: E) -> None: + """ + Move forward to the end of the next word. Words are composed of letters and + digits. + """ + buff = event.current_buffer + pos = buff.document.find_next_word_ending(count=event.arg) + + if pos: + buff.cursor_position += pos + + +@register("backward-word") +def backward_word(event: E) -> None: + """ + Move back to the start of the current or previous word. Words are composed + of letters and digits. + """ + buff = event.current_buffer + pos = buff.document.find_previous_word_beginning(count=event.arg) + + if pos: + buff.cursor_position += pos + + +@register("clear-screen") +def clear_screen(event: E) -> None: + """ + Clear the screen and redraw everything at the top of the screen. + """ + event.app.renderer.clear() + + +@register("redraw-current-line") +def redraw_current_line(event: E) -> None: + """ + Refresh the current line. + (Readline defines this command, but prompt-toolkit doesn't have it.) + """ + pass + + +# +# Commands for manipulating the history. +# See: http://www.delorie.com/gnu/docs/readline/rlman_15.html +# + + +@register("accept-line") +def accept_line(event: E) -> None: + """ + Accept the line regardless of where the cursor is. + """ + event.current_buffer.validate_and_handle() + + +@register("previous-history") +def previous_history(event: E) -> None: + """ + Move `back` through the history list, fetching the previous command. + """ + event.current_buffer.history_backward(count=event.arg) + + +@register("next-history") +def next_history(event: E) -> None: + """ + Move `forward` through the history list, fetching the next command. + """ + event.current_buffer.history_forward(count=event.arg) + + +@register("beginning-of-history") +def beginning_of_history(event: E) -> None: + """ + Move to the first line in the history. + """ + event.current_buffer.go_to_history(0) + + +@register("end-of-history") +def end_of_history(event: E) -> None: + """ + Move to the end of the input history, i.e., the line currently being entered. + """ + event.current_buffer.history_forward(count=10 ** 100) + buff = event.current_buffer + buff.go_to_history(len(buff._working_lines) - 1) + + +@register("reverse-search-history") +def reverse_search_history(event: E) -> None: + """ + Search backward starting at the current line and moving `up` through + the history as necessary. This is an incremental search. + """ + control = event.app.layout.current_control + + if isinstance(control, BufferControl) and control.search_buffer_control: + event.app.current_search_state.direction = SearchDirection.BACKWARD + event.app.layout.current_control = control.search_buffer_control + + +# +# Commands for changing text +# + + +@register("end-of-file") +def end_of_file(event: E) -> None: + """ + Exit. + """ + event.app.exit() + + +@register("delete-char") +def delete_char(event: E) -> None: + """ + Delete character before the cursor. + """ + deleted = event.current_buffer.delete(count=event.arg) + if not deleted: + event.app.output.bell() + + +@register("backward-delete-char") +def backward_delete_char(event: E) -> None: + """ + Delete the character behind the cursor. + """ + if event.arg < 0: + # When a negative argument has been given, this should delete in front + # of the cursor. + deleted = event.current_buffer.delete(count=-event.arg) + else: + deleted = event.current_buffer.delete_before_cursor(count=event.arg) + + if not deleted: + event.app.output.bell() + + +@register("self-insert") +def self_insert(event: E) -> None: + """ + Insert yourself. + """ + event.current_buffer.insert_text(event.data * event.arg) + + +@register("transpose-chars") +def transpose_chars(event: E) -> None: + """ + Emulate Emacs transpose-char behavior: at the beginning of the buffer, + do nothing. At the end of a line or buffer, swap the characters before + the cursor. Otherwise, move the cursor right, and then swap the + characters before the cursor. + """ + b = event.current_buffer + p = b.cursor_position + if p == 0: + return + elif p == len(b.text) or b.text[p] == "\n": + b.swap_characters_before_cursor() + else: + b.cursor_position += b.document.get_cursor_right_position() + b.swap_characters_before_cursor() + + +@register("uppercase-word") +def uppercase_word(event: E) -> None: + """ + Uppercase the current (or following) word. + """ + buff = event.current_buffer + + for i in range(event.arg): + pos = buff.document.find_next_word_ending() + words = buff.document.text_after_cursor[:pos] + buff.insert_text(words.upper(), overwrite=True) + + +@register("downcase-word") +def downcase_word(event: E) -> None: + """ + Lowercase the current (or following) word. + """ + buff = event.current_buffer + + for i in range(event.arg): # XXX: not DRY: see meta_c and meta_u!! + pos = buff.document.find_next_word_ending() + words = buff.document.text_after_cursor[:pos] + buff.insert_text(words.lower(), overwrite=True) + + +@register("capitalize-word") +def capitalize_word(event: E) -> None: + """ + Capitalize the current (or following) word. + """ + buff = event.current_buffer + + for i in range(event.arg): + pos = buff.document.find_next_word_ending() + words = buff.document.text_after_cursor[:pos] + buff.insert_text(words.title(), overwrite=True) + + +@register("quoted-insert") +def quoted_insert(event: E) -> None: + """ + Add the next character typed to the line verbatim. This is how to insert + key sequences like C-q, for example. + """ + event.app.quoted_insert = True + + +# +# Killing and yanking. +# + + +@register("kill-line") +def kill_line(event: E) -> None: + """ + Kill the text from the cursor to the end of the line. + + If we are at the end of the line, this should remove the newline. + (That way, it is possible to delete multiple lines by executing this + command multiple times.) + """ + buff = event.current_buffer + if event.arg < 0: + deleted = buff.delete_before_cursor( + count=-buff.document.get_start_of_line_position() + ) + else: + if buff.document.current_char == "\n": + deleted = buff.delete(1) + else: + deleted = buff.delete(count=buff.document.get_end_of_line_position()) + event.app.clipboard.set_text(deleted) + + +@register("kill-word") +def kill_word(event: E) -> None: + """ + Kill from point to the end of the current word, or if between words, to the + end of the next word. Word boundaries are the same as forward-word. + """ + buff = event.current_buffer + pos = buff.document.find_next_word_ending(count=event.arg) + + if pos: + deleted = buff.delete(count=pos) + + if event.is_repeat: + deleted = event.app.clipboard.get_data().text + deleted + + event.app.clipboard.set_text(deleted) + + +@register("unix-word-rubout") +def unix_word_rubout(event: E, WORD: bool = True) -> None: + """ + Kill the word behind point, using whitespace as a word boundary. + Usually bound to ControlW. + """ + buff = event.current_buffer + pos = buff.document.find_start_of_previous_word(count=event.arg, WORD=WORD) + + if pos is None: + # Nothing found? delete until the start of the document. (The + # input starts with whitespace and no words were found before the + # cursor.) + pos = -buff.cursor_position + + if pos: + deleted = buff.delete_before_cursor(count=-pos) + + # If the previous key press was also Control-W, concatenate deleted + # text. + if event.is_repeat: + deleted += event.app.clipboard.get_data().text + + event.app.clipboard.set_text(deleted) + else: + # Nothing to delete. Bell. + event.app.output.bell() + + +@register("backward-kill-word") +def backward_kill_word(event: E) -> None: + """ + Kills the word before point, using "not a letter nor a digit" as a word boundary. + Usually bound to M-Del or M-Backspace. + """ + unix_word_rubout(event, WORD=False) + + +@register("delete-horizontal-space") +def delete_horizontal_space(event: E) -> None: + """ + Delete all spaces and tabs around point. + """ + buff = event.current_buffer + text_before_cursor = buff.document.text_before_cursor + text_after_cursor = buff.document.text_after_cursor + + delete_before = len(text_before_cursor) - len(text_before_cursor.rstrip("\t ")) + delete_after = len(text_after_cursor) - len(text_after_cursor.lstrip("\t ")) + + buff.delete_before_cursor(count=delete_before) + buff.delete(count=delete_after) + + +@register("unix-line-discard") +def unix_line_discard(event: E) -> None: + """ + Kill backward from the cursor to the beginning of the current line. + """ + buff = event.current_buffer + + if buff.document.cursor_position_col == 0 and buff.document.cursor_position > 0: + buff.delete_before_cursor(count=1) + else: + deleted = buff.delete_before_cursor( + count=-buff.document.get_start_of_line_position() + ) + event.app.clipboard.set_text(deleted) + + +@register("yank") +def yank(event: E) -> None: + """ + Paste before cursor. + """ + event.current_buffer.paste_clipboard_data( + event.app.clipboard.get_data(), count=event.arg, paste_mode=PasteMode.EMACS + ) + + +@register("yank-nth-arg") +def yank_nth_arg(event: E) -> None: + """ + Insert the first argument of the previous command. With an argument, insert + the nth word from the previous command (start counting at 0). + """ + n = event.arg if event.arg_present else None + event.current_buffer.yank_nth_arg(n) + + +@register("yank-last-arg") +def yank_last_arg(event: E) -> None: + """ + Like `yank_nth_arg`, but if no argument has been given, yank the last word + of each line. + """ + n = event.arg if event.arg_present else None + event.current_buffer.yank_last_arg(n) + + +@register("yank-pop") +def yank_pop(event: E) -> None: + """ + Rotate the kill ring, and yank the new top. Only works following yank or + yank-pop. + """ + buff = event.current_buffer + doc_before_paste = buff.document_before_paste + clipboard = event.app.clipboard + + if doc_before_paste is not None: + buff.document = doc_before_paste + clipboard.rotate() + buff.paste_clipboard_data(clipboard.get_data(), paste_mode=PasteMode.EMACS) + + +# +# Completion. +# + + +@register("complete") +def complete(event: E) -> None: + """ + Attempt to perform completion. + """ + display_completions_like_readline(event) + + +@register("menu-complete") +def menu_complete(event: E) -> None: + """ + Generate completions, or go to the next completion. (This is the default + way of completing input in prompt_toolkit.) + """ + generate_completions(event) + + +@register("menu-complete-backward") +def menu_complete_backward(event: E) -> None: + """ + Move backward through the list of possible completions. + """ + event.current_buffer.complete_previous() + + +# +# Keyboard macros. +# + + +@register("start-kbd-macro") +def start_kbd_macro(event: E) -> None: + """ + Begin saving the characters typed into the current keyboard macro. + """ + event.app.emacs_state.start_macro() + + +@register("end-kbd-macro") +def end_kbd_macro(event: E) -> None: + """ + Stop saving the characters typed into the current keyboard macro and save + the definition. + """ + event.app.emacs_state.end_macro() + + +@register("call-last-kbd-macro") +@key_binding(record_in_macro=False) +def call_last_kbd_macro(event: E) -> None: + """ + Re-execute the last keyboard macro defined, by making the characters in the + macro appear as if typed at the keyboard. + + Notice that we pass `record_in_macro=False`. This ensures that the 'c-x e' + key sequence doesn't appear in the recording itself. This function inserts + the body of the called macro back into the KeyProcessor, so these keys will + be added later on to the macro of their handlers have `record_in_macro=True`. + """ + # Insert the macro. + macro = event.app.emacs_state.macro + + if macro: + event.app.key_processor.feed_multiple(macro, first=True) + + +@register("print-last-kbd-macro") +def print_last_kbd_macro(event: E) -> None: + """ + Print the last keyboard macro. + """ + # TODO: Make the format suitable for the inputrc file. + def print_macro() -> None: + macro = event.app.emacs_state.macro + if macro: + for k in macro: + print(k) + + from prompt_toolkit.application.run_in_terminal import run_in_terminal + + run_in_terminal(print_macro) + + +# +# Miscellaneous Commands. +# + + +@register("undo") +def undo(event: E) -> None: + """ + Incremental undo. + """ + event.current_buffer.undo() + + +@register("insert-comment") +def insert_comment(event: E) -> None: + """ + Without numeric argument, comment all lines. + With numeric argument, uncomment all lines. + In any case accept the input. + """ + buff = event.current_buffer + + # Transform all lines. + if event.arg != 1: + + def change(line: str) -> str: + return line[1:] if line.startswith("#") else line + + else: + + def change(line: str) -> str: + return "#" + line + + buff.document = Document( + text="\n".join(map(change, buff.text.splitlines())), cursor_position=0 + ) + + # Accept input. + buff.validate_and_handle() + + +@register("vi-editing-mode") +def vi_editing_mode(event: E) -> None: + """ + Switch to Vi editing mode. + """ + event.app.editing_mode = EditingMode.VI + + +@register("emacs-editing-mode") +def emacs_editing_mode(event: E) -> None: + """ + Switch to Emacs editing mode. + """ + event.app.editing_mode = EditingMode.EMACS + + +@register("prefix-meta") +def prefix_meta(event: E) -> None: + """ + Metafy the next character typed. This is for keyboards without a meta key. + + Sometimes people also want to bind other keys to Meta, e.g. 'jj':: + + key_bindings.add_key_binding('j', 'j', filter=ViInsertMode())(prefix_meta) + """ + # ('first' should be true, because we want to insert it at the current + # position in the queue.) + event.app.key_processor.feed(KeyPress(Keys.Escape), first=True) + + +@register("operate-and-get-next") +def operate_and_get_next(event: E) -> None: + """ + Accept the current line for execution and fetch the next line relative to + the current line from the history for editing. + """ + buff = event.current_buffer + new_index = buff.working_index + 1 + + # Accept the current input. (This will also redraw the interface in the + # 'done' state.) + buff.validate_and_handle() + + # Set the new index at the start of the next run. + def set_working_index() -> None: + if new_index < len(buff._working_lines): + buff.working_index = new_index + + event.app.pre_run_callables.append(set_working_index) + + +@register("edit-and-execute-command") +def edit_and_execute(event: E) -> None: + """ + Invoke an editor on the current command line, and accept the result. + """ + buff = event.current_buffer + buff.open_in_editor(validate_and_handle=True) diff --git a/.venv/lib/python3.8/site-packages/prompt_toolkit/key_binding/bindings/open_in_editor.py b/.venv/lib/python3.8/site-packages/prompt_toolkit/key_binding/bindings/open_in_editor.py new file mode 100644 index 00000000..f8699f4a --- /dev/null +++ b/.venv/lib/python3.8/site-packages/prompt_toolkit/key_binding/bindings/open_in_editor.py @@ -0,0 +1,49 @@ +""" +Open in editor key bindings. +""" +from prompt_toolkit.filters import emacs_mode, has_selection, vi_navigation_mode + +from ..key_bindings import KeyBindings, KeyBindingsBase, merge_key_bindings +from .named_commands import get_by_name + +__all__ = [ + "load_open_in_editor_bindings", + "load_emacs_open_in_editor_bindings", + "load_vi_open_in_editor_bindings", +] + + +def load_open_in_editor_bindings() -> KeyBindingsBase: + """ + Load both the Vi and emacs key bindings for handling edit-and-execute-command. + """ + return merge_key_bindings( + [ + load_emacs_open_in_editor_bindings(), + load_vi_open_in_editor_bindings(), + ] + ) + + +def load_emacs_open_in_editor_bindings() -> KeyBindings: + """ + Pressing C-X C-E will open the buffer in an external editor. + """ + key_bindings = KeyBindings() + + key_bindings.add("c-x", "c-e", filter=emacs_mode & ~has_selection)( + get_by_name("edit-and-execute-command") + ) + + return key_bindings + + +def load_vi_open_in_editor_bindings() -> KeyBindings: + """ + Pressing 'v' in navigation mode will open the buffer in an external editor. + """ + key_bindings = KeyBindings() + key_bindings.add("v", filter=vi_navigation_mode)( + get_by_name("edit-and-execute-command") + ) + return key_bindings diff --git a/.venv/lib/python3.8/site-packages/prompt_toolkit/key_binding/bindings/page_navigation.py b/.venv/lib/python3.8/site-packages/prompt_toolkit/key_binding/bindings/page_navigation.py new file mode 100644 index 00000000..4d531c04 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/prompt_toolkit/key_binding/bindings/page_navigation.py @@ -0,0 +1,82 @@ +""" +Key bindings for extra page navigation: bindings for up/down scrolling through +long pages, like in Emacs or Vi. +""" +from prompt_toolkit.filters import buffer_has_focus, emacs_mode, vi_mode +from prompt_toolkit.key_binding.key_bindings import ( + ConditionalKeyBindings, + KeyBindings, + KeyBindingsBase, + merge_key_bindings, +) + +from .scroll import ( + scroll_backward, + scroll_forward, + scroll_half_page_down, + scroll_half_page_up, + scroll_one_line_down, + scroll_one_line_up, + scroll_page_down, + scroll_page_up, +) + +__all__ = [ + "load_page_navigation_bindings", + "load_emacs_page_navigation_bindings", + "load_vi_page_navigation_bindings", +] + + +def load_page_navigation_bindings() -> KeyBindingsBase: + """ + Load both the Vi and Emacs bindings for page navigation. + """ + # Only enable when a `Buffer` is focused, otherwise, we would catch keys + # when another widget is focused (like for instance `c-d` in a + # ptterm.Terminal). + return ConditionalKeyBindings( + merge_key_bindings( + [ + load_emacs_page_navigation_bindings(), + load_vi_page_navigation_bindings(), + ] + ), + buffer_has_focus, + ) + + +def load_emacs_page_navigation_bindings() -> KeyBindingsBase: + """ + Key bindings, for scrolling up and down through pages. + This are separate bindings, because GNU readline doesn't have them. + """ + key_bindings = KeyBindings() + handle = key_bindings.add + + handle("c-v")(scroll_page_down) + handle("pagedown")(scroll_page_down) + handle("escape", "v")(scroll_page_up) + handle("pageup")(scroll_page_up) + + return ConditionalKeyBindings(key_bindings, emacs_mode) + + +def load_vi_page_navigation_bindings() -> KeyBindingsBase: + """ + Key bindings, for scrolling up and down through pages. + This are separate bindings, because GNU readline doesn't have them. + """ + key_bindings = KeyBindings() + handle = key_bindings.add + + handle("c-f")(scroll_forward) + handle("c-b")(scroll_backward) + handle("c-d")(scroll_half_page_down) + handle("c-u")(scroll_half_page_up) + handle("c-e")(scroll_one_line_down) + handle("c-y")(scroll_one_line_up) + handle("pagedown")(scroll_page_down) + handle("pageup")(scroll_page_up) + + return ConditionalKeyBindings(key_bindings, vi_mode) diff --git a/.venv/lib/python3.8/site-packages/prompt_toolkit/key_binding/bindings/scroll.py b/.venv/lib/python3.8/site-packages/prompt_toolkit/key_binding/bindings/scroll.py new file mode 100644 index 00000000..4a43ff58 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/prompt_toolkit/key_binding/bindings/scroll.py @@ -0,0 +1,187 @@ +""" +Key bindings, for scrolling up and down through pages. + +This are separate bindings, because GNU readline doesn't have them, but +they are very useful for navigating through long multiline buffers, like in +Vi, Emacs, etc... +""" +from prompt_toolkit.key_binding.key_processor import KeyPressEvent + +__all__ = [ + "scroll_forward", + "scroll_backward", + "scroll_half_page_up", + "scroll_half_page_down", + "scroll_one_line_up", + "scroll_one_line_down", +] + +E = KeyPressEvent + + +def scroll_forward(event: E, half: bool = False) -> None: + """ + Scroll window down. + """ + w = event.app.layout.current_window + b = event.app.current_buffer + + if w and w.render_info: + info = w.render_info + ui_content = info.ui_content + + # Height to scroll. + scroll_height = info.window_height + if half: + scroll_height //= 2 + + # Calculate how many lines is equivalent to that vertical space. + y = b.document.cursor_position_row + 1 + height = 0 + while y < ui_content.line_count: + line_height = info.get_height_for_line(y) + + if height + line_height < scroll_height: + height += line_height + y += 1 + else: + break + + b.cursor_position = b.document.translate_row_col_to_index(y, 0) + + +def scroll_backward(event: E, half: bool = False) -> None: + """ + Scroll window up. + """ + w = event.app.layout.current_window + b = event.app.current_buffer + + if w and w.render_info: + info = w.render_info + + # Height to scroll. + scroll_height = info.window_height + if half: + scroll_height //= 2 + + # Calculate how many lines is equivalent to that vertical space. + y = max(0, b.document.cursor_position_row - 1) + height = 0 + while y > 0: + line_height = info.get_height_for_line(y) + + if height + line_height < scroll_height: + height += line_height + y -= 1 + else: + break + + b.cursor_position = b.document.translate_row_col_to_index(y, 0) + + +def scroll_half_page_down(event: E) -> None: + """ + Same as ControlF, but only scroll half a page. + """ + scroll_forward(event, half=True) + + +def scroll_half_page_up(event: E) -> None: + """ + Same as ControlB, but only scroll half a page. + """ + scroll_backward(event, half=True) + + +def scroll_one_line_down(event: E) -> None: + """ + scroll_offset += 1 + """ + w = event.app.layout.current_window + b = event.app.current_buffer + + if w: + # When the cursor is at the top, move to the next line. (Otherwise, only scroll.) + if w.render_info: + info = w.render_info + + if w.vertical_scroll < info.content_height - info.window_height: + if info.cursor_position.y <= info.configured_scroll_offsets.top: + b.cursor_position += b.document.get_cursor_down_position() + + w.vertical_scroll += 1 + + +def scroll_one_line_up(event: E) -> None: + """ + scroll_offset -= 1 + """ + w = event.app.layout.current_window + b = event.app.current_buffer + + if w: + # When the cursor is at the bottom, move to the previous line. (Otherwise, only scroll.) + if w.render_info: + info = w.render_info + + if w.vertical_scroll > 0: + first_line_height = info.get_height_for_line(info.first_visible_line()) + + cursor_up = info.cursor_position.y - ( + info.window_height + - 1 + - first_line_height + - info.configured_scroll_offsets.bottom + ) + + # Move cursor up, as many steps as the height of the first line. + # TODO: not entirely correct yet, in case of line wrapping and many long lines. + for _ in range(max(0, cursor_up)): + b.cursor_position += b.document.get_cursor_up_position() + + # Scroll window + w.vertical_scroll -= 1 + + +def scroll_page_down(event: E) -> None: + """ + Scroll page down. (Prefer the cursor at the top of the page, after scrolling.) + """ + w = event.app.layout.current_window + b = event.app.current_buffer + + if w and w.render_info: + # Scroll down one page. + line_index = max(w.render_info.last_visible_line(), w.vertical_scroll + 1) + w.vertical_scroll = line_index + + b.cursor_position = b.document.translate_row_col_to_index(line_index, 0) + b.cursor_position += b.document.get_start_of_line_position( + after_whitespace=True + ) + + +def scroll_page_up(event: E) -> None: + """ + Scroll page up. (Prefer the cursor at the bottom of the page, after scrolling.) + """ + w = event.app.layout.current_window + b = event.app.current_buffer + + if w and w.render_info: + # Put cursor at the first visible line. (But make sure that the cursor + # moves at least one line up.) + line_index = max( + 0, + min(w.render_info.first_visible_line(), b.document.cursor_position_row - 1), + ) + + b.cursor_position = b.document.translate_row_col_to_index(line_index, 0) + b.cursor_position += b.document.get_start_of_line_position( + after_whitespace=True + ) + + # Set the scroll offset. We can safely set it to zero; the Window will + # make sure that it scrolls at least until the cursor becomes visible. + w.vertical_scroll = 0 diff --git a/.venv/lib/python3.8/site-packages/prompt_toolkit/key_binding/bindings/search.py b/.venv/lib/python3.8/site-packages/prompt_toolkit/key_binding/bindings/search.py new file mode 100644 index 00000000..06a047e4 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/prompt_toolkit/key_binding/bindings/search.py @@ -0,0 +1,93 @@ +""" +Search related key bindings. +""" +from prompt_toolkit import search +from prompt_toolkit.application.current import get_app +from prompt_toolkit.filters import Condition, control_is_searchable, is_searching +from prompt_toolkit.key_binding.key_processor import KeyPressEvent + +from ..key_bindings import key_binding + +__all__ = [ + "abort_search", + "accept_search", + "start_reverse_incremental_search", + "start_forward_incremental_search", + "reverse_incremental_search", + "forward_incremental_search", + "accept_search_and_accept_input", +] + +E = KeyPressEvent + + +@key_binding(filter=is_searching) +def abort_search(event: E) -> None: + """ + Abort an incremental search and restore the original + line. + (Usually bound to ControlG/ControlC.) + """ + search.stop_search() + + +@key_binding(filter=is_searching) +def accept_search(event: E) -> None: + """ + When enter pressed in isearch, quit isearch mode. (Multiline + isearch would be too complicated.) + (Usually bound to Enter.) + """ + search.accept_search() + + +@key_binding(filter=control_is_searchable) +def start_reverse_incremental_search(event: E) -> None: + """ + Enter reverse incremental search. + (Usually ControlR.) + """ + search.start_search(direction=search.SearchDirection.BACKWARD) + + +@key_binding(filter=control_is_searchable) +def start_forward_incremental_search(event: E) -> None: + """ + Enter forward incremental search. + (Usually ControlS.) + """ + search.start_search(direction=search.SearchDirection.FORWARD) + + +@key_binding(filter=is_searching) +def reverse_incremental_search(event: E) -> None: + """ + Apply reverse incremental search, but keep search buffer focused. + """ + search.do_incremental_search(search.SearchDirection.BACKWARD, count=event.arg) + + +@key_binding(filter=is_searching) +def forward_incremental_search(event: E) -> None: + """ + Apply forward incremental search, but keep search buffer focused. + """ + search.do_incremental_search(search.SearchDirection.FORWARD, count=event.arg) + + +@Condition +def _previous_buffer_is_returnable() -> bool: + """ + True if the previously focused buffer has a return handler. + """ + prev_control = get_app().layout.search_target_buffer_control + return bool(prev_control and prev_control.buffer.is_returnable) + + +@key_binding(filter=is_searching & _previous_buffer_is_returnable) +def accept_search_and_accept_input(event: E) -> None: + """ + Accept the search operation first, then accept the input. + """ + search.accept_search() + event.current_buffer.validate_and_handle() diff --git a/.venv/lib/python3.8/site-packages/prompt_toolkit/key_binding/bindings/vi.py b/.venv/lib/python3.8/site-packages/prompt_toolkit/key_binding/bindings/vi.py new file mode 100644 index 00000000..51519032 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/prompt_toolkit/key_binding/bindings/vi.py @@ -0,0 +1,2221 @@ +# pylint: disable=function-redefined +import codecs +import string +from enum import Enum +from itertools import accumulate +from typing import Callable, Iterable, List, Optional, Tuple, TypeVar, Union, cast + +from prompt_toolkit.application.current import get_app +from prompt_toolkit.buffer import Buffer, indent, reshape_text, unindent +from prompt_toolkit.clipboard import ClipboardData +from prompt_toolkit.document import Document +from prompt_toolkit.filters import ( + Always, + Condition, + Filter, + has_arg, + is_read_only, + is_searching, +) +from prompt_toolkit.filters.app import ( + in_paste_mode, + is_multiline, + vi_digraph_mode, + vi_insert_mode, + vi_insert_multiple_mode, + vi_mode, + vi_navigation_mode, + vi_recording_macro, + vi_replace_mode, + vi_replace_single_mode, + vi_search_direction_reversed, + vi_selection_mode, + vi_waiting_for_text_object_mode, +) +from prompt_toolkit.input.vt100_parser import Vt100Parser +from prompt_toolkit.key_binding.digraphs import DIGRAPHS +from prompt_toolkit.key_binding.key_processor import KeyPress, KeyPressEvent +from prompt_toolkit.key_binding.vi_state import CharacterFind, InputMode +from prompt_toolkit.keys import Keys +from prompt_toolkit.search import SearchDirection +from prompt_toolkit.selection import PasteMode, SelectionState, SelectionType + +from ..key_bindings import ConditionalKeyBindings, KeyBindings, KeyBindingsBase +from .named_commands import get_by_name + +__all__ = [ + "load_vi_bindings", + "load_vi_search_bindings", +] + +E = KeyPressEvent + +ascii_lowercase = string.ascii_lowercase + +vi_register_names = ascii_lowercase + "0123456789" + + +class TextObjectType(Enum): + EXCLUSIVE = "EXCLUSIVE" + INCLUSIVE = "INCLUSIVE" + LINEWISE = "LINEWISE" + BLOCK = "BLOCK" + + +class TextObject: + """ + Return struct for functions wrapped in ``text_object``. + Both `start` and `end` are relative to the current cursor position. + """ + + def __init__( + self, start: int, end: int = 0, type: TextObjectType = TextObjectType.EXCLUSIVE + ): + + self.start = start + self.end = end + self.type = type + + @property + def selection_type(self) -> SelectionType: + if self.type == TextObjectType.LINEWISE: + return SelectionType.LINES + if self.type == TextObjectType.BLOCK: + return SelectionType.BLOCK + else: + return SelectionType.CHARACTERS + + def sorted(self) -> Tuple[int, int]: + """ + Return a (start, end) tuple where start <= end. + """ + if self.start < self.end: + return self.start, self.end + else: + return self.end, self.start + + def operator_range(self, document: Document) -> Tuple[int, int]: + """ + Return a (start, end) tuple with start <= end that indicates the range + operators should operate on. + `buffer` is used to get start and end of line positions. + + This should return something that can be used in a slice, so the `end` + position is *not* included. + """ + start, end = self.sorted() + doc = document + + if ( + self.type == TextObjectType.EXCLUSIVE + and doc.translate_index_to_position(end + doc.cursor_position)[1] == 0 + ): + # If the motion is exclusive and the end of motion is on the first + # column, the end position becomes end of previous line. + end -= 1 + if self.type == TextObjectType.INCLUSIVE: + end += 1 + if self.type == TextObjectType.LINEWISE: + # Select whole lines + row, col = doc.translate_index_to_position(start + doc.cursor_position) + start = doc.translate_row_col_to_index(row, 0) - doc.cursor_position + row, col = doc.translate_index_to_position(end + doc.cursor_position) + end = ( + doc.translate_row_col_to_index(row, len(doc.lines[row])) + - doc.cursor_position + ) + return start, end + + def get_line_numbers(self, buffer: Buffer) -> Tuple[int, int]: + """ + Return a (start_line, end_line) pair. + """ + # Get absolute cursor positions from the text object. + from_, to = self.operator_range(buffer.document) + from_ += buffer.cursor_position + to += buffer.cursor_position + + # Take the start of the lines. + from_, _ = buffer.document.translate_index_to_position(from_) + to, _ = buffer.document.translate_index_to_position(to) + + return from_, to + + def cut(self, buffer: Buffer) -> Tuple[Document, ClipboardData]: + """ + Turn text object into `ClipboardData` instance. + """ + from_, to = self.operator_range(buffer.document) + + from_ += buffer.cursor_position + to += buffer.cursor_position + + # For Vi mode, the SelectionState does include the upper position, + # while `self.operator_range` does not. So, go one to the left, unless + # we're in the line mode, then we don't want to risk going to the + # previous line, and missing one line in the selection. + if self.type != TextObjectType.LINEWISE: + to -= 1 + + document = Document( + buffer.text, + to, + SelectionState(original_cursor_position=from_, type=self.selection_type), + ) + + new_document, clipboard_data = document.cut_selection() + return new_document, clipboard_data + + +# Typevar for any text object function: +TextObjectFunction = Callable[[E], TextObject] +_TOF = TypeVar("_TOF", bound=TextObjectFunction) + + +def create_text_object_decorator( + key_bindings: KeyBindings, +) -> Callable[..., Callable[[_TOF], _TOF]]: + """ + Create a decorator that can be used to register Vi text object implementations. + """ + + def text_object_decorator( + *keys: Union[Keys, str], + filter: Filter = Always(), + no_move_handler: bool = False, + no_selection_handler: bool = False, + eager: bool = False, + ) -> Callable[[_TOF], _TOF]: + """ + Register a text object function. + + Usage:: + + @text_object('w', filter=..., no_move_handler=False) + def handler(event): + # Return a text object for this key. + return TextObject(...) + + :param no_move_handler: Disable the move handler in navigation mode. + (It's still active in selection mode.) + """ + + def decorator(text_object_func: _TOF) -> _TOF: + @key_bindings.add( + *keys, filter=vi_waiting_for_text_object_mode & filter, eager=eager + ) + def _apply_operator_to_text_object(event: E) -> None: + # Arguments are multiplied. + vi_state = event.app.vi_state + event._arg = str((vi_state.operator_arg or 1) * (event.arg or 1)) + + # Call the text object handler. + text_obj = text_object_func(event) + + # Get the operator function. + # (Should never be None here, given the + # `vi_waiting_for_text_object_mode` filter state.) + operator_func = vi_state.operator_func + + if text_obj is not None and operator_func is not None: + # Call the operator function with the text object. + operator_func(event, text_obj) + + # Clear operator. + event.app.vi_state.operator_func = None + event.app.vi_state.operator_arg = None + + # Register a move operation. (Doesn't need an operator.) + if not no_move_handler: + + @key_bindings.add( + *keys, + filter=~vi_waiting_for_text_object_mode + & filter + & vi_navigation_mode, + eager=eager, + ) + def _move_in_navigation_mode(event: E) -> None: + """ + Move handler for navigation mode. + """ + text_object = text_object_func(event) + event.current_buffer.cursor_position += text_object.start + + # Register a move selection operation. + if not no_selection_handler: + + @key_bindings.add( + *keys, + filter=~vi_waiting_for_text_object_mode + & filter + & vi_selection_mode, + eager=eager, + ) + def _move_in_selection_mode(event: E) -> None: + """ + Move handler for selection mode. + """ + text_object = text_object_func(event) + buff = event.current_buffer + selection_state = buff.selection_state + + if selection_state is None: + return # Should not happen, because of the `vi_selection_mode` filter. + + # When the text object has both a start and end position, like 'i(' or 'iw', + # Turn this into a selection, otherwise the cursor. + if text_object.end: + # Take selection positions from text object. + start, end = text_object.operator_range(buff.document) + start += buff.cursor_position + end += buff.cursor_position + + selection_state.original_cursor_position = start + buff.cursor_position = end + + # Take selection type from text object. + if text_object.type == TextObjectType.LINEWISE: + selection_state.type = SelectionType.LINES + else: + selection_state.type = SelectionType.CHARACTERS + else: + event.current_buffer.cursor_position += text_object.start + + # Make it possible to chain @text_object decorators. + return text_object_func + + return decorator + + return text_object_decorator + + +# Typevar for any operator function: +OperatorFunction = Callable[[E, TextObject], None] +_OF = TypeVar("_OF", bound=OperatorFunction) + + +def create_operator_decorator( + key_bindings: KeyBindings, +) -> Callable[..., Callable[[_OF], _OF]]: + """ + Create a decorator that can be used for registering Vi operators. + """ + + def operator_decorator( + *keys: Union[Keys, str], filter: Filter = Always(), eager: bool = False + ) -> Callable[[_OF], _OF]: + """ + Register a Vi operator. + + Usage:: + + @operator('d', filter=...) + def handler(event, text_object): + # Do something with the text object here. + """ + + def decorator(operator_func: _OF) -> _OF: + @key_bindings.add( + *keys, + filter=~vi_waiting_for_text_object_mode & filter & vi_navigation_mode, + eager=eager, + ) + def _operator_in_navigation(event: E) -> None: + """ + Handle operator in navigation mode. + """ + # When this key binding is matched, only set the operator + # function in the ViState. We should execute it after a text + # object has been received. + event.app.vi_state.operator_func = operator_func + event.app.vi_state.operator_arg = event.arg + + @key_bindings.add( + *keys, + filter=~vi_waiting_for_text_object_mode & filter & vi_selection_mode, + eager=eager, + ) + def _operator_in_selection(event: E) -> None: + """ + Handle operator in selection mode. + """ + buff = event.current_buffer + selection_state = buff.selection_state + + if selection_state is not None: + # Create text object from selection. + if selection_state.type == SelectionType.LINES: + text_obj_type = TextObjectType.LINEWISE + elif selection_state.type == SelectionType.BLOCK: + text_obj_type = TextObjectType.BLOCK + else: + text_obj_type = TextObjectType.INCLUSIVE + + text_object = TextObject( + selection_state.original_cursor_position - buff.cursor_position, + type=text_obj_type, + ) + + # Execute operator. + operator_func(event, text_object) + + # Quit selection mode. + buff.selection_state = None + + return operator_func + + return decorator + + return operator_decorator + + +def load_vi_bindings() -> KeyBindingsBase: + """ + Vi extensions. + + # Overview of Readline Vi commands: + # http://www.catonmat.net/download/bash-vi-editing-mode-cheat-sheet.pdf + """ + # Note: Some key bindings have the "~IsReadOnly()" filter added. This + # prevents the handler to be executed when the focus is on a + # read-only buffer. + # This is however only required for those that change the ViState to + # INSERT mode. The `Buffer` class itself throws the + # `EditReadOnlyBuffer` exception for any text operations which is + # handled correctly. There is no need to add "~IsReadOnly" to all key + # bindings that do text manipulation. + + key_bindings = KeyBindings() + handle = key_bindings.add + + # (Note: Always take the navigation bindings in read-only mode, even when + # ViState says different.) + + TransformFunction = Tuple[Tuple[str, ...], Filter, Callable[[str], str]] + + vi_transform_functions: List[TransformFunction] = [ + # Rot 13 transformation + ( + ("g", "?"), + Always(), + lambda string: cast(str, codecs.encode(string, "rot_13")), + ), + # To lowercase + (("g", "u"), Always(), lambda string: string.lower()), + # To uppercase. + (("g", "U"), Always(), lambda string: string.upper()), + # Swap case. + (("g", "~"), Always(), lambda string: string.swapcase()), + ( + ("~",), + Condition(lambda: get_app().vi_state.tilde_operator), + lambda string: string.swapcase(), + ), + ] + + # Insert a character literally (quoted insert). + handle("c-v", filter=vi_insert_mode)(get_by_name("quoted-insert")) + + @handle("escape") + def _back_to_navigation(event: E) -> None: + """ + Escape goes to vi navigation mode. + """ + buffer = event.current_buffer + vi_state = event.app.vi_state + + if vi_state.input_mode in (InputMode.INSERT, InputMode.REPLACE): + buffer.cursor_position += buffer.document.get_cursor_left_position() + + vi_state.input_mode = InputMode.NAVIGATION + + if bool(buffer.selection_state): + buffer.exit_selection() + + @handle("k", filter=vi_selection_mode) + def _up_in_selection(event: E) -> None: + """ + Arrow up in selection mode. + """ + event.current_buffer.cursor_up(count=event.arg) + + @handle("j", filter=vi_selection_mode) + def _down_in_selection(event: E) -> None: + """ + Arrow down in selection mode. + """ + event.current_buffer.cursor_down(count=event.arg) + + @handle("up", filter=vi_navigation_mode) + @handle("c-p", filter=vi_navigation_mode) + def _up_in_navigation(event: E) -> None: + """ + Arrow up and ControlP in navigation mode go up. + """ + event.current_buffer.auto_up(count=event.arg) + + @handle("k", filter=vi_navigation_mode) + def _go_up(event: E) -> None: + """ + Go up, but if we enter a new history entry, move to the start of the + line. + """ + event.current_buffer.auto_up( + count=event.arg, go_to_start_of_line_if_history_changes=True + ) + + @handle("down", filter=vi_navigation_mode) + @handle("c-n", filter=vi_navigation_mode) + def _go_down(event: E) -> None: + """ + Arrow down and Control-N in navigation mode. + """ + event.current_buffer.auto_down(count=event.arg) + + @handle("j", filter=vi_navigation_mode) + def _go_down2(event: E) -> None: + """ + Go down, but if we enter a new history entry, go to the start of the line. + """ + event.current_buffer.auto_down( + count=event.arg, go_to_start_of_line_if_history_changes=True + ) + + @handle("backspace", filter=vi_navigation_mode) + def _go_left(event: E) -> None: + """ + In navigation-mode, move cursor. + """ + event.current_buffer.cursor_position += ( + event.current_buffer.document.get_cursor_left_position(count=event.arg) + ) + + @handle("c-n", filter=vi_insert_mode) + def _complete_next(event: E) -> None: + b = event.current_buffer + + if b.complete_state: + b.complete_next() + else: + b.start_completion(select_first=True) + + @handle("c-p", filter=vi_insert_mode) + def _complete_prev(event: E) -> None: + """ + Control-P: To previous completion. + """ + b = event.current_buffer + + if b.complete_state: + b.complete_previous() + else: + b.start_completion(select_last=True) + + @handle("c-g", filter=vi_insert_mode) + @handle("c-y", filter=vi_insert_mode) + def _accept_completion(event: E) -> None: + """ + Accept current completion. + """ + event.current_buffer.complete_state = None + + @handle("c-e", filter=vi_insert_mode) + def _cancel_completion(event: E) -> None: + """ + Cancel completion. Go back to originally typed text. + """ + event.current_buffer.cancel_completion() + + @Condition + def is_returnable() -> bool: + return get_app().current_buffer.is_returnable + + # In navigation mode, pressing enter will always return the input. + handle("enter", filter=vi_navigation_mode & is_returnable)( + get_by_name("accept-line") + ) + + # In insert mode, also accept input when enter is pressed, and the buffer + # has been marked as single line. + handle("enter", filter=is_returnable & ~is_multiline)(get_by_name("accept-line")) + + @handle("enter", filter=~is_returnable & vi_navigation_mode) + def _start_of_next_line(event: E) -> None: + """ + Go to the beginning of next line. + """ + b = event.current_buffer + b.cursor_down(count=event.arg) + b.cursor_position += b.document.get_start_of_line_position( + after_whitespace=True + ) + + # ** In navigation mode ** + + # List of navigation commands: http://hea-www.harvard.edu/~fine/Tech/vi.html + + @handle("insert", filter=vi_navigation_mode) + def _insert_mode(event: E) -> None: + """ + Pressing the Insert key. + """ + event.app.vi_state.input_mode = InputMode.INSERT + + @handle("insert", filter=vi_insert_mode) + def _navigation_mode(event: E) -> None: + """ + Pressing the Insert key. + """ + event.app.vi_state.input_mode = InputMode.NAVIGATION + + @handle("a", filter=vi_navigation_mode & ~is_read_only) + # ~IsReadOnly, because we want to stay in navigation mode for + # read-only buffers. + def _a(event: E) -> None: + event.current_buffer.cursor_position += ( + event.current_buffer.document.get_cursor_right_position() + ) + event.app.vi_state.input_mode = InputMode.INSERT + + @handle("A", filter=vi_navigation_mode & ~is_read_only) + def _A(event: E) -> None: + event.current_buffer.cursor_position += ( + event.current_buffer.document.get_end_of_line_position() + ) + event.app.vi_state.input_mode = InputMode.INSERT + + @handle("C", filter=vi_navigation_mode & ~is_read_only) + def _change_until_end_of_line(event: E) -> None: + """ + Change to end of line. + Same as 'c$' (which is implemented elsewhere.) + """ + buffer = event.current_buffer + + deleted = buffer.delete(count=buffer.document.get_end_of_line_position()) + event.app.clipboard.set_text(deleted) + event.app.vi_state.input_mode = InputMode.INSERT + + @handle("c", "c", filter=vi_navigation_mode & ~is_read_only) + @handle("S", filter=vi_navigation_mode & ~is_read_only) + def _change_current_line(event: E) -> None: # TODO: implement 'arg' + """ + Change current line + """ + buffer = event.current_buffer + + # We copy the whole line. + data = ClipboardData(buffer.document.current_line, SelectionType.LINES) + event.app.clipboard.set_data(data) + + # But we delete after the whitespace + buffer.cursor_position += buffer.document.get_start_of_line_position( + after_whitespace=True + ) + buffer.delete(count=buffer.document.get_end_of_line_position()) + event.app.vi_state.input_mode = InputMode.INSERT + + @handle("D", filter=vi_navigation_mode) + def _delete_until_end_of_line(event: E) -> None: + """ + Delete from cursor position until the end of the line. + """ + buffer = event.current_buffer + deleted = buffer.delete(count=buffer.document.get_end_of_line_position()) + event.app.clipboard.set_text(deleted) + + @handle("d", "d", filter=vi_navigation_mode) + def _delete_line(event: E) -> None: + """ + Delete line. (Or the following 'n' lines.) + """ + buffer = event.current_buffer + + # Split string in before/deleted/after text. + lines = buffer.document.lines + + before = "\n".join(lines[: buffer.document.cursor_position_row]) + deleted = "\n".join( + lines[ + buffer.document.cursor_position_row : buffer.document.cursor_position_row + + event.arg + ] + ) + after = "\n".join(lines[buffer.document.cursor_position_row + event.arg :]) + + # Set new text. + if before and after: + before = before + "\n" + + # Set text and cursor position. + buffer.document = Document( + text=before + after, + # Cursor At the start of the first 'after' line, after the leading whitespace. + cursor_position=len(before) + len(after) - len(after.lstrip(" ")), + ) + + # Set clipboard data + event.app.clipboard.set_data(ClipboardData(deleted, SelectionType.LINES)) + + @handle("x", filter=vi_selection_mode) + def _cut(event: E) -> None: + """ + Cut selection. + ('x' is not an operator.) + """ + clipboard_data = event.current_buffer.cut_selection() + event.app.clipboard.set_data(clipboard_data) + + @handle("i", filter=vi_navigation_mode & ~is_read_only) + def _i(event: E) -> None: + event.app.vi_state.input_mode = InputMode.INSERT + + @handle("I", filter=vi_navigation_mode & ~is_read_only) + def _I(event: E) -> None: + event.app.vi_state.input_mode = InputMode.INSERT + event.current_buffer.cursor_position += ( + event.current_buffer.document.get_start_of_line_position( + after_whitespace=True + ) + ) + + @Condition + def in_block_selection() -> bool: + buff = get_app().current_buffer + return bool( + buff.selection_state and buff.selection_state.type == SelectionType.BLOCK + ) + + @handle("I", filter=in_block_selection & ~is_read_only) + def insert_in_block_selection(event: E, after: bool = False) -> None: + """ + Insert in block selection mode. + """ + buff = event.current_buffer + + # Store all cursor positions. + positions = [] + + if after: + + def get_pos(from_to: Tuple[int, int]) -> int: + return from_to[1] + + else: + + def get_pos(from_to: Tuple[int, int]) -> int: + return from_to[0] + + for i, from_to in enumerate(buff.document.selection_ranges()): + positions.append(get_pos(from_to)) + if i == 0: + buff.cursor_position = get_pos(from_to) + + buff.multiple_cursor_positions = positions + + # Go to 'INSERT_MULTIPLE' mode. + event.app.vi_state.input_mode = InputMode.INSERT_MULTIPLE + buff.exit_selection() + + @handle("A", filter=in_block_selection & ~is_read_only) + def _append_after_block(event: E) -> None: + insert_in_block_selection(event, after=True) + + @handle("J", filter=vi_navigation_mode & ~is_read_only) + def _join(event: E) -> None: + """ + Join lines. + """ + for i in range(event.arg): + event.current_buffer.join_next_line() + + @handle("g", "J", filter=vi_navigation_mode & ~is_read_only) + def _join_nospace(event: E) -> None: + """ + Join lines without space. + """ + for i in range(event.arg): + event.current_buffer.join_next_line(separator="") + + @handle("J", filter=vi_selection_mode & ~is_read_only) + def _join_selection(event: E) -> None: + """ + Join selected lines. + """ + event.current_buffer.join_selected_lines() + + @handle("g", "J", filter=vi_selection_mode & ~is_read_only) + def _join_selection_nospace(event: E) -> None: + """ + Join selected lines without space. + """ + event.current_buffer.join_selected_lines(separator="") + + @handle("p", filter=vi_navigation_mode) + def _paste(event: E) -> None: + """ + Paste after + """ + event.current_buffer.paste_clipboard_data( + event.app.clipboard.get_data(), + count=event.arg, + paste_mode=PasteMode.VI_AFTER, + ) + + @handle("P", filter=vi_navigation_mode) + def _paste_before(event: E) -> None: + """ + Paste before + """ + event.current_buffer.paste_clipboard_data( + event.app.clipboard.get_data(), + count=event.arg, + paste_mode=PasteMode.VI_BEFORE, + ) + + @handle('"', Keys.Any, "p", filter=vi_navigation_mode) + def _paste_register(event: E) -> None: + """ + Paste from named register. + """ + c = event.key_sequence[1].data + if c in vi_register_names: + data = event.app.vi_state.named_registers.get(c) + if data: + event.current_buffer.paste_clipboard_data( + data, count=event.arg, paste_mode=PasteMode.VI_AFTER + ) + + @handle('"', Keys.Any, "P", filter=vi_navigation_mode) + def _paste_register_before(event: E) -> None: + """ + Paste (before) from named register. + """ + c = event.key_sequence[1].data + if c in vi_register_names: + data = event.app.vi_state.named_registers.get(c) + if data: + event.current_buffer.paste_clipboard_data( + data, count=event.arg, paste_mode=PasteMode.VI_BEFORE + ) + + @handle("r", filter=vi_navigation_mode) + def _replace(event: E) -> None: + """ + Go to 'replace-single'-mode. + """ + event.app.vi_state.input_mode = InputMode.REPLACE_SINGLE + + @handle("R", filter=vi_navigation_mode) + def _replace_mode(event: E) -> None: + """ + Go to 'replace'-mode. + """ + event.app.vi_state.input_mode = InputMode.REPLACE + + @handle("s", filter=vi_navigation_mode & ~is_read_only) + def _substitute(event: E) -> None: + """ + Substitute with new text + (Delete character(s) and go to insert mode.) + """ + text = event.current_buffer.delete(count=event.arg) + event.app.clipboard.set_text(text) + event.app.vi_state.input_mode = InputMode.INSERT + + @handle("u", filter=vi_navigation_mode, save_before=(lambda e: False)) + def _undo(event: E) -> None: + for i in range(event.arg): + event.current_buffer.undo() + + @handle("V", filter=vi_navigation_mode) + def _visual_line(event: E) -> None: + """ + Start lines selection. + """ + event.current_buffer.start_selection(selection_type=SelectionType.LINES) + + @handle("c-v", filter=vi_navigation_mode) + def _visual_block(event: E) -> None: + """ + Enter block selection mode. + """ + event.current_buffer.start_selection(selection_type=SelectionType.BLOCK) + + @handle("V", filter=vi_selection_mode) + def _visual_line2(event: E) -> None: + """ + Exit line selection mode, or go from non line selection mode to line + selection mode. + """ + selection_state = event.current_buffer.selection_state + + if selection_state is not None: + if selection_state.type != SelectionType.LINES: + selection_state.type = SelectionType.LINES + else: + event.current_buffer.exit_selection() + + @handle("v", filter=vi_navigation_mode) + def _visual(event: E) -> None: + """ + Enter character selection mode. + """ + event.current_buffer.start_selection(selection_type=SelectionType.CHARACTERS) + + @handle("v", filter=vi_selection_mode) + def _visual2(event: E) -> None: + """ + Exit character selection mode, or go from non-character-selection mode + to character selection mode. + """ + selection_state = event.current_buffer.selection_state + + if selection_state is not None: + if selection_state.type != SelectionType.CHARACTERS: + selection_state.type = SelectionType.CHARACTERS + else: + event.current_buffer.exit_selection() + + @handle("c-v", filter=vi_selection_mode) + def _visual_block2(event: E) -> None: + """ + Exit block selection mode, or go from non block selection mode to block + selection mode. + """ + selection_state = event.current_buffer.selection_state + + if selection_state is not None: + if selection_state.type != SelectionType.BLOCK: + selection_state.type = SelectionType.BLOCK + else: + event.current_buffer.exit_selection() + + @handle("a", "w", filter=vi_selection_mode) + @handle("a", "W", filter=vi_selection_mode) + def _visual_auto_word(event: E) -> None: + """ + Switch from visual linewise mode to visual characterwise mode. + """ + buffer = event.current_buffer + + if ( + buffer.selection_state + and buffer.selection_state.type == SelectionType.LINES + ): + buffer.selection_state.type = SelectionType.CHARACTERS + + @handle("x", filter=vi_navigation_mode) + def _delete(event: E) -> None: + """ + Delete character. + """ + buff = event.current_buffer + count = min(event.arg, len(buff.document.current_line_after_cursor)) + if count: + text = event.current_buffer.delete(count=count) + event.app.clipboard.set_text(text) + + @handle("X", filter=vi_navigation_mode) + def _delete_before_cursor(event: E) -> None: + buff = event.current_buffer + count = min(event.arg, len(buff.document.current_line_before_cursor)) + if count: + text = event.current_buffer.delete_before_cursor(count=count) + event.app.clipboard.set_text(text) + + @handle("y", "y", filter=vi_navigation_mode) + @handle("Y", filter=vi_navigation_mode) + def _yank_line(event: E) -> None: + """ + Yank the whole line. + """ + text = "\n".join(event.current_buffer.document.lines_from_current[: event.arg]) + event.app.clipboard.set_data(ClipboardData(text, SelectionType.LINES)) + + @handle("+", filter=vi_navigation_mode) + def _next_line(event: E) -> None: + """ + Move to first non whitespace of next line + """ + buffer = event.current_buffer + buffer.cursor_position += buffer.document.get_cursor_down_position( + count=event.arg + ) + buffer.cursor_position += buffer.document.get_start_of_line_position( + after_whitespace=True + ) + + @handle("-", filter=vi_navigation_mode) + def _prev_line(event: E) -> None: + """ + Move to first non whitespace of previous line + """ + buffer = event.current_buffer + buffer.cursor_position += buffer.document.get_cursor_up_position( + count=event.arg + ) + buffer.cursor_position += buffer.document.get_start_of_line_position( + after_whitespace=True + ) + + @handle(">", ">", filter=vi_navigation_mode) + def _indent(event: E) -> None: + """ + Indent lines. + """ + buffer = event.current_buffer + current_row = buffer.document.cursor_position_row + indent(buffer, current_row, current_row + event.arg) + + @handle("<", "<", filter=vi_navigation_mode) + def _unindent(event: E) -> None: + """ + Unindent lines. + """ + current_row = event.current_buffer.document.cursor_position_row + unindent(event.current_buffer, current_row, current_row + event.arg) + + @handle("O", filter=vi_navigation_mode & ~is_read_only) + def _open_above(event: E) -> None: + """ + Open line above and enter insertion mode + """ + event.current_buffer.insert_line_above(copy_margin=not in_paste_mode()) + event.app.vi_state.input_mode = InputMode.INSERT + + @handle("o", filter=vi_navigation_mode & ~is_read_only) + def _open_below(event: E) -> None: + """ + Open line below and enter insertion mode + """ + event.current_buffer.insert_line_below(copy_margin=not in_paste_mode()) + event.app.vi_state.input_mode = InputMode.INSERT + + @handle("~", filter=vi_navigation_mode) + def _reverse_case(event: E) -> None: + """ + Reverse case of current character and move cursor forward. + """ + buffer = event.current_buffer + c = buffer.document.current_char + + if c is not None and c != "\n": + buffer.insert_text(c.swapcase(), overwrite=True) + + @handle("g", "u", "u", filter=vi_navigation_mode & ~is_read_only) + def _lowercase_line(event: E) -> None: + """ + Lowercase current line. + """ + buff = event.current_buffer + buff.transform_current_line(lambda s: s.lower()) + + @handle("g", "U", "U", filter=vi_navigation_mode & ~is_read_only) + def _uppercase_line(event: E) -> None: + """ + Uppercase current line. + """ + buff = event.current_buffer + buff.transform_current_line(lambda s: s.upper()) + + @handle("g", "~", "~", filter=vi_navigation_mode & ~is_read_only) + def _swapcase_line(event: E) -> None: + """ + Swap case of the current line. + """ + buff = event.current_buffer + buff.transform_current_line(lambda s: s.swapcase()) + + @handle("#", filter=vi_navigation_mode) + def _prev_occurence(event: E) -> None: + """ + Go to previous occurrence of this word. + """ + b = event.current_buffer + search_state = event.app.current_search_state + + search_state.text = b.document.get_word_under_cursor() + search_state.direction = SearchDirection.BACKWARD + + b.apply_search(search_state, count=event.arg, include_current_position=False) + + @handle("*", filter=vi_navigation_mode) + def _next_occurance(event: E) -> None: + """ + Go to next occurrence of this word. + """ + b = event.current_buffer + search_state = event.app.current_search_state + + search_state.text = b.document.get_word_under_cursor() + search_state.direction = SearchDirection.FORWARD + + b.apply_search(search_state, count=event.arg, include_current_position=False) + + @handle("(", filter=vi_navigation_mode) + def _begin_of_sentence(event: E) -> None: + # TODO: go to begin of sentence. + # XXX: should become text_object. + pass + + @handle(")", filter=vi_navigation_mode) + def _end_of_sentence(event: E) -> None: + # TODO: go to end of sentence. + # XXX: should become text_object. + pass + + operator = create_operator_decorator(key_bindings) + text_object = create_text_object_decorator(key_bindings) + + @handle(Keys.Any, filter=vi_waiting_for_text_object_mode) + def _unknown_text_object(event: E) -> None: + """ + Unknown key binding while waiting for a text object. + """ + event.app.output.bell() + + # + # *** Operators *** + # + + def create_delete_and_change_operators( + delete_only: bool, with_register: bool = False + ) -> None: + """ + Delete and change operators. + + :param delete_only: Create an operator that deletes, but doesn't go to insert mode. + :param with_register: Copy the deleted text to this named register instead of the clipboard. + """ + handler_keys: Iterable[str] + if with_register: + handler_keys = ('"', Keys.Any, "cd"[delete_only]) + else: + handler_keys = "cd"[delete_only] + + @operator(*handler_keys, filter=~is_read_only) + def delete_or_change_operator(event: E, text_object: TextObject) -> None: + clipboard_data = None + buff = event.current_buffer + + if text_object: + new_document, clipboard_data = text_object.cut(buff) + buff.document = new_document + + # Set deleted/changed text to clipboard or named register. + if clipboard_data and clipboard_data.text: + if with_register: + reg_name = event.key_sequence[1].data + if reg_name in vi_register_names: + event.app.vi_state.named_registers[reg_name] = clipboard_data + else: + event.app.clipboard.set_data(clipboard_data) + + # Only go back to insert mode in case of 'change'. + if not delete_only: + event.app.vi_state.input_mode = InputMode.INSERT + + create_delete_and_change_operators(False, False) + create_delete_and_change_operators(False, True) + create_delete_and_change_operators(True, False) + create_delete_and_change_operators(True, True) + + def create_transform_handler( + filter: Filter, transform_func: Callable[[str], str], *a: str + ) -> None: + @operator(*a, filter=filter & ~is_read_only) + def _(event: E, text_object: TextObject) -> None: + """ + Apply transformation (uppercase, lowercase, rot13, swap case). + """ + buff = event.current_buffer + start, end = text_object.operator_range(buff.document) + + if start < end: + # Transform. + buff.transform_region( + buff.cursor_position + start, + buff.cursor_position + end, + transform_func, + ) + + # Move cursor + buff.cursor_position += text_object.end or text_object.start + + for k, f, func in vi_transform_functions: + create_transform_handler(f, func, *k) + + @operator("y") + def _yank(event: E, text_object: TextObject) -> None: + """ + Yank operator. (Copy text.) + """ + _, clipboard_data = text_object.cut(event.current_buffer) + if clipboard_data.text: + event.app.clipboard.set_data(clipboard_data) + + @operator('"', Keys.Any, "y") + def _yank_to_register(event: E, text_object: TextObject) -> None: + """ + Yank selection to named register. + """ + c = event.key_sequence[1].data + if c in vi_register_names: + _, clipboard_data = text_object.cut(event.current_buffer) + event.app.vi_state.named_registers[c] = clipboard_data + + @operator(">") + def _indent_text_object(event: E, text_object: TextObject) -> None: + """ + Indent. + """ + buff = event.current_buffer + from_, to = text_object.get_line_numbers(buff) + indent(buff, from_, to + 1, count=event.arg) + + @operator("<") + def _unindent_text_object(event: E, text_object: TextObject) -> None: + """ + Unindent. + """ + buff = event.current_buffer + from_, to = text_object.get_line_numbers(buff) + unindent(buff, from_, to + 1, count=event.arg) + + @operator("g", "q") + def _reshape(event: E, text_object: TextObject) -> None: + """ + Reshape text. + """ + buff = event.current_buffer + from_, to = text_object.get_line_numbers(buff) + reshape_text(buff, from_, to) + + # + # *** Text objects *** + # + + @text_object("b") + def _b(event: E) -> TextObject: + """ + Move one word or token left. + """ + return TextObject( + event.current_buffer.document.find_start_of_previous_word(count=event.arg) + or 0 + ) + + @text_object("B") + def _B(event: E) -> TextObject: + """ + Move one non-blank word left + """ + return TextObject( + event.current_buffer.document.find_start_of_previous_word( + count=event.arg, WORD=True + ) + or 0 + ) + + @text_object("$") + def _dollar(event: E) -> TextObject: + """ + 'c$', 'd$' and '$': Delete/change/move until end of line. + """ + return TextObject(event.current_buffer.document.get_end_of_line_position()) + + @text_object("w") + def _word_forward(event: E) -> TextObject: + """ + 'word' forward. 'cw', 'dw', 'w': Delete/change/move one word. + """ + return TextObject( + event.current_buffer.document.find_next_word_beginning(count=event.arg) + or event.current_buffer.document.get_end_of_document_position() + ) + + @text_object("W") + def _WORD_forward(event: E) -> TextObject: + """ + 'WORD' forward. 'cW', 'dW', 'W': Delete/change/move one WORD. + """ + return TextObject( + event.current_buffer.document.find_next_word_beginning( + count=event.arg, WORD=True + ) + or event.current_buffer.document.get_end_of_document_position() + ) + + @text_object("e") + def _end_of_word(event: E) -> TextObject: + """ + End of 'word': 'ce', 'de', 'e' + """ + end = event.current_buffer.document.find_next_word_ending(count=event.arg) + return TextObject(end - 1 if end else 0, type=TextObjectType.INCLUSIVE) + + @text_object("E") + def _end_of_WORD(event: E) -> TextObject: + """ + End of 'WORD': 'cE', 'dE', 'E' + """ + end = event.current_buffer.document.find_next_word_ending( + count=event.arg, WORD=True + ) + return TextObject(end - 1 if end else 0, type=TextObjectType.INCLUSIVE) + + @text_object("i", "w", no_move_handler=True) + def _inner_word(event: E) -> TextObject: + """ + Inner 'word': ciw and diw + """ + start, end = event.current_buffer.document.find_boundaries_of_current_word() + return TextObject(start, end) + + @text_object("a", "w", no_move_handler=True) + def _a_word(event: E) -> TextObject: + """ + A 'word': caw and daw + """ + start, end = event.current_buffer.document.find_boundaries_of_current_word( + include_trailing_whitespace=True + ) + return TextObject(start, end) + + @text_object("i", "W", no_move_handler=True) + def _inner_WORD(event: E) -> TextObject: + """ + Inner 'WORD': ciW and diW + """ + start, end = event.current_buffer.document.find_boundaries_of_current_word( + WORD=True + ) + return TextObject(start, end) + + @text_object("a", "W", no_move_handler=True) + def _a_WORD(event: E) -> TextObject: + """ + A 'WORD': caw and daw + """ + start, end = event.current_buffer.document.find_boundaries_of_current_word( + WORD=True, include_trailing_whitespace=True + ) + return TextObject(start, end) + + @text_object("a", "p", no_move_handler=True) + def _paragraph(event: E) -> TextObject: + """ + Auto paragraph. + """ + start = event.current_buffer.document.start_of_paragraph() + end = event.current_buffer.document.end_of_paragraph(count=event.arg) + return TextObject(start, end) + + @text_object("^") + def _start_of_line(event: E) -> TextObject: + """ 'c^', 'd^' and '^': Soft start of line, after whitespace. """ + return TextObject( + event.current_buffer.document.get_start_of_line_position( + after_whitespace=True + ) + ) + + @text_object("0") + def _hard_start_of_line(event: E) -> TextObject: + """ + 'c0', 'd0': Hard start of line, before whitespace. + (The move '0' key is implemented elsewhere, because a '0' could also change the `arg`.) + """ + return TextObject( + event.current_buffer.document.get_start_of_line_position( + after_whitespace=False + ) + ) + + def create_ci_ca_handles( + ci_start: str, ci_end: str, inner: bool, key: Optional[str] = None + ) -> None: + # TODO: 'dat', 'dit', (tags (like xml) + """ + Delete/Change string between this start and stop character. But keep these characters. + This implements all the ci", ci<, ci{, ci(, di", di<, ca", ca<, ... combinations. + """ + + def handler(event: E) -> TextObject: + if ci_start == ci_end: + # Quotes + start = event.current_buffer.document.find_backwards( + ci_start, in_current_line=False + ) + end = event.current_buffer.document.find(ci_end, in_current_line=False) + else: + # Brackets + start = event.current_buffer.document.find_enclosing_bracket_left( + ci_start, ci_end + ) + end = event.current_buffer.document.find_enclosing_bracket_right( + ci_start, ci_end + ) + + if start is not None and end is not None: + offset = 0 if inner else 1 + return TextObject(start + 1 - offset, end + offset) + else: + # Nothing found. + return TextObject(0) + + if key is None: + text_object("ai"[inner], ci_start, no_move_handler=True)(handler) + text_object("ai"[inner], ci_end, no_move_handler=True)(handler) + else: + text_object("ai"[inner], key, no_move_handler=True)(handler) + + for inner in (False, True): + for ci_start, ci_end in [ + ('"', '"'), + ("'", "'"), + ("`", "`"), + ("[", "]"), + ("<", ">"), + ("{", "}"), + ("(", ")"), + ]: + create_ci_ca_handles(ci_start, ci_end, inner) + + create_ci_ca_handles("(", ")", inner, "b") # 'dab', 'dib' + create_ci_ca_handles("{", "}", inner, "B") # 'daB', 'diB' + + @text_object("{") + def _previous_section(event: E) -> TextObject: + """ + Move to previous blank-line separated section. + Implements '{', 'c{', 'd{', 'y{' + """ + index = event.current_buffer.document.start_of_paragraph( + count=event.arg, before=True + ) + return TextObject(index) + + @text_object("}") + def _next_section(event: E) -> TextObject: + """ + Move to next blank-line separated section. + Implements '}', 'c}', 'd}', 'y}' + """ + index = event.current_buffer.document.end_of_paragraph( + count=event.arg, after=True + ) + return TextObject(index) + + @text_object("f", Keys.Any) + def _next_occurence(event: E) -> TextObject: + """ + Go to next occurrence of character. Typing 'fx' will move the + cursor to the next occurrence of character. 'x'. + """ + event.app.vi_state.last_character_find = CharacterFind(event.data, False) + match = event.current_buffer.document.find( + event.data, in_current_line=True, count=event.arg + ) + if match: + return TextObject(match, type=TextObjectType.INCLUSIVE) + else: + return TextObject(0) + + @text_object("F", Keys.Any) + def _previous_occurance(event: E) -> TextObject: + """ + Go to previous occurrence of character. Typing 'Fx' will move the + cursor to the previous occurrence of character. 'x'. + """ + event.app.vi_state.last_character_find = CharacterFind(event.data, True) + return TextObject( + event.current_buffer.document.find_backwards( + event.data, in_current_line=True, count=event.arg + ) + or 0 + ) + + @text_object("t", Keys.Any) + def _t(event: E) -> TextObject: + """ + Move right to the next occurrence of c, then one char backward. + """ + event.app.vi_state.last_character_find = CharacterFind(event.data, False) + match = event.current_buffer.document.find( + event.data, in_current_line=True, count=event.arg + ) + if match: + return TextObject(match - 1, type=TextObjectType.INCLUSIVE) + else: + return TextObject(0) + + @text_object("T", Keys.Any) + def _T(event: E) -> TextObject: + """ + Move left to the previous occurrence of c, then one char forward. + """ + event.app.vi_state.last_character_find = CharacterFind(event.data, True) + match = event.current_buffer.document.find_backwards( + event.data, in_current_line=True, count=event.arg + ) + return TextObject(match + 1 if match else 0) + + def repeat(reverse: bool) -> None: + """ + Create ',' and ';' commands. + """ + + @text_object("," if reverse else ";") + def _(event: E) -> TextObject: + """ + Repeat the last 'f'/'F'/'t'/'T' command. + """ + pos: Optional[int] = 0 + vi_state = event.app.vi_state + + type = TextObjectType.EXCLUSIVE + + if vi_state.last_character_find: + char = vi_state.last_character_find.character + backwards = vi_state.last_character_find.backwards + + if reverse: + backwards = not backwards + + if backwards: + pos = event.current_buffer.document.find_backwards( + char, in_current_line=True, count=event.arg + ) + else: + pos = event.current_buffer.document.find( + char, in_current_line=True, count=event.arg + ) + type = TextObjectType.INCLUSIVE + if pos: + return TextObject(pos, type=type) + else: + return TextObject(0) + + repeat(True) + repeat(False) + + @text_object("h") + @text_object("left") + def _left(event: E) -> TextObject: + """ + Implements 'ch', 'dh', 'h': Cursor left. + """ + return TextObject( + event.current_buffer.document.get_cursor_left_position(count=event.arg) + ) + + @text_object("j", no_move_handler=True, no_selection_handler=True) + # Note: We also need `no_selection_handler`, because we in + # selection mode, we prefer the other 'j' binding that keeps + # `buffer.preferred_column`. + def _down(event: E) -> TextObject: + """ + Implements 'cj', 'dj', 'j', ... Cursor up. + """ + return TextObject( + event.current_buffer.document.get_cursor_down_position(count=event.arg), + type=TextObjectType.LINEWISE, + ) + + @text_object("k", no_move_handler=True, no_selection_handler=True) + def _up(event: E) -> TextObject: + """ + Implements 'ck', 'dk', 'k', ... Cursor up. + """ + return TextObject( + event.current_buffer.document.get_cursor_up_position(count=event.arg), + type=TextObjectType.LINEWISE, + ) + + @text_object("l") + @text_object(" ") + @text_object("right") + def _right(event: E) -> TextObject: + """ + Implements 'cl', 'dl', 'l', 'c ', 'd ', ' '. Cursor right. + """ + return TextObject( + event.current_buffer.document.get_cursor_right_position(count=event.arg) + ) + + @text_object("H") + def _top_of_screen(event: E) -> TextObject: + """ + Moves to the start of the visible region. (Below the scroll offset.) + Implements 'cH', 'dH', 'H'. + """ + w = event.app.layout.current_window + b = event.current_buffer + + if w and w.render_info: + # When we find a Window that has BufferControl showing this window, + # move to the start of the visible area. + pos = ( + b.document.translate_row_col_to_index( + w.render_info.first_visible_line(after_scroll_offset=True), 0 + ) + - b.cursor_position + ) + + else: + # Otherwise, move to the start of the input. + pos = -len(b.document.text_before_cursor) + return TextObject(pos, type=TextObjectType.LINEWISE) + + @text_object("M") + def _middle_of_screen(event: E) -> TextObject: + """ + Moves cursor to the vertical center of the visible region. + Implements 'cM', 'dM', 'M'. + """ + w = event.app.layout.current_window + b = event.current_buffer + + if w and w.render_info: + # When we find a Window that has BufferControl showing this window, + # move to the center of the visible area. + pos = ( + b.document.translate_row_col_to_index( + w.render_info.center_visible_line(), 0 + ) + - b.cursor_position + ) + + else: + # Otherwise, move to the start of the input. + pos = -len(b.document.text_before_cursor) + return TextObject(pos, type=TextObjectType.LINEWISE) + + @text_object("L") + def _end_of_screen(event: E) -> TextObject: + """ + Moves to the end of the visible region. (Above the scroll offset.) + """ + w = event.app.layout.current_window + b = event.current_buffer + + if w and w.render_info: + # When we find a Window that has BufferControl showing this window, + # move to the end of the visible area. + pos = ( + b.document.translate_row_col_to_index( + w.render_info.last_visible_line(before_scroll_offset=True), 0 + ) + - b.cursor_position + ) + + else: + # Otherwise, move to the end of the input. + pos = len(b.document.text_after_cursor) + return TextObject(pos, type=TextObjectType.LINEWISE) + + @text_object("n", no_move_handler=True) + def _search_next(event: E) -> TextObject: + """ + Search next. + """ + buff = event.current_buffer + search_state = event.app.current_search_state + + cursor_position = buff.get_search_position( + search_state, include_current_position=False, count=event.arg + ) + return TextObject(cursor_position - buff.cursor_position) + + @handle("n", filter=vi_navigation_mode) + def _search_next2(event: E) -> None: + """ + Search next in navigation mode. (This goes through the history.) + """ + search_state = event.app.current_search_state + + event.current_buffer.apply_search( + search_state, include_current_position=False, count=event.arg + ) + + @text_object("N", no_move_handler=True) + def _search_previous(event: E) -> TextObject: + """ + Search previous. + """ + buff = event.current_buffer + search_state = event.app.current_search_state + + cursor_position = buff.get_search_position( + ~search_state, include_current_position=False, count=event.arg + ) + return TextObject(cursor_position - buff.cursor_position) + + @handle("N", filter=vi_navigation_mode) + def _search_previous2(event: E) -> None: + """ + Search previous in navigation mode. (This goes through the history.) + """ + search_state = event.app.current_search_state + + event.current_buffer.apply_search( + ~search_state, include_current_position=False, count=event.arg + ) + + @handle("z", "+", filter=vi_navigation_mode | vi_selection_mode) + @handle("z", "t", filter=vi_navigation_mode | vi_selection_mode) + @handle("z", "enter", filter=vi_navigation_mode | vi_selection_mode) + def _scroll_top(event: E) -> None: + """ + Scrolls the window to makes the current line the first line in the visible region. + """ + b = event.current_buffer + event.app.layout.current_window.vertical_scroll = b.document.cursor_position_row + + @handle("z", "-", filter=vi_navigation_mode | vi_selection_mode) + @handle("z", "b", filter=vi_navigation_mode | vi_selection_mode) + def _scroll_bottom(event: E) -> None: + """ + Scrolls the window to makes the current line the last line in the visible region. + """ + # We can safely set the scroll offset to zero; the Window will make + # sure that it scrolls at least enough to make the cursor visible + # again. + event.app.layout.current_window.vertical_scroll = 0 + + @handle("z", "z", filter=vi_navigation_mode | vi_selection_mode) + def _scroll_center(event: E) -> None: + """ + Center Window vertically around cursor. + """ + w = event.app.layout.current_window + b = event.current_buffer + + if w and w.render_info: + info = w.render_info + + # Calculate the offset that we need in order to position the row + # containing the cursor in the center. + scroll_height = info.window_height // 2 + + y = max(0, b.document.cursor_position_row - 1) + height = 0 + while y > 0: + line_height = info.get_height_for_line(y) + + if height + line_height < scroll_height: + height += line_height + y -= 1 + else: + break + + w.vertical_scroll = y + + @text_object("%") + def _goto_corresponding_bracket(event: E) -> TextObject: + """ + Implements 'c%', 'd%', '%, 'y%' (Move to corresponding bracket.) + If an 'arg' has been given, go this this % position in the file. + """ + buffer = event.current_buffer + + if event._arg: + # If 'arg' has been given, the meaning of % is to go to the 'x%' + # row in the file. + if 0 < event.arg <= 100: + absolute_index = buffer.document.translate_row_col_to_index( + int((event.arg * buffer.document.line_count - 1) / 100), 0 + ) + return TextObject( + absolute_index - buffer.document.cursor_position, + type=TextObjectType.LINEWISE, + ) + else: + return TextObject(0) # Do nothing. + + else: + # Move to the corresponding opening/closing bracket (()'s, []'s and {}'s). + match = buffer.document.find_matching_bracket_position() + if match: + return TextObject(match, type=TextObjectType.INCLUSIVE) + else: + return TextObject(0) + + @text_object("|") + def _to_column(event: E) -> TextObject: + """ + Move to the n-th column (you may specify the argument n by typing it on + number keys, for example, 20|). + """ + return TextObject( + event.current_buffer.document.get_column_cursor_position(event.arg - 1) + ) + + @text_object("g", "g") + def _goto_first_line(event: E) -> TextObject: + """ + Go to the start of the very first line. + Implements 'gg', 'cgg', 'ygg' + """ + d = event.current_buffer.document + + if event._arg: + # Move to the given line. + return TextObject( + d.translate_row_col_to_index(event.arg - 1, 0) - d.cursor_position, + type=TextObjectType.LINEWISE, + ) + else: + # Move to the top of the input. + return TextObject( + d.get_start_of_document_position(), type=TextObjectType.LINEWISE + ) + + @text_object("g", "_") + def _goto_last_line(event: E) -> TextObject: + """ + Go to last non-blank of line. + 'g_', 'cg_', 'yg_', etc.. + """ + return TextObject( + event.current_buffer.document.last_non_blank_of_current_line_position(), + type=TextObjectType.INCLUSIVE, + ) + + @text_object("g", "e") + def _ge(event: E) -> TextObject: + """ + Go to last character of previous word. + 'ge', 'cge', 'yge', etc.. + """ + prev_end = event.current_buffer.document.find_previous_word_ending( + count=event.arg + ) + return TextObject( + prev_end - 1 if prev_end is not None else 0, type=TextObjectType.INCLUSIVE + ) + + @text_object("g", "E") + def _gE(event: E) -> TextObject: + """ + Go to last character of previous WORD. + 'gE', 'cgE', 'ygE', etc.. + """ + prev_end = event.current_buffer.document.find_previous_word_ending( + count=event.arg, WORD=True + ) + return TextObject( + prev_end - 1 if prev_end is not None else 0, type=TextObjectType.INCLUSIVE + ) + + @text_object("g", "m") + def _gm(event: E) -> TextObject: + """ + Like g0, but half a screenwidth to the right. (Or as much as possible.) + """ + w = event.app.layout.current_window + buff = event.current_buffer + + if w and w.render_info: + width = w.render_info.window_width + start = buff.document.get_start_of_line_position(after_whitespace=False) + start += int(min(width / 2, len(buff.document.current_line))) + + return TextObject(start, type=TextObjectType.INCLUSIVE) + return TextObject(0) + + @text_object("G") + def _last_line(event: E) -> TextObject: + """ + Go to the end of the document. (If no arg has been given.) + """ + buf = event.current_buffer + return TextObject( + buf.document.translate_row_col_to_index(buf.document.line_count - 1, 0) + - buf.cursor_position, + type=TextObjectType.LINEWISE, + ) + + # + # *** Other *** + # + + @handle("G", filter=has_arg) + def _to_nth_history_line(event: E) -> None: + """ + If an argument is given, move to this line in the history. (for + example, 15G) + """ + event.current_buffer.go_to_history(event.arg - 1) + + for n in "123456789": + + @handle( + n, + filter=vi_navigation_mode + | vi_selection_mode + | vi_waiting_for_text_object_mode, + ) + def _arg(event: E) -> None: + """ + Always handle numberics in navigation mode as arg. + """ + event.append_to_arg_count(event.data) + + @handle( + "0", + filter=( + vi_navigation_mode | vi_selection_mode | vi_waiting_for_text_object_mode + ) + & has_arg, + ) + def _0_arg(event: E) -> None: + """ + Zero when an argument was already give. + """ + event.append_to_arg_count(event.data) + + @handle(Keys.Any, filter=vi_replace_mode) + def _insert_text(event: E) -> None: + """ + Insert data at cursor position. + """ + event.current_buffer.insert_text(event.data, overwrite=True) + + @handle(Keys.Any, filter=vi_replace_single_mode) + def _replace_single(event: E) -> None: + """ + Replace single character at cursor position. + """ + event.current_buffer.insert_text(event.data, overwrite=True) + event.current_buffer.cursor_position -= 1 + event.app.vi_state.input_mode = InputMode.NAVIGATION + + @handle( + Keys.Any, + filter=vi_insert_multiple_mode, + save_before=(lambda e: not e.is_repeat), + ) + def _insert_text_multiple_cursors(event: E) -> None: + """ + Insert data at multiple cursor positions at once. + (Usually a result of pressing 'I' or 'A' in block-selection mode.) + """ + buff = event.current_buffer + original_text = buff.text + + # Construct new text. + text = [] + p = 0 + + for p2 in buff.multiple_cursor_positions: + text.append(original_text[p:p2]) + text.append(event.data) + p = p2 + + text.append(original_text[p:]) + + # Shift all cursor positions. + new_cursor_positions = [ + pos + i + 1 for i, pos in enumerate(buff.multiple_cursor_positions) + ] + + # Set result. + buff.text = "".join(text) + buff.multiple_cursor_positions = new_cursor_positions + buff.cursor_position += 1 + + @handle("backspace", filter=vi_insert_multiple_mode) + def _delete_before_multiple_cursors(event: E) -> None: + """ + Backspace, using multiple cursors. + """ + buff = event.current_buffer + original_text = buff.text + + # Construct new text. + deleted_something = False + text = [] + p = 0 + + for p2 in buff.multiple_cursor_positions: + if p2 > 0 and original_text[p2 - 1] != "\n": # Don't delete across lines. + text.append(original_text[p : p2 - 1]) + deleted_something = True + else: + text.append(original_text[p:p2]) + p = p2 + + text.append(original_text[p:]) + + if deleted_something: + # Shift all cursor positions. + lengths = [len(part) for part in text[:-1]] + new_cursor_positions = list(accumulate(lengths)) + + # Set result. + buff.text = "".join(text) + buff.multiple_cursor_positions = new_cursor_positions + buff.cursor_position -= 1 + else: + event.app.output.bell() + + @handle("delete", filter=vi_insert_multiple_mode) + def _delete_after_multiple_cursors(event): + """ + Delete, using multiple cursors. + """ + buff = event.current_buffer + original_text = buff.text + + # Construct new text. + deleted_something = False + text = [] + new_cursor_positions = [] + p = 0 + + for p2 in buff.multiple_cursor_positions: + text.append(original_text[p:p2]) + if p2 >= len(original_text) or original_text[p2] == "\n": + # Don't delete across lines. + p = p2 + else: + p = p2 + 1 + deleted_something = True + + text.append(original_text[p:]) + + if deleted_something: + # Shift all cursor positions. + lengths = [len(part) for part in text[:-1]] + new_cursor_positions = list(accumulate(lengths)) + + # Set result. + buff.text = "".join(text) + buff.multiple_cursor_positions = new_cursor_positions + else: + event.app.output.bell() + + @handle("left", filter=vi_insert_multiple_mode) + def _left_multiple(event: E) -> None: + """ + Move all cursors to the left. + (But keep all cursors on the same line.) + """ + buff = event.current_buffer + new_positions = [] + + for p in buff.multiple_cursor_positions: + if buff.document.translate_index_to_position(p)[1] > 0: + p -= 1 + new_positions.append(p) + + buff.multiple_cursor_positions = new_positions + + if buff.document.cursor_position_col > 0: + buff.cursor_position -= 1 + + @handle("right", filter=vi_insert_multiple_mode) + def _right_multiple(event: E) -> None: + """ + Move all cursors to the right. + (But keep all cursors on the same line.) + """ + buff = event.current_buffer + new_positions = [] + + for p in buff.multiple_cursor_positions: + row, column = buff.document.translate_index_to_position(p) + if column < len(buff.document.lines[row]): + p += 1 + new_positions.append(p) + + buff.multiple_cursor_positions = new_positions + + if not buff.document.is_cursor_at_the_end_of_line: + buff.cursor_position += 1 + + @handle("up", filter=vi_insert_multiple_mode) + @handle("down", filter=vi_insert_multiple_mode) + def _updown_multiple(event: E) -> None: + """ + Ignore all up/down key presses when in multiple cursor mode. + """ + + @handle("c-x", "c-l", filter=vi_insert_mode) + def _complete_line(event: E) -> None: + """ + Pressing the ControlX - ControlL sequence in Vi mode does line + completion based on the other lines in the document and the history. + """ + event.current_buffer.start_history_lines_completion() + + @handle("c-x", "c-f", filter=vi_insert_mode) + def _complete_filename(event: E) -> None: + """ + Complete file names. + """ + # TODO + pass + + @handle("c-k", filter=vi_insert_mode | vi_replace_mode) + def _digraph(event: E) -> None: + """ + Go into digraph mode. + """ + event.app.vi_state.waiting_for_digraph = True + + @Condition + def digraph_symbol_1_given() -> bool: + return get_app().vi_state.digraph_symbol1 is not None + + @handle(Keys.Any, filter=vi_digraph_mode & ~digraph_symbol_1_given) + def _digraph1(event: E) -> None: + """ + First digraph symbol. + """ + event.app.vi_state.digraph_symbol1 = event.data + + @handle(Keys.Any, filter=vi_digraph_mode & digraph_symbol_1_given) + def _create_digraph(event: E) -> None: + """ + Insert digraph. + """ + try: + # Lookup. + code: Tuple[str, str] = ( + event.app.vi_state.digraph_symbol1 or "", + event.data, + ) + if code not in DIGRAPHS: + code = code[::-1] # Try reversing. + symbol = DIGRAPHS[code] + except KeyError: + # Unknown digraph. + event.app.output.bell() + else: + # Insert digraph. + overwrite = event.app.vi_state.input_mode == InputMode.REPLACE + event.current_buffer.insert_text(chr(symbol), overwrite=overwrite) + event.app.vi_state.waiting_for_digraph = False + finally: + event.app.vi_state.waiting_for_digraph = False + event.app.vi_state.digraph_symbol1 = None + + @handle("c-o", filter=vi_insert_mode | vi_replace_mode) + def _quick_normal_mode(event: E) -> None: + """ + Go into normal mode for one single action. + """ + event.app.vi_state.temporary_navigation_mode = True + + @handle("q", Keys.Any, filter=vi_navigation_mode & ~vi_recording_macro) + def _start_macro(event: E) -> None: + """ + Start recording macro. + """ + c = event.key_sequence[1].data + if c in vi_register_names: + vi_state = event.app.vi_state + + vi_state.recording_register = c + vi_state.current_recording = "" + + @handle("q", filter=vi_navigation_mode & vi_recording_macro) + def _stop_macro(event: E) -> None: + """ + Stop recording macro. + """ + vi_state = event.app.vi_state + + # Store and stop recording. + if vi_state.recording_register: + vi_state.named_registers[vi_state.recording_register] = ClipboardData( + vi_state.current_recording + ) + vi_state.recording_register = None + vi_state.current_recording = "" + + @handle("@", Keys.Any, filter=vi_navigation_mode, record_in_macro=False) + def _execute_macro(event: E) -> None: + """ + Execute macro. + + Notice that we pass `record_in_macro=False`. This ensures that the `@x` + keys don't appear in the recording itself. This function inserts the + body of the called macro back into the KeyProcessor, so these keys will + be added later on to the macro of their handlers have + `record_in_macro=True`. + """ + # Retrieve macro. + c = event.key_sequence[1].data + try: + macro = event.app.vi_state.named_registers[c] + except KeyError: + return + + # Expand macro (which is a string in the register), in individual keys. + # Use vt100 parser for this. + keys: List[KeyPress] = [] + + parser = Vt100Parser(keys.append) + parser.feed(macro.text) + parser.flush() + + # Now feed keys back to the input processor. + for _ in range(event.arg): + event.app.key_processor.feed_multiple(keys, first=True) + + return ConditionalKeyBindings(key_bindings, vi_mode) + + +def load_vi_search_bindings() -> KeyBindingsBase: + key_bindings = KeyBindings() + handle = key_bindings.add + from . import search + + @Condition + def search_buffer_is_empty() -> bool: + " Returns True when the search buffer is empty. " + return get_app().current_buffer.text == "" + + # Vi-style forward search. + handle( + "/", + filter=(vi_navigation_mode | vi_selection_mode) & ~vi_search_direction_reversed, + )(search.start_forward_incremental_search) + handle( + "?", + filter=(vi_navigation_mode | vi_selection_mode) & vi_search_direction_reversed, + )(search.start_forward_incremental_search) + handle("c-s")(search.start_forward_incremental_search) + + # Vi-style backward search. + handle( + "?", + filter=(vi_navigation_mode | vi_selection_mode) & ~vi_search_direction_reversed, + )(search.start_reverse_incremental_search) + handle( + "/", + filter=(vi_navigation_mode | vi_selection_mode) & vi_search_direction_reversed, + )(search.start_reverse_incremental_search) + handle("c-r")(search.start_reverse_incremental_search) + + # Apply the search. (At the / or ? prompt.) + handle("enter", filter=is_searching)(search.accept_search) + + handle("c-r", filter=is_searching)(search.reverse_incremental_search) + handle("c-s", filter=is_searching)(search.forward_incremental_search) + + handle("c-c")(search.abort_search) + handle("c-g")(search.abort_search) + handle("backspace", filter=search_buffer_is_empty)(search.abort_search) + + # Handle escape. This should accept the search, just like readline. + # `abort_search` would be a meaningful alternative. + handle("escape")(search.accept_search) + + return ConditionalKeyBindings(key_bindings, vi_mode) diff --git a/.venv/lib/python3.8/site-packages/prompt_toolkit/key_binding/defaults.py b/.venv/lib/python3.8/site-packages/prompt_toolkit/key_binding/defaults.py new file mode 100644 index 00000000..baa59743 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/prompt_toolkit/key_binding/defaults.py @@ -0,0 +1,60 @@ +""" +Default key bindings.:: + + key_bindings = load_key_bindings() + app = Application(key_bindings=key_bindings) +""" +from prompt_toolkit.filters import buffer_has_focus +from prompt_toolkit.key_binding.bindings.basic import load_basic_bindings +from prompt_toolkit.key_binding.bindings.cpr import load_cpr_bindings +from prompt_toolkit.key_binding.bindings.emacs import ( + load_emacs_bindings, + load_emacs_search_bindings, + load_emacs_shift_selection_bindings, +) +from prompt_toolkit.key_binding.bindings.mouse import load_mouse_bindings +from prompt_toolkit.key_binding.bindings.vi import ( + load_vi_bindings, + load_vi_search_bindings, +) +from prompt_toolkit.key_binding.key_bindings import ( + ConditionalKeyBindings, + KeyBindingsBase, + merge_key_bindings, +) + +__all__ = [ + "load_key_bindings", +] + + +def load_key_bindings() -> KeyBindingsBase: + """ + Create a KeyBindings object that contains the default key bindings. + """ + all_bindings = merge_key_bindings( + [ + # Load basic bindings. + load_basic_bindings(), + # Load emacs bindings. + load_emacs_bindings(), + load_emacs_search_bindings(), + load_emacs_shift_selection_bindings(), + # Load Vi bindings. + load_vi_bindings(), + load_vi_search_bindings(), + ] + ) + + return merge_key_bindings( + [ + # Make sure that the above key bindings are only active if the + # currently focused control is a `BufferControl`. For other controls, we + # don't want these key bindings to intervene. (This would break "ptterm" + # for instance, which handles 'Keys.Any' in the user control itself.) + ConditionalKeyBindings(all_bindings, buffer_has_focus), + # Active, even when no buffer has been focused. + load_mouse_bindings(), + load_cpr_bindings(), + ] + ) diff --git a/.venv/lib/python3.8/site-packages/prompt_toolkit/key_binding/digraphs.py b/.venv/lib/python3.8/site-packages/prompt_toolkit/key_binding/digraphs.py new file mode 100644 index 00000000..70606086 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/prompt_toolkit/key_binding/digraphs.py @@ -0,0 +1,1378 @@ +# encoding: utf-8 +""" +Vi Digraphs. +This is a list of special characters that can be inserted in Vi insert mode by +pressing Control-K followed by to normal characters. + +Taken from Neovim and translated to Python: +https://raw.githubusercontent.com/neovim/neovim/master/src/nvim/digraph.c +""" +from typing import Dict, Tuple + +__all__ = [ + "DIGRAPHS", +] + +# digraphs for Unicode from RFC1345 +# (also work for ISO-8859-1 aka latin1) +DIGRAPHS: Dict[Tuple[str, str], int] = { + ("N", "U"): 0x00, + ("S", "H"): 0x01, + ("S", "X"): 0x02, + ("E", "X"): 0x03, + ("E", "T"): 0x04, + ("E", "Q"): 0x05, + ("A", "K"): 0x06, + ("B", "L"): 0x07, + ("B", "S"): 0x08, + ("H", "T"): 0x09, + ("L", "F"): 0x0A, + ("V", "T"): 0x0B, + ("F", "F"): 0x0C, + ("C", "R"): 0x0D, + ("S", "O"): 0x0E, + ("S", "I"): 0x0F, + ("D", "L"): 0x10, + ("D", "1"): 0x11, + ("D", "2"): 0x12, + ("D", "3"): 0x13, + ("D", "4"): 0x14, + ("N", "K"): 0x15, + ("S", "Y"): 0x16, + ("E", "B"): 0x17, + ("C", "N"): 0x18, + ("E", "M"): 0x19, + ("S", "B"): 0x1A, + ("E", "C"): 0x1B, + ("F", "S"): 0x1C, + ("G", "S"): 0x1D, + ("R", "S"): 0x1E, + ("U", "S"): 0x1F, + ("S", "P"): 0x20, + ("N", "b"): 0x23, + ("D", "O"): 0x24, + ("A", "t"): 0x40, + ("<", "("): 0x5B, + ("/", "/"): 0x5C, + (")", ">"): 0x5D, + ("'", ">"): 0x5E, + ("'", "!"): 0x60, + ("(", "!"): 0x7B, + ("!", "!"): 0x7C, + ("!", ")"): 0x7D, + ("'", "?"): 0x7E, + ("D", "T"): 0x7F, + ("P", "A"): 0x80, + ("H", "O"): 0x81, + ("B", "H"): 0x82, + ("N", "H"): 0x83, + ("I", "N"): 0x84, + ("N", "L"): 0x85, + ("S", "A"): 0x86, + ("E", "S"): 0x87, + ("H", "S"): 0x88, + ("H", "J"): 0x89, + ("V", "S"): 0x8A, + ("P", "D"): 0x8B, + ("P", "U"): 0x8C, + ("R", "I"): 0x8D, + ("S", "2"): 0x8E, + ("S", "3"): 0x8F, + ("D", "C"): 0x90, + ("P", "1"): 0x91, + ("P", "2"): 0x92, + ("T", "S"): 0x93, + ("C", "C"): 0x94, + ("M", "W"): 0x95, + ("S", "G"): 0x96, + ("E", "G"): 0x97, + ("S", "S"): 0x98, + ("G", "C"): 0x99, + ("S", "C"): 0x9A, + ("C", "I"): 0x9B, + ("S", "T"): 0x9C, + ("O", "C"): 0x9D, + ("P", "M"): 0x9E, + ("A", "C"): 0x9F, + ("N", "S"): 0xA0, + ("!", "I"): 0xA1, + ("C", "t"): 0xA2, + ("P", "d"): 0xA3, + ("C", "u"): 0xA4, + ("Y", "e"): 0xA5, + ("B", "B"): 0xA6, + ("S", "E"): 0xA7, + ("'", ":"): 0xA8, + ("C", "o"): 0xA9, + ("-", "a"): 0xAA, + ("<", "<"): 0xAB, + ("N", "O"): 0xAC, + ("-", "-"): 0xAD, + ("R", "g"): 0xAE, + ("'", "m"): 0xAF, + ("D", "G"): 0xB0, + ("+", "-"): 0xB1, + ("2", "S"): 0xB2, + ("3", "S"): 0xB3, + ("'", "'"): 0xB4, + ("M", "y"): 0xB5, + ("P", "I"): 0xB6, + (".", "M"): 0xB7, + ("'", ","): 0xB8, + ("1", "S"): 0xB9, + ("-", "o"): 0xBA, + (">", ">"): 0xBB, + ("1", "4"): 0xBC, + ("1", "2"): 0xBD, + ("3", "4"): 0xBE, + ("?", "I"): 0xBF, + ("A", "!"): 0xC0, + ("A", "'"): 0xC1, + ("A", ">"): 0xC2, + ("A", "?"): 0xC3, + ("A", ":"): 0xC4, + ("A", "A"): 0xC5, + ("A", "E"): 0xC6, + ("C", ","): 0xC7, + ("E", "!"): 0xC8, + ("E", "'"): 0xC9, + ("E", ">"): 0xCA, + ("E", ":"): 0xCB, + ("I", "!"): 0xCC, + ("I", "'"): 0xCD, + ("I", ">"): 0xCE, + ("I", ":"): 0xCF, + ("D", "-"): 0xD0, + ("N", "?"): 0xD1, + ("O", "!"): 0xD2, + ("O", "'"): 0xD3, + ("O", ">"): 0xD4, + ("O", "?"): 0xD5, + ("O", ":"): 0xD6, + ("*", "X"): 0xD7, + ("O", "/"): 0xD8, + ("U", "!"): 0xD9, + ("U", "'"): 0xDA, + ("U", ">"): 0xDB, + ("U", ":"): 0xDC, + ("Y", "'"): 0xDD, + ("T", "H"): 0xDE, + ("s", "s"): 0xDF, + ("a", "!"): 0xE0, + ("a", "'"): 0xE1, + ("a", ">"): 0xE2, + ("a", "?"): 0xE3, + ("a", ":"): 0xE4, + ("a", "a"): 0xE5, + ("a", "e"): 0xE6, + ("c", ","): 0xE7, + ("e", "!"): 0xE8, + ("e", "'"): 0xE9, + ("e", ">"): 0xEA, + ("e", ":"): 0xEB, + ("i", "!"): 0xEC, + ("i", "'"): 0xED, + ("i", ">"): 0xEE, + ("i", ":"): 0xEF, + ("d", "-"): 0xF0, + ("n", "?"): 0xF1, + ("o", "!"): 0xF2, + ("o", "'"): 0xF3, + ("o", ">"): 0xF4, + ("o", "?"): 0xF5, + ("o", ":"): 0xF6, + ("-", ":"): 0xF7, + ("o", "/"): 0xF8, + ("u", "!"): 0xF9, + ("u", "'"): 0xFA, + ("u", ">"): 0xFB, + ("u", ":"): 0xFC, + ("y", "'"): 0xFD, + ("t", "h"): 0xFE, + ("y", ":"): 0xFF, + ("A", "-"): 0x0100, + ("a", "-"): 0x0101, + ("A", "("): 0x0102, + ("a", "("): 0x0103, + ("A", ";"): 0x0104, + ("a", ";"): 0x0105, + ("C", "'"): 0x0106, + ("c", "'"): 0x0107, + ("C", ">"): 0x0108, + ("c", ">"): 0x0109, + ("C", "."): 0x010A, + ("c", "."): 0x010B, + ("C", "<"): 0x010C, + ("c", "<"): 0x010D, + ("D", "<"): 0x010E, + ("d", "<"): 0x010F, + ("D", "/"): 0x0110, + ("d", "/"): 0x0111, + ("E", "-"): 0x0112, + ("e", "-"): 0x0113, + ("E", "("): 0x0114, + ("e", "("): 0x0115, + ("E", "."): 0x0116, + ("e", "."): 0x0117, + ("E", ";"): 0x0118, + ("e", ";"): 0x0119, + ("E", "<"): 0x011A, + ("e", "<"): 0x011B, + ("G", ">"): 0x011C, + ("g", ">"): 0x011D, + ("G", "("): 0x011E, + ("g", "("): 0x011F, + ("G", "."): 0x0120, + ("g", "."): 0x0121, + ("G", ","): 0x0122, + ("g", ","): 0x0123, + ("H", ">"): 0x0124, + ("h", ">"): 0x0125, + ("H", "/"): 0x0126, + ("h", "/"): 0x0127, + ("I", "?"): 0x0128, + ("i", "?"): 0x0129, + ("I", "-"): 0x012A, + ("i", "-"): 0x012B, + ("I", "("): 0x012C, + ("i", "("): 0x012D, + ("I", ";"): 0x012E, + ("i", ";"): 0x012F, + ("I", "."): 0x0130, + ("i", "."): 0x0131, + ("I", "J"): 0x0132, + ("i", "j"): 0x0133, + ("J", ">"): 0x0134, + ("j", ">"): 0x0135, + ("K", ","): 0x0136, + ("k", ","): 0x0137, + ("k", "k"): 0x0138, + ("L", "'"): 0x0139, + ("l", "'"): 0x013A, + ("L", ","): 0x013B, + ("l", ","): 0x013C, + ("L", "<"): 0x013D, + ("l", "<"): 0x013E, + ("L", "."): 0x013F, + ("l", "."): 0x0140, + ("L", "/"): 0x0141, + ("l", "/"): 0x0142, + ("N", "'"): 0x0143, + ("n", "'"): 0x0144, + ("N", ","): 0x0145, + ("n", ","): 0x0146, + ("N", "<"): 0x0147, + ("n", "<"): 0x0148, + ("'", "n"): 0x0149, + ("N", "G"): 0x014A, + ("n", "g"): 0x014B, + ("O", "-"): 0x014C, + ("o", "-"): 0x014D, + ("O", "("): 0x014E, + ("o", "("): 0x014F, + ("O", '"'): 0x0150, + ("o", '"'): 0x0151, + ("O", "E"): 0x0152, + ("o", "e"): 0x0153, + ("R", "'"): 0x0154, + ("r", "'"): 0x0155, + ("R", ","): 0x0156, + ("r", ","): 0x0157, + ("R", "<"): 0x0158, + ("r", "<"): 0x0159, + ("S", "'"): 0x015A, + ("s", "'"): 0x015B, + ("S", ">"): 0x015C, + ("s", ">"): 0x015D, + ("S", ","): 0x015E, + ("s", ","): 0x015F, + ("S", "<"): 0x0160, + ("s", "<"): 0x0161, + ("T", ","): 0x0162, + ("t", ","): 0x0163, + ("T", "<"): 0x0164, + ("t", "<"): 0x0165, + ("T", "/"): 0x0166, + ("t", "/"): 0x0167, + ("U", "?"): 0x0168, + ("u", "?"): 0x0169, + ("U", "-"): 0x016A, + ("u", "-"): 0x016B, + ("U", "("): 0x016C, + ("u", "("): 0x016D, + ("U", "0"): 0x016E, + ("u", "0"): 0x016F, + ("U", '"'): 0x0170, + ("u", '"'): 0x0171, + ("U", ";"): 0x0172, + ("u", ";"): 0x0173, + ("W", ">"): 0x0174, + ("w", ">"): 0x0175, + ("Y", ">"): 0x0176, + ("y", ">"): 0x0177, + ("Y", ":"): 0x0178, + ("Z", "'"): 0x0179, + ("z", "'"): 0x017A, + ("Z", "."): 0x017B, + ("z", "."): 0x017C, + ("Z", "<"): 0x017D, + ("z", "<"): 0x017E, + ("O", "9"): 0x01A0, + ("o", "9"): 0x01A1, + ("O", "I"): 0x01A2, + ("o", "i"): 0x01A3, + ("y", "r"): 0x01A6, + ("U", "9"): 0x01AF, + ("u", "9"): 0x01B0, + ("Z", "/"): 0x01B5, + ("z", "/"): 0x01B6, + ("E", "D"): 0x01B7, + ("A", "<"): 0x01CD, + ("a", "<"): 0x01CE, + ("I", "<"): 0x01CF, + ("i", "<"): 0x01D0, + ("O", "<"): 0x01D1, + ("o", "<"): 0x01D2, + ("U", "<"): 0x01D3, + ("u", "<"): 0x01D4, + ("A", "1"): 0x01DE, + ("a", "1"): 0x01DF, + ("A", "7"): 0x01E0, + ("a", "7"): 0x01E1, + ("A", "3"): 0x01E2, + ("a", "3"): 0x01E3, + ("G", "/"): 0x01E4, + ("g", "/"): 0x01E5, + ("G", "<"): 0x01E6, + ("g", "<"): 0x01E7, + ("K", "<"): 0x01E8, + ("k", "<"): 0x01E9, + ("O", ";"): 0x01EA, + ("o", ";"): 0x01EB, + ("O", "1"): 0x01EC, + ("o", "1"): 0x01ED, + ("E", "Z"): 0x01EE, + ("e", "z"): 0x01EF, + ("j", "<"): 0x01F0, + ("G", "'"): 0x01F4, + ("g", "'"): 0x01F5, + (";", "S"): 0x02BF, + ("'", "<"): 0x02C7, + ("'", "("): 0x02D8, + ("'", "."): 0x02D9, + ("'", "0"): 0x02DA, + ("'", ";"): 0x02DB, + ("'", '"'): 0x02DD, + ("A", "%"): 0x0386, + ("E", "%"): 0x0388, + ("Y", "%"): 0x0389, + ("I", "%"): 0x038A, + ("O", "%"): 0x038C, + ("U", "%"): 0x038E, + ("W", "%"): 0x038F, + ("i", "3"): 0x0390, + ("A", "*"): 0x0391, + ("B", "*"): 0x0392, + ("G", "*"): 0x0393, + ("D", "*"): 0x0394, + ("E", "*"): 0x0395, + ("Z", "*"): 0x0396, + ("Y", "*"): 0x0397, + ("H", "*"): 0x0398, + ("I", "*"): 0x0399, + ("K", "*"): 0x039A, + ("L", "*"): 0x039B, + ("M", "*"): 0x039C, + ("N", "*"): 0x039D, + ("C", "*"): 0x039E, + ("O", "*"): 0x039F, + ("P", "*"): 0x03A0, + ("R", "*"): 0x03A1, + ("S", "*"): 0x03A3, + ("T", "*"): 0x03A4, + ("U", "*"): 0x03A5, + ("F", "*"): 0x03A6, + ("X", "*"): 0x03A7, + ("Q", "*"): 0x03A8, + ("W", "*"): 0x03A9, + ("J", "*"): 0x03AA, + ("V", "*"): 0x03AB, + ("a", "%"): 0x03AC, + ("e", "%"): 0x03AD, + ("y", "%"): 0x03AE, + ("i", "%"): 0x03AF, + ("u", "3"): 0x03B0, + ("a", "*"): 0x03B1, + ("b", "*"): 0x03B2, + ("g", "*"): 0x03B3, + ("d", "*"): 0x03B4, + ("e", "*"): 0x03B5, + ("z", "*"): 0x03B6, + ("y", "*"): 0x03B7, + ("h", "*"): 0x03B8, + ("i", "*"): 0x03B9, + ("k", "*"): 0x03BA, + ("l", "*"): 0x03BB, + ("m", "*"): 0x03BC, + ("n", "*"): 0x03BD, + ("c", "*"): 0x03BE, + ("o", "*"): 0x03BF, + ("p", "*"): 0x03C0, + ("r", "*"): 0x03C1, + ("*", "s"): 0x03C2, + ("s", "*"): 0x03C3, + ("t", "*"): 0x03C4, + ("u", "*"): 0x03C5, + ("f", "*"): 0x03C6, + ("x", "*"): 0x03C7, + ("q", "*"): 0x03C8, + ("w", "*"): 0x03C9, + ("j", "*"): 0x03CA, + ("v", "*"): 0x03CB, + ("o", "%"): 0x03CC, + ("u", "%"): 0x03CD, + ("w", "%"): 0x03CE, + ("'", "G"): 0x03D8, + (",", "G"): 0x03D9, + ("T", "3"): 0x03DA, + ("t", "3"): 0x03DB, + ("M", "3"): 0x03DC, + ("m", "3"): 0x03DD, + ("K", "3"): 0x03DE, + ("k", "3"): 0x03DF, + ("P", "3"): 0x03E0, + ("p", "3"): 0x03E1, + ("'", "%"): 0x03F4, + ("j", "3"): 0x03F5, + ("I", "O"): 0x0401, + ("D", "%"): 0x0402, + ("G", "%"): 0x0403, + ("I", "E"): 0x0404, + ("D", "S"): 0x0405, + ("I", "I"): 0x0406, + ("Y", "I"): 0x0407, + ("J", "%"): 0x0408, + ("L", "J"): 0x0409, + ("N", "J"): 0x040A, + ("T", "s"): 0x040B, + ("K", "J"): 0x040C, + ("V", "%"): 0x040E, + ("D", "Z"): 0x040F, + ("A", "="): 0x0410, + ("B", "="): 0x0411, + ("V", "="): 0x0412, + ("G", "="): 0x0413, + ("D", "="): 0x0414, + ("E", "="): 0x0415, + ("Z", "%"): 0x0416, + ("Z", "="): 0x0417, + ("I", "="): 0x0418, + ("J", "="): 0x0419, + ("K", "="): 0x041A, + ("L", "="): 0x041B, + ("M", "="): 0x041C, + ("N", "="): 0x041D, + ("O", "="): 0x041E, + ("P", "="): 0x041F, + ("R", "="): 0x0420, + ("S", "="): 0x0421, + ("T", "="): 0x0422, + ("U", "="): 0x0423, + ("F", "="): 0x0424, + ("H", "="): 0x0425, + ("C", "="): 0x0426, + ("C", "%"): 0x0427, + ("S", "%"): 0x0428, + ("S", "c"): 0x0429, + ("=", '"'): 0x042A, + ("Y", "="): 0x042B, + ("%", '"'): 0x042C, + ("J", "E"): 0x042D, + ("J", "U"): 0x042E, + ("J", "A"): 0x042F, + ("a", "="): 0x0430, + ("b", "="): 0x0431, + ("v", "="): 0x0432, + ("g", "="): 0x0433, + ("d", "="): 0x0434, + ("e", "="): 0x0435, + ("z", "%"): 0x0436, + ("z", "="): 0x0437, + ("i", "="): 0x0438, + ("j", "="): 0x0439, + ("k", "="): 0x043A, + ("l", "="): 0x043B, + ("m", "="): 0x043C, + ("n", "="): 0x043D, + ("o", "="): 0x043E, + ("p", "="): 0x043F, + ("r", "="): 0x0440, + ("s", "="): 0x0441, + ("t", "="): 0x0442, + ("u", "="): 0x0443, + ("f", "="): 0x0444, + ("h", "="): 0x0445, + ("c", "="): 0x0446, + ("c", "%"): 0x0447, + ("s", "%"): 0x0448, + ("s", "c"): 0x0449, + ("=", "'"): 0x044A, + ("y", "="): 0x044B, + ("%", "'"): 0x044C, + ("j", "e"): 0x044D, + ("j", "u"): 0x044E, + ("j", "a"): 0x044F, + ("i", "o"): 0x0451, + ("d", "%"): 0x0452, + ("g", "%"): 0x0453, + ("i", "e"): 0x0454, + ("d", "s"): 0x0455, + ("i", "i"): 0x0456, + ("y", "i"): 0x0457, + ("j", "%"): 0x0458, + ("l", "j"): 0x0459, + ("n", "j"): 0x045A, + ("t", "s"): 0x045B, + ("k", "j"): 0x045C, + ("v", "%"): 0x045E, + ("d", "z"): 0x045F, + ("Y", "3"): 0x0462, + ("y", "3"): 0x0463, + ("O", "3"): 0x046A, + ("o", "3"): 0x046B, + ("F", "3"): 0x0472, + ("f", "3"): 0x0473, + ("V", "3"): 0x0474, + ("v", "3"): 0x0475, + ("C", "3"): 0x0480, + ("c", "3"): 0x0481, + ("G", "3"): 0x0490, + ("g", "3"): 0x0491, + ("A", "+"): 0x05D0, + ("B", "+"): 0x05D1, + ("G", "+"): 0x05D2, + ("D", "+"): 0x05D3, + ("H", "+"): 0x05D4, + ("W", "+"): 0x05D5, + ("Z", "+"): 0x05D6, + ("X", "+"): 0x05D7, + ("T", "j"): 0x05D8, + ("J", "+"): 0x05D9, + ("K", "%"): 0x05DA, + ("K", "+"): 0x05DB, + ("L", "+"): 0x05DC, + ("M", "%"): 0x05DD, + ("M", "+"): 0x05DE, + ("N", "%"): 0x05DF, + ("N", "+"): 0x05E0, + ("S", "+"): 0x05E1, + ("E", "+"): 0x05E2, + ("P", "%"): 0x05E3, + ("P", "+"): 0x05E4, + ("Z", "j"): 0x05E5, + ("Z", "J"): 0x05E6, + ("Q", "+"): 0x05E7, + ("R", "+"): 0x05E8, + ("S", "h"): 0x05E9, + ("T", "+"): 0x05EA, + (",", "+"): 0x060C, + (";", "+"): 0x061B, + ("?", "+"): 0x061F, + ("H", "'"): 0x0621, + ("a", "M"): 0x0622, + ("a", "H"): 0x0623, + ("w", "H"): 0x0624, + ("a", "h"): 0x0625, + ("y", "H"): 0x0626, + ("a", "+"): 0x0627, + ("b", "+"): 0x0628, + ("t", "m"): 0x0629, + ("t", "+"): 0x062A, + ("t", "k"): 0x062B, + ("g", "+"): 0x062C, + ("h", "k"): 0x062D, + ("x", "+"): 0x062E, + ("d", "+"): 0x062F, + ("d", "k"): 0x0630, + ("r", "+"): 0x0631, + ("z", "+"): 0x0632, + ("s", "+"): 0x0633, + ("s", "n"): 0x0634, + ("c", "+"): 0x0635, + ("d", "d"): 0x0636, + ("t", "j"): 0x0637, + ("z", "H"): 0x0638, + ("e", "+"): 0x0639, + ("i", "+"): 0x063A, + ("+", "+"): 0x0640, + ("f", "+"): 0x0641, + ("q", "+"): 0x0642, + ("k", "+"): 0x0643, + ("l", "+"): 0x0644, + ("m", "+"): 0x0645, + ("n", "+"): 0x0646, + ("h", "+"): 0x0647, + ("w", "+"): 0x0648, + ("j", "+"): 0x0649, + ("y", "+"): 0x064A, + (":", "+"): 0x064B, + ('"', "+"): 0x064C, + ("=", "+"): 0x064D, + ("/", "+"): 0x064E, + ("'", "+"): 0x064F, + ("1", "+"): 0x0650, + ("3", "+"): 0x0651, + ("0", "+"): 0x0652, + ("a", "S"): 0x0670, + ("p", "+"): 0x067E, + ("v", "+"): 0x06A4, + ("g", "f"): 0x06AF, + ("0", "a"): 0x06F0, + ("1", "a"): 0x06F1, + ("2", "a"): 0x06F2, + ("3", "a"): 0x06F3, + ("4", "a"): 0x06F4, + ("5", "a"): 0x06F5, + ("6", "a"): 0x06F6, + ("7", "a"): 0x06F7, + ("8", "a"): 0x06F8, + ("9", "a"): 0x06F9, + ("B", "."): 0x1E02, + ("b", "."): 0x1E03, + ("B", "_"): 0x1E06, + ("b", "_"): 0x1E07, + ("D", "."): 0x1E0A, + ("d", "."): 0x1E0B, + ("D", "_"): 0x1E0E, + ("d", "_"): 0x1E0F, + ("D", ","): 0x1E10, + ("d", ","): 0x1E11, + ("F", "."): 0x1E1E, + ("f", "."): 0x1E1F, + ("G", "-"): 0x1E20, + ("g", "-"): 0x1E21, + ("H", "."): 0x1E22, + ("h", "."): 0x1E23, + ("H", ":"): 0x1E26, + ("h", ":"): 0x1E27, + ("H", ","): 0x1E28, + ("h", ","): 0x1E29, + ("K", "'"): 0x1E30, + ("k", "'"): 0x1E31, + ("K", "_"): 0x1E34, + ("k", "_"): 0x1E35, + ("L", "_"): 0x1E3A, + ("l", "_"): 0x1E3B, + ("M", "'"): 0x1E3E, + ("m", "'"): 0x1E3F, + ("M", "."): 0x1E40, + ("m", "."): 0x1E41, + ("N", "."): 0x1E44, + ("n", "."): 0x1E45, + ("N", "_"): 0x1E48, + ("n", "_"): 0x1E49, + ("P", "'"): 0x1E54, + ("p", "'"): 0x1E55, + ("P", "."): 0x1E56, + ("p", "."): 0x1E57, + ("R", "."): 0x1E58, + ("r", "."): 0x1E59, + ("R", "_"): 0x1E5E, + ("r", "_"): 0x1E5F, + ("S", "."): 0x1E60, + ("s", "."): 0x1E61, + ("T", "."): 0x1E6A, + ("t", "."): 0x1E6B, + ("T", "_"): 0x1E6E, + ("t", "_"): 0x1E6F, + ("V", "?"): 0x1E7C, + ("v", "?"): 0x1E7D, + ("W", "!"): 0x1E80, + ("w", "!"): 0x1E81, + ("W", "'"): 0x1E82, + ("w", "'"): 0x1E83, + ("W", ":"): 0x1E84, + ("w", ":"): 0x1E85, + ("W", "."): 0x1E86, + ("w", "."): 0x1E87, + ("X", "."): 0x1E8A, + ("x", "."): 0x1E8B, + ("X", ":"): 0x1E8C, + ("x", ":"): 0x1E8D, + ("Y", "."): 0x1E8E, + ("y", "."): 0x1E8F, + ("Z", ">"): 0x1E90, + ("z", ">"): 0x1E91, + ("Z", "_"): 0x1E94, + ("z", "_"): 0x1E95, + ("h", "_"): 0x1E96, + ("t", ":"): 0x1E97, + ("w", "0"): 0x1E98, + ("y", "0"): 0x1E99, + ("A", "2"): 0x1EA2, + ("a", "2"): 0x1EA3, + ("E", "2"): 0x1EBA, + ("e", "2"): 0x1EBB, + ("E", "?"): 0x1EBC, + ("e", "?"): 0x1EBD, + ("I", "2"): 0x1EC8, + ("i", "2"): 0x1EC9, + ("O", "2"): 0x1ECE, + ("o", "2"): 0x1ECF, + ("U", "2"): 0x1EE6, + ("u", "2"): 0x1EE7, + ("Y", "!"): 0x1EF2, + ("y", "!"): 0x1EF3, + ("Y", "2"): 0x1EF6, + ("y", "2"): 0x1EF7, + ("Y", "?"): 0x1EF8, + ("y", "?"): 0x1EF9, + (";", "'"): 0x1F00, + (",", "'"): 0x1F01, + (";", "!"): 0x1F02, + (",", "!"): 0x1F03, + ("?", ";"): 0x1F04, + ("?", ","): 0x1F05, + ("!", ":"): 0x1F06, + ("?", ":"): 0x1F07, + ("1", "N"): 0x2002, + ("1", "M"): 0x2003, + ("3", "M"): 0x2004, + ("4", "M"): 0x2005, + ("6", "M"): 0x2006, + ("1", "T"): 0x2009, + ("1", "H"): 0x200A, + ("-", "1"): 0x2010, + ("-", "N"): 0x2013, + ("-", "M"): 0x2014, + ("-", "3"): 0x2015, + ("!", "2"): 0x2016, + ("=", "2"): 0x2017, + ("'", "6"): 0x2018, + ("'", "9"): 0x2019, + (".", "9"): 0x201A, + ("9", "'"): 0x201B, + ('"', "6"): 0x201C, + ('"', "9"): 0x201D, + (":", "9"): 0x201E, + ("9", '"'): 0x201F, + ("/", "-"): 0x2020, + ("/", "="): 0x2021, + (".", "."): 0x2025, + ("%", "0"): 0x2030, + ("1", "'"): 0x2032, + ("2", "'"): 0x2033, + ("3", "'"): 0x2034, + ("1", '"'): 0x2035, + ("2", '"'): 0x2036, + ("3", '"'): 0x2037, + ("C", "a"): 0x2038, + ("<", "1"): 0x2039, + (">", "1"): 0x203A, + (":", "X"): 0x203B, + ("'", "-"): 0x203E, + ("/", "f"): 0x2044, + ("0", "S"): 0x2070, + ("4", "S"): 0x2074, + ("5", "S"): 0x2075, + ("6", "S"): 0x2076, + ("7", "S"): 0x2077, + ("8", "S"): 0x2078, + ("9", "S"): 0x2079, + ("+", "S"): 0x207A, + ("-", "S"): 0x207B, + ("=", "S"): 0x207C, + ("(", "S"): 0x207D, + (")", "S"): 0x207E, + ("n", "S"): 0x207F, + ("0", "s"): 0x2080, + ("1", "s"): 0x2081, + ("2", "s"): 0x2082, + ("3", "s"): 0x2083, + ("4", "s"): 0x2084, + ("5", "s"): 0x2085, + ("6", "s"): 0x2086, + ("7", "s"): 0x2087, + ("8", "s"): 0x2088, + ("9", "s"): 0x2089, + ("+", "s"): 0x208A, + ("-", "s"): 0x208B, + ("=", "s"): 0x208C, + ("(", "s"): 0x208D, + (")", "s"): 0x208E, + ("L", "i"): 0x20A4, + ("P", "t"): 0x20A7, + ("W", "="): 0x20A9, + ("=", "e"): 0x20AC, # euro + ("E", "u"): 0x20AC, # euro + ("=", "R"): 0x20BD, # rouble + ("=", "P"): 0x20BD, # rouble + ("o", "C"): 0x2103, + ("c", "o"): 0x2105, + ("o", "F"): 0x2109, + ("N", "0"): 0x2116, + ("P", "O"): 0x2117, + ("R", "x"): 0x211E, + ("S", "M"): 0x2120, + ("T", "M"): 0x2122, + ("O", "m"): 0x2126, + ("A", "O"): 0x212B, + ("1", "3"): 0x2153, + ("2", "3"): 0x2154, + ("1", "5"): 0x2155, + ("2", "5"): 0x2156, + ("3", "5"): 0x2157, + ("4", "5"): 0x2158, + ("1", "6"): 0x2159, + ("5", "6"): 0x215A, + ("1", "8"): 0x215B, + ("3", "8"): 0x215C, + ("5", "8"): 0x215D, + ("7", "8"): 0x215E, + ("1", "R"): 0x2160, + ("2", "R"): 0x2161, + ("3", "R"): 0x2162, + ("4", "R"): 0x2163, + ("5", "R"): 0x2164, + ("6", "R"): 0x2165, + ("7", "R"): 0x2166, + ("8", "R"): 0x2167, + ("9", "R"): 0x2168, + ("a", "R"): 0x2169, + ("b", "R"): 0x216A, + ("c", "R"): 0x216B, + ("1", "r"): 0x2170, + ("2", "r"): 0x2171, + ("3", "r"): 0x2172, + ("4", "r"): 0x2173, + ("5", "r"): 0x2174, + ("6", "r"): 0x2175, + ("7", "r"): 0x2176, + ("8", "r"): 0x2177, + ("9", "r"): 0x2178, + ("a", "r"): 0x2179, + ("b", "r"): 0x217A, + ("c", "r"): 0x217B, + ("<", "-"): 0x2190, + ("-", "!"): 0x2191, + ("-", ">"): 0x2192, + ("-", "v"): 0x2193, + ("<", ">"): 0x2194, + ("U", "D"): 0x2195, + ("<", "="): 0x21D0, + ("=", ">"): 0x21D2, + ("=", "="): 0x21D4, + ("F", "A"): 0x2200, + ("d", "P"): 0x2202, + ("T", "E"): 0x2203, + ("/", "0"): 0x2205, + ("D", "E"): 0x2206, + ("N", "B"): 0x2207, + ("(", "-"): 0x2208, + ("-", ")"): 0x220B, + ("*", "P"): 0x220F, + ("+", "Z"): 0x2211, + ("-", "2"): 0x2212, + ("-", "+"): 0x2213, + ("*", "-"): 0x2217, + ("O", "b"): 0x2218, + ("S", "b"): 0x2219, + ("R", "T"): 0x221A, + ("0", "("): 0x221D, + ("0", "0"): 0x221E, + ("-", "L"): 0x221F, + ("-", "V"): 0x2220, + ("P", "P"): 0x2225, + ("A", "N"): 0x2227, + ("O", "R"): 0x2228, + ("(", "U"): 0x2229, + (")", "U"): 0x222A, + ("I", "n"): 0x222B, + ("D", "I"): 0x222C, + ("I", "o"): 0x222E, + (".", ":"): 0x2234, + (":", "."): 0x2235, + (":", "R"): 0x2236, + (":", ":"): 0x2237, + ("?", "1"): 0x223C, + ("C", "G"): 0x223E, + ("?", "-"): 0x2243, + ("?", "="): 0x2245, + ("?", "2"): 0x2248, + ("=", "?"): 0x224C, + ("H", "I"): 0x2253, + ("!", "="): 0x2260, + ("=", "3"): 0x2261, + ("=", "<"): 0x2264, + (">", "="): 0x2265, + ("<", "*"): 0x226A, + ("*", ">"): 0x226B, + ("!", "<"): 0x226E, + ("!", ">"): 0x226F, + ("(", "C"): 0x2282, + (")", "C"): 0x2283, + ("(", "_"): 0x2286, + (")", "_"): 0x2287, + ("0", "."): 0x2299, + ("0", "2"): 0x229A, + ("-", "T"): 0x22A5, + (".", "P"): 0x22C5, + (":", "3"): 0x22EE, + (".", "3"): 0x22EF, + ("E", "h"): 0x2302, + ("<", "7"): 0x2308, + (">", "7"): 0x2309, + ("7", "<"): 0x230A, + ("7", ">"): 0x230B, + ("N", "I"): 0x2310, + ("(", "A"): 0x2312, + ("T", "R"): 0x2315, + ("I", "u"): 0x2320, + ("I", "l"): 0x2321, + ("<", "/"): 0x2329, + ("/", ">"): 0x232A, + ("V", "s"): 0x2423, + ("1", "h"): 0x2440, + ("3", "h"): 0x2441, + ("2", "h"): 0x2442, + ("4", "h"): 0x2443, + ("1", "j"): 0x2446, + ("2", "j"): 0x2447, + ("3", "j"): 0x2448, + ("4", "j"): 0x2449, + ("1", "."): 0x2488, + ("2", "."): 0x2489, + ("3", "."): 0x248A, + ("4", "."): 0x248B, + ("5", "."): 0x248C, + ("6", "."): 0x248D, + ("7", "."): 0x248E, + ("8", "."): 0x248F, + ("9", "."): 0x2490, + ("h", "h"): 0x2500, + ("H", "H"): 0x2501, + ("v", "v"): 0x2502, + ("V", "V"): 0x2503, + ("3", "-"): 0x2504, + ("3", "_"): 0x2505, + ("3", "!"): 0x2506, + ("3", "/"): 0x2507, + ("4", "-"): 0x2508, + ("4", "_"): 0x2509, + ("4", "!"): 0x250A, + ("4", "/"): 0x250B, + ("d", "r"): 0x250C, + ("d", "R"): 0x250D, + ("D", "r"): 0x250E, + ("D", "R"): 0x250F, + ("d", "l"): 0x2510, + ("d", "L"): 0x2511, + ("D", "l"): 0x2512, + ("L", "D"): 0x2513, + ("u", "r"): 0x2514, + ("u", "R"): 0x2515, + ("U", "r"): 0x2516, + ("U", "R"): 0x2517, + ("u", "l"): 0x2518, + ("u", "L"): 0x2519, + ("U", "l"): 0x251A, + ("U", "L"): 0x251B, + ("v", "r"): 0x251C, + ("v", "R"): 0x251D, + ("V", "r"): 0x2520, + ("V", "R"): 0x2523, + ("v", "l"): 0x2524, + ("v", "L"): 0x2525, + ("V", "l"): 0x2528, + ("V", "L"): 0x252B, + ("d", "h"): 0x252C, + ("d", "H"): 0x252F, + ("D", "h"): 0x2530, + ("D", "H"): 0x2533, + ("u", "h"): 0x2534, + ("u", "H"): 0x2537, + ("U", "h"): 0x2538, + ("U", "H"): 0x253B, + ("v", "h"): 0x253C, + ("v", "H"): 0x253F, + ("V", "h"): 0x2542, + ("V", "H"): 0x254B, + ("F", "D"): 0x2571, + ("B", "D"): 0x2572, + ("T", "B"): 0x2580, + ("L", "B"): 0x2584, + ("F", "B"): 0x2588, + ("l", "B"): 0x258C, + ("R", "B"): 0x2590, + (".", "S"): 0x2591, + (":", "S"): 0x2592, + ("?", "S"): 0x2593, + ("f", "S"): 0x25A0, + ("O", "S"): 0x25A1, + ("R", "O"): 0x25A2, + ("R", "r"): 0x25A3, + ("R", "F"): 0x25A4, + ("R", "Y"): 0x25A5, + ("R", "H"): 0x25A6, + ("R", "Z"): 0x25A7, + ("R", "K"): 0x25A8, + ("R", "X"): 0x25A9, + ("s", "B"): 0x25AA, + ("S", "R"): 0x25AC, + ("O", "r"): 0x25AD, + ("U", "T"): 0x25B2, + ("u", "T"): 0x25B3, + ("P", "R"): 0x25B6, + ("T", "r"): 0x25B7, + ("D", "t"): 0x25BC, + ("d", "T"): 0x25BD, + ("P", "L"): 0x25C0, + ("T", "l"): 0x25C1, + ("D", "b"): 0x25C6, + ("D", "w"): 0x25C7, + ("L", "Z"): 0x25CA, + ("0", "m"): 0x25CB, + ("0", "o"): 0x25CE, + ("0", "M"): 0x25CF, + ("0", "L"): 0x25D0, + ("0", "R"): 0x25D1, + ("S", "n"): 0x25D8, + ("I", "c"): 0x25D9, + ("F", "d"): 0x25E2, + ("B", "d"): 0x25E3, + ("*", "2"): 0x2605, + ("*", "1"): 0x2606, + ("<", "H"): 0x261C, + (">", "H"): 0x261E, + ("0", "u"): 0x263A, + ("0", "U"): 0x263B, + ("S", "U"): 0x263C, + ("F", "m"): 0x2640, + ("M", "l"): 0x2642, + ("c", "S"): 0x2660, + ("c", "H"): 0x2661, + ("c", "D"): 0x2662, + ("c", "C"): 0x2663, + ("M", "d"): 0x2669, + ("M", "8"): 0x266A, + ("M", "2"): 0x266B, + ("M", "b"): 0x266D, + ("M", "x"): 0x266E, + ("M", "X"): 0x266F, + ("O", "K"): 0x2713, + ("X", "X"): 0x2717, + ("-", "X"): 0x2720, + ("I", "S"): 0x3000, + (",", "_"): 0x3001, + (".", "_"): 0x3002, + ("+", '"'): 0x3003, + ("+", "_"): 0x3004, + ("*", "_"): 0x3005, + (";", "_"): 0x3006, + ("0", "_"): 0x3007, + ("<", "+"): 0x300A, + (">", "+"): 0x300B, + ("<", "'"): 0x300C, + (">", "'"): 0x300D, + ("<", '"'): 0x300E, + (">", '"'): 0x300F, + ("(", '"'): 0x3010, + (")", '"'): 0x3011, + ("=", "T"): 0x3012, + ("=", "_"): 0x3013, + ("(", "'"): 0x3014, + (")", "'"): 0x3015, + ("(", "I"): 0x3016, + (")", "I"): 0x3017, + ("-", "?"): 0x301C, + ("A", "5"): 0x3041, + ("a", "5"): 0x3042, + ("I", "5"): 0x3043, + ("i", "5"): 0x3044, + ("U", "5"): 0x3045, + ("u", "5"): 0x3046, + ("E", "5"): 0x3047, + ("e", "5"): 0x3048, + ("O", "5"): 0x3049, + ("o", "5"): 0x304A, + ("k", "a"): 0x304B, + ("g", "a"): 0x304C, + ("k", "i"): 0x304D, + ("g", "i"): 0x304E, + ("k", "u"): 0x304F, + ("g", "u"): 0x3050, + ("k", "e"): 0x3051, + ("g", "e"): 0x3052, + ("k", "o"): 0x3053, + ("g", "o"): 0x3054, + ("s", "a"): 0x3055, + ("z", "a"): 0x3056, + ("s", "i"): 0x3057, + ("z", "i"): 0x3058, + ("s", "u"): 0x3059, + ("z", "u"): 0x305A, + ("s", "e"): 0x305B, + ("z", "e"): 0x305C, + ("s", "o"): 0x305D, + ("z", "o"): 0x305E, + ("t", "a"): 0x305F, + ("d", "a"): 0x3060, + ("t", "i"): 0x3061, + ("d", "i"): 0x3062, + ("t", "U"): 0x3063, + ("t", "u"): 0x3064, + ("d", "u"): 0x3065, + ("t", "e"): 0x3066, + ("d", "e"): 0x3067, + ("t", "o"): 0x3068, + ("d", "o"): 0x3069, + ("n", "a"): 0x306A, + ("n", "i"): 0x306B, + ("n", "u"): 0x306C, + ("n", "e"): 0x306D, + ("n", "o"): 0x306E, + ("h", "a"): 0x306F, + ("b", "a"): 0x3070, + ("p", "a"): 0x3071, + ("h", "i"): 0x3072, + ("b", "i"): 0x3073, + ("p", "i"): 0x3074, + ("h", "u"): 0x3075, + ("b", "u"): 0x3076, + ("p", "u"): 0x3077, + ("h", "e"): 0x3078, + ("b", "e"): 0x3079, + ("p", "e"): 0x307A, + ("h", "o"): 0x307B, + ("b", "o"): 0x307C, + ("p", "o"): 0x307D, + ("m", "a"): 0x307E, + ("m", "i"): 0x307F, + ("m", "u"): 0x3080, + ("m", "e"): 0x3081, + ("m", "o"): 0x3082, + ("y", "A"): 0x3083, + ("y", "a"): 0x3084, + ("y", "U"): 0x3085, + ("y", "u"): 0x3086, + ("y", "O"): 0x3087, + ("y", "o"): 0x3088, + ("r", "a"): 0x3089, + ("r", "i"): 0x308A, + ("r", "u"): 0x308B, + ("r", "e"): 0x308C, + ("r", "o"): 0x308D, + ("w", "A"): 0x308E, + ("w", "a"): 0x308F, + ("w", "i"): 0x3090, + ("w", "e"): 0x3091, + ("w", "o"): 0x3092, + ("n", "5"): 0x3093, + ("v", "u"): 0x3094, + ('"', "5"): 0x309B, + ("0", "5"): 0x309C, + ("*", "5"): 0x309D, + ("+", "5"): 0x309E, + ("a", "6"): 0x30A1, + ("A", "6"): 0x30A2, + ("i", "6"): 0x30A3, + ("I", "6"): 0x30A4, + ("u", "6"): 0x30A5, + ("U", "6"): 0x30A6, + ("e", "6"): 0x30A7, + ("E", "6"): 0x30A8, + ("o", "6"): 0x30A9, + ("O", "6"): 0x30AA, + ("K", "a"): 0x30AB, + ("G", "a"): 0x30AC, + ("K", "i"): 0x30AD, + ("G", "i"): 0x30AE, + ("K", "u"): 0x30AF, + ("G", "u"): 0x30B0, + ("K", "e"): 0x30B1, + ("G", "e"): 0x30B2, + ("K", "o"): 0x30B3, + ("G", "o"): 0x30B4, + ("S", "a"): 0x30B5, + ("Z", "a"): 0x30B6, + ("S", "i"): 0x30B7, + ("Z", "i"): 0x30B8, + ("S", "u"): 0x30B9, + ("Z", "u"): 0x30BA, + ("S", "e"): 0x30BB, + ("Z", "e"): 0x30BC, + ("S", "o"): 0x30BD, + ("Z", "o"): 0x30BE, + ("T", "a"): 0x30BF, + ("D", "a"): 0x30C0, + ("T", "i"): 0x30C1, + ("D", "i"): 0x30C2, + ("T", "U"): 0x30C3, + ("T", "u"): 0x30C4, + ("D", "u"): 0x30C5, + ("T", "e"): 0x30C6, + ("D", "e"): 0x30C7, + ("T", "o"): 0x30C8, + ("D", "o"): 0x30C9, + ("N", "a"): 0x30CA, + ("N", "i"): 0x30CB, + ("N", "u"): 0x30CC, + ("N", "e"): 0x30CD, + ("N", "o"): 0x30CE, + ("H", "a"): 0x30CF, + ("B", "a"): 0x30D0, + ("P", "a"): 0x30D1, + ("H", "i"): 0x30D2, + ("B", "i"): 0x30D3, + ("P", "i"): 0x30D4, + ("H", "u"): 0x30D5, + ("B", "u"): 0x30D6, + ("P", "u"): 0x30D7, + ("H", "e"): 0x30D8, + ("B", "e"): 0x30D9, + ("P", "e"): 0x30DA, + ("H", "o"): 0x30DB, + ("B", "o"): 0x30DC, + ("P", "o"): 0x30DD, + ("M", "a"): 0x30DE, + ("M", "i"): 0x30DF, + ("M", "u"): 0x30E0, + ("M", "e"): 0x30E1, + ("M", "o"): 0x30E2, + ("Y", "A"): 0x30E3, + ("Y", "a"): 0x30E4, + ("Y", "U"): 0x30E5, + ("Y", "u"): 0x30E6, + ("Y", "O"): 0x30E7, + ("Y", "o"): 0x30E8, + ("R", "a"): 0x30E9, + ("R", "i"): 0x30EA, + ("R", "u"): 0x30EB, + ("R", "e"): 0x30EC, + ("R", "o"): 0x30ED, + ("W", "A"): 0x30EE, + ("W", "a"): 0x30EF, + ("W", "i"): 0x30F0, + ("W", "e"): 0x30F1, + ("W", "o"): 0x30F2, + ("N", "6"): 0x30F3, + ("V", "u"): 0x30F4, + ("K", "A"): 0x30F5, + ("K", "E"): 0x30F6, + ("V", "a"): 0x30F7, + ("V", "i"): 0x30F8, + ("V", "e"): 0x30F9, + ("V", "o"): 0x30FA, + (".", "6"): 0x30FB, + ("-", "6"): 0x30FC, + ("*", "6"): 0x30FD, + ("+", "6"): 0x30FE, + ("b", "4"): 0x3105, + ("p", "4"): 0x3106, + ("m", "4"): 0x3107, + ("f", "4"): 0x3108, + ("d", "4"): 0x3109, + ("t", "4"): 0x310A, + ("n", "4"): 0x310B, + ("l", "4"): 0x310C, + ("g", "4"): 0x310D, + ("k", "4"): 0x310E, + ("h", "4"): 0x310F, + ("j", "4"): 0x3110, + ("q", "4"): 0x3111, + ("x", "4"): 0x3112, + ("z", "h"): 0x3113, + ("c", "h"): 0x3114, + ("s", "h"): 0x3115, + ("r", "4"): 0x3116, + ("z", "4"): 0x3117, + ("c", "4"): 0x3118, + ("s", "4"): 0x3119, + ("a", "4"): 0x311A, + ("o", "4"): 0x311B, + ("e", "4"): 0x311C, + ("a", "i"): 0x311E, + ("e", "i"): 0x311F, + ("a", "u"): 0x3120, + ("o", "u"): 0x3121, + ("a", "n"): 0x3122, + ("e", "n"): 0x3123, + ("a", "N"): 0x3124, + ("e", "N"): 0x3125, + ("e", "r"): 0x3126, + ("i", "4"): 0x3127, + ("u", "4"): 0x3128, + ("i", "u"): 0x3129, + ("v", "4"): 0x312A, + ("n", "G"): 0x312B, + ("g", "n"): 0x312C, + ("1", "c"): 0x3220, + ("2", "c"): 0x3221, + ("3", "c"): 0x3222, + ("4", "c"): 0x3223, + ("5", "c"): 0x3224, + ("6", "c"): 0x3225, + ("7", "c"): 0x3226, + ("8", "c"): 0x3227, + ("9", "c"): 0x3228, + # code points 0xe000 - 0xefff excluded, they have no assigned + # characters, only used in proposals. + ("f", "f"): 0xFB00, + ("f", "i"): 0xFB01, + ("f", "l"): 0xFB02, + ("f", "t"): 0xFB05, + ("s", "t"): 0xFB06, + # Vim 5.x compatible digraphs that don't conflict with the above + ("~", "!"): 161, + ("c", "|"): 162, + ("$", "$"): 163, + ("o", "x"): 164, # currency symbol in ISO 8859-1 + ("Y", "-"): 165, + ("|", "|"): 166, + ("c", "O"): 169, + ("-", ","): 172, + ("-", "="): 175, + ("~", "o"): 176, + ("2", "2"): 178, + ("3", "3"): 179, + ("p", "p"): 182, + ("~", "."): 183, + ("1", "1"): 185, + ("~", "?"): 191, + ("A", "`"): 192, + ("A", "^"): 194, + ("A", "~"): 195, + ("A", '"'): 196, + ("A", "@"): 197, + ("E", "`"): 200, + ("E", "^"): 202, + ("E", '"'): 203, + ("I", "`"): 204, + ("I", "^"): 206, + ("I", '"'): 207, + ("N", "~"): 209, + ("O", "`"): 210, + ("O", "^"): 212, + ("O", "~"): 213, + ("/", "\\"): 215, # multiplication symbol in ISO 8859-1 + ("U", "`"): 217, + ("U", "^"): 219, + ("I", "p"): 222, + ("a", "`"): 224, + ("a", "^"): 226, + ("a", "~"): 227, + ("a", '"'): 228, + ("a", "@"): 229, + ("e", "`"): 232, + ("e", "^"): 234, + ("e", '"'): 235, + ("i", "`"): 236, + ("i", "^"): 238, + ("n", "~"): 241, + ("o", "`"): 242, + ("o", "^"): 244, + ("o", "~"): 245, + ("u", "`"): 249, + ("u", "^"): 251, + ("y", '"'): 255, +} diff --git a/.venv/lib/python3.8/site-packages/prompt_toolkit/key_binding/emacs_state.py b/.venv/lib/python3.8/site-packages/prompt_toolkit/key_binding/emacs_state.py new file mode 100644 index 00000000..00967163 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/prompt_toolkit/key_binding/emacs_state.py @@ -0,0 +1,36 @@ +from typing import List, Optional + +from .key_processor import KeyPress + +__all__ = [ + "EmacsState", +] + + +class EmacsState: + """ + Mutable class to hold Emacs specific state. + """ + + def __init__(self) -> None: + # Simple macro recording. (Like Readline does.) + # (For Emacs mode.) + self.macro: Optional[List[KeyPress]] = [] + self.current_recording: Optional[List[KeyPress]] = None + + def reset(self) -> None: + self.current_recording = None + + @property + def is_recording(self) -> bool: + " Tell whether we are recording a macro. " + return self.current_recording is not None + + def start_macro(self) -> None: + " Start recording macro. " + self.current_recording = [] + + def end_macro(self) -> None: + " End recording macro. " + self.macro = self.current_recording + self.current_recording = None diff --git a/.venv/lib/python3.8/site-packages/prompt_toolkit/key_binding/key_bindings.py b/.venv/lib/python3.8/site-packages/prompt_toolkit/key_binding/key_bindings.py new file mode 100644 index 00000000..437f5716 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/prompt_toolkit/key_binding/key_bindings.py @@ -0,0 +1,635 @@ +""" +Key bindings registry. + +A `KeyBindings` object is a container that holds a list of key bindings. It has a +very efficient internal data structure for checking which key bindings apply +for a pressed key. + +Typical usage:: + + kb = KeyBindings() + + @kb.add(Keys.ControlX, Keys.ControlC, filter=INSERT) + def handler(event): + # Handle ControlX-ControlC key sequence. + pass + +It is also possible to combine multiple KeyBindings objects. We do this in the +default key bindings. There are some KeyBindings objects that contain the Emacs +bindings, while others contain the Vi bindings. They are merged together using +`merge_key_bindings`. + +We also have a `ConditionalKeyBindings` object that can enable/disable a group of +key bindings at once. + + +It is also possible to add a filter to a function, before a key binding has +been assigned, through the `key_binding` decorator.:: + + # First define a key handler with the `filter`. + @key_binding(filter=condition) + def my_key_binding(event): + ... + + # Later, add it to the key bindings. + kb.add(Keys.A, my_key_binding) +""" +from abc import ABCMeta, abstractmethod, abstractproperty +from typing import ( + TYPE_CHECKING, + Callable, + Hashable, + List, + Optional, + Sequence, + Tuple, + TypeVar, + Union, + cast, +) + +from prompt_toolkit.cache import SimpleCache +from prompt_toolkit.filters import FilterOrBool, Never, to_filter +from prompt_toolkit.keys import KEY_ALIASES, Keys + +# Avoid circular imports. +if TYPE_CHECKING: + from .key_processor import KeyPressEvent + + +__all__ = [ + "Binding", + "KeyBindingsBase", + "KeyBindings", + "ConditionalKeyBindings", + "merge_key_bindings", + "DynamicKeyBindings", + "GlobalOnlyKeyBindings", +] + +KeyHandlerCallable = Callable[["KeyPressEvent"], None] + + +class Binding: + """ + Key binding: (key sequence + handler + filter). + (Immutable binding class.) + + :param record_in_macro: When True, don't record this key binding when a + macro is recorded. + """ + + def __init__( + self, + keys: Tuple[Union[Keys, str], ...], + handler: KeyHandlerCallable, + filter: FilterOrBool = True, + eager: FilterOrBool = False, + is_global: FilterOrBool = False, + save_before: Callable[["KeyPressEvent"], bool] = (lambda e: True), + record_in_macro: FilterOrBool = True, + ) -> None: + self.keys = keys + self.handler = handler + self.filter = to_filter(filter) + self.eager = to_filter(eager) + self.is_global = to_filter(is_global) + self.save_before = save_before + self.record_in_macro = to_filter(record_in_macro) + + def call(self, event: "KeyPressEvent") -> None: + self.handler(event) + + def __repr__(self) -> str: + return "%s(keys=%r, handler=%r)" % ( + self.__class__.__name__, + self.keys, + self.handler, + ) + + +# Sequence of keys presses. +KeysTuple = Tuple[Union[Keys, str], ...] + + +class KeyBindingsBase(metaclass=ABCMeta): + """ + Interface for a KeyBindings. + """ + + @abstractproperty + def _version(self) -> Hashable: + """ + For cache invalidation. - This should increase every time that + something changes. + """ + return 0 + + @abstractmethod + def get_bindings_for_keys(self, keys: KeysTuple) -> List[Binding]: + """ + Return a list of key bindings that can handle these keys. + (This return also inactive bindings, so the `filter` still has to be + called, for checking it.) + + :param keys: tuple of keys. + """ + return [] + + @abstractmethod + def get_bindings_starting_with_keys(self, keys: KeysTuple) -> List[Binding]: + """ + Return a list of key bindings that handle a key sequence starting with + `keys`. (It does only return bindings for which the sequences are + longer than `keys`. And like `get_bindings_for_keys`, it also includes + inactive bindings.) + + :param keys: tuple of keys. + """ + return [] + + @abstractproperty + def bindings(self) -> List[Binding]: + """ + List of `Binding` objects. + (These need to be exposed, so that `KeyBindings` objects can be merged + together.) + """ + return [] + + # `add` and `remove` don't have to be part of this interface. + + +T = TypeVar("T", bound=Union[KeyHandlerCallable, Binding]) + + +class KeyBindings(KeyBindingsBase): + """ + A container for a set of key bindings. + + Example usage:: + + kb = KeyBindings() + + @kb.add('c-t') + def _(event): + print('Control-T pressed') + + @kb.add('c-a', 'c-b') + def _(event): + print('Control-A pressed, followed by Control-B') + + @kb.add('c-x', filter=is_searching) + def _(event): + print('Control-X pressed') # Works only if we are searching. + + """ + + def __init__(self) -> None: + self._bindings: List[Binding] = [] + self._get_bindings_for_keys_cache: SimpleCache[ + KeysTuple, List[Binding] + ] = SimpleCache(maxsize=10000) + self._get_bindings_starting_with_keys_cache: SimpleCache[ + KeysTuple, List[Binding] + ] = SimpleCache(maxsize=1000) + self.__version = 0 # For cache invalidation. + + def _clear_cache(self) -> None: + self.__version += 1 + self._get_bindings_for_keys_cache.clear() + self._get_bindings_starting_with_keys_cache.clear() + + @property + def bindings(self) -> List[Binding]: + return self._bindings + + @property + def _version(self) -> Hashable: + return self.__version + + def add( + self, + *keys: Union[Keys, str], + filter: FilterOrBool = True, + eager: FilterOrBool = False, + is_global: FilterOrBool = False, + save_before: Callable[["KeyPressEvent"], bool] = (lambda e: True), + record_in_macro: FilterOrBool = True, + ) -> Callable[[T], T]: + """ + Decorator for adding a key bindings. + + :param filter: :class:`~prompt_toolkit.filters.Filter` to determine + when this key binding is active. + :param eager: :class:`~prompt_toolkit.filters.Filter` or `bool`. + When True, ignore potential longer matches when this key binding is + hit. E.g. when there is an active eager key binding for Ctrl-X, + execute the handler immediately and ignore the key binding for + Ctrl-X Ctrl-E of which it is a prefix. + :param is_global: When this key bindings is added to a `Container` or + `Control`, make it a global (always active) binding. + :param save_before: Callable that takes an `Event` and returns True if + we should save the current buffer, before handling the event. + (That's the default.) + :param record_in_macro: Record these key bindings when a macro is + being recorded. (True by default.) + """ + assert keys + + keys = tuple(_parse_key(k) for k in keys) + + if isinstance(filter, Never): + # When a filter is Never, it will always stay disabled, so in that + # case don't bother putting it in the key bindings. It will slow + # down every key press otherwise. + def decorator(func: T) -> T: + return func + + else: + + def decorator(func: T) -> T: + if isinstance(func, Binding): + # We're adding an existing Binding object. + self.bindings.append( + Binding( + keys, + func.handler, + filter=func.filter & to_filter(filter), + eager=to_filter(eager) | func.eager, + is_global=to_filter(is_global) | func.is_global, + save_before=func.save_before, + record_in_macro=func.record_in_macro, + ) + ) + else: + self.bindings.append( + Binding( + keys, + cast(KeyHandlerCallable, func), + filter=filter, + eager=eager, + is_global=is_global, + save_before=save_before, + record_in_macro=record_in_macro, + ) + ) + self._clear_cache() + + return func + + return decorator + + def remove(self, *args: Union[Keys, str, KeyHandlerCallable]) -> None: + """ + Remove a key binding. + + This expects either a function that was given to `add` method as + parameter or a sequence of key bindings. + + Raises `ValueError` when no bindings was found. + + Usage:: + + remove(handler) # Pass handler. + remove('c-x', 'c-a') # Or pass the key bindings. + """ + found = False + + if callable(args[0]): + assert len(args) == 1 + function = args[0] + + # Remove the given function. + for b in self.bindings: + if b.handler == function: + self.bindings.remove(b) + found = True + + else: + assert len(args) > 0 + args = cast(Tuple[Union[Keys, str]], args) + + # Remove this sequence of key bindings. + keys = tuple(_parse_key(k) for k in args) + + for b in self.bindings: + if b.keys == keys: + self.bindings.remove(b) + found = True + + if found: + self._clear_cache() + else: + # No key binding found for this function. Raise ValueError. + raise ValueError("Binding not found: %r" % (function,)) + + # For backwards-compatibility. + add_binding = add + remove_binding = remove + + def get_bindings_for_keys(self, keys: KeysTuple) -> List[Binding]: + """ + Return a list of key bindings that can handle this key. + (This return also inactive bindings, so the `filter` still has to be + called, for checking it.) + + :param keys: tuple of keys. + """ + + def get() -> List[Binding]: + result: List[Tuple[int, Binding]] = [] + + for b in self.bindings: + if len(keys) == len(b.keys): + match = True + any_count = 0 + + for i, j in zip(b.keys, keys): + if i != j and i != Keys.Any: + match = False + break + + if i == Keys.Any: + any_count += 1 + + if match: + result.append((any_count, b)) + + # Place bindings that have more 'Any' occurrences in them at the end. + result = sorted(result, key=lambda item: -item[0]) + + return [item[1] for item in result] + + return self._get_bindings_for_keys_cache.get(keys, get) + + def get_bindings_starting_with_keys(self, keys: KeysTuple) -> List[Binding]: + """ + Return a list of key bindings that handle a key sequence starting with + `keys`. (It does only return bindings for which the sequences are + longer than `keys`. And like `get_bindings_for_keys`, it also includes + inactive bindings.) + + :param keys: tuple of keys. + """ + + def get() -> List[Binding]: + result = [] + for b in self.bindings: + if len(keys) < len(b.keys): + match = True + for i, j in zip(b.keys, keys): + if i != j and i != Keys.Any: + match = False + break + if match: + result.append(b) + return result + + return self._get_bindings_starting_with_keys_cache.get(keys, get) + + +def _parse_key(key: Union[Keys, str]) -> Union[str, Keys]: + """ + Replace key by alias and verify whether it's a valid one. + """ + # Already a parse key? -> Return it. + if isinstance(key, Keys): + return key + + # Lookup aliases. + key = KEY_ALIASES.get(key, key) + + # Replace 'space' by ' ' + if key == "space": + key = " " + + # Return as `Key` object when it's a special key. + try: + return Keys(key) + except ValueError: + pass + + # Final validation. + if len(key) != 1: + raise ValueError("Invalid key: %s" % (key,)) + + return key + + +def key_binding( + filter: FilterOrBool = True, + eager: FilterOrBool = False, + is_global: FilterOrBool = False, + save_before: Callable[["KeyPressEvent"], bool] = (lambda event: True), + record_in_macro: FilterOrBool = True, +) -> Callable[[KeyHandlerCallable], Binding]: + """ + Decorator that turn a function into a `Binding` object. This can be added + to a `KeyBindings` object when a key binding is assigned. + """ + assert save_before is None or callable(save_before) + + filter = to_filter(filter) + eager = to_filter(eager) + is_global = to_filter(is_global) + save_before = save_before + record_in_macro = to_filter(record_in_macro) + keys = () + + def decorator(function: KeyHandlerCallable) -> Binding: + return Binding( + keys, + function, + filter=filter, + eager=eager, + is_global=is_global, + save_before=save_before, + record_in_macro=record_in_macro, + ) + + return decorator + + +class _Proxy(KeyBindingsBase): + """ + Common part for ConditionalKeyBindings and _MergedKeyBindings. + """ + + def __init__(self) -> None: + # `KeyBindings` to be synchronized with all the others. + self._bindings2: KeyBindingsBase = KeyBindings() + self._last_version: Hashable = () + + def _update_cache(self) -> None: + """ + If `self._last_version` is outdated, then this should update + the version and `self._bindings2`. + """ + raise NotImplementedError + + # Proxy methods to self._bindings2. + + @property + def bindings(self) -> List[Binding]: + self._update_cache() + return self._bindings2.bindings + + @property + def _version(self) -> Hashable: + self._update_cache() + return self._last_version + + def get_bindings_for_keys(self, *a, **kw): + self._update_cache() + return self._bindings2.get_bindings_for_keys(*a, **kw) + + def get_bindings_starting_with_keys(self, *a, **kw): + self._update_cache() + return self._bindings2.get_bindings_starting_with_keys(*a, **kw) + + +class ConditionalKeyBindings(_Proxy): + """ + Wraps around a `KeyBindings`. Disable/enable all the key bindings according to + the given (additional) filter.:: + + @Condition + def setting_is_true(): + return True # or False + + registry = ConditionalKeyBindings(key_bindings, setting_is_true) + + When new key bindings are added to this object. They are also + enable/disabled according to the given `filter`. + + :param registries: List of :class:`.KeyBindings` objects. + :param filter: :class:`~prompt_toolkit.filters.Filter` object. + """ + + def __init__( + self, key_bindings: KeyBindingsBase, filter: FilterOrBool = True + ) -> None: + + _Proxy.__init__(self) + + self.key_bindings = key_bindings + self.filter = to_filter(filter) + + def _update_cache(self) -> None: + " If the original key bindings was changed. Update our copy version. " + expected_version = self.key_bindings._version + + if self._last_version != expected_version: + bindings2 = KeyBindings() + + # Copy all bindings from `self.key_bindings`, adding our condition. + for b in self.key_bindings.bindings: + bindings2.bindings.append( + Binding( + keys=b.keys, + handler=b.handler, + filter=self.filter & b.filter, + eager=b.eager, + is_global=b.is_global, + save_before=b.save_before, + record_in_macro=b.record_in_macro, + ) + ) + + self._bindings2 = bindings2 + self._last_version = expected_version + + +class _MergedKeyBindings(_Proxy): + """ + Merge multiple registries of key bindings into one. + + This class acts as a proxy to multiple :class:`.KeyBindings` objects, but + behaves as if this is just one bigger :class:`.KeyBindings`. + + :param registries: List of :class:`.KeyBindings` objects. + """ + + def __init__(self, registries: Sequence[KeyBindingsBase]) -> None: + _Proxy.__init__(self) + self.registries = registries + + def _update_cache(self) -> None: + """ + If one of the original registries was changed. Update our merged + version. + """ + expected_version = tuple(r._version for r in self.registries) + + if self._last_version != expected_version: + bindings2 = KeyBindings() + + for reg in self.registries: + bindings2.bindings.extend(reg.bindings) + + self._bindings2 = bindings2 + self._last_version = expected_version + + +def merge_key_bindings(bindings: Sequence[KeyBindingsBase]) -> _MergedKeyBindings: + """ + Merge multiple :class:`.Keybinding` objects together. + + Usage:: + + bindings = merge_key_bindings([bindings1, bindings2, ...]) + """ + return _MergedKeyBindings(bindings) + + +class DynamicKeyBindings(_Proxy): + """ + KeyBindings class that can dynamically returns any KeyBindings. + + :param get_key_bindings: Callable that returns a :class:`.KeyBindings` instance. + """ + + def __init__( + self, get_key_bindings: Callable[[], Optional[KeyBindingsBase]] + ) -> None: + self.get_key_bindings = get_key_bindings + self.__version = 0 + self._last_child_version = None + self._dummy = KeyBindings() # Empty key bindings. + + def _update_cache(self) -> None: + key_bindings = self.get_key_bindings() or self._dummy + assert isinstance(key_bindings, KeyBindingsBase) + version = id(key_bindings), key_bindings._version + + self._bindings2 = key_bindings + self._last_version = version + + +class GlobalOnlyKeyBindings(_Proxy): + """ + Wrapper around a :class:`.KeyBindings` object that only exposes the global + key bindings. + """ + + def __init__(self, key_bindings: KeyBindingsBase) -> None: + _Proxy.__init__(self) + self.key_bindings = key_bindings + + def _update_cache(self) -> None: + """ + If one of the original registries was changed. Update our merged + version. + """ + expected_version = self.key_bindings._version + + if self._last_version != expected_version: + bindings2 = KeyBindings() + + for b in self.key_bindings.bindings: + if b.is_global(): + bindings2.bindings.append(b) + + self._bindings2 = bindings2 + self._last_version = expected_version diff --git a/.venv/lib/python3.8/site-packages/prompt_toolkit/key_binding/key_processor.py b/.venv/lib/python3.8/site-packages/prompt_toolkit/key_binding/key_processor.py new file mode 100644 index 00000000..99c32d1e --- /dev/null +++ b/.venv/lib/python3.8/site-packages/prompt_toolkit/key_binding/key_processor.py @@ -0,0 +1,530 @@ +# *** encoding: utf-8 *** +""" +An :class:`~.KeyProcessor` receives callbacks for the keystrokes parsed from +the input in the :class:`~prompt_toolkit.inputstream.InputStream` instance. + +The `KeyProcessor` will according to the implemented keybindings call the +correct callbacks when new key presses are feed through `feed`. +""" +import weakref +from asyncio import Task, sleep +from collections import deque +from typing import TYPE_CHECKING, Any, Deque, Generator, List, Optional, Union + +from prompt_toolkit.application.current import get_app +from prompt_toolkit.enums import EditingMode +from prompt_toolkit.filters.app import vi_navigation_mode +from prompt_toolkit.keys import Keys +from prompt_toolkit.utils import Event + +from .key_bindings import Binding, KeyBindingsBase + +if TYPE_CHECKING: + from prompt_toolkit.application import Application + from prompt_toolkit.buffer import Buffer + + +__all__ = [ + "KeyProcessor", + "KeyPress", + "KeyPressEvent", +] + + +class KeyPress: + """ + :param key: A `Keys` instance or text (one character). + :param data: The received string on stdin. (Often vt100 escape codes.) + """ + + def __init__(self, key: Union[Keys, str], data: Optional[str] = None) -> None: + assert isinstance(key, Keys) or len(key) == 1 + + if data is None: + if isinstance(key, Keys): + data = key.value + else: + data = key # 'key' is a one character string. + + self.key = key + self.data = data + + def __repr__(self) -> str: + return "%s(key=%r, data=%r)" % (self.__class__.__name__, self.key, self.data) + + def __eq__(self, other: object) -> bool: + if not isinstance(other, KeyPress): + return False + return self.key == other.key and self.data == other.data + + +""" +Helper object to indicate flush operation in the KeyProcessor. +NOTE: the implementation is very similar to the VT100 parser. +""" +_Flush = KeyPress("?", data="_Flush") + + +class KeyProcessor: + """ + Statemachine that receives :class:`KeyPress` instances and according to the + key bindings in the given :class:`KeyBindings`, calls the matching handlers. + + :: + + p = KeyProcessor(key_bindings) + + # Send keys into the processor. + p.feed(KeyPress(Keys.ControlX, '\x18')) + p.feed(KeyPress(Keys.ControlC, '\x03') + + # Process all the keys in the queue. + p.process_keys() + + # Now the ControlX-ControlC callback will be called if this sequence is + # registered in the key bindings. + + :param key_bindings: `KeyBindingsBase` instance. + """ + + def __init__(self, key_bindings: KeyBindingsBase) -> None: + self._bindings = key_bindings + + self.before_key_press = Event(self) + self.after_key_press = Event(self) + + self._flush_wait_task: Optional[Task] = None + + self.reset() + + def reset(self) -> None: + self._previous_key_sequence: List[KeyPress] = [] + self._previous_handler: Optional[Binding] = None + + # The queue of keys not yet send to our _process generator/state machine. + self.input_queue: Deque[KeyPress] = deque() + + # The key buffer that is matched in the generator state machine. + # (This is at at most the amount of keys that make up for one key binding.) + self.key_buffer: List[KeyPress] = [] + + #: Readline argument (for repetition of commands.) + #: https://www.gnu.org/software/bash/manual/html_node/Readline-Arguments.html + self.arg: Optional[str] = None + + # Start the processor coroutine. + self._process_coroutine = self._process() + self._process_coroutine.send(None) # type: ignore + + def _get_matches(self, key_presses: List[KeyPress]) -> List[Binding]: + """ + For a list of :class:`KeyPress` instances. Give the matching handlers + that would handle this. + """ + keys = tuple(k.key for k in key_presses) + + # Try match, with mode flag + return [b for b in self._bindings.get_bindings_for_keys(keys) if b.filter()] + + def _is_prefix_of_longer_match(self, key_presses: List[KeyPress]) -> bool: + """ + For a list of :class:`KeyPress` instances. Return True if there is any + handler that is bound to a suffix of this keys. + """ + keys = tuple(k.key for k in key_presses) + + # Get the filters for all the key bindings that have a longer match. + # Note that we transform it into a `set`, because we don't care about + # the actual bindings and executing it more than once doesn't make + # sense. (Many key bindings share the same filter.) + filters = set( + b.filter for b in self._bindings.get_bindings_starting_with_keys(keys) + ) + + # When any key binding is active, return True. + return any(f() for f in filters) + + def _process(self) -> Generator[None, KeyPress, None]: + """ + Coroutine implementing the key match algorithm. Key strokes are sent + into this generator, and it calls the appropriate handlers. + """ + buffer = self.key_buffer + retry = False + + while True: + flush = False + + if retry: + retry = False + else: + key = yield + if key is _Flush: + flush = True + else: + buffer.append(key) + + # If we have some key presses, check for matches. + if buffer: + matches = self._get_matches(buffer) + + if flush: + is_prefix_of_longer_match = False + else: + is_prefix_of_longer_match = self._is_prefix_of_longer_match(buffer) + + # When eager matches were found, give priority to them and also + # ignore all the longer matches. + eager_matches = [m for m in matches if m.eager()] + + if eager_matches: + matches = eager_matches + is_prefix_of_longer_match = False + + # Exact matches found, call handler. + if not is_prefix_of_longer_match and matches: + self._call_handler(matches[-1], key_sequence=buffer[:]) + del buffer[:] # Keep reference. + + # No match found. + elif not is_prefix_of_longer_match and not matches: + retry = True + found = False + + # Loop over the input, try longest match first and shift. + for i in range(len(buffer), 0, -1): + matches = self._get_matches(buffer[:i]) + if matches: + self._call_handler(matches[-1], key_sequence=buffer[:i]) + del buffer[:i] + found = True + break + + if not found: + del buffer[:1] + + def feed(self, key_press: KeyPress, first: bool = False) -> None: + """ + Add a new :class:`KeyPress` to the input queue. + (Don't forget to call `process_keys` in order to process the queue.) + + :param first: If true, insert before everything else. + """ + if first: + self.input_queue.appendleft(key_press) + else: + self.input_queue.append(key_press) + + def feed_multiple(self, key_presses: List[KeyPress], first: bool = False) -> None: + """ + :param first: If true, insert before everything else. + """ + if first: + self.input_queue.extendleft(reversed(key_presses)) + else: + self.input_queue.extend(key_presses) + + def process_keys(self) -> None: + """ + Process all the keys in the `input_queue`. + (To be called after `feed`.) + + Note: because of the `feed`/`process_keys` separation, it is + possible to call `feed` from inside a key binding. + This function keeps looping until the queue is empty. + """ + app = get_app() + + def not_empty() -> bool: + # When the application result is set, stop processing keys. (E.g. + # if ENTER was received, followed by a few additional key strokes, + # leave the other keys in the queue.) + if app.is_done: + # But if there are still CPRResponse keys in the queue, these + # need to be processed. + return any(k for k in self.input_queue if k.key == Keys.CPRResponse) + else: + return bool(self.input_queue) + + def get_next() -> KeyPress: + if app.is_done: + # Only process CPR responses. Everything else is typeahead. + cpr = [k for k in self.input_queue if k.key == Keys.CPRResponse][0] + self.input_queue.remove(cpr) + return cpr + else: + return self.input_queue.popleft() + + keys_processed = False + is_flush = False + + while not_empty(): + keys_processed = True + + # Process next key. + key_press = get_next() + + is_flush = key_press is _Flush + is_cpr = key_press.key == Keys.CPRResponse + + if not is_flush and not is_cpr: + self.before_key_press.fire() + + try: + self._process_coroutine.send(key_press) + except Exception: + # If for some reason something goes wrong in the parser, (maybe + # an exception was raised) restart the processor for next time. + self.reset() + self.empty_queue() + app.invalidate() + raise + + if not is_flush and not is_cpr: + self.after_key_press.fire() + + if keys_processed: + # Invalidate user interface. + app.invalidate() + + # Skip timeout if the last key was flush. + if not is_flush: + self._start_timeout() + + def empty_queue(self) -> List[KeyPress]: + """ + Empty the input queue. Return the unprocessed input. + """ + key_presses = list(self.input_queue) + self.input_queue.clear() + + # Filter out CPRs. We don't want to return these. + key_presses = [k for k in key_presses if k.key != Keys.CPRResponse] + return key_presses + + def _call_handler(self, handler: Binding, key_sequence: List[KeyPress]) -> None: + app = get_app() + was_recording_emacs = app.emacs_state.is_recording + was_recording_vi = bool(app.vi_state.recording_register) + was_temporary_navigation_mode = app.vi_state.temporary_navigation_mode + arg = self.arg + self.arg = None + + event = KeyPressEvent( + weakref.ref(self), + arg=arg, + key_sequence=key_sequence, + previous_key_sequence=self._previous_key_sequence, + is_repeat=(handler == self._previous_handler), + ) + + # Save the state of the current buffer. + if handler.save_before(event): + event.app.current_buffer.save_to_undo_stack() + + # Call handler. + from prompt_toolkit.buffer import EditReadOnlyBuffer + + try: + handler.call(event) + self._fix_vi_cursor_position(event) + + except EditReadOnlyBuffer: + # When a key binding does an attempt to change a buffer which is + # read-only, we can ignore that. We sound a bell and go on. + app.output.bell() + + if was_temporary_navigation_mode: + self._leave_vi_temp_navigation_mode(event) + + self._previous_key_sequence = key_sequence + self._previous_handler = handler + + # Record the key sequence in our macro. (Only if we're in macro mode + # before and after executing the key.) + if handler.record_in_macro(): + if app.emacs_state.is_recording and was_recording_emacs: + recording = app.emacs_state.current_recording + if recording is not None: # Should always be true, given that + # `was_recording_emacs` is set. + recording.extend(key_sequence) + + if app.vi_state.recording_register and was_recording_vi: + for k in key_sequence: + app.vi_state.current_recording += k.data + + def _fix_vi_cursor_position(self, event: "KeyPressEvent") -> None: + """ + After every command, make sure that if we are in Vi navigation mode, we + never put the cursor after the last character of a line. (Unless it's + an empty line.) + """ + app = event.app + buff = app.current_buffer + preferred_column = buff.preferred_column + + if ( + vi_navigation_mode() + and buff.document.is_cursor_at_the_end_of_line + and len(buff.document.current_line) > 0 + ): + buff.cursor_position -= 1 + + # Set the preferred_column for arrow up/down again. + # (This was cleared after changing the cursor position.) + buff.preferred_column = preferred_column + + def _leave_vi_temp_navigation_mode(self, event: "KeyPressEvent") -> None: + """ + If we're in Vi temporary navigation (normal) mode, return to + insert/replace mode after executing one action. + """ + app = event.app + + if app.editing_mode == EditingMode.VI: + # Not waiting for a text object and no argument has been given. + if app.vi_state.operator_func is None and self.arg is None: + app.vi_state.temporary_navigation_mode = False + + def _start_timeout(self) -> None: + """ + Start auto flush timeout. Similar to Vim's `timeoutlen` option. + + Start a background coroutine with a timer. When this timeout expires + and no key was pressed in the meantime, we flush all data in the queue + and call the appropriate key binding handlers. + """ + app = get_app() + timeout = app.timeoutlen + + if timeout is None: + return + + async def wait() -> None: + " Wait for timeout. " + # This sleep can be cancelled. In that case we don't flush. + await sleep(timeout) + + if len(self.key_buffer) > 0: + # (No keys pressed in the meantime.) + flush_keys() + + def flush_keys() -> None: + " Flush keys. " + self.feed(_Flush) + self.process_keys() + + # Automatically flush keys. + if self._flush_wait_task: + self._flush_wait_task.cancel() + self._flush_wait_task = app.create_background_task(wait()) + + +class KeyPressEvent: + """ + Key press event, delivered to key bindings. + + :param key_processor_ref: Weak reference to the `KeyProcessor`. + :param arg: Repetition argument. + :param key_sequence: List of `KeyPress` instances. + :param previouskey_sequence: Previous list of `KeyPress` instances. + :param is_repeat: True when the previous event was delivered to the same handler. + """ + + def __init__( + self, + key_processor_ref: "weakref.ReferenceType[KeyProcessor]", + arg: Optional[str], + key_sequence: List[KeyPress], + previous_key_sequence: List[KeyPress], + is_repeat: bool, + ) -> None: + + self._key_processor_ref = key_processor_ref + self.key_sequence = key_sequence + self.previous_key_sequence = previous_key_sequence + + #: True when the previous key sequence was handled by the same handler. + self.is_repeat = is_repeat + + self._arg = arg + self._app = get_app() + + def __repr__(self) -> str: + return "KeyPressEvent(arg=%r, key_sequence=%r, is_repeat=%r)" % ( + self.arg, + self.key_sequence, + self.is_repeat, + ) + + @property + def data(self) -> str: + return self.key_sequence[-1].data + + @property + def key_processor(self) -> KeyProcessor: + processor = self._key_processor_ref() + if processor is None: + raise Exception("KeyProcessor was lost. This should not happen.") + return processor + + @property + def app(self) -> "Application[Any]": + """ + The current `Application` object. + """ + return self._app + + @property + def current_buffer(self) -> "Buffer": + """ + The current buffer. + """ + return self.app.current_buffer + + @property + def arg(self) -> int: + """ + Repetition argument. + """ + if self._arg == "-": + return -1 + + result = int(self._arg or 1) + + # Don't exceed a million. + if int(result) >= 1000000: + result = 1 + + return result + + @property + def arg_present(self) -> bool: + """ + True if repetition argument was explicitly provided. + """ + return self._arg is not None + + def append_to_arg_count(self, data: str) -> None: + """ + Add digit to the input argument. + + :param data: the typed digit as string + """ + assert data in "-0123456789" + current = self._arg + + if data == "-": + assert current is None or current == "-" + result = data + elif current is None: + result = data + else: + result = "%s%s" % (current, data) + + self.key_processor.arg = result + + @property + def cli(self) -> "Application": + " For backward-compatibility. " + return self.app diff --git a/.venv/lib/python3.8/site-packages/prompt_toolkit/key_binding/vi_state.py b/.venv/lib/python3.8/site-packages/prompt_toolkit/key_binding/vi_state.py new file mode 100644 index 00000000..017bb4b9 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/prompt_toolkit/key_binding/vi_state.py @@ -0,0 +1,107 @@ +from enum import Enum +from typing import TYPE_CHECKING, Callable, Dict, Optional + +from prompt_toolkit.clipboard import ClipboardData + +if TYPE_CHECKING: + from .key_bindings.vi import TextObject + from .key_processor import KeyPressEvent + +__all__ = [ + "InputMode", + "CharacterFind", + "ViState", +] + + +class InputMode(str, Enum): + value: str + + INSERT = "vi-insert" + INSERT_MULTIPLE = "vi-insert-multiple" + NAVIGATION = "vi-navigation" # Normal mode. + REPLACE = "vi-replace" + REPLACE_SINGLE = "vi-replace-single" + + +class CharacterFind: + def __init__(self, character: str, backwards: bool = False) -> None: + self.character = character + self.backwards = backwards + + +class ViState: + """ + Mutable class to hold the state of the Vi navigation. + """ + + def __init__(self) -> None: + #: None or CharacterFind instance. (This is used to repeat the last + #: search in Vi mode, by pressing the 'n' or 'N' in navigation mode.) + self.last_character_find: Optional[CharacterFind] = None + + # When an operator is given and we are waiting for text object, + # -- e.g. in the case of 'dw', after the 'd' --, an operator callback + # is set here. + self.operator_func: Optional[ + Callable[["KeyPressEvent", "TextObject"], None] + ] = None + self.operator_arg: Optional[int] = None + + #: Named registers. Maps register name (e.g. 'a') to + #: :class:`ClipboardData` instances. + self.named_registers: Dict[str, ClipboardData] = {} + + #: The Vi mode we're currently in to. + self.__input_mode = InputMode.INSERT + + #: Waiting for digraph. + self.waiting_for_digraph = False + self.digraph_symbol1: Optional[str] = None # (None or a symbol.) + + #: When true, make ~ act as an operator. + self.tilde_operator = False + + #: Register in which we are recording a macro. + #: `None` when not recording anything. + # Note that the recording is only stored in the register after the + # recording is stopped. So we record in a separate `current_recording` + # variable. + self.recording_register: Optional[str] = None + self.current_recording: str = "" + + # Temporary navigation (normal) mode. + # This happens when control-o has been pressed in insert or replace + # mode. The user can now do one navigation action and we'll return back + # to insert/replace. + self.temporary_navigation_mode = False + + @property + def input_mode(self) -> InputMode: + " Get `InputMode`. " + return self.__input_mode + + @input_mode.setter + def input_mode(self, value: InputMode) -> None: + " Set `InputMode`. " + if value == InputMode.NAVIGATION: + self.waiting_for_digraph = False + self.operator_func = None + self.operator_arg = None + + self.__input_mode = value + + def reset(self) -> None: + """ + Reset state, go back to the given mode. INSERT by default. + """ + # Go back to insert mode. + self.input_mode = InputMode.INSERT + + self.waiting_for_digraph = False + self.operator_func = None + self.operator_arg = None + + # Reset recording state. + self.recording_register = None + self.current_recording = "" diff --git a/.venv/lib/python3.8/site-packages/prompt_toolkit/keys.py b/.venv/lib/python3.8/site-packages/prompt_toolkit/keys.py new file mode 100644 index 00000000..58b2e4b7 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/prompt_toolkit/keys.py @@ -0,0 +1,219 @@ +from enum import Enum +from typing import Dict, List + +__all__ = [ + "Keys", + "ALL_KEYS", +] + + +class Keys(str, Enum): + """ + List of keys for use in key bindings. + + Note that this is an "StrEnum", all values can be compared against + strings. + """ + + value: str + + Escape = "escape" # Also Control-[ + ShiftEscape = "s-escape" + + ControlAt = "c-@" # Also Control-Space. + + ControlA = "c-a" + ControlB = "c-b" + ControlC = "c-c" + ControlD = "c-d" + ControlE = "c-e" + ControlF = "c-f" + ControlG = "c-g" + ControlH = "c-h" + ControlI = "c-i" # Tab + ControlJ = "c-j" # Newline + ControlK = "c-k" + ControlL = "c-l" + ControlM = "c-m" # Carriage return + ControlN = "c-n" + ControlO = "c-o" + ControlP = "c-p" + ControlQ = "c-q" + ControlR = "c-r" + ControlS = "c-s" + ControlT = "c-t" + ControlU = "c-u" + ControlV = "c-v" + ControlW = "c-w" + ControlX = "c-x" + ControlY = "c-y" + ControlZ = "c-z" + + Control1 = "c-1" + Control2 = "c-2" + Control3 = "c-3" + Control4 = "c-4" + Control5 = "c-5" + Control6 = "c-6" + Control7 = "c-7" + Control8 = "c-8" + Control9 = "c-9" + Control0 = "c-0" + + ControlShift1 = "c-s-1" + ControlShift2 = "c-s-2" + ControlShift3 = "c-s-3" + ControlShift4 = "c-s-4" + ControlShift5 = "c-s-5" + ControlShift6 = "c-s-6" + ControlShift7 = "c-s-7" + ControlShift8 = "c-s-8" + ControlShift9 = "c-s-9" + ControlShift0 = "c-s-0" + + ControlBackslash = "c-\\" + ControlSquareClose = "c-]" + ControlCircumflex = "c-^" + ControlUnderscore = "c-_" + + Left = "left" + Right = "right" + Up = "up" + Down = "down" + Home = "home" + End = "end" + Insert = "insert" + Delete = "delete" + PageUp = "pageup" + PageDown = "pagedown" + + ControlLeft = "c-left" + ControlRight = "c-right" + ControlUp = "c-up" + ControlDown = "c-down" + ControlHome = "c-home" + ControlEnd = "c-end" + ControlInsert = "c-insert" + ControlDelete = "c-delete" + ControlPageUp = "c-pageup" + ControlPageDown = "c-pagedown" + + ShiftLeft = "s-left" + ShiftRight = "s-right" + ShiftUp = "s-up" + ShiftDown = "s-down" + ShiftHome = "s-home" + ShiftEnd = "s-end" + ShiftInsert = "s-insert" + ShiftDelete = "s-delete" + ShiftPageUp = "s-pageup" + ShiftPageDown = "s-pagedown" + + ControlShiftLeft = "c-s-left" + ControlShiftRight = "c-s-right" + ControlShiftUp = "c-s-up" + ControlShiftDown = "c-s-down" + ControlShiftHome = "c-s-home" + ControlShiftEnd = "c-s-end" + ControlShiftInsert = "c-s-insert" + ControlShiftDelete = "c-s-delete" + ControlShiftPageUp = "c-s-pageup" + ControlShiftPageDown = "c-s-pagedown" + + BackTab = "s-tab" # shift + tab + + F1 = "f1" + F2 = "f2" + F3 = "f3" + F4 = "f4" + F5 = "f5" + F6 = "f6" + F7 = "f7" + F8 = "f8" + F9 = "f9" + F10 = "f10" + F11 = "f11" + F12 = "f12" + F13 = "f13" + F14 = "f14" + F15 = "f15" + F16 = "f16" + F17 = "f17" + F18 = "f18" + F19 = "f19" + F20 = "f20" + F21 = "f21" + F22 = "f22" + F23 = "f23" + F24 = "f24" + + ControlF1 = "c-f1" + ControlF2 = "c-f2" + ControlF3 = "c-f3" + ControlF4 = "c-f4" + ControlF5 = "c-f5" + ControlF6 = "c-f6" + ControlF7 = "c-f7" + ControlF8 = "c-f8" + ControlF9 = "c-f9" + ControlF10 = "c-f10" + ControlF11 = "c-f11" + ControlF12 = "c-f12" + ControlF13 = "c-f13" + ControlF14 = "c-f14" + ControlF15 = "c-f15" + ControlF16 = "c-f16" + ControlF17 = "c-f17" + ControlF18 = "c-f18" + ControlF19 = "c-f19" + ControlF20 = "c-f20" + ControlF21 = "c-f21" + ControlF22 = "c-f22" + ControlF23 = "c-f23" + ControlF24 = "c-f24" + + # Matches any key. + Any = "" + + # Special. + ScrollUp = "" + ScrollDown = "" + + CPRResponse = "" + Vt100MouseEvent = "" + WindowsMouseEvent = "" + BracketedPaste = "" + + # For internal use: key which is ignored. + # (The key binding for this key should not do anything.) + Ignore = "" + + # Some 'Key' aliases (for backwards-compatibility). + ControlSpace = ControlAt + Tab = ControlI + Enter = ControlM + Backspace = ControlH + + # ShiftControl was renamed to ControlShift in + # 888fcb6fa4efea0de8333177e1bbc792f3ff3c24 (20 Feb 2020). + ShiftControlLeft = ControlShiftLeft + ShiftControlRight = ControlShiftRight + ShiftControlHome = ControlShiftHome + ShiftControlEnd = ControlShiftEnd + + +ALL_KEYS: List[str] = [k.value for k in Keys] + + +# Aliases. +KEY_ALIASES: Dict[str, str] = { + "backspace": "c-h", + "c-space": "c-@", + "enter": "c-m", + "tab": "c-i", + # ShiftControl was renamed to ControlShift. + "s-c-left": "c-s-left", + "s-c-right": "c-s-right", + "s-c-home": "c-s-home", + "s-c-end": "c-s-end", +} diff --git a/.venv/lib/python3.8/site-packages/prompt_toolkit/layout/__init__.py b/.venv/lib/python3.8/site-packages/prompt_toolkit/layout/__init__.py new file mode 100644 index 00000000..a3292081 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/prompt_toolkit/layout/__init__.py @@ -0,0 +1,142 @@ +""" +Command line layout definitions +------------------------------- + +The layout of a command line interface is defined by a Container instance. +There are two main groups of classes here. Containers and controls: + +- A container can contain other containers or controls, it can have multiple + children and it decides about the dimensions. +- A control is responsible for rendering the actual content to a screen. + A control can propose some dimensions, but it's the container who decides + about the dimensions -- or when the control consumes more space -- which part + of the control will be visible. + + +Container classes:: + + - Container (Abstract base class) + |- HSplit (Horizontal split) + |- VSplit (Vertical split) + |- FloatContainer (Container which can also contain menus and other floats) + `- Window (Container which contains one actual control + +Control classes:: + + - UIControl (Abstract base class) + |- FormattedTextControl (Renders formatted text, or a simple list of text fragments) + `- BufferControl (Renders an input buffer.) + + +Usually, you end up wrapping every control inside a `Window` object, because +that's the only way to render it in a layout. + +There are some prepared toolbars which are ready to use:: + +- SystemToolbar (Shows the 'system' input buffer, for entering system commands.) +- ArgToolbar (Shows the input 'arg', for repetition of input commands.) +- SearchToolbar (Shows the 'search' input buffer, for incremental search.) +- CompletionsToolbar (Shows the completions of the current buffer.) +- ValidationToolbar (Shows validation errors of the current buffer.) + +And one prepared menu: + +- CompletionsMenu + +""" +from .containers import ( + AnyContainer, + ColorColumn, + ConditionalContainer, + Container, + DynamicContainer, + Float, + FloatContainer, + HorizontalAlign, + HSplit, + ScrollOffsets, + VerticalAlign, + VSplit, + Window, + WindowAlign, + WindowRenderInfo, + is_container, + to_container, + to_window, +) +from .controls import ( + BufferControl, + DummyControl, + FormattedTextControl, + SearchBufferControl, + UIContent, + UIControl, +) +from .dimension import ( + AnyDimension, + D, + Dimension, + is_dimension, + max_layout_dimensions, + sum_layout_dimensions, + to_dimension, +) +from .layout import InvalidLayoutError, Layout, walk +from .margins import ( + ConditionalMargin, + Margin, + NumberedMargin, + PromptMargin, + ScrollbarMargin, +) +from .menus import CompletionsMenu, MultiColumnCompletionsMenu + +__all__ = [ + # Layout. + "Layout", + "InvalidLayoutError", + "walk", + # Dimensions. + "AnyDimension", + "Dimension", + "D", + "sum_layout_dimensions", + "max_layout_dimensions", + "to_dimension", + "is_dimension", + # Containers. + "AnyContainer", + "Container", + "HorizontalAlign", + "VerticalAlign", + "HSplit", + "VSplit", + "FloatContainer", + "Float", + "WindowAlign", + "Window", + "WindowRenderInfo", + "ConditionalContainer", + "ScrollOffsets", + "ColorColumn", + "to_container", + "to_window", + "is_container", + "DynamicContainer", + # Controls. + "BufferControl", + "SearchBufferControl", + "DummyControl", + "FormattedTextControl", + "UIControl", + "UIContent", + # Margins. + "Margin", + "NumberedMargin", + "ScrollbarMargin", + "ConditionalMargin", + "PromptMargin", + # Menus. + "CompletionsMenu", + "MultiColumnCompletionsMenu", +] diff --git a/.venv/lib/python3.8/site-packages/prompt_toolkit/layout/__pycache__/__init__.cpython-38.pyc b/.venv/lib/python3.8/site-packages/prompt_toolkit/layout/__pycache__/__init__.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b1a31f0a980eed906a8f96c00594769a21edbfc2 GIT binary patch literal 3319 zcmai0OK%%D5SCxEwU+#T$Bt>owk*ezk^nt4D2h69iv(!WpmtJ#7nxd8);8qsmRwm; zQJ|;(m;(JXz4Wlxp86MhX=g~i>Xa?Ezu>lOqa({--KLIt8`VZ(KWSB*VP8yP@8m9ZP6{eJ}K|1 zZMv;?=#IKi@2g$9s|Y1(kM5~`x^HEsP$WM8hS9p~_x-QX2{P9Jm^o0GA&1Agiky0$=Lw$zM#2Ln zLW9Ao^bZG>=&=?ihWVf_1!=%(poa?`gx7W>^OF{n)*umrt_Z?nd@V#+frFhFs0hu9 zbreTN5EH546HiGUtO$~#u^KT9&hK_J>X{0Vn(^*42vV0j+wLbo2HUQbXWZ9;A*OpVdvGAq=F> zz&9&dvQi-UQ<=QDh$V#l_(i0HA5ozMdthc*=3Q6jozO|(kCOOGMl2cFb3Ax;K4Ey7 zG*OQk1k%}Zv~rATpaRoB^r}q03ql^X$;Yak*T5_&rlIsg7F|eeIvtS*0eSlpO~R%B z3&>ZIRxC*bzZ4&=OLo(@mQ@BB=2l4p%cq!KAXK1$$WY!Uv1x-9($MT0oV@MRvsR-a zbl;MmQV32E#z3;VU9XfNxo-{dR(4JabPEE9lU7XHn#D0PTigiU>9Yxn8_EUjxNs)R1Ux}6D_b=mI`wiIG5fRoTvk|>gO z21V_XicLfd#;q#40-h?6T>Cjy??hG`%Y z&}#Jc2yHH4MW(NdP6rq%65CKQ2X6V6o(sXW-yET;Xza=;!-5cc1*Q>6Z>6kB(9j{_ zwt0`x2dDN{`&Hc15bU7@m&rRO1I|##9ThkI1tPSLu!nYA!CfWZ8Snzjpr0WuE1QKO z3tz#U=lum=@Jwkb&7Xyxes!j^&m$QDA!SR2=?ctq8$l)qBDulq!g(iTD)0w0Q?~Ha zx!d)h&JViDnGCMOH0#<-TDb6`oa8r+h7pNL3%!ogm2!+r%*(J5 zrTM_r{9X@C^GP%`%E72@J4h*;7H-vDnm=zTWrF~=q${HeK3#TfxxF#xx(FmP?Y@G7 z(zK1~dG8CAj-98u!3d4)f4$OG#Xi*B4PY>9(pC5xjF?83`g=C(&4lH+T8h4>Q5 zk!IZ>ooqAtzBH9CLUMXZd(0zue87)O{w$RXqr@II>HDw@$V2-67j z2y+Mv2$Kl22onfP2+IhI2yoxZ=oN%@gjIw!giVAEghPZQgkyvQgdzf7cl8Ot>(b+N zx>n_V+c!R)!Bc=v#u-1b z+qz-xMh|GNPY4%c8(kY`8&ex%8*GBoS;sY(7n>nW4&2l&GmP_n5Dyy#3<})o@dG`G z2!;c`N446o8C?MZ3x7YWCMvGRL0oQyaEW;@cp2_GLY6=Mq?R;)c+#xGoeC&cOW&s4-)QhbgL%3J|VR^F_TnS{b8( literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/prompt_toolkit/layout/__pycache__/containers.cpython-38.pyc b/.venv/lib/python3.8/site-packages/prompt_toolkit/layout/__pycache__/containers.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c86d55e6e8ec5276409c9e29198ca5cb6da76472 GIT binary patch literal 67630 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 literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/prompt_toolkit/layout/__pycache__/controls.cpython-38.pyc b/.venv/lib/python3.8/site-packages/prompt_toolkit/layout/__pycache__/controls.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..3e76aab2719886f732ba437bab4f2f6184d67aa1 GIT binary patch literal 27178 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 literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/prompt_toolkit/layout/__pycache__/layout.cpython-38.pyc b/.venv/lib/python3.8/site-packages/prompt_toolkit/layout/__pycache__/layout.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d7c8143be2eceda210c849cf736b44fb1267d1e5 GIT binary patch literal 10959 zcmcIqOK=>=d7jtKJ^(D1AP52!MUD6nu@bqIWyz9Yik1XXG;IcUOj49KRu+q$0kOb7 zz@C99Y%L|1z?9^JQgY5ZkhjohpHjKyreh91OfIQPB~`j6x0EI2`?`B(9{}a#kR_+l z-P5oC{ph(lHB~V1`|jgE)}DIVF#e5=;a>)g*YSjZK;auz!#91aWwx!V)wZj4+o?M3 zOf}PXt8P16&6<2~w{q=#HIKUEXIh2!M0KJ)S)FW8Rj1m;YOy_CotE$1R;hicdZ;~9 zooOGg9!6i*&-wY=c6Bz$21kN?a5$J)cNUE5+!ezw_}Tjyv1e6}qBY^?(8>k#dvhAo%QuV zd~I@xOg#BUXLq^ViRw+P5znIPH`SCuZ+=j9Z#6r9_ij8Hb!&}eTG@`L)T$gPx~=%| z^`I^q8>5~1n^%+f?llQXJae`4LA}-VRr9hCfWf(2Z*4UQ;qWgd=zrkgfl)OW*&ye;Uz#M%eW#ia3c&>4TkAH)u|Mw@&_4+R6m`#pKZ%~{ zz{R+!FD(#b8tqcx28U$3b3*r>@Snmtjs;JoJ)ZwG zdXCGPPwG)8{Zn%0i6Dpd*n1kMJL5ltkxyZy+V!lzC`WlIRAv8J+4D5u;klmk&tb+% z-8%1A&^o1C7yReZI*qfP(YyY@e*rzu4E6lbe-S-r^^BMNAEC9VTQB>spj8ge;DlV^ zRh)3i|1tWW^(~0NYhng0P`?I>7d-rKq#__CqV8>rZhJebMcr;|s~O2LON~}N43}0v z8huxRAhnu}I$68&#-P4h(JMDYuigr~-c}H7hh8M=jV-Uc?%myJHa5JS5JE_H2XA{A zx!!G{%dZsFmfLkvZ_D>mik9R-Pl|3gIyvawC&YwkNln%3)q+;g4m#12rz>96_11!9 zJFnS+Xx3Y;-HNxkT<`Ezy|Wu_G&{HDLAWB-#Hw6x)mz``GzhR)Z#07KD6Ev_uocK_ zJ{8`0dTjUD6+yHkIt_bB{v6b)ahLIgzd;cheRI$38#VK`fzoQSv}Nh^E#KJ6iB@mE zZ){o*GLhRi9%LUHd*(yaG;SGpK5&dEw^a}urg6_Ujb1Uz`&`Zb#JXj?1buza{>XmU zcn>4rH97^%F7z$Vm3vM22AIQI>0Q#=Bhib)4B~f#(Cc)ggaE{pr<9l1UE2&AQKdX7 zihx8MK@q#PFapiv$xv#pTC3UF3gc3(vC(Y#;IJAf1=7SWHFC#~olfv!6qnYa4r?Gu z?XJ{|VLWv`>TXLdOw5bJTstE%98Z7H44cr+$=I?JJ7LgTmj@7Y9BBrR3~>sz|9<^K z)ZV_Z-P}IE)7i$s0{{HojUZ^9fAytWv~lN!jSHg;enHs={im|M8|P{@GEA*@2J3|< zP#A8(baQUTwQ{Cq&YLBa)_0a=eLLqA?B2A}!j)uR*%U`HsXQr!u_FiU#lhFcxrRAu_U6ZrmkcXgaRzpMCr}I|sm4k85jrj) z8R+l8PE;h335xs@=e8uBp1o(G*NSZP&h)KKXEW0`w^%nGxJnVwVY_bJnTfK#)i>A8 zIVhJ;%rDH&CAnS>GrvsNTO3+%jqAzP*7mKoHo98pKjm6^to6@*usKh+l@2hSN9GOrgW2$_sVZvg@h^T@wETjskZ}K<)NkY z(1X`e`hIojCA{6lBEY0;L*QN2lH90=fp-`Gn-G7gv`3Y|_d%+*D*h*ojEXU8U{T9IB6 zt!)ay{!J7l-@gNocjJ*6PlQ{|?b=4u_k)fAFB-kd*v^9^gX6gKz)#{LqHGWdb@1}BN9*j0Fkib{qaBFBM;*gM$_Ybh-8bYiNAe)xdOZ=gz-%2YhV z8dbhH$KnYTaZUuFF}y@Ek7n6b*6jjcN!`mZDSKCY4Q3-Y?~Ypp9`6>O@UKxA#R63B z9IOIucka7fhV9w3?aDUoxnt+doRxEO)}&RWg*Tn=(3{C+9a#K%vuGDF%QXu&9@DY7 zT5mE@<>bJ|u)?;nH=kuZ;oqW=YK;o}G`&0Dgr_%8cb%nNJhT`Amj#61Uz0XqlUfu}cw!=@N z@{#hQG?pftw*jG~6iLbsBuIPVQW%y7qL(r^OuiU&ClZ+`r@=ZaZ{H|SNWK#<08w%3 z;V7;XFQRk6V*+^#V~CSdCW8AwH$f;~(V@T?bHsVTqB!*T7^~bnumA`Ow%}j)#JEbvsPsLAmA`qBH5l(KqD-aZPApIt`M2b`Q9u{<@kHtMP9jU$;5{0klp!Q+veNDt0w zZn;3O**oLi5Icd_L_z^Ey9hiLWg>9*MDzAW1m3t?@vytp2@BXo9Dqb=mC~92Iyg)3 zu*N2=R{DPAfFnqxfDws9;m~ok?FVp-A41%TRE^m8QV}?aKa{7T`J3*V&X?>168dv> zrP~Q~x`n>ZN;#vTrJWX}t03I5eLIK}GDy)LRSfZQ9iT^bfsr+(T4gR0GWPFSA*2;I zvaSUKY4uKN%zWRheVAf^(%@1Q#Z+;e7{V9AN8;-t^!ZpI*&4^#zEE$a23mJ~h^%Uw!L-4u~}w z@9ojT*u7t*z-m^jdoAR!>G`InW*l`=BaL8gfSZxSkpD?l=3_#NJ2Oe|mlz;_W^B0v zoc}xPj&pqoD+pq(%JYJ#LTYpMv=&$>3w?jc0~b>)LLOCqf!w z;9ty{Mf~e63^AF;upa$*&Ppu!K$%Jl`BlnK3Ba_Nuqit3-N#^wPY-{jp3Y4b#hWtD zODq%e`N4X9rxoE&VAoqiqz0UaUbw+vTjt)8 zT!+(#g+UOVTc>3McBL7YB#?;z8S#87Eu=7)G{RDM{1_2THiYdOr2fW7jUW~?pm8+g zGP>v$sbrPgehbWqJiCQFd&LB6no8|c6UPQ z-2;RBW2vvdg?BH#L8d`dA3rW!?fAimD$E|}Hi;93j%4XX;!h8x+fv+?WJAYC?n8;4 zpyVVf2t@(#9&FB*BTlf6+b8>PfChN}sDt~Q-fJn%uZ;Nd=kdf>IE7Gfmo(EQz zQmnk4rT}^E;b|LmL7r9StCV3LLJ3(@;pLGluCno$DB=vnDELq%Oc>qB9Lysf@Gi0A z28%IS(MaRoFA-_fAqEp1NN$wC90jXnjUkX@|GyD9|K|{R=>P;K-1~n+qPR}9+&lm` zMa3}5vX>u=pTszhjvv7hy(B&jJkkY7ga?V`0(~WUWm3?w!MiDRx8Q+7PNWB#UY%%5 z*XjDWiCe5A?1dyXagWLyHQWi6aV6(_yUhUF6mQxC=3z)CvuV7U(=KalHpjR^4!JoZ zLlattR=+=z)f(nStN5;0DT+Rv%f9d*&TCLNZGxpbE?wNYKw| z&^zA`IyHp63LbXub7xA?29ZhIL_~(nr#9irN3b-$^`-Tx@hNWq ze0+LwfAY8HXGA6tXBwYT#UeupWs(_Eu{XErSdyd^K^!;L2H-`hw( z!`cpGz!KEv`)?#kR-WuIo_*JSeV)O*Xy8opL~zbv_r!A;TQ=iKdO0aO>J5I3caN+% ztIicFMwI%9c1kvpgw!z+a&5@0o!5xmk$~x&;t=u~86c;IMR$2V62#!ylDx8<15u_#?@!k8K&f$CM58y!V^I*b7h}SRom58b zJ(-(;??S$^dfikMhcXnJsZu$V{x%KyARjE{Q(nicD&Knb9Gy-5843M3T;a$&mF}2_ zZAsyab3YGul|OTyKuIj5sE7;XEp?1fQi^3PFwBsxAB-vEX7)K=cGK0a)#5^pa=wF) z1#0nRt#)Up-qLTfwVK~;;8vW{EEt)`C25{%hcBxSNW>YwV-8vno5E%>xUL{|}LZo-~x9nYhN< zU$FQki(j#Lhs7-xlK-WKe~ZocS&(-`oy7o?DLUncK$Mk`E9FdQ%J>G~EgVQ+mTyoi<%`*3saTrH&J>H&#e4&+ zj{HC}<8?eCk2?6=j2tJw>7aAFhF5|!h0o%kV^b-8PV!3*H{ZrADFHv=gahMHB9m)| z#7rMIy)?n{e*74GG~7Uk$H@47gZ2nLkXIPzImD^>>;`wo*5}q`h{jLx_RgXd5nKCl zBSuSQo8fqLw&H(TU~DjJCe8URK0IfRPS z$)Mj63naPW@{^O?x0daGV`Uu6#WmGR8K^lf0=$jgXqT#A5MzpQ9o8h1k=sQUMfJ$& z*Dnj|790ws|7%Fb2N2zZ9AYc5Rr>4Ybo&7VMkiYyP zKcY%L>Jhj3M)L3hgpYF;; literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/prompt_toolkit/layout/__pycache__/margins.cpython-38.pyc b/.venv/lib/python3.8/site-packages/prompt_toolkit/layout/__pycache__/margins.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..dd712a2b64d22b631256dbb59a9dc99f546c3d2d GIT binary patch literal 8853 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 literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/prompt_toolkit/layout/__pycache__/menus.cpython-38.pyc b/.venv/lib/python3.8/site-packages/prompt_toolkit/layout/__pycache__/menus.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7b6a4445f73d5e2f2449ca9d17b9b01156631f5b GIT binary patch literal 20772 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 VIoBI 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 Y|5tjD?@%JHyL)U8u725gX6)Jj4}n&c+W-In literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/prompt_toolkit/layout/__pycache__/mouse_handlers.cpython-38.pyc b/.venv/lib/python3.8/site-packages/prompt_toolkit/layout/__pycache__/mouse_handlers.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..fe248dfde90f8f18d9b77948431db505282face9 GIT binary patch literal 1606 zcmah}OOG5i5VqaVd5T9E9zm#2D0A2u5s3rQYKfFZTg{D=Jm`9mD~%84^4I1sAZGwhBMfk&<`dt6mtRekn1gF%XOAh5uA{5_&azdW7_nDTqLzJBApvp2Bj`U4XV?G4-%!4Qze_;u|0DPXBzKOT`CDj zyI&P`CBOJV=B636`okm_O6qEkzHg2I7WZLRC?tugATbj(b_5g76%{U^b7NO}+n+Ck zB^7MJ-iKU;f8~ongm5Ah46t`}2yWJ&cOw{&o)(cvGnrRuktZtBNoAytibXUB_@~MI zNfj*$9c2hMl8CmNw3ai-!PnB%I-gT;xErWLLkKpY`WS?1%YVfX>~r@QV(3p~VL^wN zbVE231Yr5IF>88l9Nxy!9WZ{yHM&1R*BC=kFl6iF77(U`<6fEQB(sREr+d-k>ta8S z(!4TBK9@ERYZOJZ7tl|Qq|&{e`0L@+WaYF>%Y!;Ep%_veJUx?A9enmFH)rQ}&!*7u ztTfydg?f^jsY+HwZKgJjvu#5s<*FHqI?GmkSJk&L1qOo9^`r&2>;8oEG*1oZlS5U& z@#<)@Z~6*7uq1DzKP<`5SW7y)&fx{s1K774ebAclP$k)^NRB>$)gLg)`p*AB*qMwS zjcn8iy&3MO350MfsTMZW5Rch-yNuq1t;z>M=o{hi@Ac^QQOADcUGOZ;+fQ=Qcq_Yt z53GW1SuH0A_U;gaNW`=!RV~_&OW+60~FT-RN8P%zqYaybbxDZTwBJ zV29*snl16SA=|5vL|QK4wp`O^230}2H=a)NrPP?`IMmo?mz6tohIZwPcq4Q)8*h^ z)C%=J=jU~zw*Lg2i(<~XMk+N)C8$)GY)D;qIAGNN`jq`S z8~2;uyiiKc4V0|1yy>Ly#^8;qY}tIXD${&v<6#3eb~V1ef43&KF7^#-VKsmmUMawg boqruZ;JQus2ro&6Nc*%;Z?V3^Ub@~tcu$Jb literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/prompt_toolkit/layout/__pycache__/processors.cpython-38.pyc b/.venv/lib/python3.8/site-packages/prompt_toolkit/layout/__pycache__/processors.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ce0135690bad2aa12b8a10d83338a2502dc57784 GIT binary patch literal 28628 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 R95VAOws1*!FaWvdy$s?LWi6SJq*@J4#fW*e? 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 None: + """ + Reset the state of this container and all the children. + (E.g. reset scroll offsets, etc...) + """ + + @abstractmethod + def preferred_width(self, max_available_width: int) -> Dimension: + """ + Return a :class:`~prompt_toolkit.layout.Dimension` that represents the + desired width for this container. + """ + + @abstractmethod + def preferred_height(self, width: int, max_available_height: int) -> Dimension: + """ + Return a :class:`~prompt_toolkit.layout.Dimension` that represents the + desired height for this container. + """ + + @abstractmethod + def write_to_screen( + self, + screen: Screen, + mouse_handlers: MouseHandlers, + write_position: WritePosition, + parent_style: str, + erase_bg: bool, + z_index: Optional[int], + ) -> None: + """ + Write the actual content to the screen. + + :param screen: :class:`~prompt_toolkit.layout.screen.Screen` + :param mouse_handlers: :class:`~prompt_toolkit.layout.mouse_handlers.MouseHandlers`. + :param parent_style: Style string to pass to the :class:`.Window` + object. This will be applied to all content of the windows. + :class:`.VSplit` and :class:`.HSplit` can use it to pass their + style down to the windows that they contain. + :param z_index: Used for propagating z_index from parent to child. + """ + + def is_modal(self) -> bool: + """ + When this container is modal, key bindings from parent containers are + not taken into account if a user control in this container is focused. + """ + return False + + def get_key_bindings(self) -> Optional[KeyBindingsBase]: + """ + Returns a :class:`.KeyBindings` object. These bindings become active when any + user control in this container has the focus, except if any containers + between this container and the focused user control is modal. + """ + return None + + @abstractmethod + def get_children(self) -> List["Container"]: + """ + Return the list of child :class:`.Container` objects. + """ + return [] + + +if TYPE_CHECKING: + + class MagicContainer(Protocol): + """ + Any object that implements ``__pt_container__`` represents a container. + """ + + def __pt_container__(self) -> "AnyContainer": + ... + + +AnyContainer = Union[Container, "MagicContainer"] + + +def _window_too_small() -> "Window": + " Create a `Window` that displays the 'Window too small' text. " + return Window( + FormattedTextControl(text=[("class:window-too-small", " Window too small... ")]) + ) + + +class VerticalAlign(Enum): + " Alignment for `HSplit`. " + TOP = "TOP" + CENTER = "CENTER" + BOTTOM = "BOTTOM" + JUSTIFY = "JUSTIFY" + + +class HorizontalAlign(Enum): + " Alignment for `VSplit`. " + LEFT = "LEFT" + CENTER = "CENTER" + RIGHT = "RIGHT" + JUSTIFY = "JUSTIFY" + + +class _Split(Container): + """ + The common parts of `VSplit` and `HSplit`. + """ + + def __init__( + self, + children: Sequence[AnyContainer], + window_too_small: Optional[Container] = None, + padding: AnyDimension = Dimension.exact(0), + padding_char: Optional[str] = None, + padding_style: str = "", + width: AnyDimension = None, + height: AnyDimension = None, + z_index: Optional[int] = None, + modal: bool = False, + key_bindings: Optional[KeyBindingsBase] = None, + style: Union[str, Callable[[], str]] = "", + ) -> None: + + self.children = [to_container(c) for c in children] + self.window_too_small = window_too_small or _window_too_small() + self.padding = padding + self.padding_char = padding_char + self.padding_style = padding_style + + self.width = width + self.height = height + self.z_index = z_index + + self.modal = modal + self.key_bindings = key_bindings + self.style = style + + def is_modal(self) -> bool: + return self.modal + + def get_key_bindings(self) -> Optional[KeyBindingsBase]: + return self.key_bindings + + def get_children(self) -> List[Container]: + return self.children + + +class HSplit(_Split): + """ + Several layouts, one stacked above/under the other. :: + + +--------------------+ + | | + +--------------------+ + | | + +--------------------+ + + By default, this doesn't display a horizontal line between the children, + but if this is something you need, then create a HSplit as follows:: + + HSplit(children=[ ... ], padding_char='-', + padding=1, padding_style='#ffff00') + + :param children: List of child :class:`.Container` objects. + :param window_too_small: A :class:`.Container` object that is displayed if + there is not enough space for all the children. By default, this is a + "Window too small" message. + :param align: `VerticalAlign` value. + :param width: When given, use this width instead of looking at the children. + :param height: When given, use this height instead of looking at the children. + :param z_index: (int or None) When specified, this can be used to bring + element in front of floating elements. `None` means: inherit from parent. + :param style: A style string. + :param modal: ``True`` or ``False``. + :param key_bindings: ``None`` or a :class:`.KeyBindings` object. + + :param padding: (`Dimension` or int), size to be used for the padding. + :param padding_char: Character to be used for filling in the padding. + :param padding_style: Style to applied to the padding. + """ + + def __init__( + self, + children: Sequence[AnyContainer], + window_too_small: Optional[Container] = None, + align: VerticalAlign = VerticalAlign.JUSTIFY, + padding: AnyDimension = 0, + padding_char: Optional[str] = None, + padding_style: str = "", + width: AnyDimension = None, + height: AnyDimension = None, + z_index: Optional[int] = None, + modal: bool = False, + key_bindings: Optional[KeyBindingsBase] = None, + style: Union[str, Callable[[], str]] = "", + ) -> None: + + super().__init__( + children=children, + window_too_small=window_too_small, + padding=padding, + padding_char=padding_char, + padding_style=padding_style, + width=width, + height=height, + z_index=z_index, + modal=modal, + key_bindings=key_bindings, + style=style, + ) + + self.align = align + + self._children_cache: SimpleCache[ + Tuple[Container, ...], List[Container] + ] = SimpleCache(maxsize=1) + self._remaining_space_window = Window() # Dummy window. + + def preferred_width(self, max_available_width: int) -> Dimension: + if self.width is not None: + return to_dimension(self.width) + + if self.children: + dimensions = [c.preferred_width(max_available_width) for c in self.children] + return max_layout_dimensions(dimensions) + else: + return Dimension() + + def preferred_height(self, width: int, max_available_height: int) -> Dimension: + if self.height is not None: + return to_dimension(self.height) + + dimensions = [ + c.preferred_height(width, max_available_height) for c in self._all_children + ] + return sum_layout_dimensions(dimensions) + + def reset(self) -> None: + for c in self.children: + c.reset() + + @property + def _all_children(self) -> List[Container]: + """ + List of child objects, including padding. + """ + + def get() -> List[Container]: + result: List[Container] = [] + + # Padding Top. + if self.align in (VerticalAlign.CENTER, VerticalAlign.BOTTOM): + result.append(Window(width=Dimension(preferred=0))) + + # The children with padding. + for child in self.children: + result.append(child) + result.append( + Window( + height=self.padding, + char=self.padding_char, + style=self.padding_style, + ) + ) + if result: + result.pop() + + # Padding right. + if self.align in (VerticalAlign.CENTER, VerticalAlign.TOP): + result.append(Window(width=Dimension(preferred=0))) + + return result + + return self._children_cache.get(tuple(self.children), get) + + def write_to_screen( + self, + screen: Screen, + mouse_handlers: MouseHandlers, + write_position: WritePosition, + parent_style: str, + erase_bg: bool, + z_index: Optional[int], + ) -> None: + """ + Render the prompt to a `Screen` instance. + + :param screen: The :class:`~prompt_toolkit.layout.screen.Screen` class + to which the output has to be written. + """ + sizes = self._divide_heights(write_position) + style = parent_style + " " + to_str(self.style) + z_index = z_index if self.z_index is None else self.z_index + + if sizes is None: + self.window_too_small.write_to_screen( + screen, mouse_handlers, write_position, style, erase_bg, z_index + ) + else: + # + ypos = write_position.ypos + xpos = write_position.xpos + width = write_position.width + + # Draw child panes. + for s, c in zip(sizes, self._all_children): + c.write_to_screen( + screen, + mouse_handlers, + WritePosition(xpos, ypos, width, s), + style, + erase_bg, + z_index, + ) + ypos += s + + # Fill in the remaining space. This happens when a child control + # refuses to take more space and we don't have any padding. Adding a + # dummy child control for this (in `self._all_children`) is not + # desired, because in some situations, it would take more space, even + # when it's not required. This is required to apply the styling. + remaining_height = write_position.ypos + write_position.height - ypos + if remaining_height > 0: + self._remaining_space_window.write_to_screen( + screen, + mouse_handlers, + WritePosition(xpos, ypos, width, remaining_height), + style, + erase_bg, + z_index, + ) + + def _divide_heights(self, write_position: WritePosition) -> Optional[List[int]]: + """ + Return the heights for all rows. + Or None when there is not enough space. + """ + if not self.children: + return [] + + width = write_position.width + height = write_position.height + + # Calculate heights. + dimensions = [c.preferred_height(width, height) for c in self._all_children] + + # Sum dimensions + sum_dimensions = sum_layout_dimensions(dimensions) + + # If there is not enough space for both. + # Don't do anything. + if sum_dimensions.min > height: + return None + + # Find optimal sizes. (Start with minimal size, increase until we cover + # the whole height.) + sizes = [d.min for d in dimensions] + + child_generator = take_using_weights( + items=list(range(len(dimensions))), weights=[d.weight for d in dimensions] + ) + + i = next(child_generator) + + # Increase until we meet at least the 'preferred' size. + preferred_stop = min(height, sum_dimensions.preferred) + preferred_dimensions = [d.preferred for d in dimensions] + + while sum(sizes) < preferred_stop: + if sizes[i] < preferred_dimensions[i]: + sizes[i] += 1 + i = next(child_generator) + + # Increase until we use all the available space. (or until "max") + if not get_app().is_done: + max_stop = min(height, sum_dimensions.max) + max_dimensions = [d.max for d in dimensions] + + while sum(sizes) < max_stop: + if sizes[i] < max_dimensions[i]: + sizes[i] += 1 + i = next(child_generator) + + return sizes + + +class VSplit(_Split): + """ + Several layouts, one stacked left/right of the other. :: + + +---------+----------+ + | | | + | | | + +---------+----------+ + + By default, this doesn't display a vertical line between the children, but + if this is something you need, then create a HSplit as follows:: + + VSplit(children=[ ... ], padding_char='|', + padding=1, padding_style='#ffff00') + + :param children: List of child :class:`.Container` objects. + :param window_too_small: A :class:`.Container` object that is displayed if + there is not enough space for all the children. By default, this is a + "Window too small" message. + :param align: `HorizontalAlign` value. + :param width: When given, use this width instead of looking at the children. + :param height: When given, use this height instead of looking at the children. + :param z_index: (int or None) When specified, this can be used to bring + element in front of floating elements. `None` means: inherit from parent. + :param style: A style string. + :param modal: ``True`` or ``False``. + :param key_bindings: ``None`` or a :class:`.KeyBindings` object. + + :param padding: (`Dimension` or int), size to be used for the padding. + :param padding_char: Character to be used for filling in the padding. + :param padding_style: Style to applied to the padding. + """ + + def __init__( + self, + children: Sequence[AnyContainer], + window_too_small: Optional[Container] = None, + align: HorizontalAlign = HorizontalAlign.JUSTIFY, + padding: AnyDimension = 0, + padding_char: Optional[str] = None, + padding_style: str = "", + width: AnyDimension = None, + height: AnyDimension = None, + z_index: Optional[int] = None, + modal: bool = False, + key_bindings: Optional[KeyBindingsBase] = None, + style: Union[str, Callable[[], str]] = "", + ) -> None: + + super().__init__( + children=children, + window_too_small=window_too_small, + padding=padding, + padding_char=padding_char, + padding_style=padding_style, + width=width, + height=height, + z_index=z_index, + modal=modal, + key_bindings=key_bindings, + style=style, + ) + + self.align = align + + self._children_cache: SimpleCache[ + Tuple[Container, ...], List[Container] + ] = SimpleCache(maxsize=1) + self._remaining_space_window = Window() # Dummy window. + + def preferred_width(self, max_available_width: int) -> Dimension: + if self.width is not None: + return to_dimension(self.width) + + dimensions = [ + c.preferred_width(max_available_width) for c in self._all_children + ] + + return sum_layout_dimensions(dimensions) + + def preferred_height(self, width: int, max_available_height: int) -> Dimension: + if self.height is not None: + return to_dimension(self.height) + + # At the point where we want to calculate the heights, the widths have + # already been decided. So we can trust `width` to be the actual + # `width` that's going to be used for the rendering. So, + # `divide_widths` is supposed to use all of the available width. + # Using only the `preferred` width caused a bug where the reported + # height was more than required. (we had a `BufferControl` which did + # wrap lines because of the smaller width returned by `_divide_widths`. + + sizes = self._divide_widths(width) + children = self._all_children + + if sizes is None: + return Dimension() + else: + dimensions = [ + c.preferred_height(s, max_available_height) + for s, c in zip(sizes, children) + ] + return max_layout_dimensions(dimensions) + + def reset(self) -> None: + for c in self.children: + c.reset() + + @property + def _all_children(self) -> List[Container]: + """ + List of child objects, including padding. + """ + + def get() -> List[Container]: + result: List[Container] = [] + + # Padding left. + if self.align in (HorizontalAlign.CENTER, HorizontalAlign.RIGHT): + result.append(Window(width=Dimension(preferred=0))) + + # The children with padding. + for child in self.children: + result.append(child) + result.append( + Window( + width=self.padding, + char=self.padding_char, + style=self.padding_style, + ) + ) + if result: + result.pop() + + # Padding right. + if self.align in (HorizontalAlign.CENTER, HorizontalAlign.LEFT): + result.append(Window(width=Dimension(preferred=0))) + + return result + + return self._children_cache.get(tuple(self.children), get) + + def _divide_widths(self, width: int) -> Optional[List[int]]: + """ + Return the widths for all columns. + Or None when there is not enough space. + """ + children = self._all_children + + if not children: + return [] + + # Calculate widths. + dimensions = [c.preferred_width(width) for c in children] + preferred_dimensions = [d.preferred for d in dimensions] + + # Sum dimensions + sum_dimensions = sum_layout_dimensions(dimensions) + + # If there is not enough space for both. + # Don't do anything. + if sum_dimensions.min > width: + return None + + # Find optimal sizes. (Start with minimal size, increase until we cover + # the whole width.) + sizes = [d.min for d in dimensions] + + child_generator = take_using_weights( + items=list(range(len(dimensions))), weights=[d.weight for d in dimensions] + ) + + i = next(child_generator) + + # Increase until we meet at least the 'preferred' size. + preferred_stop = min(width, sum_dimensions.preferred) + + while sum(sizes) < preferred_stop: + if sizes[i] < preferred_dimensions[i]: + sizes[i] += 1 + i = next(child_generator) + + # Increase until we use all the available space. + max_dimensions = [d.max for d in dimensions] + max_stop = min(width, sum_dimensions.max) + + while sum(sizes) < max_stop: + if sizes[i] < max_dimensions[i]: + sizes[i] += 1 + i = next(child_generator) + + return sizes + + def write_to_screen( + self, + screen: Screen, + mouse_handlers: MouseHandlers, + write_position: WritePosition, + parent_style: str, + erase_bg: bool, + z_index: Optional[int], + ) -> None: + """ + Render the prompt to a `Screen` instance. + + :param screen: The :class:`~prompt_toolkit.layout.screen.Screen` class + to which the output has to be written. + """ + if not self.children: + return + + children = self._all_children + sizes = self._divide_widths(write_position.width) + style = parent_style + " " + to_str(self.style) + z_index = z_index if self.z_index is None else self.z_index + + # If there is not enough space. + if sizes is None: + self.window_too_small.write_to_screen( + screen, mouse_handlers, write_position, style, erase_bg, z_index + ) + return + + # Calculate heights, take the largest possible, but not larger than + # write_position.height. + heights = [ + child.preferred_height(width, write_position.height).preferred + for width, child in zip(sizes, children) + ] + height = max(write_position.height, min(write_position.height, max(heights))) + + # + ypos = write_position.ypos + xpos = write_position.xpos + + # Draw all child panes. + for s, c in zip(sizes, children): + c.write_to_screen( + screen, + mouse_handlers, + WritePosition(xpos, ypos, s, height), + style, + erase_bg, + z_index, + ) + xpos += s + + # Fill in the remaining space. This happens when a child control + # refuses to take more space and we don't have any padding. Adding a + # dummy child control for this (in `self._all_children`) is not + # desired, because in some situations, it would take more space, even + # when it's not required. This is required to apply the styling. + remaining_width = write_position.xpos + write_position.width - xpos + if remaining_width > 0: + self._remaining_space_window.write_to_screen( + screen, + mouse_handlers, + WritePosition(xpos, ypos, remaining_width, height), + style, + erase_bg, + z_index, + ) + + +class FloatContainer(Container): + """ + Container which can contain another container for the background, as well + as a list of floating containers on top of it. + + Example Usage:: + + FloatContainer(content=Window(...), + floats=[ + Float(xcursor=True, + ycursor=True, + layout=CompletionMenu(...)) + ]) + + :param z_index: (int or None) When specified, this can be used to bring + element in front of floating elements. `None` means: inherit from parent. + This is the z_index for the whole `Float` container as a whole. + """ + + def __init__( + self, + content: AnyContainer, + floats: List["Float"], + modal: bool = False, + key_bindings: Optional[KeyBindingsBase] = None, + style: Union[str, Callable[[], str]] = "", + z_index: Optional[int] = None, + ) -> None: + + self.content = to_container(content) + self.floats = floats + + self.modal = modal + self.key_bindings = key_bindings + self.style = style + self.z_index = z_index + + def reset(self) -> None: + self.content.reset() + + for f in self.floats: + f.content.reset() + + def preferred_width(self, max_available_width: int) -> Dimension: + return self.content.preferred_width(max_available_width) + + def preferred_height(self, width: int, max_available_height: int) -> Dimension: + """ + Return the preferred height of the float container. + (We don't care about the height of the floats, they should always fit + into the dimensions provided by the container.) + """ + return self.content.preferred_height(width, max_available_height) + + def write_to_screen( + self, + screen: Screen, + mouse_handlers: MouseHandlers, + write_position: WritePosition, + parent_style: str, + erase_bg: bool, + z_index: Optional[int], + ) -> None: + style = parent_style + " " + to_str(self.style) + z_index = z_index if self.z_index is None else self.z_index + + self.content.write_to_screen( + screen, mouse_handlers, write_position, style, erase_bg, z_index + ) + + for number, fl in enumerate(self.floats): + # z_index of a Float is computed by summing the z_index of the + # container and the `Float`. + new_z_index = (z_index or 0) + fl.z_index + style = parent_style + " " + to_str(self.style) + + # If the float that we have here, is positioned relative to the + # cursor position, but the Window that specifies the cursor + # position is not drawn yet, because it's a Float itself, we have + # to postpone this calculation. (This is a work-around, but good + # enough for now.) + postpone = fl.xcursor is not None or fl.ycursor is not None + + if postpone: + new_z_index = ( + number + 10 ** 8 + ) # Draw as late as possible, but keep the order. + screen.draw_with_z_index( + z_index=new_z_index, + draw_func=partial( + self._draw_float, + fl, + screen, + mouse_handlers, + write_position, + style, + erase_bg, + new_z_index, + ), + ) + else: + self._draw_float( + fl, + screen, + mouse_handlers, + write_position, + style, + erase_bg, + new_z_index, + ) + + def _draw_float( + self, + fl: "Float", + screen: Screen, + mouse_handlers: MouseHandlers, + write_position: WritePosition, + style: str, + erase_bg: bool, + z_index: Optional[int], + ) -> None: + " Draw a single Float. " + # When a menu_position was given, use this instead of the cursor + # position. (These cursor positions are absolute, translate again + # relative to the write_position.) + # Note: This should be inside the for-loop, because one float could + # set the cursor position to be used for the next one. + cpos = screen.get_menu_position( + fl.attach_to_window or get_app().layout.current_window + ) + cursor_position = Point( + x=cpos.x - write_position.xpos, y=cpos.y - write_position.ypos + ) + + fl_width = fl.get_width() + fl_height = fl.get_height() + width: int + height: int + xpos: int + ypos: int + + # Left & width given. + if fl.left is not None and fl_width is not None: + xpos = fl.left + width = fl_width + # Left & right given -> calculate width. + elif fl.left is not None and fl.right is not None: + xpos = fl.left + width = write_position.width - fl.left - fl.right + # Width & right given -> calculate left. + elif fl_width is not None and fl.right is not None: + xpos = write_position.width - fl.right - fl_width + width = fl_width + # Near x position of cursor. + elif fl.xcursor: + if fl_width is None: + width = fl.content.preferred_width(write_position.width).preferred + width = min(write_position.width, width) + else: + width = fl_width + + xpos = cursor_position.x + if xpos + width > write_position.width: + xpos = max(0, write_position.width - width) + # Only width given -> center horizontally. + elif fl_width: + xpos = int((write_position.width - fl_width) / 2) + width = fl_width + # Otherwise, take preferred width from float content. + else: + width = fl.content.preferred_width(write_position.width).preferred + + if fl.left is not None: + xpos = fl.left + elif fl.right is not None: + xpos = max(0, write_position.width - width - fl.right) + else: # Center horizontally. + xpos = max(0, int((write_position.width - width) / 2)) + + # Trim. + width = min(width, write_position.width - xpos) + + # Top & height given. + if fl.top is not None and fl_height is not None: + ypos = fl.top + height = fl_height + # Top & bottom given -> calculate height. + elif fl.top is not None and fl.bottom is not None: + ypos = fl.top + height = write_position.height - fl.top - fl.bottom + # Height & bottom given -> calculate top. + elif fl_height is not None and fl.bottom is not None: + ypos = write_position.height - fl_height - fl.bottom + height = fl_height + # Near cursor. + elif fl.ycursor: + ypos = cursor_position.y + (0 if fl.allow_cover_cursor else 1) + + if fl_height is None: + height = fl.content.preferred_height( + width, write_position.height + ).preferred + else: + height = fl_height + + # Reduce height if not enough space. (We can use the height + # when the content requires it.) + if height > write_position.height - ypos: + if write_position.height - ypos + 1 >= ypos: + # When the space below the cursor is more than + # the space above, just reduce the height. + height = write_position.height - ypos + else: + # Otherwise, fit the float above the cursor. + height = min(height, cursor_position.y) + ypos = cursor_position.y - height + + # Only height given -> center vertically. + elif fl_height: + ypos = int((write_position.height - fl_height) / 2) + height = fl_height + # Otherwise, take preferred height from content. + else: + height = fl.content.preferred_height(width, write_position.height).preferred + + if fl.top is not None: + ypos = fl.top + elif fl.bottom is not None: + ypos = max(0, write_position.height - height - fl.bottom) + else: # Center vertically. + ypos = max(0, int((write_position.height - height) / 2)) + + # Trim. + height = min(height, write_position.height - ypos) + + # Write float. + # (xpos and ypos can be negative: a float can be partially visible.) + if height > 0 and width > 0: + wp = WritePosition( + xpos=xpos + write_position.xpos, + ypos=ypos + write_position.ypos, + width=width, + height=height, + ) + + if not fl.hide_when_covering_content or self._area_is_empty(screen, wp): + fl.content.write_to_screen( + screen, + mouse_handlers, + wp, + style, + erase_bg=not fl.transparent(), + z_index=z_index, + ) + + def _area_is_empty(self, screen: Screen, write_position: WritePosition) -> bool: + """ + Return True when the area below the write position is still empty. + (For floats that should not hide content underneath.) + """ + wp = write_position + + for y in range(wp.ypos, wp.ypos + wp.height): + if y in screen.data_buffer: + row = screen.data_buffer[y] + + for x in range(wp.xpos, wp.xpos + wp.width): + c = row[x] + if c.char != " ": + return False + + return True + + def is_modal(self) -> bool: + return self.modal + + def get_key_bindings(self) -> Optional[KeyBindingsBase]: + return self.key_bindings + + def get_children(self) -> List[Container]: + children = [self.content] + children.extend(f.content for f in self.floats) + return children + + +class Float: + """ + Float for use in a :class:`.FloatContainer`. + Except for the `content` parameter, all other options are optional. + + :param content: :class:`.Container` instance. + + :param width: :class:`.Dimension` or callable which returns a :class:`.Dimension`. + :param height: :class:`.Dimension` or callable which returns a :class:`.Dimension`. + + :param left: Distance to the left edge of the :class:`.FloatContainer`. + :param right: Distance to the right edge of the :class:`.FloatContainer`. + :param top: Distance to the top of the :class:`.FloatContainer`. + :param bottom: Distance to the bottom of the :class:`.FloatContainer`. + + :param attach_to_window: Attach to the cursor from this window, instead of + the current window. + :param hide_when_covering_content: Hide the float when it covers content underneath. + :param allow_cover_cursor: When `False`, make sure to display the float + below the cursor. Not on top of the indicated position. + :param z_index: Z-index position. For a Float, this needs to be at least + one. It is relative to the z_index of the parent container. + :param transparent: :class:`.Filter` indicating whether this float needs to be + drawn transparently. + """ + + def __init__( + self, + content: AnyContainer, + top: Optional[int] = None, + right: Optional[int] = None, + bottom: Optional[int] = None, + left: Optional[int] = None, + width: Optional[Union[int, Callable[[], int]]] = None, + height: Optional[Union[int, Callable[[], int]]] = None, + xcursor: bool = False, + ycursor: bool = False, + attach_to_window: Optional[AnyContainer] = None, + hide_when_covering_content: bool = False, + allow_cover_cursor: bool = False, + z_index: int = 1, + transparent: bool = False, + ): + + assert z_index >= 1 + + self.left = left + self.right = right + self.top = top + self.bottom = bottom + + self.width = width + self.height = height + + self.xcursor = xcursor + self.ycursor = ycursor + + self.attach_to_window = ( + to_window(attach_to_window) if attach_to_window else None + ) + + self.content = to_container(content) + self.hide_when_covering_content = hide_when_covering_content + self.allow_cover_cursor = allow_cover_cursor + self.z_index = z_index + self.transparent = to_filter(transparent) + + def get_width(self) -> Optional[int]: + if callable(self.width): + return self.width() + return self.width + + def get_height(self) -> Optional[int]: + if callable(self.height): + return self.height() + return self.height + + def __repr__(self) -> str: + return "Float(content=%r)" % self.content + + +class WindowRenderInfo: + """ + Render information for the last render time of this control. + It stores mapping information between the input buffers (in case of a + :class:`~prompt_toolkit.layout.controls.BufferControl`) and the actual + render position on the output screen. + + (Could be used for implementation of the Vi 'H' and 'L' key bindings as + well as implementing mouse support.) + + :param ui_content: The original :class:`.UIContent` instance that contains + the whole input, without clipping. (ui_content) + :param horizontal_scroll: The horizontal scroll of the :class:`.Window` instance. + :param vertical_scroll: The vertical scroll of the :class:`.Window` instance. + :param window_width: The width of the window that displays the content, + without the margins. + :param window_height: The height of the window that displays the content. + :param configured_scroll_offsets: The scroll offsets as configured for the + :class:`Window` instance. + :param visible_line_to_row_col: Mapping that maps the row numbers on the + displayed screen (starting from zero for the first visible line) to + (row, col) tuples pointing to the row and column of the :class:`.UIContent`. + :param rowcol_to_yx: Mapping that maps (row, column) tuples representing + coordinates of the :class:`UIContent` to (y, x) absolute coordinates at + the rendered screen. + """ + + def __init__( + self, + window: "Window", + ui_content: UIContent, + horizontal_scroll: int, + vertical_scroll: int, + window_width: int, + window_height: int, + configured_scroll_offsets: "ScrollOffsets", + visible_line_to_row_col: Dict[int, Tuple[int, int]], + rowcol_to_yx: Dict[Tuple[int, int], Tuple[int, int]], + x_offset: int, + y_offset: int, + wrap_lines: bool, + ) -> None: + + self.window = window + self.ui_content = ui_content + self.vertical_scroll = vertical_scroll + self.window_width = window_width # Width without margins. + self.window_height = window_height + + self.configured_scroll_offsets = configured_scroll_offsets + self.visible_line_to_row_col = visible_line_to_row_col + self.wrap_lines = wrap_lines + + self._rowcol_to_yx = rowcol_to_yx # row/col from input to absolute y/x + # screen coordinates. + self._x_offset = x_offset + self._y_offset = y_offset + + @property + def visible_line_to_input_line(self) -> Dict[int, int]: + return { + visible_line: rowcol[0] + for visible_line, rowcol in self.visible_line_to_row_col.items() + } + + @property + def cursor_position(self) -> Point: + """ + Return the cursor position coordinates, relative to the left/top corner + of the rendered screen. + """ + cpos = self.ui_content.cursor_position + try: + y, x = self._rowcol_to_yx[cpos.y, cpos.x] + except KeyError: + # For `DummyControl` for instance, the content can be empty, and so + # will `_rowcol_to_yx` be. Return 0/0 by default. + return Point(x=0, y=0) + else: + return Point(x=x - self._x_offset, y=y - self._y_offset) + + @property + def applied_scroll_offsets(self) -> "ScrollOffsets": + """ + Return a :class:`.ScrollOffsets` instance that indicates the actual + offset. This can be less than or equal to what's configured. E.g, when + the cursor is completely at the top, the top offset will be zero rather + than what's configured. + """ + if self.displayed_lines[0] == 0: + top = 0 + else: + # Get row where the cursor is displayed. + y = self.input_line_to_visible_line[self.ui_content.cursor_position.y] + top = min(y, self.configured_scroll_offsets.top) + + return ScrollOffsets( + top=top, + bottom=min( + self.ui_content.line_count - self.displayed_lines[-1] - 1, + self.configured_scroll_offsets.bottom, + ), + # For left/right, it probably doesn't make sense to return something. + # (We would have to calculate the widths of all the lines and keep + # double width characters in mind.) + left=0, + right=0, + ) + + @property + def displayed_lines(self) -> List[int]: + """ + List of all the visible rows. (Line numbers of the input buffer.) + The last line may not be entirely visible. + """ + return sorted(row for row, col in self.visible_line_to_row_col.values()) + + @property + def input_line_to_visible_line(self) -> Dict[int, int]: + """ + Return the dictionary mapping the line numbers of the input buffer to + the lines of the screen. When a line spans several rows at the screen, + the first row appears in the dictionary. + """ + result: Dict[int, int] = {} + for k, v in self.visible_line_to_input_line.items(): + if v in result: + result[v] = min(result[v], k) + else: + result[v] = k + return result + + def first_visible_line(self, after_scroll_offset: bool = False) -> int: + """ + Return the line number (0 based) of the input document that corresponds + with the first visible line. + """ + if after_scroll_offset: + return self.displayed_lines[self.applied_scroll_offsets.top] + else: + return self.displayed_lines[0] + + def last_visible_line(self, before_scroll_offset: bool = False) -> int: + """ + Like `first_visible_line`, but for the last visible line. + """ + if before_scroll_offset: + return self.displayed_lines[-1 - self.applied_scroll_offsets.bottom] + else: + return self.displayed_lines[-1] + + def center_visible_line( + self, before_scroll_offset: bool = False, after_scroll_offset: bool = False + ) -> int: + """ + Like `first_visible_line`, but for the center visible line. + """ + return ( + self.first_visible_line(after_scroll_offset) + + ( + self.last_visible_line(before_scroll_offset) + - self.first_visible_line(after_scroll_offset) + ) + // 2 + ) + + @property + def content_height(self) -> int: + """ + The full height of the user control. + """ + return self.ui_content.line_count + + @property + def full_height_visible(self) -> bool: + """ + True when the full height is visible (There is no vertical scroll.) + """ + return ( + self.vertical_scroll == 0 + and self.last_visible_line() == self.content_height + ) + + @property + def top_visible(self) -> bool: + """ + True when the top of the buffer is visible. + """ + return self.vertical_scroll == 0 + + @property + def bottom_visible(self) -> bool: + """ + True when the bottom of the buffer is visible. + """ + return self.last_visible_line() == self.content_height - 1 + + @property + def vertical_scroll_percentage(self) -> int: + """ + Vertical scroll as a percentage. (0 means: the top is visible, + 100 means: the bottom is visible.) + """ + if self.bottom_visible: + return 100 + else: + return 100 * self.vertical_scroll // self.content_height + + def get_height_for_line(self, lineno: int) -> int: + """ + Return the height of the given line. + (The height that it would take, if this line became visible.) + """ + if self.wrap_lines: + return self.ui_content.get_height_for_line( + lineno, self.window_width, self.window.get_line_prefix + ) + else: + return 1 + + +class ScrollOffsets: + """ + Scroll offsets for the :class:`.Window` class. + + Note that left/right offsets only make sense if line wrapping is disabled. + """ + + def __init__( + self, + top: Union[int, Callable[[], int]] = 0, + bottom: Union[int, Callable[[], int]] = 0, + left: Union[int, Callable[[], int]] = 0, + right: Union[int, Callable[[], int]] = 0, + ) -> None: + + self._top = top + self._bottom = bottom + self._left = left + self._right = right + + @property + def top(self) -> int: + return to_int(self._top) + + @property + def bottom(self) -> int: + return to_int(self._bottom) + + @property + def left(self) -> int: + return to_int(self._left) + + @property + def right(self) -> int: + return to_int(self._right) + + def __repr__(self) -> str: + return "ScrollOffsets(top=%r, bottom=%r, left=%r, right=%r)" % ( + self._top, + self._bottom, + self._left, + self._right, + ) + + +class ColorColumn: + """ + Column for a :class:`.Window` to be colored. + """ + + def __init__(self, position: int, style: str = "class:color-column") -> None: + self.position = position + self.style = style + + +_in_insert_mode = vi_insert_mode | emacs_insert_mode + + +class WindowAlign(Enum): + """ + Alignment of the Window content. + + Note that this is different from `HorizontalAlign` and `VerticalAlign`, + which are used for the alignment of the child containers in respectively + `VSplit` and `HSplit`. + """ + + LEFT = "LEFT" + RIGHT = "RIGHT" + CENTER = "CENTER" + + +class Window(Container): + """ + Container that holds a control. + + :param content: :class:`.UIControl` instance. + :param width: :class:`.Dimension` instance or callable. + :param height: :class:`.Dimension` instance or callable. + :param z_index: When specified, this can be used to bring element in front + of floating elements. + :param dont_extend_width: When `True`, don't take up more width then the + preferred width reported by the control. + :param dont_extend_height: When `True`, don't take up more width then the + preferred height reported by the control. + :param ignore_content_width: A `bool` or :class:`.Filter` instance. Ignore + the :class:`.UIContent` width when calculating the dimensions. + :param ignore_content_height: A `bool` or :class:`.Filter` instance. Ignore + the :class:`.UIContent` height when calculating the dimensions. + :param left_margins: A list of :class:`.Margin` instance to be displayed on + the left. For instance: :class:`~prompt_toolkit.layout.NumberedMargin` + can be one of them in order to show line numbers. + :param right_margins: Like `left_margins`, but on the other side. + :param scroll_offsets: :class:`.ScrollOffsets` instance, representing the + preferred amount of lines/columns to be always visible before/after the + cursor. When both top and bottom are a very high number, the cursor + will be centered vertically most of the time. + :param allow_scroll_beyond_bottom: A `bool` or + :class:`.Filter` instance. When True, allow scrolling so far, that the + top part of the content is not visible anymore, while there is still + empty space available at the bottom of the window. In the Vi editor for + instance, this is possible. You will see tildes while the top part of + the body is hidden. + :param wrap_lines: A `bool` or :class:`.Filter` instance. When True, don't + scroll horizontally, but wrap lines instead. + :param get_vertical_scroll: Callable that takes this window + instance as input and returns a preferred vertical scroll. + (When this is `None`, the scroll is only determined by the last and + current cursor position.) + :param get_horizontal_scroll: Callable that takes this window + instance as input and returns a preferred vertical scroll. + :param always_hide_cursor: A `bool` or + :class:`.Filter` instance. When True, never display the cursor, even + when the user control specifies a cursor position. + :param cursorline: A `bool` or :class:`.Filter` instance. When True, + display a cursorline. + :param cursorcolumn: A `bool` or :class:`.Filter` instance. When True, + display a cursorcolumn. + :param colorcolumns: A list of :class:`.ColorColumn` instances that + describe the columns to be highlighted, or a callable that returns such + a list. + :param align: :class:`.WindowAlign` value or callable that returns an + :class:`.WindowAlign` value. alignment of content. + :param style: A style string. Style to be applied to all the cells in this + window. (This can be a callable that returns a string.) + :param char: (string) Character to be used for filling the background. This + can also be a callable that returns a character. + :param get_line_prefix: None or a callable that returns formatted text to + be inserted before a line. It takes a line number (int) and a + wrap_count and returns formatted text. This can be used for + implementation of line continuations, things like Vim "breakindent" and + so on. + """ + + def __init__( + self, + content: Optional[UIControl] = None, + width: AnyDimension = None, + height: AnyDimension = None, + z_index: Optional[int] = None, + dont_extend_width: FilterOrBool = False, + dont_extend_height: FilterOrBool = False, + ignore_content_width: FilterOrBool = False, + ignore_content_height: FilterOrBool = False, + left_margins: Optional[Sequence[Margin]] = None, + right_margins: Optional[Sequence[Margin]] = None, + scroll_offsets: Optional[ScrollOffsets] = None, + allow_scroll_beyond_bottom: FilterOrBool = False, + wrap_lines: FilterOrBool = False, + get_vertical_scroll: Optional[Callable[["Window"], int]] = None, + get_horizontal_scroll: Optional[Callable[["Window"], int]] = None, + always_hide_cursor: FilterOrBool = False, + cursorline: FilterOrBool = False, + cursorcolumn: FilterOrBool = False, + colorcolumns: Union[ + None, List[ColorColumn], Callable[[], List[ColorColumn]] + ] = None, + align: Union[WindowAlign, Callable[[], WindowAlign]] = WindowAlign.LEFT, + style: Union[str, Callable[[], str]] = "", + char: Union[None, str, Callable[[], str]] = None, + get_line_prefix: Optional[GetLinePrefixCallable] = None, + ) -> None: + + self.allow_scroll_beyond_bottom = to_filter(allow_scroll_beyond_bottom) + self.always_hide_cursor = to_filter(always_hide_cursor) + self.wrap_lines = to_filter(wrap_lines) + self.cursorline = to_filter(cursorline) + self.cursorcolumn = to_filter(cursorcolumn) + + self.content = content or DummyControl() + self.dont_extend_width = to_filter(dont_extend_width) + self.dont_extend_height = to_filter(dont_extend_height) + self.ignore_content_width = to_filter(ignore_content_width) + self.ignore_content_height = to_filter(ignore_content_height) + self.left_margins = left_margins or [] + self.right_margins = right_margins or [] + self.scroll_offsets = scroll_offsets or ScrollOffsets() + self.get_vertical_scroll = get_vertical_scroll + self.get_horizontal_scroll = get_horizontal_scroll + self.colorcolumns = colorcolumns or [] + self.align = align + self.style = style + self.char = char + self.get_line_prefix = get_line_prefix + + self.width = width + self.height = height + self.z_index = z_index + + # Cache for the screens generated by the margin. + self._ui_content_cache: SimpleCache[ + Tuple[int, int, int], UIContent + ] = SimpleCache(maxsize=8) + self._margin_width_cache: SimpleCache[Tuple[Margin, int], int] = SimpleCache( + maxsize=1 + ) + + self.reset() + + def __repr__(self) -> str: + return "Window(content=%r)" % self.content + + def reset(self) -> None: + self.content.reset() + + #: Scrolling position of the main content. + self.vertical_scroll = 0 + self.horizontal_scroll = 0 + + # Vertical scroll 2: this is the vertical offset that a line is + # scrolled if a single line (the one that contains the cursor) consumes + # all of the vertical space. + self.vertical_scroll_2 = 0 + + #: Keep render information (mappings between buffer input and render + #: output.) + self.render_info: Optional[WindowRenderInfo] = None + + def _get_margin_width(self, margin: Margin) -> int: + """ + Return the width for this margin. + (Calculate only once per render time.) + """ + # Margin.get_width, needs to have a UIContent instance. + def get_ui_content() -> UIContent: + return self._get_ui_content(width=0, height=0) + + def get_width() -> int: + return margin.get_width(get_ui_content) + + key = (margin, get_app().render_counter) + return self._margin_width_cache.get(key, get_width) + + def _get_total_margin_width(self) -> int: + """ + Calculate and return the width of the margin (left + right). + """ + return sum(self._get_margin_width(m) for m in self.left_margins) + sum( + self._get_margin_width(m) for m in self.right_margins + ) + + def preferred_width(self, max_available_width: int) -> Dimension: + """ + Calculate the preferred width for this window. + """ + + def preferred_content_width() -> Optional[int]: + """Content width: is only calculated if no exact width for the + window was given.""" + if self.ignore_content_width(): + return None + + # Calculate the width of the margin. + total_margin_width = self._get_total_margin_width() + + # Window of the content. (Can be `None`.) + preferred_width = self.content.preferred_width( + max_available_width - total_margin_width + ) + + if preferred_width is not None: + # Include width of the margins. + preferred_width += total_margin_width + return preferred_width + + # Merge. + return self._merge_dimensions( + dimension=to_dimension(self.width), + get_preferred=preferred_content_width, + dont_extend=self.dont_extend_width(), + ) + + def preferred_height(self, width: int, max_available_height: int) -> Dimension: + """ + Calculate the preferred height for this window. + """ + + def preferred_content_height() -> Optional[int]: + """Content height: is only calculated if no exact height for the + window was given.""" + if self.ignore_content_height(): + return None + + total_margin_width = self._get_total_margin_width() + wrap_lines = self.wrap_lines() + + return self.content.preferred_height( + width - total_margin_width, + max_available_height, + wrap_lines, + self.get_line_prefix, + ) + + return self._merge_dimensions( + dimension=to_dimension(self.height), + get_preferred=preferred_content_height, + dont_extend=self.dont_extend_height(), + ) + + @staticmethod + def _merge_dimensions( + dimension: Optional[Dimension], + get_preferred: Callable[[], Optional[int]], + dont_extend: bool = False, + ) -> Dimension: + """ + Take the Dimension from this `Window` class and the received preferred + size from the `UIControl` and return a `Dimension` to report to the + parent container. + """ + dimension = dimension or Dimension() + + # When a preferred dimension was explicitly given to the Window, + # ignore the UIControl. + preferred: Optional[int] + + if dimension.preferred_specified: + preferred = dimension.preferred + else: + # Otherwise, calculate the preferred dimension from the UI control + # content. + preferred = get_preferred() + + # When a 'preferred' dimension is given by the UIControl, make sure + # that it stays within the bounds of the Window. + if preferred is not None: + if dimension.max_specified: + preferred = min(preferred, dimension.max) + + if dimension.min_specified: + preferred = max(preferred, dimension.min) + + # When a `dont_extend` flag has been given, use the preferred dimension + # also as the max dimension. + max_: Optional[int] + min_: Optional[int] + + if dont_extend and preferred is not None: + max_ = min(dimension.max, preferred) + else: + max_ = dimension.max if dimension.max_specified else None + + min_ = dimension.min if dimension.min_specified else None + + return Dimension( + min=min_, max=max_, preferred=preferred, weight=dimension.weight + ) + + def _get_ui_content(self, width: int, height: int) -> UIContent: + """ + Create a `UIContent` instance. + """ + + def get_content() -> UIContent: + return self.content.create_content(width=width, height=height) + + key = (get_app().render_counter, width, height) + return self._ui_content_cache.get(key, get_content) + + def _get_digraph_char(self) -> Optional[str]: + " Return `False`, or the Digraph symbol to be used. " + app = get_app() + if app.quoted_insert: + return "^" + if app.vi_state.waiting_for_digraph: + if app.vi_state.digraph_symbol1: + return app.vi_state.digraph_symbol1 + return "?" + return None + + def write_to_screen( + self, + screen: Screen, + mouse_handlers: MouseHandlers, + write_position: WritePosition, + parent_style: str, + erase_bg: bool, + z_index: Optional[int], + ) -> None: + """ + Write window to screen. This renders the user control, the margins and + copies everything over to the absolute position at the given screen. + """ + z_index = z_index if self.z_index is None else self.z_index + + draw_func = partial( + self._write_to_screen_at_index, + screen, + mouse_handlers, + write_position, + parent_style, + erase_bg, + ) + + if z_index is None or z_index <= 0: + # When no z_index is given, draw right away. + draw_func() + else: + # Otherwise, postpone. + screen.draw_with_z_index(z_index=z_index, draw_func=draw_func) + + def _write_to_screen_at_index( + self, + screen: Screen, + mouse_handlers: MouseHandlers, + write_position: WritePosition, + parent_style: str, + erase_bg: bool, + ) -> None: + # Don't bother writing invisible windows. + # (We save some time, but also avoid applying last-line styling.) + if write_position.height <= 0 or write_position.width <= 0: + return + + # Calculate margin sizes. + left_margin_widths = [self._get_margin_width(m) for m in self.left_margins] + right_margin_widths = [self._get_margin_width(m) for m in self.right_margins] + total_margin_width = sum(left_margin_widths + right_margin_widths) + + # Render UserControl. + ui_content = self.content.create_content( + write_position.width - total_margin_width, write_position.height + ) + assert isinstance(ui_content, UIContent) + + # Scroll content. + wrap_lines = self.wrap_lines() + self._scroll( + ui_content, write_position.width - total_margin_width, write_position.height + ) + + # Erase background and fill with `char`. + self._fill_bg(screen, write_position, erase_bg) + + # Resolve `align` attribute. + align = self.align() if callable(self.align) else self.align + + # Write body + visible_line_to_row_col, rowcol_to_yx = self._copy_body( + ui_content, + screen, + write_position, + sum(left_margin_widths), + write_position.width - total_margin_width, + self.vertical_scroll, + self.horizontal_scroll, + wrap_lines=wrap_lines, + highlight_lines=True, + vertical_scroll_2=self.vertical_scroll_2, + always_hide_cursor=self.always_hide_cursor(), + has_focus=get_app().layout.current_control == self.content, + align=align, + get_line_prefix=self.get_line_prefix, + ) + + # Remember render info. (Set before generating the margins. They need this.) + x_offset = write_position.xpos + sum(left_margin_widths) + y_offset = write_position.ypos + + render_info = WindowRenderInfo( + window=self, + ui_content=ui_content, + horizontal_scroll=self.horizontal_scroll, + vertical_scroll=self.vertical_scroll, + window_width=write_position.width - total_margin_width, + window_height=write_position.height, + configured_scroll_offsets=self.scroll_offsets, + visible_line_to_row_col=visible_line_to_row_col, + rowcol_to_yx=rowcol_to_yx, + x_offset=x_offset, + y_offset=y_offset, + wrap_lines=wrap_lines, + ) + self.render_info = render_info + + # Set mouse handlers. + def mouse_handler(mouse_event: MouseEvent) -> None: + """Wrapper around the mouse_handler of the `UIControl` that turns + screen coordinates into line coordinates.""" + # Don't handle mouse events outside of the current modal part of + # the UI. + if self not in get_app().layout.walk_through_modal_area(): + return + + # Find row/col position first. + yx_to_rowcol = {v: k for k, v in rowcol_to_yx.items()} + y = mouse_event.position.y + x = mouse_event.position.x + + # If clicked below the content area, look for a position in the + # last line instead. + max_y = write_position.ypos + len(visible_line_to_row_col) - 1 + y = min(max_y, y) + result: NotImplementedOrNone + + while x >= 0: + try: + row, col = yx_to_rowcol[y, x] + except KeyError: + # Try again. (When clicking on the right side of double + # width characters, or on the right side of the input.) + x -= 1 + else: + # Found position, call handler of UIControl. + result = self.content.mouse_handler( + MouseEvent( + position=Point(x=col, y=row), + event_type=mouse_event.event_type, + ) + ) + break + else: + # nobreak. + # (No x/y coordinate found for the content. This happens in + # case of a DummyControl, that does not have any content. + # Report (0,0) instead.) + result = self.content.mouse_handler( + MouseEvent( + position=Point(x=0, y=0), event_type=mouse_event.event_type + ) + ) + + # If it returns NotImplemented, handle it here. + if result == NotImplemented: + self._mouse_handler(mouse_event) + + mouse_handlers.set_mouse_handler_for_range( + x_min=write_position.xpos + sum(left_margin_widths), + x_max=write_position.xpos + write_position.width - total_margin_width, + y_min=write_position.ypos, + y_max=write_position.ypos + write_position.height, + handler=mouse_handler, + ) + + # Render and copy margins. + move_x = 0 + + def render_margin(m: Margin, width: int) -> UIContent: + " Render margin. Return `Screen`. " + # Retrieve margin fragments. + fragments = m.create_margin(render_info, width, write_position.height) + + # Turn it into a UIContent object. + # already rendered those fragments using this size.) + return FormattedTextControl(fragments).create_content( + width + 1, write_position.height + ) + + for m, width in zip(self.left_margins, left_margin_widths): + if width > 0: # (ConditionalMargin returns a zero width. -- Don't render.) + # Create screen for margin. + margin_content = render_margin(m, width) + + # Copy and shift X. + self._copy_margin(margin_content, screen, write_position, move_x, width) + move_x += width + + move_x = write_position.width - sum(right_margin_widths) + + for m, width in zip(self.right_margins, right_margin_widths): + # Create screen for margin. + margin_content = render_margin(m, width) + + # Copy and shift X. + self._copy_margin(margin_content, screen, write_position, move_x, width) + move_x += width + + # Apply 'self.style' + self._apply_style(screen, write_position, parent_style) + + # Tell the screen that this user control has been painted. + screen.visible_windows.append(self) + + def _copy_body( + self, + ui_content: UIContent, + new_screen: Screen, + write_position: WritePosition, + move_x: int, + width: int, + vertical_scroll: int = 0, + horizontal_scroll: int = 0, + wrap_lines: bool = False, + highlight_lines: bool = False, + vertical_scroll_2: int = 0, + always_hide_cursor: bool = False, + has_focus: bool = False, + align: WindowAlign = WindowAlign.LEFT, + get_line_prefix: Optional[Callable[[int, int], AnyFormattedText]] = None, + ) -> Tuple[Dict[int, Tuple[int, int]], Dict[Tuple[int, int], Tuple[int, int]]]: + """ + Copy the UIContent into the output screen. + Return (visible_line_to_row_col, rowcol_to_yx) tuple. + + :param get_line_prefix: None or a callable that takes a line number + (int) and a wrap_count (int) and returns formatted text. + """ + xpos = write_position.xpos + move_x + ypos = write_position.ypos + line_count = ui_content.line_count + new_buffer = new_screen.data_buffer + empty_char = _CHAR_CACHE["", ""] + + # Map visible line number to (row, col) of input. + # 'col' will always be zero if line wrapping is off. + visible_line_to_row_col: Dict[int, Tuple[int, int]] = {} + + # Maps (row, col) from the input to (y, x) screen coordinates. + rowcol_to_yx: Dict[Tuple[int, int], Tuple[int, int]] = {} + + def copy_line( + line: StyleAndTextTuples, + lineno: int, + x: int, + y: int, + is_input: bool = False, + ) -> Tuple[int, int]: + """ + Copy over a single line to the output screen. This can wrap over + multiple lines in the output. It will call the prefix (prompt) + function before every line. + """ + if is_input: + current_rowcol_to_yx = rowcol_to_yx + else: + current_rowcol_to_yx = {} # Throwaway dictionary. + + # Draw line prefix. + if is_input and get_line_prefix: + prompt = to_formatted_text(get_line_prefix(lineno, 0)) + x, y = copy_line(prompt, lineno, x, y, is_input=False) + + # Scroll horizontally. + skipped = 0 # Characters skipped because of horizontal scrolling. + if horizontal_scroll and is_input: + h_scroll = horizontal_scroll + line = explode_text_fragments(line) + while h_scroll > 0 and line: + h_scroll -= get_cwidth(line[0][1]) + skipped += 1 + del line[:1] # Remove first character. + + x -= h_scroll # When scrolling over double width character, + # this can end up being negative. + + # Align this line. (Note that this doesn't work well when we use + # get_line_prefix and that function returns variable width prefixes.) + if align == WindowAlign.CENTER: + line_width = fragment_list_width(line) + if line_width < width: + x += (width - line_width) // 2 + elif align == WindowAlign.RIGHT: + line_width = fragment_list_width(line) + if line_width < width: + x += width - line_width + + col = 0 + wrap_count = 0 + for style, text, *_ in line: + new_buffer_row = new_buffer[y + ypos] + + # Remember raw VT escape sequences. (E.g. FinalTerm's + # escape sequences.) + if "[ZeroWidthEscape]" in style: + new_screen.zero_width_escapes[y + ypos][x + xpos] += text + continue + + for c in text: + char = _CHAR_CACHE[c, style] + char_width = char.width + + # Wrap when the line width is exceeded. + if wrap_lines and x + char_width > width: + visible_line_to_row_col[y + 1] = ( + lineno, + visible_line_to_row_col[y][1] + x, + ) + y += 1 + wrap_count += 1 + x = 0 + + # Insert line prefix (continuation prompt). + if is_input and get_line_prefix: + prompt = to_formatted_text( + get_line_prefix(lineno, wrap_count) + ) + x, y = copy_line(prompt, lineno, x, y, is_input=False) + + new_buffer_row = new_buffer[y + ypos] + + if y >= write_position.height: + return x, y # Break out of all for loops. + + # Set character in screen and shift 'x'. + if x >= 0 and y >= 0 and x < write_position.width: + new_buffer_row[x + xpos] = char + + # When we print a multi width character, make sure + # to erase the neighbours positions in the screen. + # (The empty string if different from everything, + # so next redraw this cell will repaint anyway.) + if char_width > 1: + for i in range(1, char_width): + new_buffer_row[x + xpos + i] = empty_char + + # If this is a zero width characters, then it's + # probably part of a decomposed unicode character. + # See: https://en.wikipedia.org/wiki/Unicode_equivalence + # Merge it in the previous cell. + elif char_width == 0: + # Handle all character widths. If the previous + # character is a multiwidth character, then + # merge it two positions back. + for pw in [2, 1]: # Previous character width. + if ( + x - pw >= 0 + and new_buffer_row[x + xpos - pw].width == pw + ): + prev_char = new_buffer_row[x + xpos - pw] + char2 = _CHAR_CACHE[ + prev_char.char + c, prev_char.style + ] + new_buffer_row[x + xpos - pw] = char2 + + # Keep track of write position for each character. + current_rowcol_to_yx[lineno, col + skipped] = ( + y + ypos, + x + xpos, + ) + + col += 1 + x += char_width + return x, y + + # Copy content. + def copy() -> int: + y = -vertical_scroll_2 + lineno = vertical_scroll + + while y < write_position.height and lineno < line_count: + # Take the next line and copy it in the real screen. + line = ui_content.get_line(lineno) + + visible_line_to_row_col[y] = (lineno, horizontal_scroll) + + # Copy margin and actual line. + x = 0 + x, y = copy_line(line, lineno, x, y, is_input=True) + + lineno += 1 + y += 1 + return y + + copy() + + def cursor_pos_to_screen_pos(row: int, col: int) -> Point: + " Translate row/col from UIContent to real Screen coordinates. " + try: + y, x = rowcol_to_yx[row, col] + except KeyError: + # Normally this should never happen. (It is a bug, if it happens.) + # But to be sure, return (0, 0) + return Point(x=0, y=0) + + # raise ValueError( + # 'Invalid position. row=%r col=%r, vertical_scroll=%r, ' + # 'horizontal_scroll=%r, height=%r' % + # (row, col, vertical_scroll, horizontal_scroll, write_position.height)) + else: + return Point(x=x, y=y) + + # Set cursor and menu positions. + if ui_content.cursor_position: + screen_cursor_position = cursor_pos_to_screen_pos( + ui_content.cursor_position.y, ui_content.cursor_position.x + ) + + if has_focus: + new_screen.set_cursor_position(self, screen_cursor_position) + + if always_hide_cursor: + new_screen.show_cursor = False + else: + new_screen.show_cursor = ui_content.show_cursor + + self._highlight_digraph(new_screen) + + if highlight_lines: + self._highlight_cursorlines( + new_screen, + screen_cursor_position, + xpos, + ypos, + width, + write_position.height, + ) + + # Draw input characters from the input processor queue. + if has_focus and ui_content.cursor_position: + self._show_key_processor_key_buffer(new_screen) + + # Set menu position. + if ui_content.menu_position: + new_screen.set_menu_position( + self, + cursor_pos_to_screen_pos( + ui_content.menu_position.y, ui_content.menu_position.x + ), + ) + + # Update output screen height. + new_screen.height = max(new_screen.height, ypos + write_position.height) + + return visible_line_to_row_col, rowcol_to_yx + + def _fill_bg( + self, screen: Screen, write_position: WritePosition, erase_bg: bool + ) -> None: + """ + Erase/fill the background. + (Useful for floats and when a `char` has been given.) + """ + char: Optional[str] + if callable(self.char): + char = self.char() + else: + char = self.char + + if erase_bg or char: + wp = write_position + char_obj = _CHAR_CACHE[char or " ", ""] + + for y in range(wp.ypos, wp.ypos + wp.height): + row = screen.data_buffer[y] + for x in range(wp.xpos, wp.xpos + wp.width): + row[x] = char_obj + + def _apply_style( + self, new_screen: Screen, write_position: WritePosition, parent_style: str + ) -> None: + + # Apply `self.style`. + style = parent_style + " " + to_str(self.style) + + new_screen.fill_area(write_position, style=style, after=False) + + # Apply the 'last-line' class to the last line of each Window. This can + # be used to apply an 'underline' to the user control. + wp = WritePosition( + write_position.xpos, + write_position.ypos + write_position.height - 1, + write_position.width, + 1, + ) + new_screen.fill_area(wp, "class:last-line", after=True) + + def _highlight_digraph(self, new_screen: Screen) -> None: + """ + When we are in Vi digraph mode, put a question mark underneath the + cursor. + """ + digraph_char = self._get_digraph_char() + if digraph_char: + cpos = new_screen.get_cursor_position(self) + new_screen.data_buffer[cpos.y][cpos.x] = _CHAR_CACHE[ + digraph_char, "class:digraph" + ] + + def _show_key_processor_key_buffer(self, new_screen: Screen) -> None: + """ + When the user is typing a key binding that consists of several keys, + display the last pressed key if the user is in insert mode and the key + is meaningful to be displayed. + E.g. Some people want to bind 'jj' to escape in Vi insert mode. But the + first 'j' needs to be displayed in order to get some feedback. + """ + app = get_app() + key_buffer = app.key_processor.key_buffer + + if key_buffer and _in_insert_mode() and not app.is_done: + # The textual data for the given key. (Can be a VT100 escape + # sequence.) + data = key_buffer[-1].data + + # Display only if this is a 1 cell width character. + if get_cwidth(data) == 1: + cpos = new_screen.get_cursor_position(self) + new_screen.data_buffer[cpos.y][cpos.x] = _CHAR_CACHE[ + data, "class:partial-key-binding" + ] + + def _highlight_cursorlines( + self, new_screen: Screen, cpos: Point, x: int, y: int, width: int, height: int + ) -> None: + """ + Highlight cursor row/column. + """ + cursor_line_style = " class:cursor-line " + cursor_column_style = " class:cursor-column " + + data_buffer = new_screen.data_buffer + + # Highlight cursor line. + if self.cursorline(): + row = data_buffer[cpos.y] + for x in range(x, x + width): + original_char = row[x] + row[x] = _CHAR_CACHE[ + original_char.char, original_char.style + cursor_line_style + ] + + # Highlight cursor column. + if self.cursorcolumn(): + for y2 in range(y, y + height): + row = data_buffer[y2] + original_char = row[cpos.x] + row[cpos.x] = _CHAR_CACHE[ + original_char.char, original_char.style + cursor_column_style + ] + + # Highlight color columns + colorcolumns = self.colorcolumns + if callable(colorcolumns): + colorcolumns = colorcolumns() + + for cc in colorcolumns: + assert isinstance(cc, ColorColumn) + column = cc.position + + if column < x + width: # Only draw when visible. + color_column_style = " " + cc.style + + for y2 in range(y, y + height): + row = data_buffer[y2] + original_char = row[column + x] + row[column + x] = _CHAR_CACHE[ + original_char.char, original_char.style + color_column_style + ] + + def _copy_margin( + self, + margin_content: UIContent, + new_screen: Screen, + write_position: WritePosition, + move_x: int, + width: int, + ) -> None: + """ + Copy characters from the margin screen to the real screen. + """ + xpos = write_position.xpos + move_x + ypos = write_position.ypos + + margin_write_position = WritePosition(xpos, ypos, width, write_position.height) + self._copy_body(margin_content, new_screen, margin_write_position, 0, width) + + def _scroll(self, ui_content: UIContent, width: int, height: int) -> None: + """ + Scroll body. Ensure that the cursor is visible. + """ + if self.wrap_lines(): + func = self._scroll_when_linewrapping + else: + func = self._scroll_without_linewrapping + + func(ui_content, width, height) + + def _scroll_when_linewrapping( + self, ui_content: UIContent, width: int, height: int + ) -> None: + """ + Scroll to make sure the cursor position is visible and that we maintain + the requested scroll offset. + + Set `self.horizontal_scroll/vertical_scroll`. + """ + scroll_offsets_bottom = self.scroll_offsets.bottom + scroll_offsets_top = self.scroll_offsets.top + + # We don't have horizontal scrolling. + self.horizontal_scroll = 0 + + def get_line_height(lineno: int) -> int: + return ui_content.get_height_for_line(lineno, width, self.get_line_prefix) + + # When there is no space, reset `vertical_scroll_2` to zero and abort. + # This can happen if the margin is bigger than the window width. + # Otherwise the text height will become "infinite" (a big number) and + # the copy_line will spend a huge amount of iterations trying to render + # nothing. + if width <= 0: + self.vertical_scroll = ui_content.cursor_position.y + self.vertical_scroll_2 = 0 + return + + # If the current line consumes more than the whole window height, + # then we have to scroll vertically inside this line. (We don't take + # the scroll offsets into account for this.) + # Also, ignore the scroll offsets in this case. Just set the vertical + # scroll to this line. + line_height = get_line_height(ui_content.cursor_position.y) + if line_height > height - scroll_offsets_top: + # Calculate the height of the text before the cursor (including + # line prefixes). + text_before_height = ui_content.get_height_for_line( + ui_content.cursor_position.y, + width, + self.get_line_prefix, + slice_stop=ui_content.cursor_position.x, + ) + + # Adjust scroll offset. + self.vertical_scroll = ui_content.cursor_position.y + self.vertical_scroll_2 = min( + text_before_height - 1, # Keep the cursor visible. + line_height + - height, # Avoid blank lines at the bottom when scolling up again. + self.vertical_scroll_2, + ) + self.vertical_scroll_2 = max( + 0, text_before_height - height, self.vertical_scroll_2 + ) + return + else: + self.vertical_scroll_2 = 0 + + # Current line doesn't consume the whole height. Take scroll offsets into account. + def get_min_vertical_scroll() -> int: + # Make sure that the cursor line is not below the bottom. + # (Calculate how many lines can be shown between the cursor and the .) + used_height = 0 + prev_lineno = ui_content.cursor_position.y + + for lineno in range(ui_content.cursor_position.y, -1, -1): + used_height += get_line_height(lineno) + + if used_height > height - scroll_offsets_bottom: + return prev_lineno + else: + prev_lineno = lineno + return 0 + + def get_max_vertical_scroll() -> int: + # Make sure that the cursor line is not above the top. + prev_lineno = ui_content.cursor_position.y + used_height = 0 + + for lineno in range(ui_content.cursor_position.y - 1, -1, -1): + used_height += get_line_height(lineno) + + if used_height > scroll_offsets_top: + return prev_lineno + else: + prev_lineno = lineno + return prev_lineno + + def get_topmost_visible() -> int: + """ + Calculate the upper most line that can be visible, while the bottom + is still visible. We should not allow scroll more than this if + `allow_scroll_beyond_bottom` is false. + """ + prev_lineno = ui_content.line_count - 1 + used_height = 0 + for lineno in range(ui_content.line_count - 1, -1, -1): + used_height += get_line_height(lineno) + if used_height > height: + return prev_lineno + else: + prev_lineno = lineno + return prev_lineno + + # Scroll vertically. (Make sure that the whole line which contains the + # cursor is visible. + topmost_visible = get_topmost_visible() + + # Note: the `min(topmost_visible, ...)` is to make sure that we + # don't require scrolling up because of the bottom scroll offset, + # when we are at the end of the document. + self.vertical_scroll = max( + self.vertical_scroll, min(topmost_visible, get_min_vertical_scroll()) + ) + self.vertical_scroll = min(self.vertical_scroll, get_max_vertical_scroll()) + + # Disallow scrolling beyond bottom? + if not self.allow_scroll_beyond_bottom(): + self.vertical_scroll = min(self.vertical_scroll, topmost_visible) + + def _scroll_without_linewrapping( + self, ui_content: UIContent, width: int, height: int + ) -> None: + """ + Scroll to make sure the cursor position is visible and that we maintain + the requested scroll offset. + + Set `self.horizontal_scroll/vertical_scroll`. + """ + cursor_position = ui_content.cursor_position or Point(x=0, y=0) + + # Without line wrapping, we will never have to scroll vertically inside + # a single line. + self.vertical_scroll_2 = 0 + + if ui_content.line_count == 0: + self.vertical_scroll = 0 + self.horizontal_scroll = 0 + return + else: + current_line_text = fragment_list_to_text( + ui_content.get_line(cursor_position.y) + ) + + def do_scroll( + current_scroll: int, + scroll_offset_start: int, + scroll_offset_end: int, + cursor_pos: int, + window_size: int, + content_size: int, + ) -> int: + " Scrolling algorithm. Used for both horizontal and vertical scrolling. " + # Calculate the scroll offset to apply. + # This can obviously never be more than have the screen size. Also, when the + # cursor appears at the top or bottom, we don't apply the offset. + scroll_offset_start = int( + min(scroll_offset_start, window_size / 2, cursor_pos) + ) + scroll_offset_end = int( + min(scroll_offset_end, window_size / 2, content_size - 1 - cursor_pos) + ) + + # Prevent negative scroll offsets. + if current_scroll < 0: + current_scroll = 0 + + # Scroll back if we scrolled to much and there's still space to show more of the document. + if ( + not self.allow_scroll_beyond_bottom() + and current_scroll > content_size - window_size + ): + current_scroll = max(0, content_size - window_size) + + # Scroll up if cursor is before visible part. + if current_scroll > cursor_pos - scroll_offset_start: + current_scroll = max(0, cursor_pos - scroll_offset_start) + + # Scroll down if cursor is after visible part. + if current_scroll < (cursor_pos + 1) - window_size + scroll_offset_end: + current_scroll = (cursor_pos + 1) - window_size + scroll_offset_end + + return current_scroll + + # When a preferred scroll is given, take that first into account. + if self.get_vertical_scroll: + self.vertical_scroll = self.get_vertical_scroll(self) + assert isinstance(self.vertical_scroll, int) + if self.get_horizontal_scroll: + self.horizontal_scroll = self.get_horizontal_scroll(self) + assert isinstance(self.horizontal_scroll, int) + + # Update horizontal/vertical scroll to make sure that the cursor + # remains visible. + offsets = self.scroll_offsets + + self.vertical_scroll = do_scroll( + current_scroll=self.vertical_scroll, + scroll_offset_start=offsets.top, + scroll_offset_end=offsets.bottom, + cursor_pos=ui_content.cursor_position.y, + window_size=height, + content_size=ui_content.line_count, + ) + + if self.get_line_prefix: + current_line_prefix_width = fragment_list_width( + to_formatted_text(self.get_line_prefix(ui_content.cursor_position.y, 0)) + ) + else: + current_line_prefix_width = 0 + + self.horizontal_scroll = do_scroll( + current_scroll=self.horizontal_scroll, + scroll_offset_start=offsets.left, + scroll_offset_end=offsets.right, + cursor_pos=get_cwidth(current_line_text[: ui_content.cursor_position.x]), + window_size=width - current_line_prefix_width, + # We can only analyse the current line. Calculating the width off + # all the lines is too expensive. + content_size=max( + get_cwidth(current_line_text), self.horizontal_scroll + width + ), + ) + + def _mouse_handler(self, mouse_event: MouseEvent) -> None: + """ + Mouse handler. Called when the UI control doesn't handle this + particular event. + """ + if mouse_event.event_type == MouseEventType.SCROLL_DOWN: + self._scroll_down() + elif mouse_event.event_type == MouseEventType.SCROLL_UP: + self._scroll_up() + + def _scroll_down(self) -> None: + " Scroll window down. " + info = self.render_info + + if info is None: + return + + if self.vertical_scroll < info.content_height - info.window_height: + if info.cursor_position.y <= info.configured_scroll_offsets.top: + self.content.move_cursor_down() + + self.vertical_scroll += 1 + + def _scroll_up(self) -> None: + " Scroll window up. " + info = self.render_info + + if info is None: + return + + if info.vertical_scroll > 0: + # TODO: not entirely correct yet in case of line wrapping and long lines. + if ( + info.cursor_position.y + >= info.window_height - 1 - info.configured_scroll_offsets.bottom + ): + self.content.move_cursor_up() + + self.vertical_scroll -= 1 + + def get_key_bindings(self) -> Optional[KeyBindingsBase]: + return self.content.get_key_bindings() + + def get_children(self) -> List[Container]: + return [] + + +class ConditionalContainer(Container): + """ + Wrapper around any other container that can change the visibility. The + received `filter` determines whether the given container should be + displayed or not. + + :param content: :class:`.Container` instance. + :param filter: :class:`.Filter` instance. + """ + + def __init__(self, content: AnyContainer, filter: FilterOrBool) -> None: + self.content = to_container(content) + self.filter = to_filter(filter) + + def __repr__(self) -> str: + return "ConditionalContainer(%r, filter=%r)" % (self.content, self.filter) + + def reset(self) -> None: + self.content.reset() + + def preferred_width(self, max_available_width: int) -> Dimension: + if self.filter(): + return self.content.preferred_width(max_available_width) + else: + return Dimension.zero() + + def preferred_height(self, width: int, max_available_height: int) -> Dimension: + if self.filter(): + return self.content.preferred_height(width, max_available_height) + else: + return Dimension.zero() + + def write_to_screen( + self, + screen: Screen, + mouse_handlers: MouseHandlers, + write_position: WritePosition, + parent_style: str, + erase_bg: bool, + z_index: Optional[int], + ) -> None: + if self.filter(): + return self.content.write_to_screen( + screen, mouse_handlers, write_position, parent_style, erase_bg, z_index + ) + + def get_children(self) -> List[Container]: + return [self.content] + + +class DynamicContainer(Container): + """ + Container class that dynamically returns any Container. + + :param get_container: Callable that returns a :class:`.Container` instance + or any widget with a ``__pt_container__`` method. + """ + + def __init__(self, get_container: Callable[[], AnyContainer]) -> None: + self.get_container = get_container + + def _get_container(self) -> Container: + """ + Return the current container object. + + We call `to_container`, because `get_container` can also return a + widget with a ``__pt_container__`` method. + """ + obj = self.get_container() + return to_container(obj) + + def reset(self) -> None: + self._get_container().reset() + + def preferred_width(self, max_available_width: int) -> Dimension: + return self._get_container().preferred_width(max_available_width) + + def preferred_height(self, width: int, max_available_height: int) -> Dimension: + return self._get_container().preferred_height(width, max_available_height) + + def write_to_screen(self, *a, **kw): + self._get_container().write_to_screen(*a, **kw) + + def is_modal(self) -> bool: + return False + + def get_key_bindings(self) -> Optional[KeyBindingsBase]: + # Key bindings will be collected when `layout.walk()` finds the child + # container. + return None + + def get_children(self) -> List[Container]: + # Here we have to return the current active container itself, not its + # children. Otherwise, we run into issues where `layout.walk()` will + # never see an object of type `Window` if this contains a window. We + # can't/shouldn't proxy the "isinstance" check. + return [self._get_container()] + + +def to_container(container: AnyContainer) -> Container: + """ + Make sure that the given object is a :class:`.Container`. + """ + if isinstance(container, Container): + return container + elif hasattr(container, "__pt_container__"): + return to_container(cast("MagicContainer", container).__pt_container__()) + else: + raise ValueError("Not a container object: %r" % (container,)) + + +def to_window(container: AnyContainer) -> Window: + """ + Make sure that the given argument is a :class:`.Window`. + """ + if isinstance(container, Window): + return container + elif hasattr(container, "__pt_container__"): + return to_window(cast("MagicContainer", container).__pt_container__()) + else: + raise ValueError("Not a Window object: %r." % (container,)) + + +def is_container(value: object) -> bool: + """ + Checks whether the given value is a container object + (for use in assert statements). + """ + if isinstance(value, Container): + return True + if hasattr(value, "__pt_container__"): + return is_container(cast("MagicContainer", value).__pt_container__()) + return False diff --git a/.venv/lib/python3.8/site-packages/prompt_toolkit/layout/controls.py b/.venv/lib/python3.8/site-packages/prompt_toolkit/layout/controls.py new file mode 100644 index 00000000..f2c4a213 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/prompt_toolkit/layout/controls.py @@ -0,0 +1,947 @@ +""" +User interface Controls for the layout. +""" +import time +from abc import ABCMeta, abstractmethod +from typing import ( + TYPE_CHECKING, + Callable, + Dict, + Hashable, + Iterable, + List, + NamedTuple, + Optional, + Union, +) + +from prompt_toolkit.application.current import get_app +from prompt_toolkit.buffer import Buffer +from prompt_toolkit.cache import SimpleCache +from prompt_toolkit.data_structures import Point +from prompt_toolkit.document import Document +from prompt_toolkit.filters import FilterOrBool, to_filter +from prompt_toolkit.formatted_text import ( + AnyFormattedText, + StyleAndTextTuples, + to_formatted_text, +) +from prompt_toolkit.formatted_text.utils import ( + fragment_list_to_text, + fragment_list_width, + split_lines, +) +from prompt_toolkit.lexers import Lexer, SimpleLexer +from prompt_toolkit.mouse_events import MouseEvent, MouseEventType +from prompt_toolkit.search import SearchState +from prompt_toolkit.selection import SelectionType +from prompt_toolkit.utils import get_cwidth + +from .processors import ( + DisplayMultipleCursors, + HighlightIncrementalSearchProcessor, + HighlightSearchProcessor, + HighlightSelectionProcessor, + Processor, + TransformationInput, + merge_processors, +) + +if TYPE_CHECKING: + from prompt_toolkit.key_binding.key_bindings import KeyBindingsBase + from prompt_toolkit.utils import Event + + # The only two return values for a mouse hander are `None` and + # `NotImplemented`. For the type checker it's best to annotate this as + # `object`. (The consumer never expects a more specific instance: checking + # for NotImplemented can be done using `is NotImplemented`.) + NotImplementedOrNone = object + # Other non-working options are: + # * Optional[Literal[NotImplemented]] + # --> Doesn't work, Literal can't take an Any. + # * None + # --> Doesn't work. We can't assign the result of a function that + # returns `None` to a variable. + # * Any + # --> Works, but too broad. + + +__all__ = [ + "BufferControl", + "SearchBufferControl", + "DummyControl", + "FormattedTextControl", + "UIControl", + "UIContent", +] + +GetLinePrefixCallable = Callable[[int, int], AnyFormattedText] + + +class UIControl(metaclass=ABCMeta): + """ + Base class for all user interface controls. + """ + + def reset(self) -> None: + # Default reset. (Doesn't have to be implemented.) + pass + + def preferred_width(self, max_available_width: int) -> Optional[int]: + return None + + def preferred_height( + self, + width: int, + max_available_height: int, + wrap_lines: bool, + get_line_prefix: Optional[GetLinePrefixCallable], + ) -> Optional[int]: + return None + + def is_focusable(self) -> bool: + """ + Tell whether this user control is focusable. + """ + return False + + @abstractmethod + def create_content(self, width: int, height: int) -> "UIContent": + """ + Generate the content for this user control. + + Returns a :class:`.UIContent` instance. + """ + + def mouse_handler(self, mouse_event: MouseEvent) -> "NotImplementedOrNone": + """ + Handle mouse events. + + When `NotImplemented` is returned, it means that the given event is not + handled by the `UIControl` itself. The `Window` or key bindings can + decide to handle this event as scrolling or changing focus. + + :param mouse_event: `MouseEvent` instance. + """ + return NotImplemented + + def move_cursor_down(self) -> None: + """ + Request to move the cursor down. + This happens when scrolling down and the cursor is completely at the + top. + """ + + def move_cursor_up(self) -> None: + """ + Request to move the cursor up. + """ + + def get_key_bindings(self) -> Optional["KeyBindingsBase"]: + """ + The key bindings that are specific for this user control. + + Return a :class:`.KeyBindings` object if some key bindings are + specified, or `None` otherwise. + """ + + def get_invalidate_events(self) -> Iterable["Event[object]"]: + """ + Return a list of `Event` objects. This can be a generator. + (The application collects all these events, in order to bind redraw + handlers to these events.) + """ + return [] + + +class UIContent: + """ + Content generated by a user control. This content consists of a list of + lines. + + :param get_line: Callable that takes a line number and returns the current + line. This is a list of (style_str, text) tuples. + :param line_count: The number of lines. + :param cursor_position: a :class:`.Point` for the cursor position. + :param menu_position: a :class:`.Point` for the menu position. + :param show_cursor: Make the cursor visible. + """ + + def __init__( + self, + get_line: Callable[[int], StyleAndTextTuples] = (lambda i: []), + line_count: int = 0, + cursor_position: Optional[Point] = None, + menu_position: Optional[Point] = None, + show_cursor: bool = True, + ): + + self.get_line = get_line + self.line_count = line_count + self.cursor_position = cursor_position or Point(x=0, y=0) + self.menu_position = menu_position + self.show_cursor = show_cursor + + # Cache for line heights. Maps cache key -> height + self._line_heights_cache: Dict[Hashable, int] = {} + + def __getitem__(self, lineno: int) -> StyleAndTextTuples: + " Make it iterable (iterate line by line). " + if lineno < self.line_count: + return self.get_line(lineno) + else: + raise IndexError + + def get_height_for_line( + self, + lineno: int, + width: int, + get_line_prefix: Optional[GetLinePrefixCallable], + slice_stop: Optional[int] = None, + ) -> int: + """ + Return the height that a given line would need if it is rendered in a + space with the given width (using line wrapping). + + :param get_line_prefix: None or a `Window.get_line_prefix` callable + that returns the prefix to be inserted before this line. + :param slice_stop: Wrap only "line[:slice_stop]" and return that + partial result. This is needed for scrolling the window correctly + when line wrapping. + :returns: The computed height. + """ + # Instead of using `get_line_prefix` as key, we use render_counter + # instead. This is more reliable, because this function could still be + # the same, while the content would change over time. + key = get_app().render_counter, lineno, width, slice_stop + + try: + return self._line_heights_cache[key] + except KeyError: + if width == 0: + height = 10 ** 8 + else: + # Calculate line width first. + line = fragment_list_to_text(self.get_line(lineno))[:slice_stop] + text_width = get_cwidth(line) + + if get_line_prefix: + # Add prefix width. + text_width += fragment_list_width( + to_formatted_text(get_line_prefix(lineno, 0)) + ) + + # Slower path: compute path when there's a line prefix. + height = 1 + + # Keep wrapping as long as the line doesn't fit. + # Keep adding new prefixes for every wrapped line. + while text_width > width: + height += 1 + text_width -= width + + fragments2 = to_formatted_text( + get_line_prefix(lineno, height - 1) + ) + prefix_width = get_cwidth(fragment_list_to_text(fragments2)) + + if prefix_width >= width: # Prefix doesn't fit. + height = 10 ** 8 + break + + text_width += prefix_width + else: + # Fast path: compute height when there's no line prefix. + try: + quotient, remainder = divmod(text_width, width) + except ZeroDivisionError: + height = 10 ** 8 + else: + if remainder: + quotient += 1 # Like math.ceil. + height = max(1, quotient) + + # Cache and return + self._line_heights_cache[key] = height + return height + + +class FormattedTextControl(UIControl): + """ + Control that displays formatted text. This can be either plain text, an + :class:`~prompt_toolkit.formatted_text.HTML` object an + :class:`~prompt_toolkit.formatted_text.ANSI` object, a list of ``(style_str, + text)`` tuples or a callable that takes no argument and returns one of + those, depending on how you prefer to do the formatting. See + ``prompt_toolkit.layout.formatted_text`` for more information. + + (It's mostly optimized for rather small widgets, like toolbars, menus, etc...) + + When this UI control has the focus, the cursor will be shown in the upper + left corner of this control by default. There are two ways for specifying + the cursor position: + + - Pass a `get_cursor_position` function which returns a `Point` instance + with the current cursor position. + + - If the (formatted) text is passed as a list of ``(style, text)`` tuples + and there is one that looks like ``('[SetCursorPosition]', '')``, then + this will specify the cursor position. + + Mouse support: + + The list of fragments can also contain tuples of three items, looking like: + (style_str, text, handler). When mouse support is enabled and the user + clicks on this fragment, then the given handler is called. That handler + should accept two inputs: (Application, MouseEvent) and it should + either handle the event or return `NotImplemented` in case we want the + containing Window to handle this event. + + :param focusable: `bool` or :class:`.Filter`: Tell whether this control is + focusable. + + :param text: Text or formatted text to be displayed. + :param style: Style string applied to the content. (If you want to style + the whole :class:`~prompt_toolkit.layout.Window`, pass the style to the + :class:`~prompt_toolkit.layout.Window` instead.) + :param key_bindings: a :class:`.KeyBindings` object. + :param get_cursor_position: A callable that returns the cursor position as + a `Point` instance. + """ + + def __init__( + self, + text: AnyFormattedText = "", + style: str = "", + focusable: FilterOrBool = False, + key_bindings: Optional["KeyBindingsBase"] = None, + show_cursor: bool = True, + modal: bool = False, + get_cursor_position: Optional[Callable[[], Optional[Point]]] = None, + ) -> None: + + self.text = text # No type check on 'text'. This is done dynamically. + self.style = style + self.focusable = to_filter(focusable) + + # Key bindings. + self.key_bindings = key_bindings + self.show_cursor = show_cursor + self.modal = modal + self.get_cursor_position = get_cursor_position + + #: Cache for the content. + self._content_cache: SimpleCache[Hashable, UIContent] = SimpleCache(maxsize=18) + self._fragment_cache: SimpleCache[int, StyleAndTextTuples] = SimpleCache( + maxsize=1 + ) + # Only cache one fragment list. We don't need the previous item. + + # Render info for the mouse support. + self._fragments: Optional[StyleAndTextTuples] = None + + def reset(self) -> None: + self._fragments = None + + def is_focusable(self) -> bool: + return self.focusable() + + def __repr__(self) -> str: + return "%s(%r)" % (self.__class__.__name__, self.text) + + def _get_formatted_text_cached(self) -> StyleAndTextTuples: + """ + Get fragments, but only retrieve fragments once during one render run. + (This function is called several times during one rendering, because + we also need those for calculating the dimensions.) + """ + return self._fragment_cache.get( + get_app().render_counter, lambda: to_formatted_text(self.text, self.style) + ) + + def preferred_width(self, max_available_width: int) -> int: + """ + Return the preferred width for this control. + That is the width of the longest line. + """ + text = fragment_list_to_text(self._get_formatted_text_cached()) + line_lengths = [get_cwidth(l) for l in text.split("\n")] + return max(line_lengths) + + def preferred_height( + self, + width: int, + max_available_height: int, + wrap_lines: bool, + get_line_prefix: Optional[GetLinePrefixCallable], + ) -> Optional[int]: + + content = self.create_content(width, None) + if wrap_lines: + height = 0 + for i in range(content.line_count): + height += content.get_height_for_line(i, width, get_line_prefix) + if height >= max_available_height: + return max_available_height + return height + else: + return content.line_count + + def create_content(self, width: int, height: Optional[int]) -> UIContent: + # Get fragments + fragments_with_mouse_handlers = self._get_formatted_text_cached() + fragment_lines_with_mouse_handlers = list( + split_lines(fragments_with_mouse_handlers) + ) + + # Strip mouse handlers from fragments. + fragment_lines: List[StyleAndTextTuples] = [ + [(item[0], item[1]) for item in line] + for line in fragment_lines_with_mouse_handlers + ] + + # Keep track of the fragments with mouse handler, for later use in + # `mouse_handler`. + self._fragments = fragments_with_mouse_handlers + + # If there is a `[SetCursorPosition]` in the fragment list, set the + # cursor position here. + def get_cursor_position( + fragment: str = "[SetCursorPosition]", + ) -> Optional[Point]: + for y, line in enumerate(fragment_lines): + x = 0 + for style_str, text, *_ in line: + if fragment in style_str: + return Point(x=x, y=y) + x += len(text) + return None + + # If there is a `[SetMenuPosition]`, set the menu over here. + def get_menu_position() -> Optional[Point]: + return get_cursor_position("[SetMenuPosition]") + + cursor_position = (self.get_cursor_position or get_cursor_position)() + + # Create content, or take it from the cache. + key = (tuple(fragments_with_mouse_handlers), width, cursor_position) + + def get_content() -> UIContent: + return UIContent( + get_line=lambda i: fragment_lines[i], + line_count=len(fragment_lines), + show_cursor=self.show_cursor, + cursor_position=cursor_position, + menu_position=get_menu_position(), + ) + + return self._content_cache.get(key, get_content) + + def mouse_handler(self, mouse_event: MouseEvent) -> "NotImplementedOrNone": + """ + Handle mouse events. + + (When the fragment list contained mouse handlers and the user clicked on + on any of these, the matching handler is called. This handler can still + return `NotImplemented` in case we want the + :class:`~prompt_toolkit.layout.Window` to handle this particular + event.) + """ + if self._fragments: + # Read the generator. + fragments_for_line = list(split_lines(self._fragments)) + + try: + fragments = fragments_for_line[mouse_event.position.y] + except IndexError: + return NotImplemented + else: + # Find position in the fragment list. + xpos = mouse_event.position.x + + # Find mouse handler for this character. + count = 0 + for item in fragments: + count += len(item[1]) + if count >= xpos: + if len(item) >= 3: + # Handler found. Call it. + # (Handler can return NotImplemented, so return + # that result.) + handler = item[2] # type: ignore + return handler(mouse_event) + else: + break + + # Otherwise, don't handle here. + return NotImplemented + + def is_modal(self) -> bool: + return self.modal + + def get_key_bindings(self) -> Optional["KeyBindingsBase"]: + return self.key_bindings + + +class DummyControl(UIControl): + """ + A dummy control object that doesn't paint any content. + + Useful for filling a :class:`~prompt_toolkit.layout.Window`. (The + `fragment` and `char` attributes of the `Window` class can be used to + define the filling.) + """ + + def create_content(self, width: int, height: int) -> UIContent: + def get_line(i: int) -> StyleAndTextTuples: + return [] + + return UIContent( + get_line=get_line, line_count=100 ** 100 + ) # Something very big. + + def is_focusable(self) -> bool: + return False + + +_ProcessedLine = NamedTuple( + "_ProcessedLine", + [ + ("fragments", StyleAndTextTuples), + ("source_to_display", Callable[[int], int]), + ("display_to_source", Callable[[int], int]), + ], +) + + +class BufferControl(UIControl): + """ + Control for visualising the content of a :class:`.Buffer`. + + :param buffer: The :class:`.Buffer` object to be displayed. + :param input_processors: A list of + :class:`~prompt_toolkit.layout.processors.Processor` objects. + :param include_default_input_processors: When True, include the default + processors for highlighting of selection, search and displaying of + multiple cursors. + :param lexer: :class:`.Lexer` instance for syntax highlighting. + :param preview_search: `bool` or :class:`.Filter`: Show search while + typing. When this is `True`, probably you want to add a + ``HighlightIncrementalSearchProcessor`` as well. Otherwise only the + cursor position will move, but the text won't be highlighted. + :param focusable: `bool` or :class:`.Filter`: Tell whether this control is focusable. + :param focus_on_click: Focus this buffer when it's click, but not yet focused. + :param key_bindings: a :class:`.KeyBindings` object. + """ + + def __init__( + self, + buffer: Optional[Buffer] = None, + input_processors: Optional[List[Processor]] = None, + include_default_input_processors: bool = True, + lexer: Optional[Lexer] = None, + preview_search: FilterOrBool = False, + focusable: FilterOrBool = True, + search_buffer_control: Union[ + None, "SearchBufferControl", Callable[[], "SearchBufferControl"] + ] = None, + menu_position: Optional[Callable] = None, + focus_on_click: FilterOrBool = False, + key_bindings: Optional["KeyBindingsBase"] = None, + ): + + self.input_processors = input_processors + self.include_default_input_processors = include_default_input_processors + + self.default_input_processors = [ + HighlightSearchProcessor(), + HighlightIncrementalSearchProcessor(), + HighlightSelectionProcessor(), + DisplayMultipleCursors(), + ] + + self.preview_search = to_filter(preview_search) + self.focusable = to_filter(focusable) + self.focus_on_click = to_filter(focus_on_click) + + self.buffer = buffer or Buffer() + self.menu_position = menu_position + self.lexer = lexer or SimpleLexer() + self.key_bindings = key_bindings + self._search_buffer_control = search_buffer_control + + #: Cache for the lexer. + #: Often, due to cursor movement, undo/redo and window resizing + #: operations, it happens that a short time, the same document has to be + #: lexed. This is a fairly easy way to cache such an expensive operation. + self._fragment_cache: SimpleCache[ + Hashable, Callable[[int], StyleAndTextTuples] + ] = SimpleCache(maxsize=8) + + self._last_click_timestamp: Optional[float] = None + self._last_get_processed_line: Optional[Callable[[int], _ProcessedLine]] = None + + def __repr__(self) -> str: + return "<%s buffer=%r at %r>" % (self.__class__.__name__, self.buffer, id(self)) + + @property + def search_buffer_control(self) -> Optional["SearchBufferControl"]: + result: Optional[SearchBufferControl] + + if callable(self._search_buffer_control): + result = self._search_buffer_control() + else: + result = self._search_buffer_control + + assert result is None or isinstance(result, SearchBufferControl) + return result + + @property + def search_buffer(self) -> Optional[Buffer]: + control = self.search_buffer_control + if control is not None: + return control.buffer + return None + + @property + def search_state(self) -> SearchState: + """ + Return the `SearchState` for searching this `BufferControl`. This is + always associated with the search control. If one search bar is used + for searching multiple `BufferControls`, then they share the same + `SearchState`. + """ + search_buffer_control = self.search_buffer_control + if search_buffer_control: + return search_buffer_control.searcher_search_state + else: + return SearchState() + + def is_focusable(self) -> bool: + return self.focusable() + + def preferred_width(self, max_available_width: int) -> Optional[int]: + """ + This should return the preferred width. + + Note: We don't specify a preferred width according to the content, + because it would be too expensive. Calculating the preferred + width can be done by calculating the longest line, but this would + require applying all the processors to each line. This is + unfeasible for a larger document, and doing it for small + documents only would result in inconsistent behaviour. + """ + return None + + def preferred_height( + self, + width: int, + max_available_height: int, + wrap_lines: bool, + get_line_prefix: Optional[GetLinePrefixCallable], + ) -> Optional[int]: + + # Calculate the content height, if it was drawn on a screen with the + # given width. + height = 0 + content = self.create_content(width, height=1) # Pass a dummy '1' as height. + + # When line wrapping is off, the height should be equal to the amount + # of lines. + if not wrap_lines: + return content.line_count + + # When the number of lines exceeds the max_available_height, just + # return max_available_height. No need to calculate anything. + if content.line_count >= max_available_height: + return max_available_height + + for i in range(content.line_count): + height += content.get_height_for_line(i, width, get_line_prefix) + + if height >= max_available_height: + return max_available_height + + return height + + def _get_formatted_text_for_line_func( + self, document: Document + ) -> Callable[[int], StyleAndTextTuples]: + """ + Create a function that returns the fragments for a given line. + """ + # Cache using `document.text`. + def get_formatted_text_for_line() -> Callable[[int], StyleAndTextTuples]: + return self.lexer.lex_document(document) + + key = (document.text, self.lexer.invalidation_hash()) + return self._fragment_cache.get(key, get_formatted_text_for_line) + + def _create_get_processed_line_func( + self, document: Document, width: int, height: int + ) -> Callable[[int], _ProcessedLine]: + """ + Create a function that takes a line number of the current document and + returns a _ProcessedLine(processed_fragments, source_to_display, display_to_source) + tuple. + """ + # Merge all input processors together. + input_processors = self.input_processors or [] + if self.include_default_input_processors: + input_processors = self.default_input_processors + input_processors + + merged_processor = merge_processors(input_processors) + + def transform(lineno: int, fragments: StyleAndTextTuples) -> _ProcessedLine: + " Transform the fragments for a given line number. " + # Get cursor position at this line. + def source_to_display(i: int) -> int: + """X position from the buffer to the x position in the + processed fragment list. By default, we start from the 'identity' + operation.""" + return i + + transformation = merged_processor.apply_transformation( + TransformationInput( + self, document, lineno, source_to_display, fragments, width, height + ) + ) + + return _ProcessedLine( + transformation.fragments, + transformation.source_to_display, + transformation.display_to_source, + ) + + def create_func() -> Callable[[int], _ProcessedLine]: + get_line = self._get_formatted_text_for_line_func(document) + cache: Dict[int, _ProcessedLine] = {} + + def get_processed_line(i: int) -> _ProcessedLine: + try: + return cache[i] + except KeyError: + processed_line = transform(i, get_line(i)) + cache[i] = processed_line + return processed_line + + return get_processed_line + + return create_func() + + def create_content( + self, width: int, height: int, preview_search: bool = False + ) -> UIContent: + """ + Create a UIContent. + """ + buffer = self.buffer + + # Get the document to be shown. If we are currently searching (the + # search buffer has focus, and the preview_search filter is enabled), + # then use the search document, which has possibly a different + # text/cursor position.) + search_control = self.search_buffer_control + preview_now = preview_search or bool( + # Only if this feature is enabled. + self.preview_search() + and + # And something was typed in the associated search field. + search_control + and search_control.buffer.text + and + # And we are searching in this control. (Many controls can point to + # the same search field, like in Pyvim.) + get_app().layout.search_target_buffer_control == self + ) + + if preview_now and search_control is not None: + ss = self.search_state + + document = buffer.document_for_search( + SearchState( + text=search_control.buffer.text, + direction=ss.direction, + ignore_case=ss.ignore_case, + ) + ) + else: + document = buffer.document + + get_processed_line = self._create_get_processed_line_func( + document, width, height + ) + self._last_get_processed_line = get_processed_line + + def translate_rowcol(row: int, col: int) -> Point: + " Return the content column for this coordinate. " + return Point(x=get_processed_line(row).source_to_display(col), y=row) + + def get_line(i: int) -> StyleAndTextTuples: + " Return the fragments for a given line number. " + fragments = get_processed_line(i).fragments + + # Add a space at the end, because that is a possible cursor + # position. (When inserting after the input.) We should do this on + # all the lines, not just the line containing the cursor. (Because + # otherwise, line wrapping/scrolling could change when moving the + # cursor around.) + fragments = fragments + [("", " ")] + return fragments + + content = UIContent( + get_line=get_line, + line_count=document.line_count, + cursor_position=translate_rowcol( + document.cursor_position_row, document.cursor_position_col + ), + ) + + # If there is an auto completion going on, use that start point for a + # pop-up menu position. (But only when this buffer has the focus -- + # there is only one place for a menu, determined by the focused buffer.) + if get_app().layout.current_control == self: + menu_position = self.menu_position() if self.menu_position else None + if menu_position is not None: + assert isinstance(menu_position, int) + menu_row, menu_col = buffer.document.translate_index_to_position( + menu_position + ) + content.menu_position = translate_rowcol(menu_row, menu_col) + elif buffer.complete_state: + # Position for completion menu. + # Note: We use 'min', because the original cursor position could be + # behind the input string when the actual completion is for + # some reason shorter than the text we had before. (A completion + # can change and shorten the input.) + menu_row, menu_col = buffer.document.translate_index_to_position( + min( + buffer.cursor_position, + buffer.complete_state.original_document.cursor_position, + ) + ) + content.menu_position = translate_rowcol(menu_row, menu_col) + else: + content.menu_position = None + + return content + + def mouse_handler(self, mouse_event: MouseEvent) -> "NotImplementedOrNone": + """ + Mouse handler for this control. + """ + buffer = self.buffer + position = mouse_event.position + + # Focus buffer when clicked. + if get_app().layout.current_control == self: + if self._last_get_processed_line: + processed_line = self._last_get_processed_line(position.y) + + # Translate coordinates back to the cursor position of the + # original input. + xpos = processed_line.display_to_source(position.x) + index = buffer.document.translate_row_col_to_index(position.y, xpos) + + # Set the cursor position. + if mouse_event.event_type == MouseEventType.MOUSE_DOWN: + buffer.exit_selection() + buffer.cursor_position = index + + elif mouse_event.event_type == MouseEventType.MOUSE_UP: + # When the cursor was moved to another place, select the text. + # (The >1 is actually a small but acceptable workaround for + # selecting text in Vi navigation mode. In navigation mode, + # the cursor can never be after the text, so the cursor + # will be repositioned automatically.) + if abs(buffer.cursor_position - index) > 1: + buffer.start_selection(selection_type=SelectionType.CHARACTERS) + buffer.cursor_position = index + + # Select word around cursor on double click. + # Two MOUSE_UP events in a short timespan are considered a double click. + double_click = ( + self._last_click_timestamp + and time.time() - self._last_click_timestamp < 0.3 + ) + self._last_click_timestamp = time.time() + + if double_click: + start, end = buffer.document.find_boundaries_of_current_word() + buffer.cursor_position += start + buffer.start_selection(selection_type=SelectionType.CHARACTERS) + buffer.cursor_position += end - start + else: + # Don't handle scroll events here. + return NotImplemented + + # Not focused, but focusing on click events. + else: + if ( + self.focus_on_click() + and mouse_event.event_type == MouseEventType.MOUSE_UP + ): + # Focus happens on mouseup. (If we did this on mousedown, the + # up event will be received at the point where this widget is + # focused and be handled anyway.) + get_app().layout.current_control = self + else: + return NotImplemented + + return None + + def move_cursor_down(self) -> None: + b = self.buffer + b.cursor_position += b.document.get_cursor_down_position() + + def move_cursor_up(self) -> None: + b = self.buffer + b.cursor_position += b.document.get_cursor_up_position() + + def get_key_bindings(self) -> Optional["KeyBindingsBase"]: + """ + When additional key bindings are given. Return these. + """ + return self.key_bindings + + def get_invalidate_events(self) -> Iterable["Event[object]"]: + """ + Return the Window invalidate events. + """ + # Whenever the buffer changes, the UI has to be updated. + yield self.buffer.on_text_changed + yield self.buffer.on_cursor_position_changed + + yield self.buffer.on_completions_changed + yield self.buffer.on_suggestion_set + + +class SearchBufferControl(BufferControl): + """ + :class:`.BufferControl` which is used for searching another + :class:`.BufferControl`. + + :param ignore_case: Search case insensitive. + """ + + def __init__( + self, + buffer: Optional[Buffer] = None, + input_processors: Optional[List[Processor]] = None, + lexer: Optional[Lexer] = None, + focus_on_click: FilterOrBool = False, + key_bindings: Optional["KeyBindingsBase"] = None, + ignore_case: FilterOrBool = False, + ): + + super().__init__( + buffer=buffer, + input_processors=input_processors, + lexer=lexer, + focus_on_click=focus_on_click, + key_bindings=key_bindings, + ) + + # If this BufferControl is used as a search field for one or more other + # BufferControls, then represents the search state. + self.searcher_search_state = SearchState(ignore_case=ignore_case) diff --git a/.venv/lib/python3.8/site-packages/prompt_toolkit/layout/dimension.py b/.venv/lib/python3.8/site-packages/prompt_toolkit/layout/dimension.py new file mode 100644 index 00000000..1e41ccdc --- /dev/null +++ b/.venv/lib/python3.8/site-packages/prompt_toolkit/layout/dimension.py @@ -0,0 +1,214 @@ +""" +Layout dimensions are used to give the minimum, maximum and preferred +dimensions for containers and controls. +""" +from typing import Any, Callable, List, Optional, Union + +__all__ = [ + "Dimension", + "D", + "sum_layout_dimensions", + "max_layout_dimensions", + "AnyDimension", + "to_dimension", + "is_dimension", +] + + +class Dimension: + """ + Specified dimension (width/height) of a user control or window. + + The layout engine tries to honor the preferred size. If that is not + possible, because the terminal is larger or smaller, it tries to keep in + between min and max. + + :param min: Minimum size. + :param max: Maximum size. + :param weight: For a VSplit/HSplit, the actual size will be determined + by taking the proportion of weights from all the children. + E.g. When there are two children, one with a weight of 1, + and the other with a weight of 2, the second will always be + twice as big as the first, if the min/max values allow it. + :param preferred: Preferred size. + """ + + def __init__( + self, + min: Optional[int] = None, + max: Optional[int] = None, + weight: Optional[int] = None, + preferred: Optional[int] = None, + ) -> None: + if weight is not None: + assert weight >= 0 # Also cannot be a float. + + assert min is None or min >= 0 + assert max is None or max >= 0 + assert preferred is None or preferred >= 0 + + self.min_specified = min is not None + self.max_specified = max is not None + self.preferred_specified = preferred is not None + self.weight_specified = weight is not None + + if min is None: + min = 0 # Smallest possible value. + if max is None: # 0-values are allowed, so use "is None" + max = 1000 ** 10 # Something huge. + if preferred is None: + preferred = min + if weight is None: + weight = 1 + + self.min = min + self.max = max + self.preferred = preferred + self.weight = weight + + # Don't allow situations where max < min. (This would be a bug.) + if max < min: + raise ValueError("Invalid Dimension: max < min.") + + # Make sure that the 'preferred' size is always in the min..max range. + if self.preferred < self.min: + self.preferred = self.min + + if self.preferred > self.max: + self.preferred = self.max + + @classmethod + def exact(cls, amount: int) -> "Dimension": + """ + Return a :class:`.Dimension` with an exact size. (min, max and + preferred set to ``amount``). + """ + return cls(min=amount, max=amount, preferred=amount) + + @classmethod + def zero(cls) -> "Dimension": + """ + Create a dimension that represents a zero size. (Used for 'invisible' + controls.) + """ + return cls.exact(amount=0) + + def is_zero(self) -> bool: + " True if this `Dimension` represents a zero size. " + return self.preferred == 0 or self.max == 0 + + def __repr__(self) -> str: + fields = [] + if self.min_specified: + fields.append("min=%r" % self.min) + if self.max_specified: + fields.append("max=%r" % self.max) + if self.preferred_specified: + fields.append("preferred=%r" % self.preferred) + if self.weight_specified: + fields.append("weight=%r" % self.weight) + + return "Dimension(%s)" % ", ".join(fields) + + +def sum_layout_dimensions(dimensions: List[Dimension]) -> Dimension: + """ + Sum a list of :class:`.Dimension` instances. + """ + min = sum(d.min for d in dimensions) + max = sum(d.max for d in dimensions) + preferred = sum(d.preferred for d in dimensions) + + return Dimension(min=min, max=max, preferred=preferred) + + +def max_layout_dimensions(dimensions: List[Dimension]) -> Dimension: + """ + Take the maximum of a list of :class:`.Dimension` instances. + Used when we have a HSplit/VSplit, and we want to get the best width/height.) + """ + if not len(dimensions): + return Dimension.zero() + + # If all dimensions are size zero. Return zero. + # (This is important for HSplit/VSplit, to report the right values to their + # parent when all children are invisible.) + if all(d.is_zero() for d in dimensions): + return dimensions[0] + + # Ignore empty dimensions. (They should not reduce the size of others.) + dimensions = [d for d in dimensions if not d.is_zero()] + + if dimensions: + # Take the highest minimum dimension. + min_ = max(d.min for d in dimensions) + + # For the maximum, we would prefer not to go larger than then smallest + # 'max' value, unless other dimensions have a bigger preferred value. + # This seems to work best: + # - We don't want that a widget with a small height in a VSplit would + # shrink other widgets in the split. + # If it doesn't work well enough, then it's up to the UI designer to + # explicitly pass dimensions. + max_ = min(d.max for d in dimensions) + max_ = max(max_, max(d.preferred for d in dimensions)) + + # Make sure that min>=max. In some scenarios, when certain min..max + # ranges don't have any overlap, we can end up in such an impossible + # situation. In that case, give priority to the max value. + # E.g. taking (1..5) and (8..9) would return (8..5). Instead take (8..8). + if min_ > max_: + max_ = min_ + + preferred = max(d.preferred for d in dimensions) + + return Dimension(min=min_, max=max_, preferred=preferred) + else: + return Dimension() + + +# Anything that can be converted to a dimension. +AnyDimension = Union[ + None, # None is a valid dimension that will fit anything. + int, + Dimension, + # Callable[[], 'AnyDimension'] # Recursive definition not supported by mypy. + Callable[[], Any], +] + + +def to_dimension(value: AnyDimension) -> Dimension: + """ + Turn the given object into a `Dimension` object. + """ + if value is None: + return Dimension() + if isinstance(value, int): + return Dimension.exact(value) + if isinstance(value, Dimension): + return value + if callable(value): + return to_dimension(value()) + + raise ValueError("Not an integer or Dimension object.") + + +def is_dimension(value: object) -> bool: + """ + Test whether the given value could be a valid dimension. + (For usage in an assertion. It's not guaranteed in case of a callable.) + """ + if value is None: + return True + if callable(value): + return True # Assume it's a callable that doesn't take arguments. + if isinstance(value, (int, Dimension)): + return True + return False + + +# Common alias. +D = Dimension + +# For backward-compatibility. +LayoutDimension = Dimension diff --git a/.venv/lib/python3.8/site-packages/prompt_toolkit/layout/dummy.py b/.venv/lib/python3.8/site-packages/prompt_toolkit/layout/dummy.py new file mode 100644 index 00000000..dcd54e9f --- /dev/null +++ b/.venv/lib/python3.8/site-packages/prompt_toolkit/layout/dummy.py @@ -0,0 +1,37 @@ +""" +Dummy layout. Used when somebody creates an `Application` without specifying a +`Layout`. +""" +from prompt_toolkit.formatted_text import HTML +from prompt_toolkit.key_binding import KeyBindings +from prompt_toolkit.key_binding.key_processor import KeyPressEvent + +from .containers import Window +from .controls import FormattedTextControl +from .dimension import D +from .layout import Layout + +__all__ = [ + "create_dummy_layout", +] + +E = KeyPressEvent + + +def create_dummy_layout() -> Layout: + """ + Create a dummy layout for use in an 'Application' that doesn't have a + layout specified. When ENTER is pressed, the application quits. + """ + kb = KeyBindings() + + @kb.add("enter") + def enter(event: E) -> None: + event.app.exit() + + control = FormattedTextControl( + HTML("No layout specified. Press ENTER to quit."), + key_bindings=kb, + ) + window = Window(content=control, height=D(min=1)) + return Layout(container=window, focused_element=window) diff --git a/.venv/lib/python3.8/site-packages/prompt_toolkit/layout/layout.py b/.venv/lib/python3.8/site-packages/prompt_toolkit/layout/layout.py new file mode 100644 index 00000000..457558fd --- /dev/null +++ b/.venv/lib/python3.8/site-packages/prompt_toolkit/layout/layout.py @@ -0,0 +1,417 @@ +""" +Wrapper for the layout. +""" +from typing import Dict, Generator, Iterable, List, Optional, Union + +from prompt_toolkit.buffer import Buffer + +from .containers import ( + AnyContainer, + ConditionalContainer, + Container, + Window, + to_container, +) +from .controls import BufferControl, SearchBufferControl, UIControl + +__all__ = [ + "Layout", + "InvalidLayoutError", + "walk", +] + +FocusableElement = Union[str, Buffer, UIControl, AnyContainer] + + +class Layout: + """ + The layout for a prompt_toolkit + :class:`~prompt_toolkit.application.Application`. + This also keeps track of which user control is focused. + + :param container: The "root" container for the layout. + :param focused_element: element to be focused initially. (Can be anything + the `focus` function accepts.) + """ + + def __init__( + self, + container: AnyContainer, + focused_element: Optional[FocusableElement] = None, + ) -> None: + + self.container = to_container(container) + self._stack: List[Window] = [] + + # Map search BufferControl back to the original BufferControl. + # This is used to keep track of when exactly we are searching, and for + # applying the search. + # When a link exists in this dictionary, that means the search is + # currently active. + # Map: search_buffer_control -> original buffer control. + self.search_links: Dict[SearchBufferControl, BufferControl] = {} + + # Mapping that maps the children in the layout to their parent. + # This relationship is calculated dynamically, each time when the UI + # is rendered. (UI elements have only references to their children.) + self._child_to_parent: Dict[Container, Container] = {} + + if focused_element is None: + try: + self._stack.append(next(self.find_all_windows())) + except StopIteration as e: + raise InvalidLayoutError( + "Invalid layout. The layout does not contain any Window object." + ) from e + else: + self.focus(focused_element) + + # List of visible windows. + self.visible_windows: List[Window] = [] # List of `Window` objects. + + def __repr__(self) -> str: + return "Layout(%r, current_window=%r)" % (self.container, self.current_window) + + def find_all_windows(self) -> Generator[Window, None, None]: + """ + Find all the :class:`.UIControl` objects in this layout. + """ + for item in self.walk(): + if isinstance(item, Window): + yield item + + def find_all_controls(self) -> Iterable[UIControl]: + for container in self.find_all_windows(): + yield container.content + + def focus(self, value: FocusableElement) -> None: + """ + Focus the given UI element. + + `value` can be either: + + - a :class:`.UIControl` + - a :class:`.Buffer` instance or the name of a :class:`.Buffer` + - a :class:`.Window` + - Any container object. In this case we will focus the :class:`.Window` + from this container that was focused most recent, or the very first + focusable :class:`.Window` of the container. + """ + # BufferControl by buffer name. + if isinstance(value, str): + for control in self.find_all_controls(): + if isinstance(control, BufferControl) and control.buffer.name == value: + self.focus(control) + return + raise ValueError( + "Couldn't find Buffer in the current layout: %r." % (value,) + ) + + # BufferControl by buffer object. + elif isinstance(value, Buffer): + for control in self.find_all_controls(): + if isinstance(control, BufferControl) and control.buffer == value: + self.focus(control) + return + raise ValueError( + "Couldn't find Buffer in the current layout: %r." % (value,) + ) + + # Focus UIControl. + elif isinstance(value, UIControl): + if value not in self.find_all_controls(): + raise ValueError( + "Invalid value. Container does not appear in the layout." + ) + if not value.is_focusable(): + raise ValueError("Invalid value. UIControl is not focusable.") + + self.current_control = value + + # Otherwise, expecting any Container object. + else: + value = to_container(value) + + if isinstance(value, Window): + # This is a `Window`: focus that. + if value not in self.find_all_windows(): + raise ValueError( + "Invalid value. Window does not appear in the layout: %r" + % (value,) + ) + + self.current_window = value + else: + # Focus a window in this container. + # If we have many windows as part of this container, and some + # of them have been focused before, take the last focused + # item. (This is very useful when the UI is composed of more + # complex sub components.) + windows = [] + for c in walk(value, skip_hidden=True): + if isinstance(c, Window) and c.content.is_focusable(): + windows.append(c) + + # Take the first one that was focused before. + for w in reversed(self._stack): + if w in windows: + self.current_window = w + return + + # None was focused before: take the very first focusable window. + if windows: + self.current_window = windows[0] + return + + raise ValueError( + "Invalid value. Container cannot be focused: %r" % (value,) + ) + + def has_focus(self, value: FocusableElement) -> bool: + """ + Check whether the given control has the focus. + :param value: :class:`.UIControl` or :class:`.Window` instance. + """ + if isinstance(value, str): + if self.current_buffer is None: + return False + return self.current_buffer.name == value + if isinstance(value, Buffer): + return self.current_buffer == value + if isinstance(value, UIControl): + return self.current_control == value + else: + value = to_container(value) + if isinstance(value, Window): + return self.current_window == value + else: + # Check whether this "container" is focused. This is true if + # one of the elements inside is focused. + for element in walk(value): + if element == self.current_window: + return True + return False + + @property + def current_control(self) -> UIControl: + """ + Get the :class:`.UIControl` to currently has the focus. + """ + return self._stack[-1].content + + @current_control.setter + def current_control(self, control: UIControl) -> None: + """ + Set the :class:`.UIControl` to receive the focus. + """ + for window in self.find_all_windows(): + if window.content == control: + self.current_window = window + return + + raise ValueError("Control not found in the user interface.") + + @property + def current_window(self) -> Window: + " Return the :class:`.Window` object that is currently focused. " + return self._stack[-1] + + @current_window.setter + def current_window(self, value: Window): + " Set the :class:`.Window` object to be currently focused. " + self._stack.append(value) + + @property + def is_searching(self) -> bool: + " True if we are searching right now. " + return self.current_control in self.search_links + + @property + def search_target_buffer_control(self) -> Optional[BufferControl]: + """ + Return the :class:`.BufferControl` in which we are searching or `None`. + """ + # Not every `UIControl` is a `BufferControl`. This only applies to + # `BufferControl`. + control = self.current_control + + if isinstance(control, SearchBufferControl): + return self.search_links.get(control) + else: + return None + + def get_focusable_windows(self) -> Iterable[Window]: + """ + Return all the :class:`.Window` objects which are focusable (in the + 'modal' area). + """ + for w in self.walk_through_modal_area(): + if isinstance(w, Window) and w.content.is_focusable(): + yield w + + def get_visible_focusable_windows(self) -> List[Window]: + """ + Return a list of :class:`.Window` objects that are focusable. + """ + # focusable windows are windows that are visible, but also part of the + # modal container. Make sure to keep the ordering. + visible_windows = self.visible_windows + return [w for w in self.get_focusable_windows() if w in visible_windows] + + @property + def current_buffer(self) -> Optional[Buffer]: + """ + The currently focused :class:`~.Buffer` or `None`. + """ + ui_control = self.current_control + if isinstance(ui_control, BufferControl): + return ui_control.buffer + return None + + def get_buffer_by_name(self, buffer_name: str) -> Optional[Buffer]: + """ + Look in the layout for a buffer with the given name. + Return `None` when nothing was found. + """ + for w in self.walk(): + if isinstance(w, Window) and isinstance(w.content, BufferControl): + if w.content.buffer.name == buffer_name: + return w.content.buffer + return None + + @property + def buffer_has_focus(self) -> bool: + """ + Return `True` if the currently focused control is a + :class:`.BufferControl`. (For instance, used to determine whether the + default key bindings should be active or not.) + """ + ui_control = self.current_control + return isinstance(ui_control, BufferControl) + + @property + def previous_control(self) -> UIControl: + """ + Get the :class:`.UIControl` to previously had the focus. + """ + try: + return self._stack[-2].content + except IndexError: + return self._stack[-1].content + + def focus_last(self) -> None: + """ + Give the focus to the last focused control. + """ + if len(self._stack) > 1: + self._stack = self._stack[:-1] + + def focus_next(self) -> None: + """ + Focus the next visible/focusable Window. + """ + windows = self.get_visible_focusable_windows() + + if len(windows) > 0: + try: + index = windows.index(self.current_window) + except ValueError: + index = 0 + else: + index = (index + 1) % len(windows) + + self.focus(windows[index]) + + def focus_previous(self) -> None: + """ + Focus the previous visible/focusable Window. + """ + windows = self.get_visible_focusable_windows() + + if len(windows) > 0: + try: + index = windows.index(self.current_window) + except ValueError: + index = 0 + else: + index = (index - 1) % len(windows) + + self.focus(windows[index]) + + def walk(self) -> Iterable[Container]: + """ + Walk through all the layout nodes (and their children) and yield them. + """ + for i in walk(self.container): + yield i + + def walk_through_modal_area(self) -> Iterable[Container]: + """ + Walk through all the containers which are in the current 'modal' part + of the layout. + """ + # Go up in the tree, and find the root. (it will be a part of the + # layout, if the focus is in a modal part.) + root: Container = self.current_window + while not root.is_modal() and root in self._child_to_parent: + root = self._child_to_parent[root] + + for container in walk(root): + yield container + + def update_parents_relations(self) -> None: + """ + Update child->parent relationships mapping. + """ + parents = {} + + def walk(e: Container) -> None: + for c in e.get_children(): + parents[c] = e + walk(c) + + walk(self.container) + + self._child_to_parent = parents + + def reset(self) -> None: + # Remove all search links when the UI starts. + # (Important, for instance when control-c is been pressed while + # searching. The prompt cancels, but next `run()` call the search + # links are still there.) + self.search_links.clear() + + self.container.reset() + + def get_parent(self, container: Container) -> Optional[Container]: + """ + Return the parent container for the given container, or ``None``, if it + wasn't found. + """ + try: + return self._child_to_parent[container] + except KeyError: + return None + + +class InvalidLayoutError(Exception): + pass + + +def walk(container: Container, skip_hidden: bool = False) -> Iterable[Container]: + """ + Walk through layout, starting at this container. + """ + # When `skip_hidden` is set, don't go into disabled ConditionalContainer containers. + if ( + skip_hidden + and isinstance(container, ConditionalContainer) + and not container.filter() + ): + return + + yield container + + for c in container.get_children(): + # yield from walk(c) + yield from walk(c, skip_hidden=skip_hidden) diff --git a/.venv/lib/python3.8/site-packages/prompt_toolkit/layout/margins.py b/.venv/lib/python3.8/site-packages/prompt_toolkit/layout/margins.py new file mode 100644 index 00000000..9348fb5e --- /dev/null +++ b/.venv/lib/python3.8/site-packages/prompt_toolkit/layout/margins.py @@ -0,0 +1,305 @@ +""" +Margin implementations for a :class:`~prompt_toolkit.layout.containers.Window`. +""" +from abc import ABCMeta, abstractmethod +from typing import TYPE_CHECKING, Callable, Optional + +from prompt_toolkit.filters import FilterOrBool, to_filter +from prompt_toolkit.formatted_text import ( + StyleAndTextTuples, + fragment_list_to_text, + to_formatted_text, +) +from prompt_toolkit.utils import get_cwidth + +from .controls import UIContent + +if TYPE_CHECKING: + from .containers import WindowRenderInfo + +__all__ = [ + "Margin", + "NumberedMargin", + "ScrollbarMargin", + "ConditionalMargin", + "PromptMargin", +] + + +class Margin(metaclass=ABCMeta): + """ + Base interface for a margin. + """ + + @abstractmethod + def get_width(self, get_ui_content: Callable[[], UIContent]) -> int: + """ + Return the width that this margin is going to consume. + + :param get_ui_content: Callable that asks the user control to create + a :class:`.UIContent` instance. This can be used for instance to + obtain the number of lines. + """ + return 0 + + @abstractmethod + def create_margin( + self, window_render_info: "WindowRenderInfo", width: int, height: int + ) -> StyleAndTextTuples: + """ + Creates a margin. + This should return a list of (style_str, text) tuples. + + :param window_render_info: + :class:`~prompt_toolkit.layout.containers.WindowRenderInfo` + instance, generated after rendering and copying the visible part of + the :class:`~prompt_toolkit.layout.controls.UIControl` into the + :class:`~prompt_toolkit.layout.containers.Window`. + :param width: The width that's available for this margin. (As reported + by :meth:`.get_width`.) + :param height: The height that's available for this margin. (The height + of the :class:`~prompt_toolkit.layout.containers.Window`.) + """ + return [] + + +class NumberedMargin(Margin): + """ + Margin that displays the line numbers. + + :param relative: Number relative to the cursor position. Similar to the Vi + 'relativenumber' option. + :param display_tildes: Display tildes after the end of the document, just + like Vi does. + """ + + def __init__( + self, relative: FilterOrBool = False, display_tildes: FilterOrBool = False + ) -> None: + + self.relative = to_filter(relative) + self.display_tildes = to_filter(display_tildes) + + def get_width(self, get_ui_content: Callable[[], UIContent]) -> int: + line_count = get_ui_content().line_count + return max(3, len("%s" % line_count) + 1) + + def create_margin( + self, window_render_info: "WindowRenderInfo", width: int, height: int + ) -> StyleAndTextTuples: + relative = self.relative() + + style = "class:line-number" + style_current = "class:line-number.current" + + # Get current line number. + current_lineno = window_render_info.ui_content.cursor_position.y + + # Construct margin. + result: StyleAndTextTuples = [] + last_lineno = None + + for y, lineno in enumerate(window_render_info.displayed_lines): + # Only display line number if this line is not a continuation of the previous line. + if lineno != last_lineno: + if lineno is None: + pass + elif lineno == current_lineno: + # Current line. + if relative: + # Left align current number in relative mode. + result.append((style_current, "%i" % (lineno + 1))) + else: + result.append( + (style_current, ("%i " % (lineno + 1)).rjust(width)) + ) + else: + # Other lines. + if relative: + lineno = abs(lineno - current_lineno) - 1 + + result.append((style, ("%i " % (lineno + 1)).rjust(width))) + + last_lineno = lineno + result.append(("", "\n")) + + # Fill with tildes. + if self.display_tildes(): + while y < window_render_info.window_height: + result.append(("class:tilde", "~\n")) + y += 1 + + return result + + +class ConditionalMargin(Margin): + """ + Wrapper around other :class:`.Margin` classes to show/hide them. + """ + + def __init__(self, margin: Margin, filter: FilterOrBool) -> None: + self.margin = margin + self.filter = to_filter(filter) + + def get_width(self, get_ui_content: Callable[[], UIContent]) -> int: + if self.filter(): + return self.margin.get_width(get_ui_content) + else: + return 0 + + def create_margin( + self, window_render_info: "WindowRenderInfo", width: int, height: int + ) -> StyleAndTextTuples: + if width and self.filter(): + return self.margin.create_margin(window_render_info, width, height) + else: + return [] + + +class ScrollbarMargin(Margin): + """ + Margin displaying a scrollbar. + + :param display_arrows: Display scroll up/down arrows. + """ + + def __init__( + self, + display_arrows: FilterOrBool = False, + up_arrow_symbol: str = "^", + down_arrow_symbol: str = "v", + ) -> None: + + self.display_arrows = to_filter(display_arrows) + self.up_arrow_symbol = up_arrow_symbol + self.down_arrow_symbol = down_arrow_symbol + + def get_width(self, get_ui_content: Callable[[], UIContent]) -> int: + return 1 + + def create_margin( + self, window_render_info: "WindowRenderInfo", width: int, height: int + ) -> StyleAndTextTuples: + content_height = window_render_info.content_height + window_height = window_render_info.window_height + display_arrows = self.display_arrows() + + if display_arrows: + window_height -= 2 + + try: + fraction_visible = len(window_render_info.displayed_lines) / float( + content_height + ) + fraction_above = window_render_info.vertical_scroll / float(content_height) + + scrollbar_height = int( + min(window_height, max(1, window_height * fraction_visible)) + ) + scrollbar_top = int(window_height * fraction_above) + except ZeroDivisionError: + return [] + else: + + def is_scroll_button(row: int) -> bool: + " True if we should display a button on this row. " + return scrollbar_top <= row <= scrollbar_top + scrollbar_height + + # Up arrow. + result: StyleAndTextTuples = [] + if display_arrows: + result.extend( + [ + ("class:scrollbar.arrow", self.up_arrow_symbol), + ("class:scrollbar", "\n"), + ] + ) + + # Scrollbar body. + scrollbar_background = "class:scrollbar.background" + scrollbar_background_start = "class:scrollbar.background,scrollbar.start" + scrollbar_button = "class:scrollbar.button" + scrollbar_button_end = "class:scrollbar.button,scrollbar.end" + + for i in range(window_height): + if is_scroll_button(i): + if not is_scroll_button(i + 1): + # Give the last cell a different style, because we + # want to underline this. + result.append((scrollbar_button_end, " ")) + else: + result.append((scrollbar_button, " ")) + else: + if is_scroll_button(i + 1): + result.append((scrollbar_background_start, " ")) + else: + result.append((scrollbar_background, " ")) + result.append(("", "\n")) + + # Down arrow + if display_arrows: + result.append(("class:scrollbar.arrow", self.down_arrow_symbol)) + + return result + + +class PromptMargin(Margin): + """ + [Deprecated] + + Create margin that displays a prompt. + This can display one prompt at the first line, and a continuation prompt + (e.g, just dots) on all the following lines. + + This `PromptMargin` implementation has been largely superseded in favor of + the `get_line_prefix` attribute of `Window`. The reason is that a margin is + always a fixed width, while `get_line_prefix` can return a variable width + prefix in front of every line, making it more powerful, especially for line + continuations. + + :param get_prompt: Callable returns formatted text or a list of + `(style_str, type)` tuples to be shown as the prompt at the first line. + :param get_continuation: Callable that takes three inputs. The width (int), + line_number (int), and is_soft_wrap (bool). It should return formatted + text or a list of `(style_str, type)` tuples for the next lines of the + input. + """ + + def __init__( + self, + get_prompt: Callable[[], StyleAndTextTuples], + get_continuation: Optional[ + Callable[[int, int, bool], StyleAndTextTuples] + ] = None, + ) -> None: + + self.get_prompt = get_prompt + self.get_continuation = get_continuation + + def get_width(self, get_ui_content: Callable[[], UIContent]) -> int: + " Width to report to the `Window`. " + # Take the width from the first line. + text = fragment_list_to_text(self.get_prompt()) + return get_cwidth(text) + + def create_margin( + self, window_render_info: "WindowRenderInfo", width: int, height: int + ) -> StyleAndTextTuples: + get_continuation = self.get_continuation + result: StyleAndTextTuples = [] + + # First line. + result.extend(to_formatted_text(self.get_prompt())) + + # Next lines. + if get_continuation: + last_y = None + + for y in window_render_info.displayed_lines[1:]: + result.append(("", "\n")) + result.extend( + to_formatted_text(get_continuation(width, y, y == last_y)) + ) + last_y = y + + return result diff --git a/.venv/lib/python3.8/site-packages/prompt_toolkit/layout/menus.py b/.venv/lib/python3.8/site-packages/prompt_toolkit/layout/menus.py new file mode 100644 index 00000000..2663bd29 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/prompt_toolkit/layout/menus.py @@ -0,0 +1,720 @@ +import math +from itertools import zip_longest +from typing import ( + TYPE_CHECKING, + Callable, + Dict, + Iterable, + List, + Optional, + Tuple, + TypeVar, + Union, + cast, +) + +from prompt_toolkit.application.current import get_app +from prompt_toolkit.buffer import CompletionState +from prompt_toolkit.completion import Completion +from prompt_toolkit.data_structures import Point +from prompt_toolkit.filters import ( + Condition, + FilterOrBool, + has_completions, + is_done, + to_filter, +) +from prompt_toolkit.formatted_text import ( + StyleAndTextTuples, + fragment_list_width, + to_formatted_text, +) +from prompt_toolkit.key_binding.key_processor import KeyPressEvent +from prompt_toolkit.layout.utils import explode_text_fragments +from prompt_toolkit.mouse_events import MouseEvent, MouseEventType +from prompt_toolkit.utils import get_cwidth + +from .containers import ConditionalContainer, HSplit, ScrollOffsets, Window +from .controls import GetLinePrefixCallable, UIContent, UIControl +from .dimension import Dimension +from .margins import ScrollbarMargin + +if TYPE_CHECKING: + from prompt_toolkit.key_binding.key_bindings import KeyBindings + + NotImplementedOrNone = object + +__all__ = [ + "CompletionsMenu", + "MultiColumnCompletionsMenu", +] + +E = KeyPressEvent + + +class CompletionsMenuControl(UIControl): + """ + Helper for drawing the complete menu to the screen. + + :param scroll_offset: Number (integer) representing the preferred amount of + completions to be displayed before and after the current one. When this + is a very high number, the current completion will be shown in the + middle most of the time. + """ + + # Preferred minimum size of the menu control. + # The CompletionsMenu class defines a width of 8, and there is a scrollbar + # of 1.) + MIN_WIDTH = 7 + + def has_focus(self) -> bool: + return False + + def preferred_width(self, max_available_width: int) -> Optional[int]: + complete_state = get_app().current_buffer.complete_state + if complete_state: + menu_width = self._get_menu_width(500, complete_state) + menu_meta_width = self._get_menu_meta_width(500, complete_state) + + return menu_width + menu_meta_width + else: + return 0 + + def preferred_height( + self, + width: int, + max_available_height: int, + wrap_lines: bool, + get_line_prefix: Optional[GetLinePrefixCallable], + ) -> Optional[int]: + + complete_state = get_app().current_buffer.complete_state + if complete_state: + return len(complete_state.completions) + else: + return 0 + + def create_content(self, width: int, height: int) -> UIContent: + """ + Create a UIContent object for this control. + """ + complete_state = get_app().current_buffer.complete_state + if complete_state: + completions = complete_state.completions + index = complete_state.complete_index # Can be None! + + # Calculate width of completions menu. + menu_width = self._get_menu_width(width, complete_state) + menu_meta_width = self._get_menu_meta_width( + width - menu_width, complete_state + ) + show_meta = self._show_meta(complete_state) + + def get_line(i: int) -> StyleAndTextTuples: + c = completions[i] + is_current_completion = i == index + result = _get_menu_item_fragments( + c, is_current_completion, menu_width, space_after=True + ) + + if show_meta: + result += self._get_menu_item_meta_fragments( + c, is_current_completion, menu_meta_width + ) + return result + + return UIContent( + get_line=get_line, + cursor_position=Point(x=0, y=index or 0), + line_count=len(completions), + ) + + return UIContent() + + def _show_meta(self, complete_state: CompletionState) -> bool: + """ + Return ``True`` if we need to show a column with meta information. + """ + return any(c.display_meta_text for c in complete_state.completions) + + def _get_menu_width(self, max_width: int, complete_state: CompletionState) -> int: + """ + Return the width of the main column. + """ + return min( + max_width, + max( + self.MIN_WIDTH, + max(get_cwidth(c.display_text) for c in complete_state.completions) + 2, + ), + ) + + def _get_menu_meta_width( + self, max_width: int, complete_state: CompletionState + ) -> int: + """ + Return the width of the meta column. + """ + + def meta_width(completion: Completion) -> int: + return get_cwidth(completion.display_meta_text) + + if self._show_meta(complete_state): + return min( + max_width, max(meta_width(c) for c in complete_state.completions) + 2 + ) + else: + return 0 + + def _get_menu_item_meta_fragments( + self, completion: Completion, is_current_completion: bool, width: int + ) -> StyleAndTextTuples: + + if is_current_completion: + style_str = "class:completion-menu.meta.completion.current" + else: + style_str = "class:completion-menu.meta.completion" + + text, tw = _trim_formatted_text(completion.display_meta, width - 2) + padding = " " * (width - 1 - tw) + + return to_formatted_text( + cast(StyleAndTextTuples, []) + [("", " ")] + text + [("", padding)], + style=style_str, + ) + + def mouse_handler(self, mouse_event: MouseEvent) -> "NotImplementedOrNone": + """ + Handle mouse events: clicking and scrolling. + """ + b = get_app().current_buffer + + if mouse_event.event_type == MouseEventType.MOUSE_UP: + # Select completion. + b.go_to_completion(mouse_event.position.y) + b.complete_state = None + + elif mouse_event.event_type == MouseEventType.SCROLL_DOWN: + # Scroll up. + b.complete_next(count=3, disable_wrap_around=True) + + elif mouse_event.event_type == MouseEventType.SCROLL_UP: + # Scroll down. + b.complete_previous(count=3, disable_wrap_around=True) + + return None + + +def _get_menu_item_fragments( + completion: Completion, + is_current_completion: bool, + width: int, + space_after: bool = False, +) -> StyleAndTextTuples: + """ + Get the style/text tuples for a menu item, styled and trimmed to the given + width. + """ + if is_current_completion: + style_str = "class:completion-menu.completion.current %s %s" % ( + completion.style, + completion.selected_style, + ) + else: + style_str = "class:completion-menu.completion " + completion.style + + text, tw = _trim_formatted_text( + completion.display, (width - 2 if space_after else width - 1) + ) + + padding = " " * (width - 1 - tw) + + return to_formatted_text( + cast(StyleAndTextTuples, []) + [("", " ")] + text + [("", padding)], + style=style_str, + ) + + +def _trim_formatted_text( + formatted_text: StyleAndTextTuples, max_width: int +) -> Tuple[StyleAndTextTuples, int]: + """ + Trim the text to `max_width`, append dots when the text is too long. + Returns (text, width) tuple. + """ + width = fragment_list_width(formatted_text) + + # When the text is too wide, trim it. + if width > max_width: + result = [] # Text fragments. + remaining_width = max_width - 3 + + for style_and_ch in explode_text_fragments(formatted_text): + ch_width = get_cwidth(style_and_ch[1]) + + if ch_width <= remaining_width: + result.append(style_and_ch) + remaining_width -= ch_width + else: + break + + result.append(("", "...")) + + return result, max_width - remaining_width + else: + return formatted_text, width + + +class CompletionsMenu(ConditionalContainer): + # NOTE: We use a pretty big z_index by default. Menus are supposed to be + # above anything else. We also want to make sure that the content is + # visible at the point where we draw this menu. + def __init__( + self, + max_height: Optional[int] = None, + scroll_offset: Union[int, Callable[[], int]] = 0, + extra_filter: FilterOrBool = True, + display_arrows: FilterOrBool = False, + z_index: int = 10 ** 8, + ) -> None: + + extra_filter = to_filter(extra_filter) + display_arrows = to_filter(display_arrows) + + super().__init__( + content=Window( + content=CompletionsMenuControl(), + width=Dimension(min=8), + height=Dimension(min=1, max=max_height), + scroll_offsets=ScrollOffsets(top=scroll_offset, bottom=scroll_offset), + right_margins=[ScrollbarMargin(display_arrows=display_arrows)], + dont_extend_width=True, + style="class:completion-menu", + z_index=z_index, + ), + # Show when there are completions but not at the point we are + # returning the input. + filter=has_completions & ~is_done & extra_filter, + ) + + +class MultiColumnCompletionMenuControl(UIControl): + """ + Completion menu that displays all the completions in several columns. + When there are more completions than space for them to be displayed, an + arrow is shown on the left or right side. + + `min_rows` indicates how many rows will be available in any possible case. + When this is larger than one, it will try to use less columns and more + rows until this value is reached. + Be careful passing in a too big value, if less than the given amount of + rows are available, more columns would have been required, but + `preferred_width` doesn't know about that and reports a too small value. + This results in less completions displayed and additional scrolling. + (It's a limitation of how the layout engine currently works: first the + widths are calculated, then the heights.) + + :param suggested_max_column_width: The suggested max width of a column. + The column can still be bigger than this, but if there is place for two + columns of this width, we will display two columns. This to avoid that + if there is one very wide completion, that it doesn't significantly + reduce the amount of columns. + """ + + _required_margin = 3 # One extra padding on the right + space for arrows. + + def __init__(self, min_rows: int = 3, suggested_max_column_width: int = 30) -> None: + assert min_rows >= 1 + + self.min_rows = min_rows + self.suggested_max_column_width = suggested_max_column_width + self.scroll = 0 + + # Info of last rendering. + self._rendered_rows = 0 + self._rendered_columns = 0 + self._total_columns = 0 + self._render_pos_to_completion: Dict[Tuple[int, int], Completion] = {} + self._render_left_arrow = False + self._render_right_arrow = False + self._render_width = 0 + + def reset(self) -> None: + self.scroll = 0 + + def has_focus(self) -> bool: + return False + + def preferred_width(self, max_available_width: int) -> Optional[int]: + """ + Preferred width: prefer to use at least min_rows, but otherwise as much + as possible horizontally. + """ + complete_state = get_app().current_buffer.complete_state + if complete_state is None: + return 0 + + column_width = self._get_column_width(complete_state) + result = int( + column_width + * math.ceil(len(complete_state.completions) / float(self.min_rows)) + ) + + # When the desired width is still more than the maximum available, + # reduce by removing columns until we are less than the available + # width. + while ( + result > column_width + and result > max_available_width - self._required_margin + ): + result -= column_width + return result + self._required_margin + + def preferred_height( + self, + width: int, + max_available_height: int, + wrap_lines: bool, + get_line_prefix: Optional[GetLinePrefixCallable], + ) -> Optional[int]: + """ + Preferred height: as much as needed in order to display all the completions. + """ + complete_state = get_app().current_buffer.complete_state + if complete_state is None: + return 0 + + column_width = self._get_column_width(complete_state) + column_count = max(1, (width - self._required_margin) // column_width) + + return int(math.ceil(len(complete_state.completions) / float(column_count))) + + def create_content(self, width: int, height: int) -> UIContent: + """ + Create a UIContent object for this menu. + """ + complete_state = get_app().current_buffer.complete_state + if complete_state is None: + return UIContent() + + column_width = self._get_column_width(complete_state) + self._render_pos_to_completion = {} + + _T = TypeVar("_T") + + def grouper( + n: int, iterable: Iterable[_T], fillvalue: Optional[_T] = None + ) -> Iterable[List[_T]]: + " grouper(3, 'ABCDEFG', 'x') --> ABC DEF Gxx " + args = [iter(iterable)] * n + return zip_longest(fillvalue=fillvalue, *args) + + def is_current_completion(completion: Completion) -> bool: + " Returns True when this completion is the currently selected one. " + return ( + complete_state is not None + and complete_state.complete_index is not None + and c == complete_state.current_completion + ) + + # Space required outside of the regular columns, for displaying the + # left and right arrow. + HORIZONTAL_MARGIN_REQUIRED = 3 + + # There should be at least one column, but it cannot be wider than + # the available width. + column_width = min(width - HORIZONTAL_MARGIN_REQUIRED, column_width) + + # However, when the columns tend to be very wide, because there are + # some very wide entries, shrink it anyway. + if column_width > self.suggested_max_column_width: + # `column_width` can still be bigger that `suggested_max_column_width`, + # but if there is place for two columns, we divide by two. + column_width //= column_width // self.suggested_max_column_width + + visible_columns = max(1, (width - self._required_margin) // column_width) + + columns_ = list(grouper(height, complete_state.completions)) + rows_ = list(zip(*columns_)) + + # Make sure the current completion is always visible: update scroll offset. + selected_column = (complete_state.complete_index or 0) // height + self.scroll = min( + selected_column, max(self.scroll, selected_column - visible_columns + 1) + ) + + render_left_arrow = self.scroll > 0 + render_right_arrow = self.scroll < len(rows_[0]) - visible_columns + + # Write completions to screen. + fragments_for_line = [] + + for row_index, row in enumerate(rows_): + fragments: StyleAndTextTuples = [] + middle_row = row_index == len(rows_) // 2 + + # Draw left arrow if we have hidden completions on the left. + if render_left_arrow: + fragments.append(("class:scrollbar", "<" if middle_row else " ")) + elif render_right_arrow: + # Reserve one column empty space. (If there is a right + # arrow right now, there can be a left arrow as well.) + fragments.append(("", " ")) + + # Draw row content. + for column_index, c in enumerate(row[self.scroll :][:visible_columns]): + if c is not None: + fragments += _get_menu_item_fragments( + c, is_current_completion(c), column_width, space_after=False + ) + + # Remember render position for mouse click handler. + for x in range(column_width): + self._render_pos_to_completion[ + (column_index * column_width + x, row_index) + ] = c + else: + fragments.append(("class:completion", " " * column_width)) + + # Draw trailing padding for this row. + # (_get_menu_item_fragments only returns padding on the left.) + if render_left_arrow or render_right_arrow: + fragments.append(("class:completion", " ")) + + # Draw right arrow if we have hidden completions on the right. + if render_right_arrow: + fragments.append(("class:scrollbar", ">" if middle_row else " ")) + elif render_left_arrow: + fragments.append(("class:completion", " ")) + + # Add line. + fragments_for_line.append( + to_formatted_text(fragments, style="class:completion-menu") + ) + + self._rendered_rows = height + self._rendered_columns = visible_columns + self._total_columns = len(columns_) + self._render_left_arrow = render_left_arrow + self._render_right_arrow = render_right_arrow + self._render_width = ( + column_width * visible_columns + render_left_arrow + render_right_arrow + 1 + ) + + def get_line(i: int) -> StyleAndTextTuples: + return fragments_for_line[i] + + return UIContent(get_line=get_line, line_count=len(rows_)) + + def _get_column_width(self, complete_state: CompletionState) -> int: + """ + Return the width of each column. + """ + return max(get_cwidth(c.display_text) for c in complete_state.completions) + 1 + + def mouse_handler(self, mouse_event: MouseEvent) -> "NotImplementedOrNone": + """ + Handle scroll and click events. + """ + b = get_app().current_buffer + + def scroll_left() -> None: + b.complete_previous(count=self._rendered_rows, disable_wrap_around=True) + self.scroll = max(0, self.scroll - 1) + + def scroll_right() -> None: + b.complete_next(count=self._rendered_rows, disable_wrap_around=True) + self.scroll = min( + self._total_columns - self._rendered_columns, self.scroll + 1 + ) + + if mouse_event.event_type == MouseEventType.SCROLL_DOWN: + scroll_right() + + elif mouse_event.event_type == MouseEventType.SCROLL_UP: + scroll_left() + + elif mouse_event.event_type == MouseEventType.MOUSE_UP: + x = mouse_event.position.x + y = mouse_event.position.y + + # Mouse click on left arrow. + if x == 0: + if self._render_left_arrow: + scroll_left() + + # Mouse click on right arrow. + elif x == self._render_width - 1: + if self._render_right_arrow: + scroll_right() + + # Mouse click on completion. + else: + completion = self._render_pos_to_completion.get((x, y)) + if completion: + b.apply_completion(completion) + + return None + + def get_key_bindings(self) -> "KeyBindings": + """ + Expose key bindings that handle the left/right arrow keys when the menu + is displayed. + """ + from prompt_toolkit.key_binding.key_bindings import KeyBindings + + kb = KeyBindings() + + @Condition + def filter() -> bool: + " Only handle key bindings if this menu is visible. " + app = get_app() + complete_state = app.current_buffer.complete_state + + # There need to be completions, and one needs to be selected. + if complete_state is None or complete_state.complete_index is None: + return False + + # This menu needs to be visible. + return any(window.content == self for window in app.layout.visible_windows) + + def move(right: bool = False) -> None: + buff = get_app().current_buffer + complete_state = buff.complete_state + + if complete_state is not None and complete_state.complete_index is not None: + # Calculate new complete index. + new_index = complete_state.complete_index + if right: + new_index += self._rendered_rows + else: + new_index -= self._rendered_rows + + if 0 <= new_index < len(complete_state.completions): + buff.go_to_completion(new_index) + + # NOTE: the is_global is required because the completion menu will + # never be focussed. + + @kb.add("left", is_global=True, filter=filter) + def _left(event: E) -> None: + move() + + @kb.add("right", is_global=True, filter=filter) + def _right(event: E) -> None: + move(True) + + return kb + + +class MultiColumnCompletionsMenu(HSplit): + """ + Container that displays the completions in several columns. + When `show_meta` (a :class:`~prompt_toolkit.filters.Filter`) evaluates + to True, it shows the meta information at the bottom. + """ + + def __init__( + self, + min_rows: int = 3, + suggested_max_column_width: int = 30, + show_meta: FilterOrBool = True, + extra_filter: FilterOrBool = True, + z_index: int = 10 ** 8, + ) -> None: + + show_meta = to_filter(show_meta) + extra_filter = to_filter(extra_filter) + + # Display filter: show when there are completions but not at the point + # we are returning the input. + full_filter = has_completions & ~is_done & extra_filter + + @Condition + def any_completion_has_meta() -> bool: + complete_state = get_app().current_buffer.complete_state + return complete_state is not None and any( + c.display_meta for c in complete_state.completions + ) + + # Create child windows. + # NOTE: We don't set style='class:completion-menu' to the + # `MultiColumnCompletionMenuControl`, because this is used in a + # Float that is made transparent, and the size of the control + # doesn't always correspond exactly with the size of the + # generated content. + completions_window = ConditionalContainer( + content=Window( + content=MultiColumnCompletionMenuControl( + min_rows=min_rows, + suggested_max_column_width=suggested_max_column_width, + ), + width=Dimension(min=8), + height=Dimension(min=1), + ), + filter=full_filter, + ) + + meta_window = ConditionalContainer( + content=Window(content=_SelectedCompletionMetaControl()), + filter=show_meta & full_filter & any_completion_has_meta, + ) + + # Initialise split. + super().__init__([completions_window, meta_window], z_index=z_index) + + +class _SelectedCompletionMetaControl(UIControl): + """ + Control that shows the meta information of the selected completion. + """ + + def preferred_width(self, max_available_width: int) -> Optional[int]: + """ + Report the width of the longest meta text as the preferred width of this control. + + It could be that we use less width, but this way, we're sure that the + layout doesn't change when we select another completion (E.g. that + completions are suddenly shown in more or fewer columns.) + """ + app = get_app() + if app.current_buffer.complete_state: + state = app.current_buffer.complete_state + return 2 + max(get_cwidth(c.display_meta_text) for c in state.completions) + else: + return 0 + + def preferred_height( + self, + width: int, + max_available_height: int, + wrap_lines: bool, + get_line_prefix: Optional[GetLinePrefixCallable], + ) -> Optional[int]: + return 1 + + def create_content(self, width: int, height: int) -> UIContent: + fragments = self._get_text_fragments() + + def get_line(i: int) -> StyleAndTextTuples: + return fragments + + return UIContent(get_line=get_line, line_count=1 if fragments else 0) + + def _get_text_fragments(self) -> StyleAndTextTuples: + style = "class:completion-menu.multi-column-meta" + state = get_app().current_buffer.complete_state + + if ( + state + and state.current_completion + and state.current_completion.display_meta_text + ): + return to_formatted_text( + cast(StyleAndTextTuples, [("", " ")]) + + state.current_completion.display_meta + + [("", " ")], + style=style, + ) + + return [] diff --git a/.venv/lib/python3.8/site-packages/prompt_toolkit/layout/mouse_handlers.py b/.venv/lib/python3.8/site-packages/prompt_toolkit/layout/mouse_handlers.py new file mode 100644 index 00000000..754897dc --- /dev/null +++ b/.venv/lib/python3.8/site-packages/prompt_toolkit/layout/mouse_handlers.py @@ -0,0 +1,40 @@ +from collections import defaultdict +from itertools import product +from typing import Callable, DefaultDict, Tuple + +from prompt_toolkit.mouse_events import MouseEvent + +__all__ = [ + "MouseHandlers", +] + + +class MouseHandlers: + """ + Two dimensional raster of callbacks for mouse events. + """ + + def __init__(self) -> None: + def dummy_callback(mouse_event: MouseEvent) -> None: + """ + :param mouse_event: `MouseEvent` instance. + """ + + # Map (x,y) tuples to handlers. + self.mouse_handlers: DefaultDict[ + Tuple[int, int], Callable[[MouseEvent], None] + ] = defaultdict(lambda: dummy_callback) + + def set_mouse_handler_for_range( + self, + x_min: int, + x_max: int, + y_min: int, + y_max: int, + handler: Callable[[MouseEvent], None], + ) -> None: + """ + Set mouse handler for a region. + """ + for x, y in product(range(x_min, x_max), range(y_min, y_max)): + self.mouse_handlers[x, y] = handler diff --git a/.venv/lib/python3.8/site-packages/prompt_toolkit/layout/processors.py b/.venv/lib/python3.8/site-packages/prompt_toolkit/layout/processors.py new file mode 100644 index 00000000..a8f93b0e --- /dev/null +++ b/.venv/lib/python3.8/site-packages/prompt_toolkit/layout/processors.py @@ -0,0 +1,1029 @@ +""" +Processors are little transformation blocks that transform the fragments list +from a buffer before the BufferControl will render it to the screen. + +They can insert fragments before or after, or highlight fragments by replacing the +fragment types. +""" +import re +from abc import ABCMeta, abstractmethod +from typing import ( + TYPE_CHECKING, + Callable, + Hashable, + List, + Optional, + Tuple, + Type, + Union, + cast, +) + +from prompt_toolkit.application.current import get_app +from prompt_toolkit.cache import SimpleCache +from prompt_toolkit.document import Document +from prompt_toolkit.filters import FilterOrBool, to_filter, vi_insert_multiple_mode +from prompt_toolkit.formatted_text import ( + AnyFormattedText, + StyleAndTextTuples, + to_formatted_text, +) +from prompt_toolkit.formatted_text.utils import fragment_list_len, fragment_list_to_text +from prompt_toolkit.search import SearchDirection +from prompt_toolkit.utils import to_int, to_str + +from .utils import explode_text_fragments + +if TYPE_CHECKING: + from .controls import BufferControl, UIContent + +__all__ = [ + "Processor", + "TransformationInput", + "Transformation", + "DummyProcessor", + "HighlightSearchProcessor", + "HighlightIncrementalSearchProcessor", + "HighlightSelectionProcessor", + "PasswordProcessor", + "HighlightMatchingBracketProcessor", + "DisplayMultipleCursors", + "BeforeInput", + "ShowArg", + "AfterInput", + "AppendAutoSuggestion", + "ConditionalProcessor", + "ShowLeadingWhiteSpaceProcessor", + "ShowTrailingWhiteSpaceProcessor", + "TabsProcessor", + "ReverseSearchProcessor", + "DynamicProcessor", + "merge_processors", +] + + +class Processor(metaclass=ABCMeta): + """ + Manipulate the fragments for a given line in a + :class:`~prompt_toolkit.layout.controls.BufferControl`. + """ + + @abstractmethod + def apply_transformation( + self, transformation_input: "TransformationInput" + ) -> "Transformation": + """ + Apply transformation. Returns a :class:`.Transformation` instance. + + :param transformation_input: :class:`.TransformationInput` object. + """ + return Transformation(transformation_input.fragments) + + +SourceToDisplay = Callable[[int], int] +DisplayToSource = Callable[[int], int] + + +class TransformationInput: + """ + :param control: :class:`.BufferControl` instance. + :param lineno: The number of the line to which we apply the processor. + :param source_to_display: A function that returns the position in the + `fragments` for any position in the source string. (This takes + previous processors into account.) + :param fragments: List of fragments that we can transform. (Received from the + previous processor.) + """ + + def __init__( + self, + buffer_control: "BufferControl", + document: Document, + lineno: int, + source_to_display: SourceToDisplay, + fragments: StyleAndTextTuples, + width: int, + height: int, + ) -> None: + + self.buffer_control = buffer_control + self.document = document + self.lineno = lineno + self.source_to_display = source_to_display + self.fragments = fragments + self.width = width + self.height = height + + def unpack( + self, + ) -> Tuple[ + "BufferControl", Document, int, SourceToDisplay, StyleAndTextTuples, int, int + ]: + return ( + self.buffer_control, + self.document, + self.lineno, + self.source_to_display, + self.fragments, + self.width, + self.height, + ) + + +class Transformation: + """ + Transformation result, as returned by :meth:`.Processor.apply_transformation`. + + Important: Always make sure that the length of `document.text` is equal to + the length of all the text in `fragments`! + + :param fragments: The transformed fragments. To be displayed, or to pass to + the next processor. + :param source_to_display: Cursor position transformation from original + string to transformed string. + :param display_to_source: Cursor position transformed from source string to + original string. + """ + + def __init__( + self, + fragments: StyleAndTextTuples, + source_to_display: Optional[SourceToDisplay] = None, + display_to_source: Optional[DisplayToSource] = None, + ) -> None: + + self.fragments = fragments + self.source_to_display = source_to_display or (lambda i: i) + self.display_to_source = display_to_source or (lambda i: i) + + +class DummyProcessor(Processor): + """ + A `Processor` that doesn't do anything. + """ + + def apply_transformation( + self, transformation_input: TransformationInput + ) -> Transformation: + return Transformation(transformation_input.fragments) + + +class HighlightSearchProcessor(Processor): + """ + Processor that highlights search matches in the document. + Note that this doesn't support multiline search matches yet. + + The style classes 'search' and 'search.current' will be applied to the + content. + """ + + _classname = "search" + _classname_current = "search.current" + + def _get_search_text(self, buffer_control: "BufferControl") -> str: + """ + The text we are searching for. + """ + return buffer_control.search_state.text + + def apply_transformation( + self, transformation_input: TransformationInput + ) -> Transformation: + + ( + buffer_control, + document, + lineno, + source_to_display, + fragments, + _, + _, + ) = transformation_input.unpack() + + search_text = self._get_search_text(buffer_control) + searchmatch_fragment = " class:%s " % (self._classname,) + searchmatch_current_fragment = " class:%s " % (self._classname_current,) + + if search_text and not get_app().is_done: + # For each search match, replace the style string. + line_text = fragment_list_to_text(fragments) + fragments = explode_text_fragments(fragments) + + if buffer_control.search_state.ignore_case(): + flags = re.IGNORECASE + else: + flags = re.RegexFlag(0) + + # Get cursor column. + cursor_column: Optional[int] + if document.cursor_position_row == lineno: + cursor_column = source_to_display(document.cursor_position_col) + else: + cursor_column = None + + for match in re.finditer(re.escape(search_text), line_text, flags=flags): + if cursor_column is not None: + on_cursor = match.start() <= cursor_column < match.end() + else: + on_cursor = False + + for i in range(match.start(), match.end()): + old_fragment, text, *_ = fragments[i] + if on_cursor: + fragments[i] = ( + old_fragment + searchmatch_current_fragment, + fragments[i][1], + ) + else: + fragments[i] = ( + old_fragment + searchmatch_fragment, + fragments[i][1], + ) + + return Transformation(fragments) + + +class HighlightIncrementalSearchProcessor(HighlightSearchProcessor): + """ + Highlight the search terms that are used for highlighting the incremental + search. The style class 'incsearch' will be applied to the content. + + Important: this requires the `preview_search=True` flag to be set for the + `BufferControl`. Otherwise, the cursor position won't be set to the search + match while searching, and nothing happens. + """ + + _classname = "incsearch" + _classname_current = "incsearch.current" + + def _get_search_text(self, buffer_control: "BufferControl") -> str: + """ + The text we are searching for. + """ + # When the search buffer has focus, take that text. + search_buffer = buffer_control.search_buffer + if search_buffer is not None and search_buffer.text: + return search_buffer.text + return "" + + +class HighlightSelectionProcessor(Processor): + """ + Processor that highlights the selection in the document. + """ + + def apply_transformation( + self, transformation_input: TransformationInput + ) -> Transformation: + ( + buffer_control, + document, + lineno, + source_to_display, + fragments, + _, + _, + ) = transformation_input.unpack() + + selected_fragment = " class:selected " + + # In case of selection, highlight all matches. + selection_at_line = document.selection_range_at_line(lineno) + + if selection_at_line: + from_, to = selection_at_line + from_ = source_to_display(from_) + to = source_to_display(to) + + fragments = explode_text_fragments(fragments) + + if from_ == 0 and to == 0 and len(fragments) == 0: + # When this is an empty line, insert a space in order to + # visualise the selection. + return Transformation([(selected_fragment, " ")]) + else: + for i in range(from_, to): + if i < len(fragments): + old_fragment, old_text, *_ = fragments[i] + fragments[i] = (old_fragment + selected_fragment, old_text) + elif i == len(fragments): + fragments.append((selected_fragment, " ")) + + return Transformation(fragments) + + +class PasswordProcessor(Processor): + """ + Processor that turns masks the input. (For passwords.) + + :param char: (string) Character to be used. "*" by default. + """ + + def __init__(self, char: str = "*") -> None: + self.char = char + + def apply_transformation(self, ti: TransformationInput) -> Transformation: + fragments: StyleAndTextTuples = cast( + StyleAndTextTuples, + [ + (style, self.char * len(text), *handler) + for style, text, *handler in ti.fragments + ], + ) + + return Transformation(fragments) + + +class HighlightMatchingBracketProcessor(Processor): + """ + When the cursor is on or right after a bracket, it highlights the matching + bracket. + + :param max_cursor_distance: Only highlight matching brackets when the + cursor is within this distance. (From inside a `Processor`, we can't + know which lines will be visible on the screen. But we also don't want + to scan the whole document for matching brackets on each key press, so + we limit to this value.) + """ + + _closing_braces = "])}>" + + def __init__( + self, chars: str = "[](){}<>", max_cursor_distance: int = 1000 + ) -> None: + self.chars = chars + self.max_cursor_distance = max_cursor_distance + + self._positions_cache: SimpleCache[ + Hashable, List[Tuple[int, int]] + ] = SimpleCache(maxsize=8) + + def _get_positions_to_highlight(self, document: Document) -> List[Tuple[int, int]]: + """ + Return a list of (row, col) tuples that need to be highlighted. + """ + pos: Optional[int] + + # Try for the character under the cursor. + if document.current_char and document.current_char in self.chars: + pos = document.find_matching_bracket_position( + start_pos=document.cursor_position - self.max_cursor_distance, + end_pos=document.cursor_position + self.max_cursor_distance, + ) + + # Try for the character before the cursor. + elif ( + document.char_before_cursor + and document.char_before_cursor in self._closing_braces + and document.char_before_cursor in self.chars + ): + document = Document(document.text, document.cursor_position - 1) + + pos = document.find_matching_bracket_position( + start_pos=document.cursor_position - self.max_cursor_distance, + end_pos=document.cursor_position + self.max_cursor_distance, + ) + else: + pos = None + + # Return a list of (row, col) tuples that need to be highlighted. + if pos: + pos += document.cursor_position # pos is relative. + row, col = document.translate_index_to_position(pos) + return [ + (row, col), + (document.cursor_position_row, document.cursor_position_col), + ] + else: + return [] + + def apply_transformation( + self, transformation_input: TransformationInput + ) -> Transformation: + + ( + buffer_control, + document, + lineno, + source_to_display, + fragments, + _, + _, + ) = transformation_input.unpack() + + # When the application is in the 'done' state, don't highlight. + if get_app().is_done: + return Transformation(fragments) + + # Get the highlight positions. + key = (get_app().render_counter, document.text, document.cursor_position) + positions = self._positions_cache.get( + key, lambda: self._get_positions_to_highlight(document) + ) + + # Apply if positions were found at this line. + if positions: + for row, col in positions: + if row == lineno: + col = source_to_display(col) + fragments = explode_text_fragments(fragments) + style, text, *_ = fragments[col] + + if col == document.cursor_position_col: + style += " class:matching-bracket.cursor " + else: + style += " class:matching-bracket.other " + + fragments[col] = (style, text) + + return Transformation(fragments) + + +class DisplayMultipleCursors(Processor): + """ + When we're in Vi block insert mode, display all the cursors. + """ + + def apply_transformation( + self, transformation_input: TransformationInput + ) -> Transformation: + + ( + buffer_control, + document, + lineno, + source_to_display, + fragments, + _, + _, + ) = transformation_input.unpack() + + buff = buffer_control.buffer + + if vi_insert_multiple_mode(): + cursor_positions = buff.multiple_cursor_positions + fragments = explode_text_fragments(fragments) + + # If any cursor appears on the current line, highlight that. + start_pos = document.translate_row_col_to_index(lineno, 0) + end_pos = start_pos + len(document.lines[lineno]) + + fragment_suffix = " class:multiple-cursors" + + for p in cursor_positions: + if start_pos <= p <= end_pos: + column = source_to_display(p - start_pos) + + # Replace fragment. + try: + style, text, *_ = fragments[column] + except IndexError: + # Cursor needs to be displayed after the current text. + fragments.append((fragment_suffix, " ")) + else: + style += fragment_suffix + fragments[column] = (style, text) + + return Transformation(fragments) + else: + return Transformation(fragments) + + +class BeforeInput(Processor): + """ + Insert text before the input. + + :param text: This can be either plain text or formatted text + (or a callable that returns any of those). + :param style: style to be applied to this prompt/prefix. + """ + + def __init__(self, text: AnyFormattedText, style: str = "") -> None: + self.text = text + self.style = style + + def apply_transformation(self, ti: TransformationInput) -> Transformation: + source_to_display: Optional[SourceToDisplay] + display_to_source: Optional[DisplayToSource] + + if ti.lineno == 0: + # Get fragments. + fragments_before = to_formatted_text(self.text, self.style) + fragments = fragments_before + ti.fragments + + shift_position = fragment_list_len(fragments_before) + source_to_display = lambda i: i + shift_position + display_to_source = lambda i: i - shift_position + else: + fragments = ti.fragments + source_to_display = None + display_to_source = None + + return Transformation( + fragments, + source_to_display=source_to_display, + display_to_source=display_to_source, + ) + + def __repr__(self) -> str: + return "BeforeInput(%r, %r)" % (self.text, self.style) + + +class ShowArg(BeforeInput): + """ + Display the 'arg' in front of the input. + + This was used by the `PromptSession`, but now it uses the + `Window.get_line_prefix` function instead. + """ + + def __init__(self) -> None: + super().__init__(self._get_text_fragments) + + def _get_text_fragments(self) -> StyleAndTextTuples: + app = get_app() + if app.key_processor.arg is None: + return [] + else: + arg = app.key_processor.arg + + return [ + ("class:prompt.arg", "(arg: "), + ("class:prompt.arg.text", str(arg)), + ("class:prompt.arg", ") "), + ] + + def __repr__(self) -> str: + return "ShowArg()" + + +class AfterInput(Processor): + """ + Insert text after the input. + + :param text: This can be either plain text or formatted text + (or a callable that returns any of those). + :param style: style to be applied to this prompt/prefix. + """ + + def __init__(self, text: AnyFormattedText, style: str = "") -> None: + self.text = text + self.style = style + + def apply_transformation(self, ti: TransformationInput) -> Transformation: + # Insert fragments after the last line. + if ti.lineno == ti.document.line_count - 1: + # Get fragments. + fragments_after = to_formatted_text(self.text, self.style) + return Transformation(fragments=ti.fragments + fragments_after) + else: + return Transformation(fragments=ti.fragments) + + def __repr__(self) -> str: + return "%s(%r, style=%r)" % (self.__class__.__name__, self.text, self.style) + + +class AppendAutoSuggestion(Processor): + """ + Append the auto suggestion to the input. + (The user can then press the right arrow the insert the suggestion.) + """ + + def __init__(self, style: str = "class:auto-suggestion") -> None: + self.style = style + + def apply_transformation(self, ti: TransformationInput) -> Transformation: + # Insert fragments after the last line. + if ti.lineno == ti.document.line_count - 1: + buffer = ti.buffer_control.buffer + + if buffer.suggestion and ti.document.is_cursor_at_the_end: + suggestion = buffer.suggestion.text + else: + suggestion = "" + + return Transformation(fragments=ti.fragments + [(self.style, suggestion)]) + else: + return Transformation(fragments=ti.fragments) + + +class ShowLeadingWhiteSpaceProcessor(Processor): + """ + Make leading whitespace visible. + + :param get_char: Callable that returns one character. + """ + + def __init__( + self, + get_char: Optional[Callable[[], str]] = None, + style: str = "class:leading-whitespace", + ) -> None: + def default_get_char() -> str: + if "\xb7".encode(get_app().output.encoding(), "replace") == b"?": + return "." + else: + return "\xb7" + + self.style = style + self.get_char = get_char or default_get_char + + def apply_transformation(self, ti: TransformationInput) -> Transformation: + fragments = ti.fragments + + # Walk through all te fragments. + if fragments and fragment_list_to_text(fragments).startswith(" "): + t = (self.style, self.get_char()) + fragments = explode_text_fragments(fragments) + + for i in range(len(fragments)): + if fragments[i][1] == " ": + fragments[i] = t + else: + break + + return Transformation(fragments) + + +class ShowTrailingWhiteSpaceProcessor(Processor): + """ + Make trailing whitespace visible. + + :param get_char: Callable that returns one character. + """ + + def __init__( + self, + get_char: Optional[Callable[[], str]] = None, + style: str = "class:training-whitespace", + ) -> None: + def default_get_char() -> str: + if "\xb7".encode(get_app().output.encoding(), "replace") == b"?": + return "." + else: + return "\xb7" + + self.style = style + self.get_char = get_char or default_get_char + + def apply_transformation(self, ti: TransformationInput) -> Transformation: + fragments = ti.fragments + + if fragments and fragments[-1][1].endswith(" "): + t = (self.style, self.get_char()) + fragments = explode_text_fragments(fragments) + + # Walk backwards through all te fragments and replace whitespace. + for i in range(len(fragments) - 1, -1, -1): + char = fragments[i][1] + if char == " ": + fragments[i] = t + else: + break + + return Transformation(fragments) + + +class TabsProcessor(Processor): + """ + Render tabs as spaces (instead of ^I) or make them visible (for instance, + by replacing them with dots.) + + :param tabstop: Horizontal space taken by a tab. (`int` or callable that + returns an `int`). + :param char1: Character or callable that returns a character (text of + length one). This one is used for the first space taken by the tab. + :param char2: Like `char1`, but for the rest of the space. + """ + + def __init__( + self, + tabstop: Union[int, Callable[[], int]] = 4, + char1: Union[str, Callable[[], str]] = "|", + char2: Union[str, Callable[[], str]] = "\u2508", + style: str = "class:tab", + ) -> None: + + self.char1 = char1 + self.char2 = char2 + self.tabstop = tabstop + self.style = style + + def apply_transformation(self, ti: TransformationInput) -> Transformation: + tabstop = to_int(self.tabstop) + style = self.style + + # Create separator for tabs. + separator1 = to_str(self.char1) + separator2 = to_str(self.char2) + + # Transform fragments. + fragments = explode_text_fragments(ti.fragments) + + position_mappings = {} + result_fragments: StyleAndTextTuples = [] + pos = 0 + + for i, fragment_and_text in enumerate(fragments): + position_mappings[i] = pos + + if fragment_and_text[1] == "\t": + # Calculate how many characters we have to insert. + count = tabstop - (pos % tabstop) + if count == 0: + count = tabstop + + # Insert tab. + result_fragments.append((style, separator1)) + result_fragments.append((style, separator2 * (count - 1))) + pos += count + else: + result_fragments.append(fragment_and_text) + pos += 1 + + position_mappings[len(fragments)] = pos + # Add `pos+1` to mapping, because the cursor can be right after the + # line as well. + position_mappings[len(fragments) + 1] = pos + 1 + + def source_to_display(from_position: int) -> int: + " Maps original cursor position to the new one. " + return position_mappings[from_position] + + def display_to_source(display_pos: int) -> int: + " Maps display cursor position to the original one. " + position_mappings_reversed = {v: k for k, v in position_mappings.items()} + + while display_pos >= 0: + try: + return position_mappings_reversed[display_pos] + except KeyError: + display_pos -= 1 + return 0 + + return Transformation( + result_fragments, + source_to_display=source_to_display, + display_to_source=display_to_source, + ) + + +class ReverseSearchProcessor(Processor): + """ + Process to display the "(reverse-i-search)`...`:..." stuff around + the search buffer. + + Note: This processor is meant to be applied to the BufferControl that + contains the search buffer, it's not meant for the original input. + """ + + _excluded_input_processors: List[Type[Processor]] = [ + HighlightSearchProcessor, + HighlightSelectionProcessor, + BeforeInput, + AfterInput, + ] + + def _get_main_buffer( + self, buffer_control: "BufferControl" + ) -> Optional["BufferControl"]: + from prompt_toolkit.layout.controls import BufferControl + + prev_control = get_app().layout.search_target_buffer_control + if ( + isinstance(prev_control, BufferControl) + and prev_control.search_buffer_control == buffer_control + ): + return prev_control + return None + + def _content( + self, main_control: "BufferControl", ti: TransformationInput + ) -> "UIContent": + from prompt_toolkit.layout.controls import BufferControl + + # Emulate the BufferControl through which we are searching. + # For this we filter out some of the input processors. + excluded_processors = tuple(self._excluded_input_processors) + + def filter_processor(item: Processor) -> Optional[Processor]: + """Filter processors from the main control that we want to disable + here. This returns either an accepted processor or None.""" + # For a `_MergedProcessor`, check each individual processor, recursively. + if isinstance(item, _MergedProcessor): + accepted_processors = [filter_processor(p) for p in item.processors] + return merge_processors( + [p for p in accepted_processors if p is not None] + ) + + # For a `ConditionalProcessor`, check the body. + elif isinstance(item, ConditionalProcessor): + p = filter_processor(item.processor) + if p: + return ConditionalProcessor(p, item.filter) + + # Otherwise, check the processor itself. + else: + if not isinstance(item, excluded_processors): + return item + + return None + + filtered_processor = filter_processor( + merge_processors(main_control.input_processors or []) + ) + highlight_processor = HighlightIncrementalSearchProcessor() + + if filtered_processor: + new_processors = [filtered_processor, highlight_processor] + else: + new_processors = [highlight_processor] + + from .controls import SearchBufferControl + + assert isinstance(ti.buffer_control, SearchBufferControl) + + buffer_control = BufferControl( + buffer=main_control.buffer, + input_processors=new_processors, + include_default_input_processors=False, + lexer=main_control.lexer, + preview_search=True, + search_buffer_control=cast(SearchBufferControl, ti.buffer_control), + ) + + return buffer_control.create_content(ti.width, ti.height, preview_search=True) + + def apply_transformation(self, ti: TransformationInput) -> Transformation: + from .controls import SearchBufferControl + + assert isinstance( + ti.buffer_control, SearchBufferControl + ), "`ReverseSearchProcessor` should be applied to a `SearchBufferControl` only." + + source_to_display: Optional[SourceToDisplay] + display_to_source: Optional[DisplayToSource] + + main_control = self._get_main_buffer(ti.buffer_control) + + if ti.lineno == 0 and main_control: + content = self._content(main_control, ti) + + # Get the line from the original document for this search. + line_fragments = content.get_line(content.cursor_position.y) + + if main_control.search_state.direction == SearchDirection.FORWARD: + direction_text = "i-search" + else: + direction_text = "reverse-i-search" + + fragments_before: StyleAndTextTuples = [ + ("class:prompt.search", "("), + ("class:prompt.search", direction_text), + ("class:prompt.search", ")`"), + ] + + fragments = ( + fragments_before + + [ + ("class:prompt.search.text", fragment_list_to_text(ti.fragments)), + ("", "': "), + ] + + line_fragments + ) + + shift_position = fragment_list_len(fragments_before) + source_to_display = lambda i: i + shift_position + display_to_source = lambda i: i - shift_position + else: + source_to_display = None + display_to_source = None + fragments = ti.fragments + + return Transformation( + fragments, + source_to_display=source_to_display, + display_to_source=display_to_source, + ) + + +class ConditionalProcessor(Processor): + """ + Processor that applies another processor, according to a certain condition. + Example:: + + # Create a function that returns whether or not the processor should + # currently be applied. + def highlight_enabled(): + return true_or_false + + # Wrapped it in a `ConditionalProcessor` for usage in a `BufferControl`. + BufferControl(input_processors=[ + ConditionalProcessor(HighlightSearchProcessor(), + Condition(highlight_enabled))]) + + :param processor: :class:`.Processor` instance. + :param filter: :class:`~prompt_toolkit.filters.Filter` instance. + """ + + def __init__(self, processor: Processor, filter: FilterOrBool) -> None: + self.processor = processor + self.filter = to_filter(filter) + + def apply_transformation( + self, transformation_input: TransformationInput + ) -> Transformation: + # Run processor when enabled. + if self.filter(): + return self.processor.apply_transformation(transformation_input) + else: + return Transformation(transformation_input.fragments) + + def __repr__(self) -> str: + return "%s(processor=%r, filter=%r)" % ( + self.__class__.__name__, + self.processor, + self.filter, + ) + + +class DynamicProcessor(Processor): + """ + Processor class that can dynamically returns any Processor. + + :param get_processor: Callable that returns a :class:`.Processor` instance. + """ + + def __init__(self, get_processor: Callable[[], Optional[Processor]]) -> None: + self.get_processor = get_processor + + def apply_transformation(self, ti: TransformationInput) -> Transformation: + processor = self.get_processor() or DummyProcessor() + return processor.apply_transformation(ti) + + +def merge_processors(processors: List[Processor]) -> Processor: + """ + Merge multiple `Processor` objects into one. + """ + if len(processors) == 0: + return DummyProcessor() + + if len(processors) == 1: + return processors[0] # Nothing to merge. + + return _MergedProcessor(processors) + + +class _MergedProcessor(Processor): + """ + Processor that groups multiple other `Processor` objects, but exposes an + API as if it is one `Processor`. + """ + + def __init__(self, processors: List[Processor]): + self.processors = processors + + def apply_transformation(self, ti: TransformationInput) -> Transformation: + source_to_display_functions = [ti.source_to_display] + display_to_source_functions = [] + fragments = ti.fragments + + def source_to_display(i: int) -> int: + """Translate x position from the buffer to the x position in the + processor fragments list.""" + for f in source_to_display_functions: + i = f(i) + return i + + for p in self.processors: + transformation = p.apply_transformation( + TransformationInput( + ti.buffer_control, + ti.document, + ti.lineno, + source_to_display, + fragments, + ti.width, + ti.height, + ) + ) + fragments = transformation.fragments + display_to_source_functions.append(transformation.display_to_source) + source_to_display_functions.append(transformation.source_to_display) + + def display_to_source(i: int) -> int: + for f in reversed(display_to_source_functions): + i = f(i) + return i + + # In the case of a nested _MergedProcessor, each processor wants to + # receive a 'source_to_display' function (as part of the + # TransformationInput) that has everything in the chain before + # included, because it can be called as part of the + # `apply_transformation` function. However, this first + # `source_to_display` should not be part of the output that we are + # returning. (This is the most consistent with `display_to_source`.) + del source_to_display_functions[:1] + + return Transformation(fragments, source_to_display, display_to_source) diff --git a/.venv/lib/python3.8/site-packages/prompt_toolkit/layout/screen.py b/.venv/lib/python3.8/site-packages/prompt_toolkit/layout/screen.py new file mode 100644 index 00000000..ca311955 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/prompt_toolkit/layout/screen.py @@ -0,0 +1,316 @@ +from collections import defaultdict +from typing import TYPE_CHECKING, Callable, DefaultDict, Dict, List, Optional, Tuple + +from prompt_toolkit.cache import FastDictCache +from prompt_toolkit.data_structures import Point +from prompt_toolkit.utils import get_cwidth + +if TYPE_CHECKING: + from .containers import Window + + +__all__ = [ + "Screen", + "Char", +] + + +class Char: + """ + Represent a single character in a :class:`.Screen`. + + This should be considered immutable. + + :param char: A single character (can be a double-width character). + :param style: A style string. (Can contain classnames.) + """ + + __slots__ = ("char", "style", "width") + + # If we end up having one of these special control sequences in the input string, + # we should display them as follows: + # Usually this happens after a "quoted insert". + display_mappings: Dict[str, str] = { + "\x00": "^@", # Control space + "\x01": "^A", + "\x02": "^B", + "\x03": "^C", + "\x04": "^D", + "\x05": "^E", + "\x06": "^F", + "\x07": "^G", + "\x08": "^H", + "\x09": "^I", + "\x0a": "^J", + "\x0b": "^K", + "\x0c": "^L", + "\x0d": "^M", + "\x0e": "^N", + "\x0f": "^O", + "\x10": "^P", + "\x11": "^Q", + "\x12": "^R", + "\x13": "^S", + "\x14": "^T", + "\x15": "^U", + "\x16": "^V", + "\x17": "^W", + "\x18": "^X", + "\x19": "^Y", + "\x1a": "^Z", + "\x1b": "^[", # Escape + "\x1c": "^\\", + "\x1d": "^]", + "\x1f": "^_", + "\x7f": "^?", # ASCII Delete (backspace). + # Special characters. All visualized like Vim does. + "\x80": "<80>", + "\x81": "<81>", + "\x82": "<82>", + "\x83": "<83>", + "\x84": "<84>", + "\x85": "<85>", + "\x86": "<86>", + "\x87": "<87>", + "\x88": "<88>", + "\x89": "<89>", + "\x8a": "<8a>", + "\x8b": "<8b>", + "\x8c": "<8c>", + "\x8d": "<8d>", + "\x8e": "<8e>", + "\x8f": "<8f>", + "\x90": "<90>", + "\x91": "<91>", + "\x92": "<92>", + "\x93": "<93>", + "\x94": "<94>", + "\x95": "<95>", + "\x96": "<96>", + "\x97": "<97>", + "\x98": "<98>", + "\x99": "<99>", + "\x9a": "<9a>", + "\x9b": "<9b>", + "\x9c": "<9c>", + "\x9d": "<9d>", + "\x9e": "<9e>", + "\x9f": "<9f>", + # For the non-breaking space: visualize like Emacs does by default. + # (Print a space, but attach the 'nbsp' class that applies the + # underline style.) + "\xa0": " ", + } + + def __init__(self, char: str = " ", style: str = ""): + # If this character has to be displayed otherwise, take that one. + if char in self.display_mappings: + if char == "\xa0": + style += " class:nbsp " # Will be underlined. + else: + style += " class:control-character " + + char = self.display_mappings[char] + + self.char = char + self.style = style + + # Calculate width. (We always need this, so better to store it directly + # as a member for performance.) + self.width = get_cwidth(char) + + def __eq__(self, other) -> bool: + return self.char == other.char and self.style == other.style + + def __ne__(self, other) -> bool: + # Not equal: We don't do `not char.__eq__` here, because of the + # performance of calling yet another function. + return self.char != other.char or self.style != other.style + + def __repr__(self) -> str: + return "%s(%r, %r)" % (self.__class__.__name__, self.char, self.style) + + +_CHAR_CACHE: FastDictCache[Tuple[str, str], Char] = FastDictCache( + Char, size=1000 * 1000 +) +Transparent = "[transparent]" + + +class Screen: + """ + Two dimensional buffer of :class:`.Char` instances. + """ + + def __init__( + self, + default_char: Optional[Char] = None, + initial_width: int = 0, + initial_height: int = 0, + ) -> None: + + if default_char is None: + default_char2 = _CHAR_CACHE[" ", Transparent] + else: + default_char2 = default_char + + self.data_buffer: DefaultDict[int, DefaultDict[int, Char]] = defaultdict( + lambda: defaultdict(lambda: default_char2) + ) + + #: Escape sequences to be injected. + self.zero_width_escapes: DefaultDict[int, DefaultDict[int, str]] = defaultdict( + lambda: defaultdict(lambda: "") + ) + + #: Position of the cursor. + self.cursor_positions: Dict[ + "Window", Point + ] = {} # Map `Window` objects to `Point` objects. + + #: Visibility of the cursor. + self.show_cursor = True + + #: (Optional) Where to position the menu. E.g. at the start of a completion. + #: (We can't use the cursor position, because we don't want the + #: completion menu to change its position when we browse through all the + #: completions.) + self.menu_positions: Dict[ + "Window", Point + ] = {} # Map `Window` objects to `Point` objects. + + #: Currently used width/height of the screen. This will increase when + #: data is written to the screen. + self.width = initial_width or 0 + self.height = initial_height or 0 + + # Windows that have been drawn. (Each `Window` class will add itself to + # this list.) + self.visible_windows: List["Window"] = [] + + # List of (z_index, draw_func) + self._draw_float_functions: List[Tuple[int, Callable[[], None]]] = [] + + def set_cursor_position(self, window: "Window", position: Point) -> None: + """ + Set the cursor position for a given window. + """ + self.cursor_positions[window] = position + + def set_menu_position(self, window: "Window", position: Point) -> None: + """ + Set the cursor position for a given window. + """ + self.menu_positions[window] = position + + def get_cursor_position(self, window: "Window") -> Point: + """ + Get the cursor position for a given window. + Returns a `Point`. + """ + try: + return self.cursor_positions[window] + except KeyError: + return Point(x=0, y=0) + + def get_menu_position(self, window: "Window") -> Point: + """ + Get the menu position for a given window. + (This falls back to the cursor position if no menu position was set.) + """ + try: + return self.menu_positions[window] + except KeyError: + try: + return self.cursor_positions[window] + except KeyError: + return Point(x=0, y=0) + + def draw_with_z_index(self, z_index: int, draw_func: Callable[[], None]) -> None: + """ + Add a draw-function for a `Window` which has a >= 0 z_index. + This will be postponed until `draw_all_floats` is called. + """ + self._draw_float_functions.append((z_index, draw_func)) + + def draw_all_floats(self) -> None: + """ + Draw all float functions in order of z-index. + """ + # We keep looping because some draw functions could add new functions + # to this list. See `FloatContainer`. + while self._draw_float_functions: + # Sort the floats that we have so far by z_index. + functions = sorted(self._draw_float_functions, key=lambda item: item[0]) + + # Draw only one at a time, then sort everything again. Now floats + # might have been added. + self._draw_float_functions = functions[1:] + functions[0][1]() + + def append_style_to_content(self, style_str: str) -> None: + """ + For all the characters in the screen. + Set the style string to the given `style_str`. + """ + b = self.data_buffer + char_cache = _CHAR_CACHE + + append_style = " " + style_str + + for y, row in b.items(): + for x, char in row.items(): + b[y][x] = char_cache[char.char, char.style + append_style] + + def fill_area( + self, write_position: "WritePosition", style: str = "", after: bool = False + ) -> None: + """ + Fill the content of this area, using the given `style`. + The style is prepended before whatever was here before. + """ + if not style.strip(): + return + + xmin = write_position.xpos + xmax = write_position.xpos + write_position.width + char_cache = _CHAR_CACHE + data_buffer = self.data_buffer + + if after: + append_style = " " + style + prepend_style = "" + else: + append_style = "" + prepend_style = style + " " + + for y in range( + write_position.ypos, write_position.ypos + write_position.height + ): + row = data_buffer[y] + for x in range(xmin, xmax): + cell = row[x] + row[x] = char_cache[ + cell.char, prepend_style + cell.style + append_style + ] + + +class WritePosition: + def __init__(self, xpos: int, ypos: int, width: int, height: int) -> None: + assert height >= 0 + assert width >= 0 + # xpos and ypos can be negative. (A float can be partially visible.) + + self.xpos = xpos + self.ypos = ypos + self.width = width + self.height = height + + def __repr__(self) -> str: + return "%s(x=%r, y=%r, width=%r, height=%r)" % ( + self.__class__.__name__, + self.xpos, + self.ypos, + self.width, + self.height, + ) diff --git a/.venv/lib/python3.8/site-packages/prompt_toolkit/layout/utils.py b/.venv/lib/python3.8/site-packages/prompt_toolkit/layout/utils.py new file mode 100644 index 00000000..35673ccb --- /dev/null +++ b/.venv/lib/python3.8/site-packages/prompt_toolkit/layout/utils.py @@ -0,0 +1,76 @@ +from typing import Iterable, List, TypeVar, Union, cast, overload + +from prompt_toolkit.formatted_text.base import OneStyleAndTextTuple + +__all__ = [ + "explode_text_fragments", +] + +_T = TypeVar("_T", bound=OneStyleAndTextTuple) + + +class _ExplodedList(List[_T]): + """ + Wrapper around a list, that marks it as 'exploded'. + + As soon as items are added or the list is extended, the new items are + automatically exploded as well. + """ + + exploded = True + + def append(self, item: _T) -> None: + self.extend([item]) + + def extend(self, lst: Iterable[_T]) -> None: + super().extend(explode_text_fragments(lst)) + + def insert(self, index: int, item: _T) -> None: + raise NotImplementedError # TODO + + # TODO: When creating a copy() or [:], return also an _ExplodedList. + + @overload + def __setitem__(self, index: int, value: _T) -> None: + ... + + @overload + def __setitem__(self, index: slice, value: Iterable[_T]) -> None: + ... + + def __setitem__( + self, index: Union[int, slice], value: Union[_T, Iterable[_T]] + ) -> None: + """ + Ensure that when `(style_str, 'long string')` is set, the string will be + exploded. + """ + if not isinstance(index, slice): + index = slice(index, index + 1) + if isinstance(value, tuple): # In case of `OneStyleAndTextTuple`. + value = cast("List[_T]", [value]) + + super().__setitem__(index, explode_text_fragments(cast("Iterable[_T]", value))) + + +def explode_text_fragments(fragments: Iterable[_T]) -> _ExplodedList[_T]: + """ + Turn a list of (style_str, text) tuples into another list where each string is + exactly one character. + + It should be fine to call this function several times. Calling this on a + list that is already exploded, is a null operation. + + :param fragments: List of (style, text) tuples. + """ + # When the fragments is already exploded, don't explode again. + if isinstance(fragments, _ExplodedList): + return fragments + + result: List[_T] = [] + + for style, string, *rest in fragments: # type: ignore + for c in string: # type: ignore + result.append((style, c, *rest)) # type: ignore + + return _ExplodedList(result) diff --git a/.venv/lib/python3.8/site-packages/prompt_toolkit/lexers/__init__.py b/.venv/lib/python3.8/site-packages/prompt_toolkit/lexers/__init__.py new file mode 100644 index 00000000..3e875e65 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/prompt_toolkit/lexers/__init__.py @@ -0,0 +1,18 @@ +""" +Lexer interface and implementations. +Used for syntax highlighting. +""" +from .base import DynamicLexer, Lexer, SimpleLexer +from .pygments import PygmentsLexer, RegexSync, SyncFromStart, SyntaxSync + +__all__ = [ + # Base. + "Lexer", + "SimpleLexer", + "DynamicLexer", + # Pygments. + "PygmentsLexer", + "RegexSync", + "SyncFromStart", + "SyntaxSync", +] diff --git a/.venv/lib/python3.8/site-packages/prompt_toolkit/lexers/__pycache__/__init__.cpython-38.pyc b/.venv/lib/python3.8/site-packages/prompt_toolkit/lexers/__pycache__/__init__.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..6365453ad1583d4a00397d87feef6f95f63697cf GIT binary patch literal 510 zcmZvYy-ve05XbZ3G-=vy42)Sbw2_b)kPt$s>Vyy?>f*%;v71=69pkv7Vc~grA%?6> zJOL65*eOB`oOM6z&c6ShZatgDjY!2Rhir9&@<|J?=xF z0|;E3^I5=0aKu9x@(4zJ496x9aDYcR#1S6jxC&v6C%KbOpO*18*%Osep^4fQB}oc_ z6UrqcoCsZL+K6@$uUmqXO{0>wGs%5Y)2e31H5Jt&emC&pT1}Gs~4~c&-bj``Co0l}#$&=qq61Sp*g%3%e8*8Qi3k zK12vNB|<&8FIsZ=`dbMj`P2Bna$8$4hR}5#MlRA@TT&a<68n&f6V|JHqh7c80BealRAD#0C?-;qTJ8F*%0621wf#;gz4RpPa EZ~eT7>;M1& literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/prompt_toolkit/lexers/__pycache__/base.cpython-38.pyc b/.venv/lib/python3.8/site-packages/prompt_toolkit/lexers/__pycache__/base.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..aab8a642bf83a2a72d6fbd9e0cda3c40118f5428 GIT binary patch literal 3375 zcmai0TW=dh6yDkOJx&Or&=i$2Kt*fRI)FfksH*4%0a6Kw22u89z41)!ZT4bj$F#Q0 zMQR1*0f`^bhxW05h=+aUiNAn^;5)PSW}UV$){f_T=FE4_cg}pdy4tc({`ui|Z?kDx ze^94fs_1-xFZ~gfuv|+pVTUZTT|07Ihf&`ND^b<0Mm4t<)!n)otAvfH={8Nf8n&Vp zcLnX5sEfwHaoZnRqA6;3F(Pfz`qgn)F|s1+7^%zEJC3`Cep@uqZX$BG`BZ8@Tl4o)t^B@@ zq#h=s<7AC1ei-_Dq0AZ|`{^)meKyiT68m9?WsR#ze;mnJqrGumPeOSq7Q6Dc-W`uZ znP$~%bXK-Ges6aw*`vfKh3=43OG_xsI&Js;tTSfXT+beZms< zeOox9a<_7axlP#;)%%R#yIXNrL<3MX70hK#Pq#SAAtnY9+^T?qrXSf^L(H#|)s)m@ z75D9uUespzuHZ{6s070iw!e!(a{x)%^$&o!&$kWu+r96Xf$uI(=q^y}aX%J3KMorU zLH#-ETn~NC^;~Qi#FEG3Xiuu;eLM_O&6E9Nf3J5oC1ZFn=Q*xnk4~@0wXuo0zmZGw zx~*cgH33K9dugsoaw^JMl2HJt>FtrYq4&hSIqMJP%#NYa1 zAbeu3Hw2Ym!Ek=@>hySi@yFKeblO?N^T1Z=d0ETzqC|}0RbJNiyl=*SIG?F|gs0~z zhmNjOMHI=LAl8ZyQX5newbk=f6~@e4q@p1!HB#EpV3mr^PPTBVCW4V~2-U~LQlUdW zz?UA46{0086dMpBstBS8y%afQ1F@rNVn-b_4beobXbA_FTTv9`r@t9A4H`KKL?YAp zjOHQ%<0f!=ICL-#;=vLDi6^&)Nho;`!*(1zNn&YanH_VIZI68AN8B)To9|+iX`)sn zk*sSR25ur%?f{v!0~%D#y4(|uuR>QU)Gj=cE-+&=%R>^nZarc6s)_81*(k|OA(Q5O$MO>%cGC}Ob5TA##1-u_UjL;)_2Q;`X( zv?wj{D936bwMR4Wk%FYDW!r3nt+DAFWyH!P?_LNK#PalFcd@zSsMoMly+{=a!GIyG z338`t)R5y#~Xdiqm|q9!WjMD6=A7x}vaxpQ)uQ^DFiy5)&(&Ou`i zqS-cIyl`?kMJ_Iqc-L(2f!e9|<32JbB{*{BW+CN&s7cW;r>16i;Ln~-6ji4%4D-K^ zKNEhknkU9lG+8j#OdJ}-cmrAQV|?Zf0&if`=gSG!CGj&#aq_ z82Z4Tv4==wOM0EbLgN`_KLtYwyCc!WEW1Y1DJ)n-j1x<`m6@T4=1XaHDVUM>F6oD; zGGmlvAJ^^})-E7Bi}q2qDC2yN?@+B%OKLrq_Bv}%Vvk8_ib!ZuRf$IhmvajJcbX$7 zzC_v(`9Y@I$;yiejO%lT`g?svNSIWb)%0Y9)Q}%-@#P0j@vbzqc3(X*i@Xx~ zT1(;4L$FKFAQO2qq-}5oX`9~3#sdw-O86P)%cI|gJojIu*H233sW|KGnB8V=$7cBb Kjj*t}zWFcx#|gIp literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/prompt_toolkit/lexers/__pycache__/pygments.cpython-38.pyc b/.venv/lib/python3.8/site-packages/prompt_toolkit/lexers/__pycache__/pygments.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e7a3dc359356c8bc384274f83163b809540a0909 GIT binary patch literal 9422 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 literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/prompt_toolkit/lexers/base.py b/.venv/lib/python3.8/site-packages/prompt_toolkit/lexers/base.py new file mode 100644 index 00000000..ef36cfd4 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/prompt_toolkit/lexers/base.py @@ -0,0 +1,82 @@ +""" +Base classes for prompt_toolkit lexers. +""" +from abc import ABCMeta, abstractmethod +from typing import Callable, Hashable, Optional + +from prompt_toolkit.document import Document +from prompt_toolkit.formatted_text.base import StyleAndTextTuples + +__all__ = [ + "Lexer", + "SimpleLexer", + "DynamicLexer", +] + + +class Lexer(metaclass=ABCMeta): + """ + Base class for all lexers. + """ + + @abstractmethod + def lex_document(self, document: Document) -> Callable[[int], StyleAndTextTuples]: + """ + Takes a :class:`~prompt_toolkit.document.Document` and returns a + callable that takes a line number and returns a list of + ``(style_str, text)`` tuples for that line. + + XXX: Note that in the past, this was supposed to return a list + of ``(Token, text)`` tuples, just like a Pygments lexer. + """ + + def invalidation_hash(self) -> Hashable: + """ + When this changes, `lex_document` could give a different output. + (Only used for `DynamicLexer`.) + """ + return id(self) + + +class SimpleLexer(Lexer): + """ + Lexer that doesn't do any tokenizing and returns the whole input as one + token. + + :param style: The style string for this lexer. + """ + + def __init__(self, style: str = "") -> None: + self.style = style + + def lex_document(self, document: Document) -> Callable[[int], StyleAndTextTuples]: + lines = document.lines + + def get_line(lineno: int) -> StyleAndTextTuples: + " Return the tokens for the given line. " + try: + return [(self.style, lines[lineno])] + except IndexError: + return [] + + return get_line + + +class DynamicLexer(Lexer): + """ + Lexer class that can dynamically returns any Lexer. + + :param get_lexer: Callable that returns a :class:`.Lexer` instance. + """ + + def __init__(self, get_lexer: Callable[[], Optional[Lexer]]) -> None: + self.get_lexer = get_lexer + self._dummy = SimpleLexer() + + def lex_document(self, document: Document) -> Callable[[int], StyleAndTextTuples]: + lexer = self.get_lexer() or self._dummy + return lexer.lex_document(document) + + def invalidation_hash(self) -> Hashable: + lexer = self.get_lexer() or self._dummy + return id(lexer) diff --git a/.venv/lib/python3.8/site-packages/prompt_toolkit/lexers/pygments.py b/.venv/lib/python3.8/site-packages/prompt_toolkit/lexers/pygments.py new file mode 100644 index 00000000..025078be --- /dev/null +++ b/.venv/lib/python3.8/site-packages/prompt_toolkit/lexers/pygments.py @@ -0,0 +1,335 @@ +""" +Adaptor classes for using Pygments lexers within prompt_toolkit. + +This includes syntax synchronization code, so that we don't have to start +lexing at the beginning of a document, when displaying a very large text. +""" +import re +from abc import ABCMeta, abstractmethod +from typing import ( + TYPE_CHECKING, + Callable, + Dict, + Generator, + Iterable, + Optional, + Tuple, + Type, +) + +from prompt_toolkit.document import Document +from prompt_toolkit.filters import FilterOrBool, to_filter +from prompt_toolkit.formatted_text.base import StyleAndTextTuples +from prompt_toolkit.formatted_text.utils import split_lines +from prompt_toolkit.styles.pygments import pygments_token_to_classname + +from .base import Lexer, SimpleLexer + +if TYPE_CHECKING: + from pygments.lexer import Lexer as PygmentsLexerCls + +__all__ = [ + "PygmentsLexer", + "SyntaxSync", + "SyncFromStart", + "RegexSync", +] + + +class SyntaxSync(metaclass=ABCMeta): + """ + Syntax synchroniser. This is a tool that finds a start position for the + lexer. This is especially important when editing big documents; we don't + want to start the highlighting by running the lexer from the beginning of + the file. That is very slow when editing. + """ + + @abstractmethod + def get_sync_start_position( + self, document: Document, lineno: int + ) -> Tuple[int, int]: + """ + Return the position from where we can start lexing as a (row, column) + tuple. + + :param document: `Document` instance that contains all the lines. + :param lineno: The line that we want to highlight. (We need to return + this line, or an earlier position.) + """ + + +class SyncFromStart(SyntaxSync): + """ + Always start the syntax highlighting from the beginning. + """ + + def get_sync_start_position( + self, document: Document, lineno: int + ) -> Tuple[int, int]: + return 0, 0 + + +class RegexSync(SyntaxSync): + """ + Synchronize by starting at a line that matches the given regex pattern. + """ + + # Never go more than this amount of lines backwards for synchronisation. + # That would be too CPU intensive. + MAX_BACKWARDS = 500 + + # Start lexing at the start, if we are in the first 'n' lines and no + # synchronisation position was found. + FROM_START_IF_NO_SYNC_POS_FOUND = 100 + + def __init__(self, pattern: str) -> None: + self._compiled_pattern = re.compile(pattern) + + def get_sync_start_position( + self, document: Document, lineno: int + ) -> Tuple[int, int]: + """ + Scan backwards, and find a possible position to start. + """ + pattern = self._compiled_pattern + lines = document.lines + + # Scan upwards, until we find a point where we can start the syntax + # synchronisation. + for i in range(lineno, max(-1, lineno - self.MAX_BACKWARDS), -1): + match = pattern.match(lines[i]) + if match: + return i, match.start() + + # No synchronisation point found. If we aren't that far from the + # beginning, start at the very beginning, otherwise, just try to start + # at the current line. + if lineno < self.FROM_START_IF_NO_SYNC_POS_FOUND: + return 0, 0 + else: + return lineno, 0 + + @classmethod + def from_pygments_lexer_cls(cls, lexer_cls: "PygmentsLexerCls") -> "RegexSync": + """ + Create a :class:`.RegexSync` instance for this Pygments lexer class. + """ + patterns = { + # For Python, start highlighting at any class/def block. + "Python": r"^\s*(class|def)\s+", + "Python 3": r"^\s*(class|def)\s+", + # For HTML, start at any open/close tag definition. + "HTML": r"<[/a-zA-Z]", + # For javascript, start at a function. + "JavaScript": r"\bfunction\b" + # TODO: Add definitions for other languages. + # By default, we start at every possible line. + } + p = patterns.get(lexer_cls.name, "^") + return cls(p) + + +class _TokenCache(Dict[Tuple[str, ...], str]): + """ + Cache that converts Pygments tokens into `prompt_toolkit` style objects. + + ``Token.A.B.C`` will be converted into: + ``class:pygments,pygments.A,pygments.A.B,pygments.A.B.C`` + """ + + def __missing__(self, key: Tuple[str, ...]) -> str: + result = "class:" + pygments_token_to_classname(key) + self[key] = result + return result + + +_token_cache = _TokenCache() + + +class PygmentsLexer(Lexer): + """ + Lexer that calls a pygments lexer. + + Example:: + + from pygments.lexers.html import HtmlLexer + lexer = PygmentsLexer(HtmlLexer) + + Note: Don't forget to also load a Pygments compatible style. E.g.:: + + from prompt_toolkit.styles.from_pygments import style_from_pygments_cls + from pygments.styles import get_style_by_name + style = style_from_pygments_cls(get_style_by_name('monokai')) + + :param pygments_lexer_cls: A `Lexer` from Pygments. + :param sync_from_start: Start lexing at the start of the document. This + will always give the best results, but it will be slow for bigger + documents. (When the last part of the document is display, then the + whole document will be lexed by Pygments on every key stroke.) It is + recommended to disable this for inputs that are expected to be more + than 1,000 lines. + :param syntax_sync: `SyntaxSync` object. + """ + + # Minimum amount of lines to go backwards when starting the parser. + # This is important when the lines are retrieved in reverse order, or when + # scrolling upwards. (Due to the complexity of calculating the vertical + # scroll offset in the `Window` class, lines are not always retrieved in + # order.) + MIN_LINES_BACKWARDS = 50 + + # When a parser was started this amount of lines back, read the parser + # until we get the current line. Otherwise, start a new parser. + # (This should probably be bigger than MIN_LINES_BACKWARDS.) + REUSE_GENERATOR_MAX_DISTANCE = 100 + + def __init__( + self, + pygments_lexer_cls: Type["PygmentsLexerCls"], + sync_from_start: FilterOrBool = True, + syntax_sync: Optional[SyntaxSync] = None, + ) -> None: + + self.pygments_lexer_cls = pygments_lexer_cls + self.sync_from_start = to_filter(sync_from_start) + + # Instantiate the Pygments lexer. + self.pygments_lexer = pygments_lexer_cls( + stripnl=False, stripall=False, ensurenl=False + ) + + # Create syntax sync instance. + self.syntax_sync = syntax_sync or RegexSync.from_pygments_lexer_cls( + pygments_lexer_cls + ) + + @classmethod + def from_filename( + cls, filename: str, sync_from_start: FilterOrBool = True + ) -> "Lexer": + """ + Create a `Lexer` from a filename. + """ + # Inline imports: the Pygments dependency is optional! + from pygments.lexers import get_lexer_for_filename + from pygments.util import ClassNotFound + + try: + pygments_lexer = get_lexer_for_filename(filename) + except ClassNotFound: + return SimpleLexer() + else: + return cls(pygments_lexer.__class__, sync_from_start=sync_from_start) + + def lex_document(self, document: Document) -> Callable[[int], StyleAndTextTuples]: + """ + Create a lexer function that takes a line number and returns the list + of (style_str, text) tuples as the Pygments lexer returns for that line. + """ + LineGenerator = Generator[Tuple[int, StyleAndTextTuples], None, None] + + # Cache of already lexed lines. + cache: Dict[int, StyleAndTextTuples] = {} + + # Pygments generators that are currently lexing. + # Map lexer generator to the line number. + line_generators: Dict[LineGenerator, int] = {} + + def get_syntax_sync() -> SyntaxSync: + " The Syntax synchronisation object that we currently use. " + if self.sync_from_start(): + return SyncFromStart() + else: + return self.syntax_sync + + def find_closest_generator(i: int) -> Optional[LineGenerator]: + " Return a generator close to line 'i', or None if none was found. " + for generator, lineno in line_generators.items(): + if lineno < i and i - lineno < self.REUSE_GENERATOR_MAX_DISTANCE: + return generator + return None + + def create_line_generator(start_lineno: int, column: int = 0) -> LineGenerator: + """ + Create a generator that yields the lexed lines. + Each iteration it yields a (line_number, [(style_str, text), ...]) tuple. + """ + + def get_text_fragments() -> Iterable[Tuple[str, str]]: + text = "\n".join(document.lines[start_lineno:])[column:] + + # We call `get_text_fragments_unprocessed`, because `get_tokens` will + # still replace \r\n and \r by \n. (We don't want that, + # Pygments should return exactly the same amount of text, as we + # have given as input.) + for _, t, v in self.pygments_lexer.get_tokens_unprocessed(text): + # Turn Pygments `Token` object into prompt_toolkit style + # strings. + yield _token_cache[t], v + + yield from enumerate(split_lines(list(get_text_fragments())), start_lineno) + + def get_generator(i: int) -> LineGenerator: + """ + Find an already started generator that is close, or create a new one. + """ + # Find closest line generator. + generator = find_closest_generator(i) + if generator: + return generator + + # No generator found. Determine starting point for the syntax + # synchronisation first. + + # Go at least x lines back. (Make scrolling upwards more + # efficient.) + i = max(0, i - self.MIN_LINES_BACKWARDS) + + if i == 0: + row = 0 + column = 0 + else: + row, column = get_syntax_sync().get_sync_start_position(document, i) + + # Find generator close to this point, or otherwise create a new one. + generator = find_closest_generator(i) + if generator: + return generator + else: + generator = create_line_generator(row, column) + + # If the column is not 0, ignore the first line. (Which is + # incomplete. This happens when the synchronisation algorithm tells + # us to start parsing in the middle of a line.) + if column: + next(generator) + row += 1 + + line_generators[generator] = row + return generator + + def get_line(i: int) -> StyleAndTextTuples: + " Return the tokens for a given line number. " + try: + return cache[i] + except KeyError: + generator = get_generator(i) + + # Exhaust the generator, until we find the requested line. + for num, line in generator: + cache[num] = line + if num == i: + line_generators[generator] = i + + # Remove the next item from the cache. + # (It could happen that it's already there, because of + # another generator that started filling these lines, + # but we want to synchronise these lines with the + # current lexer's state.) + if num + 1 in cache: + del cache[num + 1] + + return cache[num] + return [] + + return get_line diff --git a/.venv/lib/python3.8/site-packages/prompt_toolkit/log.py b/.venv/lib/python3.8/site-packages/prompt_toolkit/log.py new file mode 100644 index 00000000..36ceced4 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/prompt_toolkit/log.py @@ -0,0 +1,10 @@ +""" +Logging configuration. +""" +import logging + +__all__ = [ + "logger", +] + +logger = logging.getLogger(__package__) diff --git a/.venv/lib/python3.8/site-packages/prompt_toolkit/mouse_events.py b/.venv/lib/python3.8/site-packages/prompt_toolkit/mouse_events.py new file mode 100644 index 00000000..7c2a9069 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/prompt_toolkit/mouse_events.py @@ -0,0 +1,45 @@ +""" +Mouse events. + + +How it works +------------ + +The renderer has a 2 dimensional grid of mouse event handlers. +(`prompt_toolkit.layout.MouseHandlers`.) When the layout is rendered, the +`Window` class will make sure that this grid will also be filled with +callbacks. For vt100 terminals, mouse events are received through stdin, just +like any other key press. There is a handler among the key bindings that +catches these events and forwards them to such a mouse event handler. It passes +through the `Window` class where the coordinates are translated from absolute +coordinates to coordinates relative to the user control, and there +`UIControl.mouse_handler` is called. +""" +from enum import Enum + +from .data_structures import Point + +__all__ = ["MouseEventType", "MouseEvent"] + + +class MouseEventType(Enum): + MOUSE_UP = "MOUSE_UP" + MOUSE_DOWN = "MOUSE_DOWN" + SCROLL_UP = "SCROLL_UP" + SCROLL_DOWN = "SCROLL_DOWN" + + +class MouseEvent: + """ + Mouse event, sent to `UIControl.mouse_handler`. + + :param position: `Point` instance. + :param event_type: `MouseEventType`. + """ + + def __init__(self, position: Point, event_type: MouseEventType) -> None: + self.position = position + self.event_type = event_type + + def __repr__(self) -> str: + return "MouseEvent(%r, %r)" % (self.position, self.event_type) diff --git a/.venv/lib/python3.8/site-packages/prompt_toolkit/output/__init__.py b/.venv/lib/python3.8/site-packages/prompt_toolkit/output/__init__.py new file mode 100644 index 00000000..7b90b476 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/prompt_toolkit/output/__init__.py @@ -0,0 +1,13 @@ +from .base import DummyOutput, Output +from .color_depth import ColorDepth +from .defaults import create_output + +__all__ = [ + # Base. + "Output", + "DummyOutput", + # Color depth. + "ColorDepth", + # Defaults. + "create_output", +] diff --git a/.venv/lib/python3.8/site-packages/prompt_toolkit/output/__pycache__/__init__.cpython-38.pyc b/.venv/lib/python3.8/site-packages/prompt_toolkit/output/__pycache__/__init__.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..21f6fa483a9841a04a8e64a2f39a174d25721d4b GIT binary patch literal 357 zcmYjMyH3O~5R4t?agQK=BSnaWgai^o2(E?#(YRTK*pTS#vvC}utN0#%h{7!uJq3sxzy?QK0DRRi?9-U1xyz01#~Vx!;};giFG OheNbRYl0CD_5BA|3|iIz literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/prompt_toolkit/output/__pycache__/base.cpython-38.pyc b/.venv/lib/python3.8/site-packages/prompt_toolkit/output/__pycache__/base.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a2a522b4950f1804768c13aba0136c0df0042cf4 GIT binary patch literal 13029 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 bm_}2`Pv%Cmqq$Kez;b^q^iTaP^U?nSC4fF> literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/prompt_toolkit/output/__pycache__/color_depth.cpython-38.pyc b/.venv/lib/python3.8/site-packages/prompt_toolkit/output/__pycache__/color_depth.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f3a13a6596bb00f618bd8625bb74aebab6887907 GIT binary patch literal 1646 zcmZ`(&rc&a6t+E+WEeuA?5gcntu#_Ats)iJA6==H5ZW!I1(i(@35Qy$tYK`(EY8f} zaaa+t>H+?N-h0?R_8;oO*PixY=w@m`lL|tA z*~x5!HS`>MxekUSjwPb@pGZ6)lwdpdq&M)X4`crr)5?#CSGa!#Gf@@f(x)|!yQo=x z4=12@6C1yk4F~WabPAp3Su9Psnaf;li9+`iyKA=jFnJEWJOm>U#T-#`07$4Od{No;8i*&sx%ZeIxhlR7jtw$G{hoD4-l{Yj(Nc6uKY_(mqY`w+m(>dyOoc4 z9dIrv8*%h3jG*o1WtkpI5hWI2#4W<;ES5u2Mn|xq`y$GRx)|zJx8GEp)68$R_Ilgw zG5da}H=TSlJNed4>f>!soC_GKDxrreOE4gqHUa|=`X==95g3j+xk4Ikp-cP*Yy675 z^|<#AU*MCf`uYOd74AI%Zx?C+8C6EcfwKwiy8sUNY)a{oTl#8mzw>gh$9kR4?oT^C zw%OV3>@x>464_a*@@yb7eSO+ltkT%h(~ryOP>3ul1u${#@AcC%f?piHj?W{V!y&+0 zB48mAO2=t-i&&V(QbvW!2Zd%j&*e#a6D%$YnI^H7OgU!TCUhrPUCY%nm}7K-ehJ?I zH?Pod^LJ}a4~n%SEmnqE5ho{tue|OHAy>Y8#&rMm zNq_A&wzYBX*Bq71sbjS`H{rTWOPxR#8!Hxx6;u@wGoQMbS#H2! z`WF4{{|nJ>`c9#SU|IAWSfg`lZDcfI(pcFX09m z-Ma(Zf5^3BbVB?X23Cj?4M2n#UEoXfmb^nCH*d6kEr1!had8w6rM^}0=@pv#X0MVh z?t6O?;9e{wO2k^QvA^k=VDd((ED-t$WDoSa0BoihO``6B-);Ig6}8F!r?A0Q2vzE2 zv^>MYWJ9~TYy!rzcpw-vA!CD_52YQ~89N=ua^k5m#`6T0y;3W)$XJ|ZxgP74F;%rd zYSviV)f^ZazU;I+o7-^dT6F0}ySp>Kab4DF@BVCRTdf~n9PIXJ*xNs7ja_Cwk#SiL zgzo2DdG@6H)_iKswUEanTX829`-v|<2NPo74?KVRVBbE3;QNaNHv_c#S^{ rO;w*4X?E$vWb4}RqzRJ5H| literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/prompt_toolkit/output/__pycache__/conemu.cpython-38.pyc b/.venv/lib/python3.8/site-packages/prompt_toolkit/output/__pycache__/conemu.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0e0654ff9f8bb93f653a398c10b40fb9dca9ad45 GIT binary patch literal 2250 zcmZuz&2QT_6c;7=BetBRTiUch*YQxSGuGN&hYr|K6fLq3bO#q$x((2Ukwx0pB8e(V z#dQ#1hvvHfpoi_)e`p6?cj|e!9hSXE*{u_l0O?2a@qPZ@lYi>%nWwH&*t;HcUjE>`|dAE z{>8m|TLpVE|28Y@U5xtHM*}vGVCo-W5l%?B6S|y)9uI^s8lrg(BEY>@9(sJ*2wS2p zHhA+D;VtmWe@ViQ=!$@EymEPmcTfGW$6fHOrveZdedIb$hr+0hpr3+eT+Vf$O6w1e z#@eVTM!yH0bR8D%g`KtC$^+FjE|rD{nLHAi$iatmymSUmi(FGP zQ?i`S;8)NKX4HYR{>`JsZ8{e;j&gW;BO(FjQJETM?PVO%T{V?3rOIOu;ItY@BXIX% z>Q7)X&IvgI*#7RGIE)zggdk{79ed`%na3Rfr9bKuwF&$&%yR=J?!(mBFAOvSPF^C6 z-I2nIQ>g8=qqdR8<=;m`lNG}vDejbc5ygjs-pCg{y#Se~?Dmm`4w9g1moVI>)!xOLf3lk|&0-!Gl!Bfbxex)GzwJ>H>ci%(2c{ zEn1=JRd8fmL45?V^|eSRss~rr@pm4mOUT|{Dft+78cWvkHi=7Ir|Gz7$Cux05Cm}x z7-NjgY9Ni%ro;z=6C1wotVVco1&sGUpni#NtBT0v-(=!*Sf>>*rKoVC=h< zpGTRf?XWNK6%3>?nbr=BEI@%AHq{P5#QBw+*tA+2K!Pc@z;H+XcGaE=!=PM6cmpW~ zZHkRWD(9@OP*zBtVCxBYL>`S(!7>TO&z8L>yv!5*p5xuR?Af@SOoT#DYh;AiQA?dc zU=bo;u_XCKhF6w4#?T!Pg%O+;ScT#4O3Q@{$aM<@M#d<$1AeQ^u=L$J?$_|(EqLqH zcNtsqGxizW>n1D?X?Ftm`0BafuQB$?sK1G*!RRwqbr=MJmkw zu}a+kg0@Sxy;1*C)ijF&`dKZ?Dn=8+8|Mphz#|heP+7tk0N|z2{c!gJld|0r8W{Y0 zaKi3dW3t|a4O?z?={0OF>&gW0p|ykeSW;D6iD`l@^nFf2BdA085bH;O0LzXWkN_tM LJon6RY~KDK1o>ld literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/prompt_toolkit/output/__pycache__/defaults.cpython-38.pyc b/.venv/lib/python3.8/site-packages/prompt_toolkit/output/__pycache__/defaults.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d7440d6e9bec952fd92bf957d6be4d8f5fb29c79 GIT binary patch literal 1749 zcmZWpPjBNy6d#Wr$8nQ3ZL zBN8~2>wW>mVfV;^3!i{b!NDgaPWu%&Yx=^StMm-<$V)@6Fe(R*2xb{qfKE zw+2Fg8)fmTf$|g{bp;|piIbtoym97m9AWN8F83nOF*Y}=aX<3y+RN%Zhyvb-8a#|b zu+e{qwgB>1TottQSf>bBlMY;@Rl z%iyTcsmN(o`hE67e{ocL1FCe_DVL6QBF6elDPBy#@$nhcv1XFTEWb*n$T`b(d_`qS zPcv37rz#$Zobho?bCs4M=+|kUh->x6fmi_OAB}Y}HqhaL$b@{x3Oy=Y1IegnF@%DT zeTd{M8@ODh*)^T0xR7kfWUTe1^d-|{nGdkp{@rER_Tf2zNBsptqZ>5C+IfXvqnSGe zhA#rSuibNRhNe!n0_kme4=|XNu#F*^>#)HSi)Qjk70HDr zl=S=G_Q*#j?EQR*WH~^PDy_LcXEfJD3v$ZdK|wdFF=q)moe(8B)1x#$BLZ@^iRTc+ zv~vo*zX1+F1_Xy6g%DK1NI+Y^154PDjx*isTFaq?!8R@3JP`Tkd|Z)hX6AXCKiR!g zaoGmdOu)`|T-nM_H5T!e-r3%UNisna_~ZIr0GJ_|j5sl)Ver4PesjRcGdq?Y6a0N? znqDq}h=L*1+{|U^0?D!kHakT?b?K*yn$dxQoY!8OBPd!CGCecd$5mlvV61*M#IkKL zYB0f1cIB%1(72oCoo%@Wx?DHHGr|m@tb>SZHZA$UtgAg0deRN;hUBubw(JQq-)_`d zNH?BaOPmTD-v(ZYW^jK+@)5lL+27K<*ecRubDS4+aKVzz>k(tw<|iM=dUUxv+PdF2 zTf&|%TX#IGUNMnP05WN)ryx+FY@W%_hw;C0!#7QPGF@x6~`B9*pMf+nRL#<1yB0rm8|4 zf^CUP@02QLS&x<$__M80*5jCFSsa5G8~`>&OW1;V3`k}0DHq8&W1pGBSs6+Lr-PeL U$A@%XeCwI+y2XxQJ{{59=AGWvDh9g7TA}1 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

UI0Ly~t}q;~s%;q3$O#;WoTp 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 DSgwfi literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/prompt_toolkit/output/__pycache__/windows10.cpython-38.pyc b/.venv/lib/python3.8/site-packages/prompt_toolkit/output/__pycache__/windows10.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..920d4dd1fd97072fc0935256f2fbf2b2471ab760 GIT binary patch literal 3043 zcmZ`*OLH8z5e8;vXJ?-zB|a=mmM5|uXX6qniRF}&a;Yqnw9G1b=^`n~g$puVfaH+# z5`Z<$bWEfvAHn#20r~S=mZfoAt_}vb(lkO>?CgLF)yvLnjO1|pVnDD4OoyiSi|bP zq?xu@%gVK+opxBq%6`&KC)k9Q>&av~#il?GL?gM9US(IU+)Sp^88&0(Rx+E;u{n_2 zJCuDO0(MPw*oO~^=!*6+XpbCrU3N}x$m_2tCGsON@sf&3F?H;*o8rm_>0NyTw;(;I ztZhA4a=Y{o;!Gq7DwdzFtuL4U_YeBZk5+na=|0Gwm%&31mYy?YJSD$KDZTE!mbG(R%5Kw&;LGS2z&033UbBkDfF` zXlDlt@7@V>8-Os{(nduC4AgwMxf|528YbT0R@fY#{Z# zb=Zes``QTbR$diyI~pd24=_?(V5mx8Ni$U00HHW;DC6aq;L~40XUHKvgscC{5V)Mz?@=`a9^MNs?y-UXu|f<$U(h2AhtpS> zP}P9$HBoaYWB0$M1(OyFMO@q-W<@mEm*V!pu9V5`KYz*1?z4Nl3x&$l!f=!4$$o4W zssJvWVdw6h`2ryKbrPjpBD()OaQR>O$mom9V3_AT&SJy){MSi7h!TAtglbiw`=K-&Mtl!>OQh=HWP|Sx@=WK6gfw|t zCfjNnS7OB8UR`})9gUB514g-GXkGyoS)Ffn#6XU}C6#{E1zqE$`HE2Tlze%??$ECL2?_*q z>W&sI7%jq8Y-DKiF}?xaGDC zaT>2vb~oOcDQ8#u559f0!hc*}TUy!JSXt()eISnV)|vjv>iXv62aovX%K8theGtwJ zSNjhYM!BrnBlR2=;;56WcqazF;wkQX4o#aM^*NY)2A{@qCSKr9yFT@3^B1q?(5^e0 zeJ?%M`8!F$1mS0sg4Y(*mc(~B=!G>`$=qW}#^t(AceP__l{^m~mm*pY^7 zAaZsSB?VN=w`7tZ@WD`Npq?VvF)|vPuE-1m3QWfJuqbk6*o=rZa@-~LoF1q=N%+=q zds`~JZB_B?2JTXoB$!B7$s*jbm);gIqw2v-=|b5lJdL`I z-P?0p3HippN;uL;9Rc-fq!bk|eOEnB z$iDqvTfuKSqRzSA(v!N0I%M~Xw?07$Ye``ZDP#!sd+2&D3&!NH{s0Pmi8Z{=7m{Il zf4chp!>jkD!m?P01sbPG4M@hBbOUm}cpnw2X$gp5SSh1V$zO3^iG7$#^4F~Yk0eoY|+1w=~B{LvNsZOKlb6Jsj85xqhTCb>%#99i*8o4!KfbInzgUqWvGS-2!g*2vxRXPD7h0u w%`3GC4sC2Mg!vrv@bjQ5v-?QGI)rYLPSRRx-*ryCnnyji`&HBZKcRd1y#N3J literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/prompt_toolkit/output/base.py b/.venv/lib/python3.8/site-packages/prompt_toolkit/output/base.py new file mode 100644 index 00000000..38744953 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/prompt_toolkit/output/base.py @@ -0,0 +1,303 @@ +""" +Interface for an output. +""" +from abc import ABCMeta, abstractmethod + +from prompt_toolkit.data_structures import Size +from prompt_toolkit.styles import Attrs + +from .color_depth import ColorDepth + +__all__ = [ + "Output", + "DummyOutput", +] + + +class Output(metaclass=ABCMeta): + """ + Base class defining the output interface for a + :class:`~prompt_toolkit.renderer.Renderer`. + + Actual implementations are + :class:`~prompt_toolkit.output.vt100.Vt100_Output` and + :class:`~prompt_toolkit.output.win32.Win32Output`. + """ + + @abstractmethod + def fileno(self) -> int: + " Return the file descriptor to which we can write for the output. " + + @abstractmethod + def encoding(self) -> str: + """ + Return the encoding for this output, e.g. 'utf-8'. + (This is used mainly to know which characters are supported by the + output the data, so that the UI can provide alternatives, when + required.) + """ + + @abstractmethod + def write(self, data: str) -> None: + " Write text (Terminal escape sequences will be removed/escaped.) " + + @abstractmethod + def write_raw(self, data: str) -> None: + " Write text. " + + @abstractmethod + def set_title(self, title: str) -> None: + " Set terminal title. " + + @abstractmethod + def clear_title(self) -> None: + " Clear title again. (or restore previous title.) " + + @abstractmethod + def flush(self) -> None: + " Write to output stream and flush. " + + @abstractmethod + def erase_screen(self) -> None: + """ + Erases the screen with the background colour and moves the cursor to + home. + """ + + @abstractmethod + def enter_alternate_screen(self) -> None: + " Go to the alternate screen buffer. (For full screen applications). " + + @abstractmethod + def quit_alternate_screen(self) -> None: + " Leave the alternate screen buffer. " + + @abstractmethod + def enable_mouse_support(self) -> None: + " Enable mouse. " + + @abstractmethod + def disable_mouse_support(self) -> None: + " Disable mouse. " + + @abstractmethod + def erase_end_of_line(self) -> None: + """ + Erases from the current cursor position to the end of the current line. + """ + + @abstractmethod + def erase_down(self) -> None: + """ + Erases the screen from the current line down to the bottom of the + screen. + """ + + @abstractmethod + def reset_attributes(self) -> None: + " Reset color and styling attributes. " + + @abstractmethod + def set_attributes(self, attrs: Attrs, color_depth: ColorDepth) -> None: + " Set new color and styling attributes. " + + @abstractmethod + def disable_autowrap(self) -> None: + " Disable auto line wrapping. " + + @abstractmethod + def enable_autowrap(self) -> None: + " Enable auto line wrapping. " + + @abstractmethod + def cursor_goto(self, row: int = 0, column: int = 0) -> None: + " Move cursor position. " + + @abstractmethod + def cursor_up(self, amount: int) -> None: + " Move cursor `amount` place up. " + + @abstractmethod + def cursor_down(self, amount: int) -> None: + " Move cursor `amount` place down. " + + @abstractmethod + def cursor_forward(self, amount: int) -> None: + " Move cursor `amount` place forward. " + + @abstractmethod + def cursor_backward(self, amount: int) -> None: + " Move cursor `amount` place backward. " + + @abstractmethod + def hide_cursor(self) -> None: + " Hide cursor. " + + @abstractmethod + def show_cursor(self) -> None: + " Show cursor. " + + def ask_for_cpr(self) -> None: + """ + Asks for a cursor position report (CPR). + (VT100 only.) + """ + + @property + def responds_to_cpr(self) -> bool: + """ + `True` if the `Application` can expect to receive a CPR response after + calling `ask_for_cpr` (this will come back through the corresponding + `Input`). + + This is used to determine the amount of available rows we have below + the cursor position. In the first place, we have this so that the drop + down autocompletion menus are sized according to the available space. + + On Windows, we don't need this, there we have + `get_rows_below_cursor_position`. + """ + return False + + @abstractmethod + def get_size(self) -> Size: + " Return the size of the output window. " + + def bell(self) -> None: + " Sound bell. " + + def enable_bracketed_paste(self) -> None: + " For vt100 only. " + + def disable_bracketed_paste(self) -> None: + " For vt100 only. " + + def scroll_buffer_to_prompt(self) -> None: + " For Win32 only. " + + def get_rows_below_cursor_position(self) -> int: + " For Windows only. " + raise NotImplementedError + + @abstractmethod + def get_default_color_depth(self) -> ColorDepth: + """ + Get default color depth for this output. + + This value will be used if no color depth was explicitely passed to the + `Application`. + + .. note:: + + If the `$PROMPT_TOOLKIT_COLOR_DEPTH` environment variable has been + set, then `outputs.defaults.create_output` will pass this value to + the implementation as the default_color_depth, which is returned + here. (This is not used when the output corresponds to a + prompt_toolkit SSH/Telnet session.) + """ + + +class DummyOutput(Output): + """ + For testing. An output class that doesn't render anything. + """ + + def fileno(self) -> int: + " There is no sensible default for fileno(). " + raise NotImplementedError + + def encoding(self) -> str: + return "utf-8" + + def write(self, data: str) -> None: + pass + + def write_raw(self, data: str) -> None: + pass + + def set_title(self, title: str) -> None: + pass + + def clear_title(self) -> None: + pass + + def flush(self) -> None: + pass + + def erase_screen(self) -> None: + pass + + def enter_alternate_screen(self) -> None: + pass + + def quit_alternate_screen(self) -> None: + pass + + def enable_mouse_support(self) -> None: + pass + + def disable_mouse_support(self) -> None: + pass + + def erase_end_of_line(self) -> None: + pass + + def erase_down(self) -> None: + pass + + def reset_attributes(self) -> None: + pass + + def set_attributes(self, attrs: Attrs, color_depth: ColorDepth) -> None: + pass + + def disable_autowrap(self) -> None: + pass + + def enable_autowrap(self) -> None: + pass + + def cursor_goto(self, row: int = 0, column: int = 0) -> None: + pass + + def cursor_up(self, amount: int) -> None: + pass + + def cursor_down(self, amount: int) -> None: + pass + + def cursor_forward(self, amount: int) -> None: + pass + + def cursor_backward(self, amount: int) -> None: + pass + + def hide_cursor(self) -> None: + pass + + def show_cursor(self) -> None: + pass + + def ask_for_cpr(self) -> None: + pass + + def bell(self) -> None: + pass + + def enable_bracketed_paste(self) -> None: + pass + + def disable_bracketed_paste(self) -> None: + pass + + def scroll_buffer_to_prompt(self) -> None: + pass + + def get_size(self) -> Size: + return Size(rows=40, columns=80) + + def get_rows_below_cursor_position(self) -> int: + return 40 + + def get_default_color_depth(self) -> ColorDepth: + return ColorDepth.DEPTH_1_BIT diff --git a/.venv/lib/python3.8/site-packages/prompt_toolkit/output/color_depth.py b/.venv/lib/python3.8/site-packages/prompt_toolkit/output/color_depth.py new file mode 100644 index 00000000..a6166bac --- /dev/null +++ b/.venv/lib/python3.8/site-packages/prompt_toolkit/output/color_depth.py @@ -0,0 +1,58 @@ +import os +from enum import Enum +from typing import Optional + +__all__ = [ + "ColorDepth", +] + + +class ColorDepth(str, Enum): + """ + Possible color depth values for the output. + """ + + value: str + + #: One color only. + DEPTH_1_BIT = "DEPTH_1_BIT" + + #: ANSI Colors. + DEPTH_4_BIT = "DEPTH_4_BIT" + + #: The default. + DEPTH_8_BIT = "DEPTH_8_BIT" + + #: 24 bit True color. + DEPTH_24_BIT = "DEPTH_24_BIT" + + # Aliases. + MONOCHROME = DEPTH_1_BIT + ANSI_COLORS_ONLY = DEPTH_4_BIT + DEFAULT = DEPTH_8_BIT + TRUE_COLOR = DEPTH_24_BIT + + @classmethod + def from_env(cls) -> Optional["ColorDepth"]: + """ + Return the color depth if the $PROMPT_TOOLKIT_COLOR_DEPTH environment + variable has been set. + + This is a way to enforce a certain color depth in all prompt_toolkit + applications. + """ + # Check the `PROMPT_TOOLKIT_COLOR_DEPTH` environment variable. + all_values = [i.value for i in ColorDepth] + if os.environ.get("PROMPT_TOOLKIT_COLOR_DEPTH") in all_values: + return cls(os.environ["PROMPT_TOOLKIT_COLOR_DEPTH"]) + + return None + + @classmethod + def default(cls) -> "ColorDepth": + """ + Return the default color depth for the default output. + """ + from .defaults import create_output + + return create_output().get_default_color_depth() diff --git a/.venv/lib/python3.8/site-packages/prompt_toolkit/output/conemu.py b/.venv/lib/python3.8/site-packages/prompt_toolkit/output/conemu.py new file mode 100644 index 00000000..616cf5b1 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/prompt_toolkit/output/conemu.py @@ -0,0 +1,59 @@ +from typing import Any, Optional, TextIO + +from prompt_toolkit.data_structures import Size +from prompt_toolkit.renderer import Output + +from .color_depth import ColorDepth +from .vt100 import Vt100_Output +from .win32 import Win32Output + +__all__ = [ + "ConEmuOutput", +] + + +class ConEmuOutput: + """ + ConEmu (Windows) output abstraction. + + ConEmu is a Windows console application, but it also supports ANSI escape + sequences. This output class is actually a proxy to both `Win32Output` and + `Vt100_Output`. It uses `Win32Output` for console sizing and scrolling, but + all cursor movements and scrolling happens through the `Vt100_Output`. + + This way, we can have 256 colors in ConEmu and Cmder. Rendering will be + even a little faster as well. + + http://conemu.github.io/ + http://gooseberrycreative.com/cmder/ + """ + + def __init__( + self, stdout: TextIO, default_color_depth: Optional[ColorDepth] = None + ) -> None: + self.win32_output = Win32Output(stdout, default_color_depth=default_color_depth) + self.vt100_output = Vt100_Output( + stdout, lambda: Size(0, 0), default_color_depth=default_color_depth + ) + + @property + def responds_to_cpr(self) -> bool: + return False # We don't need this on Windows. + + def __getattr__(self, name: str) -> Any: + if name in ( + "get_size", + "get_rows_below_cursor_position", + "enable_mouse_support", + "disable_mouse_support", + "scroll_buffer_to_prompt", + "get_win32_screen_buffer_info", + "enable_bracketed_paste", + "disable_bracketed_paste", + ): + return getattr(self.win32_output, name) + else: + return getattr(self.vt100_output, name) + + +Output.register(ConEmuOutput) diff --git a/.venv/lib/python3.8/site-packages/prompt_toolkit/output/defaults.py b/.venv/lib/python3.8/site-packages/prompt_toolkit/output/defaults.py new file mode 100644 index 00000000..96eac455 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/prompt_toolkit/output/defaults.py @@ -0,0 +1,76 @@ +import sys +from typing import Optional, TextIO, cast + +from prompt_toolkit.patch_stdout import StdoutProxy +from prompt_toolkit.utils import ( + get_term_environment_variable, + is_conemu_ansi, + is_windows, +) + +from .base import Output +from .color_depth import ColorDepth + +__all__ = [ + "create_output", +] + + +def create_output( + stdout: Optional[TextIO] = None, always_prefer_tty: bool = True +) -> Output: + """ + Return an :class:`~prompt_toolkit.output.Output` instance for the command + line. + + :param stdout: The stdout object + :param always_prefer_tty: When set, look for `sys.stderr` if `sys.stdout` + is not a TTY. (The prompt_toolkit render output is not meant to be + consumed by something other then a terminal, so this is a reasonable + default.) + """ + # Consider TERM and PROMPT_TOOLKIT_COLOR_DEPTH environment variables. + # Notice that PROMPT_TOOLKIT_COLOR_DEPTH value is the default that's used + # if the Application doesn't override it. + term_from_env = get_term_environment_variable() + color_depth_from_env = ColorDepth.from_env() + + if stdout is None: + # By default, render to stdout. If the output is piped somewhere else, + # render to stderr. + stdout = sys.stdout + + if always_prefer_tty: + for io in [sys.stdout, sys.stderr]: + if io.isatty(): + stdout = io + break + + # If the patch_stdout context manager has been used, then sys.stdout is + # replaced by this proxy. For prompt_toolkit applications, we want to use + # the real stdout. + while isinstance(stdout, StdoutProxy): + stdout = stdout.original_stdout + + if is_windows(): + from .conemu import ConEmuOutput + from .win32 import Win32Output + from .windows10 import Windows10_Output, is_win_vt100_enabled + + if is_win_vt100_enabled(): + return cast( + Output, + Windows10_Output(stdout, default_color_depth=color_depth_from_env), + ) + if is_conemu_ansi(): + return cast( + Output, ConEmuOutput(stdout, default_color_depth=color_depth_from_env) + ) + else: + return Win32Output(stdout, default_color_depth=color_depth_from_env) + else: + from .vt100 import Vt100_Output + + return Vt100_Output.from_pty( + stdout, term=term_from_env, default_color_depth=color_depth_from_env + ) diff --git a/.venv/lib/python3.8/site-packages/prompt_toolkit/output/vt100.py b/.venv/lib/python3.8/site-packages/prompt_toolkit/output/vt100.py new file mode 100644 index 00000000..bfa61bd1 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/prompt_toolkit/output/vt100.py @@ -0,0 +1,738 @@ +""" +Output for vt100 terminals. + +A lot of thanks, regarding outputting of colors, goes to the Pygments project: +(We don't rely on Pygments anymore, because many things are very custom, and +everything has been highly optimized.) +http://pygments.org/ +""" +import array +import errno +import io +import os +import sys +from typing import ( + IO, + Callable, + Dict, + Hashable, + Iterable, + List, + Optional, + Sequence, + Set, + TextIO, + Tuple, +) + +from prompt_toolkit.data_structures import Size +from prompt_toolkit.output import Output +from prompt_toolkit.styles import ANSI_COLOR_NAMES, Attrs +from prompt_toolkit.utils import is_dumb_terminal + +from .color_depth import ColorDepth + +__all__ = [ + "Vt100_Output", +] + + +FG_ANSI_COLORS = { + "ansidefault": 39, + # Low intensity. + "ansiblack": 30, + "ansired": 31, + "ansigreen": 32, + "ansiyellow": 33, + "ansiblue": 34, + "ansimagenta": 35, + "ansicyan": 36, + "ansigray": 37, + # High intensity. + "ansibrightblack": 90, + "ansibrightred": 91, + "ansibrightgreen": 92, + "ansibrightyellow": 93, + "ansibrightblue": 94, + "ansibrightmagenta": 95, + "ansibrightcyan": 96, + "ansiwhite": 97, +} + +BG_ANSI_COLORS = { + "ansidefault": 49, + # Low intensity. + "ansiblack": 40, + "ansired": 41, + "ansigreen": 42, + "ansiyellow": 43, + "ansiblue": 44, + "ansimagenta": 45, + "ansicyan": 46, + "ansigray": 47, + # High intensity. + "ansibrightblack": 100, + "ansibrightred": 101, + "ansibrightgreen": 102, + "ansibrightyellow": 103, + "ansibrightblue": 104, + "ansibrightmagenta": 105, + "ansibrightcyan": 106, + "ansiwhite": 107, +} + + +ANSI_COLORS_TO_RGB = { + "ansidefault": ( + 0x00, + 0x00, + 0x00, + ), # Don't use, 'default' doesn't really have a value. + "ansiblack": (0x00, 0x00, 0x00), + "ansigray": (0xE5, 0xE5, 0xE5), + "ansibrightblack": (0x7F, 0x7F, 0x7F), + "ansiwhite": (0xFF, 0xFF, 0xFF), + # Low intensity. + "ansired": (0xCD, 0x00, 0x00), + "ansigreen": (0x00, 0xCD, 0x00), + "ansiyellow": (0xCD, 0xCD, 0x00), + "ansiblue": (0x00, 0x00, 0xCD), + "ansimagenta": (0xCD, 0x00, 0xCD), + "ansicyan": (0x00, 0xCD, 0xCD), + # High intensity. + "ansibrightred": (0xFF, 0x00, 0x00), + "ansibrightgreen": (0x00, 0xFF, 0x00), + "ansibrightyellow": (0xFF, 0xFF, 0x00), + "ansibrightblue": (0x00, 0x00, 0xFF), + "ansibrightmagenta": (0xFF, 0x00, 0xFF), + "ansibrightcyan": (0x00, 0xFF, 0xFF), +} + + +assert set(FG_ANSI_COLORS) == set(ANSI_COLOR_NAMES) +assert set(BG_ANSI_COLORS) == set(ANSI_COLOR_NAMES) +assert set(ANSI_COLORS_TO_RGB) == set(ANSI_COLOR_NAMES) + + +def _get_closest_ansi_color(r: int, g: int, b: int, exclude: Sequence[str] = ()) -> str: + """ + Find closest ANSI color. Return it by name. + + :param r: Red (Between 0 and 255.) + :param g: Green (Between 0 and 255.) + :param b: Blue (Between 0 and 255.) + :param exclude: A tuple of color names to exclude. (E.g. ``('ansired', )``.) + """ + exclude = list(exclude) + + # When we have a bit of saturation, avoid the gray-like colors, otherwise, + # too often the distance to the gray color is less. + saturation = abs(r - g) + abs(g - b) + abs(b - r) # Between 0..510 + + if saturation > 30: + exclude.extend(["ansilightgray", "ansidarkgray", "ansiwhite", "ansiblack"]) + + # Take the closest color. + # (Thanks to Pygments for this part.) + distance = 257 * 257 * 3 # "infinity" (>distance from #000000 to #ffffff) + match = "ansidefault" + + for name, (r2, g2, b2) in ANSI_COLORS_TO_RGB.items(): + if name != "ansidefault" and name not in exclude: + d = (r - r2) ** 2 + (g - g2) ** 2 + (b - b2) ** 2 + + if d < distance: + match = name + distance = d + + return match + + +_ColorCodeAndName = Tuple[int, str] + + +class _16ColorCache: + """ + Cache which maps (r, g, b) tuples to 16 ansi colors. + + :param bg: Cache for background colors, instead of foreground. + """ + + def __init__(self, bg: bool = False) -> None: + self.bg = bg + self._cache: Dict[Hashable, _ColorCodeAndName] = {} + + def get_code( + self, value: Tuple[int, int, int], exclude: Sequence[str] = () + ) -> _ColorCodeAndName: + """ + Return a (ansi_code, ansi_name) tuple. (E.g. ``(44, 'ansiblue')``.) for + a given (r,g,b) value. + """ + key: Hashable = (value, tuple(exclude)) + cache = self._cache + + if key not in cache: + cache[key] = self._get(value, exclude) + + return cache[key] + + def _get( + self, value: Tuple[int, int, int], exclude: Sequence[str] = () + ) -> _ColorCodeAndName: + + r, g, b = value + match = _get_closest_ansi_color(r, g, b, exclude=exclude) + + # Turn color name into code. + if self.bg: + code = BG_ANSI_COLORS[match] + else: + code = FG_ANSI_COLORS[match] + + return code, match + + +class _256ColorCache(Dict[Tuple[int, int, int], int]): + """ + Cache which maps (r, g, b) tuples to 256 colors. + """ + + def __init__(self) -> None: + # Build color table. + colors: List[Tuple[int, int, int]] = [] + + # colors 0..15: 16 basic colors + colors.append((0x00, 0x00, 0x00)) # 0 + colors.append((0xCD, 0x00, 0x00)) # 1 + colors.append((0x00, 0xCD, 0x00)) # 2 + colors.append((0xCD, 0xCD, 0x00)) # 3 + colors.append((0x00, 0x00, 0xEE)) # 4 + colors.append((0xCD, 0x00, 0xCD)) # 5 + colors.append((0x00, 0xCD, 0xCD)) # 6 + colors.append((0xE5, 0xE5, 0xE5)) # 7 + colors.append((0x7F, 0x7F, 0x7F)) # 8 + colors.append((0xFF, 0x00, 0x00)) # 9 + colors.append((0x00, 0xFF, 0x00)) # 10 + colors.append((0xFF, 0xFF, 0x00)) # 11 + colors.append((0x5C, 0x5C, 0xFF)) # 12 + colors.append((0xFF, 0x00, 0xFF)) # 13 + colors.append((0x00, 0xFF, 0xFF)) # 14 + colors.append((0xFF, 0xFF, 0xFF)) # 15 + + # colors 16..232: the 6x6x6 color cube + valuerange = (0x00, 0x5F, 0x87, 0xAF, 0xD7, 0xFF) + + for i in range(217): + r = valuerange[(i // 36) % 6] + g = valuerange[(i // 6) % 6] + b = valuerange[i % 6] + colors.append((r, g, b)) + + # colors 233..253: grayscale + for i in range(1, 22): + v = 8 + i * 10 + colors.append((v, v, v)) + + self.colors = colors + + def __missing__(self, value: Tuple[int, int, int]) -> int: + r, g, b = value + + # Find closest color. + # (Thanks to Pygments for this!) + distance = 257 * 257 * 3 # "infinity" (>distance from #000000 to #ffffff) + match = 0 + + for i, (r2, g2, b2) in enumerate(self.colors): + if i >= 16: # XXX: We ignore the 16 ANSI colors when mapping RGB + # to the 256 colors, because these highly depend on + # the color scheme of the terminal. + d = (r - r2) ** 2 + (g - g2) ** 2 + (b - b2) ** 2 + + if d < distance: + match = i + distance = d + + # Turn color name into code. + self[value] = match + return match + + +_16_fg_colors = _16ColorCache(bg=False) +_16_bg_colors = _16ColorCache(bg=True) +_256_colors = _256ColorCache() + + +class _EscapeCodeCache(Dict[Attrs, str]): + """ + Cache for VT100 escape codes. It maps + (fgcolor, bgcolor, bold, underline, reverse) tuples to VT100 escape sequences. + + :param true_color: When True, use 24bit colors instead of 256 colors. + """ + + def __init__(self, color_depth: ColorDepth) -> None: + self.color_depth = color_depth + + def __missing__(self, attrs: Attrs) -> str: + fgcolor, bgcolor, bold, underline, italic, blink, reverse, hidden = attrs + parts: List[str] = [] + + parts.extend(self._colors_to_code(fgcolor or "", bgcolor or "")) + + if bold: + parts.append("1") + if italic: + parts.append("3") + if blink: + parts.append("5") + if underline: + parts.append("4") + if reverse: + parts.append("7") + if hidden: + parts.append("8") + + if parts: + result = "\x1b[0;" + ";".join(parts) + "m" + else: + result = "\x1b[0m" + + self[attrs] = result + return result + + def _color_name_to_rgb(self, color: str) -> Tuple[int, int, int]: + " Turn 'ffffff', into (0xff, 0xff, 0xff). " + try: + rgb = int(color, 16) + except ValueError: + raise + else: + r = (rgb >> 16) & 0xFF + g = (rgb >> 8) & 0xFF + b = rgb & 0xFF + return r, g, b + + def _colors_to_code(self, fg_color: str, bg_color: str) -> Iterable[str]: + """ + Return a tuple with the vt100 values that represent this color. + """ + # When requesting ANSI colors only, and both fg/bg color were converted + # to ANSI, ensure that the foreground and background color are not the + # same. (Unless they were explicitly defined to be the same color.) + fg_ansi = "" + + def get(color: str, bg: bool) -> List[int]: + nonlocal fg_ansi + + table = BG_ANSI_COLORS if bg else FG_ANSI_COLORS + + if not color or self.color_depth == ColorDepth.DEPTH_1_BIT: + return [] + + # 16 ANSI colors. (Given by name.) + elif color in table: + return [table[color]] + + # RGB colors. (Defined as 'ffffff'.) + else: + try: + rgb = self._color_name_to_rgb(color) + except ValueError: + return [] + + # When only 16 colors are supported, use that. + if self.color_depth == ColorDepth.DEPTH_4_BIT: + if bg: # Background. + if fg_color != bg_color: + exclude = [fg_ansi] + else: + exclude = [] + code, name = _16_bg_colors.get_code(rgb, exclude=exclude) + return [code] + else: # Foreground. + code, name = _16_fg_colors.get_code(rgb) + fg_ansi = name + return [code] + + # True colors. (Only when this feature is enabled.) + elif self.color_depth == ColorDepth.DEPTH_24_BIT: + r, g, b = rgb + return [(48 if bg else 38), 2, r, g, b] + + # 256 RGB colors. + else: + return [(48 if bg else 38), 5, _256_colors[rgb]] + + result: List[int] = [] + result.extend(get(fg_color, False)) + result.extend(get(bg_color, True)) + + return map(str, result) + + +def _get_size(fileno: int) -> Tuple[int, int]: + # Thanks to fabric (fabfile.org), and + # http://sqizit.bartletts.id.au/2011/02/14/pseudo-terminals-in-python/ + """ + Get the size of this pseudo terminal. + + :param fileno: stdout.fileno() + :returns: A (rows, cols) tuple. + """ + # Inline imports, because these modules are not available on Windows. + # (This file is used by ConEmuOutput, which is used on Windows.) + import fcntl + import termios + + # Buffer for the C call + buf = array.array("h", [0, 0, 0, 0]) + + # Do TIOCGWINSZ (Get) + # Note: We should not pass 'True' as a fourth parameter to 'ioctl'. (True + # is the default.) This causes segmentation faults on some systems. + # See: https://github.com/jonathanslenders/python-prompt-toolkit/pull/364 + fcntl.ioctl(fileno, termios.TIOCGWINSZ, buf) # type: ignore + + # Return rows, cols + return buf[0], buf[1] + + +class Vt100_Output(Output): + """ + :param get_size: A callable which returns the `Size` of the output terminal. + :param stdout: Any object with has a `write` and `flush` method + an 'encoding' property. + :param term: The terminal environment variable. (xterm, xterm-256color, linux, ...) + :param write_binary: Encode the output before writing it. If `True` (the + default), the `stdout` object is supposed to expose an `encoding` attribute. + """ + + # For the error messages. Only display "Output is not a terminal" once per + # file descriptor. + _fds_not_a_terminal: Set[int] = set() + + def __init__( + self, + stdout: TextIO, + get_size: Callable[[], Size], + term: Optional[str] = None, + write_binary: bool = True, + default_color_depth: Optional[ColorDepth] = None, + ) -> None: + + assert all(hasattr(stdout, a) for a in ("write", "flush")) + + if write_binary: + assert hasattr(stdout, "encoding") + + self._buffer: List[str] = [] + self.stdout = stdout + self.write_binary = write_binary + self.default_color_depth = default_color_depth + self._get_size = get_size + self.term = term + + # Cache for escape codes. + self._escape_code_caches: Dict[ColorDepth, _EscapeCodeCache] = { + ColorDepth.DEPTH_1_BIT: _EscapeCodeCache(ColorDepth.DEPTH_1_BIT), + ColorDepth.DEPTH_4_BIT: _EscapeCodeCache(ColorDepth.DEPTH_4_BIT), + ColorDepth.DEPTH_8_BIT: _EscapeCodeCache(ColorDepth.DEPTH_8_BIT), + ColorDepth.DEPTH_24_BIT: _EscapeCodeCache(ColorDepth.DEPTH_24_BIT), + } + + @classmethod + def from_pty( + cls, + stdout: TextIO, + term: Optional[str] = None, + default_color_depth: Optional[ColorDepth] = None, + ) -> "Vt100_Output": + """ + Create an Output class from a pseudo terminal. + (This will take the dimensions by reading the pseudo + terminal attributes.) + """ + fd: Optional[int] + # Normally, this requires a real TTY device, but people instantiate + # this class often during unit tests as well. For convenience, we print + # an error message, use standard dimensions, and go on. + try: + fd = stdout.fileno() + except io.UnsupportedOperation: + fd = None + + if not stdout.isatty() and (fd is None or fd not in cls._fds_not_a_terminal): + msg = "Warning: Output is not a terminal (fd=%r).\n" + sys.stderr.write(msg % fd) + sys.stderr.flush() + if fd is not None: + cls._fds_not_a_terminal.add(fd) + + def get_size() -> Size: + # If terminal (incorrectly) reports its size as 0, pick a + # reasonable default. See + # https://github.com/ipython/ipython/issues/10071 + rows, columns = (None, None) + + # It is possible that `stdout` is no longer a TTY device at this + # point. In that case we get an `OSError` in the ioctl call in + # `get_size`. See: + # https://github.com/prompt-toolkit/python-prompt-toolkit/pull/1021 + try: + rows, columns = _get_size(stdout.fileno()) + except OSError: + pass + return Size(rows=rows or 24, columns=columns or 80) + + return cls(stdout, get_size, term=term, default_color_depth=default_color_depth) + + def get_size(self) -> Size: + return self._get_size() + + def fileno(self) -> int: + " Return file descriptor. " + return self.stdout.fileno() + + def encoding(self) -> str: + " Return encoding used for stdout. " + return self.stdout.encoding + + def write_raw(self, data: str) -> None: + """ + Write raw data to output. + """ + self._buffer.append(data) + + def write(self, data: str) -> None: + """ + Write text to output. + (Removes vt100 escape codes. -- used for safely writing text.) + """ + self._buffer.append(data.replace("\x1b", "?")) + + def set_title(self, title: str) -> None: + """ + Set terminal title. + """ + if self.term not in ( + "linux", + "eterm-color", + ): # Not supported by the Linux console. + self.write_raw( + "\x1b]2;%s\x07" % title.replace("\x1b", "").replace("\x07", "") + ) + + def clear_title(self) -> None: + self.set_title("") + + def erase_screen(self) -> None: + """ + Erases the screen with the background colour and moves the cursor to + home. + """ + self.write_raw("\x1b[2J") + + def enter_alternate_screen(self) -> None: + self.write_raw("\x1b[?1049h\x1b[H") + + def quit_alternate_screen(self) -> None: + self.write_raw("\x1b[?1049l") + + def enable_mouse_support(self) -> None: + self.write_raw("\x1b[?1000h") + + # Enable urxvt Mouse mode. (For terminals that understand this.) + self.write_raw("\x1b[?1015h") + + # Also enable Xterm SGR mouse mode. (For terminals that understand this.) + self.write_raw("\x1b[?1006h") + + # Note: E.g. lxterminal understands 1000h, but not the urxvt or sgr + # extensions. + + def disable_mouse_support(self) -> None: + self.write_raw("\x1b[?1000l") + self.write_raw("\x1b[?1015l") + self.write_raw("\x1b[?1006l") + + def erase_end_of_line(self) -> None: + """ + Erases from the current cursor position to the end of the current line. + """ + self.write_raw("\x1b[K") + + def erase_down(self) -> None: + """ + Erases the screen from the current line down to the bottom of the + screen. + """ + self.write_raw("\x1b[J") + + def reset_attributes(self) -> None: + self.write_raw("\x1b[0m") + + def set_attributes(self, attrs: Attrs, color_depth: ColorDepth) -> None: + """ + Create new style and output. + + :param attrs: `Attrs` instance. + """ + # Get current depth. + escape_code_cache = self._escape_code_caches[color_depth] + + # Write escape character. + self.write_raw(escape_code_cache[attrs]) + + def disable_autowrap(self) -> None: + self.write_raw("\x1b[?7l") + + def enable_autowrap(self) -> None: + self.write_raw("\x1b[?7h") + + def enable_bracketed_paste(self) -> None: + self.write_raw("\x1b[?2004h") + + def disable_bracketed_paste(self) -> None: + self.write_raw("\x1b[?2004l") + + def cursor_goto(self, row: int = 0, column: int = 0) -> None: + """ + Move cursor position. + """ + self.write_raw("\x1b[%i;%iH" % (row, column)) + + def cursor_up(self, amount: int) -> None: + if amount == 0: + pass + elif amount == 1: + self.write_raw("\x1b[A") + else: + self.write_raw("\x1b[%iA" % amount) + + def cursor_down(self, amount: int) -> None: + if amount == 0: + pass + elif amount == 1: + # Note: Not the same as '\n', '\n' can cause the window content to + # scroll. + self.write_raw("\x1b[B") + else: + self.write_raw("\x1b[%iB" % amount) + + def cursor_forward(self, amount: int) -> None: + if amount == 0: + pass + elif amount == 1: + self.write_raw("\x1b[C") + else: + self.write_raw("\x1b[%iC" % amount) + + def cursor_backward(self, amount: int) -> None: + if amount == 0: + pass + elif amount == 1: + self.write_raw("\b") # '\x1b[D' + else: + self.write_raw("\x1b[%iD" % amount) + + def hide_cursor(self) -> None: + self.write_raw("\x1b[?25l") + + def show_cursor(self) -> None: + self.write_raw("\x1b[?12l\x1b[?25h") # Stop blinking cursor and show. + + def flush(self) -> None: + """ + Write to output stream and flush. + """ + if not self._buffer: + return + + data = "".join(self._buffer) + + try: + # (We try to encode ourself, because that way we can replace + # characters that don't exist in the character set, avoiding + # UnicodeEncodeError crashes. E.g. u'\xb7' does not appear in 'ascii'.) + # My Arch Linux installation of july 2015 reported 'ANSI_X3.4-1968' + # for sys.stdout.encoding in xterm. + out: IO + if self.write_binary: + if hasattr(self.stdout, "buffer"): + out = self.stdout.buffer # Py3. + else: + out = self.stdout + out.write(data.encode(self.stdout.encoding or "utf-8", "replace")) + else: + self.stdout.write(data) + + self.stdout.flush() + except IOError as e: + if e.args and e.args[0] == errno.EINTR: + # Interrupted system call. Can happen in case of a window + # resize signal. (Just ignore. The resize handler will render + # again anyway.) + pass + elif e.args and e.args[0] == 0: + # This can happen when there is a lot of output and the user + # sends a KeyboardInterrupt by pressing Control-C. E.g. in + # a Python REPL when we execute "while True: print('test')". + # (The `ptpython` REPL uses this `Output` class instead of + # `stdout` directly -- in order to be network transparent.) + # So, just ignore. + pass + else: + raise + + self._buffer = [] + + def ask_for_cpr(self) -> None: + """ + Asks for a cursor position report (CPR). + """ + self.write_raw("\x1b[6n") + self.flush() + + @property + def responds_to_cpr(self) -> bool: + # When the input is a tty, we assume that CPR is supported. + # It's not when the input is piped from Pexpect. + if os.environ.get("PROMPT_TOOLKIT_NO_CPR", "") == "1": + return False + + if is_dumb_terminal(self.term): + return False + try: + return self.stdout.isatty() + except ValueError: + return False # ValueError: I/O operation on closed file + + def bell(self) -> None: + " Sound bell. " + self.write_raw("\a") + self.flush() + + def get_default_color_depth(self) -> ColorDepth: + """ + Return the default color depth for a vt100 terminal, according to the + our term value. + + We prefer 256 colors almost always, because this is what most terminals + support these days, and is a good default. + """ + if self.default_color_depth is not None: + return self.default_color_depth + + term = self.term + + if term is None: + return ColorDepth.DEFAULT + + if is_dumb_terminal(term): + return ColorDepth.DEPTH_1_BIT + + if term in ("linux", "eterm-color"): + return ColorDepth.DEPTH_4_BIT + + return ColorDepth.DEFAULT diff --git a/.venv/lib/python3.8/site-packages/prompt_toolkit/output/win32.py b/.venv/lib/python3.8/site-packages/prompt_toolkit/output/win32.py new file mode 100644 index 00000000..4519c14b --- /dev/null +++ b/.venv/lib/python3.8/site-packages/prompt_toolkit/output/win32.py @@ -0,0 +1,656 @@ +import os +from ctypes import ( + ArgumentError, + byref, + c_char, + c_long, + c_uint, + c_ulong, + pointer, + windll, +) +from ctypes.wintypes import DWORD, HANDLE +from typing import Dict, List, Optional, TextIO, Tuple + +from prompt_toolkit.data_structures import Size +from prompt_toolkit.renderer import Output +from prompt_toolkit.styles import ANSI_COLOR_NAMES, Attrs +from prompt_toolkit.utils import get_cwidth +from prompt_toolkit.win32_types import ( + CONSOLE_SCREEN_BUFFER_INFO, + COORD, + SMALL_RECT, + STD_INPUT_HANDLE, + STD_OUTPUT_HANDLE, +) + +from .color_depth import ColorDepth + +__all__ = [ + "Win32Output", +] + + +def _coord_byval(coord): + """ + Turns a COORD object into a c_long. + This will cause it to be passed by value instead of by reference. (That is what I think at least.) + + When running ``ptipython`` is run (only with IPython), we often got the following error:: + + Error in 'SetConsoleCursorPosition'. + ArgumentError("argument 2: : wrong type",) + argument 2: : wrong type + + It was solved by turning ``COORD`` parameters into a ``c_long`` like this. + + More info: http://msdn.microsoft.com/en-us/library/windows/desktop/ms686025(v=vs.85).aspx + """ + return c_long(coord.Y * 0x10000 | coord.X & 0xFFFF) + + +#: If True: write the output of the renderer also to the following file. This +#: is very useful for debugging. (e.g.: to see that we don't write more bytes +#: than required.) +_DEBUG_RENDER_OUTPUT = False +_DEBUG_RENDER_OUTPUT_FILENAME = r"prompt-toolkit-windows-output.log" + + +class NoConsoleScreenBufferError(Exception): + """ + Raised when the application is not running inside a Windows Console, but + the user tries to instantiate Win32Output. + """ + + def __init__(self) -> None: + # Are we running in 'xterm' on Windows, like git-bash for instance? + xterm = "xterm" in os.environ.get("TERM", "") + + if xterm: + message = ( + "Found %s, while expecting a Windows console. " + 'Maybe try to run this program using "winpty" ' + "or run it in cmd.exe instead. Or otherwise, " + "in case of Cygwin, use the Python executable " + "that is compiled for Cygwin." % os.environ["TERM"] + ) + else: + message = "No Windows console found. Are you running cmd.exe?" + super().__init__(message) + + +class Win32Output(Output): + """ + I/O abstraction for rendering to Windows consoles. + (cmd.exe and similar.) + """ + + def __init__( + self, + stdout: TextIO, + use_complete_width: bool = False, + default_color_depth: Optional[ColorDepth] = None, + ) -> None: + self.use_complete_width = use_complete_width + self.default_color_depth = default_color_depth + + self._buffer: List[str] = [] + self.stdout = stdout + self.hconsole = HANDLE(windll.kernel32.GetStdHandle(STD_OUTPUT_HANDLE)) + + self._in_alternate_screen = False + self._hidden = False + + self.color_lookup_table = ColorLookupTable() + + # Remember the default console colors. + info = self.get_win32_screen_buffer_info() + self.default_attrs = info.wAttributes if info else 15 + + if _DEBUG_RENDER_OUTPUT: + self.LOG = open(_DEBUG_RENDER_OUTPUT_FILENAME, "ab") + + def fileno(self) -> int: + " Return file descriptor. " + return self.stdout.fileno() + + def encoding(self) -> str: + " Return encoding used for stdout. " + return self.stdout.encoding + + def write(self, data: str) -> None: + if self._hidden: + data = " " * get_cwidth(data) + + self._buffer.append(data) + + def write_raw(self, data: str) -> None: + " For win32, there is no difference between write and write_raw. " + self.write(data) + + def get_size(self) -> Size: + info = self.get_win32_screen_buffer_info() + + # We take the width of the *visible* region as the size. Not the width + # of the complete screen buffer. (Unless use_complete_width has been + # set.) + if self.use_complete_width: + width = info.dwSize.X + else: + width = info.srWindow.Right - info.srWindow.Left + + height = info.srWindow.Bottom - info.srWindow.Top + 1 + + # We avoid the right margin, windows will wrap otherwise. + maxwidth = info.dwSize.X - 1 + width = min(maxwidth, width) + + # Create `Size` object. + return Size(rows=height, columns=width) + + def _winapi(self, func, *a, **kw): + """ + Flush and call win API function. + """ + self.flush() + + if _DEBUG_RENDER_OUTPUT: + self.LOG.write(("%r" % func.__name__).encode("utf-8") + b"\n") + self.LOG.write( + b" " + ", ".join(["%r" % i for i in a]).encode("utf-8") + b"\n" + ) + self.LOG.write( + b" " + + ", ".join(["%r" % type(i) for i in a]).encode("utf-8") + + b"\n" + ) + self.LOG.flush() + + try: + return func(*a, **kw) + except ArgumentError as e: + if _DEBUG_RENDER_OUTPUT: + self.LOG.write( + (" Error in %r %r %s\n" % (func.__name__, e, e)).encode("utf-8") + ) + + def get_win32_screen_buffer_info(self): + """ + Return Screen buffer info. + """ + # NOTE: We don't call the `GetConsoleScreenBufferInfo` API through + # `self._winapi`. Doing so causes Python to crash on certain 64bit + # Python versions. (Reproduced with 64bit Python 2.7.6, on Windows + # 10). It is not clear why. Possibly, it has to do with passing + # these objects as an argument, or through *args. + + # The Python documentation contains the following - possibly related - warning: + # ctypes does not support passing unions or structures with + # bit-fields to functions by value. While this may work on 32-bit + # x86, it's not guaranteed by the library to work in the general + # case. Unions and structures with bit-fields should always be + # passed to functions by pointer. + + # Also see: + # - https://github.com/ipython/ipython/issues/10070 + # - https://github.com/jonathanslenders/python-prompt-toolkit/issues/406 + # - https://github.com/jonathanslenders/python-prompt-toolkit/issues/86 + + self.flush() + sbinfo = CONSOLE_SCREEN_BUFFER_INFO() + success = windll.kernel32.GetConsoleScreenBufferInfo( + self.hconsole, byref(sbinfo) + ) + + # success = self._winapi(windll.kernel32.GetConsoleScreenBufferInfo, + # self.hconsole, byref(sbinfo)) + + if success: + return sbinfo + else: + raise NoConsoleScreenBufferError + + def set_title(self, title: str) -> None: + """ + Set terminal title. + """ + self._winapi(windll.kernel32.SetConsoleTitleW, title) + + def clear_title(self) -> None: + self._winapi(windll.kernel32.SetConsoleTitleW, "") + + def erase_screen(self) -> None: + start = COORD(0, 0) + sbinfo = self.get_win32_screen_buffer_info() + length = sbinfo.dwSize.X * sbinfo.dwSize.Y + + self.cursor_goto(row=0, column=0) + self._erase(start, length) + + def erase_down(self) -> None: + sbinfo = self.get_win32_screen_buffer_info() + size = sbinfo.dwSize + + start = sbinfo.dwCursorPosition + length = (size.X - size.X) + size.X * (size.Y - sbinfo.dwCursorPosition.Y) + + self._erase(start, length) + + def erase_end_of_line(self) -> None: + """""" + sbinfo = self.get_win32_screen_buffer_info() + start = sbinfo.dwCursorPosition + length = sbinfo.dwSize.X - sbinfo.dwCursorPosition.X + + self._erase(start, length) + + def _erase(self, start, length): + chars_written = c_ulong() + + self._winapi( + windll.kernel32.FillConsoleOutputCharacterA, + self.hconsole, + c_char(b" "), + DWORD(length), + _coord_byval(start), + byref(chars_written), + ) + + # Reset attributes. + sbinfo = self.get_win32_screen_buffer_info() + self._winapi( + windll.kernel32.FillConsoleOutputAttribute, + self.hconsole, + sbinfo.wAttributes, + length, + _coord_byval(start), + byref(chars_written), + ) + + def reset_attributes(self) -> None: + " Reset the console foreground/background color. " + self._winapi( + windll.kernel32.SetConsoleTextAttribute, self.hconsole, self.default_attrs + ) + self._hidden = False + + def set_attributes(self, attrs: Attrs, color_depth: ColorDepth) -> None: + fgcolor, bgcolor, bold, underline, italic, blink, reverse, hidden = attrs + self._hidden = bool(hidden) + + # Start from the default attributes. + win_attrs: int = self.default_attrs + + if color_depth != ColorDepth.DEPTH_1_BIT: + # Override the last four bits: foreground color. + if fgcolor: + win_attrs = win_attrs & ~0xF + win_attrs |= self.color_lookup_table.lookup_fg_color(fgcolor) + + # Override the next four bits: background color. + if bgcolor: + win_attrs = win_attrs & ~0xF0 + win_attrs |= self.color_lookup_table.lookup_bg_color(bgcolor) + + # Reverse: swap these four bits groups. + if reverse: + win_attrs = ( + (win_attrs & ~0xFF) + | ((win_attrs & 0xF) << 4) + | ((win_attrs & 0xF0) >> 4) + ) + + self._winapi(windll.kernel32.SetConsoleTextAttribute, self.hconsole, win_attrs) + + def disable_autowrap(self) -> None: + # Not supported by Windows. + pass + + def enable_autowrap(self) -> None: + # Not supported by Windows. + pass + + def cursor_goto(self, row: int = 0, column: int = 0) -> None: + pos = COORD(x=column, y=row) + self._winapi( + windll.kernel32.SetConsoleCursorPosition, self.hconsole, _coord_byval(pos) + ) + + def cursor_up(self, amount: int) -> None: + sr = self.get_win32_screen_buffer_info().dwCursorPosition + pos = COORD(sr.X, sr.Y - amount) + self._winapi( + windll.kernel32.SetConsoleCursorPosition, self.hconsole, _coord_byval(pos) + ) + + def cursor_down(self, amount: int) -> None: + self.cursor_up(-amount) + + def cursor_forward(self, amount: int) -> None: + sr = self.get_win32_screen_buffer_info().dwCursorPosition + # assert sr.X + amount >= 0, 'Negative cursor position: x=%r amount=%r' % (sr.X, amount) + + pos = COORD(max(0, sr.X + amount), sr.Y) + self._winapi( + windll.kernel32.SetConsoleCursorPosition, self.hconsole, _coord_byval(pos) + ) + + def cursor_backward(self, amount: int) -> None: + self.cursor_forward(-amount) + + def flush(self) -> None: + """ + Write to output stream and flush. + """ + if not self._buffer: + # Only flush stdout buffer. (It could be that Python still has + # something in its buffer. -- We want to be sure to print that in + # the correct color.) + self.stdout.flush() + return + + data = "".join(self._buffer) + + if _DEBUG_RENDER_OUTPUT: + self.LOG.write(("%r" % data).encode("utf-8") + b"\n") + self.LOG.flush() + + # Print characters one by one. This appears to be the best solution + # in oder to avoid traces of vertical lines when the completion + # menu disappears. + for b in data: + written = DWORD() + + retval = windll.kernel32.WriteConsoleW( + self.hconsole, b, 1, byref(written), None + ) + assert retval != 0 + + self._buffer = [] + + def get_rows_below_cursor_position(self) -> int: + info = self.get_win32_screen_buffer_info() + return info.srWindow.Bottom - info.dwCursorPosition.Y + 1 + + def scroll_buffer_to_prompt(self) -> None: + """ + To be called before drawing the prompt. This should scroll the console + to left, with the cursor at the bottom (if possible). + """ + # Get current window size + info = self.get_win32_screen_buffer_info() + sr = info.srWindow + cursor_pos = info.dwCursorPosition + + result = SMALL_RECT() + + # Scroll to the left. + result.Left = 0 + result.Right = sr.Right - sr.Left + + # Scroll vertical + win_height = sr.Bottom - sr.Top + if 0 < sr.Bottom - cursor_pos.Y < win_height - 1: + # no vertical scroll if cursor already on the screen + result.Bottom = sr.Bottom + else: + result.Bottom = max(win_height, cursor_pos.Y) + result.Top = result.Bottom - win_height + + # Scroll API + self._winapi( + windll.kernel32.SetConsoleWindowInfo, self.hconsole, True, byref(result) + ) + + def enter_alternate_screen(self) -> None: + """ + Go to alternate screen buffer. + """ + if not self._in_alternate_screen: + GENERIC_READ = 0x80000000 + GENERIC_WRITE = 0x40000000 + + # Create a new console buffer and activate that one. + handle = HANDLE( + self._winapi( + windll.kernel32.CreateConsoleScreenBuffer, + GENERIC_READ | GENERIC_WRITE, + DWORD(0), + None, + DWORD(1), + None, + ) + ) + + self._winapi(windll.kernel32.SetConsoleActiveScreenBuffer, handle) + self.hconsole = handle + self._in_alternate_screen = True + + def quit_alternate_screen(self) -> None: + """ + Make stdout again the active buffer. + """ + if self._in_alternate_screen: + stdout = HANDLE( + self._winapi(windll.kernel32.GetStdHandle, STD_OUTPUT_HANDLE) + ) + self._winapi(windll.kernel32.SetConsoleActiveScreenBuffer, stdout) + self._winapi(windll.kernel32.CloseHandle, self.hconsole) + self.hconsole = stdout + self._in_alternate_screen = False + + def enable_mouse_support(self) -> None: + ENABLE_MOUSE_INPUT = 0x10 + handle = HANDLE(windll.kernel32.GetStdHandle(STD_INPUT_HANDLE)) + + original_mode = DWORD() + self._winapi(windll.kernel32.GetConsoleMode, handle, pointer(original_mode)) + self._winapi( + windll.kernel32.SetConsoleMode, + handle, + original_mode.value | ENABLE_MOUSE_INPUT, + ) + + def disable_mouse_support(self) -> None: + ENABLE_MOUSE_INPUT = 0x10 + handle = HANDLE(windll.kernel32.GetStdHandle(STD_INPUT_HANDLE)) + + original_mode = DWORD() + self._winapi(windll.kernel32.GetConsoleMode, handle, pointer(original_mode)) + self._winapi( + windll.kernel32.SetConsoleMode, + handle, + original_mode.value & ~ENABLE_MOUSE_INPUT, + ) + + def hide_cursor(self) -> None: + pass + + def show_cursor(self) -> None: + pass + + @classmethod + def win32_refresh_window(cls) -> None: + """ + Call win32 API to refresh the whole Window. + + This is sometimes necessary when the application paints background + for completion menus. When the menu disappears, it leaves traces due + to a bug in the Windows Console. Sending a repaint request solves it. + """ + # Get console handle + handle = HANDLE(windll.kernel32.GetConsoleWindow()) + + RDW_INVALIDATE = 0x0001 + windll.user32.RedrawWindow(handle, None, None, c_uint(RDW_INVALIDATE)) + + def get_default_color_depth(self) -> ColorDepth: + """ + Return the default color depth for a windows terminal. + + Contrary to the Vt100 implementation, this doesn't depend on a $TERM + variable. + """ + if self.default_color_depth is not None: + return self.default_color_depth + + # For now, by default, always use 4 bit color on Windows 10 by default, + # even when vt100 escape sequences with + # ENABLE_VIRTUAL_TERMINAL_PROCESSING are supported. We don't have a + # reliable way yet to know whether our console supports true color or + # only 4-bit. + return ColorDepth.DEPTH_4_BIT + + +class FOREGROUND_COLOR: + BLACK = 0x0000 + BLUE = 0x0001 + GREEN = 0x0002 + CYAN = 0x0003 + RED = 0x0004 + MAGENTA = 0x0005 + YELLOW = 0x0006 + GRAY = 0x0007 + INTENSITY = 0x0008 # Foreground color is intensified. + + +class BACKGROUND_COLOR: + BLACK = 0x0000 + BLUE = 0x0010 + GREEN = 0x0020 + CYAN = 0x0030 + RED = 0x0040 + MAGENTA = 0x0050 + YELLOW = 0x0060 + GRAY = 0x0070 + INTENSITY = 0x0080 # Background color is intensified. + + +def _create_ansi_color_dict(color_cls) -> Dict[str, int]: + " Create a table that maps the 16 named ansi colors to their Windows code. " + return { + "ansidefault": color_cls.BLACK, + "ansiblack": color_cls.BLACK, + "ansigray": color_cls.GRAY, + "ansibrightblack": color_cls.BLACK | color_cls.INTENSITY, + "ansiwhite": color_cls.GRAY | color_cls.INTENSITY, + # Low intensity. + "ansired": color_cls.RED, + "ansigreen": color_cls.GREEN, + "ansiyellow": color_cls.YELLOW, + "ansiblue": color_cls.BLUE, + "ansimagenta": color_cls.MAGENTA, + "ansicyan": color_cls.CYAN, + # High intensity. + "ansibrightred": color_cls.RED | color_cls.INTENSITY, + "ansibrightgreen": color_cls.GREEN | color_cls.INTENSITY, + "ansibrightyellow": color_cls.YELLOW | color_cls.INTENSITY, + "ansibrightblue": color_cls.BLUE | color_cls.INTENSITY, + "ansibrightmagenta": color_cls.MAGENTA | color_cls.INTENSITY, + "ansibrightcyan": color_cls.CYAN | color_cls.INTENSITY, + } + + +FG_ANSI_COLORS = _create_ansi_color_dict(FOREGROUND_COLOR) +BG_ANSI_COLORS = _create_ansi_color_dict(BACKGROUND_COLOR) + +assert set(FG_ANSI_COLORS) == set(ANSI_COLOR_NAMES) +assert set(BG_ANSI_COLORS) == set(ANSI_COLOR_NAMES) + + +class ColorLookupTable: + """ + Inspired by pygments/formatters/terminal256.py + """ + + def __init__(self) -> None: + self._win32_colors = self._build_color_table() + + # Cache (map color string to foreground and background code). + self.best_match: Dict[str, Tuple[int, int]] = {} + + @staticmethod + def _build_color_table() -> List[Tuple[int, int, int, int, int]]: + """ + Build an RGB-to-256 color conversion table + """ + FG = FOREGROUND_COLOR + BG = BACKGROUND_COLOR + + return [ + (0x00, 0x00, 0x00, FG.BLACK, BG.BLACK), + (0x00, 0x00, 0xAA, FG.BLUE, BG.BLUE), + (0x00, 0xAA, 0x00, FG.GREEN, BG.GREEN), + (0x00, 0xAA, 0xAA, FG.CYAN, BG.CYAN), + (0xAA, 0x00, 0x00, FG.RED, BG.RED), + (0xAA, 0x00, 0xAA, FG.MAGENTA, BG.MAGENTA), + (0xAA, 0xAA, 0x00, FG.YELLOW, BG.YELLOW), + (0x88, 0x88, 0x88, FG.GRAY, BG.GRAY), + (0x44, 0x44, 0xFF, FG.BLUE | FG.INTENSITY, BG.BLUE | BG.INTENSITY), + (0x44, 0xFF, 0x44, FG.GREEN | FG.INTENSITY, BG.GREEN | BG.INTENSITY), + (0x44, 0xFF, 0xFF, FG.CYAN | FG.INTENSITY, BG.CYAN | BG.INTENSITY), + (0xFF, 0x44, 0x44, FG.RED | FG.INTENSITY, BG.RED | BG.INTENSITY), + (0xFF, 0x44, 0xFF, FG.MAGENTA | FG.INTENSITY, BG.MAGENTA | BG.INTENSITY), + (0xFF, 0xFF, 0x44, FG.YELLOW | FG.INTENSITY, BG.YELLOW | BG.INTENSITY), + (0x44, 0x44, 0x44, FG.BLACK | FG.INTENSITY, BG.BLACK | BG.INTENSITY), + (0xFF, 0xFF, 0xFF, FG.GRAY | FG.INTENSITY, BG.GRAY | BG.INTENSITY), + ] + + def _closest_color(self, r: int, g: int, b: int) -> Tuple[int, int]: + distance = 257 * 257 * 3 # "infinity" (>distance from #000000 to #ffffff) + fg_match = 0 + bg_match = 0 + + for r_, g_, b_, fg_, bg_ in self._win32_colors: + rd = r - r_ + gd = g - g_ + bd = b - b_ + + d = rd * rd + gd * gd + bd * bd + + if d < distance: + fg_match = fg_ + bg_match = bg_ + distance = d + return fg_match, bg_match + + def _color_indexes(self, color: str) -> Tuple[int, int]: + indexes = self.best_match.get(color, None) + if indexes is None: + try: + rgb = int(str(color), 16) + except ValueError: + rgb = 0 + + r = (rgb >> 16) & 0xFF + g = (rgb >> 8) & 0xFF + b = rgb & 0xFF + indexes = self._closest_color(r, g, b) + self.best_match[color] = indexes + return indexes + + def lookup_fg_color(self, fg_color: str) -> int: + """ + Return the color for use in the + `windll.kernel32.SetConsoleTextAttribute` API call. + + :param fg_color: Foreground as text. E.g. 'ffffff' or 'red' + """ + # Foreground. + if fg_color in FG_ANSI_COLORS: + return FG_ANSI_COLORS[fg_color] + else: + return self._color_indexes(fg_color)[0] + + def lookup_bg_color(self, bg_color: str) -> int: + """ + Return the color for use in the + `windll.kernel32.SetConsoleTextAttribute` API call. + + :param bg_color: Background as text. E.g. 'ffffff' or 'red' + """ + # Background. + if bg_color in BG_ANSI_COLORS: + return BG_ANSI_COLORS[bg_color] + else: + return self._color_indexes(bg_color)[1] diff --git a/.venv/lib/python3.8/site-packages/prompt_toolkit/output/windows10.py b/.venv/lib/python3.8/site-packages/prompt_toolkit/output/windows10.py new file mode 100644 index 00000000..1a481a2e --- /dev/null +++ b/.venv/lib/python3.8/site-packages/prompt_toolkit/output/windows10.py @@ -0,0 +1,104 @@ +from ctypes import byref, windll +from ctypes.wintypes import DWORD, HANDLE +from typing import Any, Optional, TextIO + +from prompt_toolkit.data_structures import Size +from prompt_toolkit.renderer import Output +from prompt_toolkit.utils import is_windows +from prompt_toolkit.win32_types import STD_OUTPUT_HANDLE + +from .color_depth import ColorDepth +from .vt100 import Vt100_Output +from .win32 import Win32Output + +__all__ = [ + "Windows10_Output", +] + +# See: https://msdn.microsoft.com/pl-pl/library/windows/desktop/ms686033(v=vs.85).aspx +ENABLE_PROCESSED_INPUT = 0x0001 +ENABLE_VIRTUAL_TERMINAL_PROCESSING = 0x0004 + + +class Windows10_Output: + """ + Windows 10 output abstraction. This enables and uses vt100 escape sequences. + """ + + def __init__( + self, stdout: TextIO, default_color_depth: Optional[ColorDepth] = None + ) -> None: + self.win32_output = Win32Output(stdout, default_color_depth=default_color_depth) + self.vt100_output = Vt100_Output( + stdout, lambda: Size(0, 0), default_color_depth=default_color_depth + ) + self._hconsole = HANDLE(windll.kernel32.GetStdHandle(STD_OUTPUT_HANDLE)) + + def flush(self) -> None: + """ + Write to output stream and flush. + """ + original_mode = DWORD(0) + + # Remember the previous console mode. + windll.kernel32.GetConsoleMode(self._hconsole, byref(original_mode)) + + # Enable processing of vt100 sequences. + windll.kernel32.SetConsoleMode( + self._hconsole, + DWORD(ENABLE_PROCESSED_INPUT | ENABLE_VIRTUAL_TERMINAL_PROCESSING), + ) + + try: + self.vt100_output.flush() + finally: + # Restore console mode. + windll.kernel32.SetConsoleMode(self._hconsole, original_mode) + + @property + def responds_to_cpr(self) -> bool: + return False # We don't need this on Windows. + + def __getattr__(self, name: str) -> Any: + if name in ( + "get_size", + "get_rows_below_cursor_position", + "enable_mouse_support", + "disable_mouse_support", + "scroll_buffer_to_prompt", + "get_win32_screen_buffer_info", + "enable_bracketed_paste", + "disable_bracketed_paste", + "get_default_color_depth", + ): + return getattr(self.win32_output, name) + else: + return getattr(self.vt100_output, name) + + +Output.register(Windows10_Output) + + +def is_win_vt100_enabled() -> bool: + """ + Returns True when we're running Windows and VT100 escape sequences are + supported. + """ + if not is_windows(): + return False + + hconsole = HANDLE(windll.kernel32.GetStdHandle(STD_OUTPUT_HANDLE)) + + # Get original console mode. + original_mode = DWORD(0) + windll.kernel32.GetConsoleMode(hconsole, byref(original_mode)) + + try: + # Try to enable VT100 sequences. + result = windll.kernel32.SetConsoleMode( + hconsole, DWORD(ENABLE_PROCESSED_INPUT | ENABLE_VIRTUAL_TERMINAL_PROCESSING) + ) + + return result == 1 + finally: + windll.kernel32.SetConsoleMode(hconsole, original_mode) diff --git a/.venv/lib/python3.8/site-packages/prompt_toolkit/patch_stdout.py b/.venv/lib/python3.8/site-packages/prompt_toolkit/patch_stdout.py new file mode 100644 index 00000000..a2cb5a14 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/prompt_toolkit/patch_stdout.py @@ -0,0 +1,167 @@ +""" +patch_stdout +============ + +This implements a context manager that ensures that print statements within +it won't destroy the user interface. The context manager will replace +`sys.stdout` by something that draws the output above the current prompt, +rather than overwriting the UI. + +Usage:: + + with patch_stdout(application): + ... + application.run() + ... + +Multiple applications can run in the body of the context manager, one after the +other. +""" +import sys +import threading +from asyncio import get_event_loop +from contextlib import contextmanager +from typing import Generator, List, Optional, TextIO, cast + +from .application import run_in_terminal + +__all__ = [ + "patch_stdout", + "StdoutProxy", +] + + +@contextmanager +def patch_stdout(raw: bool = False) -> Generator[None, None, None]: + """ + Replace `sys.stdout` by an :class:`_StdoutProxy` instance. + + Writing to this proxy will make sure that the text appears above the + prompt, and that it doesn't destroy the output from the renderer. If no + application is curring, the behaviour should be identical to writing to + `sys.stdout` directly. + + Warning: If a new event loop is installed using `asyncio.set_event_loop()`, + then make sure that the context manager is applied after the event loop + is changed. Printing to stdout will be scheduled in the event loop + that's active when the context manager is created. + + :param raw: (`bool`) When True, vt100 terminal escape sequences are not + removed/escaped. + """ + proxy = cast(TextIO, StdoutProxy(raw=raw)) + + original_stdout = sys.stdout + original_stderr = sys.stderr + + # Enter. + sys.stdout = proxy + sys.stderr = proxy + + try: + yield + finally: + # Exit. + proxy.flush() + + sys.stdout = original_stdout + sys.stderr = original_stderr + + +class StdoutProxy: + """ + Proxy object for stdout which captures everything and prints output above + the current application. + """ + + def __init__( + self, raw: bool = False, original_stdout: Optional[TextIO] = None + ) -> None: + + original_stdout = original_stdout or sys.__stdout__ + + self.original_stdout = original_stdout + + self._lock = threading.RLock() + self._raw = raw + self._buffer: List[str] = [] + + # errors/encoding attribute for compatibility with sys.__stdout__. + self.errors = original_stdout.errors + self.encoding = original_stdout.encoding + + self.loop = get_event_loop() + + def _write_and_flush(self, text: str) -> None: + """ + Write the given text to stdout and flush. + If an application is running, use `run_in_terminal`. + """ + if not text: + # Don't bother calling `run_in_terminal` when there is nothing to + # display. + return + + def write_and_flush() -> None: + self.original_stdout.write(text) + self.original_stdout.flush() + + def write_and_flush_in_loop() -> None: + # If an application is running, use `run_in_terminal`, otherwise + # call it directly. + run_in_terminal.run_in_terminal(write_and_flush, in_executor=False) + + # Make sure `write_and_flush` is executed *in* the event loop, not in + # another thread. + self.loop.call_soon_threadsafe(write_and_flush_in_loop) + + def _write(self, data: str) -> None: + """ + Note: print()-statements cause to multiple write calls. + (write('line') and write('\n')). Of course we don't want to call + `run_in_terminal` for every individual call, because that's too + expensive, and as long as the newline hasn't been written, the + text itself is again overwritten by the rendering of the input + command line. Therefor, we have a little buffer which holds the + text until a newline is written to stdout. + """ + if "\n" in data: + # When there is a newline in the data, write everything before the + # newline, including the newline itself. + before, after = data.rsplit("\n", 1) + to_write = self._buffer + [before, "\n"] + self._buffer = [after] + + text = "".join(to_write) + self._write_and_flush(text) + else: + # Otherwise, cache in buffer. + self._buffer.append(data) + + def _flush(self) -> None: + text = "".join(self._buffer) + self._buffer = [] + self._write_and_flush(text) + + def write(self, data: str) -> int: + with self._lock: + self._write(data) + + return len(data) # Pretend everything was written. + + def flush(self) -> None: + """ + Flush buffered output. + """ + with self._lock: + self._flush() + + def fileno(self) -> int: + """ + Return file descriptor. + """ + # This is important for code that expects sys.stdout.fileno() to work. + return self.original_stdout.fileno() + + def isatty(self) -> bool: + return self.original_stdout.isatty() diff --git a/.venv/lib/python3.8/site-packages/prompt_toolkit/py.typed b/.venv/lib/python3.8/site-packages/prompt_toolkit/py.typed new file mode 100644 index 00000000..e69de29b diff --git a/.venv/lib/python3.8/site-packages/prompt_toolkit/renderer.py b/.venv/lib/python3.8/site-packages/prompt_toolkit/renderer.py new file mode 100644 index 00000000..b6000a11 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/prompt_toolkit/renderer.py @@ -0,0 +1,783 @@ +""" +Renders the command line on the console. +(Redraws parts of the input line that were changed.) +""" +from asyncio import FIRST_COMPLETED, Future, sleep, wait +from collections import deque +from enum import Enum +from typing import TYPE_CHECKING, Any, Callable, Deque, Dict, Hashable, Optional, Tuple + +from prompt_toolkit.application.current import get_app +from prompt_toolkit.data_structures import Point, Size +from prompt_toolkit.filters import FilterOrBool, to_filter +from prompt_toolkit.formatted_text import AnyFormattedText, to_formatted_text +from prompt_toolkit.layout.mouse_handlers import MouseHandlers +from prompt_toolkit.layout.screen import Char, Screen, WritePosition +from prompt_toolkit.output import ColorDepth, Output +from prompt_toolkit.styles import ( + Attrs, + BaseStyle, + DummyStyleTransformation, + StyleTransformation, +) + +if TYPE_CHECKING: + from prompt_toolkit.application import Application + from prompt_toolkit.layout.layout import Layout + + +__all__ = [ + "Renderer", + "print_formatted_text", +] + + +def _output_screen_diff( + app: "Application[Any]", + output: Output, + screen: Screen, + current_pos: Point, + color_depth: ColorDepth, + previous_screen: Optional[Screen], + last_style: Optional[str], + is_done: bool, # XXX: drop is_done + full_screen: bool, + attrs_for_style_string: "_StyleStringToAttrsCache", + style_string_has_style: "_StyleStringHasStyleCache", + size: Size, + previous_width: int, +) -> Tuple[Point, Optional[str]]: + """ + Render the diff between this screen and the previous screen. + + This takes two `Screen` instances. The one that represents the output like + it was during the last rendering and one that represents the current + output raster. Looking at these two `Screen` instances, this function will + render the difference by calling the appropriate methods of the `Output` + object that only paint the changes to the terminal. + + This is some performance-critical code which is heavily optimized. + Don't change things without profiling first. + + :param current_pos: Current cursor position. + :param last_style: The style string, used for drawing the last drawn + character. (Color/attributes.) + :param attrs_for_style_string: :class:`._StyleStringToAttrsCache` instance. + :param width: The width of the terminal. + :param previous_width: The width of the terminal during the last rendering. + """ + width, height = size.columns, size.rows + + #: Variable for capturing the output. + write = output.write + write_raw = output.write_raw + + # Create locals for the most used output methods. + # (Save expensive attribute lookups.) + _output_set_attributes = output.set_attributes + _output_reset_attributes = output.reset_attributes + _output_cursor_forward = output.cursor_forward + _output_cursor_up = output.cursor_up + _output_cursor_backward = output.cursor_backward + + # Hide cursor before rendering. (Avoid flickering.) + output.hide_cursor() + + def reset_attributes() -> None: + " Wrapper around Output.reset_attributes. " + nonlocal last_style + _output_reset_attributes() + last_style = None # Forget last char after resetting attributes. + + def move_cursor(new: Point) -> Point: + " Move cursor to this `new` point. Returns the given Point. " + current_x, current_y = current_pos.x, current_pos.y + + if new.y > current_y: + # Use newlines instead of CURSOR_DOWN, because this might add new lines. + # CURSOR_DOWN will never create new lines at the bottom. + # Also reset attributes, otherwise the newline could draw a + # background color. + reset_attributes() + write("\r\n" * (new.y - current_y)) + current_x = 0 + _output_cursor_forward(new.x) + return new + elif new.y < current_y: + _output_cursor_up(current_y - new.y) + + if current_x >= width - 1: + write("\r") + _output_cursor_forward(new.x) + elif new.x < current_x or current_x >= width - 1: + _output_cursor_backward(current_x - new.x) + elif new.x > current_x: + _output_cursor_forward(new.x - current_x) + + return new + + def output_char(char: Char) -> None: + """ + Write the output of this character. + """ + nonlocal last_style + + # If the last printed character has the same style, don't output the + # style again. + if last_style == char.style: + write(char.char) + else: + # Look up `Attr` for this style string. Only set attributes if different. + # (Two style strings can still have the same formatting.) + # Note that an empty style string can have formatting that needs to + # be applied, because of style transformations. + new_attrs = attrs_for_style_string[char.style] + if not last_style or new_attrs != attrs_for_style_string[last_style]: + _output_set_attributes(new_attrs, color_depth) + + write(char.char) + last_style = char.style + + def get_max_column_index(row: Dict[int, Char]) -> int: + """ + Return max used column index, ignoring whitespace (without style) at + the end of the line. This is important for people that copy/paste + terminal output. + + There are two reasons we are sometimes seeing whitespace at the end: + - `BufferControl` adds a trailing space to each line, because it's a + possible cursor position, so that the line wrapping won't change if + the cursor position moves around. + - The `Window` adds a style class to the current line for highlighting + (cursor-line). + """ + numbers = [ + index + for index, cell in row.items() + if cell.char != " " or style_string_has_style[cell.style] + ] + numbers.append(0) + return max(numbers) + + # Render for the first time: reset styling. + if not previous_screen: + reset_attributes() + + # Disable autowrap. (When entering a the alternate screen, or anytime when + # we have a prompt. - In the case of a REPL, like IPython, people can have + # background threads, and it's hard for debugging if their output is not + # wrapped.) + if not previous_screen or not full_screen: + output.disable_autowrap() + + # When the previous screen has a different size, redraw everything anyway. + # Also when we are done. (We might take up less rows, so clearing is important.) + if ( + is_done or not previous_screen or previous_width != width + ): # XXX: also consider height?? + current_pos = move_cursor(Point(x=0, y=0)) + reset_attributes() + output.erase_down() + + previous_screen = Screen() + + # Get height of the screen. + # (height changes as we loop over data_buffer, so remember the current value.) + # (Also make sure to clip the height to the size of the output.) + current_height = min(screen.height, height) + + # Loop over the rows. + row_count = min(max(screen.height, previous_screen.height), height) + c = 0 # Column counter. + + for y in range(row_count): + new_row = screen.data_buffer[y] + previous_row = previous_screen.data_buffer[y] + zero_width_escapes_row = screen.zero_width_escapes[y] + + new_max_line_len = min(width - 1, get_max_column_index(new_row)) + previous_max_line_len = min(width - 1, get_max_column_index(previous_row)) + + # Loop over the columns. + c = 0 + while c <= new_max_line_len: + new_char = new_row[c] + old_char = previous_row[c] + char_width = new_char.width or 1 + + # When the old and new character at this position are different, + # draw the output. (Because of the performance, we don't call + # `Char.__ne__`, but inline the same expression.) + if new_char.char != old_char.char or new_char.style != old_char.style: + current_pos = move_cursor(Point(x=c, y=y)) + + # Send injected escape sequences to output. + if c in zero_width_escapes_row: + write_raw(zero_width_escapes_row[c]) + + output_char(new_char) + current_pos = Point(x=current_pos.x + char_width, y=current_pos.y) + + c += char_width + + # If the new line is shorter, trim it. + if previous_screen and new_max_line_len < previous_max_line_len: + current_pos = move_cursor(Point(x=new_max_line_len + 1, y=y)) + reset_attributes() + output.erase_end_of_line() + + # Correctly reserve vertical space as required by the layout. + # When this is a new screen (drawn for the first time), or for some reason + # higher than the previous one. Move the cursor once to the bottom of the + # output. That way, we're sure that the terminal scrolls up, even when the + # lower lines of the canvas just contain whitespace. + + # The most obvious reason that we actually want this behaviour is the avoid + # the artifact of the input scrolling when the completion menu is shown. + # (If the scrolling is actually wanted, the layout can still be build in a + # way to behave that way by setting a dynamic height.) + if current_height > previous_screen.height: + current_pos = move_cursor(Point(x=0, y=current_height - 1)) + + # Move cursor: + if is_done: + current_pos = move_cursor(Point(x=0, y=current_height)) + output.erase_down() + else: + current_pos = move_cursor(screen.get_cursor_position(app.layout.current_window)) + + if is_done or not full_screen: + output.enable_autowrap() + + # Always reset the color attributes. This is important because a background + # thread could print data to stdout and we want that to be displayed in the + # default colors. (Also, if a background color has been set, many terminals + # give weird artifacts on resize events.) + reset_attributes() + + if screen.show_cursor or is_done: + output.show_cursor() + + return current_pos, last_style + + +class HeightIsUnknownError(Exception): + " Information unavailable. Did not yet receive the CPR response. " + + +class _StyleStringToAttrsCache(Dict[str, Attrs]): + """ + A cache structure that maps style strings to :class:`.Attr`. + (This is an important speed up.) + """ + + def __init__( + self, + get_attrs_for_style_str: Callable[["str"], Attrs], + style_transformation: StyleTransformation, + ) -> None: + + self.get_attrs_for_style_str = get_attrs_for_style_str + self.style_transformation = style_transformation + + def __missing__(self, style_str: str) -> Attrs: + attrs = self.get_attrs_for_style_str(style_str) + attrs = self.style_transformation.transform_attrs(attrs) + + self[style_str] = attrs + return attrs + + +class _StyleStringHasStyleCache(Dict[str, bool]): + """ + Cache for remember which style strings don't render the default output + style (default fg/bg, no underline and no reverse and no blink). That way + we know that we should render these cells, even when they're empty (when + they contain a space). + + Note: we don't consider bold/italic/hidden because they don't change the + output if there's no text in the cell. + """ + + def __init__(self, style_string_to_attrs: Dict[str, Attrs]) -> None: + self.style_string_to_attrs = style_string_to_attrs + + def __missing__(self, style_str: str) -> bool: + attrs = self.style_string_to_attrs[style_str] + is_default = bool( + attrs.color + or attrs.bgcolor + or attrs.underline + or attrs.blink + or attrs.reverse + ) + + self[style_str] = is_default + return is_default + + +class CPR_Support(Enum): + " Enum: whether or not CPR is supported. " + SUPPORTED = "SUPPORTED" + NOT_SUPPORTED = "NOT_SUPPORTED" + UNKNOWN = "UNKNOWN" + + +class Renderer: + """ + Typical usage: + + :: + + output = Vt100_Output.from_pty(sys.stdout) + r = Renderer(style, output) + r.render(app, layout=...) + """ + + CPR_TIMEOUT = 2 # Time to wait until we consider CPR to be not supported. + + def __init__( + self, + style: BaseStyle, + output: Output, + full_screen: bool = False, + mouse_support: FilterOrBool = False, + cpr_not_supported_callback: Optional[Callable[[], None]] = None, + ) -> None: + + self.style = style + self.output = output + self.full_screen = full_screen + self.mouse_support = to_filter(mouse_support) + self.cpr_not_supported_callback = cpr_not_supported_callback + + self._in_alternate_screen = False + self._mouse_support_enabled = False + self._bracketed_paste_enabled = False + + # Future set when we are waiting for a CPR flag. + self._waiting_for_cpr_futures: Deque[Future[None]] = deque() + self.cpr_support = CPR_Support.UNKNOWN + + if not output.responds_to_cpr: + self.cpr_support = CPR_Support.NOT_SUPPORTED + + # Cache for the style. + self._attrs_for_style: Optional[_StyleStringToAttrsCache] = None + self._style_string_has_style: Optional[_StyleStringHasStyleCache] = None + self._last_style_hash: Optional[Hashable] = None + self._last_transformation_hash: Optional[Hashable] = None + self._last_color_depth: Optional[ColorDepth] = None + + self.reset(_scroll=True) + + def reset(self, _scroll: bool = False, leave_alternate_screen: bool = True) -> None: + + # Reset position + self._cursor_pos = Point(x=0, y=0) + + # Remember the last screen instance between renderers. This way, + # we can create a `diff` between two screens and only output the + # difference. It's also to remember the last height. (To show for + # instance a toolbar at the bottom position.) + self._last_screen: Optional[Screen] = None + self._last_size: Optional[Size] = None + self._last_style: Optional[str] = None + + # Default MouseHandlers. (Just empty.) + self.mouse_handlers = MouseHandlers() + + #: Space from the top of the layout, until the bottom of the terminal. + #: We don't know this until a `report_absolute_cursor_row` call. + self._min_available_height = 0 + + # In case of Windows, also make sure to scroll to the current cursor + # position. (Only when rendering the first time.) + # It does nothing for vt100 terminals. + if _scroll: + self.output.scroll_buffer_to_prompt() + + # Quit alternate screen. + if self._in_alternate_screen and leave_alternate_screen: + self.output.quit_alternate_screen() + self._in_alternate_screen = False + + # Disable mouse support. + if self._mouse_support_enabled: + self.output.disable_mouse_support() + self._mouse_support_enabled = False + + # Disable bracketed paste. + if self._bracketed_paste_enabled: + self.output.disable_bracketed_paste() + self._bracketed_paste_enabled = False + + # Flush output. `disable_mouse_support` needs to write to stdout. + self.output.flush() + + @property + def last_rendered_screen(self) -> Optional[Screen]: + """ + The `Screen` class that was generated during the last rendering. + This can be `None`. + """ + return self._last_screen + + @property + def height_is_known(self) -> bool: + """ + True when the height from the cursor until the bottom of the terminal + is known. (It's often nicer to draw bottom toolbars only if the height + is known, in order to avoid flickering when the CPR response arrives.) + """ + if self.full_screen or self._min_available_height > 0: + return True + try: + self._min_available_height = self.output.get_rows_below_cursor_position() + return True + except NotImplementedError: + return False + + @property + def rows_above_layout(self) -> int: + """ + Return the number of rows visible in the terminal above the layout. + """ + if self._in_alternate_screen: + return 0 + elif self._min_available_height > 0: + total_rows = self.output.get_size().rows + last_screen_height = self._last_screen.height if self._last_screen else 0 + return total_rows - max(self._min_available_height, last_screen_height) + else: + raise HeightIsUnknownError("Rows above layout is unknown.") + + def request_absolute_cursor_position(self) -> None: + """ + Get current cursor position. + + We do this to calculate the minimum available height that we can + consume for rendering the prompt. This is the available space below te + cursor. + + For vt100: Do CPR request. (answer will arrive later.) + For win32: Do API call. (Answer comes immediately.) + """ + # Only do this request when the cursor is at the top row. (after a + # clear or reset). We will rely on that in `report_absolute_cursor_row`. + assert self._cursor_pos.y == 0 + + # In full-screen mode, always use the total height as min-available-height. + if self.full_screen: + self._min_available_height = self.output.get_size().rows + return + + # For Win32, we have an API call to get the number of rows below the + # cursor. + try: + self._min_available_height = self.output.get_rows_below_cursor_position() + return + except NotImplementedError: + pass + + # Use CPR. + if self.cpr_support == CPR_Support.NOT_SUPPORTED: + return + + def do_cpr() -> None: + # Asks for a cursor position report (CPR). + self._waiting_for_cpr_futures.append(Future()) + self.output.ask_for_cpr() + + if self.cpr_support == CPR_Support.SUPPORTED: + do_cpr() + return + + # If we don't know whether CPR is supported, only do a request if + # none is pending, and test it, using a timer. + if self.waiting_for_cpr: + return + + do_cpr() + + async def timer() -> None: + await sleep(self.CPR_TIMEOUT) + + # Not set in the meantime -> not supported. + if self.cpr_support == CPR_Support.UNKNOWN: + self.cpr_support = CPR_Support.NOT_SUPPORTED + + if self.cpr_not_supported_callback: + # Make sure to call this callback in the main thread. + self.cpr_not_supported_callback() + + get_app().create_background_task(timer()) + + def report_absolute_cursor_row(self, row: int) -> None: + """ + To be called when we know the absolute cursor position. + (As an answer of a "Cursor Position Request" response.) + """ + self.cpr_support = CPR_Support.SUPPORTED + + # Calculate the amount of rows from the cursor position until the + # bottom of the terminal. + total_rows = self.output.get_size().rows + rows_below_cursor = total_rows - row + 1 + + # Set the minimum available height. + self._min_available_height = rows_below_cursor + + # Pop and set waiting for CPR future. + try: + f = self._waiting_for_cpr_futures.popleft() + except IndexError: + pass # Received CPR response without having a CPR. + else: + f.set_result(None) + + @property + def waiting_for_cpr(self) -> bool: + """ + Waiting for CPR flag. True when we send the request, but didn't got a + response. + """ + return bool(self._waiting_for_cpr_futures) + + async def wait_for_cpr_responses(self, timeout: int = 1) -> None: + """ + Wait for a CPR response. + """ + cpr_futures = list(self._waiting_for_cpr_futures) # Make copy. + + # When there are no CPRs in the queue. Don't do anything. + if not cpr_futures or self.cpr_support == CPR_Support.NOT_SUPPORTED: + return None + + async def wait_for_responses() -> None: + for response_f in cpr_futures: + await response_f + + async def wait_for_timeout() -> None: + await sleep(timeout) + + # Got timeout, erase queue. + for response_f in cpr_futures: + response_f.cancel() + self._waiting_for_cpr_futures = deque() + + coroutines = [ + wait_for_responses(), + wait_for_timeout(), + ] + _, pending = await wait(coroutines, return_when=FIRST_COMPLETED) + for task in pending: + task.cancel() + + def render( + self, app: "Application[Any]", layout: "Layout", is_done: bool = False + ) -> None: + """ + Render the current interface to the output. + + :param is_done: When True, put the cursor at the end of the interface. We + won't print any changes to this part. + """ + output = self.output + + # Enter alternate screen. + if self.full_screen and not self._in_alternate_screen: + self._in_alternate_screen = True + output.enter_alternate_screen() + + # Enable bracketed paste. + if not self._bracketed_paste_enabled: + self.output.enable_bracketed_paste() + self._bracketed_paste_enabled = True + + # Enable/disable mouse support. + needs_mouse_support = self.mouse_support() + + if needs_mouse_support and not self._mouse_support_enabled: + output.enable_mouse_support() + self._mouse_support_enabled = True + + elif not needs_mouse_support and self._mouse_support_enabled: + output.disable_mouse_support() + self._mouse_support_enabled = False + + # Create screen and write layout to it. + size = output.get_size() + screen = Screen() + screen.show_cursor = False # Hide cursor by default, unless one of the + # containers decides to display it. + mouse_handlers = MouseHandlers() + + # Calculate height. + if self.full_screen: + height = size.rows + elif is_done: + # When we are done, we don't necessary want to fill up until the bottom. + height = layout.container.preferred_height( + size.columns, size.rows + ).preferred + else: + last_height = self._last_screen.height if self._last_screen else 0 + height = max( + self._min_available_height, + last_height, + layout.container.preferred_height(size.columns, size.rows).preferred, + ) + + height = min(height, size.rows) + + # When te size changes, don't consider the previous screen. + if self._last_size != size: + self._last_screen = None + + # When we render using another style or another color depth, do a full + # repaint. (Forget about the previous rendered screen.) + # (But note that we still use _last_screen to calculate the height.) + if ( + self.style.invalidation_hash() != self._last_style_hash + or app.style_transformation.invalidation_hash() + != self._last_transformation_hash + or app.color_depth != self._last_color_depth + ): + self._last_screen = None + self._attrs_for_style = None + self._style_string_has_style = None + + if self._attrs_for_style is None: + self._attrs_for_style = _StyleStringToAttrsCache( + self.style.get_attrs_for_style_str, app.style_transformation + ) + if self._style_string_has_style is None: + self._style_string_has_style = _StyleStringHasStyleCache( + self._attrs_for_style + ) + + self._last_style_hash = self.style.invalidation_hash() + self._last_transformation_hash = app.style_transformation.invalidation_hash() + self._last_color_depth = app.color_depth + + layout.container.write_to_screen( + screen, + mouse_handlers, + WritePosition(xpos=0, ypos=0, width=size.columns, height=height), + parent_style="", + erase_bg=False, + z_index=None, + ) + screen.draw_all_floats() + + # When grayed. Replace all styles in the new screen. + if app.exit_style: + screen.append_style_to_content(app.exit_style) + + # Process diff and write to output. + self._cursor_pos, self._last_style = _output_screen_diff( + app, + output, + screen, + self._cursor_pos, + app.color_depth, + self._last_screen, + self._last_style, + is_done, + full_screen=self.full_screen, + attrs_for_style_string=self._attrs_for_style, + style_string_has_style=self._style_string_has_style, + size=size, + previous_width=(self._last_size.columns if self._last_size else 0), + ) + self._last_screen = screen + self._last_size = size + self.mouse_handlers = mouse_handlers + + output.flush() + + # Set visible windows in layout. + app.layout.visible_windows = screen.visible_windows + + if is_done: + self.reset() + + def erase(self, leave_alternate_screen: bool = True) -> None: + """ + Hide all output and put the cursor back at the first line. This is for + instance used for running a system command (while hiding the CLI) and + later resuming the same CLI.) + + :param leave_alternate_screen: When True, and when inside an alternate + screen buffer, quit the alternate screen. + """ + output = self.output + + output.cursor_backward(self._cursor_pos.x) + output.cursor_up(self._cursor_pos.y) + output.erase_down() + output.reset_attributes() + output.enable_autowrap() + output.flush() + + self.reset(leave_alternate_screen=leave_alternate_screen) + + def clear(self) -> None: + """ + Clear screen and go to 0,0 + """ + # Erase current output first. + self.erase() + + # Send "Erase Screen" command and go to (0, 0). + output = self.output + + output.erase_screen() + output.cursor_goto(0, 0) + output.flush() + + self.request_absolute_cursor_position() + + +def print_formatted_text( + output: Output, + formatted_text: AnyFormattedText, + style: BaseStyle, + style_transformation: Optional[StyleTransformation] = None, + color_depth: Optional[ColorDepth] = None, +) -> None: + """ + Print a list of (style_str, text) tuples in the given style to the output. + """ + fragments = to_formatted_text(formatted_text) + style_transformation = style_transformation or DummyStyleTransformation() + color_depth = color_depth or output.get_default_color_depth() + + # Reset first. + output.reset_attributes() + output.enable_autowrap() + + # Print all (style_str, text) tuples. + attrs_for_style_string = _StyleStringToAttrsCache( + style.get_attrs_for_style_str, style_transformation + ) + + for style_str, text, *_ in fragments: + attrs = attrs_for_style_string[style_str] + + if attrs: + output.set_attributes(attrs, color_depth) + else: + output.reset_attributes() + + # Eliminate carriage returns + text = text.replace("\r", "") + + # Assume that the output is raw, and insert a carriage return before + # every newline. (Also important when the front-end is a telnet client.) + output.write(text.replace("\n", "\r\n")) + + # Reset again. + output.reset_attributes() + output.flush() diff --git a/.venv/lib/python3.8/site-packages/prompt_toolkit/search.py b/.venv/lib/python3.8/site-packages/prompt_toolkit/search.py new file mode 100644 index 00000000..6f94afe9 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/prompt_toolkit/search.py @@ -0,0 +1,229 @@ +""" +Search operations. + +For the key bindings implementation with attached filters, check +`prompt_toolkit.key_binding.bindings.search`. (Use these for new key bindings +instead of calling these function directly.) +""" +from enum import Enum +from typing import TYPE_CHECKING, Dict, Optional + +from .application.current import get_app +from .filters import FilterOrBool, is_searching, to_filter +from .key_binding.vi_state import InputMode + +if TYPE_CHECKING: + from prompt_toolkit.layout.controls import BufferControl, SearchBufferControl + from prompt_toolkit.layout.layout import Layout + +__all__ = [ + "SearchDirection", + "start_search", + "stop_search", +] + + +class SearchDirection(Enum): + FORWARD = "FORWARD" + BACKWARD = "BACKWARD" + + +class SearchState: + """ + A search 'query', associated with a search field (like a SearchToolbar). + + Every searchable `BufferControl` points to a `search_buffer_control` + (another `BufferControls`) which represents the search field. The + `SearchState` attached to that search field is used for storing the current + search query. + + It is possible to have one searchfield for multiple `BufferControls`. In + that case, they'll share the same `SearchState`. + If there are multiple `BufferControls` that display the same `Buffer`, then + they can have a different `SearchState` each (if they have a different + search control). + """ + + __slots__ = ("text", "direction", "ignore_case") + + def __init__( + self, + text: str = "", + direction: SearchDirection = SearchDirection.FORWARD, + ignore_case: FilterOrBool = False, + ) -> None: + + self.text = text + self.direction = direction + self.ignore_case = to_filter(ignore_case) + + def __repr__(self) -> str: + return "%s(%r, direction=%r, ignore_case=%r)" % ( + self.__class__.__name__, + self.text, + self.direction, + self.ignore_case, + ) + + def __invert__(self) -> "SearchState": + """ + Create a new SearchState where backwards becomes forwards and the other + way around. + """ + if self.direction == SearchDirection.BACKWARD: + direction = SearchDirection.FORWARD + else: + direction = SearchDirection.BACKWARD + + return SearchState( + text=self.text, direction=direction, ignore_case=self.ignore_case + ) + + +def start_search( + buffer_control: Optional["BufferControl"] = None, + direction: SearchDirection = SearchDirection.FORWARD, +) -> None: + """ + Start search through the given `buffer_control` using the + `search_buffer_control`. + + :param buffer_control: Start search for this `BufferControl`. If not given, + search through the current control. + """ + from prompt_toolkit.layout.controls import BufferControl + + assert buffer_control is None or isinstance(buffer_control, BufferControl) + + layout = get_app().layout + + # When no control is given, use the current control if that's a BufferControl. + if buffer_control is None: + if not isinstance(layout.current_control, BufferControl): + return + buffer_control = layout.current_control + + # Only if this control is searchable. + search_buffer_control = buffer_control.search_buffer_control + + if search_buffer_control: + buffer_control.search_state.direction = direction + + # Make sure to focus the search BufferControl + layout.focus(search_buffer_control) + + # Remember search link. + layout.search_links[search_buffer_control] = buffer_control + + # If we're in Vi mode, make sure to go into insert mode. + get_app().vi_state.input_mode = InputMode.INSERT + + +def stop_search(buffer_control: Optional["BufferControl"] = None) -> None: + """ + Stop search through the given `buffer_control`. + """ + layout = get_app().layout + + if buffer_control is None: + buffer_control = layout.search_target_buffer_control + if buffer_control is None: + # (Should not happen, but possible when `stop_search` is called + # when we're not searching.) + return + search_buffer_control = buffer_control.search_buffer_control + else: + assert buffer_control in layout.search_links.values() + search_buffer_control = _get_reverse_search_links(layout)[buffer_control] + + # Focus the original buffer again. + layout.focus(buffer_control) + + if search_buffer_control is not None: + # Remove the search link. + del layout.search_links[search_buffer_control] + + # Reset content of search control. + search_buffer_control.buffer.reset() + + # If we're in Vi mode, go back to navigation mode. + get_app().vi_state.input_mode = InputMode.NAVIGATION + + +def do_incremental_search(direction: SearchDirection, count: int = 1) -> None: + """ + Apply search, but keep search buffer focused. + """ + assert is_searching() + + layout = get_app().layout + + # Only search if the current control is a `BufferControl`. + from prompt_toolkit.layout.controls import BufferControl + + search_control = layout.current_control + if not isinstance(search_control, BufferControl): + return + + prev_control = layout.search_target_buffer_control + if prev_control is None: + return + search_state = prev_control.search_state + + # Update search_state. + direction_changed = search_state.direction != direction + + search_state.text = search_control.buffer.text + search_state.direction = direction + + # Apply search to current buffer. + if not direction_changed: + prev_control.buffer.apply_search( + search_state, include_current_position=False, count=count + ) + + +def accept_search() -> None: + """ + Accept current search query. Focus original `BufferControl` again. + """ + layout = get_app().layout + + search_control = layout.current_control + target_buffer_control = layout.search_target_buffer_control + + from prompt_toolkit.layout.controls import BufferControl + + if not isinstance(search_control, BufferControl): + return + if target_buffer_control is None: + return + + search_state = target_buffer_control.search_state + + # Update search state. + if search_control.buffer.text: + search_state.text = search_control.buffer.text + + # Apply search. + target_buffer_control.buffer.apply_search( + search_state, include_current_position=True + ) + + # Add query to history of search line. + search_control.buffer.append_to_history() + + # Stop search and focus previous control again. + stop_search(target_buffer_control) + + +def _get_reverse_search_links( + layout: "Layout", +) -> Dict["BufferControl", "SearchBufferControl"]: + """ + Return mapping from BufferControl to SearchBufferControl. + """ + return { + buffer_control: search_buffer_control + for search_buffer_control, buffer_control in layout.search_links.items() + } diff --git a/.venv/lib/python3.8/site-packages/prompt_toolkit/selection.py b/.venv/lib/python3.8/site-packages/prompt_toolkit/selection.py new file mode 100644 index 00000000..5d2545bd --- /dev/null +++ b/.venv/lib/python3.8/site-packages/prompt_toolkit/selection.py @@ -0,0 +1,60 @@ +""" +Data structures for the selection. +""" +from enum import Enum + +__all__ = [ + "SelectionType", + "PasteMode", + "SelectionState", +] + + +class SelectionType(Enum): + """ + Type of selection. + """ + + #: Characters. (Visual in Vi.) + CHARACTERS = "CHARACTERS" + + #: Whole lines. (Visual-Line in Vi.) + LINES = "LINES" + + #: A block selection. (Visual-Block in Vi.) + BLOCK = "BLOCK" + + +class PasteMode(Enum): + EMACS = "EMACS" # Yank like emacs. + VI_AFTER = "VI_AFTER" # When pressing 'p' in Vi. + VI_BEFORE = "VI_BEFORE" # When pressing 'P' in Vi. + + +class SelectionState: + """ + State of the current selection. + + :param original_cursor_position: int + :param type: :class:`~.SelectionType` + """ + + def __init__( + self, + original_cursor_position: int = 0, + type: SelectionType = SelectionType.CHARACTERS, + ) -> None: + + self.original_cursor_position = original_cursor_position + self.type = type + self.shift_mode = False + + def enter_shift_mode(self) -> None: + self.shift_mode = True + + def __repr__(self) -> str: + return "%s(original_cursor_position=%r, type=%r)" % ( + self.__class__.__name__, + self.original_cursor_position, + self.type, + ) diff --git a/.venv/lib/python3.8/site-packages/prompt_toolkit/shortcuts/__init__.py b/.venv/lib/python3.8/site-packages/prompt_toolkit/shortcuts/__init__.py new file mode 100644 index 00000000..10ad3148 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/prompt_toolkit/shortcuts/__init__.py @@ -0,0 +1,44 @@ +from .dialogs import ( + button_dialog, + checkboxlist_dialog, + input_dialog, + message_dialog, + progress_dialog, + radiolist_dialog, + yes_no_dialog, +) +from .progress_bar import ProgressBar, ProgressBarCounter +from .prompt import ( + CompleteStyle, + PromptSession, + confirm, + create_confirm_session, + prompt, +) +from .utils import clear, clear_title, print_container, print_formatted_text, set_title + +__all__ = [ + # Dialogs. + "input_dialog", + "message_dialog", + "progress_dialog", + "checkboxlist_dialog", + "radiolist_dialog", + "yes_no_dialog", + "button_dialog", + # Prompts. + "PromptSession", + "prompt", + "confirm", + "create_confirm_session", + "CompleteStyle", + # Progress bars. + "ProgressBar", + "ProgressBarCounter", + # Utils. + "clear", + "clear_title", + "print_container", + "print_formatted_text", + "set_title", +] diff --git a/.venv/lib/python3.8/site-packages/prompt_toolkit/shortcuts/__pycache__/__init__.cpython-38.pyc b/.venv/lib/python3.8/site-packages/prompt_toolkit/shortcuts/__pycache__/__init__.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..db7c2182facbc6bf640396ee2ed275009e2a6420 GIT binary patch literal 885 zcmZ{i&5qMB5XY0WY1*dgce{(UM=m|=R$7Sz5<-X-SAa^IKPE}nv*Y)dAM|U(^L{$xd`ztI#=hk@3-G`f z9{R+`fCShe4Q!Goh9txmX<vnKIM8<6bIEwPrvyd(@^= zGQHoSnzmgkbZ9x)v-ecw&~^wMdJY4J#G&sHJ9He}y-`Dlk;B-*-4->qc)z$H(f$a^ zeX?5MAJLPZ>Dj;A_k5kIv;4Jstyvdys>6hp=A!(szKJMJg`o7ir!HMl4!_(5)p#P!P;RBu1sZkPKeQ!S-<;CfkZrP5iY%O#~e=bF-+VrSZ~P(mfx cYj@?!8;j?ip??)!H3R?b2~Kl2`)fV@0m9MeegFUf literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/prompt_toolkit/shortcuts/__pycache__/dialogs.cpython-38.pyc b/.venv/lib/python3.8/site-packages/prompt_toolkit/shortcuts/__pycache__/dialogs.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..36accea6718ec51fe22868009fae5cac3f3fbdd0 GIT binary patch literal 8650 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 J*|BP){2!d~_<{fc literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/prompt_toolkit/shortcuts/dialogs.py b/.venv/lib/python3.8/site-packages/prompt_toolkit/shortcuts/dialogs.py new file mode 100644 index 00000000..06b8eb6f --- /dev/null +++ b/.venv/lib/python3.8/site-packages/prompt_toolkit/shortcuts/dialogs.py @@ -0,0 +1,324 @@ +import functools +from asyncio import get_event_loop +from typing import Any, Callable, List, Optional, Tuple, TypeVar + +from prompt_toolkit.application import Application +from prompt_toolkit.application.current import get_app +from prompt_toolkit.buffer import Buffer +from prompt_toolkit.completion import Completer +from prompt_toolkit.eventloop import run_in_executor_with_context +from prompt_toolkit.filters import FilterOrBool +from prompt_toolkit.formatted_text import AnyFormattedText +from prompt_toolkit.key_binding.bindings.focus import focus_next, focus_previous +from prompt_toolkit.key_binding.defaults import load_key_bindings +from prompt_toolkit.key_binding.key_bindings import KeyBindings, merge_key_bindings +from prompt_toolkit.layout import Layout +from prompt_toolkit.layout.containers import AnyContainer, HSplit +from prompt_toolkit.layout.dimension import Dimension as D +from prompt_toolkit.styles import BaseStyle +from prompt_toolkit.validation import Validator +from prompt_toolkit.widgets import ( + Box, + Button, + CheckboxList, + Dialog, + Label, + ProgressBar, + RadioList, + TextArea, + ValidationToolbar, +) + +__all__ = [ + "yes_no_dialog", + "button_dialog", + "input_dialog", + "message_dialog", + "radiolist_dialog", + "checkboxlist_dialog", + "progress_dialog", +] + + +def yes_no_dialog( + title: AnyFormattedText = "", + text: AnyFormattedText = "", + yes_text: str = "Yes", + no_text: str = "No", + style: Optional[BaseStyle] = None, +) -> Application[bool]: + """ + Display a Yes/No dialog. + Return a boolean. + """ + + def yes_handler() -> None: + get_app().exit(result=True) + + def no_handler() -> None: + get_app().exit(result=False) + + dialog = Dialog( + title=title, + body=Label(text=text, dont_extend_height=True), + buttons=[ + Button(text=yes_text, handler=yes_handler), + Button(text=no_text, handler=no_handler), + ], + with_background=True, + ) + + return _create_app(dialog, style) + + +_T = TypeVar("_T") + + +def button_dialog( + title: AnyFormattedText = "", + text: AnyFormattedText = "", + buttons: List[Tuple[str, _T]] = [], + style: Optional[BaseStyle] = None, +) -> Application[_T]: + """ + Display a dialog with button choices (given as a list of tuples). + Return the value associated with button. + """ + + def button_handler(v: _T) -> None: + get_app().exit(result=v) + + dialog = Dialog( + title=title, + body=Label(text=text, dont_extend_height=True), + buttons=[ + Button(text=t, handler=functools.partial(button_handler, v)) + for t, v in buttons + ], + with_background=True, + ) + + return _create_app(dialog, style) + + +def input_dialog( + title: AnyFormattedText = "", + text: AnyFormattedText = "", + ok_text: str = "OK", + cancel_text: str = "Cancel", + completer: Optional[Completer] = None, + validator: Optional[Validator] = None, + password: FilterOrBool = False, + style: Optional[BaseStyle] = None, +) -> Application[str]: + """ + Display a text input box. + Return the given text, or None when cancelled. + """ + + def accept(buf: Buffer) -> bool: + get_app().layout.focus(ok_button) + return True # Keep text. + + def ok_handler() -> None: + get_app().exit(result=textfield.text) + + ok_button = Button(text=ok_text, handler=ok_handler) + cancel_button = Button(text=cancel_text, handler=_return_none) + + textfield = TextArea( + multiline=False, + password=password, + completer=completer, + validator=validator, + accept_handler=accept, + ) + + dialog = Dialog( + title=title, + body=HSplit( + [ + Label(text=text, dont_extend_height=True), + textfield, + ValidationToolbar(), + ], + padding=D(preferred=1, max=1), + ), + buttons=[ok_button, cancel_button], + with_background=True, + ) + + return _create_app(dialog, style) + + +def message_dialog( + title: AnyFormattedText = "", + text: AnyFormattedText = "", + ok_text: str = "Ok", + style: Optional[BaseStyle] = None, +) -> Application[None]: + """ + Display a simple message box and wait until the user presses enter. + """ + dialog = Dialog( + title=title, + body=Label(text=text, dont_extend_height=True), + buttons=[Button(text=ok_text, handler=_return_none)], + with_background=True, + ) + + return _create_app(dialog, style) + + +def radiolist_dialog( + title: AnyFormattedText = "", + text: AnyFormattedText = "", + ok_text: str = "Ok", + cancel_text: str = "Cancel", + values: Optional[List[Tuple[_T, AnyFormattedText]]] = None, + style: Optional[BaseStyle] = None, +) -> Application[_T]: + """ + Display a simple list of element the user can choose amongst. + + Only one element can be selected at a time using Arrow keys and Enter. + The focus can be moved between the list and the Ok/Cancel button with tab. + """ + if values is None: + values = [] + + def ok_handler() -> None: + get_app().exit(result=radio_list.current_value) + + radio_list = RadioList(values) + + dialog = Dialog( + title=title, + body=HSplit( + [Label(text=text, dont_extend_height=True), radio_list], + padding=1, + ), + buttons=[ + Button(text=ok_text, handler=ok_handler), + Button(text=cancel_text, handler=_return_none), + ], + with_background=True, + ) + + return _create_app(dialog, style) + + +def checkboxlist_dialog( + title: AnyFormattedText = "", + text: AnyFormattedText = "", + ok_text: str = "Ok", + cancel_text: str = "Cancel", + values: Optional[List[Tuple[_T, AnyFormattedText]]] = None, + style: Optional[BaseStyle] = None, +) -> Application[List[_T]]: + """ + Display a simple list of element the user can choose multiple values amongst. + + Several elements can be selected at a time using Arrow keys and Enter. + The focus can be moved between the list and the Ok/Cancel button with tab. + """ + if values is None: + values = [] + + def ok_handler() -> None: + get_app().exit(result=cb_list.current_values) + + cb_list = CheckboxList(values) + + dialog = Dialog( + title=title, + body=HSplit( + [Label(text=text, dont_extend_height=True), cb_list], + padding=1, + ), + buttons=[ + Button(text=ok_text, handler=ok_handler), + Button(text=cancel_text, handler=_return_none), + ], + with_background=True, + ) + + return _create_app(dialog, style) + + +def progress_dialog( + title: AnyFormattedText = "", + text: AnyFormattedText = "", + run_callback: Callable[[Callable[[int], None], Callable[[str], None]], None] = ( + lambda *a: None + ), + style: Optional[BaseStyle] = None, +) -> Application[None]: + """ + :param run_callback: A function that receives as input a `set_percentage` + function and it does the work. + """ + loop = get_event_loop() + progressbar = ProgressBar() + text_area = TextArea( + focusable=False, + # Prefer this text area as big as possible, to avoid having a window + # that keeps resizing when we add text to it. + height=D(preferred=10 ** 10), + ) + + dialog = Dialog( + body=HSplit( + [ + Box(Label(text=text)), + Box(text_area, padding=D.exact(1)), + progressbar, + ] + ), + title=title, + with_background=True, + ) + app = _create_app(dialog, style) + + def set_percentage(value: int) -> None: + progressbar.percentage = int(value) + app.invalidate() + + def log_text(text: str) -> None: + loop.call_soon_threadsafe(text_area.buffer.insert_text, text) + app.invalidate() + + # Run the callback in the executor. When done, set a return value for the + # UI, so that it quits. + def start() -> None: + try: + run_callback(set_percentage, log_text) + finally: + app.exit() + + def pre_run() -> None: + run_in_executor_with_context(start) + + app.pre_run_callables.append(pre_run) + + return app + + +def _create_app(dialog: AnyContainer, style: Optional[BaseStyle]) -> Application[Any]: + # Key bindings. + bindings = KeyBindings() + bindings.add("tab")(focus_next) + bindings.add("s-tab")(focus_previous) + + return Application( + layout=Layout(dialog), + key_bindings=merge_key_bindings([load_key_bindings(), bindings]), + mouse_support=True, + style=style, + full_screen=True, + ) + + +def _return_none() -> None: + " Button handler that returns None. " + get_app().exit() diff --git a/.venv/lib/python3.8/site-packages/prompt_toolkit/shortcuts/progress_bar/__init__.py b/.venv/lib/python3.8/site-packages/prompt_toolkit/shortcuts/progress_bar/__init__.py new file mode 100644 index 00000000..7d0fbb50 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/prompt_toolkit/shortcuts/progress_bar/__init__.py @@ -0,0 +1,31 @@ +from .base import ProgressBar, ProgressBarCounter +from .formatters import ( + Bar, + Formatter, + IterationsPerSecond, + Label, + Percentage, + Progress, + Rainbow, + SpinningWheel, + Text, + TimeElapsed, + TimeLeft, +) + +__all__ = [ + "ProgressBar", + "ProgressBarCounter", + # Formatters. + "Formatter", + "Text", + "Label", + "Percentage", + "Bar", + "Progress", + "TimeElapsed", + "TimeLeft", + "IterationsPerSecond", + "SpinningWheel", + "Rainbow", +] diff --git a/.venv/lib/python3.8/site-packages/prompt_toolkit/shortcuts/progress_bar/__pycache__/__init__.cpython-38.pyc b/.venv/lib/python3.8/site-packages/prompt_toolkit/shortcuts/progress_bar/__pycache__/__init__.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..951f80539d23f90764e1dc38aee84b7c1074b4aa GIT binary patch literal 616 zcmZXR&ubJh6vt;~XLf$=>~8Db`ySQ-(Ssl&ih@u|=~jeXLUvzvcj)AYNtWu#zsG;b zL$02B^(4J$-jv#c3HiV`@8z49myb{Rl(ldu0T3VaGrE5XfAo zq&?$i#WzZV&raBy_r3}{8!jE&abMiI`TU%9a;>g>v(lZEo!oue^N^ih@Gs8S7oFhm zdZsN0U!XYQTW69`pcx@D!~~He3Pg%15!gO6MT`+O0vmq1nEQ0iEWda1)%NZc_SRvr z9?soc53cBN>or{b?-HL=%KDzt?~ysi9K_9e>x6D~rqfV**vU9E7E8{i?XE8AJpRSo{DeYwED1D;8`r@TfaOn9f{3-i5U>-l4C2^93 I_5b|!7h4UQ%m4rY literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/prompt_toolkit/shortcuts/progress_bar/__pycache__/base.cpython-38.pyc b/.venv/lib/python3.8/site-packages/prompt_toolkit/shortcuts/progress_bar/__pycache__/base.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f9de17d90b00cec55252dec1eff9a0b469f95207 GIT binary patch literal 13381 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 literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/prompt_toolkit/shortcuts/progress_bar/__pycache__/formatters.cpython-38.pyc b/.venv/lib/python3.8/site-packages/prompt_toolkit/shortcuts/progress_bar/__pycache__/formatters.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..cad46222bb5c7ca6e494a2e74a8ff45ba764a43e GIT binary patch literal 12568 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 bQLdEV#B-@UGf^zhlwU0$El KeyBindings: + """ + Key bindings handled by the progress bar. + (The main thread is not supposed to handle any key bindings.) + """ + kb = KeyBindings() + + @kb.add("c-l") + def _clear(event: E) -> None: + event.app.renderer.clear() + + @kb.add("c-c") + def _interrupt(event: E) -> None: + # Send KeyboardInterrupt to the main thread. + os.kill(os.getpid(), signal.SIGINT) + + return kb + + +_T = TypeVar("_T") + + +class ProgressBar: + """ + Progress bar context manager. + + Usage :: + + with ProgressBar(...) as pb: + for item in pb(data): + ... + + :param title: Text to be displayed above the progress bars. This can be a + callable or formatted text as well. + :param formatters: List of :class:`.Formatter` instances. + :param bottom_toolbar: Text to be displayed in the bottom toolbar. This + can be a callable or formatted text. + :param style: :class:`prompt_toolkit.styles.BaseStyle` instance. + :param key_bindings: :class:`.KeyBindings` instance. + :param file: The file object used for rendering, by default `sys.stderr` is used. + + :param color_depth: `prompt_toolkit` `ColorDepth` instance. + :param output: :class:`~prompt_toolkit.output.Output` instance. + :param input: :class:`~prompt_toolkit.input.Input` instance. + """ + + def __init__( + self, + title: AnyFormattedText = None, + formatters: Optional[Sequence[Formatter]] = None, + bottom_toolbar: AnyFormattedText = None, + style: Optional[BaseStyle] = None, + key_bindings: Optional[KeyBindings] = None, + file: Optional[TextIO] = None, + color_depth: Optional[ColorDepth] = None, + output: Optional[Output] = None, + input: Optional[Input] = None, + ) -> None: + + self.title = title + self.formatters = formatters or create_default_formatters() + self.bottom_toolbar = bottom_toolbar + self.counters: List[ProgressBarCounter[object]] = [] + self.style = style + self.key_bindings = key_bindings + + # Note that we use __stderr__ as default error output, because that + # works best with `patch_stdout`. + self.color_depth = color_depth + self.output = output or get_app_session().output + self.input = input or get_app_session().input + + self._thread: Optional[threading.Thread] = None + + self._loop = get_event_loop() + self._app_loop = new_event_loop() + + self._previous_winch_handler = None + self._has_sigwinch = False + + if TYPE_CHECKING: + # Infer type from getsignal result, as defined in typeshed. Too + # complex to repeat here. + self._previous_winch_handler = signal.getsignal(_SIGWINCH) + + def __enter__(self) -> "ProgressBar": + # Create UI Application. + title_toolbar = ConditionalContainer( + Window( + FormattedTextControl(lambda: self.title), + height=1, + style="class:progressbar,title", + ), + filter=Condition(lambda: self.title is not None), + ) + + bottom_toolbar = ConditionalContainer( + Window( + FormattedTextControl( + lambda: self.bottom_toolbar, style="class:bottom-toolbar.text" + ), + style="class:bottom-toolbar", + height=1, + ), + filter=~is_done + & renderer_height_is_known + & Condition(lambda: self.bottom_toolbar is not None), + ) + + def width_for_formatter(formatter: Formatter) -> AnyDimension: + # Needs to be passed as callable (partial) to the 'width' + # parameter, because we want to call it on every resize. + return formatter.get_width(progress_bar=self) + + progress_controls = [ + Window( + content=_ProgressControl(self, f), + width=functools.partial(width_for_formatter, f), + ) + for f in self.formatters + ] + + self.app: Application[None] = Application( + min_redraw_interval=0.05, + layout=Layout( + HSplit( + [ + title_toolbar, + VSplit( + progress_controls, + height=lambda: D( + preferred=len(self.counters), max=len(self.counters) + ), + ), + Window(), + bottom_toolbar, + ] + ) + ), + style=self.style, + key_bindings=self.key_bindings, + refresh_interval=0.3, + color_depth=self.color_depth, + output=self.output, + input=self.input, + ) + + # Run application in different thread. + def run() -> None: + set_event_loop(self._app_loop) + try: + self.app.run() + except BaseException as e: + traceback.print_exc() + print(e) + + ctx: contextvars.Context = contextvars.copy_context() + + self._thread = threading.Thread(target=ctx.run, args=(run,)) + self._thread.start() + + # Attach WINCH signal handler in main thread. + # (Interrupt that we receive during resize events.) + self._has_sigwinch = _SIGWINCH is not None and in_main_thread() + if self._has_sigwinch: + self._previous_winch_handler = signal.getsignal(_SIGWINCH) + self._loop.add_signal_handler(_SIGWINCH, self.invalidate) + + return self + + def __exit__(self, *a: object) -> None: + # Quit UI application. + if self.app.is_running: + self.app.exit() + + # Remove WINCH handler. + if self._has_sigwinch: + self._loop.remove_signal_handler(_SIGWINCH) + signal.signal(_SIGWINCH, self._previous_winch_handler) + + if self._thread is not None: + self._thread.join() + self._app_loop.close() + + def __call__( + self, + data: Optional[Iterable[_T]] = None, + label: AnyFormattedText = "", + remove_when_done: bool = False, + total: Optional[int] = None, + ) -> "ProgressBarCounter[_T]": + """ + Start a new counter. + + :param label: Title text or description for this progress. (This can be + formatted text as well). + :param remove_when_done: When `True`, hide this progress bar. + :param total: Specify the maximum value if it can't be calculated by + calling ``len``. + """ + counter = ProgressBarCounter( + self, data, label=label, remove_when_done=remove_when_done, total=total + ) + self.counters.append(counter) + return counter + + def invalidate(self) -> None: + self._app_loop.call_soon_threadsafe(self.app.invalidate) + + +class _ProgressControl(UIControl): + """ + User control for the progress bar. + """ + + def __init__(self, progress_bar: ProgressBar, formatter: Formatter) -> None: + self.progress_bar = progress_bar + self.formatter = formatter + self._key_bindings = create_key_bindings() + + def create_content(self, width: int, height: int) -> UIContent: + items: List[StyleAndTextTuples] = [] + + for pr in self.progress_bar.counters: + try: + text = self.formatter.format(self.progress_bar, pr, width) + except BaseException: + traceback.print_exc() + text = "ERROR" + + items.append(to_formatted_text(text)) + + def get_line(i: int) -> StyleAndTextTuples: + return items[i] + + return UIContent(get_line=get_line, line_count=len(items), show_cursor=False) + + def is_focusable(self) -> bool: + return True # Make sure that the key bindings work. + + def get_key_bindings(self) -> KeyBindings: + return self._key_bindings + + +_CounterItem = TypeVar("_CounterItem", covariant=True) + + +class ProgressBarCounter(Generic[_CounterItem]): + """ + An individual counter (A progress bar can have multiple counters). + """ + + def __init__( + self, + progress_bar: ProgressBar, + data: Optional[Iterable[_CounterItem]] = None, + label: AnyFormattedText = "", + remove_when_done: bool = False, + total: Optional[int] = None, + ) -> None: + + self.start_time = datetime.datetime.now() + self.stop_time: Optional[datetime.datetime] = None + self.progress_bar = progress_bar + self.data = data + self.items_completed = 0 + self.label = label + self.remove_when_done = remove_when_done + self._done = False + self.total: Optional[int] + + if total is None: + try: + self.total = len(cast(Sized, data)) + except TypeError: + self.total = None # We don't know the total length. + else: + self.total = total + + def __iter__(self) -> Iterable[_CounterItem]: + if self.data is not None: + try: + for item in self.data: + yield item + self.item_completed() + + # Only done if we iterate to the very end. + self.done = True + finally: + # Ensure counter has stopped even if we did not iterate to the + # end (e.g. break or exceptions). + self.stopped = True + else: + raise NotImplementedError("No data defined to iterate over.") + + def item_completed(self) -> None: + """ + Start handling the next item. + + (Can be called manually in case we don't have a collection to loop through.) + """ + self.items_completed += 1 + self.progress_bar.invalidate() + + @property + def done(self) -> bool: + """Whether a counter has been completed. + + Done counter have been stopped (see stopped) and removed depending on + remove_when_done value. + + Contrast this with stopped. A stopped counter may be terminated before + 100% completion. A done counter has reached its 100% completion. + """ + return self._done + + @done.setter + def done(self, value: bool) -> None: + self._done = value + self.stopped = value + + if value and self.remove_when_done: + self.progress_bar.counters.remove(self) + + @property + def stopped(self) -> bool: + """Whether a counter has been stopped. + + Stopped counters no longer have increasing time_elapsed. This distinction is + also used to prevent the Bar formatter with unknown totals from continuing to run. + + A stopped counter (but not done) can be used to signal that a given counter has + encountered an error but allows other counters to continue + (e.g. download X of Y failed). Given how only done counters are removed + (see remove_when_done) this can help aggregate failures from a large number of + successes. + + Contrast this with done. A done counter has reached its 100% completion. + A stopped counter may be terminated before 100% completion. + """ + return self.stop_time is not None + + @stopped.setter + def stopped(self, value: bool) -> None: + if value: + # This counter has not already been stopped. + if not self.stop_time: + self.stop_time = datetime.datetime.now() + else: + # Clearing any previously set stop_time. + self.stop_time = None + + @property + def percentage(self) -> float: + if self.total is None: + return 0 + else: + return self.items_completed * 100 / max(self.total, 1) + + @property + def time_elapsed(self) -> datetime.timedelta: + """ + Return how much time has been elapsed since the start. + """ + if self.stop_time is None: + return datetime.datetime.now() - self.start_time + else: + return self.stop_time - self.start_time + + @property + def time_left(self) -> Optional[datetime.timedelta]: + """ + Timedelta representing the time left. + """ + if self.total is None or not self.percentage: + return None + elif self.done or self.stopped: + return datetime.timedelta(0) + else: + return self.time_elapsed * (100 - self.percentage) / self.percentage diff --git a/.venv/lib/python3.8/site-packages/prompt_toolkit/shortcuts/progress_bar/formatters.py b/.venv/lib/python3.8/site-packages/prompt_toolkit/shortcuts/progress_bar/formatters.py new file mode 100644 index 00000000..ad3a932d --- /dev/null +++ b/.venv/lib/python3.8/site-packages/prompt_toolkit/shortcuts/progress_bar/formatters.py @@ -0,0 +1,436 @@ +""" +Formatter classes for the progress bar. +Each progress bar consists of a list of these formatters. +""" +import datetime +import time +from abc import ABCMeta, abstractmethod +from typing import TYPE_CHECKING, List, Tuple + +from prompt_toolkit.formatted_text import ( + HTML, + AnyFormattedText, + StyleAndTextTuples, + to_formatted_text, +) +from prompt_toolkit.formatted_text.utils import fragment_list_width +from prompt_toolkit.layout.dimension import AnyDimension, D +from prompt_toolkit.layout.utils import explode_text_fragments +from prompt_toolkit.utils import get_cwidth + +if TYPE_CHECKING: + from .base import ProgressBar, ProgressBarCounter + +__all__ = [ + "Formatter", + "Text", + "Label", + "Percentage", + "Bar", + "Progress", + "TimeElapsed", + "TimeLeft", + "IterationsPerSecond", + "SpinningWheel", + "Rainbow", + "create_default_formatters", +] + + +class Formatter(metaclass=ABCMeta): + """ + Base class for any formatter. + """ + + @abstractmethod + def format( + self, + progress_bar: "ProgressBar", + progress: "ProgressBarCounter[object]", + width: int, + ) -> AnyFormattedText: + pass + + def get_width(self, progress_bar: "ProgressBar") -> AnyDimension: + return D() + + +class Text(Formatter): + """ + Display plain text. + """ + + def __init__(self, text: AnyFormattedText, style: str = "") -> None: + self.text = to_formatted_text(text, style=style) + + def format( + self, + progress_bar: "ProgressBar", + progress: "ProgressBarCounter[object]", + width: int, + ) -> AnyFormattedText: + return self.text + + def get_width(self, progress_bar: "ProgressBar") -> AnyDimension: + return fragment_list_width(self.text) + + +class Label(Formatter): + """ + Display the name of the current task. + + :param width: If a `width` is given, use this width. Scroll the text if it + doesn't fit in this width. + :param suffix: String suffix to be added after the task name, e.g. ': '. + If no task name was given, no suffix will be added. + """ + + def __init__(self, width: AnyDimension = None, suffix: str = "") -> None: + self.width = width + self.suffix = suffix + + def _add_suffix(self, label: AnyFormattedText) -> StyleAndTextTuples: + label = to_formatted_text(label, style="class:label") + return label + [("", self.suffix)] + + def format( + self, + progress_bar: "ProgressBar", + progress: "ProgressBarCounter[object]", + width: int, + ) -> AnyFormattedText: + + label = self._add_suffix(progress.label) + cwidth = fragment_list_width(label) + + if cwidth > width: + # It doesn't fit -> scroll task name. + label = explode_text_fragments(label) + max_scroll = cwidth - width + current_scroll = int(time.time() * 3 % max_scroll) + label = label[current_scroll:] + + return label + + def get_width(self, progress_bar: "ProgressBar") -> AnyDimension: + if self.width: + return self.width + + all_labels = [self._add_suffix(c.label) for c in progress_bar.counters] + if all_labels: + max_widths = max(fragment_list_width(l) for l in all_labels) + return D(preferred=max_widths, max=max_widths) + else: + return D() + + +class Percentage(Formatter): + """ + Display the progress as a percentage. + """ + + template = "{percentage:>5}%" + + def format( + self, + progress_bar: "ProgressBar", + progress: "ProgressBarCounter[object]", + width: int, + ) -> AnyFormattedText: + + return HTML(self.template).format(percentage=round(progress.percentage, 1)) + + def get_width(self, progress_bar: "ProgressBar") -> AnyDimension: + return D.exact(6) + + +class Bar(Formatter): + """ + Display the progress bar itself. + """ + + template = "{start}{bar_a}{bar_b}{bar_c}{end}" + + def __init__( + self, + start: str = "[", + end: str = "]", + sym_a: str = "=", + sym_b: str = ">", + sym_c: str = " ", + unknown: str = "#", + ) -> None: + + assert len(sym_a) == 1 and get_cwidth(sym_a) == 1 + assert len(sym_c) == 1 and get_cwidth(sym_c) == 1 + + self.start = start + self.end = end + self.sym_a = sym_a + self.sym_b = sym_b + self.sym_c = sym_c + self.unknown = unknown + + def format( + self, + progress_bar: "ProgressBar", + progress: "ProgressBarCounter[object]", + width: int, + ) -> AnyFormattedText: + if progress.done or progress.total or progress.stopped: + sym_a, sym_b, sym_c = self.sym_a, self.sym_b, self.sym_c + + # Compute pb_a based on done, total, or stopped states. + if progress.done: + # 100% completed irrelevant of how much was actually marked as completed. + percent = 1.0 + else: + # Show percentage completed. + percent = progress.percentage / 100 + else: + # Total is unknown and bar is still running. + sym_a, sym_b, sym_c = self.sym_c, self.unknown, self.sym_c + + # Compute percent based on the time. + percent = time.time() * 20 % 100 / 100 + + # Subtract left, sym_b, and right. + width -= get_cwidth(self.start + sym_b + self.end) + + # Scale percent by width + pb_a = int(percent * width) + bar_a = sym_a * pb_a + bar_b = sym_b + bar_c = sym_c * (width - pb_a) + + return HTML(self.template).format( + start=self.start, end=self.end, bar_a=bar_a, bar_b=bar_b, bar_c=bar_c + ) + + def get_width(self, progress_bar: "ProgressBar") -> AnyDimension: + return D(min=9) + + +class Progress(Formatter): + """ + Display the progress as text. E.g. "8/20" + """ + + template = "{current:>3}/{total:>3}" + + def format( + self, + progress_bar: "ProgressBar", + progress: "ProgressBarCounter[object]", + width: int, + ) -> AnyFormattedText: + + return HTML(self.template).format( + current=progress.items_completed, total=progress.total or "?" + ) + + def get_width(self, progress_bar: "ProgressBar") -> AnyDimension: + all_lengths = [ + len("{0:>3}".format(c.total or "?")) for c in progress_bar.counters + ] + all_lengths.append(1) + return D.exact(max(all_lengths) * 2 + 1) + + +def _format_timedelta(timedelta: datetime.timedelta) -> str: + """ + Return hh:mm:ss, or mm:ss if the amount of hours is zero. + """ + result = "{0}".format(timedelta).split(".")[0] + if result.startswith("0:"): + result = result[2:] + return result + + +class TimeElapsed(Formatter): + """ + Display the elapsed time. + """ + + def format( + self, + progress_bar: "ProgressBar", + progress: "ProgressBarCounter[object]", + width: int, + ) -> AnyFormattedText: + + text = _format_timedelta(progress.time_elapsed).rjust(width) + return HTML("{time_elapsed}").format( + time_elapsed=text + ) + + def get_width(self, progress_bar: "ProgressBar") -> AnyDimension: + all_values = [ + len(_format_timedelta(c.time_elapsed)) for c in progress_bar.counters + ] + if all_values: + return max(all_values) + return 0 + + +class TimeLeft(Formatter): + """ + Display the time left. + """ + + template = "{time_left}" + unknown = "?:??:??" + + def format( + self, + progress_bar: "ProgressBar", + progress: "ProgressBarCounter[object]", + width: int, + ) -> AnyFormattedText: + + time_left = progress.time_left + if time_left is not None: + formatted_time_left = _format_timedelta(time_left) + else: + formatted_time_left = self.unknown + + return HTML(self.template).format(time_left=formatted_time_left.rjust(width)) + + def get_width(self, progress_bar: "ProgressBar") -> AnyDimension: + all_values = [ + len(_format_timedelta(c.time_left)) if c.time_left is not None else 7 + for c in progress_bar.counters + ] + if all_values: + return max(all_values) + return 0 + + +class IterationsPerSecond(Formatter): + """ + Display the iterations per second. + """ + + template = ( + "{iterations_per_second:.2f}" + ) + + def format( + self, + progress_bar: "ProgressBar", + progress: "ProgressBarCounter[object]", + width: int, + ) -> AnyFormattedText: + + value = progress.items_completed / progress.time_elapsed.total_seconds() + return HTML(self.template.format(iterations_per_second=value)) + + def get_width(self, progress_bar: "ProgressBar") -> AnyDimension: + all_values = [ + len("{0:.2f}".format(c.items_completed / c.time_elapsed.total_seconds())) + for c in progress_bar.counters + ] + if all_values: + return max(all_values) + return 0 + + +class SpinningWheel(Formatter): + """ + Display a spinning wheel. + """ + + characters = r"/-\|" + + def format( + self, + progress_bar: "ProgressBar", + progress: "ProgressBarCounter[object]", + width: int, + ) -> AnyFormattedText: + + index = int(time.time() * 3) % len(self.characters) + return HTML("{0}").format( + self.characters[index] + ) + + def get_width(self, progress_bar: "ProgressBar") -> AnyDimension: + return D.exact(1) + + +def _hue_to_rgb(hue: float) -> Tuple[int, int, int]: + """ + Take hue between 0 and 1, return (r, g, b). + """ + i = int(hue * 6.0) + f = (hue * 6.0) - i + + q = int(255 * (1.0 - f)) + t = int(255 * (1.0 - (1.0 - f))) + + i %= 6 + + return [ + (255, t, 0), + (q, 255, 0), + (0, 255, t), + (0, q, 255), + (t, 0, 255), + (255, 0, q), + ][i] + + +class Rainbow(Formatter): + """ + For the fun. Add rainbow colors to any of the other formatters. + """ + + colors = ["#%.2x%.2x%.2x" % _hue_to_rgb(h / 100.0) for h in range(0, 100)] + + def __init__(self, formatter: Formatter) -> None: + self.formatter = formatter + + def format( + self, + progress_bar: "ProgressBar", + progress: "ProgressBarCounter[object]", + width: int, + ) -> AnyFormattedText: + + # Get formatted text from nested formatter, and explode it in + # text/style tuples. + result = self.formatter.format(progress_bar, progress, width) + result = explode_text_fragments(to_formatted_text(result)) + + # Insert colors. + result2: StyleAndTextTuples = [] + shift = int(time.time() * 3) % len(self.colors) + + for i, (style, text, *_) in enumerate(result): + result2.append( + (style + " " + self.colors[(i + shift) % len(self.colors)], text) + ) + return result2 + + def get_width(self, progress_bar: "ProgressBar") -> AnyDimension: + return self.formatter.get_width(progress_bar) + + +def create_default_formatters() -> List[Formatter]: + """ + Return the list of default formatters. + """ + return [ + Label(), + Text(" "), + Percentage(), + Text(" "), + Bar(), + Text(" "), + Progress(), + Text(" "), + Text("eta [", style="class:time-left"), + TimeLeft(), + Text("]", style="class:time-left"), + Text(" "), + ] diff --git a/.venv/lib/python3.8/site-packages/prompt_toolkit/shortcuts/prompt.py b/.venv/lib/python3.8/site-packages/prompt_toolkit/shortcuts/prompt.py new file mode 100644 index 00000000..aa787420 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/prompt_toolkit/shortcuts/prompt.py @@ -0,0 +1,1467 @@ +""" +Line editing functionality. +--------------------------- + +This provides a UI for a line input, similar to GNU Readline, libedit and +linenoise. + +Either call the `prompt` function for every line input. Or create an instance +of the :class:`.PromptSession` class and call the `prompt` method from that +class. In the second case, we'll have a 'session' that keeps all the state like +the history in between several calls. + +There is a lot of overlap between the arguments taken by the `prompt` function +and the `PromptSession` (like `completer`, `style`, etcetera). There we have +the freedom to decide which settings we want for the whole 'session', and which +we want for an individual `prompt`. + +Example:: + + # Simple `prompt` call. + result = prompt('Say something: ') + + # Using a 'session'. + s = PromptSession() + result = s.prompt('Say something: ') +""" +from asyncio import get_event_loop +from enum import Enum +from functools import partial +from typing import ( + TYPE_CHECKING, + Callable, + Generic, + List, + Optional, + Tuple, + TypeVar, + Union, + cast, +) + +from prompt_toolkit.application import Application +from prompt_toolkit.application.current import get_app +from prompt_toolkit.auto_suggest import AutoSuggest, DynamicAutoSuggest +from prompt_toolkit.buffer import Buffer +from prompt_toolkit.clipboard import Clipboard, DynamicClipboard, InMemoryClipboard +from prompt_toolkit.completion import Completer, DynamicCompleter, ThreadedCompleter +from prompt_toolkit.document import Document +from prompt_toolkit.enums import DEFAULT_BUFFER, SEARCH_BUFFER, EditingMode +from prompt_toolkit.filters import ( + Condition, + FilterOrBool, + has_arg, + has_focus, + is_done, + is_true, + renderer_height_is_known, + to_filter, +) +from prompt_toolkit.formatted_text import ( + AnyFormattedText, + StyleAndTextTuples, + fragment_list_to_text, + merge_formatted_text, + to_formatted_text, +) +from prompt_toolkit.history import History, InMemoryHistory +from prompt_toolkit.input.base import Input +from prompt_toolkit.key_binding.bindings.auto_suggest import load_auto_suggest_bindings +from prompt_toolkit.key_binding.bindings.completion import ( + display_completions_like_readline, +) +from prompt_toolkit.key_binding.bindings.open_in_editor import ( + load_open_in_editor_bindings, +) +from prompt_toolkit.key_binding.key_bindings import ( + ConditionalKeyBindings, + DynamicKeyBindings, + KeyBindings, + KeyBindingsBase, + merge_key_bindings, +) +from prompt_toolkit.key_binding.key_processor import KeyPressEvent +from prompt_toolkit.keys import Keys +from prompt_toolkit.layout import Float, FloatContainer, HSplit, Window +from prompt_toolkit.layout.containers import ConditionalContainer, WindowAlign +from prompt_toolkit.layout.controls import ( + BufferControl, + FormattedTextControl, + SearchBufferControl, +) +from prompt_toolkit.layout.dimension import Dimension +from prompt_toolkit.layout.layout import Layout +from prompt_toolkit.layout.menus import CompletionsMenu, MultiColumnCompletionsMenu +from prompt_toolkit.layout.processors import ( + AfterInput, + AppendAutoSuggestion, + ConditionalProcessor, + DisplayMultipleCursors, + DynamicProcessor, + HighlightIncrementalSearchProcessor, + HighlightSelectionProcessor, + PasswordProcessor, + Processor, + ReverseSearchProcessor, + merge_processors, +) +from prompt_toolkit.layout.utils import explode_text_fragments +from prompt_toolkit.lexers import DynamicLexer, Lexer +from prompt_toolkit.output import ColorDepth, DummyOutput, Output +from prompt_toolkit.styles import ( + BaseStyle, + ConditionalStyleTransformation, + DynamicStyle, + DynamicStyleTransformation, + StyleTransformation, + SwapLightAndDarkStyleTransformation, + merge_style_transformations, +) +from prompt_toolkit.utils import ( + get_cwidth, + is_dumb_terminal, + suspend_to_background_supported, + to_str, +) +from prompt_toolkit.validation import DynamicValidator, Validator +from prompt_toolkit.widgets.toolbars import ( + SearchToolbar, + SystemToolbar, + ValidationToolbar, +) + +if TYPE_CHECKING: + from prompt_toolkit.formatted_text.base import MagicFormattedText + +__all__ = [ + "PromptSession", + "prompt", + "confirm", + "create_confirm_session", # Used by '_display_completions_like_readline'. + "CompleteStyle", +] + +_StyleAndTextTuplesCallable = Callable[[], StyleAndTextTuples] +E = KeyPressEvent + + +def _split_multiline_prompt( + get_prompt_text: _StyleAndTextTuplesCallable, +) -> Tuple[ + Callable[[], bool], _StyleAndTextTuplesCallable, _StyleAndTextTuplesCallable +]: + """ + Take a `get_prompt_text` function and return three new functions instead. + One that tells whether this prompt consists of multiple lines; one that + returns the fragments to be shown on the lines above the input; and another + one with the fragments to be shown at the first line of the input. + """ + + def has_before_fragments() -> bool: + for fragment, char, *_ in get_prompt_text(): + if "\n" in char: + return True + return False + + def before() -> StyleAndTextTuples: + result: StyleAndTextTuples = [] + found_nl = False + for fragment, char, *_ in reversed(explode_text_fragments(get_prompt_text())): + if found_nl: + result.insert(0, (fragment, char)) + elif char == "\n": + found_nl = True + return result + + def first_input_line() -> StyleAndTextTuples: + result: StyleAndTextTuples = [] + for fragment, char, *_ in reversed(explode_text_fragments(get_prompt_text())): + if char == "\n": + break + else: + result.insert(0, (fragment, char)) + return result + + return has_before_fragments, before, first_input_line + + +class _RPrompt(Window): + """ + The prompt that is displayed on the right side of the Window. + """ + + def __init__(self, text: AnyFormattedText) -> None: + super().__init__( + FormattedTextControl(text=text), + align=WindowAlign.RIGHT, + style="class:rprompt", + ) + + +class CompleteStyle(str, Enum): + """ + How to display autocompletions for the prompt. + """ + + value: str + + COLUMN = "COLUMN" + MULTI_COLUMN = "MULTI_COLUMN" + READLINE_LIKE = "READLINE_LIKE" + + +# Formatted text for the continuation prompt. It's the same like other +# formatted text, except that if it's a callable, it takes three arguments. +PromptContinuationText = Union[ + str, + "MagicFormattedText", + StyleAndTextTuples, + # (prompt_width, line_number, wrap_count) -> AnyFormattedText. + Callable[[int, int, int], AnyFormattedText], +] + +_T = TypeVar("_T") + + +class PromptSession(Generic[_T]): + """ + PromptSession for a prompt application, which can be used as a GNU Readline + replacement. + + This is a wrapper around a lot of ``prompt_toolkit`` functionality and can + be a replacement for `raw_input`. + + All parameters that expect "formatted text" can take either just plain text + (a unicode object), a list of ``(style_str, text)`` tuples or an HTML object. + + Example usage:: + + s = PromptSession(message='>') + text = s.prompt() + + :param message: Plain text or formatted text to be shown before the prompt. + This can also be a callable that returns formatted text. + :param multiline: `bool` or :class:`~prompt_toolkit.filters.Filter`. + When True, prefer a layout that is more adapted for multiline input. + Text after newlines is automatically indented, and search/arg input is + shown below the input, instead of replacing the prompt. + :param wrap_lines: `bool` or :class:`~prompt_toolkit.filters.Filter`. + When True (the default), automatically wrap long lines instead of + scrolling horizontally. + :param is_password: Show asterisks instead of the actual typed characters. + :param editing_mode: ``EditingMode.VI`` or ``EditingMode.EMACS``. + :param vi_mode: `bool`, if True, Identical to ``editing_mode=EditingMode.VI``. + :param complete_while_typing: `bool` or + :class:`~prompt_toolkit.filters.Filter`. Enable autocompletion while + typing. + :param validate_while_typing: `bool` or + :class:`~prompt_toolkit.filters.Filter`. Enable input validation while + typing. + :param enable_history_search: `bool` or + :class:`~prompt_toolkit.filters.Filter`. Enable up-arrow parting + string matching. + :param search_ignore_case: + :class:`~prompt_toolkit.filters.Filter`. Search case insensitive. + :param lexer: :class:`~prompt_toolkit.lexers.Lexer` to be used for the + syntax highlighting. + :param validator: :class:`~prompt_toolkit.validation.Validator` instance + for input validation. + :param completer: :class:`~prompt_toolkit.completion.Completer` instance + for input completion. + :param complete_in_thread: `bool` or + :class:`~prompt_toolkit.filters.Filter`. Run the completer code in a + background thread in order to avoid blocking the user interface. + For ``CompleteStyle.READLINE_LIKE``, this setting has no effect. There + we always run the completions in the main thread. + :param reserve_space_for_menu: Space to be reserved for displaying the menu. + (0 means that no space needs to be reserved.) + :param auto_suggest: :class:`~prompt_toolkit.auto_suggest.AutoSuggest` + instance for input suggestions. + :param style: :class:`.Style` instance for the color scheme. + :param include_default_pygments_style: `bool` or + :class:`~prompt_toolkit.filters.Filter`. Tell whether the default + styling for Pygments lexers has to be included. By default, this is + true, but it is recommended to be disabled if another Pygments style is + passed as the `style` argument, otherwise, two Pygments styles will be + merged. + :param style_transformation: + :class:`~prompt_toolkit.style.StyleTransformation` instance. + :param swap_light_and_dark_colors: `bool` or + :class:`~prompt_toolkit.filters.Filter`. When enabled, apply + :class:`~prompt_toolkit.style.SwapLightAndDarkStyleTransformation`. + This is useful for switching between dark and light terminal + backgrounds. + :param enable_system_prompt: `bool` or + :class:`~prompt_toolkit.filters.Filter`. Pressing Meta+'!' will show + a system prompt. + :param enable_suspend: `bool` or :class:`~prompt_toolkit.filters.Filter`. + Enable Control-Z style suspension. + :param enable_open_in_editor: `bool` or + :class:`~prompt_toolkit.filters.Filter`. Pressing 'v' in Vi mode or + C-X C-E in emacs mode will open an external editor. + :param history: :class:`~prompt_toolkit.history.History` instance. + :param clipboard: :class:`~prompt_toolkit.clipboard.Clipboard` instance. + (e.g. :class:`~prompt_toolkit.clipboard.InMemoryClipboard`) + :param rprompt: Text or formatted text to be displayed on the right side. + This can also be a callable that returns (formatted) text. + :param bottom_toolbar: Formatted text or callable which is supposed to + return formatted text. + :param prompt_continuation: Text that needs to be displayed for a multiline + prompt continuation. This can either be formatted text or a callable + that takes a `prompt_width`, `line_number` and `wrap_count` as input + and returns formatted text. When this is `None` (the default), then + `prompt_width` spaces will be used. + :param complete_style: ``CompleteStyle.COLUMN``, + ``CompleteStyle.MULTI_COLUMN`` or ``CompleteStyle.READLINE_LIKE``. + :param mouse_support: `bool` or :class:`~prompt_toolkit.filters.Filter` + to enable mouse support. + :param placeholder: Text to be displayed when no input has been given + yet. Unlike the `default` parameter, this won't be returned as part of + the output ever. This can be formatted text or a callable that returns + formatted text. + :param refresh_interval: (number; in seconds) When given, refresh the UI + every so many seconds. + :param input: `Input` object. (Note that the preferred way to change the + input/output is by creating an `AppSession`.) + :param output: `Output` object. + """ + + _fields = ( + "message", + "lexer", + "completer", + "complete_in_thread", + "is_password", + "editing_mode", + "key_bindings", + "is_password", + "bottom_toolbar", + "style", + "style_transformation", + "swap_light_and_dark_colors", + "color_depth", + "include_default_pygments_style", + "rprompt", + "multiline", + "prompt_continuation", + "wrap_lines", + "enable_history_search", + "search_ignore_case", + "complete_while_typing", + "validate_while_typing", + "complete_style", + "mouse_support", + "auto_suggest", + "clipboard", + "validator", + "refresh_interval", + "input_processors", + "placeholder", + "enable_system_prompt", + "enable_suspend", + "enable_open_in_editor", + "reserve_space_for_menu", + "tempfile_suffix", + "tempfile", + ) + + def __init__( + self, + message: AnyFormattedText = "", + *, + multiline: FilterOrBool = False, + wrap_lines: FilterOrBool = True, + is_password: FilterOrBool = False, + vi_mode: bool = False, + editing_mode: EditingMode = EditingMode.EMACS, + complete_while_typing: FilterOrBool = True, + validate_while_typing: FilterOrBool = True, + enable_history_search: FilterOrBool = False, + search_ignore_case: FilterOrBool = False, + lexer: Optional[Lexer] = None, + enable_system_prompt: FilterOrBool = False, + enable_suspend: FilterOrBool = False, + enable_open_in_editor: FilterOrBool = False, + validator: Optional[Validator] = None, + completer: Optional[Completer] = None, + complete_in_thread: bool = False, + reserve_space_for_menu: int = 8, + complete_style: CompleteStyle = CompleteStyle.COLUMN, + auto_suggest: Optional[AutoSuggest] = None, + style: Optional[BaseStyle] = None, + style_transformation: Optional[StyleTransformation] = None, + swap_light_and_dark_colors: FilterOrBool = False, + color_depth: Optional[ColorDepth] = None, + include_default_pygments_style: FilterOrBool = True, + history: Optional[History] = None, + clipboard: Optional[Clipboard] = None, + prompt_continuation: Optional[PromptContinuationText] = None, + rprompt: AnyFormattedText = None, + bottom_toolbar: AnyFormattedText = None, + mouse_support: FilterOrBool = False, + input_processors: Optional[List[Processor]] = None, + placeholder: Optional[AnyFormattedText] = None, + key_bindings: Optional[KeyBindingsBase] = None, + erase_when_done: bool = False, + tempfile_suffix: Optional[Union[str, Callable[[], str]]] = ".txt", + tempfile: Optional[Union[str, Callable[[], str]]] = None, + refresh_interval: float = 0, + input: Optional[Input] = None, + output: Optional[Output] = None, + ) -> None: + + history = history or InMemoryHistory() + clipboard = clipboard or InMemoryClipboard() + + # Ensure backwards-compatibility, when `vi_mode` is passed. + if vi_mode: + editing_mode = EditingMode.VI + + # Store all settings in this class. + self._input = input + self._output = output + + # Store attributes. + # (All except 'editing_mode'.) + self.message = message + self.lexer = lexer + self.completer = completer + self.complete_in_thread = complete_in_thread + self.is_password = is_password + self.key_bindings = key_bindings + self.bottom_toolbar = bottom_toolbar + self.style = style + self.style_transformation = style_transformation + self.swap_light_and_dark_colors = swap_light_and_dark_colors + self.color_depth = color_depth + self.include_default_pygments_style = include_default_pygments_style + self.rprompt = rprompt + self.multiline = multiline + self.prompt_continuation = prompt_continuation + self.wrap_lines = wrap_lines + self.enable_history_search = enable_history_search + self.search_ignore_case = search_ignore_case + self.complete_while_typing = complete_while_typing + self.validate_while_typing = validate_while_typing + self.complete_style = complete_style + self.mouse_support = mouse_support + self.auto_suggest = auto_suggest + self.clipboard = clipboard + self.validator = validator + self.refresh_interval = refresh_interval + self.input_processors = input_processors + self.placeholder = placeholder + self.enable_system_prompt = enable_system_prompt + self.enable_suspend = enable_suspend + self.enable_open_in_editor = enable_open_in_editor + self.reserve_space_for_menu = reserve_space_for_menu + self.tempfile_suffix = tempfile_suffix + self.tempfile = tempfile + + # Create buffers, layout and Application. + self.history = history + self.default_buffer = self._create_default_buffer() + self.search_buffer = self._create_search_buffer() + self.layout = self._create_layout() + self.app = self._create_application(editing_mode, erase_when_done) + + def _dyncond(self, attr_name: str) -> Condition: + """ + Dynamically take this setting from this 'PromptSession' class. + `attr_name` represents an attribute name of this class. Its value + can either be a boolean or a `Filter`. + + This returns something that can be used as either a `Filter` + or `Filter`. + """ + + @Condition + def dynamic() -> bool: + value = cast(FilterOrBool, getattr(self, attr_name)) + return to_filter(value)() + + return dynamic + + def _create_default_buffer(self) -> Buffer: + """ + Create and return the default input buffer. + """ + dyncond = self._dyncond + + # Create buffers list. + def accept(buff: Buffer) -> bool: + """Accept the content of the default buffer. This is called when + the validation succeeds.""" + cast(Application[str], get_app()).exit(result=buff.document.text) + return True # Keep text, we call 'reset' later on. + + return Buffer( + name=DEFAULT_BUFFER, + # Make sure that complete_while_typing is disabled when + # enable_history_search is enabled. (First convert to Filter, + # to avoid doing bitwise operations on bool objects.) + complete_while_typing=Condition( + lambda: is_true(self.complete_while_typing) + and not is_true(self.enable_history_search) + and not self.complete_style == CompleteStyle.READLINE_LIKE + ), + validate_while_typing=dyncond("validate_while_typing"), + enable_history_search=dyncond("enable_history_search"), + validator=DynamicValidator(lambda: self.validator), + completer=DynamicCompleter( + lambda: ThreadedCompleter(self.completer) + if self.complete_in_thread and self.completer + else self.completer + ), + history=self.history, + auto_suggest=DynamicAutoSuggest(lambda: self.auto_suggest), + accept_handler=accept, + tempfile_suffix=lambda: to_str(self.tempfile_suffix or ""), + tempfile=lambda: to_str(self.tempfile or ""), + ) + + def _create_search_buffer(self) -> Buffer: + return Buffer(name=SEARCH_BUFFER) + + def _create_layout(self) -> Layout: + """ + Create `Layout` for this prompt. + """ + dyncond = self._dyncond + + # Create functions that will dynamically split the prompt. (If we have + # a multiline prompt.) + ( + has_before_fragments, + get_prompt_text_1, + get_prompt_text_2, + ) = _split_multiline_prompt(self._get_prompt) + + default_buffer = self.default_buffer + search_buffer = self.search_buffer + + # Create processors list. + @Condition + def display_placeholder() -> bool: + return self.placeholder is not None and self.default_buffer.text == "" + + all_input_processors = [ + HighlightIncrementalSearchProcessor(), + HighlightSelectionProcessor(), + ConditionalProcessor( + AppendAutoSuggestion(), has_focus(default_buffer) & ~is_done + ), + ConditionalProcessor(PasswordProcessor(), dyncond("is_password")), + DisplayMultipleCursors(), + # Users can insert processors here. + DynamicProcessor(lambda: merge_processors(self.input_processors or [])), + ConditionalProcessor( + AfterInput(lambda: self.placeholder), + filter=display_placeholder, + ), + ] + + # Create bottom toolbars. + bottom_toolbar = ConditionalContainer( + Window( + FormattedTextControl( + lambda: self.bottom_toolbar, style="class:bottom-toolbar.text" + ), + style="class:bottom-toolbar", + dont_extend_height=True, + height=Dimension(min=1), + ), + filter=~is_done + & renderer_height_is_known + & Condition(lambda: self.bottom_toolbar is not None), + ) + + search_toolbar = SearchToolbar( + search_buffer, ignore_case=dyncond("search_ignore_case") + ) + + search_buffer_control = SearchBufferControl( + buffer=search_buffer, + input_processors=[ReverseSearchProcessor()], + ignore_case=dyncond("search_ignore_case"), + ) + + system_toolbar = SystemToolbar( + enable_global_bindings=dyncond("enable_system_prompt") + ) + + def get_search_buffer_control() -> SearchBufferControl: + " Return the UIControl to be focused when searching start. " + if is_true(self.multiline): + return search_toolbar.control + else: + return search_buffer_control + + default_buffer_control = BufferControl( + buffer=default_buffer, + search_buffer_control=get_search_buffer_control, + input_processors=all_input_processors, + include_default_input_processors=False, + lexer=DynamicLexer(lambda: self.lexer), + preview_search=True, + ) + + default_buffer_window = Window( + default_buffer_control, + height=self._get_default_buffer_control_height, + get_line_prefix=partial( + self._get_line_prefix, get_prompt_text_2=get_prompt_text_2 + ), + wrap_lines=dyncond("wrap_lines"), + ) + + @Condition + def multi_column_complete_style() -> bool: + return self.complete_style == CompleteStyle.MULTI_COLUMN + + # Build the layout. + layout = HSplit( + [ + # The main input, with completion menus floating on top of it. + FloatContainer( + HSplit( + [ + ConditionalContainer( + Window( + FormattedTextControl(get_prompt_text_1), + dont_extend_height=True, + ), + Condition(has_before_fragments), + ), + ConditionalContainer( + default_buffer_window, + Condition( + lambda: get_app().layout.current_control + != search_buffer_control + ), + ), + ConditionalContainer( + Window(search_buffer_control), + Condition( + lambda: get_app().layout.current_control + == search_buffer_control + ), + ), + ] + ), + [ + # Completion menus. + # NOTE: Especially the multi-column menu needs to be + # transparent, because the shape is not always + # rectangular due to the meta-text below the menu. + Float( + xcursor=True, + ycursor=True, + transparent=True, + content=CompletionsMenu( + max_height=16, + scroll_offset=1, + extra_filter=has_focus(default_buffer) + & ~multi_column_complete_style, + ), + ), + Float( + xcursor=True, + ycursor=True, + transparent=True, + content=MultiColumnCompletionsMenu( + show_meta=True, + extra_filter=has_focus(default_buffer) + & multi_column_complete_style, + ), + ), + # The right prompt. + Float( + right=0, + bottom=0, + hide_when_covering_content=True, + content=_RPrompt(lambda: self.rprompt), + ), + ], + ), + ConditionalContainer(ValidationToolbar(), filter=~is_done), + ConditionalContainer( + system_toolbar, dyncond("enable_system_prompt") & ~is_done + ), + # In multiline mode, we use two toolbars for 'arg' and 'search'. + ConditionalContainer( + Window(FormattedTextControl(self._get_arg_text), height=1), + dyncond("multiline") & has_arg, + ), + ConditionalContainer(search_toolbar, dyncond("multiline") & ~is_done), + bottom_toolbar, + ] + ) + + return Layout(layout, default_buffer_window) + + def _create_application( + self, editing_mode: EditingMode, erase_when_done: bool + ) -> Application[_T]: + """ + Create the `Application` object. + """ + dyncond = self._dyncond + + # Default key bindings. + auto_suggest_bindings = load_auto_suggest_bindings() + open_in_editor_bindings = load_open_in_editor_bindings() + prompt_bindings = self._create_prompt_bindings() + + # Create application + application: Application[_T] = Application( + layout=self.layout, + style=DynamicStyle(lambda: self.style), + style_transformation=merge_style_transformations( + [ + DynamicStyleTransformation(lambda: self.style_transformation), + ConditionalStyleTransformation( + SwapLightAndDarkStyleTransformation(), + dyncond("swap_light_and_dark_colors"), + ), + ] + ), + include_default_pygments_style=dyncond("include_default_pygments_style"), + clipboard=DynamicClipboard(lambda: self.clipboard), + key_bindings=merge_key_bindings( + [ + merge_key_bindings( + [ + auto_suggest_bindings, + ConditionalKeyBindings( + open_in_editor_bindings, + dyncond("enable_open_in_editor") + & has_focus(DEFAULT_BUFFER), + ), + prompt_bindings, + ] + ), + DynamicKeyBindings(lambda: self.key_bindings), + ] + ), + mouse_support=dyncond("mouse_support"), + editing_mode=editing_mode, + erase_when_done=erase_when_done, + reverse_vi_search_direction=True, + color_depth=lambda: self.color_depth, + refresh_interval=self.refresh_interval, + input=self._input, + output=self._output, + ) + + # During render time, make sure that we focus the right search control + # (if we are searching). - This could be useful if people make the + # 'multiline' property dynamic. + """ + def on_render(app): + multiline = is_true(self.multiline) + current_control = app.layout.current_control + + if multiline: + if current_control == search_buffer_control: + app.layout.current_control = search_toolbar.control + app.invalidate() + else: + if current_control == search_toolbar.control: + app.layout.current_control = search_buffer_control + app.invalidate() + + app.on_render += on_render + """ + + return application + + def _create_prompt_bindings(self) -> KeyBindings: + """ + Create the KeyBindings for a prompt application. + """ + kb = KeyBindings() + handle = kb.add + default_focused = has_focus(DEFAULT_BUFFER) + + @Condition + def do_accept() -> bool: + return not is_true(self.multiline) and self.app.layout.has_focus( + DEFAULT_BUFFER + ) + + @handle("enter", filter=do_accept & default_focused) + def _accept_input(event: E) -> None: + " Accept input when enter has been pressed. " + self.default_buffer.validate_and_handle() + + @Condition + def readline_complete_style() -> bool: + return self.complete_style == CompleteStyle.READLINE_LIKE + + @handle("tab", filter=readline_complete_style & default_focused) + def _complete_like_readline(event: E) -> None: + " Display completions (like Readline). " + display_completions_like_readline(event) + + @handle("c-c", filter=default_focused) + def _keyboard_interrupt(event: E) -> None: + " Abort when Control-C has been pressed. " + event.app.exit(exception=KeyboardInterrupt, style="class:aborting") + + @Condition + def ctrl_d_condition() -> bool: + """Ctrl-D binding is only active when the default buffer is selected + and empty.""" + app = get_app() + return ( + app.current_buffer.name == DEFAULT_BUFFER + and not app.current_buffer.text + ) + + @handle("c-d", filter=ctrl_d_condition & default_focused) + def _eof(event: E) -> None: + " Exit when Control-D has been pressed. " + event.app.exit(exception=EOFError, style="class:exiting") + + suspend_supported = Condition(suspend_to_background_supported) + + @Condition + def enable_suspend() -> bool: + return to_filter(self.enable_suspend)() + + @handle("c-z", filter=suspend_supported & enable_suspend) + def _suspend(event: E) -> None: + """ + Suspend process to background. + """ + event.app.suspend_to_background() + + return kb + + def prompt( + self, + # When any of these arguments are passed, this value is overwritten + # in this PromptSession. + message: Optional[AnyFormattedText] = None, + # `message` should go first, because people call it as + # positional argument. + *, + editing_mode: Optional[EditingMode] = None, + refresh_interval: Optional[float] = None, + vi_mode: Optional[bool] = None, + lexer: Optional[Lexer] = None, + completer: Optional[Completer] = None, + complete_in_thread: Optional[bool] = None, + is_password: Optional[bool] = None, + key_bindings: Optional[KeyBindingsBase] = None, + bottom_toolbar: Optional[AnyFormattedText] = None, + style: Optional[BaseStyle] = None, + color_depth: Optional[ColorDepth] = None, + include_default_pygments_style: Optional[FilterOrBool] = None, + style_transformation: Optional[StyleTransformation] = None, + swap_light_and_dark_colors: Optional[FilterOrBool] = None, + rprompt: Optional[AnyFormattedText] = None, + multiline: Optional[FilterOrBool] = None, + prompt_continuation: Optional[PromptContinuationText] = None, + wrap_lines: Optional[FilterOrBool] = None, + enable_history_search: Optional[FilterOrBool] = None, + search_ignore_case: Optional[FilterOrBool] = None, + complete_while_typing: Optional[FilterOrBool] = None, + validate_while_typing: Optional[FilterOrBool] = None, + complete_style: Optional[CompleteStyle] = None, + auto_suggest: Optional[AutoSuggest] = None, + validator: Optional[Validator] = None, + clipboard: Optional[Clipboard] = None, + mouse_support: Optional[FilterOrBool] = None, + input_processors: Optional[List[Processor]] = None, + placeholder: Optional[AnyFormattedText] = None, + reserve_space_for_menu: Optional[int] = None, + enable_system_prompt: Optional[FilterOrBool] = None, + enable_suspend: Optional[FilterOrBool] = None, + enable_open_in_editor: Optional[FilterOrBool] = None, + tempfile_suffix: Optional[Union[str, Callable[[], str]]] = None, + tempfile: Optional[Union[str, Callable[[], str]]] = None, + # Following arguments are specific to the current `prompt()` call. + default: Union[str, Document] = "", + accept_default: bool = False, + pre_run: Optional[Callable[[], None]] = None, + set_exception_handler: bool = True, + ) -> _T: + """ + Display the prompt. + + The first set of arguments is a subset of the :class:`~.PromptSession` + class itself. For these, passing in ``None`` will keep the current + values that are active in the session. Passing in a value will set the + attribute for the session, which means that it applies to the current, + but also to the next prompts. + + Note that in order to erase a ``Completer``, ``Validator`` or + ``AutoSuggest``, you can't use ``None``. Instead pass in a + ``DummyCompleter``, ``DummyValidator`` or ``DummyAutoSuggest`` instance + respectively. For a ``Lexer`` you can pass in an empty ``SimpleLexer``. + + Additional arguments, specific for this prompt: + + :param default: The default input text to be shown. (This can be edited + by the user). + :param accept_default: When `True`, automatically accept the default + value without allowing the user to edit the input. + :param pre_run: Callable, called at the start of `Application.run`. + + This method will raise ``KeyboardInterrupt`` when control-c has been + pressed (for abort) and ``EOFError`` when control-d has been pressed + (for exit). + """ + # NOTE: We used to create a backup of the PromptSession attributes and + # restore them after exiting the prompt. This code has been + # removed, because it was confusing and didn't really serve a use + # case. (People were changing `Application.editing_mode` + # dynamically and surprised that it was reset after every call.) + + # NOTE 2: YES, this is a lot of repeation below... + # However, it is a very convenient for a user to accept all + # these parameters in this `prompt` method as well. We could + # use `locals()` and `setattr` to avoid the repetition, but + # then we loose the advantage of mypy and pyflakes to be able + # to verify the code. + if message is not None: + self.message = message + if editing_mode is not None: + self.editing_mode = editing_mode + if refresh_interval is not None: + self.refresh_interval = refresh_interval + if vi_mode: + self.editing_mode = EditingMode.VI + if lexer is not None: + self.lexer = lexer + if completer is not None: + self.completer = completer + if complete_in_thread is not None: + self.complete_in_thread = complete_in_thread + if is_password is not None: + self.is_password = is_password + if key_bindings is not None: + self.key_bindings = key_bindings + if bottom_toolbar is not None: + self.bottom_toolbar = bottom_toolbar + if style is not None: + self.style = style + if color_depth is not None: + self.color_depth = color_depth + if include_default_pygments_style is not None: + self.include_default_pygments_style = include_default_pygments_style + if style_transformation is not None: + self.style_transformation = style_transformation + if swap_light_and_dark_colors is not None: + self.swap_light_and_dark_colors = swap_light_and_dark_colors + if rprompt is not None: + self.rprompt = rprompt + if multiline is not None: + self.multiline = multiline + if prompt_continuation is not None: + self.prompt_continuation = prompt_continuation + if wrap_lines is not None: + self.wrap_lines = wrap_lines + if enable_history_search is not None: + self.enable_history_search = enable_history_search + if search_ignore_case is not None: + self.search_ignore_case = search_ignore_case + if complete_while_typing is not None: + self.complete_while_typing = complete_while_typing + if validate_while_typing is not None: + self.validate_while_typing = validate_while_typing + if complete_style is not None: + self.complete_style = complete_style + if auto_suggest is not None: + self.auto_suggest = auto_suggest + if validator is not None: + self.validator = validator + if clipboard is not None: + self.clipboard = clipboard + if mouse_support is not None: + self.mouse_support = mouse_support + if input_processors is not None: + self.input_processors = input_processors + if placeholder is not None: + self.placeholder = placeholder + if reserve_space_for_menu is not None: + self.reserve_space_for_menu = reserve_space_for_menu + if enable_system_prompt is not None: + self.enable_system_prompt = enable_system_prompt + if enable_suspend is not None: + self.enable_suspend = enable_suspend + if enable_open_in_editor is not None: + self.enable_open_in_editor = enable_open_in_editor + if tempfile_suffix is not None: + self.tempfile_suffix = tempfile_suffix + if tempfile is not None: + self.tempfile = tempfile + + self._add_pre_run_callables(pre_run, accept_default) + self.default_buffer.reset( + default if isinstance(default, Document) else Document(default) + ) + self.app.refresh_interval = self.refresh_interval # This is not reactive. + + # If we are using the default output, and have a dumb terminal. Use the + # dumb prompt. + if self._output is None and is_dumb_terminal(): + return get_event_loop().run_until_complete(self._dumb_prompt(self.message)) + + return self.app.run(set_exception_handler=set_exception_handler) + + async def _dumb_prompt(self, message: AnyFormattedText = "") -> _T: + """ + Prompt function for dumb terminals. + + Dumb terminals have minimum rendering capabilities. We can only print + text to the screen. We can't use colors, and we can't do cursor + movements. The Emacs inferior shell is an example of a dumb terminal. + + We will show the prompt, and wait for the input. We still handle arrow + keys, and all custom key bindings, but we don't really render the + cursor movements. Instead we only print the typed character that's + right before the cursor. + """ + # Send prompt to output. + self.output.write(fragment_list_to_text(to_formatted_text(self.message))) + self.output.flush() + + # Key bindings for the dumb prompt: mostly the same as the full prompt. + key_bindings: KeyBindingsBase = self._create_prompt_bindings() + if self.key_bindings: + key_bindings = merge_key_bindings([self.key_bindings, key_bindings]) + + # Create and run application. + application = cast( + Application[_T], + Application( + input=self.input, + output=DummyOutput(), + layout=self.layout, + key_bindings=key_bindings, + ), + ) + + def on_text_changed(_) -> None: + self.output.write(self.default_buffer.document.text_before_cursor[-1:]) + self.output.flush() + + self.default_buffer.on_text_changed += on_text_changed + result = await application.run_async() + + # Render line ending. + self.output.write("\r\n") + self.output.flush() + + return result + + async def prompt_async( + self, + # When any of these arguments are passed, this value is overwritten + # in this PromptSession. + message: Optional[AnyFormattedText] = None, + # `message` should go first, because people call it as + # positional argument. + *, + editing_mode: Optional[EditingMode] = None, + refresh_interval: Optional[float] = None, + vi_mode: Optional[bool] = None, + lexer: Optional[Lexer] = None, + completer: Optional[Completer] = None, + complete_in_thread: Optional[bool] = None, + is_password: Optional[bool] = None, + key_bindings: Optional[KeyBindingsBase] = None, + bottom_toolbar: Optional[AnyFormattedText] = None, + style: Optional[BaseStyle] = None, + color_depth: Optional[ColorDepth] = None, + include_default_pygments_style: Optional[FilterOrBool] = None, + style_transformation: Optional[StyleTransformation] = None, + swap_light_and_dark_colors: Optional[FilterOrBool] = None, + rprompt: Optional[AnyFormattedText] = None, + multiline: Optional[FilterOrBool] = None, + prompt_continuation: Optional[PromptContinuationText] = None, + wrap_lines: Optional[FilterOrBool] = None, + enable_history_search: Optional[FilterOrBool] = None, + search_ignore_case: Optional[FilterOrBool] = None, + complete_while_typing: Optional[FilterOrBool] = None, + validate_while_typing: Optional[FilterOrBool] = None, + complete_style: Optional[CompleteStyle] = None, + auto_suggest: Optional[AutoSuggest] = None, + validator: Optional[Validator] = None, + clipboard: Optional[Clipboard] = None, + mouse_support: Optional[FilterOrBool] = None, + input_processors: Optional[List[Processor]] = None, + placeholder: Optional[AnyFormattedText] = None, + reserve_space_for_menu: Optional[int] = None, + enable_system_prompt: Optional[FilterOrBool] = None, + enable_suspend: Optional[FilterOrBool] = None, + enable_open_in_editor: Optional[FilterOrBool] = None, + tempfile_suffix: Optional[Union[str, Callable[[], str]]] = None, + tempfile: Optional[Union[str, Callable[[], str]]] = None, + # Following arguments are specific to the current `prompt()` call. + default: Union[str, Document] = "", + accept_default: bool = False, + pre_run: Optional[Callable[[], None]] = None, + set_exception_handler: bool = True, + ) -> _T: + + if message is not None: + self.message = message + if editing_mode is not None: + self.editing_mode = editing_mode + if refresh_interval is not None: + self.refresh_interval = refresh_interval + if vi_mode: + self.editing_mode = EditingMode.VI + if lexer is not None: + self.lexer = lexer + if completer is not None: + self.completer = completer + if complete_in_thread is not None: + self.complete_in_thread = complete_in_thread + if is_password is not None: + self.is_password = is_password + if key_bindings is not None: + self.key_bindings = key_bindings + if bottom_toolbar is not None: + self.bottom_toolbar = bottom_toolbar + if style is not None: + self.style = style + if color_depth is not None: + self.color_depth = color_depth + if include_default_pygments_style is not None: + self.include_default_pygments_style = include_default_pygments_style + if style_transformation is not None: + self.style_transformation = style_transformation + if swap_light_and_dark_colors is not None: + self.swap_light_and_dark_colors = swap_light_and_dark_colors + if rprompt is not None: + self.rprompt = rprompt + if multiline is not None: + self.multiline = multiline + if prompt_continuation is not None: + self.prompt_continuation = prompt_continuation + if wrap_lines is not None: + self.wrap_lines = wrap_lines + if enable_history_search is not None: + self.enable_history_search = enable_history_search + if search_ignore_case is not None: + self.search_ignore_case = search_ignore_case + if complete_while_typing is not None: + self.complete_while_typing = complete_while_typing + if validate_while_typing is not None: + self.validate_while_typing = validate_while_typing + if complete_style is not None: + self.complete_style = complete_style + if auto_suggest is not None: + self.auto_suggest = auto_suggest + if validator is not None: + self.validator = validator + if clipboard is not None: + self.clipboard = clipboard + if mouse_support is not None: + self.mouse_support = mouse_support + if input_processors is not None: + self.input_processors = input_processors + if placeholder is not None: + self.placeholder = placeholder + if reserve_space_for_menu is not None: + self.reserve_space_for_menu = reserve_space_for_menu + if enable_system_prompt is not None: + self.enable_system_prompt = enable_system_prompt + if enable_suspend is not None: + self.enable_suspend = enable_suspend + if enable_open_in_editor is not None: + self.enable_open_in_editor = enable_open_in_editor + if tempfile_suffix is not None: + self.tempfile_suffix = tempfile_suffix + if tempfile is not None: + self.tempfile = tempfile + + self._add_pre_run_callables(pre_run, accept_default) + self.default_buffer.reset( + default if isinstance(default, Document) else Document(default) + ) + self.app.refresh_interval = self.refresh_interval # This is not reactive. + + # If we are using the default output, and have a dumb terminal. Use the + # dumb prompt. + if self._output is None and is_dumb_terminal(): + return await self._dumb_prompt(self.message) + + return await self.app.run_async(set_exception_handler=set_exception_handler) + + def _add_pre_run_callables( + self, pre_run: Optional[Callable[[], None]], accept_default: bool + ) -> None: + def pre_run2() -> None: + if pre_run: + pre_run() + + if accept_default: + # Validate and handle input. We use `call_from_executor` in + # order to run it "soon" (during the next iteration of the + # event loop), instead of right now. Otherwise, it won't + # display the default value. + get_event_loop().call_soon(self.default_buffer.validate_and_handle) + + self.app.pre_run_callables.append(pre_run2) + + @property + def editing_mode(self) -> EditingMode: + return self.app.editing_mode + + @editing_mode.setter + def editing_mode(self, value: EditingMode) -> None: + self.app.editing_mode = value + + def _get_default_buffer_control_height(self) -> Dimension: + # If there is an autocompletion menu to be shown, make sure that our + # layout has at least a minimal height in order to display it. + if ( + self.completer is not None + and self.complete_style != CompleteStyle.READLINE_LIKE + ): + space = self.reserve_space_for_menu + else: + space = 0 + + if space and not get_app().is_done: + buff = self.default_buffer + + # Reserve the space, either when there are completions, or when + # `complete_while_typing` is true and we expect completions very + # soon. + if buff.complete_while_typing() or buff.complete_state is not None: + return Dimension(min=space) + + return Dimension() + + def _get_prompt(self) -> StyleAndTextTuples: + return to_formatted_text(self.message, style="class:prompt") + + def _get_continuation( + self, width: int, line_number: int, wrap_count: int + ) -> StyleAndTextTuples: + """ + Insert the prompt continuation. + + :param width: The width that was used for the prompt. (more or less can + be used.) + :param line_number: + :param wrap_count: Amount of times that the line has been wrapped. + """ + prompt_continuation = self.prompt_continuation + + if callable(prompt_continuation): + continuation: AnyFormattedText = prompt_continuation( + width, line_number, wrap_count + ) + else: + continuation = prompt_continuation + + # When the continuation prompt is not given, choose the same width as + # the actual prompt. + if continuation is None and is_true(self.multiline): + continuation = " " * width + + return to_formatted_text(continuation, style="class:prompt-continuation") + + def _get_line_prefix( + self, + line_number: int, + wrap_count: int, + get_prompt_text_2: _StyleAndTextTuplesCallable, + ) -> StyleAndTextTuples: + """ + Return whatever needs to be inserted before every line. + (the prompt, or a line continuation.) + """ + # First line: display the "arg" or the prompt. + if line_number == 0 and wrap_count == 0: + if not is_true(self.multiline) and get_app().key_processor.arg is not None: + return self._inline_arg() + else: + return get_prompt_text_2() + + # For the next lines, display the appropriate continuation. + prompt_width = get_cwidth(fragment_list_to_text(get_prompt_text_2())) + return self._get_continuation(prompt_width, line_number, wrap_count) + + def _get_arg_text(self) -> StyleAndTextTuples: + " 'arg' toolbar, for in multiline mode. " + arg = self.app.key_processor.arg + if arg is None: + # Should not happen because of the `has_arg` filter in the layout. + return [] + + if arg == "-": + arg = "-1" + + return [("class:arg-toolbar", "Repeat: "), ("class:arg-toolbar.text", arg)] + + def _inline_arg(self) -> StyleAndTextTuples: + " 'arg' prefix, for in single line mode. " + app = get_app() + if app.key_processor.arg is None: + return [] + else: + arg = app.key_processor.arg + + return [ + ("class:prompt.arg", "(arg: "), + ("class:prompt.arg.text", str(arg)), + ("class:prompt.arg", ") "), + ] + + # Expose the Input and Output objects as attributes, mainly for + # backward-compatibility. + + @property + def input(self) -> Input: + return self.app.input + + @property + def output(self) -> Output: + return self.app.output + + +def prompt( + message: Optional[AnyFormattedText] = None, + *, + history: Optional[History] = None, + editing_mode: Optional[EditingMode] = None, + refresh_interval: Optional[float] = None, + vi_mode: Optional[bool] = None, + lexer: Optional[Lexer] = None, + completer: Optional[Completer] = None, + complete_in_thread: Optional[bool] = None, + is_password: Optional[bool] = None, + key_bindings: Optional[KeyBindingsBase] = None, + bottom_toolbar: Optional[AnyFormattedText] = None, + style: Optional[BaseStyle] = None, + color_depth: Optional[ColorDepth] = None, + include_default_pygments_style: Optional[FilterOrBool] = None, + style_transformation: Optional[StyleTransformation] = None, + swap_light_and_dark_colors: Optional[FilterOrBool] = None, + rprompt: Optional[AnyFormattedText] = None, + multiline: Optional[FilterOrBool] = None, + prompt_continuation: Optional[PromptContinuationText] = None, + wrap_lines: Optional[FilterOrBool] = None, + enable_history_search: Optional[FilterOrBool] = None, + search_ignore_case: Optional[FilterOrBool] = None, + complete_while_typing: Optional[FilterOrBool] = None, + validate_while_typing: Optional[FilterOrBool] = None, + complete_style: Optional[CompleteStyle] = None, + auto_suggest: Optional[AutoSuggest] = None, + validator: Optional[Validator] = None, + clipboard: Optional[Clipboard] = None, + mouse_support: Optional[FilterOrBool] = None, + input_processors: Optional[List[Processor]] = None, + placeholder: Optional[AnyFormattedText] = None, + reserve_space_for_menu: Optional[int] = None, + enable_system_prompt: Optional[FilterOrBool] = None, + enable_suspend: Optional[FilterOrBool] = None, + enable_open_in_editor: Optional[FilterOrBool] = None, + tempfile_suffix: Optional[Union[str, Callable[[], str]]] = None, + tempfile: Optional[Union[str, Callable[[], str]]] = None, + # Following arguments are specific to the current `prompt()` call. + default: str = "", + accept_default: bool = False, + pre_run: Optional[Callable[[], None]] = None, +) -> str: + """ + The global `prompt` function. This will create a new `PromptSession` + instance for every call. + """ + # The history is the only attribute that has to be passed to the + # `PromptSession`, it can't be passed into the `prompt()` method. + session: PromptSession[str] = PromptSession(history=history) + + return session.prompt( + message, + editing_mode=editing_mode, + refresh_interval=refresh_interval, + vi_mode=vi_mode, + lexer=lexer, + completer=completer, + complete_in_thread=complete_in_thread, + is_password=is_password, + key_bindings=key_bindings, + bottom_toolbar=bottom_toolbar, + style=style, + color_depth=color_depth, + include_default_pygments_style=include_default_pygments_style, + style_transformation=style_transformation, + swap_light_and_dark_colors=swap_light_and_dark_colors, + rprompt=rprompt, + multiline=multiline, + prompt_continuation=prompt_continuation, + wrap_lines=wrap_lines, + enable_history_search=enable_history_search, + search_ignore_case=search_ignore_case, + complete_while_typing=complete_while_typing, + validate_while_typing=validate_while_typing, + complete_style=complete_style, + auto_suggest=auto_suggest, + validator=validator, + clipboard=clipboard, + mouse_support=mouse_support, + input_processors=input_processors, + placeholder=placeholder, + reserve_space_for_menu=reserve_space_for_menu, + enable_system_prompt=enable_system_prompt, + enable_suspend=enable_suspend, + enable_open_in_editor=enable_open_in_editor, + tempfile_suffix=tempfile_suffix, + tempfile=tempfile, + default=default, + accept_default=accept_default, + pre_run=pre_run, + ) + + +prompt.__doc__ = PromptSession.prompt.__doc__ + + +def create_confirm_session( + message: str, suffix: str = " (y/n) " +) -> PromptSession[bool]: + """ + Create a `PromptSession` object for the 'confirm' function. + """ + bindings = KeyBindings() + + @bindings.add("y") + @bindings.add("Y") + def yes(event: E) -> None: + session.default_buffer.text = "y" + event.app.exit(result=True) + + @bindings.add("n") + @bindings.add("N") + def no(event: E) -> None: + session.default_buffer.text = "n" + event.app.exit(result=False) + + @bindings.add(Keys.Any) + def _(event: E) -> None: + " Disallow inserting other text. " + pass + + complete_message = merge_formatted_text([message, suffix]) + session: PromptSession[bool] = PromptSession( + complete_message, key_bindings=bindings + ) + return session + + +def confirm(message: str = "Confirm?", suffix: str = " (y/n) ") -> bool: + """ + Display a confirmation prompt that returns True/False. + """ + session = create_confirm_session(message, suffix) + return session.prompt() diff --git a/.venv/lib/python3.8/site-packages/prompt_toolkit/shortcuts/utils.py b/.venv/lib/python3.8/site-packages/prompt_toolkit/shortcuts/utils.py new file mode 100644 index 00000000..3cd49b81 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/prompt_toolkit/shortcuts/utils.py @@ -0,0 +1,198 @@ +from asyncio import get_event_loop +from typing import TYPE_CHECKING, Any, Optional, TextIO + +from prompt_toolkit.application import Application +from prompt_toolkit.application.current import get_app_session +from prompt_toolkit.formatted_text import ( + FormattedText, + StyleAndTextTuples, + to_formatted_text, +) +from prompt_toolkit.input import DummyInput +from prompt_toolkit.layout import Layout +from prompt_toolkit.output import ColorDepth, Output +from prompt_toolkit.output.defaults import create_output +from prompt_toolkit.renderer import ( + print_formatted_text as renderer_print_formatted_text, +) +from prompt_toolkit.styles import ( + BaseStyle, + StyleTransformation, + default_pygments_style, + default_ui_style, + merge_styles, +) + +if TYPE_CHECKING: + from prompt_toolkit.layout.containers import Container + +__all__ = [ + "print_formatted_text", + "print_container", + "clear", + "set_title", + "clear_title", +] + + +def print_formatted_text( + *values: Any, + sep: str = " ", + end: str = "\n", + file: Optional[TextIO] = None, + flush: bool = False, + style: Optional[BaseStyle] = None, + output: Optional[Output] = None, + color_depth: Optional[ColorDepth] = None, + style_transformation: Optional[StyleTransformation] = None, + include_default_pygments_style: bool = True, +) -> None: + """ + :: + + print_formatted_text(*values, sep=' ', end='\\n', file=None, flush=False, style=None, output=None) + + Print text to stdout. This is supposed to be compatible with Python's print + function, but supports printing of formatted text. You can pass a + :class:`~prompt_toolkit.formatted_text.FormattedText`, + :class:`~prompt_toolkit.formatted_text.HTML` or + :class:`~prompt_toolkit.formatted_text.ANSI` object to print formatted + text. + + * Print HTML as follows:: + + print_formatted_text(HTML('Some italic text This is red!')) + + style = Style.from_dict({ + 'hello': '#ff0066', + 'world': '#884444 italic', + }) + print_formatted_text(HTML('Hello world!'), style=style) + + * Print a list of (style_str, text) tuples in the given style to the + output. E.g.:: + + style = Style.from_dict({ + 'hello': '#ff0066', + 'world': '#884444 italic', + }) + fragments = FormattedText([ + ('class:hello', 'Hello'), + ('class:world', 'World'), + ]) + print_formatted_text(fragments, style=style) + + If you want to print a list of Pygments tokens, wrap it in + :class:`~prompt_toolkit.formatted_text.PygmentsTokens` to do the + conversion. + + :param values: Any kind of printable object, or formatted string. + :param sep: String inserted between values, default a space. + :param end: String appended after the last value, default a newline. + :param style: :class:`.Style` instance for the color scheme. + :param include_default_pygments_style: `bool`. Include the default Pygments + style when set to `True` (the default). + """ + assert not (output and file) + + # Build/merge style. + styles = [default_ui_style()] + if include_default_pygments_style: + styles.append(default_pygments_style()) + if style: + styles.append(style) + + merged_style = merge_styles(styles) + + # Create Output object. + if output is None: + if file: + output = create_output(stdout=file) + else: + output = get_app_session().output + + assert isinstance(output, Output) + + # Get color depth. + color_depth = color_depth or output.get_default_color_depth() + + # Merges values. + def to_text(val: Any) -> StyleAndTextTuples: + # Normal lists which are not instances of `FormattedText` are + # considered plain text. + if isinstance(val, list) and not isinstance(val, FormattedText): + return to_formatted_text("{0}".format(val)) + return to_formatted_text(val, auto_convert=True) + + fragments = [] + for i, value in enumerate(values): + fragments.extend(to_text(value)) + + if sep and i != len(values) - 1: + fragments.extend(to_text(sep)) + + fragments.extend(to_text(end)) + + # Print output. + renderer_print_formatted_text( + output, + fragments, + merged_style, + color_depth=color_depth, + style_transformation=style_transformation, + ) + + # Flush the output stream. + if flush: + output.flush() + + +def print_container(container: "Container", file: Optional[TextIO] = None) -> None: + """ + Print any layout to the output in a non-interactive way. + + Example usage:: + + from prompt_toolkit.widgets import Frame, TextArea + print_container( + Frame(TextArea(text='Hello world!'))) + """ + if file: + output = create_output(stdout=file) + else: + output = get_app_session().output + + def exit_immediately() -> None: + # Use `call_from_executor` to exit "soon", so that we still render one + # initial time, before exiting the application. + get_event_loop().call_soon(lambda: app.exit()) + + app: Application[None] = Application( + layout=Layout(container=container), output=output, input=DummyInput() + ) + app.run(pre_run=exit_immediately) + + +def clear() -> None: + """ + Clear the screen. + """ + output = get_app_session().output + output.erase_screen() + output.cursor_goto(0, 0) + output.flush() + + +def set_title(text: str) -> None: + """ + Set the terminal title. + """ + output = get_app_session().output + output.set_title(text) + + +def clear_title() -> None: + """ + Erase the current title. + """ + set_title("") diff --git a/.venv/lib/python3.8/site-packages/prompt_toolkit/styles/__init__.py b/.venv/lib/python3.8/site-packages/prompt_toolkit/styles/__init__.py new file mode 100644 index 00000000..c270ae01 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/prompt_toolkit/styles/__init__.py @@ -0,0 +1,64 @@ +""" +Styling for prompt_toolkit applications. +""" +from .base import ( + ANSI_COLOR_NAMES, + DEFAULT_ATTRS, + Attrs, + BaseStyle, + DummyStyle, + DynamicStyle, +) +from .defaults import default_pygments_style, default_ui_style +from .named_colors import NAMED_COLORS +from .pygments import ( + pygments_token_to_classname, + style_from_pygments_cls, + style_from_pygments_dict, +) +from .style import Priority, Style, merge_styles, parse_color +from .style_transformation import ( + AdjustBrightnessStyleTransformation, + ConditionalStyleTransformation, + DummyStyleTransformation, + DynamicStyleTransformation, + ReverseStyleTransformation, + SetDefaultColorStyleTransformation, + StyleTransformation, + SwapLightAndDarkStyleTransformation, + merge_style_transformations, +) + +__all__ = [ + # Base. + "Attrs", + "DEFAULT_ATTRS", + "ANSI_COLOR_NAMES", + "BaseStyle", + "DummyStyle", + "DynamicStyle", + # Defaults. + "default_ui_style", + "default_pygments_style", + # Style. + "Style", + "Priority", + "merge_styles", + "parse_color", + # Style transformation. + "StyleTransformation", + "SwapLightAndDarkStyleTransformation", + "ReverseStyleTransformation", + "SetDefaultColorStyleTransformation", + "AdjustBrightnessStyleTransformation", + "DummyStyleTransformation", + "ConditionalStyleTransformation", + "DynamicStyleTransformation", + "merge_style_transformations", + # Pygments. + "style_from_pygments_cls", + "style_from_pygments_dict", + "pygments_token_to_classname", + # Named colors. + "NAMED_COLORS", +] diff --git a/.venv/lib/python3.8/site-packages/prompt_toolkit/styles/__pycache__/__init__.cpython-38.pyc b/.venv/lib/python3.8/site-packages/prompt_toolkit/styles/__pycache__/__init__.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..07b272ba9b77a514146076959857c657135ea9cd GIT binary patch literal 1353 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 literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/prompt_toolkit/styles/__pycache__/defaults.cpython-38.pyc b/.venv/lib/python3.8/site-packages/prompt_toolkit/styles/__pycache__/defaults.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..5c07043e17b0994a388d06471d2b39c52188f257 GIT binary patch literal 6163 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 M%Jq^yJyFvC3&;LSIRF3v literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/prompt_toolkit/styles/__pycache__/named_colors.cpython-38.pyc b/.venv/lib/python3.8/site-packages/prompt_toolkit/styles/__pycache__/named_colors.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c908a754455c5370aaef00c9391b060accc665fc GIT binary patch literal 3882 zcmeHK*>>Z`5v3%G6scuAiL*E>6K9(wGXg;Z1SS*PS}e`P(nt|Co)}q}25v)y1p*uZ z6vN44XS1^}=QwZqf&5S&^qQxflP}1NQ`HShlec_8*oWw<>gw*QTeq9wqxJP>g+A}U z_4mQj%}V7TtUUYq3n{PAH}@7Ql}8m+yb2bu7%z+#y~TwJmd+NuB~-DD8tPa<15K=A z4eQvz4LpaN_y9hL=kXzY7#|^@kKzS<3?IiQ==({03ZF&`pTTGGB0h)D;|tWjh%ez5 zzKpL>`zmhZ4mM$+4HF%7VZla^o(^2x#n*5TU&l*$8Lwaq+t|S_Ud0~v>3bg!@D03% z18RqOh$9^1o3zpi`Z&cSypG5C7T$n|Z{s`oF208Wz7GK(0RV{*XBZ;Fn>a^|5fY>r z;|Vh4C@{eVruYG7c#0q5NBA**g17KCwV&c=_&I)oU*a9Si(lc__zixG-{JT81OE8e z_q?iHl*@8CTzsJ-YgoEh!Jqn-TYr9f(cFsT)+mL{lGarEEk8@AxyloI6CP+t-lx=p%aEI2#3KAfF$Kfrk(3Qd=sNG^`r6hXV&;oW&p$5(>mD}mOv4YmlEn;NpaYGogO&*mY=FK1bn z?VBp)&vqh5S7sk&k*;g^IA$mG1BacvP6ui)Gwf0$i(v#3Z4zAC2^|u`u-$c8 zFbrQKX1m&Tgi`V zedfE%Ia??h0bZF-F*OogLsHW09Qt;^K+!UWLe(^UQz&?QfmECJdXD2VP`(j#p_xD| z(+QR&p(3H9f+yfq7@WC+#kK>e1zA_2`ogkw7@eL0CO{|fJ3S7g=i83tEeLL+3kh8Z zZAE~f*R~waz3sN$o(kUL?8(BMmpTjC_1TAxhZJ+pt6GEztunB(D7NoNQ*%RDD%3FS zY5{@*V=$$Zjtbr-wz&>jL`XJ{kjQH&M$zse%1wpOKm~BD4znesDg~S%APjIkz9Fyi zQGwZZr=#FyC{-9tYfbF7?W(*SziYKssKPON3g@oq+6;mz9pB=UOITPcFkx7x$$Qb> z)JSlsl#;`+g{9fjBa)N^V0O?D^Sj3}cWuX1%mj6ceoSK(DxI}tPBQAYWppOJ+IEzaGpVr%&bCFc|=N&WMgTCctvjnqn7pf#GiDb7mh z8hcSDx3h>!wz@|@qaxPjUfoMGnHM_3`rafM=8^Ck`yxtmKh09Fxj#(vqT~j{NrP9Q zR@H{fdiJX7-jFdB%%c&CVC8MT`@eKrwA2eJV^z3Sj64$aVs?@ei&qZQAP{+! zc&iV^g?KY9X+_G+s~^QU5CI*2b=UJ~Xd$l8d;2OGD+$mFAKNhjPDy-K~sw$%z zxei#V*Wosg#aPS)1u&*bQUt@}Nf>(7W0_6p$)~G&98X4G^EjOn85OFv62bKo=}XF_ zRF^oQ24y%auey_TCd%6O>FpqN-c>moH(*B_zf_(fIZx8Pji!#O>*j4$E!V8Wh7P z=5TXNZ~fz9P|$1sc~oo?y<(Yf^4mQI`i=k2cy_sRkN#FnV)+vNhpXf!J!{pqrN#HF QwZ(=1xBmfww=4hp4?9?PTL1t6 literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/prompt_toolkit/styles/__pycache__/pygments.cpython-38.pyc b/.venv/lib/python3.8/site-packages/prompt_toolkit/styles/__pycache__/pygments.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a3cd5b824bee1772405739632c95232812c0317e GIT binary patch literal 2103 zcmbVNO>ZML7`A67A5D|AltR19#RsHzBsxV%90)AhrCR|)>Q>tBfe196j@@M1`C8ji zn<^E8a^k`t;LwWG{ub^W=7u=!UqC|ezMf9HX_pHV+40Bg*RP-FdF^MNPK&_z&v(E3 zzcvW@6FaYdHgq0BQ9nV&NuO}at(YcO-%9Mhoj84m5^i%Rt|j$;of2WmhhXEx4d^#v zj`CVOm$dpVXxDjzHwSiqUO0U29ualk`o-e&y#AxpZws5ZMd#2m;~g09@&=4|ag;AW ze~~w#zrf#kO5CNh-&&7&kn2pcLnsHMDCSW*V7bhaT>Co9;^Rm&rN^;Q@4_O?x z$K`&t+z(^5KJ6Go9C~o$!EL<+aEWUdoxQJjxBaazwzt0ea_95Hc^rkhaQ4QzcuB$H z1ubf3PZt_{*|A8AmD1sz9gEf1O>p%0&NLW}E&wWsCr~O45>a$^uTNd>V--tN>(U{F zUeu+~BbkO6Q}tQUK(TB=QSU-!ghCQ}PASpWgiPp#rS5C{2dbS3IjUVypwSL~1}6r> zr$fLs9BHOA7D^Fl0W|eYWW9aQgtO106o^bi@p>AWu{Pdkr00qCQdCIEdC(=f4`h(AyR7wYX}$yt(KfkZ5b#VS5_y$%sN8zdtvr=*NVp_O(TbEB z9T>EW?jxlHZR#Z7%%gl`l;%NrEcnLB zP>6WrqYr&OeEz|3b2f!HOIMrIIP$Ta14s9uC=8Nx+g8_-O=!7R(W&fwq+NDlbVjER z4Ah_)oxTr^0Xe4=a!IbpWAg3&Z>)3c+@8=&3YxVp=)^v>t|%qX+ZslVX6f1Y2Bxk5 zDbiQvh*DX9k_x7Wfo4gND`xVVWd}zhgzL%B1Gfy2B;oo}o@@4YouU?Lkw7j6c`i~e z=iw-Z9M_S{(C$x(E45bCOtu#_1E-;)tlq?hNSX&lA&R8tSc`Po0`^v*cNfE%Tz?x( zI3TzJICAR}^85!;zG6CDoGtwIjQF}@*k1aC^k1noDgO$zFP0-d8QN{d>Yod|giVNrvu z)ao|s$l1qG6pE5GnsmoqEE>Mgv(Wd8x*q4Sn?$swjTM^7Rje=z;ukw^lp< E0v?)Q^Z)<= literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/prompt_toolkit/styles/__pycache__/style.cpython-38.pyc b/.venv/lib/python3.8/site-packages/prompt_toolkit/styles/__pycache__/style.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a8e3101ec184d5f280528946b35c5e269a43a73b GIT binary patch literal 11011 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 literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/prompt_toolkit/styles/__pycache__/style_transformation.cpython-38.pyc b/.venv/lib/python3.8/site-packages/prompt_toolkit/styles/__pycache__/style_transformation.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f568a34177c8f225078a2fa11c20049fe2eb7326 GIT binary patch literal 12944 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 literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/prompt_toolkit/styles/base.py b/.venv/lib/python3.8/site-packages/prompt_toolkit/styles/base.py new file mode 100644 index 00000000..e28fb5a4 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/prompt_toolkit/styles/base.py @@ -0,0 +1,181 @@ +""" +The base classes for the styling. +""" +from abc import ABCMeta, abstractmethod, abstractproperty +from typing import Callable, Dict, Hashable, List, NamedTuple, Optional, Tuple + +__all__ = [ + "Attrs", + "DEFAULT_ATTRS", + "ANSI_COLOR_NAMES", + "ANSI_COLOR_NAMES_ALIASES", + "BaseStyle", + "DummyStyle", + "DynamicStyle", +] + + +#: Style attributes. +Attrs = NamedTuple( + "Attrs", + [ + ("color", Optional[str]), + ("bgcolor", Optional[str]), + ("bold", Optional[bool]), + ("underline", Optional[bool]), + ("italic", Optional[bool]), + ("blink", Optional[bool]), + ("reverse", Optional[bool]), + ("hidden", Optional[bool]), + ], +) + +""" +:param color: Hexadecimal string. E.g. '000000' or Ansi color name: e.g. 'ansiblue' +:param bgcolor: Hexadecimal string. E.g. 'ffffff' or Ansi color name: e.g. 'ansired' +:param bold: Boolean +:param underline: Boolean +:param italic: Boolean +:param blink: Boolean +:param reverse: Boolean +:param hidden: Boolean +""" + +#: The default `Attrs`. +DEFAULT_ATTRS = Attrs( + color="", + bgcolor="", + bold=False, + underline=False, + italic=False, + blink=False, + reverse=False, + hidden=False, +) + + +#: ``Attrs.bgcolor/fgcolor`` can be in either 'ffffff' format, or can be any of +#: the following in case we want to take colors from the 8/16 color palette. +#: Usually, in that case, the terminal application allows to configure the RGB +#: values for these names. +#: ISO 6429 colors +ANSI_COLOR_NAMES = [ + "ansidefault", + # Low intensity, dark. (One or two components 0x80, the other 0x00.) + "ansiblack", + "ansired", + "ansigreen", + "ansiyellow", + "ansiblue", + "ansimagenta", + "ansicyan", + "ansigray", + # High intensity, bright. (One or two components 0xff, the other 0x00. Not supported everywhere.) + "ansibrightblack", + "ansibrightred", + "ansibrightgreen", + "ansibrightyellow", + "ansibrightblue", + "ansibrightmagenta", + "ansibrightcyan", + "ansiwhite", +] + + +# People don't use the same ANSI color names everywhere. In prompt_toolkit 1.0 +# we used some unconventional names (which were contributed like that to +# Pygments). This is fixed now, but we still support the old names. + +# The table below maps the old aliases to the current names. +ANSI_COLOR_NAMES_ALIASES: Dict[str, str] = { + "ansidarkgray": "ansibrightblack", + "ansiteal": "ansicyan", + "ansiturquoise": "ansibrightcyan", + "ansibrown": "ansiyellow", + "ansipurple": "ansimagenta", + "ansifuchsia": "ansibrightmagenta", + "ansilightgray": "ansigray", + "ansidarkred": "ansired", + "ansidarkgreen": "ansigreen", + "ansidarkblue": "ansiblue", +} +assert set(ANSI_COLOR_NAMES_ALIASES.values()).issubset(set(ANSI_COLOR_NAMES)) +assert not (set(ANSI_COLOR_NAMES_ALIASES.keys()) & set(ANSI_COLOR_NAMES)) + + +class BaseStyle(metaclass=ABCMeta): + """ + Abstract base class for prompt_toolkit styles. + """ + + @abstractmethod + def get_attrs_for_style_str( + self, style_str: str, default: Attrs = DEFAULT_ATTRS + ) -> Attrs: + """ + Return :class:`.Attrs` for the given style string. + + :param style_str: The style string. This can contain inline styling as + well as classnames (e.g. "class:title"). + :param default: `Attrs` to be used if no styling was defined. + """ + + @abstractproperty + def style_rules(self) -> List[Tuple[str, str]]: + """ + The list of style rules, used to create this style. + (Required for `DynamicStyle` and `_MergedStyle` to work.) + """ + return [] + + @abstractmethod + def invalidation_hash(self) -> Hashable: + """ + Invalidation hash for the style. When this changes over time, the + renderer knows that something in the style changed, and that everything + has to be redrawn. + """ + + +class DummyStyle(BaseStyle): + """ + A style that doesn't style anything. + """ + + def get_attrs_for_style_str( + self, style_str: str, default: Attrs = DEFAULT_ATTRS + ) -> Attrs: + return default + + def invalidation_hash(self) -> Hashable: + return 1 # Always the same value. + + @property + def style_rules(self) -> List[Tuple[str, str]]: + return [] + + +class DynamicStyle(BaseStyle): + """ + Style class that can dynamically returns an other Style. + + :param get_style: Callable that returns a :class:`.Style` instance. + """ + + def __init__(self, get_style: Callable[[], Optional[BaseStyle]]): + self.get_style = get_style + self._dummy = DummyStyle() + + def get_attrs_for_style_str( + self, style_str: str, default: Attrs = DEFAULT_ATTRS + ) -> Attrs: + style = self.get_style() or self._dummy + + return style.get_attrs_for_style_str(style_str, default) + + def invalidation_hash(self) -> Hashable: + return (self.get_style() or self._dummy).invalidation_hash() + + @property + def style_rules(self) -> List[Tuple[str, str]]: + return (self.get_style() or self._dummy).style_rules diff --git a/.venv/lib/python3.8/site-packages/prompt_toolkit/styles/defaults.py b/.venv/lib/python3.8/site-packages/prompt_toolkit/styles/defaults.py new file mode 100644 index 00000000..92a0cb83 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/prompt_toolkit/styles/defaults.py @@ -0,0 +1,227 @@ +""" +The default styling. +""" +from prompt_toolkit.cache import memoized + +from .base import ANSI_COLOR_NAMES +from .named_colors import NAMED_COLORS +from .style import BaseStyle, Style, merge_styles + +__all__ = [ + "default_ui_style", + "default_pygments_style", +] + +#: Default styling. Mapping from classnames to their style definition. +PROMPT_TOOLKIT_STYLE = [ + # Highlighting of search matches in document. + ("search", "bg:ansibrightyellow ansiblack"), + ("search.current", ""), + # Incremental search. + ("incsearch", ""), + ("incsearch.current", "reverse"), + # Highlighting of select text in document. + ("selected", "reverse"), + ("cursor-column", "bg:#dddddd"), + ("cursor-line", "underline"), + ("color-column", "bg:#ccaacc"), + # Highlighting of matching brackets. + ("matching-bracket", ""), + ("matching-bracket.other", "#000000 bg:#aacccc"), + ("matching-bracket.cursor", "#ff8888 bg:#880000"), + # Styling of other cursors, in case of block editing. + ("multiple-cursors", "#000000 bg:#ccccaa"), + # Line numbers. + ("line-number", "#888888"), + ("line-number.current", "bold"), + ("tilde", "#8888ff"), + # Default prompt. + ("prompt", ""), + ("prompt.arg", "noinherit"), + ("prompt.arg.text", ""), + ("prompt.search", "noinherit"), + ("prompt.search.text", ""), + # Search toolbar. + ("search-toolbar", "bold"), + ("search-toolbar.text", "nobold"), + # System toolbar + ("system-toolbar", "bold"), + ("system-toolbar.text", "nobold"), + # "arg" toolbar. + ("arg-toolbar", "bold"), + ("arg-toolbar.text", "nobold"), + # Validation toolbar. + ("validation-toolbar", "bg:#550000 #ffffff"), + ("window-too-small", "bg:#550000 #ffffff"), + # Completions toolbar. + ("completion-toolbar", "bg:#bbbbbb #000000"), + ("completion-toolbar.arrow", "bg:#bbbbbb #000000 bold"), + ("completion-toolbar.completion", "bg:#bbbbbb #000000"), + ("completion-toolbar.completion.current", "bg:#444444 #ffffff"), + # Completions menu. + ("completion-menu", "bg:#bbbbbb #000000"), + ("completion-menu.completion", ""), + ("completion-menu.completion.current", "bg:#888888 #ffffff"), + ("completion-menu.meta.completion", "bg:#999999 #000000"), + ("completion-menu.meta.completion.current", "bg:#aaaaaa #000000"), + ("completion-menu.multi-column-meta", "bg:#aaaaaa #000000"), + # Fuzzy matches in completion menu (for FuzzyCompleter). + ("completion-menu.completion fuzzymatch.outside", "fg:#444444"), + ("completion-menu.completion fuzzymatch.inside", "bold"), + ("completion-menu.completion fuzzymatch.inside.character", "underline"), + ("completion-menu.completion.current fuzzymatch.outside", "fg:default"), + ("completion-menu.completion.current fuzzymatch.inside", "nobold"), + # Styling of readline-like completions. + ("readline-like-completions", ""), + ("readline-like-completions.completion", ""), + ("readline-like-completions.completion fuzzymatch.outside", "#888888"), + ("readline-like-completions.completion fuzzymatch.inside", ""), + ("readline-like-completions.completion fuzzymatch.inside.character", "underline"), + # Scrollbars. + ("scrollbar.background", "bg:#aaaaaa"), + ("scrollbar.button", "bg:#444444"), + ("scrollbar.arrow", "noinherit bold"), + # Start/end of scrollbars. Adding 'underline' here provides a nice little + # detail to the progress bar, but it doesn't look good on all terminals. + # ('scrollbar.start', 'underline #ffffff'), + # ('scrollbar.end', 'underline #000000'), + # Auto suggestion text. + ("auto-suggestion", "#666666"), + # Trailing whitespace and tabs. + ("trailing-whitespace", "#999999"), + ("tab", "#999999"), + # When Control-C/D has been pressed. Grayed. + ("aborting", "#888888 bg:default noreverse noitalic nounderline noblink"), + ("exiting", "#888888 bg:default noreverse noitalic nounderline noblink"), + # Entering a Vi digraph. + ("digraph", "#4444ff"), + # Control characters, like ^C, ^X. + ("control-character", "ansiblue"), + # Non-breaking space. + ("nbsp", "underline ansiyellow"), + # Default styling of HTML elements. + ("i", "italic"), + ("u", "underline"), + ("b", "bold"), + ("em", "italic"), + ("strong", "bold"), + ("hidden", "hidden"), + # It should be possible to use the style names in HTML. + # ... or .... + ("italic", "italic"), + ("underline", "underline"), + ("bold", "bold"), + ("reverse", "reverse"), + ("noitalic", "noitalic"), + ("nounderline", "nounderline"), + ("nobold", "nobold"), + ("noreverse", "noreverse"), + # Prompt bottom toolbar + ("bottom-toolbar", "reverse"), +] + + +# Style that will turn for instance the class 'red' into 'red'. +COLORS_STYLE = [(name, "fg:" + name) for name in ANSI_COLOR_NAMES] + [ + (name.lower(), "fg:" + name) for name in NAMED_COLORS +] + + +WIDGETS_STYLE = [ + # Dialog windows. + ("dialog", "bg:#4444ff"), + ("dialog.body", "bg:#ffffff #000000"), + ("dialog.body text-area", "bg:#cccccc"), + ("dialog.body text-area last-line", "underline"), + ("dialog frame.label", "#ff0000 bold"), + # Scrollbars in dialogs. + ("dialog.body scrollbar.background", ""), + ("dialog.body scrollbar.button", "bg:#000000"), + ("dialog.body scrollbar.arrow", ""), + ("dialog.body scrollbar.start", "nounderline"), + ("dialog.body scrollbar.end", "nounderline"), + # Buttons. + ("button", ""), + ("button.arrow", "bold"), + ("button.focused", "bg:#aa0000 #ffffff"), + # Menu bars. + ("menu-bar", "bg:#aaaaaa #000000"), + ("menu-bar.selected-item", "bg:#ffffff #000000"), + ("menu", "bg:#888888 #ffffff"), + ("menu.border", "#aaaaaa"), + ("menu.border shadow", "#444444"), + # Shadows. + ("dialog shadow", "bg:#000088"), + ("dialog.body shadow", "bg:#aaaaaa"), + ("progress-bar", "bg:#000088"), + ("progress-bar.used", "bg:#ff0000"), +] + + +# The default Pygments style, include this by default in case a Pygments lexer +# is used. +PYGMENTS_DEFAULT_STYLE = { + "pygments.whitespace": "#bbbbbb", + "pygments.comment": "italic #408080", + "pygments.comment.preproc": "noitalic #bc7a00", + "pygments.keyword": "bold #008000", + "pygments.keyword.pseudo": "nobold", + "pygments.keyword.type": "nobold #b00040", + "pygments.operator": "#666666", + "pygments.operator.word": "bold #aa22ff", + "pygments.name.builtin": "#008000", + "pygments.name.function": "#0000ff", + "pygments.name.class": "bold #0000ff", + "pygments.name.namespace": "bold #0000ff", + "pygments.name.exception": "bold #d2413a", + "pygments.name.variable": "#19177c", + "pygments.name.constant": "#880000", + "pygments.name.label": "#a0a000", + "pygments.name.entity": "bold #999999", + "pygments.name.attribute": "#7d9029", + "pygments.name.tag": "bold #008000", + "pygments.name.decorator": "#aa22ff", + # Note: In Pygments, Token.String is an alias for Token.Literal.String, + # and Token.Number as an alias for Token.Literal.Number. + "pygments.literal.string": "#ba2121", + "pygments.literal.string.doc": "italic", + "pygments.literal.string.interpol": "bold #bb6688", + "pygments.literal.string.escape": "bold #bb6622", + "pygments.literal.string.regex": "#bb6688", + "pygments.literal.string.symbol": "#19177c", + "pygments.literal.string.other": "#008000", + "pygments.literal.number": "#666666", + "pygments.generic.heading": "bold #000080", + "pygments.generic.subheading": "bold #800080", + "pygments.generic.deleted": "#a00000", + "pygments.generic.inserted": "#00a000", + "pygments.generic.error": "#ff0000", + "pygments.generic.emph": "italic", + "pygments.generic.strong": "bold", + "pygments.generic.prompt": "bold #000080", + "pygments.generic.output": "#888", + "pygments.generic.traceback": "#04d", + "pygments.error": "border:#ff0000", +} + + +@memoized() +def default_ui_style() -> BaseStyle: + """ + Create a default `Style` object. + """ + return merge_styles( + [ + Style(PROMPT_TOOLKIT_STYLE), + Style(COLORS_STYLE), + Style(WIDGETS_STYLE), + ] + ) + + +@memoized() +def default_pygments_style() -> Style: + """ + Create a `Style` object that contains the default Pygments style. + """ + return Style.from_dict(PYGMENTS_DEFAULT_STYLE) diff --git a/.venv/lib/python3.8/site-packages/prompt_toolkit/styles/named_colors.py b/.venv/lib/python3.8/site-packages/prompt_toolkit/styles/named_colors.py new file mode 100644 index 00000000..37bd6de4 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/prompt_toolkit/styles/named_colors.py @@ -0,0 +1,161 @@ +""" +All modern web browsers support these 140 color names. +Taken from: https://www.w3schools.com/colors/colors_names.asp +""" +from typing import Dict + +__all__ = [ + "NAMED_COLORS", +] + + +NAMED_COLORS: Dict[str, str] = { + "AliceBlue": "#f0f8ff", + "AntiqueWhite": "#faebd7", + "Aqua": "#00ffff", + "Aquamarine": "#7fffd4", + "Azure": "#f0ffff", + "Beige": "#f5f5dc", + "Bisque": "#ffe4c4", + "Black": "#000000", + "BlanchedAlmond": "#ffebcd", + "Blue": "#0000ff", + "BlueViolet": "#8a2be2", + "Brown": "#a52a2a", + "BurlyWood": "#deb887", + "CadetBlue": "#5f9ea0", + "Chartreuse": "#7fff00", + "Chocolate": "#d2691e", + "Coral": "#ff7f50", + "CornflowerBlue": "#6495ed", + "Cornsilk": "#fff8dc", + "Crimson": "#dc143c", + "Cyan": "#00ffff", + "DarkBlue": "#00008b", + "DarkCyan": "#008b8b", + "DarkGoldenRod": "#b8860b", + "DarkGray": "#a9a9a9", + "DarkGreen": "#006400", + "DarkGrey": "#a9a9a9", + "DarkKhaki": "#bdb76b", + "DarkMagenta": "#8b008b", + "DarkOliveGreen": "#556b2f", + "DarkOrange": "#ff8c00", + "DarkOrchid": "#9932cc", + "DarkRed": "#8b0000", + "DarkSalmon": "#e9967a", + "DarkSeaGreen": "#8fbc8f", + "DarkSlateBlue": "#483d8b", + "DarkSlateGray": "#2f4f4f", + "DarkSlateGrey": "#2f4f4f", + "DarkTurquoise": "#00ced1", + "DarkViolet": "#9400d3", + "DeepPink": "#ff1493", + "DeepSkyBlue": "#00bfff", + "DimGray": "#696969", + "DimGrey": "#696969", + "DodgerBlue": "#1e90ff", + "FireBrick": "#b22222", + "FloralWhite": "#fffaf0", + "ForestGreen": "#228b22", + "Fuchsia": "#ff00ff", + "Gainsboro": "#dcdcdc", + "GhostWhite": "#f8f8ff", + "Gold": "#ffd700", + "GoldenRod": "#daa520", + "Gray": "#808080", + "Green": "#008000", + "GreenYellow": "#adff2f", + "Grey": "#808080", + "HoneyDew": "#f0fff0", + "HotPink": "#ff69b4", + "IndianRed": "#cd5c5c", + "Indigo": "#4b0082", + "Ivory": "#fffff0", + "Khaki": "#f0e68c", + "Lavender": "#e6e6fa", + "LavenderBlush": "#fff0f5", + "LawnGreen": "#7cfc00", + "LemonChiffon": "#fffacd", + "LightBlue": "#add8e6", + "LightCoral": "#f08080", + "LightCyan": "#e0ffff", + "LightGoldenRodYellow": "#fafad2", + "LightGray": "#d3d3d3", + "LightGreen": "#90ee90", + "LightGrey": "#d3d3d3", + "LightPink": "#ffb6c1", + "LightSalmon": "#ffa07a", + "LightSeaGreen": "#20b2aa", + "LightSkyBlue": "#87cefa", + "LightSlateGray": "#778899", + "LightSlateGrey": "#778899", + "LightSteelBlue": "#b0c4de", + "LightYellow": "#ffffe0", + "Lime": "#00ff00", + "LimeGreen": "#32cd32", + "Linen": "#faf0e6", + "Magenta": "#ff00ff", + "Maroon": "#800000", + "MediumAquaMarine": "#66cdaa", + "MediumBlue": "#0000cd", + "MediumOrchid": "#ba55d3", + "MediumPurple": "#9370db", + "MediumSeaGreen": "#3cb371", + "MediumSlateBlue": "#7b68ee", + "MediumSpringGreen": "#00fa9a", + "MediumTurquoise": "#48d1cc", + "MediumVioletRed": "#c71585", + "MidnightBlue": "#191970", + "MintCream": "#f5fffa", + "MistyRose": "#ffe4e1", + "Moccasin": "#ffe4b5", + "NavajoWhite": "#ffdead", + "Navy": "#000080", + "OldLace": "#fdf5e6", + "Olive": "#808000", + "OliveDrab": "#6b8e23", + "Orange": "#ffa500", + "OrangeRed": "#ff4500", + "Orchid": "#da70d6", + "PaleGoldenRod": "#eee8aa", + "PaleGreen": "#98fb98", + "PaleTurquoise": "#afeeee", + "PaleVioletRed": "#db7093", + "PapayaWhip": "#ffefd5", + "PeachPuff": "#ffdab9", + "Peru": "#cd853f", + "Pink": "#ffc0cb", + "Plum": "#dda0dd", + "PowderBlue": "#b0e0e6", + "Purple": "#800080", + "RebeccaPurple": "#663399", + "Red": "#ff0000", + "RosyBrown": "#bc8f8f", + "RoyalBlue": "#4169e1", + "SaddleBrown": "#8b4513", + "Salmon": "#fa8072", + "SandyBrown": "#f4a460", + "SeaGreen": "#2e8b57", + "SeaShell": "#fff5ee", + "Sienna": "#a0522d", + "Silver": "#c0c0c0", + "SkyBlue": "#87ceeb", + "SlateBlue": "#6a5acd", + "SlateGray": "#708090", + "SlateGrey": "#708090", + "Snow": "#fffafa", + "SpringGreen": "#00ff7f", + "SteelBlue": "#4682b4", + "Tan": "#d2b48c", + "Teal": "#008080", + "Thistle": "#d8bfd8", + "Tomato": "#ff6347", + "Turquoise": "#40e0d0", + "Violet": "#ee82ee", + "Wheat": "#f5deb3", + "White": "#ffffff", + "WhiteSmoke": "#f5f5f5", + "Yellow": "#ffff00", + "YellowGreen": "#9acd32", +} diff --git a/.venv/lib/python3.8/site-packages/prompt_toolkit/styles/pygments.py b/.venv/lib/python3.8/site-packages/prompt_toolkit/styles/pygments.py new file mode 100644 index 00000000..382e5e31 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/prompt_toolkit/styles/pygments.py @@ -0,0 +1,67 @@ +""" +Adaptor for building prompt_toolkit styles, starting from a Pygments style. + +Usage:: + + from pygments.styles.tango import TangoStyle + style = style_from_pygments_cls(pygments_style_cls=TangoStyle) +""" +from typing import TYPE_CHECKING, Dict, Type + +from .style import Style + +if TYPE_CHECKING: + from pygments.style import Style as PygmentsStyle + from pygments.token import Token + + +__all__ = [ + "style_from_pygments_cls", + "style_from_pygments_dict", + "pygments_token_to_classname", +] + + +def style_from_pygments_cls(pygments_style_cls: Type["PygmentsStyle"]) -> Style: + """ + Shortcut to create a :class:`.Style` instance from a Pygments style class + and a style dictionary. + + Example:: + + from prompt_toolkit.styles.from_pygments import style_from_pygments_cls + from pygments.styles import get_style_by_name + style = style_from_pygments_cls(get_style_by_name('monokai')) + + :param pygments_style_cls: Pygments style class to start from. + """ + # Import inline. + from pygments.style import Style as PygmentsStyle + + assert issubclass(pygments_style_cls, PygmentsStyle) + + return style_from_pygments_dict(pygments_style_cls.styles) + + +def style_from_pygments_dict(pygments_dict: Dict["Token", str]) -> Style: + """ + Create a :class:`.Style` instance from a Pygments style dictionary. + (One that maps Token objects to style strings.) + """ + pygments_style = [] + + for token, style in pygments_dict.items(): + pygments_style.append((pygments_token_to_classname(token), style)) + + return Style(pygments_style) + + +def pygments_token_to_classname(token: "Token") -> str: + """ + Turn e.g. `Token.Name.Exception` into `'pygments.name.exception'`. + + (Our Pygments lexer will also turn the tokens that pygments produces in a + prompt_toolkit list of fragments that match these styling rules.) + """ + parts = ("pygments",) + token + return ".".join(parts).lower() diff --git a/.venv/lib/python3.8/site-packages/prompt_toolkit/styles/style.py b/.venv/lib/python3.8/site-packages/prompt_toolkit/styles/style.py new file mode 100644 index 00000000..775f43f3 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/prompt_toolkit/styles/style.py @@ -0,0 +1,398 @@ +""" +Tool for creating styles from a dictionary. +""" +import itertools +import re +import sys +from enum import Enum +from typing import Dict, Hashable, List, Set, Tuple, TypeVar + +from prompt_toolkit.cache import SimpleCache + +from .base import ( + ANSI_COLOR_NAMES, + ANSI_COLOR_NAMES_ALIASES, + DEFAULT_ATTRS, + Attrs, + BaseStyle, +) +from .named_colors import NAMED_COLORS + +__all__ = [ + "Style", + "parse_color", + "Priority", + "merge_styles", +] + +_named_colors_lowercase = {k.lower(): v.lstrip("#") for k, v in NAMED_COLORS.items()} + + +def parse_color(text: str) -> str: + """ + Parse/validate color format. + + Like in Pygments, but also support the ANSI color names. + (These will map to the colors of the 16 color palette.) + """ + # ANSI color names. + if text in ANSI_COLOR_NAMES: + return text + if text in ANSI_COLOR_NAMES_ALIASES: + return ANSI_COLOR_NAMES_ALIASES[text] + + # 140 named colors. + try: + # Replace by 'hex' value. + return _named_colors_lowercase[text.lower()] + except KeyError: + pass + + # Hex codes. + if text[0:1] == "#": + col = text[1:] + + # Keep this for backwards-compatibility (Pygments does it). + # I don't like the '#' prefix for named colors. + if col in ANSI_COLOR_NAMES: + return col + elif col in ANSI_COLOR_NAMES_ALIASES: + return ANSI_COLOR_NAMES_ALIASES[col] + + # 6 digit hex color. + elif len(col) == 6: + return col + + # 3 digit hex color. + elif len(col) == 3: + return col[0] * 2 + col[1] * 2 + col[2] * 2 + + # Default. + elif text in ("", "default"): + return text + + raise ValueError("Wrong color format %r" % text) + + +# Attributes, when they are not filled in by a style. None means that we take +# the value from the parent. +_EMPTY_ATTRS = Attrs( + color=None, + bgcolor=None, + bold=None, + underline=None, + italic=None, + blink=None, + reverse=None, + hidden=None, +) + + +def _expand_classname(classname: str) -> List[str]: + """ + Split a single class name at the `.` operator, and build a list of classes. + + E.g. 'a.b.c' becomes ['a', 'a.b', 'a.b.c'] + """ + result = [] + parts = classname.split(".") + + for i in range(1, len(parts) + 1): + result.append(".".join(parts[:i]).lower()) + + return result + + +def _parse_style_str(style_str: str) -> Attrs: + """ + Take a style string, e.g. 'bg:red #88ff00 class:title' + and return a `Attrs` instance. + """ + # Start from default Attrs. + if "noinherit" in style_str: + attrs = DEFAULT_ATTRS + else: + attrs = _EMPTY_ATTRS + + # Now update with the given attributes. + for part in style_str.split(): + if part == "noinherit": + pass + elif part == "bold": + attrs = attrs._replace(bold=True) + elif part == "nobold": + attrs = attrs._replace(bold=False) + elif part == "italic": + attrs = attrs._replace(italic=True) + elif part == "noitalic": + attrs = attrs._replace(italic=False) + elif part == "underline": + attrs = attrs._replace(underline=True) + elif part == "nounderline": + attrs = attrs._replace(underline=False) + + # prompt_toolkit extensions. Not in Pygments. + elif part == "blink": + attrs = attrs._replace(blink=True) + elif part == "noblink": + attrs = attrs._replace(blink=False) + elif part == "reverse": + attrs = attrs._replace(reverse=True) + elif part == "noreverse": + attrs = attrs._replace(reverse=False) + elif part == "hidden": + attrs = attrs._replace(hidden=True) + elif part == "nohidden": + attrs = attrs._replace(hidden=False) + + # Pygments properties that we ignore. + elif part in ("roman", "sans", "mono"): + pass + elif part.startswith("border:"): + pass + + # Ignore pieces in between square brackets. This is internal stuff. + # Like '[transparent]' or '[set-cursor-position]'. + elif part.startswith("[") and part.endswith("]"): + pass + + # Colors. + elif part.startswith("bg:"): + attrs = attrs._replace(bgcolor=parse_color(part[3:])) + elif part.startswith("fg:"): # The 'fg:' prefix is optional. + attrs = attrs._replace(color=parse_color(part[3:])) + else: + attrs = attrs._replace(color=parse_color(part)) + + return attrs + + +CLASS_NAMES_RE = re.compile(r"^[a-z0-9.\s_-]*$") # This one can't contain a comma! + + +class Priority(Enum): + """ + The priority of the rules, when a style is created from a dictionary. + + In a `Style`, rules that are defined later will always override previous + defined rules, however in a dictionary, the key order was arbitrary before + Python 3.6. This means that the style could change at random between rules. + + We have two options: + + - `DICT_KEY_ORDER`: This means, iterate through the dictionary, and take + the key/value pairs in order as they come. This is a good option if you + have Python >3.6. Rules at the end will override rules at the beginning. + - `MOST_PRECISE`: keys that are defined with most precision will get higher + priority. (More precise means: more elements.) + """ + + DICT_KEY_ORDER = "KEY_ORDER" + MOST_PRECISE = "MOST_PRECISE" + + +# In the latest python verions, we take the dictionary ordering like it is, +# In older versions, we sort by by precision. If you need to write code that +# runs on all Python versions, it's best to sort them manually, with the most +# precise rules at the bottom. +if sys.version_info >= (3, 6): + default_priority = Priority.DICT_KEY_ORDER +else: + default_priority = Priority.MOST_PRECISE + + +class Style(BaseStyle): + """ + Create a ``Style`` instance from a list of style rules. + + The `style_rules` is supposed to be a list of ('classnames', 'style') tuples. + The classnames are a whitespace separated string of class names and the + style string is just like a Pygments style definition, but with a few + additions: it supports 'reverse' and 'blink'. + + Later rules always override previous rules. + + Usage:: + + Style([ + ('title', '#ff0000 bold underline'), + ('something-else', 'reverse'), + ('class1 class2', 'reverse'), + ]) + + The ``from_dict`` classmethod is similar, but takes a dictionary as input. + """ + + def __init__(self, style_rules: List[Tuple[str, str]]) -> None: + class_names_and_attrs = [] + + # Loop through the rules in the order they were defined. + # Rules that are defined later get priority. + for class_names, style_str in style_rules: + assert CLASS_NAMES_RE.match(class_names), repr(class_names) + + # The order of the class names doesn't matter. + # (But the order of rules does matter.) + class_names_set = frozenset(class_names.lower().split()) + attrs = _parse_style_str(style_str) + + class_names_and_attrs.append((class_names_set, attrs)) + + self._style_rules = style_rules + self.class_names_and_attrs = class_names_and_attrs + + @property + def style_rules(self) -> List[Tuple[str, str]]: + return self._style_rules + + @classmethod + def from_dict( + cls, style_dict: Dict[str, str], priority: Priority = default_priority + ) -> "Style": + """ + :param style_dict: Style dictionary. + :param priority: `Priority` value. + """ + if priority == Priority.MOST_PRECISE: + + def key(item: Tuple[str, str]) -> int: + # Split on '.' and whitespace. Count elements. + return sum(len(i.split(".")) for i in item[0].split()) + + return cls(sorted(style_dict.items(), key=key)) + else: + return cls(list(style_dict.items())) + + def get_attrs_for_style_str( + self, style_str: str, default: Attrs = DEFAULT_ATTRS + ) -> Attrs: + """ + Get `Attrs` for the given style string. + """ + list_of_attrs = [default] + class_names: Set[str] = set() + + # Apply default styling. + for names, attr in self.class_names_and_attrs: + if not names: + list_of_attrs.append(attr) + + # Go from left to right through the style string. Things on the right + # take precedence. + for part in style_str.split(): + # This part represents a class. + # Do lookup of this class name in the style definition, as well + # as all class combinations that we have so far. + if part.startswith("class:"): + # Expand all class names (comma separated list). + new_class_names = [] + for p in part[6:].lower().split(","): + new_class_names.extend(_expand_classname(p)) + + for new_name in new_class_names: + # Build a set of all possible class combinations to be applied. + combos = set() + combos.add(frozenset([new_name])) + + for count in range(1, len(class_names) + 1): + for c2 in itertools.combinations(class_names, count): + combos.add(frozenset(c2 + (new_name,))) + + # Apply the styles that match these class names. + for names, attr in self.class_names_and_attrs: + if names in combos: + list_of_attrs.append(attr) + + class_names.add(new_name) + + # Process inline style. + else: + inline_attrs = _parse_style_str(part) + list_of_attrs.append(inline_attrs) + + return _merge_attrs(list_of_attrs) + + def invalidation_hash(self) -> Hashable: + return id(self.class_names_and_attrs) + + +_T = TypeVar("_T") + + +def _merge_attrs(list_of_attrs: List[Attrs]) -> Attrs: + """ + Take a list of :class:`.Attrs` instances and merge them into one. + Every `Attr` in the list can override the styling of the previous one. So, + the last one has highest priority. + """ + + def _or(*values: _T) -> _T: + " Take first not-None value, starting at the end. " + for v in values[::-1]: + if v is not None: + return v + raise ValueError # Should not happen, there's always one non-null value. + + return Attrs( + color=_or("", *[a.color for a in list_of_attrs]), + bgcolor=_or("", *[a.bgcolor for a in list_of_attrs]), + bold=_or(False, *[a.bold for a in list_of_attrs]), + underline=_or(False, *[a.underline for a in list_of_attrs]), + italic=_or(False, *[a.italic for a in list_of_attrs]), + blink=_or(False, *[a.blink for a in list_of_attrs]), + reverse=_or(False, *[a.reverse for a in list_of_attrs]), + hidden=_or(False, *[a.hidden for a in list_of_attrs]), + ) + + +def merge_styles(styles: List[BaseStyle]) -> "_MergedStyle": + """ + Merge multiple `Style` objects. + """ + styles = [s for s in styles if s is not None] + return _MergedStyle(styles) + + +class _MergedStyle(BaseStyle): + """ + Merge multiple `Style` objects into one. + This is supposed to ensure consistency: if any of the given styles changes, + then this style will be updated. + """ + + # NOTE: previously, we used an algorithm where we did not generate the + # combined style. Instead this was a proxy that called one style + # after the other, passing the outcome of the previous style as the + # default for the next one. This did not work, because that way, the + # priorities like described in the `Style` class don't work. + # 'class:aborted' was for instance never displayed in gray, because + # the next style specified a default color for any text. (The + # explicit styling of class:aborted should have taken priority, + # because it was more precise.) + def __init__(self, styles: List[BaseStyle]) -> None: + self.styles = styles + self._style: SimpleCache[Hashable, Style] = SimpleCache(maxsize=1) + + @property + def _merged_style(self) -> Style: + " The `Style` object that has the other styles merged together. " + + def get() -> Style: + return Style(self.style_rules) + + return self._style.get(self.invalidation_hash(), get) + + @property + def style_rules(self) -> List[Tuple[str, str]]: + style_rules = [] + for s in self.styles: + style_rules.extend(s.style_rules) + return style_rules + + def get_attrs_for_style_str( + self, style_str: str, default: Attrs = DEFAULT_ATTRS + ) -> Attrs: + return self._merged_style.get_attrs_for_style_str(style_str, default) + + def invalidation_hash(self) -> Hashable: + return tuple(s.invalidation_hash() for s in self.styles) diff --git a/.venv/lib/python3.8/site-packages/prompt_toolkit/styles/style_transformation.py b/.venv/lib/python3.8/site-packages/prompt_toolkit/styles/style_transformation.py new file mode 100644 index 00000000..15b858aa --- /dev/null +++ b/.venv/lib/python3.8/site-packages/prompt_toolkit/styles/style_transformation.py @@ -0,0 +1,375 @@ +""" +Collection of style transformations. + +Think of it as a kind of color post processing after the rendering is done. +This could be used for instance to change the contrast/saturation; swap light +and dark colors or even change certain colors for other colors. + +When the UI is rendered, these transformations can be applied right after the +style strings are turned into `Attrs` objects that represent the actual +formatting. +""" +from abc import ABCMeta, abstractmethod +from colorsys import hls_to_rgb, rgb_to_hls +from typing import Callable, Hashable, Optional, Sequence, Tuple, Union + +from prompt_toolkit.cache import memoized +from prompt_toolkit.filters import FilterOrBool, to_filter +from prompt_toolkit.utils import AnyFloat, to_float, to_str + +from .base import ANSI_COLOR_NAMES, Attrs +from .style import parse_color + +__all__ = [ + "StyleTransformation", + "SwapLightAndDarkStyleTransformation", + "ReverseStyleTransformation", + "SetDefaultColorStyleTransformation", + "AdjustBrightnessStyleTransformation", + "DummyStyleTransformation", + "ConditionalStyleTransformation", + "DynamicStyleTransformation", + "merge_style_transformations", +] + + +class StyleTransformation(metaclass=ABCMeta): + """ + Base class for any style transformation. + """ + + @abstractmethod + def transform_attrs(self, attrs: Attrs) -> Attrs: + """ + Take an `Attrs` object and return a new `Attrs` object. + + Remember that the color formats can be either "ansi..." or a 6 digit + lowercase hexadecimal color (without '#' prefix). + """ + + def invalidation_hash(self) -> Hashable: + """ + When this changes, the cache should be invalidated. + """ + return "%s-%s" % (self.__class__.__name__, id(self)) + + +class SwapLightAndDarkStyleTransformation(StyleTransformation): + """ + Turn dark colors into light colors and the other way around. + + This is meant to make color schemes that work on a dark background usable + on a light background (and the other way around). + + Notice that this doesn't swap foreground and background like "reverse" + does. It turns light green into dark green and the other way around. + Foreground and background colors are considered individually. + + Also notice that when is used somewhere and no colors are given + in particular (like what is the default for the bottom toolbar), then this + doesn't change anything. This is what makes sense, because when the + 'default' color is chosen, it's what works best for the terminal, and + reverse works good with that. + """ + + def transform_attrs(self, attrs: Attrs) -> Attrs: + """ + Return the `Attrs` used when opposite luminosity should be used. + """ + # Reverse colors. + attrs = attrs._replace(color=get_opposite_color(attrs.color)) + attrs = attrs._replace(bgcolor=get_opposite_color(attrs.bgcolor)) + + return attrs + + +class ReverseStyleTransformation(StyleTransformation): + """ + Swap the 'reverse' attribute. + + (This is still experimental.) + """ + + def transform_attrs(self, attrs: Attrs) -> Attrs: + return attrs._replace(reverse=not attrs.reverse) + + +class SetDefaultColorStyleTransformation(StyleTransformation): + """ + Set default foreground/background color for output that doesn't specify + anything. This is useful for overriding the terminal default colors. + + :param fg: Color string or callable that returns a color string for the + foreground. + :param bg: Like `fg`, but for the background. + """ + + def __init__( + self, fg: Union[str, Callable[[], str]], bg: Union[str, Callable[[], str]] + ) -> None: + + self.fg = fg + self.bg = bg + + def transform_attrs(self, attrs: Attrs) -> Attrs: + if attrs.bgcolor in ("", "default"): + attrs = attrs._replace(bgcolor=parse_color(to_str(self.bg))) + + if attrs.color in ("", "default"): + attrs = attrs._replace(color=parse_color(to_str(self.fg))) + + return attrs + + def invalidation_hash(self) -> Hashable: + return ( + "set-default-color", + to_str(self.fg), + to_str(self.bg), + ) + + +class AdjustBrightnessStyleTransformation(StyleTransformation): + """ + Adjust the brightness to improve the rendering on either dark or light + backgrounds. + + For dark backgrounds, it's best to increase `min_brightness`. For light + backgrounds it's best to decrease `max_brightness`. Usually, only one + setting is adjusted. + + This will only change the brightness for text that has a foreground color + defined, but no background color. It works best for 256 or true color + output. + + .. note:: Notice that there is no universal way to detect whether the + application is running in a light or dark terminal. As a + developer of an command line application, you'll have to make + this configurable for the user. + + :param min_brightness: Float between 0.0 and 1.0 or a callable that returns + a float. + :param max_brightness: Float between 0.0 and 1.0 or a callable that returns + a float. + """ + + def __init__( + self, min_brightness: AnyFloat = 0.0, max_brightness: AnyFloat = 1.0 + ) -> None: + + self.min_brightness = min_brightness + self.max_brightness = max_brightness + + def transform_attrs(self, attrs: Attrs) -> Attrs: + min_brightness = to_float(self.min_brightness) + max_brightness = to_float(self.max_brightness) + assert 0 <= min_brightness <= 1 + assert 0 <= max_brightness <= 1 + + # Don't do anything if the whole brightness range is acceptable. + # This also avoids turning ansi colors into RGB sequences. + if min_brightness == 0.0 and max_brightness == 1.0: + return attrs + + # If a foreground color is given without a background color. + no_background = not attrs.bgcolor or attrs.bgcolor == "default" + has_fgcolor = attrs.color and attrs.color != "ansidefault" + + if has_fgcolor and no_background: + # Calculate new RGB values. + r, g, b = self._color_to_rgb(attrs.color or "") + hue, brightness, saturation = rgb_to_hls(r, g, b) + brightness = self._interpolate_brightness( + brightness, min_brightness, max_brightness + ) + r, g, b = hls_to_rgb(hue, brightness, saturation) + new_color = "%02x%02x%02x" % (int(r * 255), int(g * 255), int(b * 255)) + + attrs = attrs._replace(color=new_color) + + return attrs + + def _color_to_rgb(self, color: str) -> Tuple[float, float, float]: + """ + Parse `style.Attrs` color into RGB tuple. + """ + # Do RGB lookup for ANSI colors. + try: + from prompt_toolkit.output.vt100 import ANSI_COLORS_TO_RGB + + r, g, b = ANSI_COLORS_TO_RGB[color] + return r / 255.0, g / 255.0, b / 255.0 + except KeyError: + pass + + # Parse RRGGBB format. + return ( + int(color[0:2], 16) / 255.0, + int(color[2:4], 16) / 255.0, + int(color[4:6], 16) / 255.0, + ) + + # NOTE: we don't have to support named colors here. They are already + # transformed into RGB values in `style.parse_color`. + + def _interpolate_brightness( + self, value: float, min_brightness: float, max_brightness: float + ) -> float: + """ + Map the brightness to the (min_brightness..max_brightness) range. + """ + return min_brightness + (max_brightness - min_brightness) * value + + def invalidation_hash(self) -> Hashable: + return ( + "adjust-brightness", + to_float(self.min_brightness), + to_float(self.max_brightness), + ) + + +class DummyStyleTransformation(StyleTransformation): + """ + Don't transform anything at all. + """ + + def transform_attrs(self, attrs: Attrs) -> Attrs: + return attrs + + def invalidation_hash(self) -> Hashable: + # Always return the same hash for these dummy instances. + return "dummy-style-transformation" + + +class DynamicStyleTransformation(StyleTransformation): + """ + StyleTransformation class that can dynamically returns any + `StyleTransformation`. + + :param get_style_transformation: Callable that returns a + :class:`.StyleTransformation` instance. + """ + + def __init__( + self, get_style_transformation: Callable[[], Optional[StyleTransformation]] + ) -> None: + + self.get_style_transformation = get_style_transformation + + def transform_attrs(self, attrs: Attrs) -> Attrs: + style_transformation = ( + self.get_style_transformation() or DummyStyleTransformation() + ) + return style_transformation.transform_attrs(attrs) + + def invalidation_hash(self) -> Hashable: + style_transformation = ( + self.get_style_transformation() or DummyStyleTransformation() + ) + return style_transformation.invalidation_hash() + + +class ConditionalStyleTransformation(StyleTransformation): + """ + Apply the style transformation depending on a condition. + """ + + def __init__( + self, style_transformation: StyleTransformation, filter: FilterOrBool + ) -> None: + + self.style_transformation = style_transformation + self.filter = to_filter(filter) + + def transform_attrs(self, attrs: Attrs) -> Attrs: + if self.filter(): + return self.style_transformation.transform_attrs(attrs) + return attrs + + def invalidation_hash(self) -> Hashable: + return (self.filter(), self.style_transformation.invalidation_hash()) + + +class _MergedStyleTransformation(StyleTransformation): + def __init__(self, style_transformations: Sequence[StyleTransformation]) -> None: + self.style_transformations = style_transformations + + def transform_attrs(self, attrs: Attrs) -> Attrs: + for transformation in self.style_transformations: + attrs = transformation.transform_attrs(attrs) + return attrs + + def invalidation_hash(self) -> Hashable: + return tuple(t.invalidation_hash() for t in self.style_transformations) + + +def merge_style_transformations( + style_transformations: Sequence[StyleTransformation], +) -> StyleTransformation: + """ + Merge multiple transformations together. + """ + return _MergedStyleTransformation(style_transformations) + + +# Dictionary that maps ANSI color names to their opposite. This is useful for +# turning color schemes that are optimized for a black background usable for a +# white background. +OPPOSITE_ANSI_COLOR_NAMES = { + "ansidefault": "ansidefault", + "ansiblack": "ansiwhite", + "ansired": "ansibrightred", + "ansigreen": "ansibrightgreen", + "ansiyellow": "ansibrightyellow", + "ansiblue": "ansibrightblue", + "ansimagenta": "ansibrightmagenta", + "ansicyan": "ansibrightcyan", + "ansigray": "ansibrightblack", + "ansiwhite": "ansiblack", + "ansibrightred": "ansired", + "ansibrightgreen": "ansigreen", + "ansibrightyellow": "ansiyellow", + "ansibrightblue": "ansiblue", + "ansibrightmagenta": "ansimagenta", + "ansibrightcyan": "ansicyan", + "ansibrightblack": "ansigray", +} +assert set(OPPOSITE_ANSI_COLOR_NAMES.keys()) == set(ANSI_COLOR_NAMES) +assert set(OPPOSITE_ANSI_COLOR_NAMES.values()) == set(ANSI_COLOR_NAMES) + + +@memoized() +def get_opposite_color(colorname: Optional[str]) -> Optional[str]: + """ + Take a color name in either 'ansi...' format or 6 digit RGB, return the + color of opposite luminosity (same hue/saturation). + + This is used for turning color schemes that work on a light background + usable on a dark background. + """ + if colorname is None: # Because color/bgcolor can be None in `Attrs`. + return None + + # Special values. + if colorname in ("", "default"): + return colorname + + # Try ANSI color names. + try: + return OPPOSITE_ANSI_COLOR_NAMES[colorname] + except KeyError: + # Try 6 digit RGB colors. + r = int(colorname[:2], 16) / 255.0 + g = int(colorname[2:4], 16) / 255.0 + b = int(colorname[4:6], 16) / 255.0 + + h, l, s = rgb_to_hls(r, g, b) + + l = 1 - l + + r, g, b = hls_to_rgb(h, l, s) + + r = int(r * 255) + g = int(g * 255) + b = int(b * 255) + + return "%02x%02x%02x" % (r, g, b) diff --git a/.venv/lib/python3.8/site-packages/prompt_toolkit/token.py b/.venv/lib/python3.8/site-packages/prompt_toolkit/token.py new file mode 100644 index 00000000..76fd9c46 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/prompt_toolkit/token.py @@ -0,0 +1,8 @@ +""" +""" + +__all__ = [ + "ZeroWidthEscape", +] + +ZeroWidthEscape = "[ZeroWidthEscape]" diff --git a/.venv/lib/python3.8/site-packages/prompt_toolkit/utils.py b/.venv/lib/python3.8/site-packages/prompt_toolkit/utils.py new file mode 100644 index 00000000..3cc9890c --- /dev/null +++ b/.venv/lib/python3.8/site-packages/prompt_toolkit/utils.py @@ -0,0 +1,312 @@ +import os +import signal +import sys +import threading +from collections import deque +from typing import ( + Callable, + ContextManager, + Deque, + Dict, + Generator, + Generic, + List, + Optional, + TypeVar, + Union, +) + +from wcwidth import wcwidth + +__all__ = [ + "Event", + "DummyContext", + "get_cwidth", + "suspend_to_background_supported", + "is_conemu_ansi", + "is_windows", + "in_main_thread", + "get_term_environment_variable", + "take_using_weights", + "to_str", + "to_int", + "AnyFloat", + "to_float", + "is_dumb_terminal", +] + +_Sender = TypeVar("_Sender", covariant=True) + + +class Event(Generic[_Sender]): + """ + Simple event to which event handlers can be attached. For instance:: + + class Cls: + def __init__(self): + # Define event. The first parameter is the sender. + self.event = Event(self) + + obj = Cls() + + def handler(sender): + pass + + # Add event handler by using the += operator. + obj.event += handler + + # Fire event. + obj.event() + """ + + def __init__( + self, sender: _Sender, handler: Optional[Callable[[_Sender], None]] = None + ): + self.sender = sender + self._handlers: List[Callable[[_Sender], None]] = [] + + if handler is not None: + self += handler + + def __call__(self) -> None: + " Fire event. " + for handler in self._handlers: + handler(self.sender) + + def fire(self) -> None: + " Alias for just calling the event. " + self() + + def add_handler(self, handler: Callable[[_Sender], None]) -> None: + """ + Add another handler to this callback. + (Handler should be a callable that takes exactly one parameter: the + sender object.) + """ + # Add to list of event handlers. + self._handlers.append(handler) + + def remove_handler(self, handler: Callable[[_Sender], None]) -> None: + """ + Remove a handler from this callback. + """ + if handler in self._handlers: + self._handlers.remove(handler) + + def __iadd__(self, handler: Callable[[_Sender], None]) -> "Event[_Sender]": + """ + `event += handler` notation for adding a handler. + """ + self.add_handler(handler) + return self + + def __isub__(self, handler: Callable[[_Sender], None]) -> "Event[_Sender]": + """ + `event -= handler` notation for removing a handler. + """ + self.remove_handler(handler) + return self + + +class DummyContext(ContextManager[None]): + """ + (contextlib.nested is not available on Py3) + """ + + def __enter__(self) -> None: + pass + + def __exit__(self, *a: object) -> None: + pass + + +class _CharSizesCache(Dict[str, int]): + """ + Cache for wcwidth sizes. + """ + + LONG_STRING_MIN_LEN = 64 # Minimum string length for considering it long. + MAX_LONG_STRINGS = 16 # Maximum number of long strings to remember. + + def __init__(self) -> None: + super().__init__() + # Keep track of the "long" strings in this cache. + self._long_strings: Deque[str] = deque() + + def __missing__(self, string: str) -> int: + # Note: We use the `max(0, ...` because some non printable control + # characters, like e.g. Ctrl-underscore get a -1 wcwidth value. + # It can be possible that these characters end up in the input + # text. + result: int + if len(string) == 1: + result = max(0, wcwidth(string)) + else: + result = sum(self[c] for c in string) + + # Store in cache. + self[string] = result + + # Rotate long strings. + # (It's hard to tell what we can consider short...) + if len(string) > self.LONG_STRING_MIN_LEN: + long_strings = self._long_strings + long_strings.append(string) + + if len(long_strings) > self.MAX_LONG_STRINGS: + key_to_remove = long_strings.popleft() + if key_to_remove in self: + del self[key_to_remove] + + return result + + +_CHAR_SIZES_CACHE = _CharSizesCache() + + +def get_cwidth(string: str) -> int: + """ + Return width of a string. Wrapper around ``wcwidth``. + """ + return _CHAR_SIZES_CACHE[string] + + +def suspend_to_background_supported() -> bool: + """ + Returns `True` when the Python implementation supports + suspend-to-background. This is typically `False' on Windows systems. + """ + return hasattr(signal, "SIGTSTP") + + +def is_windows() -> bool: + """ + True when we are using Windows. + """ + return sys.platform.startswith("win") # E.g. 'win32', not 'darwin' or 'linux2' + + +def is_windows_vt100_supported() -> bool: + """ + True when we are using Windows, but VT100 escape sequences are supported. + """ + # Import needs to be inline. Windows libraries are not always available. + from prompt_toolkit.output.windows10 import is_win_vt100_enabled + + return is_windows() and is_win_vt100_enabled() + + +def is_conemu_ansi() -> bool: + """ + True when the ConEmu Windows console is used. + """ + return is_windows() and os.environ.get("ConEmuANSI", "OFF") == "ON" + + +def in_main_thread() -> bool: + """ + True when the current thread is the main thread. + """ + return threading.current_thread().__class__.__name__ == "_MainThread" + + +def get_term_environment_variable() -> str: + " Return the $TERM environment variable. " + return os.environ.get("TERM", "") + + +_T = TypeVar("_T") + + +def take_using_weights( + items: List[_T], weights: List[int] +) -> Generator[_T, None, None]: + """ + Generator that keeps yielding items from the items list, in proportion to + their weight. For instance:: + + # Getting the first 70 items from this generator should have yielded 10 + # times A, 20 times B and 40 times C, all distributed equally.. + take_using_weights(['A', 'B', 'C'], [5, 10, 20]) + + :param items: List of items to take from. + :param weights: Integers representing the weight. (Numbers have to be + integers, not floats.) + """ + assert len(items) == len(weights) + assert len(items) > 0 + + # Remove items with zero-weight. + items2 = [] + weights2 = [] + for item, w in zip(items, weights): + if w > 0: + items2.append(item) + weights2.append(w) + + items = items2 + weights = weights2 + + # Make sure that we have some items left. + if not items: + raise ValueError("Did't got any items with a positive weight.") + + # + already_taken = [0 for i in items] + item_count = len(items) + max_weight = max(weights) + + i = 0 + while True: + # Each iteration of this loop, we fill up until by (total_weight/max_weight). + adding = True + while adding: + adding = False + + for item_i, item, weight in zip(range(item_count), items, weights): + if already_taken[item_i] < i * weight / float(max_weight): + yield item + already_taken[item_i] += 1 + adding = True + + i += 1 + + +def to_str(value: Union[Callable[[], str], str]) -> str: + " Turn callable or string into string. " + if callable(value): + return to_str(value()) + else: + return str(value) + + +def to_int(value: Union[Callable[[], int], int]) -> int: + " Turn callable or int into int. " + if callable(value): + return to_int(value()) + else: + return int(value) + + +AnyFloat = Union[Callable[[], float], float] + + +def to_float(value: AnyFloat) -> float: + " Turn callable or float into float. " + if callable(value): + return to_float(value()) + else: + return float(value) + + +def is_dumb_terminal(term: Optional[str] = None) -> bool: + """ + True if this terminal type is considered "dumb". + + If so, we should fall back to the simplest possible form of line editing, + without cursor positioning and color support. + """ + if term is None: + return is_dumb_terminal(os.environ.get("TERM", "")) + + return term.lower() in ["dumb", "unknown"] diff --git a/.venv/lib/python3.8/site-packages/prompt_toolkit/validation.py b/.venv/lib/python3.8/site-packages/prompt_toolkit/validation.py new file mode 100644 index 00000000..db2f3fd1 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/prompt_toolkit/validation.py @@ -0,0 +1,194 @@ +""" +Input validation for a `Buffer`. +(Validators will be called before accepting input.) +""" +from abc import ABCMeta, abstractmethod +from typing import Callable, Optional + +from prompt_toolkit.eventloop import run_in_executor_with_context + +from .document import Document +from .filters import FilterOrBool, to_filter + +__all__ = [ + "ConditionalValidator", + "ValidationError", + "Validator", + "ThreadedValidator", + "DummyValidator", + "DynamicValidator", +] + + +class ValidationError(Exception): + """ + Error raised by :meth:`.Validator.validate`. + + :param cursor_position: The cursor position where the error occurred. + :param message: Text. + """ + + def __init__(self, cursor_position: int = 0, message: str = "") -> None: + super().__init__(message) + self.cursor_position = cursor_position + self.message = message + + def __repr__(self) -> str: + return "%s(cursor_position=%r, message=%r)" % ( + self.__class__.__name__, + self.cursor_position, + self.message, + ) + + +class Validator(metaclass=ABCMeta): + """ + Abstract base class for an input validator. + + A validator is typically created in one of the following two ways: + + - Either by overriding this class and implementing the `validate` method. + - Or by passing a callable to `Validator.from_callable`. + + If the validation takes some time and needs to happen in a background + thread, this can be wrapped in a :class:`.ThreadedValidator`. + """ + + @abstractmethod + def validate(self, document: Document) -> None: + """ + Validate the input. + If invalid, this should raise a :class:`.ValidationError`. + + :param document: :class:`~prompt_toolkit.document.Document` instance. + """ + pass + + async def validate_async(self, document: Document) -> None: + """ + Return a `Future` which is set when the validation is ready. + This function can be overloaded in order to provide an asynchronous + implementation. + """ + try: + self.validate(document) + except ValidationError: + raise + + @classmethod + def from_callable( + cls, + validate_func: Callable[[str], bool], + error_message: str = "Invalid input", + move_cursor_to_end: bool = False, + ) -> "Validator": + """ + Create a validator from a simple validate callable. E.g.: + + .. code:: python + + def is_valid(text): + return text in ['hello', 'world'] + Validator.from_callable(is_valid, error_message='Invalid input') + + :param validate_func: Callable that takes the input string, and returns + `True` if the input is valid input. + :param error_message: Message to be displayed if the input is invalid. + :param move_cursor_to_end: Move the cursor to the end of the input, if + the input is invalid. + """ + return _ValidatorFromCallable(validate_func, error_message, move_cursor_to_end) + + +class _ValidatorFromCallable(Validator): + """ + Validate input from a simple callable. + """ + + def __init__( + self, func: Callable[[str], bool], error_message: str, move_cursor_to_end: bool + ) -> None: + + self.func = func + self.error_message = error_message + self.move_cursor_to_end = move_cursor_to_end + + def __repr__(self) -> str: + return "Validator.from_callable(%r)" % (self.func,) + + def validate(self, document: Document) -> None: + if not self.func(document.text): + if self.move_cursor_to_end: + index = len(document.text) + else: + index = 0 + + raise ValidationError(cursor_position=index, message=self.error_message) + + +class ThreadedValidator(Validator): + """ + Wrapper that runs input validation in a thread. + (Use this to prevent the user interface from becoming unresponsive if the + input validation takes too much time.) + """ + + def __init__(self, validator: Validator) -> None: + self.validator = validator + + def validate(self, document: Document) -> None: + self.validator.validate(document) + + async def validate_async(self, document: Document) -> None: + """ + Run the `validate` function in a thread. + """ + + def run_validation_thread() -> None: + return self.validate(document) + + await run_in_executor_with_context(run_validation_thread) + + +class DummyValidator(Validator): + """ + Validator class that accepts any input. + """ + + def validate(self, document: Document) -> None: + pass # Don't raise any exception. + + +class ConditionalValidator(Validator): + """ + Validator that can be switched on/off according to + a filter. (This wraps around another validator.) + """ + + def __init__(self, validator: Validator, filter: FilterOrBool) -> None: + self.validator = validator + self.filter = to_filter(filter) + + def validate(self, document: Document) -> None: + # Call the validator only if the filter is active. + if self.filter(): + self.validator.validate(document) + + +class DynamicValidator(Validator): + """ + Validator class that can dynamically returns any Validator. + + :param get_validator: Callable that returns a :class:`.Validator` instance. + """ + + def __init__(self, get_validator: Callable[[], Optional[Validator]]) -> None: + self.get_validator = get_validator + + def validate(self, document: Document) -> None: + validator = self.get_validator() or DummyValidator() + validator.validate(document) + + async def validate_async(self, document: Document) -> None: + validator = self.get_validator() or DummyValidator() + await validator.validate_async(document) diff --git a/.venv/lib/python3.8/site-packages/prompt_toolkit/widgets/__init__.py b/.venv/lib/python3.8/site-packages/prompt_toolkit/widgets/__init__.py new file mode 100644 index 00000000..552d3559 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/prompt_toolkit/widgets/__init__.py @@ -0,0 +1,60 @@ +""" +Collection of reusable components for building full screen applications. +These are higher level abstractions on top of the `prompt_toolkit.layout` +module. + +Most of these widgets implement the ``__pt_container__`` method, which makes it +possible to embed these in the layout like any other container. +""" +from .base import ( + Box, + Button, + Checkbox, + CheckboxList, + Frame, + HorizontalLine, + Label, + ProgressBar, + RadioList, + Shadow, + TextArea, + VerticalLine, +) +from .dialogs import Dialog +from .menus import MenuContainer, MenuItem +from .toolbars import ( + ArgToolbar, + CompletionsToolbar, + FormattedTextToolbar, + SearchToolbar, + SystemToolbar, + ValidationToolbar, +) + +__all__ = [ + # Base. + "TextArea", + "Label", + "Button", + "Frame", + "Shadow", + "Box", + "VerticalLine", + "HorizontalLine", + "CheckboxList", + "RadioList", + "Checkbox", + "ProgressBar", + # Toolbars. + "ArgToolbar", + "CompletionsToolbar", + "FormattedTextToolbar", + "SearchToolbar", + "SystemToolbar", + "ValidationToolbar", + # Dialogs. + "Dialog", + # Menus. + "MenuContainer", + "MenuItem", +] diff --git a/.venv/lib/python3.8/site-packages/prompt_toolkit/widgets/__pycache__/__init__.cpython-38.pyc b/.venv/lib/python3.8/site-packages/prompt_toolkit/widgets/__pycache__/__init__.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a6891423bb4135115aa997dce7410cebed17dcaa GIT binary patch literal 1211 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 S@$rwvM#qQow{5skDEvPGxnPd~ literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/prompt_toolkit/widgets/__pycache__/dialogs.cpython-38.pyc b/.venv/lib/python3.8/site-packages/prompt_toolkit/widgets/__pycache__/dialogs.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0512adf25f7e31d9b1d4080c592d93c4a4e7d047 GIT binary patch literal 3051 zcma(T$!;V`H6yp$7rWhydzneZGSo0GBM>0WsF|^w27zRd+`}O*>8y&Vs%+=h5mC6y z$`%K=L|-iN0rLZWLx^wT5LZrp<}!>lnD-*9+~sD3$gF(z-ivrkye;#yPN!+Xb@|7? zhaYw<>mNw0Uk(tTz$5S4p z8YMg!=V_5=JX125hjB#>jlc@{)Pk;LN&W#zE>1|nb$99{oyft)DO z^&|dl&a*Ms-e(!G2Da|aA{nCYgc~v4K*l5=&*gyV{-@dEaW2wGDbAko=L#g6W--iw z(%lL#1ph;v8;RC$_+mfK&^0-5bsH2M3-Izd8b!mG*yc{=p9Y0+62$gD10C2Jlle9*iQ%P3GdPn5*SZ`B9K^DWmC1 zR2pqj#vtF>B*w@?7*@N7O|yJ3i?S)^9`&kNfnk&wiFhVl$TMlS40qhV|p(*m_bdV z<5jwYeDo9wdAPpOXx$62lme9pBlJ`jNwnZBh%@8Fj7O%hubt$Y5^x7nFZY5^gCv#; z9Xqbd;TS^Crd&Z>-|B^fn*`(_l~#(hb@=4*pr&0su=b2sy0+A-y)Ma+1u7Rc~LjGWAH{D@{VSgFNOe`u*xi6Wsh3T*S^CU6ssEV>msy!zdS$D0*^LXIZC#KT?N=6@ z!iUxGt47&oH%pJ*x^N&u{md_6HS9ABdh7O~*nlt!Z1*>paA`N;69u!tpTvoRIpT?U zI#d7En5f?l2tbpWlwsSh; zJlXl_k3uzj_Ji4OAz&=3P~~}Y606;1W$jk2C5OdA*FR38bi|^EzW|N@gvUDjMm2zj zVHjtz3d7;YNj{De`4Et5FO1Lz49p1^f-~);(er_0Jk+%!Vp#gLyF|i~so8-oc0jjo zpYTOES`ODYSZXlcoixtGM}Uj(A;Ydz`7@3o(vFHoXP(@FzyBv(;+v?0h;7t|VG`fD z!oG{x002egLjY$RW)$pI5gB4H4g5+LBd$HE76}*kasLp(Jp|tZaMoUzT%KS25SMZH zV8fiEQibn(?Ib)Cm{#pTj0Cots3X9}6PpOy05o|dx=45kZX(!1cH?R&!Q}n`+2~-U z|1M(2Gvnw3AZc?s3c`~S?ZOzADul{`Va6Hl!1!Aun-hEiL8f4k*e4_H8G0>v7&l#C z)dL!rzXM=3ed617$0u#P?Jct9xWsmB(j`q|f93i%^8f9AVPE=v7xuvp+a@-y!re#s zrF-eOT;h{W`>gj)t<8 literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/prompt_toolkit/widgets/__pycache__/menus.cpython-38.pyc b/.venv/lib/python3.8/site-packages/prompt_toolkit/widgets/__pycache__/menus.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..13e81bd379c2d92c5189fa742c797065df32beea GIT binary patch literal 10791 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 literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/prompt_toolkit/widgets/__pycache__/toolbars.cpython-38.pyc b/.venv/lib/python3.8/site-packages/prompt_toolkit/widgets/__pycache__/toolbars.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..51a849f265fc4bed7e9c609e2dab8e16b871668e GIT binary patch literal 11109 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 literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/prompt_toolkit/widgets/base.py b/.venv/lib/python3.8/site-packages/prompt_toolkit/widgets/base.py new file mode 100644 index 00000000..e994b5a7 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/prompt_toolkit/widgets/base.py @@ -0,0 +1,916 @@ +""" +Collection of reusable components for building full screen applications. + +All of these widgets implement the ``__pt_container__`` method, which makes +them usable in any situation where we are expecting a `prompt_toolkit` +container object. + +.. warning:: + + At this point, the API for these widgets is considered unstable, and can + potentially change between minor releases (we try not too, but no + guarantees are made yet). The public API in + `prompt_toolkit.shortcuts.dialogs` on the other hand is considered stable. +""" +from functools import partial +from typing import Callable, Generic, List, Optional, Sequence, Tuple, TypeVar, Union + +from prompt_toolkit.application.current import get_app +from prompt_toolkit.auto_suggest import AutoSuggest, DynamicAutoSuggest +from prompt_toolkit.buffer import Buffer, BufferAcceptHandler +from prompt_toolkit.completion import Completer, DynamicCompleter +from prompt_toolkit.document import Document +from prompt_toolkit.filters import ( + Condition, + FilterOrBool, + has_focus, + is_done, + is_true, + to_filter, +) +from prompt_toolkit.formatted_text import ( + AnyFormattedText, + StyleAndTextTuples, + Template, + to_formatted_text, +) +from prompt_toolkit.formatted_text.utils import fragment_list_to_text +from prompt_toolkit.history import History +from prompt_toolkit.key_binding.key_bindings import KeyBindings +from prompt_toolkit.key_binding.key_processor import KeyPressEvent +from prompt_toolkit.keys import Keys +from prompt_toolkit.layout.containers import ( + AnyContainer, + ConditionalContainer, + Container, + DynamicContainer, + Float, + FloatContainer, + HSplit, + VSplit, + Window, + WindowAlign, +) +from prompt_toolkit.layout.controls import ( + BufferControl, + FormattedTextControl, + GetLinePrefixCallable, +) +from prompt_toolkit.layout.dimension import AnyDimension +from prompt_toolkit.layout.dimension import Dimension as D +from prompt_toolkit.layout.dimension import to_dimension +from prompt_toolkit.layout.margins import ( + ConditionalMargin, + NumberedMargin, + ScrollbarMargin, +) +from prompt_toolkit.layout.processors import ( + AppendAutoSuggestion, + BeforeInput, + ConditionalProcessor, + PasswordProcessor, + Processor, +) +from prompt_toolkit.lexers import DynamicLexer, Lexer +from prompt_toolkit.mouse_events import MouseEvent, MouseEventType +from prompt_toolkit.utils import get_cwidth +from prompt_toolkit.validation import DynamicValidator, Validator + +from .toolbars import SearchToolbar + +__all__ = [ + "TextArea", + "Label", + "Button", + "Frame", + "Shadow", + "Box", + "VerticalLine", + "HorizontalLine", + "RadioList", + "CheckboxList", + "Checkbox", # backward compatibility + "ProgressBar", +] + +E = KeyPressEvent + + +class Border: + " Box drawing characters. (Thin) " + HORIZONTAL = "\u2500" + VERTICAL = "\u2502" + TOP_LEFT = "\u250c" + TOP_RIGHT = "\u2510" + BOTTOM_LEFT = "\u2514" + BOTTOM_RIGHT = "\u2518" + + +class TextArea: + """ + A simple input field. + + This is a higher level abstraction on top of several other classes with + sane defaults. + + This widget does have the most common options, but it does not intend to + cover every single use case. For more configurations options, you can + always build a text area manually, using a + :class:`~prompt_toolkit.buffer.Buffer`, + :class:`~prompt_toolkit.layout.BufferControl` and + :class:`~prompt_toolkit.layout.Window`. + + Buffer attributes: + + :param text: The initial text. + :param multiline: If True, allow multiline input. + :param completer: :class:`~prompt_toolkit.completion.Completer` instance + for auto completion. + :param complete_while_typing: Boolean. + :param accept_handler: Called when `Enter` is pressed (This should be a + callable that takes a buffer as input). + :param history: :class:`~prompt_toolkit.history.History` instance. + :param auto_suggest: :class:`~prompt_toolkit.auto_suggest.AutoSuggest` + instance for input suggestions. + + BufferControl attributes: + + :param password: When `True`, display using asterisks. + :param focusable: When `True`, allow this widget to receive the focus. + :param focus_on_click: When `True`, focus after mouse click. + :param input_processors: `None` or a list of + :class:`~prompt_toolkit.layout.Processor` objects. + :param validator: `None` or a :class:`~prompt_toolkit.validation.Validator` + object. + + Window attributes: + + :param lexer: :class:`~prompt_toolkit.lexers.Lexer` instance for syntax + highlighting. + :param wrap_lines: When `True`, don't scroll horizontally, but wrap lines. + :param width: Window width. (:class:`~prompt_toolkit.layout.Dimension` object.) + :param height: Window height. (:class:`~prompt_toolkit.layout.Dimension` object.) + :param scrollbar: When `True`, display a scroll bar. + :param style: A style string. + :param dont_extend_width: When `True`, don't take up more width then the + preferred width reported by the control. + :param dont_extend_height: When `True`, don't take up more width then the + preferred height reported by the control. + :param get_line_prefix: None or a callable that returns formatted text to + be inserted before a line. It takes a line number (int) and a + wrap_count and returns formatted text. This can be used for + implementation of line continuations, things like Vim "breakindent" and + so on. + + Other attributes: + + :param search_field: An optional `SearchToolbar` object. + """ + + def __init__( + self, + text: str = "", + multiline: FilterOrBool = True, + password: FilterOrBool = False, + lexer: Optional[Lexer] = None, + auto_suggest: Optional[AutoSuggest] = None, + completer: Optional[Completer] = None, + complete_while_typing: FilterOrBool = True, + validator: Optional[Validator] = None, + accept_handler: Optional[BufferAcceptHandler] = None, + history: Optional[History] = None, + focusable: FilterOrBool = True, + focus_on_click: FilterOrBool = False, + wrap_lines: FilterOrBool = True, + read_only: FilterOrBool = False, + width: AnyDimension = None, + height: AnyDimension = None, + dont_extend_height: FilterOrBool = False, + dont_extend_width: FilterOrBool = False, + line_numbers: bool = False, + get_line_prefix: Optional[GetLinePrefixCallable] = None, + scrollbar: bool = False, + style: str = "", + search_field: Optional[SearchToolbar] = None, + preview_search: FilterOrBool = True, + prompt: AnyFormattedText = "", + input_processors: Optional[List[Processor]] = None, + ) -> None: + + if search_field is None: + search_control = None + elif isinstance(search_field, SearchToolbar): + search_control = search_field.control + + if input_processors is None: + input_processors = [] + + # Writeable attributes. + self.completer = completer + self.complete_while_typing = complete_while_typing + self.lexer = lexer + self.auto_suggest = auto_suggest + self.read_only = read_only + self.wrap_lines = wrap_lines + self.validator = validator + + self.buffer = Buffer( + document=Document(text, 0), + multiline=multiline, + read_only=Condition(lambda: is_true(self.read_only)), + completer=DynamicCompleter(lambda: self.completer), + complete_while_typing=Condition( + lambda: is_true(self.complete_while_typing) + ), + validator=DynamicValidator(lambda: self.validator), + auto_suggest=DynamicAutoSuggest(lambda: self.auto_suggest), + accept_handler=accept_handler, + history=history, + ) + + self.control = BufferControl( + buffer=self.buffer, + lexer=DynamicLexer(lambda: self.lexer), + input_processors=[ + ConditionalProcessor( + AppendAutoSuggestion(), has_focus(self.buffer) & ~is_done + ), + ConditionalProcessor( + processor=PasswordProcessor(), filter=to_filter(password) + ), + BeforeInput(prompt, style="class:text-area.prompt"), + ] + + input_processors, + search_buffer_control=search_control, + preview_search=preview_search, + focusable=focusable, + focus_on_click=focus_on_click, + ) + + if multiline: + if scrollbar: + right_margins = [ScrollbarMargin(display_arrows=True)] + else: + right_margins = [] + if line_numbers: + left_margins = [NumberedMargin()] + else: + left_margins = [] + else: + height = D.exact(1) + left_margins = [] + right_margins = [] + + style = "class:text-area " + style + + self.window = Window( + height=height, + width=width, + dont_extend_height=dont_extend_height, + dont_extend_width=dont_extend_width, + content=self.control, + style=style, + wrap_lines=Condition(lambda: is_true(self.wrap_lines)), + left_margins=left_margins, + right_margins=right_margins, + get_line_prefix=get_line_prefix, + ) + + @property + def text(self) -> str: + """ + The `Buffer` text. + """ + return self.buffer.text + + @text.setter + def text(self, value: str) -> None: + self.document = Document(value, 0) + + @property + def document(self) -> Document: + """ + The `Buffer` document (text + cursor position). + """ + return self.buffer.document + + @document.setter + def document(self, value: Document) -> None: + self.buffer.set_document(value, bypass_readonly=True) + + @property + def accept_handler(self) -> Optional[BufferAcceptHandler]: + """ + The accept handler. Called when the user accepts the input. + """ + return self.buffer.accept_handler + + @accept_handler.setter + def accept_handler(self, value: BufferAcceptHandler) -> None: + self.buffer.accept_handler = value + + def __pt_container__(self) -> Container: + return self.window + + +class Label: + """ + Widget that displays the given text. It is not editable or focusable. + + :param text: The text to be displayed. (This can be multiline. This can be + formatted text as well.) + :param style: A style string. + :param width: When given, use this width, rather than calculating it from + the text size. + """ + + def __init__( + self, + text: AnyFormattedText, + style: str = "", + width: AnyDimension = None, + dont_extend_height: bool = True, + dont_extend_width: bool = False, + ) -> None: + + self.text = text + + def get_width() -> AnyDimension: + if width is None: + text_fragments = to_formatted_text(self.text) + text = fragment_list_to_text(text_fragments) + if text: + longest_line = max(get_cwidth(line) for line in text.splitlines()) + else: + return D(preferred=0) + return D(preferred=longest_line) + else: + return width + + self.formatted_text_control = FormattedTextControl(text=lambda: self.text) + + self.window = Window( + content=self.formatted_text_control, + width=get_width, + style="class:label " + style, + dont_extend_height=dont_extend_height, + dont_extend_width=dont_extend_width, + ) + + def __pt_container__(self) -> Container: + return self.window + + +class Button: + """ + Clickable button. + + :param text: The caption for the button. + :param handler: `None` or callable. Called when the button is clicked. No + parameters are passed to this callable. Use for instance Python's + `functools.partial` to pass parameters to this callable if needed. + :param width: Width of the button. + """ + + def __init__( + self, text: str, handler: Optional[Callable[[], None]] = None, width: int = 12 + ) -> None: + + self.text = text + self.handler = handler + self.width = width + self.control = FormattedTextControl( + self._get_text_fragments, + key_bindings=self._get_key_bindings(), + focusable=True, + ) + + def get_style() -> str: + if get_app().layout.has_focus(self): + return "class:button.focused" + else: + return "class:button" + + self.window = Window( + self.control, + align=WindowAlign.CENTER, + height=1, + width=width, + style=get_style, + dont_extend_width=True, + dont_extend_height=True, + ) + + def _get_text_fragments(self) -> StyleAndTextTuples: + text = ("{:^%s}" % (self.width - 2)).format(self.text) + + def handler(mouse_event: MouseEvent) -> None: + if ( + self.handler is not None + and mouse_event.event_type == MouseEventType.MOUSE_UP + ): + self.handler() + + return [ + ("class:button.arrow", "<", handler), + ("[SetCursorPosition]", ""), + ("class:button.text", text, handler), + ("class:button.arrow", ">", handler), + ] + + def _get_key_bindings(self) -> KeyBindings: + " Key bindings for the Button. " + kb = KeyBindings() + + @kb.add(" ") + @kb.add("enter") + def _(event: E) -> None: + if self.handler is not None: + self.handler() + + return kb + + def __pt_container__(self) -> Container: + return self.window + + +class Frame: + """ + Draw a border around any container, optionally with a title text. + + Changing the title and body of the frame is possible at runtime by + assigning to the `body` and `title` attributes of this class. + + :param body: Another container object. + :param title: Text to be displayed in the top of the frame (can be formatted text). + :param style: Style string to be applied to this widget. + """ + + def __init__( + self, + body: AnyContainer, + title: AnyFormattedText = "", + style: str = "", + width: AnyDimension = None, + height: AnyDimension = None, + key_bindings: Optional[KeyBindings] = None, + modal: bool = False, + ) -> None: + + self.title = title + self.body = body + + fill = partial(Window, style="class:frame.border") + style = "class:frame " + style + + top_row_with_title = VSplit( + [ + fill(width=1, height=1, char=Border.TOP_LEFT), + fill(char=Border.HORIZONTAL), + fill(width=1, height=1, char="|"), + # Notice: we use `Template` here, because `self.title` can be an + # `HTML` object for instance. + Label( + lambda: Template(" {} ").format(self.title), + style="class:frame.label", + dont_extend_width=True, + ), + fill(width=1, height=1, char="|"), + fill(char=Border.HORIZONTAL), + fill(width=1, height=1, char=Border.TOP_RIGHT), + ], + height=1, + ) + + top_row_without_title = VSplit( + [ + fill(width=1, height=1, char=Border.TOP_LEFT), + fill(char=Border.HORIZONTAL), + fill(width=1, height=1, char=Border.TOP_RIGHT), + ], + height=1, + ) + + @Condition + def has_title() -> bool: + return bool(self.title) + + self.container = HSplit( + [ + ConditionalContainer(content=top_row_with_title, filter=has_title), + ConditionalContainer(content=top_row_without_title, filter=~has_title), + VSplit( + [ + fill(width=1, char=Border.VERTICAL), + DynamicContainer(lambda: self.body), + fill(width=1, char=Border.VERTICAL), + # Padding is required to make sure that if the content is + # too small, the right frame border is still aligned. + ], + padding=0, + ), + VSplit( + [ + fill(width=1, height=1, char=Border.BOTTOM_LEFT), + fill(char=Border.HORIZONTAL), + fill(width=1, height=1, char=Border.BOTTOM_RIGHT), + ] + ), + ], + width=width, + height=height, + style=style, + key_bindings=key_bindings, + modal=modal, + ) + + def __pt_container__(self) -> Container: + return self.container + + +class Shadow: + """ + Draw a shadow underneath/behind this container. + (This applies `class:shadow` the the cells under the shadow. The Style + should define the colors for the shadow.) + + :param body: Another container object. + """ + + def __init__(self, body: AnyContainer) -> None: + self.container = FloatContainer( + content=body, + floats=[ + Float( + bottom=-1, + height=1, + left=1, + right=-1, + transparent=True, + content=Window(style="class:shadow"), + ), + Float( + bottom=-1, + top=1, + width=1, + right=-1, + transparent=True, + content=Window(style="class:shadow"), + ), + ], + ) + + def __pt_container__(self) -> Container: + return self.container + + +class Box: + """ + Add padding around a container. + + This also makes sure that the parent can provide more space than required by + the child. This is very useful when wrapping a small element with a fixed + size into a ``VSplit`` or ``HSplit`` object. The ``HSplit`` and ``VSplit`` + try to make sure to adapt respectively the width and height, possibly + shrinking other elements. Wrapping something in a ``Box`` makes it flexible. + + :param body: Another container object. + :param padding: The margin to be used around the body. This can be + overridden by `padding_left`, padding_right`, `padding_top` and + `padding_bottom`. + :param style: A style string. + :param char: Character to be used for filling the space around the body. + (This is supposed to be a character with a terminal width of 1.) + """ + + def __init__( + self, + body: AnyContainer, + padding: AnyDimension = None, + padding_left: AnyDimension = None, + padding_right: AnyDimension = None, + padding_top: AnyDimension = None, + padding_bottom: AnyDimension = None, + width: AnyDimension = None, + height: AnyDimension = None, + style: str = "", + char: Union[None, str, Callable[[], str]] = None, + modal: bool = False, + key_bindings: Optional[KeyBindings] = None, + ) -> None: + + if padding is None: + padding = D(preferred=0) + + def get(value: AnyDimension) -> D: + if value is None: + value = padding + return to_dimension(value) + + self.padding_left = get(padding_left) + self.padding_right = get(padding_right) + self.padding_top = get(padding_top) + self.padding_bottom = get(padding_bottom) + self.body = body + + self.container = HSplit( + [ + Window(height=self.padding_top, char=char), + VSplit( + [ + Window(width=self.padding_left, char=char), + body, + Window(width=self.padding_right, char=char), + ] + ), + Window(height=self.padding_bottom, char=char), + ], + width=width, + height=height, + style=style, + modal=modal, + key_bindings=None, + ) + + def __pt_container__(self) -> Container: + return self.container + + +_T = TypeVar("_T") + + +class _DialogList(Generic[_T]): + """ + Common code for `RadioList` and `CheckboxList`. + """ + + open_character: str = "" + close_character: str = "" + container_style: str = "" + default_style: str = "" + selected_style: str = "" + checked_style: str = "" + multiple_selection: bool = False + show_scrollbar: bool = True + + def __init__(self, values: Sequence[Tuple[_T, AnyFormattedText]]) -> None: + assert len(values) > 0 + + self.values = values + # current_values will be used in multiple_selection, + # current_value will be used otherwise. + self.current_values: List[_T] = [] + self.current_value: _T = values[0][0] + self._selected_index = 0 + + # Key bindings. + kb = KeyBindings() + + @kb.add("up") + def _up(event: E) -> None: + self._selected_index = max(0, self._selected_index - 1) + + @kb.add("down") + def _down(event: E) -> None: + self._selected_index = min(len(self.values) - 1, self._selected_index + 1) + + @kb.add("pageup") + def _pageup(event: E) -> None: + w = event.app.layout.current_window + if w.render_info: + self._selected_index = max( + 0, self._selected_index - len(w.render_info.displayed_lines) + ) + + @kb.add("pagedown") + def _pagedown(event: E) -> None: + w = event.app.layout.current_window + if w.render_info: + self._selected_index = min( + len(self.values) - 1, + self._selected_index + len(w.render_info.displayed_lines), + ) + + @kb.add("enter") + @kb.add(" ") + def _click(event: E) -> None: + self._handle_enter() + + @kb.add(Keys.Any) + def _find(event: E) -> None: + # We first check values after the selected value, then all values. + values = list(self.values) + for value in values[self._selected_index + 1 :] + values: + text = fragment_list_to_text(to_formatted_text(value[1])).lower() + + if text.startswith(event.data.lower()): + self._selected_index = self.values.index(value) + return + + # Control and window. + self.control = FormattedTextControl( + self._get_text_fragments, key_bindings=kb, focusable=True + ) + + self.window = Window( + content=self.control, + style=self.container_style, + right_margins=[ + ConditionalMargin( + margin=ScrollbarMargin(display_arrows=True), + filter=Condition(lambda: self.show_scrollbar), + ), + ], + dont_extend_height=True, + ) + + def _handle_enter(self) -> None: + if self.multiple_selection: + val = self.values[self._selected_index][0] + if val in self.current_values: + self.current_values.remove(val) + else: + self.current_values.append(val) + else: + self.current_value = self.values[self._selected_index][0] + + def _get_text_fragments(self) -> StyleAndTextTuples: + def mouse_handler(mouse_event: MouseEvent) -> None: + """ + Set `_selected_index` and `current_value` according to the y + position of the mouse click event. + """ + if mouse_event.event_type == MouseEventType.MOUSE_UP: + self._selected_index = mouse_event.position.y + self._handle_enter() + + result: StyleAndTextTuples = [] + for i, value in enumerate(self.values): + if self.multiple_selection: + checked = value[0] in self.current_values + else: + checked = value[0] == self.current_value + selected = i == self._selected_index + + style = "" + if checked: + style += " " + self.checked_style + if selected: + style += " " + self.selected_style + + result.append((style, self.open_character)) + + if selected: + result.append(("[SetCursorPosition]", "")) + + if checked: + result.append((style, "*")) + else: + result.append((style, " ")) + + result.append((style, self.close_character)) + result.append((self.default_style, " ")) + result.extend(to_formatted_text(value[1], style=self.default_style)) + result.append(("", "\n")) + + # Add mouse handler to all fragments. + for i in range(len(result)): + result[i] = (result[i][0], result[i][1], mouse_handler) + + result.pop() # Remove last newline. + return result + + def __pt_container__(self) -> Container: + return self.window + + +class RadioList(_DialogList[_T]): + """ + List of radio buttons. Only one can be checked at the same time. + + :param values: List of (value, label) tuples. + """ + + open_character = "(" + close_character = ")" + container_style = "class:radio-list" + default_style = "class:radio" + selected_style = "class:radio-selected" + checked_style = "class:radio-checked" + multiple_selection = False + + +class CheckboxList(_DialogList[_T]): + """ + List of checkbox buttons. Several can be checked at the same time. + + :param values: List of (value, label) tuples. + """ + + open_character = "[" + close_character = "]" + container_style = "class:checkbox-list" + default_style = "class:checkbox" + selected_style = "class:checkbox-selected" + checked_style = "class:checkbox-checked" + multiple_selection = True + + +class Checkbox(CheckboxList[str]): + """Backward compatibility util: creates a 1-sized CheckboxList + + :param text: the text + """ + + show_scrollbar = False + + def __init__(self, text: AnyFormattedText = "", checked: bool = False) -> None: + values = [("value", text)] + CheckboxList.__init__(self, values) + self.checked = checked + + @property + def checked(self) -> bool: + return "value" in self.current_values + + @checked.setter + def checked(self, value: bool) -> None: + if value: + self.current_values = ["value"] + else: + self.current_values = [] + + +class VerticalLine(object): + """ + A simple vertical line with a width of 1. + """ + + def __init__(self) -> None: + self.window = Window( + char=Border.VERTICAL, style="class:line,vertical-line", width=1 + ) + + def __pt_container__(self) -> Container: + return self.window + + +class HorizontalLine: + """ + A simple horizontal line with a height of 1. + """ + + def __init__(self) -> None: + self.window = Window( + char=Border.HORIZONTAL, style="class:line,horizontal-line", height=1 + ) + + def __pt_container__(self) -> Container: + return self.window + + +class ProgressBar: + def __init__(self) -> None: + self._percentage = 60 + + self.label = Label("60%") + self.container = FloatContainer( + content=Window(height=1), + floats=[ + # We first draw the label, then the actual progress bar. Right + # now, this is the only way to have the colors of the progress + # bar appear on top of the label. The problem is that our label + # can't be part of any `Window` below. + Float(content=self.label, top=0, bottom=0), + Float( + left=0, + top=0, + right=0, + bottom=0, + content=VSplit( + [ + Window( + style="class:progress-bar.used", + width=lambda: D(weight=int(self._percentage)), + ), + Window( + style="class:progress-bar", + width=lambda: D(weight=int(100 - self._percentage)), + ), + ] + ), + ), + ], + ) + + @property + def percentage(self) -> int: + return self._percentage + + @percentage.setter + def percentage(self, value: int) -> None: + self._percentage = value + self.label.text = "{0}%".format(value) + + def __pt_container__(self) -> Container: + return self.container diff --git a/.venv/lib/python3.8/site-packages/prompt_toolkit/widgets/dialogs.py b/.venv/lib/python3.8/site-packages/prompt_toolkit/widgets/dialogs.py new file mode 100644 index 00000000..920582b4 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/prompt_toolkit/widgets/dialogs.py @@ -0,0 +1,106 @@ +""" +Collection of reusable components for building full screen applications. +""" +from typing import Optional, Sequence, Union + +from prompt_toolkit.filters import has_completions, has_focus +from prompt_toolkit.formatted_text import AnyFormattedText +from prompt_toolkit.key_binding.bindings.focus import focus_next, focus_previous +from prompt_toolkit.key_binding.key_bindings import KeyBindings +from prompt_toolkit.layout.containers import ( + AnyContainer, + DynamicContainer, + HSplit, + VSplit, +) +from prompt_toolkit.layout.dimension import AnyDimension +from prompt_toolkit.layout.dimension import Dimension as D + +from .base import Box, Button, Frame, Shadow + +__all__ = [ + "Dialog", +] + + +class Dialog: + """ + Simple dialog window. This is the base for input dialogs, message dialogs + and confirmation dialogs. + + Changing the title and body of the dialog is possible at runtime by + assigning to the `body` and `title` attributes of this class. + + :param body: Child container object. + :param title: Text to be displayed in the heading of the dialog. + :param buttons: A list of `Button` widgets, displayed at the bottom. + """ + + def __init__( + self, + body: AnyContainer, + title: AnyFormattedText = "", + buttons: Optional[Sequence[Button]] = None, + modal: bool = True, + width: AnyDimension = None, + with_background: bool = False, + ) -> None: + + self.body = body + self.title = title + + buttons = buttons or [] + + # When a button is selected, handle left/right key bindings. + buttons_kb = KeyBindings() + if len(buttons) > 1: + first_selected = has_focus(buttons[0]) + last_selected = has_focus(buttons[-1]) + + buttons_kb.add("left", filter=~first_selected)(focus_previous) + buttons_kb.add("right", filter=~last_selected)(focus_next) + + frame_body: AnyContainer + if buttons: + frame_body = HSplit( + [ + # Add optional padding around the body. + Box( + body=DynamicContainer(lambda: self.body), + padding=D(preferred=1, max=1), + padding_bottom=0, + ), + # The buttons. + Box( + body=VSplit(buttons, padding=1, key_bindings=buttons_kb), + height=D(min=1, max=3, preferred=3), + ), + ] + ) + else: + frame_body = body + + # Key bindings for whole dialog. + kb = KeyBindings() + kb.add("tab", filter=~has_completions)(focus_next) + kb.add("s-tab", filter=~has_completions)(focus_previous) + + frame = Shadow( + body=Frame( + title=lambda: self.title, + body=frame_body, + style="class:dialog.body", + width=(None if with_background is None else width), + key_bindings=kb, + modal=modal, + ) + ) + + self.container: Union[Box, Shadow] + if with_background: + self.container = Box(body=frame, style="class:dialog", width=width) + else: + self.container = frame + + def __pt_container__(self) -> AnyContainer: + return self.container diff --git a/.venv/lib/python3.8/site-packages/prompt_toolkit/widgets/menus.py b/.venv/lib/python3.8/site-packages/prompt_toolkit/widgets/menus.py new file mode 100644 index 00000000..4408ec65 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/prompt_toolkit/widgets/menus.py @@ -0,0 +1,360 @@ +from typing import Callable, Iterable, List, Optional, Sequence, Union + +from prompt_toolkit.application.current import get_app +from prompt_toolkit.filters import Condition +from prompt_toolkit.formatted_text.base import OneStyleAndTextTuple, StyleAndTextTuples +from prompt_toolkit.key_binding.key_bindings import KeyBindings, KeyBindingsBase +from prompt_toolkit.key_binding.key_processor import KeyPressEvent +from prompt_toolkit.keys import Keys +from prompt_toolkit.layout.containers import ( + AnyContainer, + ConditionalContainer, + Container, + Float, + FloatContainer, + HSplit, + Window, +) +from prompt_toolkit.layout.controls import FormattedTextControl +from prompt_toolkit.mouse_events import MouseEvent, MouseEventType +from prompt_toolkit.utils import get_cwidth +from prompt_toolkit.widgets import Shadow + +from .base import Border + +__all__ = [ + "MenuContainer", + "MenuItem", +] + +E = KeyPressEvent + + +class MenuContainer: + """ + :param floats: List of extra Float objects to display. + :param menu_items: List of `MenuItem` objects. + """ + + def __init__( + self, + body: AnyContainer, + menu_items: List["MenuItem"], + floats: Optional[List[Float]] = None, + key_bindings: Optional[KeyBindingsBase] = None, + ) -> None: + + self.body = body + self.menu_items = menu_items + self.selected_menu = [0] + + # Key bindings. + kb = KeyBindings() + + @Condition + def in_main_menu() -> bool: + return len(self.selected_menu) == 1 + + @Condition + def in_sub_menu() -> bool: + return len(self.selected_menu) > 1 + + # Navigation through the main menu. + + @kb.add("left", filter=in_main_menu) + def _left(event: E) -> None: + self.selected_menu[0] = max(0, self.selected_menu[0] - 1) + + @kb.add("right", filter=in_main_menu) + def _right(event: E) -> None: + self.selected_menu[0] = min( + len(self.menu_items) - 1, self.selected_menu[0] + 1 + ) + + @kb.add("down", filter=in_main_menu) + def _down(event: E) -> None: + self.selected_menu.append(0) + + @kb.add("c-c", filter=in_main_menu) + @kb.add("c-g", filter=in_main_menu) + def _cancel(event: E) -> None: + " Leave menu. " + event.app.layout.focus_last() + + # Sub menu navigation. + + @kb.add("left", filter=in_sub_menu) + @kb.add("c-g", filter=in_sub_menu) + @kb.add("c-c", filter=in_sub_menu) + def _back(event: E) -> None: + " Go back to parent menu. " + if len(self.selected_menu) > 1: + self.selected_menu.pop() + + @kb.add("right", filter=in_sub_menu) + def _submenu(event: E) -> None: + " go into sub menu. " + if self._get_menu(len(self.selected_menu) - 1).children: + self.selected_menu.append(0) + + # If This item does not have a sub menu. Go up in the parent menu. + elif ( + len(self.selected_menu) == 2 + and self.selected_menu[0] < len(self.menu_items) - 1 + ): + self.selected_menu = [ + min(len(self.menu_items) - 1, self.selected_menu[0] + 1) + ] + if self.menu_items[self.selected_menu[0]].children: + self.selected_menu.append(0) + + @kb.add("up", filter=in_sub_menu) + def _up_in_submenu(event: E) -> None: + " Select previous (enabled) menu item or return to main menu. " + # Look for previous enabled items in this sub menu. + menu = self._get_menu(len(self.selected_menu) - 2) + index = self.selected_menu[-1] + + previous_indexes = [ + i + for i, item in enumerate(menu.children) + if i < index and not item.disabled + ] + + if previous_indexes: + self.selected_menu[-1] = previous_indexes[-1] + elif len(self.selected_menu) == 2: + # Return to main menu. + self.selected_menu.pop() + + @kb.add("down", filter=in_sub_menu) + def _down_in_submenu(event: E) -> None: + " Select next (enabled) menu item. " + menu = self._get_menu(len(self.selected_menu) - 2) + index = self.selected_menu[-1] + + next_indexes = [ + i + for i, item in enumerate(menu.children) + if i > index and not item.disabled + ] + + if next_indexes: + self.selected_menu[-1] = next_indexes[0] + + @kb.add("enter") + def _click(event: E) -> None: + " Click the selected menu item. " + item = self._get_menu(len(self.selected_menu) - 1) + if item.handler: + event.app.layout.focus_last() + item.handler() + + # Controls. + self.control = FormattedTextControl( + self._get_menu_fragments, key_bindings=kb, focusable=True, show_cursor=False + ) + + self.window = Window(height=1, content=self.control, style="class:menu-bar") + + submenu = self._submenu(0) + submenu2 = self._submenu(1) + submenu3 = self._submenu(2) + + @Condition + def has_focus() -> bool: + return get_app().layout.current_window == self.window + + self.container = FloatContainer( + content=HSplit( + [ + # The titlebar. + self.window, + # The 'body', like defined above. + body, + ] + ), + floats=[ + Float( + xcursor=True, + ycursor=True, + content=ConditionalContainer( + content=Shadow(body=submenu), filter=has_focus + ), + ), + Float( + attach_to_window=submenu, + xcursor=True, + ycursor=True, + allow_cover_cursor=True, + content=ConditionalContainer( + content=Shadow(body=submenu2), + filter=has_focus + & Condition(lambda: len(self.selected_menu) >= 1), + ), + ), + Float( + attach_to_window=submenu2, + xcursor=True, + ycursor=True, + allow_cover_cursor=True, + content=ConditionalContainer( + content=Shadow(body=submenu3), + filter=has_focus + & Condition(lambda: len(self.selected_menu) >= 2), + ), + ), + # -- + ] + + (floats or []), + key_bindings=key_bindings, + ) + + def _get_menu(self, level: int) -> "MenuItem": + menu = self.menu_items[self.selected_menu[0]] + + for i, index in enumerate(self.selected_menu[1:]): + if i < level: + try: + menu = menu.children[index] + except IndexError: + return MenuItem("debug") + + return menu + + def _get_menu_fragments(self) -> StyleAndTextTuples: + focused = get_app().layout.has_focus(self.window) + + # This is called during the rendering. When we discover that this + # widget doesn't have the focus anymore. Reset menu state. + if not focused: + self.selected_menu = [0] + + # Generate text fragments for the main menu. + def one_item(i: int, item: MenuItem) -> Iterable[OneStyleAndTextTuple]: + def mouse_handler(mouse_event: MouseEvent) -> None: + if mouse_event.event_type == MouseEventType.MOUSE_UP: + # Toggle focus. + app = get_app() + if app.layout.has_focus(self.window): + if self.selected_menu == [i]: + app.layout.focus_last() + else: + app.layout.focus(self.window) + self.selected_menu = [i] + + yield ("class:menu-bar", " ", mouse_handler) + if i == self.selected_menu[0] and focused: + yield ("[SetMenuPosition]", "", mouse_handler) + style = "class:menu-bar.selected-item" + else: + style = "class:menu-bar" + yield style, item.text, mouse_handler + + result: StyleAndTextTuples = [] + for i, item in enumerate(self.menu_items): + result.extend(one_item(i, item)) + + return result + + def _submenu(self, level: int = 0) -> Window: + def get_text_fragments() -> StyleAndTextTuples: + result: StyleAndTextTuples = [] + if level < len(self.selected_menu): + menu = self._get_menu(level) + if menu.children: + result.append(("class:menu", Border.TOP_LEFT)) + result.append(("class:menu", Border.HORIZONTAL * (menu.width + 4))) + result.append(("class:menu", Border.TOP_RIGHT)) + result.append(("", "\n")) + try: + selected_item = self.selected_menu[level + 1] + except IndexError: + selected_item = -1 + + def one_item( + i: int, item: MenuItem + ) -> Iterable[OneStyleAndTextTuple]: + def mouse_handler(mouse_event: MouseEvent) -> None: + if mouse_event.event_type == MouseEventType.MOUSE_UP: + app = get_app() + if item.handler: + app.layout.focus_last() + item.handler() + else: + self.selected_menu = self.selected_menu[ + : level + 1 + ] + [i] + + if i == selected_item: + yield ("[SetCursorPosition]", "") + style = "class:menu-bar.selected-item" + else: + style = "" + + yield ("class:menu", Border.VERTICAL) + if item.text == "-": + yield ( + style + "class:menu-border", + "{}".format(Border.HORIZONTAL * (menu.width + 3)), + mouse_handler, + ) + else: + yield ( + style, + " {}".format(item.text).ljust(menu.width + 3), + mouse_handler, + ) + + if item.children: + yield (style, ">", mouse_handler) + else: + yield (style, " ", mouse_handler) + + if i == selected_item: + yield ("[SetMenuPosition]", "") + yield ("class:menu", Border.VERTICAL) + + yield ("", "\n") + + for i, item in enumerate(menu.children): + result.extend(one_item(i, item)) + + result.append(("class:menu", Border.BOTTOM_LEFT)) + result.append(("class:menu", Border.HORIZONTAL * (menu.width + 4))) + result.append(("class:menu", Border.BOTTOM_RIGHT)) + return result + + return Window(FormattedTextControl(get_text_fragments), style="class:menu") + + @property + def floats(self) -> Optional[List[Float]]: + return self.container.floats + + def __pt_container__(self) -> Container: + return self.container + + +class MenuItem: + def __init__( + self, + text: str = "", + handler: Optional[Callable[[], None]] = None, + children: Optional[List["MenuItem"]] = None, + shortcut: Optional[Sequence[Union[Keys, str]]] = None, + disabled: bool = False, + ) -> None: + + self.text = text + self.handler = handler + self.children = children or [] + self.shortcut = shortcut + self.disabled = disabled + self.selected_item = 0 + + @property + def width(self) -> int: + if self.children: + return max(get_cwidth(c.text) for c in self.children) + else: + return 0 diff --git a/.venv/lib/python3.8/site-packages/prompt_toolkit/widgets/toolbars.py b/.venv/lib/python3.8/site-packages/prompt_toolkit/widgets/toolbars.py new file mode 100644 index 00000000..b9dd8484 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/prompt_toolkit/widgets/toolbars.py @@ -0,0 +1,374 @@ +from typing import Optional + +from prompt_toolkit.application.current import get_app +from prompt_toolkit.buffer import Buffer +from prompt_toolkit.enums import SYSTEM_BUFFER +from prompt_toolkit.filters import ( + Condition, + FilterOrBool, + emacs_mode, + has_arg, + has_completions, + has_focus, + has_validation_error, + to_filter, + vi_mode, + vi_navigation_mode, +) +from prompt_toolkit.formatted_text import ( + AnyFormattedText, + StyleAndTextTuples, + fragment_list_len, + to_formatted_text, +) +from prompt_toolkit.key_binding.key_bindings import ( + ConditionalKeyBindings, + KeyBindings, + KeyBindingsBase, + merge_key_bindings, +) +from prompt_toolkit.key_binding.key_processor import KeyPressEvent +from prompt_toolkit.key_binding.vi_state import InputMode +from prompt_toolkit.keys import Keys +from prompt_toolkit.layout.containers import ConditionalContainer, Container, Window +from prompt_toolkit.layout.controls import ( + BufferControl, + FormattedTextControl, + SearchBufferControl, + UIContent, + UIControl, +) +from prompt_toolkit.layout.dimension import Dimension +from prompt_toolkit.layout.processors import BeforeInput +from prompt_toolkit.lexers import SimpleLexer +from prompt_toolkit.search import SearchDirection + +__all__ = [ + "ArgToolbar", + "CompletionsToolbar", + "FormattedTextToolbar", + "SearchToolbar", + "SystemToolbar", + "ValidationToolbar", +] + +E = KeyPressEvent + + +class FormattedTextToolbar(Window): + def __init__(self, text: AnyFormattedText, style: str = "", **kw) -> None: + # Note: The style needs to be applied to the toolbar as a whole, not + # just the `FormattedTextControl`. + super().__init__( + FormattedTextControl(text, **kw), + style=style, + dont_extend_height=True, + height=Dimension(min=1), + ) + + +class SystemToolbar: + """ + Toolbar for a system prompt. + + :param prompt: Prompt to be displayed to the user. + """ + + def __init__( + self, + prompt: AnyFormattedText = "Shell command: ", + enable_global_bindings: FilterOrBool = True, + ) -> None: + + self.prompt = prompt + self.enable_global_bindings = to_filter(enable_global_bindings) + + self.system_buffer = Buffer(name=SYSTEM_BUFFER) + + self._bindings = self._build_key_bindings() + + self.buffer_control = BufferControl( + buffer=self.system_buffer, + lexer=SimpleLexer(style="class:system-toolbar.text"), + input_processors=[ + BeforeInput(lambda: self.prompt, style="class:system-toolbar") + ], + key_bindings=self._bindings, + ) + + self.window = Window( + self.buffer_control, height=1, style="class:system-toolbar" + ) + + self.container = ConditionalContainer( + content=self.window, filter=has_focus(self.system_buffer) + ) + + def _get_display_before_text(self) -> StyleAndTextTuples: + return [ + ("class:system-toolbar", "Shell command: "), + ("class:system-toolbar.text", self.system_buffer.text), + ("", "\n"), + ] + + def _build_key_bindings(self) -> KeyBindingsBase: + focused = has_focus(self.system_buffer) + + # Emacs + emacs_bindings = KeyBindings() + handle = emacs_bindings.add + + @handle("escape", filter=focused) + @handle("c-g", filter=focused) + @handle("c-c", filter=focused) + def _cancel(event: E) -> None: + " Hide system prompt. " + self.system_buffer.reset() + event.app.layout.focus_last() + + @handle("enter", filter=focused) + def _accept(event: E) -> None: + " Run system command. " + event.app.run_system_command( + self.system_buffer.text, + display_before_text=self._get_display_before_text(), + ) + self.system_buffer.reset(append_to_history=True) + event.app.layout.focus_last() + + # Vi. + vi_bindings = KeyBindings() + handle = vi_bindings.add + + @handle("escape", filter=focused) + @handle("c-c", filter=focused) + def _cancel_vi(event: E) -> None: + " Hide system prompt. " + event.app.vi_state.input_mode = InputMode.NAVIGATION + self.system_buffer.reset() + event.app.layout.focus_last() + + @handle("enter", filter=focused) + def _accept_vi(event: E) -> None: + " Run system command. " + event.app.vi_state.input_mode = InputMode.NAVIGATION + event.app.run_system_command( + self.system_buffer.text, + display_before_text=self._get_display_before_text(), + ) + self.system_buffer.reset(append_to_history=True) + event.app.layout.focus_last() + + # Global bindings. (Listen to these bindings, even when this widget is + # not focussed.) + global_bindings = KeyBindings() + handle = global_bindings.add + + @handle(Keys.Escape, "!", filter=~focused & emacs_mode, is_global=True) + def _focus_me(event: E) -> None: + " M-'!' will focus this user control. " + event.app.layout.focus(self.window) + + @handle("!", filter=~focused & vi_mode & vi_navigation_mode, is_global=True) + def _focus_me_vi(event: E) -> None: + " Focus. " + event.app.vi_state.input_mode = InputMode.INSERT + event.app.layout.focus(self.window) + + return merge_key_bindings( + [ + ConditionalKeyBindings(emacs_bindings, emacs_mode), + ConditionalKeyBindings(vi_bindings, vi_mode), + ConditionalKeyBindings(global_bindings, self.enable_global_bindings), + ] + ) + + def __pt_container__(self) -> Container: + return self.container + + +class ArgToolbar: + def __init__(self) -> None: + def get_formatted_text() -> StyleAndTextTuples: + arg = get_app().key_processor.arg or "" + if arg == "-": + arg = "-1" + + return [ + ("class:arg-toolbar", "Repeat: "), + ("class:arg-toolbar.text", arg), + ] + + self.window = Window(FormattedTextControl(get_formatted_text), height=1) + + self.container = ConditionalContainer(content=self.window, filter=has_arg) + + def __pt_container__(self) -> Container: + return self.container + + +class SearchToolbar: + """ + :param vi_mode: Display '/' and '?' instead of I-search. + :param ignore_case: Search case insensitive. + """ + + def __init__( + self, + search_buffer: Optional[Buffer] = None, + vi_mode: bool = False, + text_if_not_searching: AnyFormattedText = "", + forward_search_prompt: AnyFormattedText = "I-search: ", + backward_search_prompt: AnyFormattedText = "I-search backward: ", + ignore_case: FilterOrBool = False, + ) -> None: + + if search_buffer is None: + search_buffer = Buffer() + + @Condition + def is_searching() -> bool: + return self.control in get_app().layout.search_links + + def get_before_input() -> AnyFormattedText: + if not is_searching(): + return text_if_not_searching + elif ( + self.control.searcher_search_state.direction == SearchDirection.BACKWARD + ): + return "?" if vi_mode else backward_search_prompt + else: + return "/" if vi_mode else forward_search_prompt + + self.search_buffer = search_buffer + + self.control = SearchBufferControl( + buffer=search_buffer, + input_processors=[ + BeforeInput(get_before_input, style="class:search-toolbar.prompt") + ], + lexer=SimpleLexer(style="class:search-toolbar.text"), + ignore_case=ignore_case, + ) + + self.container = ConditionalContainer( + content=Window(self.control, height=1, style="class:search-toolbar"), + filter=is_searching, + ) + + def __pt_container__(self) -> Container: + return self.container + + +class _CompletionsToolbarControl(UIControl): + def create_content(self, width: int, height: int) -> UIContent: + all_fragments: StyleAndTextTuples = [] + + complete_state = get_app().current_buffer.complete_state + if complete_state: + completions = complete_state.completions + index = complete_state.complete_index # Can be None! + + # Width of the completions without the left/right arrows in the margins. + content_width = width - 6 + + # Booleans indicating whether we stripped from the left/right + cut_left = False + cut_right = False + + # Create Menu content. + fragments: StyleAndTextTuples = [] + + for i, c in enumerate(completions): + # When there is no more place for the next completion + if fragment_list_len(fragments) + len(c.display_text) >= content_width: + # If the current one was not yet displayed, page to the next sequence. + if i <= (index or 0): + fragments = [] + cut_left = True + # If the current one is visible, stop here. + else: + cut_right = True + break + + fragments.extend( + to_formatted_text( + c.display_text, + style=( + "class:completion-toolbar.completion.current" + if i == index + else "class:completion-toolbar.completion" + ), + ) + ) + fragments.append(("", " ")) + + # Extend/strip until the content width. + fragments.append(("", " " * (content_width - fragment_list_len(fragments)))) + fragments = fragments[:content_width] + + # Return fragments + all_fragments.append(("", " ")) + all_fragments.append( + ("class:completion-toolbar.arrow", "<" if cut_left else " ") + ) + all_fragments.append(("", " ")) + + all_fragments.extend(fragments) + + all_fragments.append(("", " ")) + all_fragments.append( + ("class:completion-toolbar.arrow", ">" if cut_right else " ") + ) + all_fragments.append(("", " ")) + + def get_line(i: int) -> StyleAndTextTuples: + return all_fragments + + return UIContent(get_line=get_line, line_count=1) + + +class CompletionsToolbar: + def __init__(self) -> None: + self.container = ConditionalContainer( + content=Window( + _CompletionsToolbarControl(), height=1, style="class:completion-toolbar" + ), + filter=has_completions, + ) + + def __pt_container__(self) -> Container: + return self.container + + +class ValidationToolbar: + def __init__(self, show_position: bool = False) -> None: + def get_formatted_text() -> StyleAndTextTuples: + buff = get_app().current_buffer + + if buff.validation_error: + row, column = buff.document.translate_index_to_position( + buff.validation_error.cursor_position + ) + + if show_position: + text = "%s (line=%s column=%s)" % ( + buff.validation_error.message, + row + 1, + column + 1, + ) + else: + text = buff.validation_error.message + + return [("class:validation-toolbar", text)] + else: + return [] + + self.control = FormattedTextControl(get_formatted_text) + + self.container = ConditionalContainer( + content=Window(self.control, height=1), filter=has_validation_error + ) + + def __pt_container__(self) -> Container: + return self.container diff --git a/.venv/lib/python3.8/site-packages/prompt_toolkit/win32_types.py b/.venv/lib/python3.8/site-packages/prompt_toolkit/win32_types.py new file mode 100644 index 00000000..8439b75c --- /dev/null +++ b/.venv/lib/python3.8/site-packages/prompt_toolkit/win32_types.py @@ -0,0 +1,166 @@ +from ctypes import Structure, Union, c_char, c_long, c_short, c_ulong +from ctypes.wintypes import BOOL, DWORD, LPVOID, WCHAR, WORD + +# Input/Output standard device numbers. Note that these are not handle objects. +# It's the `windll.kernel32.GetStdHandle` system call that turns them into a +# real handle object. +STD_INPUT_HANDLE = c_ulong(-10) +STD_OUTPUT_HANDLE = c_ulong(-11) +STD_ERROR_HANDLE = c_ulong(-12) + + +class COORD(Structure): + """ + Struct in wincon.h + http://msdn.microsoft.com/en-us/library/windows/desktop/ms682119(v=vs.85).aspx + """ + + _fields_ = [ + ("X", c_short), # Short + ("Y", c_short), # Short + ] + + def __repr__(self) -> str: + return "%s(X=%r, Y=%r, type_x=%r, type_y=%r)" % ( + self.__class__.__name__, + self.X, + self.Y, + type(self.X), + type(self.Y), + ) + + +class UNICODE_OR_ASCII(Union): + _fields_ = [ + ("AsciiChar", c_char), + ("UnicodeChar", WCHAR), + ] + + +class KEY_EVENT_RECORD(Structure): + """ + http://msdn.microsoft.com/en-us/library/windows/desktop/ms684166(v=vs.85).aspx + """ + + _fields_ = [ + ("KeyDown", c_long), # bool + ("RepeatCount", c_short), # word + ("VirtualKeyCode", c_short), # word + ("VirtualScanCode", c_short), # word + ("uChar", UNICODE_OR_ASCII), # Unicode or ASCII. + ("ControlKeyState", c_long), # double word + ] + + +class MOUSE_EVENT_RECORD(Structure): + """ + http://msdn.microsoft.com/en-us/library/windows/desktop/ms684239(v=vs.85).aspx + """ + + _fields_ = [ + ("MousePosition", COORD), + ("ButtonState", c_long), # dword + ("ControlKeyState", c_long), # dword + ("EventFlags", c_long), # dword + ] + + +class WINDOW_BUFFER_SIZE_RECORD(Structure): + """ + http://msdn.microsoft.com/en-us/library/windows/desktop/ms687093(v=vs.85).aspx + """ + + _fields_ = [("Size", COORD)] + + +class MENU_EVENT_RECORD(Structure): + """ + http://msdn.microsoft.com/en-us/library/windows/desktop/ms684213(v=vs.85).aspx + """ + + _fields_ = [("CommandId", c_long)] # uint + + +class FOCUS_EVENT_RECORD(Structure): + """ + http://msdn.microsoft.com/en-us/library/windows/desktop/ms683149(v=vs.85).aspx + """ + + _fields_ = [("SetFocus", c_long)] # bool + + +class EVENT_RECORD(Union): + _fields_ = [ + ("KeyEvent", KEY_EVENT_RECORD), + ("MouseEvent", MOUSE_EVENT_RECORD), + ("WindowBufferSizeEvent", WINDOW_BUFFER_SIZE_RECORD), + ("MenuEvent", MENU_EVENT_RECORD), + ("FocusEvent", FOCUS_EVENT_RECORD), + ] + + +class INPUT_RECORD(Structure): + """ + http://msdn.microsoft.com/en-us/library/windows/desktop/ms683499(v=vs.85).aspx + """ + + _fields_ = [("EventType", c_short), ("Event", EVENT_RECORD)] # word # Union. + + +EventTypes = { + 1: "KeyEvent", + 2: "MouseEvent", + 4: "WindowBufferSizeEvent", + 8: "MenuEvent", + 16: "FocusEvent", +} + + +class SMALL_RECT(Structure): + """struct in wincon.h.""" + + _fields_ = [ + ("Left", c_short), + ("Top", c_short), + ("Right", c_short), + ("Bottom", c_short), + ] + + +class CONSOLE_SCREEN_BUFFER_INFO(Structure): + """struct in wincon.h.""" + + _fields_ = [ + ("dwSize", COORD), + ("dwCursorPosition", COORD), + ("wAttributes", WORD), + ("srWindow", SMALL_RECT), + ("dwMaximumWindowSize", COORD), + ] + + def __str__(self) -> str: + return "(%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d)" % ( + self.dwSize.Y, + self.dwSize.X, + self.dwCursorPosition.Y, + self.dwCursorPosition.X, + self.wAttributes, + self.srWindow.Top, + self.srWindow.Left, + self.srWindow.Bottom, + self.srWindow.Right, + self.dwMaximumWindowSize.Y, + self.dwMaximumWindowSize.X, + ) + + +class SECURITY_ATTRIBUTES(Structure): + """ + http://msdn.microsoft.com/en-us/library/windows/desktop/aa379560(v=vs.85).aspx + """ + + _fields_ = [ + ("nLength", DWORD), + ("lpSecurityDescriptor", LPVOID), + ("bInheritHandle", BOOL), + ] diff --git a/.venv/lib/python3.8/site-packages/ptyprocess-0.6.0.dist-info/INSTALLER b/.venv/lib/python3.8/site-packages/ptyprocess-0.6.0.dist-info/INSTALLER new file mode 100644 index 00000000..a1b589e3 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/ptyprocess-0.6.0.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/.venv/lib/python3.8/site-packages/ptyprocess-0.6.0.dist-info/LICENSE b/.venv/lib/python3.8/site-packages/ptyprocess-0.6.0.dist-info/LICENSE new file mode 100644 index 00000000..9c772742 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/ptyprocess-0.6.0.dist-info/LICENSE @@ -0,0 +1,16 @@ +Ptyprocess is under the ISC license, as code derived from Pexpect. + http://opensource.org/licenses/ISC + +Copyright (c) 2013-2014, Pexpect development team +Copyright (c) 2012, Noah Spurrier + +PERMISSION TO USE, COPY, MODIFY, AND/OR DISTRIBUTE THIS SOFTWARE FOR ANY PURPOSE +WITH OR WITHOUT FEE IS HEREBY GRANTED, PROVIDED THAT THE ABOVE COPYRIGHT NOTICE +AND THIS PERMISSION NOTICE APPEAR IN ALL COPIES. THE SOFTWARE IS PROVIDED +"AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE +INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT +SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL +DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING +OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + diff --git a/.venv/lib/python3.8/site-packages/ptyprocess-0.6.0.dist-info/METADATA b/.venv/lib/python3.8/site-packages/ptyprocess-0.6.0.dist-info/METADATA new file mode 100644 index 00000000..f38abfe7 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/ptyprocess-0.6.0.dist-info/METADATA @@ -0,0 +1,37 @@ +Metadata-Version: 2.1 +Name: ptyprocess +Version: 0.6.0 +Summary: Run a subprocess in a pseudo terminal +Home-page: https://github.com/pexpect/ptyprocess +License: UNKNOWN +Author: Thomas Kluyver +Author-email: thomas@kluyver.me.uk +Description-Content-Type: text/x-rst +Classifier: Development Status :: 5 - Production/Stable +Classifier: Environment :: Console +Classifier: Intended Audience :: Developers +Classifier: Intended Audience :: System Administrators +Classifier: License :: OSI Approved :: ISC License (ISCL) +Classifier: Operating System :: POSIX +Classifier: Operating System :: MacOS :: MacOS X +Classifier: Programming Language :: Python +Classifier: Programming Language :: Python :: 2.7 +Classifier: Programming Language :: Python :: 3 +Classifier: Topic :: Terminals + +Launch a subprocess in a pseudo terminal (pty), and interact with both the +process and its pty. + +Sometimes, piping stdin and stdout is not enough. There might be a password +prompt that doesn't read from stdin, output that changes when it's going to a +pipe rather than a terminal, or curses-style interfaces that rely on a terminal. +If you need to automate these things, running the process in a pseudo terminal +(pty) is the answer. + +Interface:: + + p = PtyProcessUnicode.spawn(['python']) + p.read(20) + p.write('6+6\n') + p.read(20) + diff --git a/.venv/lib/python3.8/site-packages/ptyprocess-0.6.0.dist-info/RECORD b/.venv/lib/python3.8/site-packages/ptyprocess-0.6.0.dist-info/RECORD new file mode 100644 index 00000000..0d72db53 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/ptyprocess-0.6.0.dist-info/RECORD @@ -0,0 +1,13 @@ +ptyprocess-0.6.0.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +ptyprocess-0.6.0.dist-info/LICENSE,sha256=yCLThbGnMymEYkF5m-zxhpC11Edkwb7WkwC1NqQFAwo,905 +ptyprocess-0.6.0.dist-info/METADATA,sha256=E32CAJai9AnGYv75eEH1QQngK3Sg-v1JEOJ2q-FOD3Q,1312 +ptyprocess-0.6.0.dist-info/RECORD,, +ptyprocess-0.6.0.dist-info/WHEEL,sha256=Pnb1-aANNEDpiI6zZkifNVAxs3Mjlbjz3HYhduOZleI,97 +ptyprocess/__init__.py,sha256=Q7Cd31VTCkFWg4KPHqZ75ykOQ7kj5kuo-tzkqOz8suo,138 +ptyprocess/__pycache__/__init__.cpython-38.pyc,, +ptyprocess/__pycache__/_fork_pty.cpython-38.pyc,, +ptyprocess/__pycache__/ptyprocess.cpython-38.pyc,, +ptyprocess/__pycache__/util.cpython-38.pyc,, +ptyprocess/_fork_pty.py,sha256=VVvMy8c4ZpjDMiIMSg8T1BQ1g3SBexDpey_cxi0n5aw,2362 +ptyprocess/ptyprocess.py,sha256=rD_1VuW02HxwB4hPIm6cah5XGx7pHj8QaYz5OhCXwf4,31355 +ptyprocess/util.py,sha256=rQAdDRZfoOiOn6vykWth0wI6FFKAp7aJtBSdt-KBWdU,2785 diff --git a/.venv/lib/python3.8/site-packages/ptyprocess-0.6.0.dist-info/WHEEL b/.venv/lib/python3.8/site-packages/ptyprocess-0.6.0.dist-info/WHEEL new file mode 100644 index 00000000..2d80143d --- /dev/null +++ b/.venv/lib/python3.8/site-packages/ptyprocess-0.6.0.dist-info/WHEEL @@ -0,0 +1,5 @@ +Wheel-Version: 1.0 +Generator: flit 1.0 +Root-Is-Purelib: true +Tag: py2-none-any +Tag: py3-none-any diff --git a/.venv/lib/python3.8/site-packages/ptyprocess/__init__.py b/.venv/lib/python3.8/site-packages/ptyprocess/__init__.py new file mode 100644 index 00000000..e633d0cd --- /dev/null +++ b/.venv/lib/python3.8/site-packages/ptyprocess/__init__.py @@ -0,0 +1,4 @@ +"""Run a subprocess in a pseudo terminal""" +from .ptyprocess import PtyProcess, PtyProcessUnicode, PtyProcessError + +__version__ = '0.6.0' diff --git a/.venv/lib/python3.8/site-packages/ptyprocess/__pycache__/__init__.cpython-38.pyc b/.venv/lib/python3.8/site-packages/ptyprocess/__pycache__/__init__.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..bf3658a172dc8bfadc54ad786c026606a907241a GIT binary patch literal 325 zcmYjLyGq4C5Z%otUWr^p@B`9Vq{ssVZA5Hr<)YkXn;~WwT+BY$P1M}V+CTA!EVi}s z7p&YxAr8!$IWxmKvt6%q6av3~z+0%Fk^GM&kgJfc2*40U46|gwGNFkil*p8(7%@UK zmfoQ<+nwA_s^|(g-5aZW?pz@vH;zwC7bCY)sBZYeL9HY{-;DF-_s$wkOuGv08iXHp%uV8va7g=@O|El(lkbx vYEq`_A33X@A2=T>>)O*+!b`J=HUL725ui4+-@lNWO#{D-|GQ|C;^X88Di>O~ literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/ptyprocess/__pycache__/_fork_pty.cpython-38.pyc b/.venv/lib/python3.8/site-packages/ptyprocess/__pycache__/_fork_pty.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c41d214500b8a5ed46cf15b3ac3efbcf95956f51 GIT binary patch literal 1972 zcmbVMPmj|^6rZu3#4*_|rAXz_!w6L^X;~+LsL%>k6|ikrS`xI`3b2qYuV;cyY>zcF z1`;Kxf_@OvTW|dc{S-a;R`tXe=%J^+nUE!*wyHYP%)GJRzj^QXoA0)^JOl%O|7*D0 zM(B5a*c=udzJe(aV4)~L6jLk10XDl8Sg_lfojZY(H-bjq44Qc>XkkPh+Q{6z9kfAi z($)_s@Tg1Mu%DvV2z9;L^-*;!RjMk*$e0VF60=WAH6?N?70XE+W!XidIFVIZa-qnG zXOT#y@4bS2(4gzoozc;){XzKk{=wd0SZ~2;_}$UwaqsYOeQezPcK_hkD-5PxT)%fm zP45UEGb#6k;3C#8*TV+Efq4_Ad?K-Qb4xiBOJs0v%+V5Kq?&X5LhtBhYmSw>v`*yqhU{s%@QfYSc5`cv#=2Z~^c$po zl%$fRd6}`C6-tr_3iDrT=o4+}5g0PzRYu7%BRLn0=&DA?8H4Iag=qnl--mWgE_BJb zDq@xL!Y8AW#pyWJ{g_@few0q-wX-LnPI&RAJ4WL+r(nV;xzzXjU-QCRBpXQ= zT&>}f77y1st&%Pyq0+bl3}t{ZnfT;JBq1{7UPdZTG}KBi)2BJ7RmS|7L={93paQuM zc$AoIMr9>L%Ea!jXU@8=iBjcmua`$@=9eZdpNogRGA)_VAA75hJCr@{UGDdF43o9)v7cT45$aI8>z2ang5)_^ z&~^u(#;)bU^k8;y2X8x`CCVvF`Av3+mBkR^~jyr;@~-GTt(Dc*w5^H=sqf}d)j+@ zi9qwSfA_6CYHPM{#Q5cJV*LCMF)ZLeWc_x&ClOD*{oOp3&g@4+eBDyH;;3X5J zv2IGHWJ*O#{{r>9hr_|a{jL)&KL(1bYG}jOxf_Y#A72cuPik(iS(#&LPpl)1j eq@sx?bUw9vef9i&smUPq)g8l@bGT!<=l=reAQ<-m literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/ptyprocess/__pycache__/ptyprocess.cpython-38.pyc b/.venv/lib/python3.8/site-packages/ptyprocess/__pycache__/ptyprocess.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0a76cb28142dc9ca60f16064db632059bb878381 GIT binary patch literal 22693 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 3 + +if PY3: + def _byte(i): + return bytes([i]) +else: + def _byte(i): + return chr(i) + + class FileNotFoundError(OSError): pass + class TimeoutError(OSError): pass + +_EOF, _INTR = None, None + +def _make_eof_intr(): + """Set constants _EOF and _INTR. + + This avoids doing potentially costly operations on module load. + """ + global _EOF, _INTR + if (_EOF is not None) and (_INTR is not None): + return + + # inherit EOF and INTR definitions from controlling process. + try: + from termios import VEOF, VINTR + fd = None + for name in 'stdin', 'stdout': + stream = getattr(sys, '__%s__' % name, None) + if stream is None or not hasattr(stream, 'fileno'): + continue + try: + fd = stream.fileno() + except ValueError: + continue + if fd is None: + # no fd, raise ValueError to fallback on CEOF, CINTR + raise ValueError("No stream has a fileno") + intr = ord(termios.tcgetattr(fd)[6][VINTR]) + eof = ord(termios.tcgetattr(fd)[6][VEOF]) + except (ImportError, OSError, IOError, ValueError, termios.error): + # unless the controlling process is also not a terminal, + # such as cron(1), or when stdin and stdout are both closed. + # Fall-back to using CEOF and CINTR. There + try: + from termios import CEOF, CINTR + (intr, eof) = (CINTR, CEOF) + except ImportError: + # ^C, ^D + (intr, eof) = (3, 4) + + _INTR = _byte(intr) + _EOF = _byte(eof) + +# setecho and setwinsize are pulled out here because on some platforms, we need +# to do this from the child before we exec() + +def _setecho(fd, state): + errmsg = 'setecho() may not be called on this platform (it may still be possible to enable/disable echo when spawning the child process)' + + try: + attr = termios.tcgetattr(fd) + except termios.error as err: + if err.args[0] == errno.EINVAL: + raise IOError(err.args[0], '%s: %s.' % (err.args[1], errmsg)) + raise + + if state: + attr[3] = attr[3] | termios.ECHO + else: + attr[3] = attr[3] & ~termios.ECHO + + try: + # I tried TCSADRAIN and TCSAFLUSH, but these were inconsistent and + # blocked on some platforms. TCSADRAIN would probably be ideal. + termios.tcsetattr(fd, termios.TCSANOW, attr) + except IOError as err: + if err.args[0] == errno.EINVAL: + raise IOError(err.args[0], '%s: %s.' % (err.args[1], errmsg)) + raise + +def _setwinsize(fd, rows, cols): + # Some very old platforms have a bug that causes the value for + # termios.TIOCSWINSZ to be truncated. There was a hack here to work + # around this, but it caused problems with newer platforms so has been + # removed. For details see https://github.com/pexpect/pexpect/issues/39 + TIOCSWINSZ = getattr(termios, 'TIOCSWINSZ', -2146929561) + # Note, assume ws_xpixel and ws_ypixel are zero. + s = struct.pack('HHHH', rows, cols, 0, 0) + fcntl.ioctl(fd, TIOCSWINSZ, s) + +class PtyProcess(object): + '''This class represents a process running in a pseudoterminal. + + The main constructor is the :meth:`spawn` classmethod. + ''' + string_type = bytes + if PY3: + linesep = os.linesep.encode('ascii') + crlf = '\r\n'.encode('ascii') + + @staticmethod + def write_to_stdout(b): + try: + return sys.stdout.buffer.write(b) + except AttributeError: + # If stdout has been replaced, it may not have .buffer + return sys.stdout.write(b.decode('ascii', 'replace')) + else: + linesep = os.linesep + crlf = '\r\n' + write_to_stdout = sys.stdout.write + + encoding = None + + argv = None + env = None + launch_dir = None + + def __init__(self, pid, fd): + _make_eof_intr() # Ensure _EOF and _INTR are calculated + self.pid = pid + self.fd = fd + readf = io.open(fd, 'rb', buffering=0) + writef = io.open(fd, 'wb', buffering=0, closefd=False) + self.fileobj = io.BufferedRWPair(readf, writef) + + self.terminated = False + self.closed = False + self.exitstatus = None + self.signalstatus = None + # status returned by os.waitpid + self.status = None + self.flag_eof = False + # Used by close() to give kernel time to update process status. + # Time in seconds. + self.delayafterclose = 0.1 + # Used by terminate() to give kernel time to update process status. + # Time in seconds. + self.delayafterterminate = 0.1 + + @classmethod + def spawn( + cls, argv, cwd=None, env=None, echo=True, preexec_fn=None, + dimensions=(24, 80)): + '''Start the given command in a child process in a pseudo terminal. + + This does all the fork/exec type of stuff for a pty, and returns an + instance of PtyProcess. + + If preexec_fn is supplied, it will be called with no arguments in the + child process before exec-ing the specified command. + It may, for instance, set signal handlers to SIG_DFL or SIG_IGN. + + Dimensions of the psuedoterminal used for the subprocess can be + specified as a tuple (rows, cols), or the default (24, 80) will be used. + ''' + # Note that it is difficult for this method to fail. + # You cannot detect if the child process cannot start. + # So the only way you can tell if the child process started + # or not is to try to read from the file descriptor. If you get + # EOF immediately then it means that the child is already dead. + # That may not necessarily be bad because you may have spawned a child + # that performs some task; creates no stdout output; and then dies. + + if not isinstance(argv, (list, tuple)): + raise TypeError("Expected a list or tuple for argv, got %r" % argv) + + # Shallow copy of argv so we can modify it + argv = argv[:] + command = argv[0] + + command_with_path = which(command) + if command_with_path is None: + raise FileNotFoundError('The command was not found or was not ' + + 'executable: %s.' % command) + command = command_with_path + argv[0] = command + + # [issue #119] To prevent the case where exec fails and the user is + # stuck interacting with a python child process instead of whatever + # was expected, we implement the solution from + # http://stackoverflow.com/a/3703179 to pass the exception to the + # parent process + + # [issue #119] 1. Before forking, open a pipe in the parent process. + exec_err_pipe_read, exec_err_pipe_write = os.pipe() + + if use_native_pty_fork: + pid, fd = pty.fork() + else: + # Use internal fork_pty, for Solaris + pid, fd = _fork_pty.fork_pty() + + # Some platforms must call setwinsize() and setecho() from the + # child process, and others from the master process. We do both, + # allowing IOError for either. + + if pid == CHILD: + # set window size + try: + _setwinsize(STDIN_FILENO, *dimensions) + except IOError as err: + if err.args[0] not in (errno.EINVAL, errno.ENOTTY): + raise + + # disable echo if spawn argument echo was unset + if not echo: + try: + _setecho(STDIN_FILENO, False) + except (IOError, termios.error) as err: + if err.args[0] not in (errno.EINVAL, errno.ENOTTY): + raise + + # [issue #119] 3. The child closes the reading end and sets the + # close-on-exec flag for the writing end. + os.close(exec_err_pipe_read) + fcntl.fcntl(exec_err_pipe_write, fcntl.F_SETFD, fcntl.FD_CLOEXEC) + + # Do not allow child to inherit open file descriptors from parent, + # with the exception of the exec_err_pipe_write of the pipe + # Impose ceiling on max_fd: AIX bugfix for users with unlimited + # nofiles where resource.RLIMIT_NOFILE is 2^63-1 and os.closerange() + # occasionally raises out of range error + max_fd = min(1048576, resource.getrlimit(resource.RLIMIT_NOFILE)[0]) + os.closerange(3, exec_err_pipe_write) + os.closerange(exec_err_pipe_write+1, max_fd) + + if cwd is not None: + os.chdir(cwd) + + if preexec_fn is not None: + try: + preexec_fn() + except Exception as e: + ename = type(e).__name__ + tosend = '{}:0:{}'.format(ename, str(e)) + if PY3: + tosend = tosend.encode('utf-8') + + os.write(exec_err_pipe_write, tosend) + os.close(exec_err_pipe_write) + os._exit(1) + + try: + if env is None: + os.execv(command, argv) + else: + os.execvpe(command, argv, env) + except OSError as err: + # [issue #119] 5. If exec fails, the child writes the error + # code back to the parent using the pipe, then exits. + tosend = 'OSError:{}:{}'.format(err.errno, str(err)) + if PY3: + tosend = tosend.encode('utf-8') + os.write(exec_err_pipe_write, tosend) + os.close(exec_err_pipe_write) + os._exit(os.EX_OSERR) + + # Parent + inst = cls(pid, fd) + + # Set some informational attributes + inst.argv = argv + if env is not None: + inst.env = env + if cwd is not None: + inst.launch_dir = cwd + + # [issue #119] 2. After forking, the parent closes the writing end + # of the pipe and reads from the reading end. + os.close(exec_err_pipe_write) + exec_err_data = os.read(exec_err_pipe_read, 4096) + os.close(exec_err_pipe_read) + + # [issue #119] 6. The parent reads eof (a zero-length read) if the + # child successfully performed exec, since close-on-exec made + # successful exec close the writing end of the pipe. Or, if exec + # failed, the parent reads the error code and can proceed + # accordingly. Either way, the parent blocks until the child calls + # exec. + if len(exec_err_data) != 0: + try: + errclass, errno_s, errmsg = exec_err_data.split(b':', 2) + exctype = getattr(builtins, errclass.decode('ascii'), Exception) + + exception = exctype(errmsg.decode('utf-8', 'replace')) + if exctype is OSError: + exception.errno = int(errno_s) + except: + raise Exception('Subprocess failed, got bad error data: %r' + % exec_err_data) + else: + raise exception + + try: + inst.setwinsize(*dimensions) + except IOError as err: + if err.args[0] not in (errno.EINVAL, errno.ENOTTY, errno.ENXIO): + raise + + return inst + + def __repr__(self): + clsname = type(self).__name__ + if self.argv is not None: + args = [repr(self.argv)] + if self.env is not None: + args.append("env=%r" % self.env) + if self.launch_dir is not None: + args.append("cwd=%r" % self.launch_dir) + + return "{}.spawn({})".format(clsname, ", ".join(args)) + + else: + return "{}(pid={}, fd={})".format(clsname, self.pid, self.fd) + + @staticmethod + def _coerce_send_string(s): + if not isinstance(s, bytes): + return s.encode('utf-8') + return s + + @staticmethod + def _coerce_read_string(s): + return s + + def __del__(self): + '''This makes sure that no system resources are left open. Python only + garbage collects Python objects. OS file descriptors are not Python + objects, so they must be handled explicitly. If the child file + descriptor was opened outside of this class (passed to the constructor) + then this does not close it. ''' + + if not self.closed: + # It is possible for __del__ methods to execute during the + # teardown of the Python VM itself. Thus self.close() may + # trigger an exception because os.close may be None. + try: + self.close() + # which exception, shouldn't we catch explicitly .. ? + except: + pass + + + def fileno(self): + '''This returns the file descriptor of the pty for the child. + ''' + return self.fd + + def close(self, force=True): + '''This closes the connection with the child application. Note that + calling close() more than once is valid. This emulates standard Python + behavior with files. Set force to True if you want to make sure that + the child is terminated (SIGKILL is sent if the child ignores SIGHUP + and SIGINT). ''' + if not self.closed: + self.flush() + self.fileobj.close() # Closes the file descriptor + # Give kernel time to update process status. + time.sleep(self.delayafterclose) + if self.isalive(): + if not self.terminate(force): + raise PtyProcessError('Could not terminate the child.') + self.fd = -1 + self.closed = True + #self.pid = None + + def flush(self): + '''This does nothing. It is here to support the interface for a + File-like object. ''' + + pass + + def isatty(self): + '''This returns True if the file descriptor is open and connected to a + tty(-like) device, else False. + + On SVR4-style platforms implementing streams, such as SunOS and HP-UX, + the child pty may not appear as a terminal device. This means + methods such as setecho(), setwinsize(), getwinsize() may raise an + IOError. ''' + + return os.isatty(self.fd) + + def waitnoecho(self, timeout=None): + '''This waits until the terminal ECHO flag is set False. This returns + True if the echo mode is off. This returns False if the ECHO flag was + not set False before the timeout. This can be used to detect when the + child is waiting for a password. Usually a child application will turn + off echo mode when it is waiting for the user to enter a password. For + example, instead of expecting the "password:" prompt you can wait for + the child to set ECHO off:: + + p = pexpect.spawn('ssh user@example.com') + p.waitnoecho() + p.sendline(mypassword) + + If timeout==None then this method to block until ECHO flag is False. + ''' + + if timeout is not None: + end_time = time.time() + timeout + while True: + if not self.getecho(): + return True + if timeout < 0 and timeout is not None: + return False + if timeout is not None: + timeout = end_time - time.time() + time.sleep(0.1) + + def getecho(self): + '''This returns the terminal echo mode. This returns True if echo is + on or False if echo is off. Child applications that are expecting you + to enter a password often set ECHO False. See waitnoecho(). + + Not supported on platforms where ``isatty()`` returns False. ''' + + try: + attr = termios.tcgetattr(self.fd) + except termios.error as err: + errmsg = 'getecho() may not be called on this platform' + if err.args[0] == errno.EINVAL: + raise IOError(err.args[0], '%s: %s.' % (err.args[1], errmsg)) + raise + + self.echo = bool(attr[3] & termios.ECHO) + return self.echo + + def setecho(self, state): + '''This sets the terminal echo mode on or off. Note that anything the + child sent before the echo will be lost, so you should be sure that + your input buffer is empty before you call setecho(). For example, the + following will work as expected:: + + p = pexpect.spawn('cat') # Echo is on by default. + p.sendline('1234') # We expect see this twice from the child... + p.expect(['1234']) # ... once from the tty echo... + p.expect(['1234']) # ... and again from cat itself. + p.setecho(False) # Turn off tty echo + p.sendline('abcd') # We will set this only once (echoed by cat). + p.sendline('wxyz') # We will set this only once (echoed by cat) + p.expect(['abcd']) + p.expect(['wxyz']) + + The following WILL NOT WORK because the lines sent before the setecho + will be lost:: + + p = pexpect.spawn('cat') + p.sendline('1234') + p.setecho(False) # Turn off tty echo + p.sendline('abcd') # We will set this only once (echoed by cat). + p.sendline('wxyz') # We will set this only once (echoed by cat) + p.expect(['1234']) + p.expect(['1234']) + p.expect(['abcd']) + p.expect(['wxyz']) + + + Not supported on platforms where ``isatty()`` returns False. + ''' + _setecho(self.fd, state) + + self.echo = state + + def read(self, size=1024): + """Read and return at most ``size`` bytes from the pty. + + Can block if there is nothing to read. Raises :exc:`EOFError` if the + terminal was closed. + + Unlike Pexpect's ``read_nonblocking`` method, this doesn't try to deal + with the vagaries of EOF on platforms that do strange things, like IRIX + or older Solaris systems. It handles the errno=EIO pattern used on + Linux, and the empty-string return used on BSD platforms and (seemingly) + on recent Solaris. + """ + try: + s = self.fileobj.read1(size) + except (OSError, IOError) as err: + if err.args[0] == errno.EIO: + # Linux-style EOF + self.flag_eof = True + raise EOFError('End Of File (EOF). Exception style platform.') + raise + if s == b'': + # BSD-style EOF (also appears to work on recent Solaris (OpenIndiana)) + self.flag_eof = True + raise EOFError('End Of File (EOF). Empty string style platform.') + + return s + + def readline(self): + """Read one line from the pseudoterminal, and return it as unicode. + + Can block if there is nothing to read. Raises :exc:`EOFError` if the + terminal was closed. + """ + try: + s = self.fileobj.readline() + except (OSError, IOError) as err: + if err.args[0] == errno.EIO: + # Linux-style EOF + self.flag_eof = True + raise EOFError('End Of File (EOF). Exception style platform.') + raise + if s == b'': + # BSD-style EOF (also appears to work on recent Solaris (OpenIndiana)) + self.flag_eof = True + raise EOFError('End Of File (EOF). Empty string style platform.') + + return s + + def _writeb(self, b, flush=True): + n = self.fileobj.write(b) + if flush: + self.fileobj.flush() + return n + + def write(self, s, flush=True): + """Write bytes to the pseudoterminal. + + Returns the number of bytes written. + """ + return self._writeb(s, flush=flush) + + def sendcontrol(self, char): + '''Helper method that wraps send() with mnemonic access for sending control + character to the child (such as Ctrl-C or Ctrl-D). For example, to send + Ctrl-G (ASCII 7, bell, '\a'):: + + child.sendcontrol('g') + + See also, sendintr() and sendeof(). + ''' + char = char.lower() + a = ord(char) + if 97 <= a <= 122: + a = a - ord('a') + 1 + byte = _byte(a) + return self._writeb(byte), byte + d = {'@': 0, '`': 0, + '[': 27, '{': 27, + '\\': 28, '|': 28, + ']': 29, '}': 29, + '^': 30, '~': 30, + '_': 31, + '?': 127} + if char not in d: + return 0, b'' + + byte = _byte(d[char]) + return self._writeb(byte), byte + + def sendeof(self): + '''This sends an EOF to the child. This sends a character which causes + the pending parent output buffer to be sent to the waiting child + program without waiting for end-of-line. If it is the first character + of the line, the read() in the user program returns 0, which signifies + end-of-file. This means to work as expected a sendeof() has to be + called at the beginning of a line. This method does not send a newline. + It is the responsibility of the caller to ensure the eof is sent at the + beginning of a line. ''' + + return self._writeb(_EOF), _EOF + + def sendintr(self): + '''This sends a SIGINT to the child. It does not require + the SIGINT to be the first character on a line. ''' + + return self._writeb(_INTR), _INTR + + def eof(self): + '''This returns True if the EOF exception was ever raised. + ''' + + return self.flag_eof + + def terminate(self, force=False): + '''This forces a child process to terminate. It starts nicely with + SIGHUP and SIGINT. If "force" is True then moves onto SIGKILL. This + returns True if the child was terminated. This returns False if the + child could not be terminated. ''' + + if not self.isalive(): + return True + try: + self.kill(signal.SIGHUP) + time.sleep(self.delayafterterminate) + if not self.isalive(): + return True + self.kill(signal.SIGCONT) + time.sleep(self.delayafterterminate) + if not self.isalive(): + return True + self.kill(signal.SIGINT) + time.sleep(self.delayafterterminate) + if not self.isalive(): + return True + if force: + self.kill(signal.SIGKILL) + time.sleep(self.delayafterterminate) + if not self.isalive(): + return True + else: + return False + return False + except OSError: + # I think there are kernel timing issues that sometimes cause + # this to happen. I think isalive() reports True, but the + # process is dead to the kernel. + # Make one last attempt to see if the kernel is up to date. + time.sleep(self.delayafterterminate) + if not self.isalive(): + return True + else: + return False + + def wait(self): + '''This waits until the child exits. This is a blocking call. This will + not read any data from the child, so this will block forever if the + child has unread output and has terminated. In other words, the child + may have printed output then called exit(), but, the child is + technically still alive until its output is read by the parent. ''' + + if self.isalive(): + pid, status = os.waitpid(self.pid, 0) + else: + return self.exitstatus + self.exitstatus = os.WEXITSTATUS(status) + if os.WIFEXITED(status): + self.status = status + self.exitstatus = os.WEXITSTATUS(status) + self.signalstatus = None + self.terminated = True + elif os.WIFSIGNALED(status): + self.status = status + self.exitstatus = None + self.signalstatus = os.WTERMSIG(status) + self.terminated = True + elif os.WIFSTOPPED(status): # pragma: no cover + # You can't call wait() on a child process in the stopped state. + raise PtyProcessError('Called wait() on a stopped child ' + + 'process. This is not supported. Is some other ' + + 'process attempting job control with our child pid?') + return self.exitstatus + + def isalive(self): + '''This tests if the child process is running or not. This is + non-blocking. If the child was terminated then this will read the + exitstatus or signalstatus of the child. This returns True if the child + process appears to be running or False if not. It can take literally + SECONDS for Solaris to return the right status. ''' + + if self.terminated: + return False + + if self.flag_eof: + # This is for Linux, which requires the blocking form + # of waitpid to get the status of a defunct process. + # This is super-lame. The flag_eof would have been set + # in read_nonblocking(), so this should be safe. + waitpid_options = 0 + else: + waitpid_options = os.WNOHANG + + try: + pid, status = os.waitpid(self.pid, waitpid_options) + except OSError as e: + # No child processes + if e.errno == errno.ECHILD: + raise PtyProcessError('isalive() encountered condition ' + + 'where "terminated" is 0, but there was no child ' + + 'process. Did someone else call waitpid() ' + + 'on our process?') + else: + raise + + # I have to do this twice for Solaris. + # I can't even believe that I figured this out... + # If waitpid() returns 0 it means that no child process + # wishes to report, and the value of status is undefined. + if pid == 0: + try: + ### os.WNOHANG) # Solaris! + pid, status = os.waitpid(self.pid, waitpid_options) + except OSError as e: # pragma: no cover + # This should never happen... + if e.errno == errno.ECHILD: + raise PtyProcessError('isalive() encountered condition ' + + 'that should never happen. There was no child ' + + 'process. Did someone else call waitpid() ' + + 'on our process?') + else: + raise + + # If pid is still 0 after two calls to waitpid() then the process + # really is alive. This seems to work on all platforms, except for + # Irix which seems to require a blocking call on waitpid or select, + # so I let read_nonblocking take care of this situation + # (unfortunately, this requires waiting through the timeout). + if pid == 0: + return True + + if pid == 0: + return True + + if os.WIFEXITED(status): + self.status = status + self.exitstatus = os.WEXITSTATUS(status) + self.signalstatus = None + self.terminated = True + elif os.WIFSIGNALED(status): + self.status = status + self.exitstatus = None + self.signalstatus = os.WTERMSIG(status) + self.terminated = True + elif os.WIFSTOPPED(status): + raise PtyProcessError('isalive() encountered condition ' + + 'where child process is stopped. This is not ' + + 'supported. Is some other process attempting ' + + 'job control with our child pid?') + return False + + def kill(self, sig): + """Send the given signal to the child application. + + In keeping with UNIX tradition it has a misleading name. It does not + necessarily kill the child unless you send the right signal. See the + :mod:`signal` module for constants representing signal numbers. + """ + + # Same as os.kill, but the pid is given for you. + if self.isalive(): + os.kill(self.pid, sig) + + def getwinsize(self): + """Return the window size of the pseudoterminal as a tuple (rows, cols). + """ + TIOCGWINSZ = getattr(termios, 'TIOCGWINSZ', 1074295912) + s = struct.pack('HHHH', 0, 0, 0, 0) + x = fcntl.ioctl(self.fd, TIOCGWINSZ, s) + return struct.unpack('HHHH', x)[0:2] + + def setwinsize(self, rows, cols): + """Set the terminal window size of the child tty. + + This will cause a SIGWINCH signal to be sent to the child. This does not + change the physical window size. It changes the size reported to + TTY-aware applications like vi or curses -- applications that respond to + the SIGWINCH signal. + """ + return _setwinsize(self.fd, rows, cols) + + +class PtyProcessUnicode(PtyProcess): + """Unicode wrapper around a process running in a pseudoterminal. + + This class exposes a similar interface to :class:`PtyProcess`, but its read + methods return unicode, and its :meth:`write` accepts unicode. + """ + if PY3: + string_type = str + else: + string_type = unicode # analysis:ignore + + def __init__(self, pid, fd, encoding='utf-8', codec_errors='strict'): + super(PtyProcessUnicode, self).__init__(pid, fd) + self.encoding = encoding + self.codec_errors = codec_errors + self.decoder = codecs.getincrementaldecoder(encoding)(errors=codec_errors) + + def read(self, size=1024): + """Read at most ``size`` bytes from the pty, return them as unicode. + + Can block if there is nothing to read. Raises :exc:`EOFError` if the + terminal was closed. + + The size argument still refers to bytes, not unicode code points. + """ + b = super(PtyProcessUnicode, self).read(size) + return self.decoder.decode(b, final=False) + + def readline(self): + """Read one line from the pseudoterminal, and return it as unicode. + + Can block if there is nothing to read. Raises :exc:`EOFError` if the + terminal was closed. + """ + b = super(PtyProcessUnicode, self).readline() + return self.decoder.decode(b, final=False) + + def write(self, s): + """Write the unicode string ``s`` to the pseudoterminal. + + Returns the number of bytes written. + """ + b = s.encode(self.encoding) + return super(PtyProcessUnicode, self).write(b) diff --git a/.venv/lib/python3.8/site-packages/ptyprocess/util.py b/.venv/lib/python3.8/site-packages/ptyprocess/util.py new file mode 100644 index 00000000..aadbd62c --- /dev/null +++ b/.venv/lib/python3.8/site-packages/ptyprocess/util.py @@ -0,0 +1,71 @@ +try: + from shutil import which # Python >= 3.3 +except ImportError: + import os, sys + + # This is copied from Python 3.4.1 + def which(cmd, mode=os.F_OK | os.X_OK, path=None): + """Given a command, mode, and a PATH string, return the path which + conforms to the given mode on the PATH, or None if there is no such + file. + + `mode` defaults to os.F_OK | os.X_OK. `path` defaults to the result + of os.environ.get("PATH"), or can be overridden with a custom search + path. + + """ + # Check that a given file can be accessed with the correct mode. + # Additionally check that `file` is not a directory, as on Windows + # directories pass the os.access check. + def _access_check(fn, mode): + return (os.path.exists(fn) and os.access(fn, mode) + and not os.path.isdir(fn)) + + # If we're given a path with a directory part, look it up directly rather + # than referring to PATH directories. This includes checking relative to the + # current directory, e.g. ./script + if os.path.dirname(cmd): + if _access_check(cmd, mode): + return cmd + return None + + if path is None: + path = os.environ.get("PATH", os.defpath) + if not path: + return None + path = path.split(os.pathsep) + + if sys.platform == "win32": + # The current directory takes precedence on Windows. + if not os.curdir in path: + path.insert(0, os.curdir) + + # PATHEXT is necessary to check on Windows. + pathext = os.environ.get("PATHEXT", "").split(os.pathsep) + # See if the given file matches any of the expected path extensions. + # This will allow us to short circuit when given "python.exe". + # If it does match, only test that one, otherwise we have to try + # others. + if any(cmd.lower().endswith(ext.lower()) for ext in pathext): + files = [cmd] + else: + files = [cmd + ext for ext in pathext] + else: + # On other platforms you don't have things like PATHEXT to tell you + # what file suffixes are executable, so just pass on cmd as-is. + files = [cmd] + + seen = set() + for dir in path: + normdir = os.path.normcase(dir) + if not normdir in seen: + seen.add(normdir) + for thefile in files: + name = os.path.join(dir, thefile) + if _access_check(name, mode): + return name + return None + + +class PtyProcessError(Exception): + """Generic error class for this package.""" diff --git a/.venv/lib/python3.8/site-packages/pygments/__init__.py b/.venv/lib/python3.8/site-packages/pygments/__init__.py new file mode 100644 index 00000000..e5a27839 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/pygments/__init__.py @@ -0,0 +1,85 @@ +# -*- coding: utf-8 -*- +""" + Pygments + ~~~~~~~~ + + Pygments is a syntax highlighting package written in Python. + + It is a generic syntax highlighter for general use in all kinds of software + such as forum systems, wikis or other applications that need to prettify + source code. Highlights are: + + * a wide range of common languages and markup formats is supported + * special attention is paid to details, increasing quality by a fair amount + * support for new languages and formats are added easily + * a number of output formats, presently HTML, LaTeX, RTF, SVG, all image + formats that PIL supports, and ANSI sequences + * it is usable as a command-line tool and as a library + * ... and it highlights even Brainfuck! + + The `Pygments master branch`_ is installable with ``easy_install Pygments==dev``. + + .. _Pygments master branch: + https://github.com/pygments/pygments/archive/master.zip#egg=Pygments-dev + + :copyright: Copyright 2006-2020 by the Pygments team, see AUTHORS. + :license: BSD, see LICENSE for details. +""" +import sys +from io import StringIO, BytesIO + +__version__ = '2.7.3' +__docformat__ = 'restructuredtext' + +__all__ = ['lex', 'format', 'highlight'] + + +def lex(code, lexer): + """ + Lex ``code`` with ``lexer`` and return an iterable of tokens. + """ + try: + return lexer.get_tokens(code) + except TypeError as err: + if (isinstance(err.args[0], str) and + ('unbound method get_tokens' in err.args[0] or + 'missing 1 required positional argument' in err.args[0])): + raise TypeError('lex() argument must be a lexer instance, ' + 'not a class') + raise + + +def format(tokens, formatter, outfile=None): # pylint: disable=redefined-builtin + """ + Format a tokenlist ``tokens`` with the formatter ``formatter``. + + If ``outfile`` is given and a valid file object (an object + with a ``write`` method), the result will be written to it, otherwise + it is returned as a string. + """ + try: + if not outfile: + realoutfile = getattr(formatter, 'encoding', None) and BytesIO() or StringIO() + formatter.format(tokens, realoutfile) + return realoutfile.getvalue() + else: + formatter.format(tokens, outfile) + except TypeError as err: + if (isinstance(err.args[0], str) and + ('unbound method format' in err.args[0] or + 'missing 1 required positional argument' in err.args[0])): + raise TypeError('format() argument must be a formatter instance, ' + 'not a class') + raise + + +def highlight(code, lexer, formatter, outfile=None): + """ + Lex ``code`` with ``lexer`` and format it with the formatter ``formatter``. + + If ``outfile`` is given and a valid file object (an object + with a ``write`` method), the result will be written to it, otherwise + it is returned as a string. + """ + return format(lex(code, lexer), formatter, outfile) + diff --git a/.venv/lib/python3.8/site-packages/pygments/__main__.py b/.venv/lib/python3.8/site-packages/pygments/__main__.py new file mode 100644 index 00000000..8d2ea9e3 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/pygments/__main__.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- +""" + pygments.__main__ + ~~~~~~~~~~~~~~~~~ + + Main entry point for ``python -m pygments``. + + :copyright: Copyright 2006-2020 by the Pygments team, see AUTHORS. + :license: BSD, see LICENSE for details. +""" + +import sys +import pygments.cmdline + +try: + sys.exit(pygments.cmdline.main(sys.argv)) +except KeyboardInterrupt: + sys.exit(1) diff --git a/.venv/lib/python3.8/site-packages/pygments/__pycache__/__init__.cpython-38.pyc b/.venv/lib/python3.8/site-packages/pygments/__pycache__/__init__.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..5a5e569edf5bf040f1f6f773097a37a6aeb698e4 GIT binary patch literal 2972 zcmds(%X1sI9mlZ`K14~0r&D*FP7dgF+6g@r<+x5eqt>0qt`n=H${ACsU0#-}1xP~N zmjSF~a%i^`<&eLjC;QlcsE3{2dg{5S=Fs#DfTSJAhn~9JCXYq9nu z7`E6JYkoV0@5EO_LOK-BXY)zMbFJ*;`ReI>Yl{j+ zW2)x4j-S%0m`qbNE%FI1<75_3IK7ZUYo1e)L!O=%dEZGm)b85}&$$%IcVuu$$AzSJ zJ5Fh(xDgSjDV>R&DO!xFD#rREmfUKjs$@!IWj?AhNK=|;sz)!x3@SoUp{EcTmt`uF zSc@W8R8M0~bIuvn1uZ4lT8!sTSW(G@)1+X$Pw%hIf~k@pIQ6f?>59a=k#Q*^gZCPNtlW)^sCAU`0~M%9H6RGX592(m>5>aUt}S zjz;j)JX)=9GUN7b#?MEi71B^3db`wvl}qSU>rx%;?@u7KI_<-_{c@FMuLiM9rsACM zJH`47QT~`uCb!q3_i(1O;~*)@xilGfK<}=H^yZBlKi|7~N} z$Dg0vfADb7w|X5QC3vp*0lhQ$t=m63ynF9>aL-b-g0SEDC#nrO?)r6mpe0Z|d{DRU z%r#es4;GD^{a^HdHoO8zw5$?cNzOEXs_P)-PwS@RuHM>2Ch?81)f3>asd#tM)ET

US(y@6MX?q4rpK z>3!jSK^~Eh2x~m^pZkx=A4!g$HBj%Gi%+c+j`&kV*<}1^gv_=vhw5BnYKTL5s3Zyy z@)NXJGLR&?n89<-jnXrkzgOj_NJpeTN3~-pU^;Sdef`r+D4W6`LfVr`z(uqylrULu zDuA3+rrs`Y;oJ|pn>o!YrRgd1fm($eok*G<%?oW(B#o6i?ly*HtWkh(z~8guK0m0AZ}%D)o%E{yp4qkWx~`=u!Ns@xQE&h{>*oTq#G z!(#k|pRrf4Mo0>wqo@xOadD8JpsDYpBcbo@cvtYV^NsKC{KpU4eqtiMei|5TqW%Jt z#hsY7J!vDSow;D>p58YGi$t>$***SHD6=Je-=IuH>{Yuv98sxv{-8^TcD=sAi!qh^m5 zr)NCT^aG&hhE@lQXbchNf;9phZ{40vd8A>LYH*DE66CBeVcc^<_uO50A(X4suI4(v zL8L9M-~$QnxUSo%&;`T%*dc!P4aA*ovSmW}OE-Btz8fdJ9pUa)-2%b538gfkNK+%E z!K7|u9WJT3Y@4+$(;0Ro{yieyM%{GYueUZw)UB0ohugS0)73=2V?HvByY7k^nG$OJlzKag&bd^mqfs>6wJ$oC;&pt7t2~OV3Qiew#B0Y|1q=yw`&U`Ps+9lQoUP1K T_`|k$#SgvE?*#34JJZm1=7RrUx6dP zXC)4~a^fc}C!9bL;#nSh-i&9)?{sFyMjHSBK2e1cdM=!=u(Y$GcY34^Lmpz784>ny zc^Y12v;g?tgi3$neiCrM`hXuWMrVjGnh30cE%z`gR*}UjMeG7`;~X)gjcVrTpG`DG z){TLy)TK1`Lr!VQ{`n5Oq<`rQqO)a2L=tjEt`bQ)9g(SC!if`qR_k=!_ZO`o5t$6T zJ=G$c<11-48mmsT(QJ^*jHn)vqmL8rMsEbfILoWPa0L;1V0Yr{k oPOh$@&+6kQ^|8XP$Z~5fPS`MlbwgK5r?oL{3tNVP7w{~813W*RJOBUy literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/pygments/__pycache__/cmdline.cpython-38.pyc b/.venv/lib/python3.8/site-packages/pygments/__pycache__/cmdline.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..4a9890afcdd1d5854d65063be7655ca9d2bcd084 GIT binary patch literal 12630 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 UH}XgFBl(H^rTq7#?@4d{53!z_cmMzZ literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/pygments/__pycache__/console.cpython-38.pyc b/.venv/lib/python3.8/site-packages/pygments/__pycache__/console.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b23b0f11256335b979a70322644a62ee70654225 GIT binary patch literal 1866 zcmb7EPjlNu6yIG*wk$hoD51e^DQck*Cr#p{p-kNj1ElSg87445i- z^5yCm%qcr2W^|1k7l>rzWyO3A-r$(oNGCHg;LUf5V?6qCtGs1y8JK^mE_Y#L^y~1} zcf_f{+c1l73mPzo?<&l1lE#g}FP4oX>32gOW$B_9M`;{zrTqHLu$1#e4XWR{M*eU1s z2M<4g@X2SJiz-wr@I4--yk&p5dAG2C{L%Wojm>-ZPAqKTnd=AXqBUTbwsJD4+`N5f z_4b`+Gt3RaQ=U0mb2-fQP8{D`5k2F zAl^rO3ti){Mkds{9%^ytj?opIM^35FgCIU|^iI&@PC0bDc#y86dwn-@^saFGPPL=X zqWHE_2$Er>FL-K&e#B;tKS9ok0*{$TCdF?Y?D`o$x`HJ=(60O8(Hf#7tZm}qJT(|f z>o`-{0~r>6ootdrwjre9kmiOL15Xc$sG+QuG_ISaQ5h^I{k*EqzO4$RAp^<)go;UAJ%y!=Lt+i5%4!-xMuwzLhID3>-wb9b zDrgY0s~gOzDAM*m@8^2PA7?Le6%*)@o67DF_yS7fxKoHv#g#F2oGR`yf-ZT&hIk^t zzGoPpfCf||9n;%qVit5UkA{|)+$7-< zh^lnZ_hLUnr7rg;&Pi1X>$n&EqsA;ZN`1V3@Df}`xAZbDq@vSVI!SA%)=6riPSnx9 z(WvF+b{k@^-Oe?hdMYYj!mija_MSSmKwg+5DW{KfZQv(4g`5VecZ4it#df0XRkIeg zzZS;O3;27otx|ap=$6iOYSJ33VP>O;S(IVtvFG{=r0MiLoubp!VkK77Ox@J~0`Gsq Ab^rhX literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/pygments/__pycache__/filter.cpython-38.pyc b/.venv/lib/python3.8/site-packages/pygments/__pycache__/filter.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..3be10a4986b97c94bd40546547dfd95541e2ae16 GIT binary patch literal 2592 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 literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/pygments/__pycache__/plugin.cpython-38.pyc b/.venv/lib/python3.8/site-packages/pygments/__pycache__/plugin.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b34bcc1da8db487f4b99380e4d7367fac99fdac2 GIT binary patch literal 2036 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 anI|9L=e!E<*SFA5NZ>RD9BhUDR`0)uI&okC literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/pygments/__pycache__/sphinxext.cpython-38.pyc b/.venv/lib/python3.8/site-packages/pygments/__pycache__/sphinxext.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0885983f01366dbde1c2a1108a4efc4cf09e1c34 GIT binary patch literal 4474 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 literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/pygments/__pycache__/style.cpython-38.pyc b/.venv/lib/python3.8/site-packages/pygments/__pycache__/style.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7c4607f6c87f45a6539869a39f700aa9df967021 GIT binary patch literal 4373 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 literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/pygments/__pycache__/unistring.cpython-38.pyc b/.venv/lib/python3.8/site-packages/pygments/__pycache__/unistring.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..6bcb8d3dd20dd9cc15d93794ddcf208c4ac5568b GIT binary patch literal 31202 zcmeFadypi_StnTCGm=Jw1mYzS&qg4m0b(SyLJL9&Sm1y?5CW~(yIR4}OxBDVM%_bo zHz3_;H}aj8m06ilkF3f^WMo#p-|x(be1%!7Uc>B6Z&#J((JeIYp8Rogv$-rYVP|)1 zXLk4V>Z{!h<7^nd-IGcyx$ z@$$bP!NsqDE?+r2Gh>;Vow1y;oPF%f>>0~Fvu7>$&fa5r!|c75H_pDn@}}80TJD>D zljY5`_gU_reY54;X79JWW%k=FZ=HRM<=bc9YWa@YZ@0W{_B$-!Ir}!tcg=pM<-2FU z%kn+5-);Hc+3&HuefE1T-#7bq%lFTIpXD91-*5SW*>_leaP|i*KQ#M;mLHz|AL^3K^Gv;4T_CoJ!>{G{dGmiJg5u>6$er!7BYkt`2d-fMZE z<8!m_1p*SXDq*iyPui= zOUv)hec=0MW-gg>5_nySh&wcRGndI5TFNpGIX68PS_)u~NdAf7& zvHadUW=`WR9}_j5r2Q7se*bP-@XTNQmgtq`5A0_H-s67#;@o?WYy0rrdyd=sQ?nnm zd_3_>bMKma&)f&!F=Ic2wtfWt|3%BcoBQD0M;47%a-3e zu0@1?|2QN{d}8jMw{stt|HHX=|JkoRa^`N#-1|h%yJKoO`|+6v{{8t!&dki*e-3|- zf9BCo&t1H7`N69fFI>Jdf8pYz$I<`stN!jkj{o>^mdocZJ#y~+V~?Ht#Kj8_U$V@d zd-zl5=g&WUWp4g<%DIQ<=C7Q;aPi#3=da8?dTIVM4;~l(#N|25xkoO|pZoOrD-VAP zw>pO`Csj!2|LXkw+_}fjUwriH`A6q2KX~pBu3kKM<dJ@C{n}~p-2316z7I<8f8YDxC#n^tKXx)O=dR41|MbtCyF52{ z?pHtY?|$p|{@~-cJM*E(E<8MU@$%e<&i$K@|N8Cp-}&ud`;Cu&{5OufXqm$RJa+lP z`@bw+{f}OKlklV;{ZG<0?dqQ(c&+lhEIsdhK6Xp}Vt}MJX<~`VixQIqOfJH!GHXI& z)-NOiU(IQ_3AWGg5keI;Qvum0iNW@et& zrKgQ&Wa%0EGmFpopV>UDe_>tv!p5_U(zCv2gU@-S=K{}_r01&7b)@Ia=hZJR{q3Uk zx4thmr7xK;4x|@{BvF+}qDB%XNya3SR7p}J$&y4iHL}?un`4QjmPyt@vVMtVmq=ED zhlm2nHb}OGiw?>5;SEU6DUqCuL^tol7^Es7Dxjn8mpwSP8v~!G}1tW8X3~4!|Rcz zpEMQHERbfKG*PZOAT1|pEsz$B8fl?iD??g!(!%p?nWXI?Z9i!%q~j!= z1=0yhq_aXg$kxe_t}KzRm2@4XiyFFN(ruFNkaRI|x+dwlCDL0UJq$%}iS*V;Z=Lio z0KE+9p2)Nc%S1=l^f56o2m3PV+esgz-FK1x0_mf0-$(jrXMctCH%LE0`f1Y7 zl71dh1=25*exLMl$G%AhPBL(l0WuE)WDtQDB?H`XV3LuCj4Bct)ya5+j7P-u6B9#a zn$+&1c8^5uK5Acr7oZCZbOE6Sgx2Xom@dR|p;7Mw^&;9Epxy@cb`k1PuSplJbkQZz zMK@hsr#^-HLK5|@Q-4&V{uuR-;F)wOBGDy{22d){qk%CzlSWjDMl>2VBpNko%ui!$ z5{+pz)`MqKbycFOM%4;c8&qxM!lW9SqG?ns!mClO56`5D08OC&ghrF7DrwTql0-La zG=;mROq$kcx-8Ljji!h2Oq#JuG-IckD!dxabl{mZi!9k1&3Pr73(y=|pHpc*Cege~ z3mPq;AB8b3BDol#Mcl5a(IRRn)@ad`Xvw4%pF}GGT0zc=No#0uZ9wa~MC*OpK)HsG zHWwt?4AABP-jKF1>a756p%*Qa_WE>)p&PE#Av!tK=m?`aa?=sUd=#Lg4LXX@QH+k_ zbcFF6nRMKtrjwc&CUcFNF>2NkYETo=CbMRkwTY#*#cTm)Qzd58m|d2bJ;3Y@cqViC zB<2dRU`}E|lPOr76^&Ke6039=URqXNXSD@ZGg-aH8X9XMrKPiWmbLQ|YnNHO3a`dG zxaw3{2bFfl4DSK!YOI@M-5TrmSl47dH|qshZ=LltW&|W=n5-XR15`IKnTZ>jHD(Us znG>r#v8_uJ+s4EpOB07<;;2ttfr)D%OEyX(1e=#Qamla6tBIcxuush?@QVco;fX4rD>ryEk&eh z$(*9fX?b~C-hdaImV49kXj(R>72CApoYrj8w6;9$$kMbEn0ABGw5v>e9%j)~Sh7=EBrO9i}ohaXT|SHC1@p z)XYuI8bbQiM5U&A6qJ3S9B2R<9|f&T5}W`iE&|A5A0S{yz+p$g;R3ZqpnDW_A)hOT z3zr5;BH%`hdyK#W3V2lnyhvJ95Lgs}p$H(!mqx%>J_`C55%8mwU);uzq^0;#FyO#N zzzqtC0AiO#bCyxXa!~|oN5Pd<1Xk8TqS6)QSLW#-GT8 zsfM^k1A(T<+(ZCdB^=`@h?M~jMzbw?WN080fdTRiMbZ#SqX+_+Mv9m=id6xjX2m)_ zQtUPa>^_i4vIjr~5vYMsp@JEuI66m)6XT#bk?cfI6enWcq5vk6;!c1%;sUXrWe^&m zU}h;^H)sL01d4+&DHJcNUMwN7C<5Xhm}!d70rKO*hrB*aM8$`id<9Sg)CTpB6u%P* zeisM>qWHZa(F#mV#V^YEL!b>2h=DM@6n_R(5dqxIFItIdswfcih_t04+1Nw zW(7l~tRW_Z2c?91N6I>;w1Ua0gvHIn$P*TM!Wu|a97a+Eb4Q6F5cMJuMIaVMAckAS z$|8W9tC(mCX0npNi=b?3M@kCMP)Xq-q(xE=Nd?giOeLj=H%loxK`9YHQVG*t!CX-4 z7|=S})xZm(G?2F;TG7BAnwYps6Hm992Z`s@LjE=$LK`F177=X&1ctwjyLQCQI;fx{ z`qR-sSrCT2i^wj9zl#a2bdk^%4{m_KK(qogX&Kzb(K3c|S*d|AuFDw4W8ObZb znsl^^0^*XnCYPr9!+S3ydzA#(0B=iS1@GaR_3M%m`590Q-Xs)3Bw*i zOw@s=A9dD_qGG*^Vr-)g%*!Z-GTOkJ62%J_1^WOe078eO%_s=dDu&{!9W7Pyey9$- z<*Flpq`L9ysCWz11+-noN~$hm4OTI~RsT8ye#H1O4k|`QRo0HwWfg>$s>?|b9<{oh z28sHXQQvX})CUcZ)D_2(y6OU9C018`Ae3K4`Bh|CMSW{d5Jp>FTL39XY9xz`NbX40 zd~X^i!j=^`a1X-+@`8Mz zAZP`&CK5xS4G@}W#6WQn>NiloA?i0!zfl6AegpLzBM=(WM{Rv9`td$;_tT&vNZfc( z17S|YF$S89w^WmBN16@Wm1fgGn8BK@ex%uDP!NR2t>JNN4nG2pz>($@g)o0K7v4b4 zojKAx=!oV)k_UItJjlF&`J*i$W&x|awt$Kk@K`iV2`!3_X;H*PMe!)=iS|VRNnpL< zAfVy7Xm|`-0*_8hpq?b&S}iF87=0~?;+rC76ET~3hcrAPEiE#q5tGJ6rh$u06NCjo z%NU@+k(R||)3P;?xMvpma-!`y6v|^Y((smQV2qA5j7~9%M_)v{N-;d&687g(0*hiP zp&ga`c)iN~+EKLzzM_Vf*79+n1+omXiGcQ%giS`kZhj@USaarGzZKR5L&MQeA$jZk1j_q4(c6Gjm@0 z?6uD4HRj_QLk!wtqXYt!%GsuWheyhqt5K z>bAC>+)iz0wsYHs?b3E-ySClfZf$qAd)xi(;r3YCk$3Dn&K=K=PulVCEbpxCgr%M6 zPJAc1liJDb$|Pp&aSaL*d6Vfd)7Vso^#K=x3IUk=idwLDSIn> zYkTW^;l1ddx~J_W_fmVAz1&`5ue4X$tL-)RTGF1eH{3I&C*>z?Pr9F6cyjSc|C0gf zZ&v*4Fs>*{swdh&YedgglW zdf|HMdgXdey573pxvpOyNY{t|r7qpjZX|D{Ze(ucZWL~mZd7j6ZZvMRZgg(+ZWuQP zH%2$iee3?>zJEWkuk5evukEkzhxeoV>b|z0+)wRi_H+A%{nCDAzqa4lZ|!&Xd;7-z zV1Kl49@q{X2d)Fpf%m|7up}J>4wQqHgSCV8gYZH0Kt0e7k_V}S%t7v;a8Np^9MldP z2d#t7LGQpg7#xfa%tPy;{m^;nK3q6lJoFz14wb`|!?nZp!|-ABP(9QRlZUCp%wg`Z za9BF59M-;&ke>BWdk_cpKDFbhX*X#AXUxEeHf5YDJ+uw4U7{VFfjd3g!HKvVp}Ljo zcB(t6?xy+z)fcJmr+R?u3e{JrzDD(Rs)wl_rMgOWjp|9Nr>LHxdXDM^s+XuIT&ZR3A~@q=uCmc4|1O;ikp{H5RGir$&Gp3N==!u||z`YJ{l~rG`ok zjT%X6q^OahMvfWA+710Xk6VV1*9W=wO`=!gLU&1Cf5d9gnGL!)f0^O`rs(o8st3 z%@vB{G&R?$i85x6noW3ZYNCwUV-7EKEJ@4}V2%~$s4+*IISl5&$=fkvPM5@-3(UF1 zTn<*RORN!RjU;Pi5X!Pfo;8ZBQD%(>YqSv6W{obq0c%=W)6SYs)^xMx0&6a^rk^zf ztf{c(3Tv*h<~nPJSu@I-Dr;)2nPklrYi3w8$C?G!EU{*VHEXQdV9ge5c388=ng(m4 z<`HX}tYu{_J8L;v%gtH~thLBme%1=Gmcm*qthL5k>#P-Ktte}$tOb-J$yzA@6=~Kg zvsRV0S`04)YiC$H$J!Mhw(_u@hn+m^=HUe%UgTjv4+nTy;o%h?UgP0)9uD(xl!sLw z)_6F{!zmul@NkZY3p`xn;R=sfdBn~mP9Aad$O4Zn@`#^D0z9Jd$O@0F@yI%lgn1;& zV<{fX@K}z=3OrWgu?mmXBpz$yaVAukqaeZIE*qc$2rRL> zVh4dERB={PSHQ)qtB6?zH=wTez;=SkQP)aGYDh4^A+Wn4uovq33JA=Ey5Rp#iMu{H;!lQSN|Vy6Ms{ep0YmWlAcnYN=Q$opDI69 zeY*X0{|n(4BS-eYeo`lBndCML6ShflSQ%#Z?jD{yYNON?T|>?An6gw1W5+sg-nuUAPdRLBn#v{ z>mykRaI!&?U4fS;*&@6;$u>zA6=V&P9g*A;$pNp=sU!zEOfE@sfb??>k{gmd>d1RZ z9(Ck{B#%1sd6GvR`8vttHu)CG1NhH(Ngnc&yg`7~kV1?U;-rA&0z@~cq39p3Ee9tNy#8(lq~xQKuA&!61RM#(aAjtHI;si>ra4pfq)(jZkksiK0amsBA`s0ImOAW~f;RWz^~A=MbE#u3s; zH3ctCs*pici=jtThNCRWth>!-F+enh8Oq$5w z^pPg=H-n^!{LMURB7d_*aDF3AgEU8^6(=neX(dUk0k28gDAx9oHj1@_q>Www7Xv-eTZ55b<#&| z{TAtu$N&`%9Atpe9%y7J6KwuuP52G zPrXR?)~Odffwx1wSS`F`x+v2{@DYnnx(H#!Vu&toNYodkzGZl8)Q2m7gf8JeO92{$ z+$3D4;Tk+hZ*Ucf&;{plLRDO;WvZeVYMsUr z8E;W7MiYon+Gx@NPp6xR-*nJTH@rOEEK*>nG}WPirD!@%Gw4O8LNkcWv}qQR*%Hm- zDz`v!R;2k5%_ktLS*3UrXt_lpxTKXuTD42GnxL4ev|6K(IMP~%)={9Iq76S*&H!y- z)EYh7DnJ}lrY+=bHE0Wi-Rd$&2V4?_A7G3+5N&{?=!RGq66|i4bs+%hR#_Km-7f3u z@Wu=?i}hR#a6IcRu^v|6UWoNJ;Ke7hYa$OPRx1|V(8Q)qY)P!S{fXV2IGm7r)FuwB z%C4n}D*>-R!9jK6HYY(D0*}t$=`sW!HICWBWKXPZ2St6ZAra`0+A2N6eZ%<)8cKF4g`V znka6rPfbW^%ot=T*d&88;C&gOPEdy2Ko(4t3{im$)*~p7K)@7(RzC>xlm z!2mcnMdSf07{t7S1BuTnxSQZw>L|D&Vqy?{;N6C^1`@?p@1g@eq3 zRS8ybKXAEl(3Gl(sX_*W`E(R)pj$Xnz`-~SMPP^uhv+$ub`Wm>CzpXKn0TEC^z>*a&?&d{{ltlJ+^NWpdi2i+8tMoFM&KnxW;O$GWfa4;Hq zNLmVLLjhd4QnZ7>%_~L79g66wc#cX*hY&&p>KKi>7>zn^-9Rl3(Io)pig;j38w1wH z@+{-1Y1(?lvj7FFFp;F*u#EM#p)0H98(r z(?`wW)&CuOZNDnbeqNS7ANu@;^!fOfyk*;RY`L~PTiz|-*3wpRYk6yRE3~z-71@ey z#kUe$n_KCv>{foOxK-Y&Zq>J%TkWmxma#S18f}@|)@}Q?bKAY`-S%xSZ3nlPw^z4A z+Z)@F?bvpFJF&gFo!-uF=eLX7U zJKmG`YF(3!Gp=Vm(lg#?e9tUN&jg-Pq-T=P zq@-s`*8|s=rR%HLH?Bvn$F9e(C$4W^PhZbo&tETIFJG@-Z(r|SH>B(R>m%vE)NUkh zY~D!U$ll1`DBdXFsNSgGXx?bw=-$w8^luDrjQ8bz@4jz;X+OBXyuZ31+TYlZ?8o-w z`-%O{{q%lzKfhnxFYj0P>-)|9_I`I?-|z1a_s0jabYMNOA2<)(2MY&_2mXWL!SccC zLFi!PAaW2ph#w>lHV@JV*@OH+@t}NAJ*Xcv584Oa1O1?XFgzF^%7?Z?$D!-cbLc(v z9WEUP50?*D4?~9=hmphBVf-+0xOtd9%pT?si-+aI>S06rLWtVH#oC?J?xuD>#okN< z9f}v5Hv6;**tcm?U8cH?>JF;AsP3V6^<}EBQawcV4XOkEjZr;L^#s*7 zsh*~Kmg;$`7pY#RdX?&RsyC_Lrh1p^I@SABA5wix4VfA?YB;FjqK1bWUTXNLu|$m^ zHI}KdN{tXTHmDJyMvNM9Y9y$!NsTl$ved{^qezW1HLBF8Q=>_ZHZ{7`(5ca<#*i9g z+LvkHM*9xhchSCw_Pw<4qx~h?57PcJ?XS{)oc0s6ze)RP+RxH{p7x8hU#9&k?bm6) zN&9Wu@6x_b`+eFU(*BqZWIC|XfrA1Z8F=WxO9wtWSfYa<9W2wqDjkIAV1o`KbP%J1 zI2|PDV3Q8gbdaTkJRKD2piBohMfDLfXhrM`1dO(veC>P~k#`5tb8V7!N44Y^b?Npa5XZjSg#|OjBk}8*4gP)5V$|*7UNbk2RNAGsv3D zthvgXA=cbr%?NA8SToL=3D(?X%`|IfSu@X?Mb<2{W|cMTtl4DEHfwfSQ)kUSYYtg+ z%vv&Q*;vcLS}xY|u$Gs#e5|#^T0z!YX027$3bED(YeiTq##(XKO0d=@Yn525!dgup zmU-C5!ww#H@vw)7y*vyMYKez~JiN@qt2`Xy;SC;+@NkTW<2;<;;Y}V+^Kh1j^E_PS z;WCfNJYwS!2amXT#KR+A9`W(W5|0FVWSK`+c_hRm8$1%>u}vOJ^H`S0@;p}Lu`-WU zd92A}Z653Ln9gH;9vkx5n5!~ZZCrJ5)x}j0SG`>IadnBSL9Q-yb(O0ju5NHO!qpg8 z<6KQ}b(5=Uu4cKK=W3CwWv*7aYH)SHRUE3+F^|hUZsTzWkGpt$k;nZ!9^~<59uM*O z29HO0JjUa39#8Q2CXc6iJj>&G4pfoHs~krg9&ht_m&f(#Fey!kI0y(rMc!yxR&s^SOX(4j6{K{1d(Q=vnpE^mUc|EkMb zkkBnyE`tP+y4(T$3Z6qPjplle( zYZ#qXBY;;UqWw`BB*5J$G!kOq9aS&~s?g+8)ha+)(cCz+8Z?OH#R(&xPG05r%*>Fq zoumgO4Sm{-Ofo=dGCq<4&Xfs|tPS9wo#50#ax%#Q70P)?4hp(CAIYtgyq)BcRDdqF zofHu&$)vPEO2|+GB8S3dJ1LJzMJ5%Lt$0WUNfjTdtdlCTS4~m_=2WwhnhTzX)V%O~ zq_$2VVmvF<|DMQMhok-kfa6VEu?9o0N+nhL{xRAxw!i5X!Z!R346*mfd@O~&BoOL|noa4dK&4c7cye!J% zCXR17>?=MTnS3}WD?Xg8{NiZo#|g|Y&ToDkmxL~*;`f8rL3m*le+oxDaRLnD0IT5D zP!uZ&Cp)p6D9dOgq%g`dUR`Awnp-PK4b^ZFf^J+0Z?+PGPFDyi8zTP(@^6T|8$%Fc zBj{HI%Z3ucX)uC=FHk}_I9~;@v>>V9>>R3Wt=?2uqApEM875UQU1^s>pepZp59X)G4XO*6_J?D^~b3W&O zJ}5mOd0|m{L3^QoD03GJR{mB|x>fn2^2NIJx85&hr7zWAEJ-i6UL27G z>>(0il7RAkB1IAzcsY_Nz^jlXP~~KlqyXEek|YI?J#8cDK1mM=l-5bcLo$AnfmuXm zon$uQrAXFFvO|(XYR*A&ev(6UE=6)$ zp+O2AQbdlTjTDEZgiy&zO2}LCkdmL2P+=)WNt~ z>z1FikkU#KoY+a*O4=}uXb(vTck4Jv$4@#)?xaZ1OL~C)d#j`uB6@@1)JpU|G0<#d ziS!$!kBGiO`Y7KYk^wOGfuDeHBf~HmcF3?th6VvRM@C};fjb#H$QTVByU7@aFynPH z#WQ_fiYs-6s<={HG>)Yy-l1`rKEy{dTD8(D7W!(2Le@j8 z1qz!TTCLDpmevqaE6^G)AQ7lFXdR-*Iu=`0RR@la!%AzJwqTynN>Dsi+RD>bg|^zX z1)jHMP+;V=2M^my&t!nem_5eqNoI%AfxXUJHOTQBtOE-I0PQ_<0>iP1T$$Ly0M5bt z)p!_7a(KieaR?_h9>q%=ZSaJRCtN(S$nk3NM3$$3I;Wf*z#>mIc*^8yEX3&w&j9(( zC>&rS&)Rsl#Ub0{S%YVXJeT2lEYtZa&jX~+H#x+0JP)ke&I>+X81iDBLk!1@ZC-@# ze^KYy?s?JVB`Yt%%%D`^r7o{!crDLsm1#LX1pqVE15+I+unrw)H;~-L1OQmbkAr@& zYEa?vHCqh$HaR763U_n$ISW2DPL0lr)g_16`O>tqd zbps+*+`tY!VwLw`+4Uf=M>;rjL{LnO1 z{8;<_Vps5^hM;I{5WA8h_9+Fsl7f~iacnE1(aYEXpl_-yi>|Doh82+wGJho`cDoRE zx)69jB?OQ%B=W2y&$>Vf*8vP}h$=Qvd;`fFA~}rY2znc-fJ7T2s3C$5#00t-Ll0tN z`-=eujERwnA#XzTIDtGuzh6n9I`N>CJb+JZ`EbN0C3*?fd!+#2vmg||3)p{z`n^&B z@Cl0{IEX23h(H({n7DZzj|8?saL~Rw1_829I606&9-9Cro5$cK9*Iz7RhlT!hW4b= z76G)REjr&u>9*)y2m5me4S*R49AL%WH4wJUfoSKT4FD3i4V4gp5(gY?jpG0U<7Hrl z7=dUrj$IKQSDoPEo#>PbrbBgMKB}%o5SpdBDo`iJV^9~sszbN~rwbC93pfoFa1baW zr5Hs-5r>8%kUO;q-By9q#bqef%HZ4MGL&a!20$odhQwt6gemkPo`RBX z24{(Q#`~27<}4I8Yga2U>wTZ}3oj(37YeuP(k@g&HZr zE7b^0Z%Cy^z(z)6#NH7m19$`M5eaM+1!~0_WnG|9 zpP;rd)e=~g3p9bNM3`ovdX<5#7_M?*3fTfJf|tNmF-$A)Dq#wv30gI118I!~+CXF@ z%r~$UZ4@}V$x~sD(+5v4aMZ$cVGb<SA{UI;i_g#p+PnshL3_mJ3F{sz>AMZ z7!>OBu%3kjuE>rU#f}(LVi6iJIn67n2HL5w)8DJuwsMIekoRJ^lM zz}+#CIfl$a5Tm5PXQ9z>kOwj^I0!)Q38w&X8-Y*(0rVCQ4w2dt9ykuy0#p9q8Z3#NtSQxD!FJw`8 zse*yEqh)bcT~?}B@56@$t~I4=t!u`$p>%Cba@g#12C3lqQt1(l8mTo26kd5LwN>|M>A+H!mM>>g+-dxU^d_=HfX|OJ928wwZIfKdpXLW zV8m8Trb6#64$ZUC#I+3Z?ApWwDXph4S@1}cg}`J%fu~I%pqY3VCSC|~y(UlKF$y7= z16+5|(L(R=MhBgchPkjh1o3(W7xAV9f$Il-7}KB+qNOC(iy&00gD`4@gT;RnZ)b25 zBb34m7lfoFm<}P3jvfWGSPX($>?%1icu<@U=CGawVa5>@Vu)Y?LMxas!hwxY5wCj? zuV=6X7(EC(hae1j;UGqsH3TatRmBNESVa=76X77n5Df!B9~_F}L+n9z9MguW7ixlhU)^XU8-s(}au3c(n2w)7P0EVR~O;`hXeoM2=15`oxx)>JZuL z&8e|5HB!@||LSw7;DJy6(dWo;K!zh4i7~5-S;x$_#C!|Px5#`&rWTl5Vrqq{HKsP0 z+G1*lX)dPam{wp~iD?z4)mYZSvM!eOu&kG5eJs1gvO$(zX4zGi4YBM7%Y|7k%5o#7 zrutpLtMv z?}wyc{AKA^KKaRO$!oc5UFllyn)&qj8TS_=(igO67oL-!vp?s0t|dL!ettoE-ut{y zdfxwh^!d2-y!Jv-dZBV_^^3CfMgNOE=|zL!1tN(tNybSAhS!-4$<#>>2J&4}s*|RJ z^xDJ-5CiHxMwASp-8Eb$!&NeN66nPebCsB2=FJGTLKVgup!Na9RHObph0zoZS7{VX zZL~sRQ9xr|s)1$ILR13>twkuLMl|81P?VqvFU6KbGfoP-0-A>bFls4gX%U=ou|g|= zJSquVgOzd3q;;^hb&~>br45q;si7@5h0ZEeHkiE5WUMN3j>$lBWt{<9Ve*(kCxlt; z%<6`xFzX7lt|0_~)Br0yWG!H~Et7TX4E!Y1txSj3uI^#_BGaMStB05l4HG@g^eEHg z2x&~ms-;(%j@#&XXi)#tO=egbtX!C}G?Af%BHJhOXks7m6)>?YCf|T9?FKYrTRc4G zQLwqu9#4YPPC^v~=C7#$PeJo9)#s@pPXpyh*LX(bIDztr(?t8AftytZWU$&|l?Z~{4K87I z3qU7g4QpBw$^mIy!y+Y!ofZxZ9SgV+JW{X(eT1@DbIXW<<{KOc_(y99jIjIR;lS~O znZ_!t*udV}1iWGg!z*?!#R(482`p7{g1>ZweNx=OS=@dQ*g-cIPsI&p(<7Ka57;*^ z_E;ES!-1SyK^8^D<_u1FU9g(#VBx|d5Jt6OtdB|3^_}|E|PliJpi849DJlO{S-ro@IKT8McWGX2Ls>eG?fIIyjM6Cvs>aZ%pLKL{_J5 zm_e^k_0Cl9O?6|c52pHPs+&{8IyLN5!#y>^QzJSx)alSO9S)|W=yU|#)y=E_79ISF zYn#%w%(H>#7hfDpFPbC=4kOnhIeb>5L23qp>4O$!kkv68wt0Qp8%~YFbm*8uy>)6P zr)CBotihV~t1eXc$v^&+Yx!%nYwc_LQ#R=-=TpnlQ`%D*>8a9Fm8WXbQ|8m1XB^Tq zPCAAa0IUa0D>b23sC;sEL^0mh2*FWF8-hJLBJ?~*w z2eU3SEA~X|klDQGmXA3$7$!DzI+$~jxv+P-R+%dTFUnjA=1MVFmbt17Cb-NUVD4q+ zUS)3ZQi~=7GsApI<{z>p>>W!j7KlkKkYu4ATeq@xsLHLIEL>w6>en0$5HZs-3|tx0 zOa{i7Wo;}A5m*inA0=}GmctTQG8xV=tm0t6(OJbeEf=Q7=G4F|Z)B&##py7Hl^{MH z#ipb9)ZCn!1v~|uPofZNM4`4Fg~E3XB7+#tD=Jj9Rp@=kAvuWSsnkggDy21@)cT}hl1_kh z41xuV4DDpNLWY36hU)~&6d6MQvrUFwGStZ!@R*4m3XqlQBPL`FW`LN;Yi>{*_7|H* zmvCTM!a+l(SXXHd-!&^2@{Fvlu$V2g3AGY7T+ zM~XQz%#mY`0&`TE15eg5U`{V{;_DAiKXV2ccu?lTlf_o!3NzT|GZ*;YB)m=LO2f-A zR}NlzXd3j|bCnj+>?di zWB~_&1#<#5tckZiSw!;Uc!D9B1kAq!#PxSQe4YZwxfOs?&`wO0cmhCEqQ?_B<^eq_ z7}MTpYNn@Veu~$7YF4NC8phNFGw;A^9K=~J=oH(L3u=4#W(S-lP*4QG`MUrkiKAZ7 z4gI#HD3HXtqJ%96rjemCHi{7Tu~5Z{WgMb6aS&JSnD=61RH2BbI)p6GnFfgyz7wyB z&_q*RILC{-sV=+}F63{5RNCPH0ce(C+=>F4Tms=u(`+lCga}kY;O{jXOhE0}yEHpYKSGV*`mK4@^lHM9m8xkce4OK%(Xa*u#qEYJvWdCXSI>bQL6$ zqNoSZAskqv3N<24Z5?S)Plm1Q#*rrarX?0ZqQaybbQ}mHAc}7yW>ds$R$$^PGN+L_ zEn@IR2Q4FFGO*mu0Ef{sT@YH3!DG>~o1nS~;Kt(IrsdF+oG6L0)C!{ZLggxik~2)s zpZJBVZ^!kyYY7^W8HSO`UMAO=Rh!82)!FYphDV^V^pG$`Ene$@>+XO4RC!5QrM}wG z*1SkN7ZkuzQic%onMg8BDVFzR{$0Fg^ zlD*(Wa$@s=JDrMPAUMW7UZ?2?`f)0$IT17a?-+wXV1sIbf8kRNx8*js#m}hyb()8u zb|K%vD4j~G{SfuwYW)>sJWPo4kL6*f(tL~Ug`9Hd6ame4qJ|8rQvoJjJH;llB& z0tkJjl?>#8=#P*GqLV@%h^xC+GN;l(qzPf*I_zZ-QttrKivT73r+9P%MNchgUTrs% zM%t;q#o#t_{WYv;umJ%Oy=_bry=_b*#E2)7!+Fgkph91%t~C!qJs#D_xn0&Ryl z@Du{aaRye3c=3d-`YRP0UoJ5;j_ue_q=UkG8eojjxI;UH*|g`jsvVjttf%j4+~NAf ze)_~zdiZKnX{hz0)Tya7)bLQFP{V^5_S95*co$84rS;@ji6~FB_P}cjlWM5zf%*I@ zb-fcCYoVtHmiySo+L-`9?KxH1gFxum+!~R>ZW(;@tE`q!?T%o!*#XY^4>vu!BT0pw z(JB58JJ1s&Pyxf=wM#mdvfefey=$T*tV6$9Go@4eq|t5rB;RfOBp4>)*m_rp8#a%n zwctW5Ho*LqlW4Z1fBc*iZwsq3V9qS}yhMo>S z$aySXNx(ZXOM*BTX+mWO6+za5DSq1?30T#M)e#I@5h=8IfPz7y`#LO-a4}Eg+c#yP)KI7R{^i%OQvw9?a$)qV@N%OuHCj`n zH#Ll@0h6ZD6kqTX=1jL`P$xQufYnb7y^qbD{)r8n1gv%}5E5c@NLJtgkn@5+KDKfa zf^@;#zs%AJLL)!;=ws3P*D-K96)XkCiQw4M>5ha==sF#%PTnzJ$0_yb|K~UHd2qd&;8wuh%~6RNwTD&HstT6!aBNMVGH-IwiCiaGTp2 z45yOK+o}u@cw_a21KXUtvQCj%C@$O)dO9I7K3156_zr;<2;%Z%orYtJs#8@4abo^j z_Eiw~3!Mfr(O$oe74#nN$XUf?ysdX9(BE&~>Pq0sUqeX`BXq2&Cs1UesP`IL72@W? zGV6}C_gJGs#GYDb-4XxZHq#P{6atJs)}MeN@V5ShC?HfOguT`sF>yr13Z03&@?sGq zEVyoKQ9x(njszKpx!XDun+XJjDEYQ=7cTCoONhsC*Qg8V`qwk+I#roCw(Jrmg;ct6 ztR(^H{H_880FB$~5~2aGVf6Ld3KUSDxFg~2h!($wJ($ok6gNIruvifRC?=kY!%xh_ zx-T;m6YB~D*59PPn0OtJ#p-tq$Anzsw(bThJl5S1R*J_TQ~=L~Kp6B@Hf3P-k3X;R za^o_@KpFBx_2cem82-_0&R(WVk^$gztV?oR-x3#?*xyL0M2y(o4}iRG4Rol6fAwcU zzL6F>1R1YO3mww!<1d2TRV)`OFn2!<0=(;0p9TT&^{P*UKg;O0ZtTymfb(<$58%T!b1NTK+x;^T#7(|ZhtZ5 zYog)!Dr_1sr|1F+I*|u zi+LGZ17)z+L~F#?yZ$L)n!BHo0a$`h$q1MR9|Al6qD<}ddtk4D*8CHEU*Yk~;*ZXmq6PQPQTm~>t`yUANyuQ!Pyb9R)=08634X~ZBjo%y_hrR-}`Dghm z%^mROtAU%Z1=>JU_L~E3a60<$4yyqk19tnL>w`643y}GjPuRe~1gD*U%um?dhC86* z_ut94Z2n;&#T{%y0E4$bY9j*T8;`FKi2w)z1m)%5g8WAVA#NMB-}#K_|7a+}-S7U~ zKH7_e{J)&&?|uO2=Gk9+81x9}BIpw6^3Aiq^BCyUAYA{>70}h2XMY#@es>Opd>^%d zkmsXF{}|#whUd!SZEBXarpr^!;$2nE9i( zeeTSa8T-r=XWlXMhcjnp{^G1<=HoMkGaoISx%s9?AG`FY=O4RVID7N#gYUa}4}P$) zFf;#dl>4tAeD9S{KmOjwFFYbbE4*d(3sBu z7>drnQ#d~%95Ie}yD|R&F8>I0cT9c=KO#Bz*ALGV8C8=qnmHOQ|-n{`4 zg2Z56j>CEMbi6E|J9}m3iL>|t(KCO3cK(l_I5YpzC-B3g@4!@i$IO*8SI*u}`+kfa z(ofUwc?Zfof|0hI{qW3RJcbd!=LzI|UGC%prv!A=?bN4=R&lC5eChrsX z9M98v%W;hOIna}9%-aXv@X;@ehx6tC7k~32^w~GO>$3E&%MaXp^Pb1%E@BRUYX0Uu zm*y=u-+2D<$LB6u9(cp-o5c@wKJ*xV;q&G_e|q(in`a)rdFK4hGk^N(fqTnCpE`fh z^4Q!%^H(ok{u9)FS!mPEoVoXS?9QEe``NdhecSO!-gkEX7m;%FzK0(AG=Ayxp@$wg zd-KhIeZlh3*ug-n;-d}t8+%J9hEta`Q&YjHU_gt8n`OcXO zGfGfzyE<>z4@kx9UHG%wzqdGYGZi+M2rM&Z0kIAY?=zgalq7k%fyO*r@*^UVBPh4byg z0pvL|kDuC{ng34Vh#$Y0hnC^YyjZg4zgIY72KsY}roF5X7_|(F@ z_+8-n9~F-1>Fth-VL5))kLT^3A-{P3({t#;x1n$1_g6*#Zr+b!5I?qhVeazHdoSU^ zi)Zu51w71$Zk~PQ@tgPJ7g8-^DYUW~6SxJa$&2kpMjan-K&OGoTSPrOs+~N!3+N zRy9H$t+8Xp?#`|sVPE&)kRp8WgipTtxDMZZ^2rWY_~wg=@WJ7W!-T{5`!lOs518@V zv2LldvML{y`9Ht^&$~yC6tZa$OYu&hdWJ^Yt=!Nzp zvYkft;^~cR8qe~sXBzKv`nJubqj=8oZajB8$MAfdU*bo2?=yX=pMSvL;C-mQ$v@;r z`7zW6_(%LW??>$ff0GY9)0R&16Z|CZr}!!U7VdBHxA|$@-{wEy@8Evg)s}w1-{lPT zcla4Ti2J+zV}6#O!z_&dkiW-=P&56!2Kfd4K6;+zBYYJ1bG*QdxSvO_ zF@6!fE;<%g`yMwIwEQQ{zsNEC>YJ-I$B)87BXT|Y=Ii~xoP2c`ZEm#5DhBl{{?D(NG&aN)ZsP>yTrf26DW?3Z=j60F-didsZ5{db|9v@kBo<=ureJSjE-4V_7 zSHV&?$`3DxSZRK066Hh@Zzh{Zv1DxEY0dkJ`eGMl+V%b)R6r?1A1aOp zCD2F#mQ2Z5Gd?oy*x~OQk*N5Y5{L}RPQO39ye?+X~~pIJSdk+-)bU@ z#mVBu#bQ*e7wc|)wBgt7^18!EH>!@~jYb!P%427Z7u!NuBq1z7q)ZGxgDW&pWOe!c z-E`PiM$yuCw3gm7ca5!7%MvGBsU3Y+Lp{|p)-z%v0$WPu?CKR`K-<=T zthZ8Fs5##}|Ap-}94Y8Z(AfEq)f!>MR=_O9u=8Ql7-9KzY_2*{obrMVN67WY)>`2D zv01b0u^C1JT{3ExP*#X7amMy&1dlV^sn`uKinD$oYGpfg;xq<<&HD&Kw1|80ol?0P zKrc&}FHajLY18x`-O{u8v-D#x(}ozpyE1XB{UbutC27<`C83c48krGj6@d!kt(Li< z$tM#}BazWExAo+WwQYpgqZBA-wmQ`E$6Dr2dRODddRpA$7@a&@c&>8L5+l<4M{o`F z&CEBi-teE;p37OZS$EiZagfrVvPS5zi^Z`Kw&{dLKNw+=XgI}+?S;+==wA#f6$rn6 zF*ea5wx~5W0)LTSj>U!_#3|W1HqmpgIo_=ZT(BIz|taPJtxL>js7C@AY1Qi{yFrp z&||sN1H!P!c=Ryt!R0Gu`K(Rd?_lO;&``Rw>OOIp?Zae8&Z;ArmMQL9ggi<6qBJr01uFSe@pI;0UA%`L zuaLc?UDwgNpX?p&dI!2;?t*0U4J=QEbne5*O0+C}kO`8w#(eWfZR-4b#ATifBPA)B zR{|^E#fqeO#;LFl#1LE5Cr(9;y5~qTbi;0%L0}ra6 zPH4Nju01}D>+0jvT;H);`YvE45fw%|)?Vl^$0CF2u~nGRdYqFx_FNxUB2Bo&=i&&p zr#;yrZ^A;Xti`4vGeZ3i@A?>Ar!vQ-s$+BNVq=2D@TQ@YFuKsxej}}mkI-^p-{dK2 z?{tNyQT$A+NO=4#yQP1FUAOcS34~6DHg7hs+;O6Y@R`kEVIsE-aP~BU%Glm!2!&}w zJ%9x}VnX%}S;Y(RBzYbdUimy(8nQqk8H8rfHz57Cz6CSj4?xK^DEXjL^83K=3)(#_ zDIB3%b0C73BySl(^|$qH$ZKLer1b8YhxW+CAgtm;@|RTpbqXG^YxZf`k?tRkQF+Iw zFw(SiK@MJ=LjjCn(T-z7Jo#3S^@`$#GM3a(N=Ol)b0U5Qv=zc98DZ!HU`F$N&0cqs zu67iN!h{!;;X5V^`{&3TN>q9jscTMD4LDwYMyr{mLYnIds>v0+acJ5aErO(4GkUs# zhc2U5CXTm%1XDWp_)qXahJiz7NxtDUQ{r4p<7UhFiE&EG|CZ@z(TCuQ33Fjkz$AXz z9OiJN&tRt^@g~o3Q}&14@9HyPCeNPIwycDqX|N^gFtm#p8fA8}JlE0(P+RMQ%ZI$} zU7m9uM;q(D1l724@p~Xc(!29(>fF-1n^c^)Cm=A zwPADWwullOD`9n5byjR()db->PhmOQAqqkG$;nAp5kc)>u*2M1J-|fC=#qrIPN;x- zGU`y<@X*;a#YQNKE3RL3{3n5#k;Y-VfWuBiJN&r9RSp;JEwI@}xTq=C{ z8=rGjG*&jhf7UqyJ^#z47Jt*zLPbOr2BaeZrW5!ovqAi0YImH?qC#k}L=D(I!Jl0>~mHm1jy zmv2jv00-OE0;c?ax=RU>>$`0WAoj=+Asc@5XlS%D^ym@8BB?%F2?Bbwg~QxcAb7-d z*b15u1AElMgG78uokC2+?6BR=Mjdp?t1Tclbd+HSkr8c3d&KNU6hH}F*e`DrQMxTa zCZ%>8)c~|m&WQ~>tK)LD^qJS_D`wn~kvU>cpT7U_ocuHqF4l8`y!Cw3ID6(52SQeC z0hh!^tFU1Y2FQX4cwbmE*q{)#KQ!S_ZzCsX_UC4O_ww;rAkhnEY(;A*Q}Vj6?uBN7&r>ULBu2}ca!ohVR4?uO5urxGv12O&zM^+Dp$aBcq9 zo!RLt3$qB%Bo_cY$7xIo)OO&@@Cn><6;}Wv5l(=6qgem&#@{%!x34jY!kwoH@*gt@ z_8a;;IzYccp6wVRQC%#e-vReRn6raB$xTIY9W5|Kx)*&tD+Va}0PtjR6K_rFK;X^S zQoF_u;u@yb!L zI6FT$BxQeoPFw>W^4a)kviy=tsSuZMp(ReOil9*!H&GX#(+mAZoRV9V0stgTJQV~{ zW4(spTv6c_9=4}XsPpIOAIfZLns`XToA?Uv4k#0;82qaO!PGf|GI8K4P~T{NaDe*K z%+cCIAo_LKmWWkhH*6-!l6<`oTlAP$-@;9Pzr@#NN<}lo z1Jnk1(Ph~Pbk zG!lS;i6H>pNY<6OQ}&4U_pk}j$_}gXn^Gb|C@3Hz^(osB%Q*Yn&ZY_zDY8+rlE#!6 zoybINt~;CJKDB;I#UV2HN@jJY{S~@|CsAky#q!xCpd{f)1Ec~ia!Upnls~7_HbcNDL_g8-pTT3$QYX6AhC5S930AsJ0 z57XjEX9}9(Z!t>AT3S#6W#l zA(KZ$u~b0VGQ?sFKp1W*BU{t03|do3xH#^AB3mzQWe{j(c=`lMZ#L3G@j5} zI8C5?XXHKgEuK>|@$MaiKr4mU0K85@3~kG#+a=b!%AqhN}6lIQzsFGR=#0 zqVpKRs=X2Skh?+R!gHQD9%fl?%w=4X?0d;_ zIyB%WPKhi|pehxo=Nd>0IL)73bHGxh1>^w$ivk?ORIov505<}$o^1QN?Q@TiXx%Bh z5;y|$-65EA69`Fsj`3xLxoc!)75QGVTO`?1 zg~=*L+K+Miv7mjc)3MNT0D>Deq?+hN%i+?YxI!8Qmz)yx=D^BLyr68YT=_Fpn*E&!UApFq zkvKOU&h2aE+?qJ5!?C7{qLI)8*g{l~J4Un&8ll`6k}G;-RVdH;RE?B#L*}U`M+^09 zySyZ$iWEAm`(MvE(u!Z8bj1Z_%vT!-yungfnt&q)OE^78XcO7-O?G#2ZuFB+Vay@z zVKr!YPz{{W$#BXK{88E78IDMtkpE&8(LIeO1%i%1m?(mg=@Nuloo`WJ1fm{W!BG)O zj)#!MAH6ujHmYv9iui5A-b91}5lm)orW#RY^b-|VAl*j&FOn$3C&NR<$L=c6rM9XN zcUpZn?gzg+i)k++?!GBc$7ENSNr`oS0;VnX$iB&14=ZVpBpe|Dd^Jt7CB1Tn)RI!X z29%WkdSUJW+P=Yr2do>ZC<&F6kr`9~+GGZA+Y}ScKFZd#^feqIZ2<`R{ouL@j*qo7 zFn$jbY8bHw$pCb+2s(ksX7g_j@)&Uj9qcJ%<_J9CXcPPwwF|Fsns`MmvQL{lBLs+K zw&oCLCEpR5|NpT%&bAi;C5n1lUhV{SNX7nF>-hFQp5oge}T`b{gPCQpQ6Bie~;?&#h#Ip zxcq2)bEWo2MrfDR3;9IpJj5TMUZxlOf3(NTxMcow&uMT24g*k$b`%fX^~+v>gR0d< zn2^q)`~h0wYZ}cZX+>sG*)bh4{emVaDuwk%hPDw_#qZ+jFuzjt1?OX0G)<%F&C{>{ zYC(3yY4u?P{znIAl?0N0;1AL8VSD1NA?P`8%+KY?qsV__PLW-gtI7|_RIUu`;Mg}q zIP*Zzs$`HSehalYJ#%aE%FUZ`*XMU{F5b9#V}3Tyd@+0H>aB%YL7+d*+?~HMeQRb` z%+tUXD!!!RArE}$ul8ArylYMKwPF8#p^N%lo6JAM30;b0>KJP z5h##uNot1_XUTK9;eGV(P$te!s6+lq+MGP@wsK^?dd!@j?&|w@D~IsnrDgP*eO8~9 l%jNoWy}6!jPxfebGwkvl$*VmiNzKOTl{{|pT<~RTV literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/pygments/cmdline.py b/.venv/lib/python3.8/site-packages/pygments/cmdline.py new file mode 100644 index 00000000..457af34d --- /dev/null +++ b/.venv/lib/python3.8/site-packages/pygments/cmdline.py @@ -0,0 +1,582 @@ +# -*- coding: utf-8 -*- +""" + pygments.cmdline + ~~~~~~~~~~~~~~~~ + + Command line interface. + + :copyright: Copyright 2006-2020 by the Pygments team, see AUTHORS. + :license: BSD, see LICENSE for details. +""" + +import os +import sys +import getopt +from textwrap import dedent + +from pygments import __version__, highlight +from pygments.util import ClassNotFound, OptionError, docstring_headline, \ + guess_decode, guess_decode_from_terminal, terminal_encoding, \ + UnclosingTextIOWrapper +from pygments.lexers import get_all_lexers, get_lexer_by_name, guess_lexer, \ + load_lexer_from_file, get_lexer_for_filename, find_lexer_class_for_filename +from pygments.lexers.special import TextLexer +from pygments.formatters.latex import LatexEmbeddedLexer, LatexFormatter +from pygments.formatters import get_all_formatters, get_formatter_by_name, \ + load_formatter_from_file, get_formatter_for_filename, find_formatter_class +from pygments.formatters.terminal import TerminalFormatter +from pygments.formatters.terminal256 import Terminal256Formatter +from pygments.filters import get_all_filters, find_filter_class +from pygments.styles import get_all_styles, get_style_by_name + + +USAGE = """\ +Usage: %s [-l | -g] [-F [:]] [-f ] + [-O ] [-P ] [-s] [-v] [-x] [-o ] [] + + %s -S + + +

%(title)s

+ +''' + +DOC_HEADER_EXTERNALCSS = '''\ + + + + + %(title)s + + + + +

%(title)s

+ +''' + +DOC_FOOTER = '''\ + + +''' + + +class HtmlFormatter(Formatter): + r""" + Format tokens as HTML 4 ```` tags within a ``
`` tag, wrapped
+    in a ``
`` tag. The ``
``'s CSS class can be set by the `cssclass` + option. + + If the `linenos` option is set to ``"table"``, the ``
`` is
+    additionally wrapped inside a ```` which has one row and two
+    cells: one containing the line numbers and one containing the code.
+    Example:
+
+    .. sourcecode:: html
+
+        
+
+ + +
+
1
+            2
+
+
def foo(bar):
+              pass
+            
+
+ + (whitespace added to improve clarity). + + Wrapping can be disabled using the `nowrap` option. + + A list of lines can be specified using the `hl_lines` option to make these + lines highlighted (as of Pygments 0.11). + + With the `full` option, a complete HTML 4 document is output, including + the style definitions inside a ``$)', _handle_cssblock), + + include('keywords'), + include('inline'), + ], + 'keywords': [ + (words(( + '\\define', '\\end', 'caption', 'created', 'modified', 'tags', + 'title', 'type'), prefix=r'^', suffix=r'\b'), + Keyword), + ], + 'inline': [ + # escape + (r'\\.', Text), + # created or modified date + (r'\d{17}', Number.Integer), + # italics + (r'(\s)(//[^/]+//)((?=\W|\n))', + bygroups(Text, Generic.Emph, Text)), + # superscript + (r'(\s)(\^\^[^\^]+\^\^)', bygroups(Text, Generic.Emph)), + # subscript + (r'(\s)(,,[^,]+,,)', bygroups(Text, Generic.Emph)), + # underscore + (r'(\s)(__[^_]+__)', bygroups(Text, Generic.Strong)), + # bold + (r"(\s)(''[^']+'')((?=\W|\n))", + bygroups(Text, Generic.Strong, Text)), + # strikethrough + (r'(\s)(~~[^~]+~~)((?=\W|\n))', + bygroups(Text, Generic.Deleted, Text)), + # TiddlyWiki variables + (r'<<[^>]+>>', Name.Tag), + (r'\$\$[^$]+\$\$', Name.Tag), + (r'\$\([^)]+\)\$', Name.Tag), + # TiddlyWiki style or class + (r'^@@.*$', Name.Tag), + # HTML tags + (r']+>', Name.Tag), + # inline code + (r'`[^`]+`', String.Backtick), + # HTML escaped symbols + (r'&\S*?;', String.Regex), + # Wiki links + (r'(\[{2})([^]\|]+)(\]{2})', bygroups(Text, Name.Tag, Text)), + # External links + (r'(\[{2})([^]\|]+)(\|)([^]\|]+)(\]{2})', + bygroups(Text, Name.Tag, Text, Name.Attribute, Text)), + # Transclusion + (r'(\{{2})([^}]+)(\}{2})', bygroups(Text, Name.Tag, Text)), + # URLs + (r'(\b.?.?tps?://[^\s"]+)', bygroups(Name.Attribute)), + + # general text, must come last! + (r'[\w]+', Text), + (r'.', Text) + ], + } + + def __init__(self, **options): + self.handlecodeblocks = get_bool_opt(options, 'handlecodeblocks', True) + RegexLexer.__init__(self, **options) diff --git a/.venv/lib/python3.8/site-packages/pygments/lexers/math.py b/.venv/lib/python3.8/site-packages/pygments/lexers/math.py new file mode 100644 index 00000000..a4493f74 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/pygments/lexers/math.py @@ -0,0 +1,21 @@ +# -*- coding: utf-8 -*- +""" + pygments.lexers.math + ~~~~~~~~~~~~~~~~~~~~ + + Just export lexers that were contained in this module. + + :copyright: Copyright 2006-2020 by the Pygments team, see AUTHORS. + :license: BSD, see LICENSE for details. +""" + +from pygments.lexers.python import NumPyLexer +from pygments.lexers.matlab import MatlabLexer, MatlabSessionLexer, \ + OctaveLexer, ScilabLexer +from pygments.lexers.julia import JuliaLexer, JuliaConsoleLexer +from pygments.lexers.r import RConsoleLexer, SLexer, RdLexer +from pygments.lexers.modeling import BugsLexer, JagsLexer, StanLexer +from pygments.lexers.idl import IDLLexer +from pygments.lexers.algebra import MuPADLexer + +__all__ = [] diff --git a/.venv/lib/python3.8/site-packages/pygments/lexers/matlab.py b/.venv/lib/python3.8/site-packages/pygments/lexers/matlab.py new file mode 100644 index 00000000..72203113 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/pygments/lexers/matlab.py @@ -0,0 +1,720 @@ +# -*- coding: utf-8 -*- +""" + pygments.lexers.matlab + ~~~~~~~~~~~~~~~~~~~~~~ + + Lexers for Matlab and related languages. + + :copyright: Copyright 2006-2020 by the Pygments team, see AUTHORS. + :license: BSD, see LICENSE for details. +""" + +import re + +from pygments.lexer import Lexer, RegexLexer, bygroups, default, words, \ + do_insertions +from pygments.token import Text, Comment, Operator, Keyword, Name, String, \ + Number, Punctuation, Generic, Whitespace + +from pygments.lexers import _scilab_builtins + +__all__ = ['MatlabLexer', 'MatlabSessionLexer', 'OctaveLexer', 'ScilabLexer'] + + +class MatlabLexer(RegexLexer): + """ + For Matlab source code. + + .. versionadded:: 0.10 + """ + name = 'Matlab' + aliases = ['matlab'] + filenames = ['*.m'] + mimetypes = ['text/matlab'] + + # + # These lists are generated automatically. + # Run the following in bash shell: + # + # for f in elfun specfun elmat; do + # echo -n "$f = " + # matlab -nojvm -r "help $f;exit;" | perl -ne \ + # 'push(@c,$1) if /^ (\w+)\s+-/; END {print q{["}.join(q{","},@c).qq{"]\n};}' + # done + # + # elfun: Elementary math functions + # specfun: Special Math functions + # elmat: Elementary matrices and matrix manipulation + # + # taken from Matlab version 9.4 (R2018a) + # + elfun = ("sin", "sind", "sinh", "asin", "asind", "asinh", "cos", "cosd", "cosh", + "acos", "acosd", "acosh", "tan", "tand", "tanh", "atan", "atand", "atan2", + "atan2d", "atanh", "sec", "secd", "sech", "asec", "asecd", "asech", "csc", "cscd", + "csch", "acsc", "acscd", "acsch", "cot", "cotd", "coth", "acot", "acotd", + "acoth", "hypot", "deg2rad", "rad2deg", "exp", "expm1", "log", "log1p", "log10", "log2", "pow2", + "realpow", "reallog", "realsqrt", "sqrt", "nthroot", "nextpow2", "abs", + "angle", "complex", "conj", "imag", "real", "unwrap", "isreal", "cplxpair", + "fix", "floor", "ceil", "round", "mod", "rem", "sign") + specfun = ("airy", "besselj", "bessely", "besselh", "besseli", "besselk", "beta", + "betainc", "betaincinv", "betaln", "ellipj", "ellipke", "erf", "erfc", "erfcx", + "erfinv", "erfcinv", "expint", "gamma", "gammainc", "gammaincinv", "gammaln", "psi", "legendre", + "cross", "dot", "factor", "isprime", "primes", "gcd", "lcm", "rat", + "rats", "perms", "nchoosek", "factorial", "cart2sph", "cart2pol", + "pol2cart", "sph2cart", "hsv2rgb", "rgb2hsv") + elmat = ("zeros", "ones", "eye", "repmat", "repelem", "linspace", "logspace", + "freqspace", "meshgrid", "accumarray", "size", "length", "ndims", "numel", + "disp", "isempty", "isequal", "isequaln", "cat", "reshape", + "diag", "blkdiag", "tril", "triu", "fliplr", "flipud", "flip", "rot90", + "find", "end", "sub2ind", "ind2sub", "bsxfun", "ndgrid", "permute", + "ipermute", "shiftdim", "circshift", "squeeze", "isscalar", "isvector", + "isrow", "iscolumn", "ismatrix", "eps", "realmax", "realmin", "intmax", "intmin", "flintmax", "pi", "i", "inf", "nan", "isnan", + "isinf", "isfinite", "j", "true", "false", "compan", "gallery", "hadamard", "hankel", + "hilb", "invhilb", "magic", "pascal", "rosser", "toeplitz", "vander", + "wilkinson") + + _operators = r'-|==|~=|<=|>=|<|>|&&|&|~|\|\|?|\.\*|\*|\+|\.\^|\.\\|\./|/|\\' + + tokens = { + 'root': [ + # line starting with '!' is sent as a system command. not sure what + # label to use... + (r'^!.*', String.Other), + (r'%\{\s*\n', Comment.Multiline, 'blockcomment'), + (r'%.*$', Comment), + (r'^\s*function\b', Keyword, 'deffunc'), + + # from 'iskeyword' on version 9.4 (R2018a): + # Check that there is no preceding dot, as keywords are valid field + # names. + (words(('break', 'case', 'catch', 'classdef', 'continue', 'else', + 'elseif', 'end', 'for', 'function', + 'global', 'if', 'otherwise', 'parfor', + 'persistent', 'return', 'spmd', 'switch', + 'try', 'while'), + prefix=r'(?. + + .. versionadded:: 0.10 + """ + name = 'Matlab session' + aliases = ['matlabsession'] + + def get_tokens_unprocessed(self, text): + mlexer = MatlabLexer(**self.options) + + curcode = '' + insertions = [] + continuation = False + + for match in line_re.finditer(text): + line = match.group() + + if line.startswith('>> '): + insertions.append((len(curcode), + [(0, Generic.Prompt, line[:3])])) + curcode += line[3:] + + elif line.startswith('>>'): + insertions.append((len(curcode), + [(0, Generic.Prompt, line[:2])])) + curcode += line[2:] + + elif line.startswith('???'): + + idx = len(curcode) + + # without is showing error on same line as before...? + # line = "\n" + line + token = (0, Generic.Traceback, line) + insertions.append((idx, [token])) + elif continuation: + # line_start is the length of the most recent prompt symbol + line_start = len(insertions[-1][-1][-1]) + # Set leading spaces with the length of the prompt to be a generic prompt + # This keeps code aligned when prompts are removed, say with some Javascript + if line.startswith(' '*line_start): + insertions.append((len(curcode), + [(0, Generic.Prompt, line[:line_start])])) + curcode += line[line_start:] + else: + curcode += line + else: + if curcode: + yield from do_insertions( + insertions, mlexer.get_tokens_unprocessed(curcode)) + curcode = '' + insertions = [] + + yield match.start(), Generic.Output, line + + # Does not allow continuation if a comment is included after the ellipses. + # Continues any line that ends with ..., even comments (lines that start with %) + if line.strip().endswith('...'): + continuation = True + else: + continuation = False + + if curcode: # or item: + yield from do_insertions( + insertions, mlexer.get_tokens_unprocessed(curcode)) + + +class OctaveLexer(RegexLexer): + """ + For GNU Octave source code. + + .. versionadded:: 1.5 + """ + name = 'Octave' + aliases = ['octave'] + filenames = ['*.m'] + mimetypes = ['text/octave'] + + # These lists are generated automatically. + # Run the following in bash shell: + # + # First dump all of the Octave manual into a plain text file: + # + # $ info octave --subnodes -o octave-manual + # + # Now grep through it: + + # for i in \ + # "Built-in Function" "Command" "Function File" \ + # "Loadable Function" "Mapping Function"; + # do + # perl -e '@name = qw('"$i"'); + # print lc($name[0]),"_kw = [\n"'; + # + # perl -n -e 'print "\"$1\",\n" if /-- '"$i"': .* (\w*) \(/;' \ + # octave-manual | sort | uniq ; + # echo "]" ; + # echo; + # done + + # taken from Octave Mercurial changeset 8cc154f45e37 (30-jan-2011) + + builtin_kw = ( + "addlistener", "addpath", "addproperty", "all", + "and", "any", "argnames", "argv", "assignin", + "atexit", "autoload", + "available_graphics_toolkits", "beep_on_error", + "bitand", "bitmax", "bitor", "bitshift", "bitxor", + "cat", "cell", "cellstr", "char", "class", "clc", + "columns", "command_line_path", + "completion_append_char", "completion_matches", + "complex", "confirm_recursive_rmdir", "cputime", + "crash_dumps_octave_core", "ctranspose", "cumprod", + "cumsum", "debug_on_error", "debug_on_interrupt", + "debug_on_warning", "default_save_options", + "dellistener", "diag", "diff", "disp", + "doc_cache_file", "do_string_escapes", "double", + "drawnow", "e", "echo_executing_commands", "eps", + "eq", "errno", "errno_list", "error", "eval", + "evalin", "exec", "exist", "exit", "eye", "false", + "fclear", "fclose", "fcntl", "fdisp", "feof", + "ferror", "feval", "fflush", "fgetl", "fgets", + "fieldnames", "file_in_loadpath", "file_in_path", + "filemarker", "filesep", "find_dir_in_path", + "fixed_point_format", "fnmatch", "fopen", "fork", + "formula", "fprintf", "fputs", "fread", "freport", + "frewind", "fscanf", "fseek", "fskipl", "ftell", + "functions", "fwrite", "ge", "genpath", "get", + "getegid", "getenv", "geteuid", "getgid", + "getpgrp", "getpid", "getppid", "getuid", "glob", + "gt", "gui_mode", "history_control", + "history_file", "history_size", + "history_timestamp_format_string", "home", + "horzcat", "hypot", "ifelse", + "ignore_function_time_stamp", "inferiorto", + "info_file", "info_program", "inline", "input", + "intmax", "intmin", "ipermute", + "is_absolute_filename", "isargout", "isbool", + "iscell", "iscellstr", "ischar", "iscomplex", + "isempty", "isfield", "isfloat", "isglobal", + "ishandle", "isieee", "isindex", "isinteger", + "islogical", "ismatrix", "ismethod", "isnull", + "isnumeric", "isobject", "isreal", + "is_rooted_relative_filename", "issorted", + "isstruct", "isvarname", "kbhit", "keyboard", + "kill", "lasterr", "lasterror", "lastwarn", + "ldivide", "le", "length", "link", "linspace", + "logical", "lstat", "lt", "make_absolute_filename", + "makeinfo_program", "max_recursion_depth", "merge", + "methods", "mfilename", "minus", "mislocked", + "mkdir", "mkfifo", "mkstemp", "mldivide", "mlock", + "mouse_wheel_zoom", "mpower", "mrdivide", "mtimes", + "munlock", "nargin", "nargout", + "native_float_format", "ndims", "ne", "nfields", + "nnz", "norm", "not", "numel", "nzmax", + "octave_config_info", "octave_core_file_limit", + "octave_core_file_name", + "octave_core_file_options", "ones", "or", + "output_max_field_width", "output_precision", + "page_output_immediately", "page_screen_output", + "path", "pathsep", "pause", "pclose", "permute", + "pi", "pipe", "plus", "popen", "power", + "print_empty_dimensions", "printf", + "print_struct_array_contents", "prod", + "program_invocation_name", "program_name", + "putenv", "puts", "pwd", "quit", "rats", "rdivide", + "readdir", "readlink", "read_readline_init_file", + "realmax", "realmin", "rehash", "rename", + "repelems", "re_read_readline_init_file", "reset", + "reshape", "resize", "restoredefaultpath", + "rethrow", "rmdir", "rmfield", "rmpath", "rows", + "save_header_format_string", "save_precision", + "saving_history", "scanf", "set", "setenv", + "shell_cmd", "sighup_dumps_octave_core", + "sigterm_dumps_octave_core", "silent_functions", + "single", "size", "size_equal", "sizemax", + "sizeof", "sleep", "source", "sparse_auto_mutate", + "split_long_rows", "sprintf", "squeeze", "sscanf", + "stat", "stderr", "stdin", "stdout", "strcmp", + "strcmpi", "string_fill_char", "strncmp", + "strncmpi", "struct", "struct_levels_to_print", + "strvcat", "subsasgn", "subsref", "sum", "sumsq", + "superiorto", "suppress_verbose_help_message", + "symlink", "system", "tic", "tilde_expand", + "times", "tmpfile", "tmpnam", "toc", "toupper", + "transpose", "true", "typeinfo", "umask", "uminus", + "uname", "undo_string_escapes", "unlink", "uplus", + "upper", "usage", "usleep", "vec", "vectorize", + "vertcat", "waitpid", "warning", "warranty", + "whos_line_format", "yes_or_no", "zeros", + "inf", "Inf", "nan", "NaN") + + command_kw = ("close", "load", "who", "whos") + + function_kw = ( + "accumarray", "accumdim", "acosd", "acotd", + "acscd", "addtodate", "allchild", "ancestor", + "anova", "arch_fit", "arch_rnd", "arch_test", + "area", "arma_rnd", "arrayfun", "ascii", "asctime", + "asecd", "asind", "assert", "atand", + "autoreg_matrix", "autumn", "axes", "axis", "bar", + "barh", "bartlett", "bartlett_test", "beep", + "betacdf", "betainv", "betapdf", "betarnd", + "bicgstab", "bicubic", "binary", "binocdf", + "binoinv", "binopdf", "binornd", "bitcmp", + "bitget", "bitset", "blackman", "blanks", + "blkdiag", "bone", "box", "brighten", "calendar", + "cast", "cauchy_cdf", "cauchy_inv", "cauchy_pdf", + "cauchy_rnd", "caxis", "celldisp", "center", "cgs", + "chisquare_test_homogeneity", + "chisquare_test_independence", "circshift", "cla", + "clabel", "clf", "clock", "cloglog", "closereq", + "colon", "colorbar", "colormap", "colperm", + "comet", "common_size", "commutation_matrix", + "compan", "compare_versions", "compass", + "computer", "cond", "condest", "contour", + "contourc", "contourf", "contrast", "conv", + "convhull", "cool", "copper", "copyfile", "cor", + "corrcoef", "cor_test", "cosd", "cotd", "cov", + "cplxpair", "cross", "cscd", "cstrcat", "csvread", + "csvwrite", "ctime", "cumtrapz", "curl", "cut", + "cylinder", "date", "datenum", "datestr", + "datetick", "datevec", "dblquad", "deal", + "deblank", "deconv", "delaunay", "delaunayn", + "delete", "demo", "detrend", "diffpara", "diffuse", + "dir", "discrete_cdf", "discrete_inv", + "discrete_pdf", "discrete_rnd", "display", + "divergence", "dlmwrite", "dos", "dsearch", + "dsearchn", "duplication_matrix", "durbinlevinson", + "ellipsoid", "empirical_cdf", "empirical_inv", + "empirical_pdf", "empirical_rnd", "eomday", + "errorbar", "etime", "etreeplot", "example", + "expcdf", "expinv", "expm", "exppdf", "exprnd", + "ezcontour", "ezcontourf", "ezmesh", "ezmeshc", + "ezplot", "ezpolar", "ezsurf", "ezsurfc", "factor", + "factorial", "fail", "fcdf", "feather", "fftconv", + "fftfilt", "fftshift", "figure", "fileattrib", + "fileparts", "fill", "findall", "findobj", + "findstr", "finv", "flag", "flipdim", "fliplr", + "flipud", "fpdf", "fplot", "fractdiff", "freqz", + "freqz_plot", "frnd", "fsolve", + "f_test_regression", "ftp", "fullfile", "fzero", + "gamcdf", "gaminv", "gampdf", "gamrnd", "gca", + "gcbf", "gcbo", "gcf", "genvarname", "geocdf", + "geoinv", "geopdf", "geornd", "getfield", "ginput", + "glpk", "gls", "gplot", "gradient", + "graphics_toolkit", "gray", "grid", "griddata", + "griddatan", "gtext", "gunzip", "gzip", "hadamard", + "hamming", "hankel", "hanning", "hggroup", + "hidden", "hilb", "hist", "histc", "hold", "hot", + "hotelling_test", "housh", "hsv", "hurst", + "hygecdf", "hygeinv", "hygepdf", "hygernd", + "idivide", "ifftshift", "image", "imagesc", + "imfinfo", "imread", "imshow", "imwrite", "index", + "info", "inpolygon", "inputname", "interpft", + "interpn", "intersect", "invhilb", "iqr", "isa", + "isdefinite", "isdir", "is_duplicate_entry", + "isequal", "isequalwithequalnans", "isfigure", + "ishermitian", "ishghandle", "is_leap_year", + "isletter", "ismac", "ismember", "ispc", "isprime", + "isprop", "isscalar", "issquare", "isstrprop", + "issymmetric", "isunix", "is_valid_file_id", + "isvector", "jet", "kendall", + "kolmogorov_smirnov_cdf", + "kolmogorov_smirnov_test", "kruskal_wallis_test", + "krylov", "kurtosis", "laplace_cdf", "laplace_inv", + "laplace_pdf", "laplace_rnd", "legend", "legendre", + "license", "line", "linkprop", "list_primes", + "loadaudio", "loadobj", "logistic_cdf", + "logistic_inv", "logistic_pdf", "logistic_rnd", + "logit", "loglog", "loglogerr", "logm", "logncdf", + "logninv", "lognpdf", "lognrnd", "logspace", + "lookfor", "ls_command", "lsqnonneg", "magic", + "mahalanobis", "manova", "matlabroot", + "mcnemar_test", "mean", "meansq", "median", "menu", + "mesh", "meshc", "meshgrid", "meshz", "mexext", + "mget", "mkpp", "mode", "moment", "movefile", + "mpoles", "mput", "namelengthmax", "nargchk", + "nargoutchk", "nbincdf", "nbininv", "nbinpdf", + "nbinrnd", "nchoosek", "ndgrid", "newplot", "news", + "nonzeros", "normcdf", "normest", "norminv", + "normpdf", "normrnd", "now", "nthroot", "null", + "ocean", "ols", "onenormest", "optimget", + "optimset", "orderfields", "orient", "orth", + "pack", "pareto", "parseparams", "pascal", "patch", + "pathdef", "pcg", "pchip", "pcolor", "pcr", + "peaks", "periodogram", "perl", "perms", "pie", + "pink", "planerot", "playaudio", "plot", + "plotmatrix", "plotyy", "poisscdf", "poissinv", + "poisspdf", "poissrnd", "polar", "poly", + "polyaffine", "polyarea", "polyderiv", "polyfit", + "polygcd", "polyint", "polyout", "polyreduce", + "polyval", "polyvalm", "postpad", "powerset", + "ppder", "ppint", "ppjumps", "ppplot", "ppval", + "pqpnonneg", "prepad", "primes", "print", + "print_usage", "prism", "probit", "qp", "qqplot", + "quadcc", "quadgk", "quadl", "quadv", "quiver", + "qzhess", "rainbow", "randi", "range", "rank", + "ranks", "rat", "reallog", "realpow", "realsqrt", + "record", "rectangle_lw", "rectangle_sw", + "rectint", "refresh", "refreshdata", + "regexptranslate", "repmat", "residue", "ribbon", + "rindex", "roots", "rose", "rosser", "rotdim", + "rref", "run", "run_count", "rundemos", "run_test", + "runtests", "saveas", "saveaudio", "saveobj", + "savepath", "scatter", "secd", "semilogx", + "semilogxerr", "semilogy", "semilogyerr", + "setaudio", "setdiff", "setfield", "setxor", + "shading", "shift", "shiftdim", "sign_test", + "sinc", "sind", "sinetone", "sinewave", "skewness", + "slice", "sombrero", "sortrows", "spaugment", + "spconvert", "spdiags", "spearman", "spectral_adf", + "spectral_xdf", "specular", "speed", "spencer", + "speye", "spfun", "sphere", "spinmap", "spline", + "spones", "sprand", "sprandn", "sprandsym", + "spring", "spstats", "spy", "sqp", "stairs", + "statistics", "std", "stdnormal_cdf", + "stdnormal_inv", "stdnormal_pdf", "stdnormal_rnd", + "stem", "stft", "strcat", "strchr", "strjust", + "strmatch", "strread", "strsplit", "strtok", + "strtrim", "strtrunc", "structfun", "studentize", + "subplot", "subsindex", "subspace", "substr", + "substruct", "summer", "surf", "surface", "surfc", + "surfl", "surfnorm", "svds", "swapbytes", + "sylvester_matrix", "symvar", "synthesis", "table", + "tand", "tar", "tcdf", "tempdir", "tempname", + "test", "text", "textread", "textscan", "tinv", + "title", "toeplitz", "tpdf", "trace", "trapz", + "treelayout", "treeplot", "triangle_lw", + "triangle_sw", "tril", "trimesh", "triplequad", + "triplot", "trisurf", "triu", "trnd", "tsearchn", + "t_test", "t_test_regression", "type", "unidcdf", + "unidinv", "unidpdf", "unidrnd", "unifcdf", + "unifinv", "unifpdf", "unifrnd", "union", "unique", + "unix", "unmkpp", "unpack", "untabify", "untar", + "unwrap", "unzip", "u_test", "validatestring", + "vander", "var", "var_test", "vech", "ver", + "version", "view", "voronoi", "voronoin", + "waitforbuttonpress", "wavread", "wavwrite", + "wblcdf", "wblinv", "wblpdf", "wblrnd", "weekday", + "welch_test", "what", "white", "whitebg", + "wienrnd", "wilcoxon_test", "wilkinson", "winter", + "xlabel", "xlim", "ylabel", "yulewalker", "zip", + "zlabel", "z_test") + + loadable_kw = ( + "airy", "amd", "balance", "besselh", "besseli", + "besselj", "besselk", "bessely", "bitpack", + "bsxfun", "builtin", "ccolamd", "cellfun", + "cellslices", "chol", "choldelete", "cholinsert", + "cholinv", "cholshift", "cholupdate", "colamd", + "colloc", "convhulln", "convn", "csymamd", + "cummax", "cummin", "daspk", "daspk_options", + "dasrt", "dasrt_options", "dassl", "dassl_options", + "dbclear", "dbdown", "dbstack", "dbstatus", + "dbstop", "dbtype", "dbup", "dbwhere", "det", + "dlmread", "dmperm", "dot", "eig", "eigs", + "endgrent", "endpwent", "etree", "fft", "fftn", + "fftw", "filter", "find", "full", "gcd", + "getgrent", "getgrgid", "getgrnam", "getpwent", + "getpwnam", "getpwuid", "getrusage", "givens", + "gmtime", "gnuplot_binary", "hess", "ifft", + "ifftn", "inv", "isdebugmode", "issparse", "kron", + "localtime", "lookup", "lsode", "lsode_options", + "lu", "luinc", "luupdate", "matrix_type", "max", + "min", "mktime", "pinv", "qr", "qrdelete", + "qrinsert", "qrshift", "qrupdate", "quad", + "quad_options", "qz", "rand", "rande", "randg", + "randn", "randp", "randperm", "rcond", "regexp", + "regexpi", "regexprep", "schur", "setgrent", + "setpwent", "sort", "spalloc", "sparse", "spparms", + "sprank", "sqrtm", "strfind", "strftime", + "strptime", "strrep", "svd", "svd_driver", "syl", + "symamd", "symbfact", "symrcm", "time", "tsearch", + "typecast", "urlread", "urlwrite") + + mapping_kw = ( + "abs", "acos", "acosh", "acot", "acoth", "acsc", + "acsch", "angle", "arg", "asec", "asech", "asin", + "asinh", "atan", "atanh", "beta", "betainc", + "betaln", "bincoeff", "cbrt", "ceil", "conj", "cos", + "cosh", "cot", "coth", "csc", "csch", "erf", "erfc", + "erfcx", "erfinv", "exp", "finite", "fix", "floor", + "fmod", "gamma", "gammainc", "gammaln", "imag", + "isalnum", "isalpha", "isascii", "iscntrl", + "isdigit", "isfinite", "isgraph", "isinf", + "islower", "isna", "isnan", "isprint", "ispunct", + "isspace", "isupper", "isxdigit", "lcm", "lgamma", + "log", "lower", "mod", "real", "rem", "round", + "roundb", "sec", "sech", "sign", "sin", "sinh", + "sqrt", "tan", "tanh", "toascii", "tolower", "xor") + + builtin_consts = ( + "EDITOR", "EXEC_PATH", "I", "IMAGE_PATH", "NA", + "OCTAVE_HOME", "OCTAVE_VERSION", "PAGER", + "PAGER_FLAGS", "SEEK_CUR", "SEEK_END", "SEEK_SET", + "SIG", "S_ISBLK", "S_ISCHR", "S_ISDIR", "S_ISFIFO", + "S_ISLNK", "S_ISREG", "S_ISSOCK", "WCONTINUE", + "WCOREDUMP", "WEXITSTATUS", "WIFCONTINUED", + "WIFEXITED", "WIFSIGNALED", "WIFSTOPPED", "WNOHANG", + "WSTOPSIG", "WTERMSIG", "WUNTRACED") + + tokens = { + 'root': [ + # We should look into multiline comments + (r'[%#].*$', Comment), + (r'^\s*function\b', Keyword, 'deffunc'), + + # from 'iskeyword' on hg changeset 8cc154f45e37 + (words(( + '__FILE__', '__LINE__', 'break', 'case', 'catch', 'classdef', 'continue', 'do', 'else', + 'elseif', 'end', 'end_try_catch', 'end_unwind_protect', 'endclassdef', + 'endevents', 'endfor', 'endfunction', 'endif', 'endmethods', 'endproperties', + 'endswitch', 'endwhile', 'events', 'for', 'function', 'get', 'global', 'if', 'methods', + 'otherwise', 'persistent', 'properties', 'return', 'set', 'static', 'switch', 'try', + 'until', 'unwind_protect', 'unwind_protect_cleanup', 'while'), suffix=r'\b'), + Keyword), + + (words(builtin_kw + command_kw + function_kw + loadable_kw + mapping_kw, + suffix=r'\b'), Name.Builtin), + + (words(builtin_consts, suffix=r'\b'), Name.Constant), + + # operators in Octave but not Matlab: + (r'-=|!=|!|/=|--', Operator), + # operators: + (r'-|==|~=|<|>|<=|>=|&&|&|~|\|\|?', Operator), + # operators in Octave but not Matlab requiring escape for re: + (r'\*=|\+=|\^=|\/=|\\=|\*\*|\+\+|\.\*\*', Operator), + # operators requiring escape for re: + (r'\.\*|\*|\+|\.\^|\.\\|\.\/|\/|\\', Operator), + + + # punctuation: + (r'[\[\](){}:@.,]', Punctuation), + (r'=|:|;', Punctuation), + + (r'"[^"]*"', String), + + (r'(\d+\.\d*|\d*\.\d+)([eEf][+-]?[0-9]+)?', Number.Float), + (r'\d+[eEf][+-]?[0-9]+', Number.Float), + (r'\d+', Number.Integer), + + # quote can be transpose, instead of string: + # (not great, but handles common cases...) + (r'(?<=[\w)\].])\'+', Operator), + (r'(?|<=|>=|&&|&|~|\|\|?', Operator), + # operators requiring escape for re: + (r'\.\*|\*|\+|\.\^|\.\\|\.\/|\/|\\', Operator), + + # punctuation: + (r'[\[\](){}@.,=:;]', Punctuation), + + (r'"[^"]*"', String), + + # quote can be transpose, instead of string: + # (not great, but handles common cases...) + (r'(?<=[\w)\].])\'+', Operator), + (r'(?', '->', '#', + # Modules + ':>', + } + + nonid_reserved = {'(', ')', '[', ']', '{', '}', ',', ';', '...', '_'} + + alphanumid_re = r"[a-zA-Z][\w']*" + symbolicid_re = r"[!%&$#+\-/:<=>?@\\~`^|*]+" + + # A character constant is a sequence of the form #s, where s is a string + # constant denoting a string of size one character. This setup just parses + # the entire string as either a String.Double or a String.Char (depending + # on the argument), even if the String.Char is an erronous + # multiple-character string. + def stringy(whatkind): + return [ + (r'[^"\\]', whatkind), + (r'\\[\\"abtnvfr]', String.Escape), + # Control-character notation is used for codes < 32, + # where \^@ == \000 + (r'\\\^[\x40-\x5e]', String.Escape), + # Docs say 'decimal digits' + (r'\\[0-9]{3}', String.Escape), + (r'\\u[0-9a-fA-F]{4}', String.Escape), + (r'\\\s+\\', String.Interpol), + (r'"', whatkind, '#pop'), + ] + + # Callbacks for distinguishing tokens and reserved words + def long_id_callback(self, match): + if match.group(1) in self.alphanumid_reserved: + token = Error + else: + token = Name.Namespace + yield match.start(1), token, match.group(1) + yield match.start(2), Punctuation, match.group(2) + + def end_id_callback(self, match): + if match.group(1) in self.alphanumid_reserved: + token = Error + elif match.group(1) in self.symbolicid_reserved: + token = Error + else: + token = Name + yield match.start(1), token, match.group(1) + + def id_callback(self, match): + str = match.group(1) + if str in self.alphanumid_reserved: + token = Keyword.Reserved + elif str in self.symbolicid_reserved: + token = Punctuation + else: + token = Name + yield match.start(1), token, str + + tokens = { + # Whitespace and comments are (almost) everywhere + 'whitespace': [ + (r'\s+', Text), + (r'\(\*', Comment.Multiline, 'comment'), + ], + + 'delimiters': [ + # This lexer treats these delimiters specially: + # Delimiters define scopes, and the scope is how the meaning of + # the `|' is resolved - is it a case/handle expression, or function + # definition by cases? (This is not how the Definition works, but + # it's how MLton behaves, see http://mlton.org/SMLNJDeviations) + (r'\(|\[|\{', Punctuation, 'main'), + (r'\)|\]|\}', Punctuation, '#pop'), + (r'\b(let|if|local)\b(?!\')', Keyword.Reserved, ('main', 'main')), + (r'\b(struct|sig|while)\b(?!\')', Keyword.Reserved, 'main'), + (r'\b(do|else|end|in|then)\b(?!\')', Keyword.Reserved, '#pop'), + ], + + 'core': [ + # Punctuation that doesn't overlap symbolic identifiers + (r'(%s)' % '|'.join(re.escape(z) for z in nonid_reserved), + Punctuation), + + # Special constants: strings, floats, numbers in decimal and hex + (r'#"', String.Char, 'char'), + (r'"', String.Double, 'string'), + (r'~?0x[0-9a-fA-F]+', Number.Hex), + (r'0wx[0-9a-fA-F]+', Number.Hex), + (r'0w\d+', Number.Integer), + (r'~?\d+\.\d+[eE]~?\d+', Number.Float), + (r'~?\d+\.\d+', Number.Float), + (r'~?\d+[eE]~?\d+', Number.Float), + (r'~?\d+', Number.Integer), + + # Labels + (r'#\s*[1-9][0-9]*', Name.Label), + (r'#\s*(%s)' % alphanumid_re, Name.Label), + (r'#\s+(%s)' % symbolicid_re, Name.Label), + # Some reserved words trigger a special, local lexer state change + (r'\b(datatype|abstype)\b(?!\')', Keyword.Reserved, 'dname'), + (r'(?=\b(exception)\b(?!\'))', Text, ('ename')), + (r'\b(functor|include|open|signature|structure)\b(?!\')', + Keyword.Reserved, 'sname'), + (r'\b(type|eqtype)\b(?!\')', Keyword.Reserved, 'tname'), + + # Regular identifiers, long and otherwise + (r'\'[\w\']*', Name.Decorator), + (r'(%s)(\.)' % alphanumid_re, long_id_callback, "dotted"), + (r'(%s)' % alphanumid_re, id_callback), + (r'(%s)' % symbolicid_re, id_callback), + ], + 'dotted': [ + (r'(%s)(\.)' % alphanumid_re, long_id_callback), + (r'(%s)' % alphanumid_re, end_id_callback, "#pop"), + (r'(%s)' % symbolicid_re, end_id_callback, "#pop"), + (r'\s+', Error), + (r'\S+', Error), + ], + + + # Main parser (prevents errors in files that have scoping errors) + 'root': [ + default('main') + ], + + # In this scope, I expect '|' to not be followed by a function name, + # and I expect 'and' to be followed by a binding site + 'main': [ + include('whitespace'), + + # Special behavior of val/and/fun + (r'\b(val|and)\b(?!\')', Keyword.Reserved, 'vname'), + (r'\b(fun)\b(?!\')', Keyword.Reserved, + ('#pop', 'main-fun', 'fname')), + + include('delimiters'), + include('core'), + (r'\S+', Error), + ], + + # In this scope, I expect '|' and 'and' to be followed by a function + 'main-fun': [ + include('whitespace'), + + (r'\s', Text), + (r'\(\*', Comment.Multiline, 'comment'), + + # Special behavior of val/and/fun + (r'\b(fun|and)\b(?!\')', Keyword.Reserved, 'fname'), + (r'\b(val)\b(?!\')', Keyword.Reserved, + ('#pop', 'main', 'vname')), + + # Special behavior of '|' and '|'-manipulating keywords + (r'\|', Punctuation, 'fname'), + (r'\b(case|handle)\b(?!\')', Keyword.Reserved, + ('#pop', 'main')), + + include('delimiters'), + include('core'), + (r'\S+', Error), + ], + + # Character and string parsers + 'char': stringy(String.Char), + 'string': stringy(String.Double), + + 'breakout': [ + (r'(?=\b(%s)\b(?!\'))' % '|'.join(alphanumid_reserved), Text, '#pop'), + ], + + # Dealing with what comes after module system keywords + 'sname': [ + include('whitespace'), + include('breakout'), + + (r'(%s)' % alphanumid_re, Name.Namespace), + default('#pop'), + ], + + # Dealing with what comes after the 'fun' (or 'and' or '|') keyword + 'fname': [ + include('whitespace'), + (r'\'[\w\']*', Name.Decorator), + (r'\(', Punctuation, 'tyvarseq'), + + (r'(%s)' % alphanumid_re, Name.Function, '#pop'), + (r'(%s)' % symbolicid_re, Name.Function, '#pop'), + + # Ignore interesting function declarations like "fun (x + y) = ..." + default('#pop'), + ], + + # Dealing with what comes after the 'val' (or 'and') keyword + 'vname': [ + include('whitespace'), + (r'\'[\w\']*', Name.Decorator), + (r'\(', Punctuation, 'tyvarseq'), + + (r'(%s)(\s*)(=(?!%s))' % (alphanumid_re, symbolicid_re), + bygroups(Name.Variable, Text, Punctuation), '#pop'), + (r'(%s)(\s*)(=(?!%s))' % (symbolicid_re, symbolicid_re), + bygroups(Name.Variable, Text, Punctuation), '#pop'), + (r'(%s)' % alphanumid_re, Name.Variable, '#pop'), + (r'(%s)' % symbolicid_re, Name.Variable, '#pop'), + + # Ignore interesting patterns like 'val (x, y)' + default('#pop'), + ], + + # Dealing with what comes after the 'type' (or 'and') keyword + 'tname': [ + include('whitespace'), + include('breakout'), + + (r'\'[\w\']*', Name.Decorator), + (r'\(', Punctuation, 'tyvarseq'), + (r'=(?!%s)' % symbolicid_re, Punctuation, ('#pop', 'typbind')), + + (r'(%s)' % alphanumid_re, Keyword.Type), + (r'(%s)' % symbolicid_re, Keyword.Type), + (r'\S+', Error, '#pop'), + ], + + # A type binding includes most identifiers + 'typbind': [ + include('whitespace'), + + (r'\b(and)\b(?!\')', Keyword.Reserved, ('#pop', 'tname')), + + include('breakout'), + include('core'), + (r'\S+', Error, '#pop'), + ], + + # Dealing with what comes after the 'datatype' (or 'and') keyword + 'dname': [ + include('whitespace'), + include('breakout'), + + (r'\'[\w\']*', Name.Decorator), + (r'\(', Punctuation, 'tyvarseq'), + (r'(=)(\s*)(datatype)', + bygroups(Punctuation, Text, Keyword.Reserved), '#pop'), + (r'=(?!%s)' % symbolicid_re, Punctuation, + ('#pop', 'datbind', 'datcon')), + + (r'(%s)' % alphanumid_re, Keyword.Type), + (r'(%s)' % symbolicid_re, Keyword.Type), + (r'\S+', Error, '#pop'), + ], + + # common case - A | B | C of int + 'datbind': [ + include('whitespace'), + + (r'\b(and)\b(?!\')', Keyword.Reserved, ('#pop', 'dname')), + (r'\b(withtype)\b(?!\')', Keyword.Reserved, ('#pop', 'tname')), + (r'\b(of)\b(?!\')', Keyword.Reserved), + + (r'(\|)(\s*)(%s)' % alphanumid_re, + bygroups(Punctuation, Text, Name.Class)), + (r'(\|)(\s+)(%s)' % symbolicid_re, + bygroups(Punctuation, Text, Name.Class)), + + include('breakout'), + include('core'), + (r'\S+', Error), + ], + + # Dealing with what comes after an exception + 'ename': [ + include('whitespace'), + + (r'(exception|and)\b(\s+)(%s)' % alphanumid_re, + bygroups(Keyword.Reserved, Text, Name.Class)), + (r'(exception|and)\b(\s*)(%s)' % symbolicid_re, + bygroups(Keyword.Reserved, Text, Name.Class)), + (r'\b(of)\b(?!\')', Keyword.Reserved), + + include('breakout'), + include('core'), + (r'\S+', Error), + ], + + 'datcon': [ + include('whitespace'), + (r'(%s)' % alphanumid_re, Name.Class, '#pop'), + (r'(%s)' % symbolicid_re, Name.Class, '#pop'), + (r'\S+', Error, '#pop'), + ], + + # Series of type variables + 'tyvarseq': [ + (r'\s', Text), + (r'\(\*', Comment.Multiline, 'comment'), + + (r'\'[\w\']*', Name.Decorator), + (alphanumid_re, Name), + (r',', Punctuation), + (r'\)', Punctuation, '#pop'), + (symbolicid_re, Name), + ], + + 'comment': [ + (r'[^(*)]', Comment.Multiline), + (r'\(\*', Comment.Multiline, '#push'), + (r'\*\)', Comment.Multiline, '#pop'), + (r'[(*)]', Comment.Multiline), + ], + } + + +class OcamlLexer(RegexLexer): + """ + For the OCaml language. + + .. versionadded:: 0.7 + """ + + name = 'OCaml' + aliases = ['ocaml'] + filenames = ['*.ml', '*.mli', '*.mll', '*.mly'] + mimetypes = ['text/x-ocaml'] + + keywords = ( + 'as', 'assert', 'begin', 'class', 'constraint', 'do', 'done', + 'downto', 'else', 'end', 'exception', 'external', 'false', + 'for', 'fun', 'function', 'functor', 'if', 'in', 'include', + 'inherit', 'initializer', 'lazy', 'let', 'match', 'method', + 'module', 'mutable', 'new', 'object', 'of', 'open', 'private', + 'raise', 'rec', 'sig', 'struct', 'then', 'to', 'true', 'try', + 'type', 'value', 'val', 'virtual', 'when', 'while', 'with', + ) + keyopts = ( + '!=', '#', '&', '&&', r'\(', r'\)', r'\*', r'\+', ',', '-', + r'-\.', '->', r'\.', r'\.\.', ':', '::', ':=', ':>', ';', ';;', '<', + '<-', '=', '>', '>]', r'>\}', r'\?', r'\?\?', r'\[', r'\[<', r'\[>', + r'\[\|', ']', '_', '`', r'\{', r'\{<', r'\|', r'\|]', r'\}', '~' + ) + + operators = r'[!$%&*+\./:<=>?@^|~-]' + word_operators = ('and', 'asr', 'land', 'lor', 'lsl', 'lxor', 'mod', 'or') + prefix_syms = r'[!?~]' + infix_syms = r'[=<>@^|&+\*/$%-]' + primitives = ('unit', 'int', 'float', 'bool', 'string', 'char', 'list', 'array') + + tokens = { + 'escape-sequence': [ + (r'\\[\\"\'ntbr]', String.Escape), + (r'\\[0-9]{3}', String.Escape), + (r'\\x[0-9a-fA-F]{2}', String.Escape), + ], + 'root': [ + (r'\s+', Text), + (r'false|true|\(\)|\[\]', Name.Builtin.Pseudo), + (r'\b([A-Z][\w\']*)(?=\s*\.)', Name.Namespace, 'dotted'), + (r'\b([A-Z][\w\']*)', Name.Class), + (r'\(\*(?![)])', Comment, 'comment'), + (r'\b(%s)\b' % '|'.join(keywords), Keyword), + (r'(%s)' % '|'.join(keyopts[::-1]), Operator), + (r'(%s|%s)?%s' % (infix_syms, prefix_syms, operators), Operator), + (r'\b(%s)\b' % '|'.join(word_operators), Operator.Word), + (r'\b(%s)\b' % '|'.join(primitives), Keyword.Type), + + (r"[^\W\d][\w']*", Name), + + (r'-?\d[\d_]*(.[\d_]*)?([eE][+\-]?\d[\d_]*)', Number.Float), + (r'0[xX][\da-fA-F][\da-fA-F_]*', Number.Hex), + (r'0[oO][0-7][0-7_]*', Number.Oct), + (r'0[bB][01][01_]*', Number.Bin), + (r'\d[\d_]*', Number.Integer), + + (r"'(?:(\\[\\\"'ntbr ])|(\\[0-9]{3})|(\\x[0-9a-fA-F]{2}))'", + String.Char), + (r"'.'", String.Char), + (r"'", Keyword), # a stray quote is another syntax element + + (r'"', String.Double, 'string'), + + (r'[~?][a-z][\w\']*:', Name.Variable), + ], + 'comment': [ + (r'[^(*)]+', Comment), + (r'\(\*', Comment, '#push'), + (r'\*\)', Comment, '#pop'), + (r'[(*)]', Comment), + ], + 'string': [ + (r'[^\\"]+', String.Double), + include('escape-sequence'), + (r'\\\n', String.Double), + (r'"', String.Double, '#pop'), + ], + 'dotted': [ + (r'\s+', Text), + (r'\.', Punctuation), + (r'[A-Z][\w\']*(?=\s*\.)', Name.Namespace), + (r'[A-Z][\w\']*', Name.Class, '#pop'), + (r'[a-z_][\w\']*', Name, '#pop'), + default('#pop'), + ], + } + +class OpaLexer(RegexLexer): + """ + Lexer for the Opa language (http://opalang.org). + + .. versionadded:: 1.5 + """ + + name = 'Opa' + aliases = ['opa'] + filenames = ['*.opa'] + mimetypes = ['text/x-opa'] + + # most of these aren't strictly keywords + # but if you color only real keywords, you might just + # as well not color anything + keywords = ( + 'and', 'as', 'begin', 'case', 'client', 'css', 'database', 'db', 'do', + 'else', 'end', 'external', 'forall', 'function', 'if', 'import', + 'match', 'module', 'or', 'package', 'parser', 'rec', 'server', 'then', + 'type', 'val', 'with', 'xml_parser', + ) + + # matches both stuff and `stuff` + ident_re = r'(([a-zA-Z_]\w*)|(`[^`]*`))' + + op_re = r'[.=\-<>,@~%/+?*&^!]' + punc_re = r'[()\[\],;|]' # '{' and '}' are treated elsewhere + # because they are also used for inserts + + tokens = { + # copied from the caml lexer, should be adapted + 'escape-sequence': [ + (r'\\[\\"\'ntr}]', String.Escape), + (r'\\[0-9]{3}', String.Escape), + (r'\\x[0-9a-fA-F]{2}', String.Escape), + ], + + # factorizing these rules, because they are inserted many times + 'comments': [ + (r'/\*', Comment, 'nested-comment'), + (r'//.*?$', Comment), + ], + 'comments-and-spaces': [ + include('comments'), + (r'\s+', Text), + ], + + 'root': [ + include('comments-and-spaces'), + # keywords + (words(keywords, prefix=r'\b', suffix=r'\b'), Keyword), + # directives + # we could parse the actual set of directives instead of anything + # starting with @, but this is troublesome + # because it needs to be adjusted all the time + # and assuming we parse only sources that compile, it is useless + (r'@' + ident_re + r'\b', Name.Builtin.Pseudo), + + # number literals + (r'-?.[\d]+([eE][+\-]?\d+)', Number.Float), + (r'-?\d+.\d*([eE][+\-]?\d+)', Number.Float), + (r'-?\d+[eE][+\-]?\d+', Number.Float), + (r'0[xX][\da-fA-F]+', Number.Hex), + (r'0[oO][0-7]+', Number.Oct), + (r'0[bB][01]+', Number.Bin), + (r'\d+', Number.Integer), + # color literals + (r'#[\da-fA-F]{3,6}', Number.Integer), + + # string literals + (r'"', String.Double, 'string'), + # char literal, should be checked because this is the regexp from + # the caml lexer + (r"'(?:(\\[\\\"'ntbr ])|(\\[0-9]{3})|(\\x[0-9a-fA-F]{2})|.)'", + String.Char), + + # this is meant to deal with embedded exprs in strings + # every time we find a '}' we pop a state so that if we were + # inside a string, we are back in the string state + # as a consequence, we must also push a state every time we find a + # '{' or else we will have errors when parsing {} for instance + (r'\{', Operator, '#push'), + (r'\}', Operator, '#pop'), + + # html literals + # this is a much more strict that the actual parser, + # since a])', String.Single, 'html-open-tag'), + + # db path + # matching the '[_]' in '/a[_]' because it is a part + # of the syntax of the db path definition + # unfortunately, i don't know how to match the ']' in + # /a[1], so this is somewhat inconsistent + (r'[@?!]?(/\w+)+(\[_\])?', Name.Variable), + # putting the same color on <- as on db path, since + # it can be used only to mean Db.write + (r'<-(?!'+op_re+r')', Name.Variable), + + # 'modules' + # although modules are not distinguished by their names as in caml + # the standard library seems to follow the convention that modules + # only area capitalized + (r'\b([A-Z]\w*)(?=\.)', Name.Namespace), + + # operators + # = has a special role because this is the only + # way to syntactic distinguish binding constructions + # unfortunately, this colors the equal in {x=2} too + (r'=(?!'+op_re+r')', Keyword), + (r'(%s)+' % op_re, Operator), + (r'(%s)+' % punc_re, Operator), + + # coercions + (r':', Operator, 'type'), + # type variables + # we need this rule because we don't parse specially type + # definitions so in "type t('a) = ...", "'a" is parsed by 'root' + ("'"+ident_re, Keyword.Type), + + # id literal, #something, or #{expr} + (r'#'+ident_re, String.Single), + (r'#(?=\{)', String.Single), + + # identifiers + # this avoids to color '2' in 'a2' as an integer + (ident_re, Text), + + # default, not sure if that is needed or not + # (r'.', Text), + ], + + # it is quite painful to have to parse types to know where they end + # this is the general rule for a type + # a type is either: + # * -> ty + # * type-with-slash + # * type-with-slash -> ty + # * type-with-slash (, type-with-slash)+ -> ty + # + # the code is pretty funky in here, but this code would roughly + # translate in caml to: + # let rec type stream = + # match stream with + # | [< "->"; stream >] -> type stream + # | [< ""; stream >] -> + # type_with_slash stream + # type_lhs_1 stream; + # and type_1 stream = ... + 'type': [ + include('comments-and-spaces'), + (r'->', Keyword.Type), + default(('#pop', 'type-lhs-1', 'type-with-slash')), + ], + + # parses all the atomic or closed constructions in the syntax of type + # expressions: record types, tuple types, type constructors, basic type + # and type variables + 'type-1': [ + include('comments-and-spaces'), + (r'\(', Keyword.Type, ('#pop', 'type-tuple')), + (r'~?\{', Keyword.Type, ('#pop', 'type-record')), + (ident_re+r'\(', Keyword.Type, ('#pop', 'type-tuple')), + (ident_re, Keyword.Type, '#pop'), + ("'"+ident_re, Keyword.Type), + # this case is not in the syntax but sometimes + # we think we are parsing types when in fact we are parsing + # some css, so we just pop the states until we get back into + # the root state + default('#pop'), + ], + + # type-with-slash is either: + # * type-1 + # * type-1 (/ type-1)+ + 'type-with-slash': [ + include('comments-and-spaces'), + default(('#pop', 'slash-type-1', 'type-1')), + ], + 'slash-type-1': [ + include('comments-and-spaces'), + ('/', Keyword.Type, ('#pop', 'type-1')), + # same remark as above + default('#pop'), + ], + + # we go in this state after having parsed a type-with-slash + # while trying to parse a type + # and at this point we must determine if we are parsing an arrow + # type (in which case we must continue parsing) or not (in which + # case we stop) + 'type-lhs-1': [ + include('comments-and-spaces'), + (r'->', Keyword.Type, ('#pop', 'type')), + (r'(?=,)', Keyword.Type, ('#pop', 'type-arrow')), + default('#pop'), + ], + 'type-arrow': [ + include('comments-and-spaces'), + # the look ahead here allows to parse f(x : int, y : float -> truc) + # correctly + (r',(?=[^:]*?->)', Keyword.Type, 'type-with-slash'), + (r'->', Keyword.Type, ('#pop', 'type')), + # same remark as above + default('#pop'), + ], + + # no need to do precise parsing for tuples and records + # because they are closed constructions, so we can simply + # find the closing delimiter + # note that this function would be not work if the source + # contained identifiers like `{)` (although it could be patched + # to support it) + 'type-tuple': [ + include('comments-and-spaces'), + (r'[^()/*]+', Keyword.Type), + (r'[/*]', Keyword.Type), + (r'\(', Keyword.Type, '#push'), + (r'\)', Keyword.Type, '#pop'), + ], + 'type-record': [ + include('comments-and-spaces'), + (r'[^{}/*]+', Keyword.Type), + (r'[/*]', Keyword.Type), + (r'\{', Keyword.Type, '#push'), + (r'\}', Keyword.Type, '#pop'), + ], + + # 'type-tuple': [ + # include('comments-and-spaces'), + # (r'\)', Keyword.Type, '#pop'), + # default(('#pop', 'type-tuple-1', 'type-1')), + # ], + # 'type-tuple-1': [ + # include('comments-and-spaces'), + # (r',?\s*\)', Keyword.Type, '#pop'), # ,) is a valid end of tuple, in (1,) + # (r',', Keyword.Type, 'type-1'), + # ], + # 'type-record':[ + # include('comments-and-spaces'), + # (r'\}', Keyword.Type, '#pop'), + # (r'~?(?:\w+|`[^`]*`)', Keyword.Type, 'type-record-field-expr'), + # ], + # 'type-record-field-expr': [ + # + # ], + + 'nested-comment': [ + (r'[^/*]+', Comment), + (r'/\*', Comment, '#push'), + (r'\*/', Comment, '#pop'), + (r'[/*]', Comment), + ], + + # the copy pasting between string and single-string + # is kinda sad. Is there a way to avoid that?? + 'string': [ + (r'[^\\"{]+', String.Double), + (r'"', String.Double, '#pop'), + (r'\{', Operator, 'root'), + include('escape-sequence'), + ], + 'single-string': [ + (r'[^\\\'{]+', String.Double), + (r'\'', String.Double, '#pop'), + (r'\{', Operator, 'root'), + include('escape-sequence'), + ], + + # all the html stuff + # can't really reuse some existing html parser + # because we must be able to parse embedded expressions + + # we are in this state after someone parsed the '<' that + # started the html literal + 'html-open-tag': [ + (r'[\w\-:]+', String.Single, ('#pop', 'html-attr')), + (r'>', String.Single, ('#pop', 'html-content')), + ], + + # we are in this state after someone parsed the ' is allowed + (r'[\w\-:]*>', String.Single, '#pop'), + ], + + # we are in this state after having parsed '', String.Single, '#pop'), + (r'>', String.Single, ('#pop', 'html-content')), + ], + + 'html-attr-value': [ + (r"'", String.Single, ('#pop', 'single-string')), + (r'"', String.Single, ('#pop', 'string')), + (r'#'+ident_re, String.Single, '#pop'), + (r'#(?=\{)', String.Single, ('#pop', 'root')), + (r'[^"\'{`=<>]+', String.Single, '#pop'), + (r'\{', Operator, ('#pop', 'root')), # this is a tail call! + ], + + # we should probably deal with '\' escapes here + 'html-content': [ + (r'', Comment, '#pop'), + (r'[^\-]+|-', Comment), + ], + } + + +class ReasonLexer(RegexLexer): + """ + For the ReasonML language (https://reasonml.github.io/). + + .. versionadded:: 2.6 + """ + + name = 'ReasonML' + aliases = ['reason', "reasonml"] + filenames = ['*.re', '*.rei'] + mimetypes = ['text/x-reasonml'] + + keywords = ( + 'as', 'assert', 'begin', 'class', 'constraint', 'do', 'done', 'downto', + 'else', 'end', 'exception', 'external', 'false', 'for', 'fun', 'esfun', + 'function', 'functor', 'if', 'in', 'include', 'inherit', 'initializer', 'lazy', + 'let', 'switch', 'module', 'pub', 'mutable', 'new', 'nonrec', 'object', 'of', + 'open', 'pri', 'rec', 'sig', 'struct', 'then', 'to', 'true', 'try', + 'type', 'val', 'virtual', 'when', 'while', 'with', + ) + keyopts = ( + '!=', '#', '&', '&&', r'\(', r'\)', r'\*', r'\+', ',', '-', + r'-\.', '=>', r'\.', r'\.\.', r'\.\.\.', ':', '::', ':=', ':>', ';', ';;', '<', + '<-', '=', '>', '>]', r'>\}', r'\?', r'\?\?', r'\[', r'\[<', r'\[>', + r'\[\|', ']', '_', '`', r'\{', r'\{<', r'\|', r'\|\|', r'\|]', r'\}', '~' + ) + + operators = r'[!$%&*+\./:<=>?@^|~-]' + word_operators = ('and', 'asr', 'land', 'lor', 'lsl', 'lsr', 'lxor', 'mod', 'or') + prefix_syms = r'[!?~]' + infix_syms = r'[=<>@^|&+\*/$%-]' + primitives = ('unit', 'int', 'float', 'bool', 'string', 'char', 'list', 'array') + + tokens = { + 'escape-sequence': [ + (r'\\[\\"\'ntbr]', String.Escape), + (r'\\[0-9]{3}', String.Escape), + (r'\\x[0-9a-fA-F]{2}', String.Escape), + ], + 'root': [ + (r'\s+', Text), + (r'false|true|\(\)|\[\]', Name.Builtin.Pseudo), + (r'\b([A-Z][\w\']*)(?=\s*\.)', Name.Namespace, 'dotted'), + (r'\b([A-Z][\w\']*)', Name.Class), + (r'//.*?\n', Comment.Single), + (r'\/\*(?!/)', Comment.Multiline, 'comment'), + (r'\b(%s)\b' % '|'.join(keywords), Keyword), + (r'(%s)' % '|'.join(keyopts[::-1]), Operator.Word), + (r'(%s|%s)?%s' % (infix_syms, prefix_syms, operators), Operator), + (r'\b(%s)\b' % '|'.join(word_operators), Operator.Word), + (r'\b(%s)\b' % '|'.join(primitives), Keyword.Type), + + (r"[^\W\d][\w']*", Name), + + (r'-?\d[\d_]*(.[\d_]*)?([eE][+\-]?\d[\d_]*)', Number.Float), + (r'0[xX][\da-fA-F][\da-fA-F_]*', Number.Hex), + (r'0[oO][0-7][0-7_]*', Number.Oct), + (r'0[bB][01][01_]*', Number.Bin), + (r'\d[\d_]*', Number.Integer), + + (r"'(?:(\\[\\\"'ntbr ])|(\\[0-9]{3})|(\\x[0-9a-fA-F]{2}))'", + String.Char), + (r"'.'", String.Char), + (r"'", Keyword), + + (r'"', String.Double, 'string'), + + (r'[~?][a-z][\w\']*:', Name.Variable), + ], + 'comment': [ + (r'[^/*]+', Comment.Multiline), + (r'\/\*', Comment.Multiline, '#push'), + (r'\*\/', Comment.Multiline, '#pop'), + (r'\*', Comment.Multiline), + ], + 'string': [ + (r'[^\\"]+', String.Double), + include('escape-sequence'), + (r'\\\n', String.Double), + (r'"', String.Double, '#pop'), + ], + 'dotted': [ + (r'\s+', Text), + (r'\.', Punctuation), + (r'[A-Z][\w\']*(?=\s*\.)', Name.Namespace), + (r'[A-Z][\w\']*', Name.Class, '#pop'), + (r'[a-z_][\w\']*', Name, '#pop'), + default('#pop'), + ], + } + + +class FStarLexer(RegexLexer): + """ + For the F* language (https://www.fstar-lang.org/). + .. versionadded:: 2.7 + """ + + name = 'FStar' + aliases = ['fstar'] + filenames = ['*.fst', '*.fsti'] + mimetypes = ['text/x-fstar'] + + keywords = ( + 'abstract', 'attributes', 'noeq', 'unopteq', 'and' + 'begin', 'by', 'default', 'effect', 'else', 'end', 'ensures', + 'exception', 'exists', 'false', 'forall', 'fun', 'function', 'if', + 'in', 'include', 'inline', 'inline_for_extraction', 'irreducible', + 'logic', 'match', 'module', 'mutable', 'new', 'new_effect', 'noextract', + 'of', 'open', 'opaque', 'private', 'range_of', 'reifiable', + 'reify', 'reflectable', 'requires', 'set_range_of', 'sub_effect', + 'synth', 'then', 'total', 'true', 'try', 'type', 'unfold', 'unfoldable', + 'val', 'when', 'with', 'not' + ) + decl_keywords = ('let', 'rec') + assume_keywords = ('assume', 'admit', 'assert', 'calc') + keyopts = ( + r'~', r'-', r'/\\', r'\\/', r'<:', r'<@', r'\(\|', r'\|\)', r'#', r'u#', + r'&', r'\(', r'\)', r'\(\)', r',', r'~>', r'->', r'<-', r'<--', r'<==>', + r'==>', r'\.', r'\?', r'\?\.', r'\.\[', r'\.\(', r'\.\(\|', r'\.\[\|', + r'\{:pattern', r':', r'::', r':=', r';', r';;', r'=', r'%\[', r'!\{', + r'\[', r'\[@', r'\[\|', r'\|>', r'\]', r'\|\]', r'\{', r'\|', r'\}', r'\$' + ) + + operators = r'[!$%&*+\./:<=>?@^|~-]' + prefix_syms = r'[!?~]' + infix_syms = r'[=<>@^|&+\*/$%-]' + primitives = ('unit', 'int', 'float', 'bool', 'string', 'char', 'list', 'array') + + tokens = { + 'escape-sequence': [ + (r'\\[\\"\'ntbr]', String.Escape), + (r'\\[0-9]{3}', String.Escape), + (r'\\x[0-9a-fA-F]{2}', String.Escape), + ], + 'root': [ + (r'\s+', Text), + (r'false|true|False|True|\(\)|\[\]', Name.Builtin.Pseudo), + (r'\b([A-Z][\w\']*)(?=\s*\.)', Name.Namespace, 'dotted'), + (r'\b([A-Z][\w\']*)', Name.Class), + (r'\(\*(?![)])', Comment, 'comment'), + (r'^\/\/.+$', Comment), + (r'\b(%s)\b' % '|'.join(keywords), Keyword), + (r'\b(%s)\b' % '|'.join(assume_keywords), Name.Exception), + (r'\b(%s)\b' % '|'.join(decl_keywords), Keyword.Declaration), + (r'(%s)' % '|'.join(keyopts[::-1]), Operator), + (r'(%s|%s)?%s' % (infix_syms, prefix_syms, operators), Operator), + (r'\b(%s)\b' % '|'.join(primitives), Keyword.Type), + + (r"[^\W\d][\w']*", Name), + + (r'-?\d[\d_]*(.[\d_]*)?([eE][+\-]?\d[\d_]*)', Number.Float), + (r'0[xX][\da-fA-F][\da-fA-F_]*', Number.Hex), + (r'0[oO][0-7][0-7_]*', Number.Oct), + (r'0[bB][01][01_]*', Number.Bin), + (r'\d[\d_]*', Number.Integer), + + (r"'(?:(\\[\\\"'ntbr ])|(\\[0-9]{3})|(\\x[0-9a-fA-F]{2}))'", + String.Char), + (r"'.'", String.Char), + (r"'", Keyword), # a stray quote is another syntax element + (r"\`([\w\'.]+)\`", Operator.Word), # for infix applications + (r"\`", Keyword), # for quoting + (r'"', String.Double, 'string'), + + (r'[~?][a-z][\w\']*:', Name.Variable), + ], + 'comment': [ + (r'[^(*)]+', Comment), + (r'\(\*', Comment, '#push'), + (r'\*\)', Comment, '#pop'), + (r'[(*)]', Comment), + ], + 'string': [ + (r'[^\\"]+', String.Double), + include('escape-sequence'), + (r'\\\n', String.Double), + (r'"', String.Double, '#pop'), + ], + 'dotted': [ + (r'\s+', Text), + (r'\.', Punctuation), + (r'[A-Z][\w\']*(?=\s*\.)', Name.Namespace), + (r'[A-Z][\w\']*', Name.Class, '#pop'), + (r'[a-z_][\w\']*', Name, '#pop'), + default('#pop'), + ], + } diff --git a/.venv/lib/python3.8/site-packages/pygments/lexers/modeling.py b/.venv/lib/python3.8/site-packages/pygments/lexers/modeling.py new file mode 100644 index 00000000..5a9071d6 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/pygments/lexers/modeling.py @@ -0,0 +1,366 @@ +# -*- coding: utf-8 -*- +""" + pygments.lexers.modeling + ~~~~~~~~~~~~~~~~~~~~~~~~ + + Lexers for modeling languages. + + :copyright: Copyright 2006-2020 by the Pygments team, see AUTHORS. + :license: BSD, see LICENSE for details. +""" + +import re + +from pygments.lexer import RegexLexer, include, bygroups, using, default +from pygments.token import Text, Comment, Operator, Keyword, Name, String, \ + Number, Punctuation, Whitespace + +from pygments.lexers.html import HtmlLexer +from pygments.lexers import _stan_builtins + +__all__ = ['ModelicaLexer', 'BugsLexer', 'JagsLexer', 'StanLexer'] + + +class ModelicaLexer(RegexLexer): + """ + For `Modelica `_ source code. + + .. versionadded:: 1.1 + """ + name = 'Modelica' + aliases = ['modelica'] + filenames = ['*.mo'] + mimetypes = ['text/x-modelica'] + + flags = re.DOTALL | re.MULTILINE + + _name = r"(?:'(?:[^\\']|\\.)+'|[a-zA-Z_]\w*)" + + tokens = { + 'whitespace': [ + (r'[\s\ufeff]+', Text), + (r'//[^\n]*\n?', Comment.Single), + (r'/\*.*?\*/', Comment.Multiline) + ], + 'root': [ + include('whitespace'), + (r'"', String.Double, 'string'), + (r'[()\[\]{},;]+', Punctuation), + (r'\.?[*^/+-]|\.|<>|[<>:=]=?', Operator), + (r'\d+(\.?\d*[eE][-+]?\d+|\.\d*)', Number.Float), + (r'\d+', Number.Integer), + (r'(abs|acos|actualStream|array|asin|assert|AssertionLevel|atan|' + r'atan2|backSample|Boolean|cardinality|cat|ceil|change|Clock|' + r'Connections|cos|cosh|cross|delay|diagonal|div|edge|exp|' + r'ExternalObject|fill|floor|getInstanceName|hold|homotopy|' + r'identity|inStream|integer|Integer|interval|inverse|isPresent|' + r'linspace|log|log10|matrix|max|min|mod|ndims|noClock|noEvent|' + r'ones|outerProduct|pre|previous|product|Real|reinit|rem|rooted|' + r'sample|scalar|semiLinear|shiftSample|sign|sin|sinh|size|skew|' + r'smooth|spatialDistribution|sqrt|StateSelect|String|subSample|' + r'sum|superSample|symmetric|tan|tanh|terminal|terminate|time|' + r'transpose|vector|zeros)\b', Name.Builtin), + (r'(algorithm|annotation|break|connect|constant|constrainedby|der|' + r'discrete|each|else|elseif|elsewhen|encapsulated|enumeration|' + r'equation|exit|expandable|extends|external|firstTick|final|flow|for|if|' + r'import|impure|in|initial|inner|input|interval|loop|nondiscrete|outer|' + r'output|parameter|partial|protected|public|pure|redeclare|' + r'replaceable|return|stream|then|when|while)\b', + Keyword.Reserved), + (r'(and|not|or)\b', Operator.Word), + (r'(block|class|connector|end|function|model|operator|package|' + r'record|type)\b', Keyword.Reserved, 'class'), + (r'(false|true)\b', Keyword.Constant), + (r'within\b', Keyword.Reserved, 'package-prefix'), + (_name, Name) + ], + 'class': [ + include('whitespace'), + (r'(function|record)\b', Keyword.Reserved), + (r'(if|for|when|while)\b', Keyword.Reserved, '#pop'), + (_name, Name.Class, '#pop'), + default('#pop') + ], + 'package-prefix': [ + include('whitespace'), + (_name, Name.Namespace, '#pop'), + default('#pop') + ], + 'string': [ + (r'"', String.Double, '#pop'), + (r'\\[\'"?\\abfnrtv]', String.Escape), + (r'(?i)<\s*html\s*>([^\\"]|\\.)+?(<\s*/\s*html\s*>|(?="))', + using(HtmlLexer)), + (r'<|\\?[^"\\<]+', String.Double) + ] + } + + +class BugsLexer(RegexLexer): + """ + Pygments Lexer for `OpenBugs `_ and WinBugs + models. + + .. versionadded:: 1.6 + """ + + name = 'BUGS' + aliases = ['bugs', 'winbugs', 'openbugs'] + filenames = ['*.bug'] + + _FUNCTIONS = ( + # Scalar functions + 'abs', 'arccos', 'arccosh', 'arcsin', 'arcsinh', 'arctan', 'arctanh', + 'cloglog', 'cos', 'cosh', 'cumulative', 'cut', 'density', 'deviance', + 'equals', 'expr', 'gammap', 'ilogit', 'icloglog', 'integral', 'log', + 'logfact', 'loggam', 'logit', 'max', 'min', 'phi', 'post.p.value', + 'pow', 'prior.p.value', 'probit', 'replicate.post', 'replicate.prior', + 'round', 'sin', 'sinh', 'solution', 'sqrt', 'step', 'tan', 'tanh', + 'trunc', + # Vector functions + 'inprod', 'interp.lin', 'inverse', 'logdet', 'mean', 'eigen.vals', + 'ode', 'prod', 'p.valueM', 'rank', 'ranked', 'replicate.postM', + 'sd', 'sort', 'sum', + # Special + 'D', 'I', 'F', 'T', 'C') + """ OpenBUGS built-in functions + + From http://www.openbugs.info/Manuals/ModelSpecification.html#ContentsAII + + This also includes + + - T, C, I : Truncation and censoring. + ``T`` and ``C`` are in OpenBUGS. ``I`` in WinBUGS. + - D : ODE + - F : Functional http://www.openbugs.info/Examples/Functionals.html + + """ + + _DISTRIBUTIONS = ('dbern', 'dbin', 'dcat', 'dnegbin', 'dpois', + 'dhyper', 'dbeta', 'dchisqr', 'ddexp', 'dexp', + 'dflat', 'dgamma', 'dgev', 'df', 'dggamma', 'dgpar', + 'dloglik', 'dlnorm', 'dlogis', 'dnorm', 'dpar', + 'dt', 'dunif', 'dweib', 'dmulti', 'ddirch', 'dmnorm', + 'dmt', 'dwish') + """ OpenBUGS built-in distributions + + Functions from + http://www.openbugs.info/Manuals/ModelSpecification.html#ContentsAI + """ + + tokens = { + 'whitespace': [ + (r"\s+", Text), + ], + 'comments': [ + # Comments + (r'#.*$', Comment.Single), + ], + 'root': [ + # Comments + include('comments'), + include('whitespace'), + # Block start + (r'(model)(\s+)(\{)', + bygroups(Keyword.Namespace, Text, Punctuation)), + # Reserved Words + (r'(for|in)(?![\w.])', Keyword.Reserved), + # Built-in Functions + (r'(%s)(?=\s*\()' + % r'|'.join(_FUNCTIONS + _DISTRIBUTIONS), + Name.Builtin), + # Regular variable names + (r'[A-Za-z][\w.]*', Name), + # Number Literals + (r'[-+]?[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?', Number), + # Punctuation + (r'\[|\]|\(|\)|:|,|;', Punctuation), + # Assignment operators + # SLexer makes these tokens Operators. + (r'<-|~', Operator), + # Infix and prefix operators + (r'\+|-|\*|/', Operator), + # Block + (r'[{}]', Punctuation), + ] + } + + def analyse_text(text): + if re.search(r"^\s*model\s*{", text, re.M): + return 0.7 + else: + return 0.0 + + +class JagsLexer(RegexLexer): + """ + Pygments Lexer for JAGS. + + .. versionadded:: 1.6 + """ + + name = 'JAGS' + aliases = ['jags'] + filenames = ['*.jag', '*.bug'] + + # JAGS + _FUNCTIONS = ( + 'abs', 'arccos', 'arccosh', 'arcsin', 'arcsinh', 'arctan', 'arctanh', + 'cos', 'cosh', 'cloglog', + 'equals', 'exp', 'icloglog', 'ifelse', 'ilogit', 'log', 'logfact', + 'loggam', 'logit', 'phi', 'pow', 'probit', 'round', 'sin', 'sinh', + 'sqrt', 'step', 'tan', 'tanh', 'trunc', 'inprod', 'interp.lin', + 'logdet', 'max', 'mean', 'min', 'prod', 'sum', 'sd', 'inverse', + 'rank', 'sort', 't', 'acos', 'acosh', 'asin', 'asinh', 'atan', + # Truncation/Censoring (should I include) + 'T', 'I') + # Distributions with density, probability and quartile functions + _DISTRIBUTIONS = tuple('[dpq]%s' % x for x in + ('bern', 'beta', 'dchiqsqr', 'ddexp', 'dexp', + 'df', 'gamma', 'gen.gamma', 'logis', 'lnorm', + 'negbin', 'nchisqr', 'norm', 'par', 'pois', 'weib')) + # Other distributions without density and probability + _OTHER_DISTRIBUTIONS = ( + 'dt', 'dunif', 'dbetabin', 'dbern', 'dbin', 'dcat', 'dhyper', + 'ddirch', 'dmnorm', 'dwish', 'dmt', 'dmulti', 'dbinom', 'dchisq', + 'dnbinom', 'dweibull', 'ddirich') + + tokens = { + 'whitespace': [ + (r"\s+", Text), + ], + 'names': [ + # Regular variable names + (r'[a-zA-Z][\w.]*\b', Name), + ], + 'comments': [ + # do not use stateful comments + (r'(?s)/\*.*?\*/', Comment.Multiline), + # Comments + (r'#.*$', Comment.Single), + ], + 'root': [ + # Comments + include('comments'), + include('whitespace'), + # Block start + (r'(model|data)(\s+)(\{)', + bygroups(Keyword.Namespace, Text, Punctuation)), + (r'var(?![\w.])', Keyword.Declaration), + # Reserved Words + (r'(for|in)(?![\w.])', Keyword.Reserved), + # Builtins + # Need to use lookahead because . is a valid char + (r'(%s)(?=\s*\()' % r'|'.join(_FUNCTIONS + + _DISTRIBUTIONS + + _OTHER_DISTRIBUTIONS), + Name.Builtin), + # Names + include('names'), + # Number Literals + (r'[-+]?[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?', Number), + (r'\[|\]|\(|\)|:|,|;', Punctuation), + # Assignment operators + (r'<-|~', Operator), + # # JAGS includes many more than OpenBUGS + (r'\+|-|\*|\/|\|\|[&]{2}|[<>=]=?|\^|%.*?%', Operator), + (r'[{}]', Punctuation), + ] + } + + def analyse_text(text): + if re.search(r'^\s*model\s*\{', text, re.M): + if re.search(r'^\s*data\s*\{', text, re.M): + return 0.9 + elif re.search(r'^\s*var', text, re.M): + return 0.9 + else: + return 0.3 + else: + return 0 + + +class StanLexer(RegexLexer): + """Pygments Lexer for Stan models. + + The Stan modeling language is specified in the *Stan Modeling Language + User's Guide and Reference Manual, v2.17.0*, + `pdf `__. + + .. versionadded:: 1.6 + """ + + name = 'Stan' + aliases = ['stan'] + filenames = ['*.stan'] + + tokens = { + 'whitespace': [ + (r"\s+", Text), + ], + 'comments': [ + (r'(?s)/\*.*?\*/', Comment.Multiline), + # Comments + (r'(//|#).*$', Comment.Single), + ], + 'root': [ + # Stan is more restrictive on strings than this regex + (r'"[^"]*"', String), + # Comments + include('comments'), + # block start + include('whitespace'), + # Block start + (r'(%s)(\s*)(\{)' % + r'|'.join(('functions', 'data', r'transformed\s+?data', + 'parameters', r'transformed\s+parameters', + 'model', r'generated\s+quantities')), + bygroups(Keyword.Namespace, Text, Punctuation)), + # target keyword + (r'target\s*\+=', Keyword), + # Reserved Words + (r'(%s)\b' % r'|'.join(_stan_builtins.KEYWORDS), Keyword), + # Truncation + (r'T(?=\s*\[)', Keyword), + # Data types + (r'(%s)\b' % r'|'.join(_stan_builtins.TYPES), Keyword.Type), + # < should be punctuation, but elsewhere I can't tell if it is in + # a range constraint + (r'(<)(\s*)(upper|lower)(\s*)(=)', + bygroups(Operator, Whitespace, Keyword, Whitespace, Punctuation)), + (r'(,)(\s*)(upper)(\s*)(=)', + bygroups(Punctuation, Whitespace, Keyword, Whitespace, Punctuation)), + # Punctuation + (r"[;,\[\]()]", Punctuation), + # Builtin + (r'(%s)(?=\s*\()' % '|'.join(_stan_builtins.FUNCTIONS), Name.Builtin), + (r'(~)(\s*)(%s)(?=\s*\()' % '|'.join(_stan_builtins.DISTRIBUTIONS), + bygroups(Operator, Whitespace, Name.Builtin)), + # Special names ending in __, like lp__ + (r'[A-Za-z]\w*__\b', Name.Builtin.Pseudo), + (r'(%s)\b' % r'|'.join(_stan_builtins.RESERVED), Keyword.Reserved), + # user-defined functions + (r'[A-Za-z]\w*(?=\s*\()]', Name.Function), + # Regular variable names + (r'[A-Za-z]\w*\b', Name), + # Real Literals + (r'[0-9]+(\.[0-9]*)?([eE][+-]?[0-9]+)?', Number.Float), + (r'\.[0-9]+([eE][+-]?[0-9]+)?', Number.Float), + # Integer Literals + (r'[0-9]+', Number.Integer), + # Assignment operators + (r'<-|(?:\+|-|\.?/|\.?\*|=)?=|~', Operator), + # Infix, prefix and postfix operators (and = ) + (r"\+|-|\.?\*|\.?/|\\|'|\^|!=?|<=?|>=?|\|\||&&|%|\?|:", Operator), + # Block delimiters + (r'[{}]', Punctuation), + # Distribution | + (r'\|', Punctuation) + ] + } + + def analyse_text(text): + if re.search(r'^\s*parameters\s*\{', text, re.M): + return 1.0 + else: + return 0.0 diff --git a/.venv/lib/python3.8/site-packages/pygments/lexers/modula2.py b/.venv/lib/python3.8/site-packages/pygments/lexers/modula2.py new file mode 100644 index 00000000..331b18ac --- /dev/null +++ b/.venv/lib/python3.8/site-packages/pygments/lexers/modula2.py @@ -0,0 +1,1580 @@ +# -*- coding: utf-8 -*- +""" + pygments.lexers.modula2 + ~~~~~~~~~~~~~~~~~~~~~~~ + + Multi-Dialect Lexer for Modula-2. + + :copyright: Copyright 2006-2020 by the Pygments team, see AUTHORS. + :license: BSD, see LICENSE for details. +""" + +import re + +from pygments.lexer import RegexLexer, include +from pygments.util import get_bool_opt, get_list_opt +from pygments.token import Text, Comment, Operator, Keyword, Name, \ + String, Number, Punctuation, Error + +__all__ = ['Modula2Lexer'] + + +# Multi-Dialect Modula-2 Lexer +class Modula2Lexer(RegexLexer): + """ + For `Modula-2 `_ source code. + + The Modula-2 lexer supports several dialects. By default, it operates in + fallback mode, recognising the *combined* literals, punctuation symbols + and operators of all supported dialects, and the *combined* reserved words + and builtins of PIM Modula-2, ISO Modula-2 and Modula-2 R10, while not + differentiating between library defined identifiers. + + To select a specific dialect, a dialect option may be passed + or a dialect tag may be embedded into a source file. + + Dialect Options: + + `m2pim` + Select PIM Modula-2 dialect. + `m2iso` + Select ISO Modula-2 dialect. + `m2r10` + Select Modula-2 R10 dialect. + `objm2` + Select Objective Modula-2 dialect. + + The PIM and ISO dialect options may be qualified with a language extension. + + Language Extensions: + + `+aglet` + Select Aglet Modula-2 extensions, available with m2iso. + `+gm2` + Select GNU Modula-2 extensions, available with m2pim. + `+p1` + Select p1 Modula-2 extensions, available with m2iso. + `+xds` + Select XDS Modula-2 extensions, available with m2iso. + + + Passing a Dialect Option via Unix Commandline Interface + + Dialect options may be passed to the lexer using the `dialect` key. + Only one such option should be passed. If multiple dialect options are + passed, the first valid option is used, any subsequent options are ignored. + + Examples: + + `$ pygmentize -O full,dialect=m2iso -f html -o /path/to/output /path/to/input` + Use ISO dialect to render input to HTML output + `$ pygmentize -O full,dialect=m2iso+p1 -f rtf -o /path/to/output /path/to/input` + Use ISO dialect with p1 extensions to render input to RTF output + + + Embedding a Dialect Option within a source file + + A dialect option may be embedded in a source file in form of a dialect + tag, a specially formatted comment that specifies a dialect option. + + Dialect Tag EBNF:: + + dialectTag : + OpeningCommentDelim Prefix dialectOption ClosingCommentDelim ; + + dialectOption : + 'm2pim' | 'm2iso' | 'm2r10' | 'objm2' | + 'm2iso+aglet' | 'm2pim+gm2' | 'm2iso+p1' | 'm2iso+xds' ; + + Prefix : '!' ; + + OpeningCommentDelim : '(*' ; + + ClosingCommentDelim : '*)' ; + + No whitespace is permitted between the tokens of a dialect tag. + + In the event that a source file contains multiple dialect tags, the first + tag that contains a valid dialect option will be used and any subsequent + dialect tags will be ignored. Ideally, a dialect tag should be placed + at the beginning of a source file. + + An embedded dialect tag overrides a dialect option set via command line. + + Examples: + + ``(*!m2r10*) DEFINITION MODULE Foobar; ...`` + Use Modula2 R10 dialect to render this source file. + ``(*!m2pim+gm2*) DEFINITION MODULE Bazbam; ...`` + Use PIM dialect with GNU extensions to render this source file. + + + Algol Publication Mode: + + In Algol publication mode, source text is rendered for publication of + algorithms in scientific papers and academic texts, following the format + of the Revised Algol-60 Language Report. It is activated by passing + one of two corresponding styles as an option: + + `algol` + render reserved words lowercase underline boldface + and builtins lowercase boldface italic + `algol_nu` + render reserved words lowercase boldface (no underlining) + and builtins lowercase boldface italic + + The lexer automatically performs the required lowercase conversion when + this mode is activated. + + Example: + + ``$ pygmentize -O full,style=algol -f latex -o /path/to/output /path/to/input`` + Render input file in Algol publication mode to LaTeX output. + + + Rendering Mode of First Class ADT Identifiers: + + The rendering of standard library first class ADT identifiers is controlled + by option flag "treat_stdlib_adts_as_builtins". + + When this option is turned on, standard library ADT identifiers are rendered + as builtins. When it is turned off, they are rendered as ordinary library + identifiers. + + `treat_stdlib_adts_as_builtins` (default: On) + + The option is useful for dialects that support ADTs as first class objects + and provide ADTs in the standard library that would otherwise be built-in. + + At present, only Modula-2 R10 supports library ADTs as first class objects + and therefore, no ADT identifiers are defined for any other dialects. + + Example: + + ``$ pygmentize -O full,dialect=m2r10,treat_stdlib_adts_as_builtins=Off ...`` + Render standard library ADTs as ordinary library types. + + .. versionadded:: 1.3 + + .. versionchanged:: 2.1 + Added multi-dialect support. + """ + name = 'Modula-2' + aliases = ['modula2', 'm2'] + filenames = ['*.def', '*.mod'] + mimetypes = ['text/x-modula2'] + + flags = re.MULTILINE | re.DOTALL + + tokens = { + 'whitespace': [ + (r'\n+', Text), # blank lines + (r'\s+', Text), # whitespace + ], + 'dialecttags': [ + # PIM Dialect Tag + (r'\(\*!m2pim\*\)', Comment.Special), + # ISO Dialect Tag + (r'\(\*!m2iso\*\)', Comment.Special), + # M2R10 Dialect Tag + (r'\(\*!m2r10\*\)', Comment.Special), + # ObjM2 Dialect Tag + (r'\(\*!objm2\*\)', Comment.Special), + # Aglet Extensions Dialect Tag + (r'\(\*!m2iso\+aglet\*\)', Comment.Special), + # GNU Extensions Dialect Tag + (r'\(\*!m2pim\+gm2\*\)', Comment.Special), + # p1 Extensions Dialect Tag + (r'\(\*!m2iso\+p1\*\)', Comment.Special), + # XDS Extensions Dialect Tag + (r'\(\*!m2iso\+xds\*\)', Comment.Special), + ], + 'identifiers': [ + (r'([a-zA-Z_$][\w$]*)', Name), + ], + 'prefixed_number_literals': [ + # + # Base-2, whole number + (r'0b[01]+(\'[01]+)*', Number.Bin), + # + # Base-16, whole number + (r'0[ux][0-9A-F]+(\'[0-9A-F]+)*', Number.Hex), + ], + 'plain_number_literals': [ + # + # Base-10, real number with exponent + (r'[0-9]+(\'[0-9]+)*' # integral part + r'\.[0-9]+(\'[0-9]+)*' # fractional part + r'[eE][+-]?[0-9]+(\'[0-9]+)*', # exponent + Number.Float), + # + # Base-10, real number without exponent + (r'[0-9]+(\'[0-9]+)*' # integral part + r'\.[0-9]+(\'[0-9]+)*', # fractional part + Number.Float), + # + # Base-10, whole number + (r'[0-9]+(\'[0-9]+)*', Number.Integer), + ], + 'suffixed_number_literals': [ + # + # Base-8, whole number + (r'[0-7]+B', Number.Oct), + # + # Base-8, character code + (r'[0-7]+C', Number.Oct), + # + # Base-16, number + (r'[0-9A-F]+H', Number.Hex), + ], + 'string_literals': [ + (r"'(\\\\|\\'|[^'])*'", String), # single quoted string + (r'"(\\\\|\\"|[^"])*"', String), # double quoted string + ], + 'digraph_operators': [ + # Dot Product Operator + (r'\*\.', Operator), + # Array Concatenation Operator + (r'\+>', Operator), # M2R10 + ObjM2 + # Inequality Operator + (r'<>', Operator), # ISO + PIM + # Less-Or-Equal, Subset + (r'<=', Operator), + # Greater-Or-Equal, Superset + (r'>=', Operator), + # Identity Operator + (r'==', Operator), # M2R10 + ObjM2 + # Type Conversion Operator + (r'::', Operator), # M2R10 + ObjM2 + # Assignment Symbol + (r':=', Operator), + # Postfix Increment Mutator + (r'\+\+', Operator), # M2R10 + ObjM2 + # Postfix Decrement Mutator + (r'--', Operator), # M2R10 + ObjM2 + ], + 'unigraph_operators': [ + # Arithmetic Operators + (r'[+-]', Operator), + (r'[*/]', Operator), + # ISO 80000-2 compliant Set Difference Operator + (r'\\', Operator), # M2R10 + ObjM2 + # Relational Operators + (r'[=#<>]', Operator), + # Dereferencing Operator + (r'\^', Operator), + # Dereferencing Operator Synonym + (r'@', Operator), # ISO + # Logical AND Operator Synonym + (r'&', Operator), # PIM + ISO + # Logical NOT Operator Synonym + (r'~', Operator), # PIM + ISO + # Smalltalk Message Prefix + (r'`', Operator), # ObjM2 + ], + 'digraph_punctuation': [ + # Range Constructor + (r'\.\.', Punctuation), + # Opening Chevron Bracket + (r'<<', Punctuation), # M2R10 + ISO + # Closing Chevron Bracket + (r'>>', Punctuation), # M2R10 + ISO + # Blueprint Punctuation + (r'->', Punctuation), # M2R10 + ISO + # Distinguish |# and # in M2 R10 + (r'\|#', Punctuation), + # Distinguish ## and # in M2 R10 + (r'##', Punctuation), + # Distinguish |* and * in M2 R10 + (r'\|\*', Punctuation), + ], + 'unigraph_punctuation': [ + # Common Punctuation + (r'[()\[\]{},.:;|]', Punctuation), + # Case Label Separator Synonym + (r'!', Punctuation), # ISO + # Blueprint Punctuation + (r'\?', Punctuation), # M2R10 + ObjM2 + ], + 'comments': [ + # Single Line Comment + (r'^//.*?\n', Comment.Single), # M2R10 + ObjM2 + # Block Comment + (r'\(\*([^$].*?)\*\)', Comment.Multiline), + # Template Block Comment + (r'/\*(.*?)\*/', Comment.Multiline), # M2R10 + ObjM2 + ], + 'pragmas': [ + # ISO Style Pragmas + (r'<\*.*?\*>', Comment.Preproc), # ISO, M2R10 + ObjM2 + # Pascal Style Pragmas + (r'\(\*\$.*?\*\)', Comment.Preproc), # PIM + ], + 'root': [ + include('whitespace'), + include('dialecttags'), + include('pragmas'), + include('comments'), + include('identifiers'), + include('suffixed_number_literals'), # PIM + ISO + include('prefixed_number_literals'), # M2R10 + ObjM2 + include('plain_number_literals'), + include('string_literals'), + include('digraph_punctuation'), + include('digraph_operators'), + include('unigraph_punctuation'), + include('unigraph_operators'), + ] + } + +# C o m m o n D a t a s e t s + + # Common Reserved Words Dataset + common_reserved_words = ( + # 37 common reserved words + 'AND', 'ARRAY', 'BEGIN', 'BY', 'CASE', 'CONST', 'DEFINITION', 'DIV', + 'DO', 'ELSE', 'ELSIF', 'END', 'EXIT', 'FOR', 'FROM', 'IF', + 'IMPLEMENTATION', 'IMPORT', 'IN', 'LOOP', 'MOD', 'MODULE', 'NOT', + 'OF', 'OR', 'POINTER', 'PROCEDURE', 'RECORD', 'REPEAT', 'RETURN', + 'SET', 'THEN', 'TO', 'TYPE', 'UNTIL', 'VAR', 'WHILE', + ) + + # Common Builtins Dataset + common_builtins = ( + # 16 common builtins + 'ABS', 'BOOLEAN', 'CARDINAL', 'CHAR', 'CHR', 'FALSE', 'INTEGER', + 'LONGINT', 'LONGREAL', 'MAX', 'MIN', 'NIL', 'ODD', 'ORD', 'REAL', + 'TRUE', + ) + + # Common Pseudo-Module Builtins Dataset + common_pseudo_builtins = ( + # 4 common pseudo builtins + 'ADDRESS', 'BYTE', 'WORD', 'ADR' + ) + +# P I M M o d u l a - 2 D a t a s e t s + + # Lexemes to Mark as Error Tokens for PIM Modula-2 + pim_lexemes_to_reject = ( + '!', '`', '@', '$', '%', '?', '\\', '==', '++', '--', '::', '*.', + '+>', '->', '<<', '>>', '|#', '##', + ) + + # PIM Modula-2 Additional Reserved Words Dataset + pim_additional_reserved_words = ( + # 3 additional reserved words + 'EXPORT', 'QUALIFIED', 'WITH', + ) + + # PIM Modula-2 Additional Builtins Dataset + pim_additional_builtins = ( + # 16 additional builtins + 'BITSET', 'CAP', 'DEC', 'DISPOSE', 'EXCL', 'FLOAT', 'HALT', 'HIGH', + 'INC', 'INCL', 'NEW', 'NIL', 'PROC', 'SIZE', 'TRUNC', 'VAL', + ) + + # PIM Modula-2 Additional Pseudo-Module Builtins Dataset + pim_additional_pseudo_builtins = ( + # 5 additional pseudo builtins + 'SYSTEM', 'PROCESS', 'TSIZE', 'NEWPROCESS', 'TRANSFER', + ) + +# I S O M o d u l a - 2 D a t a s e t s + + # Lexemes to Mark as Error Tokens for ISO Modula-2 + iso_lexemes_to_reject = ( + '`', '$', '%', '?', '\\', '==', '++', '--', '::', '*.', '+>', '->', + '<<', '>>', '|#', '##', + ) + + # ISO Modula-2 Additional Reserved Words Dataset + iso_additional_reserved_words = ( + # 9 additional reserved words (ISO 10514-1) + 'EXCEPT', 'EXPORT', 'FINALLY', 'FORWARD', 'PACKEDSET', 'QUALIFIED', + 'REM', 'RETRY', 'WITH', + # 10 additional reserved words (ISO 10514-2 & ISO 10514-3) + 'ABSTRACT', 'AS', 'CLASS', 'GUARD', 'INHERIT', 'OVERRIDE', 'READONLY', + 'REVEAL', 'TRACED', 'UNSAFEGUARDED', + ) + + # ISO Modula-2 Additional Builtins Dataset + iso_additional_builtins = ( + # 26 additional builtins (ISO 10514-1) + 'BITSET', 'CAP', 'CMPLX', 'COMPLEX', 'DEC', 'DISPOSE', 'EXCL', 'FLOAT', + 'HALT', 'HIGH', 'IM', 'INC', 'INCL', 'INT', 'INTERRUPTIBLE', 'LENGTH', + 'LFLOAT', 'LONGCOMPLEX', 'NEW', 'PROC', 'PROTECTION', 'RE', 'SIZE', + 'TRUNC', 'UNINTERRUBTIBLE', 'VAL', + # 5 additional builtins (ISO 10514-2 & ISO 10514-3) + 'CREATE', 'DESTROY', 'EMPTY', 'ISMEMBER', 'SELF', + ) + + # ISO Modula-2 Additional Pseudo-Module Builtins Dataset + iso_additional_pseudo_builtins = ( + # 14 additional builtins (SYSTEM) + 'SYSTEM', 'BITSPERLOC', 'LOCSPERBYTE', 'LOCSPERWORD', 'LOC', + 'ADDADR', 'SUBADR', 'DIFADR', 'MAKEADR', 'ADR', + 'ROTATE', 'SHIFT', 'CAST', 'TSIZE', + # 13 additional builtins (COROUTINES) + 'COROUTINES', 'ATTACH', 'COROUTINE', 'CURRENT', 'DETACH', 'HANDLER', + 'INTERRUPTSOURCE', 'IOTRANSFER', 'IsATTACHED', 'LISTEN', + 'NEWCOROUTINE', 'PROT', 'TRANSFER', + # 9 additional builtins (EXCEPTIONS) + 'EXCEPTIONS', 'AllocateSource', 'CurrentNumber', 'ExceptionNumber', + 'ExceptionSource', 'GetMessage', 'IsCurrentSource', + 'IsExceptionalExecution', 'RAISE', + # 3 additional builtins (TERMINATION) + 'TERMINATION', 'IsTerminating', 'HasHalted', + # 4 additional builtins (M2EXCEPTION) + 'M2EXCEPTION', 'M2Exceptions', 'M2Exception', 'IsM2Exception', + 'indexException', 'rangeException', 'caseSelectException', + 'invalidLocation', 'functionException', 'wholeValueException', + 'wholeDivException', 'realValueException', 'realDivException', + 'complexValueException', 'complexDivException', 'protException', + 'sysException', 'coException', 'exException', + ) + +# M o d u l a - 2 R 1 0 D a t a s e t s + + # Lexemes to Mark as Error Tokens for Modula-2 R10 + m2r10_lexemes_to_reject = ( + '!', '`', '@', '$', '%', '&', '<>', + ) + + # Modula-2 R10 reserved words in addition to the common set + m2r10_additional_reserved_words = ( + # 12 additional reserved words + 'ALIAS', 'ARGLIST', 'BLUEPRINT', 'COPY', 'GENLIB', 'INDETERMINATE', + 'NEW', 'NONE', 'OPAQUE', 'REFERENTIAL', 'RELEASE', 'RETAIN', + # 2 additional reserved words with symbolic assembly option + 'ASM', 'REG', + ) + + # Modula-2 R10 builtins in addition to the common set + m2r10_additional_builtins = ( + # 26 additional builtins + 'CARDINAL', 'COUNT', 'EMPTY', 'EXISTS', 'INSERT', 'LENGTH', 'LONGCARD', + 'OCTET', 'PTR', 'PRED', 'READ', 'READNEW', 'REMOVE', 'RETRIEVE', 'SORT', + 'STORE', 'SUBSET', 'SUCC', 'TLIMIT', 'TMAX', 'TMIN', 'TRUE', 'TSIZE', + 'UNICHAR', 'WRITE', 'WRITEF', + ) + + # Modula-2 R10 Additional Pseudo-Module Builtins Dataset + m2r10_additional_pseudo_builtins = ( + # 13 additional builtins (TPROPERTIES) + 'TPROPERTIES', 'PROPERTY', 'LITERAL', 'TPROPERTY', 'TLITERAL', + 'TBUILTIN', 'TDYN', 'TREFC', 'TNIL', 'TBASE', 'TPRECISION', + 'TMAXEXP', 'TMINEXP', + # 4 additional builtins (CONVERSION) + 'CONVERSION', 'TSXFSIZE', 'SXF', 'VAL', + # 35 additional builtins (UNSAFE) + 'UNSAFE', 'CAST', 'INTRINSIC', 'AVAIL', 'ADD', 'SUB', 'ADDC', 'SUBC', + 'FETCHADD', 'FETCHSUB', 'SHL', 'SHR', 'ASHR', 'ROTL', 'ROTR', 'ROTLC', + 'ROTRC', 'BWNOT', 'BWAND', 'BWOR', 'BWXOR', 'BWNAND', 'BWNOR', + 'SETBIT', 'TESTBIT', 'LSBIT', 'MSBIT', 'CSBITS', 'BAIL', 'HALT', + 'TODO', 'FFI', 'ADDR', 'VARGLIST', 'VARGC', + # 11 additional builtins (ATOMIC) + 'ATOMIC', 'INTRINSIC', 'AVAIL', 'SWAP', 'CAS', 'INC', 'DEC', 'BWAND', + 'BWNAND', 'BWOR', 'BWXOR', + # 7 additional builtins (COMPILER) + 'COMPILER', 'DEBUG', 'MODNAME', 'PROCNAME', 'LINENUM', 'DEFAULT', + 'HASH', + # 5 additional builtins (ASSEMBLER) + 'ASSEMBLER', 'REGISTER', 'SETREG', 'GETREG', 'CODE', + ) + +# O b j e c t i v e M o d u l a - 2 D a t a s e t s + + # Lexemes to Mark as Error Tokens for Objective Modula-2 + objm2_lexemes_to_reject = ( + '!', '$', '%', '&', '<>', + ) + + # Objective Modula-2 Extensions + # reserved words in addition to Modula-2 R10 + objm2_additional_reserved_words = ( + # 16 additional reserved words + 'BYCOPY', 'BYREF', 'CLASS', 'CONTINUE', 'CRITICAL', 'INOUT', 'METHOD', + 'ON', 'OPTIONAL', 'OUT', 'PRIVATE', 'PROTECTED', 'PROTOCOL', 'PUBLIC', + 'SUPER', 'TRY', + ) + + # Objective Modula-2 Extensions + # builtins in addition to Modula-2 R10 + objm2_additional_builtins = ( + # 3 additional builtins + 'OBJECT', 'NO', 'YES', + ) + + # Objective Modula-2 Extensions + # pseudo-module builtins in addition to Modula-2 R10 + objm2_additional_pseudo_builtins = ( + # None + ) + +# A g l e t M o d u l a - 2 D a t a s e t s + + # Aglet Extensions + # reserved words in addition to ISO Modula-2 + aglet_additional_reserved_words = ( + # None + ) + + # Aglet Extensions + # builtins in addition to ISO Modula-2 + aglet_additional_builtins = ( + # 9 additional builtins + 'BITSET8', 'BITSET16', 'BITSET32', 'CARDINAL8', 'CARDINAL16', + 'CARDINAL32', 'INTEGER8', 'INTEGER16', 'INTEGER32', + ) + + # Aglet Modula-2 Extensions + # pseudo-module builtins in addition to ISO Modula-2 + aglet_additional_pseudo_builtins = ( + # None + ) + +# G N U M o d u l a - 2 D a t a s e t s + + # GNU Extensions + # reserved words in addition to PIM Modula-2 + gm2_additional_reserved_words = ( + # 10 additional reserved words + 'ASM', '__ATTRIBUTE__', '__BUILTIN__', '__COLUMN__', '__DATE__', + '__FILE__', '__FUNCTION__', '__LINE__', '__MODULE__', 'VOLATILE', + ) + + # GNU Extensions + # builtins in addition to PIM Modula-2 + gm2_additional_builtins = ( + # 21 additional builtins + 'BITSET8', 'BITSET16', 'BITSET32', 'CARDINAL8', 'CARDINAL16', + 'CARDINAL32', 'CARDINAL64', 'COMPLEX32', 'COMPLEX64', 'COMPLEX96', + 'COMPLEX128', 'INTEGER8', 'INTEGER16', 'INTEGER32', 'INTEGER64', + 'REAL8', 'REAL16', 'REAL32', 'REAL96', 'REAL128', 'THROW', + ) + + # GNU Extensions + # pseudo-module builtins in addition to PIM Modula-2 + gm2_additional_pseudo_builtins = ( + # None + ) + +# p 1 M o d u l a - 2 D a t a s e t s + + # p1 Extensions + # reserved words in addition to ISO Modula-2 + p1_additional_reserved_words = ( + # None + ) + + # p1 Extensions + # builtins in addition to ISO Modula-2 + p1_additional_builtins = ( + # None + ) + + # p1 Modula-2 Extensions + # pseudo-module builtins in addition to ISO Modula-2 + p1_additional_pseudo_builtins = ( + # 1 additional builtin + 'BCD', + ) + +# X D S M o d u l a - 2 D a t a s e t s + + # XDS Extensions + # reserved words in addition to ISO Modula-2 + xds_additional_reserved_words = ( + # 1 additional reserved word + 'SEQ', + ) + + # XDS Extensions + # builtins in addition to ISO Modula-2 + xds_additional_builtins = ( + # 9 additional builtins + 'ASH', 'ASSERT', 'DIFFADR_TYPE', 'ENTIER', 'INDEX', 'LEN', + 'LONGCARD', 'SHORTCARD', 'SHORTINT', + ) + + # XDS Modula-2 Extensions + # pseudo-module builtins in addition to ISO Modula-2 + xds_additional_pseudo_builtins = ( + # 22 additional builtins (SYSTEM) + 'PROCESS', 'NEWPROCESS', 'BOOL8', 'BOOL16', 'BOOL32', 'CARD8', + 'CARD16', 'CARD32', 'INT8', 'INT16', 'INT32', 'REF', 'MOVE', + 'FILL', 'GET', 'PUT', 'CC', 'int', 'unsigned', 'size_t', 'void' + # 3 additional builtins (COMPILER) + 'COMPILER', 'OPTION', 'EQUATION' + ) + +# P I M S t a n d a r d L i b r a r y D a t a s e t s + + # PIM Modula-2 Standard Library Modules Dataset + pim_stdlib_module_identifiers = ( + 'Terminal', 'FileSystem', 'InOut', 'RealInOut', 'MathLib0', 'Storage', + ) + + # PIM Modula-2 Standard Library Types Dataset + pim_stdlib_type_identifiers = ( + 'Flag', 'FlagSet', 'Response', 'Command', 'Lock', 'Permission', + 'MediumType', 'File', 'FileProc', 'DirectoryProc', 'FileCommand', + 'DirectoryCommand', + ) + + # PIM Modula-2 Standard Library Procedures Dataset + pim_stdlib_proc_identifiers = ( + 'Read', 'BusyRead', 'ReadAgain', 'Write', 'WriteString', 'WriteLn', + 'Create', 'Lookup', 'Close', 'Delete', 'Rename', 'SetRead', 'SetWrite', + 'SetModify', 'SetOpen', 'Doio', 'SetPos', 'GetPos', 'Length', 'Reset', + 'Again', 'ReadWord', 'WriteWord', 'ReadChar', 'WriteChar', + 'CreateMedium', 'DeleteMedium', 'AssignName', 'DeassignName', + 'ReadMedium', 'LookupMedium', 'OpenInput', 'OpenOutput', 'CloseInput', + 'CloseOutput', 'ReadString', 'ReadInt', 'ReadCard', 'ReadWrd', + 'WriteInt', 'WriteCard', 'WriteOct', 'WriteHex', 'WriteWrd', + 'ReadReal', 'WriteReal', 'WriteFixPt', 'WriteRealOct', 'sqrt', 'exp', + 'ln', 'sin', 'cos', 'arctan', 'entier', 'ALLOCATE', 'DEALLOCATE', + ) + + # PIM Modula-2 Standard Library Variables Dataset + pim_stdlib_var_identifiers = ( + 'Done', 'termCH', 'in', 'out' + ) + + # PIM Modula-2 Standard Library Constants Dataset + pim_stdlib_const_identifiers = ( + 'EOL', + ) + +# I S O S t a n d a r d L i b r a r y D a t a s e t s + + # ISO Modula-2 Standard Library Modules Dataset + iso_stdlib_module_identifiers = ( + # TO DO + ) + + # ISO Modula-2 Standard Library Types Dataset + iso_stdlib_type_identifiers = ( + # TO DO + ) + + # ISO Modula-2 Standard Library Procedures Dataset + iso_stdlib_proc_identifiers = ( + # TO DO + ) + + # ISO Modula-2 Standard Library Variables Dataset + iso_stdlib_var_identifiers = ( + # TO DO + ) + + # ISO Modula-2 Standard Library Constants Dataset + iso_stdlib_const_identifiers = ( + # TO DO + ) + +# M 2 R 1 0 S t a n d a r d L i b r a r y D a t a s e t s + + # Modula-2 R10 Standard Library ADTs Dataset + m2r10_stdlib_adt_identifiers = ( + 'BCD', 'LONGBCD', 'BITSET', 'SHORTBITSET', 'LONGBITSET', + 'LONGLONGBITSET', 'COMPLEX', 'LONGCOMPLEX', 'SHORTCARD', 'LONGLONGCARD', + 'SHORTINT', 'LONGLONGINT', 'POSINT', 'SHORTPOSINT', 'LONGPOSINT', + 'LONGLONGPOSINT', 'BITSET8', 'BITSET16', 'BITSET32', 'BITSET64', + 'BITSET128', 'BS8', 'BS16', 'BS32', 'BS64', 'BS128', 'CARDINAL8', + 'CARDINAL16', 'CARDINAL32', 'CARDINAL64', 'CARDINAL128', 'CARD8', + 'CARD16', 'CARD32', 'CARD64', 'CARD128', 'INTEGER8', 'INTEGER16', + 'INTEGER32', 'INTEGER64', 'INTEGER128', 'INT8', 'INT16', 'INT32', + 'INT64', 'INT128', 'STRING', 'UNISTRING', + ) + + # Modula-2 R10 Standard Library Blueprints Dataset + m2r10_stdlib_blueprint_identifiers = ( + 'ProtoRoot', 'ProtoComputational', 'ProtoNumeric', 'ProtoScalar', + 'ProtoNonScalar', 'ProtoCardinal', 'ProtoInteger', 'ProtoReal', + 'ProtoComplex', 'ProtoVector', 'ProtoTuple', 'ProtoCompArray', + 'ProtoCollection', 'ProtoStaticArray', 'ProtoStaticSet', + 'ProtoStaticString', 'ProtoArray', 'ProtoString', 'ProtoSet', + 'ProtoMultiSet', 'ProtoDictionary', 'ProtoMultiDict', 'ProtoExtension', + 'ProtoIO', 'ProtoCardMath', 'ProtoIntMath', 'ProtoRealMath', + ) + + # Modula-2 R10 Standard Library Modules Dataset + m2r10_stdlib_module_identifiers = ( + 'ASCII', 'BooleanIO', 'CharIO', 'UnicharIO', 'OctetIO', + 'CardinalIO', 'LongCardIO', 'IntegerIO', 'LongIntIO', 'RealIO', + 'LongRealIO', 'BCDIO', 'LongBCDIO', 'CardMath', 'LongCardMath', + 'IntMath', 'LongIntMath', 'RealMath', 'LongRealMath', 'BCDMath', + 'LongBCDMath', 'FileIO', 'FileSystem', 'Storage', 'IOSupport', + ) + + # Modula-2 R10 Standard Library Types Dataset + m2r10_stdlib_type_identifiers = ( + 'File', 'Status', + # TO BE COMPLETED + ) + + # Modula-2 R10 Standard Library Procedures Dataset + m2r10_stdlib_proc_identifiers = ( + 'ALLOCATE', 'DEALLOCATE', 'SIZE', + # TO BE COMPLETED + ) + + # Modula-2 R10 Standard Library Variables Dataset + m2r10_stdlib_var_identifiers = ( + 'stdIn', 'stdOut', 'stdErr', + ) + + # Modula-2 R10 Standard Library Constants Dataset + m2r10_stdlib_const_identifiers = ( + 'pi', 'tau', + ) + +# D i a l e c t s + + # Dialect modes + dialects = ( + 'unknown', + 'm2pim', 'm2iso', 'm2r10', 'objm2', + 'm2iso+aglet', 'm2pim+gm2', 'm2iso+p1', 'm2iso+xds', + ) + +# D a t a b a s e s + + # Lexemes to Mark as Errors Database + lexemes_to_reject_db = { + # Lexemes to reject for unknown dialect + 'unknown': ( + # LEAVE THIS EMPTY + ), + # Lexemes to reject for PIM Modula-2 + 'm2pim': ( + pim_lexemes_to_reject, + ), + # Lexemes to reject for ISO Modula-2 + 'm2iso': ( + iso_lexemes_to_reject, + ), + # Lexemes to reject for Modula-2 R10 + 'm2r10': ( + m2r10_lexemes_to_reject, + ), + # Lexemes to reject for Objective Modula-2 + 'objm2': ( + objm2_lexemes_to_reject, + ), + # Lexemes to reject for Aglet Modula-2 + 'm2iso+aglet': ( + iso_lexemes_to_reject, + ), + # Lexemes to reject for GNU Modula-2 + 'm2pim+gm2': ( + pim_lexemes_to_reject, + ), + # Lexemes to reject for p1 Modula-2 + 'm2iso+p1': ( + iso_lexemes_to_reject, + ), + # Lexemes to reject for XDS Modula-2 + 'm2iso+xds': ( + iso_lexemes_to_reject, + ), + } + + # Reserved Words Database + reserved_words_db = { + # Reserved words for unknown dialect + 'unknown': ( + common_reserved_words, + pim_additional_reserved_words, + iso_additional_reserved_words, + m2r10_additional_reserved_words, + ), + + # Reserved words for PIM Modula-2 + 'm2pim': ( + common_reserved_words, + pim_additional_reserved_words, + ), + + # Reserved words for Modula-2 R10 + 'm2iso': ( + common_reserved_words, + iso_additional_reserved_words, + ), + + # Reserved words for ISO Modula-2 + 'm2r10': ( + common_reserved_words, + m2r10_additional_reserved_words, + ), + + # Reserved words for Objective Modula-2 + 'objm2': ( + common_reserved_words, + m2r10_additional_reserved_words, + objm2_additional_reserved_words, + ), + + # Reserved words for Aglet Modula-2 Extensions + 'm2iso+aglet': ( + common_reserved_words, + iso_additional_reserved_words, + aglet_additional_reserved_words, + ), + + # Reserved words for GNU Modula-2 Extensions + 'm2pim+gm2': ( + common_reserved_words, + pim_additional_reserved_words, + gm2_additional_reserved_words, + ), + + # Reserved words for p1 Modula-2 Extensions + 'm2iso+p1': ( + common_reserved_words, + iso_additional_reserved_words, + p1_additional_reserved_words, + ), + + # Reserved words for XDS Modula-2 Extensions + 'm2iso+xds': ( + common_reserved_words, + iso_additional_reserved_words, + xds_additional_reserved_words, + ), + } + + # Builtins Database + builtins_db = { + # Builtins for unknown dialect + 'unknown': ( + common_builtins, + pim_additional_builtins, + iso_additional_builtins, + m2r10_additional_builtins, + ), + + # Builtins for PIM Modula-2 + 'm2pim': ( + common_builtins, + pim_additional_builtins, + ), + + # Builtins for ISO Modula-2 + 'm2iso': ( + common_builtins, + iso_additional_builtins, + ), + + # Builtins for ISO Modula-2 + 'm2r10': ( + common_builtins, + m2r10_additional_builtins, + ), + + # Builtins for Objective Modula-2 + 'objm2': ( + common_builtins, + m2r10_additional_builtins, + objm2_additional_builtins, + ), + + # Builtins for Aglet Modula-2 Extensions + 'm2iso+aglet': ( + common_builtins, + iso_additional_builtins, + aglet_additional_builtins, + ), + + # Builtins for GNU Modula-2 Extensions + 'm2pim+gm2': ( + common_builtins, + pim_additional_builtins, + gm2_additional_builtins, + ), + + # Builtins for p1 Modula-2 Extensions + 'm2iso+p1': ( + common_builtins, + iso_additional_builtins, + p1_additional_builtins, + ), + + # Builtins for XDS Modula-2 Extensions + 'm2iso+xds': ( + common_builtins, + iso_additional_builtins, + xds_additional_builtins, + ), + } + + # Pseudo-Module Builtins Database + pseudo_builtins_db = { + # Builtins for unknown dialect + 'unknown': ( + common_pseudo_builtins, + pim_additional_pseudo_builtins, + iso_additional_pseudo_builtins, + m2r10_additional_pseudo_builtins, + ), + + # Builtins for PIM Modula-2 + 'm2pim': ( + common_pseudo_builtins, + pim_additional_pseudo_builtins, + ), + + # Builtins for ISO Modula-2 + 'm2iso': ( + common_pseudo_builtins, + iso_additional_pseudo_builtins, + ), + + # Builtins for ISO Modula-2 + 'm2r10': ( + common_pseudo_builtins, + m2r10_additional_pseudo_builtins, + ), + + # Builtins for Objective Modula-2 + 'objm2': ( + common_pseudo_builtins, + m2r10_additional_pseudo_builtins, + objm2_additional_pseudo_builtins, + ), + + # Builtins for Aglet Modula-2 Extensions + 'm2iso+aglet': ( + common_pseudo_builtins, + iso_additional_pseudo_builtins, + aglet_additional_pseudo_builtins, + ), + + # Builtins for GNU Modula-2 Extensions + 'm2pim+gm2': ( + common_pseudo_builtins, + pim_additional_pseudo_builtins, + gm2_additional_pseudo_builtins, + ), + + # Builtins for p1 Modula-2 Extensions + 'm2iso+p1': ( + common_pseudo_builtins, + iso_additional_pseudo_builtins, + p1_additional_pseudo_builtins, + ), + + # Builtins for XDS Modula-2 Extensions + 'm2iso+xds': ( + common_pseudo_builtins, + iso_additional_pseudo_builtins, + xds_additional_pseudo_builtins, + ), + } + + # Standard Library ADTs Database + stdlib_adts_db = { + # Empty entry for unknown dialect + 'unknown': ( + # LEAVE THIS EMPTY + ), + # Standard Library ADTs for PIM Modula-2 + 'm2pim': ( + # No first class library types + ), + + # Standard Library ADTs for ISO Modula-2 + 'm2iso': ( + # No first class library types + ), + + # Standard Library ADTs for Modula-2 R10 + 'm2r10': ( + m2r10_stdlib_adt_identifiers, + ), + + # Standard Library ADTs for Objective Modula-2 + 'objm2': ( + m2r10_stdlib_adt_identifiers, + ), + + # Standard Library ADTs for Aglet Modula-2 + 'm2iso+aglet': ( + # No first class library types + ), + + # Standard Library ADTs for GNU Modula-2 + 'm2pim+gm2': ( + # No first class library types + ), + + # Standard Library ADTs for p1 Modula-2 + 'm2iso+p1': ( + # No first class library types + ), + + # Standard Library ADTs for XDS Modula-2 + 'm2iso+xds': ( + # No first class library types + ), + } + + # Standard Library Modules Database + stdlib_modules_db = { + # Empty entry for unknown dialect + 'unknown': ( + # LEAVE THIS EMPTY + ), + # Standard Library Modules for PIM Modula-2 + 'm2pim': ( + pim_stdlib_module_identifiers, + ), + + # Standard Library Modules for ISO Modula-2 + 'm2iso': ( + iso_stdlib_module_identifiers, + ), + + # Standard Library Modules for Modula-2 R10 + 'm2r10': ( + m2r10_stdlib_blueprint_identifiers, + m2r10_stdlib_module_identifiers, + m2r10_stdlib_adt_identifiers, + ), + + # Standard Library Modules for Objective Modula-2 + 'objm2': ( + m2r10_stdlib_blueprint_identifiers, + m2r10_stdlib_module_identifiers, + ), + + # Standard Library Modules for Aglet Modula-2 + 'm2iso+aglet': ( + iso_stdlib_module_identifiers, + ), + + # Standard Library Modules for GNU Modula-2 + 'm2pim+gm2': ( + pim_stdlib_module_identifiers, + ), + + # Standard Library Modules for p1 Modula-2 + 'm2iso+p1': ( + iso_stdlib_module_identifiers, + ), + + # Standard Library Modules for XDS Modula-2 + 'm2iso+xds': ( + iso_stdlib_module_identifiers, + ), + } + + # Standard Library Types Database + stdlib_types_db = { + # Empty entry for unknown dialect + 'unknown': ( + # LEAVE THIS EMPTY + ), + # Standard Library Types for PIM Modula-2 + 'm2pim': ( + pim_stdlib_type_identifiers, + ), + + # Standard Library Types for ISO Modula-2 + 'm2iso': ( + iso_stdlib_type_identifiers, + ), + + # Standard Library Types for Modula-2 R10 + 'm2r10': ( + m2r10_stdlib_type_identifiers, + ), + + # Standard Library Types for Objective Modula-2 + 'objm2': ( + m2r10_stdlib_type_identifiers, + ), + + # Standard Library Types for Aglet Modula-2 + 'm2iso+aglet': ( + iso_stdlib_type_identifiers, + ), + + # Standard Library Types for GNU Modula-2 + 'm2pim+gm2': ( + pim_stdlib_type_identifiers, + ), + + # Standard Library Types for p1 Modula-2 + 'm2iso+p1': ( + iso_stdlib_type_identifiers, + ), + + # Standard Library Types for XDS Modula-2 + 'm2iso+xds': ( + iso_stdlib_type_identifiers, + ), + } + + # Standard Library Procedures Database + stdlib_procedures_db = { + # Empty entry for unknown dialect + 'unknown': ( + # LEAVE THIS EMPTY + ), + # Standard Library Procedures for PIM Modula-2 + 'm2pim': ( + pim_stdlib_proc_identifiers, + ), + + # Standard Library Procedures for ISO Modula-2 + 'm2iso': ( + iso_stdlib_proc_identifiers, + ), + + # Standard Library Procedures for Modula-2 R10 + 'm2r10': ( + m2r10_stdlib_proc_identifiers, + ), + + # Standard Library Procedures for Objective Modula-2 + 'objm2': ( + m2r10_stdlib_proc_identifiers, + ), + + # Standard Library Procedures for Aglet Modula-2 + 'm2iso+aglet': ( + iso_stdlib_proc_identifiers, + ), + + # Standard Library Procedures for GNU Modula-2 + 'm2pim+gm2': ( + pim_stdlib_proc_identifiers, + ), + + # Standard Library Procedures for p1 Modula-2 + 'm2iso+p1': ( + iso_stdlib_proc_identifiers, + ), + + # Standard Library Procedures for XDS Modula-2 + 'm2iso+xds': ( + iso_stdlib_proc_identifiers, + ), + } + + # Standard Library Variables Database + stdlib_variables_db = { + # Empty entry for unknown dialect + 'unknown': ( + # LEAVE THIS EMPTY + ), + # Standard Library Variables for PIM Modula-2 + 'm2pim': ( + pim_stdlib_var_identifiers, + ), + + # Standard Library Variables for ISO Modula-2 + 'm2iso': ( + iso_stdlib_var_identifiers, + ), + + # Standard Library Variables for Modula-2 R10 + 'm2r10': ( + m2r10_stdlib_var_identifiers, + ), + + # Standard Library Variables for Objective Modula-2 + 'objm2': ( + m2r10_stdlib_var_identifiers, + ), + + # Standard Library Variables for Aglet Modula-2 + 'm2iso+aglet': ( + iso_stdlib_var_identifiers, + ), + + # Standard Library Variables for GNU Modula-2 + 'm2pim+gm2': ( + pim_stdlib_var_identifiers, + ), + + # Standard Library Variables for p1 Modula-2 + 'm2iso+p1': ( + iso_stdlib_var_identifiers, + ), + + # Standard Library Variables for XDS Modula-2 + 'm2iso+xds': ( + iso_stdlib_var_identifiers, + ), + } + + # Standard Library Constants Database + stdlib_constants_db = { + # Empty entry for unknown dialect + 'unknown': ( + # LEAVE THIS EMPTY + ), + # Standard Library Constants for PIM Modula-2 + 'm2pim': ( + pim_stdlib_const_identifiers, + ), + + # Standard Library Constants for ISO Modula-2 + 'm2iso': ( + iso_stdlib_const_identifiers, + ), + + # Standard Library Constants for Modula-2 R10 + 'm2r10': ( + m2r10_stdlib_const_identifiers, + ), + + # Standard Library Constants for Objective Modula-2 + 'objm2': ( + m2r10_stdlib_const_identifiers, + ), + + # Standard Library Constants for Aglet Modula-2 + 'm2iso+aglet': ( + iso_stdlib_const_identifiers, + ), + + # Standard Library Constants for GNU Modula-2 + 'm2pim+gm2': ( + pim_stdlib_const_identifiers, + ), + + # Standard Library Constants for p1 Modula-2 + 'm2iso+p1': ( + iso_stdlib_const_identifiers, + ), + + # Standard Library Constants for XDS Modula-2 + 'm2iso+xds': ( + iso_stdlib_const_identifiers, + ), + } + +# M e t h o d s + + # initialise a lexer instance + def __init__(self, **options): + # + # check dialect options + # + dialects = get_list_opt(options, 'dialect', []) + # + for dialect_option in dialects: + if dialect_option in self.dialects[1:-1]: + # valid dialect option found + self.set_dialect(dialect_option) + break + # + # Fallback Mode (DEFAULT) + else: + # no valid dialect option + self.set_dialect('unknown') + # + self.dialect_set_by_tag = False + # + # check style options + # + styles = get_list_opt(options, 'style', []) + # + # use lowercase mode for Algol style + if 'algol' in styles or 'algol_nu' in styles: + self.algol_publication_mode = True + else: + self.algol_publication_mode = False + # + # Check option flags + # + self.treat_stdlib_adts_as_builtins = get_bool_opt( + options, 'treat_stdlib_adts_as_builtins', True) + # + # call superclass initialiser + RegexLexer.__init__(self, **options) + + # Set lexer to a specified dialect + def set_dialect(self, dialect_id): + # + # if __debug__: + # print 'entered set_dialect with arg: ', dialect_id + # + # check dialect name against known dialects + if dialect_id not in self.dialects: + dialect = 'unknown' # default + else: + dialect = dialect_id + # + # compose lexemes to reject set + lexemes_to_reject_set = set() + # add each list of reject lexemes for this dialect + for list in self.lexemes_to_reject_db[dialect]: + lexemes_to_reject_set.update(set(list)) + # + # compose reserved words set + reswords_set = set() + # add each list of reserved words for this dialect + for list in self.reserved_words_db[dialect]: + reswords_set.update(set(list)) + # + # compose builtins set + builtins_set = set() + # add each list of builtins for this dialect excluding reserved words + for list in self.builtins_db[dialect]: + builtins_set.update(set(list).difference(reswords_set)) + # + # compose pseudo-builtins set + pseudo_builtins_set = set() + # add each list of builtins for this dialect excluding reserved words + for list in self.pseudo_builtins_db[dialect]: + pseudo_builtins_set.update(set(list).difference(reswords_set)) + # + # compose ADTs set + adts_set = set() + # add each list of ADTs for this dialect excluding reserved words + for list in self.stdlib_adts_db[dialect]: + adts_set.update(set(list).difference(reswords_set)) + # + # compose modules set + modules_set = set() + # add each list of builtins for this dialect excluding builtins + for list in self.stdlib_modules_db[dialect]: + modules_set.update(set(list).difference(builtins_set)) + # + # compose types set + types_set = set() + # add each list of types for this dialect excluding builtins + for list in self.stdlib_types_db[dialect]: + types_set.update(set(list).difference(builtins_set)) + # + # compose procedures set + procedures_set = set() + # add each list of procedures for this dialect excluding builtins + for list in self.stdlib_procedures_db[dialect]: + procedures_set.update(set(list).difference(builtins_set)) + # + # compose variables set + variables_set = set() + # add each list of variables for this dialect excluding builtins + for list in self.stdlib_variables_db[dialect]: + variables_set.update(set(list).difference(builtins_set)) + # + # compose constants set + constants_set = set() + # add each list of constants for this dialect excluding builtins + for list in self.stdlib_constants_db[dialect]: + constants_set.update(set(list).difference(builtins_set)) + # + # update lexer state + self.dialect = dialect + self.lexemes_to_reject = lexemes_to_reject_set + self.reserved_words = reswords_set + self.builtins = builtins_set + self.pseudo_builtins = pseudo_builtins_set + self.adts = adts_set + self.modules = modules_set + self.types = types_set + self.procedures = procedures_set + self.variables = variables_set + self.constants = constants_set + # + # if __debug__: + # print 'exiting set_dialect' + # print ' self.dialect: ', self.dialect + # print ' self.lexemes_to_reject: ', self.lexemes_to_reject + # print ' self.reserved_words: ', self.reserved_words + # print ' self.builtins: ', self.builtins + # print ' self.pseudo_builtins: ', self.pseudo_builtins + # print ' self.adts: ', self.adts + # print ' self.modules: ', self.modules + # print ' self.types: ', self.types + # print ' self.procedures: ', self.procedures + # print ' self.variables: ', self.variables + # print ' self.types: ', self.types + # print ' self.constants: ', self.constants + + # Extracts a dialect name from a dialect tag comment string and checks + # the extracted name against known dialects. If a match is found, the + # matching name is returned, otherwise dialect id 'unknown' is returned + def get_dialect_from_dialect_tag(self, dialect_tag): + # + # if __debug__: + # print 'entered get_dialect_from_dialect_tag with arg: ', dialect_tag + # + # constants + left_tag_delim = '(*!' + right_tag_delim = '*)' + left_tag_delim_len = len(left_tag_delim) + right_tag_delim_len = len(right_tag_delim) + indicator_start = left_tag_delim_len + indicator_end = -(right_tag_delim_len) + # + # check comment string for dialect indicator + if len(dialect_tag) > (left_tag_delim_len + right_tag_delim_len) \ + and dialect_tag.startswith(left_tag_delim) \ + and dialect_tag.endswith(right_tag_delim): + # + # if __debug__: + # print 'dialect tag found' + # + # extract dialect indicator + indicator = dialect_tag[indicator_start:indicator_end] + # + # if __debug__: + # print 'extracted: ', indicator + # + # check against known dialects + for index in range(1, len(self.dialects)): + # + # if __debug__: + # print 'dialects[', index, ']: ', self.dialects[index] + # + if indicator == self.dialects[index]: + # + # if __debug__: + # print 'matching dialect found' + # + # indicator matches known dialect + return indicator + else: + # indicator does not match any dialect + return 'unknown' # default + else: + # invalid indicator string + return 'unknown' # default + + # intercept the token stream, modify token attributes and return them + def get_tokens_unprocessed(self, text): + for index, token, value in RegexLexer.get_tokens_unprocessed(self, text): + # + # check for dialect tag if dialect has not been set by tag + if not self.dialect_set_by_tag and token == Comment.Special: + indicated_dialect = self.get_dialect_from_dialect_tag(value) + if indicated_dialect != 'unknown': + # token is a dialect indicator + # reset reserved words and builtins + self.set_dialect(indicated_dialect) + self.dialect_set_by_tag = True + # + # check for reserved words, predefined and stdlib identifiers + if token is Name: + if value in self.reserved_words: + token = Keyword.Reserved + if self.algol_publication_mode: + value = value.lower() + # + elif value in self.builtins: + token = Name.Builtin + if self.algol_publication_mode: + value = value.lower() + # + elif value in self.pseudo_builtins: + token = Name.Builtin.Pseudo + if self.algol_publication_mode: + value = value.lower() + # + elif value in self.adts: + if not self.treat_stdlib_adts_as_builtins: + token = Name.Namespace + else: + token = Name.Builtin.Pseudo + if self.algol_publication_mode: + value = value.lower() + # + elif value in self.modules: + token = Name.Namespace + # + elif value in self.types: + token = Name.Class + # + elif value in self.procedures: + token = Name.Function + # + elif value in self.variables: + token = Name.Variable + # + elif value in self.constants: + token = Name.Constant + # + elif token in Number: + # + # mark prefix number literals as error for PIM and ISO dialects + if self.dialect not in ('unknown', 'm2r10', 'objm2'): + if "'" in value or value[0:2] in ('0b', '0x', '0u'): + token = Error + # + elif self.dialect in ('m2r10', 'objm2'): + # mark base-8 number literals as errors for M2 R10 and ObjM2 + if token is Number.Oct: + token = Error + # mark suffix base-16 literals as errors for M2 R10 and ObjM2 + elif token is Number.Hex and 'H' in value: + token = Error + # mark real numbers with E as errors for M2 R10 and ObjM2 + elif token is Number.Float and 'E' in value: + token = Error + # + elif token in Comment: + # + # mark single line comment as error for PIM and ISO dialects + if token is Comment.Single: + if self.dialect not in ('unknown', 'm2r10', 'objm2'): + token = Error + # + if token is Comment.Preproc: + # mark ISO pragma as error for PIM dialects + if value.startswith('<*') and \ + self.dialect.startswith('m2pim'): + token = Error + # mark PIM pragma as comment for other dialects + elif value.startswith('(*$') and \ + self.dialect != 'unknown' and \ + not self.dialect.startswith('m2pim'): + token = Comment.Multiline + # + else: # token is neither Name nor Comment + # + # mark lexemes matching the dialect's error token set as errors + if value in self.lexemes_to_reject: + token = Error + # + # substitute lexemes when in Algol mode + if self.algol_publication_mode: + if value == '#': + value = '≠' + elif value == '<=': + value = '≤' + elif value == '>=': + value = '≥' + elif value == '==': + value = '≡' + elif value == '*.': + value = '•' + + # return result + yield index, token, value + + def analyse_text(text): + """It's Pascal-like, but does not use FUNCTION -- uses PROCEDURE + instead.""" + + # Check if this looks like Pascal, if not, bail out early + if not ('(*' in text and '*)' in text and ':=' in text): + return + + result = 0 + # Procedure is in Modula2 + if re.search(r'\bPROCEDURE\b', text): + result += 0.6 + + # FUNCTION is only valid in Pascal, but not in Modula2 + if re.search(r'\bFUNCTION\b', text): + result = 0.0 + + return result diff --git a/.venv/lib/python3.8/site-packages/pygments/lexers/monte.py b/.venv/lib/python3.8/site-packages/pygments/lexers/monte.py new file mode 100644 index 00000000..311fa172 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/pygments/lexers/monte.py @@ -0,0 +1,204 @@ +# -*- coding: utf-8 -*- +""" + pygments.lexers.monte + ~~~~~~~~~~~~~~~~~~~~~ + + Lexer for the Monte programming language. + + :copyright: Copyright 2006-2020 by the Pygments team, see AUTHORS. + :license: BSD, see LICENSE for details. +""" + +from pygments.token import Comment, Error, Keyword, Name, Number, Operator, \ + Punctuation, String, Whitespace +from pygments.lexer import RegexLexer, include, words + +__all__ = ['MonteLexer'] + + +# `var` handled separately +# `interface` handled separately +_declarations = ['bind', 'def', 'fn', 'object'] +_methods = ['method', 'to'] +_keywords = [ + 'as', 'break', 'catch', 'continue', 'else', 'escape', 'exit', 'exports', + 'extends', 'finally', 'for', 'guards', 'if', 'implements', 'import', + 'in', 'match', 'meta', 'pass', 'return', 'switch', 'try', 'via', 'when', + 'while', +] +_operators = [ + # Unary + '~', '!', + # Binary + '+', '-', '*', '/', '%', '**', '&', '|', '^', '<<', '>>', + # Binary augmented + '+=', '-=', '*=', '/=', '%=', '**=', '&=', '|=', '^=', '<<=', '>>=', + # Comparison + '==', '!=', '<', '<=', '>', '>=', '<=>', + # Patterns and assignment + ':=', '?', '=~', '!~', '=>', + # Calls and sends + '.', '<-', '->', +] +_escape_pattern = ( + r'(?:\\x[0-9a-fA-F]{2}|\\u[0-9a-fA-F]{4}|\\U[0-9a-fA-F]{8}|' + r'\\["\'\\bftnr])') +# _char = _escape_chars + [('.', String.Char)] +_identifier = r'[_a-zA-Z]\w*' + +_constants = [ + # Void constants + 'null', + # Bool constants + 'false', 'true', + # Double constants + 'Infinity', 'NaN', + # Special objects + 'M', 'Ref', 'throw', 'traceln', +] + +_guards = [ + 'Any', 'Binding', 'Bool', 'Bytes', 'Char', 'DeepFrozen', 'Double', + 'Empty', 'Int', 'List', 'Map', 'Near', 'NullOk', 'Same', 'Selfless', + 'Set', 'Str', 'SubrangeGuard', 'Transparent', 'Void', +] + +_safeScope = [ + '_accumulateList', '_accumulateMap', '_auditedBy', '_bind', + '_booleanFlow', '_comparer', '_equalizer', '_iterForever', '_loop', + '_makeBytes', '_makeDouble', '_makeFinalSlot', '_makeInt', '_makeList', + '_makeMap', '_makeMessageDesc', '_makeOrderedSpace', '_makeParamDesc', + '_makeProtocolDesc', '_makeSourceSpan', '_makeString', '_makeVarSlot', + '_makeVerbFacet', '_mapExtract', '_matchSame', '_quasiMatcher', + '_slotToBinding', '_splitList', '_suchThat', '_switchFailed', + '_validateFor', 'b__quasiParser', 'eval', 'import', 'm__quasiParser', + 'makeBrandPair', 'makeLazySlot', 'safeScope', 'simple__quasiParser', +] + + +class MonteLexer(RegexLexer): + """ + Lexer for the `Monte `_ programming language. + + .. versionadded:: 2.2 + """ + name = 'Monte' + aliases = ['monte'] + filenames = ['*.mt'] + + tokens = { + 'root': [ + # Comments + (r'#[^\n]*\n', Comment), + + # Docstrings + # Apologies for the non-greedy matcher here. + (r'/\*\*.*?\*/', String.Doc), + + # `var` declarations + (r'\bvar\b', Keyword.Declaration, 'var'), + + # `interface` declarations + (r'\binterface\b', Keyword.Declaration, 'interface'), + + # method declarations + (words(_methods, prefix='\\b', suffix='\\b'), + Keyword, 'method'), + + # All other declarations + (words(_declarations, prefix='\\b', suffix='\\b'), + Keyword.Declaration), + + # Keywords + (words(_keywords, prefix='\\b', suffix='\\b'), Keyword), + + # Literals + ('[+-]?0x[_0-9a-fA-F]+', Number.Hex), + (r'[+-]?[_0-9]+\.[_0-9]*([eE][+-]?[_0-9]+)?', Number.Float), + ('[+-]?[_0-9]+', Number.Integer), + ("'", String.Double, 'char'), + ('"', String.Double, 'string'), + + # Quasiliterals + ('`', String.Backtick, 'ql'), + + # Operators + (words(_operators), Operator), + + # Verb operators + (_identifier + '=', Operator.Word), + + # Safe scope constants + (words(_constants, prefix='\\b', suffix='\\b'), + Keyword.Pseudo), + + # Safe scope guards + (words(_guards, prefix='\\b', suffix='\\b'), Keyword.Type), + + # All other safe scope names + (words(_safeScope, prefix='\\b', suffix='\\b'), + Name.Builtin), + + # Identifiers + (_identifier, Name), + + # Punctuation + (r'\(|\)|\{|\}|\[|\]|:|,', Punctuation), + + # Whitespace + (' +', Whitespace), + + # Definite lexer errors + ('=', Error), + ], + 'char': [ + # It is definitely an error to have a char of width == 0. + ("'", Error, 'root'), + (_escape_pattern, String.Escape, 'charEnd'), + ('.', String.Char, 'charEnd'), + ], + 'charEnd': [ + ("'", String.Char, '#pop:2'), + # It is definitely an error to have a char of width > 1. + ('.', Error), + ], + # The state of things coming into an interface. + 'interface': [ + (' +', Whitespace), + (_identifier, Name.Class, '#pop'), + include('root'), + ], + # The state of things coming into a method. + 'method': [ + (' +', Whitespace), + (_identifier, Name.Function, '#pop'), + include('root'), + ], + 'string': [ + ('"', String.Double, 'root'), + (_escape_pattern, String.Escape), + (r'\n', String.Double), + ('.', String.Double), + ], + 'ql': [ + ('`', String.Backtick, 'root'), + (r'\$' + _escape_pattern, String.Escape), + (r'\$\$', String.Escape), + (r'@@', String.Escape), + (r'\$\{', String.Interpol, 'qlNest'), + (r'@\{', String.Interpol, 'qlNest'), + (r'\$' + _identifier, Name), + ('@' + _identifier, Name), + ('.', String.Backtick), + ], + 'qlNest': [ + (r'\}', String.Interpol, '#pop'), + include('root'), + ], + # The state of things immediately following `var`. + 'var': [ + (' +', Whitespace), + (_identifier, Name.Variable, '#pop'), + include('root'), + ], + } diff --git a/.venv/lib/python3.8/site-packages/pygments/lexers/mosel.py b/.venv/lib/python3.8/site-packages/pygments/lexers/mosel.py new file mode 100644 index 00000000..02cc5e3e --- /dev/null +++ b/.venv/lib/python3.8/site-packages/pygments/lexers/mosel.py @@ -0,0 +1,448 @@ +# -*- coding: utf-8 -*- +""" + pygments.lexers.mosel + ~~~~~~~~~~~~~~~~~~~~~ + + Lexers for the mosel language. + http://www.fico.com/en/products/fico-xpress-optimization + + :copyright: Copyright 2006-2020 by the Pygments team, see AUTHORS. + :license: BSD, see LICENSE for details. +""" + +from pygments.lexer import RegexLexer, words +from pygments.token import Text, Comment, Operator, Keyword, Name, String, \ + Number, Punctuation + +__all__ = ['MoselLexer'] + +FUNCTIONS = ( + # core functions + '_', + 'abs', + 'arctan', + 'asproc', + 'assert', + 'bitflip', + 'bitneg', + 'bitset', + 'bitshift', + 'bittest', + 'bitval', + 'ceil', + 'cos', + 'create', + 'currentdate', + 'currenttime', + 'cutelt', + 'cutfirst', + 'cuthead', + 'cutlast', + 'cuttail', + 'datablock', + 'delcell', + 'exists', + 'exit', + 'exp', + 'exportprob', + 'fclose', + 'fflush', + 'finalize', + 'findfirst', + 'findlast', + 'floor', + 'fopen', + 'fselect', + 'fskipline', + 'fwrite', + 'fwrite_', + 'fwriteln', + 'fwriteln_', + 'getact', + 'getcoeff', + 'getcoeffs', + 'getdual', + 'getelt', + 'getfid', + 'getfirst', + 'getfname', + 'gethead', + 'getlast', + 'getobjval', + 'getparam', + 'getrcost', + 'getreadcnt', + 'getreverse', + 'getsize', + 'getslack', + 'getsol', + 'gettail', + 'gettype', + 'getvars', + 'isdynamic', + 'iseof', + 'isfinite', + 'ishidden', + 'isinf', + 'isnan', + 'isodd', + 'ln', + 'localsetparam', + 'log', + 'makesos1', + 'makesos2', + 'maxlist', + 'memoryuse', + 'minlist', + 'newmuid', + 'publish', + 'random', + 'read', + 'readln', + 'reset', + 'restoreparam', + 'reverse', + 'round', + 'setcoeff', + 'sethidden', + 'setioerr', + 'setmatherr', + 'setname', + 'setparam', + 'setrandseed', + 'setrange', + 'settype', + 'sin', + 'splithead', + 'splittail', + 'sqrt', + 'strfmt', + 'substr', + 'timestamp', + 'unpublish', + 'versionnum', + 'versionstr', + 'write', + 'write_', + 'writeln', + 'writeln_', + + # mosel exam mmxprs | sed -n -e "s/ [pf][a-z]* \([a-zA-Z0-9_]*\).*/'\1',/p" | sort -u + 'addcut', + 'addcuts', + 'addmipsol', + 'basisstability', + 'calcsolinfo', + 'clearmipdir', + 'clearmodcut', + 'command', + 'copysoltoinit', + 'crossoverlpsol', + 'defdelayedrows', + 'defsecurevecs', + 'delcuts', + 'dropcuts', + 'estimatemarginals', + 'fixglobal', + 'flushmsgq', + 'getbstat', + 'getcnlist', + 'getcplist', + 'getdualray', + 'getiis', + 'getiissense', + 'getiistype', + 'getinfcause', + 'getinfeas', + 'getlb', + 'getlct', + 'getleft', + 'getloadedlinctrs', + 'getloadedmpvars', + 'getname', + 'getprimalray', + 'getprobstat', + 'getrange', + 'getright', + 'getsensrng', + 'getsize', + 'getsol', + 'gettype', + 'getub', + 'getvars', + 'gety', + 'hasfeature', + 'implies', + 'indicator', + 'initglobal', + 'ishidden', + 'isiisvalid', + 'isintegral', + 'loadbasis', + 'loadcuts', + 'loadlpsol', + 'loadmipsol', + 'loadprob', + 'maximise', + 'maximize', + 'minimise', + 'minimize', + 'postsolve', + 'readbasis', + 'readdirs', + 'readsol', + 'refinemipsol', + 'rejectintsol', + 'repairinfeas', + 'repairinfeas_deprec', + 'resetbasis', + 'resetiis', + 'resetsol', + 'savebasis', + 'savemipsol', + 'savesol', + 'savestate', + 'selectsol', + 'setarchconsistency', + 'setbstat', + 'setcallback', + 'setcbcutoff', + 'setgndata', + 'sethidden', + 'setlb', + 'setmipdir', + 'setmodcut', + 'setsol', + 'setub', + 'setucbdata', + 'stopoptimise', + 'stopoptimize', + 'storecut', + 'storecuts', + 'unloadprob', + 'uselastbarsol', + 'writebasis', + 'writedirs', + 'writeprob', + 'writesol', + 'xor', + 'xprs_addctr', + 'xprs_addindic', + + # mosel exam mmsystem | sed -n -e "s/ [pf][a-z]* \([a-zA-Z0-9_]*\).*/'\1',/p" | sort -u + 'addmonths', + 'copytext', + 'cuttext', + 'deltext', + 'endswith', + 'erase', + 'expandpath', + 'fcopy', + 'fdelete', + 'findfiles', + 'findtext', + 'fmove', + 'formattext', + 'getasnumber', + 'getchar', + 'getcwd', + 'getdate', + 'getday', + 'getdaynum', + 'getdays', + 'getdirsep', + 'getdsoparam', + 'getendparse', + 'getenv', + 'getfsize', + 'getfstat', + 'getftime', + 'gethour', + 'getminute', + 'getmonth', + 'getmsec', + 'getoserrmsg', + 'getoserror', + 'getpathsep', + 'getqtype', + 'getsecond', + 'getsepchar', + 'getsize', + 'getstart', + 'getsucc', + 'getsysinfo', + 'getsysstat', + 'gettime', + 'gettmpdir', + 'gettrim', + 'getweekday', + 'getyear', + 'inserttext', + 'isvalid', + 'jointext', + 'makedir', + 'makepath', + 'newtar', + 'newzip', + 'nextfield', + 'openpipe', + 'parseextn', + 'parseint', + 'parsereal', + 'parsetext', + 'pastetext', + 'pathmatch', + 'pathsplit', + 'qsort', + 'quote', + 'readtextline', + 'regmatch', + 'regreplace', + 'removedir', + 'removefiles', + 'setchar', + 'setdate', + 'setday', + 'setdsoparam', + 'setendparse', + 'setenv', + 'sethour', + 'setminute', + 'setmonth', + 'setmsec', + 'setoserror', + 'setqtype', + 'setsecond', + 'setsepchar', + 'setstart', + 'setsucc', + 'settime', + 'settrim', + 'setyear', + 'sleep', + 'splittext', + 'startswith', + 'system', + 'tarlist', + 'textfmt', + 'tolower', + 'toupper', + 'trim', + 'untar', + 'unzip', + 'ziplist', + + # mosel exam mmjobs | sed -n -e "s/ [pf][a-z]* \([a-zA-Z0-9_]*\).*/'\1',/p" | sort -u + 'canceltimer', + 'clearaliases', + 'compile', + 'connect', + 'detach', + 'disconnect', + 'dropnextevent', + 'findxsrvs', + 'getaliases', + 'getannidents', + 'getannotations', + 'getbanner', + 'getclass', + 'getdsoprop', + 'getdsopropnum', + 'getexitcode', + 'getfromgid', + 'getfromid', + 'getfromuid', + 'getgid', + 'gethostalias', + 'getid', + 'getmodprop', + 'getmodpropnum', + 'getnextevent', + 'getnode', + 'getrmtid', + 'getstatus', + 'getsysinfo', + 'gettimer', + 'getuid', + 'getvalue', + 'isqueueempty', + 'load', + 'nullevent', + 'peeknextevent', + 'resetmodpar', + 'run', + 'send', + 'setcontrol', + 'setdefstream', + 'setgid', + 'sethostalias', + 'setmodpar', + 'settimer', + 'setuid', + 'setworkdir', + 'stop', + 'unload', + 'wait', + 'waitexpired', + 'waitfor', + 'waitforend', +) + + +class MoselLexer(RegexLexer): + """ + For the Mosel optimization language. + + .. versionadded:: 2.6 + """ + name = 'Mosel' + aliases = ['mosel'] + filenames = ['*.mos'] + + tokens = { + 'root': [ + (r'\n', Text), + (r'\s+', Text.Whitespace), + (r'!.*?\n', Comment.Single), + (r'\(!(.|\n)*?!\)', Comment.Multiline), + (words(( + 'and', 'as', 'break', 'case', 'count', 'declarations', 'do', + 'dynamic', 'elif', 'else', 'end-', 'end', 'evaluation', 'false', + 'forall', 'forward', 'from', 'function', 'hashmap', 'if', + 'imports', 'include', 'initialisations', 'initializations', 'inter', + 'max', 'min', 'model', 'namespace', 'next', 'not', 'nsgroup', + 'nssearch', 'of', 'options', 'or', 'package', 'parameters', + 'procedure', 'public', 'prod', 'record', 'repeat', 'requirements', + 'return', 'sum', 'then', 'to', 'true', 'union', 'until', 'uses', + 'version', 'while', 'with'), prefix=r'\b', suffix=r'\b'), + Keyword.Builtin), + (words(( + 'range', 'array', 'set', 'list', 'mpvar', 'mpproblem', 'linctr', + 'nlctr', 'integer', 'string', 'real', 'boolean', 'text', 'time', + 'date', 'datetime', 'returned', 'Model', 'Mosel', 'counter', + 'xmldoc', 'is_sos1', 'is_sos2', 'is_integer', 'is_binary', + 'is_continuous', 'is_free', 'is_semcont', 'is_semint', + 'is_partint'), prefix=r'\b', suffix=r'\b'), + Keyword.Type), + (r'(\+|\-|\*|/|=|<=|>=|\||\^|<|>|<>|\.\.|\.|:=|::|:|in|mod|div)', + Operator), + (r'[()\[\]{},;]+', Punctuation), + (words(FUNCTIONS, prefix=r'\b', suffix=r'\b'), Name.Function), + (r'(\d+\.(?!\.)\d*|\.(?!.)\d+)([eE][+-]?\d+)?', Number.Float), + (r'\d+([eE][+-]?\d+)?', Number.Integer), + (r'[+-]?Infinity', Number.Integer), + (r'0[xX][0-9a-fA-F]+', Number), + (r'"', String.Double, 'double_quote'), + (r'\'', String.Single, 'single_quote'), + (r'(\w+|(\.(?!\.)))', Text), + ], + 'single_quote': [ + (r'\'', String.Single, '#pop'), + (r'[^\']+', String.Single), + ], + 'double_quote': [ + (r'(\\"|\\[0-7]{1,3}\D|\\[abfnrtv]|\\\\)', String.Escape), + (r'\"', String.Double, '#pop'), + (r'[^"\\]+', String.Double), + ], + } diff --git a/.venv/lib/python3.8/site-packages/pygments/lexers/ncl.py b/.venv/lib/python3.8/site-packages/pygments/lexers/ncl.py new file mode 100644 index 00000000..6e094e00 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/pygments/lexers/ncl.py @@ -0,0 +1,894 @@ +# -*- coding: utf-8 -*- +""" + pygments.lexers.ncl + ~~~~~~~~~~~~~~~~~~~ + + Lexers for NCAR Command Language. + + :copyright: Copyright 2006-2020 by the Pygments team, see AUTHORS. + :license: BSD, see LICENSE for details. +""" + +import re + +from pygments.lexer import RegexLexer, include, words +from pygments.token import Text, Comment, Operator, Keyword, Name, String, \ + Number, Punctuation + +__all__ = ['NCLLexer'] + + +class NCLLexer(RegexLexer): + """ + Lexer for NCL code. + + .. versionadded:: 2.2 + """ + name = 'NCL' + aliases = ['ncl'] + filenames = ['*.ncl'] + mimetypes = ['text/ncl'] + flags = re.MULTILINE + + tokens = { + 'root': [ + (r';.*\n', Comment), + include('strings'), + include('core'), + (r'[a-zA-Z_]\w*', Name), + include('nums'), + (r'[\s]+', Text), + ], + 'core': [ + # Statements + (words(( + 'begin', 'break', 'continue', 'create', 'defaultapp', 'do', + 'else', 'end', 'external', 'exit', 'True', 'False', 'file', 'function', + 'getvalues', 'graphic', 'group', 'if', 'list', 'load', 'local', + 'new', '_Missing', 'Missing', 'noparent', 'procedure', + 'quit', 'QUIT', 'Quit', 'record', 'return', 'setvalues', 'stop', + 'then', 'while'), prefix=r'\b', suffix=r'\s*\b'), + Keyword), + + # Data Types + (words(( + 'ubyte', 'uint', 'uint64', 'ulong', 'string', 'byte', + 'character', 'double', 'float', 'integer', 'int64', 'logical', + 'long', 'short', 'ushort', 'enumeric', 'numeric', 'snumeric'), + prefix=r'\b', suffix=r'\s*\b'), + Keyword.Type), + + # Operators + (r'[\%^*+\-/<>]', Operator), + + # punctuation: + (r'[\[\]():@$!&|.,\\{}]', Punctuation), + (r'[=:]', Punctuation), + + # Intrinsics + (words(( + 'abs', 'acos', 'addfile', 'addfiles', 'all', 'angmom_atm', 'any', + 'area_conserve_remap', 'area_hi2lores', 'area_poly_sphere', + 'asciiread', 'asciiwrite', 'asin', 'atan', 'atan2', 'attsetvalues', + 'avg', 'betainc', 'bin_avg', 'bin_sum', 'bw_bandpass_filter', + 'cancor', 'cbinread', 'cbinwrite', 'cd_calendar', 'cd_inv_calendar', + 'cdfbin_p', 'cdfbin_pr', 'cdfbin_s', 'cdfbin_xn', 'cdfchi_p', + 'cdfchi_x', 'cdfgam_p', 'cdfgam_x', 'cdfnor_p', 'cdfnor_x', + 'cdft_p', 'cdft_t', 'ceil', 'center_finite_diff', + 'center_finite_diff_n', 'cfftb', 'cfftf', 'cfftf_frq_reorder', + 'charactertodouble', 'charactertofloat', 'charactertointeger', + 'charactertolong', 'charactertoshort', 'charactertostring', + 'chartodouble', 'chartofloat', 'chartoint', 'chartointeger', + 'chartolong', 'chartoshort', 'chartostring', 'chiinv', 'clear', + 'color_index_to_rgba', 'conform', 'conform_dims', 'cos', 'cosh', + 'count_unique_values', 'covcorm', 'covcorm_xy', 'craybinnumrec', + 'craybinrecread', 'create_graphic', 'csa1', 'csa1d', 'csa1s', + 'csa1x', 'csa1xd', 'csa1xs', 'csa2', 'csa2d', 'csa2l', 'csa2ld', + 'csa2ls', 'csa2lx', 'csa2lxd', 'csa2lxs', 'csa2s', 'csa2x', + 'csa2xd', 'csa2xs', 'csa3', 'csa3d', 'csa3l', 'csa3ld', 'csa3ls', + 'csa3lx', 'csa3lxd', 'csa3lxs', 'csa3s', 'csa3x', 'csa3xd', + 'csa3xs', 'csc2s', 'csgetp', 'css2c', 'cssetp', 'cssgrid', 'csstri', + 'csvoro', 'cumsum', 'cz2ccm', 'datatondc', 'day_of_week', + 'day_of_year', 'days_in_month', 'default_fillvalue', 'delete', + 'depth_to_pres', 'destroy', 'determinant', 'dewtemp_trh', + 'dgeevx_lapack', 'dim_acumrun_n', 'dim_avg', 'dim_avg_n', + 'dim_avg_wgt', 'dim_avg_wgt_n', 'dim_cumsum', 'dim_cumsum_n', + 'dim_gamfit_n', 'dim_gbits', 'dim_max', 'dim_max_n', 'dim_median', + 'dim_median_n', 'dim_min', 'dim_min_n', 'dim_num', 'dim_num_n', + 'dim_numrun_n', 'dim_pqsort', 'dim_pqsort_n', 'dim_product', + 'dim_product_n', 'dim_rmsd', 'dim_rmsd_n', 'dim_rmvmean', + 'dim_rmvmean_n', 'dim_rmvmed', 'dim_rmvmed_n', 'dim_spi_n', + 'dim_standardize', 'dim_standardize_n', 'dim_stat4', 'dim_stat4_n', + 'dim_stddev', 'dim_stddev_n', 'dim_sum', 'dim_sum_n', 'dim_sum_wgt', + 'dim_sum_wgt_n', 'dim_variance', 'dim_variance_n', 'dimsizes', + 'doubletobyte', 'doubletochar', 'doubletocharacter', + 'doubletofloat', 'doubletoint', 'doubletointeger', 'doubletolong', + 'doubletoshort', 'dpres_hybrid_ccm', 'dpres_plevel', 'draw', + 'draw_color_palette', 'dsgetp', 'dsgrid2', 'dsgrid2d', 'dsgrid2s', + 'dsgrid3', 'dsgrid3d', 'dsgrid3s', 'dspnt2', 'dspnt2d', 'dspnt2s', + 'dspnt3', 'dspnt3d', 'dspnt3s', 'dssetp', 'dtrend', 'dtrend_msg', + 'dtrend_msg_n', 'dtrend_n', 'dtrend_quadratic', + 'dtrend_quadratic_msg_n', 'dv2uvf', 'dv2uvg', 'dz_height', + 'echo_off', 'echo_on', 'eof2data', 'eof_varimax', 'eofcor', + 'eofcor_pcmsg', 'eofcor_ts', 'eofcov', 'eofcov_pcmsg', 'eofcov_ts', + 'eofunc', 'eofunc_ts', 'eofunc_varimax', 'equiv_sample_size', 'erf', + 'erfc', 'esacr', 'esacv', 'esccr', 'esccv', 'escorc', 'escorc_n', + 'escovc', 'exit', 'exp', 'exp_tapersh', 'exp_tapersh_wgts', + 'exp_tapershC', 'ezfftb', 'ezfftb_n', 'ezfftf', 'ezfftf_n', + 'f2fosh', 'f2foshv', 'f2fsh', 'f2fshv', 'f2gsh', 'f2gshv', 'fabs', + 'fbindirread', 'fbindirwrite', 'fbinnumrec', 'fbinread', + 'fbinrecread', 'fbinrecwrite', 'fbinwrite', 'fft2db', 'fft2df', + 'fftshift', 'fileattdef', 'filechunkdimdef', 'filedimdef', + 'fileexists', 'filegrpdef', 'filevarattdef', 'filevarchunkdef', + 'filevarcompressleveldef', 'filevardef', 'filevardimsizes', + 'filwgts_lancos', 'filwgts_lanczos', 'filwgts_normal', + 'floattobyte', 'floattochar', 'floattocharacter', 'floattoint', + 'floattointeger', 'floattolong', 'floattoshort', 'floor', + 'fluxEddy', 'fo2fsh', 'fo2fshv', 'fourier_info', 'frame', 'fspan', + 'ftcurv', 'ftcurvd', 'ftcurvi', 'ftcurvp', 'ftcurvpi', 'ftcurvps', + 'ftcurvs', 'ftest', 'ftgetp', 'ftkurv', 'ftkurvd', 'ftkurvp', + 'ftkurvpd', 'ftsetp', 'ftsurf', 'g2fsh', 'g2fshv', 'g2gsh', + 'g2gshv', 'gamma', 'gammainc', 'gaus', 'gaus_lobat', + 'gaus_lobat_wgt', 'gc_aangle', 'gc_clkwise', 'gc_dangle', + 'gc_inout', 'gc_latlon', 'gc_onarc', 'gc_pnt2gc', 'gc_qarea', + 'gc_tarea', 'generate_2d_array', 'get_color_index', + 'get_color_rgba', 'get_cpu_time', 'get_isolines', 'get_ncl_version', + 'get_script_name', 'get_script_prefix_name', 'get_sphere_radius', + 'get_unique_values', 'getbitsone', 'getenv', 'getfiledimsizes', + 'getfilegrpnames', 'getfilepath', 'getfilevaratts', + 'getfilevarchunkdimsizes', 'getfilevardims', 'getfilevardimsizes', + 'getfilevarnames', 'getfilevartypes', 'getvaratts', 'getvardims', + 'gradsf', 'gradsg', 'greg2jul', 'grid2triple', 'hlsrgb', 'hsvrgb', + 'hydro', 'hyi2hyo', 'idsfft', 'igradsf', 'igradsg', 'ilapsf', + 'ilapsg', 'ilapvf', 'ilapvg', 'ind', 'ind_resolve', 'int2p', + 'int2p_n', 'integertobyte', 'integertochar', 'integertocharacter', + 'integertoshort', 'inttobyte', 'inttochar', 'inttoshort', + 'inverse_matrix', 'isatt', 'isbigendian', 'isbyte', 'ischar', + 'iscoord', 'isdefined', 'isdim', 'isdimnamed', 'isdouble', + 'isenumeric', 'isfile', 'isfilepresent', 'isfilevar', + 'isfilevaratt', 'isfilevarcoord', 'isfilevardim', 'isfloat', + 'isfunc', 'isgraphic', 'isint', 'isint64', 'isinteger', + 'isleapyear', 'islogical', 'islong', 'ismissing', 'isnan_ieee', + 'isnumeric', 'ispan', 'isproc', 'isshort', 'issnumeric', 'isstring', + 'isubyte', 'isuint', 'isuint64', 'isulong', 'isunlimited', + 'isunsigned', 'isushort', 'isvar', 'jul2greg', 'kmeans_as136', + 'kolsm2_n', 'kron_product', 'lapsf', 'lapsg', 'lapvf', 'lapvg', + 'latlon2utm', 'lclvl', 'lderuvf', 'lderuvg', 'linint1', 'linint1_n', + 'linint2', 'linint2_points', 'linmsg', 'linmsg_n', 'linrood_latwgt', + 'linrood_wgt', 'list_files', 'list_filevars', 'list_hlus', + 'list_procfuncs', 'list_vars', 'ListAppend', 'ListCount', + 'ListGetType', 'ListIndex', 'ListIndexFromName', 'ListPop', + 'ListPush', 'ListSetType', 'loadscript', 'local_max', 'local_min', + 'log', 'log10', 'longtobyte', 'longtochar', 'longtocharacter', + 'longtoint', 'longtointeger', 'longtoshort', 'lspoly', 'lspoly_n', + 'mask', 'max', 'maxind', 'min', 'minind', 'mixed_layer_depth', + 'mixhum_ptd', 'mixhum_ptrh', 'mjo_cross_coh2pha', + 'mjo_cross_segment', 'moc_globe_atl', 'monthday', 'natgrid', + 'natgridd', 'natgrids', 'ncargpath', 'ncargversion', 'ndctodata', + 'ndtooned', 'new', 'NewList', 'ngezlogo', 'nggcog', 'nggetp', + 'nglogo', 'ngsetp', 'NhlAddAnnotation', 'NhlAddData', + 'NhlAddOverlay', 'NhlAddPrimitive', 'NhlAppGetDefaultParentId', + 'NhlChangeWorkstation', 'NhlClassName', 'NhlClearWorkstation', + 'NhlDataPolygon', 'NhlDataPolyline', 'NhlDataPolymarker', + 'NhlDataToNDC', 'NhlDestroy', 'NhlDraw', 'NhlFrame', 'NhlFreeColor', + 'NhlGetBB', 'NhlGetClassResources', 'NhlGetErrorObjectId', + 'NhlGetNamedColorIndex', 'NhlGetParentId', + 'NhlGetParentWorkstation', 'NhlGetWorkspaceObjectId', + 'NhlIsAllocatedColor', 'NhlIsApp', 'NhlIsDataComm', 'NhlIsDataItem', + 'NhlIsDataSpec', 'NhlIsTransform', 'NhlIsView', 'NhlIsWorkstation', + 'NhlName', 'NhlNDCPolygon', 'NhlNDCPolyline', 'NhlNDCPolymarker', + 'NhlNDCToData', 'NhlNewColor', 'NhlNewDashPattern', 'NhlNewMarker', + 'NhlPalGetDefined', 'NhlRemoveAnnotation', 'NhlRemoveData', + 'NhlRemoveOverlay', 'NhlRemovePrimitive', 'NhlSetColor', + 'NhlSetDashPattern', 'NhlSetMarker', 'NhlUpdateData', + 'NhlUpdateWorkstation', 'nice_mnmxintvl', 'nngetaspectd', + 'nngetaspects', 'nngetp', 'nngetsloped', 'nngetslopes', 'nngetwts', + 'nngetwtsd', 'nnpnt', 'nnpntd', 'nnpntend', 'nnpntendd', + 'nnpntinit', 'nnpntinitd', 'nnpntinits', 'nnpnts', 'nnsetp', 'num', + 'obj_anal_ic', 'omega_ccm', 'onedtond', 'overlay', 'paleo_outline', + 'pdfxy_bin', 'poisson_grid_fill', 'pop_remap', 'potmp_insitu_ocn', + 'prcwater_dp', 'pres2hybrid', 'pres_hybrid_ccm', 'pres_sigma', + 'print', 'print_table', 'printFileVarSummary', 'printVarSummary', + 'product', 'pslec', 'pslhor', 'pslhyp', 'qsort', 'rand', + 'random_chi', 'random_gamma', 'random_normal', 'random_setallseed', + 'random_uniform', 'rcm2points', 'rcm2rgrid', 'rdsstoi', + 'read_colormap_file', 'reg_multlin', 'regcoef', 'regCoef_n', + 'regline', 'relhum', 'replace_ieeenan', 'reshape', 'reshape_ind', + 'rgba_to_color_index', 'rgbhls', 'rgbhsv', 'rgbyiq', 'rgrid2rcm', + 'rhomb_trunc', 'rip_cape_2d', 'rip_cape_3d', 'round', 'rtest', + 'runave', 'runave_n', 'set_default_fillvalue', 'set_sphere_radius', + 'setfileoption', 'sfvp2uvf', 'sfvp2uvg', 'shaec', 'shagc', + 'shgetnp', 'shgetp', 'shgrid', 'shorttobyte', 'shorttochar', + 'shorttocharacter', 'show_ascii', 'shsec', 'shsetp', 'shsgc', + 'shsgc_R42', 'sigma2hybrid', 'simpeq', 'simpne', 'sin', + 'sindex_yrmo', 'sinh', 'sizeof', 'sleep', 'smth9', 'snindex_yrmo', + 'solve_linsys', 'span_color_indexes', 'span_color_rgba', + 'sparse_matrix_mult', 'spcorr', 'spcorr_n', 'specx_anal', + 'specxy_anal', 'spei', 'sprintf', 'sprinti', 'sqrt', 'sqsort', + 'srand', 'stat2', 'stat4', 'stat_medrng', 'stat_trim', + 'status_exit', 'stdatmus_p2tdz', 'stdatmus_z2tdp', 'stddev', + 'str_capital', 'str_concat', 'str_fields_count', 'str_get_cols', + 'str_get_dq', 'str_get_field', 'str_get_nl', 'str_get_sq', + 'str_get_tab', 'str_index_of_substr', 'str_insert', 'str_is_blank', + 'str_join', 'str_left_strip', 'str_lower', 'str_match', + 'str_match_ic', 'str_match_ic_regex', 'str_match_ind', + 'str_match_ind_ic', 'str_match_ind_ic_regex', 'str_match_ind_regex', + 'str_match_regex', 'str_right_strip', 'str_split', + 'str_split_by_length', 'str_split_csv', 'str_squeeze', 'str_strip', + 'str_sub_str', 'str_switch', 'str_upper', 'stringtochar', + 'stringtocharacter', 'stringtodouble', 'stringtofloat', + 'stringtoint', 'stringtointeger', 'stringtolong', 'stringtoshort', + 'strlen', 'student_t', 'sum', 'svd_lapack', 'svdcov', 'svdcov_sv', + 'svdstd', 'svdstd_sv', 'system', 'systemfunc', 'tan', 'tanh', + 'taper', 'taper_n', 'tdclrs', 'tdctri', 'tdcudp', 'tdcurv', + 'tddtri', 'tdez2d', 'tdez3d', 'tdgetp', 'tdgrds', 'tdgrid', + 'tdgtrs', 'tdinit', 'tditri', 'tdlbla', 'tdlblp', 'tdlbls', + 'tdline', 'tdlndp', 'tdlnpa', 'tdlpdp', 'tdmtri', 'tdotri', + 'tdpara', 'tdplch', 'tdprpa', 'tdprpi', 'tdprpt', 'tdsetp', + 'tdsort', 'tdstri', 'tdstrs', 'tdttri', 'thornthwaite', 'tobyte', + 'tochar', 'todouble', 'tofloat', 'toint', 'toint64', 'tointeger', + 'tolong', 'toshort', 'tosigned', 'tostring', 'tostring_with_format', + 'totype', 'toubyte', 'touint', 'touint64', 'toulong', 'tounsigned', + 'toushort', 'trend_manken', 'tri_trunc', 'triple2grid', + 'triple2grid2d', 'trop_wmo', 'ttest', 'typeof', 'undef', + 'unique_string', 'update', 'ushorttoint', 'ut_calendar', + 'ut_inv_calendar', 'utm2latlon', 'uv2dv_cfd', 'uv2dvf', 'uv2dvg', + 'uv2sfvpf', 'uv2sfvpg', 'uv2vr_cfd', 'uv2vrdvf', 'uv2vrdvg', + 'uv2vrf', 'uv2vrg', 'v5d_close', 'v5d_create', 'v5d_setLowLev', + 'v5d_setUnits', 'v5d_write', 'v5d_write_var', 'variance', 'vhaec', + 'vhagc', 'vhsec', 'vhsgc', 'vibeta', 'vinth2p', 'vinth2p_ecmwf', + 'vinth2p_ecmwf_nodes', 'vinth2p_nodes', 'vintp2p_ecmwf', 'vr2uvf', + 'vr2uvg', 'vrdv2uvf', 'vrdv2uvg', 'wavelet', 'wavelet_default', + 'weibull', 'wgt_area_smooth', 'wgt_areaave', 'wgt_areaave2', + 'wgt_arearmse', 'wgt_arearmse2', 'wgt_areasum2', 'wgt_runave', + 'wgt_runave_n', 'wgt_vert_avg_beta', 'wgt_volave', 'wgt_volave_ccm', + 'wgt_volrmse', 'wgt_volrmse_ccm', 'where', 'wk_smooth121', 'wmbarb', + 'wmbarbmap', 'wmdrft', 'wmgetp', 'wmlabs', 'wmsetp', 'wmstnm', + 'wmvect', 'wmvectmap', 'wmvlbl', 'wrf_avo', 'wrf_cape_2d', + 'wrf_cape_3d', 'wrf_dbz', 'wrf_eth', 'wrf_helicity', 'wrf_ij_to_ll', + 'wrf_interp_1d', 'wrf_interp_2d_xy', 'wrf_interp_3d_z', + 'wrf_latlon_to_ij', 'wrf_ll_to_ij', 'wrf_omega', 'wrf_pvo', + 'wrf_rh', 'wrf_slp', 'wrf_smooth_2d', 'wrf_td', 'wrf_tk', + 'wrf_updraft_helicity', 'wrf_uvmet', 'wrf_virtual_temp', + 'wrf_wetbulb', 'wrf_wps_close_int', 'wrf_wps_open_int', + 'wrf_wps_rddata_int', 'wrf_wps_rdhead_int', 'wrf_wps_read_int', + 'wrf_wps_write_int', 'write_matrix', 'write_table', 'yiqrgb', + 'z2geouv', 'zonal_mpsi', 'addfiles_GetVar', 'advect_variable', + 'area_conserve_remap_Wrap', 'area_hi2lores_Wrap', + 'array_append_record', 'assignFillValue', 'byte2flt', + 'byte2flt_hdf', 'calcDayAnomTLL', 'calcMonAnomLLLT', + 'calcMonAnomLLT', 'calcMonAnomTLL', 'calcMonAnomTLLL', + 'calculate_monthly_values', 'cd_convert', 'changeCase', + 'changeCaseChar', 'clmDayTLL', 'clmDayTLLL', 'clmMon2clmDay', + 'clmMonLLLT', 'clmMonLLT', 'clmMonTLL', 'clmMonTLLL', 'closest_val', + 'copy_VarAtts', 'copy_VarCoords', 'copy_VarCoords_1', + 'copy_VarCoords_2', 'copy_VarMeta', 'copyatt', 'crossp3', + 'cshstringtolist', 'cssgrid_Wrap', 'dble2flt', 'decimalPlaces', + 'delete_VarAtts', 'dim_avg_n_Wrap', 'dim_avg_wgt_n_Wrap', + 'dim_avg_wgt_Wrap', 'dim_avg_Wrap', 'dim_cumsum_n_Wrap', + 'dim_cumsum_Wrap', 'dim_max_n_Wrap', 'dim_min_n_Wrap', + 'dim_rmsd_n_Wrap', 'dim_rmsd_Wrap', 'dim_rmvmean_n_Wrap', + 'dim_rmvmean_Wrap', 'dim_rmvmed_n_Wrap', 'dim_rmvmed_Wrap', + 'dim_standardize_n_Wrap', 'dim_standardize_Wrap', + 'dim_stddev_n_Wrap', 'dim_stddev_Wrap', 'dim_sum_n_Wrap', + 'dim_sum_wgt_n_Wrap', 'dim_sum_wgt_Wrap', 'dim_sum_Wrap', + 'dim_variance_n_Wrap', 'dim_variance_Wrap', 'dpres_plevel_Wrap', + 'dtrend_leftdim', 'dv2uvF_Wrap', 'dv2uvG_Wrap', 'eof_north', + 'eofcor_Wrap', 'eofcov_Wrap', 'eofunc_north', 'eofunc_ts_Wrap', + 'eofunc_varimax_reorder', 'eofunc_varimax_Wrap', 'eofunc_Wrap', + 'epsZero', 'f2fosh_Wrap', 'f2foshv_Wrap', 'f2fsh_Wrap', + 'f2fshv_Wrap', 'f2gsh_Wrap', 'f2gshv_Wrap', 'fbindirSwap', + 'fbinseqSwap1', 'fbinseqSwap2', 'flt2dble', 'flt2string', + 'fo2fsh_Wrap', 'fo2fshv_Wrap', 'g2fsh_Wrap', 'g2fshv_Wrap', + 'g2gsh_Wrap', 'g2gshv_Wrap', 'generate_resample_indices', + 'generate_sample_indices', 'generate_unique_indices', + 'genNormalDist', 'get1Dindex', 'get1Dindex_Collapse', + 'get1Dindex_Exclude', 'get_file_suffix', 'GetFillColor', + 'GetFillColorIndex', 'getFillValue', 'getind_latlon2d', + 'getVarDimNames', 'getVarFillValue', 'grib_stime2itime', + 'hyi2hyo_Wrap', 'ilapsF_Wrap', 'ilapsG_Wrap', 'ind_nearest_coord', + 'indStrSubset', 'int2dble', 'int2flt', 'int2p_n_Wrap', 'int2p_Wrap', + 'isMonotonic', 'isStrSubset', 'latGau', 'latGauWgt', 'latGlobeF', + 'latGlobeFo', 'latRegWgt', 'linint1_n_Wrap', 'linint1_Wrap', + 'linint2_points_Wrap', 'linint2_Wrap', 'local_max_1d', + 'local_min_1d', 'lonFlip', 'lonGlobeF', 'lonGlobeFo', 'lonPivot', + 'merge_levels_sfc', 'mod', 'month_to_annual', + 'month_to_annual_weighted', 'month_to_season', 'month_to_season12', + 'month_to_seasonN', 'monthly_total_to_daily_mean', 'nameDim', + 'natgrid_Wrap', 'NewCosWeight', 'niceLatLon2D', 'NormCosWgtGlobe', + 'numAsciiCol', 'numAsciiRow', 'numeric2int', + 'obj_anal_ic_deprecated', 'obj_anal_ic_Wrap', 'omega_ccm_driver', + 'omega_to_w', 'oneDtostring', 'pack_values', 'pattern_cor', 'pdfx', + 'pdfxy', 'pdfxy_conform', 'pot_temp', 'pot_vort_hybrid', + 'pot_vort_isobaric', 'pres2hybrid_Wrap', 'print_clock', + 'printMinMax', 'quadroots', 'rcm2points_Wrap', 'rcm2rgrid_Wrap', + 'readAsciiHead', 'readAsciiTable', 'reg_multlin_stats', + 'region_ind', 'regline_stats', 'relhum_ttd', 'replaceSingleChar', + 'RGBtoCmap', 'rgrid2rcm_Wrap', 'rho_mwjf', 'rm_single_dims', + 'rmAnnCycle1D', 'rmInsufData', 'rmMonAnnCycLLLT', 'rmMonAnnCycLLT', + 'rmMonAnnCycTLL', 'runave_n_Wrap', 'runave_Wrap', 'short2flt', + 'short2flt_hdf', 'shsgc_R42_Wrap', 'sign_f90', 'sign_matlab', + 'smth9_Wrap', 'smthClmDayTLL', 'smthClmDayTLLL', 'SqrtCosWeight', + 'stat_dispersion', 'static_stability', 'stdMonLLLT', 'stdMonLLT', + 'stdMonTLL', 'stdMonTLLL', 'symMinMaxPlt', 'table_attach_columns', + 'table_attach_rows', 'time_to_newtime', 'transpose', + 'triple2grid_Wrap', 'ut_convert', 'uv2dvF_Wrap', 'uv2dvG_Wrap', + 'uv2vrF_Wrap', 'uv2vrG_Wrap', 'vr2uvF_Wrap', 'vr2uvG_Wrap', + 'w_to_omega', 'wallClockElapseTime', 'wave_number_spc', + 'wgt_areaave_Wrap', 'wgt_runave_leftdim', 'wgt_runave_n_Wrap', + 'wgt_runave_Wrap', 'wgt_vertical_n', 'wind_component', + 'wind_direction', 'yyyyddd_to_yyyymmdd', 'yyyymm_time', + 'yyyymm_to_yyyyfrac', 'yyyymmdd_time', 'yyyymmdd_to_yyyyddd', + 'yyyymmdd_to_yyyyfrac', 'yyyymmddhh_time', 'yyyymmddhh_to_yyyyfrac', + 'zonal_mpsi_Wrap', 'zonalAve', 'calendar_decode2', 'cd_string', + 'kf_filter', 'run_cor', 'time_axis_labels', 'ut_string', + 'wrf_contour', 'wrf_map', 'wrf_map_overlay', 'wrf_map_overlays', + 'wrf_map_resources', 'wrf_map_zoom', 'wrf_overlay', 'wrf_overlays', + 'wrf_user_getvar', 'wrf_user_ij_to_ll', 'wrf_user_intrp2d', + 'wrf_user_intrp3d', 'wrf_user_latlon_to_ij', 'wrf_user_list_times', + 'wrf_user_ll_to_ij', 'wrf_user_unstagger', 'wrf_user_vert_interp', + 'wrf_vector', 'gsn_add_annotation', 'gsn_add_polygon', + 'gsn_add_polyline', 'gsn_add_polymarker', + 'gsn_add_shapefile_polygons', 'gsn_add_shapefile_polylines', + 'gsn_add_shapefile_polymarkers', 'gsn_add_text', 'gsn_attach_plots', + 'gsn_blank_plot', 'gsn_contour', 'gsn_contour_map', + 'gsn_contour_shade', 'gsn_coordinates', 'gsn_create_labelbar', + 'gsn_create_legend', 'gsn_create_text', + 'gsn_csm_attach_zonal_means', 'gsn_csm_blank_plot', + 'gsn_csm_contour', 'gsn_csm_contour_map', 'gsn_csm_contour_map_ce', + 'gsn_csm_contour_map_overlay', 'gsn_csm_contour_map_polar', + 'gsn_csm_hov', 'gsn_csm_lat_time', 'gsn_csm_map', 'gsn_csm_map_ce', + 'gsn_csm_map_polar', 'gsn_csm_pres_hgt', + 'gsn_csm_pres_hgt_streamline', 'gsn_csm_pres_hgt_vector', + 'gsn_csm_streamline', 'gsn_csm_streamline_contour_map', + 'gsn_csm_streamline_contour_map_ce', + 'gsn_csm_streamline_contour_map_polar', 'gsn_csm_streamline_map', + 'gsn_csm_streamline_map_ce', 'gsn_csm_streamline_map_polar', + 'gsn_csm_streamline_scalar', 'gsn_csm_streamline_scalar_map', + 'gsn_csm_streamline_scalar_map_ce', + 'gsn_csm_streamline_scalar_map_polar', 'gsn_csm_time_lat', + 'gsn_csm_vector', 'gsn_csm_vector_map', 'gsn_csm_vector_map_ce', + 'gsn_csm_vector_map_polar', 'gsn_csm_vector_scalar', + 'gsn_csm_vector_scalar_map', 'gsn_csm_vector_scalar_map_ce', + 'gsn_csm_vector_scalar_map_polar', 'gsn_csm_x2y', 'gsn_csm_x2y2', + 'gsn_csm_xy', 'gsn_csm_xy2', 'gsn_csm_xy3', 'gsn_csm_y', + 'gsn_define_colormap', 'gsn_draw_colormap', 'gsn_draw_named_colors', + 'gsn_histogram', 'gsn_labelbar_ndc', 'gsn_legend_ndc', 'gsn_map', + 'gsn_merge_colormaps', 'gsn_open_wks', 'gsn_panel', 'gsn_polygon', + 'gsn_polygon_ndc', 'gsn_polyline', 'gsn_polyline_ndc', + 'gsn_polymarker', 'gsn_polymarker_ndc', 'gsn_retrieve_colormap', + 'gsn_reverse_colormap', 'gsn_streamline', 'gsn_streamline_map', + 'gsn_streamline_scalar', 'gsn_streamline_scalar_map', 'gsn_table', + 'gsn_text', 'gsn_text_ndc', 'gsn_vector', 'gsn_vector_map', + 'gsn_vector_scalar', 'gsn_vector_scalar_map', 'gsn_xy', 'gsn_y', + 'hsv2rgb', 'maximize_output', 'namedcolor2rgb', 'namedcolor2rgba', + 'reset_device_coordinates', 'span_named_colors'), prefix=r'\b'), + Name.Builtin), + + # Resources + (words(( + 'amDataXF', 'amDataYF', 'amJust', 'amOn', 'amOrthogonalPosF', + 'amParallelPosF', 'amResizeNotify', 'amSide', 'amTrackData', + 'amViewId', 'amZone', 'appDefaultParent', 'appFileSuffix', + 'appResources', 'appSysDir', 'appUsrDir', 'caCopyArrays', + 'caXArray', 'caXCast', 'caXMaxV', 'caXMinV', 'caXMissingV', + 'caYArray', 'caYCast', 'caYMaxV', 'caYMinV', 'caYMissingV', + 'cnCellFillEdgeColor', 'cnCellFillMissingValEdgeColor', + 'cnConpackParams', 'cnConstFEnableFill', 'cnConstFLabelAngleF', + 'cnConstFLabelBackgroundColor', 'cnConstFLabelConstantSpacingF', + 'cnConstFLabelFont', 'cnConstFLabelFontAspectF', + 'cnConstFLabelFontColor', 'cnConstFLabelFontHeightF', + 'cnConstFLabelFontQuality', 'cnConstFLabelFontThicknessF', + 'cnConstFLabelFormat', 'cnConstFLabelFuncCode', 'cnConstFLabelJust', + 'cnConstFLabelOn', 'cnConstFLabelOrthogonalPosF', + 'cnConstFLabelParallelPosF', 'cnConstFLabelPerimColor', + 'cnConstFLabelPerimOn', 'cnConstFLabelPerimSpaceF', + 'cnConstFLabelPerimThicknessF', 'cnConstFLabelSide', + 'cnConstFLabelString', 'cnConstFLabelTextDirection', + 'cnConstFLabelZone', 'cnConstFUseInfoLabelRes', + 'cnExplicitLabelBarLabelsOn', 'cnExplicitLegendLabelsOn', + 'cnExplicitLineLabelsOn', 'cnFillBackgroundColor', 'cnFillColor', + 'cnFillColors', 'cnFillDotSizeF', 'cnFillDrawOrder', 'cnFillMode', + 'cnFillOn', 'cnFillOpacityF', 'cnFillPalette', 'cnFillPattern', + 'cnFillPatterns', 'cnFillScaleF', 'cnFillScales', 'cnFixFillBleed', + 'cnGridBoundFillColor', 'cnGridBoundFillPattern', + 'cnGridBoundFillScaleF', 'cnGridBoundPerimColor', + 'cnGridBoundPerimDashPattern', 'cnGridBoundPerimOn', + 'cnGridBoundPerimThicknessF', 'cnHighLabelAngleF', + 'cnHighLabelBackgroundColor', 'cnHighLabelConstantSpacingF', + 'cnHighLabelCount', 'cnHighLabelFont', 'cnHighLabelFontAspectF', + 'cnHighLabelFontColor', 'cnHighLabelFontHeightF', + 'cnHighLabelFontQuality', 'cnHighLabelFontThicknessF', + 'cnHighLabelFormat', 'cnHighLabelFuncCode', 'cnHighLabelPerimColor', + 'cnHighLabelPerimOn', 'cnHighLabelPerimSpaceF', + 'cnHighLabelPerimThicknessF', 'cnHighLabelString', 'cnHighLabelsOn', + 'cnHighLowLabelOverlapMode', 'cnHighUseLineLabelRes', + 'cnInfoLabelAngleF', 'cnInfoLabelBackgroundColor', + 'cnInfoLabelConstantSpacingF', 'cnInfoLabelFont', + 'cnInfoLabelFontAspectF', 'cnInfoLabelFontColor', + 'cnInfoLabelFontHeightF', 'cnInfoLabelFontQuality', + 'cnInfoLabelFontThicknessF', 'cnInfoLabelFormat', + 'cnInfoLabelFuncCode', 'cnInfoLabelJust', 'cnInfoLabelOn', + 'cnInfoLabelOrthogonalPosF', 'cnInfoLabelParallelPosF', + 'cnInfoLabelPerimColor', 'cnInfoLabelPerimOn', + 'cnInfoLabelPerimSpaceF', 'cnInfoLabelPerimThicknessF', + 'cnInfoLabelSide', 'cnInfoLabelString', 'cnInfoLabelTextDirection', + 'cnInfoLabelZone', 'cnLabelBarEndLabelsOn', 'cnLabelBarEndStyle', + 'cnLabelDrawOrder', 'cnLabelMasking', 'cnLabelScaleFactorF', + 'cnLabelScaleValueF', 'cnLabelScalingMode', 'cnLegendLevelFlags', + 'cnLevelCount', 'cnLevelFlag', 'cnLevelFlags', 'cnLevelSelectionMode', + 'cnLevelSpacingF', 'cnLevels', 'cnLineColor', 'cnLineColors', + 'cnLineDashPattern', 'cnLineDashPatterns', 'cnLineDashSegLenF', + 'cnLineDrawOrder', 'cnLineLabelAngleF', 'cnLineLabelBackgroundColor', + 'cnLineLabelConstantSpacingF', 'cnLineLabelCount', + 'cnLineLabelDensityF', 'cnLineLabelFont', 'cnLineLabelFontAspectF', + 'cnLineLabelFontColor', 'cnLineLabelFontColors', + 'cnLineLabelFontHeightF', 'cnLineLabelFontQuality', + 'cnLineLabelFontThicknessF', 'cnLineLabelFormat', + 'cnLineLabelFuncCode', 'cnLineLabelInterval', 'cnLineLabelPerimColor', + 'cnLineLabelPerimOn', 'cnLineLabelPerimSpaceF', + 'cnLineLabelPerimThicknessF', 'cnLineLabelPlacementMode', + 'cnLineLabelStrings', 'cnLineLabelsOn', 'cnLinePalette', + 'cnLineThicknessF', 'cnLineThicknesses', 'cnLinesOn', + 'cnLowLabelAngleF', 'cnLowLabelBackgroundColor', + 'cnLowLabelConstantSpacingF', 'cnLowLabelCount', 'cnLowLabelFont', + 'cnLowLabelFontAspectF', 'cnLowLabelFontColor', + 'cnLowLabelFontHeightF', 'cnLowLabelFontQuality', + 'cnLowLabelFontThicknessF', 'cnLowLabelFormat', 'cnLowLabelFuncCode', + 'cnLowLabelPerimColor', 'cnLowLabelPerimOn', 'cnLowLabelPerimSpaceF', + 'cnLowLabelPerimThicknessF', 'cnLowLabelString', 'cnLowLabelsOn', + 'cnLowUseHighLabelRes', 'cnMaxDataValueFormat', 'cnMaxLevelCount', + 'cnMaxLevelValF', 'cnMaxPointDistanceF', 'cnMinLevelValF', + 'cnMissingValFillColor', 'cnMissingValFillPattern', + 'cnMissingValFillScaleF', 'cnMissingValPerimColor', + 'cnMissingValPerimDashPattern', 'cnMissingValPerimGridBoundOn', + 'cnMissingValPerimOn', 'cnMissingValPerimThicknessF', + 'cnMonoFillColor', 'cnMonoFillPattern', 'cnMonoFillScale', + 'cnMonoLevelFlag', 'cnMonoLineColor', 'cnMonoLineDashPattern', + 'cnMonoLineLabelFontColor', 'cnMonoLineThickness', 'cnNoDataLabelOn', + 'cnNoDataLabelString', 'cnOutOfRangeFillColor', + 'cnOutOfRangeFillPattern', 'cnOutOfRangeFillScaleF', + 'cnOutOfRangePerimColor', 'cnOutOfRangePerimDashPattern', + 'cnOutOfRangePerimOn', 'cnOutOfRangePerimThicknessF', + 'cnRasterCellSizeF', 'cnRasterMinCellSizeF', 'cnRasterModeOn', + 'cnRasterSampleFactorF', 'cnRasterSmoothingOn', 'cnScalarFieldData', + 'cnSmoothingDistanceF', 'cnSmoothingOn', 'cnSmoothingTensionF', + 'cnSpanFillPalette', 'cnSpanLinePalette', 'ctCopyTables', + 'ctXElementSize', 'ctXMaxV', 'ctXMinV', 'ctXMissingV', 'ctXTable', + 'ctXTableLengths', 'ctXTableType', 'ctYElementSize', 'ctYMaxV', + 'ctYMinV', 'ctYMissingV', 'ctYTable', 'ctYTableLengths', + 'ctYTableType', 'dcDelayCompute', 'errBuffer', + 'errFileName', 'errFilePtr', 'errLevel', 'errPrint', 'errUnitNumber', + 'gsClipOn', 'gsColors', 'gsEdgeColor', 'gsEdgeDashPattern', + 'gsEdgeDashSegLenF', 'gsEdgeThicknessF', 'gsEdgesOn', + 'gsFillBackgroundColor', 'gsFillColor', 'gsFillDotSizeF', + 'gsFillIndex', 'gsFillLineThicknessF', 'gsFillOpacityF', + 'gsFillScaleF', 'gsFont', 'gsFontAspectF', 'gsFontColor', + 'gsFontHeightF', 'gsFontOpacityF', 'gsFontQuality', + 'gsFontThicknessF', 'gsLineColor', 'gsLineDashPattern', + 'gsLineDashSegLenF', 'gsLineLabelConstantSpacingF', 'gsLineLabelFont', + 'gsLineLabelFontAspectF', 'gsLineLabelFontColor', + 'gsLineLabelFontHeightF', 'gsLineLabelFontQuality', + 'gsLineLabelFontThicknessF', 'gsLineLabelFuncCode', + 'gsLineLabelString', 'gsLineOpacityF', 'gsLineThicknessF', + 'gsMarkerColor', 'gsMarkerIndex', 'gsMarkerOpacityF', 'gsMarkerSizeF', + 'gsMarkerThicknessF', 'gsSegments', 'gsTextAngleF', + 'gsTextConstantSpacingF', 'gsTextDirection', 'gsTextFuncCode', + 'gsTextJustification', 'gsnAboveYRefLineBarColors', + 'gsnAboveYRefLineBarFillScales', 'gsnAboveYRefLineBarPatterns', + 'gsnAboveYRefLineColor', 'gsnAddCyclic', 'gsnAttachBorderOn', + 'gsnAttachPlotsXAxis', 'gsnBelowYRefLineBarColors', + 'gsnBelowYRefLineBarFillScales', 'gsnBelowYRefLineBarPatterns', + 'gsnBelowYRefLineColor', 'gsnBoxMargin', 'gsnCenterString', + 'gsnCenterStringFontColor', 'gsnCenterStringFontHeightF', + 'gsnCenterStringFuncCode', 'gsnCenterStringOrthogonalPosF', + 'gsnCenterStringParallelPosF', 'gsnContourLineThicknessesScale', + 'gsnContourNegLineDashPattern', 'gsnContourPosLineDashPattern', + 'gsnContourZeroLineThicknessF', 'gsnDebugWriteFileName', 'gsnDraw', + 'gsnFrame', 'gsnHistogramBarWidthPercent', 'gsnHistogramBinIntervals', + 'gsnHistogramBinMissing', 'gsnHistogramBinWidth', + 'gsnHistogramClassIntervals', 'gsnHistogramCompare', + 'gsnHistogramComputePercentages', + 'gsnHistogramComputePercentagesNoMissing', + 'gsnHistogramDiscreteBinValues', 'gsnHistogramDiscreteClassValues', + 'gsnHistogramHorizontal', 'gsnHistogramMinMaxBinsOn', + 'gsnHistogramNumberOfBins', 'gsnHistogramPercentSign', + 'gsnHistogramSelectNiceIntervals', 'gsnLeftString', + 'gsnLeftStringFontColor', 'gsnLeftStringFontHeightF', + 'gsnLeftStringFuncCode', 'gsnLeftStringOrthogonalPosF', + 'gsnLeftStringParallelPosF', 'gsnMajorLatSpacing', + 'gsnMajorLonSpacing', 'gsnMaskLambertConformal', + 'gsnMaskLambertConformalOutlineOn', 'gsnMaximize', + 'gsnMinorLatSpacing', 'gsnMinorLonSpacing', 'gsnPanelBottom', + 'gsnPanelCenter', 'gsnPanelDebug', 'gsnPanelFigureStrings', + 'gsnPanelFigureStringsBackgroundFillColor', + 'gsnPanelFigureStringsFontHeightF', 'gsnPanelFigureStringsJust', + 'gsnPanelFigureStringsPerimOn', 'gsnPanelLabelBar', 'gsnPanelLeft', + 'gsnPanelMainFont', 'gsnPanelMainFontColor', + 'gsnPanelMainFontHeightF', 'gsnPanelMainString', 'gsnPanelRight', + 'gsnPanelRowSpec', 'gsnPanelScalePlotIndex', 'gsnPanelTop', + 'gsnPanelXF', 'gsnPanelXWhiteSpacePercent', 'gsnPanelYF', + 'gsnPanelYWhiteSpacePercent', 'gsnPaperHeight', 'gsnPaperMargin', + 'gsnPaperOrientation', 'gsnPaperWidth', 'gsnPolar', + 'gsnPolarLabelDistance', 'gsnPolarLabelFont', + 'gsnPolarLabelFontHeightF', 'gsnPolarLabelSpacing', 'gsnPolarTime', + 'gsnPolarUT', 'gsnRightString', 'gsnRightStringFontColor', + 'gsnRightStringFontHeightF', 'gsnRightStringFuncCode', + 'gsnRightStringOrthogonalPosF', 'gsnRightStringParallelPosF', + 'gsnScalarContour', 'gsnScale', 'gsnShape', 'gsnSpreadColorEnd', + 'gsnSpreadColorStart', 'gsnSpreadColors', 'gsnStringFont', + 'gsnStringFontColor', 'gsnStringFontHeightF', 'gsnStringFuncCode', + 'gsnTickMarksOn', 'gsnXAxisIrregular2Linear', 'gsnXAxisIrregular2Log', + 'gsnXRefLine', 'gsnXRefLineColor', 'gsnXRefLineDashPattern', + 'gsnXRefLineThicknessF', 'gsnXYAboveFillColors', 'gsnXYBarChart', + 'gsnXYBarChartBarWidth', 'gsnXYBarChartColors', + 'gsnXYBarChartColors2', 'gsnXYBarChartFillDotSizeF', + 'gsnXYBarChartFillLineThicknessF', 'gsnXYBarChartFillOpacityF', + 'gsnXYBarChartFillScaleF', 'gsnXYBarChartOutlineOnly', + 'gsnXYBarChartOutlineThicknessF', 'gsnXYBarChartPatterns', + 'gsnXYBarChartPatterns2', 'gsnXYBelowFillColors', 'gsnXYFillColors', + 'gsnXYFillOpacities', 'gsnXYLeftFillColors', 'gsnXYRightFillColors', + 'gsnYAxisIrregular2Linear', 'gsnYAxisIrregular2Log', 'gsnYRefLine', + 'gsnYRefLineColor', 'gsnYRefLineColors', 'gsnYRefLineDashPattern', + 'gsnYRefLineDashPatterns', 'gsnYRefLineThicknessF', + 'gsnYRefLineThicknesses', 'gsnZonalMean', 'gsnZonalMeanXMaxF', + 'gsnZonalMeanXMinF', 'gsnZonalMeanYRefLine', 'lbAutoManage', + 'lbBottomMarginF', 'lbBoxCount', 'lbBoxEndCapStyle', 'lbBoxFractions', + 'lbBoxLineColor', 'lbBoxLineDashPattern', 'lbBoxLineDashSegLenF', + 'lbBoxLineThicknessF', 'lbBoxLinesOn', 'lbBoxMajorExtentF', + 'lbBoxMinorExtentF', 'lbBoxSeparatorLinesOn', 'lbBoxSizing', + 'lbFillBackground', 'lbFillColor', 'lbFillColors', 'lbFillDotSizeF', + 'lbFillLineThicknessF', 'lbFillPattern', 'lbFillPatterns', + 'lbFillScaleF', 'lbFillScales', 'lbJustification', 'lbLabelAlignment', + 'lbLabelAngleF', 'lbLabelAutoStride', 'lbLabelBarOn', + 'lbLabelConstantSpacingF', 'lbLabelDirection', 'lbLabelFont', + 'lbLabelFontAspectF', 'lbLabelFontColor', 'lbLabelFontHeightF', + 'lbLabelFontQuality', 'lbLabelFontThicknessF', 'lbLabelFuncCode', + 'lbLabelJust', 'lbLabelOffsetF', 'lbLabelPosition', 'lbLabelStride', + 'lbLabelStrings', 'lbLabelsOn', 'lbLeftMarginF', 'lbMaxLabelLenF', + 'lbMinLabelSpacingF', 'lbMonoFillColor', 'lbMonoFillPattern', + 'lbMonoFillScale', 'lbOrientation', 'lbPerimColor', + 'lbPerimDashPattern', 'lbPerimDashSegLenF', 'lbPerimFill', + 'lbPerimFillColor', 'lbPerimOn', 'lbPerimThicknessF', + 'lbRasterFillOn', 'lbRightMarginF', 'lbTitleAngleF', + 'lbTitleConstantSpacingF', 'lbTitleDirection', 'lbTitleExtentF', + 'lbTitleFont', 'lbTitleFontAspectF', 'lbTitleFontColor', + 'lbTitleFontHeightF', 'lbTitleFontQuality', 'lbTitleFontThicknessF', + 'lbTitleFuncCode', 'lbTitleJust', 'lbTitleOffsetF', 'lbTitleOn', + 'lbTitlePosition', 'lbTitleString', 'lbTopMarginF', 'lgAutoManage', + 'lgBottomMarginF', 'lgBoxBackground', 'lgBoxLineColor', + 'lgBoxLineDashPattern', 'lgBoxLineDashSegLenF', 'lgBoxLineThicknessF', + 'lgBoxLinesOn', 'lgBoxMajorExtentF', 'lgBoxMinorExtentF', + 'lgDashIndex', 'lgDashIndexes', 'lgItemCount', 'lgItemOrder', + 'lgItemPlacement', 'lgItemPositions', 'lgItemType', 'lgItemTypes', + 'lgJustification', 'lgLabelAlignment', 'lgLabelAngleF', + 'lgLabelAutoStride', 'lgLabelConstantSpacingF', 'lgLabelDirection', + 'lgLabelFont', 'lgLabelFontAspectF', 'lgLabelFontColor', + 'lgLabelFontHeightF', 'lgLabelFontQuality', 'lgLabelFontThicknessF', + 'lgLabelFuncCode', 'lgLabelJust', 'lgLabelOffsetF', 'lgLabelPosition', + 'lgLabelStride', 'lgLabelStrings', 'lgLabelsOn', 'lgLeftMarginF', + 'lgLegendOn', 'lgLineColor', 'lgLineColors', 'lgLineDashSegLenF', + 'lgLineDashSegLens', 'lgLineLabelConstantSpacingF', 'lgLineLabelFont', + 'lgLineLabelFontAspectF', 'lgLineLabelFontColor', + 'lgLineLabelFontColors', 'lgLineLabelFontHeightF', + 'lgLineLabelFontHeights', 'lgLineLabelFontQuality', + 'lgLineLabelFontThicknessF', 'lgLineLabelFuncCode', + 'lgLineLabelStrings', 'lgLineLabelsOn', 'lgLineThicknessF', + 'lgLineThicknesses', 'lgMarkerColor', 'lgMarkerColors', + 'lgMarkerIndex', 'lgMarkerIndexes', 'lgMarkerSizeF', 'lgMarkerSizes', + 'lgMarkerThicknessF', 'lgMarkerThicknesses', 'lgMonoDashIndex', + 'lgMonoItemType', 'lgMonoLineColor', 'lgMonoLineDashSegLen', + 'lgMonoLineLabelFontColor', 'lgMonoLineLabelFontHeight', + 'lgMonoLineThickness', 'lgMonoMarkerColor', 'lgMonoMarkerIndex', + 'lgMonoMarkerSize', 'lgMonoMarkerThickness', 'lgOrientation', + 'lgPerimColor', 'lgPerimDashPattern', 'lgPerimDashSegLenF', + 'lgPerimFill', 'lgPerimFillColor', 'lgPerimOn', 'lgPerimThicknessF', + 'lgRightMarginF', 'lgTitleAngleF', 'lgTitleConstantSpacingF', + 'lgTitleDirection', 'lgTitleExtentF', 'lgTitleFont', + 'lgTitleFontAspectF', 'lgTitleFontColor', 'lgTitleFontHeightF', + 'lgTitleFontQuality', 'lgTitleFontThicknessF', 'lgTitleFuncCode', + 'lgTitleJust', 'lgTitleOffsetF', 'lgTitleOn', 'lgTitlePosition', + 'lgTitleString', 'lgTopMarginF', 'mpAreaGroupCount', + 'mpAreaMaskingOn', 'mpAreaNames', 'mpAreaTypes', 'mpBottomAngleF', + 'mpBottomMapPosF', 'mpBottomNDCF', 'mpBottomNPCF', + 'mpBottomPointLatF', 'mpBottomPointLonF', 'mpBottomWindowF', + 'mpCenterLatF', 'mpCenterLonF', 'mpCenterRotF', 'mpCountyLineColor', + 'mpCountyLineDashPattern', 'mpCountyLineDashSegLenF', + 'mpCountyLineThicknessF', 'mpDataBaseVersion', 'mpDataResolution', + 'mpDataSetName', 'mpDefaultFillColor', 'mpDefaultFillPattern', + 'mpDefaultFillScaleF', 'mpDynamicAreaGroups', 'mpEllipticalBoundary', + 'mpFillAreaSpecifiers', 'mpFillBoundarySets', 'mpFillColor', + 'mpFillColors', 'mpFillColors-default', 'mpFillDotSizeF', + 'mpFillDrawOrder', 'mpFillOn', 'mpFillPatternBackground', + 'mpFillPattern', 'mpFillPatterns', 'mpFillPatterns-default', + 'mpFillScaleF', 'mpFillScales', 'mpFillScales-default', + 'mpFixedAreaGroups', 'mpGeophysicalLineColor', + 'mpGeophysicalLineDashPattern', 'mpGeophysicalLineDashSegLenF', + 'mpGeophysicalLineThicknessF', 'mpGreatCircleLinesOn', + 'mpGridAndLimbDrawOrder', 'mpGridAndLimbOn', 'mpGridLatSpacingF', + 'mpGridLineColor', 'mpGridLineDashPattern', 'mpGridLineDashSegLenF', + 'mpGridLineThicknessF', 'mpGridLonSpacingF', 'mpGridMaskMode', + 'mpGridMaxLatF', 'mpGridPolarLonSpacingF', 'mpGridSpacingF', + 'mpInlandWaterFillColor', 'mpInlandWaterFillPattern', + 'mpInlandWaterFillScaleF', 'mpLabelDrawOrder', 'mpLabelFontColor', + 'mpLabelFontHeightF', 'mpLabelsOn', 'mpLambertMeridianF', + 'mpLambertParallel1F', 'mpLambertParallel2F', 'mpLandFillColor', + 'mpLandFillPattern', 'mpLandFillScaleF', 'mpLeftAngleF', + 'mpLeftCornerLatF', 'mpLeftCornerLonF', 'mpLeftMapPosF', + 'mpLeftNDCF', 'mpLeftNPCF', 'mpLeftPointLatF', + 'mpLeftPointLonF', 'mpLeftWindowF', 'mpLimbLineColor', + 'mpLimbLineDashPattern', 'mpLimbLineDashSegLenF', + 'mpLimbLineThicknessF', 'mpLimitMode', 'mpMaskAreaSpecifiers', + 'mpMaskOutlineSpecifiers', 'mpMaxLatF', 'mpMaxLonF', + 'mpMinLatF', 'mpMinLonF', 'mpMonoFillColor', 'mpMonoFillPattern', + 'mpMonoFillScale', 'mpNationalLineColor', 'mpNationalLineDashPattern', + 'mpNationalLineThicknessF', 'mpOceanFillColor', 'mpOceanFillPattern', + 'mpOceanFillScaleF', 'mpOutlineBoundarySets', 'mpOutlineDrawOrder', + 'mpOutlineMaskingOn', 'mpOutlineOn', 'mpOutlineSpecifiers', + 'mpPerimDrawOrder', 'mpPerimLineColor', 'mpPerimLineDashPattern', + 'mpPerimLineDashSegLenF', 'mpPerimLineThicknessF', 'mpPerimOn', + 'mpPolyMode', 'mpProjection', 'mpProvincialLineColor', + 'mpProvincialLineDashPattern', 'mpProvincialLineDashSegLenF', + 'mpProvincialLineThicknessF', 'mpRelativeCenterLat', + 'mpRelativeCenterLon', 'mpRightAngleF', 'mpRightCornerLatF', + 'mpRightCornerLonF', 'mpRightMapPosF', 'mpRightNDCF', + 'mpRightNPCF', 'mpRightPointLatF', 'mpRightPointLonF', + 'mpRightWindowF', 'mpSatelliteAngle1F', 'mpSatelliteAngle2F', + 'mpSatelliteDistF', 'mpShapeMode', 'mpSpecifiedFillColors', + 'mpSpecifiedFillDirectIndexing', 'mpSpecifiedFillPatterns', + 'mpSpecifiedFillPriority', 'mpSpecifiedFillScales', + 'mpTopAngleF', 'mpTopMapPosF', 'mpTopNDCF', 'mpTopNPCF', + 'mpTopPointLatF', 'mpTopPointLonF', 'mpTopWindowF', + 'mpUSStateLineColor', 'mpUSStateLineDashPattern', + 'mpUSStateLineDashSegLenF', 'mpUSStateLineThicknessF', + 'pmAnnoManagers', 'pmAnnoViews', 'pmLabelBarDisplayMode', + 'pmLabelBarHeightF', 'pmLabelBarKeepAspect', 'pmLabelBarOrthogonalPosF', + 'pmLabelBarParallelPosF', 'pmLabelBarSide', 'pmLabelBarWidthF', + 'pmLabelBarZone', 'pmLegendDisplayMode', 'pmLegendHeightF', + 'pmLegendKeepAspect', 'pmLegendOrthogonalPosF', + 'pmLegendParallelPosF', 'pmLegendSide', 'pmLegendWidthF', + 'pmLegendZone', 'pmOverlaySequenceIds', 'pmTickMarkDisplayMode', + 'pmTickMarkZone', 'pmTitleDisplayMode', 'pmTitleZone', + 'prGraphicStyle', 'prPolyType', 'prXArray', 'prYArray', + 'sfCopyData', 'sfDataArray', 'sfDataMaxV', 'sfDataMinV', + 'sfElementNodes', 'sfExchangeDimensions', 'sfFirstNodeIndex', + 'sfMissingValueV', 'sfXArray', 'sfXCActualEndF', 'sfXCActualStartF', + 'sfXCEndIndex', 'sfXCEndSubsetV', 'sfXCEndV', 'sfXCStartIndex', + 'sfXCStartSubsetV', 'sfXCStartV', 'sfXCStride', 'sfXCellBounds', + 'sfYArray', 'sfYCActualEndF', 'sfYCActualStartF', 'sfYCEndIndex', + 'sfYCEndSubsetV', 'sfYCEndV', 'sfYCStartIndex', 'sfYCStartSubsetV', + 'sfYCStartV', 'sfYCStride', 'sfYCellBounds', 'stArrowLengthF', + 'stArrowStride', 'stCrossoverCheckCount', + 'stExplicitLabelBarLabelsOn', 'stLabelBarEndLabelsOn', + 'stLabelFormat', 'stLengthCheckCount', 'stLevelColors', + 'stLevelCount', 'stLevelPalette', 'stLevelSelectionMode', + 'stLevelSpacingF', 'stLevels', 'stLineColor', 'stLineOpacityF', + 'stLineStartStride', 'stLineThicknessF', 'stMapDirection', + 'stMaxLevelCount', 'stMaxLevelValF', 'stMinArrowSpacingF', + 'stMinDistanceF', 'stMinLevelValF', 'stMinLineSpacingF', + 'stMinStepFactorF', 'stMonoLineColor', 'stNoDataLabelOn', + 'stNoDataLabelString', 'stScalarFieldData', 'stScalarMissingValColor', + 'stSpanLevelPalette', 'stStepSizeF', 'stStreamlineDrawOrder', + 'stUseScalarArray', 'stVectorFieldData', 'stZeroFLabelAngleF', + 'stZeroFLabelBackgroundColor', 'stZeroFLabelConstantSpacingF', + 'stZeroFLabelFont', 'stZeroFLabelFontAspectF', + 'stZeroFLabelFontColor', 'stZeroFLabelFontHeightF', + 'stZeroFLabelFontQuality', 'stZeroFLabelFontThicknessF', + 'stZeroFLabelFuncCode', 'stZeroFLabelJust', 'stZeroFLabelOn', + 'stZeroFLabelOrthogonalPosF', 'stZeroFLabelParallelPosF', + 'stZeroFLabelPerimColor', 'stZeroFLabelPerimOn', + 'stZeroFLabelPerimSpaceF', 'stZeroFLabelPerimThicknessF', + 'stZeroFLabelSide', 'stZeroFLabelString', 'stZeroFLabelTextDirection', + 'stZeroFLabelZone', 'tfDoNDCOverlay', 'tfPlotManagerOn', + 'tfPolyDrawList', 'tfPolyDrawOrder', 'tiDeltaF', 'tiMainAngleF', + 'tiMainConstantSpacingF', 'tiMainDirection', 'tiMainFont', + 'tiMainFontAspectF', 'tiMainFontColor', 'tiMainFontHeightF', + 'tiMainFontQuality', 'tiMainFontThicknessF', 'tiMainFuncCode', + 'tiMainJust', 'tiMainOffsetXF', 'tiMainOffsetYF', 'tiMainOn', + 'tiMainPosition', 'tiMainSide', 'tiMainString', 'tiUseMainAttributes', + 'tiXAxisAngleF', 'tiXAxisConstantSpacingF', 'tiXAxisDirection', + 'tiXAxisFont', 'tiXAxisFontAspectF', 'tiXAxisFontColor', + 'tiXAxisFontHeightF', 'tiXAxisFontQuality', 'tiXAxisFontThicknessF', + 'tiXAxisFuncCode', 'tiXAxisJust', 'tiXAxisOffsetXF', + 'tiXAxisOffsetYF', 'tiXAxisOn', 'tiXAxisPosition', 'tiXAxisSide', + 'tiXAxisString', 'tiYAxisAngleF', 'tiYAxisConstantSpacingF', + 'tiYAxisDirection', 'tiYAxisFont', 'tiYAxisFontAspectF', + 'tiYAxisFontColor', 'tiYAxisFontHeightF', 'tiYAxisFontQuality', + 'tiYAxisFontThicknessF', 'tiYAxisFuncCode', 'tiYAxisJust', + 'tiYAxisOffsetXF', 'tiYAxisOffsetYF', 'tiYAxisOn', 'tiYAxisPosition', + 'tiYAxisSide', 'tiYAxisString', 'tmBorderLineColor', + 'tmBorderThicknessF', 'tmEqualizeXYSizes', 'tmLabelAutoStride', + 'tmSciNoteCutoff', 'tmXBAutoPrecision', 'tmXBBorderOn', + 'tmXBDataLeftF', 'tmXBDataRightF', 'tmXBFormat', 'tmXBIrrTensionF', + 'tmXBIrregularPoints', 'tmXBLabelAngleF', 'tmXBLabelConstantSpacingF', + 'tmXBLabelDeltaF', 'tmXBLabelDirection', 'tmXBLabelFont', + 'tmXBLabelFontAspectF', 'tmXBLabelFontColor', 'tmXBLabelFontHeightF', + 'tmXBLabelFontQuality', 'tmXBLabelFontThicknessF', + 'tmXBLabelFuncCode', 'tmXBLabelJust', 'tmXBLabelStride', 'tmXBLabels', + 'tmXBLabelsOn', 'tmXBMajorLengthF', 'tmXBMajorLineColor', + 'tmXBMajorOutwardLengthF', 'tmXBMajorThicknessF', 'tmXBMaxLabelLenF', + 'tmXBMaxTicks', 'tmXBMinLabelSpacingF', 'tmXBMinorLengthF', + 'tmXBMinorLineColor', 'tmXBMinorOn', 'tmXBMinorOutwardLengthF', + 'tmXBMinorPerMajor', 'tmXBMinorThicknessF', 'tmXBMinorValues', + 'tmXBMode', 'tmXBOn', 'tmXBPrecision', 'tmXBStyle', 'tmXBTickEndF', + 'tmXBTickSpacingF', 'tmXBTickStartF', 'tmXBValues', 'tmXMajorGrid', + 'tmXMajorGridLineColor', 'tmXMajorGridLineDashPattern', + 'tmXMajorGridThicknessF', 'tmXMinorGrid', 'tmXMinorGridLineColor', + 'tmXMinorGridLineDashPattern', 'tmXMinorGridThicknessF', + 'tmXTAutoPrecision', 'tmXTBorderOn', 'tmXTDataLeftF', + 'tmXTDataRightF', 'tmXTFormat', 'tmXTIrrTensionF', + 'tmXTIrregularPoints', 'tmXTLabelAngleF', 'tmXTLabelConstantSpacingF', + 'tmXTLabelDeltaF', 'tmXTLabelDirection', 'tmXTLabelFont', + 'tmXTLabelFontAspectF', 'tmXTLabelFontColor', 'tmXTLabelFontHeightF', + 'tmXTLabelFontQuality', 'tmXTLabelFontThicknessF', + 'tmXTLabelFuncCode', 'tmXTLabelJust', 'tmXTLabelStride', 'tmXTLabels', + 'tmXTLabelsOn', 'tmXTMajorLengthF', 'tmXTMajorLineColor', + 'tmXTMajorOutwardLengthF', 'tmXTMajorThicknessF', 'tmXTMaxLabelLenF', + 'tmXTMaxTicks', 'tmXTMinLabelSpacingF', 'tmXTMinorLengthF', + 'tmXTMinorLineColor', 'tmXTMinorOn', 'tmXTMinorOutwardLengthF', + 'tmXTMinorPerMajor', 'tmXTMinorThicknessF', 'tmXTMinorValues', + 'tmXTMode', 'tmXTOn', 'tmXTPrecision', 'tmXTStyle', 'tmXTTickEndF', + 'tmXTTickSpacingF', 'tmXTTickStartF', 'tmXTValues', 'tmXUseBottom', + 'tmYLAutoPrecision', 'tmYLBorderOn', 'tmYLDataBottomF', + 'tmYLDataTopF', 'tmYLFormat', 'tmYLIrrTensionF', + 'tmYLIrregularPoints', 'tmYLLabelAngleF', 'tmYLLabelConstantSpacingF', + 'tmYLLabelDeltaF', 'tmYLLabelDirection', 'tmYLLabelFont', + 'tmYLLabelFontAspectF', 'tmYLLabelFontColor', 'tmYLLabelFontHeightF', + 'tmYLLabelFontQuality', 'tmYLLabelFontThicknessF', + 'tmYLLabelFuncCode', 'tmYLLabelJust', 'tmYLLabelStride', 'tmYLLabels', + 'tmYLLabelsOn', 'tmYLMajorLengthF', 'tmYLMajorLineColor', + 'tmYLMajorOutwardLengthF', 'tmYLMajorThicknessF', 'tmYLMaxLabelLenF', + 'tmYLMaxTicks', 'tmYLMinLabelSpacingF', 'tmYLMinorLengthF', + 'tmYLMinorLineColor', 'tmYLMinorOn', 'tmYLMinorOutwardLengthF', + 'tmYLMinorPerMajor', 'tmYLMinorThicknessF', 'tmYLMinorValues', + 'tmYLMode', 'tmYLOn', 'tmYLPrecision', 'tmYLStyle', 'tmYLTickEndF', + 'tmYLTickSpacingF', 'tmYLTickStartF', 'tmYLValues', 'tmYMajorGrid', + 'tmYMajorGridLineColor', 'tmYMajorGridLineDashPattern', + 'tmYMajorGridThicknessF', 'tmYMinorGrid', 'tmYMinorGridLineColor', + 'tmYMinorGridLineDashPattern', 'tmYMinorGridThicknessF', + 'tmYRAutoPrecision', 'tmYRBorderOn', 'tmYRDataBottomF', + 'tmYRDataTopF', 'tmYRFormat', 'tmYRIrrTensionF', + 'tmYRIrregularPoints', 'tmYRLabelAngleF', 'tmYRLabelConstantSpacingF', + 'tmYRLabelDeltaF', 'tmYRLabelDirection', 'tmYRLabelFont', + 'tmYRLabelFontAspectF', 'tmYRLabelFontColor', 'tmYRLabelFontHeightF', + 'tmYRLabelFontQuality', 'tmYRLabelFontThicknessF', + 'tmYRLabelFuncCode', 'tmYRLabelJust', 'tmYRLabelStride', 'tmYRLabels', + 'tmYRLabelsOn', 'tmYRMajorLengthF', 'tmYRMajorLineColor', + 'tmYRMajorOutwardLengthF', 'tmYRMajorThicknessF', 'tmYRMaxLabelLenF', + 'tmYRMaxTicks', 'tmYRMinLabelSpacingF', 'tmYRMinorLengthF', + 'tmYRMinorLineColor', 'tmYRMinorOn', 'tmYRMinorOutwardLengthF', + 'tmYRMinorPerMajor', 'tmYRMinorThicknessF', 'tmYRMinorValues', + 'tmYRMode', 'tmYROn', 'tmYRPrecision', 'tmYRStyle', 'tmYRTickEndF', + 'tmYRTickSpacingF', 'tmYRTickStartF', 'tmYRValues', 'tmYUseLeft', + 'trGridType', 'trLineInterpolationOn', + 'trXAxisType', 'trXCoordPoints', 'trXInterPoints', 'trXLog', + 'trXMaxF', 'trXMinF', 'trXReverse', 'trXSamples', 'trXTensionF', + 'trYAxisType', 'trYCoordPoints', 'trYInterPoints', 'trYLog', + 'trYMaxF', 'trYMinF', 'trYReverse', 'trYSamples', 'trYTensionF', + 'txAngleF', 'txBackgroundFillColor', 'txConstantSpacingF', 'txDirection', + 'txFont', 'HLU-Fonts', 'txFontAspectF', 'txFontColor', + 'txFontHeightF', 'txFontOpacityF', 'txFontQuality', + 'txFontThicknessF', 'txFuncCode', 'txJust', 'txPerimColor', + 'txPerimDashLengthF', 'txPerimDashPattern', 'txPerimOn', + 'txPerimSpaceF', 'txPerimThicknessF', 'txPosXF', 'txPosYF', + 'txString', 'vcExplicitLabelBarLabelsOn', 'vcFillArrowEdgeColor', + 'vcFillArrowEdgeThicknessF', 'vcFillArrowFillColor', + 'vcFillArrowHeadInteriorXF', 'vcFillArrowHeadMinFracXF', + 'vcFillArrowHeadMinFracYF', 'vcFillArrowHeadXF', 'vcFillArrowHeadYF', + 'vcFillArrowMinFracWidthF', 'vcFillArrowWidthF', 'vcFillArrowsOn', + 'vcFillOverEdge', 'vcGlyphOpacityF', 'vcGlyphStyle', + 'vcLabelBarEndLabelsOn', 'vcLabelFontColor', 'vcLabelFontHeightF', + 'vcLabelsOn', 'vcLabelsUseVectorColor', 'vcLevelColors', + 'vcLevelCount', 'vcLevelPalette', 'vcLevelSelectionMode', + 'vcLevelSpacingF', 'vcLevels', 'vcLineArrowColor', + 'vcLineArrowHeadMaxSizeF', 'vcLineArrowHeadMinSizeF', + 'vcLineArrowThicknessF', 'vcMagnitudeFormat', + 'vcMagnitudeScaleFactorF', 'vcMagnitudeScaleValueF', + 'vcMagnitudeScalingMode', 'vcMapDirection', 'vcMaxLevelCount', + 'vcMaxLevelValF', 'vcMaxMagnitudeF', 'vcMinAnnoAngleF', + 'vcMinAnnoArrowAngleF', 'vcMinAnnoArrowEdgeColor', + 'vcMinAnnoArrowFillColor', 'vcMinAnnoArrowLineColor', + 'vcMinAnnoArrowMinOffsetF', 'vcMinAnnoArrowSpaceF', + 'vcMinAnnoArrowUseVecColor', 'vcMinAnnoBackgroundColor', + 'vcMinAnnoConstantSpacingF', 'vcMinAnnoExplicitMagnitudeF', + 'vcMinAnnoFont', 'vcMinAnnoFontAspectF', 'vcMinAnnoFontColor', + 'vcMinAnnoFontHeightF', 'vcMinAnnoFontQuality', + 'vcMinAnnoFontThicknessF', 'vcMinAnnoFuncCode', 'vcMinAnnoJust', + 'vcMinAnnoOn', 'vcMinAnnoOrientation', 'vcMinAnnoOrthogonalPosF', + 'vcMinAnnoParallelPosF', 'vcMinAnnoPerimColor', 'vcMinAnnoPerimOn', + 'vcMinAnnoPerimSpaceF', 'vcMinAnnoPerimThicknessF', 'vcMinAnnoSide', + 'vcMinAnnoString1', 'vcMinAnnoString1On', 'vcMinAnnoString2', + 'vcMinAnnoString2On', 'vcMinAnnoTextDirection', 'vcMinAnnoZone', + 'vcMinDistanceF', 'vcMinFracLengthF', 'vcMinLevelValF', + 'vcMinMagnitudeF', 'vcMonoFillArrowEdgeColor', + 'vcMonoFillArrowFillColor', 'vcMonoLineArrowColor', + 'vcMonoWindBarbColor', 'vcNoDataLabelOn', 'vcNoDataLabelString', + 'vcPositionMode', 'vcRefAnnoAngleF', 'vcRefAnnoArrowAngleF', + 'vcRefAnnoArrowEdgeColor', 'vcRefAnnoArrowFillColor', + 'vcRefAnnoArrowLineColor', 'vcRefAnnoArrowMinOffsetF', + 'vcRefAnnoArrowSpaceF', 'vcRefAnnoArrowUseVecColor', + 'vcRefAnnoBackgroundColor', 'vcRefAnnoConstantSpacingF', + 'vcRefAnnoExplicitMagnitudeF', 'vcRefAnnoFont', + 'vcRefAnnoFontAspectF', 'vcRefAnnoFontColor', 'vcRefAnnoFontHeightF', + 'vcRefAnnoFontQuality', 'vcRefAnnoFontThicknessF', + 'vcRefAnnoFuncCode', 'vcRefAnnoJust', 'vcRefAnnoOn', + 'vcRefAnnoOrientation', 'vcRefAnnoOrthogonalPosF', + 'vcRefAnnoParallelPosF', 'vcRefAnnoPerimColor', 'vcRefAnnoPerimOn', + 'vcRefAnnoPerimSpaceF', 'vcRefAnnoPerimThicknessF', 'vcRefAnnoSide', + 'vcRefAnnoString1', 'vcRefAnnoString1On', 'vcRefAnnoString2', + 'vcRefAnnoString2On', 'vcRefAnnoTextDirection', 'vcRefAnnoZone', + 'vcRefLengthF', 'vcRefMagnitudeF', 'vcScalarFieldData', + 'vcScalarMissingValColor', 'vcScalarValueFormat', + 'vcScalarValueScaleFactorF', 'vcScalarValueScaleValueF', + 'vcScalarValueScalingMode', 'vcSpanLevelPalette', 'vcUseRefAnnoRes', + 'vcUseScalarArray', 'vcVectorDrawOrder', 'vcVectorFieldData', + 'vcWindBarbCalmCircleSizeF', 'vcWindBarbColor', + 'vcWindBarbLineThicknessF', 'vcWindBarbScaleFactorF', + 'vcWindBarbTickAngleF', 'vcWindBarbTickLengthF', + 'vcWindBarbTickSpacingF', 'vcZeroFLabelAngleF', + 'vcZeroFLabelBackgroundColor', 'vcZeroFLabelConstantSpacingF', + 'vcZeroFLabelFont', 'vcZeroFLabelFontAspectF', + 'vcZeroFLabelFontColor', 'vcZeroFLabelFontHeightF', + 'vcZeroFLabelFontQuality', 'vcZeroFLabelFontThicknessF', + 'vcZeroFLabelFuncCode', 'vcZeroFLabelJust', 'vcZeroFLabelOn', + 'vcZeroFLabelOrthogonalPosF', 'vcZeroFLabelParallelPosF', + 'vcZeroFLabelPerimColor', 'vcZeroFLabelPerimOn', + 'vcZeroFLabelPerimSpaceF', 'vcZeroFLabelPerimThicknessF', + 'vcZeroFLabelSide', 'vcZeroFLabelString', 'vcZeroFLabelTextDirection', + 'vcZeroFLabelZone', 'vfCopyData', 'vfDataArray', + 'vfExchangeDimensions', 'vfExchangeUVData', 'vfMagMaxV', 'vfMagMinV', + 'vfMissingUValueV', 'vfMissingVValueV', 'vfPolarData', + 'vfSingleMissingValue', 'vfUDataArray', 'vfUMaxV', 'vfUMinV', + 'vfVDataArray', 'vfVMaxV', 'vfVMinV', 'vfXArray', 'vfXCActualEndF', + 'vfXCActualStartF', 'vfXCEndIndex', 'vfXCEndSubsetV', 'vfXCEndV', + 'vfXCStartIndex', 'vfXCStartSubsetV', 'vfXCStartV', 'vfXCStride', + 'vfYArray', 'vfYCActualEndF', 'vfYCActualStartF', 'vfYCEndIndex', + 'vfYCEndSubsetV', 'vfYCEndV', 'vfYCStartIndex', 'vfYCStartSubsetV', + 'vfYCStartV', 'vfYCStride', 'vpAnnoManagerId', 'vpClipOn', + 'vpHeightF', 'vpKeepAspect', 'vpOn', 'vpUseSegments', 'vpWidthF', + 'vpXF', 'vpYF', 'wkAntiAlias', 'wkBackgroundColor', 'wkBackgroundOpacityF', + 'wkColorMapLen', 'wkColorMap', 'wkColorModel', 'wkDashTableLength', + 'wkDefGraphicStyleId', 'wkDeviceLowerX', 'wkDeviceLowerY', + 'wkDeviceUpperX', 'wkDeviceUpperY', 'wkFileName', 'wkFillTableLength', + 'wkForegroundColor', 'wkFormat', 'wkFullBackground', 'wkGksWorkId', + 'wkHeight', 'wkMarkerTableLength', 'wkMetaName', 'wkOrientation', + 'wkPDFFileName', 'wkPDFFormat', 'wkPDFResolution', 'wkPSFileName', + 'wkPSFormat', 'wkPSResolution', 'wkPaperHeightF', 'wkPaperSize', + 'wkPaperWidthF', 'wkPause', 'wkTopLevelViews', 'wkViews', + 'wkVisualType', 'wkWidth', 'wkWindowId', 'wkXColorMode', 'wsCurrentSize', + 'wsMaximumSize', 'wsThresholdSize', 'xyComputeXMax', + 'xyComputeXMin', 'xyComputeYMax', 'xyComputeYMin', 'xyCoordData', + 'xyCoordDataSpec', 'xyCurveDrawOrder', 'xyDashPattern', + 'xyDashPatterns', 'xyExplicitLabels', 'xyExplicitLegendLabels', + 'xyLabelMode', 'xyLineColor', 'xyLineColors', 'xyLineDashSegLenF', + 'xyLineLabelConstantSpacingF', 'xyLineLabelFont', + 'xyLineLabelFontAspectF', 'xyLineLabelFontColor', + 'xyLineLabelFontColors', 'xyLineLabelFontHeightF', + 'xyLineLabelFontQuality', 'xyLineLabelFontThicknessF', + 'xyLineLabelFuncCode', 'xyLineThicknessF', 'xyLineThicknesses', + 'xyMarkLineMode', 'xyMarkLineModes', 'xyMarker', 'xyMarkerColor', + 'xyMarkerColors', 'xyMarkerSizeF', 'xyMarkerSizes', + 'xyMarkerThicknessF', 'xyMarkerThicknesses', 'xyMarkers', + 'xyMonoDashPattern', 'xyMonoLineColor', 'xyMonoLineLabelFontColor', + 'xyMonoLineThickness', 'xyMonoMarkLineMode', 'xyMonoMarker', + 'xyMonoMarkerColor', 'xyMonoMarkerSize', 'xyMonoMarkerThickness', + 'xyXIrrTensionF', 'xyXIrregularPoints', 'xyXStyle', 'xyYIrrTensionF', + 'xyYIrregularPoints', 'xyYStyle'), prefix=r'\b'), + Name.Builtin), + + # Booleans + (r'\.(True|False)\.', Name.Builtin), + # Comparing Operators + (r'\.(eq|ne|lt|le|gt|ge|not|and|or|xor)\.', Operator.Word), + ], + + 'strings': [ + (r'(?s)"(\\\\|\\[0-7]+|\\.|[^"\\])*"', String.Double), + ], + + 'nums': [ + (r'\d+(?![.e])(_[a-z]\w+)?', Number.Integer), + (r'[+-]?\d*\.\d+(e[-+]?\d+)?(_[a-z]\w+)?', Number.Float), + (r'[+-]?\d+\.\d*(e[-+]?\d+)?(_[a-z]\w+)?', Number.Float), + ], + } diff --git a/.venv/lib/python3.8/site-packages/pygments/lexers/nimrod.py b/.venv/lib/python3.8/site-packages/pygments/lexers/nimrod.py new file mode 100644 index 00000000..14816eba --- /dev/null +++ b/.venv/lib/python3.8/site-packages/pygments/lexers/nimrod.py @@ -0,0 +1,159 @@ +# -*- coding: utf-8 -*- +""" + pygments.lexers.nimrod + ~~~~~~~~~~~~~~~~~~~~~~ + + Lexer for the Nim language (formerly known as Nimrod). + + :copyright: Copyright 2006-2020 by the Pygments team, see AUTHORS. + :license: BSD, see LICENSE for details. +""" + +import re + +from pygments.lexer import RegexLexer, include, default +from pygments.token import Text, Comment, Operator, Keyword, Name, String, \ + Number, Punctuation, Error + +__all__ = ['NimrodLexer'] + + +class NimrodLexer(RegexLexer): + """ + For `Nim `_ source code. + + .. versionadded:: 1.5 + """ + + name = 'Nimrod' + aliases = ['nim', 'nimrod'] + filenames = ['*.nim', '*.nimrod'] + mimetypes = ['text/x-nim'] + + flags = re.MULTILINE | re.IGNORECASE | re.UNICODE + + def underscorize(words): + newWords = [] + new = "" + for word in words: + for ch in word: + new += (ch + "_?") + newWords.append(new) + new = "" + return "|".join(newWords) + + keywords = [ + 'addr', 'and', 'as', 'asm', 'bind', 'block', 'break', 'case', + 'cast', 'concept', 'const', 'continue', 'converter', 'defer', 'discard', + 'distinct', 'div', 'do', 'elif', 'else', 'end', 'enum', 'except', + 'export', 'finally', 'for', 'func', 'if', 'in', 'yield', 'interface', + 'is', 'isnot', 'iterator', 'let', 'macro', 'method', 'mixin', 'mod', + 'not', 'notin', 'object', 'of', 'or', 'out', 'proc', 'ptr', 'raise', + 'ref', 'return', 'shl', 'shr', 'static', 'template', 'try', + 'tuple', 'type', 'using', 'when', 'while', 'xor' + ] + + keywordsPseudo = [ + 'nil', 'true', 'false' + ] + + opWords = [ + 'and', 'or', 'not', 'xor', 'shl', 'shr', 'div', 'mod', 'in', + 'notin', 'is', 'isnot' + ] + + types = [ + 'int', 'int8', 'int16', 'int32', 'int64', 'float', 'float32', 'float64', + 'bool', 'char', 'range', 'array', 'seq', 'set', 'string' + ] + + tokens = { + 'root': [ + (r'##.*$', String.Doc), + (r'#.*$', Comment), + (r'[*=><+\-/@$~&%!?|\\\[\]]', Operator), + (r'\.\.|\.|,|\[\.|\.\]|\{\.|\.\}|\(\.|\.\)|\{|\}|\(|\)|:|\^|`|;', + Punctuation), + + # Strings + (r'(?:[\w]+)"', String, 'rdqs'), + (r'"""', String, 'tdqs'), + ('"', String, 'dqs'), + + # Char + ("'", String.Char, 'chars'), + + # Keywords + (r'(%s)\b' % underscorize(opWords), Operator.Word), + (r'(p_?r_?o_?c_?\s)(?![(\[\]])', Keyword, 'funcname'), + (r'(%s)\b' % underscorize(keywords), Keyword), + (r'(%s)\b' % underscorize(['from', 'import', 'include']), + Keyword.Namespace), + (r'(v_?a_?r)\b', Keyword.Declaration), + (r'(%s)\b' % underscorize(types), Keyword.Type), + (r'(%s)\b' % underscorize(keywordsPseudo), Keyword.Pseudo), + # Identifiers + (r'\b((?![_\d])\w)(((?!_)\w)|(_(?!_)\w))*', Name), + # Numbers + (r'[0-9][0-9_]*(?=([e.]|\'f(32|64)))', + Number.Float, ('float-suffix', 'float-number')), + (r'0x[a-f0-9][a-f0-9_]*', Number.Hex, 'int-suffix'), + (r'0b[01][01_]*', Number.Bin, 'int-suffix'), + (r'0o[0-7][0-7_]*', Number.Oct, 'int-suffix'), + (r'[0-9][0-9_]*', Number.Integer, 'int-suffix'), + # Whitespace + (r'\s+', Text), + (r'.+$', Error), + ], + 'chars': [ + (r'\\([\\abcefnrtvl"\']|x[a-f0-9]{2}|[0-9]{1,3})', String.Escape), + (r"'", String.Char, '#pop'), + (r".", String.Char) + ], + 'strings': [ + (r'(?`_ source. + + .. versionadded:: 2.0 + """ + + name = 'Nit' + aliases = ['nit'] + filenames = ['*.nit'] + tokens = { + 'root': [ + (r'#.*?$', Comment.Single), + (words(( + 'package', 'module', 'import', 'class', 'abstract', 'interface', + 'universal', 'enum', 'end', 'fun', 'type', 'init', 'redef', + 'isa', 'do', 'readable', 'writable', 'var', 'intern', 'extern', + 'public', 'protected', 'private', 'intrude', 'if', 'then', + 'else', 'while', 'loop', 'for', 'in', 'and', 'or', 'not', + 'implies', 'return', 'continue', 'break', 'abort', 'assert', + 'new', 'is', 'once', 'super', 'self', 'true', 'false', 'nullable', + 'null', 'as', 'isset', 'label', '__debug__'), suffix=r'(?=[\r\n\t( ])'), + Keyword), + (r'[A-Z]\w*', Name.Class), + (r'"""(([^\'\\]|\\.)|\\r|\\n)*((\{\{?)?(""?\{\{?)*""""*)', String), # Simple long string + (r'\'\'\'(((\\.|[^\'\\])|\\r|\\n)|\'((\\.|[^\'\\])|\\r|\\n)|' + r'\'\'((\\.|[^\'\\])|\\r|\\n))*\'\'\'', String), # Simple long string alt + (r'"""(([^\'\\]|\\.)|\\r|\\n)*((""?)?(\{\{?""?)*\{\{\{\{*)', String), # Start long string + (r'\}\}\}(((\\.|[^\'\\])|\\r|\\n))*(""?)?(\{\{?""?)*\{\{\{\{*', String), # Mid long string + (r'\}\}\}(((\\.|[^\'\\])|\\r|\\n))*(\{\{?)?(""?\{\{?)*""""*', String), # End long string + (r'"(\\.|([^"}{\\]))*"', String), # Simple String + (r'"(\\.|([^"}{\\]))*\{', String), # Start string + (r'\}(\\.|([^"}{\\]))*\{', String), # Mid String + (r'\}(\\.|([^"}{\\]))*"', String), # End String + (r'(\'[^\'\\]\')|(\'\\.\')', String.Char), + (r'[0-9]+', Number.Integer), + (r'[0-9]*.[0-9]+', Number.Float), + (r'0(x|X)[0-9A-Fa-f]+', Number.Hex), + (r'[a-z]\w*', Name), + (r'_\w+', Name.Variable.Instance), + (r'==|!=|<==>|>=|>>|>|<=|<<|<|\+|-|=|/|\*|%|\+=|-=|!|@', Operator), + (r'\(|\)|\[|\]|,|\.\.\.|\.\.|\.|::|:', Punctuation), + (r'`\{[^`]*`\}', Text), # Extern blocks won't be Lexed by Nit + (r'[\r\n\t ]+', Text), + ], + } diff --git a/.venv/lib/python3.8/site-packages/pygments/lexers/nix.py b/.venv/lib/python3.8/site-packages/pygments/lexers/nix.py new file mode 100644 index 00000000..713348e8 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/pygments/lexers/nix.py @@ -0,0 +1,136 @@ +# -*- coding: utf-8 -*- +""" + pygments.lexers.nix + ~~~~~~~~~~~~~~~~~~~ + + Lexers for the NixOS Nix language. + + :copyright: Copyright 2006-2020 by the Pygments team, see AUTHORS. + :license: BSD, see LICENSE for details. +""" + +import re + +from pygments.lexer import RegexLexer, include +from pygments.token import Text, Comment, Operator, Keyword, Name, String, \ + Number, Punctuation, Literal + +__all__ = ['NixLexer'] + + +class NixLexer(RegexLexer): + """ + For the `Nix language `_. + + .. versionadded:: 2.0 + """ + + name = 'Nix' + aliases = ['nixos', 'nix'] + filenames = ['*.nix'] + mimetypes = ['text/x-nix'] + + flags = re.MULTILINE | re.UNICODE + + keywords = ['rec', 'with', 'let', 'in', 'inherit', 'assert', 'if', + 'else', 'then', '...'] + builtins = ['import', 'abort', 'baseNameOf', 'dirOf', 'isNull', 'builtins', + 'map', 'removeAttrs', 'throw', 'toString', 'derivation'] + operators = ['++', '+', '?', '.', '!', '//', '==', + '!=', '&&', '||', '->', '='] + + punctuations = ["(", ")", "[", "]", ";", "{", "}", ":", ",", "@"] + + tokens = { + 'root': [ + # comments starting with # + (r'#.*$', Comment.Single), + + # multiline comments + (r'/\*', Comment.Multiline, 'comment'), + + # whitespace + (r'\s+', Text), + + # keywords + ('(%s)' % '|'.join(re.escape(entry) + '\\b' for entry in keywords), Keyword), + + # highlight the builtins + ('(%s)' % '|'.join(re.escape(entry) + '\\b' for entry in builtins), + Name.Builtin), + + (r'\b(true|false|null)\b', Name.Constant), + + # operators + ('(%s)' % '|'.join(re.escape(entry) for entry in operators), + Operator), + + # word operators + (r'\b(or|and)\b', Operator.Word), + + # punctuations + ('(%s)' % '|'.join(re.escape(entry) for entry in punctuations), Punctuation), + + # integers + (r'[0-9]+', Number.Integer), + + # strings + (r'"', String.Double, 'doublequote'), + (r"''", String.Single, 'singlequote'), + + # paths + (r'[\w.+-]*(\/[\w.+-]+)+', Literal), + (r'\<[\w.+-]+(\/[\w.+-]+)*\>', Literal), + + # urls + (r'[a-zA-Z][a-zA-Z0-9\+\-\.]*\:[\w%/?:@&=+$,\\.!~*\'-]+', Literal), + + # names of variables + (r'[\w-]+\s*=', String.Symbol), + (r'[a-zA-Z_][\w\'-]*', Text), + + ], + 'comment': [ + (r'[^/*]+', Comment.Multiline), + (r'/\*', Comment.Multiline, '#push'), + (r'\*/', Comment.Multiline, '#pop'), + (r'[*/]', Comment.Multiline), + ], + 'singlequote': [ + (r"'''", String.Escape), + (r"''\$\{", String.Escape), + (r"''\n", String.Escape), + (r"''\r", String.Escape), + (r"''\t", String.Escape), + (r"''", String.Single, '#pop'), + (r'\$\{', String.Interpol, 'antiquote'), + (r"[^']", String.Single), + ], + 'doublequote': [ + (r'\\', String.Escape), + (r'\\"', String.Escape), + (r'\\$\{', String.Escape), + (r'"', String.Double, '#pop'), + (r'\$\{', String.Interpol, 'antiquote'), + (r'[^"]', String.Double), + ], + 'antiquote': [ + (r"\}", String.Interpol, '#pop'), + # TODO: we should probably escape also here ''${ \${ + (r"\$\{", String.Interpol, '#push'), + include('root'), + ], + } + + def analyse_text(text): + rv = 0.0 + # TODO: let/in + if re.search(r'import.+?<[^>]+>', text): + rv += 0.4 + if re.search(r'mkDerivation\s+(\(|\{|rec)', text): + rv += 0.4 + if re.search(r'=\s+mkIf\s+', text): + rv += 0.4 + if re.search(r'\{[a-zA-Z,\s]+\}:', text): + rv += 0.1 + return rv diff --git a/.venv/lib/python3.8/site-packages/pygments/lexers/oberon.py b/.venv/lib/python3.8/site-packages/pygments/lexers/oberon.py new file mode 100644 index 00000000..8934997a --- /dev/null +++ b/.venv/lib/python3.8/site-packages/pygments/lexers/oberon.py @@ -0,0 +1,121 @@ +# -*- coding: utf-8 -*- +""" + pygments.lexers.oberon + ~~~~~~~~~~~~~~~~~~~~~~ + + Lexers for Oberon family languages. + + :copyright: Copyright 2006-2020 by the Pygments team, see AUTHORS. + :license: BSD, see LICENSE for details. +""" + +import re + +from pygments.lexer import RegexLexer, include, words +from pygments.token import Text, Comment, Operator, Keyword, Name, String, \ + Number, Punctuation + +__all__ = ['ComponentPascalLexer'] + + +class ComponentPascalLexer(RegexLexer): + """ + For `Component Pascal `_ source code. + + .. versionadded:: 2.1 + """ + name = 'Component Pascal' + aliases = ['componentpascal', 'cp'] + filenames = ['*.cp', '*.cps'] + mimetypes = ['text/x-component-pascal'] + + flags = re.MULTILINE | re.DOTALL + + tokens = { + 'root': [ + include('whitespace'), + include('comments'), + include('punctuation'), + include('numliterals'), + include('strings'), + include('operators'), + include('builtins'), + include('identifiers'), + ], + 'whitespace': [ + (r'\n+', Text), # blank lines + (r'\s+', Text), # whitespace + ], + 'comments': [ + (r'\(\*([^$].*?)\*\)', Comment.Multiline), + # TODO: nested comments (* (* ... *) ... (* ... *) *) not supported! + ], + 'punctuation': [ + (r'[()\[\]{},.:;|]', Punctuation), + ], + 'numliterals': [ + (r'[0-9A-F]+X\b', Number.Hex), # char code + (r'[0-9A-F]+[HL]\b', Number.Hex), # hexadecimal number + (r'[0-9]+\.[0-9]+E[+-][0-9]+', Number.Float), # real number + (r'[0-9]+\.[0-9]+', Number.Float), # real number + (r'[0-9]+', Number.Integer), # decimal whole number + ], + 'strings': [ + (r"'[^\n']*'", String), # single quoted string + (r'"[^\n"]*"', String), # double quoted string + ], + 'operators': [ + # Arithmetic Operators + (r'[+-]', Operator), + (r'[*/]', Operator), + # Relational Operators + (r'[=#<>]', Operator), + # Dereferencing Operator + (r'\^', Operator), + # Logical AND Operator + (r'&', Operator), + # Logical NOT Operator + (r'~', Operator), + # Assignment Symbol + (r':=', Operator), + # Range Constructor + (r'\.\.', Operator), + (r'\$', Operator), + ], + 'identifiers': [ + (r'([a-zA-Z_$][\w$]*)', Name), + ], + 'builtins': [ + (words(( + 'ANYPTR', 'ANYREC', 'BOOLEAN', 'BYTE', 'CHAR', 'INTEGER', 'LONGINT', + 'REAL', 'SET', 'SHORTCHAR', 'SHORTINT', 'SHORTREAL' + ), suffix=r'\b'), Keyword.Type), + (words(( + 'ABS', 'ABSTRACT', 'ARRAY', 'ASH', 'ASSERT', 'BEGIN', 'BITS', 'BY', + 'CAP', 'CASE', 'CHR', 'CLOSE', 'CONST', 'DEC', 'DIV', 'DO', 'ELSE', + 'ELSIF', 'EMPTY', 'END', 'ENTIER', 'EXCL', 'EXIT', 'EXTENSIBLE', 'FOR', + 'HALT', 'IF', 'IMPORT', 'IN', 'INC', 'INCL', 'IS', 'LEN', 'LIMITED', + 'LONG', 'LOOP', 'MAX', 'MIN', 'MOD', 'MODULE', 'NEW', 'ODD', 'OF', + 'OR', 'ORD', 'OUT', 'POINTER', 'PROCEDURE', 'RECORD', 'REPEAT', 'RETURN', + 'SHORT', 'SHORTCHAR', 'SHORTINT', 'SIZE', 'THEN', 'TYPE', 'TO', 'UNTIL', + 'VAR', 'WHILE', 'WITH' + ), suffix=r'\b'), Keyword.Reserved), + (r'(TRUE|FALSE|NIL|INF)\b', Keyword.Constant), + ] + } + + def analyse_text(text): + """The only other lexer using .cp is the C++ one, so we check if for + a few common Pascal keywords here. Those are unfortunately quite + common across various business languages as well.""" + result = 0 + if 'BEGIN' in text: + result += 0.01 + if 'END' in text: + result += 0.01 + if 'PROCEDURE' in text: + result += 0.01 + if 'END' in text: + result += 0.01 + + return result diff --git a/.venv/lib/python3.8/site-packages/pygments/lexers/objective.py b/.venv/lib/python3.8/site-packages/pygments/lexers/objective.py new file mode 100644 index 00000000..3a1c3f65 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/pygments/lexers/objective.py @@ -0,0 +1,504 @@ +# -*- coding: utf-8 -*- +""" + pygments.lexers.objective + ~~~~~~~~~~~~~~~~~~~~~~~~~ + + Lexers for Objective-C family languages. + + :copyright: Copyright 2006-2020 by the Pygments team, see AUTHORS. + :license: BSD, see LICENSE for details. +""" + +import re + +from pygments.lexer import RegexLexer, include, bygroups, using, this, words, \ + inherit, default +from pygments.token import Text, Keyword, Name, String, Operator, \ + Number, Punctuation, Literal, Comment + +from pygments.lexers.c_cpp import CLexer, CppLexer + +__all__ = ['ObjectiveCLexer', 'ObjectiveCppLexer', 'LogosLexer', 'SwiftLexer'] + + +def objective(baselexer): + """ + Generate a subclass of baselexer that accepts the Objective-C syntax + extensions. + """ + + # Have to be careful not to accidentally match JavaDoc/Doxygen syntax here, + # since that's quite common in ordinary C/C++ files. It's OK to match + # JavaDoc/Doxygen keywords that only apply to Objective-C, mind. + # + # The upshot of this is that we CANNOT match @class or @interface + _oc_keywords = re.compile(r'@(?:end|implementation|protocol)') + + # Matches [ ? identifier ( identifier ? ] | identifier? : ) + # (note the identifier is *optional* when there is a ':'!) + _oc_message = re.compile(r'\[\s*[a-zA-Z_]\w*\s+' + r'(?:[a-zA-Z_]\w*\s*\]|' + r'(?:[a-zA-Z_]\w*)?:)') + + class GeneratedObjectiveCVariant(baselexer): + """ + Implements Objective-C syntax on top of an existing C family lexer. + """ + + tokens = { + 'statements': [ + (r'@"', String, 'string'), + (r'@(YES|NO)', Number), + (r"@'(\\.|\\[0-7]{1,3}|\\x[a-fA-F0-9]{1,2}|[^\\\'\n])'", String.Char), + (r'@(\d+\.\d*|\.\d+|\d+)[eE][+-]?\d+[lL]?', Number.Float), + (r'@(\d+\.\d*|\.\d+|\d+[fF])[fF]?', Number.Float), + (r'@0x[0-9a-fA-F]+[Ll]?', Number.Hex), + (r'@0[0-7]+[Ll]?', Number.Oct), + (r'@\d+[Ll]?', Number.Integer), + (r'@\(', Literal, 'literal_number'), + (r'@\[', Literal, 'literal_array'), + (r'@\{', Literal, 'literal_dictionary'), + (words(( + '@selector', '@private', '@protected', '@public', '@encode', + '@synchronized', '@try', '@throw', '@catch', '@finally', + '@end', '@property', '@synthesize', '__bridge', '__bridge_transfer', + '__autoreleasing', '__block', '__weak', '__strong', 'weak', 'strong', + 'copy', 'retain', 'assign', 'unsafe_unretained', 'atomic', 'nonatomic', + 'readonly', 'readwrite', 'setter', 'getter', 'typeof', 'in', + 'out', 'inout', 'release', 'class', '@dynamic', '@optional', + '@required', '@autoreleasepool', '@import'), suffix=r'\b'), + Keyword), + (words(('id', 'instancetype', 'Class', 'IMP', 'SEL', 'BOOL', + 'IBOutlet', 'IBAction', 'unichar'), suffix=r'\b'), + Keyword.Type), + (r'@(true|false|YES|NO)\n', Name.Builtin), + (r'(YES|NO|nil|self|super)\b', Name.Builtin), + # Carbon types + (r'(Boolean|UInt8|SInt8|UInt16|SInt16|UInt32|SInt32)\b', Keyword.Type), + # Carbon built-ins + (r'(TRUE|FALSE)\b', Name.Builtin), + (r'(@interface|@implementation)(\s+)', bygroups(Keyword, Text), + ('#pop', 'oc_classname')), + (r'(@class|@protocol)(\s+)', bygroups(Keyword, Text), + ('#pop', 'oc_forward_classname')), + # @ can also prefix other expressions like @{...} or @(...) + (r'@', Punctuation), + inherit, + ], + 'oc_classname': [ + # interface definition that inherits + (r'([a-zA-Z$_][\w$]*)(\s*:\s*)([a-zA-Z$_][\w$]*)?(\s*)(\{)', + bygroups(Name.Class, Text, Name.Class, Text, Punctuation), + ('#pop', 'oc_ivars')), + (r'([a-zA-Z$_][\w$]*)(\s*:\s*)([a-zA-Z$_][\w$]*)?', + bygroups(Name.Class, Text, Name.Class), '#pop'), + # interface definition for a category + (r'([a-zA-Z$_][\w$]*)(\s*)(\([a-zA-Z$_][\w$]*\))(\s*)(\{)', + bygroups(Name.Class, Text, Name.Label, Text, Punctuation), + ('#pop', 'oc_ivars')), + (r'([a-zA-Z$_][\w$]*)(\s*)(\([a-zA-Z$_][\w$]*\))', + bygroups(Name.Class, Text, Name.Label), '#pop'), + # simple interface / implementation + (r'([a-zA-Z$_][\w$]*)(\s*)(\{)', + bygroups(Name.Class, Text, Punctuation), ('#pop', 'oc_ivars')), + (r'([a-zA-Z$_][\w$]*)', Name.Class, '#pop') + ], + 'oc_forward_classname': [ + (r'([a-zA-Z$_][\w$]*)(\s*,\s*)', + bygroups(Name.Class, Text), 'oc_forward_classname'), + (r'([a-zA-Z$_][\w$]*)(\s*;?)', + bygroups(Name.Class, Text), '#pop') + ], + 'oc_ivars': [ + include('whitespace'), + include('statements'), + (';', Punctuation), + (r'\{', Punctuation, '#push'), + (r'\}', Punctuation, '#pop'), + ], + 'root': [ + # methods + (r'^([-+])(\s*)' # method marker + r'(\(.*?\))?(\s*)' # return type + r'([a-zA-Z$_][\w$]*:?)', # begin of method name + bygroups(Punctuation, Text, using(this), + Text, Name.Function), + 'method'), + inherit, + ], + 'method': [ + include('whitespace'), + # TODO unsure if ellipses are allowed elsewhere, see + # discussion in Issue 789 + (r',', Punctuation), + (r'\.\.\.', Punctuation), + (r'(\(.*?\))(\s*)([a-zA-Z$_][\w$]*)', + bygroups(using(this), Text, Name.Variable)), + (r'[a-zA-Z$_][\w$]*:', Name.Function), + (';', Punctuation, '#pop'), + (r'\{', Punctuation, 'function'), + default('#pop'), + ], + 'literal_number': [ + (r'\(', Punctuation, 'literal_number_inner'), + (r'\)', Literal, '#pop'), + include('statement'), + ], + 'literal_number_inner': [ + (r'\(', Punctuation, '#push'), + (r'\)', Punctuation, '#pop'), + include('statement'), + ], + 'literal_array': [ + (r'\[', Punctuation, 'literal_array_inner'), + (r'\]', Literal, '#pop'), + include('statement'), + ], + 'literal_array_inner': [ + (r'\[', Punctuation, '#push'), + (r'\]', Punctuation, '#pop'), + include('statement'), + ], + 'literal_dictionary': [ + (r'\}', Literal, '#pop'), + include('statement'), + ], + } + + def analyse_text(text): + if _oc_keywords.search(text): + return 1.0 + elif '@"' in text: # strings + return 0.8 + elif re.search('@[0-9]+', text): + return 0.7 + elif _oc_message.search(text): + return 0.8 + return 0 + + def get_tokens_unprocessed(self, text): + from pygments.lexers._cocoa_builtins import COCOA_INTERFACES, \ + COCOA_PROTOCOLS, COCOA_PRIMITIVES + + for index, token, value in \ + baselexer.get_tokens_unprocessed(self, text): + if token is Name or token is Name.Class: + if value in COCOA_INTERFACES or value in COCOA_PROTOCOLS \ + or value in COCOA_PRIMITIVES: + token = Name.Builtin.Pseudo + + yield index, token, value + + return GeneratedObjectiveCVariant + + +class ObjectiveCLexer(objective(CLexer)): + """ + For Objective-C source code with preprocessor directives. + """ + + name = 'Objective-C' + aliases = ['objective-c', 'objectivec', 'obj-c', 'objc'] + filenames = ['*.m', '*.h'] + mimetypes = ['text/x-objective-c'] + priority = 0.05 # Lower than C + + +class ObjectiveCppLexer(objective(CppLexer)): + """ + For Objective-C++ source code with preprocessor directives. + """ + + name = 'Objective-C++' + aliases = ['objective-c++', 'objectivec++', 'obj-c++', 'objc++'] + filenames = ['*.mm', '*.hh'] + mimetypes = ['text/x-objective-c++'] + priority = 0.05 # Lower than C++ + + +class LogosLexer(ObjectiveCppLexer): + """ + For Logos + Objective-C source code with preprocessor directives. + + .. versionadded:: 1.6 + """ + + name = 'Logos' + aliases = ['logos'] + filenames = ['*.x', '*.xi', '*.xm', '*.xmi'] + mimetypes = ['text/x-logos'] + priority = 0.25 + + tokens = { + 'statements': [ + (r'(%orig|%log)\b', Keyword), + (r'(%c)\b(\()(\s*)([a-zA-Z$_][\w$]*)(\s*)(\))', + bygroups(Keyword, Punctuation, Text, Name.Class, Text, Punctuation)), + (r'(%init)\b(\()', + bygroups(Keyword, Punctuation), 'logos_init_directive'), + (r'(%init)(?=\s*;)', bygroups(Keyword)), + (r'(%hook|%group)(\s+)([a-zA-Z$_][\w$]+)', + bygroups(Keyword, Text, Name.Class), '#pop'), + (r'(%subclass)(\s+)', bygroups(Keyword, Text), + ('#pop', 'logos_classname')), + inherit, + ], + 'logos_init_directive': [ + (r'\s+', Text), + (',', Punctuation, ('logos_init_directive', '#pop')), + (r'([a-zA-Z$_][\w$]*)(\s*)(=)(\s*)([^);]*)', + bygroups(Name.Class, Text, Punctuation, Text, Text)), + (r'([a-zA-Z$_][\w$]*)', Name.Class), + (r'\)', Punctuation, '#pop'), + ], + 'logos_classname': [ + (r'([a-zA-Z$_][\w$]*)(\s*:\s*)([a-zA-Z$_][\w$]*)?', + bygroups(Name.Class, Text, Name.Class), '#pop'), + (r'([a-zA-Z$_][\w$]*)', Name.Class, '#pop') + ], + 'root': [ + (r'(%subclass)(\s+)', bygroups(Keyword, Text), + 'logos_classname'), + (r'(%hook|%group)(\s+)([a-zA-Z$_][\w$]+)', + bygroups(Keyword, Text, Name.Class)), + (r'(%config)(\s*\(\s*)(\w+)(\s*=\s*)(.*?)(\s*\)\s*)', + bygroups(Keyword, Text, Name.Variable, Text, String, Text)), + (r'(%ctor)(\s*)(\{)', bygroups(Keyword, Text, Punctuation), + 'function'), + (r'(%new)(\s*)(\()(\s*.*?\s*)(\))', + bygroups(Keyword, Text, Keyword, String, Keyword)), + (r'(\s*)(%end)(\s*)', bygroups(Text, Keyword, Text)), + inherit, + ], + } + + _logos_keywords = re.compile(r'%(?:hook|ctor|init|c\()') + + def analyse_text(text): + if LogosLexer._logos_keywords.search(text): + return 1.0 + return 0 + + +class SwiftLexer(RegexLexer): + """ + For `Swift `_ source. + + .. versionadded:: 2.0 + """ + name = 'Swift' + filenames = ['*.swift'] + aliases = ['swift'] + mimetypes = ['text/x-swift'] + + tokens = { + 'root': [ + # Whitespace and Comments + (r'\n', Text), + (r'\s+', Text), + (r'//', Comment.Single, 'comment-single'), + (r'/\*', Comment.Multiline, 'comment-multi'), + (r'#(if|elseif|else|endif|available)\b', Comment.Preproc, 'preproc'), + + # Keywords + include('keywords'), + + # Global Types + (words(( + 'Array', 'AutoreleasingUnsafeMutablePointer', 'BidirectionalReverseView', + 'Bit', 'Bool', 'CFunctionPointer', 'COpaquePointer', 'CVaListPointer', + 'Character', 'ClosedInterval', 'CollectionOfOne', 'ContiguousArray', + 'Dictionary', 'DictionaryGenerator', 'DictionaryIndex', 'Double', + 'EmptyCollection', 'EmptyGenerator', 'EnumerateGenerator', + 'EnumerateSequence', 'FilterCollectionView', + 'FilterCollectionViewIndex', 'FilterGenerator', 'FilterSequenceView', + 'Float', 'Float80', 'FloatingPointClassification', 'GeneratorOf', + 'GeneratorOfOne', 'GeneratorSequence', 'HalfOpenInterval', 'HeapBuffer', + 'HeapBufferStorage', 'ImplicitlyUnwrappedOptional', 'IndexingGenerator', + 'Int', 'Int16', 'Int32', 'Int64', 'Int8', 'LazyBidirectionalCollection', + 'LazyForwardCollection', 'LazyRandomAccessCollection', + 'LazySequence', 'MapCollectionView', 'MapSequenceGenerator', + 'MapSequenceView', 'MirrorDisposition', 'ObjectIdentifier', 'OnHeap', + 'Optional', 'PermutationGenerator', 'QuickLookObject', + 'RandomAccessReverseView', 'Range', 'RangeGenerator', 'RawByte', 'Repeat', + 'ReverseBidirectionalIndex', 'ReverseRandomAccessIndex', 'SequenceOf', + 'SinkOf', 'Slice', 'StaticString', 'StrideThrough', 'StrideThroughGenerator', + 'StrideTo', 'StrideToGenerator', 'String', 'UInt', 'UInt16', 'UInt32', + 'UInt64', 'UInt8', 'UTF16', 'UTF32', 'UTF8', 'UnicodeDecodingResult', + 'UnicodeScalar', 'Unmanaged', 'UnsafeBufferPointer', + 'UnsafeBufferPointerGenerator', 'UnsafeMutableBufferPointer', + 'UnsafeMutablePointer', 'UnsafePointer', 'Zip2', 'ZipGenerator2', + # Protocols + 'AbsoluteValuable', 'AnyObject', 'ArrayLiteralConvertible', + 'BidirectionalIndexType', 'BitwiseOperationsType', + 'BooleanLiteralConvertible', 'BooleanType', 'CVarArgType', + 'CollectionType', 'Comparable', 'DebugPrintable', + 'DictionaryLiteralConvertible', 'Equatable', + 'ExtendedGraphemeClusterLiteralConvertible', + 'ExtensibleCollectionType', 'FloatLiteralConvertible', + 'FloatingPointType', 'ForwardIndexType', 'GeneratorType', 'Hashable', + 'IntegerArithmeticType', 'IntegerLiteralConvertible', 'IntegerType', + 'IntervalType', 'MirrorType', 'MutableCollectionType', 'MutableSliceable', + 'NilLiteralConvertible', 'OutputStreamType', 'Printable', + 'RandomAccessIndexType', 'RangeReplaceableCollectionType', + 'RawOptionSetType', 'RawRepresentable', 'Reflectable', 'SequenceType', + 'SignedIntegerType', 'SignedNumberType', 'SinkType', 'Sliceable', + 'Streamable', 'Strideable', 'StringInterpolationConvertible', + 'StringLiteralConvertible', 'UnicodeCodecType', + 'UnicodeScalarLiteralConvertible', 'UnsignedIntegerType', + '_ArrayBufferType', '_BidirectionalIndexType', '_CocoaStringType', + '_CollectionType', '_Comparable', '_ExtensibleCollectionType', + '_ForwardIndexType', '_Incrementable', '_IntegerArithmeticType', + '_IntegerType', '_ObjectiveCBridgeable', '_RandomAccessIndexType', + '_RawOptionSetType', '_SequenceType', '_Sequence_Type', + '_SignedIntegerType', '_SignedNumberType', '_Sliceable', '_Strideable', + '_SwiftNSArrayRequiredOverridesType', '_SwiftNSArrayType', + '_SwiftNSCopyingType', '_SwiftNSDictionaryRequiredOverridesType', + '_SwiftNSDictionaryType', '_SwiftNSEnumeratorType', + '_SwiftNSFastEnumerationType', '_SwiftNSStringRequiredOverridesType', + '_SwiftNSStringType', '_UnsignedIntegerType', + # Variables + 'C_ARGC', 'C_ARGV', 'Process', + # Typealiases + 'Any', 'AnyClass', 'BooleanLiteralType', 'CBool', 'CChar', 'CChar16', + 'CChar32', 'CDouble', 'CFloat', 'CInt', 'CLong', 'CLongLong', 'CShort', + 'CSignedChar', 'CUnsignedInt', 'CUnsignedLong', 'CUnsignedShort', + 'CWideChar', 'ExtendedGraphemeClusterType', 'Float32', 'Float64', + 'FloatLiteralType', 'IntMax', 'IntegerLiteralType', 'StringLiteralType', + 'UIntMax', 'UWord', 'UnicodeScalarType', 'Void', 'Word', + # Foundation/Cocoa + 'NSErrorPointer', 'NSObjectProtocol', 'Selector'), suffix=r'\b'), + Name.Builtin), + # Functions + (words(( + 'abs', 'advance', 'alignof', 'alignofValue', 'assert', 'assertionFailure', + 'contains', 'count', 'countElements', 'debugPrint', 'debugPrintln', + 'distance', 'dropFirst', 'dropLast', 'dump', 'enumerate', 'equal', + 'extend', 'fatalError', 'filter', 'find', 'first', 'getVaList', 'indices', + 'insert', 'isEmpty', 'join', 'last', 'lazy', 'lexicographicalCompare', + 'map', 'max', 'maxElement', 'min', 'minElement', 'numericCast', 'overlaps', + 'partition', 'precondition', 'preconditionFailure', 'prefix', 'print', + 'println', 'reduce', 'reflect', 'removeAll', 'removeAtIndex', 'removeLast', + 'removeRange', 'reverse', 'sizeof', 'sizeofValue', 'sort', 'sorted', + 'splice', 'split', 'startsWith', 'stride', 'strideof', 'strideofValue', + 'suffix', 'swap', 'toDebugString', 'toString', 'transcode', + 'underestimateCount', 'unsafeAddressOf', 'unsafeBitCast', 'unsafeDowncast', + 'withExtendedLifetime', 'withUnsafeMutablePointer', + 'withUnsafeMutablePointers', 'withUnsafePointer', 'withUnsafePointers', + 'withVaList'), suffix=r'\b'), + Name.Builtin.Pseudo), + + # Implicit Block Variables + (r'\$\d+', Name.Variable), + + # Binary Literal + (r'0b[01_]+', Number.Bin), + # Octal Literal + (r'0o[0-7_]+', Number.Oct), + # Hexadecimal Literal + (r'0x[0-9a-fA-F_]+', Number.Hex), + # Decimal Literal + (r'[0-9][0-9_]*(\.[0-9_]+[eE][+\-]?[0-9_]+|' + r'\.[0-9_]*|[eE][+\-]?[0-9_]+)', Number.Float), + (r'[0-9][0-9_]*', Number.Integer), + # String Literal + (r'"', String, 'string'), + + # Operators and Punctuation + (r'[(){}\[\].,:;=@#`?]|->|[<&?](?=\w)|(?<=\w)[>!?]', Punctuation), + (r'[/=\-+!*%<>&|^?~]+', Operator), + + # Identifier + (r'[a-zA-Z_]\w*', Name) + ], + 'keywords': [ + (words(( + 'as', 'break', 'case', 'catch', 'continue', 'default', 'defer', + 'do', 'else', 'fallthrough', 'for', 'guard', 'if', 'in', 'is', + 'repeat', 'return', '#selector', 'switch', 'throw', 'try', + 'where', 'while'), suffix=r'\b'), + Keyword), + (r'@availability\([^)]+\)', Keyword.Reserved), + (words(( + 'associativity', 'convenience', 'dynamic', 'didSet', 'final', + 'get', 'indirect', 'infix', 'inout', 'lazy', 'left', 'mutating', + 'none', 'nonmutating', 'optional', 'override', 'postfix', + 'precedence', 'prefix', 'Protocol', 'required', 'rethrows', + 'right', 'set', 'throws', 'Type', 'unowned', 'weak', 'willSet', + '@availability', '@autoclosure', '@noreturn', + '@NSApplicationMain', '@NSCopying', '@NSManaged', '@objc', + '@UIApplicationMain', '@IBAction', '@IBDesignable', + '@IBInspectable', '@IBOutlet'), suffix=r'\b'), + Keyword.Reserved), + (r'(as|dynamicType|false|is|nil|self|Self|super|true|__COLUMN__' + r'|__FILE__|__FUNCTION__|__LINE__|_' + r'|#(?:file|line|column|function))\b', Keyword.Constant), + (r'import\b', Keyword.Declaration, 'module'), + (r'(class|enum|extension|struct|protocol)(\s+)([a-zA-Z_]\w*)', + bygroups(Keyword.Declaration, Text, Name.Class)), + (r'(func)(\s+)([a-zA-Z_]\w*)', + bygroups(Keyword.Declaration, Text, Name.Function)), + (r'(var|let)(\s+)([a-zA-Z_]\w*)', bygroups(Keyword.Declaration, + Text, Name.Variable)), + (words(( + 'class', 'deinit', 'enum', 'extension', 'func', 'import', 'init', + 'internal', 'let', 'operator', 'private', 'protocol', 'public', + 'static', 'struct', 'subscript', 'typealias', 'var'), suffix=r'\b'), + Keyword.Declaration) + ], + 'comment': [ + (r':param: [a-zA-Z_]\w*|:returns?:|(FIXME|MARK|TODO):', + Comment.Special) + ], + + # Nested + 'comment-single': [ + (r'\n', Text, '#pop'), + include('comment'), + (r'[^\n]', Comment.Single) + ], + 'comment-multi': [ + include('comment'), + (r'[^*/]', Comment.Multiline), + (r'/\*', Comment.Multiline, '#push'), + (r'\*/', Comment.Multiline, '#pop'), + (r'[*/]', Comment.Multiline) + ], + 'module': [ + (r'\n', Text, '#pop'), + (r'[a-zA-Z_]\w*', Name.Class), + include('root') + ], + 'preproc': [ + (r'\n', Text, '#pop'), + include('keywords'), + (r'[A-Za-z]\w*', Comment.Preproc), + include('root') + ], + 'string': [ + (r'\\\(', String.Interpol, 'string-intp'), + (r'"', String, '#pop'), + (r"""\\['"\\nrt]|\\x[0-9a-fA-F]{2}|\\[0-7]{1,3}""" + r"""|\\u[0-9a-fA-F]{4}|\\U[0-9a-fA-F]{8}""", String.Escape), + (r'[^\\"]+', String), + (r'\\', String) + ], + 'string-intp': [ + (r'\(', String.Interpol, '#push'), + (r'\)', String.Interpol, '#pop'), + include('root') + ] + } + + def get_tokens_unprocessed(self, text): + from pygments.lexers._cocoa_builtins import COCOA_INTERFACES, \ + COCOA_PROTOCOLS, COCOA_PRIMITIVES + + for index, token, value in \ + RegexLexer.get_tokens_unprocessed(self, text): + if token is Name or token is Name.Class: + if value in COCOA_INTERFACES or value in COCOA_PROTOCOLS \ + or value in COCOA_PRIMITIVES: + token = Name.Builtin.Pseudo + + yield index, token, value diff --git a/.venv/lib/python3.8/site-packages/pygments/lexers/ooc.py b/.venv/lib/python3.8/site-packages/pygments/lexers/ooc.py new file mode 100644 index 00000000..e0e0f249 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/pygments/lexers/ooc.py @@ -0,0 +1,85 @@ +# -*- coding: utf-8 -*- +""" + pygments.lexers.ooc + ~~~~~~~~~~~~~~~~~~~ + + Lexers for the Ooc language. + + :copyright: Copyright 2006-2020 by the Pygments team, see AUTHORS. + :license: BSD, see LICENSE for details. +""" + +from pygments.lexer import RegexLexer, bygroups, words +from pygments.token import Text, Comment, Operator, Keyword, Name, String, \ + Number, Punctuation + +__all__ = ['OocLexer'] + + +class OocLexer(RegexLexer): + """ + For `Ooc `_ source code + + .. versionadded:: 1.2 + """ + name = 'Ooc' + aliases = ['ooc'] + filenames = ['*.ooc'] + mimetypes = ['text/x-ooc'] + + tokens = { + 'root': [ + (words(( + 'class', 'interface', 'implement', 'abstract', 'extends', 'from', + 'this', 'super', 'new', 'const', 'final', 'static', 'import', + 'use', 'extern', 'inline', 'proto', 'break', 'continue', + 'fallthrough', 'operator', 'if', 'else', 'for', 'while', 'do', + 'switch', 'case', 'as', 'in', 'version', 'return', 'true', + 'false', 'null'), prefix=r'\b', suffix=r'\b'), + Keyword), + (r'include\b', Keyword, 'include'), + (r'(cover)([ \t]+)(from)([ \t]+)(\w+[*@]?)', + bygroups(Keyword, Text, Keyword, Text, Name.Class)), + (r'(func)((?:[ \t]|\\\n)+)(~[a-z_]\w*)', + bygroups(Keyword, Text, Name.Function)), + (r'\bfunc\b', Keyword), + # Note: %= and ^= not listed on http://ooc-lang.org/syntax + (r'//.*', Comment), + (r'(?s)/\*.*?\*/', Comment.Multiline), + (r'(==?|\+=?|-[=>]?|\*=?|/=?|:=|!=?|%=?|\?|>{1,3}=?|<{1,3}=?|\.\.|' + r'&&?|\|\|?|\^=?)', Operator), + (r'(\.)([ \t]*)([a-z]\w*)', bygroups(Operator, Text, + Name.Function)), + (r'[A-Z][A-Z0-9_]+', Name.Constant), + (r'[A-Z]\w*([@*]|\[[ \t]*\])?', Name.Class), + + (r'([a-z]\w*(?:~[a-z]\w*)?)((?:[ \t]|\\\n)*)(?=\()', + bygroups(Name.Function, Text)), + (r'[a-z]\w*', Name.Variable), + + # : introduces types + (r'[:(){}\[\];,]', Punctuation), + + (r'0x[0-9a-fA-F]+', Number.Hex), + (r'0c[0-9]+', Number.Oct), + (r'0b[01]+', Number.Bin), + (r'[0-9_]\.[0-9_]*(?!\.)', Number.Float), + (r'[0-9_]+', Number.Decimal), + + (r'"(?:\\.|\\[0-7]{1,3}|\\x[a-fA-F0-9]{1,2}|[^\\"])*"', + String.Double), + (r"'(?:\\.|\\[0-9]{1,3}|\\x[a-fA-F0-9]{1,2}|[^\\\'\n])'", + String.Char), + (r'@', Punctuation), # pointer dereference + (r'\.', Punctuation), # imports or chain operator + + (r'\\[ \t\n]', Text), + (r'[ \t]+', Text), + ], + 'include': [ + (r'[\w/]+', Name), + (r',', Punctuation), + (r'[ \t]', Text), + (r'[;\n]', Text, '#pop'), + ], + } diff --git a/.venv/lib/python3.8/site-packages/pygments/lexers/other.py b/.venv/lib/python3.8/site-packages/pygments/lexers/other.py new file mode 100644 index 00000000..8cdedcfc --- /dev/null +++ b/.venv/lib/python3.8/site-packages/pygments/lexers/other.py @@ -0,0 +1,41 @@ +# -*- coding: utf-8 -*- +""" + pygments.lexers.other + ~~~~~~~~~~~~~~~~~~~~~ + + Just export lexer classes previously contained in this module. + + :copyright: Copyright 2006-2020 by the Pygments team, see AUTHORS. + :license: BSD, see LICENSE for details. +""" + +from pygments.lexers.sql import SqlLexer, MySqlLexer, SqliteConsoleLexer +from pygments.lexers.shell import BashLexer, BashSessionLexer, BatchLexer, \ + TcshLexer +from pygments.lexers.robotframework import RobotFrameworkLexer +from pygments.lexers.testing import GherkinLexer +from pygments.lexers.esoteric import BrainfuckLexer, BefungeLexer, RedcodeLexer +from pygments.lexers.prolog import LogtalkLexer +from pygments.lexers.snobol import SnobolLexer +from pygments.lexers.rebol import RebolLexer +from pygments.lexers.configs import KconfigLexer, Cfengine3Lexer +from pygments.lexers.modeling import ModelicaLexer +from pygments.lexers.scripting import AppleScriptLexer, MOOCodeLexer, \ + HybrisLexer +from pygments.lexers.graphics import PostScriptLexer, GnuplotLexer, \ + AsymptoteLexer, PovrayLexer +from pygments.lexers.business import ABAPLexer, OpenEdgeLexer, \ + GoodDataCLLexer, MaqlLexer +from pygments.lexers.automation import AutoItLexer, AutohotkeyLexer +from pygments.lexers.dsls import ProtoBufLexer, BroLexer, PuppetLexer, \ + MscgenLexer, VGLLexer +from pygments.lexers.basic import CbmBasicV2Lexer +from pygments.lexers.pawn import SourcePawnLexer, PawnLexer +from pygments.lexers.ecl import ECLLexer +from pygments.lexers.urbi import UrbiscriptLexer +from pygments.lexers.smalltalk import SmalltalkLexer, NewspeakLexer +from pygments.lexers.installers import NSISLexer, RPMSpecLexer +from pygments.lexers.textedit import AwkLexer +from pygments.lexers.smv import NuSMVLexer + +__all__ = [] diff --git a/.venv/lib/python3.8/site-packages/pygments/lexers/parasail.py b/.venv/lib/python3.8/site-packages/pygments/lexers/parasail.py new file mode 100644 index 00000000..1b626b08 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/pygments/lexers/parasail.py @@ -0,0 +1,79 @@ +# -*- coding: utf-8 -*- +""" + pygments.lexers.parasail + ~~~~~~~~~~~~~~~~~~~~~~~~ + + Lexer for ParaSail. + + :copyright: Copyright 2006-2020 by the Pygments team, see AUTHORS. + :license: BSD, see LICENSE for details. +""" + +import re + +from pygments.lexer import RegexLexer, include +from pygments.token import Text, Comment, Operator, Keyword, Name, String, \ + Number, Punctuation, Literal + +__all__ = ['ParaSailLexer'] + + +class ParaSailLexer(RegexLexer): + """ + For `ParaSail `_ source code. + + .. versionadded:: 2.1 + """ + + name = 'ParaSail' + aliases = ['parasail'] + filenames = ['*.psi', '*.psl'] + mimetypes = ['text/x-parasail'] + + flags = re.MULTILINE + + tokens = { + 'root': [ + (r'[^\S\n]+', Text), + (r'//.*?\n', Comment.Single), + (r'\b(and|or|xor)=', Operator.Word), + (r'\b(and(\s+then)?|or(\s+else)?|xor|rem|mod|' + r'(is|not)\s+null)\b', + Operator.Word), + # Keywords + (r'\b(abs|abstract|all|block|class|concurrent|const|continue|' + r'each|end|exit|extends|exports|forward|func|global|implements|' + r'import|in|interface|is|lambda|locked|new|not|null|of|op|' + r'optional|private|queued|ref|return|reverse|separate|some|' + r'type|until|var|with|' + # Control flow + r'if|then|else|elsif|case|for|while|loop)\b', + Keyword.Reserved), + (r'(abstract\s+)?(interface|class|op|func|type)', + Keyword.Declaration), + # Literals + (r'"[^"]*"', String), + (r'\\[\'ntrf"0]', String.Escape), + (r'#[a-zA-Z]\w*', Literal), # Enumeration + include('numbers'), + (r"'[^']'", String.Char), + (r'[a-zA-Z]\w*', Name), + # Operators and Punctuation + (r'(<==|==>|<=>|\*\*=|<\|=|<<=|>>=|==|!=|=\?|<=|>=|' + r'\*\*|<<|>>|=>|:=|\+=|-=|\*=|\|=|\||/=|\+|-|\*|/|' + r'\.\.|<\.\.|\.\.<|<\.\.<)', + Operator), + (r'(<|>|\[|\]|\(|\)|\||:|;|,|.|\{|\}|->)', + Punctuation), + (r'\n+', Text), + ], + 'numbers': [ + (r'\d[0-9_]*#[0-9a-fA-F][0-9a-fA-F_]*#', Number.Hex), # any base + (r'0[xX][0-9a-fA-F][0-9a-fA-F_]*', Number.Hex), # C-like hex + (r'0[bB][01][01_]*', Number.Bin), # C-like bin + (r'\d[0-9_]*\.\d[0-9_]*[eE][+-]\d[0-9_]*', # float exp + Number.Float), + (r'\d[0-9_]*\.\d[0-9_]*', Number.Float), # float + (r'\d[0-9_]*', Number.Integer), # integer + ], + } diff --git a/.venv/lib/python3.8/site-packages/pygments/lexers/parsers.py b/.venv/lib/python3.8/site-packages/pygments/lexers/parsers.py new file mode 100644 index 00000000..13a3a83c --- /dev/null +++ b/.venv/lib/python3.8/site-packages/pygments/lexers/parsers.py @@ -0,0 +1,800 @@ +# -*- coding: utf-8 -*- +""" + pygments.lexers.parsers + ~~~~~~~~~~~~~~~~~~~~~~~ + + Lexers for parser generators. + + :copyright: Copyright 2006-2020 by the Pygments team, see AUTHORS. + :license: BSD, see LICENSE for details. +""" + +import re + +from pygments.lexer import RegexLexer, DelegatingLexer, \ + include, bygroups, using +from pygments.token import Punctuation, Other, Text, Comment, Operator, \ + Keyword, Name, String, Number, Whitespace +from pygments.lexers.jvm import JavaLexer +from pygments.lexers.c_cpp import CLexer, CppLexer +from pygments.lexers.objective import ObjectiveCLexer +from pygments.lexers.d import DLexer +from pygments.lexers.dotnet import CSharpLexer +from pygments.lexers.ruby import RubyLexer +from pygments.lexers.python import PythonLexer +from pygments.lexers.perl import PerlLexer + +__all__ = ['RagelLexer', 'RagelEmbeddedLexer', 'RagelCLexer', 'RagelDLexer', + 'RagelCppLexer', 'RagelObjectiveCLexer', 'RagelRubyLexer', + 'RagelJavaLexer', 'AntlrLexer', 'AntlrPythonLexer', + 'AntlrPerlLexer', 'AntlrRubyLexer', 'AntlrCppLexer', + 'AntlrCSharpLexer', 'AntlrObjectiveCLexer', + 'AntlrJavaLexer', 'AntlrActionScriptLexer', + 'TreetopLexer', 'EbnfLexer'] + + +class RagelLexer(RegexLexer): + """ + A pure `Ragel `_ lexer. Use this for + fragments of Ragel. For ``.rl`` files, use RagelEmbeddedLexer instead + (or one of the language-specific subclasses). + + .. versionadded:: 1.1 + """ + + name = 'Ragel' + aliases = ['ragel'] + filenames = [] + + tokens = { + 'whitespace': [ + (r'\s+', Whitespace) + ], + 'comments': [ + (r'\#.*$', Comment), + ], + 'keywords': [ + (r'(access|action|alphtype)\b', Keyword), + (r'(getkey|write|machine|include)\b', Keyword), + (r'(any|ascii|extend|alpha|digit|alnum|lower|upper)\b', Keyword), + (r'(xdigit|cntrl|graph|print|punct|space|zlen|empty)\b', Keyword) + ], + 'numbers': [ + (r'0x[0-9A-Fa-f]+', Number.Hex), + (r'[+-]?[0-9]+', Number.Integer), + ], + 'literals': [ + (r'"(\\\\|\\"|[^"])*"', String), # double quote string + (r"'(\\\\|\\'|[^'])*'", String), # single quote string + (r'\[(\\\\|\\\]|[^\]])*\]', String), # square bracket literals + (r'/(?!\*)(\\\\|\\/|[^/])*/', String.Regex), # regular expressions + ], + 'identifiers': [ + (r'[a-zA-Z_]\w*', Name.Variable), + ], + 'operators': [ + (r',', Operator), # Join + (r'\||&|--?', Operator), # Union, Intersection and Subtraction + (r'\.|<:|:>>?', Operator), # Concatention + (r':', Operator), # Label + (r'->', Operator), # Epsilon Transition + (r'(>|\$|%|<|@|<>)(/|eof\b)', Operator), # EOF Actions + (r'(>|\$|%|<|@|<>)(!|err\b)', Operator), # Global Error Actions + (r'(>|\$|%|<|@|<>)(\^|lerr\b)', Operator), # Local Error Actions + (r'(>|\$|%|<|@|<>)(~|to\b)', Operator), # To-State Actions + (r'(>|\$|%|<|@|<>)(\*|from\b)', Operator), # From-State Actions + (r'>|@|\$|%', Operator), # Transition Actions and Priorities + (r'\*|\?|\+|\{[0-9]*,[0-9]*\}', Operator), # Repetition + (r'!|\^', Operator), # Negation + (r'\(|\)', Operator), # Grouping + ], + 'root': [ + include('literals'), + include('whitespace'), + include('comments'), + include('keywords'), + include('numbers'), + include('identifiers'), + include('operators'), + (r'\{', Punctuation, 'host'), + (r'=', Operator), + (r';', Punctuation), + ], + 'host': [ + (r'(' + r'|'.join(( # keep host code in largest possible chunks + r'[^{}\'"/#]+', # exclude unsafe characters + r'[^\\]\\[{}]', # allow escaped { or } + + # strings and comments may safely contain unsafe characters + r'"(\\\\|\\"|[^"])*"', # double quote string + r"'(\\\\|\\'|[^'])*'", # single quote string + r'//.*$\n?', # single line comment + r'/\*(.|\n)*?\*/', # multi-line javadoc-style comment + r'\#.*$\n?', # ruby comment + + # regular expression: There's no reason for it to start + # with a * and this stops confusion with comments. + r'/(?!\*)(\\\\|\\/|[^/])*/', + + # / is safe now that we've handled regex and javadoc comments + r'/', + )) + r')+', Other), + + (r'\{', Punctuation, '#push'), + (r'\}', Punctuation, '#pop'), + ], + } + + +class RagelEmbeddedLexer(RegexLexer): + """ + A lexer for `Ragel`_ embedded in a host language file. + + This will only highlight Ragel statements. If you want host language + highlighting then call the language-specific Ragel lexer. + + .. versionadded:: 1.1 + """ + + name = 'Embedded Ragel' + aliases = ['ragel-em'] + filenames = ['*.rl'] + + tokens = { + 'root': [ + (r'(' + r'|'.join(( # keep host code in largest possible chunks + r'[^%\'"/#]+', # exclude unsafe characters + r'%(?=[^%]|$)', # a single % sign is okay, just not 2 of them + + # strings and comments may safely contain unsafe characters + r'"(\\\\|\\"|[^"])*"', # double quote string + r"'(\\\\|\\'|[^'])*'", # single quote string + r'/\*(.|\n)*?\*/', # multi-line javadoc-style comment + r'//.*$\n?', # single line comment + r'\#.*$\n?', # ruby/ragel comment + r'/(?!\*)(\\\\|\\/|[^/])*/', # regular expression + + # / is safe now that we've handled regex and javadoc comments + r'/', + )) + r')+', Other), + + # Single Line FSM. + # Please don't put a quoted newline in a single line FSM. + # That's just mean. It will break this. + (r'(%%)(?![{%])(.*)($|;)(\n?)', bygroups(Punctuation, + using(RagelLexer), + Punctuation, Text)), + + # Multi Line FSM. + (r'(%%%%|%%)\{', Punctuation, 'multi-line-fsm'), + ], + 'multi-line-fsm': [ + (r'(' + r'|'.join(( # keep ragel code in largest possible chunks. + r'(' + r'|'.join(( + r'[^}\'"\[/#]', # exclude unsafe characters + r'\}(?=[^%]|$)', # } is okay as long as it's not followed by % + r'\}%(?=[^%]|$)', # ...well, one %'s okay, just not two... + r'[^\\]\\[{}]', # ...and } is okay if it's escaped + + # allow / if it's preceded with one of these symbols + # (ragel EOF actions) + r'(>|\$|%|<|@|<>)/', + + # specifically allow regex followed immediately by * + # so it doesn't get mistaken for a comment + r'/(?!\*)(\\\\|\\/|[^/])*/\*', + + # allow / as long as it's not followed by another / or by a * + r'/(?=[^/*]|$)', + + # We want to match as many of these as we can in one block. + # Not sure if we need the + sign here, + # does it help performance? + )) + r')+', + + # strings and comments may safely contain unsafe characters + r'"(\\\\|\\"|[^"])*"', # double quote string + r"'(\\\\|\\'|[^'])*'", # single quote string + r"\[(\\\\|\\\]|[^\]])*\]", # square bracket literal + r'/\*(.|\n)*?\*/', # multi-line javadoc-style comment + r'//.*$\n?', # single line comment + r'\#.*$\n?', # ruby/ragel comment + )) + r')+', using(RagelLexer)), + + (r'\}%%', Punctuation, '#pop'), + ] + } + + def analyse_text(text): + return '@LANG: indep' in text + + +class RagelRubyLexer(DelegatingLexer): + """ + A lexer for `Ragel`_ in a Ruby host file. + + .. versionadded:: 1.1 + """ + + name = 'Ragel in Ruby Host' + aliases = ['ragel-ruby', 'ragel-rb'] + filenames = ['*.rl'] + + def __init__(self, **options): + super().__init__(RubyLexer, RagelEmbeddedLexer, **options) + + def analyse_text(text): + return '@LANG: ruby' in text + + +class RagelCLexer(DelegatingLexer): + """ + A lexer for `Ragel`_ in a C host file. + + .. versionadded:: 1.1 + """ + + name = 'Ragel in C Host' + aliases = ['ragel-c'] + filenames = ['*.rl'] + + def __init__(self, **options): + super().__init__(CLexer, RagelEmbeddedLexer, **options) + + def analyse_text(text): + return '@LANG: c' in text + + +class RagelDLexer(DelegatingLexer): + """ + A lexer for `Ragel`_ in a D host file. + + .. versionadded:: 1.1 + """ + + name = 'Ragel in D Host' + aliases = ['ragel-d'] + filenames = ['*.rl'] + + def __init__(self, **options): + super().__init__(DLexer, RagelEmbeddedLexer, **options) + + def analyse_text(text): + return '@LANG: d' in text + + +class RagelCppLexer(DelegatingLexer): + """ + A lexer for `Ragel`_ in a CPP host file. + + .. versionadded:: 1.1 + """ + + name = 'Ragel in CPP Host' + aliases = ['ragel-cpp'] + filenames = ['*.rl'] + + def __init__(self, **options): + super().__init__(CppLexer, RagelEmbeddedLexer, **options) + + def analyse_text(text): + return '@LANG: c++' in text + + +class RagelObjectiveCLexer(DelegatingLexer): + """ + A lexer for `Ragel`_ in an Objective C host file. + + .. versionadded:: 1.1 + """ + + name = 'Ragel in Objective C Host' + aliases = ['ragel-objc'] + filenames = ['*.rl'] + + def __init__(self, **options): + super().__init__(ObjectiveCLexer, RagelEmbeddedLexer, **options) + + def analyse_text(text): + return '@LANG: objc' in text + + +class RagelJavaLexer(DelegatingLexer): + """ + A lexer for `Ragel`_ in a Java host file. + + .. versionadded:: 1.1 + """ + + name = 'Ragel in Java Host' + aliases = ['ragel-java'] + filenames = ['*.rl'] + + def __init__(self, **options): + super().__init__(JavaLexer, RagelEmbeddedLexer, **options) + + def analyse_text(text): + return '@LANG: java' in text + + +class AntlrLexer(RegexLexer): + """ + Generic `ANTLR`_ Lexer. + Should not be called directly, instead + use DelegatingLexer for your target language. + + .. versionadded:: 1.1 + + .. _ANTLR: http://www.antlr.org/ + """ + + name = 'ANTLR' + aliases = ['antlr'] + filenames = [] + + _id = r'[A-Za-z]\w*' + _TOKEN_REF = r'[A-Z]\w*' + _RULE_REF = r'[a-z]\w*' + _STRING_LITERAL = r'\'(?:\\\\|\\\'|[^\']*)\'' + _INT = r'[0-9]+' + + tokens = { + 'whitespace': [ + (r'\s+', Whitespace), + ], + 'comments': [ + (r'//.*$', Comment), + (r'/\*(.|\n)*?\*/', Comment), + ], + 'root': [ + include('whitespace'), + include('comments'), + + (r'(lexer|parser|tree)?(\s*)(grammar\b)(\s*)(' + _id + ')(;)', + bygroups(Keyword, Whitespace, Keyword, Whitespace, Name.Class, + Punctuation)), + # optionsSpec + (r'options\b', Keyword, 'options'), + # tokensSpec + (r'tokens\b', Keyword, 'tokens'), + # attrScope + (r'(scope)(\s*)(' + _id + r')(\s*)(\{)', + bygroups(Keyword, Whitespace, Name.Variable, Whitespace, + Punctuation), 'action'), + # exception + (r'(catch|finally)\b', Keyword, 'exception'), + # action + (r'(@' + _id + r')(\s*)(::)?(\s*)(' + _id + r')(\s*)(\{)', + bygroups(Name.Label, Whitespace, Punctuation, Whitespace, + Name.Label, Whitespace, Punctuation), 'action'), + # rule + (r'((?:protected|private|public|fragment)\b)?(\s*)(' + _id + ')(!)?', + bygroups(Keyword, Whitespace, Name.Label, Punctuation), + ('rule-alts', 'rule-prelims')), + ], + 'exception': [ + (r'\n', Whitespace, '#pop'), + (r'\s', Whitespace), + include('comments'), + + (r'\[', Punctuation, 'nested-arg-action'), + (r'\{', Punctuation, 'action'), + ], + 'rule-prelims': [ + include('whitespace'), + include('comments'), + + (r'returns\b', Keyword), + (r'\[', Punctuation, 'nested-arg-action'), + (r'\{', Punctuation, 'action'), + # throwsSpec + (r'(throws)(\s+)(' + _id + ')', + bygroups(Keyword, Whitespace, Name.Label)), + (r'(,)(\s*)(' + _id + ')', + bygroups(Punctuation, Whitespace, Name.Label)), # Additional throws + # optionsSpec + (r'options\b', Keyword, 'options'), + # ruleScopeSpec - scope followed by target language code or name of action + # TODO finish implementing other possibilities for scope + # L173 ANTLRv3.g from ANTLR book + (r'(scope)(\s+)(\{)', bygroups(Keyword, Whitespace, Punctuation), + 'action'), + (r'(scope)(\s+)(' + _id + r')(\s*)(;)', + bygroups(Keyword, Whitespace, Name.Label, Whitespace, Punctuation)), + # ruleAction + (r'(@' + _id + r')(\s*)(\{)', + bygroups(Name.Label, Whitespace, Punctuation), 'action'), + # finished prelims, go to rule alts! + (r':', Punctuation, '#pop') + ], + 'rule-alts': [ + include('whitespace'), + include('comments'), + + # These might need to go in a separate 'block' state triggered by ( + (r'options\b', Keyword, 'options'), + (r':', Punctuation), + + # literals + (r"'(\\\\|\\'|[^'])*'", String), + (r'"(\\\\|\\"|[^"])*"', String), + (r'<<([^>]|>[^>])>>', String), + # identifiers + # Tokens start with capital letter. + (r'\$?[A-Z_]\w*', Name.Constant), + # Rules start with small letter. + (r'\$?[a-z_]\w*', Name.Variable), + # operators + (r'(\+|\||->|=>|=|\(|\)|\.\.|\.|\?|\*|\^|!|\#|~)', Operator), + (r',', Punctuation), + (r'\[', Punctuation, 'nested-arg-action'), + (r'\{', Punctuation, 'action'), + (r';', Punctuation, '#pop') + ], + 'tokens': [ + include('whitespace'), + include('comments'), + (r'\{', Punctuation), + (r'(' + _TOKEN_REF + r')(\s*)(=)?(\s*)(' + _STRING_LITERAL + + r')?(\s*)(;)', + bygroups(Name.Label, Whitespace, Punctuation, Whitespace, + String, Whitespace, Punctuation)), + (r'\}', Punctuation, '#pop'), + ], + 'options': [ + include('whitespace'), + include('comments'), + (r'\{', Punctuation), + (r'(' + _id + r')(\s*)(=)(\s*)(' + + '|'.join((_id, _STRING_LITERAL, _INT, r'\*')) + r')(\s*)(;)', + bygroups(Name.Variable, Whitespace, Punctuation, Whitespace, + Text, Whitespace, Punctuation)), + (r'\}', Punctuation, '#pop'), + ], + 'action': [ + (r'(' + r'|'.join(( # keep host code in largest possible chunks + r'[^${}\'"/\\]+', # exclude unsafe characters + + # strings and comments may safely contain unsafe characters + r'"(\\\\|\\"|[^"])*"', # double quote string + r"'(\\\\|\\'|[^'])*'", # single quote string + r'//.*$\n?', # single line comment + r'/\*(.|\n)*?\*/', # multi-line javadoc-style comment + + # regular expression: There's no reason for it to start + # with a * and this stops confusion with comments. + r'/(?!\*)(\\\\|\\/|[^/])*/', + + # backslashes are okay, as long as we are not backslashing a % + r'\\(?!%)', + + # Now that we've handled regex and javadoc comments + # it's safe to let / through. + r'/', + )) + r')+', Other), + (r'(\\)(%)', bygroups(Punctuation, Other)), + (r'(\$[a-zA-Z]+)(\.?)(text|value)?', + bygroups(Name.Variable, Punctuation, Name.Property)), + (r'\{', Punctuation, '#push'), + (r'\}', Punctuation, '#pop'), + ], + 'nested-arg-action': [ + (r'(' + r'|'.join(( # keep host code in largest possible chunks. + r'[^$\[\]\'"/]+', # exclude unsafe characters + + # strings and comments may safely contain unsafe characters + r'"(\\\\|\\"|[^"])*"', # double quote string + r"'(\\\\|\\'|[^'])*'", # single quote string + r'//.*$\n?', # single line comment + r'/\*(.|\n)*?\*/', # multi-line javadoc-style comment + + # regular expression: There's no reason for it to start + # with a * and this stops confusion with comments. + r'/(?!\*)(\\\\|\\/|[^/])*/', + + # Now that we've handled regex and javadoc comments + # it's safe to let / through. + r'/', + )) + r')+', Other), + + + (r'\[', Punctuation, '#push'), + (r'\]', Punctuation, '#pop'), + (r'(\$[a-zA-Z]+)(\.?)(text|value)?', + bygroups(Name.Variable, Punctuation, Name.Property)), + (r'(\\\\|\\\]|\\\[|[^\[\]])+', Other), + ] + } + + def analyse_text(text): + return re.search(r'^\s*grammar\s+[a-zA-Z0-9]+\s*;', text, re.M) + + +# http://www.antlr.org/wiki/display/ANTLR3/Code+Generation+Targets + +class AntlrCppLexer(DelegatingLexer): + """ + `ANTLR`_ with CPP Target + + .. versionadded:: 1.1 + """ + + name = 'ANTLR With CPP Target' + aliases = ['antlr-cpp'] + filenames = ['*.G', '*.g'] + + def __init__(self, **options): + super().__init__(CppLexer, AntlrLexer, **options) + + def analyse_text(text): + return AntlrLexer.analyse_text(text) and \ + re.search(r'^\s*language\s*=\s*C\s*;', text, re.M) + + +class AntlrObjectiveCLexer(DelegatingLexer): + """ + `ANTLR`_ with Objective-C Target + + .. versionadded:: 1.1 + """ + + name = 'ANTLR With ObjectiveC Target' + aliases = ['antlr-objc'] + filenames = ['*.G', '*.g'] + + def __init__(self, **options): + super().__init__(ObjectiveCLexer, AntlrLexer, **options) + + def analyse_text(text): + return AntlrLexer.analyse_text(text) and \ + re.search(r'^\s*language\s*=\s*ObjC\s*;', text) + + +class AntlrCSharpLexer(DelegatingLexer): + """ + `ANTLR`_ with C# Target + + .. versionadded:: 1.1 + """ + + name = 'ANTLR With C# Target' + aliases = ['antlr-csharp', 'antlr-c#'] + filenames = ['*.G', '*.g'] + + def __init__(self, **options): + super().__init__(CSharpLexer, AntlrLexer, **options) + + def analyse_text(text): + return AntlrLexer.analyse_text(text) and \ + re.search(r'^\s*language\s*=\s*CSharp2\s*;', text, re.M) + + +class AntlrPythonLexer(DelegatingLexer): + """ + `ANTLR`_ with Python Target + + .. versionadded:: 1.1 + """ + + name = 'ANTLR With Python Target' + aliases = ['antlr-python'] + filenames = ['*.G', '*.g'] + + def __init__(self, **options): + super().__init__(PythonLexer, AntlrLexer, **options) + + def analyse_text(text): + return AntlrLexer.analyse_text(text) and \ + re.search(r'^\s*language\s*=\s*Python\s*;', text, re.M) + + +class AntlrJavaLexer(DelegatingLexer): + """ + `ANTLR`_ with Java Target + + .. versionadded:: 1. + """ + + name = 'ANTLR With Java Target' + aliases = ['antlr-java'] + filenames = ['*.G', '*.g'] + + def __init__(self, **options): + super().__init__(JavaLexer, AntlrLexer, **options) + + def analyse_text(text): + # Antlr language is Java by default + return AntlrLexer.analyse_text(text) and 0.9 + + +class AntlrRubyLexer(DelegatingLexer): + """ + `ANTLR`_ with Ruby Target + + .. versionadded:: 1.1 + """ + + name = 'ANTLR With Ruby Target' + aliases = ['antlr-ruby', 'antlr-rb'] + filenames = ['*.G', '*.g'] + + def __init__(self, **options): + super().__init__(RubyLexer, AntlrLexer, **options) + + def analyse_text(text): + return AntlrLexer.analyse_text(text) and \ + re.search(r'^\s*language\s*=\s*Ruby\s*;', text, re.M) + + +class AntlrPerlLexer(DelegatingLexer): + """ + `ANTLR`_ with Perl Target + + .. versionadded:: 1.1 + """ + + name = 'ANTLR With Perl Target' + aliases = ['antlr-perl'] + filenames = ['*.G', '*.g'] + + def __init__(self, **options): + super().__init__(PerlLexer, AntlrLexer, **options) + + def analyse_text(text): + return AntlrLexer.analyse_text(text) and \ + re.search(r'^\s*language\s*=\s*Perl5\s*;', text, re.M) + + +class AntlrActionScriptLexer(DelegatingLexer): + """ + `ANTLR`_ with ActionScript Target + + .. versionadded:: 1.1 + """ + + name = 'ANTLR With ActionScript Target' + aliases = ['antlr-as', 'antlr-actionscript'] + filenames = ['*.G', '*.g'] + + def __init__(self, **options): + from pygments.lexers.actionscript import ActionScriptLexer + super().__init__(ActionScriptLexer, AntlrLexer, **options) + + def analyse_text(text): + return AntlrLexer.analyse_text(text) and \ + re.search(r'^\s*language\s*=\s*ActionScript\s*;', text, re.M) + + +class TreetopBaseLexer(RegexLexer): + """ + A base lexer for `Treetop `_ grammars. + Not for direct use; use TreetopLexer instead. + + .. versionadded:: 1.6 + """ + + tokens = { + 'root': [ + include('space'), + (r'require[ \t]+[^\n\r]+[\n\r]', Other), + (r'module\b', Keyword.Namespace, 'module'), + (r'grammar\b', Keyword, 'grammar'), + ], + 'module': [ + include('space'), + include('end'), + (r'module\b', Keyword, '#push'), + (r'grammar\b', Keyword, 'grammar'), + (r'[A-Z]\w*(?:::[A-Z]\w*)*', Name.Namespace), + ], + 'grammar': [ + include('space'), + include('end'), + (r'rule\b', Keyword, 'rule'), + (r'include\b', Keyword, 'include'), + (r'[A-Z]\w*', Name), + ], + 'include': [ + include('space'), + (r'[A-Z]\w*(?:::[A-Z]\w*)*', Name.Class, '#pop'), + ], + 'rule': [ + include('space'), + include('end'), + (r'"(\\\\|\\"|[^"])*"', String.Double), + (r"'(\\\\|\\'|[^'])*'", String.Single), + (r'([A-Za-z_]\w*)(:)', bygroups(Name.Label, Punctuation)), + (r'[A-Za-z_]\w*', Name), + (r'[()]', Punctuation), + (r'[?+*/&!~]', Operator), + (r'\[(?:\\.|\[:\^?[a-z]+:\]|[^\\\]])+\]', String.Regex), + (r'([0-9]*)(\.\.)([0-9]*)', + bygroups(Number.Integer, Operator, Number.Integer)), + (r'(<)([^>]+)(>)', bygroups(Punctuation, Name.Class, Punctuation)), + (r'\{', Punctuation, 'inline_module'), + (r'\.', String.Regex), + ], + 'inline_module': [ + (r'\{', Other, 'ruby'), + (r'\}', Punctuation, '#pop'), + (r'[^{}]+', Other), + ], + 'ruby': [ + (r'\{', Other, '#push'), + (r'\}', Other, '#pop'), + (r'[^{}]+', Other), + ], + 'space': [ + (r'[ \t\n\r]+', Whitespace), + (r'#[^\n]*', Comment.Single), + ], + 'end': [ + (r'end\b', Keyword, '#pop'), + ], + } + + +class TreetopLexer(DelegatingLexer): + """ + A lexer for `Treetop `_ grammars. + + .. versionadded:: 1.6 + """ + + name = 'Treetop' + aliases = ['treetop'] + filenames = ['*.treetop', '*.tt'] + + def __init__(self, **options): + super().__init__(RubyLexer, TreetopBaseLexer, **options) + + +class EbnfLexer(RegexLexer): + """ + Lexer for `ISO/IEC 14977 EBNF + `_ + grammars. + + .. versionadded:: 2.0 + """ + + name = 'EBNF' + aliases = ['ebnf'] + filenames = ['*.ebnf'] + mimetypes = ['text/x-ebnf'] + + tokens = { + 'root': [ + include('whitespace'), + include('comment_start'), + include('identifier'), + (r'=', Operator, 'production'), + ], + 'production': [ + include('whitespace'), + include('comment_start'), + include('identifier'), + (r'"[^"]*"', String.Double), + (r"'[^']*'", String.Single), + (r'(\?[^?]*\?)', Name.Entity), + (r'[\[\]{}(),|]', Punctuation), + (r'-', Operator), + (r';', Punctuation, '#pop'), + (r'\.', Punctuation, '#pop'), + ], + 'whitespace': [ + (r'\s+', Text), + ], + 'comment_start': [ + (r'\(\*', Comment.Multiline, 'comment'), + ], + 'comment': [ + (r'[^*)]', Comment.Multiline), + include('comment_start'), + (r'\*\)', Comment.Multiline, '#pop'), + (r'[*)]', Comment.Multiline), + ], + 'identifier': [ + (r'([a-zA-Z][\w \-]*)', Keyword), + ], + } diff --git a/.venv/lib/python3.8/site-packages/pygments/lexers/pascal.py b/.venv/lib/python3.8/site-packages/pygments/lexers/pascal.py new file mode 100644 index 00000000..6756e234 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/pygments/lexers/pascal.py @@ -0,0 +1,644 @@ +# -*- coding: utf-8 -*- +""" + pygments.lexers.pascal + ~~~~~~~~~~~~~~~~~~~~~~ + + Lexers for Pascal family languages. + + :copyright: Copyright 2006-2020 by the Pygments team, see AUTHORS. + :license: BSD, see LICENSE for details. +""" + +import re + +from pygments.lexer import Lexer, RegexLexer, include, bygroups, words, \ + using, this, default +from pygments.util import get_bool_opt, get_list_opt +from pygments.token import Text, Comment, Operator, Keyword, Name, String, \ + Number, Punctuation, Error +from pygments.scanner import Scanner + +# compatibility import +from pygments.lexers.modula2 import Modula2Lexer + +__all__ = ['DelphiLexer', 'AdaLexer'] + + +class DelphiLexer(Lexer): + """ + For `Delphi `_ (Borland Object Pascal), + Turbo Pascal and Free Pascal source code. + + Additional options accepted: + + `turbopascal` + Highlight Turbo Pascal specific keywords (default: ``True``). + `delphi` + Highlight Borland Delphi specific keywords (default: ``True``). + `freepascal` + Highlight Free Pascal specific keywords (default: ``True``). + `units` + A list of units that should be considered builtin, supported are + ``System``, ``SysUtils``, ``Classes`` and ``Math``. + Default is to consider all of them builtin. + """ + name = 'Delphi' + aliases = ['delphi', 'pas', 'pascal', 'objectpascal'] + filenames = ['*.pas', '*.dpr'] + mimetypes = ['text/x-pascal'] + + TURBO_PASCAL_KEYWORDS = ( + 'absolute', 'and', 'array', 'asm', 'begin', 'break', 'case', + 'const', 'constructor', 'continue', 'destructor', 'div', 'do', + 'downto', 'else', 'end', 'file', 'for', 'function', 'goto', + 'if', 'implementation', 'in', 'inherited', 'inline', 'interface', + 'label', 'mod', 'nil', 'not', 'object', 'of', 'on', 'operator', + 'or', 'packed', 'procedure', 'program', 'record', 'reintroduce', + 'repeat', 'self', 'set', 'shl', 'shr', 'string', 'then', 'to', + 'type', 'unit', 'until', 'uses', 'var', 'while', 'with', 'xor' + ) + + DELPHI_KEYWORDS = ( + 'as', 'class', 'except', 'exports', 'finalization', 'finally', + 'initialization', 'is', 'library', 'on', 'property', 'raise', + 'threadvar', 'try' + ) + + FREE_PASCAL_KEYWORDS = ( + 'dispose', 'exit', 'false', 'new', 'true' + ) + + BLOCK_KEYWORDS = { + 'begin', 'class', 'const', 'constructor', 'destructor', 'end', + 'finalization', 'function', 'implementation', 'initialization', + 'label', 'library', 'operator', 'procedure', 'program', 'property', + 'record', 'threadvar', 'type', 'unit', 'uses', 'var' + } + + FUNCTION_MODIFIERS = { + 'alias', 'cdecl', 'export', 'inline', 'interrupt', 'nostackframe', + 'pascal', 'register', 'safecall', 'softfloat', 'stdcall', + 'varargs', 'name', 'dynamic', 'near', 'virtual', 'external', + 'override', 'assembler' + } + + # XXX: those aren't global. but currently we know no way for defining + # them just for the type context. + DIRECTIVES = { + 'absolute', 'abstract', 'assembler', 'cppdecl', 'default', 'far', + 'far16', 'forward', 'index', 'oldfpccall', 'private', 'protected', + 'published', 'public' + } + + BUILTIN_TYPES = { + 'ansichar', 'ansistring', 'bool', 'boolean', 'byte', 'bytebool', + 'cardinal', 'char', 'comp', 'currency', 'double', 'dword', + 'extended', 'int64', 'integer', 'iunknown', 'longbool', 'longint', + 'longword', 'pansichar', 'pansistring', 'pbool', 'pboolean', + 'pbyte', 'pbytearray', 'pcardinal', 'pchar', 'pcomp', 'pcurrency', + 'pdate', 'pdatetime', 'pdouble', 'pdword', 'pextended', 'phandle', + 'pint64', 'pinteger', 'plongint', 'plongword', 'pointer', + 'ppointer', 'pshortint', 'pshortstring', 'psingle', 'psmallint', + 'pstring', 'pvariant', 'pwidechar', 'pwidestring', 'pword', + 'pwordarray', 'pwordbool', 'real', 'real48', 'shortint', + 'shortstring', 'single', 'smallint', 'string', 'tclass', 'tdate', + 'tdatetime', 'textfile', 'thandle', 'tobject', 'ttime', 'variant', + 'widechar', 'widestring', 'word', 'wordbool' + } + + BUILTIN_UNITS = { + 'System': ( + 'abs', 'acquireexceptionobject', 'addr', 'ansitoutf8', + 'append', 'arctan', 'assert', 'assigned', 'assignfile', + 'beginthread', 'blockread', 'blockwrite', 'break', 'chdir', + 'chr', 'close', 'closefile', 'comptocurrency', 'comptodouble', + 'concat', 'continue', 'copy', 'cos', 'dec', 'delete', + 'dispose', 'doubletocomp', 'endthread', 'enummodules', + 'enumresourcemodules', 'eof', 'eoln', 'erase', 'exceptaddr', + 'exceptobject', 'exclude', 'exit', 'exp', 'filepos', 'filesize', + 'fillchar', 'finalize', 'findclasshinstance', 'findhinstance', + 'findresourcehinstance', 'flush', 'frac', 'freemem', + 'get8087cw', 'getdir', 'getlasterror', 'getmem', + 'getmemorymanager', 'getmodulefilename', 'getvariantmanager', + 'halt', 'hi', 'high', 'inc', 'include', 'initialize', 'insert', + 'int', 'ioresult', 'ismemorymanagerset', 'isvariantmanagerset', + 'length', 'ln', 'lo', 'low', 'mkdir', 'move', 'new', 'odd', + 'olestrtostring', 'olestrtostrvar', 'ord', 'paramcount', + 'paramstr', 'pi', 'pos', 'pred', 'ptr', 'pucs4chars', 'random', + 'randomize', 'read', 'readln', 'reallocmem', + 'releaseexceptionobject', 'rename', 'reset', 'rewrite', 'rmdir', + 'round', 'runerror', 'seek', 'seekeof', 'seekeoln', + 'set8087cw', 'setlength', 'setlinebreakstyle', + 'setmemorymanager', 'setstring', 'settextbuf', + 'setvariantmanager', 'sin', 'sizeof', 'slice', 'sqr', 'sqrt', + 'str', 'stringofchar', 'stringtoolestr', 'stringtowidechar', + 'succ', 'swap', 'trunc', 'truncate', 'typeinfo', + 'ucs4stringtowidestring', 'unicodetoutf8', 'uniquestring', + 'upcase', 'utf8decode', 'utf8encode', 'utf8toansi', + 'utf8tounicode', 'val', 'vararrayredim', 'varclear', + 'widecharlentostring', 'widecharlentostrvar', + 'widechartostring', 'widechartostrvar', + 'widestringtoucs4string', 'write', 'writeln' + ), + 'SysUtils': ( + 'abort', 'addexitproc', 'addterminateproc', 'adjustlinebreaks', + 'allocmem', 'ansicomparefilename', 'ansicomparestr', + 'ansicomparetext', 'ansidequotedstr', 'ansiextractquotedstr', + 'ansilastchar', 'ansilowercase', 'ansilowercasefilename', + 'ansipos', 'ansiquotedstr', 'ansisamestr', 'ansisametext', + 'ansistrcomp', 'ansistricomp', 'ansistrlastchar', 'ansistrlcomp', + 'ansistrlicomp', 'ansistrlower', 'ansistrpos', 'ansistrrscan', + 'ansistrscan', 'ansistrupper', 'ansiuppercase', + 'ansiuppercasefilename', 'appendstr', 'assignstr', 'beep', + 'booltostr', 'bytetocharindex', 'bytetocharlen', 'bytetype', + 'callterminateprocs', 'changefileext', 'charlength', + 'chartobyteindex', 'chartobytelen', 'comparemem', 'comparestr', + 'comparetext', 'createdir', 'createguid', 'currentyear', + 'currtostr', 'currtostrf', 'date', 'datetimetofiledate', + 'datetimetostr', 'datetimetostring', 'datetimetosystemtime', + 'datetimetotimestamp', 'datetostr', 'dayofweek', 'decodedate', + 'decodedatefully', 'decodetime', 'deletefile', 'directoryexists', + 'diskfree', 'disksize', 'disposestr', 'encodedate', 'encodetime', + 'exceptionerrormessage', 'excludetrailingbackslash', + 'excludetrailingpathdelimiter', 'expandfilename', + 'expandfilenamecase', 'expanduncfilename', 'extractfiledir', + 'extractfiledrive', 'extractfileext', 'extractfilename', + 'extractfilepath', 'extractrelativepath', 'extractshortpathname', + 'fileage', 'fileclose', 'filecreate', 'filedatetodatetime', + 'fileexists', 'filegetattr', 'filegetdate', 'fileisreadonly', + 'fileopen', 'fileread', 'filesearch', 'fileseek', 'filesetattr', + 'filesetdate', 'filesetreadonly', 'filewrite', 'finalizepackage', + 'findclose', 'findcmdlineswitch', 'findfirst', 'findnext', + 'floattocurr', 'floattodatetime', 'floattodecimal', 'floattostr', + 'floattostrf', 'floattotext', 'floattotextfmt', 'fmtloadstr', + 'fmtstr', 'forcedirectories', 'format', 'formatbuf', 'formatcurr', + 'formatdatetime', 'formatfloat', 'freeandnil', 'getcurrentdir', + 'getenvironmentvariable', 'getfileversion', 'getformatsettings', + 'getlocaleformatsettings', 'getmodulename', 'getpackagedescription', + 'getpackageinfo', 'gettime', 'guidtostring', 'incamonth', + 'includetrailingbackslash', 'includetrailingpathdelimiter', + 'incmonth', 'initializepackage', 'interlockeddecrement', + 'interlockedexchange', 'interlockedexchangeadd', + 'interlockedincrement', 'inttohex', 'inttostr', 'isdelimiter', + 'isequalguid', 'isleapyear', 'ispathdelimiter', 'isvalidident', + 'languages', 'lastdelimiter', 'loadpackage', 'loadstr', + 'lowercase', 'msecstotimestamp', 'newstr', 'nextcharindex', 'now', + 'outofmemoryerror', 'quotedstr', 'raiselastoserror', + 'raiselastwin32error', 'removedir', 'renamefile', 'replacedate', + 'replacetime', 'safeloadlibrary', 'samefilename', 'sametext', + 'setcurrentdir', 'showexception', 'sleep', 'stralloc', 'strbufsize', + 'strbytetype', 'strcat', 'strcharlength', 'strcomp', 'strcopy', + 'strdispose', 'strecopy', 'strend', 'strfmt', 'stricomp', + 'stringreplace', 'stringtoguid', 'strlcat', 'strlcomp', 'strlcopy', + 'strlen', 'strlfmt', 'strlicomp', 'strlower', 'strmove', 'strnew', + 'strnextchar', 'strpas', 'strpcopy', 'strplcopy', 'strpos', + 'strrscan', 'strscan', 'strtobool', 'strtobooldef', 'strtocurr', + 'strtocurrdef', 'strtodate', 'strtodatedef', 'strtodatetime', + 'strtodatetimedef', 'strtofloat', 'strtofloatdef', 'strtoint', + 'strtoint64', 'strtoint64def', 'strtointdef', 'strtotime', + 'strtotimedef', 'strupper', 'supports', 'syserrormessage', + 'systemtimetodatetime', 'texttofloat', 'time', 'timestamptodatetime', + 'timestamptomsecs', 'timetostr', 'trim', 'trimleft', 'trimright', + 'tryencodedate', 'tryencodetime', 'tryfloattocurr', 'tryfloattodatetime', + 'trystrtobool', 'trystrtocurr', 'trystrtodate', 'trystrtodatetime', + 'trystrtofloat', 'trystrtoint', 'trystrtoint64', 'trystrtotime', + 'unloadpackage', 'uppercase', 'widecomparestr', 'widecomparetext', + 'widefmtstr', 'wideformat', 'wideformatbuf', 'widelowercase', + 'widesamestr', 'widesametext', 'wideuppercase', 'win32check', + 'wraptext' + ), + 'Classes': ( + 'activateclassgroup', 'allocatehwnd', 'bintohex', 'checksynchronize', + 'collectionsequal', 'countgenerations', 'deallocatehwnd', 'equalrect', + 'extractstrings', 'findclass', 'findglobalcomponent', 'getclass', + 'groupdescendantswith', 'hextobin', 'identtoint', + 'initinheritedcomponent', 'inttoident', 'invalidpoint', + 'isuniqueglobalcomponentname', 'linestart', 'objectbinarytotext', + 'objectresourcetotext', 'objecttexttobinary', 'objecttexttoresource', + 'pointsequal', 'readcomponentres', 'readcomponentresex', + 'readcomponentresfile', 'rect', 'registerclass', 'registerclassalias', + 'registerclasses', 'registercomponents', 'registerintegerconsts', + 'registernoicon', 'registernonactivex', 'smallpoint', 'startclassgroup', + 'teststreamformat', 'unregisterclass', 'unregisterclasses', + 'unregisterintegerconsts', 'unregistermoduleclasses', + 'writecomponentresfile' + ), + 'Math': ( + 'arccos', 'arccosh', 'arccot', 'arccoth', 'arccsc', 'arccsch', 'arcsec', + 'arcsech', 'arcsin', 'arcsinh', 'arctan2', 'arctanh', 'ceil', + 'comparevalue', 'cosecant', 'cosh', 'cot', 'cotan', 'coth', 'csc', + 'csch', 'cycletodeg', 'cycletograd', 'cycletorad', 'degtocycle', + 'degtograd', 'degtorad', 'divmod', 'doubledecliningbalance', + 'ensurerange', 'floor', 'frexp', 'futurevalue', 'getexceptionmask', + 'getprecisionmode', 'getroundmode', 'gradtocycle', 'gradtodeg', + 'gradtorad', 'hypot', 'inrange', 'interestpayment', 'interestrate', + 'internalrateofreturn', 'intpower', 'isinfinite', 'isnan', 'iszero', + 'ldexp', 'lnxp1', 'log10', 'log2', 'logn', 'max', 'maxintvalue', + 'maxvalue', 'mean', 'meanandstddev', 'min', 'minintvalue', 'minvalue', + 'momentskewkurtosis', 'netpresentvalue', 'norm', 'numberofperiods', + 'payment', 'periodpayment', 'poly', 'popnstddev', 'popnvariance', + 'power', 'presentvalue', 'radtocycle', 'radtodeg', 'radtograd', + 'randg', 'randomrange', 'roundto', 'samevalue', 'sec', 'secant', + 'sech', 'setexceptionmask', 'setprecisionmode', 'setroundmode', + 'sign', 'simpleroundto', 'sincos', 'sinh', 'slndepreciation', 'stddev', + 'sum', 'sumint', 'sumofsquares', 'sumsandsquares', 'syddepreciation', + 'tan', 'tanh', 'totalvariance', 'variance' + ) + } + + ASM_REGISTERS = { + 'ah', 'al', 'ax', 'bh', 'bl', 'bp', 'bx', 'ch', 'cl', 'cr0', + 'cr1', 'cr2', 'cr3', 'cr4', 'cs', 'cx', 'dh', 'di', 'dl', 'dr0', + 'dr1', 'dr2', 'dr3', 'dr4', 'dr5', 'dr6', 'dr7', 'ds', 'dx', + 'eax', 'ebp', 'ebx', 'ecx', 'edi', 'edx', 'es', 'esi', 'esp', + 'fs', 'gs', 'mm0', 'mm1', 'mm2', 'mm3', 'mm4', 'mm5', 'mm6', + 'mm7', 'si', 'sp', 'ss', 'st0', 'st1', 'st2', 'st3', 'st4', 'st5', + 'st6', 'st7', 'xmm0', 'xmm1', 'xmm2', 'xmm3', 'xmm4', 'xmm5', + 'xmm6', 'xmm7' + } + + ASM_INSTRUCTIONS = { + 'aaa', 'aad', 'aam', 'aas', 'adc', 'add', 'and', 'arpl', 'bound', + 'bsf', 'bsr', 'bswap', 'bt', 'btc', 'btr', 'bts', 'call', 'cbw', + 'cdq', 'clc', 'cld', 'cli', 'clts', 'cmc', 'cmova', 'cmovae', + 'cmovb', 'cmovbe', 'cmovc', 'cmovcxz', 'cmove', 'cmovg', + 'cmovge', 'cmovl', 'cmovle', 'cmovna', 'cmovnae', 'cmovnb', + 'cmovnbe', 'cmovnc', 'cmovne', 'cmovng', 'cmovnge', 'cmovnl', + 'cmovnle', 'cmovno', 'cmovnp', 'cmovns', 'cmovnz', 'cmovo', + 'cmovp', 'cmovpe', 'cmovpo', 'cmovs', 'cmovz', 'cmp', 'cmpsb', + 'cmpsd', 'cmpsw', 'cmpxchg', 'cmpxchg486', 'cmpxchg8b', 'cpuid', + 'cwd', 'cwde', 'daa', 'das', 'dec', 'div', 'emms', 'enter', 'hlt', + 'ibts', 'icebp', 'idiv', 'imul', 'in', 'inc', 'insb', 'insd', + 'insw', 'int', 'int01', 'int03', 'int1', 'int3', 'into', 'invd', + 'invlpg', 'iret', 'iretd', 'iretw', 'ja', 'jae', 'jb', 'jbe', + 'jc', 'jcxz', 'jcxz', 'je', 'jecxz', 'jg', 'jge', 'jl', 'jle', + 'jmp', 'jna', 'jnae', 'jnb', 'jnbe', 'jnc', 'jne', 'jng', 'jnge', + 'jnl', 'jnle', 'jno', 'jnp', 'jns', 'jnz', 'jo', 'jp', 'jpe', + 'jpo', 'js', 'jz', 'lahf', 'lar', 'lcall', 'lds', 'lea', 'leave', + 'les', 'lfs', 'lgdt', 'lgs', 'lidt', 'ljmp', 'lldt', 'lmsw', + 'loadall', 'loadall286', 'lock', 'lodsb', 'lodsd', 'lodsw', + 'loop', 'loope', 'loopne', 'loopnz', 'loopz', 'lsl', 'lss', 'ltr', + 'mov', 'movd', 'movq', 'movsb', 'movsd', 'movsw', 'movsx', + 'movzx', 'mul', 'neg', 'nop', 'not', 'or', 'out', 'outsb', 'outsd', + 'outsw', 'pop', 'popa', 'popad', 'popaw', 'popf', 'popfd', 'popfw', + 'push', 'pusha', 'pushad', 'pushaw', 'pushf', 'pushfd', 'pushfw', + 'rcl', 'rcr', 'rdmsr', 'rdpmc', 'rdshr', 'rdtsc', 'rep', 'repe', + 'repne', 'repnz', 'repz', 'ret', 'retf', 'retn', 'rol', 'ror', + 'rsdc', 'rsldt', 'rsm', 'sahf', 'sal', 'salc', 'sar', 'sbb', + 'scasb', 'scasd', 'scasw', 'seta', 'setae', 'setb', 'setbe', + 'setc', 'setcxz', 'sete', 'setg', 'setge', 'setl', 'setle', + 'setna', 'setnae', 'setnb', 'setnbe', 'setnc', 'setne', 'setng', + 'setnge', 'setnl', 'setnle', 'setno', 'setnp', 'setns', 'setnz', + 'seto', 'setp', 'setpe', 'setpo', 'sets', 'setz', 'sgdt', 'shl', + 'shld', 'shr', 'shrd', 'sidt', 'sldt', 'smi', 'smint', 'smintold', + 'smsw', 'stc', 'std', 'sti', 'stosb', 'stosd', 'stosw', 'str', + 'sub', 'svdc', 'svldt', 'svts', 'syscall', 'sysenter', 'sysexit', + 'sysret', 'test', 'ud1', 'ud2', 'umov', 'verr', 'verw', 'wait', + 'wbinvd', 'wrmsr', 'wrshr', 'xadd', 'xbts', 'xchg', 'xlat', + 'xlatb', 'xor' + } + + def __init__(self, **options): + Lexer.__init__(self, **options) + self.keywords = set() + if get_bool_opt(options, 'turbopascal', True): + self.keywords.update(self.TURBO_PASCAL_KEYWORDS) + if get_bool_opt(options, 'delphi', True): + self.keywords.update(self.DELPHI_KEYWORDS) + if get_bool_opt(options, 'freepascal', True): + self.keywords.update(self.FREE_PASCAL_KEYWORDS) + self.builtins = set() + for unit in get_list_opt(options, 'units', list(self.BUILTIN_UNITS)): + self.builtins.update(self.BUILTIN_UNITS[unit]) + + def get_tokens_unprocessed(self, text): + scanner = Scanner(text, re.DOTALL | re.MULTILINE | re.IGNORECASE) + stack = ['initial'] + in_function_block = False + in_property_block = False + was_dot = False + next_token_is_function = False + next_token_is_property = False + collect_labels = False + block_labels = set() + brace_balance = [0, 0] + + while not scanner.eos: + token = Error + + if stack[-1] == 'initial': + if scanner.scan(r'\s+'): + token = Text + elif scanner.scan(r'\{.*?\}|\(\*.*?\*\)'): + if scanner.match.startswith('$'): + token = Comment.Preproc + else: + token = Comment.Multiline + elif scanner.scan(r'//.*?$'): + token = Comment.Single + elif scanner.scan(r'[-+*\/=<>:;,.@\^]'): + token = Operator + # stop label highlighting on next ";" + if collect_labels and scanner.match == ';': + collect_labels = False + elif scanner.scan(r'[\(\)\[\]]+'): + token = Punctuation + # abort function naming ``foo = Function(...)`` + next_token_is_function = False + # if we are in a function block we count the open + # braces because ootherwise it's impossible to + # determine the end of the modifier context + if in_function_block or in_property_block: + if scanner.match == '(': + brace_balance[0] += 1 + elif scanner.match == ')': + brace_balance[0] -= 1 + elif scanner.match == '[': + brace_balance[1] += 1 + elif scanner.match == ']': + brace_balance[1] -= 1 + elif scanner.scan(r'[A-Za-z_][A-Za-z_0-9]*'): + lowercase_name = scanner.match.lower() + if lowercase_name == 'result': + token = Name.Builtin.Pseudo + elif lowercase_name in self.keywords: + token = Keyword + # if we are in a special block and a + # block ending keyword occours (and the parenthesis + # is balanced) we end the current block context + if (in_function_block or in_property_block) and \ + lowercase_name in self.BLOCK_KEYWORDS and \ + brace_balance[0] <= 0 and \ + brace_balance[1] <= 0: + in_function_block = False + in_property_block = False + brace_balance = [0, 0] + block_labels = set() + if lowercase_name in ('label', 'goto'): + collect_labels = True + elif lowercase_name == 'asm': + stack.append('asm') + elif lowercase_name == 'property': + in_property_block = True + next_token_is_property = True + elif lowercase_name in ('procedure', 'operator', + 'function', 'constructor', + 'destructor'): + in_function_block = True + next_token_is_function = True + # we are in a function block and the current name + # is in the set of registered modifiers. highlight + # it as pseudo keyword + elif in_function_block and \ + lowercase_name in self.FUNCTION_MODIFIERS: + token = Keyword.Pseudo + # if we are in a property highlight some more + # modifiers + elif in_property_block and \ + lowercase_name in ('read', 'write'): + token = Keyword.Pseudo + next_token_is_function = True + # if the last iteration set next_token_is_function + # to true we now want this name highlighted as + # function. so do that and reset the state + elif next_token_is_function: + # Look if the next token is a dot. If yes it's + # not a function, but a class name and the + # part after the dot a function name + if scanner.test(r'\s*\.\s*'): + token = Name.Class + # it's not a dot, our job is done + else: + token = Name.Function + next_token_is_function = False + # same for properties + elif next_token_is_property: + token = Name.Property + next_token_is_property = False + # Highlight this token as label and add it + # to the list of known labels + elif collect_labels: + token = Name.Label + block_labels.add(scanner.match.lower()) + # name is in list of known labels + elif lowercase_name in block_labels: + token = Name.Label + elif lowercase_name in self.BUILTIN_TYPES: + token = Keyword.Type + elif lowercase_name in self.DIRECTIVES: + token = Keyword.Pseudo + # builtins are just builtins if the token + # before isn't a dot + elif not was_dot and lowercase_name in self.builtins: + token = Name.Builtin + else: + token = Name + elif scanner.scan(r"'"): + token = String + stack.append('string') + elif scanner.scan(r'\#(\d+|\$[0-9A-Fa-f]+)'): + token = String.Char + elif scanner.scan(r'\$[0-9A-Fa-f]+'): + token = Number.Hex + elif scanner.scan(r'\d+(?![eE]|\.[^.])'): + token = Number.Integer + elif scanner.scan(r'\d+(\.\d+([eE][+-]?\d+)?|[eE][+-]?\d+)'): + token = Number.Float + else: + # if the stack depth is deeper than once, pop + if len(stack) > 1: + stack.pop() + scanner.get_char() + + elif stack[-1] == 'string': + if scanner.scan(r"''"): + token = String.Escape + elif scanner.scan(r"'"): + token = String + stack.pop() + elif scanner.scan(r"[^']*"): + token = String + else: + scanner.get_char() + stack.pop() + + elif stack[-1] == 'asm': + if scanner.scan(r'\s+'): + token = Text + elif scanner.scan(r'end'): + token = Keyword + stack.pop() + elif scanner.scan(r'\{.*?\}|\(\*.*?\*\)'): + if scanner.match.startswith('$'): + token = Comment.Preproc + else: + token = Comment.Multiline + elif scanner.scan(r'//.*?$'): + token = Comment.Single + elif scanner.scan(r"'"): + token = String + stack.append('string') + elif scanner.scan(r'@@[A-Za-z_][A-Za-z_0-9]*'): + token = Name.Label + elif scanner.scan(r'[A-Za-z_][A-Za-z_0-9]*'): + lowercase_name = scanner.match.lower() + if lowercase_name in self.ASM_INSTRUCTIONS: + token = Keyword + elif lowercase_name in self.ASM_REGISTERS: + token = Name.Builtin + else: + token = Name + elif scanner.scan(r'[-+*\/=<>:;,.@\^]+'): + token = Operator + elif scanner.scan(r'[\(\)\[\]]+'): + token = Punctuation + elif scanner.scan(r'\$[0-9A-Fa-f]+'): + token = Number.Hex + elif scanner.scan(r'\d+(?![eE]|\.[^.])'): + token = Number.Integer + elif scanner.scan(r'\d+(\.\d+([eE][+-]?\d+)?|[eE][+-]?\d+)'): + token = Number.Float + else: + scanner.get_char() + stack.pop() + + # save the dot!!!11 + if scanner.match.strip(): + was_dot = scanner.match == '.' + yield scanner.start_pos, token, scanner.match or '' + + +class AdaLexer(RegexLexer): + """ + For Ada source code. + + .. versionadded:: 1.3 + """ + + name = 'Ada' + aliases = ['ada', 'ada95', 'ada2005'] + filenames = ['*.adb', '*.ads', '*.ada'] + mimetypes = ['text/x-ada'] + + flags = re.MULTILINE | re.IGNORECASE + + tokens = { + 'root': [ + (r'[^\S\n]+', Text), + (r'--.*?\n', Comment.Single), + (r'[^\S\n]+', Text), + (r'function|procedure|entry', Keyword.Declaration, 'subprogram'), + (r'(subtype|type)(\s+)(\w+)', + bygroups(Keyword.Declaration, Text, Keyword.Type), 'type_def'), + (r'task|protected', Keyword.Declaration), + (r'(subtype)(\s+)', bygroups(Keyword.Declaration, Text)), + (r'(end)(\s+)', bygroups(Keyword.Reserved, Text), 'end'), + (r'(pragma)(\s+)(\w+)', bygroups(Keyword.Reserved, Text, + Comment.Preproc)), + (r'(true|false|null)\b', Keyword.Constant), + (words(( + 'Address', 'Byte', 'Boolean', 'Character', 'Controlled', 'Count', + 'Cursor', 'Duration', 'File_Mode', 'File_Type', 'Float', 'Generator', + 'Integer', 'Long_Float', 'Long_Integer', 'Long_Long_Float', + 'Long_Long_Integer', 'Natural', 'Positive', 'Reference_Type', + 'Short_Float', 'Short_Integer', 'Short_Short_Float', + 'Short_Short_Integer', 'String', 'Wide_Character', 'Wide_String'), + suffix=r'\b'), + Keyword.Type), + (r'(and(\s+then)?|in|mod|not|or(\s+else)|rem)\b', Operator.Word), + (r'generic|private', Keyword.Declaration), + (r'package', Keyword.Declaration, 'package'), + (r'array\b', Keyword.Reserved, 'array_def'), + (r'(with|use)(\s+)', bygroups(Keyword.Namespace, Text), 'import'), + (r'(\w+)(\s*)(:)(\s*)(constant)', + bygroups(Name.Constant, Text, Punctuation, Text, + Keyword.Reserved)), + (r'<<\w+>>', Name.Label), + (r'(\w+)(\s*)(:)(\s*)(declare|begin|loop|for|while)', + bygroups(Name.Label, Text, Punctuation, Text, Keyword.Reserved)), + (words(( + 'abort', 'abs', 'abstract', 'accept', 'access', 'aliased', 'all', + 'array', 'at', 'begin', 'body', 'case', 'constant', 'declare', + 'delay', 'delta', 'digits', 'do', 'else', 'elsif', 'end', 'entry', + 'exception', 'exit', 'interface', 'for', 'goto', 'if', 'is', 'limited', + 'loop', 'new', 'null', 'of', 'or', 'others', 'out', 'overriding', + 'pragma', 'protected', 'raise', 'range', 'record', 'renames', 'requeue', + 'return', 'reverse', 'select', 'separate', 'some', 'subtype', + 'synchronized', 'task', 'tagged', 'terminate', 'then', 'type', 'until', + 'when', 'while', 'xor'), prefix=r'\b', suffix=r'\b'), + Keyword.Reserved), + (r'"[^"]*"', String), + include('attribute'), + include('numbers'), + (r"'[^']'", String.Character), + (r'(\w+)(\s*|[(,])', bygroups(Name, using(this))), + (r"(<>|=>|:=|[()|:;,.'])", Punctuation), + (r'[*<>+=/&-]', Operator), + (r'\n+', Text), + ], + 'numbers': [ + (r'[0-9_]+#[0-9a-f_\.]+#', Number.Hex), + (r'[0-9_]+\.[0-9_]*', Number.Float), + (r'[0-9_]+', Number.Integer), + ], + 'attribute': [ + (r"(')(\w+)", bygroups(Punctuation, Name.Attribute)), + ], + 'subprogram': [ + (r'\(', Punctuation, ('#pop', 'formal_part')), + (r';', Punctuation, '#pop'), + (r'is\b', Keyword.Reserved, '#pop'), + (r'"[^"]+"|\w+', Name.Function), + include('root'), + ], + 'end': [ + ('(if|case|record|loop|select)', Keyword.Reserved), + (r'"[^"]+"|[\w.]+', Name.Function), + (r'\s+', Text), + (';', Punctuation, '#pop'), + ], + 'type_def': [ + (r';', Punctuation, '#pop'), + (r'\(', Punctuation, 'formal_part'), + (r'with|and|use', Keyword.Reserved), + (r'array\b', Keyword.Reserved, ('#pop', 'array_def')), + (r'record\b', Keyword.Reserved, ('record_def')), + (r'(null record)(;)', bygroups(Keyword.Reserved, Punctuation), '#pop'), + include('root'), + ], + 'array_def': [ + (r';', Punctuation, '#pop'), + (r'(\w+)(\s+)(range)', bygroups(Keyword.Type, Text, Keyword.Reserved)), + include('root'), + ], + 'record_def': [ + (r'end record', Keyword.Reserved, '#pop'), + include('root'), + ], + 'import': [ + (r'[\w.]+', Name.Namespace, '#pop'), + default('#pop'), + ], + 'formal_part': [ + (r'\)', Punctuation, '#pop'), + (r'\w+', Name.Variable), + (r',|:[^=]', Punctuation), + (r'(in|not|null|out|access)\b', Keyword.Reserved), + include('root'), + ], + 'package': [ + ('body', Keyword.Declaration), + (r'is\s+new|renames', Keyword.Reserved), + ('is', Keyword.Reserved, '#pop'), + (';', Punctuation, '#pop'), + (r'\(', Punctuation, 'package_instantiation'), + (r'([\w.]+)', Name.Class), + include('root'), + ], + 'package_instantiation': [ + (r'("[^"]+"|\w+)(\s+)(=>)', bygroups(Name.Variable, Text, Punctuation)), + (r'[\w.\'"]', Text), + (r'\)', Punctuation, '#pop'), + include('root'), + ], + } diff --git a/.venv/lib/python3.8/site-packages/pygments/lexers/pawn.py b/.venv/lib/python3.8/site-packages/pygments/lexers/pawn.py new file mode 100644 index 00000000..bc06d0d5 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/pygments/lexers/pawn.py @@ -0,0 +1,205 @@ +# -*- coding: utf-8 -*- +""" + pygments.lexers.pawn + ~~~~~~~~~~~~~~~~~~~~ + + Lexers for the Pawn languages. + + :copyright: Copyright 2006-2020 by the Pygments team, see AUTHORS. + :license: BSD, see LICENSE for details. +""" + +from pygments.lexer import RegexLexer +from pygments.token import Text, Comment, Operator, Keyword, Name, String, \ + Number, Punctuation, Error +from pygments.util import get_bool_opt + +__all__ = ['SourcePawnLexer', 'PawnLexer'] + + +class SourcePawnLexer(RegexLexer): + """ + For SourcePawn source code with preprocessor directives. + + .. versionadded:: 1.6 + """ + name = 'SourcePawn' + aliases = ['sp'] + filenames = ['*.sp'] + mimetypes = ['text/x-sourcepawn'] + + #: optional Comment or Whitespace + _ws = r'(?:\s|//.*?\n|/\*.*?\*/)+' + #: only one /* */ style comment + _ws1 = r'\s*(?:/[*].*?[*]/\s*)*' + + tokens = { + 'root': [ + # preprocessor directives: without whitespace + (r'^#if\s+0', Comment.Preproc, 'if0'), + ('^#', Comment.Preproc, 'macro'), + # or with whitespace + ('^' + _ws1 + r'#if\s+0', Comment.Preproc, 'if0'), + ('^' + _ws1 + '#', Comment.Preproc, 'macro'), + (r'\n', Text), + (r'\s+', Text), + (r'\\\n', Text), # line continuation + (r'/(\\\n)?/(\n|(.|\n)*?[^\\]\n)', Comment.Single), + (r'/(\\\n)?\*(.|\n)*?\*(\\\n)?/', Comment.Multiline), + (r'[{}]', Punctuation), + (r'L?"', String, 'string'), + (r"L?'(\\.|\\[0-7]{1,3}|\\x[a-fA-F0-9]{1,2}|[^\\\'\n])'", String.Char), + (r'(\d+\.\d*|\.\d+|\d+)[eE][+-]?\d+[LlUu]*', Number.Float), + (r'(\d+\.\d*|\.\d+|\d+[fF])[fF]?', Number.Float), + (r'0x[0-9a-fA-F]+[LlUu]*', Number.Hex), + (r'0[0-7]+[LlUu]*', Number.Oct), + (r'\d+[LlUu]*', Number.Integer), + (r'\*/', Error), + (r'[~!%^&*+=|?:<>/-]', Operator), + (r'[()\[\],.;]', Punctuation), + (r'(case|const|continue|native|' + r'default|else|enum|for|if|new|operator|' + r'public|return|sizeof|static|decl|struct|switch)\b', Keyword), + (r'(bool|Float)\b', Keyword.Type), + (r'(true|false)\b', Keyword.Constant), + (r'[a-zA-Z_]\w*', Name), + ], + 'string': [ + (r'"', String, '#pop'), + (r'\\([\\abfnrtv"\']|x[a-fA-F0-9]{2,4}|[0-7]{1,3})', String.Escape), + (r'[^\\"\n]+', String), # all other characters + (r'\\\n', String), # line continuation + (r'\\', String), # stray backslash + ], + 'macro': [ + (r'[^/\n]+', Comment.Preproc), + (r'/\*(.|\n)*?\*/', Comment.Multiline), + (r'//.*?\n', Comment.Single, '#pop'), + (r'/', Comment.Preproc), + (r'(?<=\\)\n', Comment.Preproc), + (r'\n', Comment.Preproc, '#pop'), + ], + 'if0': [ + (r'^\s*#if.*?(?/-]', Operator), + (r'[()\[\],.;]', Punctuation), + (r'(switch|case|default|const|new|static|char|continue|break|' + r'if|else|for|while|do|operator|enum|' + r'public|return|sizeof|tagof|state|goto)\b', Keyword), + (r'(bool|Float)\b', Keyword.Type), + (r'(true|false)\b', Keyword.Constant), + (r'[a-zA-Z_]\w*', Name), + ], + 'string': [ + (r'"', String, '#pop'), + (r'\\([\\abfnrtv"\']|x[a-fA-F0-9]{2,4}|[0-7]{1,3})', String.Escape), + (r'[^\\"\n]+', String), # all other characters + (r'\\\n', String), # line continuation + (r'\\', String), # stray backslash + ], + 'macro': [ + (r'[^/\n]+', Comment.Preproc), + (r'/\*(.|\n)*?\*/', Comment.Multiline), + (r'//.*?\n', Comment.Single, '#pop'), + (r'/', Comment.Preproc), + (r'(?<=\\)\n', Comment.Preproc), + (r'\n', Comment.Preproc, '#pop'), + ], + 'if0': [ + (r'^\s*#if.*?(?`_ source code. + """ + + name = 'Perl' + aliases = ['perl', 'pl'] + filenames = ['*.pl', '*.pm', '*.t', '*.perl'] + mimetypes = ['text/x-perl', 'application/x-perl'] + + flags = re.DOTALL | re.MULTILINE + # TODO: give this to a perl guy who knows how to parse perl... + tokens = { + 'balanced-regex': [ + (r'/(\\\\|\\[^\\]|[^\\/])*/[egimosx]*', String.Regex, '#pop'), + (r'!(\\\\|\\[^\\]|[^\\!])*![egimosx]*', String.Regex, '#pop'), + (r'\\(\\\\|[^\\])*\\[egimosx]*', String.Regex, '#pop'), + (r'\{(\\\\|\\[^\\]|[^\\}])*\}[egimosx]*', String.Regex, '#pop'), + (r'<(\\\\|\\[^\\]|[^\\>])*>[egimosx]*', String.Regex, '#pop'), + (r'\[(\\\\|\\[^\\]|[^\\\]])*\][egimosx]*', String.Regex, '#pop'), + (r'\((\\\\|\\[^\\]|[^\\)])*\)[egimosx]*', String.Regex, '#pop'), + (r'@(\\\\|\\[^\\]|[^\\@])*@[egimosx]*', String.Regex, '#pop'), + (r'%(\\\\|\\[^\\]|[^\\%])*%[egimosx]*', String.Regex, '#pop'), + (r'\$(\\\\|\\[^\\]|[^\\$])*\$[egimosx]*', String.Regex, '#pop'), + ], + 'root': [ + (r'\A\#!.+?$', Comment.Hashbang), + (r'\#.*?$', Comment.Single), + (r'^=[a-zA-Z0-9]+\s+.*?\n=cut', Comment.Multiline), + (words(( + 'case', 'continue', 'do', 'else', 'elsif', 'for', 'foreach', + 'if', 'last', 'my', 'next', 'our', 'redo', 'reset', 'then', + 'unless', 'until', 'while', 'print', 'new', 'BEGIN', + 'CHECK', 'INIT', 'END', 'return'), suffix=r'\b'), + Keyword), + (r'(format)(\s+)(\w+)(\s*)(=)(\s*\n)', + bygroups(Keyword, Text, Name, Text, Punctuation, Text), 'format'), + (r'(eq|lt|gt|le|ge|ne|not|and|or|cmp)\b', Operator.Word), + # common delimiters + (r's/(\\\\|\\[^\\]|[^\\/])*/(\\\\|\\[^\\]|[^\\/])*/[egimosx]*', + String.Regex), + (r's!(\\\\|\\!|[^!])*!(\\\\|\\!|[^!])*![egimosx]*', String.Regex), + (r's\\(\\\\|[^\\])*\\(\\\\|[^\\])*\\[egimosx]*', String.Regex), + (r's@(\\\\|\\[^\\]|[^\\@])*@(\\\\|\\[^\\]|[^\\@])*@[egimosx]*', + String.Regex), + (r's%(\\\\|\\[^\\]|[^\\%])*%(\\\\|\\[^\\]|[^\\%])*%[egimosx]*', + String.Regex), + # balanced delimiters + (r's\{(\\\\|\\[^\\]|[^\\}])*\}\s*', String.Regex, 'balanced-regex'), + (r's<(\\\\|\\[^\\]|[^\\>])*>\s*', String.Regex, 'balanced-regex'), + (r's\[(\\\\|\\[^\\]|[^\\\]])*\]\s*', String.Regex, + 'balanced-regex'), + (r's\((\\\\|\\[^\\]|[^\\)])*\)\s*', String.Regex, + 'balanced-regex'), + + (r'm?/(\\\\|\\[^\\]|[^\\/\n])*/[gcimosx]*', String.Regex), + (r'm(?=[/!\\{<\[(@%$])', String.Regex, 'balanced-regex'), + (r'((?<==~)|(?<=\())\s*/(\\\\|\\[^\\]|[^\\/])*/[gcimosx]*', + String.Regex), + (r'\s+', Text), + (words(( + 'abs', 'accept', 'alarm', 'atan2', 'bind', 'binmode', 'bless', 'caller', 'chdir', + 'chmod', 'chomp', 'chop', 'chown', 'chr', 'chroot', 'close', 'closedir', 'connect', + 'continue', 'cos', 'crypt', 'dbmclose', 'dbmopen', 'defined', 'delete', 'die', + 'dump', 'each', 'endgrent', 'endhostent', 'endnetent', 'endprotoent', + 'endpwent', 'endservent', 'eof', 'eval', 'exec', 'exists', 'exit', 'exp', 'fcntl', + 'fileno', 'flock', 'fork', 'format', 'formline', 'getc', 'getgrent', 'getgrgid', + 'getgrnam', 'gethostbyaddr', 'gethostbyname', 'gethostent', 'getlogin', + 'getnetbyaddr', 'getnetbyname', 'getnetent', 'getpeername', 'getpgrp', + 'getppid', 'getpriority', 'getprotobyname', 'getprotobynumber', + 'getprotoent', 'getpwent', 'getpwnam', 'getpwuid', 'getservbyname', + 'getservbyport', 'getservent', 'getsockname', 'getsockopt', 'glob', 'gmtime', + 'goto', 'grep', 'hex', 'import', 'index', 'int', 'ioctl', 'join', 'keys', 'kill', 'last', + 'lc', 'lcfirst', 'length', 'link', 'listen', 'local', 'localtime', 'log', 'lstat', + 'map', 'mkdir', 'msgctl', 'msgget', 'msgrcv', 'msgsnd', 'my', 'next', 'oct', 'open', + 'opendir', 'ord', 'our', 'pack', 'pipe', 'pop', 'pos', 'printf', + 'prototype', 'push', 'quotemeta', 'rand', 'read', 'readdir', + 'readline', 'readlink', 'readpipe', 'recv', 'redo', 'ref', 'rename', + 'reverse', 'rewinddir', 'rindex', 'rmdir', 'scalar', 'seek', 'seekdir', + 'select', 'semctl', 'semget', 'semop', 'send', 'setgrent', 'sethostent', 'setnetent', + 'setpgrp', 'setpriority', 'setprotoent', 'setpwent', 'setservent', + 'setsockopt', 'shift', 'shmctl', 'shmget', 'shmread', 'shmwrite', 'shutdown', + 'sin', 'sleep', 'socket', 'socketpair', 'sort', 'splice', 'split', 'sprintf', 'sqrt', + 'srand', 'stat', 'study', 'substr', 'symlink', 'syscall', 'sysopen', 'sysread', + 'sysseek', 'system', 'syswrite', 'tell', 'telldir', 'tie', 'tied', 'time', 'times', 'tr', + 'truncate', 'uc', 'ucfirst', 'umask', 'undef', 'unlink', 'unpack', 'unshift', 'untie', + 'utime', 'values', 'vec', 'wait', 'waitpid', 'wantarray', 'warn', 'write'), suffix=r'\b'), + Name.Builtin), + (r'((__(DATA|DIE|WARN)__)|(STD(IN|OUT|ERR)))\b', Name.Builtin.Pseudo), + (r'(<<)([\'"]?)([a-zA-Z_]\w*)(\2;?\n.*?\n)(\3)(\n)', + bygroups(String, String, String.Delimiter, String, String.Delimiter, Text)), + (r'__END__', Comment.Preproc, 'end-part'), + (r'\$\^[ADEFHILMOPSTWX]', Name.Variable.Global), + (r"\$[\\\"\[\]'&`+*.,;=%~?@$!<>(^|/-](?!\w)", Name.Variable.Global), + (r'[$@%#]+', Name.Variable, 'varname'), + (r'0_?[0-7]+(_[0-7]+)*', Number.Oct), + (r'0x[0-9A-Fa-f]+(_[0-9A-Fa-f]+)*', Number.Hex), + (r'0b[01]+(_[01]+)*', Number.Bin), + (r'(?i)(\d*(_\d*)*\.\d+(_\d*)*|\d+(_\d*)*\.\d+(_\d*)*)(e[+-]?\d+)?', + Number.Float), + (r'(?i)\d+(_\d*)*e[+-]?\d+(_\d*)*', Number.Float), + (r'\d+(_\d+)*', Number.Integer), + (r"'(\\\\|\\[^\\]|[^'\\])*'", String), + (r'"(\\\\|\\[^\\]|[^"\\])*"', String), + (r'`(\\\\|\\[^\\]|[^`\\])*`', String.Backtick), + (r'<([^\s>]+)>', String.Regex), + (r'(q|qq|qw|qr|qx)\{', String.Other, 'cb-string'), + (r'(q|qq|qw|qr|qx)\(', String.Other, 'rb-string'), + (r'(q|qq|qw|qr|qx)\[', String.Other, 'sb-string'), + (r'(q|qq|qw|qr|qx)\<', String.Other, 'lt-string'), + (r'(q|qq|qw|qr|qx)([\W_])(.|\n)*?\2', String.Other), + (r'(package)(\s+)([a-zA-Z_]\w*(?:::[a-zA-Z_]\w*)*)', + bygroups(Keyword, Text, Name.Namespace)), + (r'(use|require|no)(\s+)([a-zA-Z_]\w*(?:::[a-zA-Z_]\w*)*)', + bygroups(Keyword, Text, Name.Namespace)), + (r'(sub)(\s+)', bygroups(Keyword, Text), 'funcname'), + (words(( + 'no', 'package', 'require', 'use'), suffix=r'\b'), + Keyword), + (r'(\[\]|\*\*|::|<<|>>|>=|<=>|<=|={3}|!=|=~|' + r'!~|&&?|\|\||\.{1,3})', Operator), + (r'[-+/*%=<>&^|!\\~]=?', Operator), + (r'[()\[\]:;,<>/?{}]', Punctuation), # yes, there's no shortage + # of punctuation in Perl! + (r'(?=\w)', Name, 'name'), + ], + 'format': [ + (r'\.\n', String.Interpol, '#pop'), + (r'[^\n]*\n', String.Interpol), + ], + 'varname': [ + (r'\s+', Text), + (r'\{', Punctuation, '#pop'), # hash syntax? + (r'\)|,', Punctuation, '#pop'), # argument specifier + (r'\w+::', Name.Namespace), + (r'[\w:]+', Name.Variable, '#pop'), + ], + 'name': [ + (r'[a-zA-Z_]\w*(::[a-zA-Z_]\w*)*(::)?(?=\s*->)', Name.Namespace, '#pop'), + (r'[a-zA-Z_]\w*(::[a-zA-Z_]\w*)*::', Name.Namespace, '#pop'), + (r'[\w:]+', Name, '#pop'), + (r'[A-Z_]+(?=\W)', Name.Constant, '#pop'), + (r'(?=\W)', Text, '#pop'), + ], + 'funcname': [ + (r'[a-zA-Z_]\w*[!?]?', Name.Function), + (r'\s+', Text), + # argument declaration + (r'(\([$@%]*\))(\s*)', bygroups(Punctuation, Text)), + (r';', Punctuation, '#pop'), + (r'.*?\{', Punctuation, '#pop'), + ], + 'cb-string': [ + (r'\\[{}\\]', String.Other), + (r'\\', String.Other), + (r'\{', String.Other, 'cb-string'), + (r'\}', String.Other, '#pop'), + (r'[^{}\\]+', String.Other) + ], + 'rb-string': [ + (r'\\[()\\]', String.Other), + (r'\\', String.Other), + (r'\(', String.Other, 'rb-string'), + (r'\)', String.Other, '#pop'), + (r'[^()]+', String.Other) + ], + 'sb-string': [ + (r'\\[\[\]\\]', String.Other), + (r'\\', String.Other), + (r'\[', String.Other, 'sb-string'), + (r'\]', String.Other, '#pop'), + (r'[^\[\]]+', String.Other) + ], + 'lt-string': [ + (r'\\[<>\\]', String.Other), + (r'\\', String.Other), + (r'\<', String.Other, 'lt-string'), + (r'\>', String.Other, '#pop'), + (r'[^<>]+', String.Other) + ], + 'end-part': [ + (r'.+', Comment.Preproc, '#pop') + ] + } + + def analyse_text(text): + if shebang_matches(text, r'perl'): + return True + + result = 0 + + if re.search(r'(?:my|our)\s+[$@%(]', text): + result += 0.9 + + if ':=' in text: + # := is not valid Perl, but it appears in unicon, so we should + # become less confident if we think we found Perl with := + result /= 2 + + return result + + +class Perl6Lexer(ExtendedRegexLexer): + """ + For `Raku `_ (a.k.a. Perl 6) source code. + + .. versionadded:: 2.0 + """ + + name = 'Perl6' + aliases = ['perl6', 'pl6', 'raku'] + filenames = ['*.pl', '*.pm', '*.nqp', '*.p6', '*.6pl', '*.p6l', '*.pl6', + '*.6pm', '*.p6m', '*.pm6', '*.t', '*.raku', '*.rakumod', + '*.rakutest', '*.rakudoc'] + mimetypes = ['text/x-perl6', 'application/x-perl6'] + flags = re.MULTILINE | re.DOTALL | re.UNICODE + + PERL6_IDENTIFIER_RANGE = r"['\w:-]" + + PERL6_KEYWORDS = ( + #Phasers + 'BEGIN','CATCH','CHECK','CLOSE','CONTROL','DOC','END','ENTER','FIRST', + 'INIT','KEEP','LAST','LEAVE','NEXT','POST','PRE','QUIT','UNDO', + #Keywords + 'anon','augment','but','class','constant','default','does','else', + 'elsif','enum','for','gather','given','grammar','has','if','import', + 'is','let','loop','made','make','method','module','multi','my','need', + 'orwith','our','proceed','proto','repeat','require','return', + 'return-rw','returns','role','rule','state','sub','submethod','subset', + 'succeed','supersede','token','try','unit','unless','until','use', + 'when','while','with','without', + #Traits + 'export','native','repr','required','rw','symbol', + ) + + PERL6_BUILTINS = ( + 'ACCEPTS','abs','abs2rel','absolute','accept','accessed','acos', + 'acosec','acosech','acosh','acotan','acotanh','acquire','act','action', + 'actions','add','add_attribute','add_enum_value','add_fallback', + 'add_method','add_parent','add_private_method','add_role','add_trustee', + 'adverb','after','all','allocate','allof','allowed','alternative-names', + 'annotations','antipair','antipairs','any','anyof','app_lifetime', + 'append','arch','archname','args','arity','Array','asec','asech','asin', + 'asinh','ASSIGN-KEY','ASSIGN-POS','assuming','ast','at','atan','atan2', + 'atanh','AT-KEY','atomic-assign','atomic-dec-fetch','atomic-fetch', + 'atomic-fetch-add','atomic-fetch-dec','atomic-fetch-inc', + 'atomic-fetch-sub','atomic-inc-fetch','AT-POS','attributes','auth', + 'await','backtrace','Bag','BagHash','bail-out','base','basename', + 'base-repeating','batch','BIND-KEY','BIND-POS','bind-stderr', + 'bind-stdin','bind-stdout','bind-udp','bits','bless','block','Bool', + 'bool-only','bounds','break','Bridge','broken','BUILD','build-date', + 'bytes','cache','callframe','calling-package','CALL-ME','callsame', + 'callwith','can','cancel','candidates','cando','can-ok','canonpath', + 'caps','caption','Capture','cas','catdir','categorize','categorize-list', + 'catfile','catpath','cause','ceiling','cglobal','changed','Channel', + 'chars','chdir','child','child-name','child-typename','chmod','chomp', + 'chop','chr','chrs','chunks','cis','classify','classify-list','cleanup', + 'clone','close','closed','close-stdin','cmp-ok','code','codes','collate', + 'column','comb','combinations','command','comment','compiler','Complex', + 'compose','compose_type','composer','condition','config', + 'configure_destroy','configure_type_checking','conj','connect', + 'constraints','construct','contains','contents','copy','cos','cosec', + 'cosech','cosh','cotan','cotanh','count','count-only','cpu-cores', + 'cpu-usage','CREATE','create_type','cross','cue','curdir','curupdir','d', + 'Date','DateTime','day','daycount','day-of-month','day-of-week', + 'day-of-year','days-in-month','declaration','decode','decoder','deepmap', + 'default','defined','DEFINITE','delayed','DELETE-KEY','DELETE-POS', + 'denominator','desc','DESTROY','destroyers','devnull','diag', + 'did-you-mean','die','dies-ok','dir','dirname','dir-sep','DISTROnames', + 'do','does','does-ok','done','done-testing','duckmap','dynamic','e', + 'eager','earlier','elems','emit','enclosing','encode','encoder', + 'encoding','end','ends-with','enum_from_value','enum_value_list', + 'enum_values','enums','eof','EVAL','eval-dies-ok','EVALFILE', + 'eval-lives-ok','exception','excludes-max','excludes-min','EXISTS-KEY', + 'EXISTS-POS','exit','exitcode','exp','expected','explicitly-manage', + 'expmod','extension','f','fail','fails-like','fc','feature','file', + 'filename','find_method','find_method_qualified','finish','first','flat', + 'flatmap','flip','floor','flunk','flush','fmt','format','formatter', + 'freeze','from','from-list','from-loop','from-posix','full', + 'full-barrier','get','get_value','getc','gist','got','grab','grabpairs', + 'grep','handle','handled','handles','hardware','has_accessor','Hash', + 'head','headers','hh-mm-ss','hidden','hides','hour','how','hyper','id', + 'illegal','im','in','indent','index','indices','indir','infinite', + 'infix','infix:<+>','infix:<->','install_method_cache','Instant', + 'instead','Int','int-bounds','interval','in-timezone','invalid-str', + 'invert','invocant','IO','IO::Notification.watch-path','is_trusted', + 'is_type','isa','is-absolute','isa-ok','is-approx','is-deeply', + 'is-hidden','is-initial-thread','is-int','is-lazy','is-leap-year', + 'isNaN','isnt','is-prime','is-relative','is-routine','is-setting', + 'is-win','item','iterator','join','keep','kept','KERNELnames','key', + 'keyof','keys','kill','kv','kxxv','l','lang','last','lastcall','later', + 'lazy','lc','leading','level','like','line','lines','link','List', + 'listen','live','lives-ok','local','lock','log','log10','lookup','lsb', + 'made','MAIN','make','Map','match','max','maxpairs','merge','message', + 'method','method_table','methods','migrate','min','minmax','minpairs', + 'minute','misplaced','Mix','MixHash','mkdir','mode','modified','month', + 'move','mro','msb','multi','multiness','my','name','named','named_names', + 'narrow','nativecast','native-descriptor','nativesizeof','new','new_type', + 'new-from-daycount','new-from-pairs','next','nextcallee','next-handle', + 'nextsame','nextwith','NFC','NFD','NFKC','NFKD','nl-in','nl-out', + 'nodemap','nok','none','norm','not','note','now','nude','Num', + 'numerator','Numeric','of','offset','offset-in-hours','offset-in-minutes', + 'ok','old','on-close','one','on-switch','open','opened','operation', + 'optional','ord','ords','orig','os-error','osname','out-buffer','pack', + 'package','package-kind','package-name','packages','pair','pairs', + 'pairup','parameter','params','parent','parent-name','parents','parse', + 'parse-base','parsefile','parse-names','parts','pass','path','path-sep', + 'payload','peer-host','peer-port','periods','perl','permutations','phaser', + 'pick','pickpairs','pid','placeholder','plan','plus','polar','poll', + 'polymod','pop','pos','positional','posix','postfix','postmatch', + 'precomp-ext','precomp-target','pred','prefix','prematch','prepend', + 'print','printf','print-nl','print-to','private','private_method_table', + 'proc','produce','Promise','prompt','protect','pull-one','push', + 'push-all','push-at-least','push-exactly','push-until-lazy','put', + 'qualifier-type','quit','r','race','radix','rand','range','Rat','raw', + 're','read','readchars','readonly','ready','Real','reallocate','reals', + 'reason','rebless','receive','recv','redispatcher','redo','reduce', + 'rel2abs','relative','release','rename','repeated','replacement', + 'report','reserved','resolve','restore','result','resume','rethrow', + 'reverse','right','rindex','rmdir','role','roles_to_compose','rolish', + 'roll','rootdir','roots','rotate','rotor','round','roundrobin', + 'routine-type','run','rwx','s','samecase','samemark','samewith','say', + 'schedule-on','scheduler','scope','sec','sech','second','seek','self', + 'send','Set','set_hidden','set_name','set_package','set_rw','set_value', + 'SetHash','set-instruments','setup_finalization','shape','share','shell', + 'shift','sibling','sigil','sign','signal','signals','signature','sin', + 'sinh','sink','sink-all','skip','skip-at-least','skip-at-least-pull-one', + 'skip-one','skip-rest','sleep','sleep-timer','sleep-until','Slip','slurp', + 'slurp-rest','slurpy','snap','snapper','so','socket-host','socket-port', + 'sort','source','source-package','spawn','SPEC','splice','split', + 'splitdir','splitpath','sprintf','spurt','sqrt','squish','srand','stable', + 'start','started','starts-with','status','stderr','stdout','Str', + 'sub_signature','subbuf','subbuf-rw','subname','subparse','subst', + 'subst-mutate','substr','substr-eq','substr-rw','subtest','succ','sum', + 'Supply','symlink','t','tail','take','take-rw','tan','tanh','tap', + 'target','target-name','tc','tclc','tell','then','throttle','throw', + 'throws-like','timezone','tmpdir','to','today','todo','toggle','to-posix', + 'total','trailing','trans','tree','trim','trim-leading','trim-trailing', + 'truncate','truncated-to','trusts','try_acquire','trying','twigil','type', + 'type_captures','typename','uc','udp','uncaught_handler','unimatch', + 'uniname','uninames','uniparse','uniprop','uniprops','unique','unival', + 'univals','unlike','unlink','unlock','unpack','unpolar','unshift', + 'unwrap','updir','USAGE','use-ok','utc','val','value','values','VAR', + 'variable','verbose-config','version','VMnames','volume','vow','w','wait', + 'warn','watch','watch-path','week','weekday-of-month','week-number', + 'week-year','WHAT','when','WHERE','WHEREFORE','WHICH','WHO', + 'whole-second','WHY','wordcase','words','workaround','wrap','write', + 'write-to','x','yada','year','yield','yyyy-mm-dd','z','zip','zip-latest', + + ) + + PERL6_BUILTIN_CLASSES = ( + #Booleans + 'False','True', + #Classes + 'Any','Array','Associative','AST','atomicint','Attribute','Backtrace', + 'Backtrace::Frame','Bag','Baggy','BagHash','Blob','Block','Bool','Buf', + 'Callable','CallFrame','Cancellation','Capture','CArray','Channel','Code', + 'compiler','Complex','ComplexStr','Cool','CurrentThreadScheduler', + 'Cursor','Date','Dateish','DateTime','Distro','Duration','Encoding', + 'Exception','Failure','FatRat','Grammar','Hash','HyperWhatever','Instant', + 'Int','int16','int32','int64','int8','IntStr','IO','IO::ArgFiles', + 'IO::CatHandle','IO::Handle','IO::Notification','IO::Path', + 'IO::Path::Cygwin','IO::Path::QNX','IO::Path::Unix','IO::Path::Win32', + 'IO::Pipe','IO::Socket','IO::Socket::Async','IO::Socket::INET','IO::Spec', + 'IO::Spec::Cygwin','IO::Spec::QNX','IO::Spec::Unix','IO::Spec::Win32', + 'IO::Special','Iterable','Iterator','Junction','Kernel','Label','List', + 'Lock','Lock::Async','long','longlong','Macro','Map','Match', + 'Metamodel::AttributeContainer','Metamodel::C3MRO','Metamodel::ClassHOW', + 'Metamodel::EnumHOW','Metamodel::Finalization','Metamodel::MethodContainer', + 'Metamodel::MROBasedMethodDispatch','Metamodel::MultipleInheritance', + 'Metamodel::Naming','Metamodel::Primitives','Metamodel::PrivateMethodContainer', + 'Metamodel::RoleContainer','Metamodel::Trusting','Method','Mix','MixHash', + 'Mixy','Mu','NFC','NFD','NFKC','NFKD','Nil','Num','num32','num64', + 'Numeric','NumStr','ObjAt','Order','Pair','Parameter','Perl','Pod::Block', + 'Pod::Block::Code','Pod::Block::Comment','Pod::Block::Declarator', + 'Pod::Block::Named','Pod::Block::Para','Pod::Block::Table','Pod::Heading', + 'Pod::Item','Pointer','Positional','PositionalBindFailover','Proc', + 'Proc::Async','Promise','Proxy','PseudoStash','QuantHash','Range','Rat', + 'Rational','RatStr','Real','Regex','Routine','Scalar','Scheduler', + 'Semaphore','Seq','Set','SetHash','Setty','Signature','size_t','Slip', + 'Stash','Str','StrDistance','Stringy','Sub','Submethod','Supplier', + 'Supplier::Preserving','Supply','Systemic','Tap','Telemetry', + 'Telemetry::Instrument::Thread','Telemetry::Instrument::Usage', + 'Telemetry::Period','Telemetry::Sampler','Thread','ThreadPoolScheduler', + 'UInt','uint16','uint32','uint64','uint8','Uni','utf8','Variable', + 'Version','VM','Whatever','WhateverCode','WrapHandle' + ) + + PERL6_OPERATORS = ( + 'X', 'Z', 'after', 'also', 'and', 'andthen', 'before', 'cmp', 'div', + 'eq', 'eqv', 'extra', 'ff', 'fff', 'ge', 'gt', 'le', 'leg', 'lt', 'm', + 'mm', 'mod', 'ne', 'or', 'orelse', 'rx', 's', 'tr', 'x', 'xor', 'xx', + '++', '--', '**', '!', '+', '-', '~', '?', '|', '||', '+^', '~^', '?^', + '^', '*', '/', '%', '%%', '+&', '+<', '+>', '~&', '~<', '~>', '?&', + 'gcd', 'lcm', '+', '-', '+|', '+^', '~|', '~^', '?|', '?^', + '~', '&', '^', 'but', 'does', '<=>', '..', '..^', '^..', '^..^', + '!=', '==', '<', '<=', '>', '>=', '~~', '===', '!eqv', + '&&', '||', '^^', '//', 'min', 'max', '??', '!!', 'ff', 'fff', 'so', + 'not', '<==', '==>', '<<==', '==>>','unicmp', + ) + + # Perl 6 has a *lot* of possible bracketing characters + # this list was lifted from STD.pm6 (https://github.com/perl6/std) + PERL6_BRACKETS = { + '\u0028': '\u0029', '\u003c': '\u003e', '\u005b': '\u005d', + '\u007b': '\u007d', '\u00ab': '\u00bb', '\u0f3a': '\u0f3b', + '\u0f3c': '\u0f3d', '\u169b': '\u169c', '\u2018': '\u2019', + '\u201a': '\u2019', '\u201b': '\u2019', '\u201c': '\u201d', + '\u201e': '\u201d', '\u201f': '\u201d', '\u2039': '\u203a', + '\u2045': '\u2046', '\u207d': '\u207e', '\u208d': '\u208e', + '\u2208': '\u220b', '\u2209': '\u220c', '\u220a': '\u220d', + '\u2215': '\u29f5', '\u223c': '\u223d', '\u2243': '\u22cd', + '\u2252': '\u2253', '\u2254': '\u2255', '\u2264': '\u2265', + '\u2266': '\u2267', '\u2268': '\u2269', '\u226a': '\u226b', + '\u226e': '\u226f', '\u2270': '\u2271', '\u2272': '\u2273', + '\u2274': '\u2275', '\u2276': '\u2277', '\u2278': '\u2279', + '\u227a': '\u227b', '\u227c': '\u227d', '\u227e': '\u227f', + '\u2280': '\u2281', '\u2282': '\u2283', '\u2284': '\u2285', + '\u2286': '\u2287', '\u2288': '\u2289', '\u228a': '\u228b', + '\u228f': '\u2290', '\u2291': '\u2292', '\u2298': '\u29b8', + '\u22a2': '\u22a3', '\u22a6': '\u2ade', '\u22a8': '\u2ae4', + '\u22a9': '\u2ae3', '\u22ab': '\u2ae5', '\u22b0': '\u22b1', + '\u22b2': '\u22b3', '\u22b4': '\u22b5', '\u22b6': '\u22b7', + '\u22c9': '\u22ca', '\u22cb': '\u22cc', '\u22d0': '\u22d1', + '\u22d6': '\u22d7', '\u22d8': '\u22d9', '\u22da': '\u22db', + '\u22dc': '\u22dd', '\u22de': '\u22df', '\u22e0': '\u22e1', + '\u22e2': '\u22e3', '\u22e4': '\u22e5', '\u22e6': '\u22e7', + '\u22e8': '\u22e9', '\u22ea': '\u22eb', '\u22ec': '\u22ed', + '\u22f0': '\u22f1', '\u22f2': '\u22fa', '\u22f3': '\u22fb', + '\u22f4': '\u22fc', '\u22f6': '\u22fd', '\u22f7': '\u22fe', + '\u2308': '\u2309', '\u230a': '\u230b', '\u2329': '\u232a', + '\u23b4': '\u23b5', '\u2768': '\u2769', '\u276a': '\u276b', + '\u276c': '\u276d', '\u276e': '\u276f', '\u2770': '\u2771', + '\u2772': '\u2773', '\u2774': '\u2775', '\u27c3': '\u27c4', + '\u27c5': '\u27c6', '\u27d5': '\u27d6', '\u27dd': '\u27de', + '\u27e2': '\u27e3', '\u27e4': '\u27e5', '\u27e6': '\u27e7', + '\u27e8': '\u27e9', '\u27ea': '\u27eb', '\u2983': '\u2984', + '\u2985': '\u2986', '\u2987': '\u2988', '\u2989': '\u298a', + '\u298b': '\u298c', '\u298d': '\u298e', '\u298f': '\u2990', + '\u2991': '\u2992', '\u2993': '\u2994', '\u2995': '\u2996', + '\u2997': '\u2998', '\u29c0': '\u29c1', '\u29c4': '\u29c5', + '\u29cf': '\u29d0', '\u29d1': '\u29d2', '\u29d4': '\u29d5', + '\u29d8': '\u29d9', '\u29da': '\u29db', '\u29f8': '\u29f9', + '\u29fc': '\u29fd', '\u2a2b': '\u2a2c', '\u2a2d': '\u2a2e', + '\u2a34': '\u2a35', '\u2a3c': '\u2a3d', '\u2a64': '\u2a65', + '\u2a79': '\u2a7a', '\u2a7d': '\u2a7e', '\u2a7f': '\u2a80', + '\u2a81': '\u2a82', '\u2a83': '\u2a84', '\u2a8b': '\u2a8c', + '\u2a91': '\u2a92', '\u2a93': '\u2a94', '\u2a95': '\u2a96', + '\u2a97': '\u2a98', '\u2a99': '\u2a9a', '\u2a9b': '\u2a9c', + '\u2aa1': '\u2aa2', '\u2aa6': '\u2aa7', '\u2aa8': '\u2aa9', + '\u2aaa': '\u2aab', '\u2aac': '\u2aad', '\u2aaf': '\u2ab0', + '\u2ab3': '\u2ab4', '\u2abb': '\u2abc', '\u2abd': '\u2abe', + '\u2abf': '\u2ac0', '\u2ac1': '\u2ac2', '\u2ac3': '\u2ac4', + '\u2ac5': '\u2ac6', '\u2acd': '\u2ace', '\u2acf': '\u2ad0', + '\u2ad1': '\u2ad2', '\u2ad3': '\u2ad4', '\u2ad5': '\u2ad6', + '\u2aec': '\u2aed', '\u2af7': '\u2af8', '\u2af9': '\u2afa', + '\u2e02': '\u2e03', '\u2e04': '\u2e05', '\u2e09': '\u2e0a', + '\u2e0c': '\u2e0d', '\u2e1c': '\u2e1d', '\u2e20': '\u2e21', + '\u3008': '\u3009', '\u300a': '\u300b', '\u300c': '\u300d', + '\u300e': '\u300f', '\u3010': '\u3011', '\u3014': '\u3015', + '\u3016': '\u3017', '\u3018': '\u3019', '\u301a': '\u301b', + '\u301d': '\u301e', '\ufd3e': '\ufd3f', '\ufe17': '\ufe18', + '\ufe35': '\ufe36', '\ufe37': '\ufe38', '\ufe39': '\ufe3a', + '\ufe3b': '\ufe3c', '\ufe3d': '\ufe3e', '\ufe3f': '\ufe40', + '\ufe41': '\ufe42', '\ufe43': '\ufe44', '\ufe47': '\ufe48', + '\ufe59': '\ufe5a', '\ufe5b': '\ufe5c', '\ufe5d': '\ufe5e', + '\uff08': '\uff09', '\uff1c': '\uff1e', '\uff3b': '\uff3d', + '\uff5b': '\uff5d', '\uff5f': '\uff60', '\uff62': '\uff63', + } + + def _build_word_match(words, boundary_regex_fragment=None, prefix='', suffix=''): + if boundary_regex_fragment is None: + return r'\b(' + prefix + r'|'.join(re.escape(x) for x in words) + \ + suffix + r')\b' + else: + return r'(? 0: + next_open_pos = text.find(opening_chars, search_pos + n_chars) + next_close_pos = text.find(closing_chars, search_pos + n_chars) + + if next_close_pos == -1: + next_close_pos = len(text) + nesting_level = 0 + elif next_open_pos != -1 and next_open_pos < next_close_pos: + nesting_level += 1 + search_pos = next_open_pos + else: # next_close_pos < next_open_pos + nesting_level -= 1 + search_pos = next_close_pos + + end_pos = next_close_pos + + if end_pos < 0: # if we didn't find a closer, just highlight the + # rest of the text in this class + end_pos = len(text) + + if adverbs is not None and re.search(r':to\b', adverbs): + heredoc_terminator = text[match.start('delimiter') + n_chars:end_pos] + end_heredoc = re.search(r'^\s*' + re.escape(heredoc_terminator) + + r'\s*$', text[end_pos:], re.MULTILINE) + + if end_heredoc: + end_pos += end_heredoc.end() + else: + end_pos = len(text) + + yield match.start(), token_class, text[match.start():end_pos + n_chars] + context.pos = end_pos + n_chars + + return callback + + def opening_brace_callback(lexer, match, context): + stack = context.stack + + yield match.start(), Text, context.text[match.start():match.end()] + context.pos = match.end() + + # if we encounter an opening brace and we're one level + # below a token state, it means we need to increment + # the nesting level for braces so we know later when + # we should return to the token rules. + if len(stack) > 2 and stack[-2] == 'token': + context.perl6_token_nesting_level += 1 + + def closing_brace_callback(lexer, match, context): + stack = context.stack + + yield match.start(), Text, context.text[match.start():match.end()] + context.pos = match.end() + + # if we encounter a free closing brace and we're one level + # below a token state, it means we need to check the nesting + # level to see if we need to return to the token state. + if len(stack) > 2 and stack[-2] == 'token': + context.perl6_token_nesting_level -= 1 + if context.perl6_token_nesting_level == 0: + stack.pop() + + def embedded_perl6_callback(lexer, match, context): + context.perl6_token_nesting_level = 1 + yield match.start(), Text, context.text[match.start():match.end()] + context.pos = match.end() + context.stack.append('root') + + # If you're modifying these rules, be careful if you need to process '{' or '}' + # characters. We have special logic for processing these characters (due to the fact + # that you can nest Perl 6 code in regex blocks), so if you need to process one of + # them, make sure you also process the corresponding one! + tokens = { + 'common': [ + (r'#[`|=](?P(?P[' + ''.join(PERL6_BRACKETS) + r'])(?P=first_char)*)', + brackets_callback(Comment.Multiline)), + (r'#[^\n]*$', Comment.Single), + (r'^(\s*)=begin\s+(\w+)\b.*?^\1=end\s+\2', Comment.Multiline), + (r'^(\s*)=for.*?\n\s*?\n', Comment.Multiline), + (r'^=.*?\n\s*?\n', Comment.Multiline), + (r'(regex|token|rule)(\s*' + PERL6_IDENTIFIER_RANGE + '+:sym)', + bygroups(Keyword, Name), 'token-sym-brackets'), + (r'(regex|token|rule)(?!' + PERL6_IDENTIFIER_RANGE + r')(\s*' + PERL6_IDENTIFIER_RANGE + '+)?', + bygroups(Keyword, Name), 'pre-token'), + # deal with a special case in the Perl 6 grammar (role q { ... }) + (r'(role)(\s+)(q)(\s*)', bygroups(Keyword, Text, Name, Text)), + (_build_word_match(PERL6_KEYWORDS, PERL6_IDENTIFIER_RANGE), Keyword), + (_build_word_match(PERL6_BUILTIN_CLASSES, PERL6_IDENTIFIER_RANGE, suffix='(?::[UD])?'), + Name.Builtin), + (_build_word_match(PERL6_BUILTINS, PERL6_IDENTIFIER_RANGE), Name.Builtin), + # copied from PerlLexer + (r'[$@%&][.^:?=!~]?' + PERL6_IDENTIFIER_RANGE + '+(?:<<.*?>>|<.*?>|«.*?»)*', + Name.Variable), + (r'\$[!/](?:<<.*?>>|<.*?>|«.*?»)*', Name.Variable.Global), + (r'::\?\w+', Name.Variable.Global), + (r'[$@%&]\*' + PERL6_IDENTIFIER_RANGE + '+(?:<<.*?>>|<.*?>|«.*?»)*', + Name.Variable.Global), + (r'\$(?:<.*?>)+', Name.Variable), + (r'(?:q|qq|Q)[a-zA-Z]?\s*(?P:[\w\s:]+)?\s*(?P(?P[^0-9a-zA-Z:\s])' + r'(?P=first_char)*)', brackets_callback(String)), + # copied from PerlLexer + (r'0_?[0-7]+(_[0-7]+)*', Number.Oct), + (r'0x[0-9A-Fa-f]+(_[0-9A-Fa-f]+)*', Number.Hex), + (r'0b[01]+(_[01]+)*', Number.Bin), + (r'(?i)(\d*(_\d*)*\.\d+(_\d*)*|\d+(_\d*)*\.\d+(_\d*)*)(e[+-]?\d+)?', + Number.Float), + (r'(?i)\d+(_\d*)*e[+-]?\d+(_\d*)*', Number.Float), + (r'\d+(_\d+)*', Number.Integer), + (r'(?<=~~)\s*/(?:\\\\|\\/|.)*?/', String.Regex), + (r'(?<=[=(,])\s*/(?:\\\\|\\/|.)*?/', String.Regex), + (r'm\w+(?=\()', Name), + (r'(?:m|ms|rx)\s*(?P:[\w\s:]+)?\s*(?P(?P[^\w:\s])' + r'(?P=first_char)*)', brackets_callback(String.Regex)), + (r'(?:s|ss|tr)\s*(?::[\w\s:]+)?\s*/(?:\\\\|\\/|.)*?/(?:\\\\|\\/|.)*?/', + String.Regex), + (r'<[^\s=].*?\S>', String), + (_build_word_match(PERL6_OPERATORS), Operator), + (r'\w' + PERL6_IDENTIFIER_RANGE + '*', Name), + (r"'(\\\\|\\[^\\]|[^'\\])*'", String), + (r'"(\\\\|\\[^\\]|[^"\\])*"', String), + ], + 'root': [ + include('common'), + (r'\{', opening_brace_callback), + (r'\}', closing_brace_callback), + (r'.+?', Text), + ], + 'pre-token': [ + include('common'), + (r'\{', Text, ('#pop', 'token')), + (r'.+?', Text), + ], + 'token-sym-brackets': [ + (r'(?P(?P[' + ''.join(PERL6_BRACKETS) + '])(?P=first_char)*)', + brackets_callback(Name), ('#pop', 'pre-token')), + default(('#pop', 'pre-token')), + ], + 'token': [ + (r'\}', Text, '#pop'), + (r'(?<=:)(?:my|our|state|constant|temp|let).*?;', using(this)), + # make sure that quotes in character classes aren't treated as strings + (r'<(?:[-!?+.]\s*)?\[.*?\]>', String.Regex), + # make sure that '#' characters in quotes aren't treated as comments + (r"(?my|our)\s+)?(?:module|class|role|enum|grammar)', line) + if class_decl: + if saw_perl_decl or class_decl.group('scope') is not None: + return True + rating = 0.05 + continue + break + + if ':=' in text: + # Same logic as above for PerlLexer + rating /= 2 + + return rating + + def __init__(self, **options): + super().__init__(**options) + self.encoding = options.get('encoding', 'utf-8') diff --git a/.venv/lib/python3.8/site-packages/pygments/lexers/php.py b/.venv/lib/python3.8/site-packages/pygments/lexers/php.py new file mode 100644 index 00000000..aab502e2 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/pygments/lexers/php.py @@ -0,0 +1,321 @@ +# -*- coding: utf-8 -*- +""" + pygments.lexers.php + ~~~~~~~~~~~~~~~~~~~ + + Lexers for PHP and related languages. + + :copyright: Copyright 2006-2020 by the Pygments team, see AUTHORS. + :license: BSD, see LICENSE for details. +""" + +import re + +from pygments.lexer import Lexer, RegexLexer, include, bygroups, default, \ + using, this, words, do_insertions +from pygments.token import Text, Comment, Operator, Keyword, Name, String, \ + Number, Punctuation, Other, Generic +from pygments.util import get_bool_opt, get_list_opt, shebang_matches + +__all__ = ['ZephirLexer', 'PsyshConsoleLexer', 'PhpLexer'] + +line_re = re.compile('.*?\n') + + +class ZephirLexer(RegexLexer): + """ + For `Zephir language `_ source code. + + Zephir is a compiled high level language aimed + to the creation of C-extensions for PHP. + + .. versionadded:: 2.0 + """ + + name = 'Zephir' + aliases = ['zephir'] + filenames = ['*.zep'] + + zephir_keywords = ['fetch', 'echo', 'isset', 'empty'] + zephir_type = ['bit', 'bits', 'string'] + + flags = re.DOTALL | re.MULTILINE + + tokens = { + 'commentsandwhitespace': [ + (r'\s+', Text), + (r'//.*?\n', Comment.Single), + (r'/\*.*?\*/', Comment.Multiline) + ], + 'slashstartsregex': [ + include('commentsandwhitespace'), + (r'/(\\.|[^[/\\\n]|\[(\\.|[^\]\\\n])*])+/' + r'([gim]+\b|\B)', String.Regex, '#pop'), + (r'/', Operator, '#pop'), + default('#pop') + ], + 'badregex': [ + (r'\n', Text, '#pop') + ], + 'root': [ + (r'^(?=\s|/)', Text, 'slashstartsregex'), + include('commentsandwhitespace'), + (r'\+\+|--|~|&&|\?|:|\|\||\\(?=\n)|' + r'(<<|>>>?|==?|!=?|->|[-<>+*%&|^/])=?', Operator, 'slashstartsregex'), + (r'[{(\[;,]', Punctuation, 'slashstartsregex'), + (r'[})\].]', Punctuation), + (r'(for|in|while|do|break|return|continue|switch|case|default|if|else|loop|' + r'require|inline|throw|try|catch|finally|new|delete|typeof|instanceof|void|' + r'namespace|use|extends|this|fetch|isset|unset|echo|fetch|likely|unlikely|' + r'empty)\b', Keyword, 'slashstartsregex'), + (r'(var|let|with|function)\b', Keyword.Declaration, 'slashstartsregex'), + (r'(abstract|boolean|bool|char|class|const|double|enum|export|extends|final|' + r'native|goto|implements|import|int|string|interface|long|ulong|char|uchar|' + r'float|unsigned|private|protected|public|short|static|self|throws|reverse|' + r'transient|volatile)\b', Keyword.Reserved), + (r'(true|false|null|undefined)\b', Keyword.Constant), + (r'(Array|Boolean|Date|_REQUEST|_COOKIE|_SESSION|' + r'_GET|_POST|_SERVER|this|stdClass|range|count|iterator|' + r'window)\b', Name.Builtin), + (r'[$a-zA-Z_][\w\\]*', Name.Other), + (r'[0-9][0-9]*\.[0-9]+([eE][0-9]+)?[fd]?', Number.Float), + (r'0x[0-9a-fA-F]+', Number.Hex), + (r'[0-9]+', Number.Integer), + (r'"(\\\\|\\"|[^"])*"', String.Double), + (r"'(\\\\|\\'|[^'])*'", String.Single), + ] + } + + +class PsyshConsoleLexer(Lexer): + """ + For `PsySH`_ console output, such as: + + .. sourcecode:: psysh + + >>> $greeting = function($name): string { + ... return "Hello, {$name}"; + ... }; + => Closure($name): string {#2371 …3} + >>> $greeting('World') + => "Hello, World" + + .. _PsySH: https://psysh.org/ + .. versionadded:: 2.7 + """ + name = 'PsySH console session for PHP' + aliases = ['psysh'] + + def __init__(self, **options): + options['startinline'] = True + Lexer.__init__(self, **options) + + def get_tokens_unprocessed(self, text): + phplexer = PhpLexer(**self.options) + curcode = '' + insertions = [] + for match in line_re.finditer(text): + line = match.group() + if line.startswith('>>> ') or line.startswith('... '): + insertions.append((len(curcode), + [(0, Generic.Prompt, line[:4])])) + curcode += line[4:] + elif line.rstrip() == '...': + insertions.append((len(curcode), + [(0, Generic.Prompt, '...')])) + curcode += line[3:] + else: + if curcode: + yield from do_insertions( + insertions, phplexer.get_tokens_unprocessed(curcode)) + curcode = '' + insertions = [] + yield match.start(), Generic.Output, line + if curcode: + yield from do_insertions(insertions, + phplexer.get_tokens_unprocessed(curcode)) + + +class PhpLexer(RegexLexer): + """ + For `PHP `_ source code. + For PHP embedded in HTML, use the `HtmlPhpLexer`. + + Additional options accepted: + + `startinline` + If given and ``True`` the lexer starts highlighting with + php code (i.e.: no starting ``>> from pygments.lexers._php_builtins import MODULES + >>> MODULES.keys() + ['PHP Options/Info', 'Zip', 'dba', ...] + + In fact the names of those modules match the module names from + the php documentation. + """ + + name = 'PHP' + aliases = ['php', 'php3', 'php4', 'php5'] + filenames = ['*.php', '*.php[345]', '*.inc'] + mimetypes = ['text/x-php'] + + # Note that a backslash is included in the following two patterns + # PHP uses a backslash as a namespace separator + _ident_char = r'[\\\w]|[^\x00-\x7f]' + _ident_begin = r'(?:[\\_a-z]|[^\x00-\x7f])' + _ident_end = r'(?:' + _ident_char + ')*' + _ident_inner = _ident_begin + _ident_end + + flags = re.IGNORECASE | re.DOTALL | re.MULTILINE + tokens = { + 'root': [ + (r'<\?(php)?', Comment.Preproc, 'php'), + (r'[^<]+', Other), + (r'<', Other) + ], + 'php': [ + (r'\?>', Comment.Preproc, '#pop'), + (r'(<<<)([\'"]?)(' + _ident_inner + r')(\2\n.*?\n\s*)(\3)(;?)(\n)', + bygroups(String, String, String.Delimiter, String, String.Delimiter, + Punctuation, Text)), + (r'\s+', Text), + (r'#.*?\n', Comment.Single), + (r'//.*?\n', Comment.Single), + # put the empty comment here, it is otherwise seen as + # the start of a docstring + (r'/\*\*/', Comment.Multiline), + (r'/\*\*.*?\*/', String.Doc), + (r'/\*.*?\*/', Comment.Multiline), + (r'(->|::)(\s*)(' + _ident_inner + ')', + bygroups(Operator, Text, Name.Attribute)), + (r'[~!%^&*+=|:.<>/@-]+', Operator), + (r'\?', Operator), # don't add to the charclass above! + (r'[\[\]{}();,]+', Punctuation), + (r'(class)(\s+)', bygroups(Keyword, Text), 'classname'), + (r'(function)(\s*)(?=\()', bygroups(Keyword, Text)), + (r'(function)(\s+)(&?)(\s*)', + bygroups(Keyword, Text, Operator, Text), 'functionname'), + (r'(const)(\s+)(' + _ident_inner + ')', + bygroups(Keyword, Text, Name.Constant)), + (r'(and|E_PARSE|old_function|E_ERROR|or|as|E_WARNING|parent|' + r'eval|PHP_OS|break|exit|case|extends|PHP_VERSION|cfunction|' + r'FALSE|print|for|require|continue|foreach|require_once|' + r'declare|return|default|static|do|switch|die|stdClass|' + r'echo|else|TRUE|elseif|var|empty|if|xor|enddeclare|include|' + r'virtual|endfor|include_once|while|endforeach|global|' + r'endif|list|endswitch|new|endwhile|not|' + r'array|E_ALL|NULL|final|php_user_filter|interface|' + r'implements|public|private|protected|abstract|clone|try|' + r'catch|throw|this|use|namespace|trait|yield|' + r'finally)\b', Keyword), + (r'(true|false|null)\b', Keyword.Constant), + include('magicconstants'), + (r'\$\{\$+' + _ident_inner + r'\}', Name.Variable), + (r'\$+' + _ident_inner, Name.Variable), + (_ident_inner, Name.Other), + (r'(\d+\.\d*|\d*\.\d+)(e[+-]?[0-9]+)?', Number.Float), + (r'\d+e[+-]?[0-9]+', Number.Float), + (r'0[0-7]+', Number.Oct), + (r'0x[a-f0-9]+', Number.Hex), + (r'\d+', Number.Integer), + (r'0b[01]+', Number.Bin), + (r"'([^'\\]*(?:\\.[^'\\]*)*)'", String.Single), + (r'`([^`\\]*(?:\\.[^`\\]*)*)`', String.Backtick), + (r'"', String.Double, 'string'), + ], + 'magicfuncs': [ + # source: http://php.net/manual/en/language.oop5.magic.php + (words(( + '__construct', '__destruct', '__call', '__callStatic', '__get', '__set', + '__isset', '__unset', '__sleep', '__wakeup', '__toString', '__invoke', + '__set_state', '__clone', '__debugInfo',), suffix=r'\b'), + Name.Function.Magic), + ], + 'magicconstants': [ + # source: http://php.net/manual/en/language.constants.predefined.php + (words(( + '__LINE__', '__FILE__', '__DIR__', '__FUNCTION__', '__CLASS__', + '__TRAIT__', '__METHOD__', '__NAMESPACE__',), + suffix=r'\b'), + Name.Constant), + ], + 'classname': [ + (_ident_inner, Name.Class, '#pop') + ], + 'functionname': [ + include('magicfuncs'), + (_ident_inner, Name.Function, '#pop'), + default('#pop') + ], + 'string': [ + (r'"', String.Double, '#pop'), + (r'[^{$"\\]+', String.Double), + (r'\\([nrt"$\\]|[0-7]{1,3}|x[0-9a-f]{1,2})', String.Escape), + (r'\$' + _ident_inner + r'(\[\S+?\]|->' + _ident_inner + ')?', + String.Interpol), + (r'(\{\$\{)(.*?)(\}\})', + bygroups(String.Interpol, using(this, _startinline=True), + String.Interpol)), + (r'(\{)(\$.*?)(\})', + bygroups(String.Interpol, using(this, _startinline=True), + String.Interpol)), + (r'(\$\{)(\S+)(\})', + bygroups(String.Interpol, Name.Variable, String.Interpol)), + (r'[${\\]', String.Double) + ], + } + + def __init__(self, **options): + self.funcnamehighlighting = get_bool_opt( + options, 'funcnamehighlighting', True) + self.disabledmodules = get_list_opt( + options, 'disabledmodules', ['unknown']) + self.startinline = get_bool_opt(options, 'startinline', False) + + # private option argument for the lexer itself + if '_startinline' in options: + self.startinline = options.pop('_startinline') + + # collect activated functions in a set + self._functions = set() + if self.funcnamehighlighting: + from pygments.lexers._php_builtins import MODULES + for key, value in MODULES.items(): + if key not in self.disabledmodules: + self._functions.update(value) + RegexLexer.__init__(self, **options) + + def get_tokens_unprocessed(self, text): + stack = ['root'] + if self.startinline: + stack.append('php') + for index, token, value in \ + RegexLexer.get_tokens_unprocessed(self, text, stack): + if token is Name.Other: + if value in self._functions: + yield index, Name.Builtin, value + continue + yield index, token, value + + def analyse_text(text): + if shebang_matches(text, r'php'): + return True + rv = 0.0 + if re.search(r'<\?(?!xml)', text): + rv += 0.3 + return rv diff --git a/.venv/lib/python3.8/site-packages/pygments/lexers/pointless.py b/.venv/lib/python3.8/site-packages/pygments/lexers/pointless.py new file mode 100644 index 00000000..9acc3ffb --- /dev/null +++ b/.venv/lib/python3.8/site-packages/pygments/lexers/pointless.py @@ -0,0 +1,71 @@ +# -*- coding: utf-8 -*- +""" + pygments.lexers.pointless + ~~~~~~~~~~~~~~~~~~~~~~~~~ + + Lexers for Pointless. + + :copyright: Copyright 2006-2020 by the Pygments team, see AUTHORS. + :license: BSD, see LICENSE for details. +""" + +from pygments.lexer import RegexLexer, words +from pygments.token import Comment, Error, Keyword, Name, Number, Operator, \ + Punctuation, String, Text + +__all__ = ['PointlessLexer'] + + +class PointlessLexer(RegexLexer): + """ + For `Pointless `_ source code. + + .. versionadded:: 2.7 + """ + + name = 'Pointless' + aliases = ['pointless'] + filenames = ['*.ptls'] + + ops = words([ + "+", "-", "*", "/", "**", "%", "+=", "-=", "*=", + "/=", "**=", "%=", "|>", "=", "==", "!=", "<", ">", + "<=", ">=", "=>", "$", "++", + ]) + + keywords = words([ + "if", "then", "else", "where", "with", "cond", + "case", "and", "or", "not", "in", "as", "for", + "requires", "throw", "try", "catch", "when", + "yield", "upval", + ], suffix=r'\b') + + tokens = { + 'root': [ + (r'[ \n\r]+', Text), + (r'--.*$', Comment.Single), + (r'"""', String, 'multiString'), + (r'"', String, 'string'), + (r'[\[\](){}:;,.]', Punctuation), + (ops, Operator), + (keywords, Keyword), + (r'\d+|\d*\.\d+', Number), + (r'(true|false)\b', Name.Builtin), + (r'[A-Z][a-zA-Z0-9]*\b', String.Symbol), + (r'output\b', Name.Variable.Magic), + (r'(export|import)\b', Keyword.Namespace), + (r'[a-z][a-zA-Z0-9]*\b', Name.Variable) + ], + 'multiString': [ + (r'\\.', String.Escape), + (r'"""', String, '#pop'), + (r'"', String), + (r'[^\\"]+', String), + ], + 'string': [ + (r'\\.', String.Escape), + (r'"', String, '#pop'), + (r'\n', Error), + (r'[^\\"]+', String), + ], + } diff --git a/.venv/lib/python3.8/site-packages/pygments/lexers/pony.py b/.venv/lib/python3.8/site-packages/pygments/lexers/pony.py new file mode 100644 index 00000000..d13338b2 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/pygments/lexers/pony.py @@ -0,0 +1,94 @@ +# -*- coding: utf-8 -*- +""" + pygments.lexers.pony + ~~~~~~~~~~~~~~~~~~~~ + + Lexers for Pony and related languages. + + :copyright: Copyright 2006-2020 by the Pygments team, see AUTHORS. + :license: BSD, see LICENSE for details. +""" + +from pygments.lexer import RegexLexer, bygroups, words +from pygments.token import Text, Comment, Operator, Keyword, Name, String, \ + Number, Punctuation + +__all__ = ['PonyLexer'] + + +class PonyLexer(RegexLexer): + """ + For Pony source code. + + .. versionadded:: 2.4 + """ + + name = 'Pony' + aliases = ['pony'] + filenames = ['*.pony'] + + _caps = r'(iso|trn|ref|val|box|tag)' + + tokens = { + 'root': [ + (r'\n', Text), + (r'[^\S\n]+', Text), + (r'//.*\n', Comment.Single), + (r'/\*', Comment.Multiline, 'nested_comment'), + (r'"""(?:.|\n)*?"""', String.Doc), + (r'"', String, 'string'), + (r'\'.*\'', String.Char), + (r'=>|[]{}:().~;,|&!^?[]', Punctuation), + (words(( + 'addressof', 'and', 'as', 'consume', 'digestof', 'is', 'isnt', + 'not', 'or'), + suffix=r'\b'), + Operator.Word), + (r'!=|==|<<|>>|[-+/*%=<>]', Operator), + (words(( + 'box', 'break', 'compile_error', 'compile_intrinsic', + 'continue', 'do', 'else', 'elseif', 'embed', 'end', 'error', + 'for', 'if', 'ifdef', 'in', 'iso', 'lambda', 'let', 'match', + 'object', 'recover', 'ref', 'repeat', 'return', 'tag', 'then', + 'this', 'trn', 'try', 'until', 'use', 'var', 'val', 'where', + 'while', 'with', '#any', '#read', '#send', '#share'), + suffix=r'\b'), + Keyword), + (r'(actor|class|struct|primitive|interface|trait|type)((?:\s)+)', + bygroups(Keyword, Text), 'typename'), + (r'(new|fun|be)((?:\s)+)', bygroups(Keyword, Text), 'methodname'), + (words(( + 'I8', 'U8', 'I16', 'U16', 'I32', 'U32', 'I64', 'U64', 'I128', + 'U128', 'ILong', 'ULong', 'ISize', 'USize', 'F32', 'F64', + 'Bool', 'Pointer', 'None', 'Any', 'Array', 'String', + 'Iterator'), + suffix=r'\b'), + Name.Builtin.Type), + (r'_?[A-Z]\w*', Name.Type), + (r'(\d+\.\d*|\.\d+|\d+)[eE][+-]?\d+', Number.Float), + (r'0x[0-9a-fA-F]+', Number.Hex), + (r'\d+', Number.Integer), + (r'(true|false)\b', Name.Builtin), + (r'_\d*', Name), + (r'_?[a-z][\w\']*', Name) + ], + 'typename': [ + (_caps + r'?((?:\s)*)(_?[A-Z]\w*)', + bygroups(Keyword, Text, Name.Class), '#pop') + ], + 'methodname': [ + (_caps + r'?((?:\s)*)(_?[a-z]\w*)', + bygroups(Keyword, Text, Name.Function), '#pop') + ], + 'nested_comment': [ + (r'[^*/]+', Comment.Multiline), + (r'/\*', Comment.Multiline, '#push'), + (r'\*/', Comment.Multiline, '#pop'), + (r'[*/]', Comment.Multiline) + ], + 'string': [ + (r'"', String, '#pop'), + (r'\\"', String), + (r'[^\\"]+', String) + ] + } diff --git a/.venv/lib/python3.8/site-packages/pygments/lexers/praat.py b/.venv/lib/python3.8/site-packages/pygments/lexers/praat.py new file mode 100644 index 00000000..36c6d69d --- /dev/null +++ b/.venv/lib/python3.8/site-packages/pygments/lexers/praat.py @@ -0,0 +1,302 @@ +# -*- coding: utf-8 -*- +""" + pygments.lexers.praat + ~~~~~~~~~~~~~~~~~~~~~ + + Lexer for Praat + + :copyright: Copyright 2006-2020 by the Pygments team, see AUTHORS. + :license: BSD, see LICENSE for details. +""" + +from pygments.lexer import RegexLexer, words, bygroups, include +from pygments.token import Name, Text, Comment, Keyword, String, Punctuation, Number, \ + Operator + +__all__ = ['PraatLexer'] + + +class PraatLexer(RegexLexer): + """ + For `Praat `_ scripts. + + .. versionadded:: 2.1 + """ + + name = 'Praat' + aliases = ['praat'] + filenames = ['*.praat', '*.proc', '*.psc'] + + keywords = ( + 'if', 'then', 'else', 'elsif', 'elif', 'endif', 'fi', 'for', 'from', 'to', + 'endfor', 'endproc', 'while', 'endwhile', 'repeat', 'until', 'select', 'plus', + 'minus', 'demo', 'assert', 'stopwatch', 'nocheck', 'nowarn', 'noprogress', + 'editor', 'endeditor', 'clearinfo', + ) + + functions_string = ( + 'backslashTrigraphsToUnicode', 'chooseDirectory', 'chooseReadFile', + 'chooseWriteFile', 'date', 'demoKey', 'do', 'environment', 'extractLine', + 'extractWord', 'fixed', 'info', 'left', 'mid', 'percent', 'readFile', 'replace', + 'replace_regex', 'right', 'selected', 'string', 'unicodeToBackslashTrigraphs', + ) + + functions_numeric = ( + 'abs', 'appendFile', 'appendFileLine', 'appendInfo', 'appendInfoLine', 'arccos', + 'arccosh', 'arcsin', 'arcsinh', 'arctan', 'arctan2', 'arctanh', 'barkToHertz', + 'beginPause', 'beginSendPraat', 'besselI', 'besselK', 'beta', 'beta2', + 'binomialP', 'binomialQ', 'boolean', 'ceiling', 'chiSquareP', 'chiSquareQ', + 'choice', 'comment', 'cos', 'cosh', 'createDirectory', 'deleteFile', + 'demoClicked', 'demoClickedIn', 'demoCommandKeyPressed', + 'demoExtraControlKeyPressed', 'demoInput', 'demoKeyPressed', + 'demoOptionKeyPressed', 'demoShiftKeyPressed', 'demoShow', 'demoWaitForInput', + 'demoWindowTitle', 'demoX', 'demoY', 'differenceLimensToPhon', 'do', 'editor', + 'endPause', 'endSendPraat', 'endsWith', 'erb', 'erbToHertz', 'erf', 'erfc', + 'exitScript', 'exp', 'extractNumber', 'fileReadable', 'fisherP', 'fisherQ', + 'floor', 'gaussP', 'gaussQ', 'hertzToBark', 'hertzToErb', 'hertzToMel', + 'hertzToSemitones', 'imax', 'imin', 'incompleteBeta', 'incompleteGammaP', 'index', + 'index_regex', 'integer', 'invBinomialP', 'invBinomialQ', 'invChiSquareQ', 'invFisherQ', + 'invGaussQ', 'invSigmoid', 'invStudentQ', 'length', 'ln', 'lnBeta', 'lnGamma', + 'log10', 'log2', 'max', 'melToHertz', 'min', 'minusObject', 'natural', 'number', + 'numberOfColumns', 'numberOfRows', 'numberOfSelected', 'objectsAreIdentical', + 'option', 'optionMenu', 'pauseScript', 'phonToDifferenceLimens', 'plusObject', + 'positive', 'randomBinomial', 'randomGauss', 'randomInteger', 'randomPoisson', + 'randomUniform', 'real', 'readFile', 'removeObject', 'rindex', 'rindex_regex', + 'round', 'runScript', 'runSystem', 'runSystem_nocheck', 'selectObject', + 'selected', 'semitonesToHertz', 'sentence', 'sentencetext', 'sigmoid', 'sin', 'sinc', + 'sincpi', 'sinh', 'soundPressureToPhon', 'sqrt', 'startsWith', 'studentP', + 'studentQ', 'tan', 'tanh', 'text', 'variableExists', 'word', 'writeFile', 'writeFileLine', + 'writeInfo', 'writeInfoLine', + ) + + functions_array = ( + 'linear', 'randomGauss', 'randomInteger', 'randomUniform', 'zero', + ) + + objects = ( + 'Activation', 'AffineTransform', 'AmplitudeTier', 'Art', 'Artword', + 'Autosegment', 'BarkFilter', 'BarkSpectrogram', 'CCA', 'Categories', + 'Cepstrogram', 'Cepstrum', 'Cepstrumc', 'ChebyshevSeries', 'ClassificationTable', + 'Cochleagram', 'Collection', 'ComplexSpectrogram', 'Configuration', 'Confusion', + 'ContingencyTable', 'Corpus', 'Correlation', 'Covariance', + 'CrossCorrelationTable', 'CrossCorrelationTables', 'DTW', 'DataModeler', + 'Diagonalizer', 'Discriminant', 'Dissimilarity', 'Distance', 'Distributions', + 'DurationTier', 'EEG', 'ERP', 'ERPTier', 'EditCostsTable', 'EditDistanceTable', + 'Eigen', 'Excitation', 'Excitations', 'ExperimentMFC', 'FFNet', 'FeatureWeights', + 'FileInMemory', 'FilesInMemory', 'Formant', 'FormantFilter', 'FormantGrid', + 'FormantModeler', 'FormantPoint', 'FormantTier', 'GaussianMixture', 'HMM', + 'HMM_Observation', 'HMM_ObservationSequence', 'HMM_State', 'HMM_StateSequence', + 'Harmonicity', 'ISpline', 'Index', 'Intensity', 'IntensityTier', 'IntervalTier', + 'KNN', 'KlattGrid', 'KlattTable', 'LFCC', 'LPC', 'Label', 'LegendreSeries', + 'LinearRegression', 'LogisticRegression', 'LongSound', 'Ltas', 'MFCC', 'MSpline', + 'ManPages', 'Manipulation', 'Matrix', 'MelFilter', 'MelSpectrogram', + 'MixingMatrix', 'Movie', 'Network', 'Object', 'OTGrammar', 'OTHistory', 'OTMulti', + 'PCA', 'PairDistribution', 'ParamCurve', 'Pattern', 'Permutation', 'Photo', + 'Pitch', 'PitchModeler', 'PitchTier', 'PointProcess', 'Polygon', 'Polynomial', + 'PowerCepstrogram', 'PowerCepstrum', 'Procrustes', 'RealPoint', 'RealTier', + 'ResultsMFC', 'Roots', 'SPINET', 'SSCP', 'SVD', 'Salience', 'ScalarProduct', + 'Similarity', 'SimpleString', 'SortedSetOfString', 'Sound', 'Speaker', + 'Spectrogram', 'Spectrum', 'SpectrumTier', 'SpeechSynthesizer', 'SpellingChecker', + 'Strings', 'StringsIndex', 'Table', 'TableOfReal', 'TextGrid', 'TextInterval', + 'TextPoint', 'TextTier', 'Tier', 'Transition', 'VocalTract', 'VocalTractTier', + 'Weight', 'WordList', + ) + + variables_numeric = ( + 'macintosh', 'windows', 'unix', 'praatVersion', 'pi', 'e', 'undefined', + ) + + variables_string = ( + 'praatVersion', 'tab', 'shellDirectory', 'homeDirectory', + 'preferencesDirectory', 'newline', 'temporaryDirectory', + 'defaultDirectory', + ) + + object_attributes = ( + 'ncol', 'nrow', 'xmin', 'ymin', 'xmax', 'ymax', 'nx', 'ny', 'dx', 'dy', + ) + + tokens = { + 'root': [ + (r'(\s+)(#.*?$)', bygroups(Text, Comment.Single)), + (r'^#.*?$', Comment.Single), + (r';[^\n]*', Comment.Single), + (r'\s+', Text), + + (r'\bprocedure\b', Keyword, 'procedure_definition'), + (r'\bcall\b', Keyword, 'procedure_call'), + (r'@', Name.Function, 'procedure_call'), + + include('function_call'), + + (words(keywords, suffix=r'\b'), Keyword), + + (r'(\bform\b)(\s+)([^\n]+)', + bygroups(Keyword, Text, String), 'old_form'), + + (r'(print(?:line|tab)?|echo|exit|asserterror|pause|send(?:praat|socket)|' + r'include|execute|system(?:_nocheck)?)(\s+)', + bygroups(Keyword, Text), 'string_unquoted'), + + (r'(goto|label)(\s+)(\w+)', bygroups(Keyword, Text, Name.Label)), + + include('variable_name'), + include('number'), + + (r'"', String, 'string'), + + (words((objects), suffix=r'(?=\s+\S+\n)'), Name.Class, 'string_unquoted'), + + (r'\b[A-Z]', Keyword, 'command'), + (r'(\.{3}|[)(,])', Punctuation), + ], + 'command': [ + (r'( ?[\w()-]+ ?)', Keyword), + + include('string_interpolated'), + + (r'\.{3}', Keyword, ('#pop', 'old_arguments')), + (r':', Keyword, ('#pop', 'comma_list')), + (r'\s', Text, '#pop'), + ], + 'procedure_call': [ + (r'\s+', Text), + (r'([\w.]+)(:|\s*\()', + bygroups(Name.Function, Text), '#pop'), + (r'([\w.]+)', Name.Function, ('#pop', 'old_arguments')), + ], + 'procedure_definition': [ + (r'\s', Text), + (r'([\w.]+)(\s*?[(:])', + bygroups(Name.Function, Text), '#pop'), + (r'([\w.]+)([^\n]*)', + bygroups(Name.Function, Text), '#pop'), + ], + 'function_call': [ + (words(functions_string, suffix=r'\$(?=\s*[:(])'), Name.Function, 'function'), + (words(functions_array, suffix=r'#(?=\s*[:(])'), Name.Function, 'function'), + (words(functions_numeric, suffix=r'(?=\s*[:(])'), Name.Function, 'function'), + ], + 'function': [ + (r'\s+', Text), + (r':', Punctuation, ('#pop', 'comma_list')), + (r'\s*\(', Punctuation, ('#pop', 'comma_list')), + ], + 'comma_list': [ + (r'(\s*\n\s*)(\.{3})', bygroups(Text, Punctuation)), + + (r'(\s*[])\n])', Text, '#pop'), + + (r'\s+', Text), + (r'"', String, 'string'), + (r'\b(if|then|else|fi|endif)\b', Keyword), + + include('function_call'), + include('variable_name'), + include('operator'), + include('number'), + + (r'[()]', Text), + (r',', Punctuation), + ], + 'old_arguments': [ + (r'\n', Text, '#pop'), + + include('variable_name'), + include('operator'), + include('number'), + + (r'"', String, 'string'), + (r'[^\n]', Text), + ], + 'number': [ + (r'\n', Text, '#pop'), + (r'\b\d+(\.\d*)?([eE][-+]?\d+)?%?', Number), + ], + 'object_reference': [ + include('string_interpolated'), + (r'([a-z][a-zA-Z0-9_]*|\d+)', Name.Builtin), + + (words(object_attributes, prefix=r'\.'), Name.Builtin, '#pop'), + + (r'\$', Name.Builtin), + (r'\[', Text, '#pop'), + ], + 'variable_name': [ + include('operator'), + include('number'), + + (words(variables_string, suffix=r'\$'), Name.Variable.Global), + (words(variables_numeric, + suffix=r'(?=[^a-zA-Z0-9_."\'$#\[:(]|\s|^|$)'), + Name.Variable.Global), + + (words(objects, prefix=r'\b', suffix=r"(_)"), + bygroups(Name.Builtin, Name.Builtin), + 'object_reference'), + + (r'\.?_?[a-z][\w.]*(\$|#)?', Text), + (r'[\[\]]', Punctuation, 'comma_list'), + + include('string_interpolated'), + ], + 'operator': [ + (r'([+\/*<>=!-]=?|[&*|][&*|]?|\^|<>)', Operator), + (r'(?', Punctuation), + (r'"(?:\\x[0-9a-fA-F]+\\|\\u[0-9a-fA-F]{4}|\\U[0-9a-fA-F]{8}|' + r'\\[0-7]+\\|\\["\nabcefnrstv]|[^\\"])*"', String.Double), + (r"'(?:''|[^'])*'", String.Atom), # quoted atom + # Needs to not be followed by an atom. + # (r'=(?=\s|[a-zA-Z\[])', Operator), + (r'is\b', Operator), + (r'(<|>|=<|>=|==|=:=|=|/|//|\*|\+|-)(?=\s|[a-zA-Z0-9\[])', + Operator), + (r'(mod|div|not)\b', Operator), + (r'_', Keyword), # The don't-care variable + (r'([a-z]+)(:)', bygroups(Name.Namespace, Punctuation)), + (r'([a-z\u00c0-\u1fff\u3040-\ud7ff\ue000-\uffef]' + r'[\w$\u00c0-\u1fff\u3040-\ud7ff\ue000-\uffef]*)' + r'(\s*)(:-|-->)', + bygroups(Name.Function, Text, Operator)), # function defn + (r'([a-z\u00c0-\u1fff\u3040-\ud7ff\ue000-\uffef]' + r'[\w$\u00c0-\u1fff\u3040-\ud7ff\ue000-\uffef]*)' + r'(\s*)(\()', + bygroups(Name.Function, Text, Punctuation)), + (r'[a-z\u00c0-\u1fff\u3040-\ud7ff\ue000-\uffef]' + r'[\w$\u00c0-\u1fff\u3040-\ud7ff\ue000-\uffef]*', + String.Atom), # atom, characters + # This one includes ! + (r'[#&*+\-./:<=>?@\\^~\u00a1-\u00bf\u2010-\u303f]+', + String.Atom), # atom, graphics + (r'[A-Z_]\w*', Name.Variable), + (r'\s+|[\u2000-\u200f\ufff0-\ufffe\uffef]', Text), + ], + 'nested-comment': [ + (r'\*/', Comment.Multiline, '#pop'), + (r'/\*', Comment.Multiline, '#push'), + (r'[^*/]+', Comment.Multiline), + (r'[*/]', Comment.Multiline), + ], + } + + def analyse_text(text): + return ':-' in text + + +class LogtalkLexer(RegexLexer): + """ + For `Logtalk `_ source code. + + .. versionadded:: 0.10 + """ + + name = 'Logtalk' + aliases = ['logtalk'] + filenames = ['*.lgt', '*.logtalk'] + mimetypes = ['text/x-logtalk'] + + tokens = { + 'root': [ + # Directives + (r'^\s*:-\s', Punctuation, 'directive'), + # Comments + (r'%.*?\n', Comment), + (r'/\*(.|\n)*?\*/', Comment), + # Whitespace + (r'\n', Text), + (r'\s+', Text), + # Numbers + (r"0'[\\]?.", Number), + (r'0b[01]+', Number.Bin), + (r'0o[0-7]+', Number.Oct), + (r'0x[0-9a-fA-F]+', Number.Hex), + (r'\d+\.?\d*((e|E)(\+|-)?\d+)?', Number), + # Variables + (r'([A-Z_][a-zA-Z0-9_]*)', Name.Variable), + # Event handlers + (r'(after|before)(?=[(])', Keyword), + # Message forwarding handler + (r'forward(?=[(])', Keyword), + # Execution-context methods + (r'(context|parameter|this|se(lf|nder))(?=[(])', Keyword), + # Reflection + (r'(current_predicate|predicate_property)(?=[(])', Keyword), + # DCGs and term expansion + (r'(expand_(goal|term)|(goal|term)_expansion|phrase)(?=[(])', Keyword), + # Entity + (r'(abolish|c(reate|urrent))_(object|protocol|category)(?=[(])', Keyword), + (r'(object|protocol|category)_property(?=[(])', Keyword), + # Entity relations + (r'co(mplements_object|nforms_to_protocol)(?=[(])', Keyword), + (r'extends_(object|protocol|category)(?=[(])', Keyword), + (r'imp(lements_protocol|orts_category)(?=[(])', Keyword), + (r'(instantiat|specializ)es_class(?=[(])', Keyword), + # Events + (r'(current_event|(abolish|define)_events)(?=[(])', Keyword), + # Flags + (r'(create|current|set)_logtalk_flag(?=[(])', Keyword), + # Compiling, loading, and library paths + (r'logtalk_(compile|l(ibrary_path|oad|oad_context)|make(_target_action)?)(?=[(])', Keyword), + (r'\blogtalk_make\b', Keyword), + # Database + (r'(clause|retract(all)?)(?=[(])', Keyword), + (r'a(bolish|ssert(a|z))(?=[(])', Keyword), + # Control constructs + (r'(ca(ll|tch)|throw)(?=[(])', Keyword), + (r'(fa(il|lse)|true|(instantiation|system)_error)\b', Keyword), + (r'(type|domain|existence|permission|representation|evaluation|resource|syntax)_error(?=[(])', Keyword), + # All solutions + (r'((bag|set)of|f(ind|or)all)(?=[(])', Keyword), + # Multi-threading predicates + (r'threaded(_(ca(ll|ncel)|once|ignore|exit|peek|wait|notify))?(?=[(])', Keyword), + # Engine predicates + (r'threaded_engine(_(create|destroy|self|next|next_reified|yield|post|fetch))?(?=[(])', Keyword), + # Term unification + (r'(subsumes_term|unify_with_occurs_check)(?=[(])', Keyword), + # Term creation and decomposition + (r'(functor|arg|copy_term|numbervars|term_variables)(?=[(])', Keyword), + # Evaluable functors + (r'(div|rem|m(ax|in|od)|abs|sign)(?=[(])', Keyword), + (r'float(_(integer|fractional)_part)?(?=[(])', Keyword), + (r'(floor|t(an|runcate)|round|ceiling)(?=[(])', Keyword), + # Other arithmetic functors + (r'(cos|a(cos|sin|tan|tan2)|exp|log|s(in|qrt)|xor)(?=[(])', Keyword), + # Term testing + (r'(var|atom(ic)?|integer|float|c(allable|ompound)|n(onvar|umber)|ground|acyclic_term)(?=[(])', Keyword), + # Term comparison + (r'compare(?=[(])', Keyword), + # Stream selection and control + (r'(curren|se)t_(in|out)put(?=[(])', Keyword), + (r'(open|close)(?=[(])', Keyword), + (r'flush_output(?=[(])', Keyword), + (r'(at_end_of_stream|flush_output)\b', Keyword), + (r'(stream_property|at_end_of_stream|set_stream_position)(?=[(])', Keyword), + # Character and byte input/output + (r'(nl|(get|peek|put)_(byte|c(har|ode)))(?=[(])', Keyword), + (r'\bnl\b', Keyword), + # Term input/output + (r'read(_term)?(?=[(])', Keyword), + (r'write(q|_(canonical|term))?(?=[(])', Keyword), + (r'(current_)?op(?=[(])', Keyword), + (r'(current_)?char_conversion(?=[(])', Keyword), + # Atomic term processing + (r'atom_(length|c(hars|o(ncat|des)))(?=[(])', Keyword), + (r'(char_code|sub_atom)(?=[(])', Keyword), + (r'number_c(har|ode)s(?=[(])', Keyword), + # Implementation defined hooks functions + (r'(se|curren)t_prolog_flag(?=[(])', Keyword), + (r'\bhalt\b', Keyword), + (r'halt(?=[(])', Keyword), + # Message sending operators + (r'(::|:|\^\^)', Operator), + # External call + (r'[{}]', Keyword), + # Logic and control + (r'(ignore|once)(?=[(])', Keyword), + (r'\brepeat\b', Keyword), + # Sorting + (r'(key)?sort(?=[(])', Keyword), + # Bitwise functors + (r'(>>|<<|/\\|\\\\|\\)', Operator), + # Predicate aliases + (r'\bas\b', Operator), + # Arithemtic evaluation + (r'\bis\b', Keyword), + # Arithemtic comparison + (r'(=:=|=\\=|<|=<|>=|>)', Operator), + # Term creation and decomposition + (r'=\.\.', Operator), + # Term unification + (r'(=|\\=)', Operator), + # Term comparison + (r'(==|\\==|@=<|@<|@>=|@>)', Operator), + # Evaluable functors + (r'(//|[-+*/])', Operator), + (r'\b(e|pi|div|mod|rem)\b', Operator), + # Other arithemtic functors + (r'\b\*\*\b', Operator), + # DCG rules + (r'-->', Operator), + # Control constructs + (r'([!;]|->)', Operator), + # Logic and control + (r'\\+', Operator), + # Mode operators + (r'[?@]', Operator), + # Existential quantifier + (r'\^', Operator), + # Strings + (r'"(\\\\|\\"|[^"])*"', String), + # Punctuation + (r'[()\[\],.|]', Text), + # Atoms + (r"[a-z][a-zA-Z0-9_]*", Text), + (r"'", String, 'quoted_atom'), + ], + + 'quoted_atom': [ + (r"''", String), + (r"'", String, '#pop'), + (r'\\([\\abfnrtv"\']|(x[a-fA-F0-9]+|[0-7]+)\\)', String.Escape), + (r"[^\\'\n]+", String), + (r'\\', String), + ], + + 'directive': [ + # Conditional compilation directives + (r'(el)?if(?=[(])', Keyword, 'root'), + (r'(e(lse|ndif))(?=[.])', Keyword, 'root'), + # Entity directives + (r'(category|object|protocol)(?=[(])', Keyword, 'entityrelations'), + (r'(end_(category|object|protocol))(?=[.])', Keyword, 'root'), + # Predicate scope directives + (r'(public|protected|private)(?=[(])', Keyword, 'root'), + # Other directives + (r'e(n(coding|sure_loaded)|xport)(?=[(])', Keyword, 'root'), + (r'in(clude|itialization|fo)(?=[(])', Keyword, 'root'), + (r'(built_in|dynamic|synchronized|threaded)(?=[.])', Keyword, 'root'), + (r'(alias|d(ynamic|iscontiguous)|m(eta_(non_terminal|predicate)|ode|ultifile)|s(et_(logtalk|prolog)_flag|ynchronized))(?=[(])', Keyword, 'root'), + (r'op(?=[(])', Keyword, 'root'), + (r'(c(alls|oinductive)|module|reexport|use(s|_module))(?=[(])', Keyword, 'root'), + (r'[a-z][a-zA-Z0-9_]*(?=[(])', Text, 'root'), + (r'[a-z][a-zA-Z0-9_]*(?=[.])', Text, 'root'), + ], + + 'entityrelations': [ + (r'(complements|extends|i(nstantiates|mp(lements|orts))|specializes)(?=[(])', Keyword), + # Numbers + (r"0'[\\]?.", Number), + (r'0b[01]+', Number.Bin), + (r'0o[0-7]+', Number.Oct), + (r'0x[0-9a-fA-F]+', Number.Hex), + (r'\d+\.?\d*((e|E)(\+|-)?\d+)?', Number), + # Variables + (r'([A-Z_][a-zA-Z0-9_]*)', Name.Variable), + # Atoms + (r"[a-z][a-zA-Z0-9_]*", Text), + (r"'", String, 'quoted_atom'), + # Strings + (r'"(\\\\|\\"|[^"])*"', String), + # End of entity-opening directive + (r'([)]\.)', Text, 'root'), + # Scope operator + (r'(::)', Operator), + # Punctuation + (r'[()\[\],.|]', Text), + # Comments + (r'%.*?\n', Comment), + (r'/\*(.|\n)*?\*/', Comment), + # Whitespace + (r'\n', Text), + (r'\s+', Text), + ] + } + + def analyse_text(text): + if ':- object(' in text: + return 1.0 + elif ':- protocol(' in text: + return 1.0 + elif ':- category(' in text: + return 1.0 + elif re.search(r'^:-\s[a-z]', text, re.M): + return 0.9 + else: + return 0.0 diff --git a/.venv/lib/python3.8/site-packages/pygments/lexers/promql.py b/.venv/lib/python3.8/site-packages/pygments/lexers/promql.py new file mode 100644 index 00000000..18069208 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/pygments/lexers/promql.py @@ -0,0 +1,183 @@ +# -*- coding: utf-8 -*- +""" + pygments.lexers.promql + ~~~~~~~~~~~~~~~~~~~~~~ + + Lexer for Prometheus Query Language. + + :copyright: Copyright 2006-2020 by the Pygments team, see AUTHORS. + :license: BSD, see LICENSE for details. +""" + +from pygments.lexer import RegexLexer, bygroups, default, words +from pygments.token import ( + Comment, + Keyword, + Name, + Number, + Operator, + Punctuation, + String, + Whitespace, +) + +__all__ = ["PromQLLexer"] + + +class PromQLLexer(RegexLexer): + """ + For `PromQL `_ queries. + + For details about the grammar see: + https://github.com/prometheus/prometheus/tree/master/promql/parser + + .. versionadded: 2.7 + """ + + name = "PromQL" + aliases = ["promql"] + filenames = ["*.promql"] + + base_keywords = ( + words( + ( + "bool", + "by", + "group_left", + "group_right", + "ignoring", + "offset", + "on", + "without", + ), + suffix=r"\b", + ), + Keyword, + ) + + aggregator_keywords = ( + words( + ( + "sum", + "min", + "max", + "avg", + "group", + "stddev", + "stdvar", + "count", + "count_values", + "bottomk", + "topk", + "quantile", + ), + suffix=r"\b", + ), + Keyword, + ) + + function_keywords = ( + words( + ( + "abs", + "absent", + "absent_over_time", + "avg_over_time", + "ceil", + "changes", + "clamp_max", + "clamp_min", + "count_over_time", + "day_of_month", + "day_of_week", + "days_in_month", + "delta", + "deriv", + "exp", + "floor", + "histogram_quantile", + "holt_winters", + "hour", + "idelta", + "increase", + "irate", + "label_join", + "label_replace", + "ln", + "log10", + "log2", + "max_over_time", + "min_over_time", + "minute", + "month", + "predict_linear", + "quantile_over_time", + "rate", + "resets", + "round", + "scalar", + "sort", + "sort_desc", + "sqrt", + "stddev_over_time", + "stdvar_over_time", + "sum_over_time", + "time", + "timestamp", + "vector", + "year", + ), + suffix=r"\b", + ), + Keyword.Reserved, + ) + + tokens = { + "root": [ + (r"\n", Whitespace), + (r"\s+", Whitespace), + (r",", Punctuation), + # Keywords + base_keywords, + aggregator_keywords, + function_keywords, + # Offsets + (r"[1-9][0-9]*[smhdwy]", String), + # Numbers + (r"-?[0-9]+\.[0-9]+", Number.Float), + (r"-?[0-9]+", Number.Integer), + # Comments + (r"#.*?$", Comment.Single), + # Operators + (r"(\+|\-|\*|\/|\%|\^)", Operator), + (r"==|!=|>=|<=|<|>", Operator), + (r"and|or|unless", Operator.Word), + # Metrics + (r"[_a-zA-Z][a-zA-Z0-9_]+", Name.Variable), + # Params + (r'(["\'])(.*?)(["\'])', bygroups(Punctuation, String, Punctuation)), + # Other states + (r"\(", Operator, "function"), + (r"\)", Operator), + (r"\{", Punctuation, "labels"), + (r"\[", Punctuation, "range"), + ], + "labels": [ + (r"\}", Punctuation, "#pop"), + (r"\n", Whitespace), + (r"\s+", Whitespace), + (r",", Punctuation), + (r'([_a-zA-Z][a-zA-Z0-9_]*?)(\s*?)(=~|!=|=|~!)(\s*?)(")(.*?)(")', + bygroups(Name.Label, Whitespace, Operator, Whitespace, + Punctuation, String, Punctuation)), + ], + "range": [ + (r"\]", Punctuation, "#pop"), + (r"[1-9][0-9]*[smhdwy]", String), + ], + "function": [ + (r"\)", Operator, "#pop"), + (r"\(", Operator, "#push"), + default("#pop"), + ], + } diff --git a/.venv/lib/python3.8/site-packages/pygments/lexers/python.py b/.venv/lib/python3.8/site-packages/pygments/lexers/python.py new file mode 100644 index 00000000..051371f9 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/pygments/lexers/python.py @@ -0,0 +1,1151 @@ +# -*- coding: utf-8 -*- +""" + pygments.lexers.python + ~~~~~~~~~~~~~~~~~~~~~~ + + Lexers for Python and related languages. + + :copyright: Copyright 2006-2020 by the Pygments team, see AUTHORS. + :license: BSD, see LICENSE for details. +""" + +import re + +from pygments.lexer import Lexer, RegexLexer, include, bygroups, using, \ + default, words, combined, do_insertions +from pygments.util import get_bool_opt, shebang_matches +from pygments.token import Text, Comment, Operator, Keyword, Name, String, \ + Number, Punctuation, Generic, Other, Error +from pygments import unistring as uni + +__all__ = ['PythonLexer', 'PythonConsoleLexer', 'PythonTracebackLexer', + 'Python2Lexer', 'Python2TracebackLexer', + 'CythonLexer', 'DgLexer', 'NumPyLexer'] + +line_re = re.compile('.*?\n') + + +class PythonLexer(RegexLexer): + """ + For `Python `_ source code (version 3.x). + + .. versionadded:: 0.10 + + .. versionchanged:: 2.5 + This is now the default ``PythonLexer``. It is still available as the + alias ``Python3Lexer``. + """ + + name = 'Python' + aliases = ['python', 'py', 'sage', 'python3', 'py3'] + filenames = [ + '*.py', + '*.pyw', + # Jython + '*.jy', + # Sage + '*.sage', + # SCons + '*.sc', + 'SConstruct', + 'SConscript', + # Skylark/Starlark (used by Bazel, Buck, and Pants) + '*.bzl', + 'BUCK', + 'BUILD', + 'BUILD.bazel', + 'WORKSPACE', + # Twisted Application infrastructure + '*.tac', + ] + mimetypes = ['text/x-python', 'application/x-python', + 'text/x-python3', 'application/x-python3'] + + flags = re.MULTILINE | re.UNICODE + + uni_name = "[%s][%s]*" % (uni.xid_start, uni.xid_continue) + + def innerstring_rules(ttype): + return [ + # the old style '%s' % (...) string formatting (still valid in Py3) + (r'%(\(\w+\))?[-#0 +]*([0-9]+|[*])?(\.([0-9]+|[*]))?' + '[hlL]?[E-GXc-giorsaux%]', String.Interpol), + # the new style '{}'.format(...) string formatting + (r'\{' + r'((\w+)((\.\w+)|(\[[^\]]+\]))*)?' # field name + r'(\![sra])?' # conversion + r'(\:(.?[<>=\^])?[-+ ]?#?0?(\d+)?,?(\.\d+)?[E-GXb-gnosx%]?)?' + r'\}', String.Interpol), + + # backslashes, quotes and formatting signs must be parsed one at a time + (r'[^\\\'"%{\n]+', ttype), + (r'[\'"\\]', ttype), + # unhandled string formatting sign + (r'%|(\{{1,2})', ttype) + # newlines are an error (use "nl" state) + ] + + def fstring_rules(ttype): + return [ + # Assuming that a '}' is the closing brace after format specifier. + # Sadly, this means that we won't detect syntax error. But it's + # more important to parse correct syntax correctly, than to + # highlight invalid syntax. + (r'\}', String.Interpol), + (r'\{', String.Interpol, 'expr-inside-fstring'), + # backslashes, quotes and formatting signs must be parsed one at a time + (r'[^\\\'"{}\n]+', ttype), + (r'[\'"\\]', ttype), + # newlines are an error (use "nl" state) + ] + + tokens = { + 'root': [ + (r'\n', Text), + (r'^(\s*)([rRuUbB]{,2})("""(?:.|\n)*?""")', + bygroups(Text, String.Affix, String.Doc)), + (r"^(\s*)([rRuUbB]{,2})('''(?:.|\n)*?''')", + bygroups(Text, String.Affix, String.Doc)), + (r'\A#!.+$', Comment.Hashbang), + (r'#.*$', Comment.Single), + (r'\\\n', Text), + (r'\\', Text), + include('keywords'), + (r'(def)((?:\s|\\\s)+)', bygroups(Keyword, Text), 'funcname'), + (r'(class)((?:\s|\\\s)+)', bygroups(Keyword, Text), 'classname'), + (r'(from)((?:\s|\\\s)+)', bygroups(Keyword.Namespace, Text), + 'fromimport'), + (r'(import)((?:\s|\\\s)+)', bygroups(Keyword.Namespace, Text), + 'import'), + include('expr'), + ], + 'expr': [ + # raw f-strings + ('(?i)(rf|fr)(""")', + bygroups(String.Affix, String.Double), 'tdqf'), + ("(?i)(rf|fr)(''')", + bygroups(String.Affix, String.Single), 'tsqf'), + ('(?i)(rf|fr)(")', + bygroups(String.Affix, String.Double), 'dqf'), + ("(?i)(rf|fr)(')", + bygroups(String.Affix, String.Single), 'sqf'), + # non-raw f-strings + ('([fF])(""")', bygroups(String.Affix, String.Double), + combined('fstringescape', 'tdqf')), + ("([fF])(''')", bygroups(String.Affix, String.Single), + combined('fstringescape', 'tsqf')), + ('([fF])(")', bygroups(String.Affix, String.Double), + combined('fstringescape', 'dqf')), + ("([fF])(')", bygroups(String.Affix, String.Single), + combined('fstringescape', 'sqf')), + # raw strings + ('(?i)(rb|br|r)(""")', + bygroups(String.Affix, String.Double), 'tdqs'), + ("(?i)(rb|br|r)(''')", + bygroups(String.Affix, String.Single), 'tsqs'), + ('(?i)(rb|br|r)(")', + bygroups(String.Affix, String.Double), 'dqs'), + ("(?i)(rb|br|r)(')", + bygroups(String.Affix, String.Single), 'sqs'), + # non-raw strings + ('([uUbB]?)(""")', bygroups(String.Affix, String.Double), + combined('stringescape', 'tdqs')), + ("([uUbB]?)(''')", bygroups(String.Affix, String.Single), + combined('stringescape', 'tsqs')), + ('([uUbB]?)(")', bygroups(String.Affix, String.Double), + combined('stringescape', 'dqs')), + ("([uUbB]?)(')", bygroups(String.Affix, String.Single), + combined('stringescape', 'sqs')), + (r'[^\S\n]+', Text), + (r'!=|==|<<|>>|:=|[-~+/*%=<>&^|.]', Operator), + (r'[]{}:(),;[]', Punctuation), + (r'(in|is|and|or|not)\b', Operator.Word), + include('expr-keywords'), + include('builtins'), + include('magicfuncs'), + include('magicvars'), + include('name'), + include('numbers'), + ], + 'expr-inside-fstring': [ + (r'[{([]', Punctuation, 'expr-inside-fstring-inner'), + # without format specifier + (r'(=\s*)?' # debug (https://bugs.python.org/issue36817) + r'(\![sraf])?' # conversion + r'\}', String.Interpol, '#pop'), + # with format specifier + # we'll catch the remaining '}' in the outer scope + (r'(=\s*)?' # debug (https://bugs.python.org/issue36817) + r'(\![sraf])?' # conversion + r':', String.Interpol, '#pop'), + (r'\s+', Text), # allow new lines + include('expr'), + ], + 'expr-inside-fstring-inner': [ + (r'[{([]', Punctuation, 'expr-inside-fstring-inner'), + (r'[])}]', Punctuation, '#pop'), + (r'\s+', Text), # allow new lines + include('expr'), + ], + 'expr-keywords': [ + # Based on https://docs.python.org/3/reference/expressions.html + (words(( + 'async for', 'await', 'else', 'for', 'if', 'lambda', + 'yield', 'yield from'), suffix=r'\b'), + Keyword), + (words(('True', 'False', 'None'), suffix=r'\b'), Keyword.Constant), + ], + 'keywords': [ + (words(( + 'assert', 'async', 'await', 'break', 'continue', 'del', 'elif', + 'else', 'except', 'finally', 'for', 'global', 'if', 'lambda', + 'pass', 'raise', 'nonlocal', 'return', 'try', 'while', 'yield', + 'yield from', 'as', 'with'), suffix=r'\b'), + Keyword), + (words(('True', 'False', 'None'), suffix=r'\b'), Keyword.Constant), + ], + 'builtins': [ + (words(( + '__import__', 'abs', 'all', 'any', 'bin', 'bool', 'bytearray', + 'bytes', 'chr', 'classmethod', 'compile', 'complex', + 'delattr', 'dict', 'dir', 'divmod', 'enumerate', 'eval', 'filter', + 'float', 'format', 'frozenset', 'getattr', 'globals', 'hasattr', + 'hash', 'hex', 'id', 'input', 'int', 'isinstance', 'issubclass', + 'iter', 'len', 'list', 'locals', 'map', 'max', 'memoryview', + 'min', 'next', 'object', 'oct', 'open', 'ord', 'pow', 'print', + 'property', 'range', 'repr', 'reversed', 'round', 'set', 'setattr', + 'slice', 'sorted', 'staticmethod', 'str', 'sum', 'super', 'tuple', + 'type', 'vars', 'zip'), prefix=r'(?`_ source code. + + .. versionchanged:: 2.5 + This class has been renamed from ``PythonLexer``. ``PythonLexer`` now + refers to the Python 3 variant. File name patterns like ``*.py`` have + been moved to Python 3 as well. + """ + + name = 'Python 2.x' + aliases = ['python2', 'py2'] + filenames = [] # now taken over by PythonLexer (3.x) + mimetypes = ['text/x-python2', 'application/x-python2'] + + def innerstring_rules(ttype): + return [ + # the old style '%s' % (...) string formatting + (r'%(\(\w+\))?[-#0 +]*([0-9]+|[*])?(\.([0-9]+|[*]))?' + '[hlL]?[E-GXc-giorsux%]', String.Interpol), + # backslashes, quotes and formatting signs must be parsed one at a time + (r'[^\\\'"%\n]+', ttype), + (r'[\'"\\]', ttype), + # unhandled string formatting sign + (r'%', ttype), + # newlines are an error (use "nl" state) + ] + + tokens = { + 'root': [ + (r'\n', Text), + (r'^(\s*)([rRuUbB]{,2})("""(?:.|\n)*?""")', + bygroups(Text, String.Affix, String.Doc)), + (r"^(\s*)([rRuUbB]{,2})('''(?:.|\n)*?''')", + bygroups(Text, String.Affix, String.Doc)), + (r'[^\S\n]+', Text), + (r'\A#!.+$', Comment.Hashbang), + (r'#.*$', Comment.Single), + (r'[]{}:(),;[]', Punctuation), + (r'\\\n', Text), + (r'\\', Text), + (r'(in|is|and|or|not)\b', Operator.Word), + (r'!=|==|<<|>>|[-~+/*%=<>&^|.]', Operator), + include('keywords'), + (r'(def)((?:\s|\\\s)+)', bygroups(Keyword, Text), 'funcname'), + (r'(class)((?:\s|\\\s)+)', bygroups(Keyword, Text), 'classname'), + (r'(from)((?:\s|\\\s)+)', bygroups(Keyword.Namespace, Text), + 'fromimport'), + (r'(import)((?:\s|\\\s)+)', bygroups(Keyword.Namespace, Text), + 'import'), + include('builtins'), + include('magicfuncs'), + include('magicvars'), + include('backtick'), + ('([rR]|[uUbB][rR]|[rR][uUbB])(""")', + bygroups(String.Affix, String.Double), 'tdqs'), + ("([rR]|[uUbB][rR]|[rR][uUbB])(''')", + bygroups(String.Affix, String.Single), 'tsqs'), + ('([rR]|[uUbB][rR]|[rR][uUbB])(")', + bygroups(String.Affix, String.Double), 'dqs'), + ("([rR]|[uUbB][rR]|[rR][uUbB])(')", + bygroups(String.Affix, String.Single), 'sqs'), + ('([uUbB]?)(""")', bygroups(String.Affix, String.Double), + combined('stringescape', 'tdqs')), + ("([uUbB]?)(''')", bygroups(String.Affix, String.Single), + combined('stringescape', 'tsqs')), + ('([uUbB]?)(")', bygroups(String.Affix, String.Double), + combined('stringescape', 'dqs')), + ("([uUbB]?)(')", bygroups(String.Affix, String.Single), + combined('stringescape', 'sqs')), + include('name'), + include('numbers'), + ], + 'keywords': [ + (words(( + 'assert', 'break', 'continue', 'del', 'elif', 'else', 'except', + 'exec', 'finally', 'for', 'global', 'if', 'lambda', 'pass', + 'print', 'raise', 'return', 'try', 'while', 'yield', + 'yield from', 'as', 'with'), suffix=r'\b'), + Keyword), + ], + 'builtins': [ + (words(( + '__import__', 'abs', 'all', 'any', 'apply', 'basestring', 'bin', + 'bool', 'buffer', 'bytearray', 'bytes', 'callable', 'chr', 'classmethod', + 'cmp', 'coerce', 'compile', 'complex', 'delattr', 'dict', 'dir', 'divmod', + 'enumerate', 'eval', 'execfile', 'exit', 'file', 'filter', 'float', + 'frozenset', 'getattr', 'globals', 'hasattr', 'hash', 'hex', 'id', + 'input', 'int', 'intern', 'isinstance', 'issubclass', 'iter', 'len', + 'list', 'locals', 'long', 'map', 'max', 'min', 'next', 'object', + 'oct', 'open', 'ord', 'pow', 'property', 'range', 'raw_input', 'reduce', + 'reload', 'repr', 'reversed', 'round', 'set', 'setattr', 'slice', + 'sorted', 'staticmethod', 'str', 'sum', 'super', 'tuple', 'type', + 'unichr', 'unicode', 'vars', 'xrange', 'zip'), + prefix=r'(?>> a = 'foo' + >>> print a + foo + >>> 1 / 0 + Traceback (most recent call last): + File "", line 1, in + ZeroDivisionError: integer division or modulo by zero + + Additional options: + + `python3` + Use Python 3 lexer for code. Default is ``True``. + + .. versionadded:: 1.0 + .. versionchanged:: 2.5 + Now defaults to ``True``. + """ + name = 'Python console session' + aliases = ['pycon'] + mimetypes = ['text/x-python-doctest'] + + def __init__(self, **options): + self.python3 = get_bool_opt(options, 'python3', True) + Lexer.__init__(self, **options) + + def get_tokens_unprocessed(self, text): + if self.python3: + pylexer = PythonLexer(**self.options) + tblexer = PythonTracebackLexer(**self.options) + else: + pylexer = Python2Lexer(**self.options) + tblexer = Python2TracebackLexer(**self.options) + + curcode = '' + insertions = [] + curtb = '' + tbindex = 0 + tb = 0 + for match in line_re.finditer(text): + line = match.group() + if line.startswith('>>> ') or line.startswith('... '): + tb = 0 + insertions.append((len(curcode), + [(0, Generic.Prompt, line[:4])])) + curcode += line[4:] + elif line.rstrip() == '...' and not tb: + # only a new >>> prompt can end an exception block + # otherwise an ellipsis in place of the traceback frames + # will be mishandled + insertions.append((len(curcode), + [(0, Generic.Prompt, '...')])) + curcode += line[3:] + else: + if curcode: + yield from do_insertions( + insertions, pylexer.get_tokens_unprocessed(curcode)) + curcode = '' + insertions = [] + if (line.startswith('Traceback (most recent call last):') or + re.match(' File "[^"]+", line \\d+\\n$', line)): + tb = 1 + curtb = line + tbindex = match.start() + elif line == 'KeyboardInterrupt\n': + yield match.start(), Name.Class, line + elif tb: + curtb += line + if not (line.startswith(' ') or line.strip() == '...'): + tb = 0 + for i, t, v in tblexer.get_tokens_unprocessed(curtb): + yield tbindex+i, t, v + curtb = '' + else: + yield match.start(), Generic.Output, line + if curcode: + yield from do_insertions(insertions, + pylexer.get_tokens_unprocessed(curcode)) + if curtb: + for i, t, v in tblexer.get_tokens_unprocessed(curtb): + yield tbindex+i, t, v + + +class PythonTracebackLexer(RegexLexer): + """ + For Python 3.x tracebacks, with support for chained exceptions. + + .. versionadded:: 1.0 + + .. versionchanged:: 2.5 + This is now the default ``PythonTracebackLexer``. It is still available + as the alias ``Python3TracebackLexer``. + """ + + name = 'Python Traceback' + aliases = ['pytb', 'py3tb'] + filenames = ['*.pytb', '*.py3tb'] + mimetypes = ['text/x-python-traceback', 'text/x-python3-traceback'] + + tokens = { + 'root': [ + (r'\n', Text), + (r'^Traceback \(most recent call last\):\n', Generic.Traceback, 'intb'), + (r'^During handling of the above exception, another ' + r'exception occurred:\n\n', Generic.Traceback), + (r'^The above exception was the direct cause of the ' + r'following exception:\n\n', Generic.Traceback), + (r'^(?= File "[^"]+", line \d+)', Generic.Traceback, 'intb'), + (r'^.*\n', Other), + ], + 'intb': [ + (r'^( File )("[^"]+")(, line )(\d+)(, in )(.+)(\n)', + bygroups(Text, Name.Builtin, Text, Number, Text, Name, Text)), + (r'^( File )("[^"]+")(, line )(\d+)(\n)', + bygroups(Text, Name.Builtin, Text, Number, Text)), + (r'^( )(.+)(\n)', + bygroups(Text, using(PythonLexer), Text)), + (r'^([ \t]*)(\.\.\.)(\n)', + bygroups(Text, Comment, Text)), # for doctests... + (r'^([^:]+)(: )(.+)(\n)', + bygroups(Generic.Error, Text, Name, Text), '#pop'), + (r'^([a-zA-Z_][\w.]*)(:?\n)', + bygroups(Generic.Error, Text), '#pop') + ], + } + + +Python3TracebackLexer = PythonTracebackLexer + + +class Python2TracebackLexer(RegexLexer): + """ + For Python tracebacks. + + .. versionadded:: 0.7 + + .. versionchanged:: 2.5 + This class has been renamed from ``PythonTracebackLexer``. + ``PythonTracebackLexer`` now refers to the Python 3 variant. + """ + + name = 'Python 2.x Traceback' + aliases = ['py2tb'] + filenames = ['*.py2tb'] + mimetypes = ['text/x-python2-traceback'] + + tokens = { + 'root': [ + # Cover both (most recent call last) and (innermost last) + # The optional ^C allows us to catch keyboard interrupt signals. + (r'^(\^C)?(Traceback.*\n)', + bygroups(Text, Generic.Traceback), 'intb'), + # SyntaxError starts with this. + (r'^(?= File "[^"]+", line \d+)', Generic.Traceback, 'intb'), + (r'^.*\n', Other), + ], + 'intb': [ + (r'^( File )("[^"]+")(, line )(\d+)(, in )(.+)(\n)', + bygroups(Text, Name.Builtin, Text, Number, Text, Name, Text)), + (r'^( File )("[^"]+")(, line )(\d+)(\n)', + bygroups(Text, Name.Builtin, Text, Number, Text)), + (r'^( )(.+)(\n)', + bygroups(Text, using(Python2Lexer), Text)), + (r'^([ \t]*)(\.\.\.)(\n)', + bygroups(Text, Comment, Text)), # for doctests... + (r'^([^:]+)(: )(.+)(\n)', + bygroups(Generic.Error, Text, Name, Text), '#pop'), + (r'^([a-zA-Z_]\w*)(:?\n)', + bygroups(Generic.Error, Text), '#pop') + ], + } + + +class CythonLexer(RegexLexer): + """ + For Pyrex and `Cython `_ source code. + + .. versionadded:: 1.1 + """ + + name = 'Cython' + aliases = ['cython', 'pyx', 'pyrex'] + filenames = ['*.pyx', '*.pxd', '*.pxi'] + mimetypes = ['text/x-cython', 'application/x-cython'] + + tokens = { + 'root': [ + (r'\n', Text), + (r'^(\s*)("""(?:.|\n)*?""")', bygroups(Text, String.Doc)), + (r"^(\s*)('''(?:.|\n)*?''')", bygroups(Text, String.Doc)), + (r'[^\S\n]+', Text), + (r'#.*$', Comment), + (r'[]{}:(),;[]', Punctuation), + (r'\\\n', Text), + (r'\\', Text), + (r'(in|is|and|or|not)\b', Operator.Word), + (r'(<)([a-zA-Z0-9.?]+)(>)', + bygroups(Punctuation, Keyword.Type, Punctuation)), + (r'!=|==|<<|>>|[-~+/*%=<>&^|.?]', Operator), + (r'(from)(\d+)(<=)(\s+)(<)(\d+)(:)', + bygroups(Keyword, Number.Integer, Operator, Name, Operator, + Name, Punctuation)), + include('keywords'), + (r'(def|property)(\s+)', bygroups(Keyword, Text), 'funcname'), + (r'(cp?def)(\s+)', bygroups(Keyword, Text), 'cdef'), + # (should actually start a block with only cdefs) + (r'(cdef)(:)', bygroups(Keyword, Punctuation)), + (r'(class|struct)(\s+)', bygroups(Keyword, Text), 'classname'), + (r'(from)(\s+)', bygroups(Keyword, Text), 'fromimport'), + (r'(c?import)(\s+)', bygroups(Keyword, Text), 'import'), + include('builtins'), + include('backtick'), + ('(?:[rR]|[uU][rR]|[rR][uU])"""', String, 'tdqs'), + ("(?:[rR]|[uU][rR]|[rR][uU])'''", String, 'tsqs'), + ('(?:[rR]|[uU][rR]|[rR][uU])"', String, 'dqs'), + ("(?:[rR]|[uU][rR]|[rR][uU])'", String, 'sqs'), + ('[uU]?"""', String, combined('stringescape', 'tdqs')), + ("[uU]?'''", String, combined('stringescape', 'tsqs')), + ('[uU]?"', String, combined('stringescape', 'dqs')), + ("[uU]?'", String, combined('stringescape', 'sqs')), + include('name'), + include('numbers'), + ], + 'keywords': [ + (words(( + 'assert', 'async', 'await', 'break', 'by', 'continue', 'ctypedef', 'del', 'elif', + 'else', 'except', 'except?', 'exec', 'finally', 'for', 'fused', 'gil', + 'global', 'if', 'include', 'lambda', 'nogil', 'pass', 'print', + 'raise', 'return', 'try', 'while', 'yield', 'as', 'with'), suffix=r'\b'), + Keyword), + (r'(DEF|IF|ELIF|ELSE)\b', Comment.Preproc), + ], + 'builtins': [ + (words(( + '__import__', 'abs', 'all', 'any', 'apply', 'basestring', 'bin', + 'bool', 'buffer', 'bytearray', 'bytes', 'callable', 'chr', + 'classmethod', 'cmp', 'coerce', 'compile', 'complex', 'delattr', + 'dict', 'dir', 'divmod', 'enumerate', 'eval', 'execfile', 'exit', + 'file', 'filter', 'float', 'frozenset', 'getattr', 'globals', + 'hasattr', 'hash', 'hex', 'id', 'input', 'int', 'intern', 'isinstance', + 'issubclass', 'iter', 'len', 'list', 'locals', 'long', 'map', 'max', + 'min', 'next', 'object', 'oct', 'open', 'ord', 'pow', 'property', + 'range', 'raw_input', 'reduce', 'reload', 'repr', 'reversed', + 'round', 'set', 'setattr', 'slice', 'sorted', 'staticmethod', + 'str', 'sum', 'super', 'tuple', 'type', 'unichr', 'unicode', 'unsigned', + 'vars', 'xrange', 'zip'), prefix=r'(?`_, + a functional and object-oriented programming language + running on the CPython 3 VM. + + .. versionadded:: 1.6 + """ + name = 'dg' + aliases = ['dg'] + filenames = ['*.dg'] + mimetypes = ['text/x-dg'] + + tokens = { + 'root': [ + (r'\s+', Text), + (r'#.*?$', Comment.Single), + + (r'(?i)0b[01]+', Number.Bin), + (r'(?i)0o[0-7]+', Number.Oct), + (r'(?i)0x[0-9a-f]+', Number.Hex), + (r'(?i)[+-]?[0-9]+\.[0-9]+(e[+-]?[0-9]+)?j?', Number.Float), + (r'(?i)[+-]?[0-9]+e[+-]?\d+j?', Number.Float), + (r'(?i)[+-]?[0-9]+j?', Number.Integer), + + (r"(?i)(br|r?b?)'''", String, combined('stringescape', 'tsqs', 'string')), + (r'(?i)(br|r?b?)"""', String, combined('stringescape', 'tdqs', 'string')), + (r"(?i)(br|r?b?)'", String, combined('stringescape', 'sqs', 'string')), + (r'(?i)(br|r?b?)"', String, combined('stringescape', 'dqs', 'string')), + + (r"`\w+'*`", Operator), + (r'\b(and|in|is|or|where)\b', Operator.Word), + (r'[!$%&*+\-./:<-@\\^|~;,]+', Operator), + + (words(( + 'bool', 'bytearray', 'bytes', 'classmethod', 'complex', 'dict', 'dict\'', + 'float', 'frozenset', 'int', 'list', 'list\'', 'memoryview', 'object', + 'property', 'range', 'set', 'set\'', 'slice', 'staticmethod', 'str', + 'super', 'tuple', 'tuple\'', 'type'), + prefix=r'(?`_. + + Reference for implementing this: «Meta Object Facility (MOF) 2.0 + Query/View/Transformation Specification», Version 1.1 - January 2011 + (http://www.omg.org/spec/QVT/1.1/), see §8.4, «Concrete Syntax» in + particular. + + Notable tokens assignments: + + - Name.Class is assigned to the identifier following any of the following + keywords: metamodel, class, exception, primitive, enum, transformation + or library + + - Name.Function is assigned to the names of mappings and queries + + - Name.Builtin.Pseudo is assigned to the pre-defined variables 'this', + 'self' and 'result'. + """ + # With obvious borrowings & inspiration from the Java, Python and C lexers + + name = 'QVTO' + aliases = ['qvto', 'qvt'] + filenames = ['*.qvto'] + + tokens = { + 'root': [ + (r'\n', Text), + (r'[^\S\n]+', Text), + (r'(--|//)(\s*)(directive:)?(.*)$', + bygroups(Comment, Comment, Comment.Preproc, Comment)), + # Uncomment the following if you want to distinguish between + # '/*' and '/**', à la javadoc + # (r'/[*]{2}(.|\n)*?[*]/', Comment.Multiline), + (r'/[*](.|\n)*?[*]/', Comment.Multiline), + (r'\\\n', Text), + (r'(and|not|or|xor|##?)\b', Operator.Word), + (r'(:{1,2}=|[-+]=)\b', Operator.Word), + (r'(@|<<|>>)\b', Keyword), # stereotypes + (r'!=|<>|==|=|!->|->|>=|<=|[.]{3}|[+/*%=<>&|.~]', Operator), + (r'[]{}:(),;[]', Punctuation), + (r'(true|false|unlimited|null)\b', Keyword.Constant), + (r'(this|self|result)\b', Name.Builtin.Pseudo), + (r'(var)\b', Keyword.Declaration), + (r'(from|import)\b', Keyword.Namespace, 'fromimport'), + (r'(metamodel|class|exception|primitive|enum|transformation|' + r'library)(\s+)(\w+)', + bygroups(Keyword.Word, Text, Name.Class)), + (r'(exception)(\s+)(\w+)', + bygroups(Keyword.Word, Text, Name.Exception)), + (r'(main)\b', Name.Function), + (r'(mapping|helper|query)(\s+)', + bygroups(Keyword.Declaration, Text), 'operation'), + (r'(assert)(\s+)\b', bygroups(Keyword, Text), 'assert'), + (r'(Bag|Collection|Dict|OrderedSet|Sequence|Set|Tuple|List)\b', + Keyword.Type), + include('keywords'), + ('"', String, combined('stringescape', 'dqs')), + ("'", String, combined('stringescape', 'sqs')), + include('name'), + include('numbers'), + # (r'([a-zA-Z_]\w*)(::)([a-zA-Z_]\w*)', + # bygroups(Text, Text, Text)), + ], + + 'fromimport': [ + (r'(?:[ \t]|\\\n)+', Text), + (r'[a-zA-Z_][\w.]*', Name.Namespace), + default('#pop'), + ], + + 'operation': [ + (r'::', Text), + (r'(.*::)([a-zA-Z_]\w*)([ \t]*)(\()', + bygroups(Text, Name.Function, Text, Punctuation), '#pop') + ], + + 'assert': [ + (r'(warning|error|fatal)\b', Keyword, '#pop'), + default('#pop'), # all else: go back + ], + + 'keywords': [ + (words(( + 'abstract', 'access', 'any', 'assert', 'blackbox', 'break', + 'case', 'collect', 'collectNested', 'collectOne', 'collectselect', + 'collectselectOne', 'composes', 'compute', 'configuration', + 'constructor', 'continue', 'datatype', 'default', 'derived', + 'disjuncts', 'do', 'elif', 'else', 'end', 'endif', 'except', + 'exists', 'extends', 'forAll', 'forEach', 'forOne', 'from', 'if', + 'implies', 'in', 'inherits', 'init', 'inout', 'intermediate', + 'invresolve', 'invresolveIn', 'invresolveone', 'invresolveoneIn', + 'isUnique', 'iterate', 'late', 'let', 'literal', 'log', 'map', + 'merges', 'modeltype', 'new', 'object', 'one', 'ordered', 'out', + 'package', 'population', 'property', 'raise', 'readonly', + 'references', 'refines', 'reject', 'resolve', 'resolveIn', + 'resolveone', 'resolveoneIn', 'return', 'select', 'selectOne', + 'sortedBy', 'static', 'switch', 'tag', 'then', 'try', 'typedef', + 'unlimited', 'uses', 'when', 'where', 'while', 'with', 'xcollect', + 'xmap', 'xselect'), suffix=r'\b'), Keyword), + ], + + # There is no need to distinguish between String.Single and + # String.Double: 'strings' is factorised for 'dqs' and 'sqs' + 'strings': [ + (r'[^\\\'"\n]+', String), + # quotes, percents and backslashes must be parsed one at a time + (r'[\'"\\]', String), + ], + 'stringescape': [ + (r'\\([\\btnfr"\']|u[0-3][0-7]{2}|u[0-7]{1,2})', String.Escape) + ], + 'dqs': [ # double-quoted string + (r'"', String, '#pop'), + (r'\\\\|\\"', String.Escape), + include('strings') + ], + 'sqs': [ # single-quoted string + (r"'", String, '#pop'), + (r"\\\\|\\'", String.Escape), + include('strings') + ], + 'name': [ + (r'[a-zA-Z_]\w*', Name), + ], + # numbers: excerpt taken from the python lexer + 'numbers': [ + (r'(\d+\.\d*|\d*\.\d+)([eE][+-]?[0-9]+)?', Number.Float), + (r'\d+[eE][+-]?[0-9]+', Number.Float), + (r'\d+', Number.Integer) + ], + } diff --git a/.venv/lib/python3.8/site-packages/pygments/lexers/r.py b/.venv/lib/python3.8/site-packages/pygments/lexers/r.py new file mode 100644 index 00000000..6d841a3a --- /dev/null +++ b/.venv/lib/python3.8/site-packages/pygments/lexers/r.py @@ -0,0 +1,191 @@ +# -*- coding: utf-8 -*- +""" + pygments.lexers.r + ~~~~~~~~~~~~~~~~~ + + Lexers for the R/S languages. + + :copyright: Copyright 2006-2020 by the Pygments team, see AUTHORS. + :license: BSD, see LICENSE for details. +""" + +import re + +from pygments.lexer import Lexer, RegexLexer, include, do_insertions, bygroups +from pygments.token import Text, Comment, Operator, Keyword, Name, String, \ + Number, Punctuation, Generic + +__all__ = ['RConsoleLexer', 'SLexer', 'RdLexer'] + + +line_re = re.compile('.*?\n') + + +class RConsoleLexer(Lexer): + """ + For R console transcripts or R CMD BATCH output files. + """ + + name = 'RConsole' + aliases = ['rconsole', 'rout'] + filenames = ['*.Rout'] + + def get_tokens_unprocessed(self, text): + slexer = SLexer(**self.options) + + current_code_block = '' + insertions = [] + + for match in line_re.finditer(text): + line = match.group() + if line.startswith('>') or line.startswith('+'): + # Colorize the prompt as such, + # then put rest of line into current_code_block + insertions.append((len(current_code_block), + [(0, Generic.Prompt, line[:2])])) + current_code_block += line[2:] + else: + # We have reached a non-prompt line! + # If we have stored prompt lines, need to process them first. + if current_code_block: + # Weave together the prompts and highlight code. + yield from do_insertions( + insertions, slexer.get_tokens_unprocessed(current_code_block)) + # Reset vars for next code block. + current_code_block = '' + insertions = [] + # Now process the actual line itself, this is output from R. + yield match.start(), Generic.Output, line + + # If we happen to end on a code block with nothing after it, need to + # process the last code block. This is neither elegant nor DRY so + # should be changed. + if current_code_block: + yield from do_insertions( + insertions, slexer.get_tokens_unprocessed(current_code_block)) + + +class SLexer(RegexLexer): + """ + For S, S-plus, and R source code. + + .. versionadded:: 0.10 + """ + + name = 'S' + aliases = ['splus', 's', 'r'] + filenames = ['*.S', '*.R', '.Rhistory', '.Rprofile', '.Renviron'] + mimetypes = ['text/S-plus', 'text/S', 'text/x-r-source', 'text/x-r', + 'text/x-R', 'text/x-r-history', 'text/x-r-profile'] + + valid_name = r'`[^`\\]*(?:\\.[^`\\]*)*`|(?:[a-zA-Z]|\.[A-Za-z_.])[\w.]*|\.' + tokens = { + 'comments': [ + (r'#.*$', Comment.Single), + ], + 'valid_name': [ + (valid_name, Name), + ], + 'punctuation': [ + (r'\[{1,2}|\]{1,2}|\(|\)|;|,', Punctuation), + ], + 'keywords': [ + (r'(if|else|for|while|repeat|in|next|break|return|switch|function)' + r'(?![\w.])', + Keyword.Reserved), + ], + 'operators': [ + (r'<>?|-|==|<=|>=|<|>|&&?|!=|\|\|?|\?', Operator), + (r'\*|\+|\^|/|!|%[^%]*%|=|~|\$|@|:{1,3}', Operator), + ], + 'builtin_symbols': [ + (r'(NULL|NA(_(integer|real|complex|character)_)?|' + r'letters|LETTERS|Inf|TRUE|FALSE|NaN|pi|\.\.(\.|[0-9]+))' + r'(?![\w.])', + Keyword.Constant), + (r'(T|F)\b', Name.Builtin.Pseudo), + ], + 'numbers': [ + # hex number + (r'0[xX][a-fA-F0-9]+([pP][0-9]+)?[Li]?', Number.Hex), + # decimal number + (r'[+-]?([0-9]+(\.[0-9]+)?|\.[0-9]+|\.)([eE][+-]?[0-9]+)?[Li]?', + Number), + ], + 'statements': [ + include('comments'), + # whitespaces + (r'\s+', Text), + (r'\'', String, 'string_squote'), + (r'\"', String, 'string_dquote'), + include('builtin_symbols'), + include('valid_name'), + include('numbers'), + include('keywords'), + include('punctuation'), + include('operators'), + ], + 'root': [ + # calls: + (r'(%s)\s*(?=\()' % valid_name, Name.Function), + include('statements'), + # blocks: + (r'\{|\}', Punctuation), + # (r'\{', Punctuation, 'block'), + (r'.', Text), + ], + # 'block': [ + # include('statements'), + # ('\{', Punctuation, '#push'), + # ('\}', Punctuation, '#pop') + # ], + 'string_squote': [ + (r'([^\'\\]|\\.)*\'', String, '#pop'), + ], + 'string_dquote': [ + (r'([^"\\]|\\.)*"', String, '#pop'), + ], + } + + def analyse_text(text): + if re.search(r'[a-z0-9_\])\s]<-(?!-)', text): + return 0.11 + + +class RdLexer(RegexLexer): + """ + Pygments Lexer for R documentation (Rd) files + + This is a very minimal implementation, highlighting little more + than the macros. A description of Rd syntax is found in `Writing R + Extensions `_ + and `Parsing Rd files `_. + + .. versionadded:: 1.6 + """ + name = 'Rd' + aliases = ['rd'] + filenames = ['*.Rd'] + mimetypes = ['text/x-r-doc'] + + # To account for verbatim / LaTeX-like / and R-like areas + # would require parsing. + tokens = { + 'root': [ + # catch escaped brackets and percent sign + (r'\\[\\{}%]', String.Escape), + # comments + (r'%.*$', Comment), + # special macros with no arguments + (r'\\(?:cr|l?dots|R|tab)\b', Keyword.Constant), + # macros + (r'\\[a-zA-Z]+\b', Keyword), + # special preprocessor macros + (r'^\s*#(?:ifn?def|endif).*\b', Comment.Preproc), + # non-escaped brackets + (r'[{}]', Name.Builtin), + # everything else + (r'[^\\%\n{}]+', Text), + (r'.', Text), + ] + } diff --git a/.venv/lib/python3.8/site-packages/pygments/lexers/rdf.py b/.venv/lib/python3.8/site-packages/pygments/lexers/rdf.py new file mode 100644 index 00000000..917807aa --- /dev/null +++ b/.venv/lib/python3.8/site-packages/pygments/lexers/rdf.py @@ -0,0 +1,463 @@ +# -*- coding: utf-8 -*- +""" + pygments.lexers.rdf + ~~~~~~~~~~~~~~~~~~~ + + Lexers for semantic web and RDF query languages and markup. + + :copyright: Copyright 2006-2020 by the Pygments team, see AUTHORS. + :license: BSD, see LICENSE for details. +""" + +import re + +from pygments.lexer import RegexLexer, bygroups, default +from pygments.token import Keyword, Punctuation, String, Number, Operator, Generic, \ + Whitespace, Name, Literal, Comment, Text + +__all__ = ['SparqlLexer', 'TurtleLexer', 'ShExCLexer'] + + +class SparqlLexer(RegexLexer): + """ + Lexer for `SPARQL `_ query language. + + .. versionadded:: 2.0 + """ + name = 'SPARQL' + aliases = ['sparql'] + filenames = ['*.rq', '*.sparql'] + mimetypes = ['application/sparql-query'] + + # character group definitions :: + + PN_CHARS_BASE_GRP = ('a-zA-Z' + '\u00c0-\u00d6' + '\u00d8-\u00f6' + '\u00f8-\u02ff' + '\u0370-\u037d' + '\u037f-\u1fff' + '\u200c-\u200d' + '\u2070-\u218f' + '\u2c00-\u2fef' + '\u3001-\ud7ff' + '\uf900-\ufdcf' + '\ufdf0-\ufffd') + + PN_CHARS_U_GRP = (PN_CHARS_BASE_GRP + '_') + + PN_CHARS_GRP = (PN_CHARS_U_GRP + + r'\-' + + r'0-9' + + '\u00b7' + + '\u0300-\u036f' + + '\u203f-\u2040') + + HEX_GRP = '0-9A-Fa-f' + + PN_LOCAL_ESC_CHARS_GRP = r' _~.\-!$&"()*+,;=/?#@%' + + # terminal productions :: + + PN_CHARS_BASE = '[' + PN_CHARS_BASE_GRP + ']' + + PN_CHARS_U = '[' + PN_CHARS_U_GRP + ']' + + PN_CHARS = '[' + PN_CHARS_GRP + ']' + + HEX = '[' + HEX_GRP + ']' + + PN_LOCAL_ESC_CHARS = '[' + PN_LOCAL_ESC_CHARS_GRP + ']' + + IRIREF = r'<(?:[^<>"{}|^`\\\x00-\x20])*>' + + BLANK_NODE_LABEL = '_:[0-9' + PN_CHARS_U_GRP + '](?:[' + PN_CHARS_GRP + \ + '.]*' + PN_CHARS + ')?' + + PN_PREFIX = PN_CHARS_BASE + '(?:[' + PN_CHARS_GRP + '.]*' + PN_CHARS + ')?' + + VARNAME = '[0-9' + PN_CHARS_U_GRP + '][' + PN_CHARS_U_GRP + \ + '0-9\u00b7\u0300-\u036f\u203f-\u2040]*' + + PERCENT = '%' + HEX + HEX + + PN_LOCAL_ESC = r'\\' + PN_LOCAL_ESC_CHARS + + PLX = '(?:' + PERCENT + ')|(?:' + PN_LOCAL_ESC + ')' + + PN_LOCAL = ('(?:[' + PN_CHARS_U_GRP + ':0-9' + ']|' + PLX + ')' + + '(?:(?:[' + PN_CHARS_GRP + '.:]|' + PLX + ')*(?:[' + + PN_CHARS_GRP + ':]|' + PLX + '))?') + + EXPONENT = r'[eE][+-]?\d+' + + # Lexer token definitions :: + + tokens = { + 'root': [ + (r'\s+', Text), + # keywords :: + (r'(?i)(select|construct|describe|ask|where|filter|group\s+by|minus|' + r'distinct|reduced|from\s+named|from|order\s+by|desc|asc|limit|' + r'offset|values|bindings|load|into|clear|drop|create|add|move|copy|' + r'insert\s+data|delete\s+data|delete\s+where|with|delete|insert|' + r'using\s+named|using|graph|default|named|all|optional|service|' + r'silent|bind|undef|union|not\s+in|in|as|having|to|prefix|base)\b', Keyword), + (r'(a)\b', Keyword), + # IRIs :: + ('(' + IRIREF + ')', Name.Label), + # blank nodes :: + ('(' + BLANK_NODE_LABEL + ')', Name.Label), + # # variables :: + ('[?$]' + VARNAME, Name.Variable), + # prefixed names :: + (r'(' + PN_PREFIX + r')?(\:)(' + PN_LOCAL + r')?', + bygroups(Name.Namespace, Punctuation, Name.Tag)), + # function names :: + (r'(?i)(str|lang|langmatches|datatype|bound|iri|uri|bnode|rand|abs|' + r'ceil|floor|round|concat|strlen|ucase|lcase|encode_for_uri|' + r'contains|strstarts|strends|strbefore|strafter|year|month|day|' + r'hours|minutes|seconds|timezone|tz|now|uuid|struuid|md5|sha1|sha256|sha384|' + r'sha512|coalesce|if|strlang|strdt|sameterm|isiri|isuri|isblank|' + r'isliteral|isnumeric|regex|substr|replace|exists|not\s+exists|' + r'count|sum|min|max|avg|sample|group_concat|separator)\b', + Name.Function), + # boolean literals :: + (r'(true|false)', Keyword.Constant), + # double literals :: + (r'[+\-]?(\d+\.\d*' + EXPONENT + r'|\.?\d+' + EXPONENT + ')', Number.Float), + # decimal literals :: + (r'[+\-]?(\d+\.\d*|\.\d+)', Number.Float), + # integer literals :: + (r'[+\-]?\d+', Number.Integer), + # operators :: + (r'(\|\||&&|=|\*|\-|\+|/|!=|<=|>=|!|<|>)', Operator), + # punctuation characters :: + (r'[(){}.;,:^\[\]]', Punctuation), + # line comments :: + (r'#[^\n]*', Comment), + # strings :: + (r'"""', String, 'triple-double-quoted-string'), + (r'"', String, 'single-double-quoted-string'), + (r"'''", String, 'triple-single-quoted-string'), + (r"'", String, 'single-single-quoted-string'), + ], + 'triple-double-quoted-string': [ + (r'"""', String, 'end-of-string'), + (r'[^\\]+', String), + (r'\\', String, 'string-escape'), + ], + 'single-double-quoted-string': [ + (r'"', String, 'end-of-string'), + (r'[^"\\\n]+', String), + (r'\\', String, 'string-escape'), + ], + 'triple-single-quoted-string': [ + (r"'''", String, 'end-of-string'), + (r'[^\\]+', String), + (r'\\', String.Escape, 'string-escape'), + ], + 'single-single-quoted-string': [ + (r"'", String, 'end-of-string'), + (r"[^'\\\n]+", String), + (r'\\', String, 'string-escape'), + ], + 'string-escape': [ + (r'u' + HEX + '{4}', String.Escape, '#pop'), + (r'U' + HEX + '{8}', String.Escape, '#pop'), + (r'.', String.Escape, '#pop'), + ], + 'end-of-string': [ + (r'(@)([a-zA-Z]+(?:-[a-zA-Z0-9]+)*)', + bygroups(Operator, Name.Function), '#pop:2'), + (r'\^\^', Operator, '#pop:2'), + default('#pop:2'), + ], + } + + +class TurtleLexer(RegexLexer): + """ + Lexer for `Turtle `_ data language. + + .. versionadded:: 2.1 + """ + name = 'Turtle' + aliases = ['turtle'] + filenames = ['*.ttl'] + mimetypes = ['text/turtle', 'application/x-turtle'] + + # character group definitions :: + PN_CHARS_BASE_GRP = ('a-zA-Z' + '\u00c0-\u00d6' + '\u00d8-\u00f6' + '\u00f8-\u02ff' + '\u0370-\u037d' + '\u037f-\u1fff' + '\u200c-\u200d' + '\u2070-\u218f' + '\u2c00-\u2fef' + '\u3001-\ud7ff' + '\uf900-\ufdcf' + '\ufdf0-\ufffd') + + PN_CHARS_U_GRP = (PN_CHARS_BASE_GRP + '_') + + PN_CHARS_GRP = (PN_CHARS_U_GRP + + r'\-' + + r'0-9' + + '\u00b7' + + '\u0300-\u036f' + + '\u203f-\u2040') + + PN_CHARS = '[' + PN_CHARS_GRP + ']' + + PN_CHARS_BASE = '[' + PN_CHARS_BASE_GRP + ']' + + PN_PREFIX = PN_CHARS_BASE + '(?:[' + PN_CHARS_GRP + '.]*' + PN_CHARS + ')?' + + HEX_GRP = '0-9A-Fa-f' + + HEX = '[' + HEX_GRP + ']' + + PERCENT = '%' + HEX + HEX + + PN_LOCAL_ESC_CHARS_GRP = r' _~.\-!$&"()*+,;=/?#@%' + + PN_LOCAL_ESC_CHARS = '[' + PN_LOCAL_ESC_CHARS_GRP + ']' + + PN_LOCAL_ESC = r'\\' + PN_LOCAL_ESC_CHARS + + PLX = '(?:' + PERCENT + ')|(?:' + PN_LOCAL_ESC + ')' + + PN_LOCAL = ('(?:[' + PN_CHARS_U_GRP + ':0-9' + ']|' + PLX + ')' + + '(?:(?:[' + PN_CHARS_GRP + '.:]|' + PLX + ')*(?:[' + + PN_CHARS_GRP + ':]|' + PLX + '))?') + + patterns = { + 'PNAME_NS': r'((?:[a-zA-Z][\w-]*)?\:)', # Simplified character range + 'IRIREF': r'(<[^<>"{}|^`\\\x00-\x20]*>)' + } + + tokens = { + 'root': [ + (r'\s+', Text), + + # Base / prefix + (r'(@base|BASE)(\s+)%(IRIREF)s(\s*)(\.?)' % patterns, + bygroups(Keyword, Whitespace, Name.Variable, Whitespace, + Punctuation)), + (r'(@prefix|PREFIX)(\s+)%(PNAME_NS)s(\s+)%(IRIREF)s(\s*)(\.?)' % patterns, + bygroups(Keyword, Whitespace, Name.Namespace, Whitespace, + Name.Variable, Whitespace, Punctuation)), + + # The shorthand predicate 'a' + (r'(?<=\s)a(?=\s)', Keyword.Type), + + # IRIREF + (r'%(IRIREF)s' % patterns, Name.Variable), + + # PrefixedName + (r'(' + PN_PREFIX + r')?(\:)(' + PN_LOCAL + r')?', + bygroups(Name.Namespace, Punctuation, Name.Tag)), + + # Comment + (r'#[^\n]+', Comment), + + (r'\b(true|false)\b', Literal), + (r'[+\-]?\d*\.\d+', Number.Float), + (r'[+\-]?\d*(:?\.\d+)?E[+\-]?\d+', Number.Float), + (r'[+\-]?\d+', Number.Integer), + (r'[\[\](){}.;,:^]', Punctuation), + + (r'"""', String, 'triple-double-quoted-string'), + (r'"', String, 'single-double-quoted-string'), + (r"'''", String, 'triple-single-quoted-string'), + (r"'", String, 'single-single-quoted-string'), + ], + 'triple-double-quoted-string': [ + (r'"""', String, 'end-of-string'), + (r'[^\\]+', String), + (r'\\', String, 'string-escape'), + ], + 'single-double-quoted-string': [ + (r'"', String, 'end-of-string'), + (r'[^"\\\n]+', String), + (r'\\', String, 'string-escape'), + ], + 'triple-single-quoted-string': [ + (r"'''", String, 'end-of-string'), + (r'[^\\]+', String), + (r'\\', String, 'string-escape'), + ], + 'single-single-quoted-string': [ + (r"'", String, 'end-of-string'), + (r"[^'\\\n]+", String), + (r'\\', String, 'string-escape'), + ], + 'string-escape': [ + (r'.', String, '#pop'), + ], + 'end-of-string': [ + (r'(@)([a-zA-Z]+(?:-[a-zA-Z0-9]+)*)', + bygroups(Operator, Generic.Emph), '#pop:2'), + + (r'(\^\^)%(IRIREF)s' % patterns, bygroups(Operator, Generic.Emph), '#pop:2'), + + default('#pop:2'), + + ], + } + + # Turtle and Tera Term macro files share the same file extension + # but each has a recognizable and distinct syntax. + def analyse_text(text): + for t in ('@base ', 'BASE ', '@prefix ', 'PREFIX '): + if re.search(r'^\s*%s' % t, text): + return 0.80 + + +class ShExCLexer(RegexLexer): + """ + Lexer for `ShExC `_ shape expressions language syntax. + """ + name = 'ShExC' + aliases = ['shexc', 'shex'] + filenames = ['*.shex'] + mimetypes = ['text/shex'] + + # character group definitions :: + + PN_CHARS_BASE_GRP = ('a-zA-Z' + '\u00c0-\u00d6' + '\u00d8-\u00f6' + '\u00f8-\u02ff' + '\u0370-\u037d' + '\u037f-\u1fff' + '\u200c-\u200d' + '\u2070-\u218f' + '\u2c00-\u2fef' + '\u3001-\ud7ff' + '\uf900-\ufdcf' + '\ufdf0-\ufffd') + + PN_CHARS_U_GRP = (PN_CHARS_BASE_GRP + '_') + + PN_CHARS_GRP = (PN_CHARS_U_GRP + + r'\-' + + r'0-9' + + '\u00b7' + + '\u0300-\u036f' + + '\u203f-\u2040') + + HEX_GRP = '0-9A-Fa-f' + + PN_LOCAL_ESC_CHARS_GRP = r"_~.\-!$&'()*+,;=/?#@%" + + # terminal productions :: + + PN_CHARS_BASE = '[' + PN_CHARS_BASE_GRP + ']' + + PN_CHARS_U = '[' + PN_CHARS_U_GRP + ']' + + PN_CHARS = '[' + PN_CHARS_GRP + ']' + + HEX = '[' + HEX_GRP + ']' + + PN_LOCAL_ESC_CHARS = '[' + PN_LOCAL_ESC_CHARS_GRP + ']' + + UCHAR_NO_BACKSLASH = '(?:u' + HEX + '{4}|U' + HEX + '{8})' + + UCHAR = r'\\' + UCHAR_NO_BACKSLASH + + IRIREF = r'<(?:[^\x00-\x20<>"{}|^`\\]|' + UCHAR + ')*>' + + BLANK_NODE_LABEL = '_:[0-9' + PN_CHARS_U_GRP + '](?:[' + PN_CHARS_GRP + \ + '.]*' + PN_CHARS + ')?' + + PN_PREFIX = PN_CHARS_BASE + '(?:[' + PN_CHARS_GRP + '.]*' + PN_CHARS + ')?' + + PERCENT = '%' + HEX + HEX + + PN_LOCAL_ESC = r'\\' + PN_LOCAL_ESC_CHARS + + PLX = '(?:' + PERCENT + ')|(?:' + PN_LOCAL_ESC + ')' + + PN_LOCAL = ('(?:[' + PN_CHARS_U_GRP + ':0-9' + ']|' + PLX + ')' + + '(?:(?:[' + PN_CHARS_GRP + '.:]|' + PLX + ')*(?:[' + + PN_CHARS_GRP + ':]|' + PLX + '))?') + + EXPONENT = r'[eE][+-]?\d+' + + # Lexer token definitions :: + + tokens = { + 'root': [ + (r'\s+', Text), + # keywords :: + (r'(?i)(base|prefix|start|external|' + r'literal|iri|bnode|nonliteral|length|minlength|maxlength|' + r'mininclusive|minexclusive|maxinclusive|maxexclusive|' + r'totaldigits|fractiondigits|' + r'closed|extra)\b', Keyword), + (r'(a)\b', Keyword), + # IRIs :: + ('(' + IRIREF + ')', Name.Label), + # blank nodes :: + ('(' + BLANK_NODE_LABEL + ')', Name.Label), + # prefixed names :: + (r'(' + PN_PREFIX + r')?(\:)(' + PN_LOCAL + ')?', + bygroups(Name.Namespace, Punctuation, Name.Tag)), + # boolean literals :: + (r'(true|false)', Keyword.Constant), + # double literals :: + (r'[+\-]?(\d+\.\d*' + EXPONENT + r'|\.?\d+' + EXPONENT + ')', Number.Float), + # decimal literals :: + (r'[+\-]?(\d+\.\d*|\.\d+)', Number.Float), + # integer literals :: + (r'[+\-]?\d+', Number.Integer), + # operators :: + (r'[@|$&=*+?^\-~]', Operator), + # operator keywords :: + (r'(?i)(and|or|not)\b', Operator.Word), + # punctuation characters :: + (r'[(){}.;,:^\[\]]', Punctuation), + # line comments :: + (r'#[^\n]*', Comment), + # strings :: + (r'"""', String, 'triple-double-quoted-string'), + (r'"', String, 'single-double-quoted-string'), + (r"'''", String, 'triple-single-quoted-string'), + (r"'", String, 'single-single-quoted-string'), + ], + 'triple-double-quoted-string': [ + (r'"""', String, 'end-of-string'), + (r'[^\\]+', String), + (r'\\', String, 'string-escape'), + ], + 'single-double-quoted-string': [ + (r'"', String, 'end-of-string'), + (r'[^"\\\n]+', String), + (r'\\', String, 'string-escape'), + ], + 'triple-single-quoted-string': [ + (r"'''", String, 'end-of-string'), + (r'[^\\]+', String), + (r'\\', String.Escape, 'string-escape'), + ], + 'single-single-quoted-string': [ + (r"'", String, 'end-of-string'), + (r"[^'\\\n]+", String), + (r'\\', String, 'string-escape'), + ], + 'string-escape': [ + (UCHAR_NO_BACKSLASH, String.Escape, '#pop'), + (r'.', String.Escape, '#pop'), + ], + 'end-of-string': [ + (r'(@)([a-zA-Z]+(?:-[a-zA-Z0-9]+)*)', + bygroups(Operator, Name.Function), '#pop:2'), + (r'\^\^', Operator, '#pop:2'), + default('#pop:2'), + ], + } diff --git a/.venv/lib/python3.8/site-packages/pygments/lexers/rebol.py b/.venv/lib/python3.8/site-packages/pygments/lexers/rebol.py new file mode 100644 index 00000000..211060b4 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/pygments/lexers/rebol.py @@ -0,0 +1,431 @@ +# -*- coding: utf-8 -*- +""" + pygments.lexers.rebol + ~~~~~~~~~~~~~~~~~~~~~ + + Lexers for the REBOL and related languages. + + :copyright: Copyright 2006-2020 by the Pygments team, see AUTHORS. + :license: BSD, see LICENSE for details. +""" + +import re + +from pygments.lexer import RegexLexer, bygroups +from pygments.token import Text, Comment, Operator, Keyword, Name, String, \ + Number, Generic, Whitespace + +__all__ = ['RebolLexer', 'RedLexer'] + + +class RebolLexer(RegexLexer): + """ + A `REBOL `_ lexer. + + .. versionadded:: 1.1 + """ + name = 'REBOL' + aliases = ['rebol'] + filenames = ['*.r', '*.r3', '*.reb'] + mimetypes = ['text/x-rebol'] + + flags = re.IGNORECASE | re.MULTILINE + + escape_re = r'(?:\^\([0-9a-f]{1,4}\)*)' + + def word_callback(lexer, match): + word = match.group() + + if re.match(".*:$", word): + yield match.start(), Generic.Subheading, word + elif re.match( + r'(native|alias|all|any|as-string|as-binary|bind|bound\?|case|' + r'catch|checksum|comment|debase|dehex|exclude|difference|disarm|' + r'either|else|enbase|foreach|remove-each|form|free|get|get-env|if|' + r'in|intersect|loop|minimum-of|maximum-of|mold|new-line|' + r'new-line\?|not|now|prin|print|reduce|compose|construct|repeat|' + r'reverse|save|script\?|set|shift|switch|throw|to-hex|trace|try|' + r'type\?|union|unique|unless|unprotect|unset|until|use|value\?|' + r'while|compress|decompress|secure|open|close|read|read-io|' + r'write-io|write|update|query|wait|input\?|exp|log-10|log-2|' + r'log-e|square-root|cosine|sine|tangent|arccosine|arcsine|' + r'arctangent|protect|lowercase|uppercase|entab|detab|connected\?|' + r'browse|launch|stats|get-modes|set-modes|to-local-file|' + r'to-rebol-file|encloak|decloak|create-link|do-browser|bind\?|' + r'hide|draw|show|size-text|textinfo|offset-to-caret|' + r'caret-to-offset|local-request-file|rgb-to-hsv|hsv-to-rgb|' + r'crypt-strength\?|dh-make-key|dh-generate-key|dh-compute-key|' + r'dsa-make-key|dsa-generate-key|dsa-make-signature|' + r'dsa-verify-signature|rsa-make-key|rsa-generate-key|' + r'rsa-encrypt)$', word): + yield match.start(), Name.Builtin, word + elif re.match( + r'(add|subtract|multiply|divide|remainder|power|and~|or~|xor~|' + r'minimum|maximum|negate|complement|absolute|random|head|tail|' + r'next|back|skip|at|pick|first|second|third|fourth|fifth|sixth|' + r'seventh|eighth|ninth|tenth|last|path|find|select|make|to|copy\*|' + r'insert|remove|change|poke|clear|trim|sort|min|max|abs|cp|' + r'copy)$', word): + yield match.start(), Name.Function, word + elif re.match( + r'(error|source|input|license|help|install|echo|Usage|with|func|' + r'throw-on-error|function|does|has|context|probe|\?\?|as-pair|' + r'mod|modulo|round|repend|about|set-net|append|join|rejoin|reform|' + r'remold|charset|array|replace|move|extract|forskip|forall|alter|' + r'first+|also|take|for|forever|dispatch|attempt|what-dir|' + r'change-dir|clean-path|list-dir|dirize|rename|split-path|delete|' + r'make-dir|delete-dir|in-dir|confirm|dump-obj|upgrade|what|' + r'build-tag|process-source|build-markup|decode-cgi|read-cgi|' + r'write-user|save-user|set-user-name|protect-system|parse-xml|' + r'cvs-date|cvs-version|do-boot|get-net-info|desktop|layout|' + r'scroll-para|get-face|alert|set-face|uninstall|unfocus|' + r'request-dir|center-face|do-events|net-error|decode-url|' + r'parse-header|parse-header-date|parse-email-addrs|import-email|' + r'send|build-attach-body|resend|show-popup|hide-popup|open-events|' + r'find-key-face|do-face|viewtop|confine|find-window|' + r'insert-event-func|remove-event-func|inform|dump-pane|dump-face|' + r'flag-face|deflag-face|clear-fields|read-net|vbug|path-thru|' + r'read-thru|load-thru|do-thru|launch-thru|load-image|' + r'request-download|do-face-alt|set-font|set-para|get-style|' + r'set-style|make-face|stylize|choose|hilight-text|hilight-all|' + r'unlight-text|focus|scroll-drag|clear-face|reset-face|scroll-face|' + r'resize-face|load-stock|load-stock-block|notify|request|flash|' + r'request-color|request-pass|request-text|request-list|' + r'request-date|request-file|dbug|editor|link-relative-path|' + r'emailer|parse-error)$', word): + yield match.start(), Keyword.Namespace, word + elif re.match( + r'(halt|quit|do|load|q|recycle|call|run|ask|parse|view|unview|' + r'return|exit|break)$', word): + yield match.start(), Name.Exception, word + elif re.match('REBOL$', word): + yield match.start(), Generic.Heading, word + elif re.match("to-.*", word): + yield match.start(), Keyword, word + elif re.match(r'(\+|-|\*|/|//|\*\*|and|or|xor|=\?|=|==|<>|<|>|<=|>=)$', + word): + yield match.start(), Operator, word + elif re.match(r".*\?$", word): + yield match.start(), Keyword, word + elif re.match(r".*\!$", word): + yield match.start(), Keyword.Type, word + elif re.match("'.*", word): + yield match.start(), Name.Variable.Instance, word # lit-word + elif re.match("#.*", word): + yield match.start(), Name.Label, word # issue + elif re.match("%.*", word): + yield match.start(), Name.Decorator, word # file + else: + yield match.start(), Name.Variable, word + + tokens = { + 'root': [ + (r'[^R]+', Comment), + (r'REBOL\s+\[', Generic.Strong, 'script'), + (r'R', Comment) + ], + 'script': [ + (r'\s+', Text), + (r'#"', String.Char, 'char'), + (r'#\{[0-9a-f]*\}', Number.Hex), + (r'2#\{', Number.Hex, 'bin2'), + (r'64#\{[0-9a-z+/=\s]*\}', Number.Hex), + (r'"', String, 'string'), + (r'\{', String, 'string2'), + (r';#+.*\n', Comment.Special), + (r';\*+.*\n', Comment.Preproc), + (r';.*\n', Comment), + (r'%"', Name.Decorator, 'stringFile'), + (r'%[^(^{")\s\[\]]+', Name.Decorator), + (r'[+-]?([a-z]{1,3})?\$\d+(\.\d+)?', Number.Float), # money + (r'[+-]?\d+\:\d+(\:\d+)?(\.\d+)?', String.Other), # time + (r'\d+[\-/][0-9a-z]+[\-/]\d+(\/\d+\:\d+((\:\d+)?' + r'([.\d+]?([+-]?\d+:\d+)?)?)?)?', String.Other), # date + (r'\d+(\.\d+)+\.\d+', Keyword.Constant), # tuple + (r'\d+X\d+', Keyword.Constant), # pair + (r'[+-]?\d+(\'\d+)?([.,]\d*)?E[+-]?\d+', Number.Float), + (r'[+-]?\d+(\'\d+)?[.,]\d*', Number.Float), + (r'[+-]?\d+(\'\d+)?', Number), + (r'[\[\]()]', Generic.Strong), + (r'[a-z]+[^(^{"\s:)]*://[^(^{"\s)]*', Name.Decorator), # url + (r'mailto:[^(^{"@\s)]+@[^(^{"@\s)]+', Name.Decorator), # url + (r'[^(^{"@\s)]+@[^(^{"@\s)]+', Name.Decorator), # email + (r'comment\s"', Comment, 'commentString1'), + (r'comment\s\{', Comment, 'commentString2'), + (r'comment\s\[', Comment, 'commentBlock'), + (r'comment\s[^(\s{"\[]+', Comment), + (r'/[^(^{")\s/[\]]*', Name.Attribute), + (r'([^(^{")\s/[\]]+)(?=[:({"\s/\[\]])', word_callback), + (r'<[\w:.-]*>', Name.Tag), + (r'<[^(<>\s")]+', Name.Tag, 'tag'), + (r'([^(^{")\s]+)', Text), + ], + 'string': [ + (r'[^(^")]+', String), + (escape_re, String.Escape), + (r'[(|)]+', String), + (r'\^.', String.Escape), + (r'"', String, '#pop'), + ], + 'string2': [ + (r'[^(^{})]+', String), + (escape_re, String.Escape), + (r'[(|)]+', String), + (r'\^.', String.Escape), + (r'\{', String, '#push'), + (r'\}', String, '#pop'), + ], + 'stringFile': [ + (r'[^(^")]+', Name.Decorator), + (escape_re, Name.Decorator), + (r'\^.', Name.Decorator), + (r'"', Name.Decorator, '#pop'), + ], + 'char': [ + (escape_re + '"', String.Char, '#pop'), + (r'\^."', String.Char, '#pop'), + (r'."', String.Char, '#pop'), + ], + 'tag': [ + (escape_re, Name.Tag), + (r'"', Name.Tag, 'tagString'), + (r'[^(<>\r\n")]+', Name.Tag), + (r'>', Name.Tag, '#pop'), + ], + 'tagString': [ + (r'[^(^")]+', Name.Tag), + (escape_re, Name.Tag), + (r'[(|)]+', Name.Tag), + (r'\^.', Name.Tag), + (r'"', Name.Tag, '#pop'), + ], + 'tuple': [ + (r'(\d+\.)+', Keyword.Constant), + (r'\d+', Keyword.Constant, '#pop'), + ], + 'bin2': [ + (r'\s+', Number.Hex), + (r'([01]\s*){8}', Number.Hex), + (r'\}', Number.Hex, '#pop'), + ], + 'commentString1': [ + (r'[^(^")]+', Comment), + (escape_re, Comment), + (r'[(|)]+', Comment), + (r'\^.', Comment), + (r'"', Comment, '#pop'), + ], + 'commentString2': [ + (r'[^(^{})]+', Comment), + (escape_re, Comment), + (r'[(|)]+', Comment), + (r'\^.', Comment), + (r'\{', Comment, '#push'), + (r'\}', Comment, '#pop'), + ], + 'commentBlock': [ + (r'\[', Comment, '#push'), + (r'\]', Comment, '#pop'), + (r'"', Comment, "commentString1"), + (r'\{', Comment, "commentString2"), + (r'[^(\[\]"{)]+', Comment), + ], + } + + def analyse_text(text): + """ + Check if code contains REBOL header and so it probably not R code + """ + if re.match(r'^\s*REBOL\s*\[', text, re.IGNORECASE): + # The code starts with REBOL header + return 1.0 + elif re.search(r'\s*REBOL\s*\[', text, re.IGNORECASE): + # The code contains REBOL header but also some text before it + return 0.5 + + +class RedLexer(RegexLexer): + """ + A `Red-language `_ lexer. + + .. versionadded:: 2.0 + """ + name = 'Red' + aliases = ['red', 'red/system'] + filenames = ['*.red', '*.reds'] + mimetypes = ['text/x-red', 'text/x-red-system'] + + flags = re.IGNORECASE | re.MULTILINE + + escape_re = r'(?:\^\([0-9a-f]{1,4}\)*)' + + def word_callback(lexer, match): + word = match.group() + + if re.match(".*:$", word): + yield match.start(), Generic.Subheading, word + elif re.match(r'(if|unless|either|any|all|while|until|loop|repeat|' + r'foreach|forall|func|function|does|has|switch|' + r'case|reduce|compose|get|set|print|prin|equal\?|' + r'not-equal\?|strict-equal\?|lesser\?|greater\?|lesser-or-equal\?|' + r'greater-or-equal\?|same\?|not|type\?|stats|' + r'bind|union|replace|charset|routine)$', word): + yield match.start(), Name.Builtin, word + elif re.match(r'(make|random|reflect|to|form|mold|absolute|add|divide|multiply|negate|' + r'power|remainder|round|subtract|even\?|odd\?|and~|complement|or~|xor~|' + r'append|at|back|change|clear|copy|find|head|head\?|index\?|insert|' + r'length\?|next|pick|poke|remove|reverse|select|sort|skip|swap|tail|tail\?|' + r'take|trim|create|close|delete|modify|open|open\?|query|read|rename|' + r'update|write)$', word): + yield match.start(), Name.Function, word + elif re.match(r'(yes|on|no|off|true|false|tab|cr|lf|newline|escape|slash|sp|space|null|' + r'none|crlf|dot|null-byte)$', word): + yield match.start(), Name.Builtin.Pseudo, word + elif re.match(r'(#system-global|#include|#enum|#define|#either|#if|#import|#export|' + r'#switch|#default|#get-definition)$', word): + yield match.start(), Keyword.Namespace, word + elif re.match(r'(system|halt|quit|quit-return|do|load|q|recycle|call|run|ask|parse|' + r'raise-error|return|exit|break|alias|push|pop|probe|\?\?|spec-of|body-of|' + r'quote|forever)$', word): + yield match.start(), Name.Exception, word + elif re.match(r'(action\?|block\?|char\?|datatype\?|file\?|function\?|get-path\?|zero\?|' + r'get-word\?|integer\?|issue\?|lit-path\?|lit-word\?|logic\?|native\?|' + r'op\?|paren\?|path\?|refinement\?|set-path\?|set-word\?|string\?|unset\?|' + r'any-struct\?|none\?|word\?|any-series\?)$', word): + yield match.start(), Keyword, word + elif re.match(r'(JNICALL|stdcall|cdecl|infix)$', word): + yield match.start(), Keyword.Namespace, word + elif re.match("to-.*", word): + yield match.start(), Keyword, word + elif re.match(r'(\+|-\*\*|-|\*\*|//|/|\*|and|or|xor|=\?|===|==|=|<>|<=|>=|' + r'<<<|>>>|<<|>>|<|>%)$', word): + yield match.start(), Operator, word + elif re.match(r".*\!$", word): + yield match.start(), Keyword.Type, word + elif re.match("'.*", word): + yield match.start(), Name.Variable.Instance, word # lit-word + elif re.match("#.*", word): + yield match.start(), Name.Label, word # issue + elif re.match("%.*", word): + yield match.start(), Name.Decorator, word # file + elif re.match(":.*", word): + yield match.start(), Generic.Subheading, word # get-word + else: + yield match.start(), Name.Variable, word + + tokens = { + 'root': [ + (r'[^R]+', Comment), + (r'Red/System\s+\[', Generic.Strong, 'script'), + (r'Red\s+\[', Generic.Strong, 'script'), + (r'R', Comment) + ], + 'script': [ + (r'\s+', Text), + (r'#"', String.Char, 'char'), + (r'#\{[0-9a-f\s]*\}', Number.Hex), + (r'2#\{', Number.Hex, 'bin2'), + (r'64#\{[0-9a-z+/=\s]*\}', Number.Hex), + (r'([0-9a-f]+)(h)((\s)|(?=[\[\]{}"()]))', + bygroups(Number.Hex, Name.Variable, Whitespace)), + (r'"', String, 'string'), + (r'\{', String, 'string2'), + (r';#+.*\n', Comment.Special), + (r';\*+.*\n', Comment.Preproc), + (r';.*\n', Comment), + (r'%"', Name.Decorator, 'stringFile'), + (r'%[^(^{")\s\[\]]+', Name.Decorator), + (r'[+-]?([a-z]{1,3})?\$\d+(\.\d+)?', Number.Float), # money + (r'[+-]?\d+\:\d+(\:\d+)?(\.\d+)?', String.Other), # time + (r'\d+[\-/][0-9a-z]+[\-/]\d+(/\d+:\d+((:\d+)?' + r'([\.\d+]?([+-]?\d+:\d+)?)?)?)?', String.Other), # date + (r'\d+(\.\d+)+\.\d+', Keyword.Constant), # tuple + (r'\d+X\d+', Keyword.Constant), # pair + (r'[+-]?\d+(\'\d+)?([.,]\d*)?E[+-]?\d+', Number.Float), + (r'[+-]?\d+(\'\d+)?[.,]\d*', Number.Float), + (r'[+-]?\d+(\'\d+)?', Number), + (r'[\[\]()]', Generic.Strong), + (r'[a-z]+[^(^{"\s:)]*://[^(^{"\s)]*', Name.Decorator), # url + (r'mailto:[^(^{"@\s)]+@[^(^{"@\s)]+', Name.Decorator), # url + (r'[^(^{"@\s)]+@[^(^{"@\s)]+', Name.Decorator), # email + (r'comment\s"', Comment, 'commentString1'), + (r'comment\s\{', Comment, 'commentString2'), + (r'comment\s\[', Comment, 'commentBlock'), + (r'comment\s[^(\s{"\[]+', Comment), + (r'/[^(^{^")\s/[\]]*', Name.Attribute), + (r'([^(^{^")\s/[\]]+)(?=[:({"\s/\[\]])', word_callback), + (r'<[\w:.-]*>', Name.Tag), + (r'<[^(<>\s")]+', Name.Tag, 'tag'), + (r'([^(^{")\s]+)', Text), + ], + 'string': [ + (r'[^(^")]+', String), + (escape_re, String.Escape), + (r'[(|)]+', String), + (r'\^.', String.Escape), + (r'"', String, '#pop'), + ], + 'string2': [ + (r'[^(^{})]+', String), + (escape_re, String.Escape), + (r'[(|)]+', String), + (r'\^.', String.Escape), + (r'\{', String, '#push'), + (r'\}', String, '#pop'), + ], + 'stringFile': [ + (r'[^(^")]+', Name.Decorator), + (escape_re, Name.Decorator), + (r'\^.', Name.Decorator), + (r'"', Name.Decorator, '#pop'), + ], + 'char': [ + (escape_re + '"', String.Char, '#pop'), + (r'\^."', String.Char, '#pop'), + (r'."', String.Char, '#pop'), + ], + 'tag': [ + (escape_re, Name.Tag), + (r'"', Name.Tag, 'tagString'), + (r'[^(<>\r\n")]+', Name.Tag), + (r'>', Name.Tag, '#pop'), + ], + 'tagString': [ + (r'[^(^")]+', Name.Tag), + (escape_re, Name.Tag), + (r'[(|)]+', Name.Tag), + (r'\^.', Name.Tag), + (r'"', Name.Tag, '#pop'), + ], + 'tuple': [ + (r'(\d+\.)+', Keyword.Constant), + (r'\d+', Keyword.Constant, '#pop'), + ], + 'bin2': [ + (r'\s+', Number.Hex), + (r'([01]\s*){8}', Number.Hex), + (r'\}', Number.Hex, '#pop'), + ], + 'commentString1': [ + (r'[^(^")]+', Comment), + (escape_re, Comment), + (r'[(|)]+', Comment), + (r'\^.', Comment), + (r'"', Comment, '#pop'), + ], + 'commentString2': [ + (r'[^(^{})]+', Comment), + (escape_re, Comment), + (r'[(|)]+', Comment), + (r'\^.', Comment), + (r'\{', Comment, '#push'), + (r'\}', Comment, '#pop'), + ], + 'commentBlock': [ + (r'\[', Comment, '#push'), + (r'\]', Comment, '#pop'), + (r'"', Comment, "commentString1"), + (r'\{', Comment, "commentString2"), + (r'[^(\[\]"{)]+', Comment), + ], + } diff --git a/.venv/lib/python3.8/site-packages/pygments/lexers/resource.py b/.venv/lib/python3.8/site-packages/pygments/lexers/resource.py new file mode 100644 index 00000000..28dff49c --- /dev/null +++ b/.venv/lib/python3.8/site-packages/pygments/lexers/resource.py @@ -0,0 +1,85 @@ +# -*- coding: utf-8 -*- +""" + pygments.lexers.resource + ~~~~~~~~~~~~~~~~~~~~~~~~ + + Lexer for resource definition files. + + :copyright: Copyright 2006-2020 by the Pygments team, see AUTHORS. + :license: BSD, see LICENSE for details. +""" + +import re + +from pygments.lexer import RegexLexer, bygroups, words +from pygments.token import Comment, String, Number, Operator, Text, \ + Keyword, Name + +__all__ = ['ResourceLexer'] + + +class ResourceLexer(RegexLexer): + """Lexer for `ICU Resource bundles + `_. + + .. versionadded:: 2.0 + """ + name = 'ResourceBundle' + aliases = ['resource', 'resourcebundle'] + filenames = [] + + _types = (':table', ':array', ':string', ':bin', ':import', ':intvector', + ':int', ':alias') + + flags = re.MULTILINE | re.IGNORECASE + tokens = { + 'root': [ + (r'//.*?$', Comment), + (r'"', String, 'string'), + (r'-?\d+', Number.Integer), + (r'[,{}]', Operator), + (r'([^\s{:]+)(\s*)(%s?)' % '|'.join(_types), + bygroups(Name, Text, Keyword)), + (r'\s+', Text), + (words(_types), Keyword), + ], + 'string': [ + (r'(\\x[0-9a-f]{2}|\\u[0-9a-f]{4}|\\U00[0-9a-f]{6}|' + r'\\[0-7]{1,3}|\\c.|\\[abtnvfre\'"?\\]|\\\{|[^"{\\])+', String), + (r'\{', String.Escape, 'msgname'), + (r'"', String, '#pop') + ], + 'msgname': [ + (r'([^{},]+)(\s*)', bygroups(Name, String.Escape), ('#pop', 'message')) + ], + 'message': [ + (r'\{', String.Escape, 'msgname'), + (r'\}', String.Escape, '#pop'), + (r'(,)(\s*)([a-z]+)(\s*\})', + bygroups(Operator, String.Escape, Keyword, String.Escape), '#pop'), + (r'(,)(\s*)([a-z]+)(\s*)(,)(\s*)(offset)(\s*)(:)(\s*)(-?\d+)(\s*)', + bygroups(Operator, String.Escape, Keyword, String.Escape, Operator, + String.Escape, Operator.Word, String.Escape, Operator, + String.Escape, Number.Integer, String.Escape), 'choice'), + (r'(,)(\s*)([a-z]+)(\s*)(,)(\s*)', + bygroups(Operator, String.Escape, Keyword, String.Escape, Operator, + String.Escape), 'choice'), + (r'\s+', String.Escape) + ], + 'choice': [ + (r'(=|<|>|<=|>=|!=)(-?\d+)(\s*\{)', + bygroups(Operator, Number.Integer, String.Escape), 'message'), + (r'([a-z]+)(\s*\{)', bygroups(Keyword.Type, String.Escape), 'str'), + (r'\}', String.Escape, ('#pop', '#pop')), + (r'\s+', String.Escape) + ], + 'str': [ + (r'\}', String.Escape, '#pop'), + (r'\{', String.Escape, 'msgname'), + (r'[^{}]+', String) + ] + } + + def analyse_text(text): + if text.startswith('root:table'): + return 1.0 diff --git a/.venv/lib/python3.8/site-packages/pygments/lexers/ride.py b/.venv/lib/python3.8/site-packages/pygments/lexers/ride.py new file mode 100644 index 00000000..490d1e07 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/pygments/lexers/ride.py @@ -0,0 +1,139 @@ +# -*- coding: utf-8 -*- +""" + pygments.lexers.ride + ~~~~~~~~~~~~~~~~~~~~ + + Lexer for the Ride programming language. + + :copyright: Copyright 2006-2020 by the Pygments team, see AUTHORS. + :license: BSD, see LICENSE for details. +""" + +from pygments.lexer import RegexLexer, words, include +from pygments.token import Comment, Keyword, Name, Number, Punctuation, String, Text + +__all__ = ['RideLexer'] + + +class RideLexer(RegexLexer): + """ + For `Ride `_ + source code. + + .. versionadded:: 2.6 + """ + + name = 'Ride' + aliases = ['ride'] + filenames = ['*.ride'] + mimetypes = ['text/x-ride'] + + validName = r'[a-zA-Z_][a-zA-Z0-9_\']*' + + builtinOps = ( + '||', '|', '>=', '>', '==', '!', + '=', '<=', '<', '::', ':+', ':', '!=', '/', + '.', '=>', '-', '+', '*', '&&', '%', '++', + ) + + globalVariablesName = ( + 'NOALG', 'MD5', 'SHA1', 'SHA224', 'SHA256', 'SHA384', 'SHA512', + 'SHA3224', 'SHA3256', 'SHA3384', 'SHA3512', 'nil', 'this', 'unit', + 'height', 'lastBlock', 'Buy', 'Sell', 'CEILING', 'FLOOR', 'DOWN', + 'HALFDOWN', 'HALFEVEN', 'HALFUP', 'UP', + ) + + typesName = ( + 'Unit', 'Int', 'Boolean', 'ByteVector', 'String', 'Address', 'Alias', + 'Transfer', 'AssetPair', 'DataEntry', 'Order', 'Transaction', + 'GenesisTransaction', 'PaymentTransaction', 'ReissueTransaction', + 'BurnTransaction', 'MassTransferTransaction', 'ExchangeTransaction', + 'TransferTransaction', 'SetAssetScriptTransaction', + 'InvokeScriptTransaction', 'IssueTransaction', 'LeaseTransaction', + 'LeaseCancelTransaction', 'CreateAliasTransaction', + 'SetScriptTransaction', 'SponsorFeeTransaction', 'DataTransaction', + 'WriteSet', 'AttachedPayment', 'ScriptTransfer', 'TransferSet', + 'ScriptResult', 'Invocation', 'Asset', 'BlockInfo', 'Issue', 'Reissue', + 'Burn', 'NoAlg', 'Md5', 'Sha1', 'Sha224', 'Sha256', 'Sha384', 'Sha512', + 'Sha3224', 'Sha3256', 'Sha3384', 'Sha3512', 'BinaryEntry', + 'BooleanEntry', 'IntegerEntry', 'StringEntry', 'List', 'Ceiling', + 'Down', 'Floor', 'HalfDown', 'HalfEven', 'HalfUp', 'Up', + ) + + functionsName = ( + 'fraction', 'size', 'toBytes', 'take', 'drop', 'takeRight', 'dropRight', + 'toString', 'isDefined', 'extract', 'throw', 'getElement', 'value', + 'cons', 'toUtf8String', 'toInt', 'indexOf', 'lastIndexOf', 'split', + 'parseInt', 'parseIntValue', 'keccak256', 'blake2b256', 'sha256', + 'sigVerify', 'toBase58String', 'fromBase58String', 'toBase64String', + 'fromBase64String', 'transactionById', 'transactionHeightById', + 'getInteger', 'getBoolean', 'getBinary', 'getString', + 'addressFromPublicKey', 'addressFromString', 'addressFromRecipient', + 'assetBalance', 'wavesBalance', 'getIntegerValue', 'getBooleanValue', + 'getBinaryValue', 'getStringValue', 'addressFromStringValue', + 'assetInfo', 'rsaVerify', 'checkMerkleProof', 'median', + 'valueOrElse', 'valueOrErrorMessage', 'contains', 'log', 'pow', + 'toBase16String', 'fromBase16String', 'blockInfoByHeight', + 'transferTransactionById', + ) + + reservedWords = words(( + 'match', 'case', 'else', 'func', 'if', + 'let', 'then', '@Callable', '@Verifier', + ), suffix=r'\b') + + tokens = { + 'root': [ + # Comments + (r'#.*', Comment.Single), + # Whitespace + (r'\s+', Text), + # Strings + (r'"', String, 'doublequote'), + (r'utf8\'', String, 'utf8quote'), + (r'base(58|64|16)\'', String, 'singlequote'), + # Keywords + (reservedWords, Keyword.Reserved), + (r'\{-#.*?#-\}', Keyword.Reserved), + (r'FOLD<\d+>', Keyword.Reserved), + # Types + (words(typesName), Keyword.Type), + # Main + # (specialName, Keyword.Reserved), + # Prefix Operators + (words(builtinOps, prefix=r'\(', suffix=r'\)'), Name.Function), + # Infix Operators + (words(builtinOps), Name.Function), + (words(globalVariablesName), Name.Function), + (words(functionsName), Name.Function), + # Numbers + include('numbers'), + # Variable Names + (validName, Name.Variable), + # Parens + (r'[,()\[\]{}]', Punctuation), + ], + + 'doublequote': [ + (r'\\u[0-9a-fA-F]{4}', String.Escape), + (r'\\[nrfvb\\"]', String.Escape), + (r'[^"]', String), + (r'"', String, '#pop'), + ], + + 'utf8quote': [ + (r'\\u[0-9a-fA-F]{4}', String.Escape), + (r'\\[nrfvb\\\']', String.Escape), + (r'[^\']', String), + (r'\'', String, '#pop'), + ], + + 'singlequote': [ + (r'[^\']', String), + (r'\'', String, '#pop'), + ], + + 'numbers': [ + (r'_?\d+', Number.Integer), + ], + } diff --git a/.venv/lib/python3.8/site-packages/pygments/lexers/rnc.py b/.venv/lib/python3.8/site-packages/pygments/lexers/rnc.py new file mode 100644 index 00000000..9fb8ab52 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/pygments/lexers/rnc.py @@ -0,0 +1,67 @@ +# -*- coding: utf-8 -*- +""" + pygments.lexers.rnc + ~~~~~~~~~~~~~~~~~~~ + + Lexer for Relax-NG Compact syntax + + :copyright: Copyright 2006-2020 by the Pygments team, see AUTHORS. + :license: BSD, see LICENSE for details. +""" + +from pygments.lexer import RegexLexer +from pygments.token import Text, Comment, Operator, Keyword, Name, String, \ + Punctuation + +__all__ = ['RNCCompactLexer'] + + +class RNCCompactLexer(RegexLexer): + """ + For `RelaxNG-compact `_ syntax. + + .. versionadded:: 2.2 + """ + + name = 'Relax-NG Compact' + aliases = ['rnc', 'rng-compact'] + filenames = ['*.rnc'] + + tokens = { + 'root': [ + (r'namespace\b', Keyword.Namespace), + (r'(?:default|datatypes)\b', Keyword.Declaration), + (r'##.*$', Comment.Preproc), + (r'#.*$', Comment.Single), + (r'"[^"]*"', String.Double), + # TODO single quoted strings and escape sequences outside of + # double-quoted strings + (r'(?:element|attribute|mixed)\b', Keyword.Declaration, 'variable'), + (r'(text\b|xsd:[^ ]+)', Keyword.Type, 'maybe_xsdattributes'), + (r'[,?&*=|~]|>>', Operator), + (r'[(){}]', Punctuation), + (r'.', Text), + ], + + # a variable has been declared using `element` or `attribute` + 'variable': [ + (r'[^{]+', Name.Variable), + (r'\{', Punctuation, '#pop'), + ], + + # after an xsd: declaration there may be attributes + 'maybe_xsdattributes': [ + (r'\{', Punctuation, 'xsdattributes'), + (r'\}', Punctuation, '#pop'), + (r'.', Text), + ], + + # attributes take the form { key1 = value1 key2 = value2 ... } + 'xsdattributes': [ + (r'[^ =}]', Name.Attribute), + (r'=', Operator), + (r'"[^"]*"', String.Double), + (r'\}', Punctuation, '#pop'), + (r'.', Text), + ], + } diff --git a/.venv/lib/python3.8/site-packages/pygments/lexers/roboconf.py b/.venv/lib/python3.8/site-packages/pygments/lexers/roboconf.py new file mode 100644 index 00000000..2419ee51 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/pygments/lexers/roboconf.py @@ -0,0 +1,82 @@ +# -*- coding: utf-8 -*- +""" + pygments.lexers.roboconf + ~~~~~~~~~~~~~~~~~~~~~~~~ + + Lexers for Roboconf DSL. + + :copyright: Copyright 2006-2020 by the Pygments team, see AUTHORS. + :license: BSD, see LICENSE for details. +""" + +from pygments.lexer import RegexLexer, words, re +from pygments.token import Text, Operator, Keyword, Name, Comment + +__all__ = ['RoboconfGraphLexer', 'RoboconfInstancesLexer'] + + +class RoboconfGraphLexer(RegexLexer): + """ + Lexer for `Roboconf `_ graph files. + + .. versionadded:: 2.1 + """ + name = 'Roboconf Graph' + aliases = ['roboconf-graph'] + filenames = ['*.graph'] + + flags = re.IGNORECASE | re.MULTILINE + tokens = { + 'root': [ + # Skip white spaces + (r'\s+', Text), + + # There is one operator + (r'=', Operator), + + # Keywords + (words(('facet', 'import'), suffix=r'\s*\b', prefix=r'\b'), Keyword), + (words(( + 'installer', 'extends', 'exports', 'imports', 'facets', + 'children'), suffix=r'\s*:?', prefix=r'\b'), Name), + + # Comments + (r'#.*\n', Comment), + + # Default + (r'[^#]', Text), + (r'.*\n', Text) + ] + } + + +class RoboconfInstancesLexer(RegexLexer): + """ + Lexer for `Roboconf `_ instances files. + + .. versionadded:: 2.1 + """ + name = 'Roboconf Instances' + aliases = ['roboconf-instances'] + filenames = ['*.instances'] + + flags = re.IGNORECASE | re.MULTILINE + tokens = { + 'root': [ + + # Skip white spaces + (r'\s+', Text), + + # Keywords + (words(('instance of', 'import'), suffix=r'\s*\b', prefix=r'\b'), Keyword), + (words(('name', 'count'), suffix=r's*:?', prefix=r'\b'), Name), + (r'\s*[\w.-]+\s*:', Name), + + # Comments + (r'#.*\n', Comment), + + # Default + (r'[^#]', Text), + (r'.*\n', Text) + ] + } diff --git a/.venv/lib/python3.8/site-packages/pygments/lexers/robotframework.py b/.venv/lib/python3.8/site-packages/pygments/lexers/robotframework.py new file mode 100644 index 00000000..cd808292 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/pygments/lexers/robotframework.py @@ -0,0 +1,552 @@ +# -*- coding: utf-8 -*- +""" + pygments.lexers.robotframework + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + Lexer for Robot Framework. + + :copyright: Copyright 2006-2020 by the Pygments team, see AUTHORS. + :license: BSD, see LICENSE for details. +""" + +# Copyright 2012 Nokia Siemens Networks Oyj +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import re + +from pygments.lexer import Lexer +from pygments.token import Token + +__all__ = ['RobotFrameworkLexer'] + + +HEADING = Token.Generic.Heading +SETTING = Token.Keyword.Namespace +IMPORT = Token.Name.Namespace +TC_KW_NAME = Token.Generic.Subheading +KEYWORD = Token.Name.Function +ARGUMENT = Token.String +VARIABLE = Token.Name.Variable +COMMENT = Token.Comment +SEPARATOR = Token.Punctuation +SYNTAX = Token.Punctuation +GHERKIN = Token.Generic.Emph +ERROR = Token.Error + + +def normalize(string, remove=''): + string = string.lower() + for char in remove + ' ': + if char in string: + string = string.replace(char, '') + return string + + +class RobotFrameworkLexer(Lexer): + """ + For `Robot Framework `_ test data. + + Supports both space and pipe separated plain text formats. + + .. versionadded:: 1.6 + """ + name = 'RobotFramework' + aliases = ['robotframework'] + filenames = ['*.robot'] + mimetypes = ['text/x-robotframework'] + + def __init__(self, **options): + options['tabsize'] = 2 + options['encoding'] = 'UTF-8' + Lexer.__init__(self, **options) + + def get_tokens_unprocessed(self, text): + row_tokenizer = RowTokenizer() + var_tokenizer = VariableTokenizer() + index = 0 + for row in text.splitlines(): + for value, token in row_tokenizer.tokenize(row): + for value, token in var_tokenizer.tokenize(value, token): + if value: + yield index, token, str(value) + index += len(value) + + +class VariableTokenizer: + + def tokenize(self, string, token): + var = VariableSplitter(string, identifiers='$@%&') + if var.start < 0 or token in (COMMENT, ERROR): + yield string, token + return + for value, token in self._tokenize(var, string, token): + if value: + yield value, token + + def _tokenize(self, var, string, orig_token): + before = string[:var.start] + yield before, orig_token + yield var.identifier + '{', SYNTAX + yield from self.tokenize(var.base, VARIABLE) + yield '}', SYNTAX + if var.index: + yield '[', SYNTAX + yield from self.tokenize(var.index, VARIABLE) + yield ']', SYNTAX + yield from self.tokenize(string[var.end:], orig_token) + + +class RowTokenizer: + + def __init__(self): + self._table = UnknownTable() + self._splitter = RowSplitter() + testcases = TestCaseTable() + settings = SettingTable(testcases.set_default_template) + variables = VariableTable() + keywords = KeywordTable() + self._tables = {'settings': settings, 'setting': settings, + 'metadata': settings, + 'variables': variables, 'variable': variables, + 'testcases': testcases, 'testcase': testcases, + 'tasks': testcases, 'task': testcases, + 'keywords': keywords, 'keyword': keywords, + 'userkeywords': keywords, 'userkeyword': keywords} + + def tokenize(self, row): + commented = False + heading = False + for index, value in enumerate(self._splitter.split(row)): + # First value, and every second after that, is a separator. + index, separator = divmod(index-1, 2) + if value.startswith('#'): + commented = True + elif index == 0 and value.startswith('*'): + self._table = self._start_table(value) + heading = True + yield from self._tokenize(value, index, commented, + separator, heading) + self._table.end_row() + + def _start_table(self, header): + name = normalize(header, remove='*') + return self._tables.get(name, UnknownTable()) + + def _tokenize(self, value, index, commented, separator, heading): + if commented: + yield value, COMMENT + elif separator: + yield value, SEPARATOR + elif heading: + yield value, HEADING + else: + yield from self._table.tokenize(value, index) + + +class RowSplitter: + _space_splitter = re.compile('( {2,})') + _pipe_splitter = re.compile(r'((?:^| +)\|(?: +|$))') + + def split(self, row): + splitter = (row.startswith('| ') and self._split_from_pipes + or self._split_from_spaces) + yield from splitter(row) + yield '\n' + + def _split_from_spaces(self, row): + yield '' # Start with (pseudo)separator similarly as with pipes + yield from self._space_splitter.split(row) + + def _split_from_pipes(self, row): + _, separator, rest = self._pipe_splitter.split(row, 1) + yield separator + while self._pipe_splitter.search(rest): + cell, separator, rest = self._pipe_splitter.split(rest, 1) + yield cell + yield separator + yield rest + + +class Tokenizer: + _tokens = None + + def __init__(self): + self._index = 0 + + def tokenize(self, value): + values_and_tokens = self._tokenize(value, self._index) + self._index += 1 + if isinstance(values_and_tokens, type(Token)): + values_and_tokens = [(value, values_and_tokens)] + return values_and_tokens + + def _tokenize(self, value, index): + index = min(index, len(self._tokens) - 1) + return self._tokens[index] + + def _is_assign(self, value): + if value.endswith('='): + value = value[:-1].strip() + var = VariableSplitter(value, identifiers='$@&') + return var.start == 0 and var.end == len(value) + + +class Comment(Tokenizer): + _tokens = (COMMENT,) + + +class Setting(Tokenizer): + _tokens = (SETTING, ARGUMENT) + _keyword_settings = ('suitesetup', 'suiteprecondition', 'suiteteardown', + 'suitepostcondition', 'testsetup', 'tasksetup', 'testprecondition', + 'testteardown','taskteardown', 'testpostcondition', 'testtemplate', 'tasktemplate') + _import_settings = ('library', 'resource', 'variables') + _other_settings = ('documentation', 'metadata', 'forcetags', 'defaulttags', + 'testtimeout','tasktimeout') + _custom_tokenizer = None + + def __init__(self, template_setter=None): + Tokenizer.__init__(self) + self._template_setter = template_setter + + def _tokenize(self, value, index): + if index == 1 and self._template_setter: + self._template_setter(value) + if index == 0: + normalized = normalize(value) + if normalized in self._keyword_settings: + self._custom_tokenizer = KeywordCall(support_assign=False) + elif normalized in self._import_settings: + self._custom_tokenizer = ImportSetting() + elif normalized not in self._other_settings: + return ERROR + elif self._custom_tokenizer: + return self._custom_tokenizer.tokenize(value) + return Tokenizer._tokenize(self, value, index) + + +class ImportSetting(Tokenizer): + _tokens = (IMPORT, ARGUMENT) + + +class TestCaseSetting(Setting): + _keyword_settings = ('setup', 'precondition', 'teardown', 'postcondition', + 'template') + _import_settings = () + _other_settings = ('documentation', 'tags', 'timeout') + + def _tokenize(self, value, index): + if index == 0: + type = Setting._tokenize(self, value[1:-1], index) + return [('[', SYNTAX), (value[1:-1], type), (']', SYNTAX)] + return Setting._tokenize(self, value, index) + + +class KeywordSetting(TestCaseSetting): + _keyword_settings = ('teardown',) + _other_settings = ('documentation', 'arguments', 'return', 'timeout', 'tags') + + +class Variable(Tokenizer): + _tokens = (SYNTAX, ARGUMENT) + + def _tokenize(self, value, index): + if index == 0 and not self._is_assign(value): + return ERROR + return Tokenizer._tokenize(self, value, index) + + +class KeywordCall(Tokenizer): + _tokens = (KEYWORD, ARGUMENT) + + def __init__(self, support_assign=True): + Tokenizer.__init__(self) + self._keyword_found = not support_assign + self._assigns = 0 + + def _tokenize(self, value, index): + if not self._keyword_found and self._is_assign(value): + self._assigns += 1 + return SYNTAX # VariableTokenizer tokenizes this later. + if self._keyword_found: + return Tokenizer._tokenize(self, value, index - self._assigns) + self._keyword_found = True + return GherkinTokenizer().tokenize(value, KEYWORD) + + +class GherkinTokenizer: + _gherkin_prefix = re.compile('^(Given|When|Then|And) ', re.IGNORECASE) + + def tokenize(self, value, token): + match = self._gherkin_prefix.match(value) + if not match: + return [(value, token)] + end = match.end() + return [(value[:end], GHERKIN), (value[end:], token)] + + +class TemplatedKeywordCall(Tokenizer): + _tokens = (ARGUMENT,) + + +class ForLoop(Tokenizer): + + def __init__(self): + Tokenizer.__init__(self) + self._in_arguments = False + + def _tokenize(self, value, index): + token = self._in_arguments and ARGUMENT or SYNTAX + if value.upper() in ('IN', 'IN RANGE'): + self._in_arguments = True + return token + + +class _Table: + _tokenizer_class = None + + def __init__(self, prev_tokenizer=None): + self._tokenizer = self._tokenizer_class() + self._prev_tokenizer = prev_tokenizer + self._prev_values_on_row = [] + + def tokenize(self, value, index): + if self._continues(value, index): + self._tokenizer = self._prev_tokenizer + yield value, SYNTAX + else: + yield from self._tokenize(value, index) + self._prev_values_on_row.append(value) + + def _continues(self, value, index): + return value == '...' and all(self._is_empty(t) + for t in self._prev_values_on_row) + + def _is_empty(self, value): + return value in ('', '\\') + + def _tokenize(self, value, index): + return self._tokenizer.tokenize(value) + + def end_row(self): + self.__init__(prev_tokenizer=self._tokenizer) + + +class UnknownTable(_Table): + _tokenizer_class = Comment + + def _continues(self, value, index): + return False + + +class VariableTable(_Table): + _tokenizer_class = Variable + + +class SettingTable(_Table): + _tokenizer_class = Setting + + def __init__(self, template_setter, prev_tokenizer=None): + _Table.__init__(self, prev_tokenizer) + self._template_setter = template_setter + + def _tokenize(self, value, index): + if index == 0 and normalize(value) == 'testtemplate': + self._tokenizer = Setting(self._template_setter) + return _Table._tokenize(self, value, index) + + def end_row(self): + self.__init__(self._template_setter, prev_tokenizer=self._tokenizer) + + +class TestCaseTable(_Table): + _setting_class = TestCaseSetting + _test_template = None + _default_template = None + + @property + def _tokenizer_class(self): + if self._test_template or (self._default_template and + self._test_template is not False): + return TemplatedKeywordCall + return KeywordCall + + def _continues(self, value, index): + return index > 0 and _Table._continues(self, value, index) + + def _tokenize(self, value, index): + if index == 0: + if value: + self._test_template = None + return GherkinTokenizer().tokenize(value, TC_KW_NAME) + if index == 1 and self._is_setting(value): + if self._is_template(value): + self._test_template = False + self._tokenizer = self._setting_class(self.set_test_template) + else: + self._tokenizer = self._setting_class() + if index == 1 and self._is_for_loop(value): + self._tokenizer = ForLoop() + if index == 1 and self._is_empty(value): + return [(value, SYNTAX)] + return _Table._tokenize(self, value, index) + + def _is_setting(self, value): + return value.startswith('[') and value.endswith(']') + + def _is_template(self, value): + return normalize(value) == '[template]' + + def _is_for_loop(self, value): + return value.startswith(':') and normalize(value, remove=':') == 'for' + + def set_test_template(self, template): + self._test_template = self._is_template_set(template) + + def set_default_template(self, template): + self._default_template = self._is_template_set(template) + + def _is_template_set(self, template): + return normalize(template) not in ('', '\\', 'none', '${empty}') + + +class KeywordTable(TestCaseTable): + _tokenizer_class = KeywordCall + _setting_class = KeywordSetting + + def _is_template(self, value): + return False + + +# Following code copied directly from Robot Framework 2.7.5. + +class VariableSplitter: + + def __init__(self, string, identifiers): + self.identifier = None + self.base = None + self.index = None + self.start = -1 + self.end = -1 + self._identifiers = identifiers + self._may_have_internal_variables = False + try: + self._split(string) + except ValueError: + pass + else: + self._finalize() + + def get_replaced_base(self, variables): + if self._may_have_internal_variables: + return variables.replace_string(self.base) + return self.base + + def _finalize(self): + self.identifier = self._variable_chars[0] + self.base = ''.join(self._variable_chars[2:-1]) + self.end = self.start + len(self._variable_chars) + if self._has_list_or_dict_variable_index(): + self.index = ''.join(self._list_and_dict_variable_index_chars[1:-1]) + self.end += len(self._list_and_dict_variable_index_chars) + + def _has_list_or_dict_variable_index(self): + return self._list_and_dict_variable_index_chars\ + and self._list_and_dict_variable_index_chars[-1] == ']' + + def _split(self, string): + start_index, max_index = self._find_variable(string) + self.start = start_index + self._open_curly = 1 + self._state = self._variable_state + self._variable_chars = [string[start_index], '{'] + self._list_and_dict_variable_index_chars = [] + self._string = string + start_index += 2 + for index, char in enumerate(string[start_index:]): + index += start_index # Giving start to enumerate only in Py 2.6+ + try: + self._state(char, index) + except StopIteration: + return + if index == max_index and not self._scanning_list_variable_index(): + return + + def _scanning_list_variable_index(self): + return self._state in [self._waiting_list_variable_index_state, + self._list_variable_index_state] + + def _find_variable(self, string): + max_end_index = string.rfind('}') + if max_end_index == -1: + raise ValueError('No variable end found') + if self._is_escaped(string, max_end_index): + return self._find_variable(string[:max_end_index]) + start_index = self._find_start_index(string, 1, max_end_index) + if start_index == -1: + raise ValueError('No variable start found') + return start_index, max_end_index + + def _find_start_index(self, string, start, end): + index = string.find('{', start, end) - 1 + if index < 0: + return -1 + if self._start_index_is_ok(string, index): + return index + return self._find_start_index(string, index+2, end) + + def _start_index_is_ok(self, string, index): + return string[index] in self._identifiers\ + and not self._is_escaped(string, index) + + def _is_escaped(self, string, index): + escaped = False + while index > 0 and string[index-1] == '\\': + index -= 1 + escaped = not escaped + return escaped + + def _variable_state(self, char, index): + self._variable_chars.append(char) + if char == '}' and not self._is_escaped(self._string, index): + self._open_curly -= 1 + if self._open_curly == 0: + if not self._is_list_or_dict_variable(): + raise StopIteration + self._state = self._waiting_list_variable_index_state + elif char in self._identifiers: + self._state = self._internal_variable_start_state + + def _is_list_or_dict_variable(self): + return self._variable_chars[0] in ('@','&') + + def _internal_variable_start_state(self, char, index): + self._state = self._variable_state + if char == '{': + self._variable_chars.append(char) + self._open_curly += 1 + self._may_have_internal_variables = True + else: + self._variable_state(char, index) + + def _waiting_list_variable_index_state(self, char, index): + if char != '[': + raise StopIteration + self._list_and_dict_variable_index_chars.append(char) + self._state = self._list_variable_index_state + + def _list_variable_index_state(self, char, index): + self._list_and_dict_variable_index_chars.append(char) + if char == ']': + raise StopIteration diff --git a/.venv/lib/python3.8/site-packages/pygments/lexers/ruby.py b/.venv/lib/python3.8/site-packages/pygments/lexers/ruby.py new file mode 100644 index 00000000..e16cd711 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/pygments/lexers/ruby.py @@ -0,0 +1,517 @@ +# -*- coding: utf-8 -*- +""" + pygments.lexers.ruby + ~~~~~~~~~~~~~~~~~~~~ + + Lexers for Ruby and related languages. + + :copyright: Copyright 2006-2020 by the Pygments team, see AUTHORS. + :license: BSD, see LICENSE for details. +""" + +import re + +from pygments.lexer import Lexer, RegexLexer, ExtendedRegexLexer, include, \ + bygroups, default, LexerContext, do_insertions, words +from pygments.token import Text, Comment, Operator, Keyword, Name, String, \ + Number, Punctuation, Error, Generic +from pygments.util import shebang_matches + +__all__ = ['RubyLexer', 'RubyConsoleLexer', 'FancyLexer'] + +line_re = re.compile('.*?\n') + + +RUBY_OPERATORS = ( + '*', '**', '-', '+', '-@', '+@', '/', '%', '&', '|', '^', '`', '~', + '[]', '[]=', '<<', '>>', '<', '<>', '<=>', '>', '>=', '==', '===' +) + + +class RubyLexer(ExtendedRegexLexer): + """ + For `Ruby `_ source code. + """ + + name = 'Ruby' + aliases = ['rb', 'ruby', 'duby'] + filenames = ['*.rb', '*.rbw', 'Rakefile', '*.rake', '*.gemspec', + '*.rbx', '*.duby', 'Gemfile'] + mimetypes = ['text/x-ruby', 'application/x-ruby'] + + flags = re.DOTALL | re.MULTILINE + + def heredoc_callback(self, match, ctx): + # okay, this is the hardest part of parsing Ruby... + # match: 1 = <<[-~]?, 2 = quote? 3 = name 4 = quote? 5 = rest of line + + start = match.start(1) + yield start, Operator, match.group(1) # <<[-~]? + yield match.start(2), String.Heredoc, match.group(2) # quote ", ', ` + yield match.start(3), String.Delimiter, match.group(3) # heredoc name + yield match.start(4), String.Heredoc, match.group(4) # quote again + + heredocstack = ctx.__dict__.setdefault('heredocstack', []) + outermost = not bool(heredocstack) + heredocstack.append((match.group(1) in ('<<-', '<<~'), match.group(3))) + + ctx.pos = match.start(5) + ctx.end = match.end(5) + # this may find other heredocs + yield from self.get_tokens_unprocessed(context=ctx) + ctx.pos = match.end() + + if outermost: + # this is the outer heredoc again, now we can process them all + for tolerant, hdname in heredocstack: + lines = [] + for match in line_re.finditer(ctx.text, ctx.pos): + if tolerant: + check = match.group().strip() + else: + check = match.group().rstrip() + if check == hdname: + for amatch in lines: + yield amatch.start(), String.Heredoc, amatch.group() + yield match.start(), String.Delimiter, match.group() + ctx.pos = match.end() + break + else: + lines.append(match) + else: + # end of heredoc not found -- error! + for amatch in lines: + yield amatch.start(), Error, amatch.group() + ctx.end = len(ctx.text) + del heredocstack[:] + + def gen_rubystrings_rules(): + def intp_regex_callback(self, match, ctx): + yield match.start(1), String.Regex, match.group(1) # begin + nctx = LexerContext(match.group(3), 0, ['interpolated-regex']) + for i, t, v in self.get_tokens_unprocessed(context=nctx): + yield match.start(3)+i, t, v + yield match.start(4), String.Regex, match.group(4) # end[mixounse]* + ctx.pos = match.end() + + def intp_string_callback(self, match, ctx): + yield match.start(1), String.Other, match.group(1) + nctx = LexerContext(match.group(3), 0, ['interpolated-string']) + for i, t, v in self.get_tokens_unprocessed(context=nctx): + yield match.start(3)+i, t, v + yield match.start(4), String.Other, match.group(4) # end + ctx.pos = match.end() + + states = {} + states['strings'] = [ + # easy ones + (r'\:@{0,2}[a-zA-Z_]\w*[!?]?', String.Symbol), + (words(RUBY_OPERATORS, prefix=r'\:@{0,2}'), String.Symbol), + (r":'(\\\\|\\'|[^'])*'", String.Symbol), + (r':"', String.Symbol, 'simple-sym'), + (r'([a-zA-Z_]\w*)(:)(?!:)', + bygroups(String.Symbol, Punctuation)), # Since Ruby 1.9 + (r'"', String.Double, 'simple-string-double'), + (r"'", String.Single, 'simple-string-single'), + (r'(?', '<>', 'ab'): + states[name+'-intp-string'] = [ + (r'\\[\\' + bracecc + ']', String.Other), + (lbrace, String.Other, '#push'), + (rbrace, String.Other, '#pop'), + include('string-intp-escaped'), + (r'[\\#' + bracecc + ']', String.Other), + (r'[^\\#' + bracecc + ']+', String.Other), + ] + states['strings'].append((r'%[QWx]?' + lbrace, String.Other, + name+'-intp-string')) + states[name+'-string'] = [ + (r'\\[\\' + bracecc + ']', String.Other), + (lbrace, String.Other, '#push'), + (rbrace, String.Other, '#pop'), + (r'[\\#' + bracecc + ']', String.Other), + (r'[^\\#' + bracecc + ']+', String.Other), + ] + states['strings'].append((r'%[qsw]' + lbrace, String.Other, + name+'-string')) + states[name+'-regex'] = [ + (r'\\[\\' + bracecc + ']', String.Regex), + (lbrace, String.Regex, '#push'), + (rbrace + '[mixounse]*', String.Regex, '#pop'), + include('string-intp'), + (r'[\\#' + bracecc + ']', String.Regex), + (r'[^\\#' + bracecc + ']+', String.Regex), + ] + states['strings'].append((r'%r' + lbrace, String.Regex, + name+'-regex')) + + # these must come after %! + states['strings'] += [ + # %r regex + (r'(%r([\W_]))((?:\\\2|(?!\2).)*)(\2[mixounse]*)', + intp_regex_callback), + # regular fancy strings with qsw + (r'%[qsw]([\W_])((?:\\\1|(?!\1).)*)\1', String.Other), + (r'(%[QWx]([\W_]))((?:\\\2|(?!\2).)*)(\2)', + intp_string_callback), + # special forms of fancy strings after operators or + # in method calls with braces + (r'(?<=[-+/*%=<>&!^|~,(])(\s*)(%([\t ])(?:(?:\\\3|(?!\3).)*)\3)', + bygroups(Text, String.Other, None)), + # and because of fixed width lookbehinds the whole thing a + # second time for line startings... + (r'^(\s*)(%([\t ])(?:(?:\\\3|(?!\3).)*)\3)', + bygroups(Text, String.Other, None)), + # all regular fancy strings without qsw + (r'(%([^a-zA-Z0-9\s]))((?:\\\2|(?!\2).)*)(\2)', + intp_string_callback), + ] + + return states + + tokens = { + 'root': [ + (r'\A#!.+?$', Comment.Hashbang), + (r'#.*?$', Comment.Single), + (r'=begin\s.*?\n=end.*?$', Comment.Multiline), + # keywords + (words(( + 'BEGIN', 'END', 'alias', 'begin', 'break', 'case', 'defined?', + 'do', 'else', 'elsif', 'end', 'ensure', 'for', 'if', 'in', 'next', 'redo', + 'rescue', 'raise', 'retry', 'return', 'super', 'then', 'undef', + 'unless', 'until', 'when', 'while', 'yield'), suffix=r'\b'), + Keyword), + # start of function, class and module names + (r'(module)(\s+)([a-zA-Z_]\w*' + r'(?:::[a-zA-Z_]\w*)*)', + bygroups(Keyword, Text, Name.Namespace)), + (r'(def)(\s+)', bygroups(Keyword, Text), 'funcname'), + (r'def(?=[*%&^`~+-/\[<>=])', Keyword, 'funcname'), + (r'(class)(\s+)', bygroups(Keyword, Text), 'classname'), + # special methods + (words(( + 'initialize', 'new', 'loop', 'include', 'extend', 'raise', 'attr_reader', + 'attr_writer', 'attr_accessor', 'attr', 'catch', 'throw', 'private', + 'module_function', 'public', 'protected', 'true', 'false', 'nil'), + suffix=r'\b'), + Keyword.Pseudo), + (r'(not|and|or)\b', Operator.Word), + (words(( + 'autoload', 'block_given', 'const_defined', 'eql', 'equal', 'frozen', 'include', + 'instance_of', 'is_a', 'iterator', 'kind_of', 'method_defined', 'nil', + 'private_method_defined', 'protected_method_defined', + 'public_method_defined', 'respond_to', 'tainted'), suffix=r'\?'), + Name.Builtin), + (r'(chomp|chop|exit|gsub|sub)!', Name.Builtin), + (words(( + 'Array', 'Float', 'Integer', 'String', '__id__', '__send__', 'abort', + 'ancestors', 'at_exit', 'autoload', 'binding', 'callcc', 'caller', + 'catch', 'chomp', 'chop', 'class_eval', 'class_variables', + 'clone', 'const_defined?', 'const_get', 'const_missing', 'const_set', + 'constants', 'display', 'dup', 'eval', 'exec', 'exit', 'extend', 'fail', 'fork', + 'format', 'freeze', 'getc', 'gets', 'global_variables', 'gsub', + 'hash', 'id', 'included_modules', 'inspect', 'instance_eval', + 'instance_method', 'instance_methods', + 'instance_variable_get', 'instance_variable_set', 'instance_variables', + 'lambda', 'load', 'local_variables', 'loop', + 'method', 'method_missing', 'methods', 'module_eval', 'name', + 'object_id', 'open', 'p', 'print', 'printf', 'private_class_method', + 'private_instance_methods', + 'private_methods', 'proc', 'protected_instance_methods', + 'protected_methods', 'public_class_method', + 'public_instance_methods', 'public_methods', + 'putc', 'puts', 'raise', 'rand', 'readline', 'readlines', 'require', + 'scan', 'select', 'self', 'send', 'set_trace_func', 'singleton_methods', 'sleep', + 'split', 'sprintf', 'srand', 'sub', 'syscall', 'system', 'taint', + 'test', 'throw', 'to_a', 'to_s', 'trace_var', 'trap', 'untaint', + 'untrace_var', 'warn'), prefix=r'(?~!:])|' + r'(?<=(?:\s|;)when\s)|' + r'(?<=(?:\s|;)or\s)|' + r'(?<=(?:\s|;)and\s)|' + r'(?<=\.index\s)|' + r'(?<=\.scan\s)|' + r'(?<=\.sub\s)|' + r'(?<=\.sub!\s)|' + r'(?<=\.gsub\s)|' + r'(?<=\.gsub!\s)|' + r'(?<=\.match\s)|' + r'(?<=(?:\s|;)if\s)|' + r'(?<=(?:\s|;)elsif\s)|' + r'(?<=^when\s)|' + r'(?<=^index\s)|' + r'(?<=^scan\s)|' + r'(?<=^sub\s)|' + r'(?<=^gsub\s)|' + r'(?<=^sub!\s)|' + r'(?<=^gsub!\s)|' + r'(?<=^match\s)|' + r'(?<=^if\s)|' + r'(?<=^elsif\s)' + r')(\s*)(/)', bygroups(Text, String.Regex), 'multiline-regex'), + # multiline regex (in method calls or subscripts) + (r'(?<=\(|,|\[)/', String.Regex, 'multiline-regex'), + # multiline regex (this time the funny no whitespace rule) + (r'(\s+)(/)(?![\s=])', bygroups(Text, String.Regex), + 'multiline-regex'), + # lex numbers and ignore following regular expressions which + # are division operators in fact (grrrr. i hate that. any + # better ideas?) + # since pygments 0.7 we also eat a "?" operator after numbers + # so that the char operator does not work. Chars are not allowed + # there so that you can use the ternary operator. + # stupid example: + # x>=0?n[x]:"" + (r'(0_?[0-7]+(?:_[0-7]+)*)(\s*)([/?])?', + bygroups(Number.Oct, Text, Operator)), + (r'(0x[0-9A-Fa-f]+(?:_[0-9A-Fa-f]+)*)(\s*)([/?])?', + bygroups(Number.Hex, Text, Operator)), + (r'(0b[01]+(?:_[01]+)*)(\s*)([/?])?', + bygroups(Number.Bin, Text, Operator)), + (r'([\d]+(?:_\d+)*)(\s*)([/?])?', + bygroups(Number.Integer, Text, Operator)), + # Names + (r'@@[a-zA-Z_]\w*', Name.Variable.Class), + (r'@[a-zA-Z_]\w*', Name.Variable.Instance), + (r'\$\w+', Name.Variable.Global), + (r'\$[!@&`\'+~=/\\,;.<>_*$?:"^-]', Name.Variable.Global), + (r'\$-[0adFiIlpvw]', Name.Variable.Global), + (r'::', Operator), + include('strings'), + # chars + (r'\?(\\[MC]-)*' # modifiers + r'(\\([\\abefnrstv#"\']|x[a-fA-F0-9]{1,2}|[0-7]{1,3})|\S)' + r'(?!\w)', + String.Char), + (r'[A-Z]\w+', Name.Constant), + # this is needed because ruby attributes can look + # like keywords (class) or like this: ` ?!? + (words(RUBY_OPERATORS, prefix=r'(\.|::)'), + bygroups(Operator, Name.Operator)), + (r'(\.|::)([a-zA-Z_]\w*[!?]?|[*%&^`~+\-/\[<>=])', + bygroups(Operator, Name)), + (r'[a-zA-Z_]\w*[!?]?', Name), + (r'(\[|\]|\*\*|<>?|>=|<=|<=>|=~|={3}|' + r'!~|&&?|\|\||\.{1,3})', Operator), + (r'[-+/*%=<>&!^|~]=?', Operator), + (r'[(){};,/?:\\]', Punctuation), + (r'\s+', Text) + ], + 'funcname': [ + (r'\(', Punctuation, 'defexpr'), + (r'(?:([a-zA-Z_]\w*)(\.))?' + r'([a-zA-Z_]\w*[!?]?|\*\*?|[-+]@?|' + r'[/%&|^`~]|\[\]=?|<<|>>|<=?>|>=?|===?)', + bygroups(Name.Class, Operator, Name.Function), '#pop'), + default('#pop') + ], + 'classname': [ + (r'\(', Punctuation, 'defexpr'), + (r'<<', Operator, '#pop'), + (r'[A-Z_]\w*', Name.Class, '#pop'), + default('#pop') + ], + 'defexpr': [ + (r'(\))(\.|::)?', bygroups(Punctuation, Operator), '#pop'), + (r'\(', Operator, '#push'), + include('root') + ], + 'in-intp': [ + (r'\{', String.Interpol, '#push'), + (r'\}', String.Interpol, '#pop'), + include('root'), + ], + 'string-intp': [ + (r'#\{', String.Interpol, 'in-intp'), + (r'#@@?[a-zA-Z_]\w*', String.Interpol), + (r'#\$[a-zA-Z_]\w*', String.Interpol) + ], + 'string-intp-escaped': [ + include('string-intp'), + (r'\\([\\abefnrstv#"\']|x[a-fA-F0-9]{1,2}|[0-7]{1,3})', + String.Escape) + ], + 'interpolated-regex': [ + include('string-intp'), + (r'[\\#]', String.Regex), + (r'[^\\#]+', String.Regex), + ], + 'interpolated-string': [ + include('string-intp'), + (r'[\\#]', String.Other), + (r'[^\\#]+', String.Other), + ], + 'multiline-regex': [ + include('string-intp'), + (r'\\\\', String.Regex), + (r'\\/', String.Regex), + (r'[\\#]', String.Regex), + (r'[^\\/#]+', String.Regex), + (r'/[mixounse]*', String.Regex, '#pop'), + ], + 'end-part': [ + (r'.+', Comment.Preproc, '#pop') + ] + } + tokens.update(gen_rubystrings_rules()) + + def analyse_text(text): + return shebang_matches(text, r'ruby(1\.\d)?') + + +class RubyConsoleLexer(Lexer): + """ + For Ruby interactive console (**irb**) output like: + + .. sourcecode:: rbcon + + irb(main):001:0> a = 1 + => 1 + irb(main):002:0> puts a + 1 + => nil + """ + name = 'Ruby irb session' + aliases = ['rbcon', 'irb'] + mimetypes = ['text/x-ruby-shellsession'] + + _prompt_re = re.compile(r'irb\([a-zA-Z_]\w*\):\d{3}:\d+[>*"\'] ' + r'|>> |\?> ') + + def get_tokens_unprocessed(self, text): + rblexer = RubyLexer(**self.options) + + curcode = '' + insertions = [] + for match in line_re.finditer(text): + line = match.group() + m = self._prompt_re.match(line) + if m is not None: + end = m.end() + insertions.append((len(curcode), + [(0, Generic.Prompt, line[:end])])) + curcode += line[end:] + else: + if curcode: + yield from do_insertions( + insertions, rblexer.get_tokens_unprocessed(curcode)) + curcode = '' + insertions = [] + yield match.start(), Generic.Output, line + if curcode: + yield from do_insertions( + insertions, rblexer.get_tokens_unprocessed(curcode)) + + +class FancyLexer(RegexLexer): + """ + Pygments Lexer For `Fancy `_. + + Fancy is a self-hosted, pure object-oriented, dynamic, + class-based, concurrent general-purpose programming language + running on Rubinius, the Ruby VM. + + .. versionadded:: 1.5 + """ + name = 'Fancy' + filenames = ['*.fy', '*.fancypack'] + aliases = ['fancy', 'fy'] + mimetypes = ['text/x-fancysrc'] + + tokens = { + # copied from PerlLexer: + 'balanced-regex': [ + (r'/(\\\\|\\/|[^/])*/[egimosx]*', String.Regex, '#pop'), + (r'!(\\\\|\\!|[^!])*![egimosx]*', String.Regex, '#pop'), + (r'\\(\\\\|[^\\])*\\[egimosx]*', String.Regex, '#pop'), + (r'\{(\\\\|\\\}|[^}])*\}[egimosx]*', String.Regex, '#pop'), + (r'<(\\\\|\\>|[^>])*>[egimosx]*', String.Regex, '#pop'), + (r'\[(\\\\|\\\]|[^\]])*\][egimosx]*', String.Regex, '#pop'), + (r'\((\\\\|\\\)|[^)])*\)[egimosx]*', String.Regex, '#pop'), + (r'@(\\\\|\\@|[^@])*@[egimosx]*', String.Regex, '#pop'), + (r'%(\\\\|\\%|[^%])*%[egimosx]*', String.Regex, '#pop'), + (r'\$(\\\\|\\\$|[^$])*\$[egimosx]*', String.Regex, '#pop'), + ], + 'root': [ + (r'\s+', Text), + + # balanced delimiters (copied from PerlLexer): + (r's\{(\\\\|\\\}|[^}])*\}\s*', String.Regex, 'balanced-regex'), + (r's<(\\\\|\\>|[^>])*>\s*', String.Regex, 'balanced-regex'), + (r's\[(\\\\|\\\]|[^\]])*\]\s*', String.Regex, 'balanced-regex'), + (r's\((\\\\|\\\)|[^)])*\)\s*', String.Regex, 'balanced-regex'), + (r'm?/(\\\\|\\/|[^/\n])*/[gcimosx]*', String.Regex), + (r'm(?=[/!\\{<\[(@%$])', String.Regex, 'balanced-regex'), + + # Comments + (r'#(.*?)\n', Comment.Single), + # Symbols + (r'\'([^\'\s\[\](){}]+|\[\])', String.Symbol), + # Multi-line DoubleQuotedString + (r'"""(\\\\|\\"|[^"])*"""', String), + # DoubleQuotedString + (r'"(\\\\|\\"|[^"])*"', String), + # keywords + (r'(def|class|try|catch|finally|retry|return|return_local|match|' + r'case|->|=>)\b', Keyword), + # constants + (r'(self|super|nil|false|true)\b', Name.Constant), + (r'[(){};,/?|:\\]', Punctuation), + # names + (words(( + 'Object', 'Array', 'Hash', 'Directory', 'File', 'Class', 'String', + 'Number', 'Enumerable', 'FancyEnumerable', 'Block', 'TrueClass', + 'NilClass', 'FalseClass', 'Tuple', 'Symbol', 'Stack', 'Set', + 'FancySpec', 'Method', 'Package', 'Range'), suffix=r'\b'), + Name.Builtin), + # functions + (r'[a-zA-Z](\w|[-+?!=*/^><%])*:', Name.Function), + # operators, must be below functions + (r'[-+*/~,<>=&!?%^\[\].$]+', Operator), + (r'[A-Z]\w*', Name.Constant), + (r'@[a-zA-Z_]\w*', Name.Variable.Instance), + (r'@@[a-zA-Z_]\w*', Name.Variable.Class), + ('@@?', Operator), + (r'[a-zA-Z_]\w*', Name), + # numbers - / checks are necessary to avoid mismarking regexes, + # see comment in RubyLexer + (r'(0[oO]?[0-7]+(?:_[0-7]+)*)(\s*)([/?])?', + bygroups(Number.Oct, Text, Operator)), + (r'(0[xX][0-9A-Fa-f]+(?:_[0-9A-Fa-f]+)*)(\s*)([/?])?', + bygroups(Number.Hex, Text, Operator)), + (r'(0[bB][01]+(?:_[01]+)*)(\s*)([/?])?', + bygroups(Number.Bin, Text, Operator)), + (r'([\d]+(?:_\d+)*)(\s*)([/?])?', + bygroups(Number.Integer, Text, Operator)), + (r'\d+([eE][+-]?[0-9]+)|\d+\.\d+([eE][+-]?[0-9]+)?', Number.Float), + (r'\d+', Number.Integer) + ] + } diff --git a/.venv/lib/python3.8/site-packages/pygments/lexers/rust.py b/.venv/lib/python3.8/site-packages/pygments/lexers/rust.py new file mode 100644 index 00000000..70f4b8da --- /dev/null +++ b/.venv/lib/python3.8/site-packages/pygments/lexers/rust.py @@ -0,0 +1,224 @@ +# -*- coding: utf-8 -*- +""" + pygments.lexers.rust + ~~~~~~~~~~~~~~~~~~~~ + + Lexers for the Rust language. + + :copyright: Copyright 2006-2020 by the Pygments team, see AUTHORS. + :license: BSD, see LICENSE for details. +""" + +from pygments.lexer import RegexLexer, include, bygroups, words, default +from pygments.token import Text, Comment, Operator, Keyword, Name, String, \ + Number, Punctuation, Whitespace + +__all__ = ['RustLexer'] + + +class RustLexer(RegexLexer): + """ + Lexer for the Rust programming language (version 1.47). + + .. versionadded:: 1.6 + """ + name = 'Rust' + filenames = ['*.rs', '*.rs.in'] + aliases = ['rust', 'rs'] + mimetypes = ['text/rust', 'text/x-rust'] + + keyword_types = (words(( + 'u8', 'u16', 'u32', 'u64', 'u128', 'i8', 'i16', 'i32', 'i64', 'i128', + 'usize', 'isize', 'f32', 'f64', 'char', 'str', 'bool', + ), suffix=r'\b'), Keyword.Type) + + builtin_funcs_types = (words(( + 'Copy', 'Send', 'Sized', 'Sync', 'Unpin', + 'Drop', 'Fn', 'FnMut', 'FnOnce', 'drop', + 'Box', 'ToOwned', 'Clone', + 'PartialEq', 'PartialOrd', 'Eq', 'Ord', + 'AsRef', 'AsMut', 'Into', 'From', 'Default', + 'Iterator', 'Extend', 'IntoIterator', 'DoubleEndedIterator', + 'ExactSizeIterator', + 'Option', 'Some', 'None', + 'Result', 'Ok', 'Err', + 'String', 'ToString', 'Vec', + ), suffix=r'\b'), Name.Builtin) + + builtin_macros = (words(( + 'asm', 'assert', 'assert_eq', 'assert_ne', 'cfg', 'column', + 'compile_error', 'concat', 'concat_idents', 'dbg', 'debug_assert', + 'debug_assert_eq', 'debug_assert_ne', 'env', 'eprint', 'eprintln', + 'file', 'format', 'format_args', 'format_args_nl', 'global_asm', + 'include', 'include_bytes', 'include_str', + 'is_aarch64_feature_detected', + 'is_arm_feature_detected', + 'is_mips64_feature_detected', + 'is_mips_feature_detected', + 'is_powerpc64_feature_detected', + 'is_powerpc_feature_detected', + 'is_x86_feature_detected', + 'line', 'llvm_asm', 'log_syntax', 'macro_rules', 'matches', + 'module_path', 'option_env', 'panic', 'print', 'println', 'stringify', + 'thread_local', 'todo', 'trace_macros', 'unimplemented', 'unreachable', + 'vec', 'write', 'writeln', + ), suffix=r'!'), Name.Function.Magic) + + tokens = { + 'root': [ + # rust allows a file to start with a shebang, but if the first line + # starts with #![ then it's not a shebang but a crate attribute. + (r'#![^[\r\n].*$', Comment.Preproc), + default('base'), + ], + 'base': [ + # Whitespace and Comments + (r'\n', Whitespace), + (r'\s+', Whitespace), + (r'//!.*?\n', String.Doc), + (r'///(\n|[^/].*?\n)', String.Doc), + (r'//(.*?)\n', Comment.Single), + (r'/\*\*(\n|[^/*])', String.Doc, 'doccomment'), + (r'/\*!', String.Doc, 'doccomment'), + (r'/\*', Comment.Multiline, 'comment'), + + # Macro parameters + (r"""\$([a-zA-Z_]\w*|\(,?|\),?|,?)""", Comment.Preproc), + # Keywords + (words(('as', 'async', 'await', 'box', 'const', 'crate', 'dyn', + 'else', 'extern', 'for', 'if', 'impl', 'in', 'loop', + 'match', 'move', 'mut', 'pub', 'ref', 'return', 'static', + 'super', 'trait', 'unsafe', 'use', 'where', 'while'), + suffix=r'\b'), Keyword), + (words(('abstract', 'become', 'do', 'final', 'macro', 'override', + 'priv', 'typeof', 'try', 'unsized', 'virtual', 'yield'), + suffix=r'\b'), Keyword.Reserved), + (r'(true|false)\b', Keyword.Constant), + (r'self\b', Name.Builtin.Pseudo), + (r'mod\b', Keyword, 'modname'), + (r'let\b', Keyword.Declaration), + (r'fn\b', Keyword, 'funcname'), + (r'(struct|enum|type|union)\b', Keyword, 'typename'), + (r'(default)(\s+)(type|fn)\b', bygroups(Keyword, Text, Keyword)), + keyword_types, + (r'[sS]elf\b', Name.Builtin.Pseudo), + # Prelude (taken from Rust's src/libstd/prelude.rs) + builtin_funcs_types, + builtin_macros, + # Path seperators, so types don't catch them. + (r'::\b', Text), + # Types in positions. + (r'(?::|->)', Text, 'typename'), + # Labels + (r'(break|continue)(\s*)(\'[A-Za-z_]\w*)?', + bygroups(Keyword, Text.Whitespace, Name.Label)), + + # Character literals + (r"""'(\\['"\\nrt]|\\x[0-7][0-9a-fA-F]|\\0""" + r"""|\\u\{[0-9a-fA-F]{1,6}\}|.)'""", + String.Char), + (r"""b'(\\['"\\nrt]|\\x[0-9a-fA-F]{2}|\\0""" + r"""|\\u\{[0-9a-fA-F]{1,6}\}|.)'""", + String.Char), + + # Binary literals + (r'0b[01_]+', Number.Bin, 'number_lit'), + # Octal literals + (r'0o[0-7_]+', Number.Oct, 'number_lit'), + # Hexadecimal literals + (r'0[xX][0-9a-fA-F_]+', Number.Hex, 'number_lit'), + # Decimal literals + (r'[0-9][0-9_]*(\.[0-9_]+[eE][+\-]?[0-9_]+|' + r'\.[0-9_]*(?!\.)|[eE][+\-]?[0-9_]+)', Number.Float, + 'number_lit'), + (r'[0-9][0-9_]*', Number.Integer, 'number_lit'), + + # String literals + (r'b"', String, 'bytestring'), + (r'"', String, 'string'), + (r'b?r(#*)".*?"\1', String), + + # Lifetime names + (r"'", Operator, 'lifetime'), + + # Operators and Punctuation + (r'\.\.=?', Operator), + (r'[{}()\[\],.;]', Punctuation), + (r'[+\-*/%&|<>^!~@=:?]', Operator), + + # Identifiers + (r'[a-zA-Z_]\w*', Name), + # Raw identifiers + (r'r#[a-zA-Z_]\w*', Name), + + # Attributes + (r'#!?\[', Comment.Preproc, 'attribute['), + ], + 'comment': [ + (r'[^*/]+', Comment.Multiline), + (r'/\*', Comment.Multiline, '#push'), + (r'\*/', Comment.Multiline, '#pop'), + (r'[*/]', Comment.Multiline), + ], + 'doccomment': [ + (r'[^*/]+', String.Doc), + (r'/\*', String.Doc, '#push'), + (r'\*/', String.Doc, '#pop'), + (r'[*/]', String.Doc), + ], + 'modname': [ + (r'\s+', Text), + (r'[a-zA-Z_]\w*', Name.Namespace, '#pop'), + default('#pop'), + ], + 'funcname': [ + (r'\s+', Text), + (r'[a-zA-Z_]\w*', Name.Function, '#pop'), + default('#pop'), + ], + 'typename': [ + (r'\s+', Text), + (r'&', Keyword.Pseudo), + (r"'", Operator, 'lifetime'), + builtin_funcs_types, + keyword_types, + (r'[a-zA-Z_]\w*', Name.Class, '#pop'), + default('#pop'), + ], + 'lifetime': [ + (r"(static|_)", Name.Builtin), + (r"[a-zA-Z_]+\w*", Name.Attribute), + default('#pop'), + ], + 'number_lit': [ + (r'[ui](8|16|32|64|size)', Keyword, '#pop'), + (r'f(32|64)', Keyword, '#pop'), + default('#pop'), + ], + 'string': [ + (r'"', String, '#pop'), + (r"""\\['"\\nrt]|\\x[0-7][0-9a-fA-F]|\\0""" + r"""|\\u\{[0-9a-fA-F]{1,6}\}""", String.Escape), + (r'[^\\"]+', String), + (r'\\', String), + ], + 'bytestring': [ + (r"""\\x[89a-fA-F][0-9a-fA-F]""", String.Escape), + include('string'), + ], + 'attribute_common': [ + (r'"', String, 'string'), + (r'\[', Comment.Preproc, 'attribute['), + (r'\(', Comment.Preproc, 'attribute('), + ], + 'attribute[': [ + include('attribute_common'), + (r'\];?', Comment.Preproc, '#pop'), + (r'[^"\]]+', Comment.Preproc), + ], + 'attribute(': [ + include('attribute_common'), + (r'\);?', Comment.Preproc, '#pop'), + (r'[^")]+', Comment.Preproc), + ], + } diff --git a/.venv/lib/python3.8/site-packages/pygments/lexers/sas.py b/.venv/lib/python3.8/site-packages/pygments/lexers/sas.py new file mode 100644 index 00000000..85b07adb --- /dev/null +++ b/.venv/lib/python3.8/site-packages/pygments/lexers/sas.py @@ -0,0 +1,228 @@ +# -*- coding: utf-8 -*- +""" + pygments.lexers.sas + ~~~~~~~~~~~~~~~~~~~ + + Lexer for SAS. + + :copyright: Copyright 2006-2020 by the Pygments team, see AUTHORS. + :license: BSD, see LICENSE for details. +""" + +import re +from pygments.lexer import RegexLexer, include, words +from pygments.token import Comment, Keyword, Name, Number, String, Text, \ + Other, Generic + +__all__ = ['SASLexer'] + + +class SASLexer(RegexLexer): + """ + For `SAS `_ files. + + .. versionadded:: 2.2 + """ + # Syntax from syntax/sas.vim by James Kidd + + name = 'SAS' + aliases = ['sas'] + filenames = ['*.SAS', '*.sas'] + mimetypes = ['text/x-sas', 'text/sas', 'application/x-sas'] + flags = re.IGNORECASE | re.MULTILINE + + builtins_macros = ( + "bquote", "nrbquote", "cmpres", "qcmpres", "compstor", "datatyp", + "display", "do", "else", "end", "eval", "global", "goto", "if", + "index", "input", "keydef", "label", "left", "length", "let", + "local", "lowcase", "macro", "mend", "nrquote", + "nrstr", "put", "qleft", "qlowcase", "qscan", + "qsubstr", "qsysfunc", "qtrim", "quote", "qupcase", "scan", + "str", "substr", "superq", "syscall", "sysevalf", "sysexec", + "sysfunc", "sysget", "syslput", "sysprod", "sysrc", "sysrput", + "then", "to", "trim", "unquote", "until", "upcase", "verify", + "while", "window" + ) + + builtins_conditionals = ( + "do", "if", "then", "else", "end", "until", "while" + ) + + builtins_statements = ( + "abort", "array", "attrib", "by", "call", "cards", "cards4", + "catname", "continue", "datalines", "datalines4", "delete", "delim", + "delimiter", "display", "dm", "drop", "endsas", "error", "file", + "filename", "footnote", "format", "goto", "in", "infile", "informat", + "input", "keep", "label", "leave", "length", "libname", "link", + "list", "lostcard", "merge", "missing", "modify", "options", "output", + "out", "page", "put", "redirect", "remove", "rename", "replace", + "retain", "return", "select", "set", "skip", "startsas", "stop", + "title", "update", "waitsas", "where", "window", "x", "systask" + ) + + builtins_sql = ( + "add", "and", "alter", "as", "cascade", "check", "create", + "delete", "describe", "distinct", "drop", "foreign", "from", + "group", "having", "index", "insert", "into", "in", "key", "like", + "message", "modify", "msgtype", "not", "null", "on", "or", + "order", "primary", "references", "reset", "restrict", "select", + "set", "table", "unique", "update", "validate", "view", "where" + ) + + builtins_functions = ( + "abs", "addr", "airy", "arcos", "arsin", "atan", "attrc", + "attrn", "band", "betainv", "blshift", "bnot", "bor", + "brshift", "bxor", "byte", "cdf", "ceil", "cexist", "cinv", + "close", "cnonct", "collate", "compbl", "compound", + "compress", "cos", "cosh", "css", "curobs", "cv", "daccdb", + "daccdbsl", "daccsl", "daccsyd", "dacctab", "dairy", "date", + "datejul", "datepart", "datetime", "day", "dclose", "depdb", + "depdbsl", "depsl", "depsyd", + "deptab", "dequote", "dhms", "dif", "digamma", + "dim", "dinfo", "dnum", "dopen", "doptname", "doptnum", + "dread", "dropnote", "dsname", "erf", "erfc", "exist", "exp", + "fappend", "fclose", "fcol", "fdelete", "fetch", "fetchobs", + "fexist", "fget", "fileexist", "filename", "fileref", + "finfo", "finv", "fipname", "fipnamel", "fipstate", "floor", + "fnonct", "fnote", "fopen", "foptname", "foptnum", "fpoint", + "fpos", "fput", "fread", "frewind", "frlen", "fsep", "fuzz", + "fwrite", "gaminv", "gamma", "getoption", "getvarc", "getvarn", + "hbound", "hms", "hosthelp", "hour", "ibessel", "index", + "indexc", "indexw", "input", "inputc", "inputn", "int", + "intck", "intnx", "intrr", "irr", "jbessel", "juldate", + "kurtosis", "lag", "lbound", "left", "length", "lgamma", + "libname", "libref", "log", "log10", "log2", "logpdf", "logpmf", + "logsdf", "lowcase", "max", "mdy", "mean", "min", "minute", + "mod", "month", "mopen", "mort", "n", "netpv", "nmiss", + "normal", "note", "npv", "open", "ordinal", "pathname", + "pdf", "peek", "peekc", "pmf", "point", "poisson", "poke", + "probbeta", "probbnml", "probchi", "probf", "probgam", + "probhypr", "probit", "probnegb", "probnorm", "probt", + "put", "putc", "putn", "qtr", "quote", "ranbin", "rancau", + "ranexp", "rangam", "range", "rank", "rannor", "ranpoi", + "rantbl", "rantri", "ranuni", "repeat", "resolve", "reverse", + "rewind", "right", "round", "saving", "scan", "sdf", "second", + "sign", "sin", "sinh", "skewness", "soundex", "spedis", + "sqrt", "std", "stderr", "stfips", "stname", "stnamel", + "substr", "sum", "symget", "sysget", "sysmsg", "sysprod", + "sysrc", "system", "tan", "tanh", "time", "timepart", "tinv", + "tnonct", "today", "translate", "tranwrd", "trigamma", + "trim", "trimn", "trunc", "uniform", "upcase", "uss", "var", + "varfmt", "varinfmt", "varlabel", "varlen", "varname", + "varnum", "varray", "varrayx", "vartype", "verify", "vformat", + "vformatd", "vformatdx", "vformatn", "vformatnx", "vformatw", + "vformatwx", "vformatx", "vinarray", "vinarrayx", "vinformat", + "vinformatd", "vinformatdx", "vinformatn", "vinformatnx", + "vinformatw", "vinformatwx", "vinformatx", "vlabel", + "vlabelx", "vlength", "vlengthx", "vname", "vnamex", "vtype", + "vtypex", "weekday", "year", "yyq", "zipfips", "zipname", + "zipnamel", "zipstate" + ) + + tokens = { + 'root': [ + include('comments'), + include('proc-data'), + include('cards-datalines'), + include('logs'), + include('general'), + (r'.', Text), + ], + # SAS is multi-line regardless, but * is ended by ; + 'comments': [ + (r'^\s*\*.*?;', Comment), + (r'/\*.*?\*/', Comment), + (r'^\s*\*(.|\n)*?;', Comment.Multiline), + (r'/[*](.|\n)*?[*]/', Comment.Multiline), + ], + # Special highlight for proc, data, quit, run + 'proc-data': [ + (r'(^|;)\s*(proc \w+|data|run|quit)[\s;]', + Keyword.Reserved), + ], + # Special highlight cards and datalines + 'cards-datalines': [ + (r'^\s*(datalines|cards)\s*;\s*$', Keyword, 'data'), + ], + 'data': [ + (r'(.|\n)*^\s*;\s*$', Other, '#pop'), + ], + # Special highlight for put NOTE|ERROR|WARNING (order matters) + 'logs': [ + (r'\n?^\s*%?put ', Keyword, 'log-messages'), + ], + 'log-messages': [ + (r'NOTE(:|-).*', Generic, '#pop'), + (r'WARNING(:|-).*', Generic.Emph, '#pop'), + (r'ERROR(:|-).*', Generic.Error, '#pop'), + include('general'), + ], + 'general': [ + include('keywords'), + include('vars-strings'), + include('special'), + include('numbers'), + ], + # Keywords, statements, functions, macros + 'keywords': [ + (words(builtins_statements, + prefix = r'\b', + suffix = r'\b'), + Keyword), + (words(builtins_sql, + prefix = r'\b', + suffix = r'\b'), + Keyword), + (words(builtins_conditionals, + prefix = r'\b', + suffix = r'\b'), + Keyword), + (words(builtins_macros, + prefix = r'%', + suffix = r'\b'), + Name.Builtin), + (words(builtins_functions, + prefix = r'\b', + suffix = r'\('), + Name.Builtin), + ], + # Strings and user-defined variables and macros (order matters) + 'vars-strings': [ + (r'&[a-z_]\w{0,31}\.?', Name.Variable), + (r'%[a-z_]\w{0,31}', Name.Function), + (r'\'', String, 'string_squote'), + (r'"', String, 'string_dquote'), + ], + 'string_squote': [ + ('\'', String, '#pop'), + (r'\\\\|\\"|\\\n', String.Escape), + # AFAIK, macro variables are not evaluated in single quotes + # (r'&', Name.Variable, 'validvar'), + (r'[^$\'\\]+', String), + (r'[$\'\\]', String), + ], + 'string_dquote': [ + (r'"', String, '#pop'), + (r'\\\\|\\"|\\\n', String.Escape), + (r'&', Name.Variable, 'validvar'), + (r'[^$&"\\]+', String), + (r'[$"\\]', String), + ], + 'validvar': [ + (r'[a-z_]\w{0,31}\.?', Name.Variable, '#pop'), + ], + # SAS numbers and special variables + 'numbers': [ + (r'\b[+-]?([0-9]+(\.[0-9]+)?|\.[0-9]+|\.)(E[+-]?[0-9]+)?i?\b', + Number), + ], + 'special': [ + (r'(null|missing|_all_|_automatic_|_character_|_n_|' + r'_infile_|_name_|_null_|_numeric_|_user_|_webout_)', + Keyword.Constant), + ], + # 'operators': [ + # (r'(-|=|<=|>=|<|>|<>|&|!=|' + # r'\||\*|\+|\^|/|!|~|~=)', Operator) + # ], + } diff --git a/.venv/lib/python3.8/site-packages/pygments/lexers/scdoc.py b/.venv/lib/python3.8/site-packages/pygments/lexers/scdoc.py new file mode 100644 index 00000000..6acc64f2 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/pygments/lexers/scdoc.py @@ -0,0 +1,83 @@ +# -*- coding: utf-8 -*- +""" + pygments.lexers.scdoc + ~~~~~~~~~~~~~~~~~~~~~ + + Lexer for scdoc, a simple man page generator. + + :copyright: Copyright 2006-2020 by the Pygments team, see AUTHORS. + :license: BSD, see LICENSE for details. +""" + +import re + +from pygments.lexer import RegexLexer, include, bygroups, \ + using, this +from pygments.token import Text, Comment, Keyword, String, \ + Generic + + +__all__ = ['ScdocLexer'] + + +class ScdocLexer(RegexLexer): + """ + `scdoc` is a simple man page generator for POSIX systems written in C99. + https://git.sr.ht/~sircmpwn/scdoc + + .. versionadded:: 2.5 + """ + name = 'scdoc' + aliases = ['scdoc', 'scd'] + filenames = ['*.scd', '*.scdoc'] + flags = re.MULTILINE + + tokens = { + 'root': [ + # comment + (r'^(;.+\n)', bygroups(Comment)), + + # heading with pound prefix + (r'^(#)([^#].+\n)', bygroups(Generic.Heading, Text)), + (r'^(#{2})(.+\n)', bygroups(Generic.Subheading, Text)), + # bulleted lists + (r'^(\s*)([*-])(\s)(.+\n)', + bygroups(Text, Keyword, Text, using(this, state='inline'))), + # numbered lists + (r'^(\s*)(\.+\.)( .+\n)', + bygroups(Text, Keyword, using(this, state='inline'))), + # quote + (r'^(\s*>\s)(.+\n)', bygroups(Keyword, Generic.Emph)), + # text block + (r'^(```\n)([\w\W]*?)(^```$)', bygroups(String, Text, String)), + + include('inline'), + ], + 'inline': [ + # escape + (r'\\.', Text), + # underlines + (r'(\s)(_[^_]+_)(\W|\n)', bygroups(Text, Generic.Emph, Text)), + # bold + (r'(\s)(\*[^*]+\*)(\W|\n)', bygroups(Text, Generic.Strong, Text)), + # inline code + (r'`[^`]+`', String.Backtick), + + # general text, must come last! + (r'[^\\\s]+', Text), + (r'.', Text), + ], + } + + def analyse_text(text): + """This is very similar to markdown, save for the escape characters + needed for * and _.""" + result = 0 + + if '\\*' in text: + result += 0.01 + + if '\\_' in text: + result += 0.01 + + return result diff --git a/.venv/lib/python3.8/site-packages/pygments/lexers/scripting.py b/.venv/lib/python3.8/site-packages/pygments/lexers/scripting.py new file mode 100644 index 00000000..885fed47 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/pygments/lexers/scripting.py @@ -0,0 +1,1284 @@ +# -*- coding: utf-8 -*- +""" + pygments.lexers.scripting + ~~~~~~~~~~~~~~~~~~~~~~~~~ + + Lexer for scripting and embedded languages. + + :copyright: Copyright 2006-2020 by the Pygments team, see AUTHORS. + :license: BSD, see LICENSE for details. +""" + +import re + +from pygments.lexer import RegexLexer, include, bygroups, default, combined, \ + words +from pygments.token import Text, Comment, Operator, Keyword, Name, String, \ + Number, Punctuation, Error, Whitespace, Other +from pygments.util import get_bool_opt, get_list_opt + +__all__ = ['LuaLexer', 'MoonScriptLexer', 'ChaiscriptLexer', 'LSLLexer', + 'AppleScriptLexer', 'RexxLexer', 'MOOCodeLexer', 'HybrisLexer', + 'EasytrieveLexer', 'JclLexer', 'MiniScriptLexer'] + + +class LuaLexer(RegexLexer): + """ + For `Lua `_ source code. + + Additional options accepted: + + `func_name_highlighting` + If given and ``True``, highlight builtin function names + (default: ``True``). + `disabled_modules` + If given, must be a list of module names whose function names + should not be highlighted. By default all modules are highlighted. + + To get a list of allowed modules have a look into the + `_lua_builtins` module: + + .. sourcecode:: pycon + + >>> from pygments.lexers._lua_builtins import MODULES + >>> MODULES.keys() + ['string', 'coroutine', 'modules', 'io', 'basic', ...] + """ + + name = 'Lua' + aliases = ['lua'] + filenames = ['*.lua', '*.wlua'] + mimetypes = ['text/x-lua', 'application/x-lua'] + + _comment_multiline = r'(?:--\[(?P=*)\[[\w\W]*?\](?P=level)\])' + _comment_single = r'(?:--.*$)' + _space = r'(?:\s+)' + _s = r'(?:%s|%s|%s)' % (_comment_multiline, _comment_single, _space) + _name = r'(?:[^\W\d]\w*)' + + tokens = { + 'root': [ + # Lua allows a file to start with a shebang. + (r'#!.*', Comment.Preproc), + default('base'), + ], + 'ws': [ + (_comment_multiline, Comment.Multiline), + (_comment_single, Comment.Single), + (_space, Text), + ], + 'base': [ + include('ws'), + + (r'(?i)0x[\da-f]*(\.[\da-f]*)?(p[+-]?\d+)?', Number.Hex), + (r'(?i)(\d*\.\d+|\d+\.\d*)(e[+-]?\d+)?', Number.Float), + (r'(?i)\d+e[+-]?\d+', Number.Float), + (r'\d+', Number.Integer), + + # multiline strings + (r'(?s)\[(=*)\[.*?\]\1\]', String), + + (r'::', Punctuation, 'label'), + (r'\.{3}', Punctuation), + (r'[=<>|~&+\-*/%#^]+|\.\.', Operator), + (r'[\[\]{}().,:;]', Punctuation), + (r'(and|or|not)\b', Operator.Word), + + ('(break|do|else|elseif|end|for|if|in|repeat|return|then|until|' + r'while)\b', Keyword.Reserved), + (r'goto\b', Keyword.Reserved, 'goto'), + (r'(local)\b', Keyword.Declaration), + (r'(true|false|nil)\b', Keyword.Constant), + + (r'(function)\b', Keyword.Reserved, 'funcname'), + + (r'[A-Za-z_]\w*(\.[A-Za-z_]\w*)?', Name), + + ("'", String.Single, combined('stringescape', 'sqs')), + ('"', String.Double, combined('stringescape', 'dqs')) + ], + + 'funcname': [ + include('ws'), + (r'[.:]', Punctuation), + (r'%s(?=%s*[.:])' % (_name, _s), Name.Class), + (_name, Name.Function, '#pop'), + # inline function + (r'\(', Punctuation, '#pop'), + ], + + 'goto': [ + include('ws'), + (_name, Name.Label, '#pop'), + ], + + 'label': [ + include('ws'), + (r'::', Punctuation, '#pop'), + (_name, Name.Label), + ], + + 'stringescape': [ + (r'\\([abfnrtv\\"\']|[\r\n]{1,2}|z\s*|x[0-9a-fA-F]{2}|\d{1,3}|' + r'u\{[0-9a-fA-F]+\})', String.Escape), + ], + + 'sqs': [ + (r"'", String.Single, '#pop'), + (r"[^\\']+", String.Single), + ], + + 'dqs': [ + (r'"', String.Double, '#pop'), + (r'[^\\"]+', String.Double), + ] + } + + def __init__(self, **options): + self.func_name_highlighting = get_bool_opt( + options, 'func_name_highlighting', True) + self.disabled_modules = get_list_opt(options, 'disabled_modules', []) + + self._functions = set() + if self.func_name_highlighting: + from pygments.lexers._lua_builtins import MODULES + for mod, func in MODULES.items(): + if mod not in self.disabled_modules: + self._functions.update(func) + RegexLexer.__init__(self, **options) + + def get_tokens_unprocessed(self, text): + for index, token, value in \ + RegexLexer.get_tokens_unprocessed(self, text): + if token is Name: + if value in self._functions: + yield index, Name.Builtin, value + continue + elif '.' in value: + a, b = value.split('.') + yield index, Name, a + yield index + len(a), Punctuation, '.' + yield index + len(a) + 1, Name, b + continue + yield index, token, value + +class MoonScriptLexer(LuaLexer): + """ + For `MoonScript `_ source code. + + .. versionadded:: 1.5 + """ + + name = "MoonScript" + aliases = ["moon", "moonscript"] + filenames = ["*.moon"] + mimetypes = ['text/x-moonscript', 'application/x-moonscript'] + + tokens = { + 'root': [ + (r'#!(.*?)$', Comment.Preproc), + default('base'), + ], + 'base': [ + ('--.*$', Comment.Single), + (r'(?i)(\d*\.\d+|\d+\.\d*)(e[+-]?\d+)?', Number.Float), + (r'(?i)\d+e[+-]?\d+', Number.Float), + (r'(?i)0x[0-9a-f]*', Number.Hex), + (r'\d+', Number.Integer), + (r'\n', Text), + (r'[^\S\n]+', Text), + (r'(?s)\[(=*)\[.*?\]\1\]', String), + (r'(->|=>)', Name.Function), + (r':[a-zA-Z_]\w*', Name.Variable), + (r'(==|!=|~=|<=|>=|\.\.\.|\.\.|[=+\-*/%^<>#!.\\:])', Operator), + (r'[;,]', Punctuation), + (r'[\[\]{}()]', Keyword.Type), + (r'[a-zA-Z_]\w*:', Name.Variable), + (words(( + 'class', 'extends', 'if', 'then', 'super', 'do', 'with', + 'import', 'export', 'while', 'elseif', 'return', 'for', 'in', + 'from', 'when', 'using', 'else', 'and', 'or', 'not', 'switch', + 'break'), suffix=r'\b'), + Keyword), + (r'(true|false|nil)\b', Keyword.Constant), + (r'(and|or|not)\b', Operator.Word), + (r'(self)\b', Name.Builtin.Pseudo), + (r'@@?([a-zA-Z_]\w*)?', Name.Variable.Class), + (r'[A-Z]\w*', Name.Class), # proper name + (r'[A-Za-z_]\w*(\.[A-Za-z_]\w*)?', Name), + ("'", String.Single, combined('stringescape', 'sqs')), + ('"', String.Double, combined('stringescape', 'dqs')) + ], + 'stringescape': [ + (r'''\\([abfnrtv\\"']|\d{1,3})''', String.Escape) + ], + 'sqs': [ + ("'", String.Single, '#pop'), + (".", String) + ], + 'dqs': [ + ('"', String.Double, '#pop'), + (".", String) + ] + } + + def get_tokens_unprocessed(self, text): + # set . as Operator instead of Punctuation + for index, token, value in LuaLexer.get_tokens_unprocessed(self, text): + if token == Punctuation and value == ".": + token = Operator + yield index, token, value + + +class ChaiscriptLexer(RegexLexer): + """ + For `ChaiScript `_ source code. + + .. versionadded:: 2.0 + """ + + name = 'ChaiScript' + aliases = ['chai', 'chaiscript'] + filenames = ['*.chai'] + mimetypes = ['text/x-chaiscript', 'application/x-chaiscript'] + + flags = re.DOTALL | re.MULTILINE + + tokens = { + 'commentsandwhitespace': [ + (r'\s+', Text), + (r'//.*?\n', Comment.Single), + (r'/\*.*?\*/', Comment.Multiline), + (r'^\#.*?\n', Comment.Single) + ], + 'slashstartsregex': [ + include('commentsandwhitespace'), + (r'/(\\.|[^[/\\\n]|\[(\\.|[^\]\\\n])*])+/' + r'([gim]+\b|\B)', String.Regex, '#pop'), + (r'(?=/)', Text, ('#pop', 'badregex')), + default('#pop') + ], + 'badregex': [ + (r'\n', Text, '#pop') + ], + 'root': [ + include('commentsandwhitespace'), + (r'\n', Text), + (r'[^\S\n]+', Text), + (r'\+\+|--|~|&&|\?|:|\|\||\\(?=\n)|\.\.' + r'(<<|>>>?|==?|!=?|[-<>+*%&|^/])=?', Operator, 'slashstartsregex'), + (r'[{(\[;,]', Punctuation, 'slashstartsregex'), + (r'[})\].]', Punctuation), + (r'[=+\-*/]', Operator), + (r'(for|in|while|do|break|return|continue|if|else|' + r'throw|try|catch' + r')\b', Keyword, 'slashstartsregex'), + (r'(var)\b', Keyword.Declaration, 'slashstartsregex'), + (r'(attr|def|fun)\b', Keyword.Reserved), + (r'(true|false)\b', Keyword.Constant), + (r'(eval|throw)\b', Name.Builtin), + (r'`\S+`', Name.Builtin), + (r'[$a-zA-Z_]\w*', Name.Other), + (r'[0-9][0-9]*\.[0-9]+([eE][0-9]+)?[fd]?', Number.Float), + (r'0x[0-9a-fA-F]+', Number.Hex), + (r'[0-9]+', Number.Integer), + (r'"', String.Double, 'dqstring'), + (r"'(\\\\|\\'|[^'])*'", String.Single), + ], + 'dqstring': [ + (r'\$\{[^"}]+?\}', String.Interpol), + (r'\$', String.Double), + (r'\\\\', String.Double), + (r'\\"', String.Double), + (r'[^\\"$]+', String.Double), + (r'"', String.Double, '#pop'), + ], + } + + +class LSLLexer(RegexLexer): + """ + For Second Life's Linden Scripting Language source code. + + .. versionadded:: 2.0 + """ + + name = 'LSL' + aliases = ['lsl'] + filenames = ['*.lsl'] + mimetypes = ['text/x-lsl'] + + flags = re.MULTILINE + + lsl_keywords = r'\b(?:do|else|for|if|jump|return|while)\b' + lsl_types = r'\b(?:float|integer|key|list|quaternion|rotation|string|vector)\b' + lsl_states = r'\b(?:(?:state)\s+\w+|default)\b' + lsl_events = r'\b(?:state_(?:entry|exit)|touch(?:_(?:start|end))?|(?:land_)?collision(?:_(?:start|end))?|timer|listen|(?:no_)?sensor|control|(?:not_)?at_(?:rot_)?target|money|email|run_time_permissions|changed|attach|dataserver|moving_(?:start|end)|link_message|(?:on|object)_rez|remote_data|http_re(?:sponse|quest)|path_update|transaction_result)\b' + lsl_functions_builtin = r'\b(?:ll(?:ReturnObjectsBy(?:ID|Owner)|Json(?:2List|[GS]etValue|ValueType)|Sin|Cos|Tan|Atan2|Sqrt|Pow|Abs|Fabs|Frand|Floor|Ceil|Round|Vec(?:Mag|Norm|Dist)|Rot(?:Between|2(?:Euler|Fwd|Left|Up))|(?:Euler|Axes)2Rot|Whisper|(?:Region|Owner)?Say|Shout|Listen(?:Control|Remove)?|Sensor(?:Repeat|Remove)?|Detected(?:Name|Key|Owner|Type|Pos|Vel|Grab|Rot|Group|LinkNumber)|Die|Ground|Wind|(?:[GS]et)(?:AnimationOverride|MemoryLimit|PrimMediaParams|ParcelMusicURL|Object(?:Desc|Name)|PhysicsMaterial|Status|Scale|Color|Alpha|Texture|Pos|Rot|Force|Torque)|ResetAnimationOverride|(?:Scale|Offset|Rotate)Texture|(?:Rot)?Target(?:Remove)?|(?:Stop)?MoveToTarget|Apply(?:Rotational)?Impulse|Set(?:KeyframedMotion|ContentType|RegionPos|(?:Angular)?Velocity|Buoyancy|HoverHeight|ForceAndTorque|TimerEvent|ScriptState|Damage|TextureAnim|Sound(?:Queueing|Radius)|Vehicle(?:Type|(?:Float|Vector|Rotation)Param)|(?:Touch|Sit)?Text|Camera(?:Eye|At)Offset|PrimitiveParams|ClickAction|Link(?:Alpha|Color|PrimitiveParams(?:Fast)?|Texture(?:Anim)?|Camera|Media)|RemoteScriptAccessPin|PayPrice|LocalRot)|ScaleByFactor|Get(?:(?:Max|Min)ScaleFactor|ClosestNavPoint|StaticPath|SimStats|Env|PrimitiveParams|Link(?:PrimitiveParams|Number(?:OfSides)?|Key|Name|Media)|HTTPHeader|FreeURLs|Object(?:Details|PermMask|PrimCount)|Parcel(?:MaxPrims|Details|Prim(?:Count|Owners))|Attached|(?:SPMax|Free|Used)Memory|Region(?:Name|TimeDilation|FPS|Corner|AgentCount)|Root(?:Position|Rotation)|UnixTime|(?:Parcel|Region)Flags|(?:Wall|GMT)clock|SimulatorHostname|BoundingBox|GeometricCenter|Creator|NumberOf(?:Prims|NotecardLines|Sides)|Animation(?:List)?|(?:Camera|Local)(?:Pos|Rot)|Vel|Accel|Omega|Time(?:stamp|OfDay)|(?:Object|CenterOf)?Mass|MassMKS|Energy|Owner|(?:Owner)?Key|SunDirection|Texture(?:Offset|Scale|Rot)|Inventory(?:Number|Name|Key|Type|Creator|PermMask)|Permissions(?:Key)?|StartParameter|List(?:Length|EntryType)|Date|Agent(?:Size|Info|Language|List)|LandOwnerAt|NotecardLine|Script(?:Name|State))|(?:Get|Reset|GetAndReset)Time|PlaySound(?:Slave)?|LoopSound(?:Master|Slave)?|(?:Trigger|Stop|Preload)Sound|(?:(?:Get|Delete)Sub|Insert)String|To(?:Upper|Lower)|Give(?:InventoryList|Money)|RezObject|(?:Stop)?LookAt|Sleep|CollisionFilter|(?:Take|Release)Controls|DetachFromAvatar|AttachToAvatar(?:Temp)?|InstantMessage|(?:GetNext)?Email|StopHover|MinEventDelay|RotLookAt|String(?:Length|Trim)|(?:Start|Stop)Animation|TargetOmega|RequestPermissions|(?:Create|Break)Link|BreakAllLinks|(?:Give|Remove)Inventory|Water|PassTouches|Request(?:Agent|Inventory)Data|TeleportAgent(?:Home|GlobalCoords)?|ModifyLand|CollisionSound|ResetScript|MessageLinked|PushObject|PassCollisions|AxisAngle2Rot|Rot2(?:Axis|Angle)|A(?:cos|sin)|AngleBetween|AllowInventoryDrop|SubStringIndex|List2(?:CSV|Integer|Json|Float|String|Key|Vector|Rot|List(?:Strided)?)|DeleteSubList|List(?:Statistics|Sort|Randomize|(?:Insert|Find|Replace)List)|EdgeOfWorld|AdjustSoundVolume|Key2Name|TriggerSoundLimited|EjectFromLand|(?:CSV|ParseString)2List|OverMyLand|SameGroup|UnSit|Ground(?:Slope|Normal|Contour)|GroundRepel|(?:Set|Remove)VehicleFlags|(?:AvatarOn)?(?:Link)?SitTarget|Script(?:Danger|Profiler)|Dialog|VolumeDetect|ResetOtherScript|RemoteLoadScriptPin|(?:Open|Close)RemoteDataChannel|SendRemoteData|RemoteDataReply|(?:Integer|String)ToBase64|XorBase64|Log(?:10)?|Base64To(?:String|Integer)|ParseStringKeepNulls|RezAtRoot|RequestSimulatorData|ForceMouselook|(?:Load|Release|(?:E|Une)scape)URL|ParcelMedia(?:CommandList|Query)|ModPow|MapDestination|(?:RemoveFrom|AddTo|Reset)Land(?:Pass|Ban)List|(?:Set|Clear)CameraParams|HTTP(?:Request|Response)|TextBox|DetectedTouch(?:UV|Face|Pos|(?:N|Bin)ormal|ST)|(?:MD5|SHA1|DumpList2)String|Request(?:Secure)?URL|Clear(?:Prim|Link)Media|(?:Link)?ParticleSystem|(?:Get|Request)(?:Username|DisplayName)|RegionSayTo|CastRay|GenerateKey|TransferLindenDollars|ManageEstateAccess|(?:Create|Delete)Character|ExecCharacterCmd|Evade|FleeFrom|NavigateTo|PatrolPoints|Pursue|UpdateCharacter|WanderWithin))\b' + lsl_constants_float = r'\b(?:DEG_TO_RAD|PI(?:_BY_TWO)?|RAD_TO_DEG|SQRT2|TWO_PI)\b' + lsl_constants_integer = r'\b(?:JSON_APPEND|STATUS_(?:PHYSICS|ROTATE_[XYZ]|PHANTOM|SANDBOX|BLOCK_GRAB(?:_OBJECT)?|(?:DIE|RETURN)_AT_EDGE|CAST_SHADOWS|OK|MALFORMED_PARAMS|TYPE_MISMATCH|BOUNDS_ERROR|NOT_(?:FOUND|SUPPORTED)|INTERNAL_ERROR|WHITELIST_FAILED)|AGENT(?:_(?:BY_(?:LEGACY_|USER)NAME|FLYING|ATTACHMENTS|SCRIPTED|MOUSELOOK|SITTING|ON_OBJECT|AWAY|WALKING|IN_AIR|TYPING|CROUCHING|BUSY|ALWAYS_RUN|AUTOPILOT|LIST_(?:PARCEL(?:_OWNER)?|REGION)))?|CAMERA_(?:PITCH|DISTANCE|BEHINDNESS_(?:ANGLE|LAG)|(?:FOCUS|POSITION)(?:_(?:THRESHOLD|LOCKED|LAG))?|FOCUS_OFFSET|ACTIVE)|ANIM_ON|LOOP|REVERSE|PING_PONG|SMOOTH|ROTATE|SCALE|ALL_SIDES|LINK_(?:ROOT|SET|ALL_(?:OTHERS|CHILDREN)|THIS)|ACTIVE|PASSIVE|SCRIPTED|CONTROL_(?:FWD|BACK|(?:ROT_)?(?:LEFT|RIGHT)|UP|DOWN|(?:ML_)?LBUTTON)|PERMISSION_(?:RETURN_OBJECTS|DEBIT|OVERRIDE_ANIMATIONS|SILENT_ESTATE_MANAGEMENT|TAKE_CONTROLS|TRIGGER_ANIMATION|ATTACH|CHANGE_LINKS|(?:CONTROL|TRACK)_CAMERA|TELEPORT)|INVENTORY_(?:TEXTURE|SOUND|OBJECT|SCRIPT|LANDMARK|CLOTHING|NOTECARD|BODYPART|ANIMATION|GESTURE|ALL|NONE)|CHANGED_(?:INVENTORY|COLOR|SHAPE|SCALE|TEXTURE|LINK|ALLOWED_DROP|OWNER|REGION(?:_START)?|TELEPORT|MEDIA)|OBJECT_(?:(?:PHYSICS|SERVER|STREAMING)_COST|UNKNOWN_DETAIL|CHARACTER_TIME|PHANTOM|PHYSICS|TEMP_ON_REZ|NAME|DESC|POS|PRIM_EQUIVALENCE|RETURN_(?:PARCEL(?:_OWNER)?|REGION)|ROO?T|VELOCITY|OWNER|GROUP|CREATOR|ATTACHED_POINT|RENDER_WEIGHT|PATHFINDING_TYPE|(?:RUNNING|TOTAL)_SCRIPT_COUNT|SCRIPT_(?:MEMORY|TIME))|TYPE_(?:INTEGER|FLOAT|STRING|KEY|VECTOR|ROTATION|INVALID)|(?:DEBUG|PUBLIC)_CHANNEL|ATTACH_(?:AVATAR_CENTER|CHEST|HEAD|BACK|PELVIS|MOUTH|CHIN|NECK|NOSE|BELLY|[LR](?:SHOULDER|HAND|FOOT|EAR|EYE|[UL](?:ARM|LEG)|HIP)|(?:LEFT|RIGHT)_PEC|HUD_(?:CENTER_[12]|TOP_(?:RIGHT|CENTER|LEFT)|BOTTOM(?:_(?:RIGHT|LEFT))?))|LAND_(?:LEVEL|RAISE|LOWER|SMOOTH|NOISE|REVERT)|DATA_(?:ONLINE|NAME|BORN|SIM_(?:POS|STATUS|RATING)|PAYINFO)|PAYMENT_INFO_(?:ON_FILE|USED)|REMOTE_DATA_(?:CHANNEL|REQUEST|REPLY)|PSYS_(?:PART_(?:BF_(?:ZERO|ONE(?:_MINUS_(?:DEST_COLOR|SOURCE_(ALPHA|COLOR)))?|DEST_COLOR|SOURCE_(ALPHA|COLOR))|BLEND_FUNC_(DEST|SOURCE)|FLAGS|(?:START|END)_(?:COLOR|ALPHA|SCALE|GLOW)|MAX_AGE|(?:RIBBON|WIND|INTERP_(?:COLOR|SCALE)|BOUNCE|FOLLOW_(?:SRC|VELOCITY)|TARGET_(?:POS|LINEAR)|EMISSIVE)_MASK)|SRC_(?:MAX_AGE|PATTERN|ANGLE_(?:BEGIN|END)|BURST_(?:RATE|PART_COUNT|RADIUS|SPEED_(?:MIN|MAX))|ACCEL|TEXTURE|TARGET_KEY|OMEGA|PATTERN_(?:DROP|EXPLODE|ANGLE(?:_CONE(?:_EMPTY)?)?)))|VEHICLE_(?:REFERENCE_FRAME|TYPE_(?:NONE|SLED|CAR|BOAT|AIRPLANE|BALLOON)|(?:LINEAR|ANGULAR)_(?:FRICTION_TIMESCALE|MOTOR_DIRECTION)|LINEAR_MOTOR_OFFSET|HOVER_(?:HEIGHT|EFFICIENCY|TIMESCALE)|BUOYANCY|(?:LINEAR|ANGULAR)_(?:DEFLECTION_(?:EFFICIENCY|TIMESCALE)|MOTOR_(?:DECAY_)?TIMESCALE)|VERTICAL_ATTRACTION_(?:EFFICIENCY|TIMESCALE)|BANKING_(?:EFFICIENCY|MIX|TIMESCALE)|FLAG_(?:NO_DEFLECTION_UP|LIMIT_(?:ROLL_ONLY|MOTOR_UP)|HOVER_(?:(?:WATER|TERRAIN|UP)_ONLY|GLOBAL_HEIGHT)|MOUSELOOK_(?:STEER|BANK)|CAMERA_DECOUPLED))|PRIM_(?:TYPE(?:_(?:BOX|CYLINDER|PRISM|SPHERE|TORUS|TUBE|RING|SCULPT))?|HOLE_(?:DEFAULT|CIRCLE|SQUARE|TRIANGLE)|MATERIAL(?:_(?:STONE|METAL|GLASS|WOOD|FLESH|PLASTIC|RUBBER))?|SHINY_(?:NONE|LOW|MEDIUM|HIGH)|BUMP_(?:NONE|BRIGHT|DARK|WOOD|BARK|BRICKS|CHECKER|CONCRETE|TILE|STONE|DISKS|GRAVEL|BLOBS|SIDING|LARGETILE|STUCCO|SUCTION|WEAVE)|TEXGEN_(?:DEFAULT|PLANAR)|SCULPT_(?:TYPE_(?:SPHERE|TORUS|PLANE|CYLINDER|MASK)|FLAG_(?:MIRROR|INVERT))|PHYSICS(?:_(?:SHAPE_(?:CONVEX|NONE|PRIM|TYPE)))?|(?:POS|ROT)_LOCAL|SLICE|TEXT|FLEXIBLE|POINT_LIGHT|TEMP_ON_REZ|PHANTOM|POSITION|SIZE|ROTATION|TEXTURE|NAME|OMEGA|DESC|LINK_TARGET|COLOR|BUMP_SHINY|FULLBRIGHT|TEXGEN|GLOW|MEDIA_(?:ALT_IMAGE_ENABLE|CONTROLS|(?:CURRENT|HOME)_URL|AUTO_(?:LOOP|PLAY|SCALE|ZOOM)|FIRST_CLICK_INTERACT|(?:WIDTH|HEIGHT)_PIXELS|WHITELIST(?:_ENABLE)?|PERMS_(?:INTERACT|CONTROL)|PARAM_MAX|CONTROLS_(?:STANDARD|MINI)|PERM_(?:NONE|OWNER|GROUP|ANYONE)|MAX_(?:URL_LENGTH|WHITELIST_(?:SIZE|COUNT)|(?:WIDTH|HEIGHT)_PIXELS)))|MASK_(?:BASE|OWNER|GROUP|EVERYONE|NEXT)|PERM_(?:TRANSFER|MODIFY|COPY|MOVE|ALL)|PARCEL_(?:MEDIA_COMMAND_(?:STOP|PAUSE|PLAY|LOOP|TEXTURE|URL|TIME|AGENT|UNLOAD|AUTO_ALIGN|TYPE|SIZE|DESC|LOOP_SET)|FLAG_(?:ALLOW_(?:FLY|(?:GROUP_)?SCRIPTS|LANDMARK|TERRAFORM|DAMAGE|CREATE_(?:GROUP_)?OBJECTS)|USE_(?:ACCESS_(?:GROUP|LIST)|BAN_LIST|LAND_PASS_LIST)|LOCAL_SOUND_ONLY|RESTRICT_PUSHOBJECT|ALLOW_(?:GROUP|ALL)_OBJECT_ENTRY)|COUNT_(?:TOTAL|OWNER|GROUP|OTHER|SELECTED|TEMP)|DETAILS_(?:NAME|DESC|OWNER|GROUP|AREA|ID|SEE_AVATARS))|LIST_STAT_(?:MAX|MIN|MEAN|MEDIAN|STD_DEV|SUM(?:_SQUARES)?|NUM_COUNT|GEOMETRIC_MEAN|RANGE)|PAY_(?:HIDE|DEFAULT)|REGION_FLAG_(?:ALLOW_DAMAGE|FIXED_SUN|BLOCK_TERRAFORM|SANDBOX|DISABLE_(?:COLLISIONS|PHYSICS)|BLOCK_FLY|ALLOW_DIRECT_TELEPORT|RESTRICT_PUSHOBJECT)|HTTP_(?:METHOD|MIMETYPE|BODY_(?:MAXLENGTH|TRUNCATED)|CUSTOM_HEADER|PRAGMA_NO_CACHE|VERBOSE_THROTTLE|VERIFY_CERT)|STRING_(?:TRIM(?:_(?:HEAD|TAIL))?)|CLICK_ACTION_(?:NONE|TOUCH|SIT|BUY|PAY|OPEN(?:_MEDIA)?|PLAY|ZOOM)|TOUCH_INVALID_FACE|PROFILE_(?:NONE|SCRIPT_MEMORY)|RC_(?:DATA_FLAGS|DETECT_PHANTOM|GET_(?:LINK_NUM|NORMAL|ROOT_KEY)|MAX_HITS|REJECT_(?:TYPES|AGENTS|(?:NON)?PHYSICAL|LAND))|RCERR_(?:CAST_TIME_EXCEEDED|SIM_PERF_LOW|UNKNOWN)|ESTATE_ACCESS_(?:ALLOWED_(?:AGENT|GROUP)_(?:ADD|REMOVE)|BANNED_AGENT_(?:ADD|REMOVE))|DENSITY|FRICTION|RESTITUTION|GRAVITY_MULTIPLIER|KFM_(?:COMMAND|CMD_(?:PLAY|STOP|PAUSE|SET_MODE)|MODE|FORWARD|LOOP|PING_PONG|REVERSE|DATA|ROTATION|TRANSLATION)|ERR_(?:GENERIC|PARCEL_PERMISSIONS|MALFORMED_PARAMS|RUNTIME_PERMISSIONS|THROTTLED)|CHARACTER_(?:CMD_(?:(?:SMOOTH_)?STOP|JUMP)|DESIRED_(?:TURN_)?SPEED|RADIUS|STAY_WITHIN_PARCEL|LENGTH|ORIENTATION|ACCOUNT_FOR_SKIPPED_FRAMES|AVOIDANCE_MODE|TYPE(?:_(?:[A-D]|NONE))?|MAX_(?:DECEL|TURN_RADIUS|(?:ACCEL|SPEED)))|PURSUIT_(?:OFFSET|FUZZ_FACTOR|GOAL_TOLERANCE|INTERCEPT)|REQUIRE_LINE_OF_SIGHT|FORCE_DIRECT_PATH|VERTICAL|HORIZONTAL|AVOID_(?:CHARACTERS|DYNAMIC_OBSTACLES|NONE)|PU_(?:EVADE_(?:HIDDEN|SPOTTED)|FAILURE_(?:DYNAMIC_PATHFINDING_DISABLED|INVALID_(?:GOAL|START)|NO_(?:NAVMESH|VALID_DESTINATION)|OTHER|TARGET_GONE|(?:PARCEL_)?UNREACHABLE)|(?:GOAL|SLOWDOWN_DISTANCE)_REACHED)|TRAVERSAL_TYPE(?:_(?:FAST|NONE|SLOW))?|CONTENT_TYPE_(?:ATOM|FORM|HTML|JSON|LLSD|RSS|TEXT|XHTML|XML)|GCNP_(?:RADIUS|STATIC)|(?:PATROL|WANDER)_PAUSE_AT_WAYPOINTS|OPT_(?:AVATAR|CHARACTER|EXCLUSION_VOLUME|LEGACY_LINKSET|MATERIAL_VOLUME|OTHER|STATIC_OBSTACLE|WALKABLE)|SIM_STAT_PCT_CHARS_STEPPED)\b' + lsl_constants_integer_boolean = r'\b(?:FALSE|TRUE)\b' + lsl_constants_rotation = r'\b(?:ZERO_ROTATION)\b' + lsl_constants_string = r'\b(?:EOF|JSON_(?:ARRAY|DELETE|FALSE|INVALID|NULL|NUMBER|OBJECT|STRING|TRUE)|NULL_KEY|TEXTURE_(?:BLANK|DEFAULT|MEDIA|PLYWOOD|TRANSPARENT)|URL_REQUEST_(?:GRANTED|DENIED))\b' + lsl_constants_vector = r'\b(?:TOUCH_INVALID_(?:TEXCOORD|VECTOR)|ZERO_VECTOR)\b' + lsl_invalid_broken = r'\b(?:LAND_(?:LARGE|MEDIUM|SMALL)_BRUSH)\b' + lsl_invalid_deprecated = r'\b(?:ATTACH_[LR]PEC|DATA_RATING|OBJECT_ATTACHMENT_(?:GEOMETRY_BYTES|SURFACE_AREA)|PRIM_(?:CAST_SHADOWS|MATERIAL_LIGHT|TYPE_LEGACY)|PSYS_SRC_(?:INNER|OUTER)ANGLE|VEHICLE_FLAG_NO_FLY_UP|ll(?:Cloud|Make(?:Explosion|Fountain|Smoke|Fire)|RemoteDataSetRegion|Sound(?:Preload)?|XorBase64Strings(?:Correct)?))\b' + lsl_invalid_illegal = r'\b(?:event)\b' + lsl_invalid_unimplemented = r'\b(?:CHARACTER_(?:MAX_ANGULAR_(?:ACCEL|SPEED)|TURN_SPEED_MULTIPLIER)|PERMISSION_(?:CHANGE_(?:JOINTS|PERMISSIONS)|RELEASE_OWNERSHIP|REMAP_CONTROLS)|PRIM_PHYSICS_MATERIAL|PSYS_SRC_OBJ_REL_MASK|ll(?:CollisionSprite|(?:Stop)?PointAt|(?:(?:Refresh|Set)Prim)URL|(?:Take|Release)Camera|RemoteLoadScript))\b' + lsl_reserved_godmode = r'\b(?:ll(?:GodLikeRezObject|Set(?:Inventory|Object)PermMask))\b' + lsl_reserved_log = r'\b(?:print)\b' + lsl_operators = r'\+\+|\-\-|<<|>>|&&?|\|\|?|\^|~|[!%<>=*+\-/]=?' + + tokens = { + 'root': + [ + (r'//.*?\n', Comment.Single), + (r'/\*', Comment.Multiline, 'comment'), + (r'"', String.Double, 'string'), + (lsl_keywords, Keyword), + (lsl_types, Keyword.Type), + (lsl_states, Name.Class), + (lsl_events, Name.Builtin), + (lsl_functions_builtin, Name.Function), + (lsl_constants_float, Keyword.Constant), + (lsl_constants_integer, Keyword.Constant), + (lsl_constants_integer_boolean, Keyword.Constant), + (lsl_constants_rotation, Keyword.Constant), + (lsl_constants_string, Keyword.Constant), + (lsl_constants_vector, Keyword.Constant), + (lsl_invalid_broken, Error), + (lsl_invalid_deprecated, Error), + (lsl_invalid_illegal, Error), + (lsl_invalid_unimplemented, Error), + (lsl_reserved_godmode, Keyword.Reserved), + (lsl_reserved_log, Keyword.Reserved), + (r'\b([a-zA-Z_]\w*)\b', Name.Variable), + (r'(\d+\.\d*|\.\d+|\d+)[eE][+-]?\d*', Number.Float), + (r'(\d+\.\d*|\.\d+)', Number.Float), + (r'0[xX][0-9a-fA-F]+', Number.Hex), + (r'\d+', Number.Integer), + (lsl_operators, Operator), + (r':=?', Error), + (r'[,;{}()\[\]]', Punctuation), + (r'\n+', Whitespace), + (r'\s+', Whitespace) + ], + 'comment': + [ + (r'[^*/]+', Comment.Multiline), + (r'/\*', Comment.Multiline, '#push'), + (r'\*/', Comment.Multiline, '#pop'), + (r'[*/]', Comment.Multiline) + ], + 'string': + [ + (r'\\([nt"\\])', String.Escape), + (r'"', String.Double, '#pop'), + (r'\\.', Error), + (r'[^"\\]+', String.Double), + ] + } + + +class AppleScriptLexer(RegexLexer): + """ + For `AppleScript source code + `_, + including `AppleScript Studio + `_. + Contributed by Andreas Amann . + + .. versionadded:: 1.0 + """ + + name = 'AppleScript' + aliases = ['applescript'] + filenames = ['*.applescript'] + + flags = re.MULTILINE | re.DOTALL + + Identifiers = r'[a-zA-Z]\w*' + + # XXX: use words() for all of these + Literals = ('AppleScript', 'current application', 'false', 'linefeed', + 'missing value', 'pi', 'quote', 'result', 'return', 'space', + 'tab', 'text item delimiters', 'true', 'version') + Classes = ('alias ', 'application ', 'boolean ', 'class ', 'constant ', + 'date ', 'file ', 'integer ', 'list ', 'number ', 'POSIX file ', + 'real ', 'record ', 'reference ', 'RGB color ', 'script ', + 'text ', 'unit types', '(?:Unicode )?text', 'string') + BuiltIn = ('attachment', 'attribute run', 'character', 'day', 'month', + 'paragraph', 'word', 'year') + HandlerParams = ('about', 'above', 'against', 'apart from', 'around', + 'aside from', 'at', 'below', 'beneath', 'beside', + 'between', 'for', 'given', 'instead of', 'on', 'onto', + 'out of', 'over', 'since') + Commands = ('ASCII (character|number)', 'activate', 'beep', 'choose URL', + 'choose application', 'choose color', 'choose file( name)?', + 'choose folder', 'choose from list', + 'choose remote application', 'clipboard info', + 'close( access)?', 'copy', 'count', 'current date', 'delay', + 'delete', 'display (alert|dialog)', 'do shell script', + 'duplicate', 'exists', 'get eof', 'get volume settings', + 'info for', 'launch', 'list (disks|folder)', 'load script', + 'log', 'make', 'mount volume', 'new', 'offset', + 'open( (for access|location))?', 'path to', 'print', 'quit', + 'random number', 'read', 'round', 'run( script)?', + 'say', 'scripting components', + 'set (eof|the clipboard to|volume)', 'store script', + 'summarize', 'system attribute', 'system info', + 'the clipboard', 'time to GMT', 'write', 'quoted form') + References = ('(in )?back of', '(in )?front of', '[0-9]+(st|nd|rd|th)', + 'first', 'second', 'third', 'fourth', 'fifth', 'sixth', + 'seventh', 'eighth', 'ninth', 'tenth', 'after', 'back', + 'before', 'behind', 'every', 'front', 'index', 'last', + 'middle', 'some', 'that', 'through', 'thru', 'where', 'whose') + Operators = ("and", "or", "is equal", "equals", "(is )?equal to", "is not", + "isn't", "isn't equal( to)?", "is not equal( to)?", + "doesn't equal", "does not equal", "(is )?greater than", + "comes after", "is not less than or equal( to)?", + "isn't less than or equal( to)?", "(is )?less than", + "comes before", "is not greater than or equal( to)?", + "isn't greater than or equal( to)?", + "(is )?greater than or equal( to)?", "is not less than", + "isn't less than", "does not come before", + "doesn't come before", "(is )?less than or equal( to)?", + "is not greater than", "isn't greater than", + "does not come after", "doesn't come after", "starts? with", + "begins? with", "ends? with", "contains?", "does not contain", + "doesn't contain", "is in", "is contained by", "is not in", + "is not contained by", "isn't contained by", "div", "mod", + "not", "(a )?(ref( to)?|reference to)", "is", "does") + Control = ('considering', 'else', 'error', 'exit', 'from', 'if', + 'ignoring', 'in', 'repeat', 'tell', 'then', 'times', 'to', + 'try', 'until', 'using terms from', 'while', 'whith', + 'with timeout( of)?', 'with transaction', 'by', 'continue', + 'end', 'its?', 'me', 'my', 'return', 'of', 'as') + Declarations = ('global', 'local', 'prop(erty)?', 'set', 'get') + Reserved = ('but', 'put', 'returning', 'the') + StudioClasses = ('action cell', 'alert reply', 'application', 'box', + 'browser( cell)?', 'bundle', 'button( cell)?', 'cell', + 'clip view', 'color well', 'color-panel', + 'combo box( item)?', 'control', + 'data( (cell|column|item|row|source))?', 'default entry', + 'dialog reply', 'document', 'drag info', 'drawer', + 'event', 'font(-panel)?', 'formatter', + 'image( (cell|view))?', 'matrix', 'menu( item)?', 'item', + 'movie( view)?', 'open-panel', 'outline view', 'panel', + 'pasteboard', 'plugin', 'popup button', + 'progress indicator', 'responder', 'save-panel', + 'scroll view', 'secure text field( cell)?', 'slider', + 'sound', 'split view', 'stepper', 'tab view( item)?', + 'table( (column|header cell|header view|view))', + 'text( (field( cell)?|view))?', 'toolbar( item)?', + 'user-defaults', 'view', 'window') + StudioEvents = ('accept outline drop', 'accept table drop', 'action', + 'activated', 'alert ended', 'awake from nib', 'became key', + 'became main', 'begin editing', 'bounds changed', + 'cell value', 'cell value changed', 'change cell value', + 'change item value', 'changed', 'child of item', + 'choose menu item', 'clicked', 'clicked toolbar item', + 'closed', 'column clicked', 'column moved', + 'column resized', 'conclude drop', 'data representation', + 'deminiaturized', 'dialog ended', 'document nib name', + 'double clicked', 'drag( (entered|exited|updated))?', + 'drop', 'end editing', 'exposed', 'idle', 'item expandable', + 'item value', 'item value changed', 'items changed', + 'keyboard down', 'keyboard up', 'launched', + 'load data representation', 'miniaturized', 'mouse down', + 'mouse dragged', 'mouse entered', 'mouse exited', + 'mouse moved', 'mouse up', 'moved', + 'number of browser rows', 'number of items', + 'number of rows', 'open untitled', 'opened', 'panel ended', + 'parameters updated', 'plugin loaded', 'prepare drop', + 'prepare outline drag', 'prepare outline drop', + 'prepare table drag', 'prepare table drop', + 'read from file', 'resigned active', 'resigned key', + 'resigned main', 'resized( sub views)?', + 'right mouse down', 'right mouse dragged', + 'right mouse up', 'rows changed', 'scroll wheel', + 'selected tab view item', 'selection changed', + 'selection changing', 'should begin editing', + 'should close', 'should collapse item', + 'should end editing', 'should expand item', + 'should open( untitled)?', + 'should quit( after last window closed)?', + 'should select column', 'should select item', + 'should select row', 'should select tab view item', + 'should selection change', 'should zoom', 'shown', + 'update menu item', 'update parameters', + 'update toolbar item', 'was hidden', 'was miniaturized', + 'will become active', 'will close', 'will dismiss', + 'will display browser cell', 'will display cell', + 'will display item cell', 'will display outline cell', + 'will finish launching', 'will hide', 'will miniaturize', + 'will move', 'will open', 'will pop up', 'will quit', + 'will resign active', 'will resize( sub views)?', + 'will select tab view item', 'will show', 'will zoom', + 'write to file', 'zoomed') + StudioCommands = ('animate', 'append', 'call method', 'center', + 'close drawer', 'close panel', 'display', + 'display alert', 'display dialog', 'display panel', 'go', + 'hide', 'highlight', 'increment', 'item for', + 'load image', 'load movie', 'load nib', 'load panel', + 'load sound', 'localized string', 'lock focus', 'log', + 'open drawer', 'path for', 'pause', 'perform action', + 'play', 'register', 'resume', 'scroll', 'select( all)?', + 'show', 'size to fit', 'start', 'step back', + 'step forward', 'stop', 'synchronize', 'unlock focus', + 'update') + StudioProperties = ('accepts arrow key', 'action method', 'active', + 'alignment', 'allowed identifiers', + 'allows branch selection', 'allows column reordering', + 'allows column resizing', 'allows column selection', + 'allows customization', + 'allows editing text attributes', + 'allows empty selection', 'allows mixed state', + 'allows multiple selection', 'allows reordering', + 'allows undo', 'alpha( value)?', 'alternate image', + 'alternate increment value', 'alternate title', + 'animation delay', 'associated file name', + 'associated object', 'auto completes', 'auto display', + 'auto enables items', 'auto repeat', + 'auto resizes( outline column)?', + 'auto save expanded items', 'auto save name', + 'auto save table columns', 'auto saves configuration', + 'auto scroll', 'auto sizes all columns to fit', + 'auto sizes cells', 'background color', 'bezel state', + 'bezel style', 'bezeled', 'border rect', 'border type', + 'bordered', 'bounds( rotation)?', 'box type', + 'button returned', 'button type', + 'can choose directories', 'can choose files', + 'can draw', 'can hide', + 'cell( (background color|size|type))?', 'characters', + 'class', 'click count', 'clicked( data)? column', + 'clicked data item', 'clicked( data)? row', + 'closeable', 'collating', 'color( (mode|panel))', + 'command key down', 'configuration', + 'content(s| (size|view( margins)?))?', 'context', + 'continuous', 'control key down', 'control size', + 'control tint', 'control view', + 'controller visible', 'coordinate system', + 'copies( on scroll)?', 'corner view', 'current cell', + 'current column', 'current( field)? editor', + 'current( menu)? item', 'current row', + 'current tab view item', 'data source', + 'default identifiers', 'delta (x|y|z)', + 'destination window', 'directory', 'display mode', + 'displayed cell', 'document( (edited|rect|view))?', + 'double value', 'dragged column', 'dragged distance', + 'dragged items', 'draws( cell)? background', + 'draws grid', 'dynamically scrolls', 'echos bullets', + 'edge', 'editable', 'edited( data)? column', + 'edited data item', 'edited( data)? row', 'enabled', + 'enclosing scroll view', 'ending page', + 'error handling', 'event number', 'event type', + 'excluded from windows menu', 'executable path', + 'expanded', 'fax number', 'field editor', 'file kind', + 'file name', 'file type', 'first responder', + 'first visible column', 'flipped', 'floating', + 'font( panel)?', 'formatter', 'frameworks path', + 'frontmost', 'gave up', 'grid color', 'has data items', + 'has horizontal ruler', 'has horizontal scroller', + 'has parent data item', 'has resize indicator', + 'has shadow', 'has sub menu', 'has vertical ruler', + 'has vertical scroller', 'header cell', 'header view', + 'hidden', 'hides when deactivated', 'highlights by', + 'horizontal line scroll', 'horizontal page scroll', + 'horizontal ruler view', 'horizontally resizable', + 'icon image', 'id', 'identifier', + 'ignores multiple clicks', + 'image( (alignment|dims when disabled|frame style|scaling))?', + 'imports graphics', 'increment value', + 'indentation per level', 'indeterminate', 'index', + 'integer value', 'intercell spacing', 'item height', + 'key( (code|equivalent( modifier)?|window))?', + 'knob thickness', 'label', 'last( visible)? column', + 'leading offset', 'leaf', 'level', 'line scroll', + 'loaded', 'localized sort', 'location', 'loop mode', + 'main( (bunde|menu|window))?', 'marker follows cell', + 'matrix mode', 'maximum( content)? size', + 'maximum visible columns', + 'menu( form representation)?', 'miniaturizable', + 'miniaturized', 'minimized image', 'minimized title', + 'minimum column width', 'minimum( content)? size', + 'modal', 'modified', 'mouse down state', + 'movie( (controller|file|rect))?', 'muted', 'name', + 'needs display', 'next state', 'next text', + 'number of tick marks', 'only tick mark values', + 'opaque', 'open panel', 'option key down', + 'outline table column', 'page scroll', 'pages across', + 'pages down', 'palette label', 'pane splitter', + 'parent data item', 'parent window', 'pasteboard', + 'path( (names|separator))?', 'playing', + 'plays every frame', 'plays selection only', 'position', + 'preferred edge', 'preferred type', 'pressure', + 'previous text', 'prompt', 'properties', + 'prototype cell', 'pulls down', 'rate', + 'released when closed', 'repeated', + 'requested print time', 'required file type', + 'resizable', 'resized column', 'resource path', + 'returns records', 'reuses columns', 'rich text', + 'roll over', 'row height', 'rulers visible', + 'save panel', 'scripts path', 'scrollable', + 'selectable( identifiers)?', 'selected cell', + 'selected( data)? columns?', 'selected data items?', + 'selected( data)? rows?', 'selected item identifier', + 'selection by rect', 'send action on arrow key', + 'sends action when done editing', 'separates columns', + 'separator item', 'sequence number', 'services menu', + 'shared frameworks path', 'shared support path', + 'sheet', 'shift key down', 'shows alpha', + 'shows state by', 'size( mode)?', + 'smart insert delete enabled', 'sort case sensitivity', + 'sort column', 'sort order', 'sort type', + 'sorted( data rows)?', 'sound', 'source( mask)?', + 'spell checking enabled', 'starting page', 'state', + 'string value', 'sub menu', 'super menu', 'super view', + 'tab key traverses cells', 'tab state', 'tab type', + 'tab view', 'table view', 'tag', 'target( printer)?', + 'text color', 'text container insert', + 'text container origin', 'text returned', + 'tick mark position', 'time stamp', + 'title(d| (cell|font|height|position|rect))?', + 'tool tip', 'toolbar', 'trailing offset', 'transparent', + 'treat packages as directories', 'truncated labels', + 'types', 'unmodified characters', 'update views', + 'use sort indicator', 'user defaults', + 'uses data source', 'uses ruler', + 'uses threaded animation', + 'uses title from previous column', 'value wraps', + 'version', + 'vertical( (line scroll|page scroll|ruler view))?', + 'vertically resizable', 'view', + 'visible( document rect)?', 'volume', 'width', 'window', + 'windows menu', 'wraps', 'zoomable', 'zoomed') + + tokens = { + 'root': [ + (r'\s+', Text), + (r'¬\n', String.Escape), + (r"'s\s+", Text), # This is a possessive, consider moving + (r'(--|#).*?$', Comment), + (r'\(\*', Comment.Multiline, 'comment'), + (r'[(){}!,.:]', Punctuation), + (r'(«)([^»]+)(»)', + bygroups(Text, Name.Builtin, Text)), + (r'\b((?:considering|ignoring)\s*)' + r'(application responses|case|diacriticals|hyphens|' + r'numeric strings|punctuation|white space)', + bygroups(Keyword, Name.Builtin)), + (r'(-|\*|\+|&|≠|>=?|<=?|=|≥|≤|/|÷|\^)', Operator), + (r"\b(%s)\b" % '|'.join(Operators), Operator.Word), + (r'^(\s*(?:on|end)\s+)' + r'(%s)' % '|'.join(StudioEvents[::-1]), + bygroups(Keyword, Name.Function)), + (r'^(\s*)(in|on|script|to)(\s+)', bygroups(Text, Keyword, Text)), + (r'\b(as )(%s)\b' % '|'.join(Classes), + bygroups(Keyword, Name.Class)), + (r'\b(%s)\b' % '|'.join(Literals), Name.Constant), + (r'\b(%s)\b' % '|'.join(Commands), Name.Builtin), + (r'\b(%s)\b' % '|'.join(Control), Keyword), + (r'\b(%s)\b' % '|'.join(Declarations), Keyword), + (r'\b(%s)\b' % '|'.join(Reserved), Name.Builtin), + (r'\b(%s)s?\b' % '|'.join(BuiltIn), Name.Builtin), + (r'\b(%s)\b' % '|'.join(HandlerParams), Name.Builtin), + (r'\b(%s)\b' % '|'.join(StudioProperties), Name.Attribute), + (r'\b(%s)s?\b' % '|'.join(StudioClasses), Name.Builtin), + (r'\b(%s)\b' % '|'.join(StudioCommands), Name.Builtin), + (r'\b(%s)\b' % '|'.join(References), Name.Builtin), + (r'"(\\\\|\\"|[^"])*"', String.Double), + (r'\b(%s)\b' % Identifiers, Name.Variable), + (r'[-+]?(\d+\.\d*|\d*\.\d+)(E[-+][0-9]+)?', Number.Float), + (r'[-+]?\d+', Number.Integer), + ], + 'comment': [ + (r'\(\*', Comment.Multiline, '#push'), + (r'\*\)', Comment.Multiline, '#pop'), + ('[^*(]+', Comment.Multiline), + ('[*(]', Comment.Multiline), + ], + } + + +class RexxLexer(RegexLexer): + """ + `Rexx `_ is a scripting language available for + a wide range of different platforms with its roots found on mainframe + systems. It is popular for I/O- and data based tasks and can act as glue + language to bind different applications together. + + .. versionadded:: 2.0 + """ + name = 'Rexx' + aliases = ['rexx', 'arexx'] + filenames = ['*.rexx', '*.rex', '*.rx', '*.arexx'] + mimetypes = ['text/x-rexx'] + flags = re.IGNORECASE + + tokens = { + 'root': [ + (r'\s', Whitespace), + (r'/\*', Comment.Multiline, 'comment'), + (r'"', String, 'string_double'), + (r"'", String, 'string_single'), + (r'[0-9]+(\.[0-9]+)?(e[+-]?[0-9])?', Number), + (r'([a-z_]\w*)(\s*)(:)(\s*)(procedure)\b', + bygroups(Name.Function, Whitespace, Operator, Whitespace, + Keyword.Declaration)), + (r'([a-z_]\w*)(\s*)(:)', + bygroups(Name.Label, Whitespace, Operator)), + include('function'), + include('keyword'), + include('operator'), + (r'[a-z_]\w*', Text), + ], + 'function': [ + (words(( + 'abbrev', 'abs', 'address', 'arg', 'b2x', 'bitand', 'bitor', 'bitxor', + 'c2d', 'c2x', 'center', 'charin', 'charout', 'chars', 'compare', + 'condition', 'copies', 'd2c', 'd2x', 'datatype', 'date', 'delstr', + 'delword', 'digits', 'errortext', 'form', 'format', 'fuzz', 'insert', + 'lastpos', 'left', 'length', 'linein', 'lineout', 'lines', 'max', + 'min', 'overlay', 'pos', 'queued', 'random', 'reverse', 'right', 'sign', + 'sourceline', 'space', 'stream', 'strip', 'substr', 'subword', 'symbol', + 'time', 'trace', 'translate', 'trunc', 'value', 'verify', 'word', + 'wordindex', 'wordlength', 'wordpos', 'words', 'x2b', 'x2c', 'x2d', + 'xrange'), suffix=r'(\s*)(\()'), + bygroups(Name.Builtin, Whitespace, Operator)), + ], + 'keyword': [ + (r'(address|arg|by|call|do|drop|else|end|exit|for|forever|if|' + r'interpret|iterate|leave|nop|numeric|off|on|options|parse|' + r'pull|push|queue|return|say|select|signal|to|then|trace|until|' + r'while)\b', Keyword.Reserved), + ], + 'operator': [ + (r'(-|//|/|\(|\)|\*\*|\*|\\<<|\\<|\\==|\\=|\\>>|\\>|\\|\|\||\||' + r'&&|&|%|\+|<<=|<<|<=|<>|<|==|=|><|>=|>>=|>>|>|¬<<|¬<|¬==|¬=|' + r'¬>>|¬>|¬|\.|,)', Operator), + ], + 'string_double': [ + (r'[^"\n]+', String), + (r'""', String), + (r'"', String, '#pop'), + (r'\n', Text, '#pop'), # Stray linefeed also terminates strings. + ], + 'string_single': [ + (r'[^\'\n]', String), + (r'\'\'', String), + (r'\'', String, '#pop'), + (r'\n', Text, '#pop'), # Stray linefeed also terminates strings. + ], + 'comment': [ + (r'[^*]+', Comment.Multiline), + (r'\*/', Comment.Multiline, '#pop'), + (r'\*', Comment.Multiline), + ] + } + + _c = lambda s: re.compile(s, re.MULTILINE) + _ADDRESS_COMMAND_PATTERN = _c(r'^\s*address\s+command\b') + _ADDRESS_PATTERN = _c(r'^\s*address\s+') + _DO_WHILE_PATTERN = _c(r'^\s*do\s+while\b') + _IF_THEN_DO_PATTERN = _c(r'^\s*if\b.+\bthen\s+do\s*$') + _PROCEDURE_PATTERN = _c(r'^\s*([a-z_]\w*)(\s*)(:)(\s*)(procedure)\b') + _ELSE_DO_PATTERN = _c(r'\belse\s+do\s*$') + _PARSE_ARG_PATTERN = _c(r'^\s*parse\s+(upper\s+)?(arg|value)\b') + PATTERNS_AND_WEIGHTS = ( + (_ADDRESS_COMMAND_PATTERN, 0.2), + (_ADDRESS_PATTERN, 0.05), + (_DO_WHILE_PATTERN, 0.1), + (_ELSE_DO_PATTERN, 0.1), + (_IF_THEN_DO_PATTERN, 0.1), + (_PROCEDURE_PATTERN, 0.5), + (_PARSE_ARG_PATTERN, 0.2), + ) + + def analyse_text(text): + """ + Check for inital comment and patterns that distinguish Rexx from other + C-like languages. + """ + if re.search(r'/\*\**\s*rexx', text, re.IGNORECASE): + # Header matches MVS Rexx requirements, this is certainly a Rexx + # script. + return 1.0 + elif text.startswith('/*'): + # Header matches general Rexx requirements; the source code might + # still be any language using C comments such as C++, C# or Java. + lowerText = text.lower() + result = sum(weight + for (pattern, weight) in RexxLexer.PATTERNS_AND_WEIGHTS + if pattern.search(lowerText)) + 0.01 + return min(result, 1.0) + + +class MOOCodeLexer(RegexLexer): + """ + For `MOOCode `_ (the MOO scripting + language). + + .. versionadded:: 0.9 + """ + name = 'MOOCode' + filenames = ['*.moo'] + aliases = ['moocode', 'moo'] + mimetypes = ['text/x-moocode'] + + tokens = { + 'root': [ + # Numbers + (r'(0|[1-9][0-9_]*)', Number.Integer), + # Strings + (r'"(\\\\|\\"|[^"])*"', String), + # exceptions + (r'(E_PERM|E_DIV)', Name.Exception), + # db-refs + (r'((#[-0-9]+)|(\$\w+))', Name.Entity), + # Keywords + (r'\b(if|else|elseif|endif|for|endfor|fork|endfork|while' + r'|endwhile|break|continue|return|try' + r'|except|endtry|finally|in)\b', Keyword), + # builtins + (r'(random|length)', Name.Builtin), + # special variables + (r'(player|caller|this|args)', Name.Variable.Instance), + # skip whitespace + (r'\s+', Text), + (r'\n', Text), + # other operators + (r'([!;=,{}&|:.\[\]@()<>?]+)', Operator), + # function call + (r'(\w+)(\()', bygroups(Name.Function, Operator)), + # variables + (r'(\w+)', Text), + ] + } + + +class HybrisLexer(RegexLexer): + """ + For `Hybris `_ source code. + + .. versionadded:: 1.4 + """ + + name = 'Hybris' + aliases = ['hybris', 'hy'] + filenames = ['*.hy', '*.hyb'] + mimetypes = ['text/x-hybris', 'application/x-hybris'] + + flags = re.MULTILINE | re.DOTALL + + tokens = { + 'root': [ + # method names + (r'^(\s*(?:function|method|operator\s+)+?)' + r'([a-zA-Z_]\w*)' + r'(\s*)(\()', bygroups(Keyword, Name.Function, Text, Operator)), + (r'[^\S\n]+', Text), + (r'//.*?\n', Comment.Single), + (r'/\*.*?\*/', Comment.Multiline), + (r'@[a-zA-Z_][\w.]*', Name.Decorator), + (r'(break|case|catch|next|default|do|else|finally|for|foreach|of|' + r'unless|if|new|return|switch|me|throw|try|while)\b', Keyword), + (r'(extends|private|protected|public|static|throws|function|method|' + r'operator)\b', Keyword.Declaration), + (r'(true|false|null|__FILE__|__LINE__|__VERSION__|__LIB_PATH__|' + r'__INC_PATH__)\b', Keyword.Constant), + (r'(class|struct)(\s+)', + bygroups(Keyword.Declaration, Text), 'class'), + (r'(import|include)(\s+)', + bygroups(Keyword.Namespace, Text), 'import'), + (words(( + 'gc_collect', 'gc_mm_items', 'gc_mm_usage', 'gc_collect_threshold', + 'urlencode', 'urldecode', 'base64encode', 'base64decode', 'sha1', 'crc32', + 'sha2', 'md5', 'md5_file', 'acos', 'asin', 'atan', 'atan2', 'ceil', 'cos', + 'cosh', 'exp', 'fabs', 'floor', 'fmod', 'log', 'log10', 'pow', 'sin', + 'sinh', 'sqrt', 'tan', 'tanh', 'isint', 'isfloat', 'ischar', 'isstring', + 'isarray', 'ismap', 'isalias', 'typeof', 'sizeof', 'toint', 'tostring', + 'fromxml', 'toxml', 'binary', 'pack', 'load', 'eval', 'var_names', + 'var_values', 'user_functions', 'dyn_functions', 'methods', 'call', + 'call_method', 'mknod', 'mkfifo', 'mount', 'umount2', 'umount', 'ticks', + 'usleep', 'sleep', 'time', 'strtime', 'strdate', 'dllopen', 'dlllink', + 'dllcall', 'dllcall_argv', 'dllclose', 'env', 'exec', 'fork', 'getpid', + 'wait', 'popen', 'pclose', 'exit', 'kill', 'pthread_create', + 'pthread_create_argv', 'pthread_exit', 'pthread_join', 'pthread_kill', + 'smtp_send', 'http_get', 'http_post', 'http_download', 'socket', 'bind', + 'listen', 'accept', 'getsockname', 'getpeername', 'settimeout', 'connect', + 'server', 'recv', 'send', 'close', 'print', 'println', 'printf', 'input', + 'readline', 'serial_open', 'serial_fcntl', 'serial_get_attr', + 'serial_get_ispeed', 'serial_get_ospeed', 'serial_set_attr', + 'serial_set_ispeed', 'serial_set_ospeed', 'serial_write', 'serial_read', + 'serial_close', 'xml_load', 'xml_parse', 'fopen', 'fseek', 'ftell', + 'fsize', 'fread', 'fwrite', 'fgets', 'fclose', 'file', 'readdir', + 'pcre_replace', 'size', 'pop', 'unmap', 'has', 'keys', 'values', + 'length', 'find', 'substr', 'replace', 'split', 'trim', 'remove', + 'contains', 'join'), suffix=r'\b'), + Name.Builtin), + (words(( + 'MethodReference', 'Runner', 'Dll', 'Thread', 'Pipe', 'Process', + 'Runnable', 'CGI', 'ClientSocket', 'Socket', 'ServerSocket', + 'File', 'Console', 'Directory', 'Exception'), suffix=r'\b'), + Keyword.Type), + (r'"(\\\\|\\"|[^"])*"', String), + (r"'\\.'|'[^\\]'|'\\u[0-9a-f]{4}'", String.Char), + (r'(\.)([a-zA-Z_]\w*)', + bygroups(Operator, Name.Attribute)), + (r'[a-zA-Z_]\w*:', Name.Label), + (r'[a-zA-Z_$]\w*', Name), + (r'[~^*!%&\[\](){}<>|+=:;,./?\-@]+', Operator), + (r'[0-9][0-9]*\.[0-9]+([eE][0-9]+)?[fd]?', Number.Float), + (r'0x[0-9a-f]+', Number.Hex), + (r'[0-9]+L?', Number.Integer), + (r'\n', Text), + ], + 'class': [ + (r'[a-zA-Z_]\w*', Name.Class, '#pop') + ], + 'import': [ + (r'[\w.]+\*?', Name.Namespace, '#pop') + ], + } + + def analyse_text(text): + """public method and private method don't seem to be quite common + elsewhere.""" + result = 0 + if re.search(r'\b(?:public|private)\s+method\b', text): + result += 0.01 + return result + + + +class EasytrieveLexer(RegexLexer): + """ + Easytrieve Plus is a programming language for extracting, filtering and + converting sequential data. Furthermore it can layout data for reports. + It is mainly used on mainframe platforms and can access several of the + mainframe's native file formats. It is somewhat comparable to awk. + + .. versionadded:: 2.1 + """ + name = 'Easytrieve' + aliases = ['easytrieve'] + filenames = ['*.ezt', '*.mac'] + mimetypes = ['text/x-easytrieve'] + flags = 0 + + # Note: We cannot use r'\b' at the start and end of keywords because + # Easytrieve Plus delimiter characters are: + # + # * space ( ) + # * apostrophe (') + # * period (.) + # * comma (,) + # * paranthesis ( and ) + # * colon (:) + # + # Additionally words end once a '*' appears, indicatins a comment. + _DELIMITERS = r' \'.,():\n' + _DELIMITERS_OR_COMENT = _DELIMITERS + '*' + _DELIMITER_PATTERN = '[' + _DELIMITERS + ']' + _DELIMITER_PATTERN_CAPTURE = '(' + _DELIMITER_PATTERN + ')' + _NON_DELIMITER_OR_COMMENT_PATTERN = '[^' + _DELIMITERS_OR_COMENT + ']' + _OPERATORS_PATTERN = '[.+\\-/=\\[\\](){}<>;,&%¬]' + _KEYWORDS = [ + 'AFTER-BREAK', 'AFTER-LINE', 'AFTER-SCREEN', 'AIM', 'AND', 'ATTR', + 'BEFORE', 'BEFORE-BREAK', 'BEFORE-LINE', 'BEFORE-SCREEN', 'BUSHU', + 'BY', 'CALL', 'CASE', 'CHECKPOINT', 'CHKP', 'CHKP-STATUS', 'CLEAR', + 'CLOSE', 'COL', 'COLOR', 'COMMIT', 'CONTROL', 'COPY', 'CURSOR', 'D', + 'DECLARE', 'DEFAULT', 'DEFINE', 'DELETE', 'DENWA', 'DISPLAY', 'DLI', + 'DO', 'DUPLICATE', 'E', 'ELSE', 'ELSE-IF', 'END', 'END-CASE', + 'END-DO', 'END-IF', 'END-PROC', 'ENDPAGE', 'ENDTABLE', 'ENTER', 'EOF', + 'EQ', 'ERROR', 'EXIT', 'EXTERNAL', 'EZLIB', 'F1', 'F10', 'F11', 'F12', + 'F13', 'F14', 'F15', 'F16', 'F17', 'F18', 'F19', 'F2', 'F20', 'F21', + 'F22', 'F23', 'F24', 'F25', 'F26', 'F27', 'F28', 'F29', 'F3', 'F30', + 'F31', 'F32', 'F33', 'F34', 'F35', 'F36', 'F4', 'F5', 'F6', 'F7', + 'F8', 'F9', 'FETCH', 'FILE-STATUS', 'FILL', 'FINAL', 'FIRST', + 'FIRST-DUP', 'FOR', 'GE', 'GET', 'GO', 'GOTO', 'GQ', 'GR', 'GT', + 'HEADING', 'HEX', 'HIGH-VALUES', 'IDD', 'IDMS', 'IF', 'IN', 'INSERT', + 'JUSTIFY', 'KANJI-DATE', 'KANJI-DATE-LONG', 'KANJI-TIME', 'KEY', + 'KEY-PRESSED', 'KOKUGO', 'KUN', 'LAST-DUP', 'LE', 'LEVEL', 'LIKE', + 'LINE', 'LINE-COUNT', 'LINE-NUMBER', 'LINK', 'LIST', 'LOW-VALUES', + 'LQ', 'LS', 'LT', 'MACRO', 'MASK', 'MATCHED', 'MEND', 'MESSAGE', + 'MOVE', 'MSTART', 'NE', 'NEWPAGE', 'NOMASK', 'NOPRINT', 'NOT', + 'NOTE', 'NOVERIFY', 'NQ', 'NULL', 'OF', 'OR', 'OTHERWISE', 'PA1', + 'PA2', 'PA3', 'PAGE-COUNT', 'PAGE-NUMBER', 'PARM-REGISTER', + 'PATH-ID', 'PATTERN', 'PERFORM', 'POINT', 'POS', 'PRIMARY', 'PRINT', + 'PROCEDURE', 'PROGRAM', 'PUT', 'READ', 'RECORD', 'RECORD-COUNT', + 'RECORD-LENGTH', 'REFRESH', 'RELEASE', 'RENUM', 'REPEAT', 'REPORT', + 'REPORT-INPUT', 'RESHOW', 'RESTART', 'RETRIEVE', 'RETURN-CODE', + 'ROLLBACK', 'ROW', 'S', 'SCREEN', 'SEARCH', 'SECONDARY', 'SELECT', + 'SEQUENCE', 'SIZE', 'SKIP', 'SOKAKU', 'SORT', 'SQL', 'STOP', 'SUM', + 'SYSDATE', 'SYSDATE-LONG', 'SYSIN', 'SYSIPT', 'SYSLST', 'SYSPRINT', + 'SYSSNAP', 'SYSTIME', 'TALLY', 'TERM-COLUMNS', 'TERM-NAME', + 'TERM-ROWS', 'TERMINATION', 'TITLE', 'TO', 'TRANSFER', 'TRC', + 'UNIQUE', 'UNTIL', 'UPDATE', 'UPPERCASE', 'USER', 'USERID', 'VALUE', + 'VERIFY', 'W', 'WHEN', 'WHILE', 'WORK', 'WRITE', 'X', 'XDM', 'XRST' + ] + + tokens = { + 'root': [ + (r'\*.*\n', Comment.Single), + (r'\n+', Whitespace), + # Macro argument + (r'&' + _NON_DELIMITER_OR_COMMENT_PATTERN + r'+\.', Name.Variable, + 'after_macro_argument'), + # Macro call + (r'%' + _NON_DELIMITER_OR_COMMENT_PATTERN + r'+', Name.Variable), + (r'(FILE|MACRO|REPORT)(\s+)', + bygroups(Keyword.Declaration, Whitespace), 'after_declaration'), + (r'(JOB|PARM)' + r'(' + _DELIMITER_PATTERN + r')', + bygroups(Keyword.Declaration, Operator)), + (words(_KEYWORDS, suffix=_DELIMITER_PATTERN_CAPTURE), + bygroups(Keyword.Reserved, Operator)), + (_OPERATORS_PATTERN, Operator), + # Procedure declaration + (r'(' + _NON_DELIMITER_OR_COMMENT_PATTERN + r'+)(\s*)(\.?)(\s*)(PROC)(\s*\n)', + bygroups(Name.Function, Whitespace, Operator, Whitespace, + Keyword.Declaration, Whitespace)), + (r'[0-9]+\.[0-9]*', Number.Float), + (r'[0-9]+', Number.Integer), + (r"'(''|[^'])*'", String), + (r'\s+', Whitespace), + # Everything else just belongs to a name + (_NON_DELIMITER_OR_COMMENT_PATTERN + r'+', Name), + ], + 'after_declaration': [ + (_NON_DELIMITER_OR_COMMENT_PATTERN + r'+', Name.Function), + default('#pop'), + ], + 'after_macro_argument': [ + (r'\*.*\n', Comment.Single, '#pop'), + (r'\s+', Whitespace, '#pop'), + (_OPERATORS_PATTERN, Operator, '#pop'), + (r"'(''|[^'])*'", String, '#pop'), + # Everything else just belongs to a name + (_NON_DELIMITER_OR_COMMENT_PATTERN + r'+', Name), + ], + } + _COMMENT_LINE_REGEX = re.compile(r'^\s*\*') + _MACRO_HEADER_REGEX = re.compile(r'^\s*MACRO') + + def analyse_text(text): + """ + Perform a structural analysis for basic Easytrieve constructs. + """ + result = 0.0 + lines = text.split('\n') + hasEndProc = False + hasHeaderComment = False + hasFile = False + hasJob = False + hasProc = False + hasParm = False + hasReport = False + + def isCommentLine(line): + return EasytrieveLexer._COMMENT_LINE_REGEX.match(lines[0]) is not None + + def isEmptyLine(line): + return not bool(line.strip()) + + # Remove possible empty lines and header comments. + while lines and (isEmptyLine(lines[0]) or isCommentLine(lines[0])): + if not isEmptyLine(lines[0]): + hasHeaderComment = True + del lines[0] + + if EasytrieveLexer._MACRO_HEADER_REGEX.match(lines[0]): + # Looks like an Easytrieve macro. + result = 0.4 + if hasHeaderComment: + result += 0.4 + else: + # Scan the source for lines starting with indicators. + for line in lines: + words = line.split() + if (len(words) >= 2): + firstWord = words[0] + if not hasReport: + if not hasJob: + if not hasFile: + if not hasParm: + if firstWord == 'PARM': + hasParm = True + if firstWord == 'FILE': + hasFile = True + if firstWord == 'JOB': + hasJob = True + elif firstWord == 'PROC': + hasProc = True + elif firstWord == 'END-PROC': + hasEndProc = True + elif firstWord == 'REPORT': + hasReport = True + + # Weight the findings. + if hasJob and (hasProc == hasEndProc): + if hasHeaderComment: + result += 0.1 + if hasParm: + if hasProc: + # Found PARM, JOB and PROC/END-PROC: + # pretty sure this is Easytrieve. + result += 0.8 + else: + # Found PARAM and JOB: probably this is Easytrieve + result += 0.5 + else: + # Found JOB and possibly other keywords: might be Easytrieve + result += 0.11 + if hasParm: + # Note: PARAM is not a proper English word, so this is + # regarded a much better indicator for Easytrieve than + # the other words. + result += 0.2 + if hasFile: + result += 0.01 + if hasReport: + result += 0.01 + assert 0.0 <= result <= 1.0 + return result + + +class JclLexer(RegexLexer): + """ + `Job Control Language (JCL) + `_ + is a scripting language used on mainframe platforms to instruct the system + on how to run a batch job or start a subsystem. It is somewhat + comparable to MS DOS batch and Unix shell scripts. + + .. versionadded:: 2.1 + """ + name = 'JCL' + aliases = ['jcl'] + filenames = ['*.jcl'] + mimetypes = ['text/x-jcl'] + flags = re.IGNORECASE + + tokens = { + 'root': [ + (r'//\*.*\n', Comment.Single), + (r'//', Keyword.Pseudo, 'statement'), + (r'/\*', Keyword.Pseudo, 'jes2_statement'), + # TODO: JES3 statement + (r'.*\n', Other) # Input text or inline code in any language. + ], + 'statement': [ + (r'\s*\n', Whitespace, '#pop'), + (r'([a-z]\w*)(\s+)(exec|job)(\s*)', + bygroups(Name.Label, Whitespace, Keyword.Reserved, Whitespace), + 'option'), + (r'[a-z]\w*', Name.Variable, 'statement_command'), + (r'\s+', Whitespace, 'statement_command'), + ], + 'statement_command': [ + (r'\s+(command|cntl|dd|endctl|endif|else|include|jcllib|' + r'output|pend|proc|set|then|xmit)\s+', Keyword.Reserved, 'option'), + include('option') + ], + 'jes2_statement': [ + (r'\s*\n', Whitespace, '#pop'), + (r'\$', Keyword, 'option'), + (r'\b(jobparam|message|netacct|notify|output|priority|route|' + r'setup|signoff|xeq|xmit)\b', Keyword, 'option'), + ], + 'option': [ + # (r'\n', Text, 'root'), + (r'\*', Name.Builtin), + (r'[\[\](){}<>;,]', Punctuation), + (r'[-+*/=&%]', Operator), + (r'[a-z_]\w*', Name), + (r'\d+\.\d*', Number.Float), + (r'\.\d+', Number.Float), + (r'\d+', Number.Integer), + (r"'", String, 'option_string'), + (r'[ \t]+', Whitespace, 'option_comment'), + (r'\.', Punctuation), + ], + 'option_string': [ + (r"(\n)(//)", bygroups(Text, Keyword.Pseudo)), + (r"''", String), + (r"[^']", String), + (r"'", String, '#pop'), + ], + 'option_comment': [ + # (r'\n', Text, 'root'), + (r'.+', Comment.Single), + ] + } + + _JOB_HEADER_PATTERN = re.compile(r'^//[a-z#$@][a-z0-9#$@]{0,7}\s+job(\s+.*)?$', + re.IGNORECASE) + + def analyse_text(text): + """ + Recognize JCL job by header. + """ + result = 0.0 + lines = text.split('\n') + if len(lines) > 0: + if JclLexer._JOB_HEADER_PATTERN.match(lines[0]): + result = 1.0 + assert 0.0 <= result <= 1.0 + return result + + +class MiniScriptLexer(RegexLexer): + """ + For `MiniScript `_ source code. + + .. versionadded:: 2.6 + """ + + name = "MiniScript" + aliases = ["ms", "miniscript"] + filenames = ["*.ms"] + mimetypes = ['text/x-minicript', 'application/x-miniscript'] + + tokens = { + 'root': [ + (r'#!(.*?)$', Comment.Preproc), + default('base'), + ], + 'base': [ + ('//.*$', Comment.Single), + (r'(?i)(\d*\.\d+|\d+\.\d*)(e[+-]?\d+)?', Number), + (r'(?i)\d+e[+-]?\d+', Number), + (r'\d+', Number), + (r'\n', Text), + (r'[^\S\n]+', Text), + (r'"', String, 'string_double'), + (r'(==|!=|<=|>=|[=+\-*/%^<>.:])', Operator), + (r'[;,\[\]{}()]', Punctuation), + (words(( + 'break', 'continue', 'else', 'end', 'for', 'function', 'if', + 'in', 'isa', 'then', 'repeat', 'return', 'while'), suffix=r'\b'), + Keyword), + (words(( + 'abs', 'acos', 'asin', 'atan', 'ceil', 'char', 'cos', 'floor', + 'log', 'round', 'rnd', 'pi', 'sign', 'sin', 'sqrt', 'str', 'tan', + 'hasIndex', 'indexOf', 'len', 'val', 'code', 'remove', 'lower', + 'upper', 'replace', 'split', 'indexes', 'values', 'join', 'sum', + 'sort', 'shuffle', 'push', 'pop', 'pull', 'range', + 'print', 'input', 'time', 'wait', 'locals', 'globals', 'outer', + 'yield'), suffix=r'\b'), + Name.Builtin), + (r'(true|false|null)\b', Keyword.Constant), + (r'(and|or|not|new)\b', Operator.Word), + (r'(self|super|__isa)\b', Name.Builtin.Pseudo), + (r'[a-zA-Z_]\w*', Name.Variable) + ], + 'string_double': [ + (r'[^"\n]+', String), + (r'""', String), + (r'"', String, '#pop'), + (r'\n', Text, '#pop'), # Stray linefeed also terminates strings. + ] + } diff --git a/.venv/lib/python3.8/site-packages/pygments/lexers/sgf.py b/.venv/lib/python3.8/site-packages/pygments/lexers/sgf.py new file mode 100644 index 00000000..6dfd275a --- /dev/null +++ b/.venv/lib/python3.8/site-packages/pygments/lexers/sgf.py @@ -0,0 +1,61 @@ +# -*- coding: utf-8 -*- +""" + pygments.lexers.sgf + ~~~~~~~~~~~~~~~~~~~ + + Lexer for Smart Game Format (sgf) file format. + + :copyright: Copyright 2006-2020 by the Pygments team, see AUTHORS. + :license: BSD, see LICENSE for details. +""" + +from pygments.lexer import RegexLexer, bygroups +from pygments.token import Name, Literal, String, Text, Punctuation + +__all__ = ["SmartGameFormatLexer"] + + +class SmartGameFormatLexer(RegexLexer): + """ + Lexer for Smart Game Format (sgf) file format. + + The format is used to store game records of board games for two players + (mainly Go game). + For more information about the definition of the format, see: + https://www.red-bean.com/sgf/ + + .. versionadded:: 2.4 + """ + name = 'SmartGameFormat' + aliases = ['sgf'] + filenames = ['*.sgf'] + + tokens = { + 'root': [ + (r'[\s():;]', Punctuation), + # tokens: + (r'(A[BW]|AE|AN|AP|AR|AS|[BW]L|BM|[BW]R|[BW]S|[BW]T|CA|CH|CP|CR|' + r'DD|DM|DO|DT|EL|EV|EX|FF|FG|G[BW]|GC|GM|GN|HA|HO|ID|IP|IT|IY|KM|' + r'KO|LB|LN|LT|L|MA|MN|M|N|OB|OM|ON|OP|OT|OV|P[BW]|PC|PL|PM|RE|RG|' + r'RO|RU|SO|SC|SE|SI|SL|SO|SQ|ST|SU|SZ|T[BW]|TC|TE|TM|TR|UC|US|VW|' + r'V|[BW]|C)', + Name.Builtin), + # number: + (r'(\[)([0-9.]+)(\])', + bygroups(Punctuation, Literal.Number, Punctuation)), + # date: + (r'(\[)([0-9]{4}-[0-9]{2}-[0-9]{2})(\])', + bygroups(Punctuation, Literal.Date, Punctuation)), + # point: + (r'(\[)([a-z]{2})(\])', + bygroups(Punctuation, String, Punctuation)), + # double points: + (r'(\[)([a-z]{2})(:)([a-z]{2})(\])', + bygroups(Punctuation, String, Punctuation, String, Punctuation)), + + (r'(\[)([\w\s#()+,\-.:?]+)(\])', + bygroups(Punctuation, String, Punctuation)), + (r'(\[)(\s.*)(\])', + bygroups(Punctuation, Text, Punctuation)), + ], + } diff --git a/.venv/lib/python3.8/site-packages/pygments/lexers/shell.py b/.venv/lib/python3.8/site-packages/pygments/lexers/shell.py new file mode 100644 index 00000000..713d4321 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/pygments/lexers/shell.py @@ -0,0 +1,914 @@ +# -*- coding: utf-8 -*- +""" + pygments.lexers.shell + ~~~~~~~~~~~~~~~~~~~~~ + + Lexers for various shells. + + :copyright: Copyright 2006-2020 by the Pygments team, see AUTHORS. + :license: BSD, see LICENSE for details. +""" + +import re + +from pygments.lexer import Lexer, RegexLexer, do_insertions, bygroups, \ + include, default, this, using, words +from pygments.token import Punctuation, \ + Text, Comment, Operator, Keyword, Name, String, Number, Generic +from pygments.util import shebang_matches + + +__all__ = ['BashLexer', 'BashSessionLexer', 'TcshLexer', 'BatchLexer', + 'SlurmBashLexer', 'MSDOSSessionLexer', 'PowerShellLexer', + 'PowerShellSessionLexer', 'TcshSessionLexer', 'FishShellLexer', + 'ExeclineLexer'] + +line_re = re.compile('.*?\n') + + +class BashLexer(RegexLexer): + """ + Lexer for (ba|k|z|)sh shell scripts. + + .. versionadded:: 0.6 + """ + + name = 'Bash' + aliases = ['bash', 'sh', 'ksh', 'zsh', 'shell'] + filenames = ['*.sh', '*.ksh', '*.bash', '*.ebuild', '*.eclass', + '*.exheres-0', '*.exlib', '*.zsh', + '.bashrc', 'bashrc', '.bash_*', 'bash_*', 'zshrc', '.zshrc', + 'PKGBUILD'] + mimetypes = ['application/x-sh', 'application/x-shellscript', 'text/x-shellscript'] + + tokens = { + 'root': [ + include('basic'), + (r'`', String.Backtick, 'backticks'), + include('data'), + include('interp'), + ], + 'interp': [ + (r'\$\(\(', Keyword, 'math'), + (r'\$\(', Keyword, 'paren'), + (r'\$\{#?', String.Interpol, 'curly'), + (r'\$[a-zA-Z_]\w*', Name.Variable), # user variable + (r'\$(?:\d+|[#$?!_*@-])', Name.Variable), # builtin + (r'\$', Text), + ], + 'basic': [ + (r'\b(if|fi|else|while|do|done|for|then|return|function|case|' + r'select|continue|until|esac|elif)(\s*)\b', + bygroups(Keyword, Text)), + (r'\b(alias|bg|bind|break|builtin|caller|cd|command|compgen|' + r'complete|declare|dirs|disown|echo|enable|eval|exec|exit|' + r'export|false|fc|fg|getopts|hash|help|history|jobs|kill|let|' + r'local|logout|popd|printf|pushd|pwd|read|readonly|set|shift|' + r'shopt|source|suspend|test|time|times|trap|true|type|typeset|' + r'ulimit|umask|unalias|unset|wait)(?=[\s)`])', + Name.Builtin), + (r'\A#!.+\n', Comment.Hashbang), + (r'#.*\n', Comment.Single), + (r'\\[\w\W]', String.Escape), + (r'(\b\w+)(\s*)(\+?=)', bygroups(Name.Variable, Text, Operator)), + (r'[\[\]{}()=]', Operator), + (r'<<<', Operator), # here-string + (r'<<-?\s*(\'?)\\?(\w+)[\w\W]+?\2', String), + (r'&&|\|\|', Operator), + ], + 'data': [ + (r'(?s)\$?"(\\.|[^"\\$])*"', String.Double), + (r'"', String.Double, 'string'), + (r"(?s)\$'(\\\\|\\[0-7]+|\\.|[^'\\])*'", String.Single), + (r"(?s)'.*?'", String.Single), + (r';', Punctuation), + (r'&', Punctuation), + (r'\|', Punctuation), + (r'\s+', Text), + (r'\d+\b', Number), + (r'[^=\s\[\]{}()$"\'`\\<&|;]+', Text), + (r'<', Text), + ], + 'string': [ + (r'"', String.Double, '#pop'), + (r'(?s)(\\\\|\\[0-7]+|\\.|[^"\\$])+', String.Double), + include('interp'), + ], + 'curly': [ + (r'\}', String.Interpol, '#pop'), + (r':-', Keyword), + (r'\w+', Name.Variable), + (r'[^}:"\'`$\\]+', Punctuation), + (r':', Punctuation), + include('root'), + ], + 'paren': [ + (r'\)', Keyword, '#pop'), + include('root'), + ], + 'math': [ + (r'\)\)', Keyword, '#pop'), + (r'[-+*/%^|&]|\*\*|\|\|', Operator), + (r'\d+#\d+', Number), + (r'\d+#(?! )', Number), + (r'\d+', Number), + include('root'), + ], + 'backticks': [ + (r'`', String.Backtick, '#pop'), + include('root'), + ], + } + + def analyse_text(text): + if shebang_matches(text, r'(ba|z|)sh'): + return 1 + if text.startswith('$ '): + return 0.2 + + +class SlurmBashLexer(BashLexer): + """ + Lexer for (ba|k|z|)sh Slurm scripts. + + .. versionadded:: 2.4 + """ + + name = 'Slurm' + aliases = ['slurm', 'sbatch'] + filenames = ['*.sl'] + mimetypes = [] + EXTRA_KEYWORDS = {'srun'} + + def get_tokens_unprocessed(self, text): + for index, token, value in BashLexer.get_tokens_unprocessed(self, text): + if token is Text and value in self.EXTRA_KEYWORDS: + yield index, Name.Builtin, value + elif token is Comment.Single and 'SBATCH' in value: + yield index, Keyword.Pseudo, value + else: + yield index, token, value + + +class ShellSessionBaseLexer(Lexer): + """ + Base lexer for shell sessions. + + .. versionadded:: 2.1 + """ + + _venv = re.compile(r'^(\([^)]*\))(\s*)') + + def get_tokens_unprocessed(self, text): + innerlexer = self._innerLexerCls(**self.options) + + pos = 0 + curcode = '' + insertions = [] + backslash_continuation = False + + for match in line_re.finditer(text): + line = match.group() + if backslash_continuation: + curcode += line + backslash_continuation = curcode.endswith('\\\n') + continue + + venv_match = self._venv.match(line) + if venv_match: + venv = venv_match.group(1) + venv_whitespace = venv_match.group(2) + insertions.append((len(curcode), + [(0, Generic.Prompt.VirtualEnv, venv)])) + if venv_whitespace: + insertions.append((len(curcode), + [(0, Text, venv_whitespace)])) + line = line[venv_match.end():] + + m = self._ps1rgx.match(line) + if m: + # To support output lexers (say diff output), the output + # needs to be broken by prompts whenever the output lexer + # changes. + if not insertions: + pos = match.start() + + insertions.append((len(curcode), + [(0, Generic.Prompt, m.group(1))])) + curcode += m.group(2) + backslash_continuation = curcode.endswith('\\\n') + elif line.startswith(self._ps2): + insertions.append((len(curcode), + [(0, Generic.Prompt, line[:len(self._ps2)])])) + curcode += line[len(self._ps2):] + backslash_continuation = curcode.endswith('\\\n') + else: + if insertions: + toks = innerlexer.get_tokens_unprocessed(curcode) + for i, t, v in do_insertions(insertions, toks): + yield pos+i, t, v + yield match.start(), Generic.Output, line + insertions = [] + curcode = '' + if insertions: + for i, t, v in do_insertions(insertions, + innerlexer.get_tokens_unprocessed(curcode)): + yield pos+i, t, v + + +class BashSessionLexer(ShellSessionBaseLexer): + """ + Lexer for Bash shell sessions, i.e. command lines, including a + prompt, interspersed with output. + + .. versionadded:: 1.1 + """ + + name = 'Bash Session' + aliases = ['console', 'shell-session'] + filenames = ['*.sh-session', '*.shell-session'] + mimetypes = ['application/x-shell-session', 'application/x-sh-session'] + + _innerLexerCls = BashLexer + _ps1rgx = re.compile( + r'^((?:(?:\[.*?\])|(?:\(\S+\))?(?:| |sh\S*?|\w+\S+[@:]\S+(?:\s+\S+)' \ + r'?|\[\S+[@:][^\n]+\].+))\s*[$#%])(.*\n?)') + _ps2 = '>' + + +class BatchLexer(RegexLexer): + """ + Lexer for the DOS/Windows Batch file format. + + .. versionadded:: 0.7 + """ + name = 'Batchfile' + aliases = ['bat', 'batch', 'dosbatch', 'winbatch'] + filenames = ['*.bat', '*.cmd'] + mimetypes = ['application/x-dos-batch'] + + flags = re.MULTILINE | re.IGNORECASE + + _nl = r'\n\x1a' + _punct = r'&<>|' + _ws = r'\t\v\f\r ,;=\xa0' + _nlws = r'\s\x1a\xa0,;=' + _space = r'(?:(?:(?:\^[%s])?[%s])+)' % (_nl, _ws) + _keyword_terminator = (r'(?=(?:\^[%s]?)?[%s+./:[\\\]]|[%s%s(])' % + (_nl, _ws, _nl, _punct)) + _token_terminator = r'(?=\^?[%s]|[%s%s])' % (_ws, _punct, _nl) + _start_label = r'((?:(?<=^[^:])|^[^:]?)[%s]*)(:)' % _ws + _label = r'(?:(?:[^%s%s+:^]|\^[%s]?[\w\W])*)' % (_nlws, _punct, _nl) + _label_compound = r'(?:(?:[^%s%s+:^)]|\^[%s]?[^)])*)' % (_nlws, _punct, _nl) + _number = r'(?:-?(?:0[0-7]+|0x[\da-f]+|\d+)%s)' % _token_terminator + _opword = r'(?:equ|geq|gtr|leq|lss|neq)' + _string = r'(?:"[^%s"]*(?:"|(?=[%s])))' % (_nl, _nl) + _variable = (r'(?:(?:%%(?:\*|(?:~[a-z]*(?:\$[^:]+:)?)?\d|' + r'[^%%:%s]+(?::(?:~(?:-?\d+)?(?:,(?:-?\d+)?)?|(?:[^%%%s^]|' + r'\^[^%%%s])[^=%s]*=(?:[^%%%s^]|\^[^%%%s])*)?)?%%))|' + r'(?:\^?![^!:%s]+(?::(?:~(?:-?\d+)?(?:,(?:-?\d+)?)?|(?:' + r'[^!%s^]|\^[^!%s])[^=%s]*=(?:[^!%s^]|\^[^!%s])*)?)?\^?!))' % + (_nl, _nl, _nl, _nl, _nl, _nl, _nl, _nl, _nl, _nl, _nl, _nl)) + _core_token = r'(?:(?:(?:\^[%s]?)?[^"%s%s])+)' % (_nl, _nlws, _punct) + _core_token_compound = r'(?:(?:(?:\^[%s]?)?[^"%s%s)])+)' % (_nl, _nlws, _punct) + _token = r'(?:[%s]+|%s)' % (_punct, _core_token) + _token_compound = r'(?:[%s]+|%s)' % (_punct, _core_token_compound) + _stoken = (r'(?:[%s]+|(?:%s|%s|%s)+)' % + (_punct, _string, _variable, _core_token)) + + def _make_begin_state(compound, _core_token=_core_token, + _core_token_compound=_core_token_compound, + _keyword_terminator=_keyword_terminator, + _nl=_nl, _punct=_punct, _string=_string, + _space=_space, _start_label=_start_label, + _stoken=_stoken, _token_terminator=_token_terminator, + _variable=_variable, _ws=_ws): + rest = '(?:%s|%s|[^"%%%s%s%s])*' % (_string, _variable, _nl, _punct, + ')' if compound else '') + rest_of_line = r'(?:(?:[^%s^]|\^[%s]?[\w\W])*)' % (_nl, _nl) + rest_of_line_compound = r'(?:(?:[^%s^)]|\^[%s]?[^)])*)' % (_nl, _nl) + set_space = r'((?:(?:\^[%s]?)?[^\S\n])*)' % _nl + suffix = '' + if compound: + _keyword_terminator = r'(?:(?=\))|%s)' % _keyword_terminator + _token_terminator = r'(?:(?=\))|%s)' % _token_terminator + suffix = '/compound' + return [ + ((r'\)', Punctuation, '#pop') if compound else + (r'\)((?=\()|%s)%s' % (_token_terminator, rest_of_line), + Comment.Single)), + (r'(?=%s)' % _start_label, Text, 'follow%s' % suffix), + (_space, using(this, state='text')), + include('redirect%s' % suffix), + (r'[%s]+' % _nl, Text), + (r'\(', Punctuation, 'root/compound'), + (r'@+', Punctuation), + (r'((?:for|if|rem)(?:(?=(?:\^[%s]?)?/)|(?:(?!\^)|' + r'(?<=m))(?:(?=\()|%s)))(%s?%s?(?:\^[%s]?)?/(?:\^[%s]?)?\?)' % + (_nl, _token_terminator, _space, + _core_token_compound if compound else _core_token, _nl, _nl), + bygroups(Keyword, using(this, state='text')), + 'follow%s' % suffix), + (r'(goto%s)(%s(?:\^[%s]?)?/(?:\^[%s]?)?\?%s)' % + (_keyword_terminator, rest, _nl, _nl, rest), + bygroups(Keyword, using(this, state='text')), + 'follow%s' % suffix), + (words(('assoc', 'break', 'cd', 'chdir', 'cls', 'color', 'copy', + 'date', 'del', 'dir', 'dpath', 'echo', 'endlocal', 'erase', + 'exit', 'ftype', 'keys', 'md', 'mkdir', 'mklink', 'move', + 'path', 'pause', 'popd', 'prompt', 'pushd', 'rd', 'ren', + 'rename', 'rmdir', 'setlocal', 'shift', 'start', 'time', + 'title', 'type', 'ver', 'verify', 'vol'), + suffix=_keyword_terminator), Keyword, 'follow%s' % suffix), + (r'(call)(%s?)(:)' % _space, + bygroups(Keyword, using(this, state='text'), Punctuation), + 'call%s' % suffix), + (r'call%s' % _keyword_terminator, Keyword), + (r'(for%s(?!\^))(%s)(/f%s)' % + (_token_terminator, _space, _token_terminator), + bygroups(Keyword, using(this, state='text'), Keyword), + ('for/f', 'for')), + (r'(for%s(?!\^))(%s)(/l%s)' % + (_token_terminator, _space, _token_terminator), + bygroups(Keyword, using(this, state='text'), Keyword), + ('for/l', 'for')), + (r'for%s(?!\^)' % _token_terminator, Keyword, ('for2', 'for')), + (r'(goto%s)(%s?)(:?)' % (_keyword_terminator, _space), + bygroups(Keyword, using(this, state='text'), Punctuation), + 'label%s' % suffix), + (r'(if(?:(?=\()|%s)(?!\^))(%s?)((?:/i%s)?)(%s?)((?:not%s)?)(%s?)' % + (_token_terminator, _space, _token_terminator, _space, + _token_terminator, _space), + bygroups(Keyword, using(this, state='text'), Keyword, + using(this, state='text'), Keyword, + using(this, state='text')), ('(?', 'if')), + (r'rem(((?=\()|%s)%s?%s?.*|%s%s)' % + (_token_terminator, _space, _stoken, _keyword_terminator, + rest_of_line_compound if compound else rest_of_line), + Comment.Single, 'follow%s' % suffix), + (r'(set%s)%s(/a)' % (_keyword_terminator, set_space), + bygroups(Keyword, using(this, state='text'), Keyword), + 'arithmetic%s' % suffix), + (r'(set%s)%s((?:/p)?)%s((?:(?:(?:\^[%s]?)?[^"%s%s^=%s]|' + r'\^[%s]?[^"=])+)?)((?:(?:\^[%s]?)?=)?)' % + (_keyword_terminator, set_space, set_space, _nl, _nl, _punct, + ')' if compound else '', _nl, _nl), + bygroups(Keyword, using(this, state='text'), Keyword, + using(this, state='text'), using(this, state='variable'), + Punctuation), + 'follow%s' % suffix), + default('follow%s' % suffix) + ] + + def _make_follow_state(compound, _label=_label, + _label_compound=_label_compound, _nl=_nl, + _space=_space, _start_label=_start_label, + _token=_token, _token_compound=_token_compound, + _ws=_ws): + suffix = '/compound' if compound else '' + state = [] + if compound: + state.append((r'(?=\))', Text, '#pop')) + state += [ + (r'%s([%s]*)(%s)(.*)' % + (_start_label, _ws, _label_compound if compound else _label), + bygroups(Text, Punctuation, Text, Name.Label, Comment.Single)), + include('redirect%s' % suffix), + (r'(?=[%s])' % _nl, Text, '#pop'), + (r'\|\|?|&&?', Punctuation, '#pop'), + include('text') + ] + return state + + def _make_arithmetic_state(compound, _nl=_nl, _punct=_punct, + _string=_string, _variable=_variable, + _ws=_ws, _nlws=_nlws): + op = r'=+\-*/!~' + state = [] + if compound: + state.append((r'(?=\))', Text, '#pop')) + state += [ + (r'0[0-7]+', Number.Oct), + (r'0x[\da-f]+', Number.Hex), + (r'\d+', Number.Integer), + (r'[(),]+', Punctuation), + (r'([%s]|%%|\^\^)+' % op, Operator), + (r'(%s|%s|(\^[%s]?)?[^()%s%%\^"%s%s]|\^[%s]?%s)+' % + (_string, _variable, _nl, op, _nlws, _punct, _nlws, + r'[^)]' if compound else r'[\w\W]'), + using(this, state='variable')), + (r'(?=[\x00|&])', Text, '#pop'), + include('follow') + ] + return state + + def _make_call_state(compound, _label=_label, + _label_compound=_label_compound): + state = [] + if compound: + state.append((r'(?=\))', Text, '#pop')) + state.append((r'(:?)(%s)' % (_label_compound if compound else _label), + bygroups(Punctuation, Name.Label), '#pop')) + return state + + def _make_label_state(compound, _label=_label, + _label_compound=_label_compound, _nl=_nl, + _punct=_punct, _string=_string, _variable=_variable): + state = [] + if compound: + state.append((r'(?=\))', Text, '#pop')) + state.append((r'(%s?)((?:%s|%s|\^[%s]?%s|[^"%%^%s%s%s])*)' % + (_label_compound if compound else _label, _string, + _variable, _nl, r'[^)]' if compound else r'[\w\W]', _nl, + _punct, r')' if compound else ''), + bygroups(Name.Label, Comment.Single), '#pop')) + return state + + def _make_redirect_state(compound, + _core_token_compound=_core_token_compound, + _nl=_nl, _punct=_punct, _stoken=_stoken, + _string=_string, _space=_space, + _variable=_variable, _nlws=_nlws): + stoken_compound = (r'(?:[%s]+|(?:%s|%s|%s)+)' % + (_punct, _string, _variable, _core_token_compound)) + return [ + (r'((?:(?<=[%s])\d)?)(>>?&|<&)([%s]*)(\d)' % + (_nlws, _nlws), + bygroups(Number.Integer, Punctuation, Text, Number.Integer)), + (r'((?:(?<=[%s])(?>?|<)(%s?%s)' % + (_nlws, _nl, _space, stoken_compound if compound else _stoken), + bygroups(Number.Integer, Punctuation, using(this, state='text'))) + ] + + tokens = { + 'root': _make_begin_state(False), + 'follow': _make_follow_state(False), + 'arithmetic': _make_arithmetic_state(False), + 'call': _make_call_state(False), + 'label': _make_label_state(False), + 'redirect': _make_redirect_state(False), + 'root/compound': _make_begin_state(True), + 'follow/compound': _make_follow_state(True), + 'arithmetic/compound': _make_arithmetic_state(True), + 'call/compound': _make_call_state(True), + 'label/compound': _make_label_state(True), + 'redirect/compound': _make_redirect_state(True), + 'variable-or-escape': [ + (_variable, Name.Variable), + (r'%%%%|\^[%s]?(\^!|[\w\W])' % _nl, String.Escape) + ], + 'string': [ + (r'"', String.Double, '#pop'), + (_variable, Name.Variable), + (r'\^!|%%', String.Escape), + (r'[^"%%^%s]+|[%%^]' % _nl, String.Double), + default('#pop') + ], + 'sqstring': [ + include('variable-or-escape'), + (r'[^%]+|%', String.Single) + ], + 'bqstring': [ + include('variable-or-escape'), + (r'[^%]+|%', String.Backtick) + ], + 'text': [ + (r'"', String.Double, 'string'), + include('variable-or-escape'), + (r'[^"%%^%s%s\d)]+|.' % (_nlws, _punct), Text) + ], + 'variable': [ + (r'"', String.Double, 'string'), + include('variable-or-escape'), + (r'[^"%%^%s]+|.' % _nl, Name.Variable) + ], + 'for': [ + (r'(%s)(in)(%s)(\()' % (_space, _space), + bygroups(using(this, state='text'), Keyword, + using(this, state='text'), Punctuation), '#pop'), + include('follow') + ], + 'for2': [ + (r'\)', Punctuation), + (r'(%s)(do%s)' % (_space, _token_terminator), + bygroups(using(this, state='text'), Keyword), '#pop'), + (r'[%s]+' % _nl, Text), + include('follow') + ], + 'for/f': [ + (r'(")((?:%s|[^"])*?")([%s]*)(\))' % (_variable, _nlws), + bygroups(String.Double, using(this, state='string'), Text, + Punctuation)), + (r'"', String.Double, ('#pop', 'for2', 'string')), + (r"('(?:%%%%|%s|[\w\W])*?')([%s]*)(\))" % (_variable, _nlws), + bygroups(using(this, state='sqstring'), Text, Punctuation)), + (r'(`(?:%%%%|%s|[\w\W])*?`)([%s]*)(\))' % (_variable, _nlws), + bygroups(using(this, state='bqstring'), Text, Punctuation)), + include('for2') + ], + 'for/l': [ + (r'-?\d+', Number.Integer), + include('for2') + ], + 'if': [ + (r'((?:cmdextversion|errorlevel)%s)(%s)(\d+)' % + (_token_terminator, _space), + bygroups(Keyword, using(this, state='text'), + Number.Integer), '#pop'), + (r'(defined%s)(%s)(%s)' % (_token_terminator, _space, _stoken), + bygroups(Keyword, using(this, state='text'), + using(this, state='variable')), '#pop'), + (r'(exist%s)(%s%s)' % (_token_terminator, _space, _stoken), + bygroups(Keyword, using(this, state='text')), '#pop'), + (r'(%s%s)(%s)(%s%s)' % (_number, _space, _opword, _space, _number), + bygroups(using(this, state='arithmetic'), Operator.Word, + using(this, state='arithmetic')), '#pop'), + (_stoken, using(this, state='text'), ('#pop', 'if2')), + ], + 'if2': [ + (r'(%s?)(==)(%s?%s)' % (_space, _space, _stoken), + bygroups(using(this, state='text'), Operator, + using(this, state='text')), '#pop'), + (r'(%s)(%s)(%s%s)' % (_space, _opword, _space, _stoken), + bygroups(using(this, state='text'), Operator.Word, + using(this, state='text')), '#pop') + ], + '(?': [ + (_space, using(this, state='text')), + (r'\(', Punctuation, ('#pop', 'else?', 'root/compound')), + default('#pop') + ], + 'else?': [ + (_space, using(this, state='text')), + (r'else%s' % _token_terminator, Keyword, '#pop'), + default('#pop') + ] + } + + +class MSDOSSessionLexer(ShellSessionBaseLexer): + """ + Lexer for MS DOS shell sessions, i.e. command lines, including a + prompt, interspersed with output. + + .. versionadded:: 2.1 + """ + + name = 'MSDOS Session' + aliases = ['doscon'] + filenames = [] + mimetypes = [] + + _innerLexerCls = BatchLexer + _ps1rgx = re.compile(r'^([^>]*>)(.*\n?)') + _ps2 = 'More? ' + + +class TcshLexer(RegexLexer): + """ + Lexer for tcsh scripts. + + .. versionadded:: 0.10 + """ + + name = 'Tcsh' + aliases = ['tcsh', 'csh'] + filenames = ['*.tcsh', '*.csh'] + mimetypes = ['application/x-csh'] + + tokens = { + 'root': [ + include('basic'), + (r'\$\(', Keyword, 'paren'), + (r'\$\{#?', Keyword, 'curly'), + (r'`', String.Backtick, 'backticks'), + include('data'), + ], + 'basic': [ + (r'\b(if|endif|else|while|then|foreach|case|default|' + r'continue|goto|breaksw|end|switch|endsw)\s*\b', + Keyword), + (r'\b(alias|alloc|bg|bindkey|break|builtins|bye|caller|cd|chdir|' + r'complete|dirs|echo|echotc|eval|exec|exit|fg|filetest|getxvers|' + r'glob|getspath|hashstat|history|hup|inlib|jobs|kill|' + r'limit|log|login|logout|ls-F|migrate|newgrp|nice|nohup|notify|' + r'onintr|popd|printenv|pushd|rehash|repeat|rootnode|popd|pushd|' + r'set|shift|sched|setenv|setpath|settc|setty|setxvers|shift|' + r'source|stop|suspend|source|suspend|telltc|time|' + r'umask|unalias|uncomplete|unhash|universe|unlimit|unset|unsetenv|' + r'ver|wait|warp|watchlog|where|which)\s*\b', + Name.Builtin), + (r'#.*', Comment), + (r'\\[\w\W]', String.Escape), + (r'(\b\w+)(\s*)(=)', bygroups(Name.Variable, Text, Operator)), + (r'[\[\]{}()=]+', Operator), + (r'<<\s*(\'?)\\?(\w+)[\w\W]+?\2', String), + (r';', Punctuation), + ], + 'data': [ + (r'(?s)"(\\\\|\\[0-7]+|\\.|[^"\\])*"', String.Double), + (r"(?s)'(\\\\|\\[0-7]+|\\.|[^'\\])*'", String.Single), + (r'\s+', Text), + (r'[^=\s\[\]{}()$"\'`\\;#]+', Text), + (r'\d+(?= |\Z)', Number), + (r'\$#?(\w+|.)', Name.Variable), + ], + 'curly': [ + (r'\}', Keyword, '#pop'), + (r':-', Keyword), + (r'\w+', Name.Variable), + (r'[^}:"\'`$]+', Punctuation), + (r':', Punctuation), + include('root'), + ], + 'paren': [ + (r'\)', Keyword, '#pop'), + include('root'), + ], + 'backticks': [ + (r'`', String.Backtick, '#pop'), + include('root'), + ], + } + + +class TcshSessionLexer(ShellSessionBaseLexer): + """ + Lexer for Tcsh sessions, i.e. command lines, including a + prompt, interspersed with output. + + .. versionadded:: 2.1 + """ + + name = 'Tcsh Session' + aliases = ['tcshcon'] + filenames = [] + mimetypes = [] + + _innerLexerCls = TcshLexer + _ps1rgx = re.compile(r'^([^>]+>)(.*\n?)') + _ps2 = '? ' + + +class PowerShellLexer(RegexLexer): + """ + For Windows PowerShell code. + + .. versionadded:: 1.5 + """ + name = 'PowerShell' + aliases = ['powershell', 'posh', 'ps1', 'psm1'] + filenames = ['*.ps1', '*.psm1'] + mimetypes = ['text/x-powershell'] + + flags = re.DOTALL | re.IGNORECASE | re.MULTILINE + + keywords = ( + 'while validateset validaterange validatepattern validatelength ' + 'validatecount until trap switch return ref process param parameter in ' + 'if global: function foreach for finally filter end elseif else ' + 'dynamicparam do default continue cmdletbinding break begin alias \\? ' + '% #script #private #local #global mandatory parametersetname position ' + 'valuefrompipeline valuefrompipelinebypropertyname ' + 'valuefromremainingarguments helpmessage try catch throw').split() + + operators = ( + 'and as band bnot bor bxor casesensitive ccontains ceq cge cgt cle ' + 'clike clt cmatch cne cnotcontains cnotlike cnotmatch contains ' + 'creplace eq exact f file ge gt icontains ieq ige igt ile ilike ilt ' + 'imatch ine inotcontains inotlike inotmatch ireplace is isnot le like ' + 'lt match ne not notcontains notlike notmatch or regex replace ' + 'wildcard').split() + + verbs = ( + 'write where watch wait use update unregister unpublish unprotect ' + 'unlock uninstall undo unblock trace test tee take sync switch ' + 'suspend submit stop step start split sort skip show set send select ' + 'search scroll save revoke resume restore restart resolve resize ' + 'reset request repair rename remove register redo receive read push ' + 'publish protect pop ping out optimize open new move mount merge ' + 'measure lock limit join invoke install initialize import hide group ' + 'grant get format foreach find export expand exit enter enable edit ' + 'dismount disconnect disable deny debug cxnew copy convertto ' + 'convertfrom convert connect confirm compress complete compare close ' + 'clear checkpoint block backup assert approve aggregate add').split() + + aliases_ = ( + 'ac asnp cat cd cfs chdir clc clear clhy cli clp cls clv cnsn ' + 'compare copy cp cpi cpp curl cvpa dbp del diff dir dnsn ebp echo epal ' + 'epcsv epsn erase etsn exsn fc fhx fl foreach ft fw gal gbp gc gci gcm ' + 'gcs gdr ghy gi gjb gl gm gmo gp gps gpv group gsn gsnp gsv gu gv gwmi ' + 'h history icm iex ihy ii ipal ipcsv ipmo ipsn irm ise iwmi iwr kill lp ' + 'ls man md measure mi mount move mp mv nal ndr ni nmo npssc nsn nv ogv ' + 'oh popd ps pushd pwd r rbp rcjb rcsn rd rdr ren ri rjb rm rmdir rmo ' + 'rni rnp rp rsn rsnp rujb rv rvpa rwmi sajb sal saps sasv sbp sc select ' + 'set shcm si sl sleep sls sort sp spjb spps spsv start sujb sv swmi tee ' + 'trcm type wget where wjb write').split() + + commenthelp = ( + 'component description example externalhelp forwardhelpcategory ' + 'forwardhelptargetname functionality inputs link ' + 'notes outputs parameter remotehelprunspace role synopsis').split() + + tokens = { + 'root': [ + # we need to count pairs of parentheses for correct highlight + # of '$(...)' blocks in strings + (r'\(', Punctuation, 'child'), + (r'\s+', Text), + (r'^(\s*#[#\s]*)(\.(?:%s))([^\n]*$)' % '|'.join(commenthelp), + bygroups(Comment, String.Doc, Comment)), + (r'#[^\n]*?$', Comment), + (r'(<|<)#', Comment.Multiline, 'multline'), + (r'@"\n', String.Heredoc, 'heredoc-double'), + (r"@'\n.*?\n'@", String.Heredoc), + # escaped syntax + (r'`[\'"$@-]', Punctuation), + (r'"', String.Double, 'string'), + (r"'([^']|'')*'", String.Single), + (r'(\$|@@|@)((global|script|private|env):)?\w+', + Name.Variable), + (r'(%s)\b' % '|'.join(keywords), Keyword), + (r'-(%s)\b' % '|'.join(operators), Operator), + (r'(%s)-[a-z_]\w*\b' % '|'.join(verbs), Name.Builtin), + (r'(%s)\s' % '|'.join(aliases_), Name.Builtin), + (r'\[[a-z_\[][\w. `,\[\]]*\]', Name.Constant), # .net [type]s + (r'-[a-z_]\w*', Name), + (r'\w+', Name), + (r'[.,;@{}\[\]$()=+*/\\&%!~?^`|<>-]|::', Punctuation), + ], + 'child': [ + (r'\)', Punctuation, '#pop'), + include('root'), + ], + 'multline': [ + (r'[^#&.]+', Comment.Multiline), + (r'#(>|>)', Comment.Multiline, '#pop'), + (r'\.(%s)' % '|'.join(commenthelp), String.Doc), + (r'[#&.]', Comment.Multiline), + ], + 'string': [ + (r"`[0abfnrtv'\"$`]", String.Escape), + (r'[^$`"]+', String.Double), + (r'\$\(', Punctuation, 'child'), + (r'""', String.Double), + (r'[`$]', String.Double), + (r'"', String.Double, '#pop'), + ], + 'heredoc-double': [ + (r'\n"@', String.Heredoc, '#pop'), + (r'\$\(', Punctuation, 'child'), + (r'[^@\n]+"]', String.Heredoc), + (r".", String.Heredoc), + ] + } + + +class PowerShellSessionLexer(ShellSessionBaseLexer): + """ + Lexer for PowerShell sessions, i.e. command lines, including a + prompt, interspersed with output. + + .. versionadded:: 2.1 + """ + + name = 'PowerShell Session' + aliases = ['ps1con'] + filenames = [] + mimetypes = [] + + _innerLexerCls = PowerShellLexer + _ps1rgx = re.compile(r'^((?:\[[^]]+\]: )?PS[^>]*> ?)(.*\n?)') + _ps2 = '>> ' + + +class FishShellLexer(RegexLexer): + """ + Lexer for Fish shell scripts. + + .. versionadded:: 2.1 + """ + + name = 'Fish' + aliases = ['fish', 'fishshell'] + filenames = ['*.fish', '*.load'] + mimetypes = ['application/x-fish'] + + tokens = { + 'root': [ + include('basic'), + include('data'), + include('interp'), + ], + 'interp': [ + (r'\$\(\(', Keyword, 'math'), + (r'\(', Keyword, 'paren'), + (r'\$#?(\w+|.)', Name.Variable), + ], + 'basic': [ + (r'\b(begin|end|if|else|while|break|for|in|return|function|block|' + r'case|continue|switch|not|and|or|set|echo|exit|pwd|true|false|' + r'cd|count|test)(\s*)\b', + bygroups(Keyword, Text)), + (r'\b(alias|bg|bind|breakpoint|builtin|command|commandline|' + r'complete|contains|dirh|dirs|emit|eval|exec|fg|fish|fish_config|' + r'fish_indent|fish_pager|fish_prompt|fish_right_prompt|' + r'fish_update_completions|fishd|funced|funcsave|functions|help|' + r'history|isatty|jobs|math|mimedb|nextd|open|popd|prevd|psub|' + r'pushd|random|read|set_color|source|status|trap|type|ulimit|' + r'umask|vared|fc|getopts|hash|kill|printf|time|wait)\s*\b(?!\.)', + Name.Builtin), + (r'#.*\n', Comment), + (r'\\[\w\W]', String.Escape), + (r'(\b\w+)(\s*)(=)', bygroups(Name.Variable, Text, Operator)), + (r'[\[\]()=]', Operator), + (r'<<-?\s*(\'?)\\?(\w+)[\w\W]+?\2', String), + ], + 'data': [ + (r'(?s)\$?"(\\\\|\\[0-7]+|\\.|[^"\\$])*"', String.Double), + (r'"', String.Double, 'string'), + (r"(?s)\$'(\\\\|\\[0-7]+|\\.|[^'\\])*'", String.Single), + (r"(?s)'.*?'", String.Single), + (r';', Punctuation), + (r'&|\||\^|<|>', Operator), + (r'\s+', Text), + (r'\d+(?= |\Z)', Number), + (r'[^=\s\[\]{}()$"\'`\\<&|;]+', Text), + ], + 'string': [ + (r'"', String.Double, '#pop'), + (r'(?s)(\\\\|\\[0-7]+|\\.|[^"\\$])+', String.Double), + include('interp'), + ], + 'paren': [ + (r'\)', Keyword, '#pop'), + include('root'), + ], + 'math': [ + (r'\)\)', Keyword, '#pop'), + (r'[-+*/%^|&]|\*\*|\|\|', Operator), + (r'\d+#\d+', Number), + (r'\d+#(?! )', Number), + (r'\d+', Number), + include('root'), + ], + } + +class ExeclineLexer(RegexLexer): + """ + Lexer for Laurent Bercot's execline language + (https://skarnet.org/software/execline). + + .. versionadded:: 2.7 + """ + + name = 'execline' + aliases = ['execline'] + filenames = ['*.exec'] + + tokens = { + 'root': [ + include('basic'), + include('data'), + include('interp') + ], + 'interp': [ + (r'\$\{', String.Interpol, 'curly'), + (r'\$[\w@#]+', Name.Variable), # user variable + (r'\$', Text), + ], + 'basic': [ + (r'\b(background|backtick|cd|define|dollarat|elgetopt|' + r'elgetpositionals|elglob|emptyenv|envfile|exec|execlineb|' + r'exit|export|fdblock|fdclose|fdmove|fdreserve|fdswap|' + r'forbacktickx|foreground|forstdin|forx|getcwd|getpid|heredoc|' + r'homeof|if|ifelse|ifte|ifthenelse|importas|loopwhilex|' + r'multidefine|multisubstitute|pipeline|piperw|posix-cd|' + r'redirfd|runblock|shift|trap|tryexec|umask|unexport|wait|' + r'withstdinas)\b', Name.Builtin), + (r'\A#!.+\n', Comment.Hashbang), + (r'#.*\n', Comment.Single), + (r'[{}]', Operator) + ], + 'data': [ + (r'(?s)"(\\.|[^"\\$])*"', String.Double), + (r'"', String.Double, 'string'), + (r'\s+', Text), + (r'[^\s{}$"\\]+', Text) + ], + 'string': [ + (r'"', String.Double, '#pop'), + (r'(?s)(\\\\|\\.|[^"\\$])+', String.Double), + include('interp'), + ], + 'curly': [ + (r'\}', String.Interpol, '#pop'), + (r'[\w#@]+', Name.Variable), + include('root') + ] + + } + + def analyse_text(text): + if shebang_matches(text, r'execlineb'): + return 1 diff --git a/.venv/lib/python3.8/site-packages/pygments/lexers/sieve.py b/.venv/lib/python3.8/site-packages/pygments/lexers/sieve.py new file mode 100644 index 00000000..9d0b16e5 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/pygments/lexers/sieve.py @@ -0,0 +1,69 @@ +# -*- coding: utf-8 -*- +""" + pygments.lexers.sieve + ~~~~~~~~~~~~~~~~~~~~~ + + Lexer for Sieve file format. + + https://tools.ietf.org/html/rfc5228 + https://tools.ietf.org/html/rfc5173 + https://tools.ietf.org/html/rfc5229 + https://tools.ietf.org/html/rfc5230 + https://tools.ietf.org/html/rfc5232 + https://tools.ietf.org/html/rfc5235 + https://tools.ietf.org/html/rfc5429 + https://tools.ietf.org/html/rfc8580 + + :copyright: Copyright 2006-2020 by the Pygments team, see AUTHORS. + :license: BSD, see LICENSE for details. +""" + +from pygments.lexer import RegexLexer, bygroups +from pygments.token import Comment, Name, Literal, String, Text, Punctuation, Keyword + +__all__ = ["SieveLexer"] + + +class SieveLexer(RegexLexer): + """ + Lexer for sieve format. + """ + name = 'Sieve' + filenames = ['*.siv', '*.sieve'] + aliases = ['sieve'] + + tokens = { + 'root': [ + (r'\s+', Text), + (r'[();,{}\[\]]', Punctuation), + # import: + (r'(?i)require', + Keyword.Namespace), + # tags: + (r'(?i)(:)(addresses|all|contains|content|create|copy|comparator|count|days|detail|domain|fcc|flags|from|handle|importance|is|localpart|length|lowerfirst|lower|matches|message|mime|options|over|percent|quotewildcard|raw|regex|specialuse|subject|text|under|upperfirst|upper|value)', + bygroups(Name.Tag, Name.Tag)), + # tokens: + (r'(?i)(address|addflag|allof|anyof|body|discard|elsif|else|envelope|ereject|exists|false|fileinto|if|hasflag|header|keep|notify_method_capability|notify|not|redirect|reject|removeflag|setflag|size|spamtest|stop|string|true|vacation|virustest)', + Name.Builtin), + (r'(?i)set', + Keyword.Declaration), + # number: + (r'([0-9.]+)([kmgKMG])?', + bygroups(Literal.Number, Literal.Number)), + # comment: + (r'#.*$', + Comment.Single), + (r'/\*.*\*/', + Comment.Multiline), + # string: + (r'"[^"]*?"', + String), + # text block: + (r'text:', + Name.Tag, 'text'), + ], + 'text': [ + (r'[^.].*?\n', String), + (r'^\.', Punctuation, "#pop"), + ] + } diff --git a/.venv/lib/python3.8/site-packages/pygments/lexers/slash.py b/.venv/lib/python3.8/site-packages/pygments/lexers/slash.py new file mode 100644 index 00000000..13f81077 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/pygments/lexers/slash.py @@ -0,0 +1,185 @@ +# -*- coding: utf-8 -*- +""" + pygments.lexers.slash + ~~~~~~~~~~~~~~~~~~~~~ + + Lexer for the `Slash `_ programming + language. + + :copyright: Copyright 2006-2020 by the Pygments team, see AUTHORS. + :license: BSD, see LICENSE for details. +""" + +from pygments.lexer import ExtendedRegexLexer, bygroups, DelegatingLexer +from pygments.token import Name, Number, String, Comment, Punctuation, \ + Other, Keyword, Operator, Whitespace + +__all__ = ['SlashLexer'] + + +class SlashLanguageLexer(ExtendedRegexLexer): + _nkw = r'(?=[^a-zA-Z_0-9])' + + def move_state(new_state): + return ("#pop", new_state) + + def right_angle_bracket(lexer, match, ctx): + if len(ctx.stack) > 1 and ctx.stack[-2] == "string": + ctx.stack.pop() + yield match.start(), String.Interpol, '}' + ctx.pos = match.end() + pass + + tokens = { + "root": [ + (r"<%=", Comment.Preproc, move_state("slash")), + (r"<%!!", Comment.Preproc, move_state("slash")), + (r"<%#.*?%>", Comment.Multiline), + (r"<%", Comment.Preproc, move_state("slash")), + (r".|\n", Other), + ], + "string": [ + (r"\\", String.Escape, move_state("string_e")), + (r"\"", String, move_state("slash")), + (r"#\{", String.Interpol, "slash"), + (r'.|\n', String), + ], + "string_e": [ + (r'n', String.Escape, move_state("string")), + (r't', String.Escape, move_state("string")), + (r'r', String.Escape, move_state("string")), + (r'e', String.Escape, move_state("string")), + (r'x[a-fA-F0-9]{2}', String.Escape, move_state("string")), + (r'.', String.Escape, move_state("string")), + ], + "regexp": [ + (r'}[a-z]*', String.Regex, move_state("slash")), + (r'\\(.|\n)', String.Regex), + (r'{', String.Regex, "regexp_r"), + (r'.|\n', String.Regex), + ], + "regexp_r": [ + (r'}[a-z]*', String.Regex, "#pop"), + (r'\\(.|\n)', String.Regex), + (r'{', String.Regex, "regexp_r"), + ], + "slash": [ + (r"%>", Comment.Preproc, move_state("root")), + (r"\"", String, move_state("string")), + (r"'[a-zA-Z0-9_]+", String), + (r'%r{', String.Regex, move_state("regexp")), + (r'/\*.*?\*/', Comment.Multiline), + (r"(#|//).*?\n", Comment.Single), + (r'-?[0-9]+e[+-]?[0-9]+', Number.Float), + (r'-?[0-9]+\.[0-9]+(e[+-]?[0-9]+)?', Number.Float), + (r'-?[0-9]+', Number.Integer), + (r'nil'+_nkw, Name.Builtin), + (r'true'+_nkw, Name.Builtin), + (r'false'+_nkw, Name.Builtin), + (r'self'+_nkw, Name.Builtin), + (r'(class)(\s+)([A-Z][a-zA-Z0-9_\']*)', + bygroups(Keyword, Whitespace, Name.Class)), + (r'class'+_nkw, Keyword), + (r'extends'+_nkw, Keyword), + (r'(def)(\s+)(self)(\s*)(\.)(\s*)([a-z_][a-zA-Z0-9_\']*=?|<<|>>|==|<=>|<=|<|>=|>|\+|-(self)?|~(self)?|\*|/|%|^|&&|&|\||\[\]=?)', + bygroups(Keyword, Whitespace, Name.Builtin, Whitespace, Punctuation, Whitespace, Name.Function)), + (r'(def)(\s+)([a-z_][a-zA-Z0-9_\']*=?|<<|>>|==|<=>|<=|<|>=|>|\+|-(self)?|~(self)?|\*|/|%|^|&&|&|\||\[\]=?)', + bygroups(Keyword, Whitespace, Name.Function)), + (r'def'+_nkw, Keyword), + (r'if'+_nkw, Keyword), + (r'elsif'+_nkw, Keyword), + (r'else'+_nkw, Keyword), + (r'unless'+_nkw, Keyword), + (r'for'+_nkw, Keyword), + (r'in'+_nkw, Keyword), + (r'while'+_nkw, Keyword), + (r'until'+_nkw, Keyword), + (r'and'+_nkw, Keyword), + (r'or'+_nkw, Keyword), + (r'not'+_nkw, Keyword), + (r'lambda'+_nkw, Keyword), + (r'try'+_nkw, Keyword), + (r'catch'+_nkw, Keyword), + (r'return'+_nkw, Keyword), + (r'next'+_nkw, Keyword), + (r'last'+_nkw, Keyword), + (r'throw'+_nkw, Keyword), + (r'use'+_nkw, Keyword), + (r'switch'+_nkw, Keyword), + (r'\\', Keyword), + (r'λ', Keyword), + (r'__FILE__'+_nkw, Name.Builtin.Pseudo), + (r'__LINE__'+_nkw, Name.Builtin.Pseudo), + (r'[A-Z][a-zA-Z0-9_\']*'+_nkw, Name.Constant), + (r'[a-z_][a-zA-Z0-9_\']*'+_nkw, Name), + (r'@[a-z_][a-zA-Z0-9_\']*'+_nkw, Name.Variable.Instance), + (r'@@[a-z_][a-zA-Z0-9_\']*'+_nkw, Name.Variable.Class), + (r'\(', Punctuation), + (r'\)', Punctuation), + (r'\[', Punctuation), + (r'\]', Punctuation), + (r'\{', Punctuation), + (r'\}', right_angle_bracket), + (r';', Punctuation), + (r',', Punctuation), + (r'<<=', Operator), + (r'>>=', Operator), + (r'<<', Operator), + (r'>>', Operator), + (r'==', Operator), + (r'!=', Operator), + (r'=>', Operator), + (r'=', Operator), + (r'<=>', Operator), + (r'<=', Operator), + (r'>=', Operator), + (r'<', Operator), + (r'>', Operator), + (r'\+\+', Operator), + (r'\+=', Operator), + (r'-=', Operator), + (r'\*\*=', Operator), + (r'\*=', Operator), + (r'\*\*', Operator), + (r'\*', Operator), + (r'/=', Operator), + (r'\+', Operator), + (r'-', Operator), + (r'/', Operator), + (r'%=', Operator), + (r'%', Operator), + (r'^=', Operator), + (r'&&=', Operator), + (r'&=', Operator), + (r'&&', Operator), + (r'&', Operator), + (r'\|\|=', Operator), + (r'\|=', Operator), + (r'\|\|', Operator), + (r'\|', Operator), + (r'!', Operator), + (r'\.\.\.', Operator), + (r'\.\.', Operator), + (r'\.', Operator), + (r'::', Operator), + (r':', Operator), + (r'(\s|\n)+', Whitespace), + (r'[a-z_][a-zA-Z0-9_\']*', Name.Variable), + ], + } + + +class SlashLexer(DelegatingLexer): + """ + Lexer for the Slash programming language. + + .. versionadded:: 2.4 + """ + + name = 'Slash' + aliases = ['slash'] + filenames = ['*.sla'] + + def __init__(self, **options): + from pygments.lexers.web import HtmlLexer + super().__init__(HtmlLexer, SlashLanguageLexer, **options) diff --git a/.venv/lib/python3.8/site-packages/pygments/lexers/smalltalk.py b/.venv/lib/python3.8/site-packages/pygments/lexers/smalltalk.py new file mode 100644 index 00000000..b7df5f33 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/pygments/lexers/smalltalk.py @@ -0,0 +1,195 @@ +# -*- coding: utf-8 -*- +""" + pygments.lexers.smalltalk + ~~~~~~~~~~~~~~~~~~~~~~~~~ + + Lexers for Smalltalk and related languages. + + :copyright: Copyright 2006-2020 by the Pygments team, see AUTHORS. + :license: BSD, see LICENSE for details. +""" + +from pygments.lexer import RegexLexer, include, bygroups, default +from pygments.token import Text, Comment, Operator, Keyword, Name, String, \ + Number, Punctuation + +__all__ = ['SmalltalkLexer', 'NewspeakLexer'] + + +class SmalltalkLexer(RegexLexer): + """ + For `Smalltalk `_ syntax. + Contributed by Stefan Matthias Aust. + Rewritten by Nils Winter. + + .. versionadded:: 0.10 + """ + name = 'Smalltalk' + filenames = ['*.st'] + aliases = ['smalltalk', 'squeak', 'st'] + mimetypes = ['text/x-smalltalk'] + + tokens = { + 'root': [ + (r'(<)(\w+:)(.*?)(>)', bygroups(Text, Keyword, Text, Text)), + include('squeak fileout'), + include('whitespaces'), + include('method definition'), + (r'(\|)([\w\s]*)(\|)', bygroups(Operator, Name.Variable, Operator)), + include('objects'), + (r'\^|\:=|\_', Operator), + # temporaries + (r'[\]({}.;!]', Text), + ], + 'method definition': [ + # Not perfect can't allow whitespaces at the beginning and the + # without breaking everything + (r'([a-zA-Z]+\w*:)(\s*)(\w+)', + bygroups(Name.Function, Text, Name.Variable)), + (r'^(\b[a-zA-Z]+\w*\b)(\s*)$', bygroups(Name.Function, Text)), + (r'^([-+*/\\~<>=|&!?,@%]+)(\s*)(\w+)(\s*)$', + bygroups(Name.Function, Text, Name.Variable, Text)), + ], + 'blockvariables': [ + include('whitespaces'), + (r'(:)(\s*)(\w+)', + bygroups(Operator, Text, Name.Variable)), + (r'\|', Operator, '#pop'), + default('#pop'), # else pop + ], + 'literals': [ + (r"'(''|[^'])*'", String, 'afterobject'), + (r'\$.', String.Char, 'afterobject'), + (r'#\(', String.Symbol, 'parenth'), + (r'\)', Text, 'afterobject'), + (r'(\d+r)?-?\d+(\.\d+)?(e-?\d+)?', Number, 'afterobject'), + ], + '_parenth_helper': [ + include('whitespaces'), + (r'(\d+r)?-?\d+(\.\d+)?(e-?\d+)?', Number), + (r'[-+*/\\~<>=|&#!?,@%\w:]+', String.Symbol), + # literals + (r"'(''|[^'])*'", String), + (r'\$.', String.Char), + (r'#*\(', String.Symbol, 'inner_parenth'), + ], + 'parenth': [ + # This state is a bit tricky since + # we can't just pop this state + (r'\)', String.Symbol, ('root', 'afterobject')), + include('_parenth_helper'), + ], + 'inner_parenth': [ + (r'\)', String.Symbol, '#pop'), + include('_parenth_helper'), + ], + 'whitespaces': [ + # skip whitespace and comments + (r'\s+', Text), + (r'"(""|[^"])*"', Comment), + ], + 'objects': [ + (r'\[', Text, 'blockvariables'), + (r'\]', Text, 'afterobject'), + (r'\b(self|super|true|false|nil|thisContext)\b', + Name.Builtin.Pseudo, 'afterobject'), + (r'\b[A-Z]\w*(?!:)\b', Name.Class, 'afterobject'), + (r'\b[a-z]\w*(?!:)\b', Name.Variable, 'afterobject'), + (r'#("(""|[^"])*"|[-+*/\\~<>=|&!?,@%]+|[\w:]+)', + String.Symbol, 'afterobject'), + include('literals'), + ], + 'afterobject': [ + (r'! !$', Keyword, '#pop'), # squeak chunk delimiter + include('whitespaces'), + (r'\b(ifTrue:|ifFalse:|whileTrue:|whileFalse:|timesRepeat:)', + Name.Builtin, '#pop'), + (r'\b(new\b(?!:))', Name.Builtin), + (r'\:=|\_', Operator, '#pop'), + (r'\b[a-zA-Z]+\w*:', Name.Function, '#pop'), + (r'\b[a-zA-Z]+\w*', Name.Function), + (r'\w+:?|[-+*/\\~<>=|&!?,@%]+', Name.Function, '#pop'), + (r'\.', Punctuation, '#pop'), + (r';', Punctuation), + (r'[\])}]', Text), + (r'[\[({]', Text, '#pop'), + ], + 'squeak fileout': [ + # Squeak fileout format (optional) + (r'^"(""|[^"])*"!', Keyword), + (r"^'(''|[^'])*'!", Keyword), + (r'^(!)(\w+)( commentStamp: )(.*?)( prior: .*?!\n)(.*?)(!)', + bygroups(Keyword, Name.Class, Keyword, String, Keyword, Text, Keyword)), + (r"^(!)(\w+(?: class)?)( methodsFor: )('(?:''|[^'])*')(.*?!)", + bygroups(Keyword, Name.Class, Keyword, String, Keyword)), + (r'^(\w+)( subclass: )(#\w+)' + r'(\s+instanceVariableNames: )(.*?)' + r'(\s+classVariableNames: )(.*?)' + r'(\s+poolDictionaries: )(.*?)' + r'(\s+category: )(.*?)(!)', + bygroups(Name.Class, Keyword, String.Symbol, Keyword, String, Keyword, + String, Keyword, String, Keyword, String, Keyword)), + (r'^(\w+(?: class)?)(\s+instanceVariableNames: )(.*?)(!)', + bygroups(Name.Class, Keyword, String, Keyword)), + (r'(!\n)(\].*)(! !)$', bygroups(Keyword, Text, Keyword)), + (r'! !$', Keyword), + ], + } + + +class NewspeakLexer(RegexLexer): + """ + For `Newspeak `_ syntax. + + .. versionadded:: 1.1 + """ + name = 'Newspeak' + filenames = ['*.ns2'] + aliases = ['newspeak', ] + mimetypes = ['text/x-newspeak'] + + tokens = { + 'root': [ + (r'\b(Newsqueak2)\b', Keyword.Declaration), + (r"'[^']*'", String), + (r'\b(class)(\s+)(\w+)(\s*)', + bygroups(Keyword.Declaration, Text, Name.Class, Text)), + (r'\b(mixin|self|super|private|public|protected|nil|true|false)\b', + Keyword), + (r'(\w+\:)(\s*)([a-zA-Z_]\w+)', + bygroups(Name.Function, Text, Name.Variable)), + (r'(\w+)(\s*)(=)', + bygroups(Name.Attribute, Text, Operator)), + (r'<\w+>', Comment.Special), + include('expressionstat'), + include('whitespace') + ], + + 'expressionstat': [ + (r'(\d+\.\d*|\.\d+|\d+[fF])[fF]?', Number.Float), + (r'\d+', Number.Integer), + (r':\w+', Name.Variable), + (r'(\w+)(::)', bygroups(Name.Variable, Operator)), + (r'\w+:', Name.Function), + (r'\w+', Name.Variable), + (r'\(|\)', Punctuation), + (r'\[|\]', Punctuation), + (r'\{|\}', Punctuation), + + (r'(\^|\+|\/|~|\*|<|>|=|@|%|\||&|\?|!|,|-|:)', Operator), + (r'\.|;', Punctuation), + include('whitespace'), + include('literals'), + ], + 'literals': [ + (r'\$.', String), + (r"'[^']*'", String), + (r"#'[^']*'", String.Symbol), + (r"#\w+:?", String.Symbol), + (r"#(\+|\/|~|\*|<|>|=|@|%|\||&|\?|!|,|-)+", String.Symbol) + ], + 'whitespace': [ + (r'\s+', Text), + (r'"[^"]*"', Comment) + ], + } diff --git a/.venv/lib/python3.8/site-packages/pygments/lexers/smv.py b/.venv/lib/python3.8/site-packages/pygments/lexers/smv.py new file mode 100644 index 00000000..a5500d93 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/pygments/lexers/smv.py @@ -0,0 +1,79 @@ +# -*- coding: utf-8 -*- +""" + pygments.lexers.smv + ~~~~~~~~~~~~~~~~~~~ + + Lexers for the SMV languages. + + :copyright: Copyright 2006-2020 by the Pygments team, see AUTHORS. + :license: BSD, see LICENSE for details. +""" + +from pygments.lexer import RegexLexer, words +from pygments.token import Comment, Keyword, Name, Number, Operator, \ + Punctuation, Text + +__all__ = ['NuSMVLexer'] + + +class NuSMVLexer(RegexLexer): + """ + Lexer for the NuSMV language. + + .. versionadded:: 2.2 + """ + + name = 'NuSMV' + aliases = ['nusmv'] + filenames = ['*.smv'] + mimetypes = [] + + tokens = { + 'root': [ + # Comments + (r'(?s)\/\-\-.*?\-\-/', Comment), + (r'--.*\n', Comment), + + # Reserved + (words(('MODULE', 'DEFINE', 'MDEFINE', 'CONSTANTS', 'VAR', 'IVAR', + 'FROZENVAR', 'INIT', 'TRANS', 'INVAR', 'SPEC', 'CTLSPEC', + 'LTLSPEC', 'PSLSPEC', 'COMPUTE', 'NAME', 'INVARSPEC', + 'FAIRNESS', 'JUSTICE', 'COMPASSION', 'ISA', 'ASSIGN', + 'CONSTRAINT', 'SIMPWFF', 'CTLWFF', 'LTLWFF', 'PSLWFF', + 'COMPWFF', 'IN', 'MIN', 'MAX', 'MIRROR', 'PRED', + 'PREDICATES'), suffix=r'(?![\w$#-])'), + Keyword.Declaration), + (r'process(?![\w$#-])', Keyword), + (words(('array', 'of', 'boolean', 'integer', 'real', 'word'), + suffix=r'(?![\w$#-])'), Keyword.Type), + (words(('case', 'esac'), suffix=r'(?![\w$#-])'), Keyword), + (words(('word1', 'bool', 'signed', 'unsigned', 'extend', 'resize', + 'sizeof', 'uwconst', 'swconst', 'init', 'self', 'count', + 'abs', 'max', 'min'), suffix=r'(?![\w$#-])'), + Name.Builtin), + (words(('EX', 'AX', 'EF', 'AF', 'EG', 'AG', 'E', 'F', 'O', 'G', + 'H', 'X', 'Y', 'Z', 'A', 'U', 'S', 'V', 'T', 'BU', 'EBF', + 'ABF', 'EBG', 'ABG', 'next', 'mod', 'union', 'in', 'xor', + 'xnor'), suffix=r'(?![\w$#-])'), + Operator.Word), + (words(('TRUE', 'FALSE'), suffix=r'(?![\w$#-])'), Keyword.Constant), + + # Names + (r'[a-zA-Z_][\w$#-]*', Name.Variable), + + # Operators + (r':=', Operator), + (r'[-&|+*/<>!=]', Operator), + + # Literals + (r'\-?\d+\b', Number.Integer), + (r'0[su][bB]\d*_[01_]+', Number.Bin), + (r'0[su][oO]\d*_[0-7_]+', Number.Oct), + (r'0[su][dD]\d*_[\d_]+', Number.Dec), + (r'0[su][hH]\d*_[\da-fA-F_]+', Number.Hex), + + # Whitespace, punctuation and the rest + (r'\s+', Text.Whitespace), + (r'[()\[\]{};?:.,]', Punctuation), + ], + } diff --git a/.venv/lib/python3.8/site-packages/pygments/lexers/snobol.py b/.venv/lib/python3.8/site-packages/pygments/lexers/snobol.py new file mode 100644 index 00000000..b0fdb01c --- /dev/null +++ b/.venv/lib/python3.8/site-packages/pygments/lexers/snobol.py @@ -0,0 +1,83 @@ +# -*- coding: utf-8 -*- +""" + pygments.lexers.snobol + ~~~~~~~~~~~~~~~~~~~~~~ + + Lexers for the SNOBOL language. + + :copyright: Copyright 2006-2020 by the Pygments team, see AUTHORS. + :license: BSD, see LICENSE for details. +""" + +from pygments.lexer import RegexLexer, bygroups +from pygments.token import Text, Comment, Operator, Keyword, Name, String, \ + Number, Punctuation + +__all__ = ['SnobolLexer'] + + +class SnobolLexer(RegexLexer): + """ + Lexer for the SNOBOL4 programming language. + + Recognizes the common ASCII equivalents of the original SNOBOL4 operators. + Does not require spaces around binary operators. + + .. versionadded:: 1.5 + """ + + name = "Snobol" + aliases = ["snobol"] + filenames = ['*.snobol'] + mimetypes = ['text/x-snobol'] + + tokens = { + # root state, start of line + # comments, continuation lines, and directives start in column 1 + # as do labels + 'root': [ + (r'\*.*\n', Comment), + (r'[+.] ', Punctuation, 'statement'), + (r'-.*\n', Comment), + (r'END\s*\n', Name.Label, 'heredoc'), + (r'[A-Za-z$][\w$]*', Name.Label, 'statement'), + (r'\s+', Text, 'statement'), + ], + # statement state, line after continuation or label + 'statement': [ + (r'\s*\n', Text, '#pop'), + (r'\s+', Text), + (r'(?<=[^\w.])(LT|LE|EQ|NE|GE|GT|INTEGER|IDENT|DIFFER|LGT|SIZE|' + r'REPLACE|TRIM|DUPL|REMDR|DATE|TIME|EVAL|APPLY|OPSYN|LOAD|UNLOAD|' + r'LEN|SPAN|BREAK|ANY|NOTANY|TAB|RTAB|REM|POS|RPOS|FAIL|FENCE|' + r'ABORT|ARB|ARBNO|BAL|SUCCEED|INPUT|OUTPUT|TERMINAL)(?=[^\w.])', + Name.Builtin), + (r'[A-Za-z][\w.]*', Name), + # ASCII equivalents of original operators + # | for the EBCDIC equivalent, ! likewise + # \ for EBCDIC negation + (r'\*\*|[?$.!%*/#+\-@|&\\=]', Operator), + (r'"[^"]*"', String), + (r"'[^']*'", String), + # Accept SPITBOL syntax for real numbers + # as well as Macro SNOBOL4 + (r'[0-9]+(?=[^.EeDd])', Number.Integer), + (r'[0-9]+(\.[0-9]*)?([EDed][-+]?[0-9]+)?', Number.Float), + # Goto + (r':', Punctuation, 'goto'), + (r'[()<>,;]', Punctuation), + ], + # Goto block + 'goto': [ + (r'\s*\n', Text, "#pop:2"), + (r'\s+', Text), + (r'F|S', Keyword), + (r'(\()([A-Za-z][\w.]*)(\))', + bygroups(Punctuation, Name.Label, Punctuation)) + ], + # everything after the END statement is basically one + # big heredoc. + 'heredoc': [ + (r'.*\n', String.Heredoc) + ] + } diff --git a/.venv/lib/python3.8/site-packages/pygments/lexers/solidity.py b/.venv/lib/python3.8/site-packages/pygments/lexers/solidity.py new file mode 100644 index 00000000..af0672ee --- /dev/null +++ b/.venv/lib/python3.8/site-packages/pygments/lexers/solidity.py @@ -0,0 +1,92 @@ +# -*- coding: utf-8 -*- +""" + pygments.lexers.solidity + ~~~~~~~~~~~~~~~~~~~~~~~~ + + Lexers for Solidity. + + :copyright: Copyright 2006-2020 by the Pygments team, see AUTHORS. + :license: BSD, see LICENSE for details. +""" + +import re + +from pygments.lexer import RegexLexer, bygroups, include, words +from pygments.token import Text, Comment, Operator, Keyword, Name, String, \ + Number, Punctuation, Whitespace + +__all__ = ['SolidityLexer'] + + +class SolidityLexer(RegexLexer): + """ + For Solidity source code. + + .. versionadded:: 2.5 + """ + + name = 'Solidity' + aliases = ['solidity'] + filenames = ['*.sol'] + mimetypes = [] + + flags = re.MULTILINE | re.UNICODE + + datatype = ( + r'\b(address|bool|(?:(?:bytes|hash|int|string|uint)(?:8|16|24|32|40|48|56|64' + r'|72|80|88|96|104|112|120|128|136|144|152|160|168|176|184|192|200|208' + r'|216|224|232|240|248|256)?))\b' + ) + + tokens = { + 'root': [ + include('whitespace'), + include('comments'), + (r'\bpragma\s+solidity\b', Keyword, 'pragma'), + (r'\b(contract)(\s+)([a-zA-Z_]\w*)', + bygroups(Keyword, Whitespace, Name.Entity)), + (datatype + r'(\s+)((?:external|public|internal|private)\s+)?' + + r'([a-zA-Z_]\w*)', + bygroups(Keyword.Type, Whitespace, Keyword, Name.Variable)), + (r'\b(enum|event|function|struct)(\s+)([a-zA-Z_]\w*)', + bygroups(Keyword.Type, Whitespace, Name.Variable)), + (r'\b(msg|block|tx)\.([A-Za-z_][a-zA-Z0-9_]*)\b', Keyword), + (words(( + 'block', 'break', 'constant', 'constructor', 'continue', + 'contract', 'do', 'else', 'external', 'false', 'for', + 'function', 'if', 'import', 'inherited', 'internal', 'is', + 'library', 'mapping', 'memory', 'modifier', 'msg', 'new', + 'payable', 'private', 'public', 'require', 'return', + 'returns', 'struct', 'suicide', 'throw', 'this', 'true', + 'tx', 'var', 'while'), prefix=r'\b', suffix=r'\b'), + Keyword.Type), + (words(('keccak256',), prefix=r'\b', suffix=r'\b'), Name.Builtin), + (datatype, Keyword.Type), + include('constants'), + (r'[a-zA-Z_]\w*', Text), + (r'[!<=>+*/-]', Operator), + (r'[.;:{}(),\[\]]', Punctuation) + ], + 'comments': [ + (r'//(\n|[\w\W]*?[^\\]\n)', Comment.Single), + (r'/(\\\n)?[*][\w\W]*?[*](\\\n)?/', Comment.Multiline), + (r'/(\\\n)?[*][\w\W]*', Comment.Multiline) + ], + 'constants': [ + (r'("(\\"|.)*?")', String.Double), + (r"('(\\'|.)*?')", String.Single), + (r'\b0[xX][0-9a-fA-F]+\b', Number.Hex), + (r'\b\d+\b', Number.Decimal), + ], + 'pragma': [ + include('whitespace'), + include('comments'), + (r'(\^|>=|<)(\s*)(\d+\.\d+\.\d+)', + bygroups(Operator, Whitespace, Keyword)), + (r';', Punctuation, '#pop') + ], + 'whitespace': [ + (r'\s+', Whitespace), + (r'\n', Whitespace) + ] + } diff --git a/.venv/lib/python3.8/site-packages/pygments/lexers/special.py b/.venv/lib/python3.8/site-packages/pygments/lexers/special.py new file mode 100644 index 00000000..84a924d9 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/pygments/lexers/special.py @@ -0,0 +1,105 @@ +# -*- coding: utf-8 -*- +""" + pygments.lexers.special + ~~~~~~~~~~~~~~~~~~~~~~~ + + Special lexers. + + :copyright: Copyright 2006-2020 by the Pygments team, see AUTHORS. + :license: BSD, see LICENSE for details. +""" + +import re +from io import BytesIO + +from pygments.lexer import Lexer +from pygments.token import Token, Error, Text +from pygments.util import get_choice_opt + + +__all__ = ['TextLexer', 'RawTokenLexer'] + + +class TextLexer(Lexer): + """ + "Null" lexer, doesn't highlight anything. + """ + name = 'Text only' + aliases = ['text'] + filenames = ['*.txt'] + mimetypes = ['text/plain'] + priority = 0.01 + + def get_tokens_unprocessed(self, text): + yield 0, Text, text + + def analyse_text(text): + return TextLexer.priority + + +_ttype_cache = {} + +line_re = re.compile(b'.*?\n') + + +class RawTokenLexer(Lexer): + """ + Recreate a token stream formatted with the `RawTokenFormatter`. This + lexer raises exceptions during parsing if the token stream in the + file is malformed. + + Additional options accepted: + + `compress` + If set to ``"gz"`` or ``"bz2"``, decompress the token stream with + the given compression algorithm before lexing (default: ``""``). + """ + name = 'Raw token data' + aliases = ['raw'] + filenames = [] + mimetypes = ['application/x-pygments-tokens'] + + def __init__(self, **options): + self.compress = get_choice_opt(options, 'compress', + ['', 'none', 'gz', 'bz2'], '') + Lexer.__init__(self, **options) + + def get_tokens(self, text): + if isinstance(text, str): + # raw token stream never has any non-ASCII characters + text = text.encode('ascii') + if self.compress == 'gz': + import gzip + gzipfile = gzip.GzipFile('', 'rb', 9, BytesIO(text)) + text = gzipfile.read() + elif self.compress == 'bz2': + import bz2 + text = bz2.decompress(text) + + # do not call Lexer.get_tokens() because we do not want Unicode + # decoding to occur, and stripping is not optional. + text = text.strip(b'\n') + b'\n' + for i, t, v in self.get_tokens_unprocessed(text): + yield t, v + + def get_tokens_unprocessed(self, text): + length = 0 + for match in line_re.finditer(text): + try: + ttypestr, val = match.group().split(b'\t', 1) + except ValueError: + val = match.group().decode('ascii', 'replace') + ttype = Error + else: + ttype = _ttype_cache.get(ttypestr) + if not ttype: + ttype = Token + ttypes = ttypestr.split('.')[1:] + for ttype_ in ttypes: + if not ttype_ or not ttype_[0].isupper(): + raise ValueError('malformed token name') + ttype = getattr(ttype, ttype_) + _ttype_cache[ttypestr] = ttype + val = val[2:-2].decode('unicode-escape') + yield length, ttype, val + length += len(val) diff --git a/.venv/lib/python3.8/site-packages/pygments/lexers/sql.py b/.venv/lib/python3.8/site-packages/pygments/lexers/sql.py new file mode 100644 index 00000000..e27e0ddb --- /dev/null +++ b/.venv/lib/python3.8/site-packages/pygments/lexers/sql.py @@ -0,0 +1,837 @@ +# -*- coding: utf-8 -*- +""" + pygments.lexers.sql + ~~~~~~~~~~~~~~~~~~~ + + Lexers for various SQL dialects and related interactive sessions. + + Postgres specific lexers: + + `PostgresLexer` + A SQL lexer for the PostgreSQL dialect. Differences w.r.t. the SQL + lexer are: + + - keywords and data types list parsed from the PG docs (run the + `_postgres_builtins` module to update them); + - Content of $-strings parsed using a specific lexer, e.g. the content + of a PL/Python function is parsed using the Python lexer; + - parse PG specific constructs: E-strings, $-strings, U&-strings, + different operators and punctuation. + + `PlPgsqlLexer` + A lexer for the PL/pgSQL language. Adds a few specific construct on + top of the PG SQL lexer (such as <

6mFabH!g<@!G%FsR0nBMHLB@xa%44!P|T1i zpCvy&t5-cxAc0pApKMwKxhs^x6>xS^0XZwfJUi0H5;$BA?^X_Rrws9dt;Pe;rC^nz zeFo9_$@wjqd&t_^B%K{CegSBV38`6B)llqy7gd2b93w7Ayi3tT(1+%oWiyqtC@M}R#iP_#t!fCiMBE1vgDbuVPyy&%x=K#Ib|_-ZYh zCIfyB;Nx@EWy}TxHK<)R+qECZmgW-d==HuDmNFziXwY%^qizPS&>v;wb_qJmecF(K z=t`s`Qk?(7^fT~)0XxM{u#y%seLp;2*cwu!r9U~70fE0*>!#m}p%ngeh&j)~)R0s& zaM3b~`{rAefzJyyApk)Aa|7ENnR^dvXr%m^sANmc3lBEv zosJj34{(aAdKeaXD$F=|fzd?_;0E@F&@_=)+Mvg5TC?3jA+^Kk{`im@)_in+6A8B}@ptd8Ct5px5UAt-1fZeew)<`5|db(i)L z8Z4!X$mWQJM}+2@JUfSUC2b$ZkXe|=u!)UEOq^+PqhDJ>43#WCv4u7V|5vVBc6G9} zYF@!PQbSuB?-dEg0-lYbmOdvK!u@4+#tB0YgS^G9pE$Y(CcEd zq6uND4W`loVWwiuMinIn?~}P>9`yz@vj!Pcq`%=_1!9W{K?U9W?>taAK6?7dT?bDE z>F{ikAU>z6+!9|q+Qf-b@i$Ye%4bh{ezp9NRvUw)7${6Q;tJje8NWE`A)1Muc$96u zgbVbtr+9x7eZV#_>^%pfsk`wc5+#VEuj;LQnGUC_QxDtRhNMlB*O2fxk%`=nHe&0j zemYDM5N@WC!+ zvAk~w%YZGOws(I!?_g)|gGGLCGhOXvIyR4Li~GUQ8kTB6=^O_Zd8iZUtRY5zVfjK%!xf>KAdJPay=BX5dbkUW09aE{+(%vQf6|7sTj~ zumiSp43BAi(B3ajiwk=5|G|^ zOm>4E1aXaFsAGp^o0R$mW)<-n$csM|z1JFY-0VpFx8-!D1MTzg^a=fyczT}lIv;WA_n;j(*1NYF0GT7XQ zFiYx4)O(g4$eK7j$k?9PNX%CnjD<+lZ+``~Sw|h`CPP*YR)!$W+&K2V&5j&eHS3&t zpPvC-v~_^9-KnuyvZw9^VRe`a_ONvW;#W{g{TVJsx5{^GD72_D5q3z&ABj2+4GUpXB#;(_ zBZ+Dx{B_&~X=6U})s4)@&2@;?q@h;)usAh9)T>}iNRwgyf+1p)4xtcqgGFP0ggXP% z$ztiIffPSq%V)%wR*-$xMYNJ1faY3=z^Mo2=Lf=S%_zaP5n3c8jD{Huu00zMapdCu zLTDA7UkIi`;1sUT%jtO1PTMwgIQV-e(LA8ZUaZ#7P)Cy{uE7KKGTJp=3!0f-!~T2d zHn9tE?T|f;!O?m<>vOayqpe0mERIk_usyaCbZLSGkhE^vJ|0D!c|4r9SiIMgl(q{ZYTNWI!dXwx)Q^lt9fELzwGb^db0I0Tv{E)jFHC>+;9I)PmY67DT7Siiz zU%+ahph4~8(TW!U9Q~0Kk?uF(BPT(~K0=tEf z^IV{)KgH$aL=W<7tVR$ESKmR;N;F0s<0eM?*5E3RPi&kJ&K*2}$RLOrie+igi&`!5 zPS!@^z**hQQ|t|GAh8}QGuUDKax$)FP;3?ZBhntgCo(QmzBJ_ukkeYdFICWqdNX2g zCu+bJaSP{)FnllFG%8qt`G>EWYXprlKoaiGsfAfPtoqjt>rjFHuYk4^%nO`~R2w*@ zxm8pWA|PA|pLl*Aypb)gqi_`F5F|nKn{++R-d`cO1N>x-Ndwms#kDzAO{TaJOpz@@ z5s+h#ntId=oGpj5m4RJwma{|z4gWYp{2ahXkd>?jc4MlPwl8*JG8xV9>K|{D*Ucg3 zWOB^hXcbW-rS?j9ICTsVk7|c-1l!OjE4gFCLya2mC7hkoZFQ4)rr z8qohtbwT-=qmViM9 z<{g9`!&DfZ7;=L5+@`Ffq|^!KGC47hx3wjMK+lN>9R@N2L z>%;*_^%|hWCspG>G8~8;9tn5MBu*b(bza&=9@j(dO|0T_-l^G>_jd%DcvP^6wbs5mNWA@7qg1OYYI^o{d&Cs_)H*VNDIX5Q8Lqf(*@8{u7 zxYOj&$XG<$nzL~KH@hV?VX22-u`{hOo4*pwx&g40VV9QK zrM3EXO|xG*NEE7R)T1AvS}+ERAX=Y`0Fi8I_&q;k!$I$Qq;eDNbpmGj`(Xv__iF7C`Br{fe+KRCPc8xoj)NqFw-+94=C)L)}w?)@)U&tdsG$fPtb(8FngL^{_gI7b89gQd_s zUNR!Pu+}#Dt6K%BIX9Z+;m0>|yIkbr-+-k)h>BJz;K-+kc?>s*nTkObIU>AEpJcTU z5(q0rePj)`!5~n;#hFZz7igb80aERwWP|F&G|EU zXaT}54FrEk4^p3-1944Y?UG<-OYP!2Q-)?j*Ob8_kfOgOu?ORf+{+#fbH~DP{-ff(Z5x_1M zm)Vd#Yft%v=XKGA%z4L;?Lk{Ss9SE}g05%> zdgr_jHMNa)@qU7x!Ur-GX0m5GyVW-St;p3vK%0opHJ*XDNzfiDUJcHoHCq&W8@dvI;577z%m`%mPZss3FjV|Lzm6hy|2`D2oJm z@(HYrab6ntw#ojrZQ|>`W*Ph2LVq?q*(r4o_pyzz)+4>JCUn}YMPe_c16qpVSXOLX z!M+DNN8u7Fts5qV_>IQ7N zZfR0N>EKJp9Q)>+GpsylG&1|aGI~E4V`4A;Ux=#9b#wH1JeX9z4h z+3b_31BL*BkJt>UnyL)Jb&+>+5gRjeJ_d;SIi$w~);b_RD<>@CbVb=f#FLCc;mmzy z(YOmWh@zREzokV)YzBnm(5RZJ5Es>3kSc*=nl(8zskfc2w8-Ads`+cER~wB!&Aavy zhyq zz`=cO-^aHOs}i{l_83zHq-F|a01|H%#OJGYbdePxE}A?iFNf^%wsVrYI3nQ?pWrk} zh#t-c=D)h^+47yfPe;(Pc5c zb@b!BdyZ+86EfElsbgHb`K#I+E|@q<3D(;i)|XGS<2)C#6BV{Y84kM!voMdwZ5w_e z9R3%HDO=EwSlq!LRmbM9H^9b&z`Q|RZD0-#d&R!SK3n}d+Fiw%P+ntA1vkVPeXP3L z1nme+pGQK_xgl?`R|v&3Xhn&IFa1Xz198iQWQM%l#?P-3_DNf{5rXh=|@I zW~W5`p9CSJ84!nt)`&G5ZEnxQegy=eAOu=e@f`ll4pqTsv%fXm!YcF=?(Ne!ZE|B5 z863@PXNQmzHcuJ0s< zXcNGT$R-m>pruY{^pM%76)m=*AV0#{6J7lx@8lwCA49SeFox<#Cmz~z9WW(?0hV}c zgk*Drk4ln4W#=Jd^76E7@bFNIe4 z3s*se23(S9EY zN+Ud~5GWK zKw4NTe!-$z*7Df|35XzWpKtleps*y)%~%{?A5MM@EL6QnVz-0%MA__zz;pD+drXrC z`!?JV>>344v>;ffMEptAx~6+!mYOc(@UZ@K%+k`8@)q%)l;#G z;Mhh4ZtB07z>dmyGNy1f-K`EOByZ~=JZSI`8T^rpPQtU*alk0(!}0q^#|{@xoV@Gw zT?g(ub}A%5VV~_2A`yG93Fp8e0d6I$Hf}a;1Yd&&L4i$O?px@j-UK1LWGwXu=tidm z;K?8D)n3D9sa4B)yN>!plp4m*AJ}6EYQulH^5y19edgnOwjx1->sb9}UVeZyhO%NSBqnOTaAN<-{l`zKKSYc9!7IG{K3{g7 zxX+Z4o#C>hUVe{E4YB%-y!<{d&#?3SaVyos$4~H%KcS;u;^jAR;m^V`Dj&bp=kON* z)o=36=Xklq%a?hPmGfWl?(4jKlNZ67Z}aXuyzro1_0PQg3orkQ3x0wDKdi<>=ky6d zDRzN}=g0vua*BwYouO9`JNV*eUY=wLiD!E=AMfO4l$XQ29N}dTF8S^|o5!NaujvT; zlE`=U0CPRaOM#b3UMK`~T+e6N!Ym&dg`>SqG%1TOU)$g5mDXMX@ehbWSq!}IO>p)s?tgXc zGVe2%{p0NVfj)=fhL^LwL+OEZU#8FL%h=ZD%h|VXNey0STU#$@ukGvJv~h^E{IYG4 zec^gJyLn(;|Hl5Fbf!Nc|JLzmHc;bLXmYo&aRVd|G*I9tS@KNIIRYG zvzN11^{>OK_7f>E|CO0t|-j^f0Q<2acrx8t##ZXdVeq`RH;o_4zv&x}u!_ITd7J)U&NC-I!j z$(%{jZCaw{`~Lgh!%`?o*6C&uZ@u@vyZraR|9(&R_opNH_wPRP-Tc7bXyiZhrv2aD zxH*8IyU&V5R3sNsQDs%4xu~42oF(U2E+%I?XUjRBi{l)tB<7O2WYpwwat@x^6=yD$ zOUAAjKpS+7#GIRa8ez{Im2IdBHgL6Zx2rqU9(AX>OT9Rz>9y&&9@#iDC9qIw~AkH@xljcJ)xe&`Bs%vAH;dLdP+Tw^Mrav<#C==XH)^_+tgV#jq~kFsiK-u=hS&s zQe`!(Dr!zuRZY#S1*Mg%>S|G4P#4uDwRA38iq6=op+2OVxL@|~Kde5Yo>d?H{8;Xe zVsvGXdQM$lwQ_eJi>T+-3(rT?3zx0jUATKueGGRWD-K?c<=&%SQXj|n?^f2y$oS7U zZoE*?rNY@t(albuFHX-EwVR!(>FlFR_4BoAcDkmD>AxcIO^rvrR7Ef5rwd3p9`n+w zI9=0)dQH2YGgniK^-{(4lC`tt;&k0b>Y?M+nW8RMr;CSb)q3$#ecbZ;?kl*(L*_$X zT(ThL^(8kyUvum8wQ5o2ix&!&#X`MQtLBSUR!xoDo_+uEWA}Th<5NeEoH#Od=!iEQ zUgnP;JpRz>6Gyzk;|JZku9cMkfmfs6@VR0=f38wHTd3q~^DMJ5^i2LkdzL>~m}oqG zE3bBV>3n`>vA(E_`Fvw6Ke?;pOTB?JZ2#PZsN5 z`o5)l@nl`2T3(7BUMQh3Z@};ShYQuhIovz<7u@sm-PG}Van60LRJ`apxYVXHa)mMV zoCk|b=56xf!aQ5+_4yZ)XW-$*I`yum7OCRGkj%(00q7LbG%YFjGb0hia7y;EdfcAep4^2#wwbx$kOs`b6;p zV7tU}`c5v+&)0O_MgMvI!43P*^#+66L$x{d{H50Wqm^2r-pYHtT5r8OQCqAkFL?+j z^rRO*%uev^!=-8DI9!}5ELQ4rV?R`K>t2ilmO83yjbc^CZmKX>RA#7Ct%f83C>T+U zJ|>Tse6&zU;Z@JMuT(AQrQ?rG1O12pY+O0`9m3Cj28YH_GqMtCM#|CE=(6>Aq`JwD z)U9%CHm!F?Bm8?3i@?dq6OpD>wpZfK=()(MbvW{Lb~#p0G-F7cylmJ| z5Ic~@!uyzOJl6O*nP%D2OtyZ$n607-*^-+rWX)X4mgd;U*%@7%%ND9Nq|sTTiAr&D z>eP738&b8rNs~8^y(G>o#!D8=JoYyE6Z$^PBn1#Wa%s9KQ^QMCYSRVan;0gzmoB-O zX7z%A-EsLYI(N=X96fysh=J(CtTn2#!aPa z9;;AZvYIMS?lU94e=^K79@mesya!oS46Oii25Loxxe8SYF?W-STdinIo+E4rn zUb+b!BG#s;{iZJ9s`Qr_3M^5{xxytEsH1@!-R{nL*T^)jW^{98IfmIehIE{pk9MZ1+n9;*aso5)Y%_LJX6(4t*b1=E)_~D; z33Nm?J6FVVtvK-LfvNE%Kpi+EH)=o}h(qT&J6u_<`%l(u^9IQhe-hIl(YmJFdb987 zVpXs!kQb&;e3omJK8YskGdO@)#0O>Sn9=0yG5tE+s#V_9>eunk9m63Kv!WyTbD~x> z6CH>-INDKt9&grkD<^<->ls`qbS2?#707HkMzqGOW(-K_eoO?sD_gh*O@mai)yP<6 z*;;stPxVtO#xtK(NBt)@&rJ*opEgMc#T%EjOrR`!O&2h00DW^pgJkQqY(XiWi00;s zu8W0KCXm4qKuZ(VT6Mzp7rt~B{|Z%=U95uYV6Ur*I#+QYryzY6;|8)xQhJd_EPIpN z*pOAl87yroTc~G&V~TvZxyQq7Z3eH1({!y?moWi0M22e3OBGzqG|~WkPt4{yXbV19 zR5^PN6C*bm-1}I!d;B)%Niu~^%S(sk*&+W3BjJwX5V7rOIy%5Hj3#hQ;H+zSKFv`J z{&6vi<0qr|=eST&8=$_7-q%|(0ugguiLOTQ%+j}G8H$*rJi`LijMigi8=(Ift|Mhk zkg|(Q zNtD8$BPD&Q8DB{?ldDl+vSu@hTKoZzQj6rm^9xP>nsNQzdb-}%jPnaBJ{!~DWew00 zOyhE978r0mQTQ=XX!dZi4%!6pf}tePoGV?x9G%fv+uSV3FO5?nYsgXo0(ZJLUz|+K z^{I=sb&_T!Sr#i&HCru~xS~o900geF%IaeFyuk+`N3h&-EjH8GWZj)DxY>)vN=35a z8pwj+^Sc3}^TjGxXS3G3HBNip1^`_t zfNsgws*?9&sZz;;9LQd*>Dk@cv&HEGDC}$rs}=eNU##H6eontfj$A5`7TYWNIlHEb zjj{(@5BTuL?0wnuXcIf!B{5?9*Y7mEICJRC?rf!4kg9T4XGwMm<}=M=Dg0-Ozi;QE z@x9r}$<{mb{E&Glm6L-wF+-^g? zh93al^%4&YxioI+91?lanXb92pTgtsa0gSj8s}!qV%q`aSEFOPGGG}$MFl(N;x&G-zV5e%`+~+br`C!t^veH^xMtimHpQB874-S!G2WZLs zWs;*nOHMTLrW3a!J6T<_p>WA=ix8P8ZT;?JH zZFX^92+g>lTD)Pu7(|_%Hmq>hNO~j0 zutl9`J|8h(Wfg=PL5&kp{Sn-EKpQC!zL&aw6Bnfj$TL|Sf$+Zgl(lSuk~j2Xq#5&3 zVt?PBmLUncmrhY5?9=r(j}jd0Nw(^%g%w3DghT{RjuvZ*pk}9Ry zV)m9xbCp}NI|cn-1g0%q067i5MqW%}78HxO$imNrlWyVCE#te{2)Q+{r7+S4VG`8e zohKuEp;%cmsHS6(11ell$}S8tP|EfeN&#DtC3+#%1N4HmvKzIu)5z(At_#t|6#BvI z0}91;9zqFl)(02QnRl-mWYb16htp5cO$LZVpwf<6S2NMZjd_ew9;4y&a&8YgeM%GC zc+p))z3Aj$y@`LPI@-v$Y$wS}m!i)mXobyK?=i`&Db1#1qNT}L89E1d(L(nWa`sgU zb7xgy|E(zR|3jWgWBXfF&QFY@Vzb4i@w68&Q66G&UC37GM^TQKFg&Ff7YOpwU^O8< zAV7LHXg1{~T(G*3Q>DBNmbN@5xeL^(^e2(qO#C<*AXmE8OZu>t>vJJOt16lGxe@c! zpZ(_97K0B8b?}=mdl?_`JG#61L)~q)IZ}cb6E=CynDvGew}2BzfCJOOh7O)3EZcJ4 zw5-fk%eF0INfLGX)2Md`UL>9g@gi3v&fC_SMhQccWY&I==fEhq+5`M!g8+-`{mpn2 zjG{h4&W5ssg>2K-_{r03>*>On2qj~Ue<<_Br=tAMA~VamENjYcgAI7EL3Wow-b$8T z?5|yu*^`Ulaf6K0g(}Dlh%$v0Mp95g1btcC%#`cqo{_`k7CN7wF(e#|&t3#AF++im z$$M&QJnjvU)^@@4=7mTQmQ=sY(I)^29E>Ln|FpyhWHobr{)h{m9^P zkMstNG=N4rBAj&`>=6_iNszx9h;ew+7|cvm{~Dfl3?>JX3!N++cjJPzHHK`LSu&b2 zy}b#p3F!NFf4~xCRB@jO?#)0=ox%!e8fP2O&iJxcnJD^KQMUdp4_ym61SKM+G3yX1RIWn}0^p_aacG-fhi=2d5F1TRjp>g-q>sH`!b_ZJgPSD|F2p}lY;NIw?t zrGR~Oy;g%rD?WW5vRkiT1W9~MF)O4Qj$Bj1nV^KcxCSuBdVlrdplayVs9wd_)^tVy z5$?@+`;w3lD^UsyF|ng{yG`sAZ4)|8$($1@pi9w%AS(j1(BV)HaBTyAlf_x490+{y z0-Si9&O)V2_eeo&YQ-VC6F(uuFhnDiK9y0wa);bWNNC8GP9mvKE9;kV{VEg|VU^67 zQSu|h^?1-HGF&_I1|wj!L|}rIcrD2cX%op;{TUu8a?;Q8K-w5z{UT1ej44KhUH<6& z1E%3;z2P+<0YWq|6S0S)`nQm%qYK!4{tn^i?!9$SE16cTQ~+44-;5}$V;G$l?&f%VHq|wnA`Ptmg_)uu*RlG8 zzs?P#JA7SF-l)I4B!noGx*5(WZpbO&eoPHyx$ta=uq(RCk9KwOwRy0z1{hsv+$xoP zVFs8$ByMNf%Uh8t0>(!EUbhpYU~0IK4`3nB5NCc3?;)hW@iau^=dyvAI(w7GS_t7* zv278&GDaQOgn2&ES{xhqp2l+{ZzyDCX0!^TsDBy~MW*meEYIEn`&P9j0%+xH`yh+HsYlVWJfnrcE%`h^hdyiLvhD$1IhMYayO0XN8id!emK|LH~AC)EGJ__dCE08=(MyZg= z+_VQ)k7=}UAP zZu{4R!KdiQPk_Rp<2z^gw(X{z?QP4(*+uic_N=UYkR5eztBx!#94s`N)4-G`L>(Hz zvZ{~+g&-^SfDZb~*6s%26aK^~sz&+0K^r>1E5c=TLVK$eD#EI7F;y2L)C@$ph+Y}; z>lr?2e7aS)rP^Y45u!Eb?9r3>=Hk4kq z9*~&@6iiE%C@I7kKt=`T8`Vpl7DYcK>sR`X&VRy?sEzluJ{YnEz0O{IN3%+!Yvpgs@c-FY9t*;3mte6F^fziW zZssw}b!ben)V2~p@;TpX9Kdp8i1sJ=E?f>8&$ZPDbVYl%oux@2m7wDx--8YV{UnKS z1{s3tU|pS?*G1?-T!{PFk3eCxouT~)1$^TCA?eelbLTtX373Xv=Jge)S$~yWpsNh$C^rUc@CGXT&h+v0wj0b%Egb|e)pYw8r$#;Yi`i2HQ&7H zAOuNsFr+{exeQ2q(TDA7Odvu`bH5`x6r7C*Tf^5<_FOz)qRhphz(O|Yv~UDiYc`7| zw$-1NejJs)v$4fgy4M#0cG*KvTeU$~i(o*(9MLNy(?~%Wn;=FIh-*eHTyrX?lF(>jbI_`ke-i^$ppCl4s+UL zPIsEqU2?hu?*ML0!V{A4gd{v62~K{JJIuQ~%)2|xyFDh~9`kOGd3UFIc&GW^o#x?P zw@YDnnRj>Xfvp%9r$a_EtQ*_vwLnZ9^sh4OmvGk8WbfMl#c*=~KbJbcVg$Cn5!(5} z#@A9Y*mK&-R&ku;Dxs1%Ct$(qsMPb2hvghxi-HB$DO_h%zdTQ?0X2xUeQHPz9qhw4Z2Ina09EF${@_Gd^AN886 z)-PELHqEyhi4QGL?Ela*1ZN3j|MF@~RL}YsP=FT$rt9vs^ggb~T#omrf^JJ#i8mX& zy1Pvm=XE~cCRYnHHimqtQCYts@4gZGe?m?5|IEX8c<2+(&eosc11G4m{$t!i{`W_G8k=*^b$!wUSed3L_}wg$MMP+mu+mrU zH?22qCxQFmF5!&y069}YN3TEzBswzzIf~q9ct+uMFfA<4ro33{58){5*Q07olFx5p z)$l{rdceCRS@UsLKt4{ur)09+`m}sh{~2EB|BZ*PQQ(W~!cSU_O`WjP0_=D3(f_#K zNBQE0wvTqr>tH#&>Rq~%XKcMKQMy`X!W(S0()&FHv*fLyOrlGb_#$k9m)}d zSXh9F$Ry`fix+#E{|(KdDv)#si<=r}2N11C;^}B(Tjx-BC+-jw6LWR8t*3(BV^_C^p!A@4_s&R`Gv(o z#eb8`LqR3`+H!@+arH3%PFUou@K@FY{_e`k_E=izkcf$9?d?{Rp8l5Xnf zoTzO(wlfMPb~GLS97j@3BSFW%4DJr#=l%)0q@7kO+Mtgt(nj!mioq}mG!yA1Qc9n< zXDm`lq>exrnR|F9sbMt&ZzOY1pQK^&N;3EKP2&44{`+f-Y01CUzo*9%%fH^-&m=)> z{W|@Zo{#1-#r~B6bt4RC;K?NP*kJeseogXZh~7=0%!cJno0rpSf__etW`y2ONV9<+ zPdJa#>j~#;==p^67`>lx-bfE9oHx-63g^xAgu;0Xy`gZvmL5?!Z>3ih&e!=qQQL~w z<*qMo%Vnhw@Q>0+o7;?=7{{_m&!`w-oBMiyl)r-%773oOc%|%9He-lCo}-JNQw_-R*J* zk1Dylqqv8jRdRi2aZmBC@_Wj6`^Wbx{rMO@uAaB??e`%iJg+3>&(Z%1-`T5{R0HRG z=z)dvKDDeqjPt$pz`}XI`lxyi=l842>Uo?Gs29|WI3H9WQ!n9spZd7^d7KZaUr?XG z`LKFfeG=y*>KD~3I3HENq&|i7G4;#pS8%>xeOi46=i};E)n{>jK>eEf9L^7_EYQ&B zy`jefuPxEOLhkcpQN@YxmLT|D-F&8-z0DV-8M|X92)N&Xkqh4VGNclXsYtd5?+pX# z3$|3`t&^Y5SJcRg1yT~OL&kV(7eok^ncK(!ws=a(T*XI?@V&q0)hc9@I(jVBL68+C56 zQfQZPWnrd1E#|gd&xwoK?NVwuZf@3y)leLy-4KU?dutOHj88T;z{FjKyHJ@3##hj? z7n^o3G{*LU#Gfl*NU%ylWdOMs#%h1#*@q~N!}nU*r3$d*rHd6L3H;PqnCtnr?daK{ z_{r=ESOUzQ#fXR`f@%YQTnZQ9#Aot|7}R~Jqwu<#b2@Mvw1I; zpFZ2@+ZR6H-)IK4^fhpSa074)Ngk}6XDDV2GPGo}kUp|MC$k4zFQtP;wi9)3@gL7K*(aij_# zcuw%jvr4tb2ZB~{4KB@;(AU0Bf^{UgQy@p4Sl?!4xgyC2)u0AT4W2T#eui1MZhJ30ruXH3D)3P7$dFR@g*A8g#HOPF}eV z16jK`;j4YR1Yz!}#<9*>?9bRP%@xh-Won}eFvt{81vw1aS*Zr|PT;f2sSY9&6hcer zFo~Nw-FHB0u3E4j0L7iRC-x_*$)Ytc|bK9LA}6^--FsYngl zG17&JXk+tZU8_eZ)zJR}**f}%L^vBqLfriX4!)%oNb$fz=rCkVAj@I7QI3B+BDO-1 zO2I|V^55VL{|g9j#I*P>-!L#H2EqsGNty)1nB@T8I|`&YOpsGEumDl%dmlC(9sC*xlNA+t2d&{m-jOzDLq^JB`soXJ_o{DJ53$CY-lLr0 zciDSnToUw1n_Sap7vOYQrEv;yy=AsAMst23YxXdnn z1vy@Y&`!{K9!rX;zKk&I`1`CQhbRGIKsqAB_bNDl%wN|?zxwnK@Vd)r$xDDgoGG32 z%&OIbMft?vGeZFf*a#~HCob`L()41~7jS6jU2?t|F)XL*HO~ov8d?b|c8WGjt~03@<4H~2;_Xztd=2`H-u~B{0bK~dJTKoyjdIaW^IC4&ZkNO<1G!8 zPhXtYuo98zU*@4}fHMYY&4T+Kj`09eMQp$-e0w)RaBM{z*R2DgCYSyO%cb{gzoGJ`Nq=K%7R95O6q;i$K_?AgORi>eh1r24n6@pe{!#M=r-9WJ=&}+-~d;2=zf=uNhR|Uc|5q9BQ%Ahuqy5 zT|r`?FQS$*T6E8M!Tw|E6;~^`x(HyG{VmABWOFzZzQosGmkGZKEp zfS+|J`a5h!-eN>X%ybFuNx<9;hE0P(?K)GYJ^jx(I{VD%yt{_I#qf-n;c2hgXxI|F zM@!bGU(=FzFjTL`8uyx^qCXzH{bw92eLZ09Ek?*kXhG>)!Zxjs(1NsU+Vd9k=2fe4 zuNj#j_s`glw-_29j|Bx^A2wlqJQk!~(}Z_0B(Tu%XAit}|2vFGznL?B;Wve?i8Z#Z zGhO_oYZ~(ww$5t)(Z&0rdARJ@O1h{ZpIpo5T-&q;O`=~yEwAZjU!m)2ad=0AG{8Vhmc&agF z=6_(__|E2y=qiOa^sSOYzQA*Wl7zz*dfBMr*6`URlU@FHOaDK;BXH|7E;F_5Aa#A7 ziOw?Ju3kx_#XEz{#v|l^;TjVidi~uEwPa^UG2GEixF$BXx2nX=m1C)0`b|Ccp z!cNQ>;leR@DdnO=Jf%7n|C+NsxaMrHaF*0llxAT*HT=2XCvi}0{VB};%xXk`N>cUX z4s*CXBmsru_27P3?h&SIWkfK=HeiY*T<;?*8=7SF9AX1F-X>N-P%nH#=4GOBms!t( z-VfNh;2uWM#yCqti3BzT!jI}dME~eNz`@snkLp1Ta*mPk;0Ffn0An~9XMESYc0Iuf zBhn0aWD!wSNckHkkkGAn5!5(5IR~H!2`3yMQv&e}bp#gBMLa%8*u`9#-RXs0Mv}O@YRl)7Sv? z5)KTTB_ilmOzaO5#wlHf6i8q>Q=vVP{2Q!&GN@1Cli1va}U9w81mW65W*P$=SUO zwa0@&L;-~vMus1fl9!P`Sb*XNygQ{Dvi5w2@WyZ2koz}oUk5Lm`uAFNq)34&O5cte z0hIt6VQhRzFX7Z$P9!XhSs=Ln7(ZD`a*WUPS8)ZS(pvo}z2-#4c^L|f&xEW@v_WahY5|qF%n!W z@bAr^T?%|w;|NX&EmUVOdOlxny6D5~&inA;NQ%>wG9g%`UIQadoUN!t!4 zEtVzT`3o8E5pD)y7KUKt2j$Cpe7*Tn$IK<*;LB#_Zo`E{`arxaf7WgRw#VEQnG$p! zfjO+K@*hQVL%}?UD=%%9T`uT7#Sla0z0tHY)oTF+MTm!PSODRBgkrV|BYs+po zs`nAK_7aNt>;&xASe4&nRoE91*pIDK5kF~1Ek=|0H6RyD!5ShPXBW6c>Wi#uwoM~p*dnohN!Ueya zEgj|H+ity?d?f~ArVnXTa@AgXpDaQB&Hj~Z(Zd5^JqB1}?OV-(6$FP{jq-?>Nh~_rDjnpjfk&O*46g1Sf?;woTd5s zo|Aldhn8LkX43R@OcR3avV2Wnz?*3K2G)nAXvMkH?1yD#6nAxe?>5z5CTq}HyR8C) zfK-0Re~S@N1FSn>>UMlB(;MP24vAM7DJF*R-%;L!_S^707+ATJj3}>>H&TWvmwAIy z!R#W3<+o=y>WsUly>j;|U|8}7JfdvcK{%I4n z%q;#>jTpkeiV{S>25h7MF%K{Da1C)B;_V{ZArF*n85>drrR)t=n5NaG7nfkvMqfr9 zSr8Ufh+5+$u_4fq3DIE!n0VKRODF@U`e6mlGhu;q8&FuVECZ_UKEp3g0c4J_`0UV7<436;(l(uOHEE%Y_#8nYCAekQ+3*rU{7$Pf|~KfFs^wPTFH;eeg<)5g-TgCxW|2l<@W?fB47 z?ac|8Ut8UO|HXRUf7Xxsu}tQH3Adfhpblw>Irz-NGwTi8P9yTifQ_0Vu(V}KERZ*> zt9YBv{Jot)`7jHCfFzcV`)N=D-tx=Ao5U6ncmwh92}Cc!y9_8>FsV_;2D|FlB>jdR zPyEzQq_5b?#82!r1Y6gxLz5A6>fc4jcTi=Nh=uIvOSl0RMp#*RdO_?7amc7oe^JbG z-k3CiN)wUkvfUV~#}S)63V|a8o|my{#B$tcK9gk!%;!^v`Ft|6u*GLSK~>e0 zSU|wq!?#4tp9M2A>lze0hG|11*{-+37$NZHJiIgYG|OaoMj=}z0h$P}bqHsGPue1(hV_4c>1y$^aW*&;!0CO@lV*m(D1zfGm zteD(u#x)eCeI6fPZ(RMcv>Kpi5p^DhC_;TQ1~wzqC(22T;{(Asa%2#pJ_1t~(rs32 z+!$%jE&I@t0<_!=Xko-T81;iLer{nt%w?Nz%2?0KSSR$8=%?=C)X$^dU^yAb$cRlp z$g2m~jex9(KF+HLd3cD2r}^xYxN0AUT$+H-Wh@v0!NVMv?y>N>F4LQYl2K6^E)pAu|M?(=(FPq<2goF|WXo*)PwZELg3Y`-fPTcbr>8;(N&hwxs(O+2vd!JK`EK07VE22gS2aE0h*z`7Qy@og%=R?ArxY7;e~G$VS4)q zVJ&)%ixK9oGcIpe2VGjP25D0+Ev^60w(qZ9r(5YddVpU>KGOqRZ~?493qzyz;Oqvj zSTOd_PvAA=k$12zh!z=o36hoZ(k()+8=eP!fm0A;`Y%{fel&u$r;%NUqzL#5cN(7x z|M5D6V!{p0<7lU>VlRsk+f-wtzerC6i}Zw9q>o}Ge~cWO*?Ky0axM6)uotby_?oJ% zM*zH&I-Ub2lsd+y8iRrLy-$BolD>Y$sG;+BDe}|*bz3dh3hcU5zmwXv^`QP+bkM1{ zsnRyu|J5!A!N-lBC1f((|F^AzxAo}8x5~Q)K*QSVb z@EYI?)AZTI{44%76u;qhvhCWLb;9QkMh_z{<+}zmg#h%ZHF2EN@pKFzo z8=Sq^@jweF%%1X+zG@Ceks@UfwvgMbw6fD%3JjIV)#cLP-m7cs>ibduzvEEejDi`1 za1;0)U*1hcmYx2ol}!J{a)$n^l}4cTzqJN?s36`(oX}BExI%Gvn+_O21zN)KpT|v; zzQI_&NEcG(s9z*00tnbfk^`g-cQk@b4N6=XHf zE!{w_G$4SvVKTirGV8bvQI*B;Wakw21`CxH<0YQQoMiQv{HZGQ} zC`M;%YAL%D^K5?_Xx!a}`bNNzl1-7xB1F6`Oo0rFfO=waF)2Qf&2h2Nhxa?BMFH(6zG73?OafJeL1$As(z`Nfc^lZ zuOE0Rf@_%LxQFY|A#htHax?l{$eXHuxDH=)5YpJY$DP47EU=-v!KNb!+Fn8Ad%Dd) zmhOI`3CEUIaHe7YFEBr#*PgX%zlogKKd79c`V%VCzUs~L)d46#zf~U;cN>O&f%0@^ zh^7F(Y84xrD9Fko58v+BV;Is<+#xs2fG};H@HTcmm)AKNVEVJh|m%7;a}UrS4W88gk)2jf(|(xe{Z8yvIh|HG1Nf7JdS zPb@tWKA}8)#IHT;%Xb`M$nkN-+F}Gv4)nd`^=rUA5;o(vMWpGhg^jI<`cYOto?a_u zeHn7`tt;1IjJKf=nWo>AxIBPT2J!ZK5K-@29zw1mM3%ru){TQ#F!r>$*FFzW18GrY*>+$x2uu4}~m#M@@&7Qw+R%YK;$2_@gdAWi4__WL}Le;gk+*jRF(WMLu= zKE*4kG9|G31H3)W!(%)!AhxEMG}jN7`)rAku-TB@04hh>sxOz%4TyLc7}jjdmKzCV zuy_QV&Yjo9{L27`fQdlJLn!+ecJ~Ut9vLR`Ci;fRDYhw^aG+I(8B7Ay14SJWLq)K4 zi%lb$#MN{n0qG-Tt}*8gdjvud+>OEvYzV3BHxrOxA})lVV)P9Jil9W3u8xrEjzSY} zWU|O>Ctk7L+I@wNofB`_&l{B_ZslvL8XQ-cJb-3wZ z8F{Q}*UBh^LQIsAiQvux0!w7*4H+$rpp!#k#tE~dS+FCZxQCMrfv=XKLTDW2QxLM+ z@212Ap23D8rO@BsfC(Nx*}e4qo|6b(d$Ut4hxTFcpN7;U{N!G01N=1bW#(S2lT6!6 zVCbT~Az}2cYLz{TtsmiQjm-LD$;HlDtResHMVyiO;$G~_QZt)e@!@#Jh(?9*u47z; zgf*g?qlEi2d?xd>MXJy9Sp#p|EgelcGKpNgf>wzHwAoiLPiaCfW42{5<|y5i^D*T4 zZO(!1C_J()Fk%GkipBss37jFnw==I>@x+zJjvi1bJfE)|lu_#l9@K|&DS{GeW&jw| z2z108afspz1*RCLSd_MdjVBe$^#*_`TgZGoQU?{|?>G2ZJt@=$jkf@TW?j;cu@r0( z@hqrp(gu!O^{<5D<}*Xhh&2C2n1R_<1Y}nT#ZGxUz@B%uitz4olq(|SwsF`}z#%xy z3$rr)9avF>&p>-w?spcx(6mS!$ zk2Q1xfD#P^WK!G{xF?gNR?xEO&^>uPsy~VZa8OPn{weh%`ZDgj;rvhV?1zN&1TKtg za%0b0Sf(HR1z(5TMg{~@x&3cL(ojxrOzAL`u=!hoKlN&l%{ye;KZ(SUQ;~ql*#%cN zBNbH8NyGezwH6u%YfCTIVx2mN=GvIy#%0yBi(Jt^!SCMKri5Qc3ZtTL;ToYPNFwAi zP#3kd{byKMSbZ;5tRl7|<8O$2wm4%OM@tTh2{J{JBbPZA1j9XoShyCyIL#E_<6)VH zB9l4CgH3be3)ES7{r8;WiD zZ8&wpEDuk)8R?ji0w6BpHdLSf-%qJ-Wg6}x*Td+n!~9^HP#*lF!5Qxb0gng*UIDrU zWLjDfFvJak)$OA%f!Tzr>QPK`tBj};M2OI&@Cj0xCuArgxB&XokIIBMf{Y}dIrycB z)bu5UF}noM53r29lXQLc%nFQ@Rt8pqdQ}`q-zvk7oM?QNiqizyNHCGV2YO-{*W&T9 zYJ=g3R-XXnF`~au(Fjl{m_qzU$@=K;lYK<4@ADf9w(@4x2h*<@Hk$KMx?h4I zSpDO$gm0;SlmK=QrNpF^0R;w?PfV%3%2I>N>H4)WU&F$RI$mWDF|?;@7q>4_e6mp|D(bnKH}L;MdYv1AhTI&4Lkfj;B~l&KmB<<3t*Ftz9dO60KJ~ zL)80+DB#L4Lk`Q{QZUyBIg2pXDRYlY<8ptM={C2glPFerVA5~s@k)Fk#;?;89JemS zEv8mNJqpc8=YuwW?bq=&y25}O{yZ-AZ}8s1a1rCWMh={ANqD`Dp}tTUEhGfaCvrT) z+`{B>LnqUhg4Msq7qXTKrhkC9qyZ%a0;4Tp<9cjERbM;{LRio>LCfH5;S4{=+xJMJ zJUq`s6VI?3wRY)pbD6-`NDMo^%S^I(%7DsP-i4f#9814aTB|2-+TH$idhc zw3S4@TY-)p@MjS5(XIuK545TtwZPRyM}Wc;;QlBAOyfyHOcMt1p7zwnOu@nxwzNwK zGRK#Q>U$U}cSCpwxy;p!(0m9#mmP=s3Skq-NZjDWhtp%_J;2zH$3Kwy_Y@ia+8Xy2==FulZf!B;Fz zvwMPnl$mmhvb)^B#ldV7wj9THTwL34spVwV zuBTxs9oL^hE?Nf1U^GB$9`FKK_MVW13vL>C3uz~J5+zDUR8BZFaUlbWK{U>j+ybm0 zmLhZlVM+Z6W|GvOk=#RV646L`xIDsz2Cj}@m$!+P4I~ovzwz%zSovntU0{BA+7ivX>!!R+=_J%>{h}y?q-U!uS^qi<)19FiB7f!n_$5AX&FD z^bb|r(ZYN+9fDSZDfdlmj zjKW_jVpp1Z2EYrgN%b$WAa2QpxTE#jbgg2TWg&wDpRX_i(QVmKV;1~rIBk8xq5s>CR}_<|68g8&6($>z zv{<$8MSWr1ZsKpY+%tS1W^T)Cv-W%zLvHL9Pq~kdBF;QhO2gqLu`93P64UVZr{xH7MvePN#7%!b5)P@ zGqxGD?rWnNyb~vnH4_=-8fd4StTmCvDHj@b65f>ca$5UuDF>bm?y-o$AsLHSnQzO< zGF*kl0;p{6u<*hAO+#fuAHRA!C`<19LRol*xmF>IhG@k98X}+VKL+;%nrjFgw(Mkf zBett-povX^M18^8LNEsBSw~n^>=()XQKr_Afy7)cf1@~n49pniWjDu6ek$OYE9m_0 z0eK4Vf64&~DZTfvMW*WnE<`O`3(&rRb#Av&^6V+JNB7KK;-UFM-(fa7_}Qd>@H=gY3sPd!z1l(R}d7Y*!Xv zq_~fKB6&y}e^5KfK=wwUhefx?0|5_?9rTVk)7GHf*gP{!#zC(T&91p_q`<=CfW{~7@&ptcsJ^ei$Otk>k&b&isk z+UJM++3#?yh=~#qOJuG#dYCR4@l%&Ic-u@0idxeE&e1#Z>xxI?qbUp2Icagkoj(BD zZH@E{+<&V%Vu(S5eIxt%5ZVOFH6YozX8RKKP_8x*03qcqnaIGqYFdCK8rKBjrzhJv z;J1szvmF)2ux)7#n;79yreb$tzK+(40mZXyEyrK?7(p>Q$p&M`CJtN`cLzg4_lq%v z5sW>9B0QTGW`<~Pb?QYz#tgr(2UoOq@U0$Ae+p+vv08@~m=t+#QxFcs&C}94Ps&Ne zCy>ziLOUbJ$@PbD!$NZ#%oZTNOMx%z5#U^9Wn}aUxJs~T!eTOhz*UCB&EV|N2u^S! zJk?C#5G=?#e*q@-gsv zyW|}sgU~1}iN!bv11D-Hu$2n$cwGiRSx&$c1ouIDywBj*FM5T41@tsPRAUsnIATsf zJoM*?TScB05_DgX^EvrCL_3UHTOXl{_OjKUYbIu**j8b-N7s1p$A1pQGz@W0m>%d! zqD!+Z#JN40HTa3%ChI$+gf!tA=aX=|L$_s$uy*}tU%UKm!2xpu5ujTnPxoAiwPt=U zc@iK)?~?Uq!G3~@kOLI+uPZ(eeNfskS1`Txzec5G=7`@Ayh%lhvk6S9A4WHbwqxWe z;!)dS!6~e@*LS*#-QJ*~Jd5o}WuBd3!HYZ)JL=Ezz&Y(DE{FlMQ86B1g0p-l@^sEv z!_3y0l+k|ZVZ%}bkti)}j1-$zPkM!iP8_cl%G=4lIe?cD2$X4BBtNkzr95=t4eo=( zIMYKg7veOcDKs}!iU9ynl36zWaeWz)`h7-A}7Hk%2 zdC793Dgl!t_}pV%w;&CTfg(p9SaPs-5c)v81G{HF8+RICl1?#vpzo_F$dnuNy0Tk@ z*&6`{&S0dBEprLuiX7qA-{Dj{Cp5SzCVVIyQW0j)_|C50!@*U8TGMbC2|GLY|CL8=x3{g?X=0 zsf|#5Z-m0TF5X|;` zE-r=(1G5z-7aisZzTsIl*Rvs4Kkqr>q6}_MAL0v#qI}L~LzQvK$qh3Sg>iBQBr%sb z%X)psMSCbtj$Yr%rE0x!$#^_EZB`?nLJ`o1ifKquc`;bcV8c>`c9O6BHhY4LMfb!Q z;tNiUQ+OE>m7op$Z2|l_0qDmJ2YRX+#TsN3*9pPu*b~j4Fnr_KbeW|4|bB)}cqSqIs)54FL_L&qV!r0`sj+3kQq144O{hye#RVVA&kE|%eEMi|oiKJM#Fx8`%Y0qjQz)|$+7tuVrUdPMkz7Cc!!DYcQIJVCdqum@C{O2xMwwC>MmEXufR9R zwh|5a*A)M}jxVR&*V~?ay^bJFO$W5=*HLC#e*;G>WvIm;$`#!=z6*BO5$lc&XhWFU z8QTslYw^ob_X@t*uadAA0lOM=s(0FWs+aU z)4Oq&9>DbpDHYLNTcx62s14p#R2sEFxxVGfsJTPEV#^s=u4GtOzjoW#)^1^>895`G zpz)01%EX`Dn3-%L9Q`~GALrp47*c~*{yDEc!DqjK18m1X%?BZy3Cj|tj5MglG`-9u zp%@)=`_UtZjvss||Hyq0cnP;y(9`GjSC~fD!w>N4aUT8-2gsWKh}Q(+T%Xv<8WzY) z%4!5ESLXW(Ci)d7N?{+LiloW)2c{k7HVF-*uvD8t9(GBW{P1r2yC?$N*_MhG)xC|P z-hdXr${C`Nh>E-fPywTQaE+z&5x8dj(oo&O$jlZmH@Y9iV55MjA&9tPkyPZSB(xi+ z0%Q!k20+n{AA|`&HQY-8Q8c8q(YKg;reU3Pj|5~m_oi?IV_I-Kv~>g;*$yiOV+%$L zFpy#pmqr4Ma?YOxJVQEe_bXu$R!ov{QW|^cJv@O)V52* zB=!SM>JJlCTA(2M-rvNtFksI#BNf6aV9f>(9YoN7M00X!afUG4TpEWn7}i0<<`YC+ z_-qhg`D>0Ab;$5LM6W{8ic#qi$=t_iZME+pY)I4)Z3}6B0_9?X2cA3!Srhu0#?Ta! z!AKeLlqsp8+ZJs>_V5}TYs9O!htFvVa!Q^jgR`VSP&0iNM2Z7ze&j$|35od%3?>%; zafW(>W)+472t{I4JG&5w4EA)4iwO-Z!^#1V(vcC7GhsF{174g&!@_F|F9MGmtTEMu zeVseCrmjB->zeJT>s7z5{+V?HTo}u_DPUJ{|IQiz@_2ejm##01`+8Kbj{24FHAE&V~Z(EqKD` z379g;d*MDIzJU=d{@{wjAU_DL!{9)P5v!MQ+mPzLCf9g$YWyMnpILiynfm|Yf#Ms@ z#XC2Etqi$wyI7H7dsbsJ`Tl9X~ep$cZC|^9N5HJN@vH zsZ-L|C%t4%FoP>*E=Dde;Ij^9b0}Ba>?VhY3=hynM)XD=uI1r69=7q2<>3Y%Zsg%6 z9&YC079MWn;cgsqV?jX5rRsE`K?G9CjRi3iI-l!%nDbs9_Vcihhdd8wc$neg91rJt zDDyDO!yFGW>89xdnxw+bYIA%eOr4Nmzs%eFc@P?#(#c$63hI=pV-zgbD&i}mA7To+ zdFTguph29m8GMCTRGUlmY)z$_C=*N^i2`patS}*Egt#U7CM%Q#TGj-&HX>MnQACA* ziP}E^)snj%DX?&*2#5H?5=6NL{$97QT77SE2LtK0l)OvI{ofKLY`yZ8jQ_l-FpiR4k%Fn*(?#qo#5Ha#L` z#PFUBFxXl1!@@j@WtRK1T^-npyN^U{=MLwD^PrP)Zgp-%t`TPpHQ4TqJ2yDDJ4xrT z)34cI)99-3AFs*C$YL;p3oN7b3UAj2T8#+}gLRmKV3$Q~BU+PE?_MaJ;l=h5>*?2ugqny50*?77@}Yw zC0Bn7wKV3WUq%wo(nT*Nvjl+XYU&vcm=dxz+a`AVIT(EypDd`w>*VQ3VdMtqm$--E zq+fN{Y-WgRU=QK0SCfnN5WjdS`kQ?E?|Jx39@zQ4CY0qX{p#Q(u)gOaIy~pVX)N@7+IR`Nl zb~zg`H{uTeZ9qKz;17|BG3OKheQsq*(i;v*DBaemtIfrp1a K66y6f`~L$UT!%3L literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/pylint/checkers/async.py b/.venv/lib/python3.8/site-packages/pylint/checkers/async.py new file mode 100644 index 00000000..1b581c0f --- /dev/null +++ b/.venv/lib/python3.8/site-packages/pylint/checkers/async.py @@ -0,0 +1,90 @@ +# 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/.venv/lib/python3.8/site-packages/pylint/checkers/base.py b/.venv/lib/python3.8/site-packages/pylint/checkers/base.py new file mode 100644 index 00000000..d830a68b --- /dev/null +++ b/.venv/lib/python3.8/site-packages/pylint/checkers/base.py @@ -0,0 +1,2507 @@ +# -*- 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": " + + + + +
...
+ + +
...
+ + + +' + for p in paths + ) + + def render_embed_js(self, js_embed: Iterable[bytes]) -> bytes: + """Default method used to render the final embedded js for the + rendered webpage. + + Override this method in a sub-classed controller to change the output. + """ + return ( + b'" + ) + + def render_linked_css(self, css_files: Iterable[str]) -> str: + """Default method used to render the final css links for the + rendered webpage. + + Override this method in a sub-classed controller to change the output. + """ + paths = [] + unique_paths = set() # type: Set[str] + + for path in css_files: + if not is_absolute(path): + path = self.static_url(path) + if path not in unique_paths: + paths.append(path) + unique_paths.add(path) + + return "".join( + '' + for p in paths + ) + + def render_embed_css(self, css_embed: Iterable[bytes]) -> bytes: + """Default method used to render the final embedded css for the + rendered webpage. + + Override this method in a sub-classed controller to change the output. + """ + return b'" + + def render_string(self, template_name: str, **kwargs: Any) -> bytes: + """Generate the given template with the given arguments. + + We return the generated byte string (in utf8). To generate and + write a template as a response, use render() above. + """ + # If no template_path is specified, use the path of the calling file + template_path = self.get_template_path() + if not template_path: + frame = sys._getframe(0) + web_file = frame.f_code.co_filename + while frame.f_code.co_filename == web_file: + frame = frame.f_back + assert frame.f_code.co_filename is not None + template_path = os.path.dirname(frame.f_code.co_filename) + with RequestHandler._template_loader_lock: + if template_path not in RequestHandler._template_loaders: + loader = self.create_template_loader(template_path) + RequestHandler._template_loaders[template_path] = loader + else: + loader = RequestHandler._template_loaders[template_path] + t = loader.load(template_name) + namespace = self.get_template_namespace() + namespace.update(kwargs) + return t.generate(**namespace) + + def get_template_namespace(self) -> Dict[str, Any]: + """Returns a dictionary to be used as the default template namespace. + + May be overridden by subclasses to add or modify values. + + The results of this method will be combined with additional + defaults in the `tornado.template` module and keyword arguments + to `render` or `render_string`. + """ + namespace = dict( + handler=self, + request=self.request, + current_user=self.current_user, + locale=self.locale, + _=self.locale.translate, + pgettext=self.locale.pgettext, + static_url=self.static_url, + xsrf_form_html=self.xsrf_form_html, + reverse_url=self.reverse_url, + ) + namespace.update(self.ui) + return namespace + + def create_template_loader(self, template_path: str) -> template.BaseLoader: + """Returns a new template loader for the given path. + + May be overridden by subclasses. By default returns a + directory-based loader on the given path, using the + ``autoescape`` and ``template_whitespace`` application + settings. If a ``template_loader`` application setting is + supplied, uses that instead. + """ + settings = self.application.settings + if "template_loader" in settings: + return settings["template_loader"] + kwargs = {} + if "autoescape" in settings: + # autoescape=None means "no escaping", so we have to be sure + # to only pass this kwarg if the user asked for it. + kwargs["autoescape"] = settings["autoescape"] + if "template_whitespace" in settings: + kwargs["whitespace"] = settings["template_whitespace"] + return template.Loader(template_path, **kwargs) + + def flush(self, include_footers: bool = False) -> "Future[None]": + """Flushes the current output buffer to the network. + + .. versionchanged:: 4.0 + Now returns a `.Future` if no callback is given. + + .. versionchanged:: 6.0 + + The ``callback`` argument was removed. + """ + assert self.request.connection is not None + chunk = b"".join(self._write_buffer) + self._write_buffer = [] + if not self._headers_written: + self._headers_written = True + for transform in self._transforms: + assert chunk is not None + ( + self._status_code, + self._headers, + chunk, + ) = transform.transform_first_chunk( + self._status_code, self._headers, chunk, include_footers + ) + # Ignore the chunk and only write the headers for HEAD requests + if self.request.method == "HEAD": + chunk = b"" + + # Finalize the cookie headers (which have been stored in a side + # object so an outgoing cookie could be overwritten before it + # is sent). + if hasattr(self, "_new_cookie"): + for cookie in self._new_cookie.values(): + self.add_header("Set-Cookie", cookie.OutputString(None)) + + start_line = httputil.ResponseStartLine("", self._status_code, self._reason) + return self.request.connection.write_headers( + start_line, self._headers, chunk + ) + else: + for transform in self._transforms: + chunk = transform.transform_chunk(chunk, include_footers) + # Ignore the chunk and only write the headers for HEAD requests + if self.request.method != "HEAD": + return self.request.connection.write(chunk) + else: + future = Future() # type: Future[None] + future.set_result(None) + return future + + def finish(self, chunk: Optional[Union[str, bytes, dict]] = None) -> "Future[None]": + """Finishes this response, ending the HTTP request. + + Passing a ``chunk`` to ``finish()`` is equivalent to passing that + chunk to ``write()`` and then calling ``finish()`` with no arguments. + + Returns a `.Future` which may optionally be awaited to track the sending + of the response to the client. This `.Future` resolves when all the response + data has been sent, and raises an error if the connection is closed before all + data can be sent. + + .. versionchanged:: 5.1 + + Now returns a `.Future` instead of ``None``. + """ + if self._finished: + raise RuntimeError("finish() called twice") + + if chunk is not None: + self.write(chunk) + + # Automatically support ETags and add the Content-Length header if + # we have not flushed any content yet. + if not self._headers_written: + if ( + self._status_code == 200 + and self.request.method in ("GET", "HEAD") + and "Etag" not in self._headers + ): + self.set_etag_header() + if self.check_etag_header(): + self._write_buffer = [] + self.set_status(304) + if self._status_code in (204, 304) or (100 <= self._status_code < 200): + assert not self._write_buffer, ( + "Cannot send body with %s" % self._status_code + ) + self._clear_representation_headers() + elif "Content-Length" not in self._headers: + content_length = sum(len(part) for part in self._write_buffer) + self.set_header("Content-Length", content_length) + + assert self.request.connection is not None + # Now that the request is finished, clear the callback we + # set on the HTTPConnection (which would otherwise prevent the + # garbage collection of the RequestHandler when there + # are keepalive connections) + self.request.connection.set_close_callback(None) # type: ignore + + future = self.flush(include_footers=True) + self.request.connection.finish() + self._log() + self._finished = True + self.on_finish() + self._break_cycles() + return future + + def detach(self) -> iostream.IOStream: + """Take control of the underlying stream. + + Returns the underlying `.IOStream` object and stops all + further HTTP processing. Intended for implementing protocols + like websockets that tunnel over an HTTP handshake. + + This method is only supported when HTTP/1.1 is used. + + .. versionadded:: 5.1 + """ + self._finished = True + # TODO: add detach to HTTPConnection? + return self.request.connection.detach() # type: ignore + + def _break_cycles(self) -> None: + # Break up a reference cycle between this handler and the + # _ui_module closures to allow for faster GC on CPython. + self.ui = None # type: ignore + + def send_error(self, status_code: int = 500, **kwargs: Any) -> None: + """Sends the given HTTP error code to the browser. + + If `flush()` has already been called, it is not possible to send + an error, so this method will simply terminate the response. + If output has been written but not yet flushed, it will be discarded + and replaced with the error page. + + Override `write_error()` to customize the error page that is returned. + Additional keyword arguments are passed through to `write_error`. + """ + if self._headers_written: + gen_log.error("Cannot send error response after headers written") + if not self._finished: + # If we get an error between writing headers and finishing, + # we are unlikely to be able to finish due to a + # Content-Length mismatch. Try anyway to release the + # socket. + try: + self.finish() + except Exception: + gen_log.error("Failed to flush partial response", exc_info=True) + return + self.clear() + + reason = kwargs.get("reason") + if "exc_info" in kwargs: + exception = kwargs["exc_info"][1] + if isinstance(exception, HTTPError) and exception.reason: + reason = exception.reason + self.set_status(status_code, reason=reason) + try: + self.write_error(status_code, **kwargs) + except Exception: + app_log.error("Uncaught exception in write_error", exc_info=True) + if not self._finished: + self.finish() + + def write_error(self, status_code: int, **kwargs: Any) -> None: + """Override to implement custom error pages. + + ``write_error`` may call `write`, `render`, `set_header`, etc + to produce output as usual. + + If this error was caused by an uncaught exception (including + HTTPError), an ``exc_info`` triple will be available as + ``kwargs["exc_info"]``. Note that this exception may not be + the "current" exception for purposes of methods like + ``sys.exc_info()`` or ``traceback.format_exc``. + """ + if self.settings.get("serve_traceback") and "exc_info" in kwargs: + # in debug mode, try to send a traceback + self.set_header("Content-Type", "text/plain") + for line in traceback.format_exception(*kwargs["exc_info"]): + self.write(line) + self.finish() + else: + self.finish( + "%(code)d: %(message)s" + "%(code)d: %(message)s" + % {"code": status_code, "message": self._reason} + ) + + @property + def locale(self) -> tornado.locale.Locale: + """The locale for the current session. + + Determined by either `get_user_locale`, which you can override to + set the locale based on, e.g., a user preference stored in a + database, or `get_browser_locale`, which uses the ``Accept-Language`` + header. + + .. versionchanged: 4.1 + Added a property setter. + """ + if not hasattr(self, "_locale"): + loc = self.get_user_locale() + if loc is not None: + self._locale = loc + else: + self._locale = self.get_browser_locale() + assert self._locale + return self._locale + + @locale.setter + def locale(self, value: tornado.locale.Locale) -> None: + self._locale = value + + def get_user_locale(self) -> Optional[tornado.locale.Locale]: + """Override to determine the locale from the authenticated user. + + If None is returned, we fall back to `get_browser_locale()`. + + This method should return a `tornado.locale.Locale` object, + most likely obtained via a call like ``tornado.locale.get("en")`` + """ + return None + + def get_browser_locale(self, default: str = "en_US") -> tornado.locale.Locale: + """Determines the user's locale from ``Accept-Language`` header. + + See http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.4 + """ + if "Accept-Language" in self.request.headers: + languages = self.request.headers["Accept-Language"].split(",") + locales = [] + for language in languages: + parts = language.strip().split(";") + if len(parts) > 1 and parts[1].startswith("q="): + try: + score = float(parts[1][2:]) + except (ValueError, TypeError): + score = 0.0 + else: + score = 1.0 + locales.append((parts[0], score)) + if locales: + locales.sort(key=lambda pair: pair[1], reverse=True) + codes = [loc[0] for loc in locales] + return locale.get(*codes) + return locale.get(default) + + @property + def current_user(self) -> Any: + """The authenticated user for this request. + + This is set in one of two ways: + + * A subclass may override `get_current_user()`, which will be called + automatically the first time ``self.current_user`` is accessed. + `get_current_user()` will only be called once per request, + and is cached for future access:: + + def get_current_user(self): + user_cookie = self.get_secure_cookie("user") + if user_cookie: + return json.loads(user_cookie) + return None + + * It may be set as a normal variable, typically from an overridden + `prepare()`:: + + @gen.coroutine + def prepare(self): + user_id_cookie = self.get_secure_cookie("user_id") + if user_id_cookie: + self.current_user = yield load_user(user_id_cookie) + + Note that `prepare()` may be a coroutine while `get_current_user()` + may not, so the latter form is necessary if loading the user requires + asynchronous operations. + + The user object may be any type of the application's choosing. + """ + if not hasattr(self, "_current_user"): + self._current_user = self.get_current_user() + return self._current_user + + @current_user.setter + def current_user(self, value: Any) -> None: + self._current_user = value + + def get_current_user(self) -> Any: + """Override to determine the current user from, e.g., a cookie. + + This method may not be a coroutine. + """ + return None + + def get_login_url(self) -> str: + """Override to customize the login URL based on the request. + + By default, we use the ``login_url`` application setting. + """ + self.require_setting("login_url", "@tornado.web.authenticated") + return self.application.settings["login_url"] + + def get_template_path(self) -> Optional[str]: + """Override to customize template path for each handler. + + By default, we use the ``template_path`` application setting. + Return None to load templates relative to the calling file. + """ + return self.application.settings.get("template_path") + + @property + def xsrf_token(self) -> bytes: + """The XSRF-prevention token for the current user/session. + + To prevent cross-site request forgery, we set an '_xsrf' cookie + and include the same '_xsrf' value as an argument with all POST + requests. If the two do not match, we reject the form submission + as a potential forgery. + + See http://en.wikipedia.org/wiki/Cross-site_request_forgery + + This property is of type `bytes`, but it contains only ASCII + characters. If a character string is required, there is no + need to base64-encode it; just decode the byte string as + UTF-8. + + .. versionchanged:: 3.2.2 + The xsrf token will now be have a random mask applied in every + request, which makes it safe to include the token in pages + that are compressed. See http://breachattack.com for more + information on the issue fixed by this change. Old (version 1) + cookies will be converted to version 2 when this method is called + unless the ``xsrf_cookie_version`` `Application` setting is + set to 1. + + .. versionchanged:: 4.3 + The ``xsrf_cookie_kwargs`` `Application` setting may be + used to supply additional cookie options (which will be + passed directly to `set_cookie`). For example, + ``xsrf_cookie_kwargs=dict(httponly=True, secure=True)`` + will set the ``secure`` and ``httponly`` flags on the + ``_xsrf`` cookie. + """ + if not hasattr(self, "_xsrf_token"): + version, token, timestamp = self._get_raw_xsrf_token() + output_version = self.settings.get("xsrf_cookie_version", 2) + cookie_kwargs = self.settings.get("xsrf_cookie_kwargs", {}) + if output_version == 1: + self._xsrf_token = binascii.b2a_hex(token) + elif output_version == 2: + mask = os.urandom(4) + self._xsrf_token = b"|".join( + [ + b"2", + binascii.b2a_hex(mask), + binascii.b2a_hex(_websocket_mask(mask, token)), + utf8(str(int(timestamp))), + ] + ) + else: + raise ValueError("unknown xsrf cookie version %d", output_version) + if version is None: + if self.current_user and "expires_days" not in cookie_kwargs: + cookie_kwargs["expires_days"] = 30 + self.set_cookie("_xsrf", self._xsrf_token, **cookie_kwargs) + return self._xsrf_token + + def _get_raw_xsrf_token(self) -> Tuple[Optional[int], bytes, float]: + """Read or generate the xsrf token in its raw form. + + The raw_xsrf_token is a tuple containing: + + * version: the version of the cookie from which this token was read, + or None if we generated a new token in this request. + * token: the raw token data; random (non-ascii) bytes. + * timestamp: the time this token was generated (will not be accurate + for version 1 cookies) + """ + if not hasattr(self, "_raw_xsrf_token"): + cookie = self.get_cookie("_xsrf") + if cookie: + version, token, timestamp = self._decode_xsrf_token(cookie) + else: + version, token, timestamp = None, None, None + if token is None: + version = None + token = os.urandom(16) + timestamp = time.time() + assert token is not None + assert timestamp is not None + self._raw_xsrf_token = (version, token, timestamp) + return self._raw_xsrf_token + + def _decode_xsrf_token( + self, cookie: str + ) -> Tuple[Optional[int], Optional[bytes], Optional[float]]: + """Convert a cookie string into a the tuple form returned by + _get_raw_xsrf_token. + """ + + try: + m = _signed_value_version_re.match(utf8(cookie)) + + if m: + version = int(m.group(1)) + if version == 2: + _, mask_str, masked_token, timestamp_str = cookie.split("|") + + mask = binascii.a2b_hex(utf8(mask_str)) + token = _websocket_mask(mask, binascii.a2b_hex(utf8(masked_token))) + timestamp = int(timestamp_str) + return version, token, timestamp + else: + # Treat unknown versions as not present instead of failing. + raise Exception("Unknown xsrf cookie version") + else: + version = 1 + try: + token = binascii.a2b_hex(utf8(cookie)) + except (binascii.Error, TypeError): + token = utf8(cookie) + # We don't have a usable timestamp in older versions. + timestamp = int(time.time()) + return (version, token, timestamp) + except Exception: + # Catch exceptions and return nothing instead of failing. + gen_log.debug("Uncaught exception in _decode_xsrf_token", exc_info=True) + return None, None, None + + def check_xsrf_cookie(self) -> None: + """Verifies that the ``_xsrf`` cookie matches the ``_xsrf`` argument. + + To prevent cross-site request forgery, we set an ``_xsrf`` + cookie and include the same value as a non-cookie + field with all ``POST`` requests. If the two do not match, we + reject the form submission as a potential forgery. + + The ``_xsrf`` value may be set as either a form field named ``_xsrf`` + or in a custom HTTP header named ``X-XSRFToken`` or ``X-CSRFToken`` + (the latter is accepted for compatibility with Django). + + See http://en.wikipedia.org/wiki/Cross-site_request_forgery + + .. versionchanged:: 3.2.2 + Added support for cookie version 2. Both versions 1 and 2 are + supported. + """ + # Prior to release 1.1.1, this check was ignored if the HTTP header + # ``X-Requested-With: XMLHTTPRequest`` was present. This exception + # has been shown to be insecure and has been removed. For more + # information please see + # http://www.djangoproject.com/weblog/2011/feb/08/security/ + # http://weblog.rubyonrails.org/2011/2/8/csrf-protection-bypass-in-ruby-on-rails + token = ( + self.get_argument("_xsrf", None) + or self.request.headers.get("X-Xsrftoken") + or self.request.headers.get("X-Csrftoken") + ) + if not token: + raise HTTPError(403, "'_xsrf' argument missing from POST") + _, token, _ = self._decode_xsrf_token(token) + _, expected_token, _ = self._get_raw_xsrf_token() + if not token: + raise HTTPError(403, "'_xsrf' argument has invalid format") + if not hmac.compare_digest(utf8(token), utf8(expected_token)): + raise HTTPError(403, "XSRF cookie does not match POST argument") + + def xsrf_form_html(self) -> str: + """An HTML ```` element to be included with all POST forms. + + It defines the ``_xsrf`` input value, which we check on all POST + requests to prevent cross-site request forgery. If you have set + the ``xsrf_cookies`` application setting, you must include this + HTML within all of your HTML forms. + + In a template, this method should be called with ``{% module + xsrf_form_html() %}`` + + See `check_xsrf_cookie()` above for more information. + """ + return ( + '' + ) + + def static_url( + self, path: str, include_host: Optional[bool] = None, **kwargs: Any + ) -> str: + """Returns a static URL for the given relative static file path. + + This method requires you set the ``static_path`` setting in your + application (which specifies the root directory of your static + files). + + This method returns a versioned url (by default appending + ``?v=``), which allows the static files to be + cached indefinitely. This can be disabled by passing + ``include_version=False`` (in the default implementation; + other static file implementations are not required to support + this, but they may support other options). + + By default this method returns URLs relative to the current + host, but if ``include_host`` is true the URL returned will be + absolute. If this handler has an ``include_host`` attribute, + that value will be used as the default for all `static_url` + calls that do not pass ``include_host`` as a keyword argument. + + """ + self.require_setting("static_path", "static_url") + get_url = self.settings.get( + "static_handler_class", StaticFileHandler + ).make_static_url + + if include_host is None: + include_host = getattr(self, "include_host", False) + + if include_host: + base = self.request.protocol + "://" + self.request.host + else: + base = "" + + return base + get_url(self.settings, path, **kwargs) + + def require_setting(self, name: str, feature: str = "this feature") -> None: + """Raises an exception if the given app setting is not defined.""" + if not self.application.settings.get(name): + raise Exception( + "You must define the '%s' setting in your " + "application to use %s" % (name, feature) + ) + + def reverse_url(self, name: str, *args: Any) -> str: + """Alias for `Application.reverse_url`.""" + return self.application.reverse_url(name, *args) + + def compute_etag(self) -> Optional[str]: + """Computes the etag header to be used for this request. + + By default uses a hash of the content written so far. + + May be overridden to provide custom etag implementations, + or may return None to disable tornado's default etag support. + """ + hasher = hashlib.sha1() + for part in self._write_buffer: + hasher.update(part) + return '"%s"' % hasher.hexdigest() + + def set_etag_header(self) -> None: + """Sets the response's Etag header using ``self.compute_etag()``. + + Note: no header will be set if ``compute_etag()`` returns ``None``. + + This method is called automatically when the request is finished. + """ + etag = self.compute_etag() + if etag is not None: + self.set_header("Etag", etag) + + def check_etag_header(self) -> bool: + """Checks the ``Etag`` header against requests's ``If-None-Match``. + + Returns ``True`` if the request's Etag matches and a 304 should be + returned. For example:: + + self.set_etag_header() + if self.check_etag_header(): + self.set_status(304) + return + + This method is called automatically when the request is finished, + but may be called earlier for applications that override + `compute_etag` and want to do an early check for ``If-None-Match`` + before completing the request. The ``Etag`` header should be set + (perhaps with `set_etag_header`) before calling this method. + """ + computed_etag = utf8(self._headers.get("Etag", "")) + # Find all weak and strong etag values from If-None-Match header + # because RFC 7232 allows multiple etag values in a single header. + etags = re.findall( + br'\*|(?:W/)?"[^"]*"', utf8(self.request.headers.get("If-None-Match", "")) + ) + if not computed_etag or not etags: + return False + + match = False + if etags[0] == b"*": + match = True + else: + # Use a weak comparison when comparing entity-tags. + def val(x: bytes) -> bytes: + return x[2:] if x.startswith(b"W/") else x + + for etag in etags: + if val(etag) == val(computed_etag): + match = True + break + return match + + async def _execute( + self, transforms: List["OutputTransform"], *args: bytes, **kwargs: bytes + ) -> None: + """Executes this request with the given output transforms.""" + self._transforms = transforms + try: + if self.request.method not in self.SUPPORTED_METHODS: + raise HTTPError(405) + self.path_args = [self.decode_argument(arg) for arg in args] + self.path_kwargs = dict( + (k, self.decode_argument(v, name=k)) for (k, v) in kwargs.items() + ) + # If XSRF cookies are turned on, reject form submissions without + # the proper cookie + if self.request.method not in ( + "GET", + "HEAD", + "OPTIONS", + ) and self.application.settings.get("xsrf_cookies"): + self.check_xsrf_cookie() + + result = self.prepare() + if result is not None: + result = await result + if self._prepared_future is not None: + # Tell the Application we've finished with prepare() + # and are ready for the body to arrive. + future_set_result_unless_cancelled(self._prepared_future, None) + if self._finished: + return + + if _has_stream_request_body(self.__class__): + # In streaming mode request.body is a Future that signals + # the body has been completely received. The Future has no + # result; the data has been passed to self.data_received + # instead. + try: + await self.request._body_future + except iostream.StreamClosedError: + return + + method = getattr(self, self.request.method.lower()) + result = method(*self.path_args, **self.path_kwargs) + if result is not None: + result = await result + if self._auto_finish and not self._finished: + self.finish() + except Exception as e: + try: + self._handle_request_exception(e) + except Exception: + app_log.error("Exception in exception handler", exc_info=True) + finally: + # Unset result to avoid circular references + result = None + if self._prepared_future is not None and not self._prepared_future.done(): + # In case we failed before setting _prepared_future, do it + # now (to unblock the HTTP server). Note that this is not + # in a finally block to avoid GC issues prior to Python 3.4. + self._prepared_future.set_result(None) + + def data_received(self, chunk: bytes) -> Optional[Awaitable[None]]: + """Implement this method to handle streamed request data. + + Requires the `.stream_request_body` decorator. + + May be a coroutine for flow control. + """ + raise NotImplementedError() + + def _log(self) -> None: + """Logs the current request. + + Sort of deprecated since this functionality was moved to the + Application, but left in place for the benefit of existing apps + that have overridden this method. + """ + self.application.log_request(self) + + def _request_summary(self) -> str: + return "%s %s (%s)" % ( + self.request.method, + self.request.uri, + self.request.remote_ip, + ) + + def _handle_request_exception(self, e: BaseException) -> None: + if isinstance(e, Finish): + # Not an error; just finish the request without logging. + if not self._finished: + self.finish(*e.args) + return + try: + self.log_exception(*sys.exc_info()) + except Exception: + # An error here should still get a best-effort send_error() + # to avoid leaking the connection. + app_log.error("Error in exception logger", exc_info=True) + if self._finished: + # Extra errors after the request has been finished should + # be logged, but there is no reason to continue to try and + # send a response. + return + if isinstance(e, HTTPError): + self.send_error(e.status_code, exc_info=sys.exc_info()) + else: + self.send_error(500, exc_info=sys.exc_info()) + + def log_exception( + self, + typ: "Optional[Type[BaseException]]", + value: Optional[BaseException], + tb: Optional[TracebackType], + ) -> None: + """Override to customize logging of uncaught exceptions. + + By default logs instances of `HTTPError` as warnings without + stack traces (on the ``tornado.general`` logger), and all + other exceptions as errors with stack traces (on the + ``tornado.application`` logger). + + .. versionadded:: 3.1 + """ + if isinstance(value, HTTPError): + if value.log_message: + format = "%d %s: " + value.log_message + args = [value.status_code, self._request_summary()] + list(value.args) + gen_log.warning(format, *args) + else: + app_log.error( + "Uncaught exception %s\n%r", + self._request_summary(), + self.request, + exc_info=(typ, value, tb), # type: ignore + ) + + def _ui_module(self, name: str, module: Type["UIModule"]) -> Callable[..., str]: + def render(*args, **kwargs) -> str: # type: ignore + if not hasattr(self, "_active_modules"): + self._active_modules = {} # type: Dict[str, UIModule] + if name not in self._active_modules: + self._active_modules[name] = module(self) + rendered = self._active_modules[name].render(*args, **kwargs) + return rendered + + return render + + def _ui_method(self, method: Callable[..., str]) -> Callable[..., str]: + return lambda *args, **kwargs: method(self, *args, **kwargs) + + def _clear_representation_headers(self) -> None: + # 304 responses should not contain representation metadata + # headers (defined in + # https://tools.ietf.org/html/rfc7231#section-3.1) + # not explicitly allowed by + # https://tools.ietf.org/html/rfc7232#section-4.1 + headers = ["Content-Encoding", "Content-Language", "Content-Type"] + for h in headers: + self.clear_header(h) + + +def stream_request_body(cls: Type[RequestHandler]) -> Type[RequestHandler]: + """Apply to `RequestHandler` subclasses to enable streaming body support. + + This decorator implies the following changes: + + * `.HTTPServerRequest.body` is undefined, and body arguments will not + be included in `RequestHandler.get_argument`. + * `RequestHandler.prepare` is called when the request headers have been + read instead of after the entire body has been read. + * The subclass must define a method ``data_received(self, data):``, which + will be called zero or more times as data is available. Note that + if the request has an empty body, ``data_received`` may not be called. + * ``prepare`` and ``data_received`` may return Futures (such as via + ``@gen.coroutine``, in which case the next method will not be called + until those futures have completed. + * The regular HTTP method (``post``, ``put``, etc) will be called after + the entire body has been read. + + See the `file receiver demo `_ + for example usage. + """ # noqa: E501 + if not issubclass(cls, RequestHandler): + raise TypeError("expected subclass of RequestHandler, got %r", cls) + cls._stream_request_body = True + return cls + + +def _has_stream_request_body(cls: Type[RequestHandler]) -> bool: + if not issubclass(cls, RequestHandler): + raise TypeError("expected subclass of RequestHandler, got %r", cls) + return cls._stream_request_body + + +def removeslash( + method: Callable[..., Optional[Awaitable[None]]] +) -> Callable[..., Optional[Awaitable[None]]]: + """Use this decorator to remove trailing slashes from the request path. + + For example, a request to ``/foo/`` would redirect to ``/foo`` with this + decorator. Your request handler mapping should use a regular expression + like ``r'/foo/*'`` in conjunction with using the decorator. + """ + + @functools.wraps(method) + def wrapper( # type: ignore + self: RequestHandler, *args, **kwargs + ) -> Optional[Awaitable[None]]: + if self.request.path.endswith("/"): + if self.request.method in ("GET", "HEAD"): + uri = self.request.path.rstrip("/") + if uri: # don't try to redirect '/' to '' + if self.request.query: + uri += "?" + self.request.query + self.redirect(uri, permanent=True) + return None + else: + raise HTTPError(404) + return method(self, *args, **kwargs) + + return wrapper + + +def addslash( + method: Callable[..., Optional[Awaitable[None]]] +) -> Callable[..., Optional[Awaitable[None]]]: + """Use this decorator to add a missing trailing slash to the request path. + + For example, a request to ``/foo`` would redirect to ``/foo/`` with this + decorator. Your request handler mapping should use a regular expression + like ``r'/foo/?'`` in conjunction with using the decorator. + """ + + @functools.wraps(method) + def wrapper( # type: ignore + self: RequestHandler, *args, **kwargs + ) -> Optional[Awaitable[None]]: + if not self.request.path.endswith("/"): + if self.request.method in ("GET", "HEAD"): + uri = self.request.path + "/" + if self.request.query: + uri += "?" + self.request.query + self.redirect(uri, permanent=True) + return None + raise HTTPError(404) + return method(self, *args, **kwargs) + + return wrapper + + +class _ApplicationRouter(ReversibleRuleRouter): + """Routing implementation used internally by `Application`. + + Provides a binding between `Application` and `RequestHandler`. + This implementation extends `~.routing.ReversibleRuleRouter` in a couple of ways: + * it allows to use `RequestHandler` subclasses as `~.routing.Rule` target and + * it allows to use a list/tuple of rules as `~.routing.Rule` target. + ``process_rule`` implementation will substitute this list with an appropriate + `_ApplicationRouter` instance. + """ + + def __init__( + self, application: "Application", rules: Optional[_RuleList] = None + ) -> None: + assert isinstance(application, Application) + self.application = application + super().__init__(rules) + + def process_rule(self, rule: Rule) -> Rule: + rule = super().process_rule(rule) + + if isinstance(rule.target, (list, tuple)): + rule.target = _ApplicationRouter( + self.application, rule.target # type: ignore + ) + + return rule + + def get_target_delegate( + self, target: Any, request: httputil.HTTPServerRequest, **target_params: Any + ) -> Optional[httputil.HTTPMessageDelegate]: + if isclass(target) and issubclass(target, RequestHandler): + return self.application.get_handler_delegate( + request, target, **target_params + ) + + return super().get_target_delegate(target, request, **target_params) + + +class Application(ReversibleRouter): + r"""A collection of request handlers that make up a web application. + + Instances of this class are callable and can be passed directly to + HTTPServer to serve the application:: + + application = web.Application([ + (r"/", MainPageHandler), + ]) + http_server = httpserver.HTTPServer(application) + http_server.listen(8080) + ioloop.IOLoop.current().start() + + The constructor for this class takes in a list of `~.routing.Rule` + objects or tuples of values corresponding to the arguments of + `~.routing.Rule` constructor: ``(matcher, target, [target_kwargs], [name])``, + the values in square brackets being optional. The default matcher is + `~.routing.PathMatches`, so ``(regexp, target)`` tuples can also be used + instead of ``(PathMatches(regexp), target)``. + + A common routing target is a `RequestHandler` subclass, but you can also + use lists of rules as a target, which create a nested routing configuration:: + + application = web.Application([ + (HostMatches("example.com"), [ + (r"/", MainPageHandler), + (r"/feed", FeedHandler), + ]), + ]) + + In addition to this you can use nested `~.routing.Router` instances, + `~.httputil.HTTPMessageDelegate` subclasses and callables as routing targets + (see `~.routing` module docs for more information). + + When we receive requests, we iterate over the list in order and + instantiate an instance of the first request class whose regexp + matches the request path. The request class can be specified as + either a class object or a (fully-qualified) name. + + A dictionary may be passed as the third element (``target_kwargs``) + of the tuple, which will be used as keyword arguments to the handler's + constructor and `~RequestHandler.initialize` method. This pattern + is used for the `StaticFileHandler` in this example (note that a + `StaticFileHandler` can be installed automatically with the + static_path setting described below):: + + application = web.Application([ + (r"/static/(.*)", web.StaticFileHandler, {"path": "/var/www"}), + ]) + + We support virtual hosts with the `add_handlers` method, which takes in + a host regular expression as the first argument:: + + application.add_handlers(r"www\.myhost\.com", [ + (r"/article/([0-9]+)", ArticleHandler), + ]) + + If there's no match for the current request's host, then ``default_host`` + parameter value is matched against host regular expressions. + + + .. warning:: + + Applications that do not use TLS may be vulnerable to :ref:`DNS + rebinding ` attacks. This attack is especially + relevant to applications that only listen on ``127.0.0.1`` or + other private networks. Appropriate host patterns must be used + (instead of the default of ``r'.*'``) to prevent this risk. The + ``default_host`` argument must not be used in applications that + may be vulnerable to DNS rebinding. + + You can serve static files by sending the ``static_path`` setting + as a keyword argument. We will serve those files from the + ``/static/`` URI (this is configurable with the + ``static_url_prefix`` setting), and we will serve ``/favicon.ico`` + and ``/robots.txt`` from the same directory. A custom subclass of + `StaticFileHandler` can be specified with the + ``static_handler_class`` setting. + + .. versionchanged:: 4.5 + Integration with the new `tornado.routing` module. + + """ + + def __init__( + self, + handlers: Optional[_RuleList] = None, + default_host: Optional[str] = None, + transforms: Optional[List[Type["OutputTransform"]]] = None, + **settings: Any + ) -> None: + if transforms is None: + self.transforms = [] # type: List[Type[OutputTransform]] + if settings.get("compress_response") or settings.get("gzip"): + self.transforms.append(GZipContentEncoding) + else: + self.transforms = transforms + self.default_host = default_host + self.settings = settings + self.ui_modules = { + "linkify": _linkify, + "xsrf_form_html": _xsrf_form_html, + "Template": TemplateModule, + } + self.ui_methods = {} # type: Dict[str, Callable[..., str]] + self._load_ui_modules(settings.get("ui_modules", {})) + self._load_ui_methods(settings.get("ui_methods", {})) + if self.settings.get("static_path"): + path = self.settings["static_path"] + handlers = list(handlers or []) + static_url_prefix = settings.get("static_url_prefix", "/static/") + static_handler_class = settings.get( + "static_handler_class", StaticFileHandler + ) + static_handler_args = settings.get("static_handler_args", {}) + static_handler_args["path"] = path + for pattern in [ + re.escape(static_url_prefix) + r"(.*)", + r"/(favicon\.ico)", + r"/(robots\.txt)", + ]: + handlers.insert(0, (pattern, static_handler_class, static_handler_args)) + + if self.settings.get("debug"): + self.settings.setdefault("autoreload", True) + self.settings.setdefault("compiled_template_cache", False) + self.settings.setdefault("static_hash_cache", False) + self.settings.setdefault("serve_traceback", True) + + self.wildcard_router = _ApplicationRouter(self, handlers) + self.default_router = _ApplicationRouter( + self, [Rule(AnyMatches(), self.wildcard_router)] + ) + + # Automatically reload modified modules + if self.settings.get("autoreload"): + from tornado import autoreload + + autoreload.start() + + def listen(self, port: int, address: str = "", **kwargs: Any) -> HTTPServer: + """Starts an HTTP server for this application on the given port. + + This is a convenience alias for creating an `.HTTPServer` + object and calling its listen method. Keyword arguments not + supported by `HTTPServer.listen <.TCPServer.listen>` are passed to the + `.HTTPServer` constructor. For advanced uses + (e.g. multi-process mode), do not use this method; create an + `.HTTPServer` and call its + `.TCPServer.bind`/`.TCPServer.start` methods directly. + + Note that after calling this method you still need to call + ``IOLoop.current().start()`` to start the server. + + Returns the `.HTTPServer` object. + + .. versionchanged:: 4.3 + Now returns the `.HTTPServer` object. + """ + server = HTTPServer(self, **kwargs) + server.listen(port, address) + return server + + def add_handlers(self, host_pattern: str, host_handlers: _RuleList) -> None: + """Appends the given handlers to our handler list. + + Host patterns are processed sequentially in the order they were + added. All matching patterns will be considered. + """ + host_matcher = HostMatches(host_pattern) + rule = Rule(host_matcher, _ApplicationRouter(self, host_handlers)) + + self.default_router.rules.insert(-1, rule) + + if self.default_host is not None: + self.wildcard_router.add_rules( + [(DefaultHostMatches(self, host_matcher.host_pattern), host_handlers)] + ) + + def add_transform(self, transform_class: Type["OutputTransform"]) -> None: + self.transforms.append(transform_class) + + def _load_ui_methods(self, methods: Any) -> None: + if isinstance(methods, types.ModuleType): + self._load_ui_methods(dict((n, getattr(methods, n)) for n in dir(methods))) + elif isinstance(methods, list): + for m in methods: + self._load_ui_methods(m) + else: + for name, fn in methods.items(): + if ( + not name.startswith("_") + and hasattr(fn, "__call__") + and name[0].lower() == name[0] + ): + self.ui_methods[name] = fn + + def _load_ui_modules(self, modules: Any) -> None: + if isinstance(modules, types.ModuleType): + self._load_ui_modules(dict((n, getattr(modules, n)) for n in dir(modules))) + elif isinstance(modules, list): + for m in modules: + self._load_ui_modules(m) + else: + assert isinstance(modules, dict) + for name, cls in modules.items(): + try: + if issubclass(cls, UIModule): + self.ui_modules[name] = cls + except TypeError: + pass + + def __call__( + self, request: httputil.HTTPServerRequest + ) -> Optional[Awaitable[None]]: + # Legacy HTTPServer interface + dispatcher = self.find_handler(request) + return dispatcher.execute() + + def find_handler( + self, request: httputil.HTTPServerRequest, **kwargs: Any + ) -> "_HandlerDelegate": + route = self.default_router.find_handler(request) + if route is not None: + return cast("_HandlerDelegate", route) + + if self.settings.get("default_handler_class"): + return self.get_handler_delegate( + request, + self.settings["default_handler_class"], + self.settings.get("default_handler_args", {}), + ) + + return self.get_handler_delegate(request, ErrorHandler, {"status_code": 404}) + + def get_handler_delegate( + self, + request: httputil.HTTPServerRequest, + target_class: Type[RequestHandler], + target_kwargs: Optional[Dict[str, Any]] = None, + path_args: Optional[List[bytes]] = None, + path_kwargs: Optional[Dict[str, bytes]] = None, + ) -> "_HandlerDelegate": + """Returns `~.httputil.HTTPMessageDelegate` that can serve a request + for application and `RequestHandler` subclass. + + :arg httputil.HTTPServerRequest request: current HTTP request. + :arg RequestHandler target_class: a `RequestHandler` class. + :arg dict target_kwargs: keyword arguments for ``target_class`` constructor. + :arg list path_args: positional arguments for ``target_class`` HTTP method that + will be executed while handling a request (``get``, ``post`` or any other). + :arg dict path_kwargs: keyword arguments for ``target_class`` HTTP method. + """ + return _HandlerDelegate( + self, request, target_class, target_kwargs, path_args, path_kwargs + ) + + def reverse_url(self, name: str, *args: Any) -> str: + """Returns a URL path for handler named ``name`` + + The handler must be added to the application as a named `URLSpec`. + + Args will be substituted for capturing groups in the `URLSpec` regex. + They will be converted to strings if necessary, encoded as utf8, + and url-escaped. + """ + reversed_url = self.default_router.reverse_url(name, *args) + if reversed_url is not None: + return reversed_url + + raise KeyError("%s not found in named urls" % name) + + def log_request(self, handler: RequestHandler) -> None: + """Writes a completed HTTP request to the logs. + + By default writes to the python root logger. To change + this behavior either subclass Application and override this method, + or pass a function in the application settings dictionary as + ``log_function``. + """ + if "log_function" in self.settings: + self.settings["log_function"](handler) + return + if handler.get_status() < 400: + log_method = access_log.info + elif handler.get_status() < 500: + log_method = access_log.warning + else: + log_method = access_log.error + request_time = 1000.0 * handler.request.request_time() + log_method( + "%d %s %.2fms", + handler.get_status(), + handler._request_summary(), + request_time, + ) + + +class _HandlerDelegate(httputil.HTTPMessageDelegate): + def __init__( + self, + application: Application, + request: httputil.HTTPServerRequest, + handler_class: Type[RequestHandler], + handler_kwargs: Optional[Dict[str, Any]], + path_args: Optional[List[bytes]], + path_kwargs: Optional[Dict[str, bytes]], + ) -> None: + self.application = application + self.connection = request.connection + self.request = request + self.handler_class = handler_class + self.handler_kwargs = handler_kwargs or {} + self.path_args = path_args or [] + self.path_kwargs = path_kwargs or {} + self.chunks = [] # type: List[bytes] + self.stream_request_body = _has_stream_request_body(self.handler_class) + + def headers_received( + self, + start_line: Union[httputil.RequestStartLine, httputil.ResponseStartLine], + headers: httputil.HTTPHeaders, + ) -> Optional[Awaitable[None]]: + if self.stream_request_body: + self.request._body_future = Future() + return self.execute() + return None + + def data_received(self, data: bytes) -> Optional[Awaitable[None]]: + if self.stream_request_body: + return self.handler.data_received(data) + else: + self.chunks.append(data) + return None + + def finish(self) -> None: + if self.stream_request_body: + future_set_result_unless_cancelled(self.request._body_future, None) + else: + self.request.body = b"".join(self.chunks) + self.request._parse_body() + self.execute() + + def on_connection_close(self) -> None: + if self.stream_request_body: + self.handler.on_connection_close() + else: + self.chunks = None # type: ignore + + def execute(self) -> Optional[Awaitable[None]]: + # If template cache is disabled (usually in the debug mode), + # re-compile templates and reload static files on every + # request so you don't need to restart to see changes + if not self.application.settings.get("compiled_template_cache", True): + with RequestHandler._template_loader_lock: + for loader in RequestHandler._template_loaders.values(): + loader.reset() + if not self.application.settings.get("static_hash_cache", True): + StaticFileHandler.reset() + + self.handler = self.handler_class( + self.application, self.request, **self.handler_kwargs + ) + transforms = [t(self.request) for t in self.application.transforms] + + if self.stream_request_body: + self.handler._prepared_future = Future() + # Note that if an exception escapes handler._execute it will be + # trapped in the Future it returns (which we are ignoring here, + # leaving it to be logged when the Future is GC'd). + # However, that shouldn't happen because _execute has a blanket + # except handler, and we cannot easily access the IOLoop here to + # call add_future (because of the requirement to remain compatible + # with WSGI) + fut = gen.convert_yielded( + self.handler._execute(transforms, *self.path_args, **self.path_kwargs) + ) + fut.add_done_callback(lambda f: f.result()) + # If we are streaming the request body, then execute() is finished + # when the handler has prepared to receive the body. If not, + # it doesn't matter when execute() finishes (so we return None) + return self.handler._prepared_future + + +class HTTPError(Exception): + """An exception that will turn into an HTTP error response. + + Raising an `HTTPError` is a convenient alternative to calling + `RequestHandler.send_error` since it automatically ends the + current function. + + To customize the response sent with an `HTTPError`, override + `RequestHandler.write_error`. + + :arg int status_code: HTTP status code. Must be listed in + `httplib.responses ` unless the ``reason`` + keyword argument is given. + :arg str log_message: Message to be written to the log for this error + (will not be shown to the user unless the `Application` is in debug + mode). May contain ``%s``-style placeholders, which will be filled + in with remaining positional parameters. + :arg str reason: Keyword-only argument. The HTTP "reason" phrase + to pass in the status line along with ``status_code``. Normally + determined automatically from ``status_code``, but can be used + to use a non-standard numeric code. + """ + + def __init__( + self, + status_code: int = 500, + log_message: Optional[str] = None, + *args: Any, + **kwargs: Any + ) -> None: + self.status_code = status_code + self.log_message = log_message + self.args = args + self.reason = kwargs.get("reason", None) + if log_message and not args: + self.log_message = log_message.replace("%", "%%") + + def __str__(self) -> str: + message = "HTTP %d: %s" % ( + self.status_code, + self.reason or httputil.responses.get(self.status_code, "Unknown"), + ) + if self.log_message: + return message + " (" + (self.log_message % self.args) + ")" + else: + return message + + +class Finish(Exception): + """An exception that ends the request without producing an error response. + + When `Finish` is raised in a `RequestHandler`, the request will + end (calling `RequestHandler.finish` if it hasn't already been + called), but the error-handling methods (including + `RequestHandler.write_error`) will not be called. + + If `Finish()` was created with no arguments, the pending response + will be sent as-is. If `Finish()` was given an argument, that + argument will be passed to `RequestHandler.finish()`. + + This can be a more convenient way to implement custom error pages + than overriding ``write_error`` (especially in library code):: + + if self.current_user is None: + self.set_status(401) + self.set_header('WWW-Authenticate', 'Basic realm="something"') + raise Finish() + + .. versionchanged:: 4.3 + Arguments passed to ``Finish()`` will be passed on to + `RequestHandler.finish`. + """ + + pass + + +class MissingArgumentError(HTTPError): + """Exception raised by `RequestHandler.get_argument`. + + This is a subclass of `HTTPError`, so if it is uncaught a 400 response + code will be used instead of 500 (and a stack trace will not be logged). + + .. versionadded:: 3.1 + """ + + def __init__(self, arg_name: str) -> None: + super().__init__(400, "Missing argument %s" % arg_name) + self.arg_name = arg_name + + +class ErrorHandler(RequestHandler): + """Generates an error response with ``status_code`` for all requests.""" + + def initialize(self, status_code: int) -> None: + self.set_status(status_code) + + def prepare(self) -> None: + raise HTTPError(self._status_code) + + def check_xsrf_cookie(self) -> None: + # POSTs to an ErrorHandler don't actually have side effects, + # so we don't need to check the xsrf token. This allows POSTs + # to the wrong url to return a 404 instead of 403. + pass + + +class RedirectHandler(RequestHandler): + """Redirects the client to the given URL for all GET requests. + + You should provide the keyword argument ``url`` to the handler, e.g.:: + + application = web.Application([ + (r"/oldpath", web.RedirectHandler, {"url": "/newpath"}), + ]) + + `RedirectHandler` supports regular expression substitutions. E.g., to + swap the first and second parts of a path while preserving the remainder:: + + application = web.Application([ + (r"/(.*?)/(.*?)/(.*)", web.RedirectHandler, {"url": "/{1}/{0}/{2}"}), + ]) + + The final URL is formatted with `str.format` and the substrings that match + the capturing groups. In the above example, a request to "/a/b/c" would be + formatted like:: + + str.format("/{1}/{0}/{2}", "a", "b", "c") # -> "/b/a/c" + + Use Python's :ref:`format string syntax ` to customize how + values are substituted. + + .. versionchanged:: 4.5 + Added support for substitutions into the destination URL. + + .. versionchanged:: 5.0 + If any query arguments are present, they will be copied to the + destination URL. + """ + + def initialize(self, url: str, permanent: bool = True) -> None: + self._url = url + self._permanent = permanent + + def get(self, *args: Any, **kwargs: Any) -> None: + to_url = self._url.format(*args, **kwargs) + if self.request.query_arguments: + # TODO: figure out typing for the next line. + to_url = httputil.url_concat( + to_url, + list(httputil.qs_to_qsl(self.request.query_arguments)), # type: ignore + ) + self.redirect(to_url, permanent=self._permanent) + + +class StaticFileHandler(RequestHandler): + """A simple handler that can serve static content from a directory. + + A `StaticFileHandler` is configured automatically if you pass the + ``static_path`` keyword argument to `Application`. This handler + can be customized with the ``static_url_prefix``, ``static_handler_class``, + and ``static_handler_args`` settings. + + To map an additional path to this handler for a static data directory + you would add a line to your application like:: + + application = web.Application([ + (r"/content/(.*)", web.StaticFileHandler, {"path": "/var/www"}), + ]) + + The handler constructor requires a ``path`` argument, which specifies the + local root directory of the content to be served. + + Note that a capture group in the regex is required to parse the value for + the ``path`` argument to the get() method (different than the constructor + argument above); see `URLSpec` for details. + + To serve a file like ``index.html`` automatically when a directory is + requested, set ``static_handler_args=dict(default_filename="index.html")`` + in your application settings, or add ``default_filename`` as an initializer + argument for your ``StaticFileHandler``. + + To maximize the effectiveness of browser caching, this class supports + versioned urls (by default using the argument ``?v=``). If a version + is given, we instruct the browser to cache this file indefinitely. + `make_static_url` (also available as `RequestHandler.static_url`) can + be used to construct a versioned url. + + This handler is intended primarily for use in development and light-duty + file serving; for heavy traffic it will be more efficient to use + a dedicated static file server (such as nginx or Apache). We support + the HTTP ``Accept-Ranges`` mechanism to return partial content (because + some browsers require this functionality to be present to seek in + HTML5 audio or video). + + **Subclassing notes** + + This class is designed to be extensible by subclassing, but because + of the way static urls are generated with class methods rather than + instance methods, the inheritance patterns are somewhat unusual. + Be sure to use the ``@classmethod`` decorator when overriding a + class method. Instance methods may use the attributes ``self.path`` + ``self.absolute_path``, and ``self.modified``. + + Subclasses should only override methods discussed in this section; + overriding other methods is error-prone. Overriding + ``StaticFileHandler.get`` is particularly problematic due to the + tight coupling with ``compute_etag`` and other methods. + + To change the way static urls are generated (e.g. to match the behavior + of another server or CDN), override `make_static_url`, `parse_url_path`, + `get_cache_time`, and/or `get_version`. + + To replace all interaction with the filesystem (e.g. to serve + static content from a database), override `get_content`, + `get_content_size`, `get_modified_time`, `get_absolute_path`, and + `validate_absolute_path`. + + .. versionchanged:: 3.1 + Many of the methods for subclasses were added in Tornado 3.1. + """ + + CACHE_MAX_AGE = 86400 * 365 * 10 # 10 years + + _static_hashes = {} # type: Dict[str, Optional[str]] + _lock = threading.Lock() # protects _static_hashes + + def initialize(self, path: str, default_filename: Optional[str] = None) -> None: + self.root = path + self.default_filename = default_filename + + @classmethod + def reset(cls) -> None: + with cls._lock: + cls._static_hashes = {} + + def head(self, path: str) -> Awaitable[None]: + return self.get(path, include_body=False) + + async def get(self, path: str, include_body: bool = True) -> None: + # Set up our path instance variables. + self.path = self.parse_url_path(path) + del path # make sure we don't refer to path instead of self.path again + absolute_path = self.get_absolute_path(self.root, self.path) + self.absolute_path = self.validate_absolute_path(self.root, absolute_path) + if self.absolute_path is None: + return + + self.modified = self.get_modified_time() + self.set_headers() + + if self.should_return_304(): + self.set_status(304) + return + + request_range = None + range_header = self.request.headers.get("Range") + if range_header: + # As per RFC 2616 14.16, if an invalid Range header is specified, + # the request will be treated as if the header didn't exist. + request_range = httputil._parse_request_range(range_header) + + size = self.get_content_size() + if request_range: + start, end = request_range + if start is not None and start < 0: + start += size + if start < 0: + start = 0 + if ( + start is not None + and (start >= size or (end is not None and start >= end)) + ) or end == 0: + # As per RFC 2616 14.35.1, a range is not satisfiable only: if + # the first requested byte is equal to or greater than the + # content, or when a suffix with length 0 is specified. + # https://tools.ietf.org/html/rfc7233#section-2.1 + # A byte-range-spec is invalid if the last-byte-pos value is present + # and less than the first-byte-pos. + self.set_status(416) # Range Not Satisfiable + self.set_header("Content-Type", "text/plain") + self.set_header("Content-Range", "bytes */%s" % (size,)) + return + if end is not None and end > size: + # Clients sometimes blindly use a large range to limit their + # download size; cap the endpoint at the actual file size. + end = size + # Note: only return HTTP 206 if less than the entire range has been + # requested. Not only is this semantically correct, but Chrome + # refuses to play audio if it gets an HTTP 206 in response to + # ``Range: bytes=0-``. + if size != (end or size) - (start or 0): + self.set_status(206) # Partial Content + self.set_header( + "Content-Range", httputil._get_content_range(start, end, size) + ) + else: + start = end = None + + if start is not None and end is not None: + content_length = end - start + elif end is not None: + content_length = end + elif start is not None: + content_length = size - start + else: + content_length = size + self.set_header("Content-Length", content_length) + + if include_body: + content = self.get_content(self.absolute_path, start, end) + if isinstance(content, bytes): + content = [content] + for chunk in content: + try: + self.write(chunk) + await self.flush() + except iostream.StreamClosedError: + return + else: + assert self.request.method == "HEAD" + + def compute_etag(self) -> Optional[str]: + """Sets the ``Etag`` header based on static url version. + + This allows efficient ``If-None-Match`` checks against cached + versions, and sends the correct ``Etag`` for a partial response + (i.e. the same ``Etag`` as the full file). + + .. versionadded:: 3.1 + """ + assert self.absolute_path is not None + version_hash = self._get_cached_version(self.absolute_path) + if not version_hash: + return None + return '"%s"' % (version_hash,) + + def set_headers(self) -> None: + """Sets the content and caching headers on the response. + + .. versionadded:: 3.1 + """ + self.set_header("Accept-Ranges", "bytes") + self.set_etag_header() + + if self.modified is not None: + self.set_header("Last-Modified", self.modified) + + content_type = self.get_content_type() + if content_type: + self.set_header("Content-Type", content_type) + + cache_time = self.get_cache_time(self.path, self.modified, content_type) + if cache_time > 0: + self.set_header( + "Expires", + datetime.datetime.utcnow() + datetime.timedelta(seconds=cache_time), + ) + self.set_header("Cache-Control", "max-age=" + str(cache_time)) + + self.set_extra_headers(self.path) + + def should_return_304(self) -> bool: + """Returns True if the headers indicate that we should return 304. + + .. versionadded:: 3.1 + """ + # If client sent If-None-Match, use it, ignore If-Modified-Since + if self.request.headers.get("If-None-Match"): + return self.check_etag_header() + + # Check the If-Modified-Since, and don't send the result if the + # content has not been modified + ims_value = self.request.headers.get("If-Modified-Since") + if ims_value is not None: + date_tuple = email.utils.parsedate(ims_value) + if date_tuple is not None: + if_since = datetime.datetime(*date_tuple[:6]) + assert self.modified is not None + if if_since >= self.modified: + return True + + return False + + @classmethod + def get_absolute_path(cls, root: str, path: str) -> str: + """Returns the absolute location of ``path`` relative to ``root``. + + ``root`` is the path configured for this `StaticFileHandler` + (in most cases the ``static_path`` `Application` setting). + + This class method may be overridden in subclasses. By default + it returns a filesystem path, but other strings may be used + as long as they are unique and understood by the subclass's + overridden `get_content`. + + .. versionadded:: 3.1 + """ + abspath = os.path.abspath(os.path.join(root, path)) + return abspath + + def validate_absolute_path(self, root: str, absolute_path: str) -> Optional[str]: + """Validate and return the absolute path. + + ``root`` is the configured path for the `StaticFileHandler`, + and ``path`` is the result of `get_absolute_path` + + This is an instance method called during request processing, + so it may raise `HTTPError` or use methods like + `RequestHandler.redirect` (return None after redirecting to + halt further processing). This is where 404 errors for missing files + are generated. + + This method may modify the path before returning it, but note that + any such modifications will not be understood by `make_static_url`. + + In instance methods, this method's result is available as + ``self.absolute_path``. + + .. versionadded:: 3.1 + """ + # os.path.abspath strips a trailing /. + # We must add it back to `root` so that we only match files + # in a directory named `root` instead of files starting with + # that prefix. + root = os.path.abspath(root) + if not root.endswith(os.path.sep): + # abspath always removes a trailing slash, except when + # root is '/'. This is an unusual case, but several projects + # have independently discovered this technique to disable + # Tornado's path validation and (hopefully) do their own, + # so we need to support it. + root += os.path.sep + # The trailing slash also needs to be temporarily added back + # the requested path so a request to root/ will match. + if not (absolute_path + os.path.sep).startswith(root): + raise HTTPError(403, "%s is not in root static directory", self.path) + if os.path.isdir(absolute_path) and self.default_filename is not None: + # need to look at the request.path here for when path is empty + # but there is some prefix to the path that was already + # trimmed by the routing + if not self.request.path.endswith("/"): + self.redirect(self.request.path + "/", permanent=True) + return None + absolute_path = os.path.join(absolute_path, self.default_filename) + if not os.path.exists(absolute_path): + raise HTTPError(404) + if not os.path.isfile(absolute_path): + raise HTTPError(403, "%s is not a file", self.path) + return absolute_path + + @classmethod + def get_content( + cls, abspath: str, start: Optional[int] = None, end: Optional[int] = None + ) -> Generator[bytes, None, None]: + """Retrieve the content of the requested resource which is located + at the given absolute path. + + This class method may be overridden by subclasses. Note that its + signature is different from other overridable class methods + (no ``settings`` argument); this is deliberate to ensure that + ``abspath`` is able to stand on its own as a cache key. + + This method should either return a byte string or an iterator + of byte strings. The latter is preferred for large files + as it helps reduce memory fragmentation. + + .. versionadded:: 3.1 + """ + with open(abspath, "rb") as file: + if start is not None: + file.seek(start) + if end is not None: + remaining = end - (start or 0) # type: Optional[int] + else: + remaining = None + while True: + chunk_size = 64 * 1024 + if remaining is not None and remaining < chunk_size: + chunk_size = remaining + chunk = file.read(chunk_size) + if chunk: + if remaining is not None: + remaining -= len(chunk) + yield chunk + else: + if remaining is not None: + assert remaining == 0 + return + + @classmethod + def get_content_version(cls, abspath: str) -> str: + """Returns a version string for the resource at the given path. + + This class method may be overridden by subclasses. The + default implementation is a SHA-512 hash of the file's contents. + + .. versionadded:: 3.1 + """ + data = cls.get_content(abspath) + hasher = hashlib.sha512() + if isinstance(data, bytes): + hasher.update(data) + else: + for chunk in data: + hasher.update(chunk) + return hasher.hexdigest() + + def _stat(self) -> os.stat_result: + assert self.absolute_path is not None + if not hasattr(self, "_stat_result"): + self._stat_result = os.stat(self.absolute_path) + return self._stat_result + + def get_content_size(self) -> int: + """Retrieve the total size of the resource at the given path. + + This method may be overridden by subclasses. + + .. versionadded:: 3.1 + + .. versionchanged:: 4.0 + This method is now always called, instead of only when + partial results are requested. + """ + stat_result = self._stat() + return stat_result.st_size + + def get_modified_time(self) -> Optional[datetime.datetime]: + """Returns the time that ``self.absolute_path`` was last modified. + + May be overridden in subclasses. Should return a `~datetime.datetime` + object or None. + + .. versionadded:: 3.1 + """ + stat_result = self._stat() + # NOTE: Historically, this used stat_result[stat.ST_MTIME], + # which truncates the fractional portion of the timestamp. It + # was changed from that form to stat_result.st_mtime to + # satisfy mypy (which disallows the bracket operator), but the + # latter form returns a float instead of an int. For + # consistency with the past (and because we have a unit test + # that relies on this), we truncate the float here, although + # I'm not sure that's the right thing to do. + modified = datetime.datetime.utcfromtimestamp(int(stat_result.st_mtime)) + return modified + + def get_content_type(self) -> str: + """Returns the ``Content-Type`` header to be used for this request. + + .. versionadded:: 3.1 + """ + assert self.absolute_path is not None + mime_type, encoding = mimetypes.guess_type(self.absolute_path) + # per RFC 6713, use the appropriate type for a gzip compressed file + if encoding == "gzip": + return "application/gzip" + # As of 2015-07-21 there is no bzip2 encoding defined at + # http://www.iana.org/assignments/media-types/media-types.xhtml + # So for that (and any other encoding), use octet-stream. + elif encoding is not None: + return "application/octet-stream" + elif mime_type is not None: + return mime_type + # if mime_type not detected, use application/octet-stream + else: + return "application/octet-stream" + + def set_extra_headers(self, path: str) -> None: + """For subclass to add extra headers to the response""" + pass + + def get_cache_time( + self, path: str, modified: Optional[datetime.datetime], mime_type: str + ) -> int: + """Override to customize cache control behavior. + + Return a positive number of seconds to make the result + cacheable for that amount of time or 0 to mark resource as + cacheable for an unspecified amount of time (subject to + browser heuristics). + + By default returns cache expiry of 10 years for resources requested + with ``v`` argument. + """ + return self.CACHE_MAX_AGE if "v" in self.request.arguments else 0 + + @classmethod + def make_static_url( + cls, settings: Dict[str, Any], path: str, include_version: bool = True + ) -> str: + """Constructs a versioned url for the given path. + + This method may be overridden in subclasses (but note that it + is a class method rather than an instance method). Subclasses + are only required to implement the signature + ``make_static_url(cls, settings, path)``; other keyword + arguments may be passed through `~RequestHandler.static_url` + but are not standard. + + ``settings`` is the `Application.settings` dictionary. ``path`` + is the static path being requested. The url returned should be + relative to the current host. + + ``include_version`` determines whether the generated URL should + include the query string containing the version hash of the + file corresponding to the given ``path``. + + """ + url = settings.get("static_url_prefix", "/static/") + path + if not include_version: + return url + + version_hash = cls.get_version(settings, path) + if not version_hash: + return url + + return "%s?v=%s" % (url, version_hash) + + def parse_url_path(self, url_path: str) -> str: + """Converts a static URL path into a filesystem path. + + ``url_path`` is the path component of the URL with + ``static_url_prefix`` removed. The return value should be + filesystem path relative to ``static_path``. + + This is the inverse of `make_static_url`. + """ + if os.path.sep != "/": + url_path = url_path.replace("/", os.path.sep) + return url_path + + @classmethod + def get_version(cls, settings: Dict[str, Any], path: str) -> Optional[str]: + """Generate the version string to be used in static URLs. + + ``settings`` is the `Application.settings` dictionary and ``path`` + is the relative location of the requested asset on the filesystem. + The returned value should be a string, or ``None`` if no version + could be determined. + + .. versionchanged:: 3.1 + This method was previously recommended for subclasses to override; + `get_content_version` is now preferred as it allows the base + class to handle caching of the result. + """ + abs_path = cls.get_absolute_path(settings["static_path"], path) + return cls._get_cached_version(abs_path) + + @classmethod + def _get_cached_version(cls, abs_path: str) -> Optional[str]: + with cls._lock: + hashes = cls._static_hashes + if abs_path not in hashes: + try: + hashes[abs_path] = cls.get_content_version(abs_path) + except Exception: + gen_log.error("Could not open static file %r", abs_path) + hashes[abs_path] = None + hsh = hashes.get(abs_path) + if hsh: + return hsh + return None + + +class FallbackHandler(RequestHandler): + """A `RequestHandler` that wraps another HTTP server callback. + + The fallback is a callable object that accepts an + `~.httputil.HTTPServerRequest`, such as an `Application` or + `tornado.wsgi.WSGIContainer`. This is most useful to use both + Tornado ``RequestHandlers`` and WSGI in the same server. Typical + usage:: + + wsgi_app = tornado.wsgi.WSGIContainer( + django.core.handlers.wsgi.WSGIHandler()) + application = tornado.web.Application([ + (r"/foo", FooHandler), + (r".*", FallbackHandler, dict(fallback=wsgi_app), + ]) + """ + + def initialize( + self, fallback: Callable[[httputil.HTTPServerRequest], None] + ) -> None: + self.fallback = fallback + + def prepare(self) -> None: + self.fallback(self.request) + self._finished = True + self.on_finish() + + +class OutputTransform(object): + """A transform modifies the result of an HTTP request (e.g., GZip encoding) + + Applications are not expected to create their own OutputTransforms + or interact with them directly; the framework chooses which transforms + (if any) to apply. + """ + + def __init__(self, request: httputil.HTTPServerRequest) -> None: + pass + + def transform_first_chunk( + self, + status_code: int, + headers: httputil.HTTPHeaders, + chunk: bytes, + finishing: bool, + ) -> Tuple[int, httputil.HTTPHeaders, bytes]: + return status_code, headers, chunk + + def transform_chunk(self, chunk: bytes, finishing: bool) -> bytes: + return chunk + + +class GZipContentEncoding(OutputTransform): + """Applies the gzip content encoding to the response. + + See http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.11 + + .. versionchanged:: 4.0 + Now compresses all mime types beginning with ``text/``, instead + of just a whitelist. (the whitelist is still used for certain + non-text mime types). + """ + + # Whitelist of compressible mime types (in addition to any types + # beginning with "text/"). + CONTENT_TYPES = set( + [ + "application/javascript", + "application/x-javascript", + "application/xml", + "application/atom+xml", + "application/json", + "application/xhtml+xml", + "image/svg+xml", + ] + ) + # Python's GzipFile defaults to level 9, while most other gzip + # tools (including gzip itself) default to 6, which is probably a + # better CPU/size tradeoff. + GZIP_LEVEL = 6 + # Responses that are too short are unlikely to benefit from gzipping + # after considering the "Content-Encoding: gzip" header and the header + # inside the gzip encoding. + # Note that responses written in multiple chunks will be compressed + # regardless of size. + MIN_LENGTH = 1024 + + def __init__(self, request: httputil.HTTPServerRequest) -> None: + self._gzipping = "gzip" in request.headers.get("Accept-Encoding", "") + + def _compressible_type(self, ctype: str) -> bool: + return ctype.startswith("text/") or ctype in self.CONTENT_TYPES + + def transform_first_chunk( + self, + status_code: int, + headers: httputil.HTTPHeaders, + chunk: bytes, + finishing: bool, + ) -> Tuple[int, httputil.HTTPHeaders, bytes]: + # TODO: can/should this type be inherited from the superclass? + if "Vary" in headers: + headers["Vary"] += ", Accept-Encoding" + else: + headers["Vary"] = "Accept-Encoding" + if self._gzipping: + ctype = _unicode(headers.get("Content-Type", "")).split(";")[0] + self._gzipping = ( + self._compressible_type(ctype) + and (not finishing or len(chunk) >= self.MIN_LENGTH) + and ("Content-Encoding" not in headers) + ) + if self._gzipping: + headers["Content-Encoding"] = "gzip" + self._gzip_value = BytesIO() + self._gzip_file = gzip.GzipFile( + mode="w", fileobj=self._gzip_value, compresslevel=self.GZIP_LEVEL + ) + chunk = self.transform_chunk(chunk, finishing) + if "Content-Length" in headers: + # The original content length is no longer correct. + # If this is the last (and only) chunk, we can set the new + # content-length; otherwise we remove it and fall back to + # chunked encoding. + if finishing: + headers["Content-Length"] = str(len(chunk)) + else: + del headers["Content-Length"] + return status_code, headers, chunk + + def transform_chunk(self, chunk: bytes, finishing: bool) -> bytes: + if self._gzipping: + self._gzip_file.write(chunk) + if finishing: + self._gzip_file.close() + else: + self._gzip_file.flush() + chunk = self._gzip_value.getvalue() + self._gzip_value.truncate(0) + self._gzip_value.seek(0) + return chunk + + +def authenticated( + method: Callable[..., Optional[Awaitable[None]]] +) -> Callable[..., Optional[Awaitable[None]]]: + """Decorate methods with this to require that the user be logged in. + + If the user is not logged in, they will be redirected to the configured + `login url `. + + If you configure a login url with a query parameter, Tornado will + assume you know what you're doing and use it as-is. If not, it + will add a `next` parameter so the login page knows where to send + you once you're logged in. + """ + + @functools.wraps(method) + def wrapper( # type: ignore + self: RequestHandler, *args, **kwargs + ) -> Optional[Awaitable[None]]: + if not self.current_user: + if self.request.method in ("GET", "HEAD"): + url = self.get_login_url() + if "?" not in url: + if urllib.parse.urlsplit(url).scheme: + # if login url is absolute, make next absolute too + next_url = self.request.full_url() + else: + assert self.request.uri is not None + next_url = self.request.uri + url += "?" + urlencode(dict(next=next_url)) + self.redirect(url) + return None + raise HTTPError(403) + return method(self, *args, **kwargs) + + return wrapper + + +class UIModule(object): + """A re-usable, modular UI unit on a page. + + UI modules often execute additional queries, and they can include + additional CSS and JavaScript that will be included in the output + page, which is automatically inserted on page render. + + Subclasses of UIModule must override the `render` method. + """ + + def __init__(self, handler: RequestHandler) -> None: + self.handler = handler + self.request = handler.request + self.ui = handler.ui + self.locale = handler.locale + + @property + def current_user(self) -> Any: + return self.handler.current_user + + def render(self, *args: Any, **kwargs: Any) -> str: + """Override in subclasses to return this module's output.""" + raise NotImplementedError() + + def embedded_javascript(self) -> Optional[str]: + """Override to return a JavaScript string + to be embedded in the page.""" + return None + + def javascript_files(self) -> Optional[Iterable[str]]: + """Override to return a list of JavaScript files needed by this module. + + If the return values are relative paths, they will be passed to + `RequestHandler.static_url`; otherwise they will be used as-is. + """ + return None + + def embedded_css(self) -> Optional[str]: + """Override to return a CSS string + that will be embedded in the page.""" + return None + + def css_files(self) -> Optional[Iterable[str]]: + """Override to returns a list of CSS files required by this module. + + If the return values are relative paths, they will be passed to + `RequestHandler.static_url`; otherwise they will be used as-is. + """ + return None + + def html_head(self) -> Optional[str]: + """Override to return an HTML string that will be put in the + element. + """ + return None + + def html_body(self) -> Optional[str]: + """Override to return an HTML string that will be put at the end of + the element. + """ + return None + + def render_string(self, path: str, **kwargs: Any) -> bytes: + """Renders a template and returns it as a string.""" + return self.handler.render_string(path, **kwargs) + + +class _linkify(UIModule): + def render(self, text: str, **kwargs: Any) -> str: # type: ignore + return escape.linkify(text, **kwargs) + + +class _xsrf_form_html(UIModule): + def render(self) -> str: # type: ignore + return self.handler.xsrf_form_html() + + +class TemplateModule(UIModule): + """UIModule that simply renders the given template. + + {% module Template("foo.html") %} is similar to {% include "foo.html" %}, + but the module version gets its own namespace (with kwargs passed to + Template()) instead of inheriting the outer template's namespace. + + Templates rendered through this module also get access to UIModule's + automatic JavaScript/CSS features. Simply call set_resources + inside the template and give it keyword arguments corresponding to + the methods on UIModule: {{ set_resources(js_files=static_url("my.js")) }} + Note that these resources are output once per template file, not once + per instantiation of the template, so they must not depend on + any arguments to the template. + """ + + def __init__(self, handler: RequestHandler) -> None: + super().__init__(handler) + # keep resources in both a list and a dict to preserve order + self._resource_list = [] # type: List[Dict[str, Any]] + self._resource_dict = {} # type: Dict[str, Dict[str, Any]] + + def render(self, path: str, **kwargs: Any) -> bytes: # type: ignore + def set_resources(**kwargs) -> str: # type: ignore + if path not in self._resource_dict: + self._resource_list.append(kwargs) + self._resource_dict[path] = kwargs + else: + if self._resource_dict[path] != kwargs: + raise ValueError( + "set_resources called with different " + "resources for the same template" + ) + return "" + + return self.render_string(path, set_resources=set_resources, **kwargs) + + def _get_resources(self, key: str) -> Iterable[str]: + return (r[key] for r in self._resource_list if key in r) + + def embedded_javascript(self) -> str: + return "\n".join(self._get_resources("embedded_javascript")) + + def javascript_files(self) -> Iterable[str]: + result = [] + for f in self._get_resources("javascript_files"): + if isinstance(f, (unicode_type, bytes)): + result.append(f) + else: + result.extend(f) + return result + + def embedded_css(self) -> str: + return "\n".join(self._get_resources("embedded_css")) + + def css_files(self) -> Iterable[str]: + result = [] + for f in self._get_resources("css_files"): + if isinstance(f, (unicode_type, bytes)): + result.append(f) + else: + result.extend(f) + return result + + def html_head(self) -> str: + return "".join(self._get_resources("html_head")) + + def html_body(self) -> str: + return "".join(self._get_resources("html_body")) + + +class _UIModuleNamespace(object): + """Lazy namespace which creates UIModule proxies bound to a handler.""" + + def __init__( + self, handler: RequestHandler, ui_modules: Dict[str, Type[UIModule]] + ) -> None: + self.handler = handler + self.ui_modules = ui_modules + + def __getitem__(self, key: str) -> Callable[..., str]: + return self.handler._ui_module(key, self.ui_modules[key]) + + def __getattr__(self, key: str) -> Callable[..., str]: + try: + return self[key] + except KeyError as e: + raise AttributeError(str(e)) + + +def create_signed_value( + secret: _CookieSecretTypes, + name: str, + value: Union[str, bytes], + version: Optional[int] = None, + clock: Optional[Callable[[], float]] = None, + key_version: Optional[int] = None, +) -> bytes: + if version is None: + version = DEFAULT_SIGNED_VALUE_VERSION + if clock is None: + clock = time.time + + timestamp = utf8(str(int(clock()))) + value = base64.b64encode(utf8(value)) + if version == 1: + assert not isinstance(secret, dict) + signature = _create_signature_v1(secret, name, value, timestamp) + value = b"|".join([value, timestamp, signature]) + return value + elif version == 2: + # The v2 format consists of a version number and a series of + # length-prefixed fields "%d:%s", the last of which is a + # signature, all separated by pipes. All numbers are in + # decimal format with no leading zeros. The signature is an + # HMAC-SHA256 of the whole string up to that point, including + # the final pipe. + # + # The fields are: + # - format version (i.e. 2; no length prefix) + # - key version (integer, default is 0) + # - timestamp (integer seconds since epoch) + # - name (not encoded; assumed to be ~alphanumeric) + # - value (base64-encoded) + # - signature (hex-encoded; no length prefix) + def format_field(s: Union[str, bytes]) -> bytes: + return utf8("%d:" % len(s)) + utf8(s) + + to_sign = b"|".join( + [ + b"2", + format_field(str(key_version or 0)), + format_field(timestamp), + format_field(name), + format_field(value), + b"", + ] + ) + + if isinstance(secret, dict): + assert ( + key_version is not None + ), "Key version must be set when sign key dict is used" + assert version >= 2, "Version must be at least 2 for key version support" + secret = secret[key_version] + + signature = _create_signature_v2(secret, to_sign) + return to_sign + signature + else: + raise ValueError("Unsupported version %d" % version) + + +# A leading version number in decimal +# with no leading zeros, followed by a pipe. +_signed_value_version_re = re.compile(br"^([1-9][0-9]*)\|(.*)$") + + +def _get_version(value: bytes) -> int: + # Figures out what version value is. Version 1 did not include an + # explicit version field and started with arbitrary base64 data, + # which makes this tricky. + m = _signed_value_version_re.match(value) + if m is None: + version = 1 + else: + try: + version = int(m.group(1)) + if version > 999: + # Certain payloads from the version-less v1 format may + # be parsed as valid integers. Due to base64 padding + # restrictions, this can only happen for numbers whose + # length is a multiple of 4, so we can treat all + # numbers up to 999 as versions, and for the rest we + # fall back to v1 format. + version = 1 + except ValueError: + version = 1 + return version + + +def decode_signed_value( + secret: _CookieSecretTypes, + name: str, + value: Union[None, str, bytes], + max_age_days: float = 31, + clock: Optional[Callable[[], float]] = None, + min_version: Optional[int] = None, +) -> Optional[bytes]: + if clock is None: + clock = time.time + if min_version is None: + min_version = DEFAULT_SIGNED_VALUE_MIN_VERSION + if min_version > 2: + raise ValueError("Unsupported min_version %d" % min_version) + if not value: + return None + + value = utf8(value) + version = _get_version(value) + + if version < min_version: + return None + if version == 1: + assert not isinstance(secret, dict) + return _decode_signed_value_v1(secret, name, value, max_age_days, clock) + elif version == 2: + return _decode_signed_value_v2(secret, name, value, max_age_days, clock) + else: + return None + + +def _decode_signed_value_v1( + secret: Union[str, bytes], + name: str, + value: bytes, + max_age_days: float, + clock: Callable[[], float], +) -> Optional[bytes]: + parts = utf8(value).split(b"|") + if len(parts) != 3: + return None + signature = _create_signature_v1(secret, name, parts[0], parts[1]) + if not hmac.compare_digest(parts[2], signature): + gen_log.warning("Invalid cookie signature %r", value) + return None + timestamp = int(parts[1]) + if timestamp < clock() - max_age_days * 86400: + gen_log.warning("Expired cookie %r", value) + return None + if timestamp > clock() + 31 * 86400: + # _cookie_signature does not hash a delimiter between the + # parts of the cookie, so an attacker could transfer trailing + # digits from the payload to the timestamp without altering the + # signature. For backwards compatibility, sanity-check timestamp + # here instead of modifying _cookie_signature. + gen_log.warning("Cookie timestamp in future; possible tampering %r", value) + return None + if parts[1].startswith(b"0"): + gen_log.warning("Tampered cookie %r", value) + return None + try: + return base64.b64decode(parts[0]) + except Exception: + return None + + +def _decode_fields_v2(value: bytes) -> Tuple[int, bytes, bytes, bytes, bytes]: + def _consume_field(s: bytes) -> Tuple[bytes, bytes]: + length, _, rest = s.partition(b":") + n = int(length) + field_value = rest[:n] + # In python 3, indexing bytes returns small integers; we must + # use a slice to get a byte string as in python 2. + if rest[n : n + 1] != b"|": + raise ValueError("malformed v2 signed value field") + rest = rest[n + 1 :] + return field_value, rest + + rest = value[2:] # remove version number + key_version, rest = _consume_field(rest) + timestamp, rest = _consume_field(rest) + name_field, rest = _consume_field(rest) + value_field, passed_sig = _consume_field(rest) + return int(key_version), timestamp, name_field, value_field, passed_sig + + +def _decode_signed_value_v2( + secret: _CookieSecretTypes, + name: str, + value: bytes, + max_age_days: float, + clock: Callable[[], float], +) -> Optional[bytes]: + try: + ( + key_version, + timestamp_bytes, + name_field, + value_field, + passed_sig, + ) = _decode_fields_v2(value) + except ValueError: + return None + signed_string = value[: -len(passed_sig)] + + if isinstance(secret, dict): + try: + secret = secret[key_version] + except KeyError: + return None + + expected_sig = _create_signature_v2(secret, signed_string) + if not hmac.compare_digest(passed_sig, expected_sig): + return None + if name_field != utf8(name): + return None + timestamp = int(timestamp_bytes) + if timestamp < clock() - max_age_days * 86400: + # The signature has expired. + return None + try: + return base64.b64decode(value_field) + except Exception: + return None + + +def get_signature_key_version(value: Union[str, bytes]) -> Optional[int]: + value = utf8(value) + version = _get_version(value) + if version < 2: + return None + try: + key_version, _, _, _, _ = _decode_fields_v2(value) + except ValueError: + return None + + return key_version + + +def _create_signature_v1(secret: Union[str, bytes], *parts: Union[str, bytes]) -> bytes: + hash = hmac.new(utf8(secret), digestmod=hashlib.sha1) + for part in parts: + hash.update(utf8(part)) + return utf8(hash.hexdigest()) + + +def _create_signature_v2(secret: Union[str, bytes], s: bytes) -> bytes: + hash = hmac.new(utf8(secret), digestmod=hashlib.sha256) + hash.update(utf8(s)) + return utf8(hash.hexdigest()) + + +def is_absolute(path: str) -> bool: + return any(path.startswith(x) for x in ["/", "http:", "https:"]) diff --git a/.venv/lib/python3.8/site-packages/tornado/websocket.py b/.venv/lib/python3.8/site-packages/tornado/websocket.py new file mode 100644 index 00000000..eef49e7c --- /dev/null +++ b/.venv/lib/python3.8/site-packages/tornado/websocket.py @@ -0,0 +1,1666 @@ +"""Implementation of the WebSocket protocol. + +`WebSockets `_ allow for bidirectional +communication between the browser and server. + +WebSockets are supported in the current versions of all major browsers, +although older versions that do not support WebSockets are still in use +(refer to http://caniuse.com/websockets for details). + +This module implements the final version of the WebSocket protocol as +defined in `RFC 6455 `_. Certain +browser versions (notably Safari 5.x) implemented an earlier draft of +the protocol (known as "draft 76") and are not compatible with this module. + +.. versionchanged:: 4.0 + Removed support for the draft 76 protocol version. +""" + +import abc +import asyncio +import base64 +import hashlib +import os +import sys +import struct +import tornado.escape +import tornado.web +from urllib.parse import urlparse +import zlib + +from tornado.concurrent import Future, future_set_result_unless_cancelled +from tornado.escape import utf8, native_str, to_unicode +from tornado import gen, httpclient, httputil +from tornado.ioloop import IOLoop, PeriodicCallback +from tornado.iostream import StreamClosedError, IOStream +from tornado.log import gen_log, app_log +from tornado import simple_httpclient +from tornado.queues import Queue +from tornado.tcpclient import TCPClient +from tornado.util import _websocket_mask + +from typing import ( + TYPE_CHECKING, + cast, + Any, + Optional, + Dict, + Union, + List, + Awaitable, + Callable, + Tuple, + Type, +) +from types import TracebackType + +if TYPE_CHECKING: + from typing_extensions import Protocol + + # The zlib compressor types aren't actually exposed anywhere + # publicly, so declare protocols for the portions we use. + class _Compressor(Protocol): + def compress(self, data: bytes) -> bytes: + pass + + def flush(self, mode: int) -> bytes: + pass + + class _Decompressor(Protocol): + unconsumed_tail = b"" # type: bytes + + def decompress(self, data: bytes, max_length: int) -> bytes: + pass + + class _WebSocketDelegate(Protocol): + # The common base interface implemented by WebSocketHandler on + # the server side and WebSocketClientConnection on the client + # side. + def on_ws_connection_close( + self, close_code: Optional[int] = None, close_reason: Optional[str] = None + ) -> None: + pass + + def on_message(self, message: Union[str, bytes]) -> Optional["Awaitable[None]"]: + pass + + def on_ping(self, data: bytes) -> None: + pass + + def on_pong(self, data: bytes) -> None: + pass + + def log_exception( + self, + typ: Optional[Type[BaseException]], + value: Optional[BaseException], + tb: Optional[TracebackType], + ) -> None: + pass + + +_default_max_message_size = 10 * 1024 * 1024 + + +class WebSocketError(Exception): + pass + + +class WebSocketClosedError(WebSocketError): + """Raised by operations on a closed connection. + + .. versionadded:: 3.2 + """ + + pass + + +class _DecompressTooLargeError(Exception): + pass + + +class _WebSocketParams(object): + def __init__( + self, + ping_interval: Optional[float] = None, + ping_timeout: Optional[float] = None, + max_message_size: int = _default_max_message_size, + compression_options: Optional[Dict[str, Any]] = None, + ) -> None: + self.ping_interval = ping_interval + self.ping_timeout = ping_timeout + self.max_message_size = max_message_size + self.compression_options = compression_options + + +class WebSocketHandler(tornado.web.RequestHandler): + """Subclass this class to create a basic WebSocket handler. + + Override `on_message` to handle incoming messages, and use + `write_message` to send messages to the client. You can also + override `open` and `on_close` to handle opened and closed + connections. + + Custom upgrade response headers can be sent by overriding + `~tornado.web.RequestHandler.set_default_headers` or + `~tornado.web.RequestHandler.prepare`. + + See http://dev.w3.org/html5/websockets/ for details on the + JavaScript interface. The protocol is specified at + http://tools.ietf.org/html/rfc6455. + + Here is an example WebSocket handler that echos back all received messages + back to the client: + + .. testcode:: + + class EchoWebSocket(tornado.websocket.WebSocketHandler): + def open(self): + print("WebSocket opened") + + def on_message(self, message): + self.write_message(u"You said: " + message) + + def on_close(self): + print("WebSocket closed") + + .. testoutput:: + :hide: + + WebSockets are not standard HTTP connections. The "handshake" is + HTTP, but after the handshake, the protocol is + message-based. Consequently, most of the Tornado HTTP facilities + are not available in handlers of this type. The only communication + methods available to you are `write_message()`, `ping()`, and + `close()`. Likewise, your request handler class should implement + `open()` method rather than ``get()`` or ``post()``. + + If you map the handler above to ``/websocket`` in your application, you can + invoke it in JavaScript with:: + + var ws = new WebSocket("ws://localhost:8888/websocket"); + ws.onopen = function() { + ws.send("Hello, world"); + }; + ws.onmessage = function (evt) { + alert(evt.data); + }; + + This script pops up an alert box that says "You said: Hello, world". + + Web browsers allow any site to open a websocket connection to any other, + instead of using the same-origin policy that governs other network + access from JavaScript. This can be surprising and is a potential + security hole, so since Tornado 4.0 `WebSocketHandler` requires + applications that wish to receive cross-origin websockets to opt in + by overriding the `~WebSocketHandler.check_origin` method (see that + method's docs for details). Failure to do so is the most likely + cause of 403 errors when making a websocket connection. + + When using a secure websocket connection (``wss://``) with a self-signed + certificate, the connection from a browser may fail because it wants + to show the "accept this certificate" dialog but has nowhere to show it. + You must first visit a regular HTML page using the same certificate + to accept it before the websocket connection will succeed. + + If the application setting ``websocket_ping_interval`` has a non-zero + value, a ping will be sent periodically, and the connection will be + closed if a response is not received before the ``websocket_ping_timeout``. + + Messages larger than the ``websocket_max_message_size`` application setting + (default 10MiB) will not be accepted. + + .. versionchanged:: 4.5 + Added ``websocket_ping_interval``, ``websocket_ping_timeout``, and + ``websocket_max_message_size``. + """ + + def __init__( + self, + application: tornado.web.Application, + request: httputil.HTTPServerRequest, + **kwargs: Any + ) -> None: + super().__init__(application, request, **kwargs) + self.ws_connection = None # type: Optional[WebSocketProtocol] + self.close_code = None # type: Optional[int] + self.close_reason = None # type: Optional[str] + self.stream = None # type: Optional[IOStream] + self._on_close_called = False + + async def get(self, *args: Any, **kwargs: Any) -> None: + self.open_args = args + self.open_kwargs = kwargs + + # Upgrade header should be present and should be equal to WebSocket + if self.request.headers.get("Upgrade", "").lower() != "websocket": + self.set_status(400) + log_msg = 'Can "Upgrade" only to "WebSocket".' + self.finish(log_msg) + gen_log.debug(log_msg) + return + + # Connection header should be upgrade. + # Some proxy servers/load balancers + # might mess with it. + headers = self.request.headers + connection = map( + lambda s: s.strip().lower(), headers.get("Connection", "").split(",") + ) + if "upgrade" not in connection: + self.set_status(400) + log_msg = '"Connection" must be "Upgrade".' + self.finish(log_msg) + gen_log.debug(log_msg) + return + + # Handle WebSocket Origin naming convention differences + # The difference between version 8 and 13 is that in 8 the + # client sends a "Sec-Websocket-Origin" header and in 13 it's + # simply "Origin". + if "Origin" in self.request.headers: + origin = self.request.headers.get("Origin") + else: + origin = self.request.headers.get("Sec-Websocket-Origin", None) + + # If there was an origin header, check to make sure it matches + # according to check_origin. When the origin is None, we assume it + # did not come from a browser and that it can be passed on. + if origin is not None and not self.check_origin(origin): + self.set_status(403) + log_msg = "Cross origin websockets not allowed" + self.finish(log_msg) + gen_log.debug(log_msg) + return + + self.ws_connection = self.get_websocket_protocol() + if self.ws_connection: + await self.ws_connection.accept_connection(self) + else: + self.set_status(426, "Upgrade Required") + self.set_header("Sec-WebSocket-Version", "7, 8, 13") + + @property + def ping_interval(self) -> Optional[float]: + """The interval for websocket keep-alive pings. + + Set websocket_ping_interval = 0 to disable pings. + """ + return self.settings.get("websocket_ping_interval", None) + + @property + def ping_timeout(self) -> Optional[float]: + """If no ping is received in this many seconds, + close the websocket connection (VPNs, etc. can fail to cleanly close ws connections). + Default is max of 3 pings or 30 seconds. + """ + return self.settings.get("websocket_ping_timeout", None) + + @property + def max_message_size(self) -> int: + """Maximum allowed message size. + + If the remote peer sends a message larger than this, the connection + will be closed. + + Default is 10MiB. + """ + return self.settings.get( + "websocket_max_message_size", _default_max_message_size + ) + + def write_message( + self, message: Union[bytes, str, Dict[str, Any]], binary: bool = False + ) -> "Future[None]": + """Sends the given message to the client of this Web Socket. + + The message may be either a string or a dict (which will be + encoded as json). If the ``binary`` argument is false, the + message will be sent as utf8; in binary mode any byte string + is allowed. + + If the connection is already closed, raises `WebSocketClosedError`. + Returns a `.Future` which can be used for flow control. + + .. versionchanged:: 3.2 + `WebSocketClosedError` was added (previously a closed connection + would raise an `AttributeError`) + + .. versionchanged:: 4.3 + Returns a `.Future` which can be used for flow control. + + .. versionchanged:: 5.0 + Consistently raises `WebSocketClosedError`. Previously could + sometimes raise `.StreamClosedError`. + """ + if self.ws_connection is None or self.ws_connection.is_closing(): + raise WebSocketClosedError() + if isinstance(message, dict): + message = tornado.escape.json_encode(message) + return self.ws_connection.write_message(message, binary=binary) + + def select_subprotocol(self, subprotocols: List[str]) -> Optional[str]: + """Override to implement subprotocol negotiation. + + ``subprotocols`` is a list of strings identifying the + subprotocols proposed by the client. This method may be + overridden to return one of those strings to select it, or + ``None`` to not select a subprotocol. + + Failure to select a subprotocol does not automatically abort + the connection, although clients may close the connection if + none of their proposed subprotocols was selected. + + The list may be empty, in which case this method must return + None. This method is always called exactly once even if no + subprotocols were proposed so that the handler can be advised + of this fact. + + .. versionchanged:: 5.1 + + Previously, this method was called with a list containing + an empty string instead of an empty list if no subprotocols + were proposed by the client. + """ + return None + + @property + def selected_subprotocol(self) -> Optional[str]: + """The subprotocol returned by `select_subprotocol`. + + .. versionadded:: 5.1 + """ + assert self.ws_connection is not None + return self.ws_connection.selected_subprotocol + + def get_compression_options(self) -> Optional[Dict[str, Any]]: + """Override to return compression options for the connection. + + If this method returns None (the default), compression will + be disabled. If it returns a dict (even an empty one), it + will be enabled. The contents of the dict may be used to + control the following compression options: + + ``compression_level`` specifies the compression level. + + ``mem_level`` specifies the amount of memory used for the internal compression state. + + These parameters are documented in details here: + https://docs.python.org/3.6/library/zlib.html#zlib.compressobj + + .. versionadded:: 4.1 + + .. versionchanged:: 4.5 + + Added ``compression_level`` and ``mem_level``. + """ + # TODO: Add wbits option. + return None + + def open(self, *args: str, **kwargs: str) -> Optional[Awaitable[None]]: + """Invoked when a new WebSocket is opened. + + The arguments to `open` are extracted from the `tornado.web.URLSpec` + regular expression, just like the arguments to + `tornado.web.RequestHandler.get`. + + `open` may be a coroutine. `on_message` will not be called until + `open` has returned. + + .. versionchanged:: 5.1 + + ``open`` may be a coroutine. + """ + pass + + def on_message(self, message: Union[str, bytes]) -> Optional[Awaitable[None]]: + """Handle incoming messages on the WebSocket + + This method must be overridden. + + .. versionchanged:: 4.5 + + ``on_message`` can be a coroutine. + """ + raise NotImplementedError + + def ping(self, data: Union[str, bytes] = b"") -> None: + """Send ping frame to the remote end. + + The data argument allows a small amount of data (up to 125 + bytes) to be sent as a part of the ping message. Note that not + all websocket implementations expose this data to + applications. + + Consider using the ``websocket_ping_interval`` application + setting instead of sending pings manually. + + .. versionchanged:: 5.1 + + The data argument is now optional. + + """ + data = utf8(data) + if self.ws_connection is None or self.ws_connection.is_closing(): + raise WebSocketClosedError() + self.ws_connection.write_ping(data) + + def on_pong(self, data: bytes) -> None: + """Invoked when the response to a ping frame is received.""" + pass + + def on_ping(self, data: bytes) -> None: + """Invoked when the a ping frame is received.""" + pass + + def on_close(self) -> None: + """Invoked when the WebSocket is closed. + + If the connection was closed cleanly and a status code or reason + phrase was supplied, these values will be available as the attributes + ``self.close_code`` and ``self.close_reason``. + + .. versionchanged:: 4.0 + + Added ``close_code`` and ``close_reason`` attributes. + """ + pass + + def close(self, code: Optional[int] = None, reason: Optional[str] = None) -> None: + """Closes this Web Socket. + + Once the close handshake is successful the socket will be closed. + + ``code`` may be a numeric status code, taken from the values + defined in `RFC 6455 section 7.4.1 + `_. + ``reason`` may be a textual message about why the connection is + closing. These values are made available to the client, but are + not otherwise interpreted by the websocket protocol. + + .. versionchanged:: 4.0 + + Added the ``code`` and ``reason`` arguments. + """ + if self.ws_connection: + self.ws_connection.close(code, reason) + self.ws_connection = None + + def check_origin(self, origin: str) -> bool: + """Override to enable support for allowing alternate origins. + + The ``origin`` argument is the value of the ``Origin`` HTTP + header, the url responsible for initiating this request. This + method is not called for clients that do not send this header; + such requests are always allowed (because all browsers that + implement WebSockets support this header, and non-browser + clients do not have the same cross-site security concerns). + + Should return ``True`` to accept the request or ``False`` to + reject it. By default, rejects all requests with an origin on + a host other than this one. + + This is a security protection against cross site scripting attacks on + browsers, since WebSockets are allowed to bypass the usual same-origin + policies and don't use CORS headers. + + .. warning:: + + This is an important security measure; don't disable it + without understanding the security implications. In + particular, if your authentication is cookie-based, you + must either restrict the origins allowed by + ``check_origin()`` or implement your own XSRF-like + protection for websocket connections. See `these + `_ + `articles + `_ + for more. + + To accept all cross-origin traffic (which was the default prior to + Tornado 4.0), simply override this method to always return ``True``:: + + def check_origin(self, origin): + return True + + To allow connections from any subdomain of your site, you might + do something like:: + + def check_origin(self, origin): + parsed_origin = urllib.parse.urlparse(origin) + return parsed_origin.netloc.endswith(".mydomain.com") + + .. versionadded:: 4.0 + + """ + parsed_origin = urlparse(origin) + origin = parsed_origin.netloc + origin = origin.lower() + + host = self.request.headers.get("Host") + + # Check to see that origin matches host directly, including ports + return origin == host + + def set_nodelay(self, value: bool) -> None: + """Set the no-delay flag for this stream. + + By default, small messages may be delayed and/or combined to minimize + the number of packets sent. This can sometimes cause 200-500ms delays + due to the interaction between Nagle's algorithm and TCP delayed + ACKs. To reduce this delay (at the expense of possibly increasing + bandwidth usage), call ``self.set_nodelay(True)`` once the websocket + connection is established. + + See `.BaseIOStream.set_nodelay` for additional details. + + .. versionadded:: 3.1 + """ + assert self.ws_connection is not None + self.ws_connection.set_nodelay(value) + + def on_connection_close(self) -> None: + if self.ws_connection: + self.ws_connection.on_connection_close() + self.ws_connection = None + if not self._on_close_called: + self._on_close_called = True + self.on_close() + self._break_cycles() + + def on_ws_connection_close( + self, close_code: Optional[int] = None, close_reason: Optional[str] = None + ) -> None: + self.close_code = close_code + self.close_reason = close_reason + self.on_connection_close() + + def _break_cycles(self) -> None: + # WebSocketHandlers call finish() early, but we don't want to + # break up reference cycles (which makes it impossible to call + # self.render_string) until after we've really closed the + # connection (if it was established in the first place, + # indicated by status code 101). + if self.get_status() != 101 or self._on_close_called: + super()._break_cycles() + + def send_error(self, *args: Any, **kwargs: Any) -> None: + if self.stream is None: + super().send_error(*args, **kwargs) + else: + # If we get an uncaught exception during the handshake, + # we have no choice but to abruptly close the connection. + # TODO: for uncaught exceptions after the handshake, + # we can close the connection more gracefully. + self.stream.close() + + def get_websocket_protocol(self) -> Optional["WebSocketProtocol"]: + websocket_version = self.request.headers.get("Sec-WebSocket-Version") + if websocket_version in ("7", "8", "13"): + params = _WebSocketParams( + ping_interval=self.ping_interval, + ping_timeout=self.ping_timeout, + max_message_size=self.max_message_size, + compression_options=self.get_compression_options(), + ) + return WebSocketProtocol13(self, False, params) + return None + + def _detach_stream(self) -> IOStream: + # disable non-WS methods + for method in [ + "write", + "redirect", + "set_header", + "set_cookie", + "set_status", + "flush", + "finish", + ]: + setattr(self, method, _raise_not_supported_for_websockets) + return self.detach() + + +def _raise_not_supported_for_websockets(*args: Any, **kwargs: Any) -> None: + raise RuntimeError("Method not supported for Web Sockets") + + +class WebSocketProtocol(abc.ABC): + """Base class for WebSocket protocol versions. + """ + + def __init__(self, handler: "_WebSocketDelegate") -> None: + self.handler = handler + self.stream = None # type: Optional[IOStream] + self.client_terminated = False + self.server_terminated = False + + def _run_callback( + self, callback: Callable, *args: Any, **kwargs: Any + ) -> "Optional[Future[Any]]": + """Runs the given callback with exception handling. + + If the callback is a coroutine, returns its Future. On error, aborts the + websocket connection and returns None. + """ + try: + result = callback(*args, **kwargs) + except Exception: + self.handler.log_exception(*sys.exc_info()) + self._abort() + return None + else: + if result is not None: + result = gen.convert_yielded(result) + assert self.stream is not None + self.stream.io_loop.add_future(result, lambda f: f.result()) + return result + + def on_connection_close(self) -> None: + self._abort() + + def _abort(self) -> None: + """Instantly aborts the WebSocket connection by closing the socket""" + self.client_terminated = True + self.server_terminated = True + if self.stream is not None: + self.stream.close() # forcibly tear down the connection + self.close() # let the subclass cleanup + + @abc.abstractmethod + def close(self, code: Optional[int] = None, reason: Optional[str] = None) -> None: + raise NotImplementedError() + + @abc.abstractmethod + def is_closing(self) -> bool: + raise NotImplementedError() + + @abc.abstractmethod + async def accept_connection(self, handler: WebSocketHandler) -> None: + raise NotImplementedError() + + @abc.abstractmethod + def write_message( + self, message: Union[str, bytes], binary: bool = False + ) -> "Future[None]": + raise NotImplementedError() + + @property + @abc.abstractmethod + def selected_subprotocol(self) -> Optional[str]: + raise NotImplementedError() + + @abc.abstractmethod + def write_ping(self, data: bytes) -> None: + raise NotImplementedError() + + # The entry points below are used by WebSocketClientConnection, + # which was introduced after we only supported a single version of + # WebSocketProtocol. The WebSocketProtocol/WebSocketProtocol13 + # boundary is currently pretty ad-hoc. + @abc.abstractmethod + def _process_server_headers( + self, key: Union[str, bytes], headers: httputil.HTTPHeaders + ) -> None: + raise NotImplementedError() + + @abc.abstractmethod + def start_pinging(self) -> None: + raise NotImplementedError() + + @abc.abstractmethod + async def _receive_frame_loop(self) -> None: + raise NotImplementedError() + + @abc.abstractmethod + def set_nodelay(self, x: bool) -> None: + raise NotImplementedError() + + +class _PerMessageDeflateCompressor(object): + def __init__( + self, + persistent: bool, + max_wbits: Optional[int], + compression_options: Optional[Dict[str, Any]] = None, + ) -> None: + if max_wbits is None: + max_wbits = zlib.MAX_WBITS + # There is no symbolic constant for the minimum wbits value. + if not (8 <= max_wbits <= zlib.MAX_WBITS): + raise ValueError( + "Invalid max_wbits value %r; allowed range 8-%d", + max_wbits, + zlib.MAX_WBITS, + ) + self._max_wbits = max_wbits + + if ( + compression_options is None + or "compression_level" not in compression_options + ): + self._compression_level = tornado.web.GZipContentEncoding.GZIP_LEVEL + else: + self._compression_level = compression_options["compression_level"] + + if compression_options is None or "mem_level" not in compression_options: + self._mem_level = 8 + else: + self._mem_level = compression_options["mem_level"] + + if persistent: + self._compressor = self._create_compressor() # type: Optional[_Compressor] + else: + self._compressor = None + + def _create_compressor(self) -> "_Compressor": + return zlib.compressobj( + self._compression_level, zlib.DEFLATED, -self._max_wbits, self._mem_level + ) + + def compress(self, data: bytes) -> bytes: + compressor = self._compressor or self._create_compressor() + data = compressor.compress(data) + compressor.flush(zlib.Z_SYNC_FLUSH) + assert data.endswith(b"\x00\x00\xff\xff") + return data[:-4] + + +class _PerMessageDeflateDecompressor(object): + def __init__( + self, + persistent: bool, + max_wbits: Optional[int], + max_message_size: int, + compression_options: Optional[Dict[str, Any]] = None, + ) -> None: + self._max_message_size = max_message_size + if max_wbits is None: + max_wbits = zlib.MAX_WBITS + if not (8 <= max_wbits <= zlib.MAX_WBITS): + raise ValueError( + "Invalid max_wbits value %r; allowed range 8-%d", + max_wbits, + zlib.MAX_WBITS, + ) + self._max_wbits = max_wbits + if persistent: + self._decompressor = ( + self._create_decompressor() + ) # type: Optional[_Decompressor] + else: + self._decompressor = None + + def _create_decompressor(self) -> "_Decompressor": + return zlib.decompressobj(-self._max_wbits) + + def decompress(self, data: bytes) -> bytes: + decompressor = self._decompressor or self._create_decompressor() + result = decompressor.decompress( + data + b"\x00\x00\xff\xff", self._max_message_size + ) + if decompressor.unconsumed_tail: + raise _DecompressTooLargeError() + return result + + +class WebSocketProtocol13(WebSocketProtocol): + """Implementation of the WebSocket protocol from RFC 6455. + + This class supports versions 7 and 8 of the protocol in addition to the + final version 13. + """ + + # Bit masks for the first byte of a frame. + FIN = 0x80 + RSV1 = 0x40 + RSV2 = 0x20 + RSV3 = 0x10 + RSV_MASK = RSV1 | RSV2 | RSV3 + OPCODE_MASK = 0x0F + + stream = None # type: IOStream + + def __init__( + self, + handler: "_WebSocketDelegate", + mask_outgoing: bool, + params: _WebSocketParams, + ) -> None: + WebSocketProtocol.__init__(self, handler) + self.mask_outgoing = mask_outgoing + self.params = params + self._final_frame = False + self._frame_opcode = None + self._masked_frame = None + self._frame_mask = None # type: Optional[bytes] + self._frame_length = None + self._fragmented_message_buffer = None # type: Optional[bytes] + self._fragmented_message_opcode = None + self._waiting = None # type: object + self._compression_options = params.compression_options + self._decompressor = None # type: Optional[_PerMessageDeflateDecompressor] + self._compressor = None # type: Optional[_PerMessageDeflateCompressor] + self._frame_compressed = None # type: Optional[bool] + # The total uncompressed size of all messages received or sent. + # Unicode messages are encoded to utf8. + # Only for testing; subject to change. + self._message_bytes_in = 0 + self._message_bytes_out = 0 + # The total size of all packets received or sent. Includes + # the effect of compression, frame overhead, and control frames. + self._wire_bytes_in = 0 + self._wire_bytes_out = 0 + self.ping_callback = None # type: Optional[PeriodicCallback] + self.last_ping = 0.0 + self.last_pong = 0.0 + self.close_code = None # type: Optional[int] + self.close_reason = None # type: Optional[str] + + # Use a property for this to satisfy the abc. + @property + def selected_subprotocol(self) -> Optional[str]: + return self._selected_subprotocol + + @selected_subprotocol.setter + def selected_subprotocol(self, value: Optional[str]) -> None: + self._selected_subprotocol = value + + async def accept_connection(self, handler: WebSocketHandler) -> None: + try: + self._handle_websocket_headers(handler) + except ValueError: + handler.set_status(400) + log_msg = "Missing/Invalid WebSocket headers" + handler.finish(log_msg) + gen_log.debug(log_msg) + return + + try: + await self._accept_connection(handler) + except asyncio.CancelledError: + self._abort() + return + except ValueError: + gen_log.debug("Malformed WebSocket request received", exc_info=True) + self._abort() + return + + def _handle_websocket_headers(self, handler: WebSocketHandler) -> None: + """Verifies all invariant- and required headers + + If a header is missing or have an incorrect value ValueError will be + raised + """ + fields = ("Host", "Sec-Websocket-Key", "Sec-Websocket-Version") + if not all(map(lambda f: handler.request.headers.get(f), fields)): + raise ValueError("Missing/Invalid WebSocket headers") + + @staticmethod + def compute_accept_value(key: Union[str, bytes]) -> str: + """Computes the value for the Sec-WebSocket-Accept header, + given the value for Sec-WebSocket-Key. + """ + sha1 = hashlib.sha1() + sha1.update(utf8(key)) + sha1.update(b"258EAFA5-E914-47DA-95CA-C5AB0DC85B11") # Magic value + return native_str(base64.b64encode(sha1.digest())) + + def _challenge_response(self, handler: WebSocketHandler) -> str: + return WebSocketProtocol13.compute_accept_value( + cast(str, handler.request.headers.get("Sec-Websocket-Key")) + ) + + async def _accept_connection(self, handler: WebSocketHandler) -> None: + subprotocol_header = handler.request.headers.get("Sec-WebSocket-Protocol") + if subprotocol_header: + subprotocols = [s.strip() for s in subprotocol_header.split(",")] + else: + subprotocols = [] + self.selected_subprotocol = handler.select_subprotocol(subprotocols) + if self.selected_subprotocol: + assert self.selected_subprotocol in subprotocols + handler.set_header("Sec-WebSocket-Protocol", self.selected_subprotocol) + + extensions = self._parse_extensions_header(handler.request.headers) + for ext in extensions: + if ext[0] == "permessage-deflate" and self._compression_options is not None: + # TODO: negotiate parameters if compression_options + # specifies limits. + self._create_compressors("server", ext[1], self._compression_options) + if ( + "client_max_window_bits" in ext[1] + and ext[1]["client_max_window_bits"] is None + ): + # Don't echo an offered client_max_window_bits + # parameter with no value. + del ext[1]["client_max_window_bits"] + handler.set_header( + "Sec-WebSocket-Extensions", + httputil._encode_header("permessage-deflate", ext[1]), + ) + break + + handler.clear_header("Content-Type") + handler.set_status(101) + handler.set_header("Upgrade", "websocket") + handler.set_header("Connection", "Upgrade") + handler.set_header("Sec-WebSocket-Accept", self._challenge_response(handler)) + handler.finish() + + self.stream = handler._detach_stream() + + self.start_pinging() + try: + open_result = handler.open(*handler.open_args, **handler.open_kwargs) + if open_result is not None: + await open_result + except Exception: + handler.log_exception(*sys.exc_info()) + self._abort() + return + + await self._receive_frame_loop() + + def _parse_extensions_header( + self, headers: httputil.HTTPHeaders + ) -> List[Tuple[str, Dict[str, str]]]: + extensions = headers.get("Sec-WebSocket-Extensions", "") + if extensions: + return [httputil._parse_header(e.strip()) for e in extensions.split(",")] + return [] + + def _process_server_headers( + self, key: Union[str, bytes], headers: httputil.HTTPHeaders + ) -> None: + """Process the headers sent by the server to this client connection. + + 'key' is the websocket handshake challenge/response key. + """ + assert headers["Upgrade"].lower() == "websocket" + assert headers["Connection"].lower() == "upgrade" + accept = self.compute_accept_value(key) + assert headers["Sec-Websocket-Accept"] == accept + + extensions = self._parse_extensions_header(headers) + for ext in extensions: + if ext[0] == "permessage-deflate" and self._compression_options is not None: + self._create_compressors("client", ext[1]) + else: + raise ValueError("unsupported extension %r", ext) + + self.selected_subprotocol = headers.get("Sec-WebSocket-Protocol", None) + + def _get_compressor_options( + self, + side: str, + agreed_parameters: Dict[str, Any], + compression_options: Optional[Dict[str, Any]] = None, + ) -> Dict[str, Any]: + """Converts a websocket agreed_parameters set to keyword arguments + for our compressor objects. + """ + options = dict( + persistent=(side + "_no_context_takeover") not in agreed_parameters + ) # type: Dict[str, Any] + wbits_header = agreed_parameters.get(side + "_max_window_bits", None) + if wbits_header is None: + options["max_wbits"] = zlib.MAX_WBITS + else: + options["max_wbits"] = int(wbits_header) + options["compression_options"] = compression_options + return options + + def _create_compressors( + self, + side: str, + agreed_parameters: Dict[str, Any], + compression_options: Optional[Dict[str, Any]] = None, + ) -> None: + # TODO: handle invalid parameters gracefully + allowed_keys = set( + [ + "server_no_context_takeover", + "client_no_context_takeover", + "server_max_window_bits", + "client_max_window_bits", + ] + ) + for key in agreed_parameters: + if key not in allowed_keys: + raise ValueError("unsupported compression parameter %r" % key) + other_side = "client" if (side == "server") else "server" + self._compressor = _PerMessageDeflateCompressor( + **self._get_compressor_options(side, agreed_parameters, compression_options) + ) + self._decompressor = _PerMessageDeflateDecompressor( + max_message_size=self.params.max_message_size, + **self._get_compressor_options( + other_side, agreed_parameters, compression_options + ) + ) + + def _write_frame( + self, fin: bool, opcode: int, data: bytes, flags: int = 0 + ) -> "Future[None]": + data_len = len(data) + if opcode & 0x8: + # All control frames MUST have a payload length of 125 + # bytes or less and MUST NOT be fragmented. + if not fin: + raise ValueError("control frames may not be fragmented") + if data_len > 125: + raise ValueError("control frame payloads may not exceed 125 bytes") + if fin: + finbit = self.FIN + else: + finbit = 0 + frame = struct.pack("B", finbit | opcode | flags) + if self.mask_outgoing: + mask_bit = 0x80 + else: + mask_bit = 0 + if data_len < 126: + frame += struct.pack("B", data_len | mask_bit) + elif data_len <= 0xFFFF: + frame += struct.pack("!BH", 126 | mask_bit, data_len) + else: + frame += struct.pack("!BQ", 127 | mask_bit, data_len) + if self.mask_outgoing: + mask = os.urandom(4) + data = mask + _websocket_mask(mask, data) + frame += data + self._wire_bytes_out += len(frame) + return self.stream.write(frame) + + def write_message( + self, message: Union[str, bytes], binary: bool = False + ) -> "Future[None]": + """Sends the given message to the client of this Web Socket.""" + if binary: + opcode = 0x2 + else: + opcode = 0x1 + message = tornado.escape.utf8(message) + assert isinstance(message, bytes) + self._message_bytes_out += len(message) + flags = 0 + if self._compressor: + message = self._compressor.compress(message) + flags |= self.RSV1 + # For historical reasons, write methods in Tornado operate in a semi-synchronous + # mode in which awaiting the Future they return is optional (But errors can + # still be raised). This requires us to go through an awkward dance here + # to transform the errors that may be returned while presenting the same + # semi-synchronous interface. + try: + fut = self._write_frame(True, opcode, message, flags=flags) + except StreamClosedError: + raise WebSocketClosedError() + + async def wrapper() -> None: + try: + await fut + except StreamClosedError: + raise WebSocketClosedError() + + return asyncio.ensure_future(wrapper()) + + def write_ping(self, data: bytes) -> None: + """Send ping frame.""" + assert isinstance(data, bytes) + self._write_frame(True, 0x9, data) + + async def _receive_frame_loop(self) -> None: + try: + while not self.client_terminated: + await self._receive_frame() + except StreamClosedError: + self._abort() + self.handler.on_ws_connection_close(self.close_code, self.close_reason) + + async def _read_bytes(self, n: int) -> bytes: + data = await self.stream.read_bytes(n) + self._wire_bytes_in += n + return data + + async def _receive_frame(self) -> None: + # Read the frame header. + data = await self._read_bytes(2) + header, mask_payloadlen = struct.unpack("BB", data) + is_final_frame = header & self.FIN + reserved_bits = header & self.RSV_MASK + opcode = header & self.OPCODE_MASK + opcode_is_control = opcode & 0x8 + if self._decompressor is not None and opcode != 0: + # Compression flag is present in the first frame's header, + # but we can't decompress until we have all the frames of + # the message. + self._frame_compressed = bool(reserved_bits & self.RSV1) + reserved_bits &= ~self.RSV1 + if reserved_bits: + # client is using as-yet-undefined extensions; abort + self._abort() + return + is_masked = bool(mask_payloadlen & 0x80) + payloadlen = mask_payloadlen & 0x7F + + # Parse and validate the length. + if opcode_is_control and payloadlen >= 126: + # control frames must have payload < 126 + self._abort() + return + if payloadlen < 126: + self._frame_length = payloadlen + elif payloadlen == 126: + data = await self._read_bytes(2) + payloadlen = struct.unpack("!H", data)[0] + elif payloadlen == 127: + data = await self._read_bytes(8) + payloadlen = struct.unpack("!Q", data)[0] + new_len = payloadlen + if self._fragmented_message_buffer is not None: + new_len += len(self._fragmented_message_buffer) + if new_len > self.params.max_message_size: + self.close(1009, "message too big") + self._abort() + return + + # Read the payload, unmasking if necessary. + if is_masked: + self._frame_mask = await self._read_bytes(4) + data = await self._read_bytes(payloadlen) + if is_masked: + assert self._frame_mask is not None + data = _websocket_mask(self._frame_mask, data) + + # Decide what to do with this frame. + if opcode_is_control: + # control frames may be interleaved with a series of fragmented + # data frames, so control frames must not interact with + # self._fragmented_* + if not is_final_frame: + # control frames must not be fragmented + self._abort() + return + elif opcode == 0: # continuation frame + if self._fragmented_message_buffer is None: + # nothing to continue + self._abort() + return + self._fragmented_message_buffer += data + if is_final_frame: + opcode = self._fragmented_message_opcode + data = self._fragmented_message_buffer + self._fragmented_message_buffer = None + else: # start of new data message + if self._fragmented_message_buffer is not None: + # can't start new message until the old one is finished + self._abort() + return + if not is_final_frame: + self._fragmented_message_opcode = opcode + self._fragmented_message_buffer = data + + if is_final_frame: + handled_future = self._handle_message(opcode, data) + if handled_future is not None: + await handled_future + + def _handle_message(self, opcode: int, data: bytes) -> "Optional[Future[None]]": + """Execute on_message, returning its Future if it is a coroutine.""" + if self.client_terminated: + return None + + if self._frame_compressed: + assert self._decompressor is not None + try: + data = self._decompressor.decompress(data) + except _DecompressTooLargeError: + self.close(1009, "message too big after decompression") + self._abort() + return None + + if opcode == 0x1: + # UTF-8 data + self._message_bytes_in += len(data) + try: + decoded = data.decode("utf-8") + except UnicodeDecodeError: + self._abort() + return None + return self._run_callback(self.handler.on_message, decoded) + elif opcode == 0x2: + # Binary data + self._message_bytes_in += len(data) + return self._run_callback(self.handler.on_message, data) + elif opcode == 0x8: + # Close + self.client_terminated = True + if len(data) >= 2: + self.close_code = struct.unpack(">H", data[:2])[0] + if len(data) > 2: + self.close_reason = to_unicode(data[2:]) + # Echo the received close code, if any (RFC 6455 section 5.5.1). + self.close(self.close_code) + elif opcode == 0x9: + # Ping + try: + self._write_frame(True, 0xA, data) + except StreamClosedError: + self._abort() + self._run_callback(self.handler.on_ping, data) + elif opcode == 0xA: + # Pong + self.last_pong = IOLoop.current().time() + return self._run_callback(self.handler.on_pong, data) + else: + self._abort() + return None + + def close(self, code: Optional[int] = None, reason: Optional[str] = None) -> None: + """Closes the WebSocket connection.""" + if not self.server_terminated: + if not self.stream.closed(): + if code is None and reason is not None: + code = 1000 # "normal closure" status code + if code is None: + close_data = b"" + else: + close_data = struct.pack(">H", code) + if reason is not None: + close_data += utf8(reason) + try: + self._write_frame(True, 0x8, close_data) + except StreamClosedError: + self._abort() + self.server_terminated = True + if self.client_terminated: + if self._waiting is not None: + self.stream.io_loop.remove_timeout(self._waiting) + self._waiting = None + self.stream.close() + elif self._waiting is None: + # Give the client a few seconds to complete a clean shutdown, + # otherwise just close the connection. + self._waiting = self.stream.io_loop.add_timeout( + self.stream.io_loop.time() + 5, self._abort + ) + if self.ping_callback: + self.ping_callback.stop() + self.ping_callback = None + + def is_closing(self) -> bool: + """Return ``True`` if this connection is closing. + + The connection is considered closing if either side has + initiated its closing handshake or if the stream has been + shut down uncleanly. + """ + return self.stream.closed() or self.client_terminated or self.server_terminated + + @property + def ping_interval(self) -> Optional[float]: + interval = self.params.ping_interval + if interval is not None: + return interval + return 0 + + @property + def ping_timeout(self) -> Optional[float]: + timeout = self.params.ping_timeout + if timeout is not None: + return timeout + assert self.ping_interval is not None + return max(3 * self.ping_interval, 30) + + def start_pinging(self) -> None: + """Start sending periodic pings to keep the connection alive""" + assert self.ping_interval is not None + if self.ping_interval > 0: + self.last_ping = self.last_pong = IOLoop.current().time() + self.ping_callback = PeriodicCallback( + self.periodic_ping, self.ping_interval * 1000 + ) + self.ping_callback.start() + + def periodic_ping(self) -> None: + """Send a ping to keep the websocket alive + + Called periodically if the websocket_ping_interval is set and non-zero. + """ + if self.is_closing() and self.ping_callback is not None: + self.ping_callback.stop() + return + + # Check for timeout on pong. Make sure that we really have + # sent a recent ping in case the machine with both server and + # client has been suspended since the last ping. + now = IOLoop.current().time() + since_last_pong = now - self.last_pong + since_last_ping = now - self.last_ping + assert self.ping_interval is not None + assert self.ping_timeout is not None + if ( + since_last_ping < 2 * self.ping_interval + and since_last_pong > self.ping_timeout + ): + self.close() + return + + self.write_ping(b"") + self.last_ping = now + + def set_nodelay(self, x: bool) -> None: + self.stream.set_nodelay(x) + + +class WebSocketClientConnection(simple_httpclient._HTTPConnection): + """WebSocket client connection. + + This class should not be instantiated directly; use the + `websocket_connect` function instead. + """ + + protocol = None # type: WebSocketProtocol + + def __init__( + self, + request: httpclient.HTTPRequest, + on_message_callback: Optional[Callable[[Union[None, str, bytes]], None]] = None, + compression_options: Optional[Dict[str, Any]] = None, + ping_interval: Optional[float] = None, + ping_timeout: Optional[float] = None, + max_message_size: int = _default_max_message_size, + subprotocols: Optional[List[str]] = [], + ) -> None: + self.connect_future = Future() # type: Future[WebSocketClientConnection] + self.read_queue = Queue(1) # type: Queue[Union[None, str, bytes]] + self.key = base64.b64encode(os.urandom(16)) + self._on_message_callback = on_message_callback + self.close_code = None # type: Optional[int] + self.close_reason = None # type: Optional[str] + self.params = _WebSocketParams( + ping_interval=ping_interval, + ping_timeout=ping_timeout, + max_message_size=max_message_size, + compression_options=compression_options, + ) + + scheme, sep, rest = request.url.partition(":") + scheme = {"ws": "http", "wss": "https"}[scheme] + request.url = scheme + sep + rest + request.headers.update( + { + "Upgrade": "websocket", + "Connection": "Upgrade", + "Sec-WebSocket-Key": self.key, + "Sec-WebSocket-Version": "13", + } + ) + if subprotocols is not None: + request.headers["Sec-WebSocket-Protocol"] = ",".join(subprotocols) + if compression_options is not None: + # Always offer to let the server set our max_wbits (and even though + # we don't offer it, we will accept a client_no_context_takeover + # from the server). + # TODO: set server parameters for deflate extension + # if requested in self.compression_options. + request.headers[ + "Sec-WebSocket-Extensions" + ] = "permessage-deflate; client_max_window_bits" + + # Websocket connection is currently unable to follow redirects + request.follow_redirects = False + + self.tcp_client = TCPClient() + super().__init__( + None, + request, + lambda: None, + self._on_http_response, + 104857600, + self.tcp_client, + 65536, + 104857600, + ) + + def close(self, code: Optional[int] = None, reason: Optional[str] = None) -> None: + """Closes the websocket connection. + + ``code`` and ``reason`` are documented under + `WebSocketHandler.close`. + + .. versionadded:: 3.2 + + .. versionchanged:: 4.0 + + Added the ``code`` and ``reason`` arguments. + """ + if self.protocol is not None: + self.protocol.close(code, reason) + self.protocol = None # type: ignore + + def on_connection_close(self) -> None: + if not self.connect_future.done(): + self.connect_future.set_exception(StreamClosedError()) + self._on_message(None) + self.tcp_client.close() + super().on_connection_close() + + def on_ws_connection_close( + self, close_code: Optional[int] = None, close_reason: Optional[str] = None + ) -> None: + self.close_code = close_code + self.close_reason = close_reason + self.on_connection_close() + + def _on_http_response(self, response: httpclient.HTTPResponse) -> None: + if not self.connect_future.done(): + if response.error: + self.connect_future.set_exception(response.error) + else: + self.connect_future.set_exception( + WebSocketError("Non-websocket response") + ) + + async def headers_received( + self, + start_line: Union[httputil.RequestStartLine, httputil.ResponseStartLine], + headers: httputil.HTTPHeaders, + ) -> None: + assert isinstance(start_line, httputil.ResponseStartLine) + if start_line.code != 101: + await super().headers_received(start_line, headers) + return + + if self._timeout is not None: + self.io_loop.remove_timeout(self._timeout) + self._timeout = None + + self.headers = headers + self.protocol = self.get_websocket_protocol() + self.protocol._process_server_headers(self.key, self.headers) + self.protocol.stream = self.connection.detach() + + IOLoop.current().add_callback(self.protocol._receive_frame_loop) + self.protocol.start_pinging() + + # Once we've taken over the connection, clear the final callback + # we set on the http request. This deactivates the error handling + # in simple_httpclient that would otherwise interfere with our + # ability to see exceptions. + self.final_callback = None # type: ignore + + future_set_result_unless_cancelled(self.connect_future, self) + + def write_message( + self, message: Union[str, bytes], binary: bool = False + ) -> "Future[None]": + """Sends a message to the WebSocket server. + + If the stream is closed, raises `WebSocketClosedError`. + Returns a `.Future` which can be used for flow control. + + .. versionchanged:: 5.0 + Exception raised on a closed stream changed from `.StreamClosedError` + to `WebSocketClosedError`. + """ + return self.protocol.write_message(message, binary=binary) + + def read_message( + self, + callback: Optional[Callable[["Future[Union[None, str, bytes]]"], None]] = None, + ) -> Awaitable[Union[None, str, bytes]]: + """Reads a message from the WebSocket server. + + If on_message_callback was specified at WebSocket + initialization, this function will never return messages + + Returns a future whose result is the message, or None + if the connection is closed. If a callback argument + is given it will be called with the future when it is + ready. + """ + + awaitable = self.read_queue.get() + if callback is not None: + self.io_loop.add_future(asyncio.ensure_future(awaitable), callback) + return awaitable + + def on_message(self, message: Union[str, bytes]) -> Optional[Awaitable[None]]: + return self._on_message(message) + + def _on_message( + self, message: Union[None, str, bytes] + ) -> Optional[Awaitable[None]]: + if self._on_message_callback: + self._on_message_callback(message) + return None + else: + return self.read_queue.put(message) + + def ping(self, data: bytes = b"") -> None: + """Send ping frame to the remote end. + + The data argument allows a small amount of data (up to 125 + bytes) to be sent as a part of the ping message. Note that not + all websocket implementations expose this data to + applications. + + Consider using the ``ping_interval`` argument to + `websocket_connect` instead of sending pings manually. + + .. versionadded:: 5.1 + + """ + data = utf8(data) + if self.protocol is None: + raise WebSocketClosedError() + self.protocol.write_ping(data) + + def on_pong(self, data: bytes) -> None: + pass + + def on_ping(self, data: bytes) -> None: + pass + + def get_websocket_protocol(self) -> WebSocketProtocol: + return WebSocketProtocol13(self, mask_outgoing=True, params=self.params) + + @property + def selected_subprotocol(self) -> Optional[str]: + """The subprotocol selected by the server. + + .. versionadded:: 5.1 + """ + return self.protocol.selected_subprotocol + + def log_exception( + self, + typ: "Optional[Type[BaseException]]", + value: Optional[BaseException], + tb: Optional[TracebackType], + ) -> None: + assert typ is not None + assert value is not None + app_log.error("Uncaught exception %s", value, exc_info=(typ, value, tb)) + + +def websocket_connect( + url: Union[str, httpclient.HTTPRequest], + callback: Optional[Callable[["Future[WebSocketClientConnection]"], None]] = None, + connect_timeout: Optional[float] = None, + on_message_callback: Optional[Callable[[Union[None, str, bytes]], None]] = None, + compression_options: Optional[Dict[str, Any]] = None, + ping_interval: Optional[float] = None, + ping_timeout: Optional[float] = None, + max_message_size: int = _default_max_message_size, + subprotocols: Optional[List[str]] = None, +) -> "Awaitable[WebSocketClientConnection]": + """Client-side websocket support. + + Takes a url and returns a Future whose result is a + `WebSocketClientConnection`. + + ``compression_options`` is interpreted in the same way as the + return value of `.WebSocketHandler.get_compression_options`. + + The connection supports two styles of operation. In the coroutine + style, the application typically calls + `~.WebSocketClientConnection.read_message` in a loop:: + + conn = yield websocket_connect(url) + while True: + msg = yield conn.read_message() + if msg is None: break + # Do something with msg + + In the callback style, pass an ``on_message_callback`` to + ``websocket_connect``. In both styles, a message of ``None`` + indicates that the connection has been closed. + + ``subprotocols`` may be a list of strings specifying proposed + subprotocols. The selected protocol may be found on the + ``selected_subprotocol`` attribute of the connection object + when the connection is complete. + + .. versionchanged:: 3.2 + Also accepts ``HTTPRequest`` objects in place of urls. + + .. versionchanged:: 4.1 + Added ``compression_options`` and ``on_message_callback``. + + .. versionchanged:: 4.5 + Added the ``ping_interval``, ``ping_timeout``, and ``max_message_size`` + arguments, which have the same meaning as in `WebSocketHandler`. + + .. versionchanged:: 5.0 + The ``io_loop`` argument (deprecated since version 4.1) has been removed. + + .. versionchanged:: 5.1 + Added the ``subprotocols`` argument. + """ + if isinstance(url, httpclient.HTTPRequest): + assert connect_timeout is None + request = url + # Copy and convert the headers dict/object (see comments in + # AsyncHTTPClient.fetch) + request.headers = httputil.HTTPHeaders(request.headers) + else: + request = httpclient.HTTPRequest(url, connect_timeout=connect_timeout) + request = cast( + httpclient.HTTPRequest, + httpclient._RequestProxy(request, httpclient.HTTPRequest._DEFAULTS), + ) + conn = WebSocketClientConnection( + request, + on_message_callback=on_message_callback, + compression_options=compression_options, + ping_interval=ping_interval, + ping_timeout=ping_timeout, + max_message_size=max_message_size, + subprotocols=subprotocols, + ) + if callback is not None: + IOLoop.current().add_future(conn.connect_future, callback) + return conn.connect_future diff --git a/.venv/lib/python3.8/site-packages/tornado/wsgi.py b/.venv/lib/python3.8/site-packages/tornado/wsgi.py new file mode 100644 index 00000000..77124aaa --- /dev/null +++ b/.venv/lib/python3.8/site-packages/tornado/wsgi.py @@ -0,0 +1,199 @@ +# +# Copyright 2009 Facebook +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +"""WSGI support for the Tornado web framework. + +WSGI is the Python standard for web servers, and allows for interoperability +between Tornado and other Python web frameworks and servers. + +This module provides WSGI support via the `WSGIContainer` class, which +makes it possible to run applications using other WSGI frameworks on +the Tornado HTTP server. The reverse is not supported; the Tornado +`.Application` and `.RequestHandler` classes are designed for use with +the Tornado `.HTTPServer` and cannot be used in a generic WSGI +container. + +""" + +import sys +from io import BytesIO +import tornado + +from tornado import escape +from tornado import httputil +from tornado.log import access_log + +from typing import List, Tuple, Optional, Callable, Any, Dict, Text +from types import TracebackType +import typing + +if typing.TYPE_CHECKING: + from typing import Type # noqa: F401 + from wsgiref.types import WSGIApplication as WSGIAppType # noqa: F401 + + +# PEP 3333 specifies that WSGI on python 3 generally deals with byte strings +# that are smuggled inside objects of type unicode (via the latin1 encoding). +# This function is like those in the tornado.escape module, but defined +# here to minimize the temptation to use it in non-wsgi contexts. +def to_wsgi_str(s: bytes) -> str: + assert isinstance(s, bytes) + return s.decode("latin1") + + +class WSGIContainer(object): + r"""Makes a WSGI-compatible function runnable on Tornado's HTTP server. + + .. warning:: + + WSGI is a *synchronous* interface, while Tornado's concurrency model + is based on single-threaded asynchronous execution. This means that + running a WSGI app with Tornado's `WSGIContainer` is *less scalable* + than running the same app in a multi-threaded WSGI server like + ``gunicorn`` or ``uwsgi``. Use `WSGIContainer` only when there are + benefits to combining Tornado and WSGI in the same process that + outweigh the reduced scalability. + + Wrap a WSGI function in a `WSGIContainer` and pass it to `.HTTPServer` to + run it. For example:: + + def simple_app(environ, start_response): + status = "200 OK" + response_headers = [("Content-type", "text/plain")] + start_response(status, response_headers) + return ["Hello world!\n"] + + container = tornado.wsgi.WSGIContainer(simple_app) + http_server = tornado.httpserver.HTTPServer(container) + http_server.listen(8888) + tornado.ioloop.IOLoop.current().start() + + This class is intended to let other frameworks (Django, web.py, etc) + run on the Tornado HTTP server and I/O loop. + + The `tornado.web.FallbackHandler` class is often useful for mixing + Tornado and WSGI apps in the same server. See + https://github.com/bdarnell/django-tornado-demo for a complete example. + """ + + def __init__(self, wsgi_application: "WSGIAppType") -> None: + self.wsgi_application = wsgi_application + + def __call__(self, request: httputil.HTTPServerRequest) -> None: + data = {} # type: Dict[str, Any] + response = [] # type: List[bytes] + + def start_response( + status: str, + headers: List[Tuple[str, str]], + exc_info: Optional[ + Tuple[ + "Optional[Type[BaseException]]", + Optional[BaseException], + Optional[TracebackType], + ] + ] = None, + ) -> Callable[[bytes], Any]: + data["status"] = status + data["headers"] = headers + return response.append + + app_response = self.wsgi_application( + WSGIContainer.environ(request), start_response + ) + try: + response.extend(app_response) + body = b"".join(response) + finally: + if hasattr(app_response, "close"): + app_response.close() # type: ignore + if not data: + raise Exception("WSGI app did not call start_response") + + status_code_str, reason = data["status"].split(" ", 1) + status_code = int(status_code_str) + headers = data["headers"] # type: List[Tuple[str, str]] + header_set = set(k.lower() for (k, v) in headers) + body = escape.utf8(body) + if status_code != 304: + if "content-length" not in header_set: + headers.append(("Content-Length", str(len(body)))) + if "content-type" not in header_set: + headers.append(("Content-Type", "text/html; charset=UTF-8")) + if "server" not in header_set: + headers.append(("Server", "TornadoServer/%s" % tornado.version)) + + start_line = httputil.ResponseStartLine("HTTP/1.1", status_code, reason) + header_obj = httputil.HTTPHeaders() + for key, value in headers: + header_obj.add(key, value) + assert request.connection is not None + request.connection.write_headers(start_line, header_obj, chunk=body) + request.connection.finish() + self._log(status_code, request) + + @staticmethod + def environ(request: httputil.HTTPServerRequest) -> Dict[Text, Any]: + """Converts a `tornado.httputil.HTTPServerRequest` to a WSGI environment. + """ + hostport = request.host.split(":") + if len(hostport) == 2: + host = hostport[0] + port = int(hostport[1]) + else: + host = request.host + port = 443 if request.protocol == "https" else 80 + environ = { + "REQUEST_METHOD": request.method, + "SCRIPT_NAME": "", + "PATH_INFO": to_wsgi_str( + escape.url_unescape(request.path, encoding=None, plus=False) + ), + "QUERY_STRING": request.query, + "REMOTE_ADDR": request.remote_ip, + "SERVER_NAME": host, + "SERVER_PORT": str(port), + "SERVER_PROTOCOL": request.version, + "wsgi.version": (1, 0), + "wsgi.url_scheme": request.protocol, + "wsgi.input": BytesIO(escape.utf8(request.body)), + "wsgi.errors": sys.stderr, + "wsgi.multithread": False, + "wsgi.multiprocess": True, + "wsgi.run_once": False, + } + if "Content-Type" in request.headers: + environ["CONTENT_TYPE"] = request.headers.pop("Content-Type") + if "Content-Length" in request.headers: + environ["CONTENT_LENGTH"] = request.headers.pop("Content-Length") + for key, value in request.headers.items(): + environ["HTTP_" + key.replace("-", "_").upper()] = value + return environ + + def _log(self, status_code: int, request: httputil.HTTPServerRequest) -> None: + if status_code < 400: + log_method = access_log.info + elif status_code < 500: + log_method = access_log.warning + else: + log_method = access_log.error + request_time = 1000.0 * request.request_time() + assert request.method is not None + assert request.uri is not None + summary = request.method + " " + request.uri + " (" + request.remote_ip + ")" + log_method("%d %s %.2fms", status_code, summary, request_time) + + +HTTPRequest = httputil.HTTPServerRequest diff --git a/.venv/lib/python3.8/site-packages/traitlets-5.0.5.dist-info/COPYING.md b/.venv/lib/python3.8/site-packages/traitlets-5.0.5.dist-info/COPYING.md new file mode 100644 index 00000000..39ca730a --- /dev/null +++ b/.venv/lib/python3.8/site-packages/traitlets-5.0.5.dist-info/COPYING.md @@ -0,0 +1,62 @@ +# Licensing terms + +Traitlets is adapted from enthought.traits, Copyright (c) Enthought, Inc., +under the terms of the Modified BSD License. + +This project is licensed under the terms of the Modified BSD License +(also known as New or Revised or 3-Clause BSD), as follows: + +- Copyright (c) 2001-, IPython Development Team + +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 IPython Development Team nor the names of its +contributors may be used to endorse or promote products derived from this +software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +## About the IPython Development Team + +The IPython Development Team is the set of all contributors to the IPython project. +This includes all of the IPython subprojects. + +The core team that coordinates development on GitHub can be found here: +https://github.com/jupyter/. + +## Our Copyright Policy + +IPython uses a shared copyright model. Each contributor maintains copyright +over their contributions to IPython. But, it is important to note that these +contributions are typically only changes to the repositories. Thus, the IPython +source code, in its entirety is not the copyright of any single person or +institution. Instead, it is the collective copyright of the entire IPython +Development Team. If individual contributors want to maintain a record of what +changes/contributions they have specific copyright on, they should indicate +their copyright in the commit message of the change, when they commit the +change to one of the IPython repositories. + +With this in mind, the following banner should be used in any source code file +to indicate the copyright and license terms: + + # Copyright (c) IPython Development Team. + # Distributed under the terms of the Modified BSD License. diff --git a/.venv/lib/python3.8/site-packages/traitlets-5.0.5.dist-info/INSTALLER b/.venv/lib/python3.8/site-packages/traitlets-5.0.5.dist-info/INSTALLER new file mode 100644 index 00000000..a1b589e3 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/traitlets-5.0.5.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/.venv/lib/python3.8/site-packages/traitlets-5.0.5.dist-info/METADATA b/.venv/lib/python3.8/site-packages/traitlets-5.0.5.dist-info/METADATA new file mode 100644 index 00000000..98fce4e7 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/traitlets-5.0.5.dist-info/METADATA @@ -0,0 +1,192 @@ +Metadata-Version: 2.1 +Name: traitlets +Version: 5.0.5 +Summary: Traitlets Python configuration system +Home-page: https://github.com/ipython/traitlets +Author: IPython Development Team +Author-email: ipython-dev@python.org +License: BSD +Project-URL: Documentation, https://traitlets.readthedocs.io/ +Project-URL: Funding, https://numfocus.org/ +Project-URL: Source, https://github.com/ipython/traitlets +Project-URL: Tracker, https://github.com/ipython/traitlets/issues +Keywords: Interactive,Interpreter,Shell,Web +Platform: Linux +Platform: Mac OS X +Platform: Windows +Classifier: Intended Audience :: Developers +Classifier: Intended Audience :: System Administrators +Classifier: Intended Audience :: Science/Research +Classifier: License :: OSI Approved :: BSD License +Classifier: Programming Language :: Python +Classifier: Programming Language :: Python :: 3 +Requires-Python: >=3.7 +Description-Content-Type: text/markdown +Requires-Dist: ipython-genutils +Provides-Extra: test +Requires-Dist: pytest ; extra == 'test' + +# Traitlets + +[![Build Status](https://travis-ci.org/ipython/traitlets.svg?branch=master)](https://travis-ci.org/ipython/traitlets) +[![Documentation Status](https://readthedocs.org/projects/traitlets/badge/?version=latest)](https://traitlets.readthedocs.io/en/latest/?badge=latest) + +| | | +|---------------|----------------------------------------| +| **home** | https://github.com/ipython/traitlets | +| **pypi-repo** | https://pypi.org/project/traitlets/ | +| **docs** | https://traitlets.readthedocs.io/ | +| **license** | Modified BSD License | + +Traitlets is a pure Python library enabling: + +- the enforcement of strong typing for attributes of Python objects + (typed attributes are called *"traits"*); +- dynamically calculated default values; +- automatic validation and coercion of trait attributes when attempting a + change; +- registering for receiving notifications when trait values change; +- reading configuring values from files or from command line + arguments - a distinct layer on top of traitlets, so you may use + traitlets without the configuration machinery. + +Its implementation relies on the [descriptor](https://docs.python.org/howto/descriptor.html) +pattern, and it is a lightweight pure-python alternative of the +[*traits* library](http://code.enthought.com/pages/traits.html). + +Traitlets powers the configuration system of IPython and Jupyter +and the declarative API of IPython interactive widgets. + +## Installation + +For a local installation, make sure you have +[pip installed](https://pip.pypa.io/en/stable/installing/) and run: + +```bash +pip install traitlets +``` + +For a **development installation**, clone this repository, change into the +`traitlets` root directory, and run pip: + +```bash +git clone https://github.com/ipython/traitlets.git +cd traitlets +pip install -e . +``` + +## Running the tests + +```bash +pip install "traitlets[test]" +py.test traitlets +``` + +## Usage + +Any class with trait attributes must inherit from `HasTraits`. +For the list of available trait types and their properties, see the +[Trait Types](https://traitlets.readthedocs.io/en/latest/trait_types.html) +section of the documentation. + +### Dynamic default values + +To calculate a default value dynamically, decorate a method of your class with +`@default({traitname})`. This method will be called on the instance, and +should return the default value. In this example, the `_username_default` +method is decorated with `@default('username')`: + +```Python +import getpass +from traitlets import HasTraits, Unicode, default + +class Identity(HasTraits): + username = Unicode() + + @default('username') + def _username_default(self): + return getpass.getuser() +``` + +### Callbacks when a trait attribute changes + +When a trait changes, an application can follow this trait change with +additional actions. + +To do something when a trait attribute is changed, decorate a method with +[`traitlets.observe()`](https://traitlets.readthedocs.io/en/latest/api.html?highlight=observe#traitlets.observe). +The method will be called with a single argument, a dictionary which contains +an owner, new value, old value, name of the changed trait, and the event type. + +In this example, the `_num_changed` method is decorated with ``@observe(`num`)``: + +```Python +from traitlets import HasTraits, Integer, observe + +class TraitletsExample(HasTraits): + num = Integer(5, help="a number").tag(config=True) + + @observe('num') + def _num_changed(self, change): + print("{name} changed from {old} to {new}".format(**change)) +``` + +and is passed the following dictionary when called: + +```Python +{ + 'owner': object, # The HasTraits instance + 'new': 6, # The new value + 'old': 5, # The old value + 'name': "foo", # The name of the changed trait + 'type': 'change', # The event type of the notification, usually 'change' +} +``` + +### Validation and coercion + +Each trait type (`Int`, `Unicode`, `Dict` etc.) may have its own validation or +coercion logic. In addition, we can register custom cross-validators +that may depend on the state of other attributes. For example: + +```Python +from traitlets import HasTraits, TraitError, Int, Bool, validate + +class Parity(HasTraits): + value = Int() + parity = Int() + + @validate('value') + def _valid_value(self, proposal): + if proposal['value'] % 2 != self.parity: + raise TraitError('value and parity should be consistent') + return proposal['value'] + + @validate('parity') + def _valid_parity(self, proposal): + parity = proposal['value'] + if parity not in [0, 1]: + raise TraitError('parity should be 0 or 1') + if self.value % 2 != parity: + raise TraitError('value and parity should be consistent') + return proposal['value'] + +parity_check = Parity(value=2) + +# Changing required parity and value together while holding cross validation +with parity_check.hold_trait_notifications(): + parity_check.value = 1 + parity_check.parity = 1 +``` + +However, we **recommend** that custom cross-validators don't modify the state +of the HasTraits instance. + +### Release build: + +```bash +$ pip install build +$ python -m build . +``` + + diff --git a/.venv/lib/python3.8/site-packages/traitlets-5.0.5.dist-info/RECORD b/.venv/lib/python3.8/site-packages/traitlets-5.0.5.dist-info/RECORD new file mode 100644 index 00000000..daf97aad --- /dev/null +++ b/.venv/lib/python3.8/site-packages/traitlets-5.0.5.dist-info/RECORD @@ -0,0 +1,66 @@ +traitlets-5.0.5.dist-info/COPYING.md,sha256=cciRKQObhwzJIwlGbE--jyhagvoOo28OhA-oOXnL4x8,2957 +traitlets-5.0.5.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +traitlets-5.0.5.dist-info/METADATA,sha256=NPAkZlx_OMwDqAUb_KG8pGWC4sDTWKR__qdTn8IK0i4,6234 +traitlets-5.0.5.dist-info/RECORD,, +traitlets-5.0.5.dist-info/WHEEL,sha256=EVRjI69F5qVjm_YgqcTXPnTAv3BfSUr0WVAHuSP3Xoo,92 +traitlets-5.0.5.dist-info/top_level.txt,sha256=EtJSeHWD2tDo4fwq8c2hXVryySaLl6HicKeISu9QIJU,10 +traitlets/__init__.py,sha256=H_B4YjqLCgminvUUUgEO9o7fKG4N66qv5z1RBPNPmr4,639 +traitlets/__pycache__/__init__.cpython-38.pyc,, +traitlets/__pycache__/_version.cpython-38.pyc,, +traitlets/__pycache__/log.cpython-38.pyc,, +traitlets/__pycache__/traitlets.cpython-38.pyc,, +traitlets/_version.py,sha256=QAWJvtOJVE0EY0K49T5P-_MOLO5BEwU5OVI8xHd9jX0,372 +traitlets/config/__init__.py,sha256=HdKqizrHk_A1Jf3qr5pWH-pEM2wyNSZq-cN1a40AePQ,203 +traitlets/config/__pycache__/__init__.cpython-38.pyc,, +traitlets/config/__pycache__/application.cpython-38.pyc,, +traitlets/config/__pycache__/configurable.cpython-38.pyc,, +traitlets/config/__pycache__/loader.cpython-38.pyc,, +traitlets/config/__pycache__/manager.cpython-38.pyc,, +traitlets/config/__pycache__/sphinxdoc.cpython-38.pyc,, +traitlets/config/application.py,sha256=Y3fJYfQNINCVfUz8qwZ5N9yDLlCBITiV4bl-4O6NAtQ,33466 +traitlets/config/configurable.py,sha256=9uxH3EcDmgSE8ib4g6ZfMQfikSoFkGMCWTetSkbwtDE,20838 +traitlets/config/loader.py,sha256=Rtp-IbkLP8DRkCiIkCHE8ZmVIciBG-rPMWN4rb0rn8w,35450 +traitlets/config/manager.py,sha256=gFNnvkw4nfRhcJ8ACQ42Tc1TCUkxHfsSkBwfUq7j2ys,2333 +traitlets/config/sphinxdoc.py,sha256=Y4ZhG8-uZJslh30RE40hzFCNk-JG4ABjmfQNgD7JYkE,4980 +traitlets/config/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +traitlets/config/tests/__pycache__/__init__.cpython-38.pyc,, +traitlets/config/tests/__pycache__/test_application.cpython-38.pyc,, +traitlets/config/tests/__pycache__/test_configurable.cpython-38.pyc,, +traitlets/config/tests/__pycache__/test_loader.cpython-38.pyc,, +traitlets/config/tests/test_application.py,sha256=2AZOiruhAg2itT17wO_xaYvVdDlds8pIclJvUDVFR2I,26271 +traitlets/config/tests/test_configurable.py,sha256=c2F0roQFfE-3CCQCiVIkB_TYUQiEoNCzT1n2obX38B8,22466 +traitlets/config/tests/test_loader.py,sha256=Xz7AHIZh8JZTdMsZT-RRQR-Tn4y_g7jo2WECsLW06us,22221 +traitlets/log.py,sha256=MimotlTTF1h5NVHfow9nezn6TeGlogwl84EIk8ZOCts,779 +traitlets/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +traitlets/tests/__pycache__/__init__.cpython-38.pyc,, +traitlets/tests/__pycache__/_warnings.cpython-38.pyc,, +traitlets/tests/__pycache__/test_traitlets.cpython-38.pyc,, +traitlets/tests/__pycache__/test_traitlets_enum.cpython-38.pyc,, +traitlets/tests/__pycache__/utils.cpython-38.pyc,, +traitlets/tests/_warnings.py,sha256=69MC4Hk_Xo_iQ5EhLdevJAxSfZxIFIS5WlcySM4nhyc,4078 +traitlets/tests/test_traitlets.py,sha256=ZlTkE2hpCTNlXWyuybbc5ezhR-E7zWnD3nv4d8OlmEQ,77243 +traitlets/tests/test_traitlets_enum.py,sha256=nj1K6-Fz_Pln29gS1QTy1a8dLqAC7Nb0sdBaE-D4mSo,13646 +traitlets/tests/utils.py,sha256=V-8Yjv4SHHbW13eEOspF90RdZDqAauH_4fsafkpS5jw,1141 +traitlets/traitlets.py,sha256=h-oOki2jHDRc7JkbJrC-P8bkWaWlGFDkZSZYeAt0vLE,114432 +traitlets/utils/__init__.py,sha256=9woW-mU-fxV_pkS70BG5QO9XW02dcNTq41C6S_TBYxM,168 +traitlets/utils/__pycache__/__init__.cpython-38.pyc,, +traitlets/utils/__pycache__/bunch.cpython-38.pyc,, +traitlets/utils/__pycache__/decorators.cpython-38.pyc,, +traitlets/utils/__pycache__/descriptions.cpython-38.pyc,, +traitlets/utils/__pycache__/getargspec.cpython-38.pyc,, +traitlets/utils/__pycache__/importstring.cpython-38.pyc,, +traitlets/utils/__pycache__/sentinel.cpython-38.pyc,, +traitlets/utils/bunch.py,sha256=L56x1dMTw1vsRK3uG5Pb6KyLGqWFZFWl0gBRbaXXF74,652 +traitlets/utils/decorators.py,sha256=j7bveZodf0BHxGYHJ6bWphv8l_W6P45Tne_0LhlgtLQ,2889 +traitlets/utils/descriptions.py,sha256=uXayMrX5CvwVui0hNlQCwRKCMfArT1XLwds-gXD5TpM,5284 +traitlets/utils/getargspec.py,sha256=kgLeqW685Sg3ZgxH45oTLnXGXDdvP4AP1qRzXCtzhl8,1610 +traitlets/utils/importstring.py,sha256=7_jmHKTPUq2SbIDkjY_oAlrIVOVXgcm8XEBlop7lrnA,1127 +traitlets/utils/sentinel.py,sha256=eRXFE4cql0gvmDrfVaFATqc3nBs9MEg4-H2XWNIIsl0,524 +traitlets/utils/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +traitlets/utils/tests/__pycache__/__init__.cpython-38.pyc,, +traitlets/utils/tests/__pycache__/test_bunch.cpython-38.pyc,, +traitlets/utils/tests/__pycache__/test_decorators.cpython-38.pyc,, +traitlets/utils/tests/__pycache__/test_importstring.cpython-38.pyc,, +traitlets/utils/tests/test_bunch.py,sha256=6zBI-dKnHKlQ75m-EBYiHczKkz6DEW9N4vkOOL295kA,272 +traitlets/utils/tests/test_decorators.py,sha256=nlXv0gjv3FgdazqMqryFvzB3y-zwbXRjdcAmn52AI5c,4788 +traitlets/utils/tests/test_importstring.py,sha256=Tv11no57mFzFNrX2mqW0Sh6cccJPYj_HA1U1FIhicRo,861 diff --git a/.venv/lib/python3.8/site-packages/traitlets-5.0.5.dist-info/WHEEL b/.venv/lib/python3.8/site-packages/traitlets-5.0.5.dist-info/WHEEL new file mode 100644 index 00000000..83ff02e9 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/traitlets-5.0.5.dist-info/WHEEL @@ -0,0 +1,5 @@ +Wheel-Version: 1.0 +Generator: bdist_wheel (0.35.1) +Root-Is-Purelib: true +Tag: py3-none-any + diff --git a/.venv/lib/python3.8/site-packages/traitlets-5.0.5.dist-info/top_level.txt b/.venv/lib/python3.8/site-packages/traitlets-5.0.5.dist-info/top_level.txt new file mode 100644 index 00000000..adfea9c6 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/traitlets-5.0.5.dist-info/top_level.txt @@ -0,0 +1 @@ +traitlets diff --git a/.venv/lib/python3.8/site-packages/traitlets/__init__.py b/.venv/lib/python3.8/site-packages/traitlets/__init__.py new file mode 100644 index 00000000..ad5ba73c --- /dev/null +++ b/.venv/lib/python3.8/site-packages/traitlets/__init__.py @@ -0,0 +1,21 @@ +from warnings import warn + +from . import traitlets +from .traitlets import * +from .utils.importstring import import_item +from .utils.decorators import signature_has_traits +from .utils.bunch import Bunch +from ._version import version_info, __version__ + + +class Sentinel(traitlets.Sentinel): + def __init__(self, *args, **kwargs): + super(Sentinel, self).__init__(*args, **kwargs) + warn( + """ + Sentinel is not a public part of the traitlets API. + It was published by mistake, and may be removed in the future. + """, + DeprecationWarning, + stacklevel=2, + ) diff --git a/.venv/lib/python3.8/site-packages/traitlets/__pycache__/__init__.cpython-38.pyc b/.venv/lib/python3.8/site-packages/traitlets/__pycache__/__init__.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f0a1f882f8c965f037a6acdd68abf8f8f6590e20 GIT binary patch literal 1034 zcmY*YPjAyO6t|PKP1_X4G{J>~4_t~^cR+#*LV%FaE)&u~NV!;U?6%(QB-qZ%rb#<& z(oS&ZE9?t#$d%K+!VZY%WSzPfy{Gs5p5LFJU%rk;0|fN%><>K)5c=zlb&9}v2W$^O zaKy1f8mAZ|9`H~FI!wbxk5u@@pLJBEJ87pm>#DBqrM*V)saW^Zext`~poi&DCuxGw zC&c@FaDn(hga@PZFdgyXJ{l+2P!El99W9y3uW@Viong``;VgLYa}YzR%fdJ+ozP%z zSvk*{tBjxvW@!`dV>=(JJX?%|Iyn-?$|9#SpB43x(v?j!UvQnmTf;sDMW7UOlm?e* zhB@ZJMVyA0C_-rj&4zWnFLEbyp)%j;ihPC+@Izqx41_}tpQ7{NAUMUR!7qT(g&e!c zgZa|~i6C3Fck+8c)@YTRNK5j<5k|^ts$@n=W*jMI#4QB5Lx#NnygRvff7g*Ev+X6j z5S&bpiI&!}L-B&JoD+T`E@Z4VEx=(4Qn6;E% zp_^AbPM15SEVrw?gj#}cFBd|nZTE8e`ot}N?A%Sfvnn|$kB!GV0k&Qsyom!GM8G#E zk5)KNR`Jj}w3{<6D6I#S>Vj9w>j|abE2dgcld>M&HkS#dV7SMSycJtsd*X$k-?R0T z$GEZg#t-V)uP_X5TS$=cKUKO}IjQWV-Cyer1emUOY_tw8vcfP|7;Ad|c-S6K{UVzf rPN4VOaEz1Y+X(*yQhx~6 literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/traitlets/__pycache__/_version.cpython-38.pyc b/.venv/lib/python3.8/site-packages/traitlets/__pycache__/_version.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..50db2528e88fdfd916ec58c8d4acabb03dede401 GIT binary patch literal 361 zcmYk0&q~8U5XN_BH%ZmD_yE2@4oMDzdJs|2s|f0)myl#fj7^hecWbp5L0_aj`a&M| z>Zz|F*t!W69GKtt4a~p$!C;rTSigOxh7$7K7XQO@#kos;=OD<42)dvM$dG)%k}kLa z!It2Z3$IgO1WOos0?-==`o#F}RPfGUcHZy&P3L>JB-{zvs=cyuNtFA6SQ^hE&MnQI zWR_-g7OTR7Dz3x8_McJdvZ>RuerPOzYRcNONhU4RM%h52tg-^_UYc$jQ#-uS8kKQV zS4uVNlc-^Pti{h!VkR+~21_V8g+2&6(pbY{2i+KK%p5Bx2tH literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/traitlets/__pycache__/log.cpython-38.pyc b/.venv/lib/python3.8/site-packages/traitlets/__pycache__/log.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..51578fd6a7082cfff04cca33d45c96d4bb4848d8 GIT binary patch literal 658 zcmah{F^|(Q6n;+9Hcjc>dIN(;D$!Pmfd!#E9nyh>%79q1L~iWMnRA`Uc2%fAEG+zs zX5iQIM});WroE5AAqP%) zq)3j)A|CVP3*<46-oT`{rB{Y6sk;%hQuUH4s_Lo|hDvQ6)1{c*;T^Cj10I6lM}m2Y zX`drFWVlVuImg=-Sw)|Kz(?4{Etm(mCM~?{G0wRB@8=uDOST4T0*eeYx(*= zEm=k}US3mnP)YZ zaIf}b_8H^+1=Cy!<423NQe9!E=cVHFb}dPquFJ ze*Rb3964sq2cIEDCosGfdx8LIO70QND2q>sImJJd1bq~|E{nnpu{ON`VQ0^L1mOao VK3&y(t;Dl19ot7pdTEqIzX9f_u?GME literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/traitlets/__pycache__/traitlets.cpython-38.pyc b/.venv/lib/python3.8/site-packages/traitlets/__pycache__/traitlets.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..03405033eb4414cc52a76e2e104d914c72f2a615 GIT binary patch literal 102088 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 v?5K?JOu4d?=Wgb^mESskS>>B62YAOTD*vokA$q literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/traitlets/_version.py b/.venv/lib/python3.8/site-packages/traitlets/_version.py new file mode 100644 index 00000000..29eb5380 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/traitlets/_version.py @@ -0,0 +1,14 @@ +version_info = (5, 0, 5) + +# unlike `.dev`, alpha, beta and rc _must not_ have dots, +# or the wheel and tgz won't look to pip like the same version. + +__version__ = ( + ".".join(map(str, version_info)) + .replace(".b", "b") + .replace(".a", "a") + .replace(".rc", "rc") +) +assert ".b" not in __version__ +assert ".a" not in __version__ +assert ".rc" not in __version__ diff --git a/.venv/lib/python3.8/site-packages/traitlets/config/__init__.py b/.venv/lib/python3.8/site-packages/traitlets/config/__init__.py new file mode 100644 index 00000000..0ae7d631 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/traitlets/config/__init__.py @@ -0,0 +1,8 @@ +# encoding: utf-8 + +# Copyright (c) IPython Development Team. +# Distributed under the terms of the Modified BSD License. + +from .application import * +from .configurable import * +from .loader import Config diff --git a/.venv/lib/python3.8/site-packages/traitlets/config/__pycache__/__init__.cpython-38.pyc b/.venv/lib/python3.8/site-packages/traitlets/config/__pycache__/__init__.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a8d456b1c2c8619dc8229c166e845ecd5354a9ea GIT binary patch literal 241 zcmWIL<>g`kf`9eb;!gwV#~=$9@{H8f9NiM*B=f40@(TTu wqQuOSoYazHeTa$r@$s2?nI-Y@dIgoYIBatBQ%ZAE?bv`O7P9~e4n__}0Di|lAOHXW literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/traitlets/config/__pycache__/application.cpython-38.pyc b/.venv/lib/python3.8/site-packages/traitlets/config/__pycache__/application.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d486003bd9bec3e0e1bb9611c3718554735227e3 GIT binary patch literal 26032 zcmc(I3veY@THfuxPhDMUG#ZWO;a7V+vUKf{W;|X$Rvvpjo`*f&S=o$ad$)JZ)g7Id zbT#)Ooo>xo*H^n_XJB`MS$2UUq*y2^wMB4%R61QMu(Eka0W2oNB!&Vv+{ zK&l+plkfXa-$zR_m?V{Gd{4hlpFWTOeE;(tzcMh8PvGy}PyJfyr#_uX{2niQ|5CVk z7C-;ztVBX3+=Q}}UA1bqYuA!)(&BZpnyRJUw4A4^88?G_scP2E$}#8WW9~8J&#AuZ1GVGs zaXHUd$7&C{4@x=x)$!VdJ5ejT#o9yeL%3JidU!kGo=^jFob;x=f*QPOf5GyH)V?Ll zE0j*EA@`KmxAMr=X|-SN+qT_Dy+^k`u$@rD*D_zQ^yBJ)`&iwH?v2R37u7-BD|nBq zQSZ^w#7*ndmO7*k-%7YoJfBcU)X`fBb<}(EX43s2uJ2NJR#Nr z*Biq18Sl)>)9y1!Kjc2Ej;s5WbIWqis{7S3l=qx>PCal9_0|8_JF|6uJApQ(W)sD+ z=83b;)w1t73)QmkJBtnNl%0h}eX+8%uFF@eo>N|3tyUJwL8VcjdYjZxw8MVoEtc1- zfvPM7VgE~7dD>IwaZ$9wobtTYg~sZ}3^EqZ^%NBzoUPQCs$S5j_uejM!qE@EdR8yJ zT-Ls4o?LE}QD!*&^2WtVHGVH+a)bkTW4-3pg9}>exZuhdo>Iw(~FulAM|78c5WP+B)%D<;ECrLIu#aNiAG zUM;Pbb$JOV%YK+q9v?J+Ge5WNIgM5Jx$j){s*M{?S!0YE_3K`};-O+rxmv-n`A*P? z50{MNWc2QdeA#!ZXq~5=O5F)i>ah!J>y_)}D!zkvk2%Wo7j#8FHCe6H@!3Vm7nMJi zpKCb2$M04DoDT`%_>G$9oLQ);XHGclzBiqB@F&;KP*v^utKLFTxh^g5Qlx1j`>o~$o;Kf^oIFPgp6c9w8jW1{@U05F01d;@ zU8$43J(U?6qxja7WpmtJRoqq>b7o|?*E#I&eHByoaWjygK?=cdX} zfBe*mM^2o6eg1^A(O7qCkj zlrCJk^3s)ONX=m?(Cc1kJu>%95|{cu-m^}H>BVx@_bxVn@Rhp1zDjCGwWY^}6ukQN zif+_7J#kl8h$Pd__+RS#;~X(|H2Qmd%pZ4dELRqmd9&Uybn3i0ehO_Je}suth$pNt zkK>zD3*b|oKQ@OPjP3A`A_)>()@Kvj)@Krn7PyUlD|ge{v|1K$FYaWaNVe$i3u+GMT-Q+b&YFVz9DU087@mb|*B zL2DZ*8}mjvS2uvk?ShLSIMVQq3TEIc3PXorasEO@JU-neG+n?_dZtLtb0XLPJn*`X8~ zNEiMhlIHMd6D@RT%laX^Wq;m!EisE;4-$d3XkW|gc`LCAL7{n~l~}R2lFDi&w`~h= z;3}nT9Mk4{E2EOzmX&xd@fbvn&EzMOA5DBLQMW&eD-2L-rg`eQP9HgdL?AxE0KM1K z;}r~0Q|8LFGv+r(4UcfjQ5RNfAj&cSZBj`ws}JCy*_bd{Z7h+*gK{-YEAQ(1QkVhw z0)oO6`?r`1ljvTV%7E=_H#kE>%LCYFOy|Cpc<0%ZL2dQqYGrkDy}nvrxaO(J8_S+o zoeUnm`b0Ch@y1CRL-0fYq$&JlFRxwQ2-B51C}R#a@(V~3wrvetBi5ibWHs*>Is^w| ztx6tw;MAFFV*%6hnJIY>?6+?bfD(Y&`C*#O#xL6X6bjOhGI@l_NhYU}gu}Z_yo~#P z21z29vj%heahxsiviFa@_bh%=M=#-8kPL0bS!9PpXS>pa@aY-wzg($Q2XvQ8VZKzV zHPm{Q=Y>*fZM|GIPfXpUf|9U;`UxZ@euy(UXUX-h+HiLB&wmI>w>EClORc0KjoNNj z=6h15Zb2IT42aY1LtWG1;APB&D&`8%6_ivSK*Ks$n0~>sQ&y@%rd+N%^UIZ`Va4L%q2+EP%yj#V5#Uw7*olYU8YNb{QPRImnV1DZx z6--#nRb&V1NR^bSgzr@sr@Akir_oG*#rGE1tAbOkE2i`KYiF;_T$*`)oG=PHt@CCC z7{2))o7Pwlq;-7b(#*w|BzvX4*f`;M!Gf9i%^_!OLK?wAD*8@qfg{oW<2ieuKc55E zvQ{{;t!rt0Hzzo*lcTs>O4Xqi@ED|nOe=BI-paPDZK0SM;V{Kqm^B}2g!{Tpl|BlG zx;ISQNl=tTOC`6j^DIn*FJW3dg^Gk3lMw`&V(*0+Gh&#oeWj9!6QzyY>Q{x^mV1|Xw;H%vF4ycjXy<>R)pc=htqXbcgq=W~&ht+Y^clhWc--iVsOwbiNjBe+wH-8qd~-;eq|q#l;~J&No5aD75e%Jm1-lsXAT>@nOw z#oiGRdPJS3(19;M?meLb^{D#5EnYpT9#fAa_XpJz>PZ}@)d$ryj!&tl)EOMlsHfF4 zI6kdDq@Km`8Ff}YhvSFTIdvY#XVnFD5y!LYdG!L0o5MI6tmb#+;N1Y>$$T~{;e zC7fMQFRO3Dvy1AAn#J*XHK$&|@dfp&dJV@*>Z9soIKHS{^>G|OjGEq1pHQz$O)sl& zRwdm1h?-Yr9B1(K4Ruv5$kUg+m(_++%9E>a@~)^wwIuy9i+oMBtSa(kPQ9sC)HT%R z71dHzRm0h%H1(+aGciA@0B z`NZo_ZYBe}mE1~hgTiqA;ASdFwE%rLZ9UOSwd`wI9PO=4D@A#ym3kG*`P#(VVZ%bp zN5O_Jksk$AD|BOhX?YJt%!4#nsV`L51@w(n5GnA`h#=tkhCNY$n-(3(X#8HJrtm)h z<{(;9VWb);z-UxVXtJ!pQ)FfJMnJJ#bUfdg2D8-D^HE-C8N$L?)VbwKRpHZ)5AFhX zSgzhEZ&00e%8Mw@iRu+et!0SzQb;>{qYi=is@ExQgFF@DT?5*$;Ya+)Ofef~qmPG4 zR4dF;poJkpg~^(3g!zh3?TEUe=72$PQ>vKO&*5Bum^Z)@yn1LYgc(z#9@&E^9F7F+V!y_?Cf=sF`Su8t zdznlyk*}uDUwH17=ff14v3>!!!?b8+VeZ_OOLI`&E;k>TrEj)Rn9E=hMiJwe* z3M_9RvQCubNtmK0KKGWTi!8Jc@0Nts#>ksIoWFDU`IH#R%Qx-7YT1De!gYcqh!|%e zatQ6EG{`;!E^d>A4dFH)KC4#NK}qo%LIkd}!seqCZ!l<6GvN5ix_5)a)mF4IoPiFr zOI|<{)6b(8y3FK3Bw-G(2}3R>Wh^0}L!esn^i^hwOOD}isq@8>$)y_sIv5!rT)h5T3Gxoyt*hi+vW}DNTFp6{2hy&EKM1jNG9@jI7eWje4ftyb~ru%A_B zB^GNznCFG5Ol(N0sc{0xkY2<|E3uW>CQ8}Se1j;#(~E3V!C<51&6sv+V#T} z&kWfNUV)m3?tjfl!VzV3YK-~n>lJj4t{@2usL#c=LQqT@&{&cuu}=-kRi~7l~~YC6hNeT-!3{dMYrFTro_~64s2&|zl00gHZWxN3I>Wc zjja?1(#%ds-kFxgf!F6-_DWWtrp*Iq8UM`M`L*LX%Wc|g$Ai9=yk23t)vqwKah}*J z1Ovg~%038_xU-q8=XeifltlSM`0dAUSO_HrrgtD>YSz|>AsMl*q|14L-)vCU0Y|z$ zPe4FqyIqa3hndJUGe&1(26P#`D3-VYhGLpGNH%3>Hqc(V7SR@1BH0xTIAX2tu#$*E zz>$zyZO~-m2mVyV{W@R@6R?IU64rvKl2er9PdHbhE3vAb@)jT}kgW;cnd#pqWP;!P zJjq!=c77hk1-gPFdYIV7X8)=fBX3N3Z@}1gLtn!X77q&Mg?%9G%jhLE^8#)gbz_ld zM8mLeRX0}4OT>X()G%Mq@=4O)@WVVxTv!iifD3b8UHR1Z!hu*ng{j6WSfJhTY0AD{ zhp432_<_z$(3%D2!8)U^ZF5k;;uPsy`+Or{vIBh!LjKVp{3xKO|q>?>CxuF-b|g2Zay{(=Ge(aN)bEG3DJ!?Dzyf96C{PJ z4Jg{kNGhBP`ys5{h^#8jGqbo5SnDCmalb2mi5NMtybeqDBuPmeCT6Y{!=av{N-KV& z-aP&O%46P$Zxq4ZC=)cLUXw`WnLJZHHJ<9}p`wLRq*=Q}BdUy4 z^Jh7^AS8iiDfTtiVdQMPZKQ=TRRpk2!n(hx8#U>WUh{od
=q`^hStH!?wX6l26b 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 literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/traitlets/config/__pycache__/configurable.cpython-38.pyc b/.venv/lib/python3.8/site-packages/traitlets/config/__pycache__/configurable.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d692a1bc1fa6e622a9cd8821c128331b26e56cb2 GIT binary patch literal 15549 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 y99N%rJZoO9EqHUzTzT%B2LCE^m;XNn@WAT; literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/traitlets/config/__pycache__/loader.cpython-38.pyc b/.venv/lib/python3.8/site-packages/traitlets/config/__pycache__/loader.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c6dabb9f7e0e65db12628000524c157f67874a95 GIT binary patch literal 32630 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 literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/traitlets/config/__pycache__/sphinxdoc.cpython-38.pyc b/.venv/lib/python3.8/site-packages/traitlets/config/__pycache__/sphinxdoc.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b5989540568787efaf3d4244a8b164ef6a915116 GIT binary patch literal 4524 zcmZu!TW=f372eq!m(<0w%t$uc8jA*j%)+9BTo9B^j2Lzj6m5hwR&K0~)rvEeR$A^d zGecV!yK_5puHQNH#mY*z#-phQQukowTSa*eAd1$q+#ec<-pT@nzBop#9?B_D% zd2cijnNG5UP|G;csn9Cy!Hd>NFbL z;l1f(C{DD<6!wH%^plK;@R}m*1}|qoDj}1^$>W~!`)DwW;#9z(>y;`FI6?u zO1nKh*qEo&x$HpgG(U(qT&+LQm88V(1EG2{F%b|R{{2#$B@ zxUf^{raETtk`6DQve#}rN6cF-R@T4BOsoiw&JsT3QL1^;(=EI76U=40^tqsSkI|m# zW8>}Ne;RKg#Zvg3fZY>-{hlE z9pFV$W!48etTkBIZ?ybeAsaXS{O% zGSIYGx0df8W${4lw(RcuFqSx0q>;q-NX328y*3}K{Fer??MlpfgsniDNS_V`bmzdA z%U~dM49mvkM<;hRK|rk9S*vBukf#M9pBXbd;8*o5Gf*2X0bPy5ukz7rJ!!^E`!0 zZ2rWETs3u~aU;oKeW3{Kqp7DwPvUeW-omsp$%?Hpmo-_y?ZBtZxJEo!bSwFdn({ob>d9 zZIA8k?QyWT_l9~y?d`p=Z-*_XbW)L(KCCD*Ub;tllC|8j7N<$9gz9>TRl!RZcYPkK zL!n+3b`=OYh;=mG@N1kjmC%KBP5k7~FxDgO&YmTFkfw};63jtDo8oHXkg<+zimvb2 zxpM&{J+QuKk3W87Puz)Dctmq;I9?+jX6IBD{42O8Tm+GtG>_J zq%mE&Q8ZriNMqbHUU8EL=Sv0Tfzxk}^G{}(pJ074B~syFa(ge0mD+kGnM@(=vqmq+I~7Uj=)~+T*J~N)@FwUfsz-W}Xn9Q!JFMQMw;x zqrte*nP#(2C||?OLfDXlIruC3Z=flx$Ey>@t%7Y>U&09A!mS{TY|!YrN7i7#9*y zcEX+KAA-X3573Mq6f$G`Q8soSp;_xpF`^SvXzuM{=l$RRc3Ks7!d9~kqKMEsib`Lh zs1UrnTybGeP^E_&W1z}<6jj4f>C*brJrwD%^uZ)DtlY%elH`z-(BySArEhRa85Am4 z7Qm{zzR*Q>7|OB^qYIO)CF!`VVKj|WrPp0RS{rXp38i8lLhuFFv$MFcUReU zC$N2X-LiiOoTj_XY_`l+kyILJ*X(81bQ&0GI?J}~fWm@n5n_|x3|^h%LnEmm-V9a| zN&%ZUfKWDJapBys&RvQ!xZFC>%$u(06NcgMO?>Sa-W0{(0pig&A|FWRQB+R?%oAD> z%F{f3(|o-MiaHR&L27%4qMo}z!TP3UPIS$Q7>AR4<4-=5D7;ZK#i-PWL%Jg5{VGyJ zQZ$N_9QBmKEd=Aed@!JE16eAZLU|Rn5;rP~FxuLczd+lnNs2PLLd^|oTGWtlm0mxM z50r6?Rzp$_D;?y)(lZq0do|!0%(Kql(5Z6i#HF0W*_r)! zNg0OnCbz2`K|SthSoMrGQ7l{$1m?7A?!T6 ztW6>MGn96y&7e9{DQ?dn(;ddRZ+1eUgXxBNsNOfn!aMebxnAI^X{I$@9)4o^;Rvp? zO|@gZPnQz2jC>8GX3QG`U=Q1kjp_C~yE5H-$@QF#dl_!N)os(bEl6DwuF5Oqz+iE9 zgy3fP5R43nk43pYI>EW2#?_Lxp^OcWM$mBFhi(j~72CI}1QVy#MW|#?We87s!9Lg- z+l@xcH-1&RIjW`7GqtgC_inR7UZEn~*rO`_DT5@fTIrIa0d=IADlCE-oAPatFIm52 zy;m`=UX|XE?=M)RnrN(5^6*u*0oV%IDqw4k$=_kT#dcb&Wi6sy6h+fOA|+Q, use: + --help-all +""".strip() # trim newlines of front and back + +keyvalue_description = """ +The command-line option below sets the respective configurable class-parameter: + --Class.parameter=value +This line is evaluated in Python, so simple expressions are allowed. +For instance, to set `C.a=[0,1,2]`, you may type this: + --C.a='range(3)' +""".strip() # trim newlines of front and back + +# sys.argv can be missing, for example when python is embedded. See the docs +# for details: http://docs.python.org/2/c-api/intro.html#embedding-python +if not hasattr(sys, "argv"): + sys.argv = [""] + +subcommand_description = """ +Subcommands are launched as `{app} cmd [args]`. For information on using +subcommand 'cmd', do: `{app} cmd -h`. +""" +# get running program name + +#----------------------------------------------------------------------------- +# Application class +#----------------------------------------------------------------------------- + + + +_envvar = os.environ.get('TRAITLETS_APPLICATION_RAISE_CONFIG_FILE_ERROR','') +if _envvar.lower() in {'1','true'}: + TRAITLETS_APPLICATION_RAISE_CONFIG_FILE_ERROR = True +elif _envvar.lower() in {'0','false',''} : + TRAITLETS_APPLICATION_RAISE_CONFIG_FILE_ERROR = False +else: + raise ValueError("Unsupported value for environment variable: 'TRAITLETS_APPLICATION_RAISE_CONFIG_FILE_ERROR' is set to '%s' which is none of {'0', '1', 'false', 'true', ''}."% _envvar ) + + +def catch_config_error(method): + """Method decorator for catching invalid config (Trait/ArgumentErrors) during init. + + On a TraitError (generally caused by bad config), this will print the trait's + message, and exit the app. + + For use on init methods, to prevent invoking excepthook on invalid input. + """ + @functools.wraps(method) + def inner(app, *args, **kwargs): + try: + return method(app, *args, **kwargs) + except (TraitError, ArgumentError) as e: + app.log.fatal("Bad config encountered during initialization: %s", e) + app.log.debug("Config at the time: %s", app.config) + app.exit(1) + + return inner + +class ApplicationError(Exception): + pass + + +class LevelFormatter(logging.Formatter): + """Formatter with additional `highlevel` record + + This field is empty if log level is less than highlevel_limit, + otherwise it is formatted with self.highlevel_format. + + Useful for adding 'WARNING' to warning messages, + without adding 'INFO' to info, etc. + """ + highlevel_limit = logging.WARN + highlevel_format = " %(levelname)s |" + + def format(self, record): + if record.levelno >= self.highlevel_limit: + record.highlevel = self.highlevel_format % record.__dict__ + else: + record.highlevel = "" + return super(LevelFormatter, self).format(record) + + +class Application(SingletonConfigurable): + """A singleton application with full configuration support.""" + + # The name of the application, will usually match the name of the command + # line application + name = Unicode('application') + + # The description of the application that is printed at the beginning + # of the help. + description = Unicode('This is an application.') + # default section descriptions + option_description = Unicode(option_description) + keyvalue_description = Unicode(keyvalue_description) + subcommand_description = Unicode(subcommand_description) + + python_config_loader_class = PyFileConfigLoader + json_config_loader_class = JSONFileConfigLoader + + # The usage and example string that goes at the end of the help string. + examples = Unicode() + + # A sequence of Configurable subclasses whose config=True attributes will + # be exposed at the command line. + classes = [] + + def _classes_inc_parents(self, classes=None): + """Iterate through configurable classes, including configurable parents + + :param classes: + The list of classes to iterate; if not set, uses :attr:`classes`. + + Children should always be after parents, and each class should only be + yielded once. + """ + if classes is None: + classes = self.classes + + seen = set() + for c in classes: + # We want to sort parents before children, so we reverse the MRO + for parent in reversed(c.mro()): + if issubclass(parent, Configurable) and (parent not in seen): + seen.add(parent) + yield parent + + # The version string of this application. + version = Unicode('0.0') + + # the argv used to initialize the application + argv = List() + + # Whether failing to load config files should prevent startup + raise_config_file_errors = Bool(TRAITLETS_APPLICATION_RAISE_CONFIG_FILE_ERROR) + + # The log level for the application + log_level = Enum((0,10,20,30,40,50,'DEBUG','INFO','WARN','ERROR','CRITICAL'), + default_value=logging.WARN, + help="Set the log level by value or name.").tag(config=True) + + @observe('log_level') + @observe_compat + def _log_level_changed(self, change): + """Adjust the log level when log_level is set.""" + new = change.new + if isinstance(new, str): + new = getattr(logging, new) + self.log_level = new + self.log.setLevel(new) + + _log_formatter_cls = LevelFormatter + + log_datefmt = Unicode("%Y-%m-%d %H:%M:%S", + help="The date format used by logging formatters for %(asctime)s" + ).tag(config=True) + + log_format = Unicode("[%(name)s]%(highlevel)s %(message)s", + help="The Logging format template", + ).tag(config=True) + + @observe('log_datefmt', 'log_format') + @observe_compat + def _log_format_changed(self, change): + """Change the log formatter when log_format is set.""" + _log_handler = self._get_log_handler() + if not _log_handler: + warnings.warn( + f"No Handler found on {self.log}, setting log_format will have no effect", + RuntimeWarning, + ) + return + _log_formatter = self._log_formatter_cls(fmt=self.log_format, datefmt=self.log_datefmt) + _log_handler.setFormatter(_log_formatter) + + @default('log') + def _log_default(self): + """Start logging for this application. + + The default is to log to stderr using a StreamHandler, if no default + handler already exists. The log level starts at logging.WARN, but this + can be adjusted by setting the ``log_level`` attribute. + """ + log = logging.getLogger(self.__class__.__name__) + log.setLevel(self.log_level) + log.propagate = False + _log = log # copied from Logger.hasHandlers() (new in Python 3.2) + while _log: + if _log.handlers: + return log + if not _log.propagate: + break + else: + _log = _log.parent + if sys.executable and sys.executable.endswith('pythonw.exe'): + # this should really go to a file, but file-logging is only + # hooked up in parallel applications + _log_handler = logging.StreamHandler(open(os.devnull, 'w')) + else: + _log_handler = logging.StreamHandler() + _log_formatter = self._log_formatter_cls(fmt=self.log_format, datefmt=self.log_datefmt) + _log_handler.setFormatter(_log_formatter) + log.addHandler(_log_handler) + return log + + #: the alias map for configurables + #: Keys might strings or tuples for additional options; single-letter alias accessed like `-v`. + #: Values might be like "Class.trait" strings of two-tuples: (Class.trait, help-text). + aliases = {'log-level' : 'Application.log_level'} + + # flags for loading Configurables or store_const style flags + # flags are loaded from this dict by '--key' flags + # this must be a dict of two-tuples, the first element being the Config/dict + # and the second being the help string for the flag + flags = { + 'debug': ({ + 'Application': { + 'log_level': logging.DEBUG, + }, + }, "Set log-level to debug, for the most verbose logging."), + 'show-config': ({ + 'Application': { + 'show_config': True, + }, + }, "Show the application's configuration (human-readable format)"), + 'show-config-json': ({ + 'Application': { + 'show_config_json': True, + }, + }, "Show the application's configuration (json format)"), + } + + # subcommands for launching other applications + # if this is not empty, this will be a parent Application + # this must be a dict of two-tuples, + # the first element being the application class/import string + # and the second being the help string for the subcommand + subcommands = Dict() + # parse_command_line will initialize a subapp, if requested + subapp = Instance('traitlets.config.application.Application', allow_none=True) + + # extra command-line arguments that don't set config values + extra_args = List(Unicode()) + + cli_config = Instance(Config, (), {}, + help="""The subset of our configuration that came from the command-line + + We re-load this configuration after loading config files, + to ensure that it maintains highest priority. + """ + ) + + _loaded_config_files = List() + + show_config = Bool( + help="Instead of starting the Application, dump configuration to stdout" + ).tag(config=True) + + show_config_json = Bool( + help="Instead of starting the Application, dump configuration to stdout (as JSON)" + ).tag(config=True) + + @observe('show_config_json') + def _show_config_json_changed(self, change): + self.show_config = change.new + + @observe('show_config') + def _show_config_changed(self, change): + if change.new: + self._save_start = self.start + self.start = self.start_show_config + + def __init__(self, **kwargs): + SingletonConfigurable.__init__(self, **kwargs) + # Ensure my class is in self.classes, so my attributes appear in command line + # options and config files. + cls = self.__class__ + if cls not in self.classes: + if self.classes is cls.classes: + # class attr, assign instead of insert + self.classes = [cls] + self.classes + else: + self.classes.insert(0, self.__class__) + + @observe('config') + @observe_compat + def _config_changed(self, change): + super(Application, self)._config_changed(change) + self.log.debug('Config changed: %r', change.new) + + @catch_config_error + def initialize(self, argv=None): + """Do the basic steps to configure me. + + Override in subclasses. + """ + self.parse_command_line(argv) + + + def start(self): + """Start the app mainloop. + + Override in subclasses. + """ + if self.subapp is not None: + return self.subapp.start() + + def start_show_config(self): + """start function used when show_config is True""" + config = self.config.copy() + # exclude show_config flags from displayed config + for cls in self.__class__.mro(): + if cls.__name__ in config: + cls_config = config[cls.__name__] + cls_config.pop('show_config', None) + cls_config.pop('show_config_json', None) + + if self.show_config_json: + json.dump(config, sys.stdout, + indent=1, sort_keys=True, default=repr) + # add trailing newline + sys.stdout.write('\n') + return + + if self._loaded_config_files: + print("Loaded config files:") + for f in self._loaded_config_files: + print(' ' + f) + print() + + for classname in sorted(config): + class_config = config[classname] + if not class_config: + continue + print(classname) + pformat_kwargs = dict(indent=4, compact=True) + + for traitname in sorted(class_config): + value = class_config[traitname] + print(' .{} = {}'.format( + traitname, + pprint.pformat(value, **pformat_kwargs), + )) + + def print_alias_help(self): + """Print the alias parts of the help.""" + print('\n'.join(self.emit_alias_help())) + + def emit_alias_help(self): + """Yield the lines for alias part of the help.""" + if not self.aliases: + return + + classdict = {} + for cls in self.classes: + # include all parents (up to, but excluding Configurable) in available names + for c in cls.mro()[:-3]: + classdict[c.__name__] = c + + for alias, longname in self.aliases.items(): + try: + if isinstance(longname, tuple): + longname, fhelp = longname + else: + fhelp = None + classname, traitname = longname.split('.')[-2:] + longname = classname + '.' + traitname + cls = classdict[classname] + + trait = cls.class_traits(config=True)[traitname] + fhelp = cls.class_get_trait_help(trait, helptext=fhelp).splitlines() + + if not isinstance(alias, tuple): + alias = (alias, ) + alias = sorted(alias, key=len) + alias = ', '.join(('--%s' if len(m) > 1 else '-%s') % m + for m in alias) + + # reformat first line + fhelp[0] = fhelp[0].replace('--' + longname, alias) + for l in fhelp: + yield l + yield indent("Equivalent to: [--%s]" % longname) + except Exception as ex: + self.log.error('Failed collecting help-message for alias %r, due to: %s', + alias, ex) + raise + + def print_flag_help(self): + """Print the flag part of the help.""" + print('\n'.join(self.emit_flag_help())) + + def emit_flag_help(self): + """Yield the lines for the flag part of the help.""" + if not self.flags: + return + + for flags, (cfg, fhelp) in self.flags.items(): + try: + if not isinstance(flags, tuple): + flags = (flags, ) + flags = sorted(flags, key=len) + flags = ', '.join(('--%s' if len(m) > 1 else '-%s') % m + for m in flags) + yield flags + yield indent(dedent(fhelp.strip())) + cfg_list = ' '.join('--%s.%s=%s' %(clname, prop, val) + for clname, props_dict + in cfg.items() + for prop, val in props_dict.items()) + cfg_txt = "Equivalent to: [%s]" % cfg_list + yield indent(dedent(cfg_txt)) + except Exception as ex: + self.log.error('Failed collecting help-message for flag %r, due to: %s', + flags, ex) + raise + + def print_options(self): + """Print the options part of the help.""" + print('\n'.join(self.emit_options_help())) + + def emit_options_help(self): + """Yield the lines for the options part of the help.""" + if not self.flags and not self.aliases: + return + header = 'Options' + yield header + yield '=' * len(header) + for p in wrap_paragraphs(self.option_description): + yield p + yield '' + + for l in self.emit_flag_help(): + yield l + for l in self.emit_alias_help(): + yield l + yield '' + + def print_subcommands(self): + """Print the subcommand part of the help.""" + print('\n'.join(self.emit_subcommands_help())) + + def emit_subcommands_help(self): + """Yield the lines for the subcommand part of the help.""" + if not self.subcommands: + return + + header = "Subcommands" + yield header + yield '=' * len(header) + for p in wrap_paragraphs(self.subcommand_description.format( + app=self.name)): + yield p + yield '' + for subc, (cls, help) in self.subcommands.items(): + yield subc + if help: + yield indent(dedent(help.strip())) + yield '' + + def emit_help_epilogue(self, classes): + """Yield the very bottom lines of the help message. + + If classes=False (the default), print `--help-all` msg. + """ + if not classes: + yield "To see all available configurables, use `--help-all`." + yield '' + + def print_help(self, classes=False): + """Print the help for each Configurable class in self.classes. + + If classes=False (the default), only flags and aliases are printed. + """ + print('\n'.join(self.emit_help(classes=classes))) + + def emit_help(self, classes=False): + """Yield the help-lines for each Configurable class in self.classes. + + If classes=False (the default), only flags and aliases are printed. + """ + for l in self.emit_description(): + yield l + for l in self.emit_subcommands_help(): + yield l + for l in self.emit_options_help(): + yield l + + if classes: + help_classes = self._classes_with_config_traits() + if help_classes: + yield "Class options" + yield "=============" + for p in wrap_paragraphs(self.keyvalue_description): + yield p + yield '' + + for cls in help_classes: + yield cls.class_get_help() + yield '' + for l in self.emit_examples(): + yield l + + for l in self.emit_help_epilogue(classes): + yield l + + def document_config_options(self): + """Generate rST format documentation for the config options this application + + Returns a multiline string. + """ + return '\n'.join(c.class_config_rst_doc() + for c in self._classes_inc_parents()) + + def print_description(self): + """Print the application description.""" + print('\n'.join(self.emit_description())) + + def emit_description(self): + """Yield lines with the application description.""" + for p in wrap_paragraphs(self.description or self.__doc__): + yield p + yield '' + + def print_examples(self): + """Print usage and examples (see `emit_examples()`). """ + print('\n'.join(self.emit_examples())) + + def emit_examples(self): + """Yield lines with the usage and examples. + + This usage string goes at the end of the command line help string + and should contain examples of the application's usage. + """ + if self.examples: + yield "Examples" + yield "--------" + yield '' + yield indent(dedent(self.examples.strip())) + yield '' + + def print_version(self): + """Print the version string.""" + print(self.version) + + @catch_config_error + def initialize_subcommand(self, subc, argv=None): + """Initialize a subcommand with argv.""" + subapp, _ = self.subcommands.get(subc) + + if isinstance(subapp, str): + subapp = import_item(subapp) + + ## Cannot issubclass() on a non-type (SOhttp://stackoverflow.com/questions/8692430) + if isinstance(subapp, type) and issubclass(subapp, Application): + # Clear existing instances before... + self.__class__.clear_instance() + # instantiating subapp... + self.subapp = subapp.instance(parent=self) + elif callable(subapp): + # or ask factory to create it... + self.subapp = subapp(self) + else: + raise AssertionError("Invalid mappings for subcommand '%s'!" % subc) + + # ... and finally initialize subapp. + self.subapp.initialize(argv) + + def flatten_flags(self): + """Flatten flags and aliases for loaders, so cl-args override as expected. + + This prevents issues such as an alias pointing to InteractiveShell, + but a config file setting the same trait in TerminalInteraciveShell + getting inappropriate priority over the command-line arg. + Also, loaders expect ``(key: longname)`` and not ````key: (longname, help)`` items. + + Only aliases with exactly one descendent in the class list + will be promoted. + + """ + # build a tree of classes in our list that inherit from a particular + # it will be a dict by parent classname of classes in our list + # that are descendents + mro_tree = defaultdict(list) + for cls in self.classes: + clsname = cls.__name__ + for parent in cls.mro()[1:-3]: + # exclude cls itself and Configurable,HasTraits,object + mro_tree[parent.__name__].append(clsname) + # flatten aliases, which have the form: + # { 'alias' : 'Class.trait' } + aliases = {} + for alias, longname in self.aliases.items(): + if isinstance(longname, tuple): + longname, _ = longname + cls, trait = longname.split('.', 1) + children = mro_tree[cls] + if len(children) == 1: + # exactly one descendent, promote alias + cls = children[0] + if not isinstance(aliases, tuple): + alias = (alias, ) + for al in alias: + aliases[al] = '.'.join([cls,trait]) + + # flatten flags, which are of the form: + # { 'key' : ({'Cls' : {'trait' : value}}, 'help')} + flags = {} + for key, (flagdict, help) in self.flags.items(): + newflag = {} + for cls, subdict in flagdict.items(): + children = mro_tree[cls] + # exactly one descendent, promote flag section + if len(children) == 1: + cls = children[0] + + if cls in newflag: + newflag[cls].update(subdict) + else: + newflag[cls] = subdict + + if not isinstance(key, tuple): + key = (key, ) + for k in key: + flags[k] = (newflag, help) + return flags, aliases + + def _create_loader(self, argv, aliases, flags, classes): + return KVArgParseConfigLoader(argv, aliases, flags, classes=classes, + log=self.log) + + @catch_config_error + def parse_command_line(self, argv=None): + """Parse the command line arguments.""" + assert not isinstance(argv, str) + argv = sys.argv[1:] if argv is None else argv + self.argv = [cast_unicode(arg) for arg in argv ] + + if argv and argv[0] == 'help': + # turn `ipython help notebook` into `ipython notebook -h` + argv = argv[1:] + ['-h'] + + if self.subcommands and len(argv) > 0: + # we have subcommands, and one may have been specified + subc, subargv = argv[0], argv[1:] + if re.match(r'^\w(\-?\w)*$', subc) and subc in self.subcommands: + # it's a subcommand, and *not* a flag or class parameter + return self.initialize_subcommand(subc, subargv) + + # Arguments after a '--' argument are for the script IPython may be + # about to run, not IPython iteslf. For arguments parsed here (help and + # version), we want to only search the arguments up to the first + # occurrence of '--', which we're calling interpreted_argv. + try: + interpreted_argv = argv[:argv.index('--')] + except ValueError: + interpreted_argv = argv + + if any(x in interpreted_argv for x in ('-h', '--help-all', '--help')): + self.print_help('--help-all' in interpreted_argv) + self.exit(0) + + if '--version' in interpreted_argv or '-V' in interpreted_argv: + self.print_version() + self.exit(0) + + # flatten flags&aliases, so cl-args get appropriate priority: + flags, aliases = self.flatten_flags() + classes = tuple(self._classes_with_config_traits()) + loader = self._create_loader(argv, aliases, flags, classes=classes) + try: + self.cli_config = deepcopy(loader.load_config()) + except SystemExit: + # traitlets 5: no longer print help output on error + # help output is huge, and comes after the error + raise + self.update_config(self.cli_config) + # store unparsed args in extra_args + self.extra_args = loader.extra_args + + @classmethod + def _load_config_files(cls, basefilename, path=None, log=None, raise_config_file_errors=False): + """Load config files (py,json) by filename and path. + + yield each config object in turn. + """ + + if not isinstance(path, list): + path = [path] + for path in path[::-1]: + # path list is in descending priority order, so load files backwards: + pyloader = cls.python_config_loader_class(basefilename+'.py', path=path, log=log) + if log: + log.debug("Looking for %s in %s", basefilename, path or os.getcwd()) + jsonloader = cls.json_config_loader_class(basefilename+'.json', path=path, log=log) + loaded = [] + filenames = [] + for loader in [pyloader, jsonloader]: + config = None + try: + config = loader.load_config() + except ConfigFileNotFound: + pass + except Exception: + # try to get the full filename, but it will be empty in the + # unlikely event that the error raised before filefind finished + filename = loader.full_filename or basefilename + # problem while running the file + if raise_config_file_errors: + raise + if log: + log.error("Exception while loading config file %s", + filename, exc_info=True) + else: + if log: + log.debug("Loaded config file: %s", loader.full_filename) + if config: + for filename, earlier_config in zip(filenames, loaded): + collisions = earlier_config.collisions(config) + if collisions and log: + log.warning("Collisions detected in {0} and {1} config files." + " {1} has higher priority: {2}".format( + filename, loader.full_filename, json.dumps(collisions, indent=2), + )) + yield (config, loader.full_filename) + loaded.append(config) + filenames.append(loader.full_filename) + + @property + def loaded_config_files(self): + """Currently loaded configuration files""" + return self._loaded_config_files[:] + + @catch_config_error + def load_config_file(self, filename, path=None): + """Load config files by filename and path.""" + filename, ext = os.path.splitext(filename) + new_config = Config() + for (config, filename) in self._load_config_files(filename, path=path, log=self.log, + raise_config_file_errors=self.raise_config_file_errors, + ): + new_config.merge(config) + if filename not in self._loaded_config_files: # only add to list of loaded files if not previously loaded + self._loaded_config_files.append(filename) + # add self.cli_config to preserve CLI config priority + new_config.merge(self.cli_config) + self.update_config(new_config) + + def _classes_with_config_traits(self, classes=None): + """ + Yields only classes with configurable traits, and their subclasses. + + :param classes: + The list of classes to iterate; if not set, uses :attr:`classes`. + + Thus, produced sample config-file will contain all classes + on which a trait-value may be overridden: + + - either on the class owning the trait, + - or on its subclasses, even if those subclasses do not define + any traits themselves. + """ + if classes is None: + classes = self.classes + + cls_to_config = OrderedDict( (cls, bool(cls.class_own_traits(config=True))) + for cls + in self._classes_inc_parents(classes)) + + def is_any_parent_included(cls): + return any(b in cls_to_config and cls_to_config[b] for b in cls.__bases__) + + ## Mark "empty" classes for inclusion if their parents own-traits, + # and loop until no more classes gets marked. + # + while True: + to_incl_orig = cls_to_config.copy() + cls_to_config = OrderedDict( (cls, inc_yes or is_any_parent_included(cls)) + for cls, inc_yes + in cls_to_config.items()) + if cls_to_config == to_incl_orig: + break + for cl, inc_yes in cls_to_config.items(): + if inc_yes: + yield cl + + def generate_config_file(self, classes=None): + """generate default config file from Configurables""" + lines = ["# Configuration file for %s." % self.name] + lines.append('') + classes = self.classes if classes is None else classes + config_classes = list(self._classes_with_config_traits(classes)) + for cls in config_classes: + lines.append(cls.class_config_section(config_classes)) + return '\n'.join(lines) + + def exit(self, exit_status=0): + self.log.debug("Exiting application: %s" % self.name) + sys.exit(exit_status) + + @classmethod + def launch_instance(cls, argv=None, **kwargs): + """Launch a global instance of this Application + + If a global instance already exists, this reinitializes and starts it + """ + app = cls.instance(**kwargs) + app.initialize(argv) + app.start() + +#----------------------------------------------------------------------------- +# utility functions, for convenience +#----------------------------------------------------------------------------- + +default_aliases = Application.aliases +default_flags = Application.flags + +def boolean_flag(name, configurable, set_help='', unset_help=''): + """Helper for building basic --trait, --no-trait flags. + + Parameters + ---------- + name : str + The name of the flag. + configurable : str + The 'Class.trait' string of the trait to be set/unset with the flag + set_help : unicode + help string for --name flag + unset_help : unicode + help string for --no-name flag + + Returns + ------- + cfg : dict + A dict with two keys: 'name', and 'no-name', for setting and unsetting + the trait, respectively. + """ + # default helpstrings + set_help = set_help or "set %s=True"%configurable + unset_help = unset_help or "set %s=False"%configurable + + cls,trait = configurable.split('.') + + setter = {cls : {trait : True}} + unsetter = {cls : {trait : False}} + return {name : (setter, set_help), 'no-'+name : (unsetter, unset_help)} + + +def get_config(): + """Get the config object for the global Application instance, if there is one + + otherwise return an empty config object + """ + if Application.initialized(): + return Application.instance().config + else: + return Config() + + +if __name__ == '__main__': + Application.launch_instance() diff --git a/.venv/lib/python3.8/site-packages/traitlets/config/configurable.py b/.venv/lib/python3.8/site-packages/traitlets/config/configurable.py new file mode 100644 index 00000000..93b743ed --- /dev/null +++ b/.venv/lib/python3.8/site-packages/traitlets/config/configurable.py @@ -0,0 +1,557 @@ +"""A base class for objects that are configurable.""" + +# Copyright (c) IPython Development Team. +# Distributed under the terms of the Modified BSD License. + + +from copy import deepcopy +import logging +import warnings + +from .loader import Config, LazyConfigValue, DeferredConfig, _is_section_key +from traitlets.traitlets import ( + Any, + HasTraits, + Instance, + Container, + Dict, + observe, + observe_compat, + default, + validate, +) +from ipython_genutils.text import indent, dedent, wrap_paragraphs + + +#----------------------------------------------------------------------------- +# Helper classes for Configurables +#----------------------------------------------------------------------------- + + +class ConfigurableError(Exception): + pass + + +class MultipleInstanceError(ConfigurableError): + pass + +#----------------------------------------------------------------------------- +# Configurable implementation +#----------------------------------------------------------------------------- + +class Configurable(HasTraits): + + config = Instance(Config, (), {}) + parent = Instance('traitlets.config.configurable.Configurable', allow_none=True) + + def __init__(self, **kwargs): + """Create a configurable given a config config. + + Parameters + ---------- + config : Config + If this is empty, default values are used. If config is a + :class:`Config` instance, it will be used to configure the + instance. + parent : Configurable instance, optional + The parent Configurable instance of this object. + + Notes + ----- + Subclasses of Configurable must call the :meth:`__init__` method of + :class:`Configurable` *before* doing anything else and using + :func:`super`:: + + class MyConfigurable(Configurable): + def __init__(self, config=None): + super(MyConfigurable, self).__init__(config=config) + # Then any other code you need to finish initialization. + + This ensures that instances will be configured properly. + """ + parent = kwargs.pop('parent', None) + if parent is not None: + # config is implied from parent + if kwargs.get('config', None) is None: + kwargs['config'] = parent.config + self.parent = parent + + config = kwargs.pop('config', None) + + # load kwarg traits, other than config + super(Configurable, self).__init__(**kwargs) + + # record traits set by config + config_override_names = set() + def notice_config_override(change): + """Record traits set by both config and kwargs. + + They will need to be overridden again after loading config. + """ + if change.name in kwargs: + config_override_names.add(change.name) + self.observe(notice_config_override) + + # load config + if config is not None: + # We used to deepcopy, but for now we are trying to just save + # by reference. This *could* have side effects as all components + # will share config. In fact, I did find such a side effect in + # _config_changed below. If a config attribute value was a mutable type + # all instances of a component were getting the same copy, effectively + # making that a class attribute. + # self.config = deepcopy(config) + self.config = config + else: + # allow _config_default to return something + self._load_config(self.config) + self.unobserve(notice_config_override) + + for name in config_override_names: + setattr(self, name, kwargs[name]) + + + #------------------------------------------------------------------------- + # Static trait notifiations + #------------------------------------------------------------------------- + + @classmethod + def section_names(cls): + """return section names as a list""" + return [c.__name__ for c in reversed(cls.__mro__) if + issubclass(c, Configurable) and issubclass(cls, c) + ] + + def _find_my_config(self, cfg): + """extract my config from a global Config object + + will construct a Config object of only the config values that apply to me + based on my mro(), as well as those of my parent(s) if they exist. + + If I am Bar and my parent is Foo, and their parent is Tim, + this will return merge following config sections, in this order:: + + [Bar, Foo.Bar, Tim.Foo.Bar] + + With the last item being the highest priority. + """ + cfgs = [cfg] + if self.parent: + cfgs.append(self.parent._find_my_config(cfg)) + my_config = Config() + for c in cfgs: + for sname in self.section_names(): + # Don't do a blind getattr as that would cause the config to + # dynamically create the section with name Class.__name__. + if c._has_section(sname): + my_config.merge(c[sname]) + return my_config + + def _load_config(self, cfg, section_names=None, traits=None): + """load traits from a Config object""" + + if traits is None: + traits = self.traits(config=True) + if section_names is None: + section_names = self.section_names() + + my_config = self._find_my_config(cfg) + + # hold trait notifications until after all config has been loaded + with self.hold_trait_notifications(): + for name, config_value in my_config.items(): + if name in traits: + if isinstance(config_value, LazyConfigValue): + # ConfigValue is a wrapper for using append / update on containers + # without having to copy the initial value + initial = getattr(self, name) + config_value = config_value.get_value(initial) + elif isinstance(config_value, DeferredConfig): + # DeferredConfig tends to come from CLI/environment variables + config_value = config_value.get_value(traits[name]) + # We have to do a deepcopy here if we don't deepcopy the entire + # config object. If we don't, a mutable config_value will be + # shared by all instances, effectively making it a class attribute. + setattr(self, name, deepcopy(config_value)) + elif not _is_section_key(name) and not isinstance(config_value, Config): + from difflib import get_close_matches + if isinstance(self, LoggingConfigurable): + warn = self.log.warning + else: + warn = lambda msg: warnings.warn(msg, stacklevel=9) + matches = get_close_matches(name, traits) + msg = "Config option `{option}` not recognized by `{klass}`.".format( + option=name, klass=self.__class__.__name__) + + if len(matches) == 1: + msg += " Did you mean `{matches}`?".format(matches=matches[0]) + elif len(matches) >= 1: + msg +=" Did you mean one of: `{matches}`?".format(matches=', '.join(sorted(matches))) + warn(msg) + + @observe('config') + @observe_compat + def _config_changed(self, change): + """Update all the class traits having ``config=True`` in metadata. + + For any class trait with a ``config`` metadata attribute that is + ``True``, we update the trait with the value of the corresponding + config entry. + """ + # Get all traits with a config metadata entry that is True + traits = self.traits(config=True) + + # We auto-load config section for this class as well as any parent + # classes that are Configurable subclasses. This starts with Configurable + # and works down the mro loading the config for each section. + section_names = self.section_names() + self._load_config(change.new, traits=traits, section_names=section_names) + + def update_config(self, config): + """Update config and load the new values""" + # traitlets prior to 4.2 created a copy of self.config in order to trigger change events. + # Some projects (IPython < 5) relied upon one side effect of this, + # that self.config prior to update_config was not modified in-place. + # For backward-compatibility, we must ensure that self.config + # is a new object and not modified in-place, + # but config consumers should not rely on this behavior. + self.config = deepcopy(self.config) + # load config + self._load_config(config) + # merge it into self.config + self.config.merge(config) + # TODO: trigger change event if/when dict-update change events take place + # DO NOT trigger full trait-change + + @classmethod + def class_get_help(cls, inst=None): + """Get the help string for this class in ReST format. + + If `inst` is given, it's current trait values will be used in place of + class defaults. + """ + assert inst is None or isinstance(inst, cls) + final_help = [] + base_classes = ', '.join(p.__name__ for p in cls.__bases__) + final_help.append('%s(%s) options' % (cls.__name__, base_classes)) + final_help.append(len(final_help[0])*'-') + for k, v in sorted(cls.class_traits(config=True).items()): + help = cls.class_get_trait_help(v, inst) + final_help.append(help) + return '\n'.join(final_help) + + @classmethod + def class_get_trait_help(cls, trait, inst=None, helptext=None): + """Get the helptext string for a single trait. + + :param inst: + If given, it's current trait values will be used in place of + the class default. + :param helptext: + If not given, uses the `help` attribute of the current trait. + """ + assert inst is None or isinstance(inst, cls) + lines = [] + header = "--%s.%s" % (cls.__name__, trait.name) + if isinstance(trait, (Container, Dict)): + multiplicity = trait.metadata.get('multiplicity', 'append') + if isinstance(trait, Dict): + sample_value = '=' + else: + sample_value = '<%s-item-1>' % trait.__class__.__name__.lower() + if multiplicity == 'append': + header = "%s=%s..." % (header, sample_value) + else: + header = "%s %s..." % (header, sample_value) + else: + header = '%s=<%s>' % (header, trait.__class__.__name__) + #header = "--%s.%s=<%s>" % (cls.__name__, trait.name, trait.__class__.__name__) + lines.append(header) + + if helptext is None: + helptext = trait.help + if helptext != '': + helptext = '\n'.join(wrap_paragraphs(helptext, 76)) + lines.append(indent(helptext, 4)) + + if 'Enum' in trait.__class__.__name__: + # include Enum choices + lines.append(indent('Choices: %s' % trait.info())) + + if inst is not None: + lines.append(indent('Current: %r' % (getattr(inst, trait.name),), 4)) + else: + try: + dvr = trait.default_value_repr() + except Exception: + dvr = None # ignore defaults we can't construct + if dvr is not None: + if len(dvr) > 64: + dvr = dvr[:61]+'...' + lines.append(indent('Default: %s' % dvr, 4)) + + return '\n'.join(lines) + + @classmethod + def class_print_help(cls, inst=None): + """Get the help string for a single trait and print it.""" + print(cls.class_get_help(inst)) + + @classmethod + def _defining_class(cls, trait, classes): + """Get the class that defines a trait + + For reducing redundant help output in config files. + Returns the current class if: + - the trait is defined on this class, or + - the class where it is defined would not be in the config file + + Parameters + ---------- + trait : Trait + The trait to look for + classes : list + The list of other classes to consider for redundancy. + Will return `cls` even if it is not defined on `cls` + if the defining class is not in `classes`. + """ + defining_cls = cls + for parent in cls.mro(): + if issubclass(parent, Configurable) and \ + parent in classes and \ + parent.class_own_traits(config=True).get(trait.name, None) is trait: + defining_cls = parent + return defining_cls + + @classmethod + def class_config_section(cls, classes=None): + """Get the config section for this class. + + Parameters + ---------- + classes : list, optional + The list of other classes in the config file. + Used to reduce redundant information. + """ + def c(s): + """return a commented, wrapped block.""" + s = '\n\n'.join(wrap_paragraphs(s, 78)) + + return '## ' + s.replace('\n', '\n# ') + + # section header + breaker = '#' + '-' * 78 + parent_classes = ', '.join( + p.__name__ for p in cls.__bases__ + if issubclass(p, Configurable) + ) + + s = "# %s(%s) configuration" % (cls.__name__, parent_classes) + lines = [breaker, s, breaker] + # get the description trait + desc = cls.class_traits().get('description') + if desc: + desc = desc.default_value + if not desc: + # no description from trait, use __doc__ + desc = getattr(cls, '__doc__', '') + if desc: + lines.append(c(desc)) + lines.append('') + + for name, trait in sorted(cls.class_traits(config=True).items()): + default_repr = trait.default_value_repr() + + if classes: + defining_class = cls._defining_class(trait, classes) + else: + defining_class = cls + if defining_class is cls: + # cls owns the trait, show full help + if trait.help: + lines.append(c(trait.help)) + if 'Enum' in type(trait).__name__: + # include Enum choices + lines.append('# Choices: %s' % trait.info()) + lines.append('# Default: %s' % default_repr) + else: + # Trait appears multiple times and isn't defined here. + # Truncate help to first line + "See also Original.trait" + if trait.help: + lines.append(c(trait.help.split('\n', 1)[0])) + lines.append('# See also: %s.%s' % (defining_class.__name__, name)) + + lines.append('# c.%s.%s = %s' % (cls.__name__, name, default_repr)) + lines.append('') + return '\n'.join(lines) + + @classmethod + def class_config_rst_doc(cls): + """Generate rST documentation for this class' config options. + + Excludes traits defined on parent classes. + """ + lines = [] + classname = cls.__name__ + for k, trait in sorted(cls.class_traits(config=True).items()): + ttype = trait.__class__.__name__ + + termline = classname + '.' + trait.name + + # Choices or type + if 'Enum' in ttype: + # include Enum choices + termline += ' : ' + trait.info_rst() + else: + termline += ' : ' + ttype + lines.append(termline) + + # Default value + try: + dvr = trait.default_value_repr() + except Exception: + dvr = None # ignore defaults we can't construct + if dvr is not None: + if len(dvr) > 64: + dvr = dvr[:61]+'...' + # Double up backslashes, so they get to the rendered docs + dvr = dvr.replace('\\n', '\\\\n') + lines.append(indent('Default: ``%s``' % dvr, 4)) + lines.append('') + + help = trait.help or 'No description' + lines.append(indent(dedent(help), 4)) + + # Blank line + lines.append('') + + return '\n'.join(lines) + + + +class LoggingConfigurable(Configurable): + """A parent class for Configurables that log. + + Subclasses have a log trait, and the default behavior + is to get the logger from the currently running Application. + """ + + log = Any(help="Logger or LoggerAdapter instance") + + @validate("log") + def _validate_log(self, proposal): + if not isinstance(proposal.value, (logging.Logger, logging.LoggerAdapter)): + # warn about unsupported type, but be lenient to allow for duck typing + warnings.warn( + f"{self.__class__.__name__}.log should be a Logger or LoggerAdapter," + f" got {proposal.value}." + ) + return proposal.value + + @default("log") + def _log_default(self): + if isinstance(self.parent, LoggingConfigurable): + return self.parent.log + from traitlets import log + return log.get_logger() + + def _get_log_handler(self): + """Return the default Handler + + Returns None if none can be found + """ + logger = self.log + if isinstance(logger, logging.LoggerAdapter): + logger = logger.logger + if not getattr(logger, "handlers", None): + # no handlers attribute or empty handlers list + return None + return logger.handlers[0] + + +class SingletonConfigurable(LoggingConfigurable): + """A configurable that only allows one instance. + + This class is for classes that should only have one instance of itself + or *any* subclass. To create and retrieve such a class use the + :meth:`SingletonConfigurable.instance` method. + """ + + _instance = None + + @classmethod + def _walk_mro(cls): + """Walk the cls.mro() for parent classes that are also singletons + + For use in instance() + """ + + for subclass in cls.mro(): + if issubclass(cls, subclass) and \ + issubclass(subclass, SingletonConfigurable) and \ + subclass != SingletonConfigurable: + yield subclass + + @classmethod + def clear_instance(cls): + """unset _instance for this class and singleton parents. + """ + if not cls.initialized(): + return + for subclass in cls._walk_mro(): + if isinstance(subclass._instance, cls): + # only clear instances that are instances + # of the calling class + subclass._instance = None + + @classmethod + def instance(cls, *args, **kwargs): + """Returns a global instance of this class. + + This method create a new instance if none have previously been created + and returns a previously created instance is one already exists. + + The arguments and keyword arguments passed to this method are passed + on to the :meth:`__init__` method of the class upon instantiation. + + Examples + -------- + Create a singleton class using instance, and retrieve it:: + + >>> from traitlets.config.configurable import SingletonConfigurable + >>> class Foo(SingletonConfigurable): pass + >>> foo = Foo.instance() + >>> foo == Foo.instance() + True + + Create a subclass that is retrived using the base class instance:: + + >>> class Bar(SingletonConfigurable): pass + >>> class Bam(Bar): pass + >>> bam = Bam.instance() + >>> bam == Bar.instance() + True + """ + # Create and save the instance + if cls._instance is None: + inst = cls(*args, **kwargs) + # Now make sure that the instance will also be returned by + # parent classes' _instance attribute. + for subclass in cls._walk_mro(): + subclass._instance = inst + + if isinstance(cls._instance, cls): + return cls._instance + else: + raise MultipleInstanceError( + "An incompatible sibling of '%s' is already instanciated" + " as singleton: %s" % (cls.__name__, type(cls._instance).__name__) + ) + + @classmethod + def initialized(cls): + """Has an instance been created?""" + return hasattr(cls, "_instance") and cls._instance is not None + + + diff --git a/.venv/lib/python3.8/site-packages/traitlets/config/loader.py b/.venv/lib/python3.8/site-packages/traitlets/config/loader.py new file mode 100644 index 00000000..d6d90ee4 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/traitlets/config/loader.py @@ -0,0 +1,1086 @@ +"""A simple configuration system.""" + +# Copyright (c) IPython Development Team. +# Distributed under the terms of the Modified BSD License. + +import argparse +import copy +import os +import re +import sys +import json +import warnings + +from ..utils import cast_unicode + +from ipython_genutils.path import filefind +from ipython_genutils.encoding import DEFAULT_ENCODING +from traitlets.traitlets import ( + HasTraits, Container, List, Dict, Any, Undefined, +) + +#----------------------------------------------------------------------------- +# Exceptions +#----------------------------------------------------------------------------- + + +class ConfigError(Exception): + pass + +class ConfigLoaderError(ConfigError): + pass + +class ConfigFileNotFound(ConfigError): + pass + +class ArgumentError(ConfigLoaderError): + pass + +#----------------------------------------------------------------------------- +# Argparse fix +#----------------------------------------------------------------------------- + +# Unfortunately argparse by default prints help messages to stderr instead of +# stdout. This makes it annoying to capture long help screens at the command +# line, since one must know how to pipe stderr, which many users don't know how +# to do. So we override the print_help method with one that defaults to +# stdout and use our class instead. + + +class _Sentinel: + def __repr__(self): + return "" + + def __str__(self): + return "" + + +_deprecated = _Sentinel() + + +class ArgumentParser(argparse.ArgumentParser): + """Simple argparse subclass that prints help to stdout by default.""" + + def print_help(self, file=None): + if file is None: + file = sys.stdout + return super(ArgumentParser, self).print_help(file) + + print_help.__doc__ = argparse.ArgumentParser.print_help.__doc__ + +#----------------------------------------------------------------------------- +# Config class for holding config information +#----------------------------------------------------------------------------- + +def execfile(fname, glob): + with open(fname, 'rb') as f: + exec(compile(f.read(), fname, 'exec'), glob, glob) + +class LazyConfigValue(HasTraits): + """Proxy object for exposing methods on configurable containers + + These methods allow appending/extending/updating + to add to non-empty defaults instead of clobbering them. + + Exposes: + + - append, extend, insert on lists + - update on dicts + - update, add on sets + """ + + _value = None + + # list methods + _extend = List() + _prepend = List() + _inserts = List() + + def append(self, obj): + """Append an item to a List""" + self._extend.append(obj) + + def extend(self, other): + """Extend a list""" + self._extend.extend(other) + + def prepend(self, other): + """like list.extend, but for the front""" + self._prepend[:0] = other + + + def merge_into(self, other): + """ + Merge with another earlier LazyConfigValue or an earlier container. + This is useful when having global system-wide configuration files. + + Self is expected to have higher precedence. + + Parameters + ---------- + other : LazyConfigValue or container + + Returns + ------- + LazyConfigValue + if ``other`` is also lazy, a reified container otherwise. + """ + if isinstance(other, LazyConfigValue): + other._extend.extend(self._extend) + self._extend = other._extend + + self._prepend.extend(other._prepend) + + other._inserts.extend(self._inserts) + self._inserts = other._inserts + + if self._update: + other.update(self._update) + self._update = other._update + return self + else: + # other is a container, reify now. + return self.get_value(other) + + def insert(self, index, other): + if not isinstance(index, int): + raise TypeError("An integer is required") + self._inserts.append((index, other)) + + # dict methods + # update is used for both dict and set + _update = Any() + + def update(self, other): + """Update either a set or dict""" + if self._update is None: + if isinstance(other, dict): + self._update = {} + else: + self._update = set() + self._update.update(other) + + # set methods + def add(self, obj): + """Add an item to a set""" + self.update({obj}) + + def get_value(self, initial): + """construct the value from the initial one + + after applying any insert / extend / update changes + """ + if self._value is not None: + return self._value + value = copy.deepcopy(initial) + if isinstance(value, list): + for idx, obj in self._inserts: + value.insert(idx, obj) + value[:0] = self._prepend + value.extend(self._extend) + + elif isinstance(value, dict): + if self._update: + value.update(self._update) + elif isinstance(value, set): + if self._update: + value.update(self._update) + self._value = value + return value + + def to_dict(self): + """return JSONable dict form of my data + + Currently update as dict or set, extend, prepend as lists, and inserts as list of tuples. + """ + d = {} + if self._update: + d['update'] = self._update + if self._extend: + d['extend'] = self._extend + if self._prepend: + d['prepend'] = self._prepend + elif self._inserts: + d['inserts'] = self._inserts + return d + + def __repr__(self): + if self._value is not None: + return "<%s value=%r>" % (self.__class__.__name__, self._value) + else: + return "<%s %r>" % (self.__class__.__name__, self.to_dict()) + + +def _is_section_key(key): + """Is a Config key a section name (does it start with a capital)?""" + if key and key[0].upper()==key[0] and not key.startswith('_'): + return True + else: + return False + + +class Config(dict): + """An attribute-based dict that can do smart merges. + + Accessing a field on a config object for the first time populates the key + with either a nested Config object for keys starting with capitals + or :class:`.LazyConfigValue` for lowercase keys, + allowing quick assignments such as:: + + c = Config() + c.Class.int_trait = 5 + c.Class.list_trait.append("x") + + """ + + def __init__(self, *args, **kwds): + dict.__init__(self, *args, **kwds) + self._ensure_subconfig() + + def _ensure_subconfig(self): + """ensure that sub-dicts that should be Config objects are + + casts dicts that are under section keys to Config objects, + which is necessary for constructing Config objects from dict literals. + """ + for key in self: + obj = self[key] + if _is_section_key(key) \ + and isinstance(obj, dict) \ + and not isinstance(obj, Config): + setattr(self, key, Config(obj)) + + def _merge(self, other): + """deprecated alias, use Config.merge()""" + self.merge(other) + + def merge(self, other): + """merge another config object into this one""" + to_update = {} + for k, v in other.items(): + if k not in self: + to_update[k] = v + else: # I have this key + if isinstance(v, Config) and isinstance(self[k], Config): + # Recursively merge common sub Configs + self[k].merge(v) + elif isinstance(v, LazyConfigValue): + self[k] = v.merge_into(self[k]) + else: + # Plain updates for non-Configs + to_update[k] = v + + self.update(to_update) + + def collisions(self, other): + """Check for collisions between two config objects. + + Returns a dict of the form {"Class": {"trait": "collision message"}}`, + indicating which values have been ignored. + + An empty dict indicates no collisions. + """ + collisions = {} + for section in self: + if section not in other: + continue + mine = self[section] + theirs = other[section] + for key in mine: + if key in theirs and mine[key] != theirs[key]: + collisions.setdefault(section, {}) + collisions[section][key] = "%r ignored, using %r" % (mine[key], theirs[key]) + return collisions + + def __contains__(self, key): + # allow nested contains of the form `"Section.key" in config` + if '.' in key: + first, remainder = key.split('.', 1) + if first not in self: + return False + return remainder in self[first] + + return super(Config, self).__contains__(key) + + # .has_key is deprecated for dictionaries. + has_key = __contains__ + + def _has_section(self, key): + return _is_section_key(key) and key in self + + def copy(self): + return type(self)(dict.copy(self)) + + def __copy__(self): + return self.copy() + + def __deepcopy__(self, memo): + new_config = type(self)() + for key, value in self.items(): + if isinstance(value, (Config, LazyConfigValue)): + # deep copy config objects + value = copy.deepcopy(value, memo) + elif type(value) in {dict, list, set, tuple}: + # shallow copy plain container traits + value = copy.copy(value) + new_config[key] = value + return new_config + + def __getitem__(self, key): + try: + return dict.__getitem__(self, key) + except KeyError: + if _is_section_key(key): + c = Config() + dict.__setitem__(self, key, c) + return c + elif not key.startswith('_'): + # undefined, create lazy value, used for container methods + v = LazyConfigValue() + dict.__setitem__(self, key, v) + return v + else: + raise KeyError + + def __setitem__(self, key, value): + if _is_section_key(key): + if not isinstance(value, Config): + raise ValueError('values whose keys begin with an uppercase ' + 'char must be Config instances: %r, %r' % (key, value)) + dict.__setitem__(self, key, value) + + def __getattr__(self, key): + if key.startswith('__'): + return dict.__getattr__(self, key) + try: + return self.__getitem__(key) + except KeyError as e: + raise AttributeError(e) + + def __setattr__(self, key, value): + if key.startswith('__'): + return dict.__setattr__(self, key, value) + try: + self.__setitem__(key, value) + except KeyError as e: + raise AttributeError(e) + + def __delattr__(self, key): + if key.startswith('__'): + return dict.__delattr__(self, key) + try: + dict.__delitem__(self, key) + except KeyError as e: + raise AttributeError(e) + + +class DeferredConfig: + """Class for deferred-evaluation of config from CLI""" + pass + + def get_value(self, trait): + raise NotImplementedError("Implement in subclasses") + + def _super_repr(self): + # explicitly call super on direct parent + return super(self.__class__, self).__repr__() + + +class DeferredConfigString(str, DeferredConfig): + """Config value for loading config from a string + + Interpretation is deferred until it is loaded into the trait. + + Subclass of str for backward compatibility. + + This class is only used for values that are not listed + in the configurable classes. + + When config is loaded, `trait.from_string` will be used. + + If an error is raised in `.from_string`, + the original string is returned. + + .. versionadded:: 5.0 + """ + def get_value(self, trait): + """Get the value stored in this string""" + s = str(self) + try: + return trait.from_string(s) + except Exception: + # exception casting from string, + # let the original string lie. + # this will raise a more informative error when config is loaded. + return s + + def __repr__(self): + return '%s(%s)' % (self.__class__.__name__, self._super_repr()) + + +class DeferredConfigList(list, DeferredConfig): + """Config value for loading config from a list of strings + + Interpretation is deferred until it is loaded into the trait. + + This class is only used for values that are not listed + in the configurable classes. + + When config is loaded, `trait.from_string_list` will be used. + + If an error is raised in `.from_string_list`, + the original string list is returned. + + .. versionadded:: 5.0 + """ + def get_value(self, trait): + """Get the value stored in this string""" + if hasattr(trait, "from_string_list"): + src = list(self) + cast = trait.from_string_list + else: + # only allow one item + if len(self) > 1: + raise ValueError(f"{trait.name} only accepts one value, got {len(self)}: {list(self)}") + src = self[0] + cast = trait.from_string + + try: + return cast(src) + except Exception: + # exception casting from string, + # let the original value lie. + # this will raise a more informative error when config is loaded. + return src + + def __repr__(self): + return '%s(%s)' % (self.__class__.__name__, self._super_repr()) + + +#----------------------------------------------------------------------------- +# Config loading classes +#----------------------------------------------------------------------------- + + +class ConfigLoader(object): + """A object for loading configurations from just about anywhere. + + The resulting configuration is packaged as a :class:`Config`. + + Notes + ----- + A :class:`ConfigLoader` does one thing: load a config from a source + (file, command line arguments) and returns the data as a :class:`Config` object. + There are lots of things that :class:`ConfigLoader` does not do. It does + not implement complex logic for finding config files. It does not handle + default values or merge multiple configs. These things need to be + handled elsewhere. + """ + + def _log_default(self): + from traitlets.log import get_logger + return get_logger() + + def __init__(self, log=None): + """A base class for config loaders. + + log : instance of :class:`logging.Logger` to use. + By default logger of :meth:`traitlets.config.application.Application.instance()` + will be used + + Examples + -------- + >>> cl = ConfigLoader() + >>> config = cl.load_config() + >>> config + {} + """ + self.clear() + if log is None: + self.log = self._log_default() + self.log.debug('Using default logger') + else: + self.log = log + + def clear(self): + self.config = Config() + + def load_config(self): + """Load a config from somewhere, return a :class:`Config` instance. + + Usually, this will cause self.config to be set and then returned. + However, in most cases, :meth:`ConfigLoader.clear` should be called + to erase any previous state. + """ + self.clear() + return self.config + + +class FileConfigLoader(ConfigLoader): + """A base class for file based configurations. + + As we add more file based config loaders, the common logic should go + here. + """ + + def __init__(self, filename, path=None, **kw): + """Build a config loader for a filename and path. + + Parameters + ---------- + filename : str + The file name of the config file. + path : str, list, tuple + The path to search for the config file on, or a sequence of + paths to try in order. + """ + super(FileConfigLoader, self).__init__(**kw) + self.filename = filename + self.path = path + self.full_filename = '' + + def _find_file(self): + """Try to find the file by searching the paths.""" + self.full_filename = filefind(self.filename, self.path) + +class JSONFileConfigLoader(FileConfigLoader): + """A JSON file loader for config + + Can also act as a context manager that rewrite the configuration file to disk on exit. + + Example:: + + with JSONFileConfigLoader('myapp.json','/home/jupyter/configurations/') as c: + c.MyNewConfigurable.new_value = 'Updated' + + """ + + def load_config(self): + """Load the config from a file and return it as a Config object.""" + self.clear() + try: + self._find_file() + except IOError as e: + raise ConfigFileNotFound(str(e)) + dct = self._read_file_as_dict() + self.config = self._convert_to_config(dct) + return self.config + + def _read_file_as_dict(self): + with open(self.full_filename) as f: + return json.load(f) + + def _convert_to_config(self, dictionary): + if 'version' in dictionary: + version = dictionary.pop('version') + else: + version = 1 + + if version == 1: + return Config(dictionary) + else: + raise ValueError('Unknown version of JSON config file: {version}'.format(version=version)) + + def __enter__(self): + self.load_config() + return self.config + + def __exit__(self, exc_type, exc_value, traceback): + """ + Exit the context manager but do not handle any errors. + + In case of any error, we do not want to write the potentially broken + configuration to disk. + """ + self.config.version = 1 + json_config = json.dumps(self.config, indent=2) + with open(self.full_filename, 'w') as f: + f.write(json_config) + + + +class PyFileConfigLoader(FileConfigLoader): + """A config loader for pure python files. + + This is responsible for locating a Python config file by filename and + path, then executing it to construct a Config object. + """ + + def load_config(self): + """Load the config from a file and return it as a Config object.""" + self.clear() + try: + self._find_file() + except IOError as e: + raise ConfigFileNotFound(str(e)) + self._read_file_as_dict() + return self.config + + def load_subconfig(self, fname, path=None): + """Injected into config file namespace as load_subconfig""" + if path is None: + path = self.path + + loader = self.__class__(fname, path) + try: + sub_config = loader.load_config() + except ConfigFileNotFound: + # Pass silently if the sub config is not there, + # treat it as an empty config file. + pass + else: + self.config.merge(sub_config) + + def _read_file_as_dict(self): + """Load the config file into self.config, with recursive loading.""" + def get_config(): + """Unnecessary now, but a deprecation warning is more trouble than it's worth.""" + return self.config + + namespace = dict( + c=self.config, + load_subconfig=self.load_subconfig, + get_config=get_config, + __file__=self.full_filename, + ) + conf_filename = self.full_filename + with open(conf_filename, 'rb') as f: + exec(compile(f.read(), conf_filename, 'exec'), namespace, namespace) + + +class CommandLineConfigLoader(ConfigLoader): + """A config loader for command line arguments. + + As we add more command line based loaders, the common logic should go + here. + """ + + def _exec_config_str(self, lhs, rhs, trait=None): + """execute self.config. = + + * expands ~ with expanduser + * interprets value with trait if available + """ + value = rhs + if isinstance(value, DeferredConfig): + if trait: + # trait available, reify config immediately + value = value.get_value(trait) + elif isinstance(rhs, DeferredConfigList) and len(rhs) == 1: + # single item, make it a deferred str + value = DeferredConfigString(os.path.expanduser(rhs[0])) + else: + if trait: + value = trait.from_string(value) + else: + value = DeferredConfigString(value) + + *path, key = lhs.split(".") + section = self.config + for part in path: + section = section[part] + section[key] = value + return + + def _load_flag(self, cfg): + """update self.config from a flag, which can be a dict or Config""" + if isinstance(cfg, (dict, Config)): + # don't clobber whole config sections, update + # each section from config: + for sec, c in cfg.items(): + self.config[sec].update(c) + else: + raise TypeError("Invalid flag: %r" % cfg) + +# match --Class.trait keys for argparse +# matches: +# --Class.trait +# --x +# -x + +class_trait_opt_pattern = re.compile(r'^\-?\-[A-Za-z][\w]*(\.[\w]+)*$') + +_DOT_REPLACEMENT = "__DOT__" +_DASH_REPLACEMENT = "__DASH__" + + +class _KVAction(argparse.Action): + """Custom argparse action for handling --Class.trait=x + + Always + """ + def __call__(self, parser, namespace, values, option_string=None): + if isinstance(values, str): + values = [values] + values = ["-" if v is _DASH_REPLACEMENT else v for v in values] + items = getattr(namespace, self.dest, None) + if items is None: + items = DeferredConfigList() + else: + items = DeferredConfigList(items) + items.extend(values) + setattr(namespace, self.dest, items) + + +class _DefaultOptionDict(dict): + """Like the default options dict + + but acts as if all --Class.trait options are predefined + """ + def _add_kv_action(self, key): + self[key] = _KVAction( + option_strings=[key], + dest=key.lstrip("-").replace(".", _DOT_REPLACEMENT), + # use metavar for display purposes + metavar=key.lstrip("-"), + ) + + def __contains__(self, key): + if '=' in key: + return False + if super().__contains__(key): + return True + + if key.startswith("-") and class_trait_opt_pattern.match(key): + self._add_kv_action(key) + return True + return False + + def __getitem__(self, key): + if key in self: + return super().__getitem__(key) + else: + raise KeyError(key) + + def get(self, key, default=None): + try: + return self[key] + except KeyError: + return default + + +class _KVArgParser(argparse.ArgumentParser): + """subclass of ArgumentParser where any --Class.trait option is implicitly defined""" + def parse_known_args(self, args=None, namespace=None): + # must be done immediately prior to parsing because if we do it in init, + # registration of explicit actions via parser.add_option will fail during setup + for container in (self, self._optionals): + container._option_string_actions = _DefaultOptionDict( + container._option_string_actions) + return super().parse_known_args(args, namespace) + + +class ArgParseConfigLoader(CommandLineConfigLoader): + """A loader that uses the argparse module to load from the command line.""" + + parser_class = ArgumentParser + + def __init__(self, argv=None, aliases=None, flags=None, log=None, classes=(), + *parser_args, **parser_kw): + """Create a config loader for use with argparse. + + Parameters + ---------- + classes : optional, list + The classes to scan for *container* config-traits and decide + for their "multiplicity" when adding them as *argparse* arguments. + argv : optional, list + If given, used to read command-line arguments from, otherwise + sys.argv[1:] is used. + parser_args : tuple + A tuple of positional arguments that will be passed to the + constructor of :class:`argparse.ArgumentParser`. + parser_kw : dict + A tuple of keyword arguments that will be passed to the + constructor of :class:`argparse.ArgumentParser`. + + Returns + ------- + config : Config + The resulting Config object. + """ + super(CommandLineConfigLoader, self).__init__(log=log) + self.clear() + if argv is None: + argv = sys.argv[1:] + self.argv = argv + self.aliases = aliases or {} + self.flags = flags or {} + self.classes = classes + + self.parser_args = parser_args + self.version = parser_kw.pop("version", None) + kwargs = dict(argument_default=argparse.SUPPRESS) + kwargs.update(parser_kw) + self.parser_kw = kwargs + + def load_config(self, argv=None, aliases=None, flags=_deprecated, classes=None): + """Parse command line arguments and return as a Config object. + + Parameters + ---------- + argv : optional, list + If given, a list with the structure of sys.argv[1:] to parse + arguments from. If not given, the instance's self.argv attribute + (given at construction time) is used. + flags + Deprecated in traitlets 5.0, instanciate the config loader with the flags. + + """ + + if flags is not _deprecated: + warnings.warn( + "The `flag` argument to load_config is deprecated since Traitlets " + f"5.0 and will be ignored, pass flags the `{type(self)}` constructor.", + DeprecationWarning, + stacklevel=2, + ) + + self.clear() + if argv is None: + argv = self.argv + if aliases is not None: + self.aliases = aliases + if classes is not None: + self.classes = classes + self._create_parser() + self._parse_args(argv) + self._convert_to_config() + return self.config + + def get_extra_args(self): + if hasattr(self, 'extra_args'): + return self.extra_args + else: + return [] + + def _create_parser(self): + self.parser = self.parser_class(*self.parser_args, **self.parser_kw) + self._add_arguments(self.aliases, self.flags, self.classes) + + def _add_arguments(self, aliases, flags, classes): + raise NotImplementedError("subclasses must implement _add_arguments") + + def _parse_args(self, args): + """self.parser->self.parsed_data""" + # decode sys.argv to support unicode command-line options + enc = DEFAULT_ENCODING + uargs = [cast_unicode(a, enc) for a in args] + + unpacked_aliases = {} + if self.aliases: + unpacked_aliases = {} + for alias, alias_target in self.aliases.items(): + if alias in self.flags: + continue + if not isinstance(alias, tuple): + short_alias, alias = alias, None + else: + short_alias, alias = alias + for al in (short_alias, alias): + if al is None: + continue + if len(al) == 1: + unpacked_aliases["-" + al] = "--" + alias_target + unpacked_aliases["--" + al] = "--" + alias_target + + def _replace(arg): + if arg == "-": + return _DASH_REPLACEMENT + for k, v in unpacked_aliases.items(): + if arg == k: + return v + if arg.startswith(k + "="): + return v + "=" + arg[len(k) + 1:] + return arg + + if '--' in uargs: + idx = uargs.index('--') + extra_args = uargs[idx+1:] + to_parse = uargs[:idx] + else: + extra_args = [] + to_parse = uargs + to_parse = [_replace(a) for a in to_parse] + + self.parsed_data = self.parser.parse_args(to_parse) + self.extra_args = extra_args + + def _convert_to_config(self): + """self.parsed_data->self.config""" + for k, v in vars(self.parsed_data).items(): + *path, key = k.split(".") + section = self.config + for p in path: + section = section[p] + setattr(section, key, v) + + +class _FlagAction(argparse.Action): + """ArgParse action to handle a flag""" + def __init__(self, *args, **kwargs): + self.flag = kwargs.pop('flag') + self.alias = kwargs.pop('alias', None) + kwargs['const'] = Undefined + if not self.alias: + kwargs['nargs'] = 0 + super(_FlagAction, self).__init__(*args, **kwargs) + + def __call__(self, parser, namespace, values, option_string=None): + if self.nargs == 0 or values is Undefined: + namespace._flags.append(self.flag) + else: + setattr(namespace, self.alias, values) + + +class KVArgParseConfigLoader(ArgParseConfigLoader): + """A config loader that loads aliases and flags with argparse, + + as well as arbitrary --Class.trait value + """ + + parser_class = _KVArgParser + + def _add_arguments(self, aliases, flags, classes): + alias_flags = {} + paa = self.parser.add_argument + self.parser.set_defaults(_flags=[]) + paa("extra_args", nargs="*") + + ## An index of all container traits collected:: + # + # { : (, ) } + # + # Used to add the correct type into the `config` tree. + # Used also for aliases, not to re-collect them. + self.argparse_traits = argparse_traits = {} + for cls in classes: + for traitname, trait in cls.class_traits(config=True).items(): + argname = '%s.%s' % (cls.__name__, traitname) + argparse_kwds = {'type': str} + if isinstance(trait, (Container, Dict)): + multiplicity = trait.metadata.get('multiplicity', 'append') + if multiplicity == 'append': + argparse_kwds['action'] = multiplicity + else: + argparse_kwds['nargs'] = multiplicity + argparse_traits[argname] = (trait, argparse_kwds) + + for keys, (value, _) in flags.items(): + if not isinstance(keys, tuple): + keys = (keys,) + for key in keys: + if key in aliases: + alias_flags[aliases[key]] = value + continue + keys = ('-' + key, '--' + key) if len(key) == 1 else ('--' + key,) + paa(*keys, action=_FlagAction, flag=value) + + for keys, traitname in aliases.items(): + if not isinstance(keys, tuple): + keys = (keys,) + + for key in keys: + argparse_kwds = { + 'type': str, + 'dest': traitname.replace(".", _DOT_REPLACEMENT), + 'metavar': traitname, + } + if traitname in argparse_traits: + argparse_kwds.update(argparse_traits[traitname][1]) + if 'action' in argparse_kwds and traitname in alias_flags: + # flag sets 'action', so can't have flag & alias with custom action + # on the same name + raise ArgumentError( + "The alias `%s` for the 'append' sequence " + "config-trait `%s` cannot be also a flag!'" + % (key, traitname)) + if traitname in alias_flags: + # alias and flag. + # when called with 0 args: flag + # when called with >= 1: alias + argparse_kwds.setdefault('nargs', '?') + argparse_kwds['action'] = _FlagAction + argparse_kwds['flag'] = alias_flags[traitname] + argparse_kwds['alias'] = traitname + keys = ('-' + key, '--' + key) if len(key) == 1 else ('--'+ key,) + paa(*keys, **argparse_kwds) + + def _convert_to_config(self): + """self.parsed_data->self.config, parse unrecognized extra args via KVLoader.""" + extra_args = self.extra_args + + for lhs, rhs in vars(self.parsed_data).items(): + if lhs == "extra_args": + self.extra_args = ["-" if a == _DASH_REPLACEMENT else a for a in rhs] + extra_args + continue + elif lhs == '_flags': + # _flags will be handled later + continue + + lhs = lhs.replace(_DOT_REPLACEMENT, ".") + if '.' not in lhs: + # probably a mistyped alias, but not technically illegal + self.log.warning("Unrecognized alias: '%s', it will have no effect.", lhs) + trait = None + + if isinstance(rhs, list): + rhs = DeferredConfigList(rhs) + elif isinstance(rhs, str): + rhs = DeferredConfigString(rhs) + + trait = self.argparse_traits.get(lhs) + if trait: + trait = trait[0] + + # eval the KV assignment + try: + self._exec_config_str(lhs, rhs, trait) + except Exception as e: + # cast deferred to nicer repr for the error + # DeferredList->list, etc + if isinstance(rhs, DeferredConfig): + rhs = rhs._super_repr() + raise ArgumentError(f"Error loading argument {lhs}={rhs}, {e}") + + for subc in self.parsed_data._flags: + self._load_flag(subc) + + +class KeyValueConfigLoader(KVArgParseConfigLoader): + """Deprecated in traitlets 5.0 + + Use KVArgParseConfigLoader + """ + def __init__(self, *args, **kwargs): + warnings.warn( + "KeyValueConfigLoader is deprecated since Traitlets 5.0." + " Use KVArgParseConfigLoader instead.", + DeprecationWarning, + stacklevel=2, + ) + super().__init__(*args, **kwargs) + + +def load_pyconfig_files(config_files, path): + """Load multiple Python config files, merging each of them in turn. + + Parameters + ---------- + config_files : list of str + List of config files names to load and merge into the config. + path : unicode + The full path to the location of the config files. + """ + config = Config() + for cf in config_files: + loader = PyFileConfigLoader(cf, path=path) + try: + next_config = loader.load_config() + except ConfigFileNotFound: + pass + except: + raise + else: + config.merge(next_config) + return config diff --git a/.venv/lib/python3.8/site-packages/traitlets/config/manager.py b/.venv/lib/python3.8/site-packages/traitlets/config/manager.py new file mode 100644 index 00000000..16405326 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/traitlets/config/manager.py @@ -0,0 +1,84 @@ +"""Manager to read and modify config data in JSON files. +""" +# Copyright (c) IPython Development Team. +# Distributed under the terms of the Modified BSD License. +import errno +import io +import json +import os + +from traitlets.config import LoggingConfigurable +from traitlets.traitlets import Unicode + + +def recursive_update(target, new): + """Recursively update one dictionary using another. + + None values will delete their keys. + """ + for k, v in new.items(): + if isinstance(v, dict): + if k not in target: + target[k] = {} + recursive_update(target[k], v) + if not target[k]: + # Prune empty subdicts + del target[k] + + elif v is None: + target.pop(k, None) + + else: + target[k] = v + + +class BaseJSONConfigManager(LoggingConfigurable): + """General JSON config manager + + Deals with persisting/storing config in a json file + """ + + config_dir = Unicode('.') + + def ensure_config_dir_exists(self): + try: + os.makedirs(self.config_dir, 0o755) + except OSError as e: + if e.errno != errno.EEXIST: + raise + + def file_name(self, section_name): + return os.path.join(self.config_dir, section_name+'.json') + + def get(self, section_name): + """Retrieve the config data for the specified section. + + Returns the data as a dictionary, or an empty dictionary if the file + doesn't exist. + """ + filename = self.file_name(section_name) + if os.path.isfile(filename): + with io.open(filename, encoding='utf-8') as f: + return json.load(f) + else: + return {} + + def set(self, section_name, data): + """Store the given config data. + """ + filename = self.file_name(section_name) + self.ensure_config_dir_exists() + + f = open(filename, 'w', encoding='utf-8') + with f: + json.dump(data, f, indent=2) + + def update(self, section_name, new_data): + """Modify the config section by recursively updating it with new_data. + + Returns the modified config data as a dictionary. + """ + data = self.get(section_name) + recursive_update(data, new_data) + self.set(section_name, data) + return data diff --git a/.venv/lib/python3.8/site-packages/traitlets/config/sphinxdoc.py b/.venv/lib/python3.8/site-packages/traitlets/config/sphinxdoc.py new file mode 100644 index 00000000..14155800 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/traitlets/config/sphinxdoc.py @@ -0,0 +1,158 @@ +"""Machinery for documenting traitlets config options with Sphinx. + +This includes: + +- A Sphinx extension defining directives and roles for config options. +- A function to generate an rst file given an Application instance. + +To make this documentation, first set this module as an extension in Sphinx's +conf.py:: + + extensions = [ + # ... + 'traitlets.config.sphinxdoc', + ] + +Autogenerate the config documentation by running code like this before +Sphinx builds:: + + from traitlets.config.sphinxdoc import write_doc + from myapp import MyApplication + + writedoc('config/options.rst', # File to write + 'MyApp config options', # Title + MyApplication() + ) + +The generated rST syntax looks like this:: + + .. configtrait:: Application.log_datefmt + + Description goes here. + + Cross reference like this: :configtrait:`Application.log_datefmt`. +""" +from traitlets import Undefined +from collections import defaultdict + +from ipython_genutils.text import indent, dedent + +def setup(app): + """Registers the Sphinx extension. + + You shouldn't need to call this directly; configure Sphinx to use this + module instead. + """ + app.add_object_type('configtrait', 'configtrait', objname='Config option') + metadata = {'parallel_read_safe': True, 'parallel_write_safe': True} + return metadata + +def interesting_default_value(dv): + if (dv is None) or (dv is Undefined): + return False + if isinstance(dv, (str, list, tuple, dict, set)): + return bool(dv) + return True + +def format_aliases(aliases): + fmted = [] + for a in aliases: + dashes = '-' if len(a) == 1 else '--' + fmted.append('``%s%s``' % (dashes, a)) + return ', '.join(fmted) + +def class_config_rst_doc(cls, trait_aliases): + """Generate rST documentation for this class' config options. + + Excludes traits defined on parent classes. + """ + lines = [] + classname = cls.__name__ + for k, trait in sorted(cls.class_traits(config=True).items()): + ttype = trait.__class__.__name__ + + fullname = classname + '.' + trait.name + lines += ['.. configtrait:: ' + fullname, + '' + ] + + help = trait.help.rstrip() or 'No description' + lines.append(indent(dedent(help), 4) + '\n') + + # Choices or type + if 'Enum' in ttype: + # include Enum choices + lines.append(indent( + ':options: ' + ', '.join('``%r``' % x for x in trait.values), 4)) + else: + lines.append(indent(':trait type: ' + ttype, 4)) + + # Default value + # Ignore boring default values like None, [] or '' + if interesting_default_value(trait.default_value): + try: + dvr = trait.default_value_repr() + except Exception: + dvr = None # ignore defaults we can't construct + if dvr is not None: + if len(dvr) > 64: + dvr = dvr[:61] + '...' + # Double up backslashes, so they get to the rendered docs + dvr = dvr.replace('\\n', '\\\\n') + lines.append(indent(':default: ``%s``' % dvr, 4)) + + # Command line aliases + if trait_aliases[fullname]: + fmt_aliases = format_aliases(trait_aliases[fullname]) + lines.append(indent(':CLI option: ' + fmt_aliases, 4)) + + # Blank line + lines.append('') + + return '\n'.join(lines) + +def reverse_aliases(app): + """Produce a mapping of trait names to lists of command line aliases. + """ + res = defaultdict(list) + for alias, trait in app.aliases.items(): + res[trait].append(alias) + + # Flags also often act as aliases for a boolean trait. + # Treat flags which set one trait to True as aliases. + for flag, (cfg, _) in app.flags.items(): + if len(cfg) == 1: + classname = list(cfg)[0] + cls_cfg = cfg[classname] + if len(cls_cfg) == 1: + traitname = list(cls_cfg)[0] + if cls_cfg[traitname] is True: + res[classname+'.'+traitname].append(flag) + + return res + +def write_doc(path, title, app, preamble=None): + """Write a rst file documenting config options for a traitlets application. + + Parameters + ---------- + path : str + The file to be written + title : str + The human-readable title of the document + app : traitlets.config.Application + An instance of the application class to be documented + preamble : str + Extra text to add just after the title (optional) + """ + trait_aliases = reverse_aliases(app) + with open(path, 'w') as f: + f.write(title + '\n') + f.write(('=' * len(title)) + '\n') + f.write('\n') + if preamble is not None: + f.write(preamble + '\n\n') + + for c in app._classes_inc_parents(): + f.write(class_config_rst_doc(c, trait_aliases)) + f.write('\n') diff --git a/.venv/lib/python3.8/site-packages/traitlets/config/tests/__init__.py b/.venv/lib/python3.8/site-packages/traitlets/config/tests/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/.venv/lib/python3.8/site-packages/traitlets/config/tests/__pycache__/__init__.cpython-38.pyc b/.venv/lib/python3.8/site-packages/traitlets/config/tests/__pycache__/__init__.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9dc7dd8b8cd3fbf7c65c60a6d2362e3dd2bb4f75 GIT binary patch literal 158 zcmWIL<>g`kf`9eb;z9Id5P=LBfgA@QE@lA|DGb33nv8xc8Hzx{2;!Hseo1bDenDn| zZfRaYVsdtBif(yEYHE&diE)y7RY`e;eo0YcW=T$JNwI!%eqLH;x_(J&F_04RVR-C literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/traitlets/config/tests/__pycache__/test_application.cpython-38.pyc b/.venv/lib/python3.8/site-packages/traitlets/config/tests/__pycache__/test_application.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f050cea9919980e07b385db3d3c902242cbf3929 GIT binary patch literal 24025 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 z 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 bY!2pNdp18?hAlG-3umq{4Ljy-CG-CR$MCl` literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/traitlets/config/tests/__pycache__/test_configurable.cpython-38.pyc b/.venv/lib/python3.8/site-packages/traitlets/config/tests/__pycache__/test_configurable.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..554d8aba8d82459645761cf4864434e5d8ca0581 GIT binary patch literal 22311 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 literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/traitlets/config/tests/test_application.py b/.venv/lib/python3.8/site-packages/traitlets/config/tests/test_application.py new file mode 100644 index 00000000..ceebbba2 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/traitlets/config/tests/test_application.py @@ -0,0 +1,764 @@ +# coding: utf-8 +""" +Tests for traitlets.config.application.Application +""" + +# Copyright (c) IPython Development Team. +# Distributed under the terms of the Modified BSD License. + +import contextlib +import io +import json +import logging +import os +import sys +from io import StringIO +from tempfile import TemporaryDirectory +from unittest import TestCase + +import pytest +from pytest import mark + +from traitlets import ( + Bool, + Bytes, + Dict, + HasTraits, + Integer, + List, + Set, + Tuple, + Unicode, +) +from traitlets.config.application import Application +from traitlets.config.configurable import Configurable +from traitlets.config.loader import Config +from traitlets.tests.utils import ( + check_help_all_output, + check_help_output, + get_output_error_code, +) + +try: + from unittest import mock +except ImportError: + import mock + +pjoin = os.path.join + + +class Foo(Configurable): + + i = Integer(0, help=""" + The integer i. + + Details about i. + """).tag(config=True) + j = Integer(1, help="The integer j.").tag(config=True) + name = Unicode('Brian', help="First name.").tag(config=True) + la = List([]).tag(config=True) + li = List(Integer()).tag(config=True) + fdict = Dict().tag(config=True, multiplicity='+') + + +class Bar(Configurable): + + b = Integer(0, help="The integer b.").tag(config=True) + enabled = Bool(True, help="Enable bar.").tag(config=True) + tb = Tuple(()).tag(config=True, multiplicity='*') + aset = Set().tag(config=True, multiplicity='+') + bdict = Dict().tag(config=True) + idict = Dict(value_trait=Integer()).tag(config=True) + key_dict = Dict(per_key_traits={'i': Integer(), 'b': Bytes()}).tag(config=True) + + +class MyApp(Application): + + name = Unicode('myapp') + running = Bool(False, help="Is the app running?").tag(config=True) + classes = List([Bar, Foo]) + config_file = Unicode('', help="Load this config file").tag(config=True) + + warn_tpyo = Unicode("yes the name is wrong on purpose", config=True, + help="Should print a warning if `MyApp.warn-typo=...` command is passed") + + aliases = {} + aliases.update(Application.aliases) + aliases.update({ + ('fooi', 'i') : 'Foo.i', + ('j', 'fooj') : ('Foo.j', "`j` terse help msg"), + 'name' : 'Foo.name', + 'la': 'Foo.la', + 'li': 'Foo.li', + 'tb': 'Bar.tb', + 'D': 'Bar.bdict', + 'enabled' : 'Bar.enabled', + 'enable' : 'Bar.enabled', + 'log-level' : 'Application.log_level', + }) + + flags = {} + flags.update(Application.flags) + flags.update({('enable', 'e'): + ({'Bar': {'enabled' : True}}, + "Set Bar.enabled to True"), + ('d', 'disable'): + ({'Bar': {'enabled' : False}}, + "Set Bar.enabled to False"), + 'crit': + ({'Application' : {'log_level' : logging.CRITICAL}}, + "set level=CRITICAL"), + }) + + def init_foo(self): + self.foo = Foo(parent=self) + + def init_bar(self): + self.bar = Bar(parent=self) + + +def class_to_names(classes): + return [klass.__name__ for klass in classes] + + +class TestApplication(TestCase): + def test_log(self): + stream = StringIO() + app = MyApp(log_level=logging.INFO) + handler = logging.StreamHandler(stream) + # trigger reconstruction of the log formatter + app.log.handlers = [handler] + app.log_format = "%(message)s" + app.log_datefmt = "%Y-%m-%d %H:%M" + app.log.info("hello") + assert "hello" in stream.getvalue() + + def test_no_eval_cli_text(self): + app = MyApp() + app.initialize(['--Foo.name=1']) + app.init_foo() + assert app.foo.name == '1' + + def test_basic(self): + app = MyApp() + self.assertEqual(app.name, 'myapp') + self.assertEqual(app.running, False) + self.assertEqual(app.classes, [MyApp, Bar, Foo]) + self.assertEqual(app.config_file, '') + + def test_mro_discovery(self): + app = MyApp() + + self.assertSequenceEqual(class_to_names(app._classes_with_config_traits()), + ['Application', 'MyApp', 'Bar', 'Foo']) + self.assertSequenceEqual(class_to_names(app._classes_inc_parents()), + ['Configurable', 'LoggingConfigurable', 'SingletonConfigurable', + 'Application', 'MyApp', 'Bar', 'Foo']) + + self.assertSequenceEqual(class_to_names(app._classes_with_config_traits([Application])), + ['Application']) + self.assertSequenceEqual(class_to_names(app._classes_inc_parents([Application])), + ['Configurable', 'LoggingConfigurable', 'SingletonConfigurable', + 'Application']) + + self.assertSequenceEqual(class_to_names(app._classes_with_config_traits([Foo])), + ['Foo']) + self.assertSequenceEqual(class_to_names(app._classes_inc_parents([Bar])), + ['Configurable', 'Bar']) + + class MyApp2(Application): # no defined `classes` attr + pass + + self.assertSequenceEqual(class_to_names(app._classes_with_config_traits([Foo])), + ['Foo']) + self.assertSequenceEqual(class_to_names(app._classes_inc_parents([Bar])), + ['Configurable', 'Bar']) + + + def test_config(self): + app = MyApp() + app.parse_command_line([ + "--i=10", + "--Foo.j=10", + "--enable=False", + "--log-level=50", + ]) + config = app.config + print(config) + self.assertEqual(config.Foo.i, 10) + self.assertEqual(config.Foo.j, 10) + self.assertEqual(config.Bar.enabled, False) + self.assertEqual(config.MyApp.log_level, 50) + + def test_config_seq_args(self): + app = MyApp() + app.parse_command_line("--li 1 --li 3 --la 1 --tb AB 2 --Foo.la=ab --Bar.aset S1 --Bar.aset S2 --Bar.aset S1".split()) + assert app.extra_args == ["2"] + config = app.config + assert config.Foo.li == [1, 3] + assert config.Foo.la == ["1", "ab"] + assert config.Bar.tb == ("AB",) + self.assertEqual(config.Bar.aset, {"S1", "S2"}) + app.init_foo() + assert app.foo.li == [1, 3] + assert app.foo.la == ['1', 'ab'] + app.init_bar() + self.assertEqual(app.bar.aset, {'S1', 'S2'}) + assert app.bar.tb == ('AB',) + + def test_config_dict_args(self): + app = MyApp() + app.parse_command_line( + "--Foo.fdict a=1 --Foo.fdict b=b --Foo.fdict c=3 " + "--Bar.bdict k=1 -D=a=b -D 22=33 " + "--Bar.idict k=1 --Bar.idict b=2 --Bar.idict c=3 " + .split()) + fdict = {'a': '1', 'b': 'b', 'c': '3'} + bdict = {'k': '1', 'a': 'b', '22': '33'} + idict = {'k': 1, 'b': 2, 'c': 3} + config = app.config + assert config.Bar.idict == idict + self.assertDictEqual(config.Foo.fdict, fdict) + self.assertDictEqual(config.Bar.bdict, bdict) + app.init_foo() + self.assertEqual(app.foo.fdict, fdict) + app.init_bar() + assert app.bar.idict == idict + self.assertEqual(app.bar.bdict, bdict) + + def test_config_propagation(self): + app = MyApp() + app.parse_command_line(["--i=10","--Foo.j=10","--enable=False","--log-level=50"]) + app.init_foo() + app.init_bar() + self.assertEqual(app.foo.i, 10) + self.assertEqual(app.foo.j, 10) + self.assertEqual(app.bar.enabled, False) + + def test_cli_priority(self): + """Test that loading config files does not override CLI options""" + name = 'config.py' + class TestApp(Application): + value = Unicode().tag(config=True) + config_file_loaded = Bool().tag(config=True) + aliases = {'v': 'TestApp.value'} + app = TestApp() + with TemporaryDirectory() as td: + config_file = pjoin(td, name) + with open(config_file, 'w') as f: + f.writelines([ + "c.TestApp.value = 'config file'\n", + "c.TestApp.config_file_loaded = True\n" + ]) + + app.parse_command_line(['--v=cli']) + assert 'value' in app.config.TestApp + assert app.config.TestApp.value == 'cli' + assert app.value == 'cli' + + app.load_config_file(name, path=[td]) + assert app.config_file_loaded + assert app.config.TestApp.value == 'cli' + assert app.value == 'cli' + + def test_ipython_cli_priority(self): + # this test is almost entirely redundant with above, + # but we can keep it around in case of subtle issues creeping into + # the exact sequence IPython follows. + name = 'config.py' + class TestApp(Application): + value = Unicode().tag(config=True) + config_file_loaded = Bool().tag(config=True) + aliases = {'v': ('TestApp.value', 'some help')} + app = TestApp() + with TemporaryDirectory() as td: + config_file = pjoin(td, name) + with open(config_file, 'w') as f: + f.writelines([ + "c.TestApp.value = 'config file'\n", + "c.TestApp.config_file_loaded = True\n" + ]) + # follow IPython's config-loading sequence to ensure CLI priority is preserved + app.parse_command_line(['--v=cli']) + # this is where IPython makes a mistake: + # it assumes app.config will not be modified, + # and storing a reference is storing a copy + cli_config = app.config + assert 'value' in app.config.TestApp + assert app.config.TestApp.value == 'cli' + assert app.value == 'cli' + app.load_config_file(name, path=[td]) + assert app.config_file_loaded + # enforce cl-opts override config file opts: + # this is where IPython makes a mistake: it assumes + # that cl_config is a different object, but it isn't. + app.update_config(cli_config) + assert app.config.TestApp.value == 'cli' + assert app.value == 'cli' + + def test_cli_allow_none(self): + class App(Application): + aliases = {"opt": "App.opt"} + opt = Unicode(allow_none=True, config=True) + + app = App() + app.parse_command_line(["--opt=None"]) + assert app.opt is None + + def test_flags(self): + app = MyApp() + app.parse_command_line(["--disable"]) + app.init_bar() + self.assertEqual(app.bar.enabled, False) + + app = MyApp() + app.parse_command_line(["-d"]) + app.init_bar() + self.assertEqual(app.bar.enabled, False) + + app = MyApp() + app.parse_command_line(["--enable"]) + app.init_bar() + self.assertEqual(app.bar.enabled, True) + + app = MyApp() + app.parse_command_line(["-e"]) + app.init_bar() + self.assertEqual(app.bar.enabled, True) + + def test_flags_help_msg(self): + app = MyApp() + stdout = io.StringIO() + with contextlib.redirect_stdout(stdout): + app.print_flag_help() + hmsg = stdout.getvalue() + self.assertRegex(hmsg, "(? 0 + + +if __name__ == '__main__': + # for test_help_output: + MyApp.launch_instance() diff --git a/.venv/lib/python3.8/site-packages/traitlets/config/tests/test_configurable.py b/.venv/lib/python3.8/site-packages/traitlets/config/tests/test_configurable.py new file mode 100644 index 00000000..da0d16d8 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/traitlets/config/tests/test_configurable.py @@ -0,0 +1,680 @@ +"""Tests for traitlets.config.configurable""" + +# Copyright (c) IPython Development Team. +# Distributed under the terms of the Modified BSD License. + +import logging +from unittest import TestCase + +from pytest import mark + +from traitlets.config.application import Application +from traitlets.config.configurable import ( + Configurable, + LoggingConfigurable, + SingletonConfigurable, +) +from traitlets.log import get_logger +from traitlets.traitlets import ( + Integer, Float, Unicode, List, Dict, Set, Enum, FuzzyEnum, + CaselessStrEnum, _deprecations_shown, validate, +) + +from traitlets.config.loader import Config + +from ...tests._warnings import expected_warnings + +class MyConfigurable(Configurable): + a = Integer(1, help="The integer a.").tag(config=True) + b = Float(1.0, help="The integer b.").tag(config=True) + c = Unicode('no config') + + +mc_help = """MyConfigurable(Configurable) options +------------------------------------ +--MyConfigurable.a= + The integer a. + Default: 1 +--MyConfigurable.b= + The integer b. + Default: 1.0""" + +mc_help_inst="""MyConfigurable(Configurable) options +------------------------------------ +--MyConfigurable.a= + The integer a. + Current: 5 +--MyConfigurable.b= + The integer b. + Current: 4.0""" + +# On Python 3, the Integer trait is a synonym for Int +mc_help = mc_help.replace("", "") +mc_help_inst = mc_help_inst.replace("", "") + +class Foo(Configurable): + a = Integer(0, help="The integer a.").tag(config=True) + b = Unicode('nope').tag(config=True) + flist = List([]).tag(config=True) + fdict = Dict().tag(config=True) + + +class Bar(Foo): + b = Unicode('gotit', help="The string b.").tag(config=False) + c = Float(help="The string c.").tag(config=True) + bset = Set([]).tag(config=True, multiplicity='+') + bset_values = Set([2,1,5]).tag(config=True, multiplicity='+') + bdict = Dict().tag(config=True, multiplicity='+') + bdict_values = Dict({1:'a','0':'b',5:'c'}).tag(config=True, multiplicity='+') + +foo_help="""Foo(Configurable) options +------------------------- +--Foo.a= + The integer a. + Default: 0 +--Foo.b= + Default: 'nope' +--Foo.fdict==... + Default: {} +--Foo.flist=... + Default: []""" + +bar_help="""Bar(Foo) options +---------------- +--Bar.a= + The integer a. + Default: 0 +--Bar.bdict =... + Default: {} +--Bar.bdict_values =... + Default: {1: 'a', '0': 'b', 5: 'c'} +--Bar.bset ... + Default: set() +--Bar.bset_values ... + Default: {1, 2, 5} +--Bar.c= + The string c. + Default: 0.0 +--Bar.fdict==... + Default: {} +--Bar.flist=... + Default: []""" + + +class TestConfigurable(TestCase): + + def test_default(self): + c1 = Configurable() + c2 = Configurable(config=c1.config) + c3 = Configurable(config=c2.config) + self.assertEqual(c1.config, c2.config) + self.assertEqual(c2.config, c3.config) + + def test_custom(self): + config = Config() + config.foo = 'foo' + config.bar = 'bar' + c1 = Configurable(config=config) + c2 = Configurable(config=c1.config) + c3 = Configurable(config=c2.config) + self.assertEqual(c1.config, config) + self.assertEqual(c2.config, config) + self.assertEqual(c3.config, config) + # Test that copies are not made + self.assertTrue(c1.config is config) + self.assertTrue(c2.config is config) + self.assertTrue(c3.config is config) + self.assertTrue(c1.config is c2.config) + self.assertTrue(c2.config is c3.config) + + def test_inheritance(self): + config = Config() + config.MyConfigurable.a = 2 + config.MyConfigurable.b = 2.0 + c1 = MyConfigurable(config=config) + c2 = MyConfigurable(config=c1.config) + self.assertEqual(c1.a, config.MyConfigurable.a) + self.assertEqual(c1.b, config.MyConfigurable.b) + self.assertEqual(c2.a, config.MyConfigurable.a) + self.assertEqual(c2.b, config.MyConfigurable.b) + + def test_parent(self): + config = Config() + config.Foo.a = 10 + config.Foo.b = "wow" + config.Bar.b = 'later' + config.Bar.c = 100.0 + f = Foo(config=config) + with expected_warnings(['`b` not recognized']): + b = Bar(config=f.config) + self.assertEqual(f.a, 10) + self.assertEqual(f.b, 'wow') + self.assertEqual(b.b, 'gotit') + self.assertEqual(b.c, 100.0) + + def test_override1(self): + config = Config() + config.MyConfigurable.a = 2 + config.MyConfigurable.b = 2.0 + c = MyConfigurable(a=3, config=config) + self.assertEqual(c.a, 3) + self.assertEqual(c.b, config.MyConfigurable.b) + self.assertEqual(c.c, 'no config') + + def test_override2(self): + config = Config() + config.Foo.a = 1 + config.Bar.b = 'or' # Up above b is config=False, so this won't do it. + config.Bar.c = 10.0 + with expected_warnings(['`b` not recognized']): + c = Bar(config=config) + self.assertEqual(c.a, config.Foo.a) + self.assertEqual(c.b, 'gotit') + self.assertEqual(c.c, config.Bar.c) + with expected_warnings(['`b` not recognized']): + c = Bar(a=2, b='and', c=20.0, config=config) + self.assertEqual(c.a, 2) + self.assertEqual(c.b, 'and') + self.assertEqual(c.c, 20.0) + + def test_help(self): + self.assertEqual(MyConfigurable.class_get_help(), mc_help) + self.assertEqual(Foo.class_get_help(), foo_help) + self.assertEqual(Bar.class_get_help(), bar_help) + + def test_help_inst(self): + inst = MyConfigurable(a=5, b=4) + self.assertEqual(MyConfigurable.class_get_help(inst), mc_help_inst) + + def test_generated_config_enum_comments(self): + class MyConf(Configurable): + an_enum = Enum('Choice1 choice2'.split(), + help="Many choices.").tag(config=True) + + help_str = "Many choices." + enum_choices_str = "Choices: any of ['Choice1', 'choice2']" + rst_choices_str = "MyConf.an_enum : any of ``'Choice1'``|``'choice2'``" + or_none_str = "or None" + + cls_help = MyConf.class_get_help() + + self.assertIn(help_str, cls_help) + self.assertIn(enum_choices_str, cls_help) + self.assertNotIn(or_none_str, cls_help) + + cls_cfg = MyConf.class_config_section() + + self.assertIn(help_str, cls_cfg) + self.assertIn(enum_choices_str, cls_cfg) + self.assertNotIn(or_none_str, cls_help) + ## Check order of Help-msg <--> Choices sections + self.assertGreater(cls_cfg.index(enum_choices_str), + cls_cfg.index(help_str)) + + rst_help = MyConf.class_config_rst_doc() + + self.assertIn(help_str, rst_help) + self.assertIn(rst_choices_str, rst_help) + self.assertNotIn(or_none_str, rst_help) + + class MyConf2(Configurable): + an_enum = Enum('Choice1 choice2'.split(), + allow_none=True, + default_value='choice2', + help="Many choices.").tag(config=True) + + defaults_str = "Default: 'choice2'" + + cls2_msg = MyConf2.class_get_help() + + self.assertIn(help_str, cls2_msg) + self.assertIn(enum_choices_str, cls2_msg) + self.assertIn(or_none_str, cls2_msg) + self.assertIn(defaults_str, cls2_msg) + ## Check order of Default <--> Choices sections + self.assertGreater(cls2_msg.index(defaults_str), + cls2_msg.index(enum_choices_str)) + + cls2_cfg = MyConf2.class_config_section() + + self.assertIn(help_str, cls2_cfg) + self.assertIn(enum_choices_str, cls2_cfg) + self.assertIn(or_none_str, cls2_cfg) + self.assertIn(defaults_str, cls2_cfg) + ## Check order of Default <--> Choices sections + self.assertGreater(cls2_cfg.index(defaults_str), + cls2_cfg.index(enum_choices_str)) + + def test_generated_config_strenum_comments(self): + help_str = "Many choices." + defaults_str = "Default: 'choice2'" + or_none_str = "or None" + + class MyConf3(Configurable): + an_enum = CaselessStrEnum('Choice1 choice2'.split(), + allow_none=True, + default_value='choice2', + help="Many choices.").tag(config=True) + + enum_choices_str = ("Choices: any of ['Choice1', 'choice2'] " + "(case-insensitive)") + + cls3_msg = MyConf3.class_get_help() + + self.assertIn(help_str, cls3_msg) + self.assertIn(enum_choices_str, cls3_msg) + self.assertIn(or_none_str, cls3_msg) + self.assertIn(defaults_str, cls3_msg) + ## Check order of Default <--> Choices sections + self.assertGreater(cls3_msg.index(defaults_str), + cls3_msg.index(enum_choices_str)) + + cls3_cfg = MyConf3.class_config_section() + + self.assertIn(help_str, cls3_cfg) + self.assertIn(enum_choices_str, cls3_cfg) + self.assertIn(or_none_str, cls3_cfg) + self.assertIn(defaults_str, cls3_cfg) + ## Check order of Default <--> Choices sections + self.assertGreater(cls3_cfg.index(defaults_str), + cls3_cfg.index(enum_choices_str)) + + class MyConf4(Configurable): + an_enum = FuzzyEnum('Choice1 choice2'.split(), + allow_none=True, + default_value='choice2', + help="Many choices.").tag(config=True) + + enum_choices_str = ("Choices: any case-insensitive prefix " + "of ['Choice1', 'choice2']") + + cls4_msg = MyConf4.class_get_help() + + self.assertIn(help_str, cls4_msg) + self.assertIn(enum_choices_str, cls4_msg) + self.assertIn(or_none_str, cls4_msg) + self.assertIn(defaults_str, cls4_msg) + ## Check order of Default <--> Choices sections + self.assertGreater(cls4_msg.index(defaults_str), + cls4_msg.index(enum_choices_str)) + + cls4_cfg = MyConf4.class_config_section() + + self.assertIn(help_str, cls4_cfg) + self.assertIn(enum_choices_str, cls4_cfg) + self.assertIn(or_none_str, cls4_cfg) + self.assertIn(defaults_str, cls4_cfg) + ## Check order of Default <--> Choices sections + self.assertGreater(cls4_cfg.index(defaults_str), + cls4_cfg.index(enum_choices_str)) + + + +class TestSingletonConfigurable(TestCase): + + def test_instance(self): + class Foo(SingletonConfigurable): pass + self.assertEqual(Foo.initialized(), False) + foo = Foo.instance() + self.assertEqual(Foo.initialized(), True) + self.assertEqual(foo, Foo.instance()) + self.assertEqual(SingletonConfigurable._instance, None) + + def test_inheritance(self): + class Bar(SingletonConfigurable): pass + class Bam(Bar): pass + self.assertEqual(Bar.initialized(), False) + self.assertEqual(Bam.initialized(), False) + bam = Bam.instance() + self.assertEqual(Bar.initialized(), True) + self.assertEqual(Bam.initialized(), True) + self.assertEqual(bam, Bam._instance) + self.assertEqual(bam, Bar._instance) + self.assertEqual(SingletonConfigurable._instance, None) + + +class TestLoggingConfigurable(TestCase): + + def test_parent_logger(self): + class Parent(LoggingConfigurable): pass + class Child(LoggingConfigurable): pass + log = get_logger().getChild("TestLoggingConfigurable") + + parent = Parent(log=log) + child = Child(parent=parent) + self.assertEqual(parent.log, log) + self.assertEqual(child.log, log) + + parent = Parent() + child = Child(parent=parent, log=log) + self.assertEqual(parent.log, get_logger()) + self.assertEqual(child.log, log) + + def test_parent_not_logging_configurable(self): + class Parent(Configurable): pass + class Child(LoggingConfigurable): pass + parent = Parent() + child = Child(parent=parent) + self.assertEqual(child.log, get_logger()) + + +class MyParent(Configurable): + pass + +class MyParent2(MyParent): + pass + +class TestParentConfigurable(TestCase): + + def test_parent_config(self): + cfg = Config({ + 'MyParent' : { + 'MyConfigurable' : { + 'b' : 2.0, + } + } + }) + parent = MyParent(config=cfg) + myc = MyConfigurable(parent=parent) + self.assertEqual(myc.b, parent.config.MyParent.MyConfigurable.b) + + def test_parent_inheritance(self): + cfg = Config({ + 'MyParent' : { + 'MyConfigurable' : { + 'b' : 2.0, + } + } + }) + parent = MyParent2(config=cfg) + myc = MyConfigurable(parent=parent) + self.assertEqual(myc.b, parent.config.MyParent.MyConfigurable.b) + + def test_multi_parent(self): + cfg = Config({ + 'MyParent2' : { + 'MyParent' : { + 'MyConfigurable' : { + 'b' : 2.0, + } + }, + # this one shouldn't count + 'MyConfigurable' : { + 'b' : 3.0, + }, + } + }) + parent2 = MyParent2(config=cfg) + parent = MyParent(parent=parent2) + myc = MyConfigurable(parent=parent) + self.assertEqual(myc.b, parent.config.MyParent2.MyParent.MyConfigurable.b) + + def test_parent_priority(self): + cfg = Config({ + 'MyConfigurable' : { + 'b' : 2.0, + }, + 'MyParent' : { + 'MyConfigurable' : { + 'b' : 3.0, + } + }, + 'MyParent2' : { + 'MyConfigurable' : { + 'b' : 4.0, + } + } + }) + parent = MyParent2(config=cfg) + myc = MyConfigurable(parent=parent) + self.assertEqual(myc.b, parent.config.MyParent2.MyConfigurable.b) + + def test_multi_parent_priority(self): + cfg = Config({ + 'MyConfigurable': { + 'b': 2.0, + }, + 'MyParent': { + 'MyConfigurable': { + 'b': 3.0, + }, + }, + 'MyParent2': { + 'MyConfigurable': { + 'b': 4.0, + }, + 'MyParent': { + 'MyConfigurable': { + 'b': 5.0, + }, + }, + }, + }) + parent2 = MyParent2(config=cfg) + parent = MyParent2(parent=parent2) + myc = MyConfigurable(parent=parent) + self.assertEqual(myc.b, parent.config.MyParent2.MyParent.MyConfigurable.b) + +class Containers(Configurable): + lis = List().tag(config=True) + def _lis_default(self): + return [-1] + + s = Set().tag(config=True) + def _s_default(self): + return {'a'} + + d = Dict().tag(config=True) + def _d_default(self): + return {'a' : 'b'} + +class TestConfigContainers(TestCase): + def test_extend(self): + c = Config() + c.Containers.lis.extend(list(range(5))) + obj = Containers(config=c) + self.assertEqual(obj.lis, list(range(-1,5))) + + def test_insert(self): + c = Config() + c.Containers.lis.insert(0, 'a') + c.Containers.lis.insert(1, 'b') + obj = Containers(config=c) + self.assertEqual(obj.lis, ['a', 'b', -1]) + + def test_prepend(self): + c = Config() + c.Containers.lis.prepend([1,2]) + c.Containers.lis.prepend([2,3]) + obj = Containers(config=c) + self.assertEqual(obj.lis, [2,3,1,2,-1]) + + def test_prepend_extend(self): + c = Config() + c.Containers.lis.prepend([1,2]) + c.Containers.lis.extend([2,3]) + obj = Containers(config=c) + self.assertEqual(obj.lis, [1,2,-1,2,3]) + + def test_append_extend(self): + c = Config() + c.Containers.lis.append([1,2]) + c.Containers.lis.extend([2,3]) + obj = Containers(config=c) + self.assertEqual(obj.lis, [-1,[1,2],2,3]) + + def test_extend_append(self): + c = Config() + c.Containers.lis.extend([2,3]) + c.Containers.lis.append([1,2]) + obj = Containers(config=c) + self.assertEqual(obj.lis, [-1,2,3,[1,2]]) + + def test_insert_extend(self): + c = Config() + c.Containers.lis.insert(0, 1) + c.Containers.lis.extend([2,3]) + obj = Containers(config=c) + self.assertEqual(obj.lis, [1,-1,2,3]) + + def test_set_update(self): + c = Config() + c.Containers.s.update({0,1,2}) + c.Containers.s.update({3}) + obj = Containers(config=c) + self.assertEqual(obj.s, {'a', 0, 1, 2, 3}) + + def test_dict_update(self): + c = Config() + c.Containers.d.update({'c' : 'd'}) + c.Containers.d.update({'e' : 'f'}) + obj = Containers(config=c) + self.assertEqual(obj.d, {'a':'b', 'c':'d', 'e':'f'}) + + def test_update_twice(self): + c = Config() + c.MyConfigurable.a = 5 + m = MyConfigurable(config=c) + self.assertEqual(m.a, 5) + + c2 = Config() + c2.MyConfigurable.a = 10 + m.update_config(c2) + self.assertEqual(m.a, 10) + + c2.MyConfigurable.a = 15 + m.update_config(c2) + self.assertEqual(m.a, 15) + + def test_update_self(self): + """update_config with same config object still triggers config_changed""" + c = Config() + c.MyConfigurable.a = 5 + m = MyConfigurable(config=c) + self.assertEqual(m.a, 5) + c.MyConfigurable.a = 10 + m.update_config(c) + self.assertEqual(m.a, 10) + + def test_config_default(self): + class SomeSingleton(SingletonConfigurable): + pass + + class DefaultConfigurable(Configurable): + a = Integer().tag(config=True) + def _config_default(self): + if SomeSingleton.initialized(): + return SomeSingleton.instance().config + return Config() + + c = Config() + c.DefaultConfigurable.a = 5 + + d1 = DefaultConfigurable() + self.assertEqual(d1.a, 0) + + single = SomeSingleton.instance(config=c) + + d2 = DefaultConfigurable() + self.assertIs(d2.config, single.config) + self.assertEqual(d2.a, 5) + + def test_config_default_deprecated(self): + """Make sure configurables work even with the deprecations in traitlets""" + class SomeSingleton(SingletonConfigurable): + pass + + # reset deprecation limiter + _deprecations_shown.clear() + with expected_warnings([]): + class DefaultConfigurable(Configurable): + a = Integer(config=True) + def _config_default(self): + if SomeSingleton.initialized(): + return SomeSingleton.instance().config + return Config() + + c = Config() + c.DefaultConfigurable.a = 5 + + d1 = DefaultConfigurable() + self.assertEqual(d1.a, 0) + + single = SomeSingleton.instance(config=c) + + d2 = DefaultConfigurable() + self.assertIs(d2.config, single.config) + self.assertEqual(d2.a, 5) + + def test_kwarg_config_priority(self): + # a, c set in kwargs + # a, b set in config + # verify that: + # - kwargs are set before config + # - kwargs have priority over config + class A(Configurable): + a = Unicode('default', config=True) + b = Unicode('default', config=True) + c = Unicode('default', config=True) + c_during_config = Unicode('never') + @validate('b') + def _record_c(self, proposal): + # setting b from config records c's value at the time + self.c_during_config = self.c + return proposal.value + + cfg = Config() + cfg.A.a = 'a-config' + cfg.A.b = 'b-config' + obj = A(a='a-kwarg', c='c-kwarg', config=cfg) + assert obj.a == 'a-kwarg' + assert obj.b == 'b-config' + assert obj.c == 'c-kwarg' + assert obj.c_during_config == 'c-kwarg' + + +class TestLogger(TestCase): + + class A(LoggingConfigurable): + foo = Integer(config=True) + bar = Integer(config=True) + baz = Integer(config=True) + + @mark.skipif(not hasattr(TestCase, 'assertLogs'), reason='requires TestCase.assertLogs') + def test_warn_match(self): + logger = logging.getLogger('test_warn_match') + cfg = Config({'A': {'bat': 5}}) + with self.assertLogs(logger, logging.WARNING) as captured: + TestLogger.A(config=cfg, log=logger) + + output = '\n'.join(captured.output) + self.assertIn('Did you mean one of: `bar, baz`?', output) + self.assertIn('Config option `bat` not recognized by `A`.', output) + + cfg = Config({'A': {'fool': 5}}) + with self.assertLogs(logger, logging.WARNING) as captured: + TestLogger.A(config=cfg, log=logger) + + output = '\n'.join(captured.output) + self.assertIn('Config option `fool` not recognized by `A`.', output) + self.assertIn('Did you mean `foo`?', output) + + cfg = Config({'A': {'totally_wrong': 5}}) + with self.assertLogs(logger, logging.WARNING) as captured: + TestLogger.A(config=cfg, log=logger) + + output = '\n'.join(captured.output) + self.assertIn('Config option `totally_wrong` not recognized by `A`.', output) + self.assertNotIn('Did you mean', output) + + def test_logger_adapter(self): + logger = logging.getLogger("test_logger_adapter") + adapter = logging.LoggerAdapter(logger, {"key": "adapted"}) + + with self.assertLogs(logger, logging.INFO) as captured: + app = Application(log=adapter, log_level=logging.INFO) + app.log_format = "%(key)s %(message)s" + app.log.info("test message") + + output = "\n".join(captured.output) + assert "adapted test message" in output diff --git a/.venv/lib/python3.8/site-packages/traitlets/config/tests/test_loader.py b/.venv/lib/python3.8/site-packages/traitlets/config/tests/test_loader.py new file mode 100644 index 00000000..74289dc9 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/traitlets/config/tests/test_loader.py @@ -0,0 +1,747 @@ +# encoding: utf-8 +"""Tests for traitlets.config.loader""" + +# Copyright (c) IPython Development Team. +# Distributed under the terms of the Modified BSD License. + +import copy +import os +import pickle +from itertools import chain +from tempfile import mkstemp +from unittest import TestCase + +import pytest + +from traitlets.config.loader import ( + Config, + LazyConfigValue, + PyFileConfigLoader, + JSONFileConfigLoader, + KeyValueConfigLoader, + ArgParseConfigLoader, + KVArgParseConfigLoader, +) +from traitlets import ( + List, + Tuple, + Dict, + Unicode, + Integer, +) +from traitlets.config import Configurable + + +pyfile = """ +c = get_config() +c.a=10 +c.b=20 +c.Foo.Bar.value=10 +c.Foo.Bam.value=list(range(10)) +c.D.C.value='hi there' +""" + +json1file = """ +{ + "version": 1, + "a": 10, + "b": 20, + "Foo": { + "Bam": { + "value": [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ] + }, + "Bar": { + "value": 10 + } + }, + "D": { + "C": { + "value": "hi there" + } + } +} +""" + +# should not load +json2file = """ +{ + "version": 2 +} +""" + +import logging +log = logging.getLogger('devnull') +log.setLevel(0) + + +class TestFileCL(TestCase): + def _check_conf(self, config): + self.assertEqual(config.a, 10) + self.assertEqual(config.b, 20) + self.assertEqual(config.Foo.Bar.value, 10) + self.assertEqual(config.Foo.Bam.value, list(range(10))) + self.assertEqual(config.D.C.value, 'hi there') + + def test_python(self): + fd, fname = mkstemp('.py', prefix='μnïcø∂e') + f = os.fdopen(fd, 'w') + f.write(pyfile) + f.close() + # Unlink the file + cl = PyFileConfigLoader(fname, log=log) + config = cl.load_config() + self._check_conf(config) + + def test_json(self): + fd, fname = mkstemp('.json', prefix='μnïcø∂e') + f = os.fdopen(fd, 'w') + f.write(json1file) + f.close() + # Unlink the file + cl = JSONFileConfigLoader(fname, log=log) + config = cl.load_config() + self._check_conf(config) + + def test_context_manager(self): + + fd, fname = mkstemp('.json', prefix='μnïcø∂e') + f = os.fdopen(fd, 'w') + f.write('{}') + f.close() + + cl = JSONFileConfigLoader(fname, log=log) + + value = 'context_manager' + + with cl as c: + c.MyAttr.value = value + + self.assertEqual(cl.config.MyAttr.value, value) + + # check that another loader does see the change + cl2 = JSONFileConfigLoader(fname, log=log) + self.assertEqual(cl.config.MyAttr.value, value) + + def test_json_context_bad_write(self): + fd, fname = mkstemp('.json', prefix='μnïcø∂e') + f = os.fdopen(fd, 'w') + f.write('{}') + f.close() + + with JSONFileConfigLoader(fname, log=log) as config: + config.A.b = 1 + + with self.assertRaises(TypeError): + with JSONFileConfigLoader(fname, log=log) as config: + config.A.cant_json = lambda x: x + + loader = JSONFileConfigLoader(fname, log=log) + cfg = loader.load_config() + assert cfg.A.b == 1 + assert 'cant_json' not in cfg.A + + def test_collision(self): + a = Config() + b = Config() + self.assertEqual(a.collisions(b), {}) + a.A.trait1 = 1 + b.A.trait2 = 2 + self.assertEqual(a.collisions(b), {}) + b.A.trait1 = 1 + self.assertEqual(a.collisions(b), {}) + b.A.trait1 = 0 + self.assertEqual(a.collisions(b), { + 'A': { + 'trait1': "1 ignored, using 0", + } + }) + self.assertEqual(b.collisions(a), { + 'A': { + 'trait1': "0 ignored, using 1", + } + }) + a.A.trait2 = 3 + self.assertEqual(b.collisions(a), { + 'A': { + 'trait1': "0 ignored, using 1", + 'trait2': "2 ignored, using 3", + } + }) + + def test_v2raise(self): + fd, fname = mkstemp('.json', prefix='μnïcø∂e') + f = os.fdopen(fd, 'w') + f.write(json2file) + f.close() + # Unlink the file + cl = JSONFileConfigLoader(fname, log=log) + with self.assertRaises(ValueError): + cl.load_config() + + +def _parse_int_or_str(v): + try: + return int(v) + except: + return str(v) + + +class MyLoader1(ArgParseConfigLoader): + def _add_arguments(self, aliases=None, flags=None, classes=None): + p = self.parser + p.add_argument('-f', '--foo', dest='Global.foo', type=str) + p.add_argument('-b', dest='MyClass.bar', type=int) + p.add_argument('-n', dest='n', action='store_true') + p.add_argument('Global.bam', type=str) + p.add_argument('--list1', action='append', type=_parse_int_or_str) + p.add_argument('--list2', nargs='+', type=int) + + +class MyLoader2(ArgParseConfigLoader): + def _add_arguments(self, aliases=None, flags=None, classes=None): + subparsers = self.parser.add_subparsers(dest='subparser_name') + subparser1 = subparsers.add_parser('1') + subparser1.add_argument('-x', dest='Global.x') + subparser2 = subparsers.add_parser('2') + subparser2.add_argument('y') + + +class TestArgParseCL(TestCase): + + def test_basic(self): + cl = MyLoader1() + config = cl.load_config('-f hi -b 10 -n wow'.split()) + self.assertEqual(config.Global.foo, 'hi') + self.assertEqual(config.MyClass.bar, 10) + self.assertEqual(config.n, True) + self.assertEqual(config.Global.bam, 'wow') + config = cl.load_config(['wow']) + self.assertEqual(list(config.keys()), ['Global']) + self.assertEqual(list(config.Global.keys()), ['bam']) + self.assertEqual(config.Global.bam, 'wow') + + def test_add_arguments(self): + cl = MyLoader2() + config = cl.load_config('2 frobble'.split()) + self.assertEqual(config.subparser_name, '2') + self.assertEqual(config.y, 'frobble') + config = cl.load_config('1 -x frobble'.split()) + self.assertEqual(config.subparser_name, '1') + self.assertEqual(config.Global.x, 'frobble') + + def test_argv(self): + cl = MyLoader1(argv='-f hi -b 10 -n wow'.split()) + config = cl.load_config() + self.assertEqual(config.Global.foo, 'hi') + self.assertEqual(config.MyClass.bar, 10) + self.assertEqual(config.n, True) + self.assertEqual(config.Global.bam, 'wow') + + def test_list_args(self): + cl = MyLoader1() + config = cl.load_config('--list1 1 wow --list2 1 2 3 --list1 B'.split()) + self.assertEqual(list(config.Global.keys()), ['bam']) + self.assertEqual(config.Global.bam, 'wow') + self.assertEqual(config.list1, [1, 'B']) + self.assertEqual(config.list2, [1, 2, 3]) + + +class C(Configurable): + str_trait = Unicode(config=True) + int_trait = Integer(config=True) + list_trait = List(config=True) + list_of_ints = List(Integer(), config=True) + dict_trait = Dict(config=True) + dict_of_ints = Dict( + key_trait=Integer(), + value_trait=Integer(), + config=True, + ) + dict_multi = Dict( + key_trait=Unicode(), + per_key_traits={ + "int": Integer(), + "str": Unicode(), + }, + config=True, + ) + + +class TestKeyValueCL(TestCase): + klass = KeyValueConfigLoader + + def test_eval(self): + cl = self.klass(log=log) + config = cl.load_config('--C.str_trait=all --C.int_trait=5 --C.list_trait=["hello",5]'.split()) + c = C(config=config) + assert c.str_trait == 'all' + assert c.int_trait == 5 + assert c.list_trait == ["hello", 5] + + def test_basic(self): + cl = self.klass(log=log) + argv = [ '--' + s[2:] for s in pyfile.split('\n') if s.startswith('c.') ] + config = cl.load_config(argv) + assert config.a == '10' + assert config.b == '20' + assert config.Foo.Bar.value == '10' + # non-literal expressions are not evaluated + self.assertEqual(config.Foo.Bam.value, 'list(range(10))') + self.assertEqual(Unicode().from_string(config.D.C.value), 'hi there') + + def test_expanduser(self): + cl = self.klass(log=log) + argv = ['--a=~/1/2/3', '--b=~', '--c=~/', '--d="~/"'] + config = cl.load_config(argv) + u = Unicode() + self.assertEqual(u.from_string(config.a), os.path.expanduser('~/1/2/3')) + self.assertEqual(u.from_string(config.b), os.path.expanduser('~')) + self.assertEqual(u.from_string(config.c), os.path.expanduser('~/')) + self.assertEqual(u.from_string(config.d), '~/') + + def test_extra_args(self): + cl = self.klass(log=log) + config = cl.load_config(['--a=5', 'b', 'd', '--c=10']) + self.assertEqual(cl.extra_args, ['b', 'd']) + assert config.a == '5' + assert config.c == '10' + config = cl.load_config(['--', '--a=5', '--c=10']) + self.assertEqual(cl.extra_args, ['--a=5', '--c=10']) + + cl = self.klass(log=log) + config = cl.load_config(['extra', '--a=2', '--c=1', '--', '-']) + self.assertEqual(cl.extra_args, ['extra', '-']) + + def test_unicode_args(self): + cl = self.klass(log=log) + argv = ['--a=épsîlön'] + config = cl.load_config(argv) + print(config, cl.extra_args) + self.assertEqual(config.a, 'épsîlön') + + def test_list_append(self): + cl = self.klass(log=log) + argv = ["--C.list_trait", "x", "--C.list_trait", "y"] + config = cl.load_config(argv) + assert config.C.list_trait == ["x", "y"] + c = C(config=config) + assert c.list_trait == ["x", "y"] + + def test_dict(self): + cl = self.klass(log=log) + argv = ["--C.dict_trait", "x=5", "--C.dict_trait", "y=10"] + config = cl.load_config(argv) + c = C(config=config) + assert c.dict_trait == {"x": "5", "y": "10"} + + def test_dict_key_traits(self): + cl = self.klass(log=log) + argv = ["--C.dict_of_ints", "1=2", "--C.dict_of_ints", "3=4"] + config = cl.load_config(argv) + c = C(config=config) + assert c.dict_of_ints == {1: 2, 3: 4} + + +class CBase(Configurable): + a = List().tag(config=True) + b = List(Integer()).tag(config=True, multiplicity='*') + c = List().tag(config=True, multiplicity='append') + adict = Dict().tag(config=True) + + +class CSub(CBase): + d = Tuple().tag(config=True) + e = Tuple().tag(config=True, multiplicity='+') + bdict = Dict().tag(config=True, multiplicity='*') + + +class TestArgParseKVCL(TestKeyValueCL): + klass = KVArgParseConfigLoader + + def test_no_cast_literals(self): + cl = self.klass(log=log) + # test ipython -c 1 doesn't cast to int + argv = ["-c", "1"] + config = cl.load_config(argv, aliases=dict(c="IPython.command_to_run")) + assert config.IPython.command_to_run == "1" + + def test_int_literals(self): + cl = self.klass(log=log) + # test ipython -c 1 doesn't cast to int + argv = ["-c", "1"] + config = cl.load_config(argv, aliases=dict(c="IPython.command_to_run")) + assert config.IPython.command_to_run == "1" + + def test_unicode_alias(self): + cl = self.klass(log=log) + argv = ['--a=épsîlön'] + config = cl.load_config(argv, aliases=dict(a='A.a')) + print(dict(config)) + print(cl.extra_args) + print(cl.aliases) + self.assertEqual(config.A.a, 'épsîlön') + + def test_expanduser2(self): + cl = self.klass(log=log) + argv = ['-a', '~/1/2/3', '--b', "'~/1/2/3'"] + config = cl.load_config(argv, aliases=dict(a='A.a', b='A.b')) + + class A(Configurable): + a = Unicode(config=True) + b = Unicode(config=True) + + a = A(config=config) + self.assertEqual(a.a, os.path.expanduser('~/1/2/3')) + self.assertEqual(a.b, '~/1/2/3') + + def test_eval(self): + cl = self.klass(log=log) + argv = ['-c', 'a=5'] + config = cl.load_config(argv, aliases=dict(c='A.c')) + self.assertEqual(config.A.c, "a=5") + + def test_seq_traits(self): + cl = self.klass(log=log, classes=(CBase, CSub)) + aliases = {'a3': 'CBase.c', 'a5': 'CSub.e'} + argv = ("--CBase.a A --CBase.a 2 --CBase.b 1 --CBase.b 3 --a3 AA --CBase.c BB " + "--CSub.d 1 --CSub.d BBB --CSub.e 1 --CSub.e=bcd a b c ").split() + config = cl.load_config(argv, aliases=aliases) + assert cl.extra_args == ["a", "b", "c"] + assert config.CBase.a == ['A', '2'] + assert config.CBase.b == [1, 3] + self.assertEqual(config.CBase.c, ['AA', 'BB']) + + assert config.CSub.d == ('1', 'BBB') + assert config.CSub.e == ('1', 'bcd') + + def test_seq_traits_single_empty_string(self): + cl = self.klass(log=log, classes=(CBase, )) + aliases = {'seqopt': 'CBase.c'} + argv = ['--seqopt', ''] + config = cl.load_config(argv, aliases=aliases) + self.assertEqual(config.CBase.c, ['']) + + def test_dict_traits(self): + cl = self.klass(log=log, classes=(CBase, CSub)) + aliases = {'D': 'CBase.adict', 'E': 'CSub.bdict'} + argv = ["-D", "k1=v1", "-D=k2=2", "-D", "k3=v 3", "-E", "k=v", "-E", "22=222"] + config = cl.load_config(argv, aliases=aliases) + c = CSub(config=config) + assert c.adict == {'k1': 'v1', 'k2': '2', 'k3': 'v 3'} + assert c.bdict == {'k': 'v', '22': '222'} + + def test_mixed_seq_positional(self): + aliases = {"c": "Class.trait"} + cl = self.klass(log=log, aliases=aliases) + assignments = [("-c", "1"), ("--Class.trait=2",), ("--c=3",), ("--Class.trait", "4")] + positionals = ["a", "b", "c"] + # test with positionals at any index + for idx in range(len(assignments) + 1): + argv_parts = assignments[:] + argv_parts[idx:idx] = (positionals,) + argv = list(chain(*argv_parts)) + + config = cl.load_config(argv) + assert config.Class.trait == ["1", "2", "3", "4"] + assert cl.extra_args == ["a", "b", "c"] + + def test_split_positional(self): + """Splitting positionals across flags is no longer allowed in traitlets 5""" + cl = self.klass(log=log) + argv = ["a", "--Class.trait=5", "b"] + with pytest.raises(SystemExit): + cl.load_config(argv) + + +class TestConfig(TestCase): + + def test_setget(self): + c = Config() + c.a = 10 + self.assertEqual(c.a, 10) + self.assertEqual('b' in c, False) + + def test_auto_section(self): + c = Config() + self.assertNotIn('A', c) + assert not c._has_section('A') + A = c.A + A.foo = 'hi there' + self.assertIn('A', c) + assert c._has_section('A') + self.assertEqual(c.A.foo, 'hi there') + del c.A + self.assertEqual(c.A, Config()) + + def test_merge_doesnt_exist(self): + c1 = Config() + c2 = Config() + c2.bar = 10 + c2.Foo.bar = 10 + c1.merge(c2) + self.assertEqual(c1.Foo.bar, 10) + self.assertEqual(c1.bar, 10) + c2.Bar.bar = 10 + c1.merge(c2) + self.assertEqual(c1.Bar.bar, 10) + + def test_merge_exists(self): + c1 = Config() + c2 = Config() + c1.Foo.bar = 10 + c1.Foo.bam = 30 + c2.Foo.bar = 20 + c2.Foo.wow = 40 + c1.merge(c2) + self.assertEqual(c1.Foo.bam, 30) + self.assertEqual(c1.Foo.bar, 20) + self.assertEqual(c1.Foo.wow, 40) + c2.Foo.Bam.bam = 10 + c1.merge(c2) + self.assertEqual(c1.Foo.Bam.bam, 10) + + def test_deepcopy(self): + c1 = Config() + c1.Foo.bar = 10 + c1.Foo.bam = 30 + c1.a = 'asdf' + c1.b = range(10) + c1.Test.logger = logging.Logger('test') + c1.Test.get_logger = logging.getLogger('test') + c2 = copy.deepcopy(c1) + self.assertEqual(c1, c2) + self.assertTrue(c1 is not c2) + self.assertTrue(c1.Foo is not c2.Foo) + self.assertTrue(c1.Test is not c2.Test) + self.assertTrue(c1.Test.logger is c2.Test.logger) + self.assertTrue(c1.Test.get_logger is c2.Test.get_logger) + + def test_builtin(self): + c1 = Config() + c1.format = "json" + + def test_fromdict(self): + c1 = Config({'Foo' : {'bar' : 1}}) + self.assertEqual(c1.Foo.__class__, Config) + self.assertEqual(c1.Foo.bar, 1) + + def test_fromdictmerge(self): + c1 = Config() + c2 = Config({'Foo' : {'bar' : 1}}) + c1.merge(c2) + self.assertEqual(c1.Foo.__class__, Config) + self.assertEqual(c1.Foo.bar, 1) + + def test_fromdictmerge2(self): + c1 = Config({'Foo' : {'baz' : 2}}) + c2 = Config({'Foo' : {'bar' : 1}}) + c1.merge(c2) + self.assertEqual(c1.Foo.__class__, Config) + self.assertEqual(c1.Foo.bar, 1) + self.assertEqual(c1.Foo.baz, 2) + self.assertNotIn('baz', c2.Foo) + + def test_contains(self): + c1 = Config({'Foo' : {'baz' : 2}}) + c2 = Config({'Foo' : {'bar' : 1}}) + self.assertIn('Foo', c1) + self.assertIn('Foo.baz', c1) + self.assertIn('Foo.bar', c2) + self.assertNotIn('Foo.bar', c1) + + def test_pickle_config(self): + cfg = Config() + cfg.Foo.bar = 1 + pcfg = pickle.dumps(cfg) + cfg2 = pickle.loads(pcfg) + self.assertEqual(cfg2, cfg) + + def test_getattr_section(self): + cfg = Config() + self.assertNotIn('Foo', cfg) + Foo = cfg.Foo + assert isinstance(Foo, Config) + self.assertIn('Foo', cfg) + + def test_getitem_section(self): + cfg = Config() + self.assertNotIn('Foo', cfg) + Foo = cfg['Foo'] + assert isinstance(Foo, Config) + self.assertIn('Foo', cfg) + + def test_getattr_not_section(self): + cfg = Config() + self.assertNotIn('foo', cfg) + foo = cfg.foo + assert isinstance(foo, LazyConfigValue) + self.assertIn('foo', cfg) + + def test_getattr_private_missing(self): + cfg = Config() + self.assertNotIn('_repr_html_', cfg) + with self.assertRaises(AttributeError): + _ = cfg._repr_html_ + self.assertNotIn('_repr_html_', cfg) + self.assertEqual(len(cfg), 0) + + def test_lazy_config_repr(self): + cfg = Config() + cfg.Class.lazy.append(1) + cfg_repr = repr(cfg) + assert '" in cfg_repr + assert 'value=' not in cfg_repr + cfg.Class.lazy.get_value([0]) + repr2 = repr(cfg) + assert repr([0,1]) in repr2 + assert 'value=' in repr2 + + + def test_getitem_not_section(self): + cfg = Config() + self.assertNotIn('foo', cfg) + foo = cfg['foo'] + assert isinstance(foo, LazyConfigValue) + self.assertIn('foo', cfg) + + def test_merge_no_copies(self): + c = Config() + c2 = Config() + c2.Foo.trait = [] + c.merge(c2) + c2.Foo.trait.append(1) + self.assertIs(c.Foo, c2.Foo) + self.assertEqual(c.Foo.trait, [1]) + self.assertEqual(c2.Foo.trait, [1]) + + + def test_merge_multi_lazy(self): + """ + With multiple config files (systemwide and users), we want compounding. + + If systemwide overwirte and user append, we want both in the right + order. + """ + c1 = Config() + c2 = Config() + + c1.Foo.trait = [1] + c2.Foo.trait.append(2) + + c = Config() + c.merge(c1) + c.merge(c2) + + self.assertEqual(c.Foo.trait, [1,2] ) + + + + def test_merge_multi_lazyII(self): + """ + With multiple config files (systemwide and users), we want compounding. + + If both are lazy we still want a lazy config. + """ + c1 = Config() + c2 = Config() + + c1.Foo.trait.append(1) + c2.Foo.trait.append(2) + + c = Config() + c.merge(c1) + c.merge(c2) + + self.assertEqual(c.Foo.trait._extend, [1,2] ) + + def test_merge_multi_lazy_III(self): + """ + With multiple config files (systemwide and users), we want compounding. + + Prepend should prepend in the right order. + """ + c1 = Config() + c2 = Config() + + c1.Foo.trait = [1] + c2.Foo.trait.prepend([0]) + + c = Config() + c.merge(c1) + c.merge(c2) + + self.assertEqual(c.Foo.trait, [0, 1] ) + + def test_merge_multi_lazy_IV(self): + """ + With multiple config files (systemwide and users), we want compounding. + + Both prepending should be lazy + """ + c1 = Config() + c2 = Config() + + c1.Foo.trait.prepend([1]) + c2.Foo.trait.prepend([0]) + + c = Config() + c.merge(c1) + c.merge(c2) + + self.assertEqual(c.Foo.trait._prepend, [0, 1]) + + def test_merge_multi_lazy_update_I(self): + """ + With multiple config files (systemwide and users), we want compounding. + + dict update shoudl be in the right order. + """ + c1 = Config() + c2 = Config() + + c1.Foo.trait = {"a": 1, "z": 26} + c2.Foo.trait.update({"a": 0, "b": 1}) + + c = Config() + c.merge(c1) + c.merge(c2) + + self.assertEqual(c.Foo.trait, {"a": 0, "b": 1, "z": 26}) + + def test_merge_multi_lazy_update_II(self): + """ + With multiple config files (systemwide and users), we want compounding. + + Later dict overwrite lazyness + """ + c1 = Config() + c2 = Config() + + c1.Foo.trait.update({"a": 0, "b": 1}) + c2.Foo.trait = {"a": 1, "z": 26} + + c = Config() + c.merge(c1) + c.merge(c2) + + self.assertEqual(c.Foo.trait, {"a": 1, "z": 26}) + + def test_merge_multi_lazy_update_III(self): + """ + With multiple config files (systemwide and users), we want compounding. + + Later dict overwrite lazyness + """ + c1 = Config() + c2 = Config() + + c1.Foo.trait.update({"a": 0, "b": 1}) + c2.Foo.trait.update({"a": 1, "z": 26}) + + c = Config() + c.merge(c1) + c.merge(c2) + + self.assertEqual(c.Foo.trait._update, {"a": 1, "z": 26, "b": 1}) diff --git a/.venv/lib/python3.8/site-packages/traitlets/log.py b/.venv/lib/python3.8/site-packages/traitlets/log.py new file mode 100644 index 00000000..af86b325 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/traitlets/log.py @@ -0,0 +1,27 @@ +"""Grab the global logger instance.""" + +# Copyright (c) IPython Development Team. +# Distributed under the terms of the Modified BSD License. + +import logging + +_logger = None + +def get_logger(): + """Grab the global logger instance. + + If a global Application is instantiated, grab its logger. + Otherwise, grab the root logger. + """ + global _logger + + if _logger is None: + from .config import Application + if Application.initialized(): + _logger = Application.instance().log + else: + _logger = logging.getLogger('traitlets') + # Add a NullHandler to silence warnings about not being + # initialized, per best practice for libraries. + _logger.addHandler(logging.NullHandler()) + return _logger diff --git a/.venv/lib/python3.8/site-packages/traitlets/tests/__init__.py b/.venv/lib/python3.8/site-packages/traitlets/tests/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/.venv/lib/python3.8/site-packages/traitlets/tests/__pycache__/__init__.cpython-38.pyc b/.venv/lib/python3.8/site-packages/traitlets/tests/__pycache__/__init__.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c0658ed3306c10151f0dad8f35c3bbfb75728b52 GIT binary patch literal 151 zcmWIL<>g`kf`9eb;z9Id5P=LBfgA@QE@lA|DGb33nv8xc8Hzx{2;!HGeo1bDenDn| zZfRaYVsdtBif(yEYHE&diE)y7RY`e;eo0YcW=T$JNwI!OYB7+EkI&4@EQycTE2zB1 TVUwGmQks)$2Qu|D5HkP(#jqsf literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/traitlets/tests/__pycache__/_warnings.cpython-38.pyc b/.venv/lib/python3.8/site-packages/traitlets/tests/__pycache__/_warnings.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ce8ea4720b49fc1c0579604b63b706495b5a5d8b GIT binary patch literal 3446 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 L(>> import warnings + >>> def foo(): + ... warnings.warn(RuntimeWarning("bar")) + We raise the warning once, while the warning filter is set to "once". + Hereafter, the warning is invisible, even with custom filters: + >>> with warnings.catch_warnings(): + ... warnings.simplefilter('once') + ... foo() + We can now run ``foo()`` without a warning being raised: + >>> from numpy.testing import assert_warns + >>> foo() + To catch the warning, we call in the help of ``all_warnings``: + >>> with all_warnings(): + ... assert_warns(RuntimeWarning, foo) + """ + + # Whenever a warning is triggered, Python adds a __warningregistry__ + # member to the *calling* module. The exercize here is to find + # and eradicate all those breadcrumbs that were left lying around. + # + # We proceed by first searching all parent calling frames and explicitly + # clearing their warning registries (necessary for the doctests above to + # pass). Then, we search for all submodules of skimage and clear theirs + # as well (necessary for the skimage test suite to pass). + + frame = inspect.currentframe() + if frame: + for f in inspect.getouterframes(frame): + f[0].f_locals['__warningregistry__'] = {} + del frame + + for mod_name, mod in list(sys.modules.items()): + try: + mod.__warningregistry__.clear() + except AttributeError: + pass + + with warnings.catch_warnings(record=True) as w, \ + mock.patch.dict(os.environ, {'TRAITLETS_ALL_DEPRECATIONS': '1'}): + warnings.simplefilter("always") + yield w + + +@contextmanager +def expected_warnings(matching): + r"""Context for use in testing to catch known warnings matching regexes + + Parameters + ---------- + matching : list of strings or compiled regexes + Regexes for the desired warning to catch + + Examples + -------- + >>> from skimage import data, img_as_ubyte, img_as_float + >>> with expected_warnings(["precision loss"]): + ... d = img_as_ubyte(img_as_float(data.coins())) + + Notes + ----- + Uses `all_warnings` to ensure all warnings are raised. + Upon exiting, it checks the recorded warnings for the desired matching + pattern(s). + Raises a ValueError if any match was not found or an unexpected + warning was raised. + Allows for three types of behaviors: "and", "or", and "optional" matches. + This is done to accomodate different build enviroments or loop conditions + that may produce different warnings. The behaviors can be combined. + If you pass multiple patterns, you get an orderless "and", where all of the + warnings must be raised. + If you use the "|" operator in a pattern, you can catch one of several warnings. + Finally, you can use "|\A\Z" in a pattern to signify it as optional. + """ + with all_warnings() as w: + # enter context + yield w + # exited user context, check the recorded warnings + remaining = [m for m in matching if not r'\A\Z' in m.split('|')] + for warn in w: + found = False + for match in matching: + if re.search(match, str(warn.message)) is not None: + found = True + if match in remaining: + remaining.remove(match) + if not found: + raise ValueError('Unexpected warning: %s' % str(warn.message)) + if len(remaining) > 0: + msg = 'No warning raised matching:\n%s' % '\n'.join(remaining) + raise ValueError(msg) diff --git a/.venv/lib/python3.8/site-packages/traitlets/tests/test_traitlets.py b/.venv/lib/python3.8/site-packages/traitlets/tests/test_traitlets.py new file mode 100644 index 00000000..595f75b0 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/traitlets/tests/test_traitlets.py @@ -0,0 +1,2933 @@ +# encoding: utf-8 +"""Tests for traitlets.traitlets.""" + +# Copyright (c) IPython Development Team. +# Distributed under the terms of the Modified BSD License. +# +# Adapted from enthought.traits, Copyright (c) Enthought, Inc., +# also under the terms of the Modified BSD License. + +import pickle +import re +from unittest import TestCase + +import pytest + +from ._warnings import expected_warnings +from traitlets import ( + HasTraits, + MetaHasTraits, + TraitType, + Any, + Bool, + CBytes, + Dict, + Enum, + Int, + CInt, + Long, + CLong, + Integer, + Float, + CFloat, + Complex, + Bytes, + Unicode, + TraitError, + Union, + Callable, + All, + Undefined, + Set, + Type, + This, + Instance, + TCPAddress, + List, + Set, + Tuple, + ObjectName, + DottedObjectName, + CRegExp, + link, + directional_link, + ForwardDeclaredType, + ForwardDeclaredInstance, + validate, + observe, + default, + observe_compat, + BaseDescriptor, + HasDescriptors, + CUnicode, +) +from traitlets.utils import cast_unicode + + +def change_dict(*ordered_values): + change_names = ('name', 'old', 'new', 'owner', 'type') + return dict(zip(change_names, ordered_values)) + +#----------------------------------------------------------------------------- +# Helper classes for testing +#----------------------------------------------------------------------------- + + +class HasTraitsStub(HasTraits): + + def notify_change(self, change): + self._notify_name = change['name'] + self._notify_old = change['old'] + self._notify_new = change['new'] + self._notify_type = change['type'] + + +#----------------------------------------------------------------------------- +# Test classes +#----------------------------------------------------------------------------- + + +class TestTraitType(TestCase): + + def test_get_undefined(self): + class A(HasTraits): + a = TraitType + a = A() + assert a.a is Undefined + + def test_set(self): + class A(HasTraitsStub): + a = TraitType + + a = A() + a.a = 10 + self.assertEqual(a.a, 10) + self.assertEqual(a._notify_name, 'a') + self.assertEqual(a._notify_old, Undefined) + self.assertEqual(a._notify_new, 10) + + def test_validate(self): + class MyTT(TraitType): + def validate(self, inst, value): + return -1 + class A(HasTraitsStub): + tt = MyTT + + a = A() + a.tt = 10 + self.assertEqual(a.tt, -1) + + def test_default_validate(self): + class MyIntTT(TraitType): + def validate(self, obj, value): + if isinstance(value, int): + return value + self.error(obj, value) + class A(HasTraits): + tt = MyIntTT(10) + a = A() + self.assertEqual(a.tt, 10) + + # Defaults are validated when the HasTraits is instantiated + class B(HasTraits): + tt = MyIntTT('bad default') + self.assertRaises(TraitError, getattr, B(), 'tt') + + def test_info(self): + class A(HasTraits): + tt = TraitType + a = A() + self.assertEqual(A.tt.info(), 'any value') + + def test_error(self): + class A(HasTraits): + tt = TraitType() + a = A() + self.assertRaises(TraitError, A.tt.error, a, 10) + + def test_deprecated_dynamic_initializer(self): + class A(HasTraits): + x = Int(10) + def _x_default(self): + return 11 + class B(A): + x = Int(20) + class C(A): + def _x_default(self): + return 21 + + a = A() + self.assertEqual(a._trait_values, {}) + self.assertEqual(a.x, 11) + self.assertEqual(a._trait_values, {'x': 11}) + b = B() + self.assertEqual(b.x, 20) + self.assertEqual(b._trait_values, {'x': 20}) + c = C() + self.assertEqual(c._trait_values, {}) + self.assertEqual(c.x, 21) + self.assertEqual(c._trait_values, {'x': 21}) + # Ensure that the base class remains unmolested when the _default + # initializer gets overridden in a subclass. + a = A() + c = C() + self.assertEqual(a._trait_values, {}) + self.assertEqual(a.x, 11) + self.assertEqual(a._trait_values, {'x': 11}) + + def test_deprecated_method_warnings(self): + + with expected_warnings([]): + class ShouldntWarn(HasTraits): + x = Integer() + @default('x') + def _x_default(self): + return 10 + + @validate('x') + def _x_validate(self, proposal): + return proposal.value + + @observe('x') + def _x_changed(self, change): + pass + + obj = ShouldntWarn() + obj.x = 5 + + assert obj.x == 5 + + with expected_warnings(['@validate', '@observe']) as w: + class ShouldWarn(HasTraits): + x = Integer() + + def _x_default(self): + return 10 + + def _x_validate(self, value, _): + return value + + def _x_changed(self): + pass + + obj = ShouldWarn() + obj.x = 5 + + assert obj.x == 5 + + def test_dynamic_initializer(self): + + class A(HasTraits): + x = Int(10) + + @default('x') + def _default_x(self): + return 11 + + class B(A): + x = Int(20) + + class C(A): + + @default('x') + def _default_x(self): + return 21 + + a = A() + self.assertEqual(a._trait_values, {}) + self.assertEqual(a.x, 11) + self.assertEqual(a._trait_values, {'x': 11}) + b = B() + self.assertEqual(b.x, 20) + self.assertEqual(b._trait_values, {'x': 20}) + c = C() + self.assertEqual(c._trait_values, {}) + self.assertEqual(c.x, 21) + self.assertEqual(c._trait_values, {'x': 21}) + # Ensure that the base class remains unmolested when the _default + # initializer gets overridden in a subclass. + a = A() + c = C() + self.assertEqual(a._trait_values, {}) + self.assertEqual(a.x, 11) + self.assertEqual(a._trait_values, {'x': 11}) + + def test_tag_metadata(self): + class MyIntTT(TraitType): + metadata = {'a': 1, 'b': 2} + a = MyIntTT(10).tag(b=3, c=4) + self.assertEqual(a.metadata, {'a': 1, 'b': 3, 'c': 4}) + + def test_metadata_localized_instance(self): + class MyIntTT(TraitType): + metadata = {'a': 1, 'b': 2} + a = MyIntTT(10) + b = MyIntTT(10) + a.metadata['c'] = 3 + # make sure that changing a's metadata didn't change b's metadata + self.assertNotIn('c', b.metadata) + + def test_union_metadata(self): + class Foo(HasTraits): + bar = (Int().tag(ta=1) | Dict().tag(ta=2, ti='b')).tag(ti='a') + foo = Foo() + # At this point, no value has been set for bar, so value-specific + # is not set. + self.assertEqual(foo.trait_metadata('bar', 'ta'), None) + self.assertEqual(foo.trait_metadata('bar', 'ti'), 'a') + foo.bar = {} + self.assertEqual(foo.trait_metadata('bar', 'ta'), 2) + self.assertEqual(foo.trait_metadata('bar', 'ti'), 'b') + foo.bar = 1 + self.assertEqual(foo.trait_metadata('bar', 'ta'), 1) + self.assertEqual(foo.trait_metadata('bar', 'ti'), 'a') + + def test_union_default_value(self): + class Foo(HasTraits): + bar = Union([Dict(), Int()], default_value=1) + foo = Foo() + self.assertEqual(foo.bar, 1) + + def test_union_validation_priority(self): + class Foo(HasTraits): + bar = Union([CInt(), Unicode()]) + foo = Foo() + foo.bar = '1' + # validation in order of the TraitTypes given + self.assertEqual(foo.bar, 1) + + def test_union_trait_default_value(self): + class Foo(HasTraits): + bar = Union([Dict(), Int()]) + self.assertEqual(Foo().bar, {}) + + def test_deprecated_metadata_access(self): + class MyIntTT(TraitType): + metadata = {'a': 1, 'b': 2} + a = MyIntTT(10) + with expected_warnings(["use the instance .metadata dictionary directly"]*2): + a.set_metadata('key', 'value') + v = a.get_metadata('key') + self.assertEqual(v, 'value') + with expected_warnings(["use the instance .help string directly"]*2): + a.set_metadata('help', 'some help') + v = a.get_metadata('help') + self.assertEqual(v, 'some help') + + def test_trait_types_deprecated(self): + with expected_warnings(["Traits should be given as instances"]): + class C(HasTraits): + t = Int + + def test_trait_types_list_deprecated(self): + with expected_warnings(["Traits should be given as instances"]): + class C(HasTraits): + t = List(Int) + + def test_trait_types_tuple_deprecated(self): + with expected_warnings(["Traits should be given as instances"]): + class C(HasTraits): + t = Tuple(Int) + + def test_trait_types_dict_deprecated(self): + with expected_warnings(["Traits should be given as instances"]): + class C(HasTraits): + t = Dict(Int) + +class TestHasDescriptorsMeta(TestCase): + + def test_metaclass(self): + self.assertEqual(type(HasTraits), MetaHasTraits) + + class A(HasTraits): + a = Int() + + a = A() + self.assertEqual(type(a.__class__), MetaHasTraits) + self.assertEqual(a.a,0) + a.a = 10 + self.assertEqual(a.a,10) + + class B(HasTraits): + b = Int() + + b = B() + self.assertEqual(b.b,0) + b.b = 10 + self.assertEqual(b.b,10) + + class C(HasTraits): + c = Int(30) + + c = C() + self.assertEqual(c.c,30) + c.c = 10 + self.assertEqual(c.c,10) + + def test_this_class(self): + class A(HasTraits): + t = This() + tt = This() + class B(A): + tt = This() + ttt = This() + self.assertEqual(A.t.this_class, A) + self.assertEqual(B.t.this_class, A) + self.assertEqual(B.tt.this_class, B) + self.assertEqual(B.ttt.this_class, B) + +class TestHasDescriptors(TestCase): + + def test_setup_instance(self): + + class FooDescriptor(BaseDescriptor): + + def instance_init(self, inst): + foo = inst.foo # instance should have the attr + + class HasFooDescriptors(HasDescriptors): + + fd = FooDescriptor() + + def setup_instance(self, *args, **kwargs): + self.foo = kwargs.get('foo', None) + super(HasFooDescriptors, self).setup_instance(*args, **kwargs) + + hfd = HasFooDescriptors(foo='bar') + +class TestHasTraitsNotify(TestCase): + + def setUp(self): + self._notify1 = [] + self._notify2 = [] + + def notify1(self, name, old, new): + self._notify1.append((name, old, new)) + + def notify2(self, name, old, new): + self._notify2.append((name, old, new)) + + def test_notify_all(self): + + class A(HasTraits): + a = Int() + b = Float() + + a = A() + a.on_trait_change(self.notify1) + a.a = 0 + self.assertEqual(len(self._notify1),0) + a.b = 0.0 + self.assertEqual(len(self._notify1),0) + a.a = 10 + self.assertTrue(('a',0,10) in self._notify1) + a.b = 10.0 + self.assertTrue(('b',0.0,10.0) in self._notify1) + self.assertRaises(TraitError,setattr,a,'a','bad string') + self.assertRaises(TraitError,setattr,a,'b','bad string') + self._notify1 = [] + a.on_trait_change(self.notify1,remove=True) + a.a = 20 + a.b = 20.0 + self.assertEqual(len(self._notify1),0) + + def test_notify_one(self): + + class A(HasTraits): + a = Int() + b = Float() + + a = A() + a.on_trait_change(self.notify1, 'a') + a.a = 0 + self.assertEqual(len(self._notify1),0) + a.a = 10 + self.assertTrue(('a',0,10) in self._notify1) + self.assertRaises(TraitError,setattr,a,'a','bad string') + + def test_subclass(self): + + class A(HasTraits): + a = Int() + + class B(A): + b = Float() + + b = B() + self.assertEqual(b.a,0) + self.assertEqual(b.b,0.0) + b.a = 100 + b.b = 100.0 + self.assertEqual(b.a,100) + self.assertEqual(b.b,100.0) + + def test_notify_subclass(self): + + class A(HasTraits): + a = Int() + + class B(A): + b = Float() + + b = B() + b.on_trait_change(self.notify1, 'a') + b.on_trait_change(self.notify2, 'b') + b.a = 0 + b.b = 0.0 + self.assertEqual(len(self._notify1),0) + self.assertEqual(len(self._notify2),0) + b.a = 10 + b.b = 10.0 + self.assertTrue(('a',0,10) in self._notify1) + self.assertTrue(('b',0.0,10.0) in self._notify2) + + def test_static_notify(self): + + class A(HasTraits): + a = Int() + _notify1 = [] + def _a_changed(self, name, old, new): + self._notify1.append((name, old, new)) + + a = A() + a.a = 0 + # This is broken!!! + self.assertEqual(len(a._notify1),0) + a.a = 10 + self.assertTrue(('a',0,10) in a._notify1) + + class B(A): + b = Float() + _notify2 = [] + def _b_changed(self, name, old, new): + self._notify2.append((name, old, new)) + + b = B() + b.a = 10 + b.b = 10.0 + self.assertTrue(('a',0,10) in b._notify1) + self.assertTrue(('b',0.0,10.0) in b._notify2) + + def test_notify_args(self): + + def callback0(): + self.cb = () + def callback1(name): + self.cb = (name,) + def callback2(name, new): + self.cb = (name, new) + def callback3(name, old, new): + self.cb = (name, old, new) + def callback4(name, old, new, obj): + self.cb = (name, old, new, obj) + + class A(HasTraits): + a = Int() + + a = A() + a.on_trait_change(callback0, 'a') + a.a = 10 + self.assertEqual(self.cb,()) + a.on_trait_change(callback0, 'a', remove=True) + + a.on_trait_change(callback1, 'a') + a.a = 100 + self.assertEqual(self.cb,('a',)) + a.on_trait_change(callback1, 'a', remove=True) + + a.on_trait_change(callback2, 'a') + a.a = 1000 + self.assertEqual(self.cb,('a',1000)) + a.on_trait_change(callback2, 'a', remove=True) + + a.on_trait_change(callback3, 'a') + a.a = 10000 + self.assertEqual(self.cb,('a',1000,10000)) + a.on_trait_change(callback3, 'a', remove=True) + + a.on_trait_change(callback4, 'a') + a.a = 100000 + self.assertEqual(self.cb,('a',10000,100000,a)) + self.assertEqual(len(a._trait_notifiers['a']['change']), 1) + a.on_trait_change(callback4, 'a', remove=True) + + self.assertEqual(len(a._trait_notifiers['a']['change']), 0) + + def test_notify_only_once(self): + + class A(HasTraits): + listen_to = ['a'] + + a = Int(0) + b = 0 + + def __init__(self, **kwargs): + super(A, self).__init__(**kwargs) + self.on_trait_change(self.listener1, ['a']) + + def listener1(self, name, old, new): + self.b += 1 + + class B(A): + + c = 0 + d = 0 + + def __init__(self, **kwargs): + super(B, self).__init__(**kwargs) + self.on_trait_change(self.listener2) + + def listener2(self, name, old, new): + self.c += 1 + + def _a_changed(self, name, old, new): + self.d += 1 + + b = B() + b.a += 1 + self.assertEqual(b.b, b.c) + self.assertEqual(b.b, b.d) + b.a += 1 + self.assertEqual(b.b, b.c) + self.assertEqual(b.b, b.d) + +class TestObserveDecorator(TestCase): + + def setUp(self): + self._notify1 = [] + self._notify2 = [] + + def notify1(self, change): + self._notify1.append(change) + + def notify2(self, change): + self._notify2.append(change) + + def test_notify_all(self): + + class A(HasTraits): + a = Int() + b = Float() + + a = A() + a.observe(self.notify1) + a.a = 0 + self.assertEqual(len(self._notify1),0) + a.b = 0.0 + self.assertEqual(len(self._notify1),0) + a.a = 10 + change = change_dict('a', 0, 10, a, 'change') + self.assertTrue(change in self._notify1) + a.b = 10.0 + change = change_dict('b', 0.0, 10.0, a, 'change') + self.assertTrue(change in self._notify1) + self.assertRaises(TraitError,setattr,a,'a','bad string') + self.assertRaises(TraitError,setattr,a,'b','bad string') + self._notify1 = [] + a.unobserve(self.notify1) + a.a = 20 + a.b = 20.0 + self.assertEqual(len(self._notify1),0) + + def test_notify_one(self): + + class A(HasTraits): + a = Int() + b = Float() + + a = A() + a.observe(self.notify1, 'a') + a.a = 0 + self.assertEqual(len(self._notify1),0) + a.a = 10 + change = change_dict('a', 0, 10, a, 'change') + self.assertTrue(change in self._notify1) + self.assertRaises(TraitError,setattr,a,'a','bad string') + + def test_subclass(self): + + class A(HasTraits): + a = Int() + + class B(A): + b = Float() + + b = B() + self.assertEqual(b.a,0) + self.assertEqual(b.b,0.0) + b.a = 100 + b.b = 100.0 + self.assertEqual(b.a,100) + self.assertEqual(b.b,100.0) + + def test_notify_subclass(self): + + class A(HasTraits): + a = Int() + + class B(A): + b = Float() + + b = B() + b.observe(self.notify1, 'a') + b.observe(self.notify2, 'b') + b.a = 0 + b.b = 0.0 + self.assertEqual(len(self._notify1),0) + self.assertEqual(len(self._notify2),0) + b.a = 10 + b.b = 10.0 + change = change_dict('a', 0, 10, b, 'change') + self.assertTrue(change in self._notify1) + change = change_dict('b', 0.0, 10.0, b, 'change') + self.assertTrue(change in self._notify2) + + def test_static_notify(self): + + class A(HasTraits): + a = Int() + b = Int() + _notify1 = [] + _notify_any = [] + + @observe('a') + def _a_changed(self, change): + self._notify1.append(change) + + @observe(All) + def _any_changed(self, change): + self._notify_any.append(change) + + a = A() + a.a = 0 + self.assertEqual(len(a._notify1),0) + a.a = 10 + change = change_dict('a', 0, 10, a, 'change') + self.assertTrue(change in a._notify1) + a.b = 1 + self.assertEqual(len(a._notify_any), 2) + change = change_dict('b', 0, 1, a, 'change') + self.assertTrue(change in a._notify_any) + + class B(A): + b = Float() + _notify2 = [] + @observe('b') + def _b_changed(self, change): + self._notify2.append(change) + + b = B() + b.a = 10 + b.b = 10.0 + change = change_dict('a', 0, 10, b, 'change') + self.assertTrue(change in b._notify1) + change = change_dict('b', 0.0, 10.0, b, 'change') + self.assertTrue(change in b._notify2) + + def test_notify_args(self): + + def callback0(): + self.cb = () + def callback1(change): + self.cb = change + + class A(HasTraits): + a = Int() + + a = A() + a.on_trait_change(callback0, 'a') + a.a = 10 + self.assertEqual(self.cb,()) + a.unobserve(callback0, 'a') + + a.observe(callback1, 'a') + a.a = 100 + change = change_dict('a', 10, 100, a, 'change') + self.assertEqual(self.cb, change) + self.assertEqual(len(a._trait_notifiers['a']['change']), 1) + a.unobserve(callback1, 'a') + + self.assertEqual(len(a._trait_notifiers['a']['change']), 0) + + def test_notify_only_once(self): + + class A(HasTraits): + listen_to = ['a'] + + a = Int(0) + b = 0 + + def __init__(self, **kwargs): + super(A, self).__init__(**kwargs) + self.observe(self.listener1, ['a']) + + def listener1(self, change): + self.b += 1 + + class B(A): + + c = 0 + d = 0 + + def __init__(self, **kwargs): + super(B, self).__init__(**kwargs) + self.observe(self.listener2) + + def listener2(self, change): + self.c += 1 + + @observe('a') + def _a_changed(self, change): + self.d += 1 + + b = B() + b.a += 1 + self.assertEqual(b.b, b.c) + self.assertEqual(b.b, b.d) + b.a += 1 + self.assertEqual(b.b, b.c) + self.assertEqual(b.b, b.d) + + +class TestHasTraits(TestCase): + + def test_trait_names(self): + class A(HasTraits): + i = Int() + f = Float() + a = A() + self.assertEqual(sorted(a.trait_names()),['f','i']) + self.assertEqual(sorted(A.class_trait_names()),['f','i']) + self.assertTrue(a.has_trait('f')) + self.assertFalse(a.has_trait('g')) + + def test_trait_has_value(self): + class A(HasTraits): + i = Int() + f = Float() + a = A() + self.assertFalse(a.trait_has_value('f')) + self.assertFalse(a.trait_has_value('g')) + a.i = 1 + a.f + self.assertTrue(a.trait_has_value('i')) + self.assertTrue(a.trait_has_value('f')) + + def test_trait_metadata_deprecated(self): + with expected_warnings([r'metadata should be set using the \.tag\(\) method']): + class A(HasTraits): + i = Int(config_key='MY_VALUE') + a = A() + self.assertEqual(a.trait_metadata('i','config_key'), 'MY_VALUE') + + def test_trait_metadata(self): + class A(HasTraits): + i = Int().tag(config_key='MY_VALUE') + a = A() + self.assertEqual(a.trait_metadata('i','config_key'), 'MY_VALUE') + + def test_trait_metadata_default(self): + class A(HasTraits): + i = Int() + a = A() + self.assertEqual(a.trait_metadata('i', 'config_key'), None) + self.assertEqual(a.trait_metadata('i', 'config_key', 'default'), 'default') + + def test_traits(self): + class A(HasTraits): + i = Int() + f = Float() + a = A() + self.assertEqual(a.traits(), dict(i=A.i, f=A.f)) + self.assertEqual(A.class_traits(), dict(i=A.i, f=A.f)) + + def test_traits_metadata(self): + class A(HasTraits): + i = Int().tag(config_key='VALUE1', other_thing='VALUE2') + f = Float().tag(config_key='VALUE3', other_thing='VALUE2') + j = Int(0) + a = A() + self.assertEqual(a.traits(), dict(i=A.i, f=A.f, j=A.j)) + traits = a.traits(config_key='VALUE1', other_thing='VALUE2') + self.assertEqual(traits, dict(i=A.i)) + + # This passes, but it shouldn't because I am replicating a bug in + # traits. + traits = a.traits(config_key=lambda v: True) + self.assertEqual(traits, dict(i=A.i, f=A.f, j=A.j)) + + def test_traits_metadata_deprecated(self): + with expected_warnings([r'metadata should be set using the \.tag\(\) method']*2): + class A(HasTraits): + i = Int(config_key='VALUE1', other_thing='VALUE2') + f = Float(config_key='VALUE3', other_thing='VALUE2') + j = Int(0) + a = A() + self.assertEqual(a.traits(), dict(i=A.i, f=A.f, j=A.j)) + traits = a.traits(config_key='VALUE1', other_thing='VALUE2') + self.assertEqual(traits, dict(i=A.i)) + + # This passes, but it shouldn't because I am replicating a bug in + # traits. + traits = a.traits(config_key=lambda v: True) + self.assertEqual(traits, dict(i=A.i, f=A.f, j=A.j)) + + + def test_init(self): + class A(HasTraits): + i = Int() + x = Float() + a = A(i=1, x=10.0) + self.assertEqual(a.i, 1) + self.assertEqual(a.x, 10.0) + + def test_positional_args(self): + class A(HasTraits): + i = Int(0) + def __init__(self, i): + super(A, self).__init__() + self.i = i + + a = A(5) + self.assertEqual(a.i, 5) + # should raise TypeError if no positional arg given + self.assertRaises(TypeError, A) + +#----------------------------------------------------------------------------- +# Tests for specific trait types +#----------------------------------------------------------------------------- + + +class TestType(TestCase): + + def test_default(self): + + class B(object): pass + class A(HasTraits): + klass = Type(allow_none=True) + + a = A() + self.assertEqual(a.klass, object) + + a.klass = B + self.assertEqual(a.klass, B) + self.assertRaises(TraitError, setattr, a, 'klass', 10) + + def test_default_options(self): + + class B(object): pass + class C(B): pass + class A(HasTraits): + # Different possible combinations of options for default_value + # and klass. default_value=None is only valid with allow_none=True. + k1 = Type() + k2 = Type(None, allow_none=True) + k3 = Type(B) + k4 = Type(klass=B) + k5 = Type(default_value=None, klass=B, allow_none=True) + k6 = Type(default_value=C, klass=B) + + self.assertIs(A.k1.default_value, object) + self.assertIs(A.k1.klass, object) + self.assertIs(A.k2.default_value, None) + self.assertIs(A.k2.klass, object) + self.assertIs(A.k3.default_value, B) + self.assertIs(A.k3.klass, B) + self.assertIs(A.k4.default_value, B) + self.assertIs(A.k4.klass, B) + self.assertIs(A.k5.default_value, None) + self.assertIs(A.k5.klass, B) + self.assertIs(A.k6.default_value, C) + self.assertIs(A.k6.klass, B) + + a = A() + self.assertIs(a.k1, object) + self.assertIs(a.k2, None) + self.assertIs(a.k3, B) + self.assertIs(a.k4, B) + self.assertIs(a.k5, None) + self.assertIs(a.k6, C) + + def test_value(self): + + class B(object): pass + class C(object): pass + class A(HasTraits): + klass = Type(B) + + a = A() + self.assertEqual(a.klass, B) + self.assertRaises(TraitError, setattr, a, 'klass', C) + self.assertRaises(TraitError, setattr, a, 'klass', object) + a.klass = B + + def test_allow_none(self): + + class B(object): pass + class C(B): pass + class A(HasTraits): + klass = Type(B) + + a = A() + self.assertEqual(a.klass, B) + self.assertRaises(TraitError, setattr, a, 'klass', None) + a.klass = C + self.assertEqual(a.klass, C) + + def test_validate_klass(self): + + class A(HasTraits): + klass = Type('no strings allowed') + + self.assertRaises(ImportError, A) + + class A(HasTraits): + klass = Type('rub.adub.Duck') + + self.assertRaises(ImportError, A) + + def test_validate_default(self): + + class B(object): pass + class A(HasTraits): + klass = Type('bad default', B) + + self.assertRaises(ImportError, A) + + class C(HasTraits): + klass = Type(None, B) + + self.assertRaises(TraitError, getattr, C(), 'klass') + + def test_str_klass(self): + + class A(HasTraits): + klass = Type('ipython_genutils.ipstruct.Struct') + + from ipython_genutils.ipstruct import Struct + a = A() + a.klass = Struct + self.assertEqual(a.klass, Struct) + + self.assertRaises(TraitError, setattr, a, 'klass', 10) + + def test_set_str_klass(self): + + class A(HasTraits): + klass = Type() + + a = A(klass='ipython_genutils.ipstruct.Struct') + from ipython_genutils.ipstruct import Struct + self.assertEqual(a.klass, Struct) + +class TestInstance(TestCase): + + def test_basic(self): + class Foo(object): pass + class Bar(Foo): pass + class Bah(object): pass + + class A(HasTraits): + inst = Instance(Foo, allow_none=True) + + a = A() + self.assertTrue(a.inst is None) + a.inst = Foo() + self.assertTrue(isinstance(a.inst, Foo)) + a.inst = Bar() + self.assertTrue(isinstance(a.inst, Foo)) + self.assertRaises(TraitError, setattr, a, 'inst', Foo) + self.assertRaises(TraitError, setattr, a, 'inst', Bar) + self.assertRaises(TraitError, setattr, a, 'inst', Bah()) + + def test_default_klass(self): + class Foo(object): pass + class Bar(Foo): pass + class Bah(object): pass + + class FooInstance(Instance): + klass = Foo + + class A(HasTraits): + inst = FooInstance(allow_none=True) + + a = A() + self.assertTrue(a.inst is None) + a.inst = Foo() + self.assertTrue(isinstance(a.inst, Foo)) + a.inst = Bar() + self.assertTrue(isinstance(a.inst, Foo)) + self.assertRaises(TraitError, setattr, a, 'inst', Foo) + self.assertRaises(TraitError, setattr, a, 'inst', Bar) + self.assertRaises(TraitError, setattr, a, 'inst', Bah()) + + def test_unique_default_value(self): + class Foo(object): pass + class A(HasTraits): + inst = Instance(Foo,(),{}) + + a = A() + b = A() + self.assertTrue(a.inst is not b.inst) + + def test_args_kw(self): + class Foo(object): + def __init__(self, c): self.c = c + class Bar(object): pass + class Bah(object): + def __init__(self, c, d): + self.c = c; self.d = d + + class A(HasTraits): + inst = Instance(Foo, (10,)) + a = A() + self.assertEqual(a.inst.c, 10) + + class B(HasTraits): + inst = Instance(Bah, args=(10,), kw=dict(d=20)) + b = B() + self.assertEqual(b.inst.c, 10) + self.assertEqual(b.inst.d, 20) + + class C(HasTraits): + inst = Instance(Foo, allow_none=True) + c = C() + self.assertTrue(c.inst is None) + + def test_bad_default(self): + class Foo(object): pass + + class A(HasTraits): + inst = Instance(Foo) + + a = A() + with self.assertRaises(TraitError): + a.inst + + def test_instance(self): + class Foo(object): pass + + def inner(): + class A(HasTraits): + inst = Instance(Foo()) + + self.assertRaises(TraitError, inner) + + +class TestThis(TestCase): + + def test_this_class(self): + class Foo(HasTraits): + this = This() + + f = Foo() + self.assertEqual(f.this, None) + g = Foo() + f.this = g + self.assertEqual(f.this, g) + self.assertRaises(TraitError, setattr, f, 'this', 10) + + def test_this_inst(self): + class Foo(HasTraits): + this = This() + + f = Foo() + f.this = Foo() + self.assertTrue(isinstance(f.this, Foo)) + + def test_subclass(self): + class Foo(HasTraits): + t = This() + class Bar(Foo): + pass + f = Foo() + b = Bar() + f.t = b + b.t = f + self.assertEqual(f.t, b) + self.assertEqual(b.t, f) + + def test_subclass_override(self): + class Foo(HasTraits): + t = This() + class Bar(Foo): + t = This() + f = Foo() + b = Bar() + f.t = b + self.assertEqual(f.t, b) + self.assertRaises(TraitError, setattr, b, 't', f) + + def test_this_in_container(self): + + class Tree(HasTraits): + value = Unicode() + leaves = List(This()) + + tree = Tree( + value='foo', + leaves=[Tree(value='bar'), Tree(value='buzz')] + ) + + with self.assertRaises(TraitError): + tree.leaves = [1, 2] + +class TraitTestBase(TestCase): + """A best testing class for basic trait types.""" + + def assign(self, value): + self.obj.value = value + + def coerce(self, value): + return value + + def test_good_values(self): + if hasattr(self, '_good_values'): + for value in self._good_values: + self.assign(value) + self.assertEqual(self.obj.value, self.coerce(value)) + + def test_bad_values(self): + if hasattr(self, '_bad_values'): + for value in self._bad_values: + try: + self.assertRaises(TraitError, self.assign, value) + except AssertionError: + assert False, value + + def test_default_value(self): + if hasattr(self, '_default_value'): + self.assertEqual(self._default_value, self.obj.value) + + def test_allow_none(self): + if (hasattr(self, '_bad_values') and hasattr(self, '_good_values') and + None in self._bad_values): + trait=self.obj.traits()['value'] + try: + trait.allow_none = True + self._bad_values.remove(None) + #skip coerce. Allow None casts None to None. + self.assign(None) + self.assertEqual(self.obj.value,None) + self.test_good_values() + self.test_bad_values() + finally: + #tear down + trait.allow_none = False + self._bad_values.append(None) + + def tearDown(self): + # restore default value after tests, if set + if hasattr(self, '_default_value'): + self.obj.value = self._default_value + + +class AnyTrait(HasTraits): + + value = Any() + +class AnyTraitTest(TraitTestBase): + + obj = AnyTrait() + + _default_value = None + _good_values = [10.0, 'ten', [10], {'ten': 10},(10,), None, 1j] + _bad_values = [] + +class UnionTrait(HasTraits): + + value = Union([Type(), Bool()]) + +class UnionTraitTest(TraitTestBase): + + obj = UnionTrait(value='ipython_genutils.ipstruct.Struct') + _good_values = [int, float, True] + _bad_values = [[], (0,), 1j] + +class CallableTrait(HasTraits): + + value = Callable() + +class CallableTraitTest(TraitTestBase): + + obj = CallableTrait(value=lambda x: type(x)) + _good_values = [int, sorted, lambda x: print(x)] + _bad_values = [[], 1, ''] + +class OrTrait(HasTraits): + + value = Bool() | Unicode() + +class OrTraitTest(TraitTestBase): + + obj = OrTrait() + _good_values = [True, False, 'ten'] + _bad_values = [[], (0,), 1j] + +class IntTrait(HasTraits): + + value = Int(99, min=-100) + +class TestInt(TraitTestBase): + + obj = IntTrait() + _default_value = 99 + _good_values = [10, -10] + _bad_values = ['ten', [10], {'ten': 10}, (10,), None, 1j, + 10.1, -10.1, '10L', '-10L', '10.1', '-10.1', + '10', '-10', -200] + + +class CIntTrait(HasTraits): + value = CInt('5') + +class TestCInt(TraitTestBase): + obj = CIntTrait() + + _default_value = 5 + _good_values = ['10', '-10', 10, 10.0, -10.0, 10.1] + _bad_values = ['ten', [10], {'ten': 10},(10,), + None, 1j, '10.1'] + + def coerce(self, n): + return int(n) + + +class MinBoundCIntTrait(HasTraits): + value = CInt('5', min=3) + +class TestMinBoundCInt(TestCInt): + obj = MinBoundCIntTrait() + + _default_value = 5 + _good_values = [3, 3.0, '3'] + _bad_values = [2.6, 2, -3, -3.0] + + +class LongTrait(HasTraits): + + value = Long(99) + +class TestLong(TraitTestBase): + + obj = LongTrait() + + _default_value = 99 + _good_values = [10, -10] + _bad_values = ['ten', [10], {'ten': 10},(10,), + None, 1j, 10.1, -10.1, '10', '-10', '10L', '-10L', '10.1', + '-10.1'] + + +class MinBoundLongTrait(HasTraits): + value = Long(99, min=5) + +class TestMinBoundLong(TraitTestBase): + obj = MinBoundLongTrait() + + _default_value = 99 + _good_values = [5, 10] + _bad_values = [4, -10] + + +class MaxBoundLongTrait(HasTraits): + value = Long(5, max=10) + +class TestMaxBoundLong(TraitTestBase): + obj = MaxBoundLongTrait() + + _default_value = 5 + _good_values = [10, -2] + _bad_values = [11, 20] + + +class CLongTrait(HasTraits): + value = CLong('5') + +class TestCLong(TraitTestBase): + obj = CLongTrait() + + _default_value = 5 + _good_values = ['10', '-10', 10, 10.0, -10.0, 10.1] + _bad_values = ['ten', [10], {'ten': 10},(10,), + None, 1j, '10.1'] + + def coerce(self, n): + return int(n) + + +class MaxBoundCLongTrait(HasTraits): + value = CLong('5', max=10) + +class TestMaxBoundCLong(TestCLong): + obj = MaxBoundCLongTrait() + + _default_value = 5 + _good_values = [10, '10', 10.3] + _bad_values = [11.0, '11'] + + +class IntegerTrait(HasTraits): + value = Integer(1) + +class TestInteger(TestLong): + obj = IntegerTrait() + _default_value = 1 + + def coerce(self, n): + return int(n) + + +class MinBoundIntegerTrait(HasTraits): + value = Integer(5, min=3) + +class TestMinBoundInteger(TraitTestBase): + obj = MinBoundIntegerTrait() + + _default_value = 5 + _good_values = 3, 20 + _bad_values = [2, -10] + + +class MaxBoundIntegerTrait(HasTraits): + value = Integer(1, max=3) + +class TestMaxBoundInteger(TraitTestBase): + obj = MaxBoundIntegerTrait() + + _default_value = 1 + _good_values = 3, -2 + _bad_values = [4, 10] + + +class FloatTrait(HasTraits): + + value = Float(99.0, max=200.0) + +class TestFloat(TraitTestBase): + + obj = FloatTrait() + + _default_value = 99.0 + _good_values = [10, -10, 10.1, -10.1] + _bad_values = ['ten', [10], {'ten': 10}, (10,), None, + 1j, '10', '-10', '10L', '-10L', '10.1', '-10.1', 201.0] + + +class CFloatTrait(HasTraits): + + value = CFloat('99.0', max=200.0) + +class TestCFloat(TraitTestBase): + + obj = CFloatTrait() + + _default_value = 99.0 + _good_values = [10, 10.0, 10.5, '10.0', '10', '-10'] + _bad_values = ['ten', [10], {'ten': 10}, (10,), None, 1j, + 200.1, '200.1'] + + def coerce(self, v): + return float(v) + + +class ComplexTrait(HasTraits): + + value = Complex(99.0-99.0j) + +class TestComplex(TraitTestBase): + + obj = ComplexTrait() + + _default_value = 99.0-99.0j + _good_values = [10, -10, 10.1, -10.1, 10j, 10+10j, 10-10j, + 10.1j, 10.1+10.1j, 10.1-10.1j] + _bad_values = ['10L', '-10L', 'ten', [10], {'ten': 10},(10,), None] + + +class BytesTrait(HasTraits): + + value = Bytes(b'string') + +class TestBytes(TraitTestBase): + + obj = BytesTrait() + + _default_value = b'string' + _good_values = [b'10', b'-10', b'10L', + b'-10L', b'10.1', b'-10.1', b'string'] + _bad_values = [10, -10, 10.1, -10.1, 1j, [10], + ['ten'],{'ten': 10},(10,), None, 'string'] + + +class UnicodeTrait(HasTraits): + + value = Unicode('unicode') + + +class TestUnicode(TraitTestBase): + + obj = UnicodeTrait() + + _default_value = 'unicode' + _good_values = ['10', '-10', '10L', '-10L', '10.1', + '-10.1', '', 'string', "€", b"bytestring"] + _bad_values = [10, -10, 10.1, -10.1, 1j, + [10], ['ten'], {'ten': 10},(10,), None] + + def coerce(self, v): + return cast_unicode(v) + + +class ObjectNameTrait(HasTraits): + value = ObjectName("abc") + +class TestObjectName(TraitTestBase): + obj = ObjectNameTrait() + + _default_value = "abc" + _good_values = ["a", "gh", "g9", "g_", "_G", "a345_"] + _bad_values = [1, "", "€", "9g", "!", "#abc", "aj@", "a.b", "a()", "a[0]", + None, object(), object] + _good_values.append("þ") # þ=1 is valid in Python 3 (PEP 3131). + + +class DottedObjectNameTrait(HasTraits): + value = DottedObjectName("a.b") + +class TestDottedObjectName(TraitTestBase): + obj = DottedObjectNameTrait() + + _default_value = "a.b" + _good_values = ["A", "y.t", "y765.__repr__", "os.path.join"] + _bad_values = [1, "abc.€", "_.@", ".", ".abc", "abc.", ".abc.", None] + + _good_values.append("t.þ") + + +class TCPAddressTrait(HasTraits): + value = TCPAddress() + +class TestTCPAddress(TraitTestBase): + + obj = TCPAddressTrait() + + _default_value = ('127.0.0.1',0) + _good_values = [('localhost',0),('192.168.0.1',1000),('www.google.com',80)] + _bad_values = [(0,0),('localhost',10.0),('localhost',-1), None] + + +class ListTrait(HasTraits): + + value = List(Int()) + + +class TestList(TraitTestBase): + + obj = ListTrait() + + _default_value = [] + _good_values = [[], [1], list(range(10)), (1,2)] + _bad_values = [10, [1,'a'], 'a'] + + def coerce(self, value): + if value is not None: + value = list(value) + return value + + +class Foo(object): + pass + +class NoneInstanceListTrait(HasTraits): + + value = List(Instance(Foo)) + +class TestNoneInstanceList(TraitTestBase): + + obj = NoneInstanceListTrait() + + _default_value = [] + _good_values = [[Foo(), Foo()], []] + _bad_values = [[None], [Foo(), None]] + + +class InstanceListTrait(HasTraits): + + value = List(Instance(__name__+'.Foo')) + +class TestInstanceList(TraitTestBase): + + obj = InstanceListTrait() + + def test_klass(self): + """Test that the instance klass is properly assigned.""" + self.assertIs(self.obj.traits()['value']._trait.klass, Foo) + + _default_value = [] + _good_values = [[Foo(), Foo()], []] + _bad_values = [['1', 2,], '1', [Foo], None] + +class UnionListTrait(HasTraits): + + value = List(Int() | Bool()) + +class TestUnionListTrait(TraitTestBase): + + obj = UnionListTrait() + + _default_value = [] + _good_values = [[True, 1], [False, True]] + _bad_values = [[1, 'True'], False] + + +class LenListTrait(HasTraits): + + value = List(Int(), [0], minlen=1, maxlen=2) + +class TestLenList(TraitTestBase): + + obj = LenListTrait() + + _default_value = [0] + _good_values = [[1], [1,2], (1,2)] + _bad_values = [10, [1,'a'], 'a', [], list(range(3))] + + def coerce(self, value): + if value is not None: + value = list(value) + return value + +class TupleTrait(HasTraits): + + value = Tuple(Int(allow_none=True), default_value=(1,)) + +class TestTupleTrait(TraitTestBase): + + obj = TupleTrait() + + _default_value = (1,) + _good_values = [(1,), (0,), [1]] + _bad_values = [10, (1, 2), ('a'), (), None] + + def coerce(self, value): + if value is not None: + value = tuple(value) + return value + + def test_invalid_args(self): + self.assertRaises(TypeError, Tuple, 5) + self.assertRaises(TypeError, Tuple, default_value='hello') + t = Tuple(Int(), CBytes(), default_value=(1,5)) + +class LooseTupleTrait(HasTraits): + + value = Tuple((1,2,3)) + +class TestLooseTupleTrait(TraitTestBase): + + obj = LooseTupleTrait() + + _default_value = (1,2,3) + _good_values = [(1,), [1], (0,), tuple(range(5)), tuple('hello'), ('a',5), ()] + _bad_values = [10, 'hello', {}, None] + + def coerce(self, value): + if value is not None: + value = tuple(value) + return value + + def test_invalid_args(self): + self.assertRaises(TypeError, Tuple, 5) + self.assertRaises(TypeError, Tuple, default_value='hello') + t = Tuple(Int(), CBytes(), default_value=(1,5)) + + +class MultiTupleTrait(HasTraits): + + value = Tuple(Int(), Bytes(), default_value=[99,b'bottles']) + +class TestMultiTuple(TraitTestBase): + + obj = MultiTupleTrait() + + _default_value = (99,b'bottles') + _good_values = [(1,b'a'), (2,b'b')] + _bad_values = ((),10, b'a', (1,b'a',3), (b'a',1), (1, 'a')) + + +@pytest.mark.parametrize( + "Trait", (List, Tuple, Set, Dict, Integer, Unicode,), +) +def test_allow_none_default_value(Trait): + class C(HasTraits): + t = Trait(default_value=None, allow_none=True) + + # test default value + c = C() + assert c.t is None + + # and in constructor + c = C(t=None) + assert c.t is None + + +@pytest.mark.parametrize( + "Trait, default_value", + ((List, []), (Tuple, ()), (Set, set()), (Dict, {}), (Integer, 0), (Unicode, "")), +) +def test_default_value(Trait, default_value): + class C(HasTraits): + t = Trait() + + # test default value + c = C() + assert type(c.t) is type(default_value) + assert c.t == default_value + + +@pytest.mark.parametrize( + "Trait, default_value", + ((List, []), (Tuple, ()), (Set, set())), +) +def test_subclass_default_value(Trait, default_value): + """Test deprecated default_value=None behavior for Container subclass traits""" + + class SubclassTrait(Trait): + def __init__(self, default_value=None): + super().__init__(default_value=default_value) + + class C(HasTraits): + t = SubclassTrait() + + # test default value + c = C() + assert type(c.t) is type(default_value) + assert c.t == default_value + + +class CRegExpTrait(HasTraits): + + value = CRegExp(r'') + + +class TestCRegExp(TraitTestBase): + + def coerce(self, value): + return re.compile(value) + + obj = CRegExpTrait() + + _default_value = re.compile(r'') + _good_values = [r'\d+', re.compile(r'\d+')] + _bad_values = ['(', None, ()] + +class DictTrait(HasTraits): + value = Dict() + +def test_dict_assignment(): + d = dict() + c = DictTrait() + c.value = d + d['a'] = 5 + assert d == c.value + assert c.value is d + + +class UniformlyValueValidatedDictTrait(HasTraits): + + value = Dict(trait=Unicode(), + default_value={'foo': '1'}) + + +class TestInstanceUniformlyValueValidatedDict(TraitTestBase): + + obj = UniformlyValueValidatedDictTrait() + + _default_value = {'foo': '1'} + _good_values = [{'foo': '0', 'bar': '1'}] + _bad_values = [{'foo': 0, 'bar': '1'}] + + +class NonuniformlyValueValidatedDictTrait(HasTraits): + + value = Dict(traits={'foo': Int()}, + default_value={'foo': 1}) + + +class TestInstanceNonuniformlyValueValidatedDict(TraitTestBase): + + obj = NonuniformlyValueValidatedDictTrait() + + _default_value = {'foo': 1} + _good_values = [{'foo': 0, 'bar': '1'}, {'foo': 0, 'bar': 1}] + _bad_values = [{'foo': '0', 'bar': '1'}] + + +class KeyValidatedDictTrait(HasTraits): + + value = Dict(key_trait=Unicode(), + default_value={'foo': '1'}) + + +class TestInstanceKeyValidatedDict(TraitTestBase): + + obj = KeyValidatedDictTrait() + + _default_value = {'foo': '1'} + _good_values = [{'foo': '0', 'bar': '1'}] + _bad_values = [{'foo': '0', 0: '1'}] + + +class FullyValidatedDictTrait(HasTraits): + + value = Dict(trait=Unicode(), + key_trait=Unicode(), + traits={'foo': Int()}, + default_value={'foo': 1}) + + +class TestInstanceFullyValidatedDict(TraitTestBase): + + obj = FullyValidatedDictTrait() + + _default_value = {'foo': 1} + _good_values = [{'foo': 0, 'bar': '1'}, {'foo': 1, 'bar': '2'}] + _bad_values = [{'foo': 0, 'bar': 1}, {'foo': '0', 'bar': '1'}, {'foo': 0, 0: '1'}] + + +def test_dict_default_value(): + """Check that the `{}` default value of the Dict traitlet constructor is + actually copied.""" + + class Foo(HasTraits): + d1 = Dict() + d2 = Dict() + + foo = Foo() + assert foo.d1 == {} + assert foo.d2 == {} + assert foo.d1 is not foo.d2 + + +class TestValidationHook(TestCase): + + def test_parity_trait(self): + """Verify that the early validation hook is effective""" + + class Parity(HasTraits): + + value = Int(0) + parity = Enum(['odd', 'even'], default_value='even') + + @validate('value') + def _value_validate(self, proposal): + value = proposal['value'] + if self.parity == 'even' and value % 2: + raise TraitError('Expected an even number') + if self.parity == 'odd' and (value % 2 == 0): + raise TraitError('Expected an odd number') + return value + + u = Parity() + u.parity = 'odd' + u.value = 1 # OK + with self.assertRaises(TraitError): + u.value = 2 # Trait Error + + u.parity = 'even' + u.value = 2 # OK + + def test_multiple_validate(self): + """Verify that we can register the same validator to multiple names""" + + class OddEven(HasTraits): + + odd = Int(1) + even = Int(0) + + @validate('odd', 'even') + def check_valid(self, proposal): + if proposal['trait'].name == 'odd' and not proposal['value'] % 2: + raise TraitError('odd should be odd') + if proposal['trait'].name == 'even' and proposal['value'] % 2: + raise TraitError('even should be even') + + u = OddEven() + u.odd = 3 # OK + with self.assertRaises(TraitError): + u.odd = 2 # Trait Error + + u.even = 2 # OK + with self.assertRaises(TraitError): + u.even = 3 # Trait Error + + + +class TestLink(TestCase): + + def test_connect_same(self): + """Verify two traitlets of the same type can be linked together using link.""" + + # Create two simple classes with Int traitlets. + class A(HasTraits): + value = Int() + a = A(value=9) + b = A(value=8) + + # Conenct the two classes. + c = link((a, 'value'), (b, 'value')) + + # Make sure the values are the same at the point of linking. + self.assertEqual(a.value, b.value) + + # Change one of the values to make sure they stay in sync. + a.value = 5 + self.assertEqual(a.value, b.value) + b.value = 6 + self.assertEqual(a.value, b.value) + + def test_link_different(self): + """Verify two traitlets of different types can be linked together using link.""" + + # Create two simple classes with Int traitlets. + class A(HasTraits): + value = Int() + class B(HasTraits): + count = Int() + a = A(value=9) + b = B(count=8) + + # Conenct the two classes. + c = link((a, 'value'), (b, 'count')) + + # Make sure the values are the same at the point of linking. + self.assertEqual(a.value, b.count) + + # Change one of the values to make sure they stay in sync. + a.value = 5 + self.assertEqual(a.value, b.count) + b.count = 4 + self.assertEqual(a.value, b.count) + + def test_unlink_link(self): + """Verify two linked traitlets can be unlinked and relinked.""" + + # Create two simple classes with Int traitlets. + class A(HasTraits): + value = Int() + a = A(value=9) + b = A(value=8) + + # Connect the two classes. + c = link((a, 'value'), (b, 'value')) + a.value = 4 + c.unlink() + + # Change one of the values to make sure they don't stay in sync. + a.value = 5 + self.assertNotEqual(a.value, b.value) + c.link() + self.assertEqual(a.value, b.value) + a.value += 1 + self.assertEqual(a.value, b.value) + + def test_callbacks(self): + """Verify two linked traitlets have their callbacks called once.""" + + # Create two simple classes with Int traitlets. + class A(HasTraits): + value = Int() + class B(HasTraits): + count = Int() + a = A(value=9) + b = B(count=8) + + # Register callbacks that count. + callback_count = [] + def a_callback(name, old, new): + callback_count.append('a') + a.on_trait_change(a_callback, 'value') + def b_callback(name, old, new): + callback_count.append('b') + b.on_trait_change(b_callback, 'count') + + # Connect the two classes. + c = link((a, 'value'), (b, 'count')) + + # Make sure b's count was set to a's value once. + self.assertEqual(''.join(callback_count), 'b') + del callback_count[:] + + # Make sure a's value was set to b's count once. + b.count = 5 + self.assertEqual(''.join(callback_count), 'ba') + del callback_count[:] + + # Make sure b's count was set to a's value once. + a.value = 4 + self.assertEqual(''.join(callback_count), 'ab') + del callback_count[:] + + def test_tranform(self): + """Test transform link.""" + + # Create two simple classes with Int traitlets. + class A(HasTraits): + value = Int() + a = A(value=9) + b = A(value=8) + + # Conenct the two classes. + c = link((a, 'value'), (b, 'value'), + transform=(lambda x: 2 * x, lambda x: int(x / 2.))) + + # Make sure the values are correct at the point of linking. + self.assertEqual(b.value, 2 * a.value) + + # Change one the value of the source and check that it modifies the target. + a.value = 5 + self.assertEqual(b.value, 10) + # Change one the value of the target and check that it modifies the + # source. + b.value = 6 + self.assertEqual(a.value, 3) + + def test_link_broken_at_source(self): + class MyClass(HasTraits): + i = Int() + j = Int() + + @observe("j") + def another_update(self, change): + self.i = change.new * 2 + + mc = MyClass() + l = link((mc, "i"), (mc, "j")) + self.assertRaises(TraitError, setattr, mc, 'i', 2) + + def test_link_broken_at_target(self): + class MyClass(HasTraits): + i =Int() + j = Int() + + @observe("i") + def another_update(self, change): + self.j = change.new * 2 + + mc = MyClass() + l = link((mc, "i"), (mc, "j")) + self.assertRaises(TraitError, setattr, mc, 'j', 2) + +class TestDirectionalLink(TestCase): + def test_connect_same(self): + """Verify two traitlets of the same type can be linked together using directional_link.""" + + # Create two simple classes with Int traitlets. + class A(HasTraits): + value = Int() + a = A(value=9) + b = A(value=8) + + # Conenct the two classes. + c = directional_link((a, 'value'), (b, 'value')) + + # Make sure the values are the same at the point of linking. + self.assertEqual(a.value, b.value) + + # Change one the value of the source and check that it synchronizes the target. + a.value = 5 + self.assertEqual(b.value, 5) + # Change one the value of the target and check that it has no impact on the source + b.value = 6 + self.assertEqual(a.value, 5) + + def test_tranform(self): + """Test transform link.""" + + # Create two simple classes with Int traitlets. + class A(HasTraits): + value = Int() + a = A(value=9) + b = A(value=8) + + # Conenct the two classes. + c = directional_link((a, 'value'), (b, 'value'), lambda x: 2 * x) + + # Make sure the values are correct at the point of linking. + self.assertEqual(b.value, 2 * a.value) + + # Change one the value of the source and check that it modifies the target. + a.value = 5 + self.assertEqual(b.value, 10) + # Change one the value of the target and check that it has no impact on the source + b.value = 6 + self.assertEqual(a.value, 5) + + def test_link_different(self): + """Verify two traitlets of different types can be linked together using link.""" + + # Create two simple classes with Int traitlets. + class A(HasTraits): + value = Int() + class B(HasTraits): + count = Int() + a = A(value=9) + b = B(count=8) + + # Conenct the two classes. + c = directional_link((a, 'value'), (b, 'count')) + + # Make sure the values are the same at the point of linking. + self.assertEqual(a.value, b.count) + + # Change one the value of the source and check that it synchronizes the target. + a.value = 5 + self.assertEqual(b.count, 5) + # Change one the value of the target and check that it has no impact on the source + b.value = 6 + self.assertEqual(a.value, 5) + + def test_unlink_link(self): + """Verify two linked traitlets can be unlinked and relinked.""" + + # Create two simple classes with Int traitlets. + class A(HasTraits): + value = Int() + a = A(value=9) + b = A(value=8) + + # Connect the two classes. + c = directional_link((a, 'value'), (b, 'value')) + a.value = 4 + c.unlink() + + # Change one of the values to make sure they don't stay in sync. + a.value = 5 + self.assertNotEqual(a.value, b.value) + c.link() + self.assertEqual(a.value, b.value) + a.value += 1 + self.assertEqual(a.value, b.value) + +class Pickleable(HasTraits): + + i = Int() + @observe('i') + def _i_changed(self, change): pass + @validate('i') + def _i_validate(self, commit): + return commit['value'] + + j = Int() + + def __init__(self): + with self.hold_trait_notifications(): + self.i = 1 + self.on_trait_change(self._i_changed, 'i') + +def test_pickle_hastraits(): + c = Pickleable() + for protocol in range(pickle.HIGHEST_PROTOCOL + 1): + p = pickle.dumps(c, protocol) + c2 = pickle.loads(p) + assert c2.i == c.i + assert c2.j == c.j + + c.i = 5 + for protocol in range(pickle.HIGHEST_PROTOCOL + 1): + p = pickle.dumps(c, protocol) + c2 = pickle.loads(p) + assert c2.i == c.i + assert c2.j == c.j + + +def test_hold_trait_notifications(): + changes = [] + + class Test(HasTraits): + a = Integer(0) + b = Integer(0) + + def _a_changed(self, name, old, new): + changes.append((old, new)) + + def _b_validate(self, value, trait): + if value != 0: + raise TraitError('Only 0 is a valid value') + return value + + # Test context manager and nesting + t = Test() + with t.hold_trait_notifications(): + with t.hold_trait_notifications(): + t.a = 1 + assert t.a == 1 + assert changes == [] + t.a = 2 + assert t.a == 2 + with t.hold_trait_notifications(): + t.a = 3 + assert t.a == 3 + assert changes == [] + t.a = 4 + assert t.a == 4 + assert changes == [] + t.a = 4 + assert t.a == 4 + assert changes == [] + + assert changes == [(0, 4)] + # Test roll-back + try: + with t.hold_trait_notifications(): + t.b = 1 # raises a Trait error + except: + pass + assert t.b == 0 + + +class RollBack(HasTraits): + bar = Int() + def _bar_validate(self, value, trait): + if value: + raise TraitError('foobar') + return value + + +class TestRollback(TestCase): + + def test_roll_back(self): + + def assign_rollback(): + RollBack(bar=1) + + self.assertRaises(TraitError, assign_rollback) + + +class CacheModification(HasTraits): + foo = Int() + bar = Int() + + def _bar_validate(self, value, trait): + self.foo = value + return value + + def _foo_validate(self, value, trait): + self.bar = value + return value + + +def test_cache_modification(): + CacheModification(foo=1) + CacheModification(bar=1) + + +class OrderTraits(HasTraits): + notified = Dict() + + a = Unicode() + b = Unicode() + c = Unicode() + d = Unicode() + e = Unicode() + f = Unicode() + g = Unicode() + h = Unicode() + i = Unicode() + j = Unicode() + k = Unicode() + l = Unicode() + + def _notify(self, name, old, new): + """check the value of all traits when each trait change is triggered + + This verifies that the values are not sensitive + to dict ordering when loaded from kwargs + """ + # check the value of the other traits + # when a given trait change notification fires + self.notified[name] = { + c: getattr(self, c) for c in 'abcdefghijkl' + } + + def __init__(self, **kwargs): + self.on_trait_change(self._notify) + super(OrderTraits, self).__init__(**kwargs) + +def test_notification_order(): + d = {c:c for c in 'abcdefghijkl'} + obj = OrderTraits() + assert obj.notified == {} + obj = OrderTraits(**d) + notifications = { + c: d for c in 'abcdefghijkl' + } + assert obj.notified == notifications + + + +### +# Traits for Forward Declaration Tests +### +class ForwardDeclaredInstanceTrait(HasTraits): + + value = ForwardDeclaredInstance('ForwardDeclaredBar', allow_none=True) + +class ForwardDeclaredTypeTrait(HasTraits): + + value = ForwardDeclaredType('ForwardDeclaredBar', allow_none=True) + +class ForwardDeclaredInstanceListTrait(HasTraits): + + value = List(ForwardDeclaredInstance('ForwardDeclaredBar')) + +class ForwardDeclaredTypeListTrait(HasTraits): + + value = List(ForwardDeclaredType('ForwardDeclaredBar')) +### +# End Traits for Forward Declaration Tests +### + +### +# Classes for Forward Declaration Tests +### +class ForwardDeclaredBar(object): + pass + +class ForwardDeclaredBarSub(ForwardDeclaredBar): + pass +### +# End Classes for Forward Declaration Tests +### + +### +# Forward Declaration Tests +### +class TestForwardDeclaredInstanceTrait(TraitTestBase): + + obj = ForwardDeclaredInstanceTrait() + _default_value = None + _good_values = [None, ForwardDeclaredBar(), ForwardDeclaredBarSub()] + _bad_values = ['foo', 3, ForwardDeclaredBar, ForwardDeclaredBarSub] + +class TestForwardDeclaredTypeTrait(TraitTestBase): + + obj = ForwardDeclaredTypeTrait() + _default_value = None + _good_values = [None, ForwardDeclaredBar, ForwardDeclaredBarSub] + _bad_values = ['foo', 3, ForwardDeclaredBar(), ForwardDeclaredBarSub()] + +class TestForwardDeclaredInstanceList(TraitTestBase): + + obj = ForwardDeclaredInstanceListTrait() + + def test_klass(self): + """Test that the instance klass is properly assigned.""" + self.assertIs(self.obj.traits()['value']._trait.klass, ForwardDeclaredBar) + + _default_value = [] + _good_values = [ + [ForwardDeclaredBar(), ForwardDeclaredBarSub()], + [], + ] + _bad_values = [ + ForwardDeclaredBar(), + [ForwardDeclaredBar(), 3, None], + '1', + # Note that this is the type, not an instance. + [ForwardDeclaredBar], + [None], + None, + ] + +class TestForwardDeclaredTypeList(TraitTestBase): + + obj = ForwardDeclaredTypeListTrait() + + def test_klass(self): + """Test that the instance klass is properly assigned.""" + self.assertIs(self.obj.traits()['value']._trait.klass, ForwardDeclaredBar) + + _default_value = [] + _good_values = [ + [ForwardDeclaredBar, ForwardDeclaredBarSub], + [], + ] + _bad_values = [ + ForwardDeclaredBar, + [ForwardDeclaredBar, 3], + '1', + # Note that this is an instance, not the type. + [ForwardDeclaredBar()], + [None], + None, + ] +### +# End Forward Declaration Tests +### + +class TestDynamicTraits(TestCase): + + def setUp(self): + self._notify1 = [] + + def notify1(self, name, old, new): + self._notify1.append((name, old, new)) + + def test_notify_all(self): + + class A(HasTraits): + pass + + a = A() + self.assertTrue(not hasattr(a, 'x')) + self.assertTrue(not hasattr(a, 'y')) + + # Dynamically add trait x. + a.add_traits(x=Int()) + self.assertTrue(hasattr(a, 'x')) + self.assertTrue(isinstance(a, (A, ))) + + # Dynamically add trait y. + a.add_traits(y=Float()) + self.assertTrue(hasattr(a, 'y')) + self.assertTrue(isinstance(a, (A, ))) + self.assertEqual(a.__class__.__name__, A.__name__) + + # Create a new instance and verify that x and y + # aren't defined. + b = A() + self.assertTrue(not hasattr(b, 'x')) + self.assertTrue(not hasattr(b, 'y')) + + # Verify that notification works like normal. + a.on_trait_change(self.notify1) + a.x = 0 + self.assertEqual(len(self._notify1), 0) + a.y = 0.0 + self.assertEqual(len(self._notify1), 0) + a.x = 10 + self.assertTrue(('x', 0, 10) in self._notify1) + a.y = 10.0 + self.assertTrue(('y', 0.0, 10.0) in self._notify1) + self.assertRaises(TraitError, setattr, a, 'x', 'bad string') + self.assertRaises(TraitError, setattr, a, 'y', 'bad string') + self._notify1 = [] + a.on_trait_change(self.notify1, remove=True) + a.x = 20 + a.y = 20.0 + self.assertEqual(len(self._notify1), 0) + + +def test_enum_no_default(): + class C(HasTraits): + t = Enum(['a', 'b']) + + c = C() + c.t = 'a' + assert c.t == 'a' + + c = C() + + with pytest.raises(TraitError): + t = c.t + + c = C(t='b') + assert c.t == 'b' + + +def test_default_value_repr(): + class C(HasTraits): + t = Type('traitlets.HasTraits') + t2 = Type(HasTraits) + n = Integer(0) + lis = List() + d = Dict() + + assert C.t.default_value_repr() == "'traitlets.HasTraits'" + assert C.t2.default_value_repr() == "'traitlets.traitlets.HasTraits'" + assert C.n.default_value_repr() == '0' + assert C.lis.default_value_repr() == '[]' + assert C.d.default_value_repr() == '{}' + + +class TransitionalClass(HasTraits): + + d = Any() + @default('d') + def _d_default(self): + return TransitionalClass + + parent_super = False + calls_super = Integer(0) + + @default('calls_super') + def _calls_super_default(self): + return -1 + + @observe('calls_super') + @observe_compat + def _calls_super_changed(self, change): + self.parent_super = change + + parent_override = False + overrides = Integer(0) + + @observe('overrides') + @observe_compat + def _overrides_changed(self, change): + self.parent_override = change + + +class SubClass(TransitionalClass): + def _d_default(self): + return SubClass + + subclass_super = False + def _calls_super_changed(self, name, old, new): + self.subclass_super = True + super(SubClass, self)._calls_super_changed(name, old, new) + + subclass_override = False + def _overrides_changed(self, name, old, new): + self.subclass_override = True + + +def test_subclass_compat(): + obj = SubClass() + obj.calls_super = 5 + assert obj.parent_super + assert obj.subclass_super + obj.overrides = 5 + assert obj.subclass_override + assert not obj.parent_override + assert obj.d is SubClass + + +class DefinesHandler(HasTraits): + parent_called = False + + trait = Integer() + @observe('trait') + def handler(self, change): + self.parent_called = True + + +class OverridesHandler(DefinesHandler): + child_called = False + + @observe('trait') + def handler(self, change): + self.child_called = True + + +def test_subclass_override_observer(): + obj = OverridesHandler() + obj.trait = 5 + assert obj.child_called + assert not obj.parent_called + + +class DoesntRegisterHandler(DefinesHandler): + child_called = False + + def handler(self, change): + self.child_called = True + + +def test_subclass_override_not_registered(): + """Subclass that overrides observer and doesn't re-register unregisters both""" + obj = DoesntRegisterHandler() + obj.trait = 5 + assert not obj.child_called + assert not obj.parent_called + + +class AddsHandler(DefinesHandler): + child_called = False + + @observe('trait') + def child_handler(self, change): + self.child_called = True + +def test_subclass_add_observer(): + obj = AddsHandler() + obj.trait = 5 + assert obj.child_called + assert obj.parent_called + + +def test_observe_iterables(): + + class C(HasTraits): + i = Integer() + s = Unicode() + + c = C() + recorded = {} + def record(change): + recorded['change'] = change + + # observe with names=set + c.observe(record, names={'i', 's'}) + c.i = 5 + assert recorded['change'].name == 'i' + assert recorded['change'].new == 5 + c.s = 'hi' + assert recorded['change'].name == 's' + assert recorded['change'].new == 'hi' + + # observe with names=custom container with iter, contains + class MyContainer(object): + def __init__(self, container): + self.container = container + + def __iter__(self): + return iter(self.container) + + def __contains__(self, key): + return key in self.container + + c.observe(record, names=MyContainer({'i', 's'})) + c.i = 10 + assert recorded['change'].name == 'i' + assert recorded['change'].new == 10 + c.s = 'ok' + assert recorded['change'].name == 's' + assert recorded['change'].new == 'ok' + + +def test_super_args(): + class SuperRecorder(object): + def __init__(self, *args, **kwargs): + self.super_args = args + self.super_kwargs = kwargs + + class SuperHasTraits(HasTraits, SuperRecorder): + i = Integer() + + obj = SuperHasTraits('a1', 'a2', b=10, i=5, c='x') + assert obj.i == 5 + assert not hasattr(obj, 'b') + assert not hasattr(obj, 'c') + assert obj.super_args == ('a1' , 'a2') + assert obj.super_kwargs == {'b': 10 , 'c': 'x'} + +def test_super_bad_args(): + class SuperHasTraits(HasTraits): + a = Integer() + + w = ["Passing unrecognized arguments"] + with expected_warnings(w): + obj = SuperHasTraits(a=1, b=2) + assert obj.a == 1 + assert not hasattr(obj, 'b') + + +def test_default_mro(): + """Verify that default values follow mro""" + class Base(HasTraits): + trait = Unicode('base') + attr = 'base' + + class A(Base): + pass + + class B(Base): + trait = Unicode('B') + attr = 'B' + + class AB(A, B): + pass + + class BA(B, A): + pass + + assert A().trait == 'base' + assert A().attr == 'base' + assert BA().trait == 'B' + assert BA().attr == 'B' + assert AB().trait == 'B' + assert AB().attr == 'B' + + +def test_cls_self_argument(): + class X(HasTraits): + def __init__(__self, cls, self): + pass + + x = X(cls=None, self=None) + + +def test_override_default(): + class C(HasTraits): + a = Unicode('hard default') + def _a_default(self): + return 'default method' + + C._a_default = lambda self: 'overridden' + c = C() + assert c.a == 'overridden' + +def test_override_default_decorator(): + class C(HasTraits): + a = Unicode('hard default') + @default('a') + def _a_default(self): + return 'default method' + + C._a_default = lambda self: 'overridden' + c = C() + assert c.a == 'overridden' + +def test_override_default_instance(): + class C(HasTraits): + a = Unicode('hard default') + @default('a') + def _a_default(self): + return 'default method' + + c = C() + c._a_default = lambda self: 'overridden' + assert c.a == 'overridden' + + +def test_copy_HasTraits(): + from copy import copy + + class C(HasTraits): + a = Int() + + c = C(a=1) + assert c.a == 1 + + cc = copy(c) + cc.a = 2 + assert cc.a == 2 + assert c.a == 1 + + +def _from_string_test(traittype, s, expected): + """Run a test of trait.from_string""" + if isinstance(traittype, TraitType): + trait = traittype + else: + trait = traittype(allow_none=True) + if isinstance(s, list): + cast = trait.from_string_list + else: + cast = trait.from_string + if type(expected) is type and issubclass(expected, Exception): + with pytest.raises(expected): + value = cast(s) + trait.validate(None, value) + else: + value = cast(s) + assert value == expected + + +@pytest.mark.parametrize( + "s, expected", + [("xyz", "xyz"), ("1", "1"), ('"xx"', "xx"), ("'abc'", "abc"), ("None", None)], +) +def test_unicode_from_string(s, expected): + _from_string_test(Unicode, s, expected) + + +@pytest.mark.parametrize( + "s, expected", + [("xyz", "xyz"), ("1", "1"), ('"xx"', "xx"), ("'abc'", "abc"), ("None", None)], +) +def test_cunicode_from_string(s, expected): + _from_string_test(CUnicode, s, expected) + + +@pytest.mark.parametrize( + "s, expected", + [("xyz", b"xyz"), ("1", b"1"), ('b"xx"', b"xx"), ("b'abc'", b"abc"), ("None", None)], +) +def test_bytes_from_string(s, expected): + _from_string_test(Bytes, s, expected) + + +@pytest.mark.parametrize( + "s, expected", + [("xyz", b"xyz"), ("1", b"1"), ('b"xx"', b"xx"), ("b'abc'", b"abc"), ("None", None)], +) +def test_cbytes_from_string(s, expected): + _from_string_test(CBytes, s, expected) + + +@pytest.mark.parametrize( + "s, expected", + [("x", ValueError), ("1", 1), ("123", 123), ("2.0", ValueError), ("None", None)], +) +def test_int_from_string(s, expected): + _from_string_test(Integer, s, expected) + + +@pytest.mark.parametrize( + "s, expected", + [("x", ValueError), ("1", 1.0), ("123.5", 123.5), ("2.5", 2.5), ("None", None)], +) +def test_float_from_string(s, expected): + _from_string_test(Float, s, expected) + + +@pytest.mark.parametrize( + "s, expected", + [ + ("x", ValueError), + ("1", 1.0), + ("123.5", 123.5), + ("2.5", 2.5), + ("1+2j", 1 + 2j), + ("None", None), + ], +) +def test_complex_from_string(s, expected): + _from_string_test(Complex, s, expected) + + +@pytest.mark.parametrize( + "s, expected", + [ + ("true", True), + ("TRUE", True), + ("1", True), + ("0", False), + ("False", False), + ("false", False), + ("1.0", ValueError), + ("None", None), + ], +) +def test_bool_from_string(s, expected): + _from_string_test(Bool, s, expected) + + +@pytest.mark.parametrize( + "s, expected", + [ + ("{}", {}), + ("1", TraitError), + ("{1: 2}", {1: 2}), + ('{"key": "value"}', {"key": "value"}), + ("x", TraitError), + ("None", None), + ], +) +def test_dict_from_string(s, expected): + _from_string_test(Dict, s, expected) + + +@pytest.mark.parametrize( + "s, expected", + [ + ("[]", []), + ('[1, 2, "x"]', [1, 2, "x"]), + (["1", "x"], ["1", "x"]), + (["None"], None), + ], +) +def test_list_from_string(s, expected): + _from_string_test(List, s, expected) + + +@pytest.mark.parametrize( + "s, expected, value_trait", + [ + (["1", "2", "3"], [1, 2, 3], Integer()), + (["x"], ValueError, Integer()), + (["1", "x"], ["1", "x"], Unicode()), + (["None"], [None], Unicode(allow_none=True)), + (["None"], ["None"], Unicode(allow_none=False)), + ], +) +def test_list_items_from_string(s, expected, value_trait): + _from_string_test(List(value_trait), s, expected) + + +@pytest.mark.parametrize( + "s, expected", + [ + ("[]", set()), + ('[1, 2, "x"]', {1, 2, "x"}), + ('{1, 2, "x"}', {1, 2, "x"}), + (["1", "x"], {"1", "x"}), + (["None"], None), + ], +) +def test_set_from_string(s, expected): + _from_string_test(Set, s, expected) + + +@pytest.mark.parametrize( + "s, expected, value_trait", + [ + (["1", "2", "3"], {1, 2, 3}, Integer()), + (["x"], ValueError, Integer()), + (["1", "x"], {"1", "x"}, Unicode()), + (["None"], {None}, Unicode(allow_none=True)), + ], +) +def test_set_items_from_string(s, expected, value_trait): + _from_string_test(Set(value_trait), s, expected) + + +@pytest.mark.parametrize( + "s, expected", + [ + ("[]", ()), + ("()", ()), + ('[1, 2, "x"]', (1, 2, "x")), + ('(1, 2, "x")', (1, 2, "x")), + (["1", "x"], ("1", "x")), + (["None"], None), + ], +) +def test_tuple_from_string(s, expected): + _from_string_test(Tuple, s, expected) + + +@pytest.mark.parametrize( + "s, expected, value_traits", + [ + (["1", "2", "3"], (1, 2, 3), [Integer(), Integer(), Integer()]), + (["x"], ValueError, [Integer()]), + (["1", "x"], ("1", "x"), [Unicode()]), + (["None"], ("None",), [Unicode(allow_none=False)]), + (["None"], (None,), [Unicode(allow_none=True)]), + ], +) +def test_tuple_items_from_string(s, expected, value_traits): + _from_string_test(Tuple(*value_traits), s, expected) + + +@pytest.mark.parametrize( + "s, expected", + [ + ("x", "x"), + ("mod.submod", "mod.submod"), + ("not an identifier", TraitError), + ("1", "1"), + ("None", None), + ], +) +def test_object_from_string(s, expected): + _from_string_test(DottedObjectName, s, expected) + + +@pytest.mark.parametrize( + "s, expected", + [ + ("127.0.0.1:8000", ("127.0.0.1", 8000)), + ("host.tld:80", ("host.tld", 80)), + ("host:notaport", ValueError), + ("127.0.0.1", ValueError), + ("None", None), + ], +) +def test_tcp_from_string(s, expected): + _from_string_test(TCPAddress, s, expected) diff --git a/.venv/lib/python3.8/site-packages/traitlets/tests/test_traitlets_enum.py b/.venv/lib/python3.8/site-packages/traitlets/tests/test_traitlets_enum.py new file mode 100644 index 00000000..769e830b --- /dev/null +++ b/.venv/lib/python3.8/site-packages/traitlets/tests/test_traitlets_enum.py @@ -0,0 +1,380 @@ +# pylint: disable=missing-docstring, too-few-public-methods +""" +Test the trait-type ``UseEnum``. +""" + +import unittest +import enum +from traitlets import HasTraits, TraitError, Enum, UseEnum, CaselessStrEnum, FuzzyEnum + + +# ----------------------------------------------------------------------------- +# TEST SUPPORT: +# ----------------------------------------------------------------------------- + +class Color(enum.Enum): + red = 1 + green = 2 + blue = 3 + yellow = 4 + +class OtherColor(enum.Enum): + red = 0 + green = 1 + + +class CSColor(enum.Enum): + red = 1 + Green = 2 + BLUE = 3 + YeLLoW = 4 + + +color_choices = 'red Green BLUE YeLLoW'.split() + + +# ----------------------------------------------------------------------------- +# TESTSUITE: +# ----------------------------------------------------------------------------- +class TestUseEnum(unittest.TestCase): + # pylint: disable=invalid-name + + class Example(HasTraits): + color = UseEnum(Color, help="Color enum") + + def test_assign_enum_value(self): + example = self.Example() + example.color = Color.green + self.assertEqual(example.color, Color.green) + + def test_assign_all_enum_values(self): + # pylint: disable=no-member + enum_values = [value for value in Color.__members__.values()] + for value in enum_values: + self.assertIsInstance(value, Color) + example = self.Example() + example.color = value + self.assertEqual(example.color, value) + self.assertIsInstance(value, Color) + + def test_assign_enum_value__with_other_enum_raises_error(self): + example = self.Example() + with self.assertRaises(TraitError): + example.color = OtherColor.green + + def test_assign_enum_name_1(self): + # -- CONVERT: string => Enum value (item) + example = self.Example() + example.color = "red" + self.assertEqual(example.color, Color.red) + + def test_assign_enum_value_name(self): + # -- CONVERT: string => Enum value (item) + # pylint: disable=no-member + enum_names = [enum_val.name for enum_val in Color.__members__.values()] + for value in enum_names: + self.assertIsInstance(value, str) + example = self.Example() + enum_value = Color.__members__.get(value) + example.color = value + self.assertIs(example.color, enum_value) + self.assertEqual(example.color.name, value) + + def test_assign_scoped_enum_value_name(self): + # -- CONVERT: string => Enum value (item) + scoped_names = ["Color.red", "Color.green", "Color.blue", "Color.yellow"] + for value in scoped_names: + example = self.Example() + example.color = value + self.assertIsInstance(example.color, Color) + self.assertEqual(str(example.color), value) + + def test_assign_bad_enum_value_name__raises_error(self): + # -- CONVERT: string => Enum value (item) + bad_enum_names = ["UNKNOWN_COLOR", "RED", "Green", "blue2"] + for value in bad_enum_names: + example = self.Example() + with self.assertRaises(TraitError): + example.color = value + + def test_assign_enum_value_number_1(self): + # -- CONVERT: number => Enum value (item) + example = self.Example() + example.color = 1 # == Color.red.value + example.color = Color.red.value + self.assertEqual(example.color, Color.red) + + def test_assign_enum_value_number(self): + # -- CONVERT: number => Enum value (item) + # pylint: disable=no-member + enum_numbers = [enum_val.value + for enum_val in Color.__members__.values()] + for value in enum_numbers: + self.assertIsInstance(value, int) + example = self.Example() + example.color = value + self.assertIsInstance(example.color, Color) + self.assertEqual(example.color.value, value) + + def test_assign_bad_enum_value_number__raises_error(self): + # -- CONVERT: number => Enum value (item) + bad_numbers = [-1, 0, 5] + for value in bad_numbers: + self.assertIsInstance(value, int) + assert UseEnum(Color).select_by_number(value, None) is None + example = self.Example() + with self.assertRaises(TraitError): + example.color = value + + def test_ctor_without_default_value(self): + # -- IMPLICIT: default_value = Color.red (first enum-value) + class Example2(HasTraits): + color = UseEnum(Color) + + example = Example2() + self.assertEqual(example.color, Color.red) + + def test_ctor_with_default_value_as_enum_value(self): + # -- CONVERT: number => Enum value (item) + class Example2(HasTraits): + color = UseEnum(Color, default_value=Color.green) + + example = Example2() + self.assertEqual(example.color, Color.green) + + + def test_ctor_with_default_value_none_and_not_allow_none(self): + # -- IMPLICIT: default_value = Color.red (first enum-value) + class Example2(HasTraits): + color1 = UseEnum(Color, default_value=None, allow_none=False) + color2 = UseEnum(Color, default_value=None) + example = Example2() + self.assertEqual(example.color1, Color.red) + self.assertEqual(example.color2, Color.red) + + def test_ctor_with_default_value_none_and_allow_none(self): + class Example2(HasTraits): + color1 = UseEnum(Color, default_value=None, allow_none=True) + color2 = UseEnum(Color, allow_none=True) + + example = Example2() + self.assertIs(example.color1, None) + self.assertIs(example.color2, None) + + def test_assign_none_without_allow_none_resets_to_default_value(self): + class Example2(HasTraits): + color1 = UseEnum(Color, allow_none=False) + color2 = UseEnum(Color) + + example = Example2() + example.color1 = None + example.color2 = None + self.assertIs(example.color1, Color.red) + self.assertIs(example.color2, Color.red) + + def test_assign_none_to_enum_or_none(self): + class Example2(HasTraits): + color = UseEnum(Color, allow_none=True) + + example = Example2() + example.color = None + self.assertIs(example.color, None) + + def test_assign_bad_value_with_to_enum_or_none(self): + class Example2(HasTraits): + color = UseEnum(Color, allow_none=True) + + example = Example2() + with self.assertRaises(TraitError): + example.color = "BAD_VALUE" + + def test_info(self): + import sys + + choices = color_choices + class Example(HasTraits): + enum1 = Enum(choices, allow_none=False) + enum2 = CaselessStrEnum(choices, allow_none=False) + enum3 = FuzzyEnum(choices, allow_none=False) + enum4 = UseEnum(CSColor, allow_none=False) + + for i in range(1,5): + attr = 'enum%s' % i + enum = getattr(Example, attr) + + enum.allow_none = True + + info = enum.info() + self.assertEqual(len(info.split(', ')), len(choices), info.split(', ')) + self.assertIn('or None', info) + + info = enum.info_rst() + self.assertEqual(len(info.split('|')), len(choices), info.split('|')) + self.assertIn('or `None`', info) + ## Check no single `\` exists. + self.assertNotRegex(info, r'\b\\\b') + + enum.allow_none = False + + info = enum.info() + self.assertEqual(len(info.split(', ')), len(choices), info.split(', ')) + self.assertNotIn('None', info) + + info = enum.info_rst() + self.assertEqual(len(info.split('|')), len(choices), info.split('|')) + self.assertNotIn('None', info) + ## Check no single `\` exists. + self.assertNotRegex(info, r'\b\\\b') + + + +# ----------------------------------------------------------------------------- +# TESTSUITE: +# ----------------------------------------------------------------------------- + +class TestFuzzyEnum(unittest.TestCase): + ## Check mostly `validate()`, Ctor must be checked on generic `Enum` + # or `CaselessStrEnum`. + + def test_search_all_prefixes__overwrite(self): + class FuzzyExample(HasTraits): + color = FuzzyEnum(color_choices, help="Color enum") + + example = FuzzyExample() + for color in color_choices: + for wlen in range(1, len(color)): + value = color[:wlen] + + example.color = value + self.assertEqual(example.color, color) + + example.color = value.upper() + self.assertEqual(example.color, color) + + example.color = value.lower() + self.assertEqual(example.color, color) + + def test_search_all_prefixes__ctor(self): + class FuzzyExample(HasTraits): + color = FuzzyEnum(color_choices, help="Color enum") + + for color in color_choices: + for wlen in range(1, len(color)): + value = color[:wlen] + + example = FuzzyExample() + example.color = value + self.assertEqual(example.color, color) + + example = FuzzyExample() + example.color = value.upper() + self.assertEqual(example.color, color) + + example = FuzzyExample() + example.color = value.lower() + self.assertEqual(example.color, color) + + def test_search_substrings__overwrite(self): + class FuzzyExample(HasTraits): + color = FuzzyEnum(color_choices, help="Color enum", + substring_matching=True) + + example = FuzzyExample() + for color in color_choices: + for wlen in range(0, 2): + value = color[wlen:] + + example.color = value + self.assertEqual(example.color, color) + + example.color = value.upper() + self.assertEqual(example.color, color) + + example.color = value.lower() + self.assertEqual(example.color, color) + + def test_search_substrings__ctor(self): + class FuzzyExample(HasTraits): + color = FuzzyEnum(color_choices, help="Color enum", + substring_matching=True) + + color = color_choices[-1] # 'YeLLoW' + for end in (-1, len(color)): + for start in range(1, len(color) - 2): + value = color[start:end] + + example = FuzzyExample() + example.color = value + self.assertEqual(example.color, color) + + example = FuzzyExample() + example.color = value.upper() + self.assertEqual(example.color, color) + + def test_assign_other_raises(self): + def new_trait_class(case_sensitive, substring_matching): + class Example(HasTraits): + color = FuzzyEnum(color_choices, + case_sensitive=case_sensitive, + substring_matching=substring_matching) + + return Example + + example = new_trait_class(case_sensitive=False, substring_matching=False)() + with self.assertRaises(TraitError): + example.color = '' + with self.assertRaises(TraitError): + example.color = 'BAD COLOR' + with self.assertRaises(TraitError): + example.color = 'ed' + + example = new_trait_class(case_sensitive=True, substring_matching=False)() + with self.assertRaises(TraitError): + example.color = '' + with self.assertRaises(TraitError): + example.color = 'Red' # not 'red' + + example = new_trait_class(case_sensitive=True, substring_matching=True)() + with self.assertRaises(TraitError): + example.color = '' + with self.assertRaises(TraitError): + example.color = 'BAD COLOR' + with self.assertRaises(TraitError): + example.color = 'green' # not 'Green' + with self.assertRaises(TraitError): + example.color = 'lue' # not (b)'LUE' + with self.assertRaises(TraitError): + example.color = 'lUE' # not (b)'LUE' + + example = new_trait_class(case_sensitive=False, substring_matching=True)() + with self.assertRaises(TraitError): + example.color = '' + with self.assertRaises(TraitError): + example.color = 'BAD COLOR' + + def test_ctor_with_default_value(self): + def new_trait_class(default_value, + case_sensitive, substring_matching): + class Example(HasTraits): + color = FuzzyEnum(color_choices, + default_value=default_value, + case_sensitive=case_sensitive, + substring_matching=substring_matching) + + return Example + + for color in color_choices: + example = new_trait_class(color, False, False)() + self.assertEqual(example.color, color) + + example = new_trait_class(color.upper(), False, False)() + self.assertEqual(example.color, color) + + color = color_choices[-1] # 'YeLLoW' + example = new_trait_class(color, True, False)() + self.assertEqual(example.color, color) + + ## FIXME: default value not validated! + #with self.assertRaises(TraitError): + # example = new_trait_class(color.lower(), True, False) + diff --git a/.venv/lib/python3.8/site-packages/traitlets/tests/utils.py b/.venv/lib/python3.8/site-packages/traitlets/tests/utils.py new file mode 100644 index 00000000..8c58ddb4 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/traitlets/tests/utils.py @@ -0,0 +1,39 @@ +from subprocess import Popen, PIPE +import sys + + +def get_output_error_code(cmd): + """Get stdout, stderr, and exit code from running a command""" + p = Popen(cmd, stdout=PIPE, stderr=PIPE) + out, err = p.communicate() + out = out.decode('utf8', 'replace') + err = err.decode('utf8', 'replace') + return out, err, p.returncode + + +def check_help_output(pkg, subcommand=None): + """test that `python -m PKG [subcommand] -h` works""" + cmd = [sys.executable, '-m', pkg] + if subcommand: + cmd.extend(subcommand) + cmd.append('-h') + out, err, rc = get_output_error_code(cmd) + assert rc == 0, err + assert "Traceback" not in err + assert "Options" in out + assert "--help-all" in out + return out, err + + +def check_help_all_output(pkg, subcommand=None): + """test that `python -m PKG --help-all` works""" + cmd = [sys.executable, '-m', pkg] + if subcommand: + cmd.extend(subcommand) + cmd.append('--help-all') + out, err, rc = get_output_error_code(cmd) + assert rc == 0, err + assert "Traceback" not in err + assert "Options" in out + assert "Class options" in out + return out, err diff --git a/.venv/lib/python3.8/site-packages/traitlets/traitlets.py b/.venv/lib/python3.8/site-packages/traitlets/traitlets.py new file mode 100644 index 00000000..20355904 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/traitlets/traitlets.py @@ -0,0 +1,3244 @@ +""" +A lightweight Traits like module. + +This is designed to provide a lightweight, simple, pure Python version of +many of the capabilities of enthought.traits. This includes: + +* Validation +* Type specification with defaults +* Static and dynamic notification +* Basic predefined types +* An API that is similar to enthought.traits + +We don't support: + +* Delegation +* Automatic GUI generation +* A full set of trait types. Most importantly, we don't provide container + traits (list, dict, tuple) that can trigger notifications if their + contents change. +* API compatibility with enthought.traits + +There are also some important difference in our design: + +* enthought.traits does not validate default values. We do. + +We choose to create this module because we need these capabilities, but +we need them to be pure Python so they work in all Python implementations, +including Jython and IronPython. + +Inheritance diagram: + +.. inheritance-diagram:: traitlets.traitlets + :parts: 3 +""" + +# Copyright (c) IPython Development Team. +# Distributed under the terms of the Modified BSD License. +# +# Adapted from enthought.traits, Copyright (c) Enthought, Inc., +# also under the terms of the Modified BSD License. + +from ast import literal_eval +import contextlib +import inspect +import os +import re +import sys +import types +import enum +from warnings import warn, warn_explicit + +from .utils.getargspec import getargspec +from .utils.importstring import import_item +from .utils.sentinel import Sentinel +from .utils.bunch import Bunch +from .utils.descriptions import describe, class_of, add_article, repr_type + +SequenceTypes = (list, tuple, set, frozenset) + +# backward compatibility, use to differ between Python 2 and 3. +ClassTypes = (type,) + +# exports: + +__all__ = [ + "default", + "validate", + "observe", + "observe_compat", + "link", + "directional_link", + "dlink", + "Undefined", + "All", + "NoDefaultSpecified", + "TraitError", + "HasDescriptors", + "HasTraits", + "MetaHasDescriptors", + "MetaHasTraits", + "BaseDescriptor", + "TraitType", + "parse_notifier_name", +] + +# any TraitType subclass (that doesn't start with _) will be added automatically + +#----------------------------------------------------------------------------- +# Basic classes +#----------------------------------------------------------------------------- + + +Undefined = Sentinel('Undefined', 'traitlets', +''' +Used in Traitlets to specify that no defaults are set in kwargs +''' +) + +All = Sentinel('All', 'traitlets', +''' +Used in Traitlets to listen to all types of notification or to notifications +from all trait attributes. +''' +) + +# Deprecated alias +NoDefaultSpecified = Undefined + +class TraitError(Exception): + pass + +#----------------------------------------------------------------------------- +# Utilities +#----------------------------------------------------------------------------- + +_name_re = re.compile(r"[a-zA-Z_][a-zA-Z0-9_]*$") + +def isidentifier(s): + return s.isidentifier() + +_deprecations_shown = set() +def _should_warn(key): + """Add our own checks for too many deprecation warnings. + + Limit to once per package. + """ + env_flag = os.environ.get('TRAITLETS_ALL_DEPRECATIONS') + if env_flag and env_flag != '0': + return True + + if key not in _deprecations_shown: + _deprecations_shown.add(key) + return True + else: + return False + +def _deprecated_method(method, cls, method_name, msg): + """Show deprecation warning about a magic method definition. + + Uses warn_explicit to bind warning to method definition instead of triggering code, + which isn't relevant. + """ + warn_msg = "{classname}.{method_name} is deprecated in traitlets 4.1: {msg}".format( + classname=cls.__name__, method_name=method_name, msg=msg + ) + + for parent in inspect.getmro(cls): + if method_name in parent.__dict__: + cls = parent + break + # limit deprecation messages to once per package + package_name = cls.__module__.split('.', 1)[0] + key = (package_name, msg) + if not _should_warn(key): + return + try: + fname = inspect.getsourcefile(method) or "" + lineno = inspect.getsourcelines(method)[1] or 0 + except (OSError, TypeError) as e: + # Failed to inspect for some reason + warn(warn_msg + ('\n(inspection failed) %s' % e), DeprecationWarning) + else: + warn_explicit(warn_msg, DeprecationWarning, fname, lineno) + +def _safe_literal_eval(s): + """Safely evaluate an expression + + Returns original string if eval fails. + + Use only where types are ambiguous. + """ + try: + return literal_eval(s) + except (NameError, SyntaxError, ValueError): + return s + +def is_trait(t): + """ Returns whether the given value is an instance or subclass of TraitType. + """ + return (isinstance(t, TraitType) or + (isinstance(t, type) and issubclass(t, TraitType))) + + +def parse_notifier_name(names): + """Convert the name argument to a list of names. + + Examples + -------- + >>> parse_notifier_name([]) + [All] + >>> parse_notifier_name("a") + ['a'] + >>> parse_notifier_name(["a", "b"]) + ['a', 'b'] + >>> parse_notifier_name(All) + [All] + """ + if names is All or isinstance(names, str): + return [names] + else: + if not names or All in names: + return [All] + for n in names: + if not isinstance(n, str): + raise TypeError("names must be strings, not %r" % n) + return names + + +class _SimpleTest: + def __init__ ( self, value ): self.value = value + def __call__ ( self, test ): + return test == self.value + def __repr__(self): + return ">> c = link((src, "value"), (tgt, "value")) + >>> src.value = 5 # updates other objects as well + """ + updating = False + + def __init__(self, source, target, transform=None): + _validate_link(source, target) + self.source, self.target = source, target + self._transform, self._transform_inv = ( + transform if transform else (lambda x: x,) * 2) + + self.link() + + def link(self): + try: + setattr(self.target[0], self.target[1], + self._transform(getattr(self.source[0], self.source[1]))) + + finally: + self.source[0].observe(self._update_target, names=self.source[1]) + self.target[0].observe(self._update_source, names=self.target[1]) + + @contextlib.contextmanager + def _busy_updating(self): + self.updating = True + try: + yield + finally: + self.updating = False + + def _update_target(self, change): + if self.updating: + return + with self._busy_updating(): + setattr(self.target[0], self.target[1], self._transform(change.new)) + if getattr(self.source[0], self.source[1]) != change.new: + raise TraitError( + "Broken link {}: the source value changed while updating " + "the target.".format(self)) + + def _update_source(self, change): + if self.updating: + return + with self._busy_updating(): + setattr(self.source[0], self.source[1], + self._transform_inv(change.new)) + if getattr(self.target[0], self.target[1]) != change.new: + raise TraitError( + "Broken link {}: the target value changed while updating " + "the source.".format(self)) + + def unlink(self): + self.source[0].unobserve(self._update_target, names=self.source[1]) + self.target[0].unobserve(self._update_source, names=self.target[1]) + + +class directional_link(object): + """Link the trait of a source object with traits of target objects. + + Parameters + ---------- + source : (object, attribute name) pair + target : (object, attribute name) pair + transform: callable (optional) + Data transformation between source and target. + + Examples + -------- + >>> c = directional_link((src, "value"), (tgt, "value")) + >>> src.value = 5 # updates target objects + >>> tgt.value = 6 # does not update source object + """ + updating = False + + def __init__(self, source, target, transform=None): + self._transform = transform if transform else lambda x: x + _validate_link(source, target) + self.source, self.target = source, target + self.link() + + def link(self): + try: + setattr(self.target[0], self.target[1], + self._transform(getattr(self.source[0], self.source[1]))) + finally: + self.source[0].observe(self._update, names=self.source[1]) + + @contextlib.contextmanager + def _busy_updating(self): + self.updating = True + try: + yield + finally: + self.updating = False + + def _update(self, change): + if self.updating: + return + with self._busy_updating(): + setattr(self.target[0], self.target[1], + self._transform(change.new)) + + def unlink(self): + self.source[0].unobserve(self._update, names=self.source[1]) + +dlink = directional_link + + +#----------------------------------------------------------------------------- +# Base Descriptor Class +#----------------------------------------------------------------------------- + + +class BaseDescriptor(object): + """Base descriptor class + + Notes + ----- + This implements Python's descriptor protocol. + + This class is the base class for all such descriptors. The + only magic we use is a custom metaclass for the main :class:`HasTraits` + class that does the following: + + 1. Sets the :attr:`name` attribute of every :class:`BaseDescriptor` + instance in the class dict to the name of the attribute. + 2. Sets the :attr:`this_class` attribute of every :class:`BaseDescriptor` + instance in the class dict to the *class* that declared the trait. + This is used by the :class:`This` trait to allow subclasses to + accept superclasses for :class:`This` values. + """ + + name = None + this_class = None + + def class_init(self, cls, name): + """Part of the initialization which may depend on the underlying + HasDescriptors class. + + It is typically overloaded for specific types. + + This method is called by :meth:`MetaHasDescriptors.__init__` + passing the class (`cls`) and `name` under which the descriptor + has been assigned. + """ + self.this_class = cls + self.name = name + + def subclass_init(self, cls): + pass + + def instance_init(self, obj): + """Part of the initialization which may depend on the underlying + HasDescriptors instance. + + It is typically overloaded for specific types. + + This method is called by :meth:`HasTraits.__new__` and in the + :meth:`BaseDescriptor.instance_init` method of descriptors holding + other descriptors. + """ + pass + + +class TraitType(BaseDescriptor): + """A base class for all trait types. + """ + + metadata = {} + allow_none = False + read_only = False + info_text = 'any value' + default_value = Undefined + + def __init__(self, default_value=Undefined, allow_none=False, read_only=None, help=None, + config=None, **kwargs): + """Declare a traitlet. + + If *allow_none* is True, None is a valid value in addition to any + values that are normally valid. The default is up to the subclass. + For most trait types, the default value for ``allow_none`` is False. + + Extra metadata can be associated with the traitlet using the .tag() convenience method + or by using the traitlet instance's .metadata dictionary. + """ + if default_value is not Undefined: + self.default_value = default_value + if allow_none: + self.allow_none = allow_none + if read_only is not None: + self.read_only = read_only + self.help = help if help is not None else '' + + if len(kwargs) > 0: + stacklevel = 1 + f = inspect.currentframe() + # count supers to determine stacklevel for warning + while f.f_code.co_name == '__init__': + stacklevel += 1 + f = f.f_back + mod = f.f_globals.get('__name__') or '' + pkg = mod.split('.', 1)[0] + key = tuple(['metadata-tag', pkg] + sorted(kwargs)) + if _should_warn(key): + warn("metadata %s was set from the constructor. " + "With traitlets 4.1, metadata should be set using the .tag() method, " + "e.g., Int().tag(key1='value1', key2='value2')" % (kwargs,), + DeprecationWarning, stacklevel=stacklevel) + if len(self.metadata) > 0: + self.metadata = self.metadata.copy() + self.metadata.update(kwargs) + else: + self.metadata = kwargs + else: + self.metadata = self.metadata.copy() + if config is not None: + self.metadata['config'] = config + + # We add help to the metadata during a deprecation period so that + # code that looks for the help string there can find it. + if help is not None: + self.metadata['help'] = help + + def from_string(self, s): + """Get a value from a config string + + such as an environment variable or CLI arguments. + + Traits can override this method to define their own + parsing of config strings. + + .. seealso:: item_from_string + + .. versionadded:: 5.0 + """ + if self.allow_none and s == 'None': + return None + return s + + def default(self, obj=None): + """The default generator for this trait + + Notes + ----- + This method is registered to HasTraits classes during ``class_init`` + in the same way that dynamic defaults defined by ``@default`` are. + """ + if self.default_value is not Undefined: + return self.default_value + elif hasattr(self, 'make_dynamic_default'): + return self.make_dynamic_default() + else: + # Undefined will raise in TraitType.get + return self.default_value + + def get_default_value(self): + """DEPRECATED: Retrieve the static default value for this trait. + Use self.default_value instead + """ + warn("get_default_value is deprecated in traitlets 4.0: use the .default_value attribute", DeprecationWarning, + stacklevel=2) + return self.default_value + + def init_default_value(self, obj): + """DEPRECATED: Set the static default value for the trait type. + """ + warn("init_default_value is deprecated in traitlets 4.0, and may be removed in the future", DeprecationWarning, + stacklevel=2) + value = self._validate(obj, self.default_value) + obj._trait_values[self.name] = value + return value + + def get(self, obj, cls=None): + try: + value = obj._trait_values[self.name] + except KeyError: + # Check for a dynamic initializer. + default = obj.trait_defaults(self.name) + if default is Undefined: + warn( + "Explicit using of Undefined as the default value " + "is deprecated in traitlets 5.0, and may cause " + "exceptions in the future.", + DeprecationWarning, + stacklevel=2 + ) + with obj.cross_validation_lock: + value = self._validate(obj, default) + obj._trait_values[self.name] = value + obj._notify_observers(Bunch( + name=self.name, + value=value, + owner=obj, + type='default', + )) + return value + except Exception: + # This should never be reached. + raise TraitError('Unexpected error in TraitType: ' + 'default value not set properly') + else: + return value + + def __get__(self, obj, cls=None): + """Get the value of the trait by self.name for the instance. + + Default values are instantiated when :meth:`HasTraits.__new__` + is called. Thus by the time this method gets called either the + default value or a user defined value (they called :meth:`__set__`) + is in the :class:`HasTraits` instance. + """ + if obj is None: + return self + else: + return self.get(obj, cls) + + def set(self, obj, value): + new_value = self._validate(obj, value) + try: + old_value = obj._trait_values[self.name] + except KeyError: + old_value = self.default_value + + obj._trait_values[self.name] = new_value + try: + silent = bool(old_value == new_value) + except Exception: + # if there is an error in comparing, default to notify + silent = False + if silent is not True: + # we explicitly compare silent to True just in case the equality + # comparison above returns something other than True/False + obj._notify_trait(self.name, old_value, new_value) + + def __set__(self, obj, value): + """Set the value of the trait by self.name for the instance. + + Values pass through a validation stage where errors are raised when + impropper types, or types that cannot be coerced, are encountered. + """ + if self.read_only: + raise TraitError('The "%s" trait is read-only.' % self.name) + else: + self.set(obj, value) + + def _validate(self, obj, value): + if value is None and self.allow_none: + return value + if hasattr(self, 'validate'): + value = self.validate(obj, value) + if obj._cross_validation_lock is False: + value = self._cross_validate(obj, value) + return value + + def _cross_validate(self, obj, value): + if self.name in obj._trait_validators: + proposal = Bunch({'trait': self, 'value': value, 'owner': obj}) + value = obj._trait_validators[self.name](obj, proposal) + elif hasattr(obj, '_%s_validate' % self.name): + meth_name = '_%s_validate' % self.name + cross_validate = getattr(obj, meth_name) + _deprecated_method(cross_validate, obj.__class__, meth_name, + "use @validate decorator instead.") + value = cross_validate(value, self) + return value + + def __or__(self, other): + if isinstance(other, Union): + return Union([self] + other.trait_types) + else: + return Union([self, other]) + + def info(self): + return self.info_text + + def error(self, obj, value, error=None, info=None): + """Raise a TraitError + + Parameters + ---------- + obj : HasTraits or None + The instance which owns the trait. If not + object is given, then an object agnostic + error will be raised. + value : any + The value that caused the error. + error : Exception (default: None) + An error that was raised by a child trait. + The arguments of this exception should be + of the form ``(value, info, *traits)``. + Where the ``value`` and ``info`` are the + problem value, and string describing the + expected value. The ``traits`` are a series + of :class:`TraitType` instances that are + "children" of this one (the first being + the deepest). + info : str (default: None) + A description of the expected value. By + default this is infered from this trait's + ``info`` method. + """ + if error is not None: + # handle nested error + error.args += (self,) + if self.name is not None: + # this is the root trait that must format the final message + chain = " of ".join(describe("a", t) for t in error.args[2:]) + if obj is not None: + error.args = ("The '%s' trait of %s instance contains %s which " + "expected %s, not %s." % (self.name, describe("an", obj), + chain, error.args[1], describe("the", error.args[0])),) + else: + error.args = ("The '%s' trait contains %s which " + "expected %s, not %s." % (self.name, chain, + error.args[1], describe("the", error.args[0])),) + raise error + else: + # this trait caused an error + if self.name is None: + # this is not the root trait + raise TraitError(value, info or self.info(), self) + else: + # this is the root trait + if obj is not None: + e = "The '%s' trait of %s instance expected %s, not %s." % ( + self.name, class_of(obj), self.info(), describe("the", value)) + else: + e = "The '%s' trait expected %s, not %s." % ( + self.name, self.info(), describe("the", value)) + raise TraitError(e) + + def get_metadata(self, key, default=None): + """DEPRECATED: Get a metadata value. + + Use .metadata[key] or .metadata.get(key, default) instead. + """ + if key == 'help': + msg = "use the instance .help string directly, like x.help" + else: + msg = "use the instance .metadata dictionary directly, like x.metadata[key] or x.metadata.get(key, default)" + warn("Deprecated in traitlets 4.1, " + msg, DeprecationWarning, stacklevel=2) + return self.metadata.get(key, default) + + def set_metadata(self, key, value): + """DEPRECATED: Set a metadata key/value. + + Use .metadata[key] = value instead. + """ + if key == 'help': + msg = "use the instance .help string directly, like x.help = value" + else: + msg = "use the instance .metadata dictionary directly, like x.metadata[key] = value" + warn("Deprecated in traitlets 4.1, " + msg, DeprecationWarning, stacklevel=2) + self.metadata[key] = value + + def tag(self, **metadata): + """Sets metadata and returns self. + + This allows convenient metadata tagging when initializing the trait, such as: + + >>> Int(0).tag(config=True, sync=True) + """ + maybe_constructor_keywords = set(metadata.keys()).intersection({'help','allow_none', 'read_only', 'default_value'}) + if maybe_constructor_keywords: + warn('The following attributes are set in using `tag`, but seem to be constructor keywords arguments: %s '% + maybe_constructor_keywords, UserWarning, stacklevel=2) + + self.metadata.update(metadata) + return self + + def default_value_repr(self): + return repr(self.default_value) + +#----------------------------------------------------------------------------- +# The HasTraits implementation +#----------------------------------------------------------------------------- + +class _CallbackWrapper(object): + """An object adapting a on_trait_change callback into an observe callback. + + The comparison operator __eq__ is implemented to enable removal of wrapped + callbacks. + """ + + def __init__(self, cb): + self.cb = cb + # Bound methods have an additional 'self' argument. + offset = -1 if isinstance(self.cb, types.MethodType) else 0 + self.nargs = len(getargspec(cb)[0]) + offset + if (self.nargs > 4): + raise TraitError('a trait changed callback must have 0-4 arguments.') + + def __eq__(self, other): + # The wrapper is equal to the wrapped element + if isinstance(other, _CallbackWrapper): + return self.cb == other.cb + else: + return self.cb == other + + def __call__(self, change): + # The wrapper is callable + if self.nargs == 0: + self.cb() + elif self.nargs == 1: + self.cb(change.name) + elif self.nargs == 2: + self.cb(change.name, change.new) + elif self.nargs == 3: + self.cb(change.name, change.old, change.new) + elif self.nargs == 4: + self.cb(change.name, change.old, change.new, change.owner) + +def _callback_wrapper(cb): + if isinstance(cb, _CallbackWrapper): + return cb + else: + return _CallbackWrapper(cb) + + +class MetaHasDescriptors(type): + """A metaclass for HasDescriptors. + + This metaclass makes sure that any TraitType class attributes are + instantiated and sets their name attribute. + """ + + def __new__(mcls, name, bases, classdict): + """Create the HasDescriptors class.""" + for k, v in classdict.items(): + # ---------------------------------------------------------------- + # Support of deprecated behavior allowing for TraitType types + # to be used instead of TraitType instances. + if inspect.isclass(v) and issubclass(v, TraitType): + warn("Traits should be given as instances, not types (for example, `Int()`, not `Int`)." + " Passing types is deprecated in traitlets 4.1.", + DeprecationWarning, stacklevel=2) + classdict[k] = v() + # ---------------------------------------------------------------- + + return super(MetaHasDescriptors, mcls).__new__(mcls, name, bases, classdict) + + def __init__(cls, name, bases, classdict): + """Finish initializing the HasDescriptors class.""" + super(MetaHasDescriptors, cls).__init__(name, bases, classdict) + cls.setup_class(classdict) + + def setup_class(cls, classdict): + """Setup descriptor instance on the class + + This sets the :attr:`this_class` and :attr:`name` attributes of each + BaseDescriptor in the class dict of the newly created ``cls`` before + calling their :attr:`class_init` method. + """ + for k, v in classdict.items(): + if isinstance(v, BaseDescriptor): + v.class_init(cls, k) + + for k, v in getmembers(cls): + if isinstance(v, BaseDescriptor): + v.subclass_init(cls) + + +class MetaHasTraits(MetaHasDescriptors): + """A metaclass for HasTraits.""" + + def setup_class(cls, classdict): + cls._trait_default_generators = {} + super(MetaHasTraits, cls).setup_class(classdict) + + +def observe(*names, **kwargs): + """A decorator which can be used to observe Traits on a class. + + The handler passed to the decorator will be called with one ``change`` + dict argument. The change dictionary at least holds a 'type' key and a + 'name' key, corresponding respectively to the type of notification and the + name of the attribute that triggered the notification. + + Other keys may be passed depending on the value of 'type'. In the case + where type is 'change', we also have the following keys: + * ``owner`` : the HasTraits instance + * ``old`` : the old value of the modified trait attribute + * ``new`` : the new value of the modified trait attribute + * ``name`` : the name of the modified trait attribute. + + Parameters + ---------- + *names + The str names of the Traits to observe on the object. + type : str, kwarg-only + The type of event to observe (e.g. 'change') + """ + if not names: + raise TypeError("Please specify at least one trait name to observe.") + for name in names: + if name is not All and not isinstance(name, str): + raise TypeError("trait names to observe must be strings or All, not %r" % name) + return ObserveHandler(names, type=kwargs.get('type', 'change')) + + +def observe_compat(func): + """Backward-compatibility shim decorator for observers + + Use with: + + @observe('name') + @observe_compat + def _foo_changed(self, change): + ... + + With this, `super()._foo_changed(self, name, old, new)` in subclasses will still work. + Allows adoption of new observer API without breaking subclasses that override and super. + """ + def compatible_observer(self, change_or_name, old=Undefined, new=Undefined): + if isinstance(change_or_name, dict): + change = change_or_name + else: + clsname = self.__class__.__name__ + warn("A parent of %s._%s_changed has adopted the new (traitlets 4.1) @observe(change) API" % ( + clsname, change_or_name), DeprecationWarning) + change = Bunch( + type='change', + old=old, + new=new, + name=change_or_name, + owner=self, + ) + return func(self, change) + return compatible_observer + + +def validate(*names): + """A decorator to register cross validator of HasTraits object's state + when a Trait is set. + + The handler passed to the decorator must have one ``proposal`` dict argument. + The proposal dictionary must hold the following keys: + + * ``owner`` : the HasTraits instance + * ``value`` : the proposed value for the modified trait attribute + * ``trait`` : the TraitType instance associated with the attribute + + Parameters + ---------- + names + The str names of the Traits to validate. + + Notes + ----- + Since the owner has access to the ``HasTraits`` instance via the 'owner' key, + the registered cross validator could potentially make changes to attributes + of the ``HasTraits`` instance. However, we recommend not to do so. The reason + is that the cross-validation of attributes may run in arbitrary order when + exiting the ``hold_trait_notifications`` context, and such changes may not + commute. + """ + if not names: + raise TypeError("Please specify at least one trait name to validate.") + for name in names: + if name is not All and not isinstance(name, str): + raise TypeError("trait names to validate must be strings or All, not %r" % name) + return ValidateHandler(names) + + +def default(name): + """ A decorator which assigns a dynamic default for a Trait on a HasTraits object. + + Parameters + ---------- + name + The str name of the Trait on the object whose default should be generated. + + Notes + ----- + Unlike observers and validators which are properties of the HasTraits + instance, default value generators are class-level properties. + + Besides, default generators are only invoked if they are registered in + subclasses of `this_type`. + + :: + + class A(HasTraits): + bar = Int() + + @default('bar') + def get_bar_default(self): + return 11 + + class B(A): + bar = Float() # This trait ignores the default generator defined in + # the base class A + + class C(B): + + @default('bar') + def some_other_default(self): # This default generator should not be + return 3.0 # ignored since it is defined in a + # class derived from B.a.this_class. + """ + if not isinstance(name, str): + raise TypeError("Trait name must be a string or All, not %r" % name) + return DefaultHandler(name) + + +class EventHandler(BaseDescriptor): + + def _init_call(self, func): + self.func = func + return self + + def __call__(self, *args, **kwargs): + """Pass `*args` and `**kwargs` to the handler's function if it exists.""" + if hasattr(self, 'func'): + return self.func(*args, **kwargs) + else: + return self._init_call(*args, **kwargs) + + def __get__(self, inst, cls=None): + if inst is None: + return self + return types.MethodType(self.func, inst) + + +class ObserveHandler(EventHandler): + + def __init__(self, names, type): + self.trait_names = names + self.type = type + + def instance_init(self, inst): + inst.observe(self, self.trait_names, type=self.type) + + +class ValidateHandler(EventHandler): + + def __init__(self, names): + self.trait_names = names + + def instance_init(self, inst): + inst._register_validator(self, self.trait_names) + + +class DefaultHandler(EventHandler): + + def __init__(self, name): + self.trait_name = name + + def class_init(self, cls, name): + super().class_init(cls, name) + cls._trait_default_generators[self.trait_name] = self + + +class HasDescriptors(metaclass=MetaHasDescriptors): + """The base class for all classes that have descriptors. + """ + + def __new__(*args, **kwargs): + # Pass cls as args[0] to allow "cls" as keyword argument + cls = args[0] + args = args[1:] + + # This is needed because object.__new__ only accepts + # the cls argument. + new_meth = super(HasDescriptors, cls).__new__ + if new_meth is object.__new__: + inst = new_meth(cls) + else: + inst = new_meth(cls, *args, **kwargs) + inst.setup_instance(*args, **kwargs) + return inst + + def setup_instance(*args, **kwargs): + """ + This is called **before** self.__init__ is called. + """ + # Pass self as args[0] to allow "self" as keyword argument + self = args[0] + args = args[1:] + + self._cross_validation_lock = False + cls = self.__class__ + for key in dir(cls): + # Some descriptors raise AttributeError like zope.interface's + # __provides__ attributes even though they exist. This causes + # AttributeErrors even though they are listed in dir(cls). + try: + value = getattr(cls, key) + except AttributeError: + pass + else: + if isinstance(value, BaseDescriptor): + value.instance_init(self) + + +class HasTraits(HasDescriptors, metaclass=MetaHasTraits): + + def setup_instance(*args, **kwargs): + # Pass self as args[0] to allow "self" as keyword argument + self = args[0] + args = args[1:] + + self._trait_values = {} + self._trait_notifiers = {} + self._trait_validators = {} + super(HasTraits, self).setup_instance(*args, **kwargs) + + def __init__(self, *args, **kwargs): + # Allow trait values to be set using keyword arguments. + # We need to use setattr for this to trigger validation and + # notifications. + super_args = args + super_kwargs = {} + with self.hold_trait_notifications(): + for key, value in kwargs.items(): + if self.has_trait(key): + setattr(self, key, value) + else: + # passthrough args that don't set traits to super + super_kwargs[key] = value + try: + super(HasTraits, self).__init__(*super_args, **super_kwargs) + except TypeError as e: + arg_s_list = [ repr(arg) for arg in super_args ] + for k, v in super_kwargs.items(): + arg_s_list.append("%s=%r" % (k, v)) + arg_s = ', '.join(arg_s_list) + warn( + "Passing unrecognized arguments to super({classname}).__init__({arg_s}).\n" + "{error}\n" + "This is deprecated in traitlets 4.2." + "This error will be raised in a future release of traitlets." + .format( + arg_s=arg_s, classname=self.__class__.__name__, + error=e, + ), + DeprecationWarning, + stacklevel=2, + ) + + def __getstate__(self): + d = self.__dict__.copy() + # event handlers stored on an instance are + # expected to be reinstantiated during a + # recall of instance_init during __setstate__ + d['_trait_notifiers'] = {} + d['_trait_validators'] = {} + d['_trait_values'] = self._trait_values.copy() + d['_cross_validation_lock'] = False # FIXME: raise if cloning locked! + + return d + + def __setstate__(self, state): + self.__dict__ = state.copy() + + # event handlers are reassigned to self + cls = self.__class__ + for key in dir(cls): + # Some descriptors raise AttributeError like zope.interface's + # __provides__ attributes even though they exist. This causes + # AttributeErrors even though they are listed in dir(cls). + try: + value = getattr(cls, key) + except AttributeError: + pass + else: + if isinstance(value, EventHandler): + value.instance_init(self) + + @property + @contextlib.contextmanager + def cross_validation_lock(self): + """ + A contextmanager for running a block with our cross validation lock set + to True. + + At the end of the block, the lock's value is restored to its value + prior to entering the block. + """ + if self._cross_validation_lock: + yield + return + else: + try: + self._cross_validation_lock = True + yield + finally: + self._cross_validation_lock = False + + @contextlib.contextmanager + def hold_trait_notifications(self): + """Context manager for bundling trait change notifications and cross + validation. + + Use this when doing multiple trait assignments (init, config), to avoid + race conditions in trait notifiers requesting other trait values. + All trait notifications will fire after all values have been assigned. + """ + if self._cross_validation_lock: + yield + return + else: + cache = {} + notify_change = self.notify_change + + def compress(past_changes, change): + """Merges the provided change with the last if possible.""" + if past_changes is None: + return [change] + else: + if past_changes[-1]['type'] == 'change' and change.type == 'change': + past_changes[-1]['new'] = change.new + else: + # In case of changes other than 'change', append the notification. + past_changes.append(change) + return past_changes + + def hold(change): + name = change.name + cache[name] = compress(cache.get(name), change) + + try: + # Replace notify_change with `hold`, caching and compressing + # notifications, disable cross validation and yield. + self.notify_change = hold + self._cross_validation_lock = True + yield + # Cross validate final values when context is released. + for name in list(cache.keys()): + trait = getattr(self.__class__, name) + value = trait._cross_validate(self, getattr(self, name)) + self.set_trait(name, value) + except TraitError as e: + # Roll back in case of TraitError during final cross validation. + self.notify_change = lambda x: None + for name, changes in cache.items(): + for change in changes[::-1]: + # TODO: Separate in a rollback function per notification type. + if change.type == 'change': + if change.old is not Undefined: + self.set_trait(name, change.old) + else: + self._trait_values.pop(name) + cache = {} + raise e + finally: + self._cross_validation_lock = False + # Restore method retrieval from class + del self.notify_change + + # trigger delayed notifications + for changes in cache.values(): + for change in changes: + self.notify_change(change) + + def _notify_trait(self, name, old_value, new_value): + self.notify_change(Bunch( + name=name, + old=old_value, + new=new_value, + owner=self, + type='change', + )) + + def notify_change(self, change): + """Notify observers of a change event""" + return self._notify_observers(change) + + def _notify_observers(self, event): + """Notify observers of any event""" + if not isinstance(event, Bunch): + # cast to bunch if given a dict + event = Bunch(event) + name, type = event.name, event.type + + callables = [] + callables.extend(self._trait_notifiers.get(name, {}).get(type, [])) + callables.extend(self._trait_notifiers.get(name, {}).get(All, [])) + callables.extend(self._trait_notifiers.get(All, {}).get(type, [])) + callables.extend(self._trait_notifiers.get(All, {}).get(All, [])) + + # Now static ones + magic_name = '_%s_changed' % name + if event.type == "change" and hasattr(self, magic_name): + class_value = getattr(self.__class__, magic_name) + if not isinstance(class_value, ObserveHandler): + _deprecated_method(class_value, self.__class__, magic_name, + "use @observe and @unobserve instead.") + cb = getattr(self, magic_name) + # Only append the magic method if it was not manually registered + if cb not in callables: + callables.append(_callback_wrapper(cb)) + + # Call them all now + # Traits catches and logs errors here. I allow them to raise + for c in callables: + # Bound methods have an additional 'self' argument. + + if isinstance(c, _CallbackWrapper): + c = c.__call__ + elif isinstance(c, EventHandler) and c.name is not None: + c = getattr(self, c.name) + + c(event) + + def _add_notifiers(self, handler, name, type): + if name not in self._trait_notifiers: + nlist = [] + self._trait_notifiers[name] = {type: nlist} + else: + if type not in self._trait_notifiers[name]: + nlist = [] + self._trait_notifiers[name][type] = nlist + else: + nlist = self._trait_notifiers[name][type] + if handler not in nlist: + nlist.append(handler) + + def _remove_notifiers(self, handler, name, type): + try: + if handler is None: + del self._trait_notifiers[name][type] + else: + self._trait_notifiers[name][type].remove(handler) + except KeyError: + pass + + def on_trait_change(self, handler=None, name=None, remove=False): + """DEPRECATED: Setup a handler to be called when a trait changes. + + This is used to setup dynamic notifications of trait changes. + + Static handlers can be created by creating methods on a HasTraits + subclass with the naming convention '_[traitname]_changed'. Thus, + to create static handler for the trait 'a', create the method + _a_changed(self, name, old, new) (fewer arguments can be used, see + below). + + If `remove` is True and `handler` is not specified, all change + handlers for the specified name are uninstalled. + + Parameters + ---------- + handler : callable, None + A callable that is called when a trait changes. Its + signature can be handler(), handler(name), handler(name, new), + handler(name, old, new), or handler(name, old, new, self). + name : list, str, None + If None, the handler will apply to all traits. If a list + of str, handler will apply to all names in the list. If a + str, the handler will apply just to that name. + remove : bool + If False (the default), then install the handler. If True + then unintall it. + """ + warn("on_trait_change is deprecated in traitlets 4.1: use observe instead", + DeprecationWarning, stacklevel=2) + if name is None: + name = All + if remove: + self.unobserve(_callback_wrapper(handler), names=name) + else: + self.observe(_callback_wrapper(handler), names=name) + + def observe(self, handler, names=All, type='change'): + """Setup a handler to be called when a trait changes. + + This is used to setup dynamic notifications of trait changes. + + Parameters + ---------- + handler : callable + A callable that is called when a trait changes. Its + signature should be ``handler(change)``, where ``change`` is a + dictionary. The change dictionary at least holds a 'type' key. + * ``type``: the type of notification. + Other keys may be passed depending on the value of 'type'. In the + case where type is 'change', we also have the following keys: + * ``owner`` : the HasTraits instance + * ``old`` : the old value of the modified trait attribute + * ``new`` : the new value of the modified trait attribute + * ``name`` : the name of the modified trait attribute. + names : list, str, All + If names is All, the handler will apply to all traits. If a list + of str, handler will apply to all names in the list. If a + str, the handler will apply just to that name. + type : str, All (default: 'change') + The type of notification to filter by. If equal to All, then all + notifications are passed to the observe handler. + """ + names = parse_notifier_name(names) + for n in names: + self._add_notifiers(handler, n, type) + + def unobserve(self, handler, names=All, type='change'): + """Remove a trait change handler. + + This is used to unregister handlers to trait change notifications. + + Parameters + ---------- + handler : callable + The callable called when a trait attribute changes. + names : list, str, All (default: All) + The names of the traits for which the specified handler should be + uninstalled. If names is All, the specified handler is uninstalled + from the list of notifiers corresponding to all changes. + type : str or All (default: 'change') + The type of notification to filter by. If All, the specified handler + is uninstalled from the list of notifiers corresponding to all types. + """ + names = parse_notifier_name(names) + for n in names: + self._remove_notifiers(handler, n, type) + + def unobserve_all(self, name=All): + """Remove trait change handlers of any type for the specified name. + If name is not specified, removes all trait notifiers.""" + if name is All: + self._trait_notifiers = {} + else: + try: + del self._trait_notifiers[name] + except KeyError: + pass + + def _register_validator(self, handler, names): + """Setup a handler to be called when a trait should be cross validated. + + This is used to setup dynamic notifications for cross-validation. + + If a validator is already registered for any of the provided names, a + TraitError is raised and no new validator is registered. + + Parameters + ---------- + handler : callable + A callable that is called when the given trait is cross-validated. + Its signature is handler(proposal), where proposal is a Bunch (dictionary with attribute access) + with the following attributes/keys: + * ``owner`` : the HasTraits instance + * ``value`` : the proposed value for the modified trait attribute + * ``trait`` : the TraitType instance associated with the attribute + names : List of strings + The names of the traits that should be cross-validated + """ + for name in names: + magic_name = '_%s_validate' % name + if hasattr(self, magic_name): + class_value = getattr(self.__class__, magic_name) + if not isinstance(class_value, ValidateHandler): + _deprecated_method(class_value, self.__class__, magic_name, + "use @validate decorator instead.") + for name in names: + self._trait_validators[name] = handler + + def add_traits(self, **traits): + """Dynamically add trait attributes to the HasTraits instance.""" + cls = self.__class__ + attrs = {"__module__": cls.__module__} + if hasattr(cls, "__qualname__"): + # __qualname__ introduced in Python 3.3 (see PEP 3155) + attrs["__qualname__"] = cls.__qualname__ + attrs.update(traits) + self.__class__ = type(cls.__name__, (cls,), attrs) + for trait in traits.values(): + trait.instance_init(self) + + def set_trait(self, name, value): + """Forcibly sets trait attribute, including read-only attributes.""" + cls = self.__class__ + if not self.has_trait(name): + raise TraitError("Class %s does not have a trait named %s" % + (cls.__name__, name)) + else: + getattr(cls, name).set(self, value) + + @classmethod + def class_trait_names(cls, **metadata): + """Get a list of all the names of this class' traits. + + This method is just like the :meth:`trait_names` method, + but is unbound. + """ + return list(cls.class_traits(**metadata)) + + @classmethod + def class_traits(cls, **metadata): + """Get a ``dict`` of all the traits of this class. The dictionary + is keyed on the name and the values are the TraitType objects. + + This method is just like the :meth:`traits` method, but is unbound. + + The TraitTypes returned don't know anything about the values + that the various HasTrait's instances are holding. + + The metadata kwargs allow functions to be passed in which + filter traits based on metadata values. The functions should + take a single value as an argument and return a boolean. If + any function returns False, then the trait is not included in + the output. If a metadata key doesn't exist, None will be passed + to the function. + """ + traits = dict([memb for memb in getmembers(cls) if + isinstance(memb[1], TraitType)]) + + if len(metadata) == 0: + return traits + + result = {} + for name, trait in traits.items(): + for meta_name, meta_eval in metadata.items(): + if not callable(meta_eval): + meta_eval = _SimpleTest(meta_eval) + if not meta_eval(trait.metadata.get(meta_name, None)): + break + else: + result[name] = trait + + return result + + @classmethod + def class_own_traits(cls, **metadata): + """Get a dict of all the traitlets defined on this class, not a parent. + + Works like `class_traits`, except for excluding traits from parents. + """ + sup = super(cls, cls) + return {n: t for (n, t) in cls.class_traits(**metadata).items() + if getattr(sup, n, None) is not t} + + def has_trait(self, name): + """Returns True if the object has a trait with the specified name.""" + return isinstance(getattr(self.__class__, name, None), TraitType) + + def trait_has_value(self, name): + """Returns True if the specified trait has a value. + + This will return false even if ``getattr`` would return a + dynamically generated default value. These default values + will be recognized as existing only after they have been + generated. + + Example + + .. code-block:: python + + class MyClass(HasTraits): + i = Int() + + mc = MyClass() + assert not mc.trait_has_value("i") + mc.i # generates a default value + assert mc.trait_has_value("i") + """ + return name in self._trait_values + + def trait_values(self, **metadata): + """A ``dict`` of trait names and their values. + + The metadata kwargs allow functions to be passed in which + filter traits based on metadata values. The functions should + take a single value as an argument and return a boolean. If + any function returns False, then the trait is not included in + the output. If a metadata key doesn't exist, None will be passed + to the function. + + Returns + ------- + A ``dict`` of trait names and their values. + + Notes + ----- + Trait values are retrieved via ``getattr``, any exceptions raised + by traits or the operations they may trigger will result in the + absence of a trait value in the result ``dict``. + """ + return {name: getattr(self, name) for name in self.trait_names(**metadata)} + + def _get_trait_default_generator(self, name): + """Return default generator for a given trait + + Walk the MRO to resolve the correct default generator according to inheritance. + """ + method_name = '_%s_default' % name + if method_name in self.__dict__: + return getattr(self, method_name) + cls = self.__class__ + trait = getattr(cls, name) + assert isinstance(trait, TraitType) + # truncate mro to the class on which the trait is defined + mro = cls.mro() + try: + mro = mro[:mro.index(trait.this_class) + 1] + except ValueError: + # this_class not in mro + pass + for c in mro: + if method_name in c.__dict__: + return getattr(c, method_name) + if name in c.__dict__.get('_trait_default_generators', {}): + return c._trait_default_generators[name] + return trait.default + + def trait_defaults(self, *names, **metadata): + """Return a trait's default value or a dictionary of them + + Notes + ----- + Dynamically generated default values may + depend on the current state of the object.""" + for n in names: + if not self.has_trait(n): + raise TraitError("'%s' is not a trait of '%s' " + "instances" % (n, type(self).__name__)) + + if len(names) == 1 and len(metadata) == 0: + return self._get_trait_default_generator(names[0])(self) + + trait_names = self.trait_names(**metadata) + trait_names.extend(names) + + defaults = {} + for n in trait_names: + defaults[n] = self._get_trait_default_generator(n)(self) + return defaults + + def trait_names(self, **metadata): + """Get a list of all the names of this class' traits.""" + return list(self.traits(**metadata)) + + def traits(self, **metadata): + """Get a ``dict`` of all the traits of this class. The dictionary + is keyed on the name and the values are the TraitType objects. + + The TraitTypes returned don't know anything about the values + that the various HasTrait's instances are holding. + + The metadata kwargs allow functions to be passed in which + filter traits based on metadata values. The functions should + take a single value as an argument and return a boolean. If + any function returns False, then the trait is not included in + the output. If a metadata key doesn't exist, None will be passed + to the function. + """ + traits = dict([memb for memb in getmembers(self.__class__) if + isinstance(memb[1], TraitType)]) + + if len(metadata) == 0: + return traits + + result = {} + for name, trait in traits.items(): + for meta_name, meta_eval in metadata.items(): + if not callable(meta_eval): + meta_eval = _SimpleTest(meta_eval) + if not meta_eval(trait.metadata.get(meta_name, None)): + break + else: + result[name] = trait + + return result + + def trait_metadata(self, traitname, key, default=None): + """Get metadata values for trait by key.""" + try: + trait = getattr(self.__class__, traitname) + except AttributeError: + raise TraitError("Class %s does not have a trait named %s" % + (self.__class__.__name__, traitname)) + metadata_name = '_' + traitname + '_metadata' + if hasattr(self, metadata_name) and key in getattr(self, metadata_name): + return getattr(self, metadata_name).get(key, default) + else: + return trait.metadata.get(key, default) + + @classmethod + def class_own_trait_events(cls, name): + """Get a dict of all event handlers defined on this class, not a parent. + + Works like ``event_handlers``, except for excluding traits from parents. + """ + sup = super(cls, cls) + return {n: e for (n, e) in cls.events(name).items() + if getattr(sup, n, None) is not e} + + @classmethod + def trait_events(cls, name=None): + """Get a ``dict`` of all the event handlers of this class. + + Parameters + ---------- + name : str (default: None) + The name of a trait of this class. If name is ``None`` then all + the event handlers of this class will be returned instead. + + Returns + ------- + The event handlers associated with a trait name, or all event handlers. + """ + events = {} + for k, v in getmembers(cls): + if isinstance(v, EventHandler): + if name is None: + events[k] = v + elif name in v.trait_names: + events[k] = v + elif hasattr(v, 'tags'): + if cls.trait_names(**v.tags): + events[k] = v + return events + +#----------------------------------------------------------------------------- +# Actual TraitTypes implementations/subclasses +#----------------------------------------------------------------------------- + +#----------------------------------------------------------------------------- +# TraitTypes subclasses for handling classes and instances of classes +#----------------------------------------------------------------------------- + + +class ClassBasedTraitType(TraitType): + """ + A trait with error reporting and string -> type resolution for Type, + Instance and This. + """ + + def _resolve_string(self, string): + """ + Resolve a string supplied for a type into an actual object. + """ + return import_item(string) + + +class Type(ClassBasedTraitType): + """A trait whose value must be a subclass of a specified class.""" + + def __init__(self, default_value=Undefined, klass=None, **kwargs): + """Construct a Type trait + + A Type trait specifies that its values must be subclasses of + a particular class. + + If only ``default_value`` is given, it is used for the ``klass`` as + well. If neither are given, both default to ``object``. + + Parameters + ---------- + default_value : class, str or None + The default value must be a subclass of klass. If an str, + the str must be a fully specified class name, like 'foo.bar.Bah'. + The string is resolved into real class, when the parent + :class:`HasTraits` class is instantiated. + klass : class, str [ default object ] + Values of this trait must be a subclass of klass. The klass + may be specified in a string like: 'foo.bar.MyClass'. + The string is resolved into real class, when the parent + :class:`HasTraits` class is instantiated. + allow_none : bool [ default False ] + Indicates whether None is allowed as an assignable value. + """ + if default_value is Undefined: + new_default_value = object if (klass is None) else klass + else: + new_default_value = default_value + + if klass is None: + if (default_value is None) or (default_value is Undefined): + klass = object + else: + klass = default_value + + if not (inspect.isclass(klass) or isinstance(klass, str)): + raise TraitError("A Type trait must specify a class.") + + self.klass = klass + + super().__init__(new_default_value, **kwargs) + + def validate(self, obj, value): + """Validates that the value is a valid object instance.""" + if isinstance(value, str): + try: + value = self._resolve_string(value) + except ImportError: + raise TraitError("The '%s' trait of %s instance must be a type, but " + "%r could not be imported" % (self.name, obj, value)) + try: + if issubclass(value, self.klass): + return value + except Exception: + pass + + self.error(obj, value) + + def info(self): + """ Returns a description of the trait.""" + if isinstance(self.klass, str): + klass = self.klass + else: + klass = self.klass.__module__ + '.' + self.klass.__name__ + result = "a subclass of '%s'" % klass + if self.allow_none: + return result + ' or None' + return result + + def instance_init(self, obj): + self._resolve_classes() + super().instance_init(obj) + + def _resolve_classes(self): + if isinstance(self.klass, str): + self.klass = self._resolve_string(self.klass) + if isinstance(self.default_value, str): + self.default_value = self._resolve_string(self.default_value) + + def default_value_repr(self): + value = self.default_value + if isinstance(value, str): + return repr(value) + else: + return repr(f'{value.__module__}.{value.__name__}') + + +class Instance(ClassBasedTraitType): + """A trait whose value must be an instance of a specified class. + + The value can also be an instance of a subclass of the specified class. + + Subclasses can declare default classes by overriding the klass attribute + """ + + klass = None + + def __init__(self, klass=None, args=None, kw=None, **kwargs): + """Construct an Instance trait. + + This trait allows values that are instances of a particular + class or its subclasses. Our implementation is quite different + from that of enthough.traits as we don't allow instances to be used + for klass and we handle the ``args`` and ``kw`` arguments differently. + + Parameters + ---------- + klass : class, str + The class that forms the basis for the trait. Class names + can also be specified as strings, like 'foo.bar.Bar'. + args : tuple + Positional arguments for generating the default value. + kw : dict + Keyword arguments for generating the default value. + allow_none : bool [ default False ] + Indicates whether None is allowed as a value. + + Notes + ----- + If both ``args`` and ``kw`` are None, then the default value is None. + If ``args`` is a tuple and ``kw`` is a dict, then the default is + created as ``klass(*args, **kw)``. If exactly one of ``args`` or ``kw`` is + None, the None is replaced by ``()`` or ``{}``, respectively. + """ + if klass is None: + klass = self.klass + + if (klass is not None) and (inspect.isclass(klass) or isinstance(klass, str)): + self.klass = klass + else: + raise TraitError('The klass attribute must be a class' + ' not: %r' % klass) + + if (kw is not None) and not isinstance(kw, dict): + raise TraitError("The 'kw' argument must be a dict or None.") + if (args is not None) and not isinstance(args, tuple): + raise TraitError("The 'args' argument must be a tuple or None.") + + self.default_args = args + self.default_kwargs = kw + + super(Instance, self).__init__(**kwargs) + + def validate(self, obj, value): + if isinstance(value, self.klass): + return value + else: + self.error(obj, value) + + def info(self): + if isinstance(self.klass, str): + result = add_article(self.klass) + else: + result = describe("a", self.klass) + if self.allow_none: + result += ' or None' + return result + + def instance_init(self, obj): + self._resolve_classes() + super().instance_init(obj) + + def _resolve_classes(self): + if isinstance(self.klass, str): + self.klass = self._resolve_string(self.klass) + + def make_dynamic_default(self): + if (self.default_args is None) and (self.default_kwargs is None): + return None + return self.klass(*(self.default_args or ()), + **(self.default_kwargs or {})) + + def default_value_repr(self): + return repr(self.make_dynamic_default()) + + def from_string(self, s): + return _safe_literal_eval(s) + + +class ForwardDeclaredMixin(object): + """ + Mixin for forward-declared versions of Instance and Type. + """ + def _resolve_string(self, string): + """ + Find the specified class name by looking for it in the module in which + our this_class attribute was defined. + """ + modname = self.this_class.__module__ + return import_item('.'.join([modname, string])) + + +class ForwardDeclaredType(ForwardDeclaredMixin, Type): + """ + Forward-declared version of Type. + """ + pass + + +class ForwardDeclaredInstance(ForwardDeclaredMixin, Instance): + """ + Forward-declared version of Instance. + """ + pass + + +class This(ClassBasedTraitType): + """A trait for instances of the class containing this trait. + + Because how how and when class bodies are executed, the ``This`` + trait can only have a default value of None. This, and because we + always validate default values, ``allow_none`` is *always* true. + """ + + info_text = 'an instance of the same type as the receiver or None' + + def __init__(self, **kwargs): + super(This, self).__init__(None, **kwargs) + + def validate(self, obj, value): + # What if value is a superclass of obj.__class__? This is + # complicated if it was the superclass that defined the This + # trait. + if isinstance(value, self.this_class) or (value is None): + return value + else: + self.error(obj, value) + + +class Union(TraitType): + """A trait type representing a Union type.""" + + def __init__(self, trait_types, **kwargs): + """Construct a Union trait. + + This trait allows values that are allowed by at least one of the + specified trait types. A Union traitlet cannot have metadata on + its own, besides the metadata of the listed types. + + Parameters + ---------- + trait_types : sequence + The list of trait types of length at least 1. + + Notes + ----- + Union([Float(), Bool(), Int()]) attempts to validate the provided values + with the validation function of Float, then Bool, and finally Int. + """ + self.trait_types = list(trait_types) + self.info_text = " or ".join([tt.info() for tt in self.trait_types]) + super(Union, self).__init__(**kwargs) + + def default(self, obj=None): + default = super(Union, self).default(obj) + for t in self.trait_types: + if default is Undefined: + default = t.default(obj) + else: + break + return default + + def class_init(self, cls, name): + for trait_type in reversed(self.trait_types): + trait_type.class_init(cls, None) + super(Union, self).class_init(cls, name) + + def instance_init(self, obj): + for trait_type in reversed(self.trait_types): + trait_type.instance_init(obj) + super(Union, self).instance_init(obj) + + def validate(self, obj, value): + with obj.cross_validation_lock: + for trait_type in self.trait_types: + try: + v = trait_type._validate(obj, value) + # In the case of an element trait, the name is None + if self.name is not None: + setattr(obj, '_' + self.name + '_metadata', trait_type.metadata) + return v + except TraitError: + continue + self.error(obj, value) + + def __or__(self, other): + if isinstance(other, Union): + return Union(self.trait_types + other.trait_types) + else: + return Union(self.trait_types + [other]) + + +#----------------------------------------------------------------------------- +# Basic TraitTypes implementations/subclasses +#----------------------------------------------------------------------------- + + +class Any(TraitType): + """A trait which allows any value.""" + default_value = None + allow_none = True + info_text = 'any value' + + +def _validate_bounds(trait, obj, value): + """ + Validate that a number to be applied to a trait is between bounds. + + If value is not between min_bound and max_bound, this raises a + TraitError with an error message appropriate for this trait. + """ + if trait.min is not None and value < trait.min: + raise TraitError( + "The value of the '{name}' trait of {klass} instance should " + "not be less than {min_bound}, but a value of {value} was " + "specified".format( + name=trait.name, klass=class_of(obj), + value=value, min_bound=trait.min)) + if trait.max is not None and value > trait.max: + raise TraitError( + "The value of the '{name}' trait of {klass} instance should " + "not be greater than {max_bound}, but a value of {value} was " + "specified".format( + name=trait.name, klass=class_of(obj), + value=value, max_bound=trait.max)) + return value + + +class Int(TraitType): + """An int trait.""" + + default_value = 0 + info_text = 'an int' + + def __init__(self, default_value=Undefined, allow_none=False, **kwargs): + self.min = kwargs.pop('min', None) + self.max = kwargs.pop('max', None) + super(Int, self).__init__(default_value=default_value, + allow_none=allow_none, **kwargs) + + def validate(self, obj, value): + if not isinstance(value, int): + self.error(obj, value) + return _validate_bounds(self, obj, value) + + def from_string(self, s): + if self.allow_none and s == 'None': + return None + return int(s) + + +class CInt(Int): + """A casting version of the int trait.""" + + def validate(self, obj, value): + try: + value = int(value) + except Exception: + self.error(obj, value) + return _validate_bounds(self, obj, value) + + +Long, CLong = Int, CInt +Integer = Int + + +class Float(TraitType): + """A float trait.""" + + default_value = 0.0 + info_text = 'a float' + + def __init__(self, default_value=Undefined, allow_none=False, **kwargs): + self.min = kwargs.pop('min', -float('inf')) + self.max = kwargs.pop('max', float('inf')) + super(Float, self).__init__(default_value=default_value, + allow_none=allow_none, **kwargs) + + def validate(self, obj, value): + if isinstance(value, int): + value = float(value) + if not isinstance(value, float): + self.error(obj, value) + return _validate_bounds(self, obj, value) + + def from_string(self, s): + if self.allow_none and s == 'None': + return None + return float(s) + + +class CFloat(Float): + """A casting version of the float trait.""" + + def validate(self, obj, value): + try: + value = float(value) + except Exception: + self.error(obj, value) + return _validate_bounds(self, obj, value) + + +class Complex(TraitType): + """A trait for complex numbers.""" + + default_value = 0.0 + 0.0j + info_text = 'a complex number' + + def validate(self, obj, value): + if isinstance(value, complex): + return value + if isinstance(value, (float, int)): + return complex(value) + self.error(obj, value) + + def from_string(self, s): + if self.allow_none and s == 'None': + return None + return complex(s) + + +class CComplex(Complex): + """A casting version of the complex number trait.""" + + def validate (self, obj, value): + try: + return complex(value) + except Exception: + self.error(obj, value) + +# We should always be explicit about whether we're using bytes or unicode, both +# for Python 3 conversion and for reliable unicode behaviour on Python 2. So +# we don't have a Str type. +class Bytes(TraitType): + """A trait for byte strings.""" + + default_value = b'' + info_text = 'a bytes object' + + def validate(self, obj, value): + if isinstance(value, bytes): + return value + self.error(obj, value) + + def from_string(self, s): + if self.allow_none and s == "None": + return None + if len(s) >= 3: + # handle deprecated b"string" + for quote in ('"', "'"): + if s[:2] == f"b{quote}" and s[-1] == quote: + old_s = s + s = s[2:-1] + warn( + "Supporting extra quotes around Bytes is deprecated in traitlets 5.0. " + "Use %r instead of %r." % (s, old_s), + FutureWarning) + break + return s.encode("utf8") + + +class CBytes(Bytes): + """A casting version of the byte string trait.""" + + def validate(self, obj, value): + try: + return bytes(value) + except Exception: + self.error(obj, value) + + +class Unicode(TraitType): + """A trait for unicode strings.""" + + default_value = '' + info_text = 'a unicode string' + + def validate(self, obj, value): + if isinstance(value, str): + return value + if isinstance(value, bytes): + try: + return value.decode('ascii', 'strict') + except UnicodeDecodeError: + msg = "Could not decode {!r} for unicode trait '{}' of {} instance." + raise TraitError(msg.format(value, self.name, class_of(obj))) + self.error(obj, value) + + def from_string(self, s): + if self.allow_none and s == 'None': + return None + s = os.path.expanduser(s) + if len(s) >= 2: + # handle deprecated "1" + for c in ('"', "'"): + if s[0] == s[-1] == c: + old_s = s + s = s[1:-1] + warn( + "Supporting extra quotes around Unicode is deprecated in traitlets 5.0. " + "Use %r instead of %r – or use CUnicode." % (s, old_s), + FutureWarning) + return s + + + +class CUnicode(Unicode): + """A casting version of the unicode trait.""" + + def validate(self, obj, value): + try: + return str(value) + except Exception: + self.error(obj, value) + + +class ObjectName(TraitType): + """A string holding a valid object name in this version of Python. + + This does not check that the name exists in any scope.""" + info_text = "a valid object identifier in Python" + + coerce_str = staticmethod(lambda _,s: s) + + def validate(self, obj, value): + value = self.coerce_str(obj, value) + + if isinstance(value, str) and isidentifier(value): + return value + self.error(obj, value) + + def from_string(self, s): + if self.allow_none and s == 'None': + return None + return s + +class DottedObjectName(ObjectName): + """A string holding a valid dotted object name in Python, such as A.b3._c""" + def validate(self, obj, value): + value = self.coerce_str(obj, value) + + if isinstance(value, str) and all(isidentifier(a) + for a in value.split('.')): + return value + self.error(obj, value) + + +class Bool(TraitType): + """A boolean (True, False) trait.""" + + default_value = False + info_text = 'a boolean' + + def validate(self, obj, value): + if isinstance(value, bool): + return value + elif isinstance(value, int): + if value == 1: + return True + elif value == 0: + return False + self.error(obj, value) + + def from_string(self, s): + if self.allow_none and s == 'None': + return None + s = s.lower() + if s in {'true', '1'}: + return True + elif s in {'false', '0'}: + return False + else: + raise ValueError("%r is not 1, 0, true, or false") + + +class CBool(Bool): + """A casting version of the boolean trait.""" + + def validate(self, obj, value): + try: + return bool(value) + except Exception: + self.error(obj, value) + + +class Enum(TraitType): + """An enum whose value must be in a given sequence.""" + + def __init__(self, values, default_value=Undefined, **kwargs): + self.values = values + if kwargs.get('allow_none', False) and default_value is Undefined: + default_value = None + super(Enum, self).__init__(default_value, **kwargs) + + def validate(self, obj, value): + if value in self.values: + return value + self.error(obj, value) + + def _choices_str(self, as_rst=False): + """ Returns a description of the trait choices (not none).""" + choices = self.values + if as_rst: + choices = '|'.join('``%r``' % x for x in choices) + else: + choices = repr(list(choices)) + return choices + + def _info(self, as_rst=False): + """ Returns a description of the trait.""" + none = (' or %s' % ('`None`' if as_rst else 'None') + if self.allow_none else + '') + return 'any of %s%s' % (self._choices_str(as_rst), none) + + def info(self): + return self._info(as_rst=False) + + def info_rst(self): + return self._info(as_rst=True) + + def from_string(self, s): + try: + return self.validate(None, s) + except TraitError: + return _safe_literal_eval(s) + + +class CaselessStrEnum(Enum): + """An enum of strings where the case should be ignored.""" + + def __init__(self, values, default_value=Undefined, **kwargs): + super().__init__(values, default_value=default_value, **kwargs) + + def validate(self, obj, value): + if not isinstance(value, str): + self.error(obj, value) + + for v in self.values: + if v.lower() == value.lower(): + return v + self.error(obj, value) + + def _info(self, as_rst=False): + """ Returns a description of the trait.""" + none = (' or %s' % ('`None`' if as_rst else 'None') + if self.allow_none else + '') + return 'any of %s (case-insensitive)%s' % (self._choices_str(as_rst), none) + + def info(self): + return self._info(as_rst=False) + + def info_rst(self): + return self._info(as_rst=True) + + +class FuzzyEnum(Enum): + """An case-ignoring enum matching choices by unique prefixes/substrings.""" + + case_sensitive = False + #: If True, choices match anywhere in the string, otherwise match prefixes. + substring_matching = False + + def __init__(self, values, default_value=Undefined, + case_sensitive=False, substring_matching=False, **kwargs): + self.case_sensitive = case_sensitive + self.substring_matching = substring_matching + super().__init__(values, default_value=default_value, **kwargs) + + def validate(self, obj, value): + if not isinstance(value, str): + self.error(obj, value) + + conv_func = (lambda c: c) if self.case_sensitive else lambda c: c.lower() + substring_matching = self.substring_matching + match_func = ((lambda v, c: v in c) + if substring_matching + else (lambda v, c: c.startswith(v))) + value = conv_func(value) + choices = self.values + matches = [match_func(value, conv_func(c)) for c in choices] + if sum(matches) == 1: + for v, m in zip(choices, matches): + if m: + return v + + self.error(obj, value) + + def _info(self, as_rst=False): + """ Returns a description of the trait.""" + none = (' or %s' % ('`None`' if as_rst else 'None') + if self.allow_none else + '') + case = 'sensitive' if self.case_sensitive else 'insensitive' + substr = 'substring' if self.substring_matching else 'prefix' + return 'any case-%s %s of %s%s' % (case, substr, + self._choices_str(as_rst), + none) + + def info(self): + return self._info(as_rst=False) + + def info_rst(self): + return self._info(as_rst=True) + + +class Container(Instance): + """An instance of a container (list, set, etc.) + + To be subclassed by overriding klass. + """ + + klass = None + _cast_types = () + _valid_defaults = SequenceTypes + _trait = None + _literal_from_string_pairs = ("[]", "()") + + def __init__(self, trait=None, default_value=Undefined, **kwargs): + """Create a container trait type from a list, set, or tuple. + + The default value is created by doing ``List(default_value)``, + which creates a copy of the ``default_value``. + + ``trait`` can be specified, which restricts the type of elements + in the container to that TraitType. + + If only one arg is given and it is not a Trait, it is taken as + ``default_value``: + + ``c = List([1, 2, 3])`` + + Parameters + ---------- + trait : TraitType [ optional ] + the type for restricting the contents of the Container. If unspecified, + types are not checked. + default_value : SequenceType [ optional ] + The default value for the Trait. Must be list/tuple/set, and + will be cast to the container type. + allow_none : bool [ default False ] + Whether to allow the value to be None + **kwargs : any + further keys for extensions to the Trait (e.g. config) + + """ + + # allow List([values]): + if trait is not None and default_value is Undefined and not is_trait(trait): + default_value = trait + trait = None + + if default_value is None and not kwargs.get("allow_none", False): + # improve backward-compatibility for possible subclasses + # specifying default_value=None as default, + # keeping 'unspecified' behavior (i.e. empty container) + warn( + f"Specifying {self.__class__.__name__}(default_value=None)" + " for no default is deprecated in traitlets 5.0.5." + " Use default_value=Undefined", + DeprecationWarning, + stacklevel=2, + ) + default_value = Undefined + + if default_value is Undefined: + args = () + elif default_value is None: + # default_value back on kwargs for super() to handle + args = () + kwargs["default_value"] = None + elif isinstance(default_value, self._valid_defaults): + args = (default_value,) + else: + raise TypeError( + "default value of %s was %s" % (self.__class__.__name__, default_value) + ) + + if is_trait(trait): + if isinstance(trait, type): + warn( + "Traits should be given as instances, not types (for example, `Int()`, not `Int`)." + " Passing types is deprecated in traitlets 4.1.", + DeprecationWarning, + stacklevel=3, + ) + self._trait = trait() if isinstance(trait, type) else trait + elif trait is not None: + raise TypeError( + "`trait` must be a Trait or None, got %s" % repr_type(trait) + ) + + super(Container, self).__init__(klass=self.klass, args=args, **kwargs) + + def validate(self, obj, value): + if isinstance(value, self._cast_types): + value = self.klass(value) + value = super(Container, self).validate(obj, value) + if value is None: + return value + + value = self.validate_elements(obj, value) + + return value + + def validate_elements(self, obj, value): + validated = [] + if self._trait is None or isinstance(self._trait, Any): + return value + for v in value: + try: + v = self._trait._validate(obj, v) + except TraitError as error: + self.error(obj, v, error) + else: + validated.append(v) + return self.klass(validated) + + def class_init(self, cls, name): + if isinstance(self._trait, TraitType): + self._trait.class_init(cls, None) + super(Container, self).class_init(cls, name) + + def instance_init(self, obj): + if isinstance(self._trait, TraitType): + self._trait.instance_init(obj) + super(Container, self).instance_init(obj) + + def from_string(self, s): + """Load value from a single string""" + if not isinstance(s, str): + raise TraitError(f"Expected string, got {s!r}") + try: + test = literal_eval(s) + except Exception: + test = None + return self.validate(None, test) + + def from_string_list(self, s_list): + """Return the value from a list of config strings + + This is where we parse CLI configuration + """ + if len(s_list) == 1: + # check for deprecated --Class.trait="['a', 'b', 'c']" + r = s_list[0] + if r == "None" and self.allow_none: + return None + if len(r) >= 2 and any( + r.startswith(start) and r.endswith(end) + for start, end in self._literal_from_string_pairs + ): + if self.this_class: + clsname = self.this_class.__name__ + "." + else: + clsname = "" + + warn( + "--{0}={1} for containers is deprecated in traitlets 5.0. " + "You can pass `--{0} item` ... multiple times to add items to a list.".format( + clsname + self.name, r + ), + FutureWarning, + ) + return self.klass(literal_eval(r)) + sig = inspect.signature(self.item_from_string) + if "index" in sig.parameters: + item_from_string = self.item_from_string + else: + # backward-compat: allow item_from_string to ignore index arg + item_from_string = lambda s, index=None: self.item_from_string(s) + return self.klass( + [item_from_string(s, index=idx) for idx, s in enumerate(s_list)] + ) + + def item_from_string(self, s, index=None): + """Cast a single item from a string + + Evaluated when parsing CLI configuration from a string + """ + if self._trait: + return self._trait.from_string(s) + else: + return s + + +class List(Container): + """An instance of a Python list.""" + klass = list + _cast_types = (tuple,) + + def __init__( + self, + trait=None, + default_value=Undefined, + minlen=0, + maxlen=sys.maxsize, + **kwargs, + ): + """Create a List trait type from a list, set, or tuple. + + The default value is created by doing ``list(default_value)``, + which creates a copy of the ``default_value``. + + ``trait`` can be specified, which restricts the type of elements + in the container to that TraitType. + + If only one arg is given and it is not a Trait, it is taken as + ``default_value``: + + ``c = List([1, 2, 3])`` + + Parameters + ---------- + trait : TraitType [ optional ] + the type for restricting the contents of the Container. + If unspecified, types are not checked. + default_value : SequenceType [ optional ] + The default value for the Trait. Must be list/tuple/set, and + will be cast to the container type. + minlen : Int [ default 0 ] + The minimum length of the input list + maxlen : Int [ default sys.maxsize ] + The maximum length of the input list + """ + self._minlen = minlen + self._maxlen = maxlen + super(List, self).__init__(trait=trait, default_value=default_value, + **kwargs) + + def length_error(self, obj, value): + e = "The '%s' trait of %s instance must be of length %i <= L <= %i, but a value of %s was specified." \ + % (self.name, class_of(obj), self._minlen, self._maxlen, value) + raise TraitError(e) + + def validate_elements(self, obj, value): + length = len(value) + if length < self._minlen or length > self._maxlen: + self.length_error(obj, value) + + return super(List, self).validate_elements(obj, value) + + +class Set(List): + """An instance of a Python set.""" + klass = set + _cast_types = (tuple, list) + + _literal_from_string_pairs = ("[]", "()", "{}") + + # Redefine __init__ just to make the docstring more accurate. + def __init__( + self, + trait=None, + default_value=Undefined, + minlen=0, + maxlen=sys.maxsize, + **kwargs, + ): + """Create a Set trait type from a list, set, or tuple. + + The default value is created by doing ``set(default_value)``, + which creates a copy of the ``default_value``. + + ``trait`` can be specified, which restricts the type of elements + in the container to that TraitType. + + If only one arg is given and it is not a Trait, it is taken as + ``default_value``: + + ``c = Set({1, 2, 3})`` + + Parameters + ---------- + trait : TraitType [ optional ] + the type for restricting the contents of the Container. + If unspecified, types are not checked. + default_value : SequenceType [ optional ] + The default value for the Trait. Must be list/tuple/set, and + will be cast to the container type. + minlen : Int [ default 0 ] + The minimum length of the input list + maxlen : Int [ default sys.maxsize ] + The maximum length of the input list + """ + super(Set, self).__init__(trait, default_value, minlen, maxlen, **kwargs) + + def default_value_repr(self): + # Ensure default value is sorted for a reproducible build + list_repr = repr(sorted(self.make_dynamic_default())) + if list_repr == '[]': + return 'set()' + return '{'+list_repr[1:-1]+'}' + + +class Tuple(Container): + """An instance of a Python tuple.""" + + klass = tuple + _cast_types = (list,) + + def __init__(self, *traits, **kwargs): + """Create a tuple from a list, set, or tuple. + + Create a fixed-type tuple with Traits: + + ``t = Tuple(Int(), Str(), CStr())`` + + would be length 3, with Int,Str,CStr for each element. + + If only one arg is given and it is not a Trait, it is taken as + default_value: + + ``t = Tuple((1, 2, 3))`` + + Otherwise, ``default_value`` *must* be specified by keyword. + + Parameters + ---------- + `*traits` : TraitTypes [ optional ] + the types for restricting the contents of the Tuple. If unspecified, + types are not checked. If specified, then each positional argument + corresponds to an element of the tuple. Tuples defined with traits + are of fixed length. + default_value : SequenceType [ optional ] + The default value for the Tuple. Must be list/tuple/set, and + will be cast to a tuple. If ``traits`` are specified, + ``default_value`` must conform to the shape and type they specify. + """ + default_value = kwargs.pop("default_value", Undefined) + # allow Tuple((values,)): + if len(traits) == 1 and default_value is Undefined and not is_trait(traits[0]): + default_value = traits[0] + traits = () + + if default_value is None and not kwargs.get("allow_none", False): + # improve backward-compatibility for possible subclasses + # specifying default_value=None as default, + # keeping 'unspecified' behavior (i.e. empty container) + warn( + f"Specifying {self.__class__.__name__}(default_value=None)" + " for no default is deprecated in traitlets 5.0.5." + " Use default_value=Undefined", + DeprecationWarning, + stacklevel=2, + ) + default_value = Undefined + + if default_value is Undefined: + args = () + elif default_value is None: + # default_value back on kwargs for super() to handle + args = () + kwargs["default_value"] = None + elif isinstance(default_value, self._valid_defaults): + args = (default_value,) + else: + raise TypeError( + "default value of %s was %s" % (self.__class__.__name__, default_value) + ) + + self._traits = [] + for trait in traits: + if isinstance(trait, type): + warn( + "Traits should be given as instances, not types (for example, `Int()`, not `Int`)" + " Passing types is deprecated in traitlets 4.1.", + DeprecationWarning, + stacklevel=2, + ) + trait = trait() + self._traits.append(trait) + + if self._traits and (default_value is None or default_value is Undefined): + # don't allow default to be an empty container if length is specified + args = None + super(Container, self).__init__(klass=self.klass, args=args, **kwargs) + + def item_from_string(self, s, index): + """Cast a single item from a string + + Evaluated when parsing CLI configuration from a string + """ + if not self._traits or index >= len(self._traits): + # return s instead of raising index error + # length errors will be raised later on validation + return s + return self._traits[index].from_string(s) + + def validate_elements(self, obj, value): + if not self._traits: + # nothing to validate + return value + if len(value) != len(self._traits): + e = "The '%s' trait of %s instance requires %i elements, but a value of %s was specified." \ + % (self.name, class_of(obj), len(self._traits), repr_type(value)) + raise TraitError(e) + + validated = [] + for t, v in zip(self._traits, value): + try: + v = t._validate(obj, v) + except TraitError as error: + self.error(obj, v, error) + else: + validated.append(v) + return tuple(validated) + + def class_init(self, cls, name): + for trait in self._traits: + if isinstance(trait, TraitType): + trait.class_init(cls, None) + super(Container, self).class_init(cls, name) + + def instance_init(self, obj): + for trait in self._traits: + if isinstance(trait, TraitType): + trait.instance_init(obj) + super(Container, self).instance_init(obj) + + +class Dict(Instance): + """An instance of a Python dict. + + One or more traits can be passed to the constructor + to validate the keys and/or values of the dict. + If you need more detailed validation, + you may use a custom validator method. + + .. versionchanged:: 5.0 + Added key_trait for validating dict keys. + + .. versionchanged:: 5.0 + Deprecated ambiguous ``trait``, ``traits`` args in favor of ``value_trait``, ``per_key_traits``. + """ + _value_trait = None + _key_trait = None + + def __init__(self, value_trait=None, per_key_traits=None, key_trait=None, default_value=Undefined, + **kwargs): + """Create a dict trait type from a Python dict. + + The default value is created by doing ``dict(default_value)``, + which creates a copy of the ``default_value``. + + Parameters + ---------- + value_trait : TraitType [ optional ] + The specified trait type to check and use to restrict the values of + the dict. If unspecified, values are not checked. + per_key_traits : Dictionary of {keys:trait types} [ optional, keyword-only ] + A Python dictionary containing the types that are valid for + restricting the values of the dict on a per-key basis. + Each value in this dict should be a Trait for validating + key_trait : TraitType [ optional, keyword-only ] + The type for restricting the keys of the dict. If + unspecified, the types of the keys are not checked. + default_value : SequenceType [ optional, keyword-only ] + The default value for the Dict. Must be dict, tuple, or None, and + will be cast to a dict if not None. If any key or value traits are specified, + the `default_value` must conform to the constraints. + + Examples + -------- + >>> d = Dict(Unicode()) + a dict whose values must be text + + >>> d2 = Dict(per_key_traits={"n": Integer(), "s": Unicode()}) + d2['n'] must be an integer + d2['s'] must be text + + >>> d3 = Dict(value_trait=Integer(), key_trait=Unicode()) + d3's keys must be text + d3's values must be integers + """ + + # handle deprecated keywords + trait = kwargs.pop('trait', None) + if trait is not None: + if value_trait is not None: + raise TypeError("Found a value for both `value_trait` and its deprecated alias `trait`.") + value_trait = trait + warn( + "Keyword `trait` is deprecated in traitlets 5.0, use `value_trait` instead", + DeprecationWarning, + stacklevel=2, + ) + traits = kwargs.pop("traits", None) + if traits is not None: + if per_key_traits is not None: + raise TypeError("Found a value for both `per_key_traits` and its deprecated alias `traits`.") + per_key_traits = traits + warn( + "Keyword `traits` is deprecated in traitlets 5.0, use `per_key_traits` instead", + DeprecationWarning, + stacklevel=2, + ) + + # Handling positional arguments + if default_value is Undefined and value_trait is not None: + if not is_trait(value_trait): + default_value = value_trait + value_trait = None + + if key_trait is None and per_key_traits is not None: + if is_trait(per_key_traits): + key_trait = per_key_traits + per_key_traits = None + + # Handling default value + if default_value is Undefined: + default_value = {} + if default_value is None: + args = None + elif isinstance(default_value, dict): + args = (default_value,) + elif isinstance(default_value, SequenceTypes): + args = (default_value,) + else: + raise TypeError('default value of Dict was %s' % default_value) + + # Case where a type of TraitType is provided rather than an instance + if is_trait(value_trait): + if isinstance(value_trait, type): + warn("Traits should be given as instances, not types (for example, `Int()`, not `Int`)" + " Passing types is deprecated in traitlets 4.1.", + DeprecationWarning, stacklevel=2) + value_trait = value_trait() + self._value_trait = value_trait + elif value_trait is not None: + raise TypeError("`value_trait` must be a Trait or None, got %s" % repr_type(value_trait)) + + if is_trait(key_trait): + if isinstance(key_trait, type): + warn("Traits should be given as instances, not types (for example, `Int()`, not `Int`)" + " Passing types is deprecated in traitlets 4.1.", + DeprecationWarning, stacklevel=2) + key_trait = key_trait() + self._key_trait = key_trait + elif key_trait is not None: + raise TypeError("`key_trait` must be a Trait or None, got %s" % repr_type(key_trait)) + + self._per_key_traits = per_key_traits + + super(Dict, self).__init__(klass=dict, args=args, **kwargs) + + def element_error(self, obj, element, validator, side='Values'): + e = side + " of the '%s' trait of %s instance must be %s, but a value of %s was specified." \ + % (self.name, class_of(obj), validator.info(), repr_type(element)) + raise TraitError(e) + + def validate(self, obj, value): + value = super(Dict, self).validate(obj, value) + if value is None: + return value + value = self.validate_elements(obj, value) + return value + + def validate_elements(self, obj, value): + per_key_override = self._per_key_traits or {} + key_trait = self._key_trait + value_trait = self._value_trait + if not (key_trait or value_trait or per_key_override): + return value + + validated = {} + for key in value: + v = value[key] + if key_trait: + try: + key = key_trait._validate(obj, key) + except TraitError as error: + self.element_error(obj, key, key_trait, 'Keys') + active_value_trait = per_key_override.get(key, value_trait) + if active_value_trait: + try: + v = active_value_trait._validate(obj, v) + except TraitError: + self.element_error(obj, v, active_value_trait, 'Values') + validated[key] = v + + return self.klass(validated) + + def class_init(self, cls, name): + if isinstance(self._value_trait, TraitType): + self._value_trait.class_init(cls, None) + if isinstance(self._key_trait, TraitType): + self._key_trait.class_init(cls, None) + if self._per_key_traits is not None: + for trait in self._per_key_traits.values(): + trait.class_init(cls, None) + super(Dict, self).class_init(cls, name) + + def instance_init(self, obj): + if isinstance(self._value_trait, TraitType): + self._value_trait.instance_init(obj) + if isinstance(self._key_trait, TraitType): + self._key_trait.instance_init(obj) + if self._per_key_traits is not None: + for trait in self._per_key_traits.values(): + trait.instance_init(obj) + super(Dict, self).instance_init(obj) + + def from_string(self, s): + """Load value from a single string""" + if not isinstance(s, str): + raise TypeError(f"from_string expects a string, got {repr(s)} of type {type(s)}") + try: + return self.from_string_list([s]) + except Exception: + test = _safe_literal_eval(s) + if isinstance(test, dict): + return test + raise + + def from_string_list(self, s_list): + """Return a dict from a list of config strings. + + This is where we parse CLI configuration. + + Each item should have the form ``"key=value"``. + + item parsing is done in :meth:`.item_from_string`. + """ + if len(s_list) == 1 and s_list[0] == "None" and self.allow_none: + return None + if ( + len(s_list) == 1 + and s_list[0].startswith("{") + and s_list[0].endswith("}") + ): + warn( + "--{0}={1} for dict-traits is deprecated in traitlets 5.0. " + "You can pass --{0} ... multiple times to add items to a dict.".format( + self.name, + s_list[0], + ), + FutureWarning, + ) + + return literal_eval(s_list[0]) + + combined = {} + for d in [self.item_from_string(s) for s in s_list]: + combined.update(d) + return combined + + def item_from_string(self, s): + """Cast a single-key dict from a string. + + Evaluated when parsing CLI configuration from a string. + + Dicts expect strings of the form key=value. + + Returns a one-key dictionary, + which will be merged in :meth:`.from_string_list`. + """ + + if '=' not in s: + raise TraitError( + "'%s' options must have the form 'key=value', got %s" + % (self.__class__.__name__, repr(s),) + ) + key, value = s.split("=", 1) + + # cast key with key trait, if defined + if self._key_trait: + key = self._key_trait.from_string(key) + + # cast value with value trait, if defined (per-key or global) + value_trait = (self._per_key_traits or {}).get(key, self._value_trait) + if value_trait: + value = value_trait.from_string(value) + return {key: value} + + +class TCPAddress(TraitType): + """A trait for an (ip, port) tuple. + + This allows for both IPv4 IP addresses as well as hostnames. + """ + + default_value = ('127.0.0.1', 0) + info_text = 'an (ip, port) tuple' + + def validate(self, obj, value): + if isinstance(value, tuple): + if len(value) == 2: + if isinstance(value[0], str) and isinstance(value[1], int): + port = value[1] + if port >= 0 and port <= 65535: + return value + self.error(obj, value) + + def from_string(self, s): + if self.allow_none and s == 'None': + return None + if ':' not in s: + raise ValueError('Require `ip:port`, got %r' % s) + ip, port = s.split(':', 1) + port = int(port) + return (ip, port) + + +class CRegExp(TraitType): + """A casting compiled regular expression trait. + + Accepts both strings and compiled regular expressions. The resulting + attribute will be a compiled regular expression.""" + + info_text = 'a regular expression' + + def validate(self, obj, value): + try: + return re.compile(value) + except Exception: + self.error(obj, value) + + +class UseEnum(TraitType): + """Use a Enum class as model for the data type description. + Note that if no default-value is provided, the first enum-value is used + as default-value. + + .. sourcecode:: python + + # -- SINCE: Python 3.4 (or install backport: pip install enum34) + import enum + from traitlets import HasTraits, UseEnum + + class Color(enum.Enum): + red = 1 # -- IMPLICIT: default_value + blue = 2 + green = 3 + + class MyEntity(HasTraits): + color = UseEnum(Color, default_value=Color.blue) + + entity = MyEntity(color=Color.red) + entity.color = Color.green # USE: Enum-value (preferred) + entity.color = "green" # USE: name (as string) + entity.color = "Color.green" # USE: scoped-name (as string) + entity.color = 3 # USE: number (as int) + assert entity.color is Color.green + """ + default_value = None + info_text = "Trait type adapter to a Enum class" + + def __init__(self, enum_class, default_value=None, **kwargs): + assert issubclass(enum_class, enum.Enum), \ + "REQUIRE: enum.Enum, but was: %r" % enum_class + allow_none = kwargs.get("allow_none", False) + if default_value is None and not allow_none: + default_value = list(enum_class.__members__.values())[0] + super(UseEnum, self).__init__(default_value=default_value, **kwargs) + self.enum_class = enum_class + self.name_prefix = enum_class.__name__ + "." + + def select_by_number(self, value, default=Undefined): + """Selects enum-value by using its number-constant.""" + assert isinstance(value, int) + enum_members = self.enum_class.__members__ + for enum_item in enum_members.values(): + if enum_item.value == value: + return enum_item + # -- NOT FOUND: + return default + + def select_by_name(self, value, default=Undefined): + """Selects enum-value by using its name or scoped-name.""" + assert isinstance(value, str) + if value.startswith(self.name_prefix): + # -- SUPPORT SCOPED-NAMES, like: "Color.red" => "red" + value = value.replace(self.name_prefix, "", 1) + return self.enum_class.__members__.get(value, default) + + def validate(self, obj, value): + if isinstance(value, self.enum_class): + return value + elif isinstance(value, int): + # -- CONVERT: number => enum_value (item) + value2 = self.select_by_number(value) + if value2 is not Undefined: + return value2 + elif isinstance(value, str): + # -- CONVERT: name or scoped_name (as string) => enum_value (item) + value2 = self.select_by_name(value) + if value2 is not Undefined: + return value2 + elif value is None: + if self.allow_none: + return None + else: + return self.default_value + self.error(obj, value) + + def _choices_str(self, as_rst=False): + """ Returns a description of the trait choices (not none).""" + choices = self.enum_class.__members__.keys() + if as_rst: + return '|'.join('``%r``' % x for x in choices) + else: + return repr(list(choices)) # Listify because py3.4- prints odict-class + + def _info(self, as_rst=False): + """ Returns a description of the trait.""" + none = (' or %s' % ('`None`' if as_rst else 'None') + if self.allow_none else + '') + return 'any of %s%s' % (self._choices_str(as_rst), none) + + def info(self): + return self._info(as_rst=False) + + def info_rst(self): + return self._info(as_rst=True) + + + +class Callable(TraitType): + """A trait which is callable. + + Notes + ----- + Classes are callable, as are instances + with a __call__() method.""" + + info_text = 'a callable' + + def validate(self, obj, value): + if callable(value): + return value + else: + self.error(obj, value) + + +def _add_all(): + """add all trait types to `__all__` + + do in a function to avoid iterating through globals while defining local variables + """ + for _name, _value in globals().items(): + if not _name.startswith('_') and isinstance(_value, type) and issubclass(_value, TraitType): + __all__.append(_name) + +_add_all() diff --git a/.venv/lib/python3.8/site-packages/traitlets/utils/__init__.py b/.venv/lib/python3.8/site-packages/traitlets/utils/__init__.py new file mode 100644 index 00000000..aeca2bbe --- /dev/null +++ b/.venv/lib/python3.8/site-packages/traitlets/utils/__init__.py @@ -0,0 +1,6 @@ + +# vestigal things from IPython_genutils. +def cast_unicode(s, encoding='utf-8'): + if isinstance(s, bytes): + return s.decode(encoding, 'replace') + return s diff --git a/.venv/lib/python3.8/site-packages/traitlets/utils/__pycache__/__init__.cpython-38.pyc b/.venv/lib/python3.8/site-packages/traitlets/utils/__pycache__/__init__.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c2285d754dbb3aabb7d8ceeb54c27f41aef2c38a GIT binary patch literal 338 zcmYjNu};G<6ttbTgs5d?;14o{3=A+-2#LK*#lm8x_5&=(&dT9-*x^le zrUc#nBb^7tOJX=8LDn{aw!^EWZ485M|G-1FetMnRdy!USUjHda9#E;a}u zjx?y1hEhZxVh)yqv9}-0=Ty9%*0^-FGp_2aYt%jHYJCULR(P^FeZ=)cjlMD10*1On z(}r3~V+~4q>^5<%nt-yiCT&R13?mZ83qIyPeafulo|BWM__uRM_GuRL>2jsJ7S2<_ HHZLk1kGjTc(=rg5-3Uj{PAHd*v@UAZFGH3Y}=jvpegV_uj139viONlE(rF$}FT!D&C!=OFHb$qz z(x^_HB&sMVl^Qj{AP?hEritk`6YTV#A+8F;2?mM{0C8{$15aZ2D>m?@FKhU$$+~Rd zvn~U~bYN>Qsq6C5sVf}LQ!@&0BS@(D&L|FWy~0&=(JfmmcFk6>fe)&49#2$p8(BjLd_#zPSiK+`j0YrCdnc63o<$8C2tgHa zmQ5ihQ(0ydw}kjy#@RMQ)uxFMn!Y97CU=({&0x=wCYp#+;06?c4?#Wf+$sKf^nJ`& ZpS}ZkwD+>BZ`AMpUlqs2)@(r|Dx+N z2>q=W=RX3AyU?WW7zz=?jHEckFd8YzjL^u;(9EpR!ibs7O6|-E9hlq9d5uDsxy*yn zV`Llk{lgniB;OgP0poEYB2@?(>=Yt+ETTlET*+W4xsc0m;Wo64tA55JP*_!50rMYvuo7LeM8uAtT3RfEuNL?0KBmp ztCbcs?Tx$v!Ru_jhA@xO2|C6n=sr5aW2{Jp_6?X3WmaV0 zI>Nu8T{JeBF*aeeV6?UTK6)m`jQ8lvnaA@L+Xe2527hEISb-6k}?=2Y7fM5kxM0pF;F(>*ax(Tlvb%I$y*W!IdD`4kqibSppsm^ zkRY8HouF-D$K#uSZ`JKElHA`zup&opxBB7*q zs!4x6JK+UwCEX>TEV>s- z+Hg`Xuck#DrE(1>(~TR4`C}-D@5UEEVFiSp7b;NEfCsm3wc+0mMte!T7i2ujWeb-s zrS7UAj`C*La~|+lWdv2sTFBdKYtVeF%lJJU9S|<)7~aS6XEbnxsSx0Z_5n$Telw;x z_DO9HlAP7f1i3zGtGD;ngQwqYZr!Jw8xNmCU0;H;#k}qop?ibFg(79NoIXOdaqSFR zq49hGt;5tk?JtDAhD8%JYb#MalfneE+NCtf6GdrlYG`Y}J6hIeT$BewN7wpx>Cxu) z`s4M@je8Fp_v)+X1zU9DdTmE#$sxA6ukUTqGZS%DUpS+MQ_J4gFjq;&9|%#1+J;9s zi;jBiX(}&j@Pzsr-q{yT63?CVOq*X5?LCgP9hu5`s zzz;@+V6@27gY#RPQ}x!VL5EE^*G-!YgkHA}=W;$ecS@U^4>X7k_ZK^_&k&)FKA9&U;vVT?8(K4(E+(KQ@5npTGL3n|#lGPhJwi@h$A=x_V>k;y zb0}p+OsTjI>)J_jS@O6=xXEclg3#-p{`P-FKk3a0=L%Q8t69N@DPPkCA$3qD Lamga-8Lssok((W| literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/traitlets/utils/__pycache__/descriptions.cpython-38.pyc b/.venv/lib/python3.8/site-packages/traitlets/utils/__pycache__/descriptions.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..089f323a18c31a9e4657854e1e3cbc3bd877b92c GIT binary patch literal 4525 zcmbVPU2o)88Mcqd9%u5g%d%`2q?WTIs>why*%e5wRw!y08nH-(svBAM4crs2r zwsm}Fvzc`SBHJ6JO8p55;s%Lp#P8sO3*Yvte}N0i^Pb~zCS@rUk9@}G>pk!Lyr1V+ ztE(*w&p&_j_x>MmTh?dPS$rIH-ol&z42`ga9b5b6-`=-%pY1cTDjd;xVedP_72XSL zzag5!$G(q|w5C#X55fFni4M5An~A{ZDQA zXukVXJAYI#j4sLF3+KWw+=5-QGf%Hvk}uR!;fY4kICq{{h4;it{vzD7=6tuj(C4uv z27k6{9W8^yznU@8IBO<*)%Xg=|Az5ZaLM${!;0%Qb>nDFxkqawcI<&OOL*$0`UdfS zZr`!6+C6iU6?Kb7Os{aT?zKuj2KiXg#7M7T7vB`kORQ423-D90!YLZU|HK8~4I&D$s=g&!g>}a|w|{2~1~n}QE)?=!sHQUExsp+G$kjMdT!i^h zMuRZt0e>3A)3DXzc-{?UFbP#CbKTvnAKeY4iiUB>9}+2^O1_&Wp`M|=Z-eM4N+K1~ zRFu@cYFm##9^vqi&&fpQ5Zb%2dOhleJ>Cx5M5P@h?XKCBWiriV6cG7^Q%|Be=7SIv zMxhKvkME7A`9^il;dBxvD(C5l9~{g@J~*gZ9tH`moaABr6i~=8lVOe>{Dd$fUeTY% zieNM7)m!zs!B9v+Bs@vy;$Ghgj&W8N0wuv!x^PyH??CV* zO*Si>M7`5Ukf|t5HjLJCYy_u)Bmi<1Btz0DdP;^sYH_PkO?)P9)& zzaY!v2+W*}!vw0TBtJOdQO?`YLz{0x(glM#IG`iUg5b*VWJp#36y}&}J`GP~XOB*4 zEwMpHRC8V#4Y9i(ZzAm&aG=i!x{ zAB?dpl$yMTCm*NNSdi@w(_|Qd1oZyYQ0s9lPil;^G|!_!45O;%IZ?==uVFkD5EdGl zq+&`dz~xpd>#bVNdO3j$%YezJgQIW=BM)+e++1tJAd6HGe=Si)k<1m3LxrG0enza! z9o$G*vqF-Z6QUW6O*EK@XkEv^%hIlU(?f8+UL(X9H_=lc0r( zQ!XHj=C8}{ow60>^Eh2P$S9>7rzfE-n;6aDllaKB$CeEOyY%~g;;Y{;n|yn_IuoaY}!K&sbAJgn!*Tya z2HBr1$+6}iZ*8ebwv|QM<}}HI;c+N75t_nyQ~hx8#!Q_&+fp)!6kN<&8Y;bNg42j@?$OsOngnmYhQ@2e!w&gaC*beKsnT}ZFuFFVU5?}p zY6z3k*WT4nM{*fmpsgX|G_MZ$*AW3#f6TsZT{xGxFdTbwTQsZnzVOXg!Q`ND#1d9DE-iey zqCtCJv2c~abw)IRX)E|Mlre`DVP_7k0db+Uth}{?kV06LWK-1tDar>5OG#)7&_Q?@ zC6yBRaEyBZ5_+}mt8WE$o&R+zpo%X__x1j&AgJqwg&bck&rvN=EshYYt1*~CXQN(k z>RKIz7wH;<_2&76qGv4Nk_NkO$t1GTFr8$m)sZTu14*~*(w$~mD7&uq>U{)hQ`YO? zE5A$hRy99;Q<3GysyQa)J!;4kKE|6<6tQj~KC)XjBAqmW2a2bqU?l|FH?P+oVJtQ+*^I-)W8g6@R() G>c0RM4bpM| literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/traitlets/utils/__pycache__/getargspec.cpython-38.pyc b/.venv/lib/python3.8/site-packages/traitlets/utils/__pycache__/getargspec.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f25686208760529e9bc8ad25b9bcd38e36f452ab GIT binary patch literal 1367 zcmZWp&2Aev5GMCuE7@^=8dT|pDB6R8T5?kq0gNPVYP)cXz%8PrO$7v-wMa`FQM+rB z3t7Ud1*$Y>KSF%$YxE&{;I${++G`I%hbtKl5H4mo{AM^D4rli1+FFQUy#4jB=sORg zzs=&^VZq{SAo&R}in@qmYH{4fFx%W3*QMI;>N?cwpiOW3Z%APDnTkbU=B!89 zX^)9qF-nd_HrlDw6_fcONl#maN_Z``IqEqLezkfP89)BEFOJEBxB^k()_xufmBhS<4YC?Fm`#>< zf#hS*DD(!G=p2iU61}u$NZBQtW91BkGc0Za=FYJ4N<7CiOZlZmaTD}2yOOOY%J--Z zYo}T}mCjWG*twv4kr-PKywpTl+A1{C98>Ri*g1ofUe@zh)ZRnS`OKf*E$ugr(m%&w z2R=VUv!Jxg;2xTWrDNuwPmO;^aLJUv$OO{ z{~lPMynY4*cfJCiE$TNB@Sus*M(NBk*m|(8HPN}>LF#IWXgIeZ58DvwwHZ3YC%0hl zb(60%EDzKTS})N}xZ`ga@DB_QRo9q)^(Yy#i>he7Q+-E;BC^QyOem3S56MV#l1M$z=6PoWMaNi#*_iz=*6 zNV0VEruJ7gs)Iz17}O}$K@=H-DAJCaKrI``+A)w0FJsmYPo&ZgO?tph8)=)fR0l&g z8E1k@?ItN@r#gISrhOqYp~D|zUa+NH|F+=#f#`RjrL?PxoHOkYVi_wXgsDXxCh{Uu zU3&tdEH|!05XZ20)w-KCaRscqwG3LRioENuRN}gE6Hs;>7hK7%KOAR9RSAGX$gtEn z5hj@x`|o~Rjq-M$;OX+wvhMMu^WIl;Hx}ty4sH-n!&4x nI{4MKDl?`^s`sgkE^o1vJ~oEI-Q_>$z9|xE>ca^Gr(yjMBW-q) literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/traitlets/utils/__pycache__/importstring.cpython-38.pyc b/.venv/lib/python3.8/site-packages/traitlets/utils/__pycache__/importstring.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..adc6b77ee204898967cd323a64313d24c23b2777 GIT binary patch literal 1108 zcmY*YOK;RL5Vn)-qXDX_66JBSDwVPlyL;e(Q~?4Z4qPfkK|qC+^~T<%lCxQy^GufxY-y@x1wi7;PMoscWvI111V9Fq4xR7aJCYwk&Q0bTrr%Zui2DF={ zd?I^cOcCtKb@;wlq@PBx73XPJUQV|?_ zx-98CZ|==~XqH~-kEv*U^X9>96;mr8I>B~X)LXe9cx!!PILKG>rC4K@YgoA$+6X~k9T6jC|aF0n`tzs{lf0j+yj!I1 zuoT^s11Xa(+#TMV!O4d{Xs#fUVEXPAntsiwer~;dYA-Db=AN0k?y6l2=^DLEFMDme sNV-s|MRchb}=8phGt=Mi(uFBGQdgSyD*~P7DDZ;y>d* z)PZaNMTeqyRFp>>^aP&nL4J4Nk)Nm2F#-Ag{Rf{gLVluiUwm**Vd*!Z1WCvzBB)?{ zBABGtUc!X8BC)@luViWRQWjBGq*_PoN<~>!YLk{mN88+-M~#;2rihfRmCgX|fq3AZ z!qRh4k|Y#rF)}C{%x9!@l}5!-ji78%U9lu=HC{ zEo})WEdxzkPrYtEu$Uk#a-hrDvwoRwqzyKeXbNeEoQo>sJoc@xWwBP+q(abS1PN_a zUVb?cHH65olZDyTi#o4oO_Y+T+nMO=rLOC7}&*ZY3UpY zdeF3E;J6&93gCnz&?&5p&EO?*{tP^g;N)Q&UG|?guoX9I98n8p6`t*YC$|<(OZ9cK zs=ngn5difykM525ZbuAHVu-`Q zN5Q!rbKX4+umS2@lNMb@;iai5s;8))qjEIw6cSe0IELH>hin{#Ug)_fJU%smj18)@ V3z-=gd>> describe("a", object()) + 'an object' + >>> describe("a", object) + 'an object' + >>> describe("a", type(object)) + 'a type' + + Definite description: + + >>> describe("the", object()) + "the object at '0x10741f1b0'" + >>> describe("the", object) + "the type 'object'" + >>> describe("the", type(object)) + "the type 'type'" + + Definitely named description: + + >>> describe("the", object(), "I made") + 'the object I made' + >>> describe("the", object, "I will use") + 'the object I will use' + """ + if isinstance(article, str): + article = article.lower() + + if not inspect.isclass(value): + typename = type(value).__name__ + else: + typename = value.__name__ + if verbose: + typename = _prefix(value) + typename + + if article == "the" or (article is None and not inspect.isclass(value)): + if name is not None: + result = "{} {}".format(typename, name) + if article is not None: + return add_article(result, True, capital) + else: + return result + else: + tick_wrap = False + if inspect.isclass(value): + name = value.__name__ + elif isinstance(value, types.FunctionType): + name = value.__name__ + tick_wrap = True + elif isinstance(value, types.MethodType): + name = value.__func__.__name__ + tick_wrap = True + elif type(value).__repr__ in (object.__repr__, type.__repr__): + name = "at '%s'" % hex(id(value)) + verbose = False + else: + name = repr(value) + verbose = False + if verbose: + name = _prefix(value) + name + if tick_wrap: + name = name.join("''") + return describe(article, value, name=name, + verbose=verbose, capital=capital) + elif article in ("a", "an") or article is None: + if article is None: + return typename + return add_article(typename, False, capital) + else: + raise ValueError("The 'article' argument should " + "be 'the', 'a', 'an', or None not %r" % article) + + +def _prefix(value): + if isinstance(value, types.MethodType): + name = describe(None, value.__self__, verbose=True) + '.' + else: + module = inspect.getmodule(value) + if module is not None and module.__name__ != "builtins": + name = module.__name__ + '.' + else: + name = "" + return name + + +def class_of(value): + """Returns a string of the value's type with an indefinite article. + + For example 'an Image' or 'a PlotValue'. + """ + if inspect.isclass(value): + return add_article(value.__name__) + else: + return class_of(type(value)) + + +def add_article(name, definite=False, capital=False): + """Returns the string with a prepended article. + + The input does not need to begin with a charater. + + Parameters + ---------- + definite : bool (default: False) + Whether the article is definite or not. + Indefinite articles being 'a' and 'an', + while 'the' is definite. + capital : bool (default: False) + Whether the added article should have + its first letter capitalized or not. + """ + if definite: + result = "the " + name + else: + first_letters = re.compile(r'[\W_]+').sub('', name) + if first_letters[:1].lower() in 'aeiou': + result = 'an ' + name + else: + result = 'a ' + name + if capital: + return result[0].upper() + result[1:] + else: + return result + + +def repr_type(obj): + """Return a string representation of a value and its type for readable + + error messages. + """ + the_type = type(obj) + msg = '{!r} {!r}'.format(obj, the_type) + return msg diff --git a/.venv/lib/python3.8/site-packages/traitlets/utils/getargspec.py b/.venv/lib/python3.8/site-packages/traitlets/utils/getargspec.py new file mode 100644 index 00000000..22511437 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/traitlets/utils/getargspec.py @@ -0,0 +1,50 @@ +""" + getargspec excerpted from: + + sphinx.util.inspect + ~~~~~~~~~~~~~~~~~~~ + Helpers for inspecting Python modules. + :copyright: Copyright 2007-2015 by the Sphinx team, see AUTHORS. + :license: BSD, see LICENSE for details. +""" + +import inspect + +# Unmodified from sphinx below this line + +from functools import partial + +def getargspec(func): + """Like inspect.getargspec but supports functools.partial as well.""" + if inspect.ismethod(func): + func = func.__func__ + if type(func) is partial: + orig_func = func.func + argspec = getargspec(orig_func) + args = list(argspec[0]) + defaults = list(argspec[3] or ()) + kwoargs = list(argspec[4]) + kwodefs = dict(argspec[5] or {}) + if func.args: + args = args[len(func.args):] + for arg in func.keywords or (): + try: + i = args.index(arg) - len(args) + del args[i] + try: + del defaults[i] + except IndexError: + pass + except ValueError: # must be a kwonly arg + i = kwoargs.index(arg) + del kwoargs[i] + del kwodefs[arg] + return inspect.FullArgSpec(args, argspec[1], argspec[2], + tuple(defaults), kwoargs, + kwodefs, argspec[6]) + while hasattr(func, '__wrapped__'): + func = func.__wrapped__ + if not inspect.isfunction(func): + raise TypeError('%r is not a Python function' % func) + return inspect.getfullargspec(func) + diff --git a/.venv/lib/python3.8/site-packages/traitlets/utils/importstring.py b/.venv/lib/python3.8/site-packages/traitlets/utils/importstring.py new file mode 100644 index 00000000..defad8f1 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/traitlets/utils/importstring.py @@ -0,0 +1,38 @@ +""" +A simple utility to import something by its string name. +""" +# Copyright (c) IPython Development Team. +# Distributed under the terms of the Modified BSD License. + + +def import_item(name): + """Import and return ``bar`` given the string ``foo.bar``. + + Calling ``bar = import_item("foo.bar")`` is the functional equivalent of + executing the code ``from foo import bar``. + + Parameters + ---------- + name : string + The fully qualified name of the module/package being imported. + + Returns + ------- + mod : module object + The module that was imported. + """ + if not isinstance(name, str): + raise TypeError("import_item accepts strings, not '%s'." % type(name)) + parts = name.rsplit('.', 1) + if len(parts) == 2: + # called with 'foo.bar....' + package, obj = parts + module = __import__(package, fromlist=[obj]) + try: + pak = getattr(module, obj) + except AttributeError: + raise ImportError('No module named %s' % obj) + return pak + else: + # called with un-dotted string + return __import__(parts[0]) diff --git a/.venv/lib/python3.8/site-packages/traitlets/utils/sentinel.py b/.venv/lib/python3.8/site-packages/traitlets/utils/sentinel.py new file mode 100644 index 00000000..0760bec8 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/traitlets/utils/sentinel.py @@ -0,0 +1,22 @@ +"""Sentinel class for constants with useful reprs""" + +# Copyright (c) IPython Development Team. +# Distributed under the terms of the Modified BSD License. + + +class Sentinel(object): + + def __init__(self, name, module, docstring=None): + self.name = name + self.module = module + if docstring: + self.__doc__ = docstring + + def __repr__(self): + return str(self.module) + '.' + self.name + + def __copy__(self): + return self + + def __deepcopy__(self, memo): + return self diff --git a/.venv/lib/python3.8/site-packages/traitlets/utils/tests/__init__.py b/.venv/lib/python3.8/site-packages/traitlets/utils/tests/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/.venv/lib/python3.8/site-packages/traitlets/utils/tests/__pycache__/__init__.cpython-38.pyc b/.venv/lib/python3.8/site-packages/traitlets/utils/tests/__pycache__/__init__.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..1e92397006e5e4df5d215c22f868baa1169c24aa GIT binary patch literal 157 zcmWIL<>g`kf`9eb;z9Id5P=LBfgA@QE@lA|DGb33nv8xc8Hzx{2;!HMeo1bDenDn| zZfRaYVsdtBif(yEYHE&diE)y7RY`e;eo0YcW=T$JNwI!uNoG#5eo1OEkR2bNnU`4- ZAFo$Xd5gm)H$SB`C)EyQ_Gchw006$4CrJPR literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/traitlets/utils/tests/__pycache__/test_bunch.cpython-38.pyc b/.venv/lib/python3.8/site-packages/traitlets/utils/tests/__pycache__/test_bunch.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..3a4e4a8283f6a758065c9c00bbe1340e0599c6b8 GIT binary patch literal 639 zcmZ`%Jx?1!5S`ik@C9sxs3=mTNOKbA5Gm3i6uu-1S^`pJPy24(?A+U#r~B1ttO2i=+sE!E0z3)%xD=Bgyv-K|4H`=r zV+Rqm(!n3-C>`pE-+_*QLRwo&eTptRo=pbB0h71I>Jaii;cYG$EUSsiUv&dIT)-$c z+ZOLoM?U^4@d7TD#*s4n{v=+2t{nhp`998``z-LyNqZTw=2E74P!6vh&Z)+PVg{#% zg~MJNlJw`AN5KFOEpu>Szm;Q0A8v*RkOimEl6RK39{*R88zo|i5A zt^fVEy}HgU^$J_&)?_nVlqR#e;aITSm-%c_=68xUeyaG2ji)pmHDCk21XjIt0Z{^y=8&| literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/traitlets/utils/tests/__pycache__/test_decorators.cpython-38.pyc b/.venv/lib/python3.8/site-packages/traitlets/utils/tests/__pycache__/test_decorators.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..6b80eebd02272c503fc483bb154f145a4d882aba GIT binary patch literal 5018 zcmbVQOLrVc6|U-@p6Pk&=^Pv$5g{h&fF$fV1c+lC96=O(Mv0_g+?!@R)v`zKc~I38 zCpzQ9Lgv_Tj>D2|vecg6!lJjZ(Ldm@0Pa`)m>$hYwrHKc(^Xwvb?esszOPE3*6S5U z*MI)-ckgeDjQsA2j;=*jL5Eq z6m759_d2~!xOOe*w_Aa_zV^$0Ke9gbgP`AZ?8x@K9%YW_MHSEM_Qf#3bItR9KWqi@ z8)=gdQK>iV-u30>^x=vuquTnc6%73&CYPzC&A&I-!|q^x&>5@_dxKW{fiG4c-uL}r zHGJ#tI|t#z&)0Q|1%9a3hhZmB>u@x-p77g!*$Vqotqs12OmenP9jhW4+bHrPmoH)1 zLQCFL5~(8>UF5yk_!9%<|{x4m}E2yz<_hlfCjJPElIdif~Ke7aae2XfB6hJB} z1RWJdc1tN=hMQD=(CG;YkVlQ*yua;zytT8rySdeT|5j9u8*Lz1QSH|ocW!TOf8cF3 zZ{3NiXqwcV@X@iNg7SksJr((FbUc@hua`qbd~Y04c>zso`Q@xpjrtB5#tpt`Rk&>| z^Le`IPe0XogZ>Uyo|hLB@WUJt4iJa>7a73s3ESfuf_4hQKe5nw$}|KyL6GwBk)a{T zXF|}JfFPd%K`y2t$i*}SxtIk(BZc5o7DG_fpP8Bz$|G|EgeHM7124U6|K3OT}f(KvYb{Igk0$3Cja26ZFnVCG@KF*%rk zTQr{az)?MMsZF$%xOEgW0sX9@t#%Ubf1hrJ-eS72<4MJ{oWU1*=JF!7Kh|$wrYDKm zO2pQgKS2~4trEbKufVLpXll4HrUh?njQm&8;CnEy!RTO5GS*QcUI*}ig!l4w7|o}b z@ubnepwXYt6D*!uAp;6{sWMFgAOKAQmtJV4rkDVni%e6WkvS(5Q1T1f4cs$dXcbv5N8s^r6n{6oNV-071D5qnAEI-A7b4 zM%{b=&m1z`IrejK2Z+lbWlre)1K*ADwE=fBIZn_u&S*UgfanK=cEAy4e9`u!mO>0zo@K8VGD8kCA^v~#1 z`7X>gm>Fd8JE~U|G9=OQpK}EL~=s78= zbq0*+xEUY7CJvmF2*P;SZ0%r7pc;tRxX_uFsv`7V>I~APuT7?kf5x|n1>B*#apsaXUZT(AL*RG- z%rJ^GEA##^9ft85H~7KnIg@=tXZw>Adjq5W80M!iKZp4R%y{te>}vD^aMfgD8}>!} z75jqyrbKBlia Z&$C>K>}&D=C9Wf9G~Lt;I^-HP^M7?JBB%fW literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/traitlets/utils/tests/__pycache__/test_importstring.cpython-38.pyc b/.venv/lib/python3.8/site-packages/traitlets/utils/tests/__pycache__/test_importstring.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..bff857ac2a45e46068d3412ed2b8c1ab48e7a39e GIT binary patch literal 1212 zcmaJ=-)j>=5Z)h`qotxQj?wc=fW@o1fte>C0iT9k4?|2wr9voJ| z%u{fZL_|`_QW{Zs@|0yf;*>~F)>1F4MKwxZ5?Pmx6CxXm4|!CVY?B0jxwxf_HLaao zx2%p6n<{I7qi9}=B$F5 z+u#&|_DICA)e{nN$)yKRXcAhfS95stx&vLuyC{_WS-7u(t$~?m;Eu=_VyT6@hV+!t z^K*|wgiS_z9>n-4CJ7*Uor>kAY~&^^V!Ky1&o^N&Px?VE@?&F^w(CaM0Z1d$m4}&? z=Q3#J8I|sQB^pQc<5k;cMY~9fr9r=lyC0NX+TT+uU9yk1pOkk0pnXAX+Y#HgNV)T3 zg5%<_x{2@3qhiocy17*IfMT!}Lg(oXTHc-HDZHX&f;*58nF4d%t-uDP;3goMB}0A; zf;plKWuNCMu@D`SA*JLkc}!lD4e}0z=J@+(%s8G^Fw+EgIc7*^<-@Dm z-HxS5`o+M8%W2+?Q?n9wa{GMKiLDdx$`_&^XG(}_T8J!{gB15oAwCY`bo9p2Kjvlt zyPCedW&s;Q0s2%Uhvoe-rMBX3R~4ZAk-p7?RzJ6`#d~Hk47{qIZ}(K!R@X;T*oYIO z%!b-k2i4TpVWD1VoolCzfNSK|0aQFQyMH${=f-pKy|=KbIdCvc&M5l@KW~nfcmB&# zC#dOJguzOE4IMJA@wPEQ)T2fkH2zmG*PwcR=GR;#XjBa$WZo6RX*=>kVip_J$WzoD cm!tbUS9TRbvVzJqJ~)s0w8@(MH_1gPb^rhX literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/traitlets/utils/tests/test_bunch.py b/.venv/lib/python3.8/site-packages/traitlets/utils/tests/test_bunch.py new file mode 100644 index 00000000..ef5c3c13 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/traitlets/utils/tests/test_bunch.py @@ -0,0 +1,14 @@ +from ..bunch import Bunch + +def test_bunch(): + b = Bunch(x=5, y=10) + assert 'y' in b + assert 'x' in b + assert b.x == 5 + b['a'] = 'hi' + assert b.a == 'hi' + +def test_bunch_dir(): + b = Bunch(x=5, y=10) + assert 'x' in dir(b) + assert 'keys' in dir(b) diff --git a/.venv/lib/python3.8/site-packages/traitlets/utils/tests/test_decorators.py b/.venv/lib/python3.8/site-packages/traitlets/utils/tests/test_decorators.py new file mode 100644 index 00000000..908b55f2 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/traitlets/utils/tests/test_decorators.py @@ -0,0 +1,139 @@ +from unittest import TestCase + +from inspect import Signature, Parameter, signature + +from ...traitlets import HasTraits, Int, Unicode + +from ..decorators import signature_has_traits + + +class TestExpandSignature(TestCase): + + def test_no_init(self): + @signature_has_traits + class Foo(HasTraits): + number1 = Int() + number2 = Int() + value = Unicode('Hello') + + parameters = signature(Foo).parameters + parameter_names = list(parameters) + + self.assertIs(parameters['args'].kind, Parameter.VAR_POSITIONAL) + self.assertEqual('args', parameter_names[0]) + + self.assertIs(parameters['number1'].kind, Parameter.KEYWORD_ONLY) + self.assertIs(parameters['number2'].kind, Parameter.KEYWORD_ONLY) + self.assertIs(parameters['value'].kind, Parameter.KEYWORD_ONLY) + + self.assertIs(parameters['kwargs'].kind, Parameter.VAR_KEYWORD) + self.assertEqual('kwargs', parameter_names[-1]) + + f = Foo(number1=32, value='World') + self.assertEqual(f.number1, 32) + self.assertEqual(f.number2, 0) + self.assertEqual(f.value, 'World') + + def test_partial_init(self): + @signature_has_traits + class Foo(HasTraits): + number1 = Int() + number2 = Int() + value = Unicode('Hello') + + def __init__(self, arg1, **kwargs): + self.arg1 = arg1 + + super(Foo, self).__init__(**kwargs) + + parameters = signature(Foo).parameters + parameter_names = list(parameters) + + self.assertIs(parameters['arg1'].kind, Parameter.POSITIONAL_OR_KEYWORD) + self.assertEqual('arg1', parameter_names[0]) + + self.assertIs(parameters['number1'].kind, Parameter.KEYWORD_ONLY) + self.assertIs(parameters['number2'].kind, Parameter.KEYWORD_ONLY) + self.assertIs(parameters['value'].kind, Parameter.KEYWORD_ONLY) + + self.assertIs(parameters['kwargs'].kind, Parameter.VAR_KEYWORD) + self.assertEqual('kwargs', parameter_names[-1]) + + f = Foo(1, number1=32, value='World') + self.assertEqual(f.arg1, 1) + self.assertEqual(f.number1, 32) + self.assertEqual(f.number2, 0) + self.assertEqual(f.value, 'World') + + def test_duplicate_init(self): + @signature_has_traits + class Foo(HasTraits): + number1 = Int() + number2 = Int() + + def __init__(self, number1, **kwargs): + self.test = number1 + + super(Foo, self).__init__(number1=number1, **kwargs) + + parameters = signature(Foo).parameters + parameter_names = list(parameters) + + self.assertListEqual(parameter_names, ['number1', 'number2', 'kwargs']) + + f = Foo(number1=32, number2=36) + self.assertEqual(f.test, 32) + self.assertEqual(f.number1, 32) + self.assertEqual(f.number2, 36) + + def test_full_init(self): + @signature_has_traits + class Foo(HasTraits): + number1 = Int() + number2 = Int() + value = Unicode('Hello') + + def __init__(self, arg1, arg2=None, *pos_args, **kw_args): + self.arg1 = arg1 + self.arg2 = arg2 + self.pos_args = pos_args + self.kw_args = kw_args + + super(Foo, self).__init__(*pos_args, **kw_args) + + parameters = signature(Foo).parameters + parameter_names = list(parameters) + + self.assertIs(parameters['arg1'].kind, Parameter.POSITIONAL_OR_KEYWORD) + self.assertEqual('arg1', parameter_names[0]) + + self.assertIs(parameters['arg2'].kind, Parameter.POSITIONAL_OR_KEYWORD) + self.assertEqual('arg2', parameter_names[1]) + + self.assertIs(parameters['pos_args'].kind, Parameter.VAR_POSITIONAL) + self.assertEqual('pos_args', parameter_names[2]) + + self.assertIs(parameters['number1'].kind, Parameter.KEYWORD_ONLY) + self.assertIs(parameters['number2'].kind, Parameter.KEYWORD_ONLY) + self.assertIs(parameters['value'].kind, Parameter.KEYWORD_ONLY) + + self.assertIs(parameters['kw_args'].kind, Parameter.VAR_KEYWORD) + self.assertEqual('kw_args', parameter_names[-1]) + + f = Foo(1, 3, 45, 'hey', number1=32, value='World') + self.assertEqual(f.arg1, 1) + self.assertEqual(f.arg2, 3) + self.assertTupleEqual(f.pos_args, (45, 'hey')) + self.assertEqual(f.number1, 32) + self.assertEqual(f.number2, 0) + self.assertEqual(f.value, 'World') + + def test_no_kwargs(self): + with self.assertRaises(RuntimeError): + @signature_has_traits + class Foo(HasTraits): + number1 = Int() + number2 = Int() + + def __init__(self, arg1, arg2=None): + pass diff --git a/.venv/lib/python3.8/site-packages/traitlets/utils/tests/test_importstring.py b/.venv/lib/python3.8/site-packages/traitlets/utils/tests/test_importstring.py new file mode 100644 index 00000000..192bb0a2 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/traitlets/utils/tests/test_importstring.py @@ -0,0 +1,29 @@ +# Copyright (c) IPython Development Team. +# Distributed under the terms of the Modified BSD License. +# +# Adapted from enthought.traits, Copyright (c) Enthought, Inc., +# also under the terms of the Modified BSD License. +"""Tests for traitlets.utils.importstring.""" + +import os +from unittest import TestCase + +from ..importstring import import_item + + +class TestImportItem(TestCase): + + def test_import_unicode(self): + self.assertIs(os, import_item('os')) + self.assertIs(os.path, import_item('os.path')) + self.assertIs(os.path.join, import_item('os.path.join')) + + def test_bad_input(self): + class NotAString(object): + pass + msg = ( + "import_item accepts strings, " + "not '%s'." % NotAString + ) + with self.assertRaisesRegex(TypeError, msg): + import_item(NotAString()) diff --git a/.venv/lib/python3.8/site-packages/wcwidth-0.2.5.dist-info/INSTALLER b/.venv/lib/python3.8/site-packages/wcwidth-0.2.5.dist-info/INSTALLER new file mode 100644 index 00000000..a1b589e3 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/wcwidth-0.2.5.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/.venv/lib/python3.8/site-packages/wcwidth-0.2.5.dist-info/LICENSE b/.venv/lib/python3.8/site-packages/wcwidth-0.2.5.dist-info/LICENSE new file mode 100644 index 00000000..a44c0757 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/wcwidth-0.2.5.dist-info/LICENSE @@ -0,0 +1,27 @@ +The MIT License (MIT) + +Copyright (c) 2014 Jeff Quast + +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. + +Markus Kuhn -- 2007-05-26 (Unicode 5.0) + +Permission to use, copy, modify, and distribute this software +for any purpose and without fee is hereby granted. The author +disclaims all warranties with regard to this software. diff --git a/.venv/lib/python3.8/site-packages/wcwidth-0.2.5.dist-info/METADATA b/.venv/lib/python3.8/site-packages/wcwidth-0.2.5.dist-info/METADATA new file mode 100644 index 00000000..263388a0 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/wcwidth-0.2.5.dist-info/METADATA @@ -0,0 +1,309 @@ +Metadata-Version: 2.1 +Name: wcwidth +Version: 0.2.5 +Summary: Measures the displayed width of unicode strings in a terminal +Home-page: https://github.com/jquast/wcwidth +Author: Jeff Quast +Author-email: contact@jeffquast.com +License: MIT +Keywords: cjk,combining,console,eastasian,emojiemulator,terminal,unicode,wcswidth,wcwidth,xterm +Platform: UNKNOWN +Classifier: Intended Audience :: Developers +Classifier: Natural Language :: English +Classifier: Development Status :: 5 - Production/Stable +Classifier: Environment :: Console +Classifier: License :: OSI Approved :: MIT License +Classifier: Operating System :: POSIX +Classifier: Programming Language :: Python :: 2.7 +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 +Classifier: Topic :: Software Development :: Localization +Classifier: Topic :: Software Development :: Internationalization +Classifier: Topic :: Terminals +Requires-Dist: backports.functools-lru-cache (>=1.2.1) ; python_version < "3.2" + +|pypi_downloads| |codecov| |license| + +============ +Introduction +============ + +This library is mainly for CLI programs that carefully produce output for +Terminals, or make pretend to be an emulator. + +**Problem Statement**: The printable length of *most* strings are equal to the +number of cells they occupy on the screen ``1 charater : 1 cell``. However, +there are categories of characters that *occupy 2 cells* (full-wide), and +others that *occupy 0* cells (zero-width). + +**Solution**: POSIX.1-2001 and POSIX.1-2008 conforming systems provide +`wcwidth(3)`_ and `wcswidth(3)`_ C functions of which this python module's +functions precisely copy. *These functions return the number of cells a +unicode string is expected to occupy.* + +Installation +------------ + +The stable version of this package is maintained on pypi, install using pip:: + + pip install wcwidth + +Example +------- + +**Problem**: given the following phrase (Japanese), + + >>> text = u'コンニãƒãƒ' + +Python **incorrectly** uses the *string length* of 5 codepoints rather than the +*printible length* of 10 cells, so that when using the `rjust` function, the +output length is wrong:: + + >>> print(len('コンニãƒãƒ')) + 5 + + >>> print('コンニãƒãƒ'.rjust(20, '_')) + _____コンニãƒãƒ + +By defining our own "rjust" function that uses wcwidth, we can correct this:: + + >>> def wc_rjust(text, length, padding=' '): + ... from wcwidth import wcswidth + ... return padding * max(0, (length - wcswidth(text))) + text + ... + +Our **Solution** uses wcswidth to determine the string length correctly:: + + >>> from wcwidth import wcswidth + >>> print(wcswidth('コンニãƒãƒ')) + 10 + + >>> print(wc_rjust('コンニãƒãƒ', 20, '_')) + __________コンニãƒãƒ + + +Choosing a Version +------------------ + +Export an environment variable, ``UNICODE_VERSION``. This should be done by +*terminal emulators* or those developers experimenting with authoring one of +their own, from shell:: + + $ export UNICODE_VERSION=13.0 + +If unspecified, the latest version is used. If your Terminal Emulator does not +export this variable, you can use the `jquast/ucs-detect`_ utility to +automatically detect and export it to your shell. + +wcwidth, wcswidth +----------------- +Use function ``wcwidth()`` to determine the length of a *single unicode +character*, and ``wcswidth()`` to determine the length of many, a *string +of unicode characters*. + +Briefly, return values of function ``wcwidth()`` are: + +``-1`` + Indeterminate (not printable). + +``0`` + Does not advance the cursor, such as NULL or Combining. + +``2`` + Characters of category East Asian Wide (W) or East Asian + Full-width (F) which are displayed using two terminal cells. + +``1`` + All others. + +Function ``wcswidth()`` simply returns the sum of all values for each character +along a string, or ``-1`` when it occurs anywhere along a string. + +Full API Documentation at http://wcwidth.readthedocs.org + +========== +Developing +========== + +Install wcwidth in editable mode:: + + pip install -e. + +Execute unit tests using tox_:: + + tox + +Regenerate python code tables from latest Unicode Specification data files:: + + tox -eupdate + +Supplementary tools for browsing and testing terminals for wide unicode +characters are found in the `bin/`_ of this project's source code. Just ensure +to first ``pip install -erequirements-develop.txt`` from this projects main +folder. For example, an interactive browser for testing:: + + ./bin/wcwidth-browser.py + +Uses +---- + +This library is used in: + +- `jquast/blessed`_: a thin, practical wrapper around terminal capabilities in + Python. + +- `jonathanslenders/python-prompt-toolkit`_: a Library for building powerful + interactive command lines in Python. + +- `dbcli/pgcli`_: Postgres CLI with autocompletion and syntax highlighting. + +- `thomasballinger/curtsies`_: a Curses-like terminal wrapper with a display + based on compositing 2d arrays of text. + +- `selectel/pyte`_: Simple VTXXX-compatible linux terminal emulator. + +- `astanin/python-tabulate`_: Pretty-print tabular data in Python, a library + and a command-line utility. + +- `LuminosoInsight/python-ftfy`_: Fixes mojibake and other glitches in Unicode + text. + +- `nbedos/termtosvg`_: Terminal recorder that renders sessions as SVG + animations. + +- `peterbrittain/asciimatics`_: Package to help people create full-screen text + UIs. + +Other Languages +--------------- + +- `timoxley/wcwidth`_: JavaScript +- `janlelis/unicode-display_width`_: Ruby +- `alecrabbit/php-wcwidth`_: PHP +- `Text::CharWidth`_: Perl +- `bluebear94/Terminal-WCWidth`: Perl 6 +- `mattn/go-runewidth`_: Go +- `emugel/wcwidth`_: Haxe +- `aperezdc/lua-wcwidth`: Lua +- `joachimschmidt557/zig-wcwidth`: Zig +- `fumiyas/wcwidth-cjk`: `LD_PRELOAD` override +- `joshuarubin/wcwidth9`: Unicode version 9 in C + +History +------- + +0.2.0 *2020-06-01* + * **Enhancement**: Unicode version may be selected by exporting the + Environment variable ``UNICODE_VERSION``, such as ``13.0``, or ``6.3.0``. + See the `jquast/ucs-detect`_ CLI utility for automatic detection. + * **Enhancement**: + API Documentation is published to readthedocs.org. + * **Updated** tables for *all* Unicode Specifications with files + published in a programmatically consumable format, versions 4.1.0 + through 13.0 + that are published + , versions + +0.1.9 *2020-03-22* + * **Performance** optimization by `Avram Lubkin`_, `PR #35`_. + * **Updated** tables to Unicode Specification 13.0.0. + +0.1.8 *2020-01-01* + * **Updated** tables to Unicode Specification 12.0.0. (`PR #30`_). + +0.1.7 *2016-07-01* + * **Updated** tables to Unicode Specification 9.0.0. (`PR #18`_). + +0.1.6 *2016-01-08 Production/Stable* + * ``LICENSE`` file now included with distribution. + +0.1.5 *2015-09-13 Alpha* + * **Bugfix**: + Resolution of "combining_ character width" issue, most especially + those that previously returned -1 now often (correctly) return 0. + resolved by `Philip Craig`_ via `PR #11`_. + * **Deprecated**: + The module path ``wcwidth.table_comb`` is no longer available, + it has been superseded by module path ``wcwidth.table_zero``. + +0.1.4 *2014-11-20 Pre-Alpha* + * **Feature**: ``wcswidth()`` now determines printable length + for (most) combining_ characters. The developer's tool + `bin/wcwidth-browser.py`_ is improved to display combining_ + characters when provided the ``--combining`` option + (`Thomas Ballinger`_ and `Leta Montopoli`_ `PR #5`_). + * **Feature**: added static analysis (prospector_) to testing + framework. + +0.1.3 *2014-10-29 Pre-Alpha* + * **Bugfix**: 2nd parameter of wcswidth was not honored. + (`Thomas Ballinger`_, `PR #4`_). + +0.1.2 *2014-10-28 Pre-Alpha* + * **Updated** tables to Unicode Specification 7.0.0. + (`Thomas Ballinger`_, `PR #3`_). + +0.1.1 *2014-05-14 Pre-Alpha* + * Initial release to pypi, Based on Unicode Specification 6.3.0 + +This code was originally derived directly from C code of the same name, +whose latest version is available at +http://www.cl.cam.ac.uk/~mgk25/ucs/wcwidth.c:: + + * Markus Kuhn -- 2007-05-26 (Unicode 5.0) + * + * Permission to use, copy, modify, and distribute this software + * for any purpose and without fee is hereby granted. The author + * disclaims all warranties with regard to this software. + +.. _`tox`: https://testrun.org/tox/latest/install.html +.. _`prospector`: https://github.com/landscapeio/prospector +.. _`combining`: https://en.wikipedia.org/wiki/Combining_character +.. _`bin/`: https://github.com/jquast/wcwidth/tree/master/bin +.. _`bin/wcwidth-browser.py`: https://github.com/jquast/wcwidth/tree/master/bin/wcwidth-browser.py +.. _`Thomas Ballinger`: https://github.com/thomasballinger +.. _`Leta Montopoli`: https://github.com/lmontopo +.. _`Philip Craig`: https://github.com/philipc +.. _`PR #3`: https://github.com/jquast/wcwidth/pull/3 +.. _`PR #4`: https://github.com/jquast/wcwidth/pull/4 +.. _`PR #5`: https://github.com/jquast/wcwidth/pull/5 +.. _`PR #11`: https://github.com/jquast/wcwidth/pull/11 +.. _`PR #18`: https://github.com/jquast/wcwidth/pull/18 +.. _`PR #30`: https://github.com/jquast/wcwidth/pull/30 +.. _`PR #35`: https://github.com/jquast/wcwidth/pull/35 +.. _`jquast/blessed`: https://github.com/jquast/blessed +.. _`selectel/pyte`: https://github.com/selectel/pyte +.. _`thomasballinger/curtsies`: https://github.com/thomasballinger/curtsies +.. _`dbcli/pgcli`: https://github.com/dbcli/pgcli +.. _`jonathanslenders/python-prompt-toolkit`: https://github.com/jonathanslenders/python-prompt-toolkit +.. _`timoxley/wcwidth`: https://github.com/timoxley/wcwidth +.. _`wcwidth(3)`: http://man7.org/linux/man-pages/man3/wcwidth.3.html +.. _`wcswidth(3)`: http://man7.org/linux/man-pages/man3/wcswidth.3.html +.. _`astanin/python-tabulate`: https://github.com/astanin/python-tabulate +.. _`janlelis/unicode-display_width`: https://github.com/janlelis/unicode-display_width +.. _`LuminosoInsight/python-ftfy`: https://github.com/LuminosoInsight/python-ftfy +.. _`alecrabbit/php-wcwidth`: https://github.com/alecrabbit/php-wcwidth +.. _`Text::CharWidth`: https://metacpan.org/pod/Text::CharWidth +.. _`bluebear94/Terminal-WCWidth`: https://github.com/bluebear94/Terminal-WCWidth +.. _`mattn/go-runewidth`: https://github.com/mattn/go-runewidth +.. _`emugel/wcwidth`: https://github.com/emugel/wcwidth +.. _`jquast/ucs-detect`: https://github.com/jquast/ucs-detect +.. _`Avram Lubkin`: https://github.com/avylove +.. _`nbedos/termtosvg`: https://github.com/nbedos/termtosvg +.. _`peterbrittain/asciimatics`: https://github.com/peterbrittain/asciimatics +.. _`aperezdc/lua-wcwidth`: https://github.com/aperezdc/lua-wcwidth +.. _`fumiyas/wcwidth-cjk`: https://github.com/fumiyas/wcwidth-cjk +.. |pypi_downloads| image:: https://img.shields.io/pypi/dm/wcwidth.svg?logo=pypi + :alt: Downloads + :target: https://pypi.org/project/wcwidth/ +.. |codecov| image:: https://codecov.io/gh/jquast/wcwidth/branch/master/graph/badge.svg + :alt: codecov.io Code Coverage + :target: https://codecov.io/gh/jquast/wcwidth/ +.. |license| image:: https://img.shields.io/github/license/jquast/wcwidth.svg + :target: https://pypi.python.org/pypi/wcwidth/ + :alt: MIT License + + diff --git a/.venv/lib/python3.8/site-packages/wcwidth-0.2.5.dist-info/RECORD b/.venv/lib/python3.8/site-packages/wcwidth-0.2.5.dist-info/RECORD new file mode 100644 index 00000000..52d7a5e2 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/wcwidth-0.2.5.dist-info/RECORD @@ -0,0 +1,22 @@ +wcwidth-0.2.5.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +wcwidth-0.2.5.dist-info/LICENSE,sha256=cLmKlaIUTrcK-AF_qMbZXOJH5AhnQ26LxknhN_4T0ho,1322 +wcwidth-0.2.5.dist-info/METADATA,sha256=K6QVxN6Eq7tMwUYeCeEgAcg0VjFqTrrUPOZL3flmEco,11257 +wcwidth-0.2.5.dist-info/RECORD,, +wcwidth-0.2.5.dist-info/WHEEL,sha256=kGT74LWyRUZrL4VgLh6_g12IeVl_9u9ZVhadrgXZUEY,110 +wcwidth-0.2.5.dist-info/top_level.txt,sha256=LLjS8SFiXXuLEcD2BNdFdGhpKWe5opHtvn7KNj9AIRI,8 +wcwidth-0.2.5.dist-info/zip-safe,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1 +wcwidth/__init__.py,sha256=89fk8q2MPb4clahe_qDVIzlIa0U2872dsE4hEwxC6W8,1557 +wcwidth/__pycache__/__init__.cpython-38.pyc,, +wcwidth/__pycache__/table_wide.cpython-38.pyc,, +wcwidth/__pycache__/table_zero.cpython-38.pyc,, +wcwidth/__pycache__/unicode_versions.cpython-38.pyc,, +wcwidth/__pycache__/wcwidth.cpython-38.pyc,, +wcwidth/table_wide.py,sha256=0yAEOGX6KIrsm5dUpzG0Jrb4s8wB6c7MC76ndXjLLj8,79422 +wcwidth/table_zero.py,sha256=w8ym8msWG1R2XhtJXRjUkT1erFIhj8d6YclXXrYoakQ,310230 +wcwidth/tests/__init__.py,sha256=v_2uRwUE3hTJkuW656dLrkDiM9al7KL1j_vwGRc0RTM,42 +wcwidth/tests/__pycache__/__init__.cpython-38.pyc,, +wcwidth/tests/__pycache__/test_core.cpython-38.pyc,, +wcwidth/tests/test_core.py,sha256=gBaR8b3Vv2Wq1q5vGk9fAT0eW12AaEK5kuzH6fwCO-Q,3886 +wcwidth/unicode_versions.py,sha256=pmyPU8jPCqNOjOHSVHLedKcWeW-SABSBcJ1EJemQJbo,792 +wcwidth/version.json,sha256=1zjrg0NodaudGjvcY-Eh-5JnBGKHkmVCIj2L9lN9k-U,202 +wcwidth/wcwidth.py,sha256=0bgA8U17QyvSHscy5zu1JW7rTWcEadw6HwNNbA9Phvk,14872 diff --git a/.venv/lib/python3.8/site-packages/wcwidth-0.2.5.dist-info/WHEEL b/.venv/lib/python3.8/site-packages/wcwidth-0.2.5.dist-info/WHEEL new file mode 100644 index 00000000..ef99c6cf --- /dev/null +++ b/.venv/lib/python3.8/site-packages/wcwidth-0.2.5.dist-info/WHEEL @@ -0,0 +1,6 @@ +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/.venv/lib/python3.8/site-packages/wcwidth-0.2.5.dist-info/top_level.txt b/.venv/lib/python3.8/site-packages/wcwidth-0.2.5.dist-info/top_level.txt new file mode 100644 index 00000000..723a22ca --- /dev/null +++ b/.venv/lib/python3.8/site-packages/wcwidth-0.2.5.dist-info/top_level.txt @@ -0,0 +1 @@ +wcwidth diff --git a/.venv/lib/python3.8/site-packages/wcwidth-0.2.5.dist-info/zip-safe b/.venv/lib/python3.8/site-packages/wcwidth-0.2.5.dist-info/zip-safe new file mode 100644 index 00000000..8b137891 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/wcwidth-0.2.5.dist-info/zip-safe @@ -0,0 +1 @@ + diff --git a/.venv/lib/python3.8/site-packages/wcwidth/__init__.py b/.venv/lib/python3.8/site-packages/wcwidth/__init__.py new file mode 100644 index 00000000..a9008f82 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/wcwidth/__init__.py @@ -0,0 +1,37 @@ +""" +wcwidth module. + +https://github.com/jquast/wcwidth +""" +# re-export all functions & definitions, even private ones, from top-level +# module path, to allow for 'from wcwidth import _private_func'. Of course, +# user beware that any _private function may disappear or change signature at +# any future version. + +# local +from .wcwidth import ZERO_WIDTH # noqa +from .wcwidth import (WIDE_EASTASIAN, + wcwidth, + wcswidth, + _bisearch, + list_versions, + _wcmatch_version, + _wcversion_value) + +# The __all__ attribute defines the items exported from statement, +# 'from wcwidth import *', but also to say, "This is the public API". +__all__ = ('wcwidth', 'wcswidth', 'list_versions') + +# I used to use a _get_package_version() function to use the `pkg_resources' +# module to parse the package version from our version.json file, but this blew +# some folks up, or more particularly, just the `xonsh' shell. +# +# Yikes! I always wanted to like xonsh and tried it many times but issues like +# these always bit me, too, so I can sympathize -- this version is now manually +# kept in sync with version.json to help them out. Shucks, this variable is just +# for legacy, from the days before 'pip freeze' was a thing. +# +# We also used pkg_resources to load unicode version tables from version.json, +# generated by bin/update-tables.py, but some environments are unable to +# import pkg_resources for one reason or another, yikes! +__version__ = '0.2.5' diff --git a/.venv/lib/python3.8/site-packages/wcwidth/__pycache__/__init__.cpython-38.pyc b/.venv/lib/python3.8/site-packages/wcwidth/__pycache__/__init__.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..cb14324aefc091371be51a082679f207ab02354b GIT binary patch literal 475 zcmYjNO-sW-5Y2be)D$n?J$T8XiI#d15epXVrGl*pdl}MfFwtxhvzvzY;_vYfdDyEb z|AH6Y?T0upk2f=Kc<>%P&s9YIynVotr6`|r_+OeBu0>M`SV0O_v6ibuLz*hNF1U_# zq9T1T8g)Dzd}{Q@IRfHVLA literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/wcwidth/__pycache__/table_wide.cpython-38.pyc b/.venv/lib/python3.8/site-packages/wcwidth/__pycache__/table_wide.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..01577572742f42f60d1054ff13967f809cb62d99 GIT binary patch literal 6137 zcmd^@X>b%p7=}BOgKz}meSjFe$RfMRf&}FV2^ayv7zv1?vV_b64Ix=Nfj~rwH!32C zfOvs|M*uONc!OM8phBr==`SoSt48?|4n@MTzHfh##41YyN{N^)p6}UjdU~g)zwTLf zNK#TWg}>;uuR@s_F={*CH2gaSZ?f>OGyu42m~vzAa@<%q&W(2y>RwIUM7OEi%x&(r zaFd=)9v0)a%vZiv6&XXd8xG|Zl$I5g>Vo2wvVxIC;f^VVCR|V!c2h=9Ng1h&(tz$q{aCV+f4eV+INdKBSBBi_;ORUdA&>O_na`@t}ZJ%l%++Sm~L z=K#3obowCi!Sqq$W9Z|=W1{d80NQV(|6tuy%2D3IsKdNcu}U9|#wuSs6N6iCVu^Sn zfoMV`5={w~k!en}0ID35grNPnIi@AEtt5L2g14R7Q<*)DIDrM3i z*3J27ucMgdzaBAaQtgUSrW=~Wli@lDpyw=lKOU^VE2#$SK^YXhGC`t|(^`K6FsNjl zsNccq_4mPG{B`q*idUu!VdpS|W+$>M?Q-G@;x8u>OG;Ja@?!veB1fkkJ1oRCI6OF!}?HRgiH+6%@koy*<3HDF5)36F^#0Oq=e`KvHg_-=YX>-r#;w>|`* z{pncc`V0WxkDhPcn}%Sp+Ia39`nBTE(65tzmcsQi0O!6>|3G{leZ6(>GX!(JocksH z2Js*1!=#^GaJ?JAXZ_6lEz+iz9uhxDFA$H%req4`+-7jy9KgA$%#V^b1L&KbMvI*HI zy8pgU*oB1ISG&3cbB`FCD==i++&r4EHi6pM{_Y zi09FVi&xTT1DLYa2?U#go)9FCdLs(L@`l9Odv{$GGY>uKr|r|iKfIKzwY3XlZ31e z@M&nj9~}KN;>a567z}2h{uU1h$o4s ziG={}+9Cw~E9wuUc!v4Kl3&97KwD4dIr=#9=jroVR4>?u-WIt2fr(TkrE$u@snV0bKC@xz>5!41s zyp(k^3BaaT!E$-Uw$W4J-m^BZs}c0u*6p69*NCq`Q!ff{P-Eugt1}0MUJSCDj+yHSZ(TVt&IJUw;kM>L2_t@rq`1KJ%@8lOY z))Ed*MbKMk*n{dJ983iMJLQEDaIe!}bJuJ5CGG$dEH(_f1vjv60K5l1N4zh6vUU6X z)tlh92GQ*rc3Z}si=~LfdM55g0{#*GMeDj6LBA=!n!ZMS3;ipgLGdP6#9tN&2GT3y zy9ClD)V=G(cNvn*kR};{x@2b_>ng`CmvDs*2|;v%g9$UoC%M72^1^cMmW@fXKaPjsVf;Y;ZDNn{CGNzcaApj;DoqFCVx3FutApcr XIy$L!uM(%knc$Q=lblM`@U`MMjA{Uj literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/wcwidth/__pycache__/table_zero.cpython-38.pyc b/.venv/lib/python3.8/site-packages/wcwidth/__pycache__/table_zero.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..729157a7fc661edfc24041264725490ec69d96a1 GIT binary patch literal 19632 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 literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/wcwidth/__pycache__/unicode_versions.cpython-38.pyc b/.venv/lib/python3.8/site-packages/wcwidth/__pycache__/unicode_versions.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a4b19ad01d4c4b40f457d4fb7c2f2be730d886d3 GIT binary patch literal 849 zcmZuw&2G~`5O&futt>_Ak>ecegB{yx4OkTdA+8)Ky%Zta@lFz}_S)KACnOgxya12E z3vtMmx8MS^Ye%6KBY9_Mc7DG3@!e!%TSR}p{!E^oSk^Bs{7XX;UehNp=wQ~p#RhEn z&AK13lUvIf?Y`UZzBIK^5*97bRZ(*&3#pPd3Q2;zbYM{nXnB#>453#;iEAuDwvG1n zZ2RM?kYFs9$Wdep8O*mZFZi@=7>TaR<|Rt6*#e~q{m^&)$PH%@M6o}M!@!$e`;mX; z**O7yL<5rE(kDlBumQmyW)UfEAo_r+6&&vVhff{=c3_moSkp?zrzsy1=cbdzri zrdF2@DHmB)lqTn)>#~OucL`+-w_S57-P7WDTg_=aP;f$$BWHvZBn^UW2@?v>poxXr zHW-_EexiCl8?AG(JH7G(&)=P1dw$1yDb!NbDWlFL@_OY=zdi5XUUclGVdH>;(Bn9u zD29_q&vo2!K(3zu!xDOq$K&_SR8`HiDH^xsO_o0(b2lr*(k-_k=W7;B`;JYYG*vIr ve)4Eb&-HrfRkv(Ge}VPh8Sc-Lgw=VH7{xJfchk1}^P6rPUTI{;eRTF0C2;J_ literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/wcwidth/__pycache__/wcwidth.cpython-38.pyc b/.venv/lib/python3.8/site-packages/wcwidth/__pycache__/wcwidth.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..67b204bbd7c6868caac511295dfcef5d048e826d GIT binary patch literal 10835 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 literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/wcwidth/table_wide.py b/.venv/lib/python3.8/site-packages/wcwidth/table_wide.py new file mode 100644 index 00000000..36fb2b60 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/wcwidth/table_wide.py @@ -0,0 +1,1102 @@ +"""Wide_Eastasian table, created by bin/update-tables.py.""" +# Generated: 2020-06-23T16:03:18.836005 +WIDE_EASTASIAN = { + '4.1.0': ( + # Source: EastAsianWidth-4.1.0.txt + # Date: 2005-03-17, 15:21:00 PST [KW] + # + (0x01100, 0x01159,), # Hangul Choseong Kiyeok ..Hangul Choseong Yeorinhi + (0x0115f, 0x0115f,), # Hangul Choseong Filler ..Hangul Choseong Filler + (0x02329, 0x0232a,), # Left-pointing Angle Brac..Right-pointing Angle Bra + (0x02e80, 0x02e99,), # Cjk Radical Repeat ..Cjk Radical Rap + (0x02e9b, 0x02ef3,), # Cjk Radical Choke ..Cjk Radical C-simplified + (0x02f00, 0x02fd5,), # Kangxi Radical One ..Kangxi Radical Flute + (0x02ff0, 0x02ffb,), # Ideographic Description ..Ideographic Description + (0x03000, 0x0303e,), # Ideographic Space ..Ideographic Variation In + (0x03041, 0x03096,), # Hiragana Letter Small A ..Hiragana Letter Small Ke + (0x03099, 0x030ff,), # Combining Katakana-hirag..Katakana Digraph Koto + (0x03105, 0x0312c,), # Bopomofo Letter B ..Bopomofo Letter Gn + (0x03131, 0x0318e,), # Hangul Letter Kiyeok ..Hangul Letter Araeae + (0x03190, 0x031b7,), # Ideographic Annotation L..Bopomofo Final Letter H + (0x031c0, 0x031cf,), # Cjk Stroke T ..Cjk Stroke N + (0x031f0, 0x0321e,), # Katakana Letter Small Ku..Parenthesized Korean Cha + (0x03220, 0x03243,), # Parenthesized Ideograph ..Parenthesized Ideograph + (0x03250, 0x032fe,), # Partnership Sign ..Circled Katakana Wo + (0x03300, 0x04db5,), # Square Apaato ..Cjk Unified Ideograph-4d + (0x04e00, 0x09fbb,), # Cjk Unified Ideograph-4e..Cjk Unified Ideograph-9f + (0x0a000, 0x0a48c,), # Yi Syllable It ..Yi Syllable Yyr + (0x0a490, 0x0a4c6,), # Yi Radical Qot ..Yi Radical Ke + (0x0ac00, 0x0d7a3,), # Hangul Syllable Ga ..Hangul Syllable Hih + (0x0f900, 0x0fa2d,), # Cjk Compatibility Ideogr..Cjk Compatibility Ideogr + (0x0fa30, 0x0fa6a,), # Cjk Compatibility Ideogr..Cjk Compatibility Ideogr + (0x0fa70, 0x0fad9,), # Cjk Compatibility Ideogr..Cjk Compatibility Ideogr + (0x0fe10, 0x0fe19,), # Presentation Form For Ve..Presentation Form For Ve + (0x0fe30, 0x0fe52,), # Presentation Form For Ve..Small Full Stop + (0x0fe54, 0x0fe66,), # Small Semicolon ..Small Equals Sign + (0x0fe68, 0x0fe6b,), # Small Reverse Solidus ..Small Commercial At + (0x0ff01, 0x0ff60,), # Fullwidth Exclamation Ma..Fullwidth Right White Pa + (0x0ffe0, 0x0ffe6,), # Fullwidth Cent Sign ..Fullwidth Won Sign + (0x20000, 0x2fffd,), # Cjk Unified Ideograph-20..(nil) + (0x30000, 0x3fffd,), # (nil) ..(nil) + ), + '5.0.0': ( + # Source: EastAsianWidth-5.0.0.txt + # Date: 2006-02-15, 14:39:00 PST [KW] + # + (0x01100, 0x01159,), # Hangul Choseong Kiyeok ..Hangul Choseong Yeorinhi + (0x0115f, 0x0115f,), # Hangul Choseong Filler ..Hangul Choseong Filler + (0x02329, 0x0232a,), # Left-pointing Angle Brac..Right-pointing Angle Bra + (0x02e80, 0x02e99,), # Cjk Radical Repeat ..Cjk Radical Rap + (0x02e9b, 0x02ef3,), # Cjk Radical Choke ..Cjk Radical C-simplified + (0x02f00, 0x02fd5,), # Kangxi Radical One ..Kangxi Radical Flute + (0x02ff0, 0x02ffb,), # Ideographic Description ..Ideographic Description + (0x03000, 0x0303e,), # Ideographic Space ..Ideographic Variation In + (0x03041, 0x03096,), # Hiragana Letter Small A ..Hiragana Letter Small Ke + (0x03099, 0x030ff,), # Combining Katakana-hirag..Katakana Digraph Koto + (0x03105, 0x0312c,), # Bopomofo Letter B ..Bopomofo Letter Gn + (0x03131, 0x0318e,), # Hangul Letter Kiyeok ..Hangul Letter Araeae + (0x03190, 0x031b7,), # Ideographic Annotation L..Bopomofo Final Letter H + (0x031c0, 0x031cf,), # Cjk Stroke T ..Cjk Stroke N + (0x031f0, 0x0321e,), # Katakana Letter Small Ku..Parenthesized Korean Cha + (0x03220, 0x03243,), # Parenthesized Ideograph ..Parenthesized Ideograph + (0x03250, 0x032fe,), # Partnership Sign ..Circled Katakana Wo + (0x03300, 0x04db5,), # Square Apaato ..Cjk Unified Ideograph-4d + (0x04e00, 0x09fbb,), # Cjk Unified Ideograph-4e..Cjk Unified Ideograph-9f + (0x0a000, 0x0a48c,), # Yi Syllable It ..Yi Syllable Yyr + (0x0a490, 0x0a4c6,), # Yi Radical Qot ..Yi Radical Ke + (0x0ac00, 0x0d7a3,), # Hangul Syllable Ga ..Hangul Syllable Hih + (0x0f900, 0x0fa2d,), # Cjk Compatibility Ideogr..Cjk Compatibility Ideogr + (0x0fa30, 0x0fa6a,), # Cjk Compatibility Ideogr..Cjk Compatibility Ideogr + (0x0fa70, 0x0fad9,), # Cjk Compatibility Ideogr..Cjk Compatibility Ideogr + (0x0fe10, 0x0fe19,), # Presentation Form For Ve..Presentation Form For Ve + (0x0fe30, 0x0fe52,), # Presentation Form For Ve..Small Full Stop + (0x0fe54, 0x0fe66,), # Small Semicolon ..Small Equals Sign + (0x0fe68, 0x0fe6b,), # Small Reverse Solidus ..Small Commercial At + (0x0ff01, 0x0ff60,), # Fullwidth Exclamation Ma..Fullwidth Right White Pa + (0x0ffe0, 0x0ffe6,), # Fullwidth Cent Sign ..Fullwidth Won Sign + (0x20000, 0x2fffd,), # Cjk Unified Ideograph-20..(nil) + (0x30000, 0x3fffd,), # (nil) ..(nil) + ), + '5.1.0': ( + # Source: EastAsianWidth-5.1.0.txt + # Date: 2008-03-20, 17:42:00 PDT [KW] + # + (0x01100, 0x01159,), # Hangul Choseong Kiyeok ..Hangul Choseong Yeorinhi + (0x0115f, 0x0115f,), # Hangul Choseong Filler ..Hangul Choseong Filler + (0x02329, 0x0232a,), # Left-pointing Angle Brac..Right-pointing Angle Bra + (0x02e80, 0x02e99,), # Cjk Radical Repeat ..Cjk Radical Rap + (0x02e9b, 0x02ef3,), # Cjk Radical Choke ..Cjk Radical C-simplified + (0x02f00, 0x02fd5,), # Kangxi Radical One ..Kangxi Radical Flute + (0x02ff0, 0x02ffb,), # Ideographic Description ..Ideographic Description + (0x03000, 0x0303e,), # Ideographic Space ..Ideographic Variation In + (0x03041, 0x03096,), # Hiragana Letter Small A ..Hiragana Letter Small Ke + (0x03099, 0x030ff,), # Combining Katakana-hirag..Katakana Digraph Koto + (0x03105, 0x0312d,), # Bopomofo Letter B ..Bopomofo Letter Ih + (0x03131, 0x0318e,), # Hangul Letter Kiyeok ..Hangul Letter Araeae + (0x03190, 0x031b7,), # Ideographic Annotation L..Bopomofo Final Letter H + (0x031c0, 0x031e3,), # Cjk Stroke T ..Cjk Stroke Q + (0x031f0, 0x0321e,), # Katakana Letter Small Ku..Parenthesized Korean Cha + (0x03220, 0x03243,), # Parenthesized Ideograph ..Parenthesized Ideograph + (0x03250, 0x032fe,), # Partnership Sign ..Circled Katakana Wo + (0x03300, 0x04db5,), # Square Apaato ..Cjk Unified Ideograph-4d + (0x04e00, 0x09fc3,), # Cjk Unified Ideograph-4e..Cjk Unified Ideograph-9f + (0x0a000, 0x0a48c,), # Yi Syllable It ..Yi Syllable Yyr + (0x0a490, 0x0a4c6,), # Yi Radical Qot ..Yi Radical Ke + (0x0ac00, 0x0d7a3,), # Hangul Syllable Ga ..Hangul Syllable Hih + (0x0f900, 0x0fa2d,), # Cjk Compatibility Ideogr..Cjk Compatibility Ideogr + (0x0fa30, 0x0fa6a,), # Cjk Compatibility Ideogr..Cjk Compatibility Ideogr + (0x0fa70, 0x0fad9,), # Cjk Compatibility Ideogr..Cjk Compatibility Ideogr + (0x0fe10, 0x0fe19,), # Presentation Form For Ve..Presentation Form For Ve + (0x0fe30, 0x0fe52,), # Presentation Form For Ve..Small Full Stop + (0x0fe54, 0x0fe66,), # Small Semicolon ..Small Equals Sign + (0x0fe68, 0x0fe6b,), # Small Reverse Solidus ..Small Commercial At + (0x0ff01, 0x0ff60,), # Fullwidth Exclamation Ma..Fullwidth Right White Pa + (0x0ffe0, 0x0ffe6,), # Fullwidth Cent Sign ..Fullwidth Won Sign + (0x20000, 0x2fffd,), # Cjk Unified Ideograph-20..(nil) + (0x30000, 0x3fffd,), # (nil) ..(nil) + ), + '5.2.0': ( + # Source: EastAsianWidth-5.2.0.txt + # Date: 2009-06-09, 17:47:00 PDT [KW] + # + (0x01100, 0x0115f,), # Hangul Choseong Kiyeok ..Hangul Choseong Filler + (0x011a3, 0x011a7,), # Hangul Jungseong A-eu ..Hangul Jungseong O-yae + (0x011fa, 0x011ff,), # Hangul Jongseong Kiyeok-..Hangul Jongseong Ssangni + (0x02329, 0x0232a,), # Left-pointing Angle Brac..Right-pointing Angle Bra + (0x02e80, 0x02e99,), # Cjk Radical Repeat ..Cjk Radical Rap + (0x02e9b, 0x02ef3,), # Cjk Radical Choke ..Cjk Radical C-simplified + (0x02f00, 0x02fd5,), # Kangxi Radical One ..Kangxi Radical Flute + (0x02ff0, 0x02ffb,), # Ideographic Description ..Ideographic Description + (0x03000, 0x0303e,), # Ideographic Space ..Ideographic Variation In + (0x03041, 0x03096,), # Hiragana Letter Small A ..Hiragana Letter Small Ke + (0x03099, 0x030ff,), # Combining Katakana-hirag..Katakana Digraph Koto + (0x03105, 0x0312d,), # Bopomofo Letter B ..Bopomofo Letter Ih + (0x03131, 0x0318e,), # Hangul Letter Kiyeok ..Hangul Letter Araeae + (0x03190, 0x031b7,), # Ideographic Annotation L..Bopomofo Final Letter H + (0x031c0, 0x031e3,), # Cjk Stroke T ..Cjk Stroke Q + (0x031f0, 0x0321e,), # Katakana Letter Small Ku..Parenthesized Korean Cha + (0x03220, 0x03247,), # Parenthesized Ideograph ..Circled Ideograph Koto + (0x03250, 0x032fe,), # Partnership Sign ..Circled Katakana Wo + (0x03300, 0x04dbf,), # Square Apaato ..(nil) + (0x04e00, 0x0a48c,), # Cjk Unified Ideograph-4e..Yi Syllable Yyr + (0x0a490, 0x0a4c6,), # Yi Radical Qot ..Yi Radical Ke + (0x0a960, 0x0a97c,), # Hangul Choseong Tikeut-m..Hangul Choseong Ssangyeo + (0x0ac00, 0x0d7a3,), # Hangul Syllable Ga ..Hangul Syllable Hih + (0x0d7b0, 0x0d7c6,), # Hangul Jungseong O-yeo ..Hangul Jungseong Araea-e + (0x0d7cb, 0x0d7fb,), # Hangul Jongseong Nieun-r..Hangul Jongseong Phieuph + (0x0f900, 0x0faff,), # Cjk Compatibility Ideogr..(nil) + (0x0fe10, 0x0fe19,), # Presentation Form For Ve..Presentation Form For Ve + (0x0fe30, 0x0fe52,), # Presentation Form For Ve..Small Full Stop + (0x0fe54, 0x0fe66,), # Small Semicolon ..Small Equals Sign + (0x0fe68, 0x0fe6b,), # Small Reverse Solidus ..Small Commercial At + (0x0ff01, 0x0ff60,), # Fullwidth Exclamation Ma..Fullwidth Right White Pa + (0x0ffe0, 0x0ffe6,), # Fullwidth Cent Sign ..Fullwidth Won Sign + (0x1f200, 0x1f200,), # Square Hiragana Hoka ..Square Hiragana Hoka + (0x1f210, 0x1f231,), # Squared Cjk Unified Ideo..Squared Cjk Unified Ideo + (0x1f240, 0x1f248,), # Tortoise Shell Bracketed..Tortoise Shell Bracketed + (0x20000, 0x2fffd,), # Cjk Unified Ideograph-20..(nil) + (0x30000, 0x3fffd,), # (nil) ..(nil) + ), + '6.0.0': ( + # Source: EastAsianWidth-6.0.0.txt + # Date: 2010-08-17, 12:17:00 PDT [KW] + # + (0x01100, 0x0115f,), # Hangul Choseong Kiyeok ..Hangul Choseong Filler + (0x011a3, 0x011a7,), # Hangul Jungseong A-eu ..Hangul Jungseong O-yae + (0x011fa, 0x011ff,), # Hangul Jongseong Kiyeok-..Hangul Jongseong Ssangni + (0x02329, 0x0232a,), # Left-pointing Angle Brac..Right-pointing Angle Bra + (0x02e80, 0x02e99,), # Cjk Radical Repeat ..Cjk Radical Rap + (0x02e9b, 0x02ef3,), # Cjk Radical Choke ..Cjk Radical C-simplified + (0x02f00, 0x02fd5,), # Kangxi Radical One ..Kangxi Radical Flute + (0x02ff0, 0x02ffb,), # Ideographic Description ..Ideographic Description + (0x03000, 0x0303e,), # Ideographic Space ..Ideographic Variation In + (0x03041, 0x03096,), # Hiragana Letter Small A ..Hiragana Letter Small Ke + (0x03099, 0x030ff,), # Combining Katakana-hirag..Katakana Digraph Koto + (0x03105, 0x0312d,), # Bopomofo Letter B ..Bopomofo Letter Ih + (0x03131, 0x0318e,), # Hangul Letter Kiyeok ..Hangul Letter Araeae + (0x03190, 0x031ba,), # Ideographic Annotation L..Bopomofo Letter Zy + (0x031c0, 0x031e3,), # Cjk Stroke T ..Cjk Stroke Q + (0x031f0, 0x0321e,), # Katakana Letter Small Ku..Parenthesized Korean Cha + (0x03220, 0x03247,), # Parenthesized Ideograph ..Circled Ideograph Koto + (0x03250, 0x032fe,), # Partnership Sign ..Circled Katakana Wo + (0x03300, 0x04dbf,), # Square Apaato ..(nil) + (0x04e00, 0x0a48c,), # Cjk Unified Ideograph-4e..Yi Syllable Yyr + (0x0a490, 0x0a4c6,), # Yi Radical Qot ..Yi Radical Ke + (0x0a960, 0x0a97c,), # Hangul Choseong Tikeut-m..Hangul Choseong Ssangyeo + (0x0ac00, 0x0d7a3,), # Hangul Syllable Ga ..Hangul Syllable Hih + (0x0d7b0, 0x0d7c6,), # Hangul Jungseong O-yeo ..Hangul Jungseong Araea-e + (0x0d7cb, 0x0d7fb,), # Hangul Jongseong Nieun-r..Hangul Jongseong Phieuph + (0x0f900, 0x0faff,), # Cjk Compatibility Ideogr..(nil) + (0x0fe10, 0x0fe19,), # Presentation Form For Ve..Presentation Form For Ve + (0x0fe30, 0x0fe52,), # Presentation Form For Ve..Small Full Stop + (0x0fe54, 0x0fe66,), # Small Semicolon ..Small Equals Sign + (0x0fe68, 0x0fe6b,), # Small Reverse Solidus ..Small Commercial At + (0x0ff01, 0x0ff60,), # Fullwidth Exclamation Ma..Fullwidth Right White Pa + (0x0ffe0, 0x0ffe6,), # Fullwidth Cent Sign ..Fullwidth Won Sign + (0x1b000, 0x1b001,), # Katakana Letter Archaic ..Hiragana Letter Archaic + (0x1f200, 0x1f202,), # Square Hiragana Hoka ..Squared Katakana Sa + (0x1f210, 0x1f23a,), # Squared Cjk Unified Ideo..Squared Cjk Unified Ideo + (0x1f240, 0x1f248,), # Tortoise Shell Bracketed..Tortoise Shell Bracketed + (0x1f250, 0x1f251,), # Circled Ideograph Advant..Circled Ideograph Accept + (0x20000, 0x2f73f,), # Cjk Unified Ideograph-20..(nil) + (0x2b740, 0x2fffd,), # Cjk Unified Ideograph-2b..(nil) + (0x30000, 0x3fffd,), # (nil) ..(nil) + ), + '6.1.0': ( + # Source: EastAsianWidth-6.1.0.txt + # Date: 2011-09-19, 18:46:00 GMT [KW] + # + (0x01100, 0x0115f,), # Hangul Choseong Kiyeok ..Hangul Choseong Filler + (0x011a3, 0x011a7,), # Hangul Jungseong A-eu ..Hangul Jungseong O-yae + (0x011fa, 0x011ff,), # Hangul Jongseong Kiyeok-..Hangul Jongseong Ssangni + (0x02329, 0x0232a,), # Left-pointing Angle Brac..Right-pointing Angle Bra + (0x02e80, 0x02e99,), # Cjk Radical Repeat ..Cjk Radical Rap + (0x02e9b, 0x02ef3,), # Cjk Radical Choke ..Cjk Radical C-simplified + (0x02f00, 0x02fd5,), # Kangxi Radical One ..Kangxi Radical Flute + (0x02ff0, 0x02ffb,), # Ideographic Description ..Ideographic Description + (0x03000, 0x0303e,), # Ideographic Space ..Ideographic Variation In + (0x03041, 0x03096,), # Hiragana Letter Small A ..Hiragana Letter Small Ke + (0x03099, 0x030ff,), # Combining Katakana-hirag..Katakana Digraph Koto + (0x03105, 0x0312d,), # Bopomofo Letter B ..Bopomofo Letter Ih + (0x03131, 0x0318e,), # Hangul Letter Kiyeok ..Hangul Letter Araeae + (0x03190, 0x031ba,), # Ideographic Annotation L..Bopomofo Letter Zy + (0x031c0, 0x031e3,), # Cjk Stroke T ..Cjk Stroke Q + (0x031f0, 0x0321e,), # Katakana Letter Small Ku..Parenthesized Korean Cha + (0x03220, 0x03247,), # Parenthesized Ideograph ..Circled Ideograph Koto + (0x03250, 0x032fe,), # Partnership Sign ..Circled Katakana Wo + (0x03300, 0x04dbf,), # Square Apaato ..(nil) + (0x04e00, 0x0a48c,), # Cjk Unified Ideograph-4e..Yi Syllable Yyr + (0x0a490, 0x0a4c6,), # Yi Radical Qot ..Yi Radical Ke + (0x0a960, 0x0a97c,), # Hangul Choseong Tikeut-m..Hangul Choseong Ssangyeo + (0x0ac00, 0x0d7a3,), # Hangul Syllable Ga ..Hangul Syllable Hih + (0x0d7b0, 0x0d7c6,), # Hangul Jungseong O-yeo ..Hangul Jungseong Araea-e + (0x0d7cb, 0x0d7fb,), # Hangul Jongseong Nieun-r..Hangul Jongseong Phieuph + (0x0f900, 0x0faff,), # Cjk Compatibility Ideogr..(nil) + (0x0fe10, 0x0fe19,), # Presentation Form For Ve..Presentation Form For Ve + (0x0fe30, 0x0fe52,), # Presentation Form For Ve..Small Full Stop + (0x0fe54, 0x0fe66,), # Small Semicolon ..Small Equals Sign + (0x0fe68, 0x0fe6b,), # Small Reverse Solidus ..Small Commercial At + (0x0ff01, 0x0ff60,), # Fullwidth Exclamation Ma..Fullwidth Right White Pa + (0x0ffe0, 0x0ffe6,), # Fullwidth Cent Sign ..Fullwidth Won Sign + (0x1b000, 0x1b001,), # Katakana Letter Archaic ..Hiragana Letter Archaic + (0x1f200, 0x1f202,), # Square Hiragana Hoka ..Squared Katakana Sa + (0x1f210, 0x1f23a,), # Squared Cjk Unified Ideo..Squared Cjk Unified Ideo + (0x1f240, 0x1f248,), # Tortoise Shell Bracketed..Tortoise Shell Bracketed + (0x1f250, 0x1f251,), # Circled Ideograph Advant..Circled Ideograph Accept + (0x20000, 0x2fffd,), # Cjk Unified Ideograph-20..(nil) + (0x30000, 0x3fffd,), # (nil) ..(nil) + ), + '6.2.0': ( + # Source: EastAsianWidth-6.2.0.txt + # Date: 2012-05-15, 18:30:00 GMT [KW] + # + (0x01100, 0x0115f,), # Hangul Choseong Kiyeok ..Hangul Choseong Filler + (0x02329, 0x0232a,), # Left-pointing Angle Brac..Right-pointing Angle Bra + (0x02e80, 0x02e99,), # Cjk Radical Repeat ..Cjk Radical Rap + (0x02e9b, 0x02ef3,), # Cjk Radical Choke ..Cjk Radical C-simplified + (0x02f00, 0x02fd5,), # Kangxi Radical One ..Kangxi Radical Flute + (0x02ff0, 0x02ffb,), # Ideographic Description ..Ideographic Description + (0x03000, 0x0303e,), # Ideographic Space ..Ideographic Variation In + (0x03041, 0x03096,), # Hiragana Letter Small A ..Hiragana Letter Small Ke + (0x03099, 0x030ff,), # Combining Katakana-hirag..Katakana Digraph Koto + (0x03105, 0x0312d,), # Bopomofo Letter B ..Bopomofo Letter Ih + (0x03131, 0x0318e,), # Hangul Letter Kiyeok ..Hangul Letter Araeae + (0x03190, 0x031ba,), # Ideographic Annotation L..Bopomofo Letter Zy + (0x031c0, 0x031e3,), # Cjk Stroke T ..Cjk Stroke Q + (0x031f0, 0x0321e,), # Katakana Letter Small Ku..Parenthesized Korean Cha + (0x03220, 0x03247,), # Parenthesized Ideograph ..Circled Ideograph Koto + (0x03250, 0x032fe,), # Partnership Sign ..Circled Katakana Wo + (0x03300, 0x04dbf,), # Square Apaato ..(nil) + (0x04e00, 0x0a48c,), # Cjk Unified Ideograph-4e..Yi Syllable Yyr + (0x0a490, 0x0a4c6,), # Yi Radical Qot ..Yi Radical Ke + (0x0a960, 0x0a97c,), # Hangul Choseong Tikeut-m..Hangul Choseong Ssangyeo + (0x0ac00, 0x0d7a3,), # Hangul Syllable Ga ..Hangul Syllable Hih + (0x0f900, 0x0faff,), # Cjk Compatibility Ideogr..(nil) + (0x0fe10, 0x0fe19,), # Presentation Form For Ve..Presentation Form For Ve + (0x0fe30, 0x0fe52,), # Presentation Form For Ve..Small Full Stop + (0x0fe54, 0x0fe66,), # Small Semicolon ..Small Equals Sign + (0x0fe68, 0x0fe6b,), # Small Reverse Solidus ..Small Commercial At + (0x0ff01, 0x0ff60,), # Fullwidth Exclamation Ma..Fullwidth Right White Pa + (0x0ffe0, 0x0ffe6,), # Fullwidth Cent Sign ..Fullwidth Won Sign + (0x1b000, 0x1b001,), # Katakana Letter Archaic ..Hiragana Letter Archaic + (0x1f200, 0x1f202,), # Square Hiragana Hoka ..Squared Katakana Sa + (0x1f210, 0x1f23a,), # Squared Cjk Unified Ideo..Squared Cjk Unified Ideo + (0x1f240, 0x1f248,), # Tortoise Shell Bracketed..Tortoise Shell Bracketed + (0x1f250, 0x1f251,), # Circled Ideograph Advant..Circled Ideograph Accept + (0x20000, 0x2fffd,), # Cjk Unified Ideograph-20..(nil) + (0x30000, 0x3fffd,), # (nil) ..(nil) + ), + '6.3.0': ( + # Source: EastAsianWidth-6.3.0.txt + # Date: 2013-02-05, 20:09:00 GMT [KW, LI] + # + (0x01100, 0x0115f,), # Hangul Choseong Kiyeok ..Hangul Choseong Filler + (0x02329, 0x0232a,), # Left-pointing Angle Brac..Right-pointing Angle Bra + (0x02e80, 0x02e99,), # Cjk Radical Repeat ..Cjk Radical Rap + (0x02e9b, 0x02ef3,), # Cjk Radical Choke ..Cjk Radical C-simplified + (0x02f00, 0x02fd5,), # Kangxi Radical One ..Kangxi Radical Flute + (0x02ff0, 0x02ffb,), # Ideographic Description ..Ideographic Description + (0x03000, 0x0303e,), # Ideographic Space ..Ideographic Variation In + (0x03041, 0x03096,), # Hiragana Letter Small A ..Hiragana Letter Small Ke + (0x03099, 0x030ff,), # Combining Katakana-hirag..Katakana Digraph Koto + (0x03105, 0x0312d,), # Bopomofo Letter B ..Bopomofo Letter Ih + (0x03131, 0x0318e,), # Hangul Letter Kiyeok ..Hangul Letter Araeae + (0x03190, 0x031ba,), # Ideographic Annotation L..Bopomofo Letter Zy + (0x031c0, 0x031e3,), # Cjk Stroke T ..Cjk Stroke Q + (0x031f0, 0x0321e,), # Katakana Letter Small Ku..Parenthesized Korean Cha + (0x03220, 0x03247,), # Parenthesized Ideograph ..Circled Ideograph Koto + (0x03250, 0x032fe,), # Partnership Sign ..Circled Katakana Wo + (0x03300, 0x04dbf,), # Square Apaato ..(nil) + (0x04e00, 0x0a48c,), # Cjk Unified Ideograph-4e..Yi Syllable Yyr + (0x0a490, 0x0a4c6,), # Yi Radical Qot ..Yi Radical Ke + (0x0a960, 0x0a97c,), # Hangul Choseong Tikeut-m..Hangul Choseong Ssangyeo + (0x0ac00, 0x0d7a3,), # Hangul Syllable Ga ..Hangul Syllable Hih + (0x0f900, 0x0faff,), # Cjk Compatibility Ideogr..(nil) + (0x0fe10, 0x0fe19,), # Presentation Form For Ve..Presentation Form For Ve + (0x0fe30, 0x0fe52,), # Presentation Form For Ve..Small Full Stop + (0x0fe54, 0x0fe66,), # Small Semicolon ..Small Equals Sign + (0x0fe68, 0x0fe6b,), # Small Reverse Solidus ..Small Commercial At + (0x0ff01, 0x0ff60,), # Fullwidth Exclamation Ma..Fullwidth Right White Pa + (0x0ffe0, 0x0ffe6,), # Fullwidth Cent Sign ..Fullwidth Won Sign + (0x1b000, 0x1b001,), # Katakana Letter Archaic ..Hiragana Letter Archaic + (0x1f200, 0x1f202,), # Square Hiragana Hoka ..Squared Katakana Sa + (0x1f210, 0x1f23a,), # Squared Cjk Unified Ideo..Squared Cjk Unified Ideo + (0x1f240, 0x1f248,), # Tortoise Shell Bracketed..Tortoise Shell Bracketed + (0x1f250, 0x1f251,), # Circled Ideograph Advant..Circled Ideograph Accept + (0x20000, 0x2fffd,), # Cjk Unified Ideograph-20..(nil) + (0x30000, 0x3fffd,), # (nil) ..(nil) + ), + '7.0.0': ( + # Source: EastAsianWidth-7.0.0.txt + # Date: 2014-02-28, 23:15:00 GMT [KW, LI] + # + (0x01100, 0x0115f,), # Hangul Choseong Kiyeok ..Hangul Choseong Filler + (0x02329, 0x0232a,), # Left-pointing Angle Brac..Right-pointing Angle Bra + (0x02e80, 0x02e99,), # Cjk Radical Repeat ..Cjk Radical Rap + (0x02e9b, 0x02ef3,), # Cjk Radical Choke ..Cjk Radical C-simplified + (0x02f00, 0x02fd5,), # Kangxi Radical One ..Kangxi Radical Flute + (0x02ff0, 0x02ffb,), # Ideographic Description ..Ideographic Description + (0x03000, 0x0303e,), # Ideographic Space ..Ideographic Variation In + (0x03041, 0x03096,), # Hiragana Letter Small A ..Hiragana Letter Small Ke + (0x03099, 0x030ff,), # Combining Katakana-hirag..Katakana Digraph Koto + (0x03105, 0x0312d,), # Bopomofo Letter B ..Bopomofo Letter Ih + (0x03131, 0x0318e,), # Hangul Letter Kiyeok ..Hangul Letter Araeae + (0x03190, 0x031ba,), # Ideographic Annotation L..Bopomofo Letter Zy + (0x031c0, 0x031e3,), # Cjk Stroke T ..Cjk Stroke Q + (0x031f0, 0x0321e,), # Katakana Letter Small Ku..Parenthesized Korean Cha + (0x03220, 0x03247,), # Parenthesized Ideograph ..Circled Ideograph Koto + (0x03250, 0x032fe,), # Partnership Sign ..Circled Katakana Wo + (0x03300, 0x04dbf,), # Square Apaato ..(nil) + (0x04e00, 0x0a48c,), # Cjk Unified Ideograph-4e..Yi Syllable Yyr + (0x0a490, 0x0a4c6,), # Yi Radical Qot ..Yi Radical Ke + (0x0a960, 0x0a97c,), # Hangul Choseong Tikeut-m..Hangul Choseong Ssangyeo + (0x0ac00, 0x0d7a3,), # Hangul Syllable Ga ..Hangul Syllable Hih + (0x0f900, 0x0faff,), # Cjk Compatibility Ideogr..(nil) + (0x0fe10, 0x0fe19,), # Presentation Form For Ve..Presentation Form For Ve + (0x0fe30, 0x0fe52,), # Presentation Form For Ve..Small Full Stop + (0x0fe54, 0x0fe66,), # Small Semicolon ..Small Equals Sign + (0x0fe68, 0x0fe6b,), # Small Reverse Solidus ..Small Commercial At + (0x0ff01, 0x0ff60,), # Fullwidth Exclamation Ma..Fullwidth Right White Pa + (0x0ffe0, 0x0ffe6,), # Fullwidth Cent Sign ..Fullwidth Won Sign + (0x1b000, 0x1b001,), # Katakana Letter Archaic ..Hiragana Letter Archaic + (0x1f200, 0x1f202,), # Square Hiragana Hoka ..Squared Katakana Sa + (0x1f210, 0x1f23a,), # Squared Cjk Unified Ideo..Squared Cjk Unified Ideo + (0x1f240, 0x1f248,), # Tortoise Shell Bracketed..Tortoise Shell Bracketed + (0x1f250, 0x1f251,), # Circled Ideograph Advant..Circled Ideograph Accept + (0x20000, 0x2fffd,), # Cjk Unified Ideograph-20..(nil) + (0x30000, 0x3fffd,), # (nil) ..(nil) + ), + '8.0.0': ( + # Source: EastAsianWidth-8.0.0.txt + # Date: 2015-02-10, 21:00:00 GMT [KW, LI] + # + (0x01100, 0x0115f,), # Hangul Choseong Kiyeok ..Hangul Choseong Filler + (0x02329, 0x0232a,), # Left-pointing Angle Brac..Right-pointing Angle Bra + (0x02e80, 0x02e99,), # Cjk Radical Repeat ..Cjk Radical Rap + (0x02e9b, 0x02ef3,), # Cjk Radical Choke ..Cjk Radical C-simplified + (0x02f00, 0x02fd5,), # Kangxi Radical One ..Kangxi Radical Flute + (0x02ff0, 0x02ffb,), # Ideographic Description ..Ideographic Description + (0x03000, 0x0303e,), # Ideographic Space ..Ideographic Variation In + (0x03041, 0x03096,), # Hiragana Letter Small A ..Hiragana Letter Small Ke + (0x03099, 0x030ff,), # Combining Katakana-hirag..Katakana Digraph Koto + (0x03105, 0x0312d,), # Bopomofo Letter B ..Bopomofo Letter Ih + (0x03131, 0x0318e,), # Hangul Letter Kiyeok ..Hangul Letter Araeae + (0x03190, 0x031ba,), # Ideographic Annotation L..Bopomofo Letter Zy + (0x031c0, 0x031e3,), # Cjk Stroke T ..Cjk Stroke Q + (0x031f0, 0x0321e,), # Katakana Letter Small Ku..Parenthesized Korean Cha + (0x03220, 0x03247,), # Parenthesized Ideograph ..Circled Ideograph Koto + (0x03250, 0x032fe,), # Partnership Sign ..Circled Katakana Wo + (0x03300, 0x04dbf,), # Square Apaato ..(nil) + (0x04e00, 0x0a48c,), # Cjk Unified Ideograph-4e..Yi Syllable Yyr + (0x0a490, 0x0a4c6,), # Yi Radical Qot ..Yi Radical Ke + (0x0a960, 0x0a97c,), # Hangul Choseong Tikeut-m..Hangul Choseong Ssangyeo + (0x0ac00, 0x0d7a3,), # Hangul Syllable Ga ..Hangul Syllable Hih + (0x0f900, 0x0faff,), # Cjk Compatibility Ideogr..(nil) + (0x0fe10, 0x0fe19,), # Presentation Form For Ve..Presentation Form For Ve + (0x0fe30, 0x0fe52,), # Presentation Form For Ve..Small Full Stop + (0x0fe54, 0x0fe66,), # Small Semicolon ..Small Equals Sign + (0x0fe68, 0x0fe6b,), # Small Reverse Solidus ..Small Commercial At + (0x0ff01, 0x0ff60,), # Fullwidth Exclamation Ma..Fullwidth Right White Pa + (0x0ffe0, 0x0ffe6,), # Fullwidth Cent Sign ..Fullwidth Won Sign + (0x1b000, 0x1b001,), # Katakana Letter Archaic ..Hiragana Letter Archaic + (0x1f200, 0x1f202,), # Square Hiragana Hoka ..Squared Katakana Sa + (0x1f210, 0x1f23a,), # Squared Cjk Unified Ideo..Squared Cjk Unified Ideo + (0x1f240, 0x1f248,), # Tortoise Shell Bracketed..Tortoise Shell Bracketed + (0x1f250, 0x1f251,), # Circled Ideograph Advant..Circled Ideograph Accept + (0x20000, 0x2fffd,), # Cjk Unified Ideograph-20..(nil) + (0x30000, 0x3fffd,), # (nil) ..(nil) + ), + '9.0.0': ( + # Source: EastAsianWidth-9.0.0.txt + # Date: 2016-05-27, 17:00:00 GMT [KW, LI] + # + (0x01100, 0x0115f,), # Hangul Choseong Kiyeok ..Hangul Choseong Filler + (0x0231a, 0x0231b,), # Watch ..Hourglass + (0x02329, 0x0232a,), # Left-pointing Angle Brac..Right-pointing Angle Bra + (0x023e9, 0x023ec,), # Black Right-pointing Dou..Black Down-pointing Doub + (0x023f0, 0x023f0,), # Alarm Clock ..Alarm Clock + (0x023f3, 0x023f3,), # Hourglass With Flowing S..Hourglass With Flowing S + (0x025fd, 0x025fe,), # White Medium Small Squar..Black Medium Small Squar + (0x02614, 0x02615,), # Umbrella With Rain Drops..Hot Beverage + (0x02648, 0x02653,), # Aries ..Pisces + (0x0267f, 0x0267f,), # Wheelchair Symbol ..Wheelchair Symbol + (0x02693, 0x02693,), # Anchor ..Anchor + (0x026a1, 0x026a1,), # High Voltage Sign ..High Voltage Sign + (0x026aa, 0x026ab,), # Medium White Circle ..Medium Black Circle + (0x026bd, 0x026be,), # Soccer Ball ..Baseball + (0x026c4, 0x026c5,), # Snowman Without Snow ..Sun Behind Cloud + (0x026ce, 0x026ce,), # Ophiuchus ..Ophiuchus + (0x026d4, 0x026d4,), # No Entry ..No Entry + (0x026ea, 0x026ea,), # Church ..Church + (0x026f2, 0x026f3,), # Fountain ..Flag In Hole + (0x026f5, 0x026f5,), # Sailboat ..Sailboat + (0x026fa, 0x026fa,), # Tent ..Tent + (0x026fd, 0x026fd,), # Fuel Pump ..Fuel Pump + (0x02705, 0x02705,), # White Heavy Check Mark ..White Heavy Check Mark + (0x0270a, 0x0270b,), # Raised Fist ..Raised Hand + (0x02728, 0x02728,), # Sparkles ..Sparkles + (0x0274c, 0x0274c,), # Cross Mark ..Cross Mark + (0x0274e, 0x0274e,), # Negative Squared Cross M..Negative Squared Cross M + (0x02753, 0x02755,), # Black Question Mark Orna..White Exclamation Mark O + (0x02757, 0x02757,), # Heavy Exclamation Mark S..Heavy Exclamation Mark S + (0x02795, 0x02797,), # Heavy Plus Sign ..Heavy Division Sign + (0x027b0, 0x027b0,), # Curly Loop ..Curly Loop + (0x027bf, 0x027bf,), # Double Curly Loop ..Double Curly Loop + (0x02b1b, 0x02b1c,), # Black Large Square ..White Large Square + (0x02b50, 0x02b50,), # White Medium Star ..White Medium Star + (0x02b55, 0x02b55,), # Heavy Large Circle ..Heavy Large Circle + (0x02e80, 0x02e99,), # Cjk Radical Repeat ..Cjk Radical Rap + (0x02e9b, 0x02ef3,), # Cjk Radical Choke ..Cjk Radical C-simplified + (0x02f00, 0x02fd5,), # Kangxi Radical One ..Kangxi Radical Flute + (0x02ff0, 0x02ffb,), # Ideographic Description ..Ideographic Description + (0x03000, 0x0303e,), # Ideographic Space ..Ideographic Variation In + (0x03041, 0x03096,), # Hiragana Letter Small A ..Hiragana Letter Small Ke + (0x03099, 0x030ff,), # Combining Katakana-hirag..Katakana Digraph Koto + (0x03105, 0x0312d,), # Bopomofo Letter B ..Bopomofo Letter Ih + (0x03131, 0x0318e,), # Hangul Letter Kiyeok ..Hangul Letter Araeae + (0x03190, 0x031ba,), # Ideographic Annotation L..Bopomofo Letter Zy + (0x031c0, 0x031e3,), # Cjk Stroke T ..Cjk Stroke Q + (0x031f0, 0x0321e,), # Katakana Letter Small Ku..Parenthesized Korean Cha + (0x03220, 0x03247,), # Parenthesized Ideograph ..Circled Ideograph Koto + (0x03250, 0x032fe,), # Partnership Sign ..Circled Katakana Wo + (0x03300, 0x04dbf,), # Square Apaato ..(nil) + (0x04e00, 0x0a48c,), # Cjk Unified Ideograph-4e..Yi Syllable Yyr + (0x0a490, 0x0a4c6,), # Yi Radical Qot ..Yi Radical Ke + (0x0a960, 0x0a97c,), # Hangul Choseong Tikeut-m..Hangul Choseong Ssangyeo + (0x0ac00, 0x0d7a3,), # Hangul Syllable Ga ..Hangul Syllable Hih + (0x0f900, 0x0faff,), # Cjk Compatibility Ideogr..(nil) + (0x0fe10, 0x0fe19,), # Presentation Form For Ve..Presentation Form For Ve + (0x0fe30, 0x0fe52,), # Presentation Form For Ve..Small Full Stop + (0x0fe54, 0x0fe66,), # Small Semicolon ..Small Equals Sign + (0x0fe68, 0x0fe6b,), # Small Reverse Solidus ..Small Commercial At + (0x0ff01, 0x0ff60,), # Fullwidth Exclamation Ma..Fullwidth Right White Pa + (0x0ffe0, 0x0ffe6,), # Fullwidth Cent Sign ..Fullwidth Won Sign + (0x16fe0, 0x16fe0,), # Tangut Iteration Mark ..Tangut Iteration Mark + (0x17000, 0x187ec,), # (nil) ..(nil) + (0x18800, 0x18af2,), # Tangut Component-001 ..Tangut Component-755 + (0x1b000, 0x1b001,), # Katakana Letter Archaic ..Hiragana Letter Archaic + (0x1f004, 0x1f004,), # Mahjong Tile Red Dragon ..Mahjong Tile Red Dragon + (0x1f0cf, 0x1f0cf,), # Playing Card Black Joker..Playing Card Black Joker + (0x1f18e, 0x1f18e,), # Negative Squared Ab ..Negative Squared Ab + (0x1f191, 0x1f19a,), # Squared Cl ..Squared Vs + (0x1f200, 0x1f202,), # Square Hiragana Hoka ..Squared Katakana Sa + (0x1f210, 0x1f23b,), # Squared Cjk Unified Ideo..Squared Cjk Unified Ideo + (0x1f240, 0x1f248,), # Tortoise Shell Bracketed..Tortoise Shell Bracketed + (0x1f250, 0x1f251,), # Circled Ideograph Advant..Circled Ideograph Accept + (0x1f300, 0x1f320,), # Cyclone ..Shooting Star + (0x1f32d, 0x1f335,), # Hot Dog ..Cactus + (0x1f337, 0x1f37c,), # Tulip ..Baby Bottle + (0x1f37e, 0x1f393,), # Bottle With Popping Cork..Graduation Cap + (0x1f3a0, 0x1f3ca,), # Carousel Horse ..Swimmer + (0x1f3cf, 0x1f3d3,), # Cricket Bat And Ball ..Table Tennis Paddle And + (0x1f3e0, 0x1f3f0,), # House Building ..European Castle + (0x1f3f4, 0x1f3f4,), # Waving Black Flag ..Waving Black Flag + (0x1f3f8, 0x1f43e,), # Badminton Racquet And Sh..Paw Prints + (0x1f440, 0x1f440,), # Eyes ..Eyes + (0x1f442, 0x1f4fc,), # Ear ..Videocassette + (0x1f4ff, 0x1f53d,), # Prayer Beads ..Down-pointing Small Red + (0x1f54b, 0x1f54e,), # Kaaba ..Menorah With Nine Branch + (0x1f550, 0x1f567,), # Clock Face One Oclock ..Clock Face Twelve-thirty + (0x1f57a, 0x1f57a,), # Man Dancing ..Man Dancing + (0x1f595, 0x1f596,), # Reversed Hand With Middl..Raised Hand With Part Be + (0x1f5a4, 0x1f5a4,), # Black Heart ..Black Heart + (0x1f5fb, 0x1f64f,), # Mount Fuji ..Person With Folded Hands + (0x1f680, 0x1f6c5,), # Rocket ..Left Luggage + (0x1f6cc, 0x1f6cc,), # Sleeping Accommodation ..Sleeping Accommodation + (0x1f6d0, 0x1f6d2,), # Place Of Worship ..Shopping Trolley + (0x1f6eb, 0x1f6ec,), # Airplane Departure ..Airplane Arriving + (0x1f6f4, 0x1f6f6,), # Scooter ..Canoe + (0x1f910, 0x1f91e,), # Zipper-mouth Face ..Hand With Index And Midd + (0x1f920, 0x1f927,), # Face With Cowboy Hat ..Sneezing Face + (0x1f930, 0x1f930,), # Pregnant Woman ..Pregnant Woman + (0x1f933, 0x1f93e,), # Selfie ..Handball + (0x1f940, 0x1f94b,), # Wilted Flower ..Martial Arts Uniform + (0x1f950, 0x1f95e,), # Croissant ..Pancakes + (0x1f980, 0x1f991,), # Crab ..Squid + (0x1f9c0, 0x1f9c0,), # Cheese Wedge ..Cheese Wedge + (0x20000, 0x2fffd,), # Cjk Unified Ideograph-20..(nil) + (0x30000, 0x3fffd,), # (nil) ..(nil) + ), + '10.0.0': ( + # Source: EastAsianWidth-10.0.0.txt + # Date: 2017-03-08, 02:00:00 GMT [KW, LI] + # + (0x01100, 0x0115f,), # Hangul Choseong Kiyeok ..Hangul Choseong Filler + (0x0231a, 0x0231b,), # Watch ..Hourglass + (0x02329, 0x0232a,), # Left-pointing Angle Brac..Right-pointing Angle Bra + (0x023e9, 0x023ec,), # Black Right-pointing Dou..Black Down-pointing Doub + (0x023f0, 0x023f0,), # Alarm Clock ..Alarm Clock + (0x023f3, 0x023f3,), # Hourglass With Flowing S..Hourglass With Flowing S + (0x025fd, 0x025fe,), # White Medium Small Squar..Black Medium Small Squar + (0x02614, 0x02615,), # Umbrella With Rain Drops..Hot Beverage + (0x02648, 0x02653,), # Aries ..Pisces + (0x0267f, 0x0267f,), # Wheelchair Symbol ..Wheelchair Symbol + (0x02693, 0x02693,), # Anchor ..Anchor + (0x026a1, 0x026a1,), # High Voltage Sign ..High Voltage Sign + (0x026aa, 0x026ab,), # Medium White Circle ..Medium Black Circle + (0x026bd, 0x026be,), # Soccer Ball ..Baseball + (0x026c4, 0x026c5,), # Snowman Without Snow ..Sun Behind Cloud + (0x026ce, 0x026ce,), # Ophiuchus ..Ophiuchus + (0x026d4, 0x026d4,), # No Entry ..No Entry + (0x026ea, 0x026ea,), # Church ..Church + (0x026f2, 0x026f3,), # Fountain ..Flag In Hole + (0x026f5, 0x026f5,), # Sailboat ..Sailboat + (0x026fa, 0x026fa,), # Tent ..Tent + (0x026fd, 0x026fd,), # Fuel Pump ..Fuel Pump + (0x02705, 0x02705,), # White Heavy Check Mark ..White Heavy Check Mark + (0x0270a, 0x0270b,), # Raised Fist ..Raised Hand + (0x02728, 0x02728,), # Sparkles ..Sparkles + (0x0274c, 0x0274c,), # Cross Mark ..Cross Mark + (0x0274e, 0x0274e,), # Negative Squared Cross M..Negative Squared Cross M + (0x02753, 0x02755,), # Black Question Mark Orna..White Exclamation Mark O + (0x02757, 0x02757,), # Heavy Exclamation Mark S..Heavy Exclamation Mark S + (0x02795, 0x02797,), # Heavy Plus Sign ..Heavy Division Sign + (0x027b0, 0x027b0,), # Curly Loop ..Curly Loop + (0x027bf, 0x027bf,), # Double Curly Loop ..Double Curly Loop + (0x02b1b, 0x02b1c,), # Black Large Square ..White Large Square + (0x02b50, 0x02b50,), # White Medium Star ..White Medium Star + (0x02b55, 0x02b55,), # Heavy Large Circle ..Heavy Large Circle + (0x02e80, 0x02e99,), # Cjk Radical Repeat ..Cjk Radical Rap + (0x02e9b, 0x02ef3,), # Cjk Radical Choke ..Cjk Radical C-simplified + (0x02f00, 0x02fd5,), # Kangxi Radical One ..Kangxi Radical Flute + (0x02ff0, 0x02ffb,), # Ideographic Description ..Ideographic Description + (0x03000, 0x0303e,), # Ideographic Space ..Ideographic Variation In + (0x03041, 0x03096,), # Hiragana Letter Small A ..Hiragana Letter Small Ke + (0x03099, 0x030ff,), # Combining Katakana-hirag..Katakana Digraph Koto + (0x03105, 0x0312e,), # Bopomofo Letter B ..Bopomofo Letter O With D + (0x03131, 0x0318e,), # Hangul Letter Kiyeok ..Hangul Letter Araeae + (0x03190, 0x031ba,), # Ideographic Annotation L..Bopomofo Letter Zy + (0x031c0, 0x031e3,), # Cjk Stroke T ..Cjk Stroke Q + (0x031f0, 0x0321e,), # Katakana Letter Small Ku..Parenthesized Korean Cha + (0x03220, 0x03247,), # Parenthesized Ideograph ..Circled Ideograph Koto + (0x03250, 0x032fe,), # Partnership Sign ..Circled Katakana Wo + (0x03300, 0x04dbf,), # Square Apaato ..(nil) + (0x04e00, 0x0a48c,), # Cjk Unified Ideograph-4e..Yi Syllable Yyr + (0x0a490, 0x0a4c6,), # Yi Radical Qot ..Yi Radical Ke + (0x0a960, 0x0a97c,), # Hangul Choseong Tikeut-m..Hangul Choseong Ssangyeo + (0x0ac00, 0x0d7a3,), # Hangul Syllable Ga ..Hangul Syllable Hih + (0x0f900, 0x0faff,), # Cjk Compatibility Ideogr..(nil) + (0x0fe10, 0x0fe19,), # Presentation Form For Ve..Presentation Form For Ve + (0x0fe30, 0x0fe52,), # Presentation Form For Ve..Small Full Stop + (0x0fe54, 0x0fe66,), # Small Semicolon ..Small Equals Sign + (0x0fe68, 0x0fe6b,), # Small Reverse Solidus ..Small Commercial At + (0x0ff01, 0x0ff60,), # Fullwidth Exclamation Ma..Fullwidth Right White Pa + (0x0ffe0, 0x0ffe6,), # Fullwidth Cent Sign ..Fullwidth Won Sign + (0x16fe0, 0x16fe1,), # Tangut Iteration Mark ..Nushu Iteration Mark + (0x17000, 0x187ec,), # (nil) ..(nil) + (0x18800, 0x18af2,), # Tangut Component-001 ..Tangut Component-755 + (0x1b000, 0x1b11e,), # Katakana Letter Archaic ..Hentaigana Letter N-mu-m + (0x1b170, 0x1b2fb,), # Nushu Character-1b170 ..Nushu Character-1b2fb + (0x1f004, 0x1f004,), # Mahjong Tile Red Dragon ..Mahjong Tile Red Dragon + (0x1f0cf, 0x1f0cf,), # Playing Card Black Joker..Playing Card Black Joker + (0x1f18e, 0x1f18e,), # Negative Squared Ab ..Negative Squared Ab + (0x1f191, 0x1f19a,), # Squared Cl ..Squared Vs + (0x1f200, 0x1f202,), # Square Hiragana Hoka ..Squared Katakana Sa + (0x1f210, 0x1f23b,), # Squared Cjk Unified Ideo..Squared Cjk Unified Ideo + (0x1f240, 0x1f248,), # Tortoise Shell Bracketed..Tortoise Shell Bracketed + (0x1f250, 0x1f251,), # Circled Ideograph Advant..Circled Ideograph Accept + (0x1f260, 0x1f265,), # Rounded Symbol For Fu ..Rounded Symbol For Cai + (0x1f300, 0x1f320,), # Cyclone ..Shooting Star + (0x1f32d, 0x1f335,), # Hot Dog ..Cactus + (0x1f337, 0x1f37c,), # Tulip ..Baby Bottle + (0x1f37e, 0x1f393,), # Bottle With Popping Cork..Graduation Cap + (0x1f3a0, 0x1f3ca,), # Carousel Horse ..Swimmer + (0x1f3cf, 0x1f3d3,), # Cricket Bat And Ball ..Table Tennis Paddle And + (0x1f3e0, 0x1f3f0,), # House Building ..European Castle + (0x1f3f4, 0x1f3f4,), # Waving Black Flag ..Waving Black Flag + (0x1f3f8, 0x1f43e,), # Badminton Racquet And Sh..Paw Prints + (0x1f440, 0x1f440,), # Eyes ..Eyes + (0x1f442, 0x1f4fc,), # Ear ..Videocassette + (0x1f4ff, 0x1f53d,), # Prayer Beads ..Down-pointing Small Red + (0x1f54b, 0x1f54e,), # Kaaba ..Menorah With Nine Branch + (0x1f550, 0x1f567,), # Clock Face One Oclock ..Clock Face Twelve-thirty + (0x1f57a, 0x1f57a,), # Man Dancing ..Man Dancing + (0x1f595, 0x1f596,), # Reversed Hand With Middl..Raised Hand With Part Be + (0x1f5a4, 0x1f5a4,), # Black Heart ..Black Heart + (0x1f5fb, 0x1f64f,), # Mount Fuji ..Person With Folded Hands + (0x1f680, 0x1f6c5,), # Rocket ..Left Luggage + (0x1f6cc, 0x1f6cc,), # Sleeping Accommodation ..Sleeping Accommodation + (0x1f6d0, 0x1f6d2,), # Place Of Worship ..Shopping Trolley + (0x1f6eb, 0x1f6ec,), # Airplane Departure ..Airplane Arriving + (0x1f6f4, 0x1f6f8,), # Scooter ..Flying Saucer + (0x1f910, 0x1f93e,), # Zipper-mouth Face ..Handball + (0x1f940, 0x1f94c,), # Wilted Flower ..Curling Stone + (0x1f950, 0x1f96b,), # Croissant ..Canned Food + (0x1f980, 0x1f997,), # Crab ..Cricket + (0x1f9c0, 0x1f9c0,), # Cheese Wedge ..Cheese Wedge + (0x1f9d0, 0x1f9e6,), # Face With Monocle ..Socks + (0x20000, 0x2fffd,), # Cjk Unified Ideograph-20..(nil) + (0x30000, 0x3fffd,), # (nil) ..(nil) + ), + '11.0.0': ( + # Source: EastAsianWidth-11.0.0.txt + # Date: 2018-05-14, 09:41:59 GMT [KW, LI] + # + (0x01100, 0x0115f,), # Hangul Choseong Kiyeok ..Hangul Choseong Filler + (0x0231a, 0x0231b,), # Watch ..Hourglass + (0x02329, 0x0232a,), # Left-pointing Angle Brac..Right-pointing Angle Bra + (0x023e9, 0x023ec,), # Black Right-pointing Dou..Black Down-pointing Doub + (0x023f0, 0x023f0,), # Alarm Clock ..Alarm Clock + (0x023f3, 0x023f3,), # Hourglass With Flowing S..Hourglass With Flowing S + (0x025fd, 0x025fe,), # White Medium Small Squar..Black Medium Small Squar + (0x02614, 0x02615,), # Umbrella With Rain Drops..Hot Beverage + (0x02648, 0x02653,), # Aries ..Pisces + (0x0267f, 0x0267f,), # Wheelchair Symbol ..Wheelchair Symbol + (0x02693, 0x02693,), # Anchor ..Anchor + (0x026a1, 0x026a1,), # High Voltage Sign ..High Voltage Sign + (0x026aa, 0x026ab,), # Medium White Circle ..Medium Black Circle + (0x026bd, 0x026be,), # Soccer Ball ..Baseball + (0x026c4, 0x026c5,), # Snowman Without Snow ..Sun Behind Cloud + (0x026ce, 0x026ce,), # Ophiuchus ..Ophiuchus + (0x026d4, 0x026d4,), # No Entry ..No Entry + (0x026ea, 0x026ea,), # Church ..Church + (0x026f2, 0x026f3,), # Fountain ..Flag In Hole + (0x026f5, 0x026f5,), # Sailboat ..Sailboat + (0x026fa, 0x026fa,), # Tent ..Tent + (0x026fd, 0x026fd,), # Fuel Pump ..Fuel Pump + (0x02705, 0x02705,), # White Heavy Check Mark ..White Heavy Check Mark + (0x0270a, 0x0270b,), # Raised Fist ..Raised Hand + (0x02728, 0x02728,), # Sparkles ..Sparkles + (0x0274c, 0x0274c,), # Cross Mark ..Cross Mark + (0x0274e, 0x0274e,), # Negative Squared Cross M..Negative Squared Cross M + (0x02753, 0x02755,), # Black Question Mark Orna..White Exclamation Mark O + (0x02757, 0x02757,), # Heavy Exclamation Mark S..Heavy Exclamation Mark S + (0x02795, 0x02797,), # Heavy Plus Sign ..Heavy Division Sign + (0x027b0, 0x027b0,), # Curly Loop ..Curly Loop + (0x027bf, 0x027bf,), # Double Curly Loop ..Double Curly Loop + (0x02b1b, 0x02b1c,), # Black Large Square ..White Large Square + (0x02b50, 0x02b50,), # White Medium Star ..White Medium Star + (0x02b55, 0x02b55,), # Heavy Large Circle ..Heavy Large Circle + (0x02e80, 0x02e99,), # Cjk Radical Repeat ..Cjk Radical Rap + (0x02e9b, 0x02ef3,), # Cjk Radical Choke ..Cjk Radical C-simplified + (0x02f00, 0x02fd5,), # Kangxi Radical One ..Kangxi Radical Flute + (0x02ff0, 0x02ffb,), # Ideographic Description ..Ideographic Description + (0x03000, 0x0303e,), # Ideographic Space ..Ideographic Variation In + (0x03041, 0x03096,), # Hiragana Letter Small A ..Hiragana Letter Small Ke + (0x03099, 0x030ff,), # Combining Katakana-hirag..Katakana Digraph Koto + (0x03105, 0x0312f,), # Bopomofo Letter B ..Bopomofo Letter Nn + (0x03131, 0x0318e,), # Hangul Letter Kiyeok ..Hangul Letter Araeae + (0x03190, 0x031ba,), # Ideographic Annotation L..Bopomofo Letter Zy + (0x031c0, 0x031e3,), # Cjk Stroke T ..Cjk Stroke Q + (0x031f0, 0x0321e,), # Katakana Letter Small Ku..Parenthesized Korean Cha + (0x03220, 0x03247,), # Parenthesized Ideograph ..Circled Ideograph Koto + (0x03250, 0x032fe,), # Partnership Sign ..Circled Katakana Wo + (0x03300, 0x04dbf,), # Square Apaato ..(nil) + (0x04e00, 0x0a48c,), # Cjk Unified Ideograph-4e..Yi Syllable Yyr + (0x0a490, 0x0a4c6,), # Yi Radical Qot ..Yi Radical Ke + (0x0a960, 0x0a97c,), # Hangul Choseong Tikeut-m..Hangul Choseong Ssangyeo + (0x0ac00, 0x0d7a3,), # Hangul Syllable Ga ..Hangul Syllable Hih + (0x0f900, 0x0faff,), # Cjk Compatibility Ideogr..(nil) + (0x0fe10, 0x0fe19,), # Presentation Form For Ve..Presentation Form For Ve + (0x0fe30, 0x0fe52,), # Presentation Form For Ve..Small Full Stop + (0x0fe54, 0x0fe66,), # Small Semicolon ..Small Equals Sign + (0x0fe68, 0x0fe6b,), # Small Reverse Solidus ..Small Commercial At + (0x0ff01, 0x0ff60,), # Fullwidth Exclamation Ma..Fullwidth Right White Pa + (0x0ffe0, 0x0ffe6,), # Fullwidth Cent Sign ..Fullwidth Won Sign + (0x16fe0, 0x16fe1,), # Tangut Iteration Mark ..Nushu Iteration Mark + (0x17000, 0x187f1,), # (nil) ..(nil) + (0x18800, 0x18af2,), # Tangut Component-001 ..Tangut Component-755 + (0x1b000, 0x1b11e,), # Katakana Letter Archaic ..Hentaigana Letter N-mu-m + (0x1b170, 0x1b2fb,), # Nushu Character-1b170 ..Nushu Character-1b2fb + (0x1f004, 0x1f004,), # Mahjong Tile Red Dragon ..Mahjong Tile Red Dragon + (0x1f0cf, 0x1f0cf,), # Playing Card Black Joker..Playing Card Black Joker + (0x1f18e, 0x1f18e,), # Negative Squared Ab ..Negative Squared Ab + (0x1f191, 0x1f19a,), # Squared Cl ..Squared Vs + (0x1f200, 0x1f202,), # Square Hiragana Hoka ..Squared Katakana Sa + (0x1f210, 0x1f23b,), # Squared Cjk Unified Ideo..Squared Cjk Unified Ideo + (0x1f240, 0x1f248,), # Tortoise Shell Bracketed..Tortoise Shell Bracketed + (0x1f250, 0x1f251,), # Circled Ideograph Advant..Circled Ideograph Accept + (0x1f260, 0x1f265,), # Rounded Symbol For Fu ..Rounded Symbol For Cai + (0x1f300, 0x1f320,), # Cyclone ..Shooting Star + (0x1f32d, 0x1f335,), # Hot Dog ..Cactus + (0x1f337, 0x1f37c,), # Tulip ..Baby Bottle + (0x1f37e, 0x1f393,), # Bottle With Popping Cork..Graduation Cap + (0x1f3a0, 0x1f3ca,), # Carousel Horse ..Swimmer + (0x1f3cf, 0x1f3d3,), # Cricket Bat And Ball ..Table Tennis Paddle And + (0x1f3e0, 0x1f3f0,), # House Building ..European Castle + (0x1f3f4, 0x1f3f4,), # Waving Black Flag ..Waving Black Flag + (0x1f3f8, 0x1f43e,), # Badminton Racquet And Sh..Paw Prints + (0x1f440, 0x1f440,), # Eyes ..Eyes + (0x1f442, 0x1f4fc,), # Ear ..Videocassette + (0x1f4ff, 0x1f53d,), # Prayer Beads ..Down-pointing Small Red + (0x1f54b, 0x1f54e,), # Kaaba ..Menorah With Nine Branch + (0x1f550, 0x1f567,), # Clock Face One Oclock ..Clock Face Twelve-thirty + (0x1f57a, 0x1f57a,), # Man Dancing ..Man Dancing + (0x1f595, 0x1f596,), # Reversed Hand With Middl..Raised Hand With Part Be + (0x1f5a4, 0x1f5a4,), # Black Heart ..Black Heart + (0x1f5fb, 0x1f64f,), # Mount Fuji ..Person With Folded Hands + (0x1f680, 0x1f6c5,), # Rocket ..Left Luggage + (0x1f6cc, 0x1f6cc,), # Sleeping Accommodation ..Sleeping Accommodation + (0x1f6d0, 0x1f6d2,), # Place Of Worship ..Shopping Trolley + (0x1f6eb, 0x1f6ec,), # Airplane Departure ..Airplane Arriving + (0x1f6f4, 0x1f6f9,), # Scooter ..Skateboard + (0x1f910, 0x1f93e,), # Zipper-mouth Face ..Handball + (0x1f940, 0x1f970,), # Wilted Flower ..Smiling Face With Smilin + (0x1f973, 0x1f976,), # Face With Party Horn And..Freezing Face + (0x1f97a, 0x1f97a,), # Face With Pleading Eyes ..Face With Pleading Eyes + (0x1f97c, 0x1f9a2,), # Lab Coat ..Swan + (0x1f9b0, 0x1f9b9,), # Emoji Component Red Hair..Supervillain + (0x1f9c0, 0x1f9c2,), # Cheese Wedge ..Salt Shaker + (0x1f9d0, 0x1f9ff,), # Face With Monocle ..Nazar Amulet + (0x20000, 0x2fffd,), # Cjk Unified Ideograph-20..(nil) + (0x30000, 0x3fffd,), # (nil) ..(nil) + ), + '12.0.0': ( + # Source: EastAsianWidth-12.0.0.txt + # Date: 2019-01-21, 14:12:58 GMT [KW, LI] + # + (0x01100, 0x0115f,), # Hangul Choseong Kiyeok ..Hangul Choseong Filler + (0x0231a, 0x0231b,), # Watch ..Hourglass + (0x02329, 0x0232a,), # Left-pointing Angle Brac..Right-pointing Angle Bra + (0x023e9, 0x023ec,), # Black Right-pointing Dou..Black Down-pointing Doub + (0x023f0, 0x023f0,), # Alarm Clock ..Alarm Clock + (0x023f3, 0x023f3,), # Hourglass With Flowing S..Hourglass With Flowing S + (0x025fd, 0x025fe,), # White Medium Small Squar..Black Medium Small Squar + (0x02614, 0x02615,), # Umbrella With Rain Drops..Hot Beverage + (0x02648, 0x02653,), # Aries ..Pisces + (0x0267f, 0x0267f,), # Wheelchair Symbol ..Wheelchair Symbol + (0x02693, 0x02693,), # Anchor ..Anchor + (0x026a1, 0x026a1,), # High Voltage Sign ..High Voltage Sign + (0x026aa, 0x026ab,), # Medium White Circle ..Medium Black Circle + (0x026bd, 0x026be,), # Soccer Ball ..Baseball + (0x026c4, 0x026c5,), # Snowman Without Snow ..Sun Behind Cloud + (0x026ce, 0x026ce,), # Ophiuchus ..Ophiuchus + (0x026d4, 0x026d4,), # No Entry ..No Entry + (0x026ea, 0x026ea,), # Church ..Church + (0x026f2, 0x026f3,), # Fountain ..Flag In Hole + (0x026f5, 0x026f5,), # Sailboat ..Sailboat + (0x026fa, 0x026fa,), # Tent ..Tent + (0x026fd, 0x026fd,), # Fuel Pump ..Fuel Pump + (0x02705, 0x02705,), # White Heavy Check Mark ..White Heavy Check Mark + (0x0270a, 0x0270b,), # Raised Fist ..Raised Hand + (0x02728, 0x02728,), # Sparkles ..Sparkles + (0x0274c, 0x0274c,), # Cross Mark ..Cross Mark + (0x0274e, 0x0274e,), # Negative Squared Cross M..Negative Squared Cross M + (0x02753, 0x02755,), # Black Question Mark Orna..White Exclamation Mark O + (0x02757, 0x02757,), # Heavy Exclamation Mark S..Heavy Exclamation Mark S + (0x02795, 0x02797,), # Heavy Plus Sign ..Heavy Division Sign + (0x027b0, 0x027b0,), # Curly Loop ..Curly Loop + (0x027bf, 0x027bf,), # Double Curly Loop ..Double Curly Loop + (0x02b1b, 0x02b1c,), # Black Large Square ..White Large Square + (0x02b50, 0x02b50,), # White Medium Star ..White Medium Star + (0x02b55, 0x02b55,), # Heavy Large Circle ..Heavy Large Circle + (0x02e80, 0x02e99,), # Cjk Radical Repeat ..Cjk Radical Rap + (0x02e9b, 0x02ef3,), # Cjk Radical Choke ..Cjk Radical C-simplified + (0x02f00, 0x02fd5,), # Kangxi Radical One ..Kangxi Radical Flute + (0x02ff0, 0x02ffb,), # Ideographic Description ..Ideographic Description + (0x03000, 0x0303e,), # Ideographic Space ..Ideographic Variation In + (0x03041, 0x03096,), # Hiragana Letter Small A ..Hiragana Letter Small Ke + (0x03099, 0x030ff,), # Combining Katakana-hirag..Katakana Digraph Koto + (0x03105, 0x0312f,), # Bopomofo Letter B ..Bopomofo Letter Nn + (0x03131, 0x0318e,), # Hangul Letter Kiyeok ..Hangul Letter Araeae + (0x03190, 0x031ba,), # Ideographic Annotation L..Bopomofo Letter Zy + (0x031c0, 0x031e3,), # Cjk Stroke T ..Cjk Stroke Q + (0x031f0, 0x0321e,), # Katakana Letter Small Ku..Parenthesized Korean Cha + (0x03220, 0x03247,), # Parenthesized Ideograph ..Circled Ideograph Koto + (0x03250, 0x032fe,), # Partnership Sign ..Circled Katakana Wo + (0x03300, 0x04dbf,), # Square Apaato ..(nil) + (0x04e00, 0x0a48c,), # Cjk Unified Ideograph-4e..Yi Syllable Yyr + (0x0a490, 0x0a4c6,), # Yi Radical Qot ..Yi Radical Ke + (0x0a960, 0x0a97c,), # Hangul Choseong Tikeut-m..Hangul Choseong Ssangyeo + (0x0ac00, 0x0d7a3,), # Hangul Syllable Ga ..Hangul Syllable Hih + (0x0f900, 0x0faff,), # Cjk Compatibility Ideogr..(nil) + (0x0fe10, 0x0fe19,), # Presentation Form For Ve..Presentation Form For Ve + (0x0fe30, 0x0fe52,), # Presentation Form For Ve..Small Full Stop + (0x0fe54, 0x0fe66,), # Small Semicolon ..Small Equals Sign + (0x0fe68, 0x0fe6b,), # Small Reverse Solidus ..Small Commercial At + (0x0ff01, 0x0ff60,), # Fullwidth Exclamation Ma..Fullwidth Right White Pa + (0x0ffe0, 0x0ffe6,), # Fullwidth Cent Sign ..Fullwidth Won Sign + (0x16fe0, 0x16fe3,), # Tangut Iteration Mark ..Old Chinese Iteration Ma + (0x17000, 0x187f7,), # (nil) ..(nil) + (0x18800, 0x18af2,), # Tangut Component-001 ..Tangut Component-755 + (0x1b000, 0x1b11e,), # Katakana Letter Archaic ..Hentaigana Letter N-mu-m + (0x1b150, 0x1b152,), # Hiragana Letter Small Wi..Hiragana Letter Small Wo + (0x1b164, 0x1b167,), # Katakana Letter Small Wi..Katakana Letter Small N + (0x1b170, 0x1b2fb,), # Nushu Character-1b170 ..Nushu Character-1b2fb + (0x1f004, 0x1f004,), # Mahjong Tile Red Dragon ..Mahjong Tile Red Dragon + (0x1f0cf, 0x1f0cf,), # Playing Card Black Joker..Playing Card Black Joker + (0x1f18e, 0x1f18e,), # Negative Squared Ab ..Negative Squared Ab + (0x1f191, 0x1f19a,), # Squared Cl ..Squared Vs + (0x1f200, 0x1f202,), # Square Hiragana Hoka ..Squared Katakana Sa + (0x1f210, 0x1f23b,), # Squared Cjk Unified Ideo..Squared Cjk Unified Ideo + (0x1f240, 0x1f248,), # Tortoise Shell Bracketed..Tortoise Shell Bracketed + (0x1f250, 0x1f251,), # Circled Ideograph Advant..Circled Ideograph Accept + (0x1f260, 0x1f265,), # Rounded Symbol For Fu ..Rounded Symbol For Cai + (0x1f300, 0x1f320,), # Cyclone ..Shooting Star + (0x1f32d, 0x1f335,), # Hot Dog ..Cactus + (0x1f337, 0x1f37c,), # Tulip ..Baby Bottle + (0x1f37e, 0x1f393,), # Bottle With Popping Cork..Graduation Cap + (0x1f3a0, 0x1f3ca,), # Carousel Horse ..Swimmer + (0x1f3cf, 0x1f3d3,), # Cricket Bat And Ball ..Table Tennis Paddle And + (0x1f3e0, 0x1f3f0,), # House Building ..European Castle + (0x1f3f4, 0x1f3f4,), # Waving Black Flag ..Waving Black Flag + (0x1f3f8, 0x1f43e,), # Badminton Racquet And Sh..Paw Prints + (0x1f440, 0x1f440,), # Eyes ..Eyes + (0x1f442, 0x1f4fc,), # Ear ..Videocassette + (0x1f4ff, 0x1f53d,), # Prayer Beads ..Down-pointing Small Red + (0x1f54b, 0x1f54e,), # Kaaba ..Menorah With Nine Branch + (0x1f550, 0x1f567,), # Clock Face One Oclock ..Clock Face Twelve-thirty + (0x1f57a, 0x1f57a,), # Man Dancing ..Man Dancing + (0x1f595, 0x1f596,), # Reversed Hand With Middl..Raised Hand With Part Be + (0x1f5a4, 0x1f5a4,), # Black Heart ..Black Heart + (0x1f5fb, 0x1f64f,), # Mount Fuji ..Person With Folded Hands + (0x1f680, 0x1f6c5,), # Rocket ..Left Luggage + (0x1f6cc, 0x1f6cc,), # Sleeping Accommodation ..Sleeping Accommodation + (0x1f6d0, 0x1f6d2,), # Place Of Worship ..Shopping Trolley + (0x1f6d5, 0x1f6d5,), # Hindu Temple ..Hindu Temple + (0x1f6eb, 0x1f6ec,), # Airplane Departure ..Airplane Arriving + (0x1f6f4, 0x1f6fa,), # Scooter ..Auto Rickshaw + (0x1f7e0, 0x1f7eb,), # Large Orange Circle ..Large Brown Square + (0x1f90d, 0x1f971,), # White Heart ..Yawning Face + (0x1f973, 0x1f976,), # Face With Party Horn And..Freezing Face + (0x1f97a, 0x1f9a2,), # Face With Pleading Eyes ..Swan + (0x1f9a5, 0x1f9aa,), # Sloth ..Oyster + (0x1f9ae, 0x1f9ca,), # Guide Dog ..Ice Cube + (0x1f9cd, 0x1f9ff,), # Standing Person ..Nazar Amulet + (0x1fa70, 0x1fa73,), # Ballet Shoes ..Shorts + (0x1fa78, 0x1fa7a,), # Drop Of Blood ..Stethoscope + (0x1fa80, 0x1fa82,), # Yo-yo ..Parachute + (0x1fa90, 0x1fa95,), # Ringed Planet ..Banjo + (0x20000, 0x2fffd,), # Cjk Unified Ideograph-20..(nil) + (0x30000, 0x3fffd,), # (nil) ..(nil) + ), + '12.1.0': ( + # Source: EastAsianWidth-12.1.0.txt + # Date: 2019-03-31, 22:01:58 GMT [KW, LI] + # + (0x01100, 0x0115f,), # Hangul Choseong Kiyeok ..Hangul Choseong Filler + (0x0231a, 0x0231b,), # Watch ..Hourglass + (0x02329, 0x0232a,), # Left-pointing Angle Brac..Right-pointing Angle Bra + (0x023e9, 0x023ec,), # Black Right-pointing Dou..Black Down-pointing Doub + (0x023f0, 0x023f0,), # Alarm Clock ..Alarm Clock + (0x023f3, 0x023f3,), # Hourglass With Flowing S..Hourglass With Flowing S + (0x025fd, 0x025fe,), # White Medium Small Squar..Black Medium Small Squar + (0x02614, 0x02615,), # Umbrella With Rain Drops..Hot Beverage + (0x02648, 0x02653,), # Aries ..Pisces + (0x0267f, 0x0267f,), # Wheelchair Symbol ..Wheelchair Symbol + (0x02693, 0x02693,), # Anchor ..Anchor + (0x026a1, 0x026a1,), # High Voltage Sign ..High Voltage Sign + (0x026aa, 0x026ab,), # Medium White Circle ..Medium Black Circle + (0x026bd, 0x026be,), # Soccer Ball ..Baseball + (0x026c4, 0x026c5,), # Snowman Without Snow ..Sun Behind Cloud + (0x026ce, 0x026ce,), # Ophiuchus ..Ophiuchus + (0x026d4, 0x026d4,), # No Entry ..No Entry + (0x026ea, 0x026ea,), # Church ..Church + (0x026f2, 0x026f3,), # Fountain ..Flag In Hole + (0x026f5, 0x026f5,), # Sailboat ..Sailboat + (0x026fa, 0x026fa,), # Tent ..Tent + (0x026fd, 0x026fd,), # Fuel Pump ..Fuel Pump + (0x02705, 0x02705,), # White Heavy Check Mark ..White Heavy Check Mark + (0x0270a, 0x0270b,), # Raised Fist ..Raised Hand + (0x02728, 0x02728,), # Sparkles ..Sparkles + (0x0274c, 0x0274c,), # Cross Mark ..Cross Mark + (0x0274e, 0x0274e,), # Negative Squared Cross M..Negative Squared Cross M + (0x02753, 0x02755,), # Black Question Mark Orna..White Exclamation Mark O + (0x02757, 0x02757,), # Heavy Exclamation Mark S..Heavy Exclamation Mark S + (0x02795, 0x02797,), # Heavy Plus Sign ..Heavy Division Sign + (0x027b0, 0x027b0,), # Curly Loop ..Curly Loop + (0x027bf, 0x027bf,), # Double Curly Loop ..Double Curly Loop + (0x02b1b, 0x02b1c,), # Black Large Square ..White Large Square + (0x02b50, 0x02b50,), # White Medium Star ..White Medium Star + (0x02b55, 0x02b55,), # Heavy Large Circle ..Heavy Large Circle + (0x02e80, 0x02e99,), # Cjk Radical Repeat ..Cjk Radical Rap + (0x02e9b, 0x02ef3,), # Cjk Radical Choke ..Cjk Radical C-simplified + (0x02f00, 0x02fd5,), # Kangxi Radical One ..Kangxi Radical Flute + (0x02ff0, 0x02ffb,), # Ideographic Description ..Ideographic Description + (0x03000, 0x0303e,), # Ideographic Space ..Ideographic Variation In + (0x03041, 0x03096,), # Hiragana Letter Small A ..Hiragana Letter Small Ke + (0x03099, 0x030ff,), # Combining Katakana-hirag..Katakana Digraph Koto + (0x03105, 0x0312f,), # Bopomofo Letter B ..Bopomofo Letter Nn + (0x03131, 0x0318e,), # Hangul Letter Kiyeok ..Hangul Letter Araeae + (0x03190, 0x031ba,), # Ideographic Annotation L..Bopomofo Letter Zy + (0x031c0, 0x031e3,), # Cjk Stroke T ..Cjk Stroke Q + (0x031f0, 0x0321e,), # Katakana Letter Small Ku..Parenthesized Korean Cha + (0x03220, 0x03247,), # Parenthesized Ideograph ..Circled Ideograph Koto + (0x03250, 0x04dbf,), # Partnership Sign ..(nil) + (0x04e00, 0x0a48c,), # Cjk Unified Ideograph-4e..Yi Syllable Yyr + (0x0a490, 0x0a4c6,), # Yi Radical Qot ..Yi Radical Ke + (0x0a960, 0x0a97c,), # Hangul Choseong Tikeut-m..Hangul Choseong Ssangyeo + (0x0ac00, 0x0d7a3,), # Hangul Syllable Ga ..Hangul Syllable Hih + (0x0f900, 0x0faff,), # Cjk Compatibility Ideogr..(nil) + (0x0fe10, 0x0fe19,), # Presentation Form For Ve..Presentation Form For Ve + (0x0fe30, 0x0fe52,), # Presentation Form For Ve..Small Full Stop + (0x0fe54, 0x0fe66,), # Small Semicolon ..Small Equals Sign + (0x0fe68, 0x0fe6b,), # Small Reverse Solidus ..Small Commercial At + (0x0ff01, 0x0ff60,), # Fullwidth Exclamation Ma..Fullwidth Right White Pa + (0x0ffe0, 0x0ffe6,), # Fullwidth Cent Sign ..Fullwidth Won Sign + (0x16fe0, 0x16fe3,), # Tangut Iteration Mark ..Old Chinese Iteration Ma + (0x17000, 0x187f7,), # (nil) ..(nil) + (0x18800, 0x18af2,), # Tangut Component-001 ..Tangut Component-755 + (0x1b000, 0x1b11e,), # Katakana Letter Archaic ..Hentaigana Letter N-mu-m + (0x1b150, 0x1b152,), # Hiragana Letter Small Wi..Hiragana Letter Small Wo + (0x1b164, 0x1b167,), # Katakana Letter Small Wi..Katakana Letter Small N + (0x1b170, 0x1b2fb,), # Nushu Character-1b170 ..Nushu Character-1b2fb + (0x1f004, 0x1f004,), # Mahjong Tile Red Dragon ..Mahjong Tile Red Dragon + (0x1f0cf, 0x1f0cf,), # Playing Card Black Joker..Playing Card Black Joker + (0x1f18e, 0x1f18e,), # Negative Squared Ab ..Negative Squared Ab + (0x1f191, 0x1f19a,), # Squared Cl ..Squared Vs + (0x1f200, 0x1f202,), # Square Hiragana Hoka ..Squared Katakana Sa + (0x1f210, 0x1f23b,), # Squared Cjk Unified Ideo..Squared Cjk Unified Ideo + (0x1f240, 0x1f248,), # Tortoise Shell Bracketed..Tortoise Shell Bracketed + (0x1f250, 0x1f251,), # Circled Ideograph Advant..Circled Ideograph Accept + (0x1f260, 0x1f265,), # Rounded Symbol For Fu ..Rounded Symbol For Cai + (0x1f300, 0x1f320,), # Cyclone ..Shooting Star + (0x1f32d, 0x1f335,), # Hot Dog ..Cactus + (0x1f337, 0x1f37c,), # Tulip ..Baby Bottle + (0x1f37e, 0x1f393,), # Bottle With Popping Cork..Graduation Cap + (0x1f3a0, 0x1f3ca,), # Carousel Horse ..Swimmer + (0x1f3cf, 0x1f3d3,), # Cricket Bat And Ball ..Table Tennis Paddle And + (0x1f3e0, 0x1f3f0,), # House Building ..European Castle + (0x1f3f4, 0x1f3f4,), # Waving Black Flag ..Waving Black Flag + (0x1f3f8, 0x1f43e,), # Badminton Racquet And Sh..Paw Prints + (0x1f440, 0x1f440,), # Eyes ..Eyes + (0x1f442, 0x1f4fc,), # Ear ..Videocassette + (0x1f4ff, 0x1f53d,), # Prayer Beads ..Down-pointing Small Red + (0x1f54b, 0x1f54e,), # Kaaba ..Menorah With Nine Branch + (0x1f550, 0x1f567,), # Clock Face One Oclock ..Clock Face Twelve-thirty + (0x1f57a, 0x1f57a,), # Man Dancing ..Man Dancing + (0x1f595, 0x1f596,), # Reversed Hand With Middl..Raised Hand With Part Be + (0x1f5a4, 0x1f5a4,), # Black Heart ..Black Heart + (0x1f5fb, 0x1f64f,), # Mount Fuji ..Person With Folded Hands + (0x1f680, 0x1f6c5,), # Rocket ..Left Luggage + (0x1f6cc, 0x1f6cc,), # Sleeping Accommodation ..Sleeping Accommodation + (0x1f6d0, 0x1f6d2,), # Place Of Worship ..Shopping Trolley + (0x1f6d5, 0x1f6d5,), # Hindu Temple ..Hindu Temple + (0x1f6eb, 0x1f6ec,), # Airplane Departure ..Airplane Arriving + (0x1f6f4, 0x1f6fa,), # Scooter ..Auto Rickshaw + (0x1f7e0, 0x1f7eb,), # Large Orange Circle ..Large Brown Square + (0x1f90d, 0x1f971,), # White Heart ..Yawning Face + (0x1f973, 0x1f976,), # Face With Party Horn And..Freezing Face + (0x1f97a, 0x1f9a2,), # Face With Pleading Eyes ..Swan + (0x1f9a5, 0x1f9aa,), # Sloth ..Oyster + (0x1f9ae, 0x1f9ca,), # Guide Dog ..Ice Cube + (0x1f9cd, 0x1f9ff,), # Standing Person ..Nazar Amulet + (0x1fa70, 0x1fa73,), # Ballet Shoes ..Shorts + (0x1fa78, 0x1fa7a,), # Drop Of Blood ..Stethoscope + (0x1fa80, 0x1fa82,), # Yo-yo ..Parachute + (0x1fa90, 0x1fa95,), # Ringed Planet ..Banjo + (0x20000, 0x2fffd,), # Cjk Unified Ideograph-20..(nil) + (0x30000, 0x3fffd,), # (nil) ..(nil) + ), + '13.0.0': ( + # Source: EastAsianWidth-13.0.0.txt + # Date: 2029-01-21, 18:14:00 GMT [KW, LI] + # + (0x01100, 0x0115f,), # Hangul Choseong Kiyeok ..Hangul Choseong Filler + (0x0231a, 0x0231b,), # Watch ..Hourglass + (0x02329, 0x0232a,), # Left-pointing Angle Brac..Right-pointing Angle Bra + (0x023e9, 0x023ec,), # Black Right-pointing Dou..Black Down-pointing Doub + (0x023f0, 0x023f0,), # Alarm Clock ..Alarm Clock + (0x023f3, 0x023f3,), # Hourglass With Flowing S..Hourglass With Flowing S + (0x025fd, 0x025fe,), # White Medium Small Squar..Black Medium Small Squar + (0x02614, 0x02615,), # Umbrella With Rain Drops..Hot Beverage + (0x02648, 0x02653,), # Aries ..Pisces + (0x0267f, 0x0267f,), # Wheelchair Symbol ..Wheelchair Symbol + (0x02693, 0x02693,), # Anchor ..Anchor + (0x026a1, 0x026a1,), # High Voltage Sign ..High Voltage Sign + (0x026aa, 0x026ab,), # Medium White Circle ..Medium Black Circle + (0x026bd, 0x026be,), # Soccer Ball ..Baseball + (0x026c4, 0x026c5,), # Snowman Without Snow ..Sun Behind Cloud + (0x026ce, 0x026ce,), # Ophiuchus ..Ophiuchus + (0x026d4, 0x026d4,), # No Entry ..No Entry + (0x026ea, 0x026ea,), # Church ..Church + (0x026f2, 0x026f3,), # Fountain ..Flag In Hole + (0x026f5, 0x026f5,), # Sailboat ..Sailboat + (0x026fa, 0x026fa,), # Tent ..Tent + (0x026fd, 0x026fd,), # Fuel Pump ..Fuel Pump + (0x02705, 0x02705,), # White Heavy Check Mark ..White Heavy Check Mark + (0x0270a, 0x0270b,), # Raised Fist ..Raised Hand + (0x02728, 0x02728,), # Sparkles ..Sparkles + (0x0274c, 0x0274c,), # Cross Mark ..Cross Mark + (0x0274e, 0x0274e,), # Negative Squared Cross M..Negative Squared Cross M + (0x02753, 0x02755,), # Black Question Mark Orna..White Exclamation Mark O + (0x02757, 0x02757,), # Heavy Exclamation Mark S..Heavy Exclamation Mark S + (0x02795, 0x02797,), # Heavy Plus Sign ..Heavy Division Sign + (0x027b0, 0x027b0,), # Curly Loop ..Curly Loop + (0x027bf, 0x027bf,), # Double Curly Loop ..Double Curly Loop + (0x02b1b, 0x02b1c,), # Black Large Square ..White Large Square + (0x02b50, 0x02b50,), # White Medium Star ..White Medium Star + (0x02b55, 0x02b55,), # Heavy Large Circle ..Heavy Large Circle + (0x02e80, 0x02e99,), # Cjk Radical Repeat ..Cjk Radical Rap + (0x02e9b, 0x02ef3,), # Cjk Radical Choke ..Cjk Radical C-simplified + (0x02f00, 0x02fd5,), # Kangxi Radical One ..Kangxi Radical Flute + (0x02ff0, 0x02ffb,), # Ideographic Description ..Ideographic Description + (0x03000, 0x0303e,), # Ideographic Space ..Ideographic Variation In + (0x03041, 0x03096,), # Hiragana Letter Small A ..Hiragana Letter Small Ke + (0x03099, 0x030ff,), # Combining Katakana-hirag..Katakana Digraph Koto + (0x03105, 0x0312f,), # Bopomofo Letter B ..Bopomofo Letter Nn + (0x03131, 0x0318e,), # Hangul Letter Kiyeok ..Hangul Letter Araeae + (0x03190, 0x031e3,), # Ideographic Annotation L..Cjk Stroke Q + (0x031f0, 0x0321e,), # Katakana Letter Small Ku..Parenthesized Korean Cha + (0x03220, 0x03247,), # Parenthesized Ideograph ..Circled Ideograph Koto + (0x03250, 0x04dbf,), # Partnership Sign ..(nil) + (0x04e00, 0x0a48c,), # Cjk Unified Ideograph-4e..Yi Syllable Yyr + (0x0a490, 0x0a4c6,), # Yi Radical Qot ..Yi Radical Ke + (0x0a960, 0x0a97c,), # Hangul Choseong Tikeut-m..Hangul Choseong Ssangyeo + (0x0ac00, 0x0d7a3,), # Hangul Syllable Ga ..Hangul Syllable Hih + (0x0f900, 0x0faff,), # Cjk Compatibility Ideogr..(nil) + (0x0fe10, 0x0fe19,), # Presentation Form For Ve..Presentation Form For Ve + (0x0fe30, 0x0fe52,), # Presentation Form For Ve..Small Full Stop + (0x0fe54, 0x0fe66,), # Small Semicolon ..Small Equals Sign + (0x0fe68, 0x0fe6b,), # Small Reverse Solidus ..Small Commercial At + (0x0ff01, 0x0ff60,), # Fullwidth Exclamation Ma..Fullwidth Right White Pa + (0x0ffe0, 0x0ffe6,), # Fullwidth Cent Sign ..Fullwidth Won Sign + (0x16fe0, 0x16fe4,), # Tangut Iteration Mark ..(nil) + (0x16ff0, 0x16ff1,), # (nil) ..(nil) + (0x17000, 0x187f7,), # (nil) ..(nil) + (0x18800, 0x18cd5,), # Tangut Component-001 ..(nil) + (0x18d00, 0x18d08,), # (nil) ..(nil) + (0x1b000, 0x1b11e,), # Katakana Letter Archaic ..Hentaigana Letter N-mu-m + (0x1b150, 0x1b152,), # Hiragana Letter Small Wi..Hiragana Letter Small Wo + (0x1b164, 0x1b167,), # Katakana Letter Small Wi..Katakana Letter Small N + (0x1b170, 0x1b2fb,), # Nushu Character-1b170 ..Nushu Character-1b2fb + (0x1f004, 0x1f004,), # Mahjong Tile Red Dragon ..Mahjong Tile Red Dragon + (0x1f0cf, 0x1f0cf,), # Playing Card Black Joker..Playing Card Black Joker + (0x1f18e, 0x1f18e,), # Negative Squared Ab ..Negative Squared Ab + (0x1f191, 0x1f19a,), # Squared Cl ..Squared Vs + (0x1f200, 0x1f202,), # Square Hiragana Hoka ..Squared Katakana Sa + (0x1f210, 0x1f23b,), # Squared Cjk Unified Ideo..Squared Cjk Unified Ideo + (0x1f240, 0x1f248,), # Tortoise Shell Bracketed..Tortoise Shell Bracketed + (0x1f250, 0x1f251,), # Circled Ideograph Advant..Circled Ideograph Accept + (0x1f260, 0x1f265,), # Rounded Symbol For Fu ..Rounded Symbol For Cai + (0x1f300, 0x1f320,), # Cyclone ..Shooting Star + (0x1f32d, 0x1f335,), # Hot Dog ..Cactus + (0x1f337, 0x1f37c,), # Tulip ..Baby Bottle + (0x1f37e, 0x1f393,), # Bottle With Popping Cork..Graduation Cap + (0x1f3a0, 0x1f3ca,), # Carousel Horse ..Swimmer + (0x1f3cf, 0x1f3d3,), # Cricket Bat And Ball ..Table Tennis Paddle And + (0x1f3e0, 0x1f3f0,), # House Building ..European Castle + (0x1f3f4, 0x1f3f4,), # Waving Black Flag ..Waving Black Flag + (0x1f3f8, 0x1f43e,), # Badminton Racquet And Sh..Paw Prints + (0x1f440, 0x1f440,), # Eyes ..Eyes + (0x1f442, 0x1f4fc,), # Ear ..Videocassette + (0x1f4ff, 0x1f53d,), # Prayer Beads ..Down-pointing Small Red + (0x1f54b, 0x1f54e,), # Kaaba ..Menorah With Nine Branch + (0x1f550, 0x1f567,), # Clock Face One Oclock ..Clock Face Twelve-thirty + (0x1f57a, 0x1f57a,), # Man Dancing ..Man Dancing + (0x1f595, 0x1f596,), # Reversed Hand With Middl..Raised Hand With Part Be + (0x1f5a4, 0x1f5a4,), # Black Heart ..Black Heart + (0x1f5fb, 0x1f64f,), # Mount Fuji ..Person With Folded Hands + (0x1f680, 0x1f6c5,), # Rocket ..Left Luggage + (0x1f6cc, 0x1f6cc,), # Sleeping Accommodation ..Sleeping Accommodation + (0x1f6d0, 0x1f6d2,), # Place Of Worship ..Shopping Trolley + (0x1f6d5, 0x1f6d7,), # Hindu Temple ..(nil) + (0x1f6eb, 0x1f6ec,), # Airplane Departure ..Airplane Arriving + (0x1f6f4, 0x1f6fc,), # Scooter ..(nil) + (0x1f7e0, 0x1f7eb,), # Large Orange Circle ..Large Brown Square + (0x1f90c, 0x1f93a,), # (nil) ..Fencer + (0x1f93c, 0x1f945,), # Wrestlers ..Goal Net + (0x1f947, 0x1f978,), # First Place Medal ..(nil) + (0x1f97a, 0x1f9cb,), # Face With Pleading Eyes ..(nil) + (0x1f9cd, 0x1f9ff,), # Standing Person ..Nazar Amulet + (0x1fa70, 0x1fa74,), # Ballet Shoes ..(nil) + (0x1fa78, 0x1fa7a,), # Drop Of Blood ..Stethoscope + (0x1fa80, 0x1fa86,), # Yo-yo ..(nil) + (0x1fa90, 0x1faa8,), # Ringed Planet ..(nil) + (0x1fab0, 0x1fab6,), # (nil) ..(nil) + (0x1fac0, 0x1fac2,), # (nil) ..(nil) + (0x1fad0, 0x1fad6,), # (nil) ..(nil) + (0x20000, 0x2fffd,), # Cjk Unified Ideograph-20..(nil) + (0x30000, 0x3fffd,), # (nil) ..(nil) + ), +} diff --git a/.venv/lib/python3.8/site-packages/wcwidth/table_zero.py b/.venv/lib/python3.8/site-packages/wcwidth/table_zero.py new file mode 100644 index 00000000..ab5150f5 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/wcwidth/table_zero.py @@ -0,0 +1,3910 @@ +"""Zero_Width table, created by bin/update-tables.py.""" +# Generated: 2020-06-23T16:03:21.187024 +ZERO_WIDTH = { + '4.1.0': ( + # Source: DerivedGeneralCategory-4.1.0.txt + # Date: 2005-02-26, 02:35:50 GMT [MD] + # + (0x00300, 0x0036f,), # Combining Grave Accent ..Combining Latin Small Le + (0x00483, 0x00486,), # Combining Cyrillic Titlo..Combining Cyrillic Psili + (0x00488, 0x00489,), # Combining Cyrillic Hundr..Combining Cyrillic Milli + (0x00591, 0x005b9,), # Hebrew Accent Etnahta ..Hebrew Point Holam + (0x005bb, 0x005bd,), # Hebrew Point Qubuts ..Hebrew Point Meteg + (0x005bf, 0x005bf,), # Hebrew Point Rafe ..Hebrew Point Rafe + (0x005c1, 0x005c2,), # Hebrew Point Shin Dot ..Hebrew Point Sin Dot + (0x005c4, 0x005c5,), # Hebrew Mark Upper Dot ..Hebrew Mark Lower Dot + (0x005c7, 0x005c7,), # Hebrew Point Qamats Qata..Hebrew Point Qamats Qata + (0x00610, 0x00615,), # Arabic Sign Sallallahou ..Arabic Small High Tah + (0x0064b, 0x0065e,), # Arabic Fathatan ..Arabic Fatha With Two Do + (0x00670, 0x00670,), # Arabic Letter Superscrip..Arabic Letter Superscrip + (0x006d6, 0x006dc,), # Arabic Small High Ligatu..Arabic Small High Seen + (0x006de, 0x006e4,), # Arabic Start Of Rub El H..Arabic Small High Madda + (0x006e7, 0x006e8,), # Arabic Small High Yeh ..Arabic Small High Noon + (0x006ea, 0x006ed,), # Arabic Empty Centre Low ..Arabic Small Low Meem + (0x00711, 0x00711,), # Syriac Letter Superscrip..Syriac Letter Superscrip + (0x00730, 0x0074a,), # Syriac Pthaha Above ..Syriac Barrekh + (0x007a6, 0x007b0,), # Thaana Abafili ..Thaana Sukun + (0x00901, 0x00902,), # Devanagari Sign Candrabi..Devanagari Sign Anusvara + (0x0093c, 0x0093c,), # Devanagari Sign Nukta ..Devanagari Sign Nukta + (0x00941, 0x00948,), # Devanagari Vowel Sign U ..Devanagari Vowel Sign Ai + (0x0094d, 0x0094d,), # Devanagari Sign Virama ..Devanagari Sign Virama + (0x00951, 0x00954,), # Devanagari Stress Sign U..Devanagari Acute Accent + (0x00962, 0x00963,), # Devanagari Vowel Sign Vo..Devanagari Vowel Sign Vo + (0x00981, 0x00981,), # Bengali Sign Candrabindu..Bengali Sign Candrabindu + (0x009bc, 0x009bc,), # Bengali Sign Nukta ..Bengali Sign Nukta + (0x009c1, 0x009c4,), # Bengali Vowel Sign U ..Bengali Vowel Sign Vocal + (0x009cd, 0x009cd,), # Bengali Sign Virama ..Bengali Sign Virama + (0x009e2, 0x009e3,), # Bengali Vowel Sign Vocal..Bengali Vowel Sign Vocal + (0x00a01, 0x00a02,), # Gurmukhi Sign Adak Bindi..Gurmukhi Sign Bindi + (0x00a3c, 0x00a3c,), # Gurmukhi Sign Nukta ..Gurmukhi Sign Nukta + (0x00a41, 0x00a42,), # Gurmukhi Vowel Sign U ..Gurmukhi Vowel Sign Uu + (0x00a47, 0x00a48,), # Gurmukhi Vowel Sign Ee ..Gurmukhi Vowel Sign Ai + (0x00a4b, 0x00a4d,), # Gurmukhi Vowel Sign Oo ..Gurmukhi Sign Virama + (0x00a70, 0x00a71,), # Gurmukhi Tippi ..Gurmukhi Addak + (0x00a81, 0x00a82,), # Gujarati Sign Candrabind..Gujarati Sign Anusvara + (0x00abc, 0x00abc,), # Gujarati Sign Nukta ..Gujarati Sign Nukta + (0x00ac1, 0x00ac5,), # Gujarati Vowel Sign U ..Gujarati Vowel Sign Cand + (0x00ac7, 0x00ac8,), # Gujarati Vowel Sign E ..Gujarati Vowel Sign Ai + (0x00acd, 0x00acd,), # Gujarati Sign Virama ..Gujarati Sign Virama + (0x00ae2, 0x00ae3,), # Gujarati Vowel Sign Voca..Gujarati Vowel Sign Voca + (0x00b01, 0x00b01,), # Oriya Sign Candrabindu ..Oriya Sign Candrabindu + (0x00b3c, 0x00b3c,), # Oriya Sign Nukta ..Oriya Sign Nukta + (0x00b3f, 0x00b3f,), # Oriya Vowel Sign I ..Oriya Vowel Sign I + (0x00b41, 0x00b43,), # Oriya Vowel Sign U ..Oriya Vowel Sign Vocalic + (0x00b4d, 0x00b4d,), # Oriya Sign Virama ..Oriya Sign Virama + (0x00b56, 0x00b56,), # Oriya Ai Length Mark ..Oriya Ai Length Mark + (0x00b82, 0x00b82,), # Tamil Sign Anusvara ..Tamil Sign Anusvara + (0x00bc0, 0x00bc0,), # Tamil Vowel Sign Ii ..Tamil Vowel Sign Ii + (0x00bcd, 0x00bcd,), # Tamil Sign Virama ..Tamil Sign Virama + (0x00c3e, 0x00c40,), # Telugu Vowel Sign Aa ..Telugu Vowel Sign Ii + (0x00c46, 0x00c48,), # Telugu Vowel Sign E ..Telugu Vowel Sign Ai + (0x00c4a, 0x00c4d,), # Telugu Vowel Sign O ..Telugu Sign Virama + (0x00c55, 0x00c56,), # Telugu Length Mark ..Telugu Ai Length Mark + (0x00cbc, 0x00cbc,), # Kannada Sign Nukta ..Kannada Sign Nukta + (0x00cbf, 0x00cbf,), # Kannada Vowel Sign I ..Kannada Vowel Sign I + (0x00cc6, 0x00cc6,), # Kannada Vowel Sign E ..Kannada Vowel Sign E + (0x00ccc, 0x00ccd,), # Kannada Vowel Sign Au ..Kannada Sign Virama + (0x00d41, 0x00d43,), # Malayalam Vowel Sign U ..Malayalam Vowel Sign Voc + (0x00d4d, 0x00d4d,), # Malayalam Sign Virama ..Malayalam Sign Virama + (0x00dca, 0x00dca,), # Sinhala Sign Al-lakuna ..Sinhala Sign Al-lakuna + (0x00dd2, 0x00dd4,), # Sinhala Vowel Sign Ketti..Sinhala Vowel Sign Ketti + (0x00dd6, 0x00dd6,), # Sinhala Vowel Sign Diga ..Sinhala Vowel Sign Diga + (0x00e31, 0x00e31,), # Thai Character Mai Han-a..Thai Character Mai Han-a + (0x00e34, 0x00e3a,), # Thai Character Sara I ..Thai Character Phinthu + (0x00e47, 0x00e4e,), # Thai Character Maitaikhu..Thai Character Yamakkan + (0x00eb1, 0x00eb1,), # Lao Vowel Sign Mai Kan ..Lao Vowel Sign Mai Kan + (0x00eb4, 0x00eb9,), # Lao Vowel Sign I ..Lao Vowel Sign Uu + (0x00ebb, 0x00ebc,), # Lao Vowel Sign Mai Kon ..Lao Semivowel Sign Lo + (0x00ec8, 0x00ecd,), # Lao Tone Mai Ek ..Lao Niggahita + (0x00f18, 0x00f19,), # Tibetan Astrological Sig..Tibetan Astrological Sig + (0x00f35, 0x00f35,), # Tibetan Mark Ngas Bzung ..Tibetan Mark Ngas Bzung + (0x00f37, 0x00f37,), # Tibetan Mark Ngas Bzung ..Tibetan Mark Ngas Bzung + (0x00f39, 0x00f39,), # Tibetan Mark Tsa -phru ..Tibetan Mark Tsa -phru + (0x00f71, 0x00f7e,), # Tibetan Vowel Sign Aa ..Tibetan Sign Rjes Su Nga + (0x00f80, 0x00f84,), # Tibetan Vowel Sign Rever..Tibetan Mark Halanta + (0x00f86, 0x00f87,), # Tibetan Sign Lci Rtags ..Tibetan Sign Yang Rtags + (0x00f90, 0x00f97,), # Tibetan Subjoined Letter..Tibetan Subjoined Letter + (0x00f99, 0x00fbc,), # Tibetan Subjoined Letter..Tibetan Subjoined Letter + (0x00fc6, 0x00fc6,), # Tibetan Symbol Padma Gda..Tibetan Symbol Padma Gda + (0x0102d, 0x01030,), # Myanmar Vowel Sign I ..Myanmar Vowel Sign Uu + (0x01032, 0x01032,), # Myanmar Vowel Sign Ai ..Myanmar Vowel Sign Ai + (0x01036, 0x01037,), # Myanmar Sign Anusvara ..Myanmar Sign Dot Below + (0x01039, 0x01039,), # Myanmar Sign Virama ..Myanmar Sign Virama + (0x01058, 0x01059,), # Myanmar Vowel Sign Vocal..Myanmar Vowel Sign Vocal + (0x0135f, 0x0135f,), # Ethiopic Combining Gemin..Ethiopic Combining Gemin + (0x01712, 0x01714,), # Tagalog Vowel Sign I ..Tagalog Sign Virama + (0x01732, 0x01734,), # Hanunoo Vowel Sign I ..Hanunoo Sign Pamudpod + (0x01752, 0x01753,), # Buhid Vowel Sign I ..Buhid Vowel Sign U + (0x01772, 0x01773,), # Tagbanwa Vowel Sign I ..Tagbanwa Vowel Sign U + (0x017b7, 0x017bd,), # Khmer Vowel Sign I ..Khmer Vowel Sign Ua + (0x017c6, 0x017c6,), # Khmer Sign Nikahit ..Khmer Sign Nikahit + (0x017c9, 0x017d3,), # Khmer Sign Muusikatoan ..Khmer Sign Bathamasat + (0x017dd, 0x017dd,), # Khmer Sign Atthacan ..Khmer Sign Atthacan + (0x0180b, 0x0180d,), # Mongolian Free Variation..Mongolian Free Variation + (0x018a9, 0x018a9,), # Mongolian Letter Ali Gal..Mongolian Letter Ali Gal + (0x01920, 0x01922,), # Limbu Vowel Sign A ..Limbu Vowel Sign U + (0x01927, 0x01928,), # Limbu Vowel Sign E ..Limbu Vowel Sign O + (0x01932, 0x01932,), # Limbu Small Letter Anusv..Limbu Small Letter Anusv + (0x01939, 0x0193b,), # Limbu Sign Mukphreng ..Limbu Sign Sa-i + (0x01a17, 0x01a18,), # Buginese Vowel Sign I ..Buginese Vowel Sign U + (0x01dc0, 0x01dc3,), # Combining Dotted Grave A..Combining Suspension Mar + (0x020d0, 0x020eb,), # Combining Left Harpoon A..Combining Long Double So + (0x0302a, 0x0302f,), # Ideographic Level Tone M..Hangul Double Dot Tone M + (0x03099, 0x0309a,), # Combining Katakana-hirag..Combining Katakana-hirag + (0x0a806, 0x0a806,), # Syloti Nagri Sign Hasant..Syloti Nagri Sign Hasant + (0x0a80b, 0x0a80b,), # Syloti Nagri Sign Anusva..Syloti Nagri Sign Anusva + (0x0a825, 0x0a826,), # Syloti Nagri Vowel Sign ..Syloti Nagri Vowel Sign + (0x0fb1e, 0x0fb1e,), # Hebrew Point Judeo-spani..Hebrew Point Judeo-spani + (0x0fe00, 0x0fe0f,), # Variation Selector-1 ..Variation Selector-16 + (0x0fe20, 0x0fe23,), # Combining Ligature Left ..Combining Double Tilde R + (0x10a01, 0x10a03,), # Kharoshthi Vowel Sign I ..Kharoshthi Vowel Sign Vo + (0x10a05, 0x10a06,), # Kharoshthi Vowel Sign E ..Kharoshthi Vowel Sign O + (0x10a0c, 0x10a0f,), # Kharoshthi Vowel Length ..Kharoshthi Sign Visarga + (0x10a38, 0x10a3a,), # Kharoshthi Sign Bar Abov..Kharoshthi Sign Dot Belo + (0x10a3f, 0x10a3f,), # Kharoshthi Virama ..Kharoshthi Virama + (0x1d167, 0x1d169,), # Musical Symbol Combining..Musical Symbol Combining + (0x1d17b, 0x1d182,), # Musical Symbol Combining..Musical Symbol Combining + (0x1d185, 0x1d18b,), # Musical Symbol Combining..Musical Symbol Combining + (0x1d1aa, 0x1d1ad,), # Musical Symbol Combining..Musical Symbol Combining + (0x1d242, 0x1d244,), # Combining Greek Musical ..Combining Greek Musical + (0xe0100, 0xe01ef,), # Variation Selector-17 ..Variation Selector-256 + ), + '5.0.0': ( + # Source: DerivedGeneralCategory-5.0.0.txt + # Date: 2006-02-27, 23:41:27 GMT [MD] + # + (0x00300, 0x0036f,), # Combining Grave Accent ..Combining Latin Small Le + (0x00483, 0x00486,), # Combining Cyrillic Titlo..Combining Cyrillic Psili + (0x00488, 0x00489,), # Combining Cyrillic Hundr..Combining Cyrillic Milli + (0x00591, 0x005bd,), # Hebrew Accent Etnahta ..Hebrew Point Meteg + (0x005bf, 0x005bf,), # Hebrew Point Rafe ..Hebrew Point Rafe + (0x005c1, 0x005c2,), # Hebrew Point Shin Dot ..Hebrew Point Sin Dot + (0x005c4, 0x005c5,), # Hebrew Mark Upper Dot ..Hebrew Mark Lower Dot + (0x005c7, 0x005c7,), # Hebrew Point Qamats Qata..Hebrew Point Qamats Qata + (0x00610, 0x00615,), # Arabic Sign Sallallahou ..Arabic Small High Tah + (0x0064b, 0x0065e,), # Arabic Fathatan ..Arabic Fatha With Two Do + (0x00670, 0x00670,), # Arabic Letter Superscrip..Arabic Letter Superscrip + (0x006d6, 0x006dc,), # Arabic Small High Ligatu..Arabic Small High Seen + (0x006de, 0x006e4,), # Arabic Start Of Rub El H..Arabic Small High Madda + (0x006e7, 0x006e8,), # Arabic Small High Yeh ..Arabic Small High Noon + (0x006ea, 0x006ed,), # Arabic Empty Centre Low ..Arabic Small Low Meem + (0x00711, 0x00711,), # Syriac Letter Superscrip..Syriac Letter Superscrip + (0x00730, 0x0074a,), # Syriac Pthaha Above ..Syriac Barrekh + (0x007a6, 0x007b0,), # Thaana Abafili ..Thaana Sukun + (0x007eb, 0x007f3,), # Nko Combining Short High..Nko Combining Double Dot + (0x00901, 0x00902,), # Devanagari Sign Candrabi..Devanagari Sign Anusvara + (0x0093c, 0x0093c,), # Devanagari Sign Nukta ..Devanagari Sign Nukta + (0x00941, 0x00948,), # Devanagari Vowel Sign U ..Devanagari Vowel Sign Ai + (0x0094d, 0x0094d,), # Devanagari Sign Virama ..Devanagari Sign Virama + (0x00951, 0x00954,), # Devanagari Stress Sign U..Devanagari Acute Accent + (0x00962, 0x00963,), # Devanagari Vowel Sign Vo..Devanagari Vowel Sign Vo + (0x00981, 0x00981,), # Bengali Sign Candrabindu..Bengali Sign Candrabindu + (0x009bc, 0x009bc,), # Bengali Sign Nukta ..Bengali Sign Nukta + (0x009c1, 0x009c4,), # Bengali Vowel Sign U ..Bengali Vowel Sign Vocal + (0x009cd, 0x009cd,), # Bengali Sign Virama ..Bengali Sign Virama + (0x009e2, 0x009e3,), # Bengali Vowel Sign Vocal..Bengali Vowel Sign Vocal + (0x00a01, 0x00a02,), # Gurmukhi Sign Adak Bindi..Gurmukhi Sign Bindi + (0x00a3c, 0x00a3c,), # Gurmukhi Sign Nukta ..Gurmukhi Sign Nukta + (0x00a41, 0x00a42,), # Gurmukhi Vowel Sign U ..Gurmukhi Vowel Sign Uu + (0x00a47, 0x00a48,), # Gurmukhi Vowel Sign Ee ..Gurmukhi Vowel Sign Ai + (0x00a4b, 0x00a4d,), # Gurmukhi Vowel Sign Oo ..Gurmukhi Sign Virama + (0x00a70, 0x00a71,), # Gurmukhi Tippi ..Gurmukhi Addak + (0x00a81, 0x00a82,), # Gujarati Sign Candrabind..Gujarati Sign Anusvara + (0x00abc, 0x00abc,), # Gujarati Sign Nukta ..Gujarati Sign Nukta + (0x00ac1, 0x00ac5,), # Gujarati Vowel Sign U ..Gujarati Vowel Sign Cand + (0x00ac7, 0x00ac8,), # Gujarati Vowel Sign E ..Gujarati Vowel Sign Ai + (0x00acd, 0x00acd,), # Gujarati Sign Virama ..Gujarati Sign Virama + (0x00ae2, 0x00ae3,), # Gujarati Vowel Sign Voca..Gujarati Vowel Sign Voca + (0x00b01, 0x00b01,), # Oriya Sign Candrabindu ..Oriya Sign Candrabindu + (0x00b3c, 0x00b3c,), # Oriya Sign Nukta ..Oriya Sign Nukta + (0x00b3f, 0x00b3f,), # Oriya Vowel Sign I ..Oriya Vowel Sign I + (0x00b41, 0x00b43,), # Oriya Vowel Sign U ..Oriya Vowel Sign Vocalic + (0x00b4d, 0x00b4d,), # Oriya Sign Virama ..Oriya Sign Virama + (0x00b56, 0x00b56,), # Oriya Ai Length Mark ..Oriya Ai Length Mark + (0x00b82, 0x00b82,), # Tamil Sign Anusvara ..Tamil Sign Anusvara + (0x00bc0, 0x00bc0,), # Tamil Vowel Sign Ii ..Tamil Vowel Sign Ii + (0x00bcd, 0x00bcd,), # Tamil Sign Virama ..Tamil Sign Virama + (0x00c3e, 0x00c40,), # Telugu Vowel Sign Aa ..Telugu Vowel Sign Ii + (0x00c46, 0x00c48,), # Telugu Vowel Sign E ..Telugu Vowel Sign Ai + (0x00c4a, 0x00c4d,), # Telugu Vowel Sign O ..Telugu Sign Virama + (0x00c55, 0x00c56,), # Telugu Length Mark ..Telugu Ai Length Mark + (0x00cbc, 0x00cbc,), # Kannada Sign Nukta ..Kannada Sign Nukta + (0x00cbf, 0x00cbf,), # Kannada Vowel Sign I ..Kannada Vowel Sign I + (0x00cc6, 0x00cc6,), # Kannada Vowel Sign E ..Kannada Vowel Sign E + (0x00ccc, 0x00ccd,), # Kannada Vowel Sign Au ..Kannada Sign Virama + (0x00ce2, 0x00ce3,), # Kannada Vowel Sign Vocal..Kannada Vowel Sign Vocal + (0x00d41, 0x00d43,), # Malayalam Vowel Sign U ..Malayalam Vowel Sign Voc + (0x00d4d, 0x00d4d,), # Malayalam Sign Virama ..Malayalam Sign Virama + (0x00dca, 0x00dca,), # Sinhala Sign Al-lakuna ..Sinhala Sign Al-lakuna + (0x00dd2, 0x00dd4,), # Sinhala Vowel Sign Ketti..Sinhala Vowel Sign Ketti + (0x00dd6, 0x00dd6,), # Sinhala Vowel Sign Diga ..Sinhala Vowel Sign Diga + (0x00e31, 0x00e31,), # Thai Character Mai Han-a..Thai Character Mai Han-a + (0x00e34, 0x00e3a,), # Thai Character Sara I ..Thai Character Phinthu + (0x00e47, 0x00e4e,), # Thai Character Maitaikhu..Thai Character Yamakkan + (0x00eb1, 0x00eb1,), # Lao Vowel Sign Mai Kan ..Lao Vowel Sign Mai Kan + (0x00eb4, 0x00eb9,), # Lao Vowel Sign I ..Lao Vowel Sign Uu + (0x00ebb, 0x00ebc,), # Lao Vowel Sign Mai Kon ..Lao Semivowel Sign Lo + (0x00ec8, 0x00ecd,), # Lao Tone Mai Ek ..Lao Niggahita + (0x00f18, 0x00f19,), # Tibetan Astrological Sig..Tibetan Astrological Sig + (0x00f35, 0x00f35,), # Tibetan Mark Ngas Bzung ..Tibetan Mark Ngas Bzung + (0x00f37, 0x00f37,), # Tibetan Mark Ngas Bzung ..Tibetan Mark Ngas Bzung + (0x00f39, 0x00f39,), # Tibetan Mark Tsa -phru ..Tibetan Mark Tsa -phru + (0x00f71, 0x00f7e,), # Tibetan Vowel Sign Aa ..Tibetan Sign Rjes Su Nga + (0x00f80, 0x00f84,), # Tibetan Vowel Sign Rever..Tibetan Mark Halanta + (0x00f86, 0x00f87,), # Tibetan Sign Lci Rtags ..Tibetan Sign Yang Rtags + (0x00f90, 0x00f97,), # Tibetan Subjoined Letter..Tibetan Subjoined Letter + (0x00f99, 0x00fbc,), # Tibetan Subjoined Letter..Tibetan Subjoined Letter + (0x00fc6, 0x00fc6,), # Tibetan Symbol Padma Gda..Tibetan Symbol Padma Gda + (0x0102d, 0x01030,), # Myanmar Vowel Sign I ..Myanmar Vowel Sign Uu + (0x01032, 0x01032,), # Myanmar Vowel Sign Ai ..Myanmar Vowel Sign Ai + (0x01036, 0x01037,), # Myanmar Sign Anusvara ..Myanmar Sign Dot Below + (0x01039, 0x01039,), # Myanmar Sign Virama ..Myanmar Sign Virama + (0x01058, 0x01059,), # Myanmar Vowel Sign Vocal..Myanmar Vowel Sign Vocal + (0x0135f, 0x0135f,), # Ethiopic Combining Gemin..Ethiopic Combining Gemin + (0x01712, 0x01714,), # Tagalog Vowel Sign I ..Tagalog Sign Virama + (0x01732, 0x01734,), # Hanunoo Vowel Sign I ..Hanunoo Sign Pamudpod + (0x01752, 0x01753,), # Buhid Vowel Sign I ..Buhid Vowel Sign U + (0x01772, 0x01773,), # Tagbanwa Vowel Sign I ..Tagbanwa Vowel Sign U + (0x017b7, 0x017bd,), # Khmer Vowel Sign I ..Khmer Vowel Sign Ua + (0x017c6, 0x017c6,), # Khmer Sign Nikahit ..Khmer Sign Nikahit + (0x017c9, 0x017d3,), # Khmer Sign Muusikatoan ..Khmer Sign Bathamasat + (0x017dd, 0x017dd,), # Khmer Sign Atthacan ..Khmer Sign Atthacan + (0x0180b, 0x0180d,), # Mongolian Free Variation..Mongolian Free Variation + (0x018a9, 0x018a9,), # Mongolian Letter Ali Gal..Mongolian Letter Ali Gal + (0x01920, 0x01922,), # Limbu Vowel Sign A ..Limbu Vowel Sign U + (0x01927, 0x01928,), # Limbu Vowel Sign E ..Limbu Vowel Sign O + (0x01932, 0x01932,), # Limbu Small Letter Anusv..Limbu Small Letter Anusv + (0x01939, 0x0193b,), # Limbu Sign Mukphreng ..Limbu Sign Sa-i + (0x01a17, 0x01a18,), # Buginese Vowel Sign I ..Buginese Vowel Sign U + (0x01b00, 0x01b03,), # Balinese Sign Ulu Ricem ..Balinese Sign Surang + (0x01b34, 0x01b34,), # Balinese Sign Rerekan ..Balinese Sign Rerekan + (0x01b36, 0x01b3a,), # Balinese Vowel Sign Ulu ..Balinese Vowel Sign Ra R + (0x01b3c, 0x01b3c,), # Balinese Vowel Sign La L..Balinese Vowel Sign La L + (0x01b42, 0x01b42,), # Balinese Vowel Sign Pepe..Balinese Vowel Sign Pepe + (0x01b6b, 0x01b73,), # Balinese Musical Symbol ..Balinese Musical Symbol + (0x01dc0, 0x01dca,), # Combining Dotted Grave A..Combining Latin Small Le + (0x01dfe, 0x01dff,), # Combining Left Arrowhead..Combining Right Arrowhea + (0x020d0, 0x020ef,), # Combining Left Harpoon A..Combining Right Arrow Be + (0x0302a, 0x0302f,), # Ideographic Level Tone M..Hangul Double Dot Tone M + (0x03099, 0x0309a,), # Combining Katakana-hirag..Combining Katakana-hirag + (0x0a806, 0x0a806,), # Syloti Nagri Sign Hasant..Syloti Nagri Sign Hasant + (0x0a80b, 0x0a80b,), # Syloti Nagri Sign Anusva..Syloti Nagri Sign Anusva + (0x0a825, 0x0a826,), # Syloti Nagri Vowel Sign ..Syloti Nagri Vowel Sign + (0x0fb1e, 0x0fb1e,), # Hebrew Point Judeo-spani..Hebrew Point Judeo-spani + (0x0fe00, 0x0fe0f,), # Variation Selector-1 ..Variation Selector-16 + (0x0fe20, 0x0fe23,), # Combining Ligature Left ..Combining Double Tilde R + (0x10a01, 0x10a03,), # Kharoshthi Vowel Sign I ..Kharoshthi Vowel Sign Vo + (0x10a05, 0x10a06,), # Kharoshthi Vowel Sign E ..Kharoshthi Vowel Sign O + (0x10a0c, 0x10a0f,), # Kharoshthi Vowel Length ..Kharoshthi Sign Visarga + (0x10a38, 0x10a3a,), # Kharoshthi Sign Bar Abov..Kharoshthi Sign Dot Belo + (0x10a3f, 0x10a3f,), # Kharoshthi Virama ..Kharoshthi Virama + (0x1d167, 0x1d169,), # Musical Symbol Combining..Musical Symbol Combining + (0x1d17b, 0x1d182,), # Musical Symbol Combining..Musical Symbol Combining + (0x1d185, 0x1d18b,), # Musical Symbol Combining..Musical Symbol Combining + (0x1d1aa, 0x1d1ad,), # Musical Symbol Combining..Musical Symbol Combining + (0x1d242, 0x1d244,), # Combining Greek Musical ..Combining Greek Musical + (0xe0100, 0xe01ef,), # Variation Selector-17 ..Variation Selector-256 + ), + '5.1.0': ( + # Source: DerivedGeneralCategory-5.1.0.txt + # Date: 2008-03-20, 17:54:57 GMT [MD] + # + (0x00300, 0x0036f,), # Combining Grave Accent ..Combining Latin Small Le + (0x00483, 0x00489,), # Combining Cyrillic Titlo..Combining Cyrillic Milli + (0x00591, 0x005bd,), # Hebrew Accent Etnahta ..Hebrew Point Meteg + (0x005bf, 0x005bf,), # Hebrew Point Rafe ..Hebrew Point Rafe + (0x005c1, 0x005c2,), # Hebrew Point Shin Dot ..Hebrew Point Sin Dot + (0x005c4, 0x005c5,), # Hebrew Mark Upper Dot ..Hebrew Mark Lower Dot + (0x005c7, 0x005c7,), # Hebrew Point Qamats Qata..Hebrew Point Qamats Qata + (0x00610, 0x0061a,), # Arabic Sign Sallallahou ..Arabic Small Kasra + (0x0064b, 0x0065e,), # Arabic Fathatan ..Arabic Fatha With Two Do + (0x00670, 0x00670,), # Arabic Letter Superscrip..Arabic Letter Superscrip + (0x006d6, 0x006dc,), # Arabic Small High Ligatu..Arabic Small High Seen + (0x006de, 0x006e4,), # Arabic Start Of Rub El H..Arabic Small High Madda + (0x006e7, 0x006e8,), # Arabic Small High Yeh ..Arabic Small High Noon + (0x006ea, 0x006ed,), # Arabic Empty Centre Low ..Arabic Small Low Meem + (0x00711, 0x00711,), # Syriac Letter Superscrip..Syriac Letter Superscrip + (0x00730, 0x0074a,), # Syriac Pthaha Above ..Syriac Barrekh + (0x007a6, 0x007b0,), # Thaana Abafili ..Thaana Sukun + (0x007eb, 0x007f3,), # Nko Combining Short High..Nko Combining Double Dot + (0x00901, 0x00902,), # Devanagari Sign Candrabi..Devanagari Sign Anusvara + (0x0093c, 0x0093c,), # Devanagari Sign Nukta ..Devanagari Sign Nukta + (0x00941, 0x00948,), # Devanagari Vowel Sign U ..Devanagari Vowel Sign Ai + (0x0094d, 0x0094d,), # Devanagari Sign Virama ..Devanagari Sign Virama + (0x00951, 0x00954,), # Devanagari Stress Sign U..Devanagari Acute Accent + (0x00962, 0x00963,), # Devanagari Vowel Sign Vo..Devanagari Vowel Sign Vo + (0x00981, 0x00981,), # Bengali Sign Candrabindu..Bengali Sign Candrabindu + (0x009bc, 0x009bc,), # Bengali Sign Nukta ..Bengali Sign Nukta + (0x009c1, 0x009c4,), # Bengali Vowel Sign U ..Bengali Vowel Sign Vocal + (0x009cd, 0x009cd,), # Bengali Sign Virama ..Bengali Sign Virama + (0x009e2, 0x009e3,), # Bengali Vowel Sign Vocal..Bengali Vowel Sign Vocal + (0x00a01, 0x00a02,), # Gurmukhi Sign Adak Bindi..Gurmukhi Sign Bindi + (0x00a3c, 0x00a3c,), # Gurmukhi Sign Nukta ..Gurmukhi Sign Nukta + (0x00a41, 0x00a42,), # Gurmukhi Vowel Sign U ..Gurmukhi Vowel Sign Uu + (0x00a47, 0x00a48,), # Gurmukhi Vowel Sign Ee ..Gurmukhi Vowel Sign Ai + (0x00a4b, 0x00a4d,), # Gurmukhi Vowel Sign Oo ..Gurmukhi Sign Virama + (0x00a51, 0x00a51,), # Gurmukhi Sign Udaat ..Gurmukhi Sign Udaat + (0x00a70, 0x00a71,), # Gurmukhi Tippi ..Gurmukhi Addak + (0x00a75, 0x00a75,), # Gurmukhi Sign Yakash ..Gurmukhi Sign Yakash + (0x00a81, 0x00a82,), # Gujarati Sign Candrabind..Gujarati Sign Anusvara + (0x00abc, 0x00abc,), # Gujarati Sign Nukta ..Gujarati Sign Nukta + (0x00ac1, 0x00ac5,), # Gujarati Vowel Sign U ..Gujarati Vowel Sign Cand + (0x00ac7, 0x00ac8,), # Gujarati Vowel Sign E ..Gujarati Vowel Sign Ai + (0x00acd, 0x00acd,), # Gujarati Sign Virama ..Gujarati Sign Virama + (0x00ae2, 0x00ae3,), # Gujarati Vowel Sign Voca..Gujarati Vowel Sign Voca + (0x00b01, 0x00b01,), # Oriya Sign Candrabindu ..Oriya Sign Candrabindu + (0x00b3c, 0x00b3c,), # Oriya Sign Nukta ..Oriya Sign Nukta + (0x00b3f, 0x00b3f,), # Oriya Vowel Sign I ..Oriya Vowel Sign I + (0x00b41, 0x00b44,), # Oriya Vowel Sign U ..Oriya Vowel Sign Vocalic + (0x00b4d, 0x00b4d,), # Oriya Sign Virama ..Oriya Sign Virama + (0x00b56, 0x00b56,), # Oriya Ai Length Mark ..Oriya Ai Length Mark + (0x00b62, 0x00b63,), # Oriya Vowel Sign Vocalic..Oriya Vowel Sign Vocalic + (0x00b82, 0x00b82,), # Tamil Sign Anusvara ..Tamil Sign Anusvara + (0x00bc0, 0x00bc0,), # Tamil Vowel Sign Ii ..Tamil Vowel Sign Ii + (0x00bcd, 0x00bcd,), # Tamil Sign Virama ..Tamil Sign Virama + (0x00c3e, 0x00c40,), # Telugu Vowel Sign Aa ..Telugu Vowel Sign Ii + (0x00c46, 0x00c48,), # Telugu Vowel Sign E ..Telugu Vowel Sign Ai + (0x00c4a, 0x00c4d,), # Telugu Vowel Sign O ..Telugu Sign Virama + (0x00c55, 0x00c56,), # Telugu Length Mark ..Telugu Ai Length Mark + (0x00c62, 0x00c63,), # Telugu Vowel Sign Vocali..Telugu Vowel Sign Vocali + (0x00cbc, 0x00cbc,), # Kannada Sign Nukta ..Kannada Sign Nukta + (0x00cbf, 0x00cbf,), # Kannada Vowel Sign I ..Kannada Vowel Sign I + (0x00cc6, 0x00cc6,), # Kannada Vowel Sign E ..Kannada Vowel Sign E + (0x00ccc, 0x00ccd,), # Kannada Vowel Sign Au ..Kannada Sign Virama + (0x00ce2, 0x00ce3,), # Kannada Vowel Sign Vocal..Kannada Vowel Sign Vocal + (0x00d41, 0x00d44,), # Malayalam Vowel Sign U ..Malayalam Vowel Sign Voc + (0x00d4d, 0x00d4d,), # Malayalam Sign Virama ..Malayalam Sign Virama + (0x00d62, 0x00d63,), # Malayalam Vowel Sign Voc..Malayalam Vowel Sign Voc + (0x00dca, 0x00dca,), # Sinhala Sign Al-lakuna ..Sinhala Sign Al-lakuna + (0x00dd2, 0x00dd4,), # Sinhala Vowel Sign Ketti..Sinhala Vowel Sign Ketti + (0x00dd6, 0x00dd6,), # Sinhala Vowel Sign Diga ..Sinhala Vowel Sign Diga + (0x00e31, 0x00e31,), # Thai Character Mai Han-a..Thai Character Mai Han-a + (0x00e34, 0x00e3a,), # Thai Character Sara I ..Thai Character Phinthu + (0x00e47, 0x00e4e,), # Thai Character Maitaikhu..Thai Character Yamakkan + (0x00eb1, 0x00eb1,), # Lao Vowel Sign Mai Kan ..Lao Vowel Sign Mai Kan + (0x00eb4, 0x00eb9,), # Lao Vowel Sign I ..Lao Vowel Sign Uu + (0x00ebb, 0x00ebc,), # Lao Vowel Sign Mai Kon ..Lao Semivowel Sign Lo + (0x00ec8, 0x00ecd,), # Lao Tone Mai Ek ..Lao Niggahita + (0x00f18, 0x00f19,), # Tibetan Astrological Sig..Tibetan Astrological Sig + (0x00f35, 0x00f35,), # Tibetan Mark Ngas Bzung ..Tibetan Mark Ngas Bzung + (0x00f37, 0x00f37,), # Tibetan Mark Ngas Bzung ..Tibetan Mark Ngas Bzung + (0x00f39, 0x00f39,), # Tibetan Mark Tsa -phru ..Tibetan Mark Tsa -phru + (0x00f71, 0x00f7e,), # Tibetan Vowel Sign Aa ..Tibetan Sign Rjes Su Nga + (0x00f80, 0x00f84,), # Tibetan Vowel Sign Rever..Tibetan Mark Halanta + (0x00f86, 0x00f87,), # Tibetan Sign Lci Rtags ..Tibetan Sign Yang Rtags + (0x00f90, 0x00f97,), # Tibetan Subjoined Letter..Tibetan Subjoined Letter + (0x00f99, 0x00fbc,), # Tibetan Subjoined Letter..Tibetan Subjoined Letter + (0x00fc6, 0x00fc6,), # Tibetan Symbol Padma Gda..Tibetan Symbol Padma Gda + (0x0102d, 0x01030,), # Myanmar Vowel Sign I ..Myanmar Vowel Sign Uu + (0x01032, 0x01037,), # Myanmar Vowel Sign Ai ..Myanmar Sign Dot Below + (0x01039, 0x0103a,), # Myanmar Sign Virama ..Myanmar Sign Asat + (0x0103d, 0x0103e,), # Myanmar Consonant Sign M..Myanmar Consonant Sign M + (0x01058, 0x01059,), # Myanmar Vowel Sign Vocal..Myanmar Vowel Sign Vocal + (0x0105e, 0x01060,), # Myanmar Consonant Sign M..Myanmar Consonant Sign M + (0x01071, 0x01074,), # Myanmar Vowel Sign Geba ..Myanmar Vowel Sign Kayah + (0x01082, 0x01082,), # Myanmar Consonant Sign S..Myanmar Consonant Sign S + (0x01085, 0x01086,), # Myanmar Vowel Sign Shan ..Myanmar Vowel Sign Shan + (0x0108d, 0x0108d,), # Myanmar Sign Shan Counci..Myanmar Sign Shan Counci + (0x0135f, 0x0135f,), # Ethiopic Combining Gemin..Ethiopic Combining Gemin + (0x01712, 0x01714,), # Tagalog Vowel Sign I ..Tagalog Sign Virama + (0x01732, 0x01734,), # Hanunoo Vowel Sign I ..Hanunoo Sign Pamudpod + (0x01752, 0x01753,), # Buhid Vowel Sign I ..Buhid Vowel Sign U + (0x01772, 0x01773,), # Tagbanwa Vowel Sign I ..Tagbanwa Vowel Sign U + (0x017b7, 0x017bd,), # Khmer Vowel Sign I ..Khmer Vowel Sign Ua + (0x017c6, 0x017c6,), # Khmer Sign Nikahit ..Khmer Sign Nikahit + (0x017c9, 0x017d3,), # Khmer Sign Muusikatoan ..Khmer Sign Bathamasat + (0x017dd, 0x017dd,), # Khmer Sign Atthacan ..Khmer Sign Atthacan + (0x0180b, 0x0180d,), # Mongolian Free Variation..Mongolian Free Variation + (0x018a9, 0x018a9,), # Mongolian Letter Ali Gal..Mongolian Letter Ali Gal + (0x01920, 0x01922,), # Limbu Vowel Sign A ..Limbu Vowel Sign U + (0x01927, 0x01928,), # Limbu Vowel Sign E ..Limbu Vowel Sign O + (0x01932, 0x01932,), # Limbu Small Letter Anusv..Limbu Small Letter Anusv + (0x01939, 0x0193b,), # Limbu Sign Mukphreng ..Limbu Sign Sa-i + (0x01a17, 0x01a18,), # Buginese Vowel Sign I ..Buginese Vowel Sign U + (0x01b00, 0x01b03,), # Balinese Sign Ulu Ricem ..Balinese Sign Surang + (0x01b34, 0x01b34,), # Balinese Sign Rerekan ..Balinese Sign Rerekan + (0x01b36, 0x01b3a,), # Balinese Vowel Sign Ulu ..Balinese Vowel Sign Ra R + (0x01b3c, 0x01b3c,), # Balinese Vowel Sign La L..Balinese Vowel Sign La L + (0x01b42, 0x01b42,), # Balinese Vowel Sign Pepe..Balinese Vowel Sign Pepe + (0x01b6b, 0x01b73,), # Balinese Musical Symbol ..Balinese Musical Symbol + (0x01b80, 0x01b81,), # Sundanese Sign Panyecek ..Sundanese Sign Panglayar + (0x01ba2, 0x01ba5,), # Sundanese Consonant Sign..Sundanese Vowel Sign Pan + (0x01ba8, 0x01ba9,), # Sundanese Vowel Sign Pam..Sundanese Vowel Sign Pan + (0x01c2c, 0x01c33,), # Lepcha Vowel Sign E ..Lepcha Consonant Sign T + (0x01c36, 0x01c37,), # Lepcha Sign Ran ..Lepcha Sign Nukta + (0x01dc0, 0x01de6,), # Combining Dotted Grave A..Combining Latin Small Le + (0x01dfe, 0x01dff,), # Combining Left Arrowhead..Combining Right Arrowhea + (0x020d0, 0x020f0,), # Combining Left Harpoon A..Combining Asterisk Above + (0x02de0, 0x02dff,), # Combining Cyrillic Lette..Combining Cyrillic Lette + (0x0302a, 0x0302f,), # Ideographic Level Tone M..Hangul Double Dot Tone M + (0x03099, 0x0309a,), # Combining Katakana-hirag..Combining Katakana-hirag + (0x0a66f, 0x0a672,), # Combining Cyrillic Vzmet..Combining Cyrillic Thous + (0x0a67c, 0x0a67d,), # Combining Cyrillic Kavyk..Combining Cyrillic Payer + (0x0a802, 0x0a802,), # Syloti Nagri Sign Dvisva..Syloti Nagri Sign Dvisva + (0x0a806, 0x0a806,), # Syloti Nagri Sign Hasant..Syloti Nagri Sign Hasant + (0x0a80b, 0x0a80b,), # Syloti Nagri Sign Anusva..Syloti Nagri Sign Anusva + (0x0a825, 0x0a826,), # Syloti Nagri Vowel Sign ..Syloti Nagri Vowel Sign + (0x0a8c4, 0x0a8c4,), # Saurashtra Sign Virama ..Saurashtra Sign Virama + (0x0a926, 0x0a92d,), # Kayah Li Vowel Ue ..Kayah Li Tone Calya Plop + (0x0a947, 0x0a951,), # Rejang Vowel Sign I ..Rejang Consonant Sign R + (0x0aa29, 0x0aa2e,), # Cham Vowel Sign Aa ..Cham Vowel Sign Oe + (0x0aa31, 0x0aa32,), # Cham Vowel Sign Au ..Cham Vowel Sign Ue + (0x0aa35, 0x0aa36,), # Cham Consonant Sign La ..Cham Consonant Sign Wa + (0x0aa43, 0x0aa43,), # Cham Consonant Sign Fina..Cham Consonant Sign Fina + (0x0aa4c, 0x0aa4c,), # Cham Consonant Sign Fina..Cham Consonant Sign Fina + (0x0fb1e, 0x0fb1e,), # Hebrew Point Judeo-spani..Hebrew Point Judeo-spani + (0x0fe00, 0x0fe0f,), # Variation Selector-1 ..Variation Selector-16 + (0x0fe20, 0x0fe26,), # Combining Ligature Left ..Combining Conjoining Mac + (0x101fd, 0x101fd,), # Phaistos Disc Sign Combi..Phaistos Disc Sign Combi + (0x10a01, 0x10a03,), # Kharoshthi Vowel Sign I ..Kharoshthi Vowel Sign Vo + (0x10a05, 0x10a06,), # Kharoshthi Vowel Sign E ..Kharoshthi Vowel Sign O + (0x10a0c, 0x10a0f,), # Kharoshthi Vowel Length ..Kharoshthi Sign Visarga + (0x10a38, 0x10a3a,), # Kharoshthi Sign Bar Abov..Kharoshthi Sign Dot Belo + (0x10a3f, 0x10a3f,), # Kharoshthi Virama ..Kharoshthi Virama + (0x1d167, 0x1d169,), # Musical Symbol Combining..Musical Symbol Combining + (0x1d17b, 0x1d182,), # Musical Symbol Combining..Musical Symbol Combining + (0x1d185, 0x1d18b,), # Musical Symbol Combining..Musical Symbol Combining + (0x1d1aa, 0x1d1ad,), # Musical Symbol Combining..Musical Symbol Combining + (0x1d242, 0x1d244,), # Combining Greek Musical ..Combining Greek Musical + (0xe0100, 0xe01ef,), # Variation Selector-17 ..Variation Selector-256 + ), + '5.2.0': ( + # Source: DerivedGeneralCategory-5.2.0.txt + # Date: 2009-08-22, 04:58:21 GMT [MD] + # + (0x00300, 0x0036f,), # Combining Grave Accent ..Combining Latin Small Le + (0x00483, 0x00489,), # Combining Cyrillic Titlo..Combining Cyrillic Milli + (0x00591, 0x005bd,), # Hebrew Accent Etnahta ..Hebrew Point Meteg + (0x005bf, 0x005bf,), # Hebrew Point Rafe ..Hebrew Point Rafe + (0x005c1, 0x005c2,), # Hebrew Point Shin Dot ..Hebrew Point Sin Dot + (0x005c4, 0x005c5,), # Hebrew Mark Upper Dot ..Hebrew Mark Lower Dot + (0x005c7, 0x005c7,), # Hebrew Point Qamats Qata..Hebrew Point Qamats Qata + (0x00610, 0x0061a,), # Arabic Sign Sallallahou ..Arabic Small Kasra + (0x0064b, 0x0065e,), # Arabic Fathatan ..Arabic Fatha With Two Do + (0x00670, 0x00670,), # Arabic Letter Superscrip..Arabic Letter Superscrip + (0x006d6, 0x006dc,), # Arabic Small High Ligatu..Arabic Small High Seen + (0x006de, 0x006e4,), # Arabic Start Of Rub El H..Arabic Small High Madda + (0x006e7, 0x006e8,), # Arabic Small High Yeh ..Arabic Small High Noon + (0x006ea, 0x006ed,), # Arabic Empty Centre Low ..Arabic Small Low Meem + (0x00711, 0x00711,), # Syriac Letter Superscrip..Syriac Letter Superscrip + (0x00730, 0x0074a,), # Syriac Pthaha Above ..Syriac Barrekh + (0x007a6, 0x007b0,), # Thaana Abafili ..Thaana Sukun + (0x007eb, 0x007f3,), # Nko Combining Short High..Nko Combining Double Dot + (0x00816, 0x00819,), # Samaritan Mark In ..Samaritan Mark Dagesh + (0x0081b, 0x00823,), # Samaritan Mark Epentheti..Samaritan Vowel Sign A + (0x00825, 0x00827,), # Samaritan Vowel Sign Sho..Samaritan Vowel Sign U + (0x00829, 0x0082d,), # Samaritan Vowel Sign Lon..Samaritan Mark Nequdaa + (0x00900, 0x00902,), # Devanagari Sign Inverted..Devanagari Sign Anusvara + (0x0093c, 0x0093c,), # Devanagari Sign Nukta ..Devanagari Sign Nukta + (0x00941, 0x00948,), # Devanagari Vowel Sign U ..Devanagari Vowel Sign Ai + (0x0094d, 0x0094d,), # Devanagari Sign Virama ..Devanagari Sign Virama + (0x00951, 0x00955,), # Devanagari Stress Sign U..Devanagari Vowel Sign Ca + (0x00962, 0x00963,), # Devanagari Vowel Sign Vo..Devanagari Vowel Sign Vo + (0x00981, 0x00981,), # Bengali Sign Candrabindu..Bengali Sign Candrabindu + (0x009bc, 0x009bc,), # Bengali Sign Nukta ..Bengali Sign Nukta + (0x009c1, 0x009c4,), # Bengali Vowel Sign U ..Bengali Vowel Sign Vocal + (0x009cd, 0x009cd,), # Bengali Sign Virama ..Bengali Sign Virama + (0x009e2, 0x009e3,), # Bengali Vowel Sign Vocal..Bengali Vowel Sign Vocal + (0x00a01, 0x00a02,), # Gurmukhi Sign Adak Bindi..Gurmukhi Sign Bindi + (0x00a3c, 0x00a3c,), # Gurmukhi Sign Nukta ..Gurmukhi Sign Nukta + (0x00a41, 0x00a42,), # Gurmukhi Vowel Sign U ..Gurmukhi Vowel Sign Uu + (0x00a47, 0x00a48,), # Gurmukhi Vowel Sign Ee ..Gurmukhi Vowel Sign Ai + (0x00a4b, 0x00a4d,), # Gurmukhi Vowel Sign Oo ..Gurmukhi Sign Virama + (0x00a51, 0x00a51,), # Gurmukhi Sign Udaat ..Gurmukhi Sign Udaat + (0x00a70, 0x00a71,), # Gurmukhi Tippi ..Gurmukhi Addak + (0x00a75, 0x00a75,), # Gurmukhi Sign Yakash ..Gurmukhi Sign Yakash + (0x00a81, 0x00a82,), # Gujarati Sign Candrabind..Gujarati Sign Anusvara + (0x00abc, 0x00abc,), # Gujarati Sign Nukta ..Gujarati Sign Nukta + (0x00ac1, 0x00ac5,), # Gujarati Vowel Sign U ..Gujarati Vowel Sign Cand + (0x00ac7, 0x00ac8,), # Gujarati Vowel Sign E ..Gujarati Vowel Sign Ai + (0x00acd, 0x00acd,), # Gujarati Sign Virama ..Gujarati Sign Virama + (0x00ae2, 0x00ae3,), # Gujarati Vowel Sign Voca..Gujarati Vowel Sign Voca + (0x00b01, 0x00b01,), # Oriya Sign Candrabindu ..Oriya Sign Candrabindu + (0x00b3c, 0x00b3c,), # Oriya Sign Nukta ..Oriya Sign Nukta + (0x00b3f, 0x00b3f,), # Oriya Vowel Sign I ..Oriya Vowel Sign I + (0x00b41, 0x00b44,), # Oriya Vowel Sign U ..Oriya Vowel Sign Vocalic + (0x00b4d, 0x00b4d,), # Oriya Sign Virama ..Oriya Sign Virama + (0x00b56, 0x00b56,), # Oriya Ai Length Mark ..Oriya Ai Length Mark + (0x00b62, 0x00b63,), # Oriya Vowel Sign Vocalic..Oriya Vowel Sign Vocalic + (0x00b82, 0x00b82,), # Tamil Sign Anusvara ..Tamil Sign Anusvara + (0x00bc0, 0x00bc0,), # Tamil Vowel Sign Ii ..Tamil Vowel Sign Ii + (0x00bcd, 0x00bcd,), # Tamil Sign Virama ..Tamil Sign Virama + (0x00c3e, 0x00c40,), # Telugu Vowel Sign Aa ..Telugu Vowel Sign Ii + (0x00c46, 0x00c48,), # Telugu Vowel Sign E ..Telugu Vowel Sign Ai + (0x00c4a, 0x00c4d,), # Telugu Vowel Sign O ..Telugu Sign Virama + (0x00c55, 0x00c56,), # Telugu Length Mark ..Telugu Ai Length Mark + (0x00c62, 0x00c63,), # Telugu Vowel Sign Vocali..Telugu Vowel Sign Vocali + (0x00cbc, 0x00cbc,), # Kannada Sign Nukta ..Kannada Sign Nukta + (0x00cbf, 0x00cbf,), # Kannada Vowel Sign I ..Kannada Vowel Sign I + (0x00cc6, 0x00cc6,), # Kannada Vowel Sign E ..Kannada Vowel Sign E + (0x00ccc, 0x00ccd,), # Kannada Vowel Sign Au ..Kannada Sign Virama + (0x00ce2, 0x00ce3,), # Kannada Vowel Sign Vocal..Kannada Vowel Sign Vocal + (0x00d41, 0x00d44,), # Malayalam Vowel Sign U ..Malayalam Vowel Sign Voc + (0x00d4d, 0x00d4d,), # Malayalam Sign Virama ..Malayalam Sign Virama + (0x00d62, 0x00d63,), # Malayalam Vowel Sign Voc..Malayalam Vowel Sign Voc + (0x00dca, 0x00dca,), # Sinhala Sign Al-lakuna ..Sinhala Sign Al-lakuna + (0x00dd2, 0x00dd4,), # Sinhala Vowel Sign Ketti..Sinhala Vowel Sign Ketti + (0x00dd6, 0x00dd6,), # Sinhala Vowel Sign Diga ..Sinhala Vowel Sign Diga + (0x00e31, 0x00e31,), # Thai Character Mai Han-a..Thai Character Mai Han-a + (0x00e34, 0x00e3a,), # Thai Character Sara I ..Thai Character Phinthu + (0x00e47, 0x00e4e,), # Thai Character Maitaikhu..Thai Character Yamakkan + (0x00eb1, 0x00eb1,), # Lao Vowel Sign Mai Kan ..Lao Vowel Sign Mai Kan + (0x00eb4, 0x00eb9,), # Lao Vowel Sign I ..Lao Vowel Sign Uu + (0x00ebb, 0x00ebc,), # Lao Vowel Sign Mai Kon ..Lao Semivowel Sign Lo + (0x00ec8, 0x00ecd,), # Lao Tone Mai Ek ..Lao Niggahita + (0x00f18, 0x00f19,), # Tibetan Astrological Sig..Tibetan Astrological Sig + (0x00f35, 0x00f35,), # Tibetan Mark Ngas Bzung ..Tibetan Mark Ngas Bzung + (0x00f37, 0x00f37,), # Tibetan Mark Ngas Bzung ..Tibetan Mark Ngas Bzung + (0x00f39, 0x00f39,), # Tibetan Mark Tsa -phru ..Tibetan Mark Tsa -phru + (0x00f71, 0x00f7e,), # Tibetan Vowel Sign Aa ..Tibetan Sign Rjes Su Nga + (0x00f80, 0x00f84,), # Tibetan Vowel Sign Rever..Tibetan Mark Halanta + (0x00f86, 0x00f87,), # Tibetan Sign Lci Rtags ..Tibetan Sign Yang Rtags + (0x00f90, 0x00f97,), # Tibetan Subjoined Letter..Tibetan Subjoined Letter + (0x00f99, 0x00fbc,), # Tibetan Subjoined Letter..Tibetan Subjoined Letter + (0x00fc6, 0x00fc6,), # Tibetan Symbol Padma Gda..Tibetan Symbol Padma Gda + (0x0102d, 0x01030,), # Myanmar Vowel Sign I ..Myanmar Vowel Sign Uu + (0x01032, 0x01037,), # Myanmar Vowel Sign Ai ..Myanmar Sign Dot Below + (0x01039, 0x0103a,), # Myanmar Sign Virama ..Myanmar Sign Asat + (0x0103d, 0x0103e,), # Myanmar Consonant Sign M..Myanmar Consonant Sign M + (0x01058, 0x01059,), # Myanmar Vowel Sign Vocal..Myanmar Vowel Sign Vocal + (0x0105e, 0x01060,), # Myanmar Consonant Sign M..Myanmar Consonant Sign M + (0x01071, 0x01074,), # Myanmar Vowel Sign Geba ..Myanmar Vowel Sign Kayah + (0x01082, 0x01082,), # Myanmar Consonant Sign S..Myanmar Consonant Sign S + (0x01085, 0x01086,), # Myanmar Vowel Sign Shan ..Myanmar Vowel Sign Shan + (0x0108d, 0x0108d,), # Myanmar Sign Shan Counci..Myanmar Sign Shan Counci + (0x0109d, 0x0109d,), # Myanmar Vowel Sign Aiton..Myanmar Vowel Sign Aiton + (0x0135f, 0x0135f,), # Ethiopic Combining Gemin..Ethiopic Combining Gemin + (0x01712, 0x01714,), # Tagalog Vowel Sign I ..Tagalog Sign Virama + (0x01732, 0x01734,), # Hanunoo Vowel Sign I ..Hanunoo Sign Pamudpod + (0x01752, 0x01753,), # Buhid Vowel Sign I ..Buhid Vowel Sign U + (0x01772, 0x01773,), # Tagbanwa Vowel Sign I ..Tagbanwa Vowel Sign U + (0x017b7, 0x017bd,), # Khmer Vowel Sign I ..Khmer Vowel Sign Ua + (0x017c6, 0x017c6,), # Khmer Sign Nikahit ..Khmer Sign Nikahit + (0x017c9, 0x017d3,), # Khmer Sign Muusikatoan ..Khmer Sign Bathamasat + (0x017dd, 0x017dd,), # Khmer Sign Atthacan ..Khmer Sign Atthacan + (0x0180b, 0x0180d,), # Mongolian Free Variation..Mongolian Free Variation + (0x018a9, 0x018a9,), # Mongolian Letter Ali Gal..Mongolian Letter Ali Gal + (0x01920, 0x01922,), # Limbu Vowel Sign A ..Limbu Vowel Sign U + (0x01927, 0x01928,), # Limbu Vowel Sign E ..Limbu Vowel Sign O + (0x01932, 0x01932,), # Limbu Small Letter Anusv..Limbu Small Letter Anusv + (0x01939, 0x0193b,), # Limbu Sign Mukphreng ..Limbu Sign Sa-i + (0x01a17, 0x01a18,), # Buginese Vowel Sign I ..Buginese Vowel Sign U + (0x01a56, 0x01a56,), # Tai Tham Consonant Sign ..Tai Tham Consonant Sign + (0x01a58, 0x01a5e,), # Tai Tham Sign Mai Kang L..Tai Tham Consonant Sign + (0x01a60, 0x01a60,), # Tai Tham Sign Sakot ..Tai Tham Sign Sakot + (0x01a62, 0x01a62,), # Tai Tham Vowel Sign Mai ..Tai Tham Vowel Sign Mai + (0x01a65, 0x01a6c,), # Tai Tham Vowel Sign I ..Tai Tham Vowel Sign Oa B + (0x01a73, 0x01a7c,), # Tai Tham Vowel Sign Oa A..Tai Tham Sign Khuen-lue + (0x01a7f, 0x01a7f,), # Tai Tham Combining Crypt..Tai Tham Combining Crypt + (0x01b00, 0x01b03,), # Balinese Sign Ulu Ricem ..Balinese Sign Surang + (0x01b34, 0x01b34,), # Balinese Sign Rerekan ..Balinese Sign Rerekan + (0x01b36, 0x01b3a,), # Balinese Vowel Sign Ulu ..Balinese Vowel Sign Ra R + (0x01b3c, 0x01b3c,), # Balinese Vowel Sign La L..Balinese Vowel Sign La L + (0x01b42, 0x01b42,), # Balinese Vowel Sign Pepe..Balinese Vowel Sign Pepe + (0x01b6b, 0x01b73,), # Balinese Musical Symbol ..Balinese Musical Symbol + (0x01b80, 0x01b81,), # Sundanese Sign Panyecek ..Sundanese Sign Panglayar + (0x01ba2, 0x01ba5,), # Sundanese Consonant Sign..Sundanese Vowel Sign Pan + (0x01ba8, 0x01ba9,), # Sundanese Vowel Sign Pam..Sundanese Vowel Sign Pan + (0x01c2c, 0x01c33,), # Lepcha Vowel Sign E ..Lepcha Consonant Sign T + (0x01c36, 0x01c37,), # Lepcha Sign Ran ..Lepcha Sign Nukta + (0x01cd0, 0x01cd2,), # Vedic Tone Karshana ..Vedic Tone Prenkha + (0x01cd4, 0x01ce0,), # Vedic Sign Yajurvedic Mi..Vedic Tone Rigvedic Kash + (0x01ce2, 0x01ce8,), # Vedic Sign Visarga Svari..Vedic Sign Visarga Anuda + (0x01ced, 0x01ced,), # Vedic Sign Tiryak ..Vedic Sign Tiryak + (0x01dc0, 0x01de6,), # Combining Dotted Grave A..Combining Latin Small Le + (0x01dfd, 0x01dff,), # Combining Almost Equal T..Combining Right Arrowhea + (0x020d0, 0x020f0,), # Combining Left Harpoon A..Combining Asterisk Above + (0x02cef, 0x02cf1,), # Coptic Combining Ni Abov..Coptic Combining Spiritu + (0x02de0, 0x02dff,), # Combining Cyrillic Lette..Combining Cyrillic Lette + (0x0302a, 0x0302f,), # Ideographic Level Tone M..Hangul Double Dot Tone M + (0x03099, 0x0309a,), # Combining Katakana-hirag..Combining Katakana-hirag + (0x0a66f, 0x0a672,), # Combining Cyrillic Vzmet..Combining Cyrillic Thous + (0x0a67c, 0x0a67d,), # Combining Cyrillic Kavyk..Combining Cyrillic Payer + (0x0a6f0, 0x0a6f1,), # Bamum Combining Mark Koq..Bamum Combining Mark Tuk + (0x0a802, 0x0a802,), # Syloti Nagri Sign Dvisva..Syloti Nagri Sign Dvisva + (0x0a806, 0x0a806,), # Syloti Nagri Sign Hasant..Syloti Nagri Sign Hasant + (0x0a80b, 0x0a80b,), # Syloti Nagri Sign Anusva..Syloti Nagri Sign Anusva + (0x0a825, 0x0a826,), # Syloti Nagri Vowel Sign ..Syloti Nagri Vowel Sign + (0x0a8c4, 0x0a8c4,), # Saurashtra Sign Virama ..Saurashtra Sign Virama + (0x0a8e0, 0x0a8f1,), # Combining Devanagari Dig..Combining Devanagari Sig + (0x0a926, 0x0a92d,), # Kayah Li Vowel Ue ..Kayah Li Tone Calya Plop + (0x0a947, 0x0a951,), # Rejang Vowel Sign I ..Rejang Consonant Sign R + (0x0a980, 0x0a982,), # Javanese Sign Panyangga ..Javanese Sign Layar + (0x0a9b3, 0x0a9b3,), # Javanese Sign Cecak Telu..Javanese Sign Cecak Telu + (0x0a9b6, 0x0a9b9,), # Javanese Vowel Sign Wulu..Javanese Vowel Sign Suku + (0x0a9bc, 0x0a9bc,), # Javanese Vowel Sign Pepe..Javanese Vowel Sign Pepe + (0x0aa29, 0x0aa2e,), # Cham Vowel Sign Aa ..Cham Vowel Sign Oe + (0x0aa31, 0x0aa32,), # Cham Vowel Sign Au ..Cham Vowel Sign Ue + (0x0aa35, 0x0aa36,), # Cham Consonant Sign La ..Cham Consonant Sign Wa + (0x0aa43, 0x0aa43,), # Cham Consonant Sign Fina..Cham Consonant Sign Fina + (0x0aa4c, 0x0aa4c,), # Cham Consonant Sign Fina..Cham Consonant Sign Fina + (0x0aab0, 0x0aab0,), # Tai Viet Mai Kang ..Tai Viet Mai Kang + (0x0aab2, 0x0aab4,), # Tai Viet Vowel I ..Tai Viet Vowel U + (0x0aab7, 0x0aab8,), # Tai Viet Mai Khit ..Tai Viet Vowel Ia + (0x0aabe, 0x0aabf,), # Tai Viet Vowel Am ..Tai Viet Tone Mai Ek + (0x0aac1, 0x0aac1,), # Tai Viet Tone Mai Tho ..Tai Viet Tone Mai Tho + (0x0abe5, 0x0abe5,), # Meetei Mayek Vowel Sign ..Meetei Mayek Vowel Sign + (0x0abe8, 0x0abe8,), # Meetei Mayek Vowel Sign ..Meetei Mayek Vowel Sign + (0x0abed, 0x0abed,), # Meetei Mayek Apun Iyek ..Meetei Mayek Apun Iyek + (0x0fb1e, 0x0fb1e,), # Hebrew Point Judeo-spani..Hebrew Point Judeo-spani + (0x0fe00, 0x0fe0f,), # Variation Selector-1 ..Variation Selector-16 + (0x0fe20, 0x0fe26,), # Combining Ligature Left ..Combining Conjoining Mac + (0x101fd, 0x101fd,), # Phaistos Disc Sign Combi..Phaistos Disc Sign Combi + (0x10a01, 0x10a03,), # Kharoshthi Vowel Sign I ..Kharoshthi Vowel Sign Vo + (0x10a05, 0x10a06,), # Kharoshthi Vowel Sign E ..Kharoshthi Vowel Sign O + (0x10a0c, 0x10a0f,), # Kharoshthi Vowel Length ..Kharoshthi Sign Visarga + (0x10a38, 0x10a3a,), # Kharoshthi Sign Bar Abov..Kharoshthi Sign Dot Belo + (0x10a3f, 0x10a3f,), # Kharoshthi Virama ..Kharoshthi Virama + (0x11080, 0x11081,), # Kaithi Sign Candrabindu ..Kaithi Sign Anusvara + (0x110b3, 0x110b6,), # Kaithi Vowel Sign U ..Kaithi Vowel Sign Ai + (0x110b9, 0x110ba,), # Kaithi Sign Virama ..Kaithi Sign Nukta + (0x1d167, 0x1d169,), # Musical Symbol Combining..Musical Symbol Combining + (0x1d17b, 0x1d182,), # Musical Symbol Combining..Musical Symbol Combining + (0x1d185, 0x1d18b,), # Musical Symbol Combining..Musical Symbol Combining + (0x1d1aa, 0x1d1ad,), # Musical Symbol Combining..Musical Symbol Combining + (0x1d242, 0x1d244,), # Combining Greek Musical ..Combining Greek Musical + (0xe0100, 0xe01ef,), # Variation Selector-17 ..Variation Selector-256 + ), + '6.0.0': ( + # Source: DerivedGeneralCategory-6.0.0.txt + # Date: 2010-08-19, 00:48:09 GMT [MD] + # + (0x00300, 0x0036f,), # Combining Grave Accent ..Combining Latin Small Le + (0x00483, 0x00489,), # Combining Cyrillic Titlo..Combining Cyrillic Milli + (0x00591, 0x005bd,), # Hebrew Accent Etnahta ..Hebrew Point Meteg + (0x005bf, 0x005bf,), # Hebrew Point Rafe ..Hebrew Point Rafe + (0x005c1, 0x005c2,), # Hebrew Point Shin Dot ..Hebrew Point Sin Dot + (0x005c4, 0x005c5,), # Hebrew Mark Upper Dot ..Hebrew Mark Lower Dot + (0x005c7, 0x005c7,), # Hebrew Point Qamats Qata..Hebrew Point Qamats Qata + (0x00610, 0x0061a,), # Arabic Sign Sallallahou ..Arabic Small Kasra + (0x0064b, 0x0065f,), # Arabic Fathatan ..Arabic Wavy Hamza Below + (0x00670, 0x00670,), # Arabic Letter Superscrip..Arabic Letter Superscrip + (0x006d6, 0x006dc,), # Arabic Small High Ligatu..Arabic Small High Seen + (0x006df, 0x006e4,), # Arabic Small High Rounde..Arabic Small High Madda + (0x006e7, 0x006e8,), # Arabic Small High Yeh ..Arabic Small High Noon + (0x006ea, 0x006ed,), # Arabic Empty Centre Low ..Arabic Small Low Meem + (0x00711, 0x00711,), # Syriac Letter Superscrip..Syriac Letter Superscrip + (0x00730, 0x0074a,), # Syriac Pthaha Above ..Syriac Barrekh + (0x007a6, 0x007b0,), # Thaana Abafili ..Thaana Sukun + (0x007eb, 0x007f3,), # Nko Combining Short High..Nko Combining Double Dot + (0x00816, 0x00819,), # Samaritan Mark In ..Samaritan Mark Dagesh + (0x0081b, 0x00823,), # Samaritan Mark Epentheti..Samaritan Vowel Sign A + (0x00825, 0x00827,), # Samaritan Vowel Sign Sho..Samaritan Vowel Sign U + (0x00829, 0x0082d,), # Samaritan Vowel Sign Lon..Samaritan Mark Nequdaa + (0x00859, 0x0085b,), # Mandaic Affrication Mark..Mandaic Gemination Mark + (0x00900, 0x00902,), # Devanagari Sign Inverted..Devanagari Sign Anusvara + (0x0093a, 0x0093a,), # Devanagari Vowel Sign Oe..Devanagari Vowel Sign Oe + (0x0093c, 0x0093c,), # Devanagari Sign Nukta ..Devanagari Sign Nukta + (0x00941, 0x00948,), # Devanagari Vowel Sign U ..Devanagari Vowel Sign Ai + (0x0094d, 0x0094d,), # Devanagari Sign Virama ..Devanagari Sign Virama + (0x00951, 0x00957,), # Devanagari Stress Sign U..Devanagari Vowel Sign Uu + (0x00962, 0x00963,), # Devanagari Vowel Sign Vo..Devanagari Vowel Sign Vo + (0x00981, 0x00981,), # Bengali Sign Candrabindu..Bengali Sign Candrabindu + (0x009bc, 0x009bc,), # Bengali Sign Nukta ..Bengali Sign Nukta + (0x009c1, 0x009c4,), # Bengali Vowel Sign U ..Bengali Vowel Sign Vocal + (0x009cd, 0x009cd,), # Bengali Sign Virama ..Bengali Sign Virama + (0x009e2, 0x009e3,), # Bengali Vowel Sign Vocal..Bengali Vowel Sign Vocal + (0x00a01, 0x00a02,), # Gurmukhi Sign Adak Bindi..Gurmukhi Sign Bindi + (0x00a3c, 0x00a3c,), # Gurmukhi Sign Nukta ..Gurmukhi Sign Nukta + (0x00a41, 0x00a42,), # Gurmukhi Vowel Sign U ..Gurmukhi Vowel Sign Uu + (0x00a47, 0x00a48,), # Gurmukhi Vowel Sign Ee ..Gurmukhi Vowel Sign Ai + (0x00a4b, 0x00a4d,), # Gurmukhi Vowel Sign Oo ..Gurmukhi Sign Virama + (0x00a51, 0x00a51,), # Gurmukhi Sign Udaat ..Gurmukhi Sign Udaat + (0x00a70, 0x00a71,), # Gurmukhi Tippi ..Gurmukhi Addak + (0x00a75, 0x00a75,), # Gurmukhi Sign Yakash ..Gurmukhi Sign Yakash + (0x00a81, 0x00a82,), # Gujarati Sign Candrabind..Gujarati Sign Anusvara + (0x00abc, 0x00abc,), # Gujarati Sign Nukta ..Gujarati Sign Nukta + (0x00ac1, 0x00ac5,), # Gujarati Vowel Sign U ..Gujarati Vowel Sign Cand + (0x00ac7, 0x00ac8,), # Gujarati Vowel Sign E ..Gujarati Vowel Sign Ai + (0x00acd, 0x00acd,), # Gujarati Sign Virama ..Gujarati Sign Virama + (0x00ae2, 0x00ae3,), # Gujarati Vowel Sign Voca..Gujarati Vowel Sign Voca + (0x00b01, 0x00b01,), # Oriya Sign Candrabindu ..Oriya Sign Candrabindu + (0x00b3c, 0x00b3c,), # Oriya Sign Nukta ..Oriya Sign Nukta + (0x00b3f, 0x00b3f,), # Oriya Vowel Sign I ..Oriya Vowel Sign I + (0x00b41, 0x00b44,), # Oriya Vowel Sign U ..Oriya Vowel Sign Vocalic + (0x00b4d, 0x00b4d,), # Oriya Sign Virama ..Oriya Sign Virama + (0x00b56, 0x00b56,), # Oriya Ai Length Mark ..Oriya Ai Length Mark + (0x00b62, 0x00b63,), # Oriya Vowel Sign Vocalic..Oriya Vowel Sign Vocalic + (0x00b82, 0x00b82,), # Tamil Sign Anusvara ..Tamil Sign Anusvara + (0x00bc0, 0x00bc0,), # Tamil Vowel Sign Ii ..Tamil Vowel Sign Ii + (0x00bcd, 0x00bcd,), # Tamil Sign Virama ..Tamil Sign Virama + (0x00c3e, 0x00c40,), # Telugu Vowel Sign Aa ..Telugu Vowel Sign Ii + (0x00c46, 0x00c48,), # Telugu Vowel Sign E ..Telugu Vowel Sign Ai + (0x00c4a, 0x00c4d,), # Telugu Vowel Sign O ..Telugu Sign Virama + (0x00c55, 0x00c56,), # Telugu Length Mark ..Telugu Ai Length Mark + (0x00c62, 0x00c63,), # Telugu Vowel Sign Vocali..Telugu Vowel Sign Vocali + (0x00cbc, 0x00cbc,), # Kannada Sign Nukta ..Kannada Sign Nukta + (0x00cbf, 0x00cbf,), # Kannada Vowel Sign I ..Kannada Vowel Sign I + (0x00cc6, 0x00cc6,), # Kannada Vowel Sign E ..Kannada Vowel Sign E + (0x00ccc, 0x00ccd,), # Kannada Vowel Sign Au ..Kannada Sign Virama + (0x00ce2, 0x00ce3,), # Kannada Vowel Sign Vocal..Kannada Vowel Sign Vocal + (0x00d41, 0x00d44,), # Malayalam Vowel Sign U ..Malayalam Vowel Sign Voc + (0x00d4d, 0x00d4d,), # Malayalam Sign Virama ..Malayalam Sign Virama + (0x00d62, 0x00d63,), # Malayalam Vowel Sign Voc..Malayalam Vowel Sign Voc + (0x00dca, 0x00dca,), # Sinhala Sign Al-lakuna ..Sinhala Sign Al-lakuna + (0x00dd2, 0x00dd4,), # Sinhala Vowel Sign Ketti..Sinhala Vowel Sign Ketti + (0x00dd6, 0x00dd6,), # Sinhala Vowel Sign Diga ..Sinhala Vowel Sign Diga + (0x00e31, 0x00e31,), # Thai Character Mai Han-a..Thai Character Mai Han-a + (0x00e34, 0x00e3a,), # Thai Character Sara I ..Thai Character Phinthu + (0x00e47, 0x00e4e,), # Thai Character Maitaikhu..Thai Character Yamakkan + (0x00eb1, 0x00eb1,), # Lao Vowel Sign Mai Kan ..Lao Vowel Sign Mai Kan + (0x00eb4, 0x00eb9,), # Lao Vowel Sign I ..Lao Vowel Sign Uu + (0x00ebb, 0x00ebc,), # Lao Vowel Sign Mai Kon ..Lao Semivowel Sign Lo + (0x00ec8, 0x00ecd,), # Lao Tone Mai Ek ..Lao Niggahita + (0x00f18, 0x00f19,), # Tibetan Astrological Sig..Tibetan Astrological Sig + (0x00f35, 0x00f35,), # Tibetan Mark Ngas Bzung ..Tibetan Mark Ngas Bzung + (0x00f37, 0x00f37,), # Tibetan Mark Ngas Bzung ..Tibetan Mark Ngas Bzung + (0x00f39, 0x00f39,), # Tibetan Mark Tsa -phru ..Tibetan Mark Tsa -phru + (0x00f71, 0x00f7e,), # Tibetan Vowel Sign Aa ..Tibetan Sign Rjes Su Nga + (0x00f80, 0x00f84,), # Tibetan Vowel Sign Rever..Tibetan Mark Halanta + (0x00f86, 0x00f87,), # Tibetan Sign Lci Rtags ..Tibetan Sign Yang Rtags + (0x00f8d, 0x00f97,), # Tibetan Subjoined Sign L..Tibetan Subjoined Letter + (0x00f99, 0x00fbc,), # Tibetan Subjoined Letter..Tibetan Subjoined Letter + (0x00fc6, 0x00fc6,), # Tibetan Symbol Padma Gda..Tibetan Symbol Padma Gda + (0x0102d, 0x01030,), # Myanmar Vowel Sign I ..Myanmar Vowel Sign Uu + (0x01032, 0x01037,), # Myanmar Vowel Sign Ai ..Myanmar Sign Dot Below + (0x01039, 0x0103a,), # Myanmar Sign Virama ..Myanmar Sign Asat + (0x0103d, 0x0103e,), # Myanmar Consonant Sign M..Myanmar Consonant Sign M + (0x01058, 0x01059,), # Myanmar Vowel Sign Vocal..Myanmar Vowel Sign Vocal + (0x0105e, 0x01060,), # Myanmar Consonant Sign M..Myanmar Consonant Sign M + (0x01071, 0x01074,), # Myanmar Vowel Sign Geba ..Myanmar Vowel Sign Kayah + (0x01082, 0x01082,), # Myanmar Consonant Sign S..Myanmar Consonant Sign S + (0x01085, 0x01086,), # Myanmar Vowel Sign Shan ..Myanmar Vowel Sign Shan + (0x0108d, 0x0108d,), # Myanmar Sign Shan Counci..Myanmar Sign Shan Counci + (0x0109d, 0x0109d,), # Myanmar Vowel Sign Aiton..Myanmar Vowel Sign Aiton + (0x0135d, 0x0135f,), # Ethiopic Combining Gemin..Ethiopic Combining Gemin + (0x01712, 0x01714,), # Tagalog Vowel Sign I ..Tagalog Sign Virama + (0x01732, 0x01734,), # Hanunoo Vowel Sign I ..Hanunoo Sign Pamudpod + (0x01752, 0x01753,), # Buhid Vowel Sign I ..Buhid Vowel Sign U + (0x01772, 0x01773,), # Tagbanwa Vowel Sign I ..Tagbanwa Vowel Sign U + (0x017b7, 0x017bd,), # Khmer Vowel Sign I ..Khmer Vowel Sign Ua + (0x017c6, 0x017c6,), # Khmer Sign Nikahit ..Khmer Sign Nikahit + (0x017c9, 0x017d3,), # Khmer Sign Muusikatoan ..Khmer Sign Bathamasat + (0x017dd, 0x017dd,), # Khmer Sign Atthacan ..Khmer Sign Atthacan + (0x0180b, 0x0180d,), # Mongolian Free Variation..Mongolian Free Variation + (0x018a9, 0x018a9,), # Mongolian Letter Ali Gal..Mongolian Letter Ali Gal + (0x01920, 0x01922,), # Limbu Vowel Sign A ..Limbu Vowel Sign U + (0x01927, 0x01928,), # Limbu Vowel Sign E ..Limbu Vowel Sign O + (0x01932, 0x01932,), # Limbu Small Letter Anusv..Limbu Small Letter Anusv + (0x01939, 0x0193b,), # Limbu Sign Mukphreng ..Limbu Sign Sa-i + (0x01a17, 0x01a18,), # Buginese Vowel Sign I ..Buginese Vowel Sign U + (0x01a56, 0x01a56,), # Tai Tham Consonant Sign ..Tai Tham Consonant Sign + (0x01a58, 0x01a5e,), # Tai Tham Sign Mai Kang L..Tai Tham Consonant Sign + (0x01a60, 0x01a60,), # Tai Tham Sign Sakot ..Tai Tham Sign Sakot + (0x01a62, 0x01a62,), # Tai Tham Vowel Sign Mai ..Tai Tham Vowel Sign Mai + (0x01a65, 0x01a6c,), # Tai Tham Vowel Sign I ..Tai Tham Vowel Sign Oa B + (0x01a73, 0x01a7c,), # Tai Tham Vowel Sign Oa A..Tai Tham Sign Khuen-lue + (0x01a7f, 0x01a7f,), # Tai Tham Combining Crypt..Tai Tham Combining Crypt + (0x01b00, 0x01b03,), # Balinese Sign Ulu Ricem ..Balinese Sign Surang + (0x01b34, 0x01b34,), # Balinese Sign Rerekan ..Balinese Sign Rerekan + (0x01b36, 0x01b3a,), # Balinese Vowel Sign Ulu ..Balinese Vowel Sign Ra R + (0x01b3c, 0x01b3c,), # Balinese Vowel Sign La L..Balinese Vowel Sign La L + (0x01b42, 0x01b42,), # Balinese Vowel Sign Pepe..Balinese Vowel Sign Pepe + (0x01b6b, 0x01b73,), # Balinese Musical Symbol ..Balinese Musical Symbol + (0x01b80, 0x01b81,), # Sundanese Sign Panyecek ..Sundanese Sign Panglayar + (0x01ba2, 0x01ba5,), # Sundanese Consonant Sign..Sundanese Vowel Sign Pan + (0x01ba8, 0x01ba9,), # Sundanese Vowel Sign Pam..Sundanese Vowel Sign Pan + (0x01be6, 0x01be6,), # Batak Sign Tompi ..Batak Sign Tompi + (0x01be8, 0x01be9,), # Batak Vowel Sign Pakpak ..Batak Vowel Sign Ee + (0x01bed, 0x01bed,), # Batak Vowel Sign Karo O ..Batak Vowel Sign Karo O + (0x01bef, 0x01bf1,), # Batak Vowel Sign U For S..Batak Consonant Sign H + (0x01c2c, 0x01c33,), # Lepcha Vowel Sign E ..Lepcha Consonant Sign T + (0x01c36, 0x01c37,), # Lepcha Sign Ran ..Lepcha Sign Nukta + (0x01cd0, 0x01cd2,), # Vedic Tone Karshana ..Vedic Tone Prenkha + (0x01cd4, 0x01ce0,), # Vedic Sign Yajurvedic Mi..Vedic Tone Rigvedic Kash + (0x01ce2, 0x01ce8,), # Vedic Sign Visarga Svari..Vedic Sign Visarga Anuda + (0x01ced, 0x01ced,), # Vedic Sign Tiryak ..Vedic Sign Tiryak + (0x01dc0, 0x01de6,), # Combining Dotted Grave A..Combining Latin Small Le + (0x01dfc, 0x01dff,), # Combining Double Inverte..Combining Right Arrowhea + (0x020d0, 0x020f0,), # Combining Left Harpoon A..Combining Asterisk Above + (0x02cef, 0x02cf1,), # Coptic Combining Ni Abov..Coptic Combining Spiritu + (0x02d7f, 0x02d7f,), # Tifinagh Consonant Joine..Tifinagh Consonant Joine + (0x02de0, 0x02dff,), # Combining Cyrillic Lette..Combining Cyrillic Lette + (0x0302a, 0x0302f,), # Ideographic Level Tone M..Hangul Double Dot Tone M + (0x03099, 0x0309a,), # Combining Katakana-hirag..Combining Katakana-hirag + (0x0a66f, 0x0a672,), # Combining Cyrillic Vzmet..Combining Cyrillic Thous + (0x0a67c, 0x0a67d,), # Combining Cyrillic Kavyk..Combining Cyrillic Payer + (0x0a6f0, 0x0a6f1,), # Bamum Combining Mark Koq..Bamum Combining Mark Tuk + (0x0a802, 0x0a802,), # Syloti Nagri Sign Dvisva..Syloti Nagri Sign Dvisva + (0x0a806, 0x0a806,), # Syloti Nagri Sign Hasant..Syloti Nagri Sign Hasant + (0x0a80b, 0x0a80b,), # Syloti Nagri Sign Anusva..Syloti Nagri Sign Anusva + (0x0a825, 0x0a826,), # Syloti Nagri Vowel Sign ..Syloti Nagri Vowel Sign + (0x0a8c4, 0x0a8c4,), # Saurashtra Sign Virama ..Saurashtra Sign Virama + (0x0a8e0, 0x0a8f1,), # Combining Devanagari Dig..Combining Devanagari Sig + (0x0a926, 0x0a92d,), # Kayah Li Vowel Ue ..Kayah Li Tone Calya Plop + (0x0a947, 0x0a951,), # Rejang Vowel Sign I ..Rejang Consonant Sign R + (0x0a980, 0x0a982,), # Javanese Sign Panyangga ..Javanese Sign Layar + (0x0a9b3, 0x0a9b3,), # Javanese Sign Cecak Telu..Javanese Sign Cecak Telu + (0x0a9b6, 0x0a9b9,), # Javanese Vowel Sign Wulu..Javanese Vowel Sign Suku + (0x0a9bc, 0x0a9bc,), # Javanese Vowel Sign Pepe..Javanese Vowel Sign Pepe + (0x0aa29, 0x0aa2e,), # Cham Vowel Sign Aa ..Cham Vowel Sign Oe + (0x0aa31, 0x0aa32,), # Cham Vowel Sign Au ..Cham Vowel Sign Ue + (0x0aa35, 0x0aa36,), # Cham Consonant Sign La ..Cham Consonant Sign Wa + (0x0aa43, 0x0aa43,), # Cham Consonant Sign Fina..Cham Consonant Sign Fina + (0x0aa4c, 0x0aa4c,), # Cham Consonant Sign Fina..Cham Consonant Sign Fina + (0x0aab0, 0x0aab0,), # Tai Viet Mai Kang ..Tai Viet Mai Kang + (0x0aab2, 0x0aab4,), # Tai Viet Vowel I ..Tai Viet Vowel U + (0x0aab7, 0x0aab8,), # Tai Viet Mai Khit ..Tai Viet Vowel Ia + (0x0aabe, 0x0aabf,), # Tai Viet Vowel Am ..Tai Viet Tone Mai Ek + (0x0aac1, 0x0aac1,), # Tai Viet Tone Mai Tho ..Tai Viet Tone Mai Tho + (0x0abe5, 0x0abe5,), # Meetei Mayek Vowel Sign ..Meetei Mayek Vowel Sign + (0x0abe8, 0x0abe8,), # Meetei Mayek Vowel Sign ..Meetei Mayek Vowel Sign + (0x0abed, 0x0abed,), # Meetei Mayek Apun Iyek ..Meetei Mayek Apun Iyek + (0x0fb1e, 0x0fb1e,), # Hebrew Point Judeo-spani..Hebrew Point Judeo-spani + (0x0fe00, 0x0fe0f,), # Variation Selector-1 ..Variation Selector-16 + (0x0fe20, 0x0fe26,), # Combining Ligature Left ..Combining Conjoining Mac + (0x101fd, 0x101fd,), # Phaistos Disc Sign Combi..Phaistos Disc Sign Combi + (0x10a01, 0x10a03,), # Kharoshthi Vowel Sign I ..Kharoshthi Vowel Sign Vo + (0x10a05, 0x10a06,), # Kharoshthi Vowel Sign E ..Kharoshthi Vowel Sign O + (0x10a0c, 0x10a0f,), # Kharoshthi Vowel Length ..Kharoshthi Sign Visarga + (0x10a38, 0x10a3a,), # Kharoshthi Sign Bar Abov..Kharoshthi Sign Dot Belo + (0x10a3f, 0x10a3f,), # Kharoshthi Virama ..Kharoshthi Virama + (0x11001, 0x11001,), # Brahmi Sign Anusvara ..Brahmi Sign Anusvara + (0x11038, 0x11046,), # Brahmi Vowel Sign Aa ..Brahmi Virama + (0x11080, 0x11081,), # Kaithi Sign Candrabindu ..Kaithi Sign Anusvara + (0x110b3, 0x110b6,), # Kaithi Vowel Sign U ..Kaithi Vowel Sign Ai + (0x110b9, 0x110ba,), # Kaithi Sign Virama ..Kaithi Sign Nukta + (0x1d167, 0x1d169,), # Musical Symbol Combining..Musical Symbol Combining + (0x1d17b, 0x1d182,), # Musical Symbol Combining..Musical Symbol Combining + (0x1d185, 0x1d18b,), # Musical Symbol Combining..Musical Symbol Combining + (0x1d1aa, 0x1d1ad,), # Musical Symbol Combining..Musical Symbol Combining + (0x1d242, 0x1d244,), # Combining Greek Musical ..Combining Greek Musical + (0xe0100, 0xe01ef,), # Variation Selector-17 ..Variation Selector-256 + ), + '6.1.0': ( + # Source: DerivedGeneralCategory-6.1.0.txt + # Date: 2011-11-27, 05:10:22 GMT [MD] + # + (0x00300, 0x0036f,), # Combining Grave Accent ..Combining Latin Small Le + (0x00483, 0x00489,), # Combining Cyrillic Titlo..Combining Cyrillic Milli + (0x00591, 0x005bd,), # Hebrew Accent Etnahta ..Hebrew Point Meteg + (0x005bf, 0x005bf,), # Hebrew Point Rafe ..Hebrew Point Rafe + (0x005c1, 0x005c2,), # Hebrew Point Shin Dot ..Hebrew Point Sin Dot + (0x005c4, 0x005c5,), # Hebrew Mark Upper Dot ..Hebrew Mark Lower Dot + (0x005c7, 0x005c7,), # Hebrew Point Qamats Qata..Hebrew Point Qamats Qata + (0x00610, 0x0061a,), # Arabic Sign Sallallahou ..Arabic Small Kasra + (0x0064b, 0x0065f,), # Arabic Fathatan ..Arabic Wavy Hamza Below + (0x00670, 0x00670,), # Arabic Letter Superscrip..Arabic Letter Superscrip + (0x006d6, 0x006dc,), # Arabic Small High Ligatu..Arabic Small High Seen + (0x006df, 0x006e4,), # Arabic Small High Rounde..Arabic Small High Madda + (0x006e7, 0x006e8,), # Arabic Small High Yeh ..Arabic Small High Noon + (0x006ea, 0x006ed,), # Arabic Empty Centre Low ..Arabic Small Low Meem + (0x00711, 0x00711,), # Syriac Letter Superscrip..Syriac Letter Superscrip + (0x00730, 0x0074a,), # Syriac Pthaha Above ..Syriac Barrekh + (0x007a6, 0x007b0,), # Thaana Abafili ..Thaana Sukun + (0x007eb, 0x007f3,), # Nko Combining Short High..Nko Combining Double Dot + (0x00816, 0x00819,), # Samaritan Mark In ..Samaritan Mark Dagesh + (0x0081b, 0x00823,), # Samaritan Mark Epentheti..Samaritan Vowel Sign A + (0x00825, 0x00827,), # Samaritan Vowel Sign Sho..Samaritan Vowel Sign U + (0x00829, 0x0082d,), # Samaritan Vowel Sign Lon..Samaritan Mark Nequdaa + (0x00859, 0x0085b,), # Mandaic Affrication Mark..Mandaic Gemination Mark + (0x008e4, 0x008fe,), # Arabic Curly Fatha ..Arabic Damma With Dot + (0x00900, 0x00902,), # Devanagari Sign Inverted..Devanagari Sign Anusvara + (0x0093a, 0x0093a,), # Devanagari Vowel Sign Oe..Devanagari Vowel Sign Oe + (0x0093c, 0x0093c,), # Devanagari Sign Nukta ..Devanagari Sign Nukta + (0x00941, 0x00948,), # Devanagari Vowel Sign U ..Devanagari Vowel Sign Ai + (0x0094d, 0x0094d,), # Devanagari Sign Virama ..Devanagari Sign Virama + (0x00951, 0x00957,), # Devanagari Stress Sign U..Devanagari Vowel Sign Uu + (0x00962, 0x00963,), # Devanagari Vowel Sign Vo..Devanagari Vowel Sign Vo + (0x00981, 0x00981,), # Bengali Sign Candrabindu..Bengali Sign Candrabindu + (0x009bc, 0x009bc,), # Bengali Sign Nukta ..Bengali Sign Nukta + (0x009c1, 0x009c4,), # Bengali Vowel Sign U ..Bengali Vowel Sign Vocal + (0x009cd, 0x009cd,), # Bengali Sign Virama ..Bengali Sign Virama + (0x009e2, 0x009e3,), # Bengali Vowel Sign Vocal..Bengali Vowel Sign Vocal + (0x00a01, 0x00a02,), # Gurmukhi Sign Adak Bindi..Gurmukhi Sign Bindi + (0x00a3c, 0x00a3c,), # Gurmukhi Sign Nukta ..Gurmukhi Sign Nukta + (0x00a41, 0x00a42,), # Gurmukhi Vowel Sign U ..Gurmukhi Vowel Sign Uu + (0x00a47, 0x00a48,), # Gurmukhi Vowel Sign Ee ..Gurmukhi Vowel Sign Ai + (0x00a4b, 0x00a4d,), # Gurmukhi Vowel Sign Oo ..Gurmukhi Sign Virama + (0x00a51, 0x00a51,), # Gurmukhi Sign Udaat ..Gurmukhi Sign Udaat + (0x00a70, 0x00a71,), # Gurmukhi Tippi ..Gurmukhi Addak + (0x00a75, 0x00a75,), # Gurmukhi Sign Yakash ..Gurmukhi Sign Yakash + (0x00a81, 0x00a82,), # Gujarati Sign Candrabind..Gujarati Sign Anusvara + (0x00abc, 0x00abc,), # Gujarati Sign Nukta ..Gujarati Sign Nukta + (0x00ac1, 0x00ac5,), # Gujarati Vowel Sign U ..Gujarati Vowel Sign Cand + (0x00ac7, 0x00ac8,), # Gujarati Vowel Sign E ..Gujarati Vowel Sign Ai + (0x00acd, 0x00acd,), # Gujarati Sign Virama ..Gujarati Sign Virama + (0x00ae2, 0x00ae3,), # Gujarati Vowel Sign Voca..Gujarati Vowel Sign Voca + (0x00b01, 0x00b01,), # Oriya Sign Candrabindu ..Oriya Sign Candrabindu + (0x00b3c, 0x00b3c,), # Oriya Sign Nukta ..Oriya Sign Nukta + (0x00b3f, 0x00b3f,), # Oriya Vowel Sign I ..Oriya Vowel Sign I + (0x00b41, 0x00b44,), # Oriya Vowel Sign U ..Oriya Vowel Sign Vocalic + (0x00b4d, 0x00b4d,), # Oriya Sign Virama ..Oriya Sign Virama + (0x00b56, 0x00b56,), # Oriya Ai Length Mark ..Oriya Ai Length Mark + (0x00b62, 0x00b63,), # Oriya Vowel Sign Vocalic..Oriya Vowel Sign Vocalic + (0x00b82, 0x00b82,), # Tamil Sign Anusvara ..Tamil Sign Anusvara + (0x00bc0, 0x00bc0,), # Tamil Vowel Sign Ii ..Tamil Vowel Sign Ii + (0x00bcd, 0x00bcd,), # Tamil Sign Virama ..Tamil Sign Virama + (0x00c3e, 0x00c40,), # Telugu Vowel Sign Aa ..Telugu Vowel Sign Ii + (0x00c46, 0x00c48,), # Telugu Vowel Sign E ..Telugu Vowel Sign Ai + (0x00c4a, 0x00c4d,), # Telugu Vowel Sign O ..Telugu Sign Virama + (0x00c55, 0x00c56,), # Telugu Length Mark ..Telugu Ai Length Mark + (0x00c62, 0x00c63,), # Telugu Vowel Sign Vocali..Telugu Vowel Sign Vocali + (0x00cbc, 0x00cbc,), # Kannada Sign Nukta ..Kannada Sign Nukta + (0x00cbf, 0x00cbf,), # Kannada Vowel Sign I ..Kannada Vowel Sign I + (0x00cc6, 0x00cc6,), # Kannada Vowel Sign E ..Kannada Vowel Sign E + (0x00ccc, 0x00ccd,), # Kannada Vowel Sign Au ..Kannada Sign Virama + (0x00ce2, 0x00ce3,), # Kannada Vowel Sign Vocal..Kannada Vowel Sign Vocal + (0x00d41, 0x00d44,), # Malayalam Vowel Sign U ..Malayalam Vowel Sign Voc + (0x00d4d, 0x00d4d,), # Malayalam Sign Virama ..Malayalam Sign Virama + (0x00d62, 0x00d63,), # Malayalam Vowel Sign Voc..Malayalam Vowel Sign Voc + (0x00dca, 0x00dca,), # Sinhala Sign Al-lakuna ..Sinhala Sign Al-lakuna + (0x00dd2, 0x00dd4,), # Sinhala Vowel Sign Ketti..Sinhala Vowel Sign Ketti + (0x00dd6, 0x00dd6,), # Sinhala Vowel Sign Diga ..Sinhala Vowel Sign Diga + (0x00e31, 0x00e31,), # Thai Character Mai Han-a..Thai Character Mai Han-a + (0x00e34, 0x00e3a,), # Thai Character Sara I ..Thai Character Phinthu + (0x00e47, 0x00e4e,), # Thai Character Maitaikhu..Thai Character Yamakkan + (0x00eb1, 0x00eb1,), # Lao Vowel Sign Mai Kan ..Lao Vowel Sign Mai Kan + (0x00eb4, 0x00eb9,), # Lao Vowel Sign I ..Lao Vowel Sign Uu + (0x00ebb, 0x00ebc,), # Lao Vowel Sign Mai Kon ..Lao Semivowel Sign Lo + (0x00ec8, 0x00ecd,), # Lao Tone Mai Ek ..Lao Niggahita + (0x00f18, 0x00f19,), # Tibetan Astrological Sig..Tibetan Astrological Sig + (0x00f35, 0x00f35,), # Tibetan Mark Ngas Bzung ..Tibetan Mark Ngas Bzung + (0x00f37, 0x00f37,), # Tibetan Mark Ngas Bzung ..Tibetan Mark Ngas Bzung + (0x00f39, 0x00f39,), # Tibetan Mark Tsa -phru ..Tibetan Mark Tsa -phru + (0x00f71, 0x00f7e,), # Tibetan Vowel Sign Aa ..Tibetan Sign Rjes Su Nga + (0x00f80, 0x00f84,), # Tibetan Vowel Sign Rever..Tibetan Mark Halanta + (0x00f86, 0x00f87,), # Tibetan Sign Lci Rtags ..Tibetan Sign Yang Rtags + (0x00f8d, 0x00f97,), # Tibetan Subjoined Sign L..Tibetan Subjoined Letter + (0x00f99, 0x00fbc,), # Tibetan Subjoined Letter..Tibetan Subjoined Letter + (0x00fc6, 0x00fc6,), # Tibetan Symbol Padma Gda..Tibetan Symbol Padma Gda + (0x0102d, 0x01030,), # Myanmar Vowel Sign I ..Myanmar Vowel Sign Uu + (0x01032, 0x01037,), # Myanmar Vowel Sign Ai ..Myanmar Sign Dot Below + (0x01039, 0x0103a,), # Myanmar Sign Virama ..Myanmar Sign Asat + (0x0103d, 0x0103e,), # Myanmar Consonant Sign M..Myanmar Consonant Sign M + (0x01058, 0x01059,), # Myanmar Vowel Sign Vocal..Myanmar Vowel Sign Vocal + (0x0105e, 0x01060,), # Myanmar Consonant Sign M..Myanmar Consonant Sign M + (0x01071, 0x01074,), # Myanmar Vowel Sign Geba ..Myanmar Vowel Sign Kayah + (0x01082, 0x01082,), # Myanmar Consonant Sign S..Myanmar Consonant Sign S + (0x01085, 0x01086,), # Myanmar Vowel Sign Shan ..Myanmar Vowel Sign Shan + (0x0108d, 0x0108d,), # Myanmar Sign Shan Counci..Myanmar Sign Shan Counci + (0x0109d, 0x0109d,), # Myanmar Vowel Sign Aiton..Myanmar Vowel Sign Aiton + (0x0135d, 0x0135f,), # Ethiopic Combining Gemin..Ethiopic Combining Gemin + (0x01712, 0x01714,), # Tagalog Vowel Sign I ..Tagalog Sign Virama + (0x01732, 0x01734,), # Hanunoo Vowel Sign I ..Hanunoo Sign Pamudpod + (0x01752, 0x01753,), # Buhid Vowel Sign I ..Buhid Vowel Sign U + (0x01772, 0x01773,), # Tagbanwa Vowel Sign I ..Tagbanwa Vowel Sign U + (0x017b4, 0x017b5,), # Khmer Vowel Inherent Aq ..Khmer Vowel Inherent Aa + (0x017b7, 0x017bd,), # Khmer Vowel Sign I ..Khmer Vowel Sign Ua + (0x017c6, 0x017c6,), # Khmer Sign Nikahit ..Khmer Sign Nikahit + (0x017c9, 0x017d3,), # Khmer Sign Muusikatoan ..Khmer Sign Bathamasat + (0x017dd, 0x017dd,), # Khmer Sign Atthacan ..Khmer Sign Atthacan + (0x0180b, 0x0180d,), # Mongolian Free Variation..Mongolian Free Variation + (0x018a9, 0x018a9,), # Mongolian Letter Ali Gal..Mongolian Letter Ali Gal + (0x01920, 0x01922,), # Limbu Vowel Sign A ..Limbu Vowel Sign U + (0x01927, 0x01928,), # Limbu Vowel Sign E ..Limbu Vowel Sign O + (0x01932, 0x01932,), # Limbu Small Letter Anusv..Limbu Small Letter Anusv + (0x01939, 0x0193b,), # Limbu Sign Mukphreng ..Limbu Sign Sa-i + (0x01a17, 0x01a18,), # Buginese Vowel Sign I ..Buginese Vowel Sign U + (0x01a56, 0x01a56,), # Tai Tham Consonant Sign ..Tai Tham Consonant Sign + (0x01a58, 0x01a5e,), # Tai Tham Sign Mai Kang L..Tai Tham Consonant Sign + (0x01a60, 0x01a60,), # Tai Tham Sign Sakot ..Tai Tham Sign Sakot + (0x01a62, 0x01a62,), # Tai Tham Vowel Sign Mai ..Tai Tham Vowel Sign Mai + (0x01a65, 0x01a6c,), # Tai Tham Vowel Sign I ..Tai Tham Vowel Sign Oa B + (0x01a73, 0x01a7c,), # Tai Tham Vowel Sign Oa A..Tai Tham Sign Khuen-lue + (0x01a7f, 0x01a7f,), # Tai Tham Combining Crypt..Tai Tham Combining Crypt + (0x01b00, 0x01b03,), # Balinese Sign Ulu Ricem ..Balinese Sign Surang + (0x01b34, 0x01b34,), # Balinese Sign Rerekan ..Balinese Sign Rerekan + (0x01b36, 0x01b3a,), # Balinese Vowel Sign Ulu ..Balinese Vowel Sign Ra R + (0x01b3c, 0x01b3c,), # Balinese Vowel Sign La L..Balinese Vowel Sign La L + (0x01b42, 0x01b42,), # Balinese Vowel Sign Pepe..Balinese Vowel Sign Pepe + (0x01b6b, 0x01b73,), # Balinese Musical Symbol ..Balinese Musical Symbol + (0x01b80, 0x01b81,), # Sundanese Sign Panyecek ..Sundanese Sign Panglayar + (0x01ba2, 0x01ba5,), # Sundanese Consonant Sign..Sundanese Vowel Sign Pan + (0x01ba8, 0x01ba9,), # Sundanese Vowel Sign Pam..Sundanese Vowel Sign Pan + (0x01bab, 0x01bab,), # Sundanese Sign Virama ..Sundanese Sign Virama + (0x01be6, 0x01be6,), # Batak Sign Tompi ..Batak Sign Tompi + (0x01be8, 0x01be9,), # Batak Vowel Sign Pakpak ..Batak Vowel Sign Ee + (0x01bed, 0x01bed,), # Batak Vowel Sign Karo O ..Batak Vowel Sign Karo O + (0x01bef, 0x01bf1,), # Batak Vowel Sign U For S..Batak Consonant Sign H + (0x01c2c, 0x01c33,), # Lepcha Vowel Sign E ..Lepcha Consonant Sign T + (0x01c36, 0x01c37,), # Lepcha Sign Ran ..Lepcha Sign Nukta + (0x01cd0, 0x01cd2,), # Vedic Tone Karshana ..Vedic Tone Prenkha + (0x01cd4, 0x01ce0,), # Vedic Sign Yajurvedic Mi..Vedic Tone Rigvedic Kash + (0x01ce2, 0x01ce8,), # Vedic Sign Visarga Svari..Vedic Sign Visarga Anuda + (0x01ced, 0x01ced,), # Vedic Sign Tiryak ..Vedic Sign Tiryak + (0x01cf4, 0x01cf4,), # Vedic Tone Candra Above ..Vedic Tone Candra Above + (0x01dc0, 0x01de6,), # Combining Dotted Grave A..Combining Latin Small Le + (0x01dfc, 0x01dff,), # Combining Double Inverte..Combining Right Arrowhea + (0x020d0, 0x020f0,), # Combining Left Harpoon A..Combining Asterisk Above + (0x02cef, 0x02cf1,), # Coptic Combining Ni Abov..Coptic Combining Spiritu + (0x02d7f, 0x02d7f,), # Tifinagh Consonant Joine..Tifinagh Consonant Joine + (0x02de0, 0x02dff,), # Combining Cyrillic Lette..Combining Cyrillic Lette + (0x0302a, 0x0302d,), # Ideographic Level Tone M..Ideographic Entering Ton + (0x03099, 0x0309a,), # Combining Katakana-hirag..Combining Katakana-hirag + (0x0a66f, 0x0a672,), # Combining Cyrillic Vzmet..Combining Cyrillic Thous + (0x0a674, 0x0a67d,), # Combining Cyrillic Lette..Combining Cyrillic Payer + (0x0a69f, 0x0a69f,), # Combining Cyrillic Lette..Combining Cyrillic Lette + (0x0a6f0, 0x0a6f1,), # Bamum Combining Mark Koq..Bamum Combining Mark Tuk + (0x0a802, 0x0a802,), # Syloti Nagri Sign Dvisva..Syloti Nagri Sign Dvisva + (0x0a806, 0x0a806,), # Syloti Nagri Sign Hasant..Syloti Nagri Sign Hasant + (0x0a80b, 0x0a80b,), # Syloti Nagri Sign Anusva..Syloti Nagri Sign Anusva + (0x0a825, 0x0a826,), # Syloti Nagri Vowel Sign ..Syloti Nagri Vowel Sign + (0x0a8c4, 0x0a8c4,), # Saurashtra Sign Virama ..Saurashtra Sign Virama + (0x0a8e0, 0x0a8f1,), # Combining Devanagari Dig..Combining Devanagari Sig + (0x0a926, 0x0a92d,), # Kayah Li Vowel Ue ..Kayah Li Tone Calya Plop + (0x0a947, 0x0a951,), # Rejang Vowel Sign I ..Rejang Consonant Sign R + (0x0a980, 0x0a982,), # Javanese Sign Panyangga ..Javanese Sign Layar + (0x0a9b3, 0x0a9b3,), # Javanese Sign Cecak Telu..Javanese Sign Cecak Telu + (0x0a9b6, 0x0a9b9,), # Javanese Vowel Sign Wulu..Javanese Vowel Sign Suku + (0x0a9bc, 0x0a9bc,), # Javanese Vowel Sign Pepe..Javanese Vowel Sign Pepe + (0x0aa29, 0x0aa2e,), # Cham Vowel Sign Aa ..Cham Vowel Sign Oe + (0x0aa31, 0x0aa32,), # Cham Vowel Sign Au ..Cham Vowel Sign Ue + (0x0aa35, 0x0aa36,), # Cham Consonant Sign La ..Cham Consonant Sign Wa + (0x0aa43, 0x0aa43,), # Cham Consonant Sign Fina..Cham Consonant Sign Fina + (0x0aa4c, 0x0aa4c,), # Cham Consonant Sign Fina..Cham Consonant Sign Fina + (0x0aab0, 0x0aab0,), # Tai Viet Mai Kang ..Tai Viet Mai Kang + (0x0aab2, 0x0aab4,), # Tai Viet Vowel I ..Tai Viet Vowel U + (0x0aab7, 0x0aab8,), # Tai Viet Mai Khit ..Tai Viet Vowel Ia + (0x0aabe, 0x0aabf,), # Tai Viet Vowel Am ..Tai Viet Tone Mai Ek + (0x0aac1, 0x0aac1,), # Tai Viet Tone Mai Tho ..Tai Viet Tone Mai Tho + (0x0aaec, 0x0aaed,), # Meetei Mayek Vowel Sign ..Meetei Mayek Vowel Sign + (0x0aaf6, 0x0aaf6,), # Meetei Mayek Virama ..Meetei Mayek Virama + (0x0abe5, 0x0abe5,), # Meetei Mayek Vowel Sign ..Meetei Mayek Vowel Sign + (0x0abe8, 0x0abe8,), # Meetei Mayek Vowel Sign ..Meetei Mayek Vowel Sign + (0x0abed, 0x0abed,), # Meetei Mayek Apun Iyek ..Meetei Mayek Apun Iyek + (0x0fb1e, 0x0fb1e,), # Hebrew Point Judeo-spani..Hebrew Point Judeo-spani + (0x0fe00, 0x0fe0f,), # Variation Selector-1 ..Variation Selector-16 + (0x0fe20, 0x0fe26,), # Combining Ligature Left ..Combining Conjoining Mac + (0x101fd, 0x101fd,), # Phaistos Disc Sign Combi..Phaistos Disc Sign Combi + (0x10a01, 0x10a03,), # Kharoshthi Vowel Sign I ..Kharoshthi Vowel Sign Vo + (0x10a05, 0x10a06,), # Kharoshthi Vowel Sign E ..Kharoshthi Vowel Sign O + (0x10a0c, 0x10a0f,), # Kharoshthi Vowel Length ..Kharoshthi Sign Visarga + (0x10a38, 0x10a3a,), # Kharoshthi Sign Bar Abov..Kharoshthi Sign Dot Belo + (0x10a3f, 0x10a3f,), # Kharoshthi Virama ..Kharoshthi Virama + (0x11001, 0x11001,), # Brahmi Sign Anusvara ..Brahmi Sign Anusvara + (0x11038, 0x11046,), # Brahmi Vowel Sign Aa ..Brahmi Virama + (0x11080, 0x11081,), # Kaithi Sign Candrabindu ..Kaithi Sign Anusvara + (0x110b3, 0x110b6,), # Kaithi Vowel Sign U ..Kaithi Vowel Sign Ai + (0x110b9, 0x110ba,), # Kaithi Sign Virama ..Kaithi Sign Nukta + (0x11100, 0x11102,), # Chakma Sign Candrabindu ..Chakma Sign Visarga + (0x11127, 0x1112b,), # Chakma Vowel Sign A ..Chakma Vowel Sign Uu + (0x1112d, 0x11134,), # Chakma Vowel Sign Ai ..Chakma Maayyaa + (0x11180, 0x11181,), # Sharada Sign Candrabindu..Sharada Sign Anusvara + (0x111b6, 0x111be,), # Sharada Vowel Sign U ..Sharada Vowel Sign O + (0x116ab, 0x116ab,), # Takri Sign Anusvara ..Takri Sign Anusvara + (0x116ad, 0x116ad,), # Takri Vowel Sign Aa ..Takri Vowel Sign Aa + (0x116b0, 0x116b5,), # Takri Vowel Sign U ..Takri Vowel Sign Au + (0x116b7, 0x116b7,), # Takri Sign Nukta ..Takri Sign Nukta + (0x16f8f, 0x16f92,), # Miao Tone Right ..Miao Tone Below + (0x1d167, 0x1d169,), # Musical Symbol Combining..Musical Symbol Combining + (0x1d17b, 0x1d182,), # Musical Symbol Combining..Musical Symbol Combining + (0x1d185, 0x1d18b,), # Musical Symbol Combining..Musical Symbol Combining + (0x1d1aa, 0x1d1ad,), # Musical Symbol Combining..Musical Symbol Combining + (0x1d242, 0x1d244,), # Combining Greek Musical ..Combining Greek Musical + (0xe0100, 0xe01ef,), # Variation Selector-17 ..Variation Selector-256 + ), + '6.2.0': ( + # Source: DerivedGeneralCategory-6.2.0.txt + # Date: 2012-05-20, 00:42:34 GMT [MD] + # + (0x00300, 0x0036f,), # Combining Grave Accent ..Combining Latin Small Le + (0x00483, 0x00489,), # Combining Cyrillic Titlo..Combining Cyrillic Milli + (0x00591, 0x005bd,), # Hebrew Accent Etnahta ..Hebrew Point Meteg + (0x005bf, 0x005bf,), # Hebrew Point Rafe ..Hebrew Point Rafe + (0x005c1, 0x005c2,), # Hebrew Point Shin Dot ..Hebrew Point Sin Dot + (0x005c4, 0x005c5,), # Hebrew Mark Upper Dot ..Hebrew Mark Lower Dot + (0x005c7, 0x005c7,), # Hebrew Point Qamats Qata..Hebrew Point Qamats Qata + (0x00610, 0x0061a,), # Arabic Sign Sallallahou ..Arabic Small Kasra + (0x0064b, 0x0065f,), # Arabic Fathatan ..Arabic Wavy Hamza Below + (0x00670, 0x00670,), # Arabic Letter Superscrip..Arabic Letter Superscrip + (0x006d6, 0x006dc,), # Arabic Small High Ligatu..Arabic Small High Seen + (0x006df, 0x006e4,), # Arabic Small High Rounde..Arabic Small High Madda + (0x006e7, 0x006e8,), # Arabic Small High Yeh ..Arabic Small High Noon + (0x006ea, 0x006ed,), # Arabic Empty Centre Low ..Arabic Small Low Meem + (0x00711, 0x00711,), # Syriac Letter Superscrip..Syriac Letter Superscrip + (0x00730, 0x0074a,), # Syriac Pthaha Above ..Syriac Barrekh + (0x007a6, 0x007b0,), # Thaana Abafili ..Thaana Sukun + (0x007eb, 0x007f3,), # Nko Combining Short High..Nko Combining Double Dot + (0x00816, 0x00819,), # Samaritan Mark In ..Samaritan Mark Dagesh + (0x0081b, 0x00823,), # Samaritan Mark Epentheti..Samaritan Vowel Sign A + (0x00825, 0x00827,), # Samaritan Vowel Sign Sho..Samaritan Vowel Sign U + (0x00829, 0x0082d,), # Samaritan Vowel Sign Lon..Samaritan Mark Nequdaa + (0x00859, 0x0085b,), # Mandaic Affrication Mark..Mandaic Gemination Mark + (0x008e4, 0x008fe,), # Arabic Curly Fatha ..Arabic Damma With Dot + (0x00900, 0x00902,), # Devanagari Sign Inverted..Devanagari Sign Anusvara + (0x0093a, 0x0093a,), # Devanagari Vowel Sign Oe..Devanagari Vowel Sign Oe + (0x0093c, 0x0093c,), # Devanagari Sign Nukta ..Devanagari Sign Nukta + (0x00941, 0x00948,), # Devanagari Vowel Sign U ..Devanagari Vowel Sign Ai + (0x0094d, 0x0094d,), # Devanagari Sign Virama ..Devanagari Sign Virama + (0x00951, 0x00957,), # Devanagari Stress Sign U..Devanagari Vowel Sign Uu + (0x00962, 0x00963,), # Devanagari Vowel Sign Vo..Devanagari Vowel Sign Vo + (0x00981, 0x00981,), # Bengali Sign Candrabindu..Bengali Sign Candrabindu + (0x009bc, 0x009bc,), # Bengali Sign Nukta ..Bengali Sign Nukta + (0x009c1, 0x009c4,), # Bengali Vowel Sign U ..Bengali Vowel Sign Vocal + (0x009cd, 0x009cd,), # Bengali Sign Virama ..Bengali Sign Virama + (0x009e2, 0x009e3,), # Bengali Vowel Sign Vocal..Bengali Vowel Sign Vocal + (0x00a01, 0x00a02,), # Gurmukhi Sign Adak Bindi..Gurmukhi Sign Bindi + (0x00a3c, 0x00a3c,), # Gurmukhi Sign Nukta ..Gurmukhi Sign Nukta + (0x00a41, 0x00a42,), # Gurmukhi Vowel Sign U ..Gurmukhi Vowel Sign Uu + (0x00a47, 0x00a48,), # Gurmukhi Vowel Sign Ee ..Gurmukhi Vowel Sign Ai + (0x00a4b, 0x00a4d,), # Gurmukhi Vowel Sign Oo ..Gurmukhi Sign Virama + (0x00a51, 0x00a51,), # Gurmukhi Sign Udaat ..Gurmukhi Sign Udaat + (0x00a70, 0x00a71,), # Gurmukhi Tippi ..Gurmukhi Addak + (0x00a75, 0x00a75,), # Gurmukhi Sign Yakash ..Gurmukhi Sign Yakash + (0x00a81, 0x00a82,), # Gujarati Sign Candrabind..Gujarati Sign Anusvara + (0x00abc, 0x00abc,), # Gujarati Sign Nukta ..Gujarati Sign Nukta + (0x00ac1, 0x00ac5,), # Gujarati Vowel Sign U ..Gujarati Vowel Sign Cand + (0x00ac7, 0x00ac8,), # Gujarati Vowel Sign E ..Gujarati Vowel Sign Ai + (0x00acd, 0x00acd,), # Gujarati Sign Virama ..Gujarati Sign Virama + (0x00ae2, 0x00ae3,), # Gujarati Vowel Sign Voca..Gujarati Vowel Sign Voca + (0x00b01, 0x00b01,), # Oriya Sign Candrabindu ..Oriya Sign Candrabindu + (0x00b3c, 0x00b3c,), # Oriya Sign Nukta ..Oriya Sign Nukta + (0x00b3f, 0x00b3f,), # Oriya Vowel Sign I ..Oriya Vowel Sign I + (0x00b41, 0x00b44,), # Oriya Vowel Sign U ..Oriya Vowel Sign Vocalic + (0x00b4d, 0x00b4d,), # Oriya Sign Virama ..Oriya Sign Virama + (0x00b56, 0x00b56,), # Oriya Ai Length Mark ..Oriya Ai Length Mark + (0x00b62, 0x00b63,), # Oriya Vowel Sign Vocalic..Oriya Vowel Sign Vocalic + (0x00b82, 0x00b82,), # Tamil Sign Anusvara ..Tamil Sign Anusvara + (0x00bc0, 0x00bc0,), # Tamil Vowel Sign Ii ..Tamil Vowel Sign Ii + (0x00bcd, 0x00bcd,), # Tamil Sign Virama ..Tamil Sign Virama + (0x00c3e, 0x00c40,), # Telugu Vowel Sign Aa ..Telugu Vowel Sign Ii + (0x00c46, 0x00c48,), # Telugu Vowel Sign E ..Telugu Vowel Sign Ai + (0x00c4a, 0x00c4d,), # Telugu Vowel Sign O ..Telugu Sign Virama + (0x00c55, 0x00c56,), # Telugu Length Mark ..Telugu Ai Length Mark + (0x00c62, 0x00c63,), # Telugu Vowel Sign Vocali..Telugu Vowel Sign Vocali + (0x00cbc, 0x00cbc,), # Kannada Sign Nukta ..Kannada Sign Nukta + (0x00cbf, 0x00cbf,), # Kannada Vowel Sign I ..Kannada Vowel Sign I + (0x00cc6, 0x00cc6,), # Kannada Vowel Sign E ..Kannada Vowel Sign E + (0x00ccc, 0x00ccd,), # Kannada Vowel Sign Au ..Kannada Sign Virama + (0x00ce2, 0x00ce3,), # Kannada Vowel Sign Vocal..Kannada Vowel Sign Vocal + (0x00d41, 0x00d44,), # Malayalam Vowel Sign U ..Malayalam Vowel Sign Voc + (0x00d4d, 0x00d4d,), # Malayalam Sign Virama ..Malayalam Sign Virama + (0x00d62, 0x00d63,), # Malayalam Vowel Sign Voc..Malayalam Vowel Sign Voc + (0x00dca, 0x00dca,), # Sinhala Sign Al-lakuna ..Sinhala Sign Al-lakuna + (0x00dd2, 0x00dd4,), # Sinhala Vowel Sign Ketti..Sinhala Vowel Sign Ketti + (0x00dd6, 0x00dd6,), # Sinhala Vowel Sign Diga ..Sinhala Vowel Sign Diga + (0x00e31, 0x00e31,), # Thai Character Mai Han-a..Thai Character Mai Han-a + (0x00e34, 0x00e3a,), # Thai Character Sara I ..Thai Character Phinthu + (0x00e47, 0x00e4e,), # Thai Character Maitaikhu..Thai Character Yamakkan + (0x00eb1, 0x00eb1,), # Lao Vowel Sign Mai Kan ..Lao Vowel Sign Mai Kan + (0x00eb4, 0x00eb9,), # Lao Vowel Sign I ..Lao Vowel Sign Uu + (0x00ebb, 0x00ebc,), # Lao Vowel Sign Mai Kon ..Lao Semivowel Sign Lo + (0x00ec8, 0x00ecd,), # Lao Tone Mai Ek ..Lao Niggahita + (0x00f18, 0x00f19,), # Tibetan Astrological Sig..Tibetan Astrological Sig + (0x00f35, 0x00f35,), # Tibetan Mark Ngas Bzung ..Tibetan Mark Ngas Bzung + (0x00f37, 0x00f37,), # Tibetan Mark Ngas Bzung ..Tibetan Mark Ngas Bzung + (0x00f39, 0x00f39,), # Tibetan Mark Tsa -phru ..Tibetan Mark Tsa -phru + (0x00f71, 0x00f7e,), # Tibetan Vowel Sign Aa ..Tibetan Sign Rjes Su Nga + (0x00f80, 0x00f84,), # Tibetan Vowel Sign Rever..Tibetan Mark Halanta + (0x00f86, 0x00f87,), # Tibetan Sign Lci Rtags ..Tibetan Sign Yang Rtags + (0x00f8d, 0x00f97,), # Tibetan Subjoined Sign L..Tibetan Subjoined Letter + (0x00f99, 0x00fbc,), # Tibetan Subjoined Letter..Tibetan Subjoined Letter + (0x00fc6, 0x00fc6,), # Tibetan Symbol Padma Gda..Tibetan Symbol Padma Gda + (0x0102d, 0x01030,), # Myanmar Vowel Sign I ..Myanmar Vowel Sign Uu + (0x01032, 0x01037,), # Myanmar Vowel Sign Ai ..Myanmar Sign Dot Below + (0x01039, 0x0103a,), # Myanmar Sign Virama ..Myanmar Sign Asat + (0x0103d, 0x0103e,), # Myanmar Consonant Sign M..Myanmar Consonant Sign M + (0x01058, 0x01059,), # Myanmar Vowel Sign Vocal..Myanmar Vowel Sign Vocal + (0x0105e, 0x01060,), # Myanmar Consonant Sign M..Myanmar Consonant Sign M + (0x01071, 0x01074,), # Myanmar Vowel Sign Geba ..Myanmar Vowel Sign Kayah + (0x01082, 0x01082,), # Myanmar Consonant Sign S..Myanmar Consonant Sign S + (0x01085, 0x01086,), # Myanmar Vowel Sign Shan ..Myanmar Vowel Sign Shan + (0x0108d, 0x0108d,), # Myanmar Sign Shan Counci..Myanmar Sign Shan Counci + (0x0109d, 0x0109d,), # Myanmar Vowel Sign Aiton..Myanmar Vowel Sign Aiton + (0x0135d, 0x0135f,), # Ethiopic Combining Gemin..Ethiopic Combining Gemin + (0x01712, 0x01714,), # Tagalog Vowel Sign I ..Tagalog Sign Virama + (0x01732, 0x01734,), # Hanunoo Vowel Sign I ..Hanunoo Sign Pamudpod + (0x01752, 0x01753,), # Buhid Vowel Sign I ..Buhid Vowel Sign U + (0x01772, 0x01773,), # Tagbanwa Vowel Sign I ..Tagbanwa Vowel Sign U + (0x017b4, 0x017b5,), # Khmer Vowel Inherent Aq ..Khmer Vowel Inherent Aa + (0x017b7, 0x017bd,), # Khmer Vowel Sign I ..Khmer Vowel Sign Ua + (0x017c6, 0x017c6,), # Khmer Sign Nikahit ..Khmer Sign Nikahit + (0x017c9, 0x017d3,), # Khmer Sign Muusikatoan ..Khmer Sign Bathamasat + (0x017dd, 0x017dd,), # Khmer Sign Atthacan ..Khmer Sign Atthacan + (0x0180b, 0x0180d,), # Mongolian Free Variation..Mongolian Free Variation + (0x018a9, 0x018a9,), # Mongolian Letter Ali Gal..Mongolian Letter Ali Gal + (0x01920, 0x01922,), # Limbu Vowel Sign A ..Limbu Vowel Sign U + (0x01927, 0x01928,), # Limbu Vowel Sign E ..Limbu Vowel Sign O + (0x01932, 0x01932,), # Limbu Small Letter Anusv..Limbu Small Letter Anusv + (0x01939, 0x0193b,), # Limbu Sign Mukphreng ..Limbu Sign Sa-i + (0x01a17, 0x01a18,), # Buginese Vowel Sign I ..Buginese Vowel Sign U + (0x01a56, 0x01a56,), # Tai Tham Consonant Sign ..Tai Tham Consonant Sign + (0x01a58, 0x01a5e,), # Tai Tham Sign Mai Kang L..Tai Tham Consonant Sign + (0x01a60, 0x01a60,), # Tai Tham Sign Sakot ..Tai Tham Sign Sakot + (0x01a62, 0x01a62,), # Tai Tham Vowel Sign Mai ..Tai Tham Vowel Sign Mai + (0x01a65, 0x01a6c,), # Tai Tham Vowel Sign I ..Tai Tham Vowel Sign Oa B + (0x01a73, 0x01a7c,), # Tai Tham Vowel Sign Oa A..Tai Tham Sign Khuen-lue + (0x01a7f, 0x01a7f,), # Tai Tham Combining Crypt..Tai Tham Combining Crypt + (0x01b00, 0x01b03,), # Balinese Sign Ulu Ricem ..Balinese Sign Surang + (0x01b34, 0x01b34,), # Balinese Sign Rerekan ..Balinese Sign Rerekan + (0x01b36, 0x01b3a,), # Balinese Vowel Sign Ulu ..Balinese Vowel Sign Ra R + (0x01b3c, 0x01b3c,), # Balinese Vowel Sign La L..Balinese Vowel Sign La L + (0x01b42, 0x01b42,), # Balinese Vowel Sign Pepe..Balinese Vowel Sign Pepe + (0x01b6b, 0x01b73,), # Balinese Musical Symbol ..Balinese Musical Symbol + (0x01b80, 0x01b81,), # Sundanese Sign Panyecek ..Sundanese Sign Panglayar + (0x01ba2, 0x01ba5,), # Sundanese Consonant Sign..Sundanese Vowel Sign Pan + (0x01ba8, 0x01ba9,), # Sundanese Vowel Sign Pam..Sundanese Vowel Sign Pan + (0x01bab, 0x01bab,), # Sundanese Sign Virama ..Sundanese Sign Virama + (0x01be6, 0x01be6,), # Batak Sign Tompi ..Batak Sign Tompi + (0x01be8, 0x01be9,), # Batak Vowel Sign Pakpak ..Batak Vowel Sign Ee + (0x01bed, 0x01bed,), # Batak Vowel Sign Karo O ..Batak Vowel Sign Karo O + (0x01bef, 0x01bf1,), # Batak Vowel Sign U For S..Batak Consonant Sign H + (0x01c2c, 0x01c33,), # Lepcha Vowel Sign E ..Lepcha Consonant Sign T + (0x01c36, 0x01c37,), # Lepcha Sign Ran ..Lepcha Sign Nukta + (0x01cd0, 0x01cd2,), # Vedic Tone Karshana ..Vedic Tone Prenkha + (0x01cd4, 0x01ce0,), # Vedic Sign Yajurvedic Mi..Vedic Tone Rigvedic Kash + (0x01ce2, 0x01ce8,), # Vedic Sign Visarga Svari..Vedic Sign Visarga Anuda + (0x01ced, 0x01ced,), # Vedic Sign Tiryak ..Vedic Sign Tiryak + (0x01cf4, 0x01cf4,), # Vedic Tone Candra Above ..Vedic Tone Candra Above + (0x01dc0, 0x01de6,), # Combining Dotted Grave A..Combining Latin Small Le + (0x01dfc, 0x01dff,), # Combining Double Inverte..Combining Right Arrowhea + (0x020d0, 0x020f0,), # Combining Left Harpoon A..Combining Asterisk Above + (0x02cef, 0x02cf1,), # Coptic Combining Ni Abov..Coptic Combining Spiritu + (0x02d7f, 0x02d7f,), # Tifinagh Consonant Joine..Tifinagh Consonant Joine + (0x02de0, 0x02dff,), # Combining Cyrillic Lette..Combining Cyrillic Lette + (0x0302a, 0x0302d,), # Ideographic Level Tone M..Ideographic Entering Ton + (0x03099, 0x0309a,), # Combining Katakana-hirag..Combining Katakana-hirag + (0x0a66f, 0x0a672,), # Combining Cyrillic Vzmet..Combining Cyrillic Thous + (0x0a674, 0x0a67d,), # Combining Cyrillic Lette..Combining Cyrillic Payer + (0x0a69f, 0x0a69f,), # Combining Cyrillic Lette..Combining Cyrillic Lette + (0x0a6f0, 0x0a6f1,), # Bamum Combining Mark Koq..Bamum Combining Mark Tuk + (0x0a802, 0x0a802,), # Syloti Nagri Sign Dvisva..Syloti Nagri Sign Dvisva + (0x0a806, 0x0a806,), # Syloti Nagri Sign Hasant..Syloti Nagri Sign Hasant + (0x0a80b, 0x0a80b,), # Syloti Nagri Sign Anusva..Syloti Nagri Sign Anusva + (0x0a825, 0x0a826,), # Syloti Nagri Vowel Sign ..Syloti Nagri Vowel Sign + (0x0a8c4, 0x0a8c4,), # Saurashtra Sign Virama ..Saurashtra Sign Virama + (0x0a8e0, 0x0a8f1,), # Combining Devanagari Dig..Combining Devanagari Sig + (0x0a926, 0x0a92d,), # Kayah Li Vowel Ue ..Kayah Li Tone Calya Plop + (0x0a947, 0x0a951,), # Rejang Vowel Sign I ..Rejang Consonant Sign R + (0x0a980, 0x0a982,), # Javanese Sign Panyangga ..Javanese Sign Layar + (0x0a9b3, 0x0a9b3,), # Javanese Sign Cecak Telu..Javanese Sign Cecak Telu + (0x0a9b6, 0x0a9b9,), # Javanese Vowel Sign Wulu..Javanese Vowel Sign Suku + (0x0a9bc, 0x0a9bc,), # Javanese Vowel Sign Pepe..Javanese Vowel Sign Pepe + (0x0aa29, 0x0aa2e,), # Cham Vowel Sign Aa ..Cham Vowel Sign Oe + (0x0aa31, 0x0aa32,), # Cham Vowel Sign Au ..Cham Vowel Sign Ue + (0x0aa35, 0x0aa36,), # Cham Consonant Sign La ..Cham Consonant Sign Wa + (0x0aa43, 0x0aa43,), # Cham Consonant Sign Fina..Cham Consonant Sign Fina + (0x0aa4c, 0x0aa4c,), # Cham Consonant Sign Fina..Cham Consonant Sign Fina + (0x0aab0, 0x0aab0,), # Tai Viet Mai Kang ..Tai Viet Mai Kang + (0x0aab2, 0x0aab4,), # Tai Viet Vowel I ..Tai Viet Vowel U + (0x0aab7, 0x0aab8,), # Tai Viet Mai Khit ..Tai Viet Vowel Ia + (0x0aabe, 0x0aabf,), # Tai Viet Vowel Am ..Tai Viet Tone Mai Ek + (0x0aac1, 0x0aac1,), # Tai Viet Tone Mai Tho ..Tai Viet Tone Mai Tho + (0x0aaec, 0x0aaed,), # Meetei Mayek Vowel Sign ..Meetei Mayek Vowel Sign + (0x0aaf6, 0x0aaf6,), # Meetei Mayek Virama ..Meetei Mayek Virama + (0x0abe5, 0x0abe5,), # Meetei Mayek Vowel Sign ..Meetei Mayek Vowel Sign + (0x0abe8, 0x0abe8,), # Meetei Mayek Vowel Sign ..Meetei Mayek Vowel Sign + (0x0abed, 0x0abed,), # Meetei Mayek Apun Iyek ..Meetei Mayek Apun Iyek + (0x0fb1e, 0x0fb1e,), # Hebrew Point Judeo-spani..Hebrew Point Judeo-spani + (0x0fe00, 0x0fe0f,), # Variation Selector-1 ..Variation Selector-16 + (0x0fe20, 0x0fe26,), # Combining Ligature Left ..Combining Conjoining Mac + (0x101fd, 0x101fd,), # Phaistos Disc Sign Combi..Phaistos Disc Sign Combi + (0x10a01, 0x10a03,), # Kharoshthi Vowel Sign I ..Kharoshthi Vowel Sign Vo + (0x10a05, 0x10a06,), # Kharoshthi Vowel Sign E ..Kharoshthi Vowel Sign O + (0x10a0c, 0x10a0f,), # Kharoshthi Vowel Length ..Kharoshthi Sign Visarga + (0x10a38, 0x10a3a,), # Kharoshthi Sign Bar Abov..Kharoshthi Sign Dot Belo + (0x10a3f, 0x10a3f,), # Kharoshthi Virama ..Kharoshthi Virama + (0x11001, 0x11001,), # Brahmi Sign Anusvara ..Brahmi Sign Anusvara + (0x11038, 0x11046,), # Brahmi Vowel Sign Aa ..Brahmi Virama + (0x11080, 0x11081,), # Kaithi Sign Candrabindu ..Kaithi Sign Anusvara + (0x110b3, 0x110b6,), # Kaithi Vowel Sign U ..Kaithi Vowel Sign Ai + (0x110b9, 0x110ba,), # Kaithi Sign Virama ..Kaithi Sign Nukta + (0x11100, 0x11102,), # Chakma Sign Candrabindu ..Chakma Sign Visarga + (0x11127, 0x1112b,), # Chakma Vowel Sign A ..Chakma Vowel Sign Uu + (0x1112d, 0x11134,), # Chakma Vowel Sign Ai ..Chakma Maayyaa + (0x11180, 0x11181,), # Sharada Sign Candrabindu..Sharada Sign Anusvara + (0x111b6, 0x111be,), # Sharada Vowel Sign U ..Sharada Vowel Sign O + (0x116ab, 0x116ab,), # Takri Sign Anusvara ..Takri Sign Anusvara + (0x116ad, 0x116ad,), # Takri Vowel Sign Aa ..Takri Vowel Sign Aa + (0x116b0, 0x116b5,), # Takri Vowel Sign U ..Takri Vowel Sign Au + (0x116b7, 0x116b7,), # Takri Sign Nukta ..Takri Sign Nukta + (0x16f8f, 0x16f92,), # Miao Tone Right ..Miao Tone Below + (0x1d167, 0x1d169,), # Musical Symbol Combining..Musical Symbol Combining + (0x1d17b, 0x1d182,), # Musical Symbol Combining..Musical Symbol Combining + (0x1d185, 0x1d18b,), # Musical Symbol Combining..Musical Symbol Combining + (0x1d1aa, 0x1d1ad,), # Musical Symbol Combining..Musical Symbol Combining + (0x1d242, 0x1d244,), # Combining Greek Musical ..Combining Greek Musical + (0xe0100, 0xe01ef,), # Variation Selector-17 ..Variation Selector-256 + ), + '6.3.0': ( + # Source: DerivedGeneralCategory-6.3.0.txt + # Date: 2013-07-05, 14:08:45 GMT [MD] + # + (0x00300, 0x0036f,), # Combining Grave Accent ..Combining Latin Small Le + (0x00483, 0x00489,), # Combining Cyrillic Titlo..Combining Cyrillic Milli + (0x00591, 0x005bd,), # Hebrew Accent Etnahta ..Hebrew Point Meteg + (0x005bf, 0x005bf,), # Hebrew Point Rafe ..Hebrew Point Rafe + (0x005c1, 0x005c2,), # Hebrew Point Shin Dot ..Hebrew Point Sin Dot + (0x005c4, 0x005c5,), # Hebrew Mark Upper Dot ..Hebrew Mark Lower Dot + (0x005c7, 0x005c7,), # Hebrew Point Qamats Qata..Hebrew Point Qamats Qata + (0x00610, 0x0061a,), # Arabic Sign Sallallahou ..Arabic Small Kasra + (0x0064b, 0x0065f,), # Arabic Fathatan ..Arabic Wavy Hamza Below + (0x00670, 0x00670,), # Arabic Letter Superscrip..Arabic Letter Superscrip + (0x006d6, 0x006dc,), # Arabic Small High Ligatu..Arabic Small High Seen + (0x006df, 0x006e4,), # Arabic Small High Rounde..Arabic Small High Madda + (0x006e7, 0x006e8,), # Arabic Small High Yeh ..Arabic Small High Noon + (0x006ea, 0x006ed,), # Arabic Empty Centre Low ..Arabic Small Low Meem + (0x00711, 0x00711,), # Syriac Letter Superscrip..Syriac Letter Superscrip + (0x00730, 0x0074a,), # Syriac Pthaha Above ..Syriac Barrekh + (0x007a6, 0x007b0,), # Thaana Abafili ..Thaana Sukun + (0x007eb, 0x007f3,), # Nko Combining Short High..Nko Combining Double Dot + (0x00816, 0x00819,), # Samaritan Mark In ..Samaritan Mark Dagesh + (0x0081b, 0x00823,), # Samaritan Mark Epentheti..Samaritan Vowel Sign A + (0x00825, 0x00827,), # Samaritan Vowel Sign Sho..Samaritan Vowel Sign U + (0x00829, 0x0082d,), # Samaritan Vowel Sign Lon..Samaritan Mark Nequdaa + (0x00859, 0x0085b,), # Mandaic Affrication Mark..Mandaic Gemination Mark + (0x008e4, 0x008fe,), # Arabic Curly Fatha ..Arabic Damma With Dot + (0x00900, 0x00902,), # Devanagari Sign Inverted..Devanagari Sign Anusvara + (0x0093a, 0x0093a,), # Devanagari Vowel Sign Oe..Devanagari Vowel Sign Oe + (0x0093c, 0x0093c,), # Devanagari Sign Nukta ..Devanagari Sign Nukta + (0x00941, 0x00948,), # Devanagari Vowel Sign U ..Devanagari Vowel Sign Ai + (0x0094d, 0x0094d,), # Devanagari Sign Virama ..Devanagari Sign Virama + (0x00951, 0x00957,), # Devanagari Stress Sign U..Devanagari Vowel Sign Uu + (0x00962, 0x00963,), # Devanagari Vowel Sign Vo..Devanagari Vowel Sign Vo + (0x00981, 0x00981,), # Bengali Sign Candrabindu..Bengali Sign Candrabindu + (0x009bc, 0x009bc,), # Bengali Sign Nukta ..Bengali Sign Nukta + (0x009c1, 0x009c4,), # Bengali Vowel Sign U ..Bengali Vowel Sign Vocal + (0x009cd, 0x009cd,), # Bengali Sign Virama ..Bengali Sign Virama + (0x009e2, 0x009e3,), # Bengali Vowel Sign Vocal..Bengali Vowel Sign Vocal + (0x00a01, 0x00a02,), # Gurmukhi Sign Adak Bindi..Gurmukhi Sign Bindi + (0x00a3c, 0x00a3c,), # Gurmukhi Sign Nukta ..Gurmukhi Sign Nukta + (0x00a41, 0x00a42,), # Gurmukhi Vowel Sign U ..Gurmukhi Vowel Sign Uu + (0x00a47, 0x00a48,), # Gurmukhi Vowel Sign Ee ..Gurmukhi Vowel Sign Ai + (0x00a4b, 0x00a4d,), # Gurmukhi Vowel Sign Oo ..Gurmukhi Sign Virama + (0x00a51, 0x00a51,), # Gurmukhi Sign Udaat ..Gurmukhi Sign Udaat + (0x00a70, 0x00a71,), # Gurmukhi Tippi ..Gurmukhi Addak + (0x00a75, 0x00a75,), # Gurmukhi Sign Yakash ..Gurmukhi Sign Yakash + (0x00a81, 0x00a82,), # Gujarati Sign Candrabind..Gujarati Sign Anusvara + (0x00abc, 0x00abc,), # Gujarati Sign Nukta ..Gujarati Sign Nukta + (0x00ac1, 0x00ac5,), # Gujarati Vowel Sign U ..Gujarati Vowel Sign Cand + (0x00ac7, 0x00ac8,), # Gujarati Vowel Sign E ..Gujarati Vowel Sign Ai + (0x00acd, 0x00acd,), # Gujarati Sign Virama ..Gujarati Sign Virama + (0x00ae2, 0x00ae3,), # Gujarati Vowel Sign Voca..Gujarati Vowel Sign Voca + (0x00b01, 0x00b01,), # Oriya Sign Candrabindu ..Oriya Sign Candrabindu + (0x00b3c, 0x00b3c,), # Oriya Sign Nukta ..Oriya Sign Nukta + (0x00b3f, 0x00b3f,), # Oriya Vowel Sign I ..Oriya Vowel Sign I + (0x00b41, 0x00b44,), # Oriya Vowel Sign U ..Oriya Vowel Sign Vocalic + (0x00b4d, 0x00b4d,), # Oriya Sign Virama ..Oriya Sign Virama + (0x00b56, 0x00b56,), # Oriya Ai Length Mark ..Oriya Ai Length Mark + (0x00b62, 0x00b63,), # Oriya Vowel Sign Vocalic..Oriya Vowel Sign Vocalic + (0x00b82, 0x00b82,), # Tamil Sign Anusvara ..Tamil Sign Anusvara + (0x00bc0, 0x00bc0,), # Tamil Vowel Sign Ii ..Tamil Vowel Sign Ii + (0x00bcd, 0x00bcd,), # Tamil Sign Virama ..Tamil Sign Virama + (0x00c3e, 0x00c40,), # Telugu Vowel Sign Aa ..Telugu Vowel Sign Ii + (0x00c46, 0x00c48,), # Telugu Vowel Sign E ..Telugu Vowel Sign Ai + (0x00c4a, 0x00c4d,), # Telugu Vowel Sign O ..Telugu Sign Virama + (0x00c55, 0x00c56,), # Telugu Length Mark ..Telugu Ai Length Mark + (0x00c62, 0x00c63,), # Telugu Vowel Sign Vocali..Telugu Vowel Sign Vocali + (0x00cbc, 0x00cbc,), # Kannada Sign Nukta ..Kannada Sign Nukta + (0x00cbf, 0x00cbf,), # Kannada Vowel Sign I ..Kannada Vowel Sign I + (0x00cc6, 0x00cc6,), # Kannada Vowel Sign E ..Kannada Vowel Sign E + (0x00ccc, 0x00ccd,), # Kannada Vowel Sign Au ..Kannada Sign Virama + (0x00ce2, 0x00ce3,), # Kannada Vowel Sign Vocal..Kannada Vowel Sign Vocal + (0x00d41, 0x00d44,), # Malayalam Vowel Sign U ..Malayalam Vowel Sign Voc + (0x00d4d, 0x00d4d,), # Malayalam Sign Virama ..Malayalam Sign Virama + (0x00d62, 0x00d63,), # Malayalam Vowel Sign Voc..Malayalam Vowel Sign Voc + (0x00dca, 0x00dca,), # Sinhala Sign Al-lakuna ..Sinhala Sign Al-lakuna + (0x00dd2, 0x00dd4,), # Sinhala Vowel Sign Ketti..Sinhala Vowel Sign Ketti + (0x00dd6, 0x00dd6,), # Sinhala Vowel Sign Diga ..Sinhala Vowel Sign Diga + (0x00e31, 0x00e31,), # Thai Character Mai Han-a..Thai Character Mai Han-a + (0x00e34, 0x00e3a,), # Thai Character Sara I ..Thai Character Phinthu + (0x00e47, 0x00e4e,), # Thai Character Maitaikhu..Thai Character Yamakkan + (0x00eb1, 0x00eb1,), # Lao Vowel Sign Mai Kan ..Lao Vowel Sign Mai Kan + (0x00eb4, 0x00eb9,), # Lao Vowel Sign I ..Lao Vowel Sign Uu + (0x00ebb, 0x00ebc,), # Lao Vowel Sign Mai Kon ..Lao Semivowel Sign Lo + (0x00ec8, 0x00ecd,), # Lao Tone Mai Ek ..Lao Niggahita + (0x00f18, 0x00f19,), # Tibetan Astrological Sig..Tibetan Astrological Sig + (0x00f35, 0x00f35,), # Tibetan Mark Ngas Bzung ..Tibetan Mark Ngas Bzung + (0x00f37, 0x00f37,), # Tibetan Mark Ngas Bzung ..Tibetan Mark Ngas Bzung + (0x00f39, 0x00f39,), # Tibetan Mark Tsa -phru ..Tibetan Mark Tsa -phru + (0x00f71, 0x00f7e,), # Tibetan Vowel Sign Aa ..Tibetan Sign Rjes Su Nga + (0x00f80, 0x00f84,), # Tibetan Vowel Sign Rever..Tibetan Mark Halanta + (0x00f86, 0x00f87,), # Tibetan Sign Lci Rtags ..Tibetan Sign Yang Rtags + (0x00f8d, 0x00f97,), # Tibetan Subjoined Sign L..Tibetan Subjoined Letter + (0x00f99, 0x00fbc,), # Tibetan Subjoined Letter..Tibetan Subjoined Letter + (0x00fc6, 0x00fc6,), # Tibetan Symbol Padma Gda..Tibetan Symbol Padma Gda + (0x0102d, 0x01030,), # Myanmar Vowel Sign I ..Myanmar Vowel Sign Uu + (0x01032, 0x01037,), # Myanmar Vowel Sign Ai ..Myanmar Sign Dot Below + (0x01039, 0x0103a,), # Myanmar Sign Virama ..Myanmar Sign Asat + (0x0103d, 0x0103e,), # Myanmar Consonant Sign M..Myanmar Consonant Sign M + (0x01058, 0x01059,), # Myanmar Vowel Sign Vocal..Myanmar Vowel Sign Vocal + (0x0105e, 0x01060,), # Myanmar Consonant Sign M..Myanmar Consonant Sign M + (0x01071, 0x01074,), # Myanmar Vowel Sign Geba ..Myanmar Vowel Sign Kayah + (0x01082, 0x01082,), # Myanmar Consonant Sign S..Myanmar Consonant Sign S + (0x01085, 0x01086,), # Myanmar Vowel Sign Shan ..Myanmar Vowel Sign Shan + (0x0108d, 0x0108d,), # Myanmar Sign Shan Counci..Myanmar Sign Shan Counci + (0x0109d, 0x0109d,), # Myanmar Vowel Sign Aiton..Myanmar Vowel Sign Aiton + (0x0135d, 0x0135f,), # Ethiopic Combining Gemin..Ethiopic Combining Gemin + (0x01712, 0x01714,), # Tagalog Vowel Sign I ..Tagalog Sign Virama + (0x01732, 0x01734,), # Hanunoo Vowel Sign I ..Hanunoo Sign Pamudpod + (0x01752, 0x01753,), # Buhid Vowel Sign I ..Buhid Vowel Sign U + (0x01772, 0x01773,), # Tagbanwa Vowel Sign I ..Tagbanwa Vowel Sign U + (0x017b4, 0x017b5,), # Khmer Vowel Inherent Aq ..Khmer Vowel Inherent Aa + (0x017b7, 0x017bd,), # Khmer Vowel Sign I ..Khmer Vowel Sign Ua + (0x017c6, 0x017c6,), # Khmer Sign Nikahit ..Khmer Sign Nikahit + (0x017c9, 0x017d3,), # Khmer Sign Muusikatoan ..Khmer Sign Bathamasat + (0x017dd, 0x017dd,), # Khmer Sign Atthacan ..Khmer Sign Atthacan + (0x0180b, 0x0180d,), # Mongolian Free Variation..Mongolian Free Variation + (0x018a9, 0x018a9,), # Mongolian Letter Ali Gal..Mongolian Letter Ali Gal + (0x01920, 0x01922,), # Limbu Vowel Sign A ..Limbu Vowel Sign U + (0x01927, 0x01928,), # Limbu Vowel Sign E ..Limbu Vowel Sign O + (0x01932, 0x01932,), # Limbu Small Letter Anusv..Limbu Small Letter Anusv + (0x01939, 0x0193b,), # Limbu Sign Mukphreng ..Limbu Sign Sa-i + (0x01a17, 0x01a18,), # Buginese Vowel Sign I ..Buginese Vowel Sign U + (0x01a1b, 0x01a1b,), # Buginese Vowel Sign Ae ..Buginese Vowel Sign Ae + (0x01a56, 0x01a56,), # Tai Tham Consonant Sign ..Tai Tham Consonant Sign + (0x01a58, 0x01a5e,), # Tai Tham Sign Mai Kang L..Tai Tham Consonant Sign + (0x01a60, 0x01a60,), # Tai Tham Sign Sakot ..Tai Tham Sign Sakot + (0x01a62, 0x01a62,), # Tai Tham Vowel Sign Mai ..Tai Tham Vowel Sign Mai + (0x01a65, 0x01a6c,), # Tai Tham Vowel Sign I ..Tai Tham Vowel Sign Oa B + (0x01a73, 0x01a7c,), # Tai Tham Vowel Sign Oa A..Tai Tham Sign Khuen-lue + (0x01a7f, 0x01a7f,), # Tai Tham Combining Crypt..Tai Tham Combining Crypt + (0x01b00, 0x01b03,), # Balinese Sign Ulu Ricem ..Balinese Sign Surang + (0x01b34, 0x01b34,), # Balinese Sign Rerekan ..Balinese Sign Rerekan + (0x01b36, 0x01b3a,), # Balinese Vowel Sign Ulu ..Balinese Vowel Sign Ra R + (0x01b3c, 0x01b3c,), # Balinese Vowel Sign La L..Balinese Vowel Sign La L + (0x01b42, 0x01b42,), # Balinese Vowel Sign Pepe..Balinese Vowel Sign Pepe + (0x01b6b, 0x01b73,), # Balinese Musical Symbol ..Balinese Musical Symbol + (0x01b80, 0x01b81,), # Sundanese Sign Panyecek ..Sundanese Sign Panglayar + (0x01ba2, 0x01ba5,), # Sundanese Consonant Sign..Sundanese Vowel Sign Pan + (0x01ba8, 0x01ba9,), # Sundanese Vowel Sign Pam..Sundanese Vowel Sign Pan + (0x01bab, 0x01bab,), # Sundanese Sign Virama ..Sundanese Sign Virama + (0x01be6, 0x01be6,), # Batak Sign Tompi ..Batak Sign Tompi + (0x01be8, 0x01be9,), # Batak Vowel Sign Pakpak ..Batak Vowel Sign Ee + (0x01bed, 0x01bed,), # Batak Vowel Sign Karo O ..Batak Vowel Sign Karo O + (0x01bef, 0x01bf1,), # Batak Vowel Sign U For S..Batak Consonant Sign H + (0x01c2c, 0x01c33,), # Lepcha Vowel Sign E ..Lepcha Consonant Sign T + (0x01c36, 0x01c37,), # Lepcha Sign Ran ..Lepcha Sign Nukta + (0x01cd0, 0x01cd2,), # Vedic Tone Karshana ..Vedic Tone Prenkha + (0x01cd4, 0x01ce0,), # Vedic Sign Yajurvedic Mi..Vedic Tone Rigvedic Kash + (0x01ce2, 0x01ce8,), # Vedic Sign Visarga Svari..Vedic Sign Visarga Anuda + (0x01ced, 0x01ced,), # Vedic Sign Tiryak ..Vedic Sign Tiryak + (0x01cf4, 0x01cf4,), # Vedic Tone Candra Above ..Vedic Tone Candra Above + (0x01dc0, 0x01de6,), # Combining Dotted Grave A..Combining Latin Small Le + (0x01dfc, 0x01dff,), # Combining Double Inverte..Combining Right Arrowhea + (0x020d0, 0x020f0,), # Combining Left Harpoon A..Combining Asterisk Above + (0x02cef, 0x02cf1,), # Coptic Combining Ni Abov..Coptic Combining Spiritu + (0x02d7f, 0x02d7f,), # Tifinagh Consonant Joine..Tifinagh Consonant Joine + (0x02de0, 0x02dff,), # Combining Cyrillic Lette..Combining Cyrillic Lette + (0x0302a, 0x0302d,), # Ideographic Level Tone M..Ideographic Entering Ton + (0x03099, 0x0309a,), # Combining Katakana-hirag..Combining Katakana-hirag + (0x0a66f, 0x0a672,), # Combining Cyrillic Vzmet..Combining Cyrillic Thous + (0x0a674, 0x0a67d,), # Combining Cyrillic Lette..Combining Cyrillic Payer + (0x0a69f, 0x0a69f,), # Combining Cyrillic Lette..Combining Cyrillic Lette + (0x0a6f0, 0x0a6f1,), # Bamum Combining Mark Koq..Bamum Combining Mark Tuk + (0x0a802, 0x0a802,), # Syloti Nagri Sign Dvisva..Syloti Nagri Sign Dvisva + (0x0a806, 0x0a806,), # Syloti Nagri Sign Hasant..Syloti Nagri Sign Hasant + (0x0a80b, 0x0a80b,), # Syloti Nagri Sign Anusva..Syloti Nagri Sign Anusva + (0x0a825, 0x0a826,), # Syloti Nagri Vowel Sign ..Syloti Nagri Vowel Sign + (0x0a8c4, 0x0a8c4,), # Saurashtra Sign Virama ..Saurashtra Sign Virama + (0x0a8e0, 0x0a8f1,), # Combining Devanagari Dig..Combining Devanagari Sig + (0x0a926, 0x0a92d,), # Kayah Li Vowel Ue ..Kayah Li Tone Calya Plop + (0x0a947, 0x0a951,), # Rejang Vowel Sign I ..Rejang Consonant Sign R + (0x0a980, 0x0a982,), # Javanese Sign Panyangga ..Javanese Sign Layar + (0x0a9b3, 0x0a9b3,), # Javanese Sign Cecak Telu..Javanese Sign Cecak Telu + (0x0a9b6, 0x0a9b9,), # Javanese Vowel Sign Wulu..Javanese Vowel Sign Suku + (0x0a9bc, 0x0a9bc,), # Javanese Vowel Sign Pepe..Javanese Vowel Sign Pepe + (0x0aa29, 0x0aa2e,), # Cham Vowel Sign Aa ..Cham Vowel Sign Oe + (0x0aa31, 0x0aa32,), # Cham Vowel Sign Au ..Cham Vowel Sign Ue + (0x0aa35, 0x0aa36,), # Cham Consonant Sign La ..Cham Consonant Sign Wa + (0x0aa43, 0x0aa43,), # Cham Consonant Sign Fina..Cham Consonant Sign Fina + (0x0aa4c, 0x0aa4c,), # Cham Consonant Sign Fina..Cham Consonant Sign Fina + (0x0aab0, 0x0aab0,), # Tai Viet Mai Kang ..Tai Viet Mai Kang + (0x0aab2, 0x0aab4,), # Tai Viet Vowel I ..Tai Viet Vowel U + (0x0aab7, 0x0aab8,), # Tai Viet Mai Khit ..Tai Viet Vowel Ia + (0x0aabe, 0x0aabf,), # Tai Viet Vowel Am ..Tai Viet Tone Mai Ek + (0x0aac1, 0x0aac1,), # Tai Viet Tone Mai Tho ..Tai Viet Tone Mai Tho + (0x0aaec, 0x0aaed,), # Meetei Mayek Vowel Sign ..Meetei Mayek Vowel Sign + (0x0aaf6, 0x0aaf6,), # Meetei Mayek Virama ..Meetei Mayek Virama + (0x0abe5, 0x0abe5,), # Meetei Mayek Vowel Sign ..Meetei Mayek Vowel Sign + (0x0abe8, 0x0abe8,), # Meetei Mayek Vowel Sign ..Meetei Mayek Vowel Sign + (0x0abed, 0x0abed,), # Meetei Mayek Apun Iyek ..Meetei Mayek Apun Iyek + (0x0fb1e, 0x0fb1e,), # Hebrew Point Judeo-spani..Hebrew Point Judeo-spani + (0x0fe00, 0x0fe0f,), # Variation Selector-1 ..Variation Selector-16 + (0x0fe20, 0x0fe26,), # Combining Ligature Left ..Combining Conjoining Mac + (0x101fd, 0x101fd,), # Phaistos Disc Sign Combi..Phaistos Disc Sign Combi + (0x10a01, 0x10a03,), # Kharoshthi Vowel Sign I ..Kharoshthi Vowel Sign Vo + (0x10a05, 0x10a06,), # Kharoshthi Vowel Sign E ..Kharoshthi Vowel Sign O + (0x10a0c, 0x10a0f,), # Kharoshthi Vowel Length ..Kharoshthi Sign Visarga + (0x10a38, 0x10a3a,), # Kharoshthi Sign Bar Abov..Kharoshthi Sign Dot Belo + (0x10a3f, 0x10a3f,), # Kharoshthi Virama ..Kharoshthi Virama + (0x11001, 0x11001,), # Brahmi Sign Anusvara ..Brahmi Sign Anusvara + (0x11038, 0x11046,), # Brahmi Vowel Sign Aa ..Brahmi Virama + (0x11080, 0x11081,), # Kaithi Sign Candrabindu ..Kaithi Sign Anusvara + (0x110b3, 0x110b6,), # Kaithi Vowel Sign U ..Kaithi Vowel Sign Ai + (0x110b9, 0x110ba,), # Kaithi Sign Virama ..Kaithi Sign Nukta + (0x11100, 0x11102,), # Chakma Sign Candrabindu ..Chakma Sign Visarga + (0x11127, 0x1112b,), # Chakma Vowel Sign A ..Chakma Vowel Sign Uu + (0x1112d, 0x11134,), # Chakma Vowel Sign Ai ..Chakma Maayyaa + (0x11180, 0x11181,), # Sharada Sign Candrabindu..Sharada Sign Anusvara + (0x111b6, 0x111be,), # Sharada Vowel Sign U ..Sharada Vowel Sign O + (0x116ab, 0x116ab,), # Takri Sign Anusvara ..Takri Sign Anusvara + (0x116ad, 0x116ad,), # Takri Vowel Sign Aa ..Takri Vowel Sign Aa + (0x116b0, 0x116b5,), # Takri Vowel Sign U ..Takri Vowel Sign Au + (0x116b7, 0x116b7,), # Takri Sign Nukta ..Takri Sign Nukta + (0x16f8f, 0x16f92,), # Miao Tone Right ..Miao Tone Below + (0x1d167, 0x1d169,), # Musical Symbol Combining..Musical Symbol Combining + (0x1d17b, 0x1d182,), # Musical Symbol Combining..Musical Symbol Combining + (0x1d185, 0x1d18b,), # Musical Symbol Combining..Musical Symbol Combining + (0x1d1aa, 0x1d1ad,), # Musical Symbol Combining..Musical Symbol Combining + (0x1d242, 0x1d244,), # Combining Greek Musical ..Combining Greek Musical + (0xe0100, 0xe01ef,), # Variation Selector-17 ..Variation Selector-256 + ), + '7.0.0': ( + # Source: DerivedGeneralCategory-7.0.0.txt + # Date: 2014-02-07, 18:42:12 GMT [MD] + # + (0x00300, 0x0036f,), # Combining Grave Accent ..Combining Latin Small Le + (0x00483, 0x00489,), # Combining Cyrillic Titlo..Combining Cyrillic Milli + (0x00591, 0x005bd,), # Hebrew Accent Etnahta ..Hebrew Point Meteg + (0x005bf, 0x005bf,), # Hebrew Point Rafe ..Hebrew Point Rafe + (0x005c1, 0x005c2,), # Hebrew Point Shin Dot ..Hebrew Point Sin Dot + (0x005c4, 0x005c5,), # Hebrew Mark Upper Dot ..Hebrew Mark Lower Dot + (0x005c7, 0x005c7,), # Hebrew Point Qamats Qata..Hebrew Point Qamats Qata + (0x00610, 0x0061a,), # Arabic Sign Sallallahou ..Arabic Small Kasra + (0x0064b, 0x0065f,), # Arabic Fathatan ..Arabic Wavy Hamza Below + (0x00670, 0x00670,), # Arabic Letter Superscrip..Arabic Letter Superscrip + (0x006d6, 0x006dc,), # Arabic Small High Ligatu..Arabic Small High Seen + (0x006df, 0x006e4,), # Arabic Small High Rounde..Arabic Small High Madda + (0x006e7, 0x006e8,), # Arabic Small High Yeh ..Arabic Small High Noon + (0x006ea, 0x006ed,), # Arabic Empty Centre Low ..Arabic Small Low Meem + (0x00711, 0x00711,), # Syriac Letter Superscrip..Syriac Letter Superscrip + (0x00730, 0x0074a,), # Syriac Pthaha Above ..Syriac Barrekh + (0x007a6, 0x007b0,), # Thaana Abafili ..Thaana Sukun + (0x007eb, 0x007f3,), # Nko Combining Short High..Nko Combining Double Dot + (0x00816, 0x00819,), # Samaritan Mark In ..Samaritan Mark Dagesh + (0x0081b, 0x00823,), # Samaritan Mark Epentheti..Samaritan Vowel Sign A + (0x00825, 0x00827,), # Samaritan Vowel Sign Sho..Samaritan Vowel Sign U + (0x00829, 0x0082d,), # Samaritan Vowel Sign Lon..Samaritan Mark Nequdaa + (0x00859, 0x0085b,), # Mandaic Affrication Mark..Mandaic Gemination Mark + (0x008e4, 0x00902,), # Arabic Curly Fatha ..Devanagari Sign Anusvara + (0x0093a, 0x0093a,), # Devanagari Vowel Sign Oe..Devanagari Vowel Sign Oe + (0x0093c, 0x0093c,), # Devanagari Sign Nukta ..Devanagari Sign Nukta + (0x00941, 0x00948,), # Devanagari Vowel Sign U ..Devanagari Vowel Sign Ai + (0x0094d, 0x0094d,), # Devanagari Sign Virama ..Devanagari Sign Virama + (0x00951, 0x00957,), # Devanagari Stress Sign U..Devanagari Vowel Sign Uu + (0x00962, 0x00963,), # Devanagari Vowel Sign Vo..Devanagari Vowel Sign Vo + (0x00981, 0x00981,), # Bengali Sign Candrabindu..Bengali Sign Candrabindu + (0x009bc, 0x009bc,), # Bengali Sign Nukta ..Bengali Sign Nukta + (0x009c1, 0x009c4,), # Bengali Vowel Sign U ..Bengali Vowel Sign Vocal + (0x009cd, 0x009cd,), # Bengali Sign Virama ..Bengali Sign Virama + (0x009e2, 0x009e3,), # Bengali Vowel Sign Vocal..Bengali Vowel Sign Vocal + (0x00a01, 0x00a02,), # Gurmukhi Sign Adak Bindi..Gurmukhi Sign Bindi + (0x00a3c, 0x00a3c,), # Gurmukhi Sign Nukta ..Gurmukhi Sign Nukta + (0x00a41, 0x00a42,), # Gurmukhi Vowel Sign U ..Gurmukhi Vowel Sign Uu + (0x00a47, 0x00a48,), # Gurmukhi Vowel Sign Ee ..Gurmukhi Vowel Sign Ai + (0x00a4b, 0x00a4d,), # Gurmukhi Vowel Sign Oo ..Gurmukhi Sign Virama + (0x00a51, 0x00a51,), # Gurmukhi Sign Udaat ..Gurmukhi Sign Udaat + (0x00a70, 0x00a71,), # Gurmukhi Tippi ..Gurmukhi Addak + (0x00a75, 0x00a75,), # Gurmukhi Sign Yakash ..Gurmukhi Sign Yakash + (0x00a81, 0x00a82,), # Gujarati Sign Candrabind..Gujarati Sign Anusvara + (0x00abc, 0x00abc,), # Gujarati Sign Nukta ..Gujarati Sign Nukta + (0x00ac1, 0x00ac5,), # Gujarati Vowel Sign U ..Gujarati Vowel Sign Cand + (0x00ac7, 0x00ac8,), # Gujarati Vowel Sign E ..Gujarati Vowel Sign Ai + (0x00acd, 0x00acd,), # Gujarati Sign Virama ..Gujarati Sign Virama + (0x00ae2, 0x00ae3,), # Gujarati Vowel Sign Voca..Gujarati Vowel Sign Voca + (0x00b01, 0x00b01,), # Oriya Sign Candrabindu ..Oriya Sign Candrabindu + (0x00b3c, 0x00b3c,), # Oriya Sign Nukta ..Oriya Sign Nukta + (0x00b3f, 0x00b3f,), # Oriya Vowel Sign I ..Oriya Vowel Sign I + (0x00b41, 0x00b44,), # Oriya Vowel Sign U ..Oriya Vowel Sign Vocalic + (0x00b4d, 0x00b4d,), # Oriya Sign Virama ..Oriya Sign Virama + (0x00b56, 0x00b56,), # Oriya Ai Length Mark ..Oriya Ai Length Mark + (0x00b62, 0x00b63,), # Oriya Vowel Sign Vocalic..Oriya Vowel Sign Vocalic + (0x00b82, 0x00b82,), # Tamil Sign Anusvara ..Tamil Sign Anusvara + (0x00bc0, 0x00bc0,), # Tamil Vowel Sign Ii ..Tamil Vowel Sign Ii + (0x00bcd, 0x00bcd,), # Tamil Sign Virama ..Tamil Sign Virama + (0x00c00, 0x00c00,), # Telugu Sign Combining Ca..Telugu Sign Combining Ca + (0x00c3e, 0x00c40,), # Telugu Vowel Sign Aa ..Telugu Vowel Sign Ii + (0x00c46, 0x00c48,), # Telugu Vowel Sign E ..Telugu Vowel Sign Ai + (0x00c4a, 0x00c4d,), # Telugu Vowel Sign O ..Telugu Sign Virama + (0x00c55, 0x00c56,), # Telugu Length Mark ..Telugu Ai Length Mark + (0x00c62, 0x00c63,), # Telugu Vowel Sign Vocali..Telugu Vowel Sign Vocali + (0x00c81, 0x00c81,), # Kannada Sign Candrabindu..Kannada Sign Candrabindu + (0x00cbc, 0x00cbc,), # Kannada Sign Nukta ..Kannada Sign Nukta + (0x00cbf, 0x00cbf,), # Kannada Vowel Sign I ..Kannada Vowel Sign I + (0x00cc6, 0x00cc6,), # Kannada Vowel Sign E ..Kannada Vowel Sign E + (0x00ccc, 0x00ccd,), # Kannada Vowel Sign Au ..Kannada Sign Virama + (0x00ce2, 0x00ce3,), # Kannada Vowel Sign Vocal..Kannada Vowel Sign Vocal + (0x00d01, 0x00d01,), # Malayalam Sign Candrabin..Malayalam Sign Candrabin + (0x00d41, 0x00d44,), # Malayalam Vowel Sign U ..Malayalam Vowel Sign Voc + (0x00d4d, 0x00d4d,), # Malayalam Sign Virama ..Malayalam Sign Virama + (0x00d62, 0x00d63,), # Malayalam Vowel Sign Voc..Malayalam Vowel Sign Voc + (0x00dca, 0x00dca,), # Sinhala Sign Al-lakuna ..Sinhala Sign Al-lakuna + (0x00dd2, 0x00dd4,), # Sinhala Vowel Sign Ketti..Sinhala Vowel Sign Ketti + (0x00dd6, 0x00dd6,), # Sinhala Vowel Sign Diga ..Sinhala Vowel Sign Diga + (0x00e31, 0x00e31,), # Thai Character Mai Han-a..Thai Character Mai Han-a + (0x00e34, 0x00e3a,), # Thai Character Sara I ..Thai Character Phinthu + (0x00e47, 0x00e4e,), # Thai Character Maitaikhu..Thai Character Yamakkan + (0x00eb1, 0x00eb1,), # Lao Vowel Sign Mai Kan ..Lao Vowel Sign Mai Kan + (0x00eb4, 0x00eb9,), # Lao Vowel Sign I ..Lao Vowel Sign Uu + (0x00ebb, 0x00ebc,), # Lao Vowel Sign Mai Kon ..Lao Semivowel Sign Lo + (0x00ec8, 0x00ecd,), # Lao Tone Mai Ek ..Lao Niggahita + (0x00f18, 0x00f19,), # Tibetan Astrological Sig..Tibetan Astrological Sig + (0x00f35, 0x00f35,), # Tibetan Mark Ngas Bzung ..Tibetan Mark Ngas Bzung + (0x00f37, 0x00f37,), # Tibetan Mark Ngas Bzung ..Tibetan Mark Ngas Bzung + (0x00f39, 0x00f39,), # Tibetan Mark Tsa -phru ..Tibetan Mark Tsa -phru + (0x00f71, 0x00f7e,), # Tibetan Vowel Sign Aa ..Tibetan Sign Rjes Su Nga + (0x00f80, 0x00f84,), # Tibetan Vowel Sign Rever..Tibetan Mark Halanta + (0x00f86, 0x00f87,), # Tibetan Sign Lci Rtags ..Tibetan Sign Yang Rtags + (0x00f8d, 0x00f97,), # Tibetan Subjoined Sign L..Tibetan Subjoined Letter + (0x00f99, 0x00fbc,), # Tibetan Subjoined Letter..Tibetan Subjoined Letter + (0x00fc6, 0x00fc6,), # Tibetan Symbol Padma Gda..Tibetan Symbol Padma Gda + (0x0102d, 0x01030,), # Myanmar Vowel Sign I ..Myanmar Vowel Sign Uu + (0x01032, 0x01037,), # Myanmar Vowel Sign Ai ..Myanmar Sign Dot Below + (0x01039, 0x0103a,), # Myanmar Sign Virama ..Myanmar Sign Asat + (0x0103d, 0x0103e,), # Myanmar Consonant Sign M..Myanmar Consonant Sign M + (0x01058, 0x01059,), # Myanmar Vowel Sign Vocal..Myanmar Vowel Sign Vocal + (0x0105e, 0x01060,), # Myanmar Consonant Sign M..Myanmar Consonant Sign M + (0x01071, 0x01074,), # Myanmar Vowel Sign Geba ..Myanmar Vowel Sign Kayah + (0x01082, 0x01082,), # Myanmar Consonant Sign S..Myanmar Consonant Sign S + (0x01085, 0x01086,), # Myanmar Vowel Sign Shan ..Myanmar Vowel Sign Shan + (0x0108d, 0x0108d,), # Myanmar Sign Shan Counci..Myanmar Sign Shan Counci + (0x0109d, 0x0109d,), # Myanmar Vowel Sign Aiton..Myanmar Vowel Sign Aiton + (0x0135d, 0x0135f,), # Ethiopic Combining Gemin..Ethiopic Combining Gemin + (0x01712, 0x01714,), # Tagalog Vowel Sign I ..Tagalog Sign Virama + (0x01732, 0x01734,), # Hanunoo Vowel Sign I ..Hanunoo Sign Pamudpod + (0x01752, 0x01753,), # Buhid Vowel Sign I ..Buhid Vowel Sign U + (0x01772, 0x01773,), # Tagbanwa Vowel Sign I ..Tagbanwa Vowel Sign U + (0x017b4, 0x017b5,), # Khmer Vowel Inherent Aq ..Khmer Vowel Inherent Aa + (0x017b7, 0x017bd,), # Khmer Vowel Sign I ..Khmer Vowel Sign Ua + (0x017c6, 0x017c6,), # Khmer Sign Nikahit ..Khmer Sign Nikahit + (0x017c9, 0x017d3,), # Khmer Sign Muusikatoan ..Khmer Sign Bathamasat + (0x017dd, 0x017dd,), # Khmer Sign Atthacan ..Khmer Sign Atthacan + (0x0180b, 0x0180d,), # Mongolian Free Variation..Mongolian Free Variation + (0x018a9, 0x018a9,), # Mongolian Letter Ali Gal..Mongolian Letter Ali Gal + (0x01920, 0x01922,), # Limbu Vowel Sign A ..Limbu Vowel Sign U + (0x01927, 0x01928,), # Limbu Vowel Sign E ..Limbu Vowel Sign O + (0x01932, 0x01932,), # Limbu Small Letter Anusv..Limbu Small Letter Anusv + (0x01939, 0x0193b,), # Limbu Sign Mukphreng ..Limbu Sign Sa-i + (0x01a17, 0x01a18,), # Buginese Vowel Sign I ..Buginese Vowel Sign U + (0x01a1b, 0x01a1b,), # Buginese Vowel Sign Ae ..Buginese Vowel Sign Ae + (0x01a56, 0x01a56,), # Tai Tham Consonant Sign ..Tai Tham Consonant Sign + (0x01a58, 0x01a5e,), # Tai Tham Sign Mai Kang L..Tai Tham Consonant Sign + (0x01a60, 0x01a60,), # Tai Tham Sign Sakot ..Tai Tham Sign Sakot + (0x01a62, 0x01a62,), # Tai Tham Vowel Sign Mai ..Tai Tham Vowel Sign Mai + (0x01a65, 0x01a6c,), # Tai Tham Vowel Sign I ..Tai Tham Vowel Sign Oa B + (0x01a73, 0x01a7c,), # Tai Tham Vowel Sign Oa A..Tai Tham Sign Khuen-lue + (0x01a7f, 0x01a7f,), # Tai Tham Combining Crypt..Tai Tham Combining Crypt + (0x01ab0, 0x01abe,), # Combining Doubled Circum..Combining Parentheses Ov + (0x01b00, 0x01b03,), # Balinese Sign Ulu Ricem ..Balinese Sign Surang + (0x01b34, 0x01b34,), # Balinese Sign Rerekan ..Balinese Sign Rerekan + (0x01b36, 0x01b3a,), # Balinese Vowel Sign Ulu ..Balinese Vowel Sign Ra R + (0x01b3c, 0x01b3c,), # Balinese Vowel Sign La L..Balinese Vowel Sign La L + (0x01b42, 0x01b42,), # Balinese Vowel Sign Pepe..Balinese Vowel Sign Pepe + (0x01b6b, 0x01b73,), # Balinese Musical Symbol ..Balinese Musical Symbol + (0x01b80, 0x01b81,), # Sundanese Sign Panyecek ..Sundanese Sign Panglayar + (0x01ba2, 0x01ba5,), # Sundanese Consonant Sign..Sundanese Vowel Sign Pan + (0x01ba8, 0x01ba9,), # Sundanese Vowel Sign Pam..Sundanese Vowel Sign Pan + (0x01bab, 0x01bad,), # Sundanese Sign Virama ..Sundanese Consonant Sign + (0x01be6, 0x01be6,), # Batak Sign Tompi ..Batak Sign Tompi + (0x01be8, 0x01be9,), # Batak Vowel Sign Pakpak ..Batak Vowel Sign Ee + (0x01bed, 0x01bed,), # Batak Vowel Sign Karo O ..Batak Vowel Sign Karo O + (0x01bef, 0x01bf1,), # Batak Vowel Sign U For S..Batak Consonant Sign H + (0x01c2c, 0x01c33,), # Lepcha Vowel Sign E ..Lepcha Consonant Sign T + (0x01c36, 0x01c37,), # Lepcha Sign Ran ..Lepcha Sign Nukta + (0x01cd0, 0x01cd2,), # Vedic Tone Karshana ..Vedic Tone Prenkha + (0x01cd4, 0x01ce0,), # Vedic Sign Yajurvedic Mi..Vedic Tone Rigvedic Kash + (0x01ce2, 0x01ce8,), # Vedic Sign Visarga Svari..Vedic Sign Visarga Anuda + (0x01ced, 0x01ced,), # Vedic Sign Tiryak ..Vedic Sign Tiryak + (0x01cf4, 0x01cf4,), # Vedic Tone Candra Above ..Vedic Tone Candra Above + (0x01cf8, 0x01cf9,), # Vedic Tone Ring Above ..Vedic Tone Double Ring A + (0x01dc0, 0x01df5,), # Combining Dotted Grave A..Combining Up Tack Above + (0x01dfc, 0x01dff,), # Combining Double Inverte..Combining Right Arrowhea + (0x020d0, 0x020f0,), # Combining Left Harpoon A..Combining Asterisk Above + (0x02cef, 0x02cf1,), # Coptic Combining Ni Abov..Coptic Combining Spiritu + (0x02d7f, 0x02d7f,), # Tifinagh Consonant Joine..Tifinagh Consonant Joine + (0x02de0, 0x02dff,), # Combining Cyrillic Lette..Combining Cyrillic Lette + (0x0302a, 0x0302d,), # Ideographic Level Tone M..Ideographic Entering Ton + (0x03099, 0x0309a,), # Combining Katakana-hirag..Combining Katakana-hirag + (0x0a66f, 0x0a672,), # Combining Cyrillic Vzmet..Combining Cyrillic Thous + (0x0a674, 0x0a67d,), # Combining Cyrillic Lette..Combining Cyrillic Payer + (0x0a69f, 0x0a69f,), # Combining Cyrillic Lette..Combining Cyrillic Lette + (0x0a6f0, 0x0a6f1,), # Bamum Combining Mark Koq..Bamum Combining Mark Tuk + (0x0a802, 0x0a802,), # Syloti Nagri Sign Dvisva..Syloti Nagri Sign Dvisva + (0x0a806, 0x0a806,), # Syloti Nagri Sign Hasant..Syloti Nagri Sign Hasant + (0x0a80b, 0x0a80b,), # Syloti Nagri Sign Anusva..Syloti Nagri Sign Anusva + (0x0a825, 0x0a826,), # Syloti Nagri Vowel Sign ..Syloti Nagri Vowel Sign + (0x0a8c4, 0x0a8c4,), # Saurashtra Sign Virama ..Saurashtra Sign Virama + (0x0a8e0, 0x0a8f1,), # Combining Devanagari Dig..Combining Devanagari Sig + (0x0a926, 0x0a92d,), # Kayah Li Vowel Ue ..Kayah Li Tone Calya Plop + (0x0a947, 0x0a951,), # Rejang Vowel Sign I ..Rejang Consonant Sign R + (0x0a980, 0x0a982,), # Javanese Sign Panyangga ..Javanese Sign Layar + (0x0a9b3, 0x0a9b3,), # Javanese Sign Cecak Telu..Javanese Sign Cecak Telu + (0x0a9b6, 0x0a9b9,), # Javanese Vowel Sign Wulu..Javanese Vowel Sign Suku + (0x0a9bc, 0x0a9bc,), # Javanese Vowel Sign Pepe..Javanese Vowel Sign Pepe + (0x0a9e5, 0x0a9e5,), # Myanmar Sign Shan Saw ..Myanmar Sign Shan Saw + (0x0aa29, 0x0aa2e,), # Cham Vowel Sign Aa ..Cham Vowel Sign Oe + (0x0aa31, 0x0aa32,), # Cham Vowel Sign Au ..Cham Vowel Sign Ue + (0x0aa35, 0x0aa36,), # Cham Consonant Sign La ..Cham Consonant Sign Wa + (0x0aa43, 0x0aa43,), # Cham Consonant Sign Fina..Cham Consonant Sign Fina + (0x0aa4c, 0x0aa4c,), # Cham Consonant Sign Fina..Cham Consonant Sign Fina + (0x0aa7c, 0x0aa7c,), # Myanmar Sign Tai Laing T..Myanmar Sign Tai Laing T + (0x0aab0, 0x0aab0,), # Tai Viet Mai Kang ..Tai Viet Mai Kang + (0x0aab2, 0x0aab4,), # Tai Viet Vowel I ..Tai Viet Vowel U + (0x0aab7, 0x0aab8,), # Tai Viet Mai Khit ..Tai Viet Vowel Ia + (0x0aabe, 0x0aabf,), # Tai Viet Vowel Am ..Tai Viet Tone Mai Ek + (0x0aac1, 0x0aac1,), # Tai Viet Tone Mai Tho ..Tai Viet Tone Mai Tho + (0x0aaec, 0x0aaed,), # Meetei Mayek Vowel Sign ..Meetei Mayek Vowel Sign + (0x0aaf6, 0x0aaf6,), # Meetei Mayek Virama ..Meetei Mayek Virama + (0x0abe5, 0x0abe5,), # Meetei Mayek Vowel Sign ..Meetei Mayek Vowel Sign + (0x0abe8, 0x0abe8,), # Meetei Mayek Vowel Sign ..Meetei Mayek Vowel Sign + (0x0abed, 0x0abed,), # Meetei Mayek Apun Iyek ..Meetei Mayek Apun Iyek + (0x0fb1e, 0x0fb1e,), # Hebrew Point Judeo-spani..Hebrew Point Judeo-spani + (0x0fe00, 0x0fe0f,), # Variation Selector-1 ..Variation Selector-16 + (0x0fe20, 0x0fe2d,), # Combining Ligature Left ..Combining Conjoining Mac + (0x101fd, 0x101fd,), # Phaistos Disc Sign Combi..Phaistos Disc Sign Combi + (0x102e0, 0x102e0,), # Coptic Epact Thousands M..Coptic Epact Thousands M + (0x10376, 0x1037a,), # Combining Old Permic Let..Combining Old Permic Let + (0x10a01, 0x10a03,), # Kharoshthi Vowel Sign I ..Kharoshthi Vowel Sign Vo + (0x10a05, 0x10a06,), # Kharoshthi Vowel Sign E ..Kharoshthi Vowel Sign O + (0x10a0c, 0x10a0f,), # Kharoshthi Vowel Length ..Kharoshthi Sign Visarga + (0x10a38, 0x10a3a,), # Kharoshthi Sign Bar Abov..Kharoshthi Sign Dot Belo + (0x10a3f, 0x10a3f,), # Kharoshthi Virama ..Kharoshthi Virama + (0x10ae5, 0x10ae6,), # Manichaean Abbreviation ..Manichaean Abbreviation + (0x11001, 0x11001,), # Brahmi Sign Anusvara ..Brahmi Sign Anusvara + (0x11038, 0x11046,), # Brahmi Vowel Sign Aa ..Brahmi Virama + (0x1107f, 0x11081,), # Brahmi Number Joiner ..Kaithi Sign Anusvara + (0x110b3, 0x110b6,), # Kaithi Vowel Sign U ..Kaithi Vowel Sign Ai + (0x110b9, 0x110ba,), # Kaithi Sign Virama ..Kaithi Sign Nukta + (0x11100, 0x11102,), # Chakma Sign Candrabindu ..Chakma Sign Visarga + (0x11127, 0x1112b,), # Chakma Vowel Sign A ..Chakma Vowel Sign Uu + (0x1112d, 0x11134,), # Chakma Vowel Sign Ai ..Chakma Maayyaa + (0x11173, 0x11173,), # Mahajani Sign Nukta ..Mahajani Sign Nukta + (0x11180, 0x11181,), # Sharada Sign Candrabindu..Sharada Sign Anusvara + (0x111b6, 0x111be,), # Sharada Vowel Sign U ..Sharada Vowel Sign O + (0x1122f, 0x11231,), # Khojki Vowel Sign U ..Khojki Vowel Sign Ai + (0x11234, 0x11234,), # Khojki Sign Anusvara ..Khojki Sign Anusvara + (0x11236, 0x11237,), # Khojki Sign Nukta ..Khojki Sign Shadda + (0x112df, 0x112df,), # Khudawadi Sign Anusvara ..Khudawadi Sign Anusvara + (0x112e3, 0x112ea,), # Khudawadi Vowel Sign U ..Khudawadi Sign Virama + (0x11301, 0x11301,), # Grantha Sign Candrabindu..Grantha Sign Candrabindu + (0x1133c, 0x1133c,), # Grantha Sign Nukta ..Grantha Sign Nukta + (0x11340, 0x11340,), # Grantha Vowel Sign Ii ..Grantha Vowel Sign Ii + (0x11366, 0x1136c,), # Combining Grantha Digit ..Combining Grantha Digit + (0x11370, 0x11374,), # Combining Grantha Letter..Combining Grantha Letter + (0x114b3, 0x114b8,), # Tirhuta Vowel Sign U ..Tirhuta Vowel Sign Vocal + (0x114ba, 0x114ba,), # Tirhuta Vowel Sign Short..Tirhuta Vowel Sign Short + (0x114bf, 0x114c0,), # Tirhuta Sign Candrabindu..Tirhuta Sign Anusvara + (0x114c2, 0x114c3,), # Tirhuta Sign Virama ..Tirhuta Sign Nukta + (0x115b2, 0x115b5,), # Siddham Vowel Sign U ..Siddham Vowel Sign Vocal + (0x115bc, 0x115bd,), # Siddham Sign Candrabindu..Siddham Sign Anusvara + (0x115bf, 0x115c0,), # Siddham Sign Virama ..Siddham Sign Nukta + (0x11633, 0x1163a,), # Modi Vowel Sign U ..Modi Vowel Sign Ai + (0x1163d, 0x1163d,), # Modi Sign Anusvara ..Modi Sign Anusvara + (0x1163f, 0x11640,), # Modi Sign Virama ..Modi Sign Ardhacandra + (0x116ab, 0x116ab,), # Takri Sign Anusvara ..Takri Sign Anusvara + (0x116ad, 0x116ad,), # Takri Vowel Sign Aa ..Takri Vowel Sign Aa + (0x116b0, 0x116b5,), # Takri Vowel Sign U ..Takri Vowel Sign Au + (0x116b7, 0x116b7,), # Takri Sign Nukta ..Takri Sign Nukta + (0x16af0, 0x16af4,), # Bassa Vah Combining High..Bassa Vah Combining High + (0x16b30, 0x16b36,), # Pahawh Hmong Mark Cim Tu..Pahawh Hmong Mark Cim Ta + (0x16f8f, 0x16f92,), # Miao Tone Right ..Miao Tone Below + (0x1bc9d, 0x1bc9e,), # Duployan Thick Letter Se..Duployan Double Mark + (0x1d167, 0x1d169,), # Musical Symbol Combining..Musical Symbol Combining + (0x1d17b, 0x1d182,), # Musical Symbol Combining..Musical Symbol Combining + (0x1d185, 0x1d18b,), # Musical Symbol Combining..Musical Symbol Combining + (0x1d1aa, 0x1d1ad,), # Musical Symbol Combining..Musical Symbol Combining + (0x1d242, 0x1d244,), # Combining Greek Musical ..Combining Greek Musical + (0x1e8d0, 0x1e8d6,), # Mende Kikakui Combining ..Mende Kikakui Combining + (0xe0100, 0xe01ef,), # Variation Selector-17 ..Variation Selector-256 + ), + '8.0.0': ( + # Source: DerivedGeneralCategory-8.0.0.txt + # Date: 2015-02-13, 13:47:11 GMT [MD] + # + (0x00300, 0x0036f,), # Combining Grave Accent ..Combining Latin Small Le + (0x00483, 0x00489,), # Combining Cyrillic Titlo..Combining Cyrillic Milli + (0x00591, 0x005bd,), # Hebrew Accent Etnahta ..Hebrew Point Meteg + (0x005bf, 0x005bf,), # Hebrew Point Rafe ..Hebrew Point Rafe + (0x005c1, 0x005c2,), # Hebrew Point Shin Dot ..Hebrew Point Sin Dot + (0x005c4, 0x005c5,), # Hebrew Mark Upper Dot ..Hebrew Mark Lower Dot + (0x005c7, 0x005c7,), # Hebrew Point Qamats Qata..Hebrew Point Qamats Qata + (0x00610, 0x0061a,), # Arabic Sign Sallallahou ..Arabic Small Kasra + (0x0064b, 0x0065f,), # Arabic Fathatan ..Arabic Wavy Hamza Below + (0x00670, 0x00670,), # Arabic Letter Superscrip..Arabic Letter Superscrip + (0x006d6, 0x006dc,), # Arabic Small High Ligatu..Arabic Small High Seen + (0x006df, 0x006e4,), # Arabic Small High Rounde..Arabic Small High Madda + (0x006e7, 0x006e8,), # Arabic Small High Yeh ..Arabic Small High Noon + (0x006ea, 0x006ed,), # Arabic Empty Centre Low ..Arabic Small Low Meem + (0x00711, 0x00711,), # Syriac Letter Superscrip..Syriac Letter Superscrip + (0x00730, 0x0074a,), # Syriac Pthaha Above ..Syriac Barrekh + (0x007a6, 0x007b0,), # Thaana Abafili ..Thaana Sukun + (0x007eb, 0x007f3,), # Nko Combining Short High..Nko Combining Double Dot + (0x00816, 0x00819,), # Samaritan Mark In ..Samaritan Mark Dagesh + (0x0081b, 0x00823,), # Samaritan Mark Epentheti..Samaritan Vowel Sign A + (0x00825, 0x00827,), # Samaritan Vowel Sign Sho..Samaritan Vowel Sign U + (0x00829, 0x0082d,), # Samaritan Vowel Sign Lon..Samaritan Mark Nequdaa + (0x00859, 0x0085b,), # Mandaic Affrication Mark..Mandaic Gemination Mark + (0x008e3, 0x00902,), # Arabic Turned Damma Belo..Devanagari Sign Anusvara + (0x0093a, 0x0093a,), # Devanagari Vowel Sign Oe..Devanagari Vowel Sign Oe + (0x0093c, 0x0093c,), # Devanagari Sign Nukta ..Devanagari Sign Nukta + (0x00941, 0x00948,), # Devanagari Vowel Sign U ..Devanagari Vowel Sign Ai + (0x0094d, 0x0094d,), # Devanagari Sign Virama ..Devanagari Sign Virama + (0x00951, 0x00957,), # Devanagari Stress Sign U..Devanagari Vowel Sign Uu + (0x00962, 0x00963,), # Devanagari Vowel Sign Vo..Devanagari Vowel Sign Vo + (0x00981, 0x00981,), # Bengali Sign Candrabindu..Bengali Sign Candrabindu + (0x009bc, 0x009bc,), # Bengali Sign Nukta ..Bengali Sign Nukta + (0x009c1, 0x009c4,), # Bengali Vowel Sign U ..Bengali Vowel Sign Vocal + (0x009cd, 0x009cd,), # Bengali Sign Virama ..Bengali Sign Virama + (0x009e2, 0x009e3,), # Bengali Vowel Sign Vocal..Bengali Vowel Sign Vocal + (0x00a01, 0x00a02,), # Gurmukhi Sign Adak Bindi..Gurmukhi Sign Bindi + (0x00a3c, 0x00a3c,), # Gurmukhi Sign Nukta ..Gurmukhi Sign Nukta + (0x00a41, 0x00a42,), # Gurmukhi Vowel Sign U ..Gurmukhi Vowel Sign Uu + (0x00a47, 0x00a48,), # Gurmukhi Vowel Sign Ee ..Gurmukhi Vowel Sign Ai + (0x00a4b, 0x00a4d,), # Gurmukhi Vowel Sign Oo ..Gurmukhi Sign Virama + (0x00a51, 0x00a51,), # Gurmukhi Sign Udaat ..Gurmukhi Sign Udaat + (0x00a70, 0x00a71,), # Gurmukhi Tippi ..Gurmukhi Addak + (0x00a75, 0x00a75,), # Gurmukhi Sign Yakash ..Gurmukhi Sign Yakash + (0x00a81, 0x00a82,), # Gujarati Sign Candrabind..Gujarati Sign Anusvara + (0x00abc, 0x00abc,), # Gujarati Sign Nukta ..Gujarati Sign Nukta + (0x00ac1, 0x00ac5,), # Gujarati Vowel Sign U ..Gujarati Vowel Sign Cand + (0x00ac7, 0x00ac8,), # Gujarati Vowel Sign E ..Gujarati Vowel Sign Ai + (0x00acd, 0x00acd,), # Gujarati Sign Virama ..Gujarati Sign Virama + (0x00ae2, 0x00ae3,), # Gujarati Vowel Sign Voca..Gujarati Vowel Sign Voca + (0x00b01, 0x00b01,), # Oriya Sign Candrabindu ..Oriya Sign Candrabindu + (0x00b3c, 0x00b3c,), # Oriya Sign Nukta ..Oriya Sign Nukta + (0x00b3f, 0x00b3f,), # Oriya Vowel Sign I ..Oriya Vowel Sign I + (0x00b41, 0x00b44,), # Oriya Vowel Sign U ..Oriya Vowel Sign Vocalic + (0x00b4d, 0x00b4d,), # Oriya Sign Virama ..Oriya Sign Virama + (0x00b56, 0x00b56,), # Oriya Ai Length Mark ..Oriya Ai Length Mark + (0x00b62, 0x00b63,), # Oriya Vowel Sign Vocalic..Oriya Vowel Sign Vocalic + (0x00b82, 0x00b82,), # Tamil Sign Anusvara ..Tamil Sign Anusvara + (0x00bc0, 0x00bc0,), # Tamil Vowel Sign Ii ..Tamil Vowel Sign Ii + (0x00bcd, 0x00bcd,), # Tamil Sign Virama ..Tamil Sign Virama + (0x00c00, 0x00c00,), # Telugu Sign Combining Ca..Telugu Sign Combining Ca + (0x00c3e, 0x00c40,), # Telugu Vowel Sign Aa ..Telugu Vowel Sign Ii + (0x00c46, 0x00c48,), # Telugu Vowel Sign E ..Telugu Vowel Sign Ai + (0x00c4a, 0x00c4d,), # Telugu Vowel Sign O ..Telugu Sign Virama + (0x00c55, 0x00c56,), # Telugu Length Mark ..Telugu Ai Length Mark + (0x00c62, 0x00c63,), # Telugu Vowel Sign Vocali..Telugu Vowel Sign Vocali + (0x00c81, 0x00c81,), # Kannada Sign Candrabindu..Kannada Sign Candrabindu + (0x00cbc, 0x00cbc,), # Kannada Sign Nukta ..Kannada Sign Nukta + (0x00cbf, 0x00cbf,), # Kannada Vowel Sign I ..Kannada Vowel Sign I + (0x00cc6, 0x00cc6,), # Kannada Vowel Sign E ..Kannada Vowel Sign E + (0x00ccc, 0x00ccd,), # Kannada Vowel Sign Au ..Kannada Sign Virama + (0x00ce2, 0x00ce3,), # Kannada Vowel Sign Vocal..Kannada Vowel Sign Vocal + (0x00d01, 0x00d01,), # Malayalam Sign Candrabin..Malayalam Sign Candrabin + (0x00d41, 0x00d44,), # Malayalam Vowel Sign U ..Malayalam Vowel Sign Voc + (0x00d4d, 0x00d4d,), # Malayalam Sign Virama ..Malayalam Sign Virama + (0x00d62, 0x00d63,), # Malayalam Vowel Sign Voc..Malayalam Vowel Sign Voc + (0x00dca, 0x00dca,), # Sinhala Sign Al-lakuna ..Sinhala Sign Al-lakuna + (0x00dd2, 0x00dd4,), # Sinhala Vowel Sign Ketti..Sinhala Vowel Sign Ketti + (0x00dd6, 0x00dd6,), # Sinhala Vowel Sign Diga ..Sinhala Vowel Sign Diga + (0x00e31, 0x00e31,), # Thai Character Mai Han-a..Thai Character Mai Han-a + (0x00e34, 0x00e3a,), # Thai Character Sara I ..Thai Character Phinthu + (0x00e47, 0x00e4e,), # Thai Character Maitaikhu..Thai Character Yamakkan + (0x00eb1, 0x00eb1,), # Lao Vowel Sign Mai Kan ..Lao Vowel Sign Mai Kan + (0x00eb4, 0x00eb9,), # Lao Vowel Sign I ..Lao Vowel Sign Uu + (0x00ebb, 0x00ebc,), # Lao Vowel Sign Mai Kon ..Lao Semivowel Sign Lo + (0x00ec8, 0x00ecd,), # Lao Tone Mai Ek ..Lao Niggahita + (0x00f18, 0x00f19,), # Tibetan Astrological Sig..Tibetan Astrological Sig + (0x00f35, 0x00f35,), # Tibetan Mark Ngas Bzung ..Tibetan Mark Ngas Bzung + (0x00f37, 0x00f37,), # Tibetan Mark Ngas Bzung ..Tibetan Mark Ngas Bzung + (0x00f39, 0x00f39,), # Tibetan Mark Tsa -phru ..Tibetan Mark Tsa -phru + (0x00f71, 0x00f7e,), # Tibetan Vowel Sign Aa ..Tibetan Sign Rjes Su Nga + (0x00f80, 0x00f84,), # Tibetan Vowel Sign Rever..Tibetan Mark Halanta + (0x00f86, 0x00f87,), # Tibetan Sign Lci Rtags ..Tibetan Sign Yang Rtags + (0x00f8d, 0x00f97,), # Tibetan Subjoined Sign L..Tibetan Subjoined Letter + (0x00f99, 0x00fbc,), # Tibetan Subjoined Letter..Tibetan Subjoined Letter + (0x00fc6, 0x00fc6,), # Tibetan Symbol Padma Gda..Tibetan Symbol Padma Gda + (0x0102d, 0x01030,), # Myanmar Vowel Sign I ..Myanmar Vowel Sign Uu + (0x01032, 0x01037,), # Myanmar Vowel Sign Ai ..Myanmar Sign Dot Below + (0x01039, 0x0103a,), # Myanmar Sign Virama ..Myanmar Sign Asat + (0x0103d, 0x0103e,), # Myanmar Consonant Sign M..Myanmar Consonant Sign M + (0x01058, 0x01059,), # Myanmar Vowel Sign Vocal..Myanmar Vowel Sign Vocal + (0x0105e, 0x01060,), # Myanmar Consonant Sign M..Myanmar Consonant Sign M + (0x01071, 0x01074,), # Myanmar Vowel Sign Geba ..Myanmar Vowel Sign Kayah + (0x01082, 0x01082,), # Myanmar Consonant Sign S..Myanmar Consonant Sign S + (0x01085, 0x01086,), # Myanmar Vowel Sign Shan ..Myanmar Vowel Sign Shan + (0x0108d, 0x0108d,), # Myanmar Sign Shan Counci..Myanmar Sign Shan Counci + (0x0109d, 0x0109d,), # Myanmar Vowel Sign Aiton..Myanmar Vowel Sign Aiton + (0x0135d, 0x0135f,), # Ethiopic Combining Gemin..Ethiopic Combining Gemin + (0x01712, 0x01714,), # Tagalog Vowel Sign I ..Tagalog Sign Virama + (0x01732, 0x01734,), # Hanunoo Vowel Sign I ..Hanunoo Sign Pamudpod + (0x01752, 0x01753,), # Buhid Vowel Sign I ..Buhid Vowel Sign U + (0x01772, 0x01773,), # Tagbanwa Vowel Sign I ..Tagbanwa Vowel Sign U + (0x017b4, 0x017b5,), # Khmer Vowel Inherent Aq ..Khmer Vowel Inherent Aa + (0x017b7, 0x017bd,), # Khmer Vowel Sign I ..Khmer Vowel Sign Ua + (0x017c6, 0x017c6,), # Khmer Sign Nikahit ..Khmer Sign Nikahit + (0x017c9, 0x017d3,), # Khmer Sign Muusikatoan ..Khmer Sign Bathamasat + (0x017dd, 0x017dd,), # Khmer Sign Atthacan ..Khmer Sign Atthacan + (0x0180b, 0x0180d,), # Mongolian Free Variation..Mongolian Free Variation + (0x018a9, 0x018a9,), # Mongolian Letter Ali Gal..Mongolian Letter Ali Gal + (0x01920, 0x01922,), # Limbu Vowel Sign A ..Limbu Vowel Sign U + (0x01927, 0x01928,), # Limbu Vowel Sign E ..Limbu Vowel Sign O + (0x01932, 0x01932,), # Limbu Small Letter Anusv..Limbu Small Letter Anusv + (0x01939, 0x0193b,), # Limbu Sign Mukphreng ..Limbu Sign Sa-i + (0x01a17, 0x01a18,), # Buginese Vowel Sign I ..Buginese Vowel Sign U + (0x01a1b, 0x01a1b,), # Buginese Vowel Sign Ae ..Buginese Vowel Sign Ae + (0x01a56, 0x01a56,), # Tai Tham Consonant Sign ..Tai Tham Consonant Sign + (0x01a58, 0x01a5e,), # Tai Tham Sign Mai Kang L..Tai Tham Consonant Sign + (0x01a60, 0x01a60,), # Tai Tham Sign Sakot ..Tai Tham Sign Sakot + (0x01a62, 0x01a62,), # Tai Tham Vowel Sign Mai ..Tai Tham Vowel Sign Mai + (0x01a65, 0x01a6c,), # Tai Tham Vowel Sign I ..Tai Tham Vowel Sign Oa B + (0x01a73, 0x01a7c,), # Tai Tham Vowel Sign Oa A..Tai Tham Sign Khuen-lue + (0x01a7f, 0x01a7f,), # Tai Tham Combining Crypt..Tai Tham Combining Crypt + (0x01ab0, 0x01abe,), # Combining Doubled Circum..Combining Parentheses Ov + (0x01b00, 0x01b03,), # Balinese Sign Ulu Ricem ..Balinese Sign Surang + (0x01b34, 0x01b34,), # Balinese Sign Rerekan ..Balinese Sign Rerekan + (0x01b36, 0x01b3a,), # Balinese Vowel Sign Ulu ..Balinese Vowel Sign Ra R + (0x01b3c, 0x01b3c,), # Balinese Vowel Sign La L..Balinese Vowel Sign La L + (0x01b42, 0x01b42,), # Balinese Vowel Sign Pepe..Balinese Vowel Sign Pepe + (0x01b6b, 0x01b73,), # Balinese Musical Symbol ..Balinese Musical Symbol + (0x01b80, 0x01b81,), # Sundanese Sign Panyecek ..Sundanese Sign Panglayar + (0x01ba2, 0x01ba5,), # Sundanese Consonant Sign..Sundanese Vowel Sign Pan + (0x01ba8, 0x01ba9,), # Sundanese Vowel Sign Pam..Sundanese Vowel Sign Pan + (0x01bab, 0x01bad,), # Sundanese Sign Virama ..Sundanese Consonant Sign + (0x01be6, 0x01be6,), # Batak Sign Tompi ..Batak Sign Tompi + (0x01be8, 0x01be9,), # Batak Vowel Sign Pakpak ..Batak Vowel Sign Ee + (0x01bed, 0x01bed,), # Batak Vowel Sign Karo O ..Batak Vowel Sign Karo O + (0x01bef, 0x01bf1,), # Batak Vowel Sign U For S..Batak Consonant Sign H + (0x01c2c, 0x01c33,), # Lepcha Vowel Sign E ..Lepcha Consonant Sign T + (0x01c36, 0x01c37,), # Lepcha Sign Ran ..Lepcha Sign Nukta + (0x01cd0, 0x01cd2,), # Vedic Tone Karshana ..Vedic Tone Prenkha + (0x01cd4, 0x01ce0,), # Vedic Sign Yajurvedic Mi..Vedic Tone Rigvedic Kash + (0x01ce2, 0x01ce8,), # Vedic Sign Visarga Svari..Vedic Sign Visarga Anuda + (0x01ced, 0x01ced,), # Vedic Sign Tiryak ..Vedic Sign Tiryak + (0x01cf4, 0x01cf4,), # Vedic Tone Candra Above ..Vedic Tone Candra Above + (0x01cf8, 0x01cf9,), # Vedic Tone Ring Above ..Vedic Tone Double Ring A + (0x01dc0, 0x01df5,), # Combining Dotted Grave A..Combining Up Tack Above + (0x01dfc, 0x01dff,), # Combining Double Inverte..Combining Right Arrowhea + (0x020d0, 0x020f0,), # Combining Left Harpoon A..Combining Asterisk Above + (0x02cef, 0x02cf1,), # Coptic Combining Ni Abov..Coptic Combining Spiritu + (0x02d7f, 0x02d7f,), # Tifinagh Consonant Joine..Tifinagh Consonant Joine + (0x02de0, 0x02dff,), # Combining Cyrillic Lette..Combining Cyrillic Lette + (0x0302a, 0x0302d,), # Ideographic Level Tone M..Ideographic Entering Ton + (0x03099, 0x0309a,), # Combining Katakana-hirag..Combining Katakana-hirag + (0x0a66f, 0x0a672,), # Combining Cyrillic Vzmet..Combining Cyrillic Thous + (0x0a674, 0x0a67d,), # Combining Cyrillic Lette..Combining Cyrillic Payer + (0x0a69e, 0x0a69f,), # Combining Cyrillic Lette..Combining Cyrillic Lette + (0x0a6f0, 0x0a6f1,), # Bamum Combining Mark Koq..Bamum Combining Mark Tuk + (0x0a802, 0x0a802,), # Syloti Nagri Sign Dvisva..Syloti Nagri Sign Dvisva + (0x0a806, 0x0a806,), # Syloti Nagri Sign Hasant..Syloti Nagri Sign Hasant + (0x0a80b, 0x0a80b,), # Syloti Nagri Sign Anusva..Syloti Nagri Sign Anusva + (0x0a825, 0x0a826,), # Syloti Nagri Vowel Sign ..Syloti Nagri Vowel Sign + (0x0a8c4, 0x0a8c4,), # Saurashtra Sign Virama ..Saurashtra Sign Virama + (0x0a8e0, 0x0a8f1,), # Combining Devanagari Dig..Combining Devanagari Sig + (0x0a926, 0x0a92d,), # Kayah Li Vowel Ue ..Kayah Li Tone Calya Plop + (0x0a947, 0x0a951,), # Rejang Vowel Sign I ..Rejang Consonant Sign R + (0x0a980, 0x0a982,), # Javanese Sign Panyangga ..Javanese Sign Layar + (0x0a9b3, 0x0a9b3,), # Javanese Sign Cecak Telu..Javanese Sign Cecak Telu + (0x0a9b6, 0x0a9b9,), # Javanese Vowel Sign Wulu..Javanese Vowel Sign Suku + (0x0a9bc, 0x0a9bc,), # Javanese Vowel Sign Pepe..Javanese Vowel Sign Pepe + (0x0a9e5, 0x0a9e5,), # Myanmar Sign Shan Saw ..Myanmar Sign Shan Saw + (0x0aa29, 0x0aa2e,), # Cham Vowel Sign Aa ..Cham Vowel Sign Oe + (0x0aa31, 0x0aa32,), # Cham Vowel Sign Au ..Cham Vowel Sign Ue + (0x0aa35, 0x0aa36,), # Cham Consonant Sign La ..Cham Consonant Sign Wa + (0x0aa43, 0x0aa43,), # Cham Consonant Sign Fina..Cham Consonant Sign Fina + (0x0aa4c, 0x0aa4c,), # Cham Consonant Sign Fina..Cham Consonant Sign Fina + (0x0aa7c, 0x0aa7c,), # Myanmar Sign Tai Laing T..Myanmar Sign Tai Laing T + (0x0aab0, 0x0aab0,), # Tai Viet Mai Kang ..Tai Viet Mai Kang + (0x0aab2, 0x0aab4,), # Tai Viet Vowel I ..Tai Viet Vowel U + (0x0aab7, 0x0aab8,), # Tai Viet Mai Khit ..Tai Viet Vowel Ia + (0x0aabe, 0x0aabf,), # Tai Viet Vowel Am ..Tai Viet Tone Mai Ek + (0x0aac1, 0x0aac1,), # Tai Viet Tone Mai Tho ..Tai Viet Tone Mai Tho + (0x0aaec, 0x0aaed,), # Meetei Mayek Vowel Sign ..Meetei Mayek Vowel Sign + (0x0aaf6, 0x0aaf6,), # Meetei Mayek Virama ..Meetei Mayek Virama + (0x0abe5, 0x0abe5,), # Meetei Mayek Vowel Sign ..Meetei Mayek Vowel Sign + (0x0abe8, 0x0abe8,), # Meetei Mayek Vowel Sign ..Meetei Mayek Vowel Sign + (0x0abed, 0x0abed,), # Meetei Mayek Apun Iyek ..Meetei Mayek Apun Iyek + (0x0fb1e, 0x0fb1e,), # Hebrew Point Judeo-spani..Hebrew Point Judeo-spani + (0x0fe00, 0x0fe0f,), # Variation Selector-1 ..Variation Selector-16 + (0x0fe20, 0x0fe2f,), # Combining Ligature Left ..Combining Cyrillic Titlo + (0x101fd, 0x101fd,), # Phaistos Disc Sign Combi..Phaistos Disc Sign Combi + (0x102e0, 0x102e0,), # Coptic Epact Thousands M..Coptic Epact Thousands M + (0x10376, 0x1037a,), # Combining Old Permic Let..Combining Old Permic Let + (0x10a01, 0x10a03,), # Kharoshthi Vowel Sign I ..Kharoshthi Vowel Sign Vo + (0x10a05, 0x10a06,), # Kharoshthi Vowel Sign E ..Kharoshthi Vowel Sign O + (0x10a0c, 0x10a0f,), # Kharoshthi Vowel Length ..Kharoshthi Sign Visarga + (0x10a38, 0x10a3a,), # Kharoshthi Sign Bar Abov..Kharoshthi Sign Dot Belo + (0x10a3f, 0x10a3f,), # Kharoshthi Virama ..Kharoshthi Virama + (0x10ae5, 0x10ae6,), # Manichaean Abbreviation ..Manichaean Abbreviation + (0x11001, 0x11001,), # Brahmi Sign Anusvara ..Brahmi Sign Anusvara + (0x11038, 0x11046,), # Brahmi Vowel Sign Aa ..Brahmi Virama + (0x1107f, 0x11081,), # Brahmi Number Joiner ..Kaithi Sign Anusvara + (0x110b3, 0x110b6,), # Kaithi Vowel Sign U ..Kaithi Vowel Sign Ai + (0x110b9, 0x110ba,), # Kaithi Sign Virama ..Kaithi Sign Nukta + (0x11100, 0x11102,), # Chakma Sign Candrabindu ..Chakma Sign Visarga + (0x11127, 0x1112b,), # Chakma Vowel Sign A ..Chakma Vowel Sign Uu + (0x1112d, 0x11134,), # Chakma Vowel Sign Ai ..Chakma Maayyaa + (0x11173, 0x11173,), # Mahajani Sign Nukta ..Mahajani Sign Nukta + (0x11180, 0x11181,), # Sharada Sign Candrabindu..Sharada Sign Anusvara + (0x111b6, 0x111be,), # Sharada Vowel Sign U ..Sharada Vowel Sign O + (0x111ca, 0x111cc,), # Sharada Sign Nukta ..Sharada Extra Short Vowe + (0x1122f, 0x11231,), # Khojki Vowel Sign U ..Khojki Vowel Sign Ai + (0x11234, 0x11234,), # Khojki Sign Anusvara ..Khojki Sign Anusvara + (0x11236, 0x11237,), # Khojki Sign Nukta ..Khojki Sign Shadda + (0x112df, 0x112df,), # Khudawadi Sign Anusvara ..Khudawadi Sign Anusvara + (0x112e3, 0x112ea,), # Khudawadi Vowel Sign U ..Khudawadi Sign Virama + (0x11300, 0x11301,), # Grantha Sign Combining A..Grantha Sign Candrabindu + (0x1133c, 0x1133c,), # Grantha Sign Nukta ..Grantha Sign Nukta + (0x11340, 0x11340,), # Grantha Vowel Sign Ii ..Grantha Vowel Sign Ii + (0x11366, 0x1136c,), # Combining Grantha Digit ..Combining Grantha Digit + (0x11370, 0x11374,), # Combining Grantha Letter..Combining Grantha Letter + (0x114b3, 0x114b8,), # Tirhuta Vowel Sign U ..Tirhuta Vowel Sign Vocal + (0x114ba, 0x114ba,), # Tirhuta Vowel Sign Short..Tirhuta Vowel Sign Short + (0x114bf, 0x114c0,), # Tirhuta Sign Candrabindu..Tirhuta Sign Anusvara + (0x114c2, 0x114c3,), # Tirhuta Sign Virama ..Tirhuta Sign Nukta + (0x115b2, 0x115b5,), # Siddham Vowel Sign U ..Siddham Vowel Sign Vocal + (0x115bc, 0x115bd,), # Siddham Sign Candrabindu..Siddham Sign Anusvara + (0x115bf, 0x115c0,), # Siddham Sign Virama ..Siddham Sign Nukta + (0x115dc, 0x115dd,), # Siddham Vowel Sign Alter..Siddham Vowel Sign Alter + (0x11633, 0x1163a,), # Modi Vowel Sign U ..Modi Vowel Sign Ai + (0x1163d, 0x1163d,), # Modi Sign Anusvara ..Modi Sign Anusvara + (0x1163f, 0x11640,), # Modi Sign Virama ..Modi Sign Ardhacandra + (0x116ab, 0x116ab,), # Takri Sign Anusvara ..Takri Sign Anusvara + (0x116ad, 0x116ad,), # Takri Vowel Sign Aa ..Takri Vowel Sign Aa + (0x116b0, 0x116b5,), # Takri Vowel Sign U ..Takri Vowel Sign Au + (0x116b7, 0x116b7,), # Takri Sign Nukta ..Takri Sign Nukta + (0x1171d, 0x1171f,), # Ahom Consonant Sign Medi..Ahom Consonant Sign Medi + (0x11722, 0x11725,), # Ahom Vowel Sign I ..Ahom Vowel Sign Uu + (0x11727, 0x1172b,), # Ahom Vowel Sign Aw ..Ahom Sign Killer + (0x16af0, 0x16af4,), # Bassa Vah Combining High..Bassa Vah Combining High + (0x16b30, 0x16b36,), # Pahawh Hmong Mark Cim Tu..Pahawh Hmong Mark Cim Ta + (0x16f8f, 0x16f92,), # Miao Tone Right ..Miao Tone Below + (0x1bc9d, 0x1bc9e,), # Duployan Thick Letter Se..Duployan Double Mark + (0x1d167, 0x1d169,), # Musical Symbol Combining..Musical Symbol Combining + (0x1d17b, 0x1d182,), # Musical Symbol Combining..Musical Symbol Combining + (0x1d185, 0x1d18b,), # Musical Symbol Combining..Musical Symbol Combining + (0x1d1aa, 0x1d1ad,), # Musical Symbol Combining..Musical Symbol Combining + (0x1d242, 0x1d244,), # Combining Greek Musical ..Combining Greek Musical + (0x1da00, 0x1da36,), # Signwriting Head Rim ..Signwriting Air Sucking + (0x1da3b, 0x1da6c,), # Signwriting Mouth Closed..Signwriting Excitement + (0x1da75, 0x1da75,), # Signwriting Upper Body T..Signwriting Upper Body T + (0x1da84, 0x1da84,), # Signwriting Location Hea..Signwriting Location Hea + (0x1da9b, 0x1da9f,), # Signwriting Fill Modifie..Signwriting Fill Modifie + (0x1daa1, 0x1daaf,), # Signwriting Rotation Mod..Signwriting Rotation Mod + (0x1e8d0, 0x1e8d6,), # Mende Kikakui Combining ..Mende Kikakui Combining + (0xe0100, 0xe01ef,), # Variation Selector-17 ..Variation Selector-256 + ), + '9.0.0': ( + # Source: DerivedGeneralCategory-9.0.0.txt + # Date: 2016-06-01, 10:34:26 GMT + # + (0x00300, 0x0036f,), # Combining Grave Accent ..Combining Latin Small Le + (0x00483, 0x00489,), # Combining Cyrillic Titlo..Combining Cyrillic Milli + (0x00591, 0x005bd,), # Hebrew Accent Etnahta ..Hebrew Point Meteg + (0x005bf, 0x005bf,), # Hebrew Point Rafe ..Hebrew Point Rafe + (0x005c1, 0x005c2,), # Hebrew Point Shin Dot ..Hebrew Point Sin Dot + (0x005c4, 0x005c5,), # Hebrew Mark Upper Dot ..Hebrew Mark Lower Dot + (0x005c7, 0x005c7,), # Hebrew Point Qamats Qata..Hebrew Point Qamats Qata + (0x00610, 0x0061a,), # Arabic Sign Sallallahou ..Arabic Small Kasra + (0x0064b, 0x0065f,), # Arabic Fathatan ..Arabic Wavy Hamza Below + (0x00670, 0x00670,), # Arabic Letter Superscrip..Arabic Letter Superscrip + (0x006d6, 0x006dc,), # Arabic Small High Ligatu..Arabic Small High Seen + (0x006df, 0x006e4,), # Arabic Small High Rounde..Arabic Small High Madda + (0x006e7, 0x006e8,), # Arabic Small High Yeh ..Arabic Small High Noon + (0x006ea, 0x006ed,), # Arabic Empty Centre Low ..Arabic Small Low Meem + (0x00711, 0x00711,), # Syriac Letter Superscrip..Syriac Letter Superscrip + (0x00730, 0x0074a,), # Syriac Pthaha Above ..Syriac Barrekh + (0x007a6, 0x007b0,), # Thaana Abafili ..Thaana Sukun + (0x007eb, 0x007f3,), # Nko Combining Short High..Nko Combining Double Dot + (0x00816, 0x00819,), # Samaritan Mark In ..Samaritan Mark Dagesh + (0x0081b, 0x00823,), # Samaritan Mark Epentheti..Samaritan Vowel Sign A + (0x00825, 0x00827,), # Samaritan Vowel Sign Sho..Samaritan Vowel Sign U + (0x00829, 0x0082d,), # Samaritan Vowel Sign Lon..Samaritan Mark Nequdaa + (0x00859, 0x0085b,), # Mandaic Affrication Mark..Mandaic Gemination Mark + (0x008d4, 0x008e1,), # Arabic Small High Word A..Arabic Small High Sign S + (0x008e3, 0x00902,), # Arabic Turned Damma Belo..Devanagari Sign Anusvara + (0x0093a, 0x0093a,), # Devanagari Vowel Sign Oe..Devanagari Vowel Sign Oe + (0x0093c, 0x0093c,), # Devanagari Sign Nukta ..Devanagari Sign Nukta + (0x00941, 0x00948,), # Devanagari Vowel Sign U ..Devanagari Vowel Sign Ai + (0x0094d, 0x0094d,), # Devanagari Sign Virama ..Devanagari Sign Virama + (0x00951, 0x00957,), # Devanagari Stress Sign U..Devanagari Vowel Sign Uu + (0x00962, 0x00963,), # Devanagari Vowel Sign Vo..Devanagari Vowel Sign Vo + (0x00981, 0x00981,), # Bengali Sign Candrabindu..Bengali Sign Candrabindu + (0x009bc, 0x009bc,), # Bengali Sign Nukta ..Bengali Sign Nukta + (0x009c1, 0x009c4,), # Bengali Vowel Sign U ..Bengali Vowel Sign Vocal + (0x009cd, 0x009cd,), # Bengali Sign Virama ..Bengali Sign Virama + (0x009e2, 0x009e3,), # Bengali Vowel Sign Vocal..Bengali Vowel Sign Vocal + (0x00a01, 0x00a02,), # Gurmukhi Sign Adak Bindi..Gurmukhi Sign Bindi + (0x00a3c, 0x00a3c,), # Gurmukhi Sign Nukta ..Gurmukhi Sign Nukta + (0x00a41, 0x00a42,), # Gurmukhi Vowel Sign U ..Gurmukhi Vowel Sign Uu + (0x00a47, 0x00a48,), # Gurmukhi Vowel Sign Ee ..Gurmukhi Vowel Sign Ai + (0x00a4b, 0x00a4d,), # Gurmukhi Vowel Sign Oo ..Gurmukhi Sign Virama + (0x00a51, 0x00a51,), # Gurmukhi Sign Udaat ..Gurmukhi Sign Udaat + (0x00a70, 0x00a71,), # Gurmukhi Tippi ..Gurmukhi Addak + (0x00a75, 0x00a75,), # Gurmukhi Sign Yakash ..Gurmukhi Sign Yakash + (0x00a81, 0x00a82,), # Gujarati Sign Candrabind..Gujarati Sign Anusvara + (0x00abc, 0x00abc,), # Gujarati Sign Nukta ..Gujarati Sign Nukta + (0x00ac1, 0x00ac5,), # Gujarati Vowel Sign U ..Gujarati Vowel Sign Cand + (0x00ac7, 0x00ac8,), # Gujarati Vowel Sign E ..Gujarati Vowel Sign Ai + (0x00acd, 0x00acd,), # Gujarati Sign Virama ..Gujarati Sign Virama + (0x00ae2, 0x00ae3,), # Gujarati Vowel Sign Voca..Gujarati Vowel Sign Voca + (0x00b01, 0x00b01,), # Oriya Sign Candrabindu ..Oriya Sign Candrabindu + (0x00b3c, 0x00b3c,), # Oriya Sign Nukta ..Oriya Sign Nukta + (0x00b3f, 0x00b3f,), # Oriya Vowel Sign I ..Oriya Vowel Sign I + (0x00b41, 0x00b44,), # Oriya Vowel Sign U ..Oriya Vowel Sign Vocalic + (0x00b4d, 0x00b4d,), # Oriya Sign Virama ..Oriya Sign Virama + (0x00b56, 0x00b56,), # Oriya Ai Length Mark ..Oriya Ai Length Mark + (0x00b62, 0x00b63,), # Oriya Vowel Sign Vocalic..Oriya Vowel Sign Vocalic + (0x00b82, 0x00b82,), # Tamil Sign Anusvara ..Tamil Sign Anusvara + (0x00bc0, 0x00bc0,), # Tamil Vowel Sign Ii ..Tamil Vowel Sign Ii + (0x00bcd, 0x00bcd,), # Tamil Sign Virama ..Tamil Sign Virama + (0x00c00, 0x00c00,), # Telugu Sign Combining Ca..Telugu Sign Combining Ca + (0x00c3e, 0x00c40,), # Telugu Vowel Sign Aa ..Telugu Vowel Sign Ii + (0x00c46, 0x00c48,), # Telugu Vowel Sign E ..Telugu Vowel Sign Ai + (0x00c4a, 0x00c4d,), # Telugu Vowel Sign O ..Telugu Sign Virama + (0x00c55, 0x00c56,), # Telugu Length Mark ..Telugu Ai Length Mark + (0x00c62, 0x00c63,), # Telugu Vowel Sign Vocali..Telugu Vowel Sign Vocali + (0x00c81, 0x00c81,), # Kannada Sign Candrabindu..Kannada Sign Candrabindu + (0x00cbc, 0x00cbc,), # Kannada Sign Nukta ..Kannada Sign Nukta + (0x00cbf, 0x00cbf,), # Kannada Vowel Sign I ..Kannada Vowel Sign I + (0x00cc6, 0x00cc6,), # Kannada Vowel Sign E ..Kannada Vowel Sign E + (0x00ccc, 0x00ccd,), # Kannada Vowel Sign Au ..Kannada Sign Virama + (0x00ce2, 0x00ce3,), # Kannada Vowel Sign Vocal..Kannada Vowel Sign Vocal + (0x00d01, 0x00d01,), # Malayalam Sign Candrabin..Malayalam Sign Candrabin + (0x00d41, 0x00d44,), # Malayalam Vowel Sign U ..Malayalam Vowel Sign Voc + (0x00d4d, 0x00d4d,), # Malayalam Sign Virama ..Malayalam Sign Virama + (0x00d62, 0x00d63,), # Malayalam Vowel Sign Voc..Malayalam Vowel Sign Voc + (0x00dca, 0x00dca,), # Sinhala Sign Al-lakuna ..Sinhala Sign Al-lakuna + (0x00dd2, 0x00dd4,), # Sinhala Vowel Sign Ketti..Sinhala Vowel Sign Ketti + (0x00dd6, 0x00dd6,), # Sinhala Vowel Sign Diga ..Sinhala Vowel Sign Diga + (0x00e31, 0x00e31,), # Thai Character Mai Han-a..Thai Character Mai Han-a + (0x00e34, 0x00e3a,), # Thai Character Sara I ..Thai Character Phinthu + (0x00e47, 0x00e4e,), # Thai Character Maitaikhu..Thai Character Yamakkan + (0x00eb1, 0x00eb1,), # Lao Vowel Sign Mai Kan ..Lao Vowel Sign Mai Kan + (0x00eb4, 0x00eb9,), # Lao Vowel Sign I ..Lao Vowel Sign Uu + (0x00ebb, 0x00ebc,), # Lao Vowel Sign Mai Kon ..Lao Semivowel Sign Lo + (0x00ec8, 0x00ecd,), # Lao Tone Mai Ek ..Lao Niggahita + (0x00f18, 0x00f19,), # Tibetan Astrological Sig..Tibetan Astrological Sig + (0x00f35, 0x00f35,), # Tibetan Mark Ngas Bzung ..Tibetan Mark Ngas Bzung + (0x00f37, 0x00f37,), # Tibetan Mark Ngas Bzung ..Tibetan Mark Ngas Bzung + (0x00f39, 0x00f39,), # Tibetan Mark Tsa -phru ..Tibetan Mark Tsa -phru + (0x00f71, 0x00f7e,), # Tibetan Vowel Sign Aa ..Tibetan Sign Rjes Su Nga + (0x00f80, 0x00f84,), # Tibetan Vowel Sign Rever..Tibetan Mark Halanta + (0x00f86, 0x00f87,), # Tibetan Sign Lci Rtags ..Tibetan Sign Yang Rtags + (0x00f8d, 0x00f97,), # Tibetan Subjoined Sign L..Tibetan Subjoined Letter + (0x00f99, 0x00fbc,), # Tibetan Subjoined Letter..Tibetan Subjoined Letter + (0x00fc6, 0x00fc6,), # Tibetan Symbol Padma Gda..Tibetan Symbol Padma Gda + (0x0102d, 0x01030,), # Myanmar Vowel Sign I ..Myanmar Vowel Sign Uu + (0x01032, 0x01037,), # Myanmar Vowel Sign Ai ..Myanmar Sign Dot Below + (0x01039, 0x0103a,), # Myanmar Sign Virama ..Myanmar Sign Asat + (0x0103d, 0x0103e,), # Myanmar Consonant Sign M..Myanmar Consonant Sign M + (0x01058, 0x01059,), # Myanmar Vowel Sign Vocal..Myanmar Vowel Sign Vocal + (0x0105e, 0x01060,), # Myanmar Consonant Sign M..Myanmar Consonant Sign M + (0x01071, 0x01074,), # Myanmar Vowel Sign Geba ..Myanmar Vowel Sign Kayah + (0x01082, 0x01082,), # Myanmar Consonant Sign S..Myanmar Consonant Sign S + (0x01085, 0x01086,), # Myanmar Vowel Sign Shan ..Myanmar Vowel Sign Shan + (0x0108d, 0x0108d,), # Myanmar Sign Shan Counci..Myanmar Sign Shan Counci + (0x0109d, 0x0109d,), # Myanmar Vowel Sign Aiton..Myanmar Vowel Sign Aiton + (0x0135d, 0x0135f,), # Ethiopic Combining Gemin..Ethiopic Combining Gemin + (0x01712, 0x01714,), # Tagalog Vowel Sign I ..Tagalog Sign Virama + (0x01732, 0x01734,), # Hanunoo Vowel Sign I ..Hanunoo Sign Pamudpod + (0x01752, 0x01753,), # Buhid Vowel Sign I ..Buhid Vowel Sign U + (0x01772, 0x01773,), # Tagbanwa Vowel Sign I ..Tagbanwa Vowel Sign U + (0x017b4, 0x017b5,), # Khmer Vowel Inherent Aq ..Khmer Vowel Inherent Aa + (0x017b7, 0x017bd,), # Khmer Vowel Sign I ..Khmer Vowel Sign Ua + (0x017c6, 0x017c6,), # Khmer Sign Nikahit ..Khmer Sign Nikahit + (0x017c9, 0x017d3,), # Khmer Sign Muusikatoan ..Khmer Sign Bathamasat + (0x017dd, 0x017dd,), # Khmer Sign Atthacan ..Khmer Sign Atthacan + (0x0180b, 0x0180d,), # Mongolian Free Variation..Mongolian Free Variation + (0x01885, 0x01886,), # Mongolian Letter Ali Gal..Mongolian Letter Ali Gal + (0x018a9, 0x018a9,), # Mongolian Letter Ali Gal..Mongolian Letter Ali Gal + (0x01920, 0x01922,), # Limbu Vowel Sign A ..Limbu Vowel Sign U + (0x01927, 0x01928,), # Limbu Vowel Sign E ..Limbu Vowel Sign O + (0x01932, 0x01932,), # Limbu Small Letter Anusv..Limbu Small Letter Anusv + (0x01939, 0x0193b,), # Limbu Sign Mukphreng ..Limbu Sign Sa-i + (0x01a17, 0x01a18,), # Buginese Vowel Sign I ..Buginese Vowel Sign U + (0x01a1b, 0x01a1b,), # Buginese Vowel Sign Ae ..Buginese Vowel Sign Ae + (0x01a56, 0x01a56,), # Tai Tham Consonant Sign ..Tai Tham Consonant Sign + (0x01a58, 0x01a5e,), # Tai Tham Sign Mai Kang L..Tai Tham Consonant Sign + (0x01a60, 0x01a60,), # Tai Tham Sign Sakot ..Tai Tham Sign Sakot + (0x01a62, 0x01a62,), # Tai Tham Vowel Sign Mai ..Tai Tham Vowel Sign Mai + (0x01a65, 0x01a6c,), # Tai Tham Vowel Sign I ..Tai Tham Vowel Sign Oa B + (0x01a73, 0x01a7c,), # Tai Tham Vowel Sign Oa A..Tai Tham Sign Khuen-lue + (0x01a7f, 0x01a7f,), # Tai Tham Combining Crypt..Tai Tham Combining Crypt + (0x01ab0, 0x01abe,), # Combining Doubled Circum..Combining Parentheses Ov + (0x01b00, 0x01b03,), # Balinese Sign Ulu Ricem ..Balinese Sign Surang + (0x01b34, 0x01b34,), # Balinese Sign Rerekan ..Balinese Sign Rerekan + (0x01b36, 0x01b3a,), # Balinese Vowel Sign Ulu ..Balinese Vowel Sign Ra R + (0x01b3c, 0x01b3c,), # Balinese Vowel Sign La L..Balinese Vowel Sign La L + (0x01b42, 0x01b42,), # Balinese Vowel Sign Pepe..Balinese Vowel Sign Pepe + (0x01b6b, 0x01b73,), # Balinese Musical Symbol ..Balinese Musical Symbol + (0x01b80, 0x01b81,), # Sundanese Sign Panyecek ..Sundanese Sign Panglayar + (0x01ba2, 0x01ba5,), # Sundanese Consonant Sign..Sundanese Vowel Sign Pan + (0x01ba8, 0x01ba9,), # Sundanese Vowel Sign Pam..Sundanese Vowel Sign Pan + (0x01bab, 0x01bad,), # Sundanese Sign Virama ..Sundanese Consonant Sign + (0x01be6, 0x01be6,), # Batak Sign Tompi ..Batak Sign Tompi + (0x01be8, 0x01be9,), # Batak Vowel Sign Pakpak ..Batak Vowel Sign Ee + (0x01bed, 0x01bed,), # Batak Vowel Sign Karo O ..Batak Vowel Sign Karo O + (0x01bef, 0x01bf1,), # Batak Vowel Sign U For S..Batak Consonant Sign H + (0x01c2c, 0x01c33,), # Lepcha Vowel Sign E ..Lepcha Consonant Sign T + (0x01c36, 0x01c37,), # Lepcha Sign Ran ..Lepcha Sign Nukta + (0x01cd0, 0x01cd2,), # Vedic Tone Karshana ..Vedic Tone Prenkha + (0x01cd4, 0x01ce0,), # Vedic Sign Yajurvedic Mi..Vedic Tone Rigvedic Kash + (0x01ce2, 0x01ce8,), # Vedic Sign Visarga Svari..Vedic Sign Visarga Anuda + (0x01ced, 0x01ced,), # Vedic Sign Tiryak ..Vedic Sign Tiryak + (0x01cf4, 0x01cf4,), # Vedic Tone Candra Above ..Vedic Tone Candra Above + (0x01cf8, 0x01cf9,), # Vedic Tone Ring Above ..Vedic Tone Double Ring A + (0x01dc0, 0x01df5,), # Combining Dotted Grave A..Combining Up Tack Above + (0x01dfb, 0x01dff,), # Combining Deletion Mark ..Combining Right Arrowhea + (0x020d0, 0x020f0,), # Combining Left Harpoon A..Combining Asterisk Above + (0x02cef, 0x02cf1,), # Coptic Combining Ni Abov..Coptic Combining Spiritu + (0x02d7f, 0x02d7f,), # Tifinagh Consonant Joine..Tifinagh Consonant Joine + (0x02de0, 0x02dff,), # Combining Cyrillic Lette..Combining Cyrillic Lette + (0x0302a, 0x0302d,), # Ideographic Level Tone M..Ideographic Entering Ton + (0x03099, 0x0309a,), # Combining Katakana-hirag..Combining Katakana-hirag + (0x0a66f, 0x0a672,), # Combining Cyrillic Vzmet..Combining Cyrillic Thous + (0x0a674, 0x0a67d,), # Combining Cyrillic Lette..Combining Cyrillic Payer + (0x0a69e, 0x0a69f,), # Combining Cyrillic Lette..Combining Cyrillic Lette + (0x0a6f0, 0x0a6f1,), # Bamum Combining Mark Koq..Bamum Combining Mark Tuk + (0x0a802, 0x0a802,), # Syloti Nagri Sign Dvisva..Syloti Nagri Sign Dvisva + (0x0a806, 0x0a806,), # Syloti Nagri Sign Hasant..Syloti Nagri Sign Hasant + (0x0a80b, 0x0a80b,), # Syloti Nagri Sign Anusva..Syloti Nagri Sign Anusva + (0x0a825, 0x0a826,), # Syloti Nagri Vowel Sign ..Syloti Nagri Vowel Sign + (0x0a8c4, 0x0a8c5,), # Saurashtra Sign Virama ..Saurashtra Sign Candrabi + (0x0a8e0, 0x0a8f1,), # Combining Devanagari Dig..Combining Devanagari Sig + (0x0a926, 0x0a92d,), # Kayah Li Vowel Ue ..Kayah Li Tone Calya Plop + (0x0a947, 0x0a951,), # Rejang Vowel Sign I ..Rejang Consonant Sign R + (0x0a980, 0x0a982,), # Javanese Sign Panyangga ..Javanese Sign Layar + (0x0a9b3, 0x0a9b3,), # Javanese Sign Cecak Telu..Javanese Sign Cecak Telu + (0x0a9b6, 0x0a9b9,), # Javanese Vowel Sign Wulu..Javanese Vowel Sign Suku + (0x0a9bc, 0x0a9bc,), # Javanese Vowel Sign Pepe..Javanese Vowel Sign Pepe + (0x0a9e5, 0x0a9e5,), # Myanmar Sign Shan Saw ..Myanmar Sign Shan Saw + (0x0aa29, 0x0aa2e,), # Cham Vowel Sign Aa ..Cham Vowel Sign Oe + (0x0aa31, 0x0aa32,), # Cham Vowel Sign Au ..Cham Vowel Sign Ue + (0x0aa35, 0x0aa36,), # Cham Consonant Sign La ..Cham Consonant Sign Wa + (0x0aa43, 0x0aa43,), # Cham Consonant Sign Fina..Cham Consonant Sign Fina + (0x0aa4c, 0x0aa4c,), # Cham Consonant Sign Fina..Cham Consonant Sign Fina + (0x0aa7c, 0x0aa7c,), # Myanmar Sign Tai Laing T..Myanmar Sign Tai Laing T + (0x0aab0, 0x0aab0,), # Tai Viet Mai Kang ..Tai Viet Mai Kang + (0x0aab2, 0x0aab4,), # Tai Viet Vowel I ..Tai Viet Vowel U + (0x0aab7, 0x0aab8,), # Tai Viet Mai Khit ..Tai Viet Vowel Ia + (0x0aabe, 0x0aabf,), # Tai Viet Vowel Am ..Tai Viet Tone Mai Ek + (0x0aac1, 0x0aac1,), # Tai Viet Tone Mai Tho ..Tai Viet Tone Mai Tho + (0x0aaec, 0x0aaed,), # Meetei Mayek Vowel Sign ..Meetei Mayek Vowel Sign + (0x0aaf6, 0x0aaf6,), # Meetei Mayek Virama ..Meetei Mayek Virama + (0x0abe5, 0x0abe5,), # Meetei Mayek Vowel Sign ..Meetei Mayek Vowel Sign + (0x0abe8, 0x0abe8,), # Meetei Mayek Vowel Sign ..Meetei Mayek Vowel Sign + (0x0abed, 0x0abed,), # Meetei Mayek Apun Iyek ..Meetei Mayek Apun Iyek + (0x0fb1e, 0x0fb1e,), # Hebrew Point Judeo-spani..Hebrew Point Judeo-spani + (0x0fe00, 0x0fe0f,), # Variation Selector-1 ..Variation Selector-16 + (0x0fe20, 0x0fe2f,), # Combining Ligature Left ..Combining Cyrillic Titlo + (0x101fd, 0x101fd,), # Phaistos Disc Sign Combi..Phaistos Disc Sign Combi + (0x102e0, 0x102e0,), # Coptic Epact Thousands M..Coptic Epact Thousands M + (0x10376, 0x1037a,), # Combining Old Permic Let..Combining Old Permic Let + (0x10a01, 0x10a03,), # Kharoshthi Vowel Sign I ..Kharoshthi Vowel Sign Vo + (0x10a05, 0x10a06,), # Kharoshthi Vowel Sign E ..Kharoshthi Vowel Sign O + (0x10a0c, 0x10a0f,), # Kharoshthi Vowel Length ..Kharoshthi Sign Visarga + (0x10a38, 0x10a3a,), # Kharoshthi Sign Bar Abov..Kharoshthi Sign Dot Belo + (0x10a3f, 0x10a3f,), # Kharoshthi Virama ..Kharoshthi Virama + (0x10ae5, 0x10ae6,), # Manichaean Abbreviation ..Manichaean Abbreviation + (0x11001, 0x11001,), # Brahmi Sign Anusvara ..Brahmi Sign Anusvara + (0x11038, 0x11046,), # Brahmi Vowel Sign Aa ..Brahmi Virama + (0x1107f, 0x11081,), # Brahmi Number Joiner ..Kaithi Sign Anusvara + (0x110b3, 0x110b6,), # Kaithi Vowel Sign U ..Kaithi Vowel Sign Ai + (0x110b9, 0x110ba,), # Kaithi Sign Virama ..Kaithi Sign Nukta + (0x11100, 0x11102,), # Chakma Sign Candrabindu ..Chakma Sign Visarga + (0x11127, 0x1112b,), # Chakma Vowel Sign A ..Chakma Vowel Sign Uu + (0x1112d, 0x11134,), # Chakma Vowel Sign Ai ..Chakma Maayyaa + (0x11173, 0x11173,), # Mahajani Sign Nukta ..Mahajani Sign Nukta + (0x11180, 0x11181,), # Sharada Sign Candrabindu..Sharada Sign Anusvara + (0x111b6, 0x111be,), # Sharada Vowel Sign U ..Sharada Vowel Sign O + (0x111ca, 0x111cc,), # Sharada Sign Nukta ..Sharada Extra Short Vowe + (0x1122f, 0x11231,), # Khojki Vowel Sign U ..Khojki Vowel Sign Ai + (0x11234, 0x11234,), # Khojki Sign Anusvara ..Khojki Sign Anusvara + (0x11236, 0x11237,), # Khojki Sign Nukta ..Khojki Sign Shadda + (0x1123e, 0x1123e,), # Khojki Sign Sukun ..Khojki Sign Sukun + (0x112df, 0x112df,), # Khudawadi Sign Anusvara ..Khudawadi Sign Anusvara + (0x112e3, 0x112ea,), # Khudawadi Vowel Sign U ..Khudawadi Sign Virama + (0x11300, 0x11301,), # Grantha Sign Combining A..Grantha Sign Candrabindu + (0x1133c, 0x1133c,), # Grantha Sign Nukta ..Grantha Sign Nukta + (0x11340, 0x11340,), # Grantha Vowel Sign Ii ..Grantha Vowel Sign Ii + (0x11366, 0x1136c,), # Combining Grantha Digit ..Combining Grantha Digit + (0x11370, 0x11374,), # Combining Grantha Letter..Combining Grantha Letter + (0x11438, 0x1143f,), # Newa Vowel Sign U ..Newa Vowel Sign Ai + (0x11442, 0x11444,), # Newa Sign Virama ..Newa Sign Anusvara + (0x11446, 0x11446,), # Newa Sign Nukta ..Newa Sign Nukta + (0x114b3, 0x114b8,), # Tirhuta Vowel Sign U ..Tirhuta Vowel Sign Vocal + (0x114ba, 0x114ba,), # Tirhuta Vowel Sign Short..Tirhuta Vowel Sign Short + (0x114bf, 0x114c0,), # Tirhuta Sign Candrabindu..Tirhuta Sign Anusvara + (0x114c2, 0x114c3,), # Tirhuta Sign Virama ..Tirhuta Sign Nukta + (0x115b2, 0x115b5,), # Siddham Vowel Sign U ..Siddham Vowel Sign Vocal + (0x115bc, 0x115bd,), # Siddham Sign Candrabindu..Siddham Sign Anusvara + (0x115bf, 0x115c0,), # Siddham Sign Virama ..Siddham Sign Nukta + (0x115dc, 0x115dd,), # Siddham Vowel Sign Alter..Siddham Vowel Sign Alter + (0x11633, 0x1163a,), # Modi Vowel Sign U ..Modi Vowel Sign Ai + (0x1163d, 0x1163d,), # Modi Sign Anusvara ..Modi Sign Anusvara + (0x1163f, 0x11640,), # Modi Sign Virama ..Modi Sign Ardhacandra + (0x116ab, 0x116ab,), # Takri Sign Anusvara ..Takri Sign Anusvara + (0x116ad, 0x116ad,), # Takri Vowel Sign Aa ..Takri Vowel Sign Aa + (0x116b0, 0x116b5,), # Takri Vowel Sign U ..Takri Vowel Sign Au + (0x116b7, 0x116b7,), # Takri Sign Nukta ..Takri Sign Nukta + (0x1171d, 0x1171f,), # Ahom Consonant Sign Medi..Ahom Consonant Sign Medi + (0x11722, 0x11725,), # Ahom Vowel Sign I ..Ahom Vowel Sign Uu + (0x11727, 0x1172b,), # Ahom Vowel Sign Aw ..Ahom Sign Killer + (0x11c30, 0x11c36,), # Bhaiksuki Vowel Sign I ..Bhaiksuki Vowel Sign Voc + (0x11c38, 0x11c3d,), # Bhaiksuki Vowel Sign E ..Bhaiksuki Sign Anusvara + (0x11c3f, 0x11c3f,), # Bhaiksuki Sign Virama ..Bhaiksuki Sign Virama + (0x11c92, 0x11ca7,), # Marchen Subjoined Letter..Marchen Subjoined Letter + (0x11caa, 0x11cb0,), # Marchen Subjoined Letter..Marchen Vowel Sign Aa + (0x11cb2, 0x11cb3,), # Marchen Vowel Sign U ..Marchen Vowel Sign E + (0x11cb5, 0x11cb6,), # Marchen Sign Anusvara ..Marchen Sign Candrabindu + (0x16af0, 0x16af4,), # Bassa Vah Combining High..Bassa Vah Combining High + (0x16b30, 0x16b36,), # Pahawh Hmong Mark Cim Tu..Pahawh Hmong Mark Cim Ta + (0x16f8f, 0x16f92,), # Miao Tone Right ..Miao Tone Below + (0x1bc9d, 0x1bc9e,), # Duployan Thick Letter Se..Duployan Double Mark + (0x1d167, 0x1d169,), # Musical Symbol Combining..Musical Symbol Combining + (0x1d17b, 0x1d182,), # Musical Symbol Combining..Musical Symbol Combining + (0x1d185, 0x1d18b,), # Musical Symbol Combining..Musical Symbol Combining + (0x1d1aa, 0x1d1ad,), # Musical Symbol Combining..Musical Symbol Combining + (0x1d242, 0x1d244,), # Combining Greek Musical ..Combining Greek Musical + (0x1da00, 0x1da36,), # Signwriting Head Rim ..Signwriting Air Sucking + (0x1da3b, 0x1da6c,), # Signwriting Mouth Closed..Signwriting Excitement + (0x1da75, 0x1da75,), # Signwriting Upper Body T..Signwriting Upper Body T + (0x1da84, 0x1da84,), # Signwriting Location Hea..Signwriting Location Hea + (0x1da9b, 0x1da9f,), # Signwriting Fill Modifie..Signwriting Fill Modifie + (0x1daa1, 0x1daaf,), # Signwriting Rotation Mod..Signwriting Rotation Mod + (0x1e000, 0x1e006,), # Combining Glagolitic Let..Combining Glagolitic Let + (0x1e008, 0x1e018,), # Combining Glagolitic Let..Combining Glagolitic Let + (0x1e01b, 0x1e021,), # Combining Glagolitic Let..Combining Glagolitic Let + (0x1e023, 0x1e024,), # Combining Glagolitic Let..Combining Glagolitic Let + (0x1e026, 0x1e02a,), # Combining Glagolitic Let..Combining Glagolitic Let + (0x1e8d0, 0x1e8d6,), # Mende Kikakui Combining ..Mende Kikakui Combining + (0x1e944, 0x1e94a,), # Adlam Alif Lengthener ..Adlam Nukta + (0xe0100, 0xe01ef,), # Variation Selector-17 ..Variation Selector-256 + ), + '10.0.0': ( + # Source: DerivedGeneralCategory-10.0.0.txt + # Date: 2017-03-08, 08:41:49 GMT + # + (0x00300, 0x0036f,), # Combining Grave Accent ..Combining Latin Small Le + (0x00483, 0x00489,), # Combining Cyrillic Titlo..Combining Cyrillic Milli + (0x00591, 0x005bd,), # Hebrew Accent Etnahta ..Hebrew Point Meteg + (0x005bf, 0x005bf,), # Hebrew Point Rafe ..Hebrew Point Rafe + (0x005c1, 0x005c2,), # Hebrew Point Shin Dot ..Hebrew Point Sin Dot + (0x005c4, 0x005c5,), # Hebrew Mark Upper Dot ..Hebrew Mark Lower Dot + (0x005c7, 0x005c7,), # Hebrew Point Qamats Qata..Hebrew Point Qamats Qata + (0x00610, 0x0061a,), # Arabic Sign Sallallahou ..Arabic Small Kasra + (0x0064b, 0x0065f,), # Arabic Fathatan ..Arabic Wavy Hamza Below + (0x00670, 0x00670,), # Arabic Letter Superscrip..Arabic Letter Superscrip + (0x006d6, 0x006dc,), # Arabic Small High Ligatu..Arabic Small High Seen + (0x006df, 0x006e4,), # Arabic Small High Rounde..Arabic Small High Madda + (0x006e7, 0x006e8,), # Arabic Small High Yeh ..Arabic Small High Noon + (0x006ea, 0x006ed,), # Arabic Empty Centre Low ..Arabic Small Low Meem + (0x00711, 0x00711,), # Syriac Letter Superscrip..Syriac Letter Superscrip + (0x00730, 0x0074a,), # Syriac Pthaha Above ..Syriac Barrekh + (0x007a6, 0x007b0,), # Thaana Abafili ..Thaana Sukun + (0x007eb, 0x007f3,), # Nko Combining Short High..Nko Combining Double Dot + (0x00816, 0x00819,), # Samaritan Mark In ..Samaritan Mark Dagesh + (0x0081b, 0x00823,), # Samaritan Mark Epentheti..Samaritan Vowel Sign A + (0x00825, 0x00827,), # Samaritan Vowel Sign Sho..Samaritan Vowel Sign U + (0x00829, 0x0082d,), # Samaritan Vowel Sign Lon..Samaritan Mark Nequdaa + (0x00859, 0x0085b,), # Mandaic Affrication Mark..Mandaic Gemination Mark + (0x008d4, 0x008e1,), # Arabic Small High Word A..Arabic Small High Sign S + (0x008e3, 0x00902,), # Arabic Turned Damma Belo..Devanagari Sign Anusvara + (0x0093a, 0x0093a,), # Devanagari Vowel Sign Oe..Devanagari Vowel Sign Oe + (0x0093c, 0x0093c,), # Devanagari Sign Nukta ..Devanagari Sign Nukta + (0x00941, 0x00948,), # Devanagari Vowel Sign U ..Devanagari Vowel Sign Ai + (0x0094d, 0x0094d,), # Devanagari Sign Virama ..Devanagari Sign Virama + (0x00951, 0x00957,), # Devanagari Stress Sign U..Devanagari Vowel Sign Uu + (0x00962, 0x00963,), # Devanagari Vowel Sign Vo..Devanagari Vowel Sign Vo + (0x00981, 0x00981,), # Bengali Sign Candrabindu..Bengali Sign Candrabindu + (0x009bc, 0x009bc,), # Bengali Sign Nukta ..Bengali Sign Nukta + (0x009c1, 0x009c4,), # Bengali Vowel Sign U ..Bengali Vowel Sign Vocal + (0x009cd, 0x009cd,), # Bengali Sign Virama ..Bengali Sign Virama + (0x009e2, 0x009e3,), # Bengali Vowel Sign Vocal..Bengali Vowel Sign Vocal + (0x00a01, 0x00a02,), # Gurmukhi Sign Adak Bindi..Gurmukhi Sign Bindi + (0x00a3c, 0x00a3c,), # Gurmukhi Sign Nukta ..Gurmukhi Sign Nukta + (0x00a41, 0x00a42,), # Gurmukhi Vowel Sign U ..Gurmukhi Vowel Sign Uu + (0x00a47, 0x00a48,), # Gurmukhi Vowel Sign Ee ..Gurmukhi Vowel Sign Ai + (0x00a4b, 0x00a4d,), # Gurmukhi Vowel Sign Oo ..Gurmukhi Sign Virama + (0x00a51, 0x00a51,), # Gurmukhi Sign Udaat ..Gurmukhi Sign Udaat + (0x00a70, 0x00a71,), # Gurmukhi Tippi ..Gurmukhi Addak + (0x00a75, 0x00a75,), # Gurmukhi Sign Yakash ..Gurmukhi Sign Yakash + (0x00a81, 0x00a82,), # Gujarati Sign Candrabind..Gujarati Sign Anusvara + (0x00abc, 0x00abc,), # Gujarati Sign Nukta ..Gujarati Sign Nukta + (0x00ac1, 0x00ac5,), # Gujarati Vowel Sign U ..Gujarati Vowel Sign Cand + (0x00ac7, 0x00ac8,), # Gujarati Vowel Sign E ..Gujarati Vowel Sign Ai + (0x00acd, 0x00acd,), # Gujarati Sign Virama ..Gujarati Sign Virama + (0x00ae2, 0x00ae3,), # Gujarati Vowel Sign Voca..Gujarati Vowel Sign Voca + (0x00afa, 0x00aff,), # Gujarati Sign Sukun ..Gujarati Sign Two-circle + (0x00b01, 0x00b01,), # Oriya Sign Candrabindu ..Oriya Sign Candrabindu + (0x00b3c, 0x00b3c,), # Oriya Sign Nukta ..Oriya Sign Nukta + (0x00b3f, 0x00b3f,), # Oriya Vowel Sign I ..Oriya Vowel Sign I + (0x00b41, 0x00b44,), # Oriya Vowel Sign U ..Oriya Vowel Sign Vocalic + (0x00b4d, 0x00b4d,), # Oriya Sign Virama ..Oriya Sign Virama + (0x00b56, 0x00b56,), # Oriya Ai Length Mark ..Oriya Ai Length Mark + (0x00b62, 0x00b63,), # Oriya Vowel Sign Vocalic..Oriya Vowel Sign Vocalic + (0x00b82, 0x00b82,), # Tamil Sign Anusvara ..Tamil Sign Anusvara + (0x00bc0, 0x00bc0,), # Tamil Vowel Sign Ii ..Tamil Vowel Sign Ii + (0x00bcd, 0x00bcd,), # Tamil Sign Virama ..Tamil Sign Virama + (0x00c00, 0x00c00,), # Telugu Sign Combining Ca..Telugu Sign Combining Ca + (0x00c3e, 0x00c40,), # Telugu Vowel Sign Aa ..Telugu Vowel Sign Ii + (0x00c46, 0x00c48,), # Telugu Vowel Sign E ..Telugu Vowel Sign Ai + (0x00c4a, 0x00c4d,), # Telugu Vowel Sign O ..Telugu Sign Virama + (0x00c55, 0x00c56,), # Telugu Length Mark ..Telugu Ai Length Mark + (0x00c62, 0x00c63,), # Telugu Vowel Sign Vocali..Telugu Vowel Sign Vocali + (0x00c81, 0x00c81,), # Kannada Sign Candrabindu..Kannada Sign Candrabindu + (0x00cbc, 0x00cbc,), # Kannada Sign Nukta ..Kannada Sign Nukta + (0x00cbf, 0x00cbf,), # Kannada Vowel Sign I ..Kannada Vowel Sign I + (0x00cc6, 0x00cc6,), # Kannada Vowel Sign E ..Kannada Vowel Sign E + (0x00ccc, 0x00ccd,), # Kannada Vowel Sign Au ..Kannada Sign Virama + (0x00ce2, 0x00ce3,), # Kannada Vowel Sign Vocal..Kannada Vowel Sign Vocal + (0x00d00, 0x00d01,), # Malayalam Sign Combining..Malayalam Sign Candrabin + (0x00d3b, 0x00d3c,), # Malayalam Sign Vertical ..Malayalam Sign Circular + (0x00d41, 0x00d44,), # Malayalam Vowel Sign U ..Malayalam Vowel Sign Voc + (0x00d4d, 0x00d4d,), # Malayalam Sign Virama ..Malayalam Sign Virama + (0x00d62, 0x00d63,), # Malayalam Vowel Sign Voc..Malayalam Vowel Sign Voc + (0x00dca, 0x00dca,), # Sinhala Sign Al-lakuna ..Sinhala Sign Al-lakuna + (0x00dd2, 0x00dd4,), # Sinhala Vowel Sign Ketti..Sinhala Vowel Sign Ketti + (0x00dd6, 0x00dd6,), # Sinhala Vowel Sign Diga ..Sinhala Vowel Sign Diga + (0x00e31, 0x00e31,), # Thai Character Mai Han-a..Thai Character Mai Han-a + (0x00e34, 0x00e3a,), # Thai Character Sara I ..Thai Character Phinthu + (0x00e47, 0x00e4e,), # Thai Character Maitaikhu..Thai Character Yamakkan + (0x00eb1, 0x00eb1,), # Lao Vowel Sign Mai Kan ..Lao Vowel Sign Mai Kan + (0x00eb4, 0x00eb9,), # Lao Vowel Sign I ..Lao Vowel Sign Uu + (0x00ebb, 0x00ebc,), # Lao Vowel Sign Mai Kon ..Lao Semivowel Sign Lo + (0x00ec8, 0x00ecd,), # Lao Tone Mai Ek ..Lao Niggahita + (0x00f18, 0x00f19,), # Tibetan Astrological Sig..Tibetan Astrological Sig + (0x00f35, 0x00f35,), # Tibetan Mark Ngas Bzung ..Tibetan Mark Ngas Bzung + (0x00f37, 0x00f37,), # Tibetan Mark Ngas Bzung ..Tibetan Mark Ngas Bzung + (0x00f39, 0x00f39,), # Tibetan Mark Tsa -phru ..Tibetan Mark Tsa -phru + (0x00f71, 0x00f7e,), # Tibetan Vowel Sign Aa ..Tibetan Sign Rjes Su Nga + (0x00f80, 0x00f84,), # Tibetan Vowel Sign Rever..Tibetan Mark Halanta + (0x00f86, 0x00f87,), # Tibetan Sign Lci Rtags ..Tibetan Sign Yang Rtags + (0x00f8d, 0x00f97,), # Tibetan Subjoined Sign L..Tibetan Subjoined Letter + (0x00f99, 0x00fbc,), # Tibetan Subjoined Letter..Tibetan Subjoined Letter + (0x00fc6, 0x00fc6,), # Tibetan Symbol Padma Gda..Tibetan Symbol Padma Gda + (0x0102d, 0x01030,), # Myanmar Vowel Sign I ..Myanmar Vowel Sign Uu + (0x01032, 0x01037,), # Myanmar Vowel Sign Ai ..Myanmar Sign Dot Below + (0x01039, 0x0103a,), # Myanmar Sign Virama ..Myanmar Sign Asat + (0x0103d, 0x0103e,), # Myanmar Consonant Sign M..Myanmar Consonant Sign M + (0x01058, 0x01059,), # Myanmar Vowel Sign Vocal..Myanmar Vowel Sign Vocal + (0x0105e, 0x01060,), # Myanmar Consonant Sign M..Myanmar Consonant Sign M + (0x01071, 0x01074,), # Myanmar Vowel Sign Geba ..Myanmar Vowel Sign Kayah + (0x01082, 0x01082,), # Myanmar Consonant Sign S..Myanmar Consonant Sign S + (0x01085, 0x01086,), # Myanmar Vowel Sign Shan ..Myanmar Vowel Sign Shan + (0x0108d, 0x0108d,), # Myanmar Sign Shan Counci..Myanmar Sign Shan Counci + (0x0109d, 0x0109d,), # Myanmar Vowel Sign Aiton..Myanmar Vowel Sign Aiton + (0x0135d, 0x0135f,), # Ethiopic Combining Gemin..Ethiopic Combining Gemin + (0x01712, 0x01714,), # Tagalog Vowel Sign I ..Tagalog Sign Virama + (0x01732, 0x01734,), # Hanunoo Vowel Sign I ..Hanunoo Sign Pamudpod + (0x01752, 0x01753,), # Buhid Vowel Sign I ..Buhid Vowel Sign U + (0x01772, 0x01773,), # Tagbanwa Vowel Sign I ..Tagbanwa Vowel Sign U + (0x017b4, 0x017b5,), # Khmer Vowel Inherent Aq ..Khmer Vowel Inherent Aa + (0x017b7, 0x017bd,), # Khmer Vowel Sign I ..Khmer Vowel Sign Ua + (0x017c6, 0x017c6,), # Khmer Sign Nikahit ..Khmer Sign Nikahit + (0x017c9, 0x017d3,), # Khmer Sign Muusikatoan ..Khmer Sign Bathamasat + (0x017dd, 0x017dd,), # Khmer Sign Atthacan ..Khmer Sign Atthacan + (0x0180b, 0x0180d,), # Mongolian Free Variation..Mongolian Free Variation + (0x01885, 0x01886,), # Mongolian Letter Ali Gal..Mongolian Letter Ali Gal + (0x018a9, 0x018a9,), # Mongolian Letter Ali Gal..Mongolian Letter Ali Gal + (0x01920, 0x01922,), # Limbu Vowel Sign A ..Limbu Vowel Sign U + (0x01927, 0x01928,), # Limbu Vowel Sign E ..Limbu Vowel Sign O + (0x01932, 0x01932,), # Limbu Small Letter Anusv..Limbu Small Letter Anusv + (0x01939, 0x0193b,), # Limbu Sign Mukphreng ..Limbu Sign Sa-i + (0x01a17, 0x01a18,), # Buginese Vowel Sign I ..Buginese Vowel Sign U + (0x01a1b, 0x01a1b,), # Buginese Vowel Sign Ae ..Buginese Vowel Sign Ae + (0x01a56, 0x01a56,), # Tai Tham Consonant Sign ..Tai Tham Consonant Sign + (0x01a58, 0x01a5e,), # Tai Tham Sign Mai Kang L..Tai Tham Consonant Sign + (0x01a60, 0x01a60,), # Tai Tham Sign Sakot ..Tai Tham Sign Sakot + (0x01a62, 0x01a62,), # Tai Tham Vowel Sign Mai ..Tai Tham Vowel Sign Mai + (0x01a65, 0x01a6c,), # Tai Tham Vowel Sign I ..Tai Tham Vowel Sign Oa B + (0x01a73, 0x01a7c,), # Tai Tham Vowel Sign Oa A..Tai Tham Sign Khuen-lue + (0x01a7f, 0x01a7f,), # Tai Tham Combining Crypt..Tai Tham Combining Crypt + (0x01ab0, 0x01abe,), # Combining Doubled Circum..Combining Parentheses Ov + (0x01b00, 0x01b03,), # Balinese Sign Ulu Ricem ..Balinese Sign Surang + (0x01b34, 0x01b34,), # Balinese Sign Rerekan ..Balinese Sign Rerekan + (0x01b36, 0x01b3a,), # Balinese Vowel Sign Ulu ..Balinese Vowel Sign Ra R + (0x01b3c, 0x01b3c,), # Balinese Vowel Sign La L..Balinese Vowel Sign La L + (0x01b42, 0x01b42,), # Balinese Vowel Sign Pepe..Balinese Vowel Sign Pepe + (0x01b6b, 0x01b73,), # Balinese Musical Symbol ..Balinese Musical Symbol + (0x01b80, 0x01b81,), # Sundanese Sign Panyecek ..Sundanese Sign Panglayar + (0x01ba2, 0x01ba5,), # Sundanese Consonant Sign..Sundanese Vowel Sign Pan + (0x01ba8, 0x01ba9,), # Sundanese Vowel Sign Pam..Sundanese Vowel Sign Pan + (0x01bab, 0x01bad,), # Sundanese Sign Virama ..Sundanese Consonant Sign + (0x01be6, 0x01be6,), # Batak Sign Tompi ..Batak Sign Tompi + (0x01be8, 0x01be9,), # Batak Vowel Sign Pakpak ..Batak Vowel Sign Ee + (0x01bed, 0x01bed,), # Batak Vowel Sign Karo O ..Batak Vowel Sign Karo O + (0x01bef, 0x01bf1,), # Batak Vowel Sign U For S..Batak Consonant Sign H + (0x01c2c, 0x01c33,), # Lepcha Vowel Sign E ..Lepcha Consonant Sign T + (0x01c36, 0x01c37,), # Lepcha Sign Ran ..Lepcha Sign Nukta + (0x01cd0, 0x01cd2,), # Vedic Tone Karshana ..Vedic Tone Prenkha + (0x01cd4, 0x01ce0,), # Vedic Sign Yajurvedic Mi..Vedic Tone Rigvedic Kash + (0x01ce2, 0x01ce8,), # Vedic Sign Visarga Svari..Vedic Sign Visarga Anuda + (0x01ced, 0x01ced,), # Vedic Sign Tiryak ..Vedic Sign Tiryak + (0x01cf4, 0x01cf4,), # Vedic Tone Candra Above ..Vedic Tone Candra Above + (0x01cf8, 0x01cf9,), # Vedic Tone Ring Above ..Vedic Tone Double Ring A + (0x01dc0, 0x01df9,), # Combining Dotted Grave A..Combining Wide Inverted + (0x01dfb, 0x01dff,), # Combining Deletion Mark ..Combining Right Arrowhea + (0x020d0, 0x020f0,), # Combining Left Harpoon A..Combining Asterisk Above + (0x02cef, 0x02cf1,), # Coptic Combining Ni Abov..Coptic Combining Spiritu + (0x02d7f, 0x02d7f,), # Tifinagh Consonant Joine..Tifinagh Consonant Joine + (0x02de0, 0x02dff,), # Combining Cyrillic Lette..Combining Cyrillic Lette + (0x0302a, 0x0302d,), # Ideographic Level Tone M..Ideographic Entering Ton + (0x03099, 0x0309a,), # Combining Katakana-hirag..Combining Katakana-hirag + (0x0a66f, 0x0a672,), # Combining Cyrillic Vzmet..Combining Cyrillic Thous + (0x0a674, 0x0a67d,), # Combining Cyrillic Lette..Combining Cyrillic Payer + (0x0a69e, 0x0a69f,), # Combining Cyrillic Lette..Combining Cyrillic Lette + (0x0a6f0, 0x0a6f1,), # Bamum Combining Mark Koq..Bamum Combining Mark Tuk + (0x0a802, 0x0a802,), # Syloti Nagri Sign Dvisva..Syloti Nagri Sign Dvisva + (0x0a806, 0x0a806,), # Syloti Nagri Sign Hasant..Syloti Nagri Sign Hasant + (0x0a80b, 0x0a80b,), # Syloti Nagri Sign Anusva..Syloti Nagri Sign Anusva + (0x0a825, 0x0a826,), # Syloti Nagri Vowel Sign ..Syloti Nagri Vowel Sign + (0x0a8c4, 0x0a8c5,), # Saurashtra Sign Virama ..Saurashtra Sign Candrabi + (0x0a8e0, 0x0a8f1,), # Combining Devanagari Dig..Combining Devanagari Sig + (0x0a926, 0x0a92d,), # Kayah Li Vowel Ue ..Kayah Li Tone Calya Plop + (0x0a947, 0x0a951,), # Rejang Vowel Sign I ..Rejang Consonant Sign R + (0x0a980, 0x0a982,), # Javanese Sign Panyangga ..Javanese Sign Layar + (0x0a9b3, 0x0a9b3,), # Javanese Sign Cecak Telu..Javanese Sign Cecak Telu + (0x0a9b6, 0x0a9b9,), # Javanese Vowel Sign Wulu..Javanese Vowel Sign Suku + (0x0a9bc, 0x0a9bc,), # Javanese Vowel Sign Pepe..Javanese Vowel Sign Pepe + (0x0a9e5, 0x0a9e5,), # Myanmar Sign Shan Saw ..Myanmar Sign Shan Saw + (0x0aa29, 0x0aa2e,), # Cham Vowel Sign Aa ..Cham Vowel Sign Oe + (0x0aa31, 0x0aa32,), # Cham Vowel Sign Au ..Cham Vowel Sign Ue + (0x0aa35, 0x0aa36,), # Cham Consonant Sign La ..Cham Consonant Sign Wa + (0x0aa43, 0x0aa43,), # Cham Consonant Sign Fina..Cham Consonant Sign Fina + (0x0aa4c, 0x0aa4c,), # Cham Consonant Sign Fina..Cham Consonant Sign Fina + (0x0aa7c, 0x0aa7c,), # Myanmar Sign Tai Laing T..Myanmar Sign Tai Laing T + (0x0aab0, 0x0aab0,), # Tai Viet Mai Kang ..Tai Viet Mai Kang + (0x0aab2, 0x0aab4,), # Tai Viet Vowel I ..Tai Viet Vowel U + (0x0aab7, 0x0aab8,), # Tai Viet Mai Khit ..Tai Viet Vowel Ia + (0x0aabe, 0x0aabf,), # Tai Viet Vowel Am ..Tai Viet Tone Mai Ek + (0x0aac1, 0x0aac1,), # Tai Viet Tone Mai Tho ..Tai Viet Tone Mai Tho + (0x0aaec, 0x0aaed,), # Meetei Mayek Vowel Sign ..Meetei Mayek Vowel Sign + (0x0aaf6, 0x0aaf6,), # Meetei Mayek Virama ..Meetei Mayek Virama + (0x0abe5, 0x0abe5,), # Meetei Mayek Vowel Sign ..Meetei Mayek Vowel Sign + (0x0abe8, 0x0abe8,), # Meetei Mayek Vowel Sign ..Meetei Mayek Vowel Sign + (0x0abed, 0x0abed,), # Meetei Mayek Apun Iyek ..Meetei Mayek Apun Iyek + (0x0fb1e, 0x0fb1e,), # Hebrew Point Judeo-spani..Hebrew Point Judeo-spani + (0x0fe00, 0x0fe0f,), # Variation Selector-1 ..Variation Selector-16 + (0x0fe20, 0x0fe2f,), # Combining Ligature Left ..Combining Cyrillic Titlo + (0x101fd, 0x101fd,), # Phaistos Disc Sign Combi..Phaistos Disc Sign Combi + (0x102e0, 0x102e0,), # Coptic Epact Thousands M..Coptic Epact Thousands M + (0x10376, 0x1037a,), # Combining Old Permic Let..Combining Old Permic Let + (0x10a01, 0x10a03,), # Kharoshthi Vowel Sign I ..Kharoshthi Vowel Sign Vo + (0x10a05, 0x10a06,), # Kharoshthi Vowel Sign E ..Kharoshthi Vowel Sign O + (0x10a0c, 0x10a0f,), # Kharoshthi Vowel Length ..Kharoshthi Sign Visarga + (0x10a38, 0x10a3a,), # Kharoshthi Sign Bar Abov..Kharoshthi Sign Dot Belo + (0x10a3f, 0x10a3f,), # Kharoshthi Virama ..Kharoshthi Virama + (0x10ae5, 0x10ae6,), # Manichaean Abbreviation ..Manichaean Abbreviation + (0x11001, 0x11001,), # Brahmi Sign Anusvara ..Brahmi Sign Anusvara + (0x11038, 0x11046,), # Brahmi Vowel Sign Aa ..Brahmi Virama + (0x1107f, 0x11081,), # Brahmi Number Joiner ..Kaithi Sign Anusvara + (0x110b3, 0x110b6,), # Kaithi Vowel Sign U ..Kaithi Vowel Sign Ai + (0x110b9, 0x110ba,), # Kaithi Sign Virama ..Kaithi Sign Nukta + (0x11100, 0x11102,), # Chakma Sign Candrabindu ..Chakma Sign Visarga + (0x11127, 0x1112b,), # Chakma Vowel Sign A ..Chakma Vowel Sign Uu + (0x1112d, 0x11134,), # Chakma Vowel Sign Ai ..Chakma Maayyaa + (0x11173, 0x11173,), # Mahajani Sign Nukta ..Mahajani Sign Nukta + (0x11180, 0x11181,), # Sharada Sign Candrabindu..Sharada Sign Anusvara + (0x111b6, 0x111be,), # Sharada Vowel Sign U ..Sharada Vowel Sign O + (0x111ca, 0x111cc,), # Sharada Sign Nukta ..Sharada Extra Short Vowe + (0x1122f, 0x11231,), # Khojki Vowel Sign U ..Khojki Vowel Sign Ai + (0x11234, 0x11234,), # Khojki Sign Anusvara ..Khojki Sign Anusvara + (0x11236, 0x11237,), # Khojki Sign Nukta ..Khojki Sign Shadda + (0x1123e, 0x1123e,), # Khojki Sign Sukun ..Khojki Sign Sukun + (0x112df, 0x112df,), # Khudawadi Sign Anusvara ..Khudawadi Sign Anusvara + (0x112e3, 0x112ea,), # Khudawadi Vowel Sign U ..Khudawadi Sign Virama + (0x11300, 0x11301,), # Grantha Sign Combining A..Grantha Sign Candrabindu + (0x1133c, 0x1133c,), # Grantha Sign Nukta ..Grantha Sign Nukta + (0x11340, 0x11340,), # Grantha Vowel Sign Ii ..Grantha Vowel Sign Ii + (0x11366, 0x1136c,), # Combining Grantha Digit ..Combining Grantha Digit + (0x11370, 0x11374,), # Combining Grantha Letter..Combining Grantha Letter + (0x11438, 0x1143f,), # Newa Vowel Sign U ..Newa Vowel Sign Ai + (0x11442, 0x11444,), # Newa Sign Virama ..Newa Sign Anusvara + (0x11446, 0x11446,), # Newa Sign Nukta ..Newa Sign Nukta + (0x114b3, 0x114b8,), # Tirhuta Vowel Sign U ..Tirhuta Vowel Sign Vocal + (0x114ba, 0x114ba,), # Tirhuta Vowel Sign Short..Tirhuta Vowel Sign Short + (0x114bf, 0x114c0,), # Tirhuta Sign Candrabindu..Tirhuta Sign Anusvara + (0x114c2, 0x114c3,), # Tirhuta Sign Virama ..Tirhuta Sign Nukta + (0x115b2, 0x115b5,), # Siddham Vowel Sign U ..Siddham Vowel Sign Vocal + (0x115bc, 0x115bd,), # Siddham Sign Candrabindu..Siddham Sign Anusvara + (0x115bf, 0x115c0,), # Siddham Sign Virama ..Siddham Sign Nukta + (0x115dc, 0x115dd,), # Siddham Vowel Sign Alter..Siddham Vowel Sign Alter + (0x11633, 0x1163a,), # Modi Vowel Sign U ..Modi Vowel Sign Ai + (0x1163d, 0x1163d,), # Modi Sign Anusvara ..Modi Sign Anusvara + (0x1163f, 0x11640,), # Modi Sign Virama ..Modi Sign Ardhacandra + (0x116ab, 0x116ab,), # Takri Sign Anusvara ..Takri Sign Anusvara + (0x116ad, 0x116ad,), # Takri Vowel Sign Aa ..Takri Vowel Sign Aa + (0x116b0, 0x116b5,), # Takri Vowel Sign U ..Takri Vowel Sign Au + (0x116b7, 0x116b7,), # Takri Sign Nukta ..Takri Sign Nukta + (0x1171d, 0x1171f,), # Ahom Consonant Sign Medi..Ahom Consonant Sign Medi + (0x11722, 0x11725,), # Ahom Vowel Sign I ..Ahom Vowel Sign Uu + (0x11727, 0x1172b,), # Ahom Vowel Sign Aw ..Ahom Sign Killer + (0x11a01, 0x11a06,), # Zanabazar Square Vowel S..Zanabazar Square Vowel S + (0x11a09, 0x11a0a,), # Zanabazar Square Vowel S..Zanabazar Square Vowel L + (0x11a33, 0x11a38,), # Zanabazar Square Final C..Zanabazar Square Sign An + (0x11a3b, 0x11a3e,), # Zanabazar Square Cluster..Zanabazar Square Cluster + (0x11a47, 0x11a47,), # Zanabazar Square Subjoin..Zanabazar Square Subjoin + (0x11a51, 0x11a56,), # Soyombo Vowel Sign I ..Soyombo Vowel Sign Oe + (0x11a59, 0x11a5b,), # Soyombo Vowel Sign Vocal..Soyombo Vowel Length Mar + (0x11a8a, 0x11a96,), # Soyombo Final Consonant ..Soyombo Sign Anusvara + (0x11a98, 0x11a99,), # Soyombo Gemination Mark ..Soyombo Subjoiner + (0x11c30, 0x11c36,), # Bhaiksuki Vowel Sign I ..Bhaiksuki Vowel Sign Voc + (0x11c38, 0x11c3d,), # Bhaiksuki Vowel Sign E ..Bhaiksuki Sign Anusvara + (0x11c3f, 0x11c3f,), # Bhaiksuki Sign Virama ..Bhaiksuki Sign Virama + (0x11c92, 0x11ca7,), # Marchen Subjoined Letter..Marchen Subjoined Letter + (0x11caa, 0x11cb0,), # Marchen Subjoined Letter..Marchen Vowel Sign Aa + (0x11cb2, 0x11cb3,), # Marchen Vowel Sign U ..Marchen Vowel Sign E + (0x11cb5, 0x11cb6,), # Marchen Sign Anusvara ..Marchen Sign Candrabindu + (0x11d31, 0x11d36,), # Masaram Gondi Vowel Sign..Masaram Gondi Vowel Sign + (0x11d3a, 0x11d3a,), # Masaram Gondi Vowel Sign..Masaram Gondi Vowel Sign + (0x11d3c, 0x11d3d,), # Masaram Gondi Vowel Sign..Masaram Gondi Vowel Sign + (0x11d3f, 0x11d45,), # Masaram Gondi Vowel Sign..Masaram Gondi Virama + (0x11d47, 0x11d47,), # Masaram Gondi Ra-kara ..Masaram Gondi Ra-kara + (0x16af0, 0x16af4,), # Bassa Vah Combining High..Bassa Vah Combining High + (0x16b30, 0x16b36,), # Pahawh Hmong Mark Cim Tu..Pahawh Hmong Mark Cim Ta + (0x16f8f, 0x16f92,), # Miao Tone Right ..Miao Tone Below + (0x1bc9d, 0x1bc9e,), # Duployan Thick Letter Se..Duployan Double Mark + (0x1d167, 0x1d169,), # Musical Symbol Combining..Musical Symbol Combining + (0x1d17b, 0x1d182,), # Musical Symbol Combining..Musical Symbol Combining + (0x1d185, 0x1d18b,), # Musical Symbol Combining..Musical Symbol Combining + (0x1d1aa, 0x1d1ad,), # Musical Symbol Combining..Musical Symbol Combining + (0x1d242, 0x1d244,), # Combining Greek Musical ..Combining Greek Musical + (0x1da00, 0x1da36,), # Signwriting Head Rim ..Signwriting Air Sucking + (0x1da3b, 0x1da6c,), # Signwriting Mouth Closed..Signwriting Excitement + (0x1da75, 0x1da75,), # Signwriting Upper Body T..Signwriting Upper Body T + (0x1da84, 0x1da84,), # Signwriting Location Hea..Signwriting Location Hea + (0x1da9b, 0x1da9f,), # Signwriting Fill Modifie..Signwriting Fill Modifie + (0x1daa1, 0x1daaf,), # Signwriting Rotation Mod..Signwriting Rotation Mod + (0x1e000, 0x1e006,), # Combining Glagolitic Let..Combining Glagolitic Let + (0x1e008, 0x1e018,), # Combining Glagolitic Let..Combining Glagolitic Let + (0x1e01b, 0x1e021,), # Combining Glagolitic Let..Combining Glagolitic Let + (0x1e023, 0x1e024,), # Combining Glagolitic Let..Combining Glagolitic Let + (0x1e026, 0x1e02a,), # Combining Glagolitic Let..Combining Glagolitic Let + (0x1e8d0, 0x1e8d6,), # Mende Kikakui Combining ..Mende Kikakui Combining + (0x1e944, 0x1e94a,), # Adlam Alif Lengthener ..Adlam Nukta + (0xe0100, 0xe01ef,), # Variation Selector-17 ..Variation Selector-256 + ), + '11.0.0': ( + # Source: DerivedGeneralCategory-11.0.0.txt + # Date: 2018-02-21, 05:34:04 GMT + # + (0x00300, 0x0036f,), # Combining Grave Accent ..Combining Latin Small Le + (0x00483, 0x00489,), # Combining Cyrillic Titlo..Combining Cyrillic Milli + (0x00591, 0x005bd,), # Hebrew Accent Etnahta ..Hebrew Point Meteg + (0x005bf, 0x005bf,), # Hebrew Point Rafe ..Hebrew Point Rafe + (0x005c1, 0x005c2,), # Hebrew Point Shin Dot ..Hebrew Point Sin Dot + (0x005c4, 0x005c5,), # Hebrew Mark Upper Dot ..Hebrew Mark Lower Dot + (0x005c7, 0x005c7,), # Hebrew Point Qamats Qata..Hebrew Point Qamats Qata + (0x00610, 0x0061a,), # Arabic Sign Sallallahou ..Arabic Small Kasra + (0x0064b, 0x0065f,), # Arabic Fathatan ..Arabic Wavy Hamza Below + (0x00670, 0x00670,), # Arabic Letter Superscrip..Arabic Letter Superscrip + (0x006d6, 0x006dc,), # Arabic Small High Ligatu..Arabic Small High Seen + (0x006df, 0x006e4,), # Arabic Small High Rounde..Arabic Small High Madda + (0x006e7, 0x006e8,), # Arabic Small High Yeh ..Arabic Small High Noon + (0x006ea, 0x006ed,), # Arabic Empty Centre Low ..Arabic Small Low Meem + (0x00711, 0x00711,), # Syriac Letter Superscrip..Syriac Letter Superscrip + (0x00730, 0x0074a,), # Syriac Pthaha Above ..Syriac Barrekh + (0x007a6, 0x007b0,), # Thaana Abafili ..Thaana Sukun + (0x007eb, 0x007f3,), # Nko Combining Short High..Nko Combining Double Dot + (0x007fd, 0x007fd,), # Nko Dantayalan ..Nko Dantayalan + (0x00816, 0x00819,), # Samaritan Mark In ..Samaritan Mark Dagesh + (0x0081b, 0x00823,), # Samaritan Mark Epentheti..Samaritan Vowel Sign A + (0x00825, 0x00827,), # Samaritan Vowel Sign Sho..Samaritan Vowel Sign U + (0x00829, 0x0082d,), # Samaritan Vowel Sign Lon..Samaritan Mark Nequdaa + (0x00859, 0x0085b,), # Mandaic Affrication Mark..Mandaic Gemination Mark + (0x008d3, 0x008e1,), # Arabic Small Low Waw ..Arabic Small High Sign S + (0x008e3, 0x00902,), # Arabic Turned Damma Belo..Devanagari Sign Anusvara + (0x0093a, 0x0093a,), # Devanagari Vowel Sign Oe..Devanagari Vowel Sign Oe + (0x0093c, 0x0093c,), # Devanagari Sign Nukta ..Devanagari Sign Nukta + (0x00941, 0x00948,), # Devanagari Vowel Sign U ..Devanagari Vowel Sign Ai + (0x0094d, 0x0094d,), # Devanagari Sign Virama ..Devanagari Sign Virama + (0x00951, 0x00957,), # Devanagari Stress Sign U..Devanagari Vowel Sign Uu + (0x00962, 0x00963,), # Devanagari Vowel Sign Vo..Devanagari Vowel Sign Vo + (0x00981, 0x00981,), # Bengali Sign Candrabindu..Bengali Sign Candrabindu + (0x009bc, 0x009bc,), # Bengali Sign Nukta ..Bengali Sign Nukta + (0x009c1, 0x009c4,), # Bengali Vowel Sign U ..Bengali Vowel Sign Vocal + (0x009cd, 0x009cd,), # Bengali Sign Virama ..Bengali Sign Virama + (0x009e2, 0x009e3,), # Bengali Vowel Sign Vocal..Bengali Vowel Sign Vocal + (0x009fe, 0x009fe,), # Bengali Sandhi Mark ..Bengali Sandhi Mark + (0x00a01, 0x00a02,), # Gurmukhi Sign Adak Bindi..Gurmukhi Sign Bindi + (0x00a3c, 0x00a3c,), # Gurmukhi Sign Nukta ..Gurmukhi Sign Nukta + (0x00a41, 0x00a42,), # Gurmukhi Vowel Sign U ..Gurmukhi Vowel Sign Uu + (0x00a47, 0x00a48,), # Gurmukhi Vowel Sign Ee ..Gurmukhi Vowel Sign Ai + (0x00a4b, 0x00a4d,), # Gurmukhi Vowel Sign Oo ..Gurmukhi Sign Virama + (0x00a51, 0x00a51,), # Gurmukhi Sign Udaat ..Gurmukhi Sign Udaat + (0x00a70, 0x00a71,), # Gurmukhi Tippi ..Gurmukhi Addak + (0x00a75, 0x00a75,), # Gurmukhi Sign Yakash ..Gurmukhi Sign Yakash + (0x00a81, 0x00a82,), # Gujarati Sign Candrabind..Gujarati Sign Anusvara + (0x00abc, 0x00abc,), # Gujarati Sign Nukta ..Gujarati Sign Nukta + (0x00ac1, 0x00ac5,), # Gujarati Vowel Sign U ..Gujarati Vowel Sign Cand + (0x00ac7, 0x00ac8,), # Gujarati Vowel Sign E ..Gujarati Vowel Sign Ai + (0x00acd, 0x00acd,), # Gujarati Sign Virama ..Gujarati Sign Virama + (0x00ae2, 0x00ae3,), # Gujarati Vowel Sign Voca..Gujarati Vowel Sign Voca + (0x00afa, 0x00aff,), # Gujarati Sign Sukun ..Gujarati Sign Two-circle + (0x00b01, 0x00b01,), # Oriya Sign Candrabindu ..Oriya Sign Candrabindu + (0x00b3c, 0x00b3c,), # Oriya Sign Nukta ..Oriya Sign Nukta + (0x00b3f, 0x00b3f,), # Oriya Vowel Sign I ..Oriya Vowel Sign I + (0x00b41, 0x00b44,), # Oriya Vowel Sign U ..Oriya Vowel Sign Vocalic + (0x00b4d, 0x00b4d,), # Oriya Sign Virama ..Oriya Sign Virama + (0x00b56, 0x00b56,), # Oriya Ai Length Mark ..Oriya Ai Length Mark + (0x00b62, 0x00b63,), # Oriya Vowel Sign Vocalic..Oriya Vowel Sign Vocalic + (0x00b82, 0x00b82,), # Tamil Sign Anusvara ..Tamil Sign Anusvara + (0x00bc0, 0x00bc0,), # Tamil Vowel Sign Ii ..Tamil Vowel Sign Ii + (0x00bcd, 0x00bcd,), # Tamil Sign Virama ..Tamil Sign Virama + (0x00c00, 0x00c00,), # Telugu Sign Combining Ca..Telugu Sign Combining Ca + (0x00c04, 0x00c04,), # Telugu Sign Combining An..Telugu Sign Combining An + (0x00c3e, 0x00c40,), # Telugu Vowel Sign Aa ..Telugu Vowel Sign Ii + (0x00c46, 0x00c48,), # Telugu Vowel Sign E ..Telugu Vowel Sign Ai + (0x00c4a, 0x00c4d,), # Telugu Vowel Sign O ..Telugu Sign Virama + (0x00c55, 0x00c56,), # Telugu Length Mark ..Telugu Ai Length Mark + (0x00c62, 0x00c63,), # Telugu Vowel Sign Vocali..Telugu Vowel Sign Vocali + (0x00c81, 0x00c81,), # Kannada Sign Candrabindu..Kannada Sign Candrabindu + (0x00cbc, 0x00cbc,), # Kannada Sign Nukta ..Kannada Sign Nukta + (0x00cbf, 0x00cbf,), # Kannada Vowel Sign I ..Kannada Vowel Sign I + (0x00cc6, 0x00cc6,), # Kannada Vowel Sign E ..Kannada Vowel Sign E + (0x00ccc, 0x00ccd,), # Kannada Vowel Sign Au ..Kannada Sign Virama + (0x00ce2, 0x00ce3,), # Kannada Vowel Sign Vocal..Kannada Vowel Sign Vocal + (0x00d00, 0x00d01,), # Malayalam Sign Combining..Malayalam Sign Candrabin + (0x00d3b, 0x00d3c,), # Malayalam Sign Vertical ..Malayalam Sign Circular + (0x00d41, 0x00d44,), # Malayalam Vowel Sign U ..Malayalam Vowel Sign Voc + (0x00d4d, 0x00d4d,), # Malayalam Sign Virama ..Malayalam Sign Virama + (0x00d62, 0x00d63,), # Malayalam Vowel Sign Voc..Malayalam Vowel Sign Voc + (0x00dca, 0x00dca,), # Sinhala Sign Al-lakuna ..Sinhala Sign Al-lakuna + (0x00dd2, 0x00dd4,), # Sinhala Vowel Sign Ketti..Sinhala Vowel Sign Ketti + (0x00dd6, 0x00dd6,), # Sinhala Vowel Sign Diga ..Sinhala Vowel Sign Diga + (0x00e31, 0x00e31,), # Thai Character Mai Han-a..Thai Character Mai Han-a + (0x00e34, 0x00e3a,), # Thai Character Sara I ..Thai Character Phinthu + (0x00e47, 0x00e4e,), # Thai Character Maitaikhu..Thai Character Yamakkan + (0x00eb1, 0x00eb1,), # Lao Vowel Sign Mai Kan ..Lao Vowel Sign Mai Kan + (0x00eb4, 0x00eb9,), # Lao Vowel Sign I ..Lao Vowel Sign Uu + (0x00ebb, 0x00ebc,), # Lao Vowel Sign Mai Kon ..Lao Semivowel Sign Lo + (0x00ec8, 0x00ecd,), # Lao Tone Mai Ek ..Lao Niggahita + (0x00f18, 0x00f19,), # Tibetan Astrological Sig..Tibetan Astrological Sig + (0x00f35, 0x00f35,), # Tibetan Mark Ngas Bzung ..Tibetan Mark Ngas Bzung + (0x00f37, 0x00f37,), # Tibetan Mark Ngas Bzung ..Tibetan Mark Ngas Bzung + (0x00f39, 0x00f39,), # Tibetan Mark Tsa -phru ..Tibetan Mark Tsa -phru + (0x00f71, 0x00f7e,), # Tibetan Vowel Sign Aa ..Tibetan Sign Rjes Su Nga + (0x00f80, 0x00f84,), # Tibetan Vowel Sign Rever..Tibetan Mark Halanta + (0x00f86, 0x00f87,), # Tibetan Sign Lci Rtags ..Tibetan Sign Yang Rtags + (0x00f8d, 0x00f97,), # Tibetan Subjoined Sign L..Tibetan Subjoined Letter + (0x00f99, 0x00fbc,), # Tibetan Subjoined Letter..Tibetan Subjoined Letter + (0x00fc6, 0x00fc6,), # Tibetan Symbol Padma Gda..Tibetan Symbol Padma Gda + (0x0102d, 0x01030,), # Myanmar Vowel Sign I ..Myanmar Vowel Sign Uu + (0x01032, 0x01037,), # Myanmar Vowel Sign Ai ..Myanmar Sign Dot Below + (0x01039, 0x0103a,), # Myanmar Sign Virama ..Myanmar Sign Asat + (0x0103d, 0x0103e,), # Myanmar Consonant Sign M..Myanmar Consonant Sign M + (0x01058, 0x01059,), # Myanmar Vowel Sign Vocal..Myanmar Vowel Sign Vocal + (0x0105e, 0x01060,), # Myanmar Consonant Sign M..Myanmar Consonant Sign M + (0x01071, 0x01074,), # Myanmar Vowel Sign Geba ..Myanmar Vowel Sign Kayah + (0x01082, 0x01082,), # Myanmar Consonant Sign S..Myanmar Consonant Sign S + (0x01085, 0x01086,), # Myanmar Vowel Sign Shan ..Myanmar Vowel Sign Shan + (0x0108d, 0x0108d,), # Myanmar Sign Shan Counci..Myanmar Sign Shan Counci + (0x0109d, 0x0109d,), # Myanmar Vowel Sign Aiton..Myanmar Vowel Sign Aiton + (0x0135d, 0x0135f,), # Ethiopic Combining Gemin..Ethiopic Combining Gemin + (0x01712, 0x01714,), # Tagalog Vowel Sign I ..Tagalog Sign Virama + (0x01732, 0x01734,), # Hanunoo Vowel Sign I ..Hanunoo Sign Pamudpod + (0x01752, 0x01753,), # Buhid Vowel Sign I ..Buhid Vowel Sign U + (0x01772, 0x01773,), # Tagbanwa Vowel Sign I ..Tagbanwa Vowel Sign U + (0x017b4, 0x017b5,), # Khmer Vowel Inherent Aq ..Khmer Vowel Inherent Aa + (0x017b7, 0x017bd,), # Khmer Vowel Sign I ..Khmer Vowel Sign Ua + (0x017c6, 0x017c6,), # Khmer Sign Nikahit ..Khmer Sign Nikahit + (0x017c9, 0x017d3,), # Khmer Sign Muusikatoan ..Khmer Sign Bathamasat + (0x017dd, 0x017dd,), # Khmer Sign Atthacan ..Khmer Sign Atthacan + (0x0180b, 0x0180d,), # Mongolian Free Variation..Mongolian Free Variation + (0x01885, 0x01886,), # Mongolian Letter Ali Gal..Mongolian Letter Ali Gal + (0x018a9, 0x018a9,), # Mongolian Letter Ali Gal..Mongolian Letter Ali Gal + (0x01920, 0x01922,), # Limbu Vowel Sign A ..Limbu Vowel Sign U + (0x01927, 0x01928,), # Limbu Vowel Sign E ..Limbu Vowel Sign O + (0x01932, 0x01932,), # Limbu Small Letter Anusv..Limbu Small Letter Anusv + (0x01939, 0x0193b,), # Limbu Sign Mukphreng ..Limbu Sign Sa-i + (0x01a17, 0x01a18,), # Buginese Vowel Sign I ..Buginese Vowel Sign U + (0x01a1b, 0x01a1b,), # Buginese Vowel Sign Ae ..Buginese Vowel Sign Ae + (0x01a56, 0x01a56,), # Tai Tham Consonant Sign ..Tai Tham Consonant Sign + (0x01a58, 0x01a5e,), # Tai Tham Sign Mai Kang L..Tai Tham Consonant Sign + (0x01a60, 0x01a60,), # Tai Tham Sign Sakot ..Tai Tham Sign Sakot + (0x01a62, 0x01a62,), # Tai Tham Vowel Sign Mai ..Tai Tham Vowel Sign Mai + (0x01a65, 0x01a6c,), # Tai Tham Vowel Sign I ..Tai Tham Vowel Sign Oa B + (0x01a73, 0x01a7c,), # Tai Tham Vowel Sign Oa A..Tai Tham Sign Khuen-lue + (0x01a7f, 0x01a7f,), # Tai Tham Combining Crypt..Tai Tham Combining Crypt + (0x01ab0, 0x01abe,), # Combining Doubled Circum..Combining Parentheses Ov + (0x01b00, 0x01b03,), # Balinese Sign Ulu Ricem ..Balinese Sign Surang + (0x01b34, 0x01b34,), # Balinese Sign Rerekan ..Balinese Sign Rerekan + (0x01b36, 0x01b3a,), # Balinese Vowel Sign Ulu ..Balinese Vowel Sign Ra R + (0x01b3c, 0x01b3c,), # Balinese Vowel Sign La L..Balinese Vowel Sign La L + (0x01b42, 0x01b42,), # Balinese Vowel Sign Pepe..Balinese Vowel Sign Pepe + (0x01b6b, 0x01b73,), # Balinese Musical Symbol ..Balinese Musical Symbol + (0x01b80, 0x01b81,), # Sundanese Sign Panyecek ..Sundanese Sign Panglayar + (0x01ba2, 0x01ba5,), # Sundanese Consonant Sign..Sundanese Vowel Sign Pan + (0x01ba8, 0x01ba9,), # Sundanese Vowel Sign Pam..Sundanese Vowel Sign Pan + (0x01bab, 0x01bad,), # Sundanese Sign Virama ..Sundanese Consonant Sign + (0x01be6, 0x01be6,), # Batak Sign Tompi ..Batak Sign Tompi + (0x01be8, 0x01be9,), # Batak Vowel Sign Pakpak ..Batak Vowel Sign Ee + (0x01bed, 0x01bed,), # Batak Vowel Sign Karo O ..Batak Vowel Sign Karo O + (0x01bef, 0x01bf1,), # Batak Vowel Sign U For S..Batak Consonant Sign H + (0x01c2c, 0x01c33,), # Lepcha Vowel Sign E ..Lepcha Consonant Sign T + (0x01c36, 0x01c37,), # Lepcha Sign Ran ..Lepcha Sign Nukta + (0x01cd0, 0x01cd2,), # Vedic Tone Karshana ..Vedic Tone Prenkha + (0x01cd4, 0x01ce0,), # Vedic Sign Yajurvedic Mi..Vedic Tone Rigvedic Kash + (0x01ce2, 0x01ce8,), # Vedic Sign Visarga Svari..Vedic Sign Visarga Anuda + (0x01ced, 0x01ced,), # Vedic Sign Tiryak ..Vedic Sign Tiryak + (0x01cf4, 0x01cf4,), # Vedic Tone Candra Above ..Vedic Tone Candra Above + (0x01cf8, 0x01cf9,), # Vedic Tone Ring Above ..Vedic Tone Double Ring A + (0x01dc0, 0x01df9,), # Combining Dotted Grave A..Combining Wide Inverted + (0x01dfb, 0x01dff,), # Combining Deletion Mark ..Combining Right Arrowhea + (0x020d0, 0x020f0,), # Combining Left Harpoon A..Combining Asterisk Above + (0x02cef, 0x02cf1,), # Coptic Combining Ni Abov..Coptic Combining Spiritu + (0x02d7f, 0x02d7f,), # Tifinagh Consonant Joine..Tifinagh Consonant Joine + (0x02de0, 0x02dff,), # Combining Cyrillic Lette..Combining Cyrillic Lette + (0x0302a, 0x0302d,), # Ideographic Level Tone M..Ideographic Entering Ton + (0x03099, 0x0309a,), # Combining Katakana-hirag..Combining Katakana-hirag + (0x0a66f, 0x0a672,), # Combining Cyrillic Vzmet..Combining Cyrillic Thous + (0x0a674, 0x0a67d,), # Combining Cyrillic Lette..Combining Cyrillic Payer + (0x0a69e, 0x0a69f,), # Combining Cyrillic Lette..Combining Cyrillic Lette + (0x0a6f0, 0x0a6f1,), # Bamum Combining Mark Koq..Bamum Combining Mark Tuk + (0x0a802, 0x0a802,), # Syloti Nagri Sign Dvisva..Syloti Nagri Sign Dvisva + (0x0a806, 0x0a806,), # Syloti Nagri Sign Hasant..Syloti Nagri Sign Hasant + (0x0a80b, 0x0a80b,), # Syloti Nagri Sign Anusva..Syloti Nagri Sign Anusva + (0x0a825, 0x0a826,), # Syloti Nagri Vowel Sign ..Syloti Nagri Vowel Sign + (0x0a8c4, 0x0a8c5,), # Saurashtra Sign Virama ..Saurashtra Sign Candrabi + (0x0a8e0, 0x0a8f1,), # Combining Devanagari Dig..Combining Devanagari Sig + (0x0a8ff, 0x0a8ff,), # Devanagari Vowel Sign Ay..Devanagari Vowel Sign Ay + (0x0a926, 0x0a92d,), # Kayah Li Vowel Ue ..Kayah Li Tone Calya Plop + (0x0a947, 0x0a951,), # Rejang Vowel Sign I ..Rejang Consonant Sign R + (0x0a980, 0x0a982,), # Javanese Sign Panyangga ..Javanese Sign Layar + (0x0a9b3, 0x0a9b3,), # Javanese Sign Cecak Telu..Javanese Sign Cecak Telu + (0x0a9b6, 0x0a9b9,), # Javanese Vowel Sign Wulu..Javanese Vowel Sign Suku + (0x0a9bc, 0x0a9bc,), # Javanese Vowel Sign Pepe..Javanese Vowel Sign Pepe + (0x0a9e5, 0x0a9e5,), # Myanmar Sign Shan Saw ..Myanmar Sign Shan Saw + (0x0aa29, 0x0aa2e,), # Cham Vowel Sign Aa ..Cham Vowel Sign Oe + (0x0aa31, 0x0aa32,), # Cham Vowel Sign Au ..Cham Vowel Sign Ue + (0x0aa35, 0x0aa36,), # Cham Consonant Sign La ..Cham Consonant Sign Wa + (0x0aa43, 0x0aa43,), # Cham Consonant Sign Fina..Cham Consonant Sign Fina + (0x0aa4c, 0x0aa4c,), # Cham Consonant Sign Fina..Cham Consonant Sign Fina + (0x0aa7c, 0x0aa7c,), # Myanmar Sign Tai Laing T..Myanmar Sign Tai Laing T + (0x0aab0, 0x0aab0,), # Tai Viet Mai Kang ..Tai Viet Mai Kang + (0x0aab2, 0x0aab4,), # Tai Viet Vowel I ..Tai Viet Vowel U + (0x0aab7, 0x0aab8,), # Tai Viet Mai Khit ..Tai Viet Vowel Ia + (0x0aabe, 0x0aabf,), # Tai Viet Vowel Am ..Tai Viet Tone Mai Ek + (0x0aac1, 0x0aac1,), # Tai Viet Tone Mai Tho ..Tai Viet Tone Mai Tho + (0x0aaec, 0x0aaed,), # Meetei Mayek Vowel Sign ..Meetei Mayek Vowel Sign + (0x0aaf6, 0x0aaf6,), # Meetei Mayek Virama ..Meetei Mayek Virama + (0x0abe5, 0x0abe5,), # Meetei Mayek Vowel Sign ..Meetei Mayek Vowel Sign + (0x0abe8, 0x0abe8,), # Meetei Mayek Vowel Sign ..Meetei Mayek Vowel Sign + (0x0abed, 0x0abed,), # Meetei Mayek Apun Iyek ..Meetei Mayek Apun Iyek + (0x0fb1e, 0x0fb1e,), # Hebrew Point Judeo-spani..Hebrew Point Judeo-spani + (0x0fe00, 0x0fe0f,), # Variation Selector-1 ..Variation Selector-16 + (0x0fe20, 0x0fe2f,), # Combining Ligature Left ..Combining Cyrillic Titlo + (0x101fd, 0x101fd,), # Phaistos Disc Sign Combi..Phaistos Disc Sign Combi + (0x102e0, 0x102e0,), # Coptic Epact Thousands M..Coptic Epact Thousands M + (0x10376, 0x1037a,), # Combining Old Permic Let..Combining Old Permic Let + (0x10a01, 0x10a03,), # Kharoshthi Vowel Sign I ..Kharoshthi Vowel Sign Vo + (0x10a05, 0x10a06,), # Kharoshthi Vowel Sign E ..Kharoshthi Vowel Sign O + (0x10a0c, 0x10a0f,), # Kharoshthi Vowel Length ..Kharoshthi Sign Visarga + (0x10a38, 0x10a3a,), # Kharoshthi Sign Bar Abov..Kharoshthi Sign Dot Belo + (0x10a3f, 0x10a3f,), # Kharoshthi Virama ..Kharoshthi Virama + (0x10ae5, 0x10ae6,), # Manichaean Abbreviation ..Manichaean Abbreviation + (0x10d24, 0x10d27,), # Hanifi Rohingya Sign Har..Hanifi Rohingya Sign Tas + (0x10f46, 0x10f50,), # Sogdian Combining Dot Be..Sogdian Combining Stroke + (0x11001, 0x11001,), # Brahmi Sign Anusvara ..Brahmi Sign Anusvara + (0x11038, 0x11046,), # Brahmi Vowel Sign Aa ..Brahmi Virama + (0x1107f, 0x11081,), # Brahmi Number Joiner ..Kaithi Sign Anusvara + (0x110b3, 0x110b6,), # Kaithi Vowel Sign U ..Kaithi Vowel Sign Ai + (0x110b9, 0x110ba,), # Kaithi Sign Virama ..Kaithi Sign Nukta + (0x11100, 0x11102,), # Chakma Sign Candrabindu ..Chakma Sign Visarga + (0x11127, 0x1112b,), # Chakma Vowel Sign A ..Chakma Vowel Sign Uu + (0x1112d, 0x11134,), # Chakma Vowel Sign Ai ..Chakma Maayyaa + (0x11173, 0x11173,), # Mahajani Sign Nukta ..Mahajani Sign Nukta + (0x11180, 0x11181,), # Sharada Sign Candrabindu..Sharada Sign Anusvara + (0x111b6, 0x111be,), # Sharada Vowel Sign U ..Sharada Vowel Sign O + (0x111c9, 0x111cc,), # Sharada Sandhi Mark ..Sharada Extra Short Vowe + (0x1122f, 0x11231,), # Khojki Vowel Sign U ..Khojki Vowel Sign Ai + (0x11234, 0x11234,), # Khojki Sign Anusvara ..Khojki Sign Anusvara + (0x11236, 0x11237,), # Khojki Sign Nukta ..Khojki Sign Shadda + (0x1123e, 0x1123e,), # Khojki Sign Sukun ..Khojki Sign Sukun + (0x112df, 0x112df,), # Khudawadi Sign Anusvara ..Khudawadi Sign Anusvara + (0x112e3, 0x112ea,), # Khudawadi Vowel Sign U ..Khudawadi Sign Virama + (0x11300, 0x11301,), # Grantha Sign Combining A..Grantha Sign Candrabindu + (0x1133b, 0x1133c,), # Combining Bindu Below ..Grantha Sign Nukta + (0x11340, 0x11340,), # Grantha Vowel Sign Ii ..Grantha Vowel Sign Ii + (0x11366, 0x1136c,), # Combining Grantha Digit ..Combining Grantha Digit + (0x11370, 0x11374,), # Combining Grantha Letter..Combining Grantha Letter + (0x11438, 0x1143f,), # Newa Vowel Sign U ..Newa Vowel Sign Ai + (0x11442, 0x11444,), # Newa Sign Virama ..Newa Sign Anusvara + (0x11446, 0x11446,), # Newa Sign Nukta ..Newa Sign Nukta + (0x1145e, 0x1145e,), # Newa Sandhi Mark ..Newa Sandhi Mark + (0x114b3, 0x114b8,), # Tirhuta Vowel Sign U ..Tirhuta Vowel Sign Vocal + (0x114ba, 0x114ba,), # Tirhuta Vowel Sign Short..Tirhuta Vowel Sign Short + (0x114bf, 0x114c0,), # Tirhuta Sign Candrabindu..Tirhuta Sign Anusvara + (0x114c2, 0x114c3,), # Tirhuta Sign Virama ..Tirhuta Sign Nukta + (0x115b2, 0x115b5,), # Siddham Vowel Sign U ..Siddham Vowel Sign Vocal + (0x115bc, 0x115bd,), # Siddham Sign Candrabindu..Siddham Sign Anusvara + (0x115bf, 0x115c0,), # Siddham Sign Virama ..Siddham Sign Nukta + (0x115dc, 0x115dd,), # Siddham Vowel Sign Alter..Siddham Vowel Sign Alter + (0x11633, 0x1163a,), # Modi Vowel Sign U ..Modi Vowel Sign Ai + (0x1163d, 0x1163d,), # Modi Sign Anusvara ..Modi Sign Anusvara + (0x1163f, 0x11640,), # Modi Sign Virama ..Modi Sign Ardhacandra + (0x116ab, 0x116ab,), # Takri Sign Anusvara ..Takri Sign Anusvara + (0x116ad, 0x116ad,), # Takri Vowel Sign Aa ..Takri Vowel Sign Aa + (0x116b0, 0x116b5,), # Takri Vowel Sign U ..Takri Vowel Sign Au + (0x116b7, 0x116b7,), # Takri Sign Nukta ..Takri Sign Nukta + (0x1171d, 0x1171f,), # Ahom Consonant Sign Medi..Ahom Consonant Sign Medi + (0x11722, 0x11725,), # Ahom Vowel Sign I ..Ahom Vowel Sign Uu + (0x11727, 0x1172b,), # Ahom Vowel Sign Aw ..Ahom Sign Killer + (0x1182f, 0x11837,), # Dogra Vowel Sign U ..Dogra Sign Anusvara + (0x11839, 0x1183a,), # Dogra Sign Virama ..Dogra Sign Nukta + (0x11a01, 0x11a0a,), # Zanabazar Square Vowel S..Zanabazar Square Vowel L + (0x11a33, 0x11a38,), # Zanabazar Square Final C..Zanabazar Square Sign An + (0x11a3b, 0x11a3e,), # Zanabazar Square Cluster..Zanabazar Square Cluster + (0x11a47, 0x11a47,), # Zanabazar Square Subjoin..Zanabazar Square Subjoin + (0x11a51, 0x11a56,), # Soyombo Vowel Sign I ..Soyombo Vowel Sign Oe + (0x11a59, 0x11a5b,), # Soyombo Vowel Sign Vocal..Soyombo Vowel Length Mar + (0x11a8a, 0x11a96,), # Soyombo Final Consonant ..Soyombo Sign Anusvara + (0x11a98, 0x11a99,), # Soyombo Gemination Mark ..Soyombo Subjoiner + (0x11c30, 0x11c36,), # Bhaiksuki Vowel Sign I ..Bhaiksuki Vowel Sign Voc + (0x11c38, 0x11c3d,), # Bhaiksuki Vowel Sign E ..Bhaiksuki Sign Anusvara + (0x11c3f, 0x11c3f,), # Bhaiksuki Sign Virama ..Bhaiksuki Sign Virama + (0x11c92, 0x11ca7,), # Marchen Subjoined Letter..Marchen Subjoined Letter + (0x11caa, 0x11cb0,), # Marchen Subjoined Letter..Marchen Vowel Sign Aa + (0x11cb2, 0x11cb3,), # Marchen Vowel Sign U ..Marchen Vowel Sign E + (0x11cb5, 0x11cb6,), # Marchen Sign Anusvara ..Marchen Sign Candrabindu + (0x11d31, 0x11d36,), # Masaram Gondi Vowel Sign..Masaram Gondi Vowel Sign + (0x11d3a, 0x11d3a,), # Masaram Gondi Vowel Sign..Masaram Gondi Vowel Sign + (0x11d3c, 0x11d3d,), # Masaram Gondi Vowel Sign..Masaram Gondi Vowel Sign + (0x11d3f, 0x11d45,), # Masaram Gondi Vowel Sign..Masaram Gondi Virama + (0x11d47, 0x11d47,), # Masaram Gondi Ra-kara ..Masaram Gondi Ra-kara + (0x11d90, 0x11d91,), # Gunjala Gondi Vowel Sign..Gunjala Gondi Vowel Sign + (0x11d95, 0x11d95,), # Gunjala Gondi Sign Anusv..Gunjala Gondi Sign Anusv + (0x11d97, 0x11d97,), # Gunjala Gondi Virama ..Gunjala Gondi Virama + (0x11ef3, 0x11ef4,), # Makasar Vowel Sign I ..Makasar Vowel Sign U + (0x16af0, 0x16af4,), # Bassa Vah Combining High..Bassa Vah Combining High + (0x16b30, 0x16b36,), # Pahawh Hmong Mark Cim Tu..Pahawh Hmong Mark Cim Ta + (0x16f8f, 0x16f92,), # Miao Tone Right ..Miao Tone Below + (0x1bc9d, 0x1bc9e,), # Duployan Thick Letter Se..Duployan Double Mark + (0x1d167, 0x1d169,), # Musical Symbol Combining..Musical Symbol Combining + (0x1d17b, 0x1d182,), # Musical Symbol Combining..Musical Symbol Combining + (0x1d185, 0x1d18b,), # Musical Symbol Combining..Musical Symbol Combining + (0x1d1aa, 0x1d1ad,), # Musical Symbol Combining..Musical Symbol Combining + (0x1d242, 0x1d244,), # Combining Greek Musical ..Combining Greek Musical + (0x1da00, 0x1da36,), # Signwriting Head Rim ..Signwriting Air Sucking + (0x1da3b, 0x1da6c,), # Signwriting Mouth Closed..Signwriting Excitement + (0x1da75, 0x1da75,), # Signwriting Upper Body T..Signwriting Upper Body T + (0x1da84, 0x1da84,), # Signwriting Location Hea..Signwriting Location Hea + (0x1da9b, 0x1da9f,), # Signwriting Fill Modifie..Signwriting Fill Modifie + (0x1daa1, 0x1daaf,), # Signwriting Rotation Mod..Signwriting Rotation Mod + (0x1e000, 0x1e006,), # Combining Glagolitic Let..Combining Glagolitic Let + (0x1e008, 0x1e018,), # Combining Glagolitic Let..Combining Glagolitic Let + (0x1e01b, 0x1e021,), # Combining Glagolitic Let..Combining Glagolitic Let + (0x1e023, 0x1e024,), # Combining Glagolitic Let..Combining Glagolitic Let + (0x1e026, 0x1e02a,), # Combining Glagolitic Let..Combining Glagolitic Let + (0x1e8d0, 0x1e8d6,), # Mende Kikakui Combining ..Mende Kikakui Combining + (0x1e944, 0x1e94a,), # Adlam Alif Lengthener ..Adlam Nukta + (0xe0100, 0xe01ef,), # Variation Selector-17 ..Variation Selector-256 + ), + '12.0.0': ( + # Source: DerivedGeneralCategory-12.0.0.txt + # Date: 2019-01-22, 08:18:28 GMT + # + (0x00300, 0x0036f,), # Combining Grave Accent ..Combining Latin Small Le + (0x00483, 0x00489,), # Combining Cyrillic Titlo..Combining Cyrillic Milli + (0x00591, 0x005bd,), # Hebrew Accent Etnahta ..Hebrew Point Meteg + (0x005bf, 0x005bf,), # Hebrew Point Rafe ..Hebrew Point Rafe + (0x005c1, 0x005c2,), # Hebrew Point Shin Dot ..Hebrew Point Sin Dot + (0x005c4, 0x005c5,), # Hebrew Mark Upper Dot ..Hebrew Mark Lower Dot + (0x005c7, 0x005c7,), # Hebrew Point Qamats Qata..Hebrew Point Qamats Qata + (0x00610, 0x0061a,), # Arabic Sign Sallallahou ..Arabic Small Kasra + (0x0064b, 0x0065f,), # Arabic Fathatan ..Arabic Wavy Hamza Below + (0x00670, 0x00670,), # Arabic Letter Superscrip..Arabic Letter Superscrip + (0x006d6, 0x006dc,), # Arabic Small High Ligatu..Arabic Small High Seen + (0x006df, 0x006e4,), # Arabic Small High Rounde..Arabic Small High Madda + (0x006e7, 0x006e8,), # Arabic Small High Yeh ..Arabic Small High Noon + (0x006ea, 0x006ed,), # Arabic Empty Centre Low ..Arabic Small Low Meem + (0x00711, 0x00711,), # Syriac Letter Superscrip..Syriac Letter Superscrip + (0x00730, 0x0074a,), # Syriac Pthaha Above ..Syriac Barrekh + (0x007a6, 0x007b0,), # Thaana Abafili ..Thaana Sukun + (0x007eb, 0x007f3,), # Nko Combining Short High..Nko Combining Double Dot + (0x007fd, 0x007fd,), # Nko Dantayalan ..Nko Dantayalan + (0x00816, 0x00819,), # Samaritan Mark In ..Samaritan Mark Dagesh + (0x0081b, 0x00823,), # Samaritan Mark Epentheti..Samaritan Vowel Sign A + (0x00825, 0x00827,), # Samaritan Vowel Sign Sho..Samaritan Vowel Sign U + (0x00829, 0x0082d,), # Samaritan Vowel Sign Lon..Samaritan Mark Nequdaa + (0x00859, 0x0085b,), # Mandaic Affrication Mark..Mandaic Gemination Mark + (0x008d3, 0x008e1,), # Arabic Small Low Waw ..Arabic Small High Sign S + (0x008e3, 0x00902,), # Arabic Turned Damma Belo..Devanagari Sign Anusvara + (0x0093a, 0x0093a,), # Devanagari Vowel Sign Oe..Devanagari Vowel Sign Oe + (0x0093c, 0x0093c,), # Devanagari Sign Nukta ..Devanagari Sign Nukta + (0x00941, 0x00948,), # Devanagari Vowel Sign U ..Devanagari Vowel Sign Ai + (0x0094d, 0x0094d,), # Devanagari Sign Virama ..Devanagari Sign Virama + (0x00951, 0x00957,), # Devanagari Stress Sign U..Devanagari Vowel Sign Uu + (0x00962, 0x00963,), # Devanagari Vowel Sign Vo..Devanagari Vowel Sign Vo + (0x00981, 0x00981,), # Bengali Sign Candrabindu..Bengali Sign Candrabindu + (0x009bc, 0x009bc,), # Bengali Sign Nukta ..Bengali Sign Nukta + (0x009c1, 0x009c4,), # Bengali Vowel Sign U ..Bengali Vowel Sign Vocal + (0x009cd, 0x009cd,), # Bengali Sign Virama ..Bengali Sign Virama + (0x009e2, 0x009e3,), # Bengali Vowel Sign Vocal..Bengali Vowel Sign Vocal + (0x009fe, 0x009fe,), # Bengali Sandhi Mark ..Bengali Sandhi Mark + (0x00a01, 0x00a02,), # Gurmukhi Sign Adak Bindi..Gurmukhi Sign Bindi + (0x00a3c, 0x00a3c,), # Gurmukhi Sign Nukta ..Gurmukhi Sign Nukta + (0x00a41, 0x00a42,), # Gurmukhi Vowel Sign U ..Gurmukhi Vowel Sign Uu + (0x00a47, 0x00a48,), # Gurmukhi Vowel Sign Ee ..Gurmukhi Vowel Sign Ai + (0x00a4b, 0x00a4d,), # Gurmukhi Vowel Sign Oo ..Gurmukhi Sign Virama + (0x00a51, 0x00a51,), # Gurmukhi Sign Udaat ..Gurmukhi Sign Udaat + (0x00a70, 0x00a71,), # Gurmukhi Tippi ..Gurmukhi Addak + (0x00a75, 0x00a75,), # Gurmukhi Sign Yakash ..Gurmukhi Sign Yakash + (0x00a81, 0x00a82,), # Gujarati Sign Candrabind..Gujarati Sign Anusvara + (0x00abc, 0x00abc,), # Gujarati Sign Nukta ..Gujarati Sign Nukta + (0x00ac1, 0x00ac5,), # Gujarati Vowel Sign U ..Gujarati Vowel Sign Cand + (0x00ac7, 0x00ac8,), # Gujarati Vowel Sign E ..Gujarati Vowel Sign Ai + (0x00acd, 0x00acd,), # Gujarati Sign Virama ..Gujarati Sign Virama + (0x00ae2, 0x00ae3,), # Gujarati Vowel Sign Voca..Gujarati Vowel Sign Voca + (0x00afa, 0x00aff,), # Gujarati Sign Sukun ..Gujarati Sign Two-circle + (0x00b01, 0x00b01,), # Oriya Sign Candrabindu ..Oriya Sign Candrabindu + (0x00b3c, 0x00b3c,), # Oriya Sign Nukta ..Oriya Sign Nukta + (0x00b3f, 0x00b3f,), # Oriya Vowel Sign I ..Oriya Vowel Sign I + (0x00b41, 0x00b44,), # Oriya Vowel Sign U ..Oriya Vowel Sign Vocalic + (0x00b4d, 0x00b4d,), # Oriya Sign Virama ..Oriya Sign Virama + (0x00b56, 0x00b56,), # Oriya Ai Length Mark ..Oriya Ai Length Mark + (0x00b62, 0x00b63,), # Oriya Vowel Sign Vocalic..Oriya Vowel Sign Vocalic + (0x00b82, 0x00b82,), # Tamil Sign Anusvara ..Tamil Sign Anusvara + (0x00bc0, 0x00bc0,), # Tamil Vowel Sign Ii ..Tamil Vowel Sign Ii + (0x00bcd, 0x00bcd,), # Tamil Sign Virama ..Tamil Sign Virama + (0x00c00, 0x00c00,), # Telugu Sign Combining Ca..Telugu Sign Combining Ca + (0x00c04, 0x00c04,), # Telugu Sign Combining An..Telugu Sign Combining An + (0x00c3e, 0x00c40,), # Telugu Vowel Sign Aa ..Telugu Vowel Sign Ii + (0x00c46, 0x00c48,), # Telugu Vowel Sign E ..Telugu Vowel Sign Ai + (0x00c4a, 0x00c4d,), # Telugu Vowel Sign O ..Telugu Sign Virama + (0x00c55, 0x00c56,), # Telugu Length Mark ..Telugu Ai Length Mark + (0x00c62, 0x00c63,), # Telugu Vowel Sign Vocali..Telugu Vowel Sign Vocali + (0x00c81, 0x00c81,), # Kannada Sign Candrabindu..Kannada Sign Candrabindu + (0x00cbc, 0x00cbc,), # Kannada Sign Nukta ..Kannada Sign Nukta + (0x00cbf, 0x00cbf,), # Kannada Vowel Sign I ..Kannada Vowel Sign I + (0x00cc6, 0x00cc6,), # Kannada Vowel Sign E ..Kannada Vowel Sign E + (0x00ccc, 0x00ccd,), # Kannada Vowel Sign Au ..Kannada Sign Virama + (0x00ce2, 0x00ce3,), # Kannada Vowel Sign Vocal..Kannada Vowel Sign Vocal + (0x00d00, 0x00d01,), # Malayalam Sign Combining..Malayalam Sign Candrabin + (0x00d3b, 0x00d3c,), # Malayalam Sign Vertical ..Malayalam Sign Circular + (0x00d41, 0x00d44,), # Malayalam Vowel Sign U ..Malayalam Vowel Sign Voc + (0x00d4d, 0x00d4d,), # Malayalam Sign Virama ..Malayalam Sign Virama + (0x00d62, 0x00d63,), # Malayalam Vowel Sign Voc..Malayalam Vowel Sign Voc + (0x00dca, 0x00dca,), # Sinhala Sign Al-lakuna ..Sinhala Sign Al-lakuna + (0x00dd2, 0x00dd4,), # Sinhala Vowel Sign Ketti..Sinhala Vowel Sign Ketti + (0x00dd6, 0x00dd6,), # Sinhala Vowel Sign Diga ..Sinhala Vowel Sign Diga + (0x00e31, 0x00e31,), # Thai Character Mai Han-a..Thai Character Mai Han-a + (0x00e34, 0x00e3a,), # Thai Character Sara I ..Thai Character Phinthu + (0x00e47, 0x00e4e,), # Thai Character Maitaikhu..Thai Character Yamakkan + (0x00eb1, 0x00eb1,), # Lao Vowel Sign Mai Kan ..Lao Vowel Sign Mai Kan + (0x00eb4, 0x00ebc,), # Lao Vowel Sign I ..Lao Semivowel Sign Lo + (0x00ec8, 0x00ecd,), # Lao Tone Mai Ek ..Lao Niggahita + (0x00f18, 0x00f19,), # Tibetan Astrological Sig..Tibetan Astrological Sig + (0x00f35, 0x00f35,), # Tibetan Mark Ngas Bzung ..Tibetan Mark Ngas Bzung + (0x00f37, 0x00f37,), # Tibetan Mark Ngas Bzung ..Tibetan Mark Ngas Bzung + (0x00f39, 0x00f39,), # Tibetan Mark Tsa -phru ..Tibetan Mark Tsa -phru + (0x00f71, 0x00f7e,), # Tibetan Vowel Sign Aa ..Tibetan Sign Rjes Su Nga + (0x00f80, 0x00f84,), # Tibetan Vowel Sign Rever..Tibetan Mark Halanta + (0x00f86, 0x00f87,), # Tibetan Sign Lci Rtags ..Tibetan Sign Yang Rtags + (0x00f8d, 0x00f97,), # Tibetan Subjoined Sign L..Tibetan Subjoined Letter + (0x00f99, 0x00fbc,), # Tibetan Subjoined Letter..Tibetan Subjoined Letter + (0x00fc6, 0x00fc6,), # Tibetan Symbol Padma Gda..Tibetan Symbol Padma Gda + (0x0102d, 0x01030,), # Myanmar Vowel Sign I ..Myanmar Vowel Sign Uu + (0x01032, 0x01037,), # Myanmar Vowel Sign Ai ..Myanmar Sign Dot Below + (0x01039, 0x0103a,), # Myanmar Sign Virama ..Myanmar Sign Asat + (0x0103d, 0x0103e,), # Myanmar Consonant Sign M..Myanmar Consonant Sign M + (0x01058, 0x01059,), # Myanmar Vowel Sign Vocal..Myanmar Vowel Sign Vocal + (0x0105e, 0x01060,), # Myanmar Consonant Sign M..Myanmar Consonant Sign M + (0x01071, 0x01074,), # Myanmar Vowel Sign Geba ..Myanmar Vowel Sign Kayah + (0x01082, 0x01082,), # Myanmar Consonant Sign S..Myanmar Consonant Sign S + (0x01085, 0x01086,), # Myanmar Vowel Sign Shan ..Myanmar Vowel Sign Shan + (0x0108d, 0x0108d,), # Myanmar Sign Shan Counci..Myanmar Sign Shan Counci + (0x0109d, 0x0109d,), # Myanmar Vowel Sign Aiton..Myanmar Vowel Sign Aiton + (0x0135d, 0x0135f,), # Ethiopic Combining Gemin..Ethiopic Combining Gemin + (0x01712, 0x01714,), # Tagalog Vowel Sign I ..Tagalog Sign Virama + (0x01732, 0x01734,), # Hanunoo Vowel Sign I ..Hanunoo Sign Pamudpod + (0x01752, 0x01753,), # Buhid Vowel Sign I ..Buhid Vowel Sign U + (0x01772, 0x01773,), # Tagbanwa Vowel Sign I ..Tagbanwa Vowel Sign U + (0x017b4, 0x017b5,), # Khmer Vowel Inherent Aq ..Khmer Vowel Inherent Aa + (0x017b7, 0x017bd,), # Khmer Vowel Sign I ..Khmer Vowel Sign Ua + (0x017c6, 0x017c6,), # Khmer Sign Nikahit ..Khmer Sign Nikahit + (0x017c9, 0x017d3,), # Khmer Sign Muusikatoan ..Khmer Sign Bathamasat + (0x017dd, 0x017dd,), # Khmer Sign Atthacan ..Khmer Sign Atthacan + (0x0180b, 0x0180d,), # Mongolian Free Variation..Mongolian Free Variation + (0x01885, 0x01886,), # Mongolian Letter Ali Gal..Mongolian Letter Ali Gal + (0x018a9, 0x018a9,), # Mongolian Letter Ali Gal..Mongolian Letter Ali Gal + (0x01920, 0x01922,), # Limbu Vowel Sign A ..Limbu Vowel Sign U + (0x01927, 0x01928,), # Limbu Vowel Sign E ..Limbu Vowel Sign O + (0x01932, 0x01932,), # Limbu Small Letter Anusv..Limbu Small Letter Anusv + (0x01939, 0x0193b,), # Limbu Sign Mukphreng ..Limbu Sign Sa-i + (0x01a17, 0x01a18,), # Buginese Vowel Sign I ..Buginese Vowel Sign U + (0x01a1b, 0x01a1b,), # Buginese Vowel Sign Ae ..Buginese Vowel Sign Ae + (0x01a56, 0x01a56,), # Tai Tham Consonant Sign ..Tai Tham Consonant Sign + (0x01a58, 0x01a5e,), # Tai Tham Sign Mai Kang L..Tai Tham Consonant Sign + (0x01a60, 0x01a60,), # Tai Tham Sign Sakot ..Tai Tham Sign Sakot + (0x01a62, 0x01a62,), # Tai Tham Vowel Sign Mai ..Tai Tham Vowel Sign Mai + (0x01a65, 0x01a6c,), # Tai Tham Vowel Sign I ..Tai Tham Vowel Sign Oa B + (0x01a73, 0x01a7c,), # Tai Tham Vowel Sign Oa A..Tai Tham Sign Khuen-lue + (0x01a7f, 0x01a7f,), # Tai Tham Combining Crypt..Tai Tham Combining Crypt + (0x01ab0, 0x01abe,), # Combining Doubled Circum..Combining Parentheses Ov + (0x01b00, 0x01b03,), # Balinese Sign Ulu Ricem ..Balinese Sign Surang + (0x01b34, 0x01b34,), # Balinese Sign Rerekan ..Balinese Sign Rerekan + (0x01b36, 0x01b3a,), # Balinese Vowel Sign Ulu ..Balinese Vowel Sign Ra R + (0x01b3c, 0x01b3c,), # Balinese Vowel Sign La L..Balinese Vowel Sign La L + (0x01b42, 0x01b42,), # Balinese Vowel Sign Pepe..Balinese Vowel Sign Pepe + (0x01b6b, 0x01b73,), # Balinese Musical Symbol ..Balinese Musical Symbol + (0x01b80, 0x01b81,), # Sundanese Sign Panyecek ..Sundanese Sign Panglayar + (0x01ba2, 0x01ba5,), # Sundanese Consonant Sign..Sundanese Vowel Sign Pan + (0x01ba8, 0x01ba9,), # Sundanese Vowel Sign Pam..Sundanese Vowel Sign Pan + (0x01bab, 0x01bad,), # Sundanese Sign Virama ..Sundanese Consonant Sign + (0x01be6, 0x01be6,), # Batak Sign Tompi ..Batak Sign Tompi + (0x01be8, 0x01be9,), # Batak Vowel Sign Pakpak ..Batak Vowel Sign Ee + (0x01bed, 0x01bed,), # Batak Vowel Sign Karo O ..Batak Vowel Sign Karo O + (0x01bef, 0x01bf1,), # Batak Vowel Sign U For S..Batak Consonant Sign H + (0x01c2c, 0x01c33,), # Lepcha Vowel Sign E ..Lepcha Consonant Sign T + (0x01c36, 0x01c37,), # Lepcha Sign Ran ..Lepcha Sign Nukta + (0x01cd0, 0x01cd2,), # Vedic Tone Karshana ..Vedic Tone Prenkha + (0x01cd4, 0x01ce0,), # Vedic Sign Yajurvedic Mi..Vedic Tone Rigvedic Kash + (0x01ce2, 0x01ce8,), # Vedic Sign Visarga Svari..Vedic Sign Visarga Anuda + (0x01ced, 0x01ced,), # Vedic Sign Tiryak ..Vedic Sign Tiryak + (0x01cf4, 0x01cf4,), # Vedic Tone Candra Above ..Vedic Tone Candra Above + (0x01cf8, 0x01cf9,), # Vedic Tone Ring Above ..Vedic Tone Double Ring A + (0x01dc0, 0x01df9,), # Combining Dotted Grave A..Combining Wide Inverted + (0x01dfb, 0x01dff,), # Combining Deletion Mark ..Combining Right Arrowhea + (0x020d0, 0x020f0,), # Combining Left Harpoon A..Combining Asterisk Above + (0x02cef, 0x02cf1,), # Coptic Combining Ni Abov..Coptic Combining Spiritu + (0x02d7f, 0x02d7f,), # Tifinagh Consonant Joine..Tifinagh Consonant Joine + (0x02de0, 0x02dff,), # Combining Cyrillic Lette..Combining Cyrillic Lette + (0x0302a, 0x0302d,), # Ideographic Level Tone M..Ideographic Entering Ton + (0x03099, 0x0309a,), # Combining Katakana-hirag..Combining Katakana-hirag + (0x0a66f, 0x0a672,), # Combining Cyrillic Vzmet..Combining Cyrillic Thous + (0x0a674, 0x0a67d,), # Combining Cyrillic Lette..Combining Cyrillic Payer + (0x0a69e, 0x0a69f,), # Combining Cyrillic Lette..Combining Cyrillic Lette + (0x0a6f0, 0x0a6f1,), # Bamum Combining Mark Koq..Bamum Combining Mark Tuk + (0x0a802, 0x0a802,), # Syloti Nagri Sign Dvisva..Syloti Nagri Sign Dvisva + (0x0a806, 0x0a806,), # Syloti Nagri Sign Hasant..Syloti Nagri Sign Hasant + (0x0a80b, 0x0a80b,), # Syloti Nagri Sign Anusva..Syloti Nagri Sign Anusva + (0x0a825, 0x0a826,), # Syloti Nagri Vowel Sign ..Syloti Nagri Vowel Sign + (0x0a8c4, 0x0a8c5,), # Saurashtra Sign Virama ..Saurashtra Sign Candrabi + (0x0a8e0, 0x0a8f1,), # Combining Devanagari Dig..Combining Devanagari Sig + (0x0a8ff, 0x0a8ff,), # Devanagari Vowel Sign Ay..Devanagari Vowel Sign Ay + (0x0a926, 0x0a92d,), # Kayah Li Vowel Ue ..Kayah Li Tone Calya Plop + (0x0a947, 0x0a951,), # Rejang Vowel Sign I ..Rejang Consonant Sign R + (0x0a980, 0x0a982,), # Javanese Sign Panyangga ..Javanese Sign Layar + (0x0a9b3, 0x0a9b3,), # Javanese Sign Cecak Telu..Javanese Sign Cecak Telu + (0x0a9b6, 0x0a9b9,), # Javanese Vowel Sign Wulu..Javanese Vowel Sign Suku + (0x0a9bc, 0x0a9bd,), # Javanese Vowel Sign Pepe..Javanese Consonant Sign + (0x0a9e5, 0x0a9e5,), # Myanmar Sign Shan Saw ..Myanmar Sign Shan Saw + (0x0aa29, 0x0aa2e,), # Cham Vowel Sign Aa ..Cham Vowel Sign Oe + (0x0aa31, 0x0aa32,), # Cham Vowel Sign Au ..Cham Vowel Sign Ue + (0x0aa35, 0x0aa36,), # Cham Consonant Sign La ..Cham Consonant Sign Wa + (0x0aa43, 0x0aa43,), # Cham Consonant Sign Fina..Cham Consonant Sign Fina + (0x0aa4c, 0x0aa4c,), # Cham Consonant Sign Fina..Cham Consonant Sign Fina + (0x0aa7c, 0x0aa7c,), # Myanmar Sign Tai Laing T..Myanmar Sign Tai Laing T + (0x0aab0, 0x0aab0,), # Tai Viet Mai Kang ..Tai Viet Mai Kang + (0x0aab2, 0x0aab4,), # Tai Viet Vowel I ..Tai Viet Vowel U + (0x0aab7, 0x0aab8,), # Tai Viet Mai Khit ..Tai Viet Vowel Ia + (0x0aabe, 0x0aabf,), # Tai Viet Vowel Am ..Tai Viet Tone Mai Ek + (0x0aac1, 0x0aac1,), # Tai Viet Tone Mai Tho ..Tai Viet Tone Mai Tho + (0x0aaec, 0x0aaed,), # Meetei Mayek Vowel Sign ..Meetei Mayek Vowel Sign + (0x0aaf6, 0x0aaf6,), # Meetei Mayek Virama ..Meetei Mayek Virama + (0x0abe5, 0x0abe5,), # Meetei Mayek Vowel Sign ..Meetei Mayek Vowel Sign + (0x0abe8, 0x0abe8,), # Meetei Mayek Vowel Sign ..Meetei Mayek Vowel Sign + (0x0abed, 0x0abed,), # Meetei Mayek Apun Iyek ..Meetei Mayek Apun Iyek + (0x0fb1e, 0x0fb1e,), # Hebrew Point Judeo-spani..Hebrew Point Judeo-spani + (0x0fe00, 0x0fe0f,), # Variation Selector-1 ..Variation Selector-16 + (0x0fe20, 0x0fe2f,), # Combining Ligature Left ..Combining Cyrillic Titlo + (0x101fd, 0x101fd,), # Phaistos Disc Sign Combi..Phaistos Disc Sign Combi + (0x102e0, 0x102e0,), # Coptic Epact Thousands M..Coptic Epact Thousands M + (0x10376, 0x1037a,), # Combining Old Permic Let..Combining Old Permic Let + (0x10a01, 0x10a03,), # Kharoshthi Vowel Sign I ..Kharoshthi Vowel Sign Vo + (0x10a05, 0x10a06,), # Kharoshthi Vowel Sign E ..Kharoshthi Vowel Sign O + (0x10a0c, 0x10a0f,), # Kharoshthi Vowel Length ..Kharoshthi Sign Visarga + (0x10a38, 0x10a3a,), # Kharoshthi Sign Bar Abov..Kharoshthi Sign Dot Belo + (0x10a3f, 0x10a3f,), # Kharoshthi Virama ..Kharoshthi Virama + (0x10ae5, 0x10ae6,), # Manichaean Abbreviation ..Manichaean Abbreviation + (0x10d24, 0x10d27,), # Hanifi Rohingya Sign Har..Hanifi Rohingya Sign Tas + (0x10f46, 0x10f50,), # Sogdian Combining Dot Be..Sogdian Combining Stroke + (0x11001, 0x11001,), # Brahmi Sign Anusvara ..Brahmi Sign Anusvara + (0x11038, 0x11046,), # Brahmi Vowel Sign Aa ..Brahmi Virama + (0x1107f, 0x11081,), # Brahmi Number Joiner ..Kaithi Sign Anusvara + (0x110b3, 0x110b6,), # Kaithi Vowel Sign U ..Kaithi Vowel Sign Ai + (0x110b9, 0x110ba,), # Kaithi Sign Virama ..Kaithi Sign Nukta + (0x11100, 0x11102,), # Chakma Sign Candrabindu ..Chakma Sign Visarga + (0x11127, 0x1112b,), # Chakma Vowel Sign A ..Chakma Vowel Sign Uu + (0x1112d, 0x11134,), # Chakma Vowel Sign Ai ..Chakma Maayyaa + (0x11173, 0x11173,), # Mahajani Sign Nukta ..Mahajani Sign Nukta + (0x11180, 0x11181,), # Sharada Sign Candrabindu..Sharada Sign Anusvara + (0x111b6, 0x111be,), # Sharada Vowel Sign U ..Sharada Vowel Sign O + (0x111c9, 0x111cc,), # Sharada Sandhi Mark ..Sharada Extra Short Vowe + (0x1122f, 0x11231,), # Khojki Vowel Sign U ..Khojki Vowel Sign Ai + (0x11234, 0x11234,), # Khojki Sign Anusvara ..Khojki Sign Anusvara + (0x11236, 0x11237,), # Khojki Sign Nukta ..Khojki Sign Shadda + (0x1123e, 0x1123e,), # Khojki Sign Sukun ..Khojki Sign Sukun + (0x112df, 0x112df,), # Khudawadi Sign Anusvara ..Khudawadi Sign Anusvara + (0x112e3, 0x112ea,), # Khudawadi Vowel Sign U ..Khudawadi Sign Virama + (0x11300, 0x11301,), # Grantha Sign Combining A..Grantha Sign Candrabindu + (0x1133b, 0x1133c,), # Combining Bindu Below ..Grantha Sign Nukta + (0x11340, 0x11340,), # Grantha Vowel Sign Ii ..Grantha Vowel Sign Ii + (0x11366, 0x1136c,), # Combining Grantha Digit ..Combining Grantha Digit + (0x11370, 0x11374,), # Combining Grantha Letter..Combining Grantha Letter + (0x11438, 0x1143f,), # Newa Vowel Sign U ..Newa Vowel Sign Ai + (0x11442, 0x11444,), # Newa Sign Virama ..Newa Sign Anusvara + (0x11446, 0x11446,), # Newa Sign Nukta ..Newa Sign Nukta + (0x1145e, 0x1145e,), # Newa Sandhi Mark ..Newa Sandhi Mark + (0x114b3, 0x114b8,), # Tirhuta Vowel Sign U ..Tirhuta Vowel Sign Vocal + (0x114ba, 0x114ba,), # Tirhuta Vowel Sign Short..Tirhuta Vowel Sign Short + (0x114bf, 0x114c0,), # Tirhuta Sign Candrabindu..Tirhuta Sign Anusvara + (0x114c2, 0x114c3,), # Tirhuta Sign Virama ..Tirhuta Sign Nukta + (0x115b2, 0x115b5,), # Siddham Vowel Sign U ..Siddham Vowel Sign Vocal + (0x115bc, 0x115bd,), # Siddham Sign Candrabindu..Siddham Sign Anusvara + (0x115bf, 0x115c0,), # Siddham Sign Virama ..Siddham Sign Nukta + (0x115dc, 0x115dd,), # Siddham Vowel Sign Alter..Siddham Vowel Sign Alter + (0x11633, 0x1163a,), # Modi Vowel Sign U ..Modi Vowel Sign Ai + (0x1163d, 0x1163d,), # Modi Sign Anusvara ..Modi Sign Anusvara + (0x1163f, 0x11640,), # Modi Sign Virama ..Modi Sign Ardhacandra + (0x116ab, 0x116ab,), # Takri Sign Anusvara ..Takri Sign Anusvara + (0x116ad, 0x116ad,), # Takri Vowel Sign Aa ..Takri Vowel Sign Aa + (0x116b0, 0x116b5,), # Takri Vowel Sign U ..Takri Vowel Sign Au + (0x116b7, 0x116b7,), # Takri Sign Nukta ..Takri Sign Nukta + (0x1171d, 0x1171f,), # Ahom Consonant Sign Medi..Ahom Consonant Sign Medi + (0x11722, 0x11725,), # Ahom Vowel Sign I ..Ahom Vowel Sign Uu + (0x11727, 0x1172b,), # Ahom Vowel Sign Aw ..Ahom Sign Killer + (0x1182f, 0x11837,), # Dogra Vowel Sign U ..Dogra Sign Anusvara + (0x11839, 0x1183a,), # Dogra Sign Virama ..Dogra Sign Nukta + (0x119d4, 0x119d7,), # Nandinagari Vowel Sign U..Nandinagari Vowel Sign V + (0x119da, 0x119db,), # Nandinagari Vowel Sign E..Nandinagari Vowel Sign A + (0x119e0, 0x119e0,), # Nandinagari Sign Virama ..Nandinagari Sign Virama + (0x11a01, 0x11a0a,), # Zanabazar Square Vowel S..Zanabazar Square Vowel L + (0x11a33, 0x11a38,), # Zanabazar Square Final C..Zanabazar Square Sign An + (0x11a3b, 0x11a3e,), # Zanabazar Square Cluster..Zanabazar Square Cluster + (0x11a47, 0x11a47,), # Zanabazar Square Subjoin..Zanabazar Square Subjoin + (0x11a51, 0x11a56,), # Soyombo Vowel Sign I ..Soyombo Vowel Sign Oe + (0x11a59, 0x11a5b,), # Soyombo Vowel Sign Vocal..Soyombo Vowel Length Mar + (0x11a8a, 0x11a96,), # Soyombo Final Consonant ..Soyombo Sign Anusvara + (0x11a98, 0x11a99,), # Soyombo Gemination Mark ..Soyombo Subjoiner + (0x11c30, 0x11c36,), # Bhaiksuki Vowel Sign I ..Bhaiksuki Vowel Sign Voc + (0x11c38, 0x11c3d,), # Bhaiksuki Vowel Sign E ..Bhaiksuki Sign Anusvara + (0x11c3f, 0x11c3f,), # Bhaiksuki Sign Virama ..Bhaiksuki Sign Virama + (0x11c92, 0x11ca7,), # Marchen Subjoined Letter..Marchen Subjoined Letter + (0x11caa, 0x11cb0,), # Marchen Subjoined Letter..Marchen Vowel Sign Aa + (0x11cb2, 0x11cb3,), # Marchen Vowel Sign U ..Marchen Vowel Sign E + (0x11cb5, 0x11cb6,), # Marchen Sign Anusvara ..Marchen Sign Candrabindu + (0x11d31, 0x11d36,), # Masaram Gondi Vowel Sign..Masaram Gondi Vowel Sign + (0x11d3a, 0x11d3a,), # Masaram Gondi Vowel Sign..Masaram Gondi Vowel Sign + (0x11d3c, 0x11d3d,), # Masaram Gondi Vowel Sign..Masaram Gondi Vowel Sign + (0x11d3f, 0x11d45,), # Masaram Gondi Vowel Sign..Masaram Gondi Virama + (0x11d47, 0x11d47,), # Masaram Gondi Ra-kara ..Masaram Gondi Ra-kara + (0x11d90, 0x11d91,), # Gunjala Gondi Vowel Sign..Gunjala Gondi Vowel Sign + (0x11d95, 0x11d95,), # Gunjala Gondi Sign Anusv..Gunjala Gondi Sign Anusv + (0x11d97, 0x11d97,), # Gunjala Gondi Virama ..Gunjala Gondi Virama + (0x11ef3, 0x11ef4,), # Makasar Vowel Sign I ..Makasar Vowel Sign U + (0x16af0, 0x16af4,), # Bassa Vah Combining High..Bassa Vah Combining High + (0x16b30, 0x16b36,), # Pahawh Hmong Mark Cim Tu..Pahawh Hmong Mark Cim Ta + (0x16f4f, 0x16f4f,), # Miao Sign Consonant Modi..Miao Sign Consonant Modi + (0x16f8f, 0x16f92,), # Miao Tone Right ..Miao Tone Below + (0x1bc9d, 0x1bc9e,), # Duployan Thick Letter Se..Duployan Double Mark + (0x1d167, 0x1d169,), # Musical Symbol Combining..Musical Symbol Combining + (0x1d17b, 0x1d182,), # Musical Symbol Combining..Musical Symbol Combining + (0x1d185, 0x1d18b,), # Musical Symbol Combining..Musical Symbol Combining + (0x1d1aa, 0x1d1ad,), # Musical Symbol Combining..Musical Symbol Combining + (0x1d242, 0x1d244,), # Combining Greek Musical ..Combining Greek Musical + (0x1da00, 0x1da36,), # Signwriting Head Rim ..Signwriting Air Sucking + (0x1da3b, 0x1da6c,), # Signwriting Mouth Closed..Signwriting Excitement + (0x1da75, 0x1da75,), # Signwriting Upper Body T..Signwriting Upper Body T + (0x1da84, 0x1da84,), # Signwriting Location Hea..Signwriting Location Hea + (0x1da9b, 0x1da9f,), # Signwriting Fill Modifie..Signwriting Fill Modifie + (0x1daa1, 0x1daaf,), # Signwriting Rotation Mod..Signwriting Rotation Mod + (0x1e000, 0x1e006,), # Combining Glagolitic Let..Combining Glagolitic Let + (0x1e008, 0x1e018,), # Combining Glagolitic Let..Combining Glagolitic Let + (0x1e01b, 0x1e021,), # Combining Glagolitic Let..Combining Glagolitic Let + (0x1e023, 0x1e024,), # Combining Glagolitic Let..Combining Glagolitic Let + (0x1e026, 0x1e02a,), # Combining Glagolitic Let..Combining Glagolitic Let + (0x1e130, 0x1e136,), # Nyiakeng Puachue Hmong T..Nyiakeng Puachue Hmong T + (0x1e2ec, 0x1e2ef,), # Wancho Tone Tup ..Wancho Tone Koini + (0x1e8d0, 0x1e8d6,), # Mende Kikakui Combining ..Mende Kikakui Combining + (0x1e944, 0x1e94a,), # Adlam Alif Lengthener ..Adlam Nukta + (0xe0100, 0xe01ef,), # Variation Selector-17 ..Variation Selector-256 + ), + '12.1.0': ( + # Source: DerivedGeneralCategory-12.1.0.txt + # Date: 2019-03-10, 10:53:08 GMT + # + (0x00300, 0x0036f,), # Combining Grave Accent ..Combining Latin Small Le + (0x00483, 0x00489,), # Combining Cyrillic Titlo..Combining Cyrillic Milli + (0x00591, 0x005bd,), # Hebrew Accent Etnahta ..Hebrew Point Meteg + (0x005bf, 0x005bf,), # Hebrew Point Rafe ..Hebrew Point Rafe + (0x005c1, 0x005c2,), # Hebrew Point Shin Dot ..Hebrew Point Sin Dot + (0x005c4, 0x005c5,), # Hebrew Mark Upper Dot ..Hebrew Mark Lower Dot + (0x005c7, 0x005c7,), # Hebrew Point Qamats Qata..Hebrew Point Qamats Qata + (0x00610, 0x0061a,), # Arabic Sign Sallallahou ..Arabic Small Kasra + (0x0064b, 0x0065f,), # Arabic Fathatan ..Arabic Wavy Hamza Below + (0x00670, 0x00670,), # Arabic Letter Superscrip..Arabic Letter Superscrip + (0x006d6, 0x006dc,), # Arabic Small High Ligatu..Arabic Small High Seen + (0x006df, 0x006e4,), # Arabic Small High Rounde..Arabic Small High Madda + (0x006e7, 0x006e8,), # Arabic Small High Yeh ..Arabic Small High Noon + (0x006ea, 0x006ed,), # Arabic Empty Centre Low ..Arabic Small Low Meem + (0x00711, 0x00711,), # Syriac Letter Superscrip..Syriac Letter Superscrip + (0x00730, 0x0074a,), # Syriac Pthaha Above ..Syriac Barrekh + (0x007a6, 0x007b0,), # Thaana Abafili ..Thaana Sukun + (0x007eb, 0x007f3,), # Nko Combining Short High..Nko Combining Double Dot + (0x007fd, 0x007fd,), # Nko Dantayalan ..Nko Dantayalan + (0x00816, 0x00819,), # Samaritan Mark In ..Samaritan Mark Dagesh + (0x0081b, 0x00823,), # Samaritan Mark Epentheti..Samaritan Vowel Sign A + (0x00825, 0x00827,), # Samaritan Vowel Sign Sho..Samaritan Vowel Sign U + (0x00829, 0x0082d,), # Samaritan Vowel Sign Lon..Samaritan Mark Nequdaa + (0x00859, 0x0085b,), # Mandaic Affrication Mark..Mandaic Gemination Mark + (0x008d3, 0x008e1,), # Arabic Small Low Waw ..Arabic Small High Sign S + (0x008e3, 0x00902,), # Arabic Turned Damma Belo..Devanagari Sign Anusvara + (0x0093a, 0x0093a,), # Devanagari Vowel Sign Oe..Devanagari Vowel Sign Oe + (0x0093c, 0x0093c,), # Devanagari Sign Nukta ..Devanagari Sign Nukta + (0x00941, 0x00948,), # Devanagari Vowel Sign U ..Devanagari Vowel Sign Ai + (0x0094d, 0x0094d,), # Devanagari Sign Virama ..Devanagari Sign Virama + (0x00951, 0x00957,), # Devanagari Stress Sign U..Devanagari Vowel Sign Uu + (0x00962, 0x00963,), # Devanagari Vowel Sign Vo..Devanagari Vowel Sign Vo + (0x00981, 0x00981,), # Bengali Sign Candrabindu..Bengali Sign Candrabindu + (0x009bc, 0x009bc,), # Bengali Sign Nukta ..Bengali Sign Nukta + (0x009c1, 0x009c4,), # Bengali Vowel Sign U ..Bengali Vowel Sign Vocal + (0x009cd, 0x009cd,), # Bengali Sign Virama ..Bengali Sign Virama + (0x009e2, 0x009e3,), # Bengali Vowel Sign Vocal..Bengali Vowel Sign Vocal + (0x009fe, 0x009fe,), # Bengali Sandhi Mark ..Bengali Sandhi Mark + (0x00a01, 0x00a02,), # Gurmukhi Sign Adak Bindi..Gurmukhi Sign Bindi + (0x00a3c, 0x00a3c,), # Gurmukhi Sign Nukta ..Gurmukhi Sign Nukta + (0x00a41, 0x00a42,), # Gurmukhi Vowel Sign U ..Gurmukhi Vowel Sign Uu + (0x00a47, 0x00a48,), # Gurmukhi Vowel Sign Ee ..Gurmukhi Vowel Sign Ai + (0x00a4b, 0x00a4d,), # Gurmukhi Vowel Sign Oo ..Gurmukhi Sign Virama + (0x00a51, 0x00a51,), # Gurmukhi Sign Udaat ..Gurmukhi Sign Udaat + (0x00a70, 0x00a71,), # Gurmukhi Tippi ..Gurmukhi Addak + (0x00a75, 0x00a75,), # Gurmukhi Sign Yakash ..Gurmukhi Sign Yakash + (0x00a81, 0x00a82,), # Gujarati Sign Candrabind..Gujarati Sign Anusvara + (0x00abc, 0x00abc,), # Gujarati Sign Nukta ..Gujarati Sign Nukta + (0x00ac1, 0x00ac5,), # Gujarati Vowel Sign U ..Gujarati Vowel Sign Cand + (0x00ac7, 0x00ac8,), # Gujarati Vowel Sign E ..Gujarati Vowel Sign Ai + (0x00acd, 0x00acd,), # Gujarati Sign Virama ..Gujarati Sign Virama + (0x00ae2, 0x00ae3,), # Gujarati Vowel Sign Voca..Gujarati Vowel Sign Voca + (0x00afa, 0x00aff,), # Gujarati Sign Sukun ..Gujarati Sign Two-circle + (0x00b01, 0x00b01,), # Oriya Sign Candrabindu ..Oriya Sign Candrabindu + (0x00b3c, 0x00b3c,), # Oriya Sign Nukta ..Oriya Sign Nukta + (0x00b3f, 0x00b3f,), # Oriya Vowel Sign I ..Oriya Vowel Sign I + (0x00b41, 0x00b44,), # Oriya Vowel Sign U ..Oriya Vowel Sign Vocalic + (0x00b4d, 0x00b4d,), # Oriya Sign Virama ..Oriya Sign Virama + (0x00b56, 0x00b56,), # Oriya Ai Length Mark ..Oriya Ai Length Mark + (0x00b62, 0x00b63,), # Oriya Vowel Sign Vocalic..Oriya Vowel Sign Vocalic + (0x00b82, 0x00b82,), # Tamil Sign Anusvara ..Tamil Sign Anusvara + (0x00bc0, 0x00bc0,), # Tamil Vowel Sign Ii ..Tamil Vowel Sign Ii + (0x00bcd, 0x00bcd,), # Tamil Sign Virama ..Tamil Sign Virama + (0x00c00, 0x00c00,), # Telugu Sign Combining Ca..Telugu Sign Combining Ca + (0x00c04, 0x00c04,), # Telugu Sign Combining An..Telugu Sign Combining An + (0x00c3e, 0x00c40,), # Telugu Vowel Sign Aa ..Telugu Vowel Sign Ii + (0x00c46, 0x00c48,), # Telugu Vowel Sign E ..Telugu Vowel Sign Ai + (0x00c4a, 0x00c4d,), # Telugu Vowel Sign O ..Telugu Sign Virama + (0x00c55, 0x00c56,), # Telugu Length Mark ..Telugu Ai Length Mark + (0x00c62, 0x00c63,), # Telugu Vowel Sign Vocali..Telugu Vowel Sign Vocali + (0x00c81, 0x00c81,), # Kannada Sign Candrabindu..Kannada Sign Candrabindu + (0x00cbc, 0x00cbc,), # Kannada Sign Nukta ..Kannada Sign Nukta + (0x00cbf, 0x00cbf,), # Kannada Vowel Sign I ..Kannada Vowel Sign I + (0x00cc6, 0x00cc6,), # Kannada Vowel Sign E ..Kannada Vowel Sign E + (0x00ccc, 0x00ccd,), # Kannada Vowel Sign Au ..Kannada Sign Virama + (0x00ce2, 0x00ce3,), # Kannada Vowel Sign Vocal..Kannada Vowel Sign Vocal + (0x00d00, 0x00d01,), # Malayalam Sign Combining..Malayalam Sign Candrabin + (0x00d3b, 0x00d3c,), # Malayalam Sign Vertical ..Malayalam Sign Circular + (0x00d41, 0x00d44,), # Malayalam Vowel Sign U ..Malayalam Vowel Sign Voc + (0x00d4d, 0x00d4d,), # Malayalam Sign Virama ..Malayalam Sign Virama + (0x00d62, 0x00d63,), # Malayalam Vowel Sign Voc..Malayalam Vowel Sign Voc + (0x00dca, 0x00dca,), # Sinhala Sign Al-lakuna ..Sinhala Sign Al-lakuna + (0x00dd2, 0x00dd4,), # Sinhala Vowel Sign Ketti..Sinhala Vowel Sign Ketti + (0x00dd6, 0x00dd6,), # Sinhala Vowel Sign Diga ..Sinhala Vowel Sign Diga + (0x00e31, 0x00e31,), # Thai Character Mai Han-a..Thai Character Mai Han-a + (0x00e34, 0x00e3a,), # Thai Character Sara I ..Thai Character Phinthu + (0x00e47, 0x00e4e,), # Thai Character Maitaikhu..Thai Character Yamakkan + (0x00eb1, 0x00eb1,), # Lao Vowel Sign Mai Kan ..Lao Vowel Sign Mai Kan + (0x00eb4, 0x00ebc,), # Lao Vowel Sign I ..Lao Semivowel Sign Lo + (0x00ec8, 0x00ecd,), # Lao Tone Mai Ek ..Lao Niggahita + (0x00f18, 0x00f19,), # Tibetan Astrological Sig..Tibetan Astrological Sig + (0x00f35, 0x00f35,), # Tibetan Mark Ngas Bzung ..Tibetan Mark Ngas Bzung + (0x00f37, 0x00f37,), # Tibetan Mark Ngas Bzung ..Tibetan Mark Ngas Bzung + (0x00f39, 0x00f39,), # Tibetan Mark Tsa -phru ..Tibetan Mark Tsa -phru + (0x00f71, 0x00f7e,), # Tibetan Vowel Sign Aa ..Tibetan Sign Rjes Su Nga + (0x00f80, 0x00f84,), # Tibetan Vowel Sign Rever..Tibetan Mark Halanta + (0x00f86, 0x00f87,), # Tibetan Sign Lci Rtags ..Tibetan Sign Yang Rtags + (0x00f8d, 0x00f97,), # Tibetan Subjoined Sign L..Tibetan Subjoined Letter + (0x00f99, 0x00fbc,), # Tibetan Subjoined Letter..Tibetan Subjoined Letter + (0x00fc6, 0x00fc6,), # Tibetan Symbol Padma Gda..Tibetan Symbol Padma Gda + (0x0102d, 0x01030,), # Myanmar Vowel Sign I ..Myanmar Vowel Sign Uu + (0x01032, 0x01037,), # Myanmar Vowel Sign Ai ..Myanmar Sign Dot Below + (0x01039, 0x0103a,), # Myanmar Sign Virama ..Myanmar Sign Asat + (0x0103d, 0x0103e,), # Myanmar Consonant Sign M..Myanmar Consonant Sign M + (0x01058, 0x01059,), # Myanmar Vowel Sign Vocal..Myanmar Vowel Sign Vocal + (0x0105e, 0x01060,), # Myanmar Consonant Sign M..Myanmar Consonant Sign M + (0x01071, 0x01074,), # Myanmar Vowel Sign Geba ..Myanmar Vowel Sign Kayah + (0x01082, 0x01082,), # Myanmar Consonant Sign S..Myanmar Consonant Sign S + (0x01085, 0x01086,), # Myanmar Vowel Sign Shan ..Myanmar Vowel Sign Shan + (0x0108d, 0x0108d,), # Myanmar Sign Shan Counci..Myanmar Sign Shan Counci + (0x0109d, 0x0109d,), # Myanmar Vowel Sign Aiton..Myanmar Vowel Sign Aiton + (0x0135d, 0x0135f,), # Ethiopic Combining Gemin..Ethiopic Combining Gemin + (0x01712, 0x01714,), # Tagalog Vowel Sign I ..Tagalog Sign Virama + (0x01732, 0x01734,), # Hanunoo Vowel Sign I ..Hanunoo Sign Pamudpod + (0x01752, 0x01753,), # Buhid Vowel Sign I ..Buhid Vowel Sign U + (0x01772, 0x01773,), # Tagbanwa Vowel Sign I ..Tagbanwa Vowel Sign U + (0x017b4, 0x017b5,), # Khmer Vowel Inherent Aq ..Khmer Vowel Inherent Aa + (0x017b7, 0x017bd,), # Khmer Vowel Sign I ..Khmer Vowel Sign Ua + (0x017c6, 0x017c6,), # Khmer Sign Nikahit ..Khmer Sign Nikahit + (0x017c9, 0x017d3,), # Khmer Sign Muusikatoan ..Khmer Sign Bathamasat + (0x017dd, 0x017dd,), # Khmer Sign Atthacan ..Khmer Sign Atthacan + (0x0180b, 0x0180d,), # Mongolian Free Variation..Mongolian Free Variation + (0x01885, 0x01886,), # Mongolian Letter Ali Gal..Mongolian Letter Ali Gal + (0x018a9, 0x018a9,), # Mongolian Letter Ali Gal..Mongolian Letter Ali Gal + (0x01920, 0x01922,), # Limbu Vowel Sign A ..Limbu Vowel Sign U + (0x01927, 0x01928,), # Limbu Vowel Sign E ..Limbu Vowel Sign O + (0x01932, 0x01932,), # Limbu Small Letter Anusv..Limbu Small Letter Anusv + (0x01939, 0x0193b,), # Limbu Sign Mukphreng ..Limbu Sign Sa-i + (0x01a17, 0x01a18,), # Buginese Vowel Sign I ..Buginese Vowel Sign U + (0x01a1b, 0x01a1b,), # Buginese Vowel Sign Ae ..Buginese Vowel Sign Ae + (0x01a56, 0x01a56,), # Tai Tham Consonant Sign ..Tai Tham Consonant Sign + (0x01a58, 0x01a5e,), # Tai Tham Sign Mai Kang L..Tai Tham Consonant Sign + (0x01a60, 0x01a60,), # Tai Tham Sign Sakot ..Tai Tham Sign Sakot + (0x01a62, 0x01a62,), # Tai Tham Vowel Sign Mai ..Tai Tham Vowel Sign Mai + (0x01a65, 0x01a6c,), # Tai Tham Vowel Sign I ..Tai Tham Vowel Sign Oa B + (0x01a73, 0x01a7c,), # Tai Tham Vowel Sign Oa A..Tai Tham Sign Khuen-lue + (0x01a7f, 0x01a7f,), # Tai Tham Combining Crypt..Tai Tham Combining Crypt + (0x01ab0, 0x01abe,), # Combining Doubled Circum..Combining Parentheses Ov + (0x01b00, 0x01b03,), # Balinese Sign Ulu Ricem ..Balinese Sign Surang + (0x01b34, 0x01b34,), # Balinese Sign Rerekan ..Balinese Sign Rerekan + (0x01b36, 0x01b3a,), # Balinese Vowel Sign Ulu ..Balinese Vowel Sign Ra R + (0x01b3c, 0x01b3c,), # Balinese Vowel Sign La L..Balinese Vowel Sign La L + (0x01b42, 0x01b42,), # Balinese Vowel Sign Pepe..Balinese Vowel Sign Pepe + (0x01b6b, 0x01b73,), # Balinese Musical Symbol ..Balinese Musical Symbol + (0x01b80, 0x01b81,), # Sundanese Sign Panyecek ..Sundanese Sign Panglayar + (0x01ba2, 0x01ba5,), # Sundanese Consonant Sign..Sundanese Vowel Sign Pan + (0x01ba8, 0x01ba9,), # Sundanese Vowel Sign Pam..Sundanese Vowel Sign Pan + (0x01bab, 0x01bad,), # Sundanese Sign Virama ..Sundanese Consonant Sign + (0x01be6, 0x01be6,), # Batak Sign Tompi ..Batak Sign Tompi + (0x01be8, 0x01be9,), # Batak Vowel Sign Pakpak ..Batak Vowel Sign Ee + (0x01bed, 0x01bed,), # Batak Vowel Sign Karo O ..Batak Vowel Sign Karo O + (0x01bef, 0x01bf1,), # Batak Vowel Sign U For S..Batak Consonant Sign H + (0x01c2c, 0x01c33,), # Lepcha Vowel Sign E ..Lepcha Consonant Sign T + (0x01c36, 0x01c37,), # Lepcha Sign Ran ..Lepcha Sign Nukta + (0x01cd0, 0x01cd2,), # Vedic Tone Karshana ..Vedic Tone Prenkha + (0x01cd4, 0x01ce0,), # Vedic Sign Yajurvedic Mi..Vedic Tone Rigvedic Kash + (0x01ce2, 0x01ce8,), # Vedic Sign Visarga Svari..Vedic Sign Visarga Anuda + (0x01ced, 0x01ced,), # Vedic Sign Tiryak ..Vedic Sign Tiryak + (0x01cf4, 0x01cf4,), # Vedic Tone Candra Above ..Vedic Tone Candra Above + (0x01cf8, 0x01cf9,), # Vedic Tone Ring Above ..Vedic Tone Double Ring A + (0x01dc0, 0x01df9,), # Combining Dotted Grave A..Combining Wide Inverted + (0x01dfb, 0x01dff,), # Combining Deletion Mark ..Combining Right Arrowhea + (0x020d0, 0x020f0,), # Combining Left Harpoon A..Combining Asterisk Above + (0x02cef, 0x02cf1,), # Coptic Combining Ni Abov..Coptic Combining Spiritu + (0x02d7f, 0x02d7f,), # Tifinagh Consonant Joine..Tifinagh Consonant Joine + (0x02de0, 0x02dff,), # Combining Cyrillic Lette..Combining Cyrillic Lette + (0x0302a, 0x0302d,), # Ideographic Level Tone M..Ideographic Entering Ton + (0x03099, 0x0309a,), # Combining Katakana-hirag..Combining Katakana-hirag + (0x0a66f, 0x0a672,), # Combining Cyrillic Vzmet..Combining Cyrillic Thous + (0x0a674, 0x0a67d,), # Combining Cyrillic Lette..Combining Cyrillic Payer + (0x0a69e, 0x0a69f,), # Combining Cyrillic Lette..Combining Cyrillic Lette + (0x0a6f0, 0x0a6f1,), # Bamum Combining Mark Koq..Bamum Combining Mark Tuk + (0x0a802, 0x0a802,), # Syloti Nagri Sign Dvisva..Syloti Nagri Sign Dvisva + (0x0a806, 0x0a806,), # Syloti Nagri Sign Hasant..Syloti Nagri Sign Hasant + (0x0a80b, 0x0a80b,), # Syloti Nagri Sign Anusva..Syloti Nagri Sign Anusva + (0x0a825, 0x0a826,), # Syloti Nagri Vowel Sign ..Syloti Nagri Vowel Sign + (0x0a8c4, 0x0a8c5,), # Saurashtra Sign Virama ..Saurashtra Sign Candrabi + (0x0a8e0, 0x0a8f1,), # Combining Devanagari Dig..Combining Devanagari Sig + (0x0a8ff, 0x0a8ff,), # Devanagari Vowel Sign Ay..Devanagari Vowel Sign Ay + (0x0a926, 0x0a92d,), # Kayah Li Vowel Ue ..Kayah Li Tone Calya Plop + (0x0a947, 0x0a951,), # Rejang Vowel Sign I ..Rejang Consonant Sign R + (0x0a980, 0x0a982,), # Javanese Sign Panyangga ..Javanese Sign Layar + (0x0a9b3, 0x0a9b3,), # Javanese Sign Cecak Telu..Javanese Sign Cecak Telu + (0x0a9b6, 0x0a9b9,), # Javanese Vowel Sign Wulu..Javanese Vowel Sign Suku + (0x0a9bc, 0x0a9bd,), # Javanese Vowel Sign Pepe..Javanese Consonant Sign + (0x0a9e5, 0x0a9e5,), # Myanmar Sign Shan Saw ..Myanmar Sign Shan Saw + (0x0aa29, 0x0aa2e,), # Cham Vowel Sign Aa ..Cham Vowel Sign Oe + (0x0aa31, 0x0aa32,), # Cham Vowel Sign Au ..Cham Vowel Sign Ue + (0x0aa35, 0x0aa36,), # Cham Consonant Sign La ..Cham Consonant Sign Wa + (0x0aa43, 0x0aa43,), # Cham Consonant Sign Fina..Cham Consonant Sign Fina + (0x0aa4c, 0x0aa4c,), # Cham Consonant Sign Fina..Cham Consonant Sign Fina + (0x0aa7c, 0x0aa7c,), # Myanmar Sign Tai Laing T..Myanmar Sign Tai Laing T + (0x0aab0, 0x0aab0,), # Tai Viet Mai Kang ..Tai Viet Mai Kang + (0x0aab2, 0x0aab4,), # Tai Viet Vowel I ..Tai Viet Vowel U + (0x0aab7, 0x0aab8,), # Tai Viet Mai Khit ..Tai Viet Vowel Ia + (0x0aabe, 0x0aabf,), # Tai Viet Vowel Am ..Tai Viet Tone Mai Ek + (0x0aac1, 0x0aac1,), # Tai Viet Tone Mai Tho ..Tai Viet Tone Mai Tho + (0x0aaec, 0x0aaed,), # Meetei Mayek Vowel Sign ..Meetei Mayek Vowel Sign + (0x0aaf6, 0x0aaf6,), # Meetei Mayek Virama ..Meetei Mayek Virama + (0x0abe5, 0x0abe5,), # Meetei Mayek Vowel Sign ..Meetei Mayek Vowel Sign + (0x0abe8, 0x0abe8,), # Meetei Mayek Vowel Sign ..Meetei Mayek Vowel Sign + (0x0abed, 0x0abed,), # Meetei Mayek Apun Iyek ..Meetei Mayek Apun Iyek + (0x0fb1e, 0x0fb1e,), # Hebrew Point Judeo-spani..Hebrew Point Judeo-spani + (0x0fe00, 0x0fe0f,), # Variation Selector-1 ..Variation Selector-16 + (0x0fe20, 0x0fe2f,), # Combining Ligature Left ..Combining Cyrillic Titlo + (0x101fd, 0x101fd,), # Phaistos Disc Sign Combi..Phaistos Disc Sign Combi + (0x102e0, 0x102e0,), # Coptic Epact Thousands M..Coptic Epact Thousands M + (0x10376, 0x1037a,), # Combining Old Permic Let..Combining Old Permic Let + (0x10a01, 0x10a03,), # Kharoshthi Vowel Sign I ..Kharoshthi Vowel Sign Vo + (0x10a05, 0x10a06,), # Kharoshthi Vowel Sign E ..Kharoshthi Vowel Sign O + (0x10a0c, 0x10a0f,), # Kharoshthi Vowel Length ..Kharoshthi Sign Visarga + (0x10a38, 0x10a3a,), # Kharoshthi Sign Bar Abov..Kharoshthi Sign Dot Belo + (0x10a3f, 0x10a3f,), # Kharoshthi Virama ..Kharoshthi Virama + (0x10ae5, 0x10ae6,), # Manichaean Abbreviation ..Manichaean Abbreviation + (0x10d24, 0x10d27,), # Hanifi Rohingya Sign Har..Hanifi Rohingya Sign Tas + (0x10f46, 0x10f50,), # Sogdian Combining Dot Be..Sogdian Combining Stroke + (0x11001, 0x11001,), # Brahmi Sign Anusvara ..Brahmi Sign Anusvara + (0x11038, 0x11046,), # Brahmi Vowel Sign Aa ..Brahmi Virama + (0x1107f, 0x11081,), # Brahmi Number Joiner ..Kaithi Sign Anusvara + (0x110b3, 0x110b6,), # Kaithi Vowel Sign U ..Kaithi Vowel Sign Ai + (0x110b9, 0x110ba,), # Kaithi Sign Virama ..Kaithi Sign Nukta + (0x11100, 0x11102,), # Chakma Sign Candrabindu ..Chakma Sign Visarga + (0x11127, 0x1112b,), # Chakma Vowel Sign A ..Chakma Vowel Sign Uu + (0x1112d, 0x11134,), # Chakma Vowel Sign Ai ..Chakma Maayyaa + (0x11173, 0x11173,), # Mahajani Sign Nukta ..Mahajani Sign Nukta + (0x11180, 0x11181,), # Sharada Sign Candrabindu..Sharada Sign Anusvara + (0x111b6, 0x111be,), # Sharada Vowel Sign U ..Sharada Vowel Sign O + (0x111c9, 0x111cc,), # Sharada Sandhi Mark ..Sharada Extra Short Vowe + (0x1122f, 0x11231,), # Khojki Vowel Sign U ..Khojki Vowel Sign Ai + (0x11234, 0x11234,), # Khojki Sign Anusvara ..Khojki Sign Anusvara + (0x11236, 0x11237,), # Khojki Sign Nukta ..Khojki Sign Shadda + (0x1123e, 0x1123e,), # Khojki Sign Sukun ..Khojki Sign Sukun + (0x112df, 0x112df,), # Khudawadi Sign Anusvara ..Khudawadi Sign Anusvara + (0x112e3, 0x112ea,), # Khudawadi Vowel Sign U ..Khudawadi Sign Virama + (0x11300, 0x11301,), # Grantha Sign Combining A..Grantha Sign Candrabindu + (0x1133b, 0x1133c,), # Combining Bindu Below ..Grantha Sign Nukta + (0x11340, 0x11340,), # Grantha Vowel Sign Ii ..Grantha Vowel Sign Ii + (0x11366, 0x1136c,), # Combining Grantha Digit ..Combining Grantha Digit + (0x11370, 0x11374,), # Combining Grantha Letter..Combining Grantha Letter + (0x11438, 0x1143f,), # Newa Vowel Sign U ..Newa Vowel Sign Ai + (0x11442, 0x11444,), # Newa Sign Virama ..Newa Sign Anusvara + (0x11446, 0x11446,), # Newa Sign Nukta ..Newa Sign Nukta + (0x1145e, 0x1145e,), # Newa Sandhi Mark ..Newa Sandhi Mark + (0x114b3, 0x114b8,), # Tirhuta Vowel Sign U ..Tirhuta Vowel Sign Vocal + (0x114ba, 0x114ba,), # Tirhuta Vowel Sign Short..Tirhuta Vowel Sign Short + (0x114bf, 0x114c0,), # Tirhuta Sign Candrabindu..Tirhuta Sign Anusvara + (0x114c2, 0x114c3,), # Tirhuta Sign Virama ..Tirhuta Sign Nukta + (0x115b2, 0x115b5,), # Siddham Vowel Sign U ..Siddham Vowel Sign Vocal + (0x115bc, 0x115bd,), # Siddham Sign Candrabindu..Siddham Sign Anusvara + (0x115bf, 0x115c0,), # Siddham Sign Virama ..Siddham Sign Nukta + (0x115dc, 0x115dd,), # Siddham Vowel Sign Alter..Siddham Vowel Sign Alter + (0x11633, 0x1163a,), # Modi Vowel Sign U ..Modi Vowel Sign Ai + (0x1163d, 0x1163d,), # Modi Sign Anusvara ..Modi Sign Anusvara + (0x1163f, 0x11640,), # Modi Sign Virama ..Modi Sign Ardhacandra + (0x116ab, 0x116ab,), # Takri Sign Anusvara ..Takri Sign Anusvara + (0x116ad, 0x116ad,), # Takri Vowel Sign Aa ..Takri Vowel Sign Aa + (0x116b0, 0x116b5,), # Takri Vowel Sign U ..Takri Vowel Sign Au + (0x116b7, 0x116b7,), # Takri Sign Nukta ..Takri Sign Nukta + (0x1171d, 0x1171f,), # Ahom Consonant Sign Medi..Ahom Consonant Sign Medi + (0x11722, 0x11725,), # Ahom Vowel Sign I ..Ahom Vowel Sign Uu + (0x11727, 0x1172b,), # Ahom Vowel Sign Aw ..Ahom Sign Killer + (0x1182f, 0x11837,), # Dogra Vowel Sign U ..Dogra Sign Anusvara + (0x11839, 0x1183a,), # Dogra Sign Virama ..Dogra Sign Nukta + (0x119d4, 0x119d7,), # Nandinagari Vowel Sign U..Nandinagari Vowel Sign V + (0x119da, 0x119db,), # Nandinagari Vowel Sign E..Nandinagari Vowel Sign A + (0x119e0, 0x119e0,), # Nandinagari Sign Virama ..Nandinagari Sign Virama + (0x11a01, 0x11a0a,), # Zanabazar Square Vowel S..Zanabazar Square Vowel L + (0x11a33, 0x11a38,), # Zanabazar Square Final C..Zanabazar Square Sign An + (0x11a3b, 0x11a3e,), # Zanabazar Square Cluster..Zanabazar Square Cluster + (0x11a47, 0x11a47,), # Zanabazar Square Subjoin..Zanabazar Square Subjoin + (0x11a51, 0x11a56,), # Soyombo Vowel Sign I ..Soyombo Vowel Sign Oe + (0x11a59, 0x11a5b,), # Soyombo Vowel Sign Vocal..Soyombo Vowel Length Mar + (0x11a8a, 0x11a96,), # Soyombo Final Consonant ..Soyombo Sign Anusvara + (0x11a98, 0x11a99,), # Soyombo Gemination Mark ..Soyombo Subjoiner + (0x11c30, 0x11c36,), # Bhaiksuki Vowel Sign I ..Bhaiksuki Vowel Sign Voc + (0x11c38, 0x11c3d,), # Bhaiksuki Vowel Sign E ..Bhaiksuki Sign Anusvara + (0x11c3f, 0x11c3f,), # Bhaiksuki Sign Virama ..Bhaiksuki Sign Virama + (0x11c92, 0x11ca7,), # Marchen Subjoined Letter..Marchen Subjoined Letter + (0x11caa, 0x11cb0,), # Marchen Subjoined Letter..Marchen Vowel Sign Aa + (0x11cb2, 0x11cb3,), # Marchen Vowel Sign U ..Marchen Vowel Sign E + (0x11cb5, 0x11cb6,), # Marchen Sign Anusvara ..Marchen Sign Candrabindu + (0x11d31, 0x11d36,), # Masaram Gondi Vowel Sign..Masaram Gondi Vowel Sign + (0x11d3a, 0x11d3a,), # Masaram Gondi Vowel Sign..Masaram Gondi Vowel Sign + (0x11d3c, 0x11d3d,), # Masaram Gondi Vowel Sign..Masaram Gondi Vowel Sign + (0x11d3f, 0x11d45,), # Masaram Gondi Vowel Sign..Masaram Gondi Virama + (0x11d47, 0x11d47,), # Masaram Gondi Ra-kara ..Masaram Gondi Ra-kara + (0x11d90, 0x11d91,), # Gunjala Gondi Vowel Sign..Gunjala Gondi Vowel Sign + (0x11d95, 0x11d95,), # Gunjala Gondi Sign Anusv..Gunjala Gondi Sign Anusv + (0x11d97, 0x11d97,), # Gunjala Gondi Virama ..Gunjala Gondi Virama + (0x11ef3, 0x11ef4,), # Makasar Vowel Sign I ..Makasar Vowel Sign U + (0x16af0, 0x16af4,), # Bassa Vah Combining High..Bassa Vah Combining High + (0x16b30, 0x16b36,), # Pahawh Hmong Mark Cim Tu..Pahawh Hmong Mark Cim Ta + (0x16f4f, 0x16f4f,), # Miao Sign Consonant Modi..Miao Sign Consonant Modi + (0x16f8f, 0x16f92,), # Miao Tone Right ..Miao Tone Below + (0x1bc9d, 0x1bc9e,), # Duployan Thick Letter Se..Duployan Double Mark + (0x1d167, 0x1d169,), # Musical Symbol Combining..Musical Symbol Combining + (0x1d17b, 0x1d182,), # Musical Symbol Combining..Musical Symbol Combining + (0x1d185, 0x1d18b,), # Musical Symbol Combining..Musical Symbol Combining + (0x1d1aa, 0x1d1ad,), # Musical Symbol Combining..Musical Symbol Combining + (0x1d242, 0x1d244,), # Combining Greek Musical ..Combining Greek Musical + (0x1da00, 0x1da36,), # Signwriting Head Rim ..Signwriting Air Sucking + (0x1da3b, 0x1da6c,), # Signwriting Mouth Closed..Signwriting Excitement + (0x1da75, 0x1da75,), # Signwriting Upper Body T..Signwriting Upper Body T + (0x1da84, 0x1da84,), # Signwriting Location Hea..Signwriting Location Hea + (0x1da9b, 0x1da9f,), # Signwriting Fill Modifie..Signwriting Fill Modifie + (0x1daa1, 0x1daaf,), # Signwriting Rotation Mod..Signwriting Rotation Mod + (0x1e000, 0x1e006,), # Combining Glagolitic Let..Combining Glagolitic Let + (0x1e008, 0x1e018,), # Combining Glagolitic Let..Combining Glagolitic Let + (0x1e01b, 0x1e021,), # Combining Glagolitic Let..Combining Glagolitic Let + (0x1e023, 0x1e024,), # Combining Glagolitic Let..Combining Glagolitic Let + (0x1e026, 0x1e02a,), # Combining Glagolitic Let..Combining Glagolitic Let + (0x1e130, 0x1e136,), # Nyiakeng Puachue Hmong T..Nyiakeng Puachue Hmong T + (0x1e2ec, 0x1e2ef,), # Wancho Tone Tup ..Wancho Tone Koini + (0x1e8d0, 0x1e8d6,), # Mende Kikakui Combining ..Mende Kikakui Combining + (0x1e944, 0x1e94a,), # Adlam Alif Lengthener ..Adlam Nukta + (0xe0100, 0xe01ef,), # Variation Selector-17 ..Variation Selector-256 + ), + '13.0.0': ( + # Source: DerivedGeneralCategory-13.0.0.txt + # Date: 2019-10-21, 14:30:32 GMT + # + (0x00300, 0x0036f,), # Combining Grave Accent ..Combining Latin Small Le + (0x00483, 0x00489,), # Combining Cyrillic Titlo..Combining Cyrillic Milli + (0x00591, 0x005bd,), # Hebrew Accent Etnahta ..Hebrew Point Meteg + (0x005bf, 0x005bf,), # Hebrew Point Rafe ..Hebrew Point Rafe + (0x005c1, 0x005c2,), # Hebrew Point Shin Dot ..Hebrew Point Sin Dot + (0x005c4, 0x005c5,), # Hebrew Mark Upper Dot ..Hebrew Mark Lower Dot + (0x005c7, 0x005c7,), # Hebrew Point Qamats Qata..Hebrew Point Qamats Qata + (0x00610, 0x0061a,), # Arabic Sign Sallallahou ..Arabic Small Kasra + (0x0064b, 0x0065f,), # Arabic Fathatan ..Arabic Wavy Hamza Below + (0x00670, 0x00670,), # Arabic Letter Superscrip..Arabic Letter Superscrip + (0x006d6, 0x006dc,), # Arabic Small High Ligatu..Arabic Small High Seen + (0x006df, 0x006e4,), # Arabic Small High Rounde..Arabic Small High Madda + (0x006e7, 0x006e8,), # Arabic Small High Yeh ..Arabic Small High Noon + (0x006ea, 0x006ed,), # Arabic Empty Centre Low ..Arabic Small Low Meem + (0x00711, 0x00711,), # Syriac Letter Superscrip..Syriac Letter Superscrip + (0x00730, 0x0074a,), # Syriac Pthaha Above ..Syriac Barrekh + (0x007a6, 0x007b0,), # Thaana Abafili ..Thaana Sukun + (0x007eb, 0x007f3,), # Nko Combining Short High..Nko Combining Double Dot + (0x007fd, 0x007fd,), # Nko Dantayalan ..Nko Dantayalan + (0x00816, 0x00819,), # Samaritan Mark In ..Samaritan Mark Dagesh + (0x0081b, 0x00823,), # Samaritan Mark Epentheti..Samaritan Vowel Sign A + (0x00825, 0x00827,), # Samaritan Vowel Sign Sho..Samaritan Vowel Sign U + (0x00829, 0x0082d,), # Samaritan Vowel Sign Lon..Samaritan Mark Nequdaa + (0x00859, 0x0085b,), # Mandaic Affrication Mark..Mandaic Gemination Mark + (0x008d3, 0x008e1,), # Arabic Small Low Waw ..Arabic Small High Sign S + (0x008e3, 0x00902,), # Arabic Turned Damma Belo..Devanagari Sign Anusvara + (0x0093a, 0x0093a,), # Devanagari Vowel Sign Oe..Devanagari Vowel Sign Oe + (0x0093c, 0x0093c,), # Devanagari Sign Nukta ..Devanagari Sign Nukta + (0x00941, 0x00948,), # Devanagari Vowel Sign U ..Devanagari Vowel Sign Ai + (0x0094d, 0x0094d,), # Devanagari Sign Virama ..Devanagari Sign Virama + (0x00951, 0x00957,), # Devanagari Stress Sign U..Devanagari Vowel Sign Uu + (0x00962, 0x00963,), # Devanagari Vowel Sign Vo..Devanagari Vowel Sign Vo + (0x00981, 0x00981,), # Bengali Sign Candrabindu..Bengali Sign Candrabindu + (0x009bc, 0x009bc,), # Bengali Sign Nukta ..Bengali Sign Nukta + (0x009c1, 0x009c4,), # Bengali Vowel Sign U ..Bengali Vowel Sign Vocal + (0x009cd, 0x009cd,), # Bengali Sign Virama ..Bengali Sign Virama + (0x009e2, 0x009e3,), # Bengali Vowel Sign Vocal..Bengali Vowel Sign Vocal + (0x009fe, 0x009fe,), # Bengali Sandhi Mark ..Bengali Sandhi Mark + (0x00a01, 0x00a02,), # Gurmukhi Sign Adak Bindi..Gurmukhi Sign Bindi + (0x00a3c, 0x00a3c,), # Gurmukhi Sign Nukta ..Gurmukhi Sign Nukta + (0x00a41, 0x00a42,), # Gurmukhi Vowel Sign U ..Gurmukhi Vowel Sign Uu + (0x00a47, 0x00a48,), # Gurmukhi Vowel Sign Ee ..Gurmukhi Vowel Sign Ai + (0x00a4b, 0x00a4d,), # Gurmukhi Vowel Sign Oo ..Gurmukhi Sign Virama + (0x00a51, 0x00a51,), # Gurmukhi Sign Udaat ..Gurmukhi Sign Udaat + (0x00a70, 0x00a71,), # Gurmukhi Tippi ..Gurmukhi Addak + (0x00a75, 0x00a75,), # Gurmukhi Sign Yakash ..Gurmukhi Sign Yakash + (0x00a81, 0x00a82,), # Gujarati Sign Candrabind..Gujarati Sign Anusvara + (0x00abc, 0x00abc,), # Gujarati Sign Nukta ..Gujarati Sign Nukta + (0x00ac1, 0x00ac5,), # Gujarati Vowel Sign U ..Gujarati Vowel Sign Cand + (0x00ac7, 0x00ac8,), # Gujarati Vowel Sign E ..Gujarati Vowel Sign Ai + (0x00acd, 0x00acd,), # Gujarati Sign Virama ..Gujarati Sign Virama + (0x00ae2, 0x00ae3,), # Gujarati Vowel Sign Voca..Gujarati Vowel Sign Voca + (0x00afa, 0x00aff,), # Gujarati Sign Sukun ..Gujarati Sign Two-circle + (0x00b01, 0x00b01,), # Oriya Sign Candrabindu ..Oriya Sign Candrabindu + (0x00b3c, 0x00b3c,), # Oriya Sign Nukta ..Oriya Sign Nukta + (0x00b3f, 0x00b3f,), # Oriya Vowel Sign I ..Oriya Vowel Sign I + (0x00b41, 0x00b44,), # Oriya Vowel Sign U ..Oriya Vowel Sign Vocalic + (0x00b4d, 0x00b4d,), # Oriya Sign Virama ..Oriya Sign Virama + (0x00b55, 0x00b56,), # (nil) ..Oriya Ai Length Mark + (0x00b62, 0x00b63,), # Oriya Vowel Sign Vocalic..Oriya Vowel Sign Vocalic + (0x00b82, 0x00b82,), # Tamil Sign Anusvara ..Tamil Sign Anusvara + (0x00bc0, 0x00bc0,), # Tamil Vowel Sign Ii ..Tamil Vowel Sign Ii + (0x00bcd, 0x00bcd,), # Tamil Sign Virama ..Tamil Sign Virama + (0x00c00, 0x00c00,), # Telugu Sign Combining Ca..Telugu Sign Combining Ca + (0x00c04, 0x00c04,), # Telugu Sign Combining An..Telugu Sign Combining An + (0x00c3e, 0x00c40,), # Telugu Vowel Sign Aa ..Telugu Vowel Sign Ii + (0x00c46, 0x00c48,), # Telugu Vowel Sign E ..Telugu Vowel Sign Ai + (0x00c4a, 0x00c4d,), # Telugu Vowel Sign O ..Telugu Sign Virama + (0x00c55, 0x00c56,), # Telugu Length Mark ..Telugu Ai Length Mark + (0x00c62, 0x00c63,), # Telugu Vowel Sign Vocali..Telugu Vowel Sign Vocali + (0x00c81, 0x00c81,), # Kannada Sign Candrabindu..Kannada Sign Candrabindu + (0x00cbc, 0x00cbc,), # Kannada Sign Nukta ..Kannada Sign Nukta + (0x00cbf, 0x00cbf,), # Kannada Vowel Sign I ..Kannada Vowel Sign I + (0x00cc6, 0x00cc6,), # Kannada Vowel Sign E ..Kannada Vowel Sign E + (0x00ccc, 0x00ccd,), # Kannada Vowel Sign Au ..Kannada Sign Virama + (0x00ce2, 0x00ce3,), # Kannada Vowel Sign Vocal..Kannada Vowel Sign Vocal + (0x00d00, 0x00d01,), # Malayalam Sign Combining..Malayalam Sign Candrabin + (0x00d3b, 0x00d3c,), # Malayalam Sign Vertical ..Malayalam Sign Circular + (0x00d41, 0x00d44,), # Malayalam Vowel Sign U ..Malayalam Vowel Sign Voc + (0x00d4d, 0x00d4d,), # Malayalam Sign Virama ..Malayalam Sign Virama + (0x00d62, 0x00d63,), # Malayalam Vowel Sign Voc..Malayalam Vowel Sign Voc + (0x00d81, 0x00d81,), # (nil) ..(nil) + (0x00dca, 0x00dca,), # Sinhala Sign Al-lakuna ..Sinhala Sign Al-lakuna + (0x00dd2, 0x00dd4,), # Sinhala Vowel Sign Ketti..Sinhala Vowel Sign Ketti + (0x00dd6, 0x00dd6,), # Sinhala Vowel Sign Diga ..Sinhala Vowel Sign Diga + (0x00e31, 0x00e31,), # Thai Character Mai Han-a..Thai Character Mai Han-a + (0x00e34, 0x00e3a,), # Thai Character Sara I ..Thai Character Phinthu + (0x00e47, 0x00e4e,), # Thai Character Maitaikhu..Thai Character Yamakkan + (0x00eb1, 0x00eb1,), # Lao Vowel Sign Mai Kan ..Lao Vowel Sign Mai Kan + (0x00eb4, 0x00ebc,), # Lao Vowel Sign I ..Lao Semivowel Sign Lo + (0x00ec8, 0x00ecd,), # Lao Tone Mai Ek ..Lao Niggahita + (0x00f18, 0x00f19,), # Tibetan Astrological Sig..Tibetan Astrological Sig + (0x00f35, 0x00f35,), # Tibetan Mark Ngas Bzung ..Tibetan Mark Ngas Bzung + (0x00f37, 0x00f37,), # Tibetan Mark Ngas Bzung ..Tibetan Mark Ngas Bzung + (0x00f39, 0x00f39,), # Tibetan Mark Tsa -phru ..Tibetan Mark Tsa -phru + (0x00f71, 0x00f7e,), # Tibetan Vowel Sign Aa ..Tibetan Sign Rjes Su Nga + (0x00f80, 0x00f84,), # Tibetan Vowel Sign Rever..Tibetan Mark Halanta + (0x00f86, 0x00f87,), # Tibetan Sign Lci Rtags ..Tibetan Sign Yang Rtags + (0x00f8d, 0x00f97,), # Tibetan Subjoined Sign L..Tibetan Subjoined Letter + (0x00f99, 0x00fbc,), # Tibetan Subjoined Letter..Tibetan Subjoined Letter + (0x00fc6, 0x00fc6,), # Tibetan Symbol Padma Gda..Tibetan Symbol Padma Gda + (0x0102d, 0x01030,), # Myanmar Vowel Sign I ..Myanmar Vowel Sign Uu + (0x01032, 0x01037,), # Myanmar Vowel Sign Ai ..Myanmar Sign Dot Below + (0x01039, 0x0103a,), # Myanmar Sign Virama ..Myanmar Sign Asat + (0x0103d, 0x0103e,), # Myanmar Consonant Sign M..Myanmar Consonant Sign M + (0x01058, 0x01059,), # Myanmar Vowel Sign Vocal..Myanmar Vowel Sign Vocal + (0x0105e, 0x01060,), # Myanmar Consonant Sign M..Myanmar Consonant Sign M + (0x01071, 0x01074,), # Myanmar Vowel Sign Geba ..Myanmar Vowel Sign Kayah + (0x01082, 0x01082,), # Myanmar Consonant Sign S..Myanmar Consonant Sign S + (0x01085, 0x01086,), # Myanmar Vowel Sign Shan ..Myanmar Vowel Sign Shan + (0x0108d, 0x0108d,), # Myanmar Sign Shan Counci..Myanmar Sign Shan Counci + (0x0109d, 0x0109d,), # Myanmar Vowel Sign Aiton..Myanmar Vowel Sign Aiton + (0x0135d, 0x0135f,), # Ethiopic Combining Gemin..Ethiopic Combining Gemin + (0x01712, 0x01714,), # Tagalog Vowel Sign I ..Tagalog Sign Virama + (0x01732, 0x01734,), # Hanunoo Vowel Sign I ..Hanunoo Sign Pamudpod + (0x01752, 0x01753,), # Buhid Vowel Sign I ..Buhid Vowel Sign U + (0x01772, 0x01773,), # Tagbanwa Vowel Sign I ..Tagbanwa Vowel Sign U + (0x017b4, 0x017b5,), # Khmer Vowel Inherent Aq ..Khmer Vowel Inherent Aa + (0x017b7, 0x017bd,), # Khmer Vowel Sign I ..Khmer Vowel Sign Ua + (0x017c6, 0x017c6,), # Khmer Sign Nikahit ..Khmer Sign Nikahit + (0x017c9, 0x017d3,), # Khmer Sign Muusikatoan ..Khmer Sign Bathamasat + (0x017dd, 0x017dd,), # Khmer Sign Atthacan ..Khmer Sign Atthacan + (0x0180b, 0x0180d,), # Mongolian Free Variation..Mongolian Free Variation + (0x01885, 0x01886,), # Mongolian Letter Ali Gal..Mongolian Letter Ali Gal + (0x018a9, 0x018a9,), # Mongolian Letter Ali Gal..Mongolian Letter Ali Gal + (0x01920, 0x01922,), # Limbu Vowel Sign A ..Limbu Vowel Sign U + (0x01927, 0x01928,), # Limbu Vowel Sign E ..Limbu Vowel Sign O + (0x01932, 0x01932,), # Limbu Small Letter Anusv..Limbu Small Letter Anusv + (0x01939, 0x0193b,), # Limbu Sign Mukphreng ..Limbu Sign Sa-i + (0x01a17, 0x01a18,), # Buginese Vowel Sign I ..Buginese Vowel Sign U + (0x01a1b, 0x01a1b,), # Buginese Vowel Sign Ae ..Buginese Vowel Sign Ae + (0x01a56, 0x01a56,), # Tai Tham Consonant Sign ..Tai Tham Consonant Sign + (0x01a58, 0x01a5e,), # Tai Tham Sign Mai Kang L..Tai Tham Consonant Sign + (0x01a60, 0x01a60,), # Tai Tham Sign Sakot ..Tai Tham Sign Sakot + (0x01a62, 0x01a62,), # Tai Tham Vowel Sign Mai ..Tai Tham Vowel Sign Mai + (0x01a65, 0x01a6c,), # Tai Tham Vowel Sign I ..Tai Tham Vowel Sign Oa B + (0x01a73, 0x01a7c,), # Tai Tham Vowel Sign Oa A..Tai Tham Sign Khuen-lue + (0x01a7f, 0x01a7f,), # Tai Tham Combining Crypt..Tai Tham Combining Crypt + (0x01ab0, 0x01ac0,), # Combining Doubled Circum..(nil) + (0x01b00, 0x01b03,), # Balinese Sign Ulu Ricem ..Balinese Sign Surang + (0x01b34, 0x01b34,), # Balinese Sign Rerekan ..Balinese Sign Rerekan + (0x01b36, 0x01b3a,), # Balinese Vowel Sign Ulu ..Balinese Vowel Sign Ra R + (0x01b3c, 0x01b3c,), # Balinese Vowel Sign La L..Balinese Vowel Sign La L + (0x01b42, 0x01b42,), # Balinese Vowel Sign Pepe..Balinese Vowel Sign Pepe + (0x01b6b, 0x01b73,), # Balinese Musical Symbol ..Balinese Musical Symbol + (0x01b80, 0x01b81,), # Sundanese Sign Panyecek ..Sundanese Sign Panglayar + (0x01ba2, 0x01ba5,), # Sundanese Consonant Sign..Sundanese Vowel Sign Pan + (0x01ba8, 0x01ba9,), # Sundanese Vowel Sign Pam..Sundanese Vowel Sign Pan + (0x01bab, 0x01bad,), # Sundanese Sign Virama ..Sundanese Consonant Sign + (0x01be6, 0x01be6,), # Batak Sign Tompi ..Batak Sign Tompi + (0x01be8, 0x01be9,), # Batak Vowel Sign Pakpak ..Batak Vowel Sign Ee + (0x01bed, 0x01bed,), # Batak Vowel Sign Karo O ..Batak Vowel Sign Karo O + (0x01bef, 0x01bf1,), # Batak Vowel Sign U For S..Batak Consonant Sign H + (0x01c2c, 0x01c33,), # Lepcha Vowel Sign E ..Lepcha Consonant Sign T + (0x01c36, 0x01c37,), # Lepcha Sign Ran ..Lepcha Sign Nukta + (0x01cd0, 0x01cd2,), # Vedic Tone Karshana ..Vedic Tone Prenkha + (0x01cd4, 0x01ce0,), # Vedic Sign Yajurvedic Mi..Vedic Tone Rigvedic Kash + (0x01ce2, 0x01ce8,), # Vedic Sign Visarga Svari..Vedic Sign Visarga Anuda + (0x01ced, 0x01ced,), # Vedic Sign Tiryak ..Vedic Sign Tiryak + (0x01cf4, 0x01cf4,), # Vedic Tone Candra Above ..Vedic Tone Candra Above + (0x01cf8, 0x01cf9,), # Vedic Tone Ring Above ..Vedic Tone Double Ring A + (0x01dc0, 0x01df9,), # Combining Dotted Grave A..Combining Wide Inverted + (0x01dfb, 0x01dff,), # Combining Deletion Mark ..Combining Right Arrowhea + (0x020d0, 0x020f0,), # Combining Left Harpoon A..Combining Asterisk Above + (0x02cef, 0x02cf1,), # Coptic Combining Ni Abov..Coptic Combining Spiritu + (0x02d7f, 0x02d7f,), # Tifinagh Consonant Joine..Tifinagh Consonant Joine + (0x02de0, 0x02dff,), # Combining Cyrillic Lette..Combining Cyrillic Lette + (0x0302a, 0x0302d,), # Ideographic Level Tone M..Ideographic Entering Ton + (0x03099, 0x0309a,), # Combining Katakana-hirag..Combining Katakana-hirag + (0x0a66f, 0x0a672,), # Combining Cyrillic Vzmet..Combining Cyrillic Thous + (0x0a674, 0x0a67d,), # Combining Cyrillic Lette..Combining Cyrillic Payer + (0x0a69e, 0x0a69f,), # Combining Cyrillic Lette..Combining Cyrillic Lette + (0x0a6f0, 0x0a6f1,), # Bamum Combining Mark Koq..Bamum Combining Mark Tuk + (0x0a802, 0x0a802,), # Syloti Nagri Sign Dvisva..Syloti Nagri Sign Dvisva + (0x0a806, 0x0a806,), # Syloti Nagri Sign Hasant..Syloti Nagri Sign Hasant + (0x0a80b, 0x0a80b,), # Syloti Nagri Sign Anusva..Syloti Nagri Sign Anusva + (0x0a825, 0x0a826,), # Syloti Nagri Vowel Sign ..Syloti Nagri Vowel Sign + (0x0a82c, 0x0a82c,), # (nil) ..(nil) + (0x0a8c4, 0x0a8c5,), # Saurashtra Sign Virama ..Saurashtra Sign Candrabi + (0x0a8e0, 0x0a8f1,), # Combining Devanagari Dig..Combining Devanagari Sig + (0x0a8ff, 0x0a8ff,), # Devanagari Vowel Sign Ay..Devanagari Vowel Sign Ay + (0x0a926, 0x0a92d,), # Kayah Li Vowel Ue ..Kayah Li Tone Calya Plop + (0x0a947, 0x0a951,), # Rejang Vowel Sign I ..Rejang Consonant Sign R + (0x0a980, 0x0a982,), # Javanese Sign Panyangga ..Javanese Sign Layar + (0x0a9b3, 0x0a9b3,), # Javanese Sign Cecak Telu..Javanese Sign Cecak Telu + (0x0a9b6, 0x0a9b9,), # Javanese Vowel Sign Wulu..Javanese Vowel Sign Suku + (0x0a9bc, 0x0a9bd,), # Javanese Vowel Sign Pepe..Javanese Consonant Sign + (0x0a9e5, 0x0a9e5,), # Myanmar Sign Shan Saw ..Myanmar Sign Shan Saw + (0x0aa29, 0x0aa2e,), # Cham Vowel Sign Aa ..Cham Vowel Sign Oe + (0x0aa31, 0x0aa32,), # Cham Vowel Sign Au ..Cham Vowel Sign Ue + (0x0aa35, 0x0aa36,), # Cham Consonant Sign La ..Cham Consonant Sign Wa + (0x0aa43, 0x0aa43,), # Cham Consonant Sign Fina..Cham Consonant Sign Fina + (0x0aa4c, 0x0aa4c,), # Cham Consonant Sign Fina..Cham Consonant Sign Fina + (0x0aa7c, 0x0aa7c,), # Myanmar Sign Tai Laing T..Myanmar Sign Tai Laing T + (0x0aab0, 0x0aab0,), # Tai Viet Mai Kang ..Tai Viet Mai Kang + (0x0aab2, 0x0aab4,), # Tai Viet Vowel I ..Tai Viet Vowel U + (0x0aab7, 0x0aab8,), # Tai Viet Mai Khit ..Tai Viet Vowel Ia + (0x0aabe, 0x0aabf,), # Tai Viet Vowel Am ..Tai Viet Tone Mai Ek + (0x0aac1, 0x0aac1,), # Tai Viet Tone Mai Tho ..Tai Viet Tone Mai Tho + (0x0aaec, 0x0aaed,), # Meetei Mayek Vowel Sign ..Meetei Mayek Vowel Sign + (0x0aaf6, 0x0aaf6,), # Meetei Mayek Virama ..Meetei Mayek Virama + (0x0abe5, 0x0abe5,), # Meetei Mayek Vowel Sign ..Meetei Mayek Vowel Sign + (0x0abe8, 0x0abe8,), # Meetei Mayek Vowel Sign ..Meetei Mayek Vowel Sign + (0x0abed, 0x0abed,), # Meetei Mayek Apun Iyek ..Meetei Mayek Apun Iyek + (0x0fb1e, 0x0fb1e,), # Hebrew Point Judeo-spani..Hebrew Point Judeo-spani + (0x0fe00, 0x0fe0f,), # Variation Selector-1 ..Variation Selector-16 + (0x0fe20, 0x0fe2f,), # Combining Ligature Left ..Combining Cyrillic Titlo + (0x101fd, 0x101fd,), # Phaistos Disc Sign Combi..Phaistos Disc Sign Combi + (0x102e0, 0x102e0,), # Coptic Epact Thousands M..Coptic Epact Thousands M + (0x10376, 0x1037a,), # Combining Old Permic Let..Combining Old Permic Let + (0x10a01, 0x10a03,), # Kharoshthi Vowel Sign I ..Kharoshthi Vowel Sign Vo + (0x10a05, 0x10a06,), # Kharoshthi Vowel Sign E ..Kharoshthi Vowel Sign O + (0x10a0c, 0x10a0f,), # Kharoshthi Vowel Length ..Kharoshthi Sign Visarga + (0x10a38, 0x10a3a,), # Kharoshthi Sign Bar Abov..Kharoshthi Sign Dot Belo + (0x10a3f, 0x10a3f,), # Kharoshthi Virama ..Kharoshthi Virama + (0x10ae5, 0x10ae6,), # Manichaean Abbreviation ..Manichaean Abbreviation + (0x10d24, 0x10d27,), # Hanifi Rohingya Sign Har..Hanifi Rohingya Sign Tas + (0x10eab, 0x10eac,), # (nil) ..(nil) + (0x10f46, 0x10f50,), # Sogdian Combining Dot Be..Sogdian Combining Stroke + (0x11001, 0x11001,), # Brahmi Sign Anusvara ..Brahmi Sign Anusvara + (0x11038, 0x11046,), # Brahmi Vowel Sign Aa ..Brahmi Virama + (0x1107f, 0x11081,), # Brahmi Number Joiner ..Kaithi Sign Anusvara + (0x110b3, 0x110b6,), # Kaithi Vowel Sign U ..Kaithi Vowel Sign Ai + (0x110b9, 0x110ba,), # Kaithi Sign Virama ..Kaithi Sign Nukta + (0x11100, 0x11102,), # Chakma Sign Candrabindu ..Chakma Sign Visarga + (0x11127, 0x1112b,), # Chakma Vowel Sign A ..Chakma Vowel Sign Uu + (0x1112d, 0x11134,), # Chakma Vowel Sign Ai ..Chakma Maayyaa + (0x11173, 0x11173,), # Mahajani Sign Nukta ..Mahajani Sign Nukta + (0x11180, 0x11181,), # Sharada Sign Candrabindu..Sharada Sign Anusvara + (0x111b6, 0x111be,), # Sharada Vowel Sign U ..Sharada Vowel Sign O + (0x111c9, 0x111cc,), # Sharada Sandhi Mark ..Sharada Extra Short Vowe + (0x111cf, 0x111cf,), # (nil) ..(nil) + (0x1122f, 0x11231,), # Khojki Vowel Sign U ..Khojki Vowel Sign Ai + (0x11234, 0x11234,), # Khojki Sign Anusvara ..Khojki Sign Anusvara + (0x11236, 0x11237,), # Khojki Sign Nukta ..Khojki Sign Shadda + (0x1123e, 0x1123e,), # Khojki Sign Sukun ..Khojki Sign Sukun + (0x112df, 0x112df,), # Khudawadi Sign Anusvara ..Khudawadi Sign Anusvara + (0x112e3, 0x112ea,), # Khudawadi Vowel Sign U ..Khudawadi Sign Virama + (0x11300, 0x11301,), # Grantha Sign Combining A..Grantha Sign Candrabindu + (0x1133b, 0x1133c,), # Combining Bindu Below ..Grantha Sign Nukta + (0x11340, 0x11340,), # Grantha Vowel Sign Ii ..Grantha Vowel Sign Ii + (0x11366, 0x1136c,), # Combining Grantha Digit ..Combining Grantha Digit + (0x11370, 0x11374,), # Combining Grantha Letter..Combining Grantha Letter + (0x11438, 0x1143f,), # Newa Vowel Sign U ..Newa Vowel Sign Ai + (0x11442, 0x11444,), # Newa Sign Virama ..Newa Sign Anusvara + (0x11446, 0x11446,), # Newa Sign Nukta ..Newa Sign Nukta + (0x1145e, 0x1145e,), # Newa Sandhi Mark ..Newa Sandhi Mark + (0x114b3, 0x114b8,), # Tirhuta Vowel Sign U ..Tirhuta Vowel Sign Vocal + (0x114ba, 0x114ba,), # Tirhuta Vowel Sign Short..Tirhuta Vowel Sign Short + (0x114bf, 0x114c0,), # Tirhuta Sign Candrabindu..Tirhuta Sign Anusvara + (0x114c2, 0x114c3,), # Tirhuta Sign Virama ..Tirhuta Sign Nukta + (0x115b2, 0x115b5,), # Siddham Vowel Sign U ..Siddham Vowel Sign Vocal + (0x115bc, 0x115bd,), # Siddham Sign Candrabindu..Siddham Sign Anusvara + (0x115bf, 0x115c0,), # Siddham Sign Virama ..Siddham Sign Nukta + (0x115dc, 0x115dd,), # Siddham Vowel Sign Alter..Siddham Vowel Sign Alter + (0x11633, 0x1163a,), # Modi Vowel Sign U ..Modi Vowel Sign Ai + (0x1163d, 0x1163d,), # Modi Sign Anusvara ..Modi Sign Anusvara + (0x1163f, 0x11640,), # Modi Sign Virama ..Modi Sign Ardhacandra + (0x116ab, 0x116ab,), # Takri Sign Anusvara ..Takri Sign Anusvara + (0x116ad, 0x116ad,), # Takri Vowel Sign Aa ..Takri Vowel Sign Aa + (0x116b0, 0x116b5,), # Takri Vowel Sign U ..Takri Vowel Sign Au + (0x116b7, 0x116b7,), # Takri Sign Nukta ..Takri Sign Nukta + (0x1171d, 0x1171f,), # Ahom Consonant Sign Medi..Ahom Consonant Sign Medi + (0x11722, 0x11725,), # Ahom Vowel Sign I ..Ahom Vowel Sign Uu + (0x11727, 0x1172b,), # Ahom Vowel Sign Aw ..Ahom Sign Killer + (0x1182f, 0x11837,), # Dogra Vowel Sign U ..Dogra Sign Anusvara + (0x11839, 0x1183a,), # Dogra Sign Virama ..Dogra Sign Nukta + (0x1193b, 0x1193c,), # (nil) ..(nil) + (0x1193e, 0x1193e,), # (nil) ..(nil) + (0x11943, 0x11943,), # (nil) ..(nil) + (0x119d4, 0x119d7,), # Nandinagari Vowel Sign U..Nandinagari Vowel Sign V + (0x119da, 0x119db,), # Nandinagari Vowel Sign E..Nandinagari Vowel Sign A + (0x119e0, 0x119e0,), # Nandinagari Sign Virama ..Nandinagari Sign Virama + (0x11a01, 0x11a0a,), # Zanabazar Square Vowel S..Zanabazar Square Vowel L + (0x11a33, 0x11a38,), # Zanabazar Square Final C..Zanabazar Square Sign An + (0x11a3b, 0x11a3e,), # Zanabazar Square Cluster..Zanabazar Square Cluster + (0x11a47, 0x11a47,), # Zanabazar Square Subjoin..Zanabazar Square Subjoin + (0x11a51, 0x11a56,), # Soyombo Vowel Sign I ..Soyombo Vowel Sign Oe + (0x11a59, 0x11a5b,), # Soyombo Vowel Sign Vocal..Soyombo Vowel Length Mar + (0x11a8a, 0x11a96,), # Soyombo Final Consonant ..Soyombo Sign Anusvara + (0x11a98, 0x11a99,), # Soyombo Gemination Mark ..Soyombo Subjoiner + (0x11c30, 0x11c36,), # Bhaiksuki Vowel Sign I ..Bhaiksuki Vowel Sign Voc + (0x11c38, 0x11c3d,), # Bhaiksuki Vowel Sign E ..Bhaiksuki Sign Anusvara + (0x11c3f, 0x11c3f,), # Bhaiksuki Sign Virama ..Bhaiksuki Sign Virama + (0x11c92, 0x11ca7,), # Marchen Subjoined Letter..Marchen Subjoined Letter + (0x11caa, 0x11cb0,), # Marchen Subjoined Letter..Marchen Vowel Sign Aa + (0x11cb2, 0x11cb3,), # Marchen Vowel Sign U ..Marchen Vowel Sign E + (0x11cb5, 0x11cb6,), # Marchen Sign Anusvara ..Marchen Sign Candrabindu + (0x11d31, 0x11d36,), # Masaram Gondi Vowel Sign..Masaram Gondi Vowel Sign + (0x11d3a, 0x11d3a,), # Masaram Gondi Vowel Sign..Masaram Gondi Vowel Sign + (0x11d3c, 0x11d3d,), # Masaram Gondi Vowel Sign..Masaram Gondi Vowel Sign + (0x11d3f, 0x11d45,), # Masaram Gondi Vowel Sign..Masaram Gondi Virama + (0x11d47, 0x11d47,), # Masaram Gondi Ra-kara ..Masaram Gondi Ra-kara + (0x11d90, 0x11d91,), # Gunjala Gondi Vowel Sign..Gunjala Gondi Vowel Sign + (0x11d95, 0x11d95,), # Gunjala Gondi Sign Anusv..Gunjala Gondi Sign Anusv + (0x11d97, 0x11d97,), # Gunjala Gondi Virama ..Gunjala Gondi Virama + (0x11ef3, 0x11ef4,), # Makasar Vowel Sign I ..Makasar Vowel Sign U + (0x16af0, 0x16af4,), # Bassa Vah Combining High..Bassa Vah Combining High + (0x16b30, 0x16b36,), # Pahawh Hmong Mark Cim Tu..Pahawh Hmong Mark Cim Ta + (0x16f4f, 0x16f4f,), # Miao Sign Consonant Modi..Miao Sign Consonant Modi + (0x16f8f, 0x16f92,), # Miao Tone Right ..Miao Tone Below + (0x16fe4, 0x16fe4,), # (nil) ..(nil) + (0x1bc9d, 0x1bc9e,), # Duployan Thick Letter Se..Duployan Double Mark + (0x1d167, 0x1d169,), # Musical Symbol Combining..Musical Symbol Combining + (0x1d17b, 0x1d182,), # Musical Symbol Combining..Musical Symbol Combining + (0x1d185, 0x1d18b,), # Musical Symbol Combining..Musical Symbol Combining + (0x1d1aa, 0x1d1ad,), # Musical Symbol Combining..Musical Symbol Combining + (0x1d242, 0x1d244,), # Combining Greek Musical ..Combining Greek Musical + (0x1da00, 0x1da36,), # Signwriting Head Rim ..Signwriting Air Sucking + (0x1da3b, 0x1da6c,), # Signwriting Mouth Closed..Signwriting Excitement + (0x1da75, 0x1da75,), # Signwriting Upper Body T..Signwriting Upper Body T + (0x1da84, 0x1da84,), # Signwriting Location Hea..Signwriting Location Hea + (0x1da9b, 0x1da9f,), # Signwriting Fill Modifie..Signwriting Fill Modifie + (0x1daa1, 0x1daaf,), # Signwriting Rotation Mod..Signwriting Rotation Mod + (0x1e000, 0x1e006,), # Combining Glagolitic Let..Combining Glagolitic Let + (0x1e008, 0x1e018,), # Combining Glagolitic Let..Combining Glagolitic Let + (0x1e01b, 0x1e021,), # Combining Glagolitic Let..Combining Glagolitic Let + (0x1e023, 0x1e024,), # Combining Glagolitic Let..Combining Glagolitic Let + (0x1e026, 0x1e02a,), # Combining Glagolitic Let..Combining Glagolitic Let + (0x1e130, 0x1e136,), # Nyiakeng Puachue Hmong T..Nyiakeng Puachue Hmong T + (0x1e2ec, 0x1e2ef,), # Wancho Tone Tup ..Wancho Tone Koini + (0x1e8d0, 0x1e8d6,), # Mende Kikakui Combining ..Mende Kikakui Combining + (0x1e944, 0x1e94a,), # Adlam Alif Lengthener ..Adlam Nukta + (0xe0100, 0xe01ef,), # Variation Selector-17 ..Variation Selector-256 + ), +} diff --git a/.venv/lib/python3.8/site-packages/wcwidth/tests/__init__.py b/.venv/lib/python3.8/site-packages/wcwidth/tests/__init__.py new file mode 100644 index 00000000..38130034 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/wcwidth/tests/__init__.py @@ -0,0 +1 @@ +"""This file intentionally left blank.""" diff --git a/.venv/lib/python3.8/site-packages/wcwidth/tests/__pycache__/__init__.cpython-38.pyc b/.venv/lib/python3.8/site-packages/wcwidth/tests/__pycache__/__init__.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d2053bf183138f27e46845713ad7577a7432033b GIT binary patch literal 196 zcmWIL<>g`kg8%i`;?J3N)(cE67#b4{4^PFvB$@!&M4u=4F<|$LkeT V-r}&y%}*)KNwovH>@yHE007XDHQN9H literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/wcwidth/tests/__pycache__/test_core.cpython-38.pyc b/.venv/lib/python3.8/site-packages/wcwidth/tests/__pycache__/test_core.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..dedc0a9c8aeaf7cb1912d9a7efafb34c867ea402 GIT binary patch literal 3087 zcmchZ%WoS+9LM+NM_x_(ptKa);TDV7iCaKWDpc1ojUl*E9zuk}X1g=VZnEB8W@j53 zIiMyzAoTze|3E8oAfj;L$bkb_4v0e!zC}Leio}IW`Tb_?#BrN)%i24$^PA^><~zUN zE({IzD{wvi>WNtxR+JVNx-Sh1*Wr$4Afd{lLRG4H>Y_?@YTQ>AHJYMn$aR{bS;!6A zNBbd9(E&OLd72K<6Od=tXZGSTchF@D-Keo2Mf4yIJz3JXzKC#*zaE!NzF!pT`Tfz-|VmlVMY{5A66M?Wi*IyyU zA`~1qlD(5v5(3^8D%x-}dTY^E%cYw-ETowdap`pu+fn!ktmfbM#zj3G58W^y`=Mp8 zF`8d@81wSp-OIjzhZe`%OBiC zFcJw4Vv-Yy07^j!B8q*13QJ%nTH&aKy$mF|Oz)N-=tBx3QGme_0ncL6hY5O{T#64u z*3_9#`4C!>B?tGDY?a(EeiECUk=#4)ZAS5JSn8`#6X6I-7V+Z-4C?$PC_e)qXD`DY zO+(Uw|6)fWQs6j}%}CtEHId$T7gPA0xQmVRwT0$a^> zwhWZ^VI)rnCuYB*2CXC|lody~2fUg(;Fr+&09K%qyYQTpc>LJ&OgXnXfg($!sduC~ zg3^2$>_^j?g4zz9M4ISCS3#C-7pgr3cPhY*9wPHjmm{5&jx>>Mu{>8LqvgOCJn%@w zK98AiGvfLnI!mx#VEJNU!?^I-L_KHhJ%y{6**REUZ70p2!-t=Rx}*8XzygO@F2uAa z+LU~@0xtCqGmF=udlxPPPO`-H3fPYg*Z7=U2L~w^3+JwW8$iLq>!?cl`nI;D>e;~UjlwRV$~$_w)qNXwPlJaHpz@cRyiy2N93Kw-Z>?i~WvgA4;;?PyS^dqClU zOVB0JjV4`CM>ns5{n+3v!er%7XRFiG)iNoUW~%e0X);}zpRdf4(jip)t)>=gle3jc zGCy@|VXjo0oFjA9n>D2O=eK`--36~$h>;Rnb6StbiWG(95)O#-L*NR>(Cu&>3?K& zwg*iFA0Ytd%Ok*C0(-8%nK4Zo*ru6;1pL5|flm5!j$TSeLyo%R$dY5ft}r13h76_I bYsvTZ`xwI`90>zw_H6b{c0~S$v%~)Zd-By^ literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/wcwidth/tests/test_core.py b/.venv/lib/python3.8/site-packages/wcwidth/tests/test_core.py new file mode 100644 index 00000000..13e2505a --- /dev/null +++ b/.venv/lib/python3.8/site-packages/wcwidth/tests/test_core.py @@ -0,0 +1,138 @@ +# coding: utf-8 +"""Core tests module for wcwidth.""" +import wcwidth + + +def test_hello_jp(): + u""" + Width of Japanese phrase: コンニãƒãƒ, セカイ! + + Given a phrase of 5 and 3 Katakana ideographs, joined with + 3 English-ASCII punctuation characters, totaling 11, this + phrase consumes 19 cells of a terminal emulator. + """ + # given, + phrase = u'コンニãƒãƒ, セカイ!' + expect_length_each = (2, 2, 2, 2, 2, 1, 1, 2, 2, 2, 1) + expect_length_phrase = sum(expect_length_each) + + # exercise, + length_each = tuple(map(wcwidth.wcwidth, phrase)) + length_phrase = wcwidth.wcswidth(phrase) + + # verify, + assert length_each == expect_length_each + assert length_phrase == expect_length_phrase + + +def test_wcswidth_substr(): + """ + Test wcswidth() optional 2nd parameter, ``n``. + + ``n`` determines at which position of the string + to stop counting length. + """ + # given, + phrase = u'コンニãƒãƒ, セカイ!' + end = 7 + expect_length_each = (2, 2, 2, 2, 2, 1, 1,) + expect_length_phrase = sum(expect_length_each) + + # exercise, + length_phrase = wcwidth.wcswidth(phrase, end) + + # verify, + assert length_phrase == expect_length_phrase + + +def test_null_width_0(): + """NULL (0) reports width 0.""" + # given, + phrase = u'abc\x00def' + expect_length_each = (1, 1, 1, 0, 1, 1, 1) + expect_length_phrase = sum(expect_length_each) + + # exercise, + length_each = tuple(map(wcwidth.wcwidth, phrase)) + length_phrase = wcwidth.wcswidth(phrase, len(phrase)) + + # verify, + assert length_each == expect_length_each + assert length_phrase == expect_length_phrase + + +def test_control_c0_width_negative_1(): + """CSI (Control sequence initiate) reports width -1.""" + # given, + phrase = u'\x1b[0m' + expect_length_each = (-1, 1, 1, 1) + expect_length_phrase = -1 + + # exercise, + length_each = tuple(map(wcwidth.wcwidth, phrase)) + length_phrase = wcwidth.wcswidth(phrase, len(phrase)) + + # verify, + assert length_each == expect_length_each + assert length_phrase == expect_length_phrase + + +def test_combining_width_negative_1(): + """Simple test combining reports total width of 4.""" + # given, + phrase = u'--\u05bf--' + expect_length_each = (1, 1, 0, 1, 1) + expect_length_phrase = 4 + + # exercise, + length_each = tuple(map(wcwidth.wcwidth, phrase)) + length_phrase = wcwidth.wcswidth(phrase, len(phrase)) + + # verify, + assert length_each == expect_length_each + assert length_phrase == expect_length_phrase + + +def test_combining_cafe(): + u"""Phrase cafe + COMBINING ACUTE ACCENT is café of length 4.""" + phrase = u"cafe\u0301" + expect_length_each = (1, 1, 1, 1, 0) + expect_length_phrase = 4 + + # exercise, + length_each = tuple(map(wcwidth.wcwidth, phrase)) + length_phrase = wcwidth.wcswidth(phrase, len(phrase)) + + # verify, + assert length_each == expect_length_each + assert length_phrase == expect_length_phrase + + +def test_combining_enclosing(): + u"""CYRILLIC CAPITAL LETTER A + COMBINING CYRILLIC HUNDRED THOUSANDS SIGN is ÐÒˆ of length 1.""" + phrase = u"\u0410\u0488" + expect_length_each = (1, 0) + expect_length_phrase = 1 + + # exercise, + length_each = tuple(map(wcwidth.wcwidth, phrase)) + length_phrase = wcwidth.wcswidth(phrase, len(phrase)) + + # verify, + assert length_each == expect_length_each + assert length_phrase == expect_length_phrase + + +def test_combining_spacing(): + u"""Balinese kapal (ship) is ᬓᬨᬮ᭄ of length 4.""" + phrase = u"\u1B13\u1B28\u1B2E\u1B44" + expect_length_each = (1, 1, 1, 1) + expect_length_phrase = 4 + + # exercise, + length_each = tuple(map(wcwidth.wcwidth, phrase)) + length_phrase = wcwidth.wcswidth(phrase, len(phrase)) + + # verify, + assert length_each == expect_length_each + assert length_phrase == expect_length_phrase diff --git a/.venv/lib/python3.8/site-packages/wcwidth/unicode_versions.py b/.venv/lib/python3.8/site-packages/wcwidth/unicode_versions.py new file mode 100644 index 00000000..9bf51eab --- /dev/null +++ b/.venv/lib/python3.8/site-packages/wcwidth/unicode_versions.py @@ -0,0 +1,35 @@ +""" +Exports function list_versions() for unicode version level support. + +This code generated by bin/update-tables.py on 2020-06-23 16:03:21.350604. +""" + + +def list_versions(): + """ + Return Unicode version levels supported by this module release. + + Any of the version strings returned may be used as keyword argument + ``unicode_version`` to the ``wcwidth()`` family of functions. + + :returns: Supported Unicode version numbers in ascending sorted order. + :rtype: list[str] + """ + return ( + "4.1.0", + "5.0.0", + "5.1.0", + "5.2.0", + "6.0.0", + "6.1.0", + "6.2.0", + "6.3.0", + "7.0.0", + "8.0.0", + "9.0.0", + "10.0.0", + "11.0.0", + "12.0.0", + "12.1.0", + "13.0.0", + ) diff --git a/.venv/lib/python3.8/site-packages/wcwidth/version.json b/.venv/lib/python3.8/site-packages/wcwidth/version.json new file mode 100644 index 00000000..59f1aa0e --- /dev/null +++ b/.venv/lib/python3.8/site-packages/wcwidth/version.json @@ -0,0 +1 @@ +{"tables": ["4.1.0", "5.0.0", "5.1.0", "5.2.0", "6.0.0", "6.1.0", "6.2.0", "6.3.0", "7.0.0", "8.0.0", "9.0.0", "10.0.0", "11.0.0", "12.0.0", "12.1.0", "13.0.0"], "package": "0.2.4", "default": "8.0.0"} diff --git a/.venv/lib/python3.8/site-packages/wcwidth/wcwidth.py b/.venv/lib/python3.8/site-packages/wcwidth/wcwidth.py new file mode 100644 index 00000000..931bd0b1 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/wcwidth/wcwidth.py @@ -0,0 +1,375 @@ +""" +This is a python implementation of wcwidth() and wcswidth(). + +https://github.com/jquast/wcwidth + +from Markus Kuhn's C code, retrieved from: + + http://www.cl.cam.ac.uk/~mgk25/ucs/wcwidth.c + +This is an implementation of wcwidth() and wcswidth() (defined in +IEEE Std 1002.1-2001) for Unicode. + +http://www.opengroup.org/onlinepubs/007904975/functions/wcwidth.html +http://www.opengroup.org/onlinepubs/007904975/functions/wcswidth.html + +In fixed-width output devices, Latin characters all occupy a single +"cell" position of equal width, whereas ideographic CJK characters +occupy two such cells. Interoperability between terminal-line +applications and (teletype-style) character terminals using the +UTF-8 encoding requires agreement on which character should advance +the cursor by how many cell positions. No established formal +standards exist at present on which Unicode character shall occupy +how many cell positions on character terminals. These routines are +a first attempt of defining such behavior based on simple rules +applied to data provided by the Unicode Consortium. + +For some graphical characters, the Unicode standard explicitly +defines a character-cell width via the definition of the East Asian +FullWidth (F), Wide (W), Half-width (H), and Narrow (Na) classes. +In all these cases, there is no ambiguity about which width a +terminal shall use. For characters in the East Asian Ambiguous (A) +class, the width choice depends purely on a preference of backward +compatibility with either historic CJK or Western practice. +Choosing single-width for these characters is easy to justify as +the appropriate long-term solution, as the CJK practice of +displaying these characters as double-width comes from historic +implementation simplicity (8-bit encoded characters were displayed +single-width and 16-bit ones double-width, even for Greek, +Cyrillic, etc.) and not any typographic considerations. + +Much less clear is the choice of width for the Not East Asian +(Neutral) class. Existing practice does not dictate a width for any +of these characters. It would nevertheless make sense +typographically to allocate two character cells to characters such +as for instance EM SPACE or VOLUME INTEGRAL, which cannot be +represented adequately with a single-width glyph. The following +routines at present merely assign a single-cell width to all +neutral characters, in the interest of simplicity. This is not +entirely satisfactory and should be reconsidered before +establishing a formal standard in this area. At the moment, the +decision which Not East Asian (Neutral) characters should be +represented by double-width glyphs cannot yet be answered by +applying a simple rule from the Unicode database content. Setting +up a proper standard for the behavior of UTF-8 character terminals +will require a careful analysis not only of each Unicode character, +but also of each presentation form, something the author of these +routines has avoided to do so far. + +http://www.unicode.org/unicode/reports/tr11/ + +Latest version: http://www.cl.cam.ac.uk/~mgk25/ucs/wcwidth.c +""" +from __future__ import division + +# std imports +import os +import sys +import warnings + +# local +from .table_wide import WIDE_EASTASIAN +from .table_zero import ZERO_WIDTH +from .unicode_versions import list_versions + +try: + from functools import lru_cache +except ImportError: + # lru_cache was added in Python 3.2 + from backports.functools_lru_cache import lru_cache + +# global cache +_UNICODE_CMPTABLE = None +_PY3 = (sys.version_info[0] >= 3) + + +# NOTE: created by hand, there isn't anything identifiable other than +# general Cf category code to identify these, and some characters in Cf +# category code are of non-zero width. +# Also includes some Cc, Mn, Zl, and Zp characters +ZERO_WIDTH_CF = set([ + 0, # Null (Cc) + 0x034F, # Combining grapheme joiner (Mn) + 0x200B, # Zero width space + 0x200C, # Zero width non-joiner + 0x200D, # Zero width joiner + 0x200E, # Left-to-right mark + 0x200F, # Right-to-left mark + 0x2028, # Line separator (Zl) + 0x2029, # Paragraph separator (Zp) + 0x202A, # Left-to-right embedding + 0x202B, # Right-to-left embedding + 0x202C, # Pop directional formatting + 0x202D, # Left-to-right override + 0x202E, # Right-to-left override + 0x2060, # Word joiner + 0x2061, # Function application + 0x2062, # Invisible times + 0x2063, # Invisible separator +]) + + +def _bisearch(ucs, table): + """ + Auxiliary function for binary search in interval table. + + :arg int ucs: Ordinal value of unicode character. + :arg list table: List of starting and ending ranges of ordinal values, + in form of ``[(start, end), ...]``. + :rtype: int + :returns: 1 if ordinal value ucs is found within lookup table, else 0. + """ + lbound = 0 + ubound = len(table) - 1 + + if ucs < table[0][0] or ucs > table[ubound][1]: + return 0 + while ubound >= lbound: + mid = (lbound + ubound) // 2 + if ucs > table[mid][1]: + lbound = mid + 1 + elif ucs < table[mid][0]: + ubound = mid - 1 + else: + return 1 + + return 0 + + +@lru_cache(maxsize=1000) +def wcwidth(wc, unicode_version='auto'): + r""" + Given one Unicode character, return its printable length on a terminal. + + :param str wc: A single Unicode character. + :param str unicode_version: A Unicode version number, such as + ``'6.0.0'``, the list of available version levels may be + listed by pairing function :func:`list_versions`. + + Any version string may be specified without error -- the nearest + matching version is selected. When ``latest`` (default), the + highest Unicode version level is used. + :return: The width, in cells, necessary to display the character of + Unicode string character, ``wc``. Returns 0 if the ``wc`` argument has + no printable effect on a terminal (such as NUL '\0'), -1 if ``wc`` is + not printable, or has an indeterminate effect on the terminal, such as + a control character. Otherwise, the number of column positions the + character occupies on a graphic terminal (1 or 2) is returned. + :rtype: int + + The following have a column width of -1: + + - C0 control characters (U+001 through U+01F). + + - C1 control characters and DEL (U+07F through U+0A0). + + The following have a column width of 0: + + - Non-spacing and enclosing combining characters (general + category code Mn or Me in the Unicode database). + + - NULL (``U+0000``). + + - COMBINING GRAPHEME JOINER (``U+034F``). + + - ZERO WIDTH SPACE (``U+200B``) *through* + RIGHT-TO-LEFT MARK (``U+200F``). + + - LINE SEPARATOR (``U+2028``) *and* + PARAGRAPH SEPARATOR (``U+2029``). + + - LEFT-TO-RIGHT EMBEDDING (``U+202A``) *through* + RIGHT-TO-LEFT OVERRIDE (``U+202E``). + + - WORD JOINER (``U+2060``) *through* + INVISIBLE SEPARATOR (``U+2063``). + + The following have a column width of 1: + + - SOFT HYPHEN (``U+00AD``). + + - All remaining characters, including all printable ISO 8859-1 + and WGL4 characters, Unicode control characters, etc. + + The following have a column width of 2: + + - Spacing characters in the East Asian Wide (W) or East Asian + Full-width (F) category as defined in Unicode Technical + Report #11 have a column width of 2. + + - Some kinds of Emoji or symbols. + """ + # NOTE: created by hand, there isn't anything identifiable other than + # general Cf category code to identify these, and some characters in Cf + # category code are of non-zero width. + ucs = ord(wc) + if ucs in ZERO_WIDTH_CF: + return 0 + + # C0/C1 control characters + if ucs < 32 or 0x07F <= ucs < 0x0A0: + return -1 + + _unicode_version = _wcmatch_version(unicode_version) + + # combining characters with zero width + if _bisearch(ucs, ZERO_WIDTH[_unicode_version]): + return 0 + + return 1 + _bisearch(ucs, WIDE_EASTASIAN[_unicode_version]) + + +def wcswidth(pwcs, n=None, unicode_version='auto'): + """ + Given a unicode string, return its printable length on a terminal. + + :param str pwcs: Measure width of given unicode string. + :param int n: When ``n`` is None (default), return the length of the + entire string, otherwise width the first ``n`` characters specified. + :param str unicode_version: An explicit definition of the unicode version + level to use for determination, may be ``auto`` (default), which uses + the Environment Variable, ``UNICODE_VERSION`` if defined, or the latest + available unicode version, otherwise. + :rtype: int + :returns: The width, in cells, necessary to display the first ``n`` + characters of the unicode string ``pwcs``. Returns ``-1`` if + a non-printable character is encountered. + """ + # pylint: disable=C0103 + # Invalid argument name "n" + + end = len(pwcs) if n is None else n + idx = slice(0, end) + width = 0 + for char in pwcs[idx]: + wcw = wcwidth(char, unicode_version) + if wcw < 0: + return -1 + width += wcw + return width + + +@lru_cache(maxsize=128) +def _wcversion_value(ver_string): + """ + Integer-mapped value of given dotted version string. + + :param str ver_string: Unicode version string, of form ``n.n.n``. + :rtype: tuple(int) + :returns: tuple of digit tuples, ``tuple(int, [...])``. + """ + retval = tuple(map(int, (ver_string.split('.')))) + return retval + + +@lru_cache(maxsize=8) +def _wcmatch_version(given_version): + """ + Return nearest matching supported Unicode version level. + + If an exact match is not determined, the nearest lowest version level is + returned after a warning is emitted. For example, given supported levels + ``4.1.0`` and ``5.0.0``, and a version string of ``4.9.9``, then ``4.1.0`` + is selected and returned: + + >>> _wcmatch_version('4.9.9') + '4.1.0' + >>> _wcmatch_version('8.0') + '8.0.0' + >>> _wcmatch_version('1') + '4.1.0' + + :param str given_version: given version for compare, may be ``auto`` + (default), to select Unicode Version from Environment Variable, + ``UNICODE_VERSION``. If the environment variable is not set, then the + latest is used. + :rtype: str + :returns: unicode string, or non-unicode ``str`` type for python 2 + when given ``version`` is also type ``str``. + """ + # Design note: the choice to return the same type that is given certainly + # complicates it for python 2 str-type, but allows us to define an api that + # to use 'string-type', for unicode version level definitions, so all of our + # example code works with all versions of python. That, along with the + # string-to-numeric and comparisons of earliest, latest, matching, or + # nearest, greatly complicates this function. + _return_str = not _PY3 and isinstance(given_version, str) + + if _return_str: + unicode_versions = [ucs.encode() for ucs in list_versions()] + else: + unicode_versions = list_versions() + latest_version = unicode_versions[-1] + + if given_version in (u'auto', 'auto'): + given_version = os.environ.get( + 'UNICODE_VERSION', + 'latest' if not _return_str else latest_version.encode()) + + if given_version in (u'latest', 'latest'): + # default match, when given as 'latest', use the most latest unicode + # version specification level supported. + return latest_version if not _return_str else latest_version.encode() + + if given_version in unicode_versions: + # exact match, downstream has specified an explicit matching version + # matching any value of list_versions(). + return given_version if not _return_str else given_version.encode() + + # The user's version is not supported by ours. We return the newest unicode + # version level that we support below their given value. + try: + cmp_given = _wcversion_value(given_version) + + except ValueError: + # submitted value raises ValueError in int(), warn and use latest. + warnings.warn("UNICODE_VERSION value, {given_version!r}, is invalid. " + "Value should be in form of `integer[.]+', the latest " + "supported unicode version {latest_version!r} has been " + "inferred.".format(given_version=given_version, + latest_version=latest_version)) + return latest_version if not _return_str else latest_version.encode() + + # given version is less than any available version, return earliest + # version. + earliest_version = unicode_versions[0] + cmp_earliest_version = _wcversion_value(earliest_version) + + if cmp_given <= cmp_earliest_version: + # this probably isn't what you wanted, the oldest wcwidth.c you will + # find in the wild is likely version 5 or 6, which we both support, + # but it's better than not saying anything at all. + warnings.warn("UNICODE_VERSION value, {given_version!r}, is lower " + "than any available unicode version. Returning lowest " + "version level, {earliest_version!r}".format( + given_version=given_version, + earliest_version=earliest_version)) + return earliest_version if not _return_str else earliest_version.encode() + + # create list of versions which are less than our equal to given version, + # and return the tail value, which is the highest level we may support, + # or the latest value we support, when completely unmatched or higher + # than any supported version. + # + # function will never complete, always returns. + for idx, unicode_version in enumerate(unicode_versions): + # look ahead to next value + try: + cmp_next_version = _wcversion_value(unicode_versions[idx + 1]) + except IndexError: + # at end of list, return latest version + return latest_version if not _return_str else latest_version.encode() + + # Maybe our given version has less parts, as in tuple(8, 0), than the + # next compare version tuple(8, 0, 0). Test for an exact match by + # comparison of only the leading dotted piece(s): (8, 0) == (8, 0). + if cmp_given == cmp_next_version[:len(cmp_given)]: + return unicode_versions[idx + 1] + + # Or, if any next value is greater than our given support level + # version, return the current value in index. Even though it must + # be less than the given value, its our closest possible match. That + # is, 4.1 is returned for given 4.9.9, where 4.1 and 5.0 are available. + if cmp_next_version > cmp_given: + return unicode_version + assert False, ("Code path unreachable", given_version, unicode_versions) diff --git a/.venv/lib/python3.8/site-packages/wrapt-1.12.1.dist-info/INSTALLER b/.venv/lib/python3.8/site-packages/wrapt-1.12.1.dist-info/INSTALLER new file mode 100644 index 00000000..a1b589e3 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/wrapt-1.12.1.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/.venv/lib/python3.8/site-packages/wrapt-1.12.1.dist-info/LICENSE b/.venv/lib/python3.8/site-packages/wrapt-1.12.1.dist-info/LICENSE new file mode 100644 index 00000000..d49cae84 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/wrapt-1.12.1.dist-info/LICENSE @@ -0,0 +1,24 @@ +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/.venv/lib/python3.8/site-packages/wrapt-1.12.1.dist-info/METADATA b/.venv/lib/python3.8/site-packages/wrapt-1.12.1.dist-info/METADATA new file mode 100644 index 00000000..34b78a03 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/wrapt-1.12.1.dist-info/METADATA @@ -0,0 +1,169 @@ +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/.venv/lib/python3.8/site-packages/wrapt-1.12.1.dist-info/RECORD b/.venv/lib/python3.8/site-packages/wrapt-1.12.1.dist-info/RECORD new file mode 100644 index 00000000..d433ee08 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/wrapt-1.12.1.dist-info/RECORD @@ -0,0 +1,15 @@ +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=f-3VpXONs2_lTz1GiPTEamT5iNuhRnn-mcqYB4WqvGc,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/.venv/lib/python3.8/site-packages/wrapt-1.12.1.dist-info/WHEEL b/.venv/lib/python3.8/site-packages/wrapt-1.12.1.dist-info/WHEEL new file mode 100644 index 00000000..d193dea9 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/wrapt-1.12.1.dist-info/WHEEL @@ -0,0 +1,5 @@ +Wheel-Version: 1.0 +Generator: bdist_wheel (0.34.2) +Root-Is-Purelib: false +Tag: cp38-cp38-linux_x86_64 + diff --git a/.venv/lib/python3.8/site-packages/wrapt-1.12.1.dist-info/top_level.txt b/.venv/lib/python3.8/site-packages/wrapt-1.12.1.dist-info/top_level.txt new file mode 100644 index 00000000..ba11553a --- /dev/null +++ b/.venv/lib/python3.8/site-packages/wrapt-1.12.1.dist-info/top_level.txt @@ -0,0 +1 @@ +wrapt diff --git a/.venv/lib/python3.8/site-packages/wrapt/__init__.py b/.venv/lib/python3.8/site-packages/wrapt/__init__.py new file mode 100644 index 00000000..7be739bf --- /dev/null +++ b/.venv/lib/python3.8/site-packages/wrapt/__init__.py @@ -0,0 +1,16 @@ +__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/.venv/lib/python3.8/site-packages/wrapt/__pycache__/__init__.cpython-38.pyc b/.venv/lib/python3.8/site-packages/wrapt/__pycache__/__init__.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c48ef1045d5cb868d2defe983450b2a90ce78818 GIT binary patch literal 953 zcmZva&2AGh5XX0uO|r@6v-xO}0taq6v{4HO4hR*HdW1>{Rr1Ah*G}WsUTuW;vX1Jqff}-jnzDsj zvW?oZgF0d0<0G*lyQnLBs3-fVF9&FFqnE^{9HOBdp^+S;vD`viUN6&%cpx95hkhNu z3ntY`(S^IHu)C*2U!4nguHidry5#NgDNF64R#!{ceNBWQ$AaA!TL+6QwOnOKn&dgt zuJ=kUGWx&TIb!7OkGM)VJ|x<5BJRst*UTt!!EjFO+$BD#-;xeRyTFI{w)I& zYc)S!SmxTZbx|1nP}OSV9eHq*6W`ItR+G$dmf1VLN#t6DlH4+lXC$>sFJ1HHN;p{C zRmxJOiTAm>S!U^6tBikO)W?oAJK+X`b7d^%GFRH-xl(7YaXDw%T4B`nGG+N}iKU_o z!LU$-dUZ^>N!7(Y@#fl}SuhD*a>8s1N2O29o5>^B#@O#S{){lsW(s2$ohqKWVO8I31|V@fQ|>M{T+eP8=!UpJwV^X#jDPl)&tNs z0YktDycM3A++RGs<*jdlehePKuf3_2`84PG_9DwkddBFs9~%?f=T}copPoO(BZ4UC literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/wrapt/__pycache__/decorators.cpython-38.pyc b/.venv/lib/python3.8/site-packages/wrapt/__pycache__/decorators.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c1139830effc526b7ac028003e6387c10603ad62 GIT binary patch literal 9225 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 literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/wrapt/__pycache__/importer.cpython-38.pyc b/.venv/lib/python3.8/site-packages/wrapt/__pycache__/importer.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ae0109e71c0a24f4352a44abd8ba7c182eb02feb GIT binary patch literal 4233 zcmb7H?{6DP8J?M4+v~OCr0MTcsOc5%T&R1rz0y0%smEOlNT;Zx2Y0nVE5|cV)^T>7 znF%G<8a|{F_W@3P0wfSh4hgA$2NHh*Li>^X)PLbV@w~H6oHQvMw&vZL*>`7W-sgFL z?2qT>LWbYpfA!DkUteMDGa4NHc^KS7Gyi~)tivRiV#qt(T}4MIKJX+z&!o2|I==FC zTb25}Q%)LAqtdCUfX337rD1hF?1Y@ftW%TaZe59;xn0(2$chY}vd+8;Rb!jWstlj9 zZQfasHCe~}2{|VlxGqlb&&vgO|K#_XJRujKGP$@dI;Su?DNkW^3Zv5)ot9@XI)l*} zc~+jo3TLHw#9HUafB0ZEHqG@^ZVpv5ULOtBx=O5RcAKNrSei+-ZLX&2T610XR=Y`T z)|3A9QangKv|KYWpx8H0xmr|>m)~VR0OqEGqwas2S zQq3o^U7fzzG?!JJtTeS6rd_FII}D%0$ZYAkfPBs&T0F0tt)#cA(nnD`rQ^Z=84&FB2BoVQ!0ykthh*ydpr6-JDr+%sDy zuN1~cXGPhrwYpW#%f(z?E3Q$}T~~R~-%NToPLsSuY9!a(Vcyw(u89_nGYfn~{8eZG@#m&L3jXR_3Pjq)=uNON}x;@&;YtwBJwqGMN zG$0sn@Q??t)%o~V)YGbK)!q?EH|pzjJu+4UvG(0zicOif+XoiYr?5^-XtJ$7LxLvs zB8k%w`KAA{>J=y%LWl8spwHskBY^jQbcfozXl4h(vW!{2E%c%lgu{ec&s>$f>sfzL z+9^w6E8A>W0L5UZnsJFfVJz8Npfz;D{aG*bFk99A73gOCE>_Mw!hhq>8C&7STyixN zD{M{ZPv}|43U5y@X^_r&wo}X4E}oO@5qst>eV`qQ>v8VY&}l za>j=jt%dqBXY_yUxcd>y_yArd#cw%Gdu}4E2g6ciL?q0_01*)0@jCGwLAIbd&r2&h z-5epZ&5hPpBCSlise8)gwSunqwN7<@A|_rryMSG=uW?&;d~w8V`MQN&>Z>H2VH_|H zg?%XU3o67CIDD$Tr*Fgj>ENW>G`m zMr=SNgUXQB-~^K##)VV`o?a7an& z*x*v5gG~?lJ3MA6Ei+0!V*KSJ+iM@tUVs}W{`W9{xUG2t+lE)a7-nMU0iW(G`BIjg< z5qVyw6Dp0|c?0+L9TG1v1I(g)5Ji8)O?Lvu$6tNf2HJbtN1!Em9kl1r$=HDH09+J2 z$AarN;_OM_>Ti)ayf0_%KVg0fVVxkn^3rV`LbBwL)NjzLw@JK7!o6K#`%2y?n*RB+QiZp_voSdSfQTQJY43xGHp%%khhf%A= zNi@>w3Zk58@dCQp#@(LjM1Muw1MK|F^@^;$57bhRklFi{&>_!qNc{z!j9a!=(RB(m z#Ge6QE9(n1l5Rv{X*{q(-$j@%@}s}aK4hQ%r!hhzWgh38PspLOqi9jOo^>1uF^S6;KJ}p1Os&5c;z?<)~j|v_WnObv2 zw4*4Rdk-JqC{iwYUEYXYwK9yC+nY8X=Dw5FJ}Q^Uj8w0n{5PEHJ1BAEe*7ojiE3q%+S zlwAcyl|Ci7j~ONJ4D6XkAeVZ}z1|&;tLSEnfHZ1B_bd@=6rRw1=2ZzK~b#Dn3diK0oq0vcAC= z5@KRM)!(7J;d0lgqOjH%FrmLkvmRzT_(bicx@%KyG=Wp_^h`>r5Pk_Iv1m+lc3IQ|Dwl(5P%HEBHm>uy M&NqTat?|x(0BW3~R{#J2 literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/wrapt/__pycache__/wrappers.cpython-38.pyc b/.venv/lib/python3.8/site-packages/wrapt/__pycache__/wrappers.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..495d9a01aafb9d3b45f02a8695784e62a12d93a6 GIT binary patch literal 24358 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 literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/wrapt/_wrappers.cpython-38-x86_64-linux-gnu.so b/.venv/lib/python3.8/site-packages/wrapt/_wrappers.cpython-38-x86_64-linux-gnu.so new file mode 100755 index 0000000000000000000000000000000000000000..37d88d13d6484229f71d504e3d6766e9b84ebb9f GIT binary patch literal 198056 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 UUw#d*(Em>_c>k4wL(onB4^jtGwg3PC literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/wrapt/decorators.py b/.venv/lib/python3.8/site-packages/wrapt/decorators.py new file mode 100644 index 00000000..506303d7 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/wrapt/decorators.py @@ -0,0 +1,516 @@ +"""This module implements decorators for implementing other decorators +as well as some commonly used decorators. + +""" + +import sys + +PY2 = sys.version_info[0] == 2 + +if PY2: + string_types = basestring, + + 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_""") + +else: + string_types = str, + + import builtins + + exec_ = getattr(builtins, "exec") + del builtins + +from functools import partial +from inspect import ismethod, isclass, formatargspec +from collections import namedtuple +from threading import Lock, RLock + +try: + from inspect import signature +except ImportError: + pass + +from .wrappers import (FunctionWrapper, BoundFunctionWrapper, ObjectProxy, + CallableObjectProxy) + +# Adapter wrapper for the wrapped function which will overlay certain +# properties from the adapter function onto the wrapped function so that +# functions such as inspect.getargspec(), inspect.getfullargspec(), +# inspect.signature() and inspect.getsource() return the correct results +# one would expect. + +class _AdapterFunctionCode(CallableObjectProxy): + + def __init__(self, wrapped_code, adapter_code): + super(_AdapterFunctionCode, self).__init__(wrapped_code) + self._self_adapter_code = adapter_code + + @property + def co_argcount(self): + return self._self_adapter_code.co_argcount + + @property + def co_code(self): + return self._self_adapter_code.co_code + + @property + def co_flags(self): + return self._self_adapter_code.co_flags + + @property + def co_kwonlyargcount(self): + return self._self_adapter_code.co_kwonlyargcount + + @property + def co_varnames(self): + return self._self_adapter_code.co_varnames + +class _AdapterFunctionSurrogate(CallableObjectProxy): + + def __init__(self, wrapped, adapter): + super(_AdapterFunctionSurrogate, self).__init__(wrapped) + self._self_adapter = adapter + + @property + def __code__(self): + return _AdapterFunctionCode(self.__wrapped__.__code__, + self._self_adapter.__code__) + + @property + def __defaults__(self): + return self._self_adapter.__defaults__ + + @property + def __kwdefaults__(self): + return self._self_adapter.__kwdefaults__ + + @property + def __signature__(self): + if 'signature' not in globals(): + return self._self_adapter.__signature__ + else: + return signature(self._self_adapter) + + if PY2: + func_code = __code__ + func_defaults = __defaults__ + +class _BoundAdapterWrapper(BoundFunctionWrapper): + + @property + def __func__(self): + return _AdapterFunctionSurrogate(self.__wrapped__.__func__, + self._self_parent._self_adapter) + + @property + def __signature__(self): + if 'signature' not in globals(): + return self.__wrapped__.__signature__ + else: + return signature(self._self_parent._self_adapter) + + if PY2: + im_func = __func__ + +class AdapterWrapper(FunctionWrapper): + + __bound_function_wrapper__ = _BoundAdapterWrapper + + def __init__(self, *args, **kwargs): + adapter = kwargs.pop('adapter') + super(AdapterWrapper, self).__init__(*args, **kwargs) + self._self_surrogate = _AdapterFunctionSurrogate( + self.__wrapped__, adapter) + self._self_adapter = adapter + + @property + def __code__(self): + return self._self_surrogate.__code__ + + @property + def __defaults__(self): + return self._self_surrogate.__defaults__ + + @property + def __kwdefaults__(self): + return self._self_surrogate.__kwdefaults__ + + if PY2: + func_code = __code__ + func_defaults = __defaults__ + + @property + def __signature__(self): + return self._self_surrogate.__signature__ + +class AdapterFactory(object): + def __call__(self, wrapped): + raise NotImplementedError() + +class DelegatedAdapterFactory(AdapterFactory): + def __init__(self, factory): + super(DelegatedAdapterFactory, self).__init__() + self.factory = factory + def __call__(self, wrapped): + return self.factory(wrapped) + +adapter_factory = DelegatedAdapterFactory + +# Decorator for creating other decorators. This decorator and the +# wrappers which they use are designed to properly preserve any name +# attributes, function signatures etc, in addition to the wrappers +# themselves acting like a transparent proxy for the original wrapped +# function so the wrapper is effectively indistinguishable from the +# original wrapped function. + +def decorator(wrapper=None, enabled=None, adapter=None): + # The decorator should be supplied with a single positional argument + # which is the wrapper function to be used to implement the + # decorator. This may be preceded by a step whereby the keyword + # arguments are supplied to customise the behaviour of the + # decorator. The 'adapter' argument is used to optionally denote a + # separate function which is notionally used by an adapter + # decorator. In that case parts of the function '__code__' and + # '__defaults__' attributes are used from the adapter function + # rather than those of the wrapped function. This allows for the + # argument specification from inspect.getargspec() and similar + # functions to be overridden with a prototype for a different + # function than what was wrapped. The 'enabled' argument provides a + # way to enable/disable the use of the decorator. If the type of + # 'enabled' is a boolean, then it is evaluated immediately and the + # wrapper not even applied if it is False. If not a boolean, it will + # be evaluated when the wrapper is called for an unbound wrapper, + # and when binding occurs for a bound wrapper. When being evaluated, + # if 'enabled' is callable it will be called to obtain the value to + # be checked. If False, the wrapper will not be called and instead + # the original wrapped function will be called directly instead. + + if wrapper is not None: + # Helper function for creating wrapper of the appropriate + # time when we need it down below. + + def _build(wrapped, wrapper, enabled=None, adapter=None): + if adapter: + if isinstance(adapter, AdapterFactory): + adapter = adapter(wrapped) + + if not callable(adapter): + ns = {} + if not isinstance(adapter, string_types): + adapter = formatargspec(*adapter) + exec_('def adapter{}: pass'.format(adapter), ns, ns) + adapter = ns['adapter'] + + return AdapterWrapper(wrapped=wrapped, wrapper=wrapper, + enabled=enabled, adapter=adapter) + + return FunctionWrapper(wrapped=wrapped, wrapper=wrapper, + enabled=enabled) + + # The wrapper has been provided so return the final decorator. + # The decorator is itself one of our function wrappers so we + # can determine when it is applied to functions, instance methods + # or class methods. This allows us to bind the instance or class + # method so the appropriate self or cls attribute is supplied + # when it is finally called. + + def _wrapper(wrapped, instance, args, kwargs): + # We first check for the case where the decorator was applied + # to a class type. + # + # @decorator + # class mydecoratorclass(object): + # def __init__(self, arg=None): + # self.arg = arg + # def __call__(self, wrapped, instance, args, kwargs): + # return wrapped(*args, **kwargs) + # + # @mydecoratorclass(arg=1) + # def function(): + # pass + # + # In this case an instance of the class is to be used as the + # decorator wrapper function. If args was empty at this point, + # then it means that there were optional keyword arguments + # supplied to be used when creating an instance of the class + # to be used as the wrapper function. + + if instance is None and isclass(wrapped) and not args: + # We still need to be passed the target function to be + # wrapped as yet, so we need to return a further function + # to be able to capture it. + + def _capture(target_wrapped): + # Now have the target function to be wrapped and need + # to create an instance of the class which is to act + # as the decorator wrapper function. Before we do that, + # we need to first check that use of the decorator + # hadn't been disabled by a simple boolean. If it was, + # the target function to be wrapped is returned instead. + + _enabled = enabled + if type(_enabled) is bool: + if not _enabled: + return target_wrapped + _enabled = None + + # Now create an instance of the class which is to act + # as the decorator wrapper function. Any arguments had + # to be supplied as keyword only arguments so that is + # all we pass when creating it. + + target_wrapper = wrapped(**kwargs) + + # Finally build the wrapper itself and return it. + + return _build(target_wrapped, target_wrapper, + _enabled, adapter) + + return _capture + + # We should always have the target function to be wrapped at + # this point as the first (and only) value in args. + + target_wrapped = args[0] + + # Need to now check that use of the decorator hadn't been + # disabled by a simple boolean. If it was, then target + # function to be wrapped is returned instead. + + _enabled = enabled + if type(_enabled) is bool: + if not _enabled: + return target_wrapped + _enabled = None + + # We now need to build the wrapper, but there are a couple of + # different cases we need to consider. + + if instance is None: + if isclass(wrapped): + # In this case the decorator was applied to a class + # type but optional keyword arguments were not supplied + # for initialising an instance of the class to be used + # as the decorator wrapper function. + # + # @decorator + # class mydecoratorclass(object): + # def __init__(self, arg=None): + # self.arg = arg + # def __call__(self, wrapped, instance, + # args, kwargs): + # return wrapped(*args, **kwargs) + # + # @mydecoratorclass + # def function(): + # pass + # + # We still need to create an instance of the class to + # be used as the decorator wrapper function, but no + # arguments are pass. + + target_wrapper = wrapped() + + else: + # In this case the decorator was applied to a normal + # function, or possibly a static method of a class. + # + # @decorator + # def mydecoratorfuntion(wrapped, instance, + # args, kwargs): + # return wrapped(*args, **kwargs) + # + # @mydecoratorfunction + # def function(): + # pass + # + # That normal function becomes the decorator wrapper + # function. + + target_wrapper = wrapper + + else: + if isclass(instance): + # In this case the decorator was applied to a class + # method. + # + # class myclass(object): + # @decorator + # @classmethod + # def decoratorclassmethod(cls, wrapped, + # instance, args, kwargs): + # return wrapped(*args, **kwargs) + # + # instance = myclass() + # + # @instance.decoratorclassmethod + # def function(): + # pass + # + # This one is a bit strange because binding was actually + # performed on the wrapper created by our decorator + # factory. We need to apply that binding to the decorator + # wrapper function which which the decorator factory + # was applied to. + + target_wrapper = wrapper.__get__(None, instance) + + else: + # In this case the decorator was applied to an instance + # method. + # + # class myclass(object): + # @decorator + # def decoratorclassmethod(self, wrapped, + # instance, args, kwargs): + # return wrapped(*args, **kwargs) + # + # instance = myclass() + # + # @instance.decoratorclassmethod + # def function(): + # pass + # + # This one is a bit strange because binding was actually + # performed on the wrapper created by our decorator + # factory. We need to apply that binding to the decorator + # wrapper function which which the decorator factory + # was applied to. + + target_wrapper = wrapper.__get__(instance, type(instance)) + + # Finally build the wrapper itself and return it. + + return _build(target_wrapped, target_wrapper, _enabled, adapter) + + # We first return our magic function wrapper here so we can + # determine in what context the decorator factory was used. In + # other words, it is itself a universal decorator. The decorator + # function is used as the adapter so that linters see a signature + # corresponding to the decorator and not the wrapper it is being + # applied to. + + return _build(wrapper, _wrapper, adapter=decorator) + + else: + # The wrapper still has not been provided, so we are just + # collecting the optional keyword arguments. Return the + # decorator again wrapped in a partial using the collected + # arguments. + + return partial(decorator, enabled=enabled, adapter=adapter) + +# Decorator for implementing thread synchronization. It can be used as a +# decorator, in which case the synchronization context is determined by +# what type of function is wrapped, or it can also be used as a context +# manager, where the user needs to supply the correct synchronization +# context. It is also possible to supply an object which appears to be a +# synchronization primitive of some sort, by virtue of having release() +# and acquire() methods. In that case that will be used directly as the +# synchronization primitive without creating a separate lock against the +# derived or supplied context. + +def synchronized(wrapped): + # Determine if being passed an object which is a synchronization + # primitive. We can't check by type for Lock, RLock, Semaphore etc, + # as the means of creating them isn't the type. Therefore use the + # existence of acquire() and release() methods. This is more + # extensible anyway as it allows custom synchronization mechanisms. + + if hasattr(wrapped, 'acquire') and hasattr(wrapped, 'release'): + # We remember what the original lock is and then return a new + # decorator which accesses and locks it. When returning the new + # decorator we wrap it with an object proxy so we can override + # the context manager methods in case it is being used to wrap + # synchronized statements with a 'with' statement. + + lock = wrapped + + @decorator + def _synchronized(wrapped, instance, args, kwargs): + # Execute the wrapped function while the original supplied + # lock is held. + + with lock: + return wrapped(*args, **kwargs) + + class _PartialDecorator(CallableObjectProxy): + + def __enter__(self): + lock.acquire() + return lock + + def __exit__(self, *args): + lock.release() + + return _PartialDecorator(wrapped=_synchronized) + + # Following only apply when the lock is being created automatically + # based on the context of what was supplied. In this case we supply + # a final decorator, but need to use FunctionWrapper directly as we + # want to derive from it to add context manager methods in case it is + # being used to wrap synchronized statements with a 'with' statement. + + def _synchronized_lock(context): + # Attempt to retrieve the lock for the specific context. + + lock = vars(context).get('_synchronized_lock', None) + + if lock is None: + # There is no existing lock defined for the context we + # are dealing with so we need to create one. This needs + # to be done in a way to guarantee there is only one + # created, even if multiple threads try and create it at + # the same time. We can't always use the setdefault() + # method on the __dict__ for the context. This is the + # case where the context is a class, as __dict__ is + # actually a dictproxy. What we therefore do is use a + # meta lock on this wrapper itself, to control the + # creation and assignment of the lock attribute against + # the context. + + with synchronized._synchronized_meta_lock: + # We need to check again for whether the lock we want + # exists in case two threads were trying to create it + # at the same time and were competing to create the + # meta lock. + + lock = vars(context).get('_synchronized_lock', None) + + if lock is None: + lock = RLock() + setattr(context, '_synchronized_lock', lock) + + return lock + + def _synchronized_wrapper(wrapped, instance, args, kwargs): + # Execute the wrapped function while the lock for the + # desired context is held. If instance is None then the + # wrapped function is used as the context. + + with _synchronized_lock(instance if instance is not None else wrapped): + return wrapped(*args, **kwargs) + + class _FinalDecorator(FunctionWrapper): + + def __enter__(self): + self._self_lock = _synchronized_lock(self.__wrapped__) + self._self_lock.acquire() + return self._self_lock + + def __exit__(self, *args): + self._self_lock.release() + + return _FinalDecorator(wrapped=wrapped, wrapper=_synchronized_wrapper) + +synchronized._synchronized_meta_lock = Lock() diff --git a/.venv/lib/python3.8/site-packages/wrapt/importer.py b/.venv/lib/python3.8/site-packages/wrapt/importer.py new file mode 100644 index 00000000..4665f386 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/wrapt/importer.py @@ -0,0 +1,230 @@ +"""This module implements a post import hook mechanism styled after what is +described in PEP-369. Note that it doesn't cope with modules being reloaded. + +""" + +import sys +import threading + +PY2 = sys.version_info[0] == 2 + +if PY2: + string_types = basestring, +else: + import importlib + string_types = str, + +from .decorators import synchronized + +# The dictionary registering any post import hooks to be triggered once +# the target module has been imported. Once a module has been imported +# and the hooks fired, the list of hooks recorded against the target +# module will be truncacted but the list left in the dictionary. This +# acts as a flag to indicate that the module had already been imported. + +_post_import_hooks = {} +_post_import_hooks_init = False +_post_import_hooks_lock = threading.RLock() + +# Register a new post import hook for the target module name. This +# differs from the PEP-369 implementation in that it also allows the +# hook function to be specified as a string consisting of the name of +# the callback in the form 'module:function'. This will result in a +# proxy callback being registered which will defer loading of the +# specified module containing the callback function until required. + +def _create_import_hook_from_string(name): + def import_hook(module): + module_name, function = name.split(':') + attrs = function.split('.') + __import__(module_name) + callback = sys.modules[module_name] + for attr in attrs: + callback = getattr(callback, attr) + return callback(module) + return import_hook + +@synchronized(_post_import_hooks_lock) +def register_post_import_hook(hook, name): + # Create a deferred import hook if hook is a string name rather than + # a callable function. + + if isinstance(hook, string_types): + hook = _create_import_hook_from_string(hook) + + # Automatically install the import hook finder if it has not already + # been installed. + + global _post_import_hooks_init + + if not _post_import_hooks_init: + _post_import_hooks_init = True + sys.meta_path.insert(0, ImportHookFinder()) + + # Determine if any prior registration of a post import hook for + # the target modules has occurred and act appropriately. + + hooks = _post_import_hooks.get(name, None) + + if hooks is None: + # No prior registration of post import hooks for the target + # module. We need to check whether the module has already been + # imported. If it has we fire the hook immediately and add an + # empty list to the registry to indicate that the module has + # already been imported and hooks have fired. Otherwise add + # the post import hook to the registry. + + module = sys.modules.get(name, None) + + if module is not None: + _post_import_hooks[name] = [] + hook(module) + + else: + _post_import_hooks[name] = [hook] + + elif hooks == []: + # A prior registration of port import hooks for the target + # module was done and the hooks already fired. Fire the hook + # immediately. + + module = sys.modules[name] + hook(module) + + else: + # A prior registration of port import hooks for the target + # module was done but the module has not yet been imported. + + _post_import_hooks[name].append(hook) + +# Register post import hooks defined as package entry points. + +def _create_import_hook_from_entrypoint(entrypoint): + def import_hook(module): + __import__(entrypoint.module_name) + callback = sys.modules[entrypoint.module_name] + for attr in entrypoint.attrs: + callback = getattr(callback, attr) + return callback(module) + return import_hook + +def discover_post_import_hooks(group): + try: + import pkg_resources + except ImportError: + return + + for entrypoint in pkg_resources.iter_entry_points(group=group): + callback = _create_import_hook_from_entrypoint(entrypoint) + register_post_import_hook(callback, entrypoint.name) + +# Indicate that a module has been loaded. Any post import hooks which +# were registered against the target module will be invoked. If an +# exception is raised in any of the post import hooks, that will cause +# the import of the target module to fail. + +@synchronized(_post_import_hooks_lock) +def notify_module_loaded(module): + name = getattr(module, '__name__', None) + hooks = _post_import_hooks.get(name, None) + + if hooks: + _post_import_hooks[name] = [] + + for hook in hooks: + hook(module) + +# A custom module import finder. This intercepts attempts to import +# modules and watches out for attempts to import target modules of +# interest. When a module of interest is imported, then any post import +# hooks which are registered will be invoked. + +class _ImportHookLoader: + + def load_module(self, fullname): + module = sys.modules[fullname] + notify_module_loaded(module) + + return module + +class _ImportHookChainedLoader: + + def __init__(self, loader): + self.loader = loader + + def load_module(self, fullname): + module = self.loader.load_module(fullname) + notify_module_loaded(module) + + return module + +class ImportHookFinder: + + def __init__(self): + self.in_progress = {} + + @synchronized(_post_import_hooks_lock) + def find_module(self, fullname, path=None): + # If the module being imported is not one we have registered + # post import hooks for, we can return immediately. We will + # take no further part in the importing of this module. + + if not fullname in _post_import_hooks: + return None + + # When we are interested in a specific module, we will call back + # into the import system a second time to defer to the import + # finder that is supposed to handle the importing of the module. + # We set an in progress flag for the target module so that on + # the second time through we don't trigger another call back + # into the import system and cause a infinite loop. + + if fullname in self.in_progress: + return None + + self.in_progress[fullname] = True + + # Now call back into the import system again. + + try: + if PY2: + # For Python 2 we don't have much choice but to + # call back in to __import__(). This will + # actually cause the module to be imported. If no + # module could be found then ImportError will be + # raised. Otherwise we return a loader which + # returns the already loaded module and invokes + # the post import hooks. + + __import__(fullname) + + return _ImportHookLoader() + + else: + # For Python 3 we need to use find_spec().loader + # from the importlib.util module. It doesn't actually + # import the target module and only finds the + # loader. If a loader is found, we need to return + # our own loader which will then in turn call the + # real loader to import the module and invoke the + # post import hooks. + try: + import importlib.util + loader = importlib.util.find_spec(fullname).loader + except (ImportError, AttributeError): + loader = importlib.find_loader(fullname, path) + if loader: + return _ImportHookChainedLoader(loader) + + + finally: + del self.in_progress[fullname] + +# Decorator for marking that a function should be called as a post +# import hook when the target module is imported. + +def when_imported(name): + def register(hook): + register_post_import_hook(hook, name) + return hook + return register diff --git a/.venv/lib/python3.8/site-packages/wrapt/wrappers.py b/.venv/lib/python3.8/site-packages/wrapt/wrappers.py new file mode 100644 index 00000000..18cf5e05 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/wrapt/wrappers.py @@ -0,0 +1,947 @@ +import os +import sys +import functools +import operator +import weakref +import inspect + +PY2 = sys.version_info[0] == 2 + +if PY2: + string_types = basestring, +else: + string_types = str, + +def with_metaclass(meta, *bases): + """Create a base class with a metaclass.""" + return meta("NewBase", bases, {}) + +class _ObjectProxyMethods(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 _ObjectProxyMetaType(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(_ObjectProxyMethods)) + + return type.__new__(cls, name, bases, dictionary) + +class ObjectProxy(with_metaclass(_ObjectProxyMetaType)): + + __slots__ = '__wrapped__' + + def __init__(self, wrapped): + object.__setattr__(self, '__wrapped__', wrapped) + + # Python 3.2+ has the __qualname__ attribute, but it does not + # allow it to be overridden using a property and it must instead + # be an actual string object instead. + + try: + object.__setattr__(self, '__qualname__', wrapped.__qualname__) + except AttributeError: + pass + + @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 + def __class__(self, value): + self.__wrapped__.__class__ = value + + @property + def __annotations__(self): + return self.__wrapped__.__annotations__ + + @__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 not PY2: + def __bytes__(self): + return bytes(self.__wrapped__) + + def __repr__(self): + return '<{} at 0x{:x} for {} at 0x{:x}>'.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/.venv/lib/python3.8/site-packages/zmq/__init__.pxd b/.venv/lib/python3.8/site-packages/zmq/__init__.pxd new file mode 100644 index 00000000..a01fc19d --- /dev/null +++ b/.venv/lib/python3.8/site-packages/zmq/__init__.pxd @@ -0,0 +1,4 @@ +from zmq.backend.cython.context cimport Context +from zmq.backend.cython.socket cimport Socket +from zmq.backend.cython.message cimport Frame +from zmq.backend.cython cimport libzmq diff --git a/.venv/lib/python3.8/site-packages/zmq/__init__.py b/.venv/lib/python3.8/site-packages/zmq/__init__.py new file mode 100644 index 00000000..a952e207 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/zmq/__init__.py @@ -0,0 +1,78 @@ +"""Python bindings for 0MQ.""" + +# Copyright (C) PyZMQ Developers +# Distributed under the terms of the Modified BSD License. + +# load bundled libzmq, if there is one: +def _load_libzmq(): + """load bundled libzmq if there is one""" + import sys, platform, os + dlopen = hasattr(sys, 'getdlopenflags') # unix-only + # RTLD flags are added to os in Python 3 + # get values from os because ctypes values are WRONG on pypy + PYPY = platform.python_implementation().lower() == 'pypy' + + if dlopen: + import ctypes + dlflags = sys.getdlopenflags() + # set RTLD_GLOBAL, unset RTLD_LOCAL + flags = ctypes.RTLD_GLOBAL | dlflags + # ctypes.RTLD_LOCAL is 0 on pypy, which is *wrong* + flags &= ~ getattr(os, 'RTLD_LOCAL', 4) + # pypy on darwin needs RTLD_LAZY for some reason + if PYPY and sys.platform == 'darwin': + flags |= getattr(os, 'RTLD_LAZY', 1) + flags &= ~ getattr(os, 'RTLD_NOW', 2) + sys.setdlopenflags(flags) + try: + from . import libzmq + except ImportError: + # raise on failure to load if libzmq is present + from importlib.util import find_spec + if find_spec(".libzmq", "zmq"): + # found libzmq, but failed to load it! + # raise instead of silently moving on + raise + else: + # store libzmq as zmq._libzmq for backward-compat + globals()['_libzmq'] = libzmq + if PYPY: + # should already have been imported above, so reimporting is as cheap as checking + import ctypes + # some versions of pypy (5.3 < ? < 5.8) needs explicit CDLL load for some reason, + # otherwise symbols won't be globally available + # do this unconditionally because it should be harmless (?) + ctypes.CDLL(libzmq.__file__, ctypes.RTLD_GLOBAL) + finally: + if dlopen: + sys.setdlopenflags(dlflags) + +_load_libzmq() + + +# zmq top-level imports + +from zmq import backend +from zmq.backend import * +from zmq import sugar +from zmq.sugar import * + +def get_includes(): + """Return a list of directories to include for linking against pyzmq with cython.""" + from os.path import join, dirname, abspath, pardir, exists + base = dirname(__file__) + parent = abspath(join(base, pardir)) + includes = [ parent ] + [ join(parent, base, subdir) for subdir in ('utils',) ] + if exists(join(parent, base, 'include')): + includes.append(join(parent, base, 'include')) + return includes + +def get_library_dirs(): + """Return a list of directories used to link against pyzmq's bundled libzmq.""" + from os.path import join, dirname, abspath, pardir + base = dirname(__file__) + parent = abspath(join(base, pardir)) + return [ join(parent, base) ] + +COPY_THRESHOLD = 65536 +__all__ = ['get_includes', 'COPY_THRESHOLD'] + sugar.__all__ + backend.__all__ diff --git a/.venv/lib/python3.8/site-packages/zmq/__pycache__/__init__.cpython-38.pyc b/.venv/lib/python3.8/site-packages/zmq/__pycache__/__init__.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..93174f8bf5c15ecb2163dfd60672684c846055c5 GIT binary patch literal 2133 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 literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/zmq/__pycache__/asyncio.cpython-38.pyc b/.venv/lib/python3.8/site-packages/zmq/__pycache__/asyncio.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..2551289b7acd538ade5e11110494c6f8d3c58b01 GIT binary patch literal 3919 zcmb7H&2QYs73Yv#E_b!7FH4Twv?&|ANj9xkHCnf6AQ&>FO<L<)lDjHH#h zc5B0!nPwBO{1O@tgGhAs`Qc#qO8P2>J&b+VRdvCvJx0?o@ z+TZ>WoMQA(noK_~CYxy4ztC~RH#p;F%zP7XD`rE>x0t5cz73ik+rye)8#=zjjH0D> z*ZukdxJ8Z-W4B<7dK=LUCp{guJ%qVdx5o0z-2fq6qTg>^Xh z()L@RHTfK9bBfjmZC=caR!#d)aXk-T$MPjYp$Y=H6Z^y<+&Z*?cIT zjt5d?UPwCzsTU^PdvKf|q>1;dZu1*x%IJ4kSr7Kc`B;jMSuX8}SVVa$d(T9Y|2|De zrSq9yWMw0(7PE*xoqkMAHqo+M=!D@jn7|a4Z;RTY0<96u=73UGd zN0W!fblMhLMpn&@H|*5dG2XI17_3*a`1AWB4+L=;#9;F+D{Zj1_tube_~_g9^?W#5 z9}Pxp<75;@PXu2(IuIgWdw%En^W!_eyR!}ztyhP2N5^G5;9@Tv$NIP*(e1>B!HVk> zKD#qp`kgt55G3JH1VPyhf?>+XF^yY6@N^u;dPUke#IFZhi?W7UIoJDhufH2SdU$`g zS31?ZsfiDJ_qNMgKrh+GW+l#4*CLvO?j1CxAeY(9VUDS&-)|WY`zMy+%(uA7Em*_m zHm~7b;|{D+FP#Tz91B_8)^AS=xJEKa_9tG{)siST8(}YYWKdhyjYzi1Lu2C7Ld!PM zomeNvA$&x>cf#JV6Z30hk12<6Pfey*O{{KU)v8v(;w!bvZLn4=-rtE11nJm|!Z>~m zt12c!PliWcmcq#SjQHeA)Rd-(nb*ckIFhVms5DAW6UzMzZ?>m(OzJJ&jW`@W=HcBB zF#9)}QGBe`(G8BmJUR$)W1w&BZp10r$?jsHKl=Z8kk@g%yg?l~u2lB@Ax0n3>|J#I zjxAU4E}J3effOMZQZ9qwE5eZ+f^l-ua@ohkGWmsJ zx+L(s6M?VT+wVAXo(^81ZV?^AX28=Z2;@(Q^i%58h3B2J7+S zTt&T2yk}x4AywEwr$(z&p|w6i>yC2!Vne?#qt(-B%@k5Hk??gXqG#(0xI=+dzyVwW z$>gE&8E`2Kz6NaHF!UE7tD|^vbC3-3K^PAT;pGRy8>Hlco{G%g0WuDP$t6+AVXmQN zq@mZw8_Kfml=7L`m&8Gb`SXGPS_k<|>$ZV4Jvzh5CqyEg6d!6ObOT~37^Fd#hq<^6 z(0<1%>sTg6C5c#C!5)|AXRDFI$^7hDzrkjm7R+Mx%G)mK(!wWO^cf+RLLjgJT@o%T zEcBvSgc8a5_)6t9n_l%$)DzrGlSp`B?nQB$iL*rrC2!#h=~4GH>dpl^2f{+2ZadS? zr`V_^sukBK63uSuciaoEFA3+$iT!p!t|TOm4YN#Az?2_ScaDOy%jHch+(w(EEfZj{ z74?#bkP~duR*G5EX-k8_cU1KQJ8q>(E}rMbdNojv9wAERQ#orbN{1s*9wT>XA+vs` zex+2zBZ`4c;Yv&8H{b>ECFuQ1u_#jah*!c5A>6hk(Jl!^ZcmSjlhZ=+no5Tjw_i1U z`)dSLzXmWkWy}A=pUz6L;>C9F!NcCxz1`mSr(RV&X{0I4jWZG%b&aw~S3Az=7=$W2 zW?puXj$`f}rSge)G{_H>*Hu+eg;{k}n0e`*r@y`Z+phAm{!HAb9AH%~qa2naxiTYX zxp`u|G?B#FDPp}!wkY=IP&2rhW{ z8!}&ql})&I^dv^aj!{MY9K_Pmp{8_?LRI@^rA?!9dAl+q&U~boI!xZdCsV*sk(rM9 z3QdJQ14g16)irHq((ga&n$Ko5iOs57Q<|h&Mmtm$BtM#V{r&|}rZs^-H0tmvhR$3E zQJ-)e$1!n69&DJB@<-<#UecQ)woN} tm;Dl*?YgXGyKK=kS&PlHWoxmqvb3_~Sj&yYIoopEj^#Q^^`!pq{tF#?e@_4a literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/zmq/__pycache__/decorators.cpython-38.pyc b/.venv/lib/python3.8/site-packages/zmq/__pycache__/decorators.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..824f99a385ac18e9b79d4af47b9a4637ba0c541d GIT binary patch literal 5559 zcmcgw-EQ2*6`movKUzz+;>3>aG|jX%Vyz;r;si!e)eUUKby6TueiWmI(1J@XxiTd# zxt`%#(s~61l?%x?=>zn}Mz4&Z=v(v=dcoVG7kPzVwEfNu$=#J=ptCD&di+i zo$s9Cy}7vt!>{u7-`(MBjQxWelRpQITPP|*<+Bau^9}A>z8zUTd&A}o_fF(&IJj1# zO0T+6CAx#SlZHvG#BP{A5S=7WgS~V`C7qohRjo#& z)e?^asnEsq{lH&c71wXH-fuKM4R-=DP$c6cGe`+9_QkpxDLhpO6Fo2Xwjg6kYz|U0 zk6)}tsQozg_F9cxh?bGhE<72CPL!y?7hWpT2Z0DML(iM->4{2Ir+2E zxP_wLLlrQfgl$+ri|wEBZQpsqfsu+|g?%f2&9CEH^=JGBt~K9+y=SwATUvW~sXkf_|ZL;k5Ck0dBjJ|1yt9u^fj!$=BA$93Q}y)Q9;zrs;2#d z$vJfY*Ly2zufNg{`^$s4?*Tvl^6rBmh?e(m?CtH}`1y?$XmX`og=+Qpv%2eIX{qb} zjAqr#;lo$Q%WoC$JAiQcBVVF&4n-}XI<~jjF+1kp@ZZ``t*7iMKVnDx$U3sSjt?(; zQa`XqHgscqe}kaXURpO^7>g*`3Oj_Xa(M0M5DLJL_C-eqUP^Dtcr9bQb{m6K>cyQvJPN&18bp8&+HGvD zn2oMe4I@GPQfPSqMvjk##eB1i-?vjuGiK@}h9EZa$cqMnA@2fz;@acu2iKZT z));F)oB3+LAN)$nL}pbmea}nD%VMt=xGuUnWSp#OOe1Hp(aeUfo0Y6y;52K{o#~M| z#Isp#XIG1mXD~p!yF5!nYdO+>frh$*idnPt=M6r~E$&zjv;J-Ur&?)P!w;t1y5mKW z>$Yx23GUQ~W1b#A%4JJ3P1BN>aglGJdf~{|>HZQ`G^t)ylbarTT{ETot>V2RWH4Uk z7hf5^{lBdO9DT7blTM)2*p;%fj%sWak-+_!fs@Fw`6?_6fO*P6Kpo8zs||6pBa zaA&keR+sp_GW^Tu#%g-M`4(xvM2saU#(OR|PwEjd91gKtf!%$vxj#J!nM)Ln^;QTi zEMa15DQ_W9XjayBLZro}azKH%Ii7wkbI3ElBZEt_Jp8Z`BC9f-oY~N*B=lx>Kj~+7 z6vRNkcEYiNvlDRg+S5SMIGeOu=idx_?;rP9KKcF3N_g5M1Z@_ee;fL3ZrBJ znv;sUh$>|%5}-rtnU&hx&U20o9d0P=cm*R>)BpiiE~2IPpV>%mvRW=0TtqfP(li4e zpoyWTu_8!eJ19lMbLG_9%e<#q)n<^_Xd+5=WRohAkj>??I{{JYgvwjgMLR34FGNw~ zf>1fvD}K4M-$l2VDceWdsgq89B-yBH<=3G6dN%JGl$Q!0u9dgbx;F{2(r%)wk8#Y< ze%3Lk2$Q)da962a*!aqnsR}wFB`8{PVXAG5h=7v71N%USZBPnP3_`B!Owfcqym~uQ ziP)0fW^o?S@l7CgqckuNezW5PTdnW+!c&_jY<@<<&ZDBRV75!S?KY(}e0UY=EH;GW77iIWFU5kw%yJs` zbn2>*z|Xow)%oruB~L|I8`FyBq!YA4dA1p{c5-oU50 z(HpRKs`Bax_St5javLsZr%0R-5Ux_fKH_)S?=BrUc<$uS7e@b;GPcNvTdZANw9b!@sN9!=1Siw3tE%tSf z&V!({BlIeDs&96(B=jKKahFz$WlT*|DyEojLO65fyPInPvNrbA^R-O_hNZ@ zT5PKj)^3l_A*)g+DXYSp?hJJl-OI(mnY82l6ljo3R4t>*>P1JqpAL1IjZ=4KW6u+8 zr-|-;4E!2J5klG725$hIj)i!KyWyLsKst&4Jk*`!Snb^;PLgm*L^Cn#m}7|w5)?(D z0UTSIt=21=Af|YhoUC+U%DYo`m>)2->;7}hnDl`LUt4t6R%#zPj8}fHF|4Q+c~9Zv zN`6i&HG3-uVg4zD&QAJ>nI!bxV&aPhy(v#sFZ1bPGvO546$$9ymi9YmqRX7lTPSA)*C3Ug(Wpq0NJ$C|+WR-o6K4(5Fj6hx zEX6rindG->rq-FF$+`6GgbXcyVhLsF&FVKz;`$+V(;?G&4bDlNV9)=0zB<2DpZ_oD Ct7AU^ literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/zmq/__pycache__/error.cpython-38.pyc b/.venv/lib/python3.8/site-packages/zmq/__pycache__/error.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..641a263dec6a5f9eaaf3df00a44f0640b57e549b GIT binary patch literal 6112 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 H@8ACec%VBh literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/zmq/_future.py b/.venv/lib/python3.8/site-packages/zmq/_future.py new file mode 100644 index 00000000..4d415ac1 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/zmq/_future.py @@ -0,0 +1,545 @@ +"""Future-returning APIs for coroutines.""" + +# Copyright (c) PyZMQ Developers. +# Distributed under the terms of the Modified BSD License. + +from collections import namedtuple, deque +from itertools import chain + +from zmq import EVENTS, POLLOUT, POLLIN +import zmq as _zmq + +_FutureEvent = namedtuple('_FutureEvent', ('future', 'kind', 'kwargs', 'msg')) + +# These are incomplete classes and need a Mixin for compatibility with an eventloop +# defining the followig attributes: +# +# _Future +# _READ +# _WRITE +# _default_loop() + + +class _AsyncPoller(_zmq.Poller): + """Poller that returns a Future on poll, instead of blocking.""" + + def poll(self, timeout=-1): + """Return a Future for a poll event""" + future = self._Future() + if timeout == 0: + try: + result = super(_AsyncPoller, self).poll(0) + except Exception as e: + future.set_exception(e) + else: + future.set_result(result) + return future + + loop = self._default_loop() + + # register Future to be called as soon as any event is available on any socket + watcher = self._Future() + + # watch raw sockets: + raw_sockets = [] + def wake_raw(*args): + if not watcher.done(): + watcher.set_result(None) + + watcher.add_done_callback(lambda f: self._unwatch_raw_sockets(loop, *raw_sockets)) + + for socket, mask in self.sockets: + if isinstance(socket, _zmq.Socket): + if not isinstance(socket, self._socket_class): + # it's a blocking zmq.Socket, wrap it in async + socket = self._socket_class.from_socket(socket) + if mask & _zmq.POLLIN: + socket._add_recv_event('poll', future=watcher) + if mask & _zmq.POLLOUT: + socket._add_send_event('poll', future=watcher) + else: + raw_sockets.append(socket) + evt = 0 + if mask & _zmq.POLLIN: + evt |= self._READ + if mask & _zmq.POLLOUT: + evt |= self._WRITE + self._watch_raw_socket(loop, socket, evt, wake_raw) + + def on_poll_ready(f): + if future.done(): + return + if watcher.cancelled(): + try: + future.cancel() + except RuntimeError: + # RuntimeError may be called during teardown + pass + return + if watcher.exception(): + future.set_exception(watcher.exception()) + else: + try: + result = super(_AsyncPoller, self).poll(0) + except Exception as e: + future.set_exception(e) + else: + future.set_result(result) + watcher.add_done_callback(on_poll_ready) + + if timeout is not None and timeout > 0: + # schedule cancel to fire on poll timeout, if any + def trigger_timeout(): + if not watcher.done(): + watcher.set_result(None) + + timeout_handle = loop.call_later( + 1e-3 * timeout, + trigger_timeout + ) + def cancel_timeout(f): + if hasattr(timeout_handle, 'cancel'): + timeout_handle.cancel() + else: + loop.remove_timeout(timeout_handle) + future.add_done_callback(cancel_timeout) + + def cancel_watcher(f): + if not watcher.done(): + watcher.cancel() + future.add_done_callback(cancel_watcher) + + return future + + +class _AsyncSocket(_zmq.Socket): + + + # Warning : these class variables are only here to allow to call super().__setattr__. + # They be overridden at instance initialization and not shared in the whole class + _recv_futures = None + _send_futures = None + _state = 0 + _shadow_sock = None + _poller_class = _AsyncPoller + io_loop = None + _fd = None + + def __init__(self, context=None, socket_type=-1, io_loop=None, **kwargs): + if isinstance(context, _zmq.Socket): + context, from_socket = (None, context) + else: + from_socket = kwargs.pop('_from_socket', None) + if from_socket is not None: + super(_AsyncSocket, self).__init__(shadow=from_socket.underlying) + self._shadow_sock = from_socket + else: + super(_AsyncSocket, self).__init__(context, socket_type, **kwargs) + self._shadow_sock = _zmq.Socket.shadow(self.underlying) + self.io_loop = io_loop or self._default_loop() + self._recv_futures = deque() + self._send_futures = deque() + self._state = 0 + self._fd = self._shadow_sock.FD + self._init_io_state() + + @classmethod + def from_socket(cls, socket, io_loop=None): + """Create an async socket from an existing Socket""" + return cls(_from_socket=socket, io_loop=io_loop) + + def close(self, linger=None): + if not self.closed: + for event in list(chain(self._recv_futures, self._send_futures)): + if not event.future.done(): + try: + event.future.cancel() + except RuntimeError: + # RuntimeError may be called during teardown + pass + self._clear_io_state() + super(_AsyncSocket, self).close(linger=linger) + close.__doc__ = _zmq.Socket.close.__doc__ + + def get(self, key): + result = super(_AsyncSocket, self).get(key) + if key == EVENTS: + self._schedule_remaining_events(result) + return result + get.__doc__ = _zmq.Socket.get.__doc__ + + def recv_multipart(self, flags=0, copy=True, track=False): + """Receive a complete multipart zmq message. + + Returns a Future whose result will be a multipart message. + """ + return self._add_recv_event('recv_multipart', + dict(flags=flags, copy=copy, track=track) + ) + + def recv(self, flags=0, copy=True, track=False): + """Receive a single zmq frame. + + Returns a Future, whose result will be the received frame. + + Recommend using recv_multipart instead. + """ + return self._add_recv_event('recv', + dict(flags=flags, copy=copy, track=track) + ) + + def send_multipart(self, msg, flags=0, copy=True, track=False, **kwargs): + """Send a complete multipart zmq message. + + Returns a Future that resolves when sending is complete. + """ + kwargs['flags'] = flags + kwargs['copy'] = copy + kwargs['track'] = track + return self._add_send_event('send_multipart', msg=msg, kwargs=kwargs) + + def send(self, msg, flags=0, copy=True, track=False, **kwargs): + """Send a single zmq frame. + + Returns a Future that resolves when sending is complete. + + Recommend using send_multipart instead. + """ + kwargs['flags'] = flags + kwargs['copy'] = copy + kwargs['track'] = track + kwargs.update(dict(flags=flags, copy=copy, track=track)) + return self._add_send_event('send', msg=msg, kwargs=kwargs) + + def _deserialize(self, recvd, load): + """Deserialize with Futures""" + f = self._Future() + def _chain(_): + """Chain result through serialization to recvd""" + if f.done(): + return + if recvd.exception(): + f.set_exception(recvd.exception()) + else: + buf = recvd.result() + try: + loaded = load(buf) + except Exception as e: + f.set_exception(e) + else: + f.set_result(loaded) + recvd.add_done_callback(_chain) + + def _chain_cancel(_): + """Chain cancellation from f to recvd""" + if recvd.done(): + return + if f.cancelled(): + recvd.cancel() + f.add_done_callback(_chain_cancel) + + return f + + def poll(self, timeout=None, flags=_zmq.POLLIN): + """poll the socket for events + + returns a Future for the poll results. + """ + + if self.closed: + raise _zmq.ZMQError(_zmq.ENOTSUP) + + p = self._poller_class() + p.register(self, flags) + f = p.poll(timeout) + + future = self._Future() + def unwrap_result(f): + if future.done(): + return + if f.cancelled(): + try: + future.cancel() + except RuntimeError: + # RuntimeError may be called during teardown + pass + return + if f.exception(): + future.set_exception(f.exception()) + else: + evts = dict(f.result()) + future.set_result(evts.get(self, 0)) + + if f.done(): + # hook up result if + unwrap_result(f) + else: + f.add_done_callback(unwrap_result) + return future + + def _add_timeout(self, future, timeout): + """Add a timeout for a send or recv Future""" + def future_timeout(): + if future.done(): + # future already resolved, do nothing + return + + # raise EAGAIN + future.set_exception(_zmq.Again()) + self._call_later(timeout, future_timeout) + + def _call_later(self, delay, callback): + """Schedule a function to be called later + + Override for different IOLoop implementations + + Tornado and asyncio happen to both have ioloop.call_later + with the same signature. + """ + self.io_loop.call_later(delay, callback) + + @staticmethod + def _remove_finished_future(future, event_list): + """Make sure that futures are removed from the event list when they resolve + + Avoids delaying cleanup until the next send/recv event, + which may never come. + """ + for f_idx, (f, kind, kwargs, _) in enumerate(event_list): + if f is future: + break + else: + return + + # "future" instance is shared between sockets, but each socket has its own event list. + event_list.remove(event_list[f_idx]) + + def _add_recv_event(self, kind, kwargs=None, future=None): + """Add a recv event, returning the corresponding Future""" + f = future or self._Future() + if kind.startswith('recv') and kwargs.get('flags', 0) & _zmq.DONTWAIT: + # short-circuit non-blocking calls + recv = getattr(self._shadow_sock, kind) + try: + r = recv(**kwargs) + except Exception as e: + f.set_exception(e) + else: + f.set_result(r) + return f + + # we add it to the list of futures before we add the timeout as the + # timeout will remove the future from recv_futures to avoid leaks + self._recv_futures.append( + _FutureEvent(f, kind, kwargs, msg=None) + ) + + # Don't let the Future sit in _recv_events after it's done + f.add_done_callback(lambda f: self._remove_finished_future(f, self._recv_futures)) + + if hasattr(_zmq, 'RCVTIMEO'): + timeout_ms = self._shadow_sock.rcvtimeo + if timeout_ms >= 0: + self._add_timeout(f, timeout_ms * 1e-3) + + if self._shadow_sock.get(EVENTS) & POLLIN: + # recv immediately, if we can + self._handle_recv() + if self._recv_futures: + self._add_io_state(POLLIN) + return f + + def _add_send_event(self, kind, msg=None, kwargs=None, future=None): + """Add a send event, returning the corresponding Future""" + f = future or self._Future() + # attempt send with DONTWAIT if no futures are waiting + # short-circuit for sends that will resolve immediately + # only call if no send Futures are waiting + if ( + kind in ('send', 'send_multipart') + and not self._send_futures + ): + flags = kwargs.get('flags', 0) + nowait_kwargs = kwargs.copy() + nowait_kwargs['flags'] = flags | _zmq.DONTWAIT + + # short-circuit non-blocking calls + send = getattr(self._shadow_sock, kind) + # track if the send resolved or not + # (EAGAIN if DONTWAIT is not set should proceed with) + finish_early = True + try: + r = send(msg, **nowait_kwargs) + except _zmq.Again as e: + if flags & _zmq.DONTWAIT: + f.set_exception(e) + else: + # EAGAIN raised and DONTWAIT not requested, + # proceed with async send + finish_early = False + except Exception as e: + f.set_exception(e) + else: + f.set_result(r) + + if finish_early: + # short-circuit resolved, return finished Future + # schedule wake for recv if there are any receivers waiting + if self._recv_futures: + self._schedule_remaining_events() + return f + + # we add it to the list of futures before we add the timeout as the + # timeout will remove the future from recv_futures to avoid leaks + self._send_futures.append( + _FutureEvent(f, kind, kwargs=kwargs, msg=msg) + ) + # Don't let the Future sit in _send_futures after it's done + f.add_done_callback(lambda f: self._remove_finished_future(f, self._send_futures)) + + if hasattr(_zmq, 'SNDTIMEO'): + timeout_ms = self._shadow_sock.get(_zmq.SNDTIMEO) + if timeout_ms >= 0: + self._add_timeout(f, timeout_ms * 1e-3) + + self._add_io_state(POLLOUT) + return f + + def _handle_recv(self): + """Handle recv events""" + if not self._shadow_sock.get(EVENTS) & POLLIN: + # event triggered, but state may have been changed between trigger and callback + return + f = None + while self._recv_futures: + f, kind, kwargs, _ = self._recv_futures.popleft() + # skip any cancelled futures + if f.done(): + f = None + else: + break + + if not self._recv_futures: + self._drop_io_state(POLLIN) + + if f is None: + return + + if kind == 'poll': + # on poll event, just signal ready, nothing else. + f.set_result(None) + return + elif kind == 'recv_multipart': + recv = self._shadow_sock.recv_multipart + elif kind == 'recv': + recv = self._shadow_sock.recv + else: + raise ValueError("Unhandled recv event type: %r" % kind) + + kwargs['flags'] |= _zmq.DONTWAIT + try: + result = recv(**kwargs) + except Exception as e: + f.set_exception(e) + else: + f.set_result(result) + + def _handle_send(self): + if not self._shadow_sock.get(EVENTS) & POLLOUT: + # event triggered, but state may have been changed between trigger and callback + return + f = None + while self._send_futures: + f, kind, kwargs, msg = self._send_futures.popleft() + # skip any cancelled futures + if f.done(): + f = None + else: + break + + if not self._send_futures: + self._drop_io_state(POLLOUT) + + if f is None: + return + + if kind == 'poll': + # on poll event, just signal ready, nothing else. + f.set_result(None) + return + elif kind == 'send_multipart': + send = self._shadow_sock.send_multipart + elif kind == 'send': + send = self._shadow_sock.send + else: + raise ValueError("Unhandled send event type: %r" % kind) + + kwargs['flags'] |= _zmq.DONTWAIT + try: + result = send(msg, **kwargs) + except Exception as e: + f.set_exception(e) + else: + f.set_result(result) + + # event masking from ZMQStream + def _handle_events(self, fd=0, events=0): + """Dispatch IO events to _handle_recv, etc.""" + zmq_events = self._shadow_sock.get(EVENTS) + if zmq_events & _zmq.POLLIN: + self._handle_recv() + if zmq_events & _zmq.POLLOUT: + self._handle_send() + self._schedule_remaining_events() + + def _schedule_remaining_events(self, events=None): + """Schedule a call to handle_events next loop iteration + + If there are still events to handle. + """ + # edge-triggered handling + # allow passing events in, in case this is triggered by retrieving events, + # so we don't have to retrieve it twice. + if self._state == 0: + # not watching for anything, nothing to schedule + return + if events is None: + events = self._shadow_sock.get(EVENTS) + if events & self._state: + self._call_later(0, self._handle_events) + + def _add_io_state(self, state): + """Add io_state to poller.""" + if self._state != state: + state = self._state = self._state | state + self._update_handler(self._state) + + def _drop_io_state(self, state): + """Stop poller from watching an io_state.""" + if self._state & state: + self._state = self._state & (~state) + self._update_handler(self._state) + + def _update_handler(self, state): + """Update IOLoop handler with state. + + zmq FD is always read-only. + """ + self._schedule_remaining_events() + + def _init_io_state(self): + """initialize the ioloop event handler""" + self.io_loop.add_handler(self._shadow_sock, self._handle_events, self._READ) + self._call_later(0, self._handle_events) + + def _clear_io_state(self): + """unregister the ioloop event handler + + called once during close + """ + fd = self._shadow_sock + if self._shadow_sock.closed: + fd = self._fd + self.io_loop.remove_handler(fd) + + diff --git a/.venv/lib/python3.8/site-packages/zmq/asyncio.py b/.venv/lib/python3.8/site-packages/zmq/asyncio.py new file mode 100644 index 00000000..2ee12b82 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/zmq/asyncio.py @@ -0,0 +1,119 @@ +"""AsyncIO support for zmq + +Requires asyncio and Python 3. +""" + +# Copyright (c) PyZMQ Developers. +# Distributed under the terms of the Modified BSD License. + +import zmq as _zmq +from zmq import _future + +# TODO: support trollius for Legacy Python? (probably not) + +import asyncio +from asyncio import SelectorEventLoop, Future + +try: + import selectors +except ImportError: + from asyncio import selectors # py33 + + +class _AsyncIO(object): + _Future = Future + _WRITE = selectors.EVENT_WRITE + _READ = selectors.EVENT_READ + + def _default_loop(self): + return asyncio.get_event_loop() + + +class Poller(_AsyncIO, _future._AsyncPoller): + """Poller returning asyncio.Future for poll results.""" + + def _watch_raw_socket(self, loop, socket, evt, f): + """Schedule callback for a raw socket""" + if evt & self._READ: + loop.add_reader(socket, lambda *args: f()) + if evt & self._WRITE: + loop.add_writer(socket, lambda *args: f()) + + def _unwatch_raw_sockets(self, loop, *sockets): + """Unschedule callback for a raw socket""" + for socket in sockets: + loop.remove_reader(socket) + loop.remove_writer(socket) + + +class Socket(_AsyncIO, _future._AsyncSocket): + """Socket returning asyncio Futures for send/recv/poll methods.""" + + _poller_class = Poller + + def _init_io_state(self): + """initialize the ioloop event handler""" + self.io_loop.add_reader(self._fd, lambda: self._handle_events(0, 0)) + + def _clear_io_state(self): + """clear any ioloop event handler + + called once at close + """ + self.io_loop.remove_reader(self._fd) + + +Poller._socket_class = Socket + + +class Context(_zmq.Context): + """Context for creating asyncio-compatible Sockets""" + + _socket_class = Socket + + # avoid sharing instance with base Context class + _instance = None + + +class ZMQEventLoop(SelectorEventLoop): + """DEPRECATED: AsyncIO eventloop using zmq_poll. + + pyzmq sockets should work with any asyncio event loop as of pyzmq 17. + """ + + def __init__(self, selector=None): + _deprecated() + return super(ZMQEventLoop, self).__init__(selector) + + +_loop = None + + +def _deprecated(): + if _deprecated.called: + return + _deprecated.called = True + import warnings + + warnings.warn( + "ZMQEventLoop and zmq.asyncio.install are deprecated in pyzmq 17. Special eventloop integration is no longer needed.", + DeprecationWarning, + stacklevel=3, + ) + + +_deprecated.called = False + + +def install(): + """DEPRECATED: No longer needed in pyzmq 17""" + _deprecated() + + +__all__ = [ + "Context", + "Socket", + "Poller", + "ZMQEventLoop", + "install", +] diff --git a/.venv/lib/python3.8/site-packages/zmq/auth/__init__.py b/.venv/lib/python3.8/site-packages/zmq/auth/__init__.py new file mode 100644 index 00000000..92b5b6db --- /dev/null +++ b/.venv/lib/python3.8/site-packages/zmq/auth/__init__.py @@ -0,0 +1,11 @@ +"""Utilities for ZAP authentication. + +To run authentication in a background thread, see :mod:`zmq.auth.thread`. +For integration with the tornado eventloop, see :mod:`zmq.auth.ioloop`. +For integration with the asyncio event loop, see :mod:`zmq.auth.asyncio`. + +.. versionadded:: 14.1 +""" + +from .base import * +from .certs import * diff --git a/.venv/lib/python3.8/site-packages/zmq/auth/__pycache__/__init__.cpython-38.pyc b/.venv/lib/python3.8/site-packages/zmq/auth/__pycache__/__init__.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..2b80d9ff6d4c3b00fcaf1a7f57e37d8158ce6f3d GIT binary patch literal 481 zcmaKoy-ve05XYT1g%YVVj9!bVqe^6;LI@Vbgpg>LF0LCNjYVn)+vx`rufq#5WM$$N zn7FhZ5CTr}o$l**@_*FnLor?5vW=*Lj^_c}BPpAW+ zgSnA|$@Bb))iAbgO;~h|CzSRuvl}*DDxcvZP;aaj(ok67<=mL!SB^4u>pzZgYn`ec zhyDrLjUg#wj4r@B{Hc%<q}+pfsc#RKf9Ww^{9TE=|gL6;6eNs+EHE?v>a* z9NM_gB=++nE>zJgb%COQ>@72ZythhLt95dg#HdDGs}XaqwDO#@VqLY*QK>SAi~5`k J(S--?;0qdFlTQEu literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/zmq/auth/__pycache__/asyncio.cpython-38.pyc b/.venv/lib/python3.8/site-packages/zmq/auth/__pycache__/asyncio.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..2d2e0a90aaf3aa9bd9986cdd8b3e656d3717f1e7 GIT binary patch literal 1783 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 literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/zmq/auth/asyncio.py b/.venv/lib/python3.8/site-packages/zmq/auth/asyncio.py new file mode 100644 index 00000000..fb16e056 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/zmq/auth/asyncio.py @@ -0,0 +1,49 @@ +"""ZAP Authenticator integrated with the asyncio IO loop. + +.. versionadded:: 15.2 +""" + +# Copyright (C) PyZMQ Developers +# Distributed under the terms of the Modified BSD License. + +import asyncio + +import zmq +from zmq.asyncio import Poller +from .base import Authenticator + + +class AsyncioAuthenticator(Authenticator): + """ZAP authentication for use in the asyncio IO loop""" + + def __init__(self, context=None, loop=None): + super().__init__(context) + self.loop = loop or asyncio.get_event_loop() + self.__poller = None + self.__task = None + + async def __handle_zap(self): + while True: + events = await self.__poller.poll() + if self.zap_socket in dict(events): + msg = await self.zap_socket.recv_multipart() + self.handle_zap_message(msg) + + def start(self): + """Start ZAP authentication""" + super().start() + self.__poller = Poller() + self.__poller.register(self.zap_socket, zmq.POLLIN) + self.__task = asyncio.ensure_future(self.__handle_zap()) + + def stop(self): + """Stop ZAP authentication""" + if self.__task: + self.__task.cancel() + if self.__poller: + self.__poller.unregister(self.zap_socket) + self.__poller = None + super().stop() + + +__all__ = ["AsyncioAuthenticator"] diff --git a/.venv/lib/python3.8/site-packages/zmq/auth/base.py b/.venv/lib/python3.8/site-packages/zmq/auth/base.py new file mode 100644 index 00000000..bfafe039 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/zmq/auth/base.py @@ -0,0 +1,379 @@ +"""Base implementation of 0MQ authentication.""" + +# Copyright (C) PyZMQ Developers +# Distributed under the terms of the Modified BSD License. + +import logging + +import zmq +from zmq.utils import z85 +from zmq.utils.strtypes import bytes, unicode, b, u +from zmq.error import _check_version + +from .certs import load_certificates + + +CURVE_ALLOW_ANY = '*' +VERSION = b'1.0' + +class Authenticator(object): + """Implementation of ZAP authentication for zmq connections. + + Note: + + - libzmq provides four levels of security: default NULL (which the Authenticator does + not see), and authenticated NULL, PLAIN, CURVE, and GSSAPI, which the Authenticator can see. + - until you add policies, all incoming NULL connections are allowed. + (classic ZeroMQ behavior), and all PLAIN and CURVE connections are denied. + - GSSAPI requires no configuration. + """ + + def __init__(self, context=None, encoding='utf-8', log=None): + _check_version((4,0), "security") + self.context = context or zmq.Context.instance() + self.encoding = encoding + self.allow_any = False + self.credentials_providers = {} + self.zap_socket = None + self.whitelist = set() + self.blacklist = set() + # passwords is a dict keyed by domain and contains values + # of dicts with username:password pairs. + self.passwords = {} + # certs is dict keyed by domain and contains values + # of dicts keyed by the public keys from the specified location. + self.certs = {} + self.log = log or logging.getLogger('zmq.auth') + + def start(self): + """Create and bind the ZAP socket""" + self.zap_socket = self.context.socket(zmq.REP) + self.zap_socket.linger = 1 + self.zap_socket.bind("inproc://zeromq.zap.01") + self.log.debug("Starting") + + def stop(self): + """Close the ZAP socket""" + if self.zap_socket: + self.zap_socket.close() + self.zap_socket = None + + def allow(self, *addresses): + """Allow (whitelist) IP address(es). + + Connections from addresses not in the whitelist will be rejected. + + - For NULL, all clients from this address will be accepted. + - For real auth setups, they will be allowed to continue with authentication. + + whitelist is mutually exclusive with blacklist. + """ + if self.blacklist: + raise ValueError("Only use a whitelist or a blacklist, not both") + self.log.debug("Allowing %s", ','.join(addresses)) + self.whitelist.update(addresses) + + def deny(self, *addresses): + """Deny (blacklist) IP address(es). + + Addresses not in the blacklist will be allowed to continue with authentication. + + Blacklist is mutually exclusive with whitelist. + """ + if self.whitelist: + raise ValueError("Only use a whitelist or a blacklist, not both") + self.log.debug("Denying %s", ','.join(addresses)) + self.blacklist.update(addresses) + + def configure_plain(self, domain='*', passwords=None): + """Configure PLAIN authentication for a given domain. + + PLAIN authentication uses a plain-text password file. + To cover all domains, use "*". + You can modify the password file at any time; it is reloaded automatically. + """ + if passwords: + self.passwords[domain] = passwords + self.log.debug("Configure plain: %s", domain) + + def configure_curve(self, domain='*', location=None): + """Configure CURVE authentication for a given domain. + + CURVE authentication uses a directory that holds all public client certificates, + i.e. their public keys. + + To cover all domains, use "*". + + You can add and remove certificates in that directory at any time. configure_curve must be called + every time certificates are added or removed, in order to update the Authenticator's state + + To allow all client keys without checking, specify CURVE_ALLOW_ANY for the location. + """ + # If location is CURVE_ALLOW_ANY then allow all clients. Otherwise + # treat location as a directory that holds the certificates. + self.log.debug("Configure curve: %s[%s]", domain, location) + if location == CURVE_ALLOW_ANY: + self.allow_any = True + else: + self.allow_any = False + try: + self.certs[domain] = load_certificates(location) + except Exception as e: + self.log.error("Failed to load CURVE certs from %s: %s", location, e) + + def configure_curve_callback(self, domain='*', credentials_provider=None): + """Configure CURVE authentication for a given domain. + + CURVE authentication using a callback function validating + the client public key according to a custom mechanism, e.g. checking the + key against records in a db. credentials_provider is an object of a class which + implements a callback method accepting two parameters (domain and key), e.g.:: + + class CredentialsProvider(object): + + def __init__(self): + ...e.g. db connection + + def callback(self, domain, key): + valid = ...lookup key and/or domain in db + if valid: + logging.info('Authorizing: {0}, {1}'.format(domain, key)) + return True + else: + logging.warning('NOT Authorizing: {0}, {1}'.format(domain, key)) + return False + + To cover all domains, use "*". + + To allow all client keys without checking, specify CURVE_ALLOW_ANY for the location. + """ + + self.allow_any = False + + if credentials_provider is not None: + self.credentials_providers[domain] = credentials_provider + else: + self.log.error("None credentials_provider provided for domain:%s",domain) + + def curve_user_id(self, client_public_key): + """Return the User-Id corresponding to a CURVE client's public key + + Default implementation uses the z85-encoding of the public key. + + Override to define a custom mapping of public key : user-id + + This is only called on successful authentication. + + Parameters + ---------- + client_public_key: bytes + The client public key used for the given message + + Returns + ------- + user_id: unicode + The user ID as text + """ + return z85.encode(client_public_key).decode('ascii') + + def configure_gssapi(self, domain='*', location=None): + """Configure GSSAPI authentication + + Currently this is a no-op because there is nothing to configure with GSSAPI. + """ + pass + + def handle_zap_message(self, msg): + """Perform ZAP authentication""" + if len(msg) < 6: + self.log.error("Invalid ZAP message, not enough frames: %r", msg) + if len(msg) < 2: + self.log.error("Not enough information to reply") + else: + self._send_zap_reply(msg[1], b"400", b"Not enough frames") + return + + version, request_id, domain, address, identity, mechanism = msg[:6] + credentials = msg[6:] + + domain = u(domain, self.encoding, 'replace') + address = u(address, self.encoding, 'replace') + + if (version != VERSION): + self.log.error("Invalid ZAP version: %r", msg) + self._send_zap_reply(request_id, b"400", b"Invalid version") + return + + self.log.debug("version: %r, request_id: %r, domain: %r," + " address: %r, identity: %r, mechanism: %r", + version, request_id, domain, + address, identity, mechanism, + ) + + + # Is address is explicitly whitelisted or blacklisted? + allowed = False + denied = False + reason = b"NO ACCESS" + + if self.whitelist: + if address in self.whitelist: + allowed = True + self.log.debug("PASSED (whitelist) address=%s", address) + else: + denied = True + reason = b"Address not in whitelist" + self.log.debug("DENIED (not in whitelist) address=%s", address) + + elif self.blacklist: + if address in self.blacklist: + denied = True + reason = b"Address is blacklisted" + self.log.debug("DENIED (blacklist) address=%s", address) + else: + allowed = True + self.log.debug("PASSED (not in blacklist) address=%s", address) + + # Perform authentication mechanism-specific checks if necessary + username = u("anonymous") + if not denied: + + if mechanism == b'NULL' and not allowed: + # For NULL, we allow if the address wasn't blacklisted + self.log.debug("ALLOWED (NULL)") + allowed = True + + elif mechanism == b'PLAIN': + # For PLAIN, even a whitelisted address must authenticate + if len(credentials) != 2: + self.log.error("Invalid PLAIN credentials: %r", credentials) + self._send_zap_reply(request_id, b"400", b"Invalid credentials") + return + username, password = [ u(c, self.encoding, 'replace') for c in credentials ] + allowed, reason = self._authenticate_plain(domain, username, password) + + elif mechanism == b'CURVE': + # For CURVE, even a whitelisted address must authenticate + if len(credentials) != 1: + self.log.error("Invalid CURVE credentials: %r", credentials) + self._send_zap_reply(request_id, b"400", b"Invalid credentials") + return + key = credentials[0] + allowed, reason = self._authenticate_curve(domain, key) + if allowed: + username = self.curve_user_id(key) + + elif mechanism == b'GSSAPI': + if len(credentials) != 1: + self.log.error("Invalid GSSAPI credentials: %r", credentials) + self._send_zap_reply(request_id, b"400", b"Invalid credentials") + return + # use principal as user-id for now + principal = username = credentials[0] + allowed, reason = self._authenticate_gssapi(domain, principal) + + if allowed: + self._send_zap_reply(request_id, b"200", b"OK", username) + else: + self._send_zap_reply(request_id, b"400", reason) + + def _authenticate_plain(self, domain, username, password): + """PLAIN ZAP authentication""" + allowed = False + reason = b"" + if self.passwords: + # If no domain is not specified then use the default domain + if not domain: + domain = '*' + + if domain in self.passwords: + if username in self.passwords[domain]: + if password == self.passwords[domain][username]: + allowed = True + else: + reason = b"Invalid password" + else: + reason = b"Invalid username" + else: + reason = b"Invalid domain" + + if allowed: + self.log.debug("ALLOWED (PLAIN) domain=%s username=%s password=%s", + domain, username, password, + ) + else: + self.log.debug("DENIED %s", reason) + + else: + reason = b"No passwords defined" + self.log.debug("DENIED (PLAIN) %s", reason) + + return allowed, reason + + def _authenticate_curve(self, domain, client_key): + """CURVE ZAP authentication""" + allowed = False + reason = b"" + if self.allow_any: + allowed = True + reason = b"OK" + self.log.debug("ALLOWED (CURVE allow any client)") + elif self.credentials_providers != {}: + # If no explicit domain is specified then use the default domain + if not domain: + domain = '*' + + if domain in self.credentials_providers: + z85_client_key = z85.encode(client_key) + # Callback to check if key is Allowed + if (self.credentials_providers[domain].callback(domain, z85_client_key)): + allowed = True + reason = b"OK" + else: + reason = b"Unknown key" + + status = "ALLOWED" if allowed else "DENIED" + self.log.debug("%s (CURVE auth_callback) domain=%s client_key=%s", + status, domain, z85_client_key, + ) + else: + reason = b"Unknown domain" + else: + # If no explicit domain is specified then use the default domain + if not domain: + domain = '*' + + if domain in self.certs: + # The certs dict stores keys in z85 format, convert binary key to z85 bytes + z85_client_key = z85.encode(client_key) + if self.certs[domain].get(z85_client_key): + allowed = True + reason = b"OK" + else: + reason = b"Unknown key" + + status = "ALLOWED" if allowed else "DENIED" + self.log.debug("%s (CURVE) domain=%s client_key=%s", + status, domain, z85_client_key, + ) + else: + reason = b"Unknown domain" + + return allowed, reason + + def _authenticate_gssapi(self, domain, principal): + """Nothing to do for GSSAPI, which has already been handled by an external service.""" + self.log.debug("ALLOWED (GSSAPI) domain=%s principal=%s", domain, principal) + return True, b'OK' + + def _send_zap_reply(self, request_id, status_code, status_text, user_id='anonymous'): + """Send a ZAP reply to finish the authentication.""" + user_id = user_id if status_code == b'200' else b'' + if isinstance(user_id, unicode): + user_id = user_id.encode(self.encoding, 'replace') + metadata = b'' # not currently used + self.log.debug("ZAP reply code=%s text=%s", status_code, status_text) + reply = [VERSION, request_id, status_code, status_text, user_id, metadata] + self.zap_socket.send_multipart(reply) + +__all__ = ['Authenticator', 'CURVE_ALLOW_ANY'] diff --git a/.venv/lib/python3.8/site-packages/zmq/auth/certs.py b/.venv/lib/python3.8/site-packages/zmq/auth/certs.py new file mode 100644 index 00000000..d4febdb5 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/zmq/auth/certs.py @@ -0,0 +1,126 @@ +"""0MQ authentication related functions and classes.""" + +# Copyright (C) PyZMQ Developers +# Distributed under the terms of the Modified BSD License. + + +import datetime +import glob +import io +import os +import zmq +from zmq.utils.strtypes import bytes, unicode, b, u + + +_cert_secret_banner = u("""# **** Generated on {0} by pyzmq **** +# ZeroMQ CURVE **Secret** Certificate +# DO NOT PROVIDE THIS FILE TO OTHER USERS nor change its permissions. + +""") + +_cert_public_banner = u("""# **** Generated on {0} by pyzmq **** +# ZeroMQ CURVE Public Certificate +# Exchange securely, or use a secure mechanism to verify the contents +# of this file after exchange. Store public certificates in your home +# directory, in the .curve subdirectory. + +""") + +def _write_key_file(key_filename, banner, public_key, secret_key=None, metadata=None, encoding='utf-8'): + """Create a certificate file""" + if isinstance(public_key, bytes): + public_key = public_key.decode(encoding) + if isinstance(secret_key, bytes): + secret_key = secret_key.decode(encoding) + with io.open(key_filename, 'w', encoding='utf8') as f: + f.write(banner.format(datetime.datetime.now())) + + f.write(u('metadata\n')) + if metadata: + for k, v in metadata.items(): + if isinstance(k, bytes): + k = k.decode(encoding) + if isinstance(v, bytes): + v = v.decode(encoding) + f.write(u(" {0} = {1}\n").format(k, v)) + + f.write(u('curve\n')) + f.write(u(" public-key = \"{0}\"\n").format(public_key)) + + if secret_key: + f.write(u(" secret-key = \"{0}\"\n").format(secret_key)) + + +def create_certificates(key_dir, name, metadata=None): + """Create zmq certificates. + + Returns the file paths to the public and secret certificate files. + """ + public_key, secret_key = zmq.curve_keypair() + base_filename = os.path.join(key_dir, name) + secret_key_file = "{0}.key_secret".format(base_filename) + public_key_file = "{0}.key".format(base_filename) + now = datetime.datetime.now() + + _write_key_file(public_key_file, + _cert_public_banner.format(now), + public_key) + + _write_key_file(secret_key_file, + _cert_secret_banner.format(now), + public_key, + secret_key=secret_key, + metadata=metadata) + + return public_key_file, secret_key_file + + +def load_certificate(filename): + """Load public and secret key from a zmq certificate. + + Returns (public_key, secret_key) + + If the certificate file only contains the public key, + secret_key will be None. + + If there is no public key found in the file, ValueError will be raised. + """ + public_key = None + secret_key = None + if not os.path.exists(filename): + raise IOError("Invalid certificate file: {0}".format(filename)) + + with open(filename, 'rb') as f: + for line in f: + line = line.strip() + if line.startswith(b'#'): + continue + if line.startswith(b'public-key'): + public_key = line.split(b"=", 1)[1].strip(b' \t\'"') + if line.startswith(b'secret-key'): + secret_key = line.split(b"=", 1)[1].strip(b' \t\'"') + if public_key and secret_key: + break + + if public_key is None: + raise ValueError("No public key found in %s" % filename) + + return public_key, secret_key + + +def load_certificates(directory='.'): + """Load public keys from all certificates in a directory""" + certs = {} + if not os.path.isdir(directory): + raise IOError("Invalid certificate directory: {0}".format(directory)) + # Follow czmq pattern of public keys stored in *.key files. + glob_string = os.path.join(directory, "*.key") + + cert_files = glob.glob(glob_string) + for cert_file in cert_files: + public_key, _ = load_certificate(cert_file) + if public_key: + certs[public_key] = True + return certs + +__all__ = ['create_certificates', 'load_certificate', 'load_certificates'] diff --git a/.venv/lib/python3.8/site-packages/zmq/auth/ioloop.py b/.venv/lib/python3.8/site-packages/zmq/auth/ioloop.py new file mode 100644 index 00000000..c0579f20 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/zmq/auth/ioloop.py @@ -0,0 +1,35 @@ +"""ZAP Authenticator integrated with the tornado IOLoop. + +.. versionadded:: 14.1 +""" + +# Copyright (C) PyZMQ Developers +# Distributed under the terms of the Modified BSD License. + +from tornado import ioloop +from zmq.eventloop import zmqstream +from .base import Authenticator + + +class IOLoopAuthenticator(Authenticator): + """ZAP authentication for use in the tornado IOLoop""" + + def __init__(self, context=None, encoding='utf-8', log=None, io_loop=None): + super(IOLoopAuthenticator, self).__init__(context, encoding, log) + self.zap_stream = None + self.io_loop = io_loop or ioloop.IOLoop.current() + + def start(self): + """Start ZAP authentication""" + super(IOLoopAuthenticator, self).start() + self.zap_stream = zmqstream.ZMQStream(self.zap_socket, self.io_loop) + self.zap_stream.on_recv(self.handle_zap_message) + + def stop(self): + """Stop ZAP authentication""" + if self.zap_stream: + self.zap_stream.close() + self.zap_stream = None + super(IOLoopAuthenticator, self).stop() + +__all__ = ['IOLoopAuthenticator'] diff --git a/.venv/lib/python3.8/site-packages/zmq/auth/thread.py b/.venv/lib/python3.8/site-packages/zmq/auth/thread.py new file mode 100644 index 00000000..1360de2f --- /dev/null +++ b/.venv/lib/python3.8/site-packages/zmq/auth/thread.py @@ -0,0 +1,225 @@ +"""ZAP Authenticator in a Python Thread. + +.. versionadded:: 14.1 +""" + +# Copyright (C) PyZMQ Developers +# Distributed under the terms of the Modified BSD License. + +import logging +from threading import Thread, Event + +import zmq +from zmq.utils import jsonapi +from zmq.utils.strtypes import b, u +import sys + +from .base import Authenticator + +class AuthenticationThread(Thread): + """A Thread for running a zmq Authenticator + + This is run in the background by ThreadedAuthenticator + """ + + def __init__(self, context, endpoint, encoding='utf-8', log=None, authenticator=None): + super(AuthenticationThread, self).__init__() + self.context = context or zmq.Context.instance() + self.encoding = encoding + self.log = log = log or logging.getLogger('zmq.auth') + self.started = Event() + self.authenticator = authenticator or Authenticator(context, encoding=encoding, log=log) + + # create a socket to communicate back to main thread. + self.pipe = context.socket(zmq.PAIR) + self.pipe.linger = 1 + self.pipe.connect(endpoint) + + def run(self): + """Start the Authentication Agent thread task""" + self.authenticator.start() + self.started.set() + zap = self.authenticator.zap_socket + poller = zmq.Poller() + poller.register(self.pipe, zmq.POLLIN) + poller.register(zap, zmq.POLLIN) + while True: + try: + socks = dict(poller.poll()) + except zmq.ZMQError: + break # interrupted + + if self.pipe in socks and socks[self.pipe] == zmq.POLLIN: + # Make sure all API requests are processed before + # looking at the ZAP socket. + while True: + try: + msg = self.pipe.recv_multipart(flags=zmq.NOBLOCK) + except zmq.Again: + break + + terminate = self._handle_pipe(msg) + if terminate: + break + if terminate: + break + + if zap in socks and socks[zap] == zmq.POLLIN: + self._handle_zap() + + self.pipe.close() + self.authenticator.stop() + + def _handle_zap(self): + """ + Handle a message from the ZAP socket. + """ + msg = self.authenticator.zap_socket.recv_multipart() + if not msg: return + self.authenticator.handle_zap_message(msg) + + def _handle_pipe(self, msg): + """ + Handle a message from front-end API. + """ + terminate = False + + if msg is None: + terminate = True + return terminate + + command = msg[0] + self.log.debug("auth received API command %r", command) + + if command == b'ALLOW': + addresses = [u(m, self.encoding) for m in msg[1:]] + try: + self.authenticator.allow(*addresses) + except Exception as e: + self.log.exception("Failed to allow %s", addresses) + + elif command == b'DENY': + addresses = [u(m, self.encoding) for m in msg[1:]] + try: + self.authenticator.deny(*addresses) + except Exception as e: + self.log.exception("Failed to deny %s", addresses) + + elif command == b'PLAIN': + domain = u(msg[1], self.encoding) + json_passwords = msg[2] + self.authenticator.configure_plain(domain, jsonapi.loads(json_passwords)) + + elif command == b'CURVE': + # For now we don't do anything with domains + domain = u(msg[1], self.encoding) + + # If location is CURVE_ALLOW_ANY, allow all clients. Otherwise + # treat location as a directory that holds the certificates. + location = u(msg[2], self.encoding) + self.authenticator.configure_curve(domain, location) + + elif command == b'TERMINATE': + terminate = True + + else: + self.log.error("Invalid auth command from API: %r", command) + + return terminate + +def _inherit_docstrings(cls): + """inherit docstrings from Authenticator, so we don't duplicate them""" + for name, method in cls.__dict__.items(): + if name.startswith('_') or not callable(method): + continue + upstream_method = getattr(Authenticator, name, None) + if not method.__doc__: + method.__doc__ = upstream_method.__doc__ + return cls + +@_inherit_docstrings +class ThreadAuthenticator(object): + """Run ZAP authentication in a background thread""" + context = None + log = None + encoding = None + pipe = None + pipe_endpoint = '' + thread = None + auth = None + + def __init__(self, context=None, encoding='utf-8', log=None): + self.context = context or zmq.Context.instance() + self.log = log + self.encoding = encoding + self.pipe = None + self.pipe_endpoint = "inproc://{0}.inproc".format(id(self)) + self.thread = None + + # proxy base Authenticator attributes + + def __setattr__(self, key, value): + for obj in [self] + self.__class__.mro(): + if key in obj.__dict__: + object.__setattr__(self, key, value) + return + setattr(self.thread.authenticator, key, value) + + def __getattr__(self, key): + try: + object.__getattr__(self, key) + except AttributeError: + return getattr(self.thread.authenticator, key) + + def allow(self, *addresses): + self.pipe.send_multipart([b'ALLOW'] + [b(a, self.encoding) for a in addresses]) + + def deny(self, *addresses): + self.pipe.send_multipart([b'DENY'] + [b(a, self.encoding) for a in addresses]) + + def configure_plain(self, domain='*', passwords=None): + self.pipe.send_multipart([b'PLAIN', b(domain, self.encoding), jsonapi.dumps(passwords or {})]) + + def configure_curve(self, domain='*', location=''): + domain = b(domain, self.encoding) + location = b(location, self.encoding) + self.pipe.send_multipart([b'CURVE', domain, location]) + + def configure_curve_callback(self, domain='*', credentials_provider=None): + self.thread.authenticator.configure_curve_callback(domain, credentials_provider=credentials_provider) + + def start(self): + """Start the authentication thread""" + # create a socket to communicate with auth thread. + self.pipe = self.context.socket(zmq.PAIR) + self.pipe.linger = 1 + self.pipe.bind(self.pipe_endpoint) + self.thread = AuthenticationThread(self.context, self.pipe_endpoint, encoding=self.encoding, log=self.log) + self.thread.start() + # Event.wait:Changed in version 2.7: Previously, the method always returned None. + if sys.version_info < (2,7): + self.thread.started.wait(timeout=10) + else: + if not self.thread.started.wait(timeout=10): + raise RuntimeError("Authenticator thread failed to start") + + def stop(self): + """Stop the authentication thread""" + if self.pipe: + self.pipe.send(b'TERMINATE') + if self.is_alive(): + self.thread.join() + self.thread = None + self.pipe.close() + self.pipe = None + + def is_alive(self): + """Is the ZAP thread currently running?""" + if self.thread and self.thread.is_alive(): + return True + return False + + def __del__(self): + self.stop() + +__all__ = ['ThreadAuthenticator'] diff --git a/.venv/lib/python3.8/site-packages/zmq/backend/__init__.py b/.venv/lib/python3.8/site-packages/zmq/backend/__init__.py new file mode 100644 index 00000000..1929153f --- /dev/null +++ b/.venv/lib/python3.8/site-packages/zmq/backend/__init__.py @@ -0,0 +1,44 @@ +"""Import basic exposure of libzmq C API as a backend""" + +# Copyright (C) PyZMQ Developers +# Distributed under the terms of the Modified BSD License. + + +import os +import platform +import sys + +from .select import public_api, select_backend + +if 'PYZMQ_BACKEND' in os.environ: + backend = os.environ['PYZMQ_BACKEND'] + if backend in ('cython', 'cffi'): + backend = 'zmq.backend.%s' % backend + _ns = select_backend(backend) +else: + # default to cython, fallback to cffi + # (reverse on PyPy) + if platform.python_implementation() == 'PyPy': + first, second = ('zmq.backend.cffi', 'zmq.backend.cython') + else: + first, second = ('zmq.backend.cython', 'zmq.backend.cffi') + + try: + _ns = select_backend(first) + except Exception: + exc_info = sys.exc_info() + exc = exc_info[1] + try: + _ns = select_backend(second) + except ImportError: + # prevent 'During handling of the above exception...' on py3 + # can't use `raise ... from` on Python 2 + if hasattr(exc, '__cause__'): + exc.__cause__ = None + # raise the *first* error, not the fallback + from zmq.utils.sixcerpt import reraise + reraise(*exc_info) + +globals().update(_ns) + +__all__ = public_api diff --git a/.venv/lib/python3.8/site-packages/zmq/backend/__pycache__/__init__.cpython-38.pyc b/.venv/lib/python3.8/site-packages/zmq/backend/__pycache__/__init__.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7bb701c1ce16927f4f014f9cc14594ba40f512a4 GIT binary patch literal 882 zcmY*Wzi$&U6t;aobGf9Uqy;2~TNpAlkr0)Ngb<~4s1Q{ULV$&2UC$16b3crIfg}@B zcSh!RN1tMMkMo;FANLJUpLM?)zIUKRZ&#LWoPx7W z);fpg-ov*jdIbiZ<^6*~RI*NvQpK}`%|)eVk|ot7$@$T;_?YY^yW@i-RY__v*_4&^ z!p`*Y!psm1kdDOcDCZeT1=n50a+cL(1;m~4JN)7$dAhszeE;y-0AW8{)W=nc-E1=9 z%dX)cuCT*3rHS}5&biIt9JaV<;0%1>NYr4Ifz;E+=34bc=Nybw7nSXrkv zHz04qrK&AWR+Ut@_U9QB%}vPW8R6xm(vFFA`)b7dQdUw2$Eix|TFTH=#7$qbn&)b$ zxcOg-TDBS~AM)xb&5g>LplQu)CuyD&@*T*#R^7Muaw6!X81_+&{sM@`^m_mR literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/zmq/backend/__pycache__/select.cpython-38.pyc b/.venv/lib/python3.8/site-packages/zmq/backend/__pycache__/select.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..243a375a97de5a5f9935344b197f5a121dfc2cfa GIT binary patch literal 965 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 WB_D!r5OA{#j@kqqCbnbS_V905@Z|~s literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/zmq/backend/cffi/__pycache__/constants.cpython-38.pyc b/.venv/lib/python3.8/site-packages/zmq/backend/cffi/__pycache__/constants.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..65d718e74749eaa0739c9b4588c9b0e1a01f3c7b GIT binary patch literal 493 zcmY+9%Sr<=6o!+`OlLaU%R*3hZY#92>Ov@@SPCu_uL}bb#>uf(Gt=oL#kMO!d=Fjv zLN2m()mLz3QmN>H{N!9X|937cl@OWmo<100gg$NZH(ZnKnI|(N98ttECjzI0lGLFN zM%>}9a8r+Z7(wY7Q6HQxx^B?`g4Z(l-f+=_fS0)cLN*Z%GZz9H!U_-wo(cF6cF<@W z$o(p<@Su;uTSv6Y{d3eP&nmNYw3Q4qsp3q@xdB8CqVa*QCu~_}S)78Ln-*$dU5TtXZyViwtsTisA-=uK1>*+9!qX-2L&-Bg=2(n7{At74TNm{Utf5p zt^K|j-o!#`+}B=WeRXKi3MC&0>Q1|hir)tnD^<|i$(1GebuRqH4#q4Zdq+jx`dazg zjZ~UP`56+^Ls=lgy+UbM@hWGnl;*SO)f8*xn zaAC6s(>wzq2`7?DmeP!ImO0#^xOY-F^SGD!+|L@k0qbwi-j%@<(rbAD)!{_E!JV#?D*NC7=@UAAjD^y3pkZTVPA;(aIea#fL)2F@AD$IIvlRSpijqQvk~(32(`^?7(kZcI6!Wb|eL$3uR*pvcIVjV2roU2ChAr>oCm_#DwWjExDkQPS_=z z5Wyr$Cy%6qzY{9mL(hC`UF)6E*VOtKjZ1=h6LP>TIS3A!-hos9qIn74y#_mG4|ZX7 z-kQ)$Od#57O9K9R{jvY5NM!W&?xqGdkX}clSEU;dj4cBJX%ewLE*rw^4`gwq131;l z5zRpG)>J{{>WI7jr`y}SiLW3Pc~M@S8f7&i1v_zC7$qThu2Jb850gUJeXR!4aKFCe z4bgW%_n-SKHXE)Cli|`R9}eO}C6|u&l}eY6SC5ZRR=;0eftyyI<4G=8Vj#^*Tr+BU zcmlqQBu}gmcfpqV7zAN1?b3kxGyoaWHasq!r{no)j+SSi#F(nt!1Yy@&@oFay#S^_ zOr1-1hIwY=Z+7=pG>}p&W1?a&valWHQt9+0$zMci@*JFvrv3raWUPekxuuijwhFm! zgK6CX@rLRJT;pA}KnP`cZSE`B8;n13#&>4UUmyR+eS}bv%!dWIjj5;o9@X=(*B_#| zb(ud+6CBkSv2k~HQGN6dlaUZtG5Q=f$YSK&1exrdI@XyuXB3-96|H+fh-feiM^p@L zQsiM6O@~n`nh^^$uip22Zbdsihc08RG&VDMivcVB+D_@c8l)ptG9BNB<$$#%P&Mc< z@gVoD87er5tB~Re3@iiGs^az~EUqD4vQq|tfC7^J$taX9fO5v)y#P?t4F4}A(7S@P z*`xd}R7;`7QDXOtk*#ZIiuAg`;G-Leoth$_fM5DE6u0u{fch%DH<)qab%E;FP~q$y ziXd#P>k8^)SRh4oh#dl%Uh$ls(sA3m6N*{&% zg*|T1(us;-37OyTb+H@dgG>oghC*b89HqE!3-NL^Nb8fz7aoeFnD(Q(I=Wy%FM=q8 zp)Q6>+Y|i}zN=6n*Yy`DkRms-P~`*bR<}SPRjVEpK*y;b7A`Ovx-gv}2%42vzc&XB zQph3}f_nlxT1|K4V%Y?089T_WsrxV1o5u839e26nP~D!ZP-0;~MLa)Hv8}A5Y4}SN Z;(cD0!TmZa50DH7KX$!&wg}Js+P?zB%{2f3 literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/zmq/backend/cffi/__pycache__/devices.cpython-38.pyc b/.venv/lib/python3.8/site-packages/zmq/backend/cffi/__pycache__/devices.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7d78d9d3e810a364669255b0ae1e6653a16402d0 GIT binary patch literal 1511 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 ToNkfTEU)HOz1rMg7=QkMHazl- literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/zmq/backend/cffi/__pycache__/utils.cpython-38.pyc b/.venv/lib/python3.8/site-packages/zmq/backend/cffi/__pycache__/utils.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a02f4c1f6d6b82fc9e08572c93199ddb22fbe4b2 GIT binary patch literal 2319 zcma)7OK;mo5ayDUL^1LcNt^VA?a3x!Nl9P_sZkUK3?Fi++ve4lML|&9l|`5@FPBy% zC_n+XhhF*{dcakWFSGZ#18j4J3HSuv(HvmYz<1|*MGdRrD^|R zXSo>A`5J02KrqeK7-4!uV%^n=#tddgMr^uf+;AJvC#(@QQ@9Sc9p!sPf8EYloPHVz*hJ$-yhu&0;Ca2S^4z%fh9{pR~aAyQG^dXz{m zM3G6(o=kGd;{!j6%C;AbcyQv0pj@q+XI$iAnt;|;k%U3Ycz}AZ3bswC2T=1J5K{T& z9DE|lOq2S#E=$B}_ zKxn5e*wh>Od1)4M_|R#IHjI{bn1@L&{UqQ5`B64`f=(#SL7GOQ0YfhC^kAn$TzheW zzcsNAv#<91GS2#0n01RJ^Me!4y5kY&QTN5(ix-o>mRTSOXjbEeJ6h5k~PjhTK<5UdIo zX0pcb`kkszF344Xr~_Qh;wIpI%o8qr$*E7>hkNvdPclCg3c@1ibR5bNV%a-*_W1cB z%{f2@crFlo%ukC@@Vo|!ZvXqoUv#&3*P$|{Bma!k0p|%F6k#MQZMCK%%TghG%bH{% zl3WdRtD@T5Suu#hUBGHlg*{u=RG9-zLJ%%>5ao&@saNZGWd$Q&{QO||m!r#Vn68;65U|on__!j` z29oI7MuDK0%|S67a^Vq^aEf60=%{w48yCO`7SVYZSi`;9Z zIfB(vgLownuQwrHbq3%=yc!JXqoUcIH<$@yL^kKG8N{}tk5$vhoVS5cko8y-=>ueG z6)BK~9;9(rfJf!R(cl;wqyi|Ar3nK#5O{yt_g7?6Xuge5YVs{)y8qr}Qd++A1*96t zh}XCTj8e0;zg7D+XBI@EKob8QG^uTUGhG+FyncitF;ek;PN;Y&5O+rxH{d63f+#x` zrz-A<4`Ap>e29x|v4V>*sfkq-nC}!T#cgb<)V980Wvu~8Dei!941r7&AEEdJ1*W?t zE`AE#F4P>gYiku3ZKBwSbJy62(SWMIg_=JAfeGqQ?WHm8051(pQ9o#>_f25vi7j@B zhTl)xsj5H1%qhG(z&d@}kNp$OO#wV;I~2lSOps#XkcNvlugWXxnLGk_sY|usRCpxG zurz&foR`g$G5+6lw{p!>ioJZ2dw9?xnyq5au!s(KTqU+HK8MjGXR~a19!mqyD;x0U zCaJ(I;Wj+X^_9bwuiKb3VF5%&6BY=xr?L!@aW`?gdKn;z$w|iZ3OsxcRCo*YsyY-; q1gku62@{15CW+GeGEP|$@vqR19JiZ|j=rwnCLP1-Sew>utMfm)$3uw# literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/zmq/backend/cffi/_cdefs.h b/.venv/lib/python3.8/site-packages/zmq/backend/cffi/_cdefs.h new file mode 100644 index 00000000..ffaedc76 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/zmq/backend/cffi/_cdefs.h @@ -0,0 +1,70 @@ +void zmq_version(int *major, int *minor, int *patch); + +void* zmq_socket(void *context, int type); +int zmq_close(void *socket); + +int zmq_bind(void *socket, const char *endpoint); +int zmq_connect(void *socket, const char *endpoint); + +int zmq_errno(void); +const char * zmq_strerror(int errnum); + +int zmq_device(int device, void *frontend, void *backend); + +int zmq_unbind(void *socket, const char *endpoint); +int zmq_disconnect(void *socket, const char *endpoint); +void* zmq_ctx_new(); +int zmq_ctx_destroy(void *context); +int zmq_ctx_get(void *context, int opt); +int zmq_ctx_set(void *context, int opt, int optval); +int zmq_proxy(void *frontend, void *backend, void *capture); +int zmq_proxy_steerable(void *frontend, + void *backend, + void *capture, + void *control); +int zmq_socket_monitor(void *socket, const char *addr, int events); + +int zmq_curve_keypair (char *z85_public_key, char *z85_secret_key); +int zmq_curve_public (char *z85_public_key, char *z85_secret_key); +int zmq_has (const char *capability); + +typedef struct { ...; } zmq_msg_t; +typedef ... zmq_free_fn; + +int zmq_msg_init(zmq_msg_t *msg); +int zmq_msg_init_size(zmq_msg_t *msg, size_t size); +int zmq_msg_init_data(zmq_msg_t *msg, + void *data, + size_t size, + zmq_free_fn *ffn, + void *hint); + +size_t zmq_msg_size(zmq_msg_t *msg); +void *zmq_msg_data(zmq_msg_t *msg); +int zmq_msg_close(zmq_msg_t *msg); + +int zmq_msg_send(zmq_msg_t *msg, void *socket, int flags); +int zmq_msg_recv(zmq_msg_t *msg, void *socket, int flags); + +int zmq_getsockopt(void *socket, + int option_name, + void *option_value, + size_t *option_len); + +int zmq_setsockopt(void *socket, + int option_name, + const void *option_value, + size_t option_len); +typedef struct +{ + void *socket; + int fd; + short events; + short revents; +} zmq_pollitem_t; + +int zmq_poll(zmq_pollitem_t *items, int nitems, long timeout); + +// miscellany +void * memcpy(void *restrict s1, const void *restrict s2, size_t n); +int get_ipc_path_max_len(void); diff --git a/.venv/lib/python3.8/site-packages/zmq/backend/cffi/_cffi.py b/.venv/lib/python3.8/site-packages/zmq/backend/cffi/_cffi.py new file mode 100644 index 00000000..3fcf0721 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/zmq/backend/cffi/_cffi.py @@ -0,0 +1,127 @@ +# coding: utf-8 +"""The main CFFI wrapping of libzmq""" + +# Copyright (C) PyZMQ Developers +# Distributed under the terms of the Modified BSD License. + + +import json +import os +from os.path import dirname, join +from cffi import FFI + +from zmq.utils.constant_names import all_names, no_prefix + + +base_zmq_version = (3,2,2) + +def load_compiler_config(): + """load pyzmq compiler arguments""" + import zmq + zmq_dir = dirname(zmq.__file__) + zmq_parent = dirname(zmq_dir) + + fname = join(zmq_dir, 'utils', 'compiler.json') + if os.path.exists(fname): + with open(fname) as f: + cfg = json.load(f) + else: + cfg = {} + + cfg.setdefault("include_dirs", []) + cfg.setdefault("library_dirs", []) + cfg.setdefault("runtime_library_dirs", []) + cfg.setdefault("libraries", ["zmq"]) + + # cast to str, because cffi can't handle unicode paths (?!) + cfg['libraries'] = [str(lib) for lib in cfg['libraries']] + for key in ("include_dirs", "library_dirs", "runtime_library_dirs"): + # interpret paths relative to parent of zmq (like source tree) + abs_paths = [] + for p in cfg[key]: + if p.startswith('zmq'): + p = join(zmq_parent, p) + abs_paths.append(str(p)) + cfg[key] = abs_paths + return cfg + + +def zmq_version_info(): + """Get libzmq version as tuple of ints""" + major = ffi.new('int*') + minor = ffi.new('int*') + patch = ffi.new('int*') + + C.zmq_version(major, minor, patch) + + return (int(major[0]), int(minor[0]), int(patch[0])) + + +cfg = load_compiler_config() +ffi = FFI() + +def _make_defines(names): + _names = [] + for name in names: + define_line = "#define %s ..." % (name) + _names.append(define_line) + + return "\n".join(_names) + +c_constant_names = ['PYZMQ_DRAFT_API'] +for name in all_names: + if no_prefix(name): + c_constant_names.append(name) + else: + c_constant_names.append("ZMQ_" + name) + +# load ffi definitions +here = os.path.dirname(__file__) +with open(os.path.join(here, '_cdefs.h')) as f: + _cdefs = f.read() + +with open(os.path.join(here, '_verify.c')) as f: + _verify = f.read() + +ffi.cdef(_cdefs) +ffi.cdef(_make_defines(c_constant_names)) + +try: + C = ffi.verify(_verify, + modulename='_cffi_ext', + libraries=cfg['libraries'], + include_dirs=cfg['include_dirs'], + library_dirs=cfg['library_dirs'], + runtime_library_dirs=cfg['runtime_library_dirs'], + ) + _version_info = zmq_version_info() +except Exception as e: + raise ImportError("PyZMQ CFFI backend couldn't find zeromq: %s\n" + "Please check that you have zeromq headers and libraries." % e) + +if _version_info < (3,2,2): + raise ImportError("PyZMQ CFFI backend requires zeromq >= 3.2.2," + " but found %i.%i.%i" % _version_info + ) + +nsp = new_sizet_pointer = lambda length: ffi.new('size_t*', length) + +new_uint64_pointer = lambda: (ffi.new('uint64_t*'), + nsp(ffi.sizeof('uint64_t'))) +new_int64_pointer = lambda: (ffi.new('int64_t*'), + nsp(ffi.sizeof('int64_t'))) +new_int_pointer = lambda: (ffi.new('int*'), + nsp(ffi.sizeof('int'))) +new_binary_data = lambda length: (ffi.new('char[%d]' % (length)), + nsp(ffi.sizeof('char') * length)) + +value_uint64_pointer = lambda val : (ffi.new('uint64_t*', val), + ffi.sizeof('uint64_t')) +value_int64_pointer = lambda val: (ffi.new('int64_t*', val), + ffi.sizeof('int64_t')) +value_int_pointer = lambda val: (ffi.new('int*', val), + ffi.sizeof('int')) +value_binary_data = lambda val, length: (ffi.new('char[%d]' % (length + 1), val), + ffi.sizeof('char') * length) + +IPC_PATH_MAX_LEN = C.get_ipc_path_max_len() diff --git a/.venv/lib/python3.8/site-packages/zmq/backend/cffi/_poll.py b/.venv/lib/python3.8/site-packages/zmq/backend/cffi/_poll.py new file mode 100644 index 00000000..a346eeda --- /dev/null +++ b/.venv/lib/python3.8/site-packages/zmq/backend/cffi/_poll.py @@ -0,0 +1,80 @@ +# coding: utf-8 +"""zmq poll function""" + +# Copyright (C) PyZMQ Developers +# Distributed under the terms of the Modified BSD License. + +try: + from time import monotonic +except ImportError: + from time import clock as monotonic +import warnings + +from ._cffi import C, ffi +from zmq.error import InterruptedSystemCall, _check_rc + +def _make_zmq_pollitem(socket, flags): + zmq_socket = socket._zmq_socket + zmq_pollitem = ffi.new('zmq_pollitem_t*') + zmq_pollitem.socket = zmq_socket + zmq_pollitem.fd = 0 + zmq_pollitem.events = flags + zmq_pollitem.revents = 0 + return zmq_pollitem[0] + +def _make_zmq_pollitem_fromfd(socket_fd, flags): + zmq_pollitem = ffi.new('zmq_pollitem_t*') + zmq_pollitem.socket = ffi.NULL + zmq_pollitem.fd = socket_fd + zmq_pollitem.events = flags + zmq_pollitem.revents = 0 + return zmq_pollitem[0] + +def zmq_poll(sockets, timeout): + cffi_pollitem_list = [] + low_level_to_socket_obj = {} + from zmq import Socket + for item in sockets: + if isinstance(item[0], Socket): + low_level_to_socket_obj[item[0]._zmq_socket] = item + cffi_pollitem_list.append(_make_zmq_pollitem(item[0], item[1])) + else: + if not isinstance(item[0], int): + # not an FD, get it from fileno() + item = (item[0].fileno(), item[1]) + low_level_to_socket_obj[item[0]] = item + cffi_pollitem_list.append(_make_zmq_pollitem_fromfd(item[0], item[1])) + items = ffi.new('zmq_pollitem_t[]', cffi_pollitem_list) + list_length = ffi.cast('int', len(cffi_pollitem_list)) + while True: + c_timeout = ffi.cast('long', timeout) + start = monotonic() + rc = C.zmq_poll(items, list_length, c_timeout) + try: + _check_rc(rc) + except InterruptedSystemCall: + if timeout > 0: + ms_passed = int(1000 * (monotonic() - start)) + if ms_passed < 0: + # don't allow negative ms_passed, + # which can happen on old Python versions without time.monotonic. + warnings.warn( + "Negative elapsed time for interrupted poll: %s." + " Did the clock change?" % ms_passed, + RuntimeWarning) + ms_passed = 0 + timeout = max(0, timeout - ms_passed) + continue + else: + break + result = [] + for index in range(len(items)): + if items[index].revents > 0: + if not items[index].socket == ffi.NULL: + result.append((low_level_to_socket_obj[items[index].socket][0], + items[index].revents)) + else: + result.append((items[index].fd, items[index].revents)) + return result + +__all__ = ['zmq_poll'] diff --git a/.venv/lib/python3.8/site-packages/zmq/backend/cffi/_verify.c b/.venv/lib/python3.8/site-packages/zmq/backend/cffi/_verify.c new file mode 100644 index 00000000..37c338ad --- /dev/null +++ b/.venv/lib/python3.8/site-packages/zmq/backend/cffi/_verify.c @@ -0,0 +1,7 @@ +#include +#include + +#include +#include "zmq_compat.h" + +#include "ipcmaxlen.h" diff --git a/.venv/lib/python3.8/site-packages/zmq/backend/cffi/constants.py b/.venv/lib/python3.8/site-packages/zmq/backend/cffi/constants.py new file mode 100644 index 00000000..b33ad870 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/zmq/backend/cffi/constants.py @@ -0,0 +1,16 @@ +# coding: utf-8 +"""zmq constants""" + +from ._cffi import C, c_constant_names +from zmq.utils.constant_names import all_names + +g = globals() +for cname in c_constant_names: + if cname.startswith("ZMQ_"): + name = cname[4:] + else: + name = cname + g[name] = getattr(C, cname) + +DRAFT_API = C.PYZMQ_DRAFT_API +__all__ = ['DRAFT_API'] + all_names diff --git a/.venv/lib/python3.8/site-packages/zmq/backend/cffi/context.py b/.venv/lib/python3.8/site-packages/zmq/backend/cffi/context.py new file mode 100644 index 00000000..a9e8ae6e --- /dev/null +++ b/.venv/lib/python3.8/site-packages/zmq/backend/cffi/context.py @@ -0,0 +1,77 @@ +# coding: utf-8 +"""zmq Context class""" + +# Copyright (C) PyZMQ Developers +# Distributed under the terms of the Modified BSD License. + +from ._cffi import C, ffi + +from .constants import EINVAL, IO_THREADS, LINGER + +from zmq.error import ZMQError, InterruptedSystemCall, _check_rc + +class Context(object): + _zmq_ctx = None + _iothreads = None + _closed = None + _shadow = False + + def __init__(self, io_threads=1, shadow=None): + + if shadow: + self._zmq_ctx = ffi.cast("void *", shadow) + self._shadow = True + else: + self._shadow = False + if not io_threads >= 0: + raise ZMQError(EINVAL) + + self._zmq_ctx = C.zmq_ctx_new() + if self._zmq_ctx == ffi.NULL: + raise ZMQError(C.zmq_errno()) + if not shadow: + C.zmq_ctx_set(self._zmq_ctx, IO_THREADS, io_threads) + self._closed = False + + @property + def underlying(self): + """The address of the underlying libzmq context""" + return int(ffi.cast('size_t', self._zmq_ctx)) + + @property + def closed(self): + return self._closed + + def set(self, option, value): + """set a context option + + see zmq_ctx_set + """ + rc = C.zmq_ctx_set(self._zmq_ctx, option, value) + _check_rc(rc) + + def get(self, option): + """get context option + + see zmq_ctx_get + """ + rc = C.zmq_ctx_get(self._zmq_ctx, option) + _check_rc(rc, error_without_errno=False) + return rc + + def term(self): + if self.closed: + return + + rc = C.zmq_ctx_destroy(self._zmq_ctx) + try: + _check_rc(rc) + except InterruptedSystemCall: + # ignore interrupted term + # see PEP 475 notes about close & EINTR for why + pass + + self._zmq_ctx = None + self._closed = True + +__all__ = ['Context'] diff --git a/.venv/lib/python3.8/site-packages/zmq/backend/cffi/devices.py b/.venv/lib/python3.8/site-packages/zmq/backend/cffi/devices.py new file mode 100644 index 00000000..a107f8cf --- /dev/null +++ b/.venv/lib/python3.8/site-packages/zmq/backend/cffi/devices.py @@ -0,0 +1,68 @@ +# coding: utf-8 +"""zmq device functions""" + +# Copyright (C) PyZMQ Developers +# Distributed under the terms of the Modified BSD License. + +from ._cffi import C, ffi +from .socket import Socket +from .utils import _retry_sys_call + + +def device(device_type, frontend, backend): + return proxy(frontend, backend) + + +def proxy(frontend, backend, capture=None): + if isinstance(capture, Socket): + capture = capture._zmq_socket + else: + capture = ffi.NULL + + _retry_sys_call( + C.zmq_proxy, + frontend._zmq_socket, + backend._zmq_socket, + capture + ) + + +def proxy_steerable(frontend, backend, capture=None, control=None): + """proxy_steerable(frontend, backend, capture, control) + + Start a zeromq proxy with control flow. + + .. versionadded:: libzmq-4.1 + .. versionadded:: 18.0 + + Parameters + ---------- + frontend : Socket + The Socket instance for the incoming traffic. + backend : Socket + The Socket instance for the outbound traffic. + capture : Socket (optional) + The Socket instance for capturing traffic. + control : Socket (optional) + The Socket instance for control flow. + """ + if isinstance(capture, Socket): + capture = capture._zmq_socket + else: + capture = ffi.NULL + + if isinstance(control, Socket): + control = control._zmq_socket + else: + control = ffi.NULL + + _retry_sys_call( + C.zmq_proxy_steerable, + frontend._zmq_socket, + backend._zmq_socket, + capture, + control + ) + + +__all__ = ['device', 'proxy', 'proxy_steerable'] diff --git a/.venv/lib/python3.8/site-packages/zmq/backend/cffi/error.py b/.venv/lib/python3.8/site-packages/zmq/backend/cffi/error.py new file mode 100644 index 00000000..a3d6bfc0 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/zmq/backend/cffi/error.py @@ -0,0 +1,17 @@ +"""zmq error functions""" + +# Copyright (C) PyZMQ Developers +# Distributed under the terms of the Modified BSD License. + +from ._cffi import C, ffi + +def strerror(errno): + s = ffi.string(C.zmq_strerror(errno)) + if not isinstance(s, str): + # py3 + s = s.decode() + return s + +zmq_errno = C.zmq_errno + +__all__ = ['strerror', 'zmq_errno'] diff --git a/.venv/lib/python3.8/site-packages/zmq/backend/cffi/message.py b/.venv/lib/python3.8/site-packages/zmq/backend/cffi/message.py new file mode 100644 index 00000000..1b2af3d4 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/zmq/backend/cffi/message.py @@ -0,0 +1,64 @@ +"""Dummy Frame object""" + +# Copyright (C) PyZMQ Developers +# Distributed under the terms of the Modified BSD License. + +from ._cffi import ffi, C + +import zmq +from zmq.utils.strtypes import unicode + +_content = lambda x: x.tobytes() if type(x) == memoryview else x + +class Frame(object): + _data = None + tracker = None + closed = False + more = False + buffer = None + + + def __init__(self, data, track=False, copy=None, copy_threshold=None): + try: + memoryview(data) + except TypeError: + raise + + self._data = data + + if isinstance(data, unicode): + raise TypeError("Unicode objects not allowed. Only: str/bytes, " + + "buffer interfaces.") + + self.more = False + self.tracker = None + self.closed = False + if track: + self.tracker = zmq._FINISHED_TRACKER + + self.buffer = memoryview(self.bytes) + + @property + def bytes(self): + data = _content(self._data) + return data + + def __len__(self): + return len(self.bytes) + + def __eq__(self, other): + return self.bytes == _content(other) + + def __str__(self): + if str is unicode: + return self.bytes.decode() + else: + return self.bytes + + @property + def done(self): + return True + +Message = Frame + +__all__ = ['Frame', 'Message'] diff --git a/.venv/lib/python3.8/site-packages/zmq/backend/cffi/socket.py b/.venv/lib/python3.8/site-packages/zmq/backend/cffi/socket.py new file mode 100644 index 00000000..fbe22440 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/zmq/backend/cffi/socket.py @@ -0,0 +1,279 @@ +# coding: utf-8 +"""zmq Socket class""" + +# Copyright (C) PyZMQ Developers +# Distributed under the terms of the Modified BSD License. + +import errno as errno_mod + +from ._cffi import (C, ffi, new_uint64_pointer, new_int64_pointer, + new_int_pointer, new_binary_data, value_uint64_pointer, + value_int64_pointer, value_int_pointer, value_binary_data, + IPC_PATH_MAX_LEN) + +from .message import Frame +from .constants import RCVMORE +from .utils import _retry_sys_call + +import zmq +from zmq.error import ZMQError, _check_rc, _check_version +from zmq.utils.strtypes import unicode + + +def new_pointer_from_opt(option, length=0): + from zmq.sugar.constants import ( + int64_sockopts, bytes_sockopts, + ) + if option in int64_sockopts: + return new_int64_pointer() + elif option in bytes_sockopts: + return new_binary_data(length) + else: + # default + return new_int_pointer() + +def value_from_opt_pointer(option, opt_pointer, length=0): + from zmq.sugar.constants import ( + int64_sockopts, bytes_sockopts, + ) + if option in int64_sockopts: + return int(opt_pointer[0]) + elif option in bytes_sockopts: + return ffi.buffer(opt_pointer, length)[:] + else: + return int(opt_pointer[0]) + +def initialize_opt_pointer(option, value, length=0): + from zmq.sugar.constants import ( + int64_sockopts, bytes_sockopts, + ) + if option in int64_sockopts: + return value_int64_pointer(value) + elif option in bytes_sockopts: + return value_binary_data(value, length) + else: + return value_int_pointer(value) + + +class Socket(object): + context = None + socket_type = None + _zmq_socket = None + _closed = None + _ref = None + _shadow = False + copy_threshold = 0 + + def __init__(self, context=None, socket_type=None, shadow=None): + self.context = context + if shadow is not None: + if isinstance(shadow, Socket): + shadow = shadow.underlying + self._zmq_socket = ffi.cast("void *", shadow) + self._shadow = True + else: + self._shadow = False + self._zmq_socket = C.zmq_socket(context._zmq_ctx, socket_type) + if self._zmq_socket == ffi.NULL: + raise ZMQError() + self._closed = False + + @property + def underlying(self): + """The address of the underlying libzmq socket""" + return int(ffi.cast('size_t', self._zmq_socket)) + + def _check_closed_deep(self): + """thorough check of whether the socket has been closed, + even if by another entity (e.g. ctx.destroy). + + Only used by the `closed` property. + + returns True if closed, False otherwise + """ + if self._closed: + return True + try: + self.get(zmq.TYPE) + except ZMQError as e: + if e.errno == zmq.ENOTSOCK: + self._closed = True + return True + else: + raise + return False + + @property + def closed(self): + return self._check_closed_deep() + + def close(self, linger=None): + rc = 0 + if not self._closed and hasattr(self, '_zmq_socket'): + if self._zmq_socket is not None: + if linger is not None: + self.set(zmq.LINGER, linger) + rc = C.zmq_close(self._zmq_socket) + self._closed = True + if rc < 0: + _check_rc(rc) + + def bind(self, address): + if isinstance(address, unicode): + address = address.encode('utf8') + rc = C.zmq_bind(self._zmq_socket, address) + if rc < 0: + if IPC_PATH_MAX_LEN and C.zmq_errno() == errno_mod.ENAMETOOLONG: + # py3compat: address is bytes, but msg wants str + if str is unicode: + address = address.decode('utf-8', 'replace') + path = address.split('://', 1)[-1] + msg = ('ipc path "{0}" is longer than {1} ' + 'characters (sizeof(sockaddr_un.sun_path)).' + .format(path, IPC_PATH_MAX_LEN)) + raise ZMQError(C.zmq_errno(), msg=msg) + elif C.zmq_errno() == errno_mod.ENOENT: + # py3compat: address is bytes, but msg wants str + if str is unicode: + address = address.decode('utf-8', 'replace') + path = address.split('://', 1)[-1] + msg = ('No such file or directory for ipc path "{0}".'.format( + path)) + raise ZMQError(C.zmq_errno(), msg=msg) + else: + _check_rc(rc) + + def unbind(self, address): + _check_version((3,2), "unbind") + if isinstance(address, unicode): + address = address.encode('utf8') + rc = C.zmq_unbind(self._zmq_socket, address) + _check_rc(rc) + + def connect(self, address): + if isinstance(address, unicode): + address = address.encode('utf8') + rc = C.zmq_connect(self._zmq_socket, address) + _check_rc(rc) + + def disconnect(self, address): + _check_version((3,2), "disconnect") + if isinstance(address, unicode): + address = address.encode('utf8') + rc = C.zmq_disconnect(self._zmq_socket, address) + _check_rc(rc) + + def set(self, option, value): + length = None + if isinstance(value, unicode): + raise TypeError("unicode not allowed, use bytes") + + if isinstance(value, bytes): + if option not in zmq.constants.bytes_sockopts: + raise TypeError("not a bytes sockopt: %s" % option) + length = len(value) + + c_data = initialize_opt_pointer(option, value, length) + + c_value_pointer = c_data[0] + c_sizet = c_data[1] + + _retry_sys_call(C.zmq_setsockopt, + self._zmq_socket, + option, + ffi.cast('void*', c_value_pointer), + c_sizet) + + def get(self, option): + c_data = new_pointer_from_opt(option, length=255) + + c_value_pointer = c_data[0] + c_sizet_pointer = c_data[1] + + _retry_sys_call(C.zmq_getsockopt, + self._zmq_socket, + option, + c_value_pointer, + c_sizet_pointer) + + sz = c_sizet_pointer[0] + v = value_from_opt_pointer(option, c_value_pointer, sz) + if option != zmq.IDENTITY and option in zmq.constants.bytes_sockopts and v.endswith(b'\0'): + v = v[:-1] + return v + + def send(self, message, flags=0, copy=False, track=False): + if isinstance(message, unicode): + raise TypeError("Message must be in bytes, not an unicode Object") + + if isinstance(message, Frame): + message = message.bytes + + zmq_msg = ffi.new('zmq_msg_t*') + if not isinstance(message, bytes): + # cast any bufferable data to bytes via memoryview + message = memoryview(message).tobytes() + + c_message = ffi.new('char[]', message) + rc = C.zmq_msg_init_size(zmq_msg, len(message)) + _check_rc(rc) + C.memcpy(C.zmq_msg_data(zmq_msg), c_message, len(message)) + _retry_sys_call(C.zmq_msg_send, zmq_msg, self._zmq_socket, flags) + rc2 = C.zmq_msg_close(zmq_msg) + _check_rc(rc2) + + if track: + return zmq.MessageTracker() + + def recv(self, flags=0, copy=True, track=False): + zmq_msg = ffi.new('zmq_msg_t*') + C.zmq_msg_init(zmq_msg) + + try: + _retry_sys_call(C.zmq_msg_recv, zmq_msg, self._zmq_socket, flags) + except Exception: + C.zmq_msg_close(zmq_msg) + raise + + _buffer = ffi.buffer(C.zmq_msg_data(zmq_msg), C.zmq_msg_size(zmq_msg)) + value = _buffer[:] + rc = C.zmq_msg_close(zmq_msg) + _check_rc(rc) + + frame = Frame(value, track=track) + frame.more = self.getsockopt(RCVMORE) + + if copy: + return frame.bytes + else: + return frame + + def monitor(self, addr, events=-1): + """s.monitor(addr, flags) + + Start publishing socket events on inproc. + See libzmq docs for zmq_monitor for details. + + Note: requires libzmq >= 3.2 + + Parameters + ---------- + addr : str + The inproc url used for monitoring. Passing None as + the addr will cause an existing socket monitor to be + deregistered. + events : int [default: zmq.EVENT_ALL] + The zmq event bitmask for which events will be sent to the monitor. + """ + + _check_version((3,2), "monitor") + if events < 0: + events = zmq.EVENT_ALL + if addr is None: + addr = ffi.NULL + if isinstance(addr, unicode): + addr = addr.encode('utf8') + rc = C.zmq_socket_monitor(self._zmq_socket, addr, events) + + +__all__ = ['Socket', 'IPC_PATH_MAX_LEN'] diff --git a/.venv/lib/python3.8/site-packages/zmq/backend/cffi/utils.py b/.venv/lib/python3.8/site-packages/zmq/backend/cffi/utils.py new file mode 100644 index 00000000..d85738d6 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/zmq/backend/cffi/utils.py @@ -0,0 +1,81 @@ +# coding: utf-8 +"""miscellaneous zmq_utils wrapping""" + +# Copyright (C) PyZMQ Developers +# Distributed under the terms of the Modified BSD License. + +from errno import EINTR + +from ._cffi import ffi, C + +from zmq.error import ZMQError, InterruptedSystemCall, _check_rc, _check_version +from zmq.utils.strtypes import unicode + + +def has(capability): + """Check for zmq capability by name (e.g. 'ipc', 'curve') + + .. versionadded:: libzmq-4.1 + .. versionadded:: 14.1 + """ + _check_version((4,1), 'zmq.has') + if isinstance(capability, unicode): + capability = capability.encode('utf8') + return bool(C.zmq_has(capability)) + + +def curve_keypair(): + """generate a Z85 keypair for use with zmq.CURVE security + + Requires libzmq (≥ 4.0) to have been built with CURVE support. + + Returns + ------- + (public, secret) : two bytestrings + The public and private keypair as 40 byte z85-encoded bytestrings. + """ + _check_version((3,2), "curve_keypair") + public = ffi.new('char[64]') + private = ffi.new('char[64]') + rc = C.zmq_curve_keypair(public, private) + _check_rc(rc) + return ffi.buffer(public)[:40], ffi.buffer(private)[:40] + + +def curve_public(private): + """ Compute the public key corresponding to a private key for use + with zmq.CURVE security + + Requires libzmq (≥ 4.2) to have been built with CURVE support. + + Parameters + ---------- + private + The private key as a 40 byte z85-encoded bytestring + Returns + ------- + bytestring + The public key as a 40 byte z85-encoded bytestring. + """ + if isinstance(private, unicode): + private = private.encode('utf8') + _check_version((4,2), "curve_public") + public = ffi.new('char[64]') + rc = C.zmq_curve_public(public, private) + _check_rc(rc) + return ffi.buffer(public)[:40] + + +def _retry_sys_call(f, *args, **kwargs): + """make a call, retrying if interrupted with EINTR""" + while True: + rc = f(*args) + try: + _check_rc(rc) + except InterruptedSystemCall: + continue + else: + break + + +__all__ = ['has', 'curve_keypair', 'curve_public'] diff --git a/.venv/lib/python3.8/site-packages/zmq/backend/cython/__init__.pxd b/.venv/lib/python3.8/site-packages/zmq/backend/cython/__init__.pxd new file mode 100644 index 00000000..069802bb --- /dev/null +++ b/.venv/lib/python3.8/site-packages/zmq/backend/cython/__init__.pxd @@ -0,0 +1,3 @@ +from zmq.backend.cython.context cimport Context +from zmq.backend.cython.socket cimport Socket +from zmq.backend.cython.message cimport Frame diff --git a/.venv/lib/python3.8/site-packages/zmq/backend/cython/__init__.py b/.venv/lib/python3.8/site-packages/zmq/backend/cython/__init__.py new file mode 100644 index 00000000..1a9bd476 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/zmq/backend/cython/__init__.py @@ -0,0 +1,26 @@ +"""Python bindings for core 0MQ objects.""" + +# Copyright (C) PyZMQ Developers +# Distributed under the terms of the Lesser GNU Public License (LGPL). + +from . import (constants, error, message, context, + socket, utils, _poll, _version, _device, + _proxy_steerable) + +__all__ = [] +for submod in (constants, error, message, context, + socket, utils, _poll, _version, _device, + _proxy_steerable): + __all__.extend(submod.__all__) + +from .constants import * +from .error import * +from .message import * +from .context import * +from .socket import * +from ._poll import * +from .utils import * +from ._proxy_steerable import * +from ._device import * +from ._version import * + diff --git a/.venv/lib/python3.8/site-packages/zmq/backend/cython/__pycache__/__init__.cpython-38.pyc b/.venv/lib/python3.8/site-packages/zmq/backend/cython/__pycache__/__init__.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..40d7dabb8d89c7e9327bea72477f41f974825637 GIT binary patch literal 603 zcmY+ByKWRQ6hQ5n@w|37gg=;uVk2!P%@#-qQqY2efW{KC=5e!`;K#)FhS^m4lu+^m zd(UjSlEyaD8b?5DrClb#m}Unq^C1h9b*WL^N3f3U z?ZAB=8x`j+XSbluprp%K54S@H?wE~QO$TNyfNok2YwYmJ>-8g_!g|#)=8*Q4M>-Bj z0!Tm_kOkxcML>8Bz3>Q&8_pS{soA$e^)B_d0@;5-`f*4K`1PW;Vywqu-0bDp`1|&o zPgekZGi|5ouzk9%@5D{rhKTIz?r)81#s)c9#!knB%b)qJ_Z*&w%9s<6gq$S_&T)k1 Pj-%gsd=%w=?*IM=N)(py literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/zmq/backend/cython/_device.cpython-38-x86_64-linux-gnu.so b/.venv/lib/python3.8/site-packages/zmq/backend/cython/_device.cpython-38-x86_64-linux-gnu.so new file mode 100755 index 0000000000000000000000000000000000000000..6d94a7b48498900d200e35dc4253b5491824386e GIT binary patch literal 59896 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 R)6(Ss>z05p4dojg{}bu}7O?;T literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/zmq/backend/cython/_poll.cpython-38-x86_64-linux-gnu.so b/.venv/lib/python3.8/site-packages/zmq/backend/cython/_poll.cpython-38-x86_64-linux-gnu.so new file mode 100755 index 0000000000000000000000000000000000000000..7d834fc11fde018b75f5b27404f38a7bcdf78ed8 GIT binary patch literal 76576 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 literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/zmq/backend/cython/_version.cpython-38-x86_64-linux-gnu.so b/.venv/lib/python3.8/site-packages/zmq/backend/cython/_version.cpython-38-x86_64-linux-gnu.so new file mode 100755 index 0000000000000000000000000000000000000000..5175ec03a30f68bf44b618e92c00ac87d92246a7 GIT binary patch literal 34744 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. +# + +#----------------------------------------------------------------------------- +# Code +#----------------------------------------------------------------------------- + +cdef class Context: + + cdef object __weakref__ # enable weakref + cdef void *handle # The C handle for the underlying zmq object. + cdef bint _shadow # whether the Context is a shadow wrapper of another + cdef int _pid # the pid of the process which created me (for fork safety) + + cdef public bint closed # bool property for a closed context. + cdef inline int _term(self) + diff --git a/.venv/lib/python3.8/site-packages/zmq/backend/cython/error.cpython-38-x86_64-linux-gnu.so b/.venv/lib/python3.8/site-packages/zmq/backend/cython/error.cpython-38-x86_64-linux-gnu.so new file mode 100755 index 0000000000000000000000000000000000000000..99ac94acb058a231620d7e14f58c5c00b3ae6cde GIT binary patch literal 38944 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 literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/zmq/backend/cython/libzmq.pxd b/.venv/lib/python3.8/site-packages/zmq/backend/cython/libzmq.pxd new file mode 100644 index 00000000..1dcea1b1 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/zmq/backend/cython/libzmq.pxd @@ -0,0 +1,117 @@ +"""All the C imports for 0MQ""" + +# +# Copyright (c) 2010 Brian E. Granger & Min Ragan-Kelley +# +# This file is part of pyzmq. +# +# pyzmq is free software; you can redistribute it and/or modify it under +# the terms of the Lesser GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# pyzmq 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 +# Lesser GNU General Public License for more details. +# +# You should have received a copy of the Lesser GNU General Public License +# along with this program. If not, see . +# + +#----------------------------------------------------------------------------- +# Imports +#----------------------------------------------------------------------------- + +#----------------------------------------------------------------------------- +# Import the C header files +#----------------------------------------------------------------------------- + +# were it not for Windows, +# we could cimport these from libc.stdint +cdef extern from "zmq_compat.h": + ctypedef signed long long int64_t "pyzmq_int64_t" + ctypedef unsigned int uint32_t "pyzmq_uint32_t" + +include "./constant_enums.pxi" + +cdef extern from "zmq.h" nogil: + + void _zmq_version "zmq_version"(int *major, int *minor, int *patch) + + ctypedef int fd_t "ZMQ_FD_T" + + enum: errno + const char *zmq_strerror (int errnum) + int zmq_errno() + + void *zmq_ctx_new () + int zmq_ctx_destroy (void *context) + int zmq_ctx_set (void *context, int option, int optval) + int zmq_ctx_get (void *context, int option) + void *zmq_init (int io_threads) + int zmq_term (void *context) + + # blackbox def for zmq_msg_t + ctypedef void * zmq_msg_t "zmq_msg_t" + + ctypedef void zmq_free_fn(void *data, void *hint) + + int zmq_msg_init (zmq_msg_t *msg) + int zmq_msg_init_size (zmq_msg_t *msg, size_t size) + int zmq_msg_init_data (zmq_msg_t *msg, void *data, + size_t size, zmq_free_fn *ffn, void *hint) + int zmq_msg_send (zmq_msg_t *msg, void *s, int flags) + int zmq_msg_recv (zmq_msg_t *msg, void *s, int flags) + int zmq_msg_close (zmq_msg_t *msg) + int zmq_msg_move (zmq_msg_t *dest, zmq_msg_t *src) + int zmq_msg_copy (zmq_msg_t *dest, zmq_msg_t *src) + void *zmq_msg_data (zmq_msg_t *msg) + size_t zmq_msg_size (zmq_msg_t *msg) + int zmq_msg_more (zmq_msg_t *msg) + int zmq_msg_get (zmq_msg_t *msg, int option) + int zmq_msg_set (zmq_msg_t *msg, int option, int optval) + const char *zmq_msg_gets (zmq_msg_t *msg, const char *property) + int zmq_has (const char *capability) + + void *zmq_socket (void *context, int type) + int zmq_close (void *s) + int zmq_setsockopt (void *s, int option, void *optval, size_t optvallen) + int zmq_getsockopt (void *s, int option, void *optval, size_t *optvallen) + int zmq_bind (void *s, char *addr) + int zmq_connect (void *s, char *addr) + int zmq_unbind (void *s, char *addr) + int zmq_disconnect (void *s, char *addr) + + int zmq_socket_monitor (void *s, char *addr, int flags) + + # send/recv + int zmq_sendbuf (void *s, const void *buf, size_t n, int flags) + int zmq_recvbuf (void *s, void *buf, size_t n, int flags) + + ctypedef struct zmq_pollitem_t: + void *socket + int fd + short events + short revents + + int zmq_poll (zmq_pollitem_t *items, int nitems, long timeout) + + int zmq_device (int device_, void *insocket_, void *outsocket_) + int zmq_proxy (void *frontend, void *backend, void *capture) + int zmq_proxy_steerable (void *frontend, + void *backend, + void *capture, + void *control) + + int zmq_curve_keypair (char *z85_public_key, char *z85_secret_key) + int zmq_curve_public (char *z85_public_key, char *z85_secret_key) + + # 4.2 draft + int zmq_join (void *s, const char *group) + int zmq_leave (void *s, const char *group) + + int zmq_msg_set_routing_id(zmq_msg_t *msg, uint32_t routing_id) + uint32_t zmq_msg_routing_id(zmq_msg_t *msg) + int zmq_msg_set_group(zmq_msg_t *msg, const char *group) + const char *zmq_msg_group(zmq_msg_t *msg) diff --git a/.venv/lib/python3.8/site-packages/zmq/backend/cython/message.cpython-38-x86_64-linux-gnu.so b/.venv/lib/python3.8/site-packages/zmq/backend/cython/message.cpython-38-x86_64-linux-gnu.so new file mode 100755 index 0000000000000000000000000000000000000000..eab12094e2fe857f9191d8e097311b3f62f747fa GIT binary patch literal 106216 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 sW}M!la#pFFc3J;X!@qZ. +# + +#----------------------------------------------------------------------------- +# Imports +#----------------------------------------------------------------------------- + +from cpython cimport PyBytes_FromStringAndSize + +from zmq.backend.cython.libzmq cimport zmq_msg_t, zmq_msg_data, zmq_msg_size + +#----------------------------------------------------------------------------- +# Code +#----------------------------------------------------------------------------- + +cdef class MessageTracker(object): + + cdef set events # Message Event objects to track. + cdef set peers # Other Message or MessageTracker objects. + + +cdef class Frame: + + cdef zmq_msg_t zmq_msg + cdef object _data # The actual message data as a Python object. + cdef object _buffer # A Python Buffer/View of the message contents + cdef object _bytes # A bytes/str copy of the message. + cdef bint _failed_init # Flag to handle failed zmq_msg_init + cdef public object tracker_event # Event for use with zmq_free_fn. + cdef public object tracker # MessageTracker object. + cdef public bint more # whether RCVMORE was set + + cdef Frame fast_copy(self) # Create shallow copy of Message object. + cdef object _getbuffer(self) # Construct self._buffer. + + +cdef inline object copy_zmq_msg_bytes(zmq_msg_t *zmq_msg): + """ Copy the data from a zmq_msg_t """ + cdef char *data_c = NULL + cdef Py_ssize_t data_len_c + data_c = zmq_msg_data(zmq_msg) + data_len_c = zmq_msg_size(zmq_msg) + return PyBytes_FromStringAndSize(data_c, data_len_c) + + diff --git a/.venv/lib/python3.8/site-packages/zmq/backend/cython/socket.cpython-38-x86_64-linux-gnu.so b/.venv/lib/python3.8/site-packages/zmq/backend/cython/socket.cpython-38-x86_64-linux-gnu.so new file mode 100755 index 0000000000000000000000000000000000000000..57cdff22ce16ac8bab2caf623c8b53f74511b0c8 GIT binary patch literal 154968 zcmeFad3aRC(g!>NM#B}q)5>X+dkndO3eI`AvzVCgX@A>}u9=y-ZocdLD zbyaosa{BZ+%pMxJs7+Fm!~Ux?XiNKKv z9Ere@2poyPkq8`#z>x?XiNKKv9Ere@2poyPkq8`#z>x?XiNKKv{Qo!t@?p~d@kc(A z`ahQX@5KMV)cxOC&?@y;TaxfxQT-o1hf8vN(!pUrUUQW6yskYx)oasH>XFYK?dNum z7X_ZI;gJ^vo~Ge8UEQ`13)p&U&Jy$@4UhB}c#VeFOMHoj7fU_$8t%vvdKxvnI8)%3 zh8IfQ(N6GfJIl_Nw1&H7y&erOlz4`QN2EQO8eS#kvo$^%QFOIZ{uNhS$q+ zqgcn^686l~aKF@3rQwZIPmP8Tm-0(Ayk?QmAJOo98HWZ9A1n1VYPhY((r{akBRR2M zCP_WX8t#zxWN7&HQa)3|ZTWl+zfH;)Xt-PIFV*mJDPN}HwtTgQ-zVi4X}Cw~uhZ~H zqL&I%7J`Gk%oUL^%QG(vE42j?vwc+(Q&WvzfQw9t`XysrQw-UzDdKsiU@gkhs1bhNcl7k zpCHdEWox)c%KJ2Ylhj|R;ch8kq~Y}|g+22$+#%(wG~6xq*JyatIl`YM8opM>r$NIT zrF^4?H%WUO9TVeIFXfYUe1)(-L&GCdK2yUT%Y}TthSx~>0u6UddrCFDTFRGcc#X8D zTEnZP{2~pHNPFruyiCg1Yj~H{!u}==FP8Gn8opb~r*%q2dEQr^(; z64|~*8g5AWVhyj7@u|{qpOjyy;l)yZiH2uO`G|)9N7~=0;h9q2((o}-J~<^ZJ{~FW z*6J*>ovSt zuB#g~{0-@EvxYZGc}M5OxIH2Ddoq2H&UyQO@yhPRRVmUc{HJRMTrqv2I@yz*&yle{lBG<=CY{%d%nlrPrsYo&aZ zhSy8^g&O{`jL#Ack4X85hF>h@8#TN}%3B&1^>7o@-Q zG`vRYuhQ^~rF@NsS4;UN8t#+%)}Y~4Qod2gW&S%-6XR1R<&!nMTH2GL;l)xuQ^U`f z_T+1Lp_DJs@VjLHD%J1;DPN}HK50+2hUZK9MH+sq)L*CJJ}Fz)|TOeyct@Xj(mJ`MLsc|*e=mHrlKxLe8>Yj~Nw->K4Yhm>Ea;W<+O5)E(4 z6#hgse3taLQNtUhyrtnz>2LC}iSenI@@@^^Ci_>WhDW4)wuY~i_7rG%jg&9c@N8*M znTA(O`FR@tr;N`c4X={&H5z`Fl&{zDc~ZVX!w*RLW(_Zs@{Y8`xOrrLdNjOP%4cZ! zX;QzT;e}E@U&GU-e6fb-OZid_FOl(IsNp^-U#;P{%l3_Ec&3!E)9|Zh|FtySBjuYk z{B)_`-6Jt>ZYiIp;rpb&*&6PU@;(jkCFKh>yy;9)Uy+7iAmcMn!yBc1m4<&P?XS`B zdMUp|!+o;9H)wc7$~S6wcWJ+)XJUM6qGAhDW7&+Vmy6P-lO5| zr2Re(&y@0phFem;NW(o+zF5O|Nck!acT4$&8h(y!uO%Apkn#}??pyN`$ zQNydHyyL{g_|!}JWF43B%+T0u4W1=1-}HFOu?Q8lEZd*QzzV zTFNid@J!hs>omMd%GYanlblbRG<=?vZ`SZ$vVDs@iSfKZK7TLP@Ju-4#4KK5w`)hdh zNy3h19q%LX4EdWZ%y78B5f|AS9$6yrY7PHNK7U-K;hCQb`6U{j_Kt`{orYUdPrZg$ z9Vg_QG(L*Q4PMX@7=>7j71Md>X!2>M=CjE#>ny zysBQtQ^V)KEBsxg;rW|nJT<(qjcCV+hVPbo>NLF25c(T5JkrveD`?d4!_qHH!+p02 zJ(IVAKr(i8K)-TOj5S;O;>7kHY6m;E91cr?6|)RUp%k#mKfYz=SxUFh*?cpIt5 z(D24zMVt$C{D9C?sNwCUo+1r*{3P_0YIx&sLQk27Zq+?FrYaNC|D4Y%zn)9?zrT{PUWPS~?h!wYwdI8x+iI8&zK_P94s!|iczp@!Sz zUbTkXECVM}&!yt>B#$d7pyIPx>&|Q1D|F`FsUGQNaro{8R-mRPam%FH-Qc z6uel$&sOkK1wTi@%M|=#1)rzjBNV(!!7owpg$h1O!K)Q~jDjyx@InQzQSfUOe2Ib= zDR@M|Z&dI)1;0tb>lOTF1#eLBpn^9lc!`2r3NDxC%xzNe8H#+ff>$WGV@GR#&QE`5c$$JgrQjX~e^|kN5S3f?)6IviyR?o#l13hq|$Dg{4A!51oc7X`0Y@U9BJNWr@) zc#VRmD)Fa5!<8SeHHl(1wUEAGZnm_f@dpuhJyPP z{1gQ@6#O&=&sXr%6}&*f&rt9}1@EumMGAhVf)^`zmV%cmxL3i;6#QHTpQqsGDR`BF zXDj$Z1o~Pg*1s|^9844ay@Jt0C zso>cP{)mG66g*$S4Fw;q;Q0zZR>2Dte4K(8D)@K>FH-Oc3SO+>1qxoO;Fl_RnSxJL z@OcV;nSxg-_~i<|P{AiDc(sE6OTiZ@xcnq1b88g*N=1H&f?uWJ5e1*D;B^XqwSw0x z_%#aNpx{#!yivigQ*cYcuUGIU1;0VTn-zSjf;+x%&HrKrPgd|-6x^-g(-b^S!EaS? zkAmN(;28>Ds^FOle!GHaEBGA>?o;qP72HtpnF^k-;IkCGK*47#c%g!qDR_~B&r$GV z1;0zdOBK9a!OIl9Qo-jb_}vO#rQq`ve4&De6uer&?@{nY3VyGG*C=>c!Ivobd!-=LP zceI-63yF3TUB&bOqK_iFjOnw8re#^QnCVlAPA0mL={`iaCpw?$oH+TqfLha^!Gz4IrFFE7>BU4JOLQ^QFB45m>}Vm= z&k)^%=zOLhC7PDhQ6JL}5KT+zXeQJ55KT+ysE6shi0(zSo9R18a$)*Oiv`b577~(M-zP#(KSpDCz_VV(Q2kIB)TurRZI^c`edTZ zm_CbWS^`IlnLd^145AB}?nCq`MCUWzlju{4_A%XsXj=M4Gnwu{^yx%kG5ndq~Lu3>s3(dQ6d z&Gc%bX(=47V)}ieX$c%HV|p>swDgS@GyO8rwB(HzGW`tEIYj3({V372#Etrxet>9N z+D0>(zK3X9(ndW@-$isT(Qc;iAexr2Q3uo0h^D1$wCN9Sf1-UvH!^({(SD-qnVv}W zg+xb~9!>OMqHCBQPBbk^qt#4bNc2#mtC$`@^hHFMF?|-%wDgP?Gkq%22GNB~_aQou z=zOMo5MO>~6m%|wqOx`yeEMAMQpTFvxoqG_oatz!CpqG^d4En|8y(X_OT z7Bl@a(X^zD7Bc+|(X^C|<}>{$(X@n&`j~!zXj(c(Gnu}JXj(ExJxt$4^dzF)Oy5B? zEfJ#*rl%22OT%c>@7(@G7ZTmb^i@P(NpwBa6N$cx=m^uJiJnY!4b#JkrlnxCn&}IP zzJ};3rUwu`h3GP-&m#I-qKlb6m1vrPqJ>QNA^JL^^O^2R^z}shnC?RK4Mb-$-GS(- zM0=QSL-dVAyO};X7xYa;JDA=_^vy&!HFNtDT}*T%)87$&3(@sVe@XN-q9aUiCi+&Q zYna|hbdcz3rdJbPLUa|=?-NZ+#Aq4Qi;132bTMem(*=g<9r|f+M^=Q-5?CQvWmHCt zkn^ccy&WZ|8e!+o@kx$a=Z9N*J1)e`To`hNJlx1$q8YMu4C@(F$K;gUT30F$y|rv88; z(AQQ(jP*^3>pR2Nw|E>y>`@d=VSQz|x>)GDPU@Q>^xY%$-HIRh%leLv>)Z5!^!F;( zHylMTWqp~r8ZY$qkorzj>g=}PF@giG>uI~FAH z^`m&r3Z>uMAex)$MTrqFf2)b%Xu@?HgB?F2qIuISYb z(#iW-(d{VnHXC&XuI33vhEz0BDEeJQ3u*4K_FxJT-i@&p8LTK1W&UJE-EsAxP}Bl< z$h%{NqQXyFEqX4l=wO|+sAV*{wi{*IVtHNb+=Qzqg`#()qPou9$q$HJWs5G0D|*^i z^cgF95@lcz6jk7Akx+D_R5V*CdR=z&KZ_U z^h&y^K(@UE5$o!BCHL5stQ3IOy?og0)yUxi!13K388o&*QkF7|D^uN zKi=n&ePm-Y%DhKVs9ib+n~|8|MChm5b-$EPQMn)0%;cy{$JM8z?m}7jG_E@(i*%Z) z_WiG>Tx}P&ohofRpKVJqMZ1gz%26AL3yK<* zQ=>**(axn|Xq>-`8u^wGwL$xA%Z^_wqxQu}vTPMHSXlNVuD%nNRpFAN_6+pE+awNA z%0$FtCEb4`TsLuVO4&*=F;i>A=zS?ii1VlOfxpyu9oIJss`qdt&cjtq)aQ})oyGN~ z_(fM84wNI2g$s%VmHVei5goxH>2- zn~zKKyBhl`Xztl;S&D@qv)?P3_7;H_exLB0t^Igg`|Yg#N+`OB{T_y^wr7%6&P=KO zLTHEIN#ui>IuR)Q?Z*ZAP38W{?-2;^f93a(y|!f?R!P6NUrc`2BFltjui@$_VcEmD zB)=D7+=1V7dAvwzf`RO}7(cwlpoQNj$H(a7ZS8Yd`*l!s4f}lwu3SQUw$wfx+TnMO z=si~fWxw-qL4H%YfAV`A!uwzO9r!8kcSQQVdpP<1F>+Q|_8(kz5tcoPOY*x0{RKV# zK3Im?qZB`OkN=SZZl;W*5ywnj!KQn!-sw+4WLveMSsIR}Q z&&Tzpydg5604PV|0$flesGJ%Jb;h_D0sp&5{H4cVxW|q}^9mV>uk$Dp>yX95vR80* zg0PI{1B%28n2+J_ZxnB=pJfJkOF*wAGpy6%L+UXrrP{k$?M=||B0D@5SN(+AT&eaF zp|-zp_*$Us@JL*c!&FXn7$lq&Q{+U%_3s?EgA$)2NBw9!+_GF+_M<@#e};4xmc5Uw zQ-x*E;*uQx4~7gl+)gwo2NVa#^;DBIybhLOWNkfy@24Y)d2Shg6Kj57B0#Cb*LJCKS#BgDTmPPJjA7Q`+LKPiWuSs#|O}3mPzeTvi7^7$OZRmowP>0 zSZJs5fwW%>?NIvyHKCb08z}od1sCKul~et;rz`S%8p8W`e%mr}zpsnN{eE9s){ZUv z5%ZF;Y%{J#3d@$_k}TVVRRr?-Rrqb+XcWfB%9HH?ele5+_$MM=c~>>)eZ>q(E5K zfJ<`m2dc_U4Y6h3)u_zA>Ax*L7M^44+dG6jeGf&^Cb)VESA{~~JgM(d)|YY$S#72+ z2Fjj3f(!DL%Bh~B>EoV0kDU3t#}a$cZG`@au489?g^+Vq+|NW=8T}AF2Nx~%q~Z?4%uhB3 zrv7;|Ik?7E5e94jU92l$UYHg<8T05|Vun*2&q{IxLaSDA^P1VXzgmG2t1?oO9-9cM z>sTr!G&l*u-pkI$PiUjTa!1j~*3z*g%Lr}H+GZWt)zT8{XEoVbv8IIXOitnQ-Vs#Z z%(fo*9zt!hwi%&@%hveE=7s)TNfnPXLcfi{E}`2R6)zslHd=-{vNju`BHW3t4}^AG zWAVhnFgqIIQMi=>qiacb)XleuRw=4COx*TBeFR~5UpC2qIieW)qvgRxB1FOS5Etlr za3RqxZ9sWIRfB>>L?_2pyGv4xP_5O6oN8PCK?~W-R-!SzcOr4DS~7-isMeIUw+0|X zvi8Ja&QCO^BS^JYcVLx~(7MuZVWd@urymn93t5xa_{Zgiek0#MgThT@Aw17Ua~Bx3 z!)T8jk)~Vla1i%%xOoGo5S&8h&@DTFA^^0VjEZ)X{~l|}PWWFwqrl;+tRUPBLPh2N z5?8GLL;E9yo!~=%p#<60St2oLcZic$Z%VG@Sw*C?X`CC?{@2J{3634dwzOe?NBn) zkyqO;oqi2TTT4ioZFyZ@d93GfB|1$uwVr>{nsH+&-T{mU)?9Ls;~l&>Yd;0}Av;&r zm3XXDWER-S2-CS>Dy6p9nI)307nL;I8sU69ZMss6T!a|J+GnBNtkY2O#LEn79kj_| zBXo%B&8?uhbvqt|$#y;tx*LS<2Yu8Neh@w3Pqg$zN@+AM+VxkcfSS*_Y0U}f2D!sY zQ!1HgrVgU{7LJ&s)AF#nVuXe|f=;8w5lge)q9leBonRkDAbJyax3eOg%K50gt*Cr# zrf_TsJV3lAa!PHIRc{$LB(#n?Q=0Ybx2z5+8uV4}DQRyEbZ)qzw}hN(gTmflOXof_<#L)>r@|Dt89q z{BCQyNEjou&Q&p=6{c(*1cl+$ZTRu?t7aH?sDdZ3RbCk>y}<~ltQR76ipWnSa)%Hx zAo7+FS)z;320pZ4;z)g!MN%He&rpn3Ay#o7_@UK-P-Erh+dGhj58;8UY<&NOyikjO zd|v1yIeLr;t>qN+Q=XoW$_d|@0auWr3u)OuMXFRe=&?ao9afd60qE7tfYkn8C4Tm0iF%Rdyo zYtD}r3R#`E+ga|aco+cYPdRaxm3WXkFBBnl!rm9pplpc-Li#+FZ|pr zJS5#0z+8|S2v5b3jy+k7ytM6y<&6hw5al81nf8T`FTlqr9Zbjg{Bt1m1FW)&(4AeZH z#1mp^2J#KeXEIviXv7v&rX_BPCm+(ynYcgY#nJftgT zpib6G1dAkl#(41N`$^1v=m%^;r=wy=<(02Zj=h#wettS;w{&{omxI+3Cb*zM<2q`9 z@>Ao=ds?RneFC!BDeY{|{3yu$%H@dSTfgEdQCnM+bb!ov|4D_+R7@0@p z{5bRU;bw3bro@ZvJ{nB5wb86+)j$zu!1j49Yhxc{a_PYXajeUw9J`-H14IWPeiOwt zTtV|wuaVy52MdhKmLOKIb{*}40|MqviAJ5H8r5GImGcWGBG|BSo1^!CiG~m7J_^XH zJPolGE66h}>kG<=(gMs!&~_E6F*7X>k{x}cbJhloCl~dHC9lyASh+XQWbq4@F##mN z?9<^MRyATtGY3UzEpmxcm)*NjX^1VH72&uE^8wSSbb@L4yT?6 zX#;n_Bn1(K?p1K_8ItbKZkJxt0T*4ehorX&UKj|!nqCH>K-hT{l?kU_hWau4W2qo# z|Gk(lZbIp-7Jj7}4QPG5g(u#53pfnUVpyJq{PlT^atjUSypJ+&BK3aC8)p+pS49~K zhjVwGgHeCK6@UuCUCrDXf?F%NPj0ihk2Ci+!JUbQvf9`svB=#G)3JI+pLu%@qK5_Y zXP^0- z;w8R8pNK)fGt2_nR_<0F2u4`#5Gi<>f)dsu220Uvys4}qb$=OIx!0NnE3s}q!Dw;r z02B!K{fao$1$x^27}g8BF>YB`qVvag&|FiwGZ5{| z*f?7H0!1}=2&_E!rYCyS z7_{?fP-gBZ=;EouJYx_TR&P78a98jxi+B&ym>0rs)?VvbGys`ZOB{Ou>His8#q2eGJOlaT~ejbrm%~2lE{z9gSM&zj2kuIpNKJm7K|akK}`pN8Y+Bcaqy? zud64KO79^WOEIvF6KuW%yP74u-|;Y;JA+D3q0U?x$qUuGDuxm}$8uG^A>_W4D!SMz z;9jO+trRM|FOKyPku_N6S(CtS)x{gMCZdlT@mg z*kNy1{Je*`9HO<>aq$OKqfp9KxeX>FRX0-~3T^i z5+l@W5^yWoZYk#=kgf{sBtimua(7}7wJ!aHQw4EzF?$0WK!!qnCkThjVKqP3?+9B$(pBOec`I0-GqAv_wF#*W0*6Ng9FND^l=0`S|)ji zeVEt)!yJRf>0r7qGQ!0zK^z#d4%yt}t+S{-N$?mJf`s)(y@2GM2!a^29-}VQ5(!?9 z`;Cm)UH)ayig6*Sf9u$jjrF8|+4F*7VLFu!96ga4FAB!T3gakdJS`aSD2zRHye;f} z7ErCze9hi{zXexQ#dh>WTt=@z$T5+RM0<(ZWWjS-F7`vo>$v2oc**l{b)zWhp^|-3 zk~eCtW8#H}*@aK%!rkJ955C&lag!*#1D8u?#nMLZ>%6fZg1E?LSY3*#j( z!qqLJ9(&GhtQo(_!@&Yc{FJ3SOSJOnn{jXqox$Gs;JjX)LZqSi`BH*TT zMFAcOWIKXbcc$J!!@B7`n}2f8hZ5^WR7UAqk3d)hK9+5SaiakMGW@|akl`3B_6nnd z7a-l+K97RK<4+hr#K>MU5mr8O8bx&u44TPNy%tyP#p#KBTt=THm1gQ%TtjmXYu;`- zH<1Omzvy4~ws2xJ)Ywj7A01BQzPSiBHpCz5jiwqYgZgoeE-1VZx@(=kfzd(K_zfuTy+w~3#s_)qWD;<{kVAXYp6Ko(L-FEe5v7ZW#cME6z`48*fdnVkgDDuf2!9T zWw960jG%;_DYc&0uyG<-f&c>@5GX*F{7fkhCLu-a#4w77NDiQ(74(FylSJ z_()+m!9XJYHV(~}e8R=bDr6IyLmU}&S1jB)t9;{=!LwKjZ2EPrVI?I%V*1UoP1 zD={itd%@vJ|382+lS1v|Pg9=dKK~#JR^crk9(~rhDqo|eQ46vTbrwO!dd+^0y)Jkz z%3V$6%-j-GNap;8PJxBs)!+;eoXg0RL2*-#i5YY=H`uyC*ie##TF<0f2LOm>AXM=g zz6EQPS0$kN!sm8F`jfElEayuuh=oioEK7`9+%5+EZKF%di(Wf(YlXN6T3sP>gt|0Czyt zlftR{fy0Ow@$+6Wnwr=1@zg$ufd%*WRF|!9g3xyx>6@YG>n-%XBJ@oleMleHR}t6u z4C}j2)pxYecQWZaP0{xW6%MBs3Vlbb`p${#8_xQAsQTXB!2V{EzHJ}2`a4JHJ6q^G zM%A}7-W~U0Aaqr1*iR}_j}@ZdXTX&zc4fQuUR-n~i#|!Brf7zLi>EH=MaQvOcM%U^ zGpH|lU{-7p?iHqT32)>{G=8WS_sVC!=yo^Ueq+^}13Qak0>&g_zU&cO6-rTa8scI+cAR zZFv$jPU14&84!Z(XKPmzG~OjOUN1FfCu;nq zmTkNfF;Z>3GeKi7p>YBQ(#*}28q=i4v_y?h3ynWKo~ZHE1dWF}a~#(}2pYe^!i2nD z|AFwjnYr;eULrI$S0`$0=&O4Dwb1w}grMsl^8{|Zy!h!UBdW!3# zr?{EO7mTo$lbbvD8?M>9Hlf0H)C*1TYEj{Fvck5q!hMv*t*LM?Re^Z`ixO;W4O)mF zyLx+PD>aQ!Z0_TMSsNo%AIpFrS3|pX96k2L&T{T}sw2NU6uv{T=g)Oy&z*48HpBX&hp^a35PAhhyY&*vC&nLD9)Gv46+!Y?%W@-3M<1fqftmXRQVD*)14t%Ev8!Sa?E#qHIh1B*?)5Yu z!}HM?QYc~;bMHjRdF&c|I#eqCJW=UK6fDzwt!ymC(gg`h-xW$P5CKb; zN}Dj&kfnV-;Qj>(N*4&Fr-}~y7Ek7@t;eL&`x2F=vr<)?2umlz(ewLc-FCy9#g7a_S7R3Iyo{bOkad-kUD94u8ap!Xu-aPIi|M5VfDF>ZPn zlEv{lf3%-@qdU1OPGW7TpL1Q_{-iJi>Te(TSjoh)~)vtm_W7Q! zpG^pAs;GYc{p>yMX~O&Bd)fOCH;uO^Rey6r_2-M~3q2Y6$SQb$w5UE!RR4*|)propmqWYNM2{`v-tXmI&(trt(Y;-GIF47p1|E_3J6I?l z{D7$bc`6fc`(s7*WmQyR$|Gc2IG4U-fu=RNMZC*sAigD``e#J-6Gio(vRu6SA+q|1 z6RY2}oV`Ceq56fQ3;cc`SKm`q|KL4beJ4@!!marI$t5$`w1tXk)vh)+uk=I84Y3^|M) zTLfyfFk}WNYuu3Yr6K!RDBcX~mT??TNHC-dnTag;mOFn+7h%Z7!jN{tkZWkE_JjS@ zhvV?3sQy!Ke(%)8>X*Yeio^4X)n6p4e~QY)<8X|qexj)UK{73z`|3Q7LnWt%_Zvjn zx*?(Zt3~x=MfG2Evc|n1B&#n-tiE);BxU7A?$DAbE8CWFg_2l~J+MS=w|*?2`ZcF3R()nJ$AfNI zX#F#eXOgkB2K0VGIYkdIhvS%xKiP^RROH?vC&fM<)@i7+)%GFO)8iv$j77aSvzNI` zXsm$k)l$*-wxVde-E=FzIg=m3T+$u4@|W^bI(ql_#P~`u&LswYu>xBIH!|ZJ!RVzh z#xlbajCRDJZ(5+lKxX_P7_rn=MjvMUDj1uIL0`Q=l>^Iqtm3PQ zF-erz%8WLGF;`)%U`8jwxQQ6_FEj2HjPr?cttfFTGv*7%NeW{k zGZqR)2VxY75`JbpAs9b*Yh`3GqgpT;6o!i#&j`j!g|UApdH$MUyg-cWMIB!=W2s<- z6~lb zw?8vB3dT1IBb6B+3dTBx@#hXwwN)@)B}TFEdiXJikmZo>CZFm@!2#?j{DkaD@`fnL*!s zLfCIq7|$`|R>2rc40=@wB}`_N2*yB#F^w6s1j9!RG$56@lo@4$(NAIcm=O|;&cr|! zRH7d>p8 z7sKmBV#q=NelT!gw*U&n87Drii%Ij?JMhG1^x~G5DOEUuM|be!&c~F36K-wr77k9V zu9@OGu>!7Pf(kop%D@ZfK7*fe#wpD>gM>GMI!|viX$=al9ViO!o7B=s->ZZC?LvN< zBEPB`&(l{MtA4n^NUAqJX)fWysh4oAn}ho%;oNDOPF%N1 zqR`_a?oO*gINoXy1GTdq`~nT6k7f|q9!Kl>wIt<8DZR9| zhyun(C!WNGwHo;zF#BGH?4YBdBa{3CJEeyV&+MD=tOQ5vao~*(gs!n3fuLFH@#F2H z@FgvC4%VSGxm8=X@(>kDfX^w8p4Epv>S_cN_0DD{26>WZtd`}%k2^;oqglzl(X-W;T=m6;) zbWzSnem{?Lk}7D^(ipuRp=<5GmHUGoqu;;55XqMxon(ZXvw{ zdi5|YVY96)GJ~Q&*jKXaG8z&@eZ-9Z3XizIo73^E=^%XC*f9xb5Th5rhN=?sSDuzm z3Kp^E@<R}?sFvI#(@UAe?%`vRK@#vCG@m}>|YbaOF^~PE$Hb9huXK^4Y(j0i?1G4lL(mW%RM%B)E5eG9HCGMF? zK{~obB6#($%!g^MrO_G)Gh&uezGNO~N3dr9u;!$am#xoWKxJe~Rq!cfu9}a~iDri` z=Pw9?Bl-s_Q~3VzbpBVo;K*+nU_vM&L-0=JmX^TT|n`fPlBZZtdd6U=Wndh%3B`#ZYS0UyvUzg<1`TWkW zvJh{3p<(w&YVUll^YHjmnnt?Z)+?{0v3ZoqFWF9mkMrBJ#e7CdijKpt2*mT>RY7m* zr~`?MI~WF&5)44fU{V1&8c#%e>-o+j2F4q6!tvAvR(*%@WwkMRW2oN9*@)z)9upmc z5k$_r@qS{{3FQuaX%{V7msp>*l)4GlK9e^>v8&=H>QUvZlS-bj<`4&+_dz=TJsvoX zYu3uuG9GJ!cs;h(`r|NY^K1ieC(yyZP*+#wsiZ@`<#_%};w{H$Dl4GKWE#r+kL456 zm=}2o6Gb;H^!PmhyjFn)pLl=A8bpnOw+D8k86G_g&48{v{AHe|z5q0vps;uCQ3!NM zzCgMZ9WA!3b-tnc&D35bDHb+HXhLQXFDWT6C_f7*&^O;}Odvey+sf}KaanA z;|b#J7#{w)^3c20NGNJC%^TEDF+{rh5SLnO(TfO4%$_g3$56fR#Mf`mPck`*(+*G` zXIlecDYlkSiAX~*_(U#4J$-WA>Yf3+tq(VjU_tJ>oi_H>cdG)3Rq(eL)9FK)Bz_}lhKU>da&y!_MKGZ~W#HU~_6RhR?MNs-m z))G4&{?_{4cukEKEgXaC7+U`l0ImKsyZ#BHk|nZ|2ym`n8UOA2dLkbRARZjqTCpcM zlq;1>-q5@D%2#t=&xeK2x8_6E{@6;myQx1%V!X8ETv#GvzWyKb^DqA6u7Gj?tFQmv zf2yD2KS9*$w*3dL`_C_<9m1$BX1y+W>791Jke6pBxhkIINp7ZxhHhecT3Kh~{@gHU z^881v>{eE?V4uyYW^Kdza`GC?t7}Oq4z?T}f6@Qgl8#p4vl!c1 zx_nJi&IfmXN;>EzpJUN*aG;d5Up5JEE?thXM~r{gX($vez@#C@AL}@xXJdGgbVs5` zx6*$+1G;xB9V5D_wfr`s*R|3g5dCN?y_D#iTj^Jb9@0ubMs$x>+9dj?Lved%5WOZ& z(?Z#rfFTj%gOp>vi$&pSN%*_~26B800l~886Pg_HMT6*O z2u`U|>bs!zgA&*>z*kG~K?$|Cr&)7iZQ+F4I>_31+_&qwp6ZG3XVCraVX-9rbzIgS zu^g)0@2YqVZI7o8%VuF$nT~RK<)^13PpHp*$`IZ3XV`w?^?uaXhN=yx zt~-R%VegQ=_~93qpP?8dr^Ks`3s4+RMvVB!M24ihsm8p}ZhA%D9qTUFDfHD8`zrwM z;FGlBaxf6W`>K1bE6{hbuY`B0XJkgR5H?i*K?Y7ZZN_7!X?No3ZdJC3OLPZ%9IZ#> z7cKZDTXQbmw7!J@`$}%6pR!=-{&Kp(@C9#1gH>^IB8}DthtkJu_yZC*piT}0y%<_T zz2_7pP4fOZqTG%03lN_@N!AQS2;`Sa#yNrmDNy!0FZ2yj(N`fycHs`rS=Wyz!QT-w zun@Iqe?&=)Q~09EUXs5Y@)Z8D_>Ij$p$A2wJ1NegFGZ-&gN?B{B7gpJ|AzYqv1eD_ z=)}H5a3&TH?tpo78n)?ZkE^`VRo>jzRWS{bo0Sa-SH&<~mNzGpovupkd}GYt?5Z5Y z)7S_M5x*z7D!ojVq{Vu2z2(iob|aK5I+U3BGzK~a+AW?hEsfX@7>|tHy8=ob*2mO) zWWQYkM7$>b5`~gFFM9LwT+0~PJ1yB9?Job$Relh*Vgh%}y1e`#Y(0r=J(%pO#GSVT z6O5~p-t)^dZ9A`K3Li8I?e({8sRG09@br}&SH**5v)Xw@{L2r*pBHVFZ=ezk9YRNJ zDUDayckIi}xA`Y1z&du?6EGW!#AiS3ae%||4AnsvRc>%qZUKSg<&B3a5xDBa5Q+MM zi4o?q$0@O}JHxj~Re{iVYzX!uw?xlG7ie8q_ZIeCDDC+U1u?pGWEl~ep>TsELv~QR za==N`E?8rPw$j%rlC6eExdG^tLdmX*!Q9UFx>D--eOFbl{9&DAmK}f|K;?-W6Q0)Vl>|%4{%pnQPYA~bM!mvD=$Xt~( za7hD1|Hs&v(@_m|8kZ>Ks-ST(e~k_xYQ>?>U~I& z^2LvEl+{WZp zq`*Y^Avuv*TSFh^Y?=L~KPTdPD&l%4lC;X7vtiaP#^epgs&CsFNxu&n=ua-WGGO)= zQ;M0|2Nu#`{XM;RnJPTT3>EAcDw;}ng=e8{l=-BbCAI~z1~?5X>+_L~=sl(JvEm9W z>4s3R+ilHzf+L+5!uy(aczjg3%~d%SF`^cq3LfTtemDPB@Nn;a9YTW-FpkC#=6!sA zVSiRjXliXWtu)n*R;r|SZgI{3f_mbHSSpXVVS4qa~MFze&cf!Jqa94X~>n*HUSXdf6#`?tB*!3a*BUwIhv6^t;a7v{JeLt%DB(#!#0ZTS`Cyr9{59Q=+g0Wb9t7aP}a6*ynHa z8_xxyFYreFzaHZ3i_S#<#%jxSUUMtG%<>agx+nTGV0_LmYd_v6!VaO|_0)QQ(*B`2 zO|!b?iDtyc|B!*#W0VabP(ubfd!sxO##Qku0_4v*96CI+pI8@7-h#d^k_S6N0e6#O zUhZx-Lg=}n%iYN(-;9{Nzq~dnZ`JqhLb+R}p$jB64G9%t?dIVg8od-o(b~5IJd2(N z%d)m1Z=$zj^coskAG=G;JJ@N@+7NZJ1N)<+kmFVlBoeySsVAaMP48njqnp!+)CHzm zuYngm7b^VW0w02FO#a1y1(p*r=8mxA4+^?-1PluG8jQbYZVvwPzlBBCOpSt%exKFS z+Vi6m0IsBuUs+$M@FDjJs7=HL)DB}&2*83&?2o*kp zXM{e*jRW=8N2q}KG6%1?$-^|@mlBR^kE^noyDe5`SoQ?dXW`xFgKdIc@wct3l5RY( z2b960xbVpGvtToQYl*?smVC z^hwLN$UmeKzQ~yeb4C}VX>n745e0%6n?skUcjI*;mR&9Rs0icgucW1XZMI03H9YL! z1`J=y68Veg?^A!~nr@_@%FTJ$(Z=|Wb;*WZ09<)>sB7f$`1-}F<_q!;)Ca;T`?x^r zQ2hAI8{3L?%?>oxia~u?m9vR{atop0eL7WPo!gAoff@E%ul0Tz?Uac`f-x2F<1hQ` ztI;Yst4l79^UMEeaaA5h16$LOpyXraKKO&rRz@wLRpu3GG3uv@`}DNmE>s0qSWn{N zCiblV!{Y?x4{VFQ6xVMJB(;<4ajS@L_1%vzg(a12vW^mU1=m!?=F;bt^2!e-1v6ap zUqzL;M%&{r+WvXaf7kXGq3zLBm~gCDstwiDgX>bjfs;C2%qJ+1s6^-?eR*Zt_UUx2`8S5RTHl}o)foD!sk zXgK%d9kM}I&^s?y^?tGzV$mZ6z`Fcrc4yz(D$lf2V4 z|4OpK^yXjRDw(cIro|=C6O!v`zLPo+J}7kJ(}?IxBpFR6DN12{Ze}l=>ZNlc_;Le9 zY!jYQqMbuA__g9>7#@8D=C1J4)qS|44&BP%$t+8(e#?bPTx zX^67u(GZwH0bME9DxDl039%Q|0C#SB6=IKfu%I@T%U!nnNYDK# zzkppX8irPppU`X1S*`t_`ycu%`gO?@6uV^W5hO8{s=Nm#p<~mmk{l}&aY^jgcBfty z8!zwcsQX7xvJyNf12+~v}|_zngU4(!QPKV@xR`5xN9a^2UB5O{<8 zNn~Vn8ue@r>%(Hx58DJBP<#oL1}m)ZHhf1O_+9ZHvDV|tIxt_D&e5u9K!~G$ z{Gq&3&jVmlQU0R`9|O7|RSZ6up|K@-I^`989g=zmwK&dY(7^^1D}%Y2iwviE)PF7j_>)FfkPkQ<9T>U=<0O0e;L#|Vk_Xs5cAqJ|ADWn z{N;bPlzeAZA`|`PAM#}M8Jv3-TW7FkKHPbKDhjPw1sm}xgH3yJud;ypzj_V`=Y7!2 z{h_rqr@t1Z<6ZW8gX)Pr+B$zEma_}FDuPJ1SkaU!>w{2B%fO*NS7kpSLo0Wd;JDgQ z>d!6iXg5Id{Utp0qLh0N%W}txWAMkSM~9DnBE~W6QxI{ZToqJQ3_IVF=s|Q=*c&~B zoTLQ@Ee(oj)#0k_MyYMmih^&*+}5S@08~b1&k!qyCCEhUC4O>&L$L zeG+txtD-Af6>cUQp+oZ1@UDsz1*UX_

sXw=-q8-4QsS@T`n~LzB)I=_&V>&5MqQ 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 literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/zmq/backend/cython/socket.pxd b/.venv/lib/python3.8/site-packages/zmq/backend/cython/socket.pxd new file mode 100644 index 00000000..ff53408a --- /dev/null +++ b/.venv/lib/python3.8/site-packages/zmq/backend/cython/socket.pxd @@ -0,0 +1,49 @@ +"""0MQ Socket class declaration.""" + +# +# Copyright (c) 2010-2011 Brian E. Granger & Min Ragan-Kelley +# +# This file is part of pyzmq. +# +# pyzmq is free software; you can redistribute it and/or modify it under +# the terms of the Lesser GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# pyzmq 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 +# Lesser GNU General Public License for more details. +# +# You should have received a copy of the Lesser GNU General Public License +# along with this program. If not, see . +# + +#----------------------------------------------------------------------------- +# Imports +#----------------------------------------------------------------------------- + +from .context cimport Context + +#----------------------------------------------------------------------------- +# Code +#----------------------------------------------------------------------------- + + +cdef class Socket: + + cdef object __weakref__ # enable weakref + cdef void *handle # The C handle for the underlying zmq object. + cdef bint _shadow # whether the Socket is a shadow wrapper of another + # Hold on to a reference to the context to make sure it is not garbage + # collected until the socket it done with it. + cdef public Context context # The zmq Context object that owns this. + cdef public bint _closed # bool property for a closed socket. + cdef public int copy_threshold # threshold below which pyzmq will always copy messages + cdef int _pid # the pid of the process which created me (for fork safety) + cdef void _c_close(self) # underlying close of zmq socket + + # cpdef methods for direct-cython access: + cpdef object send(self, object data, int flags=*, copy=*, track=*) + cpdef object recv(self, int flags=*, copy=*, track=*) + diff --git a/.venv/lib/python3.8/site-packages/zmq/backend/cython/utils.cpython-38-x86_64-linux-gnu.so b/.venv/lib/python3.8/site-packages/zmq/backend/cython/utils.cpython-38-x86_64-linux-gnu.so new file mode 100755 index 0000000000000000000000000000000000000000..01bc986372c58f6b51322786510ddbfcb0c11c75 GIT binary patch literal 55616 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 literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/zmq/backend/select.py b/.venv/lib/python3.8/site-packages/zmq/backend/select.py new file mode 100644 index 00000000..bdcb9c52 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/zmq/backend/select.py @@ -0,0 +1,40 @@ +"""Import basic exposure of libzmq C API as a backend""" + +# Copyright (C) PyZMQ Developers +# Distributed under the terms of the Modified BSD License. + +public_api = [ + 'Context', + 'Socket', + 'Frame', + 'Message', + 'device', + 'proxy', + 'proxy_steerable', + 'zmq_poll', + 'strerror', + 'zmq_errno', + 'has', + 'curve_keypair', + 'curve_public', + 'constants', + 'zmq_version_info', + 'IPC_PATH_MAX_LEN', +] + +def select_backend(name): + """Select the pyzmq backend""" + try: + mod = __import__(name, fromlist=public_api) + except ImportError: + raise + except Exception as e: + import sys + from zmq.utils.sixcerpt import reraise + exc_info = sys.exc_info() + reraise(ImportError, ImportError("Importing %s failed with %s" % (name, e)), exc_info[2]) + + ns = {} + for key in public_api: + ns[key] = getattr(mod, key) + return ns diff --git a/.venv/lib/python3.8/site-packages/zmq/decorators.py b/.venv/lib/python3.8/site-packages/zmq/decorators.py new file mode 100644 index 00000000..f95c946e --- /dev/null +++ b/.venv/lib/python3.8/site-packages/zmq/decorators.py @@ -0,0 +1,188 @@ +"""Decorators for running functions with context/sockets. + +.. versionadded:: 15.3 + +Like using Contexts and Sockets as context managers, but with decorator syntax. +Context and sockets are closed at the end of the function. + +For example:: + + from zmq.decorators import context, socket + + @context() + @socket(zmq.PUSH) + def work(ctx, push): + ... +""" + +# Copyright (c) PyZMQ Developers. +# Distributed under the terms of the Modified BSD License. + +__all__ = ( + 'context', + 'socket', +) + +from functools import wraps + +import zmq +from zmq.utils.strtypes import basestring + + +class _Decorator(object): + '''The mini decorator factory''' + + def __init__(self, target=None): + self._target = target + + def __call__(self, *dec_args, **dec_kwargs): + ''' + The main logic of decorator + + Here is how those arguments works:: + + @out_decorator(*dec_args, *dec_kwargs) + def func(*wrap_args, **wrap_kwargs): + ... + + And in the ``wrapper``, we simply create ``self.target`` instance via + ``with``:: + + target = self.get_target(*args, **kwargs) + with target(*dec_args, **dec_kwargs) as obj: + ... + + ''' + kw_name, dec_args, dec_kwargs = self.process_decorator_args(*dec_args, **dec_kwargs) + + def decorator(func): + @wraps(func) + def wrapper(*args, **kwargs): + target = self.get_target(*args, **kwargs) + + with target(*dec_args, **dec_kwargs) as obj: + # insert our object into args + if kw_name and kw_name not in kwargs: + kwargs[kw_name] = obj + elif kw_name and kw_name in kwargs: + raise TypeError( + "{0}() got multiple values for" + " argument '{1}'".format( + func.__name__, kw_name)) + else: + args = args + (obj,) + + return func(*args, **kwargs) + + return wrapper + + return decorator + + def get_target(self, *args, **kwargs): + """Return the target function + + Allows modifying args/kwargs to be passed. + """ + return self._target + + def process_decorator_args(self, *args, **kwargs): + """Process args passed to the decorator. + + args not consumed by the decorator will be passed to the target factory + (Context/Socket constructor). + """ + kw_name = None + + if isinstance(kwargs.get('name'), basestring): + kw_name = kwargs.pop('name') + elif len(args) >= 1 and isinstance(args[0], basestring): + kw_name = args[0] + args = args[1:] + + return kw_name, args, kwargs + + +class _ContextDecorator(_Decorator): + """Decorator subclass for Contexts""" + def __init__(self): + super(_ContextDecorator, self).__init__(zmq.Context) + + +class _SocketDecorator(_Decorator): + """Decorator subclass for sockets + + Gets the context from other args. + """ + + def process_decorator_args(self, *args, **kwargs): + """Also grab context_name out of kwargs""" + kw_name, args, kwargs = super(_SocketDecorator, self).process_decorator_args(*args, **kwargs) + self.context_name = kwargs.pop('context_name', 'context') + return kw_name, args, kwargs + + def get_target(self, *args, **kwargs): + """Get context, based on call-time args""" + context = self._get_context(*args, **kwargs) + return context.socket + + def _get_context(self, *args, **kwargs): + ''' + Find the ``zmq.Context`` from ``args`` and ``kwargs`` at call time. + + First, if there is an keyword argument named ``context`` and it is a + ``zmq.Context`` instance , we will take it. + + Second, we check all the ``args``, take the first ``zmq.Context`` + instance. + + Finally, we will provide default Context -- ``zmq.Context.instance`` + + :return: a ``zmq.Context`` instance + ''' + if self.context_name in kwargs: + ctx = kwargs[self.context_name] + + if isinstance(ctx, zmq.Context): + return ctx + + for arg in args: + if isinstance(arg, zmq.Context): + return arg + # not specified by any decorator + return zmq.Context.instance() + + +def context(*args, **kwargs): + '''Decorator for adding a Context to a function. + + Usage:: + + @context() + def foo(ctx): + ... + + .. versionadded:: 15.3 + + :param str name: the keyword argument passed to decorated function + ''' + return _ContextDecorator()(*args, **kwargs) + + +def socket(*args, **kwargs): + '''Decorator for adding a socket to a function. + + Usage:: + + @socket(zmq.PUSH) + def foo(push): + ... + + .. versionadded:: 15.3 + + :param str name: the keyword argument passed to decorated function + :param str context_name: the keyword only argument to identify context + object + ''' + return _SocketDecorator()(*args, **kwargs) + + diff --git a/.venv/lib/python3.8/site-packages/zmq/devices/__init__.py b/.venv/lib/python3.8/site-packages/zmq/devices/__init__.py new file mode 100644 index 00000000..4a24de0b --- /dev/null +++ b/.venv/lib/python3.8/site-packages/zmq/devices/__init__.py @@ -0,0 +1,29 @@ +"""0MQ Device classes for running in background threads or processes.""" + +# Copyright (C) PyZMQ Developers +# Distributed under the terms of the Modified BSD License. + +from zmq import device +from zmq.devices import ( + basedevice, + monitoredqueue, + monitoredqueuedevice, + proxydevice, + proxysteerabledevice, +) + +from zmq.devices.basedevice import * +from zmq.devices.proxydevice import * +from zmq.devices.proxysteerabledevice import * +from zmq.devices.monitoredqueue import * +from zmq.devices.monitoredqueuedevice import * + +__all__ = ['device'] +for submod in ( + basedevice, + proxydevice, + proxysteerabledevice, + monitoredqueue, + monitoredqueuedevice +): + __all__.extend(submod.__all__) diff --git a/.venv/lib/python3.8/site-packages/zmq/devices/__pycache__/__init__.cpython-38.pyc b/.venv/lib/python3.8/site-packages/zmq/devices/__pycache__/__init__.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..df3f441cd0a5e17882b618a8f3c06c8cee7ba42d GIT binary patch literal 703 zcmZWmO^eh(5be&SlQ>_y!lED|xsEUsF9R!xi0pL*Q7;V=GU?ixXm^t7PBgOz*`Kl= z{VV=}J>=@izn~W@vkhjnn^g7ddU>f=c{iC12`+YZ6MuII`O$&?VhCQ~W4>SzgcCu9 zBdKz@L%Z`p4wTDX#W+(Q_mt0l74TqRbLE}49mkbJn@2W}ZJuCeYs#nKf)4>O@GjUH zd4J50V0wKFM<1qNDJ9#D@ZOM_fBEvs`RniuK4mF{sZ5Lk6J8WL)ODU``8v$rjd&>*%o)X<(BV#^w# zT(h&_WDiUQpp%ufLihptSmQv+tJ&Swk7H4!am)voYP-MXBRnl`6^tGrPrF^{#;v_B z_!#)T9&7QpO@6 W%p(jg8`FnDK<#!s$Dwxr4*Wj>9nU)e literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/zmq/devices/__pycache__/basedevice.cpython-38.pyc b/.venv/lib/python3.8/site-packages/zmq/devices/__pycache__/basedevice.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..2753e71166f69b6f6774f70ad98c0f0698b30fd1 GIT binary patch literal 8400 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 PFaDLWx4g7mUatN>f%kKS literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/zmq/devices/__pycache__/monitoredqueue.cpython-38.pyc b/.venv/lib/python3.8/site-packages/zmq/devices/__pycache__/monitoredqueue.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..eb8ebc6e6a98d853bd16c21d47c22307c6b96f5c GIT binary patch literal 988 zcmY*XO;6iE5ZzsW#Bm|?L!#wU`ACq`oH$g9P%G4`RcVN5x%lF`*(EGEw%J{W1T9r1 z;D02?{-GXx?TItDUg)gTP&(F*-@F;Gci!y&^0JS>obNxQM>aygOmN>U2wuUG>)I^Z%W(s&f}B>tMPV7)i#O`0!!|8)V|3hB4z z=5GWadAj$(zlJlSZr?GlzvjXl`a;{VnVDmz(Xg;Ypja5$`kEzSFpp_(eV`-AJ$`o~)S8t07|#+xR*5v8V%gV@}W08#7@z z)PJgZz!~K#)xH7H=m;r%M2<OSQBk&=fZ(6aK(3k$B-e~p7ST2N^9J0)=OJWa#mW7rMPH zNth@-!3JC^KyGh$XXkylv?=ea(#|1Yb=&m9I!_~+fsQKlq2W6W$}O-dna^ZiGRMMP zsL(ZgnLn@*OO>okY+wrmEq$g0p47Rd#?JY*BNHCNZ1yJq+9}LFL}f>xm$nb54t}5cK`qY literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/zmq/devices/__pycache__/monitoredqueuedevice.cpython-38.pyc b/.venv/lib/python3.8/site-packages/zmq/devices/__pycache__/monitoredqueuedevice.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..60e227576d1a1980dddafd45922c3e34a996e304 GIT binary patch literal 2378 zcmb7GNsk*v6zq7*DnBdvvIQO?<<%;O@FxgPxm!>yrH`N4xn_mz^Wavwgs zGxVzNLnV)n??hTuEwijvo=%mBc)jW4Uo5mXyP;jJXK%EHFGyWXaui9qVgfKSs@5!HT0ARQI#Kt36c}yaadD6!M_Xs9F`22kquH@qgD4WGO+1`|)3#4;{5Q;_H%`PhF25P%-&x!~!Dep# zYW-$?@1EMH&Z%42bp+?ua|hFX*#hV(cJ}TNXbrU}%2}u-Y%jF(@x59nvH^nVUBbV> zMalvX-h;viZG5lEdpNIps?5XMoe!|rWRhjC*(WzIaN_*#?yyUV$)ik|#DtmTWlHOQ z2=GQ}bJ7VzF5@sfH%t+LOxVE0OzDsp%;0~8^gZ1UoV@b}6sbG5m#=eqe&PTl-!+0VD11?4lE=KnZ zK8&bL>VnCM`A*M7JYvh58BZn?p`cgEjG3a}G%{tL9@h$^f+YouI7f?N<8ck|@t747 z#i(_(kKUt24mGuT$SAcZR%4)+c9;}Xd|fM}yR{T!qKM)tPLwd6Yh<(=^57ARQZ1P- zXEUh^%^rXI?CJf-q-Re;o=&*Xo9u9!Kmhqaqt3>-gh9D1n&5mhf#Swc7NLzC;20vt zC`2-Gyh-jICTYs{L}QoWU_b-iY5cv|yV_c)pa`AIrotxK|0nvq_{WW(Q#*mZTA_eat16GdHG;n#~5TwlC=7F_cx)Ge5rm&v4Y u*C?*g2BS1Z8@vDqmH$QEJinw)rU^J+d&9nF_uY-b;L^Y!_>PUgfBprTf@re< literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/zmq/devices/__pycache__/proxydevice.cpython-38.pyc b/.venv/lib/python3.8/site-packages/zmq/devices/__pycache__/proxydevice.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8f7da7504d2a2f3915d12941b64086875d54783a GIT binary patch literal 3501 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 timeout): + time.sleep(.001) + toc = time.time() + + +class BackgroundDevice(Device): + """Base class for launching Devices in background processes and threads.""" + + launcher=None + _launch_class=None + + def start(self): + self.launcher = self._launch_class(target=self.run) + self.launcher.daemon = self.daemon + return self.launcher.start() + + def join(self, timeout=None): + return self.launcher.join(timeout=timeout) + + +class ThreadDevice(BackgroundDevice): + """A Device that will be run in a background Thread. + + See Device for details. + """ + _launch_class=Thread + +class ProcessDevice(BackgroundDevice): + """A Device that will be run in a background Process. + + See Device for details. + """ + _launch_class=Process + context_factory = Context + """Callable that returns a context. Typically either Context.instance or Context, + depending on whether the device should share the global instance or not. + """ + + +__all__ = ['Device', 'ThreadDevice', 'ProcessDevice'] diff --git a/.venv/lib/python3.8/site-packages/zmq/devices/monitoredqueue.cpython-38-x86_64-linux-gnu.so b/.venv/lib/python3.8/site-packages/zmq/devices/monitoredqueue.cpython-38-x86_64-linux-gnu.so new file mode 100755 index 0000000000000000000000000000000000000000..bb566015c45c517cd5b0a6432c47bbb8e4b23148 GIT binary patch literal 72392 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 CoP;<4 literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/zmq/devices/monitoredqueue.pxd b/.venv/lib/python3.8/site-packages/zmq/devices/monitoredqueue.pxd new file mode 100644 index 00000000..865f142e --- /dev/null +++ b/.venv/lib/python3.8/site-packages/zmq/devices/monitoredqueue.pxd @@ -0,0 +1,177 @@ +"""MonitoredQueue class declarations. + +Authors +------- +* MinRK +* Brian Granger +""" + +# +# Copyright (c) 2010 Min Ragan-Kelley, Brian Granger +# +# This file is part of pyzmq, but is derived and adapted from zmq_queue.cpp +# originally from libzmq-2.1.6, used under LGPLv3 +# +# pyzmq is free software; you can redistribute it and/or modify it under +# the terms of the Lesser GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# pyzmq 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 +# Lesser GNU General Public License for more details. +# +# You should have received a copy of the Lesser GNU General Public License +# along with this program. If not, see . +# + +#----------------------------------------------------------------------------- +# Imports +#----------------------------------------------------------------------------- + +from zmq.backend.cython.libzmq cimport * + +#----------------------------------------------------------------------------- +# MonitoredQueue C functions +#----------------------------------------------------------------------------- + +cdef inline int _relay(void *insocket_, void *outsocket_, void *sidesocket_, + zmq_msg_t msg, zmq_msg_t side_msg, zmq_msg_t id_msg, + bint swap_ids) nogil: + cdef int rc + cdef int64_t flag_2 + cdef int flag_3 + cdef int flags + cdef bint more + cdef size_t flagsz + cdef void * flag_ptr + + if ZMQ_VERSION_MAJOR < 3: + flagsz = sizeof (int64_t) + flag_ptr = &flag_2 + else: + flagsz = sizeof (int) + flag_ptr = &flag_3 + + if swap_ids:# both router, must send second identity first + # recv two ids into msg, id_msg + rc = zmq_msg_recv(&msg, insocket_, 0) + if rc < 0: return rc + + rc = zmq_msg_recv(&id_msg, insocket_, 0) + if rc < 0: return rc + + # send second id (id_msg) first + #!!!! always send a copy before the original !!!! + rc = zmq_msg_copy(&side_msg, &id_msg) + if rc < 0: return rc + rc = zmq_msg_send(&side_msg, outsocket_, ZMQ_SNDMORE) + if rc < 0: return rc + rc = zmq_msg_send(&id_msg, sidesocket_, ZMQ_SNDMORE) + if rc < 0: return rc + # send first id (msg) second + rc = zmq_msg_copy(&side_msg, &msg) + if rc < 0: return rc + rc = zmq_msg_send(&side_msg, outsocket_, ZMQ_SNDMORE) + if rc < 0: return rc + rc = zmq_msg_send(&msg, sidesocket_, ZMQ_SNDMORE) + if rc < 0: return rc + while (True): + rc = zmq_msg_recv(&msg, insocket_, 0) + if rc < 0: return rc + # assert (rc == 0) + rc = zmq_getsockopt (insocket_, ZMQ_RCVMORE, flag_ptr, &flagsz) + if rc < 0: return rc + flags = 0 + if ZMQ_VERSION_MAJOR < 3: + if flag_2: + flags |= ZMQ_SNDMORE + else: + if flag_3: + flags |= ZMQ_SNDMORE + # LABEL has been removed: + # rc = zmq_getsockopt (insocket_, ZMQ_RCVLABEL, flag_ptr, &flagsz) + # if flag_3: + # flags |= ZMQ_SNDLABEL + # assert (rc == 0) + + rc = zmq_msg_copy(&side_msg, &msg) + if rc < 0: return rc + if flags: + rc = zmq_msg_send(&side_msg, outsocket_, flags) + if rc < 0: return rc + # only SNDMORE for side-socket + rc = zmq_msg_send(&msg, sidesocket_, ZMQ_SNDMORE) + if rc < 0: return rc + else: + rc = zmq_msg_send(&side_msg, outsocket_, 0) + if rc < 0: return rc + rc = zmq_msg_send(&msg, sidesocket_, 0) + if rc < 0: return rc + break + return rc + +# the MonitoredQueue C function, adapted from zmq::queue.cpp : +cdef inline int c_monitored_queue (void *insocket_, void *outsocket_, + void *sidesocket_, zmq_msg_t *in_msg_ptr, + zmq_msg_t *out_msg_ptr, int swap_ids) nogil: + """The actual C function for a monitored queue device. + + See ``monitored_queue()`` for details. + """ + + cdef zmq_msg_t msg + cdef int rc = zmq_msg_init (&msg) + cdef zmq_msg_t id_msg + rc = zmq_msg_init (&id_msg) + if rc < 0: return rc + cdef zmq_msg_t side_msg + rc = zmq_msg_init (&side_msg) + if rc < 0: return rc + + cdef zmq_pollitem_t items [2] + items [0].socket = insocket_ + items [0].fd = 0 + items [0].events = ZMQ_POLLIN + items [0].revents = 0 + items [1].socket = outsocket_ + items [1].fd = 0 + items [1].events = ZMQ_POLLIN + items [1].revents = 0 + # I don't think sidesocket should be polled? + # items [2].socket = sidesocket_ + # items [2].fd = 0 + # items [2].events = ZMQ_POLLIN + # items [2].revents = 0 + + while (True): + + # // Wait while there are either requests or replies to process. + rc = zmq_poll (&items [0], 2, -1) + if rc < 0: return rc + # // The algorithm below asumes ratio of request and replies processed + # // under full load to be 1:1. Although processing requests replies + # // first is tempting it is suspectible to DoS attacks (overloading + # // the system with unsolicited replies). + # + # // Process a request. + if (items [0].revents & ZMQ_POLLIN): + # send in_prefix to side socket + rc = zmq_msg_copy(&side_msg, in_msg_ptr) + if rc < 0: return rc + rc = zmq_msg_send(&side_msg, sidesocket_, ZMQ_SNDMORE) + if rc < 0: return rc + # relay the rest of the message + rc = _relay(insocket_, outsocket_, sidesocket_, msg, side_msg, id_msg, swap_ids) + if rc < 0: return rc + if (items [1].revents & ZMQ_POLLIN): + # send out_prefix to side socket + rc = zmq_msg_copy(&side_msg, out_msg_ptr) + if rc < 0: return rc + rc = zmq_msg_send(&side_msg, sidesocket_, ZMQ_SNDMORE) + if rc < 0: return rc + # relay the rest of the message + rc = _relay(outsocket_, insocket_, sidesocket_, msg, side_msg, id_msg, swap_ids) + if rc < 0: return rc + return rc diff --git a/.venv/lib/python3.8/site-packages/zmq/devices/monitoredqueue.py b/.venv/lib/python3.8/site-packages/zmq/devices/monitoredqueue.py new file mode 100644 index 00000000..c6d91429 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/zmq/devices/monitoredqueue.py @@ -0,0 +1,37 @@ +"""pure Python monitored_queue function + +For use when Cython extension is unavailable (PyPy). + +Authors +------- +* MinRK +""" + +# Copyright (C) PyZMQ Developers +# Distributed under the terms of the Modified BSD License. + +import zmq + +def _relay(ins, outs, sides, prefix, swap_ids): + msg = ins.recv_multipart() + if swap_ids: + msg[:2] = msg[:2][::-1] + outs.send_multipart(msg) + sides.send_multipart([prefix] + msg) + +def monitored_queue(in_socket, out_socket, mon_socket, + in_prefix=b'in', out_prefix=b'out'): + + swap_ids = in_socket.type == zmq.ROUTER and out_socket.type == zmq.ROUTER + + poller = zmq.Poller() + poller.register(in_socket, zmq.POLLIN) + poller.register(out_socket, zmq.POLLIN) + while True: + events = dict(poller.poll()) + if in_socket in events: + _relay(in_socket, out_socket, mon_socket, in_prefix, swap_ids) + if out_socket in events: + _relay(out_socket, in_socket, mon_socket, out_prefix, swap_ids) + +__all__ = ['monitored_queue'] diff --git a/.venv/lib/python3.8/site-packages/zmq/devices/monitoredqueuedevice.py b/.venv/lib/python3.8/site-packages/zmq/devices/monitoredqueuedevice.py new file mode 100644 index 00000000..9723f866 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/zmq/devices/monitoredqueuedevice.py @@ -0,0 +1,66 @@ +"""MonitoredQueue classes and functions.""" + +# Copyright (C) PyZMQ Developers +# Distributed under the terms of the Modified BSD License. + + +from zmq import ZMQError, PUB +from zmq.devices.proxydevice import ProxyBase, Proxy, ThreadProxy, ProcessProxy +from zmq.devices.monitoredqueue import monitored_queue + + +class MonitoredQueueBase(ProxyBase): + """Base class for overriding methods.""" + + _in_prefix = b'' + _out_prefix = b'' + + def __init__(self, in_type, out_type, mon_type=PUB, in_prefix=b'in', out_prefix=b'out'): + + ProxyBase.__init__(self, in_type=in_type, out_type=out_type, mon_type=mon_type) + + self._in_prefix = in_prefix + self._out_prefix = out_prefix + + def run_device(self): + ins,outs,mons = self._setup_sockets() + monitored_queue(ins, outs, mons, self._in_prefix, self._out_prefix) + + +class MonitoredQueue(MonitoredQueueBase, Proxy): + """Class for running monitored_queue in the background. + + See zmq.devices.Device for most of the spec. MonitoredQueue differs from Proxy, + only in that it adds a ``prefix`` to messages sent on the monitor socket, + with a different prefix for each direction. + + MQ also supports ROUTER on both sides, which zmq.proxy does not. + + If a message arrives on `in_sock`, it will be prefixed with `in_prefix` on the monitor socket. + If it arrives on out_sock, it will be prefixed with `out_prefix`. + + A PUB socket is the most logical choice for the mon_socket, but it is not required. + """ + pass + + +class ThreadMonitoredQueue(MonitoredQueueBase, ThreadProxy): + """Run zmq.monitored_queue in a background thread. + + See MonitoredQueue and Proxy for details. + """ + pass + + +class ProcessMonitoredQueue(MonitoredQueueBase, ProcessProxy): + """Run zmq.monitored_queue in a background thread. + + See MonitoredQueue and Proxy for details. + """ + + +__all__ = [ + 'MonitoredQueue', + 'ThreadMonitoredQueue', + 'ProcessMonitoredQueue' +] diff --git a/.venv/lib/python3.8/site-packages/zmq/devices/proxydevice.py b/.venv/lib/python3.8/site-packages/zmq/devices/proxydevice.py new file mode 100644 index 00000000..ecadb530 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/zmq/devices/proxydevice.py @@ -0,0 +1,104 @@ +"""Proxy classes and functions.""" + +# Copyright (C) PyZMQ Developers +# Distributed under the terms of the Modified BSD License. + +import zmq +from zmq.devices.basedevice import Device, ThreadDevice, ProcessDevice + + +class ProxyBase(object): + """Base class for overriding methods.""" + + def __init__(self, in_type, out_type, mon_type=zmq.PUB): + + Device.__init__(self, in_type=in_type, out_type=out_type) + self.mon_type = mon_type + self._mon_binds = [] + self._mon_connects = [] + self._mon_sockopts = [] + + def bind_mon(self, addr): + """Enqueue ZMQ address for binding on mon_socket. + + See zmq.Socket.bind for details. + """ + self._mon_binds.append(addr) + + def bind_mon_to_random_port(self, addr, *args, **kwargs): + """Enqueue a random port on the given interface for binding on + mon_socket. + + See zmq.Socket.bind_to_random_port for details. + + .. versionadded:: 18.0 + """ + port = self._reserve_random_port(addr, *args, **kwargs) + + self.bind_mon('%s:%i' % (addr, port)) + + return port + + def connect_mon(self, addr): + """Enqueue ZMQ address for connecting on mon_socket. + + See zmq.Socket.connect for details. + """ + self._mon_connects.append(addr) + + def setsockopt_mon(self, opt, value): + """Enqueue setsockopt(opt, value) for mon_socket + + See zmq.Socket.setsockopt for details. + """ + self._mon_sockopts.append((opt, value)) + + def _setup_sockets(self): + ins,outs = Device._setup_sockets(self) + ctx = self._context + mons = ctx.socket(self.mon_type) + + # set sockopts (must be done first, in case of zmq.IDENTITY) + for opt,value in self._mon_sockopts: + mons.setsockopt(opt, value) + + for iface in self._mon_binds: + mons.bind(iface) + + for iface in self._mon_connects: + mons.connect(iface) + + return ins,outs,mons + + def run_device(self): + ins,outs,mons = self._setup_sockets() + zmq.proxy(ins, outs, mons) + +class Proxy(ProxyBase, Device): + """Threadsafe Proxy object. + + See zmq.devices.Device for most of the spec. This subclass adds a + _mon version of each _{in|out} method, for configuring the + monitor socket. + + A Proxy is a 3-socket ZMQ Device that functions just like a + QUEUE, except each message is also sent out on the monitor socket. + + A PUB socket is the most logical choice for the mon_socket, but it is not required. + """ + pass + +class ThreadProxy(ProxyBase, ThreadDevice): + """Proxy in a Thread. See Proxy for more.""" + pass + +class ProcessProxy(ProxyBase, ProcessDevice): + """Proxy in a Process. See Proxy for more.""" + pass + + +__all__ = [ + 'Proxy', + 'ThreadProxy', + 'ProcessProxy', +] diff --git a/.venv/lib/python3.8/site-packages/zmq/devices/proxysteerabledevice.py b/.venv/lib/python3.8/site-packages/zmq/devices/proxysteerabledevice.py new file mode 100644 index 00000000..56f5e3a5 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/zmq/devices/proxysteerabledevice.py @@ -0,0 +1,112 @@ +"""Classes for running a steerable ZMQ proxy""" + +# Copyright (C) PyZMQ Developers +# Distributed under the terms of the Modified BSD License. + +import zmq +from zmq.devices.proxydevice import Proxy, ThreadProxy, ProcessProxy + + +class ProxySteerableBase(object): + """Base class for overriding methods.""" + + def __init__(self, in_type, out_type, mon_type=zmq.PUB, ctrl_type=None): + super(ProxySteerableBase, self).__init__( + in_type=in_type, + out_type=out_type, + mon_type=mon_type + ) + self.ctrl_type = ctrl_type + self._ctrl_binds = [] + self._ctrl_connects = [] + self._ctrl_sockopts = [] + + def bind_ctrl(self, addr): + """Enqueue ZMQ address for binding on ctrl_socket. + + See zmq.Socket.bind for details. + """ + self._ctrl_binds.append(addr) + + def bind_ctrl_to_random_port(self, addr, *args, **kwargs): + """Enqueue a random port on the given interface for binding on + ctrl_socket. + + See zmq.Socket.bind_to_random_port for details. + """ + port = self._reserve_random_port(addr, *args, **kwargs) + + self.bind_ctrl('%s:%i' % (addr, port)) + + return port + + def connect_ctrl(self, addr): + """Enqueue ZMQ address for connecting on ctrl_socket. + + See zmq.Socket.connect for details. + """ + self._ctrl_connects.append(addr) + + def setsockopt_ctrl(self, opt, value): + """Enqueue setsockopt(opt, value) for ctrl_socket + + See zmq.Socket.setsockopt for details. + """ + self._ctrl_sockopts.append((opt, value)) + + def _setup_sockets(self): + ins, outs, mons = super(ProxySteerableBase, self)._setup_sockets() + ctx = self._context + ctrls = ctx.socket(self.ctrl_type) + + for opt, value in self._ctrl_sockopts: + ctrls.setsockopt(opt, value) + + for iface in self._ctrl_binds: + ctrls.bind(iface) + + for iface in self._ctrl_connects: + ctrls.connect(iface) + + return ins, outs, mons, ctrls + + def run_device(self): + ins, outs, mons, ctrls = self._setup_sockets() + zmq.proxy_steerable(ins, outs, mons, ctrls) + + +class ProxySteerable(ProxySteerableBase, Proxy): + """Class for running a steerable proxy in the background. + + See zmq.devices.Proxy for most of the spec. If the control socket is not + NULL, the proxy supports control flow, provided by the socket. + + If PAUSE is received on this socket, the proxy suspends its activities. If + RESUME is received, it goes on. If TERMINATE is received, it terminates + smoothly. If the control socket is NULL, the proxy behave exactly as if + zmq.devices.Proxy had been used. + + This subclass adds a _ctrl version of each _{in|out} + method, for configuring the control socket. + + .. versionadded:: libzmq-4.1 + .. versionadded:: 18.0 + """ + pass + + +class ThreadProxySteerable(ProxySteerableBase, ThreadProxy): + """ProxySteerable in a Thread. See ProxySteerable for details.""" + pass + + +class ProcessProxySteerable(ProxySteerableBase, ProcessProxy): + """ProxySteerable in a Process. See ProxySteerable for details.""" + pass + + +__all__ = [ + 'ProxySteerable', + 'ThreadProxySteerable', + 'ProcessProxySteerable', +] diff --git a/.venv/lib/python3.8/site-packages/zmq/error.py b/.venv/lib/python3.8/site-packages/zmq/error.py new file mode 100644 index 00000000..bbf045d6 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/zmq/error.py @@ -0,0 +1,198 @@ +"""0MQ Error classes and functions.""" + +# Copyright (C) PyZMQ Developers +# Distributed under the terms of the Modified BSD License. + +from errno import EINTR + + +class ZMQBaseError(Exception): + """Base exception class for 0MQ errors in Python.""" + pass + +class ZMQError(ZMQBaseError): + """Wrap an errno style error. + + Parameters + ---------- + errno : int + The ZMQ errno or None. If None, then ``zmq_errno()`` is called and + used. + msg : string + Description of the error or None. + """ + errno = None + + def __init__(self, errno=None, msg=None): + """Wrap an errno style error. + + Parameters + ---------- + errno : int + The ZMQ errno or None. If None, then ``zmq_errno()`` is called and + used. + msg : string + Description of the error or None. + """ + from zmq.backend import strerror, zmq_errno + if errno is None: + errno = zmq_errno() + if isinstance(errno, int): + self.errno = errno + if msg is None: + self.strerror = strerror(errno) + else: + self.strerror = msg + else: + if msg is None: + self.strerror = str(errno) + else: + self.strerror = msg + # flush signals, because there could be a SIGINT + # waiting to pounce, resulting in uncaught exceptions. + # Doing this here means getting SIGINT during a blocking + # libzmq call will raise a *catchable* KeyboardInterrupt + # PyErr_CheckSignals() + + def __str__(self): + return self.strerror + + def __repr__(self): + return "%s('%s')" % (self.__class__.__name__, str(self)) + + +class ZMQBindError(ZMQBaseError): + """An error for ``Socket.bind_to_random_port()``. + + See Also + -------- + .Socket.bind_to_random_port + """ + pass + + +class NotDone(ZMQBaseError): + """Raised when timeout is reached while waiting for 0MQ to finish with a Message + + See Also + -------- + .MessageTracker.wait : object for tracking when ZeroMQ is done + """ + pass + + +class ContextTerminated(ZMQError): + """Wrapper for zmq.ETERM + + .. versionadded:: 13.0 + """ + def __init__(self, errno='ignored', msg='ignored'): + from zmq import ETERM + super(ContextTerminated, self).__init__(ETERM) + + +class Again(ZMQError): + """Wrapper for zmq.EAGAIN + + .. versionadded:: 13.0 + """ + + def __init__(self, errno='ignored', msg='ignored'): + from zmq import EAGAIN + super(Again, self).__init__(EAGAIN) + + +try: + InterruptedError +except NameError: + InterruptedError = OSError + +class InterruptedSystemCall(ZMQError, InterruptedError): + """Wrapper for EINTR + + This exception should be caught internally in pyzmq + to retry system calls, and not propagate to the user. + + .. versionadded:: 14.7 + """ + + def __init__(self, errno='ignored', msg='ignored'): + super(InterruptedSystemCall, self).__init__(EINTR) + + def __str__(self): + s = super(InterruptedSystemCall, self).__str__() + return s + ": This call should have been retried. Please report this to pyzmq." + + +def _check_rc(rc, errno=None, error_without_errno=True): + """internal utility for checking zmq return condition + + and raising the appropriate Exception class + """ + if rc == -1: + if errno is None: + from zmq.backend import zmq_errno + errno = zmq_errno() + if errno == 0 and not error_without_errno: + return + from zmq import EAGAIN, ETERM + if errno == EINTR: + raise InterruptedSystemCall(errno) + elif errno == EAGAIN: + raise Again(errno) + elif errno == ETERM: + raise ContextTerminated(errno) + else: + raise ZMQError(errno) + +_zmq_version_info = None +_zmq_version = None + +class ZMQVersionError(NotImplementedError): + """Raised when a feature is not provided by the linked version of libzmq. + + .. versionadded:: 14.2 + """ + min_version = None + def __init__(self, min_version, msg='Feature'): + global _zmq_version + if _zmq_version is None: + from zmq import zmq_version + _zmq_version = zmq_version() + self.msg = msg + self.min_version = min_version + self.version = _zmq_version + + def __repr__(self): + return "ZMQVersionError('%s')" % str(self) + + def __str__(self): + return "%s requires libzmq >= %s, have %s" % (self.msg, self.min_version, self.version) + + +def _check_version(min_version_info, msg='Feature'): + """Check for libzmq + + raises ZMQVersionError if current zmq version is not at least min_version + + min_version_info is a tuple of integers, and will be compared against zmq.zmq_version_info(). + """ + global _zmq_version_info + if _zmq_version_info is None: + from zmq import zmq_version_info + _zmq_version_info = zmq_version_info() + if _zmq_version_info < min_version_info: + min_version = '.'.join(str(v) for v in min_version_info) + raise ZMQVersionError(min_version, msg) + + +__all__ = [ + 'ZMQBaseError', + 'ZMQBindError', + 'ZMQError', + 'NotDone', + 'ContextTerminated', + 'InterruptedSystemCall', + 'Again', + 'ZMQVersionError', +] diff --git a/.venv/lib/python3.8/site-packages/zmq/eventloop/__init__.py b/.venv/lib/python3.8/site-packages/zmq/eventloop/__init__.py new file mode 100644 index 00000000..9af3fe22 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/zmq/eventloop/__init__.py @@ -0,0 +1,5 @@ +"""Tornado eventloop integration for pyzmq""" + +from zmq.eventloop.ioloop import IOLoop + +__all__ = ['IOLoop'] diff --git a/.venv/lib/python3.8/site-packages/zmq/eventloop/__pycache__/__init__.cpython-38.pyc b/.venv/lib/python3.8/site-packages/zmq/eventloop/__pycache__/__init__.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..27ac69dd52d71a229e0a9cc3face54d1df745eb5 GIT binary patch literal 278 zcmYj~y-vh15QJ@C0tj&(6;(QvB5{=hgb*zff&ysLtfE_USoja050a~R9bSkcEfudo z#pa3=Bkin4n*H{1K0jon{NoEO?e8i4m!NP(vpOL|)-vQM47Z{coZ)QA+Zkr}tjss3 z4?emMeWBizOUC<9XqVJ7c1e3zJo#9JVPju^2*gT0?p@#AP$^CyZp&=k2SC37XpgB> z?;y4I6Kh+WI-M~9pDgBdwzc1LnQV|jhidIYw|G%ly+12us=n#_p*d?L0p$)T0kqQz Wpbo=$aA7^Jjk@H7TV-UKI1+zMn@dCh literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/zmq/eventloop/__pycache__/_deprecated.cpython-38.pyc b/.venv/lib/python3.8/site-packages/zmq/eventloop/__pycache__/_deprecated.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..1b8f205e348d2e790c06bec8ef1d66fec31344fa GIT binary patch literal 7217 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 XfvYpDX3W?#ugtu9j8)CDX&V0l=;G$2 literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/zmq/eventloop/__pycache__/future.cpython-38.pyc b/.venv/lib/python3.8/site-packages/zmq/eventloop/__pycache__/future.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e530200da2d1047acb911743a1edca4ce0bff907 GIT binary patch literal 3034 zcmai0TW=Fb6yBS6*Vi}!T2$J~qO`@7I8`MoN)bvF0z#@>L_n2Rs)o(ZggC5s&Fq>a zmXRt2iN3VIA(8sRAL_%t_NmW(>r=loV?&&aI@XNm%*@WYednBcQm=&GoLZh)@wI_SD+2xs33=CIP>b6ANS!*+utvr=U$kSGo%5<3b z5|MQ(l}@LX2@%Fwdh1rD(n7n{Px-BreT+G*`Ol7xi z7d~T2*cXfy6~-XfFs6Bpu@}QI);n(vNnTXLzc-ii{$Od)8!Qf!K?te%;?9;3@#5}{ z-QB$#-`!Y(UQ6PoNb(rsEo~}ebq0IV#U1BJFbjikD*A- zxWh~MFL4(dc}0Ug);8C68GW-p+=${Z%UYB5mfpDDlA@Pnc?hpOYem`&Akw50k;SHs z<~I5&diF7fv2kD=8nQ+f#N5oSedEvs2nh^!_ugaJ(BWw!f_f%$CUzq+plg+SZ_UEV zM7;UlezJ-?3s(zpk(l@x4AVCqvu2Ji%&ODT=gyY!1AMC`OwZ>gX4avR+xw91t=Vlm zvX1?t(#w?UaD7pp6;L*C;J9?-;s%U^xx9v*AwjoIqS;kO!jPW#L zOg3rhJPq#DJ>OVG?WrBKGjBb#>HkhjB`dP{}Sh?cDgjf zw=;9D+pZonmC`rxm`15)>^xdqxf_%i{S~F39zA%x7Pw6POM=X)wj?`#Mq-dYWJ?!6 zNvmgDlkh#Y=EQn7x4EO@tOP5%g{$*WL>8Ggnv=(D^z0)HWAnfmTW^d_Q{Cc^?L!+8 zqWmzrydG@{N-K!EINm_YP^mI($#AEYsk}BLAw?kd59xMd^Q*Bxb&b*-xz7pZvkbvy zP9jSMm47=9`x`vG)4@mopc|uWTKW##3G--+fg{r#JGbK$;$(L)(I0hjZ8hYaZG{O( z=53ec9IhxF@^9hl&jMS#%q2yI_Q5AKQ_Sa2u(*yrjR|XX@hmwag5k6|m{7luo{^)+ z)?MT0#w%Od*QTuV!qJ(0bmd8s{jXi2Q_zs2pS~3D)N+(s@-nUuJgrqG2{=bkr8GLv zhRJcWWnYtMB%@*Z=IGK?ty4~RVZhm}Ag>UY&uKU<8C=4~SLo_`-}D_xD>Kjlt)Q`t z|BO=06uguQCMC{YSCBe|JzW>n*+3Omri#R=f_#B<-x3G%4eAupC&aL^NKIK}Dh4-E zr%cL9x?1gu9b-{M6{{XH&j&uM3 literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/zmq/eventloop/__pycache__/ioloop.cpython-38.pyc b/.venv/lib/python3.8/site-packages/zmq/eventloop/__pycache__/ioloop.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b3da39e948e387d55f5e8dd39f15fffeed246507 GIT binary patch literal 4049 zcmbVP&2QYs6`vuwB$rx!%aWa>Es-{Lwv|_PS~sat)?2)Si57k3rG)y&<`~wu2tZ1!sqxnK$qK-tWCP z{CIxeBXG4o|1!L~M9AOqVfJ$2;eEK}Ta*w+0>UUWQkofok(q&+S%F3Iotd_Rmj1T` zd%UfCPT;`5mAY9wXzN+6)XBWSqlC|K@36z{GeaKodFJp1?l70N&&+jlMt@B|A^E07 z`23M4{zwV_n8#Y_VznCjR=QM4{UynbPYFm{4wipL*c|ITA*{of&&*(j&9j9kBv@sO zd^KESOEBxwkuAQ2^~>pMwjOLylD~$U1RH$g{PG3i8%J&N&#E76Jp3z2Tw$vqag}d? z#C5(Nbl4iZ1X8aw^8P?Y4cAgo5B<2vhLKA4lQdB$p0|6DNIxssDCIu%7#|8AM~X8)$^GF8uDJeo&)Y5h zk>px{mQ?Ss>G4NAS1In2B3%x_dnl;mmOmj}ft zW&S=#@vP@PLnd_1axvPMMLJSEOtN7iROzzhQ6fQhxqu3UQh|~g?7h>ar8D4pm=*)* z+DU=hlxuO3_mja$MEfZZ8Sh7Og^@Na)XED|{27q490=4o`o z*{vu|_oMh|{MCc_fFtzMR|ni5Bmkx#*P{Rx;)0LhjUtbE&+~k^c46vd5+FS@W7CiN z3LtNWLzQIQ&yqAvBnL#8tYz#0enRc}*+{CHU8>cn%L}TaM`OW}7(K1TL=)Vh7%4p= zO5;(g$mCfq#7#CEIKY*ax~;Z%z@ga8-_`qs4(nWrG*SH z-NqN?eACn0mQGRtXN%!eTDHS5P9rJ9@G1G~oh_9Ow}#2^+9)3aOE|j*K=Sn3@r~o- zlN&#|u?0c7HHo{eitxSRiC6{=-b4g-f;DVv{KqmpI==h@G`&X27>V9o*hfFyf?NI= z8b(h^She7ZbK`=Xl0%ajuaXVug%&)uz!T&Udk%U^=O1gl`~b;SaT@6%db$5(C(Q3y<_tV#is2;GI8R^AzY~TJM^RdjIAO?&I1Dwp#5X~_-mRRkDI4=Nh0&=(>o^5Hp#$Pu(9wQy zspT#>uA|?+lv~k2jrw<>qsSo@HR_6lz&&K0vNX0$#J6^K$0-CtZxRT-DiHoh6|3tR zqN#Rd~%ic2+R0C&uz?=9eg^{$|D(9fIG!?V7t4u69 zFjLH9gZ`MoMx&&$>B7K!a5o;K=rP+ci1BZMV;_#^dl_bus$TVA<92ZO7ga%j2|iQ} zFZm8Mv!zKFCLrY#H?Vk%L2-Hlhn>KNzReuncXWYrA&I);`>=fco9)~8?%%%k!S3zt zoBqzEiszg&s6&zTi+%;jALcn>f9=j?h25su2<6b@fX18`P>H`VS2JA|^vb}6Kr#7y=Sh|fGPp#67 zQz6!Cj?(uLD5^DR9P(jlAc$^?$l?ghi%tBU1Z$1pfB< zpJaUkpPoKyg9V;(1g@{_bn2zzI=<4BobvLA@GgbBGRm%vTAp&VUfgYq*Kzr`u|YP9 zH?Tokmvj1jk!e2*L`k4j@m*}D+f8#fW`g^0OUz}EyIY->LA?co>X?e*<#U$_Pq*Nf zD4~hWL*v|37KQ?&Kzn0+f0|jU#L;|T%zP|hnt`CmPkcG#aRPBMn@{>sM4ObMNx1`n zV!qTgnn4xypD}C#CY-u3y3+I%wMEC1mQBSC_=g;!S7BdE>b{}@#NyZ=L9jxh6b25W zwF1|QSFu5e0;g6hm}~Td?-5seM}O7mQvrUxz{iXd!Q4#74;E)0 zdLS!Uy2nLQuq3`!e<0{mT3P=+)I&QTO$eN@iYMXVdu`Cv$x|%cpH@ZxU9?L62pVf{ q&2Xt}7}SN+1O6^U0Cnh!VVg_7>)4h@7vMzIp`N*P)iPZOvHt>A68^sc literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/zmq/eventloop/__pycache__/zmqstream.cpython-38.pyc b/.venv/lib/python3.8/site-packages/zmq/eventloop/__pycache__/zmqstream.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..30238f0b1b04d6a087409fbc740bc493aa1f0823 GIT binary patch literal 16905 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 V5cGq+G2_nUOnJ`X`y!v`{uf%s>=^(6 literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/zmq/eventloop/_deprecated.py b/.venv/lib/python3.8/site-packages/zmq/eventloop/_deprecated.py new file mode 100644 index 00000000..dfde79bd --- /dev/null +++ b/.venv/lib/python3.8/site-packages/zmq/eventloop/_deprecated.py @@ -0,0 +1,214 @@ +# coding: utf-8 +"""tornado IOLoop API with zmq compatibility + +If you have tornado ≥ 3.0, this is a subclass of tornado's IOLoop, +otherwise we ship a minimal subset of tornado in zmq.eventloop.minitornado. + +The minimal shipped version of tornado's IOLoop does not include +support for concurrent futures - this will only be available if you +have tornado ≥ 3.0. +""" + +# Copyright (C) PyZMQ Developers +# Distributed under the terms of the Modified BSD License. + +from __future__ import absolute_import, division, with_statement + +import os +import time +import warnings + +from zmq import ( + Poller, + POLLIN, POLLOUT, POLLERR, + ZMQError, ETERM, +) + +try: + import tornado + tornado_version = tornado.version_info +except (ImportError, AttributeError): + tornado_version = () + +from .minitornado.ioloop import PollIOLoop, PeriodicCallback +from .minitornado.log import gen_log + + +class DelayedCallback(PeriodicCallback): + """Schedules the given callback to be called once. + + The callback is called once, after callback_time milliseconds. + + `start` must be called after the DelayedCallback is created. + + The timeout is calculated from when `start` is called. + """ + def __init__(self, callback, callback_time, io_loop=None): + # PeriodicCallback require callback_time to be positive + warnings.warn("""DelayedCallback is deprecated. + Use loop.add_timeout instead.""", DeprecationWarning) + callback_time = max(callback_time, 1e-3) + super(DelayedCallback, self).__init__(callback, callback_time, io_loop) + + def start(self): + """Starts the timer.""" + self._running = True + self._firstrun = True + self._next_timeout = time.time() + self.callback_time / 1000.0 + self.io_loop.add_timeout(self._next_timeout, self._run) + + def _run(self): + if not self._running: return + self._running = False + try: + self.callback() + except Exception: + gen_log.error("Error in delayed callback", exc_info=True) + + +class ZMQPoller(object): + """A poller that can be used in the tornado IOLoop. + + This simply wraps a regular zmq.Poller, scaling the timeout + by 1000, so that it is in seconds rather than milliseconds. + """ + + def __init__(self): + self._poller = Poller() + + @staticmethod + def _map_events(events): + """translate IOLoop.READ/WRITE/ERROR event masks into zmq.POLLIN/OUT/ERR""" + z_events = 0 + if events & IOLoop.READ: + z_events |= POLLIN + if events & IOLoop.WRITE: + z_events |= POLLOUT + if events & IOLoop.ERROR: + z_events |= POLLERR + return z_events + + @staticmethod + def _remap_events(z_events): + """translate zmq.POLLIN/OUT/ERR event masks into IOLoop.READ/WRITE/ERROR""" + events = 0 + if z_events & POLLIN: + events |= IOLoop.READ + if z_events & POLLOUT: + events |= IOLoop.WRITE + if z_events & POLLERR: + events |= IOLoop.ERROR + return events + + def register(self, fd, events): + return self._poller.register(fd, self._map_events(events)) + + def modify(self, fd, events): + return self._poller.modify(fd, self._map_events(events)) + + def unregister(self, fd): + return self._poller.unregister(fd) + + def poll(self, timeout): + """poll in seconds rather than milliseconds. + + Event masks will be IOLoop.READ/WRITE/ERROR + """ + z_events = self._poller.poll(1000*timeout) + return [ (fd,self._remap_events(evt)) for (fd,evt) in z_events ] + + def close(self): + pass + + +class ZMQIOLoop(PollIOLoop): + """ZMQ subclass of tornado's IOLoop + + Minor modifications, so that .current/.instance return self + """ + + _zmq_impl = ZMQPoller + + def initialize(self, impl=None, **kwargs): + impl = self._zmq_impl() if impl is None else impl + super(ZMQIOLoop, self).initialize(impl=impl, **kwargs) + + @classmethod + def instance(cls, *args, **kwargs): + """Returns a global `IOLoop` instance. + + Most applications have a single, global `IOLoop` running on the + main thread. Use this method to get this instance from + another thread. To get the current thread's `IOLoop`, use `current()`. + """ + # install ZMQIOLoop as the active IOLoop implementation + # when using tornado 3 + if tornado_version >= (3,): + PollIOLoop.configure(cls) + loop = PollIOLoop.instance(*args, **kwargs) + if not isinstance(loop, cls): + warnings.warn("IOLoop.current expected instance of %r, got %r" % (cls, loop), + RuntimeWarning, stacklevel=2, + ) + return loop + + @classmethod + def current(cls, *args, **kwargs): + """Returns the current thread’s IOLoop. + """ + # install ZMQIOLoop as the active IOLoop implementation + # when using tornado 3 + if tornado_version >= (3,): + PollIOLoop.configure(cls) + loop = PollIOLoop.current(*args, **kwargs) + if not isinstance(loop, cls): + warnings.warn("IOLoop.current expected instance of %r, got %r" % (cls, loop), + RuntimeWarning, stacklevel=2, + ) + return loop + + def start(self): + try: + super(ZMQIOLoop, self).start() + except ZMQError as e: + if e.errno == ETERM: + # quietly return on ETERM + pass + else: + raise + + +if (3, 0) <= tornado_version < (3, 1): + def backport_close(self, all_fds=False): + """backport IOLoop.close to 3.0 from 3.1 (supports fd.close() method)""" + from zmq.eventloop.minitornado.ioloop import PollIOLoop as mini_loop + return mini_loop.close.__get__(self)(all_fds) + ZMQIOLoop.close = backport_close + + +# public API name +IOLoop = ZMQIOLoop + + +def install(): + """set the tornado IOLoop instance with the pyzmq IOLoop. + + After calling this function, tornado's IOLoop.instance() and pyzmq's + IOLoop.instance() will return the same object. + + An assertion error will be raised if tornado's IOLoop has been initialized + prior to calling this function. + """ + from tornado import ioloop + # check if tornado's IOLoop is already initialized to something other + # than the pyzmq IOLoop instance: + assert (not ioloop.IOLoop.initialized()) or \ + ioloop.IOLoop.instance() is IOLoop.instance(), "tornado IOLoop already initialized" + + if tornado_version >= (3,): + # tornado 3 has an official API for registering new defaults, yay! + ioloop.IOLoop.configure(ZMQIOLoop) + else: + # we have to set the global instance explicitly + ioloop.IOLoop._instance = IOLoop.instance() + diff --git a/.venv/lib/python3.8/site-packages/zmq/eventloop/future.py b/.venv/lib/python3.8/site-packages/zmq/eventloop/future.py new file mode 100644 index 00000000..14bc8be3 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/zmq/eventloop/future.py @@ -0,0 +1,73 @@ +"""Future-returning APIs for tornado coroutines. + +.. seealso:: + + :mod:`zmq.asyncio` + +""" + +# Copyright (c) PyZMQ Developers. +# Distributed under the terms of the Modified BSD License. + +import zmq as _zmq + +from zmq._future import _AsyncPoller, _AsyncSocket + +from tornado.concurrent import Future +from tornado.ioloop import IOLoop + +class CancelledError(Exception): + pass + +class _TornadoFuture(Future): + """Subclass Tornado Future, reinstating cancellation.""" + def cancel(self): + if self.done(): + return False + self.set_exception(CancelledError()) + return True + + def cancelled(self): + return self.done() and isinstance(self.exception(), CancelledError) + +# mixin for tornado/asyncio compatibility + +class _AsyncTornado(object): + _Future = _TornadoFuture + _READ = IOLoop.READ + _WRITE = IOLoop.WRITE + def _default_loop(self): + return IOLoop.current() + + +class Poller(_AsyncTornado, _AsyncPoller): + def _watch_raw_socket(self, loop, socket, evt, f): + """Schedule callback for a raw socket""" + loop.add_handler(socket, lambda *args: f(), evt) + + def _unwatch_raw_sockets(self, loop, *sockets): + """Unschedule callback for a raw socket""" + for socket in sockets: + loop.remove_handler(socket) + + +class Socket(_AsyncTornado, _AsyncSocket): + _poller_class = Poller + +Poller._socket_class = Socket + +class Context(_zmq.Context): + + # avoid sharing instance with base Context class + _instance = None + + io_loop = None + @staticmethod + def _socket_class(self, socket_type): + return Socket(self, socket_type, io_loop=self.io_loop) + + def __init__(self, *args, **kwargs): + io_loop = kwargs.pop('io_loop', None) + super(Context, self).__init__(*args, **kwargs) + self.io_loop = io_loop or IOLoop.current() + diff --git a/.venv/lib/python3.8/site-packages/zmq/eventloop/ioloop.py b/.venv/lib/python3.8/site-packages/zmq/eventloop/ioloop.py new file mode 100644 index 00000000..329403ff --- /dev/null +++ b/.venv/lib/python3.8/site-packages/zmq/eventloop/ioloop.py @@ -0,0 +1,136 @@ +# coding: utf-8 +"""tornado IOLoop API with zmq compatibility + +This module is deprecated in pyzmq 17. +To use zmq with tornado, +eventloop integration is no longer required +and tornado itself should be used. +""" + +# Copyright (C) PyZMQ Developers +# Distributed under the terms of the Modified BSD License. + +from __future__ import absolute_import, division, with_statement + +import time +import warnings + +try: + import tornado + from tornado.log import gen_log + from tornado import ioloop + if not hasattr(ioloop.IOLoop, 'configurable_default'): + raise ImportError("Tornado too old: %s" % getattr(tornado, 'version', 'unknown')) +except ImportError: + from .minitornado import ioloop + from .minitornado.log import gen_log + +PeriodicCallback = ioloop.PeriodicCallback + + +class DelayedCallback(PeriodicCallback): + """Schedules the given callback to be called once. + + The callback is called once, after callback_time milliseconds. + + `start` must be called after the DelayedCallback is created. + + The timeout is calculated from when `start` is called. + """ + def __init__(self, callback, callback_time, io_loop=None): + # PeriodicCallback require callback_time to be positive + warnings.warn("""DelayedCallback is deprecated. + Use loop.add_timeout instead.""", DeprecationWarning) + callback_time = max(callback_time, 1e-3) + super(DelayedCallback, self).__init__(callback, callback_time, io_loop) + + def start(self): + """Starts the timer.""" + self._running = True + self._firstrun = True + self._next_timeout = time.time() + self.callback_time / 1000.0 + self.io_loop.add_timeout(self._next_timeout, self._run) + + def _run(self): + if not self._running: return + self._running = False + try: + self.callback() + except Exception: + gen_log.error("Error in delayed callback", exc_info=True) + + +def _deprecated(): + if _deprecated.called: + return + _deprecated.called = True + warnings.warn("zmq.eventloop.ioloop is deprecated in pyzmq 17." + " pyzmq now works with default tornado and asyncio eventloops.", + DeprecationWarning, stacklevel=3) +_deprecated.called = False + + +# resolve 'true' default loop +if '.minitornado.' in ioloop.__name__: + from ._deprecated import ZMQIOLoop as _IOLoop +else: + _IOLoop = ioloop.IOLoop + while _IOLoop.configurable_default() is not _IOLoop: + _IOLoop = _IOLoop.configurable_default() + + +class ZMQIOLoop(_IOLoop): + """DEPRECATED: No longer needed as of pyzmq-17 + + PyZMQ tornado integration now works with the default :mod:`tornado.ioloop.IOLoop`. + """ + + def __init__(self, *args, **kwargs): + _deprecated() + # super is object, which takes no args + return super(ZMQIOLoop, self).__init__() + + @classmethod + def instance(cls, *args, **kwargs): + """Returns a global `IOLoop` instance. + + Most applications have a single, global `IOLoop` running on the + main thread. Use this method to get this instance from + another thread. To get the current thread's `IOLoop`, use `current()`. + """ + # install ZMQIOLoop as the active IOLoop implementation + # when using tornado 3 + ioloop.IOLoop.configure(cls) + _deprecated() + loop = ioloop.IOLoop.instance(*args, **kwargs) + return loop + + @classmethod + def current(cls, *args, **kwargs): + """Returns the current thread’s IOLoop. + """ + # install ZMQIOLoop as the active IOLoop implementation + # when using tornado 3 + ioloop.IOLoop.configure(cls) + _deprecated() + loop = ioloop.IOLoop.current(*args, **kwargs) + return loop + + +# public API name +IOLoop = ZMQIOLoop + + +def install(): + """DEPRECATED + + pyzmq 17 no longer needs any special integration for tornado. + """ + _deprecated() + ioloop.IOLoop.configure(ZMQIOLoop) + + +# if minitornado is used, fallback on deprecated ZMQIOLoop, install implementations +if '.minitornado.' in ioloop.__name__: + from ._deprecated import ZMQIOLoop, install, IOLoop + diff --git a/.venv/lib/python3.8/site-packages/zmq/eventloop/minitornado/__init__.py b/.venv/lib/python3.8/site-packages/zmq/eventloop/minitornado/__init__.py new file mode 100644 index 00000000..c94bd80c --- /dev/null +++ b/.venv/lib/python3.8/site-packages/zmq/eventloop/minitornado/__init__.py @@ -0,0 +1,11 @@ +import warnings +class VisibleDeprecationWarning(UserWarning): + """A DeprecationWarning that users should see.""" + pass + +warnings.warn("""zmq.eventloop.minitornado is deprecated in pyzmq 14.0 and will be removed. + Install tornado itself to use zmq with the tornado IOLoop. + """, + VisibleDeprecationWarning, + stacklevel=4, +) diff --git a/.venv/lib/python3.8/site-packages/zmq/eventloop/minitornado/__pycache__/__init__.cpython-38.pyc b/.venv/lib/python3.8/site-packages/zmq/eventloop/minitornado/__pycache__/__init__.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..4e7d70fb7c9a47a7227c4e5eeb8630a7e29636fa GIT binary patch literal 621 zcmZWnO^XyU5KX#!cAC+Jy?V=a(CJoi4uXinqAbXIkWuJM=e)da(rR*nC z))qP);=58_b*0|#jHLuyN%@1dVJzuXk^C$Cs zTVLgPjmB$ho4i&=dE1&2Y%XO;q|BO48_~qDTtY783Ex$=-wB=FqO$|EP)@-9;s`<+ z(QK$$JbIix6r};NQd)}(6fM^F8X=nqvNPj+N%cJip}a%=fzlw02>6xqOA-oiTh89R zCgKD9Ca|0GenL~KOHIUd5N|c8?)p0m5_kUwy9@M5*!!o~5T!JwPoEAtKMT+7!rw~y LNpciNJo@t&;=rtT literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/zmq/eventloop/minitornado/__pycache__/concurrent.cpython-38.pyc b/.venv/lib/python3.8/site-packages/zmq/eventloop/minitornado/__pycache__/concurrent.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..af6bf31d028274d3b70f00f69eb85874be3cf0ae GIT binary patch literal 894 zcmaJ<%We}f6!knZ4N;>a(Jhj95UI%^p)QbURSEIh1R-EE8_TtwjN6&<)b^xF!~!+_ z8NP)*3vc-gR$R}tC}F{s?D4g)kIy-Gz6^&01kwBUll%w}`sI`Dh#@(HVV=UoQHI_k z9`NuM@lXVtC<{dxqb$l|9`X1VWj)^eght8wre3YfE6kNJxKb9IT-MksT~V%{7(8oi zqlGyd*jyTX(HM(0l?IAsHB-8zRxSjdD*L{y3sH*73jSJar44{!x=@nioGxTF_c_aH zH5af_xNKOCnc`wHV8D1MLdecwm_wKZ$^y_6c51SSN5DIFhr4gSX?Zem=5Iu>@<<H6dUrFW3#2$UL2i{joDe0qYPPo80re`gOiO~3 z6>kc^-Y4X$p+$G1`+(Kb-J16No_D+lqkXO)wE0dOe1UJpD_`XQVT-;Z8*D;oLNFbL zZXiwTaK(g6I(pz^u>9vG_dpslYuh~ZP@Oz|0PE=}aeIVt#ejFB&MySBEfMW2vxCo? hGI0*pcIfS$Ep+de_F`QBWhejClQw=ojvprd@DJkK>-+!! literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/zmq/eventloop/minitornado/__pycache__/ioloop.cpython-38.pyc b/.venv/lib/python3.8/site-packages/zmq/eventloop/minitornado/__pycache__/ioloop.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d5399b2dcf6eb3a9a5e7ec4d5abf1acf11085927 GIT binary patch literal 33605 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 IX5O6s0?P$vrvLx| literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/zmq/eventloop/minitornado/__pycache__/stack_context.cpython-38.pyc b/.venv/lib/python3.8/site-packages/zmq/eventloop/minitornado/__pycache__/stack_context.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c899c500e122f16d9dcd08225cba24ca8149f19d GIT binary patch literal 10705 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 ic$W~yfCw}I literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/zmq/eventloop/minitornado/__pycache__/util.cpython-38.pyc b/.venv/lib/python3.8/site-packages/zmq/eventloop/minitornado/__pycache__/util.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..1f698b8d5d81ef28a60ff0b607c0891453668325 GIT binary patch literal 7265 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 literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/zmq/eventloop/minitornado/concurrent.py b/.venv/lib/python3.8/site-packages/zmq/eventloop/minitornado/concurrent.py new file mode 100644 index 00000000..48df12bc --- /dev/null +++ b/.venv/lib/python3.8/site-packages/zmq/eventloop/minitornado/concurrent.py @@ -0,0 +1,14 @@ +"""pyzmq does not ship tornado's futures, +this just raises informative NotImplementedErrors to avoid having to change too much code. +""" + +class NotImplementedFuture(object): + def __init__(self, *args, **kwargs): + raise NotImplementedError("pyzmq does not ship tornado's Futures, " + "install tornado >= 3.0 for future support." + ) + +Future = TracebackFuture = NotImplementedFuture + +def is_future(x): + return isinstance(x, Future) diff --git a/.venv/lib/python3.8/site-packages/zmq/eventloop/minitornado/ioloop.py b/.venv/lib/python3.8/site-packages/zmq/eventloop/minitornado/ioloop.py new file mode 100644 index 00000000..b6dcbd35 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/zmq/eventloop/minitornado/ioloop.py @@ -0,0 +1,1056 @@ +#!/usr/bin/env python +# +# Copyright 2009 Facebook +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +"""An I/O event loop for non-blocking sockets. + +Typical applications will use a single `IOLoop` object, in the +`IOLoop.instance` singleton. The `IOLoop.start` method should usually +be called at the end of the ``main()`` function. Atypical applications may +use more than one `IOLoop`, such as one `IOLoop` per thread, or per `unittest` +case. + +In addition to I/O events, the `IOLoop` can also schedule time-based events. +`IOLoop.add_timeout` is a non-blocking alternative to `time.sleep`. +""" + +from __future__ import absolute_import, division, print_function, with_statement + +import datetime +import errno +import functools +import heapq +import itertools +import logging +import numbers +import os +import select +import sys +import threading +import time +import traceback +import math + +from .concurrent import TracebackFuture, is_future +from .log import app_log, gen_log +from . import stack_context +from .util import Configurable, errno_from_exception, timedelta_to_seconds + +try: + import signal +except ImportError: + signal = None + +try: + import thread # py2 +except ImportError: + import _thread as thread # py3 + +from .platform.auto import set_close_exec, Waker + + +_POLL_TIMEOUT = 3600.0 + + +class TimeoutError(Exception): + pass + + +class IOLoop(Configurable): + """A level-triggered I/O loop. + + We use ``epoll`` (Linux) or ``kqueue`` (BSD and Mac OS X) if they + are available, or else we fall back on select(). If you are + implementing a system that needs to handle thousands of + simultaneous connections, you should use a system that supports + either ``epoll`` or ``kqueue``. + + Example usage for a simple TCP server: + + .. testcode:: + + import errno + import functools + import tornado.ioloop + import socket + + def connection_ready(sock, fd, events): + while True: + try: + connection, address = sock.accept() + except socket.error as e: + if e.args[0] not in (errno.EWOULDBLOCK, errno.EAGAIN): + raise + return + connection.setblocking(0) + handle_connection(connection, address) + + if __name__ == '__main__': + sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0) + sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) + sock.setblocking(0) + sock.bind(("", port)) + sock.listen(128) + + io_loop = tornado.ioloop.IOLoop.current() + callback = functools.partial(connection_ready, sock) + io_loop.add_handler(sock.fileno(), callback, io_loop.READ) + io_loop.start() + + .. testoutput:: + :hide: + + By default, a newly-constructed `IOLoop` becomes the thread's current + `IOLoop`, unless there already is a current `IOLoop`. This behavior + can be controlled with the ``make_current`` argument to the `IOLoop` + constructor: if ``make_current=True``, the new `IOLoop` will always + try to become current and it raises an error if there is already a + current instance. If ``make_current=False``, the new `IOLoop` will + not try to become current. + + .. versionchanged:: 4.2 + Added the ``make_current`` keyword argument to the `IOLoop` + constructor. + """ + # Constants from the epoll module + _EPOLLIN = 0x001 + _EPOLLPRI = 0x002 + _EPOLLOUT = 0x004 + _EPOLLERR = 0x008 + _EPOLLHUP = 0x010 + _EPOLLRDHUP = 0x2000 + _EPOLLONESHOT = (1 << 30) + _EPOLLET = (1 << 31) + + # Our events map exactly to the epoll events + NONE = 0 + READ = _EPOLLIN + WRITE = _EPOLLOUT + ERROR = _EPOLLERR | _EPOLLHUP + + # Global lock for creating global IOLoop instance + _instance_lock = threading.Lock() + + _current = threading.local() + + @staticmethod + def instance(): + """Returns a global `IOLoop` instance. + + Most applications have a single, global `IOLoop` running on the + main thread. Use this method to get this instance from + another thread. In most other cases, it is better to use `current()` + to get the current thread's `IOLoop`. + """ + if not hasattr(IOLoop, "_instance"): + with IOLoop._instance_lock: + if not hasattr(IOLoop, "_instance"): + # New instance after double check + IOLoop._instance = IOLoop() + return IOLoop._instance + + @staticmethod + def initialized(): + """Returns true if the singleton instance has been created.""" + return hasattr(IOLoop, "_instance") + + def install(self): + """Installs this `IOLoop` object as the singleton instance. + + This is normally not necessary as `instance()` will create + an `IOLoop` on demand, but you may want to call `install` to use + a custom subclass of `IOLoop`. + """ + assert not IOLoop.initialized() + IOLoop._instance = self + + @staticmethod + def clear_instance(): + """Clear the global `IOLoop` instance. + + .. versionadded:: 4.0 + """ + if hasattr(IOLoop, "_instance"): + del IOLoop._instance + + @staticmethod + def current(instance=True): + """Returns the current thread's `IOLoop`. + + If an `IOLoop` is currently running or has been marked as + current by `make_current`, returns that instance. If there is + no current `IOLoop`, returns `IOLoop.instance()` (i.e. the + main thread's `IOLoop`, creating one if necessary) if ``instance`` + is true. + + In general you should use `IOLoop.current` as the default when + constructing an asynchronous object, and use `IOLoop.instance` + when you mean to communicate to the main thread from a different + one. + + .. versionchanged:: 4.1 + Added ``instance`` argument to control the fallback to + `IOLoop.instance()`. + """ + current = getattr(IOLoop._current, "instance", None) + if current is None and instance: + return IOLoop.instance() + return current + + def make_current(self): + """Makes this the `IOLoop` for the current thread. + + An `IOLoop` automatically becomes current for its thread + when it is started, but it is sometimes useful to call + `make_current` explicitly before starting the `IOLoop`, + so that code run at startup time can find the right + instance. + + .. versionchanged:: 4.1 + An `IOLoop` created while there is no current `IOLoop` + will automatically become current. + """ + IOLoop._current.instance = self + + @staticmethod + def clear_current(): + IOLoop._current.instance = None + + @classmethod + def configurable_base(cls): + return IOLoop + + @classmethod + def configurable_default(cls): + # this is the only patch to IOLoop: + from zmq.eventloop.ioloop import ZMQIOLoop + return ZMQIOLoop + if hasattr(select, "epoll"): + from tornado.platform.epoll import EPollIOLoop + return EPollIOLoop + if hasattr(select, "kqueue"): + # Python 2.6+ on BSD or Mac + from tornado.platform.kqueue import KQueueIOLoop + return KQueueIOLoop + from tornado.platform.select import SelectIOLoop + return SelectIOLoop + + def initialize(self, make_current=None): + if make_current is None: + if IOLoop.current(instance=False) is None: + self.make_current() + elif make_current: + if IOLoop.current(instance=False) is not None: + raise RuntimeError("current IOLoop already exists") + self.make_current() + + def close(self, all_fds=False): + """Closes the `IOLoop`, freeing any resources used. + + If ``all_fds`` is true, all file descriptors registered on the + IOLoop will be closed (not just the ones created by the + `IOLoop` itself). + + Many applications will only use a single `IOLoop` that runs for the + entire lifetime of the process. In that case closing the `IOLoop` + is not necessary since everything will be cleaned up when the + process exits. `IOLoop.close` is provided mainly for scenarios + such as unit tests, which create and destroy a large number of + ``IOLoops``. + + An `IOLoop` must be completely stopped before it can be closed. This + means that `IOLoop.stop()` must be called *and* `IOLoop.start()` must + be allowed to return before attempting to call `IOLoop.close()`. + Therefore the call to `close` will usually appear just after + the call to `start` rather than near the call to `stop`. + + .. versionchanged:: 3.1 + If the `IOLoop` implementation supports non-integer objects + for "file descriptors", those objects will have their + ``close`` method when ``all_fds`` is true. + """ + raise NotImplementedError() + + def add_handler(self, fd, handler, events): + """Registers the given handler to receive the given events for ``fd``. + + The ``fd`` argument may either be an integer file descriptor or + a file-like object with a ``fileno()`` method (and optionally a + ``close()`` method, which may be called when the `IOLoop` is shut + down). + + The ``events`` argument is a bitwise or of the constants + ``IOLoop.READ``, ``IOLoop.WRITE``, and ``IOLoop.ERROR``. + + When an event occurs, ``handler(fd, events)`` will be run. + + .. versionchanged:: 4.0 + Added the ability to pass file-like objects in addition to + raw file descriptors. + """ + raise NotImplementedError() + + def update_handler(self, fd, events): + """Changes the events we listen for ``fd``. + + .. versionchanged:: 4.0 + Added the ability to pass file-like objects in addition to + raw file descriptors. + """ + raise NotImplementedError() + + def remove_handler(self, fd): + """Stop listening for events on ``fd``. + + .. versionchanged:: 4.0 + Added the ability to pass file-like objects in addition to + raw file descriptors. + """ + raise NotImplementedError() + + def set_blocking_signal_threshold(self, seconds, action): + """Sends a signal if the `IOLoop` is blocked for more than + ``s`` seconds. + + Pass ``seconds=None`` to disable. Requires Python 2.6 on a unixy + platform. + + The action parameter is a Python signal handler. Read the + documentation for the `signal` module for more information. + If ``action`` is None, the process will be killed if it is + blocked for too long. + """ + raise NotImplementedError() + + def set_blocking_log_threshold(self, seconds): + """Logs a stack trace if the `IOLoop` is blocked for more than + ``s`` seconds. + + Equivalent to ``set_blocking_signal_threshold(seconds, + self.log_stack)`` + """ + self.set_blocking_signal_threshold(seconds, self.log_stack) + + def log_stack(self, signal, frame): + """Signal handler to log the stack trace of the current thread. + + For use with `set_blocking_signal_threshold`. + """ + gen_log.warning('IOLoop blocked for %f seconds in\n%s', + self._blocking_signal_threshold, + ''.join(traceback.format_stack(frame))) + + def start(self): + """Starts the I/O loop. + + The loop will run until one of the callbacks calls `stop()`, which + will make the loop stop after the current event iteration completes. + """ + raise NotImplementedError() + + def _setup_logging(self): + """The IOLoop catches and logs exceptions, so it's + important that log output be visible. However, python's + default behavior for non-root loggers (prior to python + 3.2) is to print an unhelpful "no handlers could be + found" message rather than the actual log entry, so we + must explicitly configure logging if we've made it this + far without anything. + + This method should be called from start() in subclasses. + """ + if not any([logging.getLogger().handlers, + logging.getLogger('tornado').handlers, + logging.getLogger('tornado.application').handlers]): + logging.basicConfig() + + def stop(self): + """Stop the I/O loop. + + If the event loop is not currently running, the next call to `start()` + will return immediately. + + To use asynchronous methods from otherwise-synchronous code (such as + unit tests), you can start and stop the event loop like this:: + + ioloop = IOLoop() + async_method(ioloop=ioloop, callback=ioloop.stop) + ioloop.start() + + ``ioloop.start()`` will return after ``async_method`` has run + its callback, whether that callback was invoked before or + after ``ioloop.start``. + + Note that even after `stop` has been called, the `IOLoop` is not + completely stopped until `IOLoop.start` has also returned. + Some work that was scheduled before the call to `stop` may still + be run before the `IOLoop` shuts down. + """ + raise NotImplementedError() + + def run_sync(self, func, timeout=None): + """Starts the `IOLoop`, runs the given function, and stops the loop. + + The function must return either a yieldable object or + ``None``. If the function returns a yieldable object, the + `IOLoop` will run until the yieldable is resolved (and + `run_sync()` will return the yieldable's result). If it raises + an exception, the `IOLoop` will stop and the exception will be + re-raised to the caller. + + The keyword-only argument ``timeout`` may be used to set + a maximum duration for the function. If the timeout expires, + a `TimeoutError` is raised. + + This method is useful in conjunction with `tornado.gen.coroutine` + to allow asynchronous calls in a ``main()`` function:: + + @gen.coroutine + def main(): + # do stuff... + + if __name__ == '__main__': + IOLoop.current().run_sync(main) + + .. versionchanged:: 4.3 + Returning a non-``None``, non-yieldable value is now an error. + """ + future_cell = [None] + + def run(): + try: + result = func() + if result is not None: + from tornado.gen import convert_yielded + result = convert_yielded(result) + except Exception: + future_cell[0] = TracebackFuture() + future_cell[0].set_exc_info(sys.exc_info()) + else: + if is_future(result): + future_cell[0] = result + else: + future_cell[0] = TracebackFuture() + future_cell[0].set_result(result) + self.add_future(future_cell[0], lambda future: self.stop()) + self.add_callback(run) + if timeout is not None: + timeout_handle = self.add_timeout(self.time() + timeout, self.stop) + self.start() + if timeout is not None: + self.remove_timeout(timeout_handle) + if not future_cell[0].done(): + raise TimeoutError('Operation timed out after %s seconds' % timeout) + return future_cell[0].result() + + def time(self): + """Returns the current time according to the `IOLoop`'s clock. + + The return value is a floating-point number relative to an + unspecified time in the past. + + By default, the `IOLoop`'s time function is `time.time`. However, + it may be configured to use e.g. `time.monotonic` instead. + Calls to `add_timeout` that pass a number instead of a + `datetime.timedelta` should use this function to compute the + appropriate time, so they can work no matter what time function + is chosen. + """ + return time.time() + + def add_timeout(self, deadline, callback, *args, **kwargs): + """Runs the ``callback`` at the time ``deadline`` from the I/O loop. + + Returns an opaque handle that may be passed to + `remove_timeout` to cancel. + + ``deadline`` may be a number denoting a time (on the same + scale as `IOLoop.time`, normally `time.time`), or a + `datetime.timedelta` object for a deadline relative to the + current time. Since Tornado 4.0, `call_later` is a more + convenient alternative for the relative case since it does not + require a timedelta object. + + Note that it is not safe to call `add_timeout` from other threads. + Instead, you must use `add_callback` to transfer control to the + `IOLoop`'s thread, and then call `add_timeout` from there. + + Subclasses of IOLoop must implement either `add_timeout` or + `call_at`; the default implementations of each will call + the other. `call_at` is usually easier to implement, but + subclasses that wish to maintain compatibility with Tornado + versions prior to 4.0 must use `add_timeout` instead. + + .. versionchanged:: 4.0 + Now passes through ``*args`` and ``**kwargs`` to the callback. + """ + if isinstance(deadline, numbers.Real): + return self.call_at(deadline, callback, *args, **kwargs) + elif isinstance(deadline, datetime.timedelta): + return self.call_at(self.time() + timedelta_to_seconds(deadline), + callback, *args, **kwargs) + else: + raise TypeError("Unsupported deadline %r" % deadline) + + def call_later(self, delay, callback, *args, **kwargs): + """Runs the ``callback`` after ``delay`` seconds have passed. + + Returns an opaque handle that may be passed to `remove_timeout` + to cancel. Note that unlike the `asyncio` method of the same + name, the returned object does not have a ``cancel()`` method. + + See `add_timeout` for comments on thread-safety and subclassing. + + .. versionadded:: 4.0 + """ + return self.call_at(self.time() + delay, callback, *args, **kwargs) + + def call_at(self, when, callback, *args, **kwargs): + """Runs the ``callback`` at the absolute time designated by ``when``. + + ``when`` must be a number using the same reference point as + `IOLoop.time`. + + Returns an opaque handle that may be passed to `remove_timeout` + to cancel. Note that unlike the `asyncio` method of the same + name, the returned object does not have a ``cancel()`` method. + + See `add_timeout` for comments on thread-safety and subclassing. + + .. versionadded:: 4.0 + """ + return self.add_timeout(when, callback, *args, **kwargs) + + def remove_timeout(self, timeout): + """Cancels a pending timeout. + + The argument is a handle as returned by `add_timeout`. It is + safe to call `remove_timeout` even if the callback has already + been run. + """ + raise NotImplementedError() + + def add_callback(self, callback, *args, **kwargs): + """Calls the given callback on the next I/O loop iteration. + + It is safe to call this method from any thread at any time, + except from a signal handler. Note that this is the **only** + method in `IOLoop` that makes this thread-safety guarantee; all + other interaction with the `IOLoop` must be done from that + `IOLoop`'s thread. `add_callback()` may be used to transfer + control from other threads to the `IOLoop`'s thread. + + To add a callback from a signal handler, see + `add_callback_from_signal`. + """ + raise NotImplementedError() + + def add_callback_from_signal(self, callback, *args, **kwargs): + """Calls the given callback on the next I/O loop iteration. + + Safe for use from a Python signal handler; should not be used + otherwise. + + Callbacks added with this method will be run without any + `.stack_context`, to avoid picking up the context of the function + that was interrupted by the signal. + """ + raise NotImplementedError() + + def spawn_callback(self, callback, *args, **kwargs): + """Calls the given callback on the next IOLoop iteration. + + Unlike all other callback-related methods on IOLoop, + ``spawn_callback`` does not associate the callback with its caller's + ``stack_context``, so it is suitable for fire-and-forget callbacks + that should not interfere with the caller. + + .. versionadded:: 4.0 + """ + with stack_context.NullContext(): + self.add_callback(callback, *args, **kwargs) + + def add_future(self, future, callback): + """Schedules a callback on the ``IOLoop`` when the given + `.Future` is finished. + + The callback is invoked with one argument, the + `.Future`. + """ + assert is_future(future) + callback = stack_context.wrap(callback) + future.add_done_callback( + lambda future: self.add_callback(callback, future)) + + def _run_callback(self, callback): + """Runs a callback with error handling. + + For use in subclasses. + """ + try: + ret = callback() + if ret is not None: + from tornado import gen + # Functions that return Futures typically swallow all + # exceptions and store them in the Future. If a Future + # makes it out to the IOLoop, ensure its exception (if any) + # gets logged too. + try: + ret = gen.convert_yielded(ret) + except gen.BadYieldError: + # It's not unusual for add_callback to be used with + # methods returning a non-None and non-yieldable + # result, which should just be ignored. + pass + else: + self.add_future(ret, lambda f: f.result()) + except Exception: + self.handle_callback_exception(callback) + + def handle_callback_exception(self, callback): + """This method is called whenever a callback run by the `IOLoop` + throws an exception. + + By default simply logs the exception as an error. Subclasses + may override this method to customize reporting of exceptions. + + The exception itself is not passed explicitly, but is available + in `sys.exc_info`. + """ + app_log.error("Exception in callback %r", callback, exc_info=True) + + def split_fd(self, fd): + """Returns an (fd, obj) pair from an ``fd`` parameter. + + We accept both raw file descriptors and file-like objects as + input to `add_handler` and related methods. When a file-like + object is passed, we must retain the object itself so we can + close it correctly when the `IOLoop` shuts down, but the + poller interfaces favor file descriptors (they will accept + file-like objects and call ``fileno()`` for you, but they + always return the descriptor itself). + + This method is provided for use by `IOLoop` subclasses and should + not generally be used by application code. + + .. versionadded:: 4.0 + """ + try: + return fd.fileno(), fd + except AttributeError: + return fd, fd + + def close_fd(self, fd): + """Utility method to close an ``fd``. + + If ``fd`` is a file-like object, we close it directly; otherwise + we use `os.close`. + + This method is provided for use by `IOLoop` subclasses (in + implementations of ``IOLoop.close(all_fds=True)`` and should + not generally be used by application code. + + .. versionadded:: 4.0 + """ + try: + try: + fd.close() + except AttributeError: + os.close(fd) + except OSError: + pass + + +class PollIOLoop(IOLoop): + """Base class for IOLoops built around a select-like function. + + For concrete implementations, see `tornado.platform.epoll.EPollIOLoop` + (Linux), `tornado.platform.kqueue.KQueueIOLoop` (BSD and Mac), or + `tornado.platform.select.SelectIOLoop` (all platforms). + """ + def initialize(self, impl, time_func=None, **kwargs): + super(PollIOLoop, self).initialize(**kwargs) + self._impl = impl + if hasattr(self._impl, 'fileno'): + set_close_exec(self._impl.fileno()) + self.time_func = time_func or time.time + self._handlers = {} + self._events = {} + self._callbacks = [] + self._callback_lock = threading.Lock() + self._timeouts = [] + self._cancellations = 0 + self._running = False + self._stopped = False + self._closing = False + self._thread_ident = None + self._blocking_signal_threshold = None + self._timeout_counter = itertools.count() + + # Create a pipe that we send bogus data to when we want to wake + # the I/O loop when it is idle + self._waker = Waker() + self.add_handler(self._waker.fileno(), + lambda fd, events: self._waker.consume(), + self.READ) + + def close(self, all_fds=False): + with self._callback_lock: + self._closing = True + self.remove_handler(self._waker.fileno()) + if all_fds: + for fd, handler in self._handlers.values(): + self.close_fd(fd) + self._waker.close() + self._impl.close() + self._callbacks = None + self._timeouts = None + + def add_handler(self, fd, handler, events): + fd, obj = self.split_fd(fd) + self._handlers[fd] = (obj, stack_context.wrap(handler)) + self._impl.register(fd, events | self.ERROR) + + def update_handler(self, fd, events): + fd, obj = self.split_fd(fd) + self._impl.modify(fd, events | self.ERROR) + + def remove_handler(self, fd): + fd, obj = self.split_fd(fd) + self._handlers.pop(fd, None) + self._events.pop(fd, None) + try: + self._impl.unregister(fd) + except Exception: + gen_log.debug("Error deleting fd from IOLoop", exc_info=True) + + def set_blocking_signal_threshold(self, seconds, action): + if not hasattr(signal, "setitimer"): + gen_log.error("set_blocking_signal_threshold requires a signal module " + "with the setitimer method") + return + self._blocking_signal_threshold = seconds + if seconds is not None: + signal.signal(signal.SIGALRM, + action if action is not None else signal.SIG_DFL) + + def start(self): + if self._running: + raise RuntimeError("IOLoop is already running") + self._setup_logging() + if self._stopped: + self._stopped = False + return + old_current = getattr(IOLoop._current, "instance", None) + IOLoop._current.instance = self + self._thread_ident = thread.get_ident() + self._running = True + + # signal.set_wakeup_fd closes a race condition in event loops: + # a signal may arrive at the beginning of select/poll/etc + # before it goes into its interruptible sleep, so the signal + # will be consumed without waking the select. The solution is + # for the (C, synchronous) signal handler to write to a pipe, + # which will then be seen by select. + # + # In python's signal handling semantics, this only matters on the + # main thread (fortunately, set_wakeup_fd only works on the main + # thread and will raise a ValueError otherwise). + # + # If someone has already set a wakeup fd, we don't want to + # disturb it. This is an issue for twisted, which does its + # SIGCHLD processing in response to its own wakeup fd being + # written to. As long as the wakeup fd is registered on the IOLoop, + # the loop will still wake up and everything should work. + old_wakeup_fd = None + if hasattr(signal, 'set_wakeup_fd') and os.name == 'posix': + # requires python 2.6+, unix. set_wakeup_fd exists but crashes + # the python process on windows. + try: + old_wakeup_fd = signal.set_wakeup_fd(self._waker.write_fileno()) + if old_wakeup_fd != -1: + # Already set, restore previous value. This is a little racy, + # but there's no clean get_wakeup_fd and in real use the + # IOLoop is just started once at the beginning. + signal.set_wakeup_fd(old_wakeup_fd) + old_wakeup_fd = None + except ValueError: + # Non-main thread, or the previous value of wakeup_fd + # is no longer valid. + old_wakeup_fd = None + + try: + while True: + # Prevent IO event starvation by delaying new callbacks + # to the next iteration of the event loop. + with self._callback_lock: + callbacks = self._callbacks + self._callbacks = [] + + # Add any timeouts that have come due to the callback list. + # Do not run anything until we have determined which ones + # are ready, so timeouts that call add_timeout cannot + # schedule anything in this iteration. + due_timeouts = [] + if self._timeouts: + now = self.time() + while self._timeouts: + if self._timeouts[0].callback is None: + # The timeout was cancelled. Note that the + # cancellation check is repeated below for timeouts + # that are cancelled by another timeout or callback. + heapq.heappop(self._timeouts) + self._cancellations -= 1 + elif self._timeouts[0].deadline <= now: + due_timeouts.append(heapq.heappop(self._timeouts)) + else: + break + if (self._cancellations > 512 + and self._cancellations > (len(self._timeouts) >> 1)): + # Clean up the timeout queue when it gets large and it's + # more than half cancellations. + self._cancellations = 0 + self._timeouts = [x for x in self._timeouts + if x.callback is not None] + heapq.heapify(self._timeouts) + + for callback in callbacks: + self._run_callback(callback) + for timeout in due_timeouts: + if timeout.callback is not None: + self._run_callback(timeout.callback) + # Closures may be holding on to a lot of memory, so allow + # them to be freed before we go into our poll wait. + callbacks = callback = due_timeouts = timeout = None + + if self._callbacks: + # If any callbacks or timeouts called add_callback, + # we don't want to wait in poll() before we run them. + poll_timeout = 0.0 + elif self._timeouts: + # If there are any timeouts, schedule the first one. + # Use self.time() instead of 'now' to account for time + # spent running callbacks. + poll_timeout = self._timeouts[0].deadline - self.time() + poll_timeout = max(0, min(poll_timeout, _POLL_TIMEOUT)) + else: + # No timeouts and no callbacks, so use the default. + poll_timeout = _POLL_TIMEOUT + + if not self._running: + break + + if self._blocking_signal_threshold is not None: + # clear alarm so it doesn't fire while poll is waiting for + # events. + signal.setitimer(signal.ITIMER_REAL, 0, 0) + + try: + event_pairs = self._impl.poll(poll_timeout) + except Exception as e: + # Depending on python version and IOLoop implementation, + # different exception types may be thrown and there are + # two ways EINTR might be signaled: + # * e.errno == errno.EINTR + # * e.args is like (errno.EINTR, 'Interrupted system call') + if errno_from_exception(e) == errno.EINTR: + continue + else: + raise + + if self._blocking_signal_threshold is not None: + signal.setitimer(signal.ITIMER_REAL, + self._blocking_signal_threshold, 0) + + # Pop one fd at a time from the set of pending fds and run + # its handler. Since that handler may perform actions on + # other file descriptors, there may be reentrant calls to + # this IOLoop that update self._events + self._events.update(event_pairs) + while self._events: + fd, events = self._events.popitem() + try: + fd_obj, handler_func = self._handlers[fd] + handler_func(fd_obj, events) + except (OSError, IOError) as e: + if errno_from_exception(e) == errno.EPIPE: + # Happens when the client closes the connection + pass + else: + self.handle_callback_exception(self._handlers.get(fd)) + except Exception: + self.handle_callback_exception(self._handlers.get(fd)) + fd_obj = handler_func = None + + finally: + # reset the stopped flag so another start/stop pair can be issued + self._stopped = False + if self._blocking_signal_threshold is not None: + signal.setitimer(signal.ITIMER_REAL, 0, 0) + IOLoop._current.instance = old_current + if old_wakeup_fd is not None: + signal.set_wakeup_fd(old_wakeup_fd) + + def stop(self): + self._running = False + self._stopped = True + self._waker.wake() + + def time(self): + return self.time_func() + + def call_at(self, deadline, callback, *args, **kwargs): + timeout = _Timeout( + deadline, + functools.partial(stack_context.wrap(callback), *args, **kwargs), + self) + heapq.heappush(self._timeouts, timeout) + return timeout + + def remove_timeout(self, timeout): + # Removing from a heap is complicated, so just leave the defunct + # timeout object in the queue (see discussion in + # http://docs.python.org/library/heapq.html). + # If this turns out to be a problem, we could add a garbage + # collection pass whenever there are too many dead timeouts. + timeout.callback = None + self._cancellations += 1 + + def add_callback(self, callback, *args, **kwargs): + if thread.get_ident() != self._thread_ident: + # If we're not on the IOLoop's thread, we need to synchronize + # with other threads, or waking logic will induce a race. + with self._callback_lock: + if self._closing: + return + list_empty = not self._callbacks + self._callbacks.append(functools.partial( + stack_context.wrap(callback), *args, **kwargs)) + if list_empty: + # If we're not in the IOLoop's thread, and we added the + # first callback to an empty list, we may need to wake it + # up (it may wake up on its own, but an occasional extra + # wake is harmless). Waking up a polling IOLoop is + # relatively expensive, so we try to avoid it when we can. + self._waker.wake() + else: + if self._closing: + return + # If we're on the IOLoop's thread, we don't need the lock, + # since we don't need to wake anyone, just add the + # callback. Blindly insert into self._callbacks. This is + # safe even from signal handlers because the GIL makes + # list.append atomic. One subtlety is that if the signal + # is interrupting another thread holding the + # _callback_lock block in IOLoop.start, we may modify + # either the old or new version of self._callbacks, but + # either way will work. + self._callbacks.append(functools.partial( + stack_context.wrap(callback), *args, **kwargs)) + + def add_callback_from_signal(self, callback, *args, **kwargs): + with stack_context.NullContext(): + self.add_callback(callback, *args, **kwargs) + + +class _Timeout(object): + """An IOLoop timeout, a UNIX timestamp and a callback""" + + # Reduce memory overhead when there are lots of pending callbacks + __slots__ = ['deadline', 'callback', 'tiebreaker'] + + def __init__(self, deadline, callback, io_loop): + if not isinstance(deadline, numbers.Real): + raise TypeError("Unsupported deadline %r" % deadline) + self.deadline = deadline + self.callback = callback + self.tiebreaker = next(io_loop._timeout_counter) + + # Comparison methods to sort by deadline, with object id as a tiebreaker + # to guarantee a consistent ordering. The heapq module uses __le__ + # in python2.5, and __lt__ in 2.6+ (sort() and most other comparisons + # use __lt__). + def __lt__(self, other): + return ((self.deadline, self.tiebreaker) < + (other.deadline, other.tiebreaker)) + + def __le__(self, other): + return ((self.deadline, self.tiebreaker) <= + (other.deadline, other.tiebreaker)) + + +class PeriodicCallback(object): + """Schedules the given callback to be called periodically. + + The callback is called every ``callback_time`` milliseconds. + Note that the timeout is given in milliseconds, while most other + time-related functions in Tornado use seconds. + + If the callback runs for longer than ``callback_time`` milliseconds, + subsequent invocations will be skipped to get back on schedule. + + `start` must be called after the `PeriodicCallback` is created. + + .. versionchanged:: 4.1 + The ``io_loop`` argument is deprecated. + """ + def __init__(self, callback, callback_time, io_loop=None): + self.callback = callback + if callback_time <= 0: + raise ValueError("Periodic callback must have a positive callback_time") + self.callback_time = callback_time + self.io_loop = io_loop or IOLoop.current() + self._running = False + self._timeout = None + + def start(self): + """Starts the timer.""" + self._running = True + self._next_timeout = self.io_loop.time() + self._schedule_next() + + def stop(self): + """Stops the timer.""" + self._running = False + if self._timeout is not None: + self.io_loop.remove_timeout(self._timeout) + self._timeout = None + + def is_running(self): + """Return True if this `.PeriodicCallback` has been started. + + .. versionadded:: 4.1 + """ + return self._running + + def _run(self): + if not self._running: + return + try: + return self.callback() + except Exception: + self.io_loop.handle_callback_exception(self.callback) + finally: + self._schedule_next() + + def _schedule_next(self): + if self._running: + current_time = self.io_loop.time() + + if self._next_timeout <= current_time: + callback_time_sec = self.callback_time / 1000.0 + self._next_timeout += (math.floor((current_time - self._next_timeout) / callback_time_sec) + 1) * callback_time_sec + + self._timeout = self.io_loop.add_timeout(self._next_timeout, self._run) diff --git a/.venv/lib/python3.8/site-packages/zmq/eventloop/minitornado/log.py b/.venv/lib/python3.8/site-packages/zmq/eventloop/minitornado/log.py new file mode 100644 index 00000000..49051e89 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/zmq/eventloop/minitornado/log.py @@ -0,0 +1,6 @@ +"""minimal subset of tornado.log for zmq.eventloop.minitornado""" + +import logging + +app_log = logging.getLogger("tornado.application") +gen_log = logging.getLogger("tornado.general") diff --git a/.venv/lib/python3.8/site-packages/zmq/eventloop/minitornado/platform/__init__.py b/.venv/lib/python3.8/site-packages/zmq/eventloop/minitornado/platform/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/.venv/lib/python3.8/site-packages/zmq/eventloop/minitornado/platform/__pycache__/__init__.cpython-38.pyc b/.venv/lib/python3.8/site-packages/zmq/eventloop/minitornado/platform/__pycache__/__init__.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b5eb4966b3e357c593de446d58b2760a731fc22f GIT binary patch literal 170 zcmWIL<>g`k0@j9W@gVv!h(HF6K#l_t7qb9~6oz01O-8?!3`HPe1o6vXza+OnzaXb&V5Z0aV{BwyN2PjfdsPzoCs}ux=p@D&6pkbK6H5Wx%V`2Rqk{mm!cm$q- z3SNlfTB^JP6)QW*5C+}c>UQ_jeyiQRcl~}raOGcqR$p^MensW))kWngzWzH3K}sSL zk*Y+eWvW|cOJ`-K^DHg~&x)b#<@op*I&DRp^~^Cn08tT378x zZR@?*-JI^1{bOS8WdsI`!mSe$pAW>O@5#jw5k0l1hvj}k5Or{c`nE-hR=K}Liq=~) zD%hihke9kvpuq$dq&3veXsuY7S*ORo1}BzSw{AfF+%A=%!cv%goE#k$1;sUUR^x$xGG4c16Ly3=&3N?2Z1O;I69SURXG zmqv6eiYyA8Skk1{H<@7?nl`r@Lu|s8os~4guKb3f$!qK7y6kQkBw}}PI`HDpoU^XU z0-9X>6UxC&4plV%AntBtisJXHY0&kwmi2gPYQ`5J#;ZAi8m|x6>+{2hhtmuFc?xGZ za?09zs-=-vRi9qZ$uw4dQlB^7$J;JH*~ifSK8mb&kap7|*-ZxNFil&yC+#FnhPeL$ D>)aQf literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/zmq/eventloop/minitornado/platform/__pycache__/common.cpython-38.pyc b/.venv/lib/python3.8/site-packages/zmq/eventloop/minitornado/platform/__pycache__/common.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f67228054fe0657b7a445a52e6ae8cae65064b1e GIT binary patch literal 2335 zcma)7&2JM&6rY*hwbvhUfJPKr4hwD7xFQbFMzm5@fszz~z=;SbU{zXecE<50yF1Rz zI3HG0RlvFGpAa9p_s{5|Ql%dD+7svAdZF*_#`!25I@Y{>GjHa7{@(cM#6*?AaDMvJ ze_JQyFI=1+HZ1PI)NLS~bO@)M#WZ0ZmRKDtu{(C+bR3HNR$S_o@^86Q<~Da?H>q?g zl-wh{#LKS;FN?}X^`+IRa%+V&-QmJRxg)fh31yPVbcTymCQ%v~sk|uZ$08A_2}~qY z?a8j!j|0<{D)G95G{oH?j?7-`4R}VHb~YKTX&DcU@ZqjhCUbeT9ceh1HTo(_jX%DZ zHFhG?^EK$sO|;)oR6(-}oD!-Vgd#+xrw4<@9he%4ARP+HV4QX=&bal8bZiV5zD^M; zB*NttSeJQ~*Wl~&I-h`Vg*PDd$;?>|Hia7gF|P!8;RUI;wBki67kvRFHC~|i(y*sw zDhJx@M}5(%Ry`QsLvjXMcrrasi1th`Fdmob=f>*=+aS~}yfWSNrs4QbPbiV=&|Vm% zsWiE!HP{QZ7Thz^(;^n3nQk_(dus#KRVdOj+!RK)Jnu;_(%@hi54h0YD!3|lbgm~z zx%Xht^kmw~*CA$eJW9YI#O7h@21pD!BqOp3 ze#z9&`!;8niK%VWH!bzc3j)@hO-KC-x+g{iY@k;;2lgwxG@>u)Shh;$pa~A_AMI!4 zIoNpy6J(7M`GG-1lLrpmo;*CqS?(ih8uKUGClAl(@n7HskWg+bOp(eF$cB}hw{Ev? z!0%?hlTECy++Do8u<-bP`{~N!8_eWzYCf-_w+1!vjEdIRg}U1OAS)Hc%1S#b0vKmi z4V8oX$-c>I_m`I+FFjfEpUf|3H6VU_X<_l<-RGH&YO+!sX(Q6CwqD#xgG6NIP^KxM zB6EaNQf1{{paWx6zD}j8fH#>F#!`!{6ojDwLnXj72jev`z7~V^C|%D=-6)3M?o>%wd)bE09=MSOX*|8#eN8ZjF_l=>V)Oz8-l8 zU;zOm6}ITS6x)To8fVZAU`59jlkM}W2SbSPVOVZ18`ZszqE+hQ#FvODJ1Xn+uniK^Z`h<3xq() z&e174tR8s{!ZY4tB9FcO8WzJ#C*I-%q}kTRE%uJrx8CD*MBqOXoW?3ec}tNMN-`5;EV?)zJV zAU=|meV@zF_tiB}lEYVhhFlZLbtJhL9&#rn$2yh|dqg*YxYRDWU%D3jN^V7=tXWft zE;Qa9n1KT03ahCsB5^< Dtpy}T literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/zmq/eventloop/minitornado/platform/__pycache__/interface.cpython-38.pyc b/.venv/lib/python3.8/site-packages/zmq/eventloop/minitornado/platform/__pycache__/interface.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..1d941d23619411d88c6277e515d7f4f9c5aff578 GIT binary patch literal 2302 zcmb7GO>ZMb5FOj&k2uLL>>fbk(kF-|Y-Jij;7|L-Bquv-mA{H+uQvBqy6J=(XYKA z_?=$XM~Ihaxa=n|BA5iCA)09;YfhS3YtqWXNtm@K?M5J4B774}I$s5%Ejn)k(UINP ztw~RGUj~ET^`D2ilV-{jY1vd8R;1kFo(*jw6E#%{o0fUvl+Jmo++x)4pUjkHnHFU# znY>cgSymX8aih|OcOi6AW-@o2R}F%ImTx)TOdOzI*_`xrMpm4p)1W;=mYf290HND&7WW12O;ldhD`dT&QAL<^@mAr5MgbI)*jTFPM305zMUF=>gWXn}^I2t^xrP*HS=mZB#%aPNw~*u=djwve&yW&4z$ zOT&LbPWPDA*oqsb>Rd8?_PtD~_8gqxIh*5mpjJ(ynUP$us`9awDSo;$h*9o7!#F_! z;vZIwP?~ZuIy`=kTg>JvO&J%$m&r%}$g-H~kZbq=LA?)!LdLc0IA%MjRvgPhrzzh2 z%lSnqONmMXUz!quPiHb;Vf0R1g>%kxqJ^$DQ5HTlf%=$%7=AU2X@fDG9OsFo&ogLf zuFqxeJ(bmOJ$PEc;zZ{b@*}`ZXoOv`TteNJn*}SR8TyPRspNTC)Zl7R$WC0RBW4h} zue+$g5N|EwBREwC-u1{YyN3*Z{zkge zpFtZWlMHTNJ{V7odi6>g^lWtgOSJtuja6Boi(8OKcVG;ul)G!#`ZYFuz6YkgeXv{N1eu~c zRYJkh16|$dfsugzhx03{-+{4Pi{|MX%|JuH~-Dojvd^UvbGoA zXKP?KYcS;bXt1&DMN!T(8AZ!}6jf(2p0}dtqU32k(~TmW#8G4(!jXB0%)4YBk$Fsp z&WtrfR5x2N440*cUL)*bg!JcU5ZkuF1`-e1-`G-MK%swudJXYtbNjJP47L<%Xrd_(;|_n%&M@8^Q`RV!)}p;)i77- zT3N^_9>!63ILabi4wJY#S$_-gNYB>S!hIUqRY8XZ`!Z(YDf#Jf~gi+oBQIR)f2J(=eu~YhP#%5q2S`W#Y z1(}n5a!v;T%o#>ml?2`nf3*Gc&K4T`#%S(r@y*@6?WfzD=S;JqfUQaRygVnW4N?By z?N@2hFXCctloergB*ohJg_OzKWMeWp*|@jSpQgus`4Y;N9lFNyVKE-6P$AosMx(51x=WHF??{ii@xav8o0cw%+?jq-1&GJ$= z_xNCM@Njo;^CyKIG}+do15>@q5o(ra2T2|s#o6;NynT=LI?N&%OAq$w0gUoK2uT78 zjAh7JV4Wo_VS@%<3Kz5^JmG_OMME?}dtybjK>MN%TcB7*cnk(K zot}~3p#7(;g2un1lz?VNTl2X!pOZKCj3SsbYeu*O-`X<I z=y_@tO&i)T6{c)@q}`#&3z=zG$xuk8-LZ;+vpq}OrA&sJDow|i3+i)@)ZqMU@Ka)q z32jk-{#&Kfj>&j^v27`JM1<8fsbjllT1A72$y9PVovxIkvI7pENT8b9K^HX1w zOSl|!MVTUARWx-69Bsjv-v>=PU716`t8LJ0XkdF5rjm2rJ{}F zc&HiFMe7!d+bGceg$fvI;ek;fg7^xCDFGavhHt^o^&4iT*VZ2AB9H2*!%;O-5LIE% zl!XGXT7_4Lxf$!jO%(j`)(5*j;uz$r=-R(uC-TDwu)~~So84ppgS9N*@tuDFRzsU# literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/zmq/eventloop/minitornado/platform/__pycache__/windows.cpython-38.pyc b/.venv/lib/python3.8/site-packages/zmq/eventloop/minitornado/platform/__pycache__/windows.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7638cdc59e969dc8148f60840ea5bc68c69d63ab GIT binary patch literal 683 zcmYjO&2AGh5VrRx*@XO1;E)3^kVCo>s0XA9QAlVaMTyjckbJS0^@MKfT`#t`Nl=jx z@E~yP3vuw3Q(u7-_C}RD(tMt=#xvi1e&6l3k+tyKA9~{<^w%Z#&9})b>xx-mh+&R$ zOmOZIFZYR`2PDAm-s2$&>$5>Z2-nSZv~H1>joRx6HFoy6@}Wh$b=icDiek2l`<wJ^x3#xRYA%{XQ zZn15VI=C~t8w#wyv96w4(C8Xz%X=^k4WPtHM4lY()W z6)Pe0q@MS9da@YLC-m+74}s=4n5r3 zC)!boH(9~NMje(r(^H^n%7p?7TSyPwmJJICcW{7Z&ql*XrcJG6x{^Stbb?6tyVA)b zLkBGjq`zO|&~~r)F%36|a}!;HEPy|MCY!D= 10: # I've never seen it go above 2 + a.close() + self.writer.close() + raise socket.error("Cannot bind trigger!") + # Close `a` and try again. Note: I originally put a short + # sleep() here, but it didn't appear to help or hurt. + a.close() + + self.reader, addr = a.accept() + self.reader.setblocking(0) + self.writer.setblocking(0) + a.close() + self.reader_fd = self.reader.fileno() + + def fileno(self): + return self.reader.fileno() + + def write_fileno(self): + return self.writer.fileno() + + def wake(self): + try: + self.writer.send(b"x") + except (IOError, socket.error): + pass + + def consume(self): + try: + while True: + result = self.reader.recv(1024) + if not result: + break + except (IOError, socket.error): + pass + + def close(self): + self.reader.close() + self.writer.close() diff --git a/.venv/lib/python3.8/site-packages/zmq/eventloop/minitornado/platform/interface.py b/.venv/lib/python3.8/site-packages/zmq/eventloop/minitornado/platform/interface.py new file mode 100644 index 00000000..07da6bab --- /dev/null +++ b/.venv/lib/python3.8/site-packages/zmq/eventloop/minitornado/platform/interface.py @@ -0,0 +1,63 @@ +#!/usr/bin/env python +# +# Copyright 2011 Facebook +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +"""Interfaces for platform-specific functionality. + +This module exists primarily for documentation purposes and as base classes +for other tornado.platform modules. Most code should import the appropriate +implementation from `tornado.platform.auto`. +""" + +from __future__ import absolute_import, division, print_function, with_statement + + +def set_close_exec(fd): + """Sets the close-on-exec bit (``FD_CLOEXEC``)for a file descriptor.""" + raise NotImplementedError() + + +class Waker(object): + """A socket-like object that can wake another thread from ``select()``. + + The `~tornado.ioloop.IOLoop` will add the Waker's `fileno()` to + its ``select`` (or ``epoll`` or ``kqueue``) calls. When another + thread wants to wake up the loop, it calls `wake`. Once it has woken + up, it will call `consume` to do any necessary per-wake cleanup. When + the ``IOLoop`` is closed, it closes its waker too. + """ + def fileno(self): + """Returns the read file descriptor for this waker. + + Must be suitable for use with ``select()`` or equivalent on the + local platform. + """ + raise NotImplementedError() + + def write_fileno(self): + """Returns the write file descriptor for this waker.""" + raise NotImplementedError() + + def wake(self): + """Triggers activity on the waker's file descriptor.""" + raise NotImplementedError() + + def consume(self): + """Called after the listen has woken up to do any necessary cleanup.""" + raise NotImplementedError() + + def close(self): + """Closes the waker's file descriptor(s).""" + raise NotImplementedError() diff --git a/.venv/lib/python3.8/site-packages/zmq/eventloop/minitornado/platform/posix.py b/.venv/lib/python3.8/site-packages/zmq/eventloop/minitornado/platform/posix.py new file mode 100644 index 00000000..ccffbb66 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/zmq/eventloop/minitornado/platform/posix.py @@ -0,0 +1,70 @@ +#!/usr/bin/env python +# +# Copyright 2011 Facebook +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +"""Posix implementations of platform-specific functionality.""" + +from __future__ import absolute_import, division, print_function, with_statement + +import fcntl +import os + +from . import interface + + +def set_close_exec(fd): + flags = fcntl.fcntl(fd, fcntl.F_GETFD) + fcntl.fcntl(fd, fcntl.F_SETFD, flags | fcntl.FD_CLOEXEC) + + +def _set_nonblocking(fd): + flags = fcntl.fcntl(fd, fcntl.F_GETFL) + fcntl.fcntl(fd, fcntl.F_SETFL, flags | os.O_NONBLOCK) + + +class Waker(interface.Waker): + def __init__(self): + r, w = os.pipe() + _set_nonblocking(r) + _set_nonblocking(w) + set_close_exec(r) + set_close_exec(w) + self.reader = os.fdopen(r, "rb", 0) + self.writer = os.fdopen(w, "wb", 0) + + def fileno(self): + return self.reader.fileno() + + def write_fileno(self): + return self.writer.fileno() + + def wake(self): + try: + self.writer.write(b"x") + except IOError: + pass + + def consume(self): + try: + while True: + result = self.reader.read() + if not result: + break + except IOError: + pass + + def close(self): + self.reader.close() + self.writer.close() diff --git a/.venv/lib/python3.8/site-packages/zmq/eventloop/minitornado/platform/windows.py b/.venv/lib/python3.8/site-packages/zmq/eventloop/minitornado/platform/windows.py new file mode 100644 index 00000000..817bdca1 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/zmq/eventloop/minitornado/platform/windows.py @@ -0,0 +1,20 @@ +# NOTE: win32 support is currently experimental, and not recommended +# for production use. + + +from __future__ import absolute_import, division, print_function, with_statement +import ctypes +import ctypes.wintypes + +# See: http://msdn.microsoft.com/en-us/library/ms724935(VS.85).aspx +SetHandleInformation = ctypes.windll.kernel32.SetHandleInformation +SetHandleInformation.argtypes = (ctypes.wintypes.HANDLE, ctypes.wintypes.DWORD, ctypes.wintypes.DWORD) +SetHandleInformation.restype = ctypes.wintypes.BOOL + +HANDLE_FLAG_INHERIT = 0x00000001 + + +def set_close_exec(fd): + success = SetHandleInformation(fd, HANDLE_FLAG_INHERIT, 0) + if not success: + raise ctypes.GetLastError() diff --git a/.venv/lib/python3.8/site-packages/zmq/eventloop/minitornado/stack_context.py b/.venv/lib/python3.8/site-packages/zmq/eventloop/minitornado/stack_context.py new file mode 100644 index 00000000..640a39b1 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/zmq/eventloop/minitornado/stack_context.py @@ -0,0 +1,388 @@ +#!/usr/bin/env python +# +# Copyright 2010 Facebook +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +"""`StackContext` allows applications to maintain threadlocal-like state +that follows execution as it moves to other execution contexts. + +The motivating examples are to eliminate the need for explicit +``async_callback`` wrappers (as in `tornado.web.RequestHandler`), and to +allow some additional context to be kept for logging. + +This is slightly magic, but it's an extension of the idea that an +exception handler is a kind of stack-local state and when that stack +is suspended and resumed in a new context that state needs to be +preserved. `StackContext` shifts the burden of restoring that state +from each call site (e.g. wrapping each `.AsyncHTTPClient` callback +in ``async_callback``) to the mechanisms that transfer control from +one context to another (e.g. `.AsyncHTTPClient` itself, `.IOLoop`, +thread pools, etc). + +Example usage:: + + @contextlib.contextmanager + def die_on_error(): + try: + yield + except Exception: + logging.error("exception in asynchronous operation",exc_info=True) + sys.exit(1) + + with StackContext(die_on_error): + # Any exception thrown here *or in callback and its descendants* + # will cause the process to exit instead of spinning endlessly + # in the ioloop. + http_client.fetch(url, callback) + ioloop.start() + +Most applications shouldn't have to work with `StackContext` directly. +Here are a few rules of thumb for when it's necessary: + +* If you're writing an asynchronous library that doesn't rely on a + stack_context-aware library like `tornado.ioloop` or `tornado.iostream` + (for example, if you're writing a thread pool), use + `.stack_context.wrap()` before any asynchronous operations to capture the + stack context from where the operation was started. + +* If you're writing an asynchronous library that has some shared + resources (such as a connection pool), create those shared resources + within a ``with stack_context.NullContext():`` block. This will prevent + ``StackContexts`` from leaking from one request to another. + +* If you want to write something like an exception handler that will + persist across asynchronous calls, create a new `StackContext` (or + `ExceptionStackContext`), and make your asynchronous calls in a ``with`` + block that references your `StackContext`. +""" + +from __future__ import absolute_import, division, print_function, with_statement + +import sys +import threading + +from .util import raise_exc_info + + +class StackContextInconsistentError(Exception): + pass + + +class _State(threading.local): + def __init__(self): + self.contexts = (tuple(), None) +_state = _State() + + +class StackContext(object): + """Establishes the given context as a StackContext that will be transferred. + + Note that the parameter is a callable that returns a context + manager, not the context itself. That is, where for a + non-transferable context manager you would say:: + + with my_context(): + + StackContext takes the function itself rather than its result:: + + with StackContext(my_context): + + The result of ``with StackContext() as cb:`` is a deactivation + callback. Run this callback when the StackContext is no longer + needed to ensure that it is not propagated any further (note that + deactivating a context does not affect any instances of that + context that are currently pending). This is an advanced feature + and not necessary in most applications. + """ + def __init__(self, context_factory): + self.context_factory = context_factory + self.contexts = [] + self.active = True + + def _deactivate(self): + self.active = False + + # StackContext protocol + def enter(self): + context = self.context_factory() + self.contexts.append(context) + context.__enter__() + + def exit(self, type, value, traceback): + context = self.contexts.pop() + context.__exit__(type, value, traceback) + + # Note that some of this code is duplicated in ExceptionStackContext + # below. ExceptionStackContext is more common and doesn't need + # the full generality of this class. + def __enter__(self): + self.old_contexts = _state.contexts + self.new_contexts = (self.old_contexts[0] + (self,), self) + _state.contexts = self.new_contexts + + try: + self.enter() + except: + _state.contexts = self.old_contexts + raise + + return self._deactivate + + def __exit__(self, type, value, traceback): + try: + self.exit(type, value, traceback) + finally: + final_contexts = _state.contexts + _state.contexts = self.old_contexts + + # Generator coroutines and with-statements with non-local + # effects interact badly. Check here for signs of + # the stack getting out of sync. + # Note that this check comes after restoring _state.context + # so that if it fails things are left in a (relatively) + # consistent state. + if final_contexts is not self.new_contexts: + raise StackContextInconsistentError( + 'stack_context inconsistency (may be caused by yield ' + 'within a "with StackContext" block)') + + # Break up a reference to itself to allow for faster GC on CPython. + self.new_contexts = None + + +class ExceptionStackContext(object): + """Specialization of StackContext for exception handling. + + The supplied ``exception_handler`` function will be called in the + event of an uncaught exception in this context. The semantics are + similar to a try/finally clause, and intended use cases are to log + an error, close a socket, or similar cleanup actions. The + ``exc_info`` triple ``(type, value, traceback)`` will be passed to the + exception_handler function. + + If the exception handler returns true, the exception will be + consumed and will not be propagated to other exception handlers. + """ + def __init__(self, exception_handler): + self.exception_handler = exception_handler + self.active = True + + def _deactivate(self): + self.active = False + + def exit(self, type, value, traceback): + if type is not None: + return self.exception_handler(type, value, traceback) + + def __enter__(self): + self.old_contexts = _state.contexts + self.new_contexts = (self.old_contexts[0], self) + _state.contexts = self.new_contexts + + return self._deactivate + + def __exit__(self, type, value, traceback): + try: + if type is not None: + return self.exception_handler(type, value, traceback) + finally: + final_contexts = _state.contexts + _state.contexts = self.old_contexts + + if final_contexts is not self.new_contexts: + raise StackContextInconsistentError( + 'stack_context inconsistency (may be caused by yield ' + 'within a "with StackContext" block)') + + # Break up a reference to itself to allow for faster GC on CPython. + self.new_contexts = None + + +class NullContext(object): + """Resets the `StackContext`. + + Useful when creating a shared resource on demand (e.g. an + `.AsyncHTTPClient`) where the stack that caused the creating is + not relevant to future operations. + """ + def __enter__(self): + self.old_contexts = _state.contexts + _state.contexts = (tuple(), None) + + def __exit__(self, type, value, traceback): + _state.contexts = self.old_contexts + + +def _remove_deactivated(contexts): + """Remove deactivated handlers from the chain""" + # Clean ctx handlers + stack_contexts = tuple([h for h in contexts[0] if h.active]) + + # Find new head + head = contexts[1] + while head is not None and not head.active: + head = head.old_contexts[1] + + # Process chain + ctx = head + while ctx is not None: + parent = ctx.old_contexts[1] + + while parent is not None: + if parent.active: + break + ctx.old_contexts = parent.old_contexts + parent = parent.old_contexts[1] + + ctx = parent + + return (stack_contexts, head) + + +def wrap(fn): + """Returns a callable object that will restore the current `StackContext` + when executed. + + Use this whenever saving a callback to be executed later in a + different execution context (either in a different thread or + asynchronously in the same thread). + """ + # Check if function is already wrapped + if fn is None or hasattr(fn, '_wrapped'): + return fn + + # Capture current stack head + # TODO: Any other better way to store contexts and update them in wrapped function? + cap_contexts = [_state.contexts] + + if not cap_contexts[0][0] and not cap_contexts[0][1]: + # Fast path when there are no active contexts. + def null_wrapper(*args, **kwargs): + try: + current_state = _state.contexts + _state.contexts = cap_contexts[0] + return fn(*args, **kwargs) + finally: + _state.contexts = current_state + null_wrapper._wrapped = True + return null_wrapper + + def wrapped(*args, **kwargs): + ret = None + try: + # Capture old state + current_state = _state.contexts + + # Remove deactivated items + cap_contexts[0] = contexts = _remove_deactivated(cap_contexts[0]) + + # Force new state + _state.contexts = contexts + + # Current exception + exc = (None, None, None) + top = None + + # Apply stack contexts + last_ctx = 0 + stack = contexts[0] + + # Apply state + for n in stack: + try: + n.enter() + last_ctx += 1 + except: + # Exception happened. Record exception info and store top-most handler + exc = sys.exc_info() + top = n.old_contexts[1] + + # Execute callback if no exception happened while restoring state + if top is None: + try: + ret = fn(*args, **kwargs) + except: + exc = sys.exc_info() + top = contexts[1] + + # If there was exception, try to handle it by going through the exception chain + if top is not None: + exc = _handle_exception(top, exc) + else: + # Otherwise take shorter path and run stack contexts in reverse order + while last_ctx > 0: + last_ctx -= 1 + c = stack[last_ctx] + + try: + c.exit(*exc) + except: + exc = sys.exc_info() + top = c.old_contexts[1] + break + else: + top = None + + # If if exception happened while unrolling, take longer exception handler path + if top is not None: + exc = _handle_exception(top, exc) + + # If exception was not handled, raise it + if exc != (None, None, None): + raise_exc_info(exc) + finally: + _state.contexts = current_state + return ret + + wrapped._wrapped = True + return wrapped + + +def _handle_exception(tail, exc): + while tail is not None: + try: + if tail.exit(*exc): + exc = (None, None, None) + except: + exc = sys.exc_info() + + tail = tail.old_contexts[1] + + return exc + + +def run_with_stack_context(context, func): + """Run a coroutine ``func`` in the given `StackContext`. + + It is not safe to have a ``yield`` statement within a ``with StackContext`` + block, so it is difficult to use stack context with `.gen.coroutine`. + This helper function runs the function in the correct context while + keeping the ``yield`` and ``with`` statements syntactically separate. + + Example:: + + @gen.coroutine + def incorrect(): + with StackContext(ctx): + # ERROR: this will raise StackContextInconsistentError + yield other_coroutine() + + @gen.coroutine + def correct(): + yield run_with_stack_context(StackContext(ctx), other_coroutine) + + .. versionadded:: 3.1 + """ + with context: + return func() diff --git a/.venv/lib/python3.8/site-packages/zmq/eventloop/minitornado/util.py b/.venv/lib/python3.8/site-packages/zmq/eventloop/minitornado/util.py new file mode 100644 index 00000000..68bb67be --- /dev/null +++ b/.venv/lib/python3.8/site-packages/zmq/eventloop/minitornado/util.py @@ -0,0 +1,216 @@ +"""Miscellaneous utility functions and classes. + +This module is used internally by Tornado. It is not necessarily expected +that the functions and classes defined here will be useful to other +applications, but they are documented here in case they are. + +The one public-facing part of this module is the `Configurable` class +and its `~Configurable.configure` method, which becomes a part of the +interface of its subclasses, including `.AsyncHTTPClient`, `.IOLoop`, +and `.Resolver`. +""" + +from __future__ import absolute_import, division, print_function, with_statement + +import sys + + +# Fake unicode literal support: Python 3.2 doesn't have the u'' marker for +# literal strings, and alternative solutions like "from __future__ import +# unicode_literals" have other problems (see PEP 414). u() can be applied +# to ascii strings that include \u escapes (but they must not contain +# literal non-ascii characters). +if not isinstance(b'', type('')): + def u(s): + return s + unicode_type = str + basestring_type = str +else: + def u(s): + return s.decode('unicode_escape') + # These names don't exist in py3, so use noqa comments to disable + # warnings in flake8. + unicode_type = unicode # noqa + basestring_type = basestring # noqa + + +def import_object(name): + """Imports an object by name. + + import_object('x') is equivalent to 'import x'. + import_object('x.y.z') is equivalent to 'from x.y import z'. + + >>> import tornado.escape + >>> import_object('tornado.escape') is tornado.escape + True + >>> import_object('tornado.escape.utf8') is tornado.escape.utf8 + True + >>> import_object('tornado') is tornado + True + >>> import_object('tornado.missing_module') + Traceback (most recent call last): + ... + ImportError: No module named missing_module + """ + if isinstance(name, unicode_type) and str is not unicode_type: + # On python 2 a byte string is required. + name = name.encode('utf-8') + if name.count('.') == 0: + return __import__(name, None, None) + + parts = name.split('.') + obj = __import__('.'.join(parts[:-1]), None, None, [parts[-1]], 0) + try: + return getattr(obj, parts[-1]) + except AttributeError: + raise ImportError("No module named %s" % parts[-1]) + + +# Deprecated alias that was used before we dropped py25 support. +# Left here in case anyone outside Tornado is using it. +bytes_type = bytes + +if sys.version_info > (3,): + exec(""" +def raise_exc_info(exc_info): + raise exc_info[1].with_traceback(exc_info[2]) + +def exec_in(code, glob, loc=None): + if isinstance(code, str): + code = compile(code, '', 'exec', dont_inherit=True) + exec(code, glob, loc) +""") +else: + exec(""" +def raise_exc_info(exc_info): + raise exc_info[0], exc_info[1], exc_info[2] + +def exec_in(code, glob, loc=None): + if isinstance(code, basestring): + # exec(string) inherits the caller's future imports; compile + # the string first to prevent that. + code = compile(code, '', 'exec', dont_inherit=True) + exec code in glob, loc +""") + + +def errno_from_exception(e): + """Provides the errno from an Exception object. + + There are cases that the errno attribute was not set so we pull + the errno out of the args but if someone instantiates an Exception + without any args you will get a tuple error. So this function + abstracts all that behavior to give you a safe way to get the + errno. + """ + + if hasattr(e, 'errno'): + return e.errno + elif e.args: + return e.args[0] + else: + return None + + +class Configurable(object): + """Base class for configurable interfaces. + + A configurable interface is an (abstract) class whose constructor + acts as a factory function for one of its implementation subclasses. + The implementation subclass as well as optional keyword arguments to + its initializer can be set globally at runtime with `configure`. + + By using the constructor as the factory method, the interface + looks like a normal class, `isinstance` works as usual, etc. This + pattern is most useful when the choice of implementation is likely + to be a global decision (e.g. when `~select.epoll` is available, + always use it instead of `~select.select`), or when a + previously-monolithic class has been split into specialized + subclasses. + + Configurable subclasses must define the class methods + `configurable_base` and `configurable_default`, and use the instance + method `initialize` instead of ``__init__``. + """ + __impl_class = None + __impl_kwargs = None + + def __new__(cls, *args, **kwargs): + base = cls.configurable_base() + init_kwargs = {} + if cls is base: + impl = cls.configured_class() + if base.__impl_kwargs: + init_kwargs.update(base.__impl_kwargs) + else: + impl = cls + init_kwargs.update(kwargs) + instance = super(Configurable, cls).__new__(impl) + # initialize vs __init__ chosen for compatibility with AsyncHTTPClient + # singleton magic. If we get rid of that we can switch to __init__ + # here too. + instance.initialize(*args, **init_kwargs) + return instance + + @classmethod + def configurable_base(cls): + """Returns the base class of a configurable hierarchy. + + This will normally return the class in which it is defined. + (which is *not* necessarily the same as the cls classmethod parameter). + """ + raise NotImplementedError() + + @classmethod + def configurable_default(cls): + """Returns the implementation class to be used if none is configured.""" + raise NotImplementedError() + + def initialize(self): + """Initialize a `Configurable` subclass instance. + + Configurable classes should use `initialize` instead of ``__init__``. + + .. versionchanged:: 4.2 + Now accepts positional arguments in addition to keyword arguments. + """ + + @classmethod + def configure(cls, impl, **kwargs): + """Sets the class to use when the base class is instantiated. + + Keyword arguments will be saved and added to the arguments passed + to the constructor. This can be used to set global defaults for + some parameters. + """ + base = cls.configurable_base() + if isinstance(impl, (unicode_type, bytes)): + impl = import_object(impl) + if impl is not None and not issubclass(impl, cls): + raise ValueError("Invalid subclass of %s" % cls) + base.__impl_class = impl + base.__impl_kwargs = kwargs + + @classmethod + def configured_class(cls): + """Returns the currently configured class.""" + base = cls.configurable_base() + if cls.__impl_class is None: + base.__impl_class = cls.configurable_default() + return base.__impl_class + + @classmethod + def _save_configuration(cls): + base = cls.configurable_base() + return (base.__impl_class, base.__impl_kwargs) + + @classmethod + def _restore_configuration(cls, saved): + base = cls.configurable_base() + base.__impl_class = saved[0] + base.__impl_kwargs = saved[1] + + +def timedelta_to_seconds(td): + """Equivalent to td.total_seconds() (introduced in python 2.7).""" + return (td.microseconds + (td.seconds + td.days * 24 * 3600) * 10 ** 6) / float(10 ** 6) diff --git a/.venv/lib/python3.8/site-packages/zmq/eventloop/zmqstream.py b/.venv/lib/python3.8/site-packages/zmq/eventloop/zmqstream.py new file mode 100644 index 00000000..bb45faf2 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/zmq/eventloop/zmqstream.py @@ -0,0 +1,553 @@ +# +# Copyright 2009 Facebook +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +"""A utility class to send to and recv from a non-blocking socket, +using tornado. + +.. seealso:: + + - :mod:`zmq.asyncio` + - :mod:`zmq.eventloop.future` + +""" + +from __future__ import with_statement +import sys +import warnings + +import zmq +from zmq.utils import jsonapi + +try: + import cPickle as pickle +except ImportError: + import pickle + +from .ioloop import IOLoop, gen_log + +try: + from tornado.stack_context import wrap as stack_context_wrap +except ImportError: + if "zmq.eventloop.minitornado" in sys.modules: + from .minitornado.stack_context import wrap as stack_context_wrap + else: + # tornado 5 deprecates stack_context, + # tornado 6 removes it + def stack_context_wrap(callback): + return callback + +try: + from queue import Queue +except ImportError: + from Queue import Queue + +from zmq.utils.strtypes import basestring + +try: + callable +except NameError: + callable = lambda obj: hasattr(obj, '__call__') + + +class ZMQStream(object): + """A utility class to register callbacks when a zmq socket sends and receives + + For use with zmq.eventloop.ioloop + + There are three main methods + + Methods: + + * **on_recv(callback, copy=True):** + register a callback to be run every time the socket has something to receive + * **on_send(callback):** + register a callback to be run every time you call send + * **send(self, msg, flags=0, copy=False, callback=None):** + perform a send that will trigger the callback + if callback is passed, on_send is also called. + + There are also send_multipart(), send_json(), send_pyobj() + + Three other methods for deactivating the callbacks: + + * **stop_on_recv():** + turn off the recv callback + * **stop_on_send():** + turn off the send callback + + which simply call ``on_(None)``. + + The entire socket interface, excluding direct recv methods, is also + provided, primarily through direct-linking the methods. + e.g. + + >>> stream.bind is stream.socket.bind + True + + """ + + socket = None + io_loop = None + poller = None + _send_queue = None + _recv_callback = None + _send_callback = None + _close_callback = None + _state = 0 + _flushed = False + _recv_copy = False + _fd = None + + def __init__(self, socket, io_loop=None): + self.socket = socket + self.io_loop = io_loop or IOLoop.current() + self.poller = zmq.Poller() + self._fd = self.socket.FD + + self._send_queue = Queue() + self._recv_callback = None + self._send_callback = None + self._close_callback = None + self._recv_copy = False + self._flushed = False + + self._state = 0 + self._init_io_state() + + # shortcircuit some socket methods + self.bind = self.socket.bind + self.bind_to_random_port = self.socket.bind_to_random_port + self.connect = self.socket.connect + self.setsockopt = self.socket.setsockopt + self.getsockopt = self.socket.getsockopt + self.setsockopt_string = self.socket.setsockopt_string + self.getsockopt_string = self.socket.getsockopt_string + self.setsockopt_unicode = self.socket.setsockopt_unicode + self.getsockopt_unicode = self.socket.getsockopt_unicode + + def stop_on_recv(self): + """Disable callback and automatic receiving.""" + return self.on_recv(None) + + def stop_on_send(self): + """Disable callback on sending.""" + return self.on_send(None) + + def stop_on_err(self): + """DEPRECATED, does nothing""" + gen_log.warn("on_err does nothing, and will be removed") + + def on_err(self, callback): + """DEPRECATED, does nothing""" + gen_log.warn("on_err does nothing, and will be removed") + + def on_recv(self, callback, copy=True): + """Register a callback for when a message is ready to recv. + + There can be only one callback registered at a time, so each + call to `on_recv` replaces previously registered callbacks. + + on_recv(None) disables recv event polling. + + Use on_recv_stream(callback) instead, to register a callback that will receive + both this ZMQStream and the message, instead of just the message. + + Parameters + ---------- + + callback : callable + callback must take exactly one argument, which will be a + list, as returned by socket.recv_multipart() + if callback is None, recv callbacks are disabled. + copy : bool + copy is passed directly to recv, so if copy is False, + callback will receive Message objects. If copy is True, + then callback will receive bytes/str objects. + + Returns : None + """ + + self._check_closed() + assert callback is None or callable(callback) + self._recv_callback = stack_context_wrap(callback) + self._recv_copy = copy + if callback is None: + self._drop_io_state(zmq.POLLIN) + else: + self._add_io_state(zmq.POLLIN) + + def on_recv_stream(self, callback, copy=True): + """Same as on_recv, but callback will get this stream as first argument + + callback must take exactly two arguments, as it will be called as:: + + callback(stream, msg) + + Useful when a single callback should be used with multiple streams. + """ + if callback is None: + self.stop_on_recv() + else: + self.on_recv(lambda msg: callback(self, msg), copy=copy) + + def on_send(self, callback): + """Register a callback to be called on each send + + There will be two arguments:: + + callback(msg, status) + + * `msg` will be the list of sendable objects that was just sent + * `status` will be the return result of socket.send_multipart(msg) - + MessageTracker or None. + + Non-copying sends return a MessageTracker object whose + `done` attribute will be True when the send is complete. + This allows users to track when an object is safe to write to + again. + + The second argument will always be None if copy=True + on the send. + + Use on_send_stream(callback) to register a callback that will be passed + this ZMQStream as the first argument, in addition to the other two. + + on_send(None) disables recv event polling. + + Parameters + ---------- + + callback : callable + callback must take exactly two arguments, which will be + the message being sent (always a list), + and the return result of socket.send_multipart(msg) - + MessageTracker or None. + + if callback is None, send callbacks are disabled. + """ + + self._check_closed() + assert callback is None or callable(callback) + self._send_callback = stack_context_wrap(callback) + + + def on_send_stream(self, callback): + """Same as on_send, but callback will get this stream as first argument + + Callback will be passed three arguments:: + + callback(stream, msg, status) + + Useful when a single callback should be used with multiple streams. + """ + if callback is None: + self.stop_on_send() + else: + self.on_send(lambda msg, status: callback(self, msg, status)) + + + def send(self, msg, flags=0, copy=True, track=False, callback=None, **kwargs): + """Send a message, optionally also register a new callback for sends. + See zmq.socket.send for details. + """ + return self.send_multipart([msg], flags=flags, copy=copy, track=track, callback=callback, **kwargs) + + def send_multipart(self, msg, flags=0, copy=True, track=False, callback=None, **kwargs): + """Send a multipart message, optionally also register a new callback for sends. + See zmq.socket.send_multipart for details. + """ + kwargs.update(dict(flags=flags, copy=copy, track=track)) + self._send_queue.put((msg, kwargs)) + callback = callback or self._send_callback + if callback is not None: + self.on_send(callback) + else: + # noop callback + self.on_send(lambda *args: None) + self._add_io_state(zmq.POLLOUT) + + def send_string(self, u, flags=0, encoding='utf-8', callback=None, **kwargs): + """Send a unicode message with an encoding. + See zmq.socket.send_unicode for details. + """ + if not isinstance(u, basestring): + raise TypeError("unicode/str objects only") + return self.send(u.encode(encoding), flags=flags, callback=callback, **kwargs) + + send_unicode = send_string + + def send_json(self, obj, flags=0, callback=None, **kwargs): + """Send json-serialized version of an object. + See zmq.socket.send_json for details. + """ + if jsonapi is None: + raise ImportError('jsonlib{1,2}, json or simplejson library is required.') + else: + msg = jsonapi.dumps(obj) + return self.send(msg, flags=flags, callback=callback, **kwargs) + + def send_pyobj(self, obj, flags=0, protocol=-1, callback=None, **kwargs): + """Send a Python object as a message using pickle to serialize. + + See zmq.socket.send_json for details. + """ + msg = pickle.dumps(obj, protocol) + return self.send(msg, flags, callback=callback, **kwargs) + + def _finish_flush(self): + """callback for unsetting _flushed flag.""" + self._flushed = False + + def flush(self, flag=zmq.POLLIN|zmq.POLLOUT, limit=None): + """Flush pending messages. + + This method safely handles all pending incoming and/or outgoing messages, + bypassing the inner loop, passing them to the registered callbacks. + + A limit can be specified, to prevent blocking under high load. + + flush will return the first time ANY of these conditions are met: + * No more events matching the flag are pending. + * the total number of events handled reaches the limit. + + Note that if ``flag|POLLIN != 0``, recv events will be flushed even if no callback + is registered, unlike normal IOLoop operation. This allows flush to be + used to remove *and ignore* incoming messages. + + Parameters + ---------- + flag : int, default=POLLIN|POLLOUT + 0MQ poll flags. + If flag|POLLIN, recv events will be flushed. + If flag|POLLOUT, send events will be flushed. + Both flags can be set at once, which is the default. + limit : None or int, optional + The maximum number of messages to send or receive. + Both send and recv count against this limit. + + Returns + ------- + int : count of events handled (both send and recv) + """ + self._check_closed() + # unset self._flushed, so callbacks will execute, in case flush has + # already been called this iteration + already_flushed = self._flushed + self._flushed = False + # initialize counters + count = 0 + def update_flag(): + """Update the poll flag, to prevent registering POLLOUT events + if we don't have pending sends.""" + return flag & zmq.POLLIN | (self.sending() and flag & zmq.POLLOUT) + flag = update_flag() + if not flag: + # nothing to do + return 0 + self.poller.register(self.socket, flag) + events = self.poller.poll(0) + while events and (not limit or count < limit): + s,event = events[0] + if event & zmq.POLLIN: # receiving + self._handle_recv() + count += 1 + if self.socket is None: + # break if socket was closed during callback + break + if event & zmq.POLLOUT and self.sending(): + self._handle_send() + count += 1 + if self.socket is None: + # break if socket was closed during callback + break + + flag = update_flag() + if flag: + self.poller.register(self.socket, flag) + events = self.poller.poll(0) + else: + events = [] + if count: # only bypass loop if we actually flushed something + # skip send/recv callbacks this iteration + self._flushed = True + # reregister them at the end of the loop + if not already_flushed: # don't need to do it again + self.io_loop.add_callback(self._finish_flush) + elif already_flushed: + self._flushed = True + + # update ioloop poll state, which may have changed + self._rebuild_io_state() + return count + + def set_close_callback(self, callback): + """Call the given callback when the stream is closed.""" + self._close_callback = stack_context_wrap(callback) + + def close(self, linger=None): + """Close this stream.""" + if self.socket is not None: + if self.socket.closed: + # fallback on raw fd for closed sockets + # hopefully this happened promptly after close, + # otherwise somebody else may have the FD + warnings.warn( + "Unregistering FD %s after closing socket. " + "This could result in unregistering handlers for the wrong socket. " + "Please use stream.close() instead of closing the socket directly." + % self._fd, + stacklevel=2, + ) + self.io_loop.remove_handler(self._fd) + else: + self.io_loop.remove_handler(self.socket) + self.socket.close(linger) + self.socket = None + if self._close_callback: + self._run_callback(self._close_callback) + + def receiving(self): + """Returns True if we are currently receiving from the stream.""" + return self._recv_callback is not None + + def sending(self): + """Returns True if we are currently sending to the stream.""" + return not self._send_queue.empty() + + def closed(self): + if self.socket is None: + return True + if self.socket.closed: + # underlying socket has been closed, but not by us! + # trigger our cleanup + self.close() + return True + + def _run_callback(self, callback, *args, **kwargs): + """Wrap running callbacks in try/except to allow us to + close our socket.""" + try: + # Use a NullContext to ensure that all StackContexts are run + # inside our blanket exception handler rather than outside. + callback(*args, **kwargs) + except: + gen_log.error("Uncaught exception in ZMQStream callback", + exc_info=True) + # Re-raise the exception so that IOLoop.handle_callback_exception + # can see it and log the error + raise + + def _handle_events(self, fd, events): + """This method is the actual handler for IOLoop, that gets called whenever + an event on my socket is posted. It dispatches to _handle_recv, etc.""" + if not self.socket: + gen_log.warning("Got events for closed stream %s", fd) + return + zmq_events = self.socket.EVENTS + try: + # dispatch events: + if zmq_events & zmq.POLLIN and self.receiving(): + self._handle_recv() + if not self.socket: + return + if zmq_events & zmq.POLLOUT and self.sending(): + self._handle_send() + if not self.socket: + return + + # rebuild the poll state + self._rebuild_io_state() + except Exception: + gen_log.error("Uncaught exception in zmqstream callback", + exc_info=True) + raise + + def _handle_recv(self): + """Handle a recv event.""" + if self._flushed: + return + try: + msg = self.socket.recv_multipart(zmq.NOBLOCK, copy=self._recv_copy) + except zmq.ZMQError as e: + if e.errno == zmq.EAGAIN: + # state changed since poll event + pass + else: + raise + else: + if self._recv_callback: + callback = self._recv_callback + self._run_callback(callback, msg) + + + def _handle_send(self): + """Handle a send event.""" + if self._flushed: + return + if not self.sending(): + gen_log.error("Shouldn't have handled a send event") + return + + msg, kwargs = self._send_queue.get() + try: + status = self.socket.send_multipart(msg, **kwargs) + except zmq.ZMQError as e: + gen_log.error("SEND Error: %s", e) + status = e + if self._send_callback: + callback = self._send_callback + self._run_callback(callback, msg, status) + + def _check_closed(self): + if not self.socket: + raise IOError("Stream is closed") + + def _rebuild_io_state(self): + """rebuild io state based on self.sending() and receiving()""" + if self.socket is None: + return + state = 0 + if self.receiving(): + state |= zmq.POLLIN + if self.sending(): + state |= zmq.POLLOUT + + self._state = state + self._update_handler(state) + + def _add_io_state(self, state): + """Add io_state to poller.""" + self._state = self._state | state + self._update_handler(self._state) + + def _drop_io_state(self, state): + """Stop poller from watching an io_state.""" + self._state = self._state & (~state) + self._update_handler(self._state) + + def _update_handler(self, state): + """Update IOLoop handler with state.""" + if self.socket is None: + return + + if state & self.socket.events: + # events still exist that haven't been processed + # explicitly schedule handling to avoid missing events due to edge-triggered FDs + self.io_loop.add_callback(lambda : self._handle_events(self.socket, 0)) + + def _init_io_state(self): + """initialize the ioloop event handler""" + self.io_loop.add_handler(self.socket, self._handle_events, self.io_loop.READ) + diff --git a/.venv/lib/python3.8/site-packages/zmq/green/__init__.py b/.venv/lib/python3.8/site-packages/zmq/green/__init__.py new file mode 100644 index 00000000..ff7e5965 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/zmq/green/__init__.py @@ -0,0 +1,40 @@ +# -*- coding: utf-8 -*- +#----------------------------------------------------------------------------- +# Copyright (C) 2011-2012 Travis Cline +# +# This file is part of pyzmq +# It is adapted from upstream project zeromq_gevent under the New BSD License +# +# Distributed under the terms of the New BSD License. The full license is in +# the file COPYING.BSD, distributed as part of this software. +#----------------------------------------------------------------------------- + +"""zmq.green - gevent compatibility with zeromq. + +Usage +----- + +Instead of importing zmq directly, do so in the following manner: + +.. + + import zmq.green as zmq + + +Any calls that would have blocked the current thread will now only block the +current green thread. + +This compatibility is accomplished by ensuring the nonblocking flag is set +before any blocking operation and the ØMQ file descriptor is polled internally +to trigger needed events. +""" + +from zmq import * +from zmq.green.core import _Context, _Socket +from zmq.green.poll import _Poller +Context = _Context +Socket = _Socket +Poller = _Poller + +from zmq.green.device import device + diff --git a/.venv/lib/python3.8/site-packages/zmq/green/__pycache__/__init__.cpython-38.pyc b/.venv/lib/python3.8/site-packages/zmq/green/__pycache__/__init__.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..4f603d2eae7777e89e93edff73f5a023add98751 GIT binary patch literal 828 zcmZ8f&5qMB5Kh`O?RtN-2OeOqMYKH?34{$KVxs z1+KgUhh91H3Y-`>%d%pkIGOP`-+VLn_30^#$VQ)kWFL|!`Wc-2HX!E(z3vq)BI1#V z#X!YZ;X71=ddP=$!jm}oi5k@@PvZ!Oe2fX7V9JjuK2oec=EsCdFQe(W{T4^jP5o(J zT0{*qC~t@l&X4dK^4@WoKR)}i0Tkdw<^2u^R9E-!z lEV4{$>9cI!boWE5+~sq`~e|4|J(oo literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/zmq/green/__pycache__/core.cpython-38.pyc b/.venv/lib/python3.8/site-packages/zmq/green/__pycache__/core.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..6745257418b4eca44a241d969cec60d56c43d173 GIT binary patch literal 7540 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 Tc#$YEi{WMUi{zDQ&<*w%La+Q6 literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/zmq/green/__pycache__/poll.cpython-38.pyc b/.venv/lib/python3.8/site-packages/zmq/green/__pycache__/poll.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0107312818a6eecca3d4bf885c6be89e99c84f3b GIT binary patch literal 2162 zcmZuy&2Jnv6t_K}yWNCk8==y2FqJ@EiEgS&kxCSm3i^dqQbaN{sCM#P@ZQtZB*frpY7-8_nzPL@6Da5 zsXBsYef_(?bpoNk^x}9kVQ~d|wg7}7h9l%vBla+?NrVT)BUtl{2n`I+#OMZMCbJF@ zv$(l$coxIUsBJ$74QR2Am7Vd3ccq?voX{)+r9UvTOOCDj^GZ^tqW-#*r zfmZi1>S1Ox=b+}H~#*pi_1Gz#DPKgPoQVN0qLU=hEAXx1zJZ}(N{m;CnIxYNnDtctQ-48 zEEITb7UtN3wS9;WF-DuMc(IglVEYB?gp2X@vJMtR3;*$f(LB3jGa!6 z&Rd^v!MRTLZYIM^0cH2Xh{s8Ot{Ts^>0p>iP@`?rAf{VE6zZ%=-sgh$SblT4vRcYL zP106Q>4e9A#n=q{BvKAf9{3(S@vnALB&lkTdf5B~ed64lgi_W}@PnixJZ zjT^WHvpTk+6WoNcNlZ*$*hU>V)z={TsR=?mud96i0$P`7os(9BQI{wKdUgpQRA7cT zT+v`;gkf%Mz?Jlz;SrRGkpbN-`KGum(K;RzSea+gAs$&Vz+z_dlN&9_(Db!At0SI$Z};K@*`8o)|OKjz!Y?rMNV;xtGrD;uV8BmKKj zrhcdDB)lkHEBuGUzAvleLcgbWO}weaoFirnR^p^4GeA63YD0E;IP)6E&nqmSVO8_} z^6%mMC4|J=`slkrGy<|qK#=1C2z0OD;Nlj6IhiI+07l)K257Y4bMYzCBr`A)e3sO4 z-Z+ATzCs(9L20|n_5B#4>HDhg`-6lHBRy~U{^l@` to be non blocking +""" + +from __future__ import print_function + +import sys +import time +import warnings + +import zmq + +from zmq import Context as _original_Context +from zmq import Socket as _original_Socket +from .poll import _Poller + +import gevent +from gevent.event import AsyncResult +from gevent.hub import get_hub + +if hasattr(zmq, 'RCVTIMEO'): + TIMEOS = (zmq.RCVTIMEO, zmq.SNDTIMEO) +else: + TIMEOS = () + +def _stop(evt): + """simple wrapper for stopping an Event, allowing for method rename in gevent 1.0""" + try: + evt.stop() + except AttributeError as e: + # gevent<1.0 compat + evt.cancel() + +class _Socket(_original_Socket): + """Green version of :class:`zmq.Socket` + + The following methods are overridden: + + * send + * recv + + To ensure that the ``zmq.NOBLOCK`` flag is set and that sending or receiving + is deferred to the hub if a ``zmq.EAGAIN`` (retry) error is raised. + + The `__state_changed` method is triggered when the zmq.FD for the socket is + marked as readable and triggers the necessary read and write events (which + are waited for in the recv and send methods). + + Some double underscore prefixes are used to minimize pollution of + :class:`zmq.Socket`'s namespace. + """ + __in_send_multipart = False + __in_recv_multipart = False + __writable = None + __readable = None + _state_event = None + _gevent_bug_timeout = 11.6 # timeout for not trusting gevent + _debug_gevent = False # turn on if you think gevent is missing events + _poller_class = _Poller + + def __init__(self, *a, **kw): + super(_Socket, self).__init__(*a, **kw) + self.__in_send_multipart = False + self.__in_recv_multipart = False + self.__setup_events() + + + def __del__(self): + self.close() + + def close(self, linger=None): + super(_Socket, self).close(linger) + self.__cleanup_events() + + def __cleanup_events(self): + # close the _state_event event, keeps the number of active file descriptors down + if getattr(self, '_state_event', None): + _stop(self._state_event) + self._state_event = None + # if the socket has entered a close state resume any waiting greenlets + self.__writable.set() + self.__readable.set() + + def __setup_events(self): + self.__readable = AsyncResult() + self.__writable = AsyncResult() + self.__readable.set() + self.__writable.set() + + try: + self._state_event = get_hub().loop.io(self.getsockopt(zmq.FD), 1) # read state watcher + self._state_event.start(self.__state_changed) + except AttributeError: + # for gevent<1.0 compatibility + from gevent.core import read_event + self._state_event = read_event(self.getsockopt(zmq.FD), self.__state_changed, persist=True) + + def __state_changed(self, event=None, _evtype=None): + if self.closed: + self.__cleanup_events() + return + try: + # avoid triggering __state_changed from inside __state_changed + events = super(_Socket, self).getsockopt(zmq.EVENTS) + except zmq.ZMQError as exc: + self.__writable.set_exception(exc) + self.__readable.set_exception(exc) + else: + if events & zmq.POLLOUT: + self.__writable.set() + if events & zmq.POLLIN: + self.__readable.set() + + def _wait_write(self): + assert self.__writable.ready(), "Only one greenlet can be waiting on this event" + self.__writable = AsyncResult() + # timeout is because libzmq cannot be trusted to properly signal a new send event: + # this is effectively a maximum poll interval of 1s + tic = time.time() + dt = self._gevent_bug_timeout + if dt: + timeout = gevent.Timeout(seconds=dt) + else: + timeout = None + try: + if timeout: + timeout.start() + self.__writable.get(block=True) + except gevent.Timeout as t: + if t is not timeout: + raise + toc = time.time() + # gevent bug: get can raise timeout even on clean return + # don't display zmq bug warning for gevent bug (this is getting ridiculous) + if self._debug_gevent and timeout and toc-tic > dt and \ + self.getsockopt(zmq.EVENTS) & zmq.POLLOUT: + print("BUG: gevent may have missed a libzmq send event on %i!" % self.FD, file=sys.stderr) + finally: + if timeout: + timeout.cancel() + self.__writable.set() + + def _wait_read(self): + assert self.__readable.ready(), "Only one greenlet can be waiting on this event" + self.__readable = AsyncResult() + # timeout is because libzmq cannot always be trusted to play nice with libevent. + # I can only confirm that this actually happens for send, but lets be symmetrical + # with our dirty hacks. + # this is effectively a maximum poll interval of 1s + tic = time.time() + dt = self._gevent_bug_timeout + if dt: + timeout = gevent.Timeout(seconds=dt) + else: + timeout = None + try: + if timeout: + timeout.start() + self.__readable.get(block=True) + except gevent.Timeout as t: + if t is not timeout: + raise + toc = time.time() + # gevent bug: get can raise timeout even on clean return + # don't display zmq bug warning for gevent bug (this is getting ridiculous) + if self._debug_gevent and timeout and toc-tic > dt and \ + self.getsockopt(zmq.EVENTS) & zmq.POLLIN: + print("BUG: gevent may have missed a libzmq recv event on %i!" % self.FD, file=sys.stderr) + finally: + if timeout: + timeout.cancel() + self.__readable.set() + + def send(self, data, flags=0, copy=True, track=False, **kwargs): + """send, which will only block current greenlet + + state_changed always fires exactly once (success or fail) at the + end of this method. + """ + + # if we're given the NOBLOCK flag act as normal and let the EAGAIN get raised + if flags & zmq.NOBLOCK: + try: + msg = super(_Socket, self).send(data, flags, copy, track, **kwargs) + finally: + if not self.__in_send_multipart: + self.__state_changed() + return msg + # ensure the zmq.NOBLOCK flag is part of flags + flags |= zmq.NOBLOCK + while True: # Attempt to complete this operation indefinitely, blocking the current greenlet + try: + # attempt the actual call + msg = super(_Socket, self).send(data, flags, copy, track) + except zmq.ZMQError as e: + # if the raised ZMQError is not EAGAIN, reraise + if e.errno != zmq.EAGAIN: + if not self.__in_send_multipart: + self.__state_changed() + raise + else: + if not self.__in_send_multipart: + self.__state_changed() + return msg + # defer to the event loop until we're notified the socket is writable + self._wait_write() + + def recv(self, flags=0, copy=True, track=False): + """recv, which will only block current greenlet + + state_changed always fires exactly once (success or fail) at the + end of this method. + """ + if flags & zmq.NOBLOCK: + try: + msg = super(_Socket, self).recv(flags, copy, track) + finally: + if not self.__in_recv_multipart: + self.__state_changed() + return msg + + flags |= zmq.NOBLOCK + while True: + try: + msg = super(_Socket, self).recv(flags, copy, track) + except zmq.ZMQError as e: + if e.errno != zmq.EAGAIN: + if not self.__in_recv_multipart: + self.__state_changed() + raise + else: + if not self.__in_recv_multipart: + self.__state_changed() + return msg + self._wait_read() + + def send_multipart(self, *args, **kwargs): + """wrap send_multipart to prevent state_changed on each partial send""" + self.__in_send_multipart = True + try: + msg = super(_Socket, self).send_multipart(*args, **kwargs) + finally: + self.__in_send_multipart = False + self.__state_changed() + return msg + + def recv_multipart(self, *args, **kwargs): + """wrap recv_multipart to prevent state_changed on each partial recv""" + self.__in_recv_multipart = True + try: + msg = super(_Socket, self).recv_multipart(*args, **kwargs) + finally: + self.__in_recv_multipart = False + self.__state_changed() + return msg + + def get(self, opt): + """trigger state_changed on getsockopt(EVENTS)""" + if opt in TIMEOS: + warnings.warn("TIMEO socket options have no effect in zmq.green", UserWarning) + optval = super(_Socket, self).get(opt) + if opt == zmq.EVENTS: + self.__state_changed() + return optval + + def set(self, opt, val): + """set socket option""" + if opt in TIMEOS: + warnings.warn("TIMEO socket options have no effect in zmq.green", UserWarning) + return super(_Socket, self).set(opt, val) + + +class _Context(_original_Context): + """Replacement for :class:`zmq.Context` + + Ensures that the greened Socket above is used in calls to `socket`. + """ + _socket_class = _Socket + + # avoid sharing instance with base Context class + _instance = None diff --git a/.venv/lib/python3.8/site-packages/zmq/green/device.py b/.venv/lib/python3.8/site-packages/zmq/green/device.py new file mode 100644 index 00000000..4b070237 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/zmq/green/device.py @@ -0,0 +1,32 @@ +# Copyright (C) PyZMQ Developers +# Distributed under the terms of the Modified BSD License. + +import zmq +from zmq.green import Poller + +def device(device_type, isocket, osocket): + """Start a zeromq device (gevent-compatible). + + Unlike the true zmq.device, this does not release the GIL. + + Parameters + ---------- + device_type : (QUEUE, FORWARDER, STREAMER) + The type of device to start (ignored). + isocket : Socket + The Socket instance for the incoming traffic. + osocket : Socket + The Socket instance for the outbound traffic. + """ + p = Poller() + if osocket == -1: + osocket = isocket + p.register(isocket, zmq.POLLIN) + p.register(osocket, zmq.POLLIN) + + while True: + events = dict(p.poll()) + if isocket in events: + osocket.send_multipart(isocket.recv_multipart()) + if osocket in events: + isocket.send_multipart(osocket.recv_multipart()) diff --git a/.venv/lib/python3.8/site-packages/zmq/green/eventloop/__init__.py b/.venv/lib/python3.8/site-packages/zmq/green/eventloop/__init__.py new file mode 100644 index 00000000..c5150efe --- /dev/null +++ b/.venv/lib/python3.8/site-packages/zmq/green/eventloop/__init__.py @@ -0,0 +1,3 @@ +from zmq.green.eventloop.ioloop import IOLoop + +__all__ = ['IOLoop'] \ No newline at end of file diff --git a/.venv/lib/python3.8/site-packages/zmq/green/eventloop/__pycache__/__init__.cpython-38.pyc b/.venv/lib/python3.8/site-packages/zmq/green/eventloop/__pycache__/__init__.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..94f7987d0fb388e64744d1440fe1404fac349dc7 GIT binary patch literal 234 zcmWIL<>g`k0@j9W@yAPTJJ7JGbr zVopwc{7Qx*7N8z5@ykKKB)34nAhSTXG_N2rIXg8)w>%>?HAlC?w4$QY)Y4QRXskZi nSbey$`tk9Zd6^~g@p=W7w>WHa^HWN5QtcRlh8BZd!@~pstu;G5 literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/zmq/green/eventloop/__pycache__/ioloop.cpython-38.pyc b/.venv/lib/python3.8/site-packages/zmq/green/eventloop/__pycache__/ioloop.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..52d18b6768b40e7dd28c4d69926e342d547819d4 GIT binary patch literal 190 zcmWIL<>g`k0@j9W@ybB@F^Gc(44TX@fg%i=jJFuI z{4^P(M5=NN^-{}H^Gb5^^9%Gc^Fh=~h9YL5A~5mGPQN6#K))cfK({onATc>RHAS~P zBQ-Tgx5BidqSDmTR3B)BetJ=AYMwsaAbp5IdIgoYIBatBQ%ZAE?HGYZeg;_%0Fj6= AYybcN literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/zmq/green/eventloop/__pycache__/zmqstream.cpython-38.pyc b/.venv/lib/python3.8/site-packages/zmq/green/eventloop/__pycache__/zmqstream.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..107f3c4fec62764773ca1218b3367a741a18182e GIT binary patch literal 674 zcmYk4J&)8d5QfK&vzJ{q6f{T_R5Xj&O~V#Q2p!ewBv=FojTqQ^qtA8RS|`IJE1i>(d-_eY9fQ5MN&aYwg(Qr51|>%#chty|M|cQK}Km>(-u*xWg#Zs70ptgqUvE!+9JZgc!h&%b;y#?Cj(&E|ahWSL!5 zXW9GCm^w3`P2Cd!ow?B4qCM{tv>oGc;eptcUECRZUkos8g^z-4bzT{z{6wj$(Q8ZV zsZwX_-0m{L&Zqww3uCQPU5fTQxkannBvkDHhvO&-4|}X3?;_k{KwS)|@*X8ZCwu9# kp@zbH1_znGF}WT1_bLYls_c`eJM?Gx7lIpw@>4GOKjV6#R{#J2 literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/zmq/green/eventloop/ioloop.py b/.venv/lib/python3.8/site-packages/zmq/green/eventloop/ioloop.py new file mode 100644 index 00000000..e09f4e23 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/zmq/green/eventloop/ioloop.py @@ -0,0 +1 @@ +from zmq.eventloop.ioloop import * diff --git a/.venv/lib/python3.8/site-packages/zmq/green/eventloop/zmqstream.py b/.venv/lib/python3.8/site-packages/zmq/green/eventloop/zmqstream.py new file mode 100644 index 00000000..90fbd1f5 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/zmq/green/eventloop/zmqstream.py @@ -0,0 +1,11 @@ +from zmq.eventloop.zmqstream import * + +from zmq.green.eventloop.ioloop import IOLoop + +RealZMQStream = ZMQStream + +class ZMQStream(RealZMQStream): + + def __init__(self, socket, io_loop=None): + io_loop = io_loop or IOLoop.instance() + super(ZMQStream, self).__init__(socket, io_loop=io_loop) diff --git a/.venv/lib/python3.8/site-packages/zmq/green/poll.py b/.venv/lib/python3.8/site-packages/zmq/green/poll.py new file mode 100644 index 00000000..8c9c32d6 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/zmq/green/poll.py @@ -0,0 +1,97 @@ +import zmq +import gevent +from gevent import select + +from zmq import Poller as _original_Poller + + +class _Poller(_original_Poller): + """Replacement for :class:`zmq.Poller` + + Ensures that the greened Poller below is used in calls to + :meth:`zmq.Poller.poll`. + """ + _gevent_bug_timeout = 1.33 # minimum poll interval, for working around gevent bug + + def _get_descriptors(self): + """Returns three elements tuple with socket descriptors ready + for gevent.select.select + """ + rlist = [] + wlist = [] + xlist = [] + + for socket, flags in self.sockets: + if isinstance(socket, zmq.Socket): + rlist.append(socket.getsockopt(zmq.FD)) + continue + elif isinstance(socket, int): + fd = socket + elif hasattr(socket, 'fileno'): + try: + fd = int(socket.fileno()) + except: + raise ValueError('fileno() must return an valid integer fd') + else: + raise TypeError('Socket must be a 0MQ socket, an integer fd ' + 'or have a fileno() method: %r' % socket) + + if flags & zmq.POLLIN: + rlist.append(fd) + if flags & zmq.POLLOUT: + wlist.append(fd) + if flags & zmq.POLLERR: + xlist.append(fd) + + return (rlist, wlist, xlist) + + def poll(self, timeout=-1): + """Overridden method to ensure that the green version of + Poller is used. + + Behaves the same as :meth:`zmq.core.Poller.poll` + """ + + if timeout is None: + timeout = -1 + + if timeout < 0: + timeout = -1 + + rlist = None + wlist = None + xlist = None + + if timeout > 0: + tout = gevent.Timeout.start_new(timeout/1000.0) + else: + tout = None + + try: + # Loop until timeout or events available + rlist, wlist, xlist = self._get_descriptors() + while True: + events = super(_Poller, self).poll(0) + if events or timeout == 0: + return events + + # wait for activity on sockets in a green way + # set a minimum poll frequency, + # because gevent < 1.0 cannot be trusted to catch edge-triggered FD events + _bug_timeout = gevent.Timeout.start_new(self._gevent_bug_timeout) + try: + select.select(rlist, wlist, xlist) + except gevent.Timeout as t: + if t is not _bug_timeout: + raise + finally: + _bug_timeout.cancel() + + except gevent.Timeout as t: + if t is not tout: + raise + return [] + finally: + if timeout > 0: + tout.cancel() + diff --git a/.venv/lib/python3.8/site-packages/zmq/log/__init__.py b/.venv/lib/python3.8/site-packages/zmq/log/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/.venv/lib/python3.8/site-packages/zmq/log/__main__.py b/.venv/lib/python3.8/site-packages/zmq/log/__main__.py new file mode 100644 index 00000000..a919a032 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/zmq/log/__main__.py @@ -0,0 +1,108 @@ +"""pyzmq log watcher. + +Easily view log messages published by the PUBHandler in zmq.log.handlers + +Designed to be run as an executable module - try this to see options: + python -m zmq.log -h + +Subscribes to the '' (empty string) topic by default which means it will work +out-of-the-box with a PUBHandler object instantiated with default settings. +If you change the root topic with PUBHandler.setRootTopic() you must pass +the value to this script with the --topic argument. + +Note that the default formats for the PUBHandler object selectively include +the log level in the message. This creates redundancy in this script as it +always prints the topic of the message, which includes the log level. +Consider overriding the default formats with PUBHandler.setFormat() to +avoid this issue. + +""" + + +# encoding: utf-8 + +# Copyright (C) PyZMQ Developers +# Distributed under the terms of the Modified BSD License. + +import argparse +from datetime import datetime + +import zmq +from zmq.utils.strtypes import u, cast_bytes + +parser = argparse.ArgumentParser('ZMQ Log Watcher') +parser.add_argument('zmq_pub_url',type=str, + help='URL to a ZMQ publisher socket.') +parser.add_argument('-t', '--topic', type=str, default='', + help='Only receive messages that start with this topic.') +parser.add_argument('--timestamp', action='store_true', + help='Append local time to the log messages.') +parser.add_argument('--separator', type=str, default=' | ', + help='String to print between topic and message.') +parser.add_argument('--dateformat', type=str, default='%Y-%d-%m %H:%M', + help='Set alternative date format for use with --timestamp.') +parser.add_argument('--align', action='store_true', default=False, + help='Try to align messages by the width of their topics.') +parser.add_argument('--color', action='store_true', default=False, + help='Color the output based on the error level. Requires the colorama module.') +args = parser.parse_args() + + + +if args.color: + import colorama + colorama.init() + colors = { + 'DEBUG' : colorama.Fore.LIGHTCYAN_EX, + 'INFO' : colorama.Fore.LIGHTWHITE_EX, + 'WARNING' : colorama.Fore.YELLOW, + 'ERROR' : colorama.Fore.LIGHTRED_EX, + 'CRITICAL' : colorama.Fore.LIGHTRED_EX, + '__RESET__': colorama.Fore.RESET, + } +else: + colors = { } + + +ctx = zmq.Context() +sub = ctx.socket(zmq.SUB) +sub.subscribe(cast_bytes(args.topic)) +sub.connect(args.zmq_pub_url) + +topic_widths = {} + +while(1): + try: + if sub.poll(10, zmq.POLLIN): + topic, msg = sub.recv_multipart() + topics = topic.decode('utf8').strip().split('.') + + if args.align: + topics.extend(' ' for extra in range(len(topics), len(topic_widths))) + aligned_parts = [] + for key, part in enumerate(topics): + topic_widths[key] = max(len(part), topic_widths.get(key,0)) + fmt = ''.join(('{:<',str(topic_widths[key]),'}')) + aligned_parts.append(fmt.format(part)) + + if len(topics)==1: + level = topics[0] + else: + level = topics[1] + + fields = { + 'msg' : msg.decode('utf8').strip(), + 'ts' : datetime.now().strftime(args.dateformat)+' ' if args.timestamp else '', + 'aligned' : '.'.join(aligned_parts) if args.align else topic.decode('utf8').strip(), + 'color' : colors.get(level,''), + 'color_rst' : colors.get('__RESET__',''), + 'sep' : args.separator, + } + print('{ts}{color}{aligned}{sep}{msg}{color_rst}'.format(**fields)) + except KeyboardInterrupt: + break + +sub.disconnect(args.zmq_pub_url) +if args.color: + print(colorama.Fore.RESET) + diff --git a/.venv/lib/python3.8/site-packages/zmq/log/__pycache__/__init__.cpython-38.pyc b/.venv/lib/python3.8/site-packages/zmq/log/__pycache__/__init__.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9bc3aaf474aaacc42819bf8c763f4b197ea92f2c GIT binary patch literal 143 zcmWIL<>g`k0@j9W@gVv!h(HF6K#l_t7qb9~6oz01O-8?!3`HPe1o6v6za+OnzaX;<%t$+Z|A%|?>ACLnH1OWo%r{s`R4t>qZ*BpIGzHX9|kc0%QyQ{0Jzj|~vUyP4? z7Cyz_{G%Qnv8;dU#o=efQMULh*9ihi+G z@=LZwc6Wpqd$wPu^5!Tnk;g}P`6m}UdOgZLaK?CrkN;F0@Fw^Xev}{EmpKlJkN62l z6b2F}!8yfGAL5*W&RKqrpWm0cU^o|tobFi9@+(x?9DiqLj`3i^pP-5Ek)8#s6Prgj zj~RO0(2oo~afqJem;PAtPsN4M@=uZ5Jq>$j=uG!4xtr(U-+4OUy+9?LaPh6(vtjdm z_Yzi@^&C3vo!wai?+U*RjjKK9os<0z>yLZZuO0uQe~m77Cpqic-RnK8dxKwr%_-ydmYX`W2_e)64lGFVPUd&?s^PbIboVH?zj~Q>AY>8j#-ll5Ljw^?K zrc*%q1t04Btg?BJPb2PM(|vw(^Yb-}zW#M=}E#TN<|{o=KU^Zsljhqm>~ zdgr|P>noh~y#?g6i0(Hy(_{eSI3)i@_f1YuY8%{Hv8F!>j=7eVwmYpiEK1hdb|9M@ zl+`?MJ`iElW?La`o1GR35v-G7Y2JuJu|b?Q+DvW`d;a3V(;(&%Wh{&tEY)DCw$Wz^ z&wE57T#q3y6V@P>71pR_GE zl9*Ln!&6vw!}C`1hG=GC1K6OX5#6}Krl^(5HWM-nv@Y}i6ky1QXd=ONC*r8t|eJ3kb+?}`~wVZ;GCccK89O_3JBw7 zlyfowbcsX+w$8LRIjD*nTh)k~86g~kWyJHC2XRwtL+$`95+6!0h_-_^Dhas(3~i^6 zJXt$z^wU9-1_1hk`v?%-hbWAYqwJC`%Ce9n=tlp){ro?Her!U3D9gkPwvrIVsZoYP zy0*?>>TmG{f;dnATRrOMvbBL>$n~DJc~M) zUMw%_Oa)Af4ew0GMACdsvIcVn*-l9nHYiFvPE~eB2KiG~=d))q0-sTnkb+^1wf{&Y zsxI44Iv|_K)u!F71juS+;CnWLRc8z)fgLKXRCz)s8P#Q$Q|J0zno`Vhv714}w2a28 z6QScfyy_ZdDL@@0@xDDlX^;i5)N$F5taEe4TrjO|vWW{Ww~3H+bK%efhSqAGO0}w^ z*{{CN#N?~$B(F}k*yPjM$!|M%S4grTl9a`Pt~{n?b%~->O{M07`n7(@shW;j5TU(1 z?%ZD0tpgF)%i*bF*rc{Yj%(5{un=Xh;RzkKF$5|b)x?Ah_L@lq_ntn~gNX@RLYhm~ z2n4P=`j3ti3J$yGF4WjEy~)E&_aE#S^`I3DdRlF|q>7K`AG~;?3JXh*pQ(|TbIVH$ zOHWjBetG%XvMN7ZURYgtIJc-q>-FXNmHE|r{k{HAq6)cO`%>Aprj6C`gMT5G{x$Iv z$3cFye(?5eZv6^xz#F{n=<3b~n=SnXqjGAuRFQUM7G$R&YsiN?GqRP=q+wdk<1|1$ z^6K^mQB>WzyR*~2`_EG zyR-L{z4u-t%}#1^3PO^VH`?TKr?n7g5TDH?jFr3AlISL;@2FD$UaO+HKx*`$OSy5ft;#^Org^@1 z&@m8zVef%{ND&vRXqt{X_DgCvk|5&?h+vlGsf1!EhT++-{Qey{Ym#`c|Ci&wu2}JV zkixmLU2)3xQOC2(w)5|jQ!%tZ_ssl%X}M5_blEA{``-`c(Si$G_EFd?xCK4hCt&%i ht>@?LGgwX7o>O)!_9c8hde*pY%=lK8t literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/zmq/log/__pycache__/handlers.cpython-38.pyc b/.venv/lib/python3.8/site-packages/zmq/log/__pycache__/handlers.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..77d8d19047a769b61b5fbf25d32d6a95b0d11cd1 GIT binary patch literal 6003 zcmbVQOK%*<5uVq+hD%bWUXJY~4IwhQ0kxDIDUKOg5lvCH0GVX{X}n-vg1ItR$bha3V5$VK;@^8@k&a+qsQKIanT;(XOT`=Xr$$dJ?9(_LL%U0wB6 zb$`0JXlr;%zx`Y5=6Ox~JAKSPWqjPkoBjcXuQ{5p`$nicI)2Sij||6%Ovj8Y$BIf$ zDJnZ;a*I#JQOY)m(4E*8YzpOJfQHS>C#8yi>NdAE5Pe^)lIyz`T* z*H#-RM>R!~WUVae1s)izc9LXuLPD$L0?oy8n_ZsWm2GQ8*mlJXKSkV3LBgN%aBV#1 z*3Ji?emI@BAai}c(C}Ize#5r6IvJ+RXj6Jg5NA+97_y0u-|b}}=!hg@4>DJ5hy4^Y78>5qGSXNV+tP10y(HQ=$V3qG z!Nv^jMmtQ}8<9)nHd65L6pxK!UA=+*HC#g5ZIp8B&hG7dc}XfDw;pcY-_1)q_wV1k zpOoANwpzVEj;W$Mwj)1cT>H8mPA&NGkXk@!L6aqh83z-a<{}gRosM z0h^<&sa$fc@K9xtW3nbOTU!m{o=7~{09H|0Hc@=1e-S&FEcM?Lv(tVj^(<=-tmU}9 zeV)Q91!w$8KX~efJSNB>mUm~>s5nZ)m%cHcfkw7P;`(GX3QnAle+k{dms82+(IXl# zLg*99Kt8yR0MpqeIdE89KI$^cb&|5oo8ONF+aeK2kUTvW}$Xcy@p*0N(f*>ca-A+X0X7EP=9MA-5UzDh)x_$r7 z-kt5OySa@Rsc6#N4$>e7JjNc+O}Ly>ejp=aURG|HR|>bxO)opjE8EIR9TPy2TjY%m zE4NY}cAV1_uWu!yrG|@hG_^gI@|7muLesylZe&q!qZjlp_2Zt480=p<+~+*Jbad_L zXmIVlYa0-T+W?hC^WsUmkmp^bmJQXzg2x&AGgWhf0k`f>UCpD zKcx>(PqDH&R-~sBzv7`fz0zPQe}cilEMDomuXM4D?}jekz>i#rD!xyjZ=%@4o08%+ zV|aFEqNxHr*-I37s7~7^r=rD;v}0{*iQ)%nYUp_#vHCuu{~iHG!;rJ*CE!q>f0q!S zVN@Z+w`QXm4$y2b(u!+<3qNg&}D-{es& z=}eeXAFSUM17IMQo+2c;l5x_(K$1sE4Td~U`-lJ}w%{HQo+6e2k;m!Mgr`h*{)4XX zbmVyCqf)FwQFHRM>8`C$n2*ygAczb+lga+a0%ju2cqMBxyf8|S)|rel%?Y>NBqPC~ zItpwLCP_rfD3RWGvE&FF8zAz}Z3A+9+IM<(#Sh8am32#JI%(Ss{a@f!w!Jt!KjUDt z9^#QpjUNI)dZp1{MP+1A0D5eQx8c{uu_+HJOV3Plh67_{Ue}(SiS6RcxL&x&@ULUv zm;mg5a}8`)oTvb;d?R@pz%|z8=A{TKG#D66o$`!ZDESTNBmD)R_)0ha!NU z$+>{IIPH)rO~D+EU?>Cm_%sCYh8_03EDk`%_Nq27|!6B{CNX`+tD7?)O2Xk}Yp(wB^r`!k{Z7AVnv$^9Wg2yI9Df&M)W zNdkg0z)2sTQiGXG9+U{b*)WyV6&0qFysY#vM#r+EJ0Y=H!vu$T#~A(Ej0q_QbHWk& z(~_ice?evVIz-cs^$fZEOXCaU8ANPp54HGpOUum1wz#Y#b|8;H&*xffe5MUoG7G3) zqNP07pP8U#1+A}W(OXuS|GDOy546v;uJ#OL4k}_avW}}%lerSr^@EzM8{#Y3hb#%R zS;w|t^2;x@k#!5FhnM;@WJL!H$MsQZWOfw|I5#Rowu9^+YNY&eoag}!BcQB034cwY zPb{F={RdT>bFpz8uu}A-6x&DImrKu(w2iR1Ut!@-3`(Jjz$I#+Xc)QCyqxRViM_~c z*SkFCM?G=l_ry&(s-X=p%#`2F2O|6qF${h$E3ekYwU*D#$~`�h0ZKjYp4rL7&@yfkN!gbCv?X!k% zn-JZsE-%%qmLM7r@7zO%a}#g+I*R%8uy5idYxx%JvxKdr9OtgQyKor{aEqn5O+nZ= z6trV>>j2oy)TuO{J=VCQ+m8^2DTXWa&h`_ZZjUIuYymVW=8f-gA})IwKf>0nvv!}L z6PE=p?j<_7nn1uxyEyYHo&fH{MDiK8q??!rq9W8vI$UhHDQ=63>Gnvt?7!@O- z7i?Q@V)|DF43Gzicd6Jwkz1s%y!`l(eouPL7AXFNS4EuKaCyeSo8XE2C-EM!+N9#= zR9vTm#?A1O&L~}w&Ocw_m4FEsTolwYT$RUk1{sj(p`eTzE{?PUX>t|-Kv~Dl-0)lW zLWe_XFEj;!oK6Ksrk}^z{QQiqj6vPVEpi=k1=QjLDyBF=^5xa*p&PY*_r{;`rBSs*LTzRtc MW}S|kdik4w1AQGt6#xJL literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/zmq/log/handlers.py b/.venv/lib/python3.8/site-packages/zmq/log/handlers.py new file mode 100644 index 00000000..af4ff299 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/zmq/log/handlers.py @@ -0,0 +1,182 @@ +"""pyzmq logging handlers. + +This mainly defines the PUBHandler object for publishing logging messages over +a zmq.PUB socket. + +The PUBHandler can be used with the regular logging module, as in:: + + >>> import logging + >>> handler = PUBHandler('tcp://127.0.0.1:12345') + >>> handler.root_topic = 'foo' + >>> logger = logging.getLogger('foobar') + >>> logger.setLevel(logging.DEBUG) + >>> logger.addHandler(handler) + +After this point, all messages logged by ``logger`` will be published on the +PUB socket. + +Code adapted from StarCluster: + + http://github.com/jtriley/StarCluster/blob/master/starcluster/logger.py +""" + +# Copyright (C) PyZMQ Developers +# Distributed under the terms of the Modified BSD License. + + +import logging +from logging import INFO, DEBUG, WARN, ERROR, FATAL + +import zmq +from zmq.utils.strtypes import bytes, unicode, cast_bytes + + +TOPIC_DELIM="::" # delimiter for splitting topics on the receiving end. + + +class PUBHandler(logging.Handler): + """A basic logging handler that emits log messages through a PUB socket. + + Takes a PUB socket already bound to interfaces or an interface to bind to. + + Example:: + + sock = context.socket(zmq.PUB) + sock.bind('inproc://log') + handler = PUBHandler(sock) + + Or:: + + handler = PUBHandler('inproc://loc') + + These are equivalent. + + Log messages handled by this handler are broadcast with ZMQ topics + ``this.root_topic`` comes first, followed by the log level + (DEBUG,INFO,etc.), followed by any additional subtopics specified in the + message by: log.debug("subtopic.subsub::the real message") + """ + + socket = None + + + def __init__(self, interface_or_socket, context=None, root_topic=''): + logging.Handler.__init__(self) + self._root_topic = root_topic + self.formatters = { + logging.DEBUG: logging.Formatter( + "%(levelname)s %(filename)s:%(lineno)d - %(message)s\n"), + logging.INFO: logging.Formatter("%(message)s\n"), + logging.WARN: logging.Formatter( + "%(levelname)s %(filename)s:%(lineno)d - %(message)s\n"), + logging.ERROR: logging.Formatter( + "%(levelname)s %(filename)s:%(lineno)d - %(message)s - %(exc_info)s\n"), + logging.CRITICAL: logging.Formatter( + "%(levelname)s %(filename)s:%(lineno)d - %(message)s\n")} + if isinstance(interface_or_socket, zmq.Socket): + self.socket = interface_or_socket + self.ctx = self.socket.context + else: + self.ctx = context or zmq.Context() + self.socket = self.ctx.socket(zmq.PUB) + self.socket.bind(interface_or_socket) + + @property + def root_topic(self): + return self._root_topic + + @root_topic.setter + def root_topic(self, value): + self.setRootTopic(value) + + def setRootTopic(self, root_topic): + """Set the root topic for this handler. + + This value is prepended to all messages published by this handler, and it + defaults to the empty string ''. When you subscribe to this socket, you must + set your subscription to an empty string, or to at least the first letter of + the binary representation of this string to ensure you receive any messages + from this handler. + + If you use the default empty string root topic, messages will begin with + the binary representation of the log level string (INFO, WARN, etc.). + Note that ZMQ SUB sockets can have multiple subscriptions. + """ + self._root_topic = root_topic + + def setFormatter(self, fmt, level=logging.NOTSET): + """Set the Formatter for this handler. + + If no level is provided, the same format is used for all levels. This + will overwrite all selective formatters set in the object constructor. + """ + if level==logging.NOTSET: + for fmt_level in self.formatters.keys(): + self.formatters[fmt_level] = fmt + else: + self.formatters[level] = fmt + + def format(self,record): + """Format a record.""" + return self.formatters[record.levelno].format(record) + + def emit(self, record): + """Emit a log message on my socket.""" + try: + topic, record.msg = record.msg.split(TOPIC_DELIM,1) + except Exception: + topic = "" + try: + bmsg = cast_bytes(self.format(record)) + except Exception: + self.handleError(record) + return + + topic_list = [] + + if self.root_topic: + topic_list.append(self.root_topic) + + topic_list.append(record.levelname) + + if topic: + topic_list.append(topic) + + btopic = b'.'.join(cast_bytes(t) for t in topic_list) + + self.socket.send_multipart([btopic, bmsg]) + + +class TopicLogger(logging.Logger): + """A simple wrapper that takes an additional argument to log methods. + + All the regular methods exist, but instead of one msg argument, two + arguments: topic, msg are passed. + + That is:: + + logger.debug('msg') + + Would become:: + + logger.debug('topic.sub', 'msg') + """ + def log(self, level, topic, msg, *args, **kwargs): + """Log 'msg % args' with level and topic. + + To pass exception information, use the keyword argument exc_info + with a True value:: + + logger.log(level, "zmq.fun", "We have a %s", + "mysterious problem", exc_info=1) + """ + logging.Logger.log(self, level, '%s::%s'%(topic,msg), *args, **kwargs) + +# Generate the methods of TopicLogger, since they are just adding a +# topic prefix to a message. +for name in "debug warn warning error critical fatal".split(): + meth = getattr(logging.Logger,name) + setattr(TopicLogger, name, + lambda self, level, topic, msg, *args, **kwargs: + meth(self, level, topic+TOPIC_DELIM+msg,*args, **kwargs)) + diff --git a/.venv/lib/python3.8/site-packages/zmq/ssh/__init__.py b/.venv/lib/python3.8/site-packages/zmq/ssh/__init__.py new file mode 100644 index 00000000..57f09568 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/zmq/ssh/__init__.py @@ -0,0 +1 @@ +from zmq.ssh.tunnel import * diff --git a/.venv/lib/python3.8/site-packages/zmq/ssh/__pycache__/__init__.cpython-38.pyc b/.venv/lib/python3.8/site-packages/zmq/ssh/__pycache__/__init__.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8b1c74d8ddada0c9fec2674dfa580e7173255b71 GIT binary patch literal 174 zcmWIL<>g`k0@j9W@v=brF^Gc(44TX@fg%i=jJFuI z{4^P(_^NUX^@@u#^h!$e@=|kFG88cbrNP866aA9h0{w!_0^QQQg2d$P)D+$FjMUT| w-3rr+ib_*UQ+=RjeV}Ij`1s7c%#!$cy@JYH95%W6DWy57c8oxSK7%X+09pzuoB#j- literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/zmq/ssh/__pycache__/forward.cpython-38.pyc b/.venv/lib/python3.8/site-packages/zmq/ssh/__pycache__/forward.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..70ba39d313df8158e41378c271de131009b1f3f0 GIT binary patch literal 2325 zcmZ`)&2JPp6t_JeJ3G5sP^b_>RW(pTS&3{)D^!6HLIny)D5|=tD5FZF$=LfrW@je$ zED5XKs#1`UIC0<)NP6SezorLEJ@wRE&m2nM^Xw*}v>w^>Y(GE0Xa9cB-!Cos1d8+X zZ_)2dg#3Y>)d}%!WQ@Y zG(5qrE@?O7vy>3O8;^=q1S*lkq72j^-x+580DeK42RskbJc-kw$YmMya=8;rj`R6b zA%h~8@o2b}cYJ?iFjNa0NuFgQDHR$h2O^MSdn{Bbc+lA3gTmnU=x{-`vVv($FOxOxIgy+7N8e#z`=oG7NZ65 zCr$?OCIoFv;Woz{8^Po-6CM9gxGvJBx>d+wRz|&Xmf-SrZGl4xP986Cl+`VN1cD$T zg_~xa;?0IOXK>z@Uizjwz^*xhjrF#py(r4!k%%JgN6{$f;}qp)6m5^=bUxGKu^8o9 z1YwGpD}5?X(|jkAVyr|Ib1sEaZ-_(`n&$17Yvrg|D~84DI4k00OYqg5fe`8H?$zDh zXIHOXU7L)y*C2|u`EhrOXVQk{pFve9c+{q5-YOLkYB7Efcu; z$%O}5l8=z8bNV3&Ynz9NPv=`dAy{1A_sp*cUyV~Y)86UArHXs)5f)+r$gJ8Y`4WW#B)TiFx zo^=xbHg!Qd17j}r-?_|YE$R~gooAhe*(Q88YC~;-)H2efHRnyIGQQrnr30p=iw*Ke zp2Oyl=#_;2$R;$Gp(^C3$4oy#CNBya!oCGnq1*S!3-W@#U_E?$*mIy&N%jEFCA>&e z0#vm3*giwh8GzaAAEbf>yVV&mw@7)fAq~8Sl=qs24yS-jHaR!XGEtSCJ2%XeqHcD& z<4ufM$o01S??_u(BNL4!iCEl=CuGr8@Io$bgJl#`%>CxpZLi5Z051bTw`hy`Y}r}9;5GgMT>e_K literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/zmq/ssh/__pycache__/tunnel.cpython-38.pyc b/.venv/lib/python3.8/site-packages/zmq/ssh/__pycache__/tunnel.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7175c133f5d658b411d7043a098431d9d07a7b0a GIT binary patch literal 10776 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 VDV-?Q3TB~PdZTo@OdsHw{{t$tf>i(j literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/zmq/ssh/forward.py b/.venv/lib/python3.8/site-packages/zmq/ssh/forward.py new file mode 100644 index 00000000..2d619462 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/zmq/ssh/forward.py @@ -0,0 +1,91 @@ +# +# This file is adapted from a paramiko demo, and thus licensed under LGPL 2.1. +# Original Copyright (C) 2003-2007 Robey Pointer +# Edits Copyright (C) 2010 The IPython Team +# +# Paramiko 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. +# +# Paramiko is distrubuted 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 Paramiko; if not, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA. + +""" +Sample script showing how to do local port forwarding over paramiko. + +This script connects to the requested SSH server and sets up local port +forwarding (the openssh -L option) from a local port through a tunneled +connection to a destination reachable from the SSH server machine. +""" + +from __future__ import print_function + +import logging +import select +try: # Python 3 + import socketserver +except ImportError: # Python 2 + import SocketServer as socketserver + +logger = logging.getLogger('ssh') + +class ForwardServer (socketserver.ThreadingTCPServer): + daemon_threads = True + allow_reuse_address = True + + +class Handler (socketserver.BaseRequestHandler): + + def handle(self): + try: + chan = self.ssh_transport.open_channel('direct-tcpip', + (self.chain_host, self.chain_port), + self.request.getpeername()) + except Exception as e: + logger.debug('Incoming request to %s:%d failed: %s' % (self.chain_host, + self.chain_port, + repr(e))) + return + if chan is None: + logger.debug('Incoming request to %s:%d was rejected by the SSH server.' % + (self.chain_host, self.chain_port)) + return + + logger.debug('Connected! Tunnel open %r -> %r -> %r' % (self.request.getpeername(), + chan.getpeername(), (self.chain_host, self.chain_port))) + while True: + r, w, x = select.select([self.request, chan], [], []) + if self.request in r: + data = self.request.recv(1024) + if len(data) == 0: + break + chan.send(data) + if chan in r: + data = chan.recv(1024) + if len(data) == 0: + break + self.request.send(data) + chan.close() + self.request.close() + logger.debug('Tunnel closed ') + + +def forward_tunnel(local_port, remote_host, remote_port, transport): + # this is a little convoluted, but lets me configure things for the Handler + # object. (SocketServer doesn't give Handlers any way to access the outer + # server normally.) + class SubHander (Handler): + chain_host = remote_host + chain_port = remote_port + ssh_transport = transport + ForwardServer(('127.0.0.1', local_port), SubHander).serve_forever() + + +__all__ = ['forward_tunnel'] diff --git a/.venv/lib/python3.8/site-packages/zmq/ssh/tunnel.py b/.venv/lib/python3.8/site-packages/zmq/ssh/tunnel.py new file mode 100644 index 00000000..9c05d6e5 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/zmq/ssh/tunnel.py @@ -0,0 +1,368 @@ +"""Basic ssh tunnel utilities, and convenience functions for tunneling +zeromq connections. +""" + +# Copyright (C) 2010-2011 IPython Development Team +# Copyright (C) 2011- PyZMQ Developers +# +# Redistributed from IPython under the terms of the BSD License. + + +from __future__ import print_function + +import atexit +import os +import re +import signal +import socket +import sys +import warnings +from getpass import getpass, getuser +from multiprocessing import Process + +try: + with warnings.catch_warnings(): + warnings.simplefilter('ignore', DeprecationWarning) + import paramiko + SSHException = paramiko.ssh_exception.SSHException +except ImportError: + paramiko = None + class SSHException(Exception): + pass +else: + from .forward import forward_tunnel + +try: + import pexpect +except ImportError: + pexpect = None + +from ..utils.strtypes import b + + +def select_random_ports(n): + """Select and return n random ports that are available.""" + ports = [] + sockets = [] + for i in range(n): + sock = socket.socket() + sock.bind(('', 0)) + ports.append(sock.getsockname()[1]) + sockets.append(sock) + for sock in sockets: + sock.close() + return ports + +#----------------------------------------------------------------------------- +# Check for passwordless login +#----------------------------------------------------------------------------- +_password_pat = re.compile(b(r'pass(word|phrase):'), re.IGNORECASE) + +def try_passwordless_ssh(server, keyfile, paramiko=None): + """Attempt to make an ssh connection without a password. + This is mainly used for requiring password input only once + when many tunnels may be connected to the same server. + + If paramiko is None, the default for the platform is chosen. + """ + if paramiko is None: + paramiko = sys.platform == 'win32' + if not paramiko: + f = _try_passwordless_openssh + else: + f = _try_passwordless_paramiko + return f(server, keyfile) + +def _try_passwordless_openssh(server, keyfile): + """Try passwordless login with shell ssh command.""" + if pexpect is None: + raise ImportError("pexpect unavailable, use paramiko") + cmd = 'ssh -f '+ server + if keyfile: + cmd += ' -i ' + keyfile + cmd += ' exit' + + # pop SSH_ASKPASS from env + env = os.environ.copy() + env.pop('SSH_ASKPASS', None) + + ssh_newkey = 'Are you sure you want to continue connecting' + p = pexpect.spawn(cmd, env=env) + while True: + try: + i = p.expect([ssh_newkey, _password_pat], timeout=.1) + if i==0: + raise SSHException('The authenticity of the host can\'t be established.') + except pexpect.TIMEOUT: + continue + except pexpect.EOF: + return True + else: + return False + +def _try_passwordless_paramiko(server, keyfile): + """Try passwordless login with paramiko.""" + if paramiko is None: + msg = "Paramiko unavailable, " + if sys.platform == 'win32': + msg += "Paramiko is required for ssh tunneled connections on Windows." + else: + msg += "use OpenSSH." + raise ImportError(msg) + username, server, port = _split_server(server) + client = paramiko.SSHClient() + client.load_system_host_keys() + client.set_missing_host_key_policy(paramiko.WarningPolicy()) + try: + client.connect(server, port, username=username, key_filename=keyfile, + look_for_keys=True) + except paramiko.AuthenticationException: + return False + else: + client.close() + return True + + +def tunnel_connection(socket, addr, server, keyfile=None, password=None, paramiko=None, timeout=60): + """Connect a socket to an address via an ssh tunnel. + + This is a wrapper for socket.connect(addr), when addr is not accessible + from the local machine. It simply creates an ssh tunnel using the remaining args, + and calls socket.connect('tcp://localhost:lport') where lport is the randomly + selected local port of the tunnel. + + """ + new_url, tunnel = open_tunnel(addr, server, keyfile=keyfile, password=password, paramiko=paramiko, timeout=timeout) + socket.connect(new_url) + return tunnel + + +def open_tunnel(addr, server, keyfile=None, password=None, paramiko=None, timeout=60): + """Open a tunneled connection from a 0MQ url. + + For use inside tunnel_connection. + + Returns + ------- + + (url, tunnel) : (str, object) + The 0MQ url that has been forwarded, and the tunnel object + """ + + lport = select_random_ports(1)[0] + transport, addr = addr.split('://') + ip,rport = addr.split(':') + rport = int(rport) + if paramiko is None: + paramiko = sys.platform == 'win32' + if paramiko: + tunnelf = paramiko_tunnel + else: + tunnelf = openssh_tunnel + + tunnel = tunnelf(lport, rport, server, remoteip=ip, keyfile=keyfile, password=password, timeout=timeout) + return 'tcp://127.0.0.1:%i'%lport, tunnel + +def openssh_tunnel(lport, rport, server, remoteip='127.0.0.1', keyfile=None, password=None, timeout=60): + """Create an ssh tunnel using command-line ssh that connects port lport + on this machine to localhost:rport on server. The tunnel + will automatically close when not in use, remaining open + for a minimum of timeout seconds for an initial connection. + + This creates a tunnel redirecting `localhost:lport` to `remoteip:rport`, + as seen from `server`. + + keyfile and password may be specified, but ssh config is checked for defaults. + + Parameters + ---------- + + lport : int + local port for connecting to the tunnel from this machine. + rport : int + port on the remote machine to connect to. + server : str + The ssh server to connect to. The full ssh server string will be parsed. + user@server:port + remoteip : str [Default: 127.0.0.1] + The remote ip, specifying the destination of the tunnel. + Default is localhost, which means that the tunnel would redirect + localhost:lport on this machine to localhost:rport on the *server*. + + keyfile : str; path to public key file + This specifies a key to be used in ssh login, default None. + Regular default ssh keys will be used without specifying this argument. + password : str; + Your ssh password to the ssh server. Note that if this is left None, + you will be prompted for it if passwordless key based login is unavailable. + timeout : int [default: 60] + The time (in seconds) after which no activity will result in the tunnel + closing. This prevents orphaned tunnels from running forever. + """ + if pexpect is None: + raise ImportError("pexpect unavailable, use paramiko_tunnel") + ssh="ssh " + if keyfile: + ssh += "-i " + keyfile + + if ':' in server: + server, port = server.split(':') + ssh += " -p %s" % port + + cmd = "%s -O check %s" % (ssh, server) + (output, exitstatus) = pexpect.run(cmd, withexitstatus=True) + if not exitstatus: + pid = int(output[output.find(b"(pid=")+5:output.find(b")")]) + cmd = "%s -O forward -L 127.0.0.1:%i:%s:%i %s" % ( + ssh, lport, remoteip, rport, server) + (output, exitstatus) = pexpect.run(cmd, withexitstatus=True) + if not exitstatus: + atexit.register(_stop_tunnel, cmd.replace("-O forward", "-O cancel", 1)) + return pid + cmd = "%s -f -S none -L 127.0.0.1:%i:%s:%i %s sleep %i" % ( + ssh, lport, remoteip, rport, server, timeout) + + # pop SSH_ASKPASS from env + env = os.environ.copy() + env.pop('SSH_ASKPASS', None) + + ssh_newkey = 'Are you sure you want to continue connecting' + tunnel = pexpect.spawn(cmd, env=env) + failed = False + while True: + try: + i = tunnel.expect([ssh_newkey, _password_pat], timeout=.1) + if i==0: + raise SSHException('The authenticity of the host can\'t be established.') + except pexpect.TIMEOUT: + continue + except pexpect.EOF: + if tunnel.exitstatus: + print(tunnel.exitstatus) + print(tunnel.before) + print(tunnel.after) + raise RuntimeError("tunnel '%s' failed to start"%(cmd)) + else: + return tunnel.pid + else: + if failed: + print("Password rejected, try again") + password=None + if password is None: + password = getpass("%s's password: "%(server)) + tunnel.sendline(password) + failed = True + +def _stop_tunnel(cmd): + pexpect.run(cmd) + +def _split_server(server): + if '@' in server: + username,server = server.split('@', 1) + else: + username = getuser() + if ':' in server: + server, port = server.split(':') + port = int(port) + else: + port = 22 + return username, server, port + +def paramiko_tunnel(lport, rport, server, remoteip='127.0.0.1', keyfile=None, password=None, timeout=60): + """launch a tunner with paramiko in a subprocess. This should only be used + when shell ssh is unavailable (e.g. Windows). + + This creates a tunnel redirecting `localhost:lport` to `remoteip:rport`, + as seen from `server`. + + If you are familiar with ssh tunnels, this creates the tunnel: + + ssh server -L localhost:lport:remoteip:rport + + keyfile and password may be specified, but ssh config is checked for defaults. + + + Parameters + ---------- + + lport : int + local port for connecting to the tunnel from this machine. + rport : int + port on the remote machine to connect to. + server : str + The ssh server to connect to. The full ssh server string will be parsed. + user@server:port + remoteip : str [Default: 127.0.0.1] + The remote ip, specifying the destination of the tunnel. + Default is localhost, which means that the tunnel would redirect + localhost:lport on this machine to localhost:rport on the *server*. + + keyfile : str; path to public key file + This specifies a key to be used in ssh login, default None. + Regular default ssh keys will be used without specifying this argument. + password : str; + Your ssh password to the ssh server. Note that if this is left None, + you will be prompted for it if passwordless key based login is unavailable. + timeout : int [default: 60] + The time (in seconds) after which no activity will result in the tunnel + closing. This prevents orphaned tunnels from running forever. + + """ + if paramiko is None: + raise ImportError("Paramiko not available") + + if password is None: + if not _try_passwordless_paramiko(server, keyfile): + password = getpass("%s's password: "%(server)) + + p = Process(target=_paramiko_tunnel, + args=(lport, rport, server, remoteip), + kwargs=dict(keyfile=keyfile, password=password)) + p.daemon = True + p.start() + return p + + +def _paramiko_tunnel(lport, rport, server, remoteip, keyfile=None, password=None): + """Function for actually starting a paramiko tunnel, to be passed + to multiprocessing.Process(target=this), and not called directly. + """ + username, server, port = _split_server(server) + client = paramiko.SSHClient() + client.load_system_host_keys() + client.set_missing_host_key_policy(paramiko.WarningPolicy()) + + try: + client.connect(server, port, username=username, key_filename=keyfile, + look_for_keys=True, password=password) +# except paramiko.AuthenticationException: +# if password is None: +# password = getpass("%s@%s's password: "%(username, server)) +# client.connect(server, port, username=username, password=password) +# else: +# raise + except Exception as e: + print('*** Failed to connect to %s:%d: %r' % (server, port, e)) + sys.exit(1) + + # Don't let SIGINT kill the tunnel subprocess + signal.signal(signal.SIGINT, signal.SIG_IGN) + + try: + forward_tunnel(lport, remoteip, rport, client.get_transport()) + except KeyboardInterrupt: + print('SIGINT: Port forwarding stopped cleanly') + sys.exit(0) + except Exception as e: + print("Port forwarding stopped uncleanly: %s"%e) + sys.exit(255) + +if sys.platform == 'win32': + ssh_tunnel = paramiko_tunnel +else: + ssh_tunnel = openssh_tunnel + + +__all__ = ['tunnel_connection', 'ssh_tunnel', 'openssh_tunnel', 'paramiko_tunnel', 'try_passwordless_ssh'] + + diff --git a/.venv/lib/python3.8/site-packages/zmq/sugar/__init__.py b/.venv/lib/python3.8/site-packages/zmq/sugar/__init__.py new file mode 100644 index 00000000..504da1c0 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/zmq/sugar/__init__.py @@ -0,0 +1,29 @@ +"""pure-Python sugar wrappers for core 0MQ objects.""" + +# Copyright (C) PyZMQ Developers +# Distributed under the terms of the Modified BSD License. + + +from zmq.sugar import ( + constants, context, frame, poll, socket, tracker, version +) +from zmq import error + +__all__ = ['constants'] +for submod in ( + constants, context, error, frame, poll, socket, tracker, version +): + __all__.extend(submod.__all__) + +from zmq.error import * +from zmq.sugar.context import * +from zmq.sugar.tracker import * +from zmq.sugar.socket import * +from zmq.sugar.constants import * +from zmq.sugar.frame import * +from zmq.sugar.poll import * +from zmq.sugar.version import * + +# deprecated: +from zmq.sugar.stopwatch import Stopwatch +__all__.append('Stopwatch') diff --git a/.venv/lib/python3.8/site-packages/zmq/sugar/__pycache__/__init__.cpython-38.pyc b/.venv/lib/python3.8/site-packages/zmq/sugar/__pycache__/__init__.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d14c3182da9dacba3228060ebbabbafa9d963c24 GIT binary patch literal 787 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 literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/zmq/sugar/__pycache__/context.cpython-38.pyc b/.venv/lib/python3.8/site-packages/zmq/sugar/__pycache__/context.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..19d27e2755275b071a208602467eb297503ca434 GIT binary patch literal 8638 zcmcgx%X8dDddF)X91b6%sHbJSE!%63mKxbvYvU-kW0{t`P9*9@MP4Ku5JZC{L<}(M z#)#t7ur{?)vZqasxl%`^DybZD$$ybUY7e;XX)igXYA;(!HovbMn3p71atTN@dVqd> z?^oZSn`;=jDu4M)FMHQ8enmgVuL^#Afm{9~8g94-H@Ov?uBo1uYvF0fcE@oYlfF4| zrBijQs$Yp~ow_@NewEkaMrYQYRsDM0?991ysy`FYcIMsr&VswpS#%fGyGDGhv*a$J zZ}QprcxTyNM!)Hw;B$Qbnc*kNd~NUrzWB`Gi{VT-_tbIgd~wHgPjl;@ z(K^;YefuEWO%t{iB|J)YB->5}`|#$S_OF4BvEDLs=SCXr;aPhS`g`}njJj)Sl7&yQ zUz-?%-!nm)$jnbNi60ABvrI%=y)4AwEEFv}uU%WewQ=wM?Yw&9oAs}+-OcBM?1`6l zGcWNwp?qQH)qB`PtzCC--nk}3Dy|0v!T3eHt>Kn+G~Dz-ZQx+7Z(!HD7e0wHVDQ2a z3;3*>-(J3yb-I_jQTJjm>H64#U)gX0m-?MYmt=3p7ngto;neOP zFA&KHfyx3EI;_V_4!C+Lr)x=o>EiA80}YtT%}5uFWmi!CeWfPYt(*UY* z7@m_2KJx)3=pN}|m3 za(gGt@|vf|<#j>;!Yu^>h+zeqPy|PY@wQl^*VVm!U+j?V&v;%C`%-$ImfS^r79?}u z!!4U=4D+nnH0xH?teXABg0Ss!`+)SKyr@q!TEi{Rp~;M=2Jkl?n(}mJ$hhs6IAm6f#+Sq4_QTHI901*_7_H2s_!o$ zIWz_&0RtF<7v{QNoZ-dvHlT3`^%kD@3BGD&Hv7j$n-pIswjuTrEpO2j;sa=BDB58= zaUL&Prg)nkw!$rUh@;{SyqVq~vO<=`^ZpPY%k9TFsXtCgH|b>J{AR9t7XX4H)c_6GYX`K6&~Aeqxf~#mEV|lZMXVRvMb1LmJA>y}D#%Z!`Fu=f<9`ei;uP zv5U8rzx`BMV?FLi6XWO?jr$9wBi1jVE1scOLC<_(TsH0)ca3k=KF}ZAKLxhm4YQs| zB=gx$oNoE?(2PeaCJVy0cEKdwH&dB03Du9o!g`0C`Q2_D1%3ummu%O6Ob%R+S)E#P zq$c-e2sMKWY99?Plo^~QgZ6dd%9KA5DNM~v(8!@2z9pzLG(w>0E^Kn?O;zg%} z(6sAQ7@4TZR5{9!G~dtQbh;sSz>tDh+9;%~C&S?`K89`ky*Ohq&bDI$A$XZv1d(aTN04^(C`wGPitEDacY&}iFSInSUG_W0Lo5?;aXE1

P2^#$>?fM+D3 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 literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/zmq/sugar/__pycache__/poll.cpython-38.pyc b/.venv/lib/python3.8/site-packages/zmq/sugar/__pycache__/poll.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..541458ea43094b471d26dd9073f224b757003349 GIT binary patch literal 4944 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 literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/zmq/sugar/__pycache__/tracker.cpython-38.pyc b/.venv/lib/python3.8/site-packages/zmq/sugar/__pycache__/tracker.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..4eab36eeb0b00f0a7ffc31ae15599ea347ae4233 GIT binary patch literal 3406 zcmbtWOK%*<5$^7pot+)7Xj+zS#Q}mw5F=cJyR?BQhy^E+podK)q7#a->#_i+@FbUnS(<*tz(1pmPU`UO**CNCXuur6HZKLCZ;5=7cUKPe}d~m&lg%M(i+9 zcPPO>SmDA77gu~na`q{Xw9mKL?^ZY_uO#LY|Ce&S%AxYnclk+s(CsHh5xCP+l0Eg?5%nk;F!( zvjN{7OS^dMV{XPu#=>GkDH;Zvb9fA!i%jwq_9H3^Pgc^iX=;)QEI^35Hk?RCBdJh#U4SPUJ+Q*;sg>~oUU96g1wjpa4IIXJF|r^~ zn`z~3FcP0xzc&8wVst35OQmkV`Rpn6ZS&jQ`r-z^><&$zC%HCpK9n^&^bL!!*gKFz z1J_XltIbsbN8Ky9Xjf38pUP)4wI`zldnVf9+@kgQmD_Fb0ye5EpfvbdBci&#vlTVE z?IDFQIr}hnT2MZOqW=t)Atz)(B3l2l1-(x`PnXO%3ufFCrruqU1Nx%1U@s{pM>p)a z2jd^XIJ+|5hVjXQ9r*gG=?Hp4zociY4*Yt5AedQMuoL?j%nG_wpaRzWNgYE!cg{)IwJ#M~o{W#QkK)q>45c1Pa>=9vNe$qYh{oC7gQmm&;d&)7D9Q@Qs|3iyE;*o!6$J# zl@F9ERN2{`P3op=pxJXuSIcx1w(B@89Wd!%iMkFVzP`0-vdQKone?am1e1{H1G~wz z|NPeT=d)Yy-`bpKN1J-OAFIv!w83On`cahRiHV}0f)ITZD$?~S{snZkE*|vO*!<1Q z&N(>S`Hk>G4ey~iOi$qc1On>%k}l{A`jTi5^Xg-A`~?9xkg1lOVPjZnI{z2~Sk>^Sn7 z3E3pG#;dB=U|hWc)mWKN8N;$=wBAI)W};um%#(on>nQX&mN1Fbv3}b>KkX{R^dJ(R$&6 z{dRG@mgy~=g|}cg$uGzfT1$4c0diU(=V!}yE$7tAX`jpapL>mH0TFreKY)lbGdPYD zvyQo`n3`Yq->csM7$;9)#y$ct*#PfAM*G&Q!6(2pH%ZE$)^eVHXELfc0vC_j&!^x&UoQ znyJdG9El3oB-tFW4L9F(Z~;7mtOaVxjk?XErm+Ku%Bzx_*&0gIuVpv#II#b4j0v(* zVT;F^J-K=&;PQtG(_Qk#?GAw#WV^QCcF!waY}>$4=%A&G#!#dk7V7=|wL+SSYx15VgIV?~k?-s(=d?QdJ_+gi8)c2(_vzQKY7&DG2RlyU94|!e+C0owmsd zsc_*(AUO8daO1F7PW=l#AjVG9E)*vodpx%1z3182l}eFd%Y6Ll{;&!8rJZ!kqO*=Y z{(=UGLx2Jc=#V*#60jT#sAFT#fbC=F|Sl6?XlwKf1VsfrMP3jP~@Y zbkhoKVvir9QAFMc`i&~42r#fdvwLK~zS9m-tb;3v%$}}Fp~f=g>PTF}8ufWJK_J|V zxyNHA{cvze*V`BR`nr{rT~~@@UsG`1#C|vO!=&V1!*%AASc5);{uy)!yJ)N|kwwjo!8IK2^Y+ey>M3baq5X|qqt2ycHgxPeN$pxI+*>op|P`N%ciqm73-}`Yplp@me1w$`HW2&VY>hR0}=Wgz5oCK literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/zmq/sugar/attrsettr.py b/.venv/lib/python3.8/site-packages/zmq/sugar/attrsettr.py new file mode 100644 index 00000000..f1fe88f7 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/zmq/sugar/attrsettr.py @@ -0,0 +1,66 @@ +# coding: utf-8 +"""Mixin for mapping set/getattr to self.set/get""" + +# Copyright (C) PyZMQ Developers +# Distributed under the terms of the Modified BSD License. + +import errno +from . import constants + +class AttributeSetter(object): + + def __setattr__(self, key, value): + """set zmq options by attribute""" + + if key in self.__dict__: + object.__setattr__(self, key, value) + return + # regular setattr only allowed for class-defined attributes + for obj in self.__class__.mro(): + if key in obj.__dict__: + object.__setattr__(self, key, value) + return + + upper_key = key.upper() + try: + opt = getattr(constants, upper_key) + except AttributeError: + raise AttributeError("%s has no such option: %s" % ( + self.__class__.__name__, upper_key) + ) + else: + self._set_attr_opt(upper_key, opt, value) + + def _set_attr_opt(self, name, opt, value): + """override if setattr should do something other than call self.set""" + self.set(opt, value) + + def __getattr__(self, key): + """get zmq options by attribute""" + upper_key = key.upper() + try: + opt = getattr(constants, upper_key) + except AttributeError: + raise AttributeError("%s has no such option: %s" % ( + self.__class__.__name__, upper_key) + ) + else: + from zmq import ZMQError + try: + return self._get_attr_opt(upper_key, opt) + except ZMQError as e: + # EINVAL will be raised on access for write-only attributes. + # Turn that into an AttributeError + # necessary for mocking + if e.errno in {errno.EINVAL, errno.EFAULT}: + raise AttributeError("{} attribute is write-only".format(key)) + else: + raise + + + def _get_attr_opt(self, name, opt): + """override if getattr should do something other than call self.get""" + return self.get(opt) + + +__all__ = ['AttributeSetter'] diff --git a/.venv/lib/python3.8/site-packages/zmq/sugar/constants.py b/.venv/lib/python3.8/site-packages/zmq/sugar/constants.py new file mode 100644 index 00000000..37ff1c55 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/zmq/sugar/constants.py @@ -0,0 +1,108 @@ +"""0MQ Constants.""" + +# Copyright (c) PyZMQ Developers. +# Distributed under the terms of the Modified BSD License. + +from zmq.backend import constants +from zmq.backend import has +from zmq.utils.constant_names import ( + base_names, + switched_sockopt_names, + int_sockopt_names, + int64_sockopt_names, + bytes_sockopt_names, + fd_sockopt_names, + ctx_opt_names, + msg_opt_names, +) + +#----------------------------------------------------------------------------- +# Python module level constants +#----------------------------------------------------------------------------- + + +__all__ = [ + 'int_sockopts', + 'int64_sockopts', + 'bytes_sockopts', + 'ctx_opts', + 'ctx_opt_names', + 'DRAFT_API', +] + +if constants.VERSION < 40200: + DRAFT_API = False +else: + DRAFT_API = bool(has('draft') and constants.DRAFT_API) + +int_sockopts = set() +int64_sockopts = set() +bytes_sockopts = set() +fd_sockopts = set() +ctx_opts = set() +msg_opts = set() + + +if constants.VERSION < 30000: + int64_sockopt_names.extend(switched_sockopt_names) +else: + int_sockopt_names.extend(switched_sockopt_names) + +_UNDEFINED = -9999 + + +def _add_constant(name, container=None): + """add a constant to be defined + + optionally add it to one of the sets for use in get/setopt checkers + """ + c = getattr(constants, name, _UNDEFINED) + if c == _UNDEFINED: + return + globals()[name] = c + __all__.append(name) + if container is not None: + container.add(c) + return c + +for name in base_names: + _add_constant(name) + +for name in int_sockopt_names: + _add_constant(name, int_sockopts) + +for name in int64_sockopt_names: + _add_constant(name, int64_sockopts) + +for name in bytes_sockopt_names: + _add_constant(name, bytes_sockopts) + +for name in fd_sockopt_names: + _add_constant(name, fd_sockopts) + +for name in ctx_opt_names: + _add_constant(name, ctx_opts) + +for name in msg_opt_names: + _add_constant(name, msg_opts) + + +# ensure some aliases are always defined +aliases = [ + ('DONTWAIT', 'NOBLOCK'), + ('XREQ', 'DEALER'), + ('XREP', 'ROUTER'), +] +for group in aliases: + undefined = set() + found = None + for name in group: + value = getattr(constants, name, -1) + if value != -1: + found = value + else: + undefined.add(name) + if found is not None: + for name in undefined: + globals()[name] = found + __all__.append(name) diff --git a/.venv/lib/python3.8/site-packages/zmq/sugar/context.py b/.venv/lib/python3.8/site-packages/zmq/sugar/context.py new file mode 100644 index 00000000..e30068d8 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/zmq/sugar/context.py @@ -0,0 +1,282 @@ +# coding: utf-8 +"""Python bindings for 0MQ.""" + +# Copyright (C) PyZMQ Developers +# Distributed under the terms of the Modified BSD License. + +import atexit +import os +from threading import Lock +from weakref import WeakSet + +from zmq.backend import Context as ContextBase +from . import constants +from .attrsettr import AttributeSetter +from .constants import ENOTSUP, LINGER, ctx_opt_names +from .socket import Socket +from zmq.error import ZMQError + +# notice when exiting, to avoid triggering term on exit +_exiting = False +def _notice_atexit(): + global _exiting + _exiting = True +atexit.register(_notice_atexit) + +class Context(ContextBase, AttributeSetter): + """Create a zmq Context + + A zmq Context creates sockets via its ``ctx.socket`` method. + """ + sockopts = None + _instance = None + _instance_lock = Lock() + _instance_pid = None + _shadow = False + _sockets = None + + def __init__(self, io_threads=1, **kwargs): + super(Context, self).__init__(io_threads=io_threads, **kwargs) + if kwargs.get('shadow', False): + self._shadow = True + else: + self._shadow = False + self.sockopts = {} + self._sockets = WeakSet() + + def __del__(self): + """deleting a Context should terminate it, without trying non-threadsafe destroy""" + + # Calling locals() here conceals issue #1167 on Windows CPython 3.5.4. + locals() + + if not self._shadow and not _exiting: + self.term() + + def __enter__(self): + return self + + def __exit__(self, *args, **kwargs): + self.term() + + def __copy__(self, memo=None): + """Copying a Context creates a shadow copy""" + return self.__class__.shadow(self.underlying) + + __deepcopy__ = __copy__ + + @classmethod + def shadow(cls, address): + """Shadow an existing libzmq context + + address is the integer address of the libzmq context + or an FFI pointer to it. + + .. versionadded:: 14.1 + """ + from zmq.utils.interop import cast_int_addr + address = cast_int_addr(address) + return cls(shadow=address) + + @classmethod + def shadow_pyczmq(cls, ctx): + """Shadow an existing pyczmq context + + ctx is the FFI `zctx_t *` pointer + + .. versionadded:: 14.1 + """ + from pyczmq import zctx + from zmq.utils.interop import cast_int_addr + + underlying = zctx.underlying(ctx) + address = cast_int_addr(underlying) + return cls(shadow=address) + + # static method copied from tornado IOLoop.instance + @classmethod + def instance(cls, io_threads=1): + """Returns a global Context instance. + + Most single-threaded applications have a single, global Context. + Use this method instead of passing around Context instances + throughout your code. + + A common pattern for classes that depend on Contexts is to use + a default argument to enable programs with multiple Contexts + but not require the argument for simpler applications:: + + class MyClass(object): + def __init__(self, context=None): + self.context = context or Context.instance() + + .. versionchanged:: 18.1 + + When called in a subprocess after forking, + a new global instance is created instead of inheriting + a Context that won't work from the parent process. + """ + if ( + cls._instance is None + or cls._instance_pid != os.getpid() + or cls._instance.closed + ): + with cls._instance_lock: + if ( + cls._instance is None + or cls._instance_pid != os.getpid() + or cls._instance.closed + ): + cls._instance = cls(io_threads=io_threads) + cls._instance_pid = os.getpid() + return cls._instance + + def term(self): + """Close or terminate the context. + + Context termination is performed in the following steps: + + - Any blocking operations currently in progress on sockets open within context shall + raise :class:`zmq.ContextTerminated`. + With the exception of socket.close(), any further operations on sockets open within this context + shall raise :class:`zmq.ContextTerminated`. + - After interrupting all blocking calls, term shall block until the following conditions are satisfied: + - All sockets open within context have been closed. + - For each socket within context, all messages sent on the socket have either been + physically transferred to a network peer, + or the socket's linger period set with the zmq.LINGER socket option has expired. + + For further details regarding socket linger behaviour refer to libzmq documentation for ZMQ_LINGER. + + This can be called to close the context by hand. If this is not called, + the context will automatically be closed when it is garbage collected. + """ + return super(Context, self).term() + + #------------------------------------------------------------------------- + # Hooks for ctxopt completion + #------------------------------------------------------------------------- + + def __dir__(self): + keys = dir(self.__class__) + + for collection in ( + ctx_opt_names, + ): + keys.extend(collection) + return keys + + #------------------------------------------------------------------------- + # Creating Sockets + #------------------------------------------------------------------------- + + def _add_socket(self, socket): + self._sockets.add(socket) + + def _rm_socket(self, socket): + if self._sockets: + self._sockets.discard(socket) + + def destroy(self, linger=None): + """Close all sockets associated with this context and then terminate + the context. + + .. warning:: + + destroy involves calling ``zmq_close()``, which is **NOT** threadsafe. + If there are active sockets in other threads, this must not be called. + + Parameters + ---------- + + linger : int, optional + If specified, set LINGER on sockets prior to closing them. + """ + if self.closed: + return + + sockets = self._sockets + self._sockets = WeakSet() + for s in sockets: + if s and not s.closed: + if linger is not None: + s.setsockopt(LINGER, linger) + s.close() + + self.term() + + @property + def _socket_class(self): + return Socket + + def socket(self, socket_type, **kwargs): + """Create a Socket associated with this Context. + + Parameters + ---------- + socket_type : int + The socket type, which can be any of the 0MQ socket types: + REQ, REP, PUB, SUB, PAIR, DEALER, ROUTER, PULL, PUSH, etc. + + kwargs: + will be passed to the __init__ method of the socket class. + """ + if self.closed: + raise ZMQError(ENOTSUP) + s = self._socket_class(self, socket_type, **kwargs) + for opt, value in self.sockopts.items(): + try: + s.setsockopt(opt, value) + except ZMQError: + # ignore ZMQErrors, which are likely for socket options + # that do not apply to a particular socket type, e.g. + # SUBSCRIBE for non-SUB sockets. + pass + self._add_socket(s) + return s + + def setsockopt(self, opt, value): + """set default socket options for new sockets created by this Context + + .. versionadded:: 13.0 + """ + self.sockopts[opt] = value + + def getsockopt(self, opt): + """get default socket options for new sockets created by this Context + + .. versionadded:: 13.0 + """ + return self.sockopts[opt] + + def _set_attr_opt(self, name, opt, value): + """set default sockopts as attributes""" + if name in constants.ctx_opt_names: + return self.set(opt, value) + else: + self.sockopts[opt] = value + + def _get_attr_opt(self, name, opt): + """get default sockopts as attributes""" + if name in constants.ctx_opt_names: + return self.get(opt) + else: + if opt not in self.sockopts: + raise AttributeError(name) + else: + return self.sockopts[opt] + + def __delattr__(self, key): + """delete default sockopts as attributes""" + key = key.upper() + try: + opt = getattr(constants, key) + except AttributeError: + raise AttributeError("no such socket option: %s" % key) + else: + if opt not in self.sockopts: + raise AttributeError(key) + else: + del self.sockopts[opt] + +__all__ = ['Context'] diff --git a/.venv/lib/python3.8/site-packages/zmq/sugar/frame.py b/.venv/lib/python3.8/site-packages/zmq/sugar/frame.py new file mode 100644 index 00000000..e24f217c --- /dev/null +++ b/.venv/lib/python3.8/site-packages/zmq/sugar/frame.py @@ -0,0 +1,88 @@ +# coding: utf-8 +"""0MQ Frame pure Python methods.""" + +# Copyright (C) PyZMQ Developers +# Distributed under the terms of the Modified BSD License. + +from .attrsettr import AttributeSetter +from zmq.backend import Frame as FrameBase +import zmq + +def _draft(v, feature): + zmq.error._check_version(v, feature) + if not zmq.DRAFT_API: + raise RuntimeError("libzmq and pyzmq must be built with draft support for %s" % feature) + +class Frame(FrameBase, AttributeSetter): + """Frame(data=None, track=False, copy=None, copy_threshold=zmq.COPY_THRESHOLD) + + A zmq message Frame class for non-copy send/recvs. + + This class is only needed if you want to do non-copying send and recvs. + When you pass a string to this class, like ``Frame(s)``, the + ref-count of `s` is increased by two: once because the Frame saves `s` as + an instance attribute and another because a ZMQ message is created that + points to the buffer of `s`. This second ref-count increase makes sure + that `s` lives until all messages that use it have been sent. Once 0MQ + sends all the messages and it doesn't need the buffer of s, 0MQ will call + ``Py_DECREF(s)``. + + Parameters + ---------- + + data : object, optional + any object that provides the buffer interface will be used to + construct the 0MQ message data. + track : bool [default: False] + whether a MessageTracker_ should be created to track this object. + Tracking a message has a cost at creation, because it creates a threadsafe + Event object. + copy : bool [default: use copy_threshold] + Whether to create a copy of the data to pass to libzmq + or share the memory with libzmq. + If unspecified, copy_threshold is used. + copy_threshold: int [default: zmq.COPY_THRESHOLD] + If copy is unspecified, messages smaller than this many bytes + will be copied and messages larger than this will be shared with libzmq. + """ + + def __getitem__(self, key): + # map Frame['User-Id'] to Frame.get('User-Id') + return self.get(key) + + @property + def group(self): + """The RADIO-DISH group of the message. + + Requires libzmq >= 4.2 and pyzmq built with draft APIs enabled. + + .. versionadded:: 17 + """ + _draft((4,2), "RADIO-DISH") + return self.get('group') + + @group.setter + def group(self, group): + _draft((4,2), "RADIO-DISH") + self.set('group', group) + + @property + def routing_id(self): + """The CLIENT-SERVER routing id of the message. + + Requires libzmq >= 4.2 and pyzmq built with draft APIs enabled. + + .. versionadded:: 17 + """ + _draft((4,2), "CLIENT-SERVER") + return self.get('routing_id') + + @routing_id.setter + def routing_id(self, routing_id): + _draft((4,2), "CLIENT-SERVER") + self.set('routing_id', routing_id) + + +# keep deprecated alias +Message = Frame +__all__ = ['Frame', 'Message'] diff --git a/.venv/lib/python3.8/site-packages/zmq/sugar/poll.py b/.venv/lib/python3.8/site-packages/zmq/sugar/poll.py new file mode 100644 index 00000000..ee0f68a7 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/zmq/sugar/poll.py @@ -0,0 +1,162 @@ +"""0MQ polling related functions and classes.""" + +# Copyright (C) PyZMQ Developers +# Distributed under the terms of the Modified BSD License. + + +import zmq +from zmq.backend import zmq_poll +from .constants import POLLIN, POLLOUT, POLLERR + +#----------------------------------------------------------------------------- +# Polling related methods +#----------------------------------------------------------------------------- + + +class Poller(object): + """A stateful poll interface that mirrors Python's built-in poll.""" + sockets = None + _map = {} + + def __init__(self): + self.sockets = [] + self._map = {} + + def __contains__(self, socket): + return socket in self._map + + def register(self, socket, flags=POLLIN|POLLOUT): + """p.register(socket, flags=POLLIN|POLLOUT) + + Register a 0MQ socket or native fd for I/O monitoring. + + register(s,0) is equivalent to unregister(s). + + Parameters + ---------- + socket : zmq.Socket or native socket + A zmq.Socket or any Python object having a ``fileno()`` + method that returns a valid file descriptor. + flags : int + The events to watch for. Can be POLLIN, POLLOUT or POLLIN|POLLOUT. + If `flags=0`, socket will be unregistered. + """ + if flags: + if socket in self._map: + idx = self._map[socket] + self.sockets[idx] = (socket, flags) + else: + idx = len(self.sockets) + self.sockets.append((socket, flags)) + self._map[socket] = idx + elif socket in self._map: + # uregister sockets registered with no events + self.unregister(socket) + else: + # ignore new sockets with no events + pass + + def modify(self, socket, flags=POLLIN|POLLOUT): + """Modify the flags for an already registered 0MQ socket or native fd.""" + self.register(socket, flags) + + def unregister(self, socket): + """Remove a 0MQ socket or native fd for I/O monitoring. + + Parameters + ---------- + socket : Socket + The socket instance to stop polling. + """ + idx = self._map.pop(socket) + self.sockets.pop(idx) + # shift indices after deletion + for socket, flags in self.sockets[idx:]: + self._map[socket] -= 1 + + def poll(self, timeout=None): + """Poll the registered 0MQ or native fds for I/O. + + If there are currently events ready to be processed, this function will return immediately. + Otherwise, this function will return as soon the first event is available or after timeout + milliseconds have elapsed. + + Parameters + ---------- + timeout : float, int + The timeout in milliseconds. If None, no `timeout` (infinite). This + is in milliseconds to be compatible with ``select.poll()``. + + Returns + ------- + events : list of tuples + The list of events that are ready to be processed. + This is a list of tuples of the form ``(socket, event_mask)``, where the 0MQ Socket + or integer fd is the first element, and the poll event mask (POLLIN, POLLOUT) is the second. + It is common to call ``events = dict(poller.poll())``, + which turns the list of tuples into a mapping of ``socket : event_mask``. + """ + if timeout is None or timeout < 0: + timeout = -1 + elif isinstance(timeout, float): + timeout = int(timeout) + return zmq_poll(self.sockets, timeout=timeout) + + +def select(rlist, wlist, xlist, timeout=None): + """select(rlist, wlist, xlist, timeout=None) -> (rlist, wlist, xlist) + + Return the result of poll as a lists of sockets ready for r/w/exception. + + This has the same interface as Python's built-in ``select.select()`` function. + + Parameters + ---------- + timeout : float, int, optional + The timeout in seconds. If None, no timeout (infinite). This is in seconds to be + compatible with ``select.select()``. + rlist : list of sockets/FDs + sockets/FDs to be polled for read events + wlist : list of sockets/FDs + sockets/FDs to be polled for write events + xlist : list of sockets/FDs + sockets/FDs to be polled for error events + + Returns + ------- + (rlist, wlist, xlist) : tuple of lists of sockets (length 3) + Lists correspond to sockets available for read/write/error events respectively. + """ + if timeout is None: + timeout = -1 + # Convert from sec -> us for zmq_poll. + # zmq_poll accepts 3.x style timeout in ms + timeout = int(timeout*1000.0) + if timeout < 0: + timeout = -1 + sockets = [] + for s in set(rlist + wlist + xlist): + flags = 0 + if s in rlist: + flags |= POLLIN + if s in wlist: + flags |= POLLOUT + if s in xlist: + flags |= POLLERR + sockets.append((s, flags)) + return_sockets = zmq_poll(sockets, timeout) + rlist, wlist, xlist = [], [], [] + for s, flags in return_sockets: + if flags & POLLIN: + rlist.append(s) + if flags & POLLOUT: + wlist.append(s) + if flags & POLLERR: + xlist.append(s) + return rlist, wlist, xlist + +#----------------------------------------------------------------------------- +# Symbols to export +#----------------------------------------------------------------------------- + +__all__ = [ 'Poller', 'select' ] diff --git a/.venv/lib/python3.8/site-packages/zmq/sugar/socket.py b/.venv/lib/python3.8/site-packages/zmq/sugar/socket.py new file mode 100644 index 00000000..40ee3278 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/zmq/sugar/socket.py @@ -0,0 +1,849 @@ +# coding: utf-8 +"""0MQ Socket pure Python methods.""" + +# Copyright (C) PyZMQ Developers +# Distributed under the terms of the Modified BSD License. + + +import errno +import random +import sys +import warnings +from contextlib import contextmanager + +import zmq +from zmq.backend import Socket as SocketBase +from .poll import Poller +from . import constants +from .attrsettr import AttributeSetter +from zmq.error import ZMQError, ZMQBindError +from zmq.utils import jsonapi +from zmq.utils.strtypes import bytes, unicode, basestring + + +from .constants import ( + SNDMORE, ENOTSUP, POLLIN, + int64_sockopt_names, + int_sockopt_names, + bytes_sockopt_names, + fd_sockopt_names, +) +try: + import cPickle + pickle = cPickle +except: + cPickle = None + import pickle + +try: + DEFAULT_PROTOCOL = pickle.DEFAULT_PROTOCOL +except AttributeError: + DEFAULT_PROTOCOL = pickle.HIGHEST_PROTOCOL + + +class Socket(SocketBase, AttributeSetter): + """The ZMQ socket object + + To create a Socket, first create a Context:: + + ctx = zmq.Context.instance() + + then call ``ctx.socket(socket_type)``:: + + s = ctx.socket(zmq.ROUTER) + + """ + _shadow = False + _monitor_socket = None + + def __init__(self, *a, **kw): + super(Socket, self).__init__(*a, **kw) + if 'shadow' in kw: + self._shadow = True + else: + self._shadow = False + + def __del__(self): + if not self._shadow: + self.close() + + # socket as context manager: + def __enter__(self): + """Sockets are context managers + + .. versionadded:: 14.4 + """ + return self + + def __exit__(self, *args, **kwargs): + self.close() + + #------------------------------------------------------------------------- + # Socket creation + #------------------------------------------------------------------------- + + def __copy__(self, memo=None): + """Copying a Socket creates a shadow copy""" + return self.__class__.shadow(self.underlying) + + __deepcopy__ = __copy__ + + @classmethod + def shadow(cls, address): + """Shadow an existing libzmq socket + + address is the integer address of the libzmq socket + or an FFI pointer to it. + + .. versionadded:: 14.1 + """ + from zmq.utils.interop import cast_int_addr + address = cast_int_addr(address) + return cls(shadow=address) + + def close(self, linger=None): + """ + Close the socket. + + If linger is specified, LINGER sockopt will be set prior to closing. + + Note: closing a zmq Socket may not close the underlying sockets + if there are undelivered messages. + Only after all messages are delivered or discarded by reaching the socket's LINGER timeout + (default: forever) + will the underlying sockets be closed. + + This can be called to close the socket by hand. If this is not + called, the socket will automatically be closed when it is + garbage collected. + """ + if self.context: + self.context._rm_socket(self) + super(Socket, self).close(linger=linger) + + #------------------------------------------------------------------------- + # Connect/Bind context managers + #------------------------------------------------------------------------- + + @contextmanager + def _connect_cm(self, addr): + """Context manager to disconnect on exit + + .. versionadded:: 20.0 + """ + try: + yield + finally: + self.disconnect(addr) + + @contextmanager + def _bind_cm(self, addr): + """Context manager to unbind on exit + + .. versionadded:: 20.0 + """ + try: + yield + finally: + self.unbind(addr) + + def bind(self, addr): + """s.bind(addr) + + Bind the socket to an address. + + This causes the socket to listen on a network port. Sockets on the + other side of this connection will use ``Socket.connect(addr)`` to + connect to this socket. + + Returns a context manager which will call unbind on exit. + + .. versionadded:: 20.0 + Can be used as a context manager. + + Parameters + ---------- + addr : str + The address string. This has the form 'protocol://interface:port', + for example 'tcp://127.0.0.1:5555'. Protocols supported include + tcp, udp, pgm, epgm, inproc and ipc. If the address is unicode, it is + encoded to utf-8 first. + + """ + super().bind(addr) + return self._bind_cm(addr) + + def connect(self, addr): + """s.connect(addr) + + Connect to a remote 0MQ socket. + + Returns a context manager which will call disconnect on exit. + + .. versionadded:: 20.0 + Can be used as a context manager. + + Parameters + ---------- + addr : str + The address string. This has the form 'protocol://interface:port', + for example 'tcp://127.0.0.1:5555'. Protocols supported are + tcp, upd, pgm, inproc and ipc. If the address is unicode, it is + encoded to utf-8 first. + + """ + super().connect(addr) + return self._connect_cm(addr) + + #------------------------------------------------------------------------- + # Deprecated aliases + #------------------------------------------------------------------------- + + @property + def socket_type(self): + warnings.warn("Socket.socket_type is deprecated, use Socket.type", + DeprecationWarning + ) + return self.type + + #------------------------------------------------------------------------- + # Hooks for sockopt completion + #------------------------------------------------------------------------- + + def __dir__(self): + keys = dir(self.__class__) + for collection in ( + bytes_sockopt_names, + int_sockopt_names, + int64_sockopt_names, + fd_sockopt_names, + ): + keys.extend(collection) + return keys + + #------------------------------------------------------------------------- + # Getting/Setting options + #------------------------------------------------------------------------- + setsockopt = SocketBase.set + getsockopt = SocketBase.get + + def __setattr__(self, key, value): + """Override to allow setting zmq.[UN]SUBSCRIBE even though we have a subscribe method""" + if key in self.__dict__: + object.__setattr__(self, key, value) + return + _key = key.lower() + if _key in ('subscribe', 'unsubscribe'): + + if isinstance(value, unicode): + value = value.encode('utf8') + if _key == 'subscribe': + self.set(zmq.SUBSCRIBE, value) + else: + self.set(zmq.UNSUBSCRIBE, value) + return + super(Socket, self).__setattr__(key, value) + + def fileno(self): + """Return edge-triggered file descriptor for this socket. + + This is a read-only edge-triggered file descriptor for both read and write events on this socket. + It is important that all available events be consumed when an event is detected, + otherwise the read event will not trigger again. + + .. versionadded:: 17.0 + """ + return self.FD + + def subscribe(self, topic): + """Subscribe to a topic + + Only for SUB sockets. + + .. versionadded:: 15.3 + """ + if isinstance(topic, unicode): + topic = topic.encode('utf8') + self.set(zmq.SUBSCRIBE, topic) + + def unsubscribe(self, topic): + """Unsubscribe from a topic + + Only for SUB sockets. + + .. versionadded:: 15.3 + """ + if isinstance(topic, unicode): + topic = topic.encode('utf8') + self.set(zmq.UNSUBSCRIBE, topic) + + def set_string(self, option, optval, encoding='utf-8'): + """Set socket options with a unicode object. + + This is simply a wrapper for setsockopt to protect from encoding ambiguity. + + See the 0MQ documentation for details on specific options. + + Parameters + ---------- + option : int + The name of the option to set. Can be any of: SUBSCRIBE, + UNSUBSCRIBE, IDENTITY + optval : unicode string (unicode on py2, str on py3) + The value of the option to set. + encoding : str + The encoding to be used, default is utf8 + """ + if not isinstance(optval, unicode): + raise TypeError("unicode strings only") + return self.set(option, optval.encode(encoding)) + + setsockopt_unicode = setsockopt_string = set_string + + def get_string(self, option, encoding='utf-8'): + """Get the value of a socket option. + + See the 0MQ documentation for details on specific options. + + Parameters + ---------- + option : int + The option to retrieve. + + Returns + ------- + optval : unicode string (unicode on py2, str on py3) + The value of the option as a unicode string. + """ + + if option not in constants.bytes_sockopts: + raise TypeError("option %i will not return a string to be decoded"%option) + return self.getsockopt(option).decode(encoding) + + getsockopt_unicode = getsockopt_string = get_string + + def bind_to_random_port(self, addr, min_port=49152, max_port=65536, max_tries=100): + """Bind this socket to a random port in a range. + + If the port range is unspecified, the system will choose the port. + + Parameters + ---------- + addr : str + The address string without the port to pass to ``Socket.bind()``. + min_port : int, optional + The minimum port in the range of ports to try (inclusive). + max_port : int, optional + The maximum port in the range of ports to try (exclusive). + max_tries : int, optional + The maximum number of bind attempts to make. + + Returns + ------- + port : int + The port the socket was bound to. + + Raises + ------ + ZMQBindError + if `max_tries` reached before successful bind + """ + if hasattr(constants, 'LAST_ENDPOINT') and min_port == 49152 and max_port == 65536: + # if LAST_ENDPOINT is supported, and min_port / max_port weren't specified, + # we can bind to port 0 and let the OS do the work + self.bind("%s:*" % addr) + url = self.last_endpoint.decode('ascii', 'replace') + _, port_s = url.rsplit(':', 1) + return int(port_s) + + for i in range(max_tries): + try: + port = random.randrange(min_port, max_port) + self.bind('%s:%s' % (addr, port)) + except ZMQError as exception: + en = exception.errno + if en == zmq.EADDRINUSE: + continue + elif sys.platform == 'win32' and en == errno.EACCES: + continue + else: + raise + else: + return port + raise ZMQBindError("Could not bind socket to random port.") + + def get_hwm(self): + """Get the High Water Mark. + + On libzmq ≥ 3, this gets SNDHWM if available, otherwise RCVHWM + """ + major = zmq.zmq_version_info()[0] + if major >= 3: + # return sndhwm, fallback on rcvhwm + try: + return self.getsockopt(zmq.SNDHWM) + except zmq.ZMQError: + pass + + return self.getsockopt(zmq.RCVHWM) + else: + return self.getsockopt(zmq.HWM) + + def set_hwm(self, value): + """Set the High Water Mark. + + On libzmq ≥ 3, this sets both SNDHWM and RCVHWM + + + .. warning:: + + New values only take effect for subsequent socket + bind/connects. + """ + major = zmq.zmq_version_info()[0] + if major >= 3: + raised = None + try: + self.sndhwm = value + except Exception as e: + raised = e + try: + self.rcvhwm = value + except Exception as e: + raised = e + + if raised: + raise raised + else: + return self.setsockopt(zmq.HWM, value) + + hwm = property(get_hwm, set_hwm, + """Property for High Water Mark. + + Setting hwm sets both SNDHWM and RCVHWM as appropriate. + It gets SNDHWM if available, otherwise RCVHWM. + """ + ) + + #------------------------------------------------------------------------- + # Sending and receiving messages + #------------------------------------------------------------------------- + + def send(self, data, flags=0, copy=True, track=False, routing_id=None, group=None): + """Send a single zmq message frame on this socket. + + This queues the message to be sent by the IO thread at a later time. + + With flags=NOBLOCK, this raises :class:`ZMQError` if the queue is full; + otherwise, this waits until space is available. + See :class:`Poller` for more general non-blocking I/O. + + Parameters + ---------- + data : bytes, Frame, memoryview + The content of the message. This can be any object that provides + the Python buffer API (i.e. `memoryview(data)` can be called). + flags : int + 0, NOBLOCK, SNDMORE, or NOBLOCK|SNDMORE. + copy : bool + Should the message be sent in a copying or non-copying manner. + track : bool + Should the message be tracked for notification that ZMQ has + finished with it? (ignored if copy=True) + routing_id : int + For use with SERVER sockets + group : str + For use with RADIO sockets + + Returns + ------- + None : if `copy` or not track + None if message was sent, raises an exception otherwise. + MessageTracker : if track and not copy + a MessageTracker object, whose `pending` property will + be True until the send is completed. + + Raises + ------ + TypeError + If a unicode object is passed + ValueError + If `track=True`, but an untracked Frame is passed. + ZMQError + If the send does not succeed for any reason (including + if NOBLOCK is set and the outgoing queue is full). + + + .. versionchanged:: 17.0 + + DRAFT support for routing_id and group arguments. + """ + if routing_id is not None: + if not isinstance(data, zmq.Frame): + data = zmq.Frame(data, track=track, copy=copy or None, + copy_threshold=self.copy_threshold) + data.routing_id = routing_id + if group is not None: + if not isinstance(data, zmq.Frame): + data = zmq.Frame(data, track=track, copy=copy or None, + copy_threshold=self.copy_threshold) + data.group = group + return super(Socket, self).send(data, flags=flags, copy=copy, track=track) + + def send_multipart(self, msg_parts, flags=0, copy=True, track=False, **kwargs): + """Send a sequence of buffers as a multipart message. + + The zmq.SNDMORE flag is added to all msg parts before the last. + + Parameters + ---------- + msg_parts : iterable + A sequence of objects to send as a multipart message. Each element + can be any sendable object (Frame, bytes, buffer-providers) + flags : int, optional + Any valid flags for :func:`Socket.send`. + SNDMORE is added automatically for frames before the last. + copy : bool, optional + Should the frame(s) be sent in a copying or non-copying manner. + If copy=False, frames smaller than self.copy_threshold bytes + will be copied anyway. + track : bool, optional + Should the frame(s) be tracked for notification that ZMQ has + finished with it (ignored if copy=True). + + Returns + ------- + None : if copy or not track + MessageTracker : if track and not copy + a MessageTracker object, whose `pending` property will + be True until the last send is completed. + """ + # typecheck parts before sending: + for i,msg in enumerate(msg_parts): + if isinstance(msg, (zmq.Frame, bytes, memoryview)): + continue + try: + memoryview(msg) + except Exception: + rmsg = repr(msg) + if len(rmsg) > 32: + rmsg = rmsg[:32] + '...' + raise TypeError( + "Frame %i (%s) does not support the buffer interface." % ( + i, rmsg, + )) + for msg in msg_parts[:-1]: + self.send(msg, SNDMORE|flags, copy=copy, track=track) + # Send the last part without the extra SNDMORE flag. + return self.send(msg_parts[-1], flags, copy=copy, track=track) + + def recv_multipart(self, flags=0, copy=True, track=False): + """Receive a multipart message as a list of bytes or Frame objects + + Parameters + ---------- + flags : int, optional + Any valid flags for :func:`Socket.recv`. + copy : bool, optional + Should the message frame(s) be received in a copying or non-copying manner? + If False a Frame object is returned for each part, if True a copy of + the bytes is made for each frame. + track : bool, optional + Should the message frame(s) be tracked for notification that ZMQ has + finished with it? (ignored if copy=True) + + Returns + ------- + msg_parts : list + A list of frames in the multipart message; either Frames or bytes, + depending on `copy`. + + Raises + ------ + ZMQError + for any of the reasons :func:`~Socket.recv` might fail + """ + parts = [self.recv(flags, copy=copy, track=track)] + # have first part already, only loop while more to receive + while self.getsockopt(zmq.RCVMORE): + part = self.recv(flags, copy=copy, track=track) + parts.append(part) + + return parts + + def _deserialize(self, recvd, load): + """Deserialize a received message + + Override in subclass (e.g. Futures) if recvd is not the raw bytes. + + The default implementation expects bytes and returns the deserialized message immediately. + + Parameters + ---------- + + load: callable + Callable that deserializes bytes + recvd: + The object returned by self.recv + + """ + return load(recvd) + + def send_serialized(self, msg, serialize, flags=0, copy=True, **kwargs): + """Send a message with a custom serialization function. + + .. versionadded:: 17 + + Parameters + ---------- + msg : The message to be sent. Can be any object serializable by `serialize`. + serialize : callable + The serialization function to use. + serialize(msg) should return an iterable of sendable message frames + (e.g. bytes objects), which will be passed to send_multipart. + flags : int, optional + Any valid flags for :func:`Socket.send`. + copy : bool, optional + Whether to copy the frames. + + """ + frames = serialize(msg) + return self.send_multipart(frames, flags=flags, copy=copy, **kwargs) + + def recv_serialized(self, deserialize, flags=0, copy=True): + """Receive a message with a custom deserialization function. + + .. versionadded:: 17 + + Parameters + ---------- + deserialize : callable + The deserialization function to use. + deserialize will be called with one argument: the list of frames + returned by recv_multipart() and can return any object. + flags : int, optional + Any valid flags for :func:`Socket.recv`. + copy : bool, optional + Whether to recv bytes or Frame objects. + + Returns + ------- + obj : object + The object returned by the deserialization function. + + Raises + ------ + ZMQError + for any of the reasons :func:`~Socket.recv` might fail + """ + frames = self.recv_multipart(flags=flags, copy=copy) + return self._deserialize(frames, deserialize) + + def send_string(self, u, flags=0, copy=True, encoding='utf-8', **kwargs): + """Send a Python unicode string as a message with an encoding. + + 0MQ communicates with raw bytes, so you must encode/decode + text (unicode on py2, str on py3) around 0MQ. + + Parameters + ---------- + u : Python unicode string (unicode on py2, str on py3) + The unicode string to send. + flags : int, optional + Any valid flags for :func:`Socket.send`. + encoding : str [default: 'utf-8'] + The encoding to be used + """ + if not isinstance(u, basestring): + raise TypeError("unicode/str objects only") + return self.send(u.encode(encoding), flags=flags, copy=copy, **kwargs) + + send_unicode = send_string + + def recv_string(self, flags=0, encoding='utf-8'): + """Receive a unicode string, as sent by send_string. + + Parameters + ---------- + flags : int + Any valid flags for :func:`Socket.recv`. + encoding : str [default: 'utf-8'] + The encoding to be used + + Returns + ------- + s : unicode string (unicode on py2, str on py3) + The Python unicode string that arrives as encoded bytes. + + Raises + ------ + ZMQError + for any of the reasons :func:`~Socket.recv` might fail + """ + msg = self.recv(flags=flags) + return self._deserialize(msg, lambda buf: buf.decode(encoding)) + + recv_unicode = recv_string + + def send_pyobj(self, obj, flags=0, protocol=DEFAULT_PROTOCOL, **kwargs): + """Send a Python object as a message using pickle to serialize. + + Parameters + ---------- + obj : Python object + The Python object to send. + flags : int + Any valid flags for :func:`Socket.send`. + protocol : int + The pickle protocol number to use. The default is pickle.DEFAULT_PROTOCOL + where defined, and pickle.HIGHEST_PROTOCOL elsewhere. + """ + msg = pickle.dumps(obj, protocol) + return self.send(msg, flags=flags, **kwargs) + + def recv_pyobj(self, flags=0): + """Receive a Python object as a message using pickle to serialize. + + Parameters + ---------- + flags : int + Any valid flags for :func:`Socket.recv`. + + Returns + ------- + obj : Python object + The Python object that arrives as a message. + + Raises + ------ + ZMQError + for any of the reasons :func:`~Socket.recv` might fail + """ + msg = self.recv(flags) + return self._deserialize(msg, pickle.loads) + + def send_json(self, obj, flags=0, **kwargs): + """Send a Python object as a message using json to serialize. + + Keyword arguments are passed on to json.dumps + + Parameters + ---------- + obj : Python object + The Python object to send + flags : int + Any valid flags for :func:`Socket.send` + """ + send_kwargs = {} + for key in ('routing_id', 'group'): + if key in kwargs: + send_kwargs[key] = kwargs.pop(key) + msg = jsonapi.dumps(obj, **kwargs) + return self.send(msg, flags=flags, **send_kwargs) + + def recv_json(self, flags=0, **kwargs): + """Receive a Python object as a message using json to serialize. + + Keyword arguments are passed on to json.loads + + Parameters + ---------- + flags : int + Any valid flags for :func:`Socket.recv`. + + Returns + ------- + obj : Python object + The Python object that arrives as a message. + + Raises + ------ + ZMQError + for any of the reasons :func:`~Socket.recv` might fail + """ + msg = self.recv(flags) + return self._deserialize(msg, lambda buf: jsonapi.loads(buf, **kwargs)) + + _poller_class = Poller + + def poll(self, timeout=None, flags=POLLIN): + """Poll the socket for events. + See :class:`Poller` to wait for multiple sockets at once. + + Parameters + ---------- + timeout : int [default: None] + The timeout (in milliseconds) to wait for an event. If unspecified + (or specified None), will wait forever for an event. + flags : int [default: POLLIN] + POLLIN, POLLOUT, or POLLIN|POLLOUT. The event flags to poll for. + + Returns + ------- + event_mask : int + The poll event mask (POLLIN, POLLOUT), + 0 if the timeout was reached without an event. + """ + + if self.closed: + raise ZMQError(ENOTSUP) + + p = self._poller_class() + p.register(self, flags) + evts = dict(p.poll(timeout)) + # return 0 if no events, otherwise return event bitfield + return evts.get(self, 0) + + def get_monitor_socket(self, events=None, addr=None): + """Return a connected PAIR socket ready to receive the event notifications. + + .. versionadded:: libzmq-4.0 + .. versionadded:: 14.0 + + Parameters + ---------- + events : int [default: ZMQ_EVENT_ALL] + The bitmask defining which events are wanted. + addr : string [default: None] + The optional endpoint for the monitoring sockets. + + Returns + ------- + socket : (PAIR) + The socket is already connected and ready to receive messages. + """ + # safe-guard, method only available on libzmq >= 4 + if zmq.zmq_version_info() < (4,): + raise NotImplementedError("get_monitor_socket requires libzmq >= 4, have %s" % zmq.zmq_version()) + + # if already monitoring, return existing socket + if self._monitor_socket: + if self._monitor_socket.closed: + self._monitor_socket = None + else: + return self._monitor_socket + + if addr is None: + # create endpoint name from internal fd + addr = "inproc://monitor.s-%d" % self.FD + if events is None: + # use all events + events = zmq.EVENT_ALL + # attach monitoring socket + self.monitor(addr, events) + # create new PAIR socket and connect it + self._monitor_socket = self.context.socket(zmq.PAIR) + self._monitor_socket.connect(addr) + return self._monitor_socket + + def disable_monitor(self): + """Shutdown the PAIR socket (created using get_monitor_socket) + that is serving socket events. + + .. versionadded:: 14.4 + """ + self._monitor_socket = None + self.monitor(None, 0) + + +__all__ = ['Socket'] diff --git a/.venv/lib/python3.8/site-packages/zmq/sugar/stopwatch.py b/.venv/lib/python3.8/site-packages/zmq/sugar/stopwatch.py new file mode 100644 index 00000000..55cc9da3 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/zmq/sugar/stopwatch.py @@ -0,0 +1,31 @@ +"""Deprecated Stopwatch implementation""" + +# Copyright (c) PyZMQ Development Team. +# Distributed under the terms of the Modified BSD License. + +class Stopwatch(object): + """Deprecated zmq.Stopwatch implementation + + You can use Python's builtin timers (time.monotonic, etc.). + """ + def __init__(self): + import warnings + warnings.warn("zmq.Stopwatch is deprecated. Use stdlib time.monotonic and friends instead", + DeprecationWarning, stacklevel=2, + ) + self._start = 0 + import time + try: + self._monotonic = time.monotonic + except AttributeError: + self._monotonic = time.time + + def start(self): + """Start the counter""" + self._start = self._monotonic() + + def stop(self): + """Return time since start in microseconds""" + stop = self._monotonic() + return int(1e6 * (stop - self._start)) + diff --git a/.venv/lib/python3.8/site-packages/zmq/sugar/tracker.py b/.venv/lib/python3.8/site-packages/zmq/sugar/tracker.py new file mode 100644 index 00000000..bca39031 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/zmq/sugar/tracker.py @@ -0,0 +1,122 @@ +"""Tracker for zero-copy messages with 0MQ.""" + +# Copyright (C) PyZMQ Developers +# Distributed under the terms of the Modified BSD License. + +import time + +try: + # below 3.3 + from threading import _Event as Event +except (ImportError, AttributeError): + # python throws ImportError, cython throws AttributeError + from threading import Event + +from zmq.error import NotDone +from zmq.backend import Frame + +class MessageTracker(object): + """MessageTracker(*towatch) + + A class for tracking if 0MQ is done using one or more messages. + + When you send a 0MQ message, it is not sent immediately. The 0MQ IO thread + sends the message at some later time. Often you want to know when 0MQ has + actually sent the message though. This is complicated by the fact that + a single 0MQ message can be sent multiple times using different sockets. + This class allows you to track all of the 0MQ usages of a message. + + Parameters + ---------- + towatch : Event, MessageTracker, Message instances. + This objects to track. This class can track the low-level + Events used by the Message class, other MessageTrackers or + actual Messages. + """ + events = None + peers = None + + def __init__(self, *towatch): + """MessageTracker(*towatch) + + Create a message tracker to track a set of mesages. + + Parameters + ---------- + *towatch : tuple of Event, MessageTracker, Message instances. + This list of objects to track. This class can track the low-level + Events used by the Message class, other MessageTrackers or + actual Messages. + """ + self.events = set() + self.peers = set() + for obj in towatch: + if isinstance(obj, Event): + self.events.add(obj) + elif isinstance(obj, MessageTracker): + self.peers.add(obj) + elif isinstance(obj, Frame): + if not obj.tracker: + raise ValueError("Not a tracked message") + self.peers.add(obj.tracker) + else: + raise TypeError("Require Events or Message Frames, not %s"%type(obj)) + + @property + def done(self): + """Is 0MQ completely done with the message(s) being tracked?""" + for evt in self.events: + if not evt.is_set(): + return False + for pm in self.peers: + if not pm.done: + return False + return True + + def wait(self, timeout=-1): + """mt.wait(timeout=-1) + + Wait for 0MQ to be done with the message or until `timeout`. + + Parameters + ---------- + timeout : float [default: -1, wait forever] + Maximum time in (s) to wait before raising NotDone. + + Returns + ------- + None + if done before `timeout` + + Raises + ------ + NotDone + if `timeout` reached before I am done. + """ + tic = time.time() + if timeout is False or timeout < 0: + remaining = 3600*24*7 # a week + else: + remaining = timeout + done = False + for evt in self.events: + if remaining < 0: + raise NotDone + evt.wait(timeout=remaining) + if not evt.is_set(): + raise NotDone + toc = time.time() + remaining -= (toc-tic) + tic = toc + + for peer in self.peers: + if remaining < 0: + raise NotDone + peer.wait(timeout=remaining) + toc = time.time() + remaining -= (toc-tic) + tic = toc + +_FINISHED_TRACKER = MessageTracker() + +__all__ = ['MessageTracker', '_FINISHED_TRACKER'] diff --git a/.venv/lib/python3.8/site-packages/zmq/sugar/version.py b/.venv/lib/python3.8/site-packages/zmq/sugar/version.py new file mode 100644 index 00000000..3a556821 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/zmq/sugar/version.py @@ -0,0 +1,48 @@ +"""PyZMQ and 0MQ version functions.""" + +# Copyright (C) PyZMQ Developers +# Distributed under the terms of the Modified BSD License. + + +from zmq.backend import zmq_version_info + + +VERSION_MAJOR = 20 +VERSION_MINOR = 0 +VERSION_PATCH = 0 +VERSION_EXTRA = "" +__version__ = '%i.%i.%i' % (VERSION_MAJOR, VERSION_MINOR, VERSION_PATCH) + +if VERSION_EXTRA: + __version__ = "%s.%s" % (__version__, VERSION_EXTRA) + version_info = (VERSION_MAJOR, VERSION_MINOR, VERSION_PATCH, float('inf')) +else: + version_info = (VERSION_MAJOR, VERSION_MINOR, VERSION_PATCH) + +__revision__ = '' + +def pyzmq_version(): + """return the version of pyzmq as a string""" + if __revision__: + return '@'.join([__version__,__revision__[:6]]) + else: + return __version__ + +def pyzmq_version_info(): + """return the pyzmq version as a tuple of at least three numbers + + If pyzmq is a development version, `inf` will be appended after the third integer. + """ + return version_info + + +def zmq_version(): + """return the version of libzmq as a string""" + return "%i.%i.%i" % zmq_version_info() + + +__all__ = ['zmq_version', 'zmq_version_info', + 'pyzmq_version','pyzmq_version_info', + '__version__', '__revision__' +] + diff --git a/.venv/lib/python3.8/site-packages/zmq/tests/__init__.py b/.venv/lib/python3.8/site-packages/zmq/tests/__init__.py new file mode 100644 index 00000000..bd9105e2 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/zmq/tests/__init__.py @@ -0,0 +1,192 @@ +# Copyright (c) PyZMQ Developers. +# Distributed under the terms of the Modified BSD License. + +import sys +import time +from threading import Thread + +from unittest import TestCase +try: + from unittest import SkipTest +except ImportError: + from unittest2 import SkipTest + +from pytest import mark +import zmq +from zmq.utils import jsonapi + +try: + import gevent + from zmq import green as gzmq + have_gevent = True +except ImportError: + have_gevent = False + + +PYPY = 'PyPy' in sys.version + +#----------------------------------------------------------------------------- +# skip decorators (directly from unittest) +#----------------------------------------------------------------------------- + +_id = lambda x: x + +skip_pypy = mark.skipif(PYPY, reason="Doesn't work on PyPy") +require_zmq_4 = mark.skipif(zmq.zmq_version_info() < (4,), reason="requires zmq >= 4") + +#----------------------------------------------------------------------------- +# Base test class +#----------------------------------------------------------------------------- + +class BaseZMQTestCase(TestCase): + green = False + teardown_timeout = 10 + + @property + def Context(self): + if self.green: + return gzmq.Context + else: + return zmq.Context + + def socket(self, socket_type): + s = self.context.socket(socket_type) + self.sockets.append(s) + return s + + def setUp(self): + super(BaseZMQTestCase, self).setUp() + if self.green and not have_gevent: + raise SkipTest("requires gevent") + self.context = self.Context.instance() + self.sockets = [] + + def tearDown(self): + contexts = set([self.context]) + while self.sockets: + sock = self.sockets.pop() + contexts.add(sock.context) # in case additional contexts are created + sock.close(0) + for ctx in contexts: + t = Thread(target=ctx.term) + t.daemon = True + t.start() + t.join(timeout=self.teardown_timeout) + if t.is_alive(): + # reset Context.instance, so the failure to term doesn't corrupt subsequent tests + zmq.sugar.context.Context._instance = None + raise RuntimeError("context could not terminate, open sockets likely remain in test") + super(BaseZMQTestCase, self).tearDown() + + def create_bound_pair(self, type1=zmq.PAIR, type2=zmq.PAIR, interface='tcp://127.0.0.1'): + """Create a bound socket pair using a random port.""" + s1 = self.context.socket(type1) + s1.setsockopt(zmq.LINGER, 0) + port = s1.bind_to_random_port(interface) + s2 = self.context.socket(type2) + s2.setsockopt(zmq.LINGER, 0) + s2.connect('%s:%s' % (interface, port)) + self.sockets.extend([s1,s2]) + return s1, s2 + + def ping_pong(self, s1, s2, msg): + s1.send(msg) + msg2 = s2.recv() + s2.send(msg2) + msg3 = s1.recv() + return msg3 + + def ping_pong_json(self, s1, s2, o): + if jsonapi.jsonmod is None: + raise SkipTest("No json library") + s1.send_json(o) + o2 = s2.recv_json() + s2.send_json(o2) + o3 = s1.recv_json() + return o3 + + def ping_pong_pyobj(self, s1, s2, o): + s1.send_pyobj(o) + o2 = s2.recv_pyobj() + s2.send_pyobj(o2) + o3 = s1.recv_pyobj() + return o3 + + def assertRaisesErrno(self, errno, func, *args, **kwargs): + try: + func(*args, **kwargs) + except zmq.ZMQError as e: + self.assertEqual(e.errno, errno, "wrong error raised, expected '%s' \ +got '%s'" % (zmq.ZMQError(errno), zmq.ZMQError(e.errno))) + else: + self.fail("Function did not raise any error") + + def _select_recv(self, multipart, socket, **kwargs): + """call recv[_multipart] in a way that raises if there is nothing to receive""" + if zmq.zmq_version_info() >= (3,1,0): + # zmq 3.1 has a bug, where poll can return false positives, + # so we wait a little bit just in case + # See LIBZMQ-280 on JIRA + time.sleep(0.1) + + r,w,x = zmq.select([socket], [], [], timeout=kwargs.pop('timeout', 5)) + assert len(r) > 0, "Should have received a message" + kwargs['flags'] = zmq.DONTWAIT | kwargs.get('flags', 0) + + recv = socket.recv_multipart if multipart else socket.recv + return recv(**kwargs) + + def recv(self, socket, **kwargs): + """call recv in a way that raises if there is nothing to receive""" + return self._select_recv(False, socket, **kwargs) + + def recv_multipart(self, socket, **kwargs): + """call recv_multipart in a way that raises if there is nothing to receive""" + return self._select_recv(True, socket, **kwargs) + + +class PollZMQTestCase(BaseZMQTestCase): + pass + +class GreenTest: + """Mixin for making green versions of test classes""" + green = True + teardown_timeout = 10 + + def assertRaisesErrno(self, errno, func, *args, **kwargs): + if errno == zmq.EAGAIN: + raise SkipTest("Skipping because we're green.") + try: + func(*args, **kwargs) + except zmq.ZMQError: + e = sys.exc_info()[1] + self.assertEqual(e.errno, errno, "wrong error raised, expected '%s' \ +got '%s'" % (zmq.ZMQError(errno), zmq.ZMQError(e.errno))) + else: + self.fail("Function did not raise any error") + + def tearDown(self): + contexts = set([self.context]) + while self.sockets: + sock = self.sockets.pop() + contexts.add(sock.context) # in case additional contexts are created + sock.close() + try: + gevent.joinall( + [gevent.spawn(ctx.term) for ctx in contexts], + timeout=self.teardown_timeout, + raise_error=True, + ) + except gevent.Timeout: + raise RuntimeError("context could not terminate, open sockets likely remain in test") + + def skip_green(self): + raise SkipTest("Skipping because we are green") + +def skip_green(f): + def skipping_test(self, *args, **kwargs): + if self.green: + raise SkipTest("Skipping because we are green") + else: + return f(self, *args, **kwargs) + return skipping_test diff --git a/.venv/lib/python3.8/site-packages/zmq/tests/__pycache__/__init__.cpython-38.pyc b/.venv/lib/python3.8/site-packages/zmq/tests/__pycache__/__init__.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..71e49070f35d1734aa3a29131cd885705de06895 GIT binary patch literal 6477 zcmbtY%a7Z}8RzgN>ap+j+KwHEX_`1nf1>3-p%Z z7)6lFULJ4hM@pH|BxWyFulf72fds_+BThw9%`BuRx$X*r{og&)Ipwyaj zrm*5sys==~nZ`306k9XSEJj++99BOxT>VeO)$`8WaMgmZH0GP8v%rhI^iXjY{X*k_ zzrd&X^dr?-l5fSq!7YW)G!;H8TMu1T_#B^qsPK8;c%V6l@xH(p@xJIE#``mPKfssp zzVtwKj_`y05LQ0Q*-fQ<_%X?Dwaij;?XK`Wj+(XR$H_%6_P0^L*{rwe9qoF{6HPpG zjW`Oub{$otCVW3!yOQeHyVtuFNPOob8P;Y(o^$B*~LER+3hG zrCo2I=!9*r()9U>^}D_woY*+CvC%#A_L-Gl>)uL&O~fm%TMz4r>n^vusdYB+T6eg2 z&c;&zMp48xNN@2{kpL&%rUvaO~^F&Q>Dsyj$02c$CC9tFQA@> z-ilOsv8wSBpL)og5})QXm@@?}&fz)D=lKGjGklRBz;l)_@q>8I@k9JDp7Z<}egw~j zpDH@+0=hez&b$vTIiGwsQrMNpbT*!@h9&g&m4+fp32Ue~l|&=Tp%_6E%etV`lj=1{ zB+Xrn!o=T5QVnn0P=D+P)v?;d6o!feASX~_6GTx>W~#k|6T4a-E>uxz%OkwOTZ}1v>~OfdG*=mJ$&4e|Ns{KWXPlZ|yX}X(tO;O(k`}Xe zH|e(hl*N;~egj^=19c0=j%{ngPW0GL z49*^~pP;W{4su)QajhEBJPEt3uJ&ejtgq(Z_rs)INR7DD_Jx=y28`HGK5u90DBkt% z`))Q&80eK!Ppx_wCtg_b#bIhYLgXL_RF!w#O5nw@>t>uwRoUo!8zq+b$);I>S;Y8( zeT>tm_wY?0r87gk$G-+ih*wqvkDJ7!Dozs}Xj=-D#|C;|Z9tKvya6OZwR@#LyQF;e z!KRj&eXWt>>La$PbFHttR$m|FrTp|p0qYdG{)p!4gVL5F-r`C!)tGLu#*90g%yEO{ zdhe}dK3R~GU!<8*s^+R7z@d|#c%tSfYY;^)ski*7lRSBEXghW#>IB>lqr^^p(W-}D z;=gJ~upWD8Om zfer!Lg9$p#EVYET-l0j`7=5uflT_O8tgM_o_2%+x_&Zr4`xyOlsF2Ob!+jSOXmxbB zb?8+E@aV7$RchJjYdG}Aa10Lprr9_5j4=l$SNmGusH#hfv@4~N8^CV*W-S8=)T#iA zvesL<2$)ZN+q3UPosbWeYPY?*usd-*tf5DEA&**iI}*vVw3(jqV*JjFaXFupg;$WU!Pwy^dkh7a+G(1=R!@FXicqo2;gJ6IjU5_p|FvF*}0Cr`Y~>h?YX zu*gxPQz-jbpWb0cPOT9C6tpOk_Z=A=d#VhwX}b^G|Eo&}h7P9M-RMrkDM+qlU0lMp zCRH~x-oG3a5CfS*+1dPaPv5+pQz6S6{b=_kluuD&f{NaBpN_izHEa=~@`t)qY!-@d zQmFn)Um2) zfDzhox{&}V)MKB&YWo{)oMWHc$6t((+co$Jsywl;biztfhlTKZ=04;E+Y7td0n3y@G_ zH3e~u2Ct6TcT45QBmGNlQ{OZ;P55>F0pn&>id| zfgh&R7o;&@xHJyOy7cMl+7}nDt)&`5m2_Gjyd8$c1xzeknOo0~o5?dtH;^)svUNd6 zM~Fbt(mE)CB2}2k1et#6<*`$085fX(i-=$Xj!S>s7U{O3kUg zcXu@RU9@#&n~4e*-p)dJvBT*EXOi2W6GJkcP@Br@!B(e{g78{Y@=drbfVr{%h#*YaIAEx0b6P$!^z$#n@)vL2Zth?7`0wb}w< ztVp^tfXoDFqeD=Fp}gyDEl>8WD09yF@&ea}ynuq(}p?n4tH4-zDQYPlH|q8GkoR?YZU{T;~ST zZIhckhbNMHp2yST1?;Vu=C8_|4aNXu&y2FY6ydx#FP9Ra2=(3Uxw zAFqi8d~**7@9}~g==r+{Ej$yh0)yjSYkiHSUw zarGh8aS8W4m|>CMdnCh)@EBBJHu6wGd#Hj!mYt4n2w^DZ>YhZJtd86caT?Q21zie! zHM=>CV;YD~ex=^i5oeQB%35k>X+PXb+glIC32IeSb@?^%CaMzxObcg&dYn|ER{Pwa z(JimtOhr|CFOB6k%HWpI1`#kXK8MO^(pp)SuF)yV*v3W3f`s#B`e;$mF&}5Y(zA&l zP}{3S+8_v)k>|0Q1E$>k#Hi&!>$HJ9|;4c`H zxgXYB9Pej5U=_z=FH)sB*X2_(X z)U$_iVw%jJicAva1tgiTg-aR=uC%?zI2ueB3i0Om}XL}~k(KnS?R^Yq2s5d9tf`t9qt z9nGzC$0WY$Rb-K5N$qaCD{f(|Gc~*mbSb7hE&Zf)T2jZ7nQyZV+<#{w!8tNn>BlU( i!NJvl3e3dC0BZEE5=Fs9G`;Ke<7klte-X8WKc3L=7dlSLRs$R)I$jGNt_Bqr&d=|Mrz ztM9OL^o2b1)ziF!CoAm=TTp*gQTbB!ZZah%6xZX`yhQN8lzY0W9RCij4o;|ij~@i&PjiO zvFL2by!0MwZ%e{b-xw=dR(HX4UN*7gzW^eNNH0PCBQOD70Lmru#}JWgD##xD`+_bJ zAkjAYfLM_t;5Q=^>E}v?SkK^a6V+U?{%XLyXR%#@=EH!TVpJ@ zrd3VP9=umtn2le`RyF|hDt5evhBsrq#4g_ECvtbd{dru4wXLkO^G@5kxs+nQIhV4X zZx`Ebzj(T+cI!`7T(_^{zGHN1`{6FI^Y|lvgA;$`qe1i-CpgD$2634V8Rx<@oVy9+ lZ1V4REW0_?*fpZuGE?Xr@@H!!x>i1q3mPXUBquqY;=eGNqrm_G literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/zmq/tests/__pycache__/test_asyncio.cpython-38.pyc b/.venv/lib/python3.8/site-packages/zmq/tests/__pycache__/test_asyncio.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..2bb6d440be21419553eb36d8547435db5600710c GIT binary patch literal 16523 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 IK4D$>Ux@J9`2YX_ literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/zmq/tests/__pycache__/test_auth.cpython-38.pyc b/.venv/lib/python3.8/site-packages/zmq/tests/__pycache__/test_auth.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..5d1d06d7ae06568a9c6b573efc6cb55c1e98e678 GIT binary patch literal 15755 zcmcgzTaX-AdG7AH^~}!Bj&@hFY-4$B*~UYxl`(c4h%uIA%QlFWkXDu%49#e|cQvEA z`E;)?lUYnzCUz>g3K9ajK(Y&@5|LCcBqUTG@{qjdF_ni-DlfdmmA9BDSEZ8g`%m}W zc19O)FhKgqLPq%vXYd0s*;j>x{|@&YTB)AC2O*8qM2*WRpz9gZ01|@mHAeoQfMty z7EI%L!%eyAHw-uJ&0kAYig?brHlA&-i03`-qMLK)-Y_eRZr+`L!>BB|1$P1WWqet5 z_u$Jt^5tIFJY$rX-T~akYS|2z)-EWo>K@q)E_m&rUaJNjg=TZJoCp_=R(-GX>Cdcr zesB!c&^~jq-sMx6^-*)WSG!kh9BK5Ih#veGQ1J}nqhh^jtedXsT5s6EN5V}4vZS*9 z2ljT>P41Z6xxjAB?U<&~H@5RTD4qGf(U{*Z@GG<}>=>^k&|1W`2iKx&0Q%Hw*?Nae zqX=j39^b2Ns(Ns>RQF45?{cZ$E;Z}td#zVXkFPx1TN%7o-m9B+<@xd3pi{a~z2ue9 z8>PS5?RHeqv(a&-3e1$3!UXD-A`0h{r~G=S?bO@r9hJhgm3isrT=cGXt94beLE7h( z>ZmY~&CbR~y}c1;H@x5k>YfU1ygK1s@|t1l+2@X)eLl>#suw+n zGlxkjQ+`lYL71or2)>jtb;dBLFJx)~;YuepwU z)^Tdhs_#3_b>qD!4+pL8;cmTqXtUj|)-HPPq01LMuX*Uo6IZTWed41}9L9*V{MASinC}u#3G&x?>!Rx*;&G8Lxx2 z&luNDk)zd4@M5dm^jZ)j&lS9?JMf{pdr*9UwIYfKaQPMr!|dI)YxV(BcR@hr76yMD z6|kM5_OT?RQ*D6V$buHy5@gXJ8Ki`T)B61xL*0Xp<&4^c8!#Pox?x^td6QZTojkLI%a*_{}Qgqzs`9H#N=m!|Zz z(euYMdL{=wf800wiGFfD0mYE*J#b89rF87<>6e}>QDW-rRKpN@$Ze@wB3D=Pqc19R zBXU&9cUAoorHxV*rhN~pL51mBvkp$|C0EcKnk&6IRvayF(59eltGixrdSRw@(d9#E zb^I{dtx}j9oq9V=;YD4kEGQ!kQ&}1j>ljEVin+R?#e4y}NfY%kcYhF0>t|U2S=e6XqPJ z)p0kQtmhr))y-;CzY&WiMnX}&Dl)Aqv3L?iI3HQXn%8VP&Ioj(nnf$qic`A$JPO;) z7wkknW8Z5hMWxr!IQApMK7-4D1x4(xxhC8+xI=W)+@zbr9gdot!9DHTZWi~9IGhma z$l=UJ4rflgo0T~)52tkL4da?wnRl1L9DBq4blrA2oN!WlALN@7eTc{lMPo^Aw%c$) z=p8`~ik~`WKxmLDbHc~kD8uxb*Wlr5LuVRcw#%p9SN}&@K~a z@sGkp?@EB^qT-rcz}*(?*S0}Bv;_;bZMx9-{nWa(&k%Kx+%UJ&_`-5Upmr>E98VA= zh*z5S1%2=i_N0kgMp{h>n*n>4>B|>xdMnYV4avOs(PJ09+Qm|ReIRSqb_t7ad$phh zpD_}~O`q5dYTZ(xs%@XXRot;mCWkNqbE)t`&6Z%yxOJVi*OF^9_-(9l!jQ8?*|y_APVS2&&L>Hs=i*Wd7KFo zCtChS#a6XTn84o{kq3%GI9IE-od^%-(cn{?8dlOwLenq8S)m2U!DY##rT4&0%8v{) z#(?C5G%lh26;wvNF*EkYWRrj`!8W`x(AM0-8>wedhpz^T8t_3(cp>7+jDG1tDLc6v ze=nvb(OcF6;<+M4r9-9FvnNihzDw{nnw|5&=$u$_buU`N%&|x$KF+7K-+@mZXu2g& zojvnHi1NgVFsCW9rZzowf?wu()vg1wSL^NT39W1g6q>|-Hh@e!?agNMRdn^~02oQQ zh*r)b#urn0?JmxixWNFkvHlDO)mVqOsJCSnO%(Ag*nXO7`xY z#NN>+wi$G7-pdX|L($%@ma~!j?0W61>Li-9Njk;a85Xn*F*6^pHo?=xomyitz8eS& zvc&W8WWSD2v^SjqiW1^Yi)x&vG*`y^{^D_T?m|8Ah$Hn9mo|o-R28b@@=Wxo)9i5* zv|NtI|N8BtWzcsvTK2(yfFX>)Y(Vh9F7VYH3MyO3KsYt%TTTk9+j4LgFv&W%)3=dr zz;X4KWaJi%0(EL!ClIGBk+pb$-T5F0h+l{{S zrT@{+#-_hoE=+JonC~{BSFlIn4n|8+K{supjs8&>J;&pzmj`UL2eohk%6`4Rv8g;q zI%+l(jhCu5I~Zk}5avXXq{Fu{ivKtYBdN7h8aiqb!bnkMeR=F@F+qJM+6*TPy@P8r z{2MK*GQ$`@5{Cl=!n2`CRfcDH+AtaBE6FWvf9ZjPhOsG0_pN@~$zVH~c5HBKS}4!A zIrO4$p26D`O7IOza$FwQJU#Z<+%$|v!A+o#(O7Vk5pVuHGvMrN+6-9Bp0V)>HzMLZ}RT0|%?%Y*u`ZE;E)#D|vdrlKSBj)@NaeToi! zF#ij;AUeNcz$YJy4!rVyN<=3mqLUgEo%CCV2v(AUB|*wwnwJ z*AigZ%r#>R9vy|LZ@a0twNDZ=zw$j~3MNa7uM9)m=}Gu~58!ARq?|ocKJjLqul=>A+pgzjtV=S(+*kU1YaTBF$vVmKg zLc$E;88VW%kpp&j$Q06HQ|T8skj#K&j&DY{9B)|h3) zlgl}tki-T&zAq+=Q`>uw+z#)J$pg=t=n5YrOnu;8Tsj^{M>~2vPjQ1`W0P=tjRv-8 zk=vRMG7UswBDXRtjxjb~u;R4ee48J*m059&bK)2yh`U|TZl(WvumGnrvt8u*8#ii= zJ^eIo?%NhDyWLoHQx`4&Px)1^(6_gjT+Wz9NO>PZ%9+M8LdySQVk>4E2qiDRZ1l6i z-hT3$iC+K7UOLFlH9Cmj4WP=wUC+S_NueZEIfj-2RgV4!oZY(wt{mWs0?@nQn!CvF zj!uDWe+=2zOm$%ZTamE2dFgdUAe)D!FQ|*4gWl8A`&CU8Yoc<=N5{(u($+fNtG&!w zY^V;s=#J46)WgCf3q>`pLm#V%NNpnE*b?4^#?D2@?$b=tQ_X7Yyjy+xECzZPLm0h} z-wJPWm*~{pp#u<)<8#+a*dJ40L2b2s$5c61c&7tX!&4oeKy}oYp*!#76+*WNtsFnUM2oPWh+UI}`P*WHb&R zn^3LcBG($pd-Uy-K&5{iy$$iV^9Xpw0v+Fr*v#@k)WTK7wzinaLp9K^hewYv8C&@d z2d7r=mu`a~-0F{;{V?O;6tRW~Mv)5_G@fPcvn)QxqQT-4i)$?Cn5eI^7@CoR5?4>* z#VfePC9>hY*a>^V-fPd{?;-m!`(x4nc`*`@je`9(Yc!$0b;=-AF$7y0IVXljVTO93q)m9~gG!o(LMO0dz z?^idliQTN#JkJdmM%vb^^(G`6n*pbZkhBUHs{v!nU`8E{z;={rB#a068{sm#3abY7 zme<(~9QF_Im~4$^QY2Am^BeZABv~u#Q|QoCl_cTDsZ+tb(uHx=0Qv}tx4hs&$JLA@ z_Ha%n)y)kG23rl&w$g|L6s>{;^mNVUw$|zip`Ch%Qw;UX$S_*1CDgYukop4_-(evv z`unWuiODa~Fi^wVk2S2qKJ|zAW|tl%3mwB1Wt{Y(ORteBt<^Q`N7w~7nQHdgW;qK)oei8~fh-{;;T^#!l!?sxB$`X033<=!pz zMYMmwy+`UxXg}cIEA?fxm)!fLz8CfT-Gfr!hi@KmAC&qXs6XU>Q0n_7Rqakt=V2Y^ z)GFb~SV*(?;2PA%#3p$(&Z#+Uj6_5nog?0T(!5ushH4ru=#oJun+2z1MH}`2$uq8` z!stvke4T8jTInrl1xXUhAk=8@aIc#UaseD8WVy-NF|@>dP-rada63|rp7zMoBDBjA zGzeN7&@Xtu9JMSCTJ}b{Zj$5%FCnd0(<`2i)7YRy+f}!NcUdHCY3)+pSII=}>ibw; zIEOqc#P-BohUqSCDFTa3IIPU0*9tPw+5rVo{V_gQzl)-h*4S2GV+(gw>U%8cSWXj&|+l7)djBWjK+&%dC7QeVfrNVf=7dagS;o=5`4OosnWGCs|>0prNLGGvfI zXJ}JOW7#`Enor|~DS2j;QyPt9xI`#n7MrB1$un)^Rx(`}})cBB5deT~ESwyQYI;9|@47!{Em{d6$>Zy$cpG zHF2$hv@b4~M`pWI*UC83fZLd%ZCQ8yD2Yv?nVRZ#3_U{n`}imccoRh9i|+uav8=U% z*}HEhnWkp1aXEA=g;Ecrg1A5F6Q%qx*4VJNkqN*6&mitE(MI(&K3AV$@eGR9a#Azp zQMMdp!9ip0dyx&FWHCXSZ=mh_T!e6=1^&C@Q(5*S1D6V-!8pFZM}eVygtKO<<=dv}bZaFB{J znr4yI7(GXL?`JU+a&D>rb%0fbwRN)HR3jl+9b}{ITEM_FDPhdf1)vUF7bI~KC)v@{ z7cwVYWEIsb7)*U0#oB5)r49T#n>JVo z@jTY1uw8gSC=w+>j0_zmN&JM%7W1F5v3>15Ia9uGJkD%NKMKfZAp+n+*28XHe_x*aVv=1 zHO?;xZReRUQyPhIX^wIMzs^sXM4S5STS1Eq>x>Nh(=oJ=pKb{)yT%zq3%PTkH(tgA zww2T!INP60YY~50pZU{!PCEFH4!NgAK_(HcM+CoNqaBGJxHEZ#_iUtZCPY%=)6+%r zCE{)s0hT9;Df+t;YH0Gz_aHxc6~*=RO%7|vjc_EvI`%TE93ocyU*enxTXHUIJPg87^zco~hH z7kfA-La5oZdd#wKmph9|91Gz=1LJ#7T;vC!{RSk(D_r}WigCT{1qR6 z$l`BU{D{ThvG{uyzsh3BdvXLJM@HYni?=BAPocs{1^z!HiT}??+bOw{cFHnyHm(e= zbaZE(ZM+t66%o(iNM&=ayid{5)&C`P2(>WbU-i|4Z2J=wmBD|9ir|c#1?hAi`4@@G zB2S3;Ph0*94#0w|UF=&E?9FpJ$zJpowYdBvsSd{Q|4bBDAqUYKTY@73HnMiX0@ohe nPwD@8d73uCCl`sb(+UqXXSiuOQGCAmn(>-Z$lZk?PU8Oo(dx<5 literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/zmq/tests/__pycache__/test_cffi_backend.cpython-38.pyc b/.venv/lib/python3.8/site-packages/zmq/tests/__pycache__/test_cffi_backend.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..fc0fd4a18f67a9fe9f950aa877eec1e357563bd1 GIT binary patch literal 7981 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 literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/zmq/tests/__pycache__/test_cython.cpython-38.pyc b/.venv/lib/python3.8/site-packages/zmq/tests/__pycache__/test_cython.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..4cfe39a72781992bbc919afa8b01d3172c5fc215 GIT binary patch literal 1191 zcmY*X%Wm676rBe}Qk1N=X`2>(fj}087PePj1PFo_ZMR;uC<<^xFq*ME5?{G9v?YN8 zirPS&MfwfWGC$PCY`gL=1Sr}&qy?lS%pKl`?woV({Cad05nO}c|4Kji2>IJN@2>!z z?{MoJjUa;NBrS3<$rj#XAef{Je;Eiayf>_mVI z=WNeJBu2O7hPq!83Hl3}j_>hCa=v-ADPEqu$Yx7fij&#eTvp}gv!CV5MuF6EABZ3F zQ)+#XnXXF9uT{Bu@?%wgYhnZI7@E?kLdHLI9pb8te^aHXuC<-ySvhaAxlD6;CG&fZ z*WNQUGxv2^PKW_+7t?oW1k%sRYbuzb3$_gOW5fTTcXZ*If$?|2o(TSiw#0-jyP-&$ zzeeG<{1tgcFPInz|2EuuE!_=UZ%-+4V&qXV+Hy+FxaDGa!}P-S6w!9j^4(F3@@@Ur zZwE`JZ@UaZp+@IG5zo6%oKQw;qaS2S<;tKUV^z-bM#xks&{Lj7TAHR#Gni|@krO+7 z(WqRw^bFnqEtmfoxBdzZawB)-PlEW6@s2wM_6(6b6zm+FL{rZWn^Kk9WO;76UTYf^ zm1uIQEw8KkEqTlAP!)9rMuN7(dcEpBnBd>vJv}u=eOjyfxG8Hlba8xrDP?}VI$N#Q zXHU;gk>zQ}va@Ob08Z+)4e{Qt@0Sj+Lr!Q!H($HrL)o*unq|3uesZY2chaFqQQyZ& zW+xh-S_*P@m39~TSW>LxLeHlY_y`>sIWtCMC*Nx=!KkYI37`TS9H@Ij&5Y%UHW|;Q zNgsxQDrf`AI1}PRm07Mf5-fpFU9aFW)0r^^k;{(W`qpy{@Oh$DESs@KLa;{|$&CR#} g>hOin`gif%O+dRFLK-r+eHs$>ug85Fb?1llKh3{Bd;kCd literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/zmq/tests/__pycache__/test_decorators.cpython-38.pyc b/.venv/lib/python3.8/site-packages/zmq/tests/__pycache__/test_decorators.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f85e5807d568cf6641021f879fd6570d1af16980 GIT binary patch literal 12765 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 literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/zmq/tests/__pycache__/test_device.cpython-38.pyc b/.venv/lib/python3.8/site-packages/zmq/tests/__pycache__/test_device.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e50743471d002eec061a68fb1e616bf73deae6e4 GIT binary patch literal 5388 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 literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/zmq/tests/__pycache__/test_draft.cpython-38.pyc b/.venv/lib/python3.8/site-packages/zmq/tests/__pycache__/test_draft.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..098720597ed2f524022e58499e3f84642678ee55 GIT binary patch literal 1722 zcmZuxOK%)S5bo}I?966uubuEXaIknBR$%*N@el$V+W||#fbH-Yftty5do#PUGvn^w z#cRzy8yn`;ti-mm}i zzdS}f>poJGv`PUP6$ja=wi<_-MFA2gx{C7%=F2=|N# zSNc;Y3IshM9q$4xlD!VA7e0%%jK2KlP-?RU!#dRcwB+Tu94DxAy*XDC{T>V?!5AX; zkQ`A#1v?8M2I~o8@PvOxBJUw_N#ujSM%_jS+bTXX2Sw7CMkn-|X&j?<{Pmk44Cztb zHf-hydQKlu;~K9bQ#SL@2?Y$mCfhrGMWDguxJ;Lac|3~KEWVdX@aCKjj-zmUfAjVs z-~4*F_RFyW|Fw&kt35p|rBVnljHS6-b|`Gg?C3GAL(Y>d)|&IjBt`X}L1Y z%NXJoE5F>AGFv%WKRFq%f4IH|j@Hn$wvyX`R?D#p!T2KH#s@*DPn-1g)#ou-wa%YG z0(bzR5wZop79c7zBZl@E{LVT1kxl4?RdnVeE);fqUd03x&LcK)DyQcQ(hv1VrtyGQ ztmg{Xu6d6b>dw3hPEFhj*85EVj9L~;e@{2Smy*XrxXW#XBPq(U#%Po*voWkRRWUSa z-sP$21odK~WNakAR}6E(%Q#gEl_P)a&hF0MA!L1L|J$8?gf$nnt7I}#ZBVG^H?@|^ zq(#1?RG~Va!bed1NtVjo)IMyEq^g~P?na*Vt>!QaE9Oyk3Gs#`p+3J8eFlDv1yg6?{|5#ygI~~!a#tYW6d-jl5yF|c#-EajXQgi%!kyA> z@>6fpFhSLr(pe}x06(bwS+fdk@>uUi6;zJ!F+Ha(u+};!lkhu|FT0rZxqegqMuG5@ znEBa)XyB)y2v`r&B7zzNh~-OIHbQ?p-{A+eD4Q zxC?nK6~4F&i@X=>Buyc~p55vG@jJFZKfSOjnAFZqg;c&wu)Do`@I~b9Z*K2?6$L68 znRFnF+U*r-UOPbO+Ea1fl`uA{_GO+F0w%E#Y6*?p1QB_g-5AteJPS`Sld`OxOy+ef z&5cxACP)x<3!OJDL7=Fl`aUos7HOg0KqK=&Dw&R?;0ch>KrmNxOFC22R3R^rMaf7! z&!Pp(1Z$3?>19yWZ-YPz`P2paxX}Bw1!O`>F&MRJn>A^Zoi4weSWnGC5ehiZ3L+ctk?$&1QrQ3BFQNdNGp_V7_AWOEQI0G60}-l@1$q@F|nOx z5=|te?3Mp8bL0ClyIL1uL%!CbnYY_PJbkEcmZdUUQCVOKa?Wlv1`KQ*$-VQYiUBI zrLdB>H_YOb*cQ^~T_57rOc!KoImS zVVrXInj{W)xC^7pJ?_Kk@qmXg`n&;mj7$qnFK;!VU|`wsC?EPhboCj42L8_J*W~Ai zXH?TE$Y*RyW=uO%rrmQkr<5FpoPk~E^ivIXH}qkqHV0wSZrNj z0DG}#JegHPAu(bm%9IjP_vNuLQLgez>8u(EDgLY`u}7-hV55mZLN|uWg}-w=Zq3dojYacRC`D!>VQ51^s$~qT4G-|VUQRJ z(_C=UJvz<`j>z`0^R}X(o5jL`h5>nDg+=Dz3jZz&*kD3 zKQYxj=r$>KL70*enNba1&FL8hpIr22|)~sJ&(M4j6-`#t<_f5}u zgQ8X{|96Xe#4j?UV4HJf#==wkLk(V2u|iq|AYQr<^+fbbpy#wc+$ zyd%bg!jW1&L^Wo$d>;W_l^+5ax8FT@CO@*`sLrcp9({}&s^6rm4bKu3%Ro=i`X{hR zVG0t+pbq2_vUa0pR<`uwz=Ua9Wu-_{6QyZc^Wy^LR+?gFFJ|N&Fe>jNJVJ;O{>x}9 zVOq-uz%A%Da3KqQ{H!)!gV*9j8CU0}Fb!>A;Jg}Ib{1q|=xp`atg`$h4ahrN=1K-I xZCbB{RC!&cdG(?;PF`u_7B!f`lizkF6Fy$}^c7}>!pns~N{fZ`9$<&M>|YU|mK*>8 literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/zmq/tests/__pycache__/test_etc.cpython-38.pyc b/.venv/lib/python3.8/site-packages/zmq/tests/__pycache__/test_etc.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e6b909df5947fd7bd7dbe4cb28e99008f282f52b GIT binary patch literal 761 zcmY*X%Z}496!jxXLmxpP)+oz~M5hALkwzLJ5Mo;)AvWGbncAhHc^KQBJ~SgChAscl zF8LuA-m>BsSaI!9QOD9f&ar*(JwDFI!Jvy^gkOK<1A@?RM~+7T;0}%<#qg&EPyu;%kgg@Y2zuV#X1Il`TpemYV z*amf>7Tc%W`pYRqekGJH+a@oYS$mSD7wO5%XV0^#JAD|S7Ey?|5c&+jpdIFTk5yvG zH|!bN;~Qi^$1Zf*`sfB-A=QJ|02SkrCQxkGU|@Q@OFRTgsubtD<87 zL=xP^308ghW}Un$FClfCTrL}437+0@FgQ}8&~05 z&_10m)s;x~Qp#2t7J53#sB*uH3LQiaoXjKW0kz5D4!O^I1ZC88<;%wpAn$yZ{L z+_=-q?XyTPN?FeQO|7%HFh=>DqZYoS?-O6tEnimRmD8l1Ju!(%pTxKuJ;DC~>GQan literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/zmq/tests/__pycache__/test_future.cpython-38.pyc b/.venv/lib/python3.8/site-packages/zmq/tests/__pycache__/test_future.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a9cbfbc79966117bce62448e5ea90c49325bb6c3 GIT binary patch literal 12155 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 literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/zmq/tests/__pycache__/test_imports.cpython-38.pyc b/.venv/lib/python3.8/site-packages/zmq/tests/__pycache__/test_imports.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..4e7c14901d37709fcc5d11ed9bcc1eff72af963e GIT binary patch literal 2725 zcmbVONsrt_6!vcSHq*&Wb{4Y+BW8w6kU$ZN6anHgij+h^Uo5Aq!kF z2&OST(Pq>diJlrWLvQEInfaZ@OlG~-n8l6X%$ddXr&?hDgI(Hbpf}z#F3ZP}qF?3EBbMWBX`_ zY|5^o9kJ`M;Gh}N&EKa*E=pOYH1NBTf8>{E+`m}F^K+UmmB@Xb$%Wupi%S0$_s^nB zp4~5pKE60BMa~v;&iqR*WSnP5aW>D>A}Zq-3HRkPE2Ar)3y}+XJl6qf^$||`J;qOt zA(##pwHgw3n$=-p7^n{SkMW?pIN0Bfzeo!Cocs#= zSrGvUJ9>4-d2)31;Oc7m;L8Um*m*){OC`hhV0m0Dn+Z*aW!_#n!Eur-)QsxRGpuwp z9rv_)mCkYpr zv%eKl%F!9j^GudeR!T7IFn$@&d1DtMzgh-XGXig6=j3L(F$m-AW!_AR<;Gldy*E@U zr@>fxN(?}ZpfnRB5=5FHvc(>WeG*d=*GOC^aR7ncHueACZWSD@Kw4|fKsk}vqFW^0 ztQli{^*7b48#^v1?Vh{Ip0&GGL0E-w>uP<&)y9UaP339|bEi5`ZfnWzIgX-y_yQH8 zUBhTE&9k_K5$s~Y7v!o$`5aFFg8AG@tGG{J@DvEB-^ZdP)C8b9+%X<1J;TYlgjX3(wYVCuO#ea4-m$b&KOc%ub&dW? z<9Cype;~_$(lX=67Nk|9ZX?evx+ zBH>AQHSaM5<~n#O_5fH^N@Zv!4IS+2tb3cyhW5dZ>txa7JLXmQ#P* z-ZtK$`4Ee%=W93Gq0qClm!^k3JG&RFwe=R!;WLg}7$N3l-(;h4@rKY_(>PMSG^Zec zkH~+sMNlS+PasywyPntvv#-d1v-J@+tuWo&VgHRDo|?uB!wm0Q7&gN&Oz}@jLj7?V zUM!-dTXDmXO;?fJ{l1r4X4UL*jQ`;-rDk~wj z57Hj{LL7YM)Cb_giJ4@Z2IvJ#o{Yzy&olFl^Kp5(Phg0z-;Mok z?Nbn%#8eSLrHY-Cm^YY!CIBt;Lxg!>jPt3|c1*$HX7oT2Fn3_uZy*o>W1Z0nn=wip zzX&eLj927BxUk}`H)ofSN4=I6pHsyTMQ!1VJ|VMUaWZgAi<6Ka*u}ywT05)6oX$e9 z_p4BeOSnxDjCa>yh*!+_RA!2FqP^UQ8lZNKX@dum=v*n$?4Y1 ztr3Jca=?qNWgF;bdFofuo^-<>0H#G?LRYASxmHWmBt3i9<#+QR=RX+7`m~H6z~Vm` zmu{(H9J#9g=DWY(n^ghuihRpTsG#LlG`t#o8%CnQtfGOzr*vE5+8VE5_Ib8%QgfO> zajhBRsbv)RP^_Z3k75Nx6q+^E+ZKp>;9UDX0DBxZtD2ietb^IFx3%hC^%%A+qTUp{ zDLEAS`Q3%?I`2lp%Ot^OO%mTvlF5;p=BN*o1e>baF^>S=;7y&FkYIy>8Th9VY$uDw ql1vV3OC+G%ip*iu246y5E6y?qywm#>=u-e74gvOk2Dk?c25uo>n6 literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/zmq/tests/__pycache__/test_ioloop.cpython-38.pyc b/.venv/lib/python3.8/site-packages/zmq/tests/__pycache__/test_ioloop.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..29c21a44377f586c9e5b7f4185dd282fffdf93de GIT binary patch literal 4810 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 literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/zmq/tests/__pycache__/test_monitor.cpython-38.pyc b/.venv/lib/python3.8/site-packages/zmq/tests/__pycache__/test_monitor.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..53e549f3d60c85a313d754061c67f72da1667526 GIT binary patch literal 2316 zcmb7F&2JM&6rYd%vc0yG5NM$V!lAT2kN|?BqN)XgRUv^BAXMsJR>m`=PIm3h%$g?F zB2|S${|x8IrHB48J{GmWT~S;XwjBMvi5oYak6iZ(p)Qa|!7Pm>@DK<6Ztv>H{@ zT2xEJD70&CQcoLEgOcxv@Pz-02wzrT@~A23W6}!#hMh^LMNP0Jb-v!!5_l)=s@)bh z%{w4R4<62zOhxbZvp74*4oqFiy-{Duc%1IV*WjaNC40}~bU5heLlvh|>+ZJfq5Go` z2jLbBeHn-(c+H4OE~sFy$V(bIz;oeP-UZ$jp5@`_cwDoHXL&sA?aKT?xmAyXr`h8I zgJT_regmW+J7hw0w!;tU3p$q^kQhkr#4BjQw%H-2q+k||b4PpHVUhueCP>`*+e4*ek=?kZDgmW5wRd$*By&#iC(72}| zFX(x0Rq9L2YPsieOYppONIvjI4ZkRZHNJ?!TA8M#KiFRB4|1uVb$fE<*-))$8%Di4 zUe0^j&9${FS8uFdhWEky&-J7pBt~-&~PXj!ymObkvug1^c=mgYwl*HckGD29H`{k3XY=;GN5<=B8T!V<3}g=ulR!YE zQa;|N*40|7yuCN-CZ;L+y8ASdvs!-b8b{0IS>);%B2Z3yk+0)23N(F9)H!hT=H^8Bs1OfKzT-`_vD{?+w0xcOQRNzs#h7r8G2CKI9WdrsNNuA;9pPGxnOT+k(y}?l zm}8d0gLL`h3wY_3Y0pS;6idn^y&pVoSeUT6R`?725I)@Kv=$Wn8OhsvPz@BDNNoNW zky}D?0m;WmuqM<;NNf$9K+YBd_Ko@k3HIZWbe}qw?)iPb1uKp9^0ve296kBz_h zkIc{Aby~g&;&{+aWgMGo4DBpN03@*q;~24}Tu~k#ZUqVUxcVH)+XGt;i&OM!h@=M(`iTODhK7MqYMc1^oS%ZC3#( zvLK-qqJhG{raf4+h%2MKpXk*o1eamP)4cDPCiuF%=QnsSjR!_hf*0Bdn`oJa{2wn_ BHF*F4 literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/zmq/tests/__pycache__/test_monqueue.cpython-38.pyc b/.venv/lib/python3.8/site-packages/zmq/tests/__pycache__/test_monqueue.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e8391c0c01fa891005884209bee217544226a0a0 GIT binary patch literal 5665 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 S1#83#iWm9}D;U#8-uMrFk|+HD literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/zmq/tests/__pycache__/test_multipart.cpython-38.pyc b/.venv/lib/python3.8/site-packages/zmq/tests/__pycache__/test_multipart.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..fbcaacffc2f54bed4f84c1dbb4c14d221dd78fd7 GIT binary patch literal 1289 zcmZuw%}*0S6rZo%F3p_sC--|CYx<%gu-rFX0{bbo0z~K zLXY13Ydp-=lV@+9d~YjKgxSoSeIN7Y&F}YSw^A7;FuX6{qi>v$AE*ou50n~A`v!y} ziY7$j$`YC~$x<$PDx^p~=~1#y6j$PcD52Rom%bKe4Q!tB!RBjE`{zQI6x}9a=_lkP zo1t(MFJr6a#)lnk^A-4Y!S-P@L(Prt#~mH*>5gvYZe-nP-9mc?7;Z z9;EH@F1r+6-lr5Jye{q2p6Jp8zvqEo>UxUx*^tjKti0!^OzZmB4Xo5u08^jP{^?{;@qx1|4Sb@}b;mJ?RDloLibIRP%dj zK2NjxteMTWTUp#V)N1zgzSha?$>Pb$>EiRnd8lVT2SjZlqx1^cx$M+Up(7d`84XUX zAhcBwgjSiLqwx8(46+RC*^?XG%-!C8gDz~%e{|JA8KMgaxS~rj#rHUnMlbna(ty4` z0m_g(-W9_nU@Pr6E#}Vmwb8$@LF%DzusIA;B*pvX*IRNNLBGDQ97p)Cbu$K`p=Zjl zI2t=zcO1Z$9)_s`-GP|EfNF8odTg7G>lBZ`V~f{Gs|8X4J$rfwLjP^s3_TY_Q7cY$ z6uHqTN{>`K!T)j;VK)psW)jky`zVm=A%PVc9|T^(BEkU+Duw0N%R_W(7>4(}etFQ) z%uU^>wRpXoAvec?V37tnE2=Ew X?@H`~r2!Z(Ft&Jb0iWTM(}Mm1=KL?? literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/zmq/tests/__pycache__/test_pair.cpython-38.pyc b/.venv/lib/python3.8/site-packages/zmq/tests/__pycache__/test_pair.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..54c3731e7fe7fdfe1ced73ecdd287c81b09be563 GIT binary patch literal 1684 zcmZ`)OHUj}5boDJmbZbR*g}@y@=5^&7O`wu5q`z8B_kUrmyxZ}u-#cNo|&EPp2dI` zDGI*&KY-*5e<+8(=48pY+;U1)uh|6_dezmBdQE*@Rr~ws=n#S7{rPwNO%U=A9*z$W z4l6Lt3m}q6nvw`tmePzxEaMT+L?kGYJo26qDWvy_NKdgn9{GyvU*XP|0o(;jD1T2x zfuwIpHT(+p$ZD0_@kfbK(aYDrDN{a%tsQ=!Y^u1fHdS8Q$}_E0j=X;Z7_=F)FqTN?XL)Xyu(ZG;#K89(2 z2GSw>q@)`R=K*`mcIhs7*yV7~JG8?({DAKYIEfDLhyw;-5U|fyO$geVGA603#j0m7 z)U--U6|Xnjxr_^NZ23;svf|al=W9`=Xyo;{Xy$c0oEW2Y`LxweQqU7drGHpv7GW+$ zA~W?xN0$zX9s?Ku-CZcNVxedhbM3rHY9ExG`}kg|bZ%>TYioP?-tq#tStub|i07gqd(-U`T|&} zGD{On*Q>#46ohQlN-NTaDfJ{sMq|Caj5ka(KODrO8L{TlX(%cV3e>m_Rt)9|zyQCU z$&(?Y$ob)(SAh87rNCf&p?W7n)fd5I)jt)Vo`u_PVB`J3itXn5hQ5p}tb=1O+N}`B zp94-Wj){T#a5Agaz=m<0Cz*<4I~2!RQ?^swkHj&SbC;th(94fVt{}OJr0?17FrhTU zhFRw-Gh|^9PKBPk9q5GE!&Xof<@=owJCPkn$k$YBO%<-8LgUrfKuljpas$a(-fsfq z4orhxHl!NQP&ZgIQ3YCxYYavsS92ur7ee$D68vx{f0khzKIr1|3#PTf5)1h>7j)v5 Gp#KB%vS_0K literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/zmq/tests/__pycache__/test_poll.cpython-38.pyc b/.venv/lib/python3.8/site-packages/zmq/tests/__pycache__/test_poll.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..76804f0be705a41794f85b726a9cb52f202d238a GIT binary patch literal 6068 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 I30^_}AG4eAW&i*H literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/zmq/tests/__pycache__/test_proxy_steerable.cpython-38.pyc b/.venv/lib/python3.8/site-packages/zmq/tests/__pycache__/test_proxy_steerable.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..599e15a3d6414cfe192f907afc518040cfd4292d GIT binary patch literal 3291 zcmeHJ&2JM&6rb5IufLKILO$pRE+wUIn}h@q0)-R^P*OnzI2>3NtsKuJ*>+$-5v4Nt15FNvshu5GqXBqAzKvHnotf>d=gK zOKocn%G8Du(WV(G+q9tql};!Ps7ylXKxGrk04ldlC<*h;9;R(mI7_{eipXkjvk!HG z1~W37Czuf_k-DS|5}ebK>mW}@>9$-CMxS1(V%!B2z`Y%)Q+iZN%) zy`USfZo~s9J}T%3?Q$A`&>S_Xw)cCd85+&Be&gb-OG(iJtwC zdf|jCc3CV-Tr5#}H=ofGFX{nLf!{mBFlis%ym3tb_}48DIZhAk+$kEr|6erzOVJ?B zp(qQ*DaTBfenq0(ZL&ohc`P(66XjWUgzOcba5zeBQQ&3vdC8pI{PZS5 zZH{!xQ}29H5hh&Yjta0@C@tJvm@6&J&6c{>rHe_334APwJOX-v#Ms+kc*sMr-k^t+ zaNfrN%TPL>4KygG7)Bx}ri_k|UzBwXilwrtTz@36P!<(P{-LNr&No_#7C6fIg_zcl zhD>JKb!1oxyz0y{?t)Qk5QS{sJ+7}q2?{}lQ<3A-Zcr(^at4S!r2^|~V$=@)lbs~p zz$20rPaiv1bV(E9G^+gw0nbHzg77KA8H57DX9!82`5dWp09Fr{H`}YZp;N`msk+=3 zqacCQbvWa+63kb)@@s@|5XKP35hf5WAWQ;4?S)g2RyygR=!Zwo`ApZ;w10N@K#Tky zpj$FJZUM_cvg(6!h7HQu)Q4Z;e9?$a+xE*Ix9vD%+g`wGF48&M#s@-6A})cU;tIko zg#A36P?(GbUN=?)iG-<`1#>Xr6?3h7yNZ*Na)EAcrJ?dC#a0RordIjD*IJyKZ9Ql# t<971uw|d(z92;IFVIVdVwcTup&FPl?Gw9Y5!_A~%3cL{p6ivyf{{X*gEWrQ( literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/zmq/tests/__pycache__/test_pubsub.cpython-38.pyc b/.venv/lib/python3.8/site-packages/zmq/tests/__pycache__/test_pubsub.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..5ce33d9ec72c078f620444b662d8440d441b0335 GIT binary patch literal 1379 zcmbtUJ8#rL5Z;%4w(pV<2owQ{S9L{l0x1O&f;<#O2sj{t#zL}ux0~d^_L*Hf1ay&* zl0N~}U74T2AEDTm0#T=~O$X z1TmWcl1Q46l!la|&Jq?fn0dle5sDL^6FT4%iJR8KTIz*f>W4lhYeYKIJs{FmwS682 z%F`Y2)uabLPx&g?7hzqp4bt?#!(F6Ft-Bs)vY)m=^`0wJti(n&xt&^uIeh%=)Me}2 z@s5hN)Q-vu>#u30GFmwj=3?QBt_Wnq(s+jqmXR9eM+f z7VPpzWKTeZV890g_euh{i}n!&Cf`1N#PRw5Q4OqA853`*X5CJAwTcTBb^2u{qde|u z%ipJOEPwi9+42p5z^KCXyRZ8>@BxmEmGuY9t5y`fR9VL)O667h9QjY>d*y z>YFl74jo)dHZ3!^KyHU3HCwkTynRUYEIj4MomP?Nt-P1dm02ElUn@EHc3Y`rZg*jK z_uaysg%-T0RRDvg!YD60rtHk;?`(kHs1uuB_X316lK_Oy&`BCl0pij37su4kk9Yr( z1&nUC1b=J4;>eAZMgSMW*^;-MM@}nm!5A{Vn zatQ&maSWG1J0Z8|=e;hLxWQv*$({Kp#nqX1)3II@WpS#a$OciA_GOu%-iRWsjpG%K zvGrAi@%@#CkI-1G_@M^d#B)5q^8C?^$lM}sLwd%|2<6Z0)VKnwZf-ZZz6RU$b%YxT zf4li6EHpt3Ho8Z3WjCy=tKW!5Z^e1&m07RA($XA#_=3=flC8?kXneTF^3pB>eoz(b bZo_)R literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/zmq/tests/__pycache__/test_reqrep.cpython-38.pyc b/.venv/lib/python3.8/site-packages/zmq/tests/__pycache__/test_reqrep.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ef5e46eba470086c68e41641f96ce14a69ca79dc GIT binary patch literal 2282 zcma)7&2Jk;6yN#S_1aFHq@*H+QYsV`Es#Wx2%@NuIUT2CF!aL z=sZyZT}gVfbjm|t&}UBIzlC+3fEa&I>f&LnWg}o_;d^L=Po9o-ruri8%cv#$GAm5^ zv63=FTN5W={wQ>|q38!7q!SY1z!8a{ubhwxCOFh^G~q$*ijwf5_C#4!pe~83n1k9E z^Kh`5so)N~@?clyO#;h}KZFF!Ln!(y5Ci9pQ;;@=!p`Wg^n{$io+k|Sd_V?tz|PnS zhn_oN1AaykJlKIYbQxxMq}Fju-mM3oS!ya77c$!K_A(LWaiR=6?i?7lyYm#qPo|tF zSu4uBS<6&ot)(h<4tjAKxQ1()J~vd?p==u7(XG0bo9B+Y0sH)Of1~K+8+nqi^|Cx} zzLa9^_ZL#8YlmBhheuoYw>Ds_jRKt3Rz^x5D4DP4N2Y?>Xg}6Ta~{3+K{#ZYa#AD5 zHzzo)PsUw=%!A=rEMz}IV-{ou7vz-u;QV$EpksnAJ0s8#LJknRFv}b8fr}6x+_oUH z##;>Fzwv_Zo|hEFu%qyJ3b9paGp>rWmQ+<#%z+3zggB!kC+*K3OI!%*NhF)6nn7m*!o;|4Q0^18dF1A7Zd@ z3lAgl6lmi$wP{?Mq%mT6&Kl|_tPoH`Vng-=e->zli=yDjE|BfPnvadD?v(^lq=;MOK)3g^NC4cnr}tCNA_?eGGdB zGt*0b0;ZvV3lsnHqwaoNt)givpN3pw?HgdeaA$D_lh{#L{P|x@f`kw3!N4zO8RgC; zCP6YDG6@?o$*Ro@-bfZd9Wlu-_IlO(==3yM3?ugzdNzwLYWA|yShZvX9Q-A^IN}T9 z17iSR+?u|%i_wjsZ2Tz7;*N|WQ;DKZSM*YB&qWdP{LrG1h13Tq?x47b0?zKJ0L27w z+d>voh#L~1MgsJyU-Esw=DWUYE!W;rq|@#3@X0%hua;Su9N#{~@L($pO!Ya6FHp=n z!5SF8g`)9|_KCuNP!9cGmK2DYLcOK#uncTtpAxMYDv_KN=C3`hojGd@<3AYU^&O72 Ms9UmNi*-)^1u$#n-2eap literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/zmq/tests/__pycache__/test_retry_eintr.cpython-38.pyc b/.venv/lib/python3.8/site-packages/zmq/tests/__pycache__/test_retry_eintr.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..3e691ceb710fe1e4650323b3ea6307ea0187846c GIT binary patch literal 3527 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 literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/zmq/tests/__pycache__/test_socket.cpython-38.pyc b/.venv/lib/python3.8/site-packages/zmq/tests/__pycache__/test_socket.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..225d6bb6b9a5f8c0c8e82224fdf221448ea8b7dd GIT binary patch literal 19756 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 literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/zmq/tests/__pycache__/test_win32_shim.cpython-38.pyc b/.venv/lib/python3.8/site-packages/zmq/tests/__pycache__/test_win32_shim.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0a83577d9e500db10c5b59aaabd7ea09b749cff8 GIT binary patch literal 1935 zcmb7F&2Jnv6t_JeJ3G7CB&d{vDv?SEu|N_jRfLdAK~19;5mNO7rOahIU3-(sdOm7< zyV=#QgxE+82jI>r;nshE|AH$ApO859U*LdvZ?>eViiDVvpP%iq-}C$Z-kY!H=0XCG z_swtduRbAv;Na}z!QeA!`Y{MjIF%%$5v8az$s$(uPUKX*8@bRs(#!nFufB0*EeoQc z(mh$v!YHhCUpBI4)C9f8gF_O{iD18VgYY^J4+#%NICZ8pn&<2;X*ZsMZPKQ;RjM>M zakrm$Oj_jIFy#$YQfg4#EKxn^=dUGNL|@*%C$!lB6{iv@i$M%qg;M>}bSR$p{6XD? z=0MX+APhO8Q~HEFp~b?nC6@5VrjcErWOUIPQRhI*!}Sx{2D=*6j_re#$J3E$u!f ze}1xRvU0Ud%jJGvCY_$(%Y!{3jddmCL7HD)i}hZbt&~I6 z1Vi)a9RN%SW3)_(PAGS{D{00i3^?j=Pdb@9aWZe>QZi=8KKD=P#2b72wTVA=$8ML6 z{WusqAnT(KO*jV6e|&3F8~d=^nX*Y>8plmuJAvHUA?xHexdU9-A^AC%n7Ll4jwr$R zYm#5QPsRavdQAOfT2t~Z&BHM{p63DX1#MwW_ZNBn1U*A8g)b8lE&@y=umaaY?D1OD zDrGC;janN?e|OI;ZQQ%FwY+f&qT^MGH3PXqx)K%Ai>GN5mxYvRzIzGJMFWJ5ZvGb} zD;WQHZ-&ncqP=qHjCg<(AjqY}RJeBQ)|U0I@7%g`-3C3Oav?9T?V?>me*bjz-sV9m zpbq4_OAo#f!-qwp_~-wm_=6>J&=Dn8iA$;m8``f`th9c|3`?Qad6*yAGtWF(NZ{qMG+NyOR z3B-Xxj_bZOXJD)lY@USxcT`o1c#MWllP<8(@o7kX2gWdSfwrj60vf>lX!(D^yWI|L z5XX6vi8!`l9A^dZOVpcjjJKMtC@iCU-!~7?OI0r^Z41$3m_H+=<;D5R}rg;rRt)dx7L zSHF{@kh-dRkzWomV3n6q9SUnjVXd%!Me{iBn^bBf&E>TU?TT6IeLNAJ`8O|ZaAg*Z Xt5{(5IS@?@GQ3R&FKs$O!=--%>WAMO literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/zmq/tests/__pycache__/test_z85.cpython-38.pyc b/.venv/lib/python3.8/site-packages/zmq/tests/__pycache__/test_z85.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0f15eaf4241bad4f54eb0d559c0cd2012b52349e GIT binary patch literal 1746 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 literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/zmq/tests/conftest.py b/.venv/lib/python3.8/site-packages/zmq/tests/conftest.py new file mode 100644 index 00000000..69d04224 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/zmq/tests/conftest.py @@ -0,0 +1,14 @@ +"""pytest configuration and fixtures""" + +import sys + +import pytest + + +@pytest.fixture(scope='session', autouse=True) +def win_py38_asyncio(): + """fix tornado compatibility on py38""" + if sys.version_info < (3, 8) or not sys.platform.startswith('win'): + return + import asyncio + asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy()) diff --git a/.venv/lib/python3.8/site-packages/zmq/tests/test_asyncio.py b/.venv/lib/python3.8/site-packages/zmq/tests/test_asyncio.py new file mode 100644 index 00000000..ba6bac91 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/zmq/tests/test_asyncio.py @@ -0,0 +1,481 @@ +"""Test asyncio support""" +# Copyright (c) PyZMQ Developers +# Distributed under the terms of the Modified BSD License. + +import json +from multiprocessing import Process +import os +import sys + +import pytest +from pytest import mark + +import zmq +from zmq.utils.strtypes import u + +import asyncio +import zmq.asyncio as zaio +from zmq.auth.asyncio import AsyncioAuthenticator + +from concurrent.futures import CancelledError +from zmq.tests import BaseZMQTestCase +from zmq.tests.test_auth import TestThreadAuthentication + + +class ProcessForTeardownTest(Process): + def __init__(self, event_loop_policy_class): + Process.__init__(self) + self.event_loop_policy_class = event_loop_policy_class + + def run(self): + """Leave context, socket and event loop upon implicit disposal""" + asyncio.set_event_loop_policy(self.event_loop_policy_class()) + + actx = zaio.Context.instance() + socket = actx.socket(zmq.PAIR) + socket.bind_to_random_port("tcp://127.0.0.1") + + async def never_ending_task(socket): + await socket.recv() # never ever receive anything + + loop = asyncio.get_event_loop() + coro = asyncio.wait_for(never_ending_task(socket), timeout=1) + try: + loop.run_until_complete(coro) + except asyncio.TimeoutError: + pass # expected timeout + else: + assert False, "never_ending_task was completed unexpectedly" + + +class TestAsyncIOSocket(BaseZMQTestCase): + Context = zaio.Context + + def setUp(self): + self.loop = asyncio.new_event_loop() + asyncio.set_event_loop(self.loop) + super(TestAsyncIOSocket, self).setUp() + + def tearDown(self): + self.loop.close() + super().tearDown() + + def test_socket_class(self): + s = self.context.socket(zmq.PUSH) + assert isinstance(s, zaio.Socket) + s.close() + + def test_instance_subclass_first(self): + actx = zmq.asyncio.Context.instance() + ctx = zmq.Context.instance() + ctx.term() + actx.term() + assert type(ctx) is zmq.Context + assert type(actx) is zmq.asyncio.Context + + def test_instance_subclass_second(self): + ctx = zmq.Context.instance() + actx = zmq.asyncio.Context.instance() + ctx.term() + actx.term() + assert type(ctx) is zmq.Context + assert type(actx) is zmq.asyncio.Context + + def test_recv_multipart(self): + async def test(): + a, b = self.create_bound_pair(zmq.PUSH, zmq.PULL) + f = b.recv_multipart() + assert not f.done() + await a.send(b"hi") + recvd = await f + self.assertEqual(recvd, [b"hi"]) + + self.loop.run_until_complete(test()) + + def test_recv(self): + async def test(): + a, b = self.create_bound_pair(zmq.PUSH, zmq.PULL) + f1 = b.recv() + f2 = b.recv() + assert not f1.done() + assert not f2.done() + await a.send_multipart([b"hi", b"there"]) + recvd = await f2 + assert f1.done() + self.assertEqual(f1.result(), b"hi") + self.assertEqual(recvd, b"there") + + self.loop.run_until_complete(test()) + + @mark.skipif(not hasattr(zmq, "RCVTIMEO"), reason="requires RCVTIMEO") + def test_recv_timeout(self): + async def test(): + a, b = self.create_bound_pair(zmq.PUSH, zmq.PULL) + b.rcvtimeo = 100 + f1 = b.recv() + b.rcvtimeo = 1000 + f2 = b.recv_multipart() + with self.assertRaises(zmq.Again): + await f1 + await a.send_multipart([b"hi", b"there"]) + recvd = await f2 + assert f2.done() + self.assertEqual(recvd, [b"hi", b"there"]) + + self.loop.run_until_complete(test()) + + @mark.skipif(not hasattr(zmq, "SNDTIMEO"), reason="requires SNDTIMEO") + def test_send_timeout(self): + async def test(): + s = self.socket(zmq.PUSH) + s.sndtimeo = 100 + with self.assertRaises(zmq.Again): + await s.send(b"not going anywhere") + + self.loop.run_until_complete(test()) + + def test_recv_string(self): + async def test(): + a, b = self.create_bound_pair(zmq.PUSH, zmq.PULL) + f = b.recv_string() + assert not f.done() + msg = u("πøøπ") + await a.send_string(msg) + recvd = await f + assert f.done() + self.assertEqual(f.result(), msg) + self.assertEqual(recvd, msg) + + self.loop.run_until_complete(test()) + + def test_recv_json(self): + async def test(): + a, b = self.create_bound_pair(zmq.PUSH, zmq.PULL) + f = b.recv_json() + assert not f.done() + obj = dict(a=5) + await a.send_json(obj) + recvd = await f + assert f.done() + self.assertEqual(f.result(), obj) + self.assertEqual(recvd, obj) + + self.loop.run_until_complete(test()) + + def test_recv_json_cancelled(self): + async def test(): + a, b = self.create_bound_pair(zmq.PUSH, zmq.PULL) + f = b.recv_json() + assert not f.done() + f.cancel() + # cycle eventloop to allow cancel events to fire + await asyncio.sleep(0) + obj = dict(a=5) + await a.send_json(obj) + # CancelledError change in 3.8 https://bugs.python.org/issue32528 + if sys.version_info < (3, 8): + with pytest.raises(CancelledError): + recvd = await f + else: + with pytest.raises(asyncio.exceptions.CancelledError): + recvd = await f + assert f.done() + # give it a chance to incorrectly consume the event + events = await b.poll(timeout=5) + assert events + await asyncio.sleep(0) + # make sure cancelled recv didn't eat up event + f = b.recv_json() + recvd = await asyncio.wait_for(f, timeout=5) + assert recvd == obj + + self.loop.run_until_complete(test()) + + def test_recv_pyobj(self): + async def test(): + a, b = self.create_bound_pair(zmq.PUSH, zmq.PULL) + f = b.recv_pyobj() + assert not f.done() + obj = dict(a=5) + await a.send_pyobj(obj) + recvd = await f + assert f.done() + self.assertEqual(f.result(), obj) + self.assertEqual(recvd, obj) + + self.loop.run_until_complete(test()) + + def test_custom_serialize(self): + def serialize(msg): + frames = [] + frames.extend(msg.get("identities", [])) + content = json.dumps(msg["content"]).encode("utf8") + frames.append(content) + return frames + + def deserialize(frames): + identities = frames[:-1] + content = json.loads(frames[-1].decode("utf8")) + return { + "identities": identities, + "content": content, + } + + async def test(): + a, b = self.create_bound_pair(zmq.DEALER, zmq.ROUTER) + + msg = { + "content": { + "a": 5, + "b": "bee", + } + } + await a.send_serialized(msg, serialize) + recvd = await b.recv_serialized(deserialize) + assert recvd["content"] == msg["content"] + assert recvd["identities"] + # bounce back, tests identities + await b.send_serialized(recvd, serialize) + r2 = await a.recv_serialized(deserialize) + assert r2["content"] == msg["content"] + assert not r2["identities"] + + self.loop.run_until_complete(test()) + + def test_custom_serialize_error(self): + async def test(): + a, b = self.create_bound_pair(zmq.DEALER, zmq.ROUTER) + + msg = { + "content": { + "a": 5, + "b": "bee", + } + } + with pytest.raises(TypeError): + await a.send_serialized(json, json.dumps) + + await a.send(b"not json") + with pytest.raises(TypeError): + recvd = await b.recv_serialized(json.loads) + + self.loop.run_until_complete(test()) + + def test_recv_dontwait(self): + async def test(): + push, pull = self.create_bound_pair(zmq.PUSH, zmq.PULL) + f = pull.recv(zmq.DONTWAIT) + with self.assertRaises(zmq.Again): + await f + await push.send(b"ping") + await pull.poll() # ensure message will be waiting + f = pull.recv(zmq.DONTWAIT) + assert f.done() + msg = await f + self.assertEqual(msg, b"ping") + + self.loop.run_until_complete(test()) + + def test_recv_cancel(self): + async def test(): + a, b = self.create_bound_pair(zmq.PUSH, zmq.PULL) + f1 = b.recv() + f2 = b.recv_multipart() + assert f1.cancel() + assert f1.done() + assert not f2.done() + await a.send_multipart([b"hi", b"there"]) + recvd = await f2 + assert f1.cancelled() + assert f2.done() + self.assertEqual(recvd, [b"hi", b"there"]) + + self.loop.run_until_complete(test()) + + def test_poll(self): + async def test(): + a, b = self.create_bound_pair(zmq.PUSH, zmq.PULL) + f = b.poll(timeout=0) + await asyncio.sleep(0) + self.assertEqual(f.result(), 0) + + f = b.poll(timeout=1) + assert not f.done() + evt = await f + + self.assertEqual(evt, 0) + + f = b.poll(timeout=1000) + assert not f.done() + await a.send_multipart([b"hi", b"there"]) + evt = await f + self.assertEqual(evt, zmq.POLLIN) + recvd = await b.recv_multipart() + self.assertEqual(recvd, [b"hi", b"there"]) + + self.loop.run_until_complete(test()) + + def test_poll_base_socket(self): + async def test(): + ctx = zmq.Context() + url = "inproc://test" + a = ctx.socket(zmq.PUSH) + b = ctx.socket(zmq.PULL) + self.sockets.extend([a, b]) + a.bind(url) + b.connect(url) + + poller = zaio.Poller() + poller.register(b, zmq.POLLIN) + + f = poller.poll(timeout=1000) + assert not f.done() + a.send_multipart([b"hi", b"there"]) + evt = await f + self.assertEqual(evt, [(b, zmq.POLLIN)]) + recvd = b.recv_multipart() + self.assertEqual(recvd, [b"hi", b"there"]) + + self.loop.run_until_complete(test()) + + def test_poll_on_closed_socket(self): + async def test(): + a, b = self.create_bound_pair(zmq.PUSH, zmq.PULL) + + f = b.poll(timeout=1) + b.close() + + # The test might stall if we try to await f directly so instead just make a few + # passes through the event loop to schedule and execute all callbacks + for _ in range(5): + await asyncio.sleep(0) + if f.cancelled(): + break + assert f.cancelled() + + self.loop.run_until_complete(test()) + + @pytest.mark.skipif( + sys.platform.startswith("win"), + reason="Windows does not support polling on files", + ) + def test_poll_raw(self): + async def test(): + p = zaio.Poller() + # make a pipe + r, w = os.pipe() + r = os.fdopen(r, "rb") + w = os.fdopen(w, "wb") + + # POLLOUT + p.register(r, zmq.POLLIN) + p.register(w, zmq.POLLOUT) + evts = await p.poll(timeout=1) + evts = dict(evts) + assert r.fileno() not in evts + assert w.fileno() in evts + assert evts[w.fileno()] == zmq.POLLOUT + + # POLLIN + p.unregister(w) + w.write(b"x") + w.flush() + evts = await p.poll(timeout=1000) + evts = dict(evts) + assert r.fileno() in evts + assert evts[r.fileno()] == zmq.POLLIN + assert r.read(1) == b"x" + r.close() + w.close() + + loop = asyncio.get_event_loop() + loop.run_until_complete(test()) + + def test_shadow(self): + async def test(): + ctx = zmq.Context() + s = ctx.socket(zmq.PULL) + async_s = zaio.Socket(s) + assert isinstance(async_s, self.socket_class) + + def test_process_teardown(self): + event_loop_policy_class = type(asyncio.get_event_loop_policy()) + proc = ProcessForTeardownTest(event_loop_policy_class) + proc.start() + try: + proc.join(10) # starting new Python process may cost a lot + self.assertEqual( + proc.exitcode, + 0, + "Python process died with code %d" % proc.exitcode + if proc.exitcode + else "process teardown hangs", + ) + finally: + proc.terminate() + + +class TestAsyncioAuthentication(TestThreadAuthentication): + """Test authentication running in a asyncio task""" + + Context = zaio.Context + + def shortDescription(self): + """Rewrite doc strings from TestThreadAuthentication from + 'threaded' to 'asyncio'. + """ + doc = self._testMethodDoc + if doc: + doc = doc.split("\n")[0].strip() + if doc.startswith("threaded auth"): + doc = doc.replace("threaded auth", "asyncio auth") + return doc + + def setUp(self): + self.loop = zaio.ZMQEventLoop() + asyncio.set_event_loop(self.loop) + super().setUp() + + def tearDown(self): + super().tearDown() + self.loop.close() + + def make_auth(self): + return AsyncioAuthenticator(self.context) + + def can_connect(self, server, client): + """Check if client can connect to server using tcp transport""" + + async def go(): + result = False + iface = "tcp://127.0.0.1" + port = server.bind_to_random_port(iface) + client.connect("%s:%i" % (iface, port)) + msg = [b"Hello World"] + + # set timeouts + server.SNDTIMEO = client.RCVTIMEO = 1000 + try: + await server.send_multipart(msg) + except zmq.Again: + return False + try: + rcvd_msg = await client.recv_multipart() + except zmq.Again: + return False + else: + assert rcvd_msg == msg + result = True + return result + + return self.loop.run_until_complete(go()) + + def _select_recv(self, multipart, socket, **kwargs): + recv = socket.recv_multipart if multipart else socket.recv + + async def coro(): + if not await socket.poll(5000): + raise TimeoutError("Should have received a message") + return await recv(**kwargs) + + return self.loop.run_until_complete(coro()) diff --git a/.venv/lib/python3.8/site-packages/zmq/tests/test_auth.py b/.venv/lib/python3.8/site-packages/zmq/tests/test_auth.py new file mode 100644 index 00000000..90b8f907 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/zmq/tests/test_auth.py @@ -0,0 +1,557 @@ +# -*- coding: utf8 -*- + +# Copyright (C) PyZMQ Developers +# Distributed under the terms of the Modified BSD License. + +import logging +import os +import shutil +import sys +import tempfile + +import pytest + +import zmq.auth +from zmq.auth.thread import ThreadAuthenticator + +from zmq.utils.strtypes import u +from zmq.tests import BaseZMQTestCase, SkipTest, skip_pypy + + +class BaseAuthTestCase(BaseZMQTestCase): + def setUp(self): + if zmq.zmq_version_info() < (4,0): + raise SkipTest("security is new in libzmq 4.0") + try: + zmq.curve_keypair() + except zmq.ZMQError: + raise SkipTest("security requires libzmq to have curve support") + super(BaseAuthTestCase, self).setUp() + # enable debug logging while we run tests + logging.getLogger('zmq.auth').setLevel(logging.DEBUG) + self.auth = self.make_auth() + self.auth.start() + self.base_dir, self.public_keys_dir, self.secret_keys_dir = self.create_certs() + + def make_auth(self): + raise NotImplementedError() + + def tearDown(self): + if self.auth: + self.auth.stop() + self.auth = None + self.remove_certs(self.base_dir) + super(BaseAuthTestCase, self).tearDown() + + def create_certs(self): + """Create CURVE certificates for a test""" + + # Create temporary CURVE keypairs for this test run. We create all keys in a + # temp directory and then move them into the appropriate private or public + # directory. + + base_dir = tempfile.mkdtemp() + keys_dir = os.path.join(base_dir, 'certificates') + public_keys_dir = os.path.join(base_dir, 'public_keys') + secret_keys_dir = os.path.join(base_dir, 'private_keys') + + os.mkdir(keys_dir) + os.mkdir(public_keys_dir) + os.mkdir(secret_keys_dir) + + server_public_file, server_secret_file = zmq.auth.create_certificates(keys_dir, "server") + client_public_file, client_secret_file = zmq.auth.create_certificates(keys_dir, "client") + + for key_file in os.listdir(keys_dir): + if key_file.endswith(".key"): + shutil.move(os.path.join(keys_dir, key_file), + os.path.join(public_keys_dir, '.')) + + for key_file in os.listdir(keys_dir): + if key_file.endswith(".key_secret"): + shutil.move(os.path.join(keys_dir, key_file), + os.path.join(secret_keys_dir, '.')) + + return (base_dir, public_keys_dir, secret_keys_dir) + + def remove_certs(self, base_dir): + """Remove certificates for a test""" + shutil.rmtree(base_dir) + + def load_certs(self, secret_keys_dir): + """Return server and client certificate keys""" + server_secret_file = os.path.join(secret_keys_dir, "server.key_secret") + client_secret_file = os.path.join(secret_keys_dir, "client.key_secret") + + server_public, server_secret = zmq.auth.load_certificate(server_secret_file) + client_public, client_secret = zmq.auth.load_certificate(client_secret_file) + + return server_public, server_secret, client_public, client_secret + + +class TestThreadAuthentication(BaseAuthTestCase): + """Test authentication running in a thread""" + + def make_auth(self): + return ThreadAuthenticator(self.context) + + def can_connect(self, server, client): + """Check if client can connect to server using tcp transport""" + result = False + iface = 'tcp://127.0.0.1' + port = server.bind_to_random_port(iface) + client.connect("%s:%i" % (iface, port)) + msg = [b"Hello World"] + if server.poll(1000, zmq.POLLOUT): + server.send_multipart(msg, zmq.NOBLOCK) + if client.poll(1000): + rcvd_msg = client.recv_multipart(zmq.NOBLOCK) + self.assertEqual(rcvd_msg, msg) + result = True + return result + + def test_null(self): + """threaded auth - NULL""" + # A default NULL connection should always succeed, and not + # go through our authentication infrastructure at all. + self.auth.stop() + self.auth = None + # use a new context, so ZAP isn't inherited + self.context = self.Context() + + server = self.socket(zmq.PUSH) + client = self.socket(zmq.PULL) + self.assertTrue(self.can_connect(server, client)) + + # By setting a domain we switch on authentication for NULL sockets, + # though no policies are configured yet. The client connection + # should still be allowed. + server = self.socket(zmq.PUSH) + server.zap_domain = b'global' + client = self.socket(zmq.PULL) + self.assertTrue(self.can_connect(server, client)) + + def test_blacklist(self): + """threaded auth - Blacklist""" + # Blacklist 127.0.0.1, connection should fail + self.auth.deny('127.0.0.1') + server = self.socket(zmq.PUSH) + # By setting a domain we switch on authentication for NULL sockets, + # though no policies are configured yet. + server.zap_domain = b'global' + client = self.socket(zmq.PULL) + self.assertFalse(self.can_connect(server, client)) + + def test_whitelist(self): + """threaded auth - Whitelist""" + # Whitelist 127.0.0.1, connection should pass" + self.auth.allow('127.0.0.1') + server = self.socket(zmq.PUSH) + # By setting a domain we switch on authentication for NULL sockets, + # though no policies are configured yet. + server.zap_domain = b'global' + client = self.socket(zmq.PULL) + self.assertTrue(self.can_connect(server, client)) + + def test_plain(self): + """threaded auth - PLAIN""" + + # Try PLAIN authentication - without configuring server, connection should fail + server = self.socket(zmq.PUSH) + server.plain_server = True + client = self.socket(zmq.PULL) + client.plain_username = b'admin' + client.plain_password = b'Password' + self.assertFalse(self.can_connect(server, client)) + + # Try PLAIN authentication - with server configured, connection should pass + server = self.socket(zmq.PUSH) + server.plain_server = True + client = self.socket(zmq.PULL) + client.plain_username = b'admin' + client.plain_password = b'Password' + self.auth.configure_plain(domain='*', passwords={'admin': 'Password'}) + self.assertTrue(self.can_connect(server, client)) + + # Try PLAIN authentication - with bogus credentials, connection should fail + server = self.socket(zmq.PUSH) + server.plain_server = True + client = self.socket(zmq.PULL) + client.plain_username = b'admin' + client.plain_password = b'Bogus' + self.assertFalse(self.can_connect(server, client)) + + # Remove authenticator and check that a normal connection works + self.auth.stop() + self.auth = None + + server = self.socket(zmq.PUSH) + client = self.socket(zmq.PULL) + self.assertTrue(self.can_connect(server, client)) + client.close() + server.close() + + def test_curve(self): + """threaded auth - CURVE""" + self.auth.allow('127.0.0.1') + certs = self.load_certs(self.secret_keys_dir) + server_public, server_secret, client_public, client_secret = certs + + #Try CURVE authentication - without configuring server, connection should fail + server = self.socket(zmq.PUSH) + server.curve_publickey = server_public + server.curve_secretkey = server_secret + server.curve_server = True + client = self.socket(zmq.PULL) + client.curve_publickey = client_public + client.curve_secretkey = client_secret + client.curve_serverkey = server_public + self.assertFalse(self.can_connect(server, client)) + + #Try CURVE authentication - with server configured to CURVE_ALLOW_ANY, connection should pass + self.auth.configure_curve(domain='*', location=zmq.auth.CURVE_ALLOW_ANY) + server = self.socket(zmq.PUSH) + server.curve_publickey = server_public + server.curve_secretkey = server_secret + server.curve_server = True + client = self.socket(zmq.PULL) + client.curve_publickey = client_public + client.curve_secretkey = client_secret + client.curve_serverkey = server_public + self.assertTrue(self.can_connect(server, client)) + + # Try CURVE authentication - with server configured, connection should pass + self.auth.configure_curve(domain='*', location=self.public_keys_dir) + server = self.socket(zmq.PULL) + server.curve_publickey = server_public + server.curve_secretkey = server_secret + server.curve_server = True + client = self.socket(zmq.PUSH) + client.curve_publickey = client_public + client.curve_secretkey = client_secret + client.curve_serverkey = server_public + assert self.can_connect(client, server) + + # Remove authenticator and check that a normal connection works + self.auth.stop() + self.auth = None + + # Try connecting using NULL and no authentication enabled, connection should pass + server = self.socket(zmq.PUSH) + client = self.socket(zmq.PULL) + self.assertTrue(self.can_connect(server, client)) + + def test_curve_callback(self): + """threaded auth - CURVE with callback authentication""" + self.auth.allow('127.0.0.1') + certs = self.load_certs(self.secret_keys_dir) + server_public, server_secret, client_public, client_secret = certs + + #Try CURVE authentication - without configuring server, connection should fail + server = self.socket(zmq.PUSH) + server.curve_publickey = server_public + server.curve_secretkey = server_secret + server.curve_server = True + client = self.socket(zmq.PULL) + client.curve_publickey = client_public + client.curve_secretkey = client_secret + client.curve_serverkey = server_public + self.assertFalse(self.can_connect(server, client)) + + #Try CURVE authentication - with callback authentication configured, connection should pass + + class CredentialsProvider(object): + def __init__(self): + self.client = client_public + + def callback(self, domain, key): + if (key == self.client): + return True + else: + return False + + provider = CredentialsProvider() + self.auth.configure_curve_callback(credentials_provider=provider) + server = self.socket(zmq.PUSH) + server.curve_publickey = server_public + server.curve_secretkey = server_secret + server.curve_server = True + client = self.socket(zmq.PULL) + client.curve_publickey = client_public + client.curve_secretkey = client_secret + client.curve_serverkey = server_public + self.assertTrue(self.can_connect(server, client)) + + #Try CURVE authentication - with callback authentication configured with wrong key, connection should not pass + + class WrongCredentialsProvider(object): + def __init__(self): + self.client = "WrongCredentials" + + def callback(self, domain, key): + if (key == self.client): + return True + else: + return False + + provider = WrongCredentialsProvider() + self.auth.configure_curve_callback(credentials_provider=provider) + server = self.socket(zmq.PUSH) + server.curve_publickey = server_public + server.curve_secretkey = server_secret + server.curve_server = True + client = self.socket(zmq.PULL) + client.curve_publickey = client_public + client.curve_secretkey = client_secret + client.curve_serverkey = server_public + self.assertFalse(self.can_connect(server, client)) + + + + @skip_pypy + def test_curve_user_id(self): + """threaded auth - CURVE""" + self.auth.allow('127.0.0.1') + certs = self.load_certs(self.secret_keys_dir) + server_public, server_secret, client_public, client_secret = certs + + self.auth.configure_curve(domain='*', location=self.public_keys_dir) + server = self.socket(zmq.PULL) + server.curve_publickey = server_public + server.curve_secretkey = server_secret + server.curve_server = True + client = self.socket(zmq.PUSH) + client.curve_publickey = client_public + client.curve_secretkey = client_secret + client.curve_serverkey = server_public + assert self.can_connect(client, server) + + # test default user-id map + client.send(b'test') + msg = self.recv(server, copy=False) + assert msg.bytes == b'test' + try: + user_id = msg.get('User-Id') + except zmq.ZMQVersionError: + pass + else: + assert user_id == u(client_public) + + # test custom user-id map + self.auth.curve_user_id = lambda client_key: u'custom' + + client2 = self.socket(zmq.PUSH) + client2.curve_publickey = client_public + client2.curve_secretkey = client_secret + client2.curve_serverkey = server_public + assert self.can_connect(client2, server) + + client2.send(b'test2') + msg = self.recv(server, copy=False) + assert msg.bytes == b'test2' + try: + user_id = msg.get('User-Id') + except zmq.ZMQVersionError: + pass + else: + assert user_id == u'custom' + + +def with_ioloop(method, expect_success=True): + """decorator for running tests with an IOLoop""" + def test_method(self): + r = method(self) + + loop = self.io_loop + if expect_success: + self.pullstream.on_recv(self.on_message_succeed) + else: + self.pullstream.on_recv(self.on_message_fail) + + loop.call_later(1, self.attempt_connection) + loop.call_later(1.2, self.send_msg) + + if expect_success: + loop.call_later(2, self.on_test_timeout_fail) + else: + loop.call_later(2, self.on_test_timeout_succeed) + + loop.start() + if self.fail_msg: + self.fail(self.fail_msg) + + return r + return test_method + +def should_auth(method): + return with_ioloop(method, True) + +def should_not_auth(method): + return with_ioloop(method, False) + +class TestIOLoopAuthentication(BaseAuthTestCase): + """Test authentication running in ioloop""" + + def setUp(self): + try: + from tornado import ioloop + except ImportError: + pytest.skip("Requires tornado") + from zmq.eventloop import zmqstream + self.fail_msg = None + self.io_loop = ioloop.IOLoop() + super(TestIOLoopAuthentication, self).setUp() + self.server = self.socket(zmq.PUSH) + self.client = self.socket(zmq.PULL) + self.pushstream = zmqstream.ZMQStream(self.server, self.io_loop) + self.pullstream = zmqstream.ZMQStream(self.client, self.io_loop) + + def make_auth(self): + from zmq.auth.ioloop import IOLoopAuthenticator + return IOLoopAuthenticator(self.context, io_loop=self.io_loop) + + def tearDown(self): + if self.auth: + self.auth.stop() + self.auth = None + self.io_loop.close(all_fds=True) + super(TestIOLoopAuthentication, self).tearDown() + + def attempt_connection(self): + """Check if client can connect to server using tcp transport""" + iface = 'tcp://127.0.0.1' + port = self.server.bind_to_random_port(iface) + self.client.connect("%s:%i" % (iface, port)) + + def send_msg(self): + """Send a message from server to a client""" + msg = [b"Hello World"] + self.pushstream.send_multipart(msg) + + def on_message_succeed(self, frames): + """A message was received, as expected.""" + if frames != [b"Hello World"]: + self.fail_msg = "Unexpected message received" + self.io_loop.stop() + + def on_message_fail(self, frames): + """A message was received, unexpectedly.""" + self.fail_msg = 'Received messaged unexpectedly, security failed' + self.io_loop.stop() + + def on_test_timeout_succeed(self): + """Test timer expired, indicates test success""" + self.io_loop.stop() + + def on_test_timeout_fail(self): + """Test timer expired, indicates test failure""" + self.fail_msg = 'Test timed out' + self.io_loop.stop() + + @should_auth + def test_none(self): + """ioloop auth - NONE""" + # A default NULL connection should always succeed, and not + # go through our authentication infrastructure at all. + # no auth should be running + self.auth.stop() + self.auth = None + + @should_auth + def test_null(self): + """ioloop auth - NULL""" + # By setting a domain we switch on authentication for NULL sockets, + # though no policies are configured yet. The client connection + # should still be allowed. + self.server.zap_domain = b'global' + + @should_not_auth + def test_blacklist(self): + """ioloop auth - Blacklist""" + # Blacklist 127.0.0.1, connection should fail + self.auth.deny('127.0.0.1') + self.server.zap_domain = b'global' + + @should_auth + def test_whitelist(self): + """ioloop auth - Whitelist""" + # Whitelist 127.0.0.1, which overrides the blacklist, connection should pass" + self.auth.allow('127.0.0.1') + + self.server.setsockopt(zmq.ZAP_DOMAIN, b'global') + + @should_not_auth + def test_plain_unconfigured_server(self): + """ioloop auth - PLAIN, unconfigured server""" + self.client.plain_username = b'admin' + self.client.plain_password = b'Password' + # Try PLAIN authentication - without configuring server, connection should fail + self.server.plain_server = True + + @should_auth + def test_plain_configured_server(self): + """ioloop auth - PLAIN, configured server""" + self.client.plain_username = b'admin' + self.client.plain_password = b'Password' + # Try PLAIN authentication - with server configured, connection should pass + self.server.plain_server = True + self.auth.configure_plain(domain='*', passwords={'admin': 'Password'}) + + @should_not_auth + def test_plain_bogus_credentials(self): + """ioloop auth - PLAIN, bogus credentials""" + self.client.plain_username = b'admin' + self.client.plain_password = b'Bogus' + self.server.plain_server = True + + self.auth.configure_plain(domain='*', passwords={'admin': 'Password'}) + + @should_not_auth + def test_curve_unconfigured_server(self): + """ioloop auth - CURVE, unconfigured server""" + certs = self.load_certs(self.secret_keys_dir) + server_public, server_secret, client_public, client_secret = certs + + self.auth.allow('127.0.0.1') + + self.server.curve_publickey = server_public + self.server.curve_secretkey = server_secret + self.server.curve_server = True + + self.client.curve_publickey = client_public + self.client.curve_secretkey = client_secret + self.client.curve_serverkey = server_public + + @should_auth + def test_curve_allow_any(self): + """ioloop auth - CURVE, CURVE_ALLOW_ANY""" + certs = self.load_certs(self.secret_keys_dir) + server_public, server_secret, client_public, client_secret = certs + + self.auth.allow('127.0.0.1') + self.auth.configure_curve(domain='*', location=zmq.auth.CURVE_ALLOW_ANY) + + self.server.curve_publickey = server_public + self.server.curve_secretkey = server_secret + self.server.curve_server = True + + self.client.curve_publickey = client_public + self.client.curve_secretkey = client_secret + self.client.curve_serverkey = server_public + + @should_auth + def test_curve_configured_server(self): + """ioloop auth - CURVE, configured server""" + self.auth.allow('127.0.0.1') + certs = self.load_certs(self.secret_keys_dir) + server_public, server_secret, client_public, client_secret = certs + + self.auth.configure_curve(domain='*', location=self.public_keys_dir) + + self.server.curve_publickey = server_public + self.server.curve_secretkey = server_secret + self.server.curve_server = True + + self.client.curve_publickey = client_public + self.client.curve_secretkey = client_secret + self.client.curve_serverkey = server_public diff --git a/.venv/lib/python3.8/site-packages/zmq/tests/test_cffi_backend.py b/.venv/lib/python3.8/site-packages/zmq/tests/test_cffi_backend.py new file mode 100644 index 00000000..bf2defe6 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/zmq/tests/test_cffi_backend.py @@ -0,0 +1,297 @@ +# -*- coding: utf8 -*- + +import sys +import time + +from unittest import TestCase + +from zmq.tests import BaseZMQTestCase, SkipTest + +try: + from zmq.backend.cffi import ( + zmq_version_info, + PUSH, PULL, IDENTITY, + REQ, REP, POLLIN, POLLOUT, + ) + from zmq.backend.cffi._cffi import ffi, C + have_ffi_backend = True +except ImportError: + have_ffi_backend = False + + +class TestCFFIBackend(TestCase): + + def setUp(self): + if not have_ffi_backend: + raise SkipTest('CFFI not available') + + def test_zmq_version_info(self): + version = zmq_version_info() + + assert version[0] in range(2,11) + + def test_zmq_ctx_new_destroy(self): + ctx = C.zmq_ctx_new() + + assert ctx != ffi.NULL + assert 0 == C.zmq_ctx_destroy(ctx) + + def test_zmq_socket_open_close(self): + ctx = C.zmq_ctx_new() + socket = C.zmq_socket(ctx, PUSH) + + assert ctx != ffi.NULL + assert ffi.NULL != socket + assert 0 == C.zmq_close(socket) + assert 0 == C.zmq_ctx_destroy(ctx) + + def test_zmq_setsockopt(self): + ctx = C.zmq_ctx_new() + socket = C.zmq_socket(ctx, PUSH) + + identity = ffi.new('char[3]', b'zmq') + ret = C.zmq_setsockopt(socket, IDENTITY, ffi.cast('void*', identity), 3) + + assert ret == 0 + assert ctx != ffi.NULL + assert ffi.NULL != socket + assert 0 == C.zmq_close(socket) + assert 0 == C.zmq_ctx_destroy(ctx) + + def test_zmq_getsockopt(self): + ctx = C.zmq_ctx_new() + socket = C.zmq_socket(ctx, PUSH) + + identity = ffi.new('char[]', b'zmq') + ret = C.zmq_setsockopt(socket, IDENTITY, ffi.cast('void*', identity), 3) + assert ret == 0 + + option_len = ffi.new('size_t*', 3) + option = ffi.new('char[3]') + ret = C.zmq_getsockopt(socket, + IDENTITY, + ffi.cast('void*', option), + option_len) + + assert ret == 0 + assert ffi.string(ffi.cast('char*', option))[0:1] == b"z" + assert ffi.string(ffi.cast('char*', option))[1:2] == b"m" + assert ffi.string(ffi.cast('char*', option))[2:3] == b"q" + assert ctx != ffi.NULL + assert ffi.NULL != socket + assert 0 == C.zmq_close(socket) + assert 0 == C.zmq_ctx_destroy(ctx) + + def test_zmq_bind(self): + ctx = C.zmq_ctx_new() + socket = C.zmq_socket(ctx, 8) + + assert 0 == C.zmq_bind(socket, b'tcp://*:4444') + assert ctx != ffi.NULL + assert ffi.NULL != socket + assert 0 == C.zmq_close(socket) + assert 0 == C.zmq_ctx_destroy(ctx) + + def test_zmq_bind_connect(self): + ctx = C.zmq_ctx_new() + + socket1 = C.zmq_socket(ctx, PUSH) + socket2 = C.zmq_socket(ctx, PULL) + + assert 0 == C.zmq_bind(socket1, b'tcp://*:4444') + assert 0 == C.zmq_connect(socket2, b'tcp://127.0.0.1:4444') + assert ctx != ffi.NULL + assert ffi.NULL != socket1 + assert ffi.NULL != socket2 + assert 0 == C.zmq_close(socket1) + assert 0 == C.zmq_close(socket2) + assert 0 == C.zmq_ctx_destroy(ctx) + + def test_zmq_msg_init_close(self): + zmq_msg = ffi.new('zmq_msg_t*') + + assert ffi.NULL != zmq_msg + assert 0 == C.zmq_msg_init(zmq_msg) + assert 0 == C.zmq_msg_close(zmq_msg) + + def test_zmq_msg_init_size(self): + zmq_msg = ffi.new('zmq_msg_t*') + + assert ffi.NULL != zmq_msg + assert 0 == C.zmq_msg_init_size(zmq_msg, 10) + assert 0 == C.zmq_msg_close(zmq_msg) + + def test_zmq_msg_init_data(self): + zmq_msg = ffi.new('zmq_msg_t*') + message = ffi.new('char[5]', b'Hello') + + assert 0 == C.zmq_msg_init_data(zmq_msg, + ffi.cast('void*', message), + 5, + ffi.NULL, + ffi.NULL) + + assert ffi.NULL != zmq_msg + assert 0 == C.zmq_msg_close(zmq_msg) + + def test_zmq_msg_data(self): + zmq_msg = ffi.new('zmq_msg_t*') + message = ffi.new('char[]', b'Hello') + assert 0 == C.zmq_msg_init_data(zmq_msg, + ffi.cast('void*', message), + 5, + ffi.NULL, + ffi.NULL) + + data = C.zmq_msg_data(zmq_msg) + + assert ffi.NULL != zmq_msg + assert ffi.string(ffi.cast("char*", data)) == b'Hello' + assert 0 == C.zmq_msg_close(zmq_msg) + + + def test_zmq_send(self): + ctx = C.zmq_ctx_new() + + sender = C.zmq_socket(ctx, REQ) + receiver = C.zmq_socket(ctx, REP) + + assert 0 == C.zmq_bind(receiver, b'tcp://*:7777') + assert 0 == C.zmq_connect(sender, b'tcp://127.0.0.1:7777') + + time.sleep(0.1) + + zmq_msg = ffi.new('zmq_msg_t*') + message = ffi.new('char[5]', b'Hello') + + C.zmq_msg_init_data(zmq_msg, + ffi.cast('void*', message), + ffi.cast('size_t', 5), + ffi.NULL, + ffi.NULL) + + assert 5 == C.zmq_msg_send(zmq_msg, sender, 0) + assert 0 == C.zmq_msg_close(zmq_msg) + assert C.zmq_close(sender) == 0 + assert C.zmq_close(receiver) == 0 + assert C.zmq_ctx_destroy(ctx) == 0 + + def test_zmq_recv(self): + ctx = C.zmq_ctx_new() + + sender = C.zmq_socket(ctx, REQ) + receiver = C.zmq_socket(ctx, REP) + + assert 0 == C.zmq_bind(receiver, b'tcp://*:2222') + assert 0 == C.zmq_connect(sender, b'tcp://127.0.0.1:2222') + + time.sleep(0.1) + + zmq_msg = ffi.new('zmq_msg_t*') + message = ffi.new('char[5]', b'Hello') + + C.zmq_msg_init_data(zmq_msg, + ffi.cast('void*', message), + ffi.cast('size_t', 5), + ffi.NULL, + ffi.NULL) + + zmq_msg2 = ffi.new('zmq_msg_t*') + C.zmq_msg_init(zmq_msg2) + + assert 5 == C.zmq_msg_send(zmq_msg, sender, 0) + assert 5 == C.zmq_msg_recv(zmq_msg2, receiver, 0) + assert 5 == C.zmq_msg_size(zmq_msg2) + assert b"Hello" == ffi.buffer(C.zmq_msg_data(zmq_msg2), + C.zmq_msg_size(zmq_msg2))[:] + assert C.zmq_close(sender) == 0 + assert C.zmq_close(receiver) == 0 + assert C.zmq_ctx_destroy(ctx) == 0 + + def test_zmq_poll(self): + ctx = C.zmq_ctx_new() + + sender = C.zmq_socket(ctx, REQ) + receiver = C.zmq_socket(ctx, REP) + + r1 = C.zmq_bind(receiver, b'tcp://*:3333') + r2 = C.zmq_connect(sender, b'tcp://127.0.0.1:3333') + + zmq_msg = ffi.new('zmq_msg_t*') + message = ffi.new('char[5]', b'Hello') + + C.zmq_msg_init_data(zmq_msg, + ffi.cast('void*', message), + ffi.cast('size_t', 5), + ffi.NULL, + ffi.NULL) + + receiver_pollitem = ffi.new('zmq_pollitem_t*') + receiver_pollitem.socket = receiver + receiver_pollitem.fd = 0 + receiver_pollitem.events = POLLIN | POLLOUT + receiver_pollitem.revents = 0 + + ret = C.zmq_poll(ffi.NULL, 0, 0) + assert ret == 0 + + ret = C.zmq_poll(receiver_pollitem, 1, 0) + assert ret == 0 + + ret = C.zmq_msg_send(zmq_msg, sender, 0) + print(ffi.string(C.zmq_strerror(C.zmq_errno()))) + assert ret == 5 + + time.sleep(0.2) + + ret = C.zmq_poll(receiver_pollitem, 1, 0) + assert ret == 1 + + assert int(receiver_pollitem.revents) & POLLIN + assert not int(receiver_pollitem.revents) & POLLOUT + + zmq_msg2 = ffi.new('zmq_msg_t*') + C.zmq_msg_init(zmq_msg2) + + ret_recv = C.zmq_msg_recv(zmq_msg2, receiver, 0) + assert ret_recv == 5 + + assert 5 == C.zmq_msg_size(zmq_msg2) + assert b"Hello" == ffi.buffer(C.zmq_msg_data(zmq_msg2), + C.zmq_msg_size(zmq_msg2))[:] + + sender_pollitem = ffi.new('zmq_pollitem_t*') + sender_pollitem.socket = sender + sender_pollitem.fd = 0 + sender_pollitem.events = POLLIN | POLLOUT + sender_pollitem.revents = 0 + + ret = C.zmq_poll(sender_pollitem, 1, 0) + assert ret == 0 + + zmq_msg_again = ffi.new('zmq_msg_t*') + message_again = ffi.new('char[11]', b'Hello Again') + + C.zmq_msg_init_data(zmq_msg_again, + ffi.cast('void*', message_again), + ffi.cast('size_t', 11), + ffi.NULL, + ffi.NULL) + + assert 11 == C.zmq_msg_send(zmq_msg_again, receiver, 0) + + time.sleep(0.2) + + assert 0 <= C.zmq_poll(sender_pollitem, 1, 0) + assert int(sender_pollitem.revents) & POLLIN + assert 11 == C.zmq_msg_recv(zmq_msg2, sender, 0) + assert 11 == C.zmq_msg_size(zmq_msg2) + assert b"Hello Again" == ffi.buffer(C.zmq_msg_data(zmq_msg2), + int(C.zmq_msg_size(zmq_msg2)))[:] + assert 0 == C.zmq_close(sender) + assert 0 == C.zmq_close(receiver) + assert 0 == C.zmq_ctx_destroy(ctx) + assert 0 == C.zmq_msg_close(zmq_msg) + assert 0 == C.zmq_msg_close(zmq_msg2) + assert 0 == C.zmq_msg_close(zmq_msg_again) + diff --git a/.venv/lib/python3.8/site-packages/zmq/tests/test_constants.py b/.venv/lib/python3.8/site-packages/zmq/tests/test_constants.py new file mode 100644 index 00000000..6b4d0c9b --- /dev/null +++ b/.venv/lib/python3.8/site-packages/zmq/tests/test_constants.py @@ -0,0 +1,121 @@ +# Copyright (C) PyZMQ Developers +# Distributed under the terms of the Modified BSD License. + +import json +from unittest import TestCase + +import pytest + +import zmq + +from zmq.utils import constant_names +from zmq.sugar import constants as sugar_constants +from zmq.backend import constants as backend_constants + +all_set = set(constant_names.all_names) + +class TestConstants(TestCase): + + def _duplicate_test(self, namelist, listname): + """test that a given list has no duplicates""" + dupes = {} + for name in set(namelist): + cnt = namelist.count(name) + if cnt > 1: + dupes[name] = cnt + if dupes: + self.fail("The following names occur more than once in %s: %s" % (listname, json.dumps(dupes, indent=2))) + + def test_duplicate_all(self): + return self._duplicate_test(constant_names.all_names, "all_names") + + def _change_key(self, change, version): + """return changed-in key""" + return "%s-in %d.%d.%d" % tuple([change] + list(version)) + + def test_duplicate_changed(self): + all_changed = [] + for change in ("new", "removed"): + d = getattr(constant_names, change + "_in") + for version, namelist in d.items(): + all_changed.extend(namelist) + self._duplicate_test(namelist, self._change_key(change, version)) + + self._duplicate_test(all_changed, "all-changed") + + def test_changed_in_all(self): + missing = {} + for change in ("new", "removed"): + d = getattr(constant_names, change + "_in") + for version, namelist in d.items(): + key = self._change_key(change, version) + for name in namelist: + if name not in all_set: + if key not in missing: + missing[key] = [] + missing[key].append(name) + + if missing: + self.fail( + "The following names are missing in `all_names`: %s" % json.dumps(missing, indent=2) + ) + + def test_no_negative_constants(self): + for name in sugar_constants.__all__: + self.assertNotEqual(getattr(zmq, name), sugar_constants._UNDEFINED) + + def test_undefined_constants(self): + all_aliases = [] + for alias_group in sugar_constants.aliases: + all_aliases.extend(alias_group) + + for name in all_set.difference(all_aliases): + raw = getattr(backend_constants, name) + if raw == sugar_constants._UNDEFINED: + self.assertRaises(AttributeError, getattr, zmq, name) + else: + self.assertEqual(getattr(zmq, name), raw) + + def test_new(self): + zmq_version = zmq.zmq_version_info() + for version, new_names in constant_names.new_in.items(): + should_have = zmq_version >= version + for name in new_names: + try: + value = getattr(zmq, name) + except AttributeError: + if should_have: + self.fail("AttributeError: zmq.%s" % name) + else: + if not should_have: + self.fail("Shouldn't have: zmq.%s=%s" % (name, value)) + + @pytest.mark.skipif(not zmq.DRAFT_API, reason="Only test draft API if built with draft API") + def test_draft(self): + zmq_version = zmq.zmq_version_info() + for version, new_names in constant_names.draft_in.items(): + should_have = zmq_version >= version + for name in new_names: + try: + value = getattr(zmq, name) + except AttributeError: + if should_have: + self.fail("AttributeError: zmq.%s" % name) + else: + if not should_have: + self.fail("Shouldn't have: zmq.%s=%s" % (name, value)) + + def test_removed(self): + zmq_version = zmq.zmq_version_info() + for version, new_names in constant_names.removed_in.items(): + should_have = zmq_version < version + for name in new_names: + try: + value = getattr(zmq, name) + except AttributeError: + if should_have: + self.fail("AttributeError: zmq.%s" % name) + else: + if not should_have: + self.fail("Shouldn't have: zmq.%s=%s" % (name, value)) + diff --git a/.venv/lib/python3.8/site-packages/zmq/tests/test_context.py b/.venv/lib/python3.8/site-packages/zmq/tests/test_context.py new file mode 100644 index 00000000..9632a8bc --- /dev/null +++ b/.venv/lib/python3.8/site-packages/zmq/tests/test_context.py @@ -0,0 +1,392 @@ +# Copyright (C) PyZMQ Developers +# Distributed under the terms of the Modified BSD License. + +import copy +import gc +import os +import sys +import time +from threading import Thread, Event +try: + from queue import Queue +except ImportError: + from Queue import Queue +try: + from unittest import mock +except ImportError: + mock = None + +from pytest import mark + +import zmq +from zmq.tests import ( + BaseZMQTestCase, have_gevent, GreenTest, skip_green, PYPY, SkipTest, +) + + +class KwargTestSocket(zmq.Socket): + test_kwarg_value = None + + def __init__(self, *args, **kwargs): + self.test_kwarg_value = kwargs.pop('test_kwarg', None) + super(KwargTestSocket, self).__init__(*args, **kwargs) + + +class KwargTestContext(zmq.Context): + _socket_class = KwargTestSocket + + +class TestContext(BaseZMQTestCase): + + def test_init(self): + c1 = self.Context() + self.assertTrue(isinstance(c1, self.Context)) + del c1 + c2 = self.Context() + self.assertTrue(isinstance(c2, self.Context)) + del c2 + c3 = self.Context() + self.assertTrue(isinstance(c3, self.Context)) + del c3 + + def test_dir(self): + ctx = self.Context() + self.assertTrue('socket' in dir(ctx)) + if zmq.zmq_version_info() > (3,): + self.assertTrue('IO_THREADS' in dir(ctx)) + ctx.term() + + @mark.skipif(mock is None, reason="requires unittest.mock") + def test_mockable(self): + m = mock.Mock(spec=self.context) + + + def test_term(self): + c = self.Context() + c.term() + self.assertTrue(c.closed) + + def test_context_manager(self): + with self.Context() as c: + pass + self.assertTrue(c.closed) + + def test_fail_init(self): + self.assertRaisesErrno(zmq.EINVAL, self.Context, -1) + + def test_term_hang(self): + rep,req = self.create_bound_pair(zmq.ROUTER, zmq.DEALER) + req.setsockopt(zmq.LINGER, 0) + req.send(b'hello', copy=False) + req.close() + rep.close() + self.context.term() + + def test_instance(self): + ctx = self.Context.instance() + c2 = self.Context.instance(io_threads=2) + self.assertTrue(c2 is ctx) + c2.term() + c3 = self.Context.instance() + c4 = self.Context.instance() + self.assertFalse(c3 is c2) + self.assertFalse(c3.closed) + self.assertTrue(c3 is c4) + + def test_instance_subclass_first(self): + self.context.term() + class SubContext(zmq.Context): + pass + sctx = SubContext.instance() + ctx = zmq.Context.instance() + ctx.term() + sctx.term() + assert type(ctx) is zmq.Context + assert type(sctx) is SubContext + + def test_instance_subclass_second(self): + self.context.term() + class SubContextInherit(zmq.Context): + pass + class SubContextNoInherit(zmq.Context): + _instance = None + pass + ctx = zmq.Context.instance() + sctx = SubContextInherit.instance() + sctx2 = SubContextNoInherit.instance() + ctx.term() + sctx.term() + sctx2.term() + assert type(ctx) is zmq.Context + assert type(sctx) is zmq.Context + assert type(sctx2) is SubContextNoInherit + + def test_instance_threadsafe(self): + self.context.term() # clear default context + + q = Queue() + # slow context initialization, + # to ensure that we are both trying to create one at the same time + class SlowContext(self.Context): + def __init__(self, *a, **kw): + time.sleep(1) + super(SlowContext, self).__init__(*a, **kw) + + def f(): + q.put(SlowContext.instance()) + + # call ctx.instance() in several threads at once + N = 16 + threads = [ Thread(target=f) for i in range(N) ] + [ t.start() for t in threads ] + # also call it in the main thread (not first) + ctx = SlowContext.instance() + assert isinstance(ctx, SlowContext) + # check that all the threads got the same context + for i in range(N): + thread_ctx = q.get(timeout=5) + assert thread_ctx is ctx + # cleanup + ctx.term() + [ t.join(timeout=5) for t in threads ] + + def test_socket_passes_kwargs(self): + test_kwarg_value = 'testing one two three' + with KwargTestContext() as ctx: + with ctx.socket(zmq.DEALER, test_kwarg=test_kwarg_value) as socket: + self.assertTrue(socket.test_kwarg_value is test_kwarg_value) + + def test_many_sockets(self): + """opening and closing many sockets shouldn't cause problems""" + ctx = self.Context() + for i in range(16): + sockets = [ ctx.socket(zmq.REP) for i in range(65) ] + [ s.close() for s in sockets ] + # give the reaper a chance + time.sleep(1e-2) + ctx.term() + + def test_sockopts(self): + """setting socket options with ctx attributes""" + ctx = self.Context() + ctx.linger = 5 + self.assertEqual(ctx.linger, 5) + s = ctx.socket(zmq.REQ) + self.assertEqual(s.linger, 5) + self.assertEqual(s.getsockopt(zmq.LINGER), 5) + s.close() + # check that subscribe doesn't get set on sockets that don't subscribe: + ctx.subscribe = b'' + s = ctx.socket(zmq.REQ) + s.close() + + ctx.term() + + @mark.skipif( + sys.platform.startswith('win'), + reason='Segfaults on Windows') + def test_destroy(self): + """Context.destroy should close sockets""" + ctx = self.Context() + sockets = [ ctx.socket(zmq.REP) for i in range(65) ] + + # close half of the sockets + [ s.close() for s in sockets[::2] ] + + ctx.destroy() + # reaper is not instantaneous + time.sleep(1e-2) + for s in sockets: + self.assertTrue(s.closed) + + def test_destroy_linger(self): + """Context.destroy should set linger on closing sockets""" + req,rep = self.create_bound_pair(zmq.REQ, zmq.REP) + req.send(b'hi') + time.sleep(1e-2) + self.context.destroy(linger=0) + # reaper is not instantaneous + time.sleep(1e-2) + for s in (req,rep): + self.assertTrue(s.closed) + + def test_term_noclose(self): + """Context.term won't close sockets""" + ctx = self.Context() + s = ctx.socket(zmq.REQ) + self.assertFalse(s.closed) + t = Thread(target=ctx.term) + t.start() + t.join(timeout=0.1) + self.assertTrue(t.is_alive(), "Context should be waiting") + s.close() + t.join(timeout=0.1) + self.assertFalse(t.is_alive(), "Context should have closed") + + def test_gc(self): + """test close&term by garbage collection alone""" + if PYPY: + raise SkipTest("GC doesn't work ") + + # test credit @dln (GH #137): + def gcf(): + def inner(): + ctx = self.Context() + s = ctx.socket(zmq.PUSH) + inner() + gc.collect() + t = Thread(target=gcf) + t.start() + t.join(timeout=1) + self.assertFalse(t.is_alive(), "Garbage collection should have cleaned up context") + + def test_cyclic_destroy(self): + """ctx.destroy should succeed when cyclic ref prevents gc""" + # test credit @dln (GH #137): + class CyclicReference(object): + def __init__(self, parent=None): + self.parent = parent + + def crash(self, sock): + self.sock = sock + self.child = CyclicReference(self) + + def crash_zmq(): + ctx = self.Context() + sock = ctx.socket(zmq.PULL) + c = CyclicReference() + c.crash(sock) + ctx.destroy() + + crash_zmq() + + def test_term_thread(self): + """ctx.term should not crash active threads (#139)""" + ctx = self.Context() + evt = Event() + evt.clear() + + def block(): + s = ctx.socket(zmq.REP) + s.bind_to_random_port('tcp://127.0.0.1') + evt.set() + try: + s.recv() + except zmq.ZMQError as e: + self.assertEqual(e.errno, zmq.ETERM) + return + finally: + s.close() + self.fail("recv should have been interrupted with ETERM") + t = Thread(target=block) + t.start() + + evt.wait(1) + self.assertTrue(evt.is_set(), "sync event never fired") + time.sleep(0.01) + ctx.term() + t.join(timeout=1) + self.assertFalse(t.is_alive(), "term should have interrupted s.recv()") + + def test_destroy_no_sockets(self): + ctx = self.Context() + s = ctx.socket(zmq.PUB) + s.bind_to_random_port('tcp://127.0.0.1') + s.close() + ctx.destroy() + assert s.closed + assert ctx.closed + + def test_ctx_opts(self): + if zmq.zmq_version_info() < (3,): + raise SkipTest("context options require libzmq 3") + ctx = self.Context() + ctx.set(zmq.MAX_SOCKETS, 2) + self.assertEqual(ctx.get(zmq.MAX_SOCKETS), 2) + ctx.max_sockets = 100 + self.assertEqual(ctx.max_sockets, 100) + self.assertEqual(ctx.get(zmq.MAX_SOCKETS), 100) + + def test_copy(self): + c1 = self.Context() + c2 = copy.copy(c1) + c2b = copy.deepcopy(c1) + c3 = copy.deepcopy(c2) + self.assertTrue(c2._shadow) + self.assertTrue(c3._shadow) + self.assertEqual(c1.underlying, c2.underlying) + self.assertEqual(c1.underlying, c3.underlying) + self.assertEqual(c1.underlying, c2b.underlying) + s = c3.socket(zmq.PUB) + s.close() + c1.term() + + def test_shadow(self): + ctx = self.Context() + ctx2 = self.Context.shadow(ctx.underlying) + self.assertEqual(ctx.underlying, ctx2.underlying) + s = ctx.socket(zmq.PUB) + s.close() + del ctx2 + self.assertFalse(ctx.closed) + s = ctx.socket(zmq.PUB) + ctx2 = self.Context.shadow(ctx.underlying) + s2 = ctx2.socket(zmq.PUB) + s.close() + s2.close() + ctx.term() + self.assertRaisesErrno(zmq.EFAULT, ctx2.socket, zmq.PUB) + del ctx2 + + def test_shadow_pyczmq(self): + try: + from pyczmq import zctx, zsocket, zstr + except Exception: + raise SkipTest("Requires pyczmq") + + ctx = zctx.new() + a = zsocket.new(ctx, zmq.PUSH) + zsocket.bind(a, "inproc://a") + ctx2 = self.Context.shadow_pyczmq(ctx) + b = ctx2.socket(zmq.PULL) + b.connect("inproc://a") + zstr.send(a, b'hi') + rcvd = self.recv(b) + self.assertEqual(rcvd, b'hi') + b.close() + + @mark.skipif( + sys.platform.startswith('win'), + reason='No fork on Windows') + def test_fork_instance(self): + ctx = self.Context.instance() + parent_ctx_id = id(ctx) + r_fd, w_fd = os.pipe() + reader = os.fdopen(r_fd, 'r') + child_pid = os.fork() + if child_pid == 0: + ctx = self.Context.instance() + writer = os.fdopen(w_fd, 'w') + child_ctx_id = id(ctx) + ctx.term() + writer.write(str(child_ctx_id) + "\n") + writer.flush() + writer.close() + os._exit(0) + else: + os.close(w_fd) + + child_id_s = reader.readline() + reader.close() + assert child_id_s + assert int(child_id_s) != parent_ctx_id + ctx.term() + + +if False: # disable green context tests + class TestContextGreen(GreenTest, TestContext): + """gevent subclass of context tests""" + # skip tests that use real threads: + test_gc = GreenTest.skip_green + test_term_thread = GreenTest.skip_green + test_destroy_linger = GreenTest.skip_green diff --git a/.venv/lib/python3.8/site-packages/zmq/tests/test_cython.py b/.venv/lib/python3.8/site-packages/zmq/tests/test_cython.py new file mode 100644 index 00000000..fa0c0d0b --- /dev/null +++ b/.venv/lib/python3.8/site-packages/zmq/tests/test_cython.py @@ -0,0 +1,41 @@ +import os +import sys + +import pytest +import zmq + +@pytest.mark.skipif( + 'zmq.backend.cython' not in sys.modules, reason="Requires cython backend" +) +@pytest.mark.skipif( + sys.platform.startswith('win'), reason="Don't try runtime Cython on Windows" +) +@pytest.mark.parametrize('language_level', [3, 2]) +def test_cython(language_level, request, tmpdir): + import pyximport + + assert 'zmq.tests.cython_ext' not in sys.modules + + importers = pyximport.install( + setup_args=dict(include_dirs=zmq.get_includes()), + language_level=language_level, + build_dir=str(tmpdir), + ) + + cython_ext = None + + def unimport(): + pyximport.uninstall(*importers) + sys.modules.pop('zmq.tests.cython_ext', None) + + request.addfinalizer(unimport) + + # this import tests the compilation + from . import cython_ext + assert hasattr(cython_ext, 'send_recv_test') + + # call the compiled function + # this shouldn't do much + msg = b'my msg' + received = cython_ext.send_recv_test(msg) + assert received == msg diff --git a/.venv/lib/python3.8/site-packages/zmq/tests/test_decorators.py b/.venv/lib/python3.8/site-packages/zmq/tests/test_decorators.py new file mode 100644 index 00000000..ae6af3df --- /dev/null +++ b/.venv/lib/python3.8/site-packages/zmq/tests/test_decorators.py @@ -0,0 +1,375 @@ +import threading +import zmq + +from pytest import raises +from zmq.decorators import context, socket + + +############################################## +# Test cases for @context +############################################## + + +def test_ctx(): + @context() + def test(ctx): + assert isinstance(ctx, zmq.Context), ctx + test() + + +def test_ctx_orig_args(): + @context() + def f(foo, bar, ctx, baz=None): + assert isinstance(ctx, zmq.Context), ctx + assert foo == 42 + assert bar is True + assert baz == 'mock' + + f(42, True, baz='mock') + + +def test_ctx_arg_naming(): + @context('myctx') + def test(myctx): + assert isinstance(myctx, zmq.Context), myctx + test() + + +def test_ctx_args(): + @context('ctx', 5) + def test(ctx): + assert isinstance(ctx, zmq.Context), ctx + assert ctx.IO_THREADS == 5, ctx.IO_THREADS + test() + + +def test_ctx_arg_kwarg(): + @context('ctx', io_threads=5) + def test(ctx): + assert isinstance(ctx, zmq.Context), ctx + assert ctx.IO_THREADS == 5, ctx.IO_THREADS + test() + + +def test_ctx_kw_naming(): + @context(name='myctx') + def test(myctx): + assert isinstance(myctx, zmq.Context), myctx + test() + + +def test_ctx_kwargs(): + @context(name='ctx', io_threads=5) + def test(ctx): + assert isinstance(ctx, zmq.Context), ctx + assert ctx.IO_THREADS == 5, ctx.IO_THREADS + test() + + +def test_ctx_kwargs_default(): + @context(name='ctx', io_threads=5) + def test(ctx=None): + assert isinstance(ctx, zmq.Context), ctx + assert ctx.IO_THREADS == 5, ctx.IO_THREADS + test() + + +def test_ctx_keyword_miss(): + @context(name='ctx') + def test(other_name): + pass # the keyword ``ctx`` not found + with raises(TypeError): + test() + + +def test_ctx_multi_assign(): + @context(name='ctx') + def test(ctx): + pass # explosion + with raises(TypeError): + test('mock') + + +def test_ctx_reinit(): + result = {'foo': None, 'bar': None} + + @context() + def f(key, ctx): + assert isinstance(ctx, zmq.Context), ctx + result[key] = ctx + + foo_t = threading.Thread(target=f, args=('foo',)) + bar_t = threading.Thread(target=f, args=('bar',)) + + foo_t.start() + bar_t.start() + + foo_t.join() + bar_t.join() + + assert result['foo'] is not None, result + assert result['bar'] is not None, result + assert result['foo'] is not result['bar'], result + + +def test_ctx_multi_thread(): + @context() + @context() + def f(foo, bar): + assert isinstance(foo, zmq.Context), foo + assert isinstance(bar, zmq.Context), bar + + assert len(set(map(id, [foo, bar]))) == 2, set(map(id, [foo, bar])) + + threads = [threading.Thread(target=f) for i in range(8)] + [t.start() for t in threads] + [t.join() for t in threads] + + +############################################## +# Test cases for @socket +############################################## + + +def test_ctx_skt(): + @context() + @socket(zmq.PUB) + def test(ctx, skt): + assert isinstance(ctx, zmq.Context), ctx + assert isinstance(skt, zmq.Socket), skt + assert skt.type == zmq.PUB + test() + + +def test_skt_name(): + @context() + @socket('myskt', zmq.PUB) + def test(ctx, myskt): + assert isinstance(myskt, zmq.Socket), myskt + assert isinstance(ctx, zmq.Context), ctx + assert myskt.type == zmq.PUB + test() + + +def test_skt_kwarg(): + @context() + @socket(zmq.PUB, name='myskt') + def test(ctx, myskt): + assert isinstance(myskt, zmq.Socket), myskt + assert isinstance(ctx, zmq.Context), ctx + assert myskt.type == zmq.PUB + test() + + +def test_ctx_skt_name(): + @context('ctx') + @socket('skt', zmq.PUB, context_name='ctx') + def test(ctx, skt): + assert isinstance(skt, zmq.Socket), skt + assert isinstance(ctx, zmq.Context), ctx + assert skt.type == zmq.PUB + test() + + +def test_skt_default_ctx(): + @socket(zmq.PUB) + def test(skt): + assert isinstance(skt, zmq.Socket), skt + assert skt.context is zmq.Context.instance() + assert skt.type == zmq.PUB + test() + + +def test_skt_reinit(): + result = {'foo': None, 'bar': None} + + @socket(zmq.PUB) + def f(key, skt): + assert isinstance(skt, zmq.Socket), skt + + result[key] = skt + + foo_t = threading.Thread(target=f, args=('foo',)) + bar_t = threading.Thread(target=f, args=('bar',)) + + foo_t.start() + bar_t.start() + + foo_t.join() + bar_t.join() + + assert result['foo'] is not None, result + assert result['bar'] is not None, result + assert result['foo'] is not result['bar'], result + + +def test_ctx_skt_reinit(): + result = {'foo': {'ctx': None, 'skt': None}, + 'bar': {'ctx': None, 'skt': None}} + + @context() + @socket(zmq.PUB) + def f(key, ctx, skt): + assert isinstance(ctx, zmq.Context), ctx + assert isinstance(skt, zmq.Socket), skt + + result[key]['ctx'] = ctx + result[key]['skt'] = skt + + foo_t = threading.Thread(target=f, args=('foo',)) + bar_t = threading.Thread(target=f, args=('bar',)) + + foo_t.start() + bar_t.start() + + foo_t.join() + bar_t.join() + + assert result['foo']['ctx'] is not None, result + assert result['foo']['skt'] is not None, result + assert result['bar']['ctx'] is not None, result + assert result['bar']['skt'] is not None, result + assert result['foo']['ctx'] is not result['bar']['ctx'], result + assert result['foo']['skt'] is not result['bar']['skt'], result + + +def test_skt_type_miss(): + @context() + @socket('myskt') + def f(ctx, myskt): + pass # the socket type is missing + with raises(TypeError): + f() + + +def test_multi_skts(): + @socket(zmq.PUB) + @socket(zmq.SUB) + @socket(zmq.PUSH) + def test(pub, sub, push): + assert isinstance(pub, zmq.Socket), pub + assert isinstance(sub, zmq.Socket), sub + assert isinstance(push, zmq.Socket), push + + assert pub.context is zmq.Context.instance() + assert sub.context is zmq.Context.instance() + assert push.context is zmq.Context.instance() + + assert pub.type == zmq.PUB + assert sub.type == zmq.SUB + assert push.type == zmq.PUSH + test() + + +def test_multi_skts_single_ctx(): + @context() + @socket(zmq.PUB) + @socket(zmq.SUB) + @socket(zmq.PUSH) + def test(ctx, pub, sub, push): + assert isinstance(ctx, zmq.Context), ctx + assert isinstance(pub, zmq.Socket), pub + assert isinstance(sub, zmq.Socket), sub + assert isinstance(push, zmq.Socket), push + + assert pub.context is ctx + assert sub.context is ctx + assert push.context is ctx + + assert pub.type == zmq.PUB + assert sub.type == zmq.SUB + assert push.type == zmq.PUSH + test() + + +def test_multi_skts_with_name(): + @socket('foo', zmq.PUSH) + @socket('bar', zmq.SUB) + @socket('baz', zmq.PUB) + def test(foo, bar, baz): + assert isinstance(foo, zmq.Socket), foo + assert isinstance(bar, zmq.Socket), bar + assert isinstance(baz, zmq.Socket), baz + + assert foo.context is zmq.Context.instance() + assert bar.context is zmq.Context.instance() + assert baz.context is zmq.Context.instance() + + assert foo.type == zmq.PUSH + assert bar.type == zmq.SUB + assert baz.type == zmq.PUB + test() + +def test_func_return(): + @context() + def f(ctx): + assert isinstance(ctx, zmq.Context), ctx + return 'something' + + assert f() == 'something' + + +def test_skt_multi_thread(): + @socket(zmq.PUB) + @socket(zmq.SUB) + @socket(zmq.PUSH) + def f(pub, sub, push): + assert isinstance(pub, zmq.Socket), pub + assert isinstance(sub, zmq.Socket), sub + assert isinstance(push, zmq.Socket), push + + assert pub.context is zmq.Context.instance() + assert sub.context is zmq.Context.instance() + assert push.context is zmq.Context.instance() + + assert pub.type == zmq.PUB + assert sub.type == zmq.SUB + assert push.type == zmq.PUSH + + assert len(set(map(id, [pub, sub, push]))) == 3 + + threads = [threading.Thread(target=f) for i in range(8)] + [t.start() for t in threads] + [t.join() for t in threads] + + +class TestMethodDecorators(): + @context() + @socket(zmq.PUB) + @socket(zmq.SUB) + def multi_skts_method(self, ctx, pub, sub, foo='bar'): + assert isinstance(self, TestMethodDecorators), self + assert isinstance(ctx, zmq.Context), ctx + assert isinstance(pub, zmq.Socket), pub + assert isinstance(sub, zmq.Socket), sub + assert foo == 'bar' + + assert pub.context is ctx + assert sub.context is ctx + + assert pub.type is zmq.PUB + assert sub.type is zmq.SUB + + def test_multi_skts_method(self): + self.multi_skts_method() + + def multi_skts_method_other_args(self): + @socket(zmq.PUB) + @socket(zmq.SUB) + def f(foo, pub, sub, bar=None): + assert isinstance(pub, zmq.Socket), pub + assert isinstance(sub, zmq.Socket), sub + + assert foo == 'mock' + assert bar == 'fake' + + assert pub.context is zmq.Context.instance() + assert sub.context is zmq.Context.instance() + + assert pub.type is zmq.PUB + assert sub.type is zmq.SUB + + f('mock', bar='fake') + + def test_multi_skts_method_other_args(self): + self.multi_skts_method_other_args() diff --git a/.venv/lib/python3.8/site-packages/zmq/tests/test_device.py b/.venv/lib/python3.8/site-packages/zmq/tests/test_device.py new file mode 100644 index 00000000..6292488e --- /dev/null +++ b/.venv/lib/python3.8/site-packages/zmq/tests/test_device.py @@ -0,0 +1,167 @@ +# Copyright (C) PyZMQ Developers +# Distributed under the terms of the Modified BSD License. + +import time + +import zmq +from zmq import devices +from zmq.tests import BaseZMQTestCase, SkipTest, have_gevent, GreenTest, PYPY +from zmq.utils.strtypes import (bytes,unicode,basestring) + +if PYPY: + # cleanup of shared Context doesn't work on PyPy + devices.Device.context_factory = zmq.Context + +class TestDevice(BaseZMQTestCase): + + def test_device_types(self): + for devtype in (zmq.STREAMER, zmq.FORWARDER, zmq.QUEUE): + dev = devices.Device(devtype, zmq.PAIR, zmq.PAIR) + self.assertEqual(dev.device_type, devtype) + del dev + + def test_device_attributes(self): + dev = devices.Device(zmq.QUEUE, zmq.SUB, zmq.PUB) + self.assertEqual(dev.in_type, zmq.SUB) + self.assertEqual(dev.out_type, zmq.PUB) + self.assertEqual(dev.device_type, zmq.QUEUE) + self.assertEqual(dev.daemon, True) + del dev + + def test_single_socket_forwarder_connect(self): + if zmq.zmq_version() in ('4.1.1', '4.0.6'): + raise SkipTest("libzmq-%s broke single-socket devices" % zmq.zmq_version()) + dev = devices.ThreadDevice(zmq.QUEUE, zmq.REP, -1) + req = self.context.socket(zmq.REQ) + port = req.bind_to_random_port('tcp://127.0.0.1') + dev.connect_in('tcp://127.0.0.1:%i'%port) + dev.start() + time.sleep(.25) + msg = b'hello' + req.send(msg) + self.assertEqual(msg, self.recv(req)) + del dev + req.close() + dev = devices.ThreadDevice(zmq.QUEUE, zmq.REP, -1) + req = self.context.socket(zmq.REQ) + port = req.bind_to_random_port('tcp://127.0.0.1') + dev.connect_out('tcp://127.0.0.1:%i'%port) + dev.start() + time.sleep(.25) + msg = b'hello again' + req.send(msg) + self.assertEqual(msg, self.recv(req)) + del dev + req.close() + + def test_single_socket_forwarder_bind(self): + if zmq.zmq_version() in ('4.1.1', '4.0.6'): + raise SkipTest("libzmq-%s broke single-socket devices" % zmq.zmq_version()) + dev = devices.ThreadDevice(zmq.QUEUE, zmq.REP, -1) + port = dev.bind_in_to_random_port('tcp://127.0.0.1') + req = self.context.socket(zmq.REQ) + req.connect('tcp://127.0.0.1:%i'%port) + dev.start() + time.sleep(.25) + msg = b'hello' + req.send(msg) + self.assertEqual(msg, self.recv(req)) + del dev + req.close() + dev = devices.ThreadDevice(zmq.QUEUE, zmq.REP, -1) + port = dev.bind_in_to_random_port('tcp://127.0.0.1') + req = self.context.socket(zmq.REQ) + req.connect('tcp://127.0.0.1:%i'%port) + dev.start() + time.sleep(.25) + msg = b'hello again' + req.send(msg) + self.assertEqual(msg, self.recv(req)) + del dev + req.close() + + def test_device_bind_to_random_with_args(self): + dev = devices.ThreadDevice(zmq.PULL, zmq.PUSH, -1) + iface = 'tcp://127.0.0.1' + ports = [] + min, max = 5000, 5050 + ports.extend([ + dev.bind_in_to_random_port(iface, min_port=min, max_port=max), + dev.bind_out_to_random_port(iface, min_port=min, max_port=max) + ]) + for port in ports: + if port < min or port > max: + self.fail('Unexpected port number: %i' % port) + + def test_device_bind_to_random_binderror(self): + dev = devices.ThreadDevice(zmq.PULL, zmq.PUSH, -1) + iface = 'tcp://127.0.0.1' + try: + for i in range(11): + dev.bind_in_to_random_port( + iface, min_port=10000, max_port=10010 + ) + except zmq.ZMQBindError as e: + return + else: + self.fail('Should have failed') + + def test_proxy(self): + if zmq.zmq_version_info() < (3,2): + raise SkipTest("Proxies only in libzmq >= 3") + dev = devices.ThreadProxy(zmq.PULL, zmq.PUSH, zmq.PUSH) + iface = 'tcp://127.0.0.1' + port = dev.bind_in_to_random_port(iface) + port2 = dev.bind_out_to_random_port(iface) + port3 = dev.bind_mon_to_random_port(iface) + dev.start() + time.sleep(0.25) + msg = b'hello' + push = self.context.socket(zmq.PUSH) + push.connect("%s:%i" % (iface, port)) + pull = self.context.socket(zmq.PULL) + pull.connect("%s:%i" % (iface, port2)) + mon = self.context.socket(zmq.PULL) + mon.connect("%s:%i" % (iface, port3)) + push.send(msg) + self.sockets.extend([push, pull, mon]) + self.assertEqual(msg, self.recv(pull)) + self.assertEqual(msg, self.recv(mon)) + + def test_proxy_bind_to_random_with_args(self): + if zmq.zmq_version_info() < (3, 2): + raise SkipTest("Proxies only in libzmq >= 3") + dev = devices.ThreadProxy(zmq.PULL, zmq.PUSH, zmq.PUSH) + iface = 'tcp://127.0.0.1' + ports = [] + min, max = 5000, 5050 + ports.extend([ + dev.bind_in_to_random_port(iface, min_port=min, max_port=max), + dev.bind_out_to_random_port(iface, min_port=min, max_port=max), + dev.bind_mon_to_random_port(iface, min_port=min, max_port=max) + ]) + for port in ports: + if port < min or port > max: + self.fail('Unexpected port number: %i' % port) + +if have_gevent: + import gevent + import zmq.green + + class TestDeviceGreen(GreenTest, BaseZMQTestCase): + + def test_green_device(self): + rep = self.context.socket(zmq.REP) + req = self.context.socket(zmq.REQ) + self.sockets.extend([req, rep]) + port = rep.bind_to_random_port('tcp://127.0.0.1') + g = gevent.spawn(zmq.green.device, zmq.QUEUE, rep, rep) + req.connect('tcp://127.0.0.1:%i' % port) + req.send(b'hi') + timeout = gevent.Timeout(3) + timeout.start() + receiver = gevent.spawn(req.recv) + self.assertEqual(receiver.get(2), b'hi') + timeout.cancel() + g.kill(block=True) + diff --git a/.venv/lib/python3.8/site-packages/zmq/tests/test_draft.py b/.venv/lib/python3.8/site-packages/zmq/tests/test_draft.py new file mode 100644 index 00000000..5bb9e29d --- /dev/null +++ b/.venv/lib/python3.8/site-packages/zmq/tests/test_draft.py @@ -0,0 +1,52 @@ +# -*- coding: utf8 -*- +# Copyright (C) PyZMQ Developers +# Distributed under the terms of the Modified BSD License. + +import os +import platform +import time + +import pytest +import zmq +from zmq.tests import ( + BaseZMQTestCase, skip_pypy +) + + +class TestDraftSockets(BaseZMQTestCase): + def setUp(self): + if not zmq.DRAFT_API: + raise pytest.skip("draft api unavailable") + super(TestDraftSockets, self).setUp() + + + def test_client_server(self): + client, server = self.create_bound_pair(zmq.CLIENT, zmq.SERVER) + client.send(b'request') + msg = self.recv(server, copy=False) + assert msg.routing_id is not None + server.send(b'reply', routing_id=msg.routing_id) + reply = self.recv(client) + assert reply == b'reply' + + def test_radio_dish(self): + dish, radio = self.create_bound_pair(zmq.DISH, zmq.RADIO) + dish.rcvtimeo = 250 + group = 'mygroup' + dish.join(group) + received_count = 0 + received = set() + sent = set() + for i in range(10): + msg = str(i).encode('ascii') + sent.add(msg) + radio.send(msg, group=group) + try: + recvd = dish.recv() + except zmq.Again: + time.sleep(0.1) + else: + received.add(recvd) + received_count += 1 + # assert that we got *something* + assert len(received.intersection(sent)) >= 5 diff --git a/.venv/lib/python3.8/site-packages/zmq/tests/test_error.py b/.venv/lib/python3.8/site-packages/zmq/tests/test_error.py new file mode 100644 index 00000000..6b1dc907 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/zmq/tests/test_error.py @@ -0,0 +1,43 @@ +# -*- coding: utf8 -*- +# Copyright (C) PyZMQ Developers +# Distributed under the terms of the Modified BSD License. + +import sys +import time +from threading import Thread + +import zmq +from zmq import ZMQError, strerror, Again, ContextTerminated +from zmq.tests import BaseZMQTestCase + +if sys.version_info[0] >= 3: + long = int + +class TestZMQError(BaseZMQTestCase): + + def test_strerror(self): + """test that strerror gets the right type.""" + for i in range(10): + e = strerror(i) + self.assertTrue(isinstance(e, str)) + + def test_zmqerror(self): + for errno in range(10): + e = ZMQError(errno) + self.assertEqual(e.errno, errno) + self.assertEqual(str(e), strerror(errno)) + + def test_again(self): + s = self.context.socket(zmq.REP) + self.assertRaises(Again, s.recv, zmq.NOBLOCK) + self.assertRaisesErrno(zmq.EAGAIN, s.recv, zmq.NOBLOCK) + s.close() + + def atest_ctxterm(self): + s = self.context.socket(zmq.REP) + t = Thread(target=self.context.term) + t.start() + self.assertRaises(ContextTerminated, s.recv, zmq.NOBLOCK) + self.assertRaisesErrno(zmq.TERM, s.recv, zmq.NOBLOCK) + s.close() + t.join() diff --git a/.venv/lib/python3.8/site-packages/zmq/tests/test_etc.py b/.venv/lib/python3.8/site-packages/zmq/tests/test_etc.py new file mode 100644 index 00000000..020dc22b --- /dev/null +++ b/.venv/lib/python3.8/site-packages/zmq/tests/test_etc.py @@ -0,0 +1,20 @@ +# Copyright (c) PyZMQ Developers. +# Distributed under the terms of the Modified BSD License. + +import sys + +import zmq + +from pytest import mark + +@mark.skipif('zmq.zmq_version_info() < (4,1)') +def test_has(): + assert not zmq.has('something weird') + has_ipc = zmq.has('ipc') + not_windows = not sys.platform.startswith('win') + assert has_ipc == not_windows + +@mark.skipif(not hasattr(zmq, '_libzmq'), reason="bundled libzmq") +def test_has_curve(): + """bundled libzmq has curve support""" + assert zmq.has('curve') diff --git a/.venv/lib/python3.8/site-packages/zmq/tests/test_future.py b/.venv/lib/python3.8/site-packages/zmq/tests/test_future.py new file mode 100644 index 00000000..8077028e --- /dev/null +++ b/.venv/lib/python3.8/site-packages/zmq/tests/test_future.py @@ -0,0 +1,341 @@ +# coding: utf-8 +# Copyright (c) PyZMQ Developers +# Distributed under the terms of the Modified BSD License. + +from datetime import timedelta +import os +import json +import sys + +import pytest +gen = pytest.importorskip('tornado.gen') + +import zmq +from zmq.eventloop import future +from tornado.ioloop import IOLoop +from zmq.utils.strtypes import u + +from zmq.tests import BaseZMQTestCase + + +class TestFutureSocket(BaseZMQTestCase): + Context = future.Context + + def setUp(self): + self.loop = IOLoop() + self.loop.make_current() + super(TestFutureSocket, self).setUp() + + def tearDown(self): + super(TestFutureSocket, self).tearDown() + if self.loop: + self.loop.close(all_fds=True) + IOLoop.clear_current() + IOLoop.clear_instance() + + def test_socket_class(self): + s = self.context.socket(zmq.PUSH) + assert isinstance(s, future.Socket) + s.close() + + def test_instance_subclass_first(self): + actx = self.Context.instance() + ctx = zmq.Context.instance() + ctx.term() + actx.term() + assert type(ctx) is zmq.Context + assert type(actx) is self.Context + + def test_instance_subclass_second(self): + ctx = zmq.Context.instance() + actx = self.Context.instance() + ctx.term() + actx.term() + assert type(ctx) is zmq.Context + assert type(actx) is self.Context + + def test_recv_multipart(self): + async def test(): + a, b = self.create_bound_pair(zmq.PUSH, zmq.PULL) + f = b.recv_multipart() + assert not f.done() + await a.send(b"hi") + recvd = await f + self.assertEqual(recvd, [b'hi']) + self.loop.run_sync(test) + + def test_recv(self): + async def test(): + a, b = self.create_bound_pair(zmq.PUSH, zmq.PULL) + f1 = b.recv() + f2 = b.recv() + assert not f1.done() + assert not f2.done() + await a.send_multipart([b"hi", b"there"]) + recvd = await f2 + assert f1.done() + self.assertEqual(f1.result(), b'hi') + self.assertEqual(recvd, b'there') + self.loop.run_sync(test) + + def test_recv_cancel(self): + async def test(): + a, b = self.create_bound_pair(zmq.PUSH, zmq.PULL) + f1 = b.recv() + f2 = b.recv_multipart() + assert f1.cancel() + assert f1.done() + assert not f2.done() + await a.send_multipart([b"hi", b"there"]) + recvd = await f2 + assert f1.cancelled() + assert f2.done() + self.assertEqual(recvd, [b'hi', b'there']) + self.loop.run_sync(test) + + @pytest.mark.skipif(not hasattr(zmq, 'RCVTIMEO'), reason="requires RCVTIMEO") + def test_recv_timeout(self): + async def test(): + a, b = self.create_bound_pair(zmq.PUSH, zmq.PULL) + b.rcvtimeo = 100 + f1 = b.recv() + b.rcvtimeo = 1000 + f2 = b.recv_multipart() + with pytest.raises(zmq.Again): + await f1 + await a.send_multipart([b"hi", b"there"]) + recvd = await f2 + assert f2.done() + self.assertEqual(recvd, [b'hi', b'there']) + self.loop.run_sync(test) + + @pytest.mark.skipif(not hasattr(zmq, 'SNDTIMEO'), reason="requires SNDTIMEO") + def test_send_timeout(self): + async def test(): + s = self.socket(zmq.PUSH) + s.sndtimeo = 100 + with pytest.raises(zmq.Again): + await s.send(b"not going anywhere") + + self.loop.run_sync(test) + + @pytest.mark.now + def test_send_noblock(self): + async def test(): + s = self.socket(zmq.PUSH) + with pytest.raises(zmq.Again): + await s.send(b"not going anywhere", flags=zmq.NOBLOCK) + + self.loop.run_sync(test) + + @pytest.mark.now + def test_send_multipart_noblock(self): + async def test(): + s = self.socket(zmq.PUSH) + with pytest.raises(zmq.Again): + await s.send_multipart([b"not going anywhere"], flags=zmq.NOBLOCK) + + self.loop.run_sync(test) + + def test_recv_string(self): + async def test(): + a, b = self.create_bound_pair(zmq.PUSH, zmq.PULL) + f = b.recv_string() + assert not f.done() + msg = u('πøøπ') + await a.send_string(msg) + recvd = await f + assert f.done() + self.assertEqual(f.result(), msg) + self.assertEqual(recvd, msg) + self.loop.run_sync(test) + + def test_recv_json(self): + async def test(): + a, b = self.create_bound_pair(zmq.PUSH, zmq.PULL) + f = b.recv_json() + assert not f.done() + obj = dict(a=5) + await a.send_json(obj) + recvd = await f + assert f.done() + self.assertEqual(f.result(), obj) + self.assertEqual(recvd, obj) + self.loop.run_sync(test) + + def test_recv_json_cancelled(self): + async def test(): + a, b = self.create_bound_pair(zmq.PUSH, zmq.PULL) + f = b.recv_json() + assert not f.done() + f.cancel() + # cycle eventloop to allow cancel events to fire + await gen.sleep(0) + obj = dict(a=5) + await a.send_json(obj) + with pytest.raises(future.CancelledError): + recvd = await f + assert f.done() + # give it a chance to incorrectly consume the event + events = await b.poll(timeout=5) + assert events + await gen.sleep(0) + # make sure cancelled recv didn't eat up event + recvd = await gen.with_timeout(timedelta(seconds=5), b.recv_json()) + assert recvd == obj + self.loop.run_sync(test) + + def test_recv_pyobj(self): + async def test(): + a, b = self.create_bound_pair(zmq.PUSH, zmq.PULL) + f = b.recv_pyobj() + assert not f.done() + obj = dict(a=5) + await a.send_pyobj(obj) + recvd = await f + assert f.done() + self.assertEqual(f.result(), obj) + self.assertEqual(recvd, obj) + self.loop.run_sync(test) + + def test_custom_serialize(self): + def serialize(msg): + frames = [] + frames.extend(msg.get('identities', [])) + content = json.dumps(msg['content']).encode('utf8') + frames.append(content) + return frames + + def deserialize(frames): + identities = frames[:-1] + content = json.loads(frames[-1].decode('utf8')) + return { + 'identities': identities, + 'content': content, + } + + async def test(): + a, b = self.create_bound_pair(zmq.DEALER, zmq.ROUTER) + + msg = { + 'content': { + 'a': 5, + 'b': 'bee', + } + } + await a.send_serialized(msg, serialize) + recvd = await b.recv_serialized(deserialize) + assert recvd['content'] == msg['content'] + assert recvd['identities'] + # bounce back, tests identities + await b.send_serialized(recvd, serialize) + r2 = await a.recv_serialized(deserialize) + assert r2['content'] == msg['content'] + assert not r2['identities'] + self.loop.run_sync(test) + + def test_custom_serialize_error(self): + async def test(): + a, b = self.create_bound_pair(zmq.DEALER, zmq.ROUTER) + + msg = { + 'content': { + 'a': 5, + 'b': 'bee', + } + } + with pytest.raises(TypeError): + await a.send_serialized(json, json.dumps) + + await a.send(b"not json") + with pytest.raises(TypeError): + recvd = await b.recv_serialized(json.loads) + self.loop.run_sync(test) + + def test_poll(self): + async def test(): + a, b = self.create_bound_pair(zmq.PUSH, zmq.PULL) + f = b.poll(timeout=0) + assert f.done() + self.assertEqual(f.result(), 0) + + f = b.poll(timeout=1) + assert not f.done() + evt = await f + self.assertEqual(evt, 0) + + f = b.poll(timeout=1000) + assert not f.done() + await a.send_multipart([b"hi", b"there"]) + evt = await f + self.assertEqual(evt, zmq.POLLIN) + recvd = await b.recv_multipart() + self.assertEqual(recvd, [b'hi', b'there']) + self.loop.run_sync(test) + + @pytest.mark.skipif( + sys.platform.startswith('win'), + reason='Windows unsupported socket type') + def test_poll_base_socket(self): + async def test(): + ctx = zmq.Context() + url = 'inproc://test' + a = ctx.socket(zmq.PUSH) + b = ctx.socket(zmq.PULL) + self.sockets.extend([a, b]) + a.bind(url) + b.connect(url) + + poller = future.Poller() + poller.register(b, zmq.POLLIN) + + f = poller.poll(timeout=1000) + assert not f.done() + a.send_multipart([b'hi', b'there']) + evt = await f + self.assertEqual(evt, [(b, zmq.POLLIN)]) + recvd = b.recv_multipart() + self.assertEqual(recvd, [b'hi', b'there']) + a.close() + b.close() + ctx.term() + self.loop.run_sync(test) + + def test_close_all_fds(self): + s = self.socket(zmq.PUB) + self.loop.close(all_fds=True) + self.loop = None # avoid second close later + assert s.closed + + @pytest.mark.skipif( + sys.platform.startswith('win'), + reason='Windows does not support polling on files') + def test_poll_raw(self): + async def test(): + p = future.Poller() + # make a pipe + r, w = os.pipe() + r = os.fdopen(r, 'rb') + w = os.fdopen(w, 'wb') + + # POLLOUT + p.register(r, zmq.POLLIN) + p.register(w, zmq.POLLOUT) + evts = await p.poll(timeout=1) + evts = dict(evts) + assert r.fileno() not in evts + assert w.fileno() in evts + assert evts[w.fileno()] == zmq.POLLOUT + + # POLLIN + p.unregister(w) + w.write(b'x') + w.flush() + evts = await p.poll(timeout=1000) + evts = dict(evts) + assert r.fileno() in evts + assert evts[r.fileno()] == zmq.POLLIN + assert r.read(1) == b'x' + r.close() + w.close() + self.loop.run_sync(test) diff --git a/.venv/lib/python3.8/site-packages/zmq/tests/test_imports.py b/.venv/lib/python3.8/site-packages/zmq/tests/test_imports.py new file mode 100644 index 00000000..2aa01167 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/zmq/tests/test_imports.py @@ -0,0 +1,68 @@ +# Copyright (C) PyZMQ Developers +# Distributed under the terms of the Modified BSD License. + +import sys +from unittest import TestCase + +import pytest + +class TestImports(TestCase): + """Test Imports - the quickest test to ensure that we haven't + introduced version-incompatible syntax errors.""" + + def test_toplevel(self): + """test toplevel import""" + import zmq + + def test_core(self): + """test core imports""" + from zmq import Context + from zmq import Socket + from zmq import Poller + from zmq import Frame + from zmq import constants + from zmq import device, proxy + from zmq import ( + zmq_version, + zmq_version_info, + pyzmq_version, + pyzmq_version_info, + ) + + def test_devices(self): + """test device imports""" + import zmq.devices + from zmq.devices import basedevice + from zmq.devices import monitoredqueue + from zmq.devices import monitoredqueuedevice + + def test_log(self): + """test log imports""" + import zmq.log + from zmq.log import handlers + + def test_eventloop(self): + """test eventloop imports""" + try: + import tornado + except ImportError: + pytest.skip('requires tornado') + import zmq.eventloop + from zmq.eventloop import ioloop + from zmq.eventloop import zmqstream + + def test_utils(self): + """test util imports""" + import zmq.utils + from zmq.utils import strtypes + from zmq.utils import jsonapi + + def test_ssh(self): + """test ssh imports""" + from zmq.ssh import tunnel + + def test_decorators(self): + """test decorators imports""" + from zmq.decorators import context, socket + + diff --git a/.venv/lib/python3.8/site-packages/zmq/tests/test_includes.py b/.venv/lib/python3.8/site-packages/zmq/tests/test_includes.py new file mode 100644 index 00000000..b1c23f13 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/zmq/tests/test_includes.py @@ -0,0 +1,33 @@ +# Copyright (C) PyZMQ Developers +# Distributed under the terms of the Modified BSD License. + + +from unittest import TestCase +import zmq +import os + +class TestIncludes(TestCase): + + def test_get_includes(self): + from os.path import dirname, basename + includes = zmq.get_includes() + self.assertTrue(isinstance(includes, list)) + self.assertTrue(len(includes) >= 2) + parent = includes[0] + self.assertTrue(isinstance(parent, str)) + utilsdir = includes[1] + self.assertTrue(isinstance(utilsdir, str)) + utils = basename(utilsdir) + self.assertEqual(utils, "utils") + + def test_get_library_dirs(self): + from os.path import dirname, basename + libdirs = zmq.get_library_dirs() + self.assertTrue(isinstance(libdirs, list)) + self.assertEqual(len(libdirs), 1) + parent = libdirs[0] + self.assertTrue(isinstance(parent, str)) + libdir = basename(parent) + self.assertEqual(libdir, "zmq") + + \ No newline at end of file diff --git a/.venv/lib/python3.8/site-packages/zmq/tests/test_ioloop.py b/.venv/lib/python3.8/site-packages/zmq/tests/test_ioloop.py new file mode 100644 index 00000000..a7cf58e2 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/zmq/tests/test_ioloop.py @@ -0,0 +1,141 @@ +# Copyright (C) PyZMQ Developers +# Distributed under the terms of the Modified BSD License. + +from __future__ import absolute_import +try: + import asyncio +except ImportError: + asyncio = None +import time +import os +import threading + +import pytest + +import zmq +from zmq.tests import BaseZMQTestCase, have_gevent +try: + from tornado.ioloop import IOLoop as BaseIOLoop + from zmq.eventloop import ioloop + _tornado = True +except ImportError: + _tornado = False + + +# tornado 5 with asyncio disables custom IOLoop implementations +t5asyncio = False +if _tornado: + import tornado + if tornado.version_info >= (5,) and asyncio: + t5asyncio = True + +def printer(): + os.system("say hello") + raise Exception + print (time.time()) + + +class Delay(threading.Thread): + def __init__(self, f, delay=1): + self.f=f + self.delay=delay + self.aborted=False + self.cond=threading.Condition() + super(Delay, self).__init__() + + def run(self): + self.cond.acquire() + self.cond.wait(self.delay) + self.cond.release() + if not self.aborted: + self.f() + + def abort(self): + self.aborted=True + self.cond.acquire() + self.cond.notify() + self.cond.release() + + +class TestIOLoop(BaseZMQTestCase): + if _tornado: + IOLoop = ioloop.IOLoop + + def setUp(self): + if not _tornado: + pytest.skip("tornado required") + super(TestIOLoop, self).setUp() + if asyncio: + asyncio.set_event_loop(asyncio.new_event_loop()) + + def tearDown(self): + super(TestIOLoop, self).tearDown() + BaseIOLoop.clear_current() + BaseIOLoop.clear_instance() + + def test_simple(self): + """simple IOLoop creation test""" + loop = self.IOLoop() + loop.make_current() + dc = ioloop.PeriodicCallback(loop.stop, 200) + pc = ioloop.PeriodicCallback(lambda : None, 10) + pc.start() + dc.start() + t = Delay(loop.stop,1) + t.start() + loop.start() + if t.is_alive(): + t.abort() + else: + self.fail("IOLoop failed to exit") + + def test_instance(self): + """IOLoop.instance returns the right object""" + loop = self.IOLoop.instance() + if not t5asyncio: + assert isinstance(loop, self.IOLoop) + base_loop = BaseIOLoop.instance() + assert base_loop is loop + + def test_current(self): + """IOLoop.current returns the right object""" + loop = ioloop.IOLoop.current() + if not t5asyncio: + assert isinstance(loop, self.IOLoop) + base_loop = BaseIOLoop.current() + assert base_loop is loop + + def test_close_all(self): + """Test close(all_fds=True)""" + loop = self.IOLoop.current() + req,rep = self.create_bound_pair(zmq.REQ, zmq.REP) + loop.add_handler(req, lambda msg: msg, ioloop.IOLoop.READ) + loop.add_handler(rep, lambda msg: msg, ioloop.IOLoop.READ) + self.assertEqual(req.closed, False) + self.assertEqual(rep.closed, False) + loop.close(all_fds=True) + self.assertEqual(req.closed, True) + self.assertEqual(rep.closed, True) + + +if have_gevent and _tornado: + import zmq.green.eventloop.ioloop as green_ioloop + + class TestIOLoopGreen(TestIOLoop): + IOLoop = green_ioloop.IOLoop + def xtest_instance(self): + """Green IOLoop.instance returns the right object""" + loop = self.IOLoop.instance() + if not t5asyncio: + assert isinstance(loop, self.IOLoop) + base_loop = BaseIOLoop.instance() + assert base_loop is loop + + def xtest_current(self): + """Green IOLoop.current returns the right object""" + loop = self.IOLoop.current() + if not t5asyncio: + assert isinstance(loop, self.IOLoop) + base_loop = BaseIOLoop.current() + assert base_loop is loop + diff --git a/.venv/lib/python3.8/site-packages/zmq/tests/test_log.py b/.venv/lib/python3.8/site-packages/zmq/tests/test_log.py new file mode 100644 index 00000000..619fba78 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/zmq/tests/test_log.py @@ -0,0 +1,178 @@ +# encoding: utf-8 + +# Copyright (C) PyZMQ Developers +# Distributed under the terms of the Modified BSD License. + + +import logging +import time +from unittest import TestCase + +import zmq +from zmq.log import handlers +from zmq.utils.strtypes import b, u +from zmq.tests import BaseZMQTestCase + + +class TestPubLog(BaseZMQTestCase): + + iface = 'inproc://zmqlog' + topic= 'zmq' + + @property + def logger(self): + # print dir(self) + logger = logging.getLogger('zmqtest') + logger.setLevel(logging.DEBUG) + return logger + + def connect_handler(self, topic=None): + topic = self.topic if topic is None else topic + logger = self.logger + pub,sub = self.create_bound_pair(zmq.PUB, zmq.SUB) + handler = handlers.PUBHandler(pub) + handler.setLevel(logging.DEBUG) + handler.root_topic = topic + logger.addHandler(handler) + sub.setsockopt(zmq.SUBSCRIBE, b(topic)) + time.sleep(0.1) + return logger, handler, sub + + def test_init_iface(self): + logger = self.logger + ctx = self.context + handler = handlers.PUBHandler(self.iface) + self.assertFalse(handler.ctx is ctx) + self.sockets.append(handler.socket) + # handler.ctx.term() + handler = handlers.PUBHandler(self.iface, self.context) + self.sockets.append(handler.socket) + self.assertTrue(handler.ctx is ctx) + handler.setLevel(logging.DEBUG) + handler.root_topic = self.topic + logger.addHandler(handler) + sub = ctx.socket(zmq.SUB) + self.sockets.append(sub) + sub.setsockopt(zmq.SUBSCRIBE, b(self.topic)) + sub.connect(self.iface) + import time; time.sleep(0.25) + msg1 = 'message' + logger.info(msg1) + + (topic, msg2) = sub.recv_multipart() + self.assertEqual(topic, b'zmq.INFO') + self.assertEqual(msg2, b(msg1)+b'\n') + logger.removeHandler(handler) + + def test_init_socket(self): + pub,sub = self.create_bound_pair(zmq.PUB, zmq.SUB) + logger = self.logger + handler = handlers.PUBHandler(pub) + handler.setLevel(logging.DEBUG) + handler.root_topic = self.topic + logger.addHandler(handler) + + self.assertTrue(handler.socket is pub) + self.assertTrue(handler.ctx is pub.context) + self.assertTrue(handler.ctx is self.context) + sub.setsockopt(zmq.SUBSCRIBE, b(self.topic)) + import time; time.sleep(0.1) + msg1 = 'message' + logger.info(msg1) + + (topic, msg2) = sub.recv_multipart() + self.assertEqual(topic, b'zmq.INFO') + self.assertEqual(msg2, b(msg1)+b'\n') + logger.removeHandler(handler) + + def test_root_topic(self): + logger, handler, sub = self.connect_handler() + handler.socket.bind(self.iface) + sub2 = sub.context.socket(zmq.SUB) + self.sockets.append(sub2) + sub2.connect(self.iface) + sub2.setsockopt(zmq.SUBSCRIBE, b'') + handler.root_topic = b'twoonly' + msg1 = 'ignored' + logger.info(msg1) + self.assertRaisesErrno(zmq.EAGAIN, sub.recv, zmq.NOBLOCK) + topic,msg2 = sub2.recv_multipart() + self.assertEqual(topic, b'twoonly.INFO') + self.assertEqual(msg2, b(msg1)+b'\n') + + logger.removeHandler(handler) + + def test_blank_root_topic(self): + logger, handler, sub_everything = self.connect_handler() + sub_everything.setsockopt(zmq.SUBSCRIBE, b'') + handler.socket.bind(self.iface) + sub_only_info = sub_everything.context.socket(zmq.SUB) + self.sockets.append(sub_only_info) + sub_only_info.connect(self.iface) + sub_only_info.setsockopt(zmq.SUBSCRIBE, b'INFO') + handler.setRootTopic(b'') + msg_debug = 'debug_message' + logger.debug(msg_debug) + self.assertRaisesErrno(zmq.EAGAIN, sub_only_info.recv, zmq.NOBLOCK) + topic, msg_debug_response = sub_everything.recv_multipart() + self.assertEqual(topic, b'DEBUG') + msg_info = 'info_message' + logger.info(msg_info) + topic, msg_info_response_everything = sub_everything.recv_multipart() + self.assertEqual(topic, b'INFO') + topic, msg_info_response_onlyinfo = sub_only_info.recv_multipart() + self.assertEqual(topic, b'INFO') + self.assertEqual(msg_info_response_everything, msg_info_response_onlyinfo) + + logger.removeHandler(handler) + + def test_unicode_message(self): + logger, handler, sub = self.connect_handler() + base_topic = b(self.topic + '.INFO') + for msg, expected in [ + (u('hello'), [base_topic, b('hello\n')]), + (u('héllo'), [base_topic, b('héllo\n')]), + (u('tøpic::héllo'), [base_topic + b('.tøpic'), b('héllo\n')]), + ]: + logger.info(msg) + received = sub.recv_multipart() + self.assertEqual(received, expected) + logger.removeHandler(handler) + + def test_set_info_formatter_via_property(self): + logger, handler, sub = self.connect_handler() + handler.formatters[logging.INFO] = logging.Formatter("%(message)s UNITTEST\n") + handler.socket.bind(self.iface) + sub.setsockopt(zmq.SUBSCRIBE, b(handler.root_topic)) + logger.info('info message') + topic, msg = sub.recv_multipart() + self.assertEqual(msg, b'info message UNITTEST\n') + logger.removeHandler(handler) + + def test_custom_global_formatter(self): + logger, handler, sub = self.connect_handler() + formatter = logging.Formatter("UNITTEST %(message)s") + handler.setFormatter(formatter) + handler.socket.bind(self.iface) + sub.setsockopt(zmq.SUBSCRIBE, b(handler.root_topic)) + logger.info('info message') + topic, msg = sub.recv_multipart() + self.assertEqual(msg, b'UNITTEST info message') + logger.debug('debug message') + topic, msg = sub.recv_multipart() + self.assertEqual(msg, b'UNITTEST debug message') + logger.removeHandler(handler) + + def test_custom_debug_formatter(self): + logger, handler, sub = self.connect_handler() + formatter = logging.Formatter("UNITTEST DEBUG %(message)s") + handler.setFormatter(formatter, logging.DEBUG) + handler.socket.bind(self.iface) + sub.setsockopt(zmq.SUBSCRIBE, b(handler.root_topic)) + logger.info('info message') + topic, msg = sub.recv_multipart() + self.assertEqual(msg, b'info message\n') + logger.debug('debug message') + topic, msg = sub.recv_multipart() + self.assertEqual(msg, b'UNITTEST DEBUG debug message') + logger.removeHandler(handler) diff --git a/.venv/lib/python3.8/site-packages/zmq/tests/test_message.py b/.venv/lib/python3.8/site-packages/zmq/tests/test_message.py new file mode 100644 index 00000000..73b5a7fd --- /dev/null +++ b/.venv/lib/python3.8/site-packages/zmq/tests/test_message.py @@ -0,0 +1,347 @@ +# -*- coding: utf8 -*- +# Copyright (C) PyZMQ Developers +# Distributed under the terms of the Modified BSD License. + + +import copy +import sys +try: + from sys import getrefcount as grc +except ImportError: + grc = None + +import time +from pprint import pprint +from unittest import TestCase + +import zmq +from zmq.tests import BaseZMQTestCase, SkipTest, skip_pypy, PYPY +from zmq.utils.strtypes import unicode, bytes, b, u + + +# some useful constants: + +x = b'x' + +if grc: + rc0 = grc(x) + v = memoryview(x) + view_rc = grc(x) - rc0 + +def await_gc(obj, rc): + """wait for refcount on an object to drop to an expected value + + Necessary because of the zero-copy gc thread, + which can take some time to receive its DECREF message. + """ + for i in range(50): + # rc + 2 because of the refs in this function + if grc(obj) <= rc + 2: + return + time.sleep(0.05) + +class TestFrame(BaseZMQTestCase): + + @skip_pypy + def test_above_30(self): + """Message above 30 bytes are never copied by 0MQ.""" + for i in range(5, 16): # 32, 64,..., 65536 + s = (2**i)*x + self.assertEqual(grc(s), 2) + m = zmq.Frame(s, copy=False) + self.assertEqual(grc(s), 4) + del m + await_gc(s, 2) + self.assertEqual(grc(s), 2) + del s + + def test_str(self): + """Test the str representations of the Frames.""" + for i in range(16): + s = (2**i)*x + m = zmq.Frame(s) + m_str = str(m) + m_str_b = b(m_str) # py3compat + self.assertEqual(s, m_str_b) + + def test_bytes(self): + """Test the Frame.bytes property.""" + for i in range(1,16): + s = (2**i)*x + m = zmq.Frame(s) + b = m.bytes + self.assertEqual(s, m.bytes) + if not PYPY: + # check that it copies + self.assertTrue(b is not s) + # check that it copies only once + self.assertTrue(b is m.bytes) + + def test_unicode(self): + """Test the unicode representations of the Frames.""" + s = u('asdf') + self.assertRaises(TypeError, zmq.Frame, s) + for i in range(16): + s = (2**i)*u('§') + m = zmq.Frame(s.encode('utf8')) + self.assertEqual(s, unicode(m.bytes,'utf8')) + + def test_len(self): + """Test the len of the Frames.""" + for i in range(16): + s = (2**i)*x + m = zmq.Frame(s) + self.assertEqual(len(s), len(m)) + + @skip_pypy + def test_lifecycle1(self): + """Run through a ref counting cycle with a copy.""" + for i in range(5, 16): # 32, 64,..., 65536 + s = (2**i)*x + rc = 2 + self.assertEqual(grc(s), rc) + m = zmq.Frame(s, copy=False) + rc += 2 + self.assertEqual(grc(s), rc) + m2 = copy.copy(m) + rc += 1 + self.assertEqual(grc(s), rc) + buf = m2.buffer + + rc += view_rc + self.assertEqual(grc(s), rc) + + self.assertEqual(s, b(str(m))) + self.assertEqual(s, bytes(m2)) + self.assertEqual(s, m.bytes) + # self.assertTrue(s is str(m)) + # self.assertTrue(s is str(m2)) + del m2 + rc -= 1 + self.assertEqual(grc(s), rc) + rc -= view_rc + del buf + self.assertEqual(grc(s), rc) + del m + rc -= 2 + await_gc(s, rc) + self.assertEqual(grc(s), rc) + self.assertEqual(rc, 2) + del s + + @skip_pypy + def test_lifecycle2(self): + """Run through a different ref counting cycle with a copy.""" + for i in range(5, 16): # 32, 64,..., 65536 + s = (2**i)*x + rc = 2 + self.assertEqual(grc(s), rc) + m = zmq.Frame(s, copy=False) + rc += 2 + self.assertEqual(grc(s), rc) + m2 = copy.copy(m) + rc += 1 + self.assertEqual(grc(s), rc) + buf = m.buffer + rc += view_rc + self.assertEqual(grc(s), rc) + self.assertEqual(s, b(str(m))) + self.assertEqual(s, bytes(m2)) + self.assertEqual(s, m2.bytes) + self.assertEqual(s, m.bytes) + # self.assertTrue(s is str(m)) + # self.assertTrue(s is str(m2)) + del buf + self.assertEqual(grc(s), rc) + del m + # m.buffer is kept until m is del'd + rc -= view_rc + rc -= 1 + self.assertEqual(grc(s), rc) + del m2 + rc -= 2 + await_gc(s, rc) + self.assertEqual(grc(s), rc) + self.assertEqual(rc, 2) + del s + + @skip_pypy + def test_tracker(self): + m = zmq.Frame(b'asdf', copy=False, track=True) + self.assertFalse(m.tracker.done) + pm = zmq.MessageTracker(m) + self.assertFalse(pm.done) + del m + for i in range(10): + if pm.done: + break + time.sleep(0.1) + self.assertTrue(pm.done) + + def test_no_tracker(self): + m = zmq.Frame(b'asdf', track=False) + self.assertEqual(m.tracker, None) + m2 = copy.copy(m) + self.assertEqual(m2.tracker, None) + self.assertRaises(ValueError, zmq.MessageTracker, m) + + @skip_pypy + def test_multi_tracker(self): + m = zmq.Frame(b'asdf', copy=False, track=True) + m2 = zmq.Frame(b'whoda', copy=False, track=True) + mt = zmq.MessageTracker(m,m2) + self.assertFalse(m.tracker.done) + self.assertFalse(mt.done) + self.assertRaises(zmq.NotDone, mt.wait, 0.1) + del m + time.sleep(0.1) + self.assertRaises(zmq.NotDone, mt.wait, 0.1) + self.assertFalse(mt.done) + del m2 + self.assertTrue(mt.wait() is None) + self.assertTrue(mt.done) + + def test_buffer_in(self): + """test using a buffer as input""" + ins = b("§§¶•ªº˜µ¬˚…∆˙åß∂©œ∑´†≈ç√") + m = zmq.Frame(memoryview(ins)) + + def test_bad_buffer_in(self): + """test using a bad object""" + self.assertRaises(TypeError, zmq.Frame, 5) + self.assertRaises(TypeError, zmq.Frame, object()) + + def test_buffer_out(self): + """receiving buffered output""" + ins = b("§§¶•ªº˜µ¬˚…∆˙åß∂©œ∑´†≈ç√") + m = zmq.Frame(ins) + outb = m.buffer + self.assertTrue(isinstance(outb, memoryview)) + assert outb is m.buffer + assert m.buffer is m.buffer + + @skip_pypy + def test_memoryview_shape(self): + """memoryview shape info""" + if sys.version_info < (3,): + raise SkipTest("only test memoryviews on Python 3") + data = b("§§¶•ªº˜µ¬˚…∆˙åß∂©œ∑´†≈ç√") + n = len(data) + f = zmq.Frame(data) + view1 = f.buffer + self.assertEqual(view1.ndim, 1) + self.assertEqual(view1.shape, (n,)) + self.assertEqual(view1.tobytes(), data) + view2 = memoryview(f) + self.assertEqual(view2.ndim, 1) + self.assertEqual(view2.shape, (n,)) + self.assertEqual(view2.tobytes(), data) + + def test_multisend(self): + """ensure that a message remains intact after multiple sends""" + a,b = self.create_bound_pair(zmq.PAIR, zmq.PAIR) + s = b"message" + m = zmq.Frame(s) + self.assertEqual(s, m.bytes) + + a.send(m, copy=False) + time.sleep(0.1) + self.assertEqual(s, m.bytes) + a.send(m, copy=False) + time.sleep(0.1) + self.assertEqual(s, m.bytes) + a.send(m, copy=True) + time.sleep(0.1) + self.assertEqual(s, m.bytes) + a.send(m, copy=True) + time.sleep(0.1) + self.assertEqual(s, m.bytes) + for i in range(4): + r = b.recv() + self.assertEqual(s,r) + self.assertEqual(s, m.bytes) + + def test_memoryview(self): + """test messages from memoryview""" + major,minor = sys.version_info[:2] + if not (major >= 3 or (major == 2 and minor >= 7)): + raise SkipTest("memoryviews only in python >= 2.7") + + s = b'carrotjuice' + v = memoryview(s) + m = zmq.Frame(s) + buf = m.buffer + s2 = buf.tobytes() + self.assertEqual(s2,s) + self.assertEqual(m.bytes,s) + + def test_noncopying_recv(self): + """check for clobbering message buffers""" + null = b'\0'*64 + sa,sb = self.create_bound_pair(zmq.PAIR, zmq.PAIR) + for i in range(32): + # try a few times + sb.send(null, copy=False) + m = sa.recv(copy=False) + mb = m.bytes + # buf = memoryview(m) + buf = m.buffer + del m + for i in range(5): + ff=b'\xff'*(40 + i*10) + sb.send(ff, copy=False) + m2 = sa.recv(copy=False) + b = buf.tobytes() + self.assertEqual(b, null) + self.assertEqual(mb, null) + self.assertEqual(m2.bytes, ff) + + @skip_pypy + def test_buffer_numpy(self): + """test non-copying numpy array messages""" + try: + import numpy + from numpy.testing import assert_array_equal + except ImportError: + raise SkipTest("requires numpy") + if sys.version_info < (2,7): + raise SkipTest("requires new-style buffer interface (py >= 2.7)") + rand = numpy.random.randint + shapes = [ rand(2,5) for i in range(5) ] + a,b = self.create_bound_pair(zmq.PAIR, zmq.PAIR) + dtypes = [int, float, '>i4', 'B'] + for i in range(1,len(shapes)+1): + shape = shapes[:i] + for dt in dtypes: + A = numpy.empty(shape, dtype=dt) + a.send(A, copy=False) + msg = b.recv(copy=False) + + B = numpy.frombuffer(msg, A.dtype).reshape(A.shape) + assert_array_equal(A, B) + + A = numpy.empty(shape, dtype=[('a', int), ('b', float), ('c', 'a32')]) + A['a'] = 1024 + A['b'] = 1e9 + A['c'] = 'hello there' + a.send(A, copy=False) + msg = b.recv(copy=False) + + B = numpy.frombuffer(msg, A.dtype).reshape(A.shape) + assert_array_equal(A, B) + + def test_frame_more(self): + """test Frame.more attribute""" + frame = zmq.Frame(b"hello") + self.assertFalse(frame.more) + sa,sb = self.create_bound_pair(zmq.PAIR, zmq.PAIR) + sa.send_multipart([b'hi', b'there']) + frame = self.recv(sb, copy=False) + self.assertTrue(frame.more) + if zmq.zmq_version_info()[0] >= 3 and not PYPY: + self.assertTrue(frame.get(zmq.MORE)) + frame = self.recv(sb, copy=False) + self.assertFalse(frame.more) + if zmq.zmq_version_info()[0] >= 3 and not PYPY: + self.assertFalse(frame.get(zmq.MORE)) + diff --git a/.venv/lib/python3.8/site-packages/zmq/tests/test_monitor.py b/.venv/lib/python3.8/site-packages/zmq/tests/test_monitor.py new file mode 100644 index 00000000..c2665063 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/zmq/tests/test_monitor.py @@ -0,0 +1,83 @@ +# -*- coding: utf-8 -*- +# Copyright (C) PyZMQ Developers +# Distributed under the terms of the Modified BSD License. + + +import errno +import sys +import time +import struct + +from unittest import TestCase +from pytest import mark +import zmq +from zmq.tests import BaseZMQTestCase, skip_pypy, require_zmq_4 +from zmq.utils.monitor import recv_monitor_message + + +class TestSocketMonitor(BaseZMQTestCase): + + @require_zmq_4 + def test_monitor(self): + """Test monitoring interface for sockets.""" + s_rep = self.context.socket(zmq.REP) + s_req = self.context.socket(zmq.REQ) + self.sockets.extend([s_rep, s_req]) + s_req.bind("tcp://127.0.0.1:6666") + # try monitoring the REP socket + + s_rep.monitor("inproc://monitor.rep", zmq.EVENT_CONNECT_DELAYED | zmq.EVENT_CONNECTED | zmq.EVENT_MONITOR_STOPPED) + # create listening socket for monitor + s_event = self.context.socket(zmq.PAIR) + self.sockets.append(s_event) + s_event.connect("inproc://monitor.rep") + s_event.linger = 0 + # test receive event for connect event + s_rep.connect("tcp://127.0.0.1:6666") + m = recv_monitor_message(s_event) + if m['event'] == zmq.EVENT_CONNECT_DELAYED: + self.assertEqual(m['endpoint'], b"tcp://127.0.0.1:6666") + # test receive event for connected event + m = recv_monitor_message(s_event) + self.assertEqual(m['event'], zmq.EVENT_CONNECTED) + self.assertEqual(m['endpoint'], b"tcp://127.0.0.1:6666") + + # test monitor can be disabled. + s_rep.disable_monitor() + m = recv_monitor_message(s_event) + self.assertEqual(m['event'], zmq.EVENT_MONITOR_STOPPED) + + @require_zmq_4 + def test_monitor_repeat(self): + s = self.socket(zmq.PULL) + m = s.get_monitor_socket() + self.sockets.append(m) + m2 = s.get_monitor_socket() + assert m is m2 + s.disable_monitor() + evt = recv_monitor_message(m) + self.assertEqual(evt['event'], zmq.EVENT_MONITOR_STOPPED) + m.close() + s.close() + + @require_zmq_4 + def test_monitor_connected(self): + """Test connected monitoring socket.""" + s_rep = self.context.socket(zmq.REP) + s_req = self.context.socket(zmq.REQ) + self.sockets.extend([s_rep, s_req]) + s_req.bind("tcp://127.0.0.1:6667") + # try monitoring the REP socket + # create listening socket for monitor + s_event = s_rep.get_monitor_socket() + s_event.linger = 0 + self.sockets.append(s_event) + # test receive event for connect event + s_rep.connect("tcp://127.0.0.1:6667") + m = recv_monitor_message(s_event) + if m['event'] == zmq.EVENT_CONNECT_DELAYED: + self.assertEqual(m['endpoint'], b"tcp://127.0.0.1:6667") + # test receive event for connected event + m = recv_monitor_message(s_event) + self.assertEqual(m['event'], zmq.EVENT_CONNECTED) + self.assertEqual(m['endpoint'], b"tcp://127.0.0.1:6667") diff --git a/.venv/lib/python3.8/site-packages/zmq/tests/test_monqueue.py b/.venv/lib/python3.8/site-packages/zmq/tests/test_monqueue.py new file mode 100644 index 00000000..3808908e --- /dev/null +++ b/.venv/lib/python3.8/site-packages/zmq/tests/test_monqueue.py @@ -0,0 +1,221 @@ +# Copyright (C) PyZMQ Developers +# Distributed under the terms of the Modified BSD License. + +import time +from unittest import TestCase + +import zmq +from zmq import devices + +from zmq.tests import BaseZMQTestCase, SkipTest, PYPY +from zmq.utils.strtypes import unicode + + +if PYPY or zmq.zmq_version_info() >= (4,1): + # cleanup of shared Context doesn't work on PyPy + # there also seems to be a bug in cleanup in libzmq-4.1 (zeromq/libzmq#1052) + devices.Device.context_factory = zmq.Context + + +class TestMonitoredQueue(BaseZMQTestCase): + + sockets = [] + + def build_device(self, mon_sub=b"", in_prefix=b'in', out_prefix=b'out'): + self.device = devices.ThreadMonitoredQueue(zmq.PAIR, zmq.PAIR, zmq.PUB, + in_prefix, out_prefix) + alice = self.context.socket(zmq.PAIR) + bob = self.context.socket(zmq.PAIR) + mon = self.context.socket(zmq.SUB) + + aport = alice.bind_to_random_port('tcp://127.0.0.1') + bport = bob.bind_to_random_port('tcp://127.0.0.1') + mport = mon.bind_to_random_port('tcp://127.0.0.1') + mon.setsockopt(zmq.SUBSCRIBE, mon_sub) + + self.device.connect_in("tcp://127.0.0.1:%i"%aport) + self.device.connect_out("tcp://127.0.0.1:%i"%bport) + self.device.connect_mon("tcp://127.0.0.1:%i"%mport) + self.device.start() + time.sleep(.2) + try: + # this is currenlty necessary to ensure no dropped monitor messages + # see LIBZMQ-248 for more info + mon.recv_multipart(zmq.NOBLOCK) + except zmq.ZMQError: + pass + self.sockets.extend([alice, bob, mon]) + return alice, bob, mon + + def teardown_device(self): + for socket in self.sockets: + socket.close() + del socket + del self.device + + def test_reply(self): + alice, bob, mon = self.build_device() + alices = b"hello bob".split() + alice.send_multipart(alices) + bobs = self.recv_multipart(bob) + self.assertEqual(alices, bobs) + bobs = b"hello alice".split() + bob.send_multipart(bobs) + alices = self.recv_multipart(alice) + self.assertEqual(alices, bobs) + self.teardown_device() + + def test_queue(self): + alice, bob, mon = self.build_device() + alices = b"hello bob".split() + alice.send_multipart(alices) + alices2 = b"hello again".split() + alice.send_multipart(alices2) + alices3 = b"hello again and again".split() + alice.send_multipart(alices3) + bobs = self.recv_multipart(bob) + self.assertEqual(alices, bobs) + bobs = self.recv_multipart(bob) + self.assertEqual(alices2, bobs) + bobs = self.recv_multipart(bob) + self.assertEqual(alices3, bobs) + bobs = b"hello alice".split() + bob.send_multipart(bobs) + alices = self.recv_multipart(alice) + self.assertEqual(alices, bobs) + self.teardown_device() + + def test_monitor(self): + alice, bob, mon = self.build_device() + alices = b"hello bob".split() + alice.send_multipart(alices) + alices2 = b"hello again".split() + alice.send_multipart(alices2) + alices3 = b"hello again and again".split() + alice.send_multipart(alices3) + bobs = self.recv_multipart(bob) + self.assertEqual(alices, bobs) + mons = self.recv_multipart(mon) + self.assertEqual([b'in']+bobs, mons) + bobs = self.recv_multipart(bob) + self.assertEqual(alices2, bobs) + bobs = self.recv_multipart(bob) + self.assertEqual(alices3, bobs) + mons = self.recv_multipart(mon) + self.assertEqual([b'in']+alices2, mons) + bobs = b"hello alice".split() + bob.send_multipart(bobs) + alices = self.recv_multipart(alice) + self.assertEqual(alices, bobs) + mons = self.recv_multipart(mon) + self.assertEqual([b'in']+alices3, mons) + mons = self.recv_multipart(mon) + self.assertEqual([b'out']+bobs, mons) + self.teardown_device() + + def test_prefix(self): + alice, bob, mon = self.build_device(b"", b'foo', b'bar') + alices = b"hello bob".split() + alice.send_multipart(alices) + alices2 = b"hello again".split() + alice.send_multipart(alices2) + alices3 = b"hello again and again".split() + alice.send_multipart(alices3) + bobs = self.recv_multipart(bob) + self.assertEqual(alices, bobs) + mons = self.recv_multipart(mon) + self.assertEqual([b'foo']+bobs, mons) + bobs = self.recv_multipart(bob) + self.assertEqual(alices2, bobs) + bobs = self.recv_multipart(bob) + self.assertEqual(alices3, bobs) + mons = self.recv_multipart(mon) + self.assertEqual([b'foo']+alices2, mons) + bobs = b"hello alice".split() + bob.send_multipart(bobs) + alices = self.recv_multipart(alice) + self.assertEqual(alices, bobs) + mons = self.recv_multipart(mon) + self.assertEqual([b'foo']+alices3, mons) + mons = self.recv_multipart(mon) + self.assertEqual([b'bar']+bobs, mons) + self.teardown_device() + + def test_monitor_subscribe(self): + alice, bob, mon = self.build_device(b"out") + alices = b"hello bob".split() + alice.send_multipart(alices) + alices2 = b"hello again".split() + alice.send_multipart(alices2) + alices3 = b"hello again and again".split() + alice.send_multipart(alices3) + bobs = self.recv_multipart(bob) + self.assertEqual(alices, bobs) + bobs = self.recv_multipart(bob) + self.assertEqual(alices2, bobs) + bobs = self.recv_multipart(bob) + self.assertEqual(alices3, bobs) + bobs = b"hello alice".split() + bob.send_multipart(bobs) + alices = self.recv_multipart(alice) + self.assertEqual(alices, bobs) + mons = self.recv_multipart(mon) + self.assertEqual([b'out']+bobs, mons) + self.teardown_device() + + def test_router_router(self): + """test router-router MQ devices""" + dev = devices.ThreadMonitoredQueue(zmq.ROUTER, zmq.ROUTER, zmq.PUB, b'in', b'out') + self.device = dev + dev.setsockopt_in(zmq.LINGER, 0) + dev.setsockopt_out(zmq.LINGER, 0) + dev.setsockopt_mon(zmq.LINGER, 0) + + porta = dev.bind_in_to_random_port('tcp://127.0.0.1') + portb = dev.bind_out_to_random_port('tcp://127.0.0.1') + a = self.context.socket(zmq.DEALER) + a.identity = b'a' + b = self.context.socket(zmq.DEALER) + b.identity = b'b' + self.sockets.extend([a, b]) + + a.connect('tcp://127.0.0.1:%i'%porta) + b.connect('tcp://127.0.0.1:%i'%portb) + dev.start() + time.sleep(1) + if zmq.zmq_version_info() >= (3,1,0): + # flush erroneous poll state, due to LIBZMQ-280 + ping_msg = [ b'ping', b'pong' ] + for s in (a,b): + s.send_multipart(ping_msg) + try: + s.recv(zmq.NOBLOCK) + except zmq.ZMQError: + pass + msg = [ b'hello', b'there' ] + a.send_multipart([b'b']+msg) + bmsg = self.recv_multipart(b) + self.assertEqual(bmsg, [b'a']+msg) + b.send_multipart(bmsg) + amsg = self.recv_multipart(a) + self.assertEqual(amsg, [b'b']+msg) + self.teardown_device() + + def test_default_mq_args(self): + self.device = dev = devices.ThreadMonitoredQueue(zmq.ROUTER, zmq.DEALER, zmq.PUB) + dev.setsockopt_in(zmq.LINGER, 0) + dev.setsockopt_out(zmq.LINGER, 0) + dev.setsockopt_mon(zmq.LINGER, 0) + # this will raise if default args are wrong + dev.start() + self.teardown_device() + + def test_mq_check_prefix(self): + ins = self.context.socket(zmq.ROUTER) + outs = self.context.socket(zmq.DEALER) + mons = self.context.socket(zmq.PUB) + self.sockets.extend([ins, outs, mons]) + + ins = unicode('in') + outs = unicode('out') + self.assertRaises(TypeError, devices.monitoredqueue, ins, outs, mons) diff --git a/.venv/lib/python3.8/site-packages/zmq/tests/test_multipart.py b/.venv/lib/python3.8/site-packages/zmq/tests/test_multipart.py new file mode 100644 index 00000000..24d41be0 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/zmq/tests/test_multipart.py @@ -0,0 +1,35 @@ +# Copyright (C) PyZMQ Developers +# Distributed under the terms of the Modified BSD License. + + +import zmq + + +from zmq.tests import BaseZMQTestCase, SkipTest, have_gevent, GreenTest + + +class TestMultipart(BaseZMQTestCase): + + def test_router_dealer(self): + router, dealer = self.create_bound_pair(zmq.ROUTER, zmq.DEALER) + + msg1 = b'message1' + dealer.send(msg1) + ident = self.recv(router) + more = router.rcvmore + self.assertEqual(more, True) + msg2 = self.recv(router) + self.assertEqual(msg1, msg2) + more = router.rcvmore + self.assertEqual(more, False) + + def test_basic_multipart(self): + a,b = self.create_bound_pair(zmq.PAIR, zmq.PAIR) + msg = [ b'hi', b'there', b'b'] + a.send_multipart(msg) + recvd = b.recv_multipart() + self.assertEqual(msg, recvd) + +if have_gevent: + class TestMultipartGreen(GreenTest, TestMultipart): + pass diff --git a/.venv/lib/python3.8/site-packages/zmq/tests/test_pair.py b/.venv/lib/python3.8/site-packages/zmq/tests/test_pair.py new file mode 100644 index 00000000..e88c1e8b --- /dev/null +++ b/.venv/lib/python3.8/site-packages/zmq/tests/test_pair.py @@ -0,0 +1,53 @@ +# Copyright (C) PyZMQ Developers +# Distributed under the terms of the Modified BSD License. + + +import zmq + + +from zmq.tests import BaseZMQTestCase, have_gevent, GreenTest + + +x = b' ' +class TestPair(BaseZMQTestCase): + + def test_basic(self): + s1, s2 = self.create_bound_pair(zmq.PAIR, zmq.PAIR) + + msg1 = b'message1' + msg2 = self.ping_pong(s1, s2, msg1) + self.assertEqual(msg1, msg2) + + def test_multiple(self): + s1, s2 = self.create_bound_pair(zmq.PAIR, zmq.PAIR) + + for i in range(10): + msg = i*x + s1.send(msg) + + for i in range(10): + msg = i*x + s2.send(msg) + + for i in range(10): + msg = s1.recv() + self.assertEqual(msg, i*x) + + for i in range(10): + msg = s2.recv() + self.assertEqual(msg, i*x) + + def test_json(self): + s1, s2 = self.create_bound_pair(zmq.PAIR, zmq.PAIR) + o = dict(a=10,b=list(range(10))) + o2 = self.ping_pong_json(s1, s2, o) + + def test_pyobj(self): + s1, s2 = self.create_bound_pair(zmq.PAIR, zmq.PAIR) + o = dict(a=10,b=range(10)) + o2 = self.ping_pong_pyobj(s1, s2, o) + +if have_gevent: + class TestReqRepGreen(GreenTest, TestPair): + pass + diff --git a/.venv/lib/python3.8/site-packages/zmq/tests/test_poll.py b/.venv/lib/python3.8/site-packages/zmq/tests/test_poll.py new file mode 100644 index 00000000..1931d075 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/zmq/tests/test_poll.py @@ -0,0 +1,238 @@ +# Copyright (C) PyZMQ Developers +# Distributed under the terms of the Modified BSD License. + +import os +import sys +import time + +from pytest import mark + +import zmq + +from zmq.tests import PollZMQTestCase, have_gevent, GreenTest + +def wait(): + time.sleep(.25) + + +class TestPoll(PollZMQTestCase): + + Poller = zmq.Poller + + def test_pair(self): + s1, s2 = self.create_bound_pair(zmq.PAIR, zmq.PAIR) + + # Sleep to allow sockets to connect. + wait() + + poller = self.Poller() + poller.register(s1, zmq.POLLIN|zmq.POLLOUT) + poller.register(s2, zmq.POLLIN|zmq.POLLOUT) + # Poll result should contain both sockets + socks = dict(poller.poll()) + # Now make sure that both are send ready. + self.assertEqual(socks[s1], zmq.POLLOUT) + self.assertEqual(socks[s2], zmq.POLLOUT) + # Now do a send on both, wait and test for zmq.POLLOUT|zmq.POLLIN + s1.send(b'msg1') + s2.send(b'msg2') + wait() + socks = dict(poller.poll()) + self.assertEqual(socks[s1], zmq.POLLOUT|zmq.POLLIN) + self.assertEqual(socks[s2], zmq.POLLOUT|zmq.POLLIN) + # Make sure that both are in POLLOUT after recv. + s1.recv() + s2.recv() + socks = dict(poller.poll()) + self.assertEqual(socks[s1], zmq.POLLOUT) + self.assertEqual(socks[s2], zmq.POLLOUT) + + poller.unregister(s1) + poller.unregister(s2) + + + def test_reqrep(self): + s1, s2 = self.create_bound_pair(zmq.REP, zmq.REQ) + + # Sleep to allow sockets to connect. + wait() + + poller = self.Poller() + poller.register(s1, zmq.POLLIN|zmq.POLLOUT) + poller.register(s2, zmq.POLLIN|zmq.POLLOUT) + + # Make sure that s1 is in state 0 and s2 is in POLLOUT + socks = dict(poller.poll()) + self.assertEqual(s1 in socks, 0) + self.assertEqual(socks[s2], zmq.POLLOUT) + + # Make sure that s2 goes immediately into state 0 after send. + s2.send(b'msg1') + socks = dict(poller.poll()) + self.assertEqual(s2 in socks, 0) + + # Make sure that s1 goes into POLLIN state after a time.sleep(). + time.sleep(0.5) + socks = dict(poller.poll()) + self.assertEqual(socks[s1], zmq.POLLIN) + + # Make sure that s1 goes into POLLOUT after recv. + s1.recv() + socks = dict(poller.poll()) + self.assertEqual(socks[s1], zmq.POLLOUT) + + # Make sure s1 goes into state 0 after send. + s1.send(b'msg2') + socks = dict(poller.poll()) + self.assertEqual(s1 in socks, 0) + + # Wait and then see that s2 is in POLLIN. + time.sleep(0.5) + socks = dict(poller.poll()) + self.assertEqual(socks[s2], zmq.POLLIN) + + # Make sure that s2 is in POLLOUT after recv. + s2.recv() + socks = dict(poller.poll()) + self.assertEqual(socks[s2], zmq.POLLOUT) + + poller.unregister(s1) + poller.unregister(s2) + + def test_no_events(self): + s1, s2 = self.create_bound_pair(zmq.PAIR, zmq.PAIR) + poller = self.Poller() + poller.register(s1, zmq.POLLIN|zmq.POLLOUT) + poller.register(s2, 0) + self.assertTrue(s1 in poller) + self.assertFalse(s2 in poller) + poller.register(s1, 0) + self.assertFalse(s1 in poller) + + def test_pubsub(self): + s1, s2 = self.create_bound_pair(zmq.PUB, zmq.SUB) + s2.setsockopt(zmq.SUBSCRIBE, b'') + + # Sleep to allow sockets to connect. + wait() + + poller = self.Poller() + poller.register(s1, zmq.POLLIN|zmq.POLLOUT) + poller.register(s2, zmq.POLLIN) + + # Now make sure that both are send ready. + socks = dict(poller.poll()) + self.assertEqual(socks[s1], zmq.POLLOUT) + self.assertEqual(s2 in socks, 0) + # Make sure that s1 stays in POLLOUT after a send. + s1.send(b'msg1') + socks = dict(poller.poll()) + self.assertEqual(socks[s1], zmq.POLLOUT) + + # Make sure that s2 is POLLIN after waiting. + wait() + socks = dict(poller.poll()) + self.assertEqual(socks[s2], zmq.POLLIN) + + # Make sure that s2 goes into 0 after recv. + s2.recv() + socks = dict(poller.poll()) + self.assertEqual(s2 in socks, 0) + + poller.unregister(s1) + poller.unregister(s2) + + @mark.skipif(sys.platform.startswith('win'), reason='Windows') + def test_raw(self): + r, w = os.pipe() + r = os.fdopen(r, 'rb') + w = os.fdopen(w, 'wb') + p = self.Poller() + p.register(r, zmq.POLLIN) + socks = dict(p.poll(1)) + assert socks == {} + w.write(b'x') + w.flush() + socks = dict(p.poll(1)) + assert socks == {r.fileno(): zmq.POLLIN} + w.close() + r.close() + + def test_timeout(self): + """make sure Poller.poll timeout has the right units (milliseconds).""" + s1, s2 = self.create_bound_pair(zmq.PAIR, zmq.PAIR) + poller = self.Poller() + poller.register(s1, zmq.POLLIN) + tic = time.time() + evt = poller.poll(.005) + toc = time.time() + self.assertTrue(toc-tic < 0.1) + tic = time.time() + evt = poller.poll(5) + toc = time.time() + self.assertTrue(toc-tic < 0.1) + self.assertTrue(toc-tic > .001) + tic = time.time() + evt = poller.poll(500) + toc = time.time() + self.assertTrue(toc-tic < 1) + self.assertTrue(toc-tic > 0.1) + +class TestSelect(PollZMQTestCase): + + def test_pair(self): + s1, s2 = self.create_bound_pair(zmq.PAIR, zmq.PAIR) + + # Sleep to allow sockets to connect. + wait() + + rlist, wlist, xlist = zmq.select([s1, s2], [s1, s2], [s1, s2]) + self.assertTrue(s1 in wlist) + self.assertTrue(s2 in wlist) + self.assertTrue(s1 not in rlist) + self.assertTrue(s2 not in rlist) + + def test_timeout(self): + """make sure select timeout has the right units (seconds).""" + s1, s2 = self.create_bound_pair(zmq.PAIR, zmq.PAIR) + tic = time.time() + r,w,x = zmq.select([s1,s2],[],[],.005) + toc = time.time() + self.assertTrue(toc-tic < 1) + self.assertTrue(toc-tic > 0.001) + tic = time.time() + r,w,x = zmq.select([s1,s2],[],[],.25) + toc = time.time() + self.assertTrue(toc-tic < 1) + self.assertTrue(toc-tic > 0.1) + + +if have_gevent: + import gevent + from zmq import green as gzmq + + class TestPollGreen(GreenTest, TestPoll): + Poller = gzmq.Poller + + def test_wakeup(self): + s1, s2 = self.create_bound_pair(zmq.PAIR, zmq.PAIR) + poller = self.Poller() + poller.register(s2, zmq.POLLIN) + + tic = time.time() + r = gevent.spawn(lambda: poller.poll(10000)) + s = gevent.spawn(lambda: s1.send(b'msg1')) + r.join() + toc = time.time() + self.assertTrue(toc-tic < 1) + + def test_socket_poll(self): + s1, s2 = self.create_bound_pair(zmq.PAIR, zmq.PAIR) + + tic = time.time() + r = gevent.spawn(lambda: s2.poll(10000)) + s = gevent.spawn(lambda: s1.send(b'msg1')) + r.join() + toc = time.time() + self.assertTrue(toc-tic < 1) + diff --git a/.venv/lib/python3.8/site-packages/zmq/tests/test_proxy_steerable.py b/.venv/lib/python3.8/site-packages/zmq/tests/test_proxy_steerable.py new file mode 100644 index 00000000..12c06364 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/zmq/tests/test_proxy_steerable.py @@ -0,0 +1,109 @@ +# Copyright (C) PyZMQ Developers +# Distributed under the terms of the Modified BSD License. + +import time +import struct + +import zmq +from zmq import devices +from zmq.tests import BaseZMQTestCase, SkipTest, PYPY + +if PYPY: + # cleanup of shared Context doesn't work on PyPy + devices.Device.context_factory = zmq.Context + + +class TestProxySteerable(BaseZMQTestCase): + + def test_proxy_steerable(self): + if zmq.zmq_version_info() < (4, 1): + raise SkipTest("Steerable Proxies only in libzmq >= 4.1") + dev = devices.ThreadProxySteerable( + zmq.PULL, + zmq.PUSH, + zmq.PUSH, + zmq.PAIR + ) + iface = 'tcp://127.0.0.1' + port = dev.bind_in_to_random_port(iface) + port2 = dev.bind_out_to_random_port(iface) + port3 = dev.bind_mon_to_random_port(iface) + port4 = dev.bind_ctrl_to_random_port(iface) + dev.start() + time.sleep(0.25) + msg = b'hello' + push = self.context.socket(zmq.PUSH) + push.connect("%s:%i" % (iface, port)) + pull = self.context.socket(zmq.PULL) + pull.connect("%s:%i" % (iface, port2)) + mon = self.context.socket(zmq.PULL) + mon.connect("%s:%i" % (iface, port3)) + ctrl = self.context.socket(zmq.PAIR) + ctrl.connect("%s:%i" % (iface, port4)) + push.send(msg) + self.sockets.extend([push, pull, mon, ctrl]) + self.assertEqual(msg, self.recv(pull)) + self.assertEqual(msg, self.recv(mon)) + ctrl.send(b'TERMINATE') + dev.join() + + def test_proxy_steerable_bind_to_random_with_args(self): + if zmq.zmq_version_info() < (4, 1): + raise SkipTest("Steerable Proxies only in libzmq >= 4.1") + dev = devices.ThreadProxySteerable( + zmq.PULL, + zmq.PUSH, + zmq.PUSH, + zmq.PAIR + ) + iface = 'tcp://127.0.0.1' + ports = [] + min, max = 5000, 5050 + ports.extend([ + dev.bind_in_to_random_port(iface, min_port=min, max_port=max), + dev.bind_out_to_random_port(iface, min_port=min, max_port=max), + dev.bind_mon_to_random_port(iface, min_port=min, max_port=max), + dev.bind_ctrl_to_random_port(iface, min_port=min, max_port=max) + ]) + for port in ports: + if port < min or port > max: + self.fail('Unexpected port number: %i' % port) + + def test_proxy_steerable_statistics(self): + if zmq.zmq_version_info() < (4, 3): + raise SkipTest("STATISTICS only in libzmq >= 4.3") + dev = devices.ThreadProxySteerable( + zmq.PULL, + zmq.PUSH, + zmq.PUSH, + zmq.PAIR + ) + iface = 'tcp://127.0.0.1' + port = dev.bind_in_to_random_port(iface) + port2 = dev.bind_out_to_random_port(iface) + port3 = dev.bind_mon_to_random_port(iface) + port4 = dev.bind_ctrl_to_random_port(iface) + dev.start() + time.sleep(0.25) + msg = b'hello' + push = self.context.socket(zmq.PUSH) + push.connect("%s:%i" % (iface, port)) + pull = self.context.socket(zmq.PULL) + pull.connect("%s:%i" % (iface, port2)) + mon = self.context.socket(zmq.PULL) + mon.connect("%s:%i" % (iface, port3)) + ctrl = self.context.socket(zmq.PAIR) + ctrl.connect("%s:%i" % (iface, port4)) + push.send(msg) + self.sockets.extend([push, pull, mon, ctrl]) + self.assertEqual(msg, self.recv(pull)) + self.assertEqual(msg, self.recv(mon)) + ctrl.send(b'STATISTICS') + stats = self.recv_multipart(ctrl) + stats_int = [struct.unpack("=Q", x)[0] for x in stats] + self.assertEqual(1, stats_int[0]) + self.assertEqual(len(msg), stats_int[1]) + self.assertEqual(1, stats_int[6]) + self.assertEqual(len(msg), stats_int[7]) + ctrl.send(b'TERMINATE') + dev.join() diff --git a/.venv/lib/python3.8/site-packages/zmq/tests/test_pubsub.py b/.venv/lib/python3.8/site-packages/zmq/tests/test_pubsub.py new file mode 100644 index 00000000..878a16e1 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/zmq/tests/test_pubsub.py @@ -0,0 +1,42 @@ +# Copyright (C) PyZMQ Developers +# Distributed under the terms of the Modified BSD License. + + +from random import Random +import time +from unittest import TestCase + +import zmq + +from zmq.tests import BaseZMQTestCase, have_gevent, GreenTest + + +class TestPubSub(BaseZMQTestCase): + + pass + + # We are disabling this test while an issue is being resolved. + def test_basic(self): + s1, s2 = self.create_bound_pair(zmq.PUB, zmq.SUB) + s2.setsockopt(zmq.SUBSCRIBE, b'') + time.sleep(0.1) + msg1 = b'message' + s1.send(msg1) + msg2 = s2.recv() # This is blocking! + self.assertEqual(msg1, msg2) + + def test_topic(self): + s1, s2 = self.create_bound_pair(zmq.PUB, zmq.SUB) + s2.setsockopt(zmq.SUBSCRIBE, b'x') + time.sleep(0.1) + msg1 = b'message' + s1.send(msg1) + self.assertRaisesErrno(zmq.EAGAIN, s2.recv, zmq.NOBLOCK) + msg1 = b'xmessage' + s1.send(msg1) + msg2 = s2.recv() + self.assertEqual(msg1, msg2) + +if have_gevent: + class TestPubSubGreen(GreenTest, TestPubSub): + pass diff --git a/.venv/lib/python3.8/site-packages/zmq/tests/test_reqrep.py b/.venv/lib/python3.8/site-packages/zmq/tests/test_reqrep.py new file mode 100644 index 00000000..de17f2b3 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/zmq/tests/test_reqrep.py @@ -0,0 +1,62 @@ +# Copyright (C) PyZMQ Developers +# Distributed under the terms of the Modified BSD License. + + +from unittest import TestCase + +import zmq +from zmq.tests import BaseZMQTestCase, have_gevent, GreenTest + + +class TestReqRep(BaseZMQTestCase): + + def test_basic(self): + s1, s2 = self.create_bound_pair(zmq.REQ, zmq.REP) + + msg1 = b'message 1' + msg2 = self.ping_pong(s1, s2, msg1) + self.assertEqual(msg1, msg2) + + def test_multiple(self): + s1, s2 = self.create_bound_pair(zmq.REQ, zmq.REP) + + for i in range(10): + msg1 = i*b' ' + msg2 = self.ping_pong(s1, s2, msg1) + self.assertEqual(msg1, msg2) + + def test_bad_send_recv(self): + s1, s2 = self.create_bound_pair(zmq.REQ, zmq.REP) + + if zmq.zmq_version() != '2.1.8': + # this doesn't work on 2.1.8 + for copy in (True,False): + self.assertRaisesErrno(zmq.EFSM, s1.recv, copy=copy) + self.assertRaisesErrno(zmq.EFSM, s2.send, b'asdf', copy=copy) + + # I have to have this or we die on an Abort trap. + msg1 = b'asdf' + msg2 = self.ping_pong(s1, s2, msg1) + self.assertEqual(msg1, msg2) + + def test_json(self): + s1, s2 = self.create_bound_pair(zmq.REQ, zmq.REP) + o = dict(a=10,b=list(range(10))) + o2 = self.ping_pong_json(s1, s2, o) + + def test_pyobj(self): + s1, s2 = self.create_bound_pair(zmq.REQ, zmq.REP) + o = dict(a=10,b=range(10)) + o2 = self.ping_pong_pyobj(s1, s2, o) + + def test_large_msg(self): + s1, s2 = self.create_bound_pair(zmq.REQ, zmq.REP) + msg1 = 10000*b'X' + + for i in range(10): + msg2 = self.ping_pong(s1, s2, msg1) + self.assertEqual(msg1, msg2) + +if have_gevent: + class TestReqRepGreen(GreenTest, TestReqRep): + pass diff --git a/.venv/lib/python3.8/site-packages/zmq/tests/test_retry_eintr.py b/.venv/lib/python3.8/site-packages/zmq/tests/test_retry_eintr.py new file mode 100644 index 00000000..299381c3 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/zmq/tests/test_retry_eintr.py @@ -0,0 +1,95 @@ +# -*- coding: utf8 -*- +# Copyright (C) PyZMQ Developers +# Distributed under the terms of the Modified BSD License. + +import signal +import time +from threading import Thread + +from pytest import mark + +import zmq +from zmq.tests import ( + BaseZMQTestCase, SkipTest, skip_pypy +) +from zmq.utils.strtypes import b + + +# Partially based on EINTRBaseTest from CPython 3.5 eintr_tester + +class TestEINTRSysCall(BaseZMQTestCase): + """ Base class for EINTR tests. """ + + # delay for initial signal delivery + signal_delay = 0.1 + # timeout for tests. Must be > signal_delay + timeout = .25 + timeout_ms = int(timeout * 1e3) + + def alarm(self, t=None): + """start a timer to fire only once + + like signal.alarm, but with better resolution than integer seconds. + """ + if not hasattr(signal, 'setitimer'): + raise SkipTest('EINTR tests require setitimer') + if t is None: + t = self.signal_delay + self.timer_fired = False + self.orig_handler = signal.signal(signal.SIGALRM, self.stop_timer) + # signal_period ignored, since only one timer event is allowed to fire + signal.setitimer(signal.ITIMER_REAL, t, 1000) + + def stop_timer(self, *args): + self.timer_fired = True + signal.setitimer(signal.ITIMER_REAL, 0, 0) + signal.signal(signal.SIGALRM, self.orig_handler) + + @mark.skipif(not hasattr(zmq, 'RCVTIMEO'), reason="requires RCVTIMEO") + def test_retry_recv(self): + pull = self.socket(zmq.PULL) + pull.rcvtimeo = self.timeout_ms + self.alarm() + self.assertRaises(zmq.Again, pull.recv) + assert self.timer_fired + + @mark.skipif(not hasattr(zmq, 'SNDTIMEO'), reason="requires SNDTIMEO") + def test_retry_send(self): + push = self.socket(zmq.PUSH) + push.sndtimeo = self.timeout_ms + self.alarm() + self.assertRaises(zmq.Again, push.send, b('buf')) + assert self.timer_fired + + def test_retry_poll(self): + x, y = self.create_bound_pair() + poller = zmq.Poller() + poller.register(x, zmq.POLLIN) + self.alarm() + def send(): + time.sleep(2 * self.signal_delay) + y.send(b('ping')) + t = Thread(target=send) + t.start() + evts = dict(poller.poll(2 * self.timeout_ms)) + t.join() + assert x in evts + assert self.timer_fired + x.recv() + + def test_retry_term(self): + push = self.socket(zmq.PUSH) + push.linger = self.timeout_ms + push.connect('tcp://127.0.0.1:5555') + push.send(b('ping')) + time.sleep(0.1) + self.alarm() + self.context.destroy() + assert self.timer_fired + assert self.context.closed + + def test_retry_getsockopt(self): + raise SkipTest("TODO: find a way to interrupt getsockopt") + + def test_retry_setsockopt(self): + raise SkipTest("TODO: find a way to interrupt setsockopt") diff --git a/.venv/lib/python3.8/site-packages/zmq/tests/test_security.py b/.venv/lib/python3.8/site-packages/zmq/tests/test_security.py new file mode 100644 index 00000000..b73234d8 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/zmq/tests/test_security.py @@ -0,0 +1,236 @@ +"""Test libzmq security (libzmq >= 3.3.0)""" +# -*- coding: utf8 -*- + +# Copyright (C) PyZMQ Developers +# Distributed under the terms of the Modified BSD License. + +import os +import contextlib +import time +from threading import Thread + +import zmq +from zmq.tests import ( + BaseZMQTestCase, SkipTest, PYPY +) +from zmq.utils import z85 + + +USER = b"admin" +PASS = b"password" + +class TestSecurity(BaseZMQTestCase): + + def setUp(self): + if zmq.zmq_version_info() < (4,0): + raise SkipTest("security is new in libzmq 4.0") + try: + zmq.curve_keypair() + except zmq.ZMQError: + raise SkipTest("security requires libzmq to be built with CURVE support") + super(TestSecurity, self).setUp() + + def zap_handler(self): + socket = self.context.socket(zmq.REP) + socket.bind("inproc://zeromq.zap.01") + try: + msg = self.recv_multipart(socket) + + version, sequence, domain, address, identity, mechanism = msg[:6] + if mechanism == b'PLAIN': + username, password = msg[6:] + elif mechanism == b'CURVE': + key = msg[6] + + self.assertEqual(version, b"1.0") + self.assertEqual(identity, b"IDENT") + reply = [version, sequence] + if mechanism == b'CURVE' or \ + (mechanism == b'PLAIN' and username == USER and password == PASS) or \ + (mechanism == b'NULL'): + reply.extend([ + b"200", + b"OK", + b"anonymous", + b"\5Hello\0\0\0\5World", + ]) + else: + reply.extend([ + b"400", + b"Invalid username or password", + b"", + b"", + ]) + socket.send_multipart(reply) + finally: + socket.close() + + @contextlib.contextmanager + def zap(self): + self.start_zap() + time.sleep(0.5) # allow time for the Thread to start + try: + yield + finally: + self.stop_zap() + + def start_zap(self): + self.zap_thread = Thread(target=self.zap_handler) + self.zap_thread.start() + + def stop_zap(self): + self.zap_thread.join() + + def bounce(self, server, client, test_metadata=True): + msg = [os.urandom(64), os.urandom(64)] + client.send_multipart(msg) + frames = self.recv_multipart(server, copy=False) + recvd = list(map(lambda x: x.bytes, frames)) + + try: + if test_metadata and not PYPY: + for frame in frames: + self.assertEqual(frame.get('User-Id'), 'anonymous') + self.assertEqual(frame.get('Hello'), 'World') + self.assertEqual(frame['Socket-Type'], 'DEALER') + except zmq.ZMQVersionError: + pass + + self.assertEqual(recvd, msg) + server.send_multipart(recvd) + msg2 = self.recv_multipart(client) + self.assertEqual(msg2, msg) + + def test_null(self): + """test NULL (default) security""" + server = self.socket(zmq.DEALER) + client = self.socket(zmq.DEALER) + self.assertEqual(client.MECHANISM, zmq.NULL) + self.assertEqual(server.mechanism, zmq.NULL) + self.assertEqual(client.plain_server, 0) + self.assertEqual(server.plain_server, 0) + iface = 'tcp://127.0.0.1' + port = server.bind_to_random_port(iface) + client.connect("%s:%i" % (iface, port)) + self.bounce(server, client, False) + + def test_plain(self): + """test PLAIN authentication""" + server = self.socket(zmq.DEALER) + server.identity = b'IDENT' + client = self.socket(zmq.DEALER) + self.assertEqual(client.plain_username, b'') + self.assertEqual(client.plain_password, b'') + client.plain_username = USER + client.plain_password = PASS + self.assertEqual(client.getsockopt(zmq.PLAIN_USERNAME), USER) + self.assertEqual(client.getsockopt(zmq.PLAIN_PASSWORD), PASS) + self.assertEqual(client.plain_server, 0) + self.assertEqual(server.plain_server, 0) + server.plain_server = True + self.assertEqual(server.mechanism, zmq.PLAIN) + self.assertEqual(client.mechanism, zmq.PLAIN) + + assert not client.plain_server + assert server.plain_server + + with self.zap(): + iface = 'tcp://127.0.0.1' + port = server.bind_to_random_port(iface) + client.connect("%s:%i" % (iface, port)) + self.bounce(server, client) + + def skip_plain_inauth(self): + """test PLAIN failed authentication""" + server = self.socket(zmq.DEALER) + server.identity = b'IDENT' + client = self.socket(zmq.DEALER) + self.sockets.extend([server, client]) + client.plain_username = USER + client.plain_password = b'incorrect' + server.plain_server = True + self.assertEqual(server.mechanism, zmq.PLAIN) + self.assertEqual(client.mechanism, zmq.PLAIN) + + with self.zap(): + iface = 'tcp://127.0.0.1' + port = server.bind_to_random_port(iface) + client.connect("%s:%i" % (iface, port)) + client.send(b'ping') + server.rcvtimeo = 250 + self.assertRaisesErrno(zmq.EAGAIN, server.recv) + + def test_keypair(self): + """test curve_keypair""" + try: + public, secret = zmq.curve_keypair() + except zmq.ZMQError: + raise SkipTest("CURVE unsupported") + + self.assertEqual(type(secret), bytes) + self.assertEqual(type(public), bytes) + self.assertEqual(len(secret), 40) + self.assertEqual(len(public), 40) + + # verify that it is indeed Z85 + bsecret, bpublic = [ z85.decode(key) for key in (public, secret) ] + self.assertEqual(type(bsecret), bytes) + self.assertEqual(type(bpublic), bytes) + self.assertEqual(len(bsecret), 32) + self.assertEqual(len(bpublic), 32) + + def test_curve_public(self): + """test curve_public""" + try: + public, secret = zmq.curve_keypair() + except zmq.ZMQError: + raise SkipTest("CURVE unsupported") + if zmq.zmq_version_info() < (4,2): + raise SkipTest("curve_public is new in libzmq 4.2") + + derived_public = zmq.curve_public(secret) + + self.assertEqual(type(derived_public), bytes) + self.assertEqual(len(derived_public), 40) + + # verify that it is indeed Z85 + bpublic = z85.decode(derived_public) + self.assertEqual(type(bpublic), bytes) + self.assertEqual(len(bpublic), 32) + + # verify that it is equal to the known public key + self.assertEqual(derived_public, public) + + def test_curve(self): + """test CURVE encryption""" + server = self.socket(zmq.DEALER) + server.identity = b'IDENT' + client = self.socket(zmq.DEALER) + self.sockets.extend([server, client]) + try: + server.curve_server = True + except zmq.ZMQError as e: + # will raise EINVAL if no CURVE support + if e.errno == zmq.EINVAL: + raise SkipTest("CURVE unsupported") + + server_public, server_secret = zmq.curve_keypair() + client_public, client_secret = zmq.curve_keypair() + + server.curve_secretkey = server_secret + server.curve_publickey = server_public + client.curve_serverkey = server_public + client.curve_publickey = client_public + client.curve_secretkey = client_secret + + self.assertEqual(server.mechanism, zmq.CURVE) + self.assertEqual(client.mechanism, zmq.CURVE) + + self.assertEqual(server.get(zmq.CURVE_SERVER), True) + self.assertEqual(client.get(zmq.CURVE_SERVER), False) + + with self.zap(): + iface = 'tcp://127.0.0.1' + port = server.bind_to_random_port(iface) + client.connect("%s:%i" % (iface, port)) + self.bounce(server, client) diff --git a/.venv/lib/python3.8/site-packages/zmq/tests/test_socket.py b/.venv/lib/python3.8/site-packages/zmq/tests/test_socket.py new file mode 100644 index 00000000..7ff412c4 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/zmq/tests/test_socket.py @@ -0,0 +1,649 @@ +# -*- coding: utf8 -*- +# Copyright (C) PyZMQ Developers +# Distributed under the terms of the Modified BSD License. + +import copy +import errno +import json +import os +import platform +import time +import warnings +import socket +import sys +try: + from unittest import mock +except ImportError: + mock = None + +import pytest +from pytest import mark + +import zmq +from zmq.tests import ( + BaseZMQTestCase, SkipTest, have_gevent, GreenTest, skip_pypy +) +from zmq.utils.strtypes import unicode + +pypy = platform.python_implementation().lower() == 'pypy' +windows = platform.platform().lower().startswith('windows') +on_travis = bool(os.environ.get('TRAVIS_PYTHON_VERSION')) + +# polling on windows is slow +POLL_TIMEOUT = 1000 if windows else 100 + +class TestSocket(BaseZMQTestCase): + + def test_create(self): + ctx = self.Context() + s = ctx.socket(zmq.PUB) + # Superluminal protocol not yet implemented + self.assertRaisesErrno(zmq.EPROTONOSUPPORT, s.bind, 'ftl://a') + self.assertRaisesErrno(zmq.EPROTONOSUPPORT, s.connect, 'ftl://a') + self.assertRaisesErrno(zmq.EINVAL, s.bind, 'tcp://') + s.close() + del ctx + + def test_context_manager(self): + url = 'inproc://a' + with self.Context() as ctx: + with ctx.socket(zmq.PUSH) as a: + a.bind(url) + with ctx.socket(zmq.PULL) as b: + b.connect(url) + msg = b'hi' + a.send(msg) + rcvd = self.recv(b) + self.assertEqual(rcvd, msg) + self.assertEqual(b.closed, True) + self.assertEqual(a.closed, True) + self.assertEqual(ctx.closed, True) + + def test_connectbind_context_managers(self): + url = 'inproc://a' + msg = b'hi' + with self.Context() as ctx: + # Test connect() context manager + with ctx.socket(zmq.PUSH) as a, ctx.socket(zmq.PULL) as b: + a.bind(url) + with b.connect(url): + a.send(msg) + rcvd = self.recv(b) + self.assertEqual(rcvd, msg) + # b should now be disconnected, so sending and receiving don't work + with pytest.raises(zmq.Again): + a.send(msg, flags=zmq.DONTWAIT) + with pytest.raises(zmq.Again): + b.recv(flags=zmq.DONTWAIT) + a.unbind(url) + # Test bind() context manager + with ctx.socket(zmq.PUSH) as a, ctx.socket(zmq.PULL) as b: + # unbind() just stops accepting of new connections, so we have to disconnect to test that + # unbind happened. + with a.bind(url): + b.connect(url) + a.send(msg) + rcvd = self.recv(b) + self.assertEqual(rcvd, msg) + b.disconnect(url) + b.connect(url) + # Since a is unbound from url, b is not connected to anything + with pytest.raises(zmq.Again): + a.send(msg, flags=zmq.DONTWAIT) + with pytest.raises(zmq.Again): + b.recv(flags=zmq.DONTWAIT) + + def test_dir(self): + ctx = self.Context() + s = ctx.socket(zmq.PUB) + self.assertTrue('send' in dir(s)) + self.assertTrue('IDENTITY' in dir(s)) + self.assertTrue('AFFINITY' in dir(s)) + self.assertTrue('FD' in dir(s)) + s.close() + ctx.term() + + @mark.skipif(mock is None, reason="requires unittest.mock") + def test_mockable(self): + s = self.socket(zmq.SUB) + m = mock.Mock(spec=s) + s.close() + + def test_bind_unicode(self): + s = self.socket(zmq.PUB) + p = s.bind_to_random_port(unicode("tcp://*")) + + def test_connect_unicode(self): + s = self.socket(zmq.PUB) + s.connect(unicode("tcp://127.0.0.1:5555")) + + def test_bind_to_random_port(self): + # Check that bind_to_random_port do not hide useful exception + ctx = self.Context() + c = ctx.socket(zmq.PUB) + # Invalid format + try: + c.bind_to_random_port('tcp:*') + except zmq.ZMQError as e: + self.assertEqual(e.errno, zmq.EINVAL) + # Invalid protocol + try: + c.bind_to_random_port('rand://*') + except zmq.ZMQError as e: + self.assertEqual(e.errno, zmq.EPROTONOSUPPORT) + + def test_identity(self): + s = self.context.socket(zmq.PULL) + self.sockets.append(s) + ident = b'identity\0\0' + s.identity = ident + self.assertEqual(s.get(zmq.IDENTITY), ident) + + def test_unicode_sockopts(self): + """test setting/getting sockopts with unicode strings""" + topic = "tést" + if str is not unicode: + topic = topic.decode('utf8') + p,s = self.create_bound_pair(zmq.PUB, zmq.SUB) + self.assertEqual(s.send_unicode, s.send_unicode) + self.assertEqual(p.recv_unicode, p.recv_unicode) + self.assertRaises(TypeError, s.setsockopt, zmq.SUBSCRIBE, topic) + self.assertRaises(TypeError, s.setsockopt, zmq.IDENTITY, topic) + s.setsockopt_unicode(zmq.IDENTITY, topic, 'utf16') + self.assertRaises(TypeError, s.setsockopt, zmq.AFFINITY, topic) + s.setsockopt_unicode(zmq.SUBSCRIBE, topic) + self.assertRaises(TypeError, s.getsockopt_unicode, zmq.AFFINITY) + self.assertRaisesErrno(zmq.EINVAL, s.getsockopt_unicode, zmq.SUBSCRIBE) + + identb = s.getsockopt(zmq.IDENTITY) + identu = identb.decode('utf16') + identu2 = s.getsockopt_unicode(zmq.IDENTITY, 'utf16') + self.assertEqual(identu, identu2) + time.sleep(0.1) # wait for connection/subscription + p.send_unicode(topic,zmq.SNDMORE) + p.send_unicode(topic*2, encoding='latin-1') + self.assertEqual(topic, s.recv_unicode()) + self.assertEqual(topic*2, s.recv_unicode(encoding='latin-1')) + + def test_int_sockopts(self): + "test integer sockopts" + v = zmq.zmq_version_info() + if v < (3,0): + default_hwm = 0 + else: + default_hwm = 1000 + p,s = self.create_bound_pair(zmq.PUB, zmq.SUB) + p.setsockopt(zmq.LINGER, 0) + self.assertEqual(p.getsockopt(zmq.LINGER), 0) + p.setsockopt(zmq.LINGER, -1) + self.assertEqual(p.getsockopt(zmq.LINGER), -1) + self.assertEqual(p.hwm, default_hwm) + p.hwm = 11 + self.assertEqual(p.hwm, 11) + # p.setsockopt(zmq.EVENTS, zmq.POLLIN) + self.assertEqual(p.getsockopt(zmq.EVENTS), zmq.POLLOUT) + self.assertRaisesErrno(zmq.EINVAL, p.setsockopt,zmq.EVENTS, 2**7-1) + self.assertEqual(p.getsockopt(zmq.TYPE), p.socket_type) + self.assertEqual(p.getsockopt(zmq.TYPE), zmq.PUB) + self.assertEqual(s.getsockopt(zmq.TYPE), s.socket_type) + self.assertEqual(s.getsockopt(zmq.TYPE), zmq.SUB) + + # check for overflow / wrong type: + errors = [] + backref = {} + constants = zmq.constants + for name in constants.__all__: + value = getattr(constants, name) + if isinstance(value, int): + backref[value] = name + for opt in zmq.constants.int_sockopts.union(zmq.constants.int64_sockopts): + sopt = backref[opt] + if sopt.startswith(( + 'ROUTER', 'XPUB', 'TCP', 'FAIL', + 'REQ_', 'CURVE_', 'PROBE_ROUTER', + 'IPC_FILTER', 'GSSAPI', 'STREAM_', + 'VMCI_BUFFER_SIZE', 'VMCI_BUFFER_MIN_SIZE', + 'VMCI_BUFFER_MAX_SIZE', 'VMCI_CONNECT_TIMEOUT', + )): + # some sockopts are write-only + continue + try: + n = p.getsockopt(opt) + except zmq.ZMQError as e: + errors.append("getsockopt(zmq.%s) raised '%s'."%(sopt, e)) + else: + if n > 2**31: + errors.append("getsockopt(zmq.%s) returned a ridiculous value." + " It is probably the wrong type."%sopt) + if errors: + self.fail('\n'.join([''] + errors)) + + def test_bad_sockopts(self): + """Test that appropriate errors are raised on bad socket options""" + s = self.context.socket(zmq.PUB) + self.sockets.append(s) + s.setsockopt(zmq.LINGER, 0) + # unrecognized int sockopts pass through to libzmq, and should raise EINVAL + self.assertRaisesErrno(zmq.EINVAL, s.setsockopt, 9999, 5) + self.assertRaisesErrno(zmq.EINVAL, s.getsockopt, 9999) + # but only int sockopts are allowed through this way, otherwise raise a TypeError + self.assertRaises(TypeError, s.setsockopt, 9999, b"5") + # some sockopts are valid in general, but not on every socket: + self.assertRaisesErrno(zmq.EINVAL, s.setsockopt, zmq.SUBSCRIBE, b'hi') + + def test_sockopt_roundtrip(self): + "test set/getsockopt roundtrip." + p = self.context.socket(zmq.PUB) + self.sockets.append(p) + p.setsockopt(zmq.LINGER, 11) + self.assertEqual(p.getsockopt(zmq.LINGER), 11) + + def test_send_unicode(self): + "test sending unicode objects" + a,b = self.create_bound_pair(zmq.PAIR, zmq.PAIR) + self.sockets.extend([a,b]) + u = "çπ§" + if str is not unicode: + u = u.decode('utf8') + self.assertRaises(TypeError, a.send, u,copy=False) + self.assertRaises(TypeError, a.send, u,copy=True) + a.send_unicode(u) + s = b.recv() + self.assertEqual(s,u.encode('utf8')) + self.assertEqual(s.decode('utf8'),u) + a.send_unicode(u,encoding='utf16') + s = b.recv_unicode(encoding='utf16') + self.assertEqual(s,u) + + def test_send_multipart_check_type(self): + "check type on all frames in send_multipart" + a,b = self.create_bound_pair(zmq.PAIR, zmq.PAIR) + self.sockets.extend([a,b]) + self.assertRaises(TypeError, a.send_multipart, [b'a', 5]) + a.send_multipart([b'b']) + rcvd = self.recv_multipart(b) + self.assertEqual(rcvd, [b'b']) + + @skip_pypy + def test_tracker(self): + "test the MessageTracker object for tracking when zmq is done with a buffer" + addr = 'tcp://127.0.0.1' + # get a port: + sock = socket.socket() + sock.bind(('127.0.0.1', 0)) + port = sock.getsockname()[1] + iface = "%s:%i" % (addr, port) + sock.close() + time.sleep(0.1) + + a = self.context.socket(zmq.PUSH) + b = self.context.socket(zmq.PULL) + self.sockets.extend([a,b]) + a.connect(iface) + time.sleep(0.1) + p1 = a.send(b'something', copy=False, track=True) + assert isinstance(p1, zmq.MessageTracker) + assert p1 is zmq._FINISHED_TRACKER + # small message, should start done + assert p1.done + + # disable zero-copy threshold + a.copy_threshold = 0 + + p2 = a.send_multipart([b'something', b'else'], copy=False, track=True) + assert isinstance(p2, zmq.MessageTracker) + assert not p2.done + + b.bind(iface) + msg = self.recv_multipart(b) + for i in range(10): + if p1.done: + break + time.sleep(0.1) + self.assertEqual(p1.done, True) + self.assertEqual(msg, [b'something']) + msg = self.recv_multipart(b) + for i in range(10): + if p2.done: + break + time.sleep(0.1) + self.assertEqual(p2.done, True) + self.assertEqual(msg, [b'something', b'else']) + m = zmq.Frame(b"again", copy=False, track=True) + self.assertEqual(m.tracker.done, False) + p1 = a.send(m, copy=False) + p2 = a.send(m, copy=False) + self.assertEqual(m.tracker.done, False) + self.assertEqual(p1.done, False) + self.assertEqual(p2.done, False) + msg = self.recv_multipart(b) + self.assertEqual(m.tracker.done, False) + self.assertEqual(msg, [b'again']) + msg = self.recv_multipart(b) + self.assertEqual(m.tracker.done, False) + self.assertEqual(msg, [b'again']) + self.assertEqual(p1.done, False) + self.assertEqual(p2.done, False) + pm = m.tracker + del m + for i in range(10): + if p1.done: + break + time.sleep(0.1) + self.assertEqual(p1.done, True) + self.assertEqual(p2.done, True) + m = zmq.Frame(b'something', track=False) + self.assertRaises(ValueError, a.send, m, copy=False, track=True) + + def test_close(self): + ctx = self.Context() + s = ctx.socket(zmq.PUB) + s.close() + self.assertRaisesErrno(zmq.ENOTSOCK, s.bind, b'') + self.assertRaisesErrno(zmq.ENOTSOCK, s.connect, b'') + self.assertRaisesErrno(zmq.ENOTSOCK, s.setsockopt, zmq.SUBSCRIBE, b'') + self.assertRaisesErrno(zmq.ENOTSOCK, s.send, b'asdf') + self.assertRaisesErrno(zmq.ENOTSOCK, s.recv) + del ctx + + def test_attr(self): + """set setting/getting sockopts as attributes""" + s = self.context.socket(zmq.DEALER) + self.sockets.append(s) + linger = 10 + s.linger = linger + self.assertEqual(linger, s.linger) + self.assertEqual(linger, s.getsockopt(zmq.LINGER)) + self.assertEqual(s.fd, s.getsockopt(zmq.FD)) + + def test_bad_attr(self): + s = self.context.socket(zmq.DEALER) + self.sockets.append(s) + try: + s.apple='foo' + except AttributeError: + pass + else: + self.fail("bad setattr should have raised AttributeError") + try: + s.apple + except AttributeError: + pass + else: + self.fail("bad getattr should have raised AttributeError") + + def test_subclass(self): + """subclasses can assign attributes""" + class S(zmq.Socket): + a = None + def __init__(self, *a, **kw): + self.a=-1 + super(S, self).__init__(*a, **kw) + + s = S(self.context, zmq.REP) + self.sockets.append(s) + self.assertEqual(s.a, -1) + s.a=1 + self.assertEqual(s.a, 1) + a=s.a + self.assertEqual(a, 1) + + def test_recv_multipart(self): + a,b = self.create_bound_pair() + msg = b'hi' + for i in range(3): + a.send(msg) + time.sleep(0.1) + for i in range(3): + self.assertEqual(self.recv_multipart(b), [msg]) + + def test_close_after_destroy(self): + """s.close() after ctx.destroy() should be fine""" + ctx = self.Context() + s = ctx.socket(zmq.REP) + ctx.destroy() + # reaper is not instantaneous + time.sleep(1e-2) + s.close() + self.assertTrue(s.closed) + + def test_poll(self): + a,b = self.create_bound_pair() + tic = time.time() + evt = a.poll(POLL_TIMEOUT) + self.assertEqual(evt, 0) + evt = a.poll(POLL_TIMEOUT, zmq.POLLOUT) + self.assertEqual(evt, zmq.POLLOUT) + msg = b'hi' + a.send(msg) + evt = b.poll(POLL_TIMEOUT) + self.assertEqual(evt, zmq.POLLIN) + msg2 = self.recv(b) + evt = b.poll(POLL_TIMEOUT) + self.assertEqual(evt, 0) + self.assertEqual(msg2, msg) + + def test_ipc_path_max_length(self): + """IPC_PATH_MAX_LEN is a sensible value""" + if zmq.IPC_PATH_MAX_LEN == 0: + raise SkipTest("IPC_PATH_MAX_LEN undefined") + + msg = "Surprising value for IPC_PATH_MAX_LEN: %s" % zmq.IPC_PATH_MAX_LEN + self.assertTrue(zmq.IPC_PATH_MAX_LEN > 30, msg) + self.assertTrue(zmq.IPC_PATH_MAX_LEN < 1025, msg) + + def test_ipc_path_max_length_msg(self): + if zmq.IPC_PATH_MAX_LEN == 0: + raise SkipTest("IPC_PATH_MAX_LEN undefined") + + s = self.context.socket(zmq.PUB) + self.sockets.append(s) + try: + s.bind('ipc://{0}'.format('a' * (zmq.IPC_PATH_MAX_LEN + 1))) + except zmq.ZMQError as e: + self.assertTrue(str(zmq.IPC_PATH_MAX_LEN) in e.strerror) + + @mark.skipif(windows, reason="ipc not supported on Windows.") + def test_ipc_path_no_such_file_or_directory_message(self): + """Display the ipc path in case of an ENOENT exception""" + s = self.context.socket(zmq.PUB) + self.sockets.append(s) + invalid_path = '/foo/bar' + with pytest.raises(zmq.ZMQError) as error: + s.bind('ipc://{0}'.format(invalid_path)) + assert error.value.errno == errno.ENOENT + error_message = str(error.value) + assert invalid_path in error_message + assert "no such file or directory" in error_message.lower() + + def test_hwm(self): + zmq3 = zmq.zmq_version_info()[0] >= 3 + for stype in (zmq.PUB, zmq.ROUTER, zmq.SUB, zmq.REQ, zmq.DEALER): + s = self.context.socket(stype) + s.hwm = 100 + self.assertEqual(s.hwm, 100) + if zmq3: + try: + self.assertEqual(s.sndhwm, 100) + except AttributeError: + pass + try: + self.assertEqual(s.rcvhwm, 100) + except AttributeError: + pass + s.close() + + def test_copy(self): + s = self.socket(zmq.PUB) + scopy = copy.copy(s) + sdcopy = copy.deepcopy(s) + self.assertTrue(scopy._shadow) + self.assertTrue(sdcopy._shadow) + self.assertEqual(s.underlying, scopy.underlying) + self.assertEqual(s.underlying, sdcopy.underlying) + s.close() + + def test_send_buffer(self): + a, b = self.create_bound_pair(zmq.PUSH, zmq.PULL) + for buffer_type in (memoryview, bytearray): + rawbytes = str(buffer_type).encode('ascii') + msg = buffer_type(rawbytes) + a.send(msg) + recvd = b.recv() + assert recvd == rawbytes + + def test_shadow(self): + p = self.socket(zmq.PUSH) + p.bind("tcp://127.0.0.1:5555") + p2 = zmq.Socket.shadow(p.underlying) + self.assertEqual(p.underlying, p2.underlying) + s = self.socket(zmq.PULL) + s2 = zmq.Socket.shadow(s.underlying) + self.assertNotEqual(s.underlying, p.underlying) + self.assertEqual(s.underlying, s2.underlying) + s2.connect("tcp://127.0.0.1:5555") + sent = b'hi' + p2.send(sent) + rcvd = self.recv(s2) + self.assertEqual(rcvd, sent) + + def test_shadow_pyczmq(self): + try: + from pyczmq import zctx, zsocket + except Exception: + raise SkipTest("Requires pyczmq") + + ctx = zctx.new() + ca = zsocket.new(ctx, zmq.PUSH) + cb = zsocket.new(ctx, zmq.PULL) + a = zmq.Socket.shadow(ca) + b = zmq.Socket.shadow(cb) + a.bind("inproc://a") + b.connect("inproc://a") + a.send(b'hi') + rcvd = self.recv(b) + self.assertEqual(rcvd, b'hi') + + def test_subscribe_method(self): + pub, sub = self.create_bound_pair(zmq.PUB, zmq.SUB) + sub.subscribe('prefix') + sub.subscribe = 'c' + p = zmq.Poller() + p.register(sub, zmq.POLLIN) + # wait for subscription handshake + for i in range(100): + pub.send(b'canary') + events = p.poll(250) + if events: + break + self.recv(sub) + pub.send(b'prefixmessage') + msg = self.recv(sub) + self.assertEqual(msg, b'prefixmessage') + sub.unsubscribe('prefix') + pub.send(b'prefixmessage') + events = p.poll(1000) + self.assertEqual(events, []) + + # Travis can't handle how much memory PyPy uses on this test + @mark.skipif( + ( + pypy and on_travis + ) or ( + sys.maxsize < 2**32 + ) or ( + windows + ), + reason="only run on 64b and not on Travis." + ) + @mark.large + def test_large_send(self): + c = os.urandom(1) + N = 2**31 + 1 + try: + buf = c * N + except MemoryError as e: + raise SkipTest("Not enough memory: %s" % e) + a, b = self.create_bound_pair() + try: + a.send(buf, copy=False) + rcvd = b.recv(copy=False) + except MemoryError as e: + raise SkipTest("Not enough memory: %s" % e) + # sample the front and back of the received message + # without checking the whole content + # Python 2: items in memoryview are bytes + # Python 3: items im memoryview are int + byte = c if sys.version_info < (3,) else ord(c) + view = memoryview(rcvd) + assert len(view) == N + assert view[0] == byte + assert view[-1] == byte + + def test_custom_serialize(self): + a, b = self.create_bound_pair(zmq.DEALER, zmq.ROUTER) + def serialize(msg): + frames = [] + frames.extend(msg.get('identities', [])) + content = json.dumps(msg['content']).encode('utf8') + frames.append(content) + return frames + + def deserialize(frames): + identities = frames[:-1] + content = json.loads(frames[-1].decode('utf8')) + return { + 'identities': identities, + 'content': content, + } + + msg = { + 'content': { + 'a': 5, + 'b': 'bee', + } + } + a.send_serialized(msg, serialize) + recvd = b.recv_serialized(deserialize) + assert recvd['content'] == msg['content'] + assert recvd['identities'] + # bounce back, tests identities + b.send_serialized(recvd, serialize) + r2 = a.recv_serialized(deserialize) + assert r2['content'] == msg['content'] + assert not r2['identities'] + + +if have_gevent and not windows: + import gevent + + class TestSocketGreen(GreenTest, TestSocket): + test_bad_attr = GreenTest.skip_green + test_close_after_destroy = GreenTest.skip_green + + def test_timeout(self): + a,b = self.create_bound_pair() + g = gevent.spawn_later(0.5, lambda: a.send(b'hi')) + timeout = gevent.Timeout(0.1) + timeout.start() + self.assertRaises(gevent.Timeout, b.recv) + g.kill() + + @mark.skipif(not hasattr(zmq, 'RCVTIMEO'), reason="requires RCVTIMEO") + def test_warn_set_timeo(self): + s = self.context.socket(zmq.REQ) + with warnings.catch_warnings(record=True) as w: + s.rcvtimeo = 5 + s.close() + self.assertEqual(len(w), 1) + self.assertEqual(w[0].category, UserWarning) + + + @mark.skipif(not hasattr(zmq, 'SNDTIMEO'), reason="requires SNDTIMEO") + def test_warn_get_timeo(self): + s = self.context.socket(zmq.REQ) + with warnings.catch_warnings(record=True) as w: + s.sndtimeo + s.close() + self.assertEqual(len(w), 1) + self.assertEqual(w[0].category, UserWarning) diff --git a/.venv/lib/python3.8/site-packages/zmq/tests/test_ssh.py b/.venv/lib/python3.8/site-packages/zmq/tests/test_ssh.py new file mode 100644 index 00000000..b282c006 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/zmq/tests/test_ssh.py @@ -0,0 +1,8 @@ +from zmq.ssh.tunnel import select_random_ports + +def test_random_ports(): + for i in range(4096): + ports = select_random_ports(10) + assert len(ports) == 10 + for p in ports: + assert ports.count(p) == 1 diff --git a/.venv/lib/python3.8/site-packages/zmq/tests/test_version.py b/.venv/lib/python3.8/site-packages/zmq/tests/test_version.py new file mode 100644 index 00000000..6ebebf30 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/zmq/tests/test_version.py @@ -0,0 +1,44 @@ +# Copyright (C) PyZMQ Developers +# Distributed under the terms of the Modified BSD License. + + +from unittest import TestCase +import zmq +from zmq.sugar import version + + +class TestVersion(TestCase): + + def test_pyzmq_version(self): + vs = zmq.pyzmq_version() + vs2 = zmq.__version__ + self.assertTrue(isinstance(vs, str)) + if zmq.__revision__: + self.assertEqual(vs, '@'.join(vs2, zmq.__revision__)) + else: + self.assertEqual(vs, vs2) + if version.VERSION_EXTRA: + self.assertTrue(version.VERSION_EXTRA in vs) + self.assertTrue(version.VERSION_EXTRA in vs2) + + def test_pyzmq_version_info(self): + info = zmq.pyzmq_version_info() + self.assertTrue(isinstance(info, tuple)) + for n in info[:3]: + self.assertTrue(isinstance(n, int)) + if version.VERSION_EXTRA: + self.assertEqual(len(info), 4) + self.assertEqual(info[-1], float('inf')) + else: + self.assertEqual(len(info), 3) + + def test_zmq_version_info(self): + info = zmq.zmq_version_info() + self.assertTrue(isinstance(info, tuple)) + for n in info[:3]: + self.assertTrue(isinstance(n, int)) + + def test_zmq_version(self): + v = zmq.zmq_version() + self.assertTrue(isinstance(v, str)) + diff --git a/.venv/lib/python3.8/site-packages/zmq/tests/test_win32_shim.py b/.venv/lib/python3.8/site-packages/zmq/tests/test_win32_shim.py new file mode 100644 index 00000000..64b92515 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/zmq/tests/test_win32_shim.py @@ -0,0 +1,63 @@ +from __future__ import print_function + +import os +import time +import sys +from functools import wraps + +from pytest import mark + +from zmq.tests import BaseZMQTestCase +from zmq.utils.win32 import allow_interrupt + + +def count_calls(f): + @wraps(f) + def _(*args, **kwds): + try: + return f(*args, **kwds) + finally: + _.__calls__ += 1 + _.__calls__ = 0 + return _ + + +@mark.new_console +class TestWindowsConsoleControlHandler(BaseZMQTestCase): + + @mark.new_console + @mark.skipif( + not sys.platform.startswith('win'), + reason='Windows only test') + def test_handler(self): + @count_calls + def interrupt_polling(): + print('Caught CTRL-C!') + + from ctypes import windll + from ctypes.wintypes import BOOL, DWORD + + kernel32 = windll.LoadLibrary('kernel32') + + # + GenerateConsoleCtrlEvent = kernel32.GenerateConsoleCtrlEvent + GenerateConsoleCtrlEvent.argtypes = (DWORD, DWORD) + GenerateConsoleCtrlEvent.restype = BOOL + + # Simulate CTRL-C event while handler is active. + try: + with allow_interrupt(interrupt_polling) as context: + result = GenerateConsoleCtrlEvent(0, 0) + # Sleep so that we give time to the handler to + # capture the Ctrl-C event. + time.sleep(0.5) + except KeyboardInterrupt: + pass + else: + if result == 0: + raise WindowsError() + else: + self.fail('Expecting `KeyboardInterrupt` exception!') + + # Make sure our handler was called. + self.assertEqual(interrupt_polling.__calls__, 1) diff --git a/.venv/lib/python3.8/site-packages/zmq/tests/test_z85.py b/.venv/lib/python3.8/site-packages/zmq/tests/test_z85.py new file mode 100644 index 00000000..8a73cb4d --- /dev/null +++ b/.venv/lib/python3.8/site-packages/zmq/tests/test_z85.py @@ -0,0 +1,63 @@ +# -*- coding: utf8 -*- +"""Test Z85 encoding + +confirm values and roundtrip with test values from the reference implementation. +""" + +# Copyright (C) PyZMQ Developers +# Distributed under the terms of the Modified BSD License. + +from unittest import TestCase +from zmq.utils import z85 + + +class TestZ85(TestCase): + + def test_client_public(self): + client_public = \ + b"\xBB\x88\x47\x1D\x65\xE2\x65\x9B" \ + b"\x30\xC5\x5A\x53\x21\xCE\xBB\x5A" \ + b"\xAB\x2B\x70\xA3\x98\x64\x5C\x26" \ + b"\xDC\xA2\xB2\xFC\xB4\x3F\xC5\x18" + encoded = z85.encode(client_public) + + self.assertEqual(encoded, b"Yne@$w-vo}U?@Lns47E1%kR.o@n%FcmmsL/@{H8]yf7") + decoded = z85.decode(encoded) + self.assertEqual(decoded, server_public) + + def test_server_secret(self): + server_secret = \ + b"\x8E\x0B\xDD\x69\x76\x28\xB9\x1D" \ + b"\x8F\x24\x55\x87\xEE\x95\xC5\xB0" \ + b"\x4D\x48\x96\x3F\x79\x25\x98\x77" \ + b"\xB4\x9C\xD9\x06\x3A\xEA\xD3\xB7" + encoded = z85.encode(server_secret) + + self.assertEqual(encoded, b"JTKVSB%%)wK0E.X)V>+}o?pNmC{O&4W4b!Ni{Lh6") + decoded = z85.decode(encoded) + self.assertEqual(decoded, server_secret) + diff --git a/.venv/lib/python3.8/site-packages/zmq/tests/test_zmqstream.py b/.venv/lib/python3.8/site-packages/zmq/tests/test_zmqstream.py new file mode 100644 index 00000000..7ff3bb8a --- /dev/null +++ b/.venv/lib/python3.8/site-packages/zmq/tests/test_zmqstream.py @@ -0,0 +1,79 @@ +# -*- coding: utf8 -*- +# Copyright (C) PyZMQ Developers +# Distributed under the terms of the Modified BSD License. + +from __future__ import absolute_import +try: + import asyncio +except ImportError: + asyncio = None + +from unittest import TestCase + +import pytest +import zmq +try: + import tornado + from tornado import gen + from zmq.eventloop import ioloop, zmqstream +except ImportError: + tornado = None + +class TestZMQStream(TestCase): + + def setUp(self): + if tornado is None: + pytest.skip() + if asyncio: + asyncio.set_event_loop(asyncio.new_event_loop()) + self.context = zmq.Context() + self.loop = ioloop.IOLoop() + self.loop.make_current() + self.push = zmqstream.ZMQStream(self.context.socket(zmq.PUSH)) + self.pull = zmqstream.ZMQStream(self.context.socket(zmq.PULL)) + port = self.push.bind_to_random_port('tcp://127.0.0.1') + self.pull.connect('tcp://127.0.0.1:%i' % port) + self.stream = self.push + + def tearDown(self): + self.loop.close(all_fds=True) + self.context.term() + ioloop.IOLoop.clear_current() + + def run_until_timeout(self, timeout=10): + timed_out = [] + @gen.coroutine + def sleep_timeout(): + yield gen.sleep(timeout) + timed_out[:] = ['timed out'] + self.loop.stop() + self.loop.add_callback(lambda : sleep_timeout()) + self.loop.start() + assert not timed_out + + def test_callable_check(self): + """Ensure callable check works (py3k).""" + + self.stream.on_send(lambda *args: None) + self.stream.on_recv(lambda *args: None) + self.assertRaises(AssertionError, self.stream.on_recv, 1) + self.assertRaises(AssertionError, self.stream.on_send, 1) + self.assertRaises(AssertionError, self.stream.on_recv, zmq) + + def test_on_recv_basic(self): + sent = [b'basic'] + def callback(msg): + assert msg == sent + self.loop.stop() + self.loop.add_callback(lambda : self.push.send_multipart(sent)) + self.pull.on_recv(callback) + self.run_until_timeout() + + def test_on_recv_wake(self): + sent = [b'wake'] + def callback(msg): + assert msg == sent + self.loop.stop() + self.pull.on_recv(callback) + self.loop.call_later(1, lambda : self.push.send_multipart(sent)) + self.run_until_timeout() diff --git a/.venv/lib/python3.8/site-packages/zmq/utils/__init__.py b/.venv/lib/python3.8/site-packages/zmq/utils/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/.venv/lib/python3.8/site-packages/zmq/utils/__pycache__/__init__.cpython-38.pyc b/.venv/lib/python3.8/site-packages/zmq/utils/__pycache__/__init__.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..492b8889063700da702d040f1846f78c2840eedc GIT binary patch literal 145 zcmWIL<>g`k0@j9W@gVv!h(HF6K#l_t7qb9~6oz01O-8?!3`HPe1o6vEza+OnzaXTZl OX-=vg$h^-$%m4sE#31_s literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/zmq/utils/__pycache__/constant_names.cpython-38.pyc b/.venv/lib/python3.8/site-packages/zmq/utils/__pycache__/constant_names.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..6bd13e88cca983355bc3d4fa9121f320c510c472 GIT binary patch literal 5992 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 AmjD0& literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/zmq/utils/__pycache__/garbage.cpython-38.pyc b/.venv/lib/python3.8/site-packages/zmq/utils/__pycache__/garbage.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..aa36f015365c20fbf9eb98f1c00d9ff110cd7049 GIT binary patch literal 5707 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 a_JOVEOP#H9@xs3g>)&*^MM(=g#KAway}nrh literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/zmq/utils/__pycache__/jsonapi.cpython-38.pyc b/.venv/lib/python3.8/site-packages/zmq/utils/__pycache__/jsonapi.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..cf907bb73711922e05a8beb21ff71af72021dec8 GIT binary patch literal 1445 zcmb7E&yO256t+D-GCN7P+o}f+mGG(RR3woWEh<%2fdmH%Dix~=7zs_B*xB`Fe#Lgk zP81}ha^^okf+PPB2VXhyFYJkDC);f=NOUU*kOd7S;Dc zB$7p{o@3;m@6qzXcko_*vwXmNJoyFX2mFAi@J@N3Cp-nDJ`YY&HekPDgkCDyC}}!6 zWm<50p_`hPa;li>sI1yX89hqVPs=syG}S^$R?3ag)HHP385qb~8^Jhj=5$rdS;GaL zH;QhAYN{ojHC4-uoXQe7Qow%MnR9p@Q&w~OAwa*Upp4kaOKp35fnVh5O@4XexLj&BbfXz;>YEn8$n`Iw z>yN;2yv2*2I^txDIev-^y1-jB2k)==Ct}E!nBX;0$6NAy$b&z?wlgbnc(^k2;p1$SQfS_s3gOGiZR=i+k=NDN2N#CPQd6h}FD_J>`_rac zw6M9RQ92`6_=79_#D;+VIE!p=4`U;bV^gVJ^|5*;l*`h_qILzC1r|3p-r-uT|3vBt zmak66rfSEnY=^75WwV9g!}Ylkj4-P zCpaO8B*iK5EAQw{;Da}MKZ1!t1}_qIACyI2+51}r%3@F!ndllc&3*_RJjy{T`U`&JhV=*Ah(d03YI*#3VUN G`u_q8Ad;^D literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/zmq/utils/__pycache__/monitor.cpython-38.pyc b/.venv/lib/python3.8/site-packages/zmq/utils/__pycache__/monitor.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f5cad59ad9bb2ffa33ce2722b0f894646343eda6 GIT binary patch literal 2112 zcmc&#TZ?Q*(wA&ibutOF zAkMz{AAHz-@WDSM(vRy?{(=wUIaS>~GYa}>g{rRGIp?c$zH{>J{(jei*8Kk0QLp1T zzvJR|^I`EBboBrR=7bJ&nHRgEYrbCS!Pk%dq!Bh;hc#I9nG-fyhqYMynH#oPleK4F z*k;~iC%Cu$@~e#HF(>mZW+I)DT#H!f4WTI`QI@WFDtH=kGR@OSi!4=Snn|)vo)8Xa znj~2&bS6QxzXLqZ*MVCcjG{S@7NZrH3Pd6o56b4jw*~zXboCt!+PQMB0sF#NM>uER zeO&tsU-q=i8duICtbcH|_uOYqd;Y@1TYuYW-A8E{S^Fpdse9$Z`#SVDFwS_CF^-@| zCEN-;SBlQK>URk=Gn`XN6RrWdS)SC*EE6>&LlO(6dy|dkDloe!j2=nySc@f<;1#Qw z=sDG7P8Fe2iWO%hO9`!fM$R9eT@aN;3$87K8U;?i5K?I}ML0yL;jlJUPw>`zACZaB z<$DCXbN0dex6W2H&iS3=G$TvOFzVfU|1r1?8s9<8yEO*fN?mZB z%k+-7j5bS;Az>oYwR*eBxQe7$BArkt-XLqC=f>KCZxk7ui{oQ5Hn3rWd>mIu#@1as zB$GsT?T}Jia+bn%!R|&E37b$oB=4xL|LI)pP$2M&rm;~pjfJpN=?)r&AM>=>yU0^5 z68^cAnJijL%RJIWD^Hg+S_EF<0~aKk{l$^{@cH9(pp)fbDV8Vp4reFpIp^`o<>}?+ z=Jey!0dQo1`K1OW4g1SY@fHw9@rszEk~yz{Ms)y#b9m(Lxv#^o^=HeMufk4*&#oF) z1MH8Wt0Ne+sR!4d3)%1-vfzdL)YIOTca8br=PyC{f=3+KXnb1c2F7^?dnu80UDJ0e zv&01DCd*5{8d+&V51haV_A5F($%W(!l4OE8@$$!?$%p-S?cq0I#R@?xlwpr!NDu&n z2&P#aXKO4&P+Fwmsv^DR4f1_RfQiSJm!<$gxRFDKQWH=s($aJv^WA1w<=v8pCgP~< zpW5sZRUjv*26Z(r4TNK&IR8)m6_rpw@CM#v0n_P}N2s*AVDOmX-^-4D1!zN$-l`gP zUZG=e?UP<4xq&~~kPJL4`!lX9FO*K{1p$_$^;|@dc^L#ITG?RR;$@UiV>(k{7;4N^ z@R*Svxc{c=DGhl^B{RT`0wYjS;eV?PfwyZwE|}V|eXXRTCDFt4v%r^_Lg4`-9@SOb zBo`EhmUVa0G;fi6s0cIM4w#h1n^w~P_f> EFURRqtN;K2 literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/zmq/utils/__pycache__/sixcerpt.cpython-38.pyc b/.venv/lib/python3.8/site-packages/zmq/utils/__pycache__/sixcerpt.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..3d588d162fc8c3524c4e6fec44306b3299070105 GIT binary patch literal 833 zcmY*X&2G~`5Z+z?CQWh(2nnfzy?`)k8wu2kB0vb#tA&I(kOM2nyJ?*`w%K*sG;$CE z9;7|;LLBzWDX+kZ*=;H9So3LSJpZ#Fy4^Mc^1l9Jp8|w_8|6AVpu7fFF#tzH#4#s1 z9%6wfgyXx2J5w@rt~3`kSGe*SZ*!0PKk(2i`h0^2JOtSnK5u=;7;*9*MV)2;V37)0 z)ryv5s69_uJIU&!|CY$nq^`7goaA!>;^-%mEy(+4Z&1&wL6ue8^P+-K!M9J2 zgvhrSyNku??*8szIr}`A*IBLx(72rfy4QgeGRc&79x7yra*Sp^v3VDJ$oESfesksWy+ZBLPp&=7E)zp y!LnjpYUka@CkCF{%h;ONIyFx~+IGVivy#tq@ye`D^#I&Eq0_@X;*yTv?*0YXGRtEC literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/zmq/utils/__pycache__/strtypes.cpython-38.pyc b/.venv/lib/python3.8/site-packages/zmq/utils/__pycache__/strtypes.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..38a0136a19d2f98a4f0a9706789301130518a024 GIT binary patch literal 1027 zcma))OK;RL5XWujx!!CaJc{4|L4re3w|k)oB!ocF6QV*qF1bY6*xiO^lVCe#Q|$p! zJ_sCp<->6Bl~cb$PmGgoRRjktWjr&oX6FCPydMlGg5!Mt8UL^m`elNP$A{o4e6j+= zP=pv}B*ziv_yb}1I%3woBR04dS=^2sZgFRqL~apq2O=A?Zsf8R<}&Xqjy$%?eAWZc z=bnwCUPQSc^%-S-7O(+ZV#~~9y@?+MjJ!qbmk#3>Jk1lq!*L?BG?YqY#UxZs#bsC* z$#k4e>av!36YiEGJV-&-?uDOGq^?5sPQW-=?J zN{W&s9MNRGU!qnEicYtVHh*BI|8cXfBd0+=GOjaHvu?#{^AB@zr8dX^}tcxm1 z_ce!7Z4#sB#N3=b8f0WD{}Oyz&y+Hg7Ap6*Yz31nUvszH78}zCvVK}ypg`q627;_DbDU{@S9A8k;>S?9;kEbQ8bN&Rw ZQ+Wf7O?|QiKL>sfG1exuNBch9zX4^t`*{EW literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/zmq/utils/__pycache__/win32.cpython-38.pyc b/.venv/lib/python3.8/site-packages/zmq/utils/__pycache__/win32.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..79bb7555561bce3f95ddf6c9dcaac337c2896384 GIT binary patch literal 4828 zcma)A&u`qu6(+f>-PKB#Ww&XQAPFXFfoctDRoL*MMqt>LRa>aCa%H(j_fU%B%v!Wa z4l~1*vQLY;Ih=VvzW2R1GkSUBM%%$P z^S6Kb^`AS=zv-oV)$#HOxBe#@?(`k*axZrK?o)@?c>NoP*M)ah>(_+)rp{*$J@pnN z8u3ih=r@vPzvA-*z3*{BDl7zIXfcq9JBQ`^@X#5c6*q`U~QQm>qax z!M}w^HhvtM+j3h0~cIfA%U$@7-mgOtK)4_M$_-#(|6&Y$K8GnI>c_Ro4keJhP9{Pw0et0KZs*_ z>_=%Xlp1Dv@TBE9FOA|68%V_l(MgoPX6w5E0d_CnPVDsqQkinX_f6(!(U!k4GINic6s(CDLqv#I(qBawTAcICu@YEP^ddA*Rb% z0Q)poGG+%s%44CH7=DeA@IZuzG%?BJ;+0!(y* zTm(c5ksvk_im44aXL6{RJWj8K#Hg!=g#iFqn=maC!GbJ{BO8EKE(TEw{3<>kAX>*! z92+Ua)F519$_P(#^?ZDVjRaz7uqO+%K%#HMDPgQk4Hq|C_I>$WbB7>%DWgQS#FDy z41|MWKaC@=;F%oe@aig7D`cXvX>~u)5Lt<~2`fuwZj6BmnM^s}RRZq}+p6rnP_{%O=Y@j7c4!}`6Q2nBN=h>!sx1oX`o~RQ;tkc zp^BAqR5zKLD3L)?K2g7M5|Cn8i9C5=mzHi9$PbZ-q2%Jh1D2Vk#eT!egN#Sc$jnbh zenshW=Yg?<7AIW4V%_dU2i|NdU0nErs#FXy z1ZKx_7$eZ|l_IxfYYw_7-_c@W6~jAXgD)Ywv}+ zLFBcd5aPYi!=|LX=(&b_9k*UUbLxEOoVwq;w7bF%$P4CO$Jw2({Cj&rNECrav;I$u z+hiFyk0lT~ABu`md;uLx6FaN~!gO3_c3tp>>k4`v3GhKf8N-+!&DHNe40{ix+CdMyQUAQIKxz1|K52;op@6;Chv}F0?7Z~Tg#Jd4P;s!rWuwb!B?>!hjPc{_pOujgzm|XfLVPj%kflz2?pf z=bhU#<|yj0Ph_3KZqiW{`AytbkvsnMs-lXcAqg)pdcL6S6v`BB`Hhl}t7gh)tCbWM zv%Zf|3+4M;crDd_d{u2Z?1D~$gLFQnxut^@ou1KI)IlkI$yEYYoFHcYc17`Zz}itA zx7TUWq%=r`?-y;~Pb444^gQqTUk!tJ@}=qfT!y}{W+B)hs^;kF1~mri^TvQqUeE|l zV71)(-S%9o)~YG$FT6DGc*WeS&E6kg_SSd*@_eIcfE+xI(Ov)j_V!jW^W@d`&Xb~b zC{!xqdv`<3yKs@9N4WJJH09|-)ZWx_>cAPxoI1=23#Sfy3Tg5ta=lgDG`o-UL&pVr z5m^Xy`qjTh^DPK=*iwsD=s)m&>iACX{@oe4=9tqubHDaZJ@k4+#m>ytlM;pV1qr+w z&g;M{T3^ILvd@EuDkl58a#8rf z07y;mU9I@wg~-?K;ch)w@iTj_GcNY$CmZe!rKIXi61rh`u@yoXcTJj+nHKJOw^bW| zbj8tYD+zf>x2YtTyaZzn2TCvL9|5)T=Q|>iM|PWVy_1F|J;fllj1_ zHlY=zrNTdtoc>MQ(?u<`pFW^Zzd%#WZOMRdMf)mHBlSz_rhux?>01j+ff-*k!6AAw n4phQ1H4>%8R``bmf+mye%~oykY1>_N7rl0^4ZCrBw}1UVOTifw literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.8/site-packages/zmq/utils/__pycache__/z85.cpython-38.pyc b/.venv/lib/python3.8/site-packages/zmq/utils/__pycache__/z85.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..27ba9aca92ccc2862610dfa44b3de8419fedfc09 GIT binary patch literal 1959 zcmaJ?&2t+y6qmFgb{r=YN=QkXfn{h)O`D``YU*}EXh>Tcpe3zIKMcXMS;_V$_O7Fq z)5NT2I=FCThJS!bj{GMaIdRaHQ_kFaf%kUZk8nVmeUhG@q^I}$>FxT+NRB|Up8i?= zBSXkvIC#C7Ft`q1)C9pvg>cGQlU8WbvI-M)%iwg9aAVu5nB1&b!sZsYpAnG}R-fJ= zecGp$EYBpmA)ZZjoIxG>(U>Ha9MAFLXQVRB^Lzx_JZEK680{Xd?W;x@IDV_$6fF@b zSNSjuYfhz9bV|k9OFGh|ZIj+-gx_+R<-YYAo7D|}d+*cw}5|%k= zAlp(X!5uep7B1nYsH_Va&E?8|;0Z@HgyS_j!8YtFMQU{Z_&%*pq?}Cw%2ubTeDD|@ zy__Be`v~Dw?%Z?k-&%p?i5pxf*KfiZx!e&1m)t!vFwpBDE?m5{aJl%=mC{vr)8nF6 zZ}?l=%~lY$cVwhGyHED^yUU-h+_-t`v)ikmfAQs=yI-x{yI=l#{lUXWk1KPt*Uo+X z-Fx#NesX4U>1^SfjqiKcXHLKGQ9NZ(@F>J~1-|HQ5Oorhjj?Z8kM>y1Vp?OrupP5Z zej^fX3x;NM7qsE?Jx#qtm5ApT=T)mc-}c+HouKV{+k($NX$aAr-7D_x?H8{W=ew<) z`Hq5{&UZ`2x%R%!EjIl~d10%)G>*rkA2w8(h0ZZA87N+QiMENC`5xsYrf-te!va0R zn5AwqiT0ZMuUwSC>vZo4=nPI{y#-h@4hH{&YM6 zx*zC^xl^P^6+1Av5rbV!4q1=YNzaJc4YF~%XDSogsh$-Z2bQv9Gq$D(Hz&v>Ii!^A z+}^paGE%B+Z1icFaO+?wHV(08!$Zh)Clgu=N4if^J|RIvd<92%+wSS62C`vw&7KDJf-avOl?+6#Yo$3 zyDb8)vvA_d?dAJrZLB?B&{pz{w7C`fLBZBpa4*$lf?eDa77p4>dI7HKuC~KkEfVTK z_-H#dK`KUw6EX61jOE!FHE9;=lmRW14$K_G3$a4pBzXM}9Yy3dMPs5^pUG?8(U<@( z^pN(*LlR7zM48(;S)v51vN%H=ACrJRB7h7cZ2-~_V8%?x1EdFYh%_L}RE8sxiGAMy zbQgODw*cv^8o~s(;lNX}dVsac#UwUj>m;B(Nn(4PTp>Mk=ckw*498}I|E|h!jc^;e zQ=>8amHkW-+!wfjoJxGI*9EJdP&*FLiL#g5mN=eKpauh^iRGx%J z=lsYIBIQET)CPEv;H6Kj2R>fpCg$ptY4QzRI)-a3=>~P7heQC5N*DaVm#%H_;?DA# zd0 zN3pVmYrwQ|_{QiI%~N>}ED9q!Q?2sQt5)GU`%&sgeiuRof1;`%!0!a_Es?R>= 3 or (PY_MAJOR_VERSION >=2 and PY_MINOR_VERSION >= 7) + +cdef inline int oldstyle_available(): + return PY_MAJOR_VERSION < 3 + + +cdef inline int check_buffer(object ob): + """Version independent check for whether an object is a buffer. + + Parameters + ---------- + object : object + Any Python object + + Returns + ------- + int : 0 if no buffer interface, 3 if newstyle buffer interface, 2 if oldstyle. + """ + if PyObject_CheckBuffer(ob): + return 3 + if oldstyle_available(): + return PyObject_CheckReadBuffer(ob) and 2 + return 0 + + +cdef inline object asbuffer(object ob, int writable, int format, + void **base, Py_ssize_t *size, + Py_ssize_t *itemsize): + """Turn an object into a C buffer in a Python version-independent way. + + Parameters + ---------- + ob : object + The object to be turned into a buffer. + Must provide a Python Buffer interface + writable : int + Whether the resulting buffer should be allowed to write + to the object. + format : int + The format of the buffer. See Python buffer docs. + base : void ** + The pointer that will be used to store the resulting C buffer. + size : Py_ssize_t * + The size of the buffer(s). + itemsize : Py_ssize_t * + The size of an item, if the buffer is non-contiguous. + + Returns + ------- + An object describing the buffer format. Generally a str, such as 'B'. + """ + + cdef void *bptr = NULL + cdef Py_ssize_t blen = 0, bitemlen = 0 + cdef Py_buffer view + cdef int flags = PyBUF_SIMPLE + cdef int mode = 0 + + bfmt = None + + mode = check_buffer(ob) + if mode == 0: + raise TypeError("%r does not provide a buffer interface."%ob) + + if mode == 3: + flags = PyBUF_ANY_CONTIGUOUS + if writable: + flags |= PyBUF_WRITABLE + if format: + flags |= PyBUF_FORMAT + PyObject_GetBuffer(ob, &view, flags) + bptr = view.buf + blen = view.len + if format: + if view.format != NULL: + bfmt = view.format + bitemlen = view.itemsize + PyBuffer_Release(&view) + else: # oldstyle + if writable: + PyObject_AsWriteBuffer(ob, &bptr, &blen) + else: + PyObject_AsReadBuffer(ob, &bptr, &blen) + if format: + try: # numpy.ndarray + dtype = ob.dtype + bfmt = dtype.char + bitemlen = dtype.itemsize + except AttributeError: + try: # array.array + bfmt = ob.typecode + bitemlen = ob.itemsize + except AttributeError: + if isinstance(ob, bytes): + bfmt = b"B" + bitemlen = 1 + else: + # nothing found + bfmt = None + bitemlen = 0 + if base: base[0] = bptr + if size: size[0] = blen + if itemsize: itemsize[0] = bitemlen + + if PY_MAJOR_VERSION >= 3 and bfmt is not None: + return bfmt.decode('ascii') + return bfmt + + +cdef inline object asbuffer_r(object ob, void **base, Py_ssize_t *size): + """Wrapper for standard calls to asbuffer with a readonly buffer.""" + asbuffer(ob, 0, 0, base, size, NULL) + return ob + + +cdef inline object asbuffer_w(object ob, void **base, Py_ssize_t *size): + """Wrapper for standard calls to asbuffer with a writable buffer.""" + asbuffer(ob, 1, 0, base, size, NULL) + return ob + +#------------------------------------------------------------------------------ +# frombuffer: python buffer/view from C buffer +#------------------------------------------------------------------------------ + + +cdef inline object frombuffer_3(void *ptr, Py_ssize_t s, int readonly): + """Python 3 version of frombuffer. + + This is the Python 3 model, but will work on Python >= 2.6. Currently, + we use it only on >= 3.0. + """ + cdef Py_buffer pybuf + cdef Py_ssize_t *shape = [s] + cdef str astr="" + PyBuffer_FillInfo(&pybuf, astr, ptr, s, readonly, PyBUF_SIMPLE) + pybuf.format = "B" + pybuf.shape = shape + pybuf.ndim = 1 + return PyMemoryView_FromBuffer(&pybuf) + + +cdef inline object frombuffer_2(void *ptr, Py_ssize_t s, int readonly): + """Python 2 version of frombuffer. + + This must be used for Python <= 2.6, but we use it for all Python < 3. + """ + + if oldstyle_available(): + if readonly: + return PyBuffer_FromMemory(ptr, s) + else: + return PyBuffer_FromReadWriteMemory(ptr, s) + else: + raise NotImplementedError("Old style buffers not available.") + + +cdef inline object frombuffer(void *ptr, Py_ssize_t s, int readonly): + """Create a Python Buffer/View of a C array. + + Parameters + ---------- + ptr : void * + Pointer to the array to be copied. + s : size_t + Length of the buffer. + readonly : int + whether the resulting object should be allowed to write to the buffer. + + Returns + ------- + Python Buffer/View of the C buffer. + """ + # oldstyle first priority for now + if oldstyle_available(): + return frombuffer_2(ptr, s, readonly) + else: + return frombuffer_3(ptr, s, readonly) + + +cdef inline object frombuffer_r(void *ptr, Py_ssize_t s): + """Wrapper for readonly view frombuffer.""" + return frombuffer(ptr, s, 1) + + +cdef inline object frombuffer_w(void *ptr, Py_ssize_t s): + """Wrapper for writable view frombuffer.""" + return frombuffer(ptr, s, 0) + +#------------------------------------------------------------------------------ +# viewfromobject: python buffer/view from python object, refcounts intact +# frombuffer(asbuffer(obj)) would lose track of refs +#------------------------------------------------------------------------------ + +cdef inline object viewfromobject(object obj, int readonly): + """Construct a Python Buffer/View object from another Python object. + + This work in a Python version independent manner. + + Parameters + ---------- + obj : object + The input object to be cast as a buffer + readonly : int + Whether the result should be prevented from overwriting the original. + + Returns + ------- + Buffer/View of the original object. + """ + if not memoryview_available(): + if readonly: + return PyBuffer_FromObject(obj, 0, Py_END_OF_BUFFER) + else: + return PyBuffer_FromReadWriteObject(obj, 0, Py_END_OF_BUFFER) + else: + return PyMemoryView_FromObject(obj) + + +cdef inline object viewfromobject_r(object obj): + """Wrapper for readonly viewfromobject.""" + return viewfromobject(obj, 1) + + +cdef inline object viewfromobject_w(object obj): + """Wrapper for writable viewfromobject.""" + return viewfromobject(obj, 0) diff --git a/.venv/lib/python3.8/site-packages/zmq/utils/compiler.json b/.venv/lib/python3.8/site-packages/zmq/utils/compiler.json new file mode 100644 index 00000000..30928bb6 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/zmq/utils/compiler.json @@ -0,0 +1,22 @@ +{ + "libraries": [ + "zmq" + ], + "include_dirs": [ + "/usr/local/include", + "zmq/utils" + ], + "library_dirs": [ + "/usr/local/lib" + ], + "runtime_library_dirs": [ + "/usr/local/lib" + ], + "extra_link_args": [], + "define_macros": [ + [ + "HAVE_SYS_UN_H", + 1 + ] + ] +} \ No newline at end of file diff --git a/.venv/lib/python3.8/site-packages/zmq/utils/config.json b/.venv/lib/python3.8/site-packages/zmq/utils/config.json new file mode 100644 index 00000000..5f94c36d --- /dev/null +++ b/.venv/lib/python3.8/site-packages/zmq/utils/config.json @@ -0,0 +1,16 @@ +{ + "zmq_prefix": "/usr/local", + "zmq_draft_api": false, + "libzmq_extension": false, + "no_libzmq_extension": false, + "skip_check_zmq": false, + "allow_legacy_libzmq": false, + "bundle_msvcp": null, + "build_ext": {}, + "bdist_egg": {}, + "egg_info": { + "tag_build": "", + "tag_date": "0" + }, + "have_sys_un_h": true +} \ No newline at end of file diff --git a/.venv/lib/python3.8/site-packages/zmq/utils/constant_names.py b/.venv/lib/python3.8/site-packages/zmq/utils/constant_names.py new file mode 100644 index 00000000..3b8588e6 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/zmq/utils/constant_names.py @@ -0,0 +1,550 @@ +"""0MQ Constant names""" + +# Copyright (C) PyZMQ Developers +# Distributed under the terms of the Modified BSD License. + +# dictionaries of constants new or removed in particular versions + +new_in = { + (2,2,0) : [ + 'RCVTIMEO', + 'SNDTIMEO', + ], + (3,2,2) : [ + # errnos + 'EMSGSIZE', + 'EAFNOSUPPORT', + 'ENETUNREACH', + 'ECONNABORTED', + 'ECONNRESET', + 'ENOTCONN', + 'ETIMEDOUT', + 'EHOSTUNREACH', + 'ENETRESET', + + # ctx opts + 'IO_THREADS', + 'MAX_SOCKETS', + 'IO_THREADS_DFLT', + 'MAX_SOCKETS_DFLT', + + # socket opts + 'IPV4ONLY', + 'LAST_ENDPOINT', + 'ROUTER_BEHAVIOR', + 'ROUTER_MANDATORY', + 'FAIL_UNROUTABLE', + 'TCP_KEEPALIVE', + 'TCP_KEEPALIVE_CNT', + 'TCP_KEEPALIVE_IDLE', + 'TCP_KEEPALIVE_INTVL', + 'DELAY_ATTACH_ON_CONNECT', + 'XPUB_VERBOSE', + + # msg opts + 'MORE', + + 'EVENT_CONNECTED', + 'EVENT_CONNECT_DELAYED', + 'EVENT_CONNECT_RETRIED', + 'EVENT_LISTENING', + 'EVENT_BIND_FAILED', + 'EVENT_ACCEPTED', + 'EVENT_ACCEPT_FAILED', + 'EVENT_CLOSED', + 'EVENT_CLOSE_FAILED', + 'EVENT_DISCONNECTED', + 'EVENT_ALL', + ], + (4,0,0) : [ + # socket types + 'STREAM', + + # socket opts + 'IMMEDIATE', + 'ROUTER_RAW', + 'IPV6', + 'MECHANISM', + 'PLAIN_SERVER', + 'PLAIN_USERNAME', + 'PLAIN_PASSWORD', + 'CURVE_SERVER', + 'CURVE_PUBLICKEY', + 'CURVE_SECRETKEY', + 'CURVE_SERVERKEY', + 'PROBE_ROUTER', + 'REQ_RELAXED', + 'REQ_CORRELATE', + 'CONFLATE', + 'ZAP_DOMAIN', + + # security + 'NULL', + 'PLAIN', + 'CURVE', + + # events + 'EVENT_MONITOR_STOPPED', + ], + (4,1,0) : [ + # ctx opts + 'SOCKET_LIMIT', + 'THREAD_PRIORITY', + 'THREAD_PRIORITY_DFLT', + 'THREAD_SCHED_POLICY', + 'THREAD_SCHED_POLICY_DFLT', + + # socket opts + 'ROUTER_HANDOVER', + 'TOS', + 'IPC_FILTER_PID', + 'IPC_FILTER_UID', + 'IPC_FILTER_GID', + 'CONNECT_RID', + 'GSSAPI_SERVER', + 'GSSAPI_PRINCIPAL', + 'GSSAPI_SERVICE_PRINCIPAL', + 'GSSAPI_PLAINTEXT', + 'HANDSHAKE_IVL', + 'XPUB_NODROP', + 'SOCKS_PROXY', + + # msg opts + 'SRCFD', + 'SHARED', + + # security + 'GSSAPI', + ], + (4,2,0): [ + # polling + 'POLLPRI', + ], + (4,2,3): [ + 'ROUTING_ID', + 'CONNECT_ROUTING_ID', + ], + (4,3,0): [ + # context options + 'MSG_T_SIZE', + 'THREAD_AFFINITY_CPU_ADD', + 'THREAD_AFFINITY_CPU_REMOVE', + 'THREAD_NAME_PREFIX', + + # socket options + 'GSSAPI_PRINCIPAL_NAMETYPE', + 'GSSAPI_SERVICE_PRINCIPAL_NAMETYPE', + 'BINDTODEVICE', + + # GSSAPI principal name types + 'GSSAPI_NT_HOSTBASED', + 'GSSAPI_NT_USER_NAME', + 'GSSAPI_NT_KRB5_PRINCIPAL', + + # events + 'EVENT_HANDSHAKE_FAILED_NO_DETAIL', + 'EVENT_HANDSHAKE_SUCCEEDED', + 'EVENT_HANDSHAKE_FAILED_PROTOCOL', + 'EVENT_HANDSHAKE_FAILED_AUTH', + + 'PROTOCOL_ERROR_ZMTP_UNSPECIFIED', + 'PROTOCOL_ERROR_ZMTP_UNEXPECTED_COMMAND', + 'PROTOCOL_ERROR_ZMTP_INVALID_SEQUENCE', + 'PROTOCOL_ERROR_ZMTP_KEY_EXCHANGE', + 'PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_UNSPECIFIED', + 'PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_MESSAGE', + 'PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_HELLO', + 'PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_INITIATE', + 'PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_ERROR', + 'PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_READY', + 'PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_WELCOME', + 'PROTOCOL_ERROR_ZMTP_INVALID_METADATA', + 'PROTOCOL_ERROR_ZMTP_CRYPTOGRAPHIC', + 'PROTOCOL_ERROR_ZMTP_MECHANISM_MISMATCH', + + 'PROTOCOL_ERROR_ZAP_UNSPECIFIED', + 'PROTOCOL_ERROR_ZAP_MALFORMED_REPLY', + 'PROTOCOL_ERROR_ZAP_BAD_REQUEST_ID', + 'PROTOCOL_ERROR_ZAP_BAD_VERSION', + 'PROTOCOL_ERROR_ZAP_INVALID_STATUS_CODE', + 'PROTOCOL_ERROR_ZAP_INVALID_METADATA', + ] +} + +draft_in = { + (4,2,0): [ + # socket types + 'SERVER', + 'CLIENT', + 'RADIO', + 'DISH', + 'GATHER', + 'SCATTER', + 'DGRAM', + + # ctx options + 'BLOCKY', + + # socket options + 'XPUB_MANUAL', + 'XPUB_WELCOME_MSG', + 'STREAM_NOTIFY', + 'INVERT_MATCHING', + 'HEARTBEAT_IVL', + 'HEARTBEAT_TTL', + 'HEARTBEAT_TIMEOUT', + 'XPUB_VERBOSER', + 'CONNECT_TIMEOUT', + 'TCP_MAXRT', + 'THREAD_SAFE', + 'MULTICAST_MAXTPDU', + 'VMCI_BUFFER_SIZE', + 'VMCI_BUFFER_MIN_SIZE', + 'VMCI_BUFFER_MAX_SIZE', + 'VMCI_CONNECT_TIMEOUT', + 'USE_FD', + ], + (4,2,4): [ + # socket options + 'ZAP_ENFORCE_DOMAIN', + 'LOOPBACK_FASTPATH', + 'METADATA', + 'ZERO_COPY_RECV', + ], + (4,3,0): [ + # socket options + 'ROUTER_NOTIFY', + 'MULTICAST_LOOP', + + 'NOTIFY_CONNECT', + 'NOTIFY_DISCONNECT', + ], +} + + +removed_in = { + (3,2,2) : [ + 'UPSTREAM', + 'DOWNSTREAM', + + 'HWM', + 'SWAP', + 'MCAST_LOOP', + 'RECOVERY_IVL_MSEC', + ] +} + +# collections of zmq constant names based on their role +# base names have no specific use +# opt names are validated in get/set methods of various objects + +base_names = [ + # base + 'VERSION', + 'VERSION_MAJOR', + 'VERSION_MINOR', + 'VERSION_PATCH', + 'NOBLOCK', + 'DONTWAIT', + + 'POLLIN', + 'POLLOUT', + 'POLLERR', + 'POLLPRI', + + 'SNDMORE', + + 'STREAMER', + 'FORWARDER', + 'QUEUE', + + 'IO_THREADS_DFLT', + 'MAX_SOCKETS_DFLT', + 'POLLITEMS_DFLT', + 'THREAD_PRIORITY_DFLT', + 'THREAD_SCHED_POLICY_DFLT', + + # socktypes + 'PAIR', + 'PUB', + 'SUB', + 'REQ', + 'REP', + 'DEALER', + 'ROUTER', + 'XREQ', + 'XREP', + 'PULL', + 'PUSH', + 'XPUB', + 'XSUB', + 'UPSTREAM', + 'DOWNSTREAM', + 'STREAM', + 'SERVER', + 'CLIENT', + 'RADIO', + 'DISH', + 'GATHER', + 'SCATTER', + 'DGRAM', + + # events + 'EVENT_CONNECTED', + 'EVENT_CONNECT_DELAYED', + 'EVENT_CONNECT_RETRIED', + 'EVENT_LISTENING', + 'EVENT_BIND_FAILED', + 'EVENT_ACCEPTED', + 'EVENT_ACCEPT_FAILED', + 'EVENT_CLOSED', + 'EVENT_CLOSE_FAILED', + 'EVENT_DISCONNECTED', + 'EVENT_ALL', + 'EVENT_MONITOR_STOPPED', + 'EVENT_HANDSHAKE_FAILED_NO_DETAIL', + 'EVENT_HANDSHAKE_SUCCEEDED', + 'EVENT_HANDSHAKE_FAILED_PROTOCOL', + 'EVENT_HANDSHAKE_FAILED_AUTH', + + 'PROTOCOL_ERROR_ZMTP_UNSPECIFIED', + 'PROTOCOL_ERROR_ZMTP_UNEXPECTED_COMMAND', + 'PROTOCOL_ERROR_ZMTP_INVALID_SEQUENCE', + 'PROTOCOL_ERROR_ZMTP_KEY_EXCHANGE', + 'PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_UNSPECIFIED', + 'PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_MESSAGE', + 'PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_HELLO', + 'PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_INITIATE', + 'PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_ERROR', + 'PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_READY', + 'PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_WELCOME', + 'PROTOCOL_ERROR_ZMTP_INVALID_METADATA', + 'PROTOCOL_ERROR_ZMTP_CRYPTOGRAPHIC', + 'PROTOCOL_ERROR_ZMTP_MECHANISM_MISMATCH', + + 'PROTOCOL_ERROR_ZAP_UNSPECIFIED', + 'PROTOCOL_ERROR_ZAP_MALFORMED_REPLY', + 'PROTOCOL_ERROR_ZAP_BAD_REQUEST_ID', + 'PROTOCOL_ERROR_ZAP_BAD_VERSION', + 'PROTOCOL_ERROR_ZAP_INVALID_STATUS_CODE', + 'PROTOCOL_ERROR_ZAP_INVALID_METADATA', + + 'NOTIFY_CONNECT', + 'NOTIFY_DISCONNECT', + + # security + 'NULL', + 'PLAIN', + 'CURVE', + 'GSSAPI', + 'GSSAPI_NT_HOSTBASED', + 'GSSAPI_NT_USER_NAME', + 'GSSAPI_NT_KRB5_PRINCIPAL', + + ## ERRNO + # Often used (these are else in errno.) + 'EAGAIN', + 'EINVAL', + 'EFAULT', + 'ENOMEM', + 'ENODEV', + 'EMSGSIZE', + 'EAFNOSUPPORT', + 'ENETUNREACH', + 'ECONNABORTED', + 'ECONNRESET', + 'ENOTCONN', + 'ETIMEDOUT', + 'EHOSTUNREACH', + 'ENETRESET', + + # For Windows compatibility + 'HAUSNUMERO', + 'ENOTSUP', + 'EPROTONOSUPPORT', + 'ENOBUFS', + 'ENETDOWN', + 'EADDRINUSE', + 'EADDRNOTAVAIL', + 'ECONNREFUSED', + 'EINPROGRESS', + 'ENOTSOCK', + + # 0MQ Native + 'EFSM', + 'ENOCOMPATPROTO', + 'ETERM', + 'EMTHREAD', +] + +int64_sockopt_names = [ + 'AFFINITY', + 'MAXMSGSIZE', + + # sockopts removed in 3.0.0 + 'HWM', + 'SWAP', + 'MCAST_LOOP', + 'RECOVERY_IVL_MSEC', + + # new in 4.2 + 'VMCI_BUFFER_SIZE', + 'VMCI_BUFFER_MIN_SIZE', + 'VMCI_BUFFER_MAX_SIZE', +] + +bytes_sockopt_names = [ + 'IDENTITY', + 'SUBSCRIBE', + 'UNSUBSCRIBE', + 'LAST_ENDPOINT', + 'TCP_ACCEPT_FILTER', + + 'PLAIN_USERNAME', + 'PLAIN_PASSWORD', + + 'CURVE_PUBLICKEY', + 'CURVE_SECRETKEY', + 'CURVE_SERVERKEY', + 'ZAP_DOMAIN', + 'CONNECT_RID', + 'GSSAPI_PRINCIPAL', + 'GSSAPI_SERVICE_PRINCIPAL', + 'SOCKS_PROXY', + + 'XPUB_WELCOME_MSG', + + # new in 4.2.3 + 'ROUTING_ID', + 'CONNECT_ROUTING_ID', + + # new in 4.3.0 + 'BINDTODEVICE', +] + +fd_sockopt_names = [ + 'FD', +] + +int_sockopt_names = [ + # sockopts + 'RECONNECT_IVL_MAX', + + # sockopts new in 2.2.0 + 'SNDTIMEO', + 'RCVTIMEO', + + # new in 3.x + 'SNDHWM', + 'RCVHWM', + 'MULTICAST_HOPS', + 'IPV4ONLY', + + 'ROUTER_BEHAVIOR', + 'TCP_KEEPALIVE', + 'TCP_KEEPALIVE_CNT', + 'TCP_KEEPALIVE_IDLE', + 'TCP_KEEPALIVE_INTVL', + 'DELAY_ATTACH_ON_CONNECT', + 'XPUB_VERBOSE', + + 'EVENTS', + 'TYPE', + 'LINGER', + 'RECONNECT_IVL', + 'BACKLOG', + + 'ROUTER_MANDATORY', + 'FAIL_UNROUTABLE', + + 'ROUTER_RAW', + 'IMMEDIATE', + 'IPV6', + 'MECHANISM', + 'PLAIN_SERVER', + 'CURVE_SERVER', + 'PROBE_ROUTER', + 'REQ_RELAXED', + 'REQ_CORRELATE', + 'CONFLATE', + 'ROUTER_HANDOVER', + 'TOS', + 'IPC_FILTER_PID', + 'IPC_FILTER_UID', + 'IPC_FILTER_GID', + 'GSSAPI_SERVER', + 'GSSAPI_PLAINTEXT', + 'HANDSHAKE_IVL', + 'XPUB_NODROP', + + # new in 4.2 + 'XPUB_MANUAL', + 'STREAM_NOTIFY', + 'INVERT_MATCHING', + 'XPUB_VERBOSER', + 'HEARTBEAT_IVL', + 'HEARTBEAT_TTL', + 'HEARTBEAT_TIMEOUT', + 'CONNECT_TIMEOUT', + 'TCP_MAXRT', + 'THREAD_SAFE', + 'MULTICAST_MAXTPDU', + 'VMCI_CONNECT_TIMEOUT', + 'USE_FD', + + # new in 4.3 + 'GSSAPI_PRINCIPAL_NAMETYPE', + 'GSSAPI_SERVICE_PRINCIPAL_NAMETYPE', + 'MULTICAST_LOOP', + 'ROUTER_NOTIFY', + 'ZAP_ENFORCE_DOMAIN', +] + +switched_sockopt_names = [ + 'RATE', + 'RECOVERY_IVL', + 'SNDBUF', + 'RCVBUF', + 'RCVMORE', +] + +ctx_opt_names = [ + 'IO_THREADS', + 'MAX_SOCKETS', + 'SOCKET_LIMIT', + 'THREAD_PRIORITY', + 'THREAD_SCHED_POLICY', + 'BLOCKY', + + # new in 4.3 + 'MSG_T_SIZE', + 'THREAD_AFFINITY_CPU_ADD', + 'THREAD_AFFINITY_CPU_REMOVE', + 'THREAD_NAME_PREFIX', +] + +msg_opt_names = [ + 'MORE', + 'SRCFD', + 'SHARED', +] + +from itertools import chain + +all_names = list(chain( + base_names, + ctx_opt_names, + bytes_sockopt_names, + fd_sockopt_names, + int_sockopt_names, + int64_sockopt_names, + switched_sockopt_names, + msg_opt_names, +)) + +del chain + +def no_prefix(name): + """does the given constant have a ZMQ_ prefix?""" + return name.startswith('E') and not name.startswith('EVENT') + diff --git a/.venv/lib/python3.8/site-packages/zmq/utils/garbage.py b/.venv/lib/python3.8/site-packages/zmq/utils/garbage.py new file mode 100644 index 00000000..d96bbd97 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/zmq/utils/garbage.py @@ -0,0 +1,200 @@ +"""Garbage collection thread for representing zmq refcount of Python objects +used in zero-copy sends. +""" + +# Copyright (C) PyZMQ Developers +# Distributed under the terms of the Modified BSD License. + + +import atexit +import struct + +from os import getpid +from collections import namedtuple +from threading import Thread, Event, Lock +import warnings + +import zmq + + +gcref = namedtuple('gcref', ['obj', 'event']) + +class GarbageCollectorThread(Thread): + """Thread in which garbage collection actually happens.""" + def __init__(self, gc): + super(GarbageCollectorThread, self).__init__() + self.gc = gc + self.daemon = True + self.pid = getpid() + self.ready = Event() + + def run(self): + # detect fork at beginning of the thread + if getpid is None or getpid() != self.pid: + self.ready.set() + return + try: + s = self.gc.context.socket(zmq.PULL) + s.linger = 0 + s.bind(self.gc.url) + finally: + self.ready.set() + + while True: + # detect fork + if getpid is None or getpid() != self.pid: + return + msg = s.recv() + if msg == b'DIE': + break + fmt = 'L' if len(msg) == 4 else 'Q' + key = struct.unpack(fmt, msg)[0] + tup = self.gc.refs.pop(key, None) + if tup and tup.event: + tup.event.set() + del tup + s.close() + + +class GarbageCollector(object): + """PyZMQ Garbage Collector + + Used for representing the reference held by libzmq during zero-copy sends. + This object holds a dictionary, keyed by Python id, + of the Python objects whose memory are currently in use by zeromq. + + When zeromq is done with the memory, it sends a message on an inproc PUSH socket + containing the packed size_t (32 or 64-bit unsigned int), + which is the key in the dict. + When the PULL socket in the gc thread receives that message, + the reference is popped from the dict, + and any tracker events that should be signaled fire. + """ + + refs = None + _context = None + _lock = None + url = "inproc://pyzmq.gc.01" + + def __init__(self, context=None): + super(GarbageCollector, self).__init__() + self.refs = {} + self.pid = None + self.thread = None + self._context = context + self._lock = Lock() + self._stay_down = False + self._push = None + self._push_mutex = None + atexit.register(self._atexit) + + @property + def context(self): + if self._context is None: + if Thread.__module__.startswith('gevent'): + # gevent has monkey-patched Thread, use green Context + from zmq import green + self._context = green.Context() + else: + self._context = zmq.Context() + return self._context + + @context.setter + def context(self, ctx): + if self.is_alive(): + if self.refs: + warnings.warn("Replacing gc context while gc is running", RuntimeWarning) + self.stop() + self._context = ctx + + def _atexit(self): + """atexit callback + + sets _stay_down flag so that gc doesn't try to start up again in other atexit handlers + """ + self._stay_down = True + self.stop() + + def stop(self): + """stop the garbage-collection thread""" + if not self.is_alive(): + return + self._stop() + + def _stop(self): + push = self.context.socket(zmq.PUSH) + push.connect(self.url) + push.send(b'DIE') + push.close() + if self._push: + self._push.close() + self._push = None + self._push_mutex = None + self.thread.join() + self.context.term() + self.refs.clear() + self.context = None + + @property + def _push_socket(self): + """The PUSH socket for use in the zmq message destructor callback. + """ + if not self.is_alive() or self._push is None: + self._push = self.context.socket(zmq.PUSH) + self._push.connect(self.url) + return self._push + + def start(self): + """Start a new garbage collection thread. + + Creates a new zmq Context used for garbage collection. + Under most circumstances, this will only be called once per process. + """ + if self.thread is not None and self.pid != getpid(): + # It's re-starting, must free earlier thread's context + # since a fork probably broke it + self._stop() + self.pid = getpid() + self.refs = {} + self.thread = GarbageCollectorThread(self) + self.thread.start() + self.thread.ready.wait() + + def is_alive(self): + """Is the garbage collection thread currently running? + + Includes checks for process shutdown or fork. + """ + if (getpid is None or + getpid() != self.pid or + self.thread is None or + not self.thread.is_alive() + ): + return False + return True + + def store(self, obj, event=None): + """store an object and (optionally) event for zero-copy""" + if not self.is_alive(): + if self._stay_down: + return 0 + # safely start the gc thread + # use lock and double check, + # so we don't start multiple threads + with self._lock: + if not self.is_alive(): + self.start() + tup = gcref(obj, event) + theid = id(tup) + self.refs[theid] = tup + return theid + + def __del__(self): + if not self.is_alive(): + return + try: + self.stop() + except Exception as e: + raise (e) + +gc = GarbageCollector() diff --git a/.venv/lib/python3.8/site-packages/zmq/utils/getpid_compat.h b/.venv/lib/python3.8/site-packages/zmq/utils/getpid_compat.h new file mode 100644 index 00000000..47ce90fa --- /dev/null +++ b/.venv/lib/python3.8/site-packages/zmq/utils/getpid_compat.h @@ -0,0 +1,6 @@ +#ifdef _WIN32 + #include + #define getpid _getpid +#else + #include +#endif diff --git a/.venv/lib/python3.8/site-packages/zmq/utils/interop.py b/.venv/lib/python3.8/site-packages/zmq/utils/interop.py new file mode 100644 index 00000000..26c01969 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/zmq/utils/interop.py @@ -0,0 +1,33 @@ +"""Utils for interoperability with other libraries. + +Just CFFI pointer casting for now. +""" + +# Copyright (C) PyZMQ Developers +# Distributed under the terms of the Modified BSD License. + + +try: + long +except NameError: + long = int # Python 3 + + +def cast_int_addr(n): + """Cast an address to a Python int + + This could be a Python integer or a CFFI pointer + """ + if isinstance(n, (int, long)): + return n + try: + import cffi + except ImportError: + pass + else: + # from pyzmq, this is an FFI void * + ffi = cffi.FFI() + if isinstance(n, ffi.CData): + return int(ffi.cast("size_t", n)) + + raise ValueError("Cannot cast %r to int" % n) diff --git a/.venv/lib/python3.8/site-packages/zmq/utils/ipcmaxlen.h b/.venv/lib/python3.8/site-packages/zmq/utils/ipcmaxlen.h new file mode 100644 index 00000000..7218db78 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/zmq/utils/ipcmaxlen.h @@ -0,0 +1,21 @@ +/* + +Platform-independant detection of IPC path max length + +Copyright (c) 2012 Godefroid Chapelle + +Distributed under the terms of the New BSD License. The full license is in +the file COPYING.BSD, distributed as part of this software. + */ + +#if defined(HAVE_SYS_UN_H) +#include "sys/un.h" +int get_ipc_path_max_len(void) { + struct sockaddr_un *dummy; + return sizeof(dummy->sun_path) - 1; +} +#else +int get_ipc_path_max_len(void) { + return 0; +} +#endif diff --git a/.venv/lib/python3.8/site-packages/zmq/utils/jsonapi.py b/.venv/lib/python3.8/site-packages/zmq/utils/jsonapi.py new file mode 100644 index 00000000..865ca6d5 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/zmq/utils/jsonapi.py @@ -0,0 +1,59 @@ +"""Priority based json library imports. + +Always serializes to bytes instead of unicode for zeromq compatibility +on Python 2 and 3. + +Use ``jsonapi.loads()`` and ``jsonapi.dumps()`` for guaranteed symmetry. + +Priority: ``simplejson`` > ``jsonlib2`` > stdlib ``json`` + +``jsonapi.loads/dumps`` provide kwarg-compatibility with stdlib json. + +``jsonapi.jsonmod`` will be the module of the actual underlying implementation. +""" + +# Copyright (C) PyZMQ Developers +# Distributed under the terms of the Modified BSD License. + +from zmq.utils.strtypes import bytes, unicode + +jsonmod = None + +priority = ['simplejson', 'jsonlib2', 'json'] +for mod in priority: + try: + jsonmod = __import__(mod) + except ImportError: + pass + else: + break + +def dumps(o, **kwargs): + """Serialize object to JSON bytes (utf-8). + + See jsonapi.jsonmod.dumps for details on kwargs. + """ + + if 'separators' not in kwargs: + kwargs['separators'] = (',', ':') + + s = jsonmod.dumps(o, **kwargs) + + if isinstance(s, unicode): + s = s.encode('utf8') + + return s + +def loads(s, **kwargs): + """Load object from JSON bytes (utf-8). + + See jsonapi.jsonmod.loads for details on kwargs. + """ + + if str is unicode and isinstance(s, bytes): + s = s.decode('utf8') + + return jsonmod.loads(s, **kwargs) + +__all__ = ['jsonmod', 'dumps', 'loads'] + diff --git a/.venv/lib/python3.8/site-packages/zmq/utils/monitor.py b/.venv/lib/python3.8/site-packages/zmq/utils/monitor.py new file mode 100644 index 00000000..e933ea71 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/zmq/utils/monitor.py @@ -0,0 +1,68 @@ +# -*- coding: utf-8 -*- +"""Module holding utility and convenience functions for zmq event monitoring.""" + +# Copyright (C) PyZMQ Developers +# Distributed under the terms of the Modified BSD License. + +import struct +import zmq +from zmq.error import _check_version + +def parse_monitor_message(msg): + """decode zmq_monitor event messages. + + Parameters + ---------- + msg : list(bytes) + zmq multipart message that has arrived on a monitor PAIR socket. + + First frame is:: + + 16 bit event id + 32 bit event value + no padding + + Second frame is the endpoint as a bytestring + + Returns + ------- + event : dict + event description as dict with the keys `event`, `value`, and `endpoint`. + """ + + if len(msg) != 2 or len(msg[0]) != 6: + raise RuntimeError("Invalid event message format: %s" % msg) + event = {'event': struct.unpack("=hi", msg[0])[0], + 'value': struct.unpack("=hi", msg[0])[1], + 'endpoint': msg[1]} + return event + +def recv_monitor_message(socket, flags=0): + """Receive and decode the given raw message from the monitoring socket and return a dict. + + Requires libzmq ≥ 4.0 + + The returned dict will have the following entries: + event : int, the event id as described in libzmq.zmq_socket_monitor + value : int, the event value associated with the event, see libzmq.zmq_socket_monitor + endpoint : string, the affected endpoint + + Parameters + ---------- + socket : zmq PAIR socket + The PAIR socket (created by other.get_monitor_socket()) on which to recv the message + flags : bitfield (int) + standard zmq recv flags + + Returns + ------- + event : dict + event description as dict with the keys `event`, `value`, and `endpoint`. + """ + _check_version((4,0), 'libzmq event API') + # will always return a list + msg = socket.recv_multipart(flags) + # 4.0-style event API + return parse_monitor_message(msg) + +__all__ = ['parse_monitor_message', 'recv_monitor_message'] diff --git a/.venv/lib/python3.8/site-packages/zmq/utils/mutex.h b/.venv/lib/python3.8/site-packages/zmq/utils/mutex.h new file mode 100644 index 00000000..2191d08d --- /dev/null +++ b/.venv/lib/python3.8/site-packages/zmq/utils/mutex.h @@ -0,0 +1,82 @@ +/* +* simplified from mutex.c from Foundation Library, in the Public Domain +* https://github.com/rampantpixels/foundation_lib/blob/master/foundation/mutex.c +* +* This file is Copyright (C) PyZMQ Developers +* Distributed under the terms of the Modified BSD License. +* +*/ + +#pragma once + +#if defined(_WIN32) +# include +#else +# include +#endif + +typedef struct { +#if defined(_WIN32) + CRITICAL_SECTION csection; +#else + pthread_mutex_t mutex; +#endif +} mutex_t; + + +static void +_mutex_initialize(mutex_t* mutex) { +#if defined(_WIN32) + InitializeCriticalSectionAndSpinCount(&mutex->csection, 4000); +#else + pthread_mutexattr_t attr; + pthread_mutexattr_init(&attr); + pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); + pthread_mutex_init(&mutex->mutex, &attr); + pthread_mutexattr_destroy(&attr); +#endif +} + +static void +_mutex_finalize(mutex_t* mutex) { +#if defined(_WIN32) + DeleteCriticalSection(&mutex->csection); +#else + pthread_mutex_destroy(&mutex->mutex); +#endif +} + +mutex_t* +mutex_allocate(void) { + mutex_t* mutex = (mutex_t*)malloc(sizeof(mutex_t)); + _mutex_initialize(mutex); + return mutex; +} + +void +mutex_deallocate(mutex_t* mutex) { + if (!mutex) + return; + _mutex_finalize(mutex); + free(mutex); +} + +int +mutex_lock(mutex_t* mutex) { +#if defined(_WIN32) + EnterCriticalSection(&mutex->csection); + return 0; +#else + return pthread_mutex_lock(&mutex->mutex); +#endif +} + +int +mutex_unlock(mutex_t* mutex) { +#if defined(_WIN32) + LeaveCriticalSection(&mutex->csection); + return 0; +#else + return pthread_mutex_unlock(&mutex->mutex); +#endif +} diff --git a/.venv/lib/python3.8/site-packages/zmq/utils/pyversion_compat.h b/.venv/lib/python3.8/site-packages/zmq/utils/pyversion_compat.h new file mode 100644 index 00000000..fac09046 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/zmq/utils/pyversion_compat.h @@ -0,0 +1,25 @@ +#include "Python.h" + +#if PY_VERSION_HEX < 0x02070000 + #define PyMemoryView_FromBuffer(info) (PyErr_SetString(PyExc_NotImplementedError, \ + "new buffer interface is not available"), (PyObject *)NULL) + #define PyMemoryView_FromObject(object) (PyErr_SetString(PyExc_NotImplementedError, \ + "new buffer interface is not available"), (PyObject *)NULL) +#endif + +#if PY_VERSION_HEX >= 0x03000000 + // for buffers + #define Py_END_OF_BUFFER ((Py_ssize_t) 0) + + #define PyObject_CheckReadBuffer(object) (0) + + #define PyBuffer_FromMemory(ptr, s) (PyErr_SetString(PyExc_NotImplementedError, \ + "old buffer interface is not available"), (PyObject *)NULL) + #define PyBuffer_FromReadWriteMemory(ptr, s) (PyErr_SetString(PyExc_NotImplementedError, \ + "old buffer interface is not available"), (PyObject *)NULL) + #define PyBuffer_FromObject(object, offset, size) (PyErr_SetString(PyExc_NotImplementedError, \ + "old buffer interface is not available"), (PyObject *)NULL) + #define PyBuffer_FromReadWriteObject(object, offset, size) (PyErr_SetString(PyExc_NotImplementedError, \ + "old buffer interface is not available"), (PyObject *)NULL) + +#endif diff --git a/.venv/lib/python3.8/site-packages/zmq/utils/sixcerpt.py b/.venv/lib/python3.8/site-packages/zmq/utils/sixcerpt.py new file mode 100644 index 00000000..5492fd59 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/zmq/utils/sixcerpt.py @@ -0,0 +1,52 @@ +"""Excerpts of six.py""" + +# Copyright (C) 2010-2014 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. + +import sys + +# Useful for very coarse version differentiation. +PY2 = sys.version_info[0] == 2 +PY3 = sys.version_info[0] == 3 + +if PY3: + + def reraise(tp, value, tb=None): + 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 +""") diff --git a/.venv/lib/python3.8/site-packages/zmq/utils/strtypes.py b/.venv/lib/python3.8/site-packages/zmq/utils/strtypes.py new file mode 100644 index 00000000..548410dc --- /dev/null +++ b/.venv/lib/python3.8/site-packages/zmq/utils/strtypes.py @@ -0,0 +1,45 @@ +"""Declare basic string types unambiguously for various Python versions. + +Authors +------- +* MinRK +""" + +# Copyright (C) PyZMQ Developers +# Distributed under the terms of the Modified BSD License. + +import sys + +if sys.version_info[0] >= 3: + bytes = bytes + unicode = str + basestring = (bytes, unicode) +else: + unicode = unicode + bytes = str + basestring = basestring + +def cast_bytes(s, encoding='utf8', errors='strict'): + """cast unicode or bytes to bytes""" + if isinstance(s, bytes): + return s + elif isinstance(s, unicode): + return s.encode(encoding, errors) + else: + raise TypeError("Expected unicode or bytes, got %r" % s) + +def cast_unicode(s, encoding='utf8', errors='strict'): + """cast bytes or unicode to unicode""" + if isinstance(s, bytes): + return s.decode(encoding, errors) + elif isinstance(s, unicode): + return s + else: + raise TypeError("Expected unicode or bytes, got %r" % s) + +# give short 'b' alias for cast_bytes, so that we can use fake b('stuff') +# to simulate b'stuff' +b = asbytes = cast_bytes +u = cast_unicode + +__all__ = ['asbytes', 'bytes', 'unicode', 'basestring', 'b', 'u', 'cast_bytes', 'cast_unicode'] diff --git a/.venv/lib/python3.8/site-packages/zmq/utils/win32.py b/.venv/lib/python3.8/site-packages/zmq/utils/win32.py new file mode 100644 index 00000000..51cbd519 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/zmq/utils/win32.py @@ -0,0 +1,132 @@ +"""Win32 compatibility utilities.""" + +#----------------------------------------------------------------------------- +# Copyright (C) PyZMQ Developers +# Distributed under the terms of the Modified BSD License. +#----------------------------------------------------------------------------- + +import os + +# No-op implementation for other platforms. +class _allow_interrupt(object): + """Utility for fixing CTRL-C events on Windows. + + On Windows, the Python interpreter intercepts CTRL-C events in order to + translate them into ``KeyboardInterrupt`` exceptions. It (presumably) + does this by setting a flag in its "console control handler" and + checking it later at a convenient location in the interpreter. + + However, when the Python interpreter is blocked waiting for the ZMQ + poll operation to complete, it must wait for ZMQ's ``select()`` + operation to complete before translating the CTRL-C event into the + ``KeyboardInterrupt`` exception. + + The only way to fix this seems to be to add our own "console control + handler" and perform some application-defined operation that will + unblock the ZMQ polling operation in order to force ZMQ to pass control + back to the Python interpreter. + + This context manager performs all that Windows-y stuff, providing you + with a hook that is called when a CTRL-C event is intercepted. This + hook allows you to unblock your ZMQ poll operation immediately, which + will then result in the expected ``KeyboardInterrupt`` exception. + + Without this context manager, your ZMQ-based application will not + respond normally to CTRL-C events on Windows. If a CTRL-C event occurs + while blocked on ZMQ socket polling, the translation to a + ``KeyboardInterrupt`` exception will be delayed until the I/O completes + and control returns to the Python interpreter (this may never happen if + you use an infinite timeout). + + A no-op implementation is provided on non-Win32 systems to avoid the + application from having to conditionally use it. + + Example usage: + + .. sourcecode:: python + + def stop_my_application(): + # ... + + with allow_interrupt(stop_my_application): + # main polling loop. + + In a typical ZMQ application, you would use the "self pipe trick" to + send message to a ``PAIR`` socket in order to interrupt your blocking + socket polling operation. + + In a Tornado event loop, you can use the ``IOLoop.stop`` method to + unblock your I/O loop. + """ + + def __init__(self, action=None): + """Translate ``action`` into a CTRL-C handler. + + ``action`` is a callable that takes no arguments and returns no + value (returned value is ignored). It must *NEVER* raise an + exception. + + If unspecified, a no-op will be used. + """ + self._init_action(action) + + def _init_action(self, action): + pass + + def __enter__(self): + return self + + def __exit__(self, *args): + return + +if os.name == 'nt': + from ctypes import WINFUNCTYPE, windll + from ctypes.wintypes import BOOL, DWORD + + kernel32 = windll.LoadLibrary('kernel32') + + # + PHANDLER_ROUTINE = WINFUNCTYPE(BOOL, DWORD) + SetConsoleCtrlHandler = kernel32.SetConsoleCtrlHandler + SetConsoleCtrlHandler.argtypes = (PHANDLER_ROUTINE, BOOL) + SetConsoleCtrlHandler.restype = BOOL + + class allow_interrupt(_allow_interrupt): + __doc__ = _allow_interrupt.__doc__ + + def _init_action(self, action): + if action is None: + action = lambda: None + self.action = action + @PHANDLER_ROUTINE + def handle(event): + if event == 0: # CTRL_C_EVENT + action() + # Typical C implementations would return 1 to indicate that + # the event was processed and other control handlers in the + # stack should not be executed. However, that would + # prevent the Python interpreter's handler from translating + # CTRL-C to a `KeyboardInterrupt` exception, so we pretend + # that we didn't handle it. + return 0 + self.handle = handle + + def __enter__(self): + """Install the custom CTRL-C handler.""" + result = SetConsoleCtrlHandler(self.handle, 1) + if result == 0: + # Have standard library automatically call `GetLastError()` and + # `FormatMessage()` into a nice exception object :-) + raise WindowsError() + + def __exit__(self, *args): + """Remove the custom CTRL-C handler.""" + result = SetConsoleCtrlHandler(self.handle, 0) + if result == 0: + # Have standard library automatically call `GetLastError()` and + # `FormatMessage()` into a nice exception object :-) + raise WindowsError() +else: + class allow_interrupt(_allow_interrupt): + __doc__ = _allow_interrupt.__doc__ + pass diff --git a/.venv/lib/python3.8/site-packages/zmq/utils/z85.py b/.venv/lib/python3.8/site-packages/zmq/utils/z85.py new file mode 100644 index 00000000..86a924d6 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/zmq/utils/z85.py @@ -0,0 +1,62 @@ +"""Python implementation of Z85 85-bit encoding + +Z85 encoding is a plaintext encoding for a bytestring interpreted as 32bit integers. +Since the chunks are 32bit, a bytestring must be a multiple of 4 bytes. +See ZMQ RFC 32 for details. + + +""" + +# Copyright (C) PyZMQ Developers +# Distributed under the terms of the Modified BSD License. + +import sys +import struct + +PY3 = sys.version_info[0] >= 3 +# Z85CHARS is the base 85 symbol table +Z85CHARS = b"0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ.-:+=^!/*?&<>()[]{}@%$#" +# Z85MAP maps integers in [0,84] to the appropriate character in Z85CHARS +Z85MAP = dict([(c, idx) for idx, c in enumerate(Z85CHARS)]) + +_85s = [ 85**i for i in range(5) ][::-1] + +def encode(rawbytes): + """encode raw bytes into Z85""" + # Accepts only byte arrays bounded to 4 bytes + if len(rawbytes) % 4: + raise ValueError("length must be multiple of 4, not %i" % len(rawbytes)) + + nvalues = len(rawbytes) / 4 + + values = struct.unpack('>%dI' % nvalues, rawbytes) + encoded = [] + for v in values: + for offset in _85s: + encoded.append(Z85CHARS[(v // offset) % 85]) + + # In Python 3, encoded is a list of integers (obviously?!) + if PY3: + return bytes(encoded) + else: + return b''.join(encoded) + +def decode(z85bytes): + """decode Z85 bytes to raw bytes, accepts ASCII string""" + if PY3 and isinstance(z85bytes, str): + try: + z85bytes = z85bytes.encode('ascii') + except UnicodeEncodeError: + raise ValueError('string argument should contain only ASCII characters') + + if len(z85bytes) % 5: + raise ValueError("Z85 length must be multiple of 5, not %i" % len(z85bytes)) + + nvalues = len(z85bytes) / 5 + values = [] + for i in range(0, len(z85bytes), 5): + value = 0 + for j, offset in enumerate(_85s): + value += Z85MAP[z85bytes[i+j]] * offset + values.append(value) + return struct.pack('>%dI' % nvalues, *values) diff --git a/.venv/lib/python3.8/site-packages/zmq/utils/zmq_compat.h b/.venv/lib/python3.8/site-packages/zmq/utils/zmq_compat.h new file mode 100644 index 00000000..ed105152 --- /dev/null +++ b/.venv/lib/python3.8/site-packages/zmq/utils/zmq_compat.h @@ -0,0 +1,113 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2010 Brian Granger, Min Ragan-Kelley +// +// Distributed under the terms of the New BSD License. The full license is in +// the file COPYING.BSD, distributed as part of this software. +//----------------------------------------------------------------------------- + +#if defined(_MSC_VER) +#define pyzmq_int64_t __int64 +#define pyzmq_uint32_t unsigned __int32 +#else +#include +#define pyzmq_int64_t int64_t +#define pyzmq_uint32_t uint32_t +#endif + + +#include "zmq.h" +// version compatibility for constants: +#include "zmq_constants.h" + +#define _missing (-1) + +#if (ZMQ_VERSION >= 40303) + // libzmq >= 4.3.3 defines zmq_fd_t for us + #define ZMQ_FD_T zmq_fd_t +#else + #ifdef _WIN32 + #if defined(_MSC_VER) && _MSC_VER <= 1400 + #define ZMQ_FD_T UINT_PTR + #else + #define ZMQ_FD_T SOCKET + #endif + #else + #define ZMQ_FD_T int + #endif +#endif + +#if (ZMQ_VERSION >= 40200) + // Nothing to remove +#else + #define zmq_curve_public(z85_public_key, z85_secret_key) _missing +#endif + +// use unambiguous aliases for zmq_send/recv functions + +#if ZMQ_VERSION_MAJOR >= 4 +// nothing to remove + #if ZMQ_VERSION_MAJOR == 4 && ZMQ_VERSION_MINOR == 0 + // zmq 4.1 deprecates zmq_utils.h + // we only get zmq_curve_keypair from it + #include "zmq_utils.h" + #endif +#else + #define zmq_curve_keypair(z85_public_key, z85_secret_key) _missing +#endif + +// libzmq 4.2 draft API +#ifdef ZMQ_BUILD_DRAFT_API + #if ZMQ_VERSION >= 40200 + #define PYZMQ_DRAFT_42 + #endif +#endif +#ifndef PYZMQ_DRAFT_42 + #define zmq_join(s, group) _missing + #define zmq_leave(s, group) _missing + #define zmq_msg_set_routing_id(msg, routing_id) _missing + #define zmq_msg_routing_id(msg) 0 + #define zmq_msg_set_group(msg, group) _missing + #define zmq_msg_group(msg) NULL +#endif + +#if ZMQ_VERSION >= 40100 +// nothing to remove +#else + #define zmq_msg_gets(msg, prop) _missing + #define zmq_has(capability) _missing + #define zmq_proxy_steerable(in, out, mon, ctrl) _missing +#endif + +#if ZMQ_VERSION_MAJOR >= 3 + #define zmq_sendbuf zmq_send + #define zmq_recvbuf zmq_recv + + // 3.x deprecations - these symbols haven't been removed, + // but let's protect against their planned removal + #define zmq_device(device_type, isocket, osocket) _missing + #define zmq_init(io_threads) ((void*)NULL) + #define zmq_term zmq_ctx_destroy +#else + #define zmq_ctx_set(ctx, opt, val) _missing + #define zmq_ctx_get(ctx, opt) _missing + #define zmq_ctx_destroy zmq_term + #define zmq_ctx_new() ((void*)NULL) + + #define zmq_proxy(a,b,c) _missing + + #define zmq_disconnect(s, addr) _missing + #define zmq_unbind(s, addr) _missing + + #define zmq_msg_more(msg) _missing + #define zmq_msg_get(msg, opt) _missing + #define zmq_msg_set(msg, opt, val) _missing + #define zmq_msg_send(msg, s, flags) zmq_send(s, msg, flags) + #define zmq_msg_recv(msg, s, flags) zmq_recv(s, msg, flags) + + #define zmq_sendbuf(s, buf, len, flags) _missing + #define zmq_recvbuf(s, buf, len, flags) _missing + + #define zmq_socket_monitor(s, addr, flags) _missing + +#endif + diff --git a/.venv/lib/python3.8/site-packages/zmq/utils/zmq_constants.h b/.venv/lib/python3.8/site-packages/zmq/utils/zmq_constants.h new file mode 100644 index 00000000..dc89945b --- /dev/null +++ b/.venv/lib/python3.8/site-packages/zmq/utils/zmq_constants.h @@ -0,0 +1,893 @@ +#ifndef _PYZMQ_CONSTANT_DEFS +#define _PYZMQ_CONSTANT_DEFS + +#ifdef ZMQ_BUILD_DRAFT_API + #define PYZMQ_DRAFT_API 1 +#else + #define PYZMQ_DRAFT_API 0 +#endif + +#define _PYZMQ_UNDEFINED (-9999) +#ifndef ZMQ_VERSION + #define ZMQ_VERSION (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_VERSION_MAJOR + #define ZMQ_VERSION_MAJOR (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_VERSION_MINOR + #define ZMQ_VERSION_MINOR (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_VERSION_PATCH + #define ZMQ_VERSION_PATCH (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_NOBLOCK + #define ZMQ_NOBLOCK (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_DONTWAIT + #define ZMQ_DONTWAIT (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_POLLIN + #define ZMQ_POLLIN (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_POLLOUT + #define ZMQ_POLLOUT (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_POLLERR + #define ZMQ_POLLERR (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_POLLPRI + #define ZMQ_POLLPRI (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_SNDMORE + #define ZMQ_SNDMORE (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_STREAMER + #define ZMQ_STREAMER (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_FORWARDER + #define ZMQ_FORWARDER (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_QUEUE + #define ZMQ_QUEUE (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_IO_THREADS_DFLT + #define ZMQ_IO_THREADS_DFLT (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_MAX_SOCKETS_DFLT + #define ZMQ_MAX_SOCKETS_DFLT (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_POLLITEMS_DFLT + #define ZMQ_POLLITEMS_DFLT (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_THREAD_PRIORITY_DFLT + #define ZMQ_THREAD_PRIORITY_DFLT (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_THREAD_SCHED_POLICY_DFLT + #define ZMQ_THREAD_SCHED_POLICY_DFLT (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_PAIR + #define ZMQ_PAIR (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_PUB + #define ZMQ_PUB (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_SUB + #define ZMQ_SUB (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_REQ + #define ZMQ_REQ (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_REP + #define ZMQ_REP (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_DEALER + #define ZMQ_DEALER (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_ROUTER + #define ZMQ_ROUTER (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_XREQ + #define ZMQ_XREQ (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_XREP + #define ZMQ_XREP (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_PULL + #define ZMQ_PULL (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_PUSH + #define ZMQ_PUSH (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_XPUB + #define ZMQ_XPUB (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_XSUB + #define ZMQ_XSUB (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_UPSTREAM + #define ZMQ_UPSTREAM (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_DOWNSTREAM + #define ZMQ_DOWNSTREAM (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_STREAM + #define ZMQ_STREAM (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_SERVER + #define ZMQ_SERVER (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_CLIENT + #define ZMQ_CLIENT (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_RADIO + #define ZMQ_RADIO (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_DISH + #define ZMQ_DISH (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_GATHER + #define ZMQ_GATHER (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_SCATTER + #define ZMQ_SCATTER (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_DGRAM + #define ZMQ_DGRAM (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_EVENT_CONNECTED + #define ZMQ_EVENT_CONNECTED (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_EVENT_CONNECT_DELAYED + #define ZMQ_EVENT_CONNECT_DELAYED (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_EVENT_CONNECT_RETRIED + #define ZMQ_EVENT_CONNECT_RETRIED (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_EVENT_LISTENING + #define ZMQ_EVENT_LISTENING (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_EVENT_BIND_FAILED + #define ZMQ_EVENT_BIND_FAILED (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_EVENT_ACCEPTED + #define ZMQ_EVENT_ACCEPTED (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_EVENT_ACCEPT_FAILED + #define ZMQ_EVENT_ACCEPT_FAILED (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_EVENT_CLOSED + #define ZMQ_EVENT_CLOSED (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_EVENT_CLOSE_FAILED + #define ZMQ_EVENT_CLOSE_FAILED (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_EVENT_DISCONNECTED + #define ZMQ_EVENT_DISCONNECTED (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_EVENT_ALL + #define ZMQ_EVENT_ALL (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_EVENT_MONITOR_STOPPED + #define ZMQ_EVENT_MONITOR_STOPPED (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_EVENT_HANDSHAKE_FAILED_NO_DETAIL + #define ZMQ_EVENT_HANDSHAKE_FAILED_NO_DETAIL (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_EVENT_HANDSHAKE_SUCCEEDED + #define ZMQ_EVENT_HANDSHAKE_SUCCEEDED (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_EVENT_HANDSHAKE_FAILED_PROTOCOL + #define ZMQ_EVENT_HANDSHAKE_FAILED_PROTOCOL (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_EVENT_HANDSHAKE_FAILED_AUTH + #define ZMQ_EVENT_HANDSHAKE_FAILED_AUTH (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_PROTOCOL_ERROR_ZMTP_UNSPECIFIED + #define ZMQ_PROTOCOL_ERROR_ZMTP_UNSPECIFIED (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_PROTOCOL_ERROR_ZMTP_UNEXPECTED_COMMAND + #define ZMQ_PROTOCOL_ERROR_ZMTP_UNEXPECTED_COMMAND (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_PROTOCOL_ERROR_ZMTP_INVALID_SEQUENCE + #define ZMQ_PROTOCOL_ERROR_ZMTP_INVALID_SEQUENCE (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_PROTOCOL_ERROR_ZMTP_KEY_EXCHANGE + #define ZMQ_PROTOCOL_ERROR_ZMTP_KEY_EXCHANGE (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_UNSPECIFIED + #define ZMQ_PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_UNSPECIFIED (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_MESSAGE + #define ZMQ_PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_MESSAGE (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_HELLO + #define ZMQ_PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_HELLO (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_INITIATE + #define ZMQ_PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_INITIATE (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_ERROR + #define ZMQ_PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_ERROR (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_READY + #define ZMQ_PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_READY (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_WELCOME + #define ZMQ_PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_WELCOME (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_PROTOCOL_ERROR_ZMTP_INVALID_METADATA + #define ZMQ_PROTOCOL_ERROR_ZMTP_INVALID_METADATA (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_PROTOCOL_ERROR_ZMTP_CRYPTOGRAPHIC + #define ZMQ_PROTOCOL_ERROR_ZMTP_CRYPTOGRAPHIC (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_PROTOCOL_ERROR_ZMTP_MECHANISM_MISMATCH + #define ZMQ_PROTOCOL_ERROR_ZMTP_MECHANISM_MISMATCH (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_PROTOCOL_ERROR_ZAP_UNSPECIFIED + #define ZMQ_PROTOCOL_ERROR_ZAP_UNSPECIFIED (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_PROTOCOL_ERROR_ZAP_MALFORMED_REPLY + #define ZMQ_PROTOCOL_ERROR_ZAP_MALFORMED_REPLY (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_PROTOCOL_ERROR_ZAP_BAD_REQUEST_ID + #define ZMQ_PROTOCOL_ERROR_ZAP_BAD_REQUEST_ID (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_PROTOCOL_ERROR_ZAP_BAD_VERSION + #define ZMQ_PROTOCOL_ERROR_ZAP_BAD_VERSION (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_PROTOCOL_ERROR_ZAP_INVALID_STATUS_CODE + #define ZMQ_PROTOCOL_ERROR_ZAP_INVALID_STATUS_CODE (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_PROTOCOL_ERROR_ZAP_INVALID_METADATA + #define ZMQ_PROTOCOL_ERROR_ZAP_INVALID_METADATA (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_NOTIFY_CONNECT + #define ZMQ_NOTIFY_CONNECT (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_NOTIFY_DISCONNECT + #define ZMQ_NOTIFY_DISCONNECT (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_NULL + #define ZMQ_NULL (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_PLAIN + #define ZMQ_PLAIN (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_CURVE + #define ZMQ_CURVE (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_GSSAPI + #define ZMQ_GSSAPI (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_GSSAPI_NT_HOSTBASED + #define ZMQ_GSSAPI_NT_HOSTBASED (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_GSSAPI_NT_USER_NAME + #define ZMQ_GSSAPI_NT_USER_NAME (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_GSSAPI_NT_KRB5_PRINCIPAL + #define ZMQ_GSSAPI_NT_KRB5_PRINCIPAL (_PYZMQ_UNDEFINED) +#endif + +#ifndef EAGAIN + #define EAGAIN (_PYZMQ_UNDEFINED) +#endif + +#ifndef EINVAL + #define EINVAL (_PYZMQ_UNDEFINED) +#endif + +#ifndef EFAULT + #define EFAULT (_PYZMQ_UNDEFINED) +#endif + +#ifndef ENOMEM + #define ENOMEM (_PYZMQ_UNDEFINED) +#endif + +#ifndef ENODEV + #define ENODEV (_PYZMQ_UNDEFINED) +#endif + +#ifndef EMSGSIZE + #define EMSGSIZE (_PYZMQ_UNDEFINED) +#endif + +#ifndef EAFNOSUPPORT + #define EAFNOSUPPORT (_PYZMQ_UNDEFINED) +#endif + +#ifndef ENETUNREACH + #define ENETUNREACH (_PYZMQ_UNDEFINED) +#endif + +#ifndef ECONNABORTED + #define ECONNABORTED (_PYZMQ_UNDEFINED) +#endif + +#ifndef ECONNRESET + #define ECONNRESET (_PYZMQ_UNDEFINED) +#endif + +#ifndef ENOTCONN + #define ENOTCONN (_PYZMQ_UNDEFINED) +#endif + +#ifndef ETIMEDOUT + #define ETIMEDOUT (_PYZMQ_UNDEFINED) +#endif + +#ifndef EHOSTUNREACH + #define EHOSTUNREACH (_PYZMQ_UNDEFINED) +#endif + +#ifndef ENETRESET + #define ENETRESET (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_HAUSNUMERO + #define ZMQ_HAUSNUMERO (_PYZMQ_UNDEFINED) +#endif + +#ifndef ENOTSUP + #define ENOTSUP (_PYZMQ_UNDEFINED) +#endif + +#ifndef EPROTONOSUPPORT + #define EPROTONOSUPPORT (_PYZMQ_UNDEFINED) +#endif + +#ifndef ENOBUFS + #define ENOBUFS (_PYZMQ_UNDEFINED) +#endif + +#ifndef ENETDOWN + #define ENETDOWN (_PYZMQ_UNDEFINED) +#endif + +#ifndef EADDRINUSE + #define EADDRINUSE (_PYZMQ_UNDEFINED) +#endif + +#ifndef EADDRNOTAVAIL + #define EADDRNOTAVAIL (_PYZMQ_UNDEFINED) +#endif + +#ifndef ECONNREFUSED + #define ECONNREFUSED (_PYZMQ_UNDEFINED) +#endif + +#ifndef EINPROGRESS + #define EINPROGRESS (_PYZMQ_UNDEFINED) +#endif + +#ifndef ENOTSOCK + #define ENOTSOCK (_PYZMQ_UNDEFINED) +#endif + +#ifndef EFSM + #define EFSM (_PYZMQ_UNDEFINED) +#endif + +#ifndef ENOCOMPATPROTO + #define ENOCOMPATPROTO (_PYZMQ_UNDEFINED) +#endif + +#ifndef ETERM + #define ETERM (_PYZMQ_UNDEFINED) +#endif + +#ifndef EMTHREAD + #define EMTHREAD (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_IO_THREADS + #define ZMQ_IO_THREADS (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_MAX_SOCKETS + #define ZMQ_MAX_SOCKETS (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_SOCKET_LIMIT + #define ZMQ_SOCKET_LIMIT (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_THREAD_PRIORITY + #define ZMQ_THREAD_PRIORITY (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_THREAD_SCHED_POLICY + #define ZMQ_THREAD_SCHED_POLICY (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_BLOCKY + #define ZMQ_BLOCKY (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_MSG_T_SIZE + #define ZMQ_MSG_T_SIZE (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_THREAD_AFFINITY_CPU_ADD + #define ZMQ_THREAD_AFFINITY_CPU_ADD (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_THREAD_AFFINITY_CPU_REMOVE + #define ZMQ_THREAD_AFFINITY_CPU_REMOVE (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_THREAD_NAME_PREFIX + #define ZMQ_THREAD_NAME_PREFIX (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_IDENTITY + #define ZMQ_IDENTITY (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_SUBSCRIBE + #define ZMQ_SUBSCRIBE (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_UNSUBSCRIBE + #define ZMQ_UNSUBSCRIBE (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_LAST_ENDPOINT + #define ZMQ_LAST_ENDPOINT (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_TCP_ACCEPT_FILTER + #define ZMQ_TCP_ACCEPT_FILTER (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_PLAIN_USERNAME + #define ZMQ_PLAIN_USERNAME (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_PLAIN_PASSWORD + #define ZMQ_PLAIN_PASSWORD (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_CURVE_PUBLICKEY + #define ZMQ_CURVE_PUBLICKEY (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_CURVE_SECRETKEY + #define ZMQ_CURVE_SECRETKEY (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_CURVE_SERVERKEY + #define ZMQ_CURVE_SERVERKEY (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_ZAP_DOMAIN + #define ZMQ_ZAP_DOMAIN (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_CONNECT_RID + #define ZMQ_CONNECT_RID (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_GSSAPI_PRINCIPAL + #define ZMQ_GSSAPI_PRINCIPAL (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_GSSAPI_SERVICE_PRINCIPAL + #define ZMQ_GSSAPI_SERVICE_PRINCIPAL (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_SOCKS_PROXY + #define ZMQ_SOCKS_PROXY (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_XPUB_WELCOME_MSG + #define ZMQ_XPUB_WELCOME_MSG (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_ROUTING_ID + #define ZMQ_ROUTING_ID (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_CONNECT_ROUTING_ID + #define ZMQ_CONNECT_ROUTING_ID (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_BINDTODEVICE + #define ZMQ_BINDTODEVICE (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_FD + #define ZMQ_FD (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_RECONNECT_IVL_MAX + #define ZMQ_RECONNECT_IVL_MAX (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_SNDTIMEO + #define ZMQ_SNDTIMEO (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_RCVTIMEO + #define ZMQ_RCVTIMEO (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_SNDHWM + #define ZMQ_SNDHWM (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_RCVHWM + #define ZMQ_RCVHWM (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_MULTICAST_HOPS + #define ZMQ_MULTICAST_HOPS (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_IPV4ONLY + #define ZMQ_IPV4ONLY (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_ROUTER_BEHAVIOR + #define ZMQ_ROUTER_BEHAVIOR (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_TCP_KEEPALIVE + #define ZMQ_TCP_KEEPALIVE (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_TCP_KEEPALIVE_CNT + #define ZMQ_TCP_KEEPALIVE_CNT (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_TCP_KEEPALIVE_IDLE + #define ZMQ_TCP_KEEPALIVE_IDLE (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_TCP_KEEPALIVE_INTVL + #define ZMQ_TCP_KEEPALIVE_INTVL (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_DELAY_ATTACH_ON_CONNECT + #define ZMQ_DELAY_ATTACH_ON_CONNECT (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_XPUB_VERBOSE + #define ZMQ_XPUB_VERBOSE (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_EVENTS + #define ZMQ_EVENTS (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_TYPE + #define ZMQ_TYPE (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_LINGER + #define ZMQ_LINGER (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_RECONNECT_IVL + #define ZMQ_RECONNECT_IVL (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_BACKLOG + #define ZMQ_BACKLOG (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_ROUTER_MANDATORY + #define ZMQ_ROUTER_MANDATORY (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_FAIL_UNROUTABLE + #define ZMQ_FAIL_UNROUTABLE (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_ROUTER_RAW + #define ZMQ_ROUTER_RAW (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_IMMEDIATE + #define ZMQ_IMMEDIATE (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_IPV6 + #define ZMQ_IPV6 (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_MECHANISM + #define ZMQ_MECHANISM (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_PLAIN_SERVER + #define ZMQ_PLAIN_SERVER (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_CURVE_SERVER + #define ZMQ_CURVE_SERVER (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_PROBE_ROUTER + #define ZMQ_PROBE_ROUTER (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_REQ_RELAXED + #define ZMQ_REQ_RELAXED (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_REQ_CORRELATE + #define ZMQ_REQ_CORRELATE (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_CONFLATE + #define ZMQ_CONFLATE (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_ROUTER_HANDOVER + #define ZMQ_ROUTER_HANDOVER (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_TOS + #define ZMQ_TOS (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_IPC_FILTER_PID + #define ZMQ_IPC_FILTER_PID (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_IPC_FILTER_UID + #define ZMQ_IPC_FILTER_UID (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_IPC_FILTER_GID + #define ZMQ_IPC_FILTER_GID (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_GSSAPI_SERVER + #define ZMQ_GSSAPI_SERVER (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_GSSAPI_PLAINTEXT + #define ZMQ_GSSAPI_PLAINTEXT (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_HANDSHAKE_IVL + #define ZMQ_HANDSHAKE_IVL (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_XPUB_NODROP + #define ZMQ_XPUB_NODROP (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_XPUB_MANUAL + #define ZMQ_XPUB_MANUAL (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_STREAM_NOTIFY + #define ZMQ_STREAM_NOTIFY (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_INVERT_MATCHING + #define ZMQ_INVERT_MATCHING (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_XPUB_VERBOSER + #define ZMQ_XPUB_VERBOSER (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_HEARTBEAT_IVL + #define ZMQ_HEARTBEAT_IVL (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_HEARTBEAT_TTL + #define ZMQ_HEARTBEAT_TTL (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_HEARTBEAT_TIMEOUT + #define ZMQ_HEARTBEAT_TIMEOUT (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_CONNECT_TIMEOUT + #define ZMQ_CONNECT_TIMEOUT (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_TCP_MAXRT + #define ZMQ_TCP_MAXRT (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_THREAD_SAFE + #define ZMQ_THREAD_SAFE (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_MULTICAST_MAXTPDU + #define ZMQ_MULTICAST_MAXTPDU (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_VMCI_CONNECT_TIMEOUT + #define ZMQ_VMCI_CONNECT_TIMEOUT (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_USE_FD + #define ZMQ_USE_FD (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_GSSAPI_PRINCIPAL_NAMETYPE + #define ZMQ_GSSAPI_PRINCIPAL_NAMETYPE (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_GSSAPI_SERVICE_PRINCIPAL_NAMETYPE + #define ZMQ_GSSAPI_SERVICE_PRINCIPAL_NAMETYPE (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_MULTICAST_LOOP + #define ZMQ_MULTICAST_LOOP (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_ROUTER_NOTIFY + #define ZMQ_ROUTER_NOTIFY (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_ZAP_ENFORCE_DOMAIN + #define ZMQ_ZAP_ENFORCE_DOMAIN (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_AFFINITY + #define ZMQ_AFFINITY (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_MAXMSGSIZE + #define ZMQ_MAXMSGSIZE (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_HWM + #define ZMQ_HWM (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_SWAP + #define ZMQ_SWAP (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_MCAST_LOOP + #define ZMQ_MCAST_LOOP (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_RECOVERY_IVL_MSEC + #define ZMQ_RECOVERY_IVL_MSEC (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_VMCI_BUFFER_SIZE + #define ZMQ_VMCI_BUFFER_SIZE (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_VMCI_BUFFER_MIN_SIZE + #define ZMQ_VMCI_BUFFER_MIN_SIZE (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_VMCI_BUFFER_MAX_SIZE + #define ZMQ_VMCI_BUFFER_MAX_SIZE (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_RATE + #define ZMQ_RATE (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_RECOVERY_IVL + #define ZMQ_RECOVERY_IVL (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_SNDBUF + #define ZMQ_SNDBUF (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_RCVBUF + #define ZMQ_RCVBUF (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_RCVMORE + #define ZMQ_RCVMORE (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_MORE + #define ZMQ_MORE (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_SRCFD + #define ZMQ_SRCFD (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_SHARED + #define ZMQ_SHARED (_PYZMQ_UNDEFINED) +#endif + + + +#endif // ifndef _PYZMQ_CONSTANT_DEFS diff --git a/.venv/lib64 b/.venv/lib64 new file mode 120000 index 00000000..7951405f --- /dev/null +++ b/.venv/lib64 @@ -0,0 +1 @@ +lib \ No newline at end of file diff --git a/.venv/pyvenv.cfg b/.venv/pyvenv.cfg new file mode 100644 index 00000000..5d5aef25 --- /dev/null +++ b/.venv/pyvenv.cfg @@ -0,0 +1,3 @@ +home = /usr/bin +include-system-site-packages = false +version = 3.8.6 diff --git a/.venv/share/jupyter/kernels/python3/kernel.json b/.venv/share/jupyter/kernels/python3/kernel.json new file mode 100644 index 00000000..4da9e0b0 --- /dev/null +++ b/.venv/share/jupyter/kernels/python3/kernel.json @@ -0,0 +1,11 @@ +{ + "argv": [ + "python", + "-m", + "ipykernel_launcher", + "-f", + "{connection_file}" + ], + "display_name": "Python 3", + "language": "python" +} \ No newline at end of file diff --git a/.venv/share/jupyter/kernels/python3/logo-32x32.png b/.venv/share/jupyter/kernels/python3/logo-32x32.png new file mode 100644 index 0000000000000000000000000000000000000000..be81330765764699553aa4fbaf0e9fc27c20c6d2 GIT binary patch literal 1084 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 JU6%?7001;H`=I~; literal 0 HcmV?d00001 diff --git a/.venv/share/python-wheels/CacheControl-0.12.6-py2.py3-none-any.whl b/.venv/share/python-wheels/CacheControl-0.12.6-py2.py3-none-any.whl new file mode 100644 index 0000000000000000000000000000000000000000..4924d956ad131cbe41250e2e7bdce3e42be2335e GIT binary patch literal 23290 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 literal 0 HcmV?d00001 diff --git a/.venv/share/python-wheels/appdirs-1.4.4-py2.py3-none-any.whl b/.venv/share/python-wheels/appdirs-1.4.4-py2.py3-none-any.whl new file mode 100644 index 0000000000000000000000000000000000000000..fab3a7b2758c2c31aa62a2454244e57f7fd43e43 GIT binary patch literal 14131 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 literal 0 HcmV?d00001 diff --git a/.venv/share/python-wheels/certifi-2020.4.5.1-py2.py3-none-any.whl b/.venv/share/python-wheels/certifi-2020.4.5.1-py2.py3-none-any.whl new file mode 100644 index 0000000000000000000000000000000000000000..c2220c20167c43c6e9d3a1b2f27ecaa53d1d13d1 GIT binary patch literal 161630 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 z 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 O_32A76`j5UkpBaaFa5>< literal 0 HcmV?d00001 diff --git a/.venv/share/python-wheels/chardet-3.0.4-py2.py3-none-any.whl b/.venv/share/python-wheels/chardet-3.0.4-py2.py3-none-any.whl new file mode 100644 index 0000000000000000000000000000000000000000..455eac3a3a287330fc94c76a95e77db8f7847452 GIT binary patch literal 136755 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ÜYiClVZUOm&-#XKk7xscQL*=T$EzXxl$j7K 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

    qbmEDpQ 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 E0P%w@F#rGn literal 0 HcmV?d00001 diff --git a/.venv/share/python-wheels/contextlib2-0.6.0-py2.py3-none-any.whl b/.venv/share/python-wheels/contextlib2-0.6.0-py2.py3-none-any.whl new file mode 100644 index 0000000000000000000000000000000000000000..6f611c17fc58f2dccb4a961d89b020df697ad5f7 GIT binary patch literal 12457 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 literal 0 HcmV?d00001 diff --git a/.venv/share/python-wheels/distlib-0.3.0-py2.py3-none-any.whl b/.venv/share/python-wheels/distlib-0.3.0-py2.py3-none-any.whl new file mode 100644 index 0000000000000000000000000000000000000000..43c7867224814e8c142404b19a9ebeaafd17c2a9 GIT binary patch literal 147296 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

    8zv7L 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 z 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 Z+zvgBpnLcIdIZ=$ZMLiE-b=sk{sQuGw7viU literal 0 HcmV?d00001 diff --git a/.venv/share/python-wheels/html5lib-1.0.1-py2.py3-none-any.whl b/.venv/share/python-wheels/html5lib-1.0.1-py2.py3-none-any.whl new file mode 100644 index 0000000000000000000000000000000000000000..a37d282b156463491f5f44cf073944e212a6c7b1 GIT binary patch literal 115285 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%0A8AySY5A)uULcQ!$ zP0EE8(Ci{qA+nf($9iu&aOI9P=6>MFBO)uQe=TOZmcG{qOZqH+8HD&kQZ@9gellQs zLomrT>G$iSIWj;%;Oz)%ueg%1+o2^zoXtYN2r*0v-lCV(KO`B6RL0G|1^U|bC=lkwX?%dJN5S1_i>$3D6 z!(a_-KJV$MM`p+PhM5MHu!suAcS5PU^RnHD<7FeVnCjiK;OiCUk(e#`89U}#o9yRz zxO{8B=nX1iA?RZsi>L|pjPBI$Qfd}453m4O5ryboV@wNllLKQG&x1pS?_*E)(5rle zUkkCP{XcG>ORU)V=f!*4c!~^jo(H5)US3ps7q?D}T0+m9fBOU^69j-9Q1@-gzI&tk z=X8b2wJ7T`&EyG-be|Ubw%y~H`3DhgN0MgA zn`Q(*JGh*D;T?fMu|(T~#%ljjnFcbEQP`-V0m0WhNYicicpG%d%Z)F`jtxw=Wk#U( zs$}^MV=ey*c%+@!^Eb<6xTwN0VB+4+p>lzfuF!8VSpyic(x1a&20$*(J)dp2w3=G! zdu!S$jONzM3+7wX)ZkVU9qjt8`ax(40BLSp!Y1<~LO3SydP?k+aJqh^cP{;+Z3Oo* zt%JSm{>u%us<`@2oq6*Vq)H`iq)!1aHw?aFE2>&O6Wynw{B9{<)7hoj^G@H$)PgrQ z^E{7o?w@;yfmun0rI)l;oG7C86|=um`!PAv^$8L2^wmky9-zTo@CEzdz4PClOMj?g zfPm(i|A&h8fA!AI|MU8n7F^-}8)Z&B=^HXn4?v}t{k0BwgN?JT-`)=^g~W|lV{KG2`&5rOuJzjVn=<4_IFtHskj<_<%y3L*hb=< zzC5H(Jg?ogSp1=U4csSWxbu>-V`)6)eDNi;&+bw;KCdO@mQe8Dq1?tmJpF0_4^PefRIwF(0pWS$L@1DXUEqrnjF4A)CLeIfmR zijq8x8cB#gl-$W<4^7c*?+kXyjiw!NM)Q@Z%t2CUvjQa9Tay)OR_L2@-h-uJ$>&m8 z5#Zhxk~nJ9=bOk!rSoL1gJ`PFC|ltqjpWtS-odRtMk|&N$ zqb63|$@T5AJg?f$XWG{TZAK{MT6Ri!U;GsLZ#wEJLTv+nFKGoDWsP}ag?4D-gso3v z^r0@~s!?e|k|Z|YjkPFBQtiz^3EJQF)iFelWUV7KT4#b;5cdmL8R=OZK~+Nmfe~4J zD_Tt;_*8=kTC_os4Fv3Up(D?uOW)q(17&}b8G%|5Ef-tloCo9En8mlPO(3jO-KhmeV7)7@E^-6q6}iK}&?L|`>h{^To}Rezo6dNnvCM+WLvT>dm>0Xq9wI9f zXU#f&H-+*whssS_>jWsN+UAymwUqZjF+b)UPNm2K%B!1`bg14%c;}Z_lYcwU!&{xK zgJbgx!w9#Bc0EO`QP~Ge>sxLHtzHl}v3fRhSK9w-kfgU9aC_8H^=@A}g*`?^gZ53V7P($fu~p57>z`*D{rO z<@t!{vDY3eNB9mp`YoN;{SJOdFp+kefvg@pe{fd2{a0@*159nXev8_2eZSNik4p3H z&6i@OB9RUggnS<~oM>{!BHrxmh*5RKX4m&)uEiquf2s#G=8_9rL5?`q&RQq`_A&0&wyOMj3Pmmm#bwHxS|iYNL|+6YKV8XwXyFY~ zejTDmy9cEbPUcweCrj8J{eOL(1yo(h(x`EVpusJ;yF+kyf;$9vcL);P-Q6Vw*We!9 z-Q6v?y)*aznM`<@yIHJ#V6Fa6?dsi9-PKja;50{GJIsOC;PT+a^#q#FP1drg?AKWhC)sh*&@33z`GgO<`4%-(sorA14 zJrJ~J>$}pi1r578l~}ndk|vGPSe+V(FpLq|2F?M`Yh83B(+^EJY8}^cpP0S-YB{Xj zh^0Bl^sKlV^C0WRMNF`jR+}x-fdH|MCKU9A#mj_Tamnl{*>|y>3o&VvlR)EYjlICR za3!UQ4bg^+osz?cUeiq7DDZAtd-VKkOCI6d3X(X{kB|+E+E4r;OnXQ80&+|O43(%{ zb9K2w8=~5Cngu1<dU^5|n#Vj>dxkrQ`%_2KBxIcy zEBe%Lv)mQQ>zr}+PAkN>#Ns17}# zb5resRoP9goO141vxw~6K~r+oa;w?g$hYNzh!=lu?qz=d#`$^{fA#73;>Sx-#|vnB zvr6Oh(RU@46++f>pV*7eVjEN4ZO9+}5b%#;2Hac=L(G(n zUBwRzJqsgRv9Ak#hk>+gKisVx6iR1ngI+eh_}NJ_Cbl3km=ELFdF_;0wFF0sWj7TY zvCf3D*8zm=+E2;TK;Np9K)&B>3C&zt<*E=|e)cte%Nhh(L!&LbAw~NzvuP!WTu0=V zv)8&_CgYce4aq|0)MQuEKawJ!4@+>k=a16 zFdts`q{WBl)~Rmx3GAaB4@VCd!N;qNj$&D5yyiIuM#f5i@=CfSBBYI>g)guv9XCM| zCXpok2u)NA^~9oO&Vp%^Xbw|P+oCPs3bnHWQ2Fohr)-ZBh1$L>*Sa%_o$~fVRlhsV zs=dx&cM-15^IyW3CB2@W)0ti+;rpidDGL$ulMQ|PBl_=?Of1=hdL4KmAWAkMAfnd} zn}4r7{b!P?W8q?H0hnpFU;`GQL@t`WdJ+N%OXAhobP)QLfRPs)A;cyLY|B*|-s?-3 zQ_r9lZ^k$|v^?IV&Z9dgO5Xb{L7Nc8Ualn1C(kRP3iHmosxVfSV|O+$ms>65G?5+$ zL|Pe})XbA@;bfq5Hj9-$ zGw%h-nN1?5gfeBr`rru4Id1k<&Kt6bP|QGWmRkNz9gVuc0EOkgM%1&)f+7$@XpRZ1 z2Agg*vzD{vYy~q(&)eCUF)HmutwDvmo0zR0%Z|_{^_X(XDo$flwVJYQl1#vvc)UET z%w6!ptYw%u3$>Z5#~>rjO%K)&il@ZJd>}nc?8E=qmS#eehAH|tH=SOf+8im&;v}TMMJ@gfFsND z(oj?%5LVMcJv4QmfOoXGGm&n$EZ`4S6opd@7>u{wC~!WCJK^3cT$AeL*lN^y#!|sO z66pHcv}@i*Ukc=QNzFSfHc9CdcwhK@JFR{i3<=7zJPqd5Yn z)wEbi$=fme9VBE1HF66p3}GFO4mo8P4eVpt3RZ>i=sWN|l&)2kEImY?X+EjolOXu) z%8$~`ky^g(rU4e}y^E1$6eenqsVtSHBKA~Qy{E#pKAmsN%Vb9thoTrq=eTsweVYyQkd7{&X2^{%hi?4Xu;=q?*c)6O=_p0 zRTFuP-)x|8q=`B76P>rApFuSAMk-A7*La|&FdS@-QO81@Q{UW<5{mZlWpX6PT8mR_ zC3}cw&?GG2gc4#(L2yFq+9@L^eP-ZmSk$G_&n2Yq)s}bW*4CBxiSQSv`Su=f&{pBi znkR2Pf5qY+=Z1fB#=Elqd|FZ}!kR2E#AdtRdns>NZ(+H;}!;RaRGUcs##a`gVd!Ei0>iU?S12$ZpD>*5Fgby*i z+yl6#hM@BZhc>g2lr*C%_P~`vZs~-Rxs^wpy@p#@$9>ij5%iNdxGfmRo>8iG<{LLTRE$%$=3CZ{`)3q$#kT57feBe8 zJL^J98!~>QDq}=7uv?y5rhV4iqt(CSuHdT>Tu?*L94Pr(h;kQn9vY&v^6>;;uVtEb zXI=w2dF0`wuh zOpMj=Ziq#fa^EC27Ue3d;*a!&P=t!NA09tG?-3s}rYumRrnUL!A_<|eHc}w43i;$X zcfM>ED#3J=CV zQI7Z2v7lbB^&^4SbM>uUPN^EDqLkdXojqoi&guhFI?A+@gUW(>D<$4@ z#l<-Tuw>7r3G2HoH=y9ncSvYN=!ij7R9MGxPM@^S)`oBG#D5X*__&Un=oMtVzQ}!TL1K$DAQ~{AD9Z{S z_vw=y?X%neqwXO!7FA{*cEz5=7^jxu(?&2pe*T zjbQQ*=%gP{Jqk)nb8#(g^1Pu$U7UI@fTf4v*etAPBlOP;Qed2ih$RBt@9N&M4q?r-rN^PBC>Ze+yrY1rRIw1MRc+zp~@Q$;St zNY$O*G=COsH{8$S2)SWS$dCgj;(G=b!kMB9;IQ0R;PL9wwZ;Vap4oM;%dpmDV?M$! zGV?9ttGq!ZB6vLGQ%h(TRP*%unB*lhA^L=+^W^zS2HA{v#3*FCrUNxDGl*DWjO-ky z_eG4H&VJ2wR6-6GGBtXumA;z7EibPqqAe3fWxPaP8L|7D-SZID5LlSX0#!czkk97} zSkD&XrnOJUnYMS!;wCp3ir;3`cvp-GI(7<7ed+ z7rVF5gOakT{gHIvxp2ZZ&ba0ZzLeU%SWA<;HR$YX5nHO`tT^x<+1n_`RdL{bvhjST ziS~UoMjOYen-%0oWKox73!BEMisSO-LkfYKA72~pF5C1P!nm@A0OxH@1NC6NtT`Z4 z=9yd7z~ekBa^}1?LZOwGmn^1gYTwQ?*5$#hxTG?s;2pcQZtc()T0}`#>(mzs>fI?g z-@9~VecJfk8p)o4&Rn@KWCqdmM9VU^W2~;q^;`o2Lemaj6a#JGT3l4t&JK`%T({D%v@G(`;?1&Jcd+Nv zW^i3pS>9;Lb^kUAhs8tW>}U^qWk2rwz@R;BdpEBf-uKYlQ!5-ELV*ckQ60be-gdPS ztv)fIX_Ccv4aL^lN^qRMOkka35G8buW2L>f3Y`u@MM`Fei*`V7+lPrTcs9s<5I&d2 zWFi~vq}+>d>xV33+al_`$Z|@6BO|D$BUiJ)y1ORgV{TK35mzQ|c1J2YD<2~}yS!rC zWrVg(0Yi9@*C}6;RtM)cUi0HFK}ve309<^p$b^f`$|tw0>*3&U{%mA{xgV%*yK@H~ zJe`%ch$Q%EL*Bh42(@pC+(&Z>x@&J~W3iHd+~o6#D}&`mOA>{>&=-#A@m_Ufh}^m8 zx$Pd2eB)+I;+#%i)#O_ROiANSoxBzkI?r&Yq9Ul~vRaO%s2l`MQS^DpkCJ-eaq|59 zyt-{j^sCrshm3|qfMZDc=p48Y*$~SYpd|bYS7r&bjoXQL43WK^hr(NZqXg|05;hX$ zWC^gGeZiSLaxv(KEGS%Yx*!zaN1r~FS{MgiX0CWh@jm|;EUYiwZ?103^c2%+{q*Vj zLXdLv{MdR`LmdXN#1umlv568jJ~zw5{u5F+PgbeKEF94Ts~B_T;6f37Y{tqhAf@syJQW@1 z2hbE3@8FJJu=s+$P{L^X%pqM`-{umo!fyF(xJ@?k+9X*(NbQypMw#Ly_eEog3gGfJ zE5HG@R8n691&EzZiDncPW4qKDbS2gBAK!gjU(=C5c8WQJn6(}DP^H{QoIt1C>OOEk z!rxW}<8B!|+vQ(ck9C7D}QG#aAG)i4|?s|EQG>&T4)WbcDSI zcq*p^WK?LOsg$v-36Be`BgXw&=Xd+;i_sEPGT<S914;Qe3n*9vI^s=ID}_pkYq8n-+nfWYw5m2Ob4YDM@MGzo` zKm#e|$n1<5R9D7rU?xCDMPZP%1-^=3k1_{~bOmu1)m+zBcpP?I`!eFEn@=#4riK6q zg^8!?wzkmN#diS-SU8T&T{)3QYY2%lA(r>)zlby5(oxY`_UuF?6mV8R)n1>$_kz?4 zj{ioc6Q7o)F~mv^p_hSK4lX%9Y#e0^2WD9b3a*}_3lS!9u5}7ytxoE*Q#UptKEN1> z(Lo@2NdVVHFlQFuVN^{c7i`VyjX)mG=M1H(+IqfPnDp$fH#SOvs?bfjo;syhSkRp` zN~Hz&T{VDE5j(XrWJ+-ndbR3ZEw&6HScj2cFn^b11HAJR>m76<;!fk+iGaiQ^je)Z zBL=)R)OU!abxT(sylm^WrHj$b~~L zZ&#RT6!n%mQV+J)`R90+(B9QD5q6+*_@l8mfD8ClVo}n)jj)U{%wX^4_O+3kc>F40 zvIS<>Wz)^*LfskS{yv$D*{$XBjNEZ_0;EMZh0fRQf#Y-V_fGIK#C!XMk@H1v6ooae zZ*G_7bkLSOiJzuC_8SQ|Sl81NwX{GV?aRZ+l;OeJTi{HG6m0oeg1hIck^~*14)_&( zxXC@wf}77b;!aIrNvyu0gcIhQq(y$Q$Xcw4&~6*}(qF+CQ#TtfqXF8*=jDXI z|CxPIU34Zq&TeB-pn6?H{^9o4W0qYRJEMM+FOkz$c-Ft*Z33RpwkzcsyH?=FwCR*f zI3~#?kx|z9^rbT}q*r$tspC0ze{_8-J`%CDWA=R5M6Qk6Ea_uJa!v((MW6ONG#iU5 zTVbPB@ge;@Zr>8O$H0&i)r9Fj*Al!695O2%3v8rfY6UPi@Rp({vq9QKk~R$~;4{no z6Ee!fqib(#stOiP(dqHe3Z>^Y)-@YLn9bT-`jgs^jE5PU#um-h%TaSZ*Vyrc9^{K% z^=W%YL?ZPuK*_?M^{|^l&31z;wPSBRVesF3sJ0)b-mtatA2sn_V7PO57BmSFL1WpL zl>}RdaOrg6Qp=jsG4_RS2H2gK#)dZ0)|Q8ObxK5O*Fl%JdXjE0e|FXjBl7QVJLH+9 z?wx6{yRqK-x_*K8y-|ujPQ7=`v%yKD95=Qsbd-W+zs7KU{K8UfwbQXM#svQ=r^2To z^hzt@sj-%MKVz&to#UEHGgLwlx|&*3R{aM<3zNtqXcQrAgl{3V$9V)@)^1+4Z|VAD zEHWe3nsh4y(CAjB`6Rf)RRL4Rv+*0AH;)7;cNvRAc-GMp*HBi~o|g$N^K7$dTw^V( zCmo&As+DaNmv4h?(XwDt(Gy4!K+JTsjzhb#)xwC_;4@Yv+c^{2eI^?K8TtZIc?9od zZXlD<4xA*3-+>i4!Mt{>d>f%$p4;4x$nox|0 zuSliVPN8%HJ#I@xl(F2j$kAK%q>#rV5mt-3{NdUiq=7SFmAn)Ns6q zHzZAw62Vj;3ddL0*kG8lP3Gm##IkYO`N27yhE*eiK{iKjo5IZ#P>NSFg9`=UZ*Q1@ ze}4SY#g~7Z@G9sBDx7S6HM^rMgCCx}^m|8lOb!Xz9!&X4Hm>OfM$7~4EaxwbDLif= zT~)4(sd}Aytk|U)Cs*7YhKKPXPo7Q%vKgn2uC|FGw}}Q)X5FV_uFnUQ!IFwx=GuRBq)H1nXrdh;Jc(AJzzI76i}%4sXo3e{gvFIjsHPv9M`O zz|J=74=tUJ;x`d0vvYXY@2G)8x-I=`WyTv0n+PgQgX`w|V+iHNtKYq}+Pg%HEg$89 z2kiHJOM3_p{6Q&MZ}46REvJ9ZL*~{g(a3kqFr(LB*PaDGI%xGGt#BX+75dF&(C|lE zRgul5OJ%XmLsmS|vr=d&U?Iz}KE0GJU($DMsnE++9-@K?k^Pq6bH#`1;I2i5$}_A? zLu=l$zWEg$)xf75vv^Q2g-o&oJsV1Rf`{h|mHY5EuLxqV3yT zOK|kEGiisTnA#?ewyi=A4%C!u^~RQiEDj2Y@FuMXNp?mkkBu7mE8&<_1oSWlm@L!? zIyQ_CTAzWSHD(s=+YPV2x3Eu|tg5Q1gE~M4Fm!cSkcgdf4u7D9?k72B& z!{8!{)HM6?;<~0ZznU%kX~mqlZN2YVmz^2wU|mirhWNliOQ$x<B+MMGXm$r? z8&YkFu~=8fpOqY|WiTYMmerROsj|Qc(t8zi(dX-#oa}nLFM=+RmhQV@Urmt`nJS3T@=QJI-MBX>1WCe$3M z1TX_SuD~3?OUt8~U0jw`Pinpe7Zt z^z9m&$}j9*nvZoVzy_ev?;4Y9X(Dry_NQ&r1m{;-++9I&tK-KiRQQKth?2Lqz&k46 zv6Okh?b5uf!L3oga&}d-#NT*7<*y>e**$t4lzDzt5VwlVVPl{i`lL_~Q-+xCC1~eS z0!&<`q}k;VD%uX11jl>;Uv!gD8ZV@%>(PevS@|HmsYk8UUPU6=Ns_Pu$CeR#MOns{Bi1S)~52rY~pT-7%US(!$6Zt+wfCu z7^veF$P(Ijmv3jB%wH-afIy;m(Go9?bDl_ci?Gam@=Q&MaD;%0z$HDWhKn<9uHsUwI5n^P^YvHNxj<`9SwPd;?` zraQ%=wQ$O4kklPE>CTIfuzF4zQ{^os%R_NX%6))V?$chSt-K!(ux8RQgEH#6Wb%F5ym;yF*A zQWMlq=ZMC{^W7h#)Ic1bYn4nYApCLBzO;MRE&Eh^Xf)`!#=w+VuER^Uql2i1dz2D{ zw-q{l^iW2%oZ07e56g8(MLdKmmt^d4F?beng=DKgzKm$=Wj!|RRiq#shk1HtVoD6J zpe0IUD)tyOr#{NsTvoLN963OIF4yTO(aDoRI&jLYa^p*6 z7xpHhV0^QvYXCx&ZuxEsR_uE?!;iMph#b`UgbM}Tc2+`f!;6!~UA&d(u*8xfwHRvi z4^(2vq!%TM0p}W8-xv5MJR(&|Sp`C?f>gDFYK91+JH0m)+*e}gCln;a;8XVAZb=ws z5pbaupD#s$7?<~Wniqs4_fRq{!l+j?q&IJ4Ey<-#iS#3I(^ac?V#-Pv*PV1-!s(E} zDBI{%Qb2@GGJgI1x&4Jo_3`d%NBWi}X!Wz#o~t&5WE}`oDwTJp8DX?JeQcDVp2;5f z*A%)mJD5nG09k9ibI~t1ma^ZMTJ-~(ttwNYJ<6GQ!=hV_(?1N<8W~(*Cp!0seGZ}< z+`yVpH?8yuY&=VI zxG*5apU+o6AY?*WcGLowi!c@!W-Sq2slG{>^L1O)3Z|l<0_zcEQ1~It+{g@U{3w*( zTv9h!_=6XJ8v-p2tRH_wiCtzSt_I011;SSVc() z<`_!tGbu(nn-F8?%q8PvWMO5Mh2jc}bz0faOQwOxRp4wRi?rY;e0^oCor2SD9*RHpsQ5>_~4VD^?jlSt;$dEjo1<%@`EvW%7Qnf5ypf} zs4sXk)`_ioW`V~M0^+D~+bGfZ2<%)C?CADRU`DKf^&?8D;4k%b!tyD)!?itDHGKM1 zyf_3qa(hG~oWxRy2tXS(rm;LNoOf6HP8_o3U(0vm9NBD~p3YHP;KbJ^tg+gzg0A&_ zjzm*sl3&)*7DirfxgW+qVZ|Q3+l{0`hKHFgkiLWPQd*UW&e$|UyArul#_l)$LE+og zyg{xs_+#s!lk}zCfwzAwXA=U(MdoOl<2=YI0!Qle`{wzs9Jg?6xMS}W`a>MX11Af3 zZQZX%IcsK%mXZ&x9BlhoR6FasA;)7x>v9a{j0%0+kXq+)oHI_Twc#oyWmLG|iip&S z!LoTQ#`+y_E#DM^Mpqg$WBrJ@2S$)wnjly2X4RajQDLH}F=Zxzvc=xCd?)%$l-kh{ z2IYqvltmopVM{~@dX6x#XB(~g7c?Pv0V?W}R(HOI;c5;qT z8~u(nyP_n(A;jT$!d${xA`Lo!cmT_qXVpOrPBEG0C1|;W)vm7$j~6jO$sLPWKRhlp zb>~=j*Yg=^bL&0%qn;Vm@thhzK2N2{gb4;barj(~#fW7dFpktvDNINilNUr}j|S?Y zWn{nZ*T`90og%+Mh=L!X?I_u*PoW1UQI#Jj2&9+I;Anq*GGxfO-czAjCU=cy0r{5F z)O%YeKsvfEAR>9)LAf`CE*hH}gw6m^ZDpbA_Fyb=Q{9udc=1wbcm8fs z#A~FpRdXPkI8!YmoTp^`T2@IJwB8?`c;h+K-3#wT!NeN>2_}59igqD8${>Rqmkq1E z@+F{-{Q=pP2TH9#bHabv{L|-#iZ+w6aI3Y#aNX0wkg*5s-;LAW?3N~7z?y3^1`rV7 zK-RCU4u82?|JFDDbcxwk)c|yms9rZ;32+?Z>4ihwHs~?nX65Asg0f=mgvmM)%mi$Mf2iuoh}06R#>(qEU@OZ2c;c4W%{6_!UiZ z=qAYEFLy@F}(k3 zo?$H2ulm&i(IFM8&M>f~BWN+6C7#A=sYU8GqO<(L0}yP;LQs|PoLM25FJP7l1izIq z#zq|PyKgevEfQRW)?VU0?jS$Hh?fh8&p1$oDw(RK^|f+p4U)<%BF=_=+RdAG;WEWYjK(jdN?jVCo#4Be!4Zd)&L7ND0!H~b{KBY zPI&NcKnL*6AFSQ`mhy*8%jyObd&oZc=Q1$&9YY#FM87ujX#!yCsLBvXd#oO8k|N}c zg);9W-|!`j-Z;=?TB--|@0U&;5*Y34d+Dsk?<;f3)GQw|_zb26YXY){RP7tIMna5A zE02^Cmo0tMByCV`_(X;1?};Xat%OpF{0Q)-yk(&0_A<1Pzyx#FGn>cOyUcEmLL44^ z#cm$Ira7eO-AJ`0mMi0?-}qWp9_{A@e=5MVoDR&J&#&}$N=GK z$QKJD6PyPg+(>hscYgF=C4c9WUs)E8fa8(#W9!cx76V$`Jg^|y!Nq=XEnt`a z8N|*xGDxRu3=(4LFuonW3ouY-CW`yscZx1)iL% zw_Y`Q7C9?e&*;)Ym1~TgJOg@iyR!v(+CR9zF!N^!OPmk!xY;}s(ihA-ZD@56yq$4R zKvIff0hJ+SX400kB_1}M8DIPme?kCzj}NT>M2RskRG+OuxYn=k;1S%j7lkIxfEN9R z2;Ev(O~p>mxL4E`F#uHZfuZ3&(XwU$duQ*RTp=JdLGa*gX7{7xJ2MN@MT46jJl{=F!p z+lyR4u-x;*&aEgkG-a}&^WFSD&u5@g;QP@R6yFujiDNA`pbI8fe_`jOaOuT{U4fM6 zol`97@IEu9ah@g4w%kz{vQt{}%X!3-`k^`)xe7l$ar==frZs*>cM>wcLFeHo=HrNcTkDd_p*HxtC^con(WR3VjizSNA}`sypur z*ttt7$fS4M5vI6i&Wx3aqlo3}bmG=uL;CjdF?leruW=ZcF6{~a_wflu#}ct05M&b^ z`VR+#evVIn2YroK>HwH~a4ox3b0_r1h`z_11cB58dhIbzr9O`2FoL!FiWSu032EgR z*QY3!WC`Z((vFoR(UBfov2kxX1IZ;MHQr(f6I`^=QlCNQ8k#bc?7|`2B8r&wWGTLz zffi9vrEXx36_>!^QrwXr($`u;+ImRXWp8pvq4oLVsH(mYpYU5-A;;x|3b z_~>}-)p=!k`^nqH{ezz3s+(b>`sYx$%Da~5@4BwF^JVpVvByVH7wzzPvp7wR2~_40 z&5$%PwcR+&SfJZ`Nj#C`wi(?q*r0kox3Pn8q25tO#~$~tAXdalO&1EqIpp-@lSb*i zT(=4Z6mNC$ku@`DXl|JYu+3hyQ~H`(w~tA5p#pW>sVz=niWv@0sQ%Tz*vCfq`_toQ;5t-d%^(d z(v@b$N^{T|uA$c7C94xr%s3NlZzg?S>L5unI}o%4+`R2w6< zvRC01y5E<=0|j=S5`bAAY#COe_nY$e|<7>u(V*YFx97Fprxl}pfxbH zcc3w~GP0)QS5g#{Rro;b;NtL_cqnx>pxNdQIp z`GJ7YeijGZ^L&_Ce@R8BV``%3VEA9(_SXncZw+2WfT}OOfPetjz~5J%PpHIi2rC;$ z2YY~hp!ZjZhSwCAM7qzlfN;ndRKWj96ZaF7=YwYUPl|)JxuMnnC5?N{IGz0ZrT|co z5U|LH^%DTN=lMJb{Kl{|HT+*nF$r5$@&Pb%K!Jb&Z|2`up3hR?|IhiqEx6ah)CG@& zX8<4(fV%lzEiu9WAH+b<0U*;K)S{_JPl^ht;Z1<8^?MB)h5mmO8`nP&ioK#hApxax z-v9w2|NSU`DWxp@p9Dt-Qw#e)l%IhOIQ<|71oU16_|+S-8T*g&AFZwI9rUamen$Wd zL_jz6k8k}?#Ot4b=lPf}{R3fSYVkT!{%fUrSAZdQ0+gBvs2R$i7{EQxC-+YzJqsHX zJ$*w5(~o)pMCa{x0EvJIZ(758d$q4jzF0du4rD`GbW2QstNJyy$NMlKBAI zIoWU0xvc(yVrpe(_|ZYf($GOq=c9=pz-`~*5Bk@5&!c4sfYJd%g#Iqt0!@nl`bhnhF3-nm=MNNX8wXQsD?JMbJ>x&AYgmMnX&>Nie{`$xdLdt70^t6?_z7gfdB6P>3+T&&L*aS8nn^-_@~AaN2(_Q zDg*>nI0pQx-R?mAgY};=#pW-4+xF1WfYu4*?WWQKz z!T*!>a|!J=@U`RPFQ9kgE8tI)=YQz`wZF+PnhIbX`#BM#`{x4Rzo`H9M%yn^QU1S> z{;d7iJ21aMbA|r``ZwjjUaa%IF?kr6BRR*(h-Lj?f=`2ms!-mXAA>l=uU1Omc_2Lkf-0SsN#l+omUI|?e?v9dz+_$tMGL(j@TtSMcF5@DO}7s+ zR;{CI#~U55ASpIKCdecgjHMKq5;~>X`@tcBNKpA_1KfDZ2kbcE2wl^7`p;f0lHy?5 zgxlLL{wP1-!a7?$+q;U)*XL4-b++;1MB&(4$)j^VD!qbg_1LCqq42@dfyw*z9JpuG z)RN63g9f}gxo{}Eqw>0cM%VK#Bx`MD0oY;ZlLgz>&r7Y^@{b{G>wER%dKN}3xnOj# z0@xfkAeJcs$GxXf$B>haV{CzHD67Glx8BbAWR38uO?NKk!qv?>R!%9MtUN86n44w@ zwUN0@tAQUUOgA{0#t%!WT*l6s@s}5XF9F_95Nd(!|zzdqunqruDWfLfM7O;X}?6p_xup3J+$GFelPq~m~3?k~xwOMyfN-{m9s1YXzU%V5> z=V_E_yYZZFBi{r0^P96l)RgxF1MuTxWCmk<@ZQQZlJ@th|S^UxP8b+aKjn*P7sZ%j`izq@bUz6~=1N%2ARAR?zmsfnB}{eVW#91=93ZFl)J)BiiFd`L zjcMcF#LB*~=dd=2dhA$xN++eKzypLYS;%9^>DJqSu9^$gsbbUvPtT%Qg9+pITeJKU z=y|OOv7T;c(Ll9JE4b`UdLa(5*Y{P8#lM4GZgeV>4{&flvQ^Ljof#NR5DZ7Hq?U+Y zT?Tg6ZtEY7?x7~4*uCI=qHtXYq9bJ9tYkf<21X0FIhC(EBk&z`0EeecZij56?q6~? zGN$-GbL50BBW9M~{In%Ah8ij?fAV%8-pBV9&~BvFj*p$>+|YL^6c1RFZX8SAb(Uza zwOiZhh_`C3ho52nfy8qvGzTO11c96Pw*E;{C^PyOOWq76tD+WovdA(J zw23^32%Pl;^g$EbkHtX z^b7MV0JBmVC~V7bcEM=UylItiicT6{3sGz*snmD{?;5H0_l$A&7g0=frUpw?&$S|J+^;E-Q398&Tg7-1+2AeBm%flvQNt}c+-fi zV7*MpT2ls-g7?c;P-fDIR#W(}pJbOT;Q4o3I}!38Of>rKM!i1sn}qs#D9?=SdaOsN zU5q$U_A`&==jQUM)C4g58nFENhQk%X(KTMhMWIwaVQz*nheze41Dr=bZ?j!dM~L#*5$6vITD0_{ z%Dy&R)-Gx%IR$faNu_ zt%~SPwb+J=?fSkSmRNp!l zsI#f)JWh2R0t|E6RpYQa7dBw_HHyE}rwmmt_r=@F-oFJtm(X)7qwd0Wu?Pfr zh#5d?UEQZFs)wIm19`3puBO5-zZL=oN}uYx(TD6aRAZZDu31e<7=Q?}|! zW3kJ?=no`;MPJZfpkwv~TOm;?29=Jo7r29dbNxJIS`$poY@-r<$Y?1x7Y-Ir=yIaY z=DJJz<)fRrGW8SXd*NZ|z|ZOnGBXsnXyS+}ka{xD-aDYYujJL|=_SI0iuv|_U0Zx7 z?OGQD&wY&?Oe3 z)Fo3_9i{saUo=;53s-xFG^=O6%Dg82H}KucYwxeB0Avpa_V1y_+4b@mKoYvbMU|)X zWr=K6)$$GsWfDoYMJhR6E1RseS%C=mq0dX8N5Fo^=Z@pqMnj-=m9!Q1qN@k(u_Ii0 zDbaJ!rA>xpZ-L_Z-|%rVff}{tDyc-k1QA~kD1a~lk%2H-eH`Zn!N$UA$60>GgQ0H( zK?0-4n)aA}OtWA{-$GIou{c)b*VB~b@=?N2b#Q!v@ldRkE>;7?Y_+n*Mz4sVuORA6 ziGTK*R4tLZK*Z@BnMkf}0Ots0bp;2!+CA9#;_KmM3tC2y#6p43EFC5x%KT3N2FG5k z*mVQ-rw9OaDY;8r2ker2&|FB6EO!xvd!`3$q25N-3aLp`6x;BgwU<@JIM;Sd86?Q3 zJ3*!UTN+4C=`VClEk-9?X?@kG^GA}MSppvG7_y24c%fyC{Wvu|RQ>q0;$wu9&Vfq? zq_xyXMtgJ-ZYIl{8&ey5Ue-*% zXJo@%M(dtiZL!;i*-BfgVp}7*jXzoj=go|>FiaeK6s$(*ekOYX<5iV$a~64?TvD&g z*q!Rl)0?$>hx`SsW_1ULmmS~vZbY)Q#C*LnoenlkkK%Fq{V!mqw$y2bCZ|yrr5$!& zggQlbKPazeT#u>p8BsyZhT?LmalcNP;u{kKJBMA7V*VIMhZ3$4ic!pRII^bD(PO%v51q>4R$+x1uY=f~q_pqQFjgcRaMH28Hz zUA&geSRH=7$pW6Wc8m!2B2+K$Hx0!TDLmK+m}9MTW4v~InIe`!Zd2}WBXNnFoPapf zE^I{bEVs}@c<1H*19}6gvQ;!~R=tciR<>ER=Hyz-Qx&WxUP>CCj}qQk`Xp_~Yz*U~ zu7XwOx(9r?IT$RJEw=U;p`qnCp3LbWL4O~4wMp%#HEj;%Vjc15)MAaqgVX8-9X|sq z<}IGRoW<)E;mJoJE+3McmibZ3v1Rezo1~XBn)(JDJ(a5Z_>s$k-Mt)>C39J4Io$hF zWJ=*0`;1eA1Y7!8eKX0lIf^OjrPEa#{=WOl>^Ct@kMcWt{VIlCVld?q#Z-MJ>rt3$ z!r$D2YUGdwbyJxIa3qBZUCj*6m6Sn;m%QKP$oY5}d3;?}Fgn3v*@_;kJ$g(8cQ8jS zWb5nrgp9DFk~&(hhN9*IjN^kO$1GU%m!~(C1w`79V#wMYi1B3pLg?6S+Xsb0 zbk{f>v=|&)@>qG?CkKI`E)@(y%xH|fsli0xhVr5W{L)}lmk&G*yjn83lXogrNxuuo ztJ{TBl*rn!9>PZzPK*XfBz7hb-wo@CU78^Gp$D1|-8tL^oOYNCx=|UmPRzq}hkkzF zh%_;;Ev?Ks&%wTjOUy|m+SR2x&q#%bVRCOg{>fsC<6<^D-r_93i|!%iIf5yB;as15 zq;$4c{^%*~YQUFU{cKox5jBblV?-`&y8aXaSM zX((6hxa$_9h5!USOHJ+kl>G+LSTf;>WWvCaC5N-1>0_Zz?eLZ(e6A~_dt?gn8v6+o zk31LU(8BX@;YrSNt~IU%poSgm-3JIdz#E1!xsS(Xw2X{u4jRf@j%c>f4(!bz2glNI zjwLE4nWks48QaNVIgs*v-oE;(JO)N0I`NJ5GbfE)jeab~=QTCh1=KA}qNN`TA{>F* zpkO55V!d=*1$RQE8A-6P-l(p~^V=FjQ7Ze#kPj?wKizAEq+Fo%D`CMn>03zs9t%!# z=?dyfls?>JzyvqtVu%D^h4nj8I!dqLeDBRoR^1)q2NiMo{{2S0CnuRjy6M?`-u^=A z3AP>vk8=b@2*+fni0I0WZZp8)O=+sG&V)>SC;R!3&Np5W?^kp1E?kC9iWztE-d{}!{k2z+x6A@UVbQ3?=%9rJ&!$=r5b`HBe(qF5ZbR@j+d&GW|p#MEtQ*x z@cLv)JmaP%I(DTPLtbhfyuTiIKeCdhzWmMJT>Zo=6Q)B^!kE)$X&bQtg0d|r>+dVFug z^uCYV!)N{cUQdU5A3G`CANzK`&+DPSuUGjmdJ6xRQaP2mUkLaP0wM(VzfGygND7O} zDU1G-QUNH-+x=xg?LJiIv9~OYbmp~bPa8nBB86R<%kAmq_>|H}VRzKS4uG&EY$aCj8@#J=-^;>?BPP-cx?sbKCkxvvxY+%jk*Mcf*u--cKOfq% zK`0?t6zdXxTPX@66uYFuwXrf50ZTnwz6e2;fY-rqNXRNr(_MJtf;?_W1$PAx2;0Hi zI~cN*2^u*RI=eK0w5zb5iG6eRum()%q(t;O8Adq<8hyXP>>p))5ZE*gXZ`b-d2fTm znq2aD=$Dd3XEl!k?dat~>^AQ_pg;SVc)z~R5=b>G5FDZ{ns8C*T4^e>5e8H=zaW~Cxa0r2Mr+4k<2ZiDcZ`0ahA-4Pp;g8afeMbFCfcW*&FF9V@N>4Da)sCyMx^UZI0VkP7jX2!$s~a8I&HQuG51W?)}Qm~2UixHMTH zfSsxrsX1~P5rsmNFCl_9Tko$sV(IlmC!M3!gpN|jXTzt=9_{;nfS!aWg;d(yUYAPKnx6ZNHY8tW{!A z)L*oqUR66?PZnl1G%s>$mD0${;6>@x0Lq4^*;zdIx~1aSy7S1081yEdKH!xzXZX&# zE=BBUxC+I2pF=7~nW*ASh__-i)<94b&eYby4YKs{eB*eP{6_0u^l1tp+gjISI7<3* zrR^?SdNp&cV=uZhZ;W)mftu%Kf1^44c-#TrEVLe+aJWsWRQt3>K%q4I~-@f zyd6^9>hO|tPMG^=qYg#Cjnum!t)+^WcxEWYuul3dIBzYLdNRRI?VCxyrNxWSDqFWB zcG}YJX1g~pP@?JyL47yW>bn1a587xGe#+K2gC7F1k_w;=Z@uF}lTx$LvHj}+;jjm+ zTshOxprzDUDtgrXdUW^k;u@RX4zSNp5DPw}Rq2>OVG$ZuC4Oq8y?1)gP{`^k=Mz`6 zTieGtLWUVYm?7O92>(yCejpbf37vaeg53G%+3y_Dqju`${`V8?$a zG|+Xs=;PWYVowjsEQ9rw9Y&IuN;;9bF-nWRR@?&{Ga);Pw6ncmk@UJK*qj#yw}Yj) zV;(zDA!3f5nB5twb~#vzhi5!(+E~+aeelQ>v4rE47eLtmg*T+qDgoGNp7j?Mu+0?Y z@%sG$R`0g0gghN=a>QR_63%z96k5Ql_^R&_gMc;eoHm^YoZ6H*)QkZwunK$Xi<;^} zl*hO4IwA7#zFiv1Ad<4u-^P;ZpoWDuUP&yK*DPbrS6F1G%N}d!)m)7vg(By_hisK2 zFDbH2{!WE4ys14Ke|mA6$?eL~q}-wtW9!?WGQcTORn_74v5G$Z`Lwe;t;_T2c(e0d zt>^XDj6UsKUw5E}pq7>V-X%jmZ_VsYE_<|E?{p&*sjg+AS}E0jVr)7$?zLaUO8@Z2 zoMPSLVt}2#jBT%o{RD2~RtXhKlnIgscN)q+w$>z4i4hgc&^S>DqWSx0#6(s4w_nC* z+dYSS+jykSY|zF=2cXr^M23!JY=}S!vi_nhQmJZn=HWqPM=m1V=E@TBxtGOit%)BJ zaZm0S$jz$UB~`i6p3s>GsWZFG>sKm?9sWO)%BCd8{TYn#XD{c&)uQ>G$Pu2xM~t*9iv z2@Q$jYpz+2;xp(@UA0paJSi)qVak0rLK0q%Ed*^@5i+_9$ayT(X1<)ShrrG0E{@k> z;Nd7RMepVV*-|dp9}WAlxx#b2 z7@HE`*8RK21v4h0yi;N8qr3ZQkKgwNfPToHB^!aQ4TJ{Hkm4ZZ@*lUn>^=SNZftEF z+VFYDXBZ>!|6u|VL2^C>F7X$x!3hCW1b&5xlY({HnKPc1Z!ws-S_G3iHp-w9CaaY2 z2Ue1Ap*?0JbPv-{<~&}BhjhiI*L@^bj$E-m+!9f7n7a01^1`g-EM|YSpBr#n!n`M3 zZV+@TSPI-bfq`kt?uyz3aKZRgo_@kdKWjG$HPDSy#e@t3J*_R%ls9K{;ZnjgAKaC^!CTSEruAhCFbKup9X zZn;iQ!pzLS;(6{Pf2Be&qCQV*1ol3~{%^&_f(FsIB-Z82$&5!eRr zD=0TtWT%119>>PVDyT;6q~-4J4Vu|5T7oi*?s%`(g&1v-CUlyso~TRhQ)>(GlRKAC zdLx?xZqAir;SFw>jJ)w7iM$>y_1)9LeR!SSw@8Koid;>|WuZba53+igqVvXxB6D_P515r%$#}V*D0{-``Q9Pa z_i9{73zc%rQ?h9ubq~=2+;>^gUEB-X&MPPZEhZ|!E^i~q8S1M}vTvyc#$M8&f)CxT9z_B-JyePOn#$l0~oqpk(D zVsbph6vNy-I~zzc;oO2{7-!KGASr`t7g}koc%TfRRG6FJ0t~cpkoLnF@!|dj@~(Nr zV`qq+gMAsy7KX8RrLC<&Xaf;7W|M6`GAYd_cQLR;-9!12?6+XZ7t> z0;s0a7yY)@%L3ZqvZ{fp&RsIt$AX?HtMDVG`EMa_=838Fwwv0R#lj>K>d*zhtjT`< za;Movj__DpkxXSUcCm>puIicTA2OLJ1hnz_Vh+bwB;hS-4(PXBHI@iF09GW~=323` z!IWQ{vedkk`Ln{Zo6glKL^&*8*I!3 z>Z|Y+YZA1TcEFktPwuw@Gv7Pc8(sTt9@cIJMk>54+ml_Vtq_Rq%>FQ-PW_%-;Osv~ z5T|NB+{h2yedXu&8QAK%dM3AJKz9gaV_DID)pXcK{(}MIU+-@OC##vjI&_g2^tXMx z3OQeixK+8H;Z6g~PsBw?`}?@&Rz1sj?yReFFP0FUirwEmI(mmna=13qNlILA<8NT1 zX_Wbfi&)R zr%8etuIp2}U17zp%gH=(ucd-O&9S5O4LQRODS>?tO$6$ttddLqSj8&fKBVVS; zonjAYdan&_IvGB!4l8uUul?BHJDMpBa@A%SkQ>ITVm5+|p=cWIQ>cupKhgooM<)iE zg2W?4E2tcrCY1tl!xgj;9GQ#ok8t~D7z&+CcF48to_nf=b69-6{p0ZG8nlsx@LHLS z7!-(KKEfa$}0n51E7)^&noJmpEO?#NpYD=&%&c({|p97l;L(5RaNyxGm zmaMaLfn2wJ>`e~zU~9R>-(Ay&5G4ha z+LtwPDtpXhf6Vn?Q?k!bpq8)*sze^(pr|JuCSABJz=T!@x6|J{%5B5jSqk(`taWA< zFn<6z{tzG3^>cuH{;o&J`11#d1={OW3;KI9k||7_OMQ)~&_(<^ei z8Tndt<{scH&2f;$dE-~#r z@Nmxc+MzZ_S0!LmiY-2hG)EtP@$dI=)nk{Txk$^F_g{bgn?9oA5e)sN{j7>QOJ2|= z^N9Jh6ECBSC|NYw@CD~fo;BvIO$N}kl-77$9C05l{dIqjx*H`0^t5VHjTUMrG0?!0 z|ACz^0(5+E+A2daoDl5$zKzL4bV?MqeWSOifZ&+v1!*@YYh?HZUJ|`}MyVLmd8?PA z@z|10B&g?od_G#vPAv2Z{_iI-Vpt@Tq^~@}kFPue=6^nk zDTxZpD~Z_5jXUHCph9eUXMrQ9M~oPvRTAv@Nq`~)of?1Z?9b^0@w^*b##2)7AJBBa zO#8~Yl#XBzX(rucbh9zf7Y3!Ebtih$%TMAw26)sT_b#7mb@sg4V26O3dvn}k0V#!Y z&ESb?_3FB1RP=U^dMSqIHM1a}WBXi$bH33FI>}4uUwzOX8~PH^{N`9W#xVxdRqRUA z7Jh+*sHLnfIolB{Umt$NzbK3o%~8z<#N@eV3EY_xTlbmo`Y)@1;p5xvg7an+HK$18x?+N>?B(26-%>1-tO zmQw%LaBLxupiGxJbS}fO+r;@A`NIv~OHx%{GHGBPbU#x7D6?%wc3yMzXoH7_O;IRm z1MUKUwpe*{Z<6dGt!d;(<8wbBTS6ci>AS~tQ)SQSj5A@g>@iR|%2yfm?n$|D{2MuK z5R%S+AZjIjyITm(o1D&v!*&0=T6|?|QHDZSGg%e(<-I|Yz1)<6dxR+pj&_*LW6<*& zJjExp*|YloeY`VohU)SQ+{?z2*o77U{pYlXd&a!o3F+YhmP&4tcWTK##5d!%w)!dD zj7H+tC4F2$v1IUTOe-uan@h_W>l%it{!SW=m^<~oTe5i2n)*E87%5Mnw?DM@YSd39 ze(62b3rs5uJe6F??nzmK(4nqI7R0W6Tg4p=TpStc<1^e>Ri27t0=AJX=t)D=9;oRF z{c?)~c8#Mfn)Ketx7hR@M#gz?IS{*nVPxt+WISbu+)>XXtK#WL&-B`AY@Hz^9X`73 zb`nJ{SsU@kU+3hjX__rP7+Priy(Q#R&656X0CaEd>|L)5@#q%0^ zUp{R6RWSauFRM$4ips!DOUO>n!b#IoO-)SKD={oEZ#l?MO4CZwjMCRBNl1;-(1p=M zmMYFL%rLXfGSBTnk4@9h-qS3>QP4_Fj>^<2QBYFJ?n6t;G%Hb*u*^-4PfIV#PLv0Q zVGxV7{I^s`@iHF=Axv9%tfv& zs!k^9q|Fp+vPm}4=Ek1vd6b&fv)3%xP1=-Zm_j_3R-53U!=YK*K!5MT?TzpcA2fhSA3Y6uspIIKYi z>64%9LxolLypZhSbCHW~bI?GgJRwk5bCVS-+3Zt2GaIu4XII3eOSz&9zG&GqUFg{p;T{l<~j#+Rwav%02{&mME}kJ}KcJ1M@ofhd@Z2ii^u38Km})A* zM~Mh30lI#Sy4>B@Gsb#k=Q43XKwSIkhxeRPuC_pNidlr{7PH?9BAI_}WFC;(7!JpX zhFWOHIz4X?Ov}{wf$IV1d+{e^@Vq>o{fj1v?X(VmYb-cvyUO>ghjM~3^HlDtgKd4C zJ6VGltzD+Ox9=@JJ@Xk5S!!=f`W067?gQRfk^Y9CGadSH@{gZFw_V*CxxF7|89C7Dg_rL3?ZW2`7dfEndD5`fe#*l}%kS$a$|HKUv;*PxB)0ZeRy{$qqYjzlcs&-PyW zReTwyMvz6kQMwaX1ozk#R)3F&BucsteIJHnwCRzinZHp7$u*G?Nge`211w(rHp3AO zi{BvC#-y?-wVLk7^g;|O=ti^#*>3ml7ygmxEagRZF%8(qd-F!wVT#% zLZ}rhQA`b3h+nWWAF4h3=_H)u7!m6Sk-=Uqt|MYIJgB!ay3&VtiS zJs|P)pFc|etSG}1nLg~xTrsBd2pcsjAV3K`ynt1QbvC5a@WBet078aMQx?!{9Nc@Anw_EyzzwO;-$>(3?>En=6n7#Ayvz zFMPV|p-hMGDb`%tr;y-FqLX*_O#GOL|Guy#kHE+G&c%m`|Nh{~5Fnsw#3;Nfoc=3U zNl+&K^sR`T-Y;O5750?z4kcZVir4a{+I}Kz@-qJC03kvg9jxsKSm5+4!i zfM3ajL?xoh2~31G%F!EoS?X2&q@=wvrD!_sePj-*F;#dVf=lRfV)2Hu7+`gRF8X0= zMOgGae@IByMx(*4W?{koPha?R5THF}?4U-#{UPGV0O0vSYk`NScTsacj^9=hd2Bae zW!^Mu%s(jhl&PM$K5(~jOel+yfy;qoxR|4Mu!LwzDx1kR}3@L?6Mc65C7z#P>% z#1H4*)I4fzcZ^9xrN~P-6K-&)iDv}OT=OO5YF?8x%S92T!IHUKBz2e%+_$Eyc%(%_ zoSR3bswsC{Ge>Q1D_~k6Z7#(1D=_NQFJ#JRYN^aN0elb}tQ|dyi(-kosni8^bAcwiQ3a z<=M+r_0m#-w~cboJl9kb1VD2ab1a!~8Z@3vQ;rg{>lL5X{sj&I<<6vB&u*YEjkw81P=~POpftQa)rQn#f6?G15^{!HCF!7RIky3*a z_gi)|o^jQ*I1cq+!CRcU>WQ@3r)}1D*P39&+42WlQKgn32Ihs6K(k}fAQ2+Z`}Rw2 z@7z9e*chu7Zv+dQ~zPLCI9yVZV^d)^@F_D)saIi}n!5hdy{*fP0nPqj_%^2p)wuMEU225(Bbhi&W1 zRZdX@1TJR4yn-#tMP%_sq}{S6AYe3Rn7k_!aEBZ-FV1NWD^~8lPZSz|bQu||U7o%M zw`$LVw5nlqR}#{4ke0y!_p^u{%y7p?Pa(m+fyaJMIyGr{BRzK;uY&6P>_&7l+@Oy3 zlV@hn797|#tK6>{bgb*k4^W2%o6~i64vR4!&!>qe11|98EY&tQzJ$PO7j6#-Ip|1oUCP zsf=&tm(oS=B%d*AB8`?2JXjx-R0QQuPTIgmsWa=$FtSL#jna-oRo|r?JzVW(Ez5Vg z#i+Q}rdDjD(L)nJ^`pk6YsRx$e>+cA32*RK`PQ;L{nTa`^g-6{@{TOmY%>$5x2wJT z!|MJtD;uY$^*N?BmF+ueGPpKg6BvK7(DThN>XMB7&}HnOWKSL%jS|}2kY)RJ1DDeJ zdBzUfP7lzHX<7*UY`E*47gf#*dfvT+{`l@xR`|4Y&A)52fB1%gc9e4pBvj5%Hf
      z&{ocM;sZmdRruvTD^WoLk=WO@D+EIY*S zXziBVINQ9a$S$vpT0H99*%d3orM8!9HYfRP+_saG<*ZfGgxf%`#GtCSN7jrjdgSQE z8?~&Wuck5$lVRI7{hDoAdSX)&^|D&U-L99bDFI1=g(Gmg?&w)rc(Sfz2Dxf8W1lbW zbh0M8Rg<+!hBf*Dj~uARuvFVrmZCay<*hy^4X8-PBWkSk(uUyzij#pmZl?P&CzDp~Z& z`(3TtdIB1W5U2o)bux}I?Vi^!4cs#XFApJr*)kgwpQOE<;|uM6XY5lQ0DqEw9u>u` z7p@*Um~Bojh#s}unAC&odal#53J<0>nT;d3&sng|s;W*c>aTl3l+3507^ zW_T;yMDW70#k5C?*+EBre}o1sU=og=w6j@~%84g}a-kuA$h+*%VfREy%C%B@ozU(+ zG0yR|y8o?~*ln6l+N3ANz&K##Z;*P;t*UFK($K6Z5EurVTnF94Z9B>m@Jiz_NMgfl=LwwG@7pw9u{B znvt^SL}S6eL7)6_XrHfehRZVfMOwvY3b{-pfVt0{pQR#@8R->XIS(@ z=aSaa;1=@VH_UqA5&IEDARyN{|Bn;-KhHH88#oz!ZJLt+($l1^HtW;X<{S}W{sWYq zq@bE$lCk7FG?4`D-|i`jcSj=`=OwMdJ}zfFxgJmXiq~P-XAni!t50GL6$`>u-bdT@ zK89cMH`gz_0hcaTpYPkRpLGbApF^tK6F=qUW7LK zeC6af-;e8GpIqPB5>KD$6Q9gPr2Y}4lc^$bB}0fMPgo|* zAg>D+)|KIVs){;PuFLpJE>}YR(8ND?fA2UeAK#4r%4Zkz8uR@07PfeS#k06%jG$@`_dbi z;cfYB!TvVJP(5F(BH)-E^R(MF>8y) zS{E)y%_d3-tI$UY&z(If`;xai*N|N)0w^6&*RU!+hHTsJto&%$0kVEFuMRXSGJQ7H z(w&nlC;SzkNs`j%lQS5~mZIhTxs;o*y3Oo~JY*XqPp|)=#55vN>pRR{bVaFGx`7vy72H1!6 z!>Jz@)u!Da!l|&Swz`;Aulf$wi=Y#>S3-{{PEE+$G??l?tVNp@Is4jS%3lF%xy^-j z95i|#vtS_miQU@21{5Mb(=Z?H_OJR+C;%xURgepsvKO zD6Z75+|KV^moVG;}w32kdJLQ8CZ7`0df+ykD9lZ(;}ROx?QgJbJ`mW`cDv6uJl#8-vu-rF0zj}PQ6_tP`(#O2nZ>&=_o zf$PmJciQGC?3CnzNA0?X*Jg&<)d6NlT7JesiB634U~^SIC3W;cNy~o?zHdgWc8hlF zYKxWE{?vN!`sn&#ilGm%ntJ1F%26Q4W3XbFx_z!FZpVE92HjNy zqks>4<82Z&Im7=h3dR6xAp?Dqne7#@VZjNhn*(pA2kgwhwZqT#zTnJ#eV}o%=`rwTX zAnR&CH6ireuabZZDZT2Z%6brbX|mo1%6eqd4s{1IOMgb=|Imzni3-jHRx_sVgy+nO zOJg7Me}-o8jqbpeu{+`!FmY+YM}RI6I4} z&tt*uNxo}t3vLaLuD@IzT*s3$OVrrPSeYXy49)Vjm?L=SiIh0+N^m?>;CZP+@sfmN#&X5?XYw766#qq| z#Qx)Qdqis5JY#LWx#H)>&sL9Lp8wBPE0t(gs$s0gTbf@LikwUTB2Mx;`P8dvyua7I z8pFBxUS9%H*1XBR>E8+7Dc(umX}o)fxxL#r3+(1D=kVvU=k(^fTk(TF3Em*L`G0&0 zJ|Xn^B7Ov3{U<8;lj2Q$n;-g9@hPUy7xg3m3jcqlvV%TJ-pIH4p*|&_2*eMH9ZV3Gswyb0&P*gZxo1mb4hM+gW42 z^sCLFPqH`m?QW<~*(bX`UzCrGE4#k08rj>w0sc$S*Hf(QljVzP`F9v!UUpqROfx&@ z$B4V~yVYXvg!@rrZzj!bnI-c7e_`F>i^>hTw=M!5wzUFVFJ&(^Aq63oKik)wRy5PT zM3i-#zrZL9E%RearDi*P63}!G(FVCw{-Y?k&!~#m;dxJBOo}Qv=Ba@oq#Qt*OKm`5 zKy_Ex-4a}*!k;`QEHovnfUB+eDH2B~+E#>&dK{m2sv7%na)++#i*$#s2qg)nS*@6; zkTi3LRn&bXh4DhJ>|1+>P8CyhV@`#jtZyoHB&DEV)MHJ#ZR(sFV_hik?5%6)aIl|* zn24AZn;4s<@K5VR{VzQXsZ=QqsaSFAHfbm-gyNfD|0hv>b47(fPv$n(H19m#HA%)n z>PGsTvBl)l6eS+H4mljT3^^TH1_}Tr45bVu4MjB1UB;6)M*NRpDdRERA%B(gm@Pn; z^-$bUc3st-i9RQTC97~@q|ew&-1^@d*b=;@f+x4X{r^Fz;_2>h|DOet3ZCHp{}-W( zr?`*wkGTH5i~nle{b}jNziij_^^+TFH`M&F8ib^(`Jn#!hTxkoic0}@rGpfV z94Ziu@SKRO6MVBmKE`892PY5~r9uOMH>Q(m`#z$h=a|cP6wj3M-ND2GG%X^e3Z7~C zNC(AOE}$EpeRT!}_^sJ!4Za0;*QJNnMEPIf9E1JlI`bd8@D5rObc)#)VJ*wvbL$~; z6|~uG4X=fF_n~J}m2>K!ngYvk_<;gR1GwZK$eO=BBnT`lqN*Pq%h%3N=Nt`UBw-ZB zm<}wgZpsnQb*t$XUZNTbOsJdT4*z{R?Dbx4Q6c;FoLlJ8oIIhjqAAk^m?*OHkVN6fhgh+9x%8j0WQ9PuVAUJNvZIf1s*G_NxxhBF zbQSvJet{b{F++tPuR{KbiQ>Je5{wq1lttCRF9jyEha zAb((geJ4O?Y=csiMOzFiDN2MFCM1i1mh;zsJENH(O<`{jZq=E1>(imj8V@!zyRNS% zSQ(st>tpWL*nqjwjl{l>xiIbR`bi}XV77IaPGholw^C&oQHu1krCjvE%ZfLXAMIDZ zIiqxUlgi>HMUWq@FW%dxe3m}Z;vNYcMKPuW1Q+iCm2a*Rc|4{5H~QE59uJ8;S;+LH z&Hry|+m!BKYCNRVS@EI&z0Z8Ag?h-#?N_%4ZytDzt2nEu|H58iDRHflTTC~!+k0*< z4m^KwrsbkT6Y52UjWuNXQ^%E4e4j`6!0FH(ThT^z_&qay2_0H#QxPV-{6f)*^hmae z&S=0mVEi+KLCm)6m8qdel16cjqh}SG@UUdH7;rdxrNvTP9`>xJA(&E@)#Y#0r1qFQmq6&k|qHUr0U#f;EtlVN9@~ zhHYD!AzC}7rXP*rXZK=mopGHTKdRa5ma(_*#U4C}J2pmi?ShuEfu~Vd9>kuVNV;~$ z)$DzzQ57Rd;W(Oc#HgHgMB@Ky_8wiaS^JM$D!gi7xPG(s!6KUa73LKpUC{%;WdF0R zfhjpiOTAgQlYDkR6t2zIMJlKBJIW6DYkVj#AO;609u1dg35!_exQD`F2x|LKVgzbS zcNYWK@=O!-L!7%VA9vea+@*mS=X@mEWdI3d7NhxFGo$U7W;gNM<;aIC%ho|7q081q zWIL#<*&1%kzI818TBg0xdRV5t>y{}wUtd_vKj>iIdFP4%l1w}nC4qS)c=YGqkTGa0 zv%B9!6SU%xZhROIp@uGCH%R}P;SUF)2HzQ};d)rdg-8W=+;Zk`XY!jil-dgsU00(2 zi?+9bisSj#MR9jcAV_d02_abU;K3Q(H9#2Lf(B;@5S-u=+}$05ySux)!|TcK|3By4 z^UhuGt-ID;t9I45zrA;L&s25QR8QB;RC3S0TxUJL>te9FGgS#6?!KJ1ojQii`Tx%0 z6zM3@)`$nv_)4skCc-Gv1^#-l7B~MB7KnxxTY^-Szp+rOVIPveBvUeg}J_JOIST|BQf zg`k>#CbyBP06T24fytVEeWt14Y}Ij6XzQ>Ba#+*%O{vTUq)W;)74YYN8MEf=L2QkE z>Dc6q1o$Utoop(AZ0Zj^%mFg;+IeY0;Q4Mdn0 z%QJyrGJQXPH}3FRauK#J>6mnJv_hA3k+tOdX)`i$g!pc8thDt-2~9vuXYtSmwYohG zldlGsymo@1PgQFR7Wqc2@j|4Y&@2ystY5DnbV`&nN3~&5 zLV6FNGhcA3b9OtzV5ttShUp_0Ye|8lS2`C5y@*MZNc5ak?9N50;h!l?UOH;T)J&eZcvZs^rY;~GfrpJ>soZN0X8|4UN;NaIn%rP#+t@)L{1%t7(pfv!Fj(SO5un>S z6hxxb)+QV@7F|-JNPMDW6}AHvwxvAnnLO)^%*nB>sj8a{dJlfyFME<<#X#dfxL!)*!yeUG`F|cm~sa$(w zr5UP{IG*pfk(MAI_edbFt867c&XDfPaIwR25yA4nyxR8CbEfOCHG}_UjViIh_M-uY zt9yZqrE_riJv7gE73H)Z@~a~)9-P1BdWcFSiy#f_8RR?VdKEFRPG|E8y!5GM^=c{E zWUNhYTT3LuTGbfgIlS|;RKB~3Y2V9sYmFH9sj?1@Zn<;e^pqhP(4}qQx9G$*-qh z)`rpS-WZMQtoS=#^Y28y4#vM1jntM*N}{0Q!GC_QD=w4L37KvT3Bzi`_82 zoMvZvwgZ=H)nRRD)Q_BYeW%hRV(89UE}}sp=Q5}%OtsGQj(qfUbgU5xd}R^w(5yB` zA;F2oF0K>fDuLx=Y3F{YC6Z(Om z-eAJ}0XtbLwhFd|R!ZDYApW=Eoa^I3Vc(?zS0U=73k49;g+99I`T9~p$sbqyAhu+A zSjKBw44ZFbYPQDS#(H5TX4xRqy@u|>h%3Nd!>DoW1udd&(yLEg#yT!C#svJo$n|I< z8c$yG?wsAPi*pC#lI!vEI7n3{o6#>0UimwSOYJ6Zi~Z6n_iSTaDl&eb5~tS?6aA;c z=1A3!WO%=1QCex;^|?x`*P>C^g{J6~rL`fZ@lVD1g=DL7J-jF5S9PqLta5|Z3KW^C zxJ_?83({D4&oaS&*p`pZKo-r#g8ZPgT>9}u=6lCkD?1@pKYU9xHw*TI(mIrkfRf)D z0Q9TFM}U2Fo6uVijZ78hiSh>iLW41ctO;&;-;Y!@4C6IlCfV}k%9(A;*nL`HS_&=E_wVt5TcX4bgb#!_ zS#ySHrnh1koJbH&=H1=b7y0rRFSRl`iiqsDGI z;J(kYir3u?AkP;bJTM z>3aS5XQBtLlMsq#UC-KyDV76vR>ootu4WhpPflI1`;$pWO^I9YF>X!YP;LV*g~wG_ z2fN2C&gnYqK1=zP6SKd>jQr0g>A*p0`ox%qaCX#KDhK!PifbMR;G=4E5APw{BQ5i& znWh?cdg-e9`8a$Nz0)Eh>9x*qJr#mmeXn)hvwK9IpeL_~3@Wem;bd;xnzO8~^K65f zht=lq?-JVXVLV^8Sk`F%j1*!QDM{l>C*9H6fp=gtc!_w;YPY=3eyDmv;W5Liw)_LK zuTm%1LOY{&vF6xjqn@%qTiCR+DH5g+Kc;4^;g)Xsml^MACi&WZEN zu}=%U7x4qx-y2(7biML& z(()G&Hf#PVzGoJ@oXR~a6W}dzc>#{m72du?bi`?hS$2MC?mt#MWtfF;2w%p&<$YXBNusLk(b?a7)>2RC9x6fB1 zYw@w=22*uGtvL@uoFqI%i|S&4qrJWFzMEL&wUHBa%DYzH^GhVh@%w{zEPLc#)iHm)t;>+gDFy7q8SG&lGs^lho$f~Zdj4^k)eEAl>q zuwHl%s5ccW!>y@^UPwX+0N&g^@6SKC|?}F%07!P7LDK~~S?P{=kAWywEHNs}5 zn@Egx?SD{yyBeY%=q7)q08Nk3T?);<_@CzQwHo@T;h~-3iSCBrC8a2Nr)@mc_eUzen)0U;)xdJ2_{L{25BYQ z?;g*a17!#%DKc0O&IYON=rzg?OFx6E>t0z%eD&kc|&?8G}s@Q?q_eT~( zLB+rdtv2lc>LmTtaRlEoGYt1%$^Rh|{lEHX#NkU zjd?z1tV^ND;=j*tVJ6TE<7$I$2W@Dso(uI$8!EcO$uh; zB33$uXJVm5$y^ql6ZWmx6t}$fb+|iCc+bx=bIm%Wz$F%fY*8%DNyI?U8h4KkvR{OC zSO)>NI>EE3l+Mi4$Z|#C@`}?Yt!9C}M5lraB;NCRGSB0U>ymu-k_)tYZRGPY9=%b8 znOd!sYqex`y|eoY>r$;)_&$GUW z!nz$BwY%4Ob&KsEDi`gfot%-)w%r@uUTbNrU63BnT6+w8cAg|Xq{E+MxC|0_%58!- zYX|o`ufm;nTRo66uxJ)O?h18zXA`Fqqa9UrOk(AByH+F_9+u*kY4M02*L9!1Qh#^C zoB2T!Ym6=_F)-Kb^rPtBsPxtQa+hMt5}jh0TH*72_!T7Aw+*Ng2f|A~b#c#eFO?*V zraIIY)_;U?P_j=iMK*1g!Z^Q{*^-VlwOi$!2KjtJUDDE7Qvi$n@os$Cpo@&E#*bL5 zO9(HEe1L)Q7-BYY^5v2}Edw;Q>h!{06E^+Y=6Y@zbpl zxN|3m{1J(!VBezFHOj$9R^3eK42Eq(%hKx7_vaf0hn1ebq$mFlJxQz;x=N0;bKAXa z3ajbw)J`F2#D>!k^Zl)LyY`-+@6MwHcwtmzUbrU{FA{~HV1MB1d;lg?$_@#?DTR1zj!%G)X(1|S}){l>xJe2p2bTv`Np4SX!E?7Z#wf0}n zGYM-YEgiqPm+%q7gsVPhtg#0yJ?u<^b1=Mx`9&s^3)dx>y}lbGY+uft+9z#+X~_)m ziIBiAVYKx^uv9SKlfA)UA>-!QNyK`O5wDxSzNIwzeY}OD==0&e_9dmMIX)gzHda!i zrPvSjpP&;Trkf6Zlsn>Kw0nsHF6>%Yh1%i6ti?Xtl|+R%XeqB?NiroINx&w~1V2Yzdq9N;VW4G1Nu96LUffGS#FlDm&5gv5(u8Q7qeY8)n zG3=RL?zh&$FX34+M{bpe(Y~w|0{-Sw7Wi6Mojc-dSAhhTH?_)*4__`T5S&u5d3HC2 zTfJ#YtVCM9QE+twI5=ejwmWE!Nw-}ZhSAJE7#Ip=6QMV8Fye|@^=CeQT{(H%DdnNk zmIOPAXDocAst{`TIbb92BgzYf-4u+_Md?2i^Veism$SfCvD;ckt9%>Z_GZLUUtfQ> zbu=>X{QE=i;@%(!5>2K%J{nR277U2cL}+Le+=PXIv6Ge7pe*vzc?@oWy5%R*(w?mE zPE2?SoKl{8D^Kyfg4^wz&V6(ojilfofgFi`FK-X-4pj5|-Yv{6_93JHj7^d~d&hAW z>D(VaH&2gM&mbCbU9WXp4yP1VG4*rvX+Z^8bxc~fe}vCCbp4Jk8|CF8{d!q(pEs4A z$%#4mIMEw+T!vL!x=_A3{BpKvLdg)R;H#3S(gDNJRk!a`R$*C({6f(~moE2^w_gdF zzv7~dLMU0mqTSvy-3og^CpTGDYlGFhkvEjmi}IRtnK9+H(*{rF?6;H`9Fzhbm1dh= znS<|67REg)&s&}am2`WxGU2Kr^C`Dv;jvxKAMcg)QSHepI_>mJ-g_=NL zPS!E{op1RolFog7-?+zR?8tIUl{NL@-f>s-hG*@D&^Ni?-)*VJe*lS zKgK=hrl!`*F*MF!B0sMXpCNPST(4n*_MS4fnzmp%LHrsJM z+`mM4zBo-Udj4+@uGAP^ly3nWz9x}iV1S?G{pU$JmeU*@lWRL{v(vgW4GXRc1F7U0JV&-x)D z7qO5dNmO!aBQIY1io%f|U}~z!apw_s==j=9WXp_A@EU0Ug3qrXutQmw5cC{KV}KNT zPX}Bwxn*~}ymJ%U&oebMSjD9Bpo-C(5>NS!SHyK=h4hh?&ri?1Kz`SEI@v_*T_y|O z?ByKyj7<4T&_Lvwd<;LW5caArTdY73t|UHfz;7k8pK5SgFcRI9 zV_Jo=YQrFu^fiJRCoCuK_r{X7!OX+&QcQ48WM66D%QaMrL5w;P4N(g?WlKIbZLG9e z^obG$)4QFX!Nu_IkXTmhXYp1U31>>H7p?45KbWvZ=2osZfp@ejyJ(YzEE&}bJ={yf zGUGG#u=7U7O!vEs(y}TdCO9nBqdmi_q}kGzld5yaNat9HI_X6aDnU)%;-CbH47#ri7V6>gk_!G0N|Tu-KbIy|C&-Eye?u~T_wX+%zUUzz zrdo!rQ)E=dKfwR5Pjks$liv{o7Xu+6(4Vb_KFGyxV_;-yU}mECuP3@f{&OdlS}90@ zYpgQ6Vd+aE7%<>% zprh&YNRy?9+u$SO-e2n#U=g6awRnDaZd_b-J!e@`HK@mO-%YIRZa-_!-u!S-zSq+4 zbvI>M!s4~xl@kYyD(rFm&j$s=&1DZoW~mxi>w0W%`&HArp6AE9?pu?aUgra6HL+gD z?6HprU22}C2ZLtInvM6fYN?)wzlilbo&p6u_Ul^AS?}Afo3FRMp0=NVK2z+LKbJjR zPBWJtP{cjg-bHLLxg5rrJWmTgrAn<^7oay^HyuCjNC>)Jg>vb+A5Ky{ewoFNdvqmu zwz{a{_j+nFOYs2DhA+8a-BMhBynLi^x7N69;Y#t?&#`W-KS(8hcFEr+=J#qkV7K(T zeQbF;I_`NOOKh>+I_`YX;qu}dSe89^?tfVP;FYs=Jn*pi)@ys~xcxzA?${Bo6fdX{ zg^Jm?2kmvaQc&RwD(1i*G^+B*ph5;J=8zsV>hiImLT)PN@R>epC(iah>guzgqK}4u z_5Tjn0?%$*G!$mwn8P*0>oSODeP)Ozz6u+n?^UN6peIzPnV`>AxAtY4ZYoxs<<8zI zR$Kx&V&*R5V|4fPO@E8-)p(2c(AtgdX}E^AoA$%|kf`pi;nLct+8YfbE^=bQ?zOG; zwQY@sZ`u!VA@kuOdd9YQwKw!EL*&FQoohquYjGM$f^44tU0v&IY8t@CNzc&O%5B@z zeHN^>xh!*dc8tV$U#9uyXyw@#P1pBUm=<#+6P28~ z=9UWMQ)yG8t`GR=R9ZOmJ_)RnUxgQm-hUMyC#w7^JWuqmx_{35v=c>Vr&(=|R-b** za;+@-IHyW(#T;H8BQf8X`9IUt9>xabniVE2)kSnw|F2}_UvoRi1ULU}Oy7StIA<#R zH;}MRF0ffjKhUzC;yuFrs$%^WqeOI98Q+yI9~B|&L!l{!^Q}srUIUC6uK{aHu%hTQ z@=J^b%g|UpMdPh$n^n+J$$@;3o$%RWn@8?!L*eQX!uIN;vj%x%;PrLI$Dq4Mcoyt( z&u7YhU-;9f*RjYNEne}PZT>FLDE+?Jr%y((6^Wq@jupu(rj1@dV5 z6%u5oj35ZAv$sMx_E3wCeM8}rw5fX>D`4oSQS26}T6;Ntv};gp>_RE0$^J3L{bQp3 zYYIflz&~KEXnK$?KPe4ibRWnP`P5v9?(Eu z2$49nH1FuGf~|w_IF7dE{w)pK|0z%ZRetY)>SYeNo&S{Sow=xWVJJ3sRwBhlz&n@t zvp`***yKmT&w>{;#NZzZFV-9BDQA4Ky9(=Xj3zKlFGb%L$eO7pwiS9Zm{#o$Sa8IH zuq-lSFV`|v-&9Ozjn?=$2;${bZT_A|8+(*Ynu?7AGfQ6Islv9+dD2W(Zx&iXRVUc= zGhJfkaWs*qFUc_U8>+ea6d_e#5F>Pn*C((zuj=D7oNx{$tkG@w)%h;;rzwyPcPeOf zJYt=2o*c{Atmq#;_^~^sk@Bf^)iC4?;|r?R*kjfSD;^`lQ!41svB_pb#|3*6-UDD(?1QMOLnb>0aqefr7QMLBR? zhC<^^hk)B0-c`OOM~!mi!GiSOnWWd3QecU(6=ePCN??f-jXDnnh~ikB zi$!sNbaorkXz#Ewi8MW_|L_Z06%)&)p$LhvX=}_y5nnU1?bTLcXA<#$QvY0rehe7x zC_-em*4!0w_nx{9KWMkIGf}F&on|{Dj!DN8IA?~%35~ZTo(}1wOb9n_RcQBwV1q2^oW)g_0iCnCJE8qHu z`byPn*y^pWAVgg)*492wah8)gO<2`ps3$qL?r!Tu1J9eX5TZXpM7r|~ty1Kp?Usp% z+`ZJAE>@qBLJXjVVdaW}I{8@s(v}jyKtZMHatMqAQ14`dl?@1RZsR~72TtBe)jNtA zI3sZcz>C1e>a%y0C9C_?BQ7pWhSM}1;!Mg1@rk3%ML4vNk3l%s9zka7YuMjMtnKreS#*30 zW^*DoOD}Jv+{7v0fj_#F{|!tXn2g;srx0(--F`V!f(FVPQXD(N~JId^S1Z1 zAnJDp!uQ#~%>8Z72Q1>hI2pyk)LbCi4}cGFR}R>-;}%~K>66uyP^oY&;X*-D0O>tq zEjiXvd#Ep55_pwyft#iE(k4h@k(&wVxw!eH-O!#Z;<)}B+H-Tkl4h$^Dx6Tj4uC4W z81+KU*+I`}oRarsT;@dq3~?X)$`fBZSIk%h*)5Kk)go${G|VRo_Zg<^L>H(cjX!8L zz3;iGF&yaEr|^_9N};TDw2$(poJ&ju-qt1eR~6a7?u9K5TK+blg$1f%4Bpy0kkClm zpcR~mY)hSvkV4lW8JviJOP#XNNY9`SoR2v8hzRHF%^*LV$Yo2Nn$XD1paHC~5!W>; z3Q2=hMHD5?)hrJ{q=urPklcS&5gO?>GlKIG5a45{+*z+chr$L1D3tjNS)h;^3Q37^ zE>36tywk#m=@1b--02Qs-&PJ6qoLg0{1}q;QJ5Pfgd6cuMH52bBlNx+rH47p)PtGp z_J*kp7l!>pAqqDlpo%JVug(f{XcP*NRRA#sCD;MN7p4;Xj|N_iDp#9!O5#1@444NB zkbxYrgK;0!`V8iE3oAXL-Q1-ybS(@~muF?*Rp&Akms z?gO+Q6GI;tDEJk{EOH9?ngBy^+cMy)N=Fye3(8FU9Xk<;1@5Y+P`wU;t%JvtrFf_6@%XJTV zN|nZ*RCDu?k*-R;DcGrY;R35F`UnkKy{)V(hz(jh)!P z^noL0f~A#w7^R>LXCUep)go}nEh^feG3c=~-v1Y79?EP{P2!f;RVaDKSdv8~@P!9P zU5L&tKK!gtEK-pO+8XkPVZP-xS^ zeaX(y3DVon4EUt2_DSyO6?7W?*_+$}4Q8&hSAho8IEMiry~P|hhNPguAqzaLz({ub zlg|to$)*ZBKqZKQ`}Psg{XnM9wSZy90RIPbL`e0G&mQ*m*qlu|=1-gvE_+ry=W z8#YyH@pFD#So#vN7?+3JizD^HWWRpc zJoDx6=grZEuMC(7_{YWX7$mRvU;BzA);9d1tkKc}(^tJ;=&UdeU)0TiS$8;%$2^gp z7&tR=Ff2$wkg2%r`H?R%dA6)e)DY}wVwC^gtfJG;HAl4*IJGJjXxEdYFv(o@;};c^1AZ>)!j-%+&ieKkbVNXvCB z!7Xfll*^yP{di`l$tVhL5xFjzPpP)`I!vb;yL8cg&*@&)vf3gWoZ_WfA=&zZqkv{rT~j!_Bec2Y+vaQVuf=J2e;Wg@#Tr|C$~ zn$TlJe~4b2e^_lRn(49W@Ac!)7V(=tUpo(`Tjezp#zhD5`VR{>3=By3n(`k z0@5333O?lEFmrhK?^Iqt-%$a+ANV0Kp7(ey*Gryu@k@@ZbmTc@T%x15XV!n9=tYmF z+|&@8F_6GFu~miNhm+)E>SP(;)ue;B&Q^ZSQ*c@GHPw^ZanziP#@1J_Dh+Gw?FG&o zy_Q+LuPrj=F!L=R&>1fy)88uh{dKVU~Sl)6smzA;-0B&Fl5YVf)Q|#k&sL z*Ne8IsbQA9WYZ43P&C;SS;Sg9 zF5m}6zm70EE34ZPqx9*du^iW4+g|b`PvRy$}2nqF=|6KJJf)|Ls_ z!JEXcyix7T@FIjn(AC;Ku2p;0^E+7CLaj)~Ojl;(>R7gzaLvh8y!v2C<+!OJ4xxTA zAAjF320ZSKXP)b(ynjHwSUo2BYB6!{E1UB@IF|eK_R@rtTirZKqESK~|CJqm7}6S> zGV_s66Xl3i!D4B$%I=n9oUF9V#?nNt5WT@~JtB5NcAU|&g3RmUVw@QQ^~JB;?I&v8 zEML(txEidxtAn5HrgLJ{Y2AH>Ox7 z`2c*A*HbQ4L4H0%_hb&C20qEAfV7e$!Eq@S$jgD+#U!^}S1oRoWX zb9JrKX=b)?>rOu;OR6UQB$k)R1R}gGXw-_hqf7Xfm{NZUQQQlA`9o>>ZO+nJ&eHF! zyeN;o&6v9|p7Tp)nIxKb$4ACbq#PyPg$~)&_S+a@$qDwvd{xEBF`sm}27i!u)m#cc zB?V!rLi+liAo?8M=hCI5-eAZ=``LMnbSYhp8fxrHv7(Rv7IKVV%EP>lB_R*#L>t=p zZnG?eDs2#Am{vnL>0Qkr?On~34{xPB0W(*ei&`m)`|ztd8L~2baj1mgm2F)^b;IG| zM&L+h>+ohM>4;QS1?Es$1+KSwFgg0}n;PzAl^*V;qY&<87AIp?GZte;GZu43a~K04 zOn?A-7@*4mx*VX(0lFNZ4*|Nd;EtTQN3!xKk5E9HxG$8>|KXz$kpl7#oePZd)4XW(Q3%vkz_Az!K@)kr4fauR(^bOR8|p_B z8FUqc#llipxndYD+uGnn6h<$fv=j3o(pAIR8zY4)-PvG86ebn~;W(VyBUZ6hA%(~l z?@J-8JKA|v;Jx2EZ-OM~*vmsixwF)9fPK!- zJy6Oi-P^F8#I-Kn*Ug-4;%2cb65u>iiYt95CcoBO_TJ>~!Aa~*`?fQKg+t!=9*r+z z9Rn^!U*ey6Jao1AO}+LQIe4-?pFYFh^_>S28ld+p(#~|)eMbFI7ER97{XwKW(Lk&e zbMYr$(shphE^A`ut9i7%36e`TxYi?)EoRa|uwJlLfbn`Gq_V-&WbTr=DO6NI{KHIs z5a06a!0m53;lkh7?<(Pvcq?U5<=_Nz5W2C=;RA>7lHk5}6?I3o8ZAVwxYd~`Sb4U@=|fqE7-e~0P0NEamaGRoHaM=gs|aR> z^zY83#h%nD4!*qcsFRNnoJH0m`m9H;uz`KuR*X0v7f5h>?on#ncCk4LdB7E%X#fH= z#bkOA_~$k+ArHcWGi?APF7||x6?C>#*wfFK(OAQ9b{58PYz1j-r0#PIq+&k?Oj&w6AoSCY$P;_ulE`?bQQxA6*+H?-F*~!WPd8gs+0qv-%w9hBxXQHO z+G7Me>w@y|_&54e*R?xUf>Z1_KYYrCV$Q3s>but^f30z&L z8II9`ldz1wrUeej*>?{C&V^)?KfR~FLEKfI@$9Tvap@Q+{zy99K@x5{`$;oLc9|{K zqG++KeH%-1gXJ3=d9E5W=$2T;@*tGQfN8O@G#}-x8K6=Tb@U5)Jj7%hvCoNT*7SiI zT)e0p6muFUJMTr)LwGlf04H=En*$fXN06jGS9!@|?QwTREcr|o{}?-nZ7;e82oZN^ z6J8_aJoTg#1!9+h(_c($obs;GIkjKYf#P%LE0?3nx}ZB z^Pa)FYT5Hf?Qi*Xvy&n0TJU&9FG(!hr*&8(_^JMj(vn5XBhQ#v6tt@FNVbH(RV6r# z{)Qgot?l2k!Q)E-6*OWVQq7bBH5`Dy)2v_A&RGlEW(j?>{pQ}Q)16T~pDOMz=w2^$ zWcy7Ucu8LMLIQRGa<>dt=1q^Zn)I~Vvv4-C|02d(RtUXAc|i^)NT)+cpBMA*jLY`o{kfwy7% znUBGvi1s1t7Iu&60DwS29RPv>u=t@Cgu9=Zpk0Fx26f(L(@k3iXc3k*=k;FZND~hb zh86TWYORSQ+WSGBivee#VWwF}gVDASx+gd45iR~ z#B|<}aTfy>$B^=CZk*;6&`)eQH8%47y!NXfIQpFi^oSG%x4F}^BcUaH3;D(T$DPrP z$m3#FDEG%;ejG|#JpXsM^1|F6M(e5^u-jsO(3z^+-W5(h1ZdG5aGMe6lWRf$fhwk& zSaePO0JvZg>gxDw5!`@FeDzsAxBuY7LMSBZOf}9mII0mHXuNB@Kv!a*b&qL>&e@>- zLgv-3jsnp9aom#)(2m1yTj~t$A8hsVX#4eymX5@r3_8y|{MI}?&eJEHlZ@Ze6P*o? zr662@U$UA5-VR!z!z!+cNkN-R>snPzB^c`aVT>3BsYEuE-ea~42;&C zr(n|MTw@qlJAbMT33@fA_Ivp&CZ7h**&LMRx3eWE9O`t)1gmaz$b<$+{l72JvQj;@ z@5GR3JL;km2~PL9nAfITih}f7#Bf_Y3#dGsQnV=QTywKh6SdzV@!l3wd3Jk>J%qtS zZpe@cPx-JI*PLIeeqtq8{KN`5WPU{0k6i8UwTIl~Q3H|*h!G&$gr~~v3~M>MDxLC# ziAr}GYbI;VEWY2B=d|CVntYQ^WcKxeV(fpgFBIcLae>}E=&pAtYyL$J)7rhIZ$ZN= zU5#xwOHup&`poj7>q(?7wSbs-x3~PXL-M=Z*>OMgWX>Hged*dM zvUi^AUj%sG13?12eE&myrFEYt{WQVn*<<64zmO0L32dM&5fpxc!tJlJb;n=%clqY! z?}jdb$^gg*zz3;ijgPy0{q*iRdc&Z1#@voWy5U$>o$r#C-1^?t2$ftE@XN3Pe?B`Z z0LN69FUL-ds}0JD1AcnRo_NS$I_1^rr{@@KLPag(e$PxfVz`j2?DBotkkc-~^yPfL z`WJc+N5vo_CE4x4zHpJxU+mQ zUagumQhj>;C;^G}%*^!b@;3J7mD>r*|1t7t5soKO=9Qnhy}+u>vPh&1!riz`afQjh zbmJw_f3T76R^vg)PBAz_M&#M7oa|v_N61gI>oYHih|#n>GspqZ2*l5Zz3h-&yF!56+fCF)h;S4kKovYx_Txvk8djk zl?|!?fN(AQys1dvhPg$iMYKG-(H03^NDvz-dwnCb4=3~M=D*C2OC!vfN6BT{%Wm(A z51m>GSoBI~l70Y9Nq6$cUyNr`PV5mA&OE*@$WRc&Lu^YgVMZbRole=4pGO&=6YHa& zG>10UeRj``*!FHw@3J~WVbC*|awaQ>z_0$w1F;R{1rjPq?7`&>Ch%jUR>jc-%L;Ra zR@R&Uo|L670+X0Kj!PCKifb;uAKNRAQ2h@R>#_{x?=tPSF=k8V(u?+1Gz6Uo5m;6F zLnXZEQy-tSA8`Z-CXI!Z4C{o5hisELWsqq?fXJh~n73vu<@4y|2O~%3Gc>M|-sy8m z&>z|6kaT-?*VN_^RM3;FPh(cEqZGHDwXC1jpos}tGoeAat`WMP?~;V4NQ)tR;a;n| zEpD=k@H;sWpCuDVD>3bE+}Fdm`}V_(XwqJ~!qpC-A3q}>R&sGzTwN7~8y#pvso2AE zn;kBHl>XQR5k_fsDG^r175C%5OMK3zbU!9VI~ZH%ZWoE<(o@7M?9>|Gt1;y7)!L#< z>?wix1mDEKZEK0Cf3`EK!ef82p*ZNP6BY84-$P3H=j4503_{3>5#sCiELJLAk;e3Z z;Jnb%hVN5r3HHKNH>FHgwI!ONrA2MTiO~qCUS%3mUjpl*@V)iByOLjW)H~=$?969TSkk>@*qCBDT*Tp8N9z8FEb-19)sc7F7U-*Nj|kXRNo%3V6OjDWw3*?sI#N`!Bo`XONApgM_ol$ zDK)#XK3h2Fn@{42#V~BE2 zZ$UoS0pC%zyut1l!a(aA)6E_o9HJ5{mL)>9 zu*|8ebm}BLsJC=?bW=n8(7;$a3;I5Ig!a`*S-&C?E^(1y<{(?BrcM`R%ynM^X~YgV z)ePrw1-Go^_XMP@_gKli=sv+bD&f_5R8An>W3vep!H`&e%IBCAOs^sbuB>7sw@MQ` z*^t=Ud>gg8IvQJG&j@*;dKLqsW>L>j*pH|gFd`{Em<(CQ5NpDe(S6c$fi2XQTq{O|BXaZ`wAY-_tfCV){LB&Fy#?t0(Js&C8&PET5PA zj9fNmP+oj2VcNknl;UlpchM16m~CN1VR91{9_da*^AT850>02xMwB^rQTv`2p2`e- zk?HS~7OuyHa`&@VE7Dnto5pp6d7pZO_9#ie95VH(@W*&U{B*;_r@}A*a5YSHHp+O@ z_ckE7L^jH}yls0$TokO%n8S(Nt!FOVX~9zz%pIy@Nu@eqF3Xa^#)(_7RY_;4^aH3U zX*@xlrRh>1kwnMBaP&Y4|81|hB~|v!7uik((o1S|E*dGf1N9;78KoM3)ueXn$2M%w zT!xu*3X(CHw>^lp$`cXy^nqUX8tHCX1IcEJgtNi#$^_eMnCx6*v98n`ypEEn22gpp zG8m9ZK)@d)Z2uuJAo^2x4%rhTCNLoXQx^hx!??OYE5@4E51A8EBghh3hx}aP=SoMp zCy^bA()+-R7QIV(snm@BN_ z6V{b#Bexao)5qu|wj)-(3ewZz>deyQ!(`ftr&=a^pBs-4(Z;D7PZN=2ESIUsr#iUH zpCrT0+n*byq;k~J!lqK1uJW%9P06RKraz2c5SItxYWZAoH>Vy_vOM7vBli(! z)lpE0p4xgCs@k>0WNkxetYON!otH{z{k$0C7AhM+#y99h8>Z|*$yzAs3ME|tGN0=G zlOpFFm^dpRCDc$Lqo|7WPHDlm$loePk&qvp2YSx4( z4d5Feh3ETQxw+N=OO(Q+SEKRte-7w#DiLwc(ykP08=J|%LiBjCSoW>_w>rUZnt%CJ5WoXVF8jZ{ zL!Ds$)!%w(;_fr|1{!n{4O3Qt7nST%W2rn4r3IYN`H_QPFV@2m+R8kF`dG z)A{>67`EM32L$IyK&Zv;;vYF%WP{>+BVfJ$M-GIm@-7=#&>W}`3e)~Kioh9Xs$TGa zX9WV5{t2+9hc4?ILX-3VE?4Jg@}TSF{~yG?(5HWguE_zbuV80VJ`k{`1J=N0${+-J zhtK?@?QR)}0SHEB1a;9KIU9+&r}p>*iN^Jsr@Z zbTZhV1J9zB7Y^w zE7_*KnYxMP|KqU^0TkgC%NJP3bT)i;UT^QLX%E^+jREc$S3yoQtr9o$+lQkW7hWgW zt~S-e_3xSuL!?+6v(Z?#v}*6dsMN+~KH<02HHs)AIDA&ba8Ojl+~F5%>-4175>aEo zSZR*1GGLy7(agz3y(rEg8mY~AW0$-Wp*=Da^k6)a0pn3x(}dal#u!aAeEK<` ztNg3T=4V`KHGo_b3lnA4{Q|)mOtzJE$;OsjU0}rO??SxfX$M0TP1fn>RUAi41*Ru0 zp;<}e?WT?>d|bsms7I)l>qi>6mpq*cS!5s!T8xe#gJG$C1i!IXdAI4yoZb6KYj`!G=0&z)V*A3 z1~wYIJi$GdDt48Fv>uJ6VIRJEt;yGy9OkgKGh*B`6SRGmefwv2DacdcwDGcEqSYI{{$H(~17 zjIBAfu$rk69o)0ad&$HYL~X808OYfxeP{9JY3_=Plp4sM&xy7bTh^vb;%tT3v6aA0 zI?V09`})asrMZD(iL>>=0h}9F2u(7pYi9{K)}76C66Y3k8J(~_FFu6SCI*H$)=L&ulX2#)km2Fb#+xgzUoj{z_Rtd$7id3u`OBXC3 z5!bUiEy~1ao=7L=*g#5&&q#QuKnE$-@#dhrvmBzCHyndPw4cYY?bg^zi>2BGg!wcK zbB)(dQJ`}wT`)C?P|k7pN{AA+m;6c5Ypm-E?9nD>by2>MJp5`J^?0AC$G?-i8!=`# z8$^o-j(_d6%8>fwABbLGQcR{%aq5#%*8Crr;hA z8|`-_bN2yPf%TP}_W=*)I~BV(l{@tapYBZ@tcG>RUwumrc6hRzVB0KyYWp|6hr$Cc zePM}z^~+nsz0kJ=1Kv3vpM=r&WHq}Mv5gHi)K+`n{tXsTTEsK{8%*TB)3VEED?B(6 zcClT-w$rvt*Th0K#u*4XqHuv;XkYQvnQh)fNFAv5nx`sh5jyc$(X1<_PVG$OXcBTz z3BsFXD3Ds%%>$VB?M$+43ES(!PW1TdBscq&Pv(+d=r2}l;dZ`YJ=TheTV3oYJL#zB z+U&3M{sU*7_Yp_VS9E6tKb(i`-3v>C^=~qv*-QO`rFh~-C4$nY_M6b=3w{fa&36Hu zF4oVHnj1{u{`8CU_zV}bkbHZKV;RXtqGpBlx;c#M@Rv#I?|zhv@TmoP_bGM_zs(|V z$^D}b@!IVAew!cS2NLD<`HS(1xrPXoZSsOcm-}tv*iGht_ow$D;@CacZt64L{T)o` zK-Jg6?ns90A6IFVAhpsTis8x;;%6e!Nld+pPuuj`82?XyXbT(lIzH_zUf-MZu&?OR z`E1~Y;`ZlZ@}wA)*sbj4d9j2)o@>||Cnf5qPb)K8P3aW}4X*Y>c%;&Gd*04<6(}vt zrmkiwWzW`Fxoh4myJv13tjOrdg2ff=%(^s8sl z_R0nG?-%c-AUnO^euUc!J1Q%je47^z#5oRGhmHuCccv_j=|FG~S3}kzm_7^0?o07{ zDqo3*$Sye+)qI=wCPZzLly>JoX7-{6bshZ0i>`Zb`lukC{*>QK0^5W9^b8XE5P_t^ z(0@7*Qi^Ay{rRtm^rA+6uMu`j&+#kOP$fL1NrwL1fe@c4NKa|^&XbTyuK)*^bG_hJY_3-Zta)jHqzn?c51Z=+ z_hECrYA_)W6S_b=wtx{)4B>O39TEl@Q4uk~n2Cr1Mqp}T?QKNHnP;-#vVSHEy2!IH zF!Tk6mdCtr!_86bR=F*F#IjziY`&bboG5fef{n?D6EF`=EEk&bPaQ^uZau_STtaTA zTgIr~A~mtN%3Qu{`4O%pz0jsI;`XQ|ZLht8E3P8B+~r*~oXG1$#=u#m6fYZ%X4AQq zL@B8c%M*l&PTYDZ_>B=pM}NMR)Gm2O|B;m2^BcyghLqs%8p>sHhXJKS#TE91>5~Q8 zg(A{fkIz)@cg?@JZIGIO{j^>Sa1c@gBq1TwRwH7S_a3TQPZO3;0)@_tU+5nBgv!PF zmc79&)972xc#yvf8L+$4QJUy+Dd!lu4i_6G(Uk% zb97m@GPE3Px8FdE4of7`91m5Qj-#5KsTpXD|B2pB;rtBJv_@6E9L5*cr#X%?WboM@K9PB}N}Z<|ACB zShY7+{@oI^sIs-QUZwsq4jh$l0(ceX&riFJGb@UtigCP% z%!f_rU3u8gzzq=eHsFi~)zZ?gO(+;0IVE~|p**8(y5G>yjY#WPrRIhPoj}Xxt?S$1 zz9x4(pLmZbk+xw#$cxpHt=l^-w(sImTi(dw_PTZYFRj~a--+2g{yj6L@tA_)Fp8N9 zXWma5T)rD>Iw2xfo+P|jx7q$Tp+Ou*!~2bh{u87fw&a(u8*RG5?yVj&fwo^1-l2zz z>|qe6%;isJ@W{0A>|bO>g@7EcET!j_;(1)92``cTCr;`U!bEyAxZRQIh=joV$^}TA zy*kMR)Ynu}YWY}b4+^s1#Krz0au zuEnZ44#{X+HTCb5W-^+->MBA);}spMknfuFv1q|6x?G&dtQJZZpO7QN{mo>=xZe?T z!F?=POvlEGYaK$5uR_9eHm}B0rlhFEbB|*mimSmMN>9QmD%&9f+}J8He2!t0W$&(^t{TIkD8EOhjr_uS zL%0CQn~EMR%HQ48YVA3t6DuOI28&thbbsgal5wi~4`qh_{?I;XG`sWd zrMPsgQMFoVvjI_5v_=ct$wziYo84(_a91UR$7abeUgaxj?2(G4{Mj-k{y6s`D36X}<1J9Ug zMR{+y{F|s-yYzt%Wxe4H|6m^sqWpusFnFLCl_ajJZfcI@_TeQVJRXeG@c*L-pgAZaXhq`aIACO$5Wo>qrLz7UNA6?Z4D9wV18GToFHwJ0WlV;=x{a8n%}L zKPP+_E-vml`S*?d)Y_<%FctDlI@u+eD(=&At0_+M*x=v%?8Ghx?h0# z2nOlwZx^}b$Fe{3RmPckC;X;LS^2MNyrxQ@vDoL@lwf>b6uA)3^LV=`1~%8GixOaS zTfZm;Ha`4|GGG(mSC_OKB0?Hs!ZeQLFOb>4i;8*M0)FLgX9xOdpJU$6=CJ11_V|OD z4H0*8#Y4p}cr;hVx%%?{HkHifYz`?vt8OUjX@aEArgc~W4ZQ_ueL#!H0rV9Yz|?0g zXLCmYT9&uGe;lKPgu~X<*owNMov?8&5aI=wY&)eErNOP(a|e6Wnv?dYc{W(!J|; zh1FHj_63?yUQQ-S+NC`MNY^9=*C^@uLBROKre#zV%UUyKauxwu5PswV*f>&-Sa4{oQl?K;>qv zdgUB{`k?i%pQFu0xMoI`!6VT=-Qg*A=JoM*4{Jm0yGvn-m#Nb)G|1x_RKZ~RrNI;>WANB8JT_1>W@(_x z!)Qc#$cEQav~j2n(dANQBb*HM2acu}0nD}T&$t$payH$c>;#%8^bKsSzDo63C^Trd61Yqpz(X-IG* z!{1d&zlP&fCYk6K`i#$L@UVWv<5K?16pcMJd6Y-dqY9<+O972vQ;{3N{)@vZ3RyDm z5}&7b!%?y_bHdc~cJWLW=&%1w$q+gfOdF75}l=kSSjC{yjkyZ+EUp7LV4>!{Z zDeynKP32VAFT%e|)&5{(LLKq_TA$y&kOx|DQ$ayG+(%9_FZ`$LV}7GH8p^GYJPOVL z+r5JP)U+c0W++=saAs~R{r&+<%;9f(yjSP_wJ(D$E#;Q0JfR*_ z+r+s$# zs10pqpR%IB>5uu@uO72-ni#L}6A%6Mn8j z%N(aqa5`$cez&ny#7OuMDqG6#dDI^C={3^f+!R(V1fW9h+*Ot zOi;lD9f>arMd}s}?j@lwiV4~&O{n)TLy2^vGhq4C6|ay?)+xvNm8)}7dCT*_DXn28@Rq8bDn7o{zF}w}zSopS zsUcG}=L7#u5ViTpC9PqUG1_h(&P5+v3PIGOD;F3WR-QnlNe#LUlh$%d8T+Xppu~7f z2kSP4%HB>|ASSEyUtm~`#`+2@G>hSk6wEdseYjx-GsW&Bz6l^SOW=nvh#>1!_Uk189dTF(n) zucMe2u0qQXS&_Y4iLgB@j3Dq7XIfNS%2$=qS&{m+y2 z_y5oqKr_(>c#fv51FgQ3j4qHi-9mT}+J-Vu-v>h5;O#zq2cd1jJPJQSXj>l<4S&I~ zVx0_%GQ&Aem0BBN4tcm6{5H24k^Vh*M`F4rGv#b=5 ztf$s`&+9PVxmF5Z1|tW>D@Z-jU^;{@&_WmdZKb=9mWz%$RI1B7p;^OT0i8}clx(a; z0=0JTPOk~d1{ya&)z4avRkQQC*k{Hw0Oi1UKae=YLIK z{M~B313}d+UX_%Z6@awLFlED43_s`Au906!si3NqCWz3%Xj-fe?SL6TVB0?fSSiSG zD;3k07GGaTphro$xHY5^KU|12R+Uy^Kxya=kcc7>b_vZp*1&0mZ9dul!Gr&e8E~s6_FBa74(B;q6d)RHBnYa)t&y24?s_YRZQ9n{ zzU{XJ)_TaspW`i*9%abRLI3XESGKy|1f5JfhNYGSjOET7K;^o>&kW{DWS6)HLe{#q z^*p;BJ9PT47(KPzGgD8yIa})kAWegi30!kwWgOj|JiI?vpHGP!y`n0QPn94^kJ3g5 zT=6fsOOi~Yk6KGv8G<)O%c+aZdW0WZ^1~n9JuTfbom;=7pE365$`D^O!6XL#Kl#ss z0j9Emg((=a@>UA_ntM5addIPkIR2kG{vTcWA6*k=mBnj-LHg|^U$$0gwFO_cT4?n< zzTuyg+ghK9Cm25V$l$6O6@n=*4(ZtiZ;%i`l9rxL({gr1=-Oqn*nS5Surm4cK8QY%OaAk~7T17_t^u&-!BCYTF*njS~W*iL#m4;AlfV{fPbG8Oia-571n zxeHU5b!0Klv9cB_G{=mVsh@0dR%mv%#s1$+t7u8wOxawS?JVt;lzXur*>_o@(Zu)f zaV`Eb@)=h|SB+-!DGE+AtSnNR1em8#+Q+o)by1S6(<5POAxH4VXCQ6)nZ8D?l32C0 z)5M;5OpVr|Akm^NwSge}+K}@0hQ0V2j@ECBvqaJ?!M}4?_lNZu!sn)jjnSNP@C2{F zphX)A-lR0>PtF-bKT6!)5S};#5*t&0lzBHXfM0y@HWSY-d~r7imwTYmb=o;Ehfp`A z#+5Xp-v(!sNNP~*AMHm{9;2Rk5$}NxF)ViN94tij9{Zj`6FX=(vjdy2MbD5Opg+ zqNJ}~edEFG=FZLzDrk7lEmSUS@=Sd+eD2~RZGsW(r|(>}>9_lS8&`tm1sWa(9ePnu z;~YwR5-%MGT>LMSP(N*KUX0Z;2yW#j!F;)TBIiOOGZVb8mrEz*F@m=$6EA+x2wP%Ef^>B-}nSvRRqX54ZQ}nQYAFMvH}b#N}5RAQA1)Menywa*>8!nne6)(2i(1L%z zWOv%{Q6;&YUdQckDaXX$aOL`C461q{U5z}vJn1w$ff_SK;9-*xdi-#offpUDV6{+z zc&J&f^-5}QS0$4Vjqzdk98a1(!)h*;qEfU|f+pefo-6UJjf6*_)@lNXX2@W zr{6;Hqjma>idS%n3>f>pStDqxbS{-RVB;45(_3!45jw`|3` z)YJ5uT(yI}2)#uws%?EsJEBLu<4=cstK4u(-}O6;Z&*uow7N!j&uQfcewBhd!S=MjFjd``%|Z3;(-tuKtsz!FM#b%-3`-_H6`s0swCt`NW# z&quom{z6F+0=sl(qYvD8bYB~RCgiFSg7$bS>(js$yIL~Gh#l~~5Fpv{*z#>E+%w!P zfeC`9hS%hIeeGVn{*A`@A=4yRLUd3g!SY3_teB4T_96G3Q zk)d=bVVd)2EYfEjusbzmf9sfw2v#X!+KpLZl4!saxQyN78zd{;LUoKqS|!0n!Iqab zO@=Z$x`%m4XXgIr9<03S81xv2pXuoJ)P3nfJl+&&w%5@T5v=Kcg`YBMPox!k%~KSI z{Cs3@eLnu#=+`~ZeJ2x+KmCsGfps7JOr(w|@RQkM?LIvp9k#m3=rqP;vvH*-uU2Qe2$#Q8^EKy=>0%}q>ujpy_k-@fC-cXZ%*@9u+C|zPJ;~L7q z3E^`2YaBL3Iq#$uT6c79BK-X!apO_TJBRiC!AON26q6^!E^l8N{eJb5$L0V3tnEIVeXqB?6aGvGiQ8(ChD! z1y43GDQ7OcLm*Zq1XZ*i7Ez{`D(wc1F=w9jzuZe)CO5Cx#jra8jZ@yUDjL%y#lK;; zAUdqelqf2=9P37+p``=scbVOuRs$(_)lJaGhTbBa@}_V*rLUh^n0A zIFzFo!C%SdM4HGpAWVz5s9-ljnMq<1qAXa2pDVR-(q{Z{*=~u=cKT z3mxVe&zoKltFZ}qG5NjRGYc$kgC#O)EP_ zVR%mD$=8zh9NQsKbmdPxte(0N^BFP-YO<2602RM9aI+|cW%#*H&yhN77sGZx2x%sl zJvg{0R&mgLCK4O>(p|jw`B&N_If^B2zVZorP&ti6gH1qpi-mdeE+2?(ptT9mSs~z* zzldnYrg+aCC{>BhDL=0-L2L6jRDfiddZ~{eWD;E|CdoIPYR|iKsz<+>zL!6NOO$U= zCI(qnO$`+9&2xAylWDIysoxiQ*-V*l5@#-a{Ik|lY9jS$_Hg&kV;i| z4^!)IU}qGCc|wc;Y{dakL(ex!o|EfT!#w$~mvOHxLU~cNOBt3EL(UAd{Th(8~L(%qioglI;{o#uSN{W zsrxb8Mpc@rNmqux_Q`+8@ktg)9lwpysJk&Whebf+#U(N$1d+vRnyI?AhBB9{jI zs%a6gBLDlaR*N3x%u{zt7&QmPM-7#RKlO}mcTpZyCX^dtkqn3X&G4Dj2g04+k9&L z{jS-A>t#tmF%NdgNbP6RU6<3^=0`&kl8TG(%8CqJ{PjjTS~$nU3wm_lH3F)ykS`K@ zv>r@rzAZ?4&W-n(7uH%tCYnfmTX?1r9NueK4WF!Sgf!!In&}(7(<^lTL(PJ;uC|qd z>C@>Uftibvd!7Q8hBade=b%(ZG>foG(~&dX+zI-64cw=lv_p3YeEOI3X6`*@OwpZD zjSwke&Y!c z!1MOC$iCC+I>Du? ztL!^X^;ks!*UFabFK&sO{vAXYRerFO8uq6c88@&NkME|e1#YtDsNrsRIl6tgTeTOB<2VvA@md?)8Q_C=#?>^56O1J%x z_~7Y9oEKcpD(?yF47H)%f9ft{RabVj?Ra!%r{ zv#Rr-qr~f1^DdZwIeP4saUu94t+bp(R1h&rxulBgj z8WLPHu}#XeEiZDFzz$F4xtDQlmYVJgYXFT9?EXu=BLnV({lz+1LKY(yvIKXtv@ zqc+}3IGVyXb0HPjy=ucC#im~`3!bSWy_*{svx0U>={>P@h$;`{2->KT0c{WctY`U4P=l^svSM}m4luWb~6 zr-^vGD?+%R<@8-_WB5hA0Rj9l{}kWkAa_3K%o2gTVu@eHjCv`y#WwyLhQKZsm@l*) z;0t{x_z5A>?X_@$C^4*1E9i8*$bi1FO83nFAshqgR)&?7aR2DcL@$we%oE0_e|&z% zVCcN?ETm%PsB7)sK4i=f)$C~r(-}Lyu@M2Zh}6ssF^SmB3>79Yl8$ycqRLEdgV|$- z;|e+A{)=dTk}k6|G$7a4_KTesr~MbZCC=-cCtOjCB^&XB@x&LVv`NGllqVV-?wBs| zG~n$soEQG2Ac3<@n#c(*eUWsX6)3@&MfzQx)S7#>9AA4)b0S4}yGn#H|aCy37v zD98QT>szwKqAN{zMbZ~9u6sU=t=@#{82kc>;$*UpZqOyV!FNqseS9v8^U#nk@oi^k zFh!_rlZ@>%c)4N7tPFCU*TbmdkeUVSX|l6syg^aDz#mBeT zN?V?qF=;Aha20wPvRDAJck_qWT+t;Kdt>yu3qktpRPhxipu|ABT9>u%Y_ssr7=7k- zBA|a>Pjhp?1l;ZG9+`#fMA`A06N&^q=!zs+b7xD0kOC0dgwiWy>1s_ULH`F3=ZfC# zY4i0>jQ!ZncCh|`u$qvZV>`*{AZzQV>*nchO-kYNvMc`p?L;1V@D>UseP_%Qd08u* zM7JhoiTI*IcX$_SQU@G9+39cb5w6svCtm#j;Duger-5ztsY`it9(md&3Ty;zLAw?7 z@vP?LQxa4;_V%zaOxtgXGTL#EnoLKQF-)T$v+-ric|%-2e1sE4Sf}Dh50R%lX_AAa zy2pK4^yN7;&GZ-6s6Z@a)nLx%=Ds!!)E3~e<2(}h*1x(E`Qh-))NxPJc4y3fD(o<4 z{Qc*Yw>Jt(t+x(kqsG)riOOFN%L;0O{5j3tzqu=p%^A2|RWOitr&QcWK`Bl)~I)yn?68Fl~K6L$XEykzK)>=10350#k0RLoW;8_0!1w+TuhwbZIu;+MXZkX7Wsm^?Gbuz4ot~nAWxqsR+ z6dvW;{+v_KQLw5~qQ#%)of*5-*!_wl<=I3tKKr*uM_d0#qvo9TI^)a+Pt(Pq?*&~C zqyVzsg*PBx75ulwH9N>xDNSsQO~d`84&U#5?g>DvA& ztn;B`jLOQsaX};UyY-xaQVW%=U*nd)2af6l@}6nL{SVzAl#u~h)}w@bB;^L%5F(lh zp7|xG!p7HIIiA{(o12xr)*m-<(gv|U^I~cKbfFd-56cb3ud>33Rn|_7u75t_JMlPu z`QvC*>+2Qf;``ehvct>4h;NqrNG`3GK7YM{8r@znHNd3f;B_m#nQynahgh`2wXjB?%jidCLYQSKW! zM{7g|!kS_ZAFmwIYsh-^v*?3aTWn@mpcUT2C+g!zx@opOFW>1_WG-CP%yk*MRqv*+ z-4VdCH{OUcAZvI$HU_gpZ)$Nv8E^PdgSGxv2Ir@MhcvB!M4+0t3wAH~+`J!(mMN=v zJZHP@%CCRSC$~NpWdyI!JVRamS|R;@reqGE+{@K7%px1Bnx*HUrJp4erACWt%I*0= zjO8=!O6aGtr3eN+3zpRq-e(j!5$*aG42~K{(bf|KMKui=jvAw*HjPZo+xOS4cqv^< zgj<3}r`o{d7YK-yT`{HEd)jV}9pD$-j$Q}=(Ovv5a;NKkDhg!T)fpc*9`7T;fgV`=T z;nc!)riIJ@1zh4+tq4jt-y_;Usx_e+I6;8zbG@GAv;p~fQp#RsWc9IjWn za}kIs!lmS8$KD9y7Hst32|+dSm+${diL=YIF(7Y$OT!DLy^Ic?3N?gajh)%SvDFb|CfzVE28?@yx8Fy5x5ebm3!Ke zgWg}XUL7>s$&>hBGFxBDM7!N+NGN@{w;3yNh7rBM@_p(fh+8hOarxrQYs{pZUV#@fZ?=@HJG41eXc9Yumtb+t z1CvrKi2j>#I6V3QUig&dn{_+AyI#`Mq|~|u@5x~L;={K1$gJ#3ET61XqXK%wX|1Rw z-kA_a@;A*HAi!Vq3lzYH3^L89CgJ05y&g}~4Y}58hn{Zs9R!^0a@1S;{LKD{CWp>k zGW!P8b}y!G>oWfk<-JYGmH93X#g_wdp3!tFP=ax+jE%>K@QMc|gI&?5#ReCRl!y<~mf&p&1L#IMsd;#lSxEU`xsIXweb)9vuC^Mj(vP?RGtI zSvibA+`dJ`R}kKB`;}b-C^^)jKBY*r!zS?~m+x*>((^fm^RFi-l^N~CVa@gwUB*m)Whh{A<`0s($&1g)sY|-D5ZzT_;kB#%s)*L+`$GHy}RCFedZLaMFzEkmXMHhF**ICxUVDWmE)i$G5Pvtp@wj^Wnp1aR)oyb4E zGCQe3r}|;AqXsQ9z-CxjzNJYjQS8wnHi+*XSccwxL{)ERRh~N z)r=mQOLDQ4)twF-PgPW$xIWd}IV)*?=(KqOJnRiqo@5udJT%Oza}zJOSzwcydlwn( zcsEYBC~E2bwb+(>7)rfaN(&HT<_iTM!LgcHrC=9-oAU{`uM^%9d7bKQEoV56+!#8TF_#)-hc&Iv(Sw4E6^&pzfiQTzf?xBa7c)-QN z)LW1C+Iw^iqrjpFs^EGp>B-XI#vq%@_G5Uckb4Ap`rD?$S%%0fTJf}3t=@I~yoYG9 zSDz;74*X>#5Suwlu7bfdQc@xiP>2hUb-g!!7C~Qy6;!Ex?_Ww`?bg-_6o`$lz#*<^7ztA zhMiuzi^hcFtEA=TEiEdNW4IIFArBTfnu!MS&pMEhW0kTJBcTkIj}B45IUhDSr;BBG z*ppDe%+KMsW-YeqgZSN-_+`kIp}g@gA~n+DUi>pt|1(R&%>8p{xx8yZR>){u?Q+Ig zla26*zYJg<{Wa*;xpV*^!1}i$$ch13T~Yvy!hi$-l`tR!z!3mw+PYr1Zb+;zUJhO$ z28jzf;k+Dl4f{l%+X{SpX8{1C8^A6ZQsA-%#$yG%Gi(4v0CAB zQEwlvYH4l^quxTG!KSjXLa`WKf~b0qkA3VgS&2Pe;}Myv>a^@3U4k~sNH4sz++Vj5 z)34z7j0dUqr? zJKh=>!H*L>0VfT>8)Ow4BP6T0xTo}-i}<)^sjXN#(W&oPDZs&M&#L8Mx?i2GdD+5~ zMSa3HO5d00!9M)tYfCe(Z>#*YuYY6g>XXeP&_Z$!BRdk?ln051) zPnAARTdE;%T(|UOIVWj}Ij+eFQ%cUjR6jG|dVUKA$k*ZZce-R!LVW;xSAU;^azR}^ z$GwuEY&bRqPMxV^vRhfQhgR#Jr#{8Vwc#Fe`!!1*gaTA=+!l^q(YjB9!;@-^t*@`# z7AT?1buCw}Nq6l@x``eO_6u9K#2b<1X}^(c{X&sMrUTY7eys5j^S$!M5N!~;@=%zD zHU{z~2+8Iy2GFb6ub$5i@wIA1Qnv=H<6z^zhjJuOQZr2$#eAj=Tei!ERPHe4@2T-ndSOG}sj z_+y>hxm}R&ETEuC{DmURbbO3NT!%Jl#7}pTf$jBM&v6WN3yV^c;-$JaR~Ge}dZ;(v zK|@7Bw~^FEW6&B}V8AKPPn@l}1$k zYe%=e%$(&oDraJS2i~OzW(}R1_$Eb%?x3QUbDbfsuW3r90AIGzB*NGjGen~N-p+EF9^+S<~5W#=IJ!Ls;Ir;WL7Hb%Einw#}SVW;J78aL+;rM0Oy zzZxSelF>CTJR_2B(Yqmpe&&q3Oh?VPBR-=&F1u&9k$iJdu9F2Q7h_y))!{ai;O85N z+4-=xNBJt0tLp|Eb2P#JaZi?a1AHmywT#EXw(R=PicU+fGf#gO#!>M!ol0(&L+UQv3*h(&yNfD;a`gx^K3!PX)7iui=n z=MMV784lU0Rhx4#rhTb!PGtLLbmp`#!e3?W6 zAQ%8P7>EX-76!rraDst&0M1|_2!M?Uv_-Fq9>Wp?LjP(@`1m|VC+03}U`@Zc-9SFjy|63f z+;K{odFh5*qdAS-zo3ZPqVJ-TBncxhk1YJ@f#!^B7)KG`@5?c$=EV@skGi*xExY+$ zaEm_MPnIOC@GP?M?KP=0E=Dg^eE)&xpc?<*ctF|!q$fgv^bU}yegYCA86fom5`z~Y zAtnIQcR(VCkwO7!;5@4Et(J&0Zu|&ce82o3K%&p%M@@d}jC%>UMIVVUsFwINvM~QC zmaO;_^7#Hkkf|8BMPGFnRamzVibMm$s6Q}V0mBq9Fv1vqz;Ff(ZNM;+3m87Ya1d2E zf&6}rr*;t~#>U&g9ogbY?|8mYE%5zU(SOx}jU^om}L>a{Z2ENFgx?ysUe(>EN zlu;C5poq+QD??WQB7T_4qaVe4P??`RVG(6-8(VPGtE={SP`)T_18ecmFFEX&6O&YM z1HZhbjQNEVkkKOc)aagD?P14l?hAe7$j+AK4iCAA9D3_W_U&c-I2F-Axwn)VKX-yP zn$<2K4Z}$3fbyH~f@=2PZB9 z9H&k!aN@9o`B9z3v1B*#kipq~6e9^sdj-z!?lVC01tdXCK-vrfBtbxeAOX@Ij6?!R z;V_aD%o92w)x$_UfRus=NRu!UVPxU;c##h>8#|WZ<_UsnX^LZ~UAbxATFeyGH5yu1 z9JL71tu{v%OoH8f+(HS)5;pEmQ!o0l-TM00GQG4!|Qe zu)G3b5BtiY?j#bFj*k?kq9R}L;(c;uOGOp2;6?W2%8HyuJrMDhf&)WJ(v+m@yUGJ$ z*BVSLtHd_R9?t$25Ov00|3SyvA9FwZzEA&tP|hnX?15{BH>;>nt=M@!Y+x_`smB$!V+fvChp#S1){~W*>Lmx+#r?X9VU4M% zRxEfEdW_l4n*4Ua18n2$6W=^vLoaUI{q?ks3GEJk<=@vE33jO#$R4roHD0LR-M@^7B2XdR; z{;TS7dyG@8-63_5!V2*zR!lKGPzS2!f7EB9yJ?}IP%$V}4t!JqAB_L4ngMc4KrX}F zv;`plPgPoT)Odtml)Uc3jK;p>4N4ZPMt?~o8-~Zi2g3tSP|+Juk%muk<5}OlW7!7< zK23#UV#eZW^c3}jaD{TWYe);&JrJ@9?iw`|3PIL4^pxrSa0MGT$ztw~0(GJsU~a6n z1`dbzv!`F?Xb=^;Dww$`+r&;V#C>~R%pp+9EwlIEW_tfWm3;|3lwJG3tRwqU#=aGz zP_`k)zGQC@l4Z&+OCgVK#0;_&Ld4kjT`9^wLwZz*5h81f8Ec^!`fUyo3(|ZCxI78|r;gex+z;nd8L$|>z#D~(> zA*E7jxx}L-Zp~W6hqdPaPE2T{u-yViUh5F3exVD=F}v;<;$Be7Fk_}&As zW=aq+`wC7|YsqLr`oD;Joc&IZ%R5-!?%TxW*IJ5{OQl0dk|(2@4ZSx4(gCLga85-N ztN`c#Bq|}mVg!V{X?UU@Ac=ytngZ6U0a&ZWoTmRj^CiHR0_=1=u?MiP0rn%nwgK#F z!2S>B(|>&-{_zUE6biFH6WD*5gnc@!>{a1E;>l80^-jRl+KB(j0~Pl(fp7Il`FDpk zc`MM02s-a#=J9ehY;B6CyXd>OdX)utEwyaVXJW0=Tm-=^xD*21*ciancmWYUm{M|?QP4+cxr znyH&-l?zIk46~$(k?2zTaw9a;&XMR0xwoiF63LMWy?u?9`OUZ?{qVxgi+K{^!{Ua5 zTmKMm-6ZQ&6vHo`R}L>c#Q$)!25wfs?VY%xBXIktC>j2)%u~F~Ed3S9qU15zvZ5Mp zC0X@<6ODnhg=E!0+AESA;Qm))0m63QyrLRaZh1-FQnE@=GW{J3$RXCyWlI~x`p@Q& zGRsSAVALFhZ5v1+2#`!Gs;5q+zdK*@_&*!#027SU2AI~8Ro~gt6*3J;zB&Qwm$a(C z8{XM+pno(aB|H*(vOA;>W3!gdy3{uA`O_T?^c-OuUTb+NPb&T0!hb7918#xkB}a+$ zcU*w`Ux_7vTLHM>Mr8o*eF%5^n z;U~+Ja4(sn$Ux zbv}{uq*0bwdJ<5x9jfbDwPpnO{nCK(piLu)njwzJAiz%GGCol%^UT25u|6fUeMa4ZJ z$U%U9I9Ymj%*goKdPZiClkC~MIOJ6x^owqJ+9YBJ*Ef#RP`&zxuqvF}oGf~YXk1XO1S?XJ%NZ8q@kq;x<(r)$iy>NYq||QBO0S!d^Zqmf1Epc9bmy*P_D~?q6Sc zr(GFpqBG5h6)W_GCm(r@^AaI{c2Wd3zieO|JGAWq8*>cDpc387xW#PrC!Nhcod2Pl z3Y)(F`hz<~%9%#pgM1%O&bc#xW4|F!7ZC@`LgRG!`f$iOO(8SqrVMm%HzP$xTo|D6ThU)=>2|TQLE@cl8tJrQ;J>I}N&(#~ z4_)Rd4sjbEqk5;F$_^dG!oz-?@q$ySzbrvHlgRf*mTu>s!#Tc0Nmm%m>WyE0W#;UR z6_|`_Fd23)7zYB3adiM9Uog_WjOS*4a7>O*Rmv5Xc?nEh4VXAP;M)WoZoH7Ejfj6q zFI%2jG-G~NA6IzwUX=a|KAO~c<)hN++~U|(Ze00Q+S?W{khE3tf{d+_K8|HYa{Hvm_jzzV`nVjBx*AA50;EoR%%77_^0S1E<(rG^hcZsAU6uIeANNWmsIGaa?t7hxTF5bYc>~RiWu}5^|=zE z_oSg``Rrw{!kV4rP4gM_Hu;IS3qYsKmAIH74ISjNmo1cOcG7Y5!-4CL0@qD*jePIP zVx%s#Yb3bz#64Q&9wdp-=D*WL3K;1s2^#sH z6I?34owU`Z5Vc%^QMS2Ar9~Dq)1po+PfKpc$!U?l34q_3Z4xc^y>4bOJ)$feZo!4w zJY&y}C|9KLil4~8?=1`d9(bF-R&;mfeNxHPdB0GRLO*_-g7K6m)p}7mQ|CRPPy&iK z5GPv=((DQouvN8jMICKWc6r(KgX2hIkL z8t-Rmdct47x0lQN1d56ulbXHYh<XR{=7luuaB- zk!PaJv}Eb$cG5uEh8I--!VXK$3x_}xfQ&<+3&7|h&<3FC5az z66ygPz*vpX<~Dujxbvko{IdE7oc)UX8JmIV)cbeM8G{_~_-ksy-vv?y!_nPc>-+C%%|3Bx2S*Ih|JGz2R}DEocf(W z6%|54gjx#rkYEHs*btYm>>(sFkuV)Utu*{_2^UYHAXi+ z!lQ)D!E=mi>mv#vGYF{#Yv$M@iN${+FTp13c9T)fMoKZsQ=$+pa_OEC-MU%h9$7k{Pi?;sE{#i&e@X~1O?ab+ zT|F(DTF|r9KjeiX8}Nos+8(whZgmTS4h`c=Z~`i!t)=w5QC;tf!t*w z4u|gb5rH?`oBF=Zj!Vm@Huu`!ZtQ9;SQl(mz1^|WX@0Dg#1q|L_ftdKlMF}MK%yBI-Z9oi+8|8SH^fw~h?6|o@By%9?rWivR$Ex4IJ{{Vum2ZNwk(g zO6(pjVPxvi;?`c3l6U?+BAQQo$NG0U%dqI1F|X>(apqgcB)QM^Tm)4__3`K9l9Q}*yM&>4_R??!@q~DH@U&kL%uY*k(9XA*SwGiU783Skl|k9y)~dN zH`2768-c9$9alSeHCFx-^Z6Ej)x<}RawFfyd?7}{s16s#x$ozDgisxB z0MG#tu@_Inp|{_gy}H0U7qMWcednMXirH3&qFE2bud&X7*g?J7p#%FU|FvNJE^5aO zv)Q${1|jMX=IvvJVCeM$YVM53CK{FGQ^Ir0`OIu?bb)tZ=gYOb-)r)V^fQxKZ`?AE zz0-hJ(ZTW$|I)>i<2U=oQ4H`Ir*=3_KJ!bb{~bp$vMCnTYqdzV$)xS4!j!^B-8}8j zuyvN)=evC`Jne^0ca!3k?AxEeG98NzI@ey%9J%?G>BT#J+7Z>SvB($S{R=}p+?3Y}g$2ub3Il}wHK94fhE`xq4)v2*j%Z9nbPQ3bdM^HjN{8%X$P}@EYU#CT? z)s%8cvyE(c-rPKa42K)T*BidmpH+U-;WfLa#(cKEU7TSQvh=ZOKTI7NzSlSqu5TmQ z@!rDItiDK0>I&DL>4&43tuNW_=MVM7M;nJiu5)$L^hi}3#_BfzNdOnZUqaB^ZC6fK z$ArR#80UhrZnB@QCepv6%Y?qkwFt!zJB0+q$=;bJ!SUp6@460Q;Nu!u4@VJ{hI3^v zWIB|5!+78~C8rxGaxb=YS|V?5o&wp3aTV6J&y#mmCI^JOV1_e*`tWB);2K zjW9+EyiH$(xfm5|#wm$kk7G147SLNg+s!_)>o~zKT}~W4X@{r#{_JbbnH0J$7^?4q zL{!I3_)V6Ejz=c5pQd{0cw{>bvau+g%wwtuU;Pimb_GHS5Yd)cvFJ~?%$N&r-sQjF zcFcKvvdb2KGkAV&wVma{r+9my1?JFFl(3>(oAG%YNT^niubc znTm*$g%+?>vnf(8%Om$0y*8Eu@lFwoUv+C4jURzeWOQCf&U0O@?|#VFtP4#vjCEkA z4Gqs20GkwIzBbg+qm@U5J-M%ZrJmb7 ziw9r9$GO)RK9o_n5oQ&+K^8!=#u3aQXaj74L?o@sEHj7Y+g@&-NDaE2)6%T8DK@Pf zSL=^wVM}oImo!sLxG?ITLu!@9`Jo2ZuJjSgE!k&7mkTaX zF56aiba*3M(3{#oOa-ZMvqmQjp>z5I-nza`wKY1B0J;hy}hD5l`|(wdauo8+BUCT zL6@tF{pif??OS@%dfOy5Rs2cR?Q3abW)fHHLvKEQlp%Yk--1NpbTGfyV`OMBrl}lk zIvClN)-1^0pQkNXv|VM_{TljMIOf~Ax4q!U%kBOQjt3=*qpqsD5o8^ zNgl-7$v$rrOwy5f#-o$&EjoB#&x0yoAgOu*T>RWE2He_k2nO(`%azzO=2M-G zuX@jWDvqf>f38I(y_}1!<14a-F6UwE1PTVJZkd}-Z8%~QL(TYN)zY%1Iv8f> zf!a8Vc0%&y%i>J?iNZYEPEre-tTp$MGN9{w=pJn%zZA!AX6^)c9xd&WeoCckt;cbqEYZp&tEhg z&6G>{$Qd*?tE|==7|GZgoEJr%ty(5to)B#hEW^Bb#R1|4QsXQ^lwdL3g^x5Q5I8kp zDIiBSbv2!J#=v8K5`<0pnuA%(QsOBd@fn-azVq_k_~*t1-5>lqekmc2uuPAT2Zapc zawc3Jl+5~a-nE1$$NOEga>bR|nBB5+7p8G`%Tl2pVUcTz#vLVaPPqKJHZ6XYFc0UD zI1C$X+G7KL=E5wdjOcQigyS~LR+Wjd$W>fpyEcO@>qYX2%oc-=y?my+jA)fb#Cezz zUJuK31)DYOvp|-po&{#*^7n^jePxH5hG#jH)Kc~zb~`-SJ^400dmijQ=x$PBf5P!Xo;*{qjf4}*J#WHj5t zG(6jHKJ-0m8)?dm(a*zMHD7yD)HAB=wDJsZJ)Lzt)I>#Hn3nc8S^?$FrM4mf#Zc@21e=8 zP<74xPPbgB55K)|ebVf=*(%JJ zC7nqHKVl=-Dl6^8F|J$=+KI_~xx$P+y>?)K9_B6ogb@_8Iu?u<+V`>lG_D~S;{juTysvjYVE;+KEwt%6@F*I;Dh5oNy?98_C_&wvCa65Nzj; zt{PquL3Gu2_XVX%IL&$Iwdg{zcLSHcFi@)PC5LP<7Hw{xj$|#_NTO#r@puh_;cGE4 zrsncREp;(bzJwt1J6~o`PX#4wWY&S51NHEDyU@5@r+IJ3f{T=itvf4J!;|RL(MU6T zOh8NcI(wux^-g25uXP1)v`NB*bww}k%|yFiHKm+yLW{TTMq_WLB+!iOYahuBw%e_k z5V)G(e?^paXr*WLk$C2b*Jg|>dwl1N?;U)2A#)`5z+*E9ebxgPIdK%&718F%10~0{&YE#N zi^sOKU%21>9(F&9CR4%&nhG{yRwOVM+JL5mpe1q(ZqP2bz1NJV84nHeh_`iOt+NQ> zT0CXH;5c_~f0#Y8{7!D6tspFH`EL5mdf#z(6eaWYGS%IsnRV|ohygkvK+iDaX0rK< z6lu`Dw-RHVVCF726F&TwuZ!MI07LrE`U8iw->0!vy zII~QxE_7nnPvGetk-exuSzUEaAN2;WoN)0#}1CP zumhb(*5d6mu=6JKx^{l)8T7}#l{`V_Q#<;#H*1DdLeX{$+p(L+B;RO5C?bRjzHvA^v8(t@BX37xQ8J4@=TOqPL z;aL0U7r+~c!sW)>;jk9Nj{;+{4PGCrlPg9&Bo*S{*x(ef;rfwuqkfIX+DD$n*i9oQ zfod}U2>+F?_e`Y7P6ce;jhRkGY>l}RRpadS=pKQ3rY7kj3Hn3fvx*b1Pj0vo^z(uV zLJX&ft(zw2uv^gq%x@b(Tx z;D;H06x?7#dYyS8sFuA0r@9xGTnPC*yFi2LhR5e6Sx}w4&rlCa&1V=<4$Nqq$ldS3!8x*!VRAGVwN`D-hZEH-!z24lc%f0BFM=42np!s6 zipIt~S%arf!J{NoAV-9e{CaCQi5>%+R5yaokEga_G;6(E#TjE-nQ9psgL%O-*;~xyPyi*l*1k62!G#TmR&l5yQKqdmRJ5Q|z>L&hQQmDD{^W zFMNK-a!?a3hx5*tlAJv44DvlePW;}gJd*Wu&=q^g#(9+S?>#MCae|-uCtd4z)e1Wp z>Yn0|k&_KSzOZx%lJgEWS=9HJ4mL(3wmb z+XKjLGp-+m*n>A+5yxlMjVfua6G-XiFW4(>wXBTFedw*E3&u}cwqZyah<${QQl+Ee zmQe-j)H|6Ha*1U}+M)VfrK8@~YgoNyMPnI26QijF;%}Phpt=APO!3Z=L8wG`;00jm3`*{>c9zqXiALN;H(#q1# z9{vGmJbYYzWi+iU4a^W0(gD8({5{r^@z!t@B?W~R_1|MzfDwKX%lLw}uBnCYuVTe_ z)*>%5QBWj_Qc&>z%!-1dIFbz{|BF~Ax|W(cnwFY>PfC=L%_SWq1p!HM|0Phi@Gk=) zbhXV8I)4w-Sw^sN1au#8LjMxR?Zhv`SR3f-8vi{?*(e-F2iP>=6#7e)youqny414M)_omA)n2t0FpAtkUD8A(X{c;KNe=rZ%g)=e$`3rW_wav$$!8&+H zOF;ovr16|1an!-v!8AfOHI;hp(PLkK)LJ%YV@Qkk`DBZZ3}h tCV{sXPcYa#05^?|>Td~<{)`Y9;4iQElTHINJ-oln6cu2aZhSeE{vRD^h-m-- literal 0 HcmV?d00001 diff --git a/.venv/share/python-wheels/ipaddr-2.2.0-py2.py3-none-any.whl b/.venv/share/python-wheels/ipaddr-2.2.0-py2.py3-none-any.whl new file mode 100644 index 0000000000000000000000000000000000000000..2c9dfd25b4e1252b1d6203e34ceee0baba494067 GIT binary patch literal 19552 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 literal 0 HcmV?d00001 diff --git a/.venv/share/python-wheels/lockfile-0.12.2-py2.py3-none-any.whl b/.venv/share/python-wheels/lockfile-0.12.2-py2.py3-none-any.whl new file mode 100644 index 0000000000000000000000000000000000000000..66fb5fe9de50c4145a1a097f87a142400ae85858 GIT binary patch literal 17238 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

      oS4SD~RY|St*hd=!XX6PPX~d( zEw9n3@_b}7cftZ$gmrMNRf9m5#DaLJ4{S4XguWQYaCx(d0R1QiZRC&b4+lOFN|5Uq z$rWqmInzY(Md{QBa^-<8 z5Q6u6Rjw-6x3B_w5reJN!uEMl+OG@VA5K{D4&HMMo_1|i&ojkV-)FoR*>s7ep0Z-g z5#D;($gDwDB2A4&fiOWyKoYp1>>2hHA57H`;H!|)!*`C*w=`tSSTR>oFC}<}&>F;) zA(sgSs?X;Iw>o5iJ$1o3VS+HF6S>4r&UU6VMOT?T&vhKI`h`5oh#e16klnEW$z5Ua z+1*9IfT9mXT)9cK*-%OarWke93MXb_GsO9Zosg|HuE_r4Om0(1?}NcKTk-d`2SGhm zf~|+|uAPN|IthT7kRQdQ=o@f!kGy~RxGk)@u2wCPUz+%6&0G)>f9Y7KAa}uDdiW~m zm~UCLMfn3rIWtMx_a&~ze$N0ejz#5w(mOi>F$*!_@oc5%1G)Z|?IdY`E}0!UJ176W zphCm1P;ysdWVRo!Vjn^~s)6ti3tD&HoKR5EFF3qqf#h4bfZhx;O{ROX3r>n2_2PFS zNg62X0mCRv!$Kjs8XX77^({}WKfju$iK!PRPGWiOzqJgCdZVt^KbSl*yevC zn(n)NKl4i8=KPURs_LN!AOv$-!joAcDhD9)5V&MQ0le6@g$Nol(6;6fw_9)H@4jgA zFvjo-A+WQ4KvkMoxCso7)pnGZ!>z)=!1uSOhyP*t5P6kkL<^9QzkI@sWoOcObRh-! zLxuF6zjoRb26ZQGNz|cIewaQ@ze}={CS2IWeEcrWC<&DL$}m7g;+=3QF!?~X?YaLj zqTj26KO-DUH|m52hhLjA9OP0Mu`cHfc&WoO^SY(_<-#ouZ&Zgl`RbE<;wp!Im+W?X z*%b@WRDb;v5SYQElm~vW!2tKY;(GfR&0O+2Zc*Mht<0G8#l6Yh6RtR!_eH;1-s`P6 zS$v?qxN*?EN;Wu|h$OuIe?m=oO&9tjzBr%KG!~8opuAX|YW>{m51@EaJmqQH8Vq1~ ziCod52ECu^tt6U>M87fKyRNX9^`*SQ+!OwFGVRNL!@1Y{D>5vsxWg8B&vZK4SU4Pj z^TKzU*=RH#0DOr*LR|KB;Pj8DiCdBM5gT~Rg_iG3rw zpIoUo?+bpDy8n262@T}y-7k7of0{A!^Ib|SJ!>s_eaCU;3@I^Pm3LZAlCN5$WYzw- zN8TaaY$n#GJhN?C%Qx4DtEJspGTz{}U?7-3sppvzJ0z2T);pbEhcwB7N;yWN6Tilg z7nu~T*VHo^Pf#*JNbTolcad39SUPoE!YG#|s>dg3EmAR-;D`XrJ+7p)a)X6D%Zo1! z0^bt$If_N28+4Y0(Yx=dDI-!iC?M7-o=B@Zs@~h>^L_}DoG6dVAXa9Q(Knw`(K9i` z+={x2e1t-CWG2#4%Z*iTc0<3AGDM;NSY3B;KX8_()yJ5&o10VHVJwJf6WU9~=S=>R z?=1O^)evG%^`q>jnA~c$WJZTN^~y#*frn9A-)H*}=?5jn{>IjPeIYN-o|cS^@B9v0 zGE3-~<nwpBa)*DaoF3n)Q-8 z%o)KJ4oDbw^{F>roX?rJF2&cC!06t(Iu1bYWBo;SRf zZe}W2|HhZXclNpc%%Q)zAgAEtlW=9JP;vCEYAsSzKD}PoAXnA&Fr{Kxiq2}k;^@5k zC`_>A#hEKN<(g%b(4Z`3S@EK0Su&0ggI7>GbkM^?S@CxDM_(lW99YtW^^E(Lw0)g0 z-!@k;4G}8bBZx6( zwChG7-T^&dmC&6!WFCQ2#-A;Mw> zXf0D~^xs!Md)P-5w!Cs+uM1n=;FIAIY+d^HFL%*HVkDj?wcY1FT+&IAh}h#Il3cvH z;!qDe%l2Qf@mqXTciQ8i^nksp;bqEguUFnt)LsiDty!@TYxDLh;@iY>j5?qnGE(Ny z-O;BweHq)_?z4&XRBz0-g%=EX%p3E)>r9_KXWakO>j$9+>@`t;;GNU_TGshbxGJOv zG1y&coT1v&Am-zrq-^=VxdSW8DQ9zlK1w;i%+{@5=M+?aJgX9X=CV-dtwB(&elNH0 zzp_`e_T8SfQQQGg9ST^SlGF{NQl`_5)seW~;%x*qpX+H9#20YOA3Zw)LMLvPW*B1n zC%UyV0IE%9e0bYi8wBAKk1Z%7wN(M1xhDNsYy$<2#z7eToffJ>%SH_P_P zw|*{meO=f)g9%W+03PmVvHHWlb!TkPvs^J5aegK;PMlUBvJJ^kYm~j0nQ$xemqeit z>a&jU{q)yCG1!B3r2iC6^xSehV6n?zSjMWoJhPc4G6m1^E9|YjdHXQRuSDJmJ4@j^ zo{uQYb}fD|5OIi(cnU~v;V*D>h>qmh9qP;gv4Qhz_`>G!2g57uY;ON8DM zz(5~KYb`k7&jg5%(Fo&huS;U*Ur+!O67FAs0XLgI#lpV52X6j;V?x2`2R*Ku?T4oi690Xp;ja|sx&^O^v-wwB|5Viy&G?44)4dr# z_zd}q@piBi`r>vcH_->w47Cof+b6CfzY*^0RW=HfFXZmllKWLEe6-RP^u2rxU!_+( zQYVOvUB#~}RaHEbW?qrzPRty4-ETh!n%4xX!M>pE6^guH{Pto{*p4I-q-g$l6FKD5&>7}m3`Ud6Xn&x!WOw3 z=_1hDU5PiZ$15DVOSnw1tM~C`u>SCoF_tYbd>4^-bMRVfcSaoj9VJu5v6gLf@QNz0 z*Cw8=wPjyY;}(I!e(L_U7OJbah5!4;HMh*u zOL?PTO#GE>XU_b1pUG68>96_R&;Mi>u~#H*rV54!+^xj zuFG!CkP9poO7u+phMb{LEKh>v^A!*va!5gaQ4NB^!@^Zwj zE5}sRD?hL2+4VZiTAAS#?GKP?r__&X`)yfNOm8eRSFCUmw^W%;%Zk0;RbAzn}PI6+1}u28Fu zS&dET>cfqFy|(cXz^2QkH~QR&Z|!-#c-F_Vr|-vDQD9P3kC?mUko+b3&MuFnFB z$GMewZxbljeKTpobZbW}`sRChuHGc<<(Y>JWlja7ImZvYmCI#E#So!JcDgH#S@R-R zaz>N8ZMQsG!`*zJ2$si9B|v21)#b&H>?hnmX!>i(8=3_)@Z)f|@T8{KA{t+DGmrPZ zQ=>Q(`V7#UKh1p6GD=$$dq~{nsb^86R*-3}hsp_w+pmh4{;uz}6}PMJdyGp!MbfW~ z70<6@?dH!?1${jHI;5Qb4Xl-0m7ncl>^4+!`{14@&ETOeeWCCcQ2+5Fq9PB3!h(Q+ zfP=_}?ox3=jfcVcwEgFT`T0AzT7gW=>{yIEEL>b|oE(`!-VE|g^wU!_>J6H+th1`D z3#zR1dyo+SlZ=2s{z5GP0)h_;0s{O0A!FfXW&v{hq~rQYC|-S1X^0iA`;g(=eu`W< zY0xkD2t)^vIxR=DB5^vV7TTt0W# zthcElI%C?{ZiZ5nP`TI8rK}f*ro(Sca zr}coRLMWmWUo1M^{opErF$LHjGB4{MjNClcM$B3cQOo6#j;eNw1+6BK7*{{KrlFbM zv=04cRv4=MBvxVQ59)Bv${M(Br@;H3^g6Ur=thxKvyUCSVf;M+l}eq^-(1e+Xv4QU zO$M@j&5D%bqrRO3hI9Up_qUD^UqS6MgfEqHy(*ZN`HeD~84N*dAza=z!aWv}OqLUQ zfjdErQczsO0cL`f`t&(i;9-Ja7R%_YsFB@S%%y*_ak@S7uT<=G^V-IIQgo<;1#Kjo zb|XrI-VAMzA6{0AF@6L``bqvB8v_dnqZ=i%ZUn9e(3H`NFLX_b2SiYYS4fi9L`W`G zZ)Ld6mk6qbFs8{}O6LZ|U5^|ov!ZfmxIP04C&tO@7lgkAa`Bn2QRo&=*@X4^YZ?8| z@*VW7oZ}*ffKW>LpVh?D#NOWYv%Y+m?!J(n>l$y$)(u00+&-hXc`fDP_L0=zpJrC0 z?$c((hn5wVuIyCeIHMR(b&X@dxh%?D&bjf-*58+r!r$?zJA7sl(kVrDHMysUblKH*RraPzX z??yasq?lK_Aml7vh7S<{!UD6KrlP*&n{Px*rW zA?o$!zk&$$y0_DZ>Ibl?Zdhf45rMH~$8AtJ-KGU~J4sLZukQcQ3u*N0;o22XbHF@8 zdf@|<*L;G2h@)|b({QcFpm#?(m}GDY;3b*sVeK@V@gd81eui3>~o@z=9TCV9#d@5ZGQnd{5YfxErT(5N-V3 zJuJV_4!>j9l)t}m?N}!7EFJB1%@!}VtF#5wV$7E2L9%`VJ#5$gzU5J83FiLCdav#_ z1Xu_%_Q1f|2*XH)5YdHpEgY>@NQwED{cA2HUh3<3l&m}I({DkU`8h`QQqJBbb;_j5TW{{SS35-SME?9j0>XUD0$b+i zRM8mP90VWJG*wH2iy>rBWW@0~@P*1^1`)gY#K>VjI7eMiP%L3HGGTJaJ2~HrWPfPt zeBWit6ubpYFDjH9x7gX?6KxpNOs_QR%yq)kZildxJf6$fZX8B=Vw z#aUSrdb%()AQgi*xG=;b>b#yua_ga#q1S&#;%gt(n=ownq^v2;cagED;rV1`GN1+@ z69Xq^dPY_rv@u>&QCFM_P29)?iHo;qtI`j+s~+cU`S-7K|M+cIygdB4eY;(e7jpJ> z$^B&*@IoDfTX00SGcbxZRn_fe;cmetx{b*CE;=;MQkwYT{9L>OA?k#?)f4c6vUhoW z7yeWic`>bwk|-T{co^B25D-#GM(MMxb+JhjFuMuvdXr9M4tN8x^ZUQt?>*jL?hMx? zZKD4oXA`?<15%h#xv0r(9=)M?BCE2qhT2G!Kfkd4(Wz zS)3o<1gFK(mZo|3QJv-A$OEckOEfT_VIOcDTDyGxB?_{>&)SPgO6>ANh|pPJUQWx- zM@XQM#16~pqAKA+_|koL0GLV4{&xu>09dtG5;Fi^NRhKZy#ClI2B63zx`pM<=}38y z3r33nvT%#jYr0yLH(pr+X_xvvF$`xfC>Z+vjq+0&hFXpIYG%ozg|t`i;fgqXSGR^) z|2|b$_EpjuLcalbwCJ~fdN&gYbTgY##=N!$O@c6juvED4f@^U$ha%^63CZAXo=Z)R ztdSd&s=Ncv7~{(@%WKK)2W!zRZlw@$HBa#};TtX9qXQvLxnqh$dr{#Huv%35Xr?{F z1R6XivBWh4Jfvct7|&L4CW=y`CxhY~@BnXt*UQ8a`-m!kjXTB`T{^dO7K` z;1#-@T5<-tz+AHAR>K6s{kQ;_!1ZJR8or!%L9M0u*|{c@LGAi zkOdve7c#?2vKy*Gs09e7tP@tY_;mP0;L*d!@TambHQsSLR&mt?b!piHhJ-S);1L%WNK?=eP}m;+DhQ9L9 zVljXsVta>tvtd@qhs3~lYsxP=j494tT3~htZ*v6VKgvF?YE?e@b>qm-Mk})A@p!*W zj`*z(t%!QLVjeJ`YxPKpjD#m#Zk`yQ0y-EyIIa6ZzNB znao<_DJq24le7M<897z_xi0%UB>Gs}O?H(O#IxHT$J}Fdv&8h6hKqpFCLVa3m0Vk_wv{{N1aL@rf1z-KbmK zGmC1DzJNDEAq^m74OM3|{n3bnYm(Kgm$X5auOBX${) zTd8U>!;B)?MZ1YDIJ0t_`54G~Gfg|IPf0Zvqs#`MpA~?r-_{C0)<+Q@Ua;?iKlkB& z&hTRvl^@4U^P6Dp1-kqzj!(6v^4I>o0~cP1sK*dKh{%5eut=tYLSE~^7sS~FG0T3Sp^-<~g7lZCOKu#=+JnmtX(U_8 zLR7yg=Wk1ZhdRxQechA+5te-@fWti7)6!V&`9wn z8e$ZqB+Eoi9{0DD$vIeUI4P%e3&hBEpn&8WLH~p{8HTWTB|42))Fqz0nPw;PgO(|i zA>t|Ld#fJ;UOTbypU45$^K$F&HFjQ#K! z8CDc&O)@XF#H33xclGD6nNNQ0Pq;shL39daVK;<~O@nyvyD|gi3~>uKn=Lr1LY9@{ z&TI2d_iWs<2Xij?Qy2Xm?NLR(!MB+D^c~4d>UsnghPq_77$ePY4N=x4HSy(^o4C4= zgEoMuezwb?gDgp&l4^mlj_pRVm0Zm@96$6CGOV9Z)RU|Fb{zTMGH*dkCo+z!1k1a5 zj%dvUeY%gld*r`jC^`^je*j7BUO#Va-c)?Wq=#;8(T>!YGQCDZc#M`9a-)^t2&rTjno_%f03-D@6K;QjedpQ@&T0|~T*-r{M##AasRz;i8_BpcHE&C&p1Wdde z*kOt^Vh+?aE=(FE%$U1=g#7a(Z53OofE?vmi$xUyja?7GAi>iVtfcjE+LydnogkHI ztaH@y09<3vWu&5J0UrJHhW**6Ci2lX1n2vOVr$FgOi$);PT!_>*M97-%1+PzoP4EC zKJb(y<%NBIP>=(bVkLZ=gYhO#PQBD5Zp3bJf1bQqM_;3B71^H{=?L@x)7N=NHL ztLiB7@ODR4nC_=xJJbwSyqi&bA>QTT$5G!DdP6Gr})2Gko#6Pf0iiZ>PHWGSC_?D(UP~ z5R$>*lXUC5Pp<_Dr^t=Ml99}>zt#mQ(JdXsY1JT+UPEu#ab#ZKw>X328MRN5K7br{ ziXl*|d^%eQ=@J0x>ZBZD-_$Ce`_J8hh2`y}>E#2#b4#Kc0quT<UF+#LVP zcm8vrj;R$|pAw;=od5C}jF)pifA8=e^g6+0tg3J&D-W-D`X!kRI(?)xLCOfE4OCz? zS`cC0h&104%)t+=IpZcH1J)9IU(v*E7zA*RO_q-JaH+UnP42oq zk$>>B&+c3eYYHs1IU?T%TbR^L-@3ws$j{&KALpn{COZMHW|jx$-zvR`ss6fUt-_tU z6cj*kw(&XTUY7;mbiL&2XTFO73~HuMH=3IVNN4NnGzUgB;EP0J1H7-v2Uy1emiZ#R7Nz*{576u z;s}dYB;y^?*R0h9F+@)H?Z+SDxKbjHz92C)xMg2^%!Z!iaF?Y9S_!tb+%hmpqx>-L z?OWr3R+IU{=wG%zV;Wd9QOLXbO$V!mD5SzTCK;a{+u?QY;ZA9PG2TDt`_bIYEPmFm=`*lglvH_HQq% zEwXhoYmic2$x$1Hl@!^A8CRQ2HV<*DbJyoKJ2h<&dK)sM@YqnFkIqNkdcvMUE}LSX zon1!+`<3H&eCc`p?DZ`9_f64Yzf)z(Dm1Z^nq#S~X$bRDwK_b&@>omFn_&D|Lf@ggNKnT+Mm;+zh--A7=8bV}KPLlhz}cHgSKNEG=T z$K49WbUA??PDKpH_u!SLeRDd%fB>`EpTkDF)uqB3S|MgGa$BUyP+~BI`YPds@mbkc z^@ECvkk>68B*%$R%#!kK?q+}Gj&(9o?KPl(8_wN%>5c7JI{jMrbGQ3_-W2cW$^`D` z!niwaPhOoN?k`KblI(@@buQwVMDCL^%6bxJ5${<`FEco@bf&?U8SaVJy3d1cj&q;9 zn)T@}zwqXVE_R_ms??qJ1N+m8U3rF7_u;~QXXcvCBpF_3$r;kUPFqFrN3CZJ#4f(t za?~8B^ubT>8ah6z{_~0+w~7xJ+Gl1IUKhoRzy8JS*%!mJ?u=gUl?&|p%hzJjh#Ml) zX{5L1z>|-C&DJoa_-h(X#psm*Vd*(b#9g6!&~t#0pG$PjtavT6HX4<>o7mFBJf1(a z?Nn`tCN+ZDHD1y-w6!}Z$_$>mvz<1^Jkljl$dvB`&rZxxL_&kS6NXREx@HnMZ1^};;M-`83wQ#p2xVM$RrC< z67w?B2Z5lq6JDJ}hmK}#^*~9FeW^+vX$7jjTL$c=T$&mtk5-sd^2G9wJQm0${KB8W z*m~Y+c|C2|_{q=b)?Y!@zU4`@cqf5jq^KZIHdQZxs0)c9faJC8AD@A_rSVVM$7G*V}6P?ChJk0uVBkJ3k} zJ=O%>2H*>?<(D}Q6lRe=e=DLgo{DcB4QqO;qJu}8AuFptYs_pCKMmjid1T{Do#N1C zy0&9U)ie>A+ND+b()=2T2o44X#?Lem1t*`NCl4rOa4){(4?ga+r-tzyY=(cLkIX4f z%SQtrRo;>M2DVt}tWzHXR=68(A`o>e$sCeuY%>y=wSKmD8uEuDw_%E-qdX$r%B6eR zBlOv$(!JjHK1r2I{<~;hEx(NYK0lZ&VTryJbzOp;UTV!3a(rWVnHSXrY3Pcl(Hb_1 zF{!2Eb>G@d2cheg2#Ez#W;O3{kJ=XMaC02^q!S)PR zQ)l`|@Pc{%apDTSRcqR8gNfS0eUe21XI(40uhZ89iWvJlV?G*QOiB?4vk=K$2f|J?o;8`xCzvA5 zf_%lBT;s0k;f+X1X3Ga>0w2Rh2EN;l1=H3EERYp*YRt3IUa9lslx6@$)DKhFnkl(j z`POJC_zo~sy_}u*6cG`!7d5^c*{J=KPA|ED}^A9Q89uB^yKjKXAUVf<( zQ78F5eHf=iwKTVkfrg^Ixk1CMsGUw!4K{Ri#?0SQrSj-Qww{-Fy24X#J{m3FKD_93 zdHs0SEK!n0wtKLDGOf%SDCtNf1S-TbZfw6~_=yU=E)k>#) z*aSU8J$b57A+HM@{i4YgM7MAcj864}=$;}PA}9nCyKU|vPL%i^$-3&EyIFHFfigE~ zRj7~(I*j*H8uYjm;w;whKxs=*354pY@fk(X7g-ILrv=TU4Ru^cOi8wzOO?WIsWqp# zWsh$p?}Rx>a1>=_`4FUfT-0Xpj79J^!u2*=L21B*3HBrC2G9fmzD=CB)rx118lkXq zHw*OLxL|U5PrLqwUZ|f8Xx||9il^lM$YBafB`jsRW+aHs?j0bUR>Bm&KvNCrp)GK^ zL}Uv><{zzaf&5rjp1hk@U9UjJO~_JGff>NH`Bive`);KJzcCYBaY+zIGr=q&%4S}GvT?x&iDLR z^D-D<*W}BUz1F0f*f>RY8IO>V9tE^wPH`hU_+&?HtOQRz`j|)60Mg-#T(EvJ^9oPx z^0fEi4=C;nf`Bd3*g}F6g5eL822FEaJKHHvU}Reb`>Fz1xJbX`V|}Raa_#|imy|K4 z!${exVtUWeMIuLDlP<}u0kgHi(O23NH&yd?^E1lyXv>bhZKrw}wSI=h6tNoVJK1M*E*5Vu@l==L^2A7Qy^U1W0hz82LAL8V6brR^_=NseKL)-I(KpOZ zns2KQHpELSXPJlAqr@SVkbC0<`76a54*>auo=`ED3(3&lGh$z+1d%7Ex^#Y~y=6^k zO=9C?IFaNnAI_wBaT5xun_w$3sqw~qrV%hjo26)mjY zdW3mjYt=5n@7s#)bED+?c^*wPlVfnF=R-$UHP?IGojH0?F`Cg&s?UV>ZUc*{T*tmz z+g6fqx1_@>2%PN=?{`iX{fwj(iF21IgbQ|L4Xmy0U0k99-dGhDP>np=$y#(vkgil* z7jM=L{qDskG|Uyo{equ6pR;5^^HRYZXl6c=~OonFJ-+s5+ck;2CVjcA{!L^h)|A+PIp<4#pn# zim#*_W8RX{=9mfo)@T?@LdP+vh~0x2pLC5f&?IQ@4?&0fff*z9{r7pjgZNC6O|tgF zF8gI(5n5XeTuL{@oj>P%K^3E~X5xae^Asw+Lpy0f8ud9}T_BTuEO6*2uAe`SzVZxB z;dkFr;qZc}-aU(JQ1fat-67ej+gVQs0whmDGPyWnVG?v>48AP zT$kU%4H*U3yEew`nA^6;m#Q7OC)69DJIm+n-W^#FW^4nAAF^n8*Y+gGphGp@+lKIlf z^+#S>nuzt4G~mdJ1npwW#Rw$n@@lyW-X+jmC5Z9^{>kO3=~86lN|NhE&4+MEv|M&?CVx%@n5~_ywPAWmDDAkF@seLh z9S4^Z?{7JtWjY{)h8zG8Wds0NusZs$C<^-X?BC)%P=HUAPl)e@y(@fcX)KFCbY3YOh7myI8t)W2%0O)c908GEq z!}di%_pxRC6HpUmAg3s2AoqKE4sV_#1hMG_-~j;GlK+aLpki#c|3uRRDQN2{{?6(x zMH)k}1Q@nqrRu+;D2RgnpIJsKAdtrIsFS|7I$|t<2;12H0{vNJ)&GM+z?~tE*6!Ah z|7+g3mRe@v*h;T&{GWpUi&_+f`5Va(f!M?B5fBJgPyan9;_GJ{?IbvWct2c#z^|vV zeNj*b*I(uFL#+NiX?#}BUI;rl4ERVK=qWA=5fuhH+QZyDfwnL=K3Dkf^xu6TzXm7@ z$`ir)^&u;YJK}ef!QY5svA=Wp56gj$`VE3VZz91SGT1K& K2*z4a0RI9Rx&#iu9ZV(H+P18kdbl&MJLYq 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 literal 0 HcmV?d00001 diff --git a/.venv/share/python-wheels/pep517-0.8.2-py2.py3-none-any.whl b/.venv/share/python-wheels/pep517-0.8.2-py2.py3-none-any.whl new file mode 100644 index 0000000000000000000000000000000000000000..1e63a69c59332682cc4ad0b8a8e7b894315a8795 GIT binary patch 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 literal 0 HcmV?d00001 diff --git a/.venv/share/python-wheels/pip-20.1.1-py2.py3-none-any.whl b/.venv/share/python-wheels/pip-20.1.1-py2.py3-none-any.whl new file mode 100644 index 0000000000000000000000000000000000000000..4fbfb3da154999f6ed10a2ee353a137f38ba43f3 GIT binary patch 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 literal 0 HcmV?d00001 diff --git a/.venv/share/python-wheels/progress-1.5-py2.py3-none-any.whl b/.venv/share/python-wheels/progress-1.5-py2.py3-none-any.whl new file mode 100644 index 0000000000000000000000000000000000000000..b795d93ed9a248550e59b5aea5dafd5a102b88ee GIT binary patch literal 12812 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 E1FM$f;Q#;t literal 0 HcmV?d00001 diff --git a/.venv/share/python-wheels/pyparsing-2.4.7-py2.py3-none-any.whl b/.venv/share/python-wheels/pyparsing-2.4.7-py2.py3-none-any.whl new file mode 100644 index 0000000000000000000000000000000000000000..375b386e2f819afef1ef45723008fb08015a929b GIT binary patch literal 72474 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̞}r+ua)zS`FMD11 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 literal 0 HcmV?d00001 diff --git a/.venv/share/python-wheels/resolvelib-0.3.0-py2.py3-none-any.whl b/.venv/share/python-wheels/resolvelib-0.3.0-py2.py3-none-any.whl new file mode 100644 index 0000000000000000000000000000000000000000..7b1a28acf42ef5cb214a5158b5d7331f892e778f GIT binary patch literal 15663 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 D#pD5M literal 0 HcmV?d00001 diff --git a/.venv/share/python-wheels/retrying-1.3.3-py2.py3-none-any.whl b/.venv/share/python-wheels/retrying-1.3.3-py2.py3-none-any.whl new file mode 100644 index 0000000000000000000000000000000000000000..bcd789f8acca8d7cd17827b9c343fdbf38c1d163 GIT binary patch literal 11621 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 Bz48D6 literal 0 HcmV?d00001 diff --git a/.venv/share/python-wheels/setuptools-44.0.0-py2.py3-none-any.whl b/.venv/share/python-wheels/setuptools-44.0.0-py2.py3-none-any.whl new file mode 100644 index 0000000000000000000000000000000000000000..e962ad5ec780971814cf1732e7957275b4778c2d GIT binary patch literal 472710 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

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

      7qMTgA?Q)J}&VAT4pFbQQL;;~_~r4O2Z9PX zH+_#yWj1xCgfYJf0Qp#%g9R6jEE^3(7m?eu z3_|;%!Sj(KPe;9vvuKn>^(xEd_TvUvF4fxxjxTPeOPwC)Z{I&Zc*@Cf%)J<%>C!l^ zmo#{R$)I}rk*5MW?>oC=S&33I5TKK2c?S|H7~trLg;r9Ne5fGKL322X)S{la=*bCP z=`Z&FbDSB~r`jAo#{3o-eh6nm5%c3tM-+7Y1LhsN>?6D5S$}GrR5+$NC9aKg%=9o3MlooycyXf>#uX;U zZ@J$LQp7Vp&Xq%9fl+VKceql%UwH6VdRa{m^shDq2*=`FiJMD+7`D;;u3pYB@Opoy z`luK`hn%fg)E|%Y`?)by2qLd1<7t^u2e0DXdcP%q$MLxxcVDvhjN}_$bx!*7KiH~6 zIt11nJg!`E+}oAcnsY4p$g6CHop9wfwvyRLa3Pu=e#~XKRAZ)(1Mpf!2$RvjmaN_P zS-E}|*xz{V>eZ`Y>M5N#N4#?Ow_|7$uS$yfG1rHYa;k79f$n&CtSr-jlCZ{SjmdP3 z`OfUD1_>AVMCnp7q@u+ohhfmOw>c$IP_ro@(s|wSr?ZCO4ZJm0)=hOz^AV+8DHF zrC!JacUXz6oa zNwSnYYQ_Y8R2KC)Ae%0Tz~g|@1L9Md%s+4rg)-U)hMvFq9*!6$;ng(f15d#0sRQ$M zhBn?JQo839Va+e7iFV(yf>CLSR9#LW;jAuGQD-pHg?zqm%tBnZ34wrY*T20kAJu>{ zJbgEV7SZa#D}G~47BChg<}dE@@RQLiZngc<+cDZi1gehRa6XyMzDOpyW|Q{8pqo!3iHLsD$GwZ#SBVHHMa^X>MLyO9pjCDbVb1H4AAu(y=dOuGQHWHEG>ch6tv-T9Ob-BH`w z{w?k#HxeaoMKu;Tof=jgT_lZ`EkqPC`LK`skk?{KMerK)e@!_xx>CmNU3ryml!3EN zdT8S%kEcDD!3@jRC@7%iF@}0mPFtw{6L#NP$yf?_$)S~5rB_?4f!sgggT1IiM}Lu)HVUe5xt zqzi`ee2UA@6m$Y%irgq_8n|R)oJz)lriX9@U|JFT)cdDcm3p$5H4uRb&~9xW1#Do1 zW-g7~H5Amti8ft>VEsWQN`K_PK@$gEH2^lOW-~;@4zRiyt?ZW)E~G_JM_VGL3T3t+ z2M~T#xRgbJ9%n)!PxGQGbif3#?%)QI<4yt6Z|jj3PHrv%CV6#Vtqi!R zhrxE_<$}C0S$xevZCBN|8Mnk518yTP+Tq;bab5?TWJePp&LqDRJMiAb=hU2Gll{L#JJk z%a8rk#y>@Sbgiiba(=iL)tYG1Z6B4QKrk%V&^vBzJcu4NTMt`bM3fbIQJ7mOTRTdl zc8x3Wcc`^mNZQpePhU<~7e-CQoWOdn5L8E(w-r>Y-T6LU_^=`Eg8Srd(P;V4O)f8Y z^VTza+c9-p&iTS(51_a~8zj6g8E*z$aim1zNF%UKhefy*Wf2zInr!T62vZ?Ucm#rq zi^?&974%?t7D_M51>TzZ-x|LvV+vQ?$+f5xkaR*FTHudWAsF4E)unBMhGP}YN6n}d z&o02^rmZ=RU43JEtT`|(X|TzpMW^EJ;;W~y)1gS z88zNvbWyiB&hJhtVjhKVy{aX9wRe5EIKRT2rz$JYdqt$x=ROl}wfS$$dTYQNAOTH; zZ7q$MI2*85R|x2y=t9!Itg(>Ou3~c(kH+Q-J{w?Mwrtjao0EEvrbH}^b)7Bh-FW(^ z5T-$bS}aTdVFk*cKCVcq`}=1+J6M6(USa;8f-!5L5R#4v$3ihaq1H$orV1+x!`JU2 z3|m@gq4;{SP<$u4pk0bkMKwKYz+@Nos$VQeUw=|L8n6Tbw?FtSYV5eeGyhYTpdE$Z ze8$>vm~eR)d6_)L(6|LUw_1Oo;~|~@Z9Dfk#{ih6-hJAmft@S=IU>B@5#fCg1AN=} zenOJG!;{Z%DLnn>81R9|0LfvDO_pRaD%w-3#4n@hwE?fRE~N*x*<$`= zKE*t-vxTc-b(zwq(lWUcKZ|6`3WRL6k0@gzP{rx~Bm$<8NdBaP=JkIB&9b2RH0z#y z0$YicEdJ2ZX>|E%O(i~GQKIaQ2Ne1TrpwEdB!2z$N%Zpd?u+l9M*n!azyI=Y(RZ(( zK7A2A-v9Aw^y}l6O=}Wd-!jUw_emU}gLIlxHJtHzUo$@5^rD`fr zKz_i3Ug}tcCAwp1C)`x*Abc)}`?(FzYbjKhj}0N*h^hv5b2=X#05dNVip}D%F&gSf zO)93jnv*o5QEPoYjanOiwjZvhCLz&2dbDoq!~EvzkJi(#yt-V7R|3`CSXc1OWTv_s z>*+(UY6<K*s_VN=w4CteXud`#Kh%^Av>nUbOAD>Np2L8R$Wz%b1~a z3ek!7B?(^J%2ivxI?waT4?5(vznnQ7qb%ZUmxhz4$^={^yQWcE3(lyur35?4pwXUp z>rF58km^=%bunm29KHcpuUEYktZ0OB*XQw|6SBmcpbDVUsWE-(I!=%t$dG-VH!&UWWCbzY&0(Jd z0>D`&tyUtax*nQ~RY$lv#Xl(UGJ(0_2g?4ph_o-FM#einWxXC9hUO!k*GIFV0(Zlx zi*CnoX1@H z&JIn@e(#TlX;v=?1<7@z>_aDPBHUs=Ol-xJ2UERH+D`6GX`m^g{3#SR$>o0vPowwr%Ue_fMlU2n#yYutP%^uiO1xO7<=_B zS80^RXS)^ zI@nOnuwRX>=bziCQk6@Mtp+n|w@|B^tC%N&;+_`{Rglj@lCcd~03$Rbu?ee*=kpUL5!&qBKp3~|hV4QaOa;R4Aqy#laPIl#f-FEm zf17{D>7qn*f4{!+7kAty-&^v!HQ`ng!!+SOg?Id|F}}U4{3=raNx^W(0z|Z9^yP z8s{d-uF3nN;yRO@u499W==YreMepu?j()@7-saQ(NnaamlD{tJj{#ZVN62_=sFEri zDFf2&`dCNV;3B&$6fL1{G@1_ve2ySX&c&9OcoA!%8S@p4<(VDl0~5!mKVxfB5#}_i zZHik!SSncu<3;M5Z5129mSBL}qU4$!Vt^(Jj*lZAbzG81p=j zCof0aREGj~ys|-Cl3G-wqpuY4?Kcb0;Na!PU3#Yp7{Zo0$WLZ5RApPrMZQ!7P+WJC z!6d=8_nq_%!Q&&_!0I-Yf$h>#KXf0o^b+VJ-pg3FyMlXBb>Pq!4cWF6$G3`uU}DD9_P_yvvVSywOYuj$XVxAa)vtgwuain?)Ddh}@+n)A1xbrO3`~Yw4$I zyj@u3=F;xClUguYnumX5_rW%toGF_ITLT7%^)fxNQFPC9*) z+%5{|yt9?)*kQWn^;PuDA-t$mw(ajoTDbttP8<@F?nFb({{np7@j*(^5R@H>R0^33 zHo4}9U*k$n3?b%-Uz+FPOf~610M6-sx+Xj z1V;n^^VJ=mDupk}{d8bUyMH?}2#_wK6;MI6ut^yGdAh{&8$S!KsSW6oa|M2QykN&$ zVaOQL5_c26=e6Nk%#Vf9S%|V+XKmZoDV@C&cP~q=&c2i}&pVCFt;`2*B4wDPh|8t} zHro>nwT-eM#(xr5%gzZ{$gf4Rw!v(VEAL(Sf@GL9X6K3)>2ITsr>K{&>qpJufzVrl);O)T{`8PW^VyH4@ zky@kN?SM9|S9}gLafE1bZ`o7OJNPm}CI3efs(DTsdvFc{tPv%P@welCk5Isw#I2NL zqv5X1$91j@>Iy=7fshX2Nb(p<;4ZBp9dObHTeM{?uF<_HX{Gf=C=2HF zM;6el<@08Bnh852y&Uje{xz^|QV{{0wsRP={^OoarjVE@W2vYQn( z2TP7g!niYVLNb;4pA{8n?n?a7Y|)GF6$Jk3h-cfXYNUMAu)4JKXF902tN6gtt@uFa z#e6UzvzBCh{Bz!&xhM1E@pzzoKLa^X#Qk~)#Q6~}R*D6qE0zgZ0g1V8M_bIk7|(uC zCW6}%#k!F(we!*{N>jtZ!Z$1qzxqVHO4~9f#)}Icl3}BANn|=$#-q#0_Dt3`4vtYN z`rV0sd_$I68RlW>MIK(1jk>r8EH$7kHK30lon8kV5RA&tFk5+%m0=2M-^)k9;6d zaqS@`h48Dk)?1DB_4U@``u!1IrXn2o)z@Er`NgA#`wTi!c~`QmKVDxb6ve|wHBX)l zbtlvntgfH>FoInQbtn4C{(iRme18+YVoT{-QNW_4fzhLSim5JuYqiLEar2A1w+O4Z zFui++R(~L}p7vbucC-r1!bMs@VIUE(@1nN~xBsJ+x~)-NZKwQ1J7ifm^pOmkOF4e^faHjRuI#3eLpA?Ym+j8w|K(NI50F|p>_vz*qxmN3@uAI!2sov7jTfP za%-646%W43{@OXn(7A=%;$EYvOc?|_oGYm#!&}gehVtZ~OVE1LVoI9V;7M!F=HJRY zBRXY+t^%;Qob-|5T!KU~=5+9!@DQ<)_;$xb@*b%xd8&VUHq+_jq7&j$Cfe;dOb&x6 zYT_%7gbG1hNk=22Bu}#_Q#K+zRuVxqPA0jArEM|$1_z2$Zye_*V|8Z`94{4gLPEx} zJkd4Z%yiVRO5qMpo8u|&UL~>V<$Q)$RisFIUKHpv^O_4cqE__(KnC1cUtjmL5Je~# zTt{zmyt~J=Ink56=uZ0_+Gg?RI*Oj)Mf%H0?ggo7;AgF2KH}@rk1Xrq3UUp`JOe~= zZo${*BRbck=4Tcam&Gg}M%`&voP}`JpD%n0eEpCjsTHu;`&}f)Bp(crj1*@dQ+(}@ zPhs?v+F*QoJ*w3MP+Jdus9$~!uYc%|FrN^Xe8cD!Xt8l|1}qCCU~;UOjnRH-bg9O+ z5Ktd}SrRh^cU~BjG7} z%M4<9&53 zbKe)qeY2`P4wIrI?b&oCe&v|DnKPXtWrb;x(}JC)9c^BtTd=Q;<&6zjVkh^KR>aN- zLr^9qTbrnNTib@TVU0wPB8%O9?r?e&lIEE%Wdrw0{Y9v~#0jzxFe=m^l~yJ6D%`oy zU@YsLHtn6D$&(V;#7U@JrP{m)Kh^Oj=&c^YDs;=V2?MK454E8206E=XVcdnOj*pyN z`)WfdE7HPgBz#?3RINpx}3i7;{kFURyKxP5AG~Ez0^sUnQx51m$EK%*k%ZAr&vsN_i76j2@9L zos0rcm?r?X%Am^@l-^9!i)`9kNfD>Y!hQ;MrG_P*bEu!1%DQmA9ua!xv@K6dCl@{1dbhTq?saqw z|EYOSM`$=s&q+N8qmkprz`zQ~rxfIWR2sU9t|zAN zYE|rwM=%UCHAr)gID=H&wxevUznD^FqBT1Mv?tRsbZKa2!J9mf_OImHSLQ@FY;}S& zpEP*14#d1B@=W1)nPu{)ykxZx#5N zN>+rjpm*M@s#q4m(~%XYE5cQT&s|QnV7v-OWl=KN_e%u3I0@`+uQUU(Cv2^-!MEcn zt{*y+(##eySpsGrbSj2bDaO!(`AAV7-p3DL#mLihNfq?3EdAG|!?*%vXX~ml25#k` ze=9$8?V7JbLpWu9*M!wv(%-w2w{T5wAARC@?V&eiKXAOW+>CsCsyi^3=Euh{{2%8yoo8mHJj9%4p8XMPauWGqyYdbxq z87N(#E4e5f&EZx7#GV?-+k_A^BA2?aR%RC;F<_Y6hoEs#RKFtv4KK6|GI1BVZ`$OiF+z zhuZF)a)h7G$MYfz_-B8kg>{(Q$_fy@#*YUa4S~J0FA@6QRW0lN3_O3Nh+MnT0F4v$ zVsB?)e*@<(GLX5+mS(GatmD|^>+DOEpb32kY7g)Vp-EBBDJ_#^#4Mj9CGgf`lmitU z(`=6X;Al>&+l`hsTjk`_o1$eQ2}H&1yK41n*2?d1 zo5^}>;{h;=)eZU3XN23>j$>3|sp(V^(OVI(Vy!y+t&V(Uefk@8r%J{?7&(;9MFLR< z3QqGe%^R>3@iI@j8*JW3$v3IJTACzB;LSb80|C~j(gc)n~#+E^>rYa zs~!hojYxu{LZ#B@Q_-w#a6Vc%B37Wl!ghOO|FPR_ZVHk#q*L1(YpQTO8mL@BNtiWy zSV3%mBrfbmxhopI~}~_n7jTarbibS(^fH^4OKiVZX z%Z}&hS*8pIi|#a=a9kXvA!pFt@nAk2Y2lDm@Pv0CZ7>*c<*NI)_c0!jG3qh7=|IK# z6sjE0r-N(~htdAc;(gswR#PI?6l&cEXf#WD^O796q6aUVU{$m!yrL~Qf}|ous+mix z%a-85q;hq1e8SgCcAwA24Zb#s@D%SH_SMx|5SZ;l$f>t110$@(eZ$;cz!(sV9;}Ug z&?A!K`i)?zPWzZb9xbcpvkBjE;Hz*;+Tr=AUT(?3C@ZLU8mExWo9{ZUG5~pw(>kXT zezCI_f2oN}T%D$_yTQD-bGB%OUIf|+B_y)dC=Wf zx#<&9_hi%bMCW3{M~X?hHOqj?2*DCx>rIsbotZOA=A~=I=<9e5SntUszL(W zEY6_cZI{KJrk}z)+?{fepYR4Pw<2=DX^3)QjL#__#(F@9NE(e%Nv{rj5zF)K^|Cfv zTts2Pv_C4fEP$|TlR?$B1#u;w+uI>K7}LWx0!8PcjvVyA^=D@SKBVd5 zGUTKYPgWLzX`$ocT}!5#d(q9d((49XsRLqTF`iFJ?-6GpEvHd8?Fn(}qFS1~=yk9o zn1}2FB}oy)f>VTE^h#U5uHy&^jDaf|-hrOX&|^R!s;0t2NF8N+^QqQiQ-l_H^D`=A zSu%Gtli6jI0X(*dX|TJ6R%5|&0u%jUogrN!DVr%pMV2s1-QEav+lrYfiJ8>|*r*_Y zDd>qEnMn_LY`%5Px1Ll@$}?lvd7I$&NavgVE9b0w6I3gH*g?+;*q~L0)t4Yz(`3U| z4K80I=W*j87zF<|%}7eXg&;jrij-nuj*9tIWiO&^tr$%N)pIzWqweDUojW_sXJ_Ny z9@Ht_c_SdwUIK3cf($zu`f4SjMxX*+P>aiPZW7<N2&Bf=6T5Y4;zSe`d;h_RLf_j`@CT1|NFnN0^V2U@_=eD%^Zfa%o3N4LGJcxMNX7CAAM=T|(O z4HO4&*qQ$Mm5PPi;RV~lr#C5-rRF-YD#-Ya9w|*+hc#?B^|*Pn2*>Ui`SJ`;HS8S~ zMsaH^zHuUGGw)Y^qr728Wb1UP%wA1sj8c;{vI|331em{l`9J;;N@Xt22u#A(>CMrA z41~~5m#lA?92Kh58lSO&AEI4Zf>TOAQuXTYE^*Pr$!|}i7iGmm7>@v7F1!HUgY(|c zMN|xW_#gb~0po%{KcB?ajCyCsOrVPX(?o*vOC@yR*z0MOv{ey0>r7s8h5Al!x5z@(7;kM4jQCIojC2{sGe+aaAN2r#6&Oo0;)0K znSXUt#@CMVT^P^Y-Wc93N~pryx*yb%mi|JDxGm6(36KGvhmtXnkwlpozuM6$&kIG1 zU9CYQD?m|sVr)-TBflaexC8%>P6y-TY!IF01CR&`dWbXARmYp~Ch%}OPUBSNQp-If z1~ciuCvd`>KC=+{PGx-JIIuSq=T`Enwi_S;6XdiCg93tNayHU=%1XSb2d3RU5lf(cE_W}@riz*N~kbqia#s7%2K?xz+i=!b2j3B z!86u{MYK^PG700PxQKUhR&av=&1p-4t}g`6JfSCn=Ka8Klj*oO?;;sTrr)e|TCjMX(XL**wT&n{j=H@lKdIRZ*o+r$uN<{Y zc^{BHMj9NEw>tU~$Fzeg#~7*dGL?X8t@Rqb>Y;4LY8>e2hW4&tTOvCqwkCtx8Gz(IaT_vB8*6d(<$=iw} zQzZtSH9=F$O=}5==Jlv%B1-9CQZ-;xHN#~)Cj(@4qhwzX8_U3&xTL+r*}Y%sz|v1c z_Z0v}dr6o!`f?P*idUVwx$pK?+43UB#1UUj^SAx+yl_&uF5eGEC1%wxXkAb9E;>$W z@4A!eSlP2sR3c`rnicoam|>z25CBsRk$5Hgs}+`pSyV&&hiq0;df#&WCOHD?`!L5X ziwq9JhB!qIf*>CLgLI*qqBIp!lbE5R?Khf!GaR*l^|jqCDl%G|t@wt8Rn&3Ola2TW z(0!bDGj;^)7bezJrcd0egUU-O6*i~V&Qx<_-3$_!zpuwPR;;B4l$CieFEG$>N}A!l zE2rDEZ>efe#yZ6j79_C}1o87J?ofK?BFn~}uVRFOs$zPROVaxvj9=4W=F>9E!#JcB zcXxDi7rGO}7J(hkO1D0h-pFc6MYB>i0sWa_5fmTw>YJ%370yMzhXL|nJ$Gg^4h}S9 zH9dk^wtNW&Id^HYF zm>@cd&6e_rZ!Gnt9E~EGb0EJLVYp+;XCi%u@1= zNN2qkas;m;c(HLy#zPc4&~Y#qFMC=Xuz<*k9?ls>&K1j06?Juil^6=}JEzWP+Y-4D z|EoxFy>72A1S^odB-o1(H;Mib45^bB-E5M-hNH*3*V*V)Il3B+?45rBhE#+JNb%o_ z&FH6wkjE&n#WX&Ihq1iE!ONv4G&Vr%`fl1eE(Td~wx%7p-S_d~C{CyNx8n7TUe98; zFUq;i$d4dxzdT7$Lqt?B@&PPC9qwaZa8F%Fh5+0BW!~?e8@7r%sGN@L!UaB3+fu>n zc$l5%c#P#_AU(B=2V)>5H}PxvYgH>Y&YL#4pzWPr9m(5X{ckBG7xeFNAhOaX?; zUJyFrA(~m!bbE$P+_1a)F*HQZisR`p<2y^P8w!Mqq=J7k9pVETX2%SvveaFr4WT<8 z4Dzmy3Zbg$G6t?DemE>@BSKGEiq>hWqOw5OGGO$WxnM|vh)^;*)?<+3VgJ{Rk1E8r zPxBF3Faf?)UoLXK7HZ$kRkj4CQWn@WZG>`SKRY@0xY}zlz zBW)8)#n%LGYxGDc+UY*btLO#}j2{D_)w&)SO6{U7`MPI9cqosyZip)ih(eu#^I8ul4EIrn;(v(QjoWbThA12QUsa;ck09da{x?)&!+Y!-cuMVjuX}eRH00$u7aXOZ7E6y z6~(JBhsWcA40r7w$%!3@qs-Z=Sg2V{fEyTrWDo!oJ;$a&s0l+EkOR-m+|zn=0(l2- zLW(ASN#f@!j(#>hos%6uMt8yWMn;F^pF~+MT*Wb?06^;=zU961YwG;F?b@!jh#4+ z;%nuM7PTE|ObKF_Lq7Dv7YZN7{X2@BAhe-K0dk&fZ{siR^`@VOXso6pVUR>|`)+ZB z*S5N9mADwjQeLLiV27!B?XRR-@G#QUn&wT$<-;5IuhKmvJdR;++|4%6^2rGWYbDk} z5zFw6l_5eb13!z|hMr(|fL9kN_Mv%8%BG5V$z3e2!Y@uc9?Je3l)b*J+D*Of^sGG7j`#Ln{exPb-G{2RgYJx&xIkoZjj zyv8Toh=zp{GFsN(+@vK>#niYel4>8sXQ{nXcPN-D8~Q^sc$06zuz7tY*QIME&H$i9 zW^5YM2;f~Y8X3+<7^91XQ-%yuD;^E-Ut?%!ufWn$OfHI6j}gf*niwz;Y#*H)6gqEh zhKmqZ>j^G3Y)1{y~dD+C9%DW3_ zbB^XQ;|d7N{jvUk;4ZbY`;_k!bqkLwKf|Hgf{6N#%>{ATh_()x>T2(Z>XB95O#7!8 zS?B=Tcs8D@)P~wIpEX|9dyVj9*ML$?d4TMz|EtcR!W!*Tx;W!+I~(g>z_L>|6Uvxh zxqERO%b`&#T_{(!IkKNvt9+De- zY$BtELirqPEl$yD_yBmolhlsbnb;^(90ySqEc^xJOw@uv4HDqZu zR@rf5%|dfyIv$qd?f^aBj8UEr>GgG=$);`p%A3HpFNJd#K!dF=Y|L!4eM~WgCWi(> zt)nD22O}lgB1%~9BI83Vg2&kd7>>1lrUa{OLl%1TOwlqn)_0qzt&FygcOsAgd(l>Z z2Z^+GzrPc0-G`?m+&~6QIT;&_9M&n8OA;T)Y1}Ubal?cGaG2~4#sz7nP<4vy=^#5T z5~%B)3s9oLqngJZ7z)Y)oaKYT;V!Dac~EF`Kv=Fm3OZd!3yaEaqE<-)*K``R1cj>sY@TRqk=~ zQEzMw-D-u&MoQI{@_u*Jb8j(W%Nf~`0@)9RK{Qz8j9H@w88nq|2nkm&q#R4bRrX3V zUP;_3a%stXtKD*w%Sui`Ih5%yGj84(frrt^@t#1LE9uHXIn4wErUlF?vtF-oqlvkk z*WQT$zKJEyzt<#nN)t!eyp&vF&l*$cF%+4p0PR*fP{ zUtSauJ2tz{-qqH@?&F;so3%;rF4?8oIgnd;o3RNMMUA81>p^x5d-Lu5ee^5b68QGK zKXPUTyWGgjfx*v3@1(WyU~pdae*T%io&WrEYhz=hw2d%FC%_AY{B@Mr5h_TpkECGU zZhwWZxFLAi^4_-iHM9;dHy)I34yYsJl{h-_bNAX(MMYs4&~G!}4DU^1nhf+?l~WwQ z9JovYAfBwWMt3+^d8HG*@Zx==mfjotOO_XfY#nYv*YR2~MPj0l(qr~su{RLS z+eqC{r+Ag!K5E=+{$=f_Z^7bqt;LJM&PV<3*)-ACpv?gXI+)fD*WcCZY3mDeZPQJ@?9R$fLTg{% zww-os^Ctyclm2Y)xUJG^5Uw0>FC6;ei{-w9bvwM5efTb+6H|sj7^o5 zBUFukq0ep^<|<&gHkl!wv`~+xQxb$Dx*A<;;k1l^v31&3k8>+V7$~M8`)Z`@YI*_- zl6Ep0MLi-b#>#E{T7w4iS+^<4d8s^= zO!5;0ifiTl@%*wzR|*JXxA9L{I-S3Gpv-db=!s{~LX*vCqHhkx9rwfwlR`Il}_Qr!`RCO+3Cwk?;ukLdk|9w^lP4i#o{i$&8qg18JPe{4$s?d1O zDS?z-Udt4eKcDtbE)g?W`jnz)gi(*1F9QjLce6 zy|}*{z1S@aLz12_I%myM=G+e{bE#402N<>AtnffFJYC1j2OAIJB=Io9_TgXSc?r+) zhyj0~LHgz&Hgs|)=Sb03V}4}k13K;h6;s@LhO_>3aDq8-SXZcus|OS0GS9;c%!0)U zbp~}a11}n}JIG{>8rp}+{%JNBw|~UdP-L=Rmy)#?;|sl||BdwKlz(YHjh^%iJpRHo zs~P&PSln~gL%B;*l(H+M;JuJWi#rhvFu~yKpP=6>l#VN=nmPb9T4r{cM93J1HjVCO zB5=bZmse-59iz6MqkU%-5_hIjiJ@M~xU!R@f!qeks;l{&_w}sT)5lkC6fvPm#p?Lf z-l?CkfxFER#y3BvVYD8#(DZFa!2zGF#$RQi&I&g52MMd=rR>%|*p=C%p?n(QNzDi| zod23NYc}YVnnskt8p&c^RyiOi8qon9fAK}i>QZ_6W)y1HxvPad*vY!3`sc<+ zak{xeKg-~n)A{HiFJ?tj%6PxN9<^H0#zvH7(X(gKdKRtsqE_Y>f?C1rcDkVq1g~9~ z$(t%kENxE>y!rx+hnLYg(5(k6pYIgU#!mJYi|_&+*+L9w{n;Q7V;G24V+;Wn;5@SI z;KE@CJ;M%Qb@pf*1;_uTh!6DzDy(B09#+e zkBvu<;2S=D06)HP`0_Hkw`)KA123xo_xX$Op1k}4zdn2Unk<6x&-X81zj^AqWq%r~ zw24(eFX+sunD5Jz=%vGaqaP6NcN*>+hWq%EwbpL{E>!skz%2)3piIZ*`w#7kj2sT9 z(?~OFzLQwyOZ5bz_VD-~RfUSdUY^kl z$`&S!`epc4Za!>%4$#yz<6=VCr{D16fAdS+3`{qS`v)G`uus98N*{1jPEvS;!HQHo z6|p0v^bc;aYjLNsDQ;L3K|KND|I~$1?|AT6DK)B_0^d2!k!Qu$g7k*5k|t^K7AZ3s z`y_^c>GxrI^^>WOu=G)SRM|)m5ihoF^&(w=m!BE}Xa{eVu?XF&&s?U!4R85})n zz625b?MBqc(&YuqMsvw*_#@2+((*DPb%dhMK9KUhpe5@3cVZ*zS<q z?8Gaquj6K%#t|S+A|Or)c8aNs3$3lY#SZF-RNXSR`fHggquvKLeLvW??(B@3SMOZ3 zLhsaut!k&HtW_7f)0SvOyEFz zFfu8iL|%jgJyRMKyww@0@5}A7lu>nUYu4Mr<%s#R$B{DN-U11DnxAaPXS3O4^ZtFa zOE)k2=Y4J;ILk2JF>ki+XFCzT1(}OkIuE>cV_LpsAiq+jL$nr8d`|-G;}yb46!KL9%zWJ)d86? zd&=88ayXUVcx!iu=0`H56W42W0L z^aq6I2Kp<~Q*5O2WM#*su@fyB|FD+F3TcrRZ$u7hz5M?E=~mz0S6zG*hFJ{+m#0N| zUx=>$5|UQ%`&V+NRoE;CsG&XenHac+O_a%m4p!;CdpJ{Y$6Q1h$|wt6RH<|Qy9_L& zllBm!Fs8+YPA$$LjfP!}%Z<7a^!j+yM5AVS?qGex?(Kla$tC%GE3>Lub}CxP^tDP) zSl+7;!Kjs@MCvCrQ*;0g4n&MM3xu`0uwxqAN}>^QuZqYiuStpoF#p$2ec|bkk9+4qwRQ# zX7h1fdVOmj^jzh;=R`AVpzhtfG0EstzA3>(QBG&fg=!YPx}2TKXvlPqK(pRn#LgfZ zpL_SNVmesEhP?+T!SOJkqB9|(3C|eMn;VOx2|0*OHrUXN*s|$m5+(7dXl*iF0A>K! zQ+l38>27QFU=r8^NsSz~0AX+G&^xp~VW{$y<>p(E5jBG|WiYtRw114UPVR_u`#a^e|eFTG9H}{W1`zbT&DI;^~8E1O98Jt*Qz; zq%u3hZE;MMg9QW6?1i2uFcRZP(}ULv zQ^aYsgOA8%>TUVl=I#}Os8Xei544P902)yTvAd2`&+6L3$dzpf!dag6*tgpNbVVGT z8e#iMQD0u@yVSlTcJ@r?uBG)ox?D!XP*4-$uc%20kUCUxb#hiL7$>X{($13CG;%8v z<6BE%4RTci+uD-8Wns=NH91+uL-WY4F;Cn;>u!)p1WX(RR3GAFlN#02aF{YmifLlL zz(V^K=(p|UJblYbWcWgn#PH2gSsPsn(tn~h2RuBcnK|Wa5M|GGU07>SX19vcMENCj zhGn(~(W@B)hH2pC2vHWb&$gqAxy9yXgil*TI>Pd%@~zOcsA0r-;)={{IDovia>HM6 z-d?PC_dkiDc?sdvqU%M5LbZ8S*SD1~X5xs$>{CwL>4+LL`{#D8R+5O{poIy=@5Rlt zP^MLSi?#CK4U0-<4DqU#7!7B5Y0!m?ntT0|lYSSSAdXdBH?zBwxtJqB;dEjd>o?d) z35(TtQd9hPTj}S6**Eax^V8WkdRrw(zs|NFnjlii{iqs@Ou zhoz>yPCak#KYe!Ka60|s_4Dt(KM3%^{s;~=FO)q{LgpDy$!~c)*{3AJ132ezTSxz- z2Iq>Y`>bB8S4Por4EMD0H*iE?6T=~v$>lCe%FVS>C5pC5FfO^)#SK*m9 z&B>{FG}CU=!!gPuS<&yBwAWezJc84;9$0|FlOJ8-bT$p8X+XC_tdnEz?7*-@6#K?Y z!zXZ3)BYOQsT~{11$P85%5SIt3KrB-v!2Vy1 z-Rp6Mn*@brEJIKh@p^P0kbP?*2q2rKLFQP3*cd(L7LfdUAQKc>WsA_oRtg&dGK&Xw z0oxr5-GWMKfC`zjoUU3Vb)l4_8lw;vV--_IFrieWT{pwla6In$W8LERt{g^xqv8U| zZQ-UV&=*t3OpvlZSL39#y0U4PXY0%~4l%_%OT2+}+oCBj%xQ2G-yRS9GqeHuM!Sc~ z8qVypfgAK(nwnLs?IerTL_9~eFq~01RGvdi;6m)X;YmXGPDb^cDDhdGTS~aH;D+fk zBI7_xPQSSKNJcNBf;!u*06AR@l6SGCFzXDn^4M@kMc6T$3Q`cbal@LMPGJ@R^92T~ zBYtRQ^t4ZDA-&Y;*2=VGeS_hk@}9OswN(I=GCV0&fvpgjIh?+xLYNhr0K`tqp{`t` z@wnFDy=Z1__h(XTphqooDzT{QUZsT1@oV>@`zRD`*y6a{s!Fd#jTK5C1qFB8!v$87 zkJcXC`@(A*p4I(_jg3a5)pDN!FkrlM4AeZFaMa;SN!n|t-F}otwKb^U1{Pnt2VcH8 zI&v%(OK7xhr3Xj0lC0xn2~}utHn2Q?;h(M6QOU!Z6K{Ai!qK!?`B@sN;TmI!PRLag z>#Xs5Qx!O`I5M>-Brc2alPo33^N8BBDOF(VZPyd@;7Bx}wJ5>NDrvpm-h3z=w{d4u zc2#h=pr3fQ&|BsS&4J5k3${BxSllg2#l-s4<+ryZKbs)Dvl}rbfTFEvqy!K03EHSs z2a)!L64fO!@9?yzZrkl$YkvZK+1u-5PnpF4S{l*@S)#ZdLw4>b(=iqvnuc|U5Z;cx zz3nW(fErH|E|g$G1|oT;a*{s2Ow8FDU#@s3Tyzz&N@)ryvZz5JG!D-Ap{mi# z)bl>*qOZPswkqbfM!6H*k;;7KOR!p76%|`Y`gGr*YjC0C*VSuwH>}eSS4Z8q<&?!NZ$FS>>2?=54zgWNlD#6IW;geu-4J^rsK&(r%yVWWBf~K zdXS^BiFVj<&F_V=u!_M_i<56R+dsvJqr>Up;n6kxisL%|b9hK^-W^@PlObX1_4>V9 zeXSPPN>OZ_*b}|+9M6qpOiF@aak>PRxJC`u1S+-KGF0OFT3m}4qoQJ6SX6%bR3y2s zWGWxEj}HElUBz7@J|-%S+wu>?gH3nU@Ew{Y7i4zL!rWHa88dVx_=Y9Q$xP zPGV&*4d3gOmYUqkC>?DY+3<7Qp_XqEc7dBFKI29{37B~@Fp(@d0W_%qpcrWnRi$64 zFH}pb5RVPhj13sVzJCHQsj`6vZ|dK;R}Vq`t!YWcqHGvj)m2-n-?}B``B&0Lk=X@_ za>~lpA-ZT22UqB}>?j9d;yb!O518Z1A+pfrOtIQ7^1PPNm57B`4*i~r0HczCQ}?t9 zWm>u&5J1=iI-3wjMKe$v^;RSw(jbrX*+rg@1l|nL$=YoK>w0GOKPp?py(>$v8z<|B zy5W&}Su*THg{lguXKvJpmUtuQ&lVj>gYyz2g9ZAI&F z4xNLElD7La#c;LC8g>W++Glm7?GkgbY(zWW%c(UTmN}$Ev?Cp062^Pqof~Z2NQa72 zraRVtGo^bc6SEddow z{4)>JHEvgc-G8Yc*ISmgLnEEy2S1wwJY?8zNtC;MB+@e z>!|x?b~(uRc&^o5upOh;-i|zklNkTT^-5P^)uALNzsta4&KlNb;9BczKEz#w7y?*H8i(-6Sa2j!LJ?!?#(lQq z7B+~9?KZ`>!H#t6NJp^fi z`bm(2BSP~*VeS39^r<>h(TPtt_Df=3=+D1&=utgy*X$z`pZ?bK=ub6s0)+f`B+9Bf zz!IaiF{ZTsQL|nar8Oztvle+gip;m=d)ZayzE-9wrK_=QumdCWwFq$6RQ1{*=lII& zF|3M%aho>%W)`#qMQz41bylXkTuZqc?9X~LQng)kccnmNJ5Cfx^WNjZxO<))S){J#BxUnpzfgNdrIP5nIaBe{j8(f5 zM@hpsPKw7;{u%%JZvA(;3&>uF+9^k{e4W6KRu)%FS7og{7o65mZjD7*h!i ziP&p)n2oa2+#wR>$8+0G%t6;+h!Gs0%K=c#u=XHq!R@In^_nvGI`UC2#4HUyeCovD-SSQsz@MNMeh~Zzw`B(1hKyDc~-F z9G|d76xn9lDdCaGPn@i$#x6S~OZ1ek1LF&zikmY<>|MDNW?{Haie2ZOg>Z@OCcnC3 z-mYUkLy3Xc*X5({;L+}eQ^o!D!2WvdHum^&lBLIK*KP6fW2Z?jxSROW=kamYDm~dK zJrS+%*{@GrL}1AelXvN5>3)WCnVg;$K2_Amx`yJ1h$)ZXat&=qZJ7(Tm<_!R!qZ={ z378vr$SN?TTLBzyp1{c-H}<%P;SSa$1ak+88eVZokK9wbtx>0)1NFf4?`G_^rPUNJ zGsga;p`~XqJTZzBi}IR)=#XHllWcf9s0K$4=^CEXTd$jLFBxoIb+BG)Z)+<`4ESqF z#%mGUR@8&>hb?%>a#aYMZNx@3>y17(W@vLQK{+iubQz9&^MTP6S@{hCIt9s;^kAAJ z4Mimk!l&y>t2j9B!bGb%=6o2sPyTM#5qXO!kZdF$h%~( zmuLV~3kx8>Vw90jnQw%?--A7;q1uzB9YO{c?9w~@bGce?Oec`z*I$+wh4zu3 z2nji6_bl(8zsmC|@9*UZh^RS0)fVMHu5T()Pbm53)4ee+aEjoaN_K}T4u1RDw&XYM zM(e1opHM}2mXySg@Bn=V3uEB9f%ZY*In4%I?eFVD7rD8jKlTKu5dj9%ORM-bqlEH_D6S=R_xs7XV`DAcjdb4Gt zluLa{XGhUob;&UT5v0X*Wrh$h_8kW8B-F8KfjBjHd^p2!UOKt3Nr?LV#gnHm(4j3+ zd46CosYqnx&LeSUU1K2ny5rT;r>`R~b5IG6UAh8}hVY|CY7qoI`l9}iFI-Ie`aCC7 zoD7wLiB9vPxA7PICH=#le@Vlq@>!`=K~Zxp5_%7&hnA6oKwKn9c3={O&(gQ)!UrOv z5GWVcHzO)p5?;~h>F1uU8Cg3IiAf`(Kt7SWk?O< zUd*!78s$bpr`o3=Qq3-Z$R-hIP)>gBPm=f)&QP$thm&Y@TyWg@D4UFnSclb1Ydc$? zNAY2eAn_p+F=22fg;VYGFHo%5LW zXSD*8B$3VQX-=Vbid{s5hCU;yNGU%+ze{^32c9=dmQjo&`IPgX-X9{27`JFPvy>T+OkL|Vrhs&G|= zWA*)eQM1{M?%ls3J2E7OZC*FK^;x6QJ}eI39Nqi2(b$m#OO#*U3__rWpgOmN365W$ z;Mx@pHK8}<>~gj>tV9|Is74d$c<=_fKpExx_sQ1kaCF`N>2P#}WU^rH-(Q6?_X*(y z!`Q=Ct6Hry_T9JFVNT< zv`VC8PXOJ0tH4Z1+vfq&UBA8U3t5p*&{#z|Iac$4RoK+NNeZj#U~t(X7)Fjgn`$`f8dhM^>q>g<)#p#2aFG zP(ywSc~anWH*<@Z42!X2qn`uzB9M0vy_Exk6QGWP-9gRnjW&_J0~{EQZ8?A{XAY8D z*@m)BqDXEHjO3<*y^xJAyn^lKf^*iwprOaRcJl43Fry}91dJNh^bss8>Zc5lFjIRO zwBKMS^q?siM`@(ItE1@W`Eb%OAr#dv*~7}?$xw)&;A<)!T<#{mI*hrN>|3<1g%Ei_`NrFTeU?y#>X3FdG1c zVvN7hN+{o92Wx&c>ko71Ej|!v?qB`*RL`@3OhE$ zX4wz_VEmkiLqtw=UOz+AvZ|L)G7Mc*{SN!(y{D^18?w`R=VS(OUwNVT7bWJcusd7e z0DFhRx}jMSC5A%91XW3GQbiS#5Dxs)F|ZpnxI_~f7mlaQ2i!|f)=EzvG+Pf_kG^&v ze$iat$TuE%;PXby)5-e@S4w?9`AD573&THrZ$+M>g*`@-BkpCfq)*SD-Im}}UTzE9 z*Mg|6y%<+@swpBjv8y+pX6&vW%p*N~Ky|nw#=h zUs#d}iu%S*+KAaw?9zeEu)dL*dpgbuMeS1O)xLIa2sKP%m~58T%6l}dCZA|mtUA%M zm+sHx`s1UUdRtC4;#10ED9%`Pwjg{8z6#*bF1k(46bh9LP++wr5g{XoYpfDMCvTrk z+qVEgY&7fT-Tp8etbn2$rp9V1YVEbg(YJ@aHOIfv>G;PXr*4@eeXEnY$ux~EF2G)| zdAuiadlI;ua3&|In(m{n_LlVoIdto>?WcZ}4ZP#O=xMLdK3SOOdK4HUp5kVe7!eK5 za6ubL$_09VhPPfuesSa~q>iD~wLj$Ia>0D5HEQxs3XL^X{ZRi&vq3yq!E6L5;}mdo zS~dN!VOpuB74xA)EtgiVIO!3rm=6toXj3mw_QU33?_SN(sG7}x!E}G-a<|H*Nyrj+ z8>4Wce2?&?9U6SKK$SWnfNj#wpC0KS*Mz(CsQzueqAx0mMOl0C$vWu{XQ1UJWVjO< zWuVb22^8?UfF;!4xLZV{eivrpU_3rI-h9TJZmA!A>a2a}ACF}u7i#=O8c0Gmi z@DJn`kETkWlgwb}kG7((bdzeQ@yG(5Jb@4ORL)1y4c-Ss-SB|v%bO%Hy4OJju0xb? z=d5V7@`atuU)afv-n%J#@}_pb$NjtRtU{rhu9(joH%WW5**L0u55L_!Y`Kr>SMJRJ zVRx^DrFa&-d$%e6A0;Nh>sj_T$7p)QIhr-$qHfpW|DbVpzsp_${D=&iq=Gm(8P2xj zyZ>n19X9UvVrfNWm=S&giKQmX&pN1D*U=^Hc}FYUoA^Z@G0AP9h#Er80|L|#4c#fI z@JzXRtMH-do}fWNBNP1Mgi0{ox^c8%0hKk;24Lw}l;uE{;<7+pvsKhCg{>*ySxNf) z&O$0Sx`8H5T;tZ)Uw;h;=Ej4T<3(Inf8nR?&^f`nDV*BV=s`=LuuH>C^W*KTb22Jh zy5Yx7-mE{$u%a{=35xM4j$oZ}@SW;79kX>{!p-~bEfQKpgOrjrzjd;fD|EOYw^cKE>joDZ6-q;FsTGkvLslZNbb|S}xRdaLLTxW5LiERV

      5`CF8sf$vGVAP$Ut-OlT)q-!|uhA)!JGRCcySsKi$Hhav2opy*;`JC)E~@ zE$mg($lu5^b0@A&10xAiI?4i9VOZdU0v=BbI=Rxa=5hI^F|>2wF6Q?OeI7 zE1FVS*0OM=bP2J&ZXjX+O%Qjy&7n#|OYtn2Zu+8Gwy^CSGy`w%bHz{g2D_y3ceBb< zR^9~->XN_0w!j!l%NULVpm1+Vy0kcWPAU}-hTQ->o4((zH!`cu1kKYMr=^XyG@3>C zB|waj07=WtmAzi{bvPxZb)<0EW0=9xo6Xots9%AwN;@V8v;=iOLP3vZ z_CO=>nb*@gZ7p+?L2F0vJ_6oPW{XO3%vl1H2NJbgr?_kg}c5HTGQjlK%P|DS8=-@_0Ojot~31r`zZ8 zsIGqPUDXwXUb)3h?|Fx5y?7(dOb?j^5XDm>hsM8}W3MTg%yxi!ta7g%@t22zBm4ud9*!P%KR0R33>j z#_{-GU;2sjkAK9QksX~pyf}_p&M~Z0j@#szmU9G!XrI1Ng73rZ zjaRv7Ibnoz_1j#1wm!$8oObX&C^?!LyeOxUj!3s9vrlE7*Msk>MOZ<7!-`R*1^u8! zy7OdmNdiSbJ29|XaIkY6O?gy-)WpdF1fiKH6MkpWDapguL_hoihQD~Q!oVxt&icA` zy~Rfiwk~_>Cg>S`-Wt`BA?`!)fGhq6^0p{!LLY9t5oJ zqaW>K?%MX{Rx$VsC}RzASzkpnca0;m;dWqN5o*fxdAxM@@0pcIEhlh5Ze+{N@JTp* z<6YmhXJiPuZgUK6oJT)CjxI^E#xEkV*kPdtsPevER_ezMtYuy0m zWbesyCqFxRCbLWKAG}EV0Llsw6$O^TPmCvu0psXt`llsPSURDj)w>h(cgh?y0yBwcpDyQZe`2WO&7lPwLMwl7A(?8GS$Ul2 zfs_k0~K!;r9$1)zb0htS+WMlV8RtdHvbo?F- zdblxHTL<)D(bie%Lfw6_j=?}P)Rg_mx$Vo?EtWTEKgiR5kgNS*F3m{*f=0N^>+_J$ za9+2a!Ua3+Nq_2`m36Zf{J)9*)z!O0~HB{<;xua(S-a~&0`DVYl-k!?5X>*XU@9Ixz z>wr-28w==hSS2z0i{wt~g zdXL|YnsIJgQZr6PAL=46{WM+gd6@OCC*|=fFo07?2VVQtL+=DR@1dXIex9ova+^~a zapH|fRWP%eYy*|5Y##Aq##O;l_hY@x{A*l4ihYY>7KzI-OhA z=TQ~F5?8lj(R5r_a^^1+e^YG%0rnMMnV89L3&WF(i1?OrX87_PbC?X#DQY6P8?c(wJhV6z5Bq5kHvhP-_<6vHh!PAi73FX~NCaBB$ zi8rn;i;-phFue^NGRRWoGJlV9dC>-=f6;^FUfyx9Am4@CXD!O*{PmN`8>ge8B`N&i z>6t6{R}81ivjKsblcRZ|d%8zbez70@S|HJciM2ebGZT+MR`8@cZmjNCALP-bg6I8$ z>Jb1f+$kATYh6tF$e`Bsi@~SR_eG9DOk{}nF9Mppx8Cu=h7|IFu{x&bg6xiWA?97j z`%*pLFZTo9@dH729Ar2T<*%Paj-LKv@ZFgb;Jd`g%QF$FTccA#_ja@RS9EMKiQ)SL zo|PhyyLr5#kd;X87SyEzbaK>)24-_Vm{^YY6PrcVeIfHnQVY-m?mq$aQg{mRbSxF* zRc+8It<~aiq!m7}6X&!vi=3QI-eBE&ItrDhPiEh&cPsW+q~}I&U_ch=)-h1EJcR$i z!k>i#4DWQ%%Hpa?t(YGNwMrAj;6@zy6VP{Nk)gspC^2=n>IN)tyXyHsnFl8U)3 zdahlJ`39^;2H$wN3@^gFO14(wsfN>Pk4r<;Q6ib+6IenY-^)GSC$Hz zx=`K1YpGZTskDH~OgfT#x-~V7i3QNOe_#QlGio%3%Y)(OOQikLFyrFDeB@%Fe^=~5 z)hVb>UI`2L$o+nv3^AiC@~LQi%-o10nm`79H*m2B4-bTX#;pS(uq^Jlys@0TQFuJk zYYr{8lqpp)O=-P==bu75;_y-}@ct5{r!(G%K{wyoLg51gsaVh5@=>s@K}SwS&y&!7 zX0?h}%Y@K9@FA#Wyt4XVE10{=YyXP$(pFjCc4Rmb2;&KXrRB0QeG|_}3|R8B!BaEc z0%;$6PQa{7Gc-LcKHTAWudoIr+N8*5B6;H)iPlfP^&Fq0E<6b z2B`z>Am;E;xA82f;7>W&S=o5x5)U#krd(RI!Q@|5i_7s1yrV&o%XRs7DS!PGuq=6KffKnul zSG4@~c`eNoP>LKMD@8&TJ1WTWXg*7`gzmdWcmx>I5S`?63tQWYhbnH1tAe`35C{3T z3|F4iyW(oaZL!`G)OW(Y#prJw!o7Kr*`3tz;S&{6D~)1(>t)iYS;w0yidSALP6>ku&|Ow6l;BkU8D$|&8 zJu4m62znp!=sjO0$N|`W3sQt*Pz*3T@E+cAk07rEUSibPd>uKCj1muRE(V%Y>n_Y**;=8( z->@j#Nc9Dn_-AHD=K=TVVB6W0s6)@3JS;*EITJTbsxQpEmrp1PF{no%|HP}0@lYZ8 zClm}~AjH&$BxT+sr~pud0BVhpz^h)T%*^2kP$d#)^X!)9Ois>Zqz7E{Wx8Vwk;cRh4MS`!4yl%msLq~8I8EZ8Mwsu}8%ame%_3*|oJN#tvYx((R6 zpJay~GpGxLUGfyiG@NIlyFu4t`hc9K%)u!A9{A8*{3ww#A8VL9^6C5d%|I$p9#Z+JdM6}Ah~y^9~SlMDByO2 z8LwHC%vczhythLM?OvMsf^N@w*{=6k+n60Vd52xqS^L6>S-ihz3N)+{#cvt=j+cPI?TP|hb=135WCD19#reaRY zX>%`VUDn@P{WadM<4?g`mZJBH2P1C!-UZ!qypx2m&cdU{Y759}#}V<#mr&J82?d=W z;~i(TWUl_}C$Yqhd*vEKBs$e^@aRBb+K+(=@%k3AKQ&a{U*k7~LI_ji*7jht61nwN zMBM>lC1mh(A=X;A7jYy(Y!u<3`*g=4?6@274n3BcgpiPo5&NDJ)?G+k;`SW8YwiHH zpA!RknslU0z+p_G9j^YYs|r4WcjO&FNQ1cjI0UpHmanmL**b5DLE=kNew&u*Kb!?ZpiE+E-zg;?C1ZAAJ)5&%*L`g|RU zRp&xB5I}K3+=)q0S2a*qz7c<-M5iPY!f53stcojSv=Itc!P8M~S#KxLlrW6&**3nc z<#L8>(edlxvYh(RwptP&+YYdip1^TUhsYVdl)^JOD)VquJbH}IC8MKp7sD4J46JF6 zc5(ZiEDkFzWG!(3PdtGq)qC++kDJDy&&4{;U;i)Lf@iVb!N3UTai~)47e&%rLfZ&p+P2ZyCPXz6T9S(jL>k zMc6+4%|+Ir%?R?%h9I9-UDC9AY)gsW7HEWF4}KWmVok}`+hFW4Fn-aW&;nzJ-h$mA z_L^Qt*TKeR_>*&?z9{f(D1_w}M%Z1HZW3{O8}aB}f^p9{J`e*xOE4L0E@?09aEAg# znECH9uw*vwK|sd`TaQM~`r4CD`4F>mZ0mJ~W_^%>SGp~NIzpHge||yRgCN@ckz#Z7 z&QxB)qBuS8)#WP(FpiVgDhC*hbdx`|-p)8ww$k72O>TG5KkUVsD7q-Yy$5meHhOD< zh?u;0N}|q7EyYuq?OZ^cSpGcB|4;C#2llcpWZZR|N*C&R>Fg17lEy1copHL@uONl; z*cKe=)9*ebnc~4ExAMw|2I+M-wHN4Dn-Jqb#eCi%O&r~OxjCla)#d7mPNdI{R6$?Z zgO#FgaqS{G59qL8KvD|WogYM zUe_Z{rfXW#aPhlgpxh zT$FTNl&8?8*TB51!$ec-x+aA`&c^mTFVKtslGyJQ z(lrd8;!^+CoKBf$-UA96QE;Bh^SZ&4g>U`^r zDBrr$q!ri2@Gw9>Zl3zx%h_+0?ny|0W914C`)#l-D|g_CcBCi2ugrssYQLgx(=|oI87LEm!^GjSHPs$17CWR{ZBb za~vLb%mp$Z{lOONm?PX?+ynp0J}rP2P_f5@zWI%-KXd9oZ0ON)`Vyzh)KUbA=8W+S z=}g5aJZA?Zw`CUI-r=&`U7RZkPRCJsK3K!Ku2eI|IytBt;DT8VR#q z47`XWf*vKfGsS+EDPI<)qSi#^yPU8Q>ybU!uUw1zd15ZK3 zmU4YRV-U)3x+7GvNGQdhDBd`M{s>r`9Coxzd7a#`W1u;Vb5nB<9w%y-(mOfqBPA@T zu6~ps{r0+kF|ZI1OK5VxzIBbic9E~2wD}0-Mo}MgXwd7-M{*2jc|7=QR=md(HR*^Tpa&br=6%%_^Xf;m zAus)n?p9RWTg!%~U#;synaD=Rs=9=$h6<%pem>jpyMX7K(FUA}W9-To1Lv6NM=t~D zOdL15FrRJrL7zhl-X=wqbtv?e=Em)Y;^mtu93G5MCU-~gj~>yT(=K9 zN4`KqGw_V6D)#}_gC9&Cm<`!!2oDTKrzE>_)XPE3q0IgPT9VSSFQ5G_E+e`605h}Q zm5WZWK^D~!dZZiuz)^#sKYM26lF89aWq$k&`Y6qXPfadh*j!Z`or_m;9nSxIUJ^Am zql~_@6&=d3dp~mT!Me` zXWSY8<^oZqF`~#F<==c9Tnpo0^CyXG)4cS_ z->}orp+_!^4F9t~{X4_|lb_=77qH>~#@J6}{t$V8Z|uE^^Pk&ruHL}YiNC>%UId!W z-eziIZwnp%Z+u(n0DI@sFYtXk{gegs>0j8pfWF7xbLnyRo<}>`dp>=gy%*4Z?43t{ z!`{X8-`Tr_{_?*OL#MXENuOp>6?8j$SJ41_FQJ>++f60*et@oJ@8xtgd#|J`*?Sdz zfW24KCG6cuE7*H2En)9*ozDHG#g|0;sPu+vQNCF;{R#y zTL7ZEu0_v$fDs30jHsxnV?<+uF(jw~Mw&qw#Kh4-1mr5}2!k;4%W#gLRCI74WjL8e z&8H?!lbBy^lcwoy;wNbm5DWh5Cz^yrn_$9C4jr0cC4dRxytVc|Gt8h^?`!VuefM>6 zxzE|(wLfR?wf0_nEur@}_=s}m!e7ZFPRhb(hFk$hy-CsH4jFZq1^3h~kD zg9;^|KNFt~QTjQ>5;n(Q@xunF4I&VW0_R2qJ&-bxkj4XD(mUwSL`zL#=7#%F5vXUXFkLiQrf8wy13e5ltXsF!D)?^U(L zkLH!vMnIK$La%Co{Ir>o7psuPkaa8=JCBC8+S~oKhx^0mo@erA`)j2b#mw{$mUDvAV_qf z=MWN->zM2;=a(Ai7aD#4s@0ro)#}{#nd5yXO-DDh%blMooL5x#+b+K-Mm^TH z)4=TDo8QDxXS>p_cD5=MN5rU_-W>);jBY~sa%Ypm*-Uaj;maMyr7tdtC37~(oy~HL_0j+iG!6`0#IRY0p|$>boCoI!Ks~?# zfY$)_0z3<_dna0f|7n{m<>5AP1#ks$JHYJ#w-ek>aJ#_m0=F03UU2)s?Q<)UzhM-e zie9NOUc^fG0jPEvn8;lyhYam_v~dSw=>JS>FZtki>E9yI9NxHY_Rc;$+Lk&YYM>Ls zzQ6opAC&8O1k3ID2wFPk5mH}opIo7R5{-RQy^Hh-M&9u#JRbmP1*l6^Og&S(K;is~ zwBFaG_5R&2Ys5{8GtgIGK}^yMwSF;o_{D=r1AX?D!ud6#tl5sY2m(bW8uL4l$!yeamSB<-lFzHLCoM%QJcVguRia2Z}FTyy~H zq>O4q|K~9q@dKcAsOM?o`KaW1GxdC(cWbJ4IE__zSvI#fj#IW;o=;u zrf^d7*ZT1f5W(-pIVA${`o_sElbl!NTh-1h3NCyPn#J_YAdV}Hyi5>YeJ1cgbnY|W zvsWrEY{swR{b$JSy0*IX#-7bT*G*UO(B%j zi6Wh!;hW1O;`6(oAeMxMteY7o*Lx{_u)P0WfgH-MXB-H!j|7F8E!1Sw~+FCm9UVJ9#9vxXFsAXU6z+FF2vU7^W?p1vl4OO zw0ydnU#gBzS8+k4YKZeE^~o3rAOk`Yh)<}2JQ zQ{is*v}$q`i#LPtu9n;tqwnEn3MEek%6NS9bMhHDDtj5f9oY63+(oYphXt@QT)yQf z{2#TgkvDZ@)J;M=KU-zagVZqhSls>9>}#~C%mP}%gE-VU_fB&0WnZIazjD5_6(`@I zy2%SX&5rMG=YpN42)QT7@m(~h08ic+4in`=_euMw)$_?il;+`h8L<;`o8!9}c3879 z9Bs0BX4i$x+r);=TTZ-C{k&%iJfL|nPpGq3%Z-BQ+z1j&Id3_qT!2OV4$;B+P>g-A zhYQ#2JFeNUUfkWFWL27Xjyv09JQI2v6i^;}XWel}yTx&39QbckINNp3hNF5@c*QtC zS`}~Xv){rg^~W|$fmbClMm&`_Ml9K@;&enmvI3YGTr4~*_}o6tZ*#*HAGvb-uJvR0@R8e? z8upXB;?SQ}^yKyhbRci+^F(;##0=`&f!qH;2KgrC_#iZt&V>|ing9b% zW)@!lUb@_LBJlSE@GD!whUQlueR>FfW$!NtZT!O1lwX;F?g8*?15iDEgZv8S{`dJ6 zg2Ryfij)Tr&L)6zfI@&Z0LuZ)0BKMEQ2YuO#*0|#R{#zGoOt@bgI|ex*2k~3J~Jf0 zGW!|QCm4B03OpAA?0Dwy@GBVm#`qPI?|+J4k@9W>96A8H0Qvxw;H?G-2e{?gABtb0 zZDfG|(*TwO6hHd|@hiT~vFt42ZKY%Z#k_}b1pPprbvtm^PsR;*_RG1*ZbOQU9RsAr zE|gD_@x6jeNe!;Cky%2ek{&UuE|MeWP|9)8ql7HsBb3g$is8s<0x}&H3aGOM%j0*JK=81cCO0s2p`<~W$g3B&NkV}T4q>0>u66cD8hYQbHssL={A1TUB=3Jr;ulD>3^X*Ks^05lC+$_S<8f>G_q#>0szBXC)I#LAg3%Or zs&dt!d(nhw1Hv_a&TF`zxWt*rPD*0>xgg;)SgQ8m3pqf7bq5xw@+`Nh6UEF-s&wd& zaM~a1oQarN&V4*^OmWIZGR(@d1))3`N`kBzMWQ5=$hCx#+^>l2b6M`p&ZTCI zm@bZ1lU!MM0V=_uvK;CyxEJ3Xgjtds@t+U6IIO?Sj*idOvf8*ws689++6KiQEpVw~ z>ybhytZS!m?#JHiz}#dSDWpKNZv;g1SFeql@Q&dPZ_U17v+((0={UF&m2%g4tyckf34&$ zFF7M<&%y3}{1NZXV}E3D3?>j&MWiHL?o^PqO%_<1rUoN<-t-A3cp1}k{gPnMLHSb zWN3TEMKmzRo%3KE&yf_1p)zuAl2c$%&flNk-D>4{X zbI%yziCsQ^dCxAdV2{th6y0FeAJ59(vO*t5aLC{r@Qc6Xo<{{#LnOn4P2C3gpyr@# zc#K!a*~IAMtac%*S~vt2PIWM}uV=I{Y5Q2ZKj5D zaN7CFPUHs910GPyfuD(f_I9qWsyju7X(h`-5rwZ|HJF`}$h3%NpN0!{KcjbX$<-kg z)dRoy-IRBARkk=qgT{?lLipKlW43sHhIbxtpGZl3f{0?dPK^_V!;f`IR zSLr%yajV}Bu-(aztU5$0b*N(OAp4!pdIKc#{JG)FAXjA@9Sf(N7biDd^mbTNib^TV z7Mi}N&8ocC;?eLh-m@Mq^gJdG7%)%|ECtj$Y@t$%!VxOe)hUkdqmo_3$X6%^3v18> z8a*bxe}msK>1=#;qGG2hek`3K&I^n8pbyc3z8`YZX)nv~J z?FhI{LOQC*o=7J(c9pYIka5dVsVGioxZQIf@iOwvTKlqN|F7u17x@HxhM3WvJzEcDnr9j8_{sowsJQ)CH9(+dY*?e{VYgDx+=Q>4Wfxg z%{M;5A3-yp$D)rxP0$H6EybT1{vmfS4~z0i=f!O6fM!f|90|R2VdC<5iY-grlvCVr?@#iA2}PeE>oMgCE6g&q*8zf zq|R)EZy?&(W?q_3EPc@uJmY=M#-9O3;PQ(+;Hw~+qNY8pVi(yZB1?HFy&0jo6ewb- zrD~6IwVLYpi5wH5Z@TQFh(bZLgoS*d5agLUuW}L}Wq~^h+uEPNc>&KX+2e$_kLR=- zW(c8!lJB}YIp5@2BhgY5f!xR@VyOypGXbNecXn_JvTN zIYiTdc7bTpvMQkBl=@EgPtl!_`$7NRRYIW>_C7wIQ*o1p!n(j+)J_+{kW|WZOFXA$ zFH}`(@onSTRk`i$P)ybURkV*%MXOLsluo7%-N(wLx0>^%GL0&>c+`D zUBKP6;BvbYn#2|&e7S?DEO&8zWJ6j132rAhK@(2H@G+}haa8;4tF@#BVSa1hj;m}e zZ&d4>aQ6jhPa-V@Z^xhwg>X^YRc>OJn}t_V$4>788>~E&is=Tb0`ea#{IS-n89{in z76sIC{=5w)t8BAyxRn~SYx3&8RsBR#kW0&qb8%Ox2nlxK(iI}id)RO3ioj`AjT)+Z z%7}&yV%tgoNyRewQoTET;kbgJ{|~R+v6l8%{yC4v01f9qI07HS*iB72!V-n z(i;y3PAZ8H4lyUyk|b*OPg!J2(x2QgUf47!F+&r3?%|DHDDE5%sH96@H_(MRr+DT< zyP_X}s!)a$O}QHRI^h>eqE=kr$Y}>nX&PsJ|B%Ao-r3`OFHhxFgblM(HlK)}H)@j$ zfe~z_t2z#Cn`q9;63^mcX%o8)wVK~vOPBLL@JNO*uGef6#k(;UjGVb{V93qFMajf_ z<;Zxhk0pB7E@C<;!P%_DLbyHB42g7EH%6$(2%b)IRIn&YJNyXlwsXVaUDHrP;el>25O4D9HJG~cQ-)1SP5TC_O6yq$y0^rtlsm&j4Oqjsy( zrtq{=+B4E?=ZdXEG;akWRBmrYQ&w){SL}y%W?A)n?CHAU2`alX;n;@X84S>foZxvo zzA|EK9L7fLPlooJb;OHD(xYI{Q^?5k@N_77lYT2@GFP_s?vu|&3X36Tj%?gKUXS$jPMdF zJ?^U!*?$WV37&El3UnV2BHoEI+$4K%x$IcTE6 zmYnuC$W|S2!j=AF(WKw0Sac+Qyu&UNHUZcM;3k1n(sPll8EfV?qA>J@EEF!i9V4|k z4@aQ&tVhW?AV!FQ2yG;Snkf0j2qNlkT2O3JOGU8fNr+!oP zM}>fJCQi|3ubQHpeN*&JRe`hYla3*#=tl=l(I3DR{k|hGaV|~lxsMo3*TUK`8fV|7 z(kyxx(aWy&+#{C5BHD@GOT7~{5QbOCB#U$O1mVXH@4@$tPS+Co<(Yz36jVYyv8bU& zg9ChUoib!zB0I6Vo*n05oRF|Z%v}cdeqvE>fJfdlwjW2=eLlC zQ?X4~ZWmN{qVUkRz=jOp=Gzx4&EjLSp$wpuGi-@j!dL~h-tMaG021DS3}bA4+-e!o z-P*ectDp~xL_#!Fm;*iaJn?Dd)?nvF#ZM$8X`~Q)g&fh}D~#OcZE3Hv()iq7P0enq zdhCuW6xE(OZ9xKCJ%s#SaS-{ovs8b66$ z?4JFOI9E_Z!{tCB+ytUp2wK7wK?qPjRf(^i3*560#82WniPpz^Dr`1owxq0gTNNcD z8`(_HVuI&q3@Spcl=pnQzHrbn2Q+*SzESY_7^#RvN zRM}xtxyF%7VjFGZxjvgLi|EfX=q81+qc+0O^U;K(J!hsKNr#nj2Hic^I89xmu)ESr8)gev9JERBT%b?zILIMI z4z#JUtGy6OV(@+6=L;WjM!%%pQMxFHOh*zqMi;cN;J8f95`OiX5AT~HAS+ui3`V&6 z#}wgaNwOu^e-rQ(f3ZidjdC2*V;Z@Fr=07Td!_zzyHT%!RXR6sSLxEUxzN2@S_l_RW$L{&!ibk)B)BGr)66$~w%HUgosOFb>;TeA7ahR?NG!&~^!cTq1Y-@y089#?cKt~f7=s3P@LY?Jel zvg#sgN#!D^5oM`o(UEbgsxOeW;0~`^y#jS}&+kiUWaq+E^mW4L>@C%8?3XCH+sKXv zuM6N63|{9vkFQ!yah~4~>A?A(I(_Jf(@x_KEur5s$v*j6m_yQj9N0IfAMni~y14P| zr@Tq6KhC!BGWdGli;G}SW~46_MrjCdIneQuuw>xTlC6Ka%h=({Y}0qbbSyp~?SDVu ze^OQp1S^()d5cOvha8pNBE0_q?xG8CJ>WxzY;-64kZDg3k`C{(uiDA4OH-mQiE!az znhWPE&SR_kmaz6_S8k{NtfpE8xpX(kH8rA=u1j~<8KUI%r+aIS{hD{`(`?EdHZqMH z!5`{5y;lbF{%8HJOfA|SgHH;zC({6KiZGRyHS7WJJV-x{otx=eHk&_mMsS(5`UblK z2vp>T$8RCTDo)*#gfp9cJnu*3Q6;rbAvxE~AZ9nWpaKhxD`mtClxR4tbuAk)lh-It zb|)#*Shj9qkmE`yTa3q9>uOcJ#vq!s&Bjh7otsid1ck=s_Opw5P2Hjq(=cK(M*NXC zqNB2329f17^0ZK(8ZhQ`j5!WthWllyps}WhX5h{%-Uj1C#M!~(=$RMk{rMl`@?sM7 z$2AX?EAZZ&R`Zi}=ocb0b-Gi6mEDX(Q;m8fp=qD zPH4Q@UZs^&HsblYsRQQzF1=BW_fRq)Alu3v&fb1a4KE}8)$XJ&KQ{I#EUb?;D1Zp* zbS)Ya<7t9XF#<+Kf%E#qLL@z})$CUlIIqCS_z<_0omawGO@V88at#a%$2^OJEfa&+dtjq{(mQBPBV=J6>)Bq>0U`{L1Ex;pk+ zG7i1cu_4Mh#8VlEgM=$EX(t>_f(iU2OLBXi^%>KB%`8m*obG0z5JX&{W`wO*{4^tM zWqs9tkmPf%W39iil1xO==YE@mF|ZzW8?_EJAn(d;tDBjr0Djg=#ffm>l z(T#XISx=NDd@q|7Yr(*~y8x2?NY7q)22SCryn38o1fmK{C4o9+dbn z9Ue$I6B7}0R+GpCgR@3|NK>Ps31sveZicxKr@&@*3?HTfavJDfQv^(dArOLb_8Qom zs!Uz*q^vSQb!Cjx)T#UxiXO0vVU=Bbb>485Cmix6>abqgt7Su|uU2^eA~6QmD{|un zo88;cCOZz82#7&u0z6kq#2tN{<*5F3k?U|9Ps7XyoOCaaxetjsYLP1edJ^p<)lWSF z^K3MX9T_{V%G!&g8IwaQNPCThv-!D0-FfKu&Z6hiNTP&a5J zm-2TrKwDS5Am7%uStHQ}SzC6mIbJUu?cUZqqt2K#K(PDQ4Ec?HM zkpV3vXYaSkou|ZXDCT*UWIj;PH*@2J56VTcDh`!8u_g#@|40*X%yCIJY*p zPuTU1mo*>nsO%fh0WT~(0V~y9;n`r484S)wpqu6jsVeXL@4Jm6AP@rxyo+DrLB;?B ztx}8E^;)Mkb3wyQT90Cw5j7)DZPquiDTz3|*jp1B12{Lso1DJM>6?-vc65{sH?hgs zFY}DWuU!V?oQ#8E;3xMeVEX7WYVrHjRKJ0GKaHZnl`Cj!_L60<_aGTK4T<>SYO42> z4+*D&jrs;nO*M(r0n6fpn~7|&e8UJJ05-%pdxJDJ1*q}z9bUTn^T}{Q~2|6OY01cKL&A$>D=i^Aj|_CY68SxKzHTI$0#t zJ$66!1T>(inw^Mp5HY7BOhfUp#D4gX8wU|T{SZHe7fPi&l6+HpK2$9c>&iuD*yIpp zdGLUiGnDWreUL;z174H+1v zL#5*@>6F5sB7qD~9tCqMz|mS9cm({{^*$W$#RK3^ z2zF>owoeig7q$?s_~CeN+d^h=sENuZ7czrzHtyp)g-Seo;CcnFjO?oNO{)fW>4;jy z*z>6R<~vR&{Kxu07Q4h(e)~lkQI~T8k24$D_j%kDI|W?!@hscQY#|&-5ZfIy!onx1wKxUtMg6seZa%9CCYoyeiVN8;1Cy04 ztZy8&sq@<+f)(BJX=xY~x|4>wH_D-Eo=|cC-?TvvMVUH9+pH|1aJXc`cV-4|JK_C> z9HMQ%gRG;JV(Syu^h*?5XZu+a&?h|p1VuRrQBEk4!cnOQk@tF=M$0k_2M!HFs;^K& zxlc&POnMcSy*a`L8$CnrfT=dRN6`sXM8{;*%iSf$K-KJnbJ<68K?_Dg?l7qq8fQtD zvZ}JH6;f6n_Dm9VHtcUL56lgxcBwG(qu+b$f^WqoMD{L+*uzDXR+LcXAp_QY$SHJo z?0Jd52Xf1m+a)~Sgx2>2GAFw-Q4I^5Lncq4QXgnSEkaX|;dFgPWRr+Uh&H-&!nc~* zCTN&#Di{h6{sEreLUJer&CJcFlC#v}LLaP`V}-mT-)_V5B5WPR7Yq~d{;w1t{C8Ux(Aij<9p@4eE zW6u*_R=A9<92dk57d|NT5+dX}XP4(~{de2$-vY%}tj`#r?YI5Wf1N_RHR$_uyr>3Q z$3O|xjB45w&;e5qxiY(O61-K|=*wQ%Rybf$!4(X+PUX7Dc}_Pyy@IY3Fw^jWqCO(L zQTs>Uz0xeASoLNs7)#I!qYM3*B994=-N^Q#blVlaIFTIWV6l=-PPJJGDwJf)Ck%b* zwb>`hiej-uRvY8G!|9HfT#BuZsY{BI*Jo??ZB}aDsjvDHNv$)zRo@|b!A5A)ce~@5+#@(F%59#ofe^m*-}P$!fl7eSMI#URmHW9@Ffv$5Z@u zh4d8v1fC&iiDoyTWQ-@=X-fB&7^N$>cWXReca~`C0n^-dW@YywEvKp-3Da4KC#ZIu z6F4VhZ<4cF8PD}@IR=@;<%;Y~$SL+c97E22MWvGO_b689lj!Wg6|b}Vhy0i!?J~YtSC9K+*zpt z4kAN%AsvlGB6)(x2@`Qk>;jN0D57aZ_6J^+m|bp%Cm7Nwxe)aG0M$@mz{A=PV4fKv z9M1PnPk6c2Z@M)2$q|@PC=RC2cQ(NS=C15~@x_7{U8ZwHoWx~nFk=6m0Gh=k+Z1ysdoYVkzJEtj#kJ2uG^xLX{X6p7pv7*S^7 z&pS!d7N9GG_%KZCGPWoh9C3;4N#58JZEWMYbBbP9WxZ!IX^dAOfti@Zn=6bBk~C?v zCa7-wB<|0O%F`$t7H5@ugojR)A^LbE11a#M&T&l=9$)M0ou{#_p$TXYwHFai=rGyL zc-_o5;bGbdbC$5}%|T0k;~Gjh+%1d)lyFqQ;PA{f16Rm1-c$<*r*ivJeZB)auoKcW z1?y6C_z>t1AU}oLRbuTVJ|;f*9MyGZiAHpp7h!&jd3 z%;k;sP*?G8C|CyNo;f(E+|j;r*Q1D@gl_y~t|>nEFt?7cJdJIdohAHiaLV(mNy@@C zpBoqmmme4u{uT|#fjJ2VCPevk|DY(lX%s~dOp5RY3i=pMQ9CKMc9JwKagX=@eC(Nt z^T<(X2U0&BLT)~xeqadotzH%Trxn8eX+D7ki87B8K3PNd`wp)OTqPE*@vRb>Jx28v zT>8(FB{fdsb;fvko!_oO2GO|&i5kz0y;|<(y)t%Ew^1!;BZO^haHQaNkYHKk+x zzu+L*2NQ_f1XD$yaAARDH;xi|`wnUL^>(M+JyFR{Nva!}aF!jd+4n8V<~7F~)!b-zl89zt!{T%MJPPzt zxJ-RX31_*+)d5;5jeXZSvGmg_8lOw`xj!kBWPUpYW`R%T=kx(8tC<{MsG$%|bqO&@ zLa-*bsF91&e@C>Ca|bHBA=*)8nMZB zW1&(((AJ*i4Hs1q>%D^E$MD3Kzq9}%6zI#fb~XHe)5hQeMR~YqE_6&JX!ak&Ja`UQ3kVq|8r2j79|A@`Q(bqH7l-Tt z9B5R6LK;CKji8W5P)H*vq!AR-ZU_a;=Oj0!0KS@GD1BYy0dg{M?2v_SLcOz9o`wOP z-U0LFRdR$=uW>iaE5C`HX1(*M__tS`4YHn(oL|f8jOy>c>v1*3IWOiwgc<{cn;uofF^(s0NMch0JMFO4!{7g z3cwDq9pI+`PXfFI@D9KS0IdKW0Q~^!?-?cnU^+kyfB_&2U@d?h;7Nej0ZssX0ni69 zrXR`zxC>wrz)Ao+z(WAL0bT;w2har20?+}_2XK?fFgF9t21o^14qyY=08kC^D8R1) z-UK)X&;sxmfIfgIAf;mf3;;{X=5XMzBf`LZmSkY^?=vv{%YhhPWAKID_ZtKAi*bgl z(iB*VimmxNwoJFq%Id6}idbDK~??R>8nO zCb^6&&exTeVLsM8^aVdlDS8wXmFDZro7uv$QWD6qmbJxJh=Mu>rcNm*A+sQaA@9C) zW#!gV66^MgJbO_&JF9&2MkvQ_1Vqgg1BNMKDwsT`jIlFT_?yM#GsW=7Ff*7^h9l3n zlDf_)<%)~xBOU|RcR`D#z|$gvZ;CZAZfbEw zs@-ZuH^a(iS&BLGyuj}{skpc-57XMYQnskXs4)#Wr-UfP6`r-3ocYV+n~fi(*Uhiwz6CU6(X~1_ybYG8QiK`*PUAq6(d*qQY9T zws^BHpR*U0uG5u5RvWA|R#9mYTVyFNdVpjfx(wsPH-acxA*F6Dw+`NQo69)6Kd!TM z3t1gREh(#Dp|0z#kULh#Zmr;o;d3d_CU(#uh@R8u7E4e zBW+6Xvva_6}c%Xx@CrLz%H+#tZ zSC^IIw0#FO6wcmcV)f;JXMAA2$$W}^T?X&@)(u5@esQHXvTiDe?*>K;wv7L`igE59 z6sH7+T@hOdYeGJbg7t&r58W0N?W8AnQ<67+NIE+}~%a?pl z1u%)R_`#Oroa;jiv%u+%j$no{73JB>D#{92T~-mPWpZ@1uRRvgNe|_6&SZ`rbHk;~I14`+7f7RFc3ye|a_b0o-KmYXG{r==P_~%Wl`)4=*|A61seOmb6JpyC{e>eII z7y+_@Klu&*4UB+)^zZN0AOFJP&;QLo?1rl>)jRP0M(aCJ@4-GY!Z13jwmYk99{fqI ztB!xj{nLkc?A-OpqmMoQv)xZT`SYiK@$@s#?s@L{7hZhnmwSKp>z7~o&8xqC?RWqF z``6#txBtMwH{bfh+wZ(v-*Bk$@E@C+j~qRA{KTJ5o;rQzy|d@u|KP)xk3K$s;m@CZ z+IsP`&)fdvi!X)tzj!+S`qkH+m;QFS>znSL-YegJ*Y|zD_zyEgLo+-##1Q?n>;KO# z|G%6e9XkAfMEj?uC6tsT;I09~5pMS?@LQ9!V43lIcJTdTb zgdJuUmu>JpF9B`|A2Y1wtk*M%TgO$f40A76O!BxFXk~Ph%I!tCCt!<&u>iXgDZVwC}+@G&McK!6G-PaFq+jD*VSG*J$KKT2b zvX_SAFZY**AhKy(bZ+%4|y!n_6biC@Ni7Y^5tC^B9v%&P=3e zuuT3|kzr;1GEK9T<`)C~@D1i_D$D1Jt*J%D*2R_*E5!boG2(7~vb~5c%Ci(_Sjqk% z!*t0PSuGo^SNVTCkPFQ?8|FJ@MzIxWiks!qs-BdeZznhh$@~vf$}w$nSxE^bTvSvF z#m~bOu=Lwmt{fNpB&HLwr#UB=ao8F^qH*%6C$uc)f;CvSx!lUU3zSW-Xl zs4jNhmokY)AzNTDn&fF#OF22@V4fq-^gv@J!NiPJX8tH&h&_NCoYwq>rFnL12^j?q z{{BFPc>OalZBnwCVZyOxmKaU=+zQxaS&EDD$(R8Oi20FnncrE;JbaT*Q|`fM--$~i zz7Z6=u|YhYEE*z3HdC$4F3Pti7h3Gg%1pRpJbyE5We#0C z9~iAKkball($|Ql`mgCmY{Jm z$XF%h-?Ae3zADH#g(v1o#ZtC7vvea+sm!kk21~89J63rykb0+@ekJt#g`R!f?;Soo zzr)r=5&xatK2|QRYh=Cs?}gDDP!bqYUVE;AoiS;<5^9c3>W&qea3$iFwkmHcL3R zoMTBH17c+}!T9C*ee;{8Sq=+LVlo(*M9M98tFN|Mfj)qB3*zY4|5+A$5gt?|G4~ml zE;cR#z97FCn5I(2QW)1{Ff;GdH2F&k==*f}0GERGgPGks_aw1U&{~eQRwP|}ef-z& zpZ}|mPV%`je~||5)p7A&(bZB9f#CpDK&!v<9}u^H{r>m=7Jp%Q>v!YcP5BG(*En{H zKLh$20OdU$q5t>!;y6VaHSd^ING_hC;dM`x2t-jpG^~PR{2>4+PpXpKVUimvg$?%$ z8zZGfS0m-CmHb8m+#~_|Pm%oRNbgC~d$ROymeMSh{4*psTgpF2D!W+n$Bh*o08F&R zw!K}#HCT%8kZ`V&-0f1hQwpz^^1%ytD2ns6^u9;J=LM;}UrPS_CHziG;U7xj5h1iK zylv)fbAOllPx=oP{-2FMRQUhipLWO}4c86%`=_G)gZ+j+bfDowZ;JnO@%|xy|G$p` z>G%KmP$(P?beLSJdI1)!HQP6DpCb9c^eJ`syhz=uXKY0Bci(mlImDg3``?%pvz=?8t6F<0Y?_MyGMLXUyz{Mx{jUotSYkx9(% z@l>%Xy4csE^ux8aS1^#Z^aQxLW3az+DM0(lk-v zjsv&v3j;GA+{55b0QVtqkygkDcM`ZM;7$g&^*;=Rme>m}j;QNOpcbGS zzyYucpd6qOU?qSVAPrz1KpenqfEa+805brh0CWJ601*J;09pVwfD)khZ_pE5Wm6vm7|=d@4Q6!r_CA5hDv%vKXb}Imi{!6b4geEC z@&5t>@bAf~$Orut($AZ|xXZxg1FQsC)@8VA{QMtKO9KQH000080GS25P}mNu^oyAQ z001Td02KfL0CQz@b#QcVZ)|ffXLV^UHZ(3}cxCLpdw5jU)i8c0Gm}hioCFvMHyL11 zG>Xyjk}y!`kcpm=iN=bGii(XQR;)BR2e1Mro{7z5JC(M!)z-Gw>g%o5S8KT{CIoVU za0!asRN{RPBN#xFa6P}Z)}Bcw5&FL0?|HueJ{~e>pM70>@3q%$uf0#{ZObLABuO^- zGfhcaC5eAN>3{yW8~z53T{B2}JAKQzRhHnEaWm)LU+G#<@z8x0cR%PVzx!uDdq{Kr zsHI-fX#t!kb&Bz;o|{ z*)8SpeE7lZT8im;SIdL+478-v^Y)gx@ci-p<@2z70=BXeNxJ88n>6B0c0(erQ<@-U zrld>Khww6A#I@zaPmbuaMT&=0B*~6HQr}ZrU=f2PlB*Jh5|1Cg_X|q4T#Ga*dGO{~ zBuB>oVvzr*f1Q%FJmu`kleK#nYw$ezK^!3LyRCm77eF();-0&;yJ7y%7j;S(z~A2f z`F!wyvdAWVaXA)*F&T#SSqA2-pS(b1q&`Alr7U=k{6Rk7|3Odx-@pG0|J3kow?hrj zcju^K&7G%)m$+TZOywr!X4Uw{6=a{PMyu(m53rMKaPp44u6DOa{OJ}o^029vx9~EU zS5KGcV6gn#CTYAHnPmyG&Kh&sz4F*9tY48=WL;QwY_@JQn_}lx9UHH^YPyyU^|Pk8 zW~*#7JI#LzHK^A8`CU!c*{azXOYw9;A=`zjxe;Ci-h;Kp=8{!VXmC=Y%S9oT&3CIR z)7)h$TjHM8WF6mBY>`wp+wBXmCe_&BQtnjlP-Zu_CH`T5^KMbAznKGzKxOuK219<& z1~nXVmr=|fl{LsK(p7dm)T#|xuA22#$1c`wO+IsWog>t$A5tSBHvMrZEO8e|a?R@!1%0#S(BE;m|3l$zqVQlSECyYTKtULB%G2Gh znk}l?s#;sBie~E$2*Oiyid1h)MP?K9gd+7=QnlC+5cnX#)(q9-obdhGl0?(F8dolV zA_DNcrQCSaPn~A|@l|3N_%+tml2r+xsU4`$}8*pUrYD^mM zv*Q;IH+4104yf!zq|8AG2HoJ@K&L&X%8n}GrINfZ6VR%}^MxADyHT9ZP9_yDN zWrhXNgqKmI-YKuhhgV*AR^FD5h}P{fvC8LtwUbrA<3IMx@=790Q>vtxB~qZg z1SX;>5WcJl3!MwV^EYz{jNIi3c%RD=@K$*NNv<(XlaO`*KA!=HVbmtowCaOd_G9BL zQcbJo@a!<1S9}DN8|MwOPwGSV`1t1_zIQ;XryfUij~WTO7x*LB%=7FBzvJ#CD&U7E z;b#{9%;6t8Bq?$WEb{Cp05rgx1@j=6={&R#QFb=u1q53Vgt}EM;KOMx#Gir^PiqNa zE_>h83a^t8?ksB;aM_$XOZW0-fydE$cAjxlS4|=yO`6^Jp35JD_O(Qtl zK9;0Xwh?cAp9IRcK#|`;k$|<0e>n)@pZZChNSKYZ zX8hJD6kD==03HR{20|e~AnK&=##@w|6-0`n0whT6h#$#Nu>2U&4`r1E z9rm=E&f|NM=~97Ms1bkG#fVM?s<&Zbo;+5nDx9q4P{}694iw9~eo?H6rUJ@RNzV=_ z%j{D=#(}`1;cHB0_rPoTnl!!(Bv7{7=rQ&2e4ABJNT6cQ6CcGVb~->ADYizBSp?N8 zfTw^G2vqnVZj^@jm^UD?yhV+?lZEMQGoMl0mt8eCspfjsyQ@-`SEPjMHOJHp%{Db# zk2a-9NHHl>#QEq)ST#yl+&zdE@I(OoR)Qp+DQsc(GKdH(4ta(BS_suDS=fI!X1Nrp z=&|Flx&?_ZRM~DI^nBqlT<}~4%ysc-3N^MD*A@^~?BktKE>e;b&88;ac9%gGm`!&u z{DND>S%Q8d`zVQAc;y-gve`(91=(=}@vtq3Q{#I~(>QGjgl+Bs47+2QOEnrD=2n$u z@>EDujb;bNsKy}+OhJ$S70m`e&~2J)1ubcI1ibq(ZRt39Y>4EA0L%J>H$xV{yQB9QwK)wlYZnCA2LKLV^CFCcCEm}yVj_cVBVP!aXnbSCO4!DD=7&$>;Iwe% zglPs@yu(a%SY={@k^LaLBKrwv&^ktZR_;>nyzBO40;n?Q{i7`s%f1VK6{3;R9%=wk zz6=(*>IjB?dBL#iy76XM?XcEil8$-yv7@X}^=_7bSMP1q&*RI_m8518c9BB31ex>f z@U-&(nkY#|iy3tyoZ;_18#;OnOm=&-N1uV~=m|>A(xeyqgf$|T~4*TQkkt*M0*G7TF{3f@>xq=u zd4WhwTQw3teinMxw6H2~x| z;+!|h0(f2@AEp4at;eAXvZ0oMaop50;rFy=FRj_3r#7dY1_l{0>#_QP5w+;=Af?;j z!p_l^zQ;Szg_JL)(cQ9mE|=Rc?8GfA|rwDYH!9ky!W_$LO$kyzW_&VH_q*- zB8bqO98`InYb}#^jRzzPx_x0lh{oPN^#3<^Zi0RR`Ui|2N5zfuiXDN~miWJb{6;%O z`zp>+yZ0EMrfI3c{023g1HyJGYY7+~R|OiPsd|xkNrM-wmOFRu+~v#Fa4uq1z--mO zD+PEmYI9YyAz-%XU5)ZspM;s3ow8929Pjr$boVoINh)t{yLyMJUIMy z!e5WRJNDFEl5bVHF&F-z1pJ615ZH}BR0y6Ne>(A}N8jFAmF1SAGXW{j-2WikQ<_VW;#+H&R4=Qud#dVpL@gB1O%SXO{FHmYG8bZ|Y4ZA!r4j*4>wtIgB& zZ&}a^vdi{>al|b3v@A7G5&f@Uk+b9>N1hzlKAVy-V9^oF+)U#9PujGOvPo2{jqLRJv(5ob1F)@ z8q%~3n627e$PzmY{c}}}NS>hZ4S6u)E=;KW8oK17AxMwUIhLq*K$N8-jb=S|6kBME z<8KMegY_0kpnyp|2kQCV>gQyr>x zhNDZd%37AZLa`bho$Av#(4I{J)=JnNeFmf=T1%x&0bT_O?K}+K>!$z+K87+hNOO~d z;h@`9in8W<73682GKq2)HVXY92zl~uy7?BNn1OU?d{cm&_hm_N-lu8d90S?Vv!j$9 zW1GS=-3wIjaV;b0J)+A&?|MyMO|11D)NSGQaL~I+&r*w?axaHy{WDnP@v!z`(0f26 zJ%>rnA_>FV+MxF{k@Vk~^be7QVeL85JGQ@Yh?Ys3a3hMAhpW6(^a}wBZ5+(0ResEi z(%|Y8Nyt*r*8pf}Lx9Y9cBqj@EHMY>wJNp4RMa?+V1>iAdr?K(I|(xZ>~^$546n0J zy;#ehI$KMhI#~yPaWrOABM+eNRyai8rg{%(7YAVkCI&&;%HI|&dV+c4woaD(dYt_Z?NXybxxYrFy+gM~luExd)_PK9Amv@$jS6Se4B8jFS3 zp|*j16?3)m%OO|nVya8c-;cSdqDhpiw=TK2E}K$2)a|K{{u*+zO)(n~&jmryi_l(! zqXU4hUx-750B0xW4P%C5BZCstwGb-0Nx~WjC8lX1)eV@TPvm!wK^(gWq{6i*RP@Oc zpu$&-Mp-E~7?5NazZ^2I9*?Zv0kR3GFN*;+3s96Jt>w-;8vFDz4V78r8&GRNjy^8L zew7_Yaj;5IceQ(WfHjnk+E+SZH-v#Fl#begnkvxRpu4bi!gh*nRxuWYa$Fjd0u&1a zRywL)g;-$5yA-3tit7E|lR`P4gZk7w0Ilqsiz!m zR2y1zqJQhh>zkB3U|>7sn#WMRxcqXIV2XhVEUzaCY>3KgS5asN(B5o&Ci35QZ5XRU z6L*b$Njfy*;OQRB0&v>P9gw4_*rAOgLQ+fFvTwp{>HNU?RJ{X}x~PT}-Dyysl&0c5 zSQba+hfD8cG8rY#zQqg=j62k`8-gMcZow9PU)9I=~GV{mzP@N>z40cxYM zDhu*jmJLJ3?IHmV1i~w?kR(6b9fR^!X#MibD@V@)vgoK<;x3f5EG$}JJcr<%QV0Ma z$xkp7f;JKTLTKi|kO6L`j7s2EA6g07l@A|DvUThxwWd}35a*mGz5p$5gd(WqK#^v@ zyAYs$6rSpIEch2tBaHd(LJQlyI0LN=1x+9zk}g*OLhz$kka%xwnDZay3zPwL5Yd7_ zm)9m(A~Kq>b(ZOML(_pxOj)nrf-LGfP&}_yyBknd(m%a6GBkZ|^=GC$xB7UGyr^Ae z7T^l$K;-m|Bw+yS39L!*-i5${I?bSUN5Hc_P}8V20HB`wMitQ4*ljk3c4+5?y0i&u z!+{(KkAm> zgUI^pEog{2+A0LH5g<7}w1v!trt?rd(#AHM+xz1cwzU!_08*UWAREN5Ms$f*xbQ`U z=Z?iN2%(i15dpYGES}?JrnO?tDOfKkvEKa^2XU1aU@LbCz9zDxl0pTbmf;{l!ph1- z+(Zasb5M!dqvb(QAB8Z_@RB9Kfq?%EBQBppdhIVZ<0E?pJoqx` z7&LVoyzhtc+l6a{@RI;La=6^ zT(gZxX?E2ZfWUJxhC5M=C;)in&|gL3?U*=>5_`yS9b{by1F#*A?}e)It%JNrNd0#VD+CY&J#<`gg_c-7Bs zwlB*PXGo^m?F7E{ z6Sdqv;zJy|%Rhv7)!I~Dh})`Kre|MRh$6A;R%fPQ2{kV{w$NCG)Ns(Eq&T-{U(wTO za+QDAn25{iO@=lqppEx%RA97UFD8S)xT0xU!1#1KUws*npwT!}zq~X~jQGD#Ko4hK zoXGiE2IYJbbK*uPzoR!N!<^>;0bkCalQI9p8LLNOLMkMf&RH92lpY2homVLou7S$< z5??$op~&9jP|5w%;!)`s)eKPpZQBW4?OGaZ;s3@=EmI}Q7h2+;FRuhSSy_!+pnkbz zQ;^l8D7cm1cM!_;AgDy5Ke3Ul$9RW^1lT*Itb)ikz7^4xHOK6$Ofne> z5ih`Q&kL|hSAczfS3+;+?@bpTK9sVD9i?nsfc?C% zH2>=^#WuGT#i;{97L{v0l4uVmthNNhzU@Unk{{0}!|0t^thguW?T{aP3FoW$B!-PY zLD+c2Cdna`EDf(k8v!JaEWB)Iz}jqX2l7#ih_S3vsa`6TS3cOGPXe0Porg5<96;Jb z5aO>~PBd@O8ewVQVmfz0G@D^l;yM6SwvE3(9TTtiu^Vlr<)yTPF$vx$1+2TsuD*q6 zf$3z8Fi{^uW)no=#vJdDDt{XN5zM-$J~lVN9(H*S2J+3K$qQ#fw{qBw?}FY>D}E%p zS9yi%JywyWdV4CU*J9||o0dR0)eqxPYHe1`?dC>m zX>!GX6TrA(;)A&=2(Sm>S*gN&C6kN<{a)hEA^Rgrhn&l3&*tN%<5pQt0kT2Y z^gI};-5?nnzsP}At(a2mTw}V!T%4`4lv;;srpPNAVh(v-EC1?3vXknzbZacdw8m?y z*|97*a4!dI4zObZ*2(tz>Y}I|u@8N9Tg=V81~9_7%G7K%`yTx|-kQlOW2&$-5Wl=3FU@Rt(ExEBP0SZrDsU%v0X3jx5+1v;%>BIRn7*V6}0zFqGzj+lm zVaWmjTh0Oi?Oi9U>DAwC7n?X;N2SCjPD_f|_u7L}?>rQJUjU;%};A|3=76G`5w^^HnM(GK`@_NWvxeX08EueLc zMJspd1NE~?t)bScVi3YJf^0oxDT6F9-i43q=VR$}u=EHrjIT#)ctej}Sj3-dz*1e) z3#&AR?;3RWzQnT6-WP>6M=wc3y%h%KxVF+)cd>$dV>8`8{P8Oc^v9>jG@?v7Acqd5 zid{vtnJ8<~kgb}{iuZ^b7UW!hq9qkKbvmZbS~OUd*KM3GuY1DL2_s>AD#xq}+oYDS zSIb+~$j}x@dMYF5J4tFdZiBXFvrUS3ha7qsz%imAxYau1fr}G?SR!d}BJf-y@CRtt zIA)P+rb5664I4f8$WJbV#Vd!ZQgH1katO6Dqo-I7ZO0MlDUm~yDdrkEG?4-~Y7ZJc zv*geh^mdyz+~~Pm4ms(qTn-^0h^jUu$t6<2*ysp&*J~H6Y!(FeYUe8QnlCct_oT|f z&w##FhJ+)3eS1%IFqFX2EQ>m5<7!OlVW{V@6^5{TLjiOS){(sCo6G>aLn`rhE39cX z>TI&V0o#B)IS%Xw8rPwnMAfS7ACq;MFfMvT`axZNCAAAngAI3nXvxv|QQR+&1;LVS3wV`;4XXzO&1(0!@9MgPN8(oUg<|~28kEbi_s2sTn zH>lR7V)h4U-0zj2a9S~N-?D8+&;4@fFb)3C}tEGdom;#XN->UhW)%IhtaWFDCB1gWZ5s77(E&jq> z4QOZsW;>j}83=_x$_P3XoN$!nRj8FBy--M)DhYk@@EqF>O@4QMp{%31%~Xspx=XxAOXTa1`hk(n!R;TIyZ3Mzckdq6I$;wG zlB%$+in&$sZhF)Xb!#pl4Xi!@Yqt9^$aazG1x8QNGOJ>3uC=P>=Gb=h_Q5KY_W*0n z{6^Jm#P-u+T>Y|vRux3C^eS(G9Ll79>CGl2HCYRysGI47d{w9J)0H@oMR5R?>eJ{- zwCsE(vhEJD%xvQi;~pqbf3nn~ED9O~>yD)=>;5i@MG3mp^5YVXCJ=#BYIzstM{32( z#tGbC>_;CYkk^Doun8?=xQqQVQSbNt!1P?^c7>hv)K`CvwiIoQ-`fcS1j{aks=0&e z0g*^Wb>CA@(2w-?=))k#1kCZ3D>+A%_afavlY`b=U=P<%A*8|K@fXc>&ys6q;27a# zUV;PXs7yl)ya?v2YlB70!Iyl}89;baW4REUqEQxCjKee{_ne7*bY8yZ_UCs)dKR!- z=&CQsHUi6a@ejI9lOk{cf*8At5A7j*b!fxk*VeB<0slJ`fU5nT`XV4Vn(pmc_H&iR z{6I*^zo0%vcn6?>uB^h9~(+a@-m7ouG_Z1;%lP>&C4UosM*)`s@$=D{w?f;k)vGfjWtQ@w2S3Bfl1Mr@NcVMI%OYyQvy zvEA*jNk6JF%2dPGL3PnY)hvcaqiodis{yRB(CC1+aoD-iw za?isj5ZbZ$1j;%bpNr*?j8EWqY4Ai2HJi}ZC$HE-{EGKnfqswPCT$#Tfzv)Eh?0Ej z_ofL01yK8@9FjvRWS>sXFzS1niRd#x%b~Xy=p#y)PRkMqk{tO1M3=Dc=#%g)j%2Ms zhV74N>h|bTN;wkM69va8aq0+@jv}2Lx$QI!j;(ulOa^S28Of@`@)5tf9Wz9yh@vh{ zf!_(*CGeZCjfdZhv?1_YAlKxH8XQqMUR5+z1T4{0XaRw-O^Y5qMNuiy1E<8`EWn>x z_%joK)Drd?^g%FoQf+^1Pu>7P>Dd)G*UkgJ?<;(pkSV&Ti)2ZPpzqjy{q?`uy)47GT0{;cN}f zqb$mkgLy=)yqo1ngfzp;Pl9$v zeL(of3izP{?S4?tPBZ&PNLH*H!uEF{5Qs3*_MS@R2Y@S8<%LyehCIM*r~AO($m|cH zN@zBF8<&ItQO3-H*H{_=gYgP874QCK%T(h>ruG2*p4RRK~ox!(- z2pa{v|RCWrULlE+FI)C#0yzxu$wS*mr+&Qx@m@S3O*dQWSqRWlq_u}7PV9n}gf zEE8F@(eV8$z#p^3`?c(EF`dur(e*D> z!D3d(kEWXC!c+sQXXT^-d!(S0l^6D!0DAXoYg+Y*{DPFT?rU6S5&Iferi>O_x1bMZ z+j}JPrK$d=18@gQE}+$+0rOb(6c)?ckNgd-l^~1cSOjmvXRq^SndxkPOXx0+6v3W- zz*V4ie(F&nO?VNeLLy|uC+CoqfT3AIbh?Yn2~;g>#CMmcm9K`l@Xl73OcSH41y*A_1(Pu14%%e+eUQ zQ;qr@as#0BTawZ@C(?&fdhb4rCn?WMy?MfUd}JOHDd&@4#a_S?Rfq=hatrMJ9+r2DTNgaf~K%=GVZ4o=9|obsO1 zTav6FfKh#$9ewspXly|q@CTPLnqh-SU^amg)T(YK^G@6t@Z}w!*r5 z9ijM3914Y?I0{gFr+B~9*ZmJroZVO1(?y7UK!NcOvQG&!cOrke?}xy&9Zdi;r5`YF zA58%Bz2f~|Uz_Zi-Y5{e*R2?L)2_Txcu6`t3|rjnA#y} zW!JK-jxHt7&~o@&9^o&UYBoVtZsWwzC6_?veISBiF5!*#=YP`XRg;MPlq)9sn2uQi z?=uYd=aSio&BdN1Zx;S_3i&UJWvoH}(Jx_kV}D-+7gO?Z;`g|%Q&aS-x|KW!nzOH9 zMfnfs)R@aI;-k?4nBAD;XU)+0&p^om=|pD5d7=7;WuxO%xHvDCX3WTQ8CxOWj2xrf zLCtFDQ=i#?Z?ex<5Ew=p$5U9b3;9oJzfrRzgE&WCQ=T`d(n)(qAgV)?fA>lfu*iBc z)+Y9Ww7AVV7{14y*XQ@+XNOBXUx+Ed{xA2KbY{cYW_qW+o@O|n5erVhs8&y)% zr4NHlDKL*CMY1CMyKy^FWzIaRW#|E@c=awkkAMJ?0wAUdjaOJV6!}h!n>aoZWcL88 z>h&dQ6fR0BQ0m0Ulp`<*Mb)spx^iVO*Lx=4g)q85m2k{;5 zEb2k3>3r!`0UI6=`25VqWwJclU*8WIt*t79?wJ$wUX`SQ<3t2TE#I?FIGat&Btyk; zo;O00BG--Kd{|=BZCD3l{R!0y^2bFt?MKtYl2foSY^*8v$Z9+b$s5THp6HRxC&NoK z9TS96xs41$d@lSf7v=PeX&Ml#pLPklg5fIM+B@3QTeK^d69~^fCB@P)^(Q9?53?8U zN9jO)C9#|bPRbpPNqhd~d(_CZ7w{a3b)RZX-7o3694&9qB#0Why!{h|I%|L5!i2H< z;^p{Q(IOJ=NjL|WqTku{4z>HR>TRxcbCo>r2TFKZv|rgxyHaKEHth@(?mnfLsopAP{!Qp(A1&knKU|mT^j*6av`@?OKxR-6cQ%4yk0fT52s# z)+u;okF}RV&lRPrNCMFj7sP4V_&wyROHs}BXd7#+nj-0623RZKT_{Oag%@i>stRXo zgGA=a2gOl9bi$c~gE%5KIG%E2orTJ)W&_l&M={Gh%yLPc1)$2GI$0YZ&pN5eIvG9r z5=HX{7L8nEQN2wIbDBzE@c$cBhqdU07Rzn2A_h+2f5s@ctdsZb5#Cah{PK!@N@$67j6N2Ywv#-lR91`hY`VPCcI$*Dq}WK< z2_JgBr9k+On_CcqGHiSnIwIhlvh}Q8S#6`KZUKOaPPVlrBFT{?dYhnusCQ7`_^nsQ z9YRrfcYr!kOOu)%IfM)6rT;=Xcg*5%h1xKSoaSeW^I5a_u1YC>fXrCpE|W9`4;sR> zVg-JoV-$!}invD$RHpEdC;;L@&|QZ1uUV*C%mJOD2I`89Pi)12;%@s^s0{RK)Wfja ze|?Ddybe$;_S+8%9b&o2Kl>2+v|I|2>8MQDFNBaF#rF2yqS<*6-VzTlFr9C`h=&ZG zg?xgWygo^sclynX!k_0A9D$|qVoY0j5Q$xe$oKdpOqdM`Ytj=M$JH;A#(}_|MJ|Sg zG8z`xIt!^j=*H>U!S8EFo6tTrvNT7D%t%$_m5u)J9X9xLz+cwfqptx)`Y|3m%0E?S z8!OP*IAqa}sFBDRsA&!MvCdXhYXR(5jRTl+_C3Tt|Bos=jm*kjz1xQiDCRH=*l>nH zH{AS!B(25jaT|J?g*F!`--tS$% zXqb|}J;3U(jRb8A(EsHv7k_v=9X?8_OAFQO@3X73NV!A<*#blrcC`)EDS;{gk2QW& z70pI?JoZmlk)G?5ARoIqiyVJ2ALK!2AmQ#z2OL==ELGIS?wNY#A}IrlD0BcNUTX4G z;c0;osKDAlrS7s?w5+Q1oVw6ZY!CMxtSQ>ys&p5|K+)Q29I04ZQ?)=km<)4$z-Uat zQz!a+v8#|9TsH;=;;%}?=Q4UmEOJ17k?F2jmV$4Cpe|q+1L`r?LrvcIE9lfM&5);! z|7NF2<^`O?{+=N5GoR>B^f8^_?Mb+UUJZOu8=@Mka8pXcV=zynlWFW{t5MnH-95xE z|0*0$acI0_GJz3le&isdI}NL;4}%5Vj7I?(o%(Ch?EK_Wq-XX|@jzerm#f5Td;epx z!U{SK$wJ5|+Cba3N?Q927k_*gmLxh_C@@s`oQgB5=vmtKfoU2OcOF9h_rz&^Vza&J zkXX^C)AxLWCf=A#6JsUDiBtOEX8W_fIR`<`*ayamllo91vd#9YcpCHBVr$RfhMMp~ zP2O`y$e?H858|tZe9n&W0D6<`V?EwRJsZU_JBVY^JUZNc(Z?U5H>JvA0k%;==Xj~8 zP!64k0;{zxVEqQ&IgDfWifFaTPvKT3p0utuqZB4@sgJRYzZdWuZ+n zqBd=`5zW?e6mJ`dc8#%-t86yhEnS6syRocQHU}Q*T9pfL;j6R!;kk~OHGHQ-jV#Ln zGPfExNPxaYJ8)>m9Qp=&T(c6lIa|!=hXZ?dRU3Mv&3_O^cFZGq7T9`FS%X}yG~z#) zgWdy$dDwnzO5B~TT6YrGfR!!oD+yF zIcTF!$t%;4$jwDF$@&x=w}T|BA4ee%(X|j4@s@V6K~hERZG*4ZAw;Z+_O{Ew;&_Ct<`^yKp;c_8}6pL4-rg^b+DczZc82MOj5z zz67N-?8USGtc^R+tj{=Pu5nZ5Ut#7>!(!?q<1e5ot>20JNNw66e)3z>MEmi?H+JHh z|BJ|NwRAmB4(4)AI@Ho-Z`lh=POd?PL6Cyl@6fBQ*cP^D#L$h*5w_bYkQKH|7}$m8 zwqV45%Rd1jj@y@xP|G*TEB!Na<|^TkS_|CBT#s2|pNXv1#}Q4I4u@=Y{t=_6*M=;v z3wkqsifUuEiOYWJNVR-hU1$XIPRv!154lLKjC}$teE1&hfMn{qAaiHz5&g9Dq0mn? zJm%PL(LK?L#v{=Ad~`rM7e?TpA7JK>G(4QhzkqS)w|s-T35t<1y9b8#TLrz-dMyf| zf|Q}2I*atwJIH2dOv^@*TOYdm6gqJphTmp;_hCV>NQ0j=&<3Hh>Pa+Jd(ckzFvu;H zsK9s|vR zxg{z7`-2!Z3gV4jgN;px#6payjv^7^?UaY95cMA6eEv56u82d|4SaoFyka%{c@dsP zc5Ax}B_QB9BaPK~qYT1zx0hhS3|z;|kw<2civ?uA8)dwrYdW>TDwDA<8Q2#)FU5Su zqdmw8+4YX36c42|yGXWr7q9c^(-o0BMF$^5xfxahaJ1^gsM-XFt9A`|&l~Vw(C z%o5wfYQ#zMS5a9fvY;GLxiCwLMKu-!jKEUL97%C>2+g8{j$Vzu?lh`!EG%S4L#>S* zl8jcf({D-d2c+NP=m(^D&l~Vw(CG2`#Tz<{89WDg9}DjpeT<)%*0fDELHJJrPCcAE2xJW;)ZdTV(k7P?FTL zeXEdKdhM6y#Es8LQX7b<=ESwn&{+lut$rqcPLE~J-G%0RQ_D7;m~Ldxgb0(|bj^ce z&vW4MhKT)!zaurReh%7iRz@SjH&}8G;x~ zacbp+euy4rQhIo8y)ZQ3wx0d3A7Ukj7zG*(o`aspqQstqVoReSS(gwno6aWy?^yOS zsDSmD&Zeh(4b5sqwX8vZ0Iu+awMX-?>>IHyw%v3-PkA>(>@bk`zQc_*=YL_GF~ebo zt+6!zY?K5nka-@byvh3k@j3sw*=tF1MARI9(UznsqIE%@%e{gz9Uuwdt{Y&|)F@`2 zp^CT3;%%0AbBVWk;%%^aTOi(S;%%{b>!R*4qG}ZJrHFV=P$T1Sf_T~a7Kj(K@ymlW zM@-1uC{IJdF~n$xLy*){yUCSK?Se-CNYhEQAJ`JwR|)J9X$apd#7y&W~7aT zitfXs)!rU$ka3lSXBmO!9_yXf6!akmZgmA0(_1*e*39qT227~!09lyl0B89pO;P3_ zP;HKUAdK!RO|ejnZ~dxwo-bk94}1`x=QY14Tj@FIg|eB>Q<%o zhfiLymH)^Y*C-JfU+vpuTJY7r;|}Ax3c2f$O!y<$T4F;mwpPT3DVA+g>8SZkcVRGY zlwitG(pnW8fhF`-P-TU-da!`Zal;Dz?pZ>?D2po?p8D8GkY(HpCTs-tV^-X*Qx?}@ zaLaa1fIZOPzn^5noP;lbSWOTNfNC#a@u_LD8F^}XXIH~x`f&cq=O}pKIR)BU0D1Z{ z6vG;PS~g!#X=LvD%wu*nShNx0M;u)ZIdUjWi@!L>`1G_IwuWcqvEn>PGdjLCT2jKr zd9RRT`NiC`uGbkIXzIjueU9jvAm-jbgf=-y3~I;Shho|lkwd79uzcJN$$ub6jZC*d zBdpkMws^k{7dw`X@Ux9jeBC&tBe7eIRu@1Jy$ZdvPn+5Vb)&v}>{ws8z zjXVCf&Qh&e>tktvpn1*EPsQQVhI@9ft)OhDa3>y;0YsHU-_pkHjGQ`{v|3AS*t?dv zQdIz1*+yPWO?ywtH5(zPyaJ6^v?|#AzFigKTFjYlf#02=(A|m*om|%aM@Y1+AwQ*qsUfjt-qf6n;d-P z*|P8aght^vf5K77aarh=mD(a$10}1!LkCUgL%$|#2~w_0$#3LBwS1pyg^3J);^1%Q zB1khoafq7HVx$Hc=yJfA?7vBv)`dVnKQ7SUnK+jtW_OU6CR`gHpMN^tr;jnF1vkKC zgTRmT%wGW7DE3hPh#RL#cVf_i+Q_we{CnD5p>tx((4Z2wzyBrKKR3`;{XX3uDb9|BilvZEWRF(krCSaBxE;ZKtG9usXhB zW3NRiNyF-YiyHYw5FNlx(eB-5ix}f187wlUn9RS^roMQ#vzkdh3CZO~iE=~#Ps=p| zvwtsx1~-$x`n~8RUC;EbMUVC01nzggQNwC+XwRWp@dR+WI#so{cjydr}s4(oc5 zv@2u~>U$pZJcZ{rpejiR)3$ zK9jAT9bw1#&EE^-I^u7m9I7MfzZRvkV7dJjI;q@VG({VNF5kxb9JQgtrdk^iU!!yh zP~x@H2Dz*O_I|+oz8oqhU#IDgQmpd|Jbz&H*!ApS_%??U@turL6j2u8g*coVeT^Kc z!~enuyVhnLbI3KE;BY#(p!hsw3)%%Ym9kBKZ~M{<0u7(qK!Qh56*MC^z135GB}w&cEnSVM6fXimSo6Db-UVNpW~jLG0Y>DNiQFp(j9WaP^emU|fcXL-~pQ7DIG8Kry$639eWg z4Gt`YFbzcX^V7l>E(s4`=^aJZ=<^nIF;C3gCUV0>S80M-UfgC%eETjyAGA zH99jEoX z8SB+O!cy5z-kuX*qWcN6pMyujD}6!qRbejslSq52U)rxk+9Hv*AUQ3j^JlSdtdo=) zY~=yMqUEGeuuXuyu}zXxbgK<5`VBd~$hsbH1Lgf*EA5yq1=fA!ZbvD*&>b5K&35jk zW}|zPn&riZk@RyQ>=r%EQy=Y;@KS?=dWI4ywes^DL0bhi!vURd1!}$AIN{KS87DHe zT;qgI%L?KtKtD|6g4iWNwvH~4p}QfC|H7~Y+4UiQwgM5N`EmSx0#U49lVDa z=-sbpv)_|j`!>bg8MCv^@bK=}G7xS%z^xAsh6z^4n&uA^be{Uexy?e5!F@kGvzfhT z51=AEKkfH4z9}@FsdaSW1)WA8Ic+$uj!aq&rn51Oo3Q)*xW^>!x+sj-_sSkAaW5LF zr`b7Fr_S*i=^L~XvYIM1d}WIoq4m;JXRH0QK&_!u;8 zJU-HeG#KdXnc#MkQ5<|osqtXqI_O(xt z$f3&q-Bn)KqVy`Squ z(f*44S^PDPX@~JtG61oI&K8W>*GA3>Ao7gDH3Fz0O`QfDw;5HB({$P9Y^#M@_&Rcp zg(N7vDe+&l_0$7=fgVLhJLSX8ZU1dM&+Y z@-G0ycnR;Acw7|x<7T9#7TnN3qhDg5j5pssr<5HIupY&@7n#>*fMrUvMR=O*(11Lr z1dI(1&q18GT$s0mz7^wP>R^Hxj}_t7wrF8UtFzXosb;gh!hPB$ z>UZrCsK4uL)MTbr?d;R%RJNs-?jUZCKwi>U1(u@i8Y)#0Tx8{!Q%OT_CCNUHbg~ zi=N3xwX#{uQoFaKf6%{C%8lP)^7Ugv3y0tbj}ZqBc=nmjSxMoyA0tx)3MnGuPmc*7 z{=y*W2&)9%L(GKT>MBpXxuAD{5SUvqJmyz#1I~2651}XCPAL3mP|A|;1FQaKH*~nv zQ(uZ6EPxq!q17b*`|B`m1E$3b$M1WjfdsiG5AX8H2{bn#6OTFKd6xHO7WF62j~K^J z>)HIkwuH?u_T!q?#go0+AsGD1bIH5Yx%_?Ff=M=+G2421o!{XwI()J5{IzXoa!#bH zPU^SD&9a4YTSUS~gJ1Bk_}yRV&6e!FHW9y)aVDR&`1M|G1ARR@-unMr(|@>+4R3_o zqrQU2nKgOt@;Y19dq=?29+>dH##L6< z1LbZ2j&@D_Dy<>_O+d202wxlzkHagrL@*=NrLP8JXaOMyeoxcyDf&H0zbEMTIQ<@@ z-yY=Zm%J6fCflMGWxoT8Fz_rPf6evdk(!%sCKI^lpg5*NS6c1VhXlPF7Y>)LND3#3EeCC@-3IM;A zq6db`HCxdBxKbP*CDYVgZ^Oc%>ir%Fr1#Xq>>z6vSKB=MDk$jXTM!NL3nF|L1exS3 zoG5^!|tIHrg;`JzTy(=rG=9I%dKr(dAfn zs5Lf3Wiuv`YX$#!GvaCaB*`exlY|(N@IdeNM-9dS0%)K#OhQeo{JVO*=$j8~?X|uP z)U5IWFxDJ97Xb5Vsm9%TQY??Z{sI}YH*+T*$?U;U{)?Co8}2s-uB5wkRuznbo__LE z+@0tEvEzk*NC}r%7o>O&ddw2WQE4jQ0}Itxg7=IAx&1nov?qNs{}li;u8`l?a)#NY zVO-iQj74v!;?g>S*VskuCqcmpG@Q08#@A!7Wm%m;K$)`A2h3SYohBFhQo4NGPlMW& zLdugxPgmH+?(HvIwB<^dUv{{(Y|jq1nYOt8cn)3M_-!|0xEwl6XD#i|LjBh=TPI{s zb5zNpy|}N_ENt+RnJCKD))UdUS8PUO(oh5Gn>iollwL$kC;)4sde)nv}xCfFD%-OL3UiGw@`lekLU>nu^#(;H$ zio0jO+GY`4%P)%JS2ixcfcB;3&_YZDZE|$t^04Q8V05LGAHC8{beq8BfQ;pR9vLR}#Lcf?OMl6@ZDG{~|VP#Fpm{5Yb1w$XHcv`CET zbST75DETL?OWeMq`R<_n1gg3;a3!FwhTf3+)#|IAk9QDcx3x;N^Az+)O1{H3daE~` zRq?vNLPHx&jb+Irrr+%Y74=?39zvlMeYm{R3R5xH=*gIiH*Me~s77N-QkE;^l{iN8 z&P6_tca_xq7OQMd0m!rwY|C6&0e&7xBZJ7n2)_wEy7vXxH-wJcX?OuuPvTcZ zZp`+R%{lV6+m%L#j5mrNRGwRhdi=(z8G2^zFvVSN{*NvhaR^b$o0 zEbeDb{``6XVNwgak7{`P2K0gU3GrqS%#&DMrt^KB%te=5@n~nf1~tD^Eyp7h-X{48 z+X z4G&X{rWBR_8t89sIF(+jkDbPDZai~0mFE9NH^0#YPF@Q@pS7!dPyL{)xaA*R5AoEe z>(F7E4n)(pi-6`OIy1RnXR<(2wuoM=r@y)J*XrXh1J$i)NnYvXrjg%52M=(4-vsru zhSlhM{Y?IP&yMyUKPUnTc*UwO)o=hhu}4(^9G?5^TlnQ$q5oN!y9E6cvRzGmWI*-j zH;ED1TS*h2X$6k#_jWz{Zp;DoR^oKRtNdgOpg%h$dJFVH@t%?&OU2Q6<0RSvvSi{e zRHyi6is}4iyh=PK?AaH6@+4x&@e0C_$FRE1JZC-Bunf=JMeMa3lX!wp%T%hSx<|?( zJb=evZouV8H*LNPLBl0QRfx|&B|iCuyb%4Coi7T%<=RoC#v=3Ve_?muo(%E!pg?RUhb@HG|o@<#oXVhw-UJ&*!J>O{{fSeWF&nj5bMnIQSm%21Q;j5nnIXd>PBK7j|$-u9jA zddEi`+67EX+LJHqQw!WY<-Ic*D#ZQY>qur^h?4d$yz}`88Hdnatm=88(-tbmBMwO) zQ3cBds6er)spQs`I6pE)jofJBH=?}97iG#TQl`TQjIp8r{$@3Q6AYr7zlX{SjW$sZ zYf3<07QYKPir<|$%Q^kB5>(~!=1BS$!Jbm@7JX1a{Or_S(1{HNY77oTlyTA7Q z7%%m1)USdNKlSbzbb9hc;)CBsou0nbCT<>iU{Zip7T_k9II+*f^-bc7PxJm39~aum z*j!TdfJ1i$*|s2S;YH#)%qra<$Y3jr4kR8&gGiAy~Z89A_i^b0EADxBK zS}J)md>Qbb(o+F^{7Q;KwD$u$e zs<~D59cUoJ(Mm&8Z!6nSoBE115N2th4c5vfKM*|A+pt^WX2H-gHNfpOr4~ zd$%pSTw$#NlsUKf3JbN2fOVsHn||16H5Jy7-=O4gRJ;vKGyDa{$)Wu*0N0;1&LBrH&F@>&>Qf{{wVDSS{~Vyq$7r z9MyRfUI_VFMx~e4puJA0UovN?&9 z@Lei!Tu;-D#RciA2ACPtt!2Z4-P0~onm z`&n;?01&!C0#$v}nGzoX?JCg`04GfQ09)gC78Q6K^vvF2iDf5xMV*1+G@aM~lsspkju8+TczXphIQ*;ZdgWW;)wcp!~J2-$w3x@i`x`Vxo=v8CtsSwE) z+Z48y&vW4zb38wU=7iL6tf#RPQ9KO-VS$>iRI59pkIlL;?>-60>E2TEvm$!NL#f;MO2I2Vq z$WyotqDE|2++DDxPug_7rX7-`@#_(~|1R-QzTnL$y z`@Fd0xY#{Nc8x;XUI4Tm=)0~0ZHGSD-+CrN+Z}$E9b6T63i9kLWu1O@ zJjkMvMHWP)X)qb+-22a;3wXAf&K39JSyasto;DQ9#jY@&OXgx?wtZECf^YSQv%6O! z`fZg%=L$TOLt`kgO|C(II;PL_9@W$Ewo_1Mi(nVD{w+LX**(OD1~r_07E`w*WY+xPP~o zWno0Gf<`mcdGy=%ZHu2VWlI8p9y6Cj82U0 zq3;GNok9F&;0Msy*eITaO0I9YT74Whl$fBh zz6mm-4jfY&I7{CIrHKiWlA8Em&W}H%2YcKJHRA+6e;rRC8_;z9($2gpX0LQovjN6TI+W{_`A)LM& zaxk7C6BC5foco{VXANp5cz&(}7EGUSV!**u-x3FD_^CH3kjK9h0T+*nz$E^e2o&%= z6v*W5BErX8L_p>5i9i`&Ap*1bKSf{;e?bK1@jr<`A^(jCEZ|`gSj?;5>^*hIH4#R# z$>)hMk`F#xgpsW9vNwAV<#E3V(;e7_B8=>pUns)Jr@2dnkyrDfB8=pQJ46`m$^7Jh zQ+PLqJ4Lty!(WInx_I;5B8=Z2=WQa4*E{ff5k|d;zb(ReP>R1S!gR>`SrNvgx_r3^ z<1t?kcd$sW|fG!ZE{KPvkvR zj|L4ihG4P`$^5#1ByN~`4!HEcdtoVMyGv_Y^+Brm*+G_{s}Q{52;N{!wEJt*W4sqo z>wf@rcoLvN)*fW*LBu!pJf+SWFdLQHlz_P&pu3O`Xdj5V2gGM#yp~FzGX4UawwBap zK*Ms)T>OG6R+Z_m_2-&O#8(!3y2&DO{k3?~4&5IB4HOJ({$M-z-$TXJ!@4vyvlD^z`2Kb2!j>j$xox8lw zGR2mmUnnF9h|>?nS(`oo2{C~4gF^0eXa(thn z=H+BK$r>*1EnEnEdkDb`JdL$bm!ha~QB0 z+5L7Z2KVk%{E=*kJ+Wc@ia>_{I#qjbg6*@D zC;T!{S5?sM;s72|e0CkVEdcTqjd}YObiSg~Vv%ffK6)gCXC-`ob>{zT?@i#MIIG<;r5gnW*G|O5gs8YA)7TojrHPF;h6pOjWC5WO zB0{IRS21xx8xrx#j7gj zvpa)fr`A(_d+qC)sB59yc3ij#ct`ImZScb)2Q=DIfUCZXP`4^#BkG=uM+|{LaL=SyMw}LdE(pb&dD&Ph41MM z0{>gMe=m73_czcxDeR%fA?xuyJ?>$4O8c|$aPkNZp*|AkMd@MoWFkK*r1xcNcUM{b z=e0{>{O5IIA1N&H38;rrQkWTFU5pWJLuAtnJs$ZaKhI8%sQyB(OZ_VOL> z8Sz^A)#rMwt{uT7yeIPy3?_81nO{19iwE{->Gq^PXPC$ zbcZiy&^tHs=&eYs;1uYU$({j5Khq|?%in51VzRGHK}nsh5_=5-pQRAP{0FpwaD1mi z3}^n3y=g@b?)dmGXxOU@h=%F66B%yeFnq~EFgV`ARti|FZB;@{wJi@_5RbrBj<@hd zBUHF|!7L_XXt5WD3WHE0U@=#N;xJj#YQ%BOyFe$7vp+bcW<)mw@SWl~)1Vh3?WV2! z{cWj%evY#ZC~hiTSD&#K9mgjv(7{^J-?-ah+gI7gf570do%dZS>TP@G5AYw*<88Wr zE@iL%Op`%O0$Zjj?@m+wP%j?SI!>SU8GH&S$78p&n{hcN8g1vrfoJUb8lkWJb{N+9|~C+4Wf)L-AC9#exq3f;T$to$IpH0Qum^7@3z=c%y9o~*eaI6X5UvD+K^OpQ zKeK!U$aGm@;@O|*MFN=gfd{}R$@$#xKZ$x-hx>`DTQS=|;mU__hXkMS7K&k*mQl$9 zUUZ0---*H+i#ftv6jRNc!BquH#yF|Q7bfzjBxK)0Wsqu7wTXYi{s*Z}x)s#x@Xd68 zT3qZO`o@FQrT;BmL|jg(K}pz>P1)7n#n`C= zal67C5Au6TUvI`MCv-CtWozDCM*By}_HOP!W~0bJyZWH@VWF4Xwo{0)Tdx%dQ=$K2 zyaT}7rL2Q<%LamFQV{RR_by|n{i!I~FAk;h@}`Xu#dSJ+H;3F5!9NGjpfv{+#kSK_ z^CV#ir#hv&XgUO+*DOhO*uGtqB4z5Oosg>OcMWc7*Oo|iGnbw22siVHww+=xSK%^@ z?6S4{hS{wZ8sSQbI@sAM^;o6LG5HX@{U836dbyw*eCZ36RB(>96~hDg9@Lr5_LM0z z1h_~py^`?xG!*AI)#Clh!1Mc1W@C3-4SS-Q={M+BufY4jvXt6lu3kq-WdRIcuKM9) z*3n}>|CfVN0LL{~$#bE=qRT%%LJ=qUC){0)8a}RuMR6jmt%Yc)Ffobh9SKCgc^X03 zn`h`&zk zT*4!K=_efY8kI2mypH6&NSKh%WI#7j5$yg6e_e{`UegKP{@tL9Y}2_citt4!Y_v|H z7#BPd#CZM_-C)edP=0SIL7vXS$kzs=1?~XUN7-U_JPoK{<0=I1C8p(R%qR4%PgvbG zo^hHDC|x4y&4KG=15c^-_dQ-^I{i3b+t4|v2R)m(OzjwtXFeSirkW}VpRyCpbELfW8N3Ql?Mcwl#_;EZP63N}_E`UShy18G$3!!>@nIOaYZbvfRdRoh>|Byr zNqA`r;ezoYis?}+q>F2(2RfuRaNw!#Y5-C(n_bG#k|{*h*MHf&4)#oZ7ezXmG3E?D zY#uESS;sWmJER?Ls1fhYC|Wn*%3gd(cGZX7^%PFOc2oTmcr0D0OpykhbD;}e^N?U>1r*M!cb8#Ja`)Oz5*59-6liv1)eOdTv8&nq2lpg2T1>%AJ3Bpnve zDe1hP=B`EA&oeBzl2DV$QikqM?Tf%3aM40RpovZ3<*pmzt`B<|hNh`0fam7tq!C-> zXQdIYvjJE@W;R~bquh9-JkhO_rCp7!VNRXwMA4i;k_+GW!t!8(Q1D_%q|HJflR9at zeF`UrUA#_Emr)yDDWb1-)lX@bOOc-FnJonu(7NTWYL8Wo%8(G&tl8ovy~$<|eP5aogR9>(0=D8tv#`Jkb=A&57e`@krcN3zTg}?45u}VgDR}uq6fCP z$(ei=OoHEJQpSnCCt_sR{GQOVfqNKEQGM>?EZjc(jGRsn5;MK=R8>}3{(b6+a;jT; z1Gm;Qq$}`g4OlOpty@f}#E|rrQ#$XeyTf4HW2)&*FD=YSR1$JsC>La^K?QF9#fd;s zRP+=49QY#m_1wFfdyDt(%Ak`eF!hR%?~pFkDyHB30i!@o2G4|Dwr0}<57UI)k->A} zvYyU`4_Z6qP*B`qJQsJEM&DN1r6~1Pn!qC&(muDeoeSL@43W86;X(-mfFHpQn8VpC=Ih6)}AOgL2t3$KbgL3#$IaAl+LsvYvfE@OvLLt zqJ~7Hl0;l?V#;JJ6+YlH3uv9G{40Kh-)-I{OzJiPhBoDvj4W@aE4%SglxaRo7h?(z z;#uZ84GM8AOZ$lFnppcNzr~c5is#QyR^iTz$JHTi{A((Efj6)x8QT_q4^y`rAE0Ou z#%Gu|8Z(t`j(W%6P`A3?;cv8nlS|pgU39p`iTmBg4Aj`@wCxu5I#YH#q( z{Fi$7vJLmdYYtITavejy>Po~6mUa{5qBT7(r58TTm(pF>EF?~P-j91ZTV2a2wJvyr zX(X?TC*qLc`(pAyMNQ+jP9m9Z)5a{O$xhblU|GSXCxO(IopL*Ukh%$FFa-n9ncj9x zIGA#*yM^F(b*Xb152@ZYp5Q^c5m9xkc(p7(++%T9KBOqLY=MDz5^#uLNL{d3&Vvy& zV1NknBbU^%1k!dfrW^hnMjV@UYu5^NciIe-2#k1I2Xs#~h_{X_qR`Ao^#z=P3k58K*npjiHAL;0VARM)P z1zJ#5SiRG#=~!omUXkqfy`ogQ6hNuyH}M=pwmy!NcLT};(z|n4$?reN4_xXJFO#?a zX0@WUZKTVlt7#GRTw7f285Vtr{KU^he-)w!?!^MX9lV7|MZJn~qq24zOpqG7`IxLl zQL16(3fGw;#>?ps2Cs`+!6+r7vY@6+=@3TU`Z>Mib-5mugx_KZ`#{jaL_g*OR^*IF zL*8Kt(e{?g^k;B3*h^V-SYFAC1z3bq72uV#>9sWf7PecJh%;d}6WKW^-~Tce3A}MT zb~)E3TIFxmFhxAe@d(wlQEzR-v)!N+mNPkDeLY}T+b4wI-%|I(ZjesVCp8)`q8`%y z@n$3u?%fHY-#NKY00g+se(zz#`ZZkXd(k;=d z?p7-@fo|!5W3$H0_C1DC(W%IA+E-Wk8!q*%trdmtLN&JHT2j8GsQSsu*z(biMastE zrJd^4(9v@V$}jI%LU$hMAjrz^M7(MFm4rPLk*Ptpg3jJ9=^&*J`P1JpHZ&VKi+e*8 za-#_9etOQ@F%A1C(h^Ok6fovpc`q&D!UVPr0V7wGoV=RVe>S0t2pOiew<@aIwmh64 z^4Y^fG@AU~Z*l1z_;gM{%Xv)ejTBLh)ZszvgErQDf|2f6l;zgZ{*aQ6_AfSTeeYTC=;Nx-=p*dG*FbhUR+`2cd|~5U zn)wFy@<-rvdY85huMwv`g+*DCLSwE{WBMVcspejwhK|U4dE`&C_|6ZqejO6Y3nt() zvfXL>-c)lEI!0!Y-Ck0p3dl3*@EKE4I$UMYJA~w^l1AXnuOH4ia{(nbA-Sg@xn1F0 zO8on+Y(|2jn^YFNi3)9gPXl}LCIqXJEEE$zL|I%RsN~_`c=oi)546SWvGne43-sdn z4k^@KSVwczV*Eghk=IH7bW~64j5*hJl0Oxea@o_~>>QGbYz9lxA$}^%3}TmI;46gv zq4K8Tv>?JDX@*|Pf_`%VrrA*cnd4Q#(;&Y+auqVz(>fdmt)jxHG97Dva!Uaxbj7Gl zDcmV#$2+0tI;9sF-JU?Y4aZ9p4r!14n{Tm_+igvz8iEgo+ja;ZcfDHaQVTxE9TZJ{ z<6E_yrkZyzuvHHP-aw0Vq*Kt9OhKWGJ-2gEULpY>^E8bE{~7{%jLW+zYhzY=y4=Ol zA`7oN76K>_QuAOCE zU0ldjmF!+kn{aQ3aQD_9f2oXX7hKfomLl^GPPWqApPOvA@yT|A{OSWepa0$8^JGh< z6>+}Zs?N7`(PEdf&9(1}2~-_e$CUd=d@SWg$!>5l_XFyb+jYKuoV~YbmJ=UPwLi2i zMDC>9`L~C9NdzXxJY!~Op^h;$- z?Q;{VQX*R>5T@(+FM1|SjgQD>;+8ndjN>JQnpcqWtR)(kbp56KaJIVWFs<3;vR!`; zY$D+KjYHa*X*-Rb=yYHPK6$P*xYI_6rRd`fY42Bx$C9(30wHv_dc8z5b%<~0j(0|#2&RI`#( zsOAm6aB$%R>Dy}*rtxj3P=>xIURRVXVA!RDuKH}P>^jD%A-+prkk?X4g`=oqKIM>0 zmz(T$uDI5vY=e?ynlcV63H@%s((Dvt{d*O;)UO`S;HY|{mQ`~UW_ScFfGbQTk6*;W zcAvb1xwO4_F?dH-)tAGx(g-)n<6mb}dA&;`57-pE`!?KFKT|`;m1epAXb%g<&#E!} zE_FrSNeNEp{IVfGHf++1!n2C$)qdN@qEmi!dFc2+83aB){An4gY7#C#DDQMGibroK z$(H6bh=ZwKM47JkXvD*vHgI;CHbxcO4hUmR8}U?QpdJWQ*>1Ov5gs#b)R{KzZv4a$ z)oeQt^Im$pvp3LQnRTR28ix(azU*ZQ{ha!lZCyMI)xlZkkKiqxvK@zh1*Y{{Q|)q0+;&uW*ST`hD63;LeO6Vg zI9e2kY3o5eElWV@*(hl{)ztH{|HLJ?^i`mU+n;zR;IJKYm?j+qQfRE^%*-yazkFSF za9hMdjoA0wCLjWKFDIW_WzBltu@jKfZ)%%(~;v`p^0+f(hTB~v==*o@~Wc<%3F z=d~-{sgaIx&8C{)64Z3ebX_}EWDzxz!@oyy=-$t)pP_Nomz;I3aHd8&$0@>WH2|cL z1}O-)*p3TXD~!Q-y7yhU&02B}qoe`u8gWEOoN*XuAjC=Ph{GbBho~55oZ2wRFQhuL zUq_GPJnFVlY^(nuPPm1+$*H!Zrd8YYs89e0;|DhB=^GPcCMt^VD@eW_)4^g_n`#z< zAE2W()!=Fd+AP*ly_guqh-!DLK_3XKE=o20<{+ad8WKFfzC`M-bcWB!fTi4q5 zHb5v~d$540CS?PS96gE&DL`_(xbLOXms5;NLfS}bx-Sh@1%e1g%)U`kLJQ~;uB?8G zCS(+@wy#K0^H|BQ5w38KiVRH7w0$I+)L>#*lg=0z!^w%OM1oeQI*Qdmkkc0v6h$!M zn|@&*fDzJ$BD-xx$#&CnT(|`WhvH#p^{EX+VqMYdkphmCuaOW;wYc+aJ7uboah*#K zPBT-EpV3u|hD_b@w$~_!e>7nB|EOP@2*~<+gSSI>6h^#B*0+dxtcD0DU|^hN+FGMQ z8&pZWtXZtiGYQab{*L;=cul!VgZR7>3bi|{!!K>9O!y&6V1+jdudSmk&{nZl8_n|`-T_jTQ( zR972TnC<8m?8-uHu_J8;>4A8s)sG*R1@-K|FG#qiP5R_w|2d%D3=OJk+9{Ze>7x=_ zN}lwIg8Ipqf~2c0PBT-|)zftWlJ1Y)k?!Uo>Eadvrp0Nu?+8ku9H~MHMAT zzor`0O9|w(%GQ;JZ=!`OPGji`Q;X|TRg{o+5UI;VK zWvzRVdw1Z(`4!haGeF+B5T&l`66N}Zp^|I~^k%y4C)27=aXOjMe=$zHM=0HV>6XrN zvG)Osv5S5-IBV`_RPG(RvD-pL*+$5>FQm$1u3y+8XVyvmpggsTY0SfOTxq+59Uhq; zX@I4FiadzLK3f%357;Gk42vBo2TnBMV@07-^OMdvEvVqfiRTT6!KV@x{2U7;$bYU1 zHo*2OOq!{#@qbL!qh3S(A-@NzdcyXp1^+<74}ZVQU1v{p)wv8aIvt!NQ#eL(yk70V zCH(ul?CTT3rM^N_SM?R&B_r*(Vt4sx~_|ngbEQp?jSx&m!ZREB_&us?vz> zN&_E>ielRGg~^w2wu#syh-h54C^;8Z>I%9H;}5vmjXQ_f0U8`bn(>&e+ICRLP1!Gu zv+Wl~$*(V<`i`O$dF6u3RL;;mpkCI_r`tq7h2x-hE|7%Mt%3n^B#`6Rj=v$#8_+qW zAE7_C;^_1i-IHxI3)kU)L-4;O{Lkb+Zxp>aTDO*(TgH0asIkbppQJEnGW+;IqVoCg6S>+Mp8&S4|+{IC|Q)3H{qfDkvmz zG7yK-qa7e?vJkj_ zQxawmV;fC*^!>A1ToJ!Xn_Aj6q|w$Wrc*A!Uehk5U7jkSd3G>Onx+fsvqWP;6BTW) z!YFtB@YIE*i+<@$$+?r@)tgI7!rfQV>F)ucMtKtaCt2I}>A9fprJ;1<$YSZpRX>-` zl{6jcm^?vb;(>We!py7b+Z`{-Z35OB&VGU4Gk&|*}G*s6WSqGY>#_&Ws_ zH)3KnSo(=^$p1Pa%GL<>>|!J2fZb5eh-3~MXdx&TsEy`L?C-VTie_lo+#!v4+2fno zfHtaKY8uiwf!G0qDHBi%Rk#jp0EU81ON11#0Z0a$p3pZ#^h6xCVhtUI0)yYwKrh22 zfP8v6S3J+04eBt(I=!g|aRDN7I-skVYG1)!4{6s>q&?h3vzu!0b!jwK3yTmmm}(!; zP-gM|rF4trnfT9t0L)?BL$W-78~$;rbqBXgIZnX=s?wfE(+GWlMRFN>~C?(RhX70+_knK^~{Aa(|PKze}BtdnInz6s+pBg zw9@SstQN%H@s^He0Bj>fhGOfT&Xk?^B}BFcG^B)`T<`Z6h_%szQSf7+6C;@ zpD(?<8`uqH2CJ*EcW2?mOv$|y=%l(R&bqWwHaE0J7@Todyjk|{~o%Q+hDMS z5(|(9N`g6R+D$c&5O(Sf{r=7&P#9-&_T>W?)%6k_yrB3N9b0KA3AYSk*9^oPl!U`q z&_U@tFYdqfM{QD6F!o$n7S)>vs7$IZN;F)8W_=cxNNtnwWmPQZ9$L)vYBBdiu6iTx zWs9AWJZ1MJ} z_4xV<#uYI+wwmN>8mPhGlYYzK3QD}}aNtZ9yYwlwxukD1Z3mzw z9x3m9K+v%P_{uznZ(Cnf9%daSyq9S^A{=l@+Du!M(B!nH3XNNC$B^@ZHQO?h((Qhi zbWSdg4X%Z4O{Ur>so|2TmafX{XQiQ-*YuNo!?uZCRzSBAYjNlFsH;9thZ~8f%DLEG zlc@$3OF*-gjU|M?-yv?p@vEuxmM&l~@0*JoM?1L^@vjP1Z=?%8lFD z9wAbFHn?f=Ra^PxZES!SCb*=JTq(y~w&SMXG!neRvThJk7hb%rp9Q!y(*w_+sPZ4W z(>O}rHaED_xM?mjmpwj3bQitbwFOrTkm-E7Wzp)CwrARoyQISzrmS7y{OYrG`VgXB zk1FNT!;)-W+j&Y7!nWq1=ACO?RS?{O;$rw3x211UD+MS`0F$H0umcTf#) zhapf?qdHILqB8db@@{;g1UbgnA>!F%uKtSa>~YkGh}s>8%3s~BW+W?jD@-~6cl}`! z)?olsO{_xI$7RyQOM{7@r7sb-oxRlc9D-j~m%f9}HtisvQO&ad?vRymV7gN}2#KO_ zCLs3L0Vp1e;S5T`{Qm5vHhxWAf_Q;_!E5TIoOF9lz0*~I&^Hp?g)op0+&vF_SF^+4 zIye(%pscwKc~hk5y^~ftHP)L<8*kSbv<;4BC+JGXw6(?Y&X3D}q^w>ZKwR~q#u?=K zh9Lwt&w>ybJlCXZx5iLCMbhtuS&vwkft^@2fz&SU%c;9IkO(%7VQIju`bVR`##)_G z`+*p-8S@I59B1F}-!PQGq9qKGz>*pGT|p*3dP8ZC6T;LIMcLekuG6Hj*I+SLr%~Ua zapUAb4-s-^gf637=`vbstDmfQ*3W_U=2_>;Q?Q!t?LV&(Vwc1@Z2Oi(P&t}6G+D4t zwaZ6J=pM?eC85K-x}$*W=bdw4;se0t%L z3`q0#WUn+(Uq*M663TFaB8)`EvW0uPay(%1MUxX3@AplPPIkb=p9LeMOqf zZ&aYjRQ1U=1Jx1I7?Oi?+$mwS!}eh?C#T7M!fE?*NneMwgGa}RG`_46Pdc{J!_(Y3 z*i~00qaqtt0J#*ZrW+?cdPy2`vuaq&Sm~7sDz}5o4!i5;?28gDO2UP{ zNNcOOvb|P052y@k)`;5D^pIb`=f9{G@fpjR*^08yc1lcP5(Rq{CE;uz^*SEvGp7U9 zhv-!J7PSQ;>6wpBMgbHEr6e3l#78Wd@G0X=cO(+3Yr!PXEDk=1g1bY@cC>~vhPW4J z&zW)g9SSMziYdW+8dYHZ{dHJ7XHZu#Fmojt^~KsOU{mU}rcGh@Uxz!+ka2O{B*V(E zh1X%To?9`=i0V4(=*GYqtf*9+Lak^Ti;w?F7nn4`Q54_zZ#UF0iqNsU;tB@IL(=n9;CG?psU<(}Yv6+0Z|6Cta?aEHO zM{G*B6+(ju7`{ZF`Uqp&td9EedTi!wV8ejN90TsUbKKz@Q_XEukwXT29|hvE5WRRI zGU|);YAL>SNeNqSL+0v;m?A&_ASR8khP_DLn#8`DlF5HSk;l!!ljvVz!P;;KDMR|^ zFB6>B(ZaBmTHy7^Z5Ia1ul){VC(MPY8TDmhn#{tTuKH;6N{wS&llW1FbUL$ee_*8D zdXGj(tzM`dCthp4RVNO0)Ze6c6*jwcdt@(5;ToEP5FVCUcmSNONx~in${c;bS+*WZRN2=LO*{t}k59QukfM}WId23(>ZU8nxcZ`W|&{s5P(v$g2 zsV{v_eXlF!J(uo?{KlppShi@Mn1$Z6z=t)VdjH;}vtV+{b}aT^5Mz9dHm@mNAx%19 z*e1I0B>|Mh&Pai_LjKLAOL#I5D53CU9JD`qmDZ9=_mdlIf2u?J&`k;KJq((1G*j1C zzG71kTxnH4;*>>XiQb0TX<(&1he?T>ooUeHOtlZu1@-OtSOWGBTyDK5AK2JKl0)+; zM}J#i&e0!~C%(}`&>!#Ood)~L)l{hkjS$;YgxwfH_fr600zvLRHq$l{)pGyJrR>80 zr5OJ#>>>w*FnJ&+DXY8g`guXuh$1E_=Z3*)42-ET#cGsIY=Kxw_OzehIOGFfPz7FBtdmJ?A8=9tXSF~m}=UnD{lM*H~?!vl)r}U z#Zk@04%<|-FBUq&vdCds6MQsE&enNvKbExyR(CBZqe_)kM}gce;}NWcKA~(FwG<8xI=e)!AJz=@Rj` zmq(PN(l5t8G$z#2nBB{)VYnB%rcr{wkQA^1{ENMWK72lE_GOI#ku%18u*`}tkvmLl zwzG%FLt{hp*=3!zQ%rQ1va;ps#%`SR`TDt2KJ4oDhJwrMg?c<%&||&O8_WwjN5qWS zHLp7hI%Q?2#dQ+lSN_E=vpMu} zSi|8X9IoeZ3x`b{9^&vb4u9m(n8fRo!(kkbPP4e$JIFu zuD^>xLkWXjf6cEj_uKn-@2~!f3rfp8MHZpLGRGrWJXNKFrLdyNV=4Ak%(HlX6@{M4 z$`QuUaD_fkf#3=Cvka{y@Q?n|E5x!QOL+yR27k~#q@0MwqM_V$DMcO7tAg! z@)XZ0DZP7c*}U=!?>)XsL7cy!YT>>2En2)}DLsD1pHD0oO6Pej9-ptmXCWkpH%PAg z=A0bnN}X~tr%evA66eiXj?8HtF4J#F9Wyq@=qR@oc)ew%g#|(>G<8WqrDa|LkW~S= z3xa2!S3puKt0(}HD)Cs-Eo%N{rL%nnzJ-?3^1=$A&r>LrEgWIYF7p&rdVny?g@QtX z#t2FM>Pkzc==E0kz{gWC&r%Epm{;NRKpJ42N5hOz%Y*ohi7^hhI6BY}A?>W3Om_(7 z3nitMmV(Mk&%D`X3oS*Wue5xQr5uu)?_r@z%S(mQg0j+kY4XNg3=g!8D0v{JWwtm6 z?3RTUqAwKJ5tdBB0zv0hR0>emxgJOzi{tZDie*6F#g@W?vNFsJY6@{0URW{DOS|5% zk%eWxYb?cLc_FP+if2IwQstF`Pb?Im@bHg%I?Kwk3QAeovD~Av+_YmxLuRLlocLmWFYDdPB# zwxYjSPDhN+Xq0#gyeuUQ_p6^N=YrCTE^XHl?}i@ZRSHEv6YqMA=M|v_=9l^ev7oG@ zk+3ysKnypw$Mo;2D9539BvclTz;sXyravmJbGhjli0xeg_9D;x(n60~i!3~^Cr_0Z z`VUYJ)=p@jRm1(NOSpMJf~7(UjPFHA5pzT1VECTvhes+Z5DGf7puZSK3S9>SpXVOY zQ;C@(1x@Fj9||XUeDg}nae^sD8o+KKmW!2GsS67Jg+l?9CpE3d@_5RjB`eD3dCCP| z9t>~oF?@kkSy3!lW|q>@ zrl+I?>&49mMGR+z&?82SAmd^Fo#TTdmKQ((v3zcM#e(u1AzvOP1Doy&qcNKW8)xBo z;rb~mqH^C?1m8gZ@Soj+r_@Ri~Yea_J_LIAMRogudcqodRaA0l)C$? z?_XXW9~K5PaBXcZAfB39on5^GX47F;TeD|X!~6=9aCSECxmku)uc(Gt1g7DVk`jX< zqRQ)C;PqZM|Ng)Jvt0H!Eckc1-{pTU;EaCmucn*7&LNhC{AqsSUugX0A%EIm_@~CT z{JX3Ff57kZHZA$TO#zyYzhC<6L;;$PKkYC4>!5&t_U|8+AOGUvFVq(5_lt|n%iY=j zOUv6)?yfGHPRqgSWy}3Fwf8@;qHd+Ms{S{>UH#xg53l*%Bac4z`0t;1@~NlSu6yR$ z=bnGz#h2Fq;g2uB@~1z)y5ax4_LtY+*tlu)n_K?+*4tbE*3h_Z`;MJWyP9|J*}HH5 zfrBmYy!+mv!$*!D`}_MJeE8AF$6G)7^u%YMfAOW<_Eq5I*Wa9K|Mt7@e>i>S?78zl z{&eBuCFP%90QJ1U`9%w$e|P!+-TD8wFF`j|GRiRocl5Pu=2h3Q~? zj6-q?1kqPiK-0O&SISMWzAq7dl|dUJvphxRo)Cvzk=e2;%Bf?H$YFti>0o?}gW)g? z`qOxmJ?dV}ELa9sEXWZk^NsE^Dm}iNXWtELj?50O+`;n$e|JHp;3&jZZFYrM^akCT z8%vI4LCOVlJd-M_Sj-tY8Pms%9^rJmS$Mz$&;hIfIlvK6MT}|vL6tzwKm|cPL3Kf` zLFGXmLRCVIV#UHQ{pM*m&&W+CBVhfFc6C2$#B7=jxX&x1@OGZxLRihrn_f{N^f>W$ z`e_D5lR-ih8B}B>gK{Iups@xrXmr2U#Fjn{NrS^k%-Gc=Mze~9L-{uk2ATt=ToZ%t zgTZ|Ob;qr-_5?x>^dTfULPPCnezq^L&(sc)4!H=~k=faOKsXry?(yJmD4NpQ&!8oS z-07XtO|pcOSj|)t(H_>S^J-HOpHwX&aRb80fZ2%+eY^?z@u`HgrZ9!xtC9%0wI3n& zPkC9Bj3jBSi6l)=Xz$$`*J5gj@kZxIWoyE)x>K_{A=b^jY&^TW5bDQbd*

      c^QryUqZ>4lS`s-rELD?eAc;lr%&27Zo9@`q-Vr(#YBl5$uSz9*)f{~UOV%d>IEJ7mS(HC&&LoAwJ zB&oe`YeGv$UB5mK7Et4u`F6a@5~(ARnzx8HmDjrvNs=J{B*;Gr@=qF_(4a{)0-o>z z-6aCu0iLuzHAXGgcWNA#uP74AXCUV3(G6-|YbO!XHyzf9yq@DQ{T(G@(g^h^6*!Jc`JO!)pklSkOTp~q6m@zxFw8^YlyqttwqiMxtj<%0pB?_KCN3L z)NLfxEtsc68B9PwMNvRUMq=^-9Yt$Nv?h)uB_l1o4z%zWpoI;T7O<|pu&#`wv=%{W zP0g#8&Tdp$xr8n}Ttc-%7}aTRYP9%qFxXH7jzrnZe1cP1u9|yOmW-~LwxV}cf&kVSk zNMB#?_PAD4OH4ylu+8knguDk|BhQznH@hRf+&P34!uQb$1~mht$v~jpfj~n8frbV` zSq6?yYVF$seI%5QrbFG(GRHuff!=eWt-(FX2jL7FVgQ`kcx9k%M#~(bB@vn@h^ALK z(43j{dM(x)lOLVU(v5_44J=(X-t=%U9k-@yv*YME7)kwA+>g#DyhY!jGbjSYBjgSHbi@)@>%=6!D%E8 zXv7ROVuCu4B?BK~G!jSqOAM4Rn)IFCIiC}22{Eh-sWaZ^lX?S9ZsT*h+BbUf^1v9a z&VOu7f&K+!VNy|W><*48Q(u7b3BC-q?P&N|Mx%fa&}OHxc;1VIJPhBRJbXNucfLf( z5^kq>&1QHFL;KZH8A<8!FmlGUN3}+_L^OnX_4&F~we7qr?z1^u4mi-U8^#HsZ$4H8 z$AowOM97(`#x+NUMHp_ex<->mX9*>UkY6925(Ys&8!e-0jm@fW@gp)@fa_@C~_q4th(sDmyv zVOkP4RzoxcBFO;Y14BxZ9R=k`8UpiS*H+7BJX=+8&V)M7je)w3Ch-rMy{T~>TLQ&+ z9^FoQ{QXB>g2DgDOECEFmY2xUO!ky}dh@fzTh2jB>%_OZSxurG*7$IUaicN60r?x2Isf=Q8&nJ5pf@13x!XpHt?6 zwfvP@zIt{P75OO6;hIq4hI=q>dd0kX5Yb&)4%v^#7_h|l38EJl)eiEsZn{u5qkI9Z zmNTlz4_FqKPkM!jb#o(&QN$bx`8%eG<;h*>^^gYQ^ptso%h0yzbJg>?V12$!u@QYf zsB_iPt)Ed|LQ{s^3q4+p42cW4{V_xjxb*1VqRp&ydS;7r=6HPBP}Zu0 z3HlMbxhpE>ir$;}VJkEM?vp%-KIsKsLG&R_2%ai|e5v943iMbEMjNfmQ{cVH=Yf(x zOU;h5vWh}-2Q5oBRw2nnvm+hmyLhatn=`V|{663}v!JZBh|*NS91l4PEsr7r*?7JO zC3q9}WX`$dD+q+K(sQr($-l5bXyFf5LQ&-j(p?B+U5k0+8_UkA~QxlL98`Q1fDC3C5o!78iSbK>4j&cX}2SfffmBJxLcVcW#AR8RXN@P*83= z>v?Fyz6SBqJG{Ul5hX5JP76nhG zgZ#^Wtr<)XtE;`!DT(+koe}4b@UH%*W?D64`!}@Cf9hP^C z4=Kv+*D!h4VBh+I+1tNokSiEgs*OD+`A_{Yk3OWMf9p6znHp4Pg%`8%js(6qh8O5j zydUpG7&wgN(8&FwLj3yhxCl)=T{Cx!gRd9=(ESSTem%E4xILZQvw589+&zcGSv>t) zdERB*9S=b)gsuArz~|$*hV$^%9Oq>mF6aJ!?q9>x!6!RV-1cd1e}?1pJkReX?!JlR zcYymJ<^G8gtS;0#3$6FA?eKHIe|7l(YW)B1^#7~z|MUCr_?dhBF@H;szke&*|FU1t z!WYcHXW@WF0Tv;PaO+Tz&=je(^Yi&%D6kvbC)j z5ZaeiQ@9?&H$M0NbCw>GUv`N>JBM%l!tf3bH$wP>&wlo7Kl1sr^0UA0IsGNiP}42I zklgbAo$p)7UGLxh{^-lYzjy58*7JmnTEb%faEb9zs7n~_>0QGA-#ItE)(8O-MSs&Q4jN|y?67xky|!FfOO`(oTajN2o*{oHwG zSJ~oxZdaGS!?-<84S$Z=dvSXUxA*4ub=;oF?Iqlv#O-!&@5k*1Ztt(Acb3@)aQk|0 zAH?k|xP36UTe#iA?eZCBSNmoAX=cAttv7D3Qt{z-RqiR3+wWD==k^QSp2+QLWgECX z@ri#e#PtKN1J)7NHeI(ORC@W2_si@sMh9*VT^u?&v~xI~Lo0`=91i2q!l9W%!r>2k z24xOE>%>;UNxNINZl!Glx4kY~b)M4mWeSfx~qiuHkT1m-K5mT*RTkVF`!% z9A3)3bYQMzS=PJY>_IVq8$N^w~#mA5EwJCgk_`~SN6YTf%K2$$+ca6I{s7R zTf_Nyz~L|sEgb%@+p~lL^-K7w!ZoBF;H@yBtpRgBz?XY7_YD9K!B-TeA+5df?3s{P zz}*b+YxsUJXgbMDhRRbSybC75A0Rx!SK<2*%m_EZw-3w+55xBsn9l*62b1D>h+75l zHkc4gVl{Y=oA~=P9BKfb;O?KHoX-Gejt6-602ZbU;KSU!2H;^HCKo2mO@o;kWdaTl zW?_y2RNxzL($Got1(+y{0EhJeZx{mo7~H)8lag870RVpw-y#U}B*5#3!Wax@!&P9u ziiNQPyoZ|wfGfHAd4NaZTLs~d0gStvkjKCr4{$p-?*KUM8sM+NyaM2iaSy8v7^9Og}EiyDA4V2~UO<~)G)@HxS}8sO0pES+NjuNevRB)DG(@Q?82 zgZUMJ55k}!fO!qTWfK4&OmhNz`wr`82f(%)VGaQIlK}6T2yGXsA#VZva3aG8;RS9+ zILXfPbpqUAXL%tUG9ylpDb2Dsl2@SCYD{dR!wWdV->?uP)bo(9vXQA45SW=1mzAH4;} z7jS><7OK~PI57;s%{i>z5RRU~$|%evWbaH?#(e-CvrwlF^izPfvsm~Q0LSG){{{E) z02}gHxe$Jq$NLMwB$!B=AG!wZnn>c_Jywu`!&Fq;9G_1 z1Kcs2rPB=Xks?;NI{;ok2gV<8&jwfv--lpc4RG5WhR+UwVI?fC0icDO5k6kR@_iEE z-cr`S`v5*M7s?J{o&@+%8T2Edfi(bcDu*@#vkTxF`0VHoaB>CkmSD~YSOZ@kn0Eji z<7Kol7T`iJYwJY-w{!Eldw~8cp)3#{;f_icejmW)0&D9UfU`tq&I9-zd|n9u1Hi@e z8GTj*JOkevFrNcBa|zH5nDYSEErmJ(^D2OAtDzlZAYXvDErT`!a}mI(8Yl~xqXA~t z0sb-gf*2v6!dDIE&j3za1#}7KY=D1zfF_=I-qP7d{N- z1^gEQyk!kD=K|cx%_YE$TzrJJ1u`_hdJOs(#I*vH9%Jpe3Sjl`VU7Yb!j|8&xZ9Mi}!P z@Q{F~1>nKw811zHT=YDwy&w!i@&cbP0KN#{W8mHb@Z?KS57;jNPFxRT4TP}+-1$eq z6U+l%CS>?4Ed5k~(km>TRRDLrf?9husK12h{>1235AcOQF?v`J@Pj|Ym<3@zM7ROw zXfPxE_5T4{1alFkB~5C-Adw-~*h z1NhC`Z0<|m3OwXihG!MPvpWHQFrNc>_bwn-Si{%_w)il$#Mg%*`nO-N?-dQ9c`SL#S|fgeXgk?g&S4Gr|mR zMu_sQ7#`sQZbli`N4Xi{1|A;a1^BYf|4W$v|NQ>TzyA+VO9KQH000080GS25P!Re2 zDbI`m0000101^NI0CQz@b#QcVZ)|ffXLV^VWq4)my?=aE#kn|qHhZ!;Nj5nPY#=~@ z07229qDwUECa^Kt5S8G@m0cnv!HP6)X-mU7fL8*+vukrQY^AN<>TSK1i+(S?xA)ez z^21hem(YX=$}fL_P#bI1iHjObOct`_yw5XdHwoDL-oAf*|9Rn)bI!~>GxN;M^E~rB zGtbOcKe&T4avaCQpQdr#eop`A8r`wdIpocTcGqwDk6HGTiv zO%HuH|KW$e_r32+`QLgZze)aH{-fW^uei^X|K0Dee&pt?tc-$089koxnHO&RZ<74` zVgEa17yJGV8G`q;=3??9ybrFrkp$S=L4L>HH<6R3D_x+DP+=%)ACtTewj$2|d za)#fMnq*uzXEbCQ(mC!82rSj(CR_&(3ro~{0l!l?E;W%S`R1Gkz0>sM76yp0Bkz$H z`?uf{$Ibl*`t*PM*V=#0*mUct{7?UGmLAz8!Ta;B1VY$W{%V+fj$3te)9Qz$hd8b= zUoVrJ1%Gc{4F~l)Z`Q%M!-ZI$K`*oK8*t%&yhZ>2zyF*6YDh(a5ON#Z1ZSX2zT{cv zEj;8SG*oeu(Qk0mO&J`g92RVv?VMUsVCmpyh1MB@pKtL+O`)G-ezK$>w~fy%St%PA zNApW&$y0*b7K_in(o46oyk_H|P3thNtc<4EH1YsKPiQrjS33T@xg9{W8K^f23fNd0 zI!v=VDh*tH-HO`wZ5PZytvg%BmvOekYM?-Xke9qtkPB}gd5yi>(#Y{ZSeg)8UBH!< z+#>TGW!lO%Lm(`F6$%uXfk@q@x1 z@8{jL4ay{I3+A%H&Qt3+wOBlu<|c#c%7Q%lFRZ`J!LT%5Jb0gBaSd%{F?=vAf6*o` zZe3E47wD3{Egn31KmBepNlH^T7g#uHNgEW2WKteI4P-KTpxq#kw}tIURgl7oPlu7h zP7VdnNfr+hMVX)z#YNjW7??ax`gt4F(3)Kt{Rw^moRz^%1~`bAn}7uxvv!y`&BYNH zSE(*|0&u!RJUHoode)r82^z52u-HvI%_9wHSp-CIyQXPCg4PD0Js|sbc#}iyYoz}+ z7x0`sekYe-#z8^pe$K7saNSOBKMLV?=-=hGu)o3$Z82ke;Li$wxiIE=?oNnArlD)n zSkquE=TC5Q5S>>6(OQlL3WEAq0&(z2tGW04IriUxPq!aH%m4!T<~8pA(8!qYMwm>P-{e&;Te9*oG zaab8~gzn}N^g)0C3J<-CZFHOstxMT*Q|LuDg#)&^gl`RPGU)Q4&EgE40($B!a~usx zCd1|rur$BHOK&nE$I`|lP~$TCcqZiSyoQ4gvhqJ5u`PF^Tp`xq-XG#`X*>)$-1P2D zCT$7`|6Axf$QCt@;#YX6(s41gInA)SqoJPsscuDbz_wk;O&KdctPmoBf_!*2a>!v& zPmQ0$VbXG}&@0HCV{rn8wxZN<9NJ)o`dW%_mdwb^$iI%r#xFaVEU;E3`lGGNfEi;X zXYOC2$Ft_aQ?-zs`S`Bly{cOP@LU*7`fslw^TMDh!MU);W5blQpXQAw+twX?7^PzzSHD2iGx%B$W5D^2cR1mm9P0sW-cEcF= zqVnkhQZp|jzb=>uEe!F6D2bdXoIW=)S*J=MiYhN@nreC-$pw&9I(Wxlw#;Dk0HmK! z_&>PmYzDFzxEqs)Hh;qEr{=LaS<;tVrr@;1GJO#no9W8tPn6dR762YxU8f0qZ-wLn z5)_D3V1{|%l@}S$c^i)*D?V#TjM{n~tA_oUam>K2Pa7FHluGUQ_)OT*A?MR?L3}4S5peS2Kl<5pHf1PBwB9!%5=60VX0X!RYMtPrzl8SGs&agw z-0YM$dT7lw2rDs7nySQxrHSN3!GqI@_b@}bFSe&&T6%eZLjtIq45tgptGPw%A-f7UyYeNfmwBrW|w>9*&ezcW)l(%xh!t4 zCYwFrwLUN3}g_a&$DOk&a!Mf<$&OAHZvOy;g|QU7qd-hAqN0`qEViss1U;>)UOoUd3{w zsXH-RHK!<%eB}_o?Gj3x&7b*)>jA<75I%A!5=$j~5Zg{JE1%AYd}<SY8tB`ei#8N}Y&jA`*YDOESHkzSyqYbTQElOWr5cl%3qC<-W17n@js#93?1$>go6qi+TqD3 z_!T+a7wi%PKSA>Lkh35=tb-kBa>K-Eku#wfF&Knk^!hfF(qTx}DHVcBdy5V!e@xB- zocxgTkx`m33I-5&C{cs_IjYSo>KobzI}u!(m@GsLJPTnxR{l&cMA8!>+rWx?9ba{l z(#d0;zx;zXJiLXNj3<;n&31@P1Tpw4&S2Okoe!Ln<^=|%>4S%W2sz1&Z%&gBtCOO+ z+y0762k?~*UmW}5ZKqhNppZbhW?NWI)9a82pb=tlqpoQ&tl2zu?Q{g4~?R8d+$dy-NM6Oh8ugk-T zeEB|%$d{_@bp`T5d)-`lA@GbX>@1!xnW`!s?HdPL7TzfrIgUzGlxB-jeBx_pgg*t4 z@M|@6*>y}FSE{lQorJj$b-H3Wf%Kw%44G0|Cu4bS%|Wa)~PrANM$1LX!&`C{1Sh@;A7W`SR$CdOm2a82C>>u~3fN<+&SXgY1kW zL;-z5hv*GKDi*S}P!{ZR{>C-Hmry!(>jqYrRS)Irp*%g5uZIfs&|C~relnIM$P@h& z>pl2SoljeHb)%#sdZWEACV%XoRST>ciRO7nP`y;Z5YY>Ra%|y-`W0PCNs&8vc52st zWYyV6YJfmUwH0F^K&pXG5&^&&5-o#griPVnV^U6ZvWc;vuHBJ^;#f|(*xtJvWk*7Q zdC6BDm1Y#?57S3(1DdTANYz?3n^ZNbOL>y*$XYkGjFZNbtnE`k=2xwg(gx{iIvUCar1nsC zA6sN@)SeGkH8TkYufb1^{pw0N1sH?Es|(p`O~>1WPFw@`0!9b!K@Qt(XL=7yi>H zVtQ<1QagxNLt!vF=e??ns;+LFg*}M2tJ~e_>VX2ccDgRyg_-VRW{pLw?je1f(uk|O zH8;xOJaoqboIj!Q$+Y->mS?uPHTbsN38avzxZ=FMIo@fv+pk+u$n>U-9T%y|$>>W`RtPH+1pQGWNHj0Kcq1xYURvt_1%~$AiO-GW@Y%(_Ut!N*6yvk#4t!2WLilVp zG{B1UvDC*{%QNVW9&n^2>K2n$`zB7DHKFul`Q7A76c*S)q3c^V?3z-X>R&wjG^10 z8v}KRC6lB0rVe)OhoNx18^M1wVi$m4e8wku_MyK zOFbf5^54OpLjK%Le+5W^w(jVYd6XUWITm(8comearSi}bgOz4nM3t9%e4&zH6>{Vv z?vJ=-Am@8%)&w*#)1aRxgetB66qtck({i;k7iP(57Fncj5!8iheXd&1gZYv&4sFy1 z=Za_wm_|vd)GTn)^?;!ns={)m$zD1k2PE(sv-Slbv?iBRuH%$70#^%p2FlD%$)r36 znF_SK`AwN*Tx*JE5ch_oX7OOS#!Y)~!Ulp}CL7aD?V4#+dQJe9qs=8~)n>W}1=m6i zN&@+^_0uFW1B=a04}g-h(rwCCfs^OKjAAfF3)_rZwLp&3X2@3#8RZG|9q3M__(oYI z$6sDVS7U+Dl&$a7uSgWO?ZT#!b*n$At~kt;W?fGENHeO*q0o!KE$W_E@Oj`oK7;$& zvyVNGu_tBE6YLpg&m-`pg9Dld_EQn97L%s8E$qgB^mMkqDt_Q)0OX_$68tr4QmfWo z!Igp|85}oIX?Du>Ug`v1sQm-l@ncp6a6y3dMTS$^s=yv*?5B`7*pk4H$1VxrdcdXB zF-rm|wbLuU~4P&a$N2G7=KzJzDslo*%+_>?OL5P(yk zKMXH%dnUxS9h#S4vV7w>@!%oxV9RotLX~dOHUMVHfGsQ@3`90Tls_#J<7?I6(~!*( z5r6n!=^&5_f|)je4q?wh_wHbw%(`w5>(V`}GxxAg-h-Xly8*I6Jqpd2?op^wx?Q1y zG^eUc%7Ks=^x@Kc2;qg^dq=+c-bEwdhF%-4>9Ow?v?~fml2Uqe;k)JXjq*G&pY(Ai zTjP#l^#EcchAs&sB@RB1QN5qyB0d}b?}RhNgKvZ?gcCYB^d5sGbq}_zHzMf8UUzM= zlok7LtXS3uz5mP#q}LS4N_m`>a<{as<#MA`(QAEe77f_oHIqO?-bJ6a{?CV&DM2H;I8g_+Bms{woc;2dN3zAfle$)e4w;1>>4|egeoVoL95Dsb(BMEzUGV#M~=dC=p6?*-BzzN#= zSYbpATn}YqoBtIPzgdMeU);Ai?ry|(hJx5+cPNNr!A%62~49x4*{Xzb*b~0jgTDN2MPqvF}N9 zmDu;i;0us8z^ZT2(H3w~=b^-C;Iid1a>oeH^v+^bF2uksmo-h#mM@vtkRTG?8r2jP z^iS0^+A+QVhflJaQ?DWeZA%t07(pHr1HZz(#WdpMl}@4e9h}C;wOszT{D@9Ytb1$i z?0btz7YEyz@Yn?@TNV*Um)kn(45$&#$^>p^WDDXJB{+Q6V1>I#_YBM z91}qewqnxaxEkC(%9I+D$-qY%t3vMth<$;9U=EL4D_WihdRQ4Q+G;1r0c@9YIB(mh z$YD~x&NOmvqC}5Yv>L(3>)^GuEe8$z*j+`=TnqX5~)0Qj1Y;M>TV zt-*H~J>xutI}E+33&NmTkfHCzk~{f9R37p5#qlVQ%<~*5GK=FFX?zYe zsZ*msQyuSaowS*EbgUmYct$zJ4Zc6xxCAro0E&2@#N-s)Ifaci*K8g`4pS5+fd`o! zx|%ddXJ)%>n#qt3$rttML}NlF7~X2aWa%ct8vfkhp|1V&wfT zCL`<3*6gLx10mPN!j8%WVkq}mW_1r^)Q522nY`6vpD%ee#=C?)I}G!k(S>)ffq0YC z>3B=-FJwe`G8Uc71lEpg1XeWd?v`RsN=4YOby&S3;tANCqyvv%S0-Rz06IvJSdNg7k`LX3Mo{(QRbYi5;c zOa&naMiWCJER=5eI+V!CTM%`g9@l5yu{*a37c@+jIC@|Mi&qg zdYbhO5_Q{&-VdR@e@Bzm1tO`AH`LqSTtVNDYFbzOj){d%Zqf}-ZZZ751b<(_UmX7K zy3xt4gEapGjmyz0eFS8u4Xv+`>lX>DG+{*fo&J1Kj2|E1>!@asR^6SORBp=W~OYb1|<~{ z$`9>e7~MDqBW0DqwX7;=Nus2zD&~?njWfRMIMj4X17oxl^KX7WY9j1Qd8C^QYFoZb zTs=epJwfs+mxiU9HY0Gry}JcDvqsBt>PuK9MD8XXxKH%SjL0V@;{ttK3^H=62?n#0 zZ+rpFl2E1DO#?UT$cq8=U(+fDsJdKn_3-xQ?#(~7og){qgd$de3C)X4G%rjoOZk>) zQ%5DgEqG2&^$#qMW{~zOwn7~K8pf;yy&+->&~JHAlNR|#a9f}*oP!;!#8PA|#TiXk zVn&&VPhk|RFK$S5=^cPkGy~x}O~cH(8#0R9(SXs|fNMF$P%hZVurlzk#Ri7)D#%;{@ zXDx?5=ifX(9y>p^0+~L$)^TKNcy>ey3w7=Eg~@E`$h6;SE#ulDuAPRGQ5AZWIkBoh z|B7od)k2Lb&?j)2iS*Ie(CVBI<9zJcu|}@g$*tCk5`H!ob!~wq1b>Cy9Jz#701_zP_+t zuoYpsK4R){X&~16na2FM1-UAVEai>IZRTS7t4{#$rDjqo=;7xu>=Fi?{2DPh5k*wB zCA5sHo;X=y#$AKz3(C;2)DXIx3-K$+k|(X9iYG0qs}DHd6$^GrR`MPV+{$rKsUaBN z?A*GTxMJiC)GEK#(hS180J(cC3fCo2@G=zcq!Sqm{dx=A0dZ_`v0~~!N#Lb-*l?}U)q^g3UN>Ei!I5?LOt#M6!^w95PSFg=nQFw< zbT4#ak#qx!@m0FSnMm`nsy;1eCCV9kYzXbDTKY4HZTDLmpG9n3aa@{L>w5eK`p;O9 zS{L^l8`S1*M=AP}H2cV4q{=)HQKVb!%LI9xo8E(%VW&@rPLEEuHw&_LAd-UPaZ4ge zHm1AIL#-5Ty2@z42K3gQ7>Jj_zGaoPCkJ3WBPhWDgCH4+>pb0fSs#i2;@H-lfzH5k zaeD>W;q~RXFkbTY5-aYDOb_v2SHYKB%=8UyzS5aXn`b5z4s)e4T(J2RXcG;vjDwK`#b$!Cg*Ql9KJB!Ro&aJ{t^?xg5Vj3B=78>YoR{Rxrcy1r@mV#CTU2$}Ej7{4%&2fCg&HnD?wo`*&Ib7zcVW&KU4h<&p z@!>zJ45F50wS{}%L5u!3)n@XQDhrN5*=QT6WO70o?%w!lQgGd?bco6)eX5N6(T>!0 z5V`RV5J^iAF`z&cn^m{#(k$7+25eznkK-@WI7s$+sOcP2?HqrRAM*Nzq!3$;O3@jJ zTw*V6ff&i=r9YX$bRjX=#P)?OXj!{$#>GU+g+ojwa~ zY-f4|4;YeWoI)eLX=}tU!%-pOc)DYaxD{fyF1Fw!A0PAa;lzg%-oK*h0RbAHactaXr_(qMJu15tMrg4`* zmh}fuNiL(yQg{dy4O^Hr$4GVm#s9#q{+kE?qI5#ReHaZG_hED&j4N4YF&-&AalfCd zp<7s4I1~wVfCloB238F~0!%Gy#JQ19R}ZtdX5(fYN4Qd$aKlnY=`?&9ZQ=HW@~=G7 z!;S2~_0VrY5lKgkTwB-!io5FS2RuE$SWb=<;kg|5^S^ko@T4@O=6PFK{5MRkqw2B? zYIPrTH;1TYkSDfc&=rRuFJ;q}8e3dTg(^{wuIOr~&q35K^m7ADbk_?u3)s&292ccj zd!2b>K6Qbi?4MZ6JV1ax1$vBG-&WGWoI_#2f!f=p$!*-7?a~B)N`t-GEIx@l>#e5B z4%3~Lq}oa%j-!&Zc(POiwhHvtGBXHil~iIDVdOyMuni`dv9}skzXQ8>x?Rtg1`Ca?r9RiE;FouKOFi~`-a`25N+fGc}^~%gLt}}HvJk!xmOa1js zOih@aDl_1A2H5BM5xZ?yY$p0B)87F5*P<&2nsAM8Gv^jG;FMAX;GjzklpsuF`n48Z zSNlybLi?pz3gx9q3eA$tRg9tb^LVIb|9JM~1$>U}fQX$0I~$9%YOF~lac)<7yUzSGg! z)ZZ5T0zf;07?B?cOE-s}|MD`@-w|=I(Q#zs#KMTv9eO$o)BXAP)8coS5GrpomIuP} z8R*Lm=1?#WS)evI)Qo^`=D6_~Xi>Iv9*Bonkk`JEWFKVm&LmP7ebQMo*MV>U+QL&RtK zt(K^9piQxpdF3r$CrwkfuH~djWMd=f zqk=!5e(!x$IXdV^eW(s((Tjtq;(;g!5LNDR6fxJn+rgNa0!GL>UGW!nok&Xa(jQ(# zts8;V#f^kPLpA_iJGu}^@tA1zM?~&{3ic0-=o=t#JTN>caisUabeMLm0H|+xSf1XQ zil5kTTFxdYsJJdJxe}r!TA~bJk;jh(kpLumP8p7)t6v{+@}r5-!3~090*)b~Y z^1ta$;A6fAFs%-#&4OcC&W721AKEYB-skaD2c9CZ?|*hO`d9rJYX++%JiinVd^UZ$ zO`}(ElVY6#UEX@x_iEhc+SdsTyqWbJ*t&Qg#6^Js8DC(O4bPb%uZ7C<&>A}h6`r~a z*PL zce>_-aS;0LZhdT`H?~!xuk>7T??UwTfG+E9Yk3+Hg$l(?XaSX#EuaRT zgmKec-Jl68&D}f{(9}yh0kzI@w3ImdZO|_LCbirgDz}8xUqCqzt|7OUtx@NfIi2^& z7s*BX9`5(<15#*NVw}c19gz(KQ1%wwFj#;aALY|u9mWOT#4*(cShU9Ah!Ke3-2uj;vo#d51B9wQ&_PLC5EiTHUSDr_zuSz-po> zlu1J)j5n2W0S*+)a$XGha2W6;6n)}L%~QPqJS*zw11-kCY3$y4l;jtET|97SME+SZcFn4OvodS)-a=Cm`Axr7Wcs z37|QvZAorkYisKyOz71UkQHw+i)o)|jAKX8p1?SH1o8jCj!>szoJV^v z$<4UU7M%~se*QOP<>(x=2=liM>A5^q!d%pF0o7()wvF<*91c`Qw?JIGQu=Zs^UC#K zpVvHZhE~%b$D=qd+ffm%d+GH4O@HBu~DKPUh`Wy**cckUY6x4^4s)SSv$c z0D5~d7yWq|bFh8#m8$^W9|b640NP$Gj~*J0-}eQx&YleG87m;8lRSACLN_6ay6Hay z0D1Bld^6R&u+vQy7Ih*Kl38JxpZdRGx=rZd+ejg4rLB3;h)MQm5i1$&>8YUJXm`+Z zR%d97yVE70W5Twru^m7a(m0X^C}aW(Fc#Ah$leeK9c(c_8l8sGpt)<+g52q)F(CKa zh7rFh=*S`@IUjJdPkWdA5Sxqoni~WA#|B;*8wigELJcEmJ+7mbPK=2(+_QNjzMXzPc5bq zq)M3arh2K1Ik$1OIORP%MW6C&k@rbwJs2`L*S4UTY3K#Un8(iK>2q!6I?&U$z+9V0 zb1-_{+Qfu=<&-|*Hud6!Yo<^1B{)7*xt5fompy%yty=e7#cvS+ZDw*w?nx{vX+;5m zCPghMQ{II(%-q>BRd+v|Pp-S^OSoDQb_$8nA7j=NtcRC2 z;>@)QYUwrMQh%%SJob&w1&ekbP>koTsrnm-3owil%#MJQx+=GL!as)rye@1hbr{YQ9V?phYskWm8Ce881ZY2fbQzPkerjZG=j94 z;v1s}Yx<<;qg&~iKKJRP^zRq+IOf=}Wi8~L?V}ejqpLGxbji9+V?xEOEaGG+M2n3n zWIBhwLf2!t)b+8ZAqTMG+Yn`=2H$4tk0wX(n*{psTWmEE1#Ug=LKPu3Hikc9GPm&+ zeD5;PK~8Pl%>ouZ@B#~1SwJa82*`^JwF?3!(PcK_vdZYMd)ea8BaN*!NZPD`(ji8wyOLs|DoNd^KOUj(1y@sd#!!;F zry_NKI&>{{_Yl!7xth}F-hh(pgiyJG>0ld0;-dQLC2=3WJSwYo zLZn#`&?o?b$M)OZ^xr2Wmbk~axdeYot1H%8cd5g58PBZRx?1aE9j;4U8In^mkLVvu$rw_Vqr@6m&%b8_y!2IF8(X#4nL2sZBIDQOJ=&NJ?S`~g{ww_ zML&!HTNtV`sM%y`Zei?h$B?>|-!jdIr`~9Ze)a^+yJ)p? zBp+(Ut(M0~wHX~UrlLc}L=sWDXONST%ew3JGgqC)=JO@1KgHvzp=}^`XCDH>LXw#S zwYF6YtwMAnNK{|QC9vw=yfImwy*VzWC;BNWB*(O2MSZf5Yrx(VaIb^;%{cO|w4yLb z$Mr!)o7D6LJVa$9G}CXS?>pHRm_ZCI&?CB>dXE72Z6A-OLtrWzoI_}Yh=DSkXx4!M z`=b@K4$tfPK*2t`qd0keL6&}|{Ou3edM3Lu<)D2Io&)DPQcJHZLu=ZqOOWdtmqR&? zLn$bRmX4GlCSBuq=w$#$WOJMoa4gwS?4|Fc!~7QxV~5}P>VmmtT;l^!Na2whH}&4Z z*7Bf;akc>+jcUD!Xo_v1(G74OA6<9*HK^X8!w^?oTkxmt&`|(%@3laDqCJ*;1J^hg zO7hX-h5AXs+x-0r50^8J52ONRNRwvxImRgqu3&lE?Q{+xUF+6v_h>oK;^c%&qR`d# zi}b#iav)HXI2JP_(eLuaM(lEW0|;w_Q~i5zw!3cUI}(z4SGfz)*4twYY|xSOxa_ zc~DV1yAeY#eMa|>Vk&l-w;57XZbU)p3MBf9zx?;n+ZglOY zQ!@az)9)WiF7+eqJ^(;pq`@<_RcI%8_jmU@xr6xdk(i@ny-3m$C-pjc$8ghEOvZZm zQ-q@b3zW~Mh4wk~*eG}OGjGsZ=mc$U69s@{$uszg6I2F?$J2GBti%}ER?JRMeQ7(D zI6qaDD?WXQ9IE?$Z=%7 zV7JRWi6nL>GN9{Wx=9?Z#T95}C{;G2Yaig$`x%P>LHYrkuvV$nF_Pf z5pZ9eC>eeN!_!NjN`{}raCYfW zFq{VAHq@v#to94q=~{Km>S!7^vPL^iT(MfUauv)-D;kpX5W3A3LwD~g!G{wc6?4nR z+-gCxu(Q2(H!q3gtM3e$jk2JG&5n+y3($09wNUSftWU+{6l5E%2+N@Ff5ohe{6;qt zL*@G;{t9Pc)>DQuw=R)#NV`9!wlE^ifhnlgzLjdlI6-rrkDjAj`q+VmF%}(`GDF+A+M_M&u8mHHo+Zs^&}&D+ zJ+%k^f&`qq50jlnaQ{TAH8w)5%g!=}dfOm(IdhS}Esz z4v*fJGu0jMA!t0<;7shzv9(B?KkRJ162ZXMB1JDG=D~yC0yC-2RFc0@z)dSK?g~m~ z$?3K(u(zPGm&CncpuLZDYz>u_(bE8$R@r6>gypZ9`I}q_O{Kk`X_}W5;b~c@5U+AU z>VE;oxujGwEcVg>dM)DxVl4Y-etxl!&OD3UQd_H*=Hl&Znsihz!4tj9OFii2cBZ^# zVQH;&tKZ`n@ggq#zpAnF=!?iebMTW>t_Q>J z#gWz8S`a3{_E2M{g>?K-S@RTI9nOalsQkR+Ari**q-Iet95A_b6przq)QxNUd z<~Eb&GPfEkp#rEba89~SX^wO9uUdxkrPP+8borN165nx`#v!dj%fvu0pn+p2@g?c9 zsWN(TY4jtOfQz{77;QS<1B3`#G=uG2xveXjQd!oraHVt!vAu2}VgOALcf8G^N<&NW zESPTkqFJ`E?Hn`%Z|`%(Pxc18r15vN%2QU}1r6$wzrwb_7)r|+jsl=?Z%MkeICxGf z6%U5p06d$%->o+?tIY(>(;KIyjkYwJMfW8@jF13H%gmL%Ui5W1C8c$waM)v*!P1+} z*h;8hfv`$Grx`}}zs&3g8T+&Zbw5Huk7f2iBk-Bm(>iS}bCW@9U?&p2S~M317jHR% zwiV~fMpcfJWpUJ`J)Tf=Kg~dwVHf%@mO`zI*55;_`@z&&e;0{GK1~Vnq9f9DyPFog z%k*EzMd^k_cH^+miv@IDNfuDG3$OH2i|~3cFj>*nanw&?=Q=F8H)0FJcXT}lQE~;=kchne(hb=6@y;6#ZB*dhiScdBh5??nEx@* z%liQe*EUc>#%b-l2mx9_UEHVT{2Hy2_UK9_mLl=cfG4z^-E3jgaZwDQ2U78LDFgjC zhVU^^*x__TUG$^38RG-GX0Mj>BIIC>Nl>5HNB={&dJ_rg7@F)hWH6Wi803U_+DT7iSv(t#G8>Fol;h?T}mH3u?rm? zqN}_(j#|z!tW%ELQX&I{*qmWobc~T-Un%5S4br;kWwOv>!TzZ0A5Fwm2@zR>#l=i+)2*ikb`5%q&b6HY$RK z&NkZC4O8jEC(y%bbocL>l}Ifoa6oQk%gyjfIDO+?-?V3B2)S-^3~ii8KR%8wNF%j>Pp=)| z#lT~lE(2DryVCnzbWt+t*qb^TLo=8;V_+uZ{&BUr#^dw)4WVjljYq9BYwLI|2bmQz zTJ3daF<7skEpQx_4ycCct4XQwPht=cEg-+)F%`#<_+$gTu~{d7$C}l9U(yx*8rP)F z>{1ZxD6=H)F8YtX%y&w-%2R3%9wPm_4pPiqel>9q(J?Pxx0)H2=fWUc;Mc!0On-x$#W+^J9#FvOYR@MNcsTE3J?_qmcdVq zC!4Yz0Jl+S5*+}$A$@5fBussvz-l`OUjlrY2j3q&qrA_NH^^yn7VD`$WZ{%KEqGLb z-G}P+L0yQM6|W>+cE7u(rt#%RN6uv=Zx)5(R;zOu2UHZy2lES{=h-Hcb!KIF80^mn z3Kl4rhe7E5ZNtr>1sg&ue{Ug~YL!`eoaf|Y%!`4P3pC|cj$^m1V!#T4=*z30Vr-@y z&TT-4T;#_x9=8FR3!r3U_efR=wj*@>9u0c9F;`m$^kC7}S?NOEeX)+gKr_^o{m8lP z%h)ZJH)ub|(|(Yv{a`N5NdSUIxXkPGkk4>lx1GWTJMH8O=Dq(J`HDpR2HG$m1rVfm zLAs`W!Zuxfc#BM<&+p`F=+A06j@kLk$l3zo{ueAERL|wWE z*Z3Vp%+Ga}pQo$ePV7B+=|h=UySXOURBm_^HxhZ;aC&rq4hm6*yTu>k>Vd~cN>?)v zGZgjck~|alwx-kXN0Td82lgWU?L^@Zv!a|G9FTaB1?bi1j^^Q!uS`%W6TZL`K|eKA z>VCPSX9C_se+l_!zq#I?%DicFkg)ISPiX6aQ19c2^=C)%L=XLly&6dSim25~ry>|V zest91xt$JqKgl%9?2tWyz<-eX81GTwS<_D~~k8};tP!(qDHuo(QQK|ht) z!@8jjmri*)>9oFU=ApMUw|Q4L`uF}TssMVA-;J7aZdy_^PDLN;A}{?kUGI6A^{yx7 z@hUKYQ%DD1`_)751Uc`apWuF;s~d8gQy6jLjYm~5vzcrIm8xtW@nXhR!BO{Pz0CY; z%lu?Ehh8S#^mYBbTXMv2X3A+dC*L||2(VDk=+TU~*;&5mc<3DHG-!0yNk$gUJz$pv zUq|&@_jaD=r7!-CjgA;Rg*W23-vGO|xm#X4dZ1&d3p>mdZNR)Zlh8sPNNUsvD*6M4 z$u|)I3*MU`gauye&?}N=z-VlE(@P66O#jj~I^Oi*H*jU}7)15r(Fn*tksjuT>5QIAEZd<5>o~e$uD{!MYB@TcTh`}M6~Gc#w_(wATvu}DFB5-LZ2#n>|6_v?{ry> zN224%GNI6I-gX&(0iY>e30pzejgHu)Fgu_pb(sa{Y9ARcd<-Ze9{Exv#~%H{m^lgS&WqoE}!{NU-CEB99nr^~Yeftiz|d7*o{M^b*VAN^V& z(S(V$JgGAik3d%Nq&jY_?pGh=(WHXs{etQd04>}p8B=RrO!>&5*7b|Qr_lFBjzLUh zi1#l7n!LB(@xg`^@`15Brssm}j&~vEUB~-UJ>D<(1K#liL3SKuI1lBopG1zH{$lXm znG)c;#K_At5vg0FQ$qK4v-nqZY%z)9`vabpB9OazyrPhmNbVNYr2=$v)QARVb3d3^ zj`tIrMb&*F^GQ+*&;ss10rXOM3h;C+735WI&?&9e;&7xDKClz#v^0yHoK4i2l_E)6mMsHw17UhZg#rxkbkNG;s!6Sw9|yHc6U5*}oG&*s z?OR`9B3Ya9;BL`txJ`@4fg&G@#wzn4QFrjvfQ7=+S(ZfE>284qiPNGdDlfJk=91+? z>~K}N{#j*dd90k1)0I{HFpE((37Y%}@-0k{@3JVEC9gi>l^}CW12QK$NbiM5LQBS7 zs0meBYuxnnLZ)2eDSQU%NJZEUyz*Va%D7{f#LhAcyD(lYMHJck_OEjs7_u93-`$Vex3|5qbu^MXnf4vh$EUn z27Nbhu?G(ignq`Y10k?1?zp_MoV-zZJko0pEw+>?RWVIzy@2PRLObH{QZ4ZQ5~Qay z-iJXq-`PUp0|Tj8&)xD-u&qHyPDRg?(0yjLidV~o&^_=WsAase`d=%UyUJ_-iuBS} zS>ASJI1&is34x{MvN3%V&qxed^0UEHGu;AdAA3%~tV=UAJuE)l;drmG1|-^~$Y&yX z;~I(9PwtDuGuD>b>#MN?RO8Dl*J3h1mlllwsDS`Tvh&eUt-VMS+~B0-O6P0((W;dkBxNe(lOoYvZzM2A~(*C z5RMYKbte-5)dGklV=77*B{E6*un#6^pia--K!aXibEfi^cKQpYI;KUlfb5hvG~2-G z&v2T~Vsh^+=mj30IA$-4%^uEtPtH)|Y-c@0Ht(pIU5)r0mv3N>PkP5yRSRR$=Qn`d>{=Y`0=Wqw4_x9&Mj_}uUnR%^*nJC9gkw+)Fgx%b-f@p0 zuLNFV)YyC-IgX4H4{a_6np5j8%wE}Ap~By=DBDQ&1(^6}W=7`$_vm2T*_5b5&zw9g zLJm0-H%zK8%)FORC<-yCM(eA^9g13}PU})P^Kw-Xo|0P=f$!jgY{rUZ>2= z;RsMA5@+-5mgY=O&SazqT=QkRV+@hT(>J$Ppwa*!S)&A+{y6Gfq1Rdy1j>}6(_f_D z0fH>pC1t7^>XLED^dJl6KI2K`YlylH*t(x&haNMi3xi$q6vs52XQ8`6*JApBoTkjd zDE%Jz&|Ul}kux7_n0u9@8rUg$wC13uu``;9yEe`qV0v?Ad-Se>O0y!};iX3o;Wot? zdU!6ngxvQU9#oEApST03ITcC*Vy?`CX*UDZ^$6MyTk_N`W;S`S!-6N!ptBuBm;4^w zL&kf;VW6K0!-PDIzI7nEcc&i~_39|#c7hqNS(MCJ7?`}bLkaC(n)!lm&w1Id_gLGQ z9XNT1UDa9p!iZVCzh??GtoX*UN0o@n?6nQ3!37`V?HuEV6F;-D^o4dk>nJvE3|?&PXgZl(@*nr2oEwv9oP?LCU!kL+YNnP<-q2 z*Tb`ACn`oo~++B z4WI9PrdxG^=YbiCX`mvFZxI7K@L&VMrFZ9ATbI4c8VcqC2IA8ZH!*1o($rA?$9Pt) zJ8>vw6~F@=iFKAuX-&*}O-mc?M!CRK1_lgH2Zu;H@ z-EzE>gs{%SqsD3r$ZE$C@yVA^)k+Bkogd>JXS8Il{_7{P#EpC98bc&H)o<|VKw#RB zfeG>Y7O_7yRNY_WH-th6Q{&e5V6zgr^;JaO0bwO%@N*&7TDKQ*BtdKx;h_6;$06*v z8}JT2mYIZ*kc<)go)XqwNL=Ff9K37p0JfhK19+Nrq)fnJOragF{;aDCK7n`S9Y9Ef zxcxW;v>=wRv2xiuZ;3(TOH$;S;y#K<&LKFkTg`!yCv=ga{! zc#VT~k{E2ndRU<;2|T46{8`K0Dodxag0a93hDR~OV?Mj#!(wOkiBDVtgSz*6^nK56 zo1nwAJ|He2*=mJY+?#Dg`a%)_QU>~b9f?)vLN*XUaY5XPNl;fcP*=VYf1*UEBoe}C zQEgdoC(o2HjPThuzO3bPhHTOC>)^7S`p~vo5+Bqa8x{cjLs#aqj49*7aHR7r&D3orzBo$ zREyKOjnT|7wr|fr-o9@czS+J94N1}-)4oO6KK#u^)}YM@^38@IpH^Mcw0dkyiQX1y zgkcYU7~f(|$=2Io>@YBX(Vx%)V~5^?-5~awUPsr##%1`EbD_Q{@M|c9sn2KegV@ zI8?UM-|bCqchNuW#hEC&D8ao4aq%{KYl4WFymv~X&Py%DQ<&{sK$}?pJk0-3@Tugp zU3xQNh!ip+YFNSUh^nV&o@XcMERB6QT?h8EEo9tvn@ShzdFkvCbdts^Oyr#-8*npe z4kB4hhxR1l68Ass(VcO+*smak^4Jy}>C^8%BbnmCCAad*hX(0&H?Bm+>E2iL#+=X_Q*w1WVDdEwD-}DpCeNJ zp-RnOD@b`&c9*a*L)>c_sK}Vc%YFEBOVIAZua=UIv73M+y64DcOv|*f*YShhg+2+O zw&9Q0;C7}3e~tqt{N7JNt|aegm`-2%{Z+e{H~&6)J3|=d5ai`sr$@WkmgtZ?y>&X3 zuFi1fce*BpKhDPXJ1@|S|B~466yzM>H=l-X@VhefABMr7%~G1J8d~8Uve+iJ3eLrM z9+hU?BVUY883_vaNU2)2RsI4|Ft+A89jC=0ZUGk0z}wNS2DvD-iMf0aH%$+@F1U#+ zF7D;r^u)o0>#m?x$L(@_{a^71aN@hcIB)0ls^tgqr>A0u4R?k%n}*e9E0i%)FT={p z*gmEVt6jE287?z9URZ6#^Xh!-j40o_(xesF#qcmdKW?7--OJf;-arR=es|T5?D^j& zc4S9^Nk?=wIa2tRaw%nVb!bxph3R8aNdG1Z&zE_lUfcu!%04ZC7ErOrgTDEV zt3PwGhK~CcT#JmkPIbU}_5d%*_#Flb>KVuNeZ@ME?u}CPzpD5lqf&K_sn;dquOL?8# zv16b)jB`_S4<09Km(n{q>?0*CsIGpLAN}^aelf5R4@+orzrJ;izjl$YpS1Z1ro(KTIGUn4VT1RpWXL&sM zYgW9+6E*3GAfN{u$L4+274zyxv>`A3jqX-d+gry zxwn)mvF?q<(8y%3ygCzlCGHrK{@j_ydZm-~3ZA&RrdMM4o52A13N+T^qw{~F-+wE| zd~9_4udb1|4MgWa=Y(9)id?r3J4e1iLo@J{lHO!pg((NvWxVdya$-p~FG9fR zf@>VWT6G7o)+GPpbqdJ8om_%{@n_r_|KU#V-+?o*n(zP(5}1dL zPfRCw5AC|FQ+ZUj4IpzcU7@(l79RJN=Xe^XXsMyMVsO z-gD`3_MS&O*?T^HoxK;(ee9h_f5YCz^xxULg#Pls5ksf8!AYNHQ5AGMdsoo_doQ7z z+1pJe_I`k_W$)#5HG8k5E7^M$eSp1J(L9HL_2Ij1{^2>0JpHy^kAZ0k2M$M-tO_P{kZIh_s5)cdi>L;3nM4Mp3O%5HJ zU?qSF;k>o>J~PaqSnq4@?S1!kaJkRf-?cwy@3r<`do7{&H~5Hh=E7geBTmY~XXNow zeEg6+qNM}j1bIZ^E}?-uK8uh0$RpbS7G5TgdkJOz8!UU~ssM$C>>NH=A4D`Wz&ud- z8*+bEsSjEt`K%{C8&vu^=84kPdGr~S$yPp9tq)ozrMa8tqSXg2mwcvCpKyK9O37yw z^@-32t&x0W)F)COlrQ;w{R;8X>4OR-pFb0y4N>|z#S%8hU-82Rs0|_zivq5ErCR^p z#tA~=uL#-bilOv=(_XKX+&rF;r^?z0&&T}fxbduV{t^ylPrs@gQ5!lx6^KE_67Dik zpW508p?fb9S7`0;lIM+pTR+$elK3_J@JMGNQzs8a4TOhenwOPPo=Ygob5sO>XM?OR zm;^P+G|wxeD!$?yV7^@Czn=@UVgTuUlT;dhs@_T!?hUBarC)k0^}d&KKE`Ki^=HZB z8AA3V%^M0t?tG}%B&e5XobOe&#E<5c*G52p(7z6k~SCJA5ta-bcy zd#_&6Mn67)-;rMi;Fs>hFUH&Gl=4Ws6W%{ ztd}+R93m2D5p{CtE6C50Jjs| zPH?-x?E<$K++J||!0mG@k-uRSor+$mFkZw;_W`JO8JNgjD2EK~c(ic`V(9-&YcKiW zcj@0E&>Y^lZuZVTJld8zA!?u#!oI)!Vjq<2cm&Js`3PD%<`Gg~Z=YPDeG-j*QoW1x z2}a)WC_EnkXa%TCRZKloyFlUminQL>r1k#YFKfh2iZjqxUqMXL3$=bRclgDFNCSQL zmBRToqO94Dw+I6Bo(;}CfE0j50LuVY0^|d1e1!B(B(!xTxDnt+fEx~OIJjDHwcx73 zRfDSnR|T#TTxDS2&^Fou|L+Fa3-E_W{Q4$U0a*L>1$htb2Y@1*4h47Kkou`1DYvx7@LC<@)YWQaUL(jcH=(tUN z>EuShXyziJ*dXF4N}Hm>S+mgd9Ma&Yh$#TcHa6Wza;L;79lGyP1$bs33eVWW3uAEe z$^$8!Cq=Z>$hAtlSdqe0&(R&as^@$-H1Qv_pT2sF&i)+PqFer4;1*r$9=hvutNBt{8`e|Lp3$Dyo&v@bJ9^ZD}nLTtn z?*h@_<=ycjT2_r0_{>&e)^pOP*Kf4GO)qL|k4W1H2cO3!-=uOS;Z8!BbD>(*oD_jU zo{{jPbSH&F5P0E?%_pgx7A517`Rzt!Wef6y^p2Y|aR)g_ZPC>HltF=_F1#uBlqBt_ zslIJM#YWd~I-gCtP#@>ZFWnL;vS78}S36bg1WP;`ylLc{BBVop|n+Ji`v) z&Ddv&s2Cew_!Q0FEPS&c{htE=J@_9`E=%GkVl;MvS;#nm*Us^c?-WuG5Up0dKyJ;f z5!o4pix}rN^`_g@Zc|6PO=cE91h3$3W0#B@R%OznzEw~Bo=0iEF=jz=fS$xnL)AQe z@DRCYHw_$R7QWa|1A#s0BjMs4tfp{M^4I$D4-moc#yKSd@cPEdEt8yAai-m_OKE^NlH;{9jH?c`iMS^m^}vdlgcc(UC0wC`j& z!>ejI&ZZQ;dC4mw98PZPpoB0xoUiC}el-kL=P7v3cgBq3?IEpp*gE2KhF=NbbbS1+mt58a>!dMR(8+pi5<0tjZQDoP8T5WPg2_XfRRP#t5&# zV-Af1Tq`{p`>(K3!71HFrAsmr=Cf2mEJX2!KAV}E1EQug(2&NjtGsW-c*cM&4I4vE zS&U{FgX@hpVrc_SYh1&4g-s!p)QKXUpW&O!B;xbCpCFcmg{+$yCf9o@eXzX$UF0f4 zT3_rD;pQ45@2};}GnVq^sHJEd7Y!I(CGL-x7*e9NnPyvm;j>Q+zPn&{r$i~~-Fk>M z1Me>2tp$-yaBhj3DYC(OHfrXE+ugG_@ao^Y7DcJ?+QOFKD;aJqy|<9^dzG+|kseSN zwP!z~EnSwEE-u8@=kw&fYO@k?;Iw?YnqR7pPgik4q-u>B>2Ey>z3mw;J@8o8eJWS7 z(zRZlnQmU5lbf^RkdhHk`{pa$D^uZa_Oxnp6pJ^5@UE8J6{GLrW(p-w1cp0%1a+~A37^rX6uU_2Upk!5=caA&TV>}aj8Wd0-duQEo zN4v#wWgPf#R5;sp&W59UQ+UNVKw1@V?6cp(DfP!TOo3M=F-AO^W#J9zVIuacXvSH>keTjlJqs!G(`;Mh0}Y8f5R^=+6g zoOn_cyNwYts!)f8rs@+t8t{?ZnB_2;DVm7L3L5s4yW-HFRrKWc1#}>9?DIr;sM+!U_0_=F^@9--a`^NYclJ9?tUy<@| z0~|U4x&ZnBl;Euf2nV?3*&m8up>1S<|I+}L0~9~|1Mw@q&9Uq(;cca40mZzBa0LB8 zopn2K*H6X`clOJ<$ZkW5j2#1{#V(XjlJUKQOGyo`v5{FqrIH>ot1glw=1|IU(4&Mb z;UkpJxr*V)X#z4G6$+@c1lgujV+I z#|gvm#bbdCL+N8TEEEu>4CEz7Acb&T(l+GL2>fH$J0$OaOyUzs+0Sk8Ssa7=N^MKa9FvIU_$7)phy%vs`S z?M0#_lgPD%k=(C{>~mS}%+94|jF>KtR+C&=cL6HFpt2n5Ew~ro9E4et8}XkHx;U)A z%#M!F)w0^SNvJ&=@7e~%9xZUGV(XDYC#-9yaPG(6>%iP(8Y!eevu^}M^H;Bpn(&U{ z4R6i9V6*V~Vd*%y5|wh-zCtDt+16?CChZno?0fOKD$QeumO^)=XW534E4v+p8;00G z4wAYy-Hn&8k4&iVIX(3Ve|Q?xDT?|d_E5ed=TV+uV9bQz!cqJ)gRBw-m*d;MsUdB z8}N(2FD?D_arDsC?DT)n%gat3@KKVaTab5PQ@hC(@Fs>(a5 z#1L_THg+P(oJ#ph^Qb!|PHm=!a&X%D$xh@3&jTJ%%7LGWe)e{*uBtmlhG`|sLJ@_p zVKtbYlE}1(W}k)&bw8tbamm#o6x9R2_}!Fubyc=FMT5qTS3>yNZ)3K2euj4*aGyv? ze1eE#xlWA}h2y$Yp>0<>x2hN}9x&|0%wx|dLsJmH$bq&Xn*dmFkSq6sM**#Y)UGgt z2&r5E7RbFyok1&(nX(fyXic0=2G4fBvW4ebp@27VQE4OzzG#AI&JkiXMYN$m7+SM6 zNYM%0wzINL>&G{&UynR^8C5s z%OF=}8yyR$oEIlIT=aHWQ;JF{%NClxr_HLo*5c9dFy6BsF7!Mm4j3>{4=e@LI&7g* zi^35q)YU1D?xT`j#K>1D1`BJ@1R6aiy?=w>G3ji7k#v~-B3#B6V2v_d#?w5LeXb=3GE2DO+q@V$eu_iHFlM=Qjl@WQK=|SXSm&SAMrBs z+=XW2IUM=G)Z$FnB20gqXkxfCd3sHJL;aMkEqKHC4vxJ3wpb+GlI6M@{wCSs`yax(#=rFiX} z=%HSkeGJl#W?=!|zJPjmYW9UtpE*R+fOdgs(y}U`;*|PM_D|8Bko!UZ-Bm)N681hm zo>Os?g~GbPUDQq&!H`tSb4xs@W-nA#YVmF3*;Tpi?NChC09CY)Qbns!U69#qQ^3DM z$i+~&i0p?)UPP5bK%6!b0yvAGgPaF4Fh~IqZTx%6DP=t1PP4Qdf1(kXe_ zsN+3;jt)H7453LuwuJ7bF>1P51JTu$fQVTR5N+3=Y=EWs)Be99i zLaD;1^32(!L_>evS<2P$u59N@@u6#v)86rnvMr-SzJ(|$U4nxg8qFvte5#O-F$J^s1 zB+WZpO0ikBNTPG20$Hi{w+MlWbJ80R22Lu84-PRW)siG?_D@-4O46U)FkaX+C^175 zd+ytzT~mA~OpyG?wr$(CZEtMb=Ek;d+s?)t zZEV~2<=*bQ*O|xe-_&$>RTsQ%mc`!*@AN)URaT$1+X(BMTC;39H$W)nt~U$FCJT3@)BV{IAuRcncm6E17fQjQ z^ySj&?3hoHqBsSnW-!SEfn5$L!MCy@*xh8A^REn~+^lTICJjIEV3<(V?CnUM&KJh1 zKb~T>6}>^*-&AssWKJ0y`2vH!fGJTQGH8@oK{lLHNlIw+ECe<-1*47(?Pkv2?wsJM zhcY&Vv@xZwBDbpf(wkx|W?GNl7pI-OP}E(_ zyDMSaSg^C<**l&*z05||xPQdY6~dmf4*vZ(XuV~YA_rKNW0$F0HcJOM=^+(hvKl%oln(wL#Y1JPF5h~XS4cdhOfp{x|d4ts3zT-mkfm;HxFtJ-n^eUfB z$K!|mqs9GXdY%S4Z`B&NWLl@DfWawPv ziUqcVf6RN@%4L2k4-%mP4&?H4=5?8cS-vU{a%zE17fG>1r6&>)a&rXzsGq$gjE?kj z7aeh!vde>OjM(PeCG)gi7;}@gj~gVZL&R$lTQWT;Y=~hRW28~e51_lF@Ye&+G4jjE zuZI~y>Zq#1yba|A;=v$34mr#wdc-^pow<0&CHee&S%txjLLznDWnh*Sf$r%F9$tG!O>aETqH9h1bex{KVJXV zV$U|YW|9rIR*u`^!&DmNH0&@`-3xDKTl>Rcw~y8_sHgXg8w+6blUZycv<5Z7TDGn# zF966}0kFn4z8h9pbDL{j5LNjIk)pz^s_7tnkG!{*2TKOWVj~Kqq?W~q-l4d2+ceP| zN4A!Ajq@)XdUDftm0lOI)ToR3TJ?GD#1>w5sGy-qgm`dPE@HD!?v6PDr{{APd+iFE zQI%@mkK2bfTG#>+x)-^hv78!;B14CQL>r)m+K}3VXhM*R{Av+(IWQYd2*V0{+!0Ho z-qbeirme-*?mB2>#5k+6Ge$wj=CIVlHObFDXL^Lo9M<@mFqYx?8Zjsw22<=M$?U6H z>MFh{wX_+&c8@^IlB%nQ${l|aq>XTF_d58qXroSMm=7?gggb(*R)UW7pj^(a6a8Bq zPJJz-8w^#Cod2Rr&u4nQ9-WYfHWaZB&fd?36!Dpt;!FKb`LP_}TjrG0Ev)aFm%%ZE z(ZFq%y7`r_aKkx9BnIDH(NNWcC}nixyL}8p;2_>tys6Yl`CC>3nM)j_xo)Rjb{g65 zF%#iBi-?d$hY?o1{cRL=*G#IBY}p^3NaF~9oT6keM%XTFww25w8{NLcsudu*LYsR& zxH$%zJcXe+t}Y)-A=Pv(>pr22l5*i8lEc1B`%W_bRg~#_&Gt(bP5|9r*?DMz7lrM8 zX4t%Pl~E+nEDw4R#sJ{_N=0>t3XIUF5YQrz}Zh7Of$jmsxiu2I}qp=V5#e z7wTG0hKO?FM^&4o`}oE)Vk@ab;xZ)D3iG)H$I42E_?8{`I_(}{SLc~)84Hu+LDdJ> z!Q%_MMca!s%8vE1SnxWS9W+?IW8SzrZ8^u>ZG_YQ*IaJjlkf%keR#TpZRTM)=*seYbO(gMG6Q#OgazX4Z;F!p>qB4IWz6z}nt3J8ht z*Nt^+<8?ABh4c{)yM~!C$25P9tKL%UpUgDu%D$>gwZS@EIL6r63KMH(+?TNm4<5_B ztz$kj-OmyR zr`qgU0xseX8O?9tUBHm42VtZ3M8nkbn@J%oS-!m25(i3TE%HQM%Tt7A9Bui)FflZy z!?4K~oYk&$I7~^)l=5yAR12D|c82l$(v&*Uqgv-yYTbVbGn=RX$dl$|DT{-K{yBVV zit?1(EJRvhG-4M2NZ=?eYSaf$IApzRR?Np{JaUQVf;SF(H?7ETDE)1=^Ot4|d|zaE zbztu#1LO4bm0D@@4Izc*W-D9$KFRe2gP6s&Qza;6Gg?F?#*3ujSANeZA(U@6 z+`gP{?297(Sb?$^D*UFqj~&L;L8Q1w?UL!mzc!0(%5f-K;~bkU54p#x8)k-RwPotW zqPQH4}CuO{S9~^g?kxneG%s0j%fF zo74|rUUQu3-?M8t^|4M0iaD?j$2dhXx+_465^``$i0g>%SXWgzdcH0y4o*DUod9vc zrfbSs`ko2fqI`$<@ORetFdSS69g2eH2t^L*rt9=0Jd9po40Ljv)e~JDUIbDgfg;sr z57=HHloVJOcU!O7R72My54p=mq=iJK<%(xpFDI9%zz3Y*4~5cD$v87pvEH5a>O zti~qzqQ=QTlGG5~W4hJy7Tv3QB`GTGd#@c8AV**HJxVdpip&Ir>l1i?xBTSb7)U-B zuZrmf*q-xuD5ZjV-GzK;0 z0H@pz(FWL#{3cyR}g5u zO}b8CFa4ss7s$vPX@0DSEHg9P?|_$kP2&mW-qxacvXt&(L{~8PKFN{M$>pdw=02}ONkJvx z=$1;Dlu9uEeQ!>;llw`V8NO$}foOtrSOx2Ma0m^fB?Ycr5Yz{$jFWfHBi4fNG_CAc z_LW&aqUf)Dvyd8%4^|QzQ{P3u_ygw} z_S`??Sm_pS=`?L61=HfmXeL(9Vr>nJv=)QmF|-V7s#a-ZoR>iVJT#p{a8?)k zF@-VdDYsT8sPV|>0?}7c=VCm#wG@&K8(`*Fv@9=Nc5T48B=Cu#->HG^uD4Z$?63FD zQfQi%S!%n4Mk)!-!JWP;SHn|@;XF3}P2vpMYB#eubM)H+P=K1{2l_7~>MqEV{mRS} zS#!L_Wt#dV=xVS$VmeWJD>#UZ&CUvf+b#3$2}>{9PFFECzs=9GR>vdSp+KhSizQ76 zDdb{+u-jKxgqXWP@RMH{@$eStZZ_c_CktE-LT=-`lW8<6-gCOsqu}VI_%BOM1tIG`)6+Y8dDJoMx~9m&w^c=z_RsK^)ASWsLN9UPn;8-Y&}2xl zdW7vF2Z*SIHXK7Y2?*6te^~OCeY1xnQ2bbTVrvIG8(_KMrWCZUR1J=E_3};>IRDG+ zb=T}usA7vyoilO=p?&WQP5`1KHNS2f&nX+Wp*-?TG2vI7<#65)L6{J0poUN3ZXk!W z{g(XM9T0krzI?&o#M#E)rm*rDlg37HU4DTx1H?ef3q-T{Yj@Qk5exROcz)IqbOrVG z`*l|gF(D!dWOtPQp3olvNR4vT@}qVcyR*=ctahAHIuaX+yzLT4Jyir}_lgb*76>QD zP*!&D_-R%mk(*00EJwrm3d4Q$NS!YDes*-Q;SR+!rNP??lhy6}Kh?fKFM*iCffO1G ztEWWMx@STxPPmAdU8~CHBm}6kpqMvsIXSk71)#~j;H(IndY>UkLIC?Pr*|+b8(8`6 z9iFj&b$V$o3 zoo$3g39qNU36>T#9^8L|02`;O3&N>8oT>WlPk% zn^Jc{FEM)`)6v#@#<4h9$;urEia}~6*UB#0&)BGSBUOu%)J*Ios$M_ zwO?1y8>lb9su!TLE^t_wB_bvJG^fdfdBnk%Fd3@sFZ@Q9+6`0=>J@Lu=GfGvh*EL5 z5asoGY4P?iYlr=`Od6bzOm-qyU+{a=hYD|MK~v=PhmcZ0wRGK#d(aaCsgl54oAkA4 z3a_dUHV%c1)x%w?3!(nz4ROBBLzyw!oUkqpf5;Z#XzHud@CmRPJeH5L#^&z8d?mUGp;xbeZ9 zsr%=&aXmmkmLK_XuSY<36d>I!WLg!Fkuh2kYhHFe?AC?N9Lggm$T66M9oVn-c|xUm zy?4C8YNIbI@8qh$-A==`hga^)-;Q|XDLzKu1kt;OHT>Siu$0oAf#O(jR-ZjLPAl-PuLLQN+Pb~2_``nSUD+!>EpEQI%iOqw~?8^MCi+avokoOtqu-SRJ3q{U5S0R zgxK*{L6K)#eMG{n(t{+W&{f;xHdoxQ69=Jf-dS2=qIM>Qb#hD;Smi1@0k)fk;Keey z#n!873mn=_2HnlT?Ra)SLvagj`+}>Bl8w$$mL6nKb$@I?Xt=n|Rx9 z=#JP1@6HuvWJ41gJG$Tb&la|$%n5tRSEKGYhu5qi2;R#e4TJZwq}vsW=3D8Gt+{n4 zNA4aOumo9gA}?WY%xyt{*B|2<6g~C!=o(y%VK@wa$_HfP18(!QW7|*n^{Z{*5%uaB z%>2u?&pH1b;V!n5cjxYMaIH~6sDIH`YbdioDhM6ST@J|IYAYv`dMoOj21)~HuHvxtG#NA5o5?ejtS}#U@>{!vj$rQ_ojR$;Q@X!lG^j z*CUsI5d&Hcbw&sMTR#Nj!*Wr@NFSlZ3cFri*22up=}c zrY(!2D?yS=&#Y*(;%4`@>~rbQ3^|7nI&Pa&aUzUfHh7aQjgJ>X0rgnrSC>&Bt#jeH zRj;M5Z+w%U)($iN!bRPv%7<&{1L`+uE|Eoq8ArZJG{uIc^m8g^2~C^3HLsp~s>K=5 z!p4s-`WL3m2S{1d5Fg$Fi;DXFLu&{IxmZNFf1l+QJUSNbJ6T`Gkx<#riX4(RuhdNH&oNq1hY?0(Zc-%!Ub(QZ73hyRJ6De}e{JtL6(Da!x<(l1xoLZ)f*_j7jijhD;39zYdLV8IuvB{&9F-I5gSR z?tE-Wm5j&T5DUpgKWL{`7(I5|k&^p;Ge}R$G8e^>JLEmZt|@7#EG}!URM`V1E*>6@ zK%Rb;ArZHi7#jOq?AG(t7T$pF@5uVz;5Ibm=|yJpexya)M8rb^O;8>0;O`sf1e12q zld@KGWM2bYLEWixmD`+Hnuv=7S|THi4%V$BJ<_Cv#Em93dKI0`@R0otFx3$Yt6R}g zy0nHi9`M_aEShMzL{`ft@^ZTm(yN)si3Lg=bn_Iikl*sjL~kCXAXGO+e;wtJ z@%7KobIKZO3ZN_yS}>60PZ(FHJT|8|b`95{oKx#Br-fwv_OYcoH|U~4k{wk0cW$QG zKs3f!wp3vt%ADSneS1N;>rv)e!OoSPUl30a2n9md)Qm1k`N{d8aTi^qiFalp%L?O) z7oL=GrDl*jiMCHB*vGWzhBR{Trw(Ht6*X?{C^f+kbGbOnH|BbsmW#r3L+n0GYN`02 z8QWs(cw=lcbI3ky9479oq$UR0@^COA(+Dt8ztG`E1G%8U$wgmXzVj)&EK$V}WFv3D zpx-d%m3XLH+!9%79pj$Ad@eE~?#GlYAe060gzfkX{0tx;YxL0G%g_ctE%|>$zszyS z{8}PU@9=d{zsS&QZflS;_{1O4e!a~klCjC}x&HC+%-OCL0-x&ukHDUZ?$N$F>S130dxy7tdUPw>;8Plxm#W0ca7e|gS$(FP zIAR;cS=_L2PYgFR7}|4w=Y@VyYM1quf->*;vk0V372~_i)$p)Djh!d+*daibWa7sI zY8I$)c>DlFU6p~WUtWMH=L*FnDO^w9TAmO!=P%J5@6;4BUIntgpH@|Cg+P7B1ea)r zX7OYxnv|Non5#9LL!4J0g55CgYFwZ!G`p002#2ADc-|AVJ9;ym+Sd#qMm?Eqabx@N zU-+{FEaus6PR|?HFxvl(gkukqcbiK&?Z+FO=1w8^uhB3**qYcb@ND%h}Q#N z0|pX{{KsbpgaBBaUq#nF3FG$#5Uz!4kTA9oQA~ckxS}KpWib-!yd5Oi)G;YX37|LA zkkVIoAIOQ>;UYfNPPnH@EjJ7(XA9{5P|YbsrOuIKlBO>r+pOol{H0AJ2d*(UE?a-{ zEc)zvw?+#cV{i|sFWde~#}}2Y3jT}lk!}bVzzH=AJ`2YP96n4L;Q7O-ga(=bY6ZCf zc);(t29O6J0M>q(GR?m6@cn>#=zjQmyqzDa6L2@^4SYWYpay^k_yn9?W03-zU|?;O?4* z@pCc|Q_uJ&bn_Vp z7WJ2`kpq^In^8uVbmcITnYP5vzm$iOQKuyMprFPmR#;+;D74GeG2+IEUq{1?X2@C? z=6d*rMpv;B7wczt&+3t|FUPXPL*wvS*o`(`pb}6hM%2BLx(@KnEXu?b@lIyO!|C+0!y`2_eVXZ^CwS2g;Y3ZHFeQ!QmFTPlMbvg35At4=At1+1SYZcPM$v8SUZWh?pmOD`c2# zL5Z-2QJ|qEkbi1RYH|}NYSbhxBPmQxr%6uR#a>~HTa<58E##R^o6h~p-gJ}j^oY7l zC>ppMmG!u>6m;K)eZ{Pr!{MQ+8)SpFv5WbWTa(pmt-cM-zQs6GlqyLW;0DPBp8#k|mOk2^GCpfC)h-?EVl( z5TzDTi5*=V{FZChBxjdEZIcU(7M>^_Rh2v?87-GbV}jYM;@X)us}W!zbVuS?hC{HMFcO=%wcQ|7fT8zMqo^-S{|*Zs@g5jyb6 z{%pj)K;XNQo31^^Y#OpAc|zz=bs4S^^!-iW9Bw;WYMg)eAg4$08MQ&vee#`L>9yIx zYxb0lP1z+L`N8!RQlilu-eVscX(@Znz7VXaf45AG9uNJ^eGGcWeIk8z!LMJJ;KV%r z981_6?WliWgNwtqMt`?OI$q(UmVt)pBI!U{3-iYYJqGV1Y|<+i`oLHRo)|VyLij(p zoquMx0K*I>G^)Oh6%aG>q@bqk39E*D#th}q98%WY4wpOwlF;*68eQwlO}9%l}0cfz)LwZBd>fE;B3j z0C1pw94a}ExT#LgC3yCB8)}mF`l{HzAM%^w`N(yDN}u?s6&0;<5&Oof4gQLBuX zJ3PdhoCI0g_y1IE+t}&D>g}rv%rsx_F_ zH|O~N4%lAw)qdIL12zHi=Xis`1ZoTvc!m3diw^LAxV~N__#WJy`JNWI2&HhuozP!EC_T4|gvHdo*e%-CJ?NEMuLy(mjhs)>oF`Os= zGYC2AX*%Be-Wf`b&&1bd)JO( zVd|1JaVgeLVc58GfAi*7=~|PMWYOwPS8{+fG4R2pKZSBX=);I0*@kuB|B#Npz=(yO z+H|ZViC^(VeAiqZ-=rbwx4QJ9T=mcxU8GRjsJxdjAXOVW(wq*zZ_FDVybH_tI*%{I zUT$gPy4Y({1LqMC3WCaVZAyij;2zqo*1|*il zqKq=up)pN0Dg5H0m&PgZmUrs8#vq0T+LZtg{Wi2R@Tk#$XQXd0r132(F;?4T4+T=mgpCYR zmbTdpCAF@GO$iO@J!X>ZU)f@ddf6}a1VhtLX1S*1BMgww8@MAY>d7CbM1|PM(nu;Y z&G1(`)1IAAV^28UL=&pH=J*%kkjprR79CEt#;ZS1Jj^sF&JmBPcmtY6WY*z)Wo~kw zJq0Jk_y>Z@1e2|kmJ}4}FI83Ok(nXX`iFI`T3n2G(o&R$GA@cV#}#aWLdUxbie}oQ zAU4g`j*W?Km}I$zlpg50u9V5{E{|UH4>qd2ruBl9o?Od`sd?c<=Uzt@d_-sm z`=Znj=L^8eUit_v@pQ9>!UBW)`VtKF_+(+URc_2M9BeR6#gu#5fL<~Afw{Z!bRg*P z*951GZLJAjpCoyes{!-v2pQsDB-F0@%g=iM#k!u<1iZyi!Tk@}3^-f4KZpx-`l@E* zX|0fktUXYi-W+`pkCMuke&U`=RG0tWO*Hcz4Sur(kEp<6_CA_i=%e-1ViSw8tJF-< zPqdL^XkScD$hI5v`m_| z(9+zqBa*y~2DLKI+QV$$SO>X`2l6A9Qdi46)wc+S_c%W$@48%yDV7@4vRyd1vz-e;9)!NbTIF=M8SPSCkk)wOB` z@&~xW?42xsYoU81;j5A|J!7TOv(p3j682%Hmnx4aV=kL8vRp5)zREzKyt}*t(tc1m zW0U8Zv_WxJJGMogRM*@0WBEGoyDCopu7lY>0sL~&@m6ncQ5hj{_l^Lu&HwZ3`5WEe z(Bs^Fe@pHa=4P4GEm8pF4I6OChgb0Z{JO^}hQ)TBt}02NTd?b@kPIoRB*(6hQT2z5z`AG!?Y@PknUKQRD(7y6w1XN$XxANS^2;i3CUf;_KKZ8HR_+9dM zMeHNLoo~O0{J;C+fKH#kUlb{E;at*xRd@lRSF^2i*yjAcL9{2; z!0%m!zQE1+e{|c0`&7MESjTU0*fIJg9$W>#l;v7`+wtBL%s|c5U~+%gc#ol+SxJ9; zERJ%UJ&v}<{g5)hR#O$U>lmkUbSx+K`sVq%OsGEktgg10_)j5x)0i~&BcBR-`h?>G zPe0cBll7SyTN0$Eu5MKus5)1c3m=ABS~M8rTOL5$+sy=E=xcYW9d1c_Z%P8IN9qEi z9>nO{i~4n;=;v9Lc49%=u3+-%?{PsWR(?=W1A^I~gM!~d?1V^fm0rVizA(0~hTJZiTsx4M1*pes?W>NZBAv^_- zqz`+5N5>sJ07dZj8yNWJdc0x`;uCd#Cabr7vi|_28dP)1wB73CgFsOR1QZnj06+pV zz`7IzHW4Y@Apn5YpCgQ)Q)g2bR|gk+dmCp4OFL&5LmL}YCwd3Z8ckdK{dT0UD}A8@ ze#zdoH62t4+(yRPr=>1Phv^c_R&PN>%4XJ9t;yol;=OjUZ*OzSiQ?)5JDu!?70H9{ znVXD);a;`1M!6z&l-<0P(>&QWtCq_C;gq6`>Xx-8ZOnD8IZSjn>=v$dDnaWK1<>pF zM>0AEuZT-K6)VQdh4N7uMuV;;>QG|pmThM(jQ;5c)OpP<)}DSB+hNEV^yUkx7!Q0U z+*SaER^F-Uo@M0I%V=A9`(f*LFUZ^E<89BZqE<;<(s*$g8_n`whxM($R$5FvPtxe< z>0!w3_1>Nlm0Vfi+|q_E)1r0(DafxA?N(qSj_4+Ek>P)tSXGV#sAFfM;cO^>JgI3U zS*OMt2369YR)p)4{IGRLAVtpxn`7!<|0y{b1Ms}XY+{wH431zky}}aO`GMhVJX~p) z4XSKA&O}wx>Q@g`!C4O8kcVypB{3!1IB>{;tjbrlEsxS?Lyh(*{hffZ!u%(>MG~}( zO6zt)FeBB3A}ebd^%of^$<$zpkfLwVPWHyo?)V-115e6Zt+yy+b`2$2KOZ z*bQXzaD3`)_zxm^#TEg}o{h6DY;Ey*gL&6x7nWXLWCE6IRa}{YUs_q-Y&}nc+>yyqf_1^qq(}gRkvu$c$z#G=x!hM-bPO*xMLg;4l2>A4@_Wq~+ zizcE<5oS^Y4zw~Upmx(j?|IT@n@v4gAs)uXFj)<#BObAdvd$>z)iDx z-nWmpuj}V+;-+nmIb`ButbG7%>V$ZaxlN1`*~Kp+u*onZMr5es&N17DNp3HVdy9)S z_^3bK4F(sdmz$Ea=xF-_yaSqs;r^KFT1~-%6*T?Xmy0O1y9I|fn_5;u1=*1W#aPn_ zU>z6@2i-}ZZe>uOA5#_gby_Dk^sL_!=y>nfDWisG-KKS9bz?@HUU{|b%7zbu{7^Lq z_{FB)weFZx?gy2p+BR2;Bw>mw=0wJ>Nbs8&qQuOtbbK1QA?LBz1^^X9?tv-kYE(V7 zlOQtMh85fFigdLaF*z)|od_8mQ6;HTa(+j;F_NJ>@%+@Rs;s-Sx6iw@yM;>y*vVM* zucuQhPY&PFdRIIa+{1248FeK!AlEPlXpye3Gj+L5l1tV7r-BZ_c+9`0TuW^A5~G~% z(Q%*s=*nWd;;_T>_^G!i5@Mu7s3HRc9#2B>RE3-w#0}4=$o6!xjr{qj^lh(khnM<( zU+;G|Je?s%f#ikZ69EYOzQ8wuODbl1Xug>!@j2R3@$$fXkWBDS6Gu9>#id~%K?w|2 zZ_|c^c3%h!KYL?f;V{EHe>z$nCvdFHFoT$vYnqmANdCY*VmB$WdePkT+LEWu?Jq!7xGhX^9E5!3N=?(5UiAtJhb zkG}IKcwqC7+e7NSz0VLc(q3HLF~NW_x>7Kxc;`m1Y~-8$b`lhnMlOL9ldMb1DTcI zj4}%wCLoS7xjTCw)i(55Pb{b@!=$F z626AK6+{Aq_F!W(6!2mW31zY3WvfjQzZ(b_>U%*daaas1!#dVYPAI=w5EFhSnHTik z-~OdS{5^Bw(cqpS7QeDD5fl17n6TiU8}v2lJ^WgR%#2Vn)o33zgr0T$@YVI3GAP!1 zl`{Lf98A34shUrHYLHXzSm%!K;FultGbSu+VZ|-ctJDS|b>B5JuKyDJ@r%s{-h4l> zeRcLvQ;*H-?f%Ev+tAFaOSyY7ea;Q^8)wL7G0^c=9o6-;K5RA?Tr)iQXO1~*R!%MV z)pd>ej>j?=tUMY}`Cvyh{G?F)3KyJn2K z@d3t#aQCN>9QSj%HT4RF7d8@wKiD`ov5k(k7R47ZBgC02pj7+L1Jl!9d12X=J+bU^LbZ_W7bYvsOaigN7mQNDe8 z`P>JNyregPyt1M{)DYE>^}G2o0!B}1d4CX7o;Ww7#Y!utji{u{(MFQ5@e^|91}kA< z$C2|LS1%aROuqXE84Z^?6YZv4JHbiSg`VAGb}`*WVOp-PHyxM8pdO2%g(N}{H=6e=m!h{ zZ2o+>F#lfwEsdC6>{;|pJ${0iqbe7d#faGRt`U7=Xqe@+vZX#@xt`)>q1NJEMSajO zxPghYYL;|acb$G?I5t`vnM`<-blmCN)3 z=%&250hhKVTt35!L8%N9K8CMpif$;YsaHHNOo0r8i9&A=VrXG_w}D->1l!i%NVRjP zin6d*$JP}gsg*A=U%Lsuc`LsO^?j%apPCSP}vua}gfQ zWELyU)aUAPILX4qE!@K26gT?C`c|)c2PN1;x-n;s7RYGZFC)dLaJMFXcj>k zd_U_U=#F^w(G=xUJ*m1==q(k8gEZ>U(jY3{CdpWDyk2Ejw1kJkwVdcwbCwQL$q7STRir-qPTfWxNn9269C0&_|zYL=^fqQF!X69AlTzgbU)lV zpks%9ZB1oQ1u@A@%yr*`{Uu2Qt$uYoJBR3oRs~^*Z7|o=l?xA zw)S?`rk+3f+VWE!tg|EjR0jhkn4}DujjZEqV3WUzWdh+Ru}wB34JjeD3vKC>%M+4O zu9vT4QOV{V8?T0dNmEC<_BV%)_0ofbgI8Ouu3u7Jrqr$HYQwb?e<}hUA~`M|KtzTG zcL^Pn4hlX+L`nRw!M6H&DYG4%GqG(q9H0cEPns2uWo{vo_*XNr}o%LSHWjgB@!QJuUR=hLU9?VOn~L zGK<>kfkW2t42yZVd0fGQsU}rkLD=qB6^Gq_>i&$9s7@BwuLD(UO{ay_a)uPB=}EB& zUflLIvzb?=J2CMKoHFq2cE0VX+2Zngtoc zme+n!Np!CPl06#?y}kg2{17)p0e&f>8&++GWW#nUji?WsGzCKX_eBSJyX58E&mWLq z{7*>4Qp#^PySnCb>UC~Tdd0Pml4cRtbv+hO?%3y`pHX6TyPKB|rJJa=f4tFIP{|hEDHz@Xm}dSoN&- zIw0w_U6)t}qCC}M%wVgrbx*!eFgMLErSo4V3O$_v;DiU~J1p1Z-6i22Q19hRVzt)4 z===w+SFIL5Q~cjo`!@-fQLCc~W&<(m=t)sEm|mczz4%cGcZSt;CoMovs zsDNdrQ(ki)J`iS*ueD5X1IJvsjp-w#dU^(i{6D-aysl>aQLy`2WwdcZX7>@(F-ZCikhdoc2=vP-lPB-U56wK&vwVeOrR2vty|=H7S1w%m%?-tPBEK!csU0 zd_07%h!(Z7wEECn;wuA#1_LPN8NKRQ85q=-*FoCztDH6rHT4 zDeuOBsMkt}w}-fLQ4gvKDekob93||7&cG1&f&A97KPaO7LPvRl(u~=Hj6h+`$|+0c zY4iiLDh9{njqUr`J-f`(_kR<#ue00wzPlQFU*8^hYfo~I^dc`LqeJIQOk>|@%+yLni0yOm zg+n;}EeQ(^-n@pk()ex#p$f?Jh2oL+p>~t}RcsQMIFCh{q>G}Luh-apUZ15NHrxXp zYOjwU6Lku1+(4T*zeRHENge>NbrB-aB*tJOCqyB#5wC*}>YVG~)Z&3b@!;^0HL+j7^4gSnqRLXu_xzQ80CE3-5HUhk3hELnE zfO9aXU0ojvMgqF-GVNk3tRYNfRwF)kN86HtMk*t_2eX_6?(8DD)sEBrk!y#EP82UX z`3ipu-L|cYIYpR?%vW&qSf8gsH;8{! ztwAh|6oy2Nn>`vwHsC6b=73@6)QJN}qGW0yOtUisAEPL}e?X{7Wzg3Z*--y_I?NI! zn1{g-r$2YVCQpI~t!V3HCjT&6Ud1@ehB>)PYwCB85_-e&`|)7C1U!ilT>$&;*l#7` zd`@}{CRLtnFMiv+LS#Gp`6c*rqo})A3d23J<-+-i@)EK>s09%4wBNt~%GcW~6L&){ zE44exRuiYpsxf5XtHb5q#PqfJD#%Z;ltnQC0uyB%cqvjTXMTa38|rs}<)z2l06n68rVHb$y4wl*^+8?5S}vvIe&E1+b66Ym;vV#e zIi$HvY!uRH{wpmE(0m<0%tl0OigU7Erge&T%iOOAcO>E5o||gHd%nPyy_w&%`53&V znpP%}-yvr5;1pAnu6ESTowLb35gU(niyB`c{rzb9EE%j2X9vTW;AQ=8wcFm5HSFtp zZ|tF}JD=nXk4DOd!R(j6J$Z*F?5~^~i~9l3i~p^nG8myHS;@=)L40)~PgX3#zTJRu zz>iBukoU#0Kwsl7r_&SD;oIb#CAoohSa@}xk~GGW-EmqvSO}G*%AO}c@u4yE_|(Aa zU+!VPzrYz+jd`zyPob20#Sb+S{X;Iq z1TCMQo{nj2@=T>)U75tV_sm4wBAxC=xTTc2cTx5zbLJF= zFI9)U3dUWv{ltOKBY>k`F95;wj)U)0-S-4$Abh?c=a@jgwXjpN+~L=VBfX7F1X;)No@Ocp+U`{3@}2OEvhpXJs4 zSADgh+Zco~ri;?>0pntNDnL{3Wm(oGx;|p$k^d=(s0gcrs*<`SIMzQL?~> zgX_%xxdC{T8WPOQ5CVz;2TIP)^FiX~82E8DBnDJGf2V=*&Y|cWGQbxs%e8ZBAn+Jw z{ILVGmit33+vKAALisPSOsXSzGGl-A(8e8qagog2NK|5j&3<4xD#lb+$v)WFAf5SDka(&WSS#x-mj-@uE| zVIdeCYXJF4uK^)xxQC(F9KB~55*5VBVjOvs?bSopi%V3#6^15{KEfqCSAaUMP$=+t zYXqd3*84b3Db>R>Atz( z-OE2>9KylDF=pRI4MRbkci_?%*TR=8!)plX>}ETI{JDM+9wfazT z@Yv3hT_{(C*$w%$1_Ft`WQ~%CPBTg%!*+Pf#K;IT+Yvj#zVE;dHAkA72~2wh!91g$ zSaIOd5J5m#y<^maZ&}5(y9Vt-$?Ghl=T#JJ?TNj9CXL)UqnbOE*+ZGc59ZyG25MCp zI0y^_QVOCNlOOTlI|rMT{sj2_^I#I*2O$ZHhA8(*n{yf94iKAJM@1|cASckK4RXH- zQ&)}%3q%<`e{|6vfH9%Ed&(8yj~dquWM)ueLu|U=eSWaIer+lvSYX0|uaecuD;4jw zB9!@zD3$tb)K7!Ah*s}XVLwwd?GyzBIPPyL(RGreV~v|a<&qHPVyib9tMKcV_`1Zff^jd)FwTZi7O>lNE~)8rKK(> zy1H1=E*nY>oh8N{fQff%kcBRL40I*ur6xnmtBrVy3;q_MI`hCVq5J4X6VyfQnvDRx z*xFMyE_u6}!(v(xfB823@=`pR>{J`hXlJr4KY9t#kqI zI3Gd>D8l}1OWA1%jEU=NGk13@bhYJqZwp3|)I)b+7AGOd^8rZA&cm%B8m)QpB;hnZ z3sdTpcUs$3a~)N{@wGIGuhljH0~PT!E^fd(FRmE)<(tW3HoplJ#7#1;t`RsM9R&Lk z`+2{3yTR^m@U&|n3VO5-7q@IT;0e(FI4_wec2m?IIh)LN|Hp_Zbdq@xhQh#xVHbus zfA={yzTHcL-X&d5uGJ=?*`=z_Vz&-~PkMu*MeL=Er;IZ?!1@mU~6qdi@8rRwkUiz*i7T0ufe# zdLb%0Km9aKK@;blZn@-V`8d5wzkK zSAh((9UPQ#X6*i983ERv*)X?ZdyGV#hR2F108T88&wTBPlC1iw^b_BJRKGM2q@rieZYBgY9$Z31fh?52srEw7(KOBj2Z z&uOr~8L~o~!Gh)`_ZIVUgs$jnj3VY<6vcf1$&=_Zg3Z{I<%o~*^kvB)!JQ}cY zi?&}URd!WQ4mNJXta%D|H}^f?1w&g}+up0EFMqbv@z(>g!frayg{;v5)}H0A(+d|y zoeEj{c>{`&aXe5XP5)#*&Q=c7#Z_TWT^zb2f8uvHq!&Z#7Gtvlubzj-hew&E4}V(_Ubr{I1b@xzCg>tZ41U}I{rLMM?g-R zg?e|t=Ygq|YL8<@RyK^2xCp~e&ZZNwfhngS9|rgg1~JrT#=v77v5tQYiW5N7nVjV8 z-vEU<%ZeK{Nwlt15f+Pq(d>- z2b}|9l&YjnidJjlM8_Xaov}8Y8 z1P;O3B%O}INiNB)to)K>gKUAqew}_nnD3LiK_AT@B0^vl|7Pq73P_>hYos0&cNy=e+EBMrHn%|BA+$V%P&PgZw!~k7#X-r-S zE;wNbrXUn(Xos+!`(RP4-Bqh@O=q-{yG-YS&}08EcO@~a$(@*(`w={gE^RA!6%Z}O zuIz1-I`n~ZP3S;!My1rbM6Hj#?o`s`xE9&?k~7J-Tp1BV9N3a2x`nC8iUAGfiUjfw zB*)imc2z!Yxb#dZk%AWr#fQ)Uy}&AH5}uSHXe)U}65!S`4I*k0FF8(4s`R!fFPf7_ zM}_e3b{?YG2@qXf-h|hDLT8cLP2FpDrXd% zm?Ifgd}>Vfz!Z`WPcR9}yb^O>J^gn*yQHC+kz>*XPRlfLd+7$rRd;AZV@GIvxCIng&fYjY3#{ArBk1o-Zwg_MjwYem$?o zxyn?0CCtZ{tC5I-s)yAV#@M-&mMb1fTb&XSdV3=6%EOaZilZ?Ry)v!SDVzx_CfBRe z8hkwZ>>Z;CzDl#pKN6*Y*zrFAA2+FTVlU$&57Az&sB2_s^&Rx{PO#rYuS6Y#;ahnw z!*S8V8Hy#sHJ}77n}2T!+)&DJqEVfTR69j$Yd0T2?l%(6Q|PWRRn42G>7}-D#LYpq z>oK~(6#Z$!?T+UlNylvOIeOxy6FrZEN??pm-;{T*XV&>v308@W;7jundYXRnY3ekW z51F%=>$8e^>W&G04~@xcP?jD>pml%xk21qZK)o;J8PRWemVhDGwP%*7w=xLu3NuCr zi^APTZ~Nrv^`UBlbp8JCQ#3^iM(4KyPsjG&{zhNA^%3}{(<#OE4o+NGz_~}!;3mx1 zpg?{`X;Q?=g4G(>Pb-~Wti*|>D(3!wFm;b-z+HFF%H@Y=^J`KeGTZq+c|fVVO}k{N z|1k_?-!Y5y-?sZ@x$?z+S>LgjOGkfN-7kZ0`+aGiRN;ePwqWsRF&=4iI)(X;xdx*O z5Y8^jMiZ&>xz`8krhQClUdrwQ9L`Z*IUWa{w?HF;nZf*Mah76CDavnnmQNPv5;I`> zA*CoACu;mDKSARR&eC&W@i9THG}eD}bU~xh&IUd3^$e1?cGABzMedt!9E@4&JJH ze)Wm)Kc|QFXs^Dk|$pP+uSKYDc*>#@#m0u7HHB zVAS$-G&gKzp9V`AG4r-A5h88RegIlJC$MgF#HjGjoWSixv=at{JXodDzXL~MZ z=4)vIYhDj@vN%52Otj*7)QzLl-#D|mWEMB6;?>oCj+Xw0)7Qush*I7Yu6EB0OZ3QV zK$D3$o{>La?T);NNid@1oOL*mb(}D+{YXk=!1^dz%*baE9!rewirxFd56}A%d4F<( z-2>8~yipL%VIsy@yU^&|*-8kiA60gse=1xOJikLW$q7Ox{i!%qQE9o*j;1=Z8RUvu z%W8T}Xfqy!rn2!zrB35D*rlfl-%B;r-yaHJlyH{9MXE$6Xy`ogE_i5mFmw^2G3M5Y8 z{4_VUcx`^4=Dw6 zh)Lmow`)UVP~iSaEj`?~$@<+2ky3PcN?jP`AuU_^yzVh7R+=mko{#^n`wi<^Il3ll zu9eYK1*sP60kmAkbIP-?%AHn%gTC@vM5W-fic5wcBK9<`Ts(P5fzJ@|E zV;k0b3MT9WwD>jOOMrg0;(*Ib0CY}af6Xa0>T&LV{-hEo?RLJvyDXL?elTD@3#U|g zW!aR|H8dRrRMAhf{M=c0V<|B*)8pH1++nD0O?#CpmXwsDu7UmU(-B(1%0c$&fPBfj z=e|6e5rLs!Y_$t2jj_Q8+XDYL%P~SuneJdPDV~6KmEsAezLM^tCGhZ7L#Ny%H{Oe| z{nqzYLI->7EbbpF+M zw05C|#ie+gjM=r#si=sXv2vsiXuW{cc4eO71u+HRoZbC;`W~~BHQSvb$l7YAXYI6_`L$1{Tm(^7LXnJL09N%a(3sv6xTk zx`Nt)a8t;%Za-?(qH;aI40iA=XD`_0|JjKug@DEhg{>H{ghU`--VS2d1>zM)=GE;W zp1MKoauB;sAgtAZ5(JVcU^vsNNYqpCvI z^6h|&OJ2=TGt&yoiXH=ir2?h^0nga41bR@K34$f-0vwXdsw*yrOEb+e=g(^4wMK)b zPPd#KS;IzIycod%c~e@2Nlj)-5Um5K^GI>O46=!~Jjamd-L22Vx7>*J3@etft9mr4 zrDSs66x=I>f4}a-KS9QeIRn4@t=3x1M^;G}9U3`!Tu3?K8icXaYvMuadJK?mD?|2- z9mg7q|Kq!6GAx!mVe&0(8b{$k=t4AYXDafwodXOfCy5D9X4&NQo zby;|5jN#w*wt}ht_ZzRGlOn$Oy^pLoz7`ex$~8x385>2*F1_a2P(m_aug_i>zlhp% zU-wd~%1Z0~e8>1j*7zN$8s#b~;307*oYG}&Ls#?WPz1456Csv0oU+=lw5HeIfmD-^ ziBsESVijK#9f>qAxv!R5JvKt`TRbTMPj2REp2w6gr8sWJDB!V7(9sU+S8?pB3V@Jq zTK;ONM=+LQ%T$87xE5`4-PH~>T51~iFf}jYwNN+J5w~Q}+&CxUP6Id7{4Qe3iycvM zx4r}rVSbTxqOdV>#O0?416^jg(OHo|oVkgzflHkn4=$o?zGkTOcy@z7O24?5nrpT0%+^MU&z zY7kc1HmlwuVW$IoHQK4|^6-O26L1}9Chd``mlp|F*9V|vThI0U2$v6EUBhL8hBL-w ze0=PH?HzlE2It=}&8>u_^)6Nu7Vl({6!DDx!FIIuWpL}Zwqh98E+Ue`e9vJXzJ>^6 z*ZQ%9qGeHa$A2EY44&fp!7sbwi*J!qc)llF?#Y&Wj+QTE%NMfc3rn6t^J=|yhE`T; zmf88i(T7Iw!xB+2U5++!1XLt<7fV>l?^m3L33~Q)ttoo;6mI~3__Jw#nlZUD_|FsM zd-_fg(H$yu{f9hh#z~#Xk;lkk?h8oNSDBT)=WET%-t#}xtduu){g8Q~D;L|$i_it% zwPGH~=ot2wax%wh5hhHXOXi(tPo4U^O7V9|;~$4&dR>sD(b0w%wctHptL5NVNVX8W zT8a~nxR232gJKmHN*1#-tSOm@hR>d&D;9ab{7x)Dl5wg4SU70xA#hu=?(7+9LeZK24^<{ z26bE4v>U-uqk;#o$%b)48ns&3CK+!$#N{A=;0giP0vmT^?hJ*}>*qeXO8w>2C}DKF zn9ge*Hy}3Tn9bAS4A8HClHcUj;q1ET81(e$r7voYiz?X4E%at7tdJf3-fUIwSycoL zMP>wxl9Z(`-}m0fXPCq@nl8qyhZn_PPz%`hB0q%e(Iv%`MZ#|=#!}Ss-F1}I0dWjc*7`P_>e!M_GU z@QvQd(DODyQ35N2{%pKS@5iB6SMj&F@fJa_QfY9Di)g>62pErE#1-g0FIp7om=*HP zRj3|xV^UTPm+vL0j`|@^;@M*Mr>#6L^=$nzUZbMdcsaw4_2Mu6qO*?qI+C&oSg-Ex zh`yC}IkqdS)TIYeX35pfElUAWv-EXeD;JvWn4Yy0RMSh*Ms_&y<)I`DQfDXgf$;YRTt;=a`J8Zkpt&Yz!zn{)# zY4URT_VCEZeYE_WP|$01Rykk8#Te#1$JTzVC=V0)(V{$L?AGz7qc8)#A^(1KU9f~) zWvxE#Gs_Ep#^!%>!urgj8E5VA6U(U7B>~kXDP5-@qMhe~$mqGuA`QSe zd!vEBH5CbvMQvKP1*|+;R{Gj7-+^3`ym4Ki#zjGORHFcaoQ9NOOhIw zVSCGnT)S_xn5)}i@>o5jJ%*?9GHOcev@h$S{YnPN=$6Es9eZMq!-%R&t|eq6F;VMO zDN!c$AGz^=6DPHW({(S$1J`myzgNM!&GdI$;Yce}L&+Mxs_DXuG?xLsPUfG*$?#Wr z@{d=0h+@;7ceQJy^^XQ=@A-D_H&RlAQX@?vx!tI(yOm;T3;KBX^e<-l!j65q!+v8<4ZBJo6sr7y8P{YF%y}G0!GiE&~1-?8?;;!KbCUS*&wO@0n`ue_G3QC-} z^ZX*p7#-d4u9h7Iero*|v-W-P%AG>%)*xo@dGz%=loUmB?{}XzxlPheG#^hJ=}dS5 zU)|1wt^Q1Qd?X}8Q|66(f?9^P28as;kWxl8`g*{5_>nD&EHXuV6+za=s7VKo*SvA9 za`H<8$b4W$gx453x4lG%yev5=_nu{9+v|CZ?+VPK5#H|N18eYq?E#iw+k#WjKC%Lj zPVrTQ03*SdA1>qKCiwj-(tz6Ct6N8M@lnNu=mvEC&f$Qz{JC>PTZyPC;_#P6f}8*o zDOqNN+J;IFHr(z}{px^~6C z$NPWJ>$!Bf(Z^kkvZ4*|Wr{bjdpJaP3jkCkA%XGB{hb8@0GbL`+Vg|DJzzxKnN{@l zwn%Vwu@L4B5zOQ37S_3vzjyD4dvUp%OBvHco2@p8VypA)sfc9Sexx@^poyxhZS^8V zi{Wb8RcfPJfMSro0bUigN|;Q010e@weLJCcostXz8`Xvi#oHoWW-7cTdB6PVB?4MU zl@)A5VDEVw1n`v{Ya_7tyynL?2IhE$!{NJ@;W^wyR7y2|*!hSoL6@3Bt2?<>)vOUV zvuY=8Ox)1I)?p|^U6v4@dm7qBxh%8r0O!PaJ_)OERIDW6YSXDz{`v51t!xfVAmDjM z9^R{q_e(tZN&CP&u{#}n9vr?I95|zZ%*6{q{%6d7Rv9K(rgK>;4XAMqOJgI9ItItfdESKlG~GJKM;{y?5?m^@Q^Bx(YsTLtb!vCiiq5Bg~;I z4+Vk}E7f_Y!mEA?x5~z3%X>Y>7kcH>o5bsHdH*Gs#+xXQM_xaj&4I5bbsT|54h%3j zL*Q(uMAX$K%D;a8@cvgeo&OHnEWb!s^k=b`huu8c??ENobwk#z8m@Y)o#)pnX;}AP z`X`@TT5VS$@E(J zwPw$8E@qvM@^H+`ZsQ1OBu;axGv(&B-s<~!{Uag>?h62_%=)e{0>8PV<$WFZD|8gB z{c9zL(Bw?iq(}0wdM!yq>XVr66E>C+^foC_nGlwYx@Ym3yb)PC0_E6 z?eR_k!&UBWTSKV^NWh%#12SrK-x}{tph6s$d!r~B$9Vg0Ii2b^V{1-3(wZ;TxA;<= ziLxo+MrB`Re|2S1=8Jr2be)HM>in*efW-@rG>El(%6K=m#Agw|+WL&~Ylx>eR2-6H zol}&HeYGiuI=15EO+D(V%Y=0t@IK*6>{{}Sk|*{4b%=hNuu+;Z!__hXP@j@v_l5j*aEL^!${W?SQqUT!(dMnvCu*jZ z?o`k=h2N*%QLf2qcLI6B=9HBHtM-%G73=lW-N|-6tHGylt9IuzTv^=U7~7bL?)EBh zCG*stWF=&(c`2)R66XY~cQE!{t9PpfT36z-i^IrN2bb|%Yf)`SkRqxL^He7-E5Gf^ z5ZPJZC!j9gtd$XNWzs|8e0@`I&M^B|w=V!d%h%Dxm0NTE znlY?Fr^g|Bn7K6a4*ULh*i7OZv#dq!{FVfyvMg+;0ee-{BL1AsAH)B_A)uE*^Or$^ zhsHC5#Jj)XS-HDS;(wv-XV*oP6g}nd#jfW4hc@xpDYy!{Z-ZC^?H6+ynsuHV!hO@GHy8%t`Z4c zf7=R5r5ch_=wPt}kPdAhd4xOfcKKDQ^g=_5s+f!t>0mlEQ!()ODs67(_C*-O^Vz(( z*@WE--FvZ^&+#@FbGO<4^-8iUUxemMv_tWb-`>HJj*fjTDkm7uUxucG>&mMQXfgBK z=)G||;>>Z~>{1z83PulKs9AlDxbdzUTui(-%mYI%=5!%U&ax$cYu=b;fwmrIjP6jv zYm8+F56AUzU~T2paPnWn=gpfp{r(~S*YCn|`m6Wad*k)J!^V!#Y4rNg@8N>u7xS2X zZIoeGkH3MsYdj32@tA%9bm6NmbM$)SoGv-3->NLA#qBGX=n2-ebqG!v3Qe7dVb7D? zx9l+`0v!RZo}|E&yTs4sx~d(gRZx;+)`z?VVu3LCh)B46J1*kqxR_mHerZpvF!BCB zP)h>@6aWAK2mqM{yHH~b004gs000;O0047kbailaZ*OdKFK%INWpi+0V`XzL zaCx;>O>g5i5WV|X5MBf#8<#*^6a}_$&_mIphXRXYZ`pugEXrm>kpxL4@xSj3DN&N0 z-F6T4#Wwlo^UVxL_uhp>T-mc~zjaD%N!oi+;1?MQLVMeb!f@#qZ%^qS~wE6D&~l(8#eay$A|L#&W|?1tor z6uIJ^d@XF9)FXfwrsDQK=Q5De-ALe!#A zY8sZ#UqoLF7T*h^h>f+8dT$^nwBom8cgHhuoz5O9ci_?tILRpb4vP&i{8@#lofQ}b zxg+$49r=+h;eL_wzn!-9h6d*n1HIqeP-t})R`_Dy=tq#7Oi9}kAWS zx%YXQULH@N&%SHx{G*xt2+QIW%RgtW`SB!~vm$inUdz78e3IZBH>7o%4P zdM$DxRz2k(Abr1S+p54j_$u;Wuw9kiPq}Y(z^b91Jur3^cu!pT+K6*?@IN!+BmACj zF0^9-(5(Odf#uBhT!>a5fR?4+MhJ9Nh-L@Cr3&hEhr!V4{iwlDW7AK_(kk0B2s^Nb zGpkO8=@n67dsY9U2lIN>1x=sLfOqh^1-i(@Jp?I(vWbO<9l4=EkZCa+J!@8u$hOr9 zIzyT~Ica3%r! z8Q(AvRGZ&d;yQSqO)a1K;RE=Ri<&Cj`+|NPFn(U))oSU?s|O=nq~m%==e+{ckd@@( zi7-n_P`^NbC4J}>)I~doS>beDYD;H-*Uz~z=58H*+mW+Yz#_Kt!NFLxz*WQyq?1ew z-ZPrd3&!2uUC{vH0eCpZ6cAO;tea$}8alw$xHatXHXg#J%&-9n((zE9_*(`5Gv#zs7|Bmw6JD zhe3zK4rx}$W1hzB>$eOPh5CQm`~y%+0|XQR000O8nFYI0o(0&Azb*g(ot^*y8vp7!%8rul`P@r!1AT6(pyiC%pSPTY(y==8Et0t(owfb7>ZkI!z5|^(d&5 zxtJEoO31HQqN;Hm>fMynd6o-){8s$Dfdyw!&rkkx^6K>)iN?vF{v^j7y5!T8t@CNU zS>tzZf_UK4>lS&raGu1Xs>(_?c&>gw!Jp+a7ptV1Emf1IN{Tv98qrzB_4eowvvLJw zQf(KanI?HYU5X@yNqc%ccwqO~6r!Fb>n`x?r4YGl^;i63Z*MwXi6)ulNnKB;!6az5 z&~Xnb_2TW5KmBm><9qnA5-|<|G>)q9?_#l-M5p5?PU~BR zkCFg^Oa{<(u#X)d!?#E9<TzxsW$T7Q#f3sE;PL6})Go}YbraP$id2ajnefHd6u@b=a8 z9kBloCpNYrkmX*?R5|-{H2P(D9Lo8{!~lCIKfOQs@!iYUKfZ&WgSbhmc=0))e=j~C z(U&0poUP&8;`1P`*Ll`NLtG~00bHO{no0PErP<3O6`x>?koHSiPv>Pdg)NUi(e|ER z;FIZf212K9Lf$Z8R)DZrSHN1_kG2*(JcE(my?*xRllRm2FMl|J%?%?Seg(fat96bj zx9oKA#bB+e+L6=gFTtB_vn-1-OP+%->+N)v{G+UX8SHI9-b?}Qq5)V0GoGVtXd=~U z5`Ot5{_;zxe!mNXIaaW{hR}!!0C%8f;?qp5o8T`=z7e#gjowLC3unVe`YC<}KbB391i&yO00a#|^am)c zMnPEx29^O1cpTiR2Emj@gV1@9#uT3=_)G752^aM+U1*94~Z;K*&LhL$Lu9*+<2pIJ{ODj{_b^&^q%F>2UajWx=6 zy@hQuKK$AliKnN=8vo&V{P1iSDqsIvRP5=FlU4fl!&^-GVedE$;#Sk_y4u2 zAN8+-iIUu8UFMN&4GM*}wh~?u{3j7xBlZB2WeM-i82;c*itVUbJzEO04MfGj$;^O8 zfG0>gFd%;3h-wSAMU^a8EPe>|o-rwVjN<1_*@y@sNiiHAgu~PE;n`5}H;)!fV8(19 z0sadS7orKt@MO5~RGFONaS-eWKmGJm@VCwEa?c^^?Z!W9#}D_zAY-~7TfnS&;tvYK zKCJrTu)8R#xm*xOnIN6PN(4J0O`2pvB1B7^zhxp%aS2hzFc|{Vcnivle}MU22h9?g zW0ftIU@;4jKpUV?B84ML9xw7<)}W>+!f+gc9!Dj;Tdix z9B~cYCCG5P0dP2^of(ex&cR0QK>L7az70s1ZQ#*Gw%C-Lx?MY>j%z-gn!ZnrX7}wV zIy~Ej?)5Ui30=16Cv40|>bb>~1sEXIEY9jFI|``vBZo!QOwM-B&E{4$wTYgitqrOY z8GzV)!YG(O*^Q;8BHLN+UAs0fi&-U5SgxzAtg;3c3I#B%YaKg7>rJAZzTjSP*uvXQ zc}Ew6I-7Qt7aFLnMmjc`cOev%AggIna5s6^;FfZtWvmuILrh3aEk9hLZOe*1Chq%c zYi;8)z>q?L>re*~?yV7dC1A)lvsm`hq8QpDi?;raW#)B>4DCJEPIr%kTTgAzZcnM5 zJI>U7rzAfLW1=i~Md}feD#8%8p@yA;QJdGlMnWcmg05twMAa*-HA(FFipCK1Mp?&X zK`2U?&lLK5%mqB<8<=kwZ57keK4y2o*oU2%5A9RQkkovyCE=e$A*!SiL6T!s3x>QB zjts7Yat`#eITjIO_XGScag3~Yu24S5jmHEApRy6Fpk2vrxe4lJxq)??ful_j&d;sb zSL_gZcz%v6mZ3ERQvjKiz=DH!2fs8W=%b8{OHkq9^oif8sma~;FU^oaJQcG99BOE= z5-Pe0GXzvxy_M9640bw@D^mw#3rZLwUc|v5NsAg>0`l4q&z-$=LnMuX6PbNXV-his;DDYaXHdvzB0#;U}z|oSPAjYt(xI%+igQ`Rb zKRADsO5N(i-4|218 zWr|psd;E_wlMqjj*Js1dk87BdV~Vwcx&3O1=k}}9Q%UHK?SL9%KX`#LW)AoTNAVwm zw4BwXNH#?VtT+`om;egkK}d3efv-!kwKV1{Br7)$L{8DLns7t^8YOC3rJ{<1x9|uz z1nk0GH^glU$`wY4l^k(L4xhm1>C>mro;|03!KfaO9|uo@r@^z}d2c7^FnjVGm$g=r&e*=8S^PCOOl8GU*agKh$X%|YOZh#*bD zcrTg+?91tN6ewysHk2AZk}!wXQ|34Mh+~_1-H(hK!ye)irUp~-kATyp?SgXwT)J+k z#_)33d1m9cXR^^1Mqld)kIPysf&Tq#m8?;%<3Soq0N#tpHc2~$px%IZqzD8`F<`At z-mtRf1_X*+KjJ6Cq*hD`jaJgZ&>_V#ETMH!?=WPm?T=0_ZjyQI!TJHsrGtEI_S|0jgiSfg+7Q9;3DR1H!%W95*gXT7YQ1Y*u+HW@RcOJD8;S3P%Lc zI9@b()GQx=k9Oo6Tn4cI@Q3FTWs1-lD1eDaj_*Pcl7yg10et?uNiaUNu~y+Unq4i> z1faDUVTXSe}Ff*H4A(E+>-dxZ=! zwkPMwOb{KZ8M378XUhuO6GEgQ$n!banV{D%4RWfX@$&+jq4j}H(ELZG&+devp@*il% zf)qs~Li8boYF)JsFh~$!+f{6-bge79aseyMB zPcp~%090~DWHX9Bl4vLwqkB$G(8B23H;)iA@|+*n%jEE%@V}#@hxpHfKhi%(Uww`L ze06yA&sF->a1uKG#izBH!5ki+CgV9CCaV+dVN2!dG%K=ZI+b+RL*hXr_cjQPZDQR7 zaM$0vP2^MDV1>AjbjzXLRE>gBdihnVMj|AbtjjWO`5%L#7{H(9pyS#D9$F2cGYHtt z3{L|h=|FC2BMzO-N^s;aX8dPM8S%nUn|JXB#6k!A!==mC$`&}VM`X~^(+Cu^jchyBCGkN z#!z^*CBF4$bIfg=Cjmv?21BN4*7fnh!Fs#S;<8#C)EP`r9Dqh$mUUB4qVR4wa-6eS zGQHRoX)a{Y42;5TzMa-}K0&z(7GY}`vJhy=XiPeG1cK4a*|{2FSb_HYyBBGc&)8fCW1riv3v{$sHz4bGirABHP9;GB#pcS?2U^a~Of>PYq z=thRIei{wU3=j1U1cpS;b?sm-zN^pjFy8_5u)UX0GZ6}#KqfX$*7g)=cg{Qdj)Zz#pkv%B|$6HY>2CKy#O!AU~Pw*e_z z*Bf9J(34ql*zG9WVb&Hk86SpLo37}xds!}WH>&~{gIG3Pg{=;J*rL2Joo)J^)s%x#ASZB|R5s1(ljP;Jf-q+hl^&#obd!hvC zUc3CS4wWgPwT|Y6Ptf8$hltW&Ng_#Y0&RD0Q5Zo%&uTycfoomQ6L6{1pf9F6!G_KG z4BQ!r55&X@*##P-7DDjY*0Y`bYF-T@k6JLr5J3({B=rm}skFO4f1t3~#iQ3d`nZR9 zJ5;IW2dNDW%Wa-CN#5ZCMAxx=S}d6c$b@VO>&>CWHDx(so6ww^>W5ZvYtctLeDuS! zq1Q>av=hCeF79N6YHv zs`wkbgRo7rydK6Mi-D~rk%SJSzEp6;)X}j$<~Z#ZXl~kDxO`}|PB96Rqv*Vh9Bi06 zybJ7%i^vB@k+qBLE-fw!Zik$byFoWs+wMN1Jx3?HRo!_=eSEvj)pXR*NzWT2I-$=k zB3{>*sYt+T&bNp(YNs{qBc!CGIY~3y3ucGLl5f9r<01MqRdS8MMD1#RUICC;#TX5{ zEuFB`&dx1_Hvi>{vGea9IH*B%*j`c(50&`=DvhHK4iq<4sb(O_%SDlW7U?&^dQv31}sj)KPSaZ{31LV1a~ z8c5hgUsfbH$Lx(u4={IF7+r0q(kQgP@H&US^z#u7c8bjAj&f#XrFY;ByFW>um5C6b zFOE31bzeINoV;*&=J#FqnLIXW@HSwPHNe@NBtzjn#|zL@xJ0#~FA~aJiTh_=RPn>t zAk4dlk;2d4p&QeRVgCRlB;f8vFu2l{qu|Rg!&9WI*Y{K(srih%jR*vKo4){RUbor3 zjKc&}c3z?ap=4U>V-kt{SpEtPextQ*-LTU1!R_#y&h6|O?zoPnR~jsUcHTg>ky=iP z1No7ns5f}xjc4FI{k7->LDAC{Asq_;(aM7zIbeQI{Wf*@P0A!9XS`*TAe8I^A64VoZTdv~bbF zFxjncbz7G(TEDr+Lqr#_k{yE@69Mpk&YfCjV1SeWmLMlF0tt>xf+w;n^9~33rWGxY zkxdbJ*kJO;V;Xbx%rNw9OAYa1jKL_D=OTBVTpGH8WgTbe%%hzVNK7uMJRswCz~G+Q33R_!lJJD|yEo8kD?1G6nNTjpwqy9bK$2V}n0HW;Zq?ia=o;Glw6$cGHX&x+$g2dNrKKv{Bo#GoR5iaHt75Zcd4WlaU0%d< zQZQQcTvTTErv``lo~WMPfV#!u7Kuy>DOUvhoI12P>ui73+GyAn2gc2d-slVn$Fvl6 zd&JLy8f)6@bvRJ#4dw}&=hq_wJd7p%{FF23Oj$5fJTRBEmT55~<61*AU-u;2s2m!~ zb+%IwcD0Y?0e=rc>~rnGUt|gq24jFy1f$-pXu*I^peFTg6nCSl@pOKIYhupVoscko zzvcyRH%po#o9-q6SMmfTpAMYgK-j|!Nkh5etCTf!d3_0Xgsa+~s zr|A0Q_> zPeIFLj|U4)`_E?O(1}}G2p7U$EuS3^OHkmwi3Cqh$iQyTuVA9rH<+&-3)gQa1BQ5E zaZ5*ME5~Z+*dnSEyk4NB6TFZlGNSgLbQR1JLp1wx>37Eu@_1Lz6LZN zBj=7eOy`{Wn;7gmJ604KSv`i10%_Af6#r2Q8PGYvD-iy5Sgk~w0eSMRVN!QB_AY}< zPNb`h5QS?I0{7GH0oaAPNMJ)EcFb+ooH37XBxBy%{v2V>oHR(<DdR3#RX zzJ%mx9-Wea(K3}+`IIrR%IbP8K;@*p$nF*xjDn~PszERq6B2WC##IrbnKdd|JhN9JV%DS=Rk zx5k_7gJ%B)8vWK? zhRt-{2ydM-*I88QB5hpDI&F)rH5>(@5*sS5#7q_Mbnduvj{C}BN2noYf=nsS9T>@r z>GCfNObX^mUaqI*rD{w2maQh&`-ctontWcerwxf#Z?c9i@1cn>-{i0`IWEw-f#12I zYt5g76)u_7x%NGNTZpTjY{|qzpc$Cp(xZpLv8nTx0_VXz$D31VL^UIMrLYz1h60kF z6q~{FbRl9tXQ8fG?IwDiEbajZPm4i)=tmggEt`j3ICAJA7 zL|vg< z@OTv0UW$93a8dSX!0sH+&ym-74q8uG`kjzu&TwqKQ*bEIvMn0hPFCy{+g`D4+qP}n zwr$(CZQFS{_v6&t``(ZK?^!*ot487|0^Gx$M^P}`bwfnxu%`3ukCX%0eT{{M z*3bUMRV-vYI0u}{!6x_RBC_H;=ijyJgDSVnks`;|qxBVAn@M4!kY~-zNVVXUGB1*k znS*M3jz&2ByX(CvzA`u68Ng9Iv(W7&`F^rrm0pS#b zLardL;?c5r%X^880#gFVmR$S;H*!i|&;scVc7uQrH?YeJ17PNyP-epBzEYup_w$BB z(4U&E@56P?^Vlrdz)s1MFEJpDQ1V)$7iiZtbH)(d0TNRwh={7O|8*&5cw0q5cvQk2 zDrGck+Gldq@~A;?F3^6kI2z_xxg`^b z6K{BHP!@oDpNQq@#Ot^RDawD5P|^{y!Cx-&WY&o zR7Lg@kGigq$mA*2fameE2s zlikVd_6@tul+YY7!bnHO5}BM2NP*O7sGV3f6IRmJi))rE4sGnVY-uF=Z@D{vG985y zo}gj(37lwD55ppO?(a-M6o#KeOoHv+Xu?}z6t1l8u+8x(_1uZ{RxMXSbUhu*>~z0( zGO2A==Q4(Xv)PtzT2BqI7mm+rtHOuHc~UvHlNvje^Hv!(>*^w){D#1s2HtdO*a-^F zkq4|OfzqN}0OvrLr~9&)#Syl1V-j3U8&k|5Q4p{>R12xYNF@KS6SL;HI=oNcHw*?; z$=hgke|TrVJv&a}B6CPx(_9BT5m<3NdZHw0*vJ%Ns-`0lc*Z{f@|%1`Aze6Y5hu zig%j`z*s8;Mw$z1S}E8Vja}9C!wN*myaC-R+`F`R5!ZG^PWw|LMG`lPL|WM>JqEv~ ztne-8V`o|CmaE_gzoUzAy#2d{4-;ph#b*;6K*fiGQem;y{RBCO$Hl+nRXnViEfkTY z=u@H)Ghaul)^5q)k=3V|8EiYv@`cFQCfxKhAlXoEGwXHo+UbiDc?-;8BYer^7**=pbAadEy93o29(lX{*D&SxytL#jW+zJ3| z%p>Vi__?}!vv9K|xRVF`+!ggs1?NoqVfw6Bkx$Y*MfV8I#R@Y1ytv;dadH6se^{l= zwn*jmr^Qb63eMZ?Am+O0JMc~^tHmFi?IN0>5K478)P^WRjP#c+!<_QsrrFv3E;WO$ z1ox-@q+aOQfj&4_*x33u$DXO%P%G%OL1HXuj4RHfQ@HK**ZRb{(9KQjFrHnVG*%CR zU7+r?;4QA}Fe~pg$ED#6htTAKoxjuA_U5a>*>Z{tdICDP*G-Z>a+%WSvf)cO4W_pVH0~BnD%k(rW!f?g$Hejl6+w`oZzwoe9KEIO&CPXeY zk9utlak`#c&tJDBH!)c*qiWzu1jcH7g(Lr2JLGA+{?&*d(hYCBJHN`|C^5MpGLbHJ zNl&_uF)ZG^Z%KO(I=r|71G#;M<6axdScRw6QXq}CWvuJI+&@;(vs8$y|9o<%#)^wE z`LSyq5}Kb{ zm#h8Ab@m?ZK&>|=LZe@s#+nng9CZ(LtxCi>Frwt#@<}P0jbme|S6Yu;trl1%%P>L` zQ-PmejUnHszuqt*yOq;|TDmerVtd2I_-`5-<3D_-;q@!emh9XH7OAxs7OSM8dmfxE77Fg&9j8Oy&9-sI%DYV1VNF=6_JWSjg?j zl1SSROs+g;ZId;rKzb4Zbm0qXz&eVZKq(ZSAI^*ZD;Esc;B6eg#n;tp++3C$IR`b^ z3A)#hq4h$Q5MkbZJA0vs_RkSfRIS#*@AwG4U?o85Hsi0e08R@44jShl9l}p1>CPN5 zSjA|S#U)|2oRB+J!A{3>JBET z%M-X;jmdv6Rl){2pcmNv2T}PRa{cY3R)ma7k$CGP;W)?%WeqX7xFJEa6Igm`l?N5o zYB}Hpn`+UC^8{DhYNkNPYd3|UVN?FfAe;=lR)TzYI(q`QrLN*`>F5xFPCSq5!9V>_dD0gK+(bzcU@ zROeCwH^4qOR)tfJ*-A-RTi!(i%`SAtu>m#kP_RXEEPue{ zzCa8ElT(IHv8$cDRwP~7+h_bqCF>GdClj&U>w!>FP`PCq&}xqq+FsGKz^3*2Q~NqG zWTWk|_4G46@1r`wc>q!$4#v1inO$1O}6L|IqL*wq7u#H%65ZAM7Q ztU(TlXu4i0zG7wZ>Z&EiqBF7uB?qZQYC~XKR`9&&s%F47MkL)I&PCfC<(p?crWg4A zq+}t+j3JvBvxlvN_4DLxFcza1~sGt}o+Co%JT$A>!>d@GD-piQ$ zi-mL=IkdLO9kEz0w%kldxqN;!dja|Rujy!|l!&UK3Q#vc*)JR6?qGzJ?VUQ>Ks{f! zivd3xUQr32TQr+xP29IL`miTqpoX|etdt`va>eI~`ON1DO)Q#AiCQk# zp2{O{qVX@jv^pbe1?SXZkF$l%9U}>^XU$tZmPZVV3!$E58D%Z@xhgHn1y_NQUsFCw z!2!o-&cLh8I%`!EZNjmE^%q(%_yPDGa6vCfK;bpSoNGu#R!2GtU^dIBt#suJT=ub= zYtXn}+rw_yeVBk*OvsrG?{UMD%0xtu_pAGJ33`qR{CvgQ`H!SP_7~+Z=OM4p#rY|N zs_YV?3xKIF-3SF02sO~f7z(3WF2xvusFP2!G`FED7BJ>k8^PT38h3l;%4C9qqm#F= z$$!GPITolct|5iL^F0D1)4F67*nY&r9`^U3@HG9;xj2ywv!UYT`3 znV}AEByG1hc}5e$rk^4`nG^7OV2H^dQbVN^jXu+ZH!09=kgXi)a*6?jC^=hg2~;2> zY)usGcuSoNrLaUDoAdfg^*rDvw%m_;ieXbpUmJO)@Upc^hrQ0znTK)`P-_%&S8GL; zre5X*ovhj#0mFPf)d4@aE`baU8Uk7Hnn#_RrsMA#casLfiQZsaquIlU)Tx<4+K zIvovO5BF+nlMO;l1wNq!6|YwIQ@lNSJyQJENVO%zbCeux|K@IY!0EgBO48jn#NI}p znoM9xJhj5DaI(&`LL>8D2s}pwBRB>+I`=RiB7vHreO`h%%ykter#BCZo;jvD{>nqq z2mMHiRoY7r?`~~yCV8-`k&YAp<%zcoa#E_+yRl++`pW_6VYxoNK;lR(YP^yek+)&g zxFeHApw{U?kefEylH$ZnoLY*!laSIfcb9c1Rwwq92bFhWZGxjEbkj6Hq*a`{6NFIA z=+5r&15$aQQISHE!tHR)rx)?u|5jzkvMt2SP#9H$l?Cw?>Kx!w`>6jLz|?9)W{TT!zH;^&wO2a-z@he(@Ir8EP$3Ih6Nn| zLkPxVxe*Bwe9R25GV(~O{DNPc(ZBe7dt^5LQm*v6U(cOIb42{t&U?Pl11k((J>&EV zOX5{@$P;DMnaH~d!kmf06oE>|r|)Q~JZMnb-2tPE3@YYky>tr$e_%6#;+b6uMv0$S zt2}x}Tvz8OcG7?4#y_VtyR8)oQro9%b$p-X1Lc571)D6!2;uFTHKzHrno7Yx5KscCeu+&A?HviNsGuP=%S#-PI zb+e@qk9eeY&Sy+nr1|t>V8FT1>@wqR+>!p+0xEj%i?mbC^vMzwe53SyOZpCP&C2=+ z3aLv8;p)Z^EE6}uSZ1bs!1xw@w2ARez`X-7jIltf5`_%!y@+r|`JE5>CyX*vURVWV z;6{M5UkHq6tAD_H@X(VnhG4c)54QC<6)HAY!$ry1G!gm^GpCFVAw{@lsW`giRCe-l z>%zo`$BozP=RPE11#cUks3QOhWU4`C!M&PsC%S4ByQg%*XH4(AY{)|k|lgnVTRzFNxzmreW&7Wvg~ zqU#V%@EfVjy2o@z@+TSUA%5ctqT|S_TUSI$$@x`hc9h&kemaBjSqq|glq*?x>esRE!&$8 zSj?MFIR>6X8d|pv8>>PFr^)ND2uHSuQB16E3|`*78&yMiHvnEQ#AnFK^=bjIb=0HV zXV7iX@gq8yfGu!_a(rxPU_WMX>ZwDHyT4tUbJi3kbLJKol(MQu*tVIo1imjOmKJS+U|ZO@$) z0~;$_J;&e6ohU^;n*}c zGizeah8G}T`mAj)*IQd1k-|g_N-N-n0io##^?QFU+oV*p$uLd+R7}cjgy*fHHw4U!X9rNiQ`X&QI8Ly-ML8~o^wc(LXRtEV(2I6iyMeDOt)AmDfC6@fEg&OJXlG^aN#DipP%9R&ju)^h$L^?Wl`4Ly7#cdd zocwuf&HPFAdRn=7YdLa!h6=Nw<@p*g%2(!nTOa zEb=Zx4`9Prt`o@>-KHYBx)hiZmo}zC;$}0unmm(Kw|b8g0)RZv!vv+Ts)U9cIEB!& zorl@WWU=HnE0bkrVe1VWnU3^A3uB7FEzD&|cp|l_a1R$Q`V*X74znW^@M1>96+EkG zMsdDMV&^TCW=ey=pmgn8ym{9|B4WrF`faazA_1=M$u2WZliYAN<>|(mxLi}oK40~CTX&Hy(;0FuyDY@%2A&VmR&*QmQQ*|Unrb>8cTRgV+%yn1mgovF@v$tu{}GFF zn1*nId<3MtxPRAj($Ts_8&Z0tg!oQgSimUU2`y*e%x^d5G&`7hSpjk#+Z=cLWfAxe z@}HFh*IUh3`|U*x|F2%e$oRjNb5gXj*q}rBuGX=0#JhA%Gs|GEt%qU2TJBplF`uV?x3CTp|HOgRszz0UTyW`C2eZyp9MEi|crLzxbHI+n#Ms)d<1ol&*D zpag5w&YX~?44xrb2hd3{+t0LvCFRfqaS?n3JND6F`&%X4h`rkEoiZdKoayX^TjLkEaU{H&&BNiXHEk z{L#R~L|?57Q#})hXji}1UMUyuxy9%Laku=>8_g8QlTmuYYDOGB+^8{As3pGxy8pzP zy=g29oOw&vU6>waR5wcVAGDIxeHPsCh;#Qynl2%UoJc8lo89BR=MAs)k9_E|Sq>_p z-tcOz6o{9L+QKkQlpC>@>RmAkP)3lDJDf7@)p-X-avqekO}SM!op7u1&J|LlAHe_o zj?v1qg1*0}U{AmCe>W1Q|NV|eky22=1TaA_>_W*|QQ+i`b3*9cL2L$KKpf(cv)kQD ze_@`fkz9H4MluECKA<~+N;_+Ob?#8o%CUX5{}>IKxZn|r33GPH?>0t{t?)UgpjeGH z?pYD0wcY*OQ3_fqcg*)#{|QZTPL5-RG)n@`un@4%F68BO?y`bIH}ix4&#WUA(hX+d z0RRSB0RT{cGyng2d^zY@8|vHqk3ZDZ9}Ale;rkBnp=>SeGR3_kKf(|I8gt@n0=@^| z1I=n%Sbd>tDq)ne>-c&nsh^LjNuE{-`Q(LTTQYn!q3P-Ak0!~w?ZtY%rgW5d@vBWE zqU8)BIjE10ZHTc9_4S>I=JE7)nl1l)M21#^t@X-kEW3@wq0Q|zl(q7KD0my<9Z6DX zwVE^}sSW}~NG^nW{p8MlXLv!Nn0Tiy)bal5jeN^+@u^iT#0@W%l`@oaYa>#{`ZaE^ z%%uxh8vtFuO|p!5)(G`#yQe;@{dwioS{6j%O+x-p~`{-vE@3ZkYl zdns6GGbf%&f9V`QdAgd5#Ob0c1aOGuyvc6+G?5FCjA-xosIQWj-=4Fy2W@qz(=BU7 z#k5B`z)KvC)Jl2EOv&x6pWgidVP}S7OTixvk!vAlw$TYp%is3>*SF#>@>wd0mK%!vfbYla#6rhHc=+Sa)}EN>~U6Z%Tb zS{w?HGE+lE3lW~F=(KP!3>;hpArg~$v~Qvk%CK^Jww+(v>+bv!Yufuk4`kgQDRMgU zk^D_tGE~{kOO0SyNM#?VA4uGHA30fLl2dbGPT~v?=+o>t$J7_m8N2@4ImAdxu_S)W z0a2LiWUGXlyMf*o&#VL4Te^?%M_=?}X)MSRG&P*Ik%#{M%y$qur+W*RFDzMrp(UPKBKoZsw0*YkxWBN!GeXJnE}-8wxe647U5ZPb z%%<-!eM>mkzrk!Ilq6{Mug$A8Ab}KgS;7J#g03Y?I)flU;ZZ1&UJaeLG1Y<6;R2(> zD;;Bj9NJQ=CSRpI^B6g`AIGgh>AWctu@vIJ1vOXrH3w)ZG)K;0@)%50A9yoa0N)D# zMbK2hq5@sBo>V$I7WiKY_{-Qd+3f=;Yveb(U_GqwTp96wqjk)bfk)g(>1WBXu34Tw zZHtmwFb9Q1k~R9$s)i=aSQ=<;v>!01IDx)6v0G_hvOS9BrzBPK-+bi|QBL_p!%AhaVdx58q{Jh*bihv)cUy&(Zq>%!iCoWluZjNT;oLZCWt%OUbU|jD5q8T|ejyn~fS6Jp z5T#>Ox|&cp=EzgSL5E2K(27~Mxq<=%0pyeE>5FmfoyWniP1McU;(5g-8fz zUMDLc&7?EuQ`3de=oBxTgY~TvC3j4&=T`?x_Xh}zjgfq8 zrL|Bk*f(l>%4g^Gv^8Ei23iTwH3GfWuqbgCwj(W_ ze?rOvN0p%FL0KcK{9b?_Uv_+UfU&KG|60S_=6-nex{NMJt!bktsXY)i7Qd*1IO`~? zDs382vd*-ETUK5F8-Y&8d7Nugj$mbS>IWmQvucmrkA9!=Yvkbs;<1jg!Ly)F9gt~Ej)ZBvHDn8Vh+{Fs=xc-I^dHgp~T?POk1o*vPBI&^6s ziQrNG{9<_UKbGSFv6!*C*+Bo!1HLat9fpFjN(sY4RMtj@xB+QPe94n+nJB#+PR*=o@jL&6C zQ5R#98`~M~oIO9G2Z)oLq?fbDh*L==aooYV@y;5f#Y4_G)MN1Q<4z}kG0CuErggND zttER_xXz#9>cbVS`EC*oG@vv@4hku&JgP09Wb3!pik#Dy$Ti%-%HHh8>g8xxzmEQ6EaNb6_Ph;ELTHm2Gzu z)xeymM-NF5ne;^5j>dT7DWuJ~>7D0F7?ACW-NZriNz zx>K0g$Ks^oGNeC_SBJju|Fi!OW?8_9#h?vH#m83;s2jJ^x;VggU&04Nm7yC*V5=VSMr}Sv`RqWxbMIsMD6Wu^n9H0p!aQilyro!z_SXb>xq?$I=<|%R z*wtOEi)nq#+b9q#0L57=oM3hG?i5e(N%54%uZ&if%=)=RF$}`poT^-E17keo^=5Go z;??^LHfwbm{-Y3c@4>WqPZH3g%WVhAGg{)-gQGEHI;-wt<+uQA6x~%!gxJ+D;t5vN z={>(YkMjc6&(ZXe4+gI(sY$Sn#Wk0Yh2 zu@k!U7_*s>W7iWjV8>+QfHY=~dg=X(L+;$iayh&09pk+DOmy z!GX#Z$&1?vz7gXb>s`C;gX4UwMs?Nu&)|S-O+4IsF9Ga%mvB-M-j)XKyJK?W{Zit7 z*v0~|tkN!mwhR)d3FJjQ`Yg1-0BjanT@?EeP2pTCOJ7D&E~C0VOyJ!7-2|G4Dda6K zVmGfD(j%w5BZEuIg>zxv=cou|1lF2D1@&PH8xDegB8T|cR>nn=kF^VhJD3L^MT2lC zzhHRM5Y&n0y1?AZ(_3+wQ9Jc;DBQ-i-laptS__qXXhHp`>^U;~2O*Ud&X&^Y9`V=% zfTJ%t`bIgm#D}(;`*RJt$qkKmm)8UCpEh+8FkR=P9zHYyt+s2&*`}9uB^zlH+vGUr zYy>mw5ywx1@~nBT%e?K?XI_5#>Otut?Z0-lnyn3zr?;DG zG?6GEq+}QJAJBju+*VABY4&s zA#DSO(p*N}_tnO7lNxK-9RCfMCtpNT?iEMI>PXL2>FO-{+T%bg^dEs&MOw_Unb`s9bi056H6M_QG}Y&HI4XHz2s%<^Hfe zKQC;w)t6o%`I{3m8#Gj_53*v&5Mtt#{y8%eb@0SSb|wDv&RNofcY6cQ2qeJ9c&j?p z<%v|@io6?Fw#r!!$10ni(M8F@J?D5O(fYlP4d2RKca7hYtgydJSJEDfg=gc|VNqMa zCs=XUJ{lGOSw6>&gA2dO>@yEz2HvH@hiSJzSGaXmIZ!xi5Mi*I&xdjv$_6>Gsnz@4 zxDaFUh1k}Gg?$(^IuhET5KyoKGt=Aa0YyL|AO704BJf!3?k7_j;WS`N-pRTHCbvQ< za+xGX>(P?ZkFA8o7ZXq?TdA{*cX^3)4FQTt9$qf7x%q|XPpn}t`M2BB*vlMT8&t?^ zbMFsY*-w=^PQHW+ocePI(pd}$N=&C6Z98XoWHZGNJaap{m2JN7R>^5%pH%Mg_dYwF zLDSukznk)&5u%rR6FEC!uHk*D_w(i2mm!eS!GOG_P+0jqI4^fHB>e~FhwJzGKGoM< z$%0QOo;s-116&biSKl1OPzX{q!PRX0*dW<`;fD{8u8&&=Bo5x?516=l+VrXs-QzCf zv#GfM-Y!hmD<>(JcS2}su)F*tk=vxl=;HHbN4D1|uBTx~nbq~pLuF7)HY%s;wFx3DNZT$^ zmk@0x&&7!{jkH5zXO(L=L(Eh)m2%Po$wc!?dvDBMZ5~iIn$OdC=4DkAA~f5j6i8uBgrV9|=9}8R)F=>Jx`~^05`lP;VT? zBjzr=OxCFpWV~dExCDf=R=+f)!HqcJ5g7j9Pn*#?DIo_CX7d!16r$+4SpVKYz!}&# zWZ5PsnJ$DVh{@_{ue;}n??ijm?N;*jP|a@DiMHl3Bt$ZspS1w4!skkRcJxdU@ zc8s*%>^st74C`G0xU(`#*5`kjL@yxWRTTUp|MlO%{;vsufxVfnBR;vIk@H^~M=M)P z?#Vu=emWSi-H&WS{CO}IJl$QrQ@8+v{oviQ#Pqg&4U3Jk7@MG}Oo4COAE@#CHp8Vn zvxxTT=OcCt=aTc)S^=7jD%9e}v4n4{8b< z(vnfe%}G4ZJ`AT4JSJAnGm=UeFH5(J*?>Bxdm(&Lc&%(c?DyFHaTpfT&WNV_ar&U3 z;$Clm0#cp-9B-5|Hg=o;J}Ue-(EeYK`#;Z8P_}h~iC%nqgod+wyqkk{hP#J>sFRmn zBBv3RTBe!@WQdPofEM3>KypxEj%eLKh>(YtV2qHDI5Egpy%1~UIXARzleI;1!L7oZ*_ltxVw(|2&sv2sV(S2 zdWxtQPMJA$fzj2Z$J9O#!zqjlX2vG4 zQCMbIx{$Ws{MHSgG0PG?;jD!;_DbCShIU^B$o)WeQq+n_b=%cKOSv3%FuNwU?! z6UAtQQiP)}gQW#7LZ%&iMQ}}d&T6mpNfu2n&iGJ}x^g+Zu#*3;r}UTE z;jSu$Y!fdjIwn7>DE99_zdEKP4$`R5lF0|5*31;CEbtxH0sWxP z#*ea(tJQ6wczA^(%G_P4GQY(kbm>bn%Z1_N|LPUfNlejd&;S6`1ONb-|J5rTEOi{5 zY;A4q|7W?`q;BP~!GiR=Q1GiGBbraj<2V~CE52SjV3RVocb>LipDbdB6BIzw57z~p zjlW*mp#g};Cn33Vl1>mK)~!>$sbeN)`1tfeF2nj;LP$D0ET?PJ*lC zUN4Tk+NfyW`3eW-FbT1~Rav|ov27b;Xx>o)8;#AVcJE(dNV8;nYer`Zsr!4aU(lDD;i$_Vh|zog5xWj>&C(4t?Q zx*lz_N40Ra;coTsS!lZ?Xqo#v%CHqHk*`TEKT^MZLNk>d&Jr^nfaw@P5cQ{Pe|^@r znWQIPsE?XKSIC!nJ)>&Q&P?}1&BzrXcDuX7^XQV%6Awnj>REt!iOsY@$6MyqhH0%nd1YWGD!fuY^8ut42 zjKgVIhy{FDXwG+VQ^fK^my|g;nnT6L_xV^ajif{I)3o6u^aSM#vo$EWpW`gurS-|0 zk*9Qg#EyAd^fG=^C*`oXKB>v~D)&R^a&`KWO}Vgydp*qt_`>`$F zt4%s8v?GU6%cx`{CMP>Rug(Ii1t^&K`3Sjx2~Tu+p2+2;jWrOgwaprD#3{B9^ph*` zF>ubkL?J^`DVtUGQV9>^PsO?KsqX{X!0UugNoL$F#nU1jC051zSrAg@F6^VJFbMgP zyAmyGQ|KV-F+mD&frrwPgQ7IgHk{gN7;Op+sh03syyXB(y+Rky+wsuh&)OO@@g z%e5c6zpW9~E%-J@`}66&=2A0tqm-$H0~bI^E}q^GXD;DTHPRXq|2h6#fj}D#0)y;D zdZIqo5ERg6I;@Z#gsKm`F%jH1!SY?Ikj-W(zP zTfSxGD9kA$Cp<*y$n)uw^L?F~VQq0)QAt_2U=x*QfdZs=QWA(dZml9}2NezkY^Wk` z4+^*tn|*_2=kG^G>eFM)76(Bi2S`OM{_3V<+F-dLV3o9z5kcSNOH~@h4?h^5E`3UH zKR_1cJC%{q$?U3qvbfT`S}Vuy13XThzy>yFA(Z7!V7-|Q-lbiaF-Qy+2Z!PzGiVj7 zc+9GY*Bm~^CC`Fp2-$B3B1zZ)>cmVn;{%4W{3A53*EIVhb(NHLaDrQuR^tzJWk51v^Sw6@s842ZDkomZjT@ZVOvq^-Ui~Q?{;0yT)HO&Gtx9Uwln1>j)6(LnbtQ4hg(%LRS z&mzWED}+#X;!w7-rVaK;DGq1vE8rsaW!vA0hL)=vzg^nugdg{U#PE!q^z@*TK|&)` ztsA?bMb%DCPx*wj2qSA_nZs|=CZ5>d$kbsCO&8O|l+iD)`FlGyP<|e60{>(ESBc?+ zy(ewI2Ylld#M)(|u;7B6$)rMUxUz-6!sEU+`_VDDg(EKGdi-+Kpu=F`KK7V8<(qm= zZ>j`#PDi;Lxr_Fxu;NIWyxpZu>p{eFMRZSQcM>%fhXSKh*C9v}s;gp8%wxUU>QW!; z6xSw$Z!eZ4cTh#UKd-|;+H(#F5QH{yf0p=Z#bAHe(4Z#)@E<-AqU(b4KMrRy?iliGNgRz)nc)MqrrAZU-Bk}_ zzZR^Mlam>;!z`SyyM4??858ABJlgDe2lwp*kT0pa-9ovBtJKyT$tv+nBM29*Oqow* za*(o9msrN=0T$NyiO3{V7P-P%Svw8Ub)Ha*ji5GehF20zlSN))>(H|8;xp?ooQ>vm zejQkmo5}#=Dt+mT(q+B~=S%21w;AyceOds==o%2XP5@`+BQSo;*Wt&G^+n6gAcid& zydq0D>T#i!lKlW#KySw?)ikzO;n$f_jk38}A=`A?mdF>0UXD+GDNd?5JP3g!59kcM z+@tU7n-Dwb5vZUwF(qk^56#~j37uX4ii?hq!|V5)o1IOqp2oPbZl*`3S-qv~JO}XT z99$->vv#TZ(94z3j^XVthiwnt@|2{p!}d_m*Ys|0crv%Qi!DHhIi{5Km(LY6z*rJG z(dHR(IfvT_d}Th(A4~z10d(YycKv+~TaN{Uk5Q6lQG`0>Xh7g(D3@p{~Xs)t1$Ut!Nj#WW5{oY@ z7gu`k%>e{&3G*S}xnDBD)?X;lASF$v&US3v?9Ps^u9t;vZ0aO0I*0Dyyfw+a zEJ)+htgClaGz8LbbCSB2(rmHInC+ZR;BR$@um_;t6yRGtixY~{9hWoPS$1yHikwzPL5`l|05Kh70++8K?f6b^NuR$E(+Aj zgAVL&;h)tBs4?TGyAVbf!bEH?^?V_+W`9}C4YSY(Mtr}p;Nf_Z-Ni?&;t&vpYO&dh zTHTkr{D280ei_sTO`;9L-KV%uGn@+k+WrH$(}95x1~aQW<&InHx03TQLbjmGX=Ck9 zS#pIA+^z{t!v>{ah6^7)NF`LmKH4;*nUbu6=>8yJDt0;3?BHYDQ2k7M0R;9qOYqIn zQf%dl>uoeYXZkPk`Od7XtL9DQlNzfm5j%ai&+#4bKnl&2Y32nH$7(=|mW(jUv+Fi2p-n~+Y5v!4t zqyNu`&ff6%j<4{YSph7#QH9XE?|o?e4xwvy^`@mCx8X`~_PYGRq8CoV2@JV4D3KB; z((+ustMVPqE2o;m>pIWKD^D@{Cvhb|Mgm)Ss>7TG9Qz}_c8)x;oC4E?Sk{*lF$~(e zXcHUhhTlo4tfm+CTBW<8%z@K_7pwYX*fC6L>g*@ze->4=PEz0K7hJ{u#((imoQ>=q z%xtWG%V`xU0p&{vBlt^^aaoE2N6>VS_QfhJl@gQZZD|Sp)3?Tju`RiZ6w%f=NnV&~ zL<~yTrfy3T${7Y09a{aNJ|!8fAe%sENGX1lL`7zxy|gmL3Bn;Fe*6wz^ve0nP7@b% zx(D{3dDRXH`NBg10D%93Kji-ee=ep*MwY)>6=7O9Yz*IV`V7Hp!TW-=+pW`Lu0)ov zHy(&pnqo(BTW$5@+v3jv0UloChmAk>xVXTFu$plmMH=0<-n`%@PaJ(@A+#B{SC`9U zc5Bk0M@S}lB#T>_6FE%X(I$9&W?2P=m2xLTW8jAX0au6<1SP#hU>f9+vAD2{}?GCL8JP zad6RG^LP5I*x4i77}Xt-Za0^{=MsH>yH)y;#J7?|rwz7wBFG`$4AFbeZtrP+9nd0| z7H-}g5FY7wL>a~(cQlgD+@0g!sAjezoKC=7e+WWf{Mv@8|#H z?sVsg)0dM&qg_?7l2TK{k2>?fLlw!vMKVcVUmQlb^9RHa{Z`ReF3~9vEC!M{|AZV0 zZJ!4*Nv{UdtxB;Bn>$jx{vecz11mHiI3h9E6CArfnl2Q4SVn009H?M$g(6J8Od#1j z0N&3C#MWk9qYq^DTGtst+&30#h=&CNFYWKz2-umyC_b(#g}ojKBWK@iu7I6k$l)#} zaj}4#fG2*|zu+{%7)i8P?@yX(jW8_!+ky*NY~N`Bf8tgocC*!ZM>c9GhRIm-iF_gv zVx{?lm$F155h`e~+}s0@#c~{$cqv%`Rki9;*fnQzbwCsHEP)U6xOa9%Y8@123~H8s z7g8wy-H9XV9_?$y@JUs{NLiRds)8!~{CoIz>~Wh*iGz zAjZ;V4q5-d))Y$Uk3mpU$lx$i{ba3VQXAzo_blVzN}nEjX*@GRnv1AE1&Ejeqbg=@ zDwWkr)b6By^I%nhFthu#??5+z8*hJoKMTx9OP9E{s453BjU5T-bDBmQq!V$8D0p@k zt6krxRWekO8+Y=Zi~(EJCCk=~)I#$Zm8hC@Z}vOU6wN$k&{}4RJ(}xs`D} zHpdo^NJq!F=tGZj!S}q8>ou6j#rj&xD=QR9hvC_nBD}n~o)S|y`h_9gn*6lcoBA!JmR3068ZUg;vY0sE>B~?J zW6i4Uw^h2C5vI_0Wp0CR{?I_v{hCfArh;Won!B2)J~EJW|B?FC{$xg@&Sih&IhKaU zZfd#3D1NrY|Nja*^LVJbH-KMTJ0dMeS)wGFkfoBH7CUd2FpV)7#>|)*JJr}LQmG`# zTTRq2iqb|}5TaC~P*Q1?UZuP(qTe(1GVblh@wuPNALr{i=XuU^o^$S5%%`5t3^{3e zdy+x8LqYnKJMU$6JqCq^&2QMI9SwM0F~}@FO@EzZ(&YZ2E!WdRTwV9usTdm#mkm#B z&&5S5E|!=RzjNIbzrP6fx367lUa+Aa?tjm0GUfNttX?OA_H!@ zM)zB2c_$~i8_$ea5)ZOw zD-mgq%be9HLfZ0e2|JWl=`ym`y)2>_1)jY-r<&!Y7^i%4-c3{MiAqhgj50pAS4*{8 zN(C6u&qxI{f0d7TP%Fx5*+YHR_hapO?^(KuCslRiVoR9~5$;Z zxpUfi?-dS@&#j4@C6Z$#*L~@4*Vfz~3zp8YMJKgLn;1cob3>Sf6Hk}M8$VBv6t?-$ z-JO&8J}S0MsZYT{Hnc&=wrBaE=*@p=OP>wUrhN7voHzZvebhH`KbL}C+h6!wHEq$q zL=J6npRDG#aG{7)f0B2H{B-kI31??~n=~uW)w#d&`(RSi*Q`Y$CQ}bpNXG|8NJ~Eo zI+J{MPF5i`x6nxQebJpm{pk|sv(FbU(8`EdCYRIDA#^MwX6bW|SnuVKkXVoBH+Vs| zYf{oJa0ua@}an9S;XCILa}KQ0$q|aZWctSGgMxR=*Y^yUk|zo4w_KAq zP}{!o=)$<8!j5H}fG8?ED=EW3+-JY?qmG(A9YrO3pG!;~SMNP8qqfaaNcoE7g?qQ{ z-OV|9RRem4m9kO|@ASf5Cgd(ij&=07rCm|uJ6?`#H2#UX?{k{h=FgLB8v-8)4}=%7 zxB0oPxa+XI=)*hP%wR9_r^f}Sw7fk%iK+S*$nRZ^FGeaJP>cB6d6IPzMsuHI8ew_9?ZR5YqeLQuJ`;b1w%iW24`9e>7 z`3@h~m+DEZi!bi#CGW0RiJ@z`po|D4m(LQ5stDe$gEfO`qJpu zsOYTqXkv?OyT_YSvGUB2V*@+C)h}yi5`xo}b4+6OqoOKXk(CZvihr>I|mC~Y&k7d(oJSw5%;>}tsIpZQPHFb5Ap9Sd>CTOa)Kq2s#}WQ#k-M6 zk^f7G`}D|k$19&wA7dYC;rlRR)wd^l1~0pxU3OjWmYNq{ydiQ|*_C^)$yM1q&n&U_ zGTBuA;Z^zDrYV}uS&z9YUme@nM`J{L#cc8oS8g-@_cis?n}^(iOY!4fm)r`H?3b>* z>b+#j#~nEV>&thq&cAEbGbbiJjF|FRfo4E(cuM|DV`sg%QAKxrdO0=rx!dPSH_B}c zmb^K*s!{6h@ldR=wBvEspOvX8hVp&(jZ_-IwO!d!oE$E7Vb zlhX?;CAu|^9bRNz8}^vBS#cmIyveb!Ps1)_tMLzML$~jkb<|(${}JcFV5JT=Bq(6w zN4N=u5zZd*0U^}MmI0qp%U`)hcm_xXe%+xaK9Qvv#^hGYvM}Xn7-rLcLHW_k8Fy+C{ufq87bxby|0u- zqTDwBq&(-yo^K^rz8q@~yk2f5+(wp|z2p12_?(JTL#O#P8*wN(Rk4%0Ht%HCzZvdeFOSE?GEE#G3ciyEgO{B+9!dHsW~ z4UHcQq73b7N}NSQ%X*hD$s4!FUOe`Tc~VICY=?=dWeTq(N+S!N?2DW+N#BV=i0&x3 zU;nbbKj4hp_Q9RbdC?+Kf9rWJ^2-#m^CvTkytVQx)B9SYv$tDyUL=*+6-u1g*!(=a z>-t>1xgXyJRwnQcY&yGUn}Z~b17mkTv^7|dK5MO-O2I?>6}+}_Co z%e$I?&y5HiIy^A=8csZ}!otycuB$99ZLm1~R$@C}2|e%-hGBfwl#PM&r7$UQXAhkm zNu*KfL2SJ0)btx%Ru4L|gPY41q3F39qYF!+b6Al?CWA`n;F1ZRLOT}#Q4Jn-6uAWM z85&Jd90rp}qlCd2700MD#y!x6`4a?O6Gs0kTBBp5s7y^Z$&Z4q;Ja5lx~9QMnGK6Y z_)98=5|0~zB5Dz#0Z}Havp^)eRQ8$m6nU?GL{kU;R}aif-@dDLJgDnIhm8H~t+K$9L$JZ_8;I)50L2!l0R z*(@p-itLj>5V_@8d%l3rVz7KEEQ&7?bc_=1m!I1DVAGux(B5k(9@;L_ZE!{Vb^jF9 z69`H2VT9sqfFdttAp=-#!1B#*DDk-7c4K1ys8_$OZJoD(N&=HZyRZxPV^N1UNMQ{w zD1G)G7C=+LjX@(DPCRa%<5*BOhZRcZgtC5KCx``W89qDRKM_G}6tU7KI*$PkCb5EG zx(Y{M2H#vg-;6_$B(OuYhq&%F29!k!38k_q!Qd+J$h|36_ZYCVERKdC;L3&*kNd@U z3^JQZAyfUR_!58oH~EK-B!VPrV_n3l*fF>ql0TlLB%{KdWH7AvpfS~9Ir+_TUfLMM zp&4DQu0H6n-fo0GtPY$Z+Oqyh9|I|vSHwd7Bom6gnh+#>s|Yd|C1-ICJ~Wa^f=NnT zAC%>03%g?wWLM~~a6dD5^ko@ZPf4u&8=XOxRRj@R487*`0QGDCrk1%lLvYvijEQ5$3 zT0|jCv^6ys7dFP|=ff^zjay**U1V&Xbq?b5{QdtVn*&LzARoF*60~b{opsBJ;x)}b z56TMn*BP&Zu~YPvUs3c>{qwjDN~59pP3lkL&F#|Fq=I<4@J&c*2ncT;*F$YoCcf!f z8Go1)4=POtD*=NWPCTx#=BPOK&z0DCZp3Swx|u#$3I`f1I*_X+;38?HP&zq)!cqiJ zNA;sXgN+ELVSAxi_J%9z&|;&Y+=|0u^2=?hjZ1~IGW7l!!G$$;ofQKao8Un=GHC-` z8jIo&_Do^n7_)3$6Hf-JkOQGUf4TZl;&Gh~@mUNGi9^95iE{7jT7g8ne(Mzut-vL* zNnsQQ6E`+vZq*xK27{t~&{)yEg33yK7T=lU2$jvOui-oKcBpuC@n){Z2T@@BhevAP zd*C)5JX;(X8aj|zYL83e@NMDufJ7PbTKfZPxdEyQEzv^{TuvyH#vu9Pka{yeR+ob1 zrvpZ5NN@1wab-M5ArXBUWIW5a?P+w5f=LXb1A_49b%qj;EAEHE(fz1+y{4S9sCG6K zD7 zQGp%3nk1kR_%>7a!||m!6k`e)GP)w3ok!)TuviS-LCeMe?fj<|a$f^iH*=^2@aA!q zE}{t$918uvuk=`-Q8SO0u@`Ex5mbzJRlXXXKlD#wYm3B*Puuums~R?JRd5y?*)jP80zYgWDFwO|54*7l zys&k1`_%d2U|Ox9RJ2ywBFBvs;lDl+*I)X6-Ixsn2V@#(25lTkTomM2zkp-m$&POi zZv^9L2T{-?3F~+?f$F2pVdxNlUVDwT4jJ;QdK)0@03pzF^e3Vy!3=s31uwkP&j0SI z2XmOY=deZ*nT95?!^k-0AW!bRp9=B8CWsHv<>)9z<)@Q^DQuWV!JRa~-uyk(T6o+; z=TMYi^Du&Yz_AsAJxWag%6fqYjXYQlOTivrC7=Yo#!yBaW`(6-k5Up)RJ*Vg!NE#c z3ibpX0i~oHOA(xhgQZ|kq!Ca8-=Qdi^J%aM?3OkGf;NCgU^lp7N!a~k0@CV19MaF- zWLO4vmzRL?3d0z==L<{0?oJUTU-$2k_#qK3d{;!(Hui^NFWf@=Inx*%=&>|B%h;en#|=KCm<@0R{i$)KEj{m z*S)pLSI_sYBlGvWlVV+Hy}eYpuu<~rU5d@Bq1w8zZCfsVwQ^$e{kqvWwr%Uk=aE6% zc)YxIs(PmKdHF!s_b(;u>}1ik$1WxdwQF9I+Op%HfYyZ`ZMQN$+Ll>CnX7Gly@CDP-CT z{(H&vh?8sbx|+ddLf)AC##UAzGfRin&de9_m#=$S`0QKob?#?Vwa!xfWwmoY!%#(| zmhy#y-aA*_&fGQEWe0W4e7Xw1XA6&Z*QC7esY?Q!*#x@%!ApCZ7^|ABc81PoqFRk@ z=fZA&LuP9?YO&jF0#8QorLMV0I1j%G8#m^uw1US+NsPJ?Q8fIT?R7UcYlbd%Hh#_R znt`pDXFsBBxwQuA&qsJdZl;-S_wzJi_x;%Zw$ZX(mIjt*)J$2vSVc1*8rX(YQLslr z^T?TCJ2lZ_P2Y?p(`&jKaa!o@AHt*}?R43! z+Obf&Y^=S=?6;#*!fw`!%HC1hw1k6Ix;iSSv~r9Mdm5Yko!DR7qvh9&s9H@A+1(%Q z<;sVe7j3N9D_50izMfmL7gt7#qVn6k8(BNuaTd|UKK2ta3W>-gQmcfUa<>b$aNIju zrQV+6`0L>_r=fJUmnTBMyQh|czxHhQ0g zdq?IyJK9V?iBd+Mmmx@8$y?cElgjMRk{#}Z87{o+hXH~k2i^@)&Y@&5l1?7D7#`7|k13*Riajgo!7ec>&4vyw-$R z?@tS8Alj8RT#lxL;HTI-C#ojmz<|5mUS;wT4(>O$`lZeJkgr>Md7zzSEwK@mbTSF}v88&w}0TS-zhF zIib7g`PJ_LZOQDhmKrNm-u|#`aXs75gXFo3(4o+3hnJ~8(aOt zcd~5E*JKg#POY7&YpfgyJeN`nP;zeo?2@kyDoLr#-r- zy1DvveG*%&u0KLOtl^c6uY&nU=9Lajb@1OYR%_-d%62(y+$Hb$u*$~Tk7b59p zZO`rXB$JY~WlNHv{h}*~RCt2M7B;|RjMG7zebGxCpF^0>qJ@)WN$IYZ)JB+Mv@A1) zQf_;6Abpg65l-BtN-)u1QD<09CxtrQ^Z3Um;O@b3Mb-_^b%&L{bLcxK?UI#%$bb@1 zYn74GuHtq#j5f{3P6?N|)bZ^w#cnd*B#Y=}<&L`o-1c;nGiYWBW-M39onVi?m7NEm z_M|WfPefk^14|ApJPLAWpLgu3lY8p+R?cpAvtsLwM*CJGT{lYhIT;3D8j*FZ&)>2( zl%b?x!}2whxiq5n6n^ZN`4!7}f&DfvguJJ}TLX?_zdra)!vnmO=O>Q5cB0j8CtN6p znWu^i3;9$Uf|&gcS#p4IxS~1wrt7#Ul&WXl=D~#_T7(d0p$j1-n*j1`lq4Nxa-E_x ziz<_~I!2DW>o%F{+)=*qi;(b(^MnOFDwjQAJn}_*-HJLwln&>dkQB6NS!KDv6%T8j z^fu{BieF?@gR|F8ph!a8m&$>f3|9r6u&6{%v;Ip_bQQ*RFQMkgBO!1U>3wQEC3cCs(u!5OR2_L#>}_VM%X*}! zG^%x!mrSpQ=aSh30B=kPp;q=1;C1y|%c6Y$hf<;m`NWns+M;%$KF9b8lxboGT1f~7 zlCmBRY%cZ6vOz2I4Z1+V*ivbHhTT}gmy0b>7Z$~x0n&qI6vI$c?P|(SeQ7Lq8EAu% zRM5Cv+FNwYflzBiD#eh>N%j&?5Fq!TGp239jNC3N!Po4Latq;5@#H=i>U^%}R0lu3 zjP+SmWZ=@X@DbGdTQYNGk2vD!IzTg-_u%t}yualA&($6LtBS?JNmEx+FYR_81J9|} znO*Aldx`axHD$52?szH<59A7d>o{SD7YD_&U1R&>a@dGGt@ScJ&4yb7e5G5io;q^> z8NO(t{ywhuJZav*Qk_LZQpCm|YoFsyRRM?r4D5)p)`gwwc->TVh1)uB*SiYYy1KPP zWXe>Me9H`Sx=uD(Y4Z{h?lZs7V6UK)o}WYK>)n=Mn>uN0>=kz}+6!mc>Pn)Ifjir5 z$-xrEo6V?cGJyuQwK}O3-QPrf10cGD$p{RDY3kEBpYXPpE{Cr2>s|~)6Yvrk12(i5 z^i!H8^9GiZnh50yA`b7fl56M5WA&j)B_?ADQhHb|;0yK2mb-%@g8qUipA~`m+ft20 z>H^VMi)12&c0rsIl=U?naB450(<@(RcO7WiAri|aehYM%gvd*%x)>bC31SZ|)ITD+ zAggJ8;yR#r+@lskf@Fm&0Pgt#(B)=ZRcpjHO;K#47uG>m6_Y}{ePuw1Uw^VnKTsy1 zpwa;yQ;X3BSK2@|_U4V`aDjlwCZ4P&8BS;o<0MfH55*uUv-|@7vUlW;0dYIyjnNTZ zgqz9g@zKnWyR(}sw+iccY6Uj1k}G%SO)ECnBW-R%_}iJ8<(CnNq8gH;V{)3FXZ3KO zV~QGNy;6wYyrqjdAp9DuYFiVA>9~>gVs4N0~B~QEoGCpozqkJx<+3vp#GDuso0O zGdS0^;Zu4;sj4kBZC3s4E>^Y$wDz<{t1A_(HeN~^p1&2m3G}Jj&iNQ7Wql=E%uTQO zu#3=GD*J5R@j_#3i9ES;A%cN^@@g~M@7vlO%H=xZaT(%uc{8@POk9$FUX9T!&R$KR4Zu4wAJu=G@_>eJ_L%l0pFOjgWQz16UPR%6mjx7p`i zS|r%ArkdMH<}8rSQ0`pryYNpu*B5}qG`*^yj)*~(CloUbm~1AY>j@*c1=YwQ zN}6VKOJGS#ll$5kTx%&q&hB`Db(X`1rISNEoGaV_=JqH zVpDrM?#E&mgG`b_B&V{aGUSp9AJ*pflm$e(&*RCuoQUycHo>hi%?!S}1C&+;ynDp}7#MNLPriV}Id zHe>iG!YOgO5-GiDrBAZn87rpqV^dFHl+RaNNunraN5akI=oOyeBYaZ(WpzT2Z(}Dhp^eF9p7ERr%41v%kL9jMJvtoipLlX-W?X*Z|9+YZ=rxincRuon zSA*Zs{g9eHM3n^sZ>{+4jcCfiktc_(s&X zdh1Qja-%h^q)QDmHF%;c=mcjJ$>cemnB6fksX1ySYc-+SK|6B1bP<|B!#S0rm}-`l z$7W(LgXKiZ^YirOukscggW$q9HO!nkaXUVv;nLU{mexve~@GlA*_!yM__@i>RoC+np%ps@xd< z6!lcM5R(F0Ad+-s#;1FY0Z%sxSF%)N5M<<5kWS&l+SPa&N}1;A+cr{#MetwmR>boj zTB1|;it*%?HVYG+SH&~lnfHv6qc+K1I}@JdYnLvz@*}WVf2g!qh4=XV<5vY0(mo^A z0&}J@9M73MaHD4+y2x1eP##Gtet9obH=H#tgxVUq%ts8IKcBK5gk`@YQW!*AuK6&> zplz_Ep~~?kOxUA(^Hj@U@Be#Z@BgtA?*DaP{Hd?-KZ+_>GB3+PzyN>{=>JDiMMhFsR8Cp+zltil z%JTM`3@H6)$~=x%r7^C&w%wT{DAt5=ILc#;Bw-#Gu#H^QdgTlmFLRxLuwg`!w@ za0g1U;NjR6J?^cw3Gi6z`SNA(ssy}F0b@eeMVg+%zi-JC$5e3F@it(3cn3$rR&zmO z#=;j?M-Yz`c5<;F?_ak!l6xr;d@je4FE)&UA2Ej~SziVA%%WIx-f~}TaahwT-p&Hj z^XROXkfEG?+=xAvTt^HR-cnw6c36U`76d}Wv_+F|OI^$TlMO_}pVo^@EXz9JsIyW0 zGr16;WASy?I-$jcC;J*xCj8@xwCq~l>CL8`bp7vuwR*J*z+mpQdwDueNw}f>Ri$)UE?%MI;TB#r3IO z_u&%iCF3`V)&$Rx98#ur=s1Ql)gSaORMPlBN<}3?Y0|{JOOcQq354_~YG_s19~)5d z^B&5N?(~#qm`*8Rf1EsVf588Ie;*yAB}qU401yZO0QWx?1!YB51Vsc@1XEQ8?T*+G zdY`Dv%Gm%CJb5U$22p7n^1FvE;i*7 z=~@<81mqv|jS>30(adwLFzkevLwTmLWV8DcauQK3@Kvg9(?_+^d4)f5>dNXHgbp8P z<=B~RQrS4KoBghkATE4}?OY<+98$MNdo?gcTc2#<^wa%m?*3{;Sr-eZ|h0xy+ z(l!J|_a#+Kt9&n#X37zfyBUk zs>NYItVWa4cX(^t&1$2ryNdtn3A~5LdZT>(LFgd)f9j z4|Nb>ugut?t>vd*&B@#3ccLkY60Xvez!mKJS;;uv5CEZpIzqdI8hQnQS9oW?azgsS z6ST}Oklhl~N6S;Gbk!}4+d_ZW&Bt*|@0DjQApl=@RJ$y2m=3HMoq1wnSVGb0hWgY~ zDD5({V4%`>oJ#YQb&q8P96AUknq7Htw#L%0AFaC~KQ9}Siu(%fxy~wkEKB6YQcW)D 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 aSSkwAVE?7803iO^zyFb?s=5B_>VE+{=r3FV literal 0 HcmV?d00001 diff --git a/.venv/share/python-wheels/toml-0.10.1-py2.py3-none-any.whl b/.venv/share/python-wheels/toml-0.10.1-py2.py3-none-any.whl new file mode 100644 index 0000000000000000000000000000000000000000..bccd1ad7a2447014f69cfecaeda65562b8188f31 GIT binary patch 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 literal 0 HcmV?d00001 diff --git a/.venv/share/python-wheels/webencodings-0.5.1-py2.py3-none-any.whl b/.venv/share/python-wheels/webencodings-0.5.1-py2.py3-none-any.whl new file mode 100644 index 0000000000000000000000000000000000000000..c4a86c103ffc06807cb1d3ff5579fc4afeba46cf GIT binary patch literal 15749 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 TfqPp`1QX4IJ`|D literal 0 HcmV?d00001 diff --git a/.venv/share/python-wheels/wheel-0.34.2-py2.py3-none-any.whl b/.venv/share/python-wheels/wheel-0.34.2-py2.py3-none-any.whl new file mode 100644 index 0000000000000000000000000000000000000000..e6ac0091e21f4600b201b0929d99054c0f2e55d1 GIT binary patch literal 30875 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 Y67;WF?2iN*RDd#20D$GcqL%^w55=wCLjV8( literal 0 HcmV?d00001 diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 00000000..de475e4d --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,4 @@ +{ + "python.pythonPath": ".venv/bin/python", + "git.ignoreLimitWarning": true +} \ No newline at end of file diff --git a/Prueba.py b/Prueba.py new file mode 100644 index 00000000..7c0bd78f --- /dev/null +++ b/Prueba.py @@ -0,0 +1 @@ +print(prueba) diff --git a/prueba2.py b/prueba2.py new file mode 100644 index 00000000..dba93719 --- /dev/null +++ b/prueba2.py @@ -0,0 +1,4 @@ +#%% +print("Hello world") +# %% +print("prueba2") \ No newline at end of file

      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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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