From a9bd02f12adc74c11030ee41bb5f93fd01543272 Mon Sep 17 00:00:00 2001 From: robo-bo Date: Wed, 24 Aug 2022 15:28:08 +0300 Subject: [PATCH] v1.2.14 --- .../INSTALLER | 0 .../Jinja2-3.1.2.dist-info/LICENSE.rst | 28 + .../Jinja2-3.1.2.dist-info/METADATA | 113 + .../Jinja2-3.1.2.dist-info/RECORD | 58 + .../Jinja2-3.1.2.dist-info/WHEEL | 5 + .../Jinja2-3.1.2.dist-info/entry_points.txt | 2 + .../Jinja2-3.1.2.dist-info/top_level.txt | 1 + .../INSTALLER | 0 .../MarkupSafe-2.1.1.dist-info/LICENSE.rst | 28 + .../MarkupSafe-2.1.1.dist-info/METADATA | 101 + .../MarkupSafe-2.1.1.dist-info/RECORD | 13 + .../WHEEL | 2 +- .../MarkupSafe-2.1.1.dist-info/top_level.txt | 1 + .../INSTALLER | 0 .../PySocks-1.7.1.dist-info/LICENSE | 22 + .../PySocks-1.7.1.dist-info/METADATA | 321 ++ .../PySocks-1.7.1.dist-info/RECORD | 10 + .../PySocks-1.7.1.dist-info/WHEEL | 5 + .../PySocks-1.7.1.dist-info/top_level.txt | 2 + .../_cffi_backend.cp37-win32.pyd | Bin 139264 -> 155648 bytes .../INSTALLER | 0 .../async_generator-1.10.dist-info/METADATA | 145 + .../async_generator-1.10.dist-info/RECORD | 21 + .../async_generator-1.10.dist-info/WHEEL | 5 + .../top_level.txt | 1 + .../site-packages/async_generator/__init__.py | 23 + .../site-packages/async_generator/_impl.py | 455 ++ .../_tests/__init__.py} | 0 .../async_generator/_tests/conftest.py | 36 + .../_tests/test_async_generator.py | 1015 +++++ .../async_generator/_tests/test_util.py | 227 + .../site-packages/async_generator/_util.py | 110 + .../site-packages/async_generator/_version.py | 1 + .../Lib/site-packages/attr/__init__.py | 79 + .../Lib/site-packages/attr/__init__.pyi | 486 +++ .../Lib/site-packages/attr/_cmp.py | 155 + .../Lib/site-packages/attr/_cmp.pyi | 13 + .../Lib/site-packages/attr/_compat.py | 185 + .../Lib/site-packages/attr/_config.py | 31 + .../Lib/site-packages/attr/_funcs.py | 420 ++ .../Lib/site-packages/attr/_make.py | 3006 ++++++++++++++ .../Lib/site-packages/attr/_next_gen.py | 220 + .../Lib/site-packages/attr/_version_info.py | 86 + .../Lib/site-packages/attr/_version_info.pyi | 9 + .../Lib/site-packages/attr/converters.py | 144 + .../Lib/site-packages/attr/converters.pyi | 13 + .../Lib/site-packages/attr/exceptions.py | 92 + .../Lib/site-packages/attr/exceptions.pyi | 17 + .../Lib/site-packages/attr/filters.py | 51 + .../Lib/site-packages/attr/filters.pyi | 6 + .../Lib/site-packages/attr/py.typed} | 0 .../Lib/site-packages/attr/setters.py | 73 + .../Lib/site-packages/attr/setters.pyi | 19 + .../Lib/site-packages/attr/validators.py | 594 +++ .../Lib/site-packages/attr/validators.pyi | 80 + .../attrs-22.1.0.dist-info/AUTHORS.rst | 11 + .../INSTALLER | 0 .../attrs-22.1.0.dist-info/LICENSE | 21 + .../attrs-22.1.0.dist-info/METADATA | 240 ++ .../attrs-22.1.0.dist-info/RECORD | 56 + .../WHEEL | 2 +- .../attrs-22.1.0.dist-info/top_level.txt | 2 + .../Lib/site-packages/attrs/__init__.py | 70 + .../Lib/site-packages/attrs/__init__.pyi | 66 + .../Lib/site-packages/attrs/converters.py | 3 + .../Lib/site-packages/attrs/exceptions.py | 3 + .../Lib/site-packages/attrs/filters.py | 3 + .../Lib/site-packages/attrs/py.typed | 0 .../Lib/site-packages/attrs/setters.py | 3 + .../Lib/site-packages/attrs/validators.py | 3 + .../DESCRIPTION.rst | 50 - .../certifi-2019.9.11.dist-info/RECORD | 14 - .../certifi-2019.9.11.dist-info/metadata.json | 1 - .../certifi-2022.6.15.dist-info}/INSTALLER | 0 .../certifi-2022.6.15.dist-info/LICENSE | 21 + .../METADATA | 35 +- .../certifi-2022.6.15.dist-info/RECORD | 14 + .../certifi-2022.6.15.dist-info/WHEEL | 5 + .../top_level.txt | 0 .../Lib/site-packages/certifi/__init__.py | 5 +- .../Lib/site-packages/certifi/__main__.py | 14 +- .../Lib/site-packages/certifi/cacert.pem | 2389 ++++++----- .../Lib/site-packages/certifi/core.py | 65 +- .../Lib/site-packages/certifi/py.typed | 0 .../cffi-1.12.3.dist-info/RECORD | 44 - .../cffi-1.15.1.dist-info/INSTALLER | 1 + .../LICENSE | 0 .../METADATA | 16 +- .../cffi-1.15.1.dist-info/RECORD | 44 + .../WHEEL | 2 +- .../entry_points.txt | 1 - .../top_level.txt | 0 .../Lib/site-packages/cffi/__init__.py | 4 +- .../Lib/site-packages/cffi/_cffi_errors.h | 2 + .../Lib/site-packages/cffi/_cffi_include.h | 105 +- .../Lib/site-packages/cffi/_embedding.h | 32 +- .../Lib/site-packages/cffi/api.py | 14 +- .../Lib/site-packages/cffi/backend_ctypes.py | 2 +- .../Lib/site-packages/cffi/cparser.py | 115 +- .../Lib/site-packages/cffi/model.py | 7 +- .../Lib/site-packages/cffi/recompiler.py | 83 +- .../Lib/site-packages/cffi/setuptools_ext.py | 8 +- .../Lib/site-packages/cffi/vengine_cpy.py | 87 +- .../Lib/site-packages/cffi/vengine_gen.py | 4 +- .../Lib/site-packages/cffi/verifier.py | 3 +- .../h11-0.13.0.dist-info/INSTALLER | 1 + .../h11-0.13.0.dist-info/LICENSE.txt | 22 + .../h11-0.13.0.dist-info/METADATA | 197 + .../site-packages/h11-0.13.0.dist-info/RECORD | 52 + .../site-packages/h11-0.13.0.dist-info/WHEEL | 5 + .../h11-0.13.0.dist-info/top_level.txt | 1 + .../Lib/site-packages/h11/__init__.py | 62 + .../Lib/site-packages/h11/_abnf.py | 129 + .../Lib/site-packages/h11/_connection.py | 631 +++ .../Lib/site-packages/h11/_events.py | 369 ++ .../Lib/site-packages/h11/_headers.py | 278 ++ .../Lib/site-packages/h11/_readers.py | 249 ++ .../Lib/site-packages/h11/_receivebuffer.py | 153 + .../Lib/site-packages/h11/_state.py | 363 ++ .../Lib/site-packages/h11/_util.py | 135 + .../Lib/site-packages/h11/_version.py | 16 + .../Lib/site-packages/h11/_writers.py | 145 + .../Lib/site-packages/h11/py.typed | 1 + .../Lib/site-packages/h11/tests/__init__.py | 0 .../site-packages/h11/tests/data/test-file | 1 + .../Lib/site-packages/h11/tests/helpers.py | 101 + .../h11/tests/test_against_stdlib_http.py | 115 + .../h11/tests/test_connection.py | 1122 +++++ .../site-packages/h11/tests/test_events.py | 150 + .../site-packages/h11/tests/test_headers.py | 157 + .../site-packages/h11/tests/test_helpers.py | 32 + .../Lib/site-packages/h11/tests/test_io.py | 566 +++ .../h11/tests/test_receivebuffer.py | 135 + .../Lib/site-packages/h11/tests/test_state.py | 271 ++ .../Lib/site-packages/h11/tests/test_util.py | 112 + .../Lib/site-packages/jinja2/__init__.py | 37 + .../Lib/site-packages/jinja2/_identifier.py | 6 + .../Lib/site-packages/jinja2/async_utils.py | 84 + .../Lib/site-packages/jinja2/bccache.py | 406 ++ .../Lib/site-packages/jinja2/compiler.py | 1957 +++++++++ .../Lib/site-packages/jinja2/constants.py | 20 + .../Lib/site-packages/jinja2/debug.py | 191 + .../Lib/site-packages/jinja2/defaults.py | 48 + .../Lib/site-packages/jinja2/environment.py | 1667 ++++++++ .../Lib/site-packages/jinja2/exceptions.py | 166 + .../Lib/site-packages/jinja2/ext.py | 859 ++++ .../Lib/site-packages/jinja2/filters.py | 1840 +++++++++ .../Lib/site-packages/jinja2/idtracking.py | 318 ++ .../Lib/site-packages/jinja2/lexer.py | 866 ++++ .../Lib/site-packages/jinja2/loaders.py | 661 +++ .../Lib/site-packages/jinja2/meta.py | 111 + .../Lib/site-packages/jinja2/nativetypes.py | 130 + .../Lib/site-packages/jinja2/nodes.py | 1204 ++++++ .../Lib/site-packages/jinja2/optimizer.py | 47 + .../Lib/site-packages/jinja2/parser.py | 1032 +++++ .../Lib/site-packages/jinja2/py.typed | 0 .../Lib/site-packages/jinja2/runtime.py | 1053 +++++ .../Lib/site-packages/jinja2/sandbox.py | 428 ++ .../Lib/site-packages/jinja2/tests.py | 255 ++ .../Lib/site-packages/jinja2/utils.py | 755 ++++ .../Lib/site-packages/jinja2/visitor.py | 92 + .../Lib/site-packages/markupsafe/__init__.py | 295 ++ .../Lib/site-packages/markupsafe/_native.py | 63 + .../markupsafe/_speedups.cp37-win32.pyd | Bin 0 -> 13824 bytes .../site-packages/markupsafe/_speedups.pyi | 9 + .../Lib/site-packages/markupsafe/py.typed | 0 .../outcome-1.2.0.dist-info/INSTALLER | 1 + .../outcome-1.2.0.dist-info/LICENSE | 3 + .../outcome-1.2.0.dist-info/LICENSE.APACHE2 | 202 + .../outcome-1.2.0.dist-info/LICENSE.MIT | 20 + .../outcome-1.2.0.dist-info/METADATA | 61 + .../outcome-1.2.0.dist-info/RECORD | 16 + .../WHEEL | 0 .../outcome-1.2.0.dist-info/top_level.txt | 1 + .../Lib/site-packages/outcome/__init__.py | 12 + .../Lib/site-packages/outcome/_impl.py | 160 + .../Lib/site-packages/outcome/_util.py | 24 + .../Lib/site-packages/outcome/_version.py | 3 + .../psutil-5.6.1.dist-info/RECORD | 59 - .../psutil-5.9.1.dist-info/INSTALLER | 1 + .../LICENSE | 4 +- .../METADATA | 258 +- .../psutil-5.9.1.dist-info/RECORD | 63 + .../psutil-5.9.1.dist-info/WHEEL | 5 + .../top_level.txt | 0 .../Lib/site-packages/psutil/__init__.py | 600 ++- .../Lib/site-packages/psutil/_common.py | 350 +- .../Lib/site-packages/psutil/_compat.py | 217 +- .../Lib/site-packages/psutil/_psaix.py | 119 +- .../Lib/site-packages/psutil/_psbsd.py | 236 +- .../Lib/site-packages/psutil/_pslinux.py | 721 ++-- .../Lib/site-packages/psutil/_psosx.py | 118 +- .../Lib/site-packages/psutil/_psposix.py | 180 +- .../Lib/site-packages/psutil/_pssunos.py | 102 +- .../psutil/_psutil_windows.cp37-win32.pyd | Bin 61952 -> 59392 bytes .../Lib/site-packages/psutil/_pswindows.py | 394 +- .../site-packages/psutil/tests/__init__.py | 1279 ++++-- .../site-packages/psutil/tests/__main__.py | 83 +- .../Lib/site-packages/psutil/tests/runner.py | 350 ++ .../site-packages/psutil/tests/test_aix.py | 23 +- .../site-packages/psutil/tests/test_bsd.py | 177 +- .../psutil/tests/test_connections.py | 362 +- .../psutil/tests/test_contracts.py | 568 +-- .../site-packages/psutil/tests/test_linux.py | 825 ++-- ...{test_memory_leaks.py => test_memleaks.py} | 410 +- .../site-packages/psutil/tests/test_misc.py | 651 +-- .../site-packages/psutil/tests/test_osx.py | 126 +- .../site-packages/psutil/tests/test_posix.py | 134 +- .../psutil/tests/test_process.py | 1047 +++-- .../site-packages/psutil/tests/test_sunos.py | 11 +- .../site-packages/psutil/tests/test_system.py | 533 +-- .../psutil/tests/test_testutils.py | 441 ++ .../psutil/tests/test_unicode.py | 287 +- .../psutil/tests/test_windows.py | 322 +- .../pyOpenRPA-1.2.14.dist-info/INSTALLER | 1 + .../pyOpenRPA-1.2.14.dist-info}/METADATA | 17 +- .../RECORD | 62 +- .../pyOpenRPA-1.2.14.dist-info/REQUESTED | 0 .../WHEEL | 0 .../top_level.txt | 0 .../Lib/site-packages/pyOpenRPA/LICENSE.pdf | Bin 321175 -> 4322139 bytes .../Orchestrator/BackwardCompatibility.py | 5 +- .../Orchestrator/Managers/ControlPanel.py | 9 +- .../Orchestrator/RobotRDPActive/Clipboard.py | 27 +- .../Orchestrator/RobotRDPActive/Connector.py | 48 +- .../Orchestrator/RobotScreenActive/Monitor.py | 22 +- .../pyOpenRPA/Orchestrator/Server.py | 12 +- .../pyOpenRPA/Orchestrator/ServerSettings.py | 25 +- .../Orchestrator/__Orchestrator__.py | 60 +- .../pyOpenRPA/Robot/Clipboard.py | 31 +- .../site-packages/pyOpenRPA/Robot/Keyboard.py | 483 ++- .../site-packages/pyOpenRPA/Robot/Mouse.py | 24 +- .../site-packages/pyOpenRPA/Robot/Screen.py | 672 ++- .../pyOpenRPA/Robot/UIDesktop.py | 131 +- .../site-packages/pyOpenRPA/Robot/UIWeb.py | 628 ++- .../pyOpenRPA/Robot/Utils/ProcessBitness.py | 4 +- .../site-packages/pyOpenRPA/Robot/__init__.py | 4 +- .../pyOpenRPA/Studio/Web/Index.xhtml | 14 +- .../site-packages/pyOpenRPA/Tools/CrossOS.py | 54 + .../site-packages/pyOpenRPA/Tools/License.py | 5 +- .../site-packages/pyOpenRPA/Tools/Template.py | 127 + .../Lib/site-packages/pyOpenRPA/__init__.py | 2 +- .../selenium-4.4.3.dist-info/INSTALLER | 1 + .../selenium-4.4.3.dist-info/METADATA | 170 + .../selenium-4.4.3.dist-info/RECORD | 592 +++ .../selenium-4.4.3.dist-info/WHEEL | 4 + .../Lib/site-packages/selenium/__init__.py | 19 + .../site-packages/selenium/common/__init__.py | 85 + .../selenium/common/exceptions.py | 326 ++ .../Lib/site-packages/selenium/py.typed | 0 .../Lib/site-packages/selenium/types.py | 24 + .../selenium/webdriver/__init__.py | 64 + .../selenium/webdriver/chrome/__init__.py | 16 + .../selenium/webdriver/chrome/options.py | 34 + .../selenium/webdriver/chrome/service.py | 48 + .../selenium/webdriver/chrome/webdriver.py | 72 + .../selenium/webdriver/chromium/__init__.py | 16 + .../selenium/webdriver/chromium/options.py | 192 + .../webdriver/chromium/remote_connection.py | 42 + .../selenium/webdriver/chromium/service.py | 48 + .../selenium/webdriver/chromium/webdriver.py | 244 ++ .../selenium/webdriver/common/__init__.py | 16 + .../webdriver/common/action_chains.py | 402 ++ .../webdriver/common/actions/__init__.py | 16 + .../common/actions/action_builder.py | 97 + .../webdriver/common/actions/input_device.py | 43 + .../webdriver/common/actions/interaction.py | 51 + .../webdriver/common/actions/key_actions.py | 50 + .../webdriver/common/actions/key_input.py | 51 + .../webdriver/common/actions/mouse_button.py | 25 + .../common/actions/pointer_actions.py | 121 + .../webdriver/common/actions/pointer_input.py | 79 + .../webdriver/common/actions/wheel_actions.py | 34 + .../webdriver/common/actions/wheel_input.py | 74 + .../selenium/webdriver/common/alert.py | 90 + .../webdriver/common/bidi/__init__.py | 16 + .../selenium/webdriver/common/bidi/cdp.py | 501 +++ .../selenium/webdriver/common/bidi/console.py | 25 + .../selenium/webdriver/common/by.py | 35 + .../webdriver/common/desired_capabilities.py | 109 + .../common/devtools/v102/__init__.py | 52 + .../common/devtools/v102/accessibility.py | 640 +++ .../common/devtools/v102/animation.py | 415 ++ .../webdriver/common/devtools/v102/audits.py | 1241 ++++++ .../devtools/v102/background_service.py | 208 + .../webdriver/common/devtools/v102/browser.py | 697 ++++ .../common/devtools/v102/cache_storage.py | 287 ++ .../webdriver/common/devtools/v102/cast.py | 170 + .../webdriver/common/devtools/v102/console.py | 105 + .../webdriver/common/devtools/v102/css.py | 1741 ++++++++ .../common/devtools/v102/database.py | 162 + .../common/devtools/v102/debugger.py | 1222 ++++++ .../devtools/v102/device_orientation.py | 43 + .../webdriver/common/devtools/v102/dom.py | 1888 +++++++++ .../common/devtools/v102/dom_debugger.py | 312 ++ .../common/devtools/v102/dom_snapshot.py | 863 ++++ .../common/devtools/v102/dom_storage.py | 201 + .../common/devtools/v102/emulation.py | 804 ++++ .../common/devtools/v102/event_breakpoints.py | 44 + .../webdriver/common/devtools/v102/fetch.py | 490 +++ .../devtools/v102/headless_experimental.py | 116 + .../common/devtools/v102/heap_profiler.py | 379 ++ .../common/devtools/v102/indexed_db.py | 461 +++ .../webdriver/common/devtools/v102/input_.py | 689 ++++ .../common/devtools/v102/inspector.py | 76 + .../webdriver/common/devtools/v102/io.py | 99 + .../common/devtools/v102/layer_tree.py | 462 +++ .../webdriver/common/devtools/v102/log.py | 188 + .../webdriver/common/devtools/v102/media.py | 288 ++ .../webdriver/common/devtools/v102/memory.py | 261 ++ .../webdriver/common/devtools/v102/network.py | 3663 ++++++++++++++++ .../webdriver/common/devtools/v102/overlay.py | 1335 ++++++ .../webdriver/common/devtools/v102/page.py | 3254 +++++++++++++++ .../common/devtools/v102/performance.py | 116 + .../devtools/v102/performance_timeline.py | 198 + .../common/devtools/v102/profiler.py | 532 +++ .../webdriver/common/devtools/v102/py.typed | 0 .../webdriver/common/devtools/v102/runtime.py | 1540 +++++++ .../webdriver/common/devtools/v102/schema.py | 48 + .../common/devtools/v102/security.py | 509 +++ .../common/devtools/v102/service_worker.py | 409 ++ .../webdriver/common/devtools/v102/storage.py | 571 +++ .../common/devtools/v102/system_info.py | 347 ++ .../webdriver/common/devtools/v102/target.py | 643 +++ .../common/devtools/v102/tethering.py | 63 + .../webdriver/common/devtools/v102/tracing.py | 340 ++ .../webdriver/common/devtools/v102/util.py | 19 + .../common/devtools/v102/web_audio.py | 603 +++ .../common/devtools/v102/web_authn.py | 388 ++ .../common/devtools/v103/__init__.py | 52 + .../common/devtools/v103/accessibility.py | 640 +++ .../common/devtools/v103/animation.py | 415 ++ .../webdriver/common/devtools/v103/audits.py | 1270 ++++++ .../devtools/v103/background_service.py | 208 + .../webdriver/common/devtools/v103/browser.py | 697 ++++ .../common/devtools/v103/cache_storage.py | 287 ++ .../webdriver/common/devtools/v103/cast.py | 170 + .../webdriver/common/devtools/v103/console.py | 105 + .../webdriver/common/devtools/v103/css.py | 1741 ++++++++ .../common/devtools/v103/database.py | 162 + .../common/devtools/v103/debugger.py | 1231 ++++++ .../devtools/v103/device_orientation.py | 43 + .../webdriver/common/devtools/v103/dom.py | 1888 +++++++++ .../common/devtools/v103/dom_debugger.py | 312 ++ .../common/devtools/v103/dom_snapshot.py | 863 ++++ .../common/devtools/v103/dom_storage.py | 239 ++ .../common/devtools/v103/emulation.py | 814 ++++ .../common/devtools/v103/event_breakpoints.py | 44 + .../webdriver/common/devtools/v103/fetch.py | 490 +++ .../devtools/v103/headless_experimental.py | 116 + .../common/devtools/v103/heap_profiler.py | 387 ++ .../common/devtools/v103/indexed_db.py | 461 +++ .../webdriver/common/devtools/v103/input_.py | 689 ++++ .../common/devtools/v103/inspector.py | 76 + .../webdriver/common/devtools/v103/io.py | 99 + .../common/devtools/v103/layer_tree.py | 462 +++ .../webdriver/common/devtools/v103/log.py | 188 + .../webdriver/common/devtools/v103/media.py | 288 ++ .../webdriver/common/devtools/v103/memory.py | 261 ++ .../webdriver/common/devtools/v103/network.py | 3663 ++++++++++++++++ .../webdriver/common/devtools/v103/overlay.py | 1335 ++++++ .../webdriver/common/devtools/v103/page.py | 3286 +++++++++++++++ .../common/devtools/v103/performance.py | 116 + .../devtools/v103/performance_timeline.py | 198 + .../common/devtools/v103/profiler.py | 532 +++ .../webdriver/common/devtools/v103/py.typed | 0 .../webdriver/common/devtools/v103/runtime.py | 1540 +++++++ .../webdriver/common/devtools/v103/schema.py | 48 + .../common/devtools/v103/security.py | 509 +++ .../common/devtools/v103/service_worker.py | 409 ++ .../webdriver/common/devtools/v103/storage.py | 583 +++ .../common/devtools/v103/system_info.py | 347 ++ .../webdriver/common/devtools/v103/target.py | 643 +++ .../common/devtools/v103/tethering.py | 63 + .../webdriver/common/devtools/v103/tracing.py | 340 ++ .../webdriver/common/devtools/v103/util.py | 19 + .../common/devtools/v103/web_audio.py | 603 +++ .../common/devtools/v103/web_authn.py | 396 ++ .../common/devtools/v104/__init__.py | 52 + .../common/devtools/v104/accessibility.py | 640 +++ .../common/devtools/v104/animation.py | 415 ++ .../webdriver/common/devtools/v104/audits.py | 1267 ++++++ .../devtools/v104/background_service.py | 208 + .../webdriver/common/devtools/v104/browser.py | 697 ++++ .../common/devtools/v104/cache_storage.py | 287 ++ .../webdriver/common/devtools/v104/cast.py | 170 + .../webdriver/common/devtools/v104/console.py | 105 + .../webdriver/common/devtools/v104/css.py | 1752 ++++++++ .../common/devtools/v104/database.py | 162 + .../common/devtools/v104/debugger.py | 1247 ++++++ .../devtools/v104/device_orientation.py | 43 + .../webdriver/common/devtools/v104/dom.py | 1900 +++++++++ .../common/devtools/v104/dom_debugger.py | 312 ++ .../common/devtools/v104/dom_snapshot.py | 870 ++++ .../common/devtools/v104/dom_storage.py | 220 + .../common/devtools/v104/emulation.py | 833 ++++ .../common/devtools/v104/event_breakpoints.py | 44 + .../webdriver/common/devtools/v104/fetch.py | 490 +++ .../devtools/v104/headless_experimental.py | 116 + .../common/devtools/v104/heap_profiler.py | 387 ++ .../common/devtools/v104/indexed_db.py | 461 +++ .../webdriver/common/devtools/v104/input_.py | 689 ++++ .../common/devtools/v104/inspector.py | 76 + .../webdriver/common/devtools/v104/io.py | 99 + .../common/devtools/v104/layer_tree.py | 462 +++ .../webdriver/common/devtools/v104/log.py | 188 + .../webdriver/common/devtools/v104/media.py | 288 ++ .../webdriver/common/devtools/v104/memory.py | 261 ++ .../webdriver/common/devtools/v104/network.py | 3664 +++++++++++++++++ .../webdriver/common/devtools/v104/overlay.py | 1335 ++++++ .../webdriver/common/devtools/v104/page.py | 3317 +++++++++++++++ .../common/devtools/v104/performance.py | 116 + .../devtools/v104/performance_timeline.py | 198 + .../common/devtools/v104/profiler.py | 532 +++ .../webdriver/common/devtools/v104/py.typed | 0 .../webdriver/common/devtools/v104/runtime.py | 1540 +++++++ .../webdriver/common/devtools/v104/schema.py | 48 + .../common/devtools/v104/security.py | 509 +++ .../common/devtools/v104/service_worker.py | 409 ++ .../webdriver/common/devtools/v104/storage.py | 603 +++ .../common/devtools/v104/system_info.py | 347 ++ .../webdriver/common/devtools/v104/target.py | 643 +++ .../common/devtools/v104/tethering.py | 63 + .../webdriver/common/devtools/v104/tracing.py | 340 ++ .../webdriver/common/devtools/v104/util.py | 19 + .../common/devtools/v104/web_audio.py | 603 +++ .../common/devtools/v104/web_authn.py | 396 ++ .../webdriver/common/devtools/v85/__init__.py | 51 + .../common/devtools/v85/accessibility.py | 455 ++ .../common/devtools/v85/animation.py | 415 ++ .../common/devtools/v85/application_cache.py | 205 + .../webdriver/common/devtools/v85/audits.py | 527 +++ .../common/devtools/v85/background_service.py | 208 + .../webdriver/common/devtools/v85/browser.py | 579 +++ .../common/devtools/v85/cache_storage.py | 287 ++ .../webdriver/common/devtools/v85/cast.py | 153 + .../webdriver/common/devtools/v85/console.py | 105 + .../webdriver/common/devtools/v85/css.py | 1365 ++++++ .../webdriver/common/devtools/v85/database.py | 162 + .../webdriver/common/devtools/v85/debugger.py | 1209 ++++++ .../common/devtools/v85/device_orientation.py | 43 + .../webdriver/common/devtools/v85/dom.py | 1747 ++++++++ .../common/devtools/v85/dom_debugger.py | 278 ++ .../common/devtools/v85/dom_snapshot.py | 837 ++++ .../common/devtools/v85/dom_storage.py | 201 + .../common/devtools/v85/emulation.py | 658 +++ .../webdriver/common/devtools/v85/fetch.py | 446 ++ .../devtools/v85/headless_experimental.py | 116 + .../common/devtools/v85/heap_profiler.py | 371 ++ .../common/devtools/v85/indexed_db.py | 461 +++ .../webdriver/common/devtools/v85/input_.py | 477 +++ .../common/devtools/v85/inspector.py | 76 + .../webdriver/common/devtools/v85/io.py | 99 + .../common/devtools/v85/layer_tree.py | 462 +++ .../webdriver/common/devtools/v85/log.py | 183 + .../webdriver/common/devtools/v85/media.py | 251 ++ .../webdriver/common/devtools/v85/memory.py | 261 ++ .../webdriver/common/devtools/v85/network.py | 2640 ++++++++++++ .../webdriver/common/devtools/v85/overlay.py | 698 ++++ .../webdriver/common/devtools/v85/page.py | 2373 +++++++++++ .../common/devtools/v85/performance.py | 116 + .../webdriver/common/devtools/v85/profiler.py | 596 +++ .../webdriver/common/devtools/v85/py.typed | 0 .../webdriver/common/devtools/v85/runtime.py | 1437 +++++++ .../webdriver/common/devtools/v85/schema.py | 48 + .../webdriver/common/devtools/v85/security.py | 509 +++ .../common/devtools/v85/service_worker.py | 409 ++ .../webdriver/common/devtools/v85/storage.py | 309 ++ .../common/devtools/v85/system_info.py | 347 ++ .../webdriver/common/devtools/v85/target.py | 599 +++ .../common/devtools/v85/tethering.py | 63 + .../webdriver/common/devtools/v85/tracing.py | 290 ++ .../webdriver/common/devtools/v85/util.py | 19 + .../common/devtools/v85/web_audio.py | 603 +++ .../common/devtools/v85/web_authn.py | 318 ++ .../webdriver/common/html5/__init__.py | 16 + .../common/html5/application_cache.py | 53 + .../selenium/webdriver/common/keys.py | 95 + .../selenium/webdriver/common/log.py | 150 + .../webdriver/common/mutation-listener.js | 55 + .../selenium/webdriver/common/options.py | 263 ++ .../webdriver/common/print_page_options.py | 285 ++ .../selenium/webdriver/common/proxy.py | 355 ++ .../selenium/webdriver/common/service.py | 173 + .../selenium/webdriver/common/timeouts.py | 114 + .../selenium/webdriver/common/utils.py | 150 + .../webdriver/common/virtual_authenticator.py | 264 ++ .../selenium/webdriver/common/window.py | 27 + .../selenium/webdriver/edge/__init__.py | 16 + .../selenium/webdriver/edge/options.py | 50 + .../selenium/webdriver/edge/service.py | 55 + .../selenium/webdriver/edge/webdriver.py | 67 + .../selenium/webdriver/firefox/__init__.py | 16 + .../webdriver/firefox/extension_connection.py | 83 + .../webdriver/firefox/firefox_binary.py | 222 + .../webdriver/firefox/firefox_profile.py | 366 ++ .../selenium/webdriver/firefox/options.py | 166 + .../webdriver/firefox/remote_connection.py | 36 + .../selenium/webdriver/firefox/service.py | 67 + .../selenium/webdriver/firefox/webdriver.py | 341 ++ .../webdriver/firefox/webdriver_prefs.json | 69 + .../selenium/webdriver/ie/__init__.py | 16 + .../selenium/webdriver/ie/options.py | 374 ++ .../selenium/webdriver/ie/service.py | 56 + .../selenium/webdriver/ie/webdriver.py | 121 + .../selenium/webdriver/remote/__init__.py | 16 + .../webdriver/remote/bidi_connection.py | 23 + .../selenium/webdriver/remote/command.py | 123 + .../selenium/webdriver/remote/errorhandler.py | 243 ++ .../webdriver/remote/file_detector.py | 61 + .../selenium/webdriver/remote/findElements.js | 122 + .../selenium/webdriver/remote/getAttribute.js | 100 + .../selenium/webdriver/remote/isDisplayed.js | 100 + .../selenium/webdriver/remote/mobile.py | 86 + .../webdriver/remote/remote_connection.py | 417 ++ .../selenium/webdriver/remote/script_key.py | 33 + .../selenium/webdriver/remote/shadowroot.py | 87 + .../selenium/webdriver/remote/switch_to.py | 154 + .../selenium/webdriver/remote/utils.py | 27 + .../selenium/webdriver/remote/webdriver.py | 1285 ++++++ .../selenium/webdriver/remote/webelement.py | 467 +++ .../selenium/webdriver/safari/__init__.py | 16 + .../selenium/webdriver/safari/options.py | 134 + .../selenium/webdriver/safari/permissions.py | 28 + .../webdriver/safari/remote_connection.py | 30 + .../selenium/webdriver/safari/service.py | 68 + .../selenium/webdriver/safari/webdriver.py | 144 + .../selenium/webdriver/support/__init__.py | 16 + .../support/abstract_event_listener.py | 79 + .../selenium/webdriver/support/color.py | 335 ++ .../support/event_firing_webdriver.py | 235 ++ .../selenium/webdriver/support/events.py | 19 + .../webdriver/support/expected_conditions.py | 488 +++ .../webdriver/support/relative_locator.py | 155 + .../selenium/webdriver/support/select.py | 237 ++ .../selenium/webdriver/support/ui.py | 19 + .../selenium/webdriver/support/wait.py | 113 + .../selenium/webdriver/webkitgtk/__init__.py | 16 + .../selenium/webdriver/webkitgtk/options.py | 84 + .../selenium/webdriver/webkitgtk/service.py | 46 + .../selenium/webdriver/webkitgtk/webdriver.py | 75 + .../selenium/webdriver/wpewebkit/__init__.py | 16 + .../selenium/webdriver/wpewebkit/options.py | 70 + .../selenium/webdriver/wpewebkit/service.py | 46 + .../selenium/webdriver/wpewebkit/webdriver.py | 70 + .../sniffio-1.2.0.dist-info/INSTALLER | 1 + .../sniffio-1.2.0.dist-info/LICENSE | 3 + .../sniffio-1.2.0.dist-info/LICENSE.APACHE2 | 202 + .../sniffio-1.2.0.dist-info/LICENSE.MIT | 20 + .../sniffio-1.2.0.dist-info/METADATA | 103 + .../sniffio-1.2.0.dist-info/RECORD | 19 + .../sniffio-1.2.0.dist-info/WHEEL | 5 + .../sniffio-1.2.0.dist-info/top_level.txt | 1 + .../Lib/site-packages/sniffio/__init__.py | 14 + .../Lib/site-packages/sniffio/_impl.py | 83 + .../site-packages/sniffio/_tests/__init__.py | 0 .../sniffio/_tests/test_sniffio.py | 67 + .../Lib/site-packages/sniffio/_version.py | 3 + .../Lib/site-packages/sniffio/py.typed | 0 .../python-3.7.2/Lib/site-packages/socks.py | 847 ++++ .../Lib/site-packages/sockshandler.py | 111 + .../INSTALLER | 1 + .../sortedcontainers-2.4.0.dist-info/LICENSE | 13 + .../sortedcontainers-2.4.0.dist-info/METADATA | 264 ++ .../sortedcontainers-2.4.0.dist-info/RECORD | 14 + .../sortedcontainers-2.4.0.dist-info/WHEEL | 6 + .../top_level.txt | 1 + .../sortedcontainers/__init__.py | 74 + .../sortedcontainers/sorteddict.py | 812 ++++ .../sortedcontainers/sortedlist.py | 2646 ++++++++++++ .../sortedcontainers/sortedset.py | 733 ++++ .../trio-0.21.0.dist-info/INSTALLER | 1 + .../trio-0.21.0.dist-info/LICENSE | 3 + .../trio-0.21.0.dist-info/LICENSE.APACHE2 | 202 + .../trio-0.21.0.dist-info/LICENSE.MIT | 22 + .../trio-0.21.0.dist-info/METADATA | 102 + .../trio-0.21.0.dist-info/RECORD | 260 ++ .../site-packages/trio-0.21.0.dist-info/WHEEL | 5 + .../trio-0.21.0.dist-info/top_level.txt | 1 + .../Lib/site-packages/trio/__init__.py | 132 + .../Lib/site-packages/trio/_abc.py | 652 +++ .../Lib/site-packages/trio/_channel.py | 386 ++ .../Lib/site-packages/trio/_core/__init__.py | 92 + .../site-packages/trio/_core/_asyncgens.py | 193 + .../site-packages/trio/_core/_entry_queue.py | 195 + .../site-packages/trio/_core/_exceptions.py | 114 + .../trio/_core/_generated_instrumentation.py | 47 + .../trio/_core/_generated_io_epoll.py | 35 + .../trio/_core/_generated_io_kqueue.py | 59 + .../trio/_core/_generated_io_windows.py | 83 + .../trio/_core/_generated_run.py | 241 ++ .../trio/_core/_instrumentation.py | 108 + .../site-packages/trio/_core/_io_common.py | 22 + .../Lib/site-packages/trio/_core/_io_epoll.py | 317 ++ .../site-packages/trio/_core/_io_kqueue.py | 196 + .../site-packages/trio/_core/_io_windows.py | 868 ++++ .../Lib/site-packages/trio/_core/_ki.py | 200 + .../Lib/site-packages/trio/_core/_local.py | 95 + .../site-packages/trio/_core/_mock_clock.py | 165 + .../site-packages/trio/_core/_multierror.py | 516 +++ .../site-packages/trio/_core/_parking_lot.py | 215 + .../Lib/site-packages/trio/_core/_run.py | 2393 +++++++++++ .../site-packages/trio/_core/_thread_cache.py | 171 + .../Lib/site-packages/trio/_core/_traps.py | 270 ++ .../trio/_core/_unbounded_queue.py | 149 + .../trio/_core/_wakeup_socketpair.py | 71 + .../site-packages/trio/_core/_windows_cffi.py | 323 ++ .../trio/_core/tests/__init__.py | 0 .../trio/_core/tests/conftest.py | 25 + .../trio/_core/tests/test_asyncgen.py | 320 ++ .../trio/_core/tests/test_guest_mode.py | 546 +++ .../trio/_core/tests/test_instrumentation.py | 253 ++ .../site-packages/trio/_core/tests/test_io.py | 447 ++ .../site-packages/trio/_core/tests/test_ki.py | 501 +++ .../trio/_core/tests/test_local.py | 115 + .../trio/_core/tests/test_mock_clock.py | 170 + .../trio/_core/tests/test_multierror.py | 772 ++++ .../tests/test_multierror_scripts/__init__.py | 2 + .../tests/test_multierror_scripts/_common.py | 7 + .../apport_excepthook.py | 13 + .../custom_excepthook.py | 18 + .../ipython_custom_exc.py | 36 + .../simple_excepthook.py | 21 + .../simple_excepthook_IPython.py | 7 + .../simple_excepthook_partial.py | 13 + .../trio/_core/tests/test_parking_lot.py | 197 + .../trio/_core/tests/test_run.py | 2333 +++++++++++ .../trio/_core/tests/test_thread_cache.py | 164 + .../trio/_core/tests/test_tutil.py | 13 + .../trio/_core/tests/test_unbounded_queue.py | 152 + .../trio/_core/tests/test_util.py | 1 + .../trio/_core/tests/test_windows.py | 218 + .../site-packages/trio/_core/tests/tutil.py | 146 + .../Lib/site-packages/trio/_deprecate.py | 133 + .../Lib/site-packages/trio/_file_io.py | 191 + .../site-packages/trio/_highlevel_generic.py | 107 + .../trio/_highlevel_open_tcp_listeners.py | 221 + .../trio/_highlevel_open_tcp_stream.py | 371 ++ .../trio/_highlevel_open_unix_stream.py | 49 + .../trio/_highlevel_serve_listeners.py | 121 + .../site-packages/trio/_highlevel_socket.py | 382 ++ .../trio/_highlevel_ssl_helpers.py | 154 + .../Lib/site-packages/trio/_path.py | 206 + .../Lib/site-packages/trio/_signals.py | 167 + .../Lib/site-packages/trio/_socket.py | 787 ++++ .../Lib/site-packages/trio/_ssl.py | 927 +++++ .../Lib/site-packages/trio/_subprocess.py | 744 ++++ .../trio/_subprocess_platform/__init__.py | 122 + .../trio/_subprocess_platform/kqueue.py | 41 + .../trio/_subprocess_platform/waitid.py | 107 + .../trio/_subprocess_platform/windows.py | 6 + .../Lib/site-packages/trio/_sync.py | 786 ++++ .../Lib/site-packages/trio/_threads.py | 372 ++ .../Lib/site-packages/trio/_timeouts.py | 130 + .../Lib/site-packages/trio/_tools/__init__.py | 0 .../site-packages/trio/_tools/gen_exports.py | 192 + .../Lib/site-packages/trio/_unix_pipes.py | 190 + .../Lib/site-packages/trio/_util.py | 341 ++ .../Lib/site-packages/trio/_version.py | 3 + .../site-packages/trio/_wait_for_object.py | 62 + .../Lib/site-packages/trio/_windows_pipes.py | 138 + .../Lib/site-packages/trio/abc.py | 21 + .../Lib/site-packages/trio/from_thread.py | 7 + .../Lib/site-packages/trio/lowlevel.py | 74 + .../Lib/site-packages/trio/socket.py | 200 + .../site-packages/trio/testing/__init__.py | 32 + .../trio/testing/_check_streams.py | 512 +++ .../trio/testing/_checkpoints.py | 62 + .../trio/testing/_memory_streams.py | 591 +++ .../site-packages/trio/testing/_network.py | 34 + .../site-packages/trio/testing/_sequencer.py | 82 + .../site-packages/trio/testing/_trio_test.py | 29 + .../Lib/site-packages/trio/tests/__init__.py | 0 .../Lib/site-packages/trio/tests/conftest.py | 41 + .../trio/tests/module_with_deprecations.py | 21 + .../Lib/site-packages/trio/tests/test_abc.py | 49 + .../site-packages/trio/tests/test_channel.py | 407 ++ .../trio/tests/test_contextvars.py | 52 + .../trio/tests/test_deprecate.py | 243 ++ .../site-packages/trio/tests/test_exports.py | 145 + .../site-packages/trio/tests/test_file_io.py | 198 + .../trio/tests/test_highlevel_generic.py | 94 + .../test_highlevel_open_tcp_listeners.py | 295 ++ .../tests/test_highlevel_open_tcp_stream.py | 571 +++ .../tests/test_highlevel_open_unix_stream.py | 67 + .../tests/test_highlevel_serve_listeners.py | 145 + .../trio/tests/test_highlevel_socket.py | 267 ++ .../trio/tests/test_highlevel_ssl_helpers.py | 113 + .../Lib/site-packages/trio/tests/test_path.py | 262 ++ .../trio/tests/test_scheduler_determinism.py | 40 + .../site-packages/trio/tests/test_signals.py | 177 + .../site-packages/trio/tests/test_socket.py | 1015 +++++ .../Lib/site-packages/trio/tests/test_ssl.py | 1303 ++++++ .../trio/tests/test_subprocess.py | 602 +++ .../Lib/site-packages/trio/tests/test_sync.py | 570 +++ .../site-packages/trio/tests/test_testing.py | 657 +++ .../site-packages/trio/tests/test_threads.py | 740 ++++ .../site-packages/trio/tests/test_timeouts.py | 104 + .../trio/tests/test_unix_pipes.py | 276 ++ .../Lib/site-packages/trio/tests/test_util.py | 193 + .../trio/tests/test_wait_for_object.py | 220 + .../trio/tests/test_windows_pipes.py | 110 + .../trio/tests/tools/__init__.py | 0 .../trio/tests/tools/test_gen_exports.py | 72 + .../Lib/site-packages/trio/to_thread.py | 2 + .../trio_websocket-0.9.2.dist-info/INSTALLER | 1 + .../trio_websocket-0.9.2.dist-info/LICENSE | 21 + .../trio_websocket-0.9.2.dist-info/METADATA | 121 + .../trio_websocket-0.9.2.dist-info/RECORD | 12 + .../trio_websocket-0.9.2.dist-info/WHEEL | 5 + .../top_level.txt | 1 + .../site-packages/trio_websocket/__init__.py | 20 + .../Lib/site-packages/trio_websocket/_impl.py | 1428 +++++++ .../site-packages/trio_websocket/_version.py | 1 + .../INSTALLER | 1 + .../typing_extensions-4.3.0.dist-info/LICENSE | 254 ++ .../METADATA | 176 + .../typing_extensions-4.3.0.dist-info/RECORD | 7 + .../typing_extensions-4.3.0.dist-info/WHEEL | 4 + .../Lib/site-packages/typing_extensions.py | 2069 ++++++++++ .../urllib3-1.25.6.dist-info/RECORD | 78 - .../urllib3-1.26.12.dist-info/INSTALLER | 1 + .../LICENSE.txt | 2 +- .../METADATA | 351 +- .../urllib3-1.26.12.dist-info/RECORD | 82 + .../urllib3-1.26.12.dist-info/WHEEL | 6 + .../top_level.txt | 0 .../Lib/site-packages/urllib3/__init__.py | 36 +- .../Lib/site-packages/urllib3/_collections.py | 9 +- .../Lib/site-packages/urllib3/_version.py | 2 + .../Lib/site-packages/urllib3/connection.py | 317 +- .../site-packages/urllib3/connectionpool.py | 257 +- .../urllib3/contrib/_appengine_environ.py | 28 +- .../contrib/_securetransport/bindings.py | 63 +- .../contrib/_securetransport/low_level.py | 75 +- .../urllib3/contrib/appengine.py | 19 +- .../site-packages/urllib3/contrib/ntlmpool.py | 13 +- .../urllib3/contrib/pyopenssl.py | 53 +- .../urllib3/contrib/securetransport.py | 105 +- .../site-packages/urllib3/contrib/socks.py | 22 +- .../Lib/site-packages/urllib3/exceptions.py | 146 +- .../Lib/site-packages/urllib3/fields.py | 5 +- .../Lib/site-packages/urllib3/filepost.py | 4 +- .../urllib3/packages/__init__.py | 5 - .../urllib3/packages/backports/makefile.py | 1 - .../Lib/site-packages/urllib3/packages/six.py | 125 +- .../packages/ssl_match_hostname/__init__.py | 19 - .../Lib/site-packages/urllib3/poolmanager.py | 107 +- .../Lib/site-packages/urllib3/request.py | 9 +- .../Lib/site-packages/urllib3/response.py | 141 +- .../site-packages/urllib3/util/__init__.py | 17 +- .../site-packages/urllib3/util/connection.py | 21 +- .../Lib/site-packages/urllib3/util/proxy.py | 57 + .../Lib/site-packages/urllib3/util/queue.py | 1 + .../Lib/site-packages/urllib3/util/request.py | 19 +- .../site-packages/urllib3/util/response.py | 31 +- .../Lib/site-packages/urllib3/util/retry.py | 244 +- .../Lib/site-packages/urllib3/util/ssl_.py | 170 +- .../ssl_match_hostname.py} | 21 +- .../urllib3/util/ssltransport.py | 221 + .../Lib/site-packages/urllib3/util/timeout.py | 56 +- .../Lib/site-packages/urllib3/util/url.py | 42 +- .../Lib/site-packages/urllib3/util/wait.py | 7 +- .../wsproto-1.2.0.dist-info/INSTALLER | 1 + .../wsproto-1.2.0.dist-info/LICENSE | 21 + .../wsproto-1.2.0.dist-info/METADATA | 177 + .../wsproto-1.2.0.dist-info/RECORD | 23 + .../wsproto-1.2.0.dist-info/WHEEL | 5 + .../wsproto-1.2.0.dist-info/top_level.txt | 1 + .../Lib/site-packages/wsproto/__init__.py | 94 + .../Lib/site-packages/wsproto/connection.py | 189 + .../Lib/site-packages/wsproto/events.py | 295 ++ .../Lib/site-packages/wsproto/extensions.py | 315 ++ .../site-packages/wsproto/frame_protocol.py | 673 +++ .../Lib/site-packages/wsproto/handshake.py | 491 +++ .../Lib/site-packages/wsproto/py.typed | 1 + .../Lib/site-packages/wsproto/typing.py | 3 + .../Lib/site-packages/wsproto/utilities.py | 88 + .../pyOpenRPA-1.2.14.dist-info/INSTALLER | 1 + .../pyOpenRPA-1.2.14.dist-info}/METADATA | 17 +- .../RECORD | 62 +- .../pyOpenRPA-1.2.14.dist-info/REQUESTED | 0 .../WHEEL | 0 .../top_level.txt | 0 .../Lib/site-packages/pyOpenRPA/LICENSE.pdf | Bin 321175 -> 4322139 bytes .../Orchestrator/BackwardCompatibility.py | 5 +- .../Orchestrator/Managers/ControlPanel.py | 9 +- .../Orchestrator/RobotRDPActive/Clipboard.py | 27 +- .../Orchestrator/RobotRDPActive/Connector.py | 48 +- .../Orchestrator/RobotScreenActive/Monitor.py | 22 +- .../pyOpenRPA/Orchestrator/Server.py | 12 +- .../pyOpenRPA/Orchestrator/ServerSettings.py | 25 +- .../Orchestrator/__Orchestrator__.py | 60 +- .../pyOpenRPA/Robot/Clipboard.py | 31 +- .../site-packages/pyOpenRPA/Robot/Keyboard.py | 483 ++- .../site-packages/pyOpenRPA/Robot/Mouse.py | 24 +- .../site-packages/pyOpenRPA/Robot/Screen.py | 672 ++- .../pyOpenRPA/Robot/UIDesktop.py | 131 +- .../site-packages/pyOpenRPA/Robot/UIWeb.py | 628 ++- .../pyOpenRPA/Robot/Utils/ProcessBitness.py | 4 +- .../site-packages/pyOpenRPA/Robot/__init__.py | 4 +- .../pyOpenRPA/Studio/Web/Index.xhtml | 14 +- .../site-packages/pyOpenRPA/Tools/CrossOS.py | 54 + .../site-packages/pyOpenRPA/Tools/License.py | 5 +- .../site-packages/pyOpenRPA/Tools/Template.py | 127 + .../Lib/site-packages/pyOpenRPA/__init__.py | 2 +- Sources/GuideSphinx/make_RUS_Guide_PDF.cmd | 2 +- Sources/pyOpenRPA/__init__.py | 2 +- .../doctrees/01_HowToInstall.doctree | Bin 12531 -> 24097 bytes .../doctrees/03_Copyrights_Contacts.doctree | Bin 31798 -> 31784 bytes Wiki/RUS_Guide/doctrees/Agent/02_Defs.doctree | Bin 53912 -> 53408 bytes .../Orchestrator/01_Orchestrator.doctree | Bin 25294 -> 25280 bytes .../doctrees/Orchestrator/02_Defs.doctree | Bin 856336 -> 851087 bytes .../Orchestrator/03_gSettingsTemplate.doctree | Bin 50877 -> 50863 bytes .../doctrees/Orchestrator/04_HowToUse.doctree | Bin 15815 -> 15801 bytes .../doctrees/Orchestrator/05_UAC.doctree | Bin 16181 -> 16167 bytes .../RUS_Guide/doctrees/Robot/01_Robot.doctree | Bin 30098 -> 30084 bytes .../doctrees/Robot/02_uidesktop.doctree | Bin 429418 -> 429534 bytes .../RUS_Guide/doctrees/Robot/03_uiweb.doctree | Bin 11743 -> 204786 bytes .../doctrees/Robot/04_keyboard.doctree | Bin 123685 -> 131401 bytes .../doctrees/Robot/05_clipboard.doctree | Bin 19848 -> 21448 bytes .../RUS_Guide/doctrees/Robot/06_mouse.doctree | Bin 121164 -> 121637 bytes .../doctrees/Robot/07_screen.doctree | Bin 272327 -> 277044 bytes .../doctrees/Robot/08_HowToUse.doctree | Bin 22050 -> 22036 bytes .../doctrees/Studio/01_Studio.doctree | Bin 13094 -> 13080 bytes .../doctrees/Studio/02_HowToUse.doctree | Bin 33118 -> 33104 bytes Wiki/RUS_Guide/doctrees/Tools/02_Defs.doctree | Bin 18806 -> 18526 bytes Wiki/RUS_Guide/doctrees/environment.pickle | Bin 546877 -> 596723 bytes Wiki/RUS_Guide/doctrees/index.doctree | Bin 74120 -> 74106 bytes Wiki/RUS_Guide/html/.buildinfo | 2 +- Wiki/RUS_Guide/html/01_HowToInstall.html | 64 +- .../html/03_Copyrights_Contacts.html | 14 +- Wiki/RUS_Guide/html/Agent/02_Defs.html | 10 +- .../html/Orchestrator/01_Orchestrator.html | 10 +- Wiki/RUS_Guide/html/Orchestrator/02_Defs.html | 12 +- .../Orchestrator/03_gSettingsTemplate.html | 10 +- .../html/Orchestrator/04_HowToUse.html | 10 +- Wiki/RUS_Guide/html/Orchestrator/05_UAC.html | 10 +- Wiki/RUS_Guide/html/Robot/01_Robot.html | 10 +- Wiki/RUS_Guide/html/Robot/02_uidesktop.html | 143 +- Wiki/RUS_Guide/html/Robot/03_uiweb.html | 667 ++- Wiki/RUS_Guide/html/Robot/04_keyboard.html | 81 +- Wiki/RUS_Guide/html/Robot/05_clipboard.html | 29 +- Wiki/RUS_Guide/html/Robot/06_mouse.html | 47 +- Wiki/RUS_Guide/html/Robot/07_screen.html | 124 +- Wiki/RUS_Guide/html/Robot/08_HowToUse.html | 10 +- Wiki/RUS_Guide/html/Studio/01_Studio.html | 10 +- Wiki/RUS_Guide/html/Studio/02_HowToUse.html | 10 +- Wiki/RUS_Guide/html/Tools/02_Defs.html | 10 +- Wiki/RUS_Guide/html/_modules/index.html | 9 +- .../_modules/pyOpenRPA/Agent/__Agent__.html | 8 +- .../Orchestrator/__Orchestrator__.html | 8 +- .../_modules/pyOpenRPA/Robot/Clipboard.html | 14 +- .../_modules/pyOpenRPA/Robot/Keyboard.html | 477 ++- .../html/_modules/pyOpenRPA/Robot/Mouse.html | 22 +- .../html/_modules/pyOpenRPA/Robot/Screen.html | 197 +- .../_modules/pyOpenRPA/Robot/UIDesktop.html | 119 +- .../html/_modules/pyOpenRPA/Robot/UIWeb.html | 863 ++++ .../_modules/pyOpenRPA/Tools/Debugger.html | 8 +- .../_modules/pyOpenRPA/Tools/StopSafe.html | 8 +- .../html/_sources/01_HowToInstall.rst.txt | 47 +- .../html/_sources/Robot/02_uidesktop.rst.txt | 1 + .../html/_sources/Robot/03_uiweb.rst.txt | 15 +- .../html/_sources/Robot/04_keyboard.rst.txt | 17 + .../html/_sources/Robot/05_clipboard.rst.txt | 6 + .../html/_sources/Robot/06_mouse.rst.txt | 2 + .../html/_sources/Robot/07_screen.rst.txt | 4 +- .../html/_static/documentation_options.js | 2 +- Wiki/RUS_Guide/html/genindex.html | 75 +- Wiki/RUS_Guide/html/index.html | 39 +- Wiki/RUS_Guide/html/objects.inv | Bin 2735 -> 2919 bytes Wiki/RUS_Guide/html/py-modindex.html | 13 +- Wiki/RUS_Guide/html/search.html | 8 +- Wiki/RUS_Guide/html/searchindex.js | 2 +- Wiki/RUS_Guide/markdown/01_HowToInstall.md | 54 +- .../markdown/03_Copyrights_Contacts.md | 2 +- Wiki/RUS_Guide/markdown/Agent/02_Defs.md | 2 +- .../markdown/Orchestrator/01_Orchestrator.md | 2 +- .../markdown/Orchestrator/02_Defs.md | 2 +- .../Orchestrator/03_gSettingsTemplate.md | 2 +- .../markdown/Orchestrator/04_HowToUse.md | 2 +- .../RUS_Guide/markdown/Orchestrator/05_UAC.md | 2 +- Wiki/RUS_Guide/markdown/Robot/01_Robot.md | 2 +- Wiki/RUS_Guide/markdown/Robot/02_uidesktop.md | 160 +- Wiki/RUS_Guide/markdown/Robot/03_uiweb.md | 777 +++- Wiki/RUS_Guide/markdown/Robot/04_keyboard.md | 67 +- Wiki/RUS_Guide/markdown/Robot/05_clipboard.md | 16 +- Wiki/RUS_Guide/markdown/Robot/06_mouse.md | 34 +- Wiki/RUS_Guide/markdown/Robot/07_screen.md | 142 +- Wiki/RUS_Guide/markdown/Robot/08_HowToUse.md | 2 +- Wiki/RUS_Guide/markdown/Studio/01_Studio.md | 2 +- Wiki/RUS_Guide/markdown/Studio/02_HowToUse.md | 2 +- Wiki/RUS_Guide/markdown/Tools/02_Defs.md | 6 +- Wiki/RUS_Guide/markdown/index.md | 23 +- Wiki/RUS_Guide/pdf/pyOpenRPA_Guide_RUS.pdf | Bin 1406790 -> 1497993 bytes 895 files changed, 219355 insertions(+), 8560 deletions(-) rename Resources/WPy32-3720/python-3.7.2/Lib/site-packages/{certifi-2019.9.11.dist-info => Jinja2-3.1.2.dist-info}/INSTALLER (100%) create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/Jinja2-3.1.2.dist-info/LICENSE.rst create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/Jinja2-3.1.2.dist-info/METADATA create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/Jinja2-3.1.2.dist-info/RECORD create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/Jinja2-3.1.2.dist-info/WHEEL create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/Jinja2-3.1.2.dist-info/entry_points.txt create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/Jinja2-3.1.2.dist-info/top_level.txt rename Resources/WPy32-3720/python-3.7.2/Lib/site-packages/{cffi-1.12.3.dist-info => MarkupSafe-2.1.1.dist-info}/INSTALLER (100%) create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/MarkupSafe-2.1.1.dist-info/LICENSE.rst create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/MarkupSafe-2.1.1.dist-info/METADATA create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/MarkupSafe-2.1.1.dist-info/RECORD rename Resources/WPy32-3720/python-3.7.2/Lib/site-packages/{cffi-1.12.3.dist-info => MarkupSafe-2.1.1.dist-info}/WHEEL (67%) create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/MarkupSafe-2.1.1.dist-info/top_level.txt rename Resources/WPy32-3720/python-3.7.2/Lib/site-packages/{psutil-5.6.1.dist-info => PySocks-1.7.1.dist-info}/INSTALLER (100%) create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/PySocks-1.7.1.dist-info/LICENSE create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/PySocks-1.7.1.dist-info/METADATA create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/PySocks-1.7.1.dist-info/RECORD create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/PySocks-1.7.1.dist-info/WHEEL create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/PySocks-1.7.1.dist-info/top_level.txt rename Resources/WPy32-3720/python-3.7.2/Lib/site-packages/{pyOpenRPA-1.2.13.dist-info => async_generator-1.10.dist-info}/INSTALLER (100%) create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/async_generator-1.10.dist-info/METADATA create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/async_generator-1.10.dist-info/RECORD create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/async_generator-1.10.dist-info/WHEEL create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/async_generator-1.10.dist-info/top_level.txt create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/async_generator/__init__.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/async_generator/_impl.py rename Resources/WPy32-3720/python-3.7.2/Lib/site-packages/{pyOpenRPA-1.2.13.dist-info/REQUESTED => async_generator/_tests/__init__.py} (100%) create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/async_generator/_tests/conftest.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/async_generator/_tests/test_async_generator.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/async_generator/_tests/test_util.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/async_generator/_util.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/async_generator/_version.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/attr/__init__.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/attr/__init__.pyi create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/attr/_cmp.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/attr/_cmp.pyi create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/attr/_compat.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/attr/_config.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/attr/_funcs.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/attr/_make.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/attr/_next_gen.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/attr/_version_info.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/attr/_version_info.pyi create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/attr/converters.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/attr/converters.pyi create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/attr/exceptions.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/attr/exceptions.pyi create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/attr/filters.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/attr/filters.pyi rename Resources/{WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA-1.2.13.dist-info/REQUESTED => WPy32-3720/python-3.7.2/Lib/site-packages/attr/py.typed} (100%) create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/attr/setters.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/attr/setters.pyi create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/attr/validators.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/attr/validators.pyi create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/attrs-22.1.0.dist-info/AUTHORS.rst rename Resources/WPy32-3720/python-3.7.2/Lib/site-packages/{urllib3-1.25.6.dist-info => attrs-22.1.0.dist-info}/INSTALLER (100%) create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/attrs-22.1.0.dist-info/LICENSE create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/attrs-22.1.0.dist-info/METADATA create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/attrs-22.1.0.dist-info/RECORD rename Resources/WPy32-3720/python-3.7.2/Lib/site-packages/{certifi-2019.9.11.dist-info => attrs-22.1.0.dist-info}/WHEEL (69%) create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/attrs-22.1.0.dist-info/top_level.txt create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/attrs/__init__.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/attrs/__init__.pyi create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/attrs/converters.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/attrs/exceptions.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/attrs/filters.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/attrs/py.typed create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/attrs/setters.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/attrs/validators.py delete mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/certifi-2019.9.11.dist-info/DESCRIPTION.rst delete mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/certifi-2019.9.11.dist-info/RECORD delete mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/certifi-2019.9.11.dist-info/metadata.json rename Resources/{WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA-1.2.13.dist-info => WPy32-3720/python-3.7.2/Lib/site-packages/certifi-2022.6.15.dist-info}/INSTALLER (100%) create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/certifi-2022.6.15.dist-info/LICENSE rename Resources/WPy32-3720/python-3.7.2/Lib/site-packages/{certifi-2019.9.11.dist-info => certifi-2022.6.15.dist-info}/METADATA (66%) create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/certifi-2022.6.15.dist-info/RECORD create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/certifi-2022.6.15.dist-info/WHEEL rename Resources/WPy32-3720/python-3.7.2/Lib/site-packages/{certifi-2019.9.11.dist-info => certifi-2022.6.15.dist-info}/top_level.txt (100%) create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/certifi/py.typed delete mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/cffi-1.12.3.dist-info/RECORD create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/cffi-1.15.1.dist-info/INSTALLER rename Resources/WPy32-3720/python-3.7.2/Lib/site-packages/{cffi-1.12.3.dist-info => cffi-1.15.1.dist-info}/LICENSE (100%) rename Resources/WPy32-3720/python-3.7.2/Lib/site-packages/{cffi-1.12.3.dist-info => cffi-1.15.1.dist-info}/METADATA (74%) create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/cffi-1.15.1.dist-info/RECORD rename Resources/WPy32-3720/python-3.7.2/Lib/site-packages/{psutil-5.6.1.dist-info => cffi-1.15.1.dist-info}/WHEEL (67%) rename Resources/WPy32-3720/python-3.7.2/Lib/site-packages/{cffi-1.12.3.dist-info => cffi-1.15.1.dist-info}/entry_points.txt (98%) rename Resources/WPy32-3720/python-3.7.2/Lib/site-packages/{cffi-1.12.3.dist-info => cffi-1.15.1.dist-info}/top_level.txt (100%) create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/h11-0.13.0.dist-info/INSTALLER create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/h11-0.13.0.dist-info/LICENSE.txt create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/h11-0.13.0.dist-info/METADATA create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/h11-0.13.0.dist-info/RECORD create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/h11-0.13.0.dist-info/WHEEL create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/h11-0.13.0.dist-info/top_level.txt create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/h11/__init__.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/h11/_abnf.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/h11/_connection.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/h11/_events.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/h11/_headers.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/h11/_readers.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/h11/_receivebuffer.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/h11/_state.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/h11/_util.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/h11/_version.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/h11/_writers.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/h11/py.typed create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/h11/tests/__init__.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/h11/tests/data/test-file create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/h11/tests/helpers.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/h11/tests/test_against_stdlib_http.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/h11/tests/test_connection.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/h11/tests/test_events.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/h11/tests/test_headers.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/h11/tests/test_helpers.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/h11/tests/test_io.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/h11/tests/test_receivebuffer.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/h11/tests/test_state.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/h11/tests/test_util.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/jinja2/__init__.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/jinja2/_identifier.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/jinja2/async_utils.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/jinja2/bccache.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/jinja2/compiler.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/jinja2/constants.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/jinja2/debug.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/jinja2/defaults.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/jinja2/environment.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/jinja2/exceptions.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/jinja2/ext.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/jinja2/filters.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/jinja2/idtracking.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/jinja2/lexer.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/jinja2/loaders.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/jinja2/meta.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/jinja2/nativetypes.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/jinja2/nodes.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/jinja2/optimizer.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/jinja2/parser.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/jinja2/py.typed create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/jinja2/runtime.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/jinja2/sandbox.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/jinja2/tests.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/jinja2/utils.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/jinja2/visitor.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/markupsafe/__init__.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/markupsafe/_native.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/markupsafe/_speedups.cp37-win32.pyd create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/markupsafe/_speedups.pyi create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/markupsafe/py.typed create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/outcome-1.2.0.dist-info/INSTALLER create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/outcome-1.2.0.dist-info/LICENSE create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/outcome-1.2.0.dist-info/LICENSE.APACHE2 create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/outcome-1.2.0.dist-info/LICENSE.MIT create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/outcome-1.2.0.dist-info/METADATA create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/outcome-1.2.0.dist-info/RECORD rename Resources/WPy32-3720/python-3.7.2/Lib/site-packages/{urllib3-1.25.6.dist-info => outcome-1.2.0.dist-info}/WHEEL (100%) create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/outcome-1.2.0.dist-info/top_level.txt create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/outcome/__init__.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/outcome/_impl.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/outcome/_util.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/outcome/_version.py delete mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/psutil-5.6.1.dist-info/RECORD create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/psutil-5.9.1.dist-info/INSTALLER rename Resources/WPy32-3720/python-3.7.2/Lib/site-packages/{psutil-5.6.1.dist-info => psutil-5.9.1.dist-info}/LICENSE (96%) rename Resources/WPy32-3720/python-3.7.2/Lib/site-packages/{psutil-5.6.1.dist-info => psutil-5.9.1.dist-info}/METADATA (72%) create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/psutil-5.9.1.dist-info/RECORD create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/psutil-5.9.1.dist-info/WHEEL rename Resources/WPy32-3720/python-3.7.2/Lib/site-packages/{psutil-5.6.1.dist-info => psutil-5.9.1.dist-info}/top_level.txt (100%) create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/psutil/tests/runner.py rename Resources/WPy32-3720/python-3.7.2/Lib/site-packages/psutil/tests/{test_memory_leaks.py => test_memleaks.py} (50%) create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/psutil/tests/test_testutils.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.2.14.dist-info/INSTALLER rename Resources/{WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA-1.2.13.dist-info => WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.2.14.dist-info}/METADATA (86%) rename Resources/WPy32-3720/python-3.7.2/Lib/site-packages/{pyOpenRPA-1.2.13.dist-info => pyOpenRPA-1.2.14.dist-info}/RECORD (92%) create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.2.14.dist-info/REQUESTED rename Resources/WPy32-3720/python-3.7.2/Lib/site-packages/{pyOpenRPA-1.2.13.dist-info => pyOpenRPA-1.2.14.dist-info}/WHEEL (100%) rename Resources/WPy32-3720/python-3.7.2/Lib/site-packages/{pyOpenRPA-1.2.13.dist-info => pyOpenRPA-1.2.14.dist-info}/top_level.txt (100%) create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA/Tools/CrossOS.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA/Tools/Template.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium-4.4.3.dist-info/INSTALLER create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium-4.4.3.dist-info/METADATA create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium-4.4.3.dist-info/RECORD create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium-4.4.3.dist-info/WHEEL create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/__init__.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/common/__init__.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/common/exceptions.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/py.typed create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/types.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/__init__.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/chrome/__init__.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/chrome/options.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/chrome/service.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/chrome/webdriver.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/chromium/__init__.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/chromium/options.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/chromium/remote_connection.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/chromium/service.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/chromium/webdriver.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/__init__.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/action_chains.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/actions/__init__.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/actions/action_builder.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/actions/input_device.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/actions/interaction.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/actions/key_actions.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/actions/key_input.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/actions/mouse_button.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/actions/pointer_actions.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/actions/pointer_input.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/actions/wheel_actions.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/actions/wheel_input.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/alert.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/bidi/__init__.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/bidi/cdp.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/bidi/console.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/by.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/desired_capabilities.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/devtools/v102/__init__.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/devtools/v102/accessibility.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/devtools/v102/animation.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/devtools/v102/audits.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/devtools/v102/background_service.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/devtools/v102/browser.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/devtools/v102/cache_storage.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/devtools/v102/cast.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/devtools/v102/console.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/devtools/v102/css.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/devtools/v102/database.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/devtools/v102/debugger.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/devtools/v102/device_orientation.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/devtools/v102/dom.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/devtools/v102/dom_debugger.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/devtools/v102/dom_snapshot.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/devtools/v102/dom_storage.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/devtools/v102/emulation.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/devtools/v102/event_breakpoints.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/devtools/v102/fetch.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/devtools/v102/headless_experimental.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/devtools/v102/heap_profiler.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/devtools/v102/indexed_db.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/devtools/v102/input_.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/devtools/v102/inspector.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/devtools/v102/io.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/devtools/v102/layer_tree.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/devtools/v102/log.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/devtools/v102/media.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/devtools/v102/memory.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/devtools/v102/network.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/devtools/v102/overlay.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/devtools/v102/page.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/devtools/v102/performance.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/devtools/v102/performance_timeline.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/devtools/v102/profiler.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/devtools/v102/py.typed create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/devtools/v102/runtime.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/devtools/v102/schema.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/devtools/v102/security.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/devtools/v102/service_worker.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/devtools/v102/storage.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/devtools/v102/system_info.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/devtools/v102/target.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/devtools/v102/tethering.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/devtools/v102/tracing.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/devtools/v102/util.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/devtools/v102/web_audio.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/devtools/v102/web_authn.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/devtools/v103/__init__.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/devtools/v103/accessibility.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/devtools/v103/animation.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/devtools/v103/audits.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/devtools/v103/background_service.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/devtools/v103/browser.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/devtools/v103/cache_storage.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/devtools/v103/cast.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/devtools/v103/console.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/devtools/v103/css.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/devtools/v103/database.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/devtools/v103/debugger.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/devtools/v103/device_orientation.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/devtools/v103/dom.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/devtools/v103/dom_debugger.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/devtools/v103/dom_snapshot.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/devtools/v103/dom_storage.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/devtools/v103/emulation.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/devtools/v103/event_breakpoints.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/devtools/v103/fetch.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/devtools/v103/headless_experimental.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/devtools/v103/heap_profiler.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/devtools/v103/indexed_db.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/devtools/v103/input_.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/devtools/v103/inspector.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/devtools/v103/io.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/devtools/v103/layer_tree.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/devtools/v103/log.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/devtools/v103/media.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/devtools/v103/memory.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/devtools/v103/network.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/devtools/v103/overlay.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/devtools/v103/page.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/devtools/v103/performance.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/devtools/v103/performance_timeline.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/devtools/v103/profiler.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/devtools/v103/py.typed create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/devtools/v103/runtime.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/devtools/v103/schema.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/devtools/v103/security.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/devtools/v103/service_worker.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/devtools/v103/storage.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/devtools/v103/system_info.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/devtools/v103/target.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/devtools/v103/tethering.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/devtools/v103/tracing.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/devtools/v103/util.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/devtools/v103/web_audio.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/devtools/v103/web_authn.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/devtools/v104/__init__.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/devtools/v104/accessibility.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/devtools/v104/animation.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/devtools/v104/audits.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/devtools/v104/background_service.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/devtools/v104/browser.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/devtools/v104/cache_storage.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/devtools/v104/cast.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/devtools/v104/console.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/devtools/v104/css.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/devtools/v104/database.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/devtools/v104/debugger.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/devtools/v104/device_orientation.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/devtools/v104/dom.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/devtools/v104/dom_debugger.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/devtools/v104/dom_snapshot.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/devtools/v104/dom_storage.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/devtools/v104/emulation.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/devtools/v104/event_breakpoints.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/devtools/v104/fetch.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/devtools/v104/headless_experimental.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/devtools/v104/heap_profiler.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/devtools/v104/indexed_db.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/devtools/v104/input_.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/devtools/v104/inspector.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/devtools/v104/io.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/devtools/v104/layer_tree.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/devtools/v104/log.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/devtools/v104/media.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/devtools/v104/memory.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/devtools/v104/network.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/devtools/v104/overlay.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/devtools/v104/page.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/devtools/v104/performance.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/devtools/v104/performance_timeline.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/devtools/v104/profiler.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/devtools/v104/py.typed create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/devtools/v104/runtime.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/devtools/v104/schema.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/devtools/v104/security.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/devtools/v104/service_worker.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/devtools/v104/storage.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/devtools/v104/system_info.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/devtools/v104/target.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/devtools/v104/tethering.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/devtools/v104/tracing.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/devtools/v104/util.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/devtools/v104/web_audio.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/devtools/v104/web_authn.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/devtools/v85/__init__.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/devtools/v85/accessibility.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/devtools/v85/animation.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/devtools/v85/application_cache.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/devtools/v85/audits.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/devtools/v85/background_service.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/devtools/v85/browser.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/devtools/v85/cache_storage.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/devtools/v85/cast.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/devtools/v85/console.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/devtools/v85/css.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/devtools/v85/database.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/devtools/v85/debugger.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/devtools/v85/device_orientation.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/devtools/v85/dom.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/devtools/v85/dom_debugger.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/devtools/v85/dom_snapshot.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/devtools/v85/dom_storage.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/devtools/v85/emulation.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/devtools/v85/fetch.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/devtools/v85/headless_experimental.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/devtools/v85/heap_profiler.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/devtools/v85/indexed_db.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/devtools/v85/input_.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/devtools/v85/inspector.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/devtools/v85/io.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/devtools/v85/layer_tree.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/devtools/v85/log.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/devtools/v85/media.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/devtools/v85/memory.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/devtools/v85/network.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/devtools/v85/overlay.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/devtools/v85/page.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/devtools/v85/performance.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/devtools/v85/profiler.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/devtools/v85/py.typed create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/devtools/v85/runtime.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/devtools/v85/schema.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/devtools/v85/security.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/devtools/v85/service_worker.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/devtools/v85/storage.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/devtools/v85/system_info.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/devtools/v85/target.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/devtools/v85/tethering.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/devtools/v85/tracing.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/devtools/v85/util.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/devtools/v85/web_audio.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/devtools/v85/web_authn.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/html5/__init__.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/html5/application_cache.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/keys.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/log.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/mutation-listener.js create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/options.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/print_page_options.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/proxy.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/service.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/timeouts.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/utils.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/virtual_authenticator.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/common/window.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/edge/__init__.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/edge/options.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/edge/service.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/edge/webdriver.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/firefox/__init__.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/firefox/extension_connection.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/firefox/firefox_binary.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/firefox/firefox_profile.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/firefox/options.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/firefox/remote_connection.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/firefox/service.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/firefox/webdriver.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/firefox/webdriver_prefs.json create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/ie/__init__.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/ie/options.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/ie/service.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/ie/webdriver.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/remote/__init__.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/remote/bidi_connection.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/remote/command.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/remote/errorhandler.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/remote/file_detector.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/remote/findElements.js create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/remote/getAttribute.js create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/remote/isDisplayed.js create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/remote/mobile.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/remote/remote_connection.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/remote/script_key.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/remote/shadowroot.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/remote/switch_to.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/remote/utils.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/remote/webdriver.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/remote/webelement.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/safari/__init__.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/safari/options.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/safari/permissions.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/safari/remote_connection.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/safari/service.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/safari/webdriver.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/support/__init__.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/support/abstract_event_listener.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/support/color.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/support/event_firing_webdriver.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/support/events.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/support/expected_conditions.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/support/relative_locator.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/support/select.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/support/ui.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/support/wait.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/webkitgtk/__init__.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/webkitgtk/options.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/webkitgtk/service.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/webkitgtk/webdriver.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/wpewebkit/__init__.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/wpewebkit/options.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/wpewebkit/service.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/selenium/webdriver/wpewebkit/webdriver.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/sniffio-1.2.0.dist-info/INSTALLER create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/sniffio-1.2.0.dist-info/LICENSE create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/sniffio-1.2.0.dist-info/LICENSE.APACHE2 create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/sniffio-1.2.0.dist-info/LICENSE.MIT create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/sniffio-1.2.0.dist-info/METADATA create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/sniffio-1.2.0.dist-info/RECORD create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/sniffio-1.2.0.dist-info/WHEEL create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/sniffio-1.2.0.dist-info/top_level.txt create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/sniffio/__init__.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/sniffio/_impl.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/sniffio/_tests/__init__.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/sniffio/_tests/test_sniffio.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/sniffio/_version.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/sniffio/py.typed create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/socks.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/sockshandler.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/sortedcontainers-2.4.0.dist-info/INSTALLER create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/sortedcontainers-2.4.0.dist-info/LICENSE create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/sortedcontainers-2.4.0.dist-info/METADATA create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/sortedcontainers-2.4.0.dist-info/RECORD create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/sortedcontainers-2.4.0.dist-info/WHEEL create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/sortedcontainers-2.4.0.dist-info/top_level.txt create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/sortedcontainers/__init__.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/sortedcontainers/sorteddict.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/sortedcontainers/sortedlist.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/sortedcontainers/sortedset.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/trio-0.21.0.dist-info/INSTALLER create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/trio-0.21.0.dist-info/LICENSE create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/trio-0.21.0.dist-info/LICENSE.APACHE2 create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/trio-0.21.0.dist-info/LICENSE.MIT create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/trio-0.21.0.dist-info/METADATA create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/trio-0.21.0.dist-info/RECORD create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/trio-0.21.0.dist-info/WHEEL create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/trio-0.21.0.dist-info/top_level.txt create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/trio/__init__.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/trio/_abc.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/trio/_channel.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/trio/_core/__init__.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/trio/_core/_asyncgens.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/trio/_core/_entry_queue.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/trio/_core/_exceptions.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/trio/_core/_generated_instrumentation.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/trio/_core/_generated_io_epoll.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/trio/_core/_generated_io_kqueue.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/trio/_core/_generated_io_windows.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/trio/_core/_generated_run.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/trio/_core/_instrumentation.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/trio/_core/_io_common.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/trio/_core/_io_epoll.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/trio/_core/_io_kqueue.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/trio/_core/_io_windows.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/trio/_core/_ki.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/trio/_core/_local.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/trio/_core/_mock_clock.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/trio/_core/_multierror.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/trio/_core/_parking_lot.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/trio/_core/_run.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/trio/_core/_thread_cache.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/trio/_core/_traps.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/trio/_core/_unbounded_queue.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/trio/_core/_wakeup_socketpair.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/trio/_core/_windows_cffi.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/trio/_core/tests/__init__.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/trio/_core/tests/conftest.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/trio/_core/tests/test_asyncgen.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/trio/_core/tests/test_guest_mode.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/trio/_core/tests/test_instrumentation.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/trio/_core/tests/test_io.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/trio/_core/tests/test_ki.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/trio/_core/tests/test_local.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/trio/_core/tests/test_mock_clock.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/trio/_core/tests/test_multierror.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/trio/_core/tests/test_multierror_scripts/__init__.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/trio/_core/tests/test_multierror_scripts/_common.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/trio/_core/tests/test_multierror_scripts/apport_excepthook.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/trio/_core/tests/test_multierror_scripts/custom_excepthook.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/trio/_core/tests/test_multierror_scripts/ipython_custom_exc.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/trio/_core/tests/test_multierror_scripts/simple_excepthook.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/trio/_core/tests/test_multierror_scripts/simple_excepthook_IPython.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/trio/_core/tests/test_multierror_scripts/simple_excepthook_partial.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/trio/_core/tests/test_parking_lot.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/trio/_core/tests/test_run.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/trio/_core/tests/test_thread_cache.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/trio/_core/tests/test_tutil.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/trio/_core/tests/test_unbounded_queue.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/trio/_core/tests/test_util.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/trio/_core/tests/test_windows.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/trio/_core/tests/tutil.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/trio/_deprecate.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/trio/_file_io.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/trio/_highlevel_generic.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/trio/_highlevel_open_tcp_listeners.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/trio/_highlevel_open_tcp_stream.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/trio/_highlevel_open_unix_stream.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/trio/_highlevel_serve_listeners.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/trio/_highlevel_socket.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/trio/_highlevel_ssl_helpers.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/trio/_path.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/trio/_signals.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/trio/_socket.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/trio/_ssl.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/trio/_subprocess.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/trio/_subprocess_platform/__init__.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/trio/_subprocess_platform/kqueue.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/trio/_subprocess_platform/waitid.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/trio/_subprocess_platform/windows.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/trio/_sync.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/trio/_threads.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/trio/_timeouts.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/trio/_tools/__init__.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/trio/_tools/gen_exports.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/trio/_unix_pipes.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/trio/_util.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/trio/_version.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/trio/_wait_for_object.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/trio/_windows_pipes.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/trio/abc.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/trio/from_thread.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/trio/lowlevel.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/trio/socket.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/trio/testing/__init__.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/trio/testing/_check_streams.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/trio/testing/_checkpoints.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/trio/testing/_memory_streams.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/trio/testing/_network.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/trio/testing/_sequencer.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/trio/testing/_trio_test.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/trio/tests/__init__.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/trio/tests/conftest.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/trio/tests/module_with_deprecations.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/trio/tests/test_abc.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/trio/tests/test_channel.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/trio/tests/test_contextvars.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/trio/tests/test_deprecate.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/trio/tests/test_exports.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/trio/tests/test_file_io.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/trio/tests/test_highlevel_generic.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/trio/tests/test_highlevel_open_tcp_listeners.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/trio/tests/test_highlevel_open_tcp_stream.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/trio/tests/test_highlevel_open_unix_stream.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/trio/tests/test_highlevel_serve_listeners.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/trio/tests/test_highlevel_socket.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/trio/tests/test_highlevel_ssl_helpers.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/trio/tests/test_path.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/trio/tests/test_scheduler_determinism.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/trio/tests/test_signals.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/trio/tests/test_socket.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/trio/tests/test_ssl.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/trio/tests/test_subprocess.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/trio/tests/test_sync.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/trio/tests/test_testing.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/trio/tests/test_threads.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/trio/tests/test_timeouts.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/trio/tests/test_unix_pipes.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/trio/tests/test_util.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/trio/tests/test_wait_for_object.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/trio/tests/test_windows_pipes.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/trio/tests/tools/__init__.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/trio/tests/tools/test_gen_exports.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/trio/to_thread.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/trio_websocket-0.9.2.dist-info/INSTALLER create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/trio_websocket-0.9.2.dist-info/LICENSE create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/trio_websocket-0.9.2.dist-info/METADATA create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/trio_websocket-0.9.2.dist-info/RECORD create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/trio_websocket-0.9.2.dist-info/WHEEL create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/trio_websocket-0.9.2.dist-info/top_level.txt create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/trio_websocket/__init__.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/trio_websocket/_impl.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/trio_websocket/_version.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/typing_extensions-4.3.0.dist-info/INSTALLER create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/typing_extensions-4.3.0.dist-info/LICENSE create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/typing_extensions-4.3.0.dist-info/METADATA create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/typing_extensions-4.3.0.dist-info/RECORD create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/typing_extensions-4.3.0.dist-info/WHEEL create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/typing_extensions.py delete mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/urllib3-1.25.6.dist-info/RECORD create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/urllib3-1.26.12.dist-info/INSTALLER rename Resources/WPy32-3720/python-3.7.2/Lib/site-packages/{urllib3-1.25.6.dist-info => urllib3-1.26.12.dist-info}/LICENSE.txt (94%) rename Resources/WPy32-3720/python-3.7.2/Lib/site-packages/{urllib3-1.25.6.dist-info => urllib3-1.26.12.dist-info}/METADATA (77%) create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/urllib3-1.26.12.dist-info/RECORD create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/urllib3-1.26.12.dist-info/WHEEL rename Resources/WPy32-3720/python-3.7.2/Lib/site-packages/{urllib3-1.25.6.dist-info => urllib3-1.26.12.dist-info}/top_level.txt (100%) create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/urllib3/_version.py delete mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/urllib3/packages/ssl_match_hostname/__init__.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/urllib3/util/proxy.py rename Resources/WPy32-3720/python-3.7.2/Lib/site-packages/urllib3/{packages/ssl_match_hostname/_implementation.py => util/ssl_match_hostname.py} (89%) create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/urllib3/util/ssltransport.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/wsproto-1.2.0.dist-info/INSTALLER create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/wsproto-1.2.0.dist-info/LICENSE create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/wsproto-1.2.0.dist-info/METADATA create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/wsproto-1.2.0.dist-info/RECORD create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/wsproto-1.2.0.dist-info/WHEEL create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/wsproto-1.2.0.dist-info/top_level.txt create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/wsproto/__init__.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/wsproto/connection.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/wsproto/events.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/wsproto/extensions.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/wsproto/frame_protocol.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/wsproto/handshake.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/wsproto/py.typed create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/wsproto/typing.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/wsproto/utilities.py create mode 100644 Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA-1.2.14.dist-info/INSTALLER rename Resources/{WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.2.13.dist-info => WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA-1.2.14.dist-info}/METADATA (86%) rename Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/{pyOpenRPA-1.2.13.dist-info => pyOpenRPA-1.2.14.dist-info}/RECORD (92%) create mode 100644 Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA-1.2.14.dist-info/REQUESTED rename Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/{pyOpenRPA-1.2.13.dist-info => pyOpenRPA-1.2.14.dist-info}/WHEEL (100%) rename Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/{pyOpenRPA-1.2.13.dist-info => pyOpenRPA-1.2.14.dist-info}/top_level.txt (100%) create mode 100644 Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA/Tools/CrossOS.py create mode 100644 Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA/Tools/Template.py create mode 100644 Wiki/RUS_Guide/html/_modules/pyOpenRPA/Robot/UIWeb.html diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/certifi-2019.9.11.dist-info/INSTALLER b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/Jinja2-3.1.2.dist-info/INSTALLER similarity index 100% rename from Resources/WPy32-3720/python-3.7.2/Lib/site-packages/certifi-2019.9.11.dist-info/INSTALLER rename to Resources/WPy32-3720/python-3.7.2/Lib/site-packages/Jinja2-3.1.2.dist-info/INSTALLER diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/Jinja2-3.1.2.dist-info/LICENSE.rst b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/Jinja2-3.1.2.dist-info/LICENSE.rst new file mode 100644 index 00000000..c37cae49 --- /dev/null +++ b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/Jinja2-3.1.2.dist-info/LICENSE.rst @@ -0,0 +1,28 @@ +Copyright 2007 Pallets + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + +3. Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED +TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/Jinja2-3.1.2.dist-info/METADATA b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/Jinja2-3.1.2.dist-info/METADATA new file mode 100644 index 00000000..f54bb5ca --- /dev/null +++ b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/Jinja2-3.1.2.dist-info/METADATA @@ -0,0 +1,113 @@ +Metadata-Version: 2.1 +Name: Jinja2 +Version: 3.1.2 +Summary: A very fast and expressive template engine. +Home-page: https://palletsprojects.com/p/jinja/ +Author: Armin Ronacher +Author-email: armin.ronacher@active-4.com +Maintainer: Pallets +Maintainer-email: contact@palletsprojects.com +License: BSD-3-Clause +Project-URL: Donate, https://palletsprojects.com/donate +Project-URL: Documentation, https://jinja.palletsprojects.com/ +Project-URL: Changes, https://jinja.palletsprojects.com/changes/ +Project-URL: Source Code, https://github.com/pallets/jinja/ +Project-URL: Issue Tracker, https://github.com/pallets/jinja/issues/ +Project-URL: Twitter, https://twitter.com/PalletsTeam +Project-URL: Chat, https://discord.gg/pallets +Platform: UNKNOWN +Classifier: Development Status :: 5 - Production/Stable +Classifier: Environment :: Web Environment +Classifier: Intended Audience :: Developers +Classifier: License :: OSI Approved :: BSD License +Classifier: Operating System :: OS Independent +Classifier: Programming Language :: Python +Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content +Classifier: Topic :: Text Processing :: Markup :: HTML +Requires-Python: >=3.7 +Description-Content-Type: text/x-rst +License-File: LICENSE.rst +Requires-Dist: MarkupSafe (>=2.0) +Provides-Extra: i18n +Requires-Dist: Babel (>=2.7) ; extra == 'i18n' + +Jinja +===== + +Jinja is a fast, expressive, extensible templating engine. Special +placeholders in the template allow writing code similar to Python +syntax. Then the template is passed data to render the final document. + +It includes: + +- Template inheritance and inclusion. +- Define and import macros within templates. +- HTML templates can use autoescaping to prevent XSS from untrusted + user input. +- A sandboxed environment can safely render untrusted templates. +- AsyncIO support for generating templates and calling async + functions. +- I18N support with Babel. +- Templates are compiled to optimized Python code just-in-time and + cached, or can be compiled ahead-of-time. +- Exceptions point to the correct line in templates to make debugging + easier. +- Extensible filters, tests, functions, and even syntax. + +Jinja's philosophy is that while application logic belongs in Python if +possible, it shouldn't make the template designer's job difficult by +restricting functionality too much. + + +Installing +---------- + +Install and update using `pip`_: + +.. code-block:: text + + $ pip install -U Jinja2 + +.. _pip: https://pip.pypa.io/en/stable/getting-started/ + + +In A Nutshell +------------- + +.. code-block:: jinja + + {% extends "base.html" %} + {% block title %}Members{% endblock %} + {% block content %} + + {% endblock %} + + +Donate +------ + +The Pallets organization develops and supports Jinja and other popular +packages. In order to grow the community of contributors and users, and +allow the maintainers to devote more time to the projects, `please +donate today`_. + +.. _please donate today: https://palletsprojects.com/donate + + +Links +----- + +- Documentation: https://jinja.palletsprojects.com/ +- Changes: https://jinja.palletsprojects.com/changes/ +- PyPI Releases: https://pypi.org/project/Jinja2/ +- Source Code: https://github.com/pallets/jinja/ +- Issue Tracker: https://github.com/pallets/jinja/issues/ +- Website: https://palletsprojects.com/p/jinja/ +- Twitter: https://twitter.com/PalletsTeam +- Chat: https://discord.gg/pallets + + diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/Jinja2-3.1.2.dist-info/RECORD b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/Jinja2-3.1.2.dist-info/RECORD new file mode 100644 index 00000000..faccbad3 --- /dev/null +++ b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/Jinja2-3.1.2.dist-info/RECORD @@ -0,0 +1,58 @@ +Jinja2-3.1.2.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +Jinja2-3.1.2.dist-info/LICENSE.rst,sha256=O0nc7kEF6ze6wQ-vG-JgQI_oXSUrjp3y4JefweCUQ3s,1475 +Jinja2-3.1.2.dist-info/METADATA,sha256=PZ6v2SIidMNixR7MRUX9f7ZWsPwtXanknqiZUmRbh4U,3539 +Jinja2-3.1.2.dist-info/RECORD,, +Jinja2-3.1.2.dist-info/WHEEL,sha256=G16H4A3IeoQmnOrYV4ueZGKSjhipXx8zc8nu9FGlvMA,92 +Jinja2-3.1.2.dist-info/entry_points.txt,sha256=zRd62fbqIyfUpsRtU7EVIFyiu1tPwfgO7EvPErnxgTE,59 +Jinja2-3.1.2.dist-info/top_level.txt,sha256=PkeVWtLb3-CqjWi1fO29OCbj55EhX_chhKrCdrVe_zs,7 +jinja2/__init__.py,sha256=8vGduD8ytwgD6GDSqpYc2m3aU-T7PKOAddvVXgGr_Fs,1927 +jinja2/__pycache__/__init__.cpython-37.pyc,, +jinja2/__pycache__/_identifier.cpython-37.pyc,, +jinja2/__pycache__/async_utils.cpython-37.pyc,, +jinja2/__pycache__/bccache.cpython-37.pyc,, +jinja2/__pycache__/compiler.cpython-37.pyc,, +jinja2/__pycache__/constants.cpython-37.pyc,, +jinja2/__pycache__/debug.cpython-37.pyc,, +jinja2/__pycache__/defaults.cpython-37.pyc,, +jinja2/__pycache__/environment.cpython-37.pyc,, +jinja2/__pycache__/exceptions.cpython-37.pyc,, +jinja2/__pycache__/ext.cpython-37.pyc,, +jinja2/__pycache__/filters.cpython-37.pyc,, +jinja2/__pycache__/idtracking.cpython-37.pyc,, +jinja2/__pycache__/lexer.cpython-37.pyc,, +jinja2/__pycache__/loaders.cpython-37.pyc,, +jinja2/__pycache__/meta.cpython-37.pyc,, +jinja2/__pycache__/nativetypes.cpython-37.pyc,, +jinja2/__pycache__/nodes.cpython-37.pyc,, +jinja2/__pycache__/optimizer.cpython-37.pyc,, +jinja2/__pycache__/parser.cpython-37.pyc,, +jinja2/__pycache__/runtime.cpython-37.pyc,, +jinja2/__pycache__/sandbox.cpython-37.pyc,, +jinja2/__pycache__/tests.cpython-37.pyc,, +jinja2/__pycache__/utils.cpython-37.pyc,, +jinja2/__pycache__/visitor.cpython-37.pyc,, +jinja2/_identifier.py,sha256=_zYctNKzRqlk_murTNlzrju1FFJL7Va_Ijqqd7ii2lU,1958 +jinja2/async_utils.py,sha256=dHlbTeaxFPtAOQEYOGYh_PHcDT0rsDaUJAFDl_0XtTg,2472 +jinja2/bccache.py,sha256=mhz5xtLxCcHRAa56azOhphIAe19u1we0ojifNMClDio,14061 +jinja2/compiler.py,sha256=Gs-N8ThJ7OWK4-reKoO8Wh1ZXz95MVphBKNVf75qBr8,72172 +jinja2/constants.py,sha256=GMoFydBF_kdpaRKPoM5cl5MviquVRLVyZtfp5-16jg0,1433 +jinja2/debug.py,sha256=iWJ432RadxJNnaMOPrjIDInz50UEgni3_HKuFXi2vuQ,6299 +jinja2/defaults.py,sha256=boBcSw78h-lp20YbaXSJsqkAI2uN_mD_TtCydpeq5wU,1267 +jinja2/environment.py,sha256=6uHIcc7ZblqOMdx_uYNKqRnnwAF0_nzbyeMP9FFtuh4,61349 +jinja2/exceptions.py,sha256=ioHeHrWwCWNaXX1inHmHVblvc4haO7AXsjCp3GfWvx0,5071 +jinja2/ext.py,sha256=ivr3P7LKbddiXDVez20EflcO3q2aHQwz9P_PgWGHVqE,31502 +jinja2/filters.py,sha256=9js1V-h2RlyW90IhLiBGLM2U-k6SCy2F4BUUMgB3K9Q,53509 +jinja2/idtracking.py,sha256=GfNmadir4oDALVxzn3DL9YInhJDr69ebXeA2ygfuCGA,10704 +jinja2/lexer.py,sha256=DW2nX9zk-6MWp65YR2bqqj0xqCvLtD-u9NWT8AnFRxQ,29726 +jinja2/loaders.py,sha256=BfptfvTVpClUd-leMkHczdyPNYFzp_n7PKOJ98iyHOg,23207 +jinja2/meta.py,sha256=GNPEvifmSaU3CMxlbheBOZjeZ277HThOPUTf1RkppKQ,4396 +jinja2/nativetypes.py,sha256=DXgORDPRmVWgy034H0xL8eF7qYoK3DrMxs-935d0Fzk,4226 +jinja2/nodes.py,sha256=i34GPRAZexXMT6bwuf5SEyvdmS-bRCy9KMjwN5O6pjk,34550 +jinja2/optimizer.py,sha256=tHkMwXxfZkbfA1KmLcqmBMSaz7RLIvvItrJcPoXTyD8,1650 +jinja2/parser.py,sha256=nHd-DFHbiygvfaPtm9rcQXJChZG7DPsWfiEsqfwKerY,39595 +jinja2/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +jinja2/runtime.py,sha256=5CmD5BjbEJxSiDNTFBeKCaq8qU4aYD2v6q2EluyExms,33476 +jinja2/sandbox.py,sha256=Y0xZeXQnH6EX5VjaV2YixESxoepnRbW_3UeQosaBU3M,14584 +jinja2/tests.py,sha256=Am5Z6Lmfr2XaH_npIfJJ8MdXtWsbLjMULZJulTAj30E,5905 +jinja2/utils.py,sha256=u9jXESxGn8ATZNVolwmkjUVu4SA-tLgV0W7PcSfPfdQ,23965 +jinja2/visitor.py,sha256=MH14C6yq24G_KVtWzjwaI7Wg14PCJIYlWW1kpkxYak0,3568 diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/Jinja2-3.1.2.dist-info/WHEEL b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/Jinja2-3.1.2.dist-info/WHEEL new file mode 100644 index 00000000..becc9a66 --- /dev/null +++ b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/Jinja2-3.1.2.dist-info/WHEEL @@ -0,0 +1,5 @@ +Wheel-Version: 1.0 +Generator: bdist_wheel (0.37.1) +Root-Is-Purelib: true +Tag: py3-none-any + diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/Jinja2-3.1.2.dist-info/entry_points.txt b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/Jinja2-3.1.2.dist-info/entry_points.txt new file mode 100644 index 00000000..7b9666c8 --- /dev/null +++ b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/Jinja2-3.1.2.dist-info/entry_points.txt @@ -0,0 +1,2 @@ +[babel.extractors] +jinja2 = jinja2.ext:babel_extract[i18n] diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/Jinja2-3.1.2.dist-info/top_level.txt b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/Jinja2-3.1.2.dist-info/top_level.txt new file mode 100644 index 00000000..7f7afbf3 --- /dev/null +++ b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/Jinja2-3.1.2.dist-info/top_level.txt @@ -0,0 +1 @@ +jinja2 diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/cffi-1.12.3.dist-info/INSTALLER b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/MarkupSafe-2.1.1.dist-info/INSTALLER similarity index 100% rename from Resources/WPy32-3720/python-3.7.2/Lib/site-packages/cffi-1.12.3.dist-info/INSTALLER rename to Resources/WPy32-3720/python-3.7.2/Lib/site-packages/MarkupSafe-2.1.1.dist-info/INSTALLER diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/MarkupSafe-2.1.1.dist-info/LICENSE.rst b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/MarkupSafe-2.1.1.dist-info/LICENSE.rst new file mode 100644 index 00000000..9d227a0c --- /dev/null +++ b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/MarkupSafe-2.1.1.dist-info/LICENSE.rst @@ -0,0 +1,28 @@ +Copyright 2010 Pallets + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + +3. Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED +TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/MarkupSafe-2.1.1.dist-info/METADATA b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/MarkupSafe-2.1.1.dist-info/METADATA new file mode 100644 index 00000000..485a5e06 --- /dev/null +++ b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/MarkupSafe-2.1.1.dist-info/METADATA @@ -0,0 +1,101 @@ +Metadata-Version: 2.1 +Name: MarkupSafe +Version: 2.1.1 +Summary: Safely add untrusted strings to HTML/XML markup. +Home-page: https://palletsprojects.com/p/markupsafe/ +Author: Armin Ronacher +Author-email: armin.ronacher@active-4.com +Maintainer: Pallets +Maintainer-email: contact@palletsprojects.com +License: BSD-3-Clause +Project-URL: Donate, https://palletsprojects.com/donate +Project-URL: Documentation, https://markupsafe.palletsprojects.com/ +Project-URL: Changes, https://markupsafe.palletsprojects.com/changes/ +Project-URL: Source Code, https://github.com/pallets/markupsafe/ +Project-URL: Issue Tracker, https://github.com/pallets/markupsafe/issues/ +Project-URL: Twitter, https://twitter.com/PalletsTeam +Project-URL: Chat, https://discord.gg/pallets +Platform: UNKNOWN +Classifier: Development Status :: 5 - Production/Stable +Classifier: Environment :: Web Environment +Classifier: Intended Audience :: Developers +Classifier: License :: OSI Approved :: BSD License +Classifier: Operating System :: OS Independent +Classifier: Programming Language :: Python +Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content +Classifier: Topic :: Text Processing :: Markup :: HTML +Requires-Python: >=3.7 +Description-Content-Type: text/x-rst +License-File: LICENSE.rst + +MarkupSafe +========== + +MarkupSafe implements a text object that escapes characters so it is +safe to use in HTML and XML. Characters that have special meanings are +replaced so that they display as the actual characters. This mitigates +injection attacks, meaning untrusted user input can safely be displayed +on a page. + + +Installing +---------- + +Install and update using `pip`_: + +.. code-block:: text + + pip install -U MarkupSafe + +.. _pip: https://pip.pypa.io/en/stable/getting-started/ + + +Examples +-------- + +.. code-block:: pycon + + >>> from markupsafe import Markup, escape + + >>> # escape replaces special characters and wraps in Markup + >>> escape("") + Markup('<script>alert(document.cookie);</script>') + + >>> # wrap in Markup to mark text "safe" and prevent escaping + >>> Markup("Hello") + Markup('hello') + + >>> escape(Markup("Hello")) + Markup('hello') + + >>> # Markup is a str subclass + >>> # methods and operators escape their arguments + >>> template = Markup("Hello {name}") + >>> template.format(name='"World"') + Markup('Hello "World"') + + +Donate +------ + +The Pallets organization develops and supports MarkupSafe and other +popular packages. In order to grow the community of contributors and +users, and allow the maintainers to devote more time to the projects, +`please donate today`_. + +.. _please donate today: https://palletsprojects.com/donate + + +Links +----- + +- Documentation: https://markupsafe.palletsprojects.com/ +- Changes: https://markupsafe.palletsprojects.com/changes/ +- PyPI Releases: https://pypi.org/project/MarkupSafe/ +- Source Code: https://github.com/pallets/markupsafe/ +- Issue Tracker: https://github.com/pallets/markupsafe/issues/ +- Website: https://palletsprojects.com/p/markupsafe/ +- Twitter: https://twitter.com/PalletsTeam +- Chat: https://discord.gg/pallets + + diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/MarkupSafe-2.1.1.dist-info/RECORD b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/MarkupSafe-2.1.1.dist-info/RECORD new file mode 100644 index 00000000..e29897ed --- /dev/null +++ b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/MarkupSafe-2.1.1.dist-info/RECORD @@ -0,0 +1,13 @@ +MarkupSafe-2.1.1.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +MarkupSafe-2.1.1.dist-info/LICENSE.rst,sha256=RjHsDbX9kKVH4zaBcmTGeYIUM4FG-KyUtKV_lu6MnsQ,1503 +MarkupSafe-2.1.1.dist-info/METADATA,sha256=DC93VszmzjLQcrVChRUjtW4XbUwjTdbaplpgdlbFdbs,3242 +MarkupSafe-2.1.1.dist-info/RECORD,, +MarkupSafe-2.1.1.dist-info/WHEEL,sha256=9OdCYMNQUOC_P9zHBse4QOXtlFK2lgCwV_yVRgNexF8,97 +MarkupSafe-2.1.1.dist-info/top_level.txt,sha256=qy0Plje5IJuvsCBjejJyhDCjEAdcDLK_2agVcex8Z6U,11 +markupsafe/__init__.py,sha256=XGdbhy_OLrsQ5ZoFV3V6HQ3GeJ_ojcabRl_8yqehISk,9579 +markupsafe/__pycache__/__init__.cpython-37.pyc,, +markupsafe/__pycache__/_native.cpython-37.pyc,, +markupsafe/_native.py,sha256=_Q7UsXCOvgdonCgqG3l5asANI6eo50EKnDM-mlwEC5M,1776 +markupsafe/_speedups.cp37-win32.pyd,sha256=PSenQCPcMXqXLoRiQEeYesPG8z647jTjYKMxZQ85Ddk,13824 +markupsafe/_speedups.pyi,sha256=f5QtwIOP0eLrxh2v5p6SmaYmlcHIGIfmz0DovaqL0OU,238 +markupsafe/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/cffi-1.12.3.dist-info/WHEEL b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/MarkupSafe-2.1.1.dist-info/WHEEL similarity index 67% rename from Resources/WPy32-3720/python-3.7.2/Lib/site-packages/cffi-1.12.3.dist-info/WHEEL rename to Resources/WPy32-3720/python-3.7.2/Lib/site-packages/MarkupSafe-2.1.1.dist-info/WHEEL index bb93ff5e..3241ef07 100644 --- a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/cffi-1.12.3.dist-info/WHEEL +++ b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/MarkupSafe-2.1.1.dist-info/WHEEL @@ -1,5 +1,5 @@ Wheel-Version: 1.0 -Generator: bdist_wheel (0.33.1) +Generator: bdist_wheel (0.37.0) Root-Is-Purelib: false Tag: cp37-cp37m-win32 diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/MarkupSafe-2.1.1.dist-info/top_level.txt b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/MarkupSafe-2.1.1.dist-info/top_level.txt new file mode 100644 index 00000000..75bf7292 --- /dev/null +++ b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/MarkupSafe-2.1.1.dist-info/top_level.txt @@ -0,0 +1 @@ +markupsafe diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/psutil-5.6.1.dist-info/INSTALLER b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/PySocks-1.7.1.dist-info/INSTALLER similarity index 100% rename from Resources/WPy32-3720/python-3.7.2/Lib/site-packages/psutil-5.6.1.dist-info/INSTALLER rename to Resources/WPy32-3720/python-3.7.2/Lib/site-packages/PySocks-1.7.1.dist-info/INSTALLER diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/PySocks-1.7.1.dist-info/LICENSE b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/PySocks-1.7.1.dist-info/LICENSE new file mode 100644 index 00000000..04b6b1f3 --- /dev/null +++ b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/PySocks-1.7.1.dist-info/LICENSE @@ -0,0 +1,22 @@ +Copyright 2006 Dan-Haim. All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: +1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. +3. Neither the name of Dan Haim nor the names of his contributors may be used + to endorse or promote products derived from this software without specific + prior written permission. + +THIS SOFTWARE IS PROVIDED BY DAN HAIM "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 DAN HAIM OR HIS 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, 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 DAMANGE. diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/PySocks-1.7.1.dist-info/METADATA b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/PySocks-1.7.1.dist-info/METADATA new file mode 100644 index 00000000..ae2ae341 --- /dev/null +++ b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/PySocks-1.7.1.dist-info/METADATA @@ -0,0 +1,321 @@ +Metadata-Version: 2.1 +Name: PySocks +Version: 1.7.1 +Summary: A Python SOCKS client module. See https://github.com/Anorov/PySocks for more information. +Home-page: https://github.com/Anorov/PySocks +Author: Anorov +Author-email: anorov.vorona@gmail.com +License: BSD +Keywords: socks,proxy +Platform: UNKNOWN +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 +Requires-Python: >=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.* +Description-Content-Type: text/markdown + +PySocks +======= + +PySocks lets you send traffic through SOCKS and HTTP proxy servers. It is a modern fork of [SocksiPy](http://socksipy.sourceforge.net/) with bug fixes and extra features. + +Acts as a drop-in replacement to the socket module. Seamlessly configure SOCKS proxies for any socket object by calling `socket_object.set_proxy()`. + +---------------- + +Features +======== + +* SOCKS proxy client for Python 2.7 and 3.4+ +* TCP supported +* UDP mostly supported (issues may occur in some edge cases) +* HTTP proxy client included but not supported or recommended (you should use urllib2's or requests' own HTTP proxy interface) +* urllib2 handler included. `pip install` / `setup.py install` will automatically install the `sockshandler` module. + +Installation +============ + + pip install PySocks + +Or download the tarball / `git clone` and... + + python setup.py install + +These will install both the `socks` and `sockshandler` modules. + +Alternatively, include just `socks.py` in your project. + +-------------------------------------------- + +*Warning:* PySocks/SocksiPy only supports HTTP proxies that use CONNECT tunneling. Certain HTTP proxies may not work with this library. If you wish to use HTTP (not SOCKS) proxies, it is recommended that you rely on your HTTP client's native proxy support (`proxies` dict for `requests`, or `urllib2.ProxyHandler` for `urllib2`) instead. + +-------------------------------------------- + +Usage +===== + +## socks.socksocket ## + + import socks + + s = socks.socksocket() # Same API as socket.socket in the standard lib + + s.set_proxy(socks.SOCKS5, "localhost") # SOCKS4 and SOCKS5 use port 1080 by default + # Or + s.set_proxy(socks.SOCKS4, "localhost", 4444) + # Or + s.set_proxy(socks.HTTP, "5.5.5.5", 8888) + + # Can be treated identical to a regular socket object + s.connect(("www.somesite.com", 80)) + s.sendall("GET / HTTP/1.1 ...") + print s.recv(4096) + +## Monkeypatching ## + +To monkeypatch the entire standard library with a single default proxy: + + import urllib2 + import socket + import socks + + socks.set_default_proxy(socks.SOCKS5, "localhost") + socket.socket = socks.socksocket + + urllib2.urlopen("http://www.somesite.com/") # All requests will pass through the SOCKS proxy + +Note that monkeypatching may not work for all standard modules or for all third party modules, and generally isn't recommended. Monkeypatching is usually an anti-pattern in Python. + +## urllib2 Handler ## + +Example use case with the `sockshandler` urllib2 handler. Note that you must import both `socks` and `sockshandler`, as the handler is its own module separate from PySocks. The module is included in the PyPI package. + + import urllib2 + import socks + from sockshandler import SocksiPyHandler + + opener = urllib2.build_opener(SocksiPyHandler(socks.SOCKS5, "127.0.0.1", 9050)) + print opener.open("http://www.somesite.com/") # All requests made by the opener will pass through the SOCKS proxy + +-------------------------------------------- + +Original SocksiPy README attached below, amended to reflect API changes. + +-------------------------------------------- + +SocksiPy + +A Python SOCKS module. + +(C) 2006 Dan-Haim. All rights reserved. + +See LICENSE file for details. + + +*WHAT IS A SOCKS PROXY?* + +A SOCKS proxy is a proxy server at the TCP level. In other words, it acts as +a tunnel, relaying all traffic going through it without modifying it. +SOCKS proxies can be used to relay traffic using any network protocol that +uses TCP. + +*WHAT IS SOCKSIPY?* + +This Python module allows you to create TCP connections through a SOCKS +proxy without any special effort. +It also supports relaying UDP packets with a SOCKS5 proxy. + +*PROXY COMPATIBILITY* + +SocksiPy is compatible with three different types of proxies: + +1. SOCKS Version 4 (SOCKS4), including the SOCKS4a extension. +2. SOCKS Version 5 (SOCKS5). +3. HTTP Proxies which support tunneling using the CONNECT method. + +*SYSTEM REQUIREMENTS* + +Being written in Python, SocksiPy can run on any platform that has a Python +interpreter and TCP/IP support. +This module has been tested with Python 2.3 and should work with greater versions +just as well. + + +INSTALLATION +------------- + +Simply copy the file "socks.py" to your Python's `lib/site-packages` directory, +and you're ready to go. [Editor's note: it is better to use `python setup.py install` for PySocks] + + +USAGE +------ + +First load the socks module with the command: + + >>> import socks + >>> + +The socks module provides a class called `socksocket`, which is the base to all of the module's functionality. + +The `socksocket` object has the same initialization parameters as the normal socket +object to ensure maximal compatibility, however it should be noted that `socksocket` will only function with family being `AF_INET` and +type being either `SOCK_STREAM` or `SOCK_DGRAM`. +Generally, it is best to initialize the `socksocket` object with no parameters + + >>> s = socks.socksocket() + >>> + +The `socksocket` object has an interface which is very similiar to socket's (in fact +the `socksocket` class is derived from socket) with a few extra methods. +To select the proxy server you would like to use, use the `set_proxy` method, whose +syntax is: + + set_proxy(proxy_type, addr[, port[, rdns[, username[, password]]]]) + +Explanation of the parameters: + +`proxy_type` - The type of the proxy server. This can be one of three possible +choices: `PROXY_TYPE_SOCKS4`, `PROXY_TYPE_SOCKS5` and `PROXY_TYPE_HTTP` for SOCKS4, +SOCKS5 and HTTP servers respectively. `SOCKS4`, `SOCKS5`, and `HTTP` are all aliases, respectively. + +`addr` - The IP address or DNS name of the proxy server. + +`port` - The port of the proxy server. Defaults to 1080 for socks and 8080 for http. + +`rdns` - This is a boolean flag than modifies the behavior regarding DNS resolving. +If it is set to True, DNS resolving will be preformed remotely, on the server. +If it is set to False, DNS resolving will be preformed locally. Please note that +setting this to True with SOCKS4 servers actually use an extension to the protocol, +called SOCKS4a, which may not be supported on all servers (SOCKS5 and http servers +always support DNS). The default is True. + +`username` - For SOCKS5 servers, this allows simple username / password authentication +with the server. For SOCKS4 servers, this parameter will be sent as the userid. +This parameter is ignored if an HTTP server is being used. If it is not provided, +authentication will not be used (servers may accept unauthenticated requests). + +`password` - This parameter is valid only for SOCKS5 servers and specifies the +respective password for the username provided. + +Example of usage: + + >>> s.set_proxy(socks.SOCKS5, "socks.example.com") # uses default port 1080 + >>> s.set_proxy(socks.SOCKS4, "socks.test.com", 1081) + +After the set_proxy method has been called, simply call the connect method with the +traditional parameters to establish a connection through the proxy: + + >>> s.connect(("www.sourceforge.net", 80)) + >>> + +Connection will take a bit longer to allow negotiation with the proxy server. +Please note that calling connect without calling `set_proxy` earlier will connect +without a proxy (just like a regular socket). + +Errors: Any errors in the connection process will trigger exceptions. The exception +may either be generated by the underlying socket layer or may be custom module +exceptions, whose details follow: + +class `ProxyError` - This is a base exception class. It is not raised directly but +rather all other exception classes raised by this module are derived from it. +This allows an easy way to catch all proxy-related errors. It descends from `IOError`. + +All `ProxyError` exceptions have an attribute `socket_err`, which will contain either a +caught `socket.error` exception, or `None` if there wasn't any. + +class `GeneralProxyError` - When thrown, it indicates a problem which does not fall +into another category. + +* `Sent invalid data` - This error means that unexpected data has been received from +the server. The most common reason is that the server specified as the proxy is +not really a SOCKS4/SOCKS5/HTTP proxy, or maybe the proxy type specified is wrong. + +* `Connection closed unexpectedly` - The proxy server unexpectedly closed the connection. +This may indicate that the proxy server is experiencing network or software problems. + +* `Bad proxy type` - This will be raised if the type of the proxy supplied to the +set_proxy function was not one of `SOCKS4`/`SOCKS5`/`HTTP`. + +* `Bad input` - This will be raised if the `connect()` method is called with bad input +parameters. + +class `SOCKS5AuthError` - This indicates that the connection through a SOCKS5 server +failed due to an authentication problem. + +* `Authentication is required` - This will happen if you use a SOCKS5 server which +requires authentication without providing a username / password at all. + +* `All offered authentication methods were rejected` - This will happen if the proxy +requires a special authentication method which is not supported by this module. + +* `Unknown username or invalid password` - Self descriptive. + +class `SOCKS5Error` - This will be raised for SOCKS5 errors which are not related to +authentication. +The parameter is a tuple containing a code, as given by the server, +and a description of the +error. The possible errors, according to the RFC, are: + +* `0x01` - General SOCKS server failure - If for any reason the proxy server is unable to +fulfill your request (internal server error). +* `0x02` - connection not allowed by ruleset - If the address you're trying to connect to +is blacklisted on the server or requires authentication. +* `0x03` - Network unreachable - The target could not be contacted. A router on the network +had replied with a destination net unreachable error. +* `0x04` - Host unreachable - The target could not be contacted. A router on the network +had replied with a destination host unreachable error. +* `0x05` - Connection refused - The target server has actively refused the connection +(the requested port is closed). +* `0x06` - TTL expired - The TTL value of the SYN packet from the proxy to the target server +has expired. This usually means that there are network problems causing the packet +to be caught in a router-to-router "ping-pong". +* `0x07` - Command not supported - For instance if the server does not support UDP. +* `0x08` - Address type not supported - The client has provided an invalid address type. +When using this module, this error should not occur. + +class `SOCKS4Error` - This will be raised for SOCKS4 errors. The parameter is a tuple +containing a code and a description of the error, as given by the server. The +possible error, according to the specification are: + +* `0x5B` - Request rejected or failed - Will be raised in the event of an failure for any +reason other then the two mentioned next. +* `0x5C` - request rejected because SOCKS server cannot connect to identd on the client - +The Socks server had tried an ident lookup on your computer and has failed. In this +case you should run an identd server and/or configure your firewall to allow incoming +connections to local port 113 from the remote server. +* `0x5D` - request rejected because the client program and identd report different user-ids - +The Socks server had performed an ident lookup on your computer and has received a +different userid than the one you have provided. Change your userid (through the +username parameter of the set_proxy method) to match and try again. + +class `HTTPError` - This will be raised for HTTP errors. The message will contain +the HTTP status code and provided error message. + +After establishing the connection, the object behaves like a standard socket. + +Methods like `makefile()` and `settimeout()` should behave just like regular sockets. +Call the `close()` method to close the connection. + +In addition to the `socksocket` class, an additional function worth mentioning is the +`set_default_proxy` function. The parameters are the same as the `set_proxy` method. +This function will set default proxy settings for newly created `socksocket` objects, +in which the proxy settings haven't been changed via the `set_proxy` method. +This is quite useful if you wish to force 3rd party modules to use a SOCKS proxy, +by overriding the socket object. +For example: + + >>> socks.set_default_proxy(socks.SOCKS5, "socks.example.com") + >>> socket.socket = socks.socksocket + >>> urllib.urlopen("http://www.sourceforge.net/") + + +PROBLEMS +--------- + +Please open a GitHub issue at https://github.com/Anorov/PySocks + + diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/PySocks-1.7.1.dist-info/RECORD b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/PySocks-1.7.1.dist-info/RECORD new file mode 100644 index 00000000..b296205f --- /dev/null +++ b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/PySocks-1.7.1.dist-info/RECORD @@ -0,0 +1,10 @@ +PySocks-1.7.1.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +PySocks-1.7.1.dist-info/LICENSE,sha256=cCfiFOAU63i3rcwc7aWspxOnn8T2oMUsnaWz5wfm_-k,1401 +PySocks-1.7.1.dist-info/METADATA,sha256=zbQMizjPOOP4DhEiEX24XXjNrYuIxF9UGUpN0uFDB6Y,13235 +PySocks-1.7.1.dist-info/RECORD,, +PySocks-1.7.1.dist-info/WHEEL,sha256=t_MpApv386-8PVts2R6wsTifdIn0vbUDTVv61IbqFC8,92 +PySocks-1.7.1.dist-info/top_level.txt,sha256=TKSOIfCFBoK9EY8FBYbYqC3PWd3--G15ph9n8-QHPDk,19 +__pycache__/socks.cpython-37.pyc,, +__pycache__/sockshandler.cpython-37.pyc,, +socks.py,sha256=xOYn27t9IGrbTBzWsUUuPa0YBuplgiUykzkOB5V5iFY,31086 +sockshandler.py,sha256=2SYGj-pwt1kjgLoZAmyeaEXCeZDWRmfVS_QG6kErGtY,3966 diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/PySocks-1.7.1.dist-info/WHEEL b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/PySocks-1.7.1.dist-info/WHEEL new file mode 100644 index 00000000..129a6735 --- /dev/null +++ b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/PySocks-1.7.1.dist-info/WHEEL @@ -0,0 +1,5 @@ +Wheel-Version: 1.0 +Generator: bdist_wheel (0.33.3) +Root-Is-Purelib: true +Tag: py3-none-any + diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/PySocks-1.7.1.dist-info/top_level.txt b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/PySocks-1.7.1.dist-info/top_level.txt new file mode 100644 index 00000000..9476163a --- /dev/null +++ b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/PySocks-1.7.1.dist-info/top_level.txt @@ -0,0 +1,2 @@ +socks +sockshandler diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/_cffi_backend.cp37-win32.pyd b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/_cffi_backend.cp37-win32.pyd index e66187dd27ccf77fe2785fd1145a9b8bb1b89b10..a92d567ef0777298e808f341bfe635048577942d 100644 GIT binary patch literal 155648 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%0Am)E)W7Y1|!6MkPm$LZA8f^gfWs%?pi8n+>ZM| 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 Mcl%NF|C+!54;}oJ8UO$Q diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.2.13.dist-info/INSTALLER b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/async_generator-1.10.dist-info/INSTALLER similarity index 100% rename from Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.2.13.dist-info/INSTALLER rename to Resources/WPy32-3720/python-3.7.2/Lib/site-packages/async_generator-1.10.dist-info/INSTALLER diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/async_generator-1.10.dist-info/METADATA b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/async_generator-1.10.dist-info/METADATA new file mode 100644 index 00000000..c0283031 --- /dev/null +++ b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/async_generator-1.10.dist-info/METADATA @@ -0,0 +1,145 @@ +Metadata-Version: 2.1 +Name: async-generator +Version: 1.10 +Summary: Async generators and context managers for Python 3.5+ +Home-page: https://github.com/python-trio/async_generator +Author: Nathaniel J. Smith +Author-email: njs@pobox.com +License: MIT -or- Apache License 2.0 +Keywords: async +Platform: UNKNOWN +Classifier: Development Status :: 5 - Production/Stable +Classifier: Intended Audience :: Developers +Classifier: License :: OSI Approved :: MIT License +Classifier: License :: OSI Approved :: Apache Software License +Classifier: Programming Language :: Python :: Implementation :: CPython +Classifier: Programming Language :: Python :: Implementation :: PyPy +Classifier: Programming Language :: Python :: 3 :: Only +Classifier: Programming Language :: Python :: 3.5 +Classifier: Programming Language :: Python :: 3.6 +Classifier: Framework :: AsyncIO +Requires-Python: >=3.5 + +.. image:: https://img.shields.io/badge/chat-join%20now-blue.svg + :target: https://gitter.im/python-trio/general + :alt: Join chatroom + +.. image:: https://img.shields.io/badge/docs-read%20now-blue.svg + :target: https://async-generator.readthedocs.io/en/latest/?badge=latest + :alt: Documentation Status + +.. image:: https://travis-ci.org/python-trio/async_generator.svg?branch=master + :target: https://travis-ci.org/python-trio/async_generator + :alt: Automated test status + +.. image:: https://ci.appveyor.com/api/projects/status/af4eyed8o8tc3t0r/branch/master?svg=true + :target: https://ci.appveyor.com/project/python-trio/trio/history + :alt: Automated test status (Windows) + +.. image:: https://codecov.io/gh/python-trio/async_generator/branch/master/graph/badge.svg + :target: https://codecov.io/gh/python-trio/async_generator + :alt: Test coverage + +The async_generator library +=========================== + +Python 3.6 added `async generators +`__. (What's an async +generator? `Check out my 5-minute lightning talk demo from PyCon 2016 +`__.) Python 3.7 adds some more +tools to make them usable, like ``contextlib.asynccontextmanager``. + +This library gives you all that back to Python 3.5. + +For example, this code only works in Python 3.6+: + +.. code-block:: python3 + + async def load_json_lines(stream_reader): + async for line in stream_reader: + yield json.loads(line) + +But this code does the same thing, and works on Python 3.5+: + +.. code-block:: python3 + + from async_generator import async_generator, yield_ + + @async_generator + async def load_json_lines(stream_reader): + async for line in stream_reader: + await yield_(json.loads(line)) + +Or in Python 3.7, you can write: + +.. code-block:: python3 + + from contextlib import asynccontextmanager + + @asynccontextmanager + async def background_server(): + async with trio.open_nursery() as nursery: + value = await nursery.start(my_server) + try: + yield value + finally: + # Kill the server when the scope exits + nursery.cancel_scope.cancel() + +This is the same, but back to 3.5: + +.. code-block:: python3 + + from async_generator import async_generator, yield_, asynccontextmanager + + @asynccontextmanager + @async_generator + async def background_server(): + async with trio.open_nursery() as nursery: + value = await nursery.start(my_server) + try: + await yield_(value) + finally: + # Kill the server when the scope exits + nursery.cancel_scope.cancel() + +(And if you're on 3.6, you can use ``@asynccontextmanager`` with +native generators.) + + +Let's do this +============= + +* Install: ``python3 -m pip install -U async_generator`` (or on Windows, + maybe ``py -3 -m pip install -U async_generator`` + +* Manual: https://async-generator.readthedocs.io/ + +* Bug tracker and source code: https://github.com/python-trio/async_generator + +* Real-time chat: https://gitter.im/python-trio/general + +* License: MIT or Apache 2, your choice + +* Contributor guide: https://trio.readthedocs.io/en/latest/contributing.html + +* Code of conduct: Contributors are requested to follow our `code of + conduct + `__ in + all project spaces. + + +How come some of those links talk about "trio"? +=============================================== + +`Trio `__ is a new async concurrency +library for Python that's obsessed with usability and correctness – we +want to make it *easy* to get things *right*. The ``async_generator`` +library is maintained by the Trio project as part of that mission, and +because Trio uses ``async_generator`` internally. + +You can use ``async_generator`` with any async library. It works great +with ``asyncio``, or Twisted, or whatever you like. (But we think Trio +is pretty sweet.) + + diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/async_generator-1.10.dist-info/RECORD b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/async_generator-1.10.dist-info/RECORD new file mode 100644 index 00000000..16613c71 --- /dev/null +++ b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/async_generator-1.10.dist-info/RECORD @@ -0,0 +1,21 @@ +async_generator-1.10.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +async_generator-1.10.dist-info/METADATA,sha256=FZoDYGYfSdJkSUSR5T_YMqq2TnwYa-RFOm6SbhWFzGA,4870 +async_generator-1.10.dist-info/RECORD,, +async_generator-1.10.dist-info/WHEEL,sha256=NzFAKnL7g-U64xnS1s5e3mJnxKpOTeOtlXdFwS9yNXI,92 +async_generator-1.10.dist-info/top_level.txt,sha256=Qc2NF6EJciFqrZ6gAdWuQIveMaqWJw4jqv1anjEHT_U,16 +async_generator/__init__.py,sha256=6eYc-CD3B5kQx8LzMhTEqJyKQH5UTsy8IZhR3AvcVb8,454 +async_generator/__pycache__/__init__.cpython-37.pyc,, +async_generator/__pycache__/_impl.cpython-37.pyc,, +async_generator/__pycache__/_util.cpython-37.pyc,, +async_generator/__pycache__/_version.cpython-37.pyc,, +async_generator/_impl.py,sha256=t1p5goS6TrQmpxLL4vOFa9zpl0SorICI8WZc8e81lxU,16106 +async_generator/_tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +async_generator/_tests/__pycache__/__init__.cpython-37.pyc,, +async_generator/_tests/__pycache__/conftest.cpython-37.pyc,, +async_generator/_tests/__pycache__/test_async_generator.cpython-37.pyc,, +async_generator/_tests/__pycache__/test_util.cpython-37.pyc,, +async_generator/_tests/conftest.py,sha256=eL5uA75o6d9feDTeEXu8vYDg-kgbnfuaGILJKGyWOFw,1211 +async_generator/_tests/test_async_generator.py,sha256=HBXQAlZdt68hzSQ6eMoSYsoO--Bic3Ojv1Z71hCQb7U,27936 +async_generator/_tests/test_util.py,sha256=-vLPOW_V2etk3Bf2M3cqEOGjxeRPFnSGfftsIYBaCCQ,6373 +async_generator/_util.py,sha256=jtBz2-fn6ec0JmaKKY-sC0TAq6zqGAKL3qs7LYQ4uFw,4358 +async_generator/_version.py,sha256=Nas37COFU-AbvlukCSCZDPrvCzgtKiG5QGZXnYenLC8,21 diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/async_generator-1.10.dist-info/WHEEL b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/async_generator-1.10.dist-info/WHEEL new file mode 100644 index 00000000..bff023ed --- /dev/null +++ b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/async_generator-1.10.dist-info/WHEEL @@ -0,0 +1,5 @@ +Wheel-Version: 1.0 +Generator: bdist_wheel (0.31.1) +Root-Is-Purelib: true +Tag: py3-none-any + diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/async_generator-1.10.dist-info/top_level.txt b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/async_generator-1.10.dist-info/top_level.txt new file mode 100644 index 00000000..9d6bff89 --- /dev/null +++ b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/async_generator-1.10.dist-info/top_level.txt @@ -0,0 +1 @@ +async_generator diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/async_generator/__init__.py b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/async_generator/__init__.py new file mode 100644 index 00000000..e81a8fe8 --- /dev/null +++ b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/async_generator/__init__.py @@ -0,0 +1,23 @@ +from ._version import __version__ +from ._impl import ( + async_generator, + yield_, + yield_from_, + isasyncgen, + isasyncgenfunction, + get_asyncgen_hooks, + set_asyncgen_hooks, +) +from ._util import aclosing, asynccontextmanager + +__all__ = [ + "async_generator", + "yield_", + "yield_from_", + "aclosing", + "isasyncgen", + "isasyncgenfunction", + "asynccontextmanager", + "get_asyncgen_hooks", + "set_asyncgen_hooks", +] diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/async_generator/_impl.py b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/async_generator/_impl.py new file mode 100644 index 00000000..0b874211 --- /dev/null +++ b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/async_generator/_impl.py @@ -0,0 +1,455 @@ +import sys +from functools import wraps +from types import coroutine +import inspect +from inspect import ( + getcoroutinestate, CORO_CREATED, CORO_CLOSED, CORO_SUSPENDED +) +import collections.abc + + +class YieldWrapper: + def __init__(self, payload): + self.payload = payload + + +def _wrap(value): + return YieldWrapper(value) + + +def _is_wrapped(box): + return isinstance(box, YieldWrapper) + + +def _unwrap(box): + return box.payload + + +# This is the magic code that lets you use yield_ and yield_from_ with native +# generators. +# +# The old version worked great on Linux and MacOS, but not on Windows, because +# it depended on _PyAsyncGenValueWrapperNew. The new version segfaults +# everywhere, and I'm not sure why -- probably my lack of understanding +# of ctypes and refcounts. +# +# There are also some commented out tests that should be re-enabled if this is +# fixed: +# +# if sys.version_info >= (3, 6): +# # Use the same box type that the interpreter uses internally. This allows +# # yield_ and (more importantly!) yield_from_ to work in built-in +# # generators. +# import ctypes # mua ha ha. +# +# # We used to call _PyAsyncGenValueWrapperNew to create and set up new +# # wrapper objects, but that symbol isn't available on Windows: +# # +# # https://github.com/python-trio/async_generator/issues/5 +# # +# # Fortunately, the type object is available, but it means we have to do +# # this the hard way. +# +# # We don't actually need to access this, but we need to make a ctypes +# # structure so we can call addressof. +# class _ctypes_PyTypeObject(ctypes.Structure): +# pass +# _PyAsyncGenWrappedValue_Type_ptr = ctypes.addressof( +# _ctypes_PyTypeObject.in_dll( +# ctypes.pythonapi, "_PyAsyncGenWrappedValue_Type")) +# _PyObject_GC_New = ctypes.pythonapi._PyObject_GC_New +# _PyObject_GC_New.restype = ctypes.py_object +# _PyObject_GC_New.argtypes = (ctypes.c_void_p,) +# +# _Py_IncRef = ctypes.pythonapi.Py_IncRef +# _Py_IncRef.restype = None +# _Py_IncRef.argtypes = (ctypes.py_object,) +# +# class _ctypes_PyAsyncGenWrappedValue(ctypes.Structure): +# _fields_ = [ +# ('PyObject_HEAD', ctypes.c_byte * object().__sizeof__()), +# ('agw_val', ctypes.py_object), +# ] +# def _wrap(value): +# box = _PyObject_GC_New(_PyAsyncGenWrappedValue_Type_ptr) +# raw = ctypes.cast(ctypes.c_void_p(id(box)), +# ctypes.POINTER(_ctypes_PyAsyncGenWrappedValue)) +# raw.contents.agw_val = value +# _Py_IncRef(value) +# return box +# +# def _unwrap(box): +# assert _is_wrapped(box) +# raw = ctypes.cast(ctypes.c_void_p(id(box)), +# ctypes.POINTER(_ctypes_PyAsyncGenWrappedValue)) +# value = raw.contents.agw_val +# _Py_IncRef(value) +# return value +# +# _PyAsyncGenWrappedValue_Type = type(_wrap(1)) +# def _is_wrapped(box): +# return isinstance(box, _PyAsyncGenWrappedValue_Type) + + +# The magic @coroutine decorator is how you write the bottom level of +# coroutine stacks -- 'async def' can only use 'await' = yield from; but +# eventually we must bottom out in a @coroutine that calls plain 'yield'. +@coroutine +def _yield_(value): + return (yield _wrap(value)) + + +# But we wrap the bare @coroutine version in an async def, because async def +# has the magic feature that users can get warnings messages if they forget to +# use 'await'. +async def yield_(value=None): + return await _yield_(value) + + +async def yield_from_(delegate): + # Transcribed with adaptations from: + # + # https://www.python.org/dev/peps/pep-0380/#formal-semantics + # + # This takes advantage of a sneaky trick: if an @async_generator-wrapped + # function calls another async function (like yield_from_), and that + # second async function calls yield_, then because of the hack we use to + # implement yield_, the yield_ will actually propagate through yield_from_ + # back to the @async_generator wrapper. So even though we're a regular + # function, we can directly yield values out of the calling async + # generator. + def unpack_StopAsyncIteration(e): + if e.args: + return e.args[0] + else: + return None + + _i = type(delegate).__aiter__(delegate) + if hasattr(_i, "__await__"): + _i = await _i + try: + _y = await type(_i).__anext__(_i) + except StopAsyncIteration as _e: + _r = unpack_StopAsyncIteration(_e) + else: + while 1: + try: + _s = await yield_(_y) + except GeneratorExit as _e: + try: + _m = _i.aclose + except AttributeError: + pass + else: + await _m() + raise _e + except BaseException as _e: + _x = sys.exc_info() + try: + _m = _i.athrow + except AttributeError: + raise _e + else: + try: + _y = await _m(*_x) + except StopAsyncIteration as _e: + _r = unpack_StopAsyncIteration(_e) + break + else: + try: + if _s is None: + _y = await type(_i).__anext__(_i) + else: + _y = await _i.asend(_s) + except StopAsyncIteration as _e: + _r = unpack_StopAsyncIteration(_e) + break + return _r + + +# This is the awaitable / iterator that implements asynciter.__anext__() and +# friends. +# +# Note: we can be sloppy about the distinction between +# +# type(self._it).__next__(self._it) +# +# and +# +# self._it.__next__() +# +# because we happen to know that self._it is not a general iterator object, +# but specifically a coroutine iterator object where these are equivalent. +class ANextIter: + def __init__(self, it, first_fn, *first_args): + self._it = it + self._first_fn = first_fn + self._first_args = first_args + + def __await__(self): + return self + + def __next__(self): + if self._first_fn is not None: + first_fn = self._first_fn + first_args = self._first_args + self._first_fn = self._first_args = None + return self._invoke(first_fn, *first_args) + else: + return self._invoke(self._it.__next__) + + def send(self, value): + return self._invoke(self._it.send, value) + + def throw(self, type, value=None, traceback=None): + return self._invoke(self._it.throw, type, value, traceback) + + def _invoke(self, fn, *args): + try: + result = fn(*args) + except StopIteration as e: + # The underlying generator returned, so we should signal the end + # of iteration. + raise StopAsyncIteration(e.value) + except StopAsyncIteration as e: + # PEP 479 says: if a generator raises Stop(Async)Iteration, then + # it should be wrapped into a RuntimeError. Python automatically + # enforces this for StopIteration; for StopAsyncIteration we need + # to it ourselves. + raise RuntimeError( + "async_generator raise StopAsyncIteration" + ) from e + if _is_wrapped(result): + raise StopIteration(_unwrap(result)) + else: + return result + + +UNSPECIFIED = object() +try: + from sys import get_asyncgen_hooks, set_asyncgen_hooks + +except ImportError: + import threading + + asyncgen_hooks = collections.namedtuple( + "asyncgen_hooks", ("firstiter", "finalizer") + ) + + class _hooks_storage(threading.local): + def __init__(self): + self.firstiter = None + self.finalizer = None + + _hooks = _hooks_storage() + + def get_asyncgen_hooks(): + return asyncgen_hooks( + firstiter=_hooks.firstiter, finalizer=_hooks.finalizer + ) + + def set_asyncgen_hooks(firstiter=UNSPECIFIED, finalizer=UNSPECIFIED): + if firstiter is not UNSPECIFIED: + if firstiter is None or callable(firstiter): + _hooks.firstiter = firstiter + else: + raise TypeError( + "callable firstiter expected, got {}".format( + type(firstiter).__name__ + ) + ) + + if finalizer is not UNSPECIFIED: + if finalizer is None or callable(finalizer): + _hooks.finalizer = finalizer + else: + raise TypeError( + "callable finalizer expected, got {}".format( + type(finalizer).__name__ + ) + ) + + +class AsyncGenerator: + # https://bitbucket.org/pypy/pypy/issues/2786: + # PyPy implements 'await' in a way that requires the frame object + # used to execute a coroutine to keep a weakref to that coroutine. + # During a GC pass, weakrefs to all doomed objects are broken + # before any of the doomed objects' finalizers are invoked. + # If an AsyncGenerator is unreachable, its _coroutine probably + # is too, and the weakref from ag._coroutine.cr_frame to + # ag._coroutine will be broken before ag.__del__ can do its + # one-turn close attempt or can schedule a full aclose() using + # the registered finalization hook. It doesn't look like the + # underlying issue is likely to be fully fixed anytime soon, + # so we work around it by preventing an AsyncGenerator and + # its _coroutine from being considered newly unreachable at + # the same time if the AsyncGenerator's finalizer might want + # to iterate the coroutine some more. + _pypy_issue2786_workaround = set() + + def __init__(self, coroutine): + self._coroutine = coroutine + self._it = coroutine.__await__() + self.ag_running = False + self._finalizer = None + self._closed = False + self._hooks_inited = False + + # On python 3.5.0 and 3.5.1, __aiter__ must be awaitable. + # Starting in 3.5.2, it should not be awaitable, and if it is, then it + # raises a PendingDeprecationWarning. + # See: + # https://www.python.org/dev/peps/pep-0492/#api-design-and-implementation-revisions + # https://docs.python.org/3/reference/datamodel.html#async-iterators + # https://bugs.python.org/issue27243 + if sys.version_info < (3, 5, 2): + + async def __aiter__(self): + return self + else: + + def __aiter__(self): + return self + + ################################################################ + # Introspection attributes + ################################################################ + + @property + def ag_code(self): + return self._coroutine.cr_code + + @property + def ag_frame(self): + return self._coroutine.cr_frame + + ################################################################ + # Core functionality + ################################################################ + + # These need to return awaitables, rather than being async functions, + # to match the native behavior where the firstiter hook is called + # immediately on asend()/etc, even if the coroutine that asend() + # produces isn't awaited for a bit. + + def __anext__(self): + return self._do_it(self._it.__next__) + + def asend(self, value): + return self._do_it(self._it.send, value) + + def athrow(self, type, value=None, traceback=None): + return self._do_it(self._it.throw, type, value, traceback) + + def _do_it(self, start_fn, *args): + if not self._hooks_inited: + self._hooks_inited = True + (firstiter, self._finalizer) = get_asyncgen_hooks() + if firstiter is not None: + firstiter(self) + if sys.implementation.name == "pypy": + self._pypy_issue2786_workaround.add(self._coroutine) + + # On CPython 3.5.2 (but not 3.5.0), coroutines get cranky if you try + # to iterate them after they're exhausted. Generators OTOH just raise + # StopIteration. We want to convert the one into the other, so we need + # to avoid iterating stopped coroutines. + if getcoroutinestate(self._coroutine) is CORO_CLOSED: + raise StopAsyncIteration() + + async def step(): + if self.ag_running: + raise ValueError("async generator already executing") + try: + self.ag_running = True + return await ANextIter(self._it, start_fn, *args) + except StopAsyncIteration: + self._pypy_issue2786_workaround.discard(self._coroutine) + raise + finally: + self.ag_running = False + + return step() + + ################################################################ + # Cleanup + ################################################################ + + async def aclose(self): + state = getcoroutinestate(self._coroutine) + if state is CORO_CLOSED or self._closed: + return + # Make sure that even if we raise "async_generator ignored + # GeneratorExit", and thus fail to exhaust the coroutine, + # __del__ doesn't complain again. + self._closed = True + if state is CORO_CREATED: + # Make sure that aclose() on an unstarted generator returns + # successfully and prevents future iteration. + self._it.close() + return + try: + await self.athrow(GeneratorExit) + except (GeneratorExit, StopAsyncIteration): + self._pypy_issue2786_workaround.discard(self._coroutine) + else: + raise RuntimeError("async_generator ignored GeneratorExit") + + def __del__(self): + self._pypy_issue2786_workaround.discard(self._coroutine) + if getcoroutinestate(self._coroutine) is CORO_CREATED: + # Never started, nothing to clean up, just suppress the "coroutine + # never awaited" message. + self._coroutine.close() + if getcoroutinestate(self._coroutine + ) is CORO_SUSPENDED and not self._closed: + if self._finalizer is not None: + self._finalizer(self) + else: + # Mimic the behavior of native generators on GC with no finalizer: + # throw in GeneratorExit, run for one turn, and complain if it didn't + # finish. + thrower = self.athrow(GeneratorExit) + try: + thrower.send(None) + except (GeneratorExit, StopAsyncIteration): + pass + except StopIteration: + raise RuntimeError("async_generator ignored GeneratorExit") + else: + raise RuntimeError( + "async_generator {!r} awaited during finalization; install " + "a finalization hook to support this, or wrap it in " + "'async with aclosing(...):'" + .format(self.ag_code.co_name) + ) + finally: + thrower.close() + + +if hasattr(collections.abc, "AsyncGenerator"): + collections.abc.AsyncGenerator.register(AsyncGenerator) + + +def async_generator(coroutine_maker): + @wraps(coroutine_maker) + def async_generator_maker(*args, **kwargs): + return AsyncGenerator(coroutine_maker(*args, **kwargs)) + + async_generator_maker._async_gen_function = id(async_generator_maker) + return async_generator_maker + + +def isasyncgen(obj): + if hasattr(inspect, "isasyncgen"): + if inspect.isasyncgen(obj): + return True + return isinstance(obj, AsyncGenerator) + + +def isasyncgenfunction(obj): + if hasattr(inspect, "isasyncgenfunction"): + if inspect.isasyncgenfunction(obj): + return True + return getattr(obj, "_async_gen_function", -1) == id(obj) diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.2.13.dist-info/REQUESTED b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/async_generator/_tests/__init__.py similarity index 100% rename from Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.2.13.dist-info/REQUESTED rename to Resources/WPy32-3720/python-3.7.2/Lib/site-packages/async_generator/_tests/__init__.py diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/async_generator/_tests/conftest.py b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/async_generator/_tests/conftest.py new file mode 100644 index 00000000..6c42d450 --- /dev/null +++ b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/async_generator/_tests/conftest.py @@ -0,0 +1,36 @@ +import pytest +from functools import wraps, partial +import inspect +import types + + +@types.coroutine +def mock_sleep(): + yield "mock_sleep" + + +# Wrap any 'async def' tests so that they get automatically iterated. +# We used to use pytest-asyncio as a convenient way to do this, but nowadays +# pytest-asyncio uses us! In addition to it being generally bad for our test +# infrastructure to depend on the code-under-test, this totally messes up +# coverage info because depending on pytest's plugin load order, we might get +# imported before pytest-cov can be loaded and start gathering coverage. +@pytest.hookimpl(tryfirst=True) +def pytest_pyfunc_call(pyfuncitem): + if inspect.iscoroutinefunction(pyfuncitem.obj): + fn = pyfuncitem.obj + + @wraps(fn) + def wrapper(**kwargs): + coro = fn(**kwargs) + try: + while True: + value = coro.send(None) + if value != "mock_sleep": # pragma: no cover + raise RuntimeError( + "coroutine runner confused: {!r}".format(value) + ) + except StopIteration: + pass + + pyfuncitem.obj = wrapper diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/async_generator/_tests/test_async_generator.py b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/async_generator/_tests/test_async_generator.py new file mode 100644 index 00000000..74636639 --- /dev/null +++ b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/async_generator/_tests/test_async_generator.py @@ -0,0 +1,1015 @@ +import pytest + +import types +import sys +import collections.abc +from functools import wraps +import gc + +from .conftest import mock_sleep +from .. import ( + async_generator, + yield_, + yield_from_, + isasyncgen, + isasyncgenfunction, + get_asyncgen_hooks, + set_asyncgen_hooks, +) + + +# like list(it) but works on async iterators +async def collect(ait): + items = [] + async for value in ait: + items.append(value) + return items + + +################################################################ +# +# Basic test +# +################################################################ + + +@async_generator +async def async_range(count): + for i in range(count): + print("Calling yield_({})".format(i)) + await yield_(i) + + +@async_generator +async def double(ait): + async for value in ait: + await yield_(value * 2) + await mock_sleep() + + +class HasAsyncGenMethod: + def __init__(self, factor): + self._factor = factor + + @async_generator + async def async_multiplied(self, ait): + async for value in ait: + await yield_(value * self._factor) + + +async def test_async_generator(): + assert await collect(async_range(10)) == list(range(10)) + assert (await collect(double(async_range(5))) == [0, 2, 4, 6, 8]) + + tripler = HasAsyncGenMethod(3) + assert ( + await + collect(tripler.async_multiplied(async_range(5))) == [0, 3, 6, 9, 12] + ) + + +@async_generator +async def agen_yield_no_arg(): + await yield_() + + +async def test_yield_no_arg(): + assert await collect(agen_yield_no_arg()) == [None] + + +################################################################ +# +# async_generators return value +# +################################################################ + + +@async_generator +async def async_gen_with_non_None_return(): + await yield_(1) + await yield_(2) + return "hi" + + +async def test_bad_return_value(): + gen = async_gen_with_non_None_return() + async for item in gen: # pragma: no branch + assert item == 1 + break + async for item in gen: # pragma: no branch + assert item == 2 + break + try: + await gen.__anext__() + except StopAsyncIteration as e: + assert e.args[0] == "hi" + + +################################################################ +# +# Exhausitve tests of the different ways to re-enter a coroutine. +# +# It used to be that re-entering via send/__next__ would work, but throw() +# immediately followed by an await yield_(...) wouldn't work, and the +# YieldWrapper object would propagate back out to the coroutine runner. +# +# Before I fixed this, the 'assert value is None' check below would fail +# (because of the YieldWrapper leaking out), and if you removed that +# assertion, then the code would appear to run successfully but the final list +# would just be [1, 3] instead of [1, 2, 3]. +# +################################################################ + + +class MyTestError(Exception): + pass + + +# This unconditionally raises a MyTestError exception, so from the outside +# it's equivalent to a simple 'raise MyTestError`. But, for this test to check +# the thing we want it to check, the point is that the exception must be +# thrown in from the coroutine runner -- this simulates something like an +# 'await sock.recv(...) -> TimeoutError'. +@types.coroutine +def hit_me(): + yield "hit me" + + +@types.coroutine +def number_me(): + assert (yield "number me") == 1 + + +@types.coroutine +def next_me(): + assert (yield "next me") is None + + +@async_generator +async def yield_after_different_entries(): + await yield_(1) + try: + await hit_me() + except MyTestError: + await yield_(2) + await number_me() + await yield_(3) + await next_me() + await yield_(4) + + +def hostile_coroutine_runner(coro): + coro_iter = coro.__await__() + value = None + while True: + try: + if value == "hit me": + value = coro_iter.throw(MyTestError()) + elif value == "number me": + value = coro_iter.send(1) + else: + assert value in (None, "next me") + value = coro_iter.__next__() + except StopIteration as exc: + return exc.value + + +def test_yield_different_entries(): + coro = collect(yield_after_different_entries()) + yielded = hostile_coroutine_runner(coro) + assert yielded == [1, 2, 3, 4] + + +async def test_reentrance_forbidden(): + @async_generator + async def recurse(): + async for obj in agen: # pragma: no branch + await yield_(obj) # pragma: no cover + + agen = recurse() + with pytest.raises(ValueError): + async for _ in agen: # pragma: no branch + pass # pragma: no cover + + +async def test_reentrance_forbidden_simultaneous_asends(): + @async_generator + async def f(): + await mock_sleep() + + ag = f() + sender1 = ag.asend(None) + sender2 = ag.asend(None) + assert sender1.send(None) == "mock_sleep" + with pytest.raises(ValueError): + sender2.send(None) + with pytest.raises(StopAsyncIteration): + sender1.send(None) + await ag.aclose() + + +# https://bugs.python.org/issue32526 +async def test_reentrance_forbidden_while_suspended_in_coroutine_runner(): + @async_generator + async def f(): + await mock_sleep() + await yield_("final yield") + + ag = f() + asend_coro = ag.asend(None) + fut = asend_coro.send(None) + assert fut == "mock_sleep" + # Now the async generator's frame is not executing, but a call to asend() + # *is* executing. Make sure that in this case, ag_running is True, and we + # can't start up another call to asend(). + assert ag.ag_running + with pytest.raises(ValueError): + await ag.asend(None) + # Clean up + with pytest.raises(StopIteration): + asend_coro.send(None) + with pytest.raises(StopAsyncIteration): + ag.asend(None).send(None) + + +################################################################ +# +# asend +# +################################################################ + + +@async_generator +async def asend_me(): + assert (await yield_(1)) == 2 + assert (await yield_(3)) == 4 + + +async def test_asend(): + aiter = asend_me() + assert (await aiter.__anext__()) == 1 + assert (await aiter.asend(2)) == 3 + with pytest.raises(StopAsyncIteration): + await aiter.asend(4) + + +################################################################ +# +# athrow +# +################################################################ + + +@async_generator +async def athrow_me(): + with pytest.raises(KeyError): + await yield_(1) + with pytest.raises(ValueError): + await yield_(2) + await yield_(3) + + +async def test_athrow(): + aiter = athrow_me() + assert (await aiter.__anext__()) == 1 + assert (await aiter.athrow(KeyError("oops"))) == 2 + assert (await aiter.athrow(ValueError("oops"))) == 3 + with pytest.raises(OSError): + await aiter.athrow(OSError("oops")) + + +################################################################ +# +# aclose +# +################################################################ + + +@async_generator +async def close_me_aiter(track): + try: + await yield_(1) + except GeneratorExit: + track[0] = "closed" + raise + else: # pragma: no cover + track[0] = "wtf" + + +async def test_aclose(): + track = [None] + aiter = close_me_aiter(track) + async for obj in aiter: # pragma: no branch + assert obj == 1 + break + assert track[0] is None + await aiter.aclose() + assert track[0] == "closed" + + +async def test_aclose_on_unstarted_generator(): + aiter = close_me_aiter([None]) + await aiter.aclose() + async for obj in aiter: + assert False # pragma: no cover + + +async def test_aclose_on_finished_generator(): + aiter = async_range(3) + async for obj in aiter: + pass # pragma: no cover + await aiter.aclose() + + +@async_generator +async def sync_yield_during_aclose(): + try: + await yield_(1) + finally: + await mock_sleep() + + +@async_generator +async def async_yield_during_aclose(): + try: + await yield_(1) + finally: + await yield_(2) + + +async def test_aclose_yielding(): + aiter = sync_yield_during_aclose() + assert (await aiter.__anext__()) == 1 + # Doesn't raise: + await aiter.aclose() + + aiter = async_yield_during_aclose() + assert (await aiter.__anext__()) == 1 + with pytest.raises(RuntimeError): + await aiter.aclose() + + +################################################################ +# +# yield from +# +################################################################ + + +@async_generator +async def async_range_twice(count): + await yield_from_(async_range(count)) + await yield_(None) + await yield_from_(async_range(count)) + + +if sys.version_info >= (3, 6): + exec( + """ +async def native_async_range(count): + for i in range(count): + yield i + +# XX uncomment if/when we re-enable the ctypes hacks: +# async def native_async_range_twice(count): +# # make sure yield_from_ works inside a native async generator +# await yield_from_(async_range(count)) +# yield None +# # make sure we can yield_from_ a native async generator +# await yield_from_(native_async_range(count)) + """ + ) + + +async def test_async_yield_from_(): + assert await collect(async_range_twice(3)) == [ + 0, + 1, + 2, + None, + 0, + 1, + 2, + ] + + if sys.version_info >= (3, 6): + # Make sure we can yield_from_ a native generator + @async_generator + async def yield_from_native(): + await yield_from_(native_async_range(3)) + + assert await collect(yield_from_native()) == [0, 1, 2] + + # XX uncomment if/when we re-enable the ctypes hacks: + # if sys.version_info >= (3, 6): + # assert await collect(native_async_range_twice(3)) == [ + # 0, 1, 2, None, 0, 1, 2, + # ] + + +@async_generator +async def doubles_sends(value): + while True: + value = await yield_(2 * value) + + +@async_generator +async def wraps_doubles_sends(value): + await yield_from_(doubles_sends(value)) + + +async def test_async_yield_from_asend(): + gen = wraps_doubles_sends(10) + await gen.__anext__() == 20 + assert (await gen.asend(2)) == 4 + assert (await gen.asend(5)) == 10 + assert (await gen.asend(0)) == 0 + await gen.aclose() + + +async def test_async_yield_from_athrow(): + gen = async_range_twice(2) + assert (await gen.__anext__()) == 0 + with pytest.raises(ValueError): + await gen.athrow(ValueError) + + +@async_generator +async def returns_1(): + await yield_(0) + return 1 + + +@async_generator +async def yields_from_returns_1(): + await yield_(await yield_from_(returns_1())) + + +async def test_async_yield_from_return_value(): + assert await collect(yields_from_returns_1()) == [0, 1] + + +# Special cases to get coverage +async def test_yield_from_empty(): + @async_generator + async def empty(): + return "done" + + @async_generator + async def yield_from_empty(): + assert (await yield_from_(empty())) == "done" + + assert await collect(yield_from_empty()) == [] + + +async def test_yield_from_non_generator(): + class Countdown: + def __init__(self, count): + self.count = count + self.closed = False + + if sys.version_info < (3, 5, 2): + + async def __aiter__(self): + return self + else: + + def __aiter__(self): + return self + + async def __anext__(self): + self.count -= 1 + if self.count < 0: + raise StopAsyncIteration("boom") + return self.count + + async def aclose(self): + self.closed = True + + @async_generator + async def yield_from_countdown(count, happenings): + try: + c = Countdown(count) + assert (await yield_from_(c)) == "boom" + except BaseException as e: + if c.closed: + happenings.append("countdown closed") + happenings.append("raise") + return e + + h = [] + assert await collect(yield_from_countdown(3, h)) == [2, 1, 0] + assert h == [] + + # Throwing into a yield_from_(object with no athrow) just raises the + # exception in the generator. + h = [] + agen = yield_from_countdown(3, h) + assert await agen.__anext__() == 2 + exc = ValueError("x") + try: + await agen.athrow(exc) + except StopAsyncIteration as e: + assert e.args[0] is exc + assert h == ["raise"] + + # Calling aclose on the generator calls aclose on the iterator + h = [] + agen = yield_from_countdown(3, h) + assert await agen.__anext__() == 2 + await agen.aclose() + assert h == ["countdown closed", "raise"] + + # Throwing GeneratorExit into the generator calls *aclose* on the iterator + # (!) + h = [] + agen = yield_from_countdown(3, h) + assert await agen.__anext__() == 2 + exc = GeneratorExit() + with pytest.raises(StopAsyncIteration): + await agen.athrow(exc) + assert h == ["countdown closed", "raise"] + + +async def test_yield_from_non_generator_with_no_aclose(): + class Countdown: + def __init__(self, count): + self.count = count + self.closed = False + + if sys.version_info < (3, 5, 2): + + async def __aiter__(self): + return self + else: + + def __aiter__(self): + return self + + async def __anext__(self): + self.count -= 1 + if self.count < 0: + raise StopAsyncIteration("boom") + return self.count + + @async_generator + async def yield_from_countdown(count): + return await yield_from_(Countdown(count)) + + assert await collect(yield_from_countdown(3)) == [2, 1, 0] + + agen = yield_from_countdown(3) + assert await agen.__anext__() == 2 + assert await agen.__anext__() == 1 + # It's OK that Countdown has no aclose + await agen.aclose() + + +async def test_yield_from_with_old_style_aiter(): + # old-style 'async def __aiter__' should still work even on newer pythons + class Countdown: + def __init__(self, count): + self.count = count + self.closed = False + + # This is wrong, that's the point + async def __aiter__(self): + return self + + async def __anext__(self): + self.count -= 1 + if self.count < 0: + raise StopAsyncIteration("boom") + return self.count + + @async_generator + async def yield_from_countdown(count): + return await yield_from_(Countdown(count)) + + assert await collect(yield_from_countdown(3)) == [2, 1, 0] + + +async def test_yield_from_athrow_raises_StopAsyncIteration(): + @async_generator + async def catch(): + try: + while True: + await yield_("hi") + except Exception as exc: + return ("bye", exc) + + @async_generator + async def yield_from_catch(): + return await yield_from_(catch()) + + agen = yield_from_catch() + assert await agen.__anext__() == "hi" + assert await agen.__anext__() == "hi" + thrown = ValueError("oops") + try: + print(await agen.athrow(thrown)) + except StopAsyncIteration as caught: + assert caught.args == (("bye", thrown),) + else: + raise AssertionError # pragma: no cover + + +################################################################ +# __del__ +################################################################ + + +async def test___del__(capfd): + completions = 0 + + @async_generator + async def awaits_when_unwinding(): + await yield_(0) + try: + await yield_(1) + finally: + await mock_sleep() + try: + await yield_(2) + finally: + nonlocal completions + completions += 1 + + gen = awaits_when_unwinding() + # Hasn't started yet, so no problem + gen.__del__() + + gen = awaits_when_unwinding() + assert await collect(gen) == [0, 1, 2] + # Exhausted, so no problem + gen.__del__() + + for stop_after_turn in (1, 2, 3): + gen = awaits_when_unwinding() + for turn in range(stop_after_turn): + assert await gen.__anext__() == turn + await gen.aclose() + # Closed, so no problem + gen.__del__() + + for stop_after_turn in (1, 2, 3): + gen = awaits_when_unwinding() + for turn in range(stop_after_turn): + assert await gen.__anext__() == turn + + if stop_after_turn == 2: + # Stopped in the middle of a try/finally that awaits in the finally, + # so __del__ can't cleanup. + with pytest.raises(RuntimeError) as info: + gen.__del__() + assert "awaited during finalization; install a finalization hook" in str( + info.value + ) + else: + # Can clean up without awaiting, so __del__ is fine + gen.__del__() + + assert completions == 3 + + @async_generator + async def yields_when_unwinding(): + try: + await yield_(1) + finally: + await yield_(2) + + gen = yields_when_unwinding() + assert await gen.__anext__() == 1 + with pytest.raises(RuntimeError) as info: + gen.__del__() + + +################################################################ +# introspection +################################################################ + + +def test_isasyncgen(): + assert not isasyncgen(async_range) + assert isasyncgen(async_range(10)) + + if sys.version_info >= (3, 6): + assert not isasyncgen(native_async_range) + assert isasyncgen(native_async_range(10)) + + +def test_isasyncgenfunction(): + assert isasyncgenfunction(async_range) + assert not isasyncgenfunction(list) + assert not isasyncgenfunction(async_range(10)) + + if sys.version_info >= (3, 6): + assert isasyncgenfunction(native_async_range) + assert not isasyncgenfunction(native_async_range(10)) + + +# Very subtle bug: functools.wraps copies across the entire contents of the +# wrapped function's __dict__. We used to use a simple _is_async_gen=True +# attribute to mark async generators. But if we do that, then simple wrappers +# like async_range_wrapper *do* return True for isasyncgenfunction. But that's +# not how inspect.isasyncgenfunction works, and it also caused problems for +# sphinxcontrib-trio, because given a function like: +# +# @acontextmanager +# @async_generator +# async def async_cm(): +# ... +# +# then we end up with async_cm introspecting as both an async context manager +# and an async generator, and it doesn't know who to believe. With the +# correct, inspect.isasyncgenfunction-compliant behavior, we have async_cm +# introspecting as an async context manager, and async_cm.__wrapped__ +# introspecting as an async generator. +def test_isasyncgenfunction_is_not_inherited_by_wrappers(): + @wraps(async_range) + def async_range_wrapper(*args, **kwargs): # pragma: no cover + return async_range(*args, **kwargs) + + assert not isasyncgenfunction(async_range_wrapper) + assert isasyncgenfunction(async_range_wrapper.__wrapped__) + + +def test_collections_abc_AsyncGenerator(): + if hasattr(collections.abc, "AsyncGenerator"): + assert isinstance(async_range(10), collections.abc.AsyncGenerator) + + +async def test_ag_attributes(): + @async_generator + async def f(): + x = 1 + await yield_() + + agen = f() + assert agen.ag_code.co_name == "f" + async for _ in agen: # pragma: no branch + assert agen.ag_frame.f_locals["x"] == 1 + break + + +################################################################ +# Finicky tests to check that the overly clever ctype stuff has plausible +# refcounting + +from .. import _impl + + +@pytest.mark.skipif(not hasattr(sys, "getrefcount"), reason="CPython only") +def test_refcnt(): + x = object() + print(sys.getrefcount(x)) + print(sys.getrefcount(x)) + print(sys.getrefcount(x)) + print(sys.getrefcount(x)) + base_count = sys.getrefcount(x) + l = [_impl._wrap(x) for _ in range(100)] + print(sys.getrefcount(x)) + print(sys.getrefcount(x)) + print(sys.getrefcount(x)) + assert sys.getrefcount(x) >= base_count + 100 + l2 = [_impl._unwrap(box) for box in l] + assert sys.getrefcount(x) >= base_count + 200 + print(sys.getrefcount(x)) + print(sys.getrefcount(x)) + print(sys.getrefcount(x)) + print(sys.getrefcount(x)) + del l + print(sys.getrefcount(x)) + print(sys.getrefcount(x)) + print(sys.getrefcount(x)) + del l2 + print(sys.getrefcount(x)) + print(sys.getrefcount(x)) + print(sys.getrefcount(x)) + assert sys.getrefcount(x) == base_count + print(sys.getrefcount(x)) + + +################################################################ +# +# Edge cases +# +################################################################ + + +# PEP 479: StopIteration or StopAsyncIteration exiting from inside an async +# generator should produce a RuntimeError with the __cause__ set to the +# original exception. Note that contextlib.asynccontextmanager depends on this +# behavior. +@async_generator +async def lets_exception_out(): + await yield_() + + +async def test_throw_StopIteration_or_StopAsyncIteration(): + for cls in [StopIteration, StopAsyncIteration]: + agen = lets_exception_out() + await agen.asend(None) + exc = cls() + with pytest.raises(RuntimeError) as excinfo: + await agen.athrow(exc) + assert excinfo.type is RuntimeError + assert excinfo.value.__cause__ is exc + + +# No "coroutine was never awaited" warnings for async generators that are not +# iterated +async def test_no_spurious_unawaited_coroutine_warning(recwarn): + agen = async_range(10) + del agen + + # Run collection a few times to make sure any + # loops/resurrection/etc. stuff gets fully handled (necessary on pypy) + for _ in range(4): + gc.collect() + + # I've seen DeprecationWarnings here triggered by pytest-asyncio, so let's + # filter for RuntimeWarning. But if there are no warnings at all, then + # that's OK too, so tell coverage not to worry about it. + for msg in recwarn: # pragma: no cover + print(msg) + assert not issubclass(msg.category, RuntimeWarning) + + +################################################################ +# +# GC hooks +# +################################################################ + + +@pytest.fixture +def local_asyncgen_hooks(): + old_hooks = get_asyncgen_hooks() + yield + set_asyncgen_hooks(*old_hooks) + + +def test_gc_hooks_interface(local_asyncgen_hooks): + def one(agen): # pragma: no cover + pass + + def two(agen): # pragma: no cover + pass + + set_asyncgen_hooks(None, None) + assert get_asyncgen_hooks() == (None, None) + set_asyncgen_hooks(finalizer=two) + assert get_asyncgen_hooks() == (None, two) + set_asyncgen_hooks(firstiter=one) + assert get_asyncgen_hooks() == (one, two) + set_asyncgen_hooks(finalizer=None, firstiter=two) + assert get_asyncgen_hooks() == (two, None) + set_asyncgen_hooks(None, one) + assert get_asyncgen_hooks() == (None, one) + tup = (one, two) + set_asyncgen_hooks(*tup) + assert get_asyncgen_hooks() == tup + + with pytest.raises(TypeError): + set_asyncgen_hooks(firstiter=42) + + with pytest.raises(TypeError): + set_asyncgen_hooks(finalizer=False) + + def in_thread(results): + results.append(get_asyncgen_hooks()) + set_asyncgen_hooks(two, one) + results.append(get_asyncgen_hooks()) + + from threading import Thread + results = [] + thread = Thread(target=in_thread, args=(results,)) + thread.start() + thread.join() + assert results == [(None, None), (two, one)] + assert get_asyncgen_hooks() == (one, two) + + +async def test_gc_hooks_behavior(local_asyncgen_hooks): + events = [] + to_finalize = [] + + def firstiter(agen): + events.append("firstiter {}".format(agen.ag_frame.f_locals["ident"])) + + def finalizer(agen): + events.append("finalizer {}".format(agen.ag_frame.f_locals["ident"])) + to_finalize.append(agen) + + @async_generator + async def agen(ident): + events.append("yield 1 {}".format(ident)) + await yield_(1) + try: + events.append("yield 2 {}".format(ident)) + await yield_(2) + events.append("after yield 2 {}".format(ident)) + finally: + events.append("mock_sleep {}".format(ident)) + await mock_sleep() + try: + events.append("yield 3 {}".format(ident)) + await yield_(3) + finally: + events.append("unwind 3 {}".format(ident)) + # this one is included to make sure we _don't_ execute it + events.append("done {}".format(ident)) # pragma: no cover + + async def anext_verbosely(iter, ident): + events.append("before asend {}".format(ident)) + sender = iter.asend(None) + events.append("before send {}".format(ident)) + await sender + events.append("after asend {}".format(ident)) + + # Ensure that firstiter is called immediately on asend(), + # before the first turn of the coroutine that asend() returns, + # to match the behavior of native generators. + # Ensure that the firstiter that gets used is the one in effect + # at the time of that first call, rather than at the time of iteration. + iterA = agen("A") + iterB = agen("B") + await anext_verbosely(iterA, "A") + set_asyncgen_hooks(firstiter, finalizer) + await anext_verbosely(iterB, "B") + iterC = agen("C") + await anext_verbosely(iterC, "C") + + assert events == [ + "before asend A", "before send A", "yield 1 A", "after asend A", + "before asend B", "firstiter B", "before send B", "yield 1 B", + "after asend B", "before asend C", "firstiter C", "before send C", + "yield 1 C", "after asend C" + ] + del events[:] + + # Ensure that firstiter is only called once, even if we create + # two asend() coroutines before iterating either of them. + iterX = agen("X") + sender1 = iterX.asend(None) + sender2 = iterX.asend(None) + events.append("before close") + sender1.close() + sender2.close() + await iterX.aclose() + assert events == ["firstiter X", "before close"] + del events[:] + + from weakref import ref + refA, refB, refC = map(ref, (iterA, iterB, iterC)) + + # iterA uses the finalizer that was in effect when it started, i.e. no finalizer + await iterA.__anext__() + await iterA.__anext__() + del iterA + # Do multiple GC passes since we're deliberately shielding the + # coroutine objects from the first pass due to PyPy issue 2786. + for _ in range(4): + gc.collect() + assert refA() is None + assert events == [ + "yield 2 A", "after yield 2 A", "mock_sleep A", "yield 3 A", + "unwind 3 A" + ] + assert not to_finalize + del events[:] + + # iterB and iterC do use our finalizer + await iterC.__anext__() + await iterB.__anext__() + await iterC.__anext__() + idB, idC = id(iterB), id(iterC) + del iterB + for _ in range(4): + gc.collect() + del iterC + for _ in range(4): + gc.collect() + assert events == [ + "yield 2 C", "yield 2 B", "after yield 2 C", "mock_sleep C", + "yield 3 C", "finalizer B", "finalizer C" + ] + del events[:] + + # finalizer invokes aclose() is not called again once the revived reference drops + assert list(map(id, to_finalize)) == [idB, idC] + events.append("before aclose B") + await to_finalize[0].aclose() + events.append("before aclose C") + await to_finalize[1].aclose() + events.append("after aclose both") + del to_finalize[:] + for _ in range(4): + gc.collect() + assert refB() is None and refC() is None + + assert events == [ + "before aclose B", "mock_sleep B", "before aclose C", "unwind 3 C", + "after aclose both" + ] diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/async_generator/_tests/test_util.py b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/async_generator/_tests/test_util.py new file mode 100644 index 00000000..16961d12 --- /dev/null +++ b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/async_generator/_tests/test_util.py @@ -0,0 +1,227 @@ +import pytest + +from .. import aclosing, async_generator, yield_, asynccontextmanager + + +@async_generator +async def async_range(count, closed_slot): + try: + for i in range(count): # pragma: no branch + await yield_(i) + except GeneratorExit: + closed_slot[0] = True + + +async def test_aclosing(): + closed_slot = [False] + async with aclosing(async_range(10, closed_slot)) as gen: + it = iter(range(10)) + async for item in gen: # pragma: no branch + assert item == next(it) + if item == 4: + break + assert closed_slot[0] + + closed_slot = [False] + try: + async with aclosing(async_range(10, closed_slot)) as gen: + it = iter(range(10)) + async for item in gen: # pragma: no branch + assert item == next(it) + if item == 4: + raise ValueError() + except ValueError: + pass + assert closed_slot[0] + + +async def test_contextmanager_do_not_unchain_non_stopiteration_exceptions(): + @asynccontextmanager + @async_generator + async def manager_issue29692(): + try: + await yield_() + except Exception as exc: + raise RuntimeError('issue29692:Chained') from exc + + with pytest.raises(RuntimeError) as excinfo: + async with manager_issue29692(): + raise ZeroDivisionError + assert excinfo.value.args[0] == 'issue29692:Chained' + assert isinstance(excinfo.value.__cause__, ZeroDivisionError) + + # This is a little funky because of implementation details in + # async_generator It can all go away once we stop supporting Python3.5 + with pytest.raises(RuntimeError) as excinfo: + async with manager_issue29692(): + exc = StopIteration('issue29692:Unchained') + raise exc + assert excinfo.value.args[0] == 'issue29692:Chained' + cause = excinfo.value.__cause__ + assert cause.args[0] == 'generator raised StopIteration' + assert cause.__cause__ is exc + + with pytest.raises(StopAsyncIteration) as excinfo: + async with manager_issue29692(): + raise StopAsyncIteration('issue29692:Unchained') + assert excinfo.value.args[0] == 'issue29692:Unchained' + assert excinfo.value.__cause__ is None + + @asynccontextmanager + @async_generator + async def noop_async_context_manager(): + await yield_() + + with pytest.raises(StopIteration): + async with noop_async_context_manager(): + raise StopIteration + + +# Native async generators are only available from Python 3.6 and onwards +nativeasyncgenerators = True +try: + exec( + """ +@asynccontextmanager +async def manager_issue29692_2(): + try: + yield + except Exception as exc: + raise RuntimeError('issue29692:Chained') from exc +""" + ) +except SyntaxError: + nativeasyncgenerators = False + + +@pytest.mark.skipif( + not nativeasyncgenerators, + reason="Python < 3.6 doesn't have native async generators" +) +async def test_native_contextmanager_do_not_unchain_non_stopiteration_exceptions( +): + + with pytest.raises(RuntimeError) as excinfo: + async with manager_issue29692_2(): + raise ZeroDivisionError + assert excinfo.value.args[0] == 'issue29692:Chained' + assert isinstance(excinfo.value.__cause__, ZeroDivisionError) + + for cls in [StopIteration, StopAsyncIteration]: + with pytest.raises(cls) as excinfo: + async with manager_issue29692_2(): + raise cls('issue29692:Unchained') + assert excinfo.value.args[0] == 'issue29692:Unchained' + assert excinfo.value.__cause__ is None + + +async def test_asynccontextmanager_exception_passthrough(): + # This was the cause of annoying coverage flapping, see gh-140 + @asynccontextmanager + @async_generator + async def noop_async_context_manager(): + await yield_() + + for exc_type in [StopAsyncIteration, RuntimeError, ValueError]: + with pytest.raises(exc_type): + async with noop_async_context_manager(): + raise exc_type + + # And let's also check a boring nothing pass-through while we're at it + async with noop_async_context_manager(): + pass + + +async def test_asynccontextmanager_catches_exception(): + @asynccontextmanager + @async_generator + async def catch_it(): + with pytest.raises(ValueError): + await yield_() + + async with catch_it(): + raise ValueError + + +async def test_asynccontextmanager_different_exception(): + @asynccontextmanager + @async_generator + async def switch_it(): + try: + await yield_() + except KeyError: + raise ValueError + + with pytest.raises(ValueError): + async with switch_it(): + raise KeyError + + +async def test_asynccontextmanager_nice_message_on_sync_enter(): + @asynccontextmanager + @async_generator + async def xxx(): # pragma: no cover + await yield_() + + cm = xxx() + + with pytest.raises(RuntimeError) as excinfo: + with cm: + pass # pragma: no cover + + assert "async with" in str(excinfo.value) + + async with cm: + pass + + +async def test_asynccontextmanager_no_yield(): + @asynccontextmanager + @async_generator + async def yeehaw(): + pass + + with pytest.raises(RuntimeError) as excinfo: + async with yeehaw(): + assert False # pragma: no cover + + assert "didn't yield" in str(excinfo.value) + + +async def test_asynccontextmanager_too_many_yields(): + closed_count = 0 + + @asynccontextmanager + @async_generator + async def doubleyield(): + try: + await yield_() + except Exception: + pass + try: + await yield_() + finally: + nonlocal closed_count + closed_count += 1 + + with pytest.raises(RuntimeError) as excinfo: + async with doubleyield(): + pass + + assert "didn't stop" in str(excinfo.value) + assert closed_count == 1 + + with pytest.raises(RuntimeError) as excinfo: + async with doubleyield(): + raise ValueError + + assert "didn't stop after athrow" in str(excinfo.value) + assert closed_count == 2 + + +async def test_asynccontextmanager_requires_asyncgenfunction(): + with pytest.raises(TypeError): + + @asynccontextmanager + def syncgen(): # pragma: no cover + yield diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/async_generator/_util.py b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/async_generator/_util.py new file mode 100644 index 00000000..aa6f1138 --- /dev/null +++ b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/async_generator/_util.py @@ -0,0 +1,110 @@ +import sys +from functools import wraps +from ._impl import isasyncgenfunction + + +class aclosing: + def __init__(self, aiter): + self._aiter = aiter + + async def __aenter__(self): + return self._aiter + + async def __aexit__(self, *args): + await self._aiter.aclose() + + +# Very much derived from the one in contextlib, by copy/pasting and then +# asyncifying everything. (Also I dropped the obscure support for using +# context managers as function decorators. It could be re-added; I just +# couldn't be bothered.) +# So this is a derivative work licensed under the PSF License, which requires +# the following notice: +# +# Copyright © 2001-2017 Python Software Foundation; All Rights Reserved +class _AsyncGeneratorContextManager: + def __init__(self, func, args, kwds): + self._func_name = func.__name__ + self._agen = func(*args, **kwds).__aiter__() + + async def __aenter__(self): + if sys.version_info < (3, 5, 2): + self._agen = await self._agen + try: + return await self._agen.asend(None) + except StopAsyncIteration: + raise RuntimeError("async generator didn't yield") from None + + async def __aexit__(self, type, value, traceback): + async with aclosing(self._agen): + if type is None: + try: + await self._agen.asend(None) + except StopAsyncIteration: + return False + else: + raise RuntimeError("async generator didn't stop") + else: + # It used to be possible to have type != None, value == None: + # https://bugs.python.org/issue1705170 + # but AFAICT this can't happen anymore. + assert value is not None + try: + await self._agen.athrow(type, value, traceback) + raise RuntimeError( + "async generator didn't stop after athrow()" + ) + except StopAsyncIteration as exc: + # Suppress StopIteration *unless* it's the same exception + # that was passed to throw(). This prevents a + # StopIteration raised inside the "with" statement from + # being suppressed. + return (exc is not value) + except RuntimeError as exc: + # Don't re-raise the passed in exception. (issue27112) + if exc is value: + return False + # Likewise, avoid suppressing if a StopIteration exception + # was passed to throw() and later wrapped into a + # RuntimeError (see PEP 479). + if (isinstance(value, (StopIteration, StopAsyncIteration)) + and exc.__cause__ is value): + return False + raise + except: + # only re-raise if it's *not* the exception that was + # passed to throw(), because __exit__() must not raise an + # exception unless __exit__() itself failed. But throw() + # has to raise the exception to signal propagation, so + # this fixes the impedance mismatch between the throw() + # protocol and the __exit__() protocol. + # + if sys.exc_info()[1] is value: + return False + raise + + def __enter__(self): + raise RuntimeError( + "use 'async with {func_name}(...)', not 'with {func_name}(...)'". + format(func_name=self._func_name) + ) + + def __exit__(self): # pragma: no cover + assert False, """Never called, but should be defined""" + + +def asynccontextmanager(func): + """Like @contextmanager, but async.""" + if not isasyncgenfunction(func): + raise TypeError( + "must be an async generator (native or from async_generator; " + "if using @async_generator then @acontextmanager must be on top." + ) + + @wraps(func) + def helper(*args, **kwds): + return _AsyncGeneratorContextManager(func, args, kwds) + + # A hint for sphinxcontrib-trio: + helper.__returns_acontextmanager__ = True + return helper diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/async_generator/_version.py b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/async_generator/_version.py new file mode 100644 index 00000000..bb438dad --- /dev/null +++ b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/async_generator/_version.py @@ -0,0 +1 @@ +__version__ = "1.10" diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/attr/__init__.py b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/attr/__init__.py new file mode 100644 index 00000000..386305d6 --- /dev/null +++ b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/attr/__init__.py @@ -0,0 +1,79 @@ +# SPDX-License-Identifier: MIT + + +import sys + +from functools import partial + +from . import converters, exceptions, filters, setters, validators +from ._cmp import cmp_using +from ._config import get_run_validators, set_run_validators +from ._funcs import asdict, assoc, astuple, evolve, has, resolve_types +from ._make import ( + NOTHING, + Attribute, + Factory, + attrib, + attrs, + fields, + fields_dict, + make_class, + validate, +) +from ._version_info import VersionInfo + + +__version__ = "22.1.0" +__version_info__ = VersionInfo._from_version_string(__version__) + +__title__ = "attrs" +__description__ = "Classes Without Boilerplate" +__url__ = "https://www.attrs.org/" +__uri__ = __url__ +__doc__ = __description__ + " <" + __uri__ + ">" + +__author__ = "Hynek Schlawack" +__email__ = "hs@ox.cx" + +__license__ = "MIT" +__copyright__ = "Copyright (c) 2015 Hynek Schlawack" + + +s = attributes = attrs +ib = attr = attrib +dataclass = partial(attrs, auto_attribs=True) # happy Easter ;) + +__all__ = [ + "Attribute", + "Factory", + "NOTHING", + "asdict", + "assoc", + "astuple", + "attr", + "attrib", + "attributes", + "attrs", + "cmp_using", + "converters", + "evolve", + "exceptions", + "fields", + "fields_dict", + "filters", + "get_run_validators", + "has", + "ib", + "make_class", + "resolve_types", + "s", + "set_run_validators", + "setters", + "validate", + "validators", +] + +if sys.version_info[:2] >= (3, 6): + from ._next_gen import define, field, frozen, mutable # noqa: F401 + + __all__.extend(("define", "field", "frozen", "mutable")) diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/attr/__init__.pyi b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/attr/__init__.pyi new file mode 100644 index 00000000..03cc4c82 --- /dev/null +++ b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/attr/__init__.pyi @@ -0,0 +1,486 @@ +import sys + +from typing import ( + Any, + Callable, + ClassVar, + Dict, + Generic, + List, + Mapping, + Optional, + Protocol, + Sequence, + Tuple, + Type, + TypeVar, + Union, + overload, +) + +# `import X as X` is required to make these public +from . import converters as converters +from . import exceptions as exceptions +from . import filters as filters +from . import setters as setters +from . import validators as validators +from ._cmp import cmp_using as cmp_using +from ._version_info import VersionInfo + +__version__: str +__version_info__: VersionInfo +__title__: str +__description__: str +__url__: str +__uri__: str +__author__: str +__email__: str +__license__: str +__copyright__: str + +_T = TypeVar("_T") +_C = TypeVar("_C", bound=type) + +_EqOrderType = Union[bool, Callable[[Any], Any]] +_ValidatorType = Callable[[Any, Attribute[_T], _T], Any] +_ConverterType = Callable[[Any], Any] +_FilterType = Callable[[Attribute[_T], _T], bool] +_ReprType = Callable[[Any], str] +_ReprArgType = Union[bool, _ReprType] +_OnSetAttrType = Callable[[Any, Attribute[Any], Any], Any] +_OnSetAttrArgType = Union[ + _OnSetAttrType, List[_OnSetAttrType], setters._NoOpType +] +_FieldTransformer = Callable[ + [type, List[Attribute[Any]]], List[Attribute[Any]] +] +# FIXME: in reality, if multiple validators are passed they must be in a list +# or tuple, but those are invariant and so would prevent subtypes of +# _ValidatorType from working when passed in a list or tuple. +_ValidatorArgType = Union[_ValidatorType[_T], Sequence[_ValidatorType[_T]]] + +# A protocol to be able to statically accept an attrs class. +class AttrsInstance(Protocol): + __attrs_attrs__: ClassVar[Any] + +# _make -- + +NOTHING: object + +# NOTE: Factory lies about its return type to make this possible: +# `x: List[int] # = Factory(list)` +# Work around mypy issue #4554 in the common case by using an overload. +if sys.version_info >= (3, 8): + from typing import Literal + @overload + def Factory(factory: Callable[[], _T]) -> _T: ... + @overload + def Factory( + factory: Callable[[Any], _T], + takes_self: Literal[True], + ) -> _T: ... + @overload + def Factory( + factory: Callable[[], _T], + takes_self: Literal[False], + ) -> _T: ... + +else: + @overload + def Factory(factory: Callable[[], _T]) -> _T: ... + @overload + def Factory( + factory: Union[Callable[[Any], _T], Callable[[], _T]], + takes_self: bool = ..., + ) -> _T: ... + +# Static type inference support via __dataclass_transform__ implemented as per: +# https://github.com/microsoft/pyright/blob/1.1.135/specs/dataclass_transforms.md +# This annotation must be applied to all overloads of "define" and "attrs" +# +# NOTE: This is a typing construct and does not exist at runtime. Extensions +# wrapping attrs decorators should declare a separate __dataclass_transform__ +# signature in the extension module using the specification linked above to +# provide pyright support. +def __dataclass_transform__( + *, + eq_default: bool = True, + order_default: bool = False, + kw_only_default: bool = False, + field_descriptors: Tuple[Union[type, Callable[..., Any]], ...] = (()), +) -> Callable[[_T], _T]: ... + +class Attribute(Generic[_T]): + name: str + default: Optional[_T] + validator: Optional[_ValidatorType[_T]] + repr: _ReprArgType + cmp: _EqOrderType + eq: _EqOrderType + order: _EqOrderType + hash: Optional[bool] + init: bool + converter: Optional[_ConverterType] + metadata: Dict[Any, Any] + type: Optional[Type[_T]] + kw_only: bool + on_setattr: _OnSetAttrType + def evolve(self, **changes: Any) -> "Attribute[Any]": ... + +# NOTE: We had several choices for the annotation to use for type arg: +# 1) Type[_T] +# - Pros: Handles simple cases correctly +# - Cons: Might produce less informative errors in the case of conflicting +# TypeVars e.g. `attr.ib(default='bad', type=int)` +# 2) Callable[..., _T] +# - Pros: Better error messages than #1 for conflicting TypeVars +# - Cons: Terrible error messages for validator checks. +# e.g. attr.ib(type=int, validator=validate_str) +# -> error: Cannot infer function type argument +# 3) type (and do all of the work in the mypy plugin) +# - Pros: Simple here, and we could customize the plugin with our own errors. +# - Cons: Would need to write mypy plugin code to handle all the cases. +# We chose option #1. + +# `attr` lies about its return type to make the following possible: +# attr() -> Any +# attr(8) -> int +# attr(validator=) -> Whatever the callable expects. +# This makes this type of assignments possible: +# x: int = attr(8) +# +# This form catches explicit None or no default but with no other arguments +# returns Any. +@overload +def attrib( + default: None = ..., + validator: None = ..., + repr: _ReprArgType = ..., + cmp: Optional[_EqOrderType] = ..., + hash: Optional[bool] = ..., + init: bool = ..., + metadata: Optional[Mapping[Any, Any]] = ..., + type: None = ..., + converter: None = ..., + factory: None = ..., + kw_only: bool = ..., + eq: Optional[_EqOrderType] = ..., + order: Optional[_EqOrderType] = ..., + on_setattr: Optional[_OnSetAttrArgType] = ..., +) -> Any: ... + +# This form catches an explicit None or no default and infers the type from the +# other arguments. +@overload +def attrib( + default: None = ..., + validator: Optional[_ValidatorArgType[_T]] = ..., + repr: _ReprArgType = ..., + cmp: Optional[_EqOrderType] = ..., + hash: Optional[bool] = ..., + init: bool = ..., + metadata: Optional[Mapping[Any, Any]] = ..., + type: Optional[Type[_T]] = ..., + converter: Optional[_ConverterType] = ..., + factory: Optional[Callable[[], _T]] = ..., + kw_only: bool = ..., + eq: Optional[_EqOrderType] = ..., + order: Optional[_EqOrderType] = ..., + on_setattr: Optional[_OnSetAttrArgType] = ..., +) -> _T: ... + +# This form catches an explicit default argument. +@overload +def attrib( + default: _T, + validator: Optional[_ValidatorArgType[_T]] = ..., + repr: _ReprArgType = ..., + cmp: Optional[_EqOrderType] = ..., + hash: Optional[bool] = ..., + init: bool = ..., + metadata: Optional[Mapping[Any, Any]] = ..., + type: Optional[Type[_T]] = ..., + converter: Optional[_ConverterType] = ..., + factory: Optional[Callable[[], _T]] = ..., + kw_only: bool = ..., + eq: Optional[_EqOrderType] = ..., + order: Optional[_EqOrderType] = ..., + on_setattr: Optional[_OnSetAttrArgType] = ..., +) -> _T: ... + +# This form covers type=non-Type: e.g. forward references (str), Any +@overload +def attrib( + default: Optional[_T] = ..., + validator: Optional[_ValidatorArgType[_T]] = ..., + repr: _ReprArgType = ..., + cmp: Optional[_EqOrderType] = ..., + hash: Optional[bool] = ..., + init: bool = ..., + metadata: Optional[Mapping[Any, Any]] = ..., + type: object = ..., + converter: Optional[_ConverterType] = ..., + factory: Optional[Callable[[], _T]] = ..., + kw_only: bool = ..., + eq: Optional[_EqOrderType] = ..., + order: Optional[_EqOrderType] = ..., + on_setattr: Optional[_OnSetAttrArgType] = ..., +) -> Any: ... +@overload +def field( + *, + default: None = ..., + validator: None = ..., + repr: _ReprArgType = ..., + hash: Optional[bool] = ..., + init: bool = ..., + metadata: Optional[Mapping[Any, Any]] = ..., + converter: None = ..., + factory: None = ..., + kw_only: bool = ..., + eq: Optional[bool] = ..., + order: Optional[bool] = ..., + on_setattr: Optional[_OnSetAttrArgType] = ..., +) -> Any: ... + +# This form catches an explicit None or no default and infers the type from the +# other arguments. +@overload +def field( + *, + default: None = ..., + validator: Optional[_ValidatorArgType[_T]] = ..., + repr: _ReprArgType = ..., + hash: Optional[bool] = ..., + init: bool = ..., + metadata: Optional[Mapping[Any, Any]] = ..., + converter: Optional[_ConverterType] = ..., + factory: Optional[Callable[[], _T]] = ..., + kw_only: bool = ..., + eq: Optional[_EqOrderType] = ..., + order: Optional[_EqOrderType] = ..., + on_setattr: Optional[_OnSetAttrArgType] = ..., +) -> _T: ... + +# This form catches an explicit default argument. +@overload +def field( + *, + default: _T, + validator: Optional[_ValidatorArgType[_T]] = ..., + repr: _ReprArgType = ..., + hash: Optional[bool] = ..., + init: bool = ..., + metadata: Optional[Mapping[Any, Any]] = ..., + converter: Optional[_ConverterType] = ..., + factory: Optional[Callable[[], _T]] = ..., + kw_only: bool = ..., + eq: Optional[_EqOrderType] = ..., + order: Optional[_EqOrderType] = ..., + on_setattr: Optional[_OnSetAttrArgType] = ..., +) -> _T: ... + +# This form covers type=non-Type: e.g. forward references (str), Any +@overload +def field( + *, + default: Optional[_T] = ..., + validator: Optional[_ValidatorArgType[_T]] = ..., + repr: _ReprArgType = ..., + hash: Optional[bool] = ..., + init: bool = ..., + metadata: Optional[Mapping[Any, Any]] = ..., + converter: Optional[_ConverterType] = ..., + factory: Optional[Callable[[], _T]] = ..., + kw_only: bool = ..., + eq: Optional[_EqOrderType] = ..., + order: Optional[_EqOrderType] = ..., + on_setattr: Optional[_OnSetAttrArgType] = ..., +) -> Any: ... +@overload +@__dataclass_transform__(order_default=True, field_descriptors=(attrib, field)) +def attrs( + maybe_cls: _C, + these: Optional[Dict[str, Any]] = ..., + repr_ns: Optional[str] = ..., + repr: bool = ..., + cmp: Optional[_EqOrderType] = ..., + hash: Optional[bool] = ..., + init: bool = ..., + slots: bool = ..., + frozen: bool = ..., + weakref_slot: bool = ..., + str: bool = ..., + auto_attribs: bool = ..., + kw_only: bool = ..., + cache_hash: bool = ..., + auto_exc: bool = ..., + eq: Optional[_EqOrderType] = ..., + order: Optional[_EqOrderType] = ..., + auto_detect: bool = ..., + collect_by_mro: bool = ..., + getstate_setstate: Optional[bool] = ..., + on_setattr: Optional[_OnSetAttrArgType] = ..., + field_transformer: Optional[_FieldTransformer] = ..., + match_args: bool = ..., +) -> _C: ... +@overload +@__dataclass_transform__(order_default=True, field_descriptors=(attrib, field)) +def attrs( + maybe_cls: None = ..., + these: Optional[Dict[str, Any]] = ..., + repr_ns: Optional[str] = ..., + repr: bool = ..., + cmp: Optional[_EqOrderType] = ..., + hash: Optional[bool] = ..., + init: bool = ..., + slots: bool = ..., + frozen: bool = ..., + weakref_slot: bool = ..., + str: bool = ..., + auto_attribs: bool = ..., + kw_only: bool = ..., + cache_hash: bool = ..., + auto_exc: bool = ..., + eq: Optional[_EqOrderType] = ..., + order: Optional[_EqOrderType] = ..., + auto_detect: bool = ..., + collect_by_mro: bool = ..., + getstate_setstate: Optional[bool] = ..., + on_setattr: Optional[_OnSetAttrArgType] = ..., + field_transformer: Optional[_FieldTransformer] = ..., + match_args: bool = ..., +) -> Callable[[_C], _C]: ... +@overload +@__dataclass_transform__(field_descriptors=(attrib, field)) +def define( + maybe_cls: _C, + *, + these: Optional[Dict[str, Any]] = ..., + repr: bool = ..., + hash: Optional[bool] = ..., + init: bool = ..., + slots: bool = ..., + frozen: bool = ..., + weakref_slot: bool = ..., + str: bool = ..., + auto_attribs: bool = ..., + kw_only: bool = ..., + cache_hash: bool = ..., + auto_exc: bool = ..., + eq: Optional[bool] = ..., + order: Optional[bool] = ..., + auto_detect: bool = ..., + getstate_setstate: Optional[bool] = ..., + on_setattr: Optional[_OnSetAttrArgType] = ..., + field_transformer: Optional[_FieldTransformer] = ..., + match_args: bool = ..., +) -> _C: ... +@overload +@__dataclass_transform__(field_descriptors=(attrib, field)) +def define( + maybe_cls: None = ..., + *, + these: Optional[Dict[str, Any]] = ..., + repr: bool = ..., + hash: Optional[bool] = ..., + init: bool = ..., + slots: bool = ..., + frozen: bool = ..., + weakref_slot: bool = ..., + str: bool = ..., + auto_attribs: bool = ..., + kw_only: bool = ..., + cache_hash: bool = ..., + auto_exc: bool = ..., + eq: Optional[bool] = ..., + order: Optional[bool] = ..., + auto_detect: bool = ..., + getstate_setstate: Optional[bool] = ..., + on_setattr: Optional[_OnSetAttrArgType] = ..., + field_transformer: Optional[_FieldTransformer] = ..., + match_args: bool = ..., +) -> Callable[[_C], _C]: ... + +mutable = define +frozen = define # they differ only in their defaults + +def fields(cls: Type[AttrsInstance]) -> Any: ... +def fields_dict(cls: Type[AttrsInstance]) -> Dict[str, Attribute[Any]]: ... +def validate(inst: AttrsInstance) -> None: ... +def resolve_types( + cls: _C, + globalns: Optional[Dict[str, Any]] = ..., + localns: Optional[Dict[str, Any]] = ..., + attribs: Optional[List[Attribute[Any]]] = ..., +) -> _C: ... + +# TODO: add support for returning a proper attrs class from the mypy plugin +# we use Any instead of _CountingAttr so that e.g. `make_class('Foo', +# [attr.ib()])` is valid +def make_class( + name: str, + attrs: Union[List[str], Tuple[str, ...], Dict[str, Any]], + bases: Tuple[type, ...] = ..., + repr_ns: Optional[str] = ..., + repr: bool = ..., + cmp: Optional[_EqOrderType] = ..., + hash: Optional[bool] = ..., + init: bool = ..., + slots: bool = ..., + frozen: bool = ..., + weakref_slot: bool = ..., + str: bool = ..., + auto_attribs: bool = ..., + kw_only: bool = ..., + cache_hash: bool = ..., + auto_exc: bool = ..., + eq: Optional[_EqOrderType] = ..., + order: Optional[_EqOrderType] = ..., + collect_by_mro: bool = ..., + on_setattr: Optional[_OnSetAttrArgType] = ..., + field_transformer: Optional[_FieldTransformer] = ..., +) -> type: ... + +# _funcs -- + +# TODO: add support for returning TypedDict from the mypy plugin +# FIXME: asdict/astuple do not honor their factory args. Waiting on one of +# these: +# https://github.com/python/mypy/issues/4236 +# https://github.com/python/typing/issues/253 +# XXX: remember to fix attrs.asdict/astuple too! +def asdict( + inst: AttrsInstance, + recurse: bool = ..., + filter: Optional[_FilterType[Any]] = ..., + dict_factory: Type[Mapping[Any, Any]] = ..., + retain_collection_types: bool = ..., + value_serializer: Optional[ + Callable[[type, Attribute[Any], Any], Any] + ] = ..., + tuple_keys: Optional[bool] = ..., +) -> Dict[str, Any]: ... + +# TODO: add support for returning NamedTuple from the mypy plugin +def astuple( + inst: AttrsInstance, + recurse: bool = ..., + filter: Optional[_FilterType[Any]] = ..., + tuple_factory: Type[Sequence[Any]] = ..., + retain_collection_types: bool = ..., +) -> Tuple[Any, ...]: ... +def has(cls: type) -> bool: ... +def assoc(inst: _T, **changes: Any) -> _T: ... +def evolve(inst: _T, **changes: Any) -> _T: ... + +# _config -- + +def set_run_validators(run: bool) -> None: ... +def get_run_validators() -> bool: ... + +# aliases -- + +s = attributes = attrs +ib = attr = attrib +dataclass = attrs # Technically, partial(attrs, auto_attribs=True) ;) diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/attr/_cmp.py b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/attr/_cmp.py new file mode 100644 index 00000000..81b99e4c --- /dev/null +++ b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/attr/_cmp.py @@ -0,0 +1,155 @@ +# SPDX-License-Identifier: MIT + + +import functools +import types + +from ._make import _make_ne + + +_operation_names = {"eq": "==", "lt": "<", "le": "<=", "gt": ">", "ge": ">="} + + +def cmp_using( + eq=None, + lt=None, + le=None, + gt=None, + ge=None, + require_same_type=True, + class_name="Comparable", +): + """ + Create a class that can be passed into `attr.ib`'s ``eq``, ``order``, and + ``cmp`` arguments to customize field comparison. + + The resulting class will have a full set of ordering methods if + at least one of ``{lt, le, gt, ge}`` and ``eq`` are provided. + + :param Optional[callable] eq: `callable` used to evaluate equality + of two objects. + :param Optional[callable] lt: `callable` used to evaluate whether + one object is less than another object. + :param Optional[callable] le: `callable` used to evaluate whether + one object is less than or equal to another object. + :param Optional[callable] gt: `callable` used to evaluate whether + one object is greater than another object. + :param Optional[callable] ge: `callable` used to evaluate whether + one object is greater than or equal to another object. + + :param bool require_same_type: When `True`, equality and ordering methods + will return `NotImplemented` if objects are not of the same type. + + :param Optional[str] class_name: Name of class. Defaults to 'Comparable'. + + See `comparison` for more details. + + .. versionadded:: 21.1.0 + """ + + body = { + "__slots__": ["value"], + "__init__": _make_init(), + "_requirements": [], + "_is_comparable_to": _is_comparable_to, + } + + # Add operations. + num_order_functions = 0 + has_eq_function = False + + if eq is not None: + has_eq_function = True + body["__eq__"] = _make_operator("eq", eq) + body["__ne__"] = _make_ne() + + if lt is not None: + num_order_functions += 1 + body["__lt__"] = _make_operator("lt", lt) + + if le is not None: + num_order_functions += 1 + body["__le__"] = _make_operator("le", le) + + if gt is not None: + num_order_functions += 1 + body["__gt__"] = _make_operator("gt", gt) + + if ge is not None: + num_order_functions += 1 + body["__ge__"] = _make_operator("ge", ge) + + type_ = types.new_class( + class_name, (object,), {}, lambda ns: ns.update(body) + ) + + # Add same type requirement. + if require_same_type: + type_._requirements.append(_check_same_type) + + # Add total ordering if at least one operation was defined. + if 0 < num_order_functions < 4: + if not has_eq_function: + # functools.total_ordering requires __eq__ to be defined, + # so raise early error here to keep a nice stack. + raise ValueError( + "eq must be define is order to complete ordering from " + "lt, le, gt, ge." + ) + type_ = functools.total_ordering(type_) + + return type_ + + +def _make_init(): + """ + Create __init__ method. + """ + + def __init__(self, value): + """ + Initialize object with *value*. + """ + self.value = value + + return __init__ + + +def _make_operator(name, func): + """ + Create operator method. + """ + + def method(self, other): + if not self._is_comparable_to(other): + return NotImplemented + + result = func(self.value, other.value) + if result is NotImplemented: + return NotImplemented + + return result + + method.__name__ = "__%s__" % (name,) + method.__doc__ = "Return a %s b. Computed by attrs." % ( + _operation_names[name], + ) + + return method + + +def _is_comparable_to(self, other): + """ + Check whether `other` is comparable to `self`. + """ + for func in self._requirements: + if not func(self, other): + return False + return True + + +def _check_same_type(self, other): + """ + Return True if *self* and *other* are of the same type, False otherwise. + """ + return other.value.__class__ is self.value.__class__ diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/attr/_cmp.pyi b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/attr/_cmp.pyi new file mode 100644 index 00000000..35437eff --- /dev/null +++ b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/attr/_cmp.pyi @@ -0,0 +1,13 @@ +from typing import Any, Callable, Optional, Type + +_CompareWithType = Callable[[Any, Any], bool] + +def cmp_using( + eq: Optional[_CompareWithType], + lt: Optional[_CompareWithType], + le: Optional[_CompareWithType], + gt: Optional[_CompareWithType], + ge: Optional[_CompareWithType], + require_same_type: bool, + class_name: str, +) -> Type: ... diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/attr/_compat.py b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/attr/_compat.py new file mode 100644 index 00000000..58264932 --- /dev/null +++ b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/attr/_compat.py @@ -0,0 +1,185 @@ +# SPDX-License-Identifier: MIT + + +import inspect +import platform +import sys +import threading +import types +import warnings + +from collections.abc import Mapping, Sequence # noqa + + +PYPY = platform.python_implementation() == "PyPy" +PY36 = sys.version_info[:2] >= (3, 6) +HAS_F_STRINGS = PY36 +PY310 = sys.version_info[:2] >= (3, 10) + + +if PYPY or PY36: + ordered_dict = dict +else: + from collections import OrderedDict + + ordered_dict = OrderedDict + + +def just_warn(*args, **kw): + warnings.warn( + "Running interpreter doesn't sufficiently support code object " + "introspection. Some features like bare super() or accessing " + "__class__ will not work with slotted classes.", + RuntimeWarning, + stacklevel=2, + ) + + +class _AnnotationExtractor: + """ + Extract type annotations from a callable, returning None whenever there + is none. + """ + + __slots__ = ["sig"] + + def __init__(self, callable): + try: + self.sig = inspect.signature(callable) + except (ValueError, TypeError): # inspect failed + self.sig = None + + def get_first_param_type(self): + """ + Return the type annotation of the first argument if it's not empty. + """ + if not self.sig: + return None + + params = list(self.sig.parameters.values()) + if params and params[0].annotation is not inspect.Parameter.empty: + return params[0].annotation + + return None + + def get_return_type(self): + """ + Return the return type if it's not empty. + """ + if ( + self.sig + and self.sig.return_annotation is not inspect.Signature.empty + ): + return self.sig.return_annotation + + return None + + +def make_set_closure_cell(): + """Return a function of two arguments (cell, value) which sets + the value stored in the closure cell `cell` to `value`. + """ + # pypy makes this easy. (It also supports the logic below, but + # why not do the easy/fast thing?) + if PYPY: + + def set_closure_cell(cell, value): + cell.__setstate__((value,)) + + return set_closure_cell + + # Otherwise gotta do it the hard way. + + # Create a function that will set its first cellvar to `value`. + def set_first_cellvar_to(value): + x = value + return + + # This function will be eliminated as dead code, but + # not before its reference to `x` forces `x` to be + # represented as a closure cell rather than a local. + def force_x_to_be_a_cell(): # pragma: no cover + return x + + try: + # Extract the code object and make sure our assumptions about + # the closure behavior are correct. + co = set_first_cellvar_to.__code__ + if co.co_cellvars != ("x",) or co.co_freevars != (): + raise AssertionError # pragma: no cover + + # Convert this code object to a code object that sets the + # function's first _freevar_ (not cellvar) to the argument. + if sys.version_info >= (3, 8): + + def set_closure_cell(cell, value): + cell.cell_contents = value + + else: + args = [co.co_argcount] + args.append(co.co_kwonlyargcount) + args.extend( + [ + co.co_nlocals, + co.co_stacksize, + co.co_flags, + co.co_code, + co.co_consts, + co.co_names, + co.co_varnames, + co.co_filename, + co.co_name, + co.co_firstlineno, + co.co_lnotab, + # These two arguments are reversed: + co.co_cellvars, + co.co_freevars, + ] + ) + set_first_freevar_code = types.CodeType(*args) + + def set_closure_cell(cell, value): + # Create a function using the set_first_freevar_code, + # whose first closure cell is `cell`. Calling it will + # change the value of that cell. + setter = types.FunctionType( + set_first_freevar_code, {}, "setter", (), (cell,) + ) + # And call it to set the cell. + setter(value) + + # Make sure it works on this interpreter: + def make_func_with_cell(): + x = None + + def func(): + return x # pragma: no cover + + return func + + cell = make_func_with_cell().__closure__[0] + set_closure_cell(cell, 100) + if cell.cell_contents != 100: + raise AssertionError # pragma: no cover + + except Exception: + return just_warn + else: + return set_closure_cell + + +set_closure_cell = make_set_closure_cell() + +# Thread-local global to track attrs instances which are already being repr'd. +# This is needed because there is no other (thread-safe) way to pass info +# about the instances that are already being repr'd through the call stack +# in order to ensure we don't perform infinite recursion. +# +# For instance, if an instance contains a dict which contains that instance, +# we need to know that we're already repr'ing the outside instance from within +# the dict's repr() call. +# +# This lives here rather than in _make.py so that the functions in _make.py +# don't have a direct reference to the thread-local in their globals dict. +# If they have such a reference, it breaks cloudpickle. +repr_context = threading.local() diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/attr/_config.py b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/attr/_config.py new file mode 100644 index 00000000..96d42007 --- /dev/null +++ b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/attr/_config.py @@ -0,0 +1,31 @@ +# SPDX-License-Identifier: MIT + + +__all__ = ["set_run_validators", "get_run_validators"] + +_run_validators = True + + +def set_run_validators(run): + """ + Set whether or not validators are run. By default, they are run. + + .. deprecated:: 21.3.0 It will not be removed, but it also will not be + moved to new ``attrs`` namespace. Use `attrs.validators.set_disabled()` + instead. + """ + if not isinstance(run, bool): + raise TypeError("'run' must be bool.") + global _run_validators + _run_validators = run + + +def get_run_validators(): + """ + Return whether or not validators are run. + + .. deprecated:: 21.3.0 It will not be removed, but it also will not be + moved to new ``attrs`` namespace. Use `attrs.validators.get_disabled()` + instead. + """ + return _run_validators diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/attr/_funcs.py b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/attr/_funcs.py new file mode 100644 index 00000000..a982d7cb --- /dev/null +++ b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/attr/_funcs.py @@ -0,0 +1,420 @@ +# SPDX-License-Identifier: MIT + + +import copy + +from ._make import NOTHING, _obj_setattr, fields +from .exceptions import AttrsAttributeNotFoundError + + +def asdict( + inst, + recurse=True, + filter=None, + dict_factory=dict, + retain_collection_types=False, + value_serializer=None, +): + """ + Return the ``attrs`` attribute values of *inst* as a dict. + + Optionally recurse into other ``attrs``-decorated classes. + + :param inst: Instance of an ``attrs``-decorated class. + :param bool recurse: Recurse into classes that are also + ``attrs``-decorated. + :param callable filter: A callable whose return code determines whether an + attribute or element is included (``True``) or dropped (``False``). Is + called with the `attrs.Attribute` as the first argument and the + value as the second argument. + :param callable dict_factory: A callable to produce dictionaries from. For + example, to produce ordered dictionaries instead of normal Python + dictionaries, pass in ``collections.OrderedDict``. + :param bool retain_collection_types: Do not convert to ``list`` when + encountering an attribute whose type is ``tuple`` or ``set``. Only + meaningful if ``recurse`` is ``True``. + :param Optional[callable] value_serializer: A hook that is called for every + attribute or dict key/value. It receives the current instance, field + and value and must return the (updated) value. The hook is run *after* + the optional *filter* has been applied. + + :rtype: return type of *dict_factory* + + :raise attr.exceptions.NotAnAttrsClassError: If *cls* is not an ``attrs`` + class. + + .. versionadded:: 16.0.0 *dict_factory* + .. versionadded:: 16.1.0 *retain_collection_types* + .. versionadded:: 20.3.0 *value_serializer* + .. versionadded:: 21.3.0 If a dict has a collection for a key, it is + serialized as a tuple. + """ + attrs = fields(inst.__class__) + rv = dict_factory() + for a in attrs: + v = getattr(inst, a.name) + if filter is not None and not filter(a, v): + continue + + if value_serializer is not None: + v = value_serializer(inst, a, v) + + if recurse is True: + if has(v.__class__): + rv[a.name] = asdict( + v, + recurse=True, + filter=filter, + dict_factory=dict_factory, + retain_collection_types=retain_collection_types, + value_serializer=value_serializer, + ) + elif isinstance(v, (tuple, list, set, frozenset)): + cf = v.__class__ if retain_collection_types is True else list + rv[a.name] = cf( + [ + _asdict_anything( + i, + is_key=False, + filter=filter, + dict_factory=dict_factory, + retain_collection_types=retain_collection_types, + value_serializer=value_serializer, + ) + for i in v + ] + ) + elif isinstance(v, dict): + df = dict_factory + rv[a.name] = df( + ( + _asdict_anything( + kk, + is_key=True, + filter=filter, + dict_factory=df, + retain_collection_types=retain_collection_types, + value_serializer=value_serializer, + ), + _asdict_anything( + vv, + is_key=False, + filter=filter, + dict_factory=df, + retain_collection_types=retain_collection_types, + value_serializer=value_serializer, + ), + ) + for kk, vv in v.items() + ) + else: + rv[a.name] = v + else: + rv[a.name] = v + return rv + + +def _asdict_anything( + val, + is_key, + filter, + dict_factory, + retain_collection_types, + value_serializer, +): + """ + ``asdict`` only works on attrs instances, this works on anything. + """ + if getattr(val.__class__, "__attrs_attrs__", None) is not None: + # Attrs class. + rv = asdict( + val, + recurse=True, + filter=filter, + dict_factory=dict_factory, + retain_collection_types=retain_collection_types, + value_serializer=value_serializer, + ) + elif isinstance(val, (tuple, list, set, frozenset)): + if retain_collection_types is True: + cf = val.__class__ + elif is_key: + cf = tuple + else: + cf = list + + rv = cf( + [ + _asdict_anything( + i, + is_key=False, + filter=filter, + dict_factory=dict_factory, + retain_collection_types=retain_collection_types, + value_serializer=value_serializer, + ) + for i in val + ] + ) + elif isinstance(val, dict): + df = dict_factory + rv = df( + ( + _asdict_anything( + kk, + is_key=True, + filter=filter, + dict_factory=df, + retain_collection_types=retain_collection_types, + value_serializer=value_serializer, + ), + _asdict_anything( + vv, + is_key=False, + filter=filter, + dict_factory=df, + retain_collection_types=retain_collection_types, + value_serializer=value_serializer, + ), + ) + for kk, vv in val.items() + ) + else: + rv = val + if value_serializer is not None: + rv = value_serializer(None, None, rv) + + return rv + + +def astuple( + inst, + recurse=True, + filter=None, + tuple_factory=tuple, + retain_collection_types=False, +): + """ + Return the ``attrs`` attribute values of *inst* as a tuple. + + Optionally recurse into other ``attrs``-decorated classes. + + :param inst: Instance of an ``attrs``-decorated class. + :param bool recurse: Recurse into classes that are also + ``attrs``-decorated. + :param callable filter: A callable whose return code determines whether an + attribute or element is included (``True``) or dropped (``False``). Is + called with the `attrs.Attribute` as the first argument and the + value as the second argument. + :param callable tuple_factory: A callable to produce tuples from. For + example, to produce lists instead of tuples. + :param bool retain_collection_types: Do not convert to ``list`` + or ``dict`` when encountering an attribute which type is + ``tuple``, ``dict`` or ``set``. Only meaningful if ``recurse`` is + ``True``. + + :rtype: return type of *tuple_factory* + + :raise attr.exceptions.NotAnAttrsClassError: If *cls* is not an ``attrs`` + class. + + .. versionadded:: 16.2.0 + """ + attrs = fields(inst.__class__) + rv = [] + retain = retain_collection_types # Very long. :/ + for a in attrs: + v = getattr(inst, a.name) + if filter is not None and not filter(a, v): + continue + if recurse is True: + if has(v.__class__): + rv.append( + astuple( + v, + recurse=True, + filter=filter, + tuple_factory=tuple_factory, + retain_collection_types=retain, + ) + ) + elif isinstance(v, (tuple, list, set, frozenset)): + cf = v.__class__ if retain is True else list + rv.append( + cf( + [ + astuple( + j, + recurse=True, + filter=filter, + tuple_factory=tuple_factory, + retain_collection_types=retain, + ) + if has(j.__class__) + else j + for j in v + ] + ) + ) + elif isinstance(v, dict): + df = v.__class__ if retain is True else dict + rv.append( + df( + ( + astuple( + kk, + tuple_factory=tuple_factory, + retain_collection_types=retain, + ) + if has(kk.__class__) + else kk, + astuple( + vv, + tuple_factory=tuple_factory, + retain_collection_types=retain, + ) + if has(vv.__class__) + else vv, + ) + for kk, vv in v.items() + ) + ) + else: + rv.append(v) + else: + rv.append(v) + + return rv if tuple_factory is list else tuple_factory(rv) + + +def has(cls): + """ + Check whether *cls* is a class with ``attrs`` attributes. + + :param type cls: Class to introspect. + :raise TypeError: If *cls* is not a class. + + :rtype: bool + """ + return getattr(cls, "__attrs_attrs__", None) is not None + + +def assoc(inst, **changes): + """ + Copy *inst* and apply *changes*. + + :param inst: Instance of a class with ``attrs`` attributes. + :param changes: Keyword changes in the new copy. + + :return: A copy of inst with *changes* incorporated. + + :raise attr.exceptions.AttrsAttributeNotFoundError: If *attr_name* couldn't + be found on *cls*. + :raise attr.exceptions.NotAnAttrsClassError: If *cls* is not an ``attrs`` + class. + + .. deprecated:: 17.1.0 + Use `attrs.evolve` instead if you can. + This function will not be removed du to the slightly different approach + compared to `attrs.evolve`. + """ + import warnings + + warnings.warn( + "assoc is deprecated and will be removed after 2018/01.", + DeprecationWarning, + stacklevel=2, + ) + new = copy.copy(inst) + attrs = fields(inst.__class__) + for k, v in changes.items(): + a = getattr(attrs, k, NOTHING) + if a is NOTHING: + raise AttrsAttributeNotFoundError( + "{k} is not an attrs attribute on {cl}.".format( + k=k, cl=new.__class__ + ) + ) + _obj_setattr(new, k, v) + return new + + +def evolve(inst, **changes): + """ + Create a new instance, based on *inst* with *changes* applied. + + :param inst: Instance of a class with ``attrs`` attributes. + :param changes: Keyword changes in the new copy. + + :return: A copy of inst with *changes* incorporated. + + :raise TypeError: If *attr_name* couldn't be found in the class + ``__init__``. + :raise attr.exceptions.NotAnAttrsClassError: If *cls* is not an ``attrs`` + class. + + .. versionadded:: 17.1.0 + """ + cls = inst.__class__ + attrs = fields(cls) + for a in attrs: + if not a.init: + continue + attr_name = a.name # To deal with private attributes. + init_name = attr_name if attr_name[0] != "_" else attr_name[1:] + if init_name not in changes: + changes[init_name] = getattr(inst, attr_name) + + return cls(**changes) + + +def resolve_types(cls, globalns=None, localns=None, attribs=None): + """ + Resolve any strings and forward annotations in type annotations. + + This is only required if you need concrete types in `Attribute`'s *type* + field. In other words, you don't need to resolve your types if you only + use them for static type checking. + + With no arguments, names will be looked up in the module in which the class + was created. If this is not what you want, e.g. if the name only exists + inside a method, you may pass *globalns* or *localns* to specify other + dictionaries in which to look up these names. See the docs of + `typing.get_type_hints` for more details. + + :param type cls: Class to resolve. + :param Optional[dict] globalns: Dictionary containing global variables. + :param Optional[dict] localns: Dictionary containing local variables. + :param Optional[list] attribs: List of attribs for the given class. + This is necessary when calling from inside a ``field_transformer`` + since *cls* is not an ``attrs`` class yet. + + :raise TypeError: If *cls* is not a class. + :raise attr.exceptions.NotAnAttrsClassError: If *cls* is not an ``attrs`` + class and you didn't pass any attribs. + :raise NameError: If types cannot be resolved because of missing variables. + + :returns: *cls* so you can use this function also as a class decorator. + Please note that you have to apply it **after** `attrs.define`. That + means the decorator has to come in the line **before** `attrs.define`. + + .. versionadded:: 20.1.0 + .. versionadded:: 21.1.0 *attribs* + + """ + # Since calling get_type_hints is expensive we cache whether we've + # done it already. + if getattr(cls, "__attrs_types_resolved__", None) != cls: + import typing + + hints = typing.get_type_hints(cls, globalns=globalns, localns=localns) + for field in fields(cls) if attribs is None else attribs: + if field.name in hints: + # Since fields have been frozen we must work around it. + _obj_setattr(field, "type", hints[field.name]) + # We store the class we resolved so that subclasses know they haven't + # been resolved. + cls.__attrs_types_resolved__ = cls + + # Return the class so you can use it as a decorator too. + return cls diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/attr/_make.py b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/attr/_make.py new file mode 100644 index 00000000..4d1afe3f --- /dev/null +++ b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/attr/_make.py @@ -0,0 +1,3006 @@ +# SPDX-License-Identifier: MIT + +import copy +import linecache +import sys +import types +import typing + +from operator import itemgetter + +# We need to import _compat itself in addition to the _compat members to avoid +# having the thread-local in the globals here. +from . import _compat, _config, setters +from ._compat import ( + HAS_F_STRINGS, + PY310, + PYPY, + _AnnotationExtractor, + ordered_dict, + set_closure_cell, +) +from .exceptions import ( + DefaultAlreadySetError, + FrozenInstanceError, + NotAnAttrsClassError, + UnannotatedAttributeError, +) + + +# This is used at least twice, so cache it here. +_obj_setattr = object.__setattr__ +_init_converter_pat = "__attr_converter_%s" +_init_factory_pat = "__attr_factory_{}" +_tuple_property_pat = ( + " {attr_name} = _attrs_property(_attrs_itemgetter({index}))" +) +_classvar_prefixes = ( + "typing.ClassVar", + "t.ClassVar", + "ClassVar", + "typing_extensions.ClassVar", +) +# we don't use a double-underscore prefix because that triggers +# name mangling when trying to create a slot for the field +# (when slots=True) +_hash_cache_field = "_attrs_cached_hash" + +_empty_metadata_singleton = types.MappingProxyType({}) + +# Unique object for unequivocal getattr() defaults. +_sentinel = object() + +_ng_default_on_setattr = setters.pipe(setters.convert, setters.validate) + + +class _Nothing: + """ + Sentinel class to indicate the lack of a value when ``None`` is ambiguous. + + ``_Nothing`` is a singleton. There is only ever one of it. + + .. versionchanged:: 21.1.0 ``bool(NOTHING)`` is now False. + """ + + _singleton = None + + def __new__(cls): + if _Nothing._singleton is None: + _Nothing._singleton = super().__new__(cls) + return _Nothing._singleton + + def __repr__(self): + return "NOTHING" + + def __bool__(self): + return False + + +NOTHING = _Nothing() +""" +Sentinel to indicate the lack of a value when ``None`` is ambiguous. +""" + + +class _CacheHashWrapper(int): + """ + An integer subclass that pickles / copies as None + + This is used for non-slots classes with ``cache_hash=True``, to avoid + serializing a potentially (even likely) invalid hash value. Since ``None`` + is the default value for uncalculated hashes, whenever this is copied, + the copy's value for the hash should automatically reset. + + See GH #613 for more details. + """ + + def __reduce__(self, _none_constructor=type(None), _args=()): + return _none_constructor, _args + + +def attrib( + default=NOTHING, + validator=None, + repr=True, + cmp=None, + hash=None, + init=True, + metadata=None, + type=None, + converter=None, + factory=None, + kw_only=False, + eq=None, + order=None, + on_setattr=None, +): + """ + Create a new attribute on a class. + + .. warning:: + + Does *not* do anything unless the class is also decorated with + `attr.s`! + + :param default: A value that is used if an ``attrs``-generated ``__init__`` + is used and no value is passed while instantiating or the attribute is + excluded using ``init=False``. + + If the value is an instance of `attrs.Factory`, its callable will be + used to construct a new value (useful for mutable data types like lists + or dicts). + + If a default is not set (or set manually to `attrs.NOTHING`), a value + *must* be supplied when instantiating; otherwise a `TypeError` + will be raised. + + The default can also be set using decorator notation as shown below. + + :type default: Any value + + :param callable factory: Syntactic sugar for + ``default=attr.Factory(factory)``. + + :param validator: `callable` that is called by ``attrs``-generated + ``__init__`` methods after the instance has been initialized. They + receive the initialized instance, the :func:`~attrs.Attribute`, and the + passed value. + + The return value is *not* inspected so the validator has to throw an + exception itself. + + If a `list` is passed, its items are treated as validators and must + all pass. + + Validators can be globally disabled and re-enabled using + `get_run_validators`. + + The validator can also be set using decorator notation as shown below. + + :type validator: `callable` or a `list` of `callable`\\ s. + + :param repr: Include this attribute in the generated ``__repr__`` + method. If ``True``, include the attribute; if ``False``, omit it. By + default, the built-in ``repr()`` function is used. To override how the + attribute value is formatted, pass a ``callable`` that takes a single + value and returns a string. Note that the resulting string is used + as-is, i.e. it will be used directly *instead* of calling ``repr()`` + (the default). + :type repr: a `bool` or a `callable` to use a custom function. + + :param eq: If ``True`` (default), include this attribute in the + generated ``__eq__`` and ``__ne__`` methods that check two instances + for equality. To override how the attribute value is compared, + pass a ``callable`` that takes a single value and returns the value + to be compared. + :type eq: a `bool` or a `callable`. + + :param order: If ``True`` (default), include this attributes in the + generated ``__lt__``, ``__le__``, ``__gt__`` and ``__ge__`` methods. + To override how the attribute value is ordered, + pass a ``callable`` that takes a single value and returns the value + to be ordered. + :type order: a `bool` or a `callable`. + + :param cmp: Setting *cmp* is equivalent to setting *eq* and *order* to the + same value. Must not be mixed with *eq* or *order*. + :type cmp: a `bool` or a `callable`. + + :param Optional[bool] hash: Include this attribute in the generated + ``__hash__`` method. If ``None`` (default), mirror *eq*'s value. This + is the correct behavior according the Python spec. Setting this value + to anything else than ``None`` is *discouraged*. + :param bool init: Include this attribute in the generated ``__init__`` + method. It is possible to set this to ``False`` and set a default + value. In that case this attributed is unconditionally initialized + with the specified default value or factory. + :param callable converter: `callable` that is called by + ``attrs``-generated ``__init__`` methods to convert attribute's value + to the desired format. It is given the passed-in value, and the + returned value will be used as the new value of the attribute. The + value is converted before being passed to the validator, if any. + :param metadata: An arbitrary mapping, to be used by third-party + components. See `extending_metadata`. + :param type: The type of the attribute. In Python 3.6 or greater, the + preferred method to specify the type is using a variable annotation + (see :pep:`526`). + This argument is provided for backward compatibility. + Regardless of the approach used, the type will be stored on + ``Attribute.type``. + + Please note that ``attrs`` doesn't do anything with this metadata by + itself. You can use it as part of your own code or for + `static type checking `. + :param kw_only: Make this attribute keyword-only (Python 3+) + in the generated ``__init__`` (if ``init`` is ``False``, this + parameter is ignored). + :param on_setattr: Allows to overwrite the *on_setattr* setting from + `attr.s`. If left `None`, the *on_setattr* value from `attr.s` is used. + Set to `attrs.setters.NO_OP` to run **no** `setattr` hooks for this + attribute -- regardless of the setting in `attr.s`. + :type on_setattr: `callable`, or a list of callables, or `None`, or + `attrs.setters.NO_OP` + + .. versionadded:: 15.2.0 *convert* + .. versionadded:: 16.3.0 *metadata* + .. versionchanged:: 17.1.0 *validator* can be a ``list`` now. + .. versionchanged:: 17.1.0 + *hash* is ``None`` and therefore mirrors *eq* by default. + .. versionadded:: 17.3.0 *type* + .. deprecated:: 17.4.0 *convert* + .. versionadded:: 17.4.0 *converter* as a replacement for the deprecated + *convert* to achieve consistency with other noun-based arguments. + .. versionadded:: 18.1.0 + ``factory=f`` is syntactic sugar for ``default=attr.Factory(f)``. + .. versionadded:: 18.2.0 *kw_only* + .. versionchanged:: 19.2.0 *convert* keyword argument removed. + .. versionchanged:: 19.2.0 *repr* also accepts a custom callable. + .. deprecated:: 19.2.0 *cmp* Removal on or after 2021-06-01. + .. versionadded:: 19.2.0 *eq* and *order* + .. versionadded:: 20.1.0 *on_setattr* + .. versionchanged:: 20.3.0 *kw_only* backported to Python 2 + .. versionchanged:: 21.1.0 + *eq*, *order*, and *cmp* also accept a custom callable + .. versionchanged:: 21.1.0 *cmp* undeprecated + """ + eq, eq_key, order, order_key = _determine_attrib_eq_order( + cmp, eq, order, True + ) + + if hash is not None and hash is not True and hash is not False: + raise TypeError( + "Invalid value for hash. Must be True, False, or None." + ) + + if factory is not None: + if default is not NOTHING: + raise ValueError( + "The `default` and `factory` arguments are mutually " + "exclusive." + ) + if not callable(factory): + raise ValueError("The `factory` argument must be a callable.") + default = Factory(factory) + + if metadata is None: + metadata = {} + + # Apply syntactic sugar by auto-wrapping. + if isinstance(on_setattr, (list, tuple)): + on_setattr = setters.pipe(*on_setattr) + + if validator and isinstance(validator, (list, tuple)): + validator = and_(*validator) + + if converter and isinstance(converter, (list, tuple)): + converter = pipe(*converter) + + return _CountingAttr( + default=default, + validator=validator, + repr=repr, + cmp=None, + hash=hash, + init=init, + converter=converter, + metadata=metadata, + type=type, + kw_only=kw_only, + eq=eq, + eq_key=eq_key, + order=order, + order_key=order_key, + on_setattr=on_setattr, + ) + + +def _compile_and_eval(script, globs, locs=None, filename=""): + """ + "Exec" the script with the given global (globs) and local (locs) variables. + """ + bytecode = compile(script, filename, "exec") + eval(bytecode, globs, locs) + + +def _make_method(name, script, filename, globs): + """ + Create the method with the script given and return the method object. + """ + locs = {} + + # In order of debuggers like PDB being able to step through the code, + # we add a fake linecache entry. + count = 1 + base_filename = filename + while True: + linecache_tuple = ( + len(script), + None, + script.splitlines(True), + filename, + ) + old_val = linecache.cache.setdefault(filename, linecache_tuple) + if old_val == linecache_tuple: + break + else: + filename = "{}-{}>".format(base_filename[:-1], count) + count += 1 + + _compile_and_eval(script, globs, locs, filename) + + return locs[name] + + +def _make_attr_tuple_class(cls_name, attr_names): + """ + Create a tuple subclass to hold `Attribute`s for an `attrs` class. + + The subclass is a bare tuple with properties for names. + + class MyClassAttributes(tuple): + __slots__ = () + x = property(itemgetter(0)) + """ + attr_class_name = "{}Attributes".format(cls_name) + attr_class_template = [ + "class {}(tuple):".format(attr_class_name), + " __slots__ = ()", + ] + if attr_names: + for i, attr_name in enumerate(attr_names): + attr_class_template.append( + _tuple_property_pat.format(index=i, attr_name=attr_name) + ) + else: + attr_class_template.append(" pass") + globs = {"_attrs_itemgetter": itemgetter, "_attrs_property": property} + _compile_and_eval("\n".join(attr_class_template), globs) + return globs[attr_class_name] + + +# Tuple class for extracted attributes from a class definition. +# `base_attrs` is a subset of `attrs`. +_Attributes = _make_attr_tuple_class( + "_Attributes", + [ + # all attributes to build dunder methods for + "attrs", + # attributes that have been inherited + "base_attrs", + # map inherited attributes to their originating classes + "base_attrs_map", + ], +) + + +def _is_class_var(annot): + """ + Check whether *annot* is a typing.ClassVar. + + The string comparison hack is used to avoid evaluating all string + annotations which would put attrs-based classes at a performance + disadvantage compared to plain old classes. + """ + annot = str(annot) + + # Annotation can be quoted. + if annot.startswith(("'", '"')) and annot.endswith(("'", '"')): + annot = annot[1:-1] + + return annot.startswith(_classvar_prefixes) + + +def _has_own_attribute(cls, attrib_name): + """ + Check whether *cls* defines *attrib_name* (and doesn't just inherit it). + + Requires Python 3. + """ + attr = getattr(cls, attrib_name, _sentinel) + if attr is _sentinel: + return False + + for base_cls in cls.__mro__[1:]: + a = getattr(base_cls, attrib_name, None) + if attr is a: + return False + + return True + + +def _get_annotations(cls): + """ + Get annotations for *cls*. + """ + if _has_own_attribute(cls, "__annotations__"): + return cls.__annotations__ + + return {} + + +def _counter_getter(e): + """ + Key function for sorting to avoid re-creating a lambda for every class. + """ + return e[1].counter + + +def _collect_base_attrs(cls, taken_attr_names): + """ + Collect attr.ibs from base classes of *cls*, except *taken_attr_names*. + """ + base_attrs = [] + base_attr_map = {} # A dictionary of base attrs to their classes. + + # Traverse the MRO and collect attributes. + for base_cls in reversed(cls.__mro__[1:-1]): + for a in getattr(base_cls, "__attrs_attrs__", []): + if a.inherited or a.name in taken_attr_names: + continue + + a = a.evolve(inherited=True) + base_attrs.append(a) + base_attr_map[a.name] = base_cls + + # For each name, only keep the freshest definition i.e. the furthest at the + # back. base_attr_map is fine because it gets overwritten with every new + # instance. + filtered = [] + seen = set() + for a in reversed(base_attrs): + if a.name in seen: + continue + filtered.insert(0, a) + seen.add(a.name) + + return filtered, base_attr_map + + +def _collect_base_attrs_broken(cls, taken_attr_names): + """ + Collect attr.ibs from base classes of *cls*, except *taken_attr_names*. + + N.B. *taken_attr_names* will be mutated. + + Adhere to the old incorrect behavior. + + Notably it collects from the front and considers inherited attributes which + leads to the buggy behavior reported in #428. + """ + base_attrs = [] + base_attr_map = {} # A dictionary of base attrs to their classes. + + # Traverse the MRO and collect attributes. + for base_cls in cls.__mro__[1:-1]: + for a in getattr(base_cls, "__attrs_attrs__", []): + if a.name in taken_attr_names: + continue + + a = a.evolve(inherited=True) + taken_attr_names.add(a.name) + base_attrs.append(a) + base_attr_map[a.name] = base_cls + + return base_attrs, base_attr_map + + +def _transform_attrs( + cls, these, auto_attribs, kw_only, collect_by_mro, field_transformer +): + """ + Transform all `_CountingAttr`s on a class into `Attribute`s. + + If *these* is passed, use that and don't look for them on the class. + + *collect_by_mro* is True, collect them in the correct MRO order, otherwise + use the old -- incorrect -- order. See #428. + + Return an `_Attributes`. + """ + cd = cls.__dict__ + anns = _get_annotations(cls) + + if these is not None: + ca_list = [(name, ca) for name, ca in these.items()] + + if not isinstance(these, ordered_dict): + ca_list.sort(key=_counter_getter) + elif auto_attribs is True: + ca_names = { + name + for name, attr in cd.items() + if isinstance(attr, _CountingAttr) + } + ca_list = [] + annot_names = set() + for attr_name, type in anns.items(): + if _is_class_var(type): + continue + annot_names.add(attr_name) + a = cd.get(attr_name, NOTHING) + + if not isinstance(a, _CountingAttr): + if a is NOTHING: + a = attrib() + else: + a = attrib(default=a) + ca_list.append((attr_name, a)) + + unannotated = ca_names - annot_names + if len(unannotated) > 0: + raise UnannotatedAttributeError( + "The following `attr.ib`s lack a type annotation: " + + ", ".join( + sorted(unannotated, key=lambda n: cd.get(n).counter) + ) + + "." + ) + else: + ca_list = sorted( + ( + (name, attr) + for name, attr in cd.items() + if isinstance(attr, _CountingAttr) + ), + key=lambda e: e[1].counter, + ) + + own_attrs = [ + Attribute.from_counting_attr( + name=attr_name, ca=ca, type=anns.get(attr_name) + ) + for attr_name, ca in ca_list + ] + + if collect_by_mro: + base_attrs, base_attr_map = _collect_base_attrs( + cls, {a.name for a in own_attrs} + ) + else: + base_attrs, base_attr_map = _collect_base_attrs_broken( + cls, {a.name for a in own_attrs} + ) + + if kw_only: + own_attrs = [a.evolve(kw_only=True) for a in own_attrs] + base_attrs = [a.evolve(kw_only=True) for a in base_attrs] + + attrs = base_attrs + own_attrs + + # Mandatory vs non-mandatory attr order only matters when they are part of + # the __init__ signature and when they aren't kw_only (which are moved to + # the end and can be mandatory or non-mandatory in any order, as they will + # be specified as keyword args anyway). Check the order of those attrs: + had_default = False + for a in (a for a in attrs if a.init is not False and a.kw_only is False): + if had_default is True and a.default is NOTHING: + raise ValueError( + "No mandatory attributes allowed after an attribute with a " + "default value or factory. Attribute in question: %r" % (a,) + ) + + if had_default is False and a.default is not NOTHING: + had_default = True + + if field_transformer is not None: + attrs = field_transformer(cls, attrs) + + # Create AttrsClass *after* applying the field_transformer since it may + # add or remove attributes! + attr_names = [a.name for a in attrs] + AttrsClass = _make_attr_tuple_class(cls.__name__, attr_names) + + return _Attributes((AttrsClass(attrs), base_attrs, base_attr_map)) + + +if PYPY: + + def _frozen_setattrs(self, name, value): + """ + Attached to frozen classes as __setattr__. + """ + if isinstance(self, BaseException) and name in ( + "__cause__", + "__context__", + ): + BaseException.__setattr__(self, name, value) + return + + raise FrozenInstanceError() + +else: + + def _frozen_setattrs(self, name, value): + """ + Attached to frozen classes as __setattr__. + """ + raise FrozenInstanceError() + + +def _frozen_delattrs(self, name): + """ + Attached to frozen classes as __delattr__. + """ + raise FrozenInstanceError() + + +class _ClassBuilder: + """ + Iteratively build *one* class. + """ + + __slots__ = ( + "_attr_names", + "_attrs", + "_base_attr_map", + "_base_names", + "_cache_hash", + "_cls", + "_cls_dict", + "_delete_attribs", + "_frozen", + "_has_pre_init", + "_has_post_init", + "_is_exc", + "_on_setattr", + "_slots", + "_weakref_slot", + "_wrote_own_setattr", + "_has_custom_setattr", + ) + + def __init__( + self, + cls, + these, + slots, + frozen, + weakref_slot, + getstate_setstate, + auto_attribs, + kw_only, + cache_hash, + is_exc, + collect_by_mro, + on_setattr, + has_custom_setattr, + field_transformer, + ): + attrs, base_attrs, base_map = _transform_attrs( + cls, + these, + auto_attribs, + kw_only, + collect_by_mro, + field_transformer, + ) + + self._cls = cls + self._cls_dict = dict(cls.__dict__) if slots else {} + self._attrs = attrs + self._base_names = {a.name for a in base_attrs} + self._base_attr_map = base_map + self._attr_names = tuple(a.name for a in attrs) + self._slots = slots + self._frozen = frozen + self._weakref_slot = weakref_slot + self._cache_hash = cache_hash + self._has_pre_init = bool(getattr(cls, "__attrs_pre_init__", False)) + self._has_post_init = bool(getattr(cls, "__attrs_post_init__", False)) + self._delete_attribs = not bool(these) + self._is_exc = is_exc + self._on_setattr = on_setattr + + self._has_custom_setattr = has_custom_setattr + self._wrote_own_setattr = False + + self._cls_dict["__attrs_attrs__"] = self._attrs + + if frozen: + self._cls_dict["__setattr__"] = _frozen_setattrs + self._cls_dict["__delattr__"] = _frozen_delattrs + + self._wrote_own_setattr = True + elif on_setattr in ( + _ng_default_on_setattr, + setters.validate, + setters.convert, + ): + has_validator = has_converter = False + for a in attrs: + if a.validator is not None: + has_validator = True + if a.converter is not None: + has_converter = True + + if has_validator and has_converter: + break + if ( + ( + on_setattr == _ng_default_on_setattr + and not (has_validator or has_converter) + ) + or (on_setattr == setters.validate and not has_validator) + or (on_setattr == setters.convert and not has_converter) + ): + # If class-level on_setattr is set to convert + validate, but + # there's no field to convert or validate, pretend like there's + # no on_setattr. + self._on_setattr = None + + if getstate_setstate: + ( + self._cls_dict["__getstate__"], + self._cls_dict["__setstate__"], + ) = self._make_getstate_setstate() + + def __repr__(self): + return "<_ClassBuilder(cls={cls})>".format(cls=self._cls.__name__) + + def build_class(self): + """ + Finalize class based on the accumulated configuration. + + Builder cannot be used after calling this method. + """ + if self._slots is True: + return self._create_slots_class() + else: + return self._patch_original_class() + + def _patch_original_class(self): + """ + Apply accumulated methods and return the class. + """ + cls = self._cls + base_names = self._base_names + + # Clean class of attribute definitions (`attr.ib()`s). + if self._delete_attribs: + for name in self._attr_names: + if ( + name not in base_names + and getattr(cls, name, _sentinel) is not _sentinel + ): + try: + delattr(cls, name) + except AttributeError: + # This can happen if a base class defines a class + # variable and we want to set an attribute with the + # same name by using only a type annotation. + pass + + # Attach our dunder methods. + for name, value in self._cls_dict.items(): + setattr(cls, name, value) + + # If we've inherited an attrs __setattr__ and don't write our own, + # reset it to object's. + if not self._wrote_own_setattr and getattr( + cls, "__attrs_own_setattr__", False + ): + cls.__attrs_own_setattr__ = False + + if not self._has_custom_setattr: + cls.__setattr__ = _obj_setattr + + return cls + + def _create_slots_class(self): + """ + Build and return a new class with a `__slots__` attribute. + """ + cd = { + k: v + for k, v in self._cls_dict.items() + if k not in tuple(self._attr_names) + ("__dict__", "__weakref__") + } + + # If our class doesn't have its own implementation of __setattr__ + # (either from the user or by us), check the bases, if one of them has + # an attrs-made __setattr__, that needs to be reset. We don't walk the + # MRO because we only care about our immediate base classes. + # XXX: This can be confused by subclassing a slotted attrs class with + # XXX: a non-attrs class and subclass the resulting class with an attrs + # XXX: class. See `test_slotted_confused` for details. For now that's + # XXX: OK with us. + if not self._wrote_own_setattr: + cd["__attrs_own_setattr__"] = False + + if not self._has_custom_setattr: + for base_cls in self._cls.__bases__: + if base_cls.__dict__.get("__attrs_own_setattr__", False): + cd["__setattr__"] = _obj_setattr + break + + # Traverse the MRO to collect existing slots + # and check for an existing __weakref__. + existing_slots = dict() + weakref_inherited = False + for base_cls in self._cls.__mro__[1:-1]: + if base_cls.__dict__.get("__weakref__", None) is not None: + weakref_inherited = True + existing_slots.update( + { + name: getattr(base_cls, name) + for name in getattr(base_cls, "__slots__", []) + } + ) + + base_names = set(self._base_names) + + names = self._attr_names + if ( + self._weakref_slot + and "__weakref__" not in getattr(self._cls, "__slots__", ()) + and "__weakref__" not in names + and not weakref_inherited + ): + names += ("__weakref__",) + + # We only add the names of attributes that aren't inherited. + # Setting __slots__ to inherited attributes wastes memory. + slot_names = [name for name in names if name not in base_names] + # There are slots for attributes from current class + # that are defined in parent classes. + # As their descriptors may be overridden by a child class, + # we collect them here and update the class dict + reused_slots = { + slot: slot_descriptor + for slot, slot_descriptor in existing_slots.items() + if slot in slot_names + } + slot_names = [name for name in slot_names if name not in reused_slots] + cd.update(reused_slots) + if self._cache_hash: + slot_names.append(_hash_cache_field) + cd["__slots__"] = tuple(slot_names) + + cd["__qualname__"] = self._cls.__qualname__ + + # Create new class based on old class and our methods. + cls = type(self._cls)(self._cls.__name__, self._cls.__bases__, cd) + + # The following is a fix for + # . On Python 3, + # if a method mentions `__class__` or uses the no-arg super(), the + # compiler will bake a reference to the class in the method itself + # as `method.__closure__`. Since we replace the class with a + # clone, we rewrite these references so it keeps working. + for item in cls.__dict__.values(): + if isinstance(item, (classmethod, staticmethod)): + # Class- and staticmethods hide their functions inside. + # These might need to be rewritten as well. + closure_cells = getattr(item.__func__, "__closure__", None) + elif isinstance(item, property): + # Workaround for property `super()` shortcut (PY3-only). + # There is no universal way for other descriptors. + closure_cells = getattr(item.fget, "__closure__", None) + else: + closure_cells = getattr(item, "__closure__", None) + + if not closure_cells: # Catch None or the empty list. + continue + for cell in closure_cells: + try: + match = cell.cell_contents is self._cls + except ValueError: # ValueError: Cell is empty + pass + else: + if match: + set_closure_cell(cell, cls) + + return cls + + def add_repr(self, ns): + self._cls_dict["__repr__"] = self._add_method_dunders( + _make_repr(self._attrs, ns, self._cls) + ) + return self + + def add_str(self): + repr = self._cls_dict.get("__repr__") + if repr is None: + raise ValueError( + "__str__ can only be generated if a __repr__ exists." + ) + + def __str__(self): + return self.__repr__() + + self._cls_dict["__str__"] = self._add_method_dunders(__str__) + return self + + def _make_getstate_setstate(self): + """ + Create custom __setstate__ and __getstate__ methods. + """ + # __weakref__ is not writable. + state_attr_names = tuple( + an for an in self._attr_names if an != "__weakref__" + ) + + def slots_getstate(self): + """ + Automatically created by attrs. + """ + return tuple(getattr(self, name) for name in state_attr_names) + + hash_caching_enabled = self._cache_hash + + def slots_setstate(self, state): + """ + Automatically created by attrs. + """ + __bound_setattr = _obj_setattr.__get__(self, Attribute) + for name, value in zip(state_attr_names, state): + __bound_setattr(name, value) + + # The hash code cache is not included when the object is + # serialized, but it still needs to be initialized to None to + # indicate that the first call to __hash__ should be a cache + # miss. + if hash_caching_enabled: + __bound_setattr(_hash_cache_field, None) + + return slots_getstate, slots_setstate + + def make_unhashable(self): + self._cls_dict["__hash__"] = None + return self + + def add_hash(self): + self._cls_dict["__hash__"] = self._add_method_dunders( + _make_hash( + self._cls, + self._attrs, + frozen=self._frozen, + cache_hash=self._cache_hash, + ) + ) + + return self + + def add_init(self): + self._cls_dict["__init__"] = self._add_method_dunders( + _make_init( + self._cls, + self._attrs, + self._has_pre_init, + self._has_post_init, + self._frozen, + self._slots, + self._cache_hash, + self._base_attr_map, + self._is_exc, + self._on_setattr, + attrs_init=False, + ) + ) + + return self + + def add_match_args(self): + self._cls_dict["__match_args__"] = tuple( + field.name + for field in self._attrs + if field.init and not field.kw_only + ) + + def add_attrs_init(self): + self._cls_dict["__attrs_init__"] = self._add_method_dunders( + _make_init( + self._cls, + self._attrs, + self._has_pre_init, + self._has_post_init, + self._frozen, + self._slots, + self._cache_hash, + self._base_attr_map, + self._is_exc, + self._on_setattr, + attrs_init=True, + ) + ) + + return self + + def add_eq(self): + cd = self._cls_dict + + cd["__eq__"] = self._add_method_dunders( + _make_eq(self._cls, self._attrs) + ) + cd["__ne__"] = self._add_method_dunders(_make_ne()) + + return self + + def add_order(self): + cd = self._cls_dict + + cd["__lt__"], cd["__le__"], cd["__gt__"], cd["__ge__"] = ( + self._add_method_dunders(meth) + for meth in _make_order(self._cls, self._attrs) + ) + + return self + + def add_setattr(self): + if self._frozen: + return self + + sa_attrs = {} + for a in self._attrs: + on_setattr = a.on_setattr or self._on_setattr + if on_setattr and on_setattr is not setters.NO_OP: + sa_attrs[a.name] = a, on_setattr + + if not sa_attrs: + return self + + if self._has_custom_setattr: + # We need to write a __setattr__ but there already is one! + raise ValueError( + "Can't combine custom __setattr__ with on_setattr hooks." + ) + + # docstring comes from _add_method_dunders + def __setattr__(self, name, val): + try: + a, hook = sa_attrs[name] + except KeyError: + nval = val + else: + nval = hook(self, a, val) + + _obj_setattr(self, name, nval) + + self._cls_dict["__attrs_own_setattr__"] = True + self._cls_dict["__setattr__"] = self._add_method_dunders(__setattr__) + self._wrote_own_setattr = True + + return self + + def _add_method_dunders(self, method): + """ + Add __module__ and __qualname__ to a *method* if possible. + """ + try: + method.__module__ = self._cls.__module__ + except AttributeError: + pass + + try: + method.__qualname__ = ".".join( + (self._cls.__qualname__, method.__name__) + ) + except AttributeError: + pass + + try: + method.__doc__ = "Method generated by attrs for class %s." % ( + self._cls.__qualname__, + ) + except AttributeError: + pass + + return method + + +def _determine_attrs_eq_order(cmp, eq, order, default_eq): + """ + Validate the combination of *cmp*, *eq*, and *order*. Derive the effective + values of eq and order. If *eq* is None, set it to *default_eq*. + """ + if cmp is not None and any((eq is not None, order is not None)): + raise ValueError("Don't mix `cmp` with `eq' and `order`.") + + # cmp takes precedence due to bw-compatibility. + if cmp is not None: + return cmp, cmp + + # If left None, equality is set to the specified default and ordering + # mirrors equality. + if eq is None: + eq = default_eq + + if order is None: + order = eq + + if eq is False and order is True: + raise ValueError("`order` can only be True if `eq` is True too.") + + return eq, order + + +def _determine_attrib_eq_order(cmp, eq, order, default_eq): + """ + Validate the combination of *cmp*, *eq*, and *order*. Derive the effective + values of eq and order. If *eq* is None, set it to *default_eq*. + """ + if cmp is not None and any((eq is not None, order is not None)): + raise ValueError("Don't mix `cmp` with `eq' and `order`.") + + def decide_callable_or_boolean(value): + """ + Decide whether a key function is used. + """ + if callable(value): + value, key = True, value + else: + key = None + return value, key + + # cmp takes precedence due to bw-compatibility. + if cmp is not None: + cmp, cmp_key = decide_callable_or_boolean(cmp) + return cmp, cmp_key, cmp, cmp_key + + # If left None, equality is set to the specified default and ordering + # mirrors equality. + if eq is None: + eq, eq_key = default_eq, None + else: + eq, eq_key = decide_callable_or_boolean(eq) + + if order is None: + order, order_key = eq, eq_key + else: + order, order_key = decide_callable_or_boolean(order) + + if eq is False and order is True: + raise ValueError("`order` can only be True if `eq` is True too.") + + return eq, eq_key, order, order_key + + +def _determine_whether_to_implement( + cls, flag, auto_detect, dunders, default=True +): + """ + Check whether we should implement a set of methods for *cls*. + + *flag* is the argument passed into @attr.s like 'init', *auto_detect* the + same as passed into @attr.s and *dunders* is a tuple of attribute names + whose presence signal that the user has implemented it themselves. + + Return *default* if no reason for either for or against is found. + """ + if flag is True or flag is False: + return flag + + if flag is None and auto_detect is False: + return default + + # Logically, flag is None and auto_detect is True here. + for dunder in dunders: + if _has_own_attribute(cls, dunder): + return False + + return default + + +def attrs( + maybe_cls=None, + these=None, + repr_ns=None, + repr=None, + cmp=None, + hash=None, + init=None, + slots=False, + frozen=False, + weakref_slot=True, + str=False, + auto_attribs=False, + kw_only=False, + cache_hash=False, + auto_exc=False, + eq=None, + order=None, + auto_detect=False, + collect_by_mro=False, + getstate_setstate=None, + on_setattr=None, + field_transformer=None, + match_args=True, +): + r""" + A class decorator that adds `dunder + `_\ -methods according to the + specified attributes using `attr.ib` or the *these* argument. + + :param these: A dictionary of name to `attr.ib` mappings. This is + useful to avoid the definition of your attributes within the class body + because you can't (e.g. if you want to add ``__repr__`` methods to + Django models) or don't want to. + + If *these* is not ``None``, ``attrs`` will *not* search the class body + for attributes and will *not* remove any attributes from it. + + If *these* is an ordered dict (`dict` on Python 3.6+, + `collections.OrderedDict` otherwise), the order is deduced from + the order of the attributes inside *these*. Otherwise the order + of the definition of the attributes is used. + + :type these: `dict` of `str` to `attr.ib` + + :param str repr_ns: When using nested classes, there's no way in Python 2 + to automatically detect that. Therefore it's possible to set the + namespace explicitly for a more meaningful ``repr`` output. + :param bool auto_detect: Instead of setting the *init*, *repr*, *eq*, + *order*, and *hash* arguments explicitly, assume they are set to + ``True`` **unless any** of the involved methods for one of the + arguments is implemented in the *current* class (i.e. it is *not* + inherited from some base class). + + So for example by implementing ``__eq__`` on a class yourself, + ``attrs`` will deduce ``eq=False`` and will create *neither* + ``__eq__`` *nor* ``__ne__`` (but Python classes come with a sensible + ``__ne__`` by default, so it *should* be enough to only implement + ``__eq__`` in most cases). + + .. warning:: + + If you prevent ``attrs`` from creating the ordering methods for you + (``order=False``, e.g. by implementing ``__le__``), it becomes + *your* responsibility to make sure its ordering is sound. The best + way is to use the `functools.total_ordering` decorator. + + + Passing ``True`` or ``False`` to *init*, *repr*, *eq*, *order*, + *cmp*, or *hash* overrides whatever *auto_detect* would determine. + + *auto_detect* requires Python 3. Setting it ``True`` on Python 2 raises + an `attrs.exceptions.PythonTooOldError`. + + :param bool repr: Create a ``__repr__`` method with a human readable + representation of ``attrs`` attributes.. + :param bool str: Create a ``__str__`` method that is identical to + ``__repr__``. This is usually not necessary except for + `Exception`\ s. + :param Optional[bool] eq: If ``True`` or ``None`` (default), add ``__eq__`` + and ``__ne__`` methods that check two instances for equality. + + They compare the instances as if they were tuples of their ``attrs`` + attributes if and only if the types of both classes are *identical*! + :param Optional[bool] order: If ``True``, add ``__lt__``, ``__le__``, + ``__gt__``, and ``__ge__`` methods that behave like *eq* above and + allow instances to be ordered. If ``None`` (default) mirror value of + *eq*. + :param Optional[bool] cmp: Setting *cmp* is equivalent to setting *eq* + and *order* to the same value. Must not be mixed with *eq* or *order*. + :param Optional[bool] hash: If ``None`` (default), the ``__hash__`` method + is generated according how *eq* and *frozen* are set. + + 1. If *both* are True, ``attrs`` will generate a ``__hash__`` for you. + 2. If *eq* is True and *frozen* is False, ``__hash__`` will be set to + None, marking it unhashable (which it is). + 3. If *eq* is False, ``__hash__`` will be left untouched meaning the + ``__hash__`` method of the base class will be used (if base class is + ``object``, this means it will fall back to id-based hashing.). + + Although not recommended, you can decide for yourself and force + ``attrs`` to create one (e.g. if the class is immutable even though you + didn't freeze it programmatically) by passing ``True`` or not. Both of + these cases are rather special and should be used carefully. + + See our documentation on `hashing`, Python's documentation on + `object.__hash__`, and the `GitHub issue that led to the default \ + behavior `_ for more + details. + :param bool init: Create a ``__init__`` method that initializes the + ``attrs`` attributes. Leading underscores are stripped for the argument + name. If a ``__attrs_pre_init__`` method exists on the class, it will + be called before the class is initialized. If a ``__attrs_post_init__`` + method exists on the class, it will be called after the class is fully + initialized. + + If ``init`` is ``False``, an ``__attrs_init__`` method will be + injected instead. This allows you to define a custom ``__init__`` + method that can do pre-init work such as ``super().__init__()``, + and then call ``__attrs_init__()`` and ``__attrs_post_init__()``. + :param bool slots: Create a `slotted class ` that's more + memory-efficient. Slotted classes are generally superior to the default + dict classes, but have some gotchas you should know about, so we + encourage you to read the `glossary entry `. + :param bool frozen: Make instances immutable after initialization. If + someone attempts to modify a frozen instance, + `attr.exceptions.FrozenInstanceError` is raised. + + .. note:: + + 1. This is achieved by installing a custom ``__setattr__`` method + on your class, so you can't implement your own. + + 2. True immutability is impossible in Python. + + 3. This *does* have a minor a runtime performance `impact + ` when initializing new instances. In other words: + ``__init__`` is slightly slower with ``frozen=True``. + + 4. If a class is frozen, you cannot modify ``self`` in + ``__attrs_post_init__`` or a self-written ``__init__``. You can + circumvent that limitation by using + ``object.__setattr__(self, "attribute_name", value)``. + + 5. Subclasses of a frozen class are frozen too. + + :param bool weakref_slot: Make instances weak-referenceable. This has no + effect unless ``slots`` is also enabled. + :param bool auto_attribs: If ``True``, collect :pep:`526`-annotated + attributes (Python 3.6 and later only) from the class body. + + In this case, you **must** annotate every field. If ``attrs`` + encounters a field that is set to an `attr.ib` but lacks a type + annotation, an `attr.exceptions.UnannotatedAttributeError` is + raised. Use ``field_name: typing.Any = attr.ib(...)`` if you don't + want to set a type. + + If you assign a value to those attributes (e.g. ``x: int = 42``), that + value becomes the default value like if it were passed using + ``attr.ib(default=42)``. Passing an instance of `attrs.Factory` also + works as expected in most cases (see warning below). + + Attributes annotated as `typing.ClassVar`, and attributes that are + neither annotated nor set to an `attr.ib` are **ignored**. + + .. warning:: + For features that use the attribute name to create decorators (e.g. + `validators `), you still *must* assign `attr.ib` to + them. Otherwise Python will either not find the name or try to use + the default value to call e.g. ``validator`` on it. + + These errors can be quite confusing and probably the most common bug + report on our bug tracker. + + :param bool kw_only: Make all attributes keyword-only (Python 3+) + in the generated ``__init__`` (if ``init`` is ``False``, this + parameter is ignored). + :param bool cache_hash: Ensure that the object's hash code is computed + only once and stored on the object. If this is set to ``True``, + hashing must be either explicitly or implicitly enabled for this + class. If the hash code is cached, avoid any reassignments of + fields involved in hash code computation or mutations of the objects + those fields point to after object creation. If such changes occur, + the behavior of the object's hash code is undefined. + :param bool auto_exc: If the class subclasses `BaseException` + (which implicitly includes any subclass of any exception), the + following happens to behave like a well-behaved Python exceptions + class: + + - the values for *eq*, *order*, and *hash* are ignored and the + instances compare and hash by the instance's ids (N.B. ``attrs`` will + *not* remove existing implementations of ``__hash__`` or the equality + methods. It just won't add own ones.), + - all attributes that are either passed into ``__init__`` or have a + default value are additionally available as a tuple in the ``args`` + attribute, + - the value of *str* is ignored leaving ``__str__`` to base classes. + :param bool collect_by_mro: Setting this to `True` fixes the way ``attrs`` + collects attributes from base classes. The default behavior is + incorrect in certain cases of multiple inheritance. It should be on by + default but is kept off for backward-compatibility. + + See issue `#428 `_ for + more details. + + :param Optional[bool] getstate_setstate: + .. note:: + This is usually only interesting for slotted classes and you should + probably just set *auto_detect* to `True`. + + If `True`, ``__getstate__`` and + ``__setstate__`` are generated and attached to the class. This is + necessary for slotted classes to be pickleable. If left `None`, it's + `True` by default for slotted classes and ``False`` for dict classes. + + If *auto_detect* is `True`, and *getstate_setstate* is left `None`, + and **either** ``__getstate__`` or ``__setstate__`` is detected directly + on the class (i.e. not inherited), it is set to `False` (this is usually + what you want). + + :param on_setattr: A callable that is run whenever the user attempts to set + an attribute (either by assignment like ``i.x = 42`` or by using + `setattr` like ``setattr(i, "x", 42)``). It receives the same arguments + as validators: the instance, the attribute that is being modified, and + the new value. + + If no exception is raised, the attribute is set to the return value of + the callable. + + If a list of callables is passed, they're automatically wrapped in an + `attrs.setters.pipe`. + :type on_setattr: `callable`, or a list of callables, or `None`, or + `attrs.setters.NO_OP` + + :param Optional[callable] field_transformer: + A function that is called with the original class object and all + fields right before ``attrs`` finalizes the class. You can use + this, e.g., to automatically add converters or validators to + fields based on their types. See `transform-fields` for more details. + + :param bool match_args: + If `True` (default), set ``__match_args__`` on the class to support + :pep:`634` (Structural Pattern Matching). It is a tuple of all + non-keyword-only ``__init__`` parameter names on Python 3.10 and later. + Ignored on older Python versions. + + .. versionadded:: 16.0.0 *slots* + .. versionadded:: 16.1.0 *frozen* + .. versionadded:: 16.3.0 *str* + .. versionadded:: 16.3.0 Support for ``__attrs_post_init__``. + .. versionchanged:: 17.1.0 + *hash* supports ``None`` as value which is also the default now. + .. versionadded:: 17.3.0 *auto_attribs* + .. versionchanged:: 18.1.0 + If *these* is passed, no attributes are deleted from the class body. + .. versionchanged:: 18.1.0 If *these* is ordered, the order is retained. + .. versionadded:: 18.2.0 *weakref_slot* + .. deprecated:: 18.2.0 + ``__lt__``, ``__le__``, ``__gt__``, and ``__ge__`` now raise a + `DeprecationWarning` if the classes compared are subclasses of + each other. ``__eq`` and ``__ne__`` never tried to compared subclasses + to each other. + .. versionchanged:: 19.2.0 + ``__lt__``, ``__le__``, ``__gt__``, and ``__ge__`` now do not consider + subclasses comparable anymore. + .. versionadded:: 18.2.0 *kw_only* + .. versionadded:: 18.2.0 *cache_hash* + .. versionadded:: 19.1.0 *auto_exc* + .. deprecated:: 19.2.0 *cmp* Removal on or after 2021-06-01. + .. versionadded:: 19.2.0 *eq* and *order* + .. versionadded:: 20.1.0 *auto_detect* + .. versionadded:: 20.1.0 *collect_by_mro* + .. versionadded:: 20.1.0 *getstate_setstate* + .. versionadded:: 20.1.0 *on_setattr* + .. versionadded:: 20.3.0 *field_transformer* + .. versionchanged:: 21.1.0 + ``init=False`` injects ``__attrs_init__`` + .. versionchanged:: 21.1.0 Support for ``__attrs_pre_init__`` + .. versionchanged:: 21.1.0 *cmp* undeprecated + .. versionadded:: 21.3.0 *match_args* + """ + eq_, order_ = _determine_attrs_eq_order(cmp, eq, order, None) + hash_ = hash # work around the lack of nonlocal + + if isinstance(on_setattr, (list, tuple)): + on_setattr = setters.pipe(*on_setattr) + + def wrap(cls): + is_frozen = frozen or _has_frozen_base_class(cls) + is_exc = auto_exc is True and issubclass(cls, BaseException) + has_own_setattr = auto_detect and _has_own_attribute( + cls, "__setattr__" + ) + + if has_own_setattr and is_frozen: + raise ValueError("Can't freeze a class with a custom __setattr__.") + + builder = _ClassBuilder( + cls, + these, + slots, + is_frozen, + weakref_slot, + _determine_whether_to_implement( + cls, + getstate_setstate, + auto_detect, + ("__getstate__", "__setstate__"), + default=slots, + ), + auto_attribs, + kw_only, + cache_hash, + is_exc, + collect_by_mro, + on_setattr, + has_own_setattr, + field_transformer, + ) + if _determine_whether_to_implement( + cls, repr, auto_detect, ("__repr__",) + ): + builder.add_repr(repr_ns) + if str is True: + builder.add_str() + + eq = _determine_whether_to_implement( + cls, eq_, auto_detect, ("__eq__", "__ne__") + ) + if not is_exc and eq is True: + builder.add_eq() + if not is_exc and _determine_whether_to_implement( + cls, order_, auto_detect, ("__lt__", "__le__", "__gt__", "__ge__") + ): + builder.add_order() + + builder.add_setattr() + + if ( + hash_ is None + and auto_detect is True + and _has_own_attribute(cls, "__hash__") + ): + hash = False + else: + hash = hash_ + if hash is not True and hash is not False and hash is not None: + # Can't use `hash in` because 1 == True for example. + raise TypeError( + "Invalid value for hash. Must be True, False, or None." + ) + elif hash is False or (hash is None and eq is False) or is_exc: + # Don't do anything. Should fall back to __object__'s __hash__ + # which is by id. + if cache_hash: + raise TypeError( + "Invalid value for cache_hash. To use hash caching," + " hashing must be either explicitly or implicitly " + "enabled." + ) + elif hash is True or ( + hash is None and eq is True and is_frozen is True + ): + # Build a __hash__ if told so, or if it's safe. + builder.add_hash() + else: + # Raise TypeError on attempts to hash. + if cache_hash: + raise TypeError( + "Invalid value for cache_hash. To use hash caching," + " hashing must be either explicitly or implicitly " + "enabled." + ) + builder.make_unhashable() + + if _determine_whether_to_implement( + cls, init, auto_detect, ("__init__",) + ): + builder.add_init() + else: + builder.add_attrs_init() + if cache_hash: + raise TypeError( + "Invalid value for cache_hash. To use hash caching," + " init must be True." + ) + + if ( + PY310 + and match_args + and not _has_own_attribute(cls, "__match_args__") + ): + builder.add_match_args() + + return builder.build_class() + + # maybe_cls's type depends on the usage of the decorator. It's a class + # if it's used as `@attrs` but ``None`` if used as `@attrs()`. + if maybe_cls is None: + return wrap + else: + return wrap(maybe_cls) + + +_attrs = attrs +""" +Internal alias so we can use it in functions that take an argument called +*attrs*. +""" + + +def _has_frozen_base_class(cls): + """ + Check whether *cls* has a frozen ancestor by looking at its + __setattr__. + """ + return cls.__setattr__ is _frozen_setattrs + + +def _generate_unique_filename(cls, func_name): + """ + Create a "filename" suitable for a function being generated. + """ + unique_filename = "".format( + func_name, + cls.__module__, + getattr(cls, "__qualname__", cls.__name__), + ) + return unique_filename + + +def _make_hash(cls, attrs, frozen, cache_hash): + attrs = tuple( + a for a in attrs if a.hash is True or (a.hash is None and a.eq is True) + ) + + tab = " " + + unique_filename = _generate_unique_filename(cls, "hash") + type_hash = hash(unique_filename) + # If eq is custom generated, we need to include the functions in globs + globs = {} + + hash_def = "def __hash__(self" + hash_func = "hash((" + closing_braces = "))" + if not cache_hash: + hash_def += "):" + else: + hash_def += ", *" + + hash_def += ( + ", _cache_wrapper=" + + "__import__('attr._make')._make._CacheHashWrapper):" + ) + hash_func = "_cache_wrapper(" + hash_func + closing_braces += ")" + + method_lines = [hash_def] + + def append_hash_computation_lines(prefix, indent): + """ + Generate the code for actually computing the hash code. + Below this will either be returned directly or used to compute + a value which is then cached, depending on the value of cache_hash + """ + + method_lines.extend( + [ + indent + prefix + hash_func, + indent + " %d," % (type_hash,), + ] + ) + + for a in attrs: + if a.eq_key: + cmp_name = "_%s_key" % (a.name,) + globs[cmp_name] = a.eq_key + method_lines.append( + indent + " %s(self.%s)," % (cmp_name, a.name) + ) + else: + method_lines.append(indent + " self.%s," % a.name) + + method_lines.append(indent + " " + closing_braces) + + if cache_hash: + method_lines.append(tab + "if self.%s is None:" % _hash_cache_field) + if frozen: + append_hash_computation_lines( + "object.__setattr__(self, '%s', " % _hash_cache_field, tab * 2 + ) + method_lines.append(tab * 2 + ")") # close __setattr__ + else: + append_hash_computation_lines( + "self.%s = " % _hash_cache_field, tab * 2 + ) + method_lines.append(tab + "return self.%s" % _hash_cache_field) + else: + append_hash_computation_lines("return ", tab) + + script = "\n".join(method_lines) + return _make_method("__hash__", script, unique_filename, globs) + + +def _add_hash(cls, attrs): + """ + Add a hash method to *cls*. + """ + cls.__hash__ = _make_hash(cls, attrs, frozen=False, cache_hash=False) + return cls + + +def _make_ne(): + """ + Create __ne__ method. + """ + + def __ne__(self, other): + """ + Check equality and either forward a NotImplemented or + return the result negated. + """ + result = self.__eq__(other) + if result is NotImplemented: + return NotImplemented + + return not result + + return __ne__ + + +def _make_eq(cls, attrs): + """ + Create __eq__ method for *cls* with *attrs*. + """ + attrs = [a for a in attrs if a.eq] + + unique_filename = _generate_unique_filename(cls, "eq") + lines = [ + "def __eq__(self, other):", + " if other.__class__ is not self.__class__:", + " return NotImplemented", + ] + + # We can't just do a big self.x = other.x and... clause due to + # irregularities like nan == nan is false but (nan,) == (nan,) is true. + globs = {} + if attrs: + lines.append(" return (") + others = [" ) == ("] + for a in attrs: + if a.eq_key: + cmp_name = "_%s_key" % (a.name,) + # Add the key function to the global namespace + # of the evaluated function. + globs[cmp_name] = a.eq_key + lines.append( + " %s(self.%s)," + % ( + cmp_name, + a.name, + ) + ) + others.append( + " %s(other.%s)," + % ( + cmp_name, + a.name, + ) + ) + else: + lines.append(" self.%s," % (a.name,)) + others.append(" other.%s," % (a.name,)) + + lines += others + [" )"] + else: + lines.append(" return True") + + script = "\n".join(lines) + + return _make_method("__eq__", script, unique_filename, globs) + + +def _make_order(cls, attrs): + """ + Create ordering methods for *cls* with *attrs*. + """ + attrs = [a for a in attrs if a.order] + + def attrs_to_tuple(obj): + """ + Save us some typing. + """ + return tuple( + key(value) if key else value + for value, key in ( + (getattr(obj, a.name), a.order_key) for a in attrs + ) + ) + + def __lt__(self, other): + """ + Automatically created by attrs. + """ + if other.__class__ is self.__class__: + return attrs_to_tuple(self) < attrs_to_tuple(other) + + return NotImplemented + + def __le__(self, other): + """ + Automatically created by attrs. + """ + if other.__class__ is self.__class__: + return attrs_to_tuple(self) <= attrs_to_tuple(other) + + return NotImplemented + + def __gt__(self, other): + """ + Automatically created by attrs. + """ + if other.__class__ is self.__class__: + return attrs_to_tuple(self) > attrs_to_tuple(other) + + return NotImplemented + + def __ge__(self, other): + """ + Automatically created by attrs. + """ + if other.__class__ is self.__class__: + return attrs_to_tuple(self) >= attrs_to_tuple(other) + + return NotImplemented + + return __lt__, __le__, __gt__, __ge__ + + +def _add_eq(cls, attrs=None): + """ + Add equality methods to *cls* with *attrs*. + """ + if attrs is None: + attrs = cls.__attrs_attrs__ + + cls.__eq__ = _make_eq(cls, attrs) + cls.__ne__ = _make_ne() + + return cls + + +if HAS_F_STRINGS: + + def _make_repr(attrs, ns, cls): + unique_filename = _generate_unique_filename(cls, "repr") + # Figure out which attributes to include, and which function to use to + # format them. The a.repr value can be either bool or a custom + # callable. + attr_names_with_reprs = tuple( + (a.name, (repr if a.repr is True else a.repr), a.init) + for a in attrs + if a.repr is not False + ) + globs = { + name + "_repr": r + for name, r, _ in attr_names_with_reprs + if r != repr + } + globs["_compat"] = _compat + globs["AttributeError"] = AttributeError + globs["NOTHING"] = NOTHING + attribute_fragments = [] + for name, r, i in attr_names_with_reprs: + accessor = ( + "self." + name + if i + else 'getattr(self, "' + name + '", NOTHING)' + ) + fragment = ( + "%s={%s!r}" % (name, accessor) + if r == repr + else "%s={%s_repr(%s)}" % (name, name, accessor) + ) + attribute_fragments.append(fragment) + repr_fragment = ", ".join(attribute_fragments) + + if ns is None: + cls_name_fragment = ( + '{self.__class__.__qualname__.rsplit(">.", 1)[-1]}' + ) + else: + cls_name_fragment = ns + ".{self.__class__.__name__}" + + lines = [ + "def __repr__(self):", + " try:", + " already_repring = _compat.repr_context.already_repring", + " except AttributeError:", + " already_repring = {id(self),}", + " _compat.repr_context.already_repring = already_repring", + " else:", + " if id(self) in already_repring:", + " return '...'", + " else:", + " already_repring.add(id(self))", + " try:", + " return f'%s(%s)'" % (cls_name_fragment, repr_fragment), + " finally:", + " already_repring.remove(id(self))", + ] + + return _make_method( + "__repr__", "\n".join(lines), unique_filename, globs=globs + ) + +else: + + def _make_repr(attrs, ns, _): + """ + Make a repr method that includes relevant *attrs*, adding *ns* to the + full name. + """ + + # Figure out which attributes to include, and which function to use to + # format them. The a.repr value can be either bool or a custom + # callable. + attr_names_with_reprs = tuple( + (a.name, repr if a.repr is True else a.repr) + for a in attrs + if a.repr is not False + ) + + def __repr__(self): + """ + Automatically created by attrs. + """ + try: + already_repring = _compat.repr_context.already_repring + except AttributeError: + already_repring = set() + _compat.repr_context.already_repring = already_repring + + if id(self) in already_repring: + return "..." + real_cls = self.__class__ + if ns is None: + class_name = real_cls.__qualname__.rsplit(">.", 1)[-1] + else: + class_name = ns + "." + real_cls.__name__ + + # Since 'self' remains on the stack (i.e.: strongly referenced) + # for the duration of this call, it's safe to depend on id(...) + # stability, and not need to track the instance and therefore + # worry about properties like weakref- or hash-ability. + already_repring.add(id(self)) + try: + result = [class_name, "("] + first = True + for name, attr_repr in attr_names_with_reprs: + if first: + first = False + else: + result.append(", ") + result.extend( + (name, "=", attr_repr(getattr(self, name, NOTHING))) + ) + return "".join(result) + ")" + finally: + already_repring.remove(id(self)) + + return __repr__ + + +def _add_repr(cls, ns=None, attrs=None): + """ + Add a repr method to *cls*. + """ + if attrs is None: + attrs = cls.__attrs_attrs__ + + cls.__repr__ = _make_repr(attrs, ns, cls) + return cls + + +def fields(cls): + """ + Return the tuple of ``attrs`` attributes for a class. + + The tuple also allows accessing the fields by their names (see below for + examples). + + :param type cls: Class to introspect. + + :raise TypeError: If *cls* is not a class. + :raise attr.exceptions.NotAnAttrsClassError: If *cls* is not an ``attrs`` + class. + + :rtype: tuple (with name accessors) of `attrs.Attribute` + + .. versionchanged:: 16.2.0 Returned tuple allows accessing the fields + by name. + """ + if not isinstance(cls, type): + raise TypeError("Passed object must be a class.") + attrs = getattr(cls, "__attrs_attrs__", None) + if attrs is None: + raise NotAnAttrsClassError( + "{cls!r} is not an attrs-decorated class.".format(cls=cls) + ) + return attrs + + +def fields_dict(cls): + """ + Return an ordered dictionary of ``attrs`` attributes for a class, whose + keys are the attribute names. + + :param type cls: Class to introspect. + + :raise TypeError: If *cls* is not a class. + :raise attr.exceptions.NotAnAttrsClassError: If *cls* is not an ``attrs`` + class. + + :rtype: an ordered dict where keys are attribute names and values are + `attrs.Attribute`\\ s. This will be a `dict` if it's + naturally ordered like on Python 3.6+ or an + :class:`~collections.OrderedDict` otherwise. + + .. versionadded:: 18.1.0 + """ + if not isinstance(cls, type): + raise TypeError("Passed object must be a class.") + attrs = getattr(cls, "__attrs_attrs__", None) + if attrs is None: + raise NotAnAttrsClassError( + "{cls!r} is not an attrs-decorated class.".format(cls=cls) + ) + return ordered_dict((a.name, a) for a in attrs) + + +def validate(inst): + """ + Validate all attributes on *inst* that have a validator. + + Leaves all exceptions through. + + :param inst: Instance of a class with ``attrs`` attributes. + """ + if _config._run_validators is False: + return + + for a in fields(inst.__class__): + v = a.validator + if v is not None: + v(inst, a, getattr(inst, a.name)) + + +def _is_slot_cls(cls): + return "__slots__" in cls.__dict__ + + +def _is_slot_attr(a_name, base_attr_map): + """ + Check if the attribute name comes from a slot class. + """ + return a_name in base_attr_map and _is_slot_cls(base_attr_map[a_name]) + + +def _make_init( + cls, + attrs, + pre_init, + post_init, + frozen, + slots, + cache_hash, + base_attr_map, + is_exc, + cls_on_setattr, + attrs_init, +): + has_cls_on_setattr = ( + cls_on_setattr is not None and cls_on_setattr is not setters.NO_OP + ) + + if frozen and has_cls_on_setattr: + raise ValueError("Frozen classes can't use on_setattr.") + + needs_cached_setattr = cache_hash or frozen + filtered_attrs = [] + attr_dict = {} + for a in attrs: + if not a.init and a.default is NOTHING: + continue + + filtered_attrs.append(a) + attr_dict[a.name] = a + + if a.on_setattr is not None: + if frozen is True: + raise ValueError("Frozen classes can't use on_setattr.") + + needs_cached_setattr = True + elif has_cls_on_setattr and a.on_setattr is not setters.NO_OP: + needs_cached_setattr = True + + unique_filename = _generate_unique_filename(cls, "init") + + script, globs, annotations = _attrs_to_init_script( + filtered_attrs, + frozen, + slots, + pre_init, + post_init, + cache_hash, + base_attr_map, + is_exc, + has_cls_on_setattr, + attrs_init, + ) + if cls.__module__ in sys.modules: + # This makes typing.get_type_hints(CLS.__init__) resolve string types. + globs.update(sys.modules[cls.__module__].__dict__) + + globs.update({"NOTHING": NOTHING, "attr_dict": attr_dict}) + + if needs_cached_setattr: + # Save the lookup overhead in __init__ if we need to circumvent + # setattr hooks. + globs["_setattr"] = _obj_setattr + + init = _make_method( + "__attrs_init__" if attrs_init else "__init__", + script, + unique_filename, + globs, + ) + init.__annotations__ = annotations + + return init + + +def _setattr(attr_name, value_var, has_on_setattr): + """ + Use the cached object.setattr to set *attr_name* to *value_var*. + """ + return "_setattr(self, '%s', %s)" % (attr_name, value_var) + + +def _setattr_with_converter(attr_name, value_var, has_on_setattr): + """ + Use the cached object.setattr to set *attr_name* to *value_var*, but run + its converter first. + """ + return "_setattr(self, '%s', %s(%s))" % ( + attr_name, + _init_converter_pat % (attr_name,), + value_var, + ) + + +def _assign(attr_name, value, has_on_setattr): + """ + Unless *attr_name* has an on_setattr hook, use normal assignment. Otherwise + relegate to _setattr. + """ + if has_on_setattr: + return _setattr(attr_name, value, True) + + return "self.%s = %s" % (attr_name, value) + + +def _assign_with_converter(attr_name, value_var, has_on_setattr): + """ + Unless *attr_name* has an on_setattr hook, use normal assignment after + conversion. Otherwise relegate to _setattr_with_converter. + """ + if has_on_setattr: + return _setattr_with_converter(attr_name, value_var, True) + + return "self.%s = %s(%s)" % ( + attr_name, + _init_converter_pat % (attr_name,), + value_var, + ) + + +def _attrs_to_init_script( + attrs, + frozen, + slots, + pre_init, + post_init, + cache_hash, + base_attr_map, + is_exc, + has_cls_on_setattr, + attrs_init, +): + """ + Return a script of an initializer for *attrs* and a dict of globals. + + The globals are expected by the generated script. + + If *frozen* is True, we cannot set the attributes directly so we use + a cached ``object.__setattr__``. + """ + lines = [] + if pre_init: + lines.append("self.__attrs_pre_init__()") + + if frozen is True: + if slots is True: + fmt_setter = _setattr + fmt_setter_with_converter = _setattr_with_converter + else: + # Dict frozen classes assign directly to __dict__. + # But only if the attribute doesn't come from an ancestor slot + # class. + # Note _inst_dict will be used again below if cache_hash is True + lines.append("_inst_dict = self.__dict__") + + def fmt_setter(attr_name, value_var, has_on_setattr): + if _is_slot_attr(attr_name, base_attr_map): + return _setattr(attr_name, value_var, has_on_setattr) + + return "_inst_dict['%s'] = %s" % (attr_name, value_var) + + def fmt_setter_with_converter( + attr_name, value_var, has_on_setattr + ): + if has_on_setattr or _is_slot_attr(attr_name, base_attr_map): + return _setattr_with_converter( + attr_name, value_var, has_on_setattr + ) + + return "_inst_dict['%s'] = %s(%s)" % ( + attr_name, + _init_converter_pat % (attr_name,), + value_var, + ) + + else: + # Not frozen. + fmt_setter = _assign + fmt_setter_with_converter = _assign_with_converter + + args = [] + kw_only_args = [] + attrs_to_validate = [] + + # This is a dictionary of names to validator and converter callables. + # Injecting this into __init__ globals lets us avoid lookups. + names_for_globals = {} + annotations = {"return": None} + + for a in attrs: + if a.validator: + attrs_to_validate.append(a) + + attr_name = a.name + has_on_setattr = a.on_setattr is not None or ( + a.on_setattr is not setters.NO_OP and has_cls_on_setattr + ) + arg_name = a.name.lstrip("_") + + has_factory = isinstance(a.default, Factory) + if has_factory and a.default.takes_self: + maybe_self = "self" + else: + maybe_self = "" + + if a.init is False: + if has_factory: + init_factory_name = _init_factory_pat.format(a.name) + if a.converter is not None: + lines.append( + fmt_setter_with_converter( + attr_name, + init_factory_name + "(%s)" % (maybe_self,), + has_on_setattr, + ) + ) + conv_name = _init_converter_pat % (a.name,) + names_for_globals[conv_name] = a.converter + else: + lines.append( + fmt_setter( + attr_name, + init_factory_name + "(%s)" % (maybe_self,), + has_on_setattr, + ) + ) + names_for_globals[init_factory_name] = a.default.factory + else: + if a.converter is not None: + lines.append( + fmt_setter_with_converter( + attr_name, + "attr_dict['%s'].default" % (attr_name,), + has_on_setattr, + ) + ) + conv_name = _init_converter_pat % (a.name,) + names_for_globals[conv_name] = a.converter + else: + lines.append( + fmt_setter( + attr_name, + "attr_dict['%s'].default" % (attr_name,), + has_on_setattr, + ) + ) + elif a.default is not NOTHING and not has_factory: + arg = "%s=attr_dict['%s'].default" % (arg_name, attr_name) + if a.kw_only: + kw_only_args.append(arg) + else: + args.append(arg) + + if a.converter is not None: + lines.append( + fmt_setter_with_converter( + attr_name, arg_name, has_on_setattr + ) + ) + names_for_globals[ + _init_converter_pat % (a.name,) + ] = a.converter + else: + lines.append(fmt_setter(attr_name, arg_name, has_on_setattr)) + + elif has_factory: + arg = "%s=NOTHING" % (arg_name,) + if a.kw_only: + kw_only_args.append(arg) + else: + args.append(arg) + lines.append("if %s is not NOTHING:" % (arg_name,)) + + init_factory_name = _init_factory_pat.format(a.name) + if a.converter is not None: + lines.append( + " " + + fmt_setter_with_converter( + attr_name, arg_name, has_on_setattr + ) + ) + lines.append("else:") + lines.append( + " " + + fmt_setter_with_converter( + attr_name, + init_factory_name + "(" + maybe_self + ")", + has_on_setattr, + ) + ) + names_for_globals[ + _init_converter_pat % (a.name,) + ] = a.converter + else: + lines.append( + " " + fmt_setter(attr_name, arg_name, has_on_setattr) + ) + lines.append("else:") + lines.append( + " " + + fmt_setter( + attr_name, + init_factory_name + "(" + maybe_self + ")", + has_on_setattr, + ) + ) + names_for_globals[init_factory_name] = a.default.factory + else: + if a.kw_only: + kw_only_args.append(arg_name) + else: + args.append(arg_name) + + if a.converter is not None: + lines.append( + fmt_setter_with_converter( + attr_name, arg_name, has_on_setattr + ) + ) + names_for_globals[ + _init_converter_pat % (a.name,) + ] = a.converter + else: + lines.append(fmt_setter(attr_name, arg_name, has_on_setattr)) + + if a.init is True: + if a.type is not None and a.converter is None: + annotations[arg_name] = a.type + elif a.converter is not None: + # Try to get the type from the converter. + t = _AnnotationExtractor(a.converter).get_first_param_type() + if t: + annotations[arg_name] = t + + if attrs_to_validate: # we can skip this if there are no validators. + names_for_globals["_config"] = _config + lines.append("if _config._run_validators is True:") + for a in attrs_to_validate: + val_name = "__attr_validator_" + a.name + attr_name = "__attr_" + a.name + lines.append( + " %s(self, %s, self.%s)" % (val_name, attr_name, a.name) + ) + names_for_globals[val_name] = a.validator + names_for_globals[attr_name] = a + + if post_init: + lines.append("self.__attrs_post_init__()") + + # because this is set only after __attrs_post_init__ is called, a crash + # will result if post-init tries to access the hash code. This seemed + # preferable to setting this beforehand, in which case alteration to + # field values during post-init combined with post-init accessing the + # hash code would result in silent bugs. + if cache_hash: + if frozen: + if slots: + # if frozen and slots, then _setattr defined above + init_hash_cache = "_setattr(self, '%s', %s)" + else: + # if frozen and not slots, then _inst_dict defined above + init_hash_cache = "_inst_dict['%s'] = %s" + else: + init_hash_cache = "self.%s = %s" + lines.append(init_hash_cache % (_hash_cache_field, "None")) + + # For exceptions we rely on BaseException.__init__ for proper + # initialization. + if is_exc: + vals = ",".join("self." + a.name for a in attrs if a.init) + + lines.append("BaseException.__init__(self, %s)" % (vals,)) + + args = ", ".join(args) + if kw_only_args: + args += "%s*, %s" % ( + ", " if args else "", # leading comma + ", ".join(kw_only_args), # kw_only args + ) + return ( + """\ +def {init_name}(self, {args}): + {lines} +""".format( + init_name=("__attrs_init__" if attrs_init else "__init__"), + args=args, + lines="\n ".join(lines) if lines else "pass", + ), + names_for_globals, + annotations, + ) + + +class Attribute: + """ + *Read-only* representation of an attribute. + + The class has *all* arguments of `attr.ib` (except for ``factory`` + which is only syntactic sugar for ``default=Factory(...)`` plus the + following: + + - ``name`` (`str`): The name of the attribute. + - ``inherited`` (`bool`): Whether or not that attribute has been inherited + from a base class. + - ``eq_key`` and ``order_key`` (`typing.Callable` or `None`): The callables + that are used for comparing and ordering objects by this attribute, + respectively. These are set by passing a callable to `attr.ib`'s ``eq``, + ``order``, or ``cmp`` arguments. See also :ref:`comparison customization + `. + + Instances of this class are frequently used for introspection purposes + like: + + - `fields` returns a tuple of them. + - Validators get them passed as the first argument. + - The :ref:`field transformer ` hook receives a list of + them. + + .. versionadded:: 20.1.0 *inherited* + .. versionadded:: 20.1.0 *on_setattr* + .. versionchanged:: 20.2.0 *inherited* is not taken into account for + equality checks and hashing anymore. + .. versionadded:: 21.1.0 *eq_key* and *order_key* + + For the full version history of the fields, see `attr.ib`. + """ + + __slots__ = ( + "name", + "default", + "validator", + "repr", + "eq", + "eq_key", + "order", + "order_key", + "hash", + "init", + "metadata", + "type", + "converter", + "kw_only", + "inherited", + "on_setattr", + ) + + def __init__( + self, + name, + default, + validator, + repr, + cmp, # XXX: unused, remove along with other cmp code. + hash, + init, + inherited, + metadata=None, + type=None, + converter=None, + kw_only=False, + eq=None, + eq_key=None, + order=None, + order_key=None, + on_setattr=None, + ): + eq, eq_key, order, order_key = _determine_attrib_eq_order( + cmp, eq_key or eq, order_key or order, True + ) + + # Cache this descriptor here to speed things up later. + bound_setattr = _obj_setattr.__get__(self, Attribute) + + # Despite the big red warning, people *do* instantiate `Attribute` + # themselves. + bound_setattr("name", name) + bound_setattr("default", default) + bound_setattr("validator", validator) + bound_setattr("repr", repr) + bound_setattr("eq", eq) + bound_setattr("eq_key", eq_key) + bound_setattr("order", order) + bound_setattr("order_key", order_key) + bound_setattr("hash", hash) + bound_setattr("init", init) + bound_setattr("converter", converter) + bound_setattr( + "metadata", + ( + types.MappingProxyType(dict(metadata)) # Shallow copy + if metadata + else _empty_metadata_singleton + ), + ) + bound_setattr("type", type) + bound_setattr("kw_only", kw_only) + bound_setattr("inherited", inherited) + bound_setattr("on_setattr", on_setattr) + + def __setattr__(self, name, value): + raise FrozenInstanceError() + + @classmethod + def from_counting_attr(cls, name, ca, type=None): + # type holds the annotated value. deal with conflicts: + if type is None: + type = ca.type + elif ca.type is not None: + raise ValueError( + "Type annotation and type argument cannot both be present" + ) + inst_dict = { + k: getattr(ca, k) + for k in Attribute.__slots__ + if k + not in ( + "name", + "validator", + "default", + "type", + "inherited", + ) # exclude methods and deprecated alias + } + return cls( + name=name, + validator=ca._validator, + default=ca._default, + type=type, + cmp=None, + inherited=False, + **inst_dict + ) + + # Don't use attr.evolve since fields(Attribute) doesn't work + def evolve(self, **changes): + """ + Copy *self* and apply *changes*. + + This works similarly to `attr.evolve` but that function does not work + with ``Attribute``. + + It is mainly meant to be used for `transform-fields`. + + .. versionadded:: 20.3.0 + """ + new = copy.copy(self) + + new._setattrs(changes.items()) + + return new + + # Don't use _add_pickle since fields(Attribute) doesn't work + def __getstate__(self): + """ + Play nice with pickle. + """ + return tuple( + getattr(self, name) if name != "metadata" else dict(self.metadata) + for name in self.__slots__ + ) + + def __setstate__(self, state): + """ + Play nice with pickle. + """ + self._setattrs(zip(self.__slots__, state)) + + def _setattrs(self, name_values_pairs): + bound_setattr = _obj_setattr.__get__(self, Attribute) + for name, value in name_values_pairs: + if name != "metadata": + bound_setattr(name, value) + else: + bound_setattr( + name, + types.MappingProxyType(dict(value)) + if value + else _empty_metadata_singleton, + ) + + +_a = [ + Attribute( + name=name, + default=NOTHING, + validator=None, + repr=True, + cmp=None, + eq=True, + order=False, + hash=(name != "metadata"), + init=True, + inherited=False, + ) + for name in Attribute.__slots__ +] + +Attribute = _add_hash( + _add_eq( + _add_repr(Attribute, attrs=_a), + attrs=[a for a in _a if a.name != "inherited"], + ), + attrs=[a for a in _a if a.hash and a.name != "inherited"], +) + + +class _CountingAttr: + """ + Intermediate representation of attributes that uses a counter to preserve + the order in which the attributes have been defined. + + *Internal* data structure of the attrs library. Running into is most + likely the result of a bug like a forgotten `@attr.s` decorator. + """ + + __slots__ = ( + "counter", + "_default", + "repr", + "eq", + "eq_key", + "order", + "order_key", + "hash", + "init", + "metadata", + "_validator", + "converter", + "type", + "kw_only", + "on_setattr", + ) + __attrs_attrs__ = tuple( + Attribute( + name=name, + default=NOTHING, + validator=None, + repr=True, + cmp=None, + hash=True, + init=True, + kw_only=False, + eq=True, + eq_key=None, + order=False, + order_key=None, + inherited=False, + on_setattr=None, + ) + for name in ( + "counter", + "_default", + "repr", + "eq", + "order", + "hash", + "init", + "on_setattr", + ) + ) + ( + Attribute( + name="metadata", + default=None, + validator=None, + repr=True, + cmp=None, + hash=False, + init=True, + kw_only=False, + eq=True, + eq_key=None, + order=False, + order_key=None, + inherited=False, + on_setattr=None, + ), + ) + cls_counter = 0 + + def __init__( + self, + default, + validator, + repr, + cmp, + hash, + init, + converter, + metadata, + type, + kw_only, + eq, + eq_key, + order, + order_key, + on_setattr, + ): + _CountingAttr.cls_counter += 1 + self.counter = _CountingAttr.cls_counter + self._default = default + self._validator = validator + self.converter = converter + self.repr = repr + self.eq = eq + self.eq_key = eq_key + self.order = order + self.order_key = order_key + self.hash = hash + self.init = init + self.metadata = metadata + self.type = type + self.kw_only = kw_only + self.on_setattr = on_setattr + + def validator(self, meth): + """ + Decorator that adds *meth* to the list of validators. + + Returns *meth* unchanged. + + .. versionadded:: 17.1.0 + """ + if self._validator is None: + self._validator = meth + else: + self._validator = and_(self._validator, meth) + return meth + + def default(self, meth): + """ + Decorator that allows to set the default for an attribute. + + Returns *meth* unchanged. + + :raises DefaultAlreadySetError: If default has been set before. + + .. versionadded:: 17.1.0 + """ + if self._default is not NOTHING: + raise DefaultAlreadySetError() + + self._default = Factory(meth, takes_self=True) + + return meth + + +_CountingAttr = _add_eq(_add_repr(_CountingAttr)) + + +class Factory: + """ + Stores a factory callable. + + If passed as the default value to `attrs.field`, the factory is used to + generate a new value. + + :param callable factory: A callable that takes either none or exactly one + mandatory positional argument depending on *takes_self*. + :param bool takes_self: Pass the partially initialized instance that is + being initialized as a positional argument. + + .. versionadded:: 17.1.0 *takes_self* + """ + + __slots__ = ("factory", "takes_self") + + def __init__(self, factory, takes_self=False): + """ + `Factory` is part of the default machinery so if we want a default + value here, we have to implement it ourselves. + """ + self.factory = factory + self.takes_self = takes_self + + def __getstate__(self): + """ + Play nice with pickle. + """ + return tuple(getattr(self, name) for name in self.__slots__) + + def __setstate__(self, state): + """ + Play nice with pickle. + """ + for name, value in zip(self.__slots__, state): + setattr(self, name, value) + + +_f = [ + Attribute( + name=name, + default=NOTHING, + validator=None, + repr=True, + cmp=None, + eq=True, + order=False, + hash=True, + init=True, + inherited=False, + ) + for name in Factory.__slots__ +] + +Factory = _add_hash(_add_eq(_add_repr(Factory, attrs=_f), attrs=_f), attrs=_f) + + +def make_class(name, attrs, bases=(object,), **attributes_arguments): + """ + A quick way to create a new class called *name* with *attrs*. + + :param str name: The name for the new class. + + :param attrs: A list of names or a dictionary of mappings of names to + attributes. + + If *attrs* is a list or an ordered dict (`dict` on Python 3.6+, + `collections.OrderedDict` otherwise), the order is deduced from + the order of the names or attributes inside *attrs*. Otherwise the + order of the definition of the attributes is used. + :type attrs: `list` or `dict` + + :param tuple bases: Classes that the new class will subclass. + + :param attributes_arguments: Passed unmodified to `attr.s`. + + :return: A new class with *attrs*. + :rtype: type + + .. versionadded:: 17.1.0 *bases* + .. versionchanged:: 18.1.0 If *attrs* is ordered, the order is retained. + """ + if isinstance(attrs, dict): + cls_dict = attrs + elif isinstance(attrs, (list, tuple)): + cls_dict = {a: attrib() for a in attrs} + else: + raise TypeError("attrs argument must be a dict or a list.") + + pre_init = cls_dict.pop("__attrs_pre_init__", None) + post_init = cls_dict.pop("__attrs_post_init__", None) + user_init = cls_dict.pop("__init__", None) + + body = {} + if pre_init is not None: + body["__attrs_pre_init__"] = pre_init + if post_init is not None: + body["__attrs_post_init__"] = post_init + if user_init is not None: + body["__init__"] = user_init + + type_ = types.new_class(name, bases, {}, lambda ns: ns.update(body)) + + # For pickling to work, the __module__ variable needs to be set to the + # frame where the class is created. Bypass this step in environments where + # sys._getframe is not defined (Jython for example) or sys._getframe is not + # defined for arguments greater than 0 (IronPython). + try: + type_.__module__ = sys._getframe(1).f_globals.get( + "__name__", "__main__" + ) + except (AttributeError, ValueError): + pass + + # We do it here for proper warnings with meaningful stacklevel. + cmp = attributes_arguments.pop("cmp", None) + ( + attributes_arguments["eq"], + attributes_arguments["order"], + ) = _determine_attrs_eq_order( + cmp, + attributes_arguments.get("eq"), + attributes_arguments.get("order"), + True, + ) + + return _attrs(these=cls_dict, **attributes_arguments)(type_) + + +# These are required by within this module so we define them here and merely +# import into .validators / .converters. + + +@attrs(slots=True, hash=True) +class _AndValidator: + """ + Compose many validators to a single one. + """ + + _validators = attrib() + + def __call__(self, inst, attr, value): + for v in self._validators: + v(inst, attr, value) + + +def and_(*validators): + """ + A validator that composes multiple validators into one. + + When called on a value, it runs all wrapped validators. + + :param callables validators: Arbitrary number of validators. + + .. versionadded:: 17.1.0 + """ + vals = [] + for validator in validators: + vals.extend( + validator._validators + if isinstance(validator, _AndValidator) + else [validator] + ) + + return _AndValidator(tuple(vals)) + + +def pipe(*converters): + """ + A converter that composes multiple converters into one. + + When called on a value, it runs all wrapped converters, returning the + *last* value. + + Type annotations will be inferred from the wrapped converters', if + they have any. + + :param callables converters: Arbitrary number of converters. + + .. versionadded:: 20.1.0 + """ + + def pipe_converter(val): + for converter in converters: + val = converter(val) + + return val + + if not converters: + # If the converter list is empty, pipe_converter is the identity. + A = typing.TypeVar("A") + pipe_converter.__annotations__ = {"val": A, "return": A} + else: + # Get parameter type from first converter. + t = _AnnotationExtractor(converters[0]).get_first_param_type() + if t: + pipe_converter.__annotations__["val"] = t + + # Get return type from last converter. + rt = _AnnotationExtractor(converters[-1]).get_return_type() + if rt: + pipe_converter.__annotations__["return"] = rt + + return pipe_converter diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/attr/_next_gen.py b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/attr/_next_gen.py new file mode 100644 index 00000000..5a06a743 --- /dev/null +++ b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/attr/_next_gen.py @@ -0,0 +1,220 @@ +# SPDX-License-Identifier: MIT + +""" +These are Python 3.6+-only and keyword-only APIs that call `attr.s` and +`attr.ib` with different default values. +""" + + +from functools import partial + +from . import setters +from ._funcs import asdict as _asdict +from ._funcs import astuple as _astuple +from ._make import ( + NOTHING, + _frozen_setattrs, + _ng_default_on_setattr, + attrib, + attrs, +) +from .exceptions import UnannotatedAttributeError + + +def define( + maybe_cls=None, + *, + these=None, + repr=None, + hash=None, + init=None, + slots=True, + frozen=False, + weakref_slot=True, + str=False, + auto_attribs=None, + kw_only=False, + cache_hash=False, + auto_exc=True, + eq=None, + order=False, + auto_detect=True, + getstate_setstate=None, + on_setattr=None, + field_transformer=None, + match_args=True, +): + r""" + Define an ``attrs`` class. + + Differences to the classic `attr.s` that it uses underneath: + + - Automatically detect whether or not *auto_attribs* should be `True` (c.f. + *auto_attribs* parameter). + - If *frozen* is `False`, run converters and validators when setting an + attribute by default. + - *slots=True* + + .. caution:: + + Usually this has only upsides and few visible effects in everyday + programming. But it *can* lead to some suprising behaviors, so please + make sure to read :term:`slotted classes`. + - *auto_exc=True* + - *auto_detect=True* + - *order=False* + - Some options that were only relevant on Python 2 or were kept around for + backwards-compatibility have been removed. + + Please note that these are all defaults and you can change them as you + wish. + + :param Optional[bool] auto_attribs: If set to `True` or `False`, it behaves + exactly like `attr.s`. If left `None`, `attr.s` will try to guess: + + 1. If any attributes are annotated and no unannotated `attrs.fields`\ s + are found, it assumes *auto_attribs=True*. + 2. Otherwise it assumes *auto_attribs=False* and tries to collect + `attrs.fields`\ s. + + For now, please refer to `attr.s` for the rest of the parameters. + + .. versionadded:: 20.1.0 + .. versionchanged:: 21.3.0 Converters are also run ``on_setattr``. + """ + + def do_it(cls, auto_attribs): + return attrs( + maybe_cls=cls, + these=these, + repr=repr, + hash=hash, + init=init, + slots=slots, + frozen=frozen, + weakref_slot=weakref_slot, + str=str, + auto_attribs=auto_attribs, + kw_only=kw_only, + cache_hash=cache_hash, + auto_exc=auto_exc, + eq=eq, + order=order, + auto_detect=auto_detect, + collect_by_mro=True, + getstate_setstate=getstate_setstate, + on_setattr=on_setattr, + field_transformer=field_transformer, + match_args=match_args, + ) + + def wrap(cls): + """ + Making this a wrapper ensures this code runs during class creation. + + We also ensure that frozen-ness of classes is inherited. + """ + nonlocal frozen, on_setattr + + had_on_setattr = on_setattr not in (None, setters.NO_OP) + + # By default, mutable classes convert & validate on setattr. + if frozen is False and on_setattr is None: + on_setattr = _ng_default_on_setattr + + # However, if we subclass a frozen class, we inherit the immutability + # and disable on_setattr. + for base_cls in cls.__bases__: + if base_cls.__setattr__ is _frozen_setattrs: + if had_on_setattr: + raise ValueError( + "Frozen classes can't use on_setattr " + "(frozen-ness was inherited)." + ) + + on_setattr = setters.NO_OP + break + + if auto_attribs is not None: + return do_it(cls, auto_attribs) + + try: + return do_it(cls, True) + except UnannotatedAttributeError: + return do_it(cls, False) + + # maybe_cls's type depends on the usage of the decorator. It's a class + # if it's used as `@attrs` but ``None`` if used as `@attrs()`. + if maybe_cls is None: + return wrap + else: + return wrap(maybe_cls) + + +mutable = define +frozen = partial(define, frozen=True, on_setattr=None) + + +def field( + *, + default=NOTHING, + validator=None, + repr=True, + hash=None, + init=True, + metadata=None, + converter=None, + factory=None, + kw_only=False, + eq=None, + order=None, + on_setattr=None, +): + """ + Identical to `attr.ib`, except keyword-only and with some arguments + removed. + + .. versionadded:: 20.1.0 + """ + return attrib( + default=default, + validator=validator, + repr=repr, + hash=hash, + init=init, + metadata=metadata, + converter=converter, + factory=factory, + kw_only=kw_only, + eq=eq, + order=order, + on_setattr=on_setattr, + ) + + +def asdict(inst, *, recurse=True, filter=None, value_serializer=None): + """ + Same as `attr.asdict`, except that collections types are always retained + and dict is always used as *dict_factory*. + + .. versionadded:: 21.3.0 + """ + return _asdict( + inst=inst, + recurse=recurse, + filter=filter, + value_serializer=value_serializer, + retain_collection_types=True, + ) + + +def astuple(inst, *, recurse=True, filter=None): + """ + Same as `attr.astuple`, except that collections types are always retained + and `tuple` is always used as the *tuple_factory*. + + .. versionadded:: 21.3.0 + """ + return _astuple( + inst=inst, recurse=recurse, filter=filter, retain_collection_types=True + ) diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/attr/_version_info.py b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/attr/_version_info.py new file mode 100644 index 00000000..51a1312f --- /dev/null +++ b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/attr/_version_info.py @@ -0,0 +1,86 @@ +# SPDX-License-Identifier: MIT + + +from functools import total_ordering + +from ._funcs import astuple +from ._make import attrib, attrs + + +@total_ordering +@attrs(eq=False, order=False, slots=True, frozen=True) +class VersionInfo: + """ + A version object that can be compared to tuple of length 1--4: + + >>> attr.VersionInfo(19, 1, 0, "final") <= (19, 2) + True + >>> attr.VersionInfo(19, 1, 0, "final") < (19, 1, 1) + True + >>> vi = attr.VersionInfo(19, 2, 0, "final") + >>> vi < (19, 1, 1) + False + >>> vi < (19,) + False + >>> vi == (19, 2,) + True + >>> vi == (19, 2, 1) + False + + .. versionadded:: 19.2 + """ + + year = attrib(type=int) + minor = attrib(type=int) + micro = attrib(type=int) + releaselevel = attrib(type=str) + + @classmethod + def _from_version_string(cls, s): + """ + Parse *s* and return a _VersionInfo. + """ + v = s.split(".") + if len(v) == 3: + v.append("final") + + return cls( + year=int(v[0]), minor=int(v[1]), micro=int(v[2]), releaselevel=v[3] + ) + + def _ensure_tuple(self, other): + """ + Ensure *other* is a tuple of a valid length. + + Returns a possibly transformed *other* and ourselves as a tuple of + the same length as *other*. + """ + + if self.__class__ is other.__class__: + other = astuple(other) + + if not isinstance(other, tuple): + raise NotImplementedError + + if not (1 <= len(other) <= 4): + raise NotImplementedError + + return astuple(self)[: len(other)], other + + def __eq__(self, other): + try: + us, them = self._ensure_tuple(other) + except NotImplementedError: + return NotImplemented + + return us == them + + def __lt__(self, other): + try: + us, them = self._ensure_tuple(other) + except NotImplementedError: + return NotImplemented + + # Since alphabetically "dev0" < "final" < "post1" < "post2", we don't + # have to do anything special with releaselevel for now. + return us < them diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/attr/_version_info.pyi b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/attr/_version_info.pyi new file mode 100644 index 00000000..45ced086 --- /dev/null +++ b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/attr/_version_info.pyi @@ -0,0 +1,9 @@ +class VersionInfo: + @property + def year(self) -> int: ... + @property + def minor(self) -> int: ... + @property + def micro(self) -> int: ... + @property + def releaselevel(self) -> str: ... diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/attr/converters.py b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/attr/converters.py new file mode 100644 index 00000000..a73626c2 --- /dev/null +++ b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/attr/converters.py @@ -0,0 +1,144 @@ +# SPDX-License-Identifier: MIT + +""" +Commonly useful converters. +""" + + +import typing + +from ._compat import _AnnotationExtractor +from ._make import NOTHING, Factory, pipe + + +__all__ = [ + "default_if_none", + "optional", + "pipe", + "to_bool", +] + + +def optional(converter): + """ + A converter that allows an attribute to be optional. An optional attribute + is one which can be set to ``None``. + + Type annotations will be inferred from the wrapped converter's, if it + has any. + + :param callable converter: the converter that is used for non-``None`` + values. + + .. versionadded:: 17.1.0 + """ + + def optional_converter(val): + if val is None: + return None + return converter(val) + + xtr = _AnnotationExtractor(converter) + + t = xtr.get_first_param_type() + if t: + optional_converter.__annotations__["val"] = typing.Optional[t] + + rt = xtr.get_return_type() + if rt: + optional_converter.__annotations__["return"] = typing.Optional[rt] + + return optional_converter + + +def default_if_none(default=NOTHING, factory=None): + """ + A converter that allows to replace ``None`` values by *default* or the + result of *factory*. + + :param default: Value to be used if ``None`` is passed. Passing an instance + of `attrs.Factory` is supported, however the ``takes_self`` option + is *not*. + :param callable factory: A callable that takes no parameters whose result + is used if ``None`` is passed. + + :raises TypeError: If **neither** *default* or *factory* is passed. + :raises TypeError: If **both** *default* and *factory* are passed. + :raises ValueError: If an instance of `attrs.Factory` is passed with + ``takes_self=True``. + + .. versionadded:: 18.2.0 + """ + if default is NOTHING and factory is None: + raise TypeError("Must pass either `default` or `factory`.") + + if default is not NOTHING and factory is not None: + raise TypeError( + "Must pass either `default` or `factory` but not both." + ) + + if factory is not None: + default = Factory(factory) + + if isinstance(default, Factory): + if default.takes_self: + raise ValueError( + "`takes_self` is not supported by default_if_none." + ) + + def default_if_none_converter(val): + if val is not None: + return val + + return default.factory() + + else: + + def default_if_none_converter(val): + if val is not None: + return val + + return default + + return default_if_none_converter + + +def to_bool(val): + """ + Convert "boolean" strings (e.g., from env. vars.) to real booleans. + + Values mapping to :code:`True`: + + - :code:`True` + - :code:`"true"` / :code:`"t"` + - :code:`"yes"` / :code:`"y"` + - :code:`"on"` + - :code:`"1"` + - :code:`1` + + Values mapping to :code:`False`: + + - :code:`False` + - :code:`"false"` / :code:`"f"` + - :code:`"no"` / :code:`"n"` + - :code:`"off"` + - :code:`"0"` + - :code:`0` + + :raises ValueError: for any other value. + + .. versionadded:: 21.3.0 + """ + if isinstance(val, str): + val = val.lower() + truthy = {True, "true", "t", "yes", "y", "on", "1", 1} + falsy = {False, "false", "f", "no", "n", "off", "0", 0} + try: + if val in truthy: + return True + if val in falsy: + return False + except TypeError: + # Raised when "val" is not hashable (e.g., lists) + pass + raise ValueError("Cannot convert value to bool: {}".format(val)) diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/attr/converters.pyi b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/attr/converters.pyi new file mode 100644 index 00000000..0f58088a --- /dev/null +++ b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/attr/converters.pyi @@ -0,0 +1,13 @@ +from typing import Callable, Optional, TypeVar, overload + +from . import _ConverterType + +_T = TypeVar("_T") + +def pipe(*validators: _ConverterType) -> _ConverterType: ... +def optional(converter: _ConverterType) -> _ConverterType: ... +@overload +def default_if_none(default: _T) -> _ConverterType: ... +@overload +def default_if_none(*, factory: Callable[[], _T]) -> _ConverterType: ... +def to_bool(val: str) -> bool: ... diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/attr/exceptions.py b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/attr/exceptions.py new file mode 100644 index 00000000..5dc51e0a --- /dev/null +++ b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/attr/exceptions.py @@ -0,0 +1,92 @@ +# SPDX-License-Identifier: MIT + + +class FrozenError(AttributeError): + """ + A frozen/immutable instance or attribute have been attempted to be + modified. + + It mirrors the behavior of ``namedtuples`` by using the same error message + and subclassing `AttributeError`. + + .. versionadded:: 20.1.0 + """ + + msg = "can't set attribute" + args = [msg] + + +class FrozenInstanceError(FrozenError): + """ + A frozen instance has been attempted to be modified. + + .. versionadded:: 16.1.0 + """ + + +class FrozenAttributeError(FrozenError): + """ + A frozen attribute has been attempted to be modified. + + .. versionadded:: 20.1.0 + """ + + +class AttrsAttributeNotFoundError(ValueError): + """ + An ``attrs`` function couldn't find an attribute that the user asked for. + + .. versionadded:: 16.2.0 + """ + + +class NotAnAttrsClassError(ValueError): + """ + A non-``attrs`` class has been passed into an ``attrs`` function. + + .. versionadded:: 16.2.0 + """ + + +class DefaultAlreadySetError(RuntimeError): + """ + A default has been set using ``attr.ib()`` and is attempted to be reset + using the decorator. + + .. versionadded:: 17.1.0 + """ + + +class UnannotatedAttributeError(RuntimeError): + """ + A class with ``auto_attribs=True`` has an ``attr.ib()`` without a type + annotation. + + .. versionadded:: 17.3.0 + """ + + +class PythonTooOldError(RuntimeError): + """ + It was attempted to use an ``attrs`` feature that requires a newer Python + version. + + .. versionadded:: 18.2.0 + """ + + +class NotCallableError(TypeError): + """ + A ``attr.ib()`` requiring a callable has been set with a value + that is not callable. + + .. versionadded:: 19.2.0 + """ + + def __init__(self, msg, value): + super(TypeError, self).__init__(msg, value) + self.msg = msg + self.value = value + + def __str__(self): + return str(self.msg) diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/attr/exceptions.pyi b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/attr/exceptions.pyi new file mode 100644 index 00000000..f2680118 --- /dev/null +++ b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/attr/exceptions.pyi @@ -0,0 +1,17 @@ +from typing import Any + +class FrozenError(AttributeError): + msg: str = ... + +class FrozenInstanceError(FrozenError): ... +class FrozenAttributeError(FrozenError): ... +class AttrsAttributeNotFoundError(ValueError): ... +class NotAnAttrsClassError(ValueError): ... +class DefaultAlreadySetError(RuntimeError): ... +class UnannotatedAttributeError(RuntimeError): ... +class PythonTooOldError(RuntimeError): ... + +class NotCallableError(TypeError): + msg: str = ... + value: Any = ... + def __init__(self, msg: str, value: Any) -> None: ... diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/attr/filters.py b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/attr/filters.py new file mode 100644 index 00000000..baa25e94 --- /dev/null +++ b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/attr/filters.py @@ -0,0 +1,51 @@ +# SPDX-License-Identifier: MIT + +""" +Commonly useful filters for `attr.asdict`. +""" + +from ._make import Attribute + + +def _split_what(what): + """ + Returns a tuple of `frozenset`s of classes and attributes. + """ + return ( + frozenset(cls for cls in what if isinstance(cls, type)), + frozenset(cls for cls in what if isinstance(cls, Attribute)), + ) + + +def include(*what): + """ + Include *what*. + + :param what: What to include. + :type what: `list` of `type` or `attrs.Attribute`\\ s + + :rtype: `callable` + """ + cls, attrs = _split_what(what) + + def include_(attribute, value): + return value.__class__ in cls or attribute in attrs + + return include_ + + +def exclude(*what): + """ + Exclude *what*. + + :param what: What to exclude. + :type what: `list` of classes or `attrs.Attribute`\\ s. + + :rtype: `callable` + """ + cls, attrs = _split_what(what) + + def exclude_(attribute, value): + return value.__class__ not in cls and attribute not in attrs + + return exclude_ diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/attr/filters.pyi b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/attr/filters.pyi new file mode 100644 index 00000000..99386686 --- /dev/null +++ b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/attr/filters.pyi @@ -0,0 +1,6 @@ +from typing import Any, Union + +from . import Attribute, _FilterType + +def include(*what: Union[type, Attribute[Any]]) -> _FilterType[Any]: ... +def exclude(*what: Union[type, Attribute[Any]]) -> _FilterType[Any]: ... diff --git a/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA-1.2.13.dist-info/REQUESTED b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/attr/py.typed similarity index 100% rename from Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA-1.2.13.dist-info/REQUESTED rename to Resources/WPy32-3720/python-3.7.2/Lib/site-packages/attr/py.typed diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/attr/setters.py b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/attr/setters.py new file mode 100644 index 00000000..12ed6750 --- /dev/null +++ b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/attr/setters.py @@ -0,0 +1,73 @@ +# SPDX-License-Identifier: MIT + +""" +Commonly used hooks for on_setattr. +""" + + +from . import _config +from .exceptions import FrozenAttributeError + + +def pipe(*setters): + """ + Run all *setters* and return the return value of the last one. + + .. versionadded:: 20.1.0 + """ + + def wrapped_pipe(instance, attrib, new_value): + rv = new_value + + for setter in setters: + rv = setter(instance, attrib, rv) + + return rv + + return wrapped_pipe + + +def frozen(_, __, ___): + """ + Prevent an attribute to be modified. + + .. versionadded:: 20.1.0 + """ + raise FrozenAttributeError() + + +def validate(instance, attrib, new_value): + """ + Run *attrib*'s validator on *new_value* if it has one. + + .. versionadded:: 20.1.0 + """ + if _config._run_validators is False: + return new_value + + v = attrib.validator + if not v: + return new_value + + v(instance, attrib, new_value) + + return new_value + + +def convert(instance, attrib, new_value): + """ + Run *attrib*'s converter -- if it has one -- on *new_value* and return the + result. + + .. versionadded:: 20.1.0 + """ + c = attrib.converter + if c: + return c(new_value) + + return new_value + + +# Sentinel for disabling class-wide *on_setattr* hooks for certain attributes. +# autodata stopped working, so the docstring is inlined in the API docs. +NO_OP = object() diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/attr/setters.pyi b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/attr/setters.pyi new file mode 100644 index 00000000..3f5603c2 --- /dev/null +++ b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/attr/setters.pyi @@ -0,0 +1,19 @@ +from typing import Any, NewType, NoReturn, TypeVar, cast + +from . import Attribute, _OnSetAttrType + +_T = TypeVar("_T") + +def frozen( + instance: Any, attribute: Attribute[Any], new_value: Any +) -> NoReturn: ... +def pipe(*setters: _OnSetAttrType) -> _OnSetAttrType: ... +def validate(instance: Any, attribute: Attribute[_T], new_value: _T) -> _T: ... + +# convert is allowed to return Any, because they can be chained using pipe. +def convert( + instance: Any, attribute: Attribute[Any], new_value: Any +) -> Any: ... + +_NoOpType = NewType("_NoOpType", object) +NO_OP: _NoOpType diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/attr/validators.py b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/attr/validators.py new file mode 100644 index 00000000..eece517d --- /dev/null +++ b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/attr/validators.py @@ -0,0 +1,594 @@ +# SPDX-License-Identifier: MIT + +""" +Commonly useful validators. +""" + + +import operator +import re + +from contextlib import contextmanager + +from ._config import get_run_validators, set_run_validators +from ._make import _AndValidator, and_, attrib, attrs +from .exceptions import NotCallableError + + +try: + Pattern = re.Pattern +except AttributeError: # Python <3.7 lacks a Pattern type. + Pattern = type(re.compile("")) + + +__all__ = [ + "and_", + "deep_iterable", + "deep_mapping", + "disabled", + "ge", + "get_disabled", + "gt", + "in_", + "instance_of", + "is_callable", + "le", + "lt", + "matches_re", + "max_len", + "min_len", + "optional", + "provides", + "set_disabled", +] + + +def set_disabled(disabled): + """ + Globally disable or enable running validators. + + By default, they are run. + + :param disabled: If ``True``, disable running all validators. + :type disabled: bool + + .. warning:: + + This function is not thread-safe! + + .. versionadded:: 21.3.0 + """ + set_run_validators(not disabled) + + +def get_disabled(): + """ + Return a bool indicating whether validators are currently disabled or not. + + :return: ``True`` if validators are currently disabled. + :rtype: bool + + .. versionadded:: 21.3.0 + """ + return not get_run_validators() + + +@contextmanager +def disabled(): + """ + Context manager that disables running validators within its context. + + .. warning:: + + This context manager is not thread-safe! + + .. versionadded:: 21.3.0 + """ + set_run_validators(False) + try: + yield + finally: + set_run_validators(True) + + +@attrs(repr=False, slots=True, hash=True) +class _InstanceOfValidator: + type = attrib() + + def __call__(self, inst, attr, value): + """ + We use a callable class to be able to change the ``__repr__``. + """ + if not isinstance(value, self.type): + raise TypeError( + "'{name}' must be {type!r} (got {value!r} that is a " + "{actual!r}).".format( + name=attr.name, + type=self.type, + actual=value.__class__, + value=value, + ), + attr, + self.type, + value, + ) + + def __repr__(self): + return "".format( + type=self.type + ) + + +def instance_of(type): + """ + A validator that raises a `TypeError` if the initializer is called + with a wrong type for this particular attribute (checks are performed using + `isinstance` therefore it's also valid to pass a tuple of types). + + :param type: The type to check for. + :type type: type or tuple of types + + :raises TypeError: With a human readable error message, the attribute + (of type `attrs.Attribute`), the expected type, and the value it + got. + """ + return _InstanceOfValidator(type) + + +@attrs(repr=False, frozen=True, slots=True) +class _MatchesReValidator: + pattern = attrib() + match_func = attrib() + + def __call__(self, inst, attr, value): + """ + We use a callable class to be able to change the ``__repr__``. + """ + if not self.match_func(value): + raise ValueError( + "'{name}' must match regex {pattern!r}" + " ({value!r} doesn't)".format( + name=attr.name, pattern=self.pattern.pattern, value=value + ), + attr, + self.pattern, + value, + ) + + def __repr__(self): + return "".format( + pattern=self.pattern + ) + + +def matches_re(regex, flags=0, func=None): + r""" + A validator that raises `ValueError` if the initializer is called + with a string that doesn't match *regex*. + + :param regex: a regex string or precompiled pattern to match against + :param int flags: flags that will be passed to the underlying re function + (default 0) + :param callable func: which underlying `re` function to call. Valid options + are `re.fullmatch`, `re.search`, and `re.match`; the default ``None`` + means `re.fullmatch`. For performance reasons, the pattern is always + precompiled using `re.compile`. + + .. versionadded:: 19.2.0 + .. versionchanged:: 21.3.0 *regex* can be a pre-compiled pattern. + """ + valid_funcs = (re.fullmatch, None, re.search, re.match) + if func not in valid_funcs: + raise ValueError( + "'func' must be one of {}.".format( + ", ".join( + sorted( + e and e.__name__ or "None" for e in set(valid_funcs) + ) + ) + ) + ) + + if isinstance(regex, Pattern): + if flags: + raise TypeError( + "'flags' can only be used with a string pattern; " + "pass flags to re.compile() instead" + ) + pattern = regex + else: + pattern = re.compile(regex, flags) + + if func is re.match: + match_func = pattern.match + elif func is re.search: + match_func = pattern.search + else: + match_func = pattern.fullmatch + + return _MatchesReValidator(pattern, match_func) + + +@attrs(repr=False, slots=True, hash=True) +class _ProvidesValidator: + interface = attrib() + + def __call__(self, inst, attr, value): + """ + We use a callable class to be able to change the ``__repr__``. + """ + if not self.interface.providedBy(value): + raise TypeError( + "'{name}' must provide {interface!r} which {value!r} " + "doesn't.".format( + name=attr.name, interface=self.interface, value=value + ), + attr, + self.interface, + value, + ) + + def __repr__(self): + return "".format( + interface=self.interface + ) + + +def provides(interface): + """ + A validator that raises a `TypeError` if the initializer is called + with an object that does not provide the requested *interface* (checks are + performed using ``interface.providedBy(value)`` (see `zope.interface + `_). + + :param interface: The interface to check for. + :type interface: ``zope.interface.Interface`` + + :raises TypeError: With a human readable error message, the attribute + (of type `attrs.Attribute`), the expected interface, and the + value it got. + """ + return _ProvidesValidator(interface) + + +@attrs(repr=False, slots=True, hash=True) +class _OptionalValidator: + validator = attrib() + + def __call__(self, inst, attr, value): + if value is None: + return + + self.validator(inst, attr, value) + + def __repr__(self): + return "".format( + what=repr(self.validator) + ) + + +def optional(validator): + """ + A validator that makes an attribute optional. An optional attribute is one + which can be set to ``None`` in addition to satisfying the requirements of + the sub-validator. + + :param validator: A validator (or a list of validators) that is used for + non-``None`` values. + :type validator: callable or `list` of callables. + + .. versionadded:: 15.1.0 + .. versionchanged:: 17.1.0 *validator* can be a list of validators. + """ + if isinstance(validator, list): + return _OptionalValidator(_AndValidator(validator)) + return _OptionalValidator(validator) + + +@attrs(repr=False, slots=True, hash=True) +class _InValidator: + options = attrib() + + def __call__(self, inst, attr, value): + try: + in_options = value in self.options + except TypeError: # e.g. `1 in "abc"` + in_options = False + + if not in_options: + raise ValueError( + "'{name}' must be in {options!r} (got {value!r})".format( + name=attr.name, options=self.options, value=value + ), + attr, + self.options, + value, + ) + + def __repr__(self): + return "".format( + options=self.options + ) + + +def in_(options): + """ + A validator that raises a `ValueError` if the initializer is called + with a value that does not belong in the options provided. The check is + performed using ``value in options``. + + :param options: Allowed options. + :type options: list, tuple, `enum.Enum`, ... + + :raises ValueError: With a human readable error message, the attribute (of + type `attrs.Attribute`), the expected options, and the value it + got. + + .. versionadded:: 17.1.0 + .. versionchanged:: 22.1.0 + The ValueError was incomplete until now and only contained the human + readable error message. Now it contains all the information that has + been promised since 17.1.0. + """ + return _InValidator(options) + + +@attrs(repr=False, slots=False, hash=True) +class _IsCallableValidator: + def __call__(self, inst, attr, value): + """ + We use a callable class to be able to change the ``__repr__``. + """ + if not callable(value): + message = ( + "'{name}' must be callable " + "(got {value!r} that is a {actual!r})." + ) + raise NotCallableError( + msg=message.format( + name=attr.name, value=value, actual=value.__class__ + ), + value=value, + ) + + def __repr__(self): + return "" + + +def is_callable(): + """ + A validator that raises a `attr.exceptions.NotCallableError` if the + initializer is called with a value for this particular attribute + that is not callable. + + .. versionadded:: 19.1.0 + + :raises `attr.exceptions.NotCallableError`: With a human readable error + message containing the attribute (`attrs.Attribute`) name, + and the value it got. + """ + return _IsCallableValidator() + + +@attrs(repr=False, slots=True, hash=True) +class _DeepIterable: + member_validator = attrib(validator=is_callable()) + iterable_validator = attrib( + default=None, validator=optional(is_callable()) + ) + + def __call__(self, inst, attr, value): + """ + We use a callable class to be able to change the ``__repr__``. + """ + if self.iterable_validator is not None: + self.iterable_validator(inst, attr, value) + + for member in value: + self.member_validator(inst, attr, member) + + def __repr__(self): + iterable_identifier = ( + "" + if self.iterable_validator is None + else " {iterable!r}".format(iterable=self.iterable_validator) + ) + return ( + "" + ).format( + iterable_identifier=iterable_identifier, + member=self.member_validator, + ) + + +def deep_iterable(member_validator, iterable_validator=None): + """ + A validator that performs deep validation of an iterable. + + :param member_validator: Validator(s) to apply to iterable members + :param iterable_validator: Validator to apply to iterable itself + (optional) + + .. versionadded:: 19.1.0 + + :raises TypeError: if any sub-validators fail + """ + if isinstance(member_validator, (list, tuple)): + member_validator = and_(*member_validator) + return _DeepIterable(member_validator, iterable_validator) + + +@attrs(repr=False, slots=True, hash=True) +class _DeepMapping: + key_validator = attrib(validator=is_callable()) + value_validator = attrib(validator=is_callable()) + mapping_validator = attrib(default=None, validator=optional(is_callable())) + + def __call__(self, inst, attr, value): + """ + We use a callable class to be able to change the ``__repr__``. + """ + if self.mapping_validator is not None: + self.mapping_validator(inst, attr, value) + + for key in value: + self.key_validator(inst, attr, key) + self.value_validator(inst, attr, value[key]) + + def __repr__(self): + return ( + "" + ).format(key=self.key_validator, value=self.value_validator) + + +def deep_mapping(key_validator, value_validator, mapping_validator=None): + """ + A validator that performs deep validation of a dictionary. + + :param key_validator: Validator to apply to dictionary keys + :param value_validator: Validator to apply to dictionary values + :param mapping_validator: Validator to apply to top-level mapping + attribute (optional) + + .. versionadded:: 19.1.0 + + :raises TypeError: if any sub-validators fail + """ + return _DeepMapping(key_validator, value_validator, mapping_validator) + + +@attrs(repr=False, frozen=True, slots=True) +class _NumberValidator: + bound = attrib() + compare_op = attrib() + compare_func = attrib() + + def __call__(self, inst, attr, value): + """ + We use a callable class to be able to change the ``__repr__``. + """ + if not self.compare_func(value, self.bound): + raise ValueError( + "'{name}' must be {op} {bound}: {value}".format( + name=attr.name, + op=self.compare_op, + bound=self.bound, + value=value, + ) + ) + + def __repr__(self): + return "".format( + op=self.compare_op, bound=self.bound + ) + + +def lt(val): + """ + A validator that raises `ValueError` if the initializer is called + with a number larger or equal to *val*. + + :param val: Exclusive upper bound for values + + .. versionadded:: 21.3.0 + """ + return _NumberValidator(val, "<", operator.lt) + + +def le(val): + """ + A validator that raises `ValueError` if the initializer is called + with a number greater than *val*. + + :param val: Inclusive upper bound for values + + .. versionadded:: 21.3.0 + """ + return _NumberValidator(val, "<=", operator.le) + + +def ge(val): + """ + A validator that raises `ValueError` if the initializer is called + with a number smaller than *val*. + + :param val: Inclusive lower bound for values + + .. versionadded:: 21.3.0 + """ + return _NumberValidator(val, ">=", operator.ge) + + +def gt(val): + """ + A validator that raises `ValueError` if the initializer is called + with a number smaller or equal to *val*. + + :param val: Exclusive lower bound for values + + .. versionadded:: 21.3.0 + """ + return _NumberValidator(val, ">", operator.gt) + + +@attrs(repr=False, frozen=True, slots=True) +class _MaxLengthValidator: + max_length = attrib() + + def __call__(self, inst, attr, value): + """ + We use a callable class to be able to change the ``__repr__``. + """ + if len(value) > self.max_length: + raise ValueError( + "Length of '{name}' must be <= {max}: {len}".format( + name=attr.name, max=self.max_length, len=len(value) + ) + ) + + def __repr__(self): + return "".format(max=self.max_length) + + +def max_len(length): + """ + A validator that raises `ValueError` if the initializer is called + with a string or iterable that is longer than *length*. + + :param int length: Maximum length of the string or iterable + + .. versionadded:: 21.3.0 + """ + return _MaxLengthValidator(length) + + +@attrs(repr=False, frozen=True, slots=True) +class _MinLengthValidator: + min_length = attrib() + + def __call__(self, inst, attr, value): + """ + We use a callable class to be able to change the ``__repr__``. + """ + if len(value) < self.min_length: + raise ValueError( + "Length of '{name}' must be => {min}: {len}".format( + name=attr.name, min=self.min_length, len=len(value) + ) + ) + + def __repr__(self): + return "".format(min=self.min_length) + + +def min_len(length): + """ + A validator that raises `ValueError` if the initializer is called + with a string or iterable that is shorter than *length*. + + :param int length: Minimum length of the string or iterable + + .. versionadded:: 22.1.0 + """ + return _MinLengthValidator(length) diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/attr/validators.pyi b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/attr/validators.pyi new file mode 100644 index 00000000..54b9dba2 --- /dev/null +++ b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/attr/validators.pyi @@ -0,0 +1,80 @@ +from typing import ( + Any, + AnyStr, + Callable, + Container, + ContextManager, + Iterable, + List, + Mapping, + Match, + Optional, + Pattern, + Tuple, + Type, + TypeVar, + Union, + overload, +) + +from . import _ValidatorType +from . import _ValidatorArgType + +_T = TypeVar("_T") +_T1 = TypeVar("_T1") +_T2 = TypeVar("_T2") +_T3 = TypeVar("_T3") +_I = TypeVar("_I", bound=Iterable) +_K = TypeVar("_K") +_V = TypeVar("_V") +_M = TypeVar("_M", bound=Mapping) + +def set_disabled(run: bool) -> None: ... +def get_disabled() -> bool: ... +def disabled() -> ContextManager[None]: ... + +# To be more precise on instance_of use some overloads. +# If there are more than 3 items in the tuple then we fall back to Any +@overload +def instance_of(type: Type[_T]) -> _ValidatorType[_T]: ... +@overload +def instance_of(type: Tuple[Type[_T]]) -> _ValidatorType[_T]: ... +@overload +def instance_of( + type: Tuple[Type[_T1], Type[_T2]] +) -> _ValidatorType[Union[_T1, _T2]]: ... +@overload +def instance_of( + type: Tuple[Type[_T1], Type[_T2], Type[_T3]] +) -> _ValidatorType[Union[_T1, _T2, _T3]]: ... +@overload +def instance_of(type: Tuple[type, ...]) -> _ValidatorType[Any]: ... +def provides(interface: Any) -> _ValidatorType[Any]: ... +def optional( + validator: Union[_ValidatorType[_T], List[_ValidatorType[_T]]] +) -> _ValidatorType[Optional[_T]]: ... +def in_(options: Container[_T]) -> _ValidatorType[_T]: ... +def and_(*validators: _ValidatorType[_T]) -> _ValidatorType[_T]: ... +def matches_re( + regex: Union[Pattern[AnyStr], AnyStr], + flags: int = ..., + func: Optional[ + Callable[[AnyStr, AnyStr, int], Optional[Match[AnyStr]]] + ] = ..., +) -> _ValidatorType[AnyStr]: ... +def deep_iterable( + member_validator: _ValidatorArgType[_T], + iterable_validator: Optional[_ValidatorType[_I]] = ..., +) -> _ValidatorType[_I]: ... +def deep_mapping( + key_validator: _ValidatorType[_K], + value_validator: _ValidatorType[_V], + mapping_validator: Optional[_ValidatorType[_M]] = ..., +) -> _ValidatorType[_M]: ... +def is_callable() -> _ValidatorType[_T]: ... +def lt(val: _T) -> _ValidatorType[_T]: ... +def le(val: _T) -> _ValidatorType[_T]: ... +def ge(val: _T) -> _ValidatorType[_T]: ... +def gt(val: _T) -> _ValidatorType[_T]: ... +def max_len(length: int) -> _ValidatorType[_T]: ... +def min_len(length: int) -> _ValidatorType[_T]: ... diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/attrs-22.1.0.dist-info/AUTHORS.rst b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/attrs-22.1.0.dist-info/AUTHORS.rst new file mode 100644 index 00000000..aa677e81 --- /dev/null +++ b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/attrs-22.1.0.dist-info/AUTHORS.rst @@ -0,0 +1,11 @@ +Credits +======= + +``attrs`` is written and maintained by `Hynek Schlawack `_. + +The development is kindly supported by `Variomedia AG `_. + +A full list of contributors can be found in `GitHub's overview `_. + +It’s the spiritual successor of `characteristic `_ and aspires to fix some of it clunkiness and unfortunate decisions. +Both were inspired by Twisted’s `FancyEqMixin `_ but both are implemented using class decorators because `subclassing is bad for you `_, m’kay? diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/urllib3-1.25.6.dist-info/INSTALLER b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/attrs-22.1.0.dist-info/INSTALLER similarity index 100% rename from Resources/WPy32-3720/python-3.7.2/Lib/site-packages/urllib3-1.25.6.dist-info/INSTALLER rename to Resources/WPy32-3720/python-3.7.2/Lib/site-packages/attrs-22.1.0.dist-info/INSTALLER diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/attrs-22.1.0.dist-info/LICENSE b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/attrs-22.1.0.dist-info/LICENSE new file mode 100644 index 00000000..2bd6453d --- /dev/null +++ b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/attrs-22.1.0.dist-info/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2015 Hynek Schlawack and the attrs contributors + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/attrs-22.1.0.dist-info/METADATA b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/attrs-22.1.0.dist-info/METADATA new file mode 100644 index 00000000..60b6653e --- /dev/null +++ b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/attrs-22.1.0.dist-info/METADATA @@ -0,0 +1,240 @@ +Metadata-Version: 2.1 +Name: attrs +Version: 22.1.0 +Summary: Classes Without Boilerplate +Home-page: https://www.attrs.org/ +Author: Hynek Schlawack +Author-email: hs@ox.cx +Maintainer: Hynek Schlawack +Maintainer-email: hs@ox.cx +License: MIT +Project-URL: Documentation, https://www.attrs.org/ +Project-URL: Changelog, https://www.attrs.org/en/stable/changelog.html +Project-URL: Bug Tracker, https://github.com/python-attrs/attrs/issues +Project-URL: Source Code, https://github.com/python-attrs/attrs +Project-URL: Funding, https://github.com/sponsors/hynek +Project-URL: Tidelift, https://tidelift.com/subscription/pkg/pypi-attrs?utm_source=pypi-attrs&utm_medium=pypi +Project-URL: Ko-fi, https://ko-fi.com/the_hynek +Keywords: class,attribute,boilerplate +Classifier: Development Status :: 5 - Production/Stable +Classifier: Intended Audience :: Developers +Classifier: Natural Language :: English +Classifier: License :: OSI Approved :: MIT License +Classifier: Operating System :: OS Independent +Classifier: Programming Language :: Python +Classifier: Programming Language :: Python :: 3 +Classifier: Programming Language :: Python :: 3.5 +Classifier: Programming Language :: Python :: 3.6 +Classifier: Programming Language :: Python :: 3.7 +Classifier: Programming Language :: Python :: 3.8 +Classifier: Programming Language :: Python :: 3.9 +Classifier: Programming Language :: Python :: 3.10 +Classifier: Programming Language :: Python :: 3.11 +Classifier: Programming Language :: Python :: Implementation :: CPython +Classifier: Programming Language :: Python :: Implementation :: PyPy +Classifier: Topic :: Software Development :: Libraries :: Python Modules +Requires-Python: >=3.5 +Description-Content-Type: text/x-rst +License-File: LICENSE +License-File: AUTHORS.rst +Provides-Extra: dev +Requires-Dist: coverage[toml] (>=5.0.2) ; extra == 'dev' +Requires-Dist: hypothesis ; extra == 'dev' +Requires-Dist: pympler ; extra == 'dev' +Requires-Dist: pytest (>=4.3.0) ; extra == 'dev' +Requires-Dist: mypy (!=0.940,>=0.900) ; extra == 'dev' +Requires-Dist: pytest-mypy-plugins ; extra == 'dev' +Requires-Dist: zope.interface ; extra == 'dev' +Requires-Dist: furo ; extra == 'dev' +Requires-Dist: sphinx ; extra == 'dev' +Requires-Dist: sphinx-notfound-page ; extra == 'dev' +Requires-Dist: pre-commit ; extra == 'dev' +Requires-Dist: cloudpickle ; (platform_python_implementation == "CPython") and extra == 'dev' +Provides-Extra: docs +Requires-Dist: furo ; extra == 'docs' +Requires-Dist: sphinx ; extra == 'docs' +Requires-Dist: zope.interface ; extra == 'docs' +Requires-Dist: sphinx-notfound-page ; extra == 'docs' +Provides-Extra: tests +Requires-Dist: coverage[toml] (>=5.0.2) ; extra == 'tests' +Requires-Dist: hypothesis ; extra == 'tests' +Requires-Dist: pympler ; extra == 'tests' +Requires-Dist: pytest (>=4.3.0) ; extra == 'tests' +Requires-Dist: mypy (!=0.940,>=0.900) ; extra == 'tests' +Requires-Dist: pytest-mypy-plugins ; extra == 'tests' +Requires-Dist: zope.interface ; extra == 'tests' +Requires-Dist: cloudpickle ; (platform_python_implementation == "CPython") and extra == 'tests' +Provides-Extra: tests_no_zope +Requires-Dist: coverage[toml] (>=5.0.2) ; extra == 'tests_no_zope' +Requires-Dist: hypothesis ; extra == 'tests_no_zope' +Requires-Dist: pympler ; extra == 'tests_no_zope' +Requires-Dist: pytest (>=4.3.0) ; extra == 'tests_no_zope' +Requires-Dist: mypy (!=0.940,>=0.900) ; extra == 'tests_no_zope' +Requires-Dist: pytest-mypy-plugins ; extra == 'tests_no_zope' +Requires-Dist: cloudpickle ; (platform_python_implementation == "CPython") and extra == 'tests_no_zope' + + +.. image:: https://www.attrs.org/en/stable/_static/attrs_logo.png + :alt: attrs logo + :align: center + + +``attrs`` is the Python package that will bring back the **joy** of **writing classes** by relieving you from the drudgery of implementing object protocols (aka `dunder methods `_). +`Trusted by NASA `_ for Mars missions since 2020! + +Its main goal is to help you to write **concise** and **correct** software without slowing down your code. + +.. teaser-end + +For that, it gives you a class decorator and a way to declaratively define the attributes on that class: + +.. -code-begin- + +.. code-block:: pycon + + >>> from attrs import asdict, define, make_class, Factory + + >>> @define + ... class SomeClass: + ... a_number: int = 42 + ... list_of_numbers: list[int] = Factory(list) + ... + ... def hard_math(self, another_number): + ... return self.a_number + sum(self.list_of_numbers) * another_number + + + >>> sc = SomeClass(1, [1, 2, 3]) + >>> sc + SomeClass(a_number=1, list_of_numbers=[1, 2, 3]) + + >>> sc.hard_math(3) + 19 + >>> sc == SomeClass(1, [1, 2, 3]) + True + >>> sc != SomeClass(2, [3, 2, 1]) + True + + >>> asdict(sc) + {'a_number': 1, 'list_of_numbers': [1, 2, 3]} + + >>> SomeClass() + SomeClass(a_number=42, list_of_numbers=[]) + + >>> C = make_class("C", ["a", "b"]) + >>> C("foo", "bar") + C(a='foo', b='bar') + + +After *declaring* your attributes, ``attrs`` gives you: + +- a concise and explicit overview of the class's attributes, +- a nice human-readable ``__repr__``, +- equality-checking methods, +- an initializer, +- and much more, + +*without* writing dull boilerplate code again and again and *without* runtime performance penalties. + +**Hate type annotations**!? +No problem! +Types are entirely **optional** with ``attrs``. +Simply assign ``attrs.field()`` to the attributes instead of annotating them with types. + +---- + +This example uses ``attrs``'s modern APIs that have been introduced in version 20.1.0, and the ``attrs`` package import name that has been added in version 21.3.0. +The classic APIs (``@attr.s``, ``attr.ib``, plus their serious-business aliases) and the ``attr`` package import name will remain **indefinitely**. + +Please check out `On The Core API Names `_ for a more in-depth explanation. + + +Data Classes +============ + +On the tin, ``attrs`` might remind you of ``dataclasses`` (and indeed, ``dataclasses`` `are a descendant `_ of ``attrs``). +In practice it does a lot more and is more flexible. +For instance it allows you to define `special handling of NumPy arrays for equality checks `_, or allows more ways to `plug into the initialization process `_. + +For more details, please refer to our `comparison page `_. + +.. -project-information- + +Project Information +=================== + +- **License**: `MIT `_ +- **PyPI**: https://pypi.org/project/attrs/ +- **Source Code**: https://github.com/python-attrs/attrs +- **Documentation**: https://www.attrs.org/ +- **Changelog**: https://www.attrs.org/en/stable/changelog.html +- **Get Help**: please use the ``python-attrs`` tag on `StackOverflow `_ +- **Third-party Extensions**: https://github.com/python-attrs/attrs/wiki/Extensions-to-attrs +- **Supported Python Versions**: 3.5 and later (last 2.7-compatible release is `21.4.0 `_) + +If you'd like to contribute to ``attrs`` you're most welcome and we've written `a little guide `_ to get you started! + + +``attrs`` for Enterprise +------------------------ + +Available as part of the Tidelift Subscription. + +The maintainers of ``attrs`` and thousands of other packages are working with Tidelift to deliver commercial support and maintenance for the open source packages you use to build your applications. +Save time, reduce risk, and improve code health, while paying the maintainers of the exact packages you use. +`Learn more. `_ + + +Release Information +=================== + +22.1.0 (2022-07-28) +------------------- + +Backwards-incompatible Changes +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +- Python 2.7 is not supported anymore. + + Dealing with Python 2.7 tooling has become too difficult for a volunteer-run project. + + We have supported Python 2 more than 2 years after it was officially discontinued and feel that we have paid our dues. + All version up to 21.4.0 from December 2021 remain fully functional, of course. + `#936 `_ +- The deprecated ``cmp`` attribute of ``attrs.Attribute`` has been removed. + This does not affect the *cmp* argument to ``attr.s`` that can be used as a shortcut to set *eq* and *order* at the same time. + `#939 `_ + + +Changes +^^^^^^^ + +- Instantiation of frozen slotted classes is now faster. + `#898 `_ +- If an ``eq`` key is defined, it is also used before hashing the attribute. + `#909 `_ +- Added ``attrs.validators.min_len()``. + `#916 `_ +- ``attrs.validators.deep_iterable()``'s *member_validator* argument now also accepts a list of validators and wraps them in an ``attrs.validators.and_()``. + `#925 `_ +- Added missing type stub re-imports for ``attrs.converters`` and ``attrs.filters``. + `#931 `_ +- Added missing stub for ``attr(s).cmp_using()``. + `#949 `_ +- ``attrs.validators._in()``'s ``ValueError`` is not missing the attribute, expected options, and the value it got anymore. + `#951 `_ +- Python 3.11 is now officially supported. + `#969 `_ + +`Full changelog `_. + +Credits +======= + +``attrs`` is written and maintained by `Hynek Schlawack `_. + +The development is kindly supported by `Variomedia AG `_. + +A full list of contributors can be found in `GitHub's overview `_. + +It’s the spiritual successor of `characteristic `_ and aspires to fix some of it clunkiness and unfortunate decisions. +Both were inspired by Twisted’s `FancyEqMixin `_ but both are implemented using class decorators because `subclassing is bad for you `_, m’kay? diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/attrs-22.1.0.dist-info/RECORD b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/attrs-22.1.0.dist-info/RECORD new file mode 100644 index 00000000..098469fc --- /dev/null +++ b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/attrs-22.1.0.dist-info/RECORD @@ -0,0 +1,56 @@ +attr/__init__.py,sha256=KZjj88xCd_tH-W59HR1EvHiYAUi4Zd1dzOxx8P77jeI,1602 +attr/__init__.pyi,sha256=t-1r-I1VnyxFrqic__QxIk1HUc3ag53L2b8lv0xDZTw,15137 +attr/__pycache__/__init__.cpython-37.pyc,, +attr/__pycache__/_cmp.cpython-37.pyc,, +attr/__pycache__/_compat.cpython-37.pyc,, +attr/__pycache__/_config.cpython-37.pyc,, +attr/__pycache__/_funcs.cpython-37.pyc,, +attr/__pycache__/_make.cpython-37.pyc,, +attr/__pycache__/_next_gen.cpython-37.pyc,, +attr/__pycache__/_version_info.cpython-37.pyc,, +attr/__pycache__/converters.cpython-37.pyc,, +attr/__pycache__/exceptions.cpython-37.pyc,, +attr/__pycache__/filters.cpython-37.pyc,, +attr/__pycache__/setters.cpython-37.pyc,, +attr/__pycache__/validators.cpython-37.pyc,, +attr/_cmp.py,sha256=Mmqj-6w71g_vx0TTLLkU4pbmv28qz_FyBGcUb1HX9ZE,4102 +attr/_cmp.pyi,sha256=cSlVvIH4As2NlDIoLglPEbSrBMWVVTpwExVDDBH6pn8,357 +attr/_compat.py,sha256=Qr9kZOu95Og7joPaQiXoPb54epKqxNU39Xu0u4QVGZI,5568 +attr/_config.py,sha256=5W8lgRePuIOWu1ZuqF1899e2CmXGc95-ipwTpF1cEU4,826 +attr/_funcs.py,sha256=XTFKZtd5zxsUvWocBw7VAswTxH-nFHk0H8gJ2JQkxD4,14645 +attr/_make.py,sha256=Srxbhb8kB17T6nP9e_dgcXY72zda9xfL5uJzva6LExY,97569 +attr/_next_gen.py,sha256=N0Gb5WdBHfcfQhcUsLAc_2ZYzl0JtAX1NOHuDgvkecE,5882 +attr/_version_info.py,sha256=exSqb3b5E-fMSsgZAlEw9XcLpEgobPORCZpcaEglAM4,2121 +attr/_version_info.pyi,sha256=x_M3L3WuB7r_ULXAWjx959udKQ4HLB8l-hsc1FDGNvk,209 +attr/converters.py,sha256=TWCfmCAxk8s2tgTSYnyQv9MRDPf1pk8Rj16KO_Xqe1c,3610 +attr/converters.pyi,sha256=MQo7iEzPNVoFpKqD30sVwgVpdNoIeSCF2nsXvoxLZ-Y,416 +attr/exceptions.py,sha256=ZGEMLv0CDY1TOtj49OF84myejOn-LCCXAKGIKalKkVU,1915 +attr/exceptions.pyi,sha256=zZq8bCUnKAy9mDtBEw42ZhPhAUIHoTKedDQInJD883M,539 +attr/filters.py,sha256=aZep54h8-4ZYV5lmZ3Dx2mqeQH4cMx6tuCmCylLNbEU,1038 +attr/filters.pyi,sha256=_Sm80jGySETX_Clzdkon5NHVjQWRl3Y3liQKZX1czXc,215 +attr/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +attr/setters.py,sha256=pbCZQ-pE6ZxjDqZfWWUhUFefXtpekIU4qS_YDMLPQ50,1400 +attr/setters.pyi,sha256=7dM10rqpQVDW0y-iJUnq8rabdO5Wx2Sbo5LwNa0IXl0,573 +attr/validators.py,sha256=cpOHMNSt02ApbTQtQAwBTMeWZqp0u_sx-e3xH-jTyR4,16793 +attr/validators.pyi,sha256=6ngbvnWnFSkbf5J2dK86pq2xpEtrwzWTKfJ4aUvSIlk,2355 +attrs-22.1.0.dist-info/AUTHORS.rst,sha256=jau5p7JMPbBJeCCpGBWsRj8zpxUVAhpyoHFJRfjM888,743 +attrs-22.1.0.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +attrs-22.1.0.dist-info/LICENSE,sha256=iCEVyV38KvHutnFPjsbVy8q_Znyv-HKfQkINpj9xTp8,1109 +attrs-22.1.0.dist-info/METADATA,sha256=vwSMK_BbEgVHrgFWpj3iW0PISTMPHzi6qham9jg7LtA,11015 +attrs-22.1.0.dist-info/RECORD,, +attrs-22.1.0.dist-info/WHEEL,sha256=z9j0xAa_JmUKMpmz72K0ZGALSM_n-wQVmGbleXx2VHg,110 +attrs-22.1.0.dist-info/top_level.txt,sha256=AGbmKnOtYpdkLRsDRQVSBIwfL32pAQ6BSo1mt-BxI7M,11 +attrs/__init__.py,sha256=CeyxLGVViAEKKsLOLaif8vF3vs1a28vsrRVLv7eMEgM,1109 +attrs/__init__.pyi,sha256=vuFxNbulP9Q7hfpO6Lb5A-_0mbEJOiwYyefjzXMqVfs,2100 +attrs/__pycache__/__init__.cpython-37.pyc,, +attrs/__pycache__/converters.cpython-37.pyc,, +attrs/__pycache__/exceptions.cpython-37.pyc,, +attrs/__pycache__/filters.cpython-37.pyc,, +attrs/__pycache__/setters.cpython-37.pyc,, +attrs/__pycache__/validators.cpython-37.pyc,, +attrs/converters.py,sha256=fCBEdlYWcmI3sCnpUk2pz22GYtXzqTkp6NeOpdI64PY,70 +attrs/exceptions.py,sha256=SlDli6AY77f6ny-H7oy98OkQjsrw-D_supEuErIVYkE,70 +attrs/filters.py,sha256=dc_dNey29kH6KLU1mT2Dakq7tZ3kBfzEGwzOmDzw1F8,67 +attrs/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +attrs/setters.py,sha256=oKw51C72Hh45wTwYvDHJP9kbicxiMhMR4Y5GvdpKdHQ,67 +attrs/validators.py,sha256=4ag1SyVD2Hm3PYKiNG_NOtR_e7f81Hr6GiNl4YvXo4Q,70 diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/certifi-2019.9.11.dist-info/WHEEL b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/attrs-22.1.0.dist-info/WHEEL similarity index 69% rename from Resources/WPy32-3720/python-3.7.2/Lib/site-packages/certifi-2019.9.11.dist-info/WHEEL rename to Resources/WPy32-3720/python-3.7.2/Lib/site-packages/attrs-22.1.0.dist-info/WHEEL index 7bf9daa1..0b18a281 100644 --- a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/certifi-2019.9.11.dist-info/WHEEL +++ b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/attrs-22.1.0.dist-info/WHEEL @@ -1,5 +1,5 @@ Wheel-Version: 1.0 -Generator: bdist_wheel (0.30.0.a0) +Generator: bdist_wheel (0.37.1) Root-Is-Purelib: true Tag: py2-none-any Tag: py3-none-any diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/attrs-22.1.0.dist-info/top_level.txt b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/attrs-22.1.0.dist-info/top_level.txt new file mode 100644 index 00000000..eca8ba9f --- /dev/null +++ b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/attrs-22.1.0.dist-info/top_level.txt @@ -0,0 +1,2 @@ +attr +attrs diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/attrs/__init__.py b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/attrs/__init__.py new file mode 100644 index 00000000..a704b8b5 --- /dev/null +++ b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/attrs/__init__.py @@ -0,0 +1,70 @@ +# SPDX-License-Identifier: MIT + +from attr import ( + NOTHING, + Attribute, + Factory, + __author__, + __copyright__, + __description__, + __doc__, + __email__, + __license__, + __title__, + __url__, + __version__, + __version_info__, + assoc, + cmp_using, + define, + evolve, + field, + fields, + fields_dict, + frozen, + has, + make_class, + mutable, + resolve_types, + validate, +) +from attr._next_gen import asdict, astuple + +from . import converters, exceptions, filters, setters, validators + + +__all__ = [ + "__author__", + "__copyright__", + "__description__", + "__doc__", + "__email__", + "__license__", + "__title__", + "__url__", + "__version__", + "__version_info__", + "asdict", + "assoc", + "astuple", + "Attribute", + "cmp_using", + "converters", + "define", + "evolve", + "exceptions", + "Factory", + "field", + "fields_dict", + "fields", + "filters", + "frozen", + "has", + "make_class", + "mutable", + "NOTHING", + "resolve_types", + "setters", + "validate", + "validators", +] diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/attrs/__init__.pyi b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/attrs/__init__.pyi new file mode 100644 index 00000000..fc44de46 --- /dev/null +++ b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/attrs/__init__.pyi @@ -0,0 +1,66 @@ +from typing import ( + Any, + Callable, + Dict, + Mapping, + Optional, + Sequence, + Tuple, + Type, +) + +# Because we need to type our own stuff, we have to make everything from +# attr explicitly public too. +from attr import __author__ as __author__ +from attr import __copyright__ as __copyright__ +from attr import __description__ as __description__ +from attr import __email__ as __email__ +from attr import __license__ as __license__ +from attr import __title__ as __title__ +from attr import __url__ as __url__ +from attr import __version__ as __version__ +from attr import __version_info__ as __version_info__ +from attr import _FilterType +from attr import assoc as assoc +from attr import Attribute as Attribute +from attr import cmp_using as cmp_using +from attr import converters as converters +from attr import define as define +from attr import evolve as evolve +from attr import exceptions as exceptions +from attr import Factory as Factory +from attr import field as field +from attr import fields as fields +from attr import fields_dict as fields_dict +from attr import filters as filters +from attr import frozen as frozen +from attr import has as has +from attr import make_class as make_class +from attr import mutable as mutable +from attr import NOTHING as NOTHING +from attr import resolve_types as resolve_types +from attr import setters as setters +from attr import validate as validate +from attr import validators as validators + +# TODO: see definition of attr.asdict/astuple +def asdict( + inst: Any, + recurse: bool = ..., + filter: Optional[_FilterType[Any]] = ..., + dict_factory: Type[Mapping[Any, Any]] = ..., + retain_collection_types: bool = ..., + value_serializer: Optional[ + Callable[[type, Attribute[Any], Any], Any] + ] = ..., + tuple_keys: bool = ..., +) -> Dict[str, Any]: ... + +# TODO: add support for returning NamedTuple from the mypy plugin +def astuple( + inst: Any, + recurse: bool = ..., + filter: Optional[_FilterType[Any]] = ..., + tuple_factory: Type[Sequence[Any]] = ..., + retain_collection_types: bool = ..., +) -> Tuple[Any, ...]: ... diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/attrs/converters.py b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/attrs/converters.py new file mode 100644 index 00000000..edfa8d3c --- /dev/null +++ b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/attrs/converters.py @@ -0,0 +1,3 @@ +# SPDX-License-Identifier: MIT + +from attr.converters import * # noqa diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/attrs/exceptions.py b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/attrs/exceptions.py new file mode 100644 index 00000000..bd9efed2 --- /dev/null +++ b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/attrs/exceptions.py @@ -0,0 +1,3 @@ +# SPDX-License-Identifier: MIT + +from attr.exceptions import * # noqa diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/attrs/filters.py b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/attrs/filters.py new file mode 100644 index 00000000..52959005 --- /dev/null +++ b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/attrs/filters.py @@ -0,0 +1,3 @@ +# SPDX-License-Identifier: MIT + +from attr.filters import * # noqa diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/attrs/py.typed b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/attrs/py.typed new file mode 100644 index 00000000..e69de29b diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/attrs/setters.py b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/attrs/setters.py new file mode 100644 index 00000000..9b507708 --- /dev/null +++ b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/attrs/setters.py @@ -0,0 +1,3 @@ +# SPDX-License-Identifier: MIT + +from attr.setters import * # noqa diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/attrs/validators.py b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/attrs/validators.py new file mode 100644 index 00000000..ab2c9b30 --- /dev/null +++ b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/attrs/validators.py @@ -0,0 +1,3 @@ +# SPDX-License-Identifier: MIT + +from attr.validators import * # noqa diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/certifi-2019.9.11.dist-info/DESCRIPTION.rst b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/certifi-2019.9.11.dist-info/DESCRIPTION.rst deleted file mode 100644 index 0b0953d8..00000000 --- a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/certifi-2019.9.11.dist-info/DESCRIPTION.rst +++ /dev/null @@ -1,50 +0,0 @@ -Certifi: Python SSL Certificates -================================ - -`Certifi`_ is a carefully curated collection of Root Certificates for -validating the trustworthiness of SSL certificates while verifying the identity -of TLS hosts. It has been extracted from the `Requests`_ project. - -Installation ------------- - -``certifi`` is available on PyPI. Simply install it with ``pip``:: - - $ pip install certifi - -Usage ------ - -To reference the installed certificate authority (CA) bundle, you can use the -built-in function:: - - >>> import certifi - - >>> certifi.where() - '/usr/local/lib/python2.7/site-packages/certifi/cacert.pem' - -Or from the command line:: - - $ python -m certifi - /usr/local/lib/python2.7/site-packages/certifi/cacert.pem - -Enjoy! - -1024-bit Root Certificates -~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Browsers and certificate authorities have concluded that 1024-bit keys are -unacceptably weak for certificates, particularly root certificates. For this -reason, Mozilla has removed any weak (i.e. 1024-bit key) certificate from its -bundle, replacing it with an equivalent strong (i.e. 2048-bit or greater key) -certificate from the same CA. Because Mozilla removed these certificates from -its bundle, ``certifi`` removed them as well. - -In previous versions, ``certifi`` provided the ``certifi.old_where()`` function -to intentionally re-add the 1024-bit roots back into your bundle. This was not -recommended in production and therefore was removed at the end of 2018. - -.. _`Certifi`: https://certifi.io/en/latest/ -.. _`Requests`: http://docs.python-requests.org/en/latest/ - - diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/certifi-2019.9.11.dist-info/RECORD b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/certifi-2019.9.11.dist-info/RECORD deleted file mode 100644 index 4cee9228..00000000 --- a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/certifi-2019.9.11.dist-info/RECORD +++ /dev/null @@ -1,14 +0,0 @@ -certifi-2019.9.11.dist-info/DESCRIPTION.rst,sha256=aLNHONztn2ZiBpSTivVFy6EDIWmuNYSsEQwx4NWbvB4,1580 -certifi-2019.9.11.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 -certifi-2019.9.11.dist-info/METADATA,sha256=M0Gen7rhgJKIvggZuENXqcZexg74gXdjGC679bMeoDw,2522 -certifi-2019.9.11.dist-info/RECORD,, -certifi-2019.9.11.dist-info/WHEEL,sha256=5wvfB7GvgZAbKBSE9uX9Zbi6LCL-_KgezgHblXhCRnM,113 -certifi-2019.9.11.dist-info/metadata.json,sha256=NppG2TtVr6va5nwyG9pxGhktdvudS-IfpTkaQaWKlBE,1022 -certifi-2019.9.11.dist-info/top_level.txt,sha256=KMu4vUCfsjLrkPbSNdgdekS-pVJzBAJFO__nI8NF6-U,8 -certifi/__init__.py,sha256=WFoavXHhpX-BZ5kbvyinZTbhLsqPJypLKIZu29nUsQg,52 -certifi/__main__.py,sha256=FiOYt1Fltst7wk9DRa6GCoBr8qBUxlNQu_MKJf04E6s,41 -certifi/__pycache__/__init__.cpython-37.pyc,, -certifi/__pycache__/__main__.cpython-37.pyc,, -certifi/__pycache__/core.cpython-37.pyc,, -certifi/cacert.pem,sha256=cVC1b0T-OcQzgdcRql2yMxT7O08O6pcJHnuO9nbLLn0,278533 -certifi/core.py,sha256=EuFc2BsToG5O1-qsx4BSjQ1r1-7WRtH87b1WflZOWhI,218 diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/certifi-2019.9.11.dist-info/metadata.json b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/certifi-2019.9.11.dist-info/metadata.json deleted file mode 100644 index 7f155f55..00000000 --- a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/certifi-2019.9.11.dist-info/metadata.json +++ /dev/null @@ -1 +0,0 @@ -{"classifiers": ["Development Status :: 5 - Production/Stable", "Intended Audience :: Developers", "License :: OSI Approved :: Mozilla Public License 2.0 (MPL 2.0)", "Natural Language :: English", "Programming Language :: Python", "Programming Language :: Python :: 2", "Programming Language :: Python :: 2.6", "Programming Language :: Python :: 2.7", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.3", "Programming Language :: Python :: 3.4", "Programming Language :: Python :: 3.5", "Programming Language :: Python :: 3.6", "Programming Language :: Python :: 3.7"], "extensions": {"python.details": {"contacts": [{"email": "me@kennethreitz.com", "name": "Kenneth Reitz", "role": "author"}], "document_names": {"description": "DESCRIPTION.rst"}, "project_urls": {"Home": "https://certifi.io/"}}}, "generator": "bdist_wheel (0.30.0.a0)", "license": "MPL-2.0", "metadata_version": "2.0", "name": "certifi", "summary": "Python package for providing Mozilla's CA Bundle.", "version": "2019.9.11"} \ No newline at end of file diff --git a/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA-1.2.13.dist-info/INSTALLER b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/certifi-2022.6.15.dist-info/INSTALLER similarity index 100% rename from Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA-1.2.13.dist-info/INSTALLER rename to Resources/WPy32-3720/python-3.7.2/Lib/site-packages/certifi-2022.6.15.dist-info/INSTALLER diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/certifi-2022.6.15.dist-info/LICENSE b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/certifi-2022.6.15.dist-info/LICENSE new file mode 100644 index 00000000..c2fda9a2 --- /dev/null +++ b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/certifi-2022.6.15.dist-info/LICENSE @@ -0,0 +1,21 @@ +This package contains a modified version of ca-bundle.crt: + +ca-bundle.crt -- Bundle of CA Root Certificates + +Certificate data from Mozilla as of: Thu Nov 3 19:04:19 2011# +This is a bundle of X.509 certificates of public Certificate Authorities +(CA). These were automatically extracted from Mozilla's root certificates +file (certdata.txt). This file can be found in the mozilla source tree: +http://mxr.mozilla.org/mozilla/source/security/nss/lib/ckfw/builtins/certdata.txt?raw=1# +It contains the certificates in PEM format and therefore +can be directly used with curl / libcurl / php_curl, or with +an Apache+mod_ssl webserver for SSL client authentication. +Just configure this file as the SSLCACertificateFile.# + +***** BEGIN LICENSE BLOCK ***** +This Source Code Form is subject to the terms of the Mozilla Public License, +v. 2.0. If a copy of the MPL was not distributed with this file, You can obtain +one at http://mozilla.org/MPL/2.0/. + +***** END LICENSE BLOCK ***** +@(#) $RCSfile: certdata.txt,v $ $Revision: 1.80 $ $Date: 2011/11/03 15:11:58 $ diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/certifi-2019.9.11.dist-info/METADATA b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/certifi-2022.6.15.dist-info/METADATA similarity index 66% rename from Resources/WPy32-3720/python-3.7.2/Lib/site-packages/certifi-2019.9.11.dist-info/METADATA rename to Resources/WPy32-3720/python-3.7.2/Lib/site-packages/certifi-2022.6.15.dist-info/METADATA index 6ecc70c0..6f8de5dc 100644 --- a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/certifi-2019.9.11.dist-info/METADATA +++ b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/certifi-2022.6.15.dist-info/METADATA @@ -1,31 +1,31 @@ -Metadata-Version: 2.0 +Metadata-Version: 2.1 Name: certifi -Version: 2019.9.11 +Version: 2022.6.15 Summary: Python package for providing Mozilla's CA Bundle. -Home-page: https://certifi.io/ +Home-page: https://github.com/certifi/python-certifi Author: Kenneth Reitz Author-email: me@kennethreitz.com License: MPL-2.0 +Project-URL: Source, https://github.com/certifi/python-certifi Platform: UNKNOWN Classifier: Development Status :: 5 - Production/Stable Classifier: Intended Audience :: Developers Classifier: License :: OSI Approved :: Mozilla Public License 2.0 (MPL 2.0) Classifier: Natural Language :: English Classifier: Programming Language :: Python -Classifier: Programming Language :: Python :: 2 -Classifier: Programming Language :: Python :: 2.6 -Classifier: Programming Language :: Python :: 2.7 Classifier: Programming Language :: Python :: 3 -Classifier: Programming Language :: Python :: 3.3 -Classifier: Programming Language :: Python :: 3.4 -Classifier: Programming Language :: Python :: 3.5 Classifier: Programming Language :: Python :: 3.6 Classifier: Programming Language :: Python :: 3.7 +Classifier: Programming Language :: Python :: 3.8 +Classifier: Programming Language :: Python :: 3.9 +Classifier: Programming Language :: Python :: 3.10 +Requires-Python: >=3.6 +License-File: LICENSE Certifi: Python SSL Certificates ================================ -`Certifi`_ is a carefully curated collection of Root Certificates for +Certifi provides Mozilla's carefully curated collection of Root Certificates for validating the trustworthiness of SSL certificates while verifying the identity of TLS hosts. It has been extracted from the `Requests`_ project. @@ -45,12 +45,12 @@ built-in function:: >>> import certifi >>> certifi.where() - '/usr/local/lib/python2.7/site-packages/certifi/cacert.pem' + '/usr/local/lib/python3.7/site-packages/certifi/cacert.pem' Or from the command line:: $ python -m certifi - /usr/local/lib/python2.7/site-packages/certifi/cacert.pem + /usr/local/lib/python3.7/site-packages/certifi/cacert.pem Enjoy! @@ -68,7 +68,14 @@ In previous versions, ``certifi`` provided the ``certifi.old_where()`` function to intentionally re-add the 1024-bit roots back into your bundle. This was not recommended in production and therefore was removed at the end of 2018. -.. _`Certifi`: https://certifi.io/en/latest/ -.. _`Requests`: http://docs.python-requests.org/en/latest/ +.. _`Requests`: https://requests.readthedocs.io/en/master/ + +Addition/Removal of Certificates +-------------------------------- + +Certifi does not support any addition/removal or other modification of the +CA trust store content. This project is intended to provide a reliable and +highly portable root of trust to python deployments. Look to upstream projects +for methods to use alternate trust. diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/certifi-2022.6.15.dist-info/RECORD b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/certifi-2022.6.15.dist-info/RECORD new file mode 100644 index 00000000..6f61b5c1 --- /dev/null +++ b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/certifi-2022.6.15.dist-info/RECORD @@ -0,0 +1,14 @@ +certifi-2022.6.15.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +certifi-2022.6.15.dist-info/LICENSE,sha256=vp2C82ES-Hp_HXTs1Ih-FGe7roh4qEAEoAEXseR1o-I,1049 +certifi-2022.6.15.dist-info/METADATA,sha256=1sLjV7SjXkcGhJr631JUqCLCDnqgTyFoFe-tRLxakTE,2804 +certifi-2022.6.15.dist-info/RECORD,, +certifi-2022.6.15.dist-info/WHEEL,sha256=ewwEueio1C2XeHTvT17n8dZUJgOvyCWCt0WVNLClP9o,92 +certifi-2022.6.15.dist-info/top_level.txt,sha256=KMu4vUCfsjLrkPbSNdgdekS-pVJzBAJFO__nI8NF6-U,8 +certifi/__init__.py,sha256=SuZ3iYmzdRyUv-PiaZkquUgXtWZ16ICUKgymlEBspx0,94 +certifi/__main__.py,sha256=xBBoj905TUWBLRGANOcf7oi6e-3dMP4cEoG9OyMs11g,243 +certifi/__pycache__/__init__.cpython-37.pyc,, +certifi/__pycache__/__main__.cpython-37.pyc,, +certifi/__pycache__/core.cpython-37.pyc,, +certifi/cacert.pem,sha256=pZ_eiDoO-ddKudrQCWieABc9KFlbV0FsmLLugygMbkw,285222 +certifi/core.py,sha256=G5LqCBr4o8bozzzlYBE8nsd_ziB6XcxJiuMV4llFeYY,2515 +certifi/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/certifi-2022.6.15.dist-info/WHEEL b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/certifi-2022.6.15.dist-info/WHEEL new file mode 100644 index 00000000..5bad85fd --- /dev/null +++ b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/certifi-2022.6.15.dist-info/WHEEL @@ -0,0 +1,5 @@ +Wheel-Version: 1.0 +Generator: bdist_wheel (0.37.0) +Root-Is-Purelib: true +Tag: py3-none-any + diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/certifi-2019.9.11.dist-info/top_level.txt b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/certifi-2022.6.15.dist-info/top_level.txt similarity index 100% rename from Resources/WPy32-3720/python-3.7.2/Lib/site-packages/certifi-2019.9.11.dist-info/top_level.txt rename to Resources/WPy32-3720/python-3.7.2/Lib/site-packages/certifi-2022.6.15.dist-info/top_level.txt diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/certifi/__init__.py b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/certifi/__init__.py index 8e358e4c..bdeb06be 100644 --- a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/certifi/__init__.py +++ b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/certifi/__init__.py @@ -1,3 +1,4 @@ -from .core import where +from .core import contents, where -__version__ = "2019.09.11" +__all__ = ["contents", "where"] +__version__ = "2022.06.15" diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/certifi/__main__.py b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/certifi/__main__.py index 5f1da0dd..8945b5da 100644 --- a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/certifi/__main__.py +++ b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/certifi/__main__.py @@ -1,2 +1,12 @@ -from certifi import where -print(where()) +import argparse + +from certifi import contents, where + +parser = argparse.ArgumentParser() +parser.add_argument("-c", "--contents", action="store_true") +args = parser.parse_args() + +if args.contents: + print(contents()) +else: + print(where()) diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/certifi/cacert.pem b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/certifi/cacert.pem index 70fa91f6..ee9be4cb 100644 --- a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/certifi/cacert.pem +++ b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/certifi/cacert.pem @@ -28,68 +28,6 @@ DKqC5JlR3XC321Y9YeRq4VzW9v493kHMB65jUr9TU/Qr6cf9tveCX4XSQRjbgbME HMUfpIBvFSDJ3gyICh3WZlXi/EjJKSZp4A== -----END CERTIFICATE----- -# Issuer: CN=GlobalSign O=GlobalSign OU=GlobalSign Root CA - R2 -# Subject: CN=GlobalSign O=GlobalSign OU=GlobalSign Root CA - R2 -# Label: "GlobalSign Root CA - R2" -# Serial: 4835703278459682885658125 -# MD5 Fingerprint: 94:14:77:7e:3e:5e:fd:8f:30:bd:41:b0:cf:e7:d0:30 -# SHA1 Fingerprint: 75:e0:ab:b6:13:85:12:27:1c:04:f8:5f:dd:de:38:e4:b7:24:2e:fe -# SHA256 Fingerprint: ca:42:dd:41:74:5f:d0:b8:1e:b9:02:36:2c:f9:d8:bf:71:9d:a1:bd:1b:1e:fc:94:6f:5b:4c:99:f4:2c:1b:9e ------BEGIN CERTIFICATE----- -MIIDujCCAqKgAwIBAgILBAAAAAABD4Ym5g0wDQYJKoZIhvcNAQEFBQAwTDEgMB4G -A1UECxMXR2xvYmFsU2lnbiBSb290IENBIC0gUjIxEzARBgNVBAoTCkdsb2JhbFNp -Z24xEzARBgNVBAMTCkdsb2JhbFNpZ24wHhcNMDYxMjE1MDgwMDAwWhcNMjExMjE1 -MDgwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxTaWduIFJvb3QgQ0EgLSBSMjETMBEG -A1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2lnbjCCASIwDQYJKoZI -hvcNAQEBBQADggEPADCCAQoCggEBAKbPJA6+Lm8omUVCxKs+IVSbC9N/hHD6ErPL -v4dfxn+G07IwXNb9rfF73OX4YJYJkhD10FPe+3t+c4isUoh7SqbKSaZeqKeMWhG8 -eoLrvozps6yWJQeXSpkqBy+0Hne/ig+1AnwblrjFuTosvNYSuetZfeLQBoZfXklq -tTleiDTsvHgMCJiEbKjNS7SgfQx5TfC4LcshytVsW33hoCmEofnTlEnLJGKRILzd -C9XZzPnqJworc5HGnRusyMvo4KD0L5CLTfuwNhv2GXqF4G3yYROIXJ/gkwpRl4pa -zq+r1feqCapgvdzZX99yqWATXgAByUr6P6TqBwMhAo6CygPCm48CAwEAAaOBnDCB -mTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUm+IH -V2ccHsBqBt5ZtJot39wZhi4wNgYDVR0fBC8wLTAroCmgJ4YlaHR0cDovL2NybC5n -bG9iYWxzaWduLm5ldC9yb290LXIyLmNybDAfBgNVHSMEGDAWgBSb4gdXZxwewGoG -3lm0mi3f3BmGLjANBgkqhkiG9w0BAQUFAAOCAQEAmYFThxxol4aR7OBKuEQLq4Gs -J0/WwbgcQ3izDJr86iw8bmEbTUsp9Z8FHSbBuOmDAGJFtqkIk7mpM0sYmsL4h4hO -291xNBrBVNpGP+DTKqttVCL1OmLNIG+6KYnX3ZHu01yiPqFbQfXf5WRDLenVOavS -ot+3i9DAgBkcRcAtjOj4LaR0VknFBbVPFd5uRHg5h6h+u/N5GJG79G+dwfCMNYxd -AfvDbbnvRG15RjF+Cv6pgsH/76tuIMRQyV+dTZsXjAzlAcmgQWpzU/qlULRuJQ/7 -TBj0/VLZjmmx6BEP3ojY+x1J96relc8geMJgEtslQIxq/H5COEBkEveegeGTLg== ------END CERTIFICATE----- - -# Issuer: CN=VeriSign Class 3 Public Primary Certification Authority - G3 O=VeriSign, Inc. OU=VeriSign Trust Network/(c) 1999 VeriSign, Inc. - For authorized use only -# Subject: CN=VeriSign Class 3 Public Primary Certification Authority - G3 O=VeriSign, Inc. OU=VeriSign Trust Network/(c) 1999 VeriSign, Inc. - For authorized use only -# Label: "Verisign Class 3 Public Primary Certification Authority - G3" -# Serial: 206684696279472310254277870180966723415 -# MD5 Fingerprint: cd:68:b6:a7:c7:c4:ce:75:e0:1d:4f:57:44:61:92:09 -# SHA1 Fingerprint: 13:2d:0d:45:53:4b:69:97:cd:b2:d5:c3:39:e2:55:76:60:9b:5c:c6 -# SHA256 Fingerprint: eb:04:cf:5e:b1:f3:9a:fa:76:2f:2b:b1:20:f2:96:cb:a5:20:c1:b9:7d:b1:58:95:65:b8:1c:b9:a1:7b:72:44 ------BEGIN CERTIFICATE----- -MIIEGjCCAwICEQCbfgZJoz5iudXukEhxKe9XMA0GCSqGSIb3DQEBBQUAMIHKMQsw -CQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZl -cmlTaWduIFRydXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWdu -LCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlT -aWduIENsYXNzIDMgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3Jp -dHkgLSBHMzAeFw05OTEwMDEwMDAwMDBaFw0zNjA3MTYyMzU5NTlaMIHKMQswCQYD -VQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlT -aWduIFRydXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWduLCBJ -bmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlTaWdu -IENsYXNzIDMgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkg -LSBHMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMu6nFL8eB8aHm8b -N3O9+MlrlBIwT/A2R/XQkQr1F8ilYcEWQE37imGQ5XYgwREGfassbqb1EUGO+i2t -KmFZpGcmTNDovFJbcCAEWNF6yaRpvIMXZK0Fi7zQWM6NjPXr8EJJC52XJ2cybuGu -kxUccLwgTS8Y3pKI6GyFVxEa6X7jJhFUokWWVYPKMIno3Nij7SqAP395ZVc+FSBm -CC+Vk7+qRy+oRpfwEuL+wgorUeZ25rdGt+INpsyow0xZVYnm6FNcHOqd8GIWC6fJ -Xwzw3sJ2zq/3avL6QaaiMxTJ5Xpj055iN9WFZZ4O5lMkdBteHRJTW8cs54NJOxWu -imi5V5cCAwEAATANBgkqhkiG9w0BAQUFAAOCAQEAERSWwauSCPc/L8my/uRan2Te -2yFPhpk0djZX3dAVL8WtfxUfN2JzPtTnX84XA9s1+ivbrmAJXx5fj267Cz3qWhMe -DGBvtcC1IyIuBwvLqXTLR7sdwdela8wv0kL9Sd2nic9TutoAWii/gt/4uhMdUIaC -/Y4wjylGsB49Ndo4YhYYSq3mtlFs3q9i6wHQHiT+eo8SGhJouPtmmRQURVyu565p -F4ErWjfJXir0xuKhXFSbplQAz/DxwceYMBo7Nhbbo27q/a2ywtrvAkcTisDxszGt -TxzhT5yvDwyd93gN2PQ1VoDat20Xj50egWTh/sVFuq1ruQp6Tk9LhO5L8X3dEQ== ------END CERTIFICATE----- - # Issuer: CN=Entrust.net Certification Authority (2048) O=Entrust.net OU=www.entrust.net/CPS_2048 incorp. by ref. (limits liab.)/(c) 1999 Entrust.net Limited # Subject: CN=Entrust.net Certification Authority (2048) O=Entrust.net OU=www.entrust.net/CPS_2048 incorp. by ref. (limits liab.)/(c) 1999 Entrust.net Limited # Label: "Entrust.net Premium 2048 Secure Server CA" @@ -152,39 +90,6 @@ ksLi4xaNmjICq44Y3ekQEe5+NauQrz4wlHrQMz2nZQ/1/I6eYs9HRCwBXbsdtTLS R9I4LtD+gdwyah617jzV/OeBHRnDJELqYzmp -----END CERTIFICATE----- -# Issuer: CN=AddTrust External CA Root O=AddTrust AB OU=AddTrust External TTP Network -# Subject: CN=AddTrust External CA Root O=AddTrust AB OU=AddTrust External TTP Network -# Label: "AddTrust External Root" -# Serial: 1 -# MD5 Fingerprint: 1d:35:54:04:85:78:b0:3f:42:42:4d:bf:20:73:0a:3f -# SHA1 Fingerprint: 02:fa:f3:e2:91:43:54:68:60:78:57:69:4d:f5:e4:5b:68:85:18:68 -# SHA256 Fingerprint: 68:7f:a4:51:38:22:78:ff:f0:c8:b1:1f:8d:43:d5:76:67:1c:6e:b2:bc:ea:b4:13:fb:83:d9:65:d0:6d:2f:f2 ------BEGIN CERTIFICATE----- -MIIENjCCAx6gAwIBAgIBATANBgkqhkiG9w0BAQUFADBvMQswCQYDVQQGEwJTRTEU -MBIGA1UEChMLQWRkVHJ1c3QgQUIxJjAkBgNVBAsTHUFkZFRydXN0IEV4dGVybmFs -IFRUUCBOZXR3b3JrMSIwIAYDVQQDExlBZGRUcnVzdCBFeHRlcm5hbCBDQSBSb290 -MB4XDTAwMDUzMDEwNDgzOFoXDTIwMDUzMDEwNDgzOFowbzELMAkGA1UEBhMCU0Ux -FDASBgNVBAoTC0FkZFRydXN0IEFCMSYwJAYDVQQLEx1BZGRUcnVzdCBFeHRlcm5h -bCBUVFAgTmV0d29yazEiMCAGA1UEAxMZQWRkVHJ1c3QgRXh0ZXJuYWwgQ0EgUm9v -dDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALf3GjPm8gAELTngTlvt -H7xsD821+iO2zt6bETOXpClMfZOfvUq8k+0DGuOPz+VtUFrWlymUWoCwSXrbLpX9 -uMq/NzgtHj6RQa1wVsfwTz/oMp50ysiQVOnGXw94nZpAPA6sYapeFI+eh6FqUNzX -mk6vBbOmcZSccbNQYArHE504B4YCqOmoaSYYkKtMsE8jqzpPhNjfzp/haW+710LX -a0Tkx63ubUFfclpxCDezeWWkWaCUN/cALw3CknLa0Dhy2xSoRcRdKn23tNbE7qzN -E0S3ySvdQwAl+mG5aWpYIxG3pzOPVnVZ9c0p10a3CitlttNCbxWyuHv77+ldU9U0 -WicCAwEAAaOB3DCB2TAdBgNVHQ4EFgQUrb2YejS0Jvf6xCZU7wO94CTLVBowCwYD -VR0PBAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wgZkGA1UdIwSBkTCBjoAUrb2YejS0 -Jvf6xCZU7wO94CTLVBqhc6RxMG8xCzAJBgNVBAYTAlNFMRQwEgYDVQQKEwtBZGRU -cnVzdCBBQjEmMCQGA1UECxMdQWRkVHJ1c3QgRXh0ZXJuYWwgVFRQIE5ldHdvcmsx -IjAgBgNVBAMTGUFkZFRydXN0IEV4dGVybmFsIENBIFJvb3SCAQEwDQYJKoZIhvcN -AQEFBQADggEBALCb4IUlwtYj4g+WBpKdQZic2YR5gdkeWxQHIzZlj7DYd7usQWxH -YINRsPkyPef89iYTx4AWpb9a/IfPeHmJIZriTAcKhjW88t5RxNKWt9x+Tu5w/Rw5 -6wwCURQtjr0W4MHfRnXnJK3s9EK0hZNwEGe6nQY1ShjTK3rMUUKhemPR5ruhxSvC -Nr4TDea9Y355e6cJDUCrat2PisP29owaQgVR1EX1n6diIWgVIEM8med8vSTYqZEX -c4g/VhsxOBi0cQ+azcgOno4uG+GMmIPLHzHxREzGBHNJdmAPx/i9F4BrLunMTA5a -mnkPIAou1Z5jJh5VkpTYghdae9C8x49OhgQ= ------END CERTIFICATE----- - # Issuer: CN=Entrust Root Certification Authority O=Entrust, Inc. OU=www.entrust.net/CPS is incorporated by reference/(c) 2006 Entrust, Inc. # Subject: CN=Entrust Root Certification Authority O=Entrust, Inc. OU=www.entrust.net/CPS is incorporated by reference/(c) 2006 Entrust, Inc. # Label: "Entrust Root Certification Authority" @@ -220,112 +125,6 @@ eu6FSqdQgPCnXEqULl8FmTxSQeDNtGPPAUO6nIPcj2A781q0tHuu2guQOHXvgR1m 0vdXcDazv/wor3ElhVsT/h5/WrQ8 -----END CERTIFICATE----- -# Issuer: CN=GeoTrust Global CA O=GeoTrust Inc. -# Subject: CN=GeoTrust Global CA O=GeoTrust Inc. -# Label: "GeoTrust Global CA" -# Serial: 144470 -# MD5 Fingerprint: f7:75:ab:29:fb:51:4e:b7:77:5e:ff:05:3c:99:8e:f5 -# SHA1 Fingerprint: de:28:f4:a4:ff:e5:b9:2f:a3:c5:03:d1:a3:49:a7:f9:96:2a:82:12 -# SHA256 Fingerprint: ff:85:6a:2d:25:1d:cd:88:d3:66:56:f4:50:12:67:98:cf:ab:aa:de:40:79:9c:72:2d:e4:d2:b5:db:36:a7:3a ------BEGIN CERTIFICATE----- -MIIDVDCCAjygAwIBAgIDAjRWMA0GCSqGSIb3DQEBBQUAMEIxCzAJBgNVBAYTAlVT -MRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMRswGQYDVQQDExJHZW9UcnVzdCBHbG9i -YWwgQ0EwHhcNMDIwNTIxMDQwMDAwWhcNMjIwNTIxMDQwMDAwWjBCMQswCQYDVQQG -EwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEbMBkGA1UEAxMSR2VvVHJ1c3Qg -R2xvYmFsIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2swYYzD9 -9BcjGlZ+W988bDjkcbd4kdS8odhM+KhDtgPpTSEHCIjaWC9mOSm9BXiLnTjoBbdq -fnGk5sRgprDvgOSJKA+eJdbtg/OtppHHmMlCGDUUna2YRpIuT8rxh0PBFpVXLVDv -iS2Aelet8u5fa9IAjbkU+BQVNdnARqN7csiRv8lVK83Qlz6cJmTM386DGXHKTubU -1XupGc1V3sjs0l44U+VcT4wt/lAjNvxm5suOpDkZALeVAjmRCw7+OC7RHQWa9k0+ -bw8HHa8sHo9gOeL6NlMTOdReJivbPagUvTLrGAMoUgRx5aszPeE4uwc2hGKceeoW -MPRfwCvocWvk+QIDAQABo1MwUTAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBTA -ephojYn7qwVkDBF9qn1luMrMTjAfBgNVHSMEGDAWgBTAephojYn7qwVkDBF9qn1l -uMrMTjANBgkqhkiG9w0BAQUFAAOCAQEANeMpauUvXVSOKVCUn5kaFOSPeCpilKIn -Z57QzxpeR+nBsqTP3UEaBU6bS+5Kb1VSsyShNwrrZHYqLizz/Tt1kL/6cdjHPTfS -tQWVYrmm3ok9Nns4d0iXrKYgjy6myQzCsplFAMfOEVEiIuCl6rYVSAlk6l5PdPcF -PseKUgzbFbS9bZvlxrFUaKnjaZC2mqUPuLk/IH2uSrW4nOQdtqvmlKXBx4Ot2/Un -hw4EbNX/3aBd7YdStysVAq45pmp06drE57xNNB6pXE0zX5IJL4hmXXeXxx12E6nV -5fEWCRE11azbJHFwLJhWC9kXtNHjUStedejV0NxPNO3CBWaAocvmMw== ------END CERTIFICATE----- - -# Issuer: CN=GeoTrust Universal CA O=GeoTrust Inc. -# Subject: CN=GeoTrust Universal CA O=GeoTrust Inc. -# Label: "GeoTrust Universal CA" -# Serial: 1 -# MD5 Fingerprint: 92:65:58:8b:a2:1a:31:72:73:68:5c:b4:a5:7a:07:48 -# SHA1 Fingerprint: e6:21:f3:35:43:79:05:9a:4b:68:30:9d:8a:2f:74:22:15:87:ec:79 -# SHA256 Fingerprint: a0:45:9b:9f:63:b2:25:59:f5:fa:5d:4c:6d:b3:f9:f7:2f:f1:93:42:03:35:78:f0:73:bf:1d:1b:46:cb:b9:12 ------BEGIN CERTIFICATE----- -MIIFaDCCA1CgAwIBAgIBATANBgkqhkiG9w0BAQUFADBFMQswCQYDVQQGEwJVUzEW -MBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEeMBwGA1UEAxMVR2VvVHJ1c3QgVW5pdmVy -c2FsIENBMB4XDTA0MDMwNDA1MDAwMFoXDTI5MDMwNDA1MDAwMFowRTELMAkGA1UE -BhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4xHjAcBgNVBAMTFUdlb1RydXN0 -IFVuaXZlcnNhbCBDQTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAKYV -VaCjxuAfjJ0hUNfBvitbtaSeodlyWL0AG0y/YckUHUWCq8YdgNY96xCcOq9tJPi8 -cQGeBvV8Xx7BDlXKg5pZMK4ZyzBIle0iN430SppyZj6tlcDgFgDgEB8rMQ7XlFTT -QjOgNB0eRXbdT8oYN+yFFXoZCPzVx5zw8qkuEKmS5j1YPakWaDwvdSEYfyh3peFh -F7em6fgemdtzbvQKoiFs7tqqhZJmr/Z6a4LauiIINQ/PQvE1+mrufislzDoR5G2v -c7J2Ha3QsnhnGqQ5HFELZ1aD/ThdDc7d8Lsrlh/eezJS/R27tQahsiFepdaVaH/w -mZ7cRQg+59IJDTWU3YBOU5fXtQlEIGQWFwMCTFMNaN7VqnJNk22CDtucvc+081xd -VHppCZbW2xHBjXWotM85yM48vCR85mLK4b19p71XZQvk/iXttmkQ3CgaRr0BHdCX -teGYO8A3ZNY9lO4L4fUorgtWv3GLIylBjobFS1J72HGrH4oVpjuDWtdYAVHGTEHZ -f9hBZ3KiKN9gg6meyHv8U3NyWfWTehd2Ds735VzZC1U0oqpbtWpU5xPKV+yXbfRe -Bi9Fi1jUIxaS5BZuKGNZMN9QAZxjiRqf2xeUgnA3wySemkfWWspOqGmJch+RbNt+ -nhutxx9z3SxPGWX9f5NAEC7S8O08ni4oPmkmM8V7AgMBAAGjYzBhMA8GA1UdEwEB -/wQFMAMBAf8wHQYDVR0OBBYEFNq7LqqwDLiIJlF0XG0D08DYj3rWMB8GA1UdIwQY -MBaAFNq7LqqwDLiIJlF0XG0D08DYj3rWMA4GA1UdDwEB/wQEAwIBhjANBgkqhkiG -9w0BAQUFAAOCAgEAMXjmx7XfuJRAyXHEqDXsRh3ChfMoWIawC/yOsjmPRFWrZIRc -aanQmjg8+uUfNeVE44B5lGiku8SfPeE0zTBGi1QrlaXv9z+ZhP015s8xxtxqv6fX -IwjhmF7DWgh2qaavdy+3YL1ERmrvl/9zlcGO6JP7/TG37FcREUWbMPEaiDnBTzyn -ANXH/KttgCJwpQzgXQQpAvvLoJHRfNbDflDVnVi+QTjruXU8FdmbyUqDWcDaU/0z -uzYYm4UPFd3uLax2k7nZAY1IEKj79TiG8dsKxr2EoyNB3tZ3b4XUhRxQ4K5RirqN -Pnbiucon8l+f725ZDQbYKxek0nxru18UGkiPGkzns0ccjkxFKyDuSN/n3QmOGKja -QI2SJhFTYXNd673nxE0pN2HrrDktZy4W1vUAg4WhzH92xH3kt0tm7wNFYGm2DFKW -koRepqO1pD4r2czYG0eq8kTaT/kD6PAUyz/zg97QwVTjt+gKN02LIFkDMBmhLMi9 -ER/frslKxfMnZmaGrGiR/9nmUxwPi1xpZQomyB40w11Re9epnAahNt3ViZS82eQt -DF4JbAiXfKM9fJP/P6EUp8+1Xevb2xzEdt+Iub1FBZUbrvxGakyvSOPOrg/Sfuvm -bJxPgWp6ZKy7PtXny3YuxadIwVyQD8vIP/rmMuGNG2+k5o7Y+SlIis5z/iw= ------END CERTIFICATE----- - -# Issuer: CN=GeoTrust Universal CA 2 O=GeoTrust Inc. -# Subject: CN=GeoTrust Universal CA 2 O=GeoTrust Inc. -# Label: "GeoTrust Universal CA 2" -# Serial: 1 -# MD5 Fingerprint: 34:fc:b8:d0:36:db:9e:14:b3:c2:f2:db:8f:e4:94:c7 -# SHA1 Fingerprint: 37:9a:19:7b:41:85:45:35:0c:a6:03:69:f3:3c:2e:af:47:4f:20:79 -# SHA256 Fingerprint: a0:23:4f:3b:c8:52:7c:a5:62:8e:ec:81:ad:5d:69:89:5d:a5:68:0d:c9:1d:1c:b8:47:7f:33:f8:78:b9:5b:0b ------BEGIN CERTIFICATE----- -MIIFbDCCA1SgAwIBAgIBATANBgkqhkiG9w0BAQUFADBHMQswCQYDVQQGEwJVUzEW -MBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEgMB4GA1UEAxMXR2VvVHJ1c3QgVW5pdmVy -c2FsIENBIDIwHhcNMDQwMzA0MDUwMDAwWhcNMjkwMzA0MDUwMDAwWjBHMQswCQYD -VQQGEwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEgMB4GA1UEAxMXR2VvVHJ1 -c3QgVW5pdmVyc2FsIENBIDIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC -AQCzVFLByT7y2dyxUxpZKeexw0Uo5dfR7cXFS6GqdHtXr0om/Nj1XqduGdt0DE81 -WzILAePb63p3NeqqWuDW6KFXlPCQo3RWlEQwAx5cTiuFJnSCegx2oG9NzkEtoBUG -FF+3Qs17j1hhNNwqCPkuwwGmIkQcTAeC5lvO0Ep8BNMZcyfwqph/Lq9O64ceJHdq -XbboW0W63MOhBW9Wjo8QJqVJwy7XQYci4E+GymC16qFjwAGXEHm9ADwSbSsVsaxL -se4YuU6W3Nx2/zu+z18DwPw76L5GG//aQMJS9/7jOvdqdzXQ2o3rXhhqMcceujwb -KNZrVMaqW9eiLBsZzKIC9ptZvTdrhrVtgrrY6slWvKk2WP0+GfPtDCapkzj4T8Fd -IgbQl+rhrcZV4IErKIM6+vR7IVEAvlI4zs1meaj0gVbi0IMJR1FbUGrP20gaXT73 -y/Zl92zxlfgCOzJWgjl6W70viRu/obTo/3+NjN8D8WBOWBFM66M/ECuDmgFz2ZRt -hAAnZqzwcEAJQpKtT5MNYQlRJNiS1QuUYbKHsu3/mjX/hVTK7URDrBs8FmtISgoc -QIgfksILAAX/8sgCSqSqqcyZlpwvWOB94b67B9xfBHJcMTTD7F8t4D1kkCLm0ey4 -Lt1ZrtmhN79UNdxzMk+MBB4zsslG8dhcyFVQyWi9qLo2CQIDAQABo2MwYTAPBgNV -HRMBAf8EBTADAQH/MB0GA1UdDgQWBBR281Xh+qQ2+/CfXGJx7Tz0RzgQKzAfBgNV -HSMEGDAWgBR281Xh+qQ2+/CfXGJx7Tz0RzgQKzAOBgNVHQ8BAf8EBAMCAYYwDQYJ -KoZIhvcNAQEFBQADggIBAGbBxiPz2eAubl/oz66wsCVNK/g7WJtAJDday6sWSf+z -dXkzoS9tcBc0kf5nfo/sm+VegqlVHy/c1FEHEv6sFj4sNcZj/NwQ6w2jqtB8zNHQ -L1EuxBRa3ugZ4T7GzKQp5y6EqgYweHZUcyiYWTjgAA1i00J9IZ+uPTqM1fp3DRgr -Fg5fNuH8KrUwJM/gYwx7WBr+mbpCErGR9Hxo4sjoryzqyX6uuyo9DRXcNJW2GHSo -ag/HtPQTxORb7QrSpJdMKu0vbBKJPfEncKpqA1Ihn0CoZ1Dy81of398j9tx4TuaY -T1U6U+Pv8vSfx3zYWK8pIpe44L2RLrB27FcRz+8pRPPphXpgY+RdM4kX2TGq2tbz -GDVyz4crL2MjhF2EjD9XoIj8mZEoJmmZ1I+XRL6O1UixpCgp8RW04eWe3fiPpm8m -1wk8OhwRDqZsN/etRIcsKMfYdIKz0G9KV7s1KSegi+ghp4dkNl3M2Basx7InQJJV -OCiNUW7dFGdTbHFcJoRNdVq2fmBWqU2t+5sel/MN2dKXVHfaPRK34B7vCAas+YWH -6aLcr34YEoP9VhdBLtUpgn2Z9DH2canPLAEnpQW5qrJITirvn5NSUZU8UnOOVkwX -QMAJKOSLakhT2+zNVVXxxvjpoixMptEmX36vWkzaH6byHCx+rgIW0lbQL1dTR+iS ------END CERTIFICATE----- - # Issuer: CN=AAA Certificate Services O=Comodo CA Limited # Subject: CN=AAA Certificate Services O=Comodo CA Limited # Label: "Comodo AAA Services root" @@ -359,48 +158,6 @@ l2D4kF501KKaU73yqWjgom7C12yxow+ev+to51byrvLjKzg6CYG1a4XXvi3tPxq3 smPi9WIsgtRqAEFQ8TmDn5XpNpaYbg== -----END CERTIFICATE----- -# Issuer: CN=QuoVadis Root Certification Authority O=QuoVadis Limited OU=Root Certification Authority -# Subject: CN=QuoVadis Root Certification Authority O=QuoVadis Limited OU=Root Certification Authority -# Label: "QuoVadis Root CA" -# Serial: 985026699 -# MD5 Fingerprint: 27:de:36:fe:72:b7:00:03:00:9d:f4:f0:1e:6c:04:24 -# SHA1 Fingerprint: de:3f:40:bd:50:93:d3:9b:6c:60:f6:da:bc:07:62:01:00:89:76:c9 -# SHA256 Fingerprint: a4:5e:de:3b:bb:f0:9c:8a:e1:5c:72:ef:c0:72:68:d6:93:a2:1c:99:6f:d5:1e:67:ca:07:94:60:fd:6d:88:73 ------BEGIN CERTIFICATE----- -MIIF0DCCBLigAwIBAgIEOrZQizANBgkqhkiG9w0BAQUFADB/MQswCQYDVQQGEwJC -TTEZMBcGA1UEChMQUXVvVmFkaXMgTGltaXRlZDElMCMGA1UECxMcUm9vdCBDZXJ0 -aWZpY2F0aW9uIEF1dGhvcml0eTEuMCwGA1UEAxMlUXVvVmFkaXMgUm9vdCBDZXJ0 -aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wMTAzMTkxODMzMzNaFw0yMTAzMTcxODMz -MzNaMH8xCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMSUw -IwYDVQQLExxSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MS4wLAYDVQQDEyVR -dW9WYWRpcyBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIIBIjANBgkqhkiG -9w0BAQEFAAOCAQ8AMIIBCgKCAQEAv2G1lVO6V/z68mcLOhrfEYBklbTRvM16z/Yp -li4kVEAkOPcahdxYTMukJ0KX0J+DisPkBgNbAKVRHnAEdOLB1Dqr1607BxgFjv2D -rOpm2RgbaIr1VxqYuvXtdj182d6UajtLF8HVj71lODqV0D1VNk7feVcxKh7YWWVJ -WCCYfqtffp/p1k3sg3Spx2zY7ilKhSoGFPlU5tPaZQeLYzcS19Dsw3sgQUSj7cug -F+FxZc4dZjH3dgEZyH0DWLaVSR2mEiboxgx24ONmy+pdpibu5cxfvWenAScOospU -xbF6lR1xHkopigPcakXBpBlebzbNw6Kwt/5cOOJSvPhEQ+aQuwIDAQABo4ICUjCC -Ak4wPQYIKwYBBQUHAQEEMTAvMC0GCCsGAQUFBzABhiFodHRwczovL29jc3AucXVv -dmFkaXNvZmZzaG9yZS5jb20wDwYDVR0TAQH/BAUwAwEB/zCCARoGA1UdIASCAREw -ggENMIIBCQYJKwYBBAG+WAABMIH7MIHUBggrBgEFBQcCAjCBxxqBxFJlbGlhbmNl -IG9uIHRoZSBRdW9WYWRpcyBSb290IENlcnRpZmljYXRlIGJ5IGFueSBwYXJ0eSBh -c3N1bWVzIGFjY2VwdGFuY2Ugb2YgdGhlIHRoZW4gYXBwbGljYWJsZSBzdGFuZGFy -ZCB0ZXJtcyBhbmQgY29uZGl0aW9ucyBvZiB1c2UsIGNlcnRpZmljYXRpb24gcHJh -Y3RpY2VzLCBhbmQgdGhlIFF1b1ZhZGlzIENlcnRpZmljYXRlIFBvbGljeS4wIgYI -KwYBBQUHAgEWFmh0dHA6Ly93d3cucXVvdmFkaXMuYm0wHQYDVR0OBBYEFItLbe3T -KbkGGew5Oanwl4Rqy+/fMIGuBgNVHSMEgaYwgaOAFItLbe3TKbkGGew5Oanwl4Rq -y+/foYGEpIGBMH8xCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBMaW1p -dGVkMSUwIwYDVQQLExxSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MS4wLAYD -VQQDEyVRdW9WYWRpcyBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5ggQ6tlCL -MA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQUFAAOCAQEAitQUtf70mpKnGdSk -fnIYj9lofFIk3WdvOXrEql494liwTXCYhGHoG+NpGA7O+0dQoE7/8CQfvbLO9Sf8 -7C9TqnN7Az10buYWnuulLsS/VidQK2K6vkscPFVcQR0kvoIgR13VRH56FmjffU1R -cHhXHTMe/QKZnAzNCgVPx7uOpHX6Sm2xgI4JVrmcGmD+XcHXetwReNDWXcG31a0y -mQM6isxUJTkxgXsTIlG6Rmyhu576BGxJJnSP0nPrzDCi5upZIof4l/UO/erMkqQW -xFIY6iHOsfHmhIHluqmGKPJDWl0Snawe2ajlCmqnf6CHKc/yiU3U7MXi5nrQNiOK -SnQ2+Q== ------END CERTIFICATE----- - # Issuer: CN=QuoVadis Root CA 2 O=QuoVadis Limited # Subject: CN=QuoVadis Root CA 2 O=QuoVadis Limited # Label: "QuoVadis Root CA 2" @@ -516,33 +273,6 @@ JRDL8Try2frbSVa7pv6nQTXD4IhhyYjH3zYQIphZ6rBK+1YWc26sTfcioU+tHXot RSflMMFe8toTyyVCUZVHA4xsIcx0Qu1T/zOLjw9XARYvz6buyXAiFL39vmwLAw== -----END CERTIFICATE----- -# Issuer: CN=Sonera Class2 CA O=Sonera -# Subject: CN=Sonera Class2 CA O=Sonera -# Label: "Sonera Class 2 Root CA" -# Serial: 29 -# MD5 Fingerprint: a3:ec:75:0f:2e:88:df:fa:48:01:4e:0b:5c:48:6f:fb -# SHA1 Fingerprint: 37:f7:6d:e6:07:7c:90:c5:b1:3e:93:1a:b7:41:10:b4:f2:e4:9a:27 -# SHA256 Fingerprint: 79:08:b4:03:14:c1:38:10:0b:51:8d:07:35:80:7f:fb:fc:f8:51:8a:00:95:33:71:05:ba:38:6b:15:3d:d9:27 ------BEGIN CERTIFICATE----- -MIIDIDCCAgigAwIBAgIBHTANBgkqhkiG9w0BAQUFADA5MQswCQYDVQQGEwJGSTEP -MA0GA1UEChMGU29uZXJhMRkwFwYDVQQDExBTb25lcmEgQ2xhc3MyIENBMB4XDTAx -MDQwNjA3Mjk0MFoXDTIxMDQwNjA3Mjk0MFowOTELMAkGA1UEBhMCRkkxDzANBgNV -BAoTBlNvbmVyYTEZMBcGA1UEAxMQU29uZXJhIENsYXNzMiBDQTCCASIwDQYJKoZI -hvcNAQEBBQADggEPADCCAQoCggEBAJAXSjWdyvANlsdE+hY3/Ei9vX+ALTU74W+o -Z6m/AxxNjG8yR9VBaKQTBME1DJqEQ/xcHf+Js+gXGM2RX/uJ4+q/Tl18GybTdXnt -5oTjV+WtKcT0OijnpXuENmmz/V52vaMtmdOQTiMofRhj8VQ7Jp12W5dCsv+u8E7s -3TmVToMGf+dJQMjFAbJUWmYdPfz56TwKnoG4cPABi+QjVHzIrviQHgCWctRUz2Ej -vOr7nQKV0ba5cTppCD8PtOFCx4j1P5iop7oc4HFx71hXgVB6XGt0Rg6DA5jDjqhu -8nYybieDwnPz3BjotJPqdURrBGAgcVeHnfO+oJAjPYok4doh28MCAwEAAaMzMDEw -DwYDVR0TAQH/BAUwAwEB/zARBgNVHQ4ECgQISqCqWITTXjwwCwYDVR0PBAQDAgEG -MA0GCSqGSIb3DQEBBQUAA4IBAQBazof5FnIVV0sd2ZvnoiYw7JNn39Yt0jSv9zil -zqsWuasvfDXLrNAPtEwr/IDva4yRXzZ299uzGxnq9LIR/WFxRL8oszodv7ND6J+/ -3DEIcbCdjdY0RzKQxmUk96BKfARzjzlvF4xytb1LyHr4e4PDKE6cCepnP7JnBBvD -FNr450kkkdAdavphOe9r5yF1BgfYErQhIHBCcYHaPJo2vqZbDWpsmh+Re/n570K6 -Tk6ezAyNlNzZRZxe7EJQY670XcSxEtzKO6gunRRaBXW37Ndj4ro1tgQIkejanZz2 -ZrUYrAqmVCY0M9IbwdR/GjqOC6oybtv8TyWf2TLHllpwrN9M ------END CERTIFICATE----- - # Issuer: CN=XRamp Global Certification Authority O=XRamp Security Services Inc OU=www.xrampsecurity.com # Subject: CN=XRamp Global Certification Authority O=XRamp Security Services Inc OU=www.xrampsecurity.com # Label: "XRamp Global CA Root" @@ -640,46 +370,6 @@ VSJYACPq4xJDKVtHCN2MQWplBqjlIapBtJUhlbl90TSrE9atvNziPTnNvT51cKEY WQPJIrSPnNVeKtelttQKbfi3QBFGmh95DmK/D5fs4C8fF5Q= -----END CERTIFICATE----- -# Issuer: O=Government Root Certification Authority -# Subject: O=Government Root Certification Authority -# Label: "Taiwan GRCA" -# Serial: 42023070807708724159991140556527066870 -# MD5 Fingerprint: 37:85:44:53:32:45:1f:20:f0:f3:95:e1:25:c4:43:4e -# SHA1 Fingerprint: f4:8b:11:bf:de:ab:be:94:54:20:71:e6:41:de:6b:be:88:2b:40:b9 -# SHA256 Fingerprint: 76:00:29:5e:ef:e8:5b:9e:1f:d6:24:db:76:06:2a:aa:ae:59:81:8a:54:d2:77:4c:d4:c0:b2:c0:11:31:e1:b3 ------BEGIN CERTIFICATE----- -MIIFcjCCA1qgAwIBAgIQH51ZWtcvwgZEpYAIaeNe9jANBgkqhkiG9w0BAQUFADA/ -MQswCQYDVQQGEwJUVzEwMC4GA1UECgwnR292ZXJubWVudCBSb290IENlcnRpZmlj -YXRpb24gQXV0aG9yaXR5MB4XDTAyMTIwNTEzMjMzM1oXDTMyMTIwNTEzMjMzM1ow -PzELMAkGA1UEBhMCVFcxMDAuBgNVBAoMJ0dvdmVybm1lbnQgUm9vdCBDZXJ0aWZp -Y2F0aW9uIEF1dGhvcml0eTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIB -AJoluOzMonWoe/fOW1mKydGGEghU7Jzy50b2iPN86aXfTEc2pBsBHH8eV4qNw8XR -IePaJD9IK/ufLqGU5ywck9G/GwGHU5nOp/UKIXZ3/6m3xnOUT0b3EEk3+qhZSV1q -gQdW8or5BtD3cCJNtLdBuTK4sfCxw5w/cP1T3YGq2GN49thTbqGsaoQkclSGxtKy -yhwOeYHWtXBiCAEuTk8O1RGvqa/lmr/czIdtJuTJV6L7lvnM4T9TjGxMfptTCAts -F/tnyMKtsc2AtJfcdgEWFelq16TheEfOhtX7MfP6Mb40qij7cEwdScevLJ1tZqa2 -jWR+tSBqnTuBto9AAGdLiYa4zGX+FVPpBMHWXx1E1wovJ5pGfaENda1UhhXcSTvx -ls4Pm6Dso3pdvtUqdULle96ltqqvKKyskKw4t9VoNSZ63Pc78/1Fm9G7Q3hub/FC -VGqY8A2tl+lSXunVanLeavcbYBT0peS2cWeqH+riTcFCQP5nRhc4L0c/cZyu5SHK -YS1tB6iEfC3uUSXxY5Ce/eFXiGvviiNtsea9P63RPZYLhY3Naye7twWb7LuRqQoH -EgKXTiCQ8P8NHuJBO9NAOueNXdpm5AKwB1KYXA6OM5zCppX7VRluTI6uSw+9wThN -Xo+EHWbNxWCWtFJaBYmOlXqYwZE8lSOyDvR5tMl8wUohAgMBAAGjajBoMB0GA1Ud -DgQWBBTMzO/MKWCkO7GStjz6MmKPrCUVOzAMBgNVHRMEBTADAQH/MDkGBGcqBwAE -MTAvMC0CAQAwCQYFKw4DAhoFADAHBgVnKgMAAAQUA5vwIhP/lSg209yewDL7MTqK -UWUwDQYJKoZIhvcNAQEFBQADggIBAECASvomyc5eMN1PhnR2WPWus4MzeKR6dBcZ -TulStbngCnRiqmjKeKBMmo4sIy7VahIkv9Ro04rQ2JyftB8M3jh+Vzj8jeJPXgyf -qzvS/3WXy6TjZwj/5cAWtUgBfen5Cv8b5Wppv3ghqMKnI6mGq3ZW6A4M9hPdKmaK -ZEk9GhiHkASfQlK3T8v+R0F2Ne//AHY2RTKbxkaFXeIksB7jSJaYV0eUVXoPQbFE -JPPB/hprv4j9wabak2BegUqZIJxIZhm1AHlUD7gsL0u8qV1bYH+Mh6XgUmMqvtg7 -hUAV/h62ZT/FS9p+tXo1KaMuephgIqP0fSdOLeq0dDzpD6QzDxARvBMB1uUO07+1 -EqLhRSPAzAhuYbeJq4PjJB7mXQfnHyA+z2fI56wwbSdLaG5LKlwCCDTb+HbkZ6Mm -nD+iMsJKxYEYMRBWqoTvLQr/uB930r+lWKBi5NdLkXWNiYCYfm3LU05er/ayl4WX -udpVBrkk7tfGOB5jGxI7leFYrPLfhNVfmS8NVVvmONsuP3LpSIXLuykTjx44Vbnz -ssQwmSNOXfJIoRIM3BKQCZBUkQM8R+XVyWXgt0t97EfTsws+rZ7QdAAO671RrcDe -LMDDav7v3Aun+kbfYNucpllQdSNpc5Oy+fwC00fmcc4QAu4njIT/rEUNE1yDMuAl -pYYsfPQS ------END CERTIFICATE----- - # Issuer: CN=DigiCert Assured ID Root CA O=DigiCert Inc OU=www.digicert.com # Subject: CN=DigiCert Assured ID Root CA O=DigiCert Inc OU=www.digicert.com # Label: "DigiCert Assured ID Root CA" @@ -771,34 +461,6 @@ vEsXCS+0yx5DaMkHJ8HSXPfqIbloEpw8nL+e/IBcm2PN7EeqJSdnoDfzAIJ9VNep +OkuE6N36B9K -----END CERTIFICATE----- -# Issuer: CN=DST Root CA X3 O=Digital Signature Trust Co. -# Subject: CN=DST Root CA X3 O=Digital Signature Trust Co. -# Label: "DST Root CA X3" -# Serial: 91299735575339953335919266965803778155 -# MD5 Fingerprint: 41:03:52:dc:0f:f7:50:1b:16:f0:02:8e:ba:6f:45:c5 -# SHA1 Fingerprint: da:c9:02:4f:54:d8:f6:df:94:93:5f:b1:73:26:38:ca:6a:d7:7c:13 -# SHA256 Fingerprint: 06:87:26:03:31:a7:24:03:d9:09:f1:05:e6:9b:cf:0d:32:e1:bd:24:93:ff:c6:d9:20:6d:11:bc:d6:77:07:39 ------BEGIN CERTIFICATE----- -MIIDSjCCAjKgAwIBAgIQRK+wgNajJ7qJMDmGLvhAazANBgkqhkiG9w0BAQUFADA/ -MSQwIgYDVQQKExtEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdCBDby4xFzAVBgNVBAMT -DkRTVCBSb290IENBIFgzMB4XDTAwMDkzMDIxMTIxOVoXDTIxMDkzMDE0MDExNVow -PzEkMCIGA1UEChMbRGlnaXRhbCBTaWduYXR1cmUgVHJ1c3QgQ28uMRcwFQYDVQQD -Ew5EU1QgUm9vdCBDQSBYMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB -AN+v6ZdQCINXtMxiZfaQguzH0yxrMMpb7NnDfcdAwRgUi+DoM3ZJKuM/IUmTrE4O -rz5Iy2Xu/NMhD2XSKtkyj4zl93ewEnu1lcCJo6m67XMuegwGMoOifooUMM0RoOEq -OLl5CjH9UL2AZd+3UWODyOKIYepLYYHsUmu5ouJLGiifSKOeDNoJjj4XLh7dIN9b -xiqKqy69cK3FCxolkHRyxXtqqzTWMIn/5WgTe1QLyNau7Fqckh49ZLOMxt+/yUFw -7BZy1SbsOFU5Q9D8/RhcQPGX69Wam40dutolucbY38EVAjqr2m7xPi71XAicPNaD -aeQQmxkqtilX4+U9m5/wAl0CAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNV -HQ8BAf8EBAMCAQYwHQYDVR0OBBYEFMSnsaR7LHH62+FLkHX/xBVghYkQMA0GCSqG -SIb3DQEBBQUAA4IBAQCjGiybFwBcqR7uKGY3Or+Dxz9LwwmglSBd49lZRNI+DT69 -ikugdB/OEIKcdBodfpga3csTS7MgROSR6cz8faXbauX+5v3gTt23ADq1cEmv8uXr -AvHRAosZy5Q6XkjEGB5YGV8eAlrwDPGxrancWYaLbumR9YbK+rlmM6pZW87ipxZz -R8srzJmwN0jP41ZL9c8PDHIyh8bwRLtTcm1D9SZImlJnt1ir/md2cXjbDaJWFBM5 -JDGFoqgCWjBH4d1QB7wCCZAA62RjYJsWvIjJEubSfZGL+T0yjWW06XyxV3bqxbYo -Ob8VZRzI9neWagqNdwvYkQsEjgfbKbYK7p2CNTUQ ------END CERTIFICATE----- - # Issuer: CN=SwissSign Gold CA - G2 O=SwissSign AG # Subject: CN=SwissSign Gold CA - G2 O=SwissSign AG # Label: "SwissSign Gold CA - G2" @@ -881,104 +543,6 @@ hAhm0sQ2fac+EPyI4NSA5QC9qvNOBqN6avlicuMJT+ubDgEj8Z+7fNzcbBGXJbLy tGMU0gYqZ4yD9c7qB9iaah7s5Aq7KkzrCWA5zspi2C5u -----END CERTIFICATE----- -# Issuer: CN=GeoTrust Primary Certification Authority O=GeoTrust Inc. -# Subject: CN=GeoTrust Primary Certification Authority O=GeoTrust Inc. -# Label: "GeoTrust Primary Certification Authority" -# Serial: 32798226551256963324313806436981982369 -# MD5 Fingerprint: 02:26:c3:01:5e:08:30:37:43:a9:d0:7d:cf:37:e6:bf -# SHA1 Fingerprint: 32:3c:11:8e:1b:f7:b8:b6:52:54:e2:e2:10:0d:d6:02:90:37:f0:96 -# SHA256 Fingerprint: 37:d5:10:06:c5:12:ea:ab:62:64:21:f1:ec:8c:92:01:3f:c5:f8:2a:e9:8e:e5:33:eb:46:19:b8:de:b4:d0:6c ------BEGIN CERTIFICATE----- -MIIDfDCCAmSgAwIBAgIQGKy1av1pthU6Y2yv2vrEoTANBgkqhkiG9w0BAQUFADBY -MQswCQYDVQQGEwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjExMC8GA1UEAxMo -R2VvVHJ1c3QgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wNjEx -MjcwMDAwMDBaFw0zNjA3MTYyMzU5NTlaMFgxCzAJBgNVBAYTAlVTMRYwFAYDVQQK -Ew1HZW9UcnVzdCBJbmMuMTEwLwYDVQQDEyhHZW9UcnVzdCBQcmltYXJ5IENlcnRp -ZmljYXRpb24gQXV0aG9yaXR5MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC -AQEAvrgVe//UfH1nrYNke8hCUy3f9oQIIGHWAVlqnEQRr+92/ZV+zmEwu3qDXwK9 -AWbK7hWNb6EwnL2hhZ6UOvNWiAAxz9juapYC2e0DjPt1befquFUWBRaa9OBesYjA -ZIVcFU2Ix7e64HXprQU9nceJSOC7KMgD4TCTZF5SwFlwIjVXiIrxlQqD17wxcwE0 -7e9GceBrAqg1cmuXm2bgyxx5X9gaBGgeRwLmnWDiNpcB3841kt++Z8dtd1k7j53W -kBWUvEI0EME5+bEnPn7WinXFsq+W06Lem+SYvn3h6YGttm/81w7a4DSwDRp35+MI -mO9Y+pyEtzavwt+s0vQQBnBxNQIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4G -A1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQULNVQQZcVi/CPNmFbSvtr2ZnJM5IwDQYJ -KoZIhvcNAQEFBQADggEBAFpwfyzdtzRP9YZRqSa+S7iq8XEN3GHHoOo0Hnp3DwQ1 -6CePbJC/kRYkRj5KTs4rFtULUh38H2eiAkUxT87z+gOneZ1TatnaYzr4gNfTmeGl -4b7UVXGYNTq+k+qurUKykG/g/CFNNWMziUnWm07Kx+dOCQD32sfvmWKZd7aVIl6K -oKv0uHiYyjgZmclynnjNS6yvGaBzEi38wkG6gZHaFloxt/m0cYASSJlyc1pZU8Fj -UjPtp8nSOQJw+uCxQmYpqptR7TBUIhRf2asdweSU8Pj1K/fqynhG1riR/aYNKxoU -AT6A8EKglQdebc3MS6RFjasS6LPeWuWgfOgPIh1a6Vk= ------END CERTIFICATE----- - -# Issuer: CN=thawte Primary Root CA O=thawte, Inc. OU=Certification Services Division/(c) 2006 thawte, Inc. - For authorized use only -# Subject: CN=thawte Primary Root CA O=thawte, Inc. OU=Certification Services Division/(c) 2006 thawte, Inc. - For authorized use only -# Label: "thawte Primary Root CA" -# Serial: 69529181992039203566298953787712940909 -# MD5 Fingerprint: 8c:ca:dc:0b:22:ce:f5:be:72:ac:41:1a:11:a8:d8:12 -# SHA1 Fingerprint: 91:c6:d6:ee:3e:8a:c8:63:84:e5:48:c2:99:29:5c:75:6c:81:7b:81 -# SHA256 Fingerprint: 8d:72:2f:81:a9:c1:13:c0:79:1d:f1:36:a2:96:6d:b2:6c:95:0a:97:1d:b4:6b:41:99:f4:ea:54:b7:8b:fb:9f ------BEGIN CERTIFICATE----- -MIIEIDCCAwigAwIBAgIQNE7VVyDV7exJ9C/ON9srbTANBgkqhkiG9w0BAQUFADCB -qTELMAkGA1UEBhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5jLjEoMCYGA1UECxMf -Q2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjE4MDYGA1UECxMvKGMpIDIw -MDYgdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxHzAdBgNV -BAMTFnRoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EwHhcNMDYxMTE3MDAwMDAwWhcNMzYw -NzE2MjM1OTU5WjCBqTELMAkGA1UEBhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5j -LjEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjE4MDYG -A1UECxMvKGMpIDIwMDYgdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNl -IG9ubHkxHzAdBgNVBAMTFnRoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EwggEiMA0GCSqG -SIb3DQEBAQUAA4IBDwAwggEKAoIBAQCsoPD7gFnUnMekz52hWXMJEEUMDSxuaPFs -W0hoSVk3/AszGcJ3f8wQLZU0HObrTQmnHNK4yZc2AreJ1CRfBsDMRJSUjQJib+ta -3RGNKJpchJAQeg29dGYvajig4tVUROsdB58Hum/u6f1OCyn1PoSgAfGcq/gcfomk -6KHYcWUNo1F77rzSImANuVud37r8UVsLr5iy6S7pBOhih94ryNdOwUxkHt3Ph1i6 -Sk/KaAcdHJ1KxtUvkcx8cXIcxcBn6zL9yZJclNqFwJu/U30rCfSMnZEfl2pSy94J -NqR32HuHUETVPm4pafs5SSYeCaWAe0At6+gnhcn+Yf1+5nyXHdWdAgMBAAGjQjBA -MA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBR7W0XP -r87Lev0xkhpqtvNG61dIUDANBgkqhkiG9w0BAQUFAAOCAQEAeRHAS7ORtvzw6WfU -DW5FvlXok9LOAz/t2iWwHVfLHjp2oEzsUHboZHIMpKnxuIvW1oeEuzLlQRHAd9mz -YJ3rG9XRbkREqaYB7FViHXe4XI5ISXycO1cRrK1zN44veFyQaEfZYGDm/Ac9IiAX -xPcW6cTYcvnIc3zfFi8VqT79aie2oetaupgf1eNNZAqdE8hhuvU5HIe6uL17In/2 -/qxAeeWsEG89jxt5dovEN7MhGITlNgDrYyCZuen+MwS7QcjBAvlEYyCegc5C09Y/ -LHbTY5xZ3Y+m4Q6gLkH3LpVHz7z9M/P2C2F+fpErgUfCJzDupxBdN49cOSvkBPB7 -jVaMaA== ------END CERTIFICATE----- - -# Issuer: CN=VeriSign Class 3 Public Primary Certification Authority - G5 O=VeriSign, Inc. OU=VeriSign Trust Network/(c) 2006 VeriSign, Inc. - For authorized use only -# Subject: CN=VeriSign Class 3 Public Primary Certification Authority - G5 O=VeriSign, Inc. OU=VeriSign Trust Network/(c) 2006 VeriSign, Inc. - For authorized use only -# Label: "VeriSign Class 3 Public Primary Certification Authority - G5" -# Serial: 33037644167568058970164719475676101450 -# MD5 Fingerprint: cb:17:e4:31:67:3e:e2:09:fe:45:57:93:f3:0a:fa:1c -# SHA1 Fingerprint: 4e:b6:d5:78:49:9b:1c:cf:5f:58:1e:ad:56:be:3d:9b:67:44:a5:e5 -# SHA256 Fingerprint: 9a:cf:ab:7e:43:c8:d8:80:d0:6b:26:2a:94:de:ee:e4:b4:65:99:89:c3:d0:ca:f1:9b:af:64:05:e4:1a:b7:df ------BEGIN CERTIFICATE----- -MIIE0zCCA7ugAwIBAgIQGNrRniZ96LtKIVjNzGs7SjANBgkqhkiG9w0BAQUFADCB -yjELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQL -ExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJp -U2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxW -ZXJpU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0 -aG9yaXR5IC0gRzUwHhcNMDYxMTA4MDAwMDAwWhcNMzYwNzE2MjM1OTU5WjCByjEL -MAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZW -ZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJpU2ln -biwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxWZXJp -U2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9y -aXR5IC0gRzUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCvJAgIKXo1 -nmAMqudLO07cfLw8RRy7K+D+KQL5VwijZIUVJ/XxrcgxiV0i6CqqpkKzj/i5Vbex -t0uz/o9+B1fs70PbZmIVYc9gDaTY3vjgw2IIPVQT60nKWVSFJuUrjxuf6/WhkcIz -SdhDY2pSS9KP6HBRTdGJaXvHcPaz3BJ023tdS1bTlr8Vd6Gw9KIl8q8ckmcY5fQG -BO+QueQA5N06tRn/Arr0PO7gi+s3i+z016zy9vA9r911kTMZHRxAy3QkGSGT2RT+ -rCpSx4/VBEnkjWNHiDxpg8v+R70rfk/Fla4OndTRQ8Bnc+MUCH7lP59zuDMKz10/ -NIeWiu5T6CUVAgMBAAGjgbIwga8wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8E -BAMCAQYwbQYIKwYBBQUHAQwEYTBfoV2gWzBZMFcwVRYJaW1hZ2UvZ2lmMCEwHzAH -BgUrDgMCGgQUj+XTGoasjY5rw8+AatRIGCx7GS4wJRYjaHR0cDovL2xvZ28udmVy -aXNpZ24uY29tL3ZzbG9nby5naWYwHQYDVR0OBBYEFH/TZafC3ey78DAJ80M5+gKv -MzEzMA0GCSqGSIb3DQEBBQUAA4IBAQCTJEowX2LP2BqYLz3q3JktvXf2pXkiOOzE -p6B4Eq1iDkVwZMXnl2YtmAl+X6/WzChl8gGqCBpH3vn5fJJaCGkgDdk+bW48DW7Y -5gaRQBi5+MHt39tBquCWIMnNZBU4gcmU7qKEKQsTb47bDN0lAtukixlE0kF6BWlK -WE9gyn6CagsCqiUXObXbf+eEZSqVir2G3l6BFoMtEMze/aiCKm0oHw0LxOXnGiYZ -4fQRbxC1lfznQgUy286dUV4otp6F01vvpX1FQHKOtw5rDgb7MzVIcbidJ4vEZV8N -hnacRHr2lVz2XTIIM6RUthg/aFzyQkqFOFSDX9HoLPKsEdao7WNq ------END CERTIFICATE----- - # Issuer: CN=SecureTrust CA O=SecureTrust Corporation # Subject: CN=SecureTrust CA O=SecureTrust Corporation # Label: "SecureTrust CA" @@ -1127,38 +691,6 @@ fQjGGoe9GKhzvSbKYAydzpmfz1wPMOG+FDHqAjAU9JM8SaczepBGR7NjfRObTrdv GDeAU/7dIOA1mjbRxwG55tzd8/8dLDoWV9mSOdY= -----END CERTIFICATE----- -# Issuer: CN=OISTE WISeKey Global Root GA CA O=WISeKey OU=Copyright (c) 2005/OISTE Foundation Endorsed -# Subject: CN=OISTE WISeKey Global Root GA CA O=WISeKey OU=Copyright (c) 2005/OISTE Foundation Endorsed -# Label: "OISTE WISeKey Global Root GA CA" -# Serial: 86718877871133159090080555911823548314 -# MD5 Fingerprint: bc:6c:51:33:a7:e9:d3:66:63:54:15:72:1b:21:92:93 -# SHA1 Fingerprint: 59:22:a1:e1:5a:ea:16:35:21:f8:98:39:6a:46:46:b0:44:1b:0f:a9 -# SHA256 Fingerprint: 41:c9:23:86:6a:b4:ca:d6:b7:ad:57:80:81:58:2e:02:07:97:a6:cb:df:4f:ff:78:ce:83:96:b3:89:37:d7:f5 ------BEGIN CERTIFICATE----- -MIID8TCCAtmgAwIBAgIQQT1yx/RrH4FDffHSKFTfmjANBgkqhkiG9w0BAQUFADCB -ijELMAkGA1UEBhMCQ0gxEDAOBgNVBAoTB1dJU2VLZXkxGzAZBgNVBAsTEkNvcHly -aWdodCAoYykgMjAwNTEiMCAGA1UECxMZT0lTVEUgRm91bmRhdGlvbiBFbmRvcnNl -ZDEoMCYGA1UEAxMfT0lTVEUgV0lTZUtleSBHbG9iYWwgUm9vdCBHQSBDQTAeFw0w -NTEyMTExNjAzNDRaFw0zNzEyMTExNjA5NTFaMIGKMQswCQYDVQQGEwJDSDEQMA4G -A1UEChMHV0lTZUtleTEbMBkGA1UECxMSQ29weXJpZ2h0IChjKSAyMDA1MSIwIAYD -VQQLExlPSVNURSBGb3VuZGF0aW9uIEVuZG9yc2VkMSgwJgYDVQQDEx9PSVNURSBX -SVNlS2V5IEdsb2JhbCBSb290IEdBIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A -MIIBCgKCAQEAy0+zAJs9Nt350UlqaxBJH+zYK7LG+DKBKUOVTJoZIyEVRd7jyBxR -VVuuk+g3/ytr6dTqvirdqFEr12bDYVxgAsj1znJ7O7jyTmUIms2kahnBAbtzptf2 -w93NvKSLtZlhuAGio9RN1AU9ka34tAhxZK9w8RxrfvbDd50kc3vkDIzh2TbhmYsF -mQvtRTEJysIA2/dyoJaqlYfQjse2YXMNdmaM3Bu0Y6Kff5MTMPGhJ9vZ/yxViJGg -4E8HsChWjBgbl0SOid3gF27nKu+POQoxhILYQBRJLnpB5Kf+42TMwVlxSywhp1t9 -4B3RLoGbw9ho972WG6xwsRYUC9tguSYBBQIDAQABo1EwTzALBgNVHQ8EBAMCAYYw -DwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUswN+rja8sHnR3JQmthG+IbJphpQw -EAYJKwYBBAGCNxUBBAMCAQAwDQYJKoZIhvcNAQEFBQADggEBAEuh/wuHbrP5wUOx -SPMowB0uyQlB+pQAHKSkq0lPjz0e701vvbyk9vImMMkQyh2I+3QZH4VFvbBsUfk2 -ftv1TDI6QU9bR8/oCy22xBmddMVHxjtqD6wU2zz0c5ypBd8A3HR4+vg1YFkCExh8 -vPtNsCBtQ7tgMHpnM1zFmdH4LTlSc/uMqpclXHLZCB6rTjzjgTGfA6b7wP4piFXa -hNVQA7bihKOmNqoROgHhGEvWRGizPflTdISzRpFGlgC3gCy24eMQ4tui5yiPAZZi -Fj4A4xylNoEYokxSdsARo27mHbrjWr42U8U+dY+GaSlYU7Wcu2+fXMUY7N0v4ZjJ -/L7fCg0= ------END CERTIFICATE----- - # Issuer: CN=Certigna O=Dhimyotis # Subject: CN=Certigna O=Dhimyotis # Label: "Certigna" @@ -1189,36 +721,6 @@ t0QmwCbAr1UwnjvVNioZBPRcHv/PLLf/0P2HQBHVESO7SMAhqaQoLf0V+LBOK/Qw WyH8EZE0vkHve52Xdf+XlcCWWC/qu0bXu+TZLg== -----END CERTIFICATE----- -# Issuer: CN=Cybertrust Global Root O=Cybertrust, Inc -# Subject: CN=Cybertrust Global Root O=Cybertrust, Inc -# Label: "Cybertrust Global Root" -# Serial: 4835703278459682877484360 -# MD5 Fingerprint: 72:e4:4a:87:e3:69:40:80:77:ea:bc:e3:f4:ff:f0:e1 -# SHA1 Fingerprint: 5f:43:e5:b1:bf:f8:78:8c:ac:1c:c7:ca:4a:9a:c6:22:2b:cc:34:c6 -# SHA256 Fingerprint: 96:0a:df:00:63:e9:63:56:75:0c:29:65:dd:0a:08:67:da:0b:9c:bd:6e:77:71:4a:ea:fb:23:49:ab:39:3d:a3 ------BEGIN CERTIFICATE----- -MIIDoTCCAomgAwIBAgILBAAAAAABD4WqLUgwDQYJKoZIhvcNAQEFBQAwOzEYMBYG -A1UEChMPQ3liZXJ0cnVzdCwgSW5jMR8wHQYDVQQDExZDeWJlcnRydXN0IEdsb2Jh -bCBSb290MB4XDTA2MTIxNTA4MDAwMFoXDTIxMTIxNTA4MDAwMFowOzEYMBYGA1UE -ChMPQ3liZXJ0cnVzdCwgSW5jMR8wHQYDVQQDExZDeWJlcnRydXN0IEdsb2JhbCBS -b290MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA+Mi8vRRQZhP/8NN5 -7CPytxrHjoXxEnOmGaoQ25yiZXRadz5RfVb23CO21O1fWLE3TdVJDm71aofW0ozS -J8bi/zafmGWgE07GKmSb1ZASzxQG9Dvj1Ci+6A74q05IlG2OlTEQXO2iLb3VOm2y -HLtgwEZLAfVJrn5GitB0jaEMAs7u/OePuGtm839EAL9mJRQr3RAwHQeWP032a7iP -t3sMpTjr3kfb1V05/Iin89cqdPHoWqI7n1C6poxFNcJQZZXcY4Lv3b93TZxiyWNz -FtApD0mpSPCzqrdsxacwOUBdrsTiXSZT8M4cIwhhqJQZugRiQOwfOHB3EgZxpzAY -XSUnpQIDAQABo4GlMIGiMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/ -MB0GA1UdDgQWBBS2CHsNesysIEyGVjJez6tuhS1wVzA/BgNVHR8EODA2MDSgMqAw -hi5odHRwOi8vd3d3Mi5wdWJsaWMtdHJ1c3QuY29tL2NybC9jdC9jdHJvb3QuY3Js -MB8GA1UdIwQYMBaAFLYIew16zKwgTIZWMl7Pq26FLXBXMA0GCSqGSIb3DQEBBQUA -A4IBAQBW7wojoFROlZfJ+InaRcHUowAl9B8Tq7ejhVhpwjCt2BWKLePJzYFa+HMj -Wqd8BfP9IjsO0QbE2zZMcwSO5bAi5MXzLqXZI+O4Tkogp24CJJ8iYGd7ix1yCcUx -XOl5n4BHPa2hCwcUPUf/A2kaDAtE52Mlp3+yybh2hO0j9n0Hq0V+09+zv+mKts2o -omcrUtW3ZfA5TGOgkXmTUg9U3YO7n9GPp1Nzw8v/MOx8BLjYRB+TX3EJIrduPuoc -A06dGiBh+4E37F78CkWr1+cXVdCg6mCbpvbjjFspwgZgFJ0tl0ypkxWdYcQBX0jW -WL1WMRJOEcgh4LMRkWXbtKaIOM5V ------END CERTIFICATE----- - # Issuer: O=Chunghwa Telecom Co., Ltd. OU=ePKI Root Certification Authority # Subject: O=Chunghwa Telecom Co., Ltd. OU=ePKI Root Certification Authority # Label: "ePKI Root Certification Authority" @@ -1288,185 +790,6 @@ i/nDhDwTqn6Sm1dTk/pwwpEOMfmbZ13pljheX7NzTogVZ96edhBiIL5VaZVDADlN 9u6wWk5JRFRYX0KD -----END CERTIFICATE----- -# Issuer: CN=GeoTrust Primary Certification Authority - G3 O=GeoTrust Inc. OU=(c) 2008 GeoTrust Inc. - For authorized use only -# Subject: CN=GeoTrust Primary Certification Authority - G3 O=GeoTrust Inc. OU=(c) 2008 GeoTrust Inc. - For authorized use only -# Label: "GeoTrust Primary Certification Authority - G3" -# Serial: 28809105769928564313984085209975885599 -# MD5 Fingerprint: b5:e8:34:36:c9:10:44:58:48:70:6d:2e:83:d4:b8:05 -# SHA1 Fingerprint: 03:9e:ed:b8:0b:e7:a0:3c:69:53:89:3b:20:d2:d9:32:3a:4c:2a:fd -# SHA256 Fingerprint: b4:78:b8:12:25:0d:f8:78:63:5c:2a:a7:ec:7d:15:5e:aa:62:5e:e8:29:16:e2:cd:29:43:61:88:6c:d1:fb:d4 ------BEGIN CERTIFICATE----- -MIID/jCCAuagAwIBAgIQFaxulBmyeUtB9iepwxgPHzANBgkqhkiG9w0BAQsFADCB -mDELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4xOTA3BgNVBAsT -MChjKSAyMDA4IEdlb1RydXN0IEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25s -eTE2MDQGA1UEAxMtR2VvVHJ1c3QgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhv -cml0eSAtIEczMB4XDTA4MDQwMjAwMDAwMFoXDTM3MTIwMTIzNTk1OVowgZgxCzAJ -BgNVBAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMTkwNwYDVQQLEzAoYykg -MjAwOCBHZW9UcnVzdCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxNjA0 -BgNVBAMTLUdlb1RydXN0IFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkg -LSBHMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANziXmJYHTNXOTIz -+uvLh4yn1ErdBojqZI4xmKU4kB6Yzy5jK/BGvESyiaHAKAxJcCGVn2TAppMSAmUm -hsalifD614SgcK9PGpc/BkTVyetyEH3kMSj7HGHmKAdEc5IiaacDiGydY8hS2pgn -5whMcD60yRLBxWeDXTPzAxHsatBT4tG6NmCUgLthY2xbF37fQJQeqw3CIShwiP/W -JmxsYAQlTlV+fe+/lEjetx3dcI0FX4ilm/LC7urRQEFtYjgdVgbFA0dRIBn8exAL -DmKudlW/X3e+PkkBUz2YJQN2JFodtNuJ6nnltrM7P7pMKEF/BqxqjsHQ9gUdfeZC -huOl1UcCAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYw -HQYDVR0OBBYEFMR5yo6hTgMdHNxr2zFblD4/MH8tMA0GCSqGSIb3DQEBCwUAA4IB -AQAtxRPPVoB7eni9n64smefv2t+UXglpp+duaIy9cr5HqQ6XErhK8WTTOd8lNNTB -zU6B8A8ExCSzNJbGpqow32hhc9f5joWJ7w5elShKKiePEI4ufIbEAp7aDHdlDkQN -kv39sxY2+hENHYwOB4lqKVb3cvTdFZx3NWZXqxNT2I7BQMXXExZacse3aQHEerGD -AWh9jUGhlBjBJVz88P6DAod8DQ3PLghcSkANPuyBYeYk28rgDi0Hsj5W3I31QYUH -SJsMC8tJP33st/3LjWeJGqvtux6jAAgIFyqCXDFdRootD4abdNlF+9RAsXqqaC2G -spki4cErx5z481+oghLrGREt ------END CERTIFICATE----- - -# Issuer: CN=thawte Primary Root CA - G2 O=thawte, Inc. OU=(c) 2007 thawte, Inc. - For authorized use only -# Subject: CN=thawte Primary Root CA - G2 O=thawte, Inc. OU=(c) 2007 thawte, Inc. - For authorized use only -# Label: "thawte Primary Root CA - G2" -# Serial: 71758320672825410020661621085256472406 -# MD5 Fingerprint: 74:9d:ea:60:24:c4:fd:22:53:3e:cc:3a:72:d9:29:4f -# SHA1 Fingerprint: aa:db:bc:22:23:8f:c4:01:a1:27:bb:38:dd:f4:1d:db:08:9e:f0:12 -# SHA256 Fingerprint: a4:31:0d:50:af:18:a6:44:71:90:37:2a:86:af:af:8b:95:1f:fb:43:1d:83:7f:1e:56:88:b4:59:71:ed:15:57 ------BEGIN CERTIFICATE----- -MIICiDCCAg2gAwIBAgIQNfwmXNmET8k9Jj1Xm67XVjAKBggqhkjOPQQDAzCBhDEL -MAkGA1UEBhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5jLjE4MDYGA1UECxMvKGMp -IDIwMDcgdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxJDAi -BgNVBAMTG3RoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EgLSBHMjAeFw0wNzExMDUwMDAw -MDBaFw0zODAxMTgyMzU5NTlaMIGEMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMdGhh -d3RlLCBJbmMuMTgwNgYDVQQLEy8oYykgMjAwNyB0aGF3dGUsIEluYy4gLSBGb3Ig -YXV0aG9yaXplZCB1c2Ugb25seTEkMCIGA1UEAxMbdGhhd3RlIFByaW1hcnkgUm9v -dCBDQSAtIEcyMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEotWcgnuVnfFSeIf+iha/ -BebfowJPDQfGAFG6DAJSLSKkQjnE/o/qycG+1E3/n3qe4rF8mq2nhglzh9HnmuN6 -papu+7qzcMBniKI11KOasf2twu8x+qi58/sIxpHR+ymVo0IwQDAPBgNVHRMBAf8E -BTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUmtgAMADna3+FGO6Lts6K -DPgR4bswCgYIKoZIzj0EAwMDaQAwZgIxAN344FdHW6fmCsO99YCKlzUNG4k8VIZ3 -KMqh9HneteY4sPBlcIx/AlTCv//YoT7ZzwIxAMSNlPzcU9LcnXgWHxUzI1NS41ox -XZ3Krr0TKUQNJ1uo52icEvdYPy5yAlejj6EULg== ------END CERTIFICATE----- - -# Issuer: CN=thawte Primary Root CA - G3 O=thawte, Inc. OU=Certification Services Division/(c) 2008 thawte, Inc. - For authorized use only -# Subject: CN=thawte Primary Root CA - G3 O=thawte, Inc. OU=Certification Services Division/(c) 2008 thawte, Inc. - For authorized use only -# Label: "thawte Primary Root CA - G3" -# Serial: 127614157056681299805556476275995414779 -# MD5 Fingerprint: fb:1b:5d:43:8a:94:cd:44:c6:76:f2:43:4b:47:e7:31 -# SHA1 Fingerprint: f1:8b:53:8d:1b:e9:03:b6:a6:f0:56:43:5b:17:15:89:ca:f3:6b:f2 -# SHA256 Fingerprint: 4b:03:f4:58:07:ad:70:f2:1b:fc:2c:ae:71:c9:fd:e4:60:4c:06:4c:f5:ff:b6:86:ba:e5:db:aa:d7:fd:d3:4c ------BEGIN CERTIFICATE----- -MIIEKjCCAxKgAwIBAgIQYAGXt0an6rS0mtZLL/eQ+zANBgkqhkiG9w0BAQsFADCB -rjELMAkGA1UEBhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5jLjEoMCYGA1UECxMf -Q2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjE4MDYGA1UECxMvKGMpIDIw -MDggdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxJDAiBgNV -BAMTG3RoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EgLSBHMzAeFw0wODA0MDIwMDAwMDBa -Fw0zNzEyMDEyMzU5NTlaMIGuMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMdGhhd3Rl -LCBJbmMuMSgwJgYDVQQLEx9DZXJ0aWZpY2F0aW9uIFNlcnZpY2VzIERpdmlzaW9u -MTgwNgYDVQQLEy8oYykgMjAwOCB0aGF3dGUsIEluYy4gLSBGb3IgYXV0aG9yaXpl -ZCB1c2Ugb25seTEkMCIGA1UEAxMbdGhhd3RlIFByaW1hcnkgUm9vdCBDQSAtIEcz -MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsr8nLPvb2FvdeHsbnndm -gcs+vHyu86YnmjSjaDFxODNi5PNxZnmxqWWjpYvVj2AtP0LMqmsywCPLLEHd5N/8 -YZzic7IilRFDGF/Eth9XbAoFWCLINkw6fKXRz4aviKdEAhN0cXMKQlkC+BsUa0Lf -b1+6a4KinVvnSr0eAXLbS3ToO39/fR8EtCab4LRarEc9VbjXsCZSKAExQGbY2SS9 -9irY7CFJXJv2eul/VTV+lmuNk5Mny5K76qxAwJ/C+IDPXfRa3M50hqY+bAtTyr2S -zhkGcuYMXDhpxwTWvGzOW/b3aJzcJRVIiKHpqfiYnODz1TEoYRFsZ5aNOZnLwkUk -OQIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNV -HQ4EFgQUrWyqlGCc7eT/+j4KdCtjA/e2Wb8wDQYJKoZIhvcNAQELBQADggEBABpA -2JVlrAmSicY59BDlqQ5mU1143vokkbvnRFHfxhY0Cu9qRFHqKweKA3rD6z8KLFIW -oCtDuSWQP3CpMyVtRRooOyfPqsMpQhvfO0zAMzRbQYi/aytlryjvsvXDqmbOe1bu -t8jLZ8HJnBoYuMTDSQPxYA5QzUbF83d597YV4Djbxy8ooAw/dyZ02SUS2jHaGh7c -KUGRIjxpp7sC8rZcJwOJ9Abqm+RyguOhCcHpABnTPtRwa7pxpqpYrvS76Wy274fM -m7v/OeZWYdMKp8RcTGB7BXcmer/YB1IsYvdwY9k5vG8cwnncdimvzsUsZAReiDZu -MdRAGmI0Nj81Aa6sY6A= ------END CERTIFICATE----- - -# Issuer: CN=GeoTrust Primary Certification Authority - G2 O=GeoTrust Inc. OU=(c) 2007 GeoTrust Inc. - For authorized use only -# Subject: CN=GeoTrust Primary Certification Authority - G2 O=GeoTrust Inc. OU=(c) 2007 GeoTrust Inc. - For authorized use only -# Label: "GeoTrust Primary Certification Authority - G2" -# Serial: 80682863203381065782177908751794619243 -# MD5 Fingerprint: 01:5e:d8:6b:bd:6f:3d:8e:a1:31:f8:12:e0:98:73:6a -# SHA1 Fingerprint: 8d:17:84:d5:37:f3:03:7d:ec:70:fe:57:8b:51:9a:99:e6:10:d7:b0 -# SHA256 Fingerprint: 5e:db:7a:c4:3b:82:a0:6a:87:61:e8:d7:be:49:79:eb:f2:61:1f:7d:d7:9b:f9:1c:1c:6b:56:6a:21:9e:d7:66 ------BEGIN CERTIFICATE----- -MIICrjCCAjWgAwIBAgIQPLL0SAoA4v7rJDteYD7DazAKBggqhkjOPQQDAzCBmDEL -MAkGA1UEBhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4xOTA3BgNVBAsTMChj -KSAyMDA3IEdlb1RydXN0IEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25seTE2 -MDQGA1UEAxMtR2VvVHJ1c3QgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0 -eSAtIEcyMB4XDTA3MTEwNTAwMDAwMFoXDTM4MDExODIzNTk1OVowgZgxCzAJBgNV -BAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMTkwNwYDVQQLEzAoYykgMjAw -NyBHZW9UcnVzdCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxNjA0BgNV -BAMTLUdlb1RydXN0IFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBH -MjB2MBAGByqGSM49AgEGBSuBBAAiA2IABBWx6P0DFUPlrOuHNxFi79KDNlJ9RVcL -So17VDs6bl8VAsBQps8lL33KSLjHUGMcKiEIfJo22Av+0SbFWDEwKCXzXV2juLal -tJLtbCyf691DiaI8S0iRHVDsJt/WYC69IaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAO -BgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFBVfNVdRVfslsq0DafwBo/q+EVXVMAoG -CCqGSM49BAMDA2cAMGQCMGSWWaboCd6LuvpaiIjwH5HTRqjySkwCY/tsXzjbLkGT -qQ7mndwxHLKgpxgceeHHNgIwOlavmnRs9vuD4DPTCF+hnMJbn0bWtsuRBmOiBucz -rD6ogRLQy7rQkgu2npaqBA+K ------END CERTIFICATE----- - -# Issuer: CN=VeriSign Universal Root Certification Authority O=VeriSign, Inc. OU=VeriSign Trust Network/(c) 2008 VeriSign, Inc. - For authorized use only -# Subject: CN=VeriSign Universal Root Certification Authority O=VeriSign, Inc. OU=VeriSign Trust Network/(c) 2008 VeriSign, Inc. - For authorized use only -# Label: "VeriSign Universal Root Certification Authority" -# Serial: 85209574734084581917763752644031726877 -# MD5 Fingerprint: 8e:ad:b5:01:aa:4d:81:e4:8c:1d:d1:e1:14:00:95:19 -# SHA1 Fingerprint: 36:79:ca:35:66:87:72:30:4d:30:a5:fb:87:3b:0f:a7:7b:b7:0d:54 -# SHA256 Fingerprint: 23:99:56:11:27:a5:71:25:de:8c:ef:ea:61:0d:df:2f:a0:78:b5:c8:06:7f:4e:82:82:90:bf:b8:60:e8:4b:3c ------BEGIN CERTIFICATE----- -MIIEuTCCA6GgAwIBAgIQQBrEZCGzEyEDDrvkEhrFHTANBgkqhkiG9w0BAQsFADCB -vTELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQL -ExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwOCBWZXJp -U2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MTgwNgYDVQQDEy9W -ZXJpU2lnbiBVbml2ZXJzYWwgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAe -Fw0wODA0MDIwMDAwMDBaFw0zNzEyMDEyMzU5NTlaMIG9MQswCQYDVQQGEwJVUzEX -MBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0 -IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAyMDA4IFZlcmlTaWduLCBJbmMuIC0gRm9y -IGF1dGhvcml6ZWQgdXNlIG9ubHkxODA2BgNVBAMTL1ZlcmlTaWduIFVuaXZlcnNh -bCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIIBIjANBgkqhkiG9w0BAQEF -AAOCAQ8AMIIBCgKCAQEAx2E3XrEBNNti1xWb/1hajCMj1mCOkdeQmIN65lgZOIzF -9uVkhbSicfvtvbnazU0AtMgtc6XHaXGVHzk8skQHnOgO+k1KxCHfKWGPMiJhgsWH -H26MfF8WIFFE0XBPV+rjHOPMee5Y2A7Cs0WTwCznmhcrewA3ekEzeOEz4vMQGn+H -LL729fdC4uW/h2KJXwBL38Xd5HVEMkE6HnFuacsLdUYI0crSK5XQz/u5QGtkjFdN -/BMReYTtXlT2NJ8IAfMQJQYXStrxHXpma5hgZqTZ79IugvHw7wnqRMkVauIDbjPT -rJ9VAMf2CGqUuV/c4DPxhGD5WycRtPwW8rtWaoAljQIDAQABo4GyMIGvMA8GA1Ud -EwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMG0GCCsGAQUFBwEMBGEwX6FdoFsw -WTBXMFUWCWltYWdlL2dpZjAhMB8wBwYFKw4DAhoEFI/l0xqGrI2Oa8PPgGrUSBgs -exkuMCUWI2h0dHA6Ly9sb2dvLnZlcmlzaWduLmNvbS92c2xvZ28uZ2lmMB0GA1Ud -DgQWBBS2d/ppSEefUxLVwuoHMnYH0ZcHGTANBgkqhkiG9w0BAQsFAAOCAQEASvj4 -sAPmLGd75JR3Y8xuTPl9Dg3cyLk1uXBPY/ok+myDjEedO2Pzmvl2MpWRsXe8rJq+ -seQxIcaBlVZaDrHC1LGmWazxY8u4TB1ZkErvkBYoH1quEPuBUDgMbMzxPcP1Y+Oz -4yHJJDnp/RVmRvQbEdBNc6N9Rvk97ahfYtTxP/jgdFcrGJ2BtMQo2pSXpXDrrB2+ -BxHw1dvd5Yzw1TKwg+ZX4o+/vqGqvz0dtdQ46tewXDpPaj+PwGZsY6rp2aQW9IHR -lRQOfc2VNNnSj3BzgXucfr2YYdhFh5iQxeuGMMY1v/D/w1WIg0vvBZIGcfK4mJO3 -7M2CYfE45k+XmCpajQ== ------END CERTIFICATE----- - -# Issuer: CN=VeriSign Class 3 Public Primary Certification Authority - G4 O=VeriSign, Inc. OU=VeriSign Trust Network/(c) 2007 VeriSign, Inc. - For authorized use only -# Subject: CN=VeriSign Class 3 Public Primary Certification Authority - G4 O=VeriSign, Inc. OU=VeriSign Trust Network/(c) 2007 VeriSign, Inc. - For authorized use only -# Label: "VeriSign Class 3 Public Primary Certification Authority - G4" -# Serial: 63143484348153506665311985501458640051 -# MD5 Fingerprint: 3a:52:e1:e7:fd:6f:3a:e3:6f:f3:6f:99:1b:f9:22:41 -# SHA1 Fingerprint: 22:d5:d8:df:8f:02:31:d1:8d:f7:9d:b7:cf:8a:2d:64:c9:3f:6c:3a -# SHA256 Fingerprint: 69:dd:d7:ea:90:bb:57:c9:3e:13:5d:c8:5e:a6:fc:d5:48:0b:60:32:39:bd:c4:54:fc:75:8b:2a:26:cf:7f:79 ------BEGIN CERTIFICATE----- -MIIDhDCCAwqgAwIBAgIQL4D+I4wOIg9IZxIokYesszAKBggqhkjOPQQDAzCByjEL -MAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZW -ZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNyBWZXJpU2ln -biwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxWZXJp -U2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9y -aXR5IC0gRzQwHhcNMDcxMTA1MDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCByjELMAkG -A1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZWZXJp -U2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNyBWZXJpU2lnbiwg -SW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxWZXJpU2ln -biBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5 -IC0gRzQwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAASnVnp8Utpkmw4tXNherJI9/gHm -GUo9FANL+mAnINmDiWn6VMaaGF5VKmTeBvaNSjutEDxlPZCIBIngMGGzrl0Bp3ve -fLK+ymVhAIau2o970ImtTR1ZmkGxvEeA3J5iw/mjgbIwga8wDwYDVR0TAQH/BAUw -AwEB/zAOBgNVHQ8BAf8EBAMCAQYwbQYIKwYBBQUHAQwEYTBfoV2gWzBZMFcwVRYJ -aW1hZ2UvZ2lmMCEwHzAHBgUrDgMCGgQUj+XTGoasjY5rw8+AatRIGCx7GS4wJRYj -aHR0cDovL2xvZ28udmVyaXNpZ24uY29tL3ZzbG9nby5naWYwHQYDVR0OBBYEFLMW -kf3upm7ktS5Jj4d4gYDs5bG1MAoGCCqGSM49BAMDA2gAMGUCMGYhDBgmYFo4e1ZC -4Kf8NoRRkSAsdk1DPcQdhCPQrNZ8NQbOzWm9kA3bbEhCHQ6qQgIxAJw9SDkjOVga -FRJZap7v1VmyHVIsmXHNxynfGyphe3HR3vPA5Q06Sqotp9iGKt0uEA== ------END CERTIFICATE----- - # Issuer: CN=NetLock Arany (Class Gold) F\u0151tan\xfas\xedtv\xe1ny O=NetLock Kft. OU=Tan\xfas\xedtv\xe1nykiad\xf3k (Certification Services) # Subject: CN=NetLock Arany (Class Gold) F\u0151tan\xfas\xedtv\xe1ny O=NetLock Kft. OU=Tan\xfas\xedtv\xe1nykiad\xf3k (Certification Services) # Label: "NetLock Arany (Class Gold) F\u0151tan\xfas\xedtv\xe1ny" @@ -1499,47 +822,6 @@ uLjbvrW5KfnaNwUASZQDhETnv0Mxz3WLJdH0pmT1kvarBes96aULNmLazAZfNou2 XjG4Kvte9nHfRCaexOYNkbQudZWAUWpLMKawYqGT8ZvYzsRjdT9ZR7E= -----END CERTIFICATE----- -# Issuer: CN=Staat der Nederlanden Root CA - G2 O=Staat der Nederlanden -# Subject: CN=Staat der Nederlanden Root CA - G2 O=Staat der Nederlanden -# Label: "Staat der Nederlanden Root CA - G2" -# Serial: 10000012 -# MD5 Fingerprint: 7c:a5:0f:f8:5b:9a:7d:6d:30:ae:54:5a:e3:42:a2:8a -# SHA1 Fingerprint: 59:af:82:79:91:86:c7:b4:75:07:cb:cf:03:57:46:eb:04:dd:b7:16 -# SHA256 Fingerprint: 66:8c:83:94:7d:a6:3b:72:4b:ec:e1:74:3c:31:a0:e6:ae:d0:db:8e:c5:b3:1b:e3:77:bb:78:4f:91:b6:71:6f ------BEGIN CERTIFICATE----- -MIIFyjCCA7KgAwIBAgIEAJiWjDANBgkqhkiG9w0BAQsFADBaMQswCQYDVQQGEwJO -TDEeMBwGA1UECgwVU3RhYXQgZGVyIE5lZGVybGFuZGVuMSswKQYDVQQDDCJTdGFh -dCBkZXIgTmVkZXJsYW5kZW4gUm9vdCBDQSAtIEcyMB4XDTA4MDMyNjExMTgxN1oX -DTIwMDMyNTExMDMxMFowWjELMAkGA1UEBhMCTkwxHjAcBgNVBAoMFVN0YWF0IGRl -ciBOZWRlcmxhbmRlbjErMCkGA1UEAwwiU3RhYXQgZGVyIE5lZGVybGFuZGVuIFJv -b3QgQ0EgLSBHMjCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMVZ5291 -qj5LnLW4rJ4L5PnZyqtdj7U5EILXr1HgO+EASGrP2uEGQxGZqhQlEq0i6ABtQ8Sp -uOUfiUtnvWFI7/3S4GCI5bkYYCjDdyutsDeqN95kWSpGV+RLufg3fNU254DBtvPU -Z5uW6M7XxgpT0GtJlvOjCwV3SPcl5XCsMBQgJeN/dVrlSPhOewMHBPqCYYdu8DvE -pMfQ9XQ+pV0aCPKbJdL2rAQmPlU6Yiile7Iwr/g3wtG61jj99O9JMDeZJiFIhQGp -5Rbn3JBV3w/oOM2ZNyFPXfUib2rFEhZgF1XyZWampzCROME4HYYEhLoaJXhena/M -UGDWE4dS7WMfbWV9whUYdMrhfmQpjHLYFhN9C0lK8SgbIHRrxT3dsKpICT0ugpTN -GmXZK4iambwYfp/ufWZ8Pr2UuIHOzZgweMFvZ9C+X+Bo7d7iscksWXiSqt8rYGPy -5V6548r6f1CGPqI0GAwJaCgRHOThuVw+R7oyPxjMW4T182t0xHJ04eOLoEq9jWYv -6q012iDTiIJh8BIitrzQ1aTsr1SIJSQ8p22xcik/Plemf1WvbibG/ufMQFxRRIEK -eN5KzlW/HdXZt1bv8Hb/C3m1r737qWmRRpdogBQ2HbN/uymYNqUg+oJgYjOk7Na6 -B6duxc8UpufWkjTYgfX8HV2qXB72o007uPc5AgMBAAGjgZcwgZQwDwYDVR0TAQH/ -BAUwAwEB/zBSBgNVHSAESzBJMEcGBFUdIAAwPzA9BggrBgEFBQcCARYxaHR0cDov -L3d3dy5wa2lvdmVyaGVpZC5ubC9wb2xpY2llcy9yb290LXBvbGljeS1HMjAOBgNV -HQ8BAf8EBAMCAQYwHQYDVR0OBBYEFJFoMocVHYnitfGsNig0jQt8YojrMA0GCSqG -SIb3DQEBCwUAA4ICAQCoQUpnKpKBglBu4dfYszk78wIVCVBR7y29JHuIhjv5tLyS -CZa59sCrI2AGeYwRTlHSeYAz+51IvuxBQ4EffkdAHOV6CMqqi3WtFMTC6GY8ggen -5ieCWxjmD27ZUD6KQhgpxrRW/FYQoAUXvQwjf/ST7ZwaUb7dRUG/kSS0H4zpX897 -IZmflZ85OkYcbPnNe5yQzSipx6lVu6xiNGI1E0sUOlWDuYaNkqbG9AclVMwWVxJK -gnjIFNkXgiYtXSAfea7+1HAWFpWD2DU5/1JddRwWxRNVz0fMdWVSSt7wsKfkCpYL -+63C4iWEst3kvX5ZbJvw8NjnyvLplzh+ib7M+zkXYT9y2zqR2GUBGR2tUKRXCnxL -vJxxcypFURmFzI79R6d0lR2o0a9OF7FpJsKqeFdbxU2n5Z4FF5TKsl+gSRiNNOkm -bEgeqmiSBeGCc1qb3AdbCG19ndeNIdn8FCCqwkXfP+cAslHkwvgFuXkajDTznlvk -N1trSt8sV4pAWja63XVECDdCcAz+3F4hoKOKwJCcaNpQ5kUQR3i2TtJlycM33+FC -Y7BXN0Ute4qcvwXqZVUz9zkQxSgqIXobisQk+T8VyJoVIPVVYpbtbZNQvOSqeK3Z -ywplh6ZmwcSBo3c6WB4L7oOLnR7SUqTMHW+wmG2UMbX4cQrcufx9MmDm66+KAQ== ------END CERTIFICATE----- - # Issuer: CN=Hongkong Post Root CA 1 O=Hongkong Post # Subject: CN=Hongkong Post Root CA 1 O=Hongkong Post # Label: "Hongkong Post Root CA 1" @@ -1743,105 +1025,6 @@ naM8THLCV8Sg1Mw4J87VBp6iSNnpn86CcDaTmjvfliHjWbcM2pE38P1ZWrOZyGls QyYBNWNgVYkDOnXYukrZVP/u3oDYLdE41V4tC5h9Pmzb/CaIxw== -----END CERTIFICATE----- -# Issuer: CN=Chambers of Commerce Root - 2008 O=AC Camerfirma S.A. -# Subject: CN=Chambers of Commerce Root - 2008 O=AC Camerfirma S.A. -# Label: "Chambers of Commerce Root - 2008" -# Serial: 11806822484801597146 -# MD5 Fingerprint: 5e:80:9e:84:5a:0e:65:0b:17:02:f3:55:18:2a:3e:d7 -# SHA1 Fingerprint: 78:6a:74:ac:76:ab:14:7f:9c:6a:30:50:ba:9e:a8:7e:fe:9a:ce:3c -# SHA256 Fingerprint: 06:3e:4a:fa:c4:91:df:d3:32:f3:08:9b:85:42:e9:46:17:d8:93:d7:fe:94:4e:10:a7:93:7e:e2:9d:96:93:c0 ------BEGIN CERTIFICATE----- -MIIHTzCCBTegAwIBAgIJAKPaQn6ksa7aMA0GCSqGSIb3DQEBBQUAMIGuMQswCQYD -VQQGEwJFVTFDMEEGA1UEBxM6TWFkcmlkIChzZWUgY3VycmVudCBhZGRyZXNzIGF0 -IHd3dy5jYW1lcmZpcm1hLmNvbS9hZGRyZXNzKTESMBAGA1UEBRMJQTgyNzQzMjg3 -MRswGQYDVQQKExJBQyBDYW1lcmZpcm1hIFMuQS4xKTAnBgNVBAMTIENoYW1iZXJz -IG9mIENvbW1lcmNlIFJvb3QgLSAyMDA4MB4XDTA4MDgwMTEyMjk1MFoXDTM4MDcz -MTEyMjk1MFowga4xCzAJBgNVBAYTAkVVMUMwQQYDVQQHEzpNYWRyaWQgKHNlZSBj -dXJyZW50IGFkZHJlc3MgYXQgd3d3LmNhbWVyZmlybWEuY29tL2FkZHJlc3MpMRIw -EAYDVQQFEwlBODI3NDMyODcxGzAZBgNVBAoTEkFDIENhbWVyZmlybWEgUy5BLjEp -MCcGA1UEAxMgQ2hhbWJlcnMgb2YgQ29tbWVyY2UgUm9vdCAtIDIwMDgwggIiMA0G -CSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCvAMtwNyuAWko6bHiUfaN/Gh/2NdW9 -28sNRHI+JrKQUrpjOyhYb6WzbZSm891kDFX29ufyIiKAXuFixrYp4YFs8r/lfTJq -VKAyGVn+H4vXPWCGhSRv4xGzdz4gljUha7MI2XAuZPeEklPWDrCQiorjh40G072Q -DuKZoRuGDtqaCrsLYVAGUvGef3bsyw/QHg3PmTA9HMRFEFis1tPo1+XqxQEHd9ZR -5gN/ikilTWh1uem8nk4ZcfUyS5xtYBkL+8ydddy/Js2Pk3g5eXNeJQ7KXOt3EgfL -ZEFHcpOrUMPrCXZkNNI5t3YRCQ12RcSprj1qr7V9ZS+UWBDsXHyvfuK2GNnQm05a -Sd+pZgvMPMZ4fKecHePOjlO+Bd5gD2vlGts/4+EhySnB8esHnFIbAURRPHsl18Tl -UlRdJQfKFiC4reRB7noI/plvg6aRArBsNlVq5331lubKgdaX8ZSD6e2wsWsSaR6s -+12pxZjptFtYer49okQ6Y1nUCyXeG0+95QGezdIp1Z8XGQpvvwyQ0wlf2eOKNcx5 -Wk0ZN5K3xMGtr/R5JJqyAQuxr1yW84Ay+1w9mPGgP0revq+ULtlVmhduYJ1jbLhj -ya6BXBg14JC7vjxPNyK5fuvPnnchpj04gftI2jE9K+OJ9dC1vX7gUMQSibMjmhAx -hduub+84Mxh2EQIDAQABo4IBbDCCAWgwEgYDVR0TAQH/BAgwBgEB/wIBDDAdBgNV -HQ4EFgQU+SSsD7K1+HnA+mCIG8TZTQKeFxkwgeMGA1UdIwSB2zCB2IAU+SSsD7K1 -+HnA+mCIG8TZTQKeFxmhgbSkgbEwga4xCzAJBgNVBAYTAkVVMUMwQQYDVQQHEzpN -YWRyaWQgKHNlZSBjdXJyZW50IGFkZHJlc3MgYXQgd3d3LmNhbWVyZmlybWEuY29t -L2FkZHJlc3MpMRIwEAYDVQQFEwlBODI3NDMyODcxGzAZBgNVBAoTEkFDIENhbWVy -ZmlybWEgUy5BLjEpMCcGA1UEAxMgQ2hhbWJlcnMgb2YgQ29tbWVyY2UgUm9vdCAt -IDIwMDiCCQCj2kJ+pLGu2jAOBgNVHQ8BAf8EBAMCAQYwPQYDVR0gBDYwNDAyBgRV -HSAAMCowKAYIKwYBBQUHAgEWHGh0dHA6Ly9wb2xpY3kuY2FtZXJmaXJtYS5jb20w -DQYJKoZIhvcNAQEFBQADggIBAJASryI1wqM58C7e6bXpeHxIvj99RZJe6dqxGfwW -PJ+0W2aeaufDuV2I6A+tzyMP3iU6XsxPpcG1Lawk0lgH3qLPaYRgM+gQDROpI9CF -5Y57pp49chNyM/WqfcZjHwj0/gF/JM8rLFQJ3uIrbZLGOU8W6jx+ekbURWpGqOt1 -glanq6B8aBMz9p0w8G8nOSQjKpD9kCk18pPfNKXG9/jvjA9iSnyu0/VU+I22mlaH -FoI6M6taIgj3grrqLuBHmrS1RaMFO9ncLkVAO+rcf+g769HsJtg1pDDFOqxXnrN2 -pSB7+R5KBWIBpih1YJeSDW4+TTdDDZIVnBgizVGZoCkaPF+KMjNbMMeJL0eYD6MD -xvbxrN8y8NmBGuScvfaAFPDRLLmF9dijscilIeUcE5fuDr3fKanvNFNb0+RqE4QG -tjICxFKuItLcsiFCGtpA8CnJ7AoMXOLQusxI0zcKzBIKinmwPQN/aUv0NCB9szTq -jktk9T79syNnFQ0EuPAtwQlRPLJsFfClI9eDdOTlLsn+mCdCxqvGnrDQWzilm1De -fhiYtUU79nm06PcaewaD+9CL2rvHvRirCG88gGtAPxkZumWK5r7VXNM21+9AUiRg -OGcEMeyP84LG3rlV8zsxkVrctQgVrXYlCg17LofiDKYGvCYQbTed7N14jHyAxfDZ -d0jQ ------END CERTIFICATE----- - -# Issuer: CN=Global Chambersign Root - 2008 O=AC Camerfirma S.A. -# Subject: CN=Global Chambersign Root - 2008 O=AC Camerfirma S.A. -# Label: "Global Chambersign Root - 2008" -# Serial: 14541511773111788494 -# MD5 Fingerprint: 9e:80:ff:78:01:0c:2e:c1:36:bd:fe:96:90:6e:08:f3 -# SHA1 Fingerprint: 4a:bd:ee:ec:95:0d:35:9c:89:ae:c7:52:a1:2c:5b:29:f6:d6:aa:0c -# SHA256 Fingerprint: 13:63:35:43:93:34:a7:69:80:16:a0:d3:24:de:72:28:4e:07:9d:7b:52:20:bb:8f:bd:74:78:16:ee:be:ba:ca ------BEGIN CERTIFICATE----- -MIIHSTCCBTGgAwIBAgIJAMnN0+nVfSPOMA0GCSqGSIb3DQEBBQUAMIGsMQswCQYD -VQQGEwJFVTFDMEEGA1UEBxM6TWFkcmlkIChzZWUgY3VycmVudCBhZGRyZXNzIGF0 -IHd3dy5jYW1lcmZpcm1hLmNvbS9hZGRyZXNzKTESMBAGA1UEBRMJQTgyNzQzMjg3 -MRswGQYDVQQKExJBQyBDYW1lcmZpcm1hIFMuQS4xJzAlBgNVBAMTHkdsb2JhbCBD -aGFtYmVyc2lnbiBSb290IC0gMjAwODAeFw0wODA4MDExMjMxNDBaFw0zODA3MzEx -MjMxNDBaMIGsMQswCQYDVQQGEwJFVTFDMEEGA1UEBxM6TWFkcmlkIChzZWUgY3Vy -cmVudCBhZGRyZXNzIGF0IHd3dy5jYW1lcmZpcm1hLmNvbS9hZGRyZXNzKTESMBAG -A1UEBRMJQTgyNzQzMjg3MRswGQYDVQQKExJBQyBDYW1lcmZpcm1hIFMuQS4xJzAl -BgNVBAMTHkdsb2JhbCBDaGFtYmVyc2lnbiBSb290IC0gMjAwODCCAiIwDQYJKoZI -hvcNAQEBBQADggIPADCCAgoCggIBAMDfVtPkOpt2RbQT2//BthmLN0EYlVJH6xed -KYiONWwGMi5HYvNJBL99RDaxccy9Wglz1dmFRP+RVyXfXjaOcNFccUMd2drvXNL7 -G706tcuto8xEpw2uIRU/uXpbknXYpBI4iRmKt4DS4jJvVpyR1ogQC7N0ZJJ0YPP2 -zxhPYLIj0Mc7zmFLmY/CDNBAspjcDahOo7kKrmCgrUVSY7pmvWjg+b4aqIG7HkF4 -ddPB/gBVsIdU6CeQNR1MM62X/JcumIS/LMmjv9GYERTtY/jKmIhYF5ntRQOXfjyG -HoiMvvKRhI9lNNgATH23MRdaKXoKGCQwoze1eqkBfSbW+Q6OWfH9GzO1KTsXO0G2 -Id3UwD2ln58fQ1DJu7xsepeY7s2MH/ucUa6LcL0nn3HAa6x9kGbo1106DbDVwo3V -yJ2dwW3Q0L9R5OP4wzg2rtandeavhENdk5IMagfeOx2YItaswTXbo6Al/3K1dh3e -beksZixShNBFks4c5eUzHdwHU1SjqoI7mjcv3N2gZOnm3b2u/GSFHTynyQbehP9r -6GsaPMWis0L7iwk+XwhSx2LE1AVxv8Rk5Pihg+g+EpuoHtQ2TS9x9o0o9oOpE9Jh -wZG7SMA0j0GMS0zbaRL/UJScIINZc+18ofLx/d33SdNDWKBWY8o9PeU1VlnpDsog -zCtLkykPAgMBAAGjggFqMIIBZjASBgNVHRMBAf8ECDAGAQH/AgEMMB0GA1UdDgQW -BBS5CcqcHtvTbDprru1U8VuTBjUuXjCB4QYDVR0jBIHZMIHWgBS5CcqcHtvTbDpr -ru1U8VuTBjUuXqGBsqSBrzCBrDELMAkGA1UEBhMCRVUxQzBBBgNVBAcTOk1hZHJp -ZCAoc2VlIGN1cnJlbnQgYWRkcmVzcyBhdCB3d3cuY2FtZXJmaXJtYS5jb20vYWRk -cmVzcykxEjAQBgNVBAUTCUE4Mjc0MzI4NzEbMBkGA1UEChMSQUMgQ2FtZXJmaXJt -YSBTLkEuMScwJQYDVQQDEx5HbG9iYWwgQ2hhbWJlcnNpZ24gUm9vdCAtIDIwMDiC -CQDJzdPp1X0jzjAOBgNVHQ8BAf8EBAMCAQYwPQYDVR0gBDYwNDAyBgRVHSAAMCow -KAYIKwYBBQUHAgEWHGh0dHA6Ly9wb2xpY3kuY2FtZXJmaXJtYS5jb20wDQYJKoZI -hvcNAQEFBQADggIBAICIf3DekijZBZRG/5BXqfEv3xoNa/p8DhxJJHkn2EaqbylZ -UohwEurdPfWbU1Rv4WCiqAm57OtZfMY18dwY6fFn5a+6ReAJ3spED8IXDneRRXoz -X1+WLGiLwUePmJs9wOzL9dWCkoQ10b42OFZyMVtHLaoXpGNR6woBrX/sdZ7LoR/x -fxKxueRkf2fWIyr0uDldmOghp+G9PUIadJpwr2hsUF1Jz//7Dl3mLEfXgTpZALVz -a2Mg9jFFCDkO9HB+QHBaP9BrQql0PSgvAm11cpUJjUhjxsYjV5KTXjXBjfkK9yyd -Yhz2rXzdpjEetrHHfoUm+qRqtdpjMNHvkzeyZi99Bffnt0uYlDXA2TopwZ2yUDMd -SqlapskD7+3056huirRXhOukP9DuqqqHW2Pok+JrqNS4cnhrG+055F3Lm6qH1U9O -AP7Zap88MQ8oAgF9mOinsKJknnn4SPIVqczmyETrP3iZ8ntxPjzxmKfFGBI/5rso -M0LpRQp8bfKGeS/Fghl9CYl8slR2iK7ewfPM4W7bMdaTrpmg7yVqc5iJWzouE4ge -v8CSlDQb4ye3ix5vQv/n6TebUB0tovkC7stYWDpxvGjjqsGvHCgfotwjZT+B6q6Z -09gwzxMNTxXJhLynSC34MCN32EZLeW32jO06f2ARePTpm67VVMB0gNELQp/B ------END CERTIFICATE----- - # Issuer: CN=Go Daddy Root Certificate Authority - G2 O=GoDaddy.com, Inc. # Subject: CN=Go Daddy Root Certificate Authority - G2 O=GoDaddy.com, Inc. # Label: "Go Daddy Root Certificate Authority - G2" @@ -2140,37 +1323,43 @@ t/2jioSgrGK+KwmHNPBqAbubKVY8/gA3zyNs8U6qtnRGEmyR7jTV7JqR50S+kDFy SjnRBUkLp7Y3gaVdjKozXoEofKd9J+sAro03 -----END CERTIFICATE----- -# Issuer: CN=Hellenic Academic and Research Institutions RootCA 2011 O=Hellenic Academic and Research Institutions Cert. Authority -# Subject: CN=Hellenic Academic and Research Institutions RootCA 2011 O=Hellenic Academic and Research Institutions Cert. Authority -# Label: "Hellenic Academic and Research Institutions RootCA 2011" -# Serial: 0 -# MD5 Fingerprint: 73:9f:4c:4b:73:5b:79:e9:fa:ba:1c:ef:6e:cb:d5:c9 -# SHA1 Fingerprint: fe:45:65:9b:79:03:5b:98:a1:61:b5:51:2e:ac:da:58:09:48:22:4d -# SHA256 Fingerprint: bc:10:4f:15:a4:8b:e7:09:dc:a5:42:a7:e1:d4:b9:df:6f:05:45:27:e8:02:ea:a9:2d:59:54:44:25:8a:fe:71 ------BEGIN CERTIFICATE----- -MIIEMTCCAxmgAwIBAgIBADANBgkqhkiG9w0BAQUFADCBlTELMAkGA1UEBhMCR1Ix -RDBCBgNVBAoTO0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1 -dGlvbnMgQ2VydC4gQXV0aG9yaXR5MUAwPgYDVQQDEzdIZWxsZW5pYyBBY2FkZW1p -YyBhbmQgUmVzZWFyY2ggSW5zdGl0dXRpb25zIFJvb3RDQSAyMDExMB4XDTExMTIw -NjEzNDk1MloXDTMxMTIwMTEzNDk1MlowgZUxCzAJBgNVBAYTAkdSMUQwQgYDVQQK -EztIZWxsZW5pYyBBY2FkZW1pYyBhbmQgUmVzZWFyY2ggSW5zdGl0dXRpb25zIENl -cnQuIEF1dGhvcml0eTFAMD4GA1UEAxM3SGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJl -c2VhcmNoIEluc3RpdHV0aW9ucyBSb290Q0EgMjAxMTCCASIwDQYJKoZIhvcNAQEB -BQADggEPADCCAQoCggEBAKlTAOMupvaO+mDYLZU++CwqVE7NuYRhlFhPjz2L5EPz -dYmNUeTDN9KKiE15HrcS3UN4SoqS5tdI1Q+kOilENbgH9mgdVc04UfCMJDGFr4PJ -fel3r+0ae50X+bOdOFAPplp5kYCvN66m0zH7tSYJnTxa71HFK9+WXesyHgLacEns -bgzImjeN9/E2YEsmLIKe0HjzDQ9jpFEw4fkrJxIH2Oq9GGKYsFk3fb7u8yBRQlqD -75O6aRXxYp2fmTmCobd0LovUxQt7L/DICto9eQqakxylKHJzkUOap9FNhYS5qXSP -FEDH3N6sQWRstBmbAmNtJGSPRLIl6s5ddAxjMlyNh+UCAwEAAaOBiTCBhjAPBgNV -HRMBAf8EBTADAQH/MAsGA1UdDwQEAwIBBjAdBgNVHQ4EFgQUppFC/RNhSiOeCKQp -5dgTBCPuQSUwRwYDVR0eBEAwPqA8MAWCAy5ncjAFggMuZXUwBoIELmVkdTAGggQu -b3JnMAWBAy5ncjAFgQMuZXUwBoEELmVkdTAGgQQub3JnMA0GCSqGSIb3DQEBBQUA -A4IBAQAf73lB4XtuP7KMhjdCSk4cNx6NZrokgclPEg8hwAOXhiVtXdMiKahsog2p -6z0GW5k6x8zDmjR/qw7IThzh+uTczQ2+vyT+bOdrwg3IBp5OjWEopmr95fZi6hg8 -TqBTnbI6nOulnJEWtk2C4AwFSKls9cz4y51JtPACpf1wA+2KIaWuE4ZJwzNzvoc7 -dIsXRSZMFpGD/md9zU1jZ/rzAxKWeAaNsWftjj++n08C9bMJL/NMh98qy5V8Acys -Nnq/onN694/BtZqhFLKPM58N7yLcZnuEvUUXBj08yrl3NI/K6s8/MT7jiOOASSXI -l7WdmplNsDz4SgCbZN2fOUvRJ9e4 +# Issuer: CN=EC-ACC O=Agencia Catalana de Certificacio (NIF Q-0801176-I) OU=Serveis Publics de Certificacio/Vegeu https://www.catcert.net/verarrel (c)03/Jerarquia Entitats de Certificacio Catalanes +# Subject: CN=EC-ACC O=Agencia Catalana de Certificacio (NIF Q-0801176-I) OU=Serveis Publics de Certificacio/Vegeu https://www.catcert.net/verarrel (c)03/Jerarquia Entitats de Certificacio Catalanes +# Label: "EC-ACC" +# Serial: -23701579247955709139626555126524820479 +# MD5 Fingerprint: eb:f5:9d:29:0d:61:f9:42:1f:7c:c2:ba:6d:e3:15:09 +# SHA1 Fingerprint: 28:90:3a:63:5b:52:80:fa:e6:77:4c:0b:6d:a7:d6:ba:a6:4a:f2:e8 +# SHA256 Fingerprint: 88:49:7f:01:60:2f:31:54:24:6a:e2:8c:4d:5a:ef:10:f1:d8:7e:bb:76:62:6f:4a:e0:b7:f9:5b:a7:96:87:99 +-----BEGIN CERTIFICATE----- +MIIFVjCCBD6gAwIBAgIQ7is969Qh3hSoYqwE893EATANBgkqhkiG9w0BAQUFADCB +8zELMAkGA1UEBhMCRVMxOzA5BgNVBAoTMkFnZW5jaWEgQ2F0YWxhbmEgZGUgQ2Vy +dGlmaWNhY2lvIChOSUYgUS0wODAxMTc2LUkpMSgwJgYDVQQLEx9TZXJ2ZWlzIFB1 +YmxpY3MgZGUgQ2VydGlmaWNhY2lvMTUwMwYDVQQLEyxWZWdldSBodHRwczovL3d3 +dy5jYXRjZXJ0Lm5ldC92ZXJhcnJlbCAoYykwMzE1MDMGA1UECxMsSmVyYXJxdWlh +IEVudGl0YXRzIGRlIENlcnRpZmljYWNpbyBDYXRhbGFuZXMxDzANBgNVBAMTBkVD +LUFDQzAeFw0wMzAxMDcyMzAwMDBaFw0zMTAxMDcyMjU5NTlaMIHzMQswCQYDVQQG +EwJFUzE7MDkGA1UEChMyQWdlbmNpYSBDYXRhbGFuYSBkZSBDZXJ0aWZpY2FjaW8g +KE5JRiBRLTA4MDExNzYtSSkxKDAmBgNVBAsTH1NlcnZlaXMgUHVibGljcyBkZSBD +ZXJ0aWZpY2FjaW8xNTAzBgNVBAsTLFZlZ2V1IGh0dHBzOi8vd3d3LmNhdGNlcnQu +bmV0L3ZlcmFycmVsIChjKTAzMTUwMwYDVQQLEyxKZXJhcnF1aWEgRW50aXRhdHMg +ZGUgQ2VydGlmaWNhY2lvIENhdGFsYW5lczEPMA0GA1UEAxMGRUMtQUNDMIIBIjAN +BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsyLHT+KXQpWIR4NA9h0X84NzJB5R +85iKw5K4/0CQBXCHYMkAqbWUZRkiFRfCQ2xmRJoNBD45b6VLeqpjt4pEndljkYRm +4CgPukLjbo73FCeTae6RDqNfDrHrZqJyTxIThmV6PttPB/SnCWDaOkKZx7J/sxaV +HMf5NLWUhdWZXqBIoH7nF2W4onW4HvPlQn2v7fOKSGRdghST2MDk/7NQcvJ29rNd +QlB50JQ+awwAvthrDk4q7D7SzIKiGGUzE3eeml0aE9jD2z3Il3rucO2n5nzbcc8t +lGLfbdb1OL4/pYUKGbio2Al1QnDE6u/LDsg0qBIimAy4E5S2S+zw0JDnJwIDAQAB +o4HjMIHgMB0GA1UdEQQWMBSBEmVjX2FjY0BjYXRjZXJ0Lm5ldDAPBgNVHRMBAf8E +BTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUoMOLRKo3pUW/l4Ba0fF4 +opvpXY0wfwYDVR0gBHgwdjB0BgsrBgEEAfV4AQMBCjBlMCwGCCsGAQUFBwIBFiBo +dHRwczovL3d3dy5jYXRjZXJ0Lm5ldC92ZXJhcnJlbDA1BggrBgEFBQcCAjApGidW +ZWdldSBodHRwczovL3d3dy5jYXRjZXJ0Lm5ldC92ZXJhcnJlbCAwDQYJKoZIhvcN +AQEFBQADggEBAKBIW4IB9k1IuDlVNZyAelOZ1Vr/sXE7zDkJlF7W2u++AVtd0x7Y +/X1PzaBB4DSTv8vihpw3kpBWHNzrKQXlxJ7HNd+KDM3FIUPpqojlNcAZQmNaAl6k +SBg6hW/cnbw/nZzBh7h6YQjpdwt/cKt63dmXLGQehb+8dJahw3oS7AwaboMMPOhy +Rp/7SNVel+axofjk70YllJyJ22k4vuxcDlbHZVHlUIiIv0LVKz3l+bqeLrPK9HOS +Agu+TGbrIP65y7WZf+a2E/rKS03Z7lNGBjvGTq2TWoF+bCpLagVFjPIhpDGQh2xl +nJ2lYJU6Un/10asIbvPuW/mIPX64b24D5EI= -----END CERTIFICATE----- # Issuer: CN=Actalis Authentication Root CA O=Actalis S.p.A./03358520967 @@ -2214,35 +1403,6 @@ LysRJyU3eExRarDzzFhdFPFqSBX/wge2sY0PjlxQRrM9vwGYT7JZVEc+NHt4bVaT LnPqZih4zR0Uv6CPLy64Lo7yFIrM6bV8+2ydDKXhlg== -----END CERTIFICATE----- -# Issuer: O=Trustis Limited OU=Trustis FPS Root CA -# Subject: O=Trustis Limited OU=Trustis FPS Root CA -# Label: "Trustis FPS Root CA" -# Serial: 36053640375399034304724988975563710553 -# MD5 Fingerprint: 30:c9:e7:1e:6b:e6:14:eb:65:b2:16:69:20:31:67:4d -# SHA1 Fingerprint: 3b:c0:38:0b:33:c3:f6:a6:0c:86:15:22:93:d9:df:f5:4b:81:c0:04 -# SHA256 Fingerprint: c1:b4:82:99:ab:a5:20:8f:e9:63:0a:ce:55:ca:68:a0:3e:da:5a:51:9c:88:02:a0:d3:a6:73:be:8f:8e:55:7d ------BEGIN CERTIFICATE----- -MIIDZzCCAk+gAwIBAgIQGx+ttiD5JNM2a/fH8YygWTANBgkqhkiG9w0BAQUFADBF -MQswCQYDVQQGEwJHQjEYMBYGA1UEChMPVHJ1c3RpcyBMaW1pdGVkMRwwGgYDVQQL -ExNUcnVzdGlzIEZQUyBSb290IENBMB4XDTAzMTIyMzEyMTQwNloXDTI0MDEyMTEx -MzY1NFowRTELMAkGA1UEBhMCR0IxGDAWBgNVBAoTD1RydXN0aXMgTGltaXRlZDEc -MBoGA1UECxMTVHJ1c3RpcyBGUFMgUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQAD -ggEPADCCAQoCggEBAMVQe547NdDfxIzNjpvto8A2mfRC6qc+gIMPpqdZh8mQRUN+ -AOqGeSoDvT03mYlmt+WKVoaTnGhLaASMk5MCPjDSNzoiYYkchU59j9WvezX2fihH -iTHcDnlkH5nSW7r+f2C/revnPDgpai/lkQtV/+xvWNUtyd5MZnGPDNcE2gfmHhjj -vSkCqPoc4Vu5g6hBSLwacY3nYuUtsuvffM/bq1rKMfFMIvMFE/eC+XN5DL7XSxzA -0RU8k0Fk0ea+IxciAIleH2ulrG6nS4zto3Lmr2NNL4XSFDWaLk6M6jKYKIahkQlB -OrTh4/L68MkKokHdqeMDx4gVOxzUGpTXn2RZEm0CAwEAAaNTMFEwDwYDVR0TAQH/ -BAUwAwEB/zAfBgNVHSMEGDAWgBS6+nEleYtXQSUhhgtx67JkDoshZzAdBgNVHQ4E -FgQUuvpxJXmLV0ElIYYLceuyZA6LIWcwDQYJKoZIhvcNAQEFBQADggEBAH5Y//01 -GX2cGE+esCu8jowU/yyg2kdbw++BLa8F6nRIW/M+TgfHbcWzk88iNVy2P3UnXwmW -zaD+vkAMXBJV+JOCyinpXj9WV4s4NvdFGkwozZ5BuO1WTISkQMi4sKUraXAEasP4 -1BIy+Q7DsdwyhEQsb8tGD+pmQQ9P8Vilpg0ND2HepZ5dfWWhPBfnqFVO76DH7cZE -f1T1o+CP8HxVIo8ptoGj4W1OLBuAZ+ytIJ8MYmHVl/9D7S3B2l0pKoU/rGXuhg8F -jZBf3+6f9L/uHfuY5H+QK4R4EA5sSVPvFVtlRkpdr7r7OnIdzfYliB6XzCGcKQEN -ZetX2fNXlrtIzYE= ------END CERTIFICATE----- - # Issuer: CN=Buypass Class 2 Root CA O=Buypass AS-983163327 # Subject: CN=Buypass Class 2 Root CA O=Buypass AS-983163327 # Label: "Buypass Class 2 Root CA" @@ -2352,38 +1512,6 @@ e9eiPZaGzPImNC1qkp2aGtAw4l1OBLBfiyB+d8E9lYLRRpo7PHi4b6HQDWSieB4p TpPDpFQUWw== -----END CERTIFICATE----- -# Issuer: CN=EE Certification Centre Root CA O=AS Sertifitseerimiskeskus -# Subject: CN=EE Certification Centre Root CA O=AS Sertifitseerimiskeskus -# Label: "EE Certification Centre Root CA" -# Serial: 112324828676200291871926431888494945866 -# MD5 Fingerprint: 43:5e:88:d4:7d:1a:4a:7e:fd:84:2e:52:eb:01:d4:6f -# SHA1 Fingerprint: c9:a8:b9:e7:55:80:5e:58:e3:53:77:a7:25:eb:af:c3:7b:27:cc:d7 -# SHA256 Fingerprint: 3e:84:ba:43:42:90:85:16:e7:75:73:c0:99:2f:09:79:ca:08:4e:46:85:68:1f:f1:95:cc:ba:8a:22:9b:8a:76 ------BEGIN CERTIFICATE----- -MIIEAzCCAuugAwIBAgIQVID5oHPtPwBMyonY43HmSjANBgkqhkiG9w0BAQUFADB1 -MQswCQYDVQQGEwJFRTEiMCAGA1UECgwZQVMgU2VydGlmaXRzZWVyaW1pc2tlc2t1 -czEoMCYGA1UEAwwfRUUgQ2VydGlmaWNhdGlvbiBDZW50cmUgUm9vdCBDQTEYMBYG -CSqGSIb3DQEJARYJcGtpQHNrLmVlMCIYDzIwMTAxMDMwMTAxMDMwWhgPMjAzMDEy -MTcyMzU5NTlaMHUxCzAJBgNVBAYTAkVFMSIwIAYDVQQKDBlBUyBTZXJ0aWZpdHNl -ZXJpbWlza2Vza3VzMSgwJgYDVQQDDB9FRSBDZXJ0aWZpY2F0aW9uIENlbnRyZSBS -b290IENBMRgwFgYJKoZIhvcNAQkBFglwa2lAc2suZWUwggEiMA0GCSqGSIb3DQEB -AQUAA4IBDwAwggEKAoIBAQDIIMDs4MVLqwd4lfNE7vsLDP90jmG7sWLqI9iroWUy -euuOF0+W2Ap7kaJjbMeMTC55v6kF/GlclY1i+blw7cNRfdCT5mzrMEvhvH2/UpvO -bntl8jixwKIy72KyaOBhU8E2lf/slLo2rpwcpzIP5Xy0xm90/XsY6KxX7QYgSzIw -WFv9zajmofxwvI6Sc9uXp3whrj3B9UiHbCe9nyV0gVWw93X2PaRka9ZP585ArQ/d -MtO8ihJTmMmJ+xAdTX7Nfh9WDSFwhfYggx/2uh8Ej+p3iDXE/+pOoYtNP2MbRMNE -1CV2yreN1x5KZmTNXMWcg+HCCIia7E6j8T4cLNlsHaFLAgMBAAGjgYowgYcwDwYD -VR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFBLyWj7qVhy/ -zQas8fElyalL1BSZMEUGA1UdJQQ+MDwGCCsGAQUFBwMCBggrBgEFBQcDAQYIKwYB -BQUHAwMGCCsGAQUFBwMEBggrBgEFBQcDCAYIKwYBBQUHAwkwDQYJKoZIhvcNAQEF -BQADggEBAHv25MANqhlHt01Xo/6tu7Fq1Q+e2+RjxY6hUFaTlrg4wCQiZrxTFGGV -v9DHKpY5P30osxBAIWrEr7BSdxjhlthWXePdNl4dp1BUoMUq5KqMlIpPnTX/dqQG -E5Gion0ARD9V04I8GtVbvFZMIi5GQ4okQC3zErg7cBqklrkar4dBGmoYDQZPxz5u -uSlNDUmJEYcyW+ZLBMjkXOZ0c5RdFpgTlf7727FE5TpwrDdr5rMzcijJs1eg9gIW -iAYLtqZLICjU3j2LrTcFU3T+bsy8QxdxXvnFzBqpYe73dgzzcvRyrc9yAjYHR8/v -GVCJYMzpJJUPwssd8m92kMfMdcGWxZ0= ------END CERTIFICATE----- - # Issuer: CN=D-TRUST Root Class 3 CA 2 2009 O=D-Trust GmbH # Subject: CN=D-TRUST Root Class 3 CA 2 2009 O=D-Trust GmbH # Label: "D-TRUST Root Class 3 CA 2 2009" @@ -3093,27 +2221,6 @@ zzuqQhFkoJ2UOQIReVx7Hfpkue4WQrO/isIJxOzksU0CMQDpKmFHjFJKS04YcPbW RNZu9YO6bVi9JNlWSOrvxKJGgYhqOkbRqZtNyWHa0V1Xahg= -----END CERTIFICATE----- -# Issuer: CN=GlobalSign O=GlobalSign OU=GlobalSign ECC Root CA - R4 -# Subject: CN=GlobalSign O=GlobalSign OU=GlobalSign ECC Root CA - R4 -# Label: "GlobalSign ECC Root CA - R4" -# Serial: 14367148294922964480859022125800977897474 -# MD5 Fingerprint: 20:f0:27:68:d1:7e:a0:9d:0e:e6:2a:ca:df:5c:89:8e -# SHA1 Fingerprint: 69:69:56:2e:40:80:f4:24:a1:e7:19:9f:14:ba:f3:ee:58:ab:6a:bb -# SHA256 Fingerprint: be:c9:49:11:c2:95:56:76:db:6c:0a:55:09:86:d7:6e:3b:a0:05:66:7c:44:2c:97:62:b4:fb:b7:73:de:22:8c ------BEGIN CERTIFICATE----- -MIIB4TCCAYegAwIBAgIRKjikHJYKBN5CsiilC+g0mAIwCgYIKoZIzj0EAwIwUDEk -MCIGA1UECxMbR2xvYmFsU2lnbiBFQ0MgUm9vdCBDQSAtIFI0MRMwEQYDVQQKEwpH -bG9iYWxTaWduMRMwEQYDVQQDEwpHbG9iYWxTaWduMB4XDTEyMTExMzAwMDAwMFoX -DTM4MDExOTAzMTQwN1owUDEkMCIGA1UECxMbR2xvYmFsU2lnbiBFQ0MgUm9vdCBD -QSAtIFI0MRMwEQYDVQQKEwpHbG9iYWxTaWduMRMwEQYDVQQDEwpHbG9iYWxTaWdu -MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEuMZ5049sJQ6fLjkZHAOkrprlOQcJ -FspjsbmG+IpXwVfOQvpzofdlQv8ewQCybnMO/8ch5RikqtlxP6jUuc6MHaNCMEAw -DgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFFSwe61F -uOJAf/sKbvu+M8k8o4TVMAoGCCqGSM49BAMCA0gAMEUCIQDckqGgE6bPA7DmxCGX -kPoUVy0D7O48027KqGx2vKLeuwIgJ6iFJzWbVsaj8kfSt24bAgAXqmemFZHe+pTs -ewv4n4Q= ------END CERTIFICATE----- - # Issuer: CN=GlobalSign O=GlobalSign OU=GlobalSign ECC Root CA - R5 # Subject: CN=GlobalSign O=GlobalSign OU=GlobalSign ECC Root CA - R5 # Label: "GlobalSign ECC Root CA - R5" @@ -3136,46 +2243,6 @@ KoZIzj0EAwMDaAAwZQIxAOVpEslu28YxuglB4Zf4+/2a4n0Sye18ZNPLBSWLVtmg xwy8p2Fp8fc74SrL+SvzZpA3 -----END CERTIFICATE----- -# Issuer: CN=Staat der Nederlanden Root CA - G3 O=Staat der Nederlanden -# Subject: CN=Staat der Nederlanden Root CA - G3 O=Staat der Nederlanden -# Label: "Staat der Nederlanden Root CA - G3" -# Serial: 10003001 -# MD5 Fingerprint: 0b:46:67:07:db:10:2f:19:8c:35:50:60:d1:0b:f4:37 -# SHA1 Fingerprint: d8:eb:6b:41:51:92:59:e0:f3:e7:85:00:c0:3d:b6:88:97:c9:ee:fc -# SHA256 Fingerprint: 3c:4f:b0:b9:5a:b8:b3:00:32:f4:32:b8:6f:53:5f:e1:72:c1:85:d0:fd:39:86:58:37:cf:36:18:7f:a6:f4:28 ------BEGIN CERTIFICATE----- -MIIFdDCCA1ygAwIBAgIEAJiiOTANBgkqhkiG9w0BAQsFADBaMQswCQYDVQQGEwJO -TDEeMBwGA1UECgwVU3RhYXQgZGVyIE5lZGVybGFuZGVuMSswKQYDVQQDDCJTdGFh -dCBkZXIgTmVkZXJsYW5kZW4gUm9vdCBDQSAtIEczMB4XDTEzMTExNDExMjg0MloX -DTI4MTExMzIzMDAwMFowWjELMAkGA1UEBhMCTkwxHjAcBgNVBAoMFVN0YWF0IGRl -ciBOZWRlcmxhbmRlbjErMCkGA1UEAwwiU3RhYXQgZGVyIE5lZGVybGFuZGVuIFJv -b3QgQ0EgLSBHMzCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAL4yolQP -cPssXFnrbMSkUeiFKrPMSjTysF/zDsccPVMeiAho2G89rcKezIJnByeHaHE6n3WW -IkYFsO2tx1ueKt6c/DrGlaf1F2cY5y9JCAxcz+bMNO14+1Cx3Gsy8KL+tjzk7FqX -xz8ecAgwoNzFs21v0IJyEavSgWhZghe3eJJg+szeP4TrjTgzkApyI/o1zCZxMdFy -KJLZWyNtZrVtB0LrpjPOktvA9mxjeM3KTj215VKb8b475lRgsGYeCasH/lSJEULR -9yS6YHgamPfJEf0WwTUaVHXvQ9Plrk7O53vDxk5hUUurmkVLoR9BvUhTFXFkC4az -5S6+zqQbwSmEorXLCCN2QyIkHxcE1G6cxvx/K2Ya7Irl1s9N9WMJtxU51nus6+N8 -6U78dULI7ViVDAZCopz35HCz33JvWjdAidiFpNfxC95DGdRKWCyMijmev4SH8RY7 -Ngzp07TKbBlBUgmhHbBqv4LvcFEhMtwFdozL92TkA1CvjJFnq8Xy7ljY3r735zHP -bMk7ccHViLVlvMDoFxcHErVc0qsgk7TmgoNwNsXNo42ti+yjwUOH5kPiNL6VizXt -BznaqB16nzaeErAMZRKQFWDZJkBE41ZgpRDUajz9QdwOWke275dhdU/Z/seyHdTt -XUmzqWrLZoQT1Vyg3N9udwbRcXXIV2+vD3dbAgMBAAGjQjBAMA8GA1UdEwEB/wQF -MAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBRUrfrHkleuyjWcLhL75Lpd -INyUVzANBgkqhkiG9w0BAQsFAAOCAgEAMJmdBTLIXg47mAE6iqTnB/d6+Oea31BD -U5cqPco8R5gu4RV78ZLzYdqQJRZlwJ9UXQ4DO1t3ApyEtg2YXzTdO2PCwyiBwpwp -LiniyMMB8jPqKqrMCQj3ZWfGzd/TtiunvczRDnBfuCPRy5FOCvTIeuXZYzbB1N/8 -Ipf3YF3qKS9Ysr1YvY2WTxB1v0h7PVGHoTx0IsL8B3+A3MSs/mrBcDCw6Y5p4ixp -gZQJut3+TcCDjJRYwEYgr5wfAvg1VUkvRtTA8KCWAg8zxXHzniN9lLf9OtMJgwYh -/WA9rjLA0u6NpvDntIJ8CsxwyXmA+P5M9zWEGYox+wrZ13+b8KKaa8MFSu1BYBQw -0aoRQm7TIwIEC8Zl3d1Sd9qBa7Ko+gE4uZbqKmxnl4mUnrzhVNXkanjvSr0rmj1A -fsbAddJu+2gw7OyLnflJNZoaLNmzlTnVHpL3prllL+U9bTpITAjc5CgSKL59NVzq -4BZ+Extq1z7XnvwtdbLBFNUjA9tbbws+eC8N3jONFrdI54OagQ97wUNNVQQXOEpR -1VmiiXTTn74eS9fGbbeIJG9gkaSChVtWQbzQRKtqE77RLFi3EjNYsjdj3BP1lB0/ -QFH1T/U67cjF68IeHRaVesd+QnGTbksVtzDfqu1XhUisHWrdOWnk4Xl4vs4Fv6EM -94B7IWcnMFk= ------END CERTIFICATE----- - # Issuer: CN=Staat der Nederlanden EV Root CA O=Staat der Nederlanden # Subject: CN=Staat der Nederlanden EV Root CA O=Staat der Nederlanden # Label: "Staat der Nederlanden EV Root CA" @@ -3749,47 +2816,6 @@ CkcO8DdZEv8tmZQoTipPNU0zWgIxAOp1AE47xDqUEpHJWEadIRNyp4iciuRMStuW 1KyLa2tJElMzrdfkviT8tQp21KW8EA== -----END CERTIFICATE----- -# Issuer: CN=LuxTrust Global Root 2 O=LuxTrust S.A. -# Subject: CN=LuxTrust Global Root 2 O=LuxTrust S.A. -# Label: "LuxTrust Global Root 2" -# Serial: 59914338225734147123941058376788110305822489521 -# MD5 Fingerprint: b2:e1:09:00:61:af:f7:f1:91:6f:c4:ad:8d:5e:3b:7c -# SHA1 Fingerprint: 1e:0e:56:19:0a:d1:8b:25:98:b2:04:44:ff:66:8a:04:17:99:5f:3f -# SHA256 Fingerprint: 54:45:5f:71:29:c2:0b:14:47:c4:18:f9:97:16:8f:24:c5:8f:c5:02:3b:f5:da:5b:e2:eb:6e:1d:d8:90:2e:d5 ------BEGIN CERTIFICATE----- -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 ------END CERTIFICATE----- - # Issuer: CN=TUBITAK Kamu SM SSL Kok Sertifikasi - Surum 1 O=Turkiye Bilimsel ve Teknolojik Arastirma Kurumu - TUBITAK OU=Kamu Sertifikasyon Merkezi - Kamu SM # Subject: CN=TUBITAK Kamu SM SSL Kok Sertifikasi - Surum 1 O=Turkiye Bilimsel ve Teknolojik Arastirma Kurumu - TUBITAK OU=Kamu Sertifikasyon Merkezi - Kamu SM # Label: "TUBITAK Kamu SM SSL Kok Sertifikasi - Surum 1" @@ -4169,126 +3195,6 @@ rYy0UGYwEAYJKwYBBAGCNxUBBAMCAQAwCgYIKoZIzj0EAwMDaAAwZQIwJsdpW9zV Mgj/mkkCtojeFK9dbJlxjRo/i9fgojaGHAeCOnZT/cKi7e97sIBPWA9LUzm9 -----END CERTIFICATE----- -# Issuer: CN=GTS Root R1 O=Google Trust Services LLC -# Subject: CN=GTS Root R1 O=Google Trust Services LLC -# Label: "GTS Root R1" -# Serial: 146587175971765017618439757810265552097 -# MD5 Fingerprint: 82:1a:ef:d4:d2:4a:f2:9f:e2:3d:97:06:14:70:72:85 -# SHA1 Fingerprint: e1:c9:50:e6:ef:22:f8:4c:56:45:72:8b:92:20:60:d7:d5:a7:a3:e8 -# SHA256 Fingerprint: 2a:57:54:71:e3:13:40:bc:21:58:1c:bd:2c:f1:3e:15:84:63:20:3e:ce:94:bc:f9:d3:cc:19:6b:f0:9a:54:72 ------BEGIN CERTIFICATE----- -MIIFWjCCA0KgAwIBAgIQbkepxUtHDA3sM9CJuRz04TANBgkqhkiG9w0BAQwFADBH -MQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExM -QzEUMBIGA1UEAxMLR1RTIFJvb3QgUjEwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIy -MDAwMDAwWjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNl -cnZpY2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjEwggIiMA0GCSqGSIb3DQEB -AQUAA4ICDwAwggIKAoICAQC2EQKLHuOhd5s73L+UPreVp0A8of2C+X0yBoJx9vaM -f/vo27xqLpeXo4xL+Sv2sfnOhB2x+cWX3u+58qPpvBKJXqeqUqv4IyfLpLGcY9vX -mX7wCl7raKb0xlpHDU0QM+NOsROjyBhsS+z8CZDfnWQpJSMHobTSPS5g4M/SCYe7 -zUjwTcLCeoiKu7rPWRnWr4+wB7CeMfGCwcDfLqZtbBkOtdh+JhpFAz2weaSUKK0P -fyblqAj+lug8aJRT7oM6iCsVlgmy4HqMLnXWnOunVmSPlk9orj2XwoSPwLxAwAtc -vfaHszVsrBhQf4TgTM2S0yDpM7xSma8ytSmzJSq0SPly4cpk9+aCEI3oncKKiPo4 -Zor8Y/kB+Xj9e1x3+naH+uzfsQ55lVe0vSbv1gHR6xYKu44LtcXFilWr06zqkUsp -zBmkMiVOKvFlRNACzqrOSbTqn3yDsEB750Orp2yjj32JgfpMpf/VjsPOS+C12LOO -Rc92wO1AK/1TD7Cn1TsNsYqiA94xrcx36m97PtbfkSIS5r762DL8EGMUUXLeXdYW -k70paDPvOmbsB4om3xPXV2V4J95eSRQAogB/mqghtqmxlbCluQ0WEdrHbEg8QOB+ -DVrNVjzRlwW5y0vtOUucxD/SVRNuJLDWcfr0wbrM7Rv1/oFB2ACYPTrIrnqYNxgF -lQIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNV -HQ4EFgQU5K8rJnEaK0gnhS9SZizv8IkTcT4wDQYJKoZIhvcNAQEMBQADggIBADiW -Cu49tJYeX++dnAsznyvgyv3SjgofQXSlfKqE1OXyHuY3UjKcC9FhHb8owbZEKTV1 -d5iyfNm9dKyKaOOpMQkpAWBz40d8U6iQSifvS9efk+eCNs6aaAyC58/UEBZvXw6Z -XPYfcX3v73svfuo21pdwCxXu11xWajOl40k4DLh9+42FpLFZXvRq4d2h9mREruZR -gyFmxhE+885H7pwoHyXa/6xmld01D1zvICxi/ZG6qcz8WpyTgYMpl0p8WnK0OdC3 -d8t5/Wk6kjftbjhlRn7pYL15iJdfOBL07q9bgsiG1eGZbYwE8na6SfZu6W0eX6Dv -J4J2QPim01hcDyxC2kLGe4g0x8HYRZvBPsVhHdljUEn2NIVq4BjFbkerQUIpm/Zg -DdIx02OYI5NaAIFItO/Nis3Jz5nu2Z6qNuFoS3FJFDYoOj0dzpqPJeaAcWErtXvM -+SUWgeExX6GjfhaknBZqlxi9dnKlC54dNuYvoS++cJEPqOba+MSSQGwlfnuzCdyy -F62ARPBopY+Udf90WuioAnwMCeKpSwughQtiue+hMZL77/ZRBIls6Kl0obsXs7X9 -SQ98POyDGCBDTtWTurQ0sR8WNh8M5mQ5Fkzc4P4dyKliPUDqysU0ArSuiYgzNdws -E3PYJ/HQcu51OyLemGhmW/HGY0dVHLqlCFF1pkgl ------END CERTIFICATE----- - -# Issuer: CN=GTS Root R2 O=Google Trust Services LLC -# Subject: CN=GTS Root R2 O=Google Trust Services LLC -# Label: "GTS Root R2" -# Serial: 146587176055767053814479386953112547951 -# MD5 Fingerprint: 44:ed:9a:0e:a4:09:3b:00:f2:ae:4c:a3:c6:61:b0:8b -# SHA1 Fingerprint: d2:73:96:2a:2a:5e:39:9f:73:3f:e1:c7:1e:64:3f:03:38:34:fc:4d -# SHA256 Fingerprint: c4:5d:7b:b0:8e:6d:67:e6:2e:42:35:11:0b:56:4e:5f:78:fd:92:ef:05:8c:84:0a:ea:4e:64:55:d7:58:5c:60 ------BEGIN CERTIFICATE----- -MIIFWjCCA0KgAwIBAgIQbkepxlqz5yDFMJo/aFLybzANBgkqhkiG9w0BAQwFADBH -MQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExM -QzEUMBIGA1UEAxMLR1RTIFJvb3QgUjIwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIy -MDAwMDAwWjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNl -cnZpY2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjIwggIiMA0GCSqGSIb3DQEB -AQUAA4ICDwAwggIKAoICAQDO3v2m++zsFDQ8BwZabFn3GTXd98GdVarTzTukk3Lv -CvptnfbwhYBboUhSnznFt+4orO/LdmgUud+tAWyZH8QiHZ/+cnfgLFuv5AS/T3Kg -GjSY6Dlo7JUle3ah5mm5hRm9iYz+re026nO8/4Piy33B0s5Ks40FnotJk9/BW9Bu -XvAuMC6C/Pq8tBcKSOWIm8Wba96wyrQD8Nr0kLhlZPdcTK3ofmZemde4wj7I0BOd -re7kRXuJVfeKH2JShBKzwkCX44ofR5GmdFrS+LFjKBC4swm4VndAoiaYecb+3yXu -PuWgf9RhD1FLPD+M2uFwdNjCaKH5wQzpoeJ/u1U8dgbuak7MkogwTZq9TwtImoS1 -mKPV+3PBV2HdKFZ1E66HjucMUQkQdYhMvI35ezzUIkgfKtzra7tEscszcTJGr61K -8YzodDqs5xoic4DSMPclQsciOzsSrZYuxsN2B6ogtzVJV+mSSeh2FnIxZyuWfoqj -x5RWIr9qS34BIbIjMt/kmkRtWVtd9QCgHJvGeJeNkP+byKq0rxFROV7Z+2et1VsR -nTKaG73VululycslaVNVJ1zgyjbLiGH7HrfQy+4W+9OmTN6SpdTi3/UGVN4unUu0 -kzCqgc7dGtxRcw1PcOnlthYhGXmy5okLdWTK1au8CcEYof/UVKGFPP0UJAOyh9Ok -twIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNV -HQ4EFgQUu//KjiOfT5nK2+JopqUVJxce2Q4wDQYJKoZIhvcNAQEMBQADggIBALZp -8KZ3/p7uC4Gt4cCpx/k1HUCCq+YEtN/L9x0Pg/B+E02NjO7jMyLDOfxA325BS0JT -vhaI8dI4XsRomRyYUpOM52jtG2pzegVATX9lO9ZY8c6DR2Dj/5epnGB3GFW1fgiT -z9D2PGcDFWEJ+YF59exTpJ/JjwGLc8R3dtyDovUMSRqodt6Sm2T4syzFJ9MHwAiA -pJiS4wGWAqoC7o87xdFtCjMwc3i5T1QWvwsHoaRc5svJXISPD+AVdyx+Jn7axEvb -pxZ3B7DNdehyQtaVhJ2Gg/LkkM0JR9SLA3DaWsYDQvTtN6LwG1BUSw7YhN4ZKJmB -R64JGz9I0cNv4rBgF/XuIwKl2gBbbZCr7qLpGzvpx0QnRY5rn/WkhLx3+WuXrD5R -RaIRpsyF7gpo8j5QOHokYh4XIDdtak23CZvJ/KRY9bb7nE4Yu5UC56GtmwfuNmsk -0jmGwZODUNKBRqhfYlcsu2xkiAhu7xNUX90txGdj08+JN7+dIPT7eoOboB6BAFDC -5AwiWVIQ7UNWhwD4FFKnHYuTjKJNRn8nxnGbJN7k2oaLDX5rIMHAnuFl2GqjpuiF -izoHCBy69Y9Vmhh1fuXsgWbRIXOhNUQLgD1bnF5vKheW0YMjiGZt5obicDIvUiLn -yOd/xCxgXS/Dr55FBcOEArf9LAhST4Ldo/DUhgkC ------END CERTIFICATE----- - -# Issuer: CN=GTS Root R3 O=Google Trust Services LLC -# Subject: CN=GTS Root R3 O=Google Trust Services LLC -# Label: "GTS Root R3" -# Serial: 146587176140553309517047991083707763997 -# MD5 Fingerprint: 1a:79:5b:6b:04:52:9c:5d:c7:74:33:1b:25:9a:f9:25 -# SHA1 Fingerprint: 30:d4:24:6f:07:ff:db:91:89:8a:0b:e9:49:66:11:eb:8c:5e:46:e5 -# SHA256 Fingerprint: 15:d5:b8:77:46:19:ea:7d:54:ce:1c:a6:d0:b0:c4:03:e0:37:a9:17:f1:31:e8:a0:4e:1e:6b:7a:71:ba:bc:e5 ------BEGIN CERTIFICATE----- -MIICDDCCAZGgAwIBAgIQbkepx2ypcyRAiQ8DVd2NHTAKBggqhkjOPQQDAzBHMQsw -CQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEU -MBIGA1UEAxMLR1RTIFJvb3QgUjMwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAw -MDAwWjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZp -Y2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjMwdjAQBgcqhkjOPQIBBgUrgQQA -IgNiAAQfTzOHMymKoYTey8chWEGJ6ladK0uFxh1MJ7x/JlFyb+Kf1qPKzEUURout -736GjOyxfi//qXGdGIRFBEFVbivqJn+7kAHjSxm65FSWRQmx1WyRRK2EE46ajA2A -DDL24CejQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1Ud -DgQWBBTB8Sa6oC2uhYHP0/EqEr24Cmf9vDAKBggqhkjOPQQDAwNpADBmAjEAgFuk -fCPAlaUs3L6JbyO5o91lAFJekazInXJ0glMLfalAvWhgxeG4VDvBNhcl2MG9AjEA -njWSdIUlUfUk7GRSJFClH9voy8l27OyCbvWFGFPouOOaKaqW04MjyaR7YbPMAuhd ------END CERTIFICATE----- - -# Issuer: CN=GTS Root R4 O=Google Trust Services LLC -# Subject: CN=GTS Root R4 O=Google Trust Services LLC -# Label: "GTS Root R4" -# Serial: 146587176229350439916519468929765261721 -# MD5 Fingerprint: 5d:b6:6a:c4:60:17:24:6a:1a:99:a8:4b:ee:5e:b4:26 -# SHA1 Fingerprint: 2a:1d:60:27:d9:4a:b1:0a:1c:4d:91:5c:cd:33:a0:cb:3e:2d:54:cb -# SHA256 Fingerprint: 71:cc:a5:39:1f:9e:79:4b:04:80:25:30:b3:63:e1:21:da:8a:30:43:bb:26:66:2f:ea:4d:ca:7f:c9:51:a4:bd ------BEGIN CERTIFICATE----- -MIICCjCCAZGgAwIBAgIQbkepyIuUtui7OyrYorLBmTAKBggqhkjOPQQDAzBHMQsw -CQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEU -MBIGA1UEAxMLR1RTIFJvb3QgUjQwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAw -MDAwWjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZp -Y2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjQwdjAQBgcqhkjOPQIBBgUrgQQA -IgNiAATzdHOnaItgrkO4NcWBMHtLSZ37wWHO5t5GvWvVYRg1rkDdc/eJkTBa6zzu -hXyiQHY7qca4R9gq55KRanPpsXI5nymfopjTX15YhmUPoYRlBtHci8nHc8iMai/l -xKvRHYqjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1Ud -DgQWBBSATNbrdP9JNqPV2Py1PsVq8JQdjDAKBggqhkjOPQQDAwNnADBkAjBqUFJ0 -CMRw3J5QdCHojXohw0+WbhXRIjVhLfoIN+4Zba3bssx9BzT1YBkstTTZbyACMANx -sbqjYAuG7ZoIapVon+Kz4ZNkfF6Tpt95LY2F45TPI11xzPKwTdb+mciUqXWi4w== ------END CERTIFICATE----- - # Issuer: CN=UCA Global G2 Root O=UniTrust # Subject: CN=UCA Global G2 Root O=UniTrust # Label: "UCA Global G2 Root" @@ -4556,3 +3462,1224 @@ L5/ndtFhKvshuzHQqp9HpLIiyhY6UFfEW0NnxWViA0kB60PZ2Pierc+xYw5F9KBa LJstxabArahH9CdMOA0uG0k7UvToiIMrVCjU8jVStDKDYmlkDJGcn5fqdBb9HxEG mpv0 -----END CERTIFICATE----- + +# Issuer: CN=Entrust Root Certification Authority - G4 O=Entrust, Inc. OU=See www.entrust.net/legal-terms/(c) 2015 Entrust, Inc. - for authorized use only +# Subject: CN=Entrust Root Certification Authority - G4 O=Entrust, Inc. OU=See www.entrust.net/legal-terms/(c) 2015 Entrust, Inc. - for authorized use only +# Label: "Entrust Root Certification Authority - G4" +# Serial: 289383649854506086828220374796556676440 +# MD5 Fingerprint: 89:53:f1:83:23:b7:7c:8e:05:f1:8c:71:38:4e:1f:88 +# SHA1 Fingerprint: 14:88:4e:86:26:37:b0:26:af:59:62:5c:40:77:ec:35:29:ba:96:01 +# SHA256 Fingerprint: db:35:17:d1:f6:73:2a:2d:5a:b9:7c:53:3e:c7:07:79:ee:32:70:a6:2f:b4:ac:42:38:37:24:60:e6:f0:1e:88 +-----BEGIN CERTIFICATE----- +MIIGSzCCBDOgAwIBAgIRANm1Q3+vqTkPAAAAAFVlrVgwDQYJKoZIhvcNAQELBQAw +gb4xCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1FbnRydXN0LCBJbmMuMSgwJgYDVQQL +Ex9TZWUgd3d3LmVudHJ1c3QubmV0L2xlZ2FsLXRlcm1zMTkwNwYDVQQLEzAoYykg +MjAxNSBFbnRydXN0LCBJbmMuIC0gZm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxMjAw +BgNVBAMTKUVudHJ1c3QgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEc0 +MB4XDTE1MDUyNzExMTExNloXDTM3MTIyNzExNDExNlowgb4xCzAJBgNVBAYTAlVT +MRYwFAYDVQQKEw1FbnRydXN0LCBJbmMuMSgwJgYDVQQLEx9TZWUgd3d3LmVudHJ1 +c3QubmV0L2xlZ2FsLXRlcm1zMTkwNwYDVQQLEzAoYykgMjAxNSBFbnRydXN0LCBJ +bmMuIC0gZm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxMjAwBgNVBAMTKUVudHJ1c3Qg +Um9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEc0MIICIjANBgkqhkiG9w0B +AQEFAAOCAg8AMIICCgKCAgEAsewsQu7i0TD/pZJH4i3DumSXbcr3DbVZwbPLqGgZ +2K+EbTBwXX7zLtJTmeH+H17ZSK9dE43b/2MzTdMAArzE+NEGCJR5WIoV3imz/f3E +T+iq4qA7ec2/a0My3dl0ELn39GjUu9CH1apLiipvKgS1sqbHoHrmSKvS0VnM1n4j +5pds8ELl3FFLFUHtSUrJ3hCX1nbB76W1NhSXNdh4IjVS70O92yfbYVaCNNzLiGAM +C1rlLAHGVK/XqsEQe9IFWrhAnoanw5CGAlZSCXqc0ieCU0plUmr1POeo8pyvi73T +DtTUXm6Hnmo9RR3RXRv06QqsYJn7ibT/mCzPfB3pAqoEmh643IhuJbNsZvc8kPNX +wbMv9W3y+8qh+CmdRouzavbmZwe+LGcKKh9asj5XxNMhIWNlUpEbsZmOeX7m640A +2Vqq6nPopIICR5b+W45UYaPrL0swsIsjdXJ8ITzI9vF01Bx7owVV7rtNOzK+mndm +nqxpkCIHH2E6lr7lmk/MBTwoWdPBDFSoWWG9yHJM6Nyfh3+9nEg2XpWjDrk4JFX8 +dWbrAuMINClKxuMrLzOg2qOGpRKX/YAr2hRC45K9PvJdXmd0LhyIRyk0X+IyqJwl +N4y6mACXi0mWHv0liqzc2thddG5msP9E36EYxr5ILzeUePiVSj9/E15dWf10hkNj +c0kCAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYD +VR0OBBYEFJ84xFYjwznooHFs6FRM5Og6sb9nMA0GCSqGSIb3DQEBCwUAA4ICAQAS +5UKme4sPDORGpbZgQIeMJX6tuGguW8ZAdjwD+MlZ9POrYs4QjbRaZIxowLByQzTS +Gwv2LFPSypBLhmb8qoMi9IsabyZIrHZ3CL/FmFz0Jomee8O5ZDIBf9PD3Vht7LGr +hFV0d4QEJ1JrhkzO3bll/9bGXp+aEJlLdWr+aumXIOTkdnrG0CSqkM0gkLpHZPt/ +B7NTeLUKYvJzQ85BK4FqLoUWlFPUa19yIqtRLULVAJyZv967lDtX/Zr1hstWO1uI +AeV8KEsD+UmDfLJ/fOPtjqF/YFOOVZ1QNBIPt5d7bIdKROf1beyAN/BYGW5KaHbw +H5Lk6rWS02FREAutp9lfx1/cH6NcjKF+m7ee01ZvZl4HliDtC3T7Zk6LERXpgUl+ +b7DUUH8i119lAg2m9IUe2K4GS0qn0jFmwvjO5QimpAKWRGhXxNUzzxkvFMSUHHuk +2fCfDrGA4tGeEWSpiBE6doLlYsKA2KSD7ZPvfC+QsDJMlhVoSFLUmQjAJOgc47Ol +IQ6SwJAfzyBfyjs4x7dtOvPmRLgOMWuIjnDrnBdSqEGULoe256YSxXXfW8AKbnuk +5F6G+TaU33fD6Q3AOfF5u0aOq0NZJ7cguyPpVkAh7DE9ZapD8j3fcEThuk0mEDuY +n/PIjhs4ViFqUZPTkcpG2om3PVODLAgfi49T3f+sHw== +-----END CERTIFICATE----- + +# Issuer: CN=Microsoft ECC Root Certificate Authority 2017 O=Microsoft Corporation +# Subject: CN=Microsoft ECC Root Certificate Authority 2017 O=Microsoft Corporation +# Label: "Microsoft ECC Root Certificate Authority 2017" +# Serial: 136839042543790627607696632466672567020 +# MD5 Fingerprint: dd:a1:03:e6:4a:93:10:d1:bf:f0:19:42:cb:fe:ed:67 +# SHA1 Fingerprint: 99:9a:64:c3:7f:f4:7d:9f:ab:95:f1:47:69:89:14:60:ee:c4:c3:c5 +# SHA256 Fingerprint: 35:8d:f3:9d:76:4a:f9:e1:b7:66:e9:c9:72:df:35:2e:e1:5c:fa:c2:27:af:6a:d1:d7:0e:8e:4a:6e:dc:ba:02 +-----BEGIN CERTIFICATE----- +MIICWTCCAd+gAwIBAgIQZvI9r4fei7FK6gxXMQHC7DAKBggqhkjOPQQDAzBlMQsw +CQYDVQQGEwJVUzEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMTYwNAYD +VQQDEy1NaWNyb3NvZnQgRUNDIFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IDIw +MTcwHhcNMTkxMjE4MjMwNjQ1WhcNNDIwNzE4MjMxNjA0WjBlMQswCQYDVQQGEwJV +UzEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMTYwNAYDVQQDEy1NaWNy +b3NvZnQgRUNDIFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IDIwMTcwdjAQBgcq +hkjOPQIBBgUrgQQAIgNiAATUvD0CQnVBEyPNgASGAlEvaqiBYgtlzPbKnR5vSmZR +ogPZnZH6thaxjG7efM3beaYvzrvOcS/lpaso7GMEZpn4+vKTEAXhgShC48Zo9OYb +hGBKia/teQ87zvH2RPUBeMCjVDBSMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8E +BTADAQH/MB0GA1UdDgQWBBTIy5lycFIM+Oa+sgRXKSrPQhDtNTAQBgkrBgEEAYI3 +FQEEAwIBADAKBggqhkjOPQQDAwNoADBlAjBY8k3qDPlfXu5gKcs68tvWMoQZP3zV +L8KxzJOuULsJMsbG7X7JNpQS5GiFBqIb0C8CMQCZ6Ra0DvpWSNSkMBaReNtUjGUB +iudQZsIxtzm6uBoiB078a1QWIP8rtedMDE2mT3M= +-----END CERTIFICATE----- + +# Issuer: CN=Microsoft RSA Root Certificate Authority 2017 O=Microsoft Corporation +# Subject: CN=Microsoft RSA Root Certificate Authority 2017 O=Microsoft Corporation +# Label: "Microsoft RSA Root Certificate Authority 2017" +# Serial: 40975477897264996090493496164228220339 +# MD5 Fingerprint: 10:ff:00:ff:cf:c9:f8:c7:7a:c0:ee:35:8e:c9:0f:47 +# SHA1 Fingerprint: 73:a5:e6:4a:3b:ff:83:16:ff:0e:dc:cc:61:8a:90:6e:4e:ae:4d:74 +# SHA256 Fingerprint: c7:41:f7:0f:4b:2a:8d:88:bf:2e:71:c1:41:22:ef:53:ef:10:eb:a0:cf:a5:e6:4c:fa:20:f4:18:85:30:73:e0 +-----BEGIN CERTIFICATE----- +MIIFqDCCA5CgAwIBAgIQHtOXCV/YtLNHcB6qvn9FszANBgkqhkiG9w0BAQwFADBl +MQswCQYDVQQGEwJVUzEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMTYw +NAYDVQQDEy1NaWNyb3NvZnQgUlNBIFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5 +IDIwMTcwHhcNMTkxMjE4MjI1MTIyWhcNNDIwNzE4MjMwMDIzWjBlMQswCQYDVQQG +EwJVUzEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMTYwNAYDVQQDEy1N +aWNyb3NvZnQgUlNBIFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IDIwMTcwggIi +MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDKW76UM4wplZEWCpW9R2LBifOZ +Nt9GkMml7Xhqb0eRaPgnZ1AzHaGm++DlQ6OEAlcBXZxIQIJTELy/xztokLaCLeX0 +ZdDMbRnMlfl7rEqUrQ7eS0MdhweSE5CAg2Q1OQT85elss7YfUJQ4ZVBcF0a5toW1 +HLUX6NZFndiyJrDKxHBKrmCk3bPZ7Pw71VdyvD/IybLeS2v4I2wDwAW9lcfNcztm +gGTjGqwu+UcF8ga2m3P1eDNbx6H7JyqhtJqRjJHTOoI+dkC0zVJhUXAoP8XFWvLJ +jEm7FFtNyP9nTUwSlq31/niol4fX/V4ggNyhSyL71Imtus5Hl0dVe49FyGcohJUc +aDDv70ngNXtk55iwlNpNhTs+VcQor1fznhPbRiefHqJeRIOkpcrVE7NLP8TjwuaG +YaRSMLl6IE9vDzhTyzMMEyuP1pq9KsgtsRx9S1HKR9FIJ3Jdh+vVReZIZZ2vUpC6 +W6IYZVcSn2i51BVrlMRpIpj0M+Dt+VGOQVDJNE92kKz8OMHY4Xu54+OU4UZpyw4K +UGsTuqwPN1q3ErWQgR5WrlcihtnJ0tHXUeOrO8ZV/R4O03QK0dqq6mm4lyiPSMQH ++FJDOvTKVTUssKZqwJz58oHhEmrARdlns87/I6KJClTUFLkqqNfs+avNJVgyeY+Q +W5g5xAgGwax/Dj0ApQIDAQABo1QwUjAOBgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/ +BAUwAwEB/zAdBgNVHQ4EFgQUCctZf4aycI8awznjwNnpv7tNsiMwEAYJKwYBBAGC +NxUBBAMCAQAwDQYJKoZIhvcNAQEMBQADggIBAKyvPl3CEZaJjqPnktaXFbgToqZC +LgLNFgVZJ8og6Lq46BrsTaiXVq5lQ7GPAJtSzVXNUzltYkyLDVt8LkS/gxCP81OC +gMNPOsduET/m4xaRhPtthH80dK2Jp86519efhGSSvpWhrQlTM93uCupKUY5vVau6 +tZRGrox/2KJQJWVggEbbMwSubLWYdFQl3JPk+ONVFT24bcMKpBLBaYVu32TxU5nh +SnUgnZUP5NbcA/FZGOhHibJXWpS2qdgXKxdJ5XbLwVaZOjex/2kskZGT4d9Mozd2 +TaGf+G0eHdP67Pv0RR0Tbc/3WeUiJ3IrhvNXuzDtJE3cfVa7o7P4NHmJweDyAmH3 +pvwPuxwXC65B2Xy9J6P9LjrRk5Sxcx0ki69bIImtt2dmefU6xqaWM/5TkshGsRGR +xpl/j8nWZjEgQRCHLQzWwa80mMpkg/sTV9HB8Dx6jKXB/ZUhoHHBk2dxEuqPiApp +GWSZI1b7rCoucL5mxAyE7+WL85MB+GqQk2dLsmijtWKP6T+MejteD+eMuMZ87zf9 +dOLITzNy4ZQ5bb0Sr74MTnB8G2+NszKTc0QWbej09+CVgI+WXTik9KveCjCHk9hN +AHFiRSdLOkKEW39lt2c0Ui2cFmuqqNh7o0JMcccMyj6D5KbvtwEwXlGjefVwaaZB +RA+GsCyRxj3qrg+E +-----END CERTIFICATE----- + +# Issuer: CN=e-Szigno Root CA 2017 O=Microsec Ltd. +# Subject: CN=e-Szigno Root CA 2017 O=Microsec Ltd. +# Label: "e-Szigno Root CA 2017" +# Serial: 411379200276854331539784714 +# MD5 Fingerprint: de:1f:f6:9e:84:ae:a7:b4:21:ce:1e:58:7d:d1:84:98 +# SHA1 Fingerprint: 89:d4:83:03:4f:9e:9a:48:80:5f:72:37:d4:a9:a6:ef:cb:7c:1f:d1 +# SHA256 Fingerprint: be:b0:0b:30:83:9b:9b:c3:2c:32:e4:44:79:05:95:06:41:f2:64:21:b1:5e:d0:89:19:8b:51:8a:e2:ea:1b:99 +-----BEGIN CERTIFICATE----- +MIICQDCCAeWgAwIBAgIMAVRI7yH9l1kN9QQKMAoGCCqGSM49BAMCMHExCzAJBgNV +BAYTAkhVMREwDwYDVQQHDAhCdWRhcGVzdDEWMBQGA1UECgwNTWljcm9zZWMgTHRk +LjEXMBUGA1UEYQwOVkFUSFUtMjM1ODQ0OTcxHjAcBgNVBAMMFWUtU3ppZ25vIFJv +b3QgQ0EgMjAxNzAeFw0xNzA4MjIxMjA3MDZaFw00MjA4MjIxMjA3MDZaMHExCzAJ +BgNVBAYTAkhVMREwDwYDVQQHDAhCdWRhcGVzdDEWMBQGA1UECgwNTWljcm9zZWMg +THRkLjEXMBUGA1UEYQwOVkFUSFUtMjM1ODQ0OTcxHjAcBgNVBAMMFWUtU3ppZ25v +IFJvb3QgQ0EgMjAxNzBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABJbcPYrYsHtv +xie+RJCxs1YVe45DJH0ahFnuY2iyxl6H0BVIHqiQrb1TotreOpCmYF9oMrWGQd+H +Wyx7xf58etqjYzBhMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0G +A1UdDgQWBBSHERUI0arBeAyxr87GyZDvvzAEwDAfBgNVHSMEGDAWgBSHERUI0arB +eAyxr87GyZDvvzAEwDAKBggqhkjOPQQDAgNJADBGAiEAtVfd14pVCzbhhkT61Nlo +jbjcI4qKDdQvfepz7L9NbKgCIQDLpbQS+ue16M9+k/zzNY9vTlp8tLxOsvxyqltZ ++efcMQ== +-----END CERTIFICATE----- + +# Issuer: O=CERTSIGN SA OU=certSIGN ROOT CA G2 +# Subject: O=CERTSIGN SA OU=certSIGN ROOT CA G2 +# Label: "certSIGN Root CA G2" +# Serial: 313609486401300475190 +# MD5 Fingerprint: 8c:f1:75:8a:c6:19:cf:94:b7:f7:65:20:87:c3:97:c7 +# SHA1 Fingerprint: 26:f9:93:b4:ed:3d:28:27:b0:b9:4b:a7:e9:15:1d:a3:8d:92:e5:32 +# SHA256 Fingerprint: 65:7c:fe:2f:a7:3f:aa:38:46:25:71:f3:32:a2:36:3a:46:fc:e7:02:09:51:71:07:02:cd:fb:b6:ee:da:33:05 +-----BEGIN CERTIFICATE----- +MIIFRzCCAy+gAwIBAgIJEQA0tk7GNi02MA0GCSqGSIb3DQEBCwUAMEExCzAJBgNV +BAYTAlJPMRQwEgYDVQQKEwtDRVJUU0lHTiBTQTEcMBoGA1UECxMTY2VydFNJR04g +Uk9PVCBDQSBHMjAeFw0xNzAyMDYwOTI3MzVaFw00MjAyMDYwOTI3MzVaMEExCzAJ +BgNVBAYTAlJPMRQwEgYDVQQKEwtDRVJUU0lHTiBTQTEcMBoGA1UECxMTY2VydFNJ +R04gUk9PVCBDQSBHMjCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMDF +dRmRfUR0dIf+DjuW3NgBFszuY5HnC2/OOwppGnzC46+CjobXXo9X69MhWf05N0Iw +vlDqtg+piNguLWkh59E3GE59kdUWX2tbAMI5Qw02hVK5U2UPHULlj88F0+7cDBrZ +uIt4ImfkabBoxTzkbFpG583H+u/E7Eu9aqSs/cwoUe+StCmrqzWaTOTECMYmzPhp +n+Sc8CnTXPnGFiWeI8MgwT0PPzhAsP6CRDiqWhqKa2NYOLQV07YRaXseVO6MGiKs +cpc/I1mbySKEwQdPzH/iV8oScLumZfNpdWO9lfsbl83kqK/20U6o2YpxJM02PbyW +xPFsqa7lzw1uKA2wDrXKUXt4FMMgL3/7FFXhEZn91QqhngLjYl/rNUssuHLoPj1P +rCy7Lobio3aP5ZMqz6WryFyNSwb/EkaseMsUBzXgqd+L6a8VTxaJW732jcZZroiF +DsGJ6x9nxUWO/203Nit4ZoORUSs9/1F3dmKh7Gc+PoGD4FapUB8fepmrY7+EF3fx +DTvf95xhszWYijqy7DwaNz9+j5LP2RIUZNoQAhVB/0/E6xyjyfqZ90bp4RjZsbgy +LcsUDFDYg2WD7rlcz8sFWkz6GZdr1l0T08JcVLwyc6B49fFtHsufpaafItzRUZ6C +eWRgKRM+o/1Pcmqr4tTluCRVLERLiohEnMqE0yo7AgMBAAGjQjBAMA8GA1UdEwEB +/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBSCIS1mxteg4BXrzkwJ +d8RgnlRuAzANBgkqhkiG9w0BAQsFAAOCAgEAYN4auOfyYILVAzOBywaK8SJJ6ejq +kX/GM15oGQOGO0MBzwdw5AgeZYWR5hEit/UCI46uuR59H35s5r0l1ZUa8gWmr4UC +b6741jH/JclKyMeKqdmfS0mbEVeZkkMR3rYzpMzXjWR91M08KCy0mpbqTfXERMQl +qiCA2ClV9+BB/AYm/7k29UMUA2Z44RGx2iBfRgB4ACGlHgAoYXhvqAEBj500mv/0 +OJD7uNGzcgbJceaBxXntC6Z58hMLnPddDnskk7RI24Zf3lCGeOdA5jGokHZwYa+c +NywRtYK3qq4kNFtyDGkNzVmf9nGvnAvRCjj5BiKDUyUM/FHE5r7iOZULJK2v0ZXk +ltd0ZGtxTgI8qoXzIKNDOXZbbFD+mpwUHmUUihW9o4JFWklWatKcsWMy5WHgUyIO +pwpJ6st+H6jiYoD2EEVSmAYY3qXNL3+q1Ok+CHLsIwMCPKaq2LxndD0UF/tUSxfj +03k9bWtJySgOLnRQvwzZRjoQhsmnP+mg7H/rpXdYaXHmgwo38oZJar55CJD2AhZk +PuXaTH4MNMn5X7azKFGnpyuqSfqNZSlO42sTp5SjLVFteAxEy9/eCG/Oo2Sr05WE +1LlSVHJ7liXMvGnjSG4N0MedJ5qq+BOS3R7fY581qRY27Iy4g/Q9iY/NtBde17MX +QRBdJ3NghVdJIgc= +-----END CERTIFICATE----- + +# Issuer: CN=Trustwave Global Certification Authority O=Trustwave Holdings, Inc. +# Subject: CN=Trustwave Global Certification Authority O=Trustwave Holdings, Inc. +# Label: "Trustwave Global Certification Authority" +# Serial: 1846098327275375458322922162 +# MD5 Fingerprint: f8:1c:18:2d:2f:ba:5f:6d:a1:6c:bc:c7:ab:91:c7:0e +# SHA1 Fingerprint: 2f:8f:36:4f:e1:58:97:44:21:59:87:a5:2a:9a:d0:69:95:26:7f:b5 +# SHA256 Fingerprint: 97:55:20:15:f5:dd:fc:3c:87:88:c0:06:94:45:55:40:88:94:45:00:84:f1:00:86:70:86:bc:1a:2b:b5:8d:c8 +-----BEGIN CERTIFICATE----- +MIIF2jCCA8KgAwIBAgIMBfcOhtpJ80Y1LrqyMA0GCSqGSIb3DQEBCwUAMIGIMQsw +CQYDVQQGEwJVUzERMA8GA1UECAwISWxsaW5vaXMxEDAOBgNVBAcMB0NoaWNhZ28x +ITAfBgNVBAoMGFRydXN0d2F2ZSBIb2xkaW5ncywgSW5jLjExMC8GA1UEAwwoVHJ1 +c3R3YXZlIEdsb2JhbCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0xNzA4MjMx +OTM0MTJaFw00MjA4MjMxOTM0MTJaMIGIMQswCQYDVQQGEwJVUzERMA8GA1UECAwI +SWxsaW5vaXMxEDAOBgNVBAcMB0NoaWNhZ28xITAfBgNVBAoMGFRydXN0d2F2ZSBI +b2xkaW5ncywgSW5jLjExMC8GA1UEAwwoVHJ1c3R3YXZlIEdsb2JhbCBDZXJ0aWZp +Y2F0aW9uIEF1dGhvcml0eTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIB +ALldUShLPDeS0YLOvR29zd24q88KPuFd5dyqCblXAj7mY2Hf8g+CY66j96xz0Xzn +swuvCAAJWX/NKSqIk4cXGIDtiLK0thAfLdZfVaITXdHG6wZWiYj+rDKd/VzDBcdu +7oaJuogDnXIhhpCujwOl3J+IKMujkkkP7NAP4m1ET4BqstTnoApTAbqOl5F2brz8 +1Ws25kCI1nsvXwXoLG0R8+eyvpJETNKXpP7ScoFDB5zpET71ixpZfR9oWN0EACyW +80OzfpgZdNmcc9kYvkHHNHnZ9GLCQ7mzJ7Aiy/k9UscwR7PJPrhq4ufogXBeQotP +JqX+OsIgbrv4Fo7NDKm0G2x2EOFYeUY+VM6AqFcJNykbmROPDMjWLBz7BegIlT1l +RtzuzWniTY+HKE40Cz7PFNm73bZQmq131BnW2hqIyE4bJ3XYsgjxroMwuREOzYfw +hI0Vcnyh78zyiGG69Gm7DIwLdVcEuE4qFC49DxweMqZiNu5m4iK4BUBjECLzMx10 +coos9TkpoNPnG4CELcU9402x/RpvumUHO1jsQkUm+9jaJXLE9gCxInm943xZYkqc +BW89zubWR2OZxiRvchLIrH+QtAuRcOi35hYQcRfO3gZPSEF9NUqjifLJS3tBEW1n +twiYTOURGa5CgNz7kAXU+FDKvuStx8KU1xad5hePrzb7AgMBAAGjQjBAMA8GA1Ud +EwEB/wQFMAMBAf8wHQYDVR0OBBYEFJngGWcNYtt2s9o9uFvo/ULSMQ6HMA4GA1Ud +DwEB/wQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAgEAmHNw4rDT7TnsTGDZqRKGFx6W +0OhUKDtkLSGm+J1WE2pIPU/HPinbbViDVD2HfSMF1OQc3Og4ZYbFdada2zUFvXfe +uyk3QAUHw5RSn8pk3fEbK9xGChACMf1KaA0HZJDmHvUqoai7PF35owgLEQzxPy0Q +lG/+4jSHg9bP5Rs1bdID4bANqKCqRieCNqcVtgimQlRXtpla4gt5kNdXElE1GYhB +aCXUNxeEFfsBctyV3lImIJgm4nb1J2/6ADtKYdkNy1GTKv0WBpanI5ojSP5RvbbE +sLFUzt5sQa0WZ37b/TjNuThOssFgy50X31ieemKyJo90lZvkWx3SD92YHJtZuSPT +MaCm/zjdzyBP6VhWOmfD0faZmZ26NraAL4hHT4a/RDqA5Dccprrql5gR0IRiR2Qe +qu5AvzSxnI9O4fKSTx+O856X3vOmeWqJcU9LJxdI/uz0UA9PSX3MReO9ekDFQdxh +VicGaeVyQYHTtgGJoC86cnn+OjC/QezHYj6RS8fZMXZC+fc8Y+wmjHMMfRod6qh8 +h6jCJ3zhM0EPz8/8AKAigJ5Kp28AsEFFtyLKaEjFQqKu3R3y4G5OBVixwJAWKqQ9 +EEC+j2Jjg6mcgn0tAumDMHzLJ8n9HmYAsC7TIS+OMxZsmO0QqAfWzJPP29FpHOTK +yeC2nOnOcXHebD8WpHk= +-----END CERTIFICATE----- + +# Issuer: CN=Trustwave Global ECC P256 Certification Authority O=Trustwave Holdings, Inc. +# Subject: CN=Trustwave Global ECC P256 Certification Authority O=Trustwave Holdings, Inc. +# Label: "Trustwave Global ECC P256 Certification Authority" +# Serial: 4151900041497450638097112925 +# MD5 Fingerprint: 5b:44:e3:8d:5d:36:86:26:e8:0d:05:d2:59:a7:83:54 +# SHA1 Fingerprint: b4:90:82:dd:45:0c:be:8b:5b:b1:66:d3:e2:a4:08:26:cd:ed:42:cf +# SHA256 Fingerprint: 94:5b:bc:82:5e:a5:54:f4:89:d1:fd:51:a7:3d:df:2e:a6:24:ac:70:19:a0:52:05:22:5c:22:a7:8c:cf:a8:b4 +-----BEGIN CERTIFICATE----- +MIICYDCCAgegAwIBAgIMDWpfCD8oXD5Rld9dMAoGCCqGSM49BAMCMIGRMQswCQYD +VQQGEwJVUzERMA8GA1UECBMISWxsaW5vaXMxEDAOBgNVBAcTB0NoaWNhZ28xITAf +BgNVBAoTGFRydXN0d2F2ZSBIb2xkaW5ncywgSW5jLjE6MDgGA1UEAxMxVHJ1c3R3 +YXZlIEdsb2JhbCBFQ0MgUDI1NiBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0x +NzA4MjMxOTM1MTBaFw00MjA4MjMxOTM1MTBaMIGRMQswCQYDVQQGEwJVUzERMA8G +A1UECBMISWxsaW5vaXMxEDAOBgNVBAcTB0NoaWNhZ28xITAfBgNVBAoTGFRydXN0 +d2F2ZSBIb2xkaW5ncywgSW5jLjE6MDgGA1UEAxMxVHJ1c3R3YXZlIEdsb2JhbCBF +Q0MgUDI1NiBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTBZMBMGByqGSM49AgEGCCqG +SM49AwEHA0IABH77bOYj43MyCMpg5lOcunSNGLB4kFKA3TjASh3RqMyTpJcGOMoN +FWLGjgEqZZ2q3zSRLoHB5DOSMcT9CTqmP62jQzBBMA8GA1UdEwEB/wQFMAMBAf8w +DwYDVR0PAQH/BAUDAwcGADAdBgNVHQ4EFgQUo0EGrJBt0UrrdaVKEJmzsaGLSvcw +CgYIKoZIzj0EAwIDRwAwRAIgB+ZU2g6gWrKuEZ+Hxbb/ad4lvvigtwjzRM4q3wgh +DDcCIC0mA6AFvWvR9lz4ZcyGbbOcNEhjhAnFjXca4syc4XR7 +-----END CERTIFICATE----- + +# Issuer: CN=Trustwave Global ECC P384 Certification Authority O=Trustwave Holdings, Inc. +# Subject: CN=Trustwave Global ECC P384 Certification Authority O=Trustwave Holdings, Inc. +# Label: "Trustwave Global ECC P384 Certification Authority" +# Serial: 2704997926503831671788816187 +# MD5 Fingerprint: ea:cf:60:c4:3b:b9:15:29:40:a1:97:ed:78:27:93:d6 +# SHA1 Fingerprint: e7:f3:a3:c8:cf:6f:c3:04:2e:6d:0e:67:32:c5:9e:68:95:0d:5e:d2 +# SHA256 Fingerprint: 55:90:38:59:c8:c0:c3:eb:b8:75:9e:ce:4e:25:57:22:5f:f5:75:8b:bd:38:eb:d4:82:76:60:1e:1b:d5:80:97 +-----BEGIN CERTIFICATE----- +MIICnTCCAiSgAwIBAgIMCL2Fl2yZJ6SAaEc7MAoGCCqGSM49BAMDMIGRMQswCQYD +VQQGEwJVUzERMA8GA1UECBMISWxsaW5vaXMxEDAOBgNVBAcTB0NoaWNhZ28xITAf +BgNVBAoTGFRydXN0d2F2ZSBIb2xkaW5ncywgSW5jLjE6MDgGA1UEAxMxVHJ1c3R3 +YXZlIEdsb2JhbCBFQ0MgUDM4NCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0x +NzA4MjMxOTM2NDNaFw00MjA4MjMxOTM2NDNaMIGRMQswCQYDVQQGEwJVUzERMA8G +A1UECBMISWxsaW5vaXMxEDAOBgNVBAcTB0NoaWNhZ28xITAfBgNVBAoTGFRydXN0 +d2F2ZSBIb2xkaW5ncywgSW5jLjE6MDgGA1UEAxMxVHJ1c3R3YXZlIEdsb2JhbCBF +Q0MgUDM4NCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTB2MBAGByqGSM49AgEGBSuB +BAAiA2IABGvaDXU1CDFHBa5FmVXxERMuSvgQMSOjfoPTfygIOiYaOs+Xgh+AtycJ +j9GOMMQKmw6sWASr9zZ9lCOkmwqKi6vr/TklZvFe/oyujUF5nQlgziip04pt89ZF +1PKYhDhloKNDMEEwDwYDVR0TAQH/BAUwAwEB/zAPBgNVHQ8BAf8EBQMDBwYAMB0G +A1UdDgQWBBRVqYSJ0sEyvRjLbKYHTsjnnb6CkDAKBggqhkjOPQQDAwNnADBkAjA3 +AZKXRRJ+oPM+rRk6ct30UJMDEr5E0k9BpIycnR+j9sKS50gU/k6bpZFXrsY3crsC +MGclCrEMXu6pY5Jv5ZAL/mYiykf9ijH3g/56vxC+GCsej/YpHpRZ744hN8tRmKVu +Sw== +-----END CERTIFICATE----- + +# Issuer: CN=NAVER Global Root Certification Authority O=NAVER BUSINESS PLATFORM Corp. +# Subject: CN=NAVER Global Root Certification Authority O=NAVER BUSINESS PLATFORM Corp. +# Label: "NAVER Global Root Certification Authority" +# Serial: 9013692873798656336226253319739695165984492813 +# MD5 Fingerprint: c8:7e:41:f6:25:3b:f5:09:b3:17:e8:46:3d:bf:d0:9b +# SHA1 Fingerprint: 8f:6b:f2:a9:27:4a:da:14:a0:c4:f4:8e:61:27:f9:c0:1e:78:5d:d1 +# SHA256 Fingerprint: 88:f4:38:dc:f8:ff:d1:fa:8f:42:91:15:ff:e5:f8:2a:e1:e0:6e:0c:70:c3:75:fa:ad:71:7b:34:a4:9e:72:65 +-----BEGIN CERTIFICATE----- +MIIFojCCA4qgAwIBAgIUAZQwHqIL3fXFMyqxQ0Rx+NZQTQ0wDQYJKoZIhvcNAQEM +BQAwaTELMAkGA1UEBhMCS1IxJjAkBgNVBAoMHU5BVkVSIEJVU0lORVNTIFBMQVRG +T1JNIENvcnAuMTIwMAYDVQQDDClOQVZFUiBHbG9iYWwgUm9vdCBDZXJ0aWZpY2F0 +aW9uIEF1dGhvcml0eTAeFw0xNzA4MTgwODU4NDJaFw0zNzA4MTgyMzU5NTlaMGkx +CzAJBgNVBAYTAktSMSYwJAYDVQQKDB1OQVZFUiBCVVNJTkVTUyBQTEFURk9STSBD +b3JwLjEyMDAGA1UEAwwpTkFWRVIgR2xvYmFsIFJvb3QgQ2VydGlmaWNhdGlvbiBB +dXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC21PGTXLVA +iQqrDZBbUGOukJR0F0Vy1ntlWilLp1agS7gvQnXp2XskWjFlqxcX0TM62RHcQDaH +38dq6SZeWYp34+hInDEW+j6RscrJo+KfziFTowI2MMtSAuXaMl3Dxeb57hHHi8lE +HoSTGEq0n+USZGnQJoViAbbJAh2+g1G7XNr4rRVqmfeSVPc0W+m/6imBEtRTkZaz +kVrd/pBzKPswRrXKCAfHcXLJZtM0l/aM9BhK4dA9WkW2aacp+yPOiNgSnABIqKYP +szuSjXEOdMWLyEz59JuOuDxp7W87UC9Y7cSw0BwbagzivESq2M0UXZR4Yb8Obtoq +vC8MC3GmsxY/nOb5zJ9TNeIDoKAYv7vxvvTWjIcNQvcGufFt7QSUqP620wbGQGHf +nZ3zVHbOUzoBppJB7ASjjw2i1QnK1sua8e9DXcCrpUHPXFNwcMmIpi3Ua2FzUCaG +YQ5fG8Ir4ozVu53BA0K6lNpfqbDKzE0K70dpAy8i+/Eozr9dUGWokG2zdLAIx6yo +0es+nPxdGoMuK8u180SdOqcXYZaicdNwlhVNt0xz7hlcxVs+Qf6sdWA7G2POAN3a +CJBitOUt7kinaxeZVL6HSuOpXgRM6xBtVNbv8ejyYhbLgGvtPe31HzClrkvJE+2K +AQHJuFFYwGY6sWZLxNUxAmLpdIQM201GLQIDAQABo0IwQDAdBgNVHQ4EFgQU0p+I +36HNLL3s9TsBAZMzJ7LrYEswDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMB +Af8wDQYJKoZIhvcNAQEMBQADggIBADLKgLOdPVQG3dLSLvCkASELZ0jKbY7gyKoN +qo0hV4/GPnrK21HUUrPUloSlWGB/5QuOH/XcChWB5Tu2tyIvCZwTFrFsDDUIbatj +cu3cvuzHV+YwIHHW1xDBE1UBjCpD5EHxzzp6U5LOogMFDTjfArsQLtk70pt6wKGm ++LUx5vR1yblTmXVHIloUFcd4G7ad6Qz4G3bxhYTeodoS76TiEJd6eN4MUZeoIUCL +hr0N8F5OSza7OyAfikJW4Qsav3vQIkMsRIz75Sq0bBwcupTgE34h5prCy8VCZLQe +lHsIJchxzIdFV4XTnyliIoNRlwAYl3dqmJLJfGBs32x9SuRwTMKeuB330DTHD8z7 +p/8Dvq1wkNoL3chtl1+afwkyQf3NosxabUzyqkn+Zvjp2DXrDige7kgvOtB5CTh8 +piKCk5XQA76+AqAF3SAi428diDRgxuYKuQl1C/AH6GmWNcf7I4GOODm4RStDeKLR +LBT/DShycpWbXgnbiUSYqqFJu3FS8r/2/yehNq+4tneI3TqkbZs0kNwUXTC/t+sX +5Ie3cdCh13cV1ELX8vMxmV2b3RZtP+oGI/hGoiLtk/bdmuYqh7GYVPEi92tF4+KO +dh2ajcQGjTa3FPOdVGm3jjzVpG2Tgbet9r1ke8LJaDmgkpzNNIaRkPpkUZ3+/uul +9XXeifdy +-----END CERTIFICATE----- + +# Issuer: CN=AC RAIZ FNMT-RCM SERVIDORES SEGUROS O=FNMT-RCM OU=Ceres +# Subject: CN=AC RAIZ FNMT-RCM SERVIDORES SEGUROS O=FNMT-RCM OU=Ceres +# Label: "AC RAIZ FNMT-RCM SERVIDORES SEGUROS" +# Serial: 131542671362353147877283741781055151509 +# MD5 Fingerprint: 19:36:9c:52:03:2f:d2:d1:bb:23:cc:dd:1e:12:55:bb +# SHA1 Fingerprint: 62:ff:d9:9e:c0:65:0d:03:ce:75:93:d2:ed:3f:2d:32:c9:e3:e5:4a +# SHA256 Fingerprint: 55:41:53:b1:3d:2c:f9:dd:b7:53:bf:be:1a:4e:0a:e0:8d:0a:a4:18:70:58:fe:60:a2:b8:62:b2:e4:b8:7b:cb +-----BEGIN CERTIFICATE----- +MIICbjCCAfOgAwIBAgIQYvYybOXE42hcG2LdnC6dlTAKBggqhkjOPQQDAzB4MQsw +CQYDVQQGEwJFUzERMA8GA1UECgwIRk5NVC1SQ00xDjAMBgNVBAsMBUNlcmVzMRgw +FgYDVQRhDA9WQVRFUy1RMjgyNjAwNEoxLDAqBgNVBAMMI0FDIFJBSVogRk5NVC1S +Q00gU0VSVklET1JFUyBTRUdVUk9TMB4XDTE4MTIyMDA5MzczM1oXDTQzMTIyMDA5 +MzczM1oweDELMAkGA1UEBhMCRVMxETAPBgNVBAoMCEZOTVQtUkNNMQ4wDAYDVQQL +DAVDZXJlczEYMBYGA1UEYQwPVkFURVMtUTI4MjYwMDRKMSwwKgYDVQQDDCNBQyBS +QUlaIEZOTVQtUkNNIFNFUlZJRE9SRVMgU0VHVVJPUzB2MBAGByqGSM49AgEGBSuB +BAAiA2IABPa6V1PIyqvfNkpSIeSX0oNnnvBlUdBeh8dHsVnyV0ebAAKTRBdp20LH +sbI6GA60XYyzZl2hNPk2LEnb80b8s0RpRBNm/dfF/a82Tc4DTQdxz69qBdKiQ1oK +Um8BA06Oi6NCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYD +VR0OBBYEFAG5L++/EYZg8k/QQW6rcx/n0m5JMAoGCCqGSM49BAMDA2kAMGYCMQCu +SuMrQMN0EfKVrRYj3k4MGuZdpSRea0R7/DjiT8ucRRcRTBQnJlU5dUoDzBOQn5IC +MQD6SmxgiHPz7riYYqnOK8LZiqZwMR2vsJRM60/G49HzYqc8/5MuB1xJAWdpEgJy +v+c= +-----END CERTIFICATE----- + +# Issuer: CN=GlobalSign Root R46 O=GlobalSign nv-sa +# Subject: CN=GlobalSign Root R46 O=GlobalSign nv-sa +# Label: "GlobalSign Root R46" +# Serial: 1552617688466950547958867513931858518042577 +# MD5 Fingerprint: c4:14:30:e4:fa:66:43:94:2a:6a:1b:24:5f:19:d0:ef +# SHA1 Fingerprint: 53:a2:b0:4b:ca:6b:d6:45:e6:39:8a:8e:c4:0d:d2:bf:77:c3:a2:90 +# SHA256 Fingerprint: 4f:a3:12:6d:8d:3a:11:d1:c4:85:5a:4f:80:7c:ba:d6:cf:91:9d:3a:5a:88:b0:3b:ea:2c:63:72:d9:3c:40:c9 +-----BEGIN CERTIFICATE----- +MIIFWjCCA0KgAwIBAgISEdK7udcjGJ5AXwqdLdDfJWfRMA0GCSqGSIb3DQEBDAUA +MEYxCzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMRwwGgYD +VQQDExNHbG9iYWxTaWduIFJvb3QgUjQ2MB4XDTE5MDMyMDAwMDAwMFoXDTQ2MDMy +MDAwMDAwMFowRjELMAkGA1UEBhMCQkUxGTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYt +c2ExHDAaBgNVBAMTE0dsb2JhbFNpZ24gUm9vdCBSNDYwggIiMA0GCSqGSIb3DQEB +AQUAA4ICDwAwggIKAoICAQCsrHQy6LNl5brtQyYdpokNRbopiLKkHWPd08EsCVeJ +OaFV6Wc0dwxu5FUdUiXSE2te4R2pt32JMl8Nnp8semNgQB+msLZ4j5lUlghYruQG +vGIFAha/r6gjA7aUD7xubMLL1aa7DOn2wQL7Id5m3RerdELv8HQvJfTqa1VbkNud +316HCkD7rRlr+/fKYIje2sGP1q7Vf9Q8g+7XFkyDRTNrJ9CG0Bwta/OrffGFqfUo +0q3v84RLHIf8E6M6cqJaESvWJ3En7YEtbWaBkoe0G1h6zD8K+kZPTXhc+CtI4wSE +y132tGqzZfxCnlEmIyDLPRT5ge1lFgBPGmSXZgjPjHvjK8Cd+RTyG/FWaha/LIWF +zXg4mutCagI0GIMXTpRW+LaCtfOW3T3zvn8gdz57GSNrLNRyc0NXfeD412lPFzYE ++cCQYDdF3uYM2HSNrpyibXRdQr4G9dlkbgIQrImwTDsHTUB+JMWKmIJ5jqSngiCN +I/onccnfxkF0oE32kRbcRoxfKWMxWXEM2G/CtjJ9++ZdU6Z+Ffy7dXxd7Pj2Fxzs +x2sZy/N78CsHpdlseVR2bJ0cpm4O6XkMqCNqo98bMDGfsVR7/mrLZqrcZdCinkqa +ByFrgY/bxFn63iLABJzjqls2k+g9vXqhnQt2sQvHnf3PmKgGwvgqo6GDoLclcqUC +4wIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNV +HQ4EFgQUA1yrc4GHqMywptWU4jaWSf8FmSwwDQYJKoZIhvcNAQEMBQADggIBAHx4 +7PYCLLtbfpIrXTncvtgdokIzTfnvpCo7RGkerNlFo048p9gkUbJUHJNOxO97k4Vg +JuoJSOD1u8fpaNK7ajFxzHmuEajwmf3lH7wvqMxX63bEIaZHU1VNaL8FpO7XJqti +2kM3S+LGteWygxk6x9PbTZ4IevPuzz5i+6zoYMzRx6Fcg0XERczzF2sUyQQCPtIk +pnnpHs6i58FZFZ8d4kuaPp92CC1r2LpXFNqD6v6MVenQTqnMdzGxRBF6XLE+0xRF +FRhiJBPSy03OXIPBNvIQtQ6IbbjhVp+J3pZmOUdkLG5NrmJ7v2B0GbhWrJKsFjLt +rWhV/pi60zTe9Mlhww6G9kuEYO4Ne7UyWHmRVSyBQ7N0H3qqJZ4d16GLuc1CLgSk +ZoNNiTW2bKg2SnkheCLQQrzRQDGQob4Ez8pn7fXwgNNgyYMqIgXQBztSvwyeqiv5 +u+YfjyW6hY0XHgL+XVAEV8/+LbzvXMAaq7afJMbfc2hIkCwU9D9SGuTSyxTDYWnP +4vkYxboznxSjBF25cfe1lNj2M8FawTSLfJvdkzrnE6JwYZ+vj+vYxXX4M2bUdGc6 +N3ec592kD3ZDZopD8p/7DEJ4Y9HiD2971KE9dJeFt0g5QdYg/NA6s/rob8SKunE3 +vouXsXgxT7PntgMTzlSdriVZzH81Xwj3QEUxeCp6 +-----END CERTIFICATE----- + +# Issuer: CN=GlobalSign Root E46 O=GlobalSign nv-sa +# Subject: CN=GlobalSign Root E46 O=GlobalSign nv-sa +# Label: "GlobalSign Root E46" +# Serial: 1552617690338932563915843282459653771421763 +# MD5 Fingerprint: b5:b8:66:ed:de:08:83:e3:c9:e2:01:34:06:ac:51:6f +# SHA1 Fingerprint: 39:b4:6c:d5:fe:80:06:eb:e2:2f:4a:bb:08:33:a0:af:db:b9:dd:84 +# SHA256 Fingerprint: cb:b9:c4:4d:84:b8:04:3e:10:50:ea:31:a6:9f:51:49:55:d7:bf:d2:e2:c6:b4:93:01:01:9a:d6:1d:9f:50:58 +-----BEGIN CERTIFICATE----- +MIICCzCCAZGgAwIBAgISEdK7ujNu1LzmJGjFDYQdmOhDMAoGCCqGSM49BAMDMEYx +CzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMRwwGgYDVQQD +ExNHbG9iYWxTaWduIFJvb3QgRTQ2MB4XDTE5MDMyMDAwMDAwMFoXDTQ2MDMyMDAw +MDAwMFowRjELMAkGA1UEBhMCQkUxGTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2Ex +HDAaBgNVBAMTE0dsb2JhbFNpZ24gUm9vdCBFNDYwdjAQBgcqhkjOPQIBBgUrgQQA +IgNiAAScDrHPt+ieUnd1NPqlRqetMhkytAepJ8qUuwzSChDH2omwlwxwEwkBjtjq +R+q+soArzfwoDdusvKSGN+1wCAB16pMLey5SnCNoIwZD7JIvU4Tb+0cUB+hflGdd +yXqBPCCjQjBAMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1Ud +DgQWBBQxCpCPtsad0kRLgLWi5h+xEk8blTAKBggqhkjOPQQDAwNoADBlAjEA31SQ +7Zvvi5QCkxeCmb6zniz2C5GMn0oUsfZkvLtoURMMA/cVi4RguYv/Uo7njLwcAjA8 ++RHUjE7AwWHCFUyqqx0LMV87HOIAl0Qx5v5zli/altP+CAezNIm8BZ/3Hobui3A= +-----END CERTIFICATE----- + +# Issuer: CN=GLOBALTRUST 2020 O=e-commerce monitoring GmbH +# Subject: CN=GLOBALTRUST 2020 O=e-commerce monitoring GmbH +# Label: "GLOBALTRUST 2020" +# Serial: 109160994242082918454945253 +# MD5 Fingerprint: 8a:c7:6f:cb:6d:e3:cc:a2:f1:7c:83:fa:0e:78:d7:e8 +# SHA1 Fingerprint: d0:67:c1:13:51:01:0c:aa:d0:c7:6a:65:37:31:16:26:4f:53:71:a2 +# SHA256 Fingerprint: 9a:29:6a:51:82:d1:d4:51:a2:e3:7f:43:9b:74:da:af:a2:67:52:33:29:f9:0f:9a:0d:20:07:c3:34:e2:3c:9a +-----BEGIN CERTIFICATE----- +MIIFgjCCA2qgAwIBAgILWku9WvtPilv6ZeUwDQYJKoZIhvcNAQELBQAwTTELMAkG +A1UEBhMCQVQxIzAhBgNVBAoTGmUtY29tbWVyY2UgbW9uaXRvcmluZyBHbWJIMRkw +FwYDVQQDExBHTE9CQUxUUlVTVCAyMDIwMB4XDTIwMDIxMDAwMDAwMFoXDTQwMDYx +MDAwMDAwMFowTTELMAkGA1UEBhMCQVQxIzAhBgNVBAoTGmUtY29tbWVyY2UgbW9u +aXRvcmluZyBHbWJIMRkwFwYDVQQDExBHTE9CQUxUUlVTVCAyMDIwMIICIjANBgkq +hkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAri5WrRsc7/aVj6B3GyvTY4+ETUWiD59b +RatZe1E0+eyLinjF3WuvvcTfk0Uev5E4C64OFudBc/jbu9G4UeDLgztzOG53ig9Z +YybNpyrOVPu44sB8R85gfD+yc/LAGbaKkoc1DZAoouQVBGM+uq/ufF7MpotQsjj3 +QWPKzv9pj2gOlTblzLmMCcpL3TGQlsjMH/1WljTbjhzqLL6FLmPdqqmV0/0plRPw +yJiT2S0WR5ARg6I6IqIoV6Lr/sCMKKCmfecqQjuCgGOlYx8ZzHyyZqjC0203b+J+ +BlHZRYQfEs4kUmSFC0iAToexIiIwquuuvuAC4EDosEKAA1GqtH6qRNdDYfOiaxaJ +SaSjpCuKAsR49GiKweR6NrFvG5Ybd0mN1MkGco/PU+PcF4UgStyYJ9ORJitHHmkH +r96i5OTUawuzXnzUJIBHKWk7buis/UDr2O1xcSvy6Fgd60GXIsUf1DnQJ4+H4xj0 +4KlGDfV0OoIu0G4skaMxXDtG6nsEEFZegB31pWXogvziB4xiRfUg3kZwhqG8k9Me +dKZssCz3AwyIDMvUclOGvGBG85hqwvG/Q/lwIHfKN0F5VVJjjVsSn8VoxIidrPIw +q7ejMZdnrY8XD2zHc+0klGvIg5rQmjdJBKuxFshsSUktq6HQjJLyQUp5ISXbY9e2 +nKd+Qmn7OmMCAwEAAaNjMGEwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC +AQYwHQYDVR0OBBYEFNwuH9FhN3nkq9XVsxJxaD1qaJwiMB8GA1UdIwQYMBaAFNwu +H9FhN3nkq9XVsxJxaD1qaJwiMA0GCSqGSIb3DQEBCwUAA4ICAQCR8EICaEDuw2jA +VC/f7GLDw56KoDEoqoOOpFaWEhCGVrqXctJUMHytGdUdaG/7FELYjQ7ztdGl4wJC +XtzoRlgHNQIw4Lx0SsFDKv/bGtCwr2zD/cuz9X9tAy5ZVp0tLTWMstZDFyySCstd +6IwPS3BD0IL/qMy/pJTAvoe9iuOTe8aPmxadJ2W8esVCgmxcB9CpwYhgROmYhRZf ++I/KARDOJcP5YBugxZfD0yyIMaK9MOzQ0MAS8cE54+X1+NZK3TTN+2/BT+MAi1bi +kvcoskJ3ciNnxz8RFbLEAwW+uxF7Cr+obuf/WEPPm2eggAe2HcqtbepBEX4tdJP7 +wry+UUTF72glJ4DjyKDUEuzZpTcdN3y0kcra1LGWge9oXHYQSa9+pTeAsRxSvTOB +TI/53WXZFM2KJVj04sWDpQmQ1GwUY7VA3+vA/MRYfg0UFodUJ25W5HCEuGwyEn6C +MUO+1918oa2u1qsgEu8KwxCMSZY13At1XrFP1U80DhEgB3VDRemjEdqso5nCtnkn +4rnvyOL2NSl6dPrFf4IFYqYK6miyeUcGbvJXqBUzxvd4Sj1Ce2t+/vdG6tHrju+I +aFvowdlxfv1k7/9nR4hYJS8+hge9+6jlgqispdNpQ80xiEmEU5LAsTkbOYMBMMTy +qfrQA71yN2BWHzZ8vTmR9W0Nv3vXkg== +-----END CERTIFICATE----- + +# Issuer: CN=ANF Secure Server Root CA O=ANF Autoridad de Certificacion OU=ANF CA Raiz +# Subject: CN=ANF Secure Server Root CA O=ANF Autoridad de Certificacion OU=ANF CA Raiz +# Label: "ANF Secure Server Root CA" +# Serial: 996390341000653745 +# MD5 Fingerprint: 26:a6:44:5a:d9:af:4e:2f:b2:1d:b6:65:b0:4e:e8:96 +# SHA1 Fingerprint: 5b:6e:68:d0:cc:15:b6:a0:5f:1e:c1:5f:ae:02:fc:6b:2f:5d:6f:74 +# SHA256 Fingerprint: fb:8f:ec:75:91:69:b9:10:6b:1e:51:16:44:c6:18:c5:13:04:37:3f:6c:06:43:08:8d:8b:ef:fd:1b:99:75:99 +-----BEGIN CERTIFICATE----- +MIIF7zCCA9egAwIBAgIIDdPjvGz5a7EwDQYJKoZIhvcNAQELBQAwgYQxEjAQBgNV +BAUTCUc2MzI4NzUxMDELMAkGA1UEBhMCRVMxJzAlBgNVBAoTHkFORiBBdXRvcmlk +YWQgZGUgQ2VydGlmaWNhY2lvbjEUMBIGA1UECxMLQU5GIENBIFJhaXoxIjAgBgNV +BAMTGUFORiBTZWN1cmUgU2VydmVyIFJvb3QgQ0EwHhcNMTkwOTA0MTAwMDM4WhcN +MzkwODMwMTAwMDM4WjCBhDESMBAGA1UEBRMJRzYzMjg3NTEwMQswCQYDVQQGEwJF +UzEnMCUGA1UEChMeQU5GIEF1dG9yaWRhZCBkZSBDZXJ0aWZpY2FjaW9uMRQwEgYD +VQQLEwtBTkYgQ0EgUmFpejEiMCAGA1UEAxMZQU5GIFNlY3VyZSBTZXJ2ZXIgUm9v +dCBDQTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBANvrayvmZFSVgpCj +cqQZAZ2cC4Ffc0m6p6zzBE57lgvsEeBbphzOG9INgxwruJ4dfkUyYA8H6XdYfp9q +yGFOtibBTI3/TO80sh9l2Ll49a2pcbnvT1gdpd50IJeh7WhM3pIXS7yr/2WanvtH +2Vdy8wmhrnZEE26cLUQ5vPnHO6RYPUG9tMJJo8gN0pcvB2VSAKduyK9o7PQUlrZX +H1bDOZ8rbeTzPvY1ZNoMHKGESy9LS+IsJJ1tk0DrtSOOMspvRdOoiXsezx76W0OL +zc2oD2rKDF65nkeP8Nm2CgtYZRczuSPkdxl9y0oukntPLxB3sY0vaJxizOBQ+OyR +p1RMVwnVdmPF6GUe7m1qzwmd+nxPrWAI/VaZDxUse6mAq4xhj0oHdkLePfTdsiQz +W7i1o0TJrH93PB0j7IKppuLIBkwC/qxcmZkLLxCKpvR/1Yd0DVlJRfbwcVw5Kda/ +SiOL9V8BY9KHcyi1Swr1+KuCLH5zJTIdC2MKF4EA/7Z2Xue0sUDKIbvVgFHlSFJn +LNJhiQcND85Cd8BEc5xEUKDbEAotlRyBr+Qc5RQe8TZBAQIvfXOn3kLMTOmJDVb3 +n5HUA8ZsyY/b2BzgQJhdZpmYgG4t/wHFzstGH6wCxkPmrqKEPMVOHj1tyRRM4y5B +u8o5vzY8KhmqQYdOpc5LMnndkEl/AgMBAAGjYzBhMB8GA1UdIwQYMBaAFJxf0Gxj +o1+TypOYCK2Mh6UsXME3MB0GA1UdDgQWBBScX9BsY6Nfk8qTmAitjIelLFzBNzAO +BgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOC +AgEATh65isagmD9uw2nAalxJUqzLK114OMHVVISfk/CHGT0sZonrDUL8zPB1hT+L +9IBdeeUXZ701guLyPI59WzbLWoAAKfLOKyzxj6ptBZNscsdW699QIyjlRRA96Gej +rw5VD5AJYu9LWaL2U/HANeQvwSS9eS9OICI7/RogsKQOLHDtdD+4E5UGUcjohybK +pFtqFiGS3XNgnhAY3jyB6ugYw3yJ8otQPr0R4hUDqDZ9MwFsSBXXiJCZBMXM5gf0 +vPSQ7RPi6ovDj6MzD8EpTBNO2hVWcXNyglD2mjN8orGoGjR0ZVzO0eurU+AagNjq +OknkJjCb5RyKqKkVMoaZkgoQI1YS4PbOTOK7vtuNknMBZi9iPrJyJ0U27U1W45eZ +/zo1PqVUSlJZS2Db7v54EX9K3BR5YLZrZAPbFYPhor72I5dQ8AkzNqdxliXzuUJ9 +2zg/LFis6ELhDtjTO0wugumDLmsx2d1Hhk9tl5EuT+IocTUW0fJz/iUrB0ckYyfI ++PbZa/wSMVYIwFNCr5zQM378BvAxRAMU8Vjq8moNqRGyg77FGr8H6lnco4g175x2 +MjxNBiLOFeXdntiP2t7SxDnlF4HPOEfrf4htWRvfn0IUrn7PqLBmZdo3r5+qPeoo +tt7VMVgWglvquxl1AnMaykgaIZOQCo6ThKd9OyMYkomgjaw= +-----END CERTIFICATE----- + +# Issuer: CN=Certum EC-384 CA O=Asseco Data Systems S.A. OU=Certum Certification Authority +# Subject: CN=Certum EC-384 CA O=Asseco Data Systems S.A. OU=Certum Certification Authority +# Label: "Certum EC-384 CA" +# Serial: 160250656287871593594747141429395092468 +# MD5 Fingerprint: b6:65:b3:96:60:97:12:a1:ec:4e:e1:3d:a3:c6:c9:f1 +# SHA1 Fingerprint: f3:3e:78:3c:ac:df:f4:a2:cc:ac:67:55:69:56:d7:e5:16:3c:e1:ed +# SHA256 Fingerprint: 6b:32:80:85:62:53:18:aa:50:d1:73:c9:8d:8b:da:09:d5:7e:27:41:3d:11:4c:f7:87:a0:f5:d0:6c:03:0c:f6 +-----BEGIN CERTIFICATE----- +MIICZTCCAeugAwIBAgIQeI8nXIESUiClBNAt3bpz9DAKBggqhkjOPQQDAzB0MQsw +CQYDVQQGEwJQTDEhMB8GA1UEChMYQXNzZWNvIERhdGEgU3lzdGVtcyBTLkEuMScw +JQYDVQQLEx5DZXJ0dW0gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxGTAXBgNVBAMT +EENlcnR1bSBFQy0zODQgQ0EwHhcNMTgwMzI2MDcyNDU0WhcNNDMwMzI2MDcyNDU0 +WjB0MQswCQYDVQQGEwJQTDEhMB8GA1UEChMYQXNzZWNvIERhdGEgU3lzdGVtcyBT +LkEuMScwJQYDVQQLEx5DZXJ0dW0gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxGTAX +BgNVBAMTEENlcnR1bSBFQy0zODQgQ0EwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAATE +KI6rGFtqvm5kN2PkzeyrOvfMobgOgknXhimfoZTy42B4mIF4Bk3y7JoOV2CDn7Tm +Fy8as10CW4kjPMIRBSqniBMY81CE1700LCeJVf/OTOffph8oxPBUw7l8t1Ot68Kj +QjBAMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFI0GZnQkdjrzife81r1HfS+8 +EF9LMA4GA1UdDwEB/wQEAwIBBjAKBggqhkjOPQQDAwNoADBlAjADVS2m5hjEfO/J +UG7BJw+ch69u1RsIGL2SKcHvlJF40jocVYli5RsJHrpka/F2tNQCMQC0QoSZ/6vn +nvuRlydd3LBbMHHOXjgaatkl5+r3YZJW+OraNsKHZZYuciUvf9/DE8k= +-----END CERTIFICATE----- + +# Issuer: CN=Certum Trusted Root CA O=Asseco Data Systems S.A. OU=Certum Certification Authority +# Subject: CN=Certum Trusted Root CA O=Asseco Data Systems S.A. OU=Certum Certification Authority +# Label: "Certum Trusted Root CA" +# Serial: 40870380103424195783807378461123655149 +# MD5 Fingerprint: 51:e1:c2:e7:fe:4c:84:af:59:0e:2f:f4:54:6f:ea:29 +# SHA1 Fingerprint: c8:83:44:c0:18:ae:9f:cc:f1:87:b7:8f:22:d1:c5:d7:45:84:ba:e5 +# SHA256 Fingerprint: fe:76:96:57:38:55:77:3e:37:a9:5e:7a:d4:d9:cc:96:c3:01:57:c1:5d:31:76:5b:a9:b1:57:04:e1:ae:78:fd +-----BEGIN CERTIFICATE----- +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 +-----END CERTIFICATE----- + +# Issuer: CN=TunTrust Root CA O=Agence Nationale de Certification Electronique +# Subject: CN=TunTrust Root CA O=Agence Nationale de Certification Electronique +# Label: "TunTrust Root CA" +# Serial: 108534058042236574382096126452369648152337120275 +# MD5 Fingerprint: 85:13:b9:90:5b:36:5c:b6:5e:b8:5a:f8:e0:31:57:b4 +# SHA1 Fingerprint: cf:e9:70:84:0f:e0:73:0f:9d:f6:0c:7f:2c:4b:ee:20:46:34:9c:bb +# SHA256 Fingerprint: 2e:44:10:2a:b5:8c:b8:54:19:45:1c:8e:19:d9:ac:f3:66:2c:af:bc:61:4b:6a:53:96:0a:30:f7:d0:e2:eb:41 +-----BEGIN CERTIFICATE----- +MIIFszCCA5ugAwIBAgIUEwLV4kBMkkaGFmddtLu7sms+/BMwDQYJKoZIhvcNAQEL +BQAwYTELMAkGA1UEBhMCVE4xNzA1BgNVBAoMLkFnZW5jZSBOYXRpb25hbGUgZGUg +Q2VydGlmaWNhdGlvbiBFbGVjdHJvbmlxdWUxGTAXBgNVBAMMEFR1blRydXN0IFJv +b3QgQ0EwHhcNMTkwNDI2MDg1NzU2WhcNNDQwNDI2MDg1NzU2WjBhMQswCQYDVQQG +EwJUTjE3MDUGA1UECgwuQWdlbmNlIE5hdGlvbmFsZSBkZSBDZXJ0aWZpY2F0aW9u +IEVsZWN0cm9uaXF1ZTEZMBcGA1UEAwwQVHVuVHJ1c3QgUm9vdCBDQTCCAiIwDQYJ +KoZIhvcNAQEBBQADggIPADCCAgoCggIBAMPN0/y9BFPdDCA61YguBUtB9YOCfvdZ +n56eY+hz2vYGqU8ftPkLHzmMmiDQfgbU7DTZhrx1W4eI8NLZ1KMKsmwb60ksPqxd +2JQDoOw05TDENX37Jk0bbjBU2PWARZw5rZzJJQRNmpA+TkBuimvNKWfGzC3gdOgF +VwpIUPp6Q9p+7FuaDmJ2/uqdHYVy7BG7NegfJ7/Boce7SBbdVtfMTqDhuazb1YMZ +GoXRlJfXyqNlC/M4+QKu3fZnz8k/9YosRxqZbwUN/dAdgjH8KcwAWJeRTIAAHDOF +li/LQcKLEITDCSSJH7UP2dl3RxiSlGBcx5kDPP73lad9UKGAwqmDrViWVSHbhlnU +r8a83YFuB9tgYv7sEG7aaAH0gxupPqJbI9dkxt/con3YS7qC0lH4Zr8GRuR5KiY2 +eY8fTpkdso8MDhz/yV3A/ZAQprE38806JG60hZC/gLkMjNWb1sjxVj8agIl6qeIb +MlEsPvLfe/ZdeikZjuXIvTZxi11Mwh0/rViizz1wTaZQmCXcI/m4WEEIcb9PuISg +jwBUFfyRbVinljvrS5YnzWuioYasDXxU5mZMZl+QviGaAkYt5IPCgLnPSz7ofzwB +7I9ezX/SKEIBlYrilz0QIX32nRzFNKHsLA4KUiwSVXAkPcvCFDVDXSdOvsC9qnyW +5/yeYa1E0wCXAgMBAAGjYzBhMB0GA1UdDgQWBBQGmpsfU33x9aTI04Y+oXNZtPdE +ITAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFAaamx9TffH1pMjThj6hc1m0 +90QhMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAgEAqgVutt0Vyb+z +xiD2BkewhpMl0425yAA/l/VSJ4hxyXT968pk21vvHl26v9Hr7lxpuhbI87mP0zYu +QEkHDVneixCwSQXi/5E/S7fdAo74gShczNxtr18UnH1YeA32gAm56Q6XKRm4t+v4 +FstVEuTGfbvE7Pi1HE4+Z7/FXxttbUcoqgRYYdZ2vyJ/0Adqp2RT8JeNnYA/u8EH +22Wv5psymsNUk8QcCMNE+3tjEUPRahphanltkE8pjkcFwRJpadbGNjHh/PqAulxP +xOu3Mqz4dWEX1xAZufHSCe96Qp1bWgvUxpVOKs7/B9dPfhgGiPEZtdmYu65xxBzn +dFlY7wyJz4sfdZMaBBSSSFCp61cpABbjNhzI+L/wM9VBD8TMPN3pM0MBkRArHtG5 +Xc0yGYuPjCB31yLEQtyEFpslbei0VXF/sHyz03FJuc9SpAQ/3D2gu68zngowYI7b +nV2UqL1g52KAdoGDDIzMMEZJ4gzSqK/rYXHv5yJiqfdcZGyfFoxnNidF9Ql7v/YQ +CvGwjVRDjAS6oz/v4jXH+XTgbzRB0L9zZVcg+ZtnemZoJE6AZb0QmQZZ8mWvuMZH +u/2QeItBcy6vVR/cO5JyboTT0GFMDcx2V+IthSIVNg3rAZ3r2OvEhJn7wAzMMujj +d9qDRIueVSjAi1jTkD5OGwDxFa2DK5o= +-----END CERTIFICATE----- + +# Issuer: CN=HARICA TLS RSA Root CA 2021 O=Hellenic Academic and Research Institutions CA +# Subject: CN=HARICA TLS RSA Root CA 2021 O=Hellenic Academic and Research Institutions CA +# Label: "HARICA TLS RSA Root CA 2021" +# Serial: 76817823531813593706434026085292783742 +# MD5 Fingerprint: 65:47:9b:58:86:dd:2c:f0:fc:a2:84:1f:1e:96:c4:91 +# SHA1 Fingerprint: 02:2d:05:82:fa:88:ce:14:0c:06:79:de:7f:14:10:e9:45:d7:a5:6d +# SHA256 Fingerprint: d9:5d:0e:8e:da:79:52:5b:f9:be:b1:1b:14:d2:10:0d:32:94:98:5f:0c:62:d9:fa:bd:9c:d9:99:ec:cb:7b:1d +-----BEGIN CERTIFICATE----- +MIIFpDCCA4ygAwIBAgIQOcqTHO9D88aOk8f0ZIk4fjANBgkqhkiG9w0BAQsFADBs +MQswCQYDVQQGEwJHUjE3MDUGA1UECgwuSGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJl +c2VhcmNoIEluc3RpdHV0aW9ucyBDQTEkMCIGA1UEAwwbSEFSSUNBIFRMUyBSU0Eg +Um9vdCBDQSAyMDIxMB4XDTIxMDIxOTEwNTUzOFoXDTQ1MDIxMzEwNTUzN1owbDEL +MAkGA1UEBhMCR1IxNzA1BgNVBAoMLkhlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNl +YXJjaCBJbnN0aXR1dGlvbnMgQ0ExJDAiBgNVBAMMG0hBUklDQSBUTFMgUlNBIFJv +b3QgQ0EgMjAyMTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAIvC569l +mwVnlskNJLnQDmT8zuIkGCyEf3dRywQRNrhe7Wlxp57kJQmXZ8FHws+RFjZiPTgE +4VGC/6zStGndLuwRo0Xua2s7TL+MjaQenRG56Tj5eg4MmOIjHdFOY9TnuEFE+2uv +a9of08WRiFukiZLRgeaMOVig1mlDqa2YUlhu2wr7a89o+uOkXjpFc5gH6l8Cct4M +pbOfrqkdtx2z/IpZ525yZa31MJQjB/OCFks1mJxTuy/K5FrZx40d/JiZ+yykgmvw +Kh+OC19xXFyuQnspiYHLA6OZyoieC0AJQTPb5lh6/a6ZcMBaD9YThnEvdmn8kN3b +LW7R8pv1GmuebxWMevBLKKAiOIAkbDakO/IwkfN4E8/BPzWr8R0RI7VDIp4BkrcY +AuUR0YLbFQDMYTfBKnya4dC6s1BG7oKsnTH4+yPiAwBIcKMJJnkVU2DzOFytOOqB +AGMUuTNe3QvboEUHGjMJ+E20pwKmafTCWQWIZYVWrkvL4N48fS0ayOn7H6NhStYq +E613TBoYm5EPWNgGVMWX+Ko/IIqmhaZ39qb8HOLubpQzKoNQhArlT4b4UEV4AIHr +W2jjJo3Me1xR9BQsQL4aYB16cmEdH2MtiKrOokWQCPxrvrNQKlr9qEgYRtaQQJKQ +CoReaDH46+0N0x3GfZkYVVYnZS6NRcUk7M7jAgMBAAGjQjBAMA8GA1UdEwEB/wQF +MAMBAf8wHQYDVR0OBBYEFApII6ZgpJIKM+qTW8VX6iVNvRLuMA4GA1UdDwEB/wQE +AwIBhjANBgkqhkiG9w0BAQsFAAOCAgEAPpBIqm5iFSVmewzVjIuJndftTgfvnNAU +X15QvWiWkKQUEapobQk1OUAJ2vQJLDSle1mESSmXdMgHHkdt8s4cUCbjnj1AUz/3 +f5Z2EMVGpdAgS1D0NTsY9FVqQRtHBmg8uwkIYtlfVUKqrFOFrJVWNlar5AWMxaja +H6NpvVMPxP/cyuN+8kyIhkdGGvMA9YCRotxDQpSbIPDRzbLrLFPCU3hKTwSUQZqP +JzLB5UkZv/HywouoCjkxKLR9YjYsTewfM7Z+d21+UPCfDtcRj88YxeMn/ibvBZ3P +zzfF0HvaO7AWhAw6k9a+F9sPPg4ZeAnHqQJyIkv3N3a6dcSFA1pj1bF1BcK5vZSt +jBWZp5N99sXzqnTPBIWUmAD04vnKJGW/4GKvyMX6ssmeVkjaef2WdhW+o45WxLM0 +/L5H9MG0qPzVMIho7suuyWPEdr6sOBjhXlzPrjoiUevRi7PzKzMHVIf6tLITe7pT +BGIBnfHAT+7hOtSLIBD6Alfm78ELt5BGnBkpjNxvoEppaZS3JGWg/6w/zgH7IS79 +aPib8qXPMThcFarmlwDB31qlpzmq6YR/PFGoOtmUW4y/Twhx5duoXNTSpv4Ao8YW +xw/ogM4cKGR0GQjTQuPOAF1/sdwTsOEFy9EgqoZ0njnnkf3/W9b3raYvAwtt41dU +63ZTGI0RmLo= +-----END CERTIFICATE----- + +# Issuer: CN=HARICA TLS ECC Root CA 2021 O=Hellenic Academic and Research Institutions CA +# Subject: CN=HARICA TLS ECC Root CA 2021 O=Hellenic Academic and Research Institutions CA +# Label: "HARICA TLS ECC Root CA 2021" +# Serial: 137515985548005187474074462014555733966 +# MD5 Fingerprint: ae:f7:4c:e5:66:35:d1:b7:9b:8c:22:93:74:d3:4b:b0 +# SHA1 Fingerprint: bc:b0:c1:9d:e9:98:92:70:19:38:57:e9:8d:a7:b4:5d:6e:ee:01:48 +# SHA256 Fingerprint: 3f:99:cc:47:4a:cf:ce:4d:fe:d5:87:94:66:5e:47:8d:15:47:73:9f:2e:78:0f:1b:b4:ca:9b:13:30:97:d4:01 +-----BEGIN CERTIFICATE----- +MIICVDCCAdugAwIBAgIQZ3SdjXfYO2rbIvT/WeK/zjAKBggqhkjOPQQDAzBsMQsw +CQYDVQQGEwJHUjE3MDUGA1UECgwuSGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJlc2Vh +cmNoIEluc3RpdHV0aW9ucyBDQTEkMCIGA1UEAwwbSEFSSUNBIFRMUyBFQ0MgUm9v +dCBDQSAyMDIxMB4XDTIxMDIxOTExMDExMFoXDTQ1MDIxMzExMDEwOVowbDELMAkG +A1UEBhMCR1IxNzA1BgNVBAoMLkhlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJj +aCBJbnN0aXR1dGlvbnMgQ0ExJDAiBgNVBAMMG0hBUklDQSBUTFMgRUNDIFJvb3Qg +Q0EgMjAyMTB2MBAGByqGSM49AgEGBSuBBAAiA2IABDgI/rGgltJ6rK9JOtDA4MM7 +KKrxcm1lAEeIhPyaJmuqS7psBAqIXhfyVYf8MLA04jRYVxqEU+kw2anylnTDUR9Y +STHMmE5gEYd103KUkE+bECUqqHgtvpBBWJAVcqeht6NCMEAwDwYDVR0TAQH/BAUw +AwEB/zAdBgNVHQ4EFgQUyRtTgRL+BNUW0aq8mm+3oJUZbsowDgYDVR0PAQH/BAQD +AgGGMAoGCCqGSM49BAMDA2cAMGQCMBHervjcToiwqfAircJRQO9gcS3ujwLEXQNw +SaSS6sUUiHCm0w2wqsosQJz76YJumgIwK0eaB8bRwoF8yguWGEEbo/QwCZ61IygN +nxS2PFOiTAZpffpskcYqSUXm7LcT4Tps +-----END CERTIFICATE----- + +# Issuer: CN=Autoridad de Certificacion Firmaprofesional CIF A62634068 +# Subject: CN=Autoridad de Certificacion Firmaprofesional CIF A62634068 +# Label: "Autoridad de Certificacion Firmaprofesional CIF A62634068" +# Serial: 1977337328857672817 +# MD5 Fingerprint: 4e:6e:9b:54:4c:ca:b7:fa:48:e4:90:b1:15:4b:1c:a3 +# SHA1 Fingerprint: 0b:be:c2:27:22:49:cb:39:aa:db:35:5c:53:e3:8c:ae:78:ff:b6:fe +# SHA256 Fingerprint: 57:de:05:83:ef:d2:b2:6e:03:61:da:99:da:9d:f4:64:8d:ef:7e:e8:44:1c:3b:72:8a:fa:9b:cd:e0:f9:b2:6a +-----BEGIN CERTIFICATE----- +MIIGFDCCA/ygAwIBAgIIG3Dp0v+ubHEwDQYJKoZIhvcNAQELBQAwUTELMAkGA1UE +BhMCRVMxQjBABgNVBAMMOUF1dG9yaWRhZCBkZSBDZXJ0aWZpY2FjaW9uIEZpcm1h +cHJvZmVzaW9uYWwgQ0lGIEE2MjYzNDA2ODAeFw0xNDA5MjMxNTIyMDdaFw0zNjA1 +MDUxNTIyMDdaMFExCzAJBgNVBAYTAkVTMUIwQAYDVQQDDDlBdXRvcmlkYWQgZGUg +Q2VydGlmaWNhY2lvbiBGaXJtYXByb2Zlc2lvbmFsIENJRiBBNjI2MzQwNjgwggIi +MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDKlmuO6vj78aI14H9M2uDDUtd9 +thDIAl6zQyrET2qyyhxdKJp4ERppWVevtSBC5IsP5t9bpgOSL/UR5GLXMnE42QQM +cas9UX4PB99jBVzpv5RvwSmCwLTaUbDBPLutN0pcyvFLNg4kq7/DhHf9qFD0sefG +L9ItWY16Ck6WaVICqjaY7Pz6FIMMNx/Jkjd/14Et5cS54D40/mf0PmbR0/RAz15i +NA9wBj4gGFrO93IbJWyTdBSTo3OxDqqHECNZXyAFGUftaI6SEspd/NYrspI8IM/h +X68gvqB2f3bl7BqGYTM+53u0P6APjqK5am+5hyZvQWyIplD9amML9ZMWGxmPsu2b +m8mQ9QEM3xk9Dz44I8kvjwzRAv4bVdZO0I08r0+k8/6vKtMFnXkIoctXMbScyJCy +Z/QYFpM6/EfY0XiWMR+6KwxfXZmtY4laJCB22N/9q06mIqqdXuYnin1oKaPnirja +EbsXLZmdEyRG98Xi2J+Of8ePdG1asuhy9azuJBCtLxTa/y2aRnFHvkLfuwHb9H/T +KI8xWVvTyQKmtFLKbpf7Q8UIJm+K9Lv9nyiqDdVF8xM6HdjAeI9BZzwelGSuewvF +6NkBiDkal4ZkQdU7hwxu+g/GvUgUvzlN1J5Bto+WHWOWk9mVBngxaJ43BjuAiUVh +OSPHG0SjFeUc+JIwuwIDAQABo4HvMIHsMB0GA1UdDgQWBBRlzeurNR4APn7VdMAc +tHNHDhpkLzASBgNVHRMBAf8ECDAGAQH/AgEBMIGmBgNVHSAEgZ4wgZswgZgGBFUd +IAAwgY8wLwYIKwYBBQUHAgEWI2h0dHA6Ly93d3cuZmlybWFwcm9mZXNpb25hbC5j +b20vY3BzMFwGCCsGAQUFBwICMFAeTgBQAGEAcwBlAG8AIABkAGUAIABsAGEAIABC +AG8AbgBhAG4AbwB2AGEAIAA0ADcAIABCAGEAcgBjAGUAbABvAG4AYQAgADAAOAAw +ADEANzAOBgNVHQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQELBQADggIBAHSHKAIrdx9m +iWTtj3QuRhy7qPj4Cx2Dtjqn6EWKB7fgPiDL4QjbEwj4KKE1soCzC1HA01aajTNF +Sa9J8OA9B3pFE1r/yJfY0xgsfZb43aJlQ3CTkBW6kN/oGbDbLIpgD7dvlAceHabJ +hfa9NPhAeGIQcDq+fUs5gakQ1JZBu/hfHAsdCPKxsIl68veg4MSPi3i1O1ilI45P +Vf42O+AMt8oqMEEgtIDNrvx2ZnOorm7hfNoD6JQg5iKj0B+QXSBTFCZX2lSX3xZE +EAEeiGaPcjiT3SC3NL7X8e5jjkd5KAb881lFJWAiMxujX6i6KtoaPc1A6ozuBRWV +1aUsIC+nmCjuRfzxuIgALI9C2lHVnOUTaHFFQ4ueCyE8S1wF3BqfmI7avSKecs2t +CsvMo2ebKHTEm9caPARYpoKdrcd7b/+Alun4jWq9GJAd/0kakFI3ky88Al2CdgtR +5xbHV/g4+afNmyJU72OwFW1TZQNKXkqgsqeOSQBZONXH9IBk9W6VULgRfhVwOEqw +f9DEMnDAGf/JOC0ULGb0QkTmVXYbgBVX/8Cnp6o5qtjTcNAuuuuUavpfNIbnYrX9 +ivAwhZTJryQCL2/W3Wf+47BVTwSYT6RBVuKT0Gro1vP7ZeDOdcQxWQzugsgMYDNK +GbqEZycPvEJdvSRUDewdcAZfpLz6IHxV +-----END CERTIFICATE----- + +# Issuer: CN=vTrus ECC Root CA O=iTrusChina Co.,Ltd. +# Subject: CN=vTrus ECC Root CA O=iTrusChina Co.,Ltd. +# Label: "vTrus ECC Root CA" +# Serial: 630369271402956006249506845124680065938238527194 +# MD5 Fingerprint: de:4b:c1:f5:52:8c:9b:43:e1:3e:8f:55:54:17:8d:85 +# SHA1 Fingerprint: f6:9c:db:b0:fc:f6:02:13:b6:52:32:a6:a3:91:3f:16:70:da:c3:e1 +# SHA256 Fingerprint: 30:fb:ba:2c:32:23:8e:2a:98:54:7a:f9:79:31:e5:50:42:8b:9b:3f:1c:8e:eb:66:33:dc:fa:86:c5:b2:7d:d3 +-----BEGIN CERTIFICATE----- +MIICDzCCAZWgAwIBAgIUbmq8WapTvpg5Z6LSa6Q75m0c1towCgYIKoZIzj0EAwMw +RzELMAkGA1UEBhMCQ04xHDAaBgNVBAoTE2lUcnVzQ2hpbmEgQ28uLEx0ZC4xGjAY +BgNVBAMTEXZUcnVzIEVDQyBSb290IENBMB4XDTE4MDczMTA3MjY0NFoXDTQzMDcz +MTA3MjY0NFowRzELMAkGA1UEBhMCQ04xHDAaBgNVBAoTE2lUcnVzQ2hpbmEgQ28u +LEx0ZC4xGjAYBgNVBAMTEXZUcnVzIEVDQyBSb290IENBMHYwEAYHKoZIzj0CAQYF +K4EEACIDYgAEZVBKrox5lkqqHAjDo6LN/llWQXf9JpRCux3NCNtzslt188+cToL0 +v/hhJoVs1oVbcnDS/dtitN9Ti72xRFhiQgnH+n9bEOf+QP3A2MMrMudwpremIFUd +e4BdS49nTPEQo0IwQDAdBgNVHQ4EFgQUmDnNvtiyjPeyq+GtJK97fKHbH88wDwYD +VR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwCgYIKoZIzj0EAwMDaAAwZQIw +V53dVvHH4+m4SVBrm2nDb+zDfSXkV5UTQJtS0zvzQBm8JsctBp61ezaf9SXUY2sA +AjEA6dPGnlaaKsyh2j/IZivTWJwghfqrkYpwcBE4YGQLYgmRWAD5Tfs0aNoJrSEG +GJTO +-----END CERTIFICATE----- + +# Issuer: CN=vTrus Root CA O=iTrusChina Co.,Ltd. +# Subject: CN=vTrus Root CA O=iTrusChina Co.,Ltd. +# Label: "vTrus Root CA" +# Serial: 387574501246983434957692974888460947164905180485 +# MD5 Fingerprint: b8:c9:37:df:fa:6b:31:84:64:c5:ea:11:6a:1b:75:fc +# SHA1 Fingerprint: 84:1a:69:fb:f5:cd:1a:25:34:13:3d:e3:f8:fc:b8:99:d0:c9:14:b7 +# SHA256 Fingerprint: 8a:71:de:65:59:33:6f:42:6c:26:e5:38:80:d0:0d:88:a1:8d:a4:c6:a9:1f:0d:cb:61:94:e2:06:c5:c9:63:87 +-----BEGIN CERTIFICATE----- +MIIFVjCCAz6gAwIBAgIUQ+NxE9izWRRdt86M/TX9b7wFjUUwDQYJKoZIhvcNAQEL +BQAwQzELMAkGA1UEBhMCQ04xHDAaBgNVBAoTE2lUcnVzQ2hpbmEgQ28uLEx0ZC4x +FjAUBgNVBAMTDXZUcnVzIFJvb3QgQ0EwHhcNMTgwNzMxMDcyNDA1WhcNNDMwNzMx +MDcyNDA1WjBDMQswCQYDVQQGEwJDTjEcMBoGA1UEChMTaVRydXNDaGluYSBDby4s +THRkLjEWMBQGA1UEAxMNdlRydXMgUm9vdCBDQTCCAiIwDQYJKoZIhvcNAQEBBQAD +ggIPADCCAgoCggIBAL1VfGHTuB0EYgWgrmy3cLRB6ksDXhA/kFocizuwZotsSKYc +IrrVQJLuM7IjWcmOvFjai57QGfIvWcaMY1q6n6MLsLOaXLoRuBLpDLvPbmyAhykU +AyyNJJrIZIO1aqwTLDPxn9wsYTwaP3BVm60AUn/PBLn+NvqcwBauYv6WTEN+VRS+ +GrPSbcKvdmaVayqwlHeFXgQPYh1jdfdr58tbmnDsPmcF8P4HCIDPKNsFxhQnL4Z9 +8Cfe/+Z+M0jnCx5Y0ScrUw5XSmXX+6KAYPxMvDVTAWqXcoKv8R1w6Jz1717CbMdH +flqUhSZNO7rrTOiwCcJlwp2dCZtOtZcFrPUGoPc2BX70kLJrxLT5ZOrpGgrIDajt +J8nU57O5q4IikCc9Kuh8kO+8T/3iCiSn3mUkpF3qwHYw03dQ+A0Em5Q2AXPKBlim +0zvc+gRGE1WKyURHuFE5Gi7oNOJ5y1lKCn+8pu8fA2dqWSslYpPZUxlmPCdiKYZN +pGvu/9ROutW04o5IWgAZCfEF2c6Rsffr6TlP9m8EQ5pV9T4FFL2/s1m02I4zhKOQ +UqqzApVg+QxMaPnu1RcN+HFXtSXkKe5lXa/R7jwXC1pDxaWG6iSe4gUH3DRCEpHW +OXSuTEGC2/KmSNGzm/MzqvOmwMVO9fSddmPmAsYiS8GVP1BkLFTltvA8Kc9XAgMB +AAGjQjBAMB0GA1UdDgQWBBRUYnBj8XWEQ1iO0RYgscasGrz2iTAPBgNVHRMBAf8E +BTADAQH/MA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAgEAKbqSSaet +8PFww+SX8J+pJdVrnjT+5hpk9jprUrIQeBqfTNqK2uwcN1LgQkv7bHbKJAs5EhWd +nxEt/Hlk3ODg9d3gV8mlsnZwUKT+twpw1aA08XXXTUm6EdGz2OyC/+sOxL9kLX1j +bhd47F18iMjrjld22VkE+rxSH0Ws8HqA7Oxvdq6R2xCOBNyS36D25q5J08FsEhvM +Kar5CKXiNxTKsbhm7xqC5PD48acWabfbqWE8n/Uxy+QARsIvdLGx14HuqCaVvIiv +TDUHKgLKeBRtRytAVunLKmChZwOgzoy8sHJnxDHO2zTlJQNgJXtxmOTAGytfdELS +S8VZCAeHvsXDf+eW2eHcKJfWjwXj9ZtOyh1QRwVTsMo554WgicEFOwE30z9J4nfr +I8iIZjs9OXYhRvHsXyO466JmdXTBQPfYaJqT4i2pLr0cox7IdMakLXogqzu4sEb9 +b91fUlV1YvCXoHzXOP0l382gmxDPi7g4Xl7FtKYCNqEeXxzP4padKar9mK5S4fNB +UvupLnKWnyfjqnN9+BojZns7q2WwMgFLFT49ok8MKzWixtlnEjUwzXYuFrOZnk1P +Ti07NEPhmg4NpGaXutIcSkwsKouLgU9xGqndXHt7CMUADTdA43x7VF8vhV929ven +sBxXVsFy6K2ir40zSbofitzmdHxghm+Hl3s= +-----END CERTIFICATE----- + +# Issuer: CN=ISRG Root X2 O=Internet Security Research Group +# Subject: CN=ISRG Root X2 O=Internet Security Research Group +# Label: "ISRG Root X2" +# Serial: 87493402998870891108772069816698636114 +# MD5 Fingerprint: d3:9e:c4:1e:23:3c:a6:df:cf:a3:7e:6d:e0:14:e6:e5 +# SHA1 Fingerprint: bd:b1:b9:3c:d5:97:8d:45:c6:26:14:55:f8:db:95:c7:5a:d1:53:af +# SHA256 Fingerprint: 69:72:9b:8e:15:a8:6e:fc:17:7a:57:af:b7:17:1d:fc:64:ad:d2:8c:2f:ca:8c:f1:50:7e:34:45:3c:cb:14:70 +-----BEGIN CERTIFICATE----- +MIICGzCCAaGgAwIBAgIQQdKd0XLq7qeAwSxs6S+HUjAKBggqhkjOPQQDAzBPMQsw +CQYDVQQGEwJVUzEpMCcGA1UEChMgSW50ZXJuZXQgU2VjdXJpdHkgUmVzZWFyY2gg +R3JvdXAxFTATBgNVBAMTDElTUkcgUm9vdCBYMjAeFw0yMDA5MDQwMDAwMDBaFw00 +MDA5MTcxNjAwMDBaME8xCzAJBgNVBAYTAlVTMSkwJwYDVQQKEyBJbnRlcm5ldCBT +ZWN1cml0eSBSZXNlYXJjaCBHcm91cDEVMBMGA1UEAxMMSVNSRyBSb290IFgyMHYw +EAYHKoZIzj0CAQYFK4EEACIDYgAEzZvVn4CDCuwJSvMWSj5cz3es3mcFDR0HttwW ++1qLFNvicWDEukWVEYmO6gbf9yoWHKS5xcUy4APgHoIYOIvXRdgKam7mAHf7AlF9 +ItgKbppbd9/w+kHsOdx1ymgHDB/qo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0T +AQH/BAUwAwEB/zAdBgNVHQ4EFgQUfEKWrt5LSDv6kviejM9ti6lyN5UwCgYIKoZI +zj0EAwMDaAAwZQIwe3lORlCEwkSHRhtFcP9Ymd70/aTSVaYgLXTWNLxBo1BfASdW +tL4ndQavEi51mI38AjEAi/V3bNTIZargCyzuFJ0nN6T5U6VR5CmD1/iQMVtCnwr1 +/q4AaOeMSQ+2b1tbFfLn +-----END CERTIFICATE----- + +# Issuer: CN=HiPKI Root CA - G1 O=Chunghwa Telecom Co., Ltd. +# Subject: CN=HiPKI Root CA - G1 O=Chunghwa Telecom Co., Ltd. +# Label: "HiPKI Root CA - G1" +# Serial: 60966262342023497858655262305426234976 +# MD5 Fingerprint: 69:45:df:16:65:4b:e8:68:9a:8f:76:5f:ff:80:9e:d3 +# SHA1 Fingerprint: 6a:92:e4:a8:ee:1b:ec:96:45:37:e3:29:57:49:cd:96:e3:e5:d2:60 +# SHA256 Fingerprint: f0:15:ce:3c:c2:39:bf:ef:06:4b:e9:f1:d2:c4:17:e1:a0:26:4a:0a:94:be:1f:0c:8d:12:18:64:eb:69:49:cc +-----BEGIN CERTIFICATE----- +MIIFajCCA1KgAwIBAgIQLd2szmKXlKFD6LDNdmpeYDANBgkqhkiG9w0BAQsFADBP +MQswCQYDVQQGEwJUVzEjMCEGA1UECgwaQ2h1bmdod2EgVGVsZWNvbSBDby4sIEx0 +ZC4xGzAZBgNVBAMMEkhpUEtJIFJvb3QgQ0EgLSBHMTAeFw0xOTAyMjIwOTQ2MDRa +Fw0zNzEyMzExNTU5NTlaME8xCzAJBgNVBAYTAlRXMSMwIQYDVQQKDBpDaHVuZ2h3 +YSBUZWxlY29tIENvLiwgTHRkLjEbMBkGA1UEAwwSSGlQS0kgUm9vdCBDQSAtIEcx +MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA9B5/UnMyDHPkvRN0o9Qw +qNCuS9i233VHZvR85zkEHmpwINJaR3JnVfSl6J3VHiGh8Ge6zCFovkRTv4354twv +Vcg3Px+kwJyz5HdcoEb+d/oaoDjq7Zpy3iu9lFc6uux55199QmQ5eiY29yTw1S+6 +lZgRZq2XNdZ1AYDgr/SEYYwNHl98h5ZeQa/rh+r4XfEuiAU+TCK72h8q3VJGZDnz +Qs7ZngyzsHeXZJzA9KMuH5UHsBffMNsAGJZMoYFL3QRtU6M9/Aes1MU3guvklQgZ +KILSQjqj2FPseYlgSGDIcpJQ3AOPgz+yQlda22rpEZfdhSi8MEyr48KxRURHH+CK +FgeW0iEPU8DtqX7UTuybCeyvQqww1r/REEXgphaypcXTT3OUM3ECoWqj1jOXTyFj +HluP2cFeRXF3D4FdXyGarYPM+l7WjSNfGz1BryB1ZlpK9p/7qxj3ccC2HTHsOyDr +y+K49a6SsvfhhEvyovKTmiKe0xRvNlS9H15ZFblzqMF8b3ti6RZsR1pl8w4Rm0bZ +/W3c1pzAtH2lsN0/Vm+h+fbkEkj9Bn8SV7apI09bA8PgcSojt/ewsTu8mL3WmKgM +a/aOEmem8rJY5AIJEzypuxC00jBF8ez3ABHfZfjcK0NVvxaXxA/VLGGEqnKG/uY6 +fsI/fe78LxQ+5oXdUG+3Se0CAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAdBgNV +HQ4EFgQU8ncX+l6o/vY9cdVouslGDDjYr7AwDgYDVR0PAQH/BAQDAgGGMA0GCSqG +SIb3DQEBCwUAA4ICAQBQUfB13HAE4/+qddRxosuej6ip0691x1TPOhwEmSKsxBHi +7zNKpiMdDg1H2DfHb680f0+BazVP6XKlMeJ45/dOlBhbQH3PayFUhuaVevvGyuqc +SE5XCV0vrPSltJczWNWseanMX/mF+lLFjfiRFOs6DRfQUsJ748JzjkZ4Bjgs6Fza +ZsT0pPBWGTMpWmWSBUdGSquEwx4noR8RkpkndZMPvDY7l1ePJlsMu5wP1G4wB9Tc +XzZoZjmDlicmisjEOf6aIW/Vcobpf2Lll07QJNBAsNB1CI69aO4I1258EHBGG3zg +iLKecoaZAeO/n0kZtCW+VmWuF2PlHt/o/0elv+EmBYTksMCv5wiZqAxeJoBF1Pho +L5aPruJKHJwWDBNvOIf2u8g0X5IDUXlwpt/L9ZlNec1OvFefQ05rLisY+GpzjLrF +Ne85akEez3GoorKGB1s6yeHvP2UEgEcyRHCVTjFnanRbEEV16rCf0OY1/k6fi8wr +kkVbbiVghUbN0aqwdmaTd5a+g744tiROJgvM7XpWGuDpWsZkrUx6AEhEL7lAuxM+ +vhV4nYWBSipX3tUZQ9rbyltHhoMLP7YNdnhzeSJesYAfz77RP1YQmCuVh6EfnWQU +YDksswBVLuT1sw5XxJFBAJw/6KXf6vb/yPCtbVKoF6ubYfwSUTXkJf2vqmqGOQ== +-----END CERTIFICATE----- + +# Issuer: CN=GlobalSign O=GlobalSign OU=GlobalSign ECC Root CA - R4 +# Subject: CN=GlobalSign O=GlobalSign OU=GlobalSign ECC Root CA - R4 +# Label: "GlobalSign ECC Root CA - R4" +# Serial: 159662223612894884239637590694 +# MD5 Fingerprint: 26:29:f8:6d:e1:88:bf:a2:65:7f:aa:c4:cd:0f:7f:fc +# SHA1 Fingerprint: 6b:a0:b0:98:e1:71:ef:5a:ad:fe:48:15:80:77:10:f4:bd:6f:0b:28 +# SHA256 Fingerprint: b0:85:d7:0b:96:4f:19:1a:73:e4:af:0d:54:ae:7a:0e:07:aa:fd:af:9b:71:dd:08:62:13:8a:b7:32:5a:24:a2 +-----BEGIN CERTIFICATE----- +MIIB3DCCAYOgAwIBAgINAgPlfvU/k/2lCSGypjAKBggqhkjOPQQDAjBQMSQwIgYD +VQQLExtHbG9iYWxTaWduIEVDQyBSb290IENBIC0gUjQxEzARBgNVBAoTCkdsb2Jh +bFNpZ24xEzARBgNVBAMTCkdsb2JhbFNpZ24wHhcNMTIxMTEzMDAwMDAwWhcNMzgw +MTE5MDMxNDA3WjBQMSQwIgYDVQQLExtHbG9iYWxTaWduIEVDQyBSb290IENBIC0g +UjQxEzARBgNVBAoTCkdsb2JhbFNpZ24xEzARBgNVBAMTCkdsb2JhbFNpZ24wWTAT +BgcqhkjOPQIBBggqhkjOPQMBBwNCAAS4xnnTj2wlDp8uORkcA6SumuU5BwkWymOx +uYb4ilfBV85C+nOh92VC/x7BALJucw7/xyHlGKSq2XE/qNS5zowdo0IwQDAOBgNV +HQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUVLB7rUW44kB/ ++wpu+74zyTyjhNUwCgYIKoZIzj0EAwIDRwAwRAIgIk90crlgr/HmnKAWBVBfw147 +bmF0774BxL4YSFlhgjICICadVGNA3jdgUM/I2O2dgq43mLyjj0xMqTQrbO/7lZsm +-----END CERTIFICATE----- + +# Issuer: CN=GTS Root R1 O=Google Trust Services LLC +# Subject: CN=GTS Root R1 O=Google Trust Services LLC +# Label: "GTS Root R1" +# Serial: 159662320309726417404178440727 +# MD5 Fingerprint: 05:fe:d0:bf:71:a8:a3:76:63:da:01:e0:d8:52:dc:40 +# SHA1 Fingerprint: e5:8c:1c:c4:91:3b:38:63:4b:e9:10:6e:e3:ad:8e:6b:9d:d9:81:4a +# SHA256 Fingerprint: d9:47:43:2a:bd:e7:b7:fa:90:fc:2e:6b:59:10:1b:12:80:e0:e1:c7:e4:e4:0f:a3:c6:88:7f:ff:57:a7:f4:cf +-----BEGIN CERTIFICATE----- +MIIFVzCCAz+gAwIBAgINAgPlk28xsBNJiGuiFzANBgkqhkiG9w0BAQwFADBHMQsw +CQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEU +MBIGA1UEAxMLR1RTIFJvb3QgUjEwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAw +MDAwWjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZp +Y2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjEwggIiMA0GCSqGSIb3DQEBAQUA +A4ICDwAwggIKAoICAQC2EQKLHuOhd5s73L+UPreVp0A8of2C+X0yBoJx9vaMf/vo +27xqLpeXo4xL+Sv2sfnOhB2x+cWX3u+58qPpvBKJXqeqUqv4IyfLpLGcY9vXmX7w +Cl7raKb0xlpHDU0QM+NOsROjyBhsS+z8CZDfnWQpJSMHobTSPS5g4M/SCYe7zUjw +TcLCeoiKu7rPWRnWr4+wB7CeMfGCwcDfLqZtbBkOtdh+JhpFAz2weaSUKK0Pfybl +qAj+lug8aJRT7oM6iCsVlgmy4HqMLnXWnOunVmSPlk9orj2XwoSPwLxAwAtcvfaH +szVsrBhQf4TgTM2S0yDpM7xSma8ytSmzJSq0SPly4cpk9+aCEI3oncKKiPo4Zor8 +Y/kB+Xj9e1x3+naH+uzfsQ55lVe0vSbv1gHR6xYKu44LtcXFilWr06zqkUspzBmk +MiVOKvFlRNACzqrOSbTqn3yDsEB750Orp2yjj32JgfpMpf/VjsPOS+C12LOORc92 +wO1AK/1TD7Cn1TsNsYqiA94xrcx36m97PtbfkSIS5r762DL8EGMUUXLeXdYWk70p +aDPvOmbsB4om3xPXV2V4J95eSRQAogB/mqghtqmxlbCluQ0WEdrHbEg8QOB+DVrN +VjzRlwW5y0vtOUucxD/SVRNuJLDWcfr0wbrM7Rv1/oFB2ACYPTrIrnqYNxgFlQID +AQABo0IwQDAOBgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4E +FgQU5K8rJnEaK0gnhS9SZizv8IkTcT4wDQYJKoZIhvcNAQEMBQADggIBAJ+qQibb +C5u+/x6Wki4+omVKapi6Ist9wTrYggoGxval3sBOh2Z5ofmmWJyq+bXmYOfg6LEe +QkEzCzc9zolwFcq1JKjPa7XSQCGYzyI0zzvFIoTgxQ6KfF2I5DUkzps+GlQebtuy +h6f88/qBVRRiClmpIgUxPoLW7ttXNLwzldMXG+gnoot7TiYaelpkttGsN/H9oPM4 +7HLwEXWdyzRSjeZ2axfG34arJ45JK3VmgRAhpuo+9K4l/3wV3s6MJT/KYnAK9y8J +ZgfIPxz88NtFMN9iiMG1D53Dn0reWVlHxYciNuaCp+0KueIHoI17eko8cdLiA6Ef +MgfdG+RCzgwARWGAtQsgWSl4vflVy2PFPEz0tv/bal8xa5meLMFrUKTX5hgUvYU/ +Z6tGn6D/Qqc6f1zLXbBwHSs09dR2CQzreExZBfMzQsNhFRAbd03OIozUhfJFfbdT +6u9AWpQKXCBfTkBdYiJ23//OYb2MI3jSNwLgjt7RETeJ9r/tSQdirpLsQBqvFAnZ +0E6yove+7u7Y/9waLd64NnHi/Hm3lCXRSHNboTXns5lndcEZOitHTtNCjv0xyBZm +2tIMPNuzjsmhDYAPexZ3FL//2wmUspO8IFgV6dtxQ/PeEMMA3KgqlbbC1j+Qa3bb +bP6MvPJwNQzcmRk13NfIRmPVNnGuV/u3gm3c +-----END CERTIFICATE----- + +# Issuer: CN=GTS Root R2 O=Google Trust Services LLC +# Subject: CN=GTS Root R2 O=Google Trust Services LLC +# Label: "GTS Root R2" +# Serial: 159662449406622349769042896298 +# MD5 Fingerprint: 1e:39:c0:53:e6:1e:29:82:0b:ca:52:55:36:5d:57:dc +# SHA1 Fingerprint: 9a:44:49:76:32:db:de:fa:d0:bc:fb:5a:7b:17:bd:9e:56:09:24:94 +# SHA256 Fingerprint: 8d:25:cd:97:22:9d:bf:70:35:6b:da:4e:b3:cc:73:40:31:e2:4c:f0:0f:af:cf:d3:2d:c7:6e:b5:84:1c:7e:a8 +-----BEGIN CERTIFICATE----- +MIIFVzCCAz+gAwIBAgINAgPlrsWNBCUaqxElqjANBgkqhkiG9w0BAQwFADBHMQsw +CQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEU +MBIGA1UEAxMLR1RTIFJvb3QgUjIwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAw +MDAwWjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZp +Y2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjIwggIiMA0GCSqGSIb3DQEBAQUA +A4ICDwAwggIKAoICAQDO3v2m++zsFDQ8BwZabFn3GTXd98GdVarTzTukk3LvCvpt +nfbwhYBboUhSnznFt+4orO/LdmgUud+tAWyZH8QiHZ/+cnfgLFuv5AS/T3KgGjSY +6Dlo7JUle3ah5mm5hRm9iYz+re026nO8/4Piy33B0s5Ks40FnotJk9/BW9BuXvAu +MC6C/Pq8tBcKSOWIm8Wba96wyrQD8Nr0kLhlZPdcTK3ofmZemde4wj7I0BOdre7k +RXuJVfeKH2JShBKzwkCX44ofR5GmdFrS+LFjKBC4swm4VndAoiaYecb+3yXuPuWg +f9RhD1FLPD+M2uFwdNjCaKH5wQzpoeJ/u1U8dgbuak7MkogwTZq9TwtImoS1mKPV ++3PBV2HdKFZ1E66HjucMUQkQdYhMvI35ezzUIkgfKtzra7tEscszcTJGr61K8Yzo +dDqs5xoic4DSMPclQsciOzsSrZYuxsN2B6ogtzVJV+mSSeh2FnIxZyuWfoqjx5RW +Ir9qS34BIbIjMt/kmkRtWVtd9QCgHJvGeJeNkP+byKq0rxFROV7Z+2et1VsRnTKa +G73VululycslaVNVJ1zgyjbLiGH7HrfQy+4W+9OmTN6SpdTi3/UGVN4unUu0kzCq +gc7dGtxRcw1PcOnlthYhGXmy5okLdWTK1au8CcEYof/UVKGFPP0UJAOyh9OktwID +AQABo0IwQDAOBgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4E +FgQUu//KjiOfT5nK2+JopqUVJxce2Q4wDQYJKoZIhvcNAQEMBQADggIBAB/Kzt3H +vqGf2SdMC9wXmBFqiN495nFWcrKeGk6c1SuYJF2ba3uwM4IJvd8lRuqYnrYb/oM8 +0mJhwQTtzuDFycgTE1XnqGOtjHsB/ncw4c5omwX4Eu55MaBBRTUoCnGkJE+M3DyC +B19m3H0Q/gxhswWV7uGugQ+o+MePTagjAiZrHYNSVc61LwDKgEDg4XSsYPWHgJ2u +NmSRXbBoGOqKYcl3qJfEycel/FVL8/B/uWU9J2jQzGv6U53hkRrJXRqWbTKH7QMg +yALOWr7Z6v2yTcQvG99fevX4i8buMTolUVVnjWQye+mew4K6Ki3pHrTgSAai/Gev +HyICc/sgCq+dVEuhzf9gR7A/Xe8bVr2XIZYtCtFenTgCR2y59PYjJbigapordwj6 +xLEokCZYCDzifqrXPW+6MYgKBesntaFJ7qBFVHvmJ2WZICGoo7z7GJa7Um8M7YNR +TOlZ4iBgxcJlkoKM8xAfDoqXvneCbT+PHV28SSe9zE8P4c52hgQjxcCMElv924Sg +JPFI/2R80L5cFtHvma3AH/vLrrw4IgYmZNralw4/KBVEqE8AyvCazM90arQ+POuV +7LXTWtiBmelDGDfrs7vRWGJB82bSj6p4lVQgw1oudCvV0b4YacCs1aTPObpRhANl +6WLAYv7YTVWW4tAR+kg0Eeye7QUd5MjWHYbL +-----END CERTIFICATE----- + +# Issuer: CN=GTS Root R3 O=Google Trust Services LLC +# Subject: CN=GTS Root R3 O=Google Trust Services LLC +# Label: "GTS Root R3" +# Serial: 159662495401136852707857743206 +# MD5 Fingerprint: 3e:e7:9d:58:02:94:46:51:94:e5:e0:22:4a:8b:e7:73 +# SHA1 Fingerprint: ed:e5:71:80:2b:c8:92:b9:5b:83:3c:d2:32:68:3f:09:cd:a0:1e:46 +# SHA256 Fingerprint: 34:d8:a7:3e:e2:08:d9:bc:db:0d:95:65:20:93:4b:4e:40:e6:94:82:59:6e:8b:6f:73:c8:42:6b:01:0a:6f:48 +-----BEGIN CERTIFICATE----- +MIICCTCCAY6gAwIBAgINAgPluILrIPglJ209ZjAKBggqhkjOPQQDAzBHMQswCQYD +VQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEUMBIG +A1UEAxMLR1RTIFJvb3QgUjMwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAwMDAw +WjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2Vz +IExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjMwdjAQBgcqhkjOPQIBBgUrgQQAIgNi +AAQfTzOHMymKoYTey8chWEGJ6ladK0uFxh1MJ7x/JlFyb+Kf1qPKzEUURout736G +jOyxfi//qXGdGIRFBEFVbivqJn+7kAHjSxm65FSWRQmx1WyRRK2EE46ajA2ADDL2 +4CejQjBAMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQW +BBTB8Sa6oC2uhYHP0/EqEr24Cmf9vDAKBggqhkjOPQQDAwNpADBmAjEA9uEglRR7 +VKOQFhG/hMjqb2sXnh5GmCCbn9MN2azTL818+FsuVbu/3ZL3pAzcMeGiAjEA/Jdm +ZuVDFhOD3cffL74UOO0BzrEXGhF16b0DjyZ+hOXJYKaV11RZt+cRLInUue4X +-----END CERTIFICATE----- + +# Issuer: CN=GTS Root R4 O=Google Trust Services LLC +# Subject: CN=GTS Root R4 O=Google Trust Services LLC +# Label: "GTS Root R4" +# Serial: 159662532700760215368942768210 +# MD5 Fingerprint: 43:96:83:77:19:4d:76:b3:9d:65:52:e4:1d:22:a5:e8 +# SHA1 Fingerprint: 77:d3:03:67:b5:e0:0c:15:f6:0c:38:61:df:7c:e1:3b:92:46:4d:47 +# SHA256 Fingerprint: 34:9d:fa:40:58:c5:e2:63:12:3b:39:8a:e7:95:57:3c:4e:13:13:c8:3f:e6:8f:93:55:6c:d5:e8:03:1b:3c:7d +-----BEGIN CERTIFICATE----- +MIICCTCCAY6gAwIBAgINAgPlwGjvYxqccpBQUjAKBggqhkjOPQQDAzBHMQswCQYD +VQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEUMBIG +A1UEAxMLR1RTIFJvb3QgUjQwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAwMDAw +WjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2Vz +IExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjQwdjAQBgcqhkjOPQIBBgUrgQQAIgNi +AATzdHOnaItgrkO4NcWBMHtLSZ37wWHO5t5GvWvVYRg1rkDdc/eJkTBa6zzuhXyi +QHY7qca4R9gq55KRanPpsXI5nymfopjTX15YhmUPoYRlBtHci8nHc8iMai/lxKvR +HYqjQjBAMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQW +BBSATNbrdP9JNqPV2Py1PsVq8JQdjDAKBggqhkjOPQQDAwNpADBmAjEA6ED/g94D +9J+uHXqnLrmvT/aDHQ4thQEd0dlq7A/Cr8deVl5c1RxYIigL9zC2L7F8AjEA8GE8 +p/SgguMh1YQdc4acLa/KNJvxn7kjNuK8YAOdgLOaVsjh4rsUecrNIdSUtUlD +-----END CERTIFICATE----- + +# Issuer: CN=Telia Root CA v2 O=Telia Finland Oyj +# Subject: CN=Telia Root CA v2 O=Telia Finland Oyj +# Label: "Telia Root CA v2" +# Serial: 7288924052977061235122729490515358 +# MD5 Fingerprint: 0e:8f:ac:aa:82:df:85:b1:f4:dc:10:1c:fc:99:d9:48 +# SHA1 Fingerprint: b9:99:cd:d1:73:50:8a:c4:47:05:08:9c:8c:88:fb:be:a0:2b:40:cd +# SHA256 Fingerprint: 24:2b:69:74:2f:cb:1e:5b:2a:bf:98:89:8b:94:57:21:87:54:4e:5b:4d:99:11:78:65:73:62:1f:6a:74:b8:2c +-----BEGIN CERTIFICATE----- +MIIFdDCCA1ygAwIBAgIPAWdfJ9b+euPkrL4JWwWeMA0GCSqGSIb3DQEBCwUAMEQx +CzAJBgNVBAYTAkZJMRowGAYDVQQKDBFUZWxpYSBGaW5sYW5kIE95ajEZMBcGA1UE +AwwQVGVsaWEgUm9vdCBDQSB2MjAeFw0xODExMjkxMTU1NTRaFw00MzExMjkxMTU1 +NTRaMEQxCzAJBgNVBAYTAkZJMRowGAYDVQQKDBFUZWxpYSBGaW5sYW5kIE95ajEZ +MBcGA1UEAwwQVGVsaWEgUm9vdCBDQSB2MjCCAiIwDQYJKoZIhvcNAQEBBQADggIP +ADCCAgoCggIBALLQPwe84nvQa5n44ndp586dpAO8gm2h/oFlH0wnrI4AuhZ76zBq +AMCzdGh+sq/H1WKzej9Qyow2RCRj0jbpDIX2Q3bVTKFgcmfiKDOlyzG4OiIjNLh9 +vVYiQJ3q9HsDrWj8soFPmNB06o3lfc1jw6P23pLCWBnglrvFxKk9pXSW/q/5iaq9 +lRdU2HhE8Qx3FZLgmEKnpNaqIJLNwaCzlrI6hEKNfdWV5Nbb6WLEWLN5xYzTNTOD +n3WhUidhOPFZPY5Q4L15POdslv5e2QJltI5c0BE0312/UqeBAMN/mUWZFdUXyApT +7GPzmX3MaRKGwhfwAZ6/hLzRUssbkmbOpFPlob/E2wnW5olWK8jjfN7j/4nlNW4o +6GwLI1GpJQXrSPjdscr6bAhR77cYbETKJuFzxokGgeWKrLDiKca5JLNrRBH0pUPC +TEPlcDaMtjNXepUugqD0XBCzYYP2AgWGLnwtbNwDRm41k9V6lS/eINhbfpSQBGq6 +WT0EBXWdN6IOLj3rwaRSg/7Qa9RmjtzG6RJOHSpXqhC8fF6CfaamyfItufUXJ63R +DolUK5X6wK0dmBR4M0KGCqlztft0DbcbMBnEWg4cJ7faGND/isgFuvGqHKI3t+ZI +pEYslOqodmJHixBTB0hXbOKSTbauBcvcwUpej6w9GU7C7WB1K9vBykLVAgMBAAGj +YzBhMB8GA1UdIwQYMBaAFHKs5DN5qkWH9v2sHZ7Wxy+G2CQ5MB0GA1UdDgQWBBRy +rOQzeapFh/b9rB2e1scvhtgkOTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUw +AwEB/zANBgkqhkiG9w0BAQsFAAOCAgEAoDtZpwmUPjaE0n4vOaWWl/oRrfxn83EJ +8rKJhGdEr7nv7ZbsnGTbMjBvZ5qsfl+yqwE2foH65IRe0qw24GtixX1LDoJt0nZi +0f6X+J8wfBj5tFJ3gh1229MdqfDBmgC9bXXYfef6xzijnHDoRnkDry5023X4blMM +A8iZGok1GTzTyVR8qPAs5m4HeW9q4ebqkYJpCh3DflminmtGFZhb069GHWLIzoBS +SRE/yQQSwxN8PzuKlts8oB4KtItUsiRnDe+Cy748fdHif64W1lZYudogsYMVoe+K +TTJvQS8TUoKU1xrBeKJR3Stwbbca+few4GeXVtt8YVMJAygCQMez2P2ccGrGKMOF +6eLtGpOg3kuYooQ+BXcBlj37tCAPnHICehIv1aO6UXivKitEZU61/Qrowc15h2Er +3oBXRb9n8ZuRXqWk7FlIEA04x7D6w0RtBPV4UBySllva9bguulvP5fBqnUsvWHMt +Ty3EHD70sz+rFQ47GUGKpMFXEmZxTPpT41frYpUJnlTd0cI8Vzy9OK2YZLe4A5pT +VmBds9hCG1xLEooc6+t9xnppxyd/pPiL8uSUZodL6ZQHCRJ5irLrdATczvREWeAW +ysUsWNc8e89ihmpQfTU2Zqf7N+cox9jQraVplI/owd8k+BsHMYeB2F326CjYSlKA +rBPuUBQemMc= +-----END CERTIFICATE----- + +# Issuer: CN=D-TRUST BR Root CA 1 2020 O=D-Trust GmbH +# Subject: CN=D-TRUST BR Root CA 1 2020 O=D-Trust GmbH +# Label: "D-TRUST BR Root CA 1 2020" +# Serial: 165870826978392376648679885835942448534 +# MD5 Fingerprint: b5:aa:4b:d5:ed:f7:e3:55:2e:8f:72:0a:f3:75:b8:ed +# SHA1 Fingerprint: 1f:5b:98:f0:e3:b5:f7:74:3c:ed:e6:b0:36:7d:32:cd:f4:09:41:67 +# SHA256 Fingerprint: e5:9a:aa:81:60:09:c2:2b:ff:5b:25:ba:d3:7d:f3:06:f0:49:79:7c:1f:81:d8:5a:b0:89:e6:57:bd:8f:00:44 +-----BEGIN CERTIFICATE----- +MIIC2zCCAmCgAwIBAgIQfMmPK4TX3+oPyWWa00tNljAKBggqhkjOPQQDAzBIMQsw +CQYDVQQGEwJERTEVMBMGA1UEChMMRC1UcnVzdCBHbWJIMSIwIAYDVQQDExlELVRS +VVNUIEJSIFJvb3QgQ0EgMSAyMDIwMB4XDTIwMDIxMTA5NDUwMFoXDTM1MDIxMTA5 +NDQ1OVowSDELMAkGA1UEBhMCREUxFTATBgNVBAoTDEQtVHJ1c3QgR21iSDEiMCAG +A1UEAxMZRC1UUlVTVCBCUiBSb290IENBIDEgMjAyMDB2MBAGByqGSM49AgEGBSuB +BAAiA2IABMbLxyjR+4T1mu9CFCDhQ2tuda38KwOE1HaTJddZO0Flax7mNCq7dPYS +zuht56vkPE4/RAiLzRZxy7+SmfSk1zxQVFKQhYN4lGdnoxwJGT11NIXe7WB9xwy0 +QVK5buXuQqOCAQ0wggEJMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFHOREKv/ +VbNafAkl1bK6CKBrqx9tMA4GA1UdDwEB/wQEAwIBBjCBxgYDVR0fBIG+MIG7MD6g +PKA6hjhodHRwOi8vY3JsLmQtdHJ1c3QubmV0L2NybC9kLXRydXN0X2JyX3Jvb3Rf +Y2FfMV8yMDIwLmNybDB5oHegdYZzbGRhcDovL2RpcmVjdG9yeS5kLXRydXN0Lm5l +dC9DTj1ELVRSVVNUJTIwQlIlMjBSb290JTIwQ0ElMjAxJTIwMjAyMCxPPUQtVHJ1 +c3QlMjBHbWJILEM9REU/Y2VydGlmaWNhdGVyZXZvY2F0aW9ubGlzdDAKBggqhkjO +PQQDAwNpADBmAjEAlJAtE/rhY/hhY+ithXhUkZy4kzg+GkHaQBZTQgjKL47xPoFW +wKrY7RjEsK70PvomAjEA8yjixtsrmfu3Ubgko6SUeho/5jbiA1czijDLgsfWFBHV +dWNbFJWcHwHP2NVypw87 +-----END CERTIFICATE----- + +# Issuer: CN=D-TRUST EV Root CA 1 2020 O=D-Trust GmbH +# Subject: CN=D-TRUST EV Root CA 1 2020 O=D-Trust GmbH +# Label: "D-TRUST EV Root CA 1 2020" +# Serial: 126288379621884218666039612629459926992 +# MD5 Fingerprint: 8c:2d:9d:70:9f:48:99:11:06:11:fb:e9:cb:30:c0:6e +# SHA1 Fingerprint: 61:db:8c:21:59:69:03:90:d8:7c:9c:12:86:54:cf:9d:3d:f4:dd:07 +# SHA256 Fingerprint: 08:17:0d:1a:a3:64:53:90:1a:2f:95:92:45:e3:47:db:0c:8d:37:ab:aa:bc:56:b8:1a:a1:00:dc:95:89:70:db +-----BEGIN CERTIFICATE----- +MIIC2zCCAmCgAwIBAgIQXwJB13qHfEwDo6yWjfv/0DAKBggqhkjOPQQDAzBIMQsw +CQYDVQQGEwJERTEVMBMGA1UEChMMRC1UcnVzdCBHbWJIMSIwIAYDVQQDExlELVRS +VVNUIEVWIFJvb3QgQ0EgMSAyMDIwMB4XDTIwMDIxMTEwMDAwMFoXDTM1MDIxMTA5 +NTk1OVowSDELMAkGA1UEBhMCREUxFTATBgNVBAoTDEQtVHJ1c3QgR21iSDEiMCAG +A1UEAxMZRC1UUlVTVCBFViBSb290IENBIDEgMjAyMDB2MBAGByqGSM49AgEGBSuB +BAAiA2IABPEL3YZDIBnfl4XoIkqbz52Yv7QFJsnL46bSj8WeeHsxiamJrSc8ZRCC +/N/DnU7wMyPE0jL1HLDfMxddxfCxivnvubcUyilKwg+pf3VlSSowZ/Rk99Yad9rD +wpdhQntJraOCAQ0wggEJMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFH8QARY3 +OqQo5FD4pPfsazK2/umLMA4GA1UdDwEB/wQEAwIBBjCBxgYDVR0fBIG+MIG7MD6g +PKA6hjhodHRwOi8vY3JsLmQtdHJ1c3QubmV0L2NybC9kLXRydXN0X2V2X3Jvb3Rf +Y2FfMV8yMDIwLmNybDB5oHegdYZzbGRhcDovL2RpcmVjdG9yeS5kLXRydXN0Lm5l +dC9DTj1ELVRSVVNUJTIwRVYlMjBSb290JTIwQ0ElMjAxJTIwMjAyMCxPPUQtVHJ1 +c3QlMjBHbWJILEM9REU/Y2VydGlmaWNhdGVyZXZvY2F0aW9ubGlzdDAKBggqhkjO +PQQDAwNpADBmAjEAyjzGKnXCXnViOTYAYFqLwZOZzNnbQTs7h5kXO9XMT8oi96CA +y/m0sRtW9XLS/BnRAjEAkfcwkz8QRitxpNA7RJvAKQIFskF3UfN5Wp6OFKBOQtJb +gfM0agPnIjhQW+0ZT0MW +-----END CERTIFICATE----- + +# Issuer: CN=DigiCert TLS ECC P384 Root G5 O=DigiCert, Inc. +# Subject: CN=DigiCert TLS ECC P384 Root G5 O=DigiCert, Inc. +# Label: "DigiCert TLS ECC P384 Root G5" +# Serial: 13129116028163249804115411775095713523 +# MD5 Fingerprint: d3:71:04:6a:43:1c:db:a6:59:e1:a8:a3:aa:c5:71:ed +# SHA1 Fingerprint: 17:f3:de:5e:9f:0f:19:e9:8e:f6:1f:32:26:6e:20:c4:07:ae:30:ee +# SHA256 Fingerprint: 01:8e:13:f0:77:25:32:cf:80:9b:d1:b1:72:81:86:72:83:fc:48:c6:e1:3b:e9:c6:98:12:85:4a:49:0c:1b:05 +-----BEGIN CERTIFICATE----- +MIICGTCCAZ+gAwIBAgIQCeCTZaz32ci5PhwLBCou8zAKBggqhkjOPQQDAzBOMQsw +CQYDVQQGEwJVUzEXMBUGA1UEChMORGlnaUNlcnQsIEluYy4xJjAkBgNVBAMTHURp +Z2lDZXJ0IFRMUyBFQ0MgUDM4NCBSb290IEc1MB4XDTIxMDExNTAwMDAwMFoXDTQ2 +MDExNDIzNTk1OVowTjELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDkRpZ2lDZXJ0LCBJ +bmMuMSYwJAYDVQQDEx1EaWdpQ2VydCBUTFMgRUNDIFAzODQgUm9vdCBHNTB2MBAG +ByqGSM49AgEGBSuBBAAiA2IABMFEoc8Rl1Ca3iOCNQfN0MsYndLxf3c1TzvdlHJS +7cI7+Oz6e2tYIOyZrsn8aLN1udsJ7MgT9U7GCh1mMEy7H0cKPGEQQil8pQgO4CLp +0zVozptjn4S1mU1YoI71VOeVyaNCMEAwHQYDVR0OBBYEFMFRRVBZqz7nLFr6ICIS +B4CIfBFqMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MAoGCCqGSM49 +BAMDA2gAMGUCMQCJao1H5+z8blUD2WdsJk6Dxv3J+ysTvLd6jLRl0mlpYxNjOyZQ +LgGheQaRnUi/wr4CMEfDFXuxoJGZSZOoPHzoRgaLLPIxAJSdYsiJvRmEFOml+wG4 +DXZDjC5Ty3zfDBeWUA== +-----END CERTIFICATE----- + +# Issuer: CN=DigiCert TLS RSA4096 Root G5 O=DigiCert, Inc. +# Subject: CN=DigiCert TLS RSA4096 Root G5 O=DigiCert, Inc. +# Label: "DigiCert TLS RSA4096 Root G5" +# Serial: 11930366277458970227240571539258396554 +# MD5 Fingerprint: ac:fe:f7:34:96:a9:f2:b3:b4:12:4b:e4:27:41:6f:e1 +# SHA1 Fingerprint: a7:88:49:dc:5d:7c:75:8c:8c:de:39:98:56:b3:aa:d0:b2:a5:71:35 +# SHA256 Fingerprint: 37:1a:00:dc:05:33:b3:72:1a:7e:eb:40:e8:41:9e:70:79:9d:2b:0a:0f:2c:1d:80:69:31:65:f7:ce:c4:ad:75 +-----BEGIN CERTIFICATE----- +MIIFZjCCA06gAwIBAgIQCPm0eKj6ftpqMzeJ3nzPijANBgkqhkiG9w0BAQwFADBN +MQswCQYDVQQGEwJVUzEXMBUGA1UEChMORGlnaUNlcnQsIEluYy4xJTAjBgNVBAMT +HERpZ2lDZXJ0IFRMUyBSU0E0MDk2IFJvb3QgRzUwHhcNMjEwMTE1MDAwMDAwWhcN +NDYwMTE0MjM1OTU5WjBNMQswCQYDVQQGEwJVUzEXMBUGA1UEChMORGlnaUNlcnQs +IEluYy4xJTAjBgNVBAMTHERpZ2lDZXJ0IFRMUyBSU0E0MDk2IFJvb3QgRzUwggIi +MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCz0PTJeRGd/fxmgefM1eS87IE+ +ajWOLrfn3q/5B03PMJ3qCQuZvWxX2hhKuHisOjmopkisLnLlvevxGs3npAOpPxG0 +2C+JFvuUAT27L/gTBaF4HI4o4EXgg/RZG5Wzrn4DReW+wkL+7vI8toUTmDKdFqgp +wgscONyfMXdcvyej/Cestyu9dJsXLfKB2l2w4SMXPohKEiPQ6s+d3gMXsUJKoBZM +pG2T6T867jp8nVid9E6P/DsjyG244gXazOvswzH016cpVIDPRFtMbzCe88zdH5RD +nU1/cHAN1DrRN/BsnZvAFJNY781BOHW8EwOVfH/jXOnVDdXifBBiqmvwPXbzP6Po +sMH976pXTayGpxi0KcEsDr9kvimM2AItzVwv8n/vFfQMFawKsPHTDU9qTXeXAaDx +Zre3zu/O7Oyldcqs4+Fj97ihBMi8ez9dLRYiVu1ISf6nL3kwJZu6ay0/nTvEF+cd +Lvvyz6b84xQslpghjLSR6Rlgg/IwKwZzUNWYOwbpx4oMYIwo+FKbbuH2TbsGJJvX +KyY//SovcfXWJL5/MZ4PbeiPT02jP/816t9JXkGPhvnxd3lLG7SjXi/7RgLQZhNe +XoVPzthwiHvOAbWWl9fNff2C+MIkwcoBOU+NosEUQB+cZtUMCUbW8tDRSHZWOkPL +tgoRObqME2wGtZ7P6wIDAQABo0IwQDAdBgNVHQ4EFgQUUTMc7TZArxfTJc1paPKv +TiM+s0EwDgYDVR0PAQH/BAQDAgGGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcN +AQEMBQADggIBAGCmr1tfV9qJ20tQqcQjNSH/0GEwhJG3PxDPJY7Jv0Y02cEhJhxw +GXIeo8mH/qlDZJY6yFMECrZBu8RHANmfGBg7sg7zNOok992vIGCukihfNudd5N7H +PNtQOa27PShNlnx2xlv0wdsUpasZYgcYQF+Xkdycx6u1UQ3maVNVzDl92sURVXLF +O4uJ+DQtpBflF+aZfTCIITfNMBc9uPK8qHWgQ9w+iUuQrm0D4ByjoJYJu32jtyoQ +REtGBzRj7TG5BO6jm5qu5jF49OokYTurWGT/u4cnYiWB39yhL/btp/96j1EuMPik +AdKFOV8BmZZvWltwGUb+hmA+rYAQCd05JS9Yf7vSdPD3Rh9GOUrYU9DzLjtxpdRv +/PNn5AeP3SYZ4Y1b+qOTEZvpyDrDVWiakuFSdjjo4bq9+0/V77PnSIMx8IIh47a+ +p6tv75/fTM8BuGJqIz3nCU2AG3swpMPdB380vqQmsvZB6Akd4yCYqjdP//fx4ilw +MUc/dNAUFvohigLVigmUdy7yWSiLfFCSCmZ4OIN1xLVaqBHG5cGdZlXPU8Sv13WF +qUITVuwhd4GTWgzqltlJyqEI8pc7bZsEGCREjnwB8twl2F6GmrE52/WRMmrRpnCK +ovfepEWFJqgejF0pW8hL2JpqA15w8oVPbEtoL8pU9ozaMv7Da4M/OMZ+ +-----END CERTIFICATE----- + +# Issuer: CN=Certainly Root R1 O=Certainly +# Subject: CN=Certainly Root R1 O=Certainly +# Label: "Certainly Root R1" +# Serial: 188833316161142517227353805653483829216 +# MD5 Fingerprint: 07:70:d4:3e:82:87:a0:fa:33:36:13:f4:fa:33:e7:12 +# SHA1 Fingerprint: a0:50:ee:0f:28:71:f4:27:b2:12:6d:6f:50:96:25:ba:cc:86:42:af +# SHA256 Fingerprint: 77:b8:2c:d8:64:4c:43:05:f7:ac:c5:cb:15:6b:45:67:50:04:03:3d:51:c6:0c:62:02:a8:e0:c3:34:67:d3:a0 +-----BEGIN CERTIFICATE----- +MIIFRzCCAy+gAwIBAgIRAI4P+UuQcWhlM1T01EQ5t+AwDQYJKoZIhvcNAQELBQAw +PTELMAkGA1UEBhMCVVMxEjAQBgNVBAoTCUNlcnRhaW5seTEaMBgGA1UEAxMRQ2Vy +dGFpbmx5IFJvb3QgUjEwHhcNMjEwNDAxMDAwMDAwWhcNNDYwNDAxMDAwMDAwWjA9 +MQswCQYDVQQGEwJVUzESMBAGA1UEChMJQ2VydGFpbmx5MRowGAYDVQQDExFDZXJ0 +YWlubHkgUm9vdCBSMTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBANA2 +1B/q3avk0bbm+yLA3RMNansiExyXPGhjZjKcA7WNpIGD2ngwEc/csiu+kr+O5MQT +vqRoTNoCaBZ0vrLdBORrKt03H2As2/X3oXyVtwxwhi7xOu9S98zTm/mLvg7fMbed +aFySpvXl8wo0tf97ouSHocavFwDvA5HtqRxOcT3Si2yJ9HiG5mpJoM610rCrm/b0 +1C7jcvk2xusVtyWMOvwlDbMicyF0yEqWYZL1LwsYpfSt4u5BvQF5+paMjRcCMLT5 +r3gajLQ2EBAHBXDQ9DGQilHFhiZ5shGIXsXwClTNSaa/ApzSRKft43jvRl5tcdF5 +cBxGX1HpyTfcX35pe0HfNEXgO4T0oYoKNp43zGJS4YkNKPl6I7ENPT2a/Z2B7yyQ +wHtETrtJ4A5KVpK8y7XdeReJkd5hiXSSqOMyhb5OhaRLWcsrxXiOcVTQAjeZjOVJ +6uBUcqQRBi8LjMFbvrWhsFNunLhgkR9Za/kt9JQKl7XsxXYDVBtlUrpMklZRNaBA +2CnbrlJ2Oy0wQJuK0EJWtLeIAaSHO1OWzaMWj/Nmqhexx2DgwUMFDO6bW2BvBlyH +Wyf5QBGenDPBt+U1VwV/J84XIIwc/PH72jEpSe31C4SnT8H2TsIonPru4K8H+zMR +eiFPCyEQtkA6qyI6BJyLm4SGcprSp6XEtHWRqSsjAgMBAAGjQjBAMA4GA1UdDwEB +/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBTgqj8ljZ9EXME66C6u +d0yEPmcM9DANBgkqhkiG9w0BAQsFAAOCAgEAuVevuBLaV4OPaAszHQNTVfSVcOQr +PbA56/qJYv331hgELyE03fFo8NWWWt7CgKPBjcZq91l3rhVkz1t5BXdm6ozTaw3d +8VkswTOlMIAVRQdFGjEitpIAq5lNOo93r6kiyi9jyhXWx8bwPWz8HA2YEGGeEaIi +1wrykXprOQ4vMMM2SZ/g6Q8CRFA3lFV96p/2O7qUpUzpvD5RtOjKkjZUbVwlKNrd +rRT90+7iIgXr0PK3aBLXWopBGsaSpVo7Y0VPv+E6dyIvXL9G+VoDhRNCX8reU9di +taY1BMJH/5n9hN9czulegChB8n3nHpDYT3Y+gjwN/KUD+nsa2UUeYNrEjvn8K8l7 +lcUq/6qJ34IxD3L/DCfXCh5WAFAeDJDBlrXYFIW7pw0WwfgHJBu6haEaBQmAupVj +yTrsJZ9/nbqkRxWbRHDxakvWOF5D8xh+UG7pWijmZeZ3Gzr9Hb4DJqPb1OG7fpYn +Kx3upPvaJVQTA945xsMfTZDsjxtK0hzthZU4UHlG1sGQUDGpXJpuHfUzVounmdLy +yCwzk5Iwx06MZTMQZBf9JBeW0Y3COmor6xOLRPIh80oat3df1+2IpHLlOR+Vnb5n +wXARPbv0+Em34yaXOp/SX3z7wJl8OSngex2/DaeP0ik0biQVy96QXr8axGbqwua6 +OV+KmalBWQewLK8= +-----END CERTIFICATE----- + +# Issuer: CN=Certainly Root E1 O=Certainly +# Subject: CN=Certainly Root E1 O=Certainly +# Label: "Certainly Root E1" +# Serial: 8168531406727139161245376702891150584 +# MD5 Fingerprint: 0a:9e:ca:cd:3e:52:50:c6:36:f3:4b:a3:ed:a7:53:e9 +# SHA1 Fingerprint: f9:e1:6d:dc:01:89:cf:d5:82:45:63:3e:c5:37:7d:c2:eb:93:6f:2b +# SHA256 Fingerprint: b4:58:5f:22:e4:ac:75:6a:4e:86:12:a1:36:1c:5d:9d:03:1a:93:fd:84:fe:bb:77:8f:a3:06:8b:0f:c4:2d:c2 +-----BEGIN CERTIFICATE----- +MIIB9zCCAX2gAwIBAgIQBiUzsUcDMydc+Y2aub/M+DAKBggqhkjOPQQDAzA9MQsw +CQYDVQQGEwJVUzESMBAGA1UEChMJQ2VydGFpbmx5MRowGAYDVQQDExFDZXJ0YWlu +bHkgUm9vdCBFMTAeFw0yMTA0MDEwMDAwMDBaFw00NjA0MDEwMDAwMDBaMD0xCzAJ +BgNVBAYTAlVTMRIwEAYDVQQKEwlDZXJ0YWlubHkxGjAYBgNVBAMTEUNlcnRhaW5s +eSBSb290IEUxMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAE3m/4fxzf7flHh4axpMCK ++IKXgOqPyEpeKn2IaKcBYhSRJHpcnqMXfYqGITQYUBsQ3tA3SybHGWCA6TS9YBk2 +QNYphwk8kXr2vBMj3VlOBF7PyAIcGFPBMdjaIOlEjeR2o0IwQDAOBgNVHQ8BAf8E +BAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU8ygYy2R17ikq6+2uI1g4 +hevIIgcwCgYIKoZIzj0EAwMDaAAwZQIxALGOWiDDshliTd6wT99u0nCK8Z9+aozm +ut6Dacpps6kFtZaSF4fC0urQe87YQVt8rgIwRt7qy12a7DLCZRawTDBcMPPaTnOG +BtjOiQRINzf43TNRnXCve1XYAS59BWQOhriR +-----END CERTIFICATE----- + +# Issuer: CN=E-Tugra Global Root CA RSA v3 O=E-Tugra EBG A.S. OU=E-Tugra Trust Center +# Subject: CN=E-Tugra Global Root CA RSA v3 O=E-Tugra EBG A.S. OU=E-Tugra Trust Center +# Label: "E-Tugra Global Root CA RSA v3" +# Serial: 75951268308633135324246244059508261641472512052 +# MD5 Fingerprint: 22:be:10:f6:c2:f8:03:88:73:5f:33:29:47:28:47:a4 +# SHA1 Fingerprint: e9:a8:5d:22:14:52:1c:5b:aa:0a:b4:be:24:6a:23:8a:c9:ba:e2:a9 +# SHA256 Fingerprint: ef:66:b0:b1:0a:3c:db:9f:2e:36:48:c7:6b:d2:af:18:ea:d2:bf:e6:f1:17:65:5e:28:c4:06:0d:a1:a3:f4:c2 +-----BEGIN CERTIFICATE----- +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 +-----END CERTIFICATE----- + +# Issuer: CN=E-Tugra Global Root CA ECC v3 O=E-Tugra EBG A.S. OU=E-Tugra Trust Center +# Subject: CN=E-Tugra Global Root CA ECC v3 O=E-Tugra EBG A.S. OU=E-Tugra Trust Center +# Label: "E-Tugra Global Root CA ECC v3" +# Serial: 218504919822255052842371958738296604628416471745 +# MD5 Fingerprint: 46:bc:81:bb:f1:b5:1e:f7:4b:96:bc:14:e2:e7:27:64 +# SHA1 Fingerprint: 8a:2f:af:57:53:b1:b0:e6:a1:04:ec:5b:6a:69:71:6d:f6:1c:e2:84 +# SHA256 Fingerprint: 87:3f:46:85:fa:7f:56:36:25:25:2e:6d:36:bc:d7:f1:6f:c2:49:51:f2:64:e4:7e:1b:95:4f:49:08:cd:ca:13 +-----BEGIN CERTIFICATE----- +MIICpTCCAiqgAwIBAgIUJkYZdzHhT28oNt45UYbm1JeIIsEwCgYIKoZIzj0EAwMw +gYAxCzAJBgNVBAYTAlRSMQ8wDQYDVQQHEwZBbmthcmExGTAXBgNVBAoTEEUtVHVn +cmEgRUJHIEEuUy4xHTAbBgNVBAsTFEUtVHVncmEgVHJ1c3QgQ2VudGVyMSYwJAYD +VQQDEx1FLVR1Z3JhIEdsb2JhbCBSb290IENBIEVDQyB2MzAeFw0yMDAzMTgwOTQ2 +NThaFw00NTAzMTIwOTQ2NThaMIGAMQswCQYDVQQGEwJUUjEPMA0GA1UEBxMGQW5r +YXJhMRkwFwYDVQQKExBFLVR1Z3JhIEVCRyBBLlMuMR0wGwYDVQQLExRFLVR1Z3Jh +IFRydXN0IENlbnRlcjEmMCQGA1UEAxMdRS1UdWdyYSBHbG9iYWwgUm9vdCBDQSBF +Q0MgdjMwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAASOmCm/xxAeJ9urA8woLNheSBkQ +KczLWYHMjLiSF4mDKpL2w6QdTGLVn9agRtwcvHbB40fQWxPa56WzZkjnIZpKT4YK +fWzqTTKACrJ6CZtpS5iB4i7sAnCWH/31Rs7K3IKjYzBhMA8GA1UdEwEB/wQFMAMB +Af8wHwYDVR0jBBgwFoAU/4Ixcj75xGZsrTie0bBRiKWQzPUwHQYDVR0OBBYEFP+C +MXI++cRmbK04ntGwUYilkMz1MA4GA1UdDwEB/wQEAwIBBjAKBggqhkjOPQQDAwNp +ADBmAjEA5gVYaWHlLcoNy/EZCL3W/VGSGn5jVASQkZo1kTmZ+gepZpO6yGjUij/6 +7W4WAie3AjEA3VoXK3YdZUKWpqxdinlW2Iob35reX8dQj7FbcQwm32pAAOwzkSFx +vmjkI6TZraE3 +-----END CERTIFICATE----- diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/certifi/core.py b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/certifi/core.py index 7271acf4..497d938d 100644 --- a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/certifi/core.py +++ b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/certifi/core.py @@ -1,15 +1,68 @@ -# -*- coding: utf-8 -*- - """ certifi.py ~~~~~~~~~~ -This module returns the installation location of cacert.pem. +This module returns the installation location of cacert.pem or its contents. """ import os +import types +from typing import Union + +try: + from importlib.resources import path as get_path, read_text + + _CACERT_CTX = None + _CACERT_PATH = None + + def where() -> str: + # This is slightly terrible, but we want to delay extracting the file + # in cases where we're inside of a zipimport situation until someone + # actually calls where(), but we don't want to re-extract the file + # on every call of where(), so we'll do it once then store it in a + # global variable. + global _CACERT_CTX + global _CACERT_PATH + if _CACERT_PATH is None: + # This is slightly janky, the importlib.resources API wants you to + # manage the cleanup of this file, so it doesn't actually return a + # path, it returns a context manager that will give you the path + # when you enter it and will do any cleanup when you leave it. In + # the common case of not needing a temporary file, it will just + # return the file system location and the __exit__() is a no-op. + # + # We also have to hold onto the actual context manager, because + # it will do the cleanup whenever it gets garbage collected, so + # we will also store that at the global level as well. + _CACERT_CTX = get_path("certifi", "cacert.pem") + _CACERT_PATH = str(_CACERT_CTX.__enter__()) + + return _CACERT_PATH + + +except ImportError: + Package = Union[types.ModuleType, str] + Resource = Union[str, "os.PathLike"] + + # This fallback will work for Python versions prior to 3.7 that lack the + # importlib.resources module but relies on the existing `where` function + # so won't address issues with environments like PyOxidizer that don't set + # __file__ on modules. + def read_text( + package: Package, + resource: Resource, + encoding: str = 'utf-8', + errors: str = 'strict' + ) -> str: + with open(where(), encoding=encoding) as data: + return data.read() + + # If we don't have importlib.resources, then we will just do the old logic + # of assuming we're on the filesystem and munge the path directly. + def where() -> str: + f = os.path.dirname(__file__) + return os.path.join(f, "cacert.pem") -def where(): - f = os.path.dirname(__file__) - return os.path.join(f, 'cacert.pem') +def contents() -> str: + return read_text("certifi", "cacert.pem", encoding="ascii") diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/certifi/py.typed b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/certifi/py.typed new file mode 100644 index 00000000..e69de29b diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/cffi-1.12.3.dist-info/RECORD b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/cffi-1.12.3.dist-info/RECORD deleted file mode 100644 index a2d93fd1..00000000 --- a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/cffi-1.12.3.dist-info/RECORD +++ /dev/null @@ -1,44 +0,0 @@ -_cffi_backend.cp37-win32.pyd,sha256=LbpnOkcB1o-4UFT2SiLEwknE-4x7oLjK6Dg7vMn412I,139264 -cffi-1.12.3.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 -cffi-1.12.3.dist-info/LICENSE,sha256=BLgPWwd7vtaICM_rreteNSPyqMmpZJXFh72W3x6sKjM,1294 -cffi-1.12.3.dist-info/METADATA,sha256=OA_DlKzbYB72gWWz0R2ds_RJzTIzvFx5cnHf5NXTRuo,1140 -cffi-1.12.3.dist-info/RECORD,, -cffi-1.12.3.dist-info/WHEEL,sha256=u4Efs1ohefs6i6rm-BSBkNuQzwmF2Y4Na3ETsbtk2VM,102 -cffi-1.12.3.dist-info/entry_points.txt,sha256=Q9f5C9IpjYxo0d2PK9eUcnkgxHc9pHWwjEMaANPKNCI,76 -cffi-1.12.3.dist-info/top_level.txt,sha256=rE7WR3rZfNKxWI9-jn6hsHCAl7MDkB-FmuQbxWjFehQ,19 -cffi/__init__.py,sha256=XPx-ySmw7OmYmr-7iXd3YoXhXj1HQLHYviMKpmAuWLc,513 -cffi/__pycache__/__init__.cpython-37.pyc,, -cffi/__pycache__/api.cpython-37.pyc,, -cffi/__pycache__/backend_ctypes.cpython-37.pyc,, -cffi/__pycache__/cffi_opcode.cpython-37.pyc,, -cffi/__pycache__/commontypes.cpython-37.pyc,, -cffi/__pycache__/cparser.cpython-37.pyc,, -cffi/__pycache__/error.cpython-37.pyc,, -cffi/__pycache__/ffiplatform.cpython-37.pyc,, -cffi/__pycache__/lock.cpython-37.pyc,, -cffi/__pycache__/model.cpython-37.pyc,, -cffi/__pycache__/pkgconfig.cpython-37.pyc,, -cffi/__pycache__/recompiler.cpython-37.pyc,, -cffi/__pycache__/setuptools_ext.cpython-37.pyc,, -cffi/__pycache__/vengine_cpy.cpython-37.pyc,, -cffi/__pycache__/vengine_gen.cpython-37.pyc,, -cffi/__pycache__/verifier.cpython-37.pyc,, -cffi/_cffi_errors.h,sha256=6nFQ-4dRQI1bXRoSeqdvyKU33TmutQJB_2fAhWSzdl8,3856 -cffi/_cffi_include.h,sha256=JuFfmwpRE65vym3Nxr9vDMOIEuv21tXdarkL1l2WNms,12149 -cffi/_embedding.h,sha256=PuNkRzXjURiRh7tXzVdIn0RD9pTJx04ZokHbcEO_3OY,17226 -cffi/api.py,sha256=Q07iwDD0FRwWa2fx2ZzQft69iJs9aNR52fvrtUy3EY4,41800 -cffi/backend_ctypes.py,sha256=_WkpD1SJel5gJovV-0u8hw-XvD3Efapqm9pIAEHTHn4,42449 -cffi/cffi_opcode.py,sha256=v9RdD_ovA8rCtqsC95Ivki5V667rAOhGgs3fb2q9xpM,5724 -cffi/commontypes.py,sha256=QS4uxCDI7JhtTyjh1hlnCA-gynmaszWxJaRRLGkJa1A,2689 -cffi/cparser.py,sha256=dcVqrRob1zqrCO--RZ6e-TtobJ7VMDpCU85W6QJ-N-4,40874 -cffi/error.py,sha256=v6xTiS4U0kvDcy4h_BDRo5v39ZQuj-IMRYLv5ETddZs,877 -cffi/ffiplatform.py,sha256=HMXqR8ks2wtdsNxGaWpQ_PyqIvtiuos_vf1qKCy-cwg,4046 -cffi/lock.py,sha256=l9TTdwMIMpi6jDkJGnQgE9cvTIR7CAntIJr8EGHt3pY,747 -cffi/model.py,sha256=AYyjS26uiFKXtkm43qmStpy9zfGh5HVJF4UETYFBt6w,21682 -cffi/parse_c_type.h,sha256=OdwQfwM9ktq6vlCB43exFQmxDBtj2MBNdK8LYl15tjw,5976 -cffi/pkgconfig.py,sha256=LP1w7vmWvmKwyqLaU1Z243FOWGNQMrgMUZrvgFuOlco,4374 -cffi/recompiler.py,sha256=LGqj7GPuq4KIG4axrN5G0Oy6YGmrLbBA0bHE-jCl6Oo,62711 -cffi/setuptools_ext.py,sha256=qc6arfrSzm4RNT5oJz6d5td7KJ-pHfI7bqYD0X4Q-08,8848 -cffi/vengine_cpy.py,sha256=hdyjjZNijLrg_uGMnnFyC-7GG_LxWtwB8BlS2vvVDQ0,41470 -cffi/vengine_gen.py,sha256=Zkq0-EdeZwn6qUvf_CI8iUEs2UxVIvDmKCH1j0-y0GI,26676 -cffi/verifier.py,sha256=J9Enz2rbJb9CHPqWlWQ5uQESoyr0uc7MNWugchjXBv4,11207 diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/cffi-1.15.1.dist-info/INSTALLER b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/cffi-1.15.1.dist-info/INSTALLER new file mode 100644 index 00000000..a1b589e3 --- /dev/null +++ b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/cffi-1.15.1.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/cffi-1.12.3.dist-info/LICENSE b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/cffi-1.15.1.dist-info/LICENSE similarity index 100% rename from Resources/WPy32-3720/python-3.7.2/Lib/site-packages/cffi-1.12.3.dist-info/LICENSE rename to Resources/WPy32-3720/python-3.7.2/Lib/site-packages/cffi-1.15.1.dist-info/LICENSE diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/cffi-1.12.3.dist-info/METADATA b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/cffi-1.15.1.dist-info/METADATA similarity index 74% rename from Resources/WPy32-3720/python-3.7.2/Lib/site-packages/cffi-1.12.3.dist-info/METADATA rename to Resources/WPy32-3720/python-3.7.2/Lib/site-packages/cffi-1.15.1.dist-info/METADATA index b2284b32..538e6791 100644 --- a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/cffi-1.12.3.dist-info/METADATA +++ b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/cffi-1.15.1.dist-info/METADATA @@ -1,24 +1,24 @@ Metadata-Version: 2.1 Name: cffi -Version: 1.12.3 +Version: 1.15.1 Summary: Foreign Function Interface for Python calling C code. Home-page: http://cffi.readthedocs.org Author: Armin Rigo, Maciej Fijalkowski Author-email: python-cffi@googlegroups.com License: MIT -Platform: UNKNOWN Classifier: Programming Language :: Python Classifier: Programming Language :: Python :: 2 -Classifier: Programming Language :: Python :: 2.6 Classifier: Programming Language :: Python :: 2.7 Classifier: Programming Language :: Python :: 3 -Classifier: Programming Language :: Python :: 3.2 -Classifier: Programming Language :: Python :: 3.3 -Classifier: Programming Language :: Python :: 3.4 -Classifier: Programming Language :: Python :: 3.5 Classifier: Programming Language :: Python :: 3.6 +Classifier: Programming Language :: Python :: 3.7 +Classifier: Programming Language :: Python :: 3.8 +Classifier: Programming Language :: Python :: 3.9 +Classifier: Programming Language :: Python :: 3.10 Classifier: Programming Language :: Python :: Implementation :: CPython Classifier: Programming Language :: Python :: Implementation :: PyPy +Classifier: License :: OSI Approved :: MIT License +License-File: LICENSE Requires-Dist: pycparser @@ -32,5 +32,3 @@ Contact ------- `Mailing list `_ - - diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/cffi-1.15.1.dist-info/RECORD b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/cffi-1.15.1.dist-info/RECORD new file mode 100644 index 00000000..26502729 --- /dev/null +++ b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/cffi-1.15.1.dist-info/RECORD @@ -0,0 +1,44 @@ +_cffi_backend.cp37-win32.pyd,sha256=M6WrbGJ1J4h7ggWMTb-_1diLvxhzAuc6oxabgeEsukA,155648 +cffi-1.15.1.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +cffi-1.15.1.dist-info/LICENSE,sha256=esEZUOct9bRcUXFqeyLnuzSzJNZ_Bl4pOBUt1HLEgV8,1320 +cffi-1.15.1.dist-info/METADATA,sha256=KP4G3WmavRgDGwD2b8Y_eDsM1YeV6ckcG6Alz3-D8VY,1144 +cffi-1.15.1.dist-info/RECORD,, +cffi-1.15.1.dist-info/WHEEL,sha256=cpY2CIQibwgnIWFRKvRDp2Kii5IPBXf6TQxjD0tLibE,97 +cffi-1.15.1.dist-info/entry_points.txt,sha256=y6jTxnyeuLnL-XJcDv8uML3n6wyYiGRg8MTp_QGJ9Ho,75 +cffi-1.15.1.dist-info/top_level.txt,sha256=rE7WR3rZfNKxWI9-jn6hsHCAl7MDkB-FmuQbxWjFehQ,19 +cffi/__init__.py,sha256=uABQQ4lgzvhAvVhd1_ZA_oSO9T-O93qMod-rs0Ihjb8,527 +cffi/__pycache__/__init__.cpython-37.pyc,, +cffi/__pycache__/api.cpython-37.pyc,, +cffi/__pycache__/backend_ctypes.cpython-37.pyc,, +cffi/__pycache__/cffi_opcode.cpython-37.pyc,, +cffi/__pycache__/commontypes.cpython-37.pyc,, +cffi/__pycache__/cparser.cpython-37.pyc,, +cffi/__pycache__/error.cpython-37.pyc,, +cffi/__pycache__/ffiplatform.cpython-37.pyc,, +cffi/__pycache__/lock.cpython-37.pyc,, +cffi/__pycache__/model.cpython-37.pyc,, +cffi/__pycache__/pkgconfig.cpython-37.pyc,, +cffi/__pycache__/recompiler.cpython-37.pyc,, +cffi/__pycache__/setuptools_ext.cpython-37.pyc,, +cffi/__pycache__/vengine_cpy.cpython-37.pyc,, +cffi/__pycache__/vengine_gen.cpython-37.pyc,, +cffi/__pycache__/verifier.cpython-37.pyc,, +cffi/_cffi_errors.h,sha256=G0bGOb-6SNIO0UY8KEN3cM40Yd1JuR5bETQ8Ni5PxWY,4057 +cffi/_cffi_include.h,sha256=H7cgdZR-POwmUFrIup4jOGzmje8YoQHhN99gVFg7w08,15185 +cffi/_embedding.h,sha256=zo5hCU0uCLgUeTOPdfXbXc5ABXjOffCMHyfUKBjCQ5E,18208 +cffi/api.py,sha256=Xs_dAN5x1ehfnn_F9ZTdA3Ce0bmPrqeIOkO4Ya1tfbQ,43029 +cffi/backend_ctypes.py,sha256=BHN3q2giL2_Y8wMDST2CIcc_qoMrs65qV9Ob5JvxBZ4,43575 +cffi/cffi_opcode.py,sha256=57P2NHLZkuTWueZybu5iosWljb6ocQmUXzGrCplrnyE,5911 +cffi/commontypes.py,sha256=mEZD4g0qtadnv6O6CEXvMQaJ1K6SRbG5S1h4YvVZHOU,2769 +cffi/cparser.py,sha256=CwVk2V3ATYlCoywG6zN35w6UQ7zj2EWX68KjoJp2Mzk,45237 +cffi/error.py,sha256=Bka7fSV22aIglTQDPIDfpnxTc1aWZLMQdQOJY-h_PUA,908 +cffi/ffiplatform.py,sha256=qioydJeC63dEvrQ3ht5_BPmSs7wzzzuWnZAJtfhic7I,4173 +cffi/lock.py,sha256=vnbsel7392Ib8gGBifIfAfc7MHteSwd3nP725pvc25Q,777 +cffi/model.py,sha256=HRD0WEYHF2Vr6RjS-4wyncElrZxU2256zY0fbMkSKec,22385 +cffi/parse_c_type.h,sha256=fKYNqWNX5f9kZNNhbXcRLTOlpRGRhh8eCLyHmTXIZnQ,6157 +cffi/pkgconfig.py,sha256=9zDcDf0XKIJaxFHLg7e-W8-Xb8Yq5hdhqH7kLg-ugRo,4495 +cffi/recompiler.py,sha256=lV6Hz-F1RXPk8YjafaIe3a-UNNVfLIeEQk0FwmXqg3s,66179 +cffi/setuptools_ext.py,sha256=8y14TOlRAkgdczmwtPOahyFXJHNyIqhLjUHMYQmjOHs,9150 +cffi/vengine_cpy.py,sha256=ukugKCIsURxJzHxlxS265tGjQfPTFDbThwsqBrwKh-A,44396 +cffi/vengine_gen.py,sha256=mykUhLFJIcV6AyQ5cMJ3n_7dbqw0a9WEjXW0E-WfgiI,27359 +cffi/verifier.py,sha256=AZuuR7MxjMYZc8IsZjGsF8mdGajCsOY60AZLwZZ_Z2Y,11560 diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/psutil-5.6.1.dist-info/WHEEL b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/cffi-1.15.1.dist-info/WHEEL similarity index 67% rename from Resources/WPy32-3720/python-3.7.2/Lib/site-packages/psutil-5.6.1.dist-info/WHEEL rename to Resources/WPy32-3720/python-3.7.2/Lib/site-packages/cffi-1.15.1.dist-info/WHEEL index bb93ff5e..220681c3 100644 --- a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/psutil-5.6.1.dist-info/WHEEL +++ b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/cffi-1.15.1.dist-info/WHEEL @@ -1,5 +1,5 @@ Wheel-Version: 1.0 -Generator: bdist_wheel (0.33.1) +Generator: bdist_wheel (0.37.1) Root-Is-Purelib: false Tag: cp37-cp37m-win32 diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/cffi-1.12.3.dist-info/entry_points.txt b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/cffi-1.15.1.dist-info/entry_points.txt similarity index 98% rename from Resources/WPy32-3720/python-3.7.2/Lib/site-packages/cffi-1.12.3.dist-info/entry_points.txt rename to Resources/WPy32-3720/python-3.7.2/Lib/site-packages/cffi-1.15.1.dist-info/entry_points.txt index eee7e0fb..4b0274f2 100644 --- a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/cffi-1.12.3.dist-info/entry_points.txt +++ b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/cffi-1.15.1.dist-info/entry_points.txt @@ -1,3 +1,2 @@ [distutils.setup_keywords] cffi_modules = cffi.setuptools_ext:cffi_modules - diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/cffi-1.12.3.dist-info/top_level.txt b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/cffi-1.15.1.dist-info/top_level.txt similarity index 100% rename from Resources/WPy32-3720/python-3.7.2/Lib/site-packages/cffi-1.12.3.dist-info/top_level.txt rename to Resources/WPy32-3720/python-3.7.2/Lib/site-packages/cffi-1.15.1.dist-info/top_level.txt diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/cffi/__init__.py b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/cffi/__init__.py index 0224a15a..90e2e655 100644 --- a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/cffi/__init__.py +++ b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/cffi/__init__.py @@ -5,8 +5,8 @@ from .api import FFI from .error import CDefError, FFIError, VerificationError, VerificationMissing from .error import PkgConfigError -__version__ = "1.12.3" -__version_info__ = (1, 12, 3) +__version__ = "1.15.1" +__version_info__ = (1, 15, 1) # The verifier module file names are based on the CRC32 of a string that # contains the following version number. It may be older than __version__ diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/cffi/_cffi_errors.h b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/cffi/_cffi_errors.h index 83cdad06..158e0590 100644 --- a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/cffi/_cffi_errors.h +++ b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/cffi/_cffi_errors.h @@ -54,6 +54,8 @@ static PyObject *_cffi_start_error_capture(void) " of.write(x)\n" " except: pass\n" " self.buf += x\n" + " def flush(self):\n" + " pass\n" "fl = FileLike()\n" "fl.buf = ''\n" "of = sys.stderr\n" diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/cffi/_cffi_include.h b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/cffi/_cffi_include.h index 37ea74fe..e4c0a672 100644 --- a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/cffi/_cffi_include.h +++ b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/cffi/_cffi_include.h @@ -8,20 +8,49 @@ the same works for the other two macros. Py_DEBUG implies them, but not the other way around. - Issue #350 is still open: on Windows, the code here causes it to link - with PYTHON36.DLL (for example) instead of PYTHON3.DLL. A fix was - attempted in 164e526a5515 and 14ce6985e1c3, but reverted: virtualenv - does not make PYTHON3.DLL available, and so the "correctly" compiled - version would not run inside a virtualenv. We will re-apply the fix - after virtualenv has been fixed for some time. For explanation, see - issue #355. For a workaround if you want PYTHON3.DLL and don't worry - about virtualenv, see issue #350. See also 'py_limited_api' in - setuptools_ext.py. + The implementation is messy (issue #350): on Windows, with _MSC_VER, + we have to define Py_LIMITED_API even before including pyconfig.h. + In that case, we guess what pyconfig.h will do to the macros above, + and check our guess after the #include. + + Note that on Windows, with CPython 3.x, you need >= 3.5 and virtualenv + version >= 16.0.0. With older versions of either, you don't get a + copy of PYTHON3.DLL in the virtualenv. We can't check the version of + CPython *before* we even include pyconfig.h. ffi.set_source() puts + a ``#define _CFFI_NO_LIMITED_API'' at the start of this file if it is + running on Windows < 3.5, as an attempt at fixing it, but that's + arguably wrong because it may not be the target version of Python. + Still better than nothing I guess. As another workaround, you can + remove the definition of Py_LIMITED_API here. + + See also 'py_limited_api' in cffi/setuptools_ext.py. */ #if !defined(_CFFI_USE_EMBEDDING) && !defined(Py_LIMITED_API) -# include -# if !defined(Py_DEBUG) && !defined(Py_TRACE_REFS) && !defined(Py_REF_DEBUG) -# define Py_LIMITED_API +# ifdef _MSC_VER +# if !defined(_DEBUG) && !defined(Py_DEBUG) && !defined(Py_TRACE_REFS) && !defined(Py_REF_DEBUG) && !defined(_CFFI_NO_LIMITED_API) +# define Py_LIMITED_API +# endif +# include + /* sanity-check: Py_LIMITED_API will cause crashes if any of these + are also defined. Normally, the Python file PC/pyconfig.h does not + cause any of these to be defined, with the exception that _DEBUG + causes Py_DEBUG. Double-check that. */ +# ifdef Py_LIMITED_API +# if defined(Py_DEBUG) +# error "pyconfig.h unexpectedly defines Py_DEBUG, but Py_LIMITED_API is set" +# endif +# if defined(Py_TRACE_REFS) +# error "pyconfig.h unexpectedly defines Py_TRACE_REFS, but Py_LIMITED_API is set" +# endif +# if defined(Py_REF_DEBUG) +# error "pyconfig.h unexpectedly defines Py_REF_DEBUG, but Py_LIMITED_API is set" +# endif +# endif +# else +# include +# if !defined(Py_DEBUG) && !defined(Py_TRACE_REFS) && !defined(Py_REF_DEBUG) && !defined(_CFFI_NO_LIMITED_API) +# define Py_LIMITED_API +# endif # endif #endif @@ -261,14 +290,62 @@ _CFFI_UNUSED_FN static int _cffi_to_c_char32_t(PyObject *o) return (int)_cffi_to_c_wchar3216_t(o); } -_CFFI_UNUSED_FN static PyObject *_cffi_from_c_char32_t(int x) +_CFFI_UNUSED_FN static PyObject *_cffi_from_c_char32_t(unsigned int x) { if (sizeof(_cffi_wchar_t) == 4) return _cffi_from_c_wchar_t((_cffi_wchar_t)x); else - return _cffi_from_c_wchar3216_t(x); + return _cffi_from_c_wchar3216_t((int)x); +} + +union _cffi_union_alignment_u { + unsigned char m_char; + unsigned short m_short; + unsigned int m_int; + unsigned long m_long; + unsigned long long m_longlong; + float m_float; + double m_double; + long double m_longdouble; +}; + +struct _cffi_freeme_s { + struct _cffi_freeme_s *next; + union _cffi_union_alignment_u alignment; +}; + +_CFFI_UNUSED_FN static int +_cffi_convert_array_argument(struct _cffi_ctypedescr *ctptr, PyObject *arg, + char **output_data, Py_ssize_t datasize, + struct _cffi_freeme_s **freeme) +{ + char *p; + if (datasize < 0) + return -1; + + p = *output_data; + if (p == NULL) { + struct _cffi_freeme_s *fp = (struct _cffi_freeme_s *)PyObject_Malloc( + offsetof(struct _cffi_freeme_s, alignment) + (size_t)datasize); + if (fp == NULL) + return -1; + fp->next = *freeme; + *freeme = fp; + p = *output_data = (char *)&fp->alignment; + } + memset((void *)p, 0, (size_t)datasize); + return _cffi_convert_array_from_object(p, ctptr, arg); } +_CFFI_UNUSED_FN static void +_cffi_free_array_arguments(struct _cffi_freeme_s *freeme) +{ + do { + void *p = (void *)freeme; + freeme = freeme->next; + PyObject_Free(p); + } while (freeme != NULL); +} /********** end CPython-specific section **********/ #else diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/cffi/_embedding.h b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/cffi/_embedding.h index 30842c17..8e8df882 100644 --- a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/cffi/_embedding.h +++ b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/cffi/_embedding.h @@ -22,7 +22,8 @@ extern "C" { * _cffi_call_python_org, which on CPython is actually part of the _cffi_exports[] array, is the function pointer copied from - _cffi_backend. + _cffi_backend. If _cffi_start_python() fails, then this is set + to NULL; otherwise, it should never be NULL. After initialization is complete, both are equal. However, the first one remains equal to &_cffi_start_and_call_python until the @@ -224,7 +225,7 @@ static int _cffi_initialize_python(void) if (f != NULL && f != Py_None) { PyFile_WriteString("\nFrom: " _CFFI_MODULE_NAME - "\ncompiled with cffi version: 1.12.3" + "\ncompiled with cffi version: 1.15.1" "\n_cffi_backend module: ", f); modules = PyImport_GetModuleDict(); mod = PyDict_GetItemString(modules, "_cffi_backend"); @@ -246,7 +247,9 @@ static int _cffi_initialize_python(void) goto done; } +#if PY_VERSION_HEX < 0x03080000 PyAPI_DATA(char *) _PyParser_TokenNames[]; /* from CPython */ +#endif static int _cffi_carefully_make_gil(void) { @@ -327,15 +330,22 @@ static int _cffi_carefully_make_gil(void) #endif /* call Py_InitializeEx() */ - { - PyGILState_STATE state = PyGILState_UNLOCKED; - if (!Py_IsInitialized()) - _cffi_py_initialize(); - else - state = PyGILState_Ensure(); - + if (!Py_IsInitialized()) { + _cffi_py_initialize(); +#if PY_VERSION_HEX < 0x03070000 + PyEval_InitThreads(); +#endif + PyEval_SaveThread(); /* release the GIL */ + /* the returned tstate must be the one that has been stored into the + autoTLSkey by _PyGILState_Init() called from Py_Initialize(). */ + } + else { +#if PY_VERSION_HEX < 0x03070000 + /* PyEval_InitThreads() is always a no-op from CPython 3.7 */ + PyGILState_STATE state = PyGILState_Ensure(); PyEval_InitThreads(); PyGILState_Release(state); +#endif } #ifdef WITH_THREAD @@ -359,11 +369,11 @@ PyMODINIT_FUNC _CFFI_PYTHON_STARTUP_FUNC(const void *[]); /* forward */ static struct _cffi_pypy_init_s { const char *name; - void (*func)(const void *[]); + void *func; /* function pointer */ const char *code; } _cffi_pypy_init = { _CFFI_MODULE_NAME, - (void(*)(const void *[]))_CFFI_PYTHON_STARTUP_FUNC, + _CFFI_PYTHON_STARTUP_FUNC, _CFFI_PYTHON_STARTUP_CODE, }; diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/cffi/api.py b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/cffi/api.py index 32fe6208..999a8aef 100644 --- a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/cffi/api.py +++ b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/cffi/api.py @@ -141,7 +141,11 @@ class FFI(object): linked to a particular library, just like C headers; in the library we only look for the actual (untyped) symbols. """ - assert isinstance(name, basestring) or name is None + if not (isinstance(name, basestring) or + name is None or + isinstance(name, self.CData)): + raise TypeError("dlopen(name): name must be a file name, None, " + "or an already-opened 'void *' handle") with self._lock: lib, function_cache = _make_ffi_library(self, name, flags) self._function_caches.append(function_cache) @@ -799,9 +803,9 @@ class FFI(object): def _load_backend_lib(backend, name, flags): import os - if name is None: - if sys.platform != "win32": - return backend.load_library(None, flags) + if not isinstance(name, basestring): + if sys.platform != "win32" or name is not None: + return backend.load_library(name, flags) name = "c" # Windows: load_library(None) fails, but this works # on Python 2 (backward compatibility hack only) first_error = None @@ -935,7 +939,7 @@ def _make_ffi_library(ffi, libname, flags): backendlib.close_lib() self.__dict__.clear() # - if libname is not None: + if isinstance(libname, basestring): try: if not isinstance(libname, str): # unicode, on Python 2 libname = libname.encode('utf-8') diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/cffi/backend_ctypes.py b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/cffi/backend_ctypes.py index 679ae057..e7956a79 100644 --- a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/cffi/backend_ctypes.py +++ b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/cffi/backend_ctypes.py @@ -403,7 +403,7 @@ class CTypesBackend(object): source = _cast_source_to_int(source) return cls(bool(source)) def __int__(self): - return self._value + return int(self._value) if kind == 'char': @classmethod diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/cffi/cparser.py b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/cffi/cparser.py index 262fd765..74830e91 100644 --- a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/cffi/cparser.py +++ b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/cffi/cparser.py @@ -29,6 +29,7 @@ _r_comment = re.compile(r"/\*.*?\*/|//([^\n\\]|\\.)*?$", _r_define = re.compile(r"^\s*#\s*define\s+([A-Za-z_][A-Za-z_0-9]*)" r"\b((?:[^\n\\]|\\.)*?)$", re.DOTALL | re.MULTILINE) +_r_line_directive = re.compile(r"^[ \t]*#[ \t]*(?:line|\d+)\b.*$", re.MULTILINE) _r_partial_enum = re.compile(r"=\s*\.\.\.\s*[,}]|\.\.\.\s*\}") _r_enum_dotdotdot = re.compile(r"__dotdotdot\d+__$") _r_partial_array = re.compile(r"\[\s*\.\.\.\s*\]") @@ -145,17 +146,55 @@ def _preprocess_extern_python(csource): return ''.join(parts) def _warn_for_string_literal(csource): - if '"' in csource: + if '"' not in csource: + return + for line in csource.splitlines(): + if '"' in line and not line.lstrip().startswith('#'): + import warnings + warnings.warn("String literal found in cdef() or type source. " + "String literals are ignored here, but you should " + "remove them anyway because some character sequences " + "confuse pre-parsing.") + break + +def _warn_for_non_extern_non_static_global_variable(decl): + if not decl.storage: import warnings - warnings.warn("String literal found in cdef() or type source. " - "String literals are ignored here, but you should " - "remove them anyway because some character sequences " - "confuse pre-parsing.") + warnings.warn("Global variable '%s' in cdef(): for consistency " + "with C it should have a storage class specifier " + "(usually 'extern')" % (decl.name,)) + +def _remove_line_directives(csource): + # _r_line_directive matches whole lines, without the final \n, if they + # start with '#line' with some spacing allowed, or '#NUMBER'. This + # function stores them away and replaces them with exactly the string + # '#line@N', where N is the index in the list 'line_directives'. + line_directives = [] + def replace(m): + i = len(line_directives) + line_directives.append(m.group()) + return '#line@%d' % i + csource = _r_line_directive.sub(replace, csource) + return csource, line_directives + +def _put_back_line_directives(csource, line_directives): + def replace(m): + s = m.group() + if not s.startswith('#line@'): + raise AssertionError("unexpected #line directive " + "(should have been processed and removed") + return line_directives[int(s[6:])] + return _r_line_directive.sub(replace, csource) def _preprocess(csource): + # First, remove the lines of the form '#line N "filename"' because + # the "filename" part could confuse the rest + csource, line_directives = _remove_line_directives(csource) # Remove comments. NOTE: this only work because the cdef() section - # should not contain any string literal! - csource = _r_comment.sub(' ', csource) + # should not contain any string literals (except in line directives)! + def replace_keeping_newlines(m): + return ' ' + m.group().count('\n') * '\n' + csource = _r_comment.sub(replace_keeping_newlines, csource) # Remove the "#define FOO x" lines macros = {} for match in _r_define.finditer(csource): @@ -208,7 +247,10 @@ def _preprocess(csource): csource = _r_float_dotdotdot.sub(' __dotdotdotfloat__ ', csource) # Replace all remaining "..." with the same name, "__dotdotdot__", # which is declared with a typedef for the purpose of C parsing. - return csource.replace('...', ' __dotdotdot__ '), macros + csource = csource.replace('...', ' __dotdotdot__ ') + # Finally, put back the line directives + csource = _put_back_line_directives(csource, line_directives) + return csource, macros def _common_type_names(csource): # Look in the source for what looks like usages of types from the @@ -384,7 +426,8 @@ class Parser(object): realtype = self._get_unknown_ptr_type(decl) else: realtype, quals = self._get_type_and_quals( - decl.type, name=decl.name, partial_length_ok=True) + decl.type, name=decl.name, partial_length_ok=True, + typedef_example="*(%s *)0" % (decl.name,)) self._declare('typedef ' + decl.name, realtype, quals=quals) elif decl.__class__.__name__ == 'Pragma': pass # skip pragma, only in pycparser 2.15 @@ -502,6 +545,7 @@ class Parser(object): if (quals & model.Q_CONST) and not tp.is_array_type: self._declare('constant ' + decl.name, tp, quals=quals) else: + _warn_for_non_extern_non_static_global_variable(decl) self._declare('variable ' + decl.name, tp, quals=quals) def parse_type(self, cdecl): @@ -550,7 +594,8 @@ class Parser(object): return model.NamedPointerType(type, declname, quals) return model.PointerType(type, quals) - def _get_type_and_quals(self, typenode, name=None, partial_length_ok=False): + def _get_type_and_quals(self, typenode, name=None, partial_length_ok=False, + typedef_example=None): # first, dereference typedefs, if we have it already parsed, we're good if (isinstance(typenode, pycparser.c_ast.TypeDecl) and isinstance(typenode.type, pycparser.c_ast.IdentifierType) and @@ -567,8 +612,18 @@ class Parser(object): else: length = self._parse_constant( typenode.dim, partial_length_ok=partial_length_ok) + # a hack: in 'typedef int foo_t[...][...];', don't use '...' as + # the length but use directly the C expression that would be + # generated by recompiler.py. This lets the typedef be used in + # many more places within recompiler.py + if typedef_example is not None: + if length == '...': + length = '_cffi_array_len(%s)' % (typedef_example,) + typedef_example = "*" + typedef_example + # tp, quals = self._get_type_and_quals(typenode.type, - partial_length_ok=partial_length_ok) + partial_length_ok=partial_length_ok, + typedef_example=typedef_example) return model.ArrayType(tp, length), quals # if isinstance(typenode, pycparser.c_ast.PtrDecl): @@ -858,19 +913,39 @@ class Parser(object): "the actual array length in this context" % exprnode.coord.line) # - if (isinstance(exprnode, pycparser.c_ast.BinaryOp) and - exprnode.op == '+'): - return (self._parse_constant(exprnode.left) + - self._parse_constant(exprnode.right)) - # - if (isinstance(exprnode, pycparser.c_ast.BinaryOp) and - exprnode.op == '-'): - return (self._parse_constant(exprnode.left) - - self._parse_constant(exprnode.right)) + if isinstance(exprnode, pycparser.c_ast.BinaryOp): + left = self._parse_constant(exprnode.left) + right = self._parse_constant(exprnode.right) + if exprnode.op == '+': + return left + right + elif exprnode.op == '-': + return left - right + elif exprnode.op == '*': + return left * right + elif exprnode.op == '/': + return self._c_div(left, right) + elif exprnode.op == '%': + return left - self._c_div(left, right) * right + elif exprnode.op == '<<': + return left << right + elif exprnode.op == '>>': + return left >> right + elif exprnode.op == '&': + return left & right + elif exprnode.op == '|': + return left | right + elif exprnode.op == '^': + return left ^ right # raise FFIError(":%d: unsupported expression: expected a " "simple numeric constant" % exprnode.coord.line) + def _c_div(self, a, b): + result = a // b + if ((a < 0) ^ (b < 0)) and (a % b) != 0: + result += 1 + return result + def _build_enum_type(self, explicit_name, decls): if decls is not None: partial = False diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/cffi/model.py b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/cffi/model.py index 5f1b0d2b..ad1c1764 100644 --- a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/cffi/model.py +++ b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/cffi/model.py @@ -307,11 +307,14 @@ class ArrayType(BaseType): self.c_name_with_marker = ( self.item.c_name_with_marker.replace('&', brackets)) + def length_is_unknown(self): + return isinstance(self.length, str) + def resolve_length(self, newlength): return ArrayType(self.item, newlength) def build_backend_type(self, ffi, finishlist): - if self.length == '...': + if self.length_is_unknown(): raise CDefError("cannot render the type %r: unknown length" % (self,)) self.item.get_cached_btype(ffi, finishlist) # force the item BType @@ -430,7 +433,7 @@ class StructOrUnion(StructOrUnionOrEnum): fsize = fieldsize[i] ftype = self.fldtypes[i] # - if isinstance(ftype, ArrayType) and ftype.length == '...': + if isinstance(ftype, ArrayType) and ftype.length_is_unknown(): # fix the length to match the total size BItemType = ftype.item.get_cached_btype(ffi, finishlist) nlen, nrest = divmod(fsize, ffi.sizeof(BItemType)) diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/cffi/recompiler.py b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/cffi/recompiler.py index 20e912b2..5d9d32d7 100644 --- a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/cffi/recompiler.py +++ b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/cffi/recompiler.py @@ -7,6 +7,9 @@ VERSION_BASE = 0x2601 VERSION_EMBEDDED = 0x2701 VERSION_CHAR16CHAR32 = 0x2801 +USE_LIMITED_API = (sys.platform != 'win32' or sys.version_info < (3, 0) or + sys.version_info >= (3, 5)) + class GlobalExpr: def __init__(self, name, address, type_op, size=0, check_value=0): @@ -190,6 +193,17 @@ class Recompiler: assert isinstance(op, CffiOp) self.cffi_types = tuple(self.cffi_types) # don't change any more + def _enum_fields(self, tp): + # When producing C, expand all anonymous struct/union fields. + # That's necessary to have C code checking the offsets of the + # individual fields contained in them. When producing Python, + # don't do it and instead write it like it is, with the + # corresponding fields having an empty name. Empty names are + # recognized at runtime when we import the generated Python + # file. + expand_anonymous_struct_union = not self.target_is_python + return tp.enumfields(expand_anonymous_struct_union) + def _do_collect_type(self, tp): if not isinstance(tp, model.BaseTypeByIdentity): if isinstance(tp, tuple): @@ -203,7 +217,7 @@ class Recompiler: elif isinstance(tp, model.StructOrUnion): if tp.fldtypes is not None and ( tp not in self.ffi._parser._included_declarations): - for name1, tp1, _, _ in tp.enumfields(): + for name1, tp1, _, _ in self._enum_fields(tp): self._do_collect_type(self._field_type(tp, name1, tp1)) else: for _, x in tp._get_items(): @@ -283,6 +297,8 @@ class Recompiler: prnt = self._prnt if self.ffi._embedding is not None: prnt('#define _CFFI_USE_EMBEDDING') + if not USE_LIMITED_API: + prnt('#define _CFFI_NO_LIMITED_API') # # first the '#include' (actually done by inlining the file's content) lines = self._rel_readlines('_cffi_include.h') @@ -391,7 +407,7 @@ class Recompiler: prnt(' NULL, /* no includes */') prnt(' %d, /* num_types */' % (len(self.cffi_types),)) flags = 0 - if self._num_externpy: + if self._num_externpy > 0 or self.ffi._embedding is not None: flags |= 1 # set to mean that we use extern "Python" prnt(' %d, /* flags */' % flags) prnt('};') @@ -406,7 +422,7 @@ class Recompiler: prnt('PyMODINIT_FUNC') prnt('_cffi_pypyinit_%s(const void *p[])' % (base_module_name,)) prnt('{') - if self._num_externpy: + if flags & 1: prnt(' if (((intptr_t)p[0]) >= 0x0A03) {') prnt(' _cffi_call_python_org = ' '(void(*)(struct _cffi_externpy_s *, char *))p[1];') @@ -560,23 +576,24 @@ class Recompiler: tovar, tp.get_c_name(''), errvalue)) self._prnt(' %s;' % errcode) - def _extra_local_variables(self, tp, localvars): + def _extra_local_variables(self, tp, localvars, freelines): if isinstance(tp, model.PointerType): localvars.add('Py_ssize_t datasize') + localvars.add('struct _cffi_freeme_s *large_args_free = NULL') + freelines.add('if (large_args_free != NULL)' + ' _cffi_free_array_arguments(large_args_free);') def _convert_funcarg_to_c_ptr_or_array(self, tp, fromvar, tovar, errcode): self._prnt(' datasize = _cffi_prepare_pointer_call_argument(') self._prnt(' _cffi_type(%d), %s, (char **)&%s);' % ( self._gettypenum(tp), fromvar, tovar)) self._prnt(' if (datasize != 0) {') - self._prnt(' if (datasize < 0)') - self._prnt(' %s;' % errcode) - self._prnt(' %s = (%s)alloca((size_t)datasize);' % ( + self._prnt(' %s = ((size_t)datasize) <= 640 ? ' + '(%s)alloca((size_t)datasize) : NULL;' % ( tovar, tp.get_c_name(''))) - self._prnt(' memset((void *)%s, 0, (size_t)datasize);' % (tovar,)) - self._prnt(' if (_cffi_convert_array_from_object(' - '(char *)%s, _cffi_type(%d), %s) < 0)' % ( - tovar, self._gettypenum(tp), fromvar)) + self._prnt(' if (_cffi_convert_array_argument(_cffi_type(%d), %s, ' + '(char **)&%s,' % (self._gettypenum(tp), fromvar, tovar)) + self._prnt(' datasize, &large_args_free) < 0)') self._prnt(' %s;' % errcode) self._prnt(' }') @@ -699,9 +716,10 @@ class Recompiler: prnt(' %s;' % arg) # localvars = set() + freelines = set() for type in tp.args: - self._extra_local_variables(type, localvars) - for decl in localvars: + self._extra_local_variables(type, localvars, freelines) + for decl in sorted(localvars): prnt(' %s;' % (decl,)) # if not isinstance(tp.result, model.VoidType): @@ -709,6 +727,7 @@ class Recompiler: context = 'result of %s' % name result_decl = ' %s;' % tp.result.get_c_name(' result', context) prnt(result_decl) + prnt(' PyObject *pyresult;') else: result_decl = None result_code = '' @@ -742,9 +761,14 @@ class Recompiler: if numargs == 0: prnt(' (void)noarg; /* unused */') if result_code: - prnt(' return %s;' % + prnt(' pyresult = %s;' % self._convert_expr_from_c(tp.result, 'result', 'result type')) + for freeline in freelines: + prnt(' ' + freeline) + prnt(' return pyresult;') else: + for freeline in freelines: + prnt(' ' + freeline) prnt(' Py_INCREF(Py_None);') prnt(' return Py_None;') prnt('}') @@ -851,12 +875,13 @@ class Recompiler: prnt('{') prnt(' /* only to generate compile-time warnings or errors */') prnt(' (void)p;') - for fname, ftype, fbitsize, fqual in tp.enumfields(): + for fname, ftype, fbitsize, fqual in self._enum_fields(tp): try: if ftype.is_integer_type() or fbitsize >= 0: # accept all integers, but complain on float or double - prnt(" (void)((p->%s) | 0); /* check that '%s.%s' is " - "an integer */" % (fname, cname, fname)) + if fname != '': + prnt(" (void)((p->%s) | 0); /* check that '%s.%s' is " + "an integer */" % (fname, cname, fname)) continue # only accept exactly the type declared, except that '[]' # is interpreted as a '*' and so will match any array length. @@ -906,8 +931,7 @@ class Recompiler: flags = '|'.join(flags) or '0' c_fields = [] if reason_for_not_expanding is None: - expand_anonymous_struct_union = not self.target_is_python - enumfields = list(tp.enumfields(expand_anonymous_struct_union)) + enumfields = list(self._enum_fields(tp)) for fldname, fldtype, fbitsize, fqual in enumfields: fldtype = self._field_type(tp, fldname, fldtype) self._check_not_opaque(fldtype, @@ -1215,7 +1239,8 @@ class Recompiler: size_of_result = '(int)sizeof(%s)' % ( tp.result.get_c_name('', context),) prnt('static struct _cffi_externpy_s _cffi_externpy__%s =' % name) - prnt(' { "%s.%s", %s };' % (self.module_name, name, size_of_result)) + prnt(' { "%s.%s", %s, 0, 0 };' % ( + self.module_name, name, size_of_result)) prnt() # arguments = [] @@ -1286,14 +1311,28 @@ class Recompiler: def _print_string_literal_in_array(self, s): prnt = self._prnt prnt('// # NB. this is not a string because of a size limit in MSVC') + if not isinstance(s, bytes): # unicode + s = s.encode('utf-8') # -> bytes + else: + s.decode('utf-8') # got bytes, check for valid utf-8 + try: + s.decode('ascii') + except UnicodeDecodeError: + s = b'# -*- encoding: utf8 -*-\n' + s for line in s.splitlines(True): - prnt(('// ' + line).rstrip()) + comment = line + if type('//') is bytes: # python2 + line = map(ord, line) # make a list of integers + else: # python3 + # type(line) is bytes, which enumerates like a list of integers + comment = ascii(comment)[1:-1] + prnt(('// ' + comment).rstrip()) printed_line = '' for c in line: if len(printed_line) >= 76: prnt(printed_line) printed_line = '' - printed_line += '%d,' % (ord(c),) + printed_line += '%d,' % (c,) prnt(printed_line) # ---------- diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/cffi/setuptools_ext.py b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/cffi/setuptools_ext.py index df5a5183..8fe36148 100644 --- a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/cffi/setuptools_ext.py +++ b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/cffi/setuptools_ext.py @@ -84,11 +84,13 @@ def _set_py_limited_api(Extension, kwds): On Windows, with CPython <= 3.4, it's better not to use py_limited_api because virtualenv *still* doesn't copy PYTHON3.DLL on these versions. - For now we'll skip py_limited_api on all Windows versions to avoid an - inconsistent mess. + Recently (2020) we started shipping only >= 3.5 wheels, though. So + we'll give it another try and set py_limited_api on Windows >= 3.5. """ + from cffi import recompiler + if ('py_limited_api' not in kwds and not hasattr(sys, 'gettotalrefcount') - and sys.platform != 'win32'): + and recompiler.USE_LIMITED_API): import setuptools try: setuptools_major_version = int(setuptools.__version__.partition('.')[0]) diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/cffi/vengine_cpy.py b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/cffi/vengine_cpy.py index 536f11f8..6de0df0e 100644 --- a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/cffi/vengine_cpy.py +++ b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/cffi/vengine_cpy.py @@ -275,22 +275,23 @@ class VCPythonEngine(object): tovar, tp.get_c_name(''), errvalue)) self._prnt(' %s;' % errcode) - def _extra_local_variables(self, tp, localvars): + def _extra_local_variables(self, tp, localvars, freelines): if isinstance(tp, model.PointerType): localvars.add('Py_ssize_t datasize') + localvars.add('struct _cffi_freeme_s *large_args_free = NULL') + freelines.add('if (large_args_free != NULL)' + ' _cffi_free_array_arguments(large_args_free);') def _convert_funcarg_to_c_ptr_or_array(self, tp, fromvar, tovar, errcode): self._prnt(' datasize = _cffi_prepare_pointer_call_argument(') self._prnt(' _cffi_type(%d), %s, (char **)&%s);' % ( self._gettypenum(tp), fromvar, tovar)) self._prnt(' if (datasize != 0) {') - self._prnt(' if (datasize < 0)') - self._prnt(' %s;' % errcode) - self._prnt(' %s = alloca((size_t)datasize);' % (tovar,)) - self._prnt(' memset((void *)%s, 0, (size_t)datasize);' % (tovar,)) - self._prnt(' if (_cffi_convert_array_from_object(' - '(char *)%s, _cffi_type(%d), %s) < 0)' % ( - tovar, self._gettypenum(tp), fromvar)) + self._prnt(' %s = ((size_t)datasize) <= 640 ? ' + 'alloca((size_t)datasize) : NULL;' % (tovar,)) + self._prnt(' if (_cffi_convert_array_argument(_cffi_type(%d), %s, ' + '(char **)&%s,' % (self._gettypenum(tp), fromvar, tovar)) + self._prnt(' datasize, &large_args_free) < 0)') self._prnt(' %s;' % errcode) self._prnt(' }') @@ -369,15 +370,17 @@ class VCPythonEngine(object): prnt(' %s;' % type.get_c_name(' x%d' % i, context)) # localvars = set() + freelines = set() for type in tp.args: - self._extra_local_variables(type, localvars) - for decl in localvars: + self._extra_local_variables(type, localvars, freelines) + for decl in sorted(localvars): prnt(' %s;' % (decl,)) # if not isinstance(tp.result, model.VoidType): result_code = 'result = ' context = 'result of %s' % name prnt(' %s;' % tp.result.get_c_name(' result', context)) + prnt(' PyObject *pyresult;') else: result_code = '' # @@ -409,9 +412,14 @@ class VCPythonEngine(object): if numargs == 0: prnt(' (void)noarg; /* unused */') if result_code: - prnt(' return %s;' % + prnt(' pyresult = %s;' % self._convert_expr_from_c(tp.result, 'result', 'result type')) + for freeline in freelines: + prnt(' ' + freeline) + prnt(' return pyresult;') else: + for freeline in freelines: + prnt(' ' + freeline) prnt(' Py_INCREF(Py_None);') prnt(' return Py_None;') prnt('}') @@ -754,7 +762,7 @@ class VCPythonEngine(object): if isinstance(tp, model.ArrayType): tp_ptr = model.PointerType(tp.item) self._generate_cpy_const(False, name, tp, vartp=tp_ptr, - size_too = (tp.length == '...')) + size_too = tp.length_is_unknown()) else: tp_ptr = model.PointerType(tp) self._generate_cpy_const(False, name, tp_ptr, category='var') @@ -766,7 +774,7 @@ class VCPythonEngine(object): value = getattr(library, name) if isinstance(tp, model.ArrayType): # int a[5] is "constant" in the # sense that "a=..." is forbidden - if tp.length == '...': + if tp.length_is_unknown(): assert isinstance(value, tuple) (value, size) = value BItemType = self.ffi._get_cached_btype(tp.item) @@ -981,6 +989,59 @@ static PyObject *_cffi_setup(PyObject *self, PyObject *args) return PyBool_FromLong(was_alive); } +union _cffi_union_alignment_u { + unsigned char m_char; + unsigned short m_short; + unsigned int m_int; + unsigned long m_long; + unsigned long long m_longlong; + float m_float; + double m_double; + long double m_longdouble; +}; + +struct _cffi_freeme_s { + struct _cffi_freeme_s *next; + union _cffi_union_alignment_u alignment; +}; + +#ifdef __GNUC__ + __attribute__((unused)) +#endif +static int _cffi_convert_array_argument(CTypeDescrObject *ctptr, PyObject *arg, + char **output_data, Py_ssize_t datasize, + struct _cffi_freeme_s **freeme) +{ + char *p; + if (datasize < 0) + return -1; + + p = *output_data; + if (p == NULL) { + struct _cffi_freeme_s *fp = (struct _cffi_freeme_s *)PyObject_Malloc( + offsetof(struct _cffi_freeme_s, alignment) + (size_t)datasize); + if (fp == NULL) + return -1; + fp->next = *freeme; + *freeme = fp; + p = *output_data = (char *)&fp->alignment; + } + memset((void *)p, 0, (size_t)datasize); + return _cffi_convert_array_from_object(p, ctptr, arg); +} + +#ifdef __GNUC__ + __attribute__((unused)) +#endif +static void _cffi_free_array_arguments(struct _cffi_freeme_s *freeme) +{ + do { + void *p = (void *)freeme; + freeme = freeme->next; + PyObject_Free(p); + } while (freeme != NULL); +} + static int _cffi_init(void) { PyObject *module, *c_api_object = NULL; diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/cffi/vengine_gen.py b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/cffi/vengine_gen.py index a64ff644..26421526 100644 --- a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/cffi/vengine_gen.py +++ b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/cffi/vengine_gen.py @@ -565,7 +565,7 @@ class VGenericEngine(object): def _generate_gen_variable_decl(self, tp, name): if isinstance(tp, model.ArrayType): - if tp.length == '...': + if tp.length_is_unknown(): prnt = self._prnt funcname = '_cffi_sizeof_%s' % (name,) self.export_symbols.append(funcname) @@ -584,7 +584,7 @@ class VGenericEngine(object): def _loaded_gen_variable(self, tp, name, module, library): if isinstance(tp, model.ArrayType): # int a[5] is "constant" in the # sense that "a=..." is forbidden - if tp.length == '...': + if tp.length_is_unknown(): funcname = '_cffi_sizeof_%s' % (name,) BFunc = self.ffi._typeof_locked('size_t(*)(void)')[0] function = module.load_function(BFunc, funcname) diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/cffi/verifier.py b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/cffi/verifier.py index 59b78c21..a500c781 100644 --- a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/cffi/verifier.py +++ b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/cffi/verifier.py @@ -50,7 +50,8 @@ class Verifier(object): if tag: raise TypeError("can't specify both 'modulename' and 'tag'") else: - key = '\x00'.join([sys.version[:3], __version_verifier_modules__, + key = '\x00'.join(['%d.%d' % sys.version_info[:2], + __version_verifier_modules__, preamble, flattened_kwds] + ffi._cdefsources) if sys.version_info >= (3,): diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/h11-0.13.0.dist-info/INSTALLER b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/h11-0.13.0.dist-info/INSTALLER new file mode 100644 index 00000000..a1b589e3 --- /dev/null +++ b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/h11-0.13.0.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/h11-0.13.0.dist-info/LICENSE.txt b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/h11-0.13.0.dist-info/LICENSE.txt new file mode 100644 index 00000000..8f080eae --- /dev/null +++ b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/h11-0.13.0.dist-info/LICENSE.txt @@ -0,0 +1,22 @@ +The MIT License (MIT) + +Copyright (c) 2016 Nathaniel J. Smith and other contributors + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/h11-0.13.0.dist-info/METADATA b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/h11-0.13.0.dist-info/METADATA new file mode 100644 index 00000000..8c77b40c --- /dev/null +++ b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/h11-0.13.0.dist-info/METADATA @@ -0,0 +1,197 @@ +Metadata-Version: 2.1 +Name: h11 +Version: 0.13.0 +Summary: A pure-Python, bring-your-own-I/O implementation of HTTP/1.1 +Home-page: https://github.com/python-hyper/h11 +Author: Nathaniel J. Smith +Author-email: njs@pobox.com +License: MIT +Platform: UNKNOWN +Classifier: Development Status :: 3 - Alpha +Classifier: Intended Audience :: Developers +Classifier: License :: OSI Approved :: MIT License +Classifier: Programming Language :: Python :: Implementation :: CPython +Classifier: Programming Language :: Python :: Implementation :: PyPy +Classifier: Programming Language :: Python :: 3 +Classifier: Programming Language :: Python :: 3 :: Only +Classifier: Programming Language :: Python :: 3.6 +Classifier: Programming Language :: Python :: 3.7 +Classifier: Programming Language :: Python :: 3.8 +Classifier: Programming Language :: Python :: 3.9 +Classifier: Topic :: Internet :: WWW/HTTP +Classifier: Topic :: System :: Networking +Requires-Python: >=3.6 +License-File: LICENSE.txt +Requires-Dist: dataclasses ; python_version < "3.7" +Requires-Dist: typing-extensions ; python_version < "3.8" + +h11 +=== + +.. image:: https://travis-ci.org/python-hyper/h11.svg?branch=master + :target: https://travis-ci.org/python-hyper/h11 + :alt: Automated test status + +.. image:: https://codecov.io/gh/python-hyper/h11/branch/master/graph/badge.svg + :target: https://codecov.io/gh/python-hyper/h11 + :alt: Test coverage + +.. image:: https://readthedocs.org/projects/h11/badge/?version=latest + :target: http://h11.readthedocs.io/en/latest/?badge=latest + :alt: Documentation Status + +This is a little HTTP/1.1 library written from scratch in Python, +heavily inspired by `hyper-h2 `_. + +It's a "bring-your-own-I/O" library; h11 contains no IO code +whatsoever. This means you can hook h11 up to your favorite network +API, and that could be anything you want: synchronous, threaded, +asynchronous, or your own implementation of `RFC 6214 +`_ -- h11 won't judge you. +(Compare this to the current state of the art, where every time a `new +network API `_ comes along then someone +gets to start over reimplementing the entire HTTP protocol from +scratch.) Cory Benfield made an `excellent blog post describing the +benefits of this approach +`_, or if you like video +then here's his `PyCon 2016 talk on the same theme +`_. + +This also means that h11 is not immediately useful out of the box: +it's a toolkit for building programs that speak HTTP, not something +that could directly replace ``requests`` or ``twisted.web`` or +whatever. But h11 makes it much easier to implement something like +``requests`` or ``twisted.web``. + +At a high level, working with h11 goes like this: + +1) First, create an ``h11.Connection`` object to track the state of a + single HTTP/1.1 connection. + +2) When you read data off the network, pass it to + ``conn.receive_data(...)``; you'll get back a list of objects + representing high-level HTTP "events". + +3) When you want to send a high-level HTTP event, create the + corresponding "event" object and pass it to ``conn.send(...)``; + this will give you back some bytes that you can then push out + through the network. + +For example, a client might instantiate and then send a +``h11.Request`` object, then zero or more ``h11.Data`` objects for the +request body (e.g., if this is a POST), and then a +``h11.EndOfMessage`` to indicate the end of the message. Then the +server would then send back a ``h11.Response``, some ``h11.Data``, and +its own ``h11.EndOfMessage``. If either side violates the protocol, +you'll get a ``h11.ProtocolError`` exception. + +h11 is suitable for implementing both servers and clients, and has a +pleasantly symmetric API: the events you send as a client are exactly +the ones that you receive as a server and vice-versa. + +`Here's an example of a tiny HTTP client +`_ + +It also has `a fine manual `_. + +FAQ +--- + +*Whyyyyy?* + +I wanted to play with HTTP in `Curio +`__ and `Trio +`__, which at the time didn't have any +HTTP libraries. So I thought, no big deal, Python has, like, a dozen +different implementations of HTTP, surely I can find one that's +reusable. I didn't find one, but I did find Cory's call-to-arms +blog-post. So I figured, well, fine, if I have to implement HTTP from +scratch, at least I can make sure no-one *else* has to ever again. + +*Should I use it?* + +Maybe. You should be aware that it's a very young project. But, it's +feature complete and has an exhaustive test-suite and complete docs, +so the next step is for people to try using it and see how it goes +:-). If you do then please let us know -- if nothing else we'll want +to talk to you before making any incompatible changes! + +*What are the features/limitations?* + +Roughly speaking, it's trying to be a robust, complete, and non-hacky +implementation of the first "chapter" of the HTTP/1.1 spec: `RFC 7230: +HTTP/1.1 Message Syntax and Routing +`_. That is, it mostly focuses on +implementing HTTP at the level of taking bytes on and off the wire, +and the headers related to that, and tries to be anal about spec +conformance. It doesn't know about higher-level concerns like URL +routing, conditional GETs, cross-origin cookie policies, or content +negotiation. But it does know how to take care of framing, +cross-version differences in keep-alive handling, and the "obsolete +line folding" rule, so you can focus your energies on the hard / +interesting parts for your application, and it tries to support the +full specification in the sense that any useful HTTP/1.1 conformant +application should be able to use h11. + +It's pure Python, and has no dependencies outside of the standard +library. + +It has a test suite with 100.0% coverage for both statements and +branches. + +Currently it supports Python 3 (testing on 3.6-3.9) and PyPy 3. +The last Python 2-compatible version was h11 0.11.x. +(Originally it had a Cython wrapper for `http-parser +`_ and a beautiful nested state +machine implemented with ``yield from`` to postprocess the output. But +I had to take these out -- the new *parser* needs fewer lines-of-code +than the old *parser wrapper*, is written in pure Python, uses no +exotic language syntax, and has more features. It's sad, really; that +old state machine was really slick. I just need a few sentences here +to mourn that.) + +I don't know how fast it is. I haven't benchmarked or profiled it yet, +so it's probably got a few pointless hot spots, and I've been trying +to err on the side of simplicity and robustness instead of +micro-optimization. But at the architectural level I tried hard to +avoid fundamentally bad decisions, e.g., I believe that all the +parsing algorithms remain linear-time even in the face of pathological +input like slowloris, and there are no byte-by-byte loops. (I also +believe that it maintains bounded memory usage in the face of +arbitrary/pathological input.) + +The whole library is ~800 lines-of-code. You can read and understand +the whole thing in less than an hour. Most of the energy invested in +this so far has been spent on trying to keep things simple by +minimizing special-cases and ad hoc state manipulation; even though it +is now quite small and simple, I'm still annoyed that I haven't +figured out how to make it even smaller and simpler. (Unfortunately, +HTTP does not lend itself to simplicity.) + +The API is ~feature complete and I don't expect the general outlines +to change much, but you can't judge an API's ergonomics until you +actually document and use it, so I'd expect some changes in the +details. + +*How do I try it?* + +.. code-block:: sh + + $ pip install h11 + $ git clone git@github.com:python-hyper/h11 + $ cd h11/examples + $ python basic-client.py + +and go from there. + +*License?* + +MIT + +*Code of conduct?* + +Contributors are requested to follow our `code of conduct +`_ in +all project spaces. + + diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/h11-0.13.0.dist-info/RECORD b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/h11-0.13.0.dist-info/RECORD new file mode 100644 index 00000000..98ad52af --- /dev/null +++ b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/h11-0.13.0.dist-info/RECORD @@ -0,0 +1,52 @@ +h11-0.13.0.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +h11-0.13.0.dist-info/LICENSE.txt,sha256=N9tbuFkm2yikJ6JYZ_ELEjIAOuob5pzLhRE4rbjm82E,1124 +h11-0.13.0.dist-info/METADATA,sha256=Fd9foEJycn0gUB9YsXul6neMlYnEU0MRQ8IUBsSOHxE,8245 +h11-0.13.0.dist-info/RECORD,, +h11-0.13.0.dist-info/WHEEL,sha256=ewwEueio1C2XeHTvT17n8dZUJgOvyCWCt0WVNLClP9o,92 +h11-0.13.0.dist-info/top_level.txt,sha256=F7dC4jl3zeh8TGHEPaWJrMbeuoWbS379Gwdi-Yvdcis,4 +h11/__init__.py,sha256=iO1KzkSO42yZ6ffg-VMgbx_ZVTWGUY00nRYEWn-s3kY,1507 +h11/__pycache__/__init__.cpython-37.pyc,, +h11/__pycache__/_abnf.cpython-37.pyc,, +h11/__pycache__/_connection.cpython-37.pyc,, +h11/__pycache__/_events.cpython-37.pyc,, +h11/__pycache__/_headers.cpython-37.pyc,, +h11/__pycache__/_readers.cpython-37.pyc,, +h11/__pycache__/_receivebuffer.cpython-37.pyc,, +h11/__pycache__/_state.cpython-37.pyc,, +h11/__pycache__/_util.cpython-37.pyc,, +h11/__pycache__/_version.cpython-37.pyc,, +h11/__pycache__/_writers.cpython-37.pyc,, +h11/_abnf.py,sha256=tMKqgOEkTHHp8sPd_gmU9Qowe_yXXrihct63RX2zJsg,4637 +h11/_connection.py,sha256=udHjqEO1fOcQUKa3hYIw88DMeoyG4fxiIXKjgE4DwJw,26480 +h11/_events.py,sha256=LEfuvg1AbhHaVRwxCd0I-pFn9-ezUOaoL8o2Kvy1PBA,11816 +h11/_headers.py,sha256=tRwZuFy5Wj4Yi9VVad_s7EqwCgeN6O3TIbcHd5CN_GI,10230 +h11/_readers.py,sha256=TWWoSbLVBfYGzD5dunReTd2QCxz466wjwu-4Fkzk_sQ,8370 +h11/_receivebuffer.py,sha256=xrspsdsNgWFxRfQcTXxR8RrdjRXXTK0Io5cQYWpJ1Ws,5252 +h11/_state.py,sha256=F8MPHIFMJV3kUPYR3YjrjqjJ1AYp_FZ38UwGr0855lE,13184 +h11/_util.py,sha256=LWkkjXyJaFlAy6Lt39w73UStklFT5ovcvo0TkY7RYuk,4888 +h11/_version.py,sha256=ye-8iNs3P1TB71VRGlNQe2OxnAe-RupjozAMywAS5z8,686 +h11/_writers.py,sha256=7WBTXyJqFAUqqmLl5adGF8_7UVQdOVa2phL8s8csljI,5063 +h11/py.typed,sha256=sow9soTwP9T_gEAQSVh7Gb8855h04Nwmhs2We-JRgZM,7 +h11/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +h11/tests/__pycache__/__init__.cpython-37.pyc,, +h11/tests/__pycache__/helpers.cpython-37.pyc,, +h11/tests/__pycache__/test_against_stdlib_http.cpython-37.pyc,, +h11/tests/__pycache__/test_connection.cpython-37.pyc,, +h11/tests/__pycache__/test_events.cpython-37.pyc,, +h11/tests/__pycache__/test_headers.cpython-37.pyc,, +h11/tests/__pycache__/test_helpers.cpython-37.pyc,, +h11/tests/__pycache__/test_io.cpython-37.pyc,, +h11/tests/__pycache__/test_receivebuffer.cpython-37.pyc,, +h11/tests/__pycache__/test_state.cpython-37.pyc,, +h11/tests/__pycache__/test_util.cpython-37.pyc,, +h11/tests/data/test-file,sha256=ZJ03Rqs98oJw29OHzJg7LlMzyGQaRAY0r3AqBeM2wVU,65 +h11/tests/helpers.py,sha256=a1EVG_p7xU4wRsa3tMPTRxuaKCmretok9sxXWvqfmQA,3355 +h11/tests/test_against_stdlib_http.py,sha256=cojCHgHXFQ8gWhNlEEwl3trmOpN-5uDukRoHnElqo3A,3995 +h11/tests/test_connection.py,sha256=ZbPLDPclKvjgjAhgk-WlCPBaf17c4XUIV2tpaW08jOI,38720 +h11/tests/test_events.py,sha256=LPVLbcV-NvPNK9fW3rraR6Bdpz1hAlsWubMtNaJ5gHg,4657 +h11/tests/test_headers.py,sha256=qd8T1Zenuz5GbD6wklSJ5G8VS7trrYgMV0jT-SMvqg8,5612 +h11/tests/test_helpers.py,sha256=kAo0CEM4LGqmyyP2ZFmhsyq3UFJqoFfAbzu3hbWreRM,794 +h11/tests/test_io.py,sha256=gXFSKpcx6n3-Ld0Y8w5kBkom1LZsCq3uHtqdotQ3S2c,16243 +h11/tests/test_receivebuffer.py,sha256=3jGbeJM36Akqg_pAhPb7XzIn2NS6RhPg-Ryg8Eu6ytk,3454 +h11/tests/test_state.py,sha256=rqll9WqFsJPE0zSrtCn9LH659mPKsDeXZ-DwXwleuBQ,8928 +h11/tests/test_util.py,sha256=ZWdRng_P-JP-cnvmcBhazBxfyWmEKBB0NLrDy5eq3h0,2970 diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/h11-0.13.0.dist-info/WHEEL b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/h11-0.13.0.dist-info/WHEEL new file mode 100644 index 00000000..5bad85fd --- /dev/null +++ b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/h11-0.13.0.dist-info/WHEEL @@ -0,0 +1,5 @@ +Wheel-Version: 1.0 +Generator: bdist_wheel (0.37.0) +Root-Is-Purelib: true +Tag: py3-none-any + diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/h11-0.13.0.dist-info/top_level.txt b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/h11-0.13.0.dist-info/top_level.txt new file mode 100644 index 00000000..0d24def7 --- /dev/null +++ b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/h11-0.13.0.dist-info/top_level.txt @@ -0,0 +1 @@ +h11 diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/h11/__init__.py b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/h11/__init__.py new file mode 100644 index 00000000..989e92c3 --- /dev/null +++ b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/h11/__init__.py @@ -0,0 +1,62 @@ +# A highish-level implementation of the HTTP/1.1 wire protocol (RFC 7230), +# containing no networking code at all, loosely modelled on hyper-h2's generic +# implementation of HTTP/2 (and in particular the h2.connection.H2Connection +# class). There's still a bunch of subtle details you need to get right if you +# want to make this actually useful, because it doesn't implement all the +# semantics to check that what you're asking to write to the wire is sensible, +# but at least it gets you out of dealing with the wire itself. + +from h11._connection import Connection, NEED_DATA, PAUSED +from h11._events import ( + ConnectionClosed, + Data, + EndOfMessage, + Event, + InformationalResponse, + Request, + Response, +) +from h11._state import ( + CLIENT, + CLOSED, + DONE, + ERROR, + IDLE, + MIGHT_SWITCH_PROTOCOL, + MUST_CLOSE, + SEND_BODY, + SEND_RESPONSE, + SERVER, + SWITCHED_PROTOCOL, +) +from h11._util import LocalProtocolError, ProtocolError, RemoteProtocolError +from h11._version import __version__ + +PRODUCT_ID = "python-h11/" + __version__ + + +__all__ = ( + "Connection", + "NEED_DATA", + "PAUSED", + "ConnectionClosed", + "Data", + "EndOfMessage", + "Event", + "InformationalResponse", + "Request", + "Response", + "CLIENT", + "CLOSED", + "DONE", + "ERROR", + "IDLE", + "MUST_CLOSE", + "SEND_BODY", + "SEND_RESPONSE", + "SERVER", + "SWITCHED_PROTOCOL", + "ProtocolError", + "LocalProtocolError", + "RemoteProtocolError", +) diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/h11/_abnf.py b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/h11/_abnf.py new file mode 100644 index 00000000..e6d49e1e --- /dev/null +++ b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/h11/_abnf.py @@ -0,0 +1,129 @@ +# We use native strings for all the re patterns, to take advantage of string +# formatting, and then convert to bytestrings when compiling the final re +# objects. + +# https://svn.tools.ietf.org/svn/wg/httpbis/specs/rfc7230.html#whitespace +# OWS = *( SP / HTAB ) +# ; optional whitespace +OWS = r"[ \t]*" + +# https://svn.tools.ietf.org/svn/wg/httpbis/specs/rfc7230.html#rule.token.separators +# token = 1*tchar +# +# tchar = "!" / "#" / "$" / "%" / "&" / "'" / "*" +# / "+" / "-" / "." / "^" / "_" / "`" / "|" / "~" +# / DIGIT / ALPHA +# ; any VCHAR, except delimiters +token = r"[-!#$%&'*+.^_`|~0-9a-zA-Z]+" + +# https://svn.tools.ietf.org/svn/wg/httpbis/specs/rfc7230.html#header.fields +# field-name = token +field_name = token + +# The standard says: +# +# field-value = *( field-content / obs-fold ) +# field-content = field-vchar [ 1*( SP / HTAB ) field-vchar ] +# field-vchar = VCHAR / obs-text +# obs-fold = CRLF 1*( SP / HTAB ) +# ; obsolete line folding +# ; see Section 3.2.4 +# +# https://tools.ietf.org/html/rfc5234#appendix-B.1 +# +# VCHAR = %x21-7E +# ; visible (printing) characters +# +# https://svn.tools.ietf.org/svn/wg/httpbis/specs/rfc7230.html#rule.quoted-string +# obs-text = %x80-FF +# +# However, the standard definition of field-content is WRONG! It disallows +# fields containing a single visible character surrounded by whitespace, +# e.g. "foo a bar". +# +# See: https://www.rfc-editor.org/errata_search.php?rfc=7230&eid=4189 +# +# So our definition of field_content attempts to fix it up... +# +# Also, we allow lots of control characters, because apparently people assume +# that they're legal in practice (e.g., google analytics makes cookies with +# \x01 in them!): +# https://github.com/python-hyper/h11/issues/57 +# We still don't allow NUL or whitespace, because those are often treated as +# meta-characters and letting them through can lead to nasty issues like SSRF. +vchar = r"[\x21-\x7e]" +vchar_or_obs_text = r"[^\x00\s]" +field_vchar = vchar_or_obs_text +field_content = r"{field_vchar}+(?:[ \t]+{field_vchar}+)*".format(**globals()) + +# We handle obs-fold at a different level, and our fixed-up field_content +# already grows to swallow the whole value, so ? instead of * +field_value = r"({field_content})?".format(**globals()) + +# header-field = field-name ":" OWS field-value OWS +header_field = ( + r"(?P{field_name})" + r":" + r"{OWS}" + r"(?P{field_value})" + r"{OWS}".format(**globals()) +) + +# https://svn.tools.ietf.org/svn/wg/httpbis/specs/rfc7230.html#request.line +# +# request-line = method SP request-target SP HTTP-version CRLF +# method = token +# HTTP-version = HTTP-name "/" DIGIT "." DIGIT +# HTTP-name = %x48.54.54.50 ; "HTTP", case-sensitive +# +# request-target is complicated (see RFC 7230 sec 5.3) -- could be path, full +# URL, host+port (for connect), or even "*", but in any case we are guaranteed +# that it contists of the visible printing characters. +method = token +request_target = r"{vchar}+".format(**globals()) +http_version = r"HTTP/(?P[0-9]\.[0-9])" +request_line = ( + r"(?P{method})" + r" " + r"(?P{request_target})" + r" " + r"{http_version}".format(**globals()) +) + +# https://svn.tools.ietf.org/svn/wg/httpbis/specs/rfc7230.html#status.line +# +# status-line = HTTP-version SP status-code SP reason-phrase CRLF +# status-code = 3DIGIT +# reason-phrase = *( HTAB / SP / VCHAR / obs-text ) +status_code = r"[0-9]{3}" +reason_phrase = r"([ \t]|{vchar_or_obs_text})*".format(**globals()) +status_line = ( + r"{http_version}" + r" " + r"(?P{status_code})" + # However, there are apparently a few too many servers out there that just + # leave out the reason phrase: + # https://github.com/scrapy/scrapy/issues/345#issuecomment-281756036 + # https://github.com/seanmonstar/httparse/issues/29 + # so make it optional. ?: is a non-capturing group. + r"(?: (?P{reason_phrase}))?".format(**globals()) +) + +HEXDIG = r"[0-9A-Fa-f]" +# Actually +# +# chunk-size = 1*HEXDIG +# +# but we impose an upper-limit to avoid ridiculosity. len(str(2**64)) == 20 +chunk_size = r"({HEXDIG}){{1,20}}".format(**globals()) +# Actually +# +# chunk-ext = *( ";" chunk-ext-name [ "=" chunk-ext-val ] ) +# +# but we aren't parsing the things so we don't really care. +chunk_ext = r";.*" +chunk_header = ( + r"(?P{chunk_size})" + r"(?P{chunk_ext})?" + r"\r\n".format(**globals()) +) diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/h11/_connection.py b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/h11/_connection.py new file mode 100644 index 00000000..d11386f0 --- /dev/null +++ b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/h11/_connection.py @@ -0,0 +1,631 @@ +# This contains the main Connection class. Everything in h11 revolves around +# this. +from typing import Any, Callable, cast, Dict, List, Optional, Tuple, Type, Union + +from ._events import ( + ConnectionClosed, + Data, + EndOfMessage, + Event, + InformationalResponse, + Request, + Response, +) +from ._headers import get_comma_header, has_expect_100_continue, set_comma_header +from ._readers import READERS, ReadersType +from ._receivebuffer import ReceiveBuffer +from ._state import ( + _SWITCH_CONNECT, + _SWITCH_UPGRADE, + CLIENT, + ConnectionState, + DONE, + ERROR, + MIGHT_SWITCH_PROTOCOL, + SEND_BODY, + SERVER, + SWITCHED_PROTOCOL, +) +from ._util import ( # Import the internal things we need + LocalProtocolError, + RemoteProtocolError, + Sentinel, +) +from ._writers import WRITERS, WritersType + +# Everything in __all__ gets re-exported as part of the h11 public API. +__all__ = ["Connection", "NEED_DATA", "PAUSED"] + + +class NEED_DATA(Sentinel, metaclass=Sentinel): + pass + + +class PAUSED(Sentinel, metaclass=Sentinel): + pass + + +# If we ever have this much buffered without it making a complete parseable +# event, we error out. The only time we really buffer is when reading the +# request/response line + headers together, so this is effectively the limit on +# the size of that. +# +# Some precedents for defaults: +# - node.js: 80 * 1024 +# - tomcat: 8 * 1024 +# - IIS: 16 * 1024 +# - Apache: <8 KiB per line> +DEFAULT_MAX_INCOMPLETE_EVENT_SIZE = 16 * 1024 + +# RFC 7230's rules for connection lifecycles: +# - If either side says they want to close the connection, then the connection +# must close. +# - HTTP/1.1 defaults to keep-alive unless someone says Connection: close +# - HTTP/1.0 defaults to close unless both sides say Connection: keep-alive +# (and even this is a mess -- e.g. if you're implementing a proxy then +# sending Connection: keep-alive is forbidden). +# +# We simplify life by simply not supporting keep-alive with HTTP/1.0 peers. So +# our rule is: +# - If someone says Connection: close, we will close +# - If someone uses HTTP/1.0, we will close. +def _keep_alive(event: Union[Request, Response]) -> bool: + connection = get_comma_header(event.headers, b"connection") + if b"close" in connection: + return False + if getattr(event, "http_version", b"1.1") < b"1.1": + return False + return True + + +def _body_framing( + request_method: bytes, event: Union[Request, Response] +) -> Tuple[str, Union[Tuple[()], Tuple[int]]]: + # Called when we enter SEND_BODY to figure out framing information for + # this body. + # + # These are the only two events that can trigger a SEND_BODY state: + assert type(event) in (Request, Response) + # Returns one of: + # + # ("content-length", count) + # ("chunked", ()) + # ("http/1.0", ()) + # + # which are (lookup key, *args) for constructing body reader/writer + # objects. + # + # Reference: https://tools.ietf.org/html/rfc7230#section-3.3.3 + # + # Step 1: some responses always have an empty body, regardless of what the + # headers say. + if type(event) is Response: + if ( + event.status_code in (204, 304) + or request_method == b"HEAD" + or (request_method == b"CONNECT" and 200 <= event.status_code < 300) + ): + return ("content-length", (0,)) + # Section 3.3.3 also lists another case -- responses with status_code + # < 200. For us these are InformationalResponses, not Responses, so + # they can't get into this function in the first place. + assert event.status_code >= 200 + + # Step 2: check for Transfer-Encoding (T-E beats C-L): + transfer_encodings = get_comma_header(event.headers, b"transfer-encoding") + if transfer_encodings: + assert transfer_encodings == [b"chunked"] + return ("chunked", ()) + + # Step 3: check for Content-Length + content_lengths = get_comma_header(event.headers, b"content-length") + if content_lengths: + return ("content-length", (int(content_lengths[0]),)) + + # Step 4: no applicable headers; fallback/default depends on type + if type(event) is Request: + return ("content-length", (0,)) + else: + return ("http/1.0", ()) + + +################################################################ +# +# The main Connection class +# +################################################################ + + +class Connection: + """An object encapsulating the state of an HTTP connection. + + Args: + our_role: If you're implementing a client, pass :data:`h11.CLIENT`. If + you're implementing a server, pass :data:`h11.SERVER`. + + max_incomplete_event_size (int): + The maximum number of bytes we're willing to buffer of an + incomplete event. In practice this mostly sets a limit on the + maximum size of the request/response line + headers. If this is + exceeded, then :meth:`next_event` will raise + :exc:`RemoteProtocolError`. + + """ + + def __init__( + self, + our_role: Type[Sentinel], + max_incomplete_event_size: int = DEFAULT_MAX_INCOMPLETE_EVENT_SIZE, + ) -> None: + self._max_incomplete_event_size = max_incomplete_event_size + # State and role tracking + if our_role not in (CLIENT, SERVER): + raise ValueError("expected CLIENT or SERVER, not {!r}".format(our_role)) + self.our_role = our_role + self.their_role: Type[Sentinel] + if our_role is CLIENT: + self.their_role = SERVER + else: + self.their_role = CLIENT + self._cstate = ConnectionState() + + # Callables for converting data->events or vice-versa given the + # current state + self._writer = self._get_io_object(self.our_role, None, WRITERS) + self._reader = self._get_io_object(self.their_role, None, READERS) + + # Holds any unprocessed received data + self._receive_buffer = ReceiveBuffer() + # If this is true, then it indicates that the incoming connection was + # closed *after* the end of whatever's in self._receive_buffer: + self._receive_buffer_closed = False + + # Extra bits of state that don't fit into the state machine. + # + # These two are only used to interpret framing headers for figuring + # out how to read/write response bodies. their_http_version is also + # made available as a convenient public API. + self.their_http_version: Optional[bytes] = None + self._request_method: Optional[bytes] = None + # This is pure flow-control and doesn't at all affect the set of legal + # transitions, so no need to bother ConnectionState with it: + self.client_is_waiting_for_100_continue = False + + @property + def states(self) -> Dict[Type[Sentinel], Type[Sentinel]]: + """A dictionary like:: + + {CLIENT: , SERVER: } + + See :ref:`state-machine` for details. + + """ + return dict(self._cstate.states) + + @property + def our_state(self) -> Type[Sentinel]: + """The current state of whichever role we are playing. See + :ref:`state-machine` for details. + """ + return self._cstate.states[self.our_role] + + @property + def their_state(self) -> Type[Sentinel]: + """The current state of whichever role we are NOT playing. See + :ref:`state-machine` for details. + """ + return self._cstate.states[self.their_role] + + @property + def they_are_waiting_for_100_continue(self) -> bool: + return self.their_role is CLIENT and self.client_is_waiting_for_100_continue + + def start_next_cycle(self) -> None: + """Attempt to reset our connection state for a new request/response + cycle. + + If both client and server are in :data:`DONE` state, then resets them + both to :data:`IDLE` state in preparation for a new request/response + cycle on this same connection. Otherwise, raises a + :exc:`LocalProtocolError`. + + See :ref:`keepalive-and-pipelining`. + + """ + old_states = dict(self._cstate.states) + self._cstate.start_next_cycle() + self._request_method = None + # self.their_http_version gets left alone, since it presumably lasts + # beyond a single request/response cycle + assert not self.client_is_waiting_for_100_continue + self._respond_to_state_changes(old_states) + + def _process_error(self, role: Type[Sentinel]) -> None: + old_states = dict(self._cstate.states) + self._cstate.process_error(role) + self._respond_to_state_changes(old_states) + + def _server_switch_event(self, event: Event) -> Optional[Type[Sentinel]]: + if type(event) is InformationalResponse and event.status_code == 101: + return _SWITCH_UPGRADE + if type(event) is Response: + if ( + _SWITCH_CONNECT in self._cstate.pending_switch_proposals + and 200 <= event.status_code < 300 + ): + return _SWITCH_CONNECT + return None + + # All events go through here + def _process_event(self, role: Type[Sentinel], event: Event) -> None: + # First, pass the event through the state machine to make sure it + # succeeds. + old_states = dict(self._cstate.states) + if role is CLIENT and type(event) is Request: + if event.method == b"CONNECT": + self._cstate.process_client_switch_proposal(_SWITCH_CONNECT) + if get_comma_header(event.headers, b"upgrade"): + self._cstate.process_client_switch_proposal(_SWITCH_UPGRADE) + server_switch_event = None + if role is SERVER: + server_switch_event = self._server_switch_event(event) + self._cstate.process_event(role, type(event), server_switch_event) + + # Then perform the updates triggered by it. + + if type(event) is Request: + self._request_method = event.method + + if role is self.their_role and type(event) in ( + Request, + Response, + InformationalResponse, + ): + event = cast(Union[Request, Response, InformationalResponse], event) + self.their_http_version = event.http_version + + # Keep alive handling + # + # RFC 7230 doesn't really say what one should do if Connection: close + # shows up on a 1xx InformationalResponse. I think the idea is that + # this is not supposed to happen. In any case, if it does happen, we + # ignore it. + if type(event) in (Request, Response) and not _keep_alive( + cast(Union[Request, Response], event) + ): + self._cstate.process_keep_alive_disabled() + + # 100-continue + if type(event) is Request and has_expect_100_continue(event): + self.client_is_waiting_for_100_continue = True + if type(event) in (InformationalResponse, Response): + self.client_is_waiting_for_100_continue = False + if role is CLIENT and type(event) in (Data, EndOfMessage): + self.client_is_waiting_for_100_continue = False + + self._respond_to_state_changes(old_states, event) + + def _get_io_object( + self, + role: Type[Sentinel], + event: Optional[Event], + io_dict: Union[ReadersType, WritersType], + ) -> Optional[Callable[..., Any]]: + # event may be None; it's only used when entering SEND_BODY + state = self._cstate.states[role] + if state is SEND_BODY: + # Special case: the io_dict has a dict of reader/writer factories + # that depend on the request/response framing. + framing_type, args = _body_framing( + cast(bytes, self._request_method), cast(Union[Request, Response], event) + ) + return io_dict[SEND_BODY][framing_type](*args) # type: ignore[index] + else: + # General case: the io_dict just has the appropriate reader/writer + # for this state + return io_dict.get((role, state)) # type: ignore + + # This must be called after any action that might have caused + # self._cstate.states to change. + def _respond_to_state_changes( + self, + old_states: Dict[Type[Sentinel], Type[Sentinel]], + event: Optional[Event] = None, + ) -> None: + # Update reader/writer + if self.our_state != old_states[self.our_role]: + self._writer = self._get_io_object(self.our_role, event, WRITERS) + if self.their_state != old_states[self.their_role]: + self._reader = self._get_io_object(self.their_role, event, READERS) + + @property + def trailing_data(self) -> Tuple[bytes, bool]: + """Data that has been received, but not yet processed, represented as + a tuple with two elements, where the first is a byte-string containing + the unprocessed data itself, and the second is a bool that is True if + the receive connection was closed. + + See :ref:`switching-protocols` for discussion of why you'd want this. + """ + return (bytes(self._receive_buffer), self._receive_buffer_closed) + + def receive_data(self, data: bytes) -> None: + """Add data to our internal receive buffer. + + This does not actually do any processing on the data, just stores + it. To trigger processing, you have to call :meth:`next_event`. + + Args: + data (:term:`bytes-like object`): + The new data that was just received. + + Special case: If *data* is an empty byte-string like ``b""``, + then this indicates that the remote side has closed the + connection (end of file). Normally this is convenient, because + standard Python APIs like :meth:`file.read` or + :meth:`socket.recv` use ``b""`` to indicate end-of-file, while + other failures to read are indicated using other mechanisms + like raising :exc:`TimeoutError`. When using such an API you + can just blindly pass through whatever you get from ``read`` + to :meth:`receive_data`, and everything will work. + + But, if you have an API where reading an empty string is a + valid non-EOF condition, then you need to be aware of this and + make sure to check for such strings and avoid passing them to + :meth:`receive_data`. + + Returns: + Nothing, but after calling this you should call :meth:`next_event` + to parse the newly received data. + + Raises: + RuntimeError: + Raised if you pass an empty *data*, indicating EOF, and then + pass a non-empty *data*, indicating more data that somehow + arrived after the EOF. + + (Calling ``receive_data(b"")`` multiple times is fine, + and equivalent to calling it once.) + + """ + if data: + if self._receive_buffer_closed: + raise RuntimeError("received close, then received more data?") + self._receive_buffer += data + else: + self._receive_buffer_closed = True + + def _extract_next_receive_event(self) -> Union[Event, Type[Sentinel]]: + state = self.their_state + # We don't pause immediately when they enter DONE, because even in + # DONE state we can still process a ConnectionClosed() event. But + # if we have data in our buffer, then we definitely aren't getting + # a ConnectionClosed() immediately and we need to pause. + if state is DONE and self._receive_buffer: + return PAUSED + if state is MIGHT_SWITCH_PROTOCOL or state is SWITCHED_PROTOCOL: + return PAUSED + assert self._reader is not None + event = self._reader(self._receive_buffer) + if event is None: + if not self._receive_buffer and self._receive_buffer_closed: + # In some unusual cases (basically just HTTP/1.0 bodies), EOF + # triggers an actual protocol event; in that case, we want to + # return that event, and then the state will change and we'll + # get called again to generate the actual ConnectionClosed(). + if hasattr(self._reader, "read_eof"): + event = self._reader.read_eof() # type: ignore[attr-defined] + else: + event = ConnectionClosed() + if event is None: + event = NEED_DATA + return event # type: ignore[no-any-return] + + def next_event(self) -> Union[Event, Type[Sentinel]]: + """Parse the next event out of our receive buffer, update our internal + state, and return it. + + This is a mutating operation -- think of it like calling :func:`next` + on an iterator. + + Returns: + : One of three things: + + 1) An event object -- see :ref:`events`. + + 2) The special constant :data:`NEED_DATA`, which indicates that + you need to read more data from your socket and pass it to + :meth:`receive_data` before this method will be able to return + any more events. + + 3) The special constant :data:`PAUSED`, which indicates that we + are not in a state where we can process incoming data (usually + because the peer has finished their part of the current + request/response cycle, and you have not yet called + :meth:`start_next_cycle`). See :ref:`flow-control` for details. + + Raises: + RemoteProtocolError: + The peer has misbehaved. You should close the connection + (possibly after sending some kind of 4xx response). + + Once this method returns :class:`ConnectionClosed` once, then all + subsequent calls will also return :class:`ConnectionClosed`. + + If this method raises any exception besides :exc:`RemoteProtocolError` + then that's a bug -- if it happens please file a bug report! + + If this method raises any exception then it also sets + :attr:`Connection.their_state` to :data:`ERROR` -- see + :ref:`error-handling` for discussion. + + """ + + if self.their_state is ERROR: + raise RemoteProtocolError("Can't receive data when peer state is ERROR") + try: + event = self._extract_next_receive_event() + if event not in [NEED_DATA, PAUSED]: + self._process_event(self.their_role, cast(Event, event)) + if event is NEED_DATA: + if len(self._receive_buffer) > self._max_incomplete_event_size: + # 431 is "Request header fields too large" which is pretty + # much the only situation where we can get here + raise RemoteProtocolError( + "Receive buffer too long", error_status_hint=431 + ) + if self._receive_buffer_closed: + # We're still trying to complete some event, but that's + # never going to happen because no more data is coming + raise RemoteProtocolError("peer unexpectedly closed connection") + return event + except BaseException as exc: + self._process_error(self.their_role) + if isinstance(exc, LocalProtocolError): + exc._reraise_as_remote_protocol_error() + else: + raise + + def send(self, event: Event) -> Optional[bytes]: + """Convert a high-level event into bytes that can be sent to the peer, + while updating our internal state machine. + + Args: + event: The :ref:`event ` to send. + + Returns: + If ``type(event) is ConnectionClosed``, then returns + ``None``. Otherwise, returns a :term:`bytes-like object`. + + Raises: + LocalProtocolError: + Sending this event at this time would violate our + understanding of the HTTP/1.1 protocol. + + If this method raises any exception then it also sets + :attr:`Connection.our_state` to :data:`ERROR` -- see + :ref:`error-handling` for discussion. + + """ + data_list = self.send_with_data_passthrough(event) + if data_list is None: + return None + else: + return b"".join(data_list) + + def send_with_data_passthrough(self, event: Event) -> Optional[List[bytes]]: + """Identical to :meth:`send`, except that in situations where + :meth:`send` returns a single :term:`bytes-like object`, this instead + returns a list of them -- and when sending a :class:`Data` event, this + list is guaranteed to contain the exact object you passed in as + :attr:`Data.data`. See :ref:`sendfile` for discussion. + + """ + if self.our_state is ERROR: + raise LocalProtocolError("Can't send data when our state is ERROR") + try: + if type(event) is Response: + event = self._clean_up_response_headers_for_sending(event) + # We want to call _process_event before calling the writer, + # because if someone tries to do something invalid then this will + # give a sensible error message, while our writers all just assume + # they will only receive valid events. But, _process_event might + # change self._writer. So we have to do a little dance: + writer = self._writer + self._process_event(self.our_role, event) + if type(event) is ConnectionClosed: + return None + else: + # In any situation where writer is None, process_event should + # have raised ProtocolError + assert writer is not None + data_list: List[bytes] = [] + writer(event, data_list.append) + return data_list + except: + self._process_error(self.our_role) + raise + + def send_failed(self) -> None: + """Notify the state machine that we failed to send the data it gave + us. + + This causes :attr:`Connection.our_state` to immediately become + :data:`ERROR` -- see :ref:`error-handling` for discussion. + + """ + self._process_error(self.our_role) + + # When sending a Response, we take responsibility for a few things: + # + # - Sometimes you MUST set Connection: close. We take care of those + # times. (You can also set it yourself if you want, and if you do then + # we'll respect that and close the connection at the right time. But you + # don't have to worry about that unless you want to.) + # + # - The user has to set Content-Length if they want it. Otherwise, for + # responses that have bodies (e.g. not HEAD), then we will automatically + # select the right mechanism for streaming a body of unknown length, + # which depends on depending on the peer's HTTP version. + # + # This function's *only* responsibility is making sure headers are set up + # right -- everything downstream just looks at the headers. There are no + # side channels. + def _clean_up_response_headers_for_sending(self, response: Response) -> Response: + assert type(response) is Response + + headers = response.headers + need_close = False + + # HEAD requests need some special handling: they always act like they + # have Content-Length: 0, and that's how _body_framing treats + # them. But their headers are supposed to match what we would send if + # the request was a GET. (Technically there is one deviation allowed: + # we're allowed to leave out the framing headers -- see + # https://tools.ietf.org/html/rfc7231#section-4.3.2 . But it's just as + # easy to get them right.) + method_for_choosing_headers = cast(bytes, self._request_method) + if method_for_choosing_headers == b"HEAD": + method_for_choosing_headers = b"GET" + framing_type, _ = _body_framing(method_for_choosing_headers, response) + if framing_type in ("chunked", "http/1.0"): + # This response has a body of unknown length. + # If our peer is HTTP/1.1, we use Transfer-Encoding: chunked + # If our peer is HTTP/1.0, we use no framing headers, and close the + # connection afterwards. + # + # Make sure to clear Content-Length (in principle user could have + # set both and then we ignored Content-Length b/c + # Transfer-Encoding overwrote it -- this would be naughty of them, + # but the HTTP spec says that if our peer does this then we have + # to fix it instead of erroring out, so we'll accord the user the + # same respect). + headers = set_comma_header(headers, b"content-length", []) + if self.their_http_version is None or self.their_http_version < b"1.1": + # Either we never got a valid request and are sending back an + # error (their_http_version is None), so we assume the worst; + # or else we did get a valid HTTP/1.0 request, so we know that + # they don't understand chunked encoding. + headers = set_comma_header(headers, b"transfer-encoding", []) + # This is actually redundant ATM, since currently we + # unconditionally disable keep-alive when talking to HTTP/1.0 + # peers. But let's be defensive just in case we add + # Connection: keep-alive support later: + if self._request_method != b"HEAD": + need_close = True + else: + headers = set_comma_header(headers, b"transfer-encoding", [b"chunked"]) + + if not self._cstate.keep_alive or need_close: + # Make sure Connection: close is set + connection = set(get_comma_header(headers, b"connection")) + connection.discard(b"keep-alive") + connection.add(b"close") + headers = set_comma_header(headers, b"connection", sorted(connection)) + + return Response( + headers=headers, + status_code=response.status_code, + http_version=response.http_version, + reason=response.reason, + ) diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/h11/_events.py b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/h11/_events.py new file mode 100644 index 00000000..075bf8a4 --- /dev/null +++ b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/h11/_events.py @@ -0,0 +1,369 @@ +# High level events that make up HTTP/1.1 conversations. Loosely inspired by +# the corresponding events in hyper-h2: +# +# http://python-hyper.org/h2/en/stable/api.html#events +# +# Don't subclass these. Stuff will break. + +import re +from abc import ABC +from dataclasses import dataclass, field +from typing import Any, cast, Dict, List, Tuple, Union + +from ._abnf import method, request_target +from ._headers import Headers, normalize_and_validate +from ._util import bytesify, LocalProtocolError, validate + +# Everything in __all__ gets re-exported as part of the h11 public API. +__all__ = [ + "Event", + "Request", + "InformationalResponse", + "Response", + "Data", + "EndOfMessage", + "ConnectionClosed", +] + +method_re = re.compile(method.encode("ascii")) +request_target_re = re.compile(request_target.encode("ascii")) + + +class Event(ABC): + """ + Base class for h11 events. + """ + + __slots__ = () + + +@dataclass(init=False, frozen=True) +class Request(Event): + """The beginning of an HTTP request. + + Fields: + + .. attribute:: method + + An HTTP method, e.g. ``b"GET"`` or ``b"POST"``. Always a byte + string. :term:`Bytes-like objects ` and native + strings containing only ascii characters will be automatically + converted to byte strings. + + .. attribute:: target + + The target of an HTTP request, e.g. ``b"/index.html"``, or one of the + more exotic formats described in `RFC 7320, section 5.3 + `_. Always a byte + string. :term:`Bytes-like objects ` and native + strings containing only ascii characters will be automatically + converted to byte strings. + + .. attribute:: headers + + Request headers, represented as a list of (name, value) pairs. See + :ref:`the header normalization rules ` for details. + + .. attribute:: http_version + + The HTTP protocol version, represented as a byte string like + ``b"1.1"``. See :ref:`the HTTP version normalization rules + ` for details. + + """ + + __slots__ = ("method", "headers", "target", "http_version") + + method: bytes + headers: Headers + target: bytes + http_version: bytes + + def __init__( + self, + *, + method: Union[bytes, str], + headers: Union[Headers, List[Tuple[bytes, bytes]], List[Tuple[str, str]]], + target: Union[bytes, str], + http_version: Union[bytes, str] = b"1.1", + _parsed: bool = False, + ) -> None: + super().__init__() + if isinstance(headers, Headers): + object.__setattr__(self, "headers", headers) + else: + object.__setattr__( + self, "headers", normalize_and_validate(headers, _parsed=_parsed) + ) + if not _parsed: + object.__setattr__(self, "method", bytesify(method)) + object.__setattr__(self, "target", bytesify(target)) + object.__setattr__(self, "http_version", bytesify(http_version)) + else: + object.__setattr__(self, "method", method) + object.__setattr__(self, "target", target) + object.__setattr__(self, "http_version", http_version) + + # "A server MUST respond with a 400 (Bad Request) status code to any + # HTTP/1.1 request message that lacks a Host header field and to any + # request message that contains more than one Host header field or a + # Host header field with an invalid field-value." + # -- https://tools.ietf.org/html/rfc7230#section-5.4 + host_count = 0 + for name, value in self.headers: + if name == b"host": + host_count += 1 + if self.http_version == b"1.1" and host_count == 0: + raise LocalProtocolError("Missing mandatory Host: header") + if host_count > 1: + raise LocalProtocolError("Found multiple Host: headers") + + validate(method_re, self.method, "Illegal method characters") + validate(request_target_re, self.target, "Illegal target characters") + + # This is an unhashable type. + __hash__ = None # type: ignore + + +@dataclass(init=False, frozen=True) +class _ResponseBase(Event): + __slots__ = ("headers", "http_version", "reason", "status_code") + + headers: Headers + http_version: bytes + reason: bytes + status_code: int + + def __init__( + self, + *, + headers: Union[Headers, List[Tuple[bytes, bytes]], List[Tuple[str, str]]], + status_code: int, + http_version: Union[bytes, str] = b"1.1", + reason: Union[bytes, str] = b"", + _parsed: bool = False, + ) -> None: + super().__init__() + if isinstance(headers, Headers): + object.__setattr__(self, "headers", headers) + else: + object.__setattr__( + self, "headers", normalize_and_validate(headers, _parsed=_parsed) + ) + if not _parsed: + object.__setattr__(self, "reason", bytesify(reason)) + object.__setattr__(self, "http_version", bytesify(http_version)) + if not isinstance(status_code, int): + raise LocalProtocolError("status code must be integer") + # Because IntEnum objects are instances of int, but aren't + # duck-compatible (sigh), see gh-72. + object.__setattr__(self, "status_code", int(status_code)) + else: + object.__setattr__(self, "reason", reason) + object.__setattr__(self, "http_version", http_version) + object.__setattr__(self, "status_code", status_code) + + self.__post_init__() + + def __post_init__(self) -> None: + pass + + # This is an unhashable type. + __hash__ = None # type: ignore + + +@dataclass(init=False, frozen=True) +class InformationalResponse(_ResponseBase): + """An HTTP informational response. + + Fields: + + .. attribute:: status_code + + The status code of this response, as an integer. For an + :class:`InformationalResponse`, this is always in the range [100, + 200). + + .. attribute:: headers + + Request headers, represented as a list of (name, value) pairs. See + :ref:`the header normalization rules ` for + details. + + .. attribute:: http_version + + The HTTP protocol version, represented as a byte string like + ``b"1.1"``. See :ref:`the HTTP version normalization rules + ` for details. + + .. attribute:: reason + + The reason phrase of this response, as a byte string. For example: + ``b"OK"``, or ``b"Not Found"``. + + """ + + def __post_init__(self) -> None: + if not (100 <= self.status_code < 200): + raise LocalProtocolError( + "InformationalResponse status_code should be in range " + "[100, 200), not {}".format(self.status_code) + ) + + # This is an unhashable type. + __hash__ = None # type: ignore + + +@dataclass(init=False, frozen=True) +class Response(_ResponseBase): + """The beginning of an HTTP response. + + Fields: + + .. attribute:: status_code + + The status code of this response, as an integer. For an + :class:`Response`, this is always in the range [200, + 1000). + + .. attribute:: headers + + Request headers, represented as a list of (name, value) pairs. See + :ref:`the header normalization rules ` for details. + + .. attribute:: http_version + + The HTTP protocol version, represented as a byte string like + ``b"1.1"``. See :ref:`the HTTP version normalization rules + ` for details. + + .. attribute:: reason + + The reason phrase of this response, as a byte string. For example: + ``b"OK"``, or ``b"Not Found"``. + + """ + + def __post_init__(self) -> None: + if not (200 <= self.status_code < 1000): + raise LocalProtocolError( + "Response status_code should be in range [200, 1000), not {}".format( + self.status_code + ) + ) + + # This is an unhashable type. + __hash__ = None # type: ignore + + +@dataclass(init=False, frozen=True) +class Data(Event): + """Part of an HTTP message body. + + Fields: + + .. attribute:: data + + A :term:`bytes-like object` containing part of a message body. Or, if + using the ``combine=False`` argument to :meth:`Connection.send`, then + any object that your socket writing code knows what to do with, and for + which calling :func:`len` returns the number of bytes that will be + written -- see :ref:`sendfile` for details. + + .. attribute:: chunk_start + + A marker that indicates whether this data object is from the start of a + chunked transfer encoding chunk. This field is ignored when when a Data + event is provided to :meth:`Connection.send`: it is only valid on + events emitted from :meth:`Connection.next_event`. You probably + shouldn't use this attribute at all; see + :ref:`chunk-delimiters-are-bad` for details. + + .. attribute:: chunk_end + + A marker that indicates whether this data object is the last for a + given chunked transfer encoding chunk. This field is ignored when when + a Data event is provided to :meth:`Connection.send`: it is only valid + on events emitted from :meth:`Connection.next_event`. You probably + shouldn't use this attribute at all; see + :ref:`chunk-delimiters-are-bad` for details. + + """ + + __slots__ = ("data", "chunk_start", "chunk_end") + + data: bytes + chunk_start: bool + chunk_end: bool + + def __init__( + self, data: bytes, chunk_start: bool = False, chunk_end: bool = False + ) -> None: + object.__setattr__(self, "data", data) + object.__setattr__(self, "chunk_start", chunk_start) + object.__setattr__(self, "chunk_end", chunk_end) + + # This is an unhashable type. + __hash__ = None # type: ignore + + +# XX FIXME: "A recipient MUST ignore (or consider as an error) any fields that +# are forbidden to be sent in a trailer, since processing them as if they were +# present in the header section might bypass external security filters." +# https://svn.tools.ietf.org/svn/wg/httpbis/specs/rfc7230.html#chunked.trailer.part +# Unfortunately, the list of forbidden fields is long and vague :-/ +@dataclass(init=False, frozen=True) +class EndOfMessage(Event): + """The end of an HTTP message. + + Fields: + + .. attribute:: headers + + Default value: ``[]`` + + Any trailing headers attached to this message, represented as a list of + (name, value) pairs. See :ref:`the header normalization rules + ` for details. + + Must be empty unless ``Transfer-Encoding: chunked`` is in use. + + """ + + __slots__ = ("headers",) + + headers: Headers + + def __init__( + self, + *, + headers: Union[ + Headers, List[Tuple[bytes, bytes]], List[Tuple[str, str]], None + ] = None, + _parsed: bool = False, + ) -> None: + super().__init__() + if headers is None: + headers = Headers([]) + elif not isinstance(headers, Headers): + headers = normalize_and_validate(headers, _parsed=_parsed) + + object.__setattr__(self, "headers", headers) + + # This is an unhashable type. + __hash__ = None # type: ignore + + +@dataclass(frozen=True) +class ConnectionClosed(Event): + """This event indicates that the sender has closed their outgoing + connection. + + Note that this does not necessarily mean that they can't *receive* further + data, because TCP connections are composed to two one-way channels which + can be closed independently. See :ref:`closing` for details. + + No fields. + """ + + pass diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/h11/_headers.py b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/h11/_headers.py new file mode 100644 index 00000000..acc45969 --- /dev/null +++ b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/h11/_headers.py @@ -0,0 +1,278 @@ +import re +from typing import AnyStr, cast, List, overload, Sequence, Tuple, TYPE_CHECKING, Union + +from ._abnf import field_name, field_value +from ._util import bytesify, LocalProtocolError, validate + +if TYPE_CHECKING: + from ._events import Request + +try: + from typing import Literal +except ImportError: + from typing_extensions import Literal # type: ignore + + +# Facts +# ----- +# +# Headers are: +# keys: case-insensitive ascii +# values: mixture of ascii and raw bytes +# +# "Historically, HTTP has allowed field content with text in the ISO-8859-1 +# charset [ISO-8859-1], supporting other charsets only through use of +# [RFC2047] encoding. In practice, most HTTP header field values use only a +# subset of the US-ASCII charset [USASCII]. Newly defined header fields SHOULD +# limit their field values to US-ASCII octets. A recipient SHOULD treat other +# octets in field content (obs-text) as opaque data." +# And it deprecates all non-ascii values +# +# Leading/trailing whitespace in header names is forbidden +# +# Values get leading/trailing whitespace stripped +# +# Content-Disposition actually needs to contain unicode semantically; to +# accomplish this it has a terrifically weird way of encoding the filename +# itself as ascii (and even this still has lots of cross-browser +# incompatibilities) +# +# Order is important: +# "a proxy MUST NOT change the order of these field values when forwarding a +# message" +# (and there are several headers where the order indicates a preference) +# +# Multiple occurences of the same header: +# "A sender MUST NOT generate multiple header fields with the same field name +# in a message unless either the entire field value for that header field is +# defined as a comma-separated list [or the header is Set-Cookie which gets a +# special exception]" - RFC 7230. (cookies are in RFC 6265) +# +# So every header aside from Set-Cookie can be merged by b", ".join if it +# occurs repeatedly. But, of course, they can't necessarily be split by +# .split(b","), because quoting. +# +# Given all this mess (case insensitive, duplicates allowed, order is +# important, ...), there doesn't appear to be any standard way to handle +# headers in Python -- they're almost like dicts, but... actually just +# aren't. For now we punt and just use a super simple representation: headers +# are a list of pairs +# +# [(name1, value1), (name2, value2), ...] +# +# where all entries are bytestrings, names are lowercase and have no +# leading/trailing whitespace, and values are bytestrings with no +# leading/trailing whitespace. Searching and updating are done via naive O(n) +# methods. +# +# Maybe a dict-of-lists would be better? + +_content_length_re = re.compile(br"[0-9]+") +_field_name_re = re.compile(field_name.encode("ascii")) +_field_value_re = re.compile(field_value.encode("ascii")) + + +class Headers(Sequence[Tuple[bytes, bytes]]): + """ + A list-like interface that allows iterating over headers as byte-pairs + of (lowercased-name, value). + + Internally we actually store the representation as three-tuples, + including both the raw original casing, in order to preserve casing + over-the-wire, and the lowercased name, for case-insensitive comparisions. + + r = Request( + method="GET", + target="/", + headers=[("Host", "example.org"), ("Connection", "keep-alive")], + http_version="1.1", + ) + assert r.headers == [ + (b"host", b"example.org"), + (b"connection", b"keep-alive") + ] + assert r.headers.raw_items() == [ + (b"Host", b"example.org"), + (b"Connection", b"keep-alive") + ] + """ + + __slots__ = "_full_items" + + def __init__(self, full_items: List[Tuple[bytes, bytes, bytes]]) -> None: + self._full_items = full_items + + def __bool__(self) -> bool: + return bool(self._full_items) + + def __eq__(self, other: object) -> bool: + return list(self) == list(other) # type: ignore + + def __len__(self) -> int: + return len(self._full_items) + + def __repr__(self) -> str: + return "" % repr(list(self)) + + def __getitem__(self, idx: int) -> Tuple[bytes, bytes]: # type: ignore[override] + _, name, value = self._full_items[idx] + return (name, value) + + def raw_items(self) -> List[Tuple[bytes, bytes]]: + return [(raw_name, value) for raw_name, _, value in self._full_items] + + +HeaderTypes = Union[ + List[Tuple[bytes, bytes]], + List[Tuple[bytes, str]], + List[Tuple[str, bytes]], + List[Tuple[str, str]], +] + + +@overload +def normalize_and_validate(headers: Headers, _parsed: Literal[True]) -> Headers: + ... + + +@overload +def normalize_and_validate(headers: HeaderTypes, _parsed: Literal[False]) -> Headers: + ... + + +@overload +def normalize_and_validate( + headers: Union[Headers, HeaderTypes], _parsed: bool = False +) -> Headers: + ... + + +def normalize_and_validate( + headers: Union[Headers, HeaderTypes], _parsed: bool = False +) -> Headers: + new_headers = [] + seen_content_length = None + saw_transfer_encoding = False + for name, value in headers: + # For headers coming out of the parser, we can safely skip some steps, + # because it always returns bytes and has already run these regexes + # over the data: + if not _parsed: + name = bytesify(name) + value = bytesify(value) + validate(_field_name_re, name, "Illegal header name {!r}", name) + validate(_field_value_re, value, "Illegal header value {!r}", value) + assert isinstance(name, bytes) + assert isinstance(value, bytes) + + raw_name = name + name = name.lower() + if name == b"content-length": + lengths = {length.strip() for length in value.split(b",")} + if len(lengths) != 1: + raise LocalProtocolError("conflicting Content-Length headers") + value = lengths.pop() + validate(_content_length_re, value, "bad Content-Length") + if seen_content_length is None: + seen_content_length = value + new_headers.append((raw_name, name, value)) + elif seen_content_length != value: + raise LocalProtocolError("conflicting Content-Length headers") + elif name == b"transfer-encoding": + # "A server that receives a request message with a transfer coding + # it does not understand SHOULD respond with 501 (Not + # Implemented)." + # https://tools.ietf.org/html/rfc7230#section-3.3.1 + if saw_transfer_encoding: + raise LocalProtocolError( + "multiple Transfer-Encoding headers", error_status_hint=501 + ) + # "All transfer-coding names are case-insensitive" + # -- https://tools.ietf.org/html/rfc7230#section-4 + value = value.lower() + if value != b"chunked": + raise LocalProtocolError( + "Only Transfer-Encoding: chunked is supported", + error_status_hint=501, + ) + saw_transfer_encoding = True + new_headers.append((raw_name, name, value)) + else: + new_headers.append((raw_name, name, value)) + return Headers(new_headers) + + +def get_comma_header(headers: Headers, name: bytes) -> List[bytes]: + # Should only be used for headers whose value is a list of + # comma-separated, case-insensitive values. + # + # The header name `name` is expected to be lower-case bytes. + # + # Connection: meets these criteria (including cast insensitivity). + # + # Content-Length: technically is just a single value (1*DIGIT), but the + # standard makes reference to implementations that do multiple values, and + # using this doesn't hurt. Ditto, case insensitivity doesn't things either + # way. + # + # Transfer-Encoding: is more complex (allows for quoted strings), so + # splitting on , is actually wrong. For example, this is legal: + # + # Transfer-Encoding: foo; options="1,2", chunked + # + # and should be parsed as + # + # foo; options="1,2" + # chunked + # + # but this naive function will parse it as + # + # foo; options="1 + # 2" + # chunked + # + # However, this is okay because the only thing we are going to do with + # any Transfer-Encoding is reject ones that aren't just "chunked", so + # both of these will be treated the same anyway. + # + # Expect: the only legal value is the literal string + # "100-continue". Splitting on commas is harmless. Case insensitive. + # + out: List[bytes] = [] + for _, found_name, found_raw_value in headers._full_items: + if found_name == name: + found_raw_value = found_raw_value.lower() + for found_split_value in found_raw_value.split(b","): + found_split_value = found_split_value.strip() + if found_split_value: + out.append(found_split_value) + return out + + +def set_comma_header(headers: Headers, name: bytes, new_values: List[bytes]) -> Headers: + # The header name `name` is expected to be lower-case bytes. + # + # Note that when we store the header we use title casing for the header + # names, in order to match the conventional HTTP header style. + # + # Simply calling `.title()` is a blunt approach, but it's correct + # here given the cases where we're using `set_comma_header`... + # + # Connection, Content-Length, Transfer-Encoding. + new_headers: List[Tuple[bytes, bytes]] = [] + for found_raw_name, found_name, found_raw_value in headers._full_items: + if found_name != name: + new_headers.append((found_raw_name, found_raw_value)) + for new_value in new_values: + new_headers.append((name.title(), new_value)) + return normalize_and_validate(new_headers) + + +def has_expect_100_continue(request: "Request") -> bool: + # https://tools.ietf.org/html/rfc7231#section-5.1.1 + # "A server that receives a 100-continue expectation in an HTTP/1.0 request + # MUST ignore that expectation." + if request.http_version < b"1.1": + return False + expect = get_comma_header(request.headers, b"expect") + return b"100-continue" in expect diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/h11/_readers.py b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/h11/_readers.py new file mode 100644 index 00000000..a036d790 --- /dev/null +++ b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/h11/_readers.py @@ -0,0 +1,249 @@ +# Code to read HTTP data +# +# Strategy: each reader is a callable which takes a ReceiveBuffer object, and +# either: +# 1) consumes some of it and returns an Event +# 2) raises a LocalProtocolError (for consistency -- e.g. we call validate() +# and it might raise a LocalProtocolError, so simpler just to always use +# this) +# 3) returns None, meaning "I need more data" +# +# If they have a .read_eof attribute, then this will be called if an EOF is +# received -- but this is optional. Either way, the actual ConnectionClosed +# event will be generated afterwards. +# +# READERS is a dict describing how to pick a reader. It maps states to either: +# - a reader +# - or, for body readers, a dict of per-framing reader factories + +import re +from typing import Any, Callable, Dict, Iterable, NoReturn, Optional, Tuple, Type, Union + +from ._abnf import chunk_header, header_field, request_line, status_line +from ._events import Data, EndOfMessage, InformationalResponse, Request, Response +from ._receivebuffer import ReceiveBuffer +from ._state import ( + CLIENT, + CLOSED, + DONE, + IDLE, + MUST_CLOSE, + SEND_BODY, + SEND_RESPONSE, + SERVER, +) +from ._util import LocalProtocolError, RemoteProtocolError, Sentinel, validate + +__all__ = ["READERS"] + +header_field_re = re.compile(header_field.encode("ascii")) + +# Remember that this has to run in O(n) time -- so e.g. the bytearray cast is +# critical. +obs_fold_re = re.compile(br"[ \t]+") + + +def _obsolete_line_fold(lines: Iterable[bytes]) -> Iterable[bytes]: + it = iter(lines) + last: Optional[bytes] = None + for line in it: + match = obs_fold_re.match(line) + if match: + if last is None: + raise LocalProtocolError("continuation line at start of headers") + if not isinstance(last, bytearray): + last = bytearray(last) + last += b" " + last += line[match.end() :] + else: + if last is not None: + yield last + last = line + if last is not None: + yield last + + +def _decode_header_lines( + lines: Iterable[bytes], +) -> Iterable[Tuple[bytes, bytes]]: + for line in _obsolete_line_fold(lines): + matches = validate(header_field_re, line, "illegal header line: {!r}", line) + yield (matches["field_name"], matches["field_value"]) + + +request_line_re = re.compile(request_line.encode("ascii")) + + +def maybe_read_from_IDLE_client(buf: ReceiveBuffer) -> Optional[Request]: + lines = buf.maybe_extract_lines() + if lines is None: + if buf.is_next_line_obviously_invalid_request_line(): + raise LocalProtocolError("illegal request line") + return None + if not lines: + raise LocalProtocolError("no request line received") + matches = validate( + request_line_re, lines[0], "illegal request line: {!r}", lines[0] + ) + return Request( + headers=list(_decode_header_lines(lines[1:])), _parsed=True, **matches + ) + + +status_line_re = re.compile(status_line.encode("ascii")) + + +def maybe_read_from_SEND_RESPONSE_server( + buf: ReceiveBuffer, +) -> Union[InformationalResponse, Response, None]: + lines = buf.maybe_extract_lines() + if lines is None: + if buf.is_next_line_obviously_invalid_request_line(): + raise LocalProtocolError("illegal request line") + return None + if not lines: + raise LocalProtocolError("no response line received") + matches = validate(status_line_re, lines[0], "illegal status line: {!r}", lines[0]) + http_version = ( + b"1.1" if matches["http_version"] is None else matches["http_version"] + ) + reason = b"" if matches["reason"] is None else matches["reason"] + status_code = int(matches["status_code"]) + class_: Union[Type[InformationalResponse], Type[Response]] = ( + InformationalResponse if status_code < 200 else Response + ) + return class_( + headers=list(_decode_header_lines(lines[1:])), + _parsed=True, + status_code=status_code, + reason=reason, + http_version=http_version, + ) + + +class ContentLengthReader: + def __init__(self, length: int) -> None: + self._length = length + self._remaining = length + + def __call__(self, buf: ReceiveBuffer) -> Union[Data, EndOfMessage, None]: + if self._remaining == 0: + return EndOfMessage() + data = buf.maybe_extract_at_most(self._remaining) + if data is None: + return None + self._remaining -= len(data) + return Data(data=data) + + def read_eof(self) -> NoReturn: + raise RemoteProtocolError( + "peer closed connection without sending complete message body " + "(received {} bytes, expected {})".format( + self._length - self._remaining, self._length + ) + ) + + +chunk_header_re = re.compile(chunk_header.encode("ascii")) + + +class ChunkedReader: + def __init__(self) -> None: + self._bytes_in_chunk = 0 + # After reading a chunk, we have to throw away the trailing \r\n; if + # this is >0 then we discard that many bytes before resuming regular + # de-chunkification. + self._bytes_to_discard = 0 + self._reading_trailer = False + + def __call__(self, buf: ReceiveBuffer) -> Union[Data, EndOfMessage, None]: + if self._reading_trailer: + lines = buf.maybe_extract_lines() + if lines is None: + return None + return EndOfMessage(headers=list(_decode_header_lines(lines))) + if self._bytes_to_discard > 0: + data = buf.maybe_extract_at_most(self._bytes_to_discard) + if data is None: + return None + self._bytes_to_discard -= len(data) + if self._bytes_to_discard > 0: + return None + # else, fall through and read some more + assert self._bytes_to_discard == 0 + if self._bytes_in_chunk == 0: + # We need to refill our chunk count + chunk_header = buf.maybe_extract_next_line() + if chunk_header is None: + return None + matches = validate( + chunk_header_re, + chunk_header, + "illegal chunk header: {!r}", + chunk_header, + ) + # XX FIXME: we discard chunk extensions. Does anyone care? + self._bytes_in_chunk = int(matches["chunk_size"], base=16) + if self._bytes_in_chunk == 0: + self._reading_trailer = True + return self(buf) + chunk_start = True + else: + chunk_start = False + assert self._bytes_in_chunk > 0 + data = buf.maybe_extract_at_most(self._bytes_in_chunk) + if data is None: + return None + self._bytes_in_chunk -= len(data) + if self._bytes_in_chunk == 0: + self._bytes_to_discard = 2 + chunk_end = True + else: + chunk_end = False + return Data(data=data, chunk_start=chunk_start, chunk_end=chunk_end) + + def read_eof(self) -> NoReturn: + raise RemoteProtocolError( + "peer closed connection without sending complete message body " + "(incomplete chunked read)" + ) + + +class Http10Reader: + def __call__(self, buf: ReceiveBuffer) -> Optional[Data]: + data = buf.maybe_extract_at_most(999999999) + if data is None: + return None + return Data(data=data) + + def read_eof(self) -> EndOfMessage: + return EndOfMessage() + + +def expect_nothing(buf: ReceiveBuffer) -> None: + if buf: + raise LocalProtocolError("Got data when expecting EOF") + return None + + +ReadersType = Dict[ + Union[Sentinel, Tuple[Sentinel, Sentinel]], + Union[Callable[..., Any], Dict[str, Callable[..., Any]]], +] + +READERS: ReadersType = { + (CLIENT, IDLE): maybe_read_from_IDLE_client, + (SERVER, IDLE): maybe_read_from_SEND_RESPONSE_server, + (SERVER, SEND_RESPONSE): maybe_read_from_SEND_RESPONSE_server, + (CLIENT, DONE): expect_nothing, + (CLIENT, MUST_CLOSE): expect_nothing, + (CLIENT, CLOSED): expect_nothing, + (SERVER, DONE): expect_nothing, + (SERVER, MUST_CLOSE): expect_nothing, + (SERVER, CLOSED): expect_nothing, + SEND_BODY: { + "chunked": ChunkedReader, + "content-length": ContentLengthReader, + "http/1.0": Http10Reader, + }, +} diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/h11/_receivebuffer.py b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/h11/_receivebuffer.py new file mode 100644 index 00000000..e5c4e08a --- /dev/null +++ b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/h11/_receivebuffer.py @@ -0,0 +1,153 @@ +import re +import sys +from typing import List, Optional, Union + +__all__ = ["ReceiveBuffer"] + + +# Operations we want to support: +# - find next \r\n or \r\n\r\n (\n or \n\n are also acceptable), +# or wait until there is one +# - read at-most-N bytes +# Goals: +# - on average, do this fast +# - worst case, do this in O(n) where n is the number of bytes processed +# Plan: +# - store bytearray, offset, how far we've searched for a separator token +# - use the how-far-we've-searched data to avoid rescanning +# - while doing a stream of uninterrupted processing, advance offset instead +# of constantly copying +# WARNING: +# - I haven't benchmarked or profiled any of this yet. +# +# Note that starting in Python 3.4, deleting the initial n bytes from a +# bytearray is amortized O(n), thanks to some excellent work by Antoine +# Martin: +# +# https://bugs.python.org/issue19087 +# +# This means that if we only supported 3.4+, we could get rid of the code here +# involving self._start and self.compress, because it's doing exactly the same +# thing that bytearray now does internally. +# +# BUT unfortunately, we still support 2.7, and reading short segments out of a +# long buffer MUST be O(bytes read) to avoid DoS issues, so we can't actually +# delete this code. Yet: +# +# https://pythonclock.org/ +# +# (Two things to double-check first though: make sure PyPy also has the +# optimization, and benchmark to make sure it's a win, since we do have a +# slightly clever thing where we delay calling compress() until we've +# processed a whole event, which could in theory be slightly more efficient +# than the internal bytearray support.) +blank_line_regex = re.compile(b"\n\r?\n", re.MULTILINE) + + +class ReceiveBuffer: + def __init__(self) -> None: + self._data = bytearray() + self._next_line_search = 0 + self._multiple_lines_search = 0 + + def __iadd__(self, byteslike: Union[bytes, bytearray]) -> "ReceiveBuffer": + self._data += byteslike + return self + + def __bool__(self) -> bool: + return bool(len(self)) + + def __len__(self) -> int: + return len(self._data) + + # for @property unprocessed_data + def __bytes__(self) -> bytes: + return bytes(self._data) + + def _extract(self, count: int) -> bytearray: + # extracting an initial slice of the data buffer and return it + out = self._data[:count] + del self._data[:count] + + self._next_line_search = 0 + self._multiple_lines_search = 0 + + return out + + def maybe_extract_at_most(self, count: int) -> Optional[bytearray]: + """ + Extract a fixed number of bytes from the buffer. + """ + out = self._data[:count] + if not out: + return None + + return self._extract(count) + + def maybe_extract_next_line(self) -> Optional[bytearray]: + """ + Extract the first line, if it is completed in the buffer. + """ + # Only search in buffer space that we've not already looked at. + search_start_index = max(0, self._next_line_search - 1) + partial_idx = self._data.find(b"\r\n", search_start_index) + + if partial_idx == -1: + self._next_line_search = len(self._data) + return None + + # + 2 is to compensate len(b"\r\n") + idx = partial_idx + 2 + + return self._extract(idx) + + def maybe_extract_lines(self) -> Optional[List[bytearray]]: + """ + Extract everything up to the first blank line, and return a list of lines. + """ + # Handle the case where we have an immediate empty line. + if self._data[:1] == b"\n": + self._extract(1) + return [] + + if self._data[:2] == b"\r\n": + self._extract(2) + return [] + + # Only search in buffer space that we've not already looked at. + match = blank_line_regex.search(self._data, self._multiple_lines_search) + if match is None: + self._multiple_lines_search = max(0, len(self._data) - 2) + return None + + # Truncate the buffer and return it. + idx = match.span(0)[-1] + out = self._extract(idx) + lines = out.split(b"\n") + + for line in lines: + if line.endswith(b"\r"): + del line[-1] + + assert lines[-2] == lines[-1] == b"" + + del lines[-2:] + + return lines + + # In theory we should wait until `\r\n` before starting to validate + # incoming data. However it's interesting to detect (very) invalid data + # early given they might not even contain `\r\n` at all (hence only + # timeout will get rid of them). + # This is not a 100% effective detection but more of a cheap sanity check + # allowing for early abort in some useful cases. + # This is especially interesting when peer is messing up with HTTPS and + # sent us a TLS stream where we were expecting plain HTTP given all + # versions of TLS so far start handshake with a 0x16 message type code. + def is_next_line_obviously_invalid_request_line(self) -> bool: + try: + # HTTP header line must not contain non-printable characters + # and should not start with a space + return self._data[0] < 0x21 + except IndexError: + return False diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/h11/_state.py b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/h11/_state.py new file mode 100644 index 00000000..27907688 --- /dev/null +++ b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/h11/_state.py @@ -0,0 +1,363 @@ +################################################################ +# The core state machine +################################################################ +# +# Rule 1: everything that affects the state machine and state transitions must +# live here in this file. As much as possible goes into the table-based +# representation, but for the bits that don't quite fit, the actual code and +# state must nonetheless live here. +# +# Rule 2: this file does not know about what role we're playing; it only knows +# about HTTP request/response cycles in the abstract. This ensures that we +# don't cheat and apply different rules to local and remote parties. +# +# +# Theory of operation +# =================== +# +# Possibly the simplest way to think about this is that we actually have 5 +# different state machines here. Yes, 5. These are: +# +# 1) The client state, with its complicated automaton (see the docs) +# 2) The server state, with its complicated automaton (see the docs) +# 3) The keep-alive state, with possible states {True, False} +# 4) The SWITCH_CONNECT state, with possible states {False, True} +# 5) The SWITCH_UPGRADE state, with possible states {False, True} +# +# For (3)-(5), the first state listed is the initial state. +# +# (1)-(3) are stored explicitly in member variables. The last +# two are stored implicitly in the pending_switch_proposals set as: +# (state of 4) == (_SWITCH_CONNECT in pending_switch_proposals) +# (state of 5) == (_SWITCH_UPGRADE in pending_switch_proposals) +# +# And each of these machines has two different kinds of transitions: +# +# a) Event-triggered +# b) State-triggered +# +# Event triggered is the obvious thing that you'd think it is: some event +# happens, and if it's the right event at the right time then a transition +# happens. But there are somewhat complicated rules for which machines can +# "see" which events. (As a rule of thumb, if a machine "sees" an event, this +# means two things: the event can affect the machine, and if the machine is +# not in a state where it expects that event then it's an error.) These rules +# are: +# +# 1) The client machine sees all h11.events objects emitted by the client. +# +# 2) The server machine sees all h11.events objects emitted by the server. +# +# It also sees the client's Request event. +# +# And sometimes, server events are annotated with a _SWITCH_* event. For +# example, we can have a (Response, _SWITCH_CONNECT) event, which is +# different from a regular Response event. +# +# 3) The keep-alive machine sees the process_keep_alive_disabled() event +# (which is derived from Request/Response events), and this event +# transitions it from True -> False, or from False -> False. There's no way +# to transition back. +# +# 4&5) The _SWITCH_* machines transition from False->True when we get a +# Request that proposes the relevant type of switch (via +# process_client_switch_proposals), and they go from True->False when we +# get a Response that has no _SWITCH_* annotation. +# +# So that's event-triggered transitions. +# +# State-triggered transitions are less standard. What they do here is couple +# the machines together. The way this works is, when certain *joint* +# configurations of states are achieved, then we automatically transition to a +# new *joint* state. So, for example, if we're ever in a joint state with +# +# client: DONE +# keep-alive: False +# +# then the client state immediately transitions to: +# +# client: MUST_CLOSE +# +# This is fundamentally different from an event-based transition, because it +# doesn't matter how we arrived at the {client: DONE, keep-alive: False} state +# -- maybe the client transitioned SEND_BODY -> DONE, or keep-alive +# transitioned True -> False. Either way, once this precondition is satisfied, +# this transition is immediately triggered. +# +# What if two conflicting state-based transitions get enabled at the same +# time? In practice there's only one case where this arises (client DONE -> +# MIGHT_SWITCH_PROTOCOL versus DONE -> MUST_CLOSE), and we resolve it by +# explicitly prioritizing the DONE -> MIGHT_SWITCH_PROTOCOL transition. +# +# Implementation +# -------------- +# +# The event-triggered transitions for the server and client machines are all +# stored explicitly in a table. Ditto for the state-triggered transitions that +# involve just the server and client state. +# +# The transitions for the other machines, and the state-triggered transitions +# that involve the other machines, are written out as explicit Python code. +# +# It'd be nice if there were some cleaner way to do all this. This isn't +# *too* terrible, but I feel like it could probably be better. +# +# WARNING +# ------- +# +# The script that generates the state machine diagrams for the docs knows how +# to read out the EVENT_TRIGGERED_TRANSITIONS and STATE_TRIGGERED_TRANSITIONS +# tables. But it can't automatically read the transitions that are written +# directly in Python code. So if you touch those, you need to also update the +# script to keep it in sync! +from typing import cast, Dict, Optional, Set, Tuple, Type, Union + +from ._events import * +from ._util import LocalProtocolError, Sentinel + +# Everything in __all__ gets re-exported as part of the h11 public API. +__all__ = [ + "CLIENT", + "SERVER", + "IDLE", + "SEND_RESPONSE", + "SEND_BODY", + "DONE", + "MUST_CLOSE", + "CLOSED", + "MIGHT_SWITCH_PROTOCOL", + "SWITCHED_PROTOCOL", + "ERROR", +] + + +class CLIENT(Sentinel, metaclass=Sentinel): + pass + + +class SERVER(Sentinel, metaclass=Sentinel): + pass + + +# States +class IDLE(Sentinel, metaclass=Sentinel): + pass + + +class SEND_RESPONSE(Sentinel, metaclass=Sentinel): + pass + + +class SEND_BODY(Sentinel, metaclass=Sentinel): + pass + + +class DONE(Sentinel, metaclass=Sentinel): + pass + + +class MUST_CLOSE(Sentinel, metaclass=Sentinel): + pass + + +class CLOSED(Sentinel, metaclass=Sentinel): + pass + + +class ERROR(Sentinel, metaclass=Sentinel): + pass + + +# Switch types +class MIGHT_SWITCH_PROTOCOL(Sentinel, metaclass=Sentinel): + pass + + +class SWITCHED_PROTOCOL(Sentinel, metaclass=Sentinel): + pass + + +class _SWITCH_UPGRADE(Sentinel, metaclass=Sentinel): + pass + + +class _SWITCH_CONNECT(Sentinel, metaclass=Sentinel): + pass + + +EventTransitionType = Dict[ + Type[Sentinel], + Dict[ + Type[Sentinel], + Dict[Union[Type[Event], Tuple[Type[Event], Type[Sentinel]]], Type[Sentinel]], + ], +] + +EVENT_TRIGGERED_TRANSITIONS: EventTransitionType = { + CLIENT: { + IDLE: {Request: SEND_BODY, ConnectionClosed: CLOSED}, + SEND_BODY: {Data: SEND_BODY, EndOfMessage: DONE}, + DONE: {ConnectionClosed: CLOSED}, + MUST_CLOSE: {ConnectionClosed: CLOSED}, + CLOSED: {ConnectionClosed: CLOSED}, + MIGHT_SWITCH_PROTOCOL: {}, + SWITCHED_PROTOCOL: {}, + ERROR: {}, + }, + SERVER: { + IDLE: { + ConnectionClosed: CLOSED, + Response: SEND_BODY, + # Special case: server sees client Request events, in this form + (Request, CLIENT): SEND_RESPONSE, + }, + SEND_RESPONSE: { + InformationalResponse: SEND_RESPONSE, + Response: SEND_BODY, + (InformationalResponse, _SWITCH_UPGRADE): SWITCHED_PROTOCOL, + (Response, _SWITCH_CONNECT): SWITCHED_PROTOCOL, + }, + SEND_BODY: {Data: SEND_BODY, EndOfMessage: DONE}, + DONE: {ConnectionClosed: CLOSED}, + MUST_CLOSE: {ConnectionClosed: CLOSED}, + CLOSED: {ConnectionClosed: CLOSED}, + SWITCHED_PROTOCOL: {}, + ERROR: {}, + }, +} + +# NB: there are also some special-case state-triggered transitions hard-coded +# into _fire_state_triggered_transitions below. +STATE_TRIGGERED_TRANSITIONS = { + # (Client state, Server state) -> new states + # Protocol negotiation + (MIGHT_SWITCH_PROTOCOL, SWITCHED_PROTOCOL): {CLIENT: SWITCHED_PROTOCOL}, + # Socket shutdown + (CLOSED, DONE): {SERVER: MUST_CLOSE}, + (CLOSED, IDLE): {SERVER: MUST_CLOSE}, + (ERROR, DONE): {SERVER: MUST_CLOSE}, + (DONE, CLOSED): {CLIENT: MUST_CLOSE}, + (IDLE, CLOSED): {CLIENT: MUST_CLOSE}, + (DONE, ERROR): {CLIENT: MUST_CLOSE}, +} + + +class ConnectionState: + def __init__(self) -> None: + # Extra bits of state that don't quite fit into the state model. + + # If this is False then it enables the automatic DONE -> MUST_CLOSE + # transition. Don't set this directly; call .keep_alive_disabled() + self.keep_alive = True + + # This is a subset of {UPGRADE, CONNECT}, containing the proposals + # made by the client for switching protocols. + self.pending_switch_proposals: Set[Type[Sentinel]] = set() + + self.states: Dict[Type[Sentinel], Type[Sentinel]] = {CLIENT: IDLE, SERVER: IDLE} + + def process_error(self, role: Type[Sentinel]) -> None: + self.states[role] = ERROR + self._fire_state_triggered_transitions() + + def process_keep_alive_disabled(self) -> None: + self.keep_alive = False + self._fire_state_triggered_transitions() + + def process_client_switch_proposal(self, switch_event: Type[Sentinel]) -> None: + self.pending_switch_proposals.add(switch_event) + self._fire_state_triggered_transitions() + + def process_event( + self, + role: Type[Sentinel], + event_type: Type[Event], + server_switch_event: Optional[Type[Sentinel]] = None, + ) -> None: + _event_type: Union[Type[Event], Tuple[Type[Event], Type[Sentinel]]] = event_type + if server_switch_event is not None: + assert role is SERVER + if server_switch_event not in self.pending_switch_proposals: + raise LocalProtocolError( + "Received server {} event without a pending proposal".format( + server_switch_event + ) + ) + _event_type = (event_type, server_switch_event) + if server_switch_event is None and _event_type is Response: + self.pending_switch_proposals = set() + self._fire_event_triggered_transitions(role, _event_type) + # Special case: the server state does get to see Request + # events. + if _event_type is Request: + assert role is CLIENT + self._fire_event_triggered_transitions(SERVER, (Request, CLIENT)) + self._fire_state_triggered_transitions() + + def _fire_event_triggered_transitions( + self, + role: Type[Sentinel], + event_type: Union[Type[Event], Tuple[Type[Event], Type[Sentinel]]], + ) -> None: + state = self.states[role] + try: + new_state = EVENT_TRIGGERED_TRANSITIONS[role][state][event_type] + except KeyError: + event_type = cast(Type[Event], event_type) + raise LocalProtocolError( + "can't handle event type {} when role={} and state={}".format( + event_type.__name__, role, self.states[role] + ) + ) from None + self.states[role] = new_state + + def _fire_state_triggered_transitions(self) -> None: + # We apply these rules repeatedly until converging on a fixed point + while True: + start_states = dict(self.states) + + # It could happen that both these special-case transitions are + # enabled at the same time: + # + # DONE -> MIGHT_SWITCH_PROTOCOL + # DONE -> MUST_CLOSE + # + # For example, this will always be true of a HTTP/1.0 client + # requesting CONNECT. If this happens, the protocol switch takes + # priority. From there the client will either go to + # SWITCHED_PROTOCOL, in which case it's none of our business when + # they close the connection, or else the server will deny the + # request, in which case the client will go back to DONE and then + # from there to MUST_CLOSE. + if self.pending_switch_proposals: + if self.states[CLIENT] is DONE: + self.states[CLIENT] = MIGHT_SWITCH_PROTOCOL + + if not self.pending_switch_proposals: + if self.states[CLIENT] is MIGHT_SWITCH_PROTOCOL: + self.states[CLIENT] = DONE + + if not self.keep_alive: + for role in (CLIENT, SERVER): + if self.states[role] is DONE: + self.states[role] = MUST_CLOSE + + # Tabular state-triggered transitions + joint_state = (self.states[CLIENT], self.states[SERVER]) + changes = STATE_TRIGGERED_TRANSITIONS.get(joint_state, {}) + self.states.update(changes) # type: ignore + + if self.states == start_states: + # Fixed point reached + return + + def start_next_cycle(self) -> None: + if self.states != {CLIENT: DONE, SERVER: DONE}: + raise LocalProtocolError( + "not in a reusable state. self.states={}".format(self.states) + ) + # Can't reach DONE/DONE with any of these active, but still, let's be + # sure. + assert self.keep_alive + assert not self.pending_switch_proposals + self.states = {CLIENT: IDLE, SERVER: IDLE} diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/h11/_util.py b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/h11/_util.py new file mode 100644 index 00000000..67184452 --- /dev/null +++ b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/h11/_util.py @@ -0,0 +1,135 @@ +from typing import Any, Dict, NoReturn, Pattern, Tuple, Type, TypeVar, Union + +__all__ = [ + "ProtocolError", + "LocalProtocolError", + "RemoteProtocolError", + "validate", + "bytesify", +] + + +class ProtocolError(Exception): + """Exception indicating a violation of the HTTP/1.1 protocol. + + This as an abstract base class, with two concrete base classes: + :exc:`LocalProtocolError`, which indicates that you tried to do something + that HTTP/1.1 says is illegal, and :exc:`RemoteProtocolError`, which + indicates that the remote peer tried to do something that HTTP/1.1 says is + illegal. See :ref:`error-handling` for details. + + In addition to the normal :exc:`Exception` features, it has one attribute: + + .. attribute:: error_status_hint + + This gives a suggestion as to what status code a server might use if + this error occurred as part of a request. + + For a :exc:`RemoteProtocolError`, this is useful as a suggestion for + how you might want to respond to a misbehaving peer, if you're + implementing a server. + + For a :exc:`LocalProtocolError`, this can be taken as a suggestion for + how your peer might have responded to *you* if h11 had allowed you to + continue. + + The default is 400 Bad Request, a generic catch-all for protocol + violations. + + """ + + def __init__(self, msg: str, error_status_hint: int = 400) -> None: + if type(self) is ProtocolError: + raise TypeError("tried to directly instantiate ProtocolError") + Exception.__init__(self, msg) + self.error_status_hint = error_status_hint + + +# Strategy: there are a number of public APIs where a LocalProtocolError can +# be raised (send(), all the different event constructors, ...), and only one +# public API where RemoteProtocolError can be raised +# (receive_data()). Therefore we always raise LocalProtocolError internally, +# and then receive_data will translate this into a RemoteProtocolError. +# +# Internally: +# LocalProtocolError is the generic "ProtocolError". +# Externally: +# LocalProtocolError is for local errors and RemoteProtocolError is for +# remote errors. +class LocalProtocolError(ProtocolError): + def _reraise_as_remote_protocol_error(self) -> NoReturn: + # After catching a LocalProtocolError, use this method to re-raise it + # as a RemoteProtocolError. This method must be called from inside an + # except: block. + # + # An easy way to get an equivalent RemoteProtocolError is just to + # modify 'self' in place. + self.__class__ = RemoteProtocolError # type: ignore + # But the re-raising is somewhat non-trivial -- you might think that + # now that we've modified the in-flight exception object, that just + # doing 'raise' to re-raise it would be enough. But it turns out that + # this doesn't work, because Python tracks the exception type + # (exc_info[0]) separately from the exception object (exc_info[1]), + # and we only modified the latter. So we really do need to re-raise + # the new type explicitly. + # On py3, the traceback is part of the exception object, so our + # in-place modification preserved it and we can just re-raise: + raise self + + +class RemoteProtocolError(ProtocolError): + pass + + +def validate( + regex: Pattern[bytes], data: bytes, msg: str = "malformed data", *format_args: Any +) -> Dict[str, bytes]: + match = regex.fullmatch(data) + if not match: + if format_args: + msg = msg.format(*format_args) + raise LocalProtocolError(msg) + return match.groupdict() + + +# Sentinel values +# +# - Inherit identity-based comparison and hashing from object +# - Have a nice repr +# - Have a *bonus property*: type(sentinel) is sentinel +# +# The bonus property is useful if you want to take the return value from +# next_event() and do some sort of dispatch based on type(event). + +_T_Sentinel = TypeVar("_T_Sentinel", bound="Sentinel") + + +class Sentinel(type): + def __new__( + cls: Type[_T_Sentinel], + name: str, + bases: Tuple[type, ...], + namespace: Dict[str, Any], + **kwds: Any + ) -> _T_Sentinel: + assert bases == (Sentinel,) + v = super().__new__(cls, name, bases, namespace, **kwds) + v.__class__ = v # type: ignore + return v + + def __repr__(self) -> str: + return self.__name__ + + +# Used for methods, request targets, HTTP versions, header names, and header +# values. Accepts ascii-strings, or bytes/bytearray/memoryview/..., and always +# returns bytes. +def bytesify(s: Union[bytes, bytearray, memoryview, int, str]) -> bytes: + # Fast-path: + if type(s) is bytes: + return s + if isinstance(s, str): + s = s.encode("ascii") + if isinstance(s, int): + raise TypeError("expected bytes-like object, not int") + return bytes(s) diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/h11/_version.py b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/h11/_version.py new file mode 100644 index 00000000..75d42886 --- /dev/null +++ b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/h11/_version.py @@ -0,0 +1,16 @@ +# This file must be kept very simple, because it is consumed from several +# places -- it is imported by h11/__init__.py, execfile'd by setup.py, etc. + +# We use a simple scheme: +# 1.0.0 -> 1.0.0+dev -> 1.1.0 -> 1.1.0+dev +# where the +dev versions are never released into the wild, they're just what +# we stick into the VCS in between releases. +# +# This is compatible with PEP 440: +# http://legacy.python.org/dev/peps/pep-0440/ +# via the use of the "local suffix" "+dev", which is disallowed on index +# servers and causes 1.0.0+dev to sort after plain 1.0.0, which is what we +# want. (Contrast with the special suffix 1.0.0.dev, which sorts *before* +# 1.0.0.) + +__version__ = "0.13.0" diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/h11/_writers.py b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/h11/_writers.py new file mode 100644 index 00000000..90a8dc0a --- /dev/null +++ b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/h11/_writers.py @@ -0,0 +1,145 @@ +# Code to read HTTP data +# +# Strategy: each writer takes an event + a write-some-bytes function, which is +# calls. +# +# WRITERS is a dict describing how to pick a reader. It maps states to either: +# - a writer +# - or, for body writers, a dict of framin-dependent writer factories + +from typing import Any, Callable, Dict, List, Tuple, Type, Union + +from ._events import Data, EndOfMessage, Event, InformationalResponse, Request, Response +from ._headers import Headers +from ._state import CLIENT, IDLE, SEND_BODY, SEND_RESPONSE, SERVER +from ._util import LocalProtocolError, Sentinel + +__all__ = ["WRITERS"] + +Writer = Callable[[bytes], Any] + + +def write_headers(headers: Headers, write: Writer) -> None: + # "Since the Host field-value is critical information for handling a + # request, a user agent SHOULD generate Host as the first header field + # following the request-line." - RFC 7230 + raw_items = headers._full_items + for raw_name, name, value in raw_items: + if name == b"host": + write(b"%s: %s\r\n" % (raw_name, value)) + for raw_name, name, value in raw_items: + if name != b"host": + write(b"%s: %s\r\n" % (raw_name, value)) + write(b"\r\n") + + +def write_request(request: Request, write: Writer) -> None: + if request.http_version != b"1.1": + raise LocalProtocolError("I only send HTTP/1.1") + write(b"%s %s HTTP/1.1\r\n" % (request.method, request.target)) + write_headers(request.headers, write) + + +# Shared between InformationalResponse and Response +def write_any_response( + response: Union[InformationalResponse, Response], write: Writer +) -> None: + if response.http_version != b"1.1": + raise LocalProtocolError("I only send HTTP/1.1") + status_bytes = str(response.status_code).encode("ascii") + # We don't bother sending ascii status messages like "OK"; they're + # optional and ignored by the protocol. (But the space after the numeric + # status code is mandatory.) + # + # XX FIXME: could at least make an effort to pull out the status message + # from stdlib's http.HTTPStatus table. Or maybe just steal their enums + # (either by import or copy/paste). We already accept them as status codes + # since they're of type IntEnum < int. + write(b"HTTP/1.1 %s %s\r\n" % (status_bytes, response.reason)) + write_headers(response.headers, write) + + +class BodyWriter: + def __call__(self, event: Event, write: Writer) -> None: + if type(event) is Data: + self.send_data(event.data, write) + elif type(event) is EndOfMessage: + self.send_eom(event.headers, write) + else: # pragma: no cover + assert False + + def send_data(self, data: bytes, write: Writer) -> None: + pass + + def send_eom(self, headers: Headers, write: Writer) -> None: + pass + + +# +# These are all careful not to do anything to 'data' except call len(data) and +# write(data). This allows us to transparently pass-through funny objects, +# like placeholder objects referring to files on disk that will be sent via +# sendfile(2). +# +class ContentLengthWriter(BodyWriter): + def __init__(self, length: int) -> None: + self._length = length + + def send_data(self, data: bytes, write: Writer) -> None: + self._length -= len(data) + if self._length < 0: + raise LocalProtocolError("Too much data for declared Content-Length") + write(data) + + def send_eom(self, headers: Headers, write: Writer) -> None: + if self._length != 0: + raise LocalProtocolError("Too little data for declared Content-Length") + if headers: + raise LocalProtocolError("Content-Length and trailers don't mix") + + +class ChunkedWriter(BodyWriter): + def send_data(self, data: bytes, write: Writer) -> None: + # if we encoded 0-length data in the naive way, it would look like an + # end-of-message. + if not data: + return + write(b"%x\r\n" % len(data)) + write(data) + write(b"\r\n") + + def send_eom(self, headers: Headers, write: Writer) -> None: + write(b"0\r\n") + write_headers(headers, write) + + +class Http10Writer(BodyWriter): + def send_data(self, data: bytes, write: Writer) -> None: + write(data) + + def send_eom(self, headers: Headers, write: Writer) -> None: + if headers: + raise LocalProtocolError("can't send trailers to HTTP/1.0 client") + # no need to close the socket ourselves, that will be taken care of by + # Connection: close machinery + + +WritersType = Dict[ + Union[Tuple[Sentinel, Sentinel], Sentinel], + Union[ + Dict[str, Type[BodyWriter]], + Callable[[Union[InformationalResponse, Response], Writer], None], + Callable[[Request, Writer], None], + ], +] + +WRITERS: WritersType = { + (CLIENT, IDLE): write_request, + (SERVER, IDLE): write_any_response, + (SERVER, SEND_RESPONSE): write_any_response, + SEND_BODY: { + "chunked": ChunkedWriter, + "content-length": ContentLengthWriter, + "http/1.0": Http10Writer, + }, +} diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/h11/py.typed b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/h11/py.typed new file mode 100644 index 00000000..f5642f79 --- /dev/null +++ b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/h11/py.typed @@ -0,0 +1 @@ +Marker diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/h11/tests/__init__.py b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/h11/tests/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/h11/tests/data/test-file b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/h11/tests/data/test-file new file mode 100644 index 00000000..d0be0a6c --- /dev/null +++ b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/h11/tests/data/test-file @@ -0,0 +1 @@ +92b12bc045050b55b848d37167a1a63947c364579889ce1d39788e45e9fac9e5 diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/h11/tests/helpers.py b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/h11/tests/helpers.py new file mode 100644 index 00000000..571be444 --- /dev/null +++ b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/h11/tests/helpers.py @@ -0,0 +1,101 @@ +from typing import cast, List, Type, Union, ValuesView + +from .._connection import Connection, NEED_DATA, PAUSED +from .._events import ( + ConnectionClosed, + Data, + EndOfMessage, + Event, + InformationalResponse, + Request, + Response, +) +from .._state import CLIENT, CLOSED, DONE, MUST_CLOSE, SERVER +from .._util import Sentinel + +try: + from typing import Literal +except ImportError: + from typing_extensions import Literal # type: ignore + + +def get_all_events(conn: Connection) -> List[Event]: + got_events = [] + while True: + event = conn.next_event() + if event in (NEED_DATA, PAUSED): + break + event = cast(Event, event) + got_events.append(event) + if type(event) is ConnectionClosed: + break + return got_events + + +def receive_and_get(conn: Connection, data: bytes) -> List[Event]: + conn.receive_data(data) + return get_all_events(conn) + + +# Merges adjacent Data events, converts payloads to bytestrings, and removes +# chunk boundaries. +def normalize_data_events(in_events: List[Event]) -> List[Event]: + out_events: List[Event] = [] + for event in in_events: + if type(event) is Data: + event = Data(data=bytes(event.data), chunk_start=False, chunk_end=False) + if out_events and type(out_events[-1]) is type(event) is Data: + out_events[-1] = Data( + data=out_events[-1].data + event.data, + chunk_start=out_events[-1].chunk_start, + chunk_end=out_events[-1].chunk_end, + ) + else: + out_events.append(event) + return out_events + + +# Given that we want to write tests that push some events through a Connection +# and check that its state updates appropriately... we might as make a habit +# of pushing them through two Connections with a fake network link in +# between. +class ConnectionPair: + def __init__(self) -> None: + self.conn = {CLIENT: Connection(CLIENT), SERVER: Connection(SERVER)} + self.other = {CLIENT: SERVER, SERVER: CLIENT} + + @property + def conns(self) -> ValuesView[Connection]: + return self.conn.values() + + # expect="match" if expect=send_events; expect=[...] to say what expected + def send( + self, + role: Type[Sentinel], + send_events: Union[List[Event], Event], + expect: Union[List[Event], Event, Literal["match"]] = "match", + ) -> bytes: + if not isinstance(send_events, list): + send_events = [send_events] + data = b"" + closed = False + for send_event in send_events: + new_data = self.conn[role].send(send_event) + if new_data is None: + closed = True + else: + data += new_data + # send uses b"" to mean b"", and None to mean closed + # receive uses b"" to mean closed, and None to mean "try again" + # so we have to translate between the two conventions + if data: + self.conn[self.other[role]].receive_data(data) + if closed: + self.conn[self.other[role]].receive_data(b"") + got_events = get_all_events(self.conn[self.other[role]]) + if expect == "match": + expect = send_events + if not isinstance(expect, list): + expect = [expect] + assert got_events == expect + return data diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/h11/tests/test_against_stdlib_http.py b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/h11/tests/test_against_stdlib_http.py new file mode 100644 index 00000000..d2ee1314 --- /dev/null +++ b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/h11/tests/test_against_stdlib_http.py @@ -0,0 +1,115 @@ +import json +import os.path +import socket +import socketserver +import threading +from contextlib import closing, contextmanager +from http.server import SimpleHTTPRequestHandler +from typing import Callable, Generator +from urllib.request import urlopen + +import h11 + + +@contextmanager +def socket_server( + handler: Callable[..., socketserver.BaseRequestHandler] +) -> Generator[socketserver.TCPServer, None, None]: + httpd = socketserver.TCPServer(("127.0.0.1", 0), handler) + thread = threading.Thread( + target=httpd.serve_forever, kwargs={"poll_interval": 0.01} + ) + thread.daemon = True + try: + thread.start() + yield httpd + finally: + httpd.shutdown() + + +test_file_path = os.path.join(os.path.dirname(__file__), "data/test-file") +with open(test_file_path, "rb") as f: + test_file_data = f.read() + + +class SingleMindedRequestHandler(SimpleHTTPRequestHandler): + def translate_path(self, path: str) -> str: + return test_file_path + + +def test_h11_as_client() -> None: + with socket_server(SingleMindedRequestHandler) as httpd: + with closing(socket.create_connection(httpd.server_address)) as s: + c = h11.Connection(h11.CLIENT) + + s.sendall( + c.send( # type: ignore[arg-type] + h11.Request( + method="GET", target="/foo", headers=[("Host", "localhost")] + ) + ) + ) + s.sendall(c.send(h11.EndOfMessage())) # type: ignore[arg-type] + + data = bytearray() + while True: + event = c.next_event() + print(event) + if event is h11.NEED_DATA: + # Use a small read buffer to make things more challenging + # and exercise more paths :-) + c.receive_data(s.recv(10)) + continue + if type(event) is h11.Response: + assert event.status_code == 200 + if type(event) is h11.Data: + data += event.data + if type(event) is h11.EndOfMessage: + break + assert bytes(data) == test_file_data + + +class H11RequestHandler(socketserver.BaseRequestHandler): + def handle(self) -> None: + with closing(self.request) as s: + c = h11.Connection(h11.SERVER) + request = None + while True: + event = c.next_event() + if event is h11.NEED_DATA: + # Use a small read buffer to make things more challenging + # and exercise more paths :-) + c.receive_data(s.recv(10)) + continue + if type(event) is h11.Request: + request = event + if type(event) is h11.EndOfMessage: + break + assert request is not None + info = json.dumps( + { + "method": request.method.decode("ascii"), + "target": request.target.decode("ascii"), + "headers": { + name.decode("ascii"): value.decode("ascii") + for (name, value) in request.headers + }, + } + ) + s.sendall(c.send(h11.Response(status_code=200, headers=[]))) # type: ignore[arg-type] + s.sendall(c.send(h11.Data(data=info.encode("ascii")))) + s.sendall(c.send(h11.EndOfMessage())) + + +def test_h11_as_server() -> None: + with socket_server(H11RequestHandler) as httpd: + host, port = httpd.server_address + url = "http://{}:{}/some-path".format(host, port) + with closing(urlopen(url)) as f: + assert f.getcode() == 200 + data = f.read() + info = json.loads(data.decode("ascii")) + print(info) + assert info["method"] == "GET" + assert info["target"] == "/some-path" + assert "urllib" in info["headers"]["user-agent"] diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/h11/tests/test_connection.py b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/h11/tests/test_connection.py new file mode 100644 index 00000000..73a27b98 --- /dev/null +++ b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/h11/tests/test_connection.py @@ -0,0 +1,1122 @@ +from typing import Any, cast, Dict, List, Optional, Tuple, Type + +import pytest + +from .._connection import _body_framing, _keep_alive, Connection, NEED_DATA, PAUSED +from .._events import ( + ConnectionClosed, + Data, + EndOfMessage, + Event, + InformationalResponse, + Request, + Response, +) +from .._state import ( + CLIENT, + CLOSED, + DONE, + ERROR, + IDLE, + MIGHT_SWITCH_PROTOCOL, + MUST_CLOSE, + SEND_BODY, + SEND_RESPONSE, + SERVER, + SWITCHED_PROTOCOL, +) +from .._util import LocalProtocolError, RemoteProtocolError, Sentinel +from .helpers import ConnectionPair, get_all_events, receive_and_get + + +def test__keep_alive() -> None: + assert _keep_alive( + Request(method="GET", target="/", headers=[("Host", "Example.com")]) + ) + assert not _keep_alive( + Request( + method="GET", + target="/", + headers=[("Host", "Example.com"), ("Connection", "close")], + ) + ) + assert not _keep_alive( + Request( + method="GET", + target="/", + headers=[("Host", "Example.com"), ("Connection", "a, b, cLOse, foo")], + ) + ) + assert not _keep_alive( + Request(method="GET", target="/", headers=[], http_version="1.0") # type: ignore[arg-type] + ) + + assert _keep_alive(Response(status_code=200, headers=[])) # type: ignore[arg-type] + assert not _keep_alive(Response(status_code=200, headers=[("Connection", "close")])) + assert not _keep_alive( + Response(status_code=200, headers=[("Connection", "a, b, cLOse, foo")]) + ) + assert not _keep_alive(Response(status_code=200, headers=[], http_version="1.0")) # type: ignore[arg-type] + + +def test__body_framing() -> None: + def headers(cl: Optional[int], te: bool) -> List[Tuple[str, str]]: + headers = [] + if cl is not None: + headers.append(("Content-Length", str(cl))) + if te: + headers.append(("Transfer-Encoding", "chunked")) + return headers + + def resp( + status_code: int = 200, cl: Optional[int] = None, te: bool = False + ) -> Response: + return Response(status_code=status_code, headers=headers(cl, te)) + + def req(cl: Optional[int] = None, te: bool = False) -> Request: + h = headers(cl, te) + h += [("Host", "example.com")] + return Request(method="GET", target="/", headers=h) + + # Special cases where the headers are ignored: + for kwargs in [{}, {"cl": 100}, {"te": True}, {"cl": 100, "te": True}]: + kwargs = cast(Dict[str, Any], kwargs) + for meth, r in [ + (b"HEAD", resp(**kwargs)), + (b"GET", resp(status_code=204, **kwargs)), + (b"GET", resp(status_code=304, **kwargs)), + ]: + assert _body_framing(meth, r) == ("content-length", (0,)) + + # Transfer-encoding + for kwargs in [{"te": True}, {"cl": 100, "te": True}]: + kwargs = cast(Dict[str, Any], kwargs) + for meth, r in [(None, req(**kwargs)), (b"GET", resp(**kwargs))]: # type: ignore + assert _body_framing(meth, r) == ("chunked", ()) + + # Content-Length + for meth, r in [(None, req(cl=100)), (b"GET", resp(cl=100))]: # type: ignore + assert _body_framing(meth, r) == ("content-length", (100,)) + + # No headers + assert _body_framing(None, req()) == ("content-length", (0,)) # type: ignore + assert _body_framing(b"GET", resp()) == ("http/1.0", ()) + + +def test_Connection_basics_and_content_length() -> None: + with pytest.raises(ValueError): + Connection("CLIENT") # type: ignore + + p = ConnectionPair() + assert p.conn[CLIENT].our_role is CLIENT + assert p.conn[CLIENT].their_role is SERVER + assert p.conn[SERVER].our_role is SERVER + assert p.conn[SERVER].their_role is CLIENT + + data = p.send( + CLIENT, + Request( + method="GET", + target="/", + headers=[("Host", "example.com"), ("Content-Length", "10")], + ), + ) + assert data == ( + b"GET / HTTP/1.1\r\n" b"Host: example.com\r\n" b"Content-Length: 10\r\n\r\n" + ) + + for conn in p.conns: + assert conn.states == {CLIENT: SEND_BODY, SERVER: SEND_RESPONSE} + assert p.conn[CLIENT].our_state is SEND_BODY + assert p.conn[CLIENT].their_state is SEND_RESPONSE + assert p.conn[SERVER].our_state is SEND_RESPONSE + assert p.conn[SERVER].their_state is SEND_BODY + + assert p.conn[CLIENT].their_http_version is None + assert p.conn[SERVER].their_http_version == b"1.1" + + data = p.send(SERVER, InformationalResponse(status_code=100, headers=[])) # type: ignore[arg-type] + assert data == b"HTTP/1.1 100 \r\n\r\n" + + data = p.send(SERVER, Response(status_code=200, headers=[("Content-Length", "11")])) + assert data == b"HTTP/1.1 200 \r\nContent-Length: 11\r\n\r\n" + + for conn in p.conns: + assert conn.states == {CLIENT: SEND_BODY, SERVER: SEND_BODY} + + assert p.conn[CLIENT].their_http_version == b"1.1" + assert p.conn[SERVER].their_http_version == b"1.1" + + data = p.send(CLIENT, Data(data=b"12345")) + assert data == b"12345" + data = p.send( + CLIENT, Data(data=b"67890"), expect=[Data(data=b"67890"), EndOfMessage()] + ) + assert data == b"67890" + data = p.send(CLIENT, EndOfMessage(), expect=[]) + assert data == b"" + + for conn in p.conns: + assert conn.states == {CLIENT: DONE, SERVER: SEND_BODY} + + data = p.send(SERVER, Data(data=b"1234567890")) + assert data == b"1234567890" + data = p.send(SERVER, Data(data=b"1"), expect=[Data(data=b"1"), EndOfMessage()]) + assert data == b"1" + data = p.send(SERVER, EndOfMessage(), expect=[]) + assert data == b"" + + for conn in p.conns: + assert conn.states == {CLIENT: DONE, SERVER: DONE} + + +def test_chunked() -> None: + p = ConnectionPair() + + p.send( + CLIENT, + Request( + method="GET", + target="/", + headers=[("Host", "example.com"), ("Transfer-Encoding", "chunked")], + ), + ) + data = p.send(CLIENT, Data(data=b"1234567890", chunk_start=True, chunk_end=True)) + assert data == b"a\r\n1234567890\r\n" + data = p.send(CLIENT, Data(data=b"abcde", chunk_start=True, chunk_end=True)) + assert data == b"5\r\nabcde\r\n" + data = p.send(CLIENT, Data(data=b""), expect=[]) + assert data == b"" + data = p.send(CLIENT, EndOfMessage(headers=[("hello", "there")])) + assert data == b"0\r\nhello: there\r\n\r\n" + + p.send( + SERVER, Response(status_code=200, headers=[("Transfer-Encoding", "chunked")]) + ) + p.send(SERVER, Data(data=b"54321", chunk_start=True, chunk_end=True)) + p.send(SERVER, Data(data=b"12345", chunk_start=True, chunk_end=True)) + p.send(SERVER, EndOfMessage()) + + for conn in p.conns: + assert conn.states == {CLIENT: DONE, SERVER: DONE} + + +def test_chunk_boundaries() -> None: + conn = Connection(our_role=SERVER) + + request = ( + b"POST / HTTP/1.1\r\n" + b"Host: example.com\r\n" + b"Transfer-Encoding: chunked\r\n" + b"\r\n" + ) + conn.receive_data(request) + assert conn.next_event() == Request( + method="POST", + target="/", + headers=[("Host", "example.com"), ("Transfer-Encoding", "chunked")], + ) + assert conn.next_event() is NEED_DATA + + conn.receive_data(b"5\r\nhello\r\n") + assert conn.next_event() == Data(data=b"hello", chunk_start=True, chunk_end=True) + + conn.receive_data(b"5\r\nhel") + assert conn.next_event() == Data(data=b"hel", chunk_start=True, chunk_end=False) + + conn.receive_data(b"l") + assert conn.next_event() == Data(data=b"l", chunk_start=False, chunk_end=False) + + conn.receive_data(b"o\r\n") + assert conn.next_event() == Data(data=b"o", chunk_start=False, chunk_end=True) + + conn.receive_data(b"5\r\nhello") + assert conn.next_event() == Data(data=b"hello", chunk_start=True, chunk_end=True) + + conn.receive_data(b"\r\n") + assert conn.next_event() == NEED_DATA + + conn.receive_data(b"0\r\n\r\n") + assert conn.next_event() == EndOfMessage() + + +def test_client_talking_to_http10_server() -> None: + c = Connection(CLIENT) + c.send(Request(method="GET", target="/", headers=[("Host", "example.com")])) + c.send(EndOfMessage()) + assert c.our_state is DONE + # No content-length, so Http10 framing for body + assert receive_and_get(c, b"HTTP/1.0 200 OK\r\n\r\n") == [ + Response(status_code=200, headers=[], http_version="1.0", reason=b"OK") # type: ignore[arg-type] + ] + assert c.our_state is MUST_CLOSE + assert receive_and_get(c, b"12345") == [Data(data=b"12345")] + assert receive_and_get(c, b"67890") == [Data(data=b"67890")] + assert receive_and_get(c, b"") == [EndOfMessage(), ConnectionClosed()] + assert c.their_state is CLOSED + + +def test_server_talking_to_http10_client() -> None: + c = Connection(SERVER) + # No content-length, so no body + # NB: no host header + assert receive_and_get(c, b"GET / HTTP/1.0\r\n\r\n") == [ + Request(method="GET", target="/", headers=[], http_version="1.0"), # type: ignore[arg-type] + EndOfMessage(), + ] + assert c.their_state is MUST_CLOSE + + # We automatically Connection: close back at them + assert ( + c.send(Response(status_code=200, headers=[])) # type: ignore[arg-type] + == b"HTTP/1.1 200 \r\nConnection: close\r\n\r\n" + ) + + assert c.send(Data(data=b"12345")) == b"12345" + assert c.send(EndOfMessage()) == b"" + assert c.our_state is MUST_CLOSE + + # Check that it works if they do send Content-Length + c = Connection(SERVER) + # NB: no host header + assert receive_and_get(c, b"POST / HTTP/1.0\r\nContent-Length: 10\r\n\r\n1") == [ + Request( + method="POST", + target="/", + headers=[("Content-Length", "10")], + http_version="1.0", + ), + Data(data=b"1"), + ] + assert receive_and_get(c, b"234567890") == [Data(data=b"234567890"), EndOfMessage()] + assert c.their_state is MUST_CLOSE + assert receive_and_get(c, b"") == [ConnectionClosed()] + + +def test_automatic_transfer_encoding_in_response() -> None: + # Check that in responses, the user can specify either Transfer-Encoding: + # chunked or no framing at all, and in both cases we automatically select + # the right option depending on whether the peer speaks HTTP/1.0 or + # HTTP/1.1 + for user_headers in [ + [("Transfer-Encoding", "chunked")], + [], + # In fact, this even works if Content-Length is set, + # because if both are set then Transfer-Encoding wins + [("Transfer-Encoding", "chunked"), ("Content-Length", "100")], + ]: + user_headers = cast(List[Tuple[str, str]], user_headers) + p = ConnectionPair() + p.send( + CLIENT, + [ + Request(method="GET", target="/", headers=[("Host", "example.com")]), + EndOfMessage(), + ], + ) + # When speaking to HTTP/1.1 client, all of the above cases get + # normalized to Transfer-Encoding: chunked + p.send( + SERVER, + Response(status_code=200, headers=user_headers), + expect=Response( + status_code=200, headers=[("Transfer-Encoding", "chunked")] + ), + ) + + # When speaking to HTTP/1.0 client, all of the above cases get + # normalized to no-framing-headers + c = Connection(SERVER) + receive_and_get(c, b"GET / HTTP/1.0\r\n\r\n") + assert ( + c.send(Response(status_code=200, headers=user_headers)) + == b"HTTP/1.1 200 \r\nConnection: close\r\n\r\n" + ) + assert c.send(Data(data=b"12345")) == b"12345" + + +def test_automagic_connection_close_handling() -> None: + p = ConnectionPair() + # If the user explicitly sets Connection: close, then we notice and + # respect it + p.send( + CLIENT, + [ + Request( + method="GET", + target="/", + headers=[("Host", "example.com"), ("Connection", "close")], + ), + EndOfMessage(), + ], + ) + for conn in p.conns: + assert conn.states[CLIENT] is MUST_CLOSE + # And if the client sets it, the server automatically echoes it back + p.send( + SERVER, + # no header here... + [Response(status_code=204, headers=[]), EndOfMessage()], # type: ignore[arg-type] + # ...but oh look, it arrived anyway + expect=[ + Response(status_code=204, headers=[("connection", "close")]), + EndOfMessage(), + ], + ) + for conn in p.conns: + assert conn.states == {CLIENT: MUST_CLOSE, SERVER: MUST_CLOSE} + + +def test_100_continue() -> None: + def setup() -> ConnectionPair: + p = ConnectionPair() + p.send( + CLIENT, + Request( + method="GET", + target="/", + headers=[ + ("Host", "example.com"), + ("Content-Length", "100"), + ("Expect", "100-continue"), + ], + ), + ) + for conn in p.conns: + assert conn.client_is_waiting_for_100_continue + assert not p.conn[CLIENT].they_are_waiting_for_100_continue + assert p.conn[SERVER].they_are_waiting_for_100_continue + return p + + # Disabled by 100 Continue + p = setup() + p.send(SERVER, InformationalResponse(status_code=100, headers=[])) # type: ignore[arg-type] + for conn in p.conns: + assert not conn.client_is_waiting_for_100_continue + assert not conn.they_are_waiting_for_100_continue + + # Disabled by a real response + p = setup() + p.send( + SERVER, Response(status_code=200, headers=[("Transfer-Encoding", "chunked")]) + ) + for conn in p.conns: + assert not conn.client_is_waiting_for_100_continue + assert not conn.they_are_waiting_for_100_continue + + # Disabled by the client going ahead and sending stuff anyway + p = setup() + p.send(CLIENT, Data(data=b"12345")) + for conn in p.conns: + assert not conn.client_is_waiting_for_100_continue + assert not conn.they_are_waiting_for_100_continue + + +def test_max_incomplete_event_size_countermeasure() -> None: + # Infinitely long headers are definitely not okay + c = Connection(SERVER) + c.receive_data(b"GET / HTTP/1.0\r\nEndless: ") + assert c.next_event() is NEED_DATA + with pytest.raises(RemoteProtocolError): + while True: + c.receive_data(b"a" * 1024) + c.next_event() + + # Checking that the same header is accepted / rejected depending on the + # max_incomplete_event_size setting: + c = Connection(SERVER, max_incomplete_event_size=5000) + c.receive_data(b"GET / HTTP/1.0\r\nBig: ") + c.receive_data(b"a" * 4000) + c.receive_data(b"\r\n\r\n") + assert get_all_events(c) == [ + Request( + method="GET", target="/", http_version="1.0", headers=[("big", "a" * 4000)] + ), + EndOfMessage(), + ] + + c = Connection(SERVER, max_incomplete_event_size=4000) + c.receive_data(b"GET / HTTP/1.0\r\nBig: ") + c.receive_data(b"a" * 4000) + with pytest.raises(RemoteProtocolError): + c.next_event() + + # Temporarily exceeding the size limit is fine, as long as its done with + # complete events: + c = Connection(SERVER, max_incomplete_event_size=5000) + c.receive_data(b"GET / HTTP/1.0\r\nContent-Length: 10000") + c.receive_data(b"\r\n\r\n" + b"a" * 10000) + assert get_all_events(c) == [ + Request( + method="GET", + target="/", + http_version="1.0", + headers=[("Content-Length", "10000")], + ), + Data(data=b"a" * 10000), + EndOfMessage(), + ] + + c = Connection(SERVER, max_incomplete_event_size=100) + # Two pipelined requests to create a way-too-big receive buffer... but + # it's fine because we're not checking + c.receive_data( + b"GET /1 HTTP/1.1\r\nHost: a\r\n\r\n" + b"GET /2 HTTP/1.1\r\nHost: b\r\n\r\n" + b"X" * 1000 + ) + assert get_all_events(c) == [ + Request(method="GET", target="/1", headers=[("host", "a")]), + EndOfMessage(), + ] + # Even more data comes in, still no problem + c.receive_data(b"X" * 1000) + # We can respond and reuse to get the second pipelined request + c.send(Response(status_code=200, headers=[])) # type: ignore[arg-type] + c.send(EndOfMessage()) + c.start_next_cycle() + assert get_all_events(c) == [ + Request(method="GET", target="/2", headers=[("host", "b")]), + EndOfMessage(), + ] + # But once we unpause and try to read the next message, and find that it's + # incomplete and the buffer is *still* way too large, then *that's* a + # problem: + c.send(Response(status_code=200, headers=[])) # type: ignore[arg-type] + c.send(EndOfMessage()) + c.start_next_cycle() + with pytest.raises(RemoteProtocolError): + c.next_event() + + +def test_reuse_simple() -> None: + p = ConnectionPair() + p.send( + CLIENT, + [Request(method="GET", target="/", headers=[("Host", "a")]), EndOfMessage()], + ) + p.send( + SERVER, + [ + Response(status_code=200, headers=[(b"transfer-encoding", b"chunked")]), + EndOfMessage(), + ], + ) + for conn in p.conns: + assert conn.states == {CLIENT: DONE, SERVER: DONE} + conn.start_next_cycle() + + p.send( + CLIENT, + [ + Request(method="DELETE", target="/foo", headers=[("Host", "a")]), + EndOfMessage(), + ], + ) + p.send( + SERVER, + [ + Response(status_code=404, headers=[(b"transfer-encoding", b"chunked")]), + EndOfMessage(), + ], + ) + + +def test_pipelining() -> None: + # Client doesn't support pipelining, so we have to do this by hand + c = Connection(SERVER) + assert c.next_event() is NEED_DATA + # 3 requests all bunched up + c.receive_data( + b"GET /1 HTTP/1.1\r\nHost: a.com\r\nContent-Length: 5\r\n\r\n" + b"12345" + b"GET /2 HTTP/1.1\r\nHost: a.com\r\nContent-Length: 5\r\n\r\n" + b"67890" + b"GET /3 HTTP/1.1\r\nHost: a.com\r\n\r\n" + ) + assert get_all_events(c) == [ + Request( + method="GET", + target="/1", + headers=[("Host", "a.com"), ("Content-Length", "5")], + ), + Data(data=b"12345"), + EndOfMessage(), + ] + assert c.their_state is DONE + assert c.our_state is SEND_RESPONSE + + assert c.next_event() is PAUSED + + c.send(Response(status_code=200, headers=[])) # type: ignore[arg-type] + c.send(EndOfMessage()) + assert c.their_state is DONE + assert c.our_state is DONE + + c.start_next_cycle() + + assert get_all_events(c) == [ + Request( + method="GET", + target="/2", + headers=[("Host", "a.com"), ("Content-Length", "5")], + ), + Data(data=b"67890"), + EndOfMessage(), + ] + assert c.next_event() is PAUSED + c.send(Response(status_code=200, headers=[])) # type: ignore[arg-type] + c.send(EndOfMessage()) + c.start_next_cycle() + + assert get_all_events(c) == [ + Request(method="GET", target="/3", headers=[("Host", "a.com")]), + EndOfMessage(), + ] + # Doesn't pause this time, no trailing data + assert c.next_event() is NEED_DATA + c.send(Response(status_code=200, headers=[])) # type: ignore[arg-type] + c.send(EndOfMessage()) + + # Arrival of more data triggers pause + assert c.next_event() is NEED_DATA + c.receive_data(b"SADF") + assert c.next_event() is PAUSED + assert c.trailing_data == (b"SADF", False) + # If EOF arrives while paused, we don't see that either: + c.receive_data(b"") + assert c.trailing_data == (b"SADF", True) + assert c.next_event() is PAUSED + c.receive_data(b"") + assert c.next_event() is PAUSED + # Can't call receive_data with non-empty buf after closing it + with pytest.raises(RuntimeError): + c.receive_data(b"FDSA") + + +def test_protocol_switch() -> None: + for (req, deny, accept) in [ + ( + Request( + method="CONNECT", + target="example.com:443", + headers=[("Host", "foo"), ("Content-Length", "1")], + ), + Response(status_code=404, headers=[(b"transfer-encoding", b"chunked")]), + Response(status_code=200, headers=[(b"transfer-encoding", b"chunked")]), + ), + ( + Request( + method="GET", + target="/", + headers=[("Host", "foo"), ("Content-Length", "1"), ("Upgrade", "a, b")], + ), + Response(status_code=200, headers=[(b"transfer-encoding", b"chunked")]), + InformationalResponse(status_code=101, headers=[("Upgrade", "a")]), + ), + ( + Request( + method="CONNECT", + target="example.com:443", + headers=[("Host", "foo"), ("Content-Length", "1"), ("Upgrade", "a, b")], + ), + Response(status_code=404, headers=[(b"transfer-encoding", b"chunked")]), + # Accept CONNECT, not upgrade + Response(status_code=200, headers=[(b"transfer-encoding", b"chunked")]), + ), + ( + Request( + method="CONNECT", + target="example.com:443", + headers=[("Host", "foo"), ("Content-Length", "1"), ("Upgrade", "a, b")], + ), + Response(status_code=404, headers=[(b"transfer-encoding", b"chunked")]), + # Accept Upgrade, not CONNECT + InformationalResponse(status_code=101, headers=[("Upgrade", "b")]), + ), + ]: + + def setup() -> ConnectionPair: + p = ConnectionPair() + p.send(CLIENT, req) + # No switch-related state change stuff yet; the client has to + # finish the request before that kicks in + for conn in p.conns: + assert conn.states[CLIENT] is SEND_BODY + p.send(CLIENT, [Data(data=b"1"), EndOfMessage()]) + for conn in p.conns: + assert conn.states[CLIENT] is MIGHT_SWITCH_PROTOCOL + assert p.conn[SERVER].next_event() is PAUSED + return p + + # Test deny case + p = setup() + p.send(SERVER, deny) + for conn in p.conns: + assert conn.states == {CLIENT: DONE, SERVER: SEND_BODY} + p.send(SERVER, EndOfMessage()) + # Check that re-use is still allowed after a denial + for conn in p.conns: + conn.start_next_cycle() + + # Test accept case + p = setup() + p.send(SERVER, accept) + for conn in p.conns: + assert conn.states == {CLIENT: SWITCHED_PROTOCOL, SERVER: SWITCHED_PROTOCOL} + conn.receive_data(b"123") + assert conn.next_event() is PAUSED + conn.receive_data(b"456") + assert conn.next_event() is PAUSED + assert conn.trailing_data == (b"123456", False) + + # Pausing in might-switch, then recovery + # (weird artificial case where the trailing data actually is valid + # HTTP for some reason, because this makes it easier to test the state + # logic) + p = setup() + sc = p.conn[SERVER] + sc.receive_data(b"GET / HTTP/1.0\r\n\r\n") + assert sc.next_event() is PAUSED + assert sc.trailing_data == (b"GET / HTTP/1.0\r\n\r\n", False) + sc.send(deny) + assert sc.next_event() is PAUSED + sc.send(EndOfMessage()) + sc.start_next_cycle() + assert get_all_events(sc) == [ + Request(method="GET", target="/", headers=[], http_version="1.0"), # type: ignore[arg-type] + EndOfMessage(), + ] + + # When we're DONE, have no trailing data, and the connection gets + # closed, we report ConnectionClosed(). When we're in might-switch or + # switched, we don't. + p = setup() + sc = p.conn[SERVER] + sc.receive_data(b"") + assert sc.next_event() is PAUSED + assert sc.trailing_data == (b"", True) + p.send(SERVER, accept) + assert sc.next_event() is PAUSED + + p = setup() + sc = p.conn[SERVER] + sc.receive_data(b"") + assert sc.next_event() is PAUSED + sc.send(deny) + assert sc.next_event() == ConnectionClosed() + + # You can't send after switching protocols, or while waiting for a + # protocol switch + p = setup() + with pytest.raises(LocalProtocolError): + p.conn[CLIENT].send( + Request(method="GET", target="/", headers=[("Host", "a")]) + ) + p = setup() + p.send(SERVER, accept) + with pytest.raises(LocalProtocolError): + p.conn[SERVER].send(Data(data=b"123")) + + +def test_close_simple() -> None: + # Just immediately closing a new connection without anything having + # happened yet. + for (who_shot_first, who_shot_second) in [(CLIENT, SERVER), (SERVER, CLIENT)]: + + def setup() -> ConnectionPair: + p = ConnectionPair() + p.send(who_shot_first, ConnectionClosed()) + for conn in p.conns: + assert conn.states == { + who_shot_first: CLOSED, + who_shot_second: MUST_CLOSE, + } + return p + + # You can keep putting b"" into a closed connection, and you keep + # getting ConnectionClosed() out: + p = setup() + assert p.conn[who_shot_second].next_event() == ConnectionClosed() + assert p.conn[who_shot_second].next_event() == ConnectionClosed() + p.conn[who_shot_second].receive_data(b"") + assert p.conn[who_shot_second].next_event() == ConnectionClosed() + # Second party can close... + p = setup() + p.send(who_shot_second, ConnectionClosed()) + for conn in p.conns: + assert conn.our_state is CLOSED + assert conn.their_state is CLOSED + # But trying to receive new data on a closed connection is a + # RuntimeError (not ProtocolError, because the problem here isn't + # violation of HTTP, it's violation of physics) + p = setup() + with pytest.raises(RuntimeError): + p.conn[who_shot_second].receive_data(b"123") + # And receiving new data on a MUST_CLOSE connection is a ProtocolError + p = setup() + p.conn[who_shot_first].receive_data(b"GET") + with pytest.raises(RemoteProtocolError): + p.conn[who_shot_first].next_event() + + +def test_close_different_states() -> None: + req = [ + Request(method="GET", target="/foo", headers=[("Host", "a")]), + EndOfMessage(), + ] + resp = [ + Response(status_code=200, headers=[(b"transfer-encoding", b"chunked")]), + EndOfMessage(), + ] + + # Client before request + p = ConnectionPair() + p.send(CLIENT, ConnectionClosed()) + for conn in p.conns: + assert conn.states == {CLIENT: CLOSED, SERVER: MUST_CLOSE} + + # Client after request + p = ConnectionPair() + p.send(CLIENT, req) + p.send(CLIENT, ConnectionClosed()) + for conn in p.conns: + assert conn.states == {CLIENT: CLOSED, SERVER: SEND_RESPONSE} + + # Server after request -> not allowed + p = ConnectionPair() + p.send(CLIENT, req) + with pytest.raises(LocalProtocolError): + p.conn[SERVER].send(ConnectionClosed()) + p.conn[CLIENT].receive_data(b"") + with pytest.raises(RemoteProtocolError): + p.conn[CLIENT].next_event() + + # Server after response + p = ConnectionPair() + p.send(CLIENT, req) + p.send(SERVER, resp) + p.send(SERVER, ConnectionClosed()) + for conn in p.conns: + assert conn.states == {CLIENT: MUST_CLOSE, SERVER: CLOSED} + + # Both after closing (ConnectionClosed() is idempotent) + p = ConnectionPair() + p.send(CLIENT, req) + p.send(SERVER, resp) + p.send(CLIENT, ConnectionClosed()) + p.send(SERVER, ConnectionClosed()) + p.send(CLIENT, ConnectionClosed()) + p.send(SERVER, ConnectionClosed()) + + # In the middle of sending -> not allowed + p = ConnectionPair() + p.send( + CLIENT, + Request( + method="GET", target="/", headers=[("Host", "a"), ("Content-Length", "10")] + ), + ) + with pytest.raises(LocalProtocolError): + p.conn[CLIENT].send(ConnectionClosed()) + p.conn[SERVER].receive_data(b"") + with pytest.raises(RemoteProtocolError): + p.conn[SERVER].next_event() + + +# Receive several requests and then client shuts down their side of the +# connection; we can respond to each +def test_pipelined_close() -> None: + c = Connection(SERVER) + # 2 requests then a close + c.receive_data( + b"GET /1 HTTP/1.1\r\nHost: a.com\r\nContent-Length: 5\r\n\r\n" + b"12345" + b"GET /2 HTTP/1.1\r\nHost: a.com\r\nContent-Length: 5\r\n\r\n" + b"67890" + ) + c.receive_data(b"") + assert get_all_events(c) == [ + Request( + method="GET", + target="/1", + headers=[("host", "a.com"), ("content-length", "5")], + ), + Data(data=b"12345"), + EndOfMessage(), + ] + assert c.states[CLIENT] is DONE + c.send(Response(status_code=200, headers=[])) # type: ignore[arg-type] + c.send(EndOfMessage()) + assert c.states[SERVER] is DONE + c.start_next_cycle() + assert get_all_events(c) == [ + Request( + method="GET", + target="/2", + headers=[("host", "a.com"), ("content-length", "5")], + ), + Data(data=b"67890"), + EndOfMessage(), + ConnectionClosed(), + ] + assert c.states == {CLIENT: CLOSED, SERVER: SEND_RESPONSE} + c.send(Response(status_code=200, headers=[])) # type: ignore[arg-type] + c.send(EndOfMessage()) + assert c.states == {CLIENT: CLOSED, SERVER: MUST_CLOSE} + c.send(ConnectionClosed()) + assert c.states == {CLIENT: CLOSED, SERVER: CLOSED} + + +def test_sendfile() -> None: + class SendfilePlaceholder: + def __len__(self) -> int: + return 10 + + placeholder = SendfilePlaceholder() + + def setup( + header: Tuple[str, str], http_version: str + ) -> Tuple[Connection, Optional[List[bytes]]]: + c = Connection(SERVER) + receive_and_get( + c, "GET / HTTP/{}\r\nHost: a\r\n\r\n".format(http_version).encode("ascii") + ) + headers = [] + if header: + headers.append(header) + c.send(Response(status_code=200, headers=headers)) + return c, c.send_with_data_passthrough(Data(data=placeholder)) # type: ignore + + c, data = setup(("Content-Length", "10"), "1.1") + assert data == [placeholder] # type: ignore + # Raises an error if the connection object doesn't think we've sent + # exactly 10 bytes + c.send(EndOfMessage()) + + _, data = setup(("Transfer-Encoding", "chunked"), "1.1") + assert placeholder in data # type: ignore + data[data.index(placeholder)] = b"x" * 10 # type: ignore + assert b"".join(data) == b"a\r\nxxxxxxxxxx\r\n" # type: ignore + + c, data = setup(None, "1.0") # type: ignore + assert data == [placeholder] # type: ignore + assert c.our_state is SEND_BODY + + +def test_errors() -> None: + # After a receive error, you can't receive + for role in [CLIENT, SERVER]: + c = Connection(our_role=role) + c.receive_data(b"gibberish\r\n\r\n") + with pytest.raises(RemoteProtocolError): + c.next_event() + # Now any attempt to receive continues to raise + assert c.their_state is ERROR + assert c.our_state is not ERROR + print(c._cstate.states) + with pytest.raises(RemoteProtocolError): + c.next_event() + # But we can still yell at the client for sending us gibberish + if role is SERVER: + assert ( + c.send(Response(status_code=400, headers=[])) # type: ignore[arg-type] + == b"HTTP/1.1 400 \r\nConnection: close\r\n\r\n" + ) + + # After an error sending, you can no longer send + # (This is especially important for things like content-length errors, + # where there's complex internal state being modified) + def conn(role: Type[Sentinel]) -> Connection: + c = Connection(our_role=role) + if role is SERVER: + # Put it into the state where it *could* send a response... + receive_and_get(c, b"GET / HTTP/1.0\r\n\r\n") + assert c.our_state is SEND_RESPONSE + return c + + for role in [CLIENT, SERVER]: + if role is CLIENT: + # This HTTP/1.0 request won't be detected as bad until after we go + # through the state machine and hit the writing code + good = Request(method="GET", target="/", headers=[("Host", "example.com")]) + bad = Request( + method="GET", + target="/", + headers=[("Host", "example.com")], + http_version="1.0", + ) + elif role is SERVER: + good = Response(status_code=200, headers=[]) # type: ignore[arg-type,assignment] + bad = Response(status_code=200, headers=[], http_version="1.0") # type: ignore[arg-type,assignment] + # Make sure 'good' actually is good + c = conn(role) + c.send(good) + assert c.our_state is not ERROR + # Do that again, but this time sending 'bad' first + c = conn(role) + with pytest.raises(LocalProtocolError): + c.send(bad) + assert c.our_state is ERROR + assert c.their_state is not ERROR + # Now 'good' is not so good + with pytest.raises(LocalProtocolError): + c.send(good) + + # And check send_failed() too + c = conn(role) + c.send_failed() + assert c.our_state is ERROR + assert c.their_state is not ERROR + # This is idempotent + c.send_failed() + assert c.our_state is ERROR + assert c.their_state is not ERROR + + +def test_idle_receive_nothing() -> None: + # At one point this incorrectly raised an error + for role in [CLIENT, SERVER]: + c = Connection(role) + assert c.next_event() is NEED_DATA + + +def test_connection_drop() -> None: + c = Connection(SERVER) + c.receive_data(b"GET /") + assert c.next_event() is NEED_DATA + c.receive_data(b"") + with pytest.raises(RemoteProtocolError): + c.next_event() + + +def test_408_request_timeout() -> None: + # Should be able to send this spontaneously as a server without seeing + # anything from client + p = ConnectionPair() + p.send(SERVER, Response(status_code=408, headers=[(b"connection", b"close")])) + + +# This used to raise IndexError +def test_empty_request() -> None: + c = Connection(SERVER) + c.receive_data(b"\r\n") + with pytest.raises(RemoteProtocolError): + c.next_event() + + +# This used to raise IndexError +def test_empty_response() -> None: + c = Connection(CLIENT) + c.send(Request(method="GET", target="/", headers=[("Host", "a")])) + c.receive_data(b"\r\n") + with pytest.raises(RemoteProtocolError): + c.next_event() + + +@pytest.mark.parametrize( + "data", + [ + b"\x00", + b"\x20", + b"\x16\x03\x01\x00\xa5", # Typical start of a TLS Client Hello + ], +) +def test_early_detection_of_invalid_request(data: bytes) -> None: + c = Connection(SERVER) + # Early detection should occur before even receiving a `\r\n` + c.receive_data(data) + with pytest.raises(RemoteProtocolError): + c.next_event() + + +@pytest.mark.parametrize( + "data", + [ + b"\x00", + b"\x20", + b"\x16\x03\x03\x00\x31", # Typical start of a TLS Server Hello + ], +) +def test_early_detection_of_invalid_response(data: bytes) -> None: + c = Connection(CLIENT) + # Early detection should occur before even receiving a `\r\n` + c.receive_data(data) + with pytest.raises(RemoteProtocolError): + c.next_event() + + +# This used to give different headers for HEAD and GET. +# The correct way to handle HEAD is to put whatever headers we *would* have +# put if it were a GET -- even though we know that for HEAD, those headers +# will be ignored. +def test_HEAD_framing_headers() -> None: + def setup(method: bytes, http_version: bytes) -> Connection: + c = Connection(SERVER) + c.receive_data( + method + b" / HTTP/" + http_version + b"\r\n" + b"Host: example.com\r\n\r\n" + ) + assert type(c.next_event()) is Request + assert type(c.next_event()) is EndOfMessage + return c + + for method in [b"GET", b"HEAD"]: + # No Content-Length, HTTP/1.1 peer, should use chunked + c = setup(method, b"1.1") + assert ( + c.send(Response(status_code=200, headers=[])) == b"HTTP/1.1 200 \r\n" # type: ignore[arg-type] + b"Transfer-Encoding: chunked\r\n\r\n" + ) + + # No Content-Length, HTTP/1.0 peer, frame with connection: close + c = setup(method, b"1.0") + assert ( + c.send(Response(status_code=200, headers=[])) == b"HTTP/1.1 200 \r\n" # type: ignore[arg-type] + b"Connection: close\r\n\r\n" + ) + + # Content-Length + Transfer-Encoding, TE wins + c = setup(method, b"1.1") + assert ( + c.send( + Response( + status_code=200, + headers=[ + ("Content-Length", "100"), + ("Transfer-Encoding", "chunked"), + ], + ) + ) + == b"HTTP/1.1 200 \r\n" + b"Transfer-Encoding: chunked\r\n\r\n" + ) + + +def test_special_exceptions_for_lost_connection_in_message_body() -> None: + c = Connection(SERVER) + c.receive_data( + b"POST / HTTP/1.1\r\n" b"Host: example.com\r\n" b"Content-Length: 100\r\n\r\n" + ) + assert type(c.next_event()) is Request + assert c.next_event() is NEED_DATA + c.receive_data(b"12345") + assert c.next_event() == Data(data=b"12345") + c.receive_data(b"") + with pytest.raises(RemoteProtocolError) as excinfo: + c.next_event() + assert "received 5 bytes" in str(excinfo.value) + assert "expected 100" in str(excinfo.value) + + c = Connection(SERVER) + c.receive_data( + b"POST / HTTP/1.1\r\n" + b"Host: example.com\r\n" + b"Transfer-Encoding: chunked\r\n\r\n" + ) + assert type(c.next_event()) is Request + assert c.next_event() is NEED_DATA + c.receive_data(b"8\r\n012345") + assert c.next_event().data == b"012345" # type: ignore + c.receive_data(b"") + with pytest.raises(RemoteProtocolError) as excinfo: + c.next_event() + assert "incomplete chunked read" in str(excinfo.value) diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/h11/tests/test_events.py b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/h11/tests/test_events.py new file mode 100644 index 00000000..bc6c3137 --- /dev/null +++ b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/h11/tests/test_events.py @@ -0,0 +1,150 @@ +from http import HTTPStatus + +import pytest + +from .. import _events +from .._events import ( + ConnectionClosed, + Data, + EndOfMessage, + Event, + InformationalResponse, + Request, + Response, +) +from .._util import LocalProtocolError + + +def test_events() -> None: + with pytest.raises(LocalProtocolError): + # Missing Host: + req = Request( + method="GET", target="/", headers=[("a", "b")], http_version="1.1" + ) + # But this is okay (HTTP/1.0) + req = Request(method="GET", target="/", headers=[("a", "b")], http_version="1.0") + # fields are normalized + assert req.method == b"GET" + assert req.target == b"/" + assert req.headers == [(b"a", b"b")] + assert req.http_version == b"1.0" + + # This is also okay -- has a Host (with weird capitalization, which is ok) + req = Request( + method="GET", + target="/", + headers=[("a", "b"), ("hOSt", "example.com")], + http_version="1.1", + ) + # we normalize header capitalization + assert req.headers == [(b"a", b"b"), (b"host", b"example.com")] + + # Multiple host is bad too + with pytest.raises(LocalProtocolError): + req = Request( + method="GET", + target="/", + headers=[("Host", "a"), ("Host", "a")], + http_version="1.1", + ) + # Even for HTTP/1.0 + with pytest.raises(LocalProtocolError): + req = Request( + method="GET", + target="/", + headers=[("Host", "a"), ("Host", "a")], + http_version="1.0", + ) + + # Header values are validated + for bad_char in "\x00\r\n\f\v": + with pytest.raises(LocalProtocolError): + req = Request( + method="GET", + target="/", + headers=[("Host", "a"), ("Foo", "asd" + bad_char)], + http_version="1.0", + ) + + # But for compatibility we allow non-whitespace control characters, even + # though they're forbidden by the spec. + Request( + method="GET", + target="/", + headers=[("Host", "a"), ("Foo", "asd\x01\x02\x7f")], + http_version="1.0", + ) + + # Request target is validated + for bad_byte in b"\x00\x20\x7f\xee": + target = bytearray(b"/") + target.append(bad_byte) + with pytest.raises(LocalProtocolError): + Request( + method="GET", target=target, headers=[("Host", "a")], http_version="1.1" + ) + + # Request method is validated + with pytest.raises(LocalProtocolError): + Request( + method="GET / HTTP/1.1", + target=target, + headers=[("Host", "a")], + http_version="1.1", + ) + + ir = InformationalResponse(status_code=100, headers=[("Host", "a")]) + assert ir.status_code == 100 + assert ir.headers == [(b"host", b"a")] + assert ir.http_version == b"1.1" + + with pytest.raises(LocalProtocolError): + InformationalResponse(status_code=200, headers=[("Host", "a")]) + + resp = Response(status_code=204, headers=[], http_version="1.0") # type: ignore[arg-type] + assert resp.status_code == 204 + assert resp.headers == [] + assert resp.http_version == b"1.0" + + with pytest.raises(LocalProtocolError): + resp = Response(status_code=100, headers=[], http_version="1.0") # type: ignore[arg-type] + + with pytest.raises(LocalProtocolError): + Response(status_code="100", headers=[], http_version="1.0") # type: ignore[arg-type] + + with pytest.raises(LocalProtocolError): + InformationalResponse(status_code=b"100", headers=[], http_version="1.0") # type: ignore[arg-type] + + d = Data(data=b"asdf") + assert d.data == b"asdf" + + eom = EndOfMessage() + assert eom.headers == [] + + cc = ConnectionClosed() + assert repr(cc) == "ConnectionClosed()" + + +def test_intenum_status_code() -> None: + # https://github.com/python-hyper/h11/issues/72 + + r = Response(status_code=HTTPStatus.OK, headers=[], http_version="1.0") # type: ignore[arg-type] + assert r.status_code == HTTPStatus.OK + assert type(r.status_code) is not type(HTTPStatus.OK) + assert type(r.status_code) is int + + +def test_header_casing() -> None: + r = Request( + method="GET", + target="/", + headers=[("Host", "example.org"), ("Connection", "keep-alive")], + http_version="1.1", + ) + assert len(r.headers) == 2 + assert r.headers[0] == (b"host", b"example.org") + assert r.headers == [(b"host", b"example.org"), (b"connection", b"keep-alive")] + assert r.headers.raw_items() == [ + (b"Host", b"example.org"), + (b"Connection", b"keep-alive"), + ] diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/h11/tests/test_headers.py b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/h11/tests/test_headers.py new file mode 100644 index 00000000..ba53d088 --- /dev/null +++ b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/h11/tests/test_headers.py @@ -0,0 +1,157 @@ +import pytest + +from .._events import Request +from .._headers import ( + get_comma_header, + has_expect_100_continue, + Headers, + normalize_and_validate, + set_comma_header, +) +from .._util import LocalProtocolError + + +def test_normalize_and_validate() -> None: + assert normalize_and_validate([("foo", "bar")]) == [(b"foo", b"bar")] + assert normalize_and_validate([(b"foo", b"bar")]) == [(b"foo", b"bar")] + + # no leading/trailing whitespace in names + with pytest.raises(LocalProtocolError): + normalize_and_validate([(b"foo ", "bar")]) + with pytest.raises(LocalProtocolError): + normalize_and_validate([(b" foo", "bar")]) + + # no weird characters in names + with pytest.raises(LocalProtocolError) as excinfo: + normalize_and_validate([(b"foo bar", b"baz")]) + assert "foo bar" in str(excinfo.value) + with pytest.raises(LocalProtocolError): + normalize_and_validate([(b"foo\x00bar", b"baz")]) + # Not even 8-bit characters: + with pytest.raises(LocalProtocolError): + normalize_and_validate([(b"foo\xffbar", b"baz")]) + # And not even the control characters we allow in values: + with pytest.raises(LocalProtocolError): + normalize_and_validate([(b"foo\x01bar", b"baz")]) + + # no return or NUL characters in values + with pytest.raises(LocalProtocolError) as excinfo: + normalize_and_validate([("foo", "bar\rbaz")]) + assert "bar\\rbaz" in str(excinfo.value) + with pytest.raises(LocalProtocolError): + normalize_and_validate([("foo", "bar\nbaz")]) + with pytest.raises(LocalProtocolError): + normalize_and_validate([("foo", "bar\x00baz")]) + # no leading/trailing whitespace + with pytest.raises(LocalProtocolError): + normalize_and_validate([("foo", "barbaz ")]) + with pytest.raises(LocalProtocolError): + normalize_and_validate([("foo", " barbaz")]) + with pytest.raises(LocalProtocolError): + normalize_and_validate([("foo", "barbaz\t")]) + with pytest.raises(LocalProtocolError): + normalize_and_validate([("foo", "\tbarbaz")]) + + # content-length + assert normalize_and_validate([("Content-Length", "1")]) == [ + (b"content-length", b"1") + ] + with pytest.raises(LocalProtocolError): + normalize_and_validate([("Content-Length", "asdf")]) + with pytest.raises(LocalProtocolError): + normalize_and_validate([("Content-Length", "1x")]) + with pytest.raises(LocalProtocolError): + normalize_and_validate([("Content-Length", "1"), ("Content-Length", "2")]) + assert normalize_and_validate( + [("Content-Length", "0"), ("Content-Length", "0")] + ) == [(b"content-length", b"0")] + assert normalize_and_validate([("Content-Length", "0 , 0")]) == [ + (b"content-length", b"0") + ] + with pytest.raises(LocalProtocolError): + normalize_and_validate( + [("Content-Length", "1"), ("Content-Length", "1"), ("Content-Length", "2")] + ) + with pytest.raises(LocalProtocolError): + normalize_and_validate([("Content-Length", "1 , 1,2")]) + + # transfer-encoding + assert normalize_and_validate([("Transfer-Encoding", "chunked")]) == [ + (b"transfer-encoding", b"chunked") + ] + assert normalize_and_validate([("Transfer-Encoding", "cHuNkEd")]) == [ + (b"transfer-encoding", b"chunked") + ] + with pytest.raises(LocalProtocolError) as excinfo: + normalize_and_validate([("Transfer-Encoding", "gzip")]) + assert excinfo.value.error_status_hint == 501 # Not Implemented + with pytest.raises(LocalProtocolError) as excinfo: + normalize_and_validate( + [("Transfer-Encoding", "chunked"), ("Transfer-Encoding", "gzip")] + ) + assert excinfo.value.error_status_hint == 501 # Not Implemented + + +def test_get_set_comma_header() -> None: + headers = normalize_and_validate( + [ + ("Connection", "close"), + ("whatever", "something"), + ("connectiON", "fOo,, , BAR"), + ] + ) + + assert get_comma_header(headers, b"connection") == [b"close", b"foo", b"bar"] + + headers = set_comma_header(headers, b"newthing", ["a", "b"]) # type: ignore + + with pytest.raises(LocalProtocolError): + set_comma_header(headers, b"newthing", [" a", "b"]) # type: ignore + + assert headers == [ + (b"connection", b"close"), + (b"whatever", b"something"), + (b"connection", b"fOo,, , BAR"), + (b"newthing", b"a"), + (b"newthing", b"b"), + ] + + headers = set_comma_header(headers, b"whatever", ["different thing"]) # type: ignore + + assert headers == [ + (b"connection", b"close"), + (b"connection", b"fOo,, , BAR"), + (b"newthing", b"a"), + (b"newthing", b"b"), + (b"whatever", b"different thing"), + ] + + +def test_has_100_continue() -> None: + assert has_expect_100_continue( + Request( + method="GET", + target="/", + headers=[("Host", "example.com"), ("Expect", "100-continue")], + ) + ) + assert not has_expect_100_continue( + Request(method="GET", target="/", headers=[("Host", "example.com")]) + ) + # Case insensitive + assert has_expect_100_continue( + Request( + method="GET", + target="/", + headers=[("Host", "example.com"), ("Expect", "100-Continue")], + ) + ) + # Doesn't work in HTTP/1.0 + assert not has_expect_100_continue( + Request( + method="GET", + target="/", + headers=[("Host", "example.com"), ("Expect", "100-continue")], + http_version="1.0", + ) + ) diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/h11/tests/test_helpers.py b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/h11/tests/test_helpers.py new file mode 100644 index 00000000..c329c767 --- /dev/null +++ b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/h11/tests/test_helpers.py @@ -0,0 +1,32 @@ +from .._events import ( + ConnectionClosed, + Data, + EndOfMessage, + Event, + InformationalResponse, + Request, + Response, +) +from .helpers import normalize_data_events + + +def test_normalize_data_events() -> None: + assert normalize_data_events( + [ + Data(data=bytearray(b"1")), + Data(data=b"2"), + Response(status_code=200, headers=[]), # type: ignore[arg-type] + Data(data=b"3"), + Data(data=b"4"), + EndOfMessage(), + Data(data=b"5"), + Data(data=b"6"), + Data(data=b"7"), + ] + ) == [ + Data(data=b"12"), + Response(status_code=200, headers=[]), # type: ignore[arg-type] + Data(data=b"34"), + EndOfMessage(), + Data(data=b"567"), + ] diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/h11/tests/test_io.py b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/h11/tests/test_io.py new file mode 100644 index 00000000..e9c01bd5 --- /dev/null +++ b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/h11/tests/test_io.py @@ -0,0 +1,566 @@ +from typing import Any, Callable, Generator, List + +import pytest + +from .._events import ( + ConnectionClosed, + Data, + EndOfMessage, + Event, + InformationalResponse, + Request, + Response, +) +from .._headers import Headers, normalize_and_validate +from .._readers import ( + _obsolete_line_fold, + ChunkedReader, + ContentLengthReader, + Http10Reader, + READERS, +) +from .._receivebuffer import ReceiveBuffer +from .._state import ( + CLIENT, + CLOSED, + DONE, + IDLE, + MIGHT_SWITCH_PROTOCOL, + MUST_CLOSE, + SEND_BODY, + SEND_RESPONSE, + SERVER, + SWITCHED_PROTOCOL, +) +from .._util import LocalProtocolError +from .._writers import ( + ChunkedWriter, + ContentLengthWriter, + Http10Writer, + write_any_response, + write_headers, + write_request, + WRITERS, +) +from .helpers import normalize_data_events + +SIMPLE_CASES = [ + ( + (CLIENT, IDLE), + Request( + method="GET", + target="/a", + headers=[("Host", "foo"), ("Connection", "close")], + ), + b"GET /a HTTP/1.1\r\nHost: foo\r\nConnection: close\r\n\r\n", + ), + ( + (SERVER, SEND_RESPONSE), + Response(status_code=200, headers=[("Connection", "close")], reason=b"OK"), + b"HTTP/1.1 200 OK\r\nConnection: close\r\n\r\n", + ), + ( + (SERVER, SEND_RESPONSE), + Response(status_code=200, headers=[], reason=b"OK"), # type: ignore[arg-type] + b"HTTP/1.1 200 OK\r\n\r\n", + ), + ( + (SERVER, SEND_RESPONSE), + InformationalResponse( + status_code=101, headers=[("Upgrade", "websocket")], reason=b"Upgrade" + ), + b"HTTP/1.1 101 Upgrade\r\nUpgrade: websocket\r\n\r\n", + ), + ( + (SERVER, SEND_RESPONSE), + InformationalResponse(status_code=101, headers=[], reason=b"Upgrade"), # type: ignore[arg-type] + b"HTTP/1.1 101 Upgrade\r\n\r\n", + ), +] + + +def dowrite(writer: Callable[..., None], obj: Any) -> bytes: + got_list: List[bytes] = [] + writer(obj, got_list.append) + return b"".join(got_list) + + +def tw(writer: Any, obj: Any, expected: Any) -> None: + got = dowrite(writer, obj) + assert got == expected + + +def makebuf(data: bytes) -> ReceiveBuffer: + buf = ReceiveBuffer() + buf += data + return buf + + +def tr(reader: Any, data: bytes, expected: Any) -> None: + def check(got: Any) -> None: + assert got == expected + # Headers should always be returned as bytes, not e.g. bytearray + # https://github.com/python-hyper/wsproto/pull/54#issuecomment-377709478 + for name, value in getattr(got, "headers", []): + assert type(name) is bytes + assert type(value) is bytes + + # Simple: consume whole thing + buf = makebuf(data) + check(reader(buf)) + assert not buf + + # Incrementally growing buffer + buf = ReceiveBuffer() + for i in range(len(data)): + assert reader(buf) is None + buf += data[i : i + 1] + check(reader(buf)) + + # Trailing data + buf = makebuf(data) + buf += b"trailing" + check(reader(buf)) + assert bytes(buf) == b"trailing" + + +def test_writers_simple() -> None: + for ((role, state), event, binary) in SIMPLE_CASES: + tw(WRITERS[role, state], event, binary) + + +def test_readers_simple() -> None: + for ((role, state), event, binary) in SIMPLE_CASES: + tr(READERS[role, state], binary, event) + + +def test_writers_unusual() -> None: + # Simple test of the write_headers utility routine + tw( + write_headers, + normalize_and_validate([("foo", "bar"), ("baz", "quux")]), + b"foo: bar\r\nbaz: quux\r\n\r\n", + ) + tw(write_headers, Headers([]), b"\r\n") + + # We understand HTTP/1.0, but we don't speak it + with pytest.raises(LocalProtocolError): + tw( + write_request, + Request( + method="GET", + target="/", + headers=[("Host", "foo"), ("Connection", "close")], + http_version="1.0", + ), + None, + ) + with pytest.raises(LocalProtocolError): + tw( + write_any_response, + Response( + status_code=200, headers=[("Connection", "close")], http_version="1.0" + ), + None, + ) + + +def test_readers_unusual() -> None: + # Reading HTTP/1.0 + tr( + READERS[CLIENT, IDLE], + b"HEAD /foo HTTP/1.0\r\nSome: header\r\n\r\n", + Request( + method="HEAD", + target="/foo", + headers=[("Some", "header")], + http_version="1.0", + ), + ) + + # check no-headers, since it's only legal with HTTP/1.0 + tr( + READERS[CLIENT, IDLE], + b"HEAD /foo HTTP/1.0\r\n\r\n", + Request(method="HEAD", target="/foo", headers=[], http_version="1.0"), # type: ignore[arg-type] + ) + + tr( + READERS[SERVER, SEND_RESPONSE], + b"HTTP/1.0 200 OK\r\nSome: header\r\n\r\n", + Response( + status_code=200, + headers=[("Some", "header")], + http_version="1.0", + reason=b"OK", + ), + ) + + # single-character header values (actually disallowed by the ABNF in RFC + # 7230 -- this is a bug in the standard that we originally copied...) + tr( + READERS[SERVER, SEND_RESPONSE], + b"HTTP/1.0 200 OK\r\n" b"Foo: a a a a a \r\n\r\n", + Response( + status_code=200, + headers=[("Foo", "a a a a a")], + http_version="1.0", + reason=b"OK", + ), + ) + + # Empty headers -- also legal + tr( + READERS[SERVER, SEND_RESPONSE], + b"HTTP/1.0 200 OK\r\n" b"Foo:\r\n\r\n", + Response( + status_code=200, headers=[("Foo", "")], http_version="1.0", reason=b"OK" + ), + ) + + tr( + READERS[SERVER, SEND_RESPONSE], + b"HTTP/1.0 200 OK\r\n" b"Foo: \t \t \r\n\r\n", + Response( + status_code=200, headers=[("Foo", "")], http_version="1.0", reason=b"OK" + ), + ) + + # Tolerate broken servers that leave off the response code + tr( + READERS[SERVER, SEND_RESPONSE], + b"HTTP/1.0 200\r\n" b"Foo: bar\r\n\r\n", + Response( + status_code=200, headers=[("Foo", "bar")], http_version="1.0", reason=b"" + ), + ) + + # Tolerate headers line endings (\r\n and \n) + # \n\r\b between headers and body + tr( + READERS[SERVER, SEND_RESPONSE], + b"HTTP/1.1 200 OK\r\nSomeHeader: val\n\r\n", + Response( + status_code=200, + headers=[("SomeHeader", "val")], + http_version="1.1", + reason="OK", + ), + ) + + # delimited only with \n + tr( + READERS[SERVER, SEND_RESPONSE], + b"HTTP/1.1 200 OK\nSomeHeader1: val1\nSomeHeader2: val2\n\n", + Response( + status_code=200, + headers=[("SomeHeader1", "val1"), ("SomeHeader2", "val2")], + http_version="1.1", + reason="OK", + ), + ) + + # mixed \r\n and \n + tr( + READERS[SERVER, SEND_RESPONSE], + b"HTTP/1.1 200 OK\r\nSomeHeader1: val1\nSomeHeader2: val2\n\r\n", + Response( + status_code=200, + headers=[("SomeHeader1", "val1"), ("SomeHeader2", "val2")], + http_version="1.1", + reason="OK", + ), + ) + + # obsolete line folding + tr( + READERS[CLIENT, IDLE], + b"HEAD /foo HTTP/1.1\r\n" + b"Host: example.com\r\n" + b"Some: multi-line\r\n" + b" header\r\n" + b"\tnonsense\r\n" + b" \t \t\tI guess\r\n" + b"Connection: close\r\n" + b"More-nonsense: in the\r\n" + b" last header \r\n\r\n", + Request( + method="HEAD", + target="/foo", + headers=[ + ("Host", "example.com"), + ("Some", "multi-line header nonsense I guess"), + ("Connection", "close"), + ("More-nonsense", "in the last header"), + ], + ), + ) + + with pytest.raises(LocalProtocolError): + tr( + READERS[CLIENT, IDLE], + b"HEAD /foo HTTP/1.1\r\n" b" folded: line\r\n\r\n", + None, + ) + + with pytest.raises(LocalProtocolError): + tr( + READERS[CLIENT, IDLE], + b"HEAD /foo HTTP/1.1\r\n" b"foo : line\r\n\r\n", + None, + ) + with pytest.raises(LocalProtocolError): + tr( + READERS[CLIENT, IDLE], + b"HEAD /foo HTTP/1.1\r\n" b"foo\t: line\r\n\r\n", + None, + ) + with pytest.raises(LocalProtocolError): + tr( + READERS[CLIENT, IDLE], + b"HEAD /foo HTTP/1.1\r\n" b"foo\t: line\r\n\r\n", + None, + ) + with pytest.raises(LocalProtocolError): + tr(READERS[CLIENT, IDLE], b"HEAD /foo HTTP/1.1\r\n" b": line\r\n\r\n", None) + + +def test__obsolete_line_fold_bytes() -> None: + # _obsolete_line_fold has a defensive cast to bytearray, which is + # necessary to protect against O(n^2) behavior in case anyone ever passes + # in regular bytestrings... but right now we never pass in regular + # bytestrings. so this test just exists to get some coverage on that + # defensive cast. + assert list(_obsolete_line_fold([b"aaa", b"bbb", b" ccc", b"ddd"])) == [ + b"aaa", + bytearray(b"bbb ccc"), + b"ddd", + ] + + +def _run_reader_iter( + reader: Any, buf: bytes, do_eof: bool +) -> Generator[Any, None, None]: + while True: + event = reader(buf) + if event is None: + break + yield event + # body readers have undefined behavior after returning EndOfMessage, + # because this changes the state so they don't get called again + if type(event) is EndOfMessage: + break + if do_eof: + assert not buf + yield reader.read_eof() + + +def _run_reader(*args: Any) -> List[Event]: + events = list(_run_reader_iter(*args)) + return normalize_data_events(events) + + +def t_body_reader(thunk: Any, data: bytes, expected: Any, do_eof: bool = False) -> None: + # Simple: consume whole thing + print("Test 1") + buf = makebuf(data) + assert _run_reader(thunk(), buf, do_eof) == expected + + # Incrementally growing buffer + print("Test 2") + reader = thunk() + buf = ReceiveBuffer() + events = [] + for i in range(len(data)): + events += _run_reader(reader, buf, False) + buf += data[i : i + 1] + events += _run_reader(reader, buf, do_eof) + assert normalize_data_events(events) == expected + + is_complete = any(type(event) is EndOfMessage for event in expected) + if is_complete and not do_eof: + buf = makebuf(data + b"trailing") + assert _run_reader(thunk(), buf, False) == expected + + +def test_ContentLengthReader() -> None: + t_body_reader(lambda: ContentLengthReader(0), b"", [EndOfMessage()]) + + t_body_reader( + lambda: ContentLengthReader(10), + b"0123456789", + [Data(data=b"0123456789"), EndOfMessage()], + ) + + +def test_Http10Reader() -> None: + t_body_reader(Http10Reader, b"", [EndOfMessage()], do_eof=True) + t_body_reader(Http10Reader, b"asdf", [Data(data=b"asdf")], do_eof=False) + t_body_reader( + Http10Reader, b"asdf", [Data(data=b"asdf"), EndOfMessage()], do_eof=True + ) + + +def test_ChunkedReader() -> None: + t_body_reader(ChunkedReader, b"0\r\n\r\n", [EndOfMessage()]) + + t_body_reader( + ChunkedReader, + b"0\r\nSome: header\r\n\r\n", + [EndOfMessage(headers=[("Some", "header")])], + ) + + t_body_reader( + ChunkedReader, + b"5\r\n01234\r\n" + + b"10\r\n0123456789abcdef\r\n" + + b"0\r\n" + + b"Some: header\r\n\r\n", + [ + Data(data=b"012340123456789abcdef"), + EndOfMessage(headers=[("Some", "header")]), + ], + ) + + t_body_reader( + ChunkedReader, + b"5\r\n01234\r\n" + b"10\r\n0123456789abcdef\r\n" + b"0\r\n\r\n", + [Data(data=b"012340123456789abcdef"), EndOfMessage()], + ) + + # handles upper and lowercase hex + t_body_reader( + ChunkedReader, + b"aA\r\n" + b"x" * 0xAA + b"\r\n" + b"0\r\n\r\n", + [Data(data=b"x" * 0xAA), EndOfMessage()], + ) + + # refuses arbitrarily long chunk integers + with pytest.raises(LocalProtocolError): + # Technically this is legal HTTP/1.1, but we refuse to process chunk + # sizes that don't fit into 20 characters of hex + t_body_reader(ChunkedReader, b"9" * 100 + b"\r\nxxx", [Data(data=b"xxx")]) + + # refuses garbage in the chunk count + with pytest.raises(LocalProtocolError): + t_body_reader(ChunkedReader, b"10\x00\r\nxxx", None) + + # handles (and discards) "chunk extensions" omg wtf + t_body_reader( + ChunkedReader, + b"5; hello=there\r\n" + + b"xxxxx" + + b"\r\n" + + b'0; random="junk"; some=more; canbe=lonnnnngg\r\n\r\n', + [Data(data=b"xxxxx"), EndOfMessage()], + ) + + +def test_ContentLengthWriter() -> None: + w = ContentLengthWriter(5) + assert dowrite(w, Data(data=b"123")) == b"123" + assert dowrite(w, Data(data=b"45")) == b"45" + assert dowrite(w, EndOfMessage()) == b"" + + w = ContentLengthWriter(5) + with pytest.raises(LocalProtocolError): + dowrite(w, Data(data=b"123456")) + + w = ContentLengthWriter(5) + dowrite(w, Data(data=b"123")) + with pytest.raises(LocalProtocolError): + dowrite(w, Data(data=b"456")) + + w = ContentLengthWriter(5) + dowrite(w, Data(data=b"123")) + with pytest.raises(LocalProtocolError): + dowrite(w, EndOfMessage()) + + w = ContentLengthWriter(5) + dowrite(w, Data(data=b"123")) == b"123" + dowrite(w, Data(data=b"45")) == b"45" + with pytest.raises(LocalProtocolError): + dowrite(w, EndOfMessage(headers=[("Etag", "asdf")])) + + +def test_ChunkedWriter() -> None: + w = ChunkedWriter() + assert dowrite(w, Data(data=b"aaa")) == b"3\r\naaa\r\n" + assert dowrite(w, Data(data=b"a" * 20)) == b"14\r\n" + b"a" * 20 + b"\r\n" + + assert dowrite(w, Data(data=b"")) == b"" + + assert dowrite(w, EndOfMessage()) == b"0\r\n\r\n" + + assert ( + dowrite(w, EndOfMessage(headers=[("Etag", "asdf"), ("a", "b")])) + == b"0\r\nEtag: asdf\r\na: b\r\n\r\n" + ) + + +def test_Http10Writer() -> None: + w = Http10Writer() + assert dowrite(w, Data(data=b"1234")) == b"1234" + assert dowrite(w, EndOfMessage()) == b"" + + with pytest.raises(LocalProtocolError): + dowrite(w, EndOfMessage(headers=[("Etag", "asdf")])) + + +def test_reject_garbage_after_request_line() -> None: + with pytest.raises(LocalProtocolError): + tr(READERS[SERVER, SEND_RESPONSE], b"HTTP/1.0 200 OK\x00xxxx\r\n\r\n", None) + + +def test_reject_garbage_after_response_line() -> None: + with pytest.raises(LocalProtocolError): + tr( + READERS[CLIENT, IDLE], + b"HEAD /foo HTTP/1.1 xxxxxx\r\n" b"Host: a\r\n\r\n", + None, + ) + + +def test_reject_garbage_in_header_line() -> None: + with pytest.raises(LocalProtocolError): + tr( + READERS[CLIENT, IDLE], + b"HEAD /foo HTTP/1.1\r\n" b"Host: foo\x00bar\r\n\r\n", + None, + ) + + +def test_reject_non_vchar_in_path() -> None: + for bad_char in b"\x00\x20\x7f\xee": + message = bytearray(b"HEAD /") + message.append(bad_char) + message.extend(b" HTTP/1.1\r\nHost: foobar\r\n\r\n") + with pytest.raises(LocalProtocolError): + tr(READERS[CLIENT, IDLE], message, None) + + +# https://github.com/python-hyper/h11/issues/57 +def test_allow_some_garbage_in_cookies() -> None: + tr( + READERS[CLIENT, IDLE], + b"HEAD /foo HTTP/1.1\r\n" + b"Host: foo\r\n" + b"Set-Cookie: ___utmvafIumyLc=kUd\x01UpAt; path=/; Max-Age=900\r\n" + b"\r\n", + Request( + method="HEAD", + target="/foo", + headers=[ + ("Host", "foo"), + ("Set-Cookie", "___utmvafIumyLc=kUd\x01UpAt; path=/; Max-Age=900"), + ], + ), + ) + + +def test_host_comes_first() -> None: + tw( + write_headers, + normalize_and_validate([("foo", "bar"), ("Host", "example.com")]), + b"Host: example.com\r\nfoo: bar\r\n\r\n", + ) diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/h11/tests/test_receivebuffer.py b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/h11/tests/test_receivebuffer.py new file mode 100644 index 00000000..21a3870b --- /dev/null +++ b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/h11/tests/test_receivebuffer.py @@ -0,0 +1,135 @@ +import re +from typing import Tuple + +import pytest + +from .._receivebuffer import ReceiveBuffer + + +def test_receivebuffer() -> None: + b = ReceiveBuffer() + assert not b + assert len(b) == 0 + assert bytes(b) == b"" + + b += b"123" + assert b + assert len(b) == 3 + assert bytes(b) == b"123" + + assert bytes(b) == b"123" + + assert b.maybe_extract_at_most(2) == b"12" + assert b + assert len(b) == 1 + assert bytes(b) == b"3" + + assert bytes(b) == b"3" + + assert b.maybe_extract_at_most(10) == b"3" + assert bytes(b) == b"" + + assert b.maybe_extract_at_most(10) is None + assert not b + + ################################################################ + # maybe_extract_until_next + ################################################################ + + b += b"123\n456\r\n789\r\n" + + assert b.maybe_extract_next_line() == b"123\n456\r\n" + assert bytes(b) == b"789\r\n" + + assert b.maybe_extract_next_line() == b"789\r\n" + assert bytes(b) == b"" + + b += b"12\r" + assert b.maybe_extract_next_line() is None + assert bytes(b) == b"12\r" + + b += b"345\n\r" + assert b.maybe_extract_next_line() is None + assert bytes(b) == b"12\r345\n\r" + + # here we stopped at the middle of b"\r\n" delimiter + + b += b"\n6789aaa123\r\n" + assert b.maybe_extract_next_line() == b"12\r345\n\r\n" + assert b.maybe_extract_next_line() == b"6789aaa123\r\n" + assert b.maybe_extract_next_line() is None + assert bytes(b) == b"" + + ################################################################ + # maybe_extract_lines + ################################################################ + + b += b"123\r\na: b\r\nfoo:bar\r\n\r\ntrailing" + lines = b.maybe_extract_lines() + assert lines == [b"123", b"a: b", b"foo:bar"] + assert bytes(b) == b"trailing" + + assert b.maybe_extract_lines() is None + + b += b"\r\n\r" + assert b.maybe_extract_lines() is None + + assert b.maybe_extract_at_most(100) == b"trailing\r\n\r" + assert not b + + # Empty body case (as happens at the end of chunked encoding if there are + # no trailing headers, e.g.) + b += b"\r\ntrailing" + assert b.maybe_extract_lines() == [] + assert bytes(b) == b"trailing" + + +@pytest.mark.parametrize( + "data", + [ + pytest.param( + ( + b"HTTP/1.1 200 OK\r\n", + b"Content-type: text/plain\r\n", + b"Connection: close\r\n", + b"\r\n", + b"Some body", + ), + id="with_crlf_delimiter", + ), + pytest.param( + ( + b"HTTP/1.1 200 OK\n", + b"Content-type: text/plain\n", + b"Connection: close\n", + b"\n", + b"Some body", + ), + id="with_lf_only_delimiter", + ), + pytest.param( + ( + b"HTTP/1.1 200 OK\n", + b"Content-type: text/plain\r\n", + b"Connection: close\n", + b"\n", + b"Some body", + ), + id="with_mixed_crlf_and_lf", + ), + ], +) +def test_receivebuffer_for_invalid_delimiter(data: Tuple[bytes]) -> None: + b = ReceiveBuffer() + + for line in data: + b += line + + lines = b.maybe_extract_lines() + + assert lines == [ + b"HTTP/1.1 200 OK", + b"Content-type: text/plain", + b"Connection: close", + ] + assert bytes(b) == b"Some body" diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/h11/tests/test_state.py b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/h11/tests/test_state.py new file mode 100644 index 00000000..bc974e63 --- /dev/null +++ b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/h11/tests/test_state.py @@ -0,0 +1,271 @@ +import pytest + +from .._events import ( + ConnectionClosed, + Data, + EndOfMessage, + Event, + InformationalResponse, + Request, + Response, +) +from .._state import ( + _SWITCH_CONNECT, + _SWITCH_UPGRADE, + CLIENT, + CLOSED, + ConnectionState, + DONE, + IDLE, + MIGHT_SWITCH_PROTOCOL, + MUST_CLOSE, + SEND_BODY, + SEND_RESPONSE, + SERVER, + SWITCHED_PROTOCOL, +) +from .._util import LocalProtocolError + + +def test_ConnectionState() -> None: + cs = ConnectionState() + + # Basic event-triggered transitions + + assert cs.states == {CLIENT: IDLE, SERVER: IDLE} + + cs.process_event(CLIENT, Request) + # The SERVER-Request special case: + assert cs.states == {CLIENT: SEND_BODY, SERVER: SEND_RESPONSE} + + # Illegal transitions raise an error and nothing happens + with pytest.raises(LocalProtocolError): + cs.process_event(CLIENT, Request) + assert cs.states == {CLIENT: SEND_BODY, SERVER: SEND_RESPONSE} + + cs.process_event(SERVER, InformationalResponse) + assert cs.states == {CLIENT: SEND_BODY, SERVER: SEND_RESPONSE} + + cs.process_event(SERVER, Response) + assert cs.states == {CLIENT: SEND_BODY, SERVER: SEND_BODY} + + cs.process_event(CLIENT, EndOfMessage) + cs.process_event(SERVER, EndOfMessage) + assert cs.states == {CLIENT: DONE, SERVER: DONE} + + # State-triggered transition + + cs.process_event(SERVER, ConnectionClosed) + assert cs.states == {CLIENT: MUST_CLOSE, SERVER: CLOSED} + + +def test_ConnectionState_keep_alive() -> None: + # keep_alive = False + cs = ConnectionState() + cs.process_event(CLIENT, Request) + cs.process_keep_alive_disabled() + cs.process_event(CLIENT, EndOfMessage) + assert cs.states == {CLIENT: MUST_CLOSE, SERVER: SEND_RESPONSE} + + cs.process_event(SERVER, Response) + cs.process_event(SERVER, EndOfMessage) + assert cs.states == {CLIENT: MUST_CLOSE, SERVER: MUST_CLOSE} + + +def test_ConnectionState_keep_alive_in_DONE() -> None: + # Check that if keep_alive is disabled when the CLIENT is already in DONE, + # then this is sufficient to immediately trigger the DONE -> MUST_CLOSE + # transition + cs = ConnectionState() + cs.process_event(CLIENT, Request) + cs.process_event(CLIENT, EndOfMessage) + assert cs.states[CLIENT] is DONE + cs.process_keep_alive_disabled() + assert cs.states[CLIENT] is MUST_CLOSE + + +def test_ConnectionState_switch_denied() -> None: + for switch_type in (_SWITCH_CONNECT, _SWITCH_UPGRADE): + for deny_early in (True, False): + cs = ConnectionState() + cs.process_client_switch_proposal(switch_type) + cs.process_event(CLIENT, Request) + cs.process_event(CLIENT, Data) + assert cs.states == {CLIENT: SEND_BODY, SERVER: SEND_RESPONSE} + + assert switch_type in cs.pending_switch_proposals + + if deny_early: + # before client reaches DONE + cs.process_event(SERVER, Response) + assert not cs.pending_switch_proposals + + cs.process_event(CLIENT, EndOfMessage) + + if deny_early: + assert cs.states == {CLIENT: DONE, SERVER: SEND_BODY} + else: + assert cs.states == { + CLIENT: MIGHT_SWITCH_PROTOCOL, + SERVER: SEND_RESPONSE, + } + + cs.process_event(SERVER, InformationalResponse) + assert cs.states == { + CLIENT: MIGHT_SWITCH_PROTOCOL, + SERVER: SEND_RESPONSE, + } + + cs.process_event(SERVER, Response) + assert cs.states == {CLIENT: DONE, SERVER: SEND_BODY} + assert not cs.pending_switch_proposals + + +_response_type_for_switch = { + _SWITCH_UPGRADE: InformationalResponse, + _SWITCH_CONNECT: Response, + None: Response, +} + + +def test_ConnectionState_protocol_switch_accepted() -> None: + for switch_event in [_SWITCH_UPGRADE, _SWITCH_CONNECT]: + cs = ConnectionState() + cs.process_client_switch_proposal(switch_event) + cs.process_event(CLIENT, Request) + cs.process_event(CLIENT, Data) + assert cs.states == {CLIENT: SEND_BODY, SERVER: SEND_RESPONSE} + + cs.process_event(CLIENT, EndOfMessage) + assert cs.states == {CLIENT: MIGHT_SWITCH_PROTOCOL, SERVER: SEND_RESPONSE} + + cs.process_event(SERVER, InformationalResponse) + assert cs.states == {CLIENT: MIGHT_SWITCH_PROTOCOL, SERVER: SEND_RESPONSE} + + cs.process_event(SERVER, _response_type_for_switch[switch_event], switch_event) + assert cs.states == {CLIENT: SWITCHED_PROTOCOL, SERVER: SWITCHED_PROTOCOL} + + +def test_ConnectionState_double_protocol_switch() -> None: + # CONNECT + Upgrade is legal! Very silly, but legal. So we support + # it. Because sometimes doing the silly thing is easier than not. + for server_switch in [None, _SWITCH_UPGRADE, _SWITCH_CONNECT]: + cs = ConnectionState() + cs.process_client_switch_proposal(_SWITCH_UPGRADE) + cs.process_client_switch_proposal(_SWITCH_CONNECT) + cs.process_event(CLIENT, Request) + cs.process_event(CLIENT, EndOfMessage) + assert cs.states == {CLIENT: MIGHT_SWITCH_PROTOCOL, SERVER: SEND_RESPONSE} + cs.process_event( + SERVER, _response_type_for_switch[server_switch], server_switch + ) + if server_switch is None: + assert cs.states == {CLIENT: DONE, SERVER: SEND_BODY} + else: + assert cs.states == {CLIENT: SWITCHED_PROTOCOL, SERVER: SWITCHED_PROTOCOL} + + +def test_ConnectionState_inconsistent_protocol_switch() -> None: + for client_switches, server_switch in [ + ([], _SWITCH_CONNECT), + ([], _SWITCH_UPGRADE), + ([_SWITCH_UPGRADE], _SWITCH_CONNECT), + ([_SWITCH_CONNECT], _SWITCH_UPGRADE), + ]: + cs = ConnectionState() + for client_switch in client_switches: # type: ignore[attr-defined] + cs.process_client_switch_proposal(client_switch) + cs.process_event(CLIENT, Request) + with pytest.raises(LocalProtocolError): + cs.process_event(SERVER, Response, server_switch) + + +def test_ConnectionState_keepalive_protocol_switch_interaction() -> None: + # keep_alive=False + pending_switch_proposals + cs = ConnectionState() + cs.process_client_switch_proposal(_SWITCH_UPGRADE) + cs.process_event(CLIENT, Request) + cs.process_keep_alive_disabled() + cs.process_event(CLIENT, Data) + assert cs.states == {CLIENT: SEND_BODY, SERVER: SEND_RESPONSE} + + # the protocol switch "wins" + cs.process_event(CLIENT, EndOfMessage) + assert cs.states == {CLIENT: MIGHT_SWITCH_PROTOCOL, SERVER: SEND_RESPONSE} + + # but when the server denies the request, keep_alive comes back into play + cs.process_event(SERVER, Response) + assert cs.states == {CLIENT: MUST_CLOSE, SERVER: SEND_BODY} + + +def test_ConnectionState_reuse() -> None: + cs = ConnectionState() + + with pytest.raises(LocalProtocolError): + cs.start_next_cycle() + + cs.process_event(CLIENT, Request) + cs.process_event(CLIENT, EndOfMessage) + + with pytest.raises(LocalProtocolError): + cs.start_next_cycle() + + cs.process_event(SERVER, Response) + cs.process_event(SERVER, EndOfMessage) + + cs.start_next_cycle() + assert cs.states == {CLIENT: IDLE, SERVER: IDLE} + + # No keepalive + + cs.process_event(CLIENT, Request) + cs.process_keep_alive_disabled() + cs.process_event(CLIENT, EndOfMessage) + cs.process_event(SERVER, Response) + cs.process_event(SERVER, EndOfMessage) + + with pytest.raises(LocalProtocolError): + cs.start_next_cycle() + + # One side closed + + cs = ConnectionState() + cs.process_event(CLIENT, Request) + cs.process_event(CLIENT, EndOfMessage) + cs.process_event(CLIENT, ConnectionClosed) + cs.process_event(SERVER, Response) + cs.process_event(SERVER, EndOfMessage) + + with pytest.raises(LocalProtocolError): + cs.start_next_cycle() + + # Succesful protocol switch + + cs = ConnectionState() + cs.process_client_switch_proposal(_SWITCH_UPGRADE) + cs.process_event(CLIENT, Request) + cs.process_event(CLIENT, EndOfMessage) + cs.process_event(SERVER, InformationalResponse, _SWITCH_UPGRADE) + + with pytest.raises(LocalProtocolError): + cs.start_next_cycle() + + # Failed protocol switch + + cs = ConnectionState() + cs.process_client_switch_proposal(_SWITCH_UPGRADE) + cs.process_event(CLIENT, Request) + cs.process_event(CLIENT, EndOfMessage) + cs.process_event(SERVER, Response) + cs.process_event(SERVER, EndOfMessage) + + cs.start_next_cycle() + assert cs.states == {CLIENT: IDLE, SERVER: IDLE} + + +def test_server_request_is_illegal() -> None: + # There used to be a bug in how we handled the Request special case that + # made this allowed... + cs = ConnectionState() + with pytest.raises(LocalProtocolError): + cs.process_event(SERVER, Request) diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/h11/tests/test_util.py b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/h11/tests/test_util.py new file mode 100644 index 00000000..1637919b --- /dev/null +++ b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/h11/tests/test_util.py @@ -0,0 +1,112 @@ +import re +import sys +import traceback +from typing import NoReturn + +import pytest + +from .._util import ( + bytesify, + LocalProtocolError, + ProtocolError, + RemoteProtocolError, + Sentinel, + validate, +) + + +def test_ProtocolError() -> None: + with pytest.raises(TypeError): + ProtocolError("abstract base class") + + +def test_LocalProtocolError() -> None: + try: + raise LocalProtocolError("foo") + except LocalProtocolError as e: + assert str(e) == "foo" + assert e.error_status_hint == 400 + + try: + raise LocalProtocolError("foo", error_status_hint=418) + except LocalProtocolError as e: + assert str(e) == "foo" + assert e.error_status_hint == 418 + + def thunk() -> NoReturn: + raise LocalProtocolError("a", error_status_hint=420) + + try: + try: + thunk() + except LocalProtocolError as exc1: + orig_traceback = "".join(traceback.format_tb(sys.exc_info()[2])) + exc1._reraise_as_remote_protocol_error() + except RemoteProtocolError as exc2: + assert type(exc2) is RemoteProtocolError + assert exc2.args == ("a",) + assert exc2.error_status_hint == 420 + new_traceback = "".join(traceback.format_tb(sys.exc_info()[2])) + assert new_traceback.endswith(orig_traceback) + + +def test_validate() -> None: + my_re = re.compile(br"(?P[0-9]+)\.(?P[0-9]+)") + with pytest.raises(LocalProtocolError): + validate(my_re, b"0.") + + groups = validate(my_re, b"0.1") + assert groups == {"group1": b"0", "group2": b"1"} + + # successful partial matches are an error - must match whole string + with pytest.raises(LocalProtocolError): + validate(my_re, b"0.1xx") + with pytest.raises(LocalProtocolError): + validate(my_re, b"0.1\n") + + +def test_validate_formatting() -> None: + my_re = re.compile(br"foo") + + with pytest.raises(LocalProtocolError) as excinfo: + validate(my_re, b"", "oops") + assert "oops" in str(excinfo.value) + + with pytest.raises(LocalProtocolError) as excinfo: + validate(my_re, b"", "oops {}") + assert "oops {}" in str(excinfo.value) + + with pytest.raises(LocalProtocolError) as excinfo: + validate(my_re, b"", "oops {} xx", 10) + assert "oops 10 xx" in str(excinfo.value) + + +def test_make_sentinel() -> None: + class S(Sentinel, metaclass=Sentinel): + pass + + assert repr(S) == "S" + assert S == S + assert type(S).__name__ == "S" + assert S in {S} + assert type(S) is S + + class S2(Sentinel, metaclass=Sentinel): + pass + + assert repr(S2) == "S2" + assert S != S2 + assert S not in {S2} + assert type(S) is not type(S2) + + +def test_bytesify() -> None: + assert bytesify(b"123") == b"123" + assert bytesify(bytearray(b"123")) == b"123" + assert bytesify("123") == b"123" + + with pytest.raises(UnicodeEncodeError): + bytesify("\u1234") + + with pytest.raises(TypeError): + bytesify(10) diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/jinja2/__init__.py b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/jinja2/__init__.py new file mode 100644 index 00000000..e3239267 --- /dev/null +++ b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/jinja2/__init__.py @@ -0,0 +1,37 @@ +"""Jinja is a template engine written in pure Python. It provides a +non-XML syntax that supports inline expressions and an optional +sandboxed environment. +""" +from .bccache import BytecodeCache as BytecodeCache +from .bccache import FileSystemBytecodeCache as FileSystemBytecodeCache +from .bccache import MemcachedBytecodeCache as MemcachedBytecodeCache +from .environment import Environment as Environment +from .environment import Template as Template +from .exceptions import TemplateAssertionError as TemplateAssertionError +from .exceptions import TemplateError as TemplateError +from .exceptions import TemplateNotFound as TemplateNotFound +from .exceptions import TemplateRuntimeError as TemplateRuntimeError +from .exceptions import TemplatesNotFound as TemplatesNotFound +from .exceptions import TemplateSyntaxError as TemplateSyntaxError +from .exceptions import UndefinedError as UndefinedError +from .loaders import BaseLoader as BaseLoader +from .loaders import ChoiceLoader as ChoiceLoader +from .loaders import DictLoader as DictLoader +from .loaders import FileSystemLoader as FileSystemLoader +from .loaders import FunctionLoader as FunctionLoader +from .loaders import ModuleLoader as ModuleLoader +from .loaders import PackageLoader as PackageLoader +from .loaders import PrefixLoader as PrefixLoader +from .runtime import ChainableUndefined as ChainableUndefined +from .runtime import DebugUndefined as DebugUndefined +from .runtime import make_logging_undefined as make_logging_undefined +from .runtime import StrictUndefined as StrictUndefined +from .runtime import Undefined as Undefined +from .utils import clear_caches as clear_caches +from .utils import is_undefined as is_undefined +from .utils import pass_context as pass_context +from .utils import pass_environment as pass_environment +from .utils import pass_eval_context as pass_eval_context +from .utils import select_autoescape as select_autoescape + +__version__ = "3.1.2" diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/jinja2/_identifier.py b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/jinja2/_identifier.py new file mode 100644 index 00000000..928c1503 --- /dev/null +++ b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/jinja2/_identifier.py @@ -0,0 +1,6 @@ +import re + +# generated by scripts/generate_identifier_pattern.py +pattern = re.compile( + r"[\w·̀-ͯ·҃-֑҇-ׇֽֿׁׂׅׄؐ-ًؚ-ٰٟۖ-ۜ۟-۪ۤۧۨ-ܑۭܰ-݊ަ-ް߫-߽߳ࠖ-࠙ࠛ-ࠣࠥ-ࠧࠩ-࡙࠭-࡛࣓-ࣣ࣡-ःऺ-़ा-ॏ॑-ॗॢॣঁ-ঃ়া-ৄেৈো-্ৗৢৣ৾ਁ-ਃ਼ਾ-ੂੇੈੋ-੍ੑੰੱੵઁ-ઃ઼ા-ૅે-ૉો-્ૢૣૺ-૿ଁ-ଃ଼ା-ୄେୈୋ-୍ୖୗୢୣஂா-ூெ-ைொ-்ௗఀ-ఄా-ౄె-ైొ-్ౕౖౢౣಁ-ಃ಼ಾ-ೄೆ-ೈೊ-್ೕೖೢೣഀ-ഃ഻഼ാ-ൄെ-ൈൊ-്ൗൢൣංඃ්ා-ුූෘ-ෟෲෳัิ-ฺ็-๎ັິ-ູົຼ່-ໍ༹༘༙༵༷༾༿ཱ-྄྆྇ྍ-ྗྙ-ྼ࿆ါ-ှၖ-ၙၞ-ၠၢ-ၤၧ-ၭၱ-ၴႂ-ႍႏႚ-ႝ፝-፟ᜒ-᜔ᜲ-᜴ᝒᝓᝲᝳ឴-៓៝᠋-᠍ᢅᢆᢩᤠ-ᤫᤰ-᤻ᨗ-ᨛᩕ-ᩞ᩠-᩿᩼᪰-᪽ᬀ-ᬄ᬴-᭄᭫-᭳ᮀ-ᮂᮡ-ᮭ᯦-᯳ᰤ-᰷᳐-᳔᳒-᳨᳭ᳲ-᳴᳷-᳹᷀-᷹᷻-᷿‿⁀⁔⃐-⃥⃜⃡-⃰℘℮⳯-⵿⳱ⷠ-〪ⷿ-゙゚〯꙯ꙴ-꙽ꚞꚟ꛰꛱ꠂ꠆ꠋꠣ-ꠧꢀꢁꢴ-ꣅ꣠-꣱ꣿꤦ-꤭ꥇ-꥓ꦀ-ꦃ꦳-꧀ꧥꨩ-ꨶꩃꩌꩍꩻ-ꩽꪰꪲ-ꪴꪷꪸꪾ꪿꫁ꫫ-ꫯꫵ꫶ꯣ-ꯪ꯬꯭ﬞ︀-️︠-︯︳︴﹍-﹏_𐇽𐋠𐍶-𐍺𐨁-𐨃𐨅𐨆𐨌-𐨏𐨸-𐨿𐨺𐫦𐫥𐴤-𐽆𐴧-𐽐𑀀-𑀂𑀸-𑁆𑁿-𑂂𑂰-𑂺𑄀-𑄂𑄧-𑄴𑅅𑅆𑅳𑆀-𑆂𑆳-𑇀𑇉-𑇌𑈬-𑈷𑈾𑋟-𑋪𑌀-𑌃𑌻𑌼𑌾-𑍄𑍇𑍈𑍋-𑍍𑍗𑍢𑍣𑍦-𑍬𑍰-𑍴𑐵-𑑆𑑞𑒰-𑓃𑖯-𑖵𑖸-𑗀𑗜𑗝𑘰-𑙀𑚫-𑚷𑜝-𑜫𑠬-𑠺𑨁-𑨊𑨳-𑨹𑨻-𑨾𑩇𑩑-𑩛𑪊-𑪙𑰯-𑰶𑰸-𑰿𑲒-𑲧𑲩-𑲶𑴱-𑴶𑴺𑴼𑴽𑴿-𑵅𑵇𑶊-𑶎𑶐𑶑𑶓-𑶗𑻳-𑻶𖫰-𖫴𖬰-𖬶𖽑-𖽾𖾏-𖾒𛲝𛲞𝅥-𝅩𝅭-𝅲𝅻-𝆂𝆅-𝆋𝆪-𝆭𝉂-𝉄𝨀-𝨶𝨻-𝩬𝩵𝪄𝪛-𝪟𝪡-𝪯𞀀-𞀆𞀈-𞀘𞀛-𞀡𞀣𞀤𞀦-𞣐𞀪-𞣖𞥄-𞥊󠄀-󠇯]+" # noqa: B950 +) diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/jinja2/async_utils.py b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/jinja2/async_utils.py new file mode 100644 index 00000000..1a4f3892 --- /dev/null +++ b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/jinja2/async_utils.py @@ -0,0 +1,84 @@ +import inspect +import typing as t +from functools import WRAPPER_ASSIGNMENTS +from functools import wraps + +from .utils import _PassArg +from .utils import pass_eval_context + +V = t.TypeVar("V") + + +def async_variant(normal_func): # type: ignore + def decorator(async_func): # type: ignore + pass_arg = _PassArg.from_obj(normal_func) + need_eval_context = pass_arg is None + + if pass_arg is _PassArg.environment: + + def is_async(args: t.Any) -> bool: + return t.cast(bool, args[0].is_async) + + else: + + def is_async(args: t.Any) -> bool: + return t.cast(bool, args[0].environment.is_async) + + # Take the doc and annotations from the sync function, but the + # name from the async function. Pallets-Sphinx-Themes + # build_function_directive expects __wrapped__ to point to the + # sync function. + async_func_attrs = ("__module__", "__name__", "__qualname__") + normal_func_attrs = tuple(set(WRAPPER_ASSIGNMENTS).difference(async_func_attrs)) + + @wraps(normal_func, assigned=normal_func_attrs) + @wraps(async_func, assigned=async_func_attrs, updated=()) + def wrapper(*args, **kwargs): # type: ignore + b = is_async(args) + + if need_eval_context: + args = args[1:] + + if b: + return async_func(*args, **kwargs) + + return normal_func(*args, **kwargs) + + if need_eval_context: + wrapper = pass_eval_context(wrapper) + + wrapper.jinja_async_variant = True + return wrapper + + return decorator + + +_common_primitives = {int, float, bool, str, list, dict, tuple, type(None)} + + +async def auto_await(value: t.Union[t.Awaitable["V"], "V"]) -> "V": + # Avoid a costly call to isawaitable + if type(value) in _common_primitives: + return t.cast("V", value) + + if inspect.isawaitable(value): + return await t.cast("t.Awaitable[V]", value) + + return t.cast("V", value) + + +async def auto_aiter( + iterable: "t.Union[t.AsyncIterable[V], t.Iterable[V]]", +) -> "t.AsyncIterator[V]": + if hasattr(iterable, "__aiter__"): + async for item in t.cast("t.AsyncIterable[V]", iterable): + yield item + else: + for item in t.cast("t.Iterable[V]", iterable): + yield item + + +async def auto_to_list( + value: "t.Union[t.AsyncIterable[V], t.Iterable[V]]", +) -> t.List["V"]: + return [x async for x in auto_aiter(value)] diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/jinja2/bccache.py b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/jinja2/bccache.py new file mode 100644 index 00000000..d0ddf56e --- /dev/null +++ b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/jinja2/bccache.py @@ -0,0 +1,406 @@ +"""The optional bytecode cache system. This is useful if you have very +complex template situations and the compilation of all those templates +slows down your application too much. + +Situations where this is useful are often forking web applications that +are initialized on the first request. +""" +import errno +import fnmatch +import marshal +import os +import pickle +import stat +import sys +import tempfile +import typing as t +from hashlib import sha1 +from io import BytesIO +from types import CodeType + +if t.TYPE_CHECKING: + import typing_extensions as te + from .environment import Environment + + class _MemcachedClient(te.Protocol): + def get(self, key: str) -> bytes: + ... + + def set(self, key: str, value: bytes, timeout: t.Optional[int] = None) -> None: + ... + + +bc_version = 5 +# Magic bytes to identify Jinja bytecode cache files. Contains the +# Python major and minor version to avoid loading incompatible bytecode +# if a project upgrades its Python version. +bc_magic = ( + b"j2" + + pickle.dumps(bc_version, 2) + + pickle.dumps((sys.version_info[0] << 24) | sys.version_info[1], 2) +) + + +class Bucket: + """Buckets are used to store the bytecode for one template. It's created + and initialized by the bytecode cache and passed to the loading functions. + + The buckets get an internal checksum from the cache assigned and use this + to automatically reject outdated cache material. Individual bytecode + cache subclasses don't have to care about cache invalidation. + """ + + def __init__(self, environment: "Environment", key: str, checksum: str) -> None: + self.environment = environment + self.key = key + self.checksum = checksum + self.reset() + + def reset(self) -> None: + """Resets the bucket (unloads the bytecode).""" + self.code: t.Optional[CodeType] = None + + def load_bytecode(self, f: t.BinaryIO) -> None: + """Loads bytecode from a file or file like object.""" + # make sure the magic header is correct + magic = f.read(len(bc_magic)) + if magic != bc_magic: + self.reset() + return + # the source code of the file changed, we need to reload + checksum = pickle.load(f) + if self.checksum != checksum: + self.reset() + return + # if marshal_load fails then we need to reload + try: + self.code = marshal.load(f) + except (EOFError, ValueError, TypeError): + self.reset() + return + + def write_bytecode(self, f: t.IO[bytes]) -> None: + """Dump the bytecode into the file or file like object passed.""" + if self.code is None: + raise TypeError("can't write empty bucket") + f.write(bc_magic) + pickle.dump(self.checksum, f, 2) + marshal.dump(self.code, f) + + def bytecode_from_string(self, string: bytes) -> None: + """Load bytecode from bytes.""" + self.load_bytecode(BytesIO(string)) + + def bytecode_to_string(self) -> bytes: + """Return the bytecode as bytes.""" + out = BytesIO() + self.write_bytecode(out) + return out.getvalue() + + +class BytecodeCache: + """To implement your own bytecode cache you have to subclass this class + and override :meth:`load_bytecode` and :meth:`dump_bytecode`. Both of + these methods are passed a :class:`~jinja2.bccache.Bucket`. + + A very basic bytecode cache that saves the bytecode on the file system:: + + from os import path + + class MyCache(BytecodeCache): + + def __init__(self, directory): + self.directory = directory + + def load_bytecode(self, bucket): + filename = path.join(self.directory, bucket.key) + if path.exists(filename): + with open(filename, 'rb') as f: + bucket.load_bytecode(f) + + def dump_bytecode(self, bucket): + filename = path.join(self.directory, bucket.key) + with open(filename, 'wb') as f: + bucket.write_bytecode(f) + + A more advanced version of a filesystem based bytecode cache is part of + Jinja. + """ + + def load_bytecode(self, bucket: Bucket) -> None: + """Subclasses have to override this method to load bytecode into a + bucket. If they are not able to find code in the cache for the + bucket, it must not do anything. + """ + raise NotImplementedError() + + def dump_bytecode(self, bucket: Bucket) -> None: + """Subclasses have to override this method to write the bytecode + from a bucket back to the cache. If it unable to do so it must not + fail silently but raise an exception. + """ + raise NotImplementedError() + + def clear(self) -> None: + """Clears the cache. This method is not used by Jinja but should be + implemented to allow applications to clear the bytecode cache used + by a particular environment. + """ + + def get_cache_key( + self, name: str, filename: t.Optional[t.Union[str]] = None + ) -> str: + """Returns the unique hash key for this template name.""" + hash = sha1(name.encode("utf-8")) + + if filename is not None: + hash.update(f"|{filename}".encode()) + + return hash.hexdigest() + + def get_source_checksum(self, source: str) -> str: + """Returns a checksum for the source.""" + return sha1(source.encode("utf-8")).hexdigest() + + def get_bucket( + self, + environment: "Environment", + name: str, + filename: t.Optional[str], + source: str, + ) -> Bucket: + """Return a cache bucket for the given template. All arguments are + mandatory but filename may be `None`. + """ + key = self.get_cache_key(name, filename) + checksum = self.get_source_checksum(source) + bucket = Bucket(environment, key, checksum) + self.load_bytecode(bucket) + return bucket + + def set_bucket(self, bucket: Bucket) -> None: + """Put the bucket into the cache.""" + self.dump_bytecode(bucket) + + +class FileSystemBytecodeCache(BytecodeCache): + """A bytecode cache that stores bytecode on the filesystem. It accepts + two arguments: The directory where the cache items are stored and a + pattern string that is used to build the filename. + + If no directory is specified a default cache directory is selected. On + Windows the user's temp directory is used, on UNIX systems a directory + is created for the user in the system temp directory. + + The pattern can be used to have multiple separate caches operate on the + same directory. The default pattern is ``'__jinja2_%s.cache'``. ``%s`` + is replaced with the cache key. + + >>> bcc = FileSystemBytecodeCache('/tmp/jinja_cache', '%s.cache') + + This bytecode cache supports clearing of the cache using the clear method. + """ + + def __init__( + self, directory: t.Optional[str] = None, pattern: str = "__jinja2_%s.cache" + ) -> None: + if directory is None: + directory = self._get_default_cache_dir() + self.directory = directory + self.pattern = pattern + + def _get_default_cache_dir(self) -> str: + def _unsafe_dir() -> "te.NoReturn": + raise RuntimeError( + "Cannot determine safe temp directory. You " + "need to explicitly provide one." + ) + + tmpdir = tempfile.gettempdir() + + # On windows the temporary directory is used specific unless + # explicitly forced otherwise. We can just use that. + if os.name == "nt": + return tmpdir + if not hasattr(os, "getuid"): + _unsafe_dir() + + dirname = f"_jinja2-cache-{os.getuid()}" + actual_dir = os.path.join(tmpdir, dirname) + + try: + os.mkdir(actual_dir, stat.S_IRWXU) + except OSError as e: + if e.errno != errno.EEXIST: + raise + try: + os.chmod(actual_dir, stat.S_IRWXU) + actual_dir_stat = os.lstat(actual_dir) + if ( + actual_dir_stat.st_uid != os.getuid() + or not stat.S_ISDIR(actual_dir_stat.st_mode) + or stat.S_IMODE(actual_dir_stat.st_mode) != stat.S_IRWXU + ): + _unsafe_dir() + except OSError as e: + if e.errno != errno.EEXIST: + raise + + actual_dir_stat = os.lstat(actual_dir) + if ( + actual_dir_stat.st_uid != os.getuid() + or not stat.S_ISDIR(actual_dir_stat.st_mode) + or stat.S_IMODE(actual_dir_stat.st_mode) != stat.S_IRWXU + ): + _unsafe_dir() + + return actual_dir + + def _get_cache_filename(self, bucket: Bucket) -> str: + return os.path.join(self.directory, self.pattern % (bucket.key,)) + + def load_bytecode(self, bucket: Bucket) -> None: + filename = self._get_cache_filename(bucket) + + # Don't test for existence before opening the file, since the + # file could disappear after the test before the open. + try: + f = open(filename, "rb") + except (FileNotFoundError, IsADirectoryError, PermissionError): + # PermissionError can occur on Windows when an operation is + # in progress, such as calling clear(). + return + + with f: + bucket.load_bytecode(f) + + def dump_bytecode(self, bucket: Bucket) -> None: + # Write to a temporary file, then rename to the real name after + # writing. This avoids another process reading the file before + # it is fully written. + name = self._get_cache_filename(bucket) + f = tempfile.NamedTemporaryFile( + mode="wb", + dir=os.path.dirname(name), + prefix=os.path.basename(name), + suffix=".tmp", + delete=False, + ) + + def remove_silent() -> None: + try: + os.remove(f.name) + except OSError: + # Another process may have called clear(). On Windows, + # another program may be holding the file open. + pass + + try: + with f: + bucket.write_bytecode(f) + except BaseException: + remove_silent() + raise + + try: + os.replace(f.name, name) + except OSError: + # Another process may have called clear(). On Windows, + # another program may be holding the file open. + remove_silent() + except BaseException: + remove_silent() + raise + + def clear(self) -> None: + # imported lazily here because google app-engine doesn't support + # write access on the file system and the function does not exist + # normally. + from os import remove + + files = fnmatch.filter(os.listdir(self.directory), self.pattern % ("*",)) + for filename in files: + try: + remove(os.path.join(self.directory, filename)) + except OSError: + pass + + +class MemcachedBytecodeCache(BytecodeCache): + """This class implements a bytecode cache that uses a memcache cache for + storing the information. It does not enforce a specific memcache library + (tummy's memcache or cmemcache) but will accept any class that provides + the minimal interface required. + + Libraries compatible with this class: + + - `cachelib `_ + - `python-memcached `_ + + (Unfortunately the django cache interface is not compatible because it + does not support storing binary data, only text. You can however pass + the underlying cache client to the bytecode cache which is available + as `django.core.cache.cache._client`.) + + The minimal interface for the client passed to the constructor is this: + + .. class:: MinimalClientInterface + + .. method:: set(key, value[, timeout]) + + Stores the bytecode in the cache. `value` is a string and + `timeout` the timeout of the key. If timeout is not provided + a default timeout or no timeout should be assumed, if it's + provided it's an integer with the number of seconds the cache + item should exist. + + .. method:: get(key) + + Returns the value for the cache key. If the item does not + exist in the cache the return value must be `None`. + + The other arguments to the constructor are the prefix for all keys that + is added before the actual cache key and the timeout for the bytecode in + the cache system. We recommend a high (or no) timeout. + + This bytecode cache does not support clearing of used items in the cache. + The clear method is a no-operation function. + + .. versionadded:: 2.7 + Added support for ignoring memcache errors through the + `ignore_memcache_errors` parameter. + """ + + def __init__( + self, + client: "_MemcachedClient", + prefix: str = "jinja2/bytecode/", + timeout: t.Optional[int] = None, + ignore_memcache_errors: bool = True, + ): + self.client = client + self.prefix = prefix + self.timeout = timeout + self.ignore_memcache_errors = ignore_memcache_errors + + def load_bytecode(self, bucket: Bucket) -> None: + try: + code = self.client.get(self.prefix + bucket.key) + except Exception: + if not self.ignore_memcache_errors: + raise + else: + bucket.bytecode_from_string(code) + + def dump_bytecode(self, bucket: Bucket) -> None: + key = self.prefix + bucket.key + value = bucket.bytecode_to_string() + + try: + if self.timeout is not None: + self.client.set(key, value, self.timeout) + else: + self.client.set(key, value) + except Exception: + if not self.ignore_memcache_errors: + raise diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/jinja2/compiler.py b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/jinja2/compiler.py new file mode 100644 index 00000000..3458095f --- /dev/null +++ b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/jinja2/compiler.py @@ -0,0 +1,1957 @@ +"""Compiles nodes from the parser into Python code.""" +import typing as t +from contextlib import contextmanager +from functools import update_wrapper +from io import StringIO +from itertools import chain +from keyword import iskeyword as is_python_keyword + +from markupsafe import escape +from markupsafe import Markup + +from . import nodes +from .exceptions import TemplateAssertionError +from .idtracking import Symbols +from .idtracking import VAR_LOAD_ALIAS +from .idtracking import VAR_LOAD_PARAMETER +from .idtracking import VAR_LOAD_RESOLVE +from .idtracking import VAR_LOAD_UNDEFINED +from .nodes import EvalContext +from .optimizer import Optimizer +from .utils import _PassArg +from .utils import concat +from .visitor import NodeVisitor + +if t.TYPE_CHECKING: + import typing_extensions as te + from .environment import Environment + +F = t.TypeVar("F", bound=t.Callable[..., t.Any]) + +operators = { + "eq": "==", + "ne": "!=", + "gt": ">", + "gteq": ">=", + "lt": "<", + "lteq": "<=", + "in": "in", + "notin": "not in", +} + + +def optimizeconst(f: F) -> F: + def new_func( + self: "CodeGenerator", node: nodes.Expr, frame: "Frame", **kwargs: t.Any + ) -> t.Any: + # Only optimize if the frame is not volatile + if self.optimizer is not None and not frame.eval_ctx.volatile: + new_node = self.optimizer.visit(node, frame.eval_ctx) + + if new_node != node: + return self.visit(new_node, frame) + + return f(self, node, frame, **kwargs) + + return update_wrapper(t.cast(F, new_func), f) + + +def _make_binop(op: str) -> t.Callable[["CodeGenerator", nodes.BinExpr, "Frame"], None]: + @optimizeconst + def visitor(self: "CodeGenerator", node: nodes.BinExpr, frame: Frame) -> None: + if ( + self.environment.sandboxed + and op in self.environment.intercepted_binops # type: ignore + ): + self.write(f"environment.call_binop(context, {op!r}, ") + self.visit(node.left, frame) + self.write(", ") + self.visit(node.right, frame) + else: + self.write("(") + self.visit(node.left, frame) + self.write(f" {op} ") + self.visit(node.right, frame) + + self.write(")") + + return visitor + + +def _make_unop( + op: str, +) -> t.Callable[["CodeGenerator", nodes.UnaryExpr, "Frame"], None]: + @optimizeconst + def visitor(self: "CodeGenerator", node: nodes.UnaryExpr, frame: Frame) -> None: + if ( + self.environment.sandboxed + and op in self.environment.intercepted_unops # type: ignore + ): + self.write(f"environment.call_unop(context, {op!r}, ") + self.visit(node.node, frame) + else: + self.write("(" + op) + self.visit(node.node, frame) + + self.write(")") + + return visitor + + +def generate( + node: nodes.Template, + environment: "Environment", + name: t.Optional[str], + filename: t.Optional[str], + stream: t.Optional[t.TextIO] = None, + defer_init: bool = False, + optimized: bool = True, +) -> t.Optional[str]: + """Generate the python source for a node tree.""" + if not isinstance(node, nodes.Template): + raise TypeError("Can't compile non template nodes") + + generator = environment.code_generator_class( + environment, name, filename, stream, defer_init, optimized + ) + generator.visit(node) + + if stream is None: + return generator.stream.getvalue() # type: ignore + + return None + + +def has_safe_repr(value: t.Any) -> bool: + """Does the node have a safe representation?""" + if value is None or value is NotImplemented or value is Ellipsis: + return True + + if type(value) in {bool, int, float, complex, range, str, Markup}: + return True + + if type(value) in {tuple, list, set, frozenset}: + return all(has_safe_repr(v) for v in value) + + if type(value) is dict: + return all(has_safe_repr(k) and has_safe_repr(v) for k, v in value.items()) + + return False + + +def find_undeclared( + nodes: t.Iterable[nodes.Node], names: t.Iterable[str] +) -> t.Set[str]: + """Check if the names passed are accessed undeclared. The return value + is a set of all the undeclared names from the sequence of names found. + """ + visitor = UndeclaredNameVisitor(names) + try: + for node in nodes: + visitor.visit(node) + except VisitorExit: + pass + return visitor.undeclared + + +class MacroRef: + def __init__(self, node: t.Union[nodes.Macro, nodes.CallBlock]) -> None: + self.node = node + self.accesses_caller = False + self.accesses_kwargs = False + self.accesses_varargs = False + + +class Frame: + """Holds compile time information for us.""" + + def __init__( + self, + eval_ctx: EvalContext, + parent: t.Optional["Frame"] = None, + level: t.Optional[int] = None, + ) -> None: + self.eval_ctx = eval_ctx + + # the parent of this frame + self.parent = parent + + if parent is None: + self.symbols = Symbols(level=level) + + # in some dynamic inheritance situations the compiler needs to add + # write tests around output statements. + self.require_output_check = False + + # inside some tags we are using a buffer rather than yield statements. + # this for example affects {% filter %} or {% macro %}. If a frame + # is buffered this variable points to the name of the list used as + # buffer. + self.buffer: t.Optional[str] = None + + # the name of the block we're in, otherwise None. + self.block: t.Optional[str] = None + + else: + self.symbols = Symbols(parent.symbols, level=level) + self.require_output_check = parent.require_output_check + self.buffer = parent.buffer + self.block = parent.block + + # a toplevel frame is the root + soft frames such as if conditions. + self.toplevel = False + + # the root frame is basically just the outermost frame, so no if + # conditions. This information is used to optimize inheritance + # situations. + self.rootlevel = False + + # variables set inside of loops and blocks should not affect outer frames, + # but they still needs to be kept track of as part of the active context. + self.loop_frame = False + self.block_frame = False + + # track whether the frame is being used in an if-statement or conditional + # expression as it determines which errors should be raised during runtime + # or compile time. + self.soft_frame = False + + def copy(self) -> "Frame": + """Create a copy of the current one.""" + rv = object.__new__(self.__class__) + rv.__dict__.update(self.__dict__) + rv.symbols = self.symbols.copy() + return rv + + def inner(self, isolated: bool = False) -> "Frame": + """Return an inner frame.""" + if isolated: + return Frame(self.eval_ctx, level=self.symbols.level + 1) + return Frame(self.eval_ctx, self) + + def soft(self) -> "Frame": + """Return a soft frame. A soft frame may not be modified as + standalone thing as it shares the resources with the frame it + was created of, but it's not a rootlevel frame any longer. + + This is only used to implement if-statements and conditional + expressions. + """ + rv = self.copy() + rv.rootlevel = False + rv.soft_frame = True + return rv + + __copy__ = copy + + +class VisitorExit(RuntimeError): + """Exception used by the `UndeclaredNameVisitor` to signal a stop.""" + + +class DependencyFinderVisitor(NodeVisitor): + """A visitor that collects filter and test calls.""" + + def __init__(self) -> None: + self.filters: t.Set[str] = set() + self.tests: t.Set[str] = set() + + def visit_Filter(self, node: nodes.Filter) -> None: + self.generic_visit(node) + self.filters.add(node.name) + + def visit_Test(self, node: nodes.Test) -> None: + self.generic_visit(node) + self.tests.add(node.name) + + def visit_Block(self, node: nodes.Block) -> None: + """Stop visiting at blocks.""" + + +class UndeclaredNameVisitor(NodeVisitor): + """A visitor that checks if a name is accessed without being + declared. This is different from the frame visitor as it will + not stop at closure frames. + """ + + def __init__(self, names: t.Iterable[str]) -> None: + self.names = set(names) + self.undeclared: t.Set[str] = set() + + def visit_Name(self, node: nodes.Name) -> None: + if node.ctx == "load" and node.name in self.names: + self.undeclared.add(node.name) + if self.undeclared == self.names: + raise VisitorExit() + else: + self.names.discard(node.name) + + def visit_Block(self, node: nodes.Block) -> None: + """Stop visiting a blocks.""" + + +class CompilerExit(Exception): + """Raised if the compiler encountered a situation where it just + doesn't make sense to further process the code. Any block that + raises such an exception is not further processed. + """ + + +class CodeGenerator(NodeVisitor): + def __init__( + self, + environment: "Environment", + name: t.Optional[str], + filename: t.Optional[str], + stream: t.Optional[t.TextIO] = None, + defer_init: bool = False, + optimized: bool = True, + ) -> None: + if stream is None: + stream = StringIO() + self.environment = environment + self.name = name + self.filename = filename + self.stream = stream + self.created_block_context = False + self.defer_init = defer_init + self.optimizer: t.Optional[Optimizer] = None + + if optimized: + self.optimizer = Optimizer(environment) + + # aliases for imports + self.import_aliases: t.Dict[str, str] = {} + + # a registry for all blocks. Because blocks are moved out + # into the global python scope they are registered here + self.blocks: t.Dict[str, nodes.Block] = {} + + # the number of extends statements so far + self.extends_so_far = 0 + + # some templates have a rootlevel extends. In this case we + # can safely assume that we're a child template and do some + # more optimizations. + self.has_known_extends = False + + # the current line number + self.code_lineno = 1 + + # registry of all filters and tests (global, not block local) + self.tests: t.Dict[str, str] = {} + self.filters: t.Dict[str, str] = {} + + # the debug information + self.debug_info: t.List[t.Tuple[int, int]] = [] + self._write_debug_info: t.Optional[int] = None + + # the number of new lines before the next write() + self._new_lines = 0 + + # the line number of the last written statement + self._last_line = 0 + + # true if nothing was written so far. + self._first_write = True + + # used by the `temporary_identifier` method to get new + # unique, temporary identifier + self._last_identifier = 0 + + # the current indentation + self._indentation = 0 + + # Tracks toplevel assignments + self._assign_stack: t.List[t.Set[str]] = [] + + # Tracks parameter definition blocks + self._param_def_block: t.List[t.Set[str]] = [] + + # Tracks the current context. + self._context_reference_stack = ["context"] + + @property + def optimized(self) -> bool: + return self.optimizer is not None + + # -- Various compilation helpers + + def fail(self, msg: str, lineno: int) -> "te.NoReturn": + """Fail with a :exc:`TemplateAssertionError`.""" + raise TemplateAssertionError(msg, lineno, self.name, self.filename) + + def temporary_identifier(self) -> str: + """Get a new unique identifier.""" + self._last_identifier += 1 + return f"t_{self._last_identifier}" + + def buffer(self, frame: Frame) -> None: + """Enable buffering for the frame from that point onwards.""" + frame.buffer = self.temporary_identifier() + self.writeline(f"{frame.buffer} = []") + + def return_buffer_contents( + self, frame: Frame, force_unescaped: bool = False + ) -> None: + """Return the buffer contents of the frame.""" + if not force_unescaped: + if frame.eval_ctx.volatile: + self.writeline("if context.eval_ctx.autoescape:") + self.indent() + self.writeline(f"return Markup(concat({frame.buffer}))") + self.outdent() + self.writeline("else:") + self.indent() + self.writeline(f"return concat({frame.buffer})") + self.outdent() + return + elif frame.eval_ctx.autoescape: + self.writeline(f"return Markup(concat({frame.buffer}))") + return + self.writeline(f"return concat({frame.buffer})") + + def indent(self) -> None: + """Indent by one.""" + self._indentation += 1 + + def outdent(self, step: int = 1) -> None: + """Outdent by step.""" + self._indentation -= step + + def start_write(self, frame: Frame, node: t.Optional[nodes.Node] = None) -> None: + """Yield or write into the frame buffer.""" + if frame.buffer is None: + self.writeline("yield ", node) + else: + self.writeline(f"{frame.buffer}.append(", node) + + def end_write(self, frame: Frame) -> None: + """End the writing process started by `start_write`.""" + if frame.buffer is not None: + self.write(")") + + def simple_write( + self, s: str, frame: Frame, node: t.Optional[nodes.Node] = None + ) -> None: + """Simple shortcut for start_write + write + end_write.""" + self.start_write(frame, node) + self.write(s) + self.end_write(frame) + + def blockvisit(self, nodes: t.Iterable[nodes.Node], frame: Frame) -> None: + """Visit a list of nodes as block in a frame. If the current frame + is no buffer a dummy ``if 0: yield None`` is written automatically. + """ + try: + self.writeline("pass") + for node in nodes: + self.visit(node, frame) + except CompilerExit: + pass + + def write(self, x: str) -> None: + """Write a string into the output stream.""" + if self._new_lines: + if not self._first_write: + self.stream.write("\n" * self._new_lines) + self.code_lineno += self._new_lines + if self._write_debug_info is not None: + self.debug_info.append((self._write_debug_info, self.code_lineno)) + self._write_debug_info = None + self._first_write = False + self.stream.write(" " * self._indentation) + self._new_lines = 0 + self.stream.write(x) + + def writeline( + self, x: str, node: t.Optional[nodes.Node] = None, extra: int = 0 + ) -> None: + """Combination of newline and write.""" + self.newline(node, extra) + self.write(x) + + def newline(self, node: t.Optional[nodes.Node] = None, extra: int = 0) -> None: + """Add one or more newlines before the next write.""" + self._new_lines = max(self._new_lines, 1 + extra) + if node is not None and node.lineno != self._last_line: + self._write_debug_info = node.lineno + self._last_line = node.lineno + + def signature( + self, + node: t.Union[nodes.Call, nodes.Filter, nodes.Test], + frame: Frame, + extra_kwargs: t.Optional[t.Mapping[str, t.Any]] = None, + ) -> None: + """Writes a function call to the stream for the current node. + A leading comma is added automatically. The extra keyword + arguments may not include python keywords otherwise a syntax + error could occur. The extra keyword arguments should be given + as python dict. + """ + # if any of the given keyword arguments is a python keyword + # we have to make sure that no invalid call is created. + kwarg_workaround = any( + is_python_keyword(t.cast(str, k)) + for k in chain((x.key for x in node.kwargs), extra_kwargs or ()) + ) + + for arg in node.args: + self.write(", ") + self.visit(arg, frame) + + if not kwarg_workaround: + for kwarg in node.kwargs: + self.write(", ") + self.visit(kwarg, frame) + if extra_kwargs is not None: + for key, value in extra_kwargs.items(): + self.write(f", {key}={value}") + if node.dyn_args: + self.write(", *") + self.visit(node.dyn_args, frame) + + if kwarg_workaround: + if node.dyn_kwargs is not None: + self.write(", **dict({") + else: + self.write(", **{") + for kwarg in node.kwargs: + self.write(f"{kwarg.key!r}: ") + self.visit(kwarg.value, frame) + self.write(", ") + if extra_kwargs is not None: + for key, value in extra_kwargs.items(): + self.write(f"{key!r}: {value}, ") + if node.dyn_kwargs is not None: + self.write("}, **") + self.visit(node.dyn_kwargs, frame) + self.write(")") + else: + self.write("}") + + elif node.dyn_kwargs is not None: + self.write(", **") + self.visit(node.dyn_kwargs, frame) + + def pull_dependencies(self, nodes: t.Iterable[nodes.Node]) -> None: + """Find all filter and test names used in the template and + assign them to variables in the compiled namespace. Checking + that the names are registered with the environment is done when + compiling the Filter and Test nodes. If the node is in an If or + CondExpr node, the check is done at runtime instead. + + .. versionchanged:: 3.0 + Filters and tests in If and CondExpr nodes are checked at + runtime instead of compile time. + """ + visitor = DependencyFinderVisitor() + + for node in nodes: + visitor.visit(node) + + for id_map, names, dependency in (self.filters, visitor.filters, "filters"), ( + self.tests, + visitor.tests, + "tests", + ): + for name in sorted(names): + if name not in id_map: + id_map[name] = self.temporary_identifier() + + # add check during runtime that dependencies used inside of executed + # blocks are defined, as this step may be skipped during compile time + self.writeline("try:") + self.indent() + self.writeline(f"{id_map[name]} = environment.{dependency}[{name!r}]") + self.outdent() + self.writeline("except KeyError:") + self.indent() + self.writeline("@internalcode") + self.writeline(f"def {id_map[name]}(*unused):") + self.indent() + self.writeline( + f'raise TemplateRuntimeError("No {dependency[:-1]}' + f' named {name!r} found.")' + ) + self.outdent() + self.outdent() + + def enter_frame(self, frame: Frame) -> None: + undefs = [] + for target, (action, param) in frame.symbols.loads.items(): + if action == VAR_LOAD_PARAMETER: + pass + elif action == VAR_LOAD_RESOLVE: + self.writeline(f"{target} = {self.get_resolve_func()}({param!r})") + elif action == VAR_LOAD_ALIAS: + self.writeline(f"{target} = {param}") + elif action == VAR_LOAD_UNDEFINED: + undefs.append(target) + else: + raise NotImplementedError("unknown load instruction") + if undefs: + self.writeline(f"{' = '.join(undefs)} = missing") + + def leave_frame(self, frame: Frame, with_python_scope: bool = False) -> None: + if not with_python_scope: + undefs = [] + for target in frame.symbols.loads: + undefs.append(target) + if undefs: + self.writeline(f"{' = '.join(undefs)} = missing") + + def choose_async(self, async_value: str = "async ", sync_value: str = "") -> str: + return async_value if self.environment.is_async else sync_value + + def func(self, name: str) -> str: + return f"{self.choose_async()}def {name}" + + def macro_body( + self, node: t.Union[nodes.Macro, nodes.CallBlock], frame: Frame + ) -> t.Tuple[Frame, MacroRef]: + """Dump the function def of a macro or call block.""" + frame = frame.inner() + frame.symbols.analyze_node(node) + macro_ref = MacroRef(node) + + explicit_caller = None + skip_special_params = set() + args = [] + + for idx, arg in enumerate(node.args): + if arg.name == "caller": + explicit_caller = idx + if arg.name in ("kwargs", "varargs"): + skip_special_params.add(arg.name) + args.append(frame.symbols.ref(arg.name)) + + undeclared = find_undeclared(node.body, ("caller", "kwargs", "varargs")) + + if "caller" in undeclared: + # In older Jinja versions there was a bug that allowed caller + # to retain the special behavior even if it was mentioned in + # the argument list. However thankfully this was only really + # working if it was the last argument. So we are explicitly + # checking this now and error out if it is anywhere else in + # the argument list. + if explicit_caller is not None: + try: + node.defaults[explicit_caller - len(node.args)] + except IndexError: + self.fail( + "When defining macros or call blocks the " + 'special "caller" argument must be omitted ' + "or be given a default.", + node.lineno, + ) + else: + args.append(frame.symbols.declare_parameter("caller")) + macro_ref.accesses_caller = True + if "kwargs" in undeclared and "kwargs" not in skip_special_params: + args.append(frame.symbols.declare_parameter("kwargs")) + macro_ref.accesses_kwargs = True + if "varargs" in undeclared and "varargs" not in skip_special_params: + args.append(frame.symbols.declare_parameter("varargs")) + macro_ref.accesses_varargs = True + + # macros are delayed, they never require output checks + frame.require_output_check = False + frame.symbols.analyze_node(node) + self.writeline(f"{self.func('macro')}({', '.join(args)}):", node) + self.indent() + + self.buffer(frame) + self.enter_frame(frame) + + self.push_parameter_definitions(frame) + for idx, arg in enumerate(node.args): + ref = frame.symbols.ref(arg.name) + self.writeline(f"if {ref} is missing:") + self.indent() + try: + default = node.defaults[idx - len(node.args)] + except IndexError: + self.writeline( + f'{ref} = undefined("parameter {arg.name!r} was not provided",' + f" name={arg.name!r})" + ) + else: + self.writeline(f"{ref} = ") + self.visit(default, frame) + self.mark_parameter_stored(ref) + self.outdent() + self.pop_parameter_definitions() + + self.blockvisit(node.body, frame) + self.return_buffer_contents(frame, force_unescaped=True) + self.leave_frame(frame, with_python_scope=True) + self.outdent() + + return frame, macro_ref + + def macro_def(self, macro_ref: MacroRef, frame: Frame) -> None: + """Dump the macro definition for the def created by macro_body.""" + arg_tuple = ", ".join(repr(x.name) for x in macro_ref.node.args) + name = getattr(macro_ref.node, "name", None) + if len(macro_ref.node.args) == 1: + arg_tuple += "," + self.write( + f"Macro(environment, macro, {name!r}, ({arg_tuple})," + f" {macro_ref.accesses_kwargs!r}, {macro_ref.accesses_varargs!r}," + f" {macro_ref.accesses_caller!r}, context.eval_ctx.autoescape)" + ) + + def position(self, node: nodes.Node) -> str: + """Return a human readable position for the node.""" + rv = f"line {node.lineno}" + if self.name is not None: + rv = f"{rv} in {self.name!r}" + return rv + + def dump_local_context(self, frame: Frame) -> str: + items_kv = ", ".join( + f"{name!r}: {target}" + for name, target in frame.symbols.dump_stores().items() + ) + return f"{{{items_kv}}}" + + def write_commons(self) -> None: + """Writes a common preamble that is used by root and block functions. + Primarily this sets up common local helpers and enforces a generator + through a dead branch. + """ + self.writeline("resolve = context.resolve_or_missing") + self.writeline("undefined = environment.undefined") + self.writeline("concat = environment.concat") + # always use the standard Undefined class for the implicit else of + # conditional expressions + self.writeline("cond_expr_undefined = Undefined") + self.writeline("if 0: yield None") + + def push_parameter_definitions(self, frame: Frame) -> None: + """Pushes all parameter targets from the given frame into a local + stack that permits tracking of yet to be assigned parameters. In + particular this enables the optimization from `visit_Name` to skip + undefined expressions for parameters in macros as macros can reference + otherwise unbound parameters. + """ + self._param_def_block.append(frame.symbols.dump_param_targets()) + + def pop_parameter_definitions(self) -> None: + """Pops the current parameter definitions set.""" + self._param_def_block.pop() + + def mark_parameter_stored(self, target: str) -> None: + """Marks a parameter in the current parameter definitions as stored. + This will skip the enforced undefined checks. + """ + if self._param_def_block: + self._param_def_block[-1].discard(target) + + def push_context_reference(self, target: str) -> None: + self._context_reference_stack.append(target) + + def pop_context_reference(self) -> None: + self._context_reference_stack.pop() + + def get_context_ref(self) -> str: + return self._context_reference_stack[-1] + + def get_resolve_func(self) -> str: + target = self._context_reference_stack[-1] + if target == "context": + return "resolve" + return f"{target}.resolve" + + def derive_context(self, frame: Frame) -> str: + return f"{self.get_context_ref()}.derived({self.dump_local_context(frame)})" + + def parameter_is_undeclared(self, target: str) -> bool: + """Checks if a given target is an undeclared parameter.""" + if not self._param_def_block: + return False + return target in self._param_def_block[-1] + + def push_assign_tracking(self) -> None: + """Pushes a new layer for assignment tracking.""" + self._assign_stack.append(set()) + + def pop_assign_tracking(self, frame: Frame) -> None: + """Pops the topmost level for assignment tracking and updates the + context variables if necessary. + """ + vars = self._assign_stack.pop() + if ( + not frame.block_frame + and not frame.loop_frame + and not frame.toplevel + or not vars + ): + return + public_names = [x for x in vars if x[:1] != "_"] + if len(vars) == 1: + name = next(iter(vars)) + ref = frame.symbols.ref(name) + if frame.loop_frame: + self.writeline(f"_loop_vars[{name!r}] = {ref}") + return + if frame.block_frame: + self.writeline(f"_block_vars[{name!r}] = {ref}") + return + self.writeline(f"context.vars[{name!r}] = {ref}") + else: + if frame.loop_frame: + self.writeline("_loop_vars.update({") + elif frame.block_frame: + self.writeline("_block_vars.update({") + else: + self.writeline("context.vars.update({") + for idx, name in enumerate(vars): + if idx: + self.write(", ") + ref = frame.symbols.ref(name) + self.write(f"{name!r}: {ref}") + self.write("})") + if not frame.block_frame and not frame.loop_frame and public_names: + if len(public_names) == 1: + self.writeline(f"context.exported_vars.add({public_names[0]!r})") + else: + names_str = ", ".join(map(repr, public_names)) + self.writeline(f"context.exported_vars.update(({names_str}))") + + # -- Statement Visitors + + def visit_Template( + self, node: nodes.Template, frame: t.Optional[Frame] = None + ) -> None: + assert frame is None, "no root frame allowed" + eval_ctx = EvalContext(self.environment, self.name) + + from .runtime import exported, async_exported + + if self.environment.is_async: + exported_names = sorted(exported + async_exported) + else: + exported_names = sorted(exported) + + self.writeline("from jinja2.runtime import " + ", ".join(exported_names)) + + # if we want a deferred initialization we cannot move the + # environment into a local name + envenv = "" if self.defer_init else ", environment=environment" + + # do we have an extends tag at all? If not, we can save some + # overhead by just not processing any inheritance code. + have_extends = node.find(nodes.Extends) is not None + + # find all blocks + for block in node.find_all(nodes.Block): + if block.name in self.blocks: + self.fail(f"block {block.name!r} defined twice", block.lineno) + self.blocks[block.name] = block + + # find all imports and import them + for import_ in node.find_all(nodes.ImportedName): + if import_.importname not in self.import_aliases: + imp = import_.importname + self.import_aliases[imp] = alias = self.temporary_identifier() + if "." in imp: + module, obj = imp.rsplit(".", 1) + self.writeline(f"from {module} import {obj} as {alias}") + else: + self.writeline(f"import {imp} as {alias}") + + # add the load name + self.writeline(f"name = {self.name!r}") + + # generate the root render function. + self.writeline( + f"{self.func('root')}(context, missing=missing{envenv}):", extra=1 + ) + self.indent() + self.write_commons() + + # process the root + frame = Frame(eval_ctx) + if "self" in find_undeclared(node.body, ("self",)): + ref = frame.symbols.declare_parameter("self") + self.writeline(f"{ref} = TemplateReference(context)") + frame.symbols.analyze_node(node) + frame.toplevel = frame.rootlevel = True + frame.require_output_check = have_extends and not self.has_known_extends + if have_extends: + self.writeline("parent_template = None") + self.enter_frame(frame) + self.pull_dependencies(node.body) + self.blockvisit(node.body, frame) + self.leave_frame(frame, with_python_scope=True) + self.outdent() + + # make sure that the parent root is called. + if have_extends: + if not self.has_known_extends: + self.indent() + self.writeline("if parent_template is not None:") + self.indent() + if not self.environment.is_async: + self.writeline("yield from parent_template.root_render_func(context)") + else: + self.writeline( + "async for event in parent_template.root_render_func(context):" + ) + self.indent() + self.writeline("yield event") + self.outdent() + self.outdent(1 + (not self.has_known_extends)) + + # at this point we now have the blocks collected and can visit them too. + for name, block in self.blocks.items(): + self.writeline( + f"{self.func('block_' + name)}(context, missing=missing{envenv}):", + block, + 1, + ) + self.indent() + self.write_commons() + # It's important that we do not make this frame a child of the + # toplevel template. This would cause a variety of + # interesting issues with identifier tracking. + block_frame = Frame(eval_ctx) + block_frame.block_frame = True + undeclared = find_undeclared(block.body, ("self", "super")) + if "self" in undeclared: + ref = block_frame.symbols.declare_parameter("self") + self.writeline(f"{ref} = TemplateReference(context)") + if "super" in undeclared: + ref = block_frame.symbols.declare_parameter("super") + self.writeline(f"{ref} = context.super({name!r}, block_{name})") + block_frame.symbols.analyze_node(block) + block_frame.block = name + self.writeline("_block_vars = {}") + self.enter_frame(block_frame) + self.pull_dependencies(block.body) + self.blockvisit(block.body, block_frame) + self.leave_frame(block_frame, with_python_scope=True) + self.outdent() + + blocks_kv_str = ", ".join(f"{x!r}: block_{x}" for x in self.blocks) + self.writeline(f"blocks = {{{blocks_kv_str}}}", extra=1) + debug_kv_str = "&".join(f"{k}={v}" for k, v in self.debug_info) + self.writeline(f"debug_info = {debug_kv_str!r}") + + def visit_Block(self, node: nodes.Block, frame: Frame) -> None: + """Call a block and register it for the template.""" + level = 0 + if frame.toplevel: + # if we know that we are a child template, there is no need to + # check if we are one + if self.has_known_extends: + return + if self.extends_so_far > 0: + self.writeline("if parent_template is None:") + self.indent() + level += 1 + + if node.scoped: + context = self.derive_context(frame) + else: + context = self.get_context_ref() + + if node.required: + self.writeline(f"if len(context.blocks[{node.name!r}]) <= 1:", node) + self.indent() + self.writeline( + f'raise TemplateRuntimeError("Required block {node.name!r} not found")', + node, + ) + self.outdent() + + if not self.environment.is_async and frame.buffer is None: + self.writeline( + f"yield from context.blocks[{node.name!r}][0]({context})", node + ) + else: + self.writeline( + f"{self.choose_async()}for event in" + f" context.blocks[{node.name!r}][0]({context}):", + node, + ) + self.indent() + self.simple_write("event", frame) + self.outdent() + + self.outdent(level) + + def visit_Extends(self, node: nodes.Extends, frame: Frame) -> None: + """Calls the extender.""" + if not frame.toplevel: + self.fail("cannot use extend from a non top-level scope", node.lineno) + + # if the number of extends statements in general is zero so + # far, we don't have to add a check if something extended + # the template before this one. + if self.extends_so_far > 0: + + # if we have a known extends we just add a template runtime + # error into the generated code. We could catch that at compile + # time too, but i welcome it not to confuse users by throwing the + # same error at different times just "because we can". + if not self.has_known_extends: + self.writeline("if parent_template is not None:") + self.indent() + self.writeline('raise TemplateRuntimeError("extended multiple times")') + + # if we have a known extends already we don't need that code here + # as we know that the template execution will end here. + if self.has_known_extends: + raise CompilerExit() + else: + self.outdent() + + self.writeline("parent_template = environment.get_template(", node) + self.visit(node.template, frame) + self.write(f", {self.name!r})") + self.writeline("for name, parent_block in parent_template.blocks.items():") + self.indent() + self.writeline("context.blocks.setdefault(name, []).append(parent_block)") + self.outdent() + + # if this extends statement was in the root level we can take + # advantage of that information and simplify the generated code + # in the top level from this point onwards + if frame.rootlevel: + self.has_known_extends = True + + # and now we have one more + self.extends_so_far += 1 + + def visit_Include(self, node: nodes.Include, frame: Frame) -> None: + """Handles includes.""" + if node.ignore_missing: + self.writeline("try:") + self.indent() + + func_name = "get_or_select_template" + if isinstance(node.template, nodes.Const): + if isinstance(node.template.value, str): + func_name = "get_template" + elif isinstance(node.template.value, (tuple, list)): + func_name = "select_template" + elif isinstance(node.template, (nodes.Tuple, nodes.List)): + func_name = "select_template" + + self.writeline(f"template = environment.{func_name}(", node) + self.visit(node.template, frame) + self.write(f", {self.name!r})") + if node.ignore_missing: + self.outdent() + self.writeline("except TemplateNotFound:") + self.indent() + self.writeline("pass") + self.outdent() + self.writeline("else:") + self.indent() + + skip_event_yield = False + if node.with_context: + self.writeline( + f"{self.choose_async()}for event in template.root_render_func(" + "template.new_context(context.get_all(), True," + f" {self.dump_local_context(frame)})):" + ) + elif self.environment.is_async: + self.writeline( + "for event in (await template._get_default_module_async())" + "._body_stream:" + ) + else: + self.writeline("yield from template._get_default_module()._body_stream") + skip_event_yield = True + + if not skip_event_yield: + self.indent() + self.simple_write("event", frame) + self.outdent() + + if node.ignore_missing: + self.outdent() + + def _import_common( + self, node: t.Union[nodes.Import, nodes.FromImport], frame: Frame + ) -> None: + self.write(f"{self.choose_async('await ')}environment.get_template(") + self.visit(node.template, frame) + self.write(f", {self.name!r}).") + + if node.with_context: + f_name = f"make_module{self.choose_async('_async')}" + self.write( + f"{f_name}(context.get_all(), True, {self.dump_local_context(frame)})" + ) + else: + self.write(f"_get_default_module{self.choose_async('_async')}(context)") + + def visit_Import(self, node: nodes.Import, frame: Frame) -> None: + """Visit regular imports.""" + self.writeline(f"{frame.symbols.ref(node.target)} = ", node) + if frame.toplevel: + self.write(f"context.vars[{node.target!r}] = ") + + self._import_common(node, frame) + + if frame.toplevel and not node.target.startswith("_"): + self.writeline(f"context.exported_vars.discard({node.target!r})") + + def visit_FromImport(self, node: nodes.FromImport, frame: Frame) -> None: + """Visit named imports.""" + self.newline(node) + self.write("included_template = ") + self._import_common(node, frame) + var_names = [] + discarded_names = [] + for name in node.names: + if isinstance(name, tuple): + name, alias = name + else: + alias = name + self.writeline( + f"{frame.symbols.ref(alias)} =" + f" getattr(included_template, {name!r}, missing)" + ) + self.writeline(f"if {frame.symbols.ref(alias)} is missing:") + self.indent() + message = ( + "the template {included_template.__name__!r}" + f" (imported on {self.position(node)})" + f" does not export the requested name {name!r}" + ) + self.writeline( + f"{frame.symbols.ref(alias)} = undefined(f{message!r}, name={name!r})" + ) + self.outdent() + if frame.toplevel: + var_names.append(alias) + if not alias.startswith("_"): + discarded_names.append(alias) + + if var_names: + if len(var_names) == 1: + name = var_names[0] + self.writeline(f"context.vars[{name!r}] = {frame.symbols.ref(name)}") + else: + names_kv = ", ".join( + f"{name!r}: {frame.symbols.ref(name)}" for name in var_names + ) + self.writeline(f"context.vars.update({{{names_kv}}})") + if discarded_names: + if len(discarded_names) == 1: + self.writeline(f"context.exported_vars.discard({discarded_names[0]!r})") + else: + names_str = ", ".join(map(repr, discarded_names)) + self.writeline( + f"context.exported_vars.difference_update(({names_str}))" + ) + + def visit_For(self, node: nodes.For, frame: Frame) -> None: + loop_frame = frame.inner() + loop_frame.loop_frame = True + test_frame = frame.inner() + else_frame = frame.inner() + + # try to figure out if we have an extended loop. An extended loop + # is necessary if the loop is in recursive mode if the special loop + # variable is accessed in the body if the body is a scoped block. + extended_loop = ( + node.recursive + or "loop" + in find_undeclared(node.iter_child_nodes(only=("body",)), ("loop",)) + or any(block.scoped for block in node.find_all(nodes.Block)) + ) + + loop_ref = None + if extended_loop: + loop_ref = loop_frame.symbols.declare_parameter("loop") + + loop_frame.symbols.analyze_node(node, for_branch="body") + if node.else_: + else_frame.symbols.analyze_node(node, for_branch="else") + + if node.test: + loop_filter_func = self.temporary_identifier() + test_frame.symbols.analyze_node(node, for_branch="test") + self.writeline(f"{self.func(loop_filter_func)}(fiter):", node.test) + self.indent() + self.enter_frame(test_frame) + self.writeline(self.choose_async("async for ", "for ")) + self.visit(node.target, loop_frame) + self.write(" in ") + self.write(self.choose_async("auto_aiter(fiter)", "fiter")) + self.write(":") + self.indent() + self.writeline("if ", node.test) + self.visit(node.test, test_frame) + self.write(":") + self.indent() + self.writeline("yield ") + self.visit(node.target, loop_frame) + self.outdent(3) + self.leave_frame(test_frame, with_python_scope=True) + + # if we don't have an recursive loop we have to find the shadowed + # variables at that point. Because loops can be nested but the loop + # variable is a special one we have to enforce aliasing for it. + if node.recursive: + self.writeline( + f"{self.func('loop')}(reciter, loop_render_func, depth=0):", node + ) + self.indent() + self.buffer(loop_frame) + + # Use the same buffer for the else frame + else_frame.buffer = loop_frame.buffer + + # make sure the loop variable is a special one and raise a template + # assertion error if a loop tries to write to loop + if extended_loop: + self.writeline(f"{loop_ref} = missing") + + for name in node.find_all(nodes.Name): + if name.ctx == "store" and name.name == "loop": + self.fail( + "Can't assign to special loop variable in for-loop target", + name.lineno, + ) + + if node.else_: + iteration_indicator = self.temporary_identifier() + self.writeline(f"{iteration_indicator} = 1") + + self.writeline(self.choose_async("async for ", "for "), node) + self.visit(node.target, loop_frame) + if extended_loop: + self.write(f", {loop_ref} in {self.choose_async('Async')}LoopContext(") + else: + self.write(" in ") + + if node.test: + self.write(f"{loop_filter_func}(") + if node.recursive: + self.write("reciter") + else: + if self.environment.is_async and not extended_loop: + self.write("auto_aiter(") + self.visit(node.iter, frame) + if self.environment.is_async and not extended_loop: + self.write(")") + if node.test: + self.write(")") + + if node.recursive: + self.write(", undefined, loop_render_func, depth):") + else: + self.write(", undefined):" if extended_loop else ":") + + self.indent() + self.enter_frame(loop_frame) + + self.writeline("_loop_vars = {}") + self.blockvisit(node.body, loop_frame) + if node.else_: + self.writeline(f"{iteration_indicator} = 0") + self.outdent() + self.leave_frame( + loop_frame, with_python_scope=node.recursive and not node.else_ + ) + + if node.else_: + self.writeline(f"if {iteration_indicator}:") + self.indent() + self.enter_frame(else_frame) + self.blockvisit(node.else_, else_frame) + self.leave_frame(else_frame) + self.outdent() + + # if the node was recursive we have to return the buffer contents + # and start the iteration code + if node.recursive: + self.return_buffer_contents(loop_frame) + self.outdent() + self.start_write(frame, node) + self.write(f"{self.choose_async('await ')}loop(") + if self.environment.is_async: + self.write("auto_aiter(") + self.visit(node.iter, frame) + if self.environment.is_async: + self.write(")") + self.write(", loop)") + self.end_write(frame) + + # at the end of the iteration, clear any assignments made in the + # loop from the top level + if self._assign_stack: + self._assign_stack[-1].difference_update(loop_frame.symbols.stores) + + def visit_If(self, node: nodes.If, frame: Frame) -> None: + if_frame = frame.soft() + self.writeline("if ", node) + self.visit(node.test, if_frame) + self.write(":") + self.indent() + self.blockvisit(node.body, if_frame) + self.outdent() + for elif_ in node.elif_: + self.writeline("elif ", elif_) + self.visit(elif_.test, if_frame) + self.write(":") + self.indent() + self.blockvisit(elif_.body, if_frame) + self.outdent() + if node.else_: + self.writeline("else:") + self.indent() + self.blockvisit(node.else_, if_frame) + self.outdent() + + def visit_Macro(self, node: nodes.Macro, frame: Frame) -> None: + macro_frame, macro_ref = self.macro_body(node, frame) + self.newline() + if frame.toplevel: + if not node.name.startswith("_"): + self.write(f"context.exported_vars.add({node.name!r})") + self.writeline(f"context.vars[{node.name!r}] = ") + self.write(f"{frame.symbols.ref(node.name)} = ") + self.macro_def(macro_ref, macro_frame) + + def visit_CallBlock(self, node: nodes.CallBlock, frame: Frame) -> None: + call_frame, macro_ref = self.macro_body(node, frame) + self.writeline("caller = ") + self.macro_def(macro_ref, call_frame) + self.start_write(frame, node) + self.visit_Call(node.call, frame, forward_caller=True) + self.end_write(frame) + + def visit_FilterBlock(self, node: nodes.FilterBlock, frame: Frame) -> None: + filter_frame = frame.inner() + filter_frame.symbols.analyze_node(node) + self.enter_frame(filter_frame) + self.buffer(filter_frame) + self.blockvisit(node.body, filter_frame) + self.start_write(frame, node) + self.visit_Filter(node.filter, filter_frame) + self.end_write(frame) + self.leave_frame(filter_frame) + + def visit_With(self, node: nodes.With, frame: Frame) -> None: + with_frame = frame.inner() + with_frame.symbols.analyze_node(node) + self.enter_frame(with_frame) + for target, expr in zip(node.targets, node.values): + self.newline() + self.visit(target, with_frame) + self.write(" = ") + self.visit(expr, frame) + self.blockvisit(node.body, with_frame) + self.leave_frame(with_frame) + + def visit_ExprStmt(self, node: nodes.ExprStmt, frame: Frame) -> None: + self.newline(node) + self.visit(node.node, frame) + + class _FinalizeInfo(t.NamedTuple): + const: t.Optional[t.Callable[..., str]] + src: t.Optional[str] + + @staticmethod + def _default_finalize(value: t.Any) -> t.Any: + """The default finalize function if the environment isn't + configured with one. Or, if the environment has one, this is + called on that function's output for constants. + """ + return str(value) + + _finalize: t.Optional[_FinalizeInfo] = None + + def _make_finalize(self) -> _FinalizeInfo: + """Build the finalize function to be used on constants and at + runtime. Cached so it's only created once for all output nodes. + + Returns a ``namedtuple`` with the following attributes: + + ``const`` + A function to finalize constant data at compile time. + + ``src`` + Source code to output around nodes to be evaluated at + runtime. + """ + if self._finalize is not None: + return self._finalize + + finalize: t.Optional[t.Callable[..., t.Any]] + finalize = default = self._default_finalize + src = None + + if self.environment.finalize: + src = "environment.finalize(" + env_finalize = self.environment.finalize + pass_arg = { + _PassArg.context: "context", + _PassArg.eval_context: "context.eval_ctx", + _PassArg.environment: "environment", + }.get( + _PassArg.from_obj(env_finalize) # type: ignore + ) + finalize = None + + if pass_arg is None: + + def finalize(value: t.Any) -> t.Any: + return default(env_finalize(value)) + + else: + src = f"{src}{pass_arg}, " + + if pass_arg == "environment": + + def finalize(value: t.Any) -> t.Any: + return default(env_finalize(self.environment, value)) + + self._finalize = self._FinalizeInfo(finalize, src) + return self._finalize + + def _output_const_repr(self, group: t.Iterable[t.Any]) -> str: + """Given a group of constant values converted from ``Output`` + child nodes, produce a string to write to the template module + source. + """ + return repr(concat(group)) + + def _output_child_to_const( + self, node: nodes.Expr, frame: Frame, finalize: _FinalizeInfo + ) -> str: + """Try to optimize a child of an ``Output`` node by trying to + convert it to constant, finalized data at compile time. + + If :exc:`Impossible` is raised, the node is not constant and + will be evaluated at runtime. Any other exception will also be + evaluated at runtime for easier debugging. + """ + const = node.as_const(frame.eval_ctx) + + if frame.eval_ctx.autoescape: + const = escape(const) + + # Template data doesn't go through finalize. + if isinstance(node, nodes.TemplateData): + return str(const) + + return finalize.const(const) # type: ignore + + def _output_child_pre( + self, node: nodes.Expr, frame: Frame, finalize: _FinalizeInfo + ) -> None: + """Output extra source code before visiting a child of an + ``Output`` node. + """ + if frame.eval_ctx.volatile: + self.write("(escape if context.eval_ctx.autoescape else str)(") + elif frame.eval_ctx.autoescape: + self.write("escape(") + else: + self.write("str(") + + if finalize.src is not None: + self.write(finalize.src) + + def _output_child_post( + self, node: nodes.Expr, frame: Frame, finalize: _FinalizeInfo + ) -> None: + """Output extra source code after visiting a child of an + ``Output`` node. + """ + self.write(")") + + if finalize.src is not None: + self.write(")") + + def visit_Output(self, node: nodes.Output, frame: Frame) -> None: + # If an extends is active, don't render outside a block. + if frame.require_output_check: + # A top-level extends is known to exist at compile time. + if self.has_known_extends: + return + + self.writeline("if parent_template is None:") + self.indent() + + finalize = self._make_finalize() + body: t.List[t.Union[t.List[t.Any], nodes.Expr]] = [] + + # Evaluate constants at compile time if possible. Each item in + # body will be either a list of static data or a node to be + # evaluated at runtime. + for child in node.nodes: + try: + if not ( + # If the finalize function requires runtime context, + # constants can't be evaluated at compile time. + finalize.const + # Unless it's basic template data that won't be + # finalized anyway. + or isinstance(child, nodes.TemplateData) + ): + raise nodes.Impossible() + + const = self._output_child_to_const(child, frame, finalize) + except (nodes.Impossible, Exception): + # The node was not constant and needs to be evaluated at + # runtime. Or another error was raised, which is easier + # to debug at runtime. + body.append(child) + continue + + if body and isinstance(body[-1], list): + body[-1].append(const) + else: + body.append([const]) + + if frame.buffer is not None: + if len(body) == 1: + self.writeline(f"{frame.buffer}.append(") + else: + self.writeline(f"{frame.buffer}.extend((") + + self.indent() + + for item in body: + if isinstance(item, list): + # A group of constant data to join and output. + val = self._output_const_repr(item) + + if frame.buffer is None: + self.writeline("yield " + val) + else: + self.writeline(val + ",") + else: + if frame.buffer is None: + self.writeline("yield ", item) + else: + self.newline(item) + + # A node to be evaluated at runtime. + self._output_child_pre(item, frame, finalize) + self.visit(item, frame) + self._output_child_post(item, frame, finalize) + + if frame.buffer is not None: + self.write(",") + + if frame.buffer is not None: + self.outdent() + self.writeline(")" if len(body) == 1 else "))") + + if frame.require_output_check: + self.outdent() + + def visit_Assign(self, node: nodes.Assign, frame: Frame) -> None: + self.push_assign_tracking() + self.newline(node) + self.visit(node.target, frame) + self.write(" = ") + self.visit(node.node, frame) + self.pop_assign_tracking(frame) + + def visit_AssignBlock(self, node: nodes.AssignBlock, frame: Frame) -> None: + self.push_assign_tracking() + block_frame = frame.inner() + # This is a special case. Since a set block always captures we + # will disable output checks. This way one can use set blocks + # toplevel even in extended templates. + block_frame.require_output_check = False + block_frame.symbols.analyze_node(node) + self.enter_frame(block_frame) + self.buffer(block_frame) + self.blockvisit(node.body, block_frame) + self.newline(node) + self.visit(node.target, frame) + self.write(" = (Markup if context.eval_ctx.autoescape else identity)(") + if node.filter is not None: + self.visit_Filter(node.filter, block_frame) + else: + self.write(f"concat({block_frame.buffer})") + self.write(")") + self.pop_assign_tracking(frame) + self.leave_frame(block_frame) + + # -- Expression Visitors + + def visit_Name(self, node: nodes.Name, frame: Frame) -> None: + if node.ctx == "store" and ( + frame.toplevel or frame.loop_frame or frame.block_frame + ): + if self._assign_stack: + self._assign_stack[-1].add(node.name) + ref = frame.symbols.ref(node.name) + + # If we are looking up a variable we might have to deal with the + # case where it's undefined. We can skip that case if the load + # instruction indicates a parameter which are always defined. + if node.ctx == "load": + load = frame.symbols.find_load(ref) + if not ( + load is not None + and load[0] == VAR_LOAD_PARAMETER + and not self.parameter_is_undeclared(ref) + ): + self.write( + f"(undefined(name={node.name!r}) if {ref} is missing else {ref})" + ) + return + + self.write(ref) + + def visit_NSRef(self, node: nodes.NSRef, frame: Frame) -> None: + # NSRefs can only be used to store values; since they use the normal + # `foo.bar` notation they will be parsed as a normal attribute access + # when used anywhere but in a `set` context + ref = frame.symbols.ref(node.name) + self.writeline(f"if not isinstance({ref}, Namespace):") + self.indent() + self.writeline( + "raise TemplateRuntimeError" + '("cannot assign attribute on non-namespace object")' + ) + self.outdent() + self.writeline(f"{ref}[{node.attr!r}]") + + def visit_Const(self, node: nodes.Const, frame: Frame) -> None: + val = node.as_const(frame.eval_ctx) + if isinstance(val, float): + self.write(str(val)) + else: + self.write(repr(val)) + + def visit_TemplateData(self, node: nodes.TemplateData, frame: Frame) -> None: + try: + self.write(repr(node.as_const(frame.eval_ctx))) + except nodes.Impossible: + self.write( + f"(Markup if context.eval_ctx.autoescape else identity)({node.data!r})" + ) + + def visit_Tuple(self, node: nodes.Tuple, frame: Frame) -> None: + self.write("(") + idx = -1 + for idx, item in enumerate(node.items): + if idx: + self.write(", ") + self.visit(item, frame) + self.write(",)" if idx == 0 else ")") + + def visit_List(self, node: nodes.List, frame: Frame) -> None: + self.write("[") + for idx, item in enumerate(node.items): + if idx: + self.write(", ") + self.visit(item, frame) + self.write("]") + + def visit_Dict(self, node: nodes.Dict, frame: Frame) -> None: + self.write("{") + for idx, item in enumerate(node.items): + if idx: + self.write(", ") + self.visit(item.key, frame) + self.write(": ") + self.visit(item.value, frame) + self.write("}") + + visit_Add = _make_binop("+") + visit_Sub = _make_binop("-") + visit_Mul = _make_binop("*") + visit_Div = _make_binop("/") + visit_FloorDiv = _make_binop("//") + visit_Pow = _make_binop("**") + visit_Mod = _make_binop("%") + visit_And = _make_binop("and") + visit_Or = _make_binop("or") + visit_Pos = _make_unop("+") + visit_Neg = _make_unop("-") + visit_Not = _make_unop("not ") + + @optimizeconst + def visit_Concat(self, node: nodes.Concat, frame: Frame) -> None: + if frame.eval_ctx.volatile: + func_name = "(markup_join if context.eval_ctx.volatile else str_join)" + elif frame.eval_ctx.autoescape: + func_name = "markup_join" + else: + func_name = "str_join" + self.write(f"{func_name}((") + for arg in node.nodes: + self.visit(arg, frame) + self.write(", ") + self.write("))") + + @optimizeconst + def visit_Compare(self, node: nodes.Compare, frame: Frame) -> None: + self.write("(") + self.visit(node.expr, frame) + for op in node.ops: + self.visit(op, frame) + self.write(")") + + def visit_Operand(self, node: nodes.Operand, frame: Frame) -> None: + self.write(f" {operators[node.op]} ") + self.visit(node.expr, frame) + + @optimizeconst + def visit_Getattr(self, node: nodes.Getattr, frame: Frame) -> None: + if self.environment.is_async: + self.write("(await auto_await(") + + self.write("environment.getattr(") + self.visit(node.node, frame) + self.write(f", {node.attr!r})") + + if self.environment.is_async: + self.write("))") + + @optimizeconst + def visit_Getitem(self, node: nodes.Getitem, frame: Frame) -> None: + # slices bypass the environment getitem method. + if isinstance(node.arg, nodes.Slice): + self.visit(node.node, frame) + self.write("[") + self.visit(node.arg, frame) + self.write("]") + else: + if self.environment.is_async: + self.write("(await auto_await(") + + self.write("environment.getitem(") + self.visit(node.node, frame) + self.write(", ") + self.visit(node.arg, frame) + self.write(")") + + if self.environment.is_async: + self.write("))") + + def visit_Slice(self, node: nodes.Slice, frame: Frame) -> None: + if node.start is not None: + self.visit(node.start, frame) + self.write(":") + if node.stop is not None: + self.visit(node.stop, frame) + if node.step is not None: + self.write(":") + self.visit(node.step, frame) + + @contextmanager + def _filter_test_common( + self, node: t.Union[nodes.Filter, nodes.Test], frame: Frame, is_filter: bool + ) -> t.Iterator[None]: + if self.environment.is_async: + self.write("(await auto_await(") + + if is_filter: + self.write(f"{self.filters[node.name]}(") + func = self.environment.filters.get(node.name) + else: + self.write(f"{self.tests[node.name]}(") + func = self.environment.tests.get(node.name) + + # When inside an If or CondExpr frame, allow the filter to be + # undefined at compile time and only raise an error if it's + # actually called at runtime. See pull_dependencies. + if func is None and not frame.soft_frame: + type_name = "filter" if is_filter else "test" + self.fail(f"No {type_name} named {node.name!r}.", node.lineno) + + pass_arg = { + _PassArg.context: "context", + _PassArg.eval_context: "context.eval_ctx", + _PassArg.environment: "environment", + }.get( + _PassArg.from_obj(func) # type: ignore + ) + + if pass_arg is not None: + self.write(f"{pass_arg}, ") + + # Back to the visitor function to handle visiting the target of + # the filter or test. + yield + + self.signature(node, frame) + self.write(")") + + if self.environment.is_async: + self.write("))") + + @optimizeconst + def visit_Filter(self, node: nodes.Filter, frame: Frame) -> None: + with self._filter_test_common(node, frame, True): + # if the filter node is None we are inside a filter block + # and want to write to the current buffer + if node.node is not None: + self.visit(node.node, frame) + elif frame.eval_ctx.volatile: + self.write( + f"(Markup(concat({frame.buffer}))" + f" if context.eval_ctx.autoescape else concat({frame.buffer}))" + ) + elif frame.eval_ctx.autoescape: + self.write(f"Markup(concat({frame.buffer}))") + else: + self.write(f"concat({frame.buffer})") + + @optimizeconst + def visit_Test(self, node: nodes.Test, frame: Frame) -> None: + with self._filter_test_common(node, frame, False): + self.visit(node.node, frame) + + @optimizeconst + def visit_CondExpr(self, node: nodes.CondExpr, frame: Frame) -> None: + frame = frame.soft() + + def write_expr2() -> None: + if node.expr2 is not None: + self.visit(node.expr2, frame) + return + + self.write( + f'cond_expr_undefined("the inline if-expression on' + f" {self.position(node)} evaluated to false and no else" + f' section was defined.")' + ) + + self.write("(") + self.visit(node.expr1, frame) + self.write(" if ") + self.visit(node.test, frame) + self.write(" else ") + write_expr2() + self.write(")") + + @optimizeconst + def visit_Call( + self, node: nodes.Call, frame: Frame, forward_caller: bool = False + ) -> None: + if self.environment.is_async: + self.write("(await auto_await(") + if self.environment.sandboxed: + self.write("environment.call(context, ") + else: + self.write("context.call(") + self.visit(node.node, frame) + extra_kwargs = {"caller": "caller"} if forward_caller else None + loop_kwargs = {"_loop_vars": "_loop_vars"} if frame.loop_frame else {} + block_kwargs = {"_block_vars": "_block_vars"} if frame.block_frame else {} + if extra_kwargs: + extra_kwargs.update(loop_kwargs, **block_kwargs) + elif loop_kwargs or block_kwargs: + extra_kwargs = dict(loop_kwargs, **block_kwargs) + self.signature(node, frame, extra_kwargs) + self.write(")") + if self.environment.is_async: + self.write("))") + + def visit_Keyword(self, node: nodes.Keyword, frame: Frame) -> None: + self.write(node.key + "=") + self.visit(node.value, frame) + + # -- Unused nodes for extensions + + def visit_MarkSafe(self, node: nodes.MarkSafe, frame: Frame) -> None: + self.write("Markup(") + self.visit(node.expr, frame) + self.write(")") + + def visit_MarkSafeIfAutoescape( + self, node: nodes.MarkSafeIfAutoescape, frame: Frame + ) -> None: + self.write("(Markup if context.eval_ctx.autoescape else identity)(") + self.visit(node.expr, frame) + self.write(")") + + def visit_EnvironmentAttribute( + self, node: nodes.EnvironmentAttribute, frame: Frame + ) -> None: + self.write("environment." + node.name) + + def visit_ExtensionAttribute( + self, node: nodes.ExtensionAttribute, frame: Frame + ) -> None: + self.write(f"environment.extensions[{node.identifier!r}].{node.name}") + + def visit_ImportedName(self, node: nodes.ImportedName, frame: Frame) -> None: + self.write(self.import_aliases[node.importname]) + + def visit_InternalName(self, node: nodes.InternalName, frame: Frame) -> None: + self.write(node.name) + + def visit_ContextReference( + self, node: nodes.ContextReference, frame: Frame + ) -> None: + self.write("context") + + def visit_DerivedContextReference( + self, node: nodes.DerivedContextReference, frame: Frame + ) -> None: + self.write(self.derive_context(frame)) + + def visit_Continue(self, node: nodes.Continue, frame: Frame) -> None: + self.writeline("continue", node) + + def visit_Break(self, node: nodes.Break, frame: Frame) -> None: + self.writeline("break", node) + + def visit_Scope(self, node: nodes.Scope, frame: Frame) -> None: + scope_frame = frame.inner() + scope_frame.symbols.analyze_node(node) + self.enter_frame(scope_frame) + self.blockvisit(node.body, scope_frame) + self.leave_frame(scope_frame) + + def visit_OverlayScope(self, node: nodes.OverlayScope, frame: Frame) -> None: + ctx = self.temporary_identifier() + self.writeline(f"{ctx} = {self.derive_context(frame)}") + self.writeline(f"{ctx}.vars = ") + self.visit(node.context, frame) + self.push_context_reference(ctx) + + scope_frame = frame.inner(isolated=True) + scope_frame.symbols.analyze_node(node) + self.enter_frame(scope_frame) + self.blockvisit(node.body, scope_frame) + self.leave_frame(scope_frame) + self.pop_context_reference() + + def visit_EvalContextModifier( + self, node: nodes.EvalContextModifier, frame: Frame + ) -> None: + for keyword in node.options: + self.writeline(f"context.eval_ctx.{keyword.key} = ") + self.visit(keyword.value, frame) + try: + val = keyword.value.as_const(frame.eval_ctx) + except nodes.Impossible: + frame.eval_ctx.volatile = True + else: + setattr(frame.eval_ctx, keyword.key, val) + + def visit_ScopedEvalContextModifier( + self, node: nodes.ScopedEvalContextModifier, frame: Frame + ) -> None: + old_ctx_name = self.temporary_identifier() + saved_ctx = frame.eval_ctx.save() + self.writeline(f"{old_ctx_name} = context.eval_ctx.save()") + self.visit_EvalContextModifier(node, frame) + for child in node.body: + self.visit(child, frame) + frame.eval_ctx.revert(saved_ctx) + self.writeline(f"context.eval_ctx.revert({old_ctx_name})") diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/jinja2/constants.py b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/jinja2/constants.py new file mode 100644 index 00000000..41a1c23b --- /dev/null +++ b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/jinja2/constants.py @@ -0,0 +1,20 @@ +#: list of lorem ipsum words used by the lipsum() helper function +LOREM_IPSUM_WORDS = """\ +a ac accumsan ad adipiscing aenean aliquam aliquet amet ante aptent arcu at +auctor augue bibendum blandit class commodo condimentum congue consectetuer +consequat conubia convallis cras cubilia cum curabitur curae cursus dapibus +diam dictum dictumst dignissim dis dolor donec dui duis egestas eget eleifend +elementum elit enim erat eros est et etiam eu euismod facilisi facilisis fames +faucibus felis fermentum feugiat fringilla fusce gravida habitant habitasse hac +hendrerit hymenaeos iaculis id imperdiet in inceptos integer interdum ipsum +justo lacinia lacus laoreet lectus leo libero ligula litora lobortis lorem +luctus maecenas magna magnis malesuada massa mattis mauris metus mi molestie +mollis montes morbi mus nam nascetur natoque nec neque netus nibh nisi nisl non +nonummy nostra nulla nullam nunc odio orci ornare parturient pede pellentesque +penatibus per pharetra phasellus placerat platea porta porttitor posuere +potenti praesent pretium primis proin pulvinar purus quam quis quisque rhoncus +ridiculus risus rutrum sagittis sapien scelerisque sed sem semper senectus sit +sociis sociosqu sodales sollicitudin suscipit suspendisse taciti tellus tempor +tempus tincidunt torquent tortor tristique turpis ullamcorper ultrices +ultricies urna ut varius vehicula vel velit venenatis vestibulum vitae vivamus +viverra volutpat vulputate""" diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/jinja2/debug.py b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/jinja2/debug.py new file mode 100644 index 00000000..7ed7e929 --- /dev/null +++ b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/jinja2/debug.py @@ -0,0 +1,191 @@ +import sys +import typing as t +from types import CodeType +from types import TracebackType + +from .exceptions import TemplateSyntaxError +from .utils import internal_code +from .utils import missing + +if t.TYPE_CHECKING: + from .runtime import Context + + +def rewrite_traceback_stack(source: t.Optional[str] = None) -> BaseException: + """Rewrite the current exception to replace any tracebacks from + within compiled template code with tracebacks that look like they + came from the template source. + + This must be called within an ``except`` block. + + :param source: For ``TemplateSyntaxError``, the original source if + known. + :return: The original exception with the rewritten traceback. + """ + _, exc_value, tb = sys.exc_info() + exc_value = t.cast(BaseException, exc_value) + tb = t.cast(TracebackType, tb) + + if isinstance(exc_value, TemplateSyntaxError) and not exc_value.translated: + exc_value.translated = True + exc_value.source = source + # Remove the old traceback, otherwise the frames from the + # compiler still show up. + exc_value.with_traceback(None) + # Outside of runtime, so the frame isn't executing template + # code, but it still needs to point at the template. + tb = fake_traceback( + exc_value, None, exc_value.filename or "", exc_value.lineno + ) + else: + # Skip the frame for the render function. + tb = tb.tb_next + + stack = [] + + # Build the stack of traceback object, replacing any in template + # code with the source file and line information. + while tb is not None: + # Skip frames decorated with @internalcode. These are internal + # calls that aren't useful in template debugging output. + if tb.tb_frame.f_code in internal_code: + tb = tb.tb_next + continue + + template = tb.tb_frame.f_globals.get("__jinja_template__") + + if template is not None: + lineno = template.get_corresponding_lineno(tb.tb_lineno) + fake_tb = fake_traceback(exc_value, tb, template.filename, lineno) + stack.append(fake_tb) + else: + stack.append(tb) + + tb = tb.tb_next + + tb_next = None + + # Assign tb_next in reverse to avoid circular references. + for tb in reversed(stack): + tb.tb_next = tb_next + tb_next = tb + + return exc_value.with_traceback(tb_next) + + +def fake_traceback( # type: ignore + exc_value: BaseException, tb: t.Optional[TracebackType], filename: str, lineno: int +) -> TracebackType: + """Produce a new traceback object that looks like it came from the + template source instead of the compiled code. The filename, line + number, and location name will point to the template, and the local + variables will be the current template context. + + :param exc_value: The original exception to be re-raised to create + the new traceback. + :param tb: The original traceback to get the local variables and + code info from. + :param filename: The template filename. + :param lineno: The line number in the template source. + """ + if tb is not None: + # Replace the real locals with the context that would be + # available at that point in the template. + locals = get_template_locals(tb.tb_frame.f_locals) + locals.pop("__jinja_exception__", None) + else: + locals = {} + + globals = { + "__name__": filename, + "__file__": filename, + "__jinja_exception__": exc_value, + } + # Raise an exception at the correct line number. + code: CodeType = compile( + "\n" * (lineno - 1) + "raise __jinja_exception__", filename, "exec" + ) + + # Build a new code object that points to the template file and + # replaces the location with a block name. + location = "template" + + if tb is not None: + function = tb.tb_frame.f_code.co_name + + if function == "root": + location = "top-level template code" + elif function.startswith("block_"): + location = f"block {function[6:]!r}" + + if sys.version_info >= (3, 8): + code = code.replace(co_name=location) + else: + code = CodeType( + code.co_argcount, + code.co_kwonlyargcount, + code.co_nlocals, + code.co_stacksize, + code.co_flags, + code.co_code, + code.co_consts, + code.co_names, + code.co_varnames, + code.co_filename, + location, + code.co_firstlineno, + code.co_lnotab, + code.co_freevars, + code.co_cellvars, + ) + + # Execute the new code, which is guaranteed to raise, and return + # the new traceback without this frame. + try: + exec(code, globals, locals) + except BaseException: + return sys.exc_info()[2].tb_next # type: ignore + + +def get_template_locals(real_locals: t.Mapping[str, t.Any]) -> t.Dict[str, t.Any]: + """Based on the runtime locals, get the context that would be + available at that point in the template. + """ + # Start with the current template context. + ctx: "t.Optional[Context]" = real_locals.get("context") + + if ctx is not None: + data: t.Dict[str, t.Any] = ctx.get_all().copy() + else: + data = {} + + # Might be in a derived context that only sets local variables + # rather than pushing a context. Local variables follow the scheme + # l_depth_name. Find the highest-depth local that has a value for + # each name. + local_overrides: t.Dict[str, t.Tuple[int, t.Any]] = {} + + for name, value in real_locals.items(): + if not name.startswith("l_") or value is missing: + # Not a template variable, or no longer relevant. + continue + + try: + _, depth_str, name = name.split("_", 2) + depth = int(depth_str) + except ValueError: + continue + + cur_depth = local_overrides.get(name, (-1,))[0] + + if cur_depth < depth: + local_overrides[name] = (depth, value) + + # Modify the context with any derived context. + for name, (_, value) in local_overrides.items(): + if value is missing: + data.pop(name, None) + else: + data[name] = value + + return data diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/jinja2/defaults.py b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/jinja2/defaults.py new file mode 100644 index 00000000..638cad3d --- /dev/null +++ b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/jinja2/defaults.py @@ -0,0 +1,48 @@ +import typing as t + +from .filters import FILTERS as DEFAULT_FILTERS # noqa: F401 +from .tests import TESTS as DEFAULT_TESTS # noqa: F401 +from .utils import Cycler +from .utils import generate_lorem_ipsum +from .utils import Joiner +from .utils import Namespace + +if t.TYPE_CHECKING: + import typing_extensions as te + +# defaults for the parser / lexer +BLOCK_START_STRING = "{%" +BLOCK_END_STRING = "%}" +VARIABLE_START_STRING = "{{" +VARIABLE_END_STRING = "}}" +COMMENT_START_STRING = "{#" +COMMENT_END_STRING = "#}" +LINE_STATEMENT_PREFIX: t.Optional[str] = None +LINE_COMMENT_PREFIX: t.Optional[str] = None +TRIM_BLOCKS = False +LSTRIP_BLOCKS = False +NEWLINE_SEQUENCE: "te.Literal['\\n', '\\r\\n', '\\r']" = "\n" +KEEP_TRAILING_NEWLINE = False + +# default filters, tests and namespace + +DEFAULT_NAMESPACE = { + "range": range, + "dict": dict, + "lipsum": generate_lorem_ipsum, + "cycler": Cycler, + "joiner": Joiner, + "namespace": Namespace, +} + +# default policies +DEFAULT_POLICIES: t.Dict[str, t.Any] = { + "compiler.ascii_str": True, + "urlize.rel": "noopener", + "urlize.target": None, + "urlize.extra_schemes": None, + "truncate.leeway": 5, + "json.dumps_function": None, + "json.dumps_kwargs": {"sort_keys": True}, + "ext.i18n.trimmed": False, +} diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/jinja2/environment.py b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/jinja2/environment.py new file mode 100644 index 00000000..ea04e8b4 --- /dev/null +++ b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/jinja2/environment.py @@ -0,0 +1,1667 @@ +"""Classes for managing templates and their runtime and compile time +options. +""" +import os +import typing +import typing as t +import weakref +from collections import ChainMap +from functools import lru_cache +from functools import partial +from functools import reduce +from types import CodeType + +from markupsafe import Markup + +from . import nodes +from .compiler import CodeGenerator +from .compiler import generate +from .defaults import BLOCK_END_STRING +from .defaults import BLOCK_START_STRING +from .defaults import COMMENT_END_STRING +from .defaults import COMMENT_START_STRING +from .defaults import DEFAULT_FILTERS +from .defaults import DEFAULT_NAMESPACE +from .defaults import DEFAULT_POLICIES +from .defaults import DEFAULT_TESTS +from .defaults import KEEP_TRAILING_NEWLINE +from .defaults import LINE_COMMENT_PREFIX +from .defaults import LINE_STATEMENT_PREFIX +from .defaults import LSTRIP_BLOCKS +from .defaults import NEWLINE_SEQUENCE +from .defaults import TRIM_BLOCKS +from .defaults import VARIABLE_END_STRING +from .defaults import VARIABLE_START_STRING +from .exceptions import TemplateNotFound +from .exceptions import TemplateRuntimeError +from .exceptions import TemplatesNotFound +from .exceptions import TemplateSyntaxError +from .exceptions import UndefinedError +from .lexer import get_lexer +from .lexer import Lexer +from .lexer import TokenStream +from .nodes import EvalContext +from .parser import Parser +from .runtime import Context +from .runtime import new_context +from .runtime import Undefined +from .utils import _PassArg +from .utils import concat +from .utils import consume +from .utils import import_string +from .utils import internalcode +from .utils import LRUCache +from .utils import missing + +if t.TYPE_CHECKING: + import typing_extensions as te + from .bccache import BytecodeCache + from .ext import Extension + from .loaders import BaseLoader + +_env_bound = t.TypeVar("_env_bound", bound="Environment") + + +# for direct template usage we have up to ten living environments +@lru_cache(maxsize=10) +def get_spontaneous_environment(cls: t.Type[_env_bound], *args: t.Any) -> _env_bound: + """Return a new spontaneous environment. A spontaneous environment + is used for templates created directly rather than through an + existing environment. + + :param cls: Environment class to create. + :param args: Positional arguments passed to environment. + """ + env = cls(*args) + env.shared = True + return env + + +def create_cache( + size: int, +) -> t.Optional[t.MutableMapping[t.Tuple[weakref.ref, str], "Template"]]: + """Return the cache class for the given size.""" + if size == 0: + return None + + if size < 0: + return {} + + return LRUCache(size) # type: ignore + + +def copy_cache( + cache: t.Optional[t.MutableMapping], +) -> t.Optional[t.MutableMapping[t.Tuple[weakref.ref, str], "Template"]]: + """Create an empty copy of the given cache.""" + if cache is None: + return None + + if type(cache) is dict: + return {} + + return LRUCache(cache.capacity) # type: ignore + + +def load_extensions( + environment: "Environment", + extensions: t.Sequence[t.Union[str, t.Type["Extension"]]], +) -> t.Dict[str, "Extension"]: + """Load the extensions from the list and bind it to the environment. + Returns a dict of instantiated extensions. + """ + result = {} + + for extension in extensions: + if isinstance(extension, str): + extension = t.cast(t.Type["Extension"], import_string(extension)) + + result[extension.identifier] = extension(environment) + + return result + + +def _environment_config_check(environment: "Environment") -> "Environment": + """Perform a sanity check on the environment.""" + assert issubclass( + environment.undefined, Undefined + ), "'undefined' must be a subclass of 'jinja2.Undefined'." + assert ( + environment.block_start_string + != environment.variable_start_string + != environment.comment_start_string + ), "block, variable and comment start strings must be different." + assert environment.newline_sequence in { + "\r", + "\r\n", + "\n", + }, "'newline_sequence' must be one of '\\n', '\\r\\n', or '\\r'." + return environment + + +class Environment: + r"""The core component of Jinja is the `Environment`. It contains + important shared variables like configuration, filters, tests, + globals and others. Instances of this class may be modified if + they are not shared and if no template was loaded so far. + Modifications on environments after the first template was loaded + will lead to surprising effects and undefined behavior. + + Here are the possible initialization parameters: + + `block_start_string` + The string marking the beginning of a block. Defaults to ``'{%'``. + + `block_end_string` + The string marking the end of a block. Defaults to ``'%}'``. + + `variable_start_string` + The string marking the beginning of a print statement. + Defaults to ``'{{'``. + + `variable_end_string` + The string marking the end of a print statement. Defaults to + ``'}}'``. + + `comment_start_string` + The string marking the beginning of a comment. Defaults to ``'{#'``. + + `comment_end_string` + The string marking the end of a comment. Defaults to ``'#}'``. + + `line_statement_prefix` + If given and a string, this will be used as prefix for line based + statements. See also :ref:`line-statements`. + + `line_comment_prefix` + If given and a string, this will be used as prefix for line based + comments. See also :ref:`line-statements`. + + .. versionadded:: 2.2 + + `trim_blocks` + If this is set to ``True`` the first newline after a block is + removed (block, not variable tag!). Defaults to `False`. + + `lstrip_blocks` + If this is set to ``True`` leading spaces and tabs are stripped + from the start of a line to a block. Defaults to `False`. + + `newline_sequence` + The sequence that starts a newline. Must be one of ``'\r'``, + ``'\n'`` or ``'\r\n'``. The default is ``'\n'`` which is a + useful default for Linux and OS X systems as well as web + applications. + + `keep_trailing_newline` + Preserve the trailing newline when rendering templates. + The default is ``False``, which causes a single newline, + if present, to be stripped from the end of the template. + + .. versionadded:: 2.7 + + `extensions` + List of Jinja extensions to use. This can either be import paths + as strings or extension classes. For more information have a + look at :ref:`the extensions documentation `. + + `optimized` + should the optimizer be enabled? Default is ``True``. + + `undefined` + :class:`Undefined` or a subclass of it that is used to represent + undefined values in the template. + + `finalize` + A callable that can be used to process the result of a variable + expression before it is output. For example one can convert + ``None`` implicitly into an empty string here. + + `autoescape` + If set to ``True`` the XML/HTML autoescaping feature is enabled by + default. For more details about autoescaping see + :class:`~markupsafe.Markup`. As of Jinja 2.4 this can also + be a callable that is passed the template name and has to + return ``True`` or ``False`` depending on autoescape should be + enabled by default. + + .. versionchanged:: 2.4 + `autoescape` can now be a function + + `loader` + The template loader for this environment. + + `cache_size` + The size of the cache. Per default this is ``400`` which means + that if more than 400 templates are loaded the loader will clean + out the least recently used template. If the cache size is set to + ``0`` templates are recompiled all the time, if the cache size is + ``-1`` the cache will not be cleaned. + + .. versionchanged:: 2.8 + The cache size was increased to 400 from a low 50. + + `auto_reload` + Some loaders load templates from locations where the template + sources may change (ie: file system or database). If + ``auto_reload`` is set to ``True`` (default) every time a template is + requested the loader checks if the source changed and if yes, it + will reload the template. For higher performance it's possible to + disable that. + + `bytecode_cache` + If set to a bytecode cache object, this object will provide a + cache for the internal Jinja bytecode so that templates don't + have to be parsed if they were not changed. + + See :ref:`bytecode-cache` for more information. + + `enable_async` + If set to true this enables async template execution which + allows using async functions and generators. + """ + + #: if this environment is sandboxed. Modifying this variable won't make + #: the environment sandboxed though. For a real sandboxed environment + #: have a look at jinja2.sandbox. This flag alone controls the code + #: generation by the compiler. + sandboxed = False + + #: True if the environment is just an overlay + overlayed = False + + #: the environment this environment is linked to if it is an overlay + linked_to: t.Optional["Environment"] = None + + #: shared environments have this set to `True`. A shared environment + #: must not be modified + shared = False + + #: the class that is used for code generation. See + #: :class:`~jinja2.compiler.CodeGenerator` for more information. + code_generator_class: t.Type["CodeGenerator"] = CodeGenerator + + concat = "".join + + #: the context class that is used for templates. See + #: :class:`~jinja2.runtime.Context` for more information. + context_class: t.Type[Context] = Context + + template_class: t.Type["Template"] + + def __init__( + self, + block_start_string: str = BLOCK_START_STRING, + block_end_string: str = BLOCK_END_STRING, + variable_start_string: str = VARIABLE_START_STRING, + variable_end_string: str = VARIABLE_END_STRING, + comment_start_string: str = COMMENT_START_STRING, + comment_end_string: str = COMMENT_END_STRING, + line_statement_prefix: t.Optional[str] = LINE_STATEMENT_PREFIX, + line_comment_prefix: t.Optional[str] = LINE_COMMENT_PREFIX, + trim_blocks: bool = TRIM_BLOCKS, + lstrip_blocks: bool = LSTRIP_BLOCKS, + newline_sequence: "te.Literal['\\n', '\\r\\n', '\\r']" = NEWLINE_SEQUENCE, + keep_trailing_newline: bool = KEEP_TRAILING_NEWLINE, + extensions: t.Sequence[t.Union[str, t.Type["Extension"]]] = (), + optimized: bool = True, + undefined: t.Type[Undefined] = Undefined, + finalize: t.Optional[t.Callable[..., t.Any]] = None, + autoescape: t.Union[bool, t.Callable[[t.Optional[str]], bool]] = False, + loader: t.Optional["BaseLoader"] = None, + cache_size: int = 400, + auto_reload: bool = True, + bytecode_cache: t.Optional["BytecodeCache"] = None, + enable_async: bool = False, + ): + # !!Important notice!! + # The constructor accepts quite a few arguments that should be + # passed by keyword rather than position. However it's important to + # not change the order of arguments because it's used at least + # internally in those cases: + # - spontaneous environments (i18n extension and Template) + # - unittests + # If parameter changes are required only add parameters at the end + # and don't change the arguments (or the defaults!) of the arguments + # existing already. + + # lexer / parser information + self.block_start_string = block_start_string + self.block_end_string = block_end_string + self.variable_start_string = variable_start_string + self.variable_end_string = variable_end_string + self.comment_start_string = comment_start_string + self.comment_end_string = comment_end_string + self.line_statement_prefix = line_statement_prefix + self.line_comment_prefix = line_comment_prefix + self.trim_blocks = trim_blocks + self.lstrip_blocks = lstrip_blocks + self.newline_sequence = newline_sequence + self.keep_trailing_newline = keep_trailing_newline + + # runtime information + self.undefined: t.Type[Undefined] = undefined + self.optimized = optimized + self.finalize = finalize + self.autoescape = autoescape + + # defaults + self.filters = DEFAULT_FILTERS.copy() + self.tests = DEFAULT_TESTS.copy() + self.globals = DEFAULT_NAMESPACE.copy() + + # set the loader provided + self.loader = loader + self.cache = create_cache(cache_size) + self.bytecode_cache = bytecode_cache + self.auto_reload = auto_reload + + # configurable policies + self.policies = DEFAULT_POLICIES.copy() + + # load extensions + self.extensions = load_extensions(self, extensions) + + self.is_async = enable_async + _environment_config_check(self) + + def add_extension(self, extension: t.Union[str, t.Type["Extension"]]) -> None: + """Adds an extension after the environment was created. + + .. versionadded:: 2.5 + """ + self.extensions.update(load_extensions(self, [extension])) + + def extend(self, **attributes: t.Any) -> None: + """Add the items to the instance of the environment if they do not exist + yet. This is used by :ref:`extensions ` to register + callbacks and configuration values without breaking inheritance. + """ + for key, value in attributes.items(): + if not hasattr(self, key): + setattr(self, key, value) + + def overlay( + self, + block_start_string: str = missing, + block_end_string: str = missing, + variable_start_string: str = missing, + variable_end_string: str = missing, + comment_start_string: str = missing, + comment_end_string: str = missing, + line_statement_prefix: t.Optional[str] = missing, + line_comment_prefix: t.Optional[str] = missing, + trim_blocks: bool = missing, + lstrip_blocks: bool = missing, + newline_sequence: "te.Literal['\\n', '\\r\\n', '\\r']" = missing, + keep_trailing_newline: bool = missing, + extensions: t.Sequence[t.Union[str, t.Type["Extension"]]] = missing, + optimized: bool = missing, + undefined: t.Type[Undefined] = missing, + finalize: t.Optional[t.Callable[..., t.Any]] = missing, + autoescape: t.Union[bool, t.Callable[[t.Optional[str]], bool]] = missing, + loader: t.Optional["BaseLoader"] = missing, + cache_size: int = missing, + auto_reload: bool = missing, + bytecode_cache: t.Optional["BytecodeCache"] = missing, + enable_async: bool = False, + ) -> "Environment": + """Create a new overlay environment that shares all the data with the + current environment except for cache and the overridden attributes. + Extensions cannot be removed for an overlayed environment. An overlayed + environment automatically gets all the extensions of the environment it + is linked to plus optional extra extensions. + + Creating overlays should happen after the initial environment was set + up completely. Not all attributes are truly linked, some are just + copied over so modifications on the original environment may not shine + through. + + .. versionchanged:: 3.1.2 + Added the ``newline_sequence``,, ``keep_trailing_newline``, + and ``enable_async`` parameters to match ``__init__``. + """ + args = dict(locals()) + del args["self"], args["cache_size"], args["extensions"], args["enable_async"] + + rv = object.__new__(self.__class__) + rv.__dict__.update(self.__dict__) + rv.overlayed = True + rv.linked_to = self + + for key, value in args.items(): + if value is not missing: + setattr(rv, key, value) + + if cache_size is not missing: + rv.cache = create_cache(cache_size) + else: + rv.cache = copy_cache(self.cache) + + rv.extensions = {} + for key, value in self.extensions.items(): + rv.extensions[key] = value.bind(rv) + if extensions is not missing: + rv.extensions.update(load_extensions(rv, extensions)) + + if enable_async is not missing: + rv.is_async = enable_async + + return _environment_config_check(rv) + + @property + def lexer(self) -> Lexer: + """The lexer for this environment.""" + return get_lexer(self) + + def iter_extensions(self) -> t.Iterator["Extension"]: + """Iterates over the extensions by priority.""" + return iter(sorted(self.extensions.values(), key=lambda x: x.priority)) + + def getitem( + self, obj: t.Any, argument: t.Union[str, t.Any] + ) -> t.Union[t.Any, Undefined]: + """Get an item or attribute of an object but prefer the item.""" + try: + return obj[argument] + except (AttributeError, TypeError, LookupError): + if isinstance(argument, str): + try: + attr = str(argument) + except Exception: + pass + else: + try: + return getattr(obj, attr) + except AttributeError: + pass + return self.undefined(obj=obj, name=argument) + + def getattr(self, obj: t.Any, attribute: str) -> t.Any: + """Get an item or attribute of an object but prefer the attribute. + Unlike :meth:`getitem` the attribute *must* be a string. + """ + try: + return getattr(obj, attribute) + except AttributeError: + pass + try: + return obj[attribute] + except (TypeError, LookupError, AttributeError): + return self.undefined(obj=obj, name=attribute) + + def _filter_test_common( + self, + name: t.Union[str, Undefined], + value: t.Any, + args: t.Optional[t.Sequence[t.Any]], + kwargs: t.Optional[t.Mapping[str, t.Any]], + context: t.Optional[Context], + eval_ctx: t.Optional[EvalContext], + is_filter: bool, + ) -> t.Any: + if is_filter: + env_map = self.filters + type_name = "filter" + else: + env_map = self.tests + type_name = "test" + + func = env_map.get(name) # type: ignore + + if func is None: + msg = f"No {type_name} named {name!r}." + + if isinstance(name, Undefined): + try: + name._fail_with_undefined_error() + except Exception as e: + msg = f"{msg} ({e}; did you forget to quote the callable name?)" + + raise TemplateRuntimeError(msg) + + args = [value, *(args if args is not None else ())] + kwargs = kwargs if kwargs is not None else {} + pass_arg = _PassArg.from_obj(func) + + if pass_arg is _PassArg.context: + if context is None: + raise TemplateRuntimeError( + f"Attempted to invoke a context {type_name} without context." + ) + + args.insert(0, context) + elif pass_arg is _PassArg.eval_context: + if eval_ctx is None: + if context is not None: + eval_ctx = context.eval_ctx + else: + eval_ctx = EvalContext(self) + + args.insert(0, eval_ctx) + elif pass_arg is _PassArg.environment: + args.insert(0, self) + + return func(*args, **kwargs) + + def call_filter( + self, + name: str, + value: t.Any, + args: t.Optional[t.Sequence[t.Any]] = None, + kwargs: t.Optional[t.Mapping[str, t.Any]] = None, + context: t.Optional[Context] = None, + eval_ctx: t.Optional[EvalContext] = None, + ) -> t.Any: + """Invoke a filter on a value the same way the compiler does. + + This might return a coroutine if the filter is running from an + environment in async mode and the filter supports async + execution. It's your responsibility to await this if needed. + + .. versionadded:: 2.7 + """ + return self._filter_test_common( + name, value, args, kwargs, context, eval_ctx, True + ) + + def call_test( + self, + name: str, + value: t.Any, + args: t.Optional[t.Sequence[t.Any]] = None, + kwargs: t.Optional[t.Mapping[str, t.Any]] = None, + context: t.Optional[Context] = None, + eval_ctx: t.Optional[EvalContext] = None, + ) -> t.Any: + """Invoke a test on a value the same way the compiler does. + + This might return a coroutine if the test is running from an + environment in async mode and the test supports async execution. + It's your responsibility to await this if needed. + + .. versionchanged:: 3.0 + Tests support ``@pass_context``, etc. decorators. Added + the ``context`` and ``eval_ctx`` parameters. + + .. versionadded:: 2.7 + """ + return self._filter_test_common( + name, value, args, kwargs, context, eval_ctx, False + ) + + @internalcode + def parse( + self, + source: str, + name: t.Optional[str] = None, + filename: t.Optional[str] = None, + ) -> nodes.Template: + """Parse the sourcecode and return the abstract syntax tree. This + tree of nodes is used by the compiler to convert the template into + executable source- or bytecode. This is useful for debugging or to + extract information from templates. + + If you are :ref:`developing Jinja extensions ` + this gives you a good overview of the node tree generated. + """ + try: + return self._parse(source, name, filename) + except TemplateSyntaxError: + self.handle_exception(source=source) + + def _parse( + self, source: str, name: t.Optional[str], filename: t.Optional[str] + ) -> nodes.Template: + """Internal parsing function used by `parse` and `compile`.""" + return Parser(self, source, name, filename).parse() + + def lex( + self, + source: str, + name: t.Optional[str] = None, + filename: t.Optional[str] = None, + ) -> t.Iterator[t.Tuple[int, str, str]]: + """Lex the given sourcecode and return a generator that yields + tokens as tuples in the form ``(lineno, token_type, value)``. + This can be useful for :ref:`extension development ` + and debugging templates. + + This does not perform preprocessing. If you want the preprocessing + of the extensions to be applied you have to filter source through + the :meth:`preprocess` method. + """ + source = str(source) + try: + return self.lexer.tokeniter(source, name, filename) + except TemplateSyntaxError: + self.handle_exception(source=source) + + def preprocess( + self, + source: str, + name: t.Optional[str] = None, + filename: t.Optional[str] = None, + ) -> str: + """Preprocesses the source with all extensions. This is automatically + called for all parsing and compiling methods but *not* for :meth:`lex` + because there you usually only want the actual source tokenized. + """ + return reduce( + lambda s, e: e.preprocess(s, name, filename), + self.iter_extensions(), + str(source), + ) + + def _tokenize( + self, + source: str, + name: t.Optional[str], + filename: t.Optional[str] = None, + state: t.Optional[str] = None, + ) -> TokenStream: + """Called by the parser to do the preprocessing and filtering + for all the extensions. Returns a :class:`~jinja2.lexer.TokenStream`. + """ + source = self.preprocess(source, name, filename) + stream = self.lexer.tokenize(source, name, filename, state) + + for ext in self.iter_extensions(): + stream = ext.filter_stream(stream) # type: ignore + + if not isinstance(stream, TokenStream): + stream = TokenStream(stream, name, filename) # type: ignore + + return stream + + def _generate( + self, + source: nodes.Template, + name: t.Optional[str], + filename: t.Optional[str], + defer_init: bool = False, + ) -> str: + """Internal hook that can be overridden to hook a different generate + method in. + + .. versionadded:: 2.5 + """ + return generate( # type: ignore + source, + self, + name, + filename, + defer_init=defer_init, + optimized=self.optimized, + ) + + def _compile(self, source: str, filename: str) -> CodeType: + """Internal hook that can be overridden to hook a different compile + method in. + + .. versionadded:: 2.5 + """ + return compile(source, filename, "exec") # type: ignore + + @typing.overload + def compile( # type: ignore + self, + source: t.Union[str, nodes.Template], + name: t.Optional[str] = None, + filename: t.Optional[str] = None, + raw: "te.Literal[False]" = False, + defer_init: bool = False, + ) -> CodeType: + ... + + @typing.overload + def compile( + self, + source: t.Union[str, nodes.Template], + name: t.Optional[str] = None, + filename: t.Optional[str] = None, + raw: "te.Literal[True]" = ..., + defer_init: bool = False, + ) -> str: + ... + + @internalcode + def compile( + self, + source: t.Union[str, nodes.Template], + name: t.Optional[str] = None, + filename: t.Optional[str] = None, + raw: bool = False, + defer_init: bool = False, + ) -> t.Union[str, CodeType]: + """Compile a node or template source code. The `name` parameter is + the load name of the template after it was joined using + :meth:`join_path` if necessary, not the filename on the file system. + the `filename` parameter is the estimated filename of the template on + the file system. If the template came from a database or memory this + can be omitted. + + The return value of this method is a python code object. If the `raw` + parameter is `True` the return value will be a string with python + code equivalent to the bytecode returned otherwise. This method is + mainly used internally. + + `defer_init` is use internally to aid the module code generator. This + causes the generated code to be able to import without the global + environment variable to be set. + + .. versionadded:: 2.4 + `defer_init` parameter added. + """ + source_hint = None + try: + if isinstance(source, str): + source_hint = source + source = self._parse(source, name, filename) + source = self._generate(source, name, filename, defer_init=defer_init) + if raw: + return source + if filename is None: + filename = "