diff --git a/.gitattributes b/.gitattributes index f6bee6b297f41fbb74dc4488c5df67802ac70c78..191d6d1e1a04642e928056c8c3d6ee15e8c4dc4d 100644 --- a/.gitattributes +++ b/.gitattributes @@ -226,3 +226,9 @@ my_container_sandbox/workspace/anaconda3/lib/python3.8/lib-dynload/_sha3.cpython my_container_sandbox/workspace/anaconda3/lib/python3.8/lib-dynload/_codecs_jp.cpython-38-x86_64-linux-gnu.so filter=lfs diff=lfs merge=lfs -text my_container_sandbox/workspace/anaconda3/lib/python3.8/lib-dynload/_decimal.cpython-38-x86_64-linux-gnu.so filter=lfs diff=lfs merge=lfs -text my_container_sandbox/workspace/anaconda3/lib/python3.8/lib-dynload/readline.cpython-38-x86_64-linux-gnu.so filter=lfs diff=lfs merge=lfs -text +my_container_sandbox/workspace/anaconda3/lib/python3.8/lib-dynload/_tkinter.cpython-38-x86_64-linux-gnu.so filter=lfs diff=lfs merge=lfs -text +my_container_sandbox/workspace/anaconda3/lib/python3.8/lib-dynload/mmap.cpython-38-x86_64-linux-gnu.so filter=lfs diff=lfs merge=lfs -text +my_container_sandbox/workspace/anaconda3/lib/python3.8/lib-dynload/_csv.cpython-38-x86_64-linux-gnu.so filter=lfs diff=lfs merge=lfs -text +my_container_sandbox/workspace/anaconda3/lib/python3.8/lib-dynload/unicodedata.cpython-38-x86_64-linux-gnu.so filter=lfs diff=lfs merge=lfs -text +my_container_sandbox/workspace/anaconda3/lib/python3.8/lib-dynload/math.cpython-38-x86_64-linux-gnu.so filter=lfs diff=lfs merge=lfs -text +my_container_sandbox/workspace/anaconda3/bin/x86_64-conda_cos6-linux-gnu-ld filter=lfs diff=lfs merge=lfs -text diff --git a/my_container_sandbox/workspace/anaconda3/bin/x86_64-conda_cos6-linux-gnu-ld b/my_container_sandbox/workspace/anaconda3/bin/x86_64-conda_cos6-linux-gnu-ld new file mode 100644 index 0000000000000000000000000000000000000000..747afe305838363c49f9a2cbcdfb40ff2e717d3d --- /dev/null +++ b/my_container_sandbox/workspace/anaconda3/bin/x86_64-conda_cos6-linux-gnu-ld @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:db98363adc9b1f3f785009e63bc77617093f5841ce0736b0407fc4bf66a30ab9 +size 2568888 diff --git a/my_container_sandbox/workspace/anaconda3/lib/python3.8/lib-dynload/_csv.cpython-38-x86_64-linux-gnu.so b/my_container_sandbox/workspace/anaconda3/lib/python3.8/lib-dynload/_csv.cpython-38-x86_64-linux-gnu.so new file mode 100644 index 0000000000000000000000000000000000000000..1d0003e2c42e8a14216492152e758068ef27b20a --- /dev/null +++ b/my_container_sandbox/workspace/anaconda3/lib/python3.8/lib-dynload/_csv.cpython-38-x86_64-linux-gnu.so @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b589b745b5e75b99f3e76ced322e018482546477129c6a26ab08d1634b2b2cfe +size 121936 diff --git a/my_container_sandbox/workspace/anaconda3/lib/python3.8/lib-dynload/_tkinter.cpython-38-x86_64-linux-gnu.so b/my_container_sandbox/workspace/anaconda3/lib/python3.8/lib-dynload/_tkinter.cpython-38-x86_64-linux-gnu.so new file mode 100644 index 0000000000000000000000000000000000000000..24036a760c2339bfcdfc28047565a140f132eb6b --- /dev/null +++ b/my_container_sandbox/workspace/anaconda3/lib/python3.8/lib-dynload/_tkinter.cpython-38-x86_64-linux-gnu.so @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:832b13f4e094686c809adb072054d79139f80531479ab8dd90efe991c76d1691 +size 221992 diff --git a/my_container_sandbox/workspace/anaconda3/lib/python3.8/lib-dynload/math.cpython-38-x86_64-linux-gnu.so b/my_container_sandbox/workspace/anaconda3/lib/python3.8/lib-dynload/math.cpython-38-x86_64-linux-gnu.so new file mode 100644 index 0000000000000000000000000000000000000000..93c72a3d93641303bcff0aa363e9a46d62d7788c --- /dev/null +++ b/my_container_sandbox/workspace/anaconda3/lib/python3.8/lib-dynload/math.cpython-38-x86_64-linux-gnu.so @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6788eb7b2bc17778d5694e2d0100dd6c74e955f0740c55f48f8da2c997ba2420 +size 253424 diff --git a/my_container_sandbox/workspace/anaconda3/lib/python3.8/lib-dynload/mmap.cpython-38-x86_64-linux-gnu.so b/my_container_sandbox/workspace/anaconda3/lib/python3.8/lib-dynload/mmap.cpython-38-x86_64-linux-gnu.so new file mode 100644 index 0000000000000000000000000000000000000000..82f5a5eebfea125735c80f9d801cb497d2b7b3ac --- /dev/null +++ b/my_container_sandbox/workspace/anaconda3/lib/python3.8/lib-dynload/mmap.cpython-38-x86_64-linux-gnu.so @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:58be3da0f728647b97e53afa534e95e42ac7731b8cb014371d0f53eee118ac3f +size 104664 diff --git a/my_container_sandbox/workspace/anaconda3/lib/python3.8/lib-dynload/unicodedata.cpython-38-x86_64-linux-gnu.so b/my_container_sandbox/workspace/anaconda3/lib/python3.8/lib-dynload/unicodedata.cpython-38-x86_64-linux-gnu.so new file mode 100644 index 0000000000000000000000000000000000000000..86b7734e9467a0c4602555a7c57a463c3139c932 --- /dev/null +++ b/my_container_sandbox/workspace/anaconda3/lib/python3.8/lib-dynload/unicodedata.cpython-38-x86_64-linux-gnu.so @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a4a47c7a22336b3de31509eaa3e60a65daf3d486a1deef81610fc2f3d163eb0c +size 1170032 diff --git a/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/attrs-21.4.0.dist-info/METADATA b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/attrs-21.4.0.dist-info/METADATA new file mode 100644 index 0000000000000000000000000000000000000000..aa327d5e1ff6719f482b9ec32961ae4b6de6304b --- /dev/null +++ b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/attrs-21.4.0.dist-info/METADATA @@ -0,0 +1,232 @@ +Metadata-Version: 2.1 +Name: attrs +Version: 21.4.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 +Platform: UNKNOWN +Classifier: Development Status :: 5 - Production/Stable +Classifier: Intended Audience :: Developers +Classifier: Natural Language :: English +Classifier: License :: OSI Approved :: MIT License +Classifier: Operating System :: OS Independent +Classifier: Programming Language :: Python +Classifier: Programming Language :: Python :: 2 +Classifier: Programming Language :: Python :: 2.7 +Classifier: Programming Language :: Python :: 3 +Classifier: Programming Language :: Python :: 3.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: Topic :: Software Development :: Libraries :: Python Modules +Requires-Python: >=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.* +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: six ; extra == 'dev' +Requires-Dist: mypy ; 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: six ; extra == 'tests' +Requires-Dist: mypy ; 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: six ; extra == 'tests_no_zope' +Requires-Dist: mypy ; 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__``, +- a 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 `_. + + +.. -getting-help- + +Getting Help +============ + +Please use the ``python-attrs`` tag on `Stack Overflow `_ to get help. + +Answering questions of your fellow developers is also a great way to help the project! + + +.. -project-information- + +Project Information +=================== + +``attrs`` is released under the `MIT `_ license, +its documentation lives at `Read the Docs `_, +the code on `GitHub `_, +and the latest release on `PyPI `_. +It’s rigorously tested on Python 2.7, 3.5+, and PyPy. + +We collect information on **third-party extensions** in our `wiki `_. +Feel free to browse and add your own! + +If you'd like to contribute to ``attrs`` you're most welcome and we've written `a little guide `_ to get you started! + + +``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 +=================== + +21.4.0 (2021-12-29) +------------------- + +Changes +^^^^^^^ + +- Fixed the test suite on PyPy3.8 where ``cloudpickle`` does not work. + `#892 `_ +- Fixed ``coverage report`` for projects that use ``attrs`` and don't set a ``--source``. + `#895 `_, + `#896 `_ + +`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/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/attrs-21.4.0.dist-info/RECORD b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/attrs-21.4.0.dist-info/RECORD new file mode 100644 index 0000000000000000000000000000000000000000..8269ec45f8cc78cad87cbdec330d7030b786940d --- /dev/null +++ b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/attrs-21.4.0.dist-info/RECORD @@ -0,0 +1,57 @@ +attr/__init__.py,sha256=_zhJ4O8Q5KR5gaIrjX73vkR5nA6NjfpMGXQChEdNljI,1667 +attr/__init__.pyi,sha256=ubRkstoRHPpQN17iA0OCh8waIwZ5NeJgbz0lwI8XUjY,15100 +attr/__pycache__/__init__.cpython-38.pyc,, +attr/__pycache__/_cmp.cpython-38.pyc,, +attr/__pycache__/_compat.cpython-38.pyc,, +attr/__pycache__/_config.cpython-38.pyc,, +attr/__pycache__/_funcs.cpython-38.pyc,, +attr/__pycache__/_make.cpython-38.pyc,, +attr/__pycache__/_next_gen.cpython-38.pyc,, +attr/__pycache__/_version_info.cpython-38.pyc,, +attr/__pycache__/converters.cpython-38.pyc,, +attr/__pycache__/exceptions.cpython-38.pyc,, +attr/__pycache__/filters.cpython-38.pyc,, +attr/__pycache__/setters.cpython-38.pyc,, +attr/__pycache__/validators.cpython-38.pyc,, +attr/_cmp.py,sha256=JP0N7OIyTqIR3prUDfMZOR4DV4tlV_xXf39-bQg7xOo,4165 +attr/_cmp.pyi,sha256=oyjJVytrwwkUJOoe332IiYzp6pCVZEKKcKveH-ev604,317 +attr/_compat.py,sha256=i8u27AAK_4SzQnmTf3aliGV27UdYbJxdZ-O0tOHbLU8,8396 +attr/_config.py,sha256=aj1Lh8t2CuVa5nSxgCrLQtg_ZSdO8ZKeNJQd6RvpIp8,892 +attr/_funcs.py,sha256=sm_D12y2IyRW_bCnR7M-O7U5qHaieXr0BzINwJ7_K38,14753 +attr/_make.py,sha256=D05j0_ckcVIRFn2xHch5SPUCwh3t7WpeFj-3Ku9SocQ,102736 +attr/_next_gen.py,sha256=s5jCsVEQ4IhOjAykP4N0ETaWpg0RsgQttMvEZErUrhQ,5752 +attr/_version_info.py,sha256=sxD9yNai0jGbur_-RGEQHbgV2YX5_5G9PhrhBA5pA54,2194 +attr/_version_info.pyi,sha256=x_M3L3WuB7r_ULXAWjx959udKQ4HLB8l-hsc1FDGNvk,209 +attr/converters.py,sha256=uiiWTz8GLJe8I1Ty7UICK1DegVUnqHTXbOSnar7g7Nk,4078 +attr/converters.pyi,sha256=MQo7iEzPNVoFpKqD30sVwgVpdNoIeSCF2nsXvoxLZ-Y,416 +attr/exceptions.py,sha256=BMg7AljkJnvG-irMwL2TBHYlaLBXhSKnzoEWo4e42Zw,1981 +attr/exceptions.pyi,sha256=zZq8bCUnKAy9mDtBEw42ZhPhAUIHoTKedDQInJD883M,539 +attr/filters.py,sha256=JGZgvPGkdOfttkoL6XhXS6ZCoaVV5nZ8GCYeZNUN_mE,1124 +attr/filters.pyi,sha256=_Sm80jGySETX_Clzdkon5NHVjQWRl3Y3liQKZX1czXc,215 +attr/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +attr/setters.py,sha256=rH_UtQuHgQEC7hfZyMO_SJW0R1Gus7-a83U8igZfqs8,1466 +attr/setters.pyi,sha256=7dM10rqpQVDW0y-iJUnq8rabdO5Wx2Sbo5LwNa0IXl0,573 +attr/validators.py,sha256=jVE9roaSOmTf0dJNSLHNaQNilkrlzc3pNNBKmv0g7pk,15966 +attr/validators.pyi,sha256=adn6rNbIXmRXlg_FKrTmWj0dOX0vKTsGG82Jd3YcJbQ,2268 +attrs-21.4.0.dist-info/AUTHORS.rst,sha256=wsqCNbGz_mklcJrt54APIZHZpoTIJLkXqEhhn4Nd8hc,752 +attrs-21.4.0.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +attrs-21.4.0.dist-info/LICENSE,sha256=v2WaKLSSQGAvVrvfSQy-LsUJsVuY-Z17GaUsdA4yeGM,1082 +attrs-21.4.0.dist-info/METADATA,sha256=WwgR4MfxE55PpGGv21UOEOEtXZGCqwekfXYg-JgA5HY,9810 +attrs-21.4.0.dist-info/RECORD,, +attrs-21.4.0.dist-info/REQUESTED,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +attrs-21.4.0.dist-info/WHEEL,sha256=z9j0xAa_JmUKMpmz72K0ZGALSM_n-wQVmGbleXx2VHg,110 +attrs-21.4.0.dist-info/top_level.txt,sha256=AGbmKnOtYpdkLRsDRQVSBIwfL32pAQ6BSo1mt-BxI7M,11 +attrs/__init__.py,sha256=CeyxLGVViAEKKsLOLaif8vF3vs1a28vsrRVLv7eMEgM,1109 +attrs/__init__.pyi,sha256=57aCxUJukK9lZlrUgk9RuWiBiPY5DzDKJAJkhbrStYw,1982 +attrs/__pycache__/__init__.cpython-38.pyc,, +attrs/__pycache__/converters.cpython-38.pyc,, +attrs/__pycache__/exceptions.cpython-38.pyc,, +attrs/__pycache__/filters.cpython-38.pyc,, +attrs/__pycache__/setters.cpython-38.pyc,, +attrs/__pycache__/validators.cpython-38.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/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/attrs-21.4.0.dist-info/WHEEL b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/attrs-21.4.0.dist-info/WHEEL new file mode 100644 index 0000000000000000000000000000000000000000..0b18a281107a0448a9980396d9d324ea2aa7a7f8 --- /dev/null +++ b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/attrs-21.4.0.dist-info/WHEEL @@ -0,0 +1,6 @@ +Wheel-Version: 1.0 +Generator: bdist_wheel (0.37.1) +Root-Is-Purelib: true +Tag: py2-none-any +Tag: py3-none-any + diff --git a/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/attrs-21.4.0.dist-info/top_level.txt b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/attrs-21.4.0.dist-info/top_level.txt new file mode 100644 index 0000000000000000000000000000000000000000..eca8ba9f00d076427ffa86447222830fef60693d --- /dev/null +++ b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/attrs-21.4.0.dist-info/top_level.txt @@ -0,0 +1,2 @@ +attr +attrs diff --git a/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/click/_termui_impl.py b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/click/_termui_impl.py new file mode 100644 index 0000000000000000000000000000000000000000..4b979bcc1edcb33feb9b385156492221d92253dc --- /dev/null +++ b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/click/_termui_impl.py @@ -0,0 +1,717 @@ +""" +This module contains implementations for the termui module. To keep the +import time of Click down, some infrequently used functionality is +placed in this module and only imported as needed. +""" +import contextlib +import math +import os +import sys +import time +import typing as t +from gettext import gettext as _ + +from ._compat import _default_text_stdout +from ._compat import CYGWIN +from ._compat import get_best_encoding +from ._compat import isatty +from ._compat import open_stream +from ._compat import strip_ansi +from ._compat import term_len +from ._compat import WIN +from .exceptions import ClickException +from .utils import echo + +V = t.TypeVar("V") + +if os.name == "nt": + BEFORE_BAR = "\r" + AFTER_BAR = "\n" +else: + BEFORE_BAR = "\r\033[?25l" + AFTER_BAR = "\033[?25h\n" + + +class ProgressBar(t.Generic[V]): + def __init__( + self, + iterable: t.Optional[t.Iterable[V]], + length: t.Optional[int] = None, + fill_char: str = "#", + empty_char: str = " ", + bar_template: str = "%(bar)s", + info_sep: str = " ", + show_eta: bool = True, + show_percent: t.Optional[bool] = None, + show_pos: bool = False, + item_show_func: t.Optional[t.Callable[[t.Optional[V]], t.Optional[str]]] = None, + label: t.Optional[str] = None, + file: t.Optional[t.TextIO] = None, + color: t.Optional[bool] = None, + update_min_steps: int = 1, + width: int = 30, + ) -> None: + self.fill_char = fill_char + self.empty_char = empty_char + self.bar_template = bar_template + self.info_sep = info_sep + self.show_eta = show_eta + self.show_percent = show_percent + self.show_pos = show_pos + self.item_show_func = item_show_func + self.label = label or "" + if file is None: + file = _default_text_stdout() + self.file = file + self.color = color + self.update_min_steps = update_min_steps + self._completed_intervals = 0 + self.width = width + self.autowidth = width == 0 + + if length is None: + from operator import length_hint + + length = length_hint(iterable, -1) + + if length == -1: + length = None + if iterable is None: + if length is None: + raise TypeError("iterable or length is required") + iterable = t.cast(t.Iterable[V], range(length)) + self.iter = iter(iterable) + self.length = length + self.pos = 0 + self.avg: t.List[float] = [] + self.start = self.last_eta = time.time() + self.eta_known = False + self.finished = False + self.max_width: t.Optional[int] = None + self.entered = False + self.current_item: t.Optional[V] = None + self.is_hidden = not isatty(self.file) + self._last_line: t.Optional[str] = None + + def __enter__(self) -> "ProgressBar": + self.entered = True + self.render_progress() + return self + + def __exit__(self, exc_type, exc_value, tb): # type: ignore + self.render_finish() + + def __iter__(self) -> t.Iterator[V]: + if not self.entered: + raise RuntimeError("You need to use progress bars in a with block.") + self.render_progress() + return self.generator() + + def __next__(self) -> V: + # Iteration is defined in terms of a generator function, + # returned by iter(self); use that to define next(). This works + # because `self.iter` is an iterable consumed by that generator, + # so it is re-entry safe. Calling `next(self.generator())` + # twice works and does "what you want". + return next(iter(self)) + + def render_finish(self) -> None: + if self.is_hidden: + return + self.file.write(AFTER_BAR) + self.file.flush() + + @property + def pct(self) -> float: + if self.finished: + return 1.0 + return min(self.pos / (float(self.length or 1) or 1), 1.0) + + @property + def time_per_iteration(self) -> float: + if not self.avg: + return 0.0 + return sum(self.avg) / float(len(self.avg)) + + @property + def eta(self) -> float: + if self.length is not None and not self.finished: + return self.time_per_iteration * (self.length - self.pos) + return 0.0 + + def format_eta(self) -> str: + if self.eta_known: + t = int(self.eta) + seconds = t % 60 + t //= 60 + minutes = t % 60 + t //= 60 + hours = t % 24 + t //= 24 + if t > 0: + return f"{t}d {hours:02}:{minutes:02}:{seconds:02}" + else: + return f"{hours:02}:{minutes:02}:{seconds:02}" + return "" + + def format_pos(self) -> str: + pos = str(self.pos) + if self.length is not None: + pos += f"/{self.length}" + return pos + + def format_pct(self) -> str: + return f"{int(self.pct * 100): 4}%"[1:] + + def format_bar(self) -> str: + if self.length is not None: + bar_length = int(self.pct * self.width) + bar = self.fill_char * bar_length + bar += self.empty_char * (self.width - bar_length) + elif self.finished: + bar = self.fill_char * self.width + else: + chars = list(self.empty_char * (self.width or 1)) + if self.time_per_iteration != 0: + chars[ + int( + (math.cos(self.pos * self.time_per_iteration) / 2.0 + 0.5) + * self.width + ) + ] = self.fill_char + bar = "".join(chars) + return bar + + def format_progress_line(self) -> str: + show_percent = self.show_percent + + info_bits = [] + if self.length is not None and show_percent is None: + show_percent = not self.show_pos + + if self.show_pos: + info_bits.append(self.format_pos()) + if show_percent: + info_bits.append(self.format_pct()) + if self.show_eta and self.eta_known and not self.finished: + info_bits.append(self.format_eta()) + if self.item_show_func is not None: + item_info = self.item_show_func(self.current_item) + if item_info is not None: + info_bits.append(item_info) + + return ( + self.bar_template + % { + "label": self.label, + "bar": self.format_bar(), + "info": self.info_sep.join(info_bits), + } + ).rstrip() + + def render_progress(self) -> None: + import shutil + + if self.is_hidden: + # Only output the label as it changes if the output is not a + # TTY. Use file=stderr if you expect to be piping stdout. + if self._last_line != self.label: + self._last_line = self.label + echo(self.label, file=self.file, color=self.color) + + return + + buf = [] + # Update width in case the terminal has been resized + if self.autowidth: + old_width = self.width + self.width = 0 + clutter_length = term_len(self.format_progress_line()) + new_width = max(0, shutil.get_terminal_size().columns - clutter_length) + if new_width < old_width: + buf.append(BEFORE_BAR) + buf.append(" " * self.max_width) # type: ignore + self.max_width = new_width + self.width = new_width + + clear_width = self.width + if self.max_width is not None: + clear_width = self.max_width + + buf.append(BEFORE_BAR) + line = self.format_progress_line() + line_len = term_len(line) + if self.max_width is None or self.max_width < line_len: + self.max_width = line_len + + buf.append(line) + buf.append(" " * (clear_width - line_len)) + line = "".join(buf) + # Render the line only if it changed. + + if line != self._last_line: + self._last_line = line + echo(line, file=self.file, color=self.color, nl=False) + self.file.flush() + + def make_step(self, n_steps: int) -> None: + self.pos += n_steps + if self.length is not None and self.pos >= self.length: + self.finished = True + + if (time.time() - self.last_eta) < 1.0: + return + + self.last_eta = time.time() + + # self.avg is a rolling list of length <= 7 of steps where steps are + # defined as time elapsed divided by the total progress through + # self.length. + if self.pos: + step = (time.time() - self.start) / self.pos + else: + step = time.time() - self.start + + self.avg = self.avg[-6:] + [step] + + self.eta_known = self.length is not None + + def update(self, n_steps: int, current_item: t.Optional[V] = None) -> None: + """Update the progress bar by advancing a specified number of + steps, and optionally set the ``current_item`` for this new + position. + + :param n_steps: Number of steps to advance. + :param current_item: Optional item to set as ``current_item`` + for the updated position. + + .. versionchanged:: 8.0 + Added the ``current_item`` optional parameter. + + .. versionchanged:: 8.0 + Only render when the number of steps meets the + ``update_min_steps`` threshold. + """ + if current_item is not None: + self.current_item = current_item + + self._completed_intervals += n_steps + + if self._completed_intervals >= self.update_min_steps: + self.make_step(self._completed_intervals) + self.render_progress() + self._completed_intervals = 0 + + def finish(self) -> None: + self.eta_known = False + self.current_item = None + self.finished = True + + def generator(self) -> t.Iterator[V]: + """Return a generator which yields the items added to the bar + during construction, and updates the progress bar *after* the + yielded block returns. + """ + # WARNING: the iterator interface for `ProgressBar` relies on + # this and only works because this is a simple generator which + # doesn't create or manage additional state. If this function + # changes, the impact should be evaluated both against + # `iter(bar)` and `next(bar)`. `next()` in particular may call + # `self.generator()` repeatedly, and this must remain safe in + # order for that interface to work. + if not self.entered: + raise RuntimeError("You need to use progress bars in a with block.") + + if self.is_hidden: + yield from self.iter + else: + for rv in self.iter: + self.current_item = rv + + # This allows show_item_func to be updated before the + # item is processed. Only trigger at the beginning of + # the update interval. + if self._completed_intervals == 0: + self.render_progress() + + yield rv + self.update(1) + + self.finish() + self.render_progress() + + +def pager(generator: t.Iterable[str], color: t.Optional[bool] = None) -> None: + """Decide what method to use for paging through text.""" + stdout = _default_text_stdout() + if not isatty(sys.stdin) or not isatty(stdout): + return _nullpager(stdout, generator, color) + pager_cmd = (os.environ.get("PAGER", None) or "").strip() + if pager_cmd: + if WIN: + return _tempfilepager(generator, pager_cmd, color) + return _pipepager(generator, pager_cmd, color) + if os.environ.get("TERM") in ("dumb", "emacs"): + return _nullpager(stdout, generator, color) + if WIN or sys.platform.startswith("os2"): + return _tempfilepager(generator, "more <", color) + if hasattr(os, "system") and os.system("(less) 2>/dev/null") == 0: + return _pipepager(generator, "less", color) + + import tempfile + + fd, filename = tempfile.mkstemp() + os.close(fd) + try: + if hasattr(os, "system") and os.system(f'more "{filename}"') == 0: + return _pipepager(generator, "more", color) + return _nullpager(stdout, generator, color) + finally: + os.unlink(filename) + + +def _pipepager(generator: t.Iterable[str], cmd: str, color: t.Optional[bool]) -> None: + """Page through text by feeding it to another program. Invoking a + pager through this might support colors. + """ + import subprocess + + env = dict(os.environ) + + # If we're piping to less we might support colors under the + # condition that + cmd_detail = cmd.rsplit("/", 1)[-1].split() + if color is None and cmd_detail[0] == "less": + less_flags = f"{os.environ.get('LESS', '')}{' '.join(cmd_detail[1:])}" + if not less_flags: + env["LESS"] = "-R" + color = True + elif "r" in less_flags or "R" in less_flags: + color = True + + c = subprocess.Popen(cmd, shell=True, stdin=subprocess.PIPE, env=env) + stdin = t.cast(t.BinaryIO, c.stdin) + encoding = get_best_encoding(stdin) + try: + for text in generator: + if not color: + text = strip_ansi(text) + + stdin.write(text.encode(encoding, "replace")) + except (OSError, KeyboardInterrupt): + pass + else: + stdin.close() + + # Less doesn't respect ^C, but catches it for its own UI purposes (aborting + # search or other commands inside less). + # + # That means when the user hits ^C, the parent process (click) terminates, + # but less is still alive, paging the output and messing up the terminal. + # + # If the user wants to make the pager exit on ^C, they should set + # `LESS='-K'`. It's not our decision to make. + while True: + try: + c.wait() + except KeyboardInterrupt: + pass + else: + break + + +def _tempfilepager( + generator: t.Iterable[str], cmd: str, color: t.Optional[bool] +) -> None: + """Page through text by invoking a program on a temporary file.""" + import tempfile + + fd, filename = tempfile.mkstemp() + # TODO: This never terminates if the passed generator never terminates. + text = "".join(generator) + if not color: + text = strip_ansi(text) + encoding = get_best_encoding(sys.stdout) + with open_stream(filename, "wb")[0] as f: + f.write(text.encode(encoding)) + try: + os.system(f'{cmd} "{filename}"') + finally: + os.close(fd) + os.unlink(filename) + + +def _nullpager( + stream: t.TextIO, generator: t.Iterable[str], color: t.Optional[bool] +) -> None: + """Simply print unformatted text. This is the ultimate fallback.""" + for text in generator: + if not color: + text = strip_ansi(text) + stream.write(text) + + +class Editor: + def __init__( + self, + editor: t.Optional[str] = None, + env: t.Optional[t.Mapping[str, str]] = None, + require_save: bool = True, + extension: str = ".txt", + ) -> None: + self.editor = editor + self.env = env + self.require_save = require_save + self.extension = extension + + def get_editor(self) -> str: + if self.editor is not None: + return self.editor + for key in "VISUAL", "EDITOR": + rv = os.environ.get(key) + if rv: + return rv + if WIN: + return "notepad" + for editor in "sensible-editor", "vim", "nano": + if os.system(f"which {editor} >/dev/null 2>&1") == 0: + return editor + return "vi" + + def edit_file(self, filename: str) -> None: + import subprocess + + editor = self.get_editor() + environ: t.Optional[t.Dict[str, str]] = None + + if self.env: + environ = os.environ.copy() + environ.update(self.env) + + try: + c = subprocess.Popen(f'{editor} "{filename}"', env=environ, shell=True) + exit_code = c.wait() + if exit_code != 0: + raise ClickException( + _("{editor}: Editing failed").format(editor=editor) + ) + except OSError as e: + raise ClickException( + _("{editor}: Editing failed: {e}").format(editor=editor, e=e) + ) from e + + def edit(self, text: t.Optional[t.AnyStr]) -> t.Optional[t.AnyStr]: + import tempfile + + if not text: + data = b"" + elif isinstance(text, (bytes, bytearray)): + data = text + else: + if text and not text.endswith("\n"): + text += "\n" + + if WIN: + data = text.replace("\n", "\r\n").encode("utf-8-sig") + else: + data = text.encode("utf-8") + + fd, name = tempfile.mkstemp(prefix="editor-", suffix=self.extension) + f: t.BinaryIO + + try: + with os.fdopen(fd, "wb") as f: + f.write(data) + + # If the filesystem resolution is 1 second, like Mac OS + # 10.12 Extended, or 2 seconds, like FAT32, and the editor + # closes very fast, require_save can fail. Set the modified + # time to be 2 seconds in the past to work around this. + os.utime(name, (os.path.getatime(name), os.path.getmtime(name) - 2)) + # Depending on the resolution, the exact value might not be + # recorded, so get the new recorded value. + timestamp = os.path.getmtime(name) + + self.edit_file(name) + + if self.require_save and os.path.getmtime(name) == timestamp: + return None + + with open(name, "rb") as f: + rv = f.read() + + if isinstance(text, (bytes, bytearray)): + return rv + + return rv.decode("utf-8-sig").replace("\r\n", "\n") # type: ignore + finally: + os.unlink(name) + + +def open_url(url: str, wait: bool = False, locate: bool = False) -> int: + import subprocess + + def _unquote_file(url: str) -> str: + from urllib.parse import unquote + + if url.startswith("file://"): + url = unquote(url[7:]) + + return url + + if sys.platform == "darwin": + args = ["open"] + if wait: + args.append("-W") + if locate: + args.append("-R") + args.append(_unquote_file(url)) + null = open("/dev/null", "w") + try: + return subprocess.Popen(args, stderr=null).wait() + finally: + null.close() + elif WIN: + if locate: + url = _unquote_file(url.replace('"', "")) + args = f'explorer /select,"{url}"' + else: + url = url.replace('"', "") + wait_str = "/WAIT" if wait else "" + args = f'start {wait_str} "" "{url}"' + return os.system(args) + elif CYGWIN: + if locate: + url = os.path.dirname(_unquote_file(url).replace('"', "")) + args = f'cygstart "{url}"' + else: + url = url.replace('"', "") + wait_str = "-w" if wait else "" + args = f'cygstart {wait_str} "{url}"' + return os.system(args) + + try: + if locate: + url = os.path.dirname(_unquote_file(url)) or "." + else: + url = _unquote_file(url) + c = subprocess.Popen(["xdg-open", url]) + if wait: + return c.wait() + return 0 + except OSError: + if url.startswith(("http://", "https://")) and not locate and not wait: + import webbrowser + + webbrowser.open(url) + return 0 + return 1 + + +def _translate_ch_to_exc(ch: str) -> t.Optional[BaseException]: + if ch == "\x03": + raise KeyboardInterrupt() + + if ch == "\x04" and not WIN: # Unix-like, Ctrl+D + raise EOFError() + + if ch == "\x1a" and WIN: # Windows, Ctrl+Z + raise EOFError() + + return None + + +if WIN: + import msvcrt + + @contextlib.contextmanager + def raw_terminal() -> t.Iterator[int]: + yield -1 + + def getchar(echo: bool) -> str: + # The function `getch` will return a bytes object corresponding to + # the pressed character. Since Windows 10 build 1803, it will also + # return \x00 when called a second time after pressing a regular key. + # + # `getwch` does not share this probably-bugged behavior. Moreover, it + # returns a Unicode object by default, which is what we want. + # + # Either of these functions will return \x00 or \xe0 to indicate + # a special key, and you need to call the same function again to get + # the "rest" of the code. The fun part is that \u00e0 is + # "latin small letter a with grave", so if you type that on a French + # keyboard, you _also_ get a \xe0. + # E.g., consider the Up arrow. This returns \xe0 and then \x48. The + # resulting Unicode string reads as "a with grave" + "capital H". + # This is indistinguishable from when the user actually types + # "a with grave" and then "capital H". + # + # When \xe0 is returned, we assume it's part of a special-key sequence + # and call `getwch` again, but that means that when the user types + # the \u00e0 character, `getchar` doesn't return until a second + # character is typed. + # The alternative is returning immediately, but that would mess up + # cross-platform handling of arrow keys and others that start with + # \xe0. Another option is using `getch`, but then we can't reliably + # read non-ASCII characters, because return values of `getch` are + # limited to the current 8-bit codepage. + # + # Anyway, Click doesn't claim to do this Right(tm), and using `getwch` + # is doing the right thing in more situations than with `getch`. + func: t.Callable[[], str] + + if echo: + func = msvcrt.getwche # type: ignore + else: + func = msvcrt.getwch # type: ignore + + rv = func() + + if rv in ("\x00", "\xe0"): + # \x00 and \xe0 are control characters that indicate special key, + # see above. + rv += func() + + _translate_ch_to_exc(rv) + return rv + +else: + import tty + import termios + + @contextlib.contextmanager + def raw_terminal() -> t.Iterator[int]: + f: t.Optional[t.TextIO] + fd: int + + if not isatty(sys.stdin): + f = open("/dev/tty") + fd = f.fileno() + else: + fd = sys.stdin.fileno() + f = None + + try: + old_settings = termios.tcgetattr(fd) + + try: + tty.setraw(fd) + yield fd + finally: + termios.tcsetattr(fd, termios.TCSADRAIN, old_settings) + sys.stdout.flush() + + if f is not None: + f.close() + except termios.error: + pass + + def getchar(echo: bool) -> str: + with raw_terminal() as fd: + ch = os.read(fd, 32).decode(get_best_encoding(sys.stdin), "replace") + + if echo and isatty(sys.stdout): + sys.stdout.write(ch) + + _translate_ch_to_exc(ch) + return ch diff --git a/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/google_auth-2.9.0-py3.10-nspkg.pth b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/google_auth-2.9.0-py3.10-nspkg.pth new file mode 100644 index 0000000000000000000000000000000000000000..e66daf5af3d0e509b4735d7c3d2810f265b2e76a --- /dev/null +++ b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/google_auth-2.9.0-py3.10-nspkg.pth @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c47e604f1738522a583f7aab6cffb80821cd18157dede051e10aa185e0af065e +size 539 diff --git a/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/grpc/__init__.py b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/grpc/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..bc645e5750e55b40ea063c56b958b5405ff3c49d --- /dev/null +++ b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/grpc/__init__.py @@ -0,0 +1,2190 @@ +# Copyright 2015-2016 gRPC authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""gRPC's Python API.""" + +import abc +import contextlib +import enum +import logging +import sys + +from grpc import _compression +from grpc._cython import cygrpc as _cygrpc +from grpc._runtime_protos import protos +from grpc._runtime_protos import protos_and_services +from grpc._runtime_protos import services +import six + +logging.getLogger(__name__).addHandler(logging.NullHandler()) + +try: + # pylint: disable=ungrouped-imports + from grpc._grpcio_metadata import __version__ +except ImportError: + __version__ = "dev0" + +############################## Future Interface ############################### + + +class FutureTimeoutError(Exception): + """Indicates that a method call on a Future timed out.""" + + +class FutureCancelledError(Exception): + """Indicates that the computation underlying a Future was cancelled.""" + + +class Future(six.with_metaclass(abc.ABCMeta)): + """A representation of a computation in another control flow. + + Computations represented by a Future may be yet to be begun, + may be ongoing, or may have already completed. + """ + + @abc.abstractmethod + def cancel(self): + """Attempts to cancel the computation. + + This method does not block. + + Returns: + bool: + Returns True if the computation was canceled. + + Returns False under all other circumstances, for example: + + 1. computation has begun and could not be canceled. + 2. computation has finished + 3. computation is scheduled for execution and it is impossible + to determine its state without blocking. + """ + raise NotImplementedError() + + @abc.abstractmethod + def cancelled(self): + """Describes whether the computation was cancelled. + + This method does not block. + + Returns: + bool: + Returns True if the computation was cancelled before its result became + available. + + Returns False under all other circumstances, for example: + + 1. computation was not cancelled. + 2. computation's result is available. + """ + raise NotImplementedError() + + @abc.abstractmethod + def running(self): + """Describes whether the computation is taking place. + + This method does not block. + + Returns: + Returns True if the computation is scheduled for execution or + currently executing. + + Returns False if the computation already executed or was cancelled. + """ + raise NotImplementedError() + + @abc.abstractmethod + def done(self): + """Describes whether the computation has taken place. + + This method does not block. + + Returns: + bool: + Returns True if the computation already executed or was cancelled. + Returns False if the computation is scheduled for execution or + currently executing. + This is exactly opposite of the running() method's result. + """ + raise NotImplementedError() + + @abc.abstractmethod + def result(self, timeout=None): + """Returns the result of the computation or raises its exception. + + This method may return immediately or may block. + + Args: + timeout: The length of time in seconds to wait for the computation to + finish or be cancelled. If None, the call will block until the + computations's termination. + + Returns: + The return value of the computation. + + Raises: + FutureTimeoutError: If a timeout value is passed and the computation + does not terminate within the allotted time. + FutureCancelledError: If the computation was cancelled. + Exception: If the computation raised an exception, this call will + raise the same exception. + """ + raise NotImplementedError() + + @abc.abstractmethod + def exception(self, timeout=None): + """Return the exception raised by the computation. + + This method may return immediately or may block. + + Args: + timeout: The length of time in seconds to wait for the computation to + terminate or be cancelled. If None, the call will block until the + computations's termination. + + Returns: + The exception raised by the computation, or None if the computation + did not raise an exception. + + Raises: + FutureTimeoutError: If a timeout value is passed and the computation + does not terminate within the allotted time. + FutureCancelledError: If the computation was cancelled. + """ + raise NotImplementedError() + + @abc.abstractmethod + def traceback(self, timeout=None): + """Access the traceback of the exception raised by the computation. + + This method may return immediately or may block. + + Args: + timeout: The length of time in seconds to wait for the computation + to terminate or be cancelled. If None, the call will block until + the computation's termination. + + Returns: + The traceback of the exception raised by the computation, or None + if the computation did not raise an exception. + + Raises: + FutureTimeoutError: If a timeout value is passed and the computation + does not terminate within the allotted time. + FutureCancelledError: If the computation was cancelled. + """ + raise NotImplementedError() + + @abc.abstractmethod + def add_done_callback(self, fn): + """Adds a function to be called at completion of the computation. + + The callback will be passed this Future object describing the outcome + of the computation. Callbacks will be invoked after the future is + terminated, whether successfully or not. + + If the computation has already completed, the callback will be called + immediately. + + Exceptions raised in the callback will be logged at ERROR level, but + will not terminate any threads of execution. + + Args: + fn: A callable taking this Future object as its single parameter. + """ + raise NotImplementedError() + + +################################ gRPC Enums ################################## + + +@enum.unique +class ChannelConnectivity(enum.Enum): + """Mirrors grpc_connectivity_state in the gRPC Core. + + Attributes: + IDLE: The channel is idle. + CONNECTING: The channel is connecting. + READY: The channel is ready to conduct RPCs. + TRANSIENT_FAILURE: The channel has seen a failure from which it expects + to recover. + SHUTDOWN: The channel has seen a failure from which it cannot recover. + """ + IDLE = (_cygrpc.ConnectivityState.idle, 'idle') + CONNECTING = (_cygrpc.ConnectivityState.connecting, 'connecting') + READY = (_cygrpc.ConnectivityState.ready, 'ready') + TRANSIENT_FAILURE = (_cygrpc.ConnectivityState.transient_failure, + 'transient failure') + SHUTDOWN = (_cygrpc.ConnectivityState.shutdown, 'shutdown') + + +@enum.unique +class StatusCode(enum.Enum): + """Mirrors grpc_status_code in the gRPC Core. + + Attributes: + OK: Not an error; returned on success + CANCELLED: The operation was cancelled (typically by the caller). + UNKNOWN: Unknown error. + INVALID_ARGUMENT: Client specified an invalid argument. + DEADLINE_EXCEEDED: Deadline expired before operation could complete. + NOT_FOUND: Some requested entity (e.g., file or directory) was not found. + ALREADY_EXISTS: Some entity that we attempted to create (e.g., file or directory) + already exists. + PERMISSION_DENIED: The caller does not have permission to execute the specified + operation. + UNAUTHENTICATED: The request does not have valid authentication credentials for the + operation. + RESOURCE_EXHAUSTED: Some resource has been exhausted, perhaps a per-user quota, or + perhaps the entire file system is out of space. + FAILED_PRECONDITION: Operation was rejected because the system is not in a state + required for the operation's execution. + ABORTED: The operation was aborted, typically due to a concurrency issue + like sequencer check failures, transaction aborts, etc. + UNIMPLEMENTED: Operation is not implemented or not supported/enabled in this service. + INTERNAL: Internal errors. Means some invariants expected by underlying + system has been broken. + UNAVAILABLE: The service is currently unavailable. + DATA_LOSS: Unrecoverable data loss or corruption. + """ + OK = (_cygrpc.StatusCode.ok, 'ok') + CANCELLED = (_cygrpc.StatusCode.cancelled, 'cancelled') + UNKNOWN = (_cygrpc.StatusCode.unknown, 'unknown') + INVALID_ARGUMENT = (_cygrpc.StatusCode.invalid_argument, 'invalid argument') + DEADLINE_EXCEEDED = (_cygrpc.StatusCode.deadline_exceeded, + 'deadline exceeded') + NOT_FOUND = (_cygrpc.StatusCode.not_found, 'not found') + ALREADY_EXISTS = (_cygrpc.StatusCode.already_exists, 'already exists') + PERMISSION_DENIED = (_cygrpc.StatusCode.permission_denied, + 'permission denied') + RESOURCE_EXHAUSTED = (_cygrpc.StatusCode.resource_exhausted, + 'resource exhausted') + FAILED_PRECONDITION = (_cygrpc.StatusCode.failed_precondition, + 'failed precondition') + ABORTED = (_cygrpc.StatusCode.aborted, 'aborted') + OUT_OF_RANGE = (_cygrpc.StatusCode.out_of_range, 'out of range') + UNIMPLEMENTED = (_cygrpc.StatusCode.unimplemented, 'unimplemented') + INTERNAL = (_cygrpc.StatusCode.internal, 'internal') + UNAVAILABLE = (_cygrpc.StatusCode.unavailable, 'unavailable') + DATA_LOSS = (_cygrpc.StatusCode.data_loss, 'data loss') + UNAUTHENTICATED = (_cygrpc.StatusCode.unauthenticated, 'unauthenticated') + + +############################# gRPC Status ################################ + + +class Status(six.with_metaclass(abc.ABCMeta)): + """Describes the status of an RPC. + + This is an EXPERIMENTAL API. + + Attributes: + code: A StatusCode object to be sent to the client. + details: A UTF-8-encodable string to be sent to the client upon + termination of the RPC. + trailing_metadata: The trailing :term:`metadata` in the RPC. + """ + + +############################# gRPC Exceptions ################################ + + +class RpcError(Exception): + """Raised by the gRPC library to indicate non-OK-status RPC termination.""" + + +############################## Shared Context ################################ + + +class RpcContext(six.with_metaclass(abc.ABCMeta)): + """Provides RPC-related information and action.""" + + @abc.abstractmethod + def is_active(self): + """Describes whether the RPC is active or has terminated. + + Returns: + bool: + True if RPC is active, False otherwise. + """ + raise NotImplementedError() + + @abc.abstractmethod + def time_remaining(self): + """Describes the length of allowed time remaining for the RPC. + + Returns: + A nonnegative float indicating the length of allowed time in seconds + remaining for the RPC to complete before it is considered to have + timed out, or None if no deadline was specified for the RPC. + """ + raise NotImplementedError() + + @abc.abstractmethod + def cancel(self): + """Cancels the RPC. + + Idempotent and has no effect if the RPC has already terminated. + """ + raise NotImplementedError() + + @abc.abstractmethod + def add_callback(self, callback): + """Registers a callback to be called on RPC termination. + + Args: + callback: A no-parameter callable to be called on RPC termination. + + Returns: + True if the callback was added and will be called later; False if + the callback was not added and will not be called (because the RPC + already terminated or some other reason). + """ + raise NotImplementedError() + + +######################### Invocation-Side Context ############################ + + +class Call(six.with_metaclass(abc.ABCMeta, RpcContext)): + """Invocation-side utility object for an RPC.""" + + @abc.abstractmethod + def initial_metadata(self): + """Accesses the initial metadata sent by the server. + + This method blocks until the value is available. + + Returns: + The initial :term:`metadata`. + """ + raise NotImplementedError() + + @abc.abstractmethod + def trailing_metadata(self): + """Accesses the trailing metadata sent by the server. + + This method blocks until the value is available. + + Returns: + The trailing :term:`metadata`. + """ + raise NotImplementedError() + + @abc.abstractmethod + def code(self): + """Accesses the status code sent by the server. + + This method blocks until the value is available. + + Returns: + The StatusCode value for the RPC. + """ + raise NotImplementedError() + + @abc.abstractmethod + def details(self): + """Accesses the details sent by the server. + + This method blocks until the value is available. + + Returns: + The details string of the RPC. + """ + raise NotImplementedError() + + +############## Invocation-Side Interceptor Interfaces & Classes ############## + + +class ClientCallDetails(six.with_metaclass(abc.ABCMeta)): + """Describes an RPC to be invoked. + + Attributes: + method: The method name of the RPC. + timeout: An optional duration of time in seconds to allow for the RPC. + metadata: Optional :term:`metadata` to be transmitted to + the service-side of the RPC. + credentials: An optional CallCredentials for the RPC. + wait_for_ready: This is an EXPERIMENTAL argument. An optional + flag to enable :term:`wait_for_ready` mechanism. + compression: An element of grpc.compression, e.g. + grpc.compression.Gzip. This is an EXPERIMENTAL option. + """ + + +class UnaryUnaryClientInterceptor(six.with_metaclass(abc.ABCMeta)): + """Affords intercepting unary-unary invocations.""" + + @abc.abstractmethod + def intercept_unary_unary(self, continuation, client_call_details, request): + """Intercepts a unary-unary invocation asynchronously. + + Args: + continuation: A function that proceeds with the invocation by + executing the next interceptor in chain or invoking the + actual RPC on the underlying Channel. It is the interceptor's + responsibility to call it if it decides to move the RPC forward. + The interceptor can use + `response_future = continuation(client_call_details, request)` + to continue with the RPC. `continuation` returns an object that is + both a Call for the RPC and a Future. In the event of RPC + completion, the return Call-Future's result value will be + the response message of the RPC. Should the event terminate + with non-OK status, the returned Call-Future's exception value + will be an RpcError. + client_call_details: A ClientCallDetails object describing the + outgoing RPC. + request: The request value for the RPC. + + Returns: + An object that is both a Call for the RPC and a Future. + In the event of RPC completion, the return Call-Future's + result value will be the response message of the RPC. + Should the event terminate with non-OK status, the returned + Call-Future's exception value will be an RpcError. + """ + raise NotImplementedError() + + +class UnaryStreamClientInterceptor(six.with_metaclass(abc.ABCMeta)): + """Affords intercepting unary-stream invocations.""" + + @abc.abstractmethod + def intercept_unary_stream(self, continuation, client_call_details, + request): + """Intercepts a unary-stream invocation. + + Args: + continuation: A function that proceeds with the invocation by + executing the next interceptor in chain or invoking the + actual RPC on the underlying Channel. It is the interceptor's + responsibility to call it if it decides to move the RPC forward. + The interceptor can use + `response_iterator = continuation(client_call_details, request)` + to continue with the RPC. `continuation` returns an object that is + both a Call for the RPC and an iterator for response values. + Drawing response values from the returned Call-iterator may + raise RpcError indicating termination of the RPC with non-OK + status. + client_call_details: A ClientCallDetails object describing the + outgoing RPC. + request: The request value for the RPC. + + Returns: + An object that is both a Call for the RPC and an iterator of + response values. Drawing response values from the returned + Call-iterator may raise RpcError indicating termination of + the RPC with non-OK status. This object *should* also fulfill the + Future interface, though it may not. + """ + raise NotImplementedError() + + +class StreamUnaryClientInterceptor(six.with_metaclass(abc.ABCMeta)): + """Affords intercepting stream-unary invocations.""" + + @abc.abstractmethod + def intercept_stream_unary(self, continuation, client_call_details, + request_iterator): + """Intercepts a stream-unary invocation asynchronously. + + Args: + continuation: A function that proceeds with the invocation by + executing the next interceptor in chain or invoking the + actual RPC on the underlying Channel. It is the interceptor's + responsibility to call it if it decides to move the RPC forward. + The interceptor can use + `response_future = continuation(client_call_details, request_iterator)` + to continue with the RPC. `continuation` returns an object that is + both a Call for the RPC and a Future. In the event of RPC completion, + the return Call-Future's result value will be the response message + of the RPC. Should the event terminate with non-OK status, the + returned Call-Future's exception value will be an RpcError. + client_call_details: A ClientCallDetails object describing the + outgoing RPC. + request_iterator: An iterator that yields request values for the RPC. + + Returns: + An object that is both a Call for the RPC and a Future. + In the event of RPC completion, the return Call-Future's + result value will be the response message of the RPC. + Should the event terminate with non-OK status, the returned + Call-Future's exception value will be an RpcError. + """ + raise NotImplementedError() + + +class StreamStreamClientInterceptor(six.with_metaclass(abc.ABCMeta)): + """Affords intercepting stream-stream invocations.""" + + @abc.abstractmethod + def intercept_stream_stream(self, continuation, client_call_details, + request_iterator): + """Intercepts a stream-stream invocation. + + Args: + continuation: A function that proceeds with the invocation by + executing the next interceptor in chain or invoking the + actual RPC on the underlying Channel. It is the interceptor's + responsibility to call it if it decides to move the RPC forward. + The interceptor can use + `response_iterator = continuation(client_call_details, request_iterator)` + to continue with the RPC. `continuation` returns an object that is + both a Call for the RPC and an iterator for response values. + Drawing response values from the returned Call-iterator may + raise RpcError indicating termination of the RPC with non-OK + status. + client_call_details: A ClientCallDetails object describing the + outgoing RPC. + request_iterator: An iterator that yields request values for the RPC. + + Returns: + An object that is both a Call for the RPC and an iterator of + response values. Drawing response values from the returned + Call-iterator may raise RpcError indicating termination of + the RPC with non-OK status. This object *should* also fulfill the + Future interface, though it may not. + """ + raise NotImplementedError() + + +############ Authentication & Authorization Interfaces & Classes ############# + + +class ChannelCredentials(object): + """An encapsulation of the data required to create a secure Channel. + + This class has no supported interface - it exists to define the type of its + instances and its instances exist to be passed to other functions. For + example, ssl_channel_credentials returns an instance of this class and + secure_channel requires an instance of this class. + """ + + def __init__(self, credentials): + self._credentials = credentials + + +class CallCredentials(object): + """An encapsulation of the data required to assert an identity over a call. + + A CallCredentials has to be used with secure Channel, otherwise the + metadata will not be transmitted to the server. + + A CallCredentials may be composed with ChannelCredentials to always assert + identity for every call over that Channel. + + This class has no supported interface - it exists to define the type of its + instances and its instances exist to be passed to other functions. + """ + + def __init__(self, credentials): + self._credentials = credentials + + +class AuthMetadataContext(six.with_metaclass(abc.ABCMeta)): + """Provides information to call credentials metadata plugins. + + Attributes: + service_url: A string URL of the service being called into. + method_name: A string of the fully qualified method name being called. + """ + + +class AuthMetadataPluginCallback(six.with_metaclass(abc.ABCMeta)): + """Callback object received by a metadata plugin.""" + + def __call__(self, metadata, error): + """Passes to the gRPC runtime authentication metadata for an RPC. + + Args: + metadata: The :term:`metadata` used to construct the CallCredentials. + error: An Exception to indicate error or None to indicate success. + """ + raise NotImplementedError() + + +class AuthMetadataPlugin(six.with_metaclass(abc.ABCMeta)): + """A specification for custom authentication.""" + + def __call__(self, context, callback): + """Implements authentication by passing metadata to a callback. + + This method will be invoked asynchronously in a separate thread. + + Args: + context: An AuthMetadataContext providing information on the RPC that + the plugin is being called to authenticate. + callback: An AuthMetadataPluginCallback to be invoked either + synchronously or asynchronously. + """ + raise NotImplementedError() + + +class ServerCredentials(object): + """An encapsulation of the data required to open a secure port on a Server. + + This class has no supported interface - it exists to define the type of its + instances and its instances exist to be passed to other functions. + """ + + def __init__(self, credentials): + self._credentials = credentials + + +class ServerCertificateConfiguration(object): + """A certificate configuration for use with an SSL-enabled Server. + + Instances of this class can be returned in the certificate configuration + fetching callback. + + This class has no supported interface -- it exists to define the + type of its instances and its instances exist to be passed to + other functions. + """ + + def __init__(self, certificate_configuration): + self._certificate_configuration = certificate_configuration + + +######################## Multi-Callable Interfaces ########################### + + +class UnaryUnaryMultiCallable(six.with_metaclass(abc.ABCMeta)): + """Affords invoking a unary-unary RPC from client-side.""" + + @abc.abstractmethod + def __call__(self, + request, + timeout=None, + metadata=None, + credentials=None, + wait_for_ready=None, + compression=None): + """Synchronously invokes the underlying RPC. + + Args: + request: The request value for the RPC. + timeout: An optional duration of time in seconds to allow + for the RPC. + metadata: Optional :term:`metadata` to be transmitted to the + service-side of the RPC. + credentials: An optional CallCredentials for the RPC. Only valid for + secure Channel. + wait_for_ready: This is an EXPERIMENTAL argument. An optional + flag to enable :term:`wait_for_ready` mechanism. + compression: An element of grpc.compression, e.g. + grpc.compression.Gzip. This is an EXPERIMENTAL option. + + Returns: + The response value for the RPC. + + Raises: + RpcError: Indicating that the RPC terminated with non-OK status. The + raised RpcError will also be a Call for the RPC affording the RPC's + metadata, status code, and details. + """ + raise NotImplementedError() + + @abc.abstractmethod + def with_call(self, + request, + timeout=None, + metadata=None, + credentials=None, + wait_for_ready=None, + compression=None): + """Synchronously invokes the underlying RPC. + + Args: + request: The request value for the RPC. + timeout: An optional durating of time in seconds to allow for + the RPC. + metadata: Optional :term:`metadata` to be transmitted to the + service-side of the RPC. + credentials: An optional CallCredentials for the RPC. Only valid for + secure Channel. + wait_for_ready: This is an EXPERIMENTAL argument. An optional + flag to enable :term:`wait_for_ready` mechanism. + compression: An element of grpc.compression, e.g. + grpc.compression.Gzip. This is an EXPERIMENTAL option. + + Returns: + The response value for the RPC and a Call value for the RPC. + + Raises: + RpcError: Indicating that the RPC terminated with non-OK status. The + raised RpcError will also be a Call for the RPC affording the RPC's + metadata, status code, and details. + """ + raise NotImplementedError() + + @abc.abstractmethod + def future(self, + request, + timeout=None, + metadata=None, + credentials=None, + wait_for_ready=None, + compression=None): + """Asynchronously invokes the underlying RPC. + + Args: + request: The request value for the RPC. + timeout: An optional duration of time in seconds to allow for + the RPC. + metadata: Optional :term:`metadata` to be transmitted to the + service-side of the RPC. + credentials: An optional CallCredentials for the RPC. Only valid for + secure Channel. + wait_for_ready: This is an EXPERIMENTAL argument. An optional + flag to enable :term:`wait_for_ready` mechanism. + compression: An element of grpc.compression, e.g. + grpc.compression.Gzip. This is an EXPERIMENTAL option. + + Returns: + An object that is both a Call for the RPC and a Future. + In the event of RPC completion, the return Call-Future's result + value will be the response message of the RPC. + Should the event terminate with non-OK status, + the returned Call-Future's exception value will be an RpcError. + """ + raise NotImplementedError() + + +class UnaryStreamMultiCallable(six.with_metaclass(abc.ABCMeta)): + """Affords invoking a unary-stream RPC from client-side.""" + + @abc.abstractmethod + def __call__(self, + request, + timeout=None, + metadata=None, + credentials=None, + wait_for_ready=None, + compression=None): + """Invokes the underlying RPC. + + Args: + request: The request value for the RPC. + timeout: An optional duration of time in seconds to allow for + the RPC. If None, the timeout is considered infinite. + metadata: An optional :term:`metadata` to be transmitted to the + service-side of the RPC. + credentials: An optional CallCredentials for the RPC. Only valid for + secure Channel. + wait_for_ready: This is an EXPERIMENTAL argument. An optional + flag to enable :term:`wait_for_ready` mechanism. + compression: An element of grpc.compression, e.g. + grpc.compression.Gzip. This is an EXPERIMENTAL option. + + Returns: + An object that is a Call for the RPC, an iterator of response + values, and a Future for the RPC. Drawing response values from the + returned Call-iterator may raise RpcError indicating termination of + the RPC with non-OK status. + """ + raise NotImplementedError() + + +class StreamUnaryMultiCallable(six.with_metaclass(abc.ABCMeta)): + """Affords invoking a stream-unary RPC from client-side.""" + + @abc.abstractmethod + def __call__(self, + request_iterator, + timeout=None, + metadata=None, + credentials=None, + wait_for_ready=None, + compression=None): + """Synchronously invokes the underlying RPC. + + Args: + request_iterator: An iterator that yields request values for + the RPC. + timeout: An optional duration of time in seconds to allow for + the RPC. If None, the timeout is considered infinite. + metadata: Optional :term:`metadata` to be transmitted to the + service-side of the RPC. + credentials: An optional CallCredentials for the RPC. Only valid for + secure Channel. + wait_for_ready: This is an EXPERIMENTAL argument. An optional + flag to enable :term:`wait_for_ready` mechanism. + compression: An element of grpc.compression, e.g. + grpc.compression.Gzip. This is an EXPERIMENTAL option. + + Returns: + The response value for the RPC. + + Raises: + RpcError: Indicating that the RPC terminated with non-OK status. The + raised RpcError will also implement grpc.Call, affording methods + such as metadata, code, and details. + """ + raise NotImplementedError() + + @abc.abstractmethod + def with_call(self, + request_iterator, + timeout=None, + metadata=None, + credentials=None, + wait_for_ready=None, + compression=None): + """Synchronously invokes the underlying RPC on the client. + + Args: + request_iterator: An iterator that yields request values for + the RPC. + timeout: An optional duration of time in seconds to allow for + the RPC. If None, the timeout is considered infinite. + metadata: Optional :term:`metadata` to be transmitted to the + service-side of the RPC. + credentials: An optional CallCredentials for the RPC. Only valid for + secure Channel. + wait_for_ready: This is an EXPERIMENTAL argument. An optional + flag to enable :term:`wait_for_ready` mechanism. + compression: An element of grpc.compression, e.g. + grpc.compression.Gzip. This is an EXPERIMENTAL option. + + Returns: + The response value for the RPC and a Call object for the RPC. + + Raises: + RpcError: Indicating that the RPC terminated with non-OK status. The + raised RpcError will also be a Call for the RPC affording the RPC's + metadata, status code, and details. + """ + raise NotImplementedError() + + @abc.abstractmethod + def future(self, + request_iterator, + timeout=None, + metadata=None, + credentials=None, + wait_for_ready=None, + compression=None): + """Asynchronously invokes the underlying RPC on the client. + + Args: + request_iterator: An iterator that yields request values for the RPC. + timeout: An optional duration of time in seconds to allow for + the RPC. If None, the timeout is considered infinite. + metadata: Optional :term:`metadata` to be transmitted to the + service-side of the RPC. + credentials: An optional CallCredentials for the RPC. Only valid for + secure Channel. + wait_for_ready: This is an EXPERIMENTAL argument. An optional + flag to enable :term:`wait_for_ready` mechanism. + compression: An element of grpc.compression, e.g. + grpc.compression.Gzip. This is an EXPERIMENTAL option. + + Returns: + An object that is both a Call for the RPC and a Future. + In the event of RPC completion, the return Call-Future's result value + will be the response message of the RPC. Should the event terminate + with non-OK status, the returned Call-Future's exception value will + be an RpcError. + """ + raise NotImplementedError() + + +class StreamStreamMultiCallable(six.with_metaclass(abc.ABCMeta)): + """Affords invoking a stream-stream RPC on client-side.""" + + @abc.abstractmethod + def __call__(self, + request_iterator, + timeout=None, + metadata=None, + credentials=None, + wait_for_ready=None, + compression=None): + """Invokes the underlying RPC on the client. + + Args: + request_iterator: An iterator that yields request values for the RPC. + timeout: An optional duration of time in seconds to allow for + the RPC. If not specified, the timeout is considered infinite. + metadata: Optional :term:`metadata` to be transmitted to the + service-side of the RPC. + credentials: An optional CallCredentials for the RPC. Only valid for + secure Channel. + wait_for_ready: This is an EXPERIMENTAL argument. An optional + flag to enable :term:`wait_for_ready` mechanism. + compression: An element of grpc.compression, e.g. + grpc.compression.Gzip. This is an EXPERIMENTAL option. + + Returns: + An object that is a Call for the RPC, an iterator of response + values, and a Future for the RPC. Drawing response values from the + returned Call-iterator may raise RpcError indicating termination of + the RPC with non-OK status. + """ + raise NotImplementedError() + + +############################# Channel Interface ############################## + + +class Channel(six.with_metaclass(abc.ABCMeta)): + """Affords RPC invocation via generic methods on client-side. + + Channel objects implement the Context Manager type, although they need not + support being entered and exited multiple times. + """ + + @abc.abstractmethod + def subscribe(self, callback, try_to_connect=False): + """Subscribe to this Channel's connectivity state machine. + + A Channel may be in any of the states described by ChannelConnectivity. + This method allows application to monitor the state transitions. + The typical use case is to debug or gain better visibility into gRPC + runtime's state. + + Args: + callback: A callable to be invoked with ChannelConnectivity argument. + ChannelConnectivity describes current state of the channel. + The callable will be invoked immediately upon subscription + and again for every change to ChannelConnectivity until it + is unsubscribed or this Channel object goes out of scope. + try_to_connect: A boolean indicating whether or not this Channel + should attempt to connect immediately. If set to False, gRPC + runtime decides when to connect. + """ + raise NotImplementedError() + + @abc.abstractmethod + def unsubscribe(self, callback): + """Unsubscribes a subscribed callback from this Channel's connectivity. + + Args: + callback: A callable previously registered with this Channel from + having been passed to its "subscribe" method. + """ + raise NotImplementedError() + + @abc.abstractmethod + def unary_unary(self, + method, + request_serializer=None, + response_deserializer=None): + """Creates a UnaryUnaryMultiCallable for a unary-unary method. + + Args: + method: The name of the RPC method. + request_serializer: Optional :term:`serializer` for serializing the request + message. Request goes unserialized in case None is passed. + response_deserializer: Optional :term:`deserializer` for deserializing the + response message. Response goes undeserialized in case None + is passed. + + Returns: + A UnaryUnaryMultiCallable value for the named unary-unary method. + """ + raise NotImplementedError() + + @abc.abstractmethod + def unary_stream(self, + method, + request_serializer=None, + response_deserializer=None): + """Creates a UnaryStreamMultiCallable for a unary-stream method. + + Args: + method: The name of the RPC method. + request_serializer: Optional :term:`serializer` for serializing the request + message. Request goes unserialized in case None is passed. + response_deserializer: Optional :term:`deserializer` for deserializing the + response message. Response goes undeserialized in case None is + passed. + + Returns: + A UnaryStreamMultiCallable value for the name unary-stream method. + """ + raise NotImplementedError() + + @abc.abstractmethod + def stream_unary(self, + method, + request_serializer=None, + response_deserializer=None): + """Creates a StreamUnaryMultiCallable for a stream-unary method. + + Args: + method: The name of the RPC method. + request_serializer: Optional :term:`serializer` for serializing the request + message. Request goes unserialized in case None is passed. + response_deserializer: Optional :term:`deserializer` for deserializing the + response message. Response goes undeserialized in case None is + passed. + + Returns: + A StreamUnaryMultiCallable value for the named stream-unary method. + """ + raise NotImplementedError() + + @abc.abstractmethod + def stream_stream(self, + method, + request_serializer=None, + response_deserializer=None): + """Creates a StreamStreamMultiCallable for a stream-stream method. + + Args: + method: The name of the RPC method. + request_serializer: Optional :term:`serializer` for serializing the request + message. Request goes unserialized in case None is passed. + response_deserializer: Optional :term:`deserializer` for deserializing the + response message. Response goes undeserialized in case None + is passed. + + Returns: + A StreamStreamMultiCallable value for the named stream-stream method. + """ + raise NotImplementedError() + + @abc.abstractmethod + def close(self): + """Closes this Channel and releases all resources held by it. + + Closing the Channel will immediately terminate all RPCs active with the + Channel and it is not valid to invoke new RPCs with the Channel. + + This method is idempotent. + """ + raise NotImplementedError() + + def __enter__(self): + """Enters the runtime context related to the channel object.""" + raise NotImplementedError() + + def __exit__(self, exc_type, exc_val, exc_tb): + """Exits the runtime context related to the channel object.""" + raise NotImplementedError() + + +########################## Service-Side Context ############################## + + +class ServicerContext(six.with_metaclass(abc.ABCMeta, RpcContext)): + """A context object passed to method implementations.""" + + @abc.abstractmethod + def invocation_metadata(self): + """Accesses the metadata from the sent by the client. + + Returns: + The invocation :term:`metadata`. + """ + raise NotImplementedError() + + @abc.abstractmethod + def peer(self): + """Identifies the peer that invoked the RPC being serviced. + + Returns: + A string identifying the peer that invoked the RPC being serviced. + The string format is determined by gRPC runtime. + """ + raise NotImplementedError() + + @abc.abstractmethod + def peer_identities(self): + """Gets one or more peer identity(s). + + Equivalent to + servicer_context.auth_context().get(servicer_context.peer_identity_key()) + + Returns: + An iterable of the identities, or None if the call is not + authenticated. Each identity is returned as a raw bytes type. + """ + raise NotImplementedError() + + @abc.abstractmethod + def peer_identity_key(self): + """The auth property used to identify the peer. + + For example, "x509_common_name" or "x509_subject_alternative_name" are + used to identify an SSL peer. + + Returns: + The auth property (string) that indicates the + peer identity, or None if the call is not authenticated. + """ + raise NotImplementedError() + + @abc.abstractmethod + def auth_context(self): + """Gets the auth context for the call. + + Returns: + A map of strings to an iterable of bytes for each auth property. + """ + raise NotImplementedError() + + def set_compression(self, compression): + """Set the compression algorithm to be used for the entire call. + + This is an EXPERIMENTAL method. + + Args: + compression: An element of grpc.compression, e.g. + grpc.compression.Gzip. + """ + raise NotImplementedError() + + @abc.abstractmethod + def send_initial_metadata(self, initial_metadata): + """Sends the initial metadata value to the client. + + This method need not be called by implementations if they have no + metadata to add to what the gRPC runtime will transmit. + + Args: + initial_metadata: The initial :term:`metadata`. + """ + raise NotImplementedError() + + @abc.abstractmethod + def set_trailing_metadata(self, trailing_metadata): + """Sets the trailing metadata for the RPC. + + Sets the trailing metadata to be sent upon completion of the RPC. + + If this method is invoked multiple times throughout the lifetime of an + RPC, the value supplied in the final invocation will be the value sent + over the wire. + + This method need not be called by implementations if they have no + metadata to add to what the gRPC runtime will transmit. + + Args: + trailing_metadata: The trailing :term:`metadata`. + """ + raise NotImplementedError() + + def trailing_metadata(self): + """Access value to be used as trailing metadata upon RPC completion. + + This is an EXPERIMENTAL API. + + Returns: + The trailing :term:`metadata` for the RPC. + """ + raise NotImplementedError() + + @abc.abstractmethod + def abort(self, code, details): + """Raises an exception to terminate the RPC with a non-OK status. + + The code and details passed as arguments will supercede any existing + ones. + + Args: + code: A StatusCode object to be sent to the client. + It must not be StatusCode.OK. + details: A UTF-8-encodable string to be sent to the client upon + termination of the RPC. + + Raises: + Exception: An exception is always raised to signal the abortion the + RPC to the gRPC runtime. + """ + raise NotImplementedError() + + @abc.abstractmethod + def abort_with_status(self, status): + """Raises an exception to terminate the RPC with a non-OK status. + + The status passed as argument will supercede any existing status code, + status message and trailing metadata. + + This is an EXPERIMENTAL API. + + Args: + status: A grpc.Status object. The status code in it must not be + StatusCode.OK. + + Raises: + Exception: An exception is always raised to signal the abortion the + RPC to the gRPC runtime. + """ + raise NotImplementedError() + + @abc.abstractmethod + def set_code(self, code): + """Sets the value to be used as status code upon RPC completion. + + This method need not be called by method implementations if they wish + the gRPC runtime to determine the status code of the RPC. + + Args: + code: A StatusCode object to be sent to the client. + """ + raise NotImplementedError() + + @abc.abstractmethod + def set_details(self, details): + """Sets the value to be used as detail string upon RPC completion. + + This method need not be called by method implementations if they have + no details to transmit. + + Args: + details: A UTF-8-encodable string to be sent to the client upon + termination of the RPC. + """ + raise NotImplementedError() + + def code(self): + """Accesses the value to be used as status code upon RPC completion. + + This is an EXPERIMENTAL API. + + Returns: + The StatusCode value for the RPC. + """ + raise NotImplementedError() + + def details(self): + """Accesses the value to be used as detail string upon RPC completion. + + This is an EXPERIMENTAL API. + + Returns: + The details string of the RPC. + """ + raise NotImplementedError() + + def disable_next_message_compression(self): + """Disables compression for the next response message. + + This is an EXPERIMENTAL method. + + This method will override any compression configuration set during + server creation or set on the call. + """ + raise NotImplementedError() + + +##################### Service-Side Handler Interfaces ######################## + + +class RpcMethodHandler(six.with_metaclass(abc.ABCMeta)): + """An implementation of a single RPC method. + + Attributes: + request_streaming: Whether the RPC supports exactly one request message + or any arbitrary number of request messages. + response_streaming: Whether the RPC supports exactly one response message + or any arbitrary number of response messages. + request_deserializer: A callable :term:`deserializer` that accepts a byte string and + returns an object suitable to be passed to this object's business + logic, or None to indicate that this object's business logic should be + passed the raw request bytes. + response_serializer: A callable :term:`serializer` that accepts an object produced + by this object's business logic and returns a byte string, or None to + indicate that the byte strings produced by this object's business logic + should be transmitted on the wire as they are. + unary_unary: This object's application-specific business logic as a + callable value that takes a request value and a ServicerContext object + and returns a response value. Only non-None if both request_streaming + and response_streaming are False. + unary_stream: This object's application-specific business logic as a + callable value that takes a request value and a ServicerContext object + and returns an iterator of response values. Only non-None if + request_streaming is False and response_streaming is True. + stream_unary: This object's application-specific business logic as a + callable value that takes an iterator of request values and a + ServicerContext object and returns a response value. Only non-None if + request_streaming is True and response_streaming is False. + stream_stream: This object's application-specific business logic as a + callable value that takes an iterator of request values and a + ServicerContext object and returns an iterator of response values. + Only non-None if request_streaming and response_streaming are both + True. + """ + + +class HandlerCallDetails(six.with_metaclass(abc.ABCMeta)): + """Describes an RPC that has just arrived for service. + + Attributes: + method: The method name of the RPC. + invocation_metadata: The :term:`metadata` sent by the client. + """ + + +class GenericRpcHandler(six.with_metaclass(abc.ABCMeta)): + """An implementation of arbitrarily many RPC methods.""" + + @abc.abstractmethod + def service(self, handler_call_details): + """Returns the handler for servicing the RPC. + + Args: + handler_call_details: A HandlerCallDetails describing the RPC. + + Returns: + An RpcMethodHandler with which the RPC may be serviced if the + implementation chooses to service this RPC, or None otherwise. + """ + raise NotImplementedError() + + +class ServiceRpcHandler(six.with_metaclass(abc.ABCMeta, GenericRpcHandler)): + """An implementation of RPC methods belonging to a service. + + A service handles RPC methods with structured names of the form + '/Service.Name/Service.Method', where 'Service.Name' is the value + returned by service_name(), and 'Service.Method' is the method + name. A service can have multiple method names, but only a single + service name. + """ + + @abc.abstractmethod + def service_name(self): + """Returns this service's name. + + Returns: + The service name. + """ + raise NotImplementedError() + + +#################### Service-Side Interceptor Interfaces ##################### + + +class ServerInterceptor(six.with_metaclass(abc.ABCMeta)): + """Affords intercepting incoming RPCs on the service-side.""" + + @abc.abstractmethod + def intercept_service(self, continuation, handler_call_details): + """Intercepts incoming RPCs before handing them over to a handler. + + Args: + continuation: A function that takes a HandlerCallDetails and + proceeds to invoke the next interceptor in the chain, if any, + or the RPC handler lookup logic, with the call details passed + as an argument, and returns an RpcMethodHandler instance if + the RPC is considered serviced, or None otherwise. + handler_call_details: A HandlerCallDetails describing the RPC. + + Returns: + An RpcMethodHandler with which the RPC may be serviced if the + interceptor chooses to service this RPC, or None otherwise. + """ + raise NotImplementedError() + + +############################# Server Interface ############################### + + +class Server(six.with_metaclass(abc.ABCMeta)): + """Services RPCs.""" + + @abc.abstractmethod + def add_generic_rpc_handlers(self, generic_rpc_handlers): + """Registers GenericRpcHandlers with this Server. + + This method is only safe to call before the server is started. + + Args: + generic_rpc_handlers: An iterable of GenericRpcHandlers that will be + used to service RPCs. + """ + raise NotImplementedError() + + @abc.abstractmethod + def add_insecure_port(self, address): + """Opens an insecure port for accepting RPCs. + + This method may only be called before starting the server. + + Args: + address: The address for which to open a port. If the port is 0, + or not specified in the address, then gRPC runtime will choose a port. + + Returns: + An integer port on which server will accept RPC requests. + """ + raise NotImplementedError() + + @abc.abstractmethod + def add_secure_port(self, address, server_credentials): + """Opens a secure port for accepting RPCs. + + This method may only be called before starting the server. + + Args: + address: The address for which to open a port. + if the port is 0, or not specified in the address, then gRPC + runtime will choose a port. + server_credentials: A ServerCredentials object. + + Returns: + An integer port on which server will accept RPC requests. + """ + raise NotImplementedError() + + @abc.abstractmethod + def start(self): + """Starts this Server. + + This method may only be called once. (i.e. it is not idempotent). + """ + raise NotImplementedError() + + @abc.abstractmethod + def stop(self, grace): + """Stops this Server. + + This method immediately stop service of new RPCs in all cases. + + If a grace period is specified, this method returns immediately + and all RPCs active at the end of the grace period are aborted. + If a grace period is not specified (by passing None for `grace`), + all existing RPCs are aborted immediately and this method + blocks until the last RPC handler terminates. + + This method is idempotent and may be called at any time. + Passing a smaller grace value in a subsequent call will have + the effect of stopping the Server sooner (passing None will + have the effect of stopping the server immediately). Passing + a larger grace value in a subsequent call *will not* have the + effect of stopping the server later (i.e. the most restrictive + grace value is used). + + Args: + grace: A duration of time in seconds or None. + + Returns: + A threading.Event that will be set when this Server has completely + stopped, i.e. when running RPCs either complete or are aborted and + all handlers have terminated. + """ + raise NotImplementedError() + + def wait_for_termination(self, timeout=None): + """Block current thread until the server stops. + + This is an EXPERIMENTAL API. + + The wait will not consume computational resources during blocking, and + it will block until one of the two following conditions are met: + + 1) The server is stopped or terminated; + 2) A timeout occurs if timeout is not `None`. + + The timeout argument works in the same way as `threading.Event.wait()`. + https://docs.python.org/3/library/threading.html#threading.Event.wait + + Args: + timeout: A floating point number specifying a timeout for the + operation in seconds. + + Returns: + A bool indicates if the operation times out. + """ + raise NotImplementedError() + + +################################# Functions ################################ + + +def unary_unary_rpc_method_handler(behavior, + request_deserializer=None, + response_serializer=None): + """Creates an RpcMethodHandler for a unary-unary RPC method. + + Args: + behavior: The implementation of an RPC that accepts one request + and returns one response. + request_deserializer: An optional :term:`deserializer` for request deserialization. + response_serializer: An optional :term:`serializer` for response serialization. + + Returns: + An RpcMethodHandler object that is typically used by grpc.Server. + """ + from grpc import _utilities # pylint: disable=cyclic-import + return _utilities.RpcMethodHandler(False, False, request_deserializer, + response_serializer, behavior, None, + None, None) + + +def unary_stream_rpc_method_handler(behavior, + request_deserializer=None, + response_serializer=None): + """Creates an RpcMethodHandler for a unary-stream RPC method. + + Args: + behavior: The implementation of an RPC that accepts one request + and returns an iterator of response values. + request_deserializer: An optional :term:`deserializer` for request deserialization. + response_serializer: An optional :term:`serializer` for response serialization. + + Returns: + An RpcMethodHandler object that is typically used by grpc.Server. + """ + from grpc import _utilities # pylint: disable=cyclic-import + return _utilities.RpcMethodHandler(False, True, request_deserializer, + response_serializer, None, behavior, + None, None) + + +def stream_unary_rpc_method_handler(behavior, + request_deserializer=None, + response_serializer=None): + """Creates an RpcMethodHandler for a stream-unary RPC method. + + Args: + behavior: The implementation of an RPC that accepts an iterator of + request values and returns a single response value. + request_deserializer: An optional :term:`deserializer` for request deserialization. + response_serializer: An optional :term:`serializer` for response serialization. + + Returns: + An RpcMethodHandler object that is typically used by grpc.Server. + """ + from grpc import _utilities # pylint: disable=cyclic-import + return _utilities.RpcMethodHandler(True, False, request_deserializer, + response_serializer, None, None, + behavior, None) + + +def stream_stream_rpc_method_handler(behavior, + request_deserializer=None, + response_serializer=None): + """Creates an RpcMethodHandler for a stream-stream RPC method. + + Args: + behavior: The implementation of an RPC that accepts an iterator of + request values and returns an iterator of response values. + request_deserializer: An optional :term:`deserializer` for request deserialization. + response_serializer: An optional :term:`serializer` for response serialization. + + Returns: + An RpcMethodHandler object that is typically used by grpc.Server. + """ + from grpc import _utilities # pylint: disable=cyclic-import + return _utilities.RpcMethodHandler(True, True, request_deserializer, + response_serializer, None, None, None, + behavior) + + +def method_handlers_generic_handler(service, method_handlers): + """Creates a GenericRpcHandler from RpcMethodHandlers. + + Args: + service: The name of the service that is implemented by the + method_handlers. + method_handlers: A dictionary that maps method names to corresponding + RpcMethodHandler. + + Returns: + A GenericRpcHandler. This is typically added to the grpc.Server object + with add_generic_rpc_handlers() before starting the server. + """ + from grpc import _utilities # pylint: disable=cyclic-import + return _utilities.DictionaryGenericHandler(service, method_handlers) + + +def ssl_channel_credentials(root_certificates=None, + private_key=None, + certificate_chain=None): + """Creates a ChannelCredentials for use with an SSL-enabled Channel. + + Args: + root_certificates: The PEM-encoded root certificates as a byte string, + or None to retrieve them from a default location chosen by gRPC + runtime. + private_key: The PEM-encoded private key as a byte string, or None if no + private key should be used. + certificate_chain: The PEM-encoded certificate chain as a byte string + to use or None if no certificate chain should be used. + + Returns: + A ChannelCredentials for use with an SSL-enabled Channel. + """ + return ChannelCredentials( + _cygrpc.SSLChannelCredentials(root_certificates, private_key, + certificate_chain)) + + +def xds_channel_credentials(fallback_credentials=None): + """Creates a ChannelCredentials for use with xDS. This is an EXPERIMENTAL + API. + + Args: + fallback_credentials: Credentials to use in case it is not possible to + establish a secure connection via xDS. If no fallback_credentials + argument is supplied, a default SSLChannelCredentials is used. + """ + fallback_credentials = ssl_channel_credentials( + ) if fallback_credentials is None else fallback_credentials + return ChannelCredentials( + _cygrpc.XDSChannelCredentials(fallback_credentials._credentials)) + + +def metadata_call_credentials(metadata_plugin, name=None): + """Construct CallCredentials from an AuthMetadataPlugin. + + Args: + metadata_plugin: An AuthMetadataPlugin to use for authentication. + name: An optional name for the plugin. + + Returns: + A CallCredentials. + """ + from grpc import _plugin_wrapping # pylint: disable=cyclic-import + return _plugin_wrapping.metadata_plugin_call_credentials( + metadata_plugin, name) + + +def access_token_call_credentials(access_token): + """Construct CallCredentials from an access token. + + Args: + access_token: A string to place directly in the http request + authorization header, for example + "authorization: Bearer ". + + Returns: + A CallCredentials. + """ + from grpc import _auth # pylint: disable=cyclic-import + from grpc import _plugin_wrapping # pylint: disable=cyclic-import + return _plugin_wrapping.metadata_plugin_call_credentials( + _auth.AccessTokenAuthMetadataPlugin(access_token), None) + + +def composite_call_credentials(*call_credentials): + """Compose multiple CallCredentials to make a new CallCredentials. + + Args: + *call_credentials: At least two CallCredentials objects. + + Returns: + A CallCredentials object composed of the given CallCredentials objects. + """ + return CallCredentials( + _cygrpc.CompositeCallCredentials( + tuple(single_call_credentials._credentials + for single_call_credentials in call_credentials))) + + +def composite_channel_credentials(channel_credentials, *call_credentials): + """Compose a ChannelCredentials and one or more CallCredentials objects. + + Args: + channel_credentials: A ChannelCredentials object. + *call_credentials: One or more CallCredentials objects. + + Returns: + A ChannelCredentials composed of the given ChannelCredentials and + CallCredentials objects. + """ + return ChannelCredentials( + _cygrpc.CompositeChannelCredentials( + tuple(single_call_credentials._credentials + for single_call_credentials in call_credentials), + channel_credentials._credentials)) + + +def ssl_server_credentials(private_key_certificate_chain_pairs, + root_certificates=None, + require_client_auth=False): + """Creates a ServerCredentials for use with an SSL-enabled Server. + + Args: + private_key_certificate_chain_pairs: A list of pairs of the form + [PEM-encoded private key, PEM-encoded certificate chain]. + root_certificates: An optional byte string of PEM-encoded client root + certificates that the server will use to verify client authentication. + If omitted, require_client_auth must also be False. + require_client_auth: A boolean indicating whether or not to require + clients to be authenticated. May only be True if root_certificates + is not None. + + Returns: + A ServerCredentials for use with an SSL-enabled Server. Typically, this + object is an argument to add_secure_port() method during server setup. + """ + if not private_key_certificate_chain_pairs: + raise ValueError( + 'At least one private key-certificate chain pair is required!') + elif require_client_auth and root_certificates is None: + raise ValueError( + 'Illegal to require client auth without providing root certificates!' + ) + else: + return ServerCredentials( + _cygrpc.server_credentials_ssl(root_certificates, [ + _cygrpc.SslPemKeyCertPair(key, pem) + for key, pem in private_key_certificate_chain_pairs + ], require_client_auth)) + + +def xds_server_credentials(fallback_credentials): + """Creates a ServerCredentials for use with xDS. This is an EXPERIMENTAL + API. + + Args: + fallback_credentials: Credentials to use in case it is not possible to + establish a secure connection via xDS. No default value is provided. + """ + return ServerCredentials( + _cygrpc.xds_server_credentials(fallback_credentials._credentials)) + + +def insecure_server_credentials(): + """Creates a credentials object directing the server to use no credentials. + This is an EXPERIMENTAL API. + + This object cannot be used directly in a call to `add_secure_port`. + Instead, it should be used to construct other credentials objects, e.g. + with xds_server_credentials. + """ + return ServerCredentials(_cygrpc.insecure_server_credentials()) + + +def ssl_server_certificate_configuration(private_key_certificate_chain_pairs, + root_certificates=None): + """Creates a ServerCertificateConfiguration for use with a Server. + + Args: + private_key_certificate_chain_pairs: A collection of pairs of + the form [PEM-encoded private key, PEM-encoded certificate + chain]. + root_certificates: An optional byte string of PEM-encoded client root + certificates that the server will use to verify client authentication. + + Returns: + A ServerCertificateConfiguration that can be returned in the certificate + configuration fetching callback. + """ + if private_key_certificate_chain_pairs: + return ServerCertificateConfiguration( + _cygrpc.server_certificate_config_ssl(root_certificates, [ + _cygrpc.SslPemKeyCertPair(key, pem) + for key, pem in private_key_certificate_chain_pairs + ])) + else: + raise ValueError( + 'At least one private key-certificate chain pair is required!') + + +def dynamic_ssl_server_credentials(initial_certificate_configuration, + certificate_configuration_fetcher, + require_client_authentication=False): + """Creates a ServerCredentials for use with an SSL-enabled Server. + + Args: + initial_certificate_configuration (ServerCertificateConfiguration): The + certificate configuration with which the server will be initialized. + certificate_configuration_fetcher (callable): A callable that takes no + arguments and should return a ServerCertificateConfiguration to + replace the server's current certificate, or None for no change + (i.e., the server will continue its current certificate + config). The library will call this callback on *every* new + client connection before starting the TLS handshake with the + client, thus allowing the user application to optionally + return a new ServerCertificateConfiguration that the server will then + use for the handshake. + require_client_authentication: A boolean indicating whether or not to + require clients to be authenticated. + + Returns: + A ServerCredentials. + """ + return ServerCredentials( + _cygrpc.server_credentials_ssl_dynamic_cert_config( + initial_certificate_configuration, + certificate_configuration_fetcher, require_client_authentication)) + + +@enum.unique +class LocalConnectionType(enum.Enum): + """Types of local connection for local credential creation. + + Attributes: + UDS: Unix domain socket connections + LOCAL_TCP: Local TCP connections. + """ + UDS = _cygrpc.LocalConnectionType.uds + LOCAL_TCP = _cygrpc.LocalConnectionType.local_tcp + + +def local_channel_credentials(local_connect_type=LocalConnectionType.LOCAL_TCP): + """Creates a local ChannelCredentials used for local connections. + + This is an EXPERIMENTAL API. + + Local credentials are used by local TCP endpoints (e.g. localhost:10000) + also UDS connections. + + The connections created by local channel credentials are not + encrypted, but will be checked if they are local or not. + The UDS connections are considered secure by providing peer authentication + and data confidentiality while TCP connections are considered insecure. + + It is allowed to transmit call credentials over connections created by + local channel credentials. + + Local channel credentials are useful for 1) eliminating insecure_channel usage; + 2) enable unit testing for call credentials without setting up secrets. + + Args: + local_connect_type: Local connection type (either + grpc.LocalConnectionType.UDS or grpc.LocalConnectionType.LOCAL_TCP) + + Returns: + A ChannelCredentials for use with a local Channel + """ + return ChannelCredentials( + _cygrpc.channel_credentials_local(local_connect_type.value)) + + +def local_server_credentials(local_connect_type=LocalConnectionType.LOCAL_TCP): + """Creates a local ServerCredentials used for local connections. + + This is an EXPERIMENTAL API. + + Local credentials are used by local TCP endpoints (e.g. localhost:10000) + also UDS connections. + + The connections created by local server credentials are not + encrypted, but will be checked if they are local or not. + The UDS connections are considered secure by providing peer authentication + and data confidentiality while TCP connections are considered insecure. + + It is allowed to transmit call credentials over connections created by local + server credentials. + + Local server credentials are useful for 1) eliminating insecure_channel usage; + 2) enable unit testing for call credentials without setting up secrets. + + Args: + local_connect_type: Local connection type (either + grpc.LocalConnectionType.UDS or grpc.LocalConnectionType.LOCAL_TCP) + + Returns: + A ServerCredentials for use with a local Server + """ + return ServerCredentials( + _cygrpc.server_credentials_local(local_connect_type.value)) + + +def alts_channel_credentials(service_accounts=None): + """Creates a ChannelCredentials for use with an ALTS-enabled Channel. + + This is an EXPERIMENTAL API. + ALTS credentials API can only be used in GCP environment as it relies on + handshaker service being available. For more info about ALTS see + https://cloud.google.com/security/encryption-in-transit/application-layer-transport-security + + Args: + service_accounts: A list of server identities accepted by the client. + If target service accounts are provided and none of them matches the + peer identity of the server, handshake will fail. The arg can be empty + if the client does not have any information about trusted server + identity. + Returns: + A ChannelCredentials for use with an ALTS-enabled Channel + """ + return ChannelCredentials( + _cygrpc.channel_credentials_alts(service_accounts or [])) + + +def alts_server_credentials(): + """Creates a ServerCredentials for use with an ALTS-enabled connection. + + This is an EXPERIMENTAL API. + ALTS credentials API can only be used in GCP environment as it relies on + handshaker service being available. For more info about ALTS see + https://cloud.google.com/security/encryption-in-transit/application-layer-transport-security + + Returns: + A ServerCredentials for use with an ALTS-enabled Server + """ + return ServerCredentials(_cygrpc.server_credentials_alts()) + + +def compute_engine_channel_credentials(call_credentials): + """Creates a compute engine channel credential. + + This credential can only be used in a GCP environment as it relies on + a handshaker service. For more info about ALTS, see + https://cloud.google.com/security/encryption-in-transit/application-layer-transport-security + + This channel credential is expected to be used as part of a composite + credential in conjunction with a call credentials that authenticates the + VM's default service account. If used with any other sort of call + credential, the connection may suddenly and unexpectedly begin failing RPCs. + """ + return ChannelCredentials( + _cygrpc.channel_credentials_compute_engine( + call_credentials._credentials)) + + +def channel_ready_future(channel): + """Creates a Future that tracks when a Channel is ready. + + Cancelling the Future does not affect the channel's state machine. + It merely decouples the Future from channel state machine. + + Args: + channel: A Channel object. + + Returns: + A Future object that matures when the channel connectivity is + ChannelConnectivity.READY. + """ + from grpc import _utilities # pylint: disable=cyclic-import + return _utilities.channel_ready_future(channel) + + +def insecure_channel(target, options=None, compression=None): + """Creates an insecure Channel to a server. + + The returned Channel is thread-safe. + + Args: + target: The server address + options: An optional list of key-value pairs (:term:`channel_arguments` + in gRPC Core runtime) to configure the channel. + compression: An optional value indicating the compression method to be + used over the lifetime of the channel. This is an EXPERIMENTAL option. + + Returns: + A Channel. + """ + from grpc import _channel # pylint: disable=cyclic-import + return _channel.Channel(target, () if options is None else options, None, + compression) + + +def secure_channel(target, credentials, options=None, compression=None): + """Creates a secure Channel to a server. + + The returned Channel is thread-safe. + + Args: + target: The server address. + credentials: A ChannelCredentials instance. + options: An optional list of key-value pairs (:term:`channel_arguments` + in gRPC Core runtime) to configure the channel. + compression: An optional value indicating the compression method to be + used over the lifetime of the channel. This is an EXPERIMENTAL option. + + Returns: + A Channel. + """ + from grpc import _channel # pylint: disable=cyclic-import + from grpc.experimental import _insecure_channel_credentials + if credentials._credentials is _insecure_channel_credentials: + raise ValueError( + "secure_channel cannot be called with insecure credentials." + + " Call insecure_channel instead.") + return _channel.Channel(target, () if options is None else options, + credentials._credentials, compression) + + +def intercept_channel(channel, *interceptors): + """Intercepts a channel through a set of interceptors. + + Args: + channel: A Channel. + interceptors: Zero or more objects of type + UnaryUnaryClientInterceptor, + UnaryStreamClientInterceptor, + StreamUnaryClientInterceptor, or + StreamStreamClientInterceptor. + Interceptors are given control in the order they are listed. + + Returns: + A Channel that intercepts each invocation via the provided interceptors. + + Raises: + TypeError: If interceptor does not derive from any of + UnaryUnaryClientInterceptor, + UnaryStreamClientInterceptor, + StreamUnaryClientInterceptor, or + StreamStreamClientInterceptor. + """ + from grpc import _interceptor # pylint: disable=cyclic-import + return _interceptor.intercept_channel(channel, *interceptors) + + +def server(thread_pool, + handlers=None, + interceptors=None, + options=None, + maximum_concurrent_rpcs=None, + compression=None, + xds=False): + """Creates a Server with which RPCs can be serviced. + + Args: + thread_pool: A futures.ThreadPoolExecutor to be used by the Server + to execute RPC handlers. + handlers: An optional list of GenericRpcHandlers used for executing RPCs. + More handlers may be added by calling add_generic_rpc_handlers any time + before the server is started. + interceptors: An optional list of ServerInterceptor objects that observe + and optionally manipulate the incoming RPCs before handing them over to + handlers. The interceptors are given control in the order they are + specified. This is an EXPERIMENTAL API. + options: An optional list of key-value pairs (:term:`channel_arguments` in gRPC runtime) + to configure the channel. + maximum_concurrent_rpcs: The maximum number of concurrent RPCs this server + will service before returning RESOURCE_EXHAUSTED status, or None to + indicate no limit. + compression: An element of grpc.compression, e.g. + grpc.compression.Gzip. This compression algorithm will be used for the + lifetime of the server unless overridden. This is an EXPERIMENTAL option. + xds: If set to true, retrieves server configuration via xDS. This is an + EXPERIMENTAL option. + + Returns: + A Server object. + """ + from grpc import _server # pylint: disable=cyclic-import + return _server.create_server(thread_pool, + () if handlers is None else handlers, + () if interceptors is None else interceptors, + () if options is None else options, + maximum_concurrent_rpcs, compression, xds) + + +@contextlib.contextmanager +def _create_servicer_context(rpc_event, state, request_deserializer): + from grpc import _server # pylint: disable=cyclic-import + context = _server._Context(rpc_event, state, request_deserializer) + yield context + context._finalize_state() # pylint: disable=protected-access + + +@enum.unique +class Compression(enum.IntEnum): + """Indicates the compression method to be used for an RPC. + + This enumeration is part of an EXPERIMENTAL API. + + Attributes: + NoCompression: Do not use compression algorithm. + Deflate: Use "Deflate" compression algorithm. + Gzip: Use "Gzip" compression algorithm. + """ + NoCompression = _compression.NoCompression + Deflate = _compression.Deflate + Gzip = _compression.Gzip + + +################################### __all__ ################################# + +__all__ = ( + 'FutureTimeoutError', + 'FutureCancelledError', + 'Future', + 'ChannelConnectivity', + 'StatusCode', + 'Status', + 'RpcError', + 'RpcContext', + 'Call', + 'ChannelCredentials', + 'CallCredentials', + 'AuthMetadataContext', + 'AuthMetadataPluginCallback', + 'AuthMetadataPlugin', + 'Compression', + 'ClientCallDetails', + 'ServerCertificateConfiguration', + 'ServerCredentials', + 'LocalConnectionType', + 'UnaryUnaryMultiCallable', + 'UnaryStreamMultiCallable', + 'StreamUnaryMultiCallable', + 'StreamStreamMultiCallable', + 'UnaryUnaryClientInterceptor', + 'UnaryStreamClientInterceptor', + 'StreamUnaryClientInterceptor', + 'StreamStreamClientInterceptor', + 'Channel', + 'ServicerContext', + 'RpcMethodHandler', + 'HandlerCallDetails', + 'GenericRpcHandler', + 'ServiceRpcHandler', + 'Server', + 'ServerInterceptor', + 'unary_unary_rpc_method_handler', + 'unary_stream_rpc_method_handler', + 'stream_unary_rpc_method_handler', + 'stream_stream_rpc_method_handler', + 'method_handlers_generic_handler', + 'ssl_channel_credentials', + 'metadata_call_credentials', + 'access_token_call_credentials', + 'composite_call_credentials', + 'composite_channel_credentials', + 'compute_engine_channel_credentials', + 'local_channel_credentials', + 'local_server_credentials', + 'alts_channel_credentials', + 'alts_server_credentials', + 'ssl_server_credentials', + 'ssl_server_certificate_configuration', + 'dynamic_ssl_server_credentials', + 'channel_ready_future', + 'insecure_channel', + 'secure_channel', + 'intercept_channel', + 'server', + 'protos', + 'services', + 'protos_and_services', + 'xds_channel_credentials', + 'xds_server_credentials', + 'insecure_server_credentials', +) + +############################### Extension Shims ################################ + +# Here to maintain backwards compatibility; avoid using these in new code! +try: + import grpc_tools + sys.modules.update({'grpc.tools': grpc_tools}) +except ImportError: + pass +try: + import grpc_health + sys.modules.update({'grpc.health': grpc_health}) +except ImportError: + pass +try: + import grpc_reflection + sys.modules.update({'grpc.reflection': grpc_reflection}) +except ImportError: + pass + +# Prevents import order issue in the case of renamed path. +if sys.version_info >= (3, 6) and __name__ == "grpc": + from grpc import aio # pylint: disable=ungrouped-imports + sys.modules.update({'grpc.aio': aio}) diff --git a/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/grpc/_channel.py b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/grpc/_channel.py new file mode 100644 index 0000000000000000000000000000000000000000..b36e70f4a991edc4efa9510ea36a871868dae481 --- /dev/null +++ b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/grpc/_channel.py @@ -0,0 +1,1585 @@ +# Copyright 2016 gRPC authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""Invocation-side implementation of gRPC Python.""" + +import copy +import functools +import logging +import os +import sys +import threading +import time + +import grpc +from grpc import _common +from grpc import _compression +from grpc import _grpcio_metadata +from grpc._cython import cygrpc +import grpc.experimental + +_LOGGER = logging.getLogger(__name__) + +_USER_AGENT = 'grpc-python/{}'.format(_grpcio_metadata.__version__) + +_EMPTY_FLAGS = 0 + +# NOTE(rbellevi): No guarantees are given about the maintenance of this +# environment variable. +_DEFAULT_SINGLE_THREADED_UNARY_STREAM = os.getenv( + "GRPC_SINGLE_THREADED_UNARY_STREAM") is not None + +_UNARY_UNARY_INITIAL_DUE = ( + cygrpc.OperationType.send_initial_metadata, + cygrpc.OperationType.send_message, + cygrpc.OperationType.send_close_from_client, + cygrpc.OperationType.receive_initial_metadata, + cygrpc.OperationType.receive_message, + cygrpc.OperationType.receive_status_on_client, +) +_UNARY_STREAM_INITIAL_DUE = ( + cygrpc.OperationType.send_initial_metadata, + cygrpc.OperationType.send_message, + cygrpc.OperationType.send_close_from_client, + cygrpc.OperationType.receive_initial_metadata, + cygrpc.OperationType.receive_status_on_client, +) +_STREAM_UNARY_INITIAL_DUE = ( + cygrpc.OperationType.send_initial_metadata, + cygrpc.OperationType.receive_initial_metadata, + cygrpc.OperationType.receive_message, + cygrpc.OperationType.receive_status_on_client, +) +_STREAM_STREAM_INITIAL_DUE = ( + cygrpc.OperationType.send_initial_metadata, + cygrpc.OperationType.receive_initial_metadata, + cygrpc.OperationType.receive_status_on_client, +) + +_CHANNEL_SUBSCRIPTION_CALLBACK_ERROR_LOG_MESSAGE = ( + 'Exception calling channel subscription callback!') + +_OK_RENDEZVOUS_REPR_FORMAT = ('<{} of RPC that terminated with:\n' + '\tstatus = {}\n' + '\tdetails = "{}"\n' + '>') + +_NON_OK_RENDEZVOUS_REPR_FORMAT = ('<{} of RPC that terminated with:\n' + '\tstatus = {}\n' + '\tdetails = "{}"\n' + '\tdebug_error_string = "{}"\n' + '>') + + +def _deadline(timeout): + return None if timeout is None else time.time() + timeout + + +def _unknown_code_details(unknown_cygrpc_code, details): + return 'Server sent unknown code {} and details "{}"'.format( + unknown_cygrpc_code, details) + + +class _RPCState(object): + + def __init__(self, due, initial_metadata, trailing_metadata, code, details): + # `condition` guards all members of _RPCState. `notify_all` is called on + # `condition` when the state of the RPC has changed. + self.condition = threading.Condition() + + # The cygrpc.OperationType objects representing events due from the RPC's + # completion queue. If an operation is in `due`, it is guaranteed that + # `operate()` has been called on a corresponding operation. But the + # converse is not true. That is, in the case of failed `operate()` + # calls, there may briefly be events in `due` that do not correspond to + # operations submitted to Core. + self.due = set(due) + self.initial_metadata = initial_metadata + self.response = None + self.trailing_metadata = trailing_metadata + self.code = code + self.details = details + self.debug_error_string = None + + # The semantics of grpc.Future.cancel and grpc.Future.cancelled are + # slightly wonky, so they have to be tracked separately from the rest of the + # result of the RPC. This field tracks whether cancellation was requested + # prior to termination of the RPC. + self.cancelled = False + self.callbacks = [] + self.fork_epoch = cygrpc.get_fork_epoch() + + def reset_postfork_child(self): + self.condition = threading.Condition() + + +def _abort(state, code, details): + if state.code is None: + state.code = code + state.details = details + if state.initial_metadata is None: + state.initial_metadata = () + state.trailing_metadata = () + + +def _handle_event(event, state, response_deserializer): + callbacks = [] + for batch_operation in event.batch_operations: + operation_type = batch_operation.type() + state.due.remove(operation_type) + if operation_type == cygrpc.OperationType.receive_initial_metadata: + state.initial_metadata = batch_operation.initial_metadata() + elif operation_type == cygrpc.OperationType.receive_message: + serialized_response = batch_operation.message() + if serialized_response is not None: + response = _common.deserialize(serialized_response, + response_deserializer) + if response is None: + details = 'Exception deserializing response!' + _abort(state, grpc.StatusCode.INTERNAL, details) + else: + state.response = response + elif operation_type == cygrpc.OperationType.receive_status_on_client: + state.trailing_metadata = batch_operation.trailing_metadata() + if state.code is None: + code = _common.CYGRPC_STATUS_CODE_TO_STATUS_CODE.get( + batch_operation.code()) + if code is None: + state.code = grpc.StatusCode.UNKNOWN + state.details = _unknown_code_details( + code, batch_operation.details()) + else: + state.code = code + state.details = batch_operation.details() + state.debug_error_string = batch_operation.error_string() + callbacks.extend(state.callbacks) + state.callbacks = None + return callbacks + + +def _event_handler(state, response_deserializer): + + def handle_event(event): + with state.condition: + callbacks = _handle_event(event, state, response_deserializer) + state.condition.notify_all() + done = not state.due + for callback in callbacks: + try: + callback() + except Exception as e: # pylint: disable=broad-except + # NOTE(rbellevi): We suppress but log errors here so as not to + # kill the channel spin thread. + logging.error('Exception in callback %s: %s', + repr(callback.func), repr(e)) + return done and state.fork_epoch >= cygrpc.get_fork_epoch() + + return handle_event + + +#pylint: disable=too-many-statements +def _consume_request_iterator(request_iterator, state, call, request_serializer, + event_handler): + """Consume a request iterator supplied by the user.""" + + def consume_request_iterator(): # pylint: disable=too-many-branches + # Iterate over the request iterator until it is exhausted or an error + # condition is encountered. + while True: + return_from_user_request_generator_invoked = False + try: + # The thread may die in user-code. Do not block fork for this. + cygrpc.enter_user_request_generator() + request = next(request_iterator) + except StopIteration: + break + except Exception: # pylint: disable=broad-except + cygrpc.return_from_user_request_generator() + return_from_user_request_generator_invoked = True + code = grpc.StatusCode.UNKNOWN + details = 'Exception iterating requests!' + _LOGGER.exception(details) + call.cancel(_common.STATUS_CODE_TO_CYGRPC_STATUS_CODE[code], + details) + _abort(state, code, details) + return + finally: + if not return_from_user_request_generator_invoked: + cygrpc.return_from_user_request_generator() + serialized_request = _common.serialize(request, request_serializer) + with state.condition: + if state.code is None and not state.cancelled: + if serialized_request is None: + code = grpc.StatusCode.INTERNAL + details = 'Exception serializing request!' + call.cancel( + _common.STATUS_CODE_TO_CYGRPC_STATUS_CODE[code], + details) + _abort(state, code, details) + return + else: + state.due.add(cygrpc.OperationType.send_message) + operations = (cygrpc.SendMessageOperation( + serialized_request, _EMPTY_FLAGS),) + operating = call.operate(operations, event_handler) + if not operating: + state.due.remove(cygrpc.OperationType.send_message) + return + + def _done(): + return (state.code is not None or + cygrpc.OperationType.send_message + not in state.due) + + _common.wait(state.condition.wait, + _done, + spin_cb=functools.partial( + cygrpc.block_if_fork_in_progress, + state)) + if state.code is not None: + return + else: + return + with state.condition: + if state.code is None: + state.due.add(cygrpc.OperationType.send_close_from_client) + operations = ( + cygrpc.SendCloseFromClientOperation(_EMPTY_FLAGS),) + operating = call.operate(operations, event_handler) + if not operating: + state.due.remove( + cygrpc.OperationType.send_close_from_client) + + consumption_thread = cygrpc.ForkManagedThread( + target=consume_request_iterator) + consumption_thread.setDaemon(True) + consumption_thread.start() + + +def _rpc_state_string(class_name, rpc_state): + """Calculates error string for RPC.""" + with rpc_state.condition: + if rpc_state.code is None: + return '<{} object>'.format(class_name) + elif rpc_state.code is grpc.StatusCode.OK: + return _OK_RENDEZVOUS_REPR_FORMAT.format(class_name, rpc_state.code, + rpc_state.details) + else: + return _NON_OK_RENDEZVOUS_REPR_FORMAT.format( + class_name, rpc_state.code, rpc_state.details, + rpc_state.debug_error_string) + + +class _InactiveRpcError(grpc.RpcError, grpc.Call, grpc.Future): + """An RPC error not tied to the execution of a particular RPC. + + The RPC represented by the state object must not be in-progress or + cancelled. + + Attributes: + _state: An instance of _RPCState. + """ + + def __init__(self, state): + with state.condition: + self._state = _RPCState((), copy.deepcopy(state.initial_metadata), + copy.deepcopy(state.trailing_metadata), + state.code, copy.deepcopy(state.details)) + self._state.response = copy.copy(state.response) + self._state.debug_error_string = copy.copy(state.debug_error_string) + + def initial_metadata(self): + return self._state.initial_metadata + + def trailing_metadata(self): + return self._state.trailing_metadata + + def code(self): + return self._state.code + + def details(self): + return _common.decode(self._state.details) + + def debug_error_string(self): + return _common.decode(self._state.debug_error_string) + + def _repr(self): + return _rpc_state_string(self.__class__.__name__, self._state) + + def __repr__(self): + return self._repr() + + def __str__(self): + return self._repr() + + def cancel(self): + """See grpc.Future.cancel.""" + return False + + def cancelled(self): + """See grpc.Future.cancelled.""" + return False + + def running(self): + """See grpc.Future.running.""" + return False + + def done(self): + """See grpc.Future.done.""" + return True + + def result(self, timeout=None): # pylint: disable=unused-argument + """See grpc.Future.result.""" + raise self + + def exception(self, timeout=None): # pylint: disable=unused-argument + """See grpc.Future.exception.""" + return self + + def traceback(self, timeout=None): # pylint: disable=unused-argument + """See grpc.Future.traceback.""" + try: + raise self + except grpc.RpcError: + return sys.exc_info()[2] + + def add_done_callback(self, fn, timeout=None): # pylint: disable=unused-argument + """See grpc.Future.add_done_callback.""" + fn(self) + + +class _Rendezvous(grpc.RpcError, grpc.RpcContext): + """An RPC iterator. + + Attributes: + _state: An instance of _RPCState. + _call: An instance of SegregatedCall or IntegratedCall. + In either case, the _call object is expected to have operate, cancel, + and next_event methods. + _response_deserializer: A callable taking bytes and return a Python + object. + _deadline: A float representing the deadline of the RPC in seconds. Or + possibly None, to represent an RPC with no deadline at all. + """ + + def __init__(self, state, call, response_deserializer, deadline): + super(_Rendezvous, self).__init__() + self._state = state + self._call = call + self._response_deserializer = response_deserializer + self._deadline = deadline + + def is_active(self): + """See grpc.RpcContext.is_active""" + with self._state.condition: + return self._state.code is None + + def time_remaining(self): + """See grpc.RpcContext.time_remaining""" + with self._state.condition: + if self._deadline is None: + return None + else: + return max(self._deadline - time.time(), 0) + + def cancel(self): + """See grpc.RpcContext.cancel""" + with self._state.condition: + if self._state.code is None: + code = grpc.StatusCode.CANCELLED + details = 'Locally cancelled by application!' + self._call.cancel( + _common.STATUS_CODE_TO_CYGRPC_STATUS_CODE[code], details) + self._state.cancelled = True + _abort(self._state, code, details) + self._state.condition.notify_all() + return True + else: + return False + + def add_callback(self, callback): + """See grpc.RpcContext.add_callback""" + with self._state.condition: + if self._state.callbacks is None: + return False + else: + self._state.callbacks.append(callback) + return True + + def __iter__(self): + return self + + def next(self): + return self._next() + + def __next__(self): + return self._next() + + def _next(self): + raise NotImplementedError() + + def debug_error_string(self): + raise NotImplementedError() + + def _repr(self): + return _rpc_state_string(self.__class__.__name__, self._state) + + def __repr__(self): + return self._repr() + + def __str__(self): + return self._repr() + + def __del__(self): + with self._state.condition: + if self._state.code is None: + self._state.code = grpc.StatusCode.CANCELLED + self._state.details = 'Cancelled upon garbage collection!' + self._state.cancelled = True + self._call.cancel( + _common.STATUS_CODE_TO_CYGRPC_STATUS_CODE[self._state.code], + self._state.details) + self._state.condition.notify_all() + + +class _SingleThreadedRendezvous(_Rendezvous, grpc.Call, grpc.Future): # pylint: disable=too-many-ancestors + """An RPC iterator operating entirely on a single thread. + + The __next__ method of _SingleThreadedRendezvous does not depend on the + existence of any other thread, including the "channel spin thread". + However, this means that its interface is entirely synchronous. So this + class cannot completely fulfill the grpc.Future interface. The result, + exception, and traceback methods will never block and will instead raise + an exception if calling the method would result in blocking. + + This means that these methods are safe to call from add_done_callback + handlers. + """ + + def _is_complete(self): + return self._state.code is not None + + def cancelled(self): + with self._state.condition: + return self._state.cancelled + + def running(self): + with self._state.condition: + return self._state.code is None + + def done(self): + with self._state.condition: + return self._state.code is not None + + def result(self, timeout=None): + """Returns the result of the computation or raises its exception. + + This method will never block. Instead, it will raise an exception + if calling this method would otherwise result in blocking. + + Since this method will never block, any `timeout` argument passed will + be ignored. + """ + del timeout + with self._state.condition: + if not self._is_complete(): + raise grpc.experimental.UsageError( + "_SingleThreadedRendezvous only supports result() when the RPC is complete." + ) + if self._state.code is grpc.StatusCode.OK: + return self._state.response + elif self._state.cancelled: + raise grpc.FutureCancelledError() + else: + raise self + + def exception(self, timeout=None): + """Return the exception raised by the computation. + + This method will never block. Instead, it will raise an exception + if calling this method would otherwise result in blocking. + + Since this method will never block, any `timeout` argument passed will + be ignored. + """ + del timeout + with self._state.condition: + if not self._is_complete(): + raise grpc.experimental.UsageError( + "_SingleThreadedRendezvous only supports exception() when the RPC is complete." + ) + if self._state.code is grpc.StatusCode.OK: + return None + elif self._state.cancelled: + raise grpc.FutureCancelledError() + else: + return self + + def traceback(self, timeout=None): + """Access the traceback of the exception raised by the computation. + + This method will never block. Instead, it will raise an exception + if calling this method would otherwise result in blocking. + + Since this method will never block, any `timeout` argument passed will + be ignored. + """ + del timeout + with self._state.condition: + if not self._is_complete(): + raise grpc.experimental.UsageError( + "_SingleThreadedRendezvous only supports traceback() when the RPC is complete." + ) + if self._state.code is grpc.StatusCode.OK: + return None + elif self._state.cancelled: + raise grpc.FutureCancelledError() + else: + try: + raise self + except grpc.RpcError: + return sys.exc_info()[2] + + def add_done_callback(self, fn): + with self._state.condition: + if self._state.code is None: + self._state.callbacks.append(functools.partial(fn, self)) + return + + fn(self) + + def initial_metadata(self): + """See grpc.Call.initial_metadata""" + with self._state.condition: + # NOTE(gnossen): Based on our initial call batch, we are guaranteed + # to receive initial metadata before any messages. + while self._state.initial_metadata is None: + self._consume_next_event() + return self._state.initial_metadata + + def trailing_metadata(self): + """See grpc.Call.trailing_metadata""" + with self._state.condition: + if self._state.trailing_metadata is None: + raise grpc.experimental.UsageError( + "Cannot get trailing metadata until RPC is completed.") + return self._state.trailing_metadata + + def code(self): + """See grpc.Call.code""" + with self._state.condition: + if self._state.code is None: + raise grpc.experimental.UsageError( + "Cannot get code until RPC is completed.") + return self._state.code + + def details(self): + """See grpc.Call.details""" + with self._state.condition: + if self._state.details is None: + raise grpc.experimental.UsageError( + "Cannot get details until RPC is completed.") + return _common.decode(self._state.details) + + def _consume_next_event(self): + event = self._call.next_event() + with self._state.condition: + callbacks = _handle_event(event, self._state, + self._response_deserializer) + for callback in callbacks: + # NOTE(gnossen): We intentionally allow exceptions to bubble up + # to the user when running on a single thread. + callback() + return event + + def _next_response(self): + while True: + self._consume_next_event() + with self._state.condition: + if self._state.response is not None: + response = self._state.response + self._state.response = None + return response + elif cygrpc.OperationType.receive_message not in self._state.due: + if self._state.code is grpc.StatusCode.OK: + raise StopIteration() + elif self._state.code is not None: + raise self + + def _next(self): + with self._state.condition: + if self._state.code is None: + # We tentatively add the operation as expected and remove + # it if the enqueue operation fails. This allows us to guarantee that + # if an event has been submitted to the core completion queue, + # it is in `due`. If we waited until after a successful + # enqueue operation then a signal could interrupt this + # thread between the enqueue operation and the addition of the + # operation to `due`. This would cause an exception on the + # channel spin thread when the operation completes and no + # corresponding operation would be present in state.due. + # Note that, since `condition` is held through this block, there is + # no data race on `due`. + self._state.due.add(cygrpc.OperationType.receive_message) + operating = self._call.operate( + (cygrpc.ReceiveMessageOperation(_EMPTY_FLAGS),), None) + if not operating: + self._state.due.remove(cygrpc.OperationType.receive_message) + elif self._state.code is grpc.StatusCode.OK: + raise StopIteration() + else: + raise self + return self._next_response() + + def debug_error_string(self): + with self._state.condition: + if self._state.debug_error_string is None: + raise grpc.experimental.UsageError( + "Cannot get debug error string until RPC is completed.") + return _common.decode(self._state.debug_error_string) + + +class _MultiThreadedRendezvous(_Rendezvous, grpc.Call, grpc.Future): # pylint: disable=too-many-ancestors + """An RPC iterator that depends on a channel spin thread. + + This iterator relies upon a per-channel thread running in the background, + dequeueing events from the completion queue, and notifying threads waiting + on the threading.Condition object in the _RPCState object. + + This extra thread allows _MultiThreadedRendezvous to fulfill the grpc.Future interface + and to mediate a bidirection streaming RPC. + """ + + def initial_metadata(self): + """See grpc.Call.initial_metadata""" + with self._state.condition: + + def _done(): + return self._state.initial_metadata is not None + + _common.wait(self._state.condition.wait, _done) + return self._state.initial_metadata + + def trailing_metadata(self): + """See grpc.Call.trailing_metadata""" + with self._state.condition: + + def _done(): + return self._state.trailing_metadata is not None + + _common.wait(self._state.condition.wait, _done) + return self._state.trailing_metadata + + def code(self): + """See grpc.Call.code""" + with self._state.condition: + + def _done(): + return self._state.code is not None + + _common.wait(self._state.condition.wait, _done) + return self._state.code + + def details(self): + """See grpc.Call.details""" + with self._state.condition: + + def _done(): + return self._state.details is not None + + _common.wait(self._state.condition.wait, _done) + return _common.decode(self._state.details) + + def debug_error_string(self): + with self._state.condition: + + def _done(): + return self._state.debug_error_string is not None + + _common.wait(self._state.condition.wait, _done) + return _common.decode(self._state.debug_error_string) + + def cancelled(self): + with self._state.condition: + return self._state.cancelled + + def running(self): + with self._state.condition: + return self._state.code is None + + def done(self): + with self._state.condition: + return self._state.code is not None + + def _is_complete(self): + return self._state.code is not None + + def result(self, timeout=None): + """Returns the result of the computation or raises its exception. + + See grpc.Future.result for the full API contract. + """ + with self._state.condition: + timed_out = _common.wait(self._state.condition.wait, + self._is_complete, + timeout=timeout) + if timed_out: + raise grpc.FutureTimeoutError() + else: + if self._state.code is grpc.StatusCode.OK: + return self._state.response + elif self._state.cancelled: + raise grpc.FutureCancelledError() + else: + raise self + + def exception(self, timeout=None): + """Return the exception raised by the computation. + + See grpc.Future.exception for the full API contract. + """ + with self._state.condition: + timed_out = _common.wait(self._state.condition.wait, + self._is_complete, + timeout=timeout) + if timed_out: + raise grpc.FutureTimeoutError() + else: + if self._state.code is grpc.StatusCode.OK: + return None + elif self._state.cancelled: + raise grpc.FutureCancelledError() + else: + return self + + def traceback(self, timeout=None): + """Access the traceback of the exception raised by the computation. + + See grpc.future.traceback for the full API contract. + """ + with self._state.condition: + timed_out = _common.wait(self._state.condition.wait, + self._is_complete, + timeout=timeout) + if timed_out: + raise grpc.FutureTimeoutError() + else: + if self._state.code is grpc.StatusCode.OK: + return None + elif self._state.cancelled: + raise grpc.FutureCancelledError() + else: + try: + raise self + except grpc.RpcError: + return sys.exc_info()[2] + + def add_done_callback(self, fn): + with self._state.condition: + if self._state.code is None: + self._state.callbacks.append(functools.partial(fn, self)) + return + + fn(self) + + def _next(self): + with self._state.condition: + if self._state.code is None: + event_handler = _event_handler(self._state, + self._response_deserializer) + self._state.due.add(cygrpc.OperationType.receive_message) + operating = self._call.operate( + (cygrpc.ReceiveMessageOperation(_EMPTY_FLAGS),), + event_handler) + if not operating: + self._state.due.remove(cygrpc.OperationType.receive_message) + elif self._state.code is grpc.StatusCode.OK: + raise StopIteration() + else: + raise self + + def _response_ready(): + return (self._state.response is not None or + (cygrpc.OperationType.receive_message + not in self._state.due and + self._state.code is not None)) + + _common.wait(self._state.condition.wait, _response_ready) + if self._state.response is not None: + response = self._state.response + self._state.response = None + return response + elif cygrpc.OperationType.receive_message not in self._state.due: + if self._state.code is grpc.StatusCode.OK: + raise StopIteration() + elif self._state.code is not None: + raise self + + +def _start_unary_request(request, timeout, request_serializer): + deadline = _deadline(timeout) + serialized_request = _common.serialize(request, request_serializer) + if serialized_request is None: + state = _RPCState((), (), (), grpc.StatusCode.INTERNAL, + 'Exception serializing request!') + error = _InactiveRpcError(state) + return deadline, None, error + else: + return deadline, serialized_request, None + + +def _end_unary_response_blocking(state, call, with_call, deadline): + if state.code is grpc.StatusCode.OK: + if with_call: + rendezvous = _MultiThreadedRendezvous(state, call, None, deadline) + return state.response, rendezvous + else: + return state.response + else: + raise _InactiveRpcError(state) + + +def _stream_unary_invocation_operationses(metadata, initial_metadata_flags): + return ( + ( + cygrpc.SendInitialMetadataOperation(metadata, + initial_metadata_flags), + cygrpc.ReceiveMessageOperation(_EMPTY_FLAGS), + cygrpc.ReceiveStatusOnClientOperation(_EMPTY_FLAGS), + ), + (cygrpc.ReceiveInitialMetadataOperation(_EMPTY_FLAGS),), + ) + + +def _stream_unary_invocation_operationses_and_tags(metadata, + initial_metadata_flags): + return tuple(( + operations, + None, + ) for operations in _stream_unary_invocation_operationses( + metadata, initial_metadata_flags)) + + +def _determine_deadline(user_deadline): + parent_deadline = cygrpc.get_deadline_from_context() + if parent_deadline is None and user_deadline is None: + return None + elif parent_deadline is not None and user_deadline is None: + return parent_deadline + elif user_deadline is not None and parent_deadline is None: + return user_deadline + else: + return min(parent_deadline, user_deadline) + + +class _UnaryUnaryMultiCallable(grpc.UnaryUnaryMultiCallable): + + # pylint: disable=too-many-arguments + def __init__(self, channel, managed_call, method, request_serializer, + response_deserializer): + self._channel = channel + self._managed_call = managed_call + self._method = method + self._request_serializer = request_serializer + self._response_deserializer = response_deserializer + self._context = cygrpc.build_census_context() + + def _prepare(self, request, timeout, metadata, wait_for_ready, compression): + deadline, serialized_request, rendezvous = _start_unary_request( + request, timeout, self._request_serializer) + initial_metadata_flags = _InitialMetadataFlags().with_wait_for_ready( + wait_for_ready) + augmented_metadata = _compression.augment_metadata( + metadata, compression) + if serialized_request is None: + return None, None, None, rendezvous + else: + state = _RPCState(_UNARY_UNARY_INITIAL_DUE, None, None, None, None) + operations = ( + cygrpc.SendInitialMetadataOperation(augmented_metadata, + initial_metadata_flags), + cygrpc.SendMessageOperation(serialized_request, _EMPTY_FLAGS), + cygrpc.SendCloseFromClientOperation(_EMPTY_FLAGS), + cygrpc.ReceiveInitialMetadataOperation(_EMPTY_FLAGS), + cygrpc.ReceiveMessageOperation(_EMPTY_FLAGS), + cygrpc.ReceiveStatusOnClientOperation(_EMPTY_FLAGS), + ) + return state, operations, deadline, None + + def _blocking(self, request, timeout, metadata, credentials, wait_for_ready, + compression): + state, operations, deadline, rendezvous = self._prepare( + request, timeout, metadata, wait_for_ready, compression) + if state is None: + raise rendezvous # pylint: disable-msg=raising-bad-type + else: + call = self._channel.segregated_call( + cygrpc.PropagationConstants.GRPC_PROPAGATE_DEFAULTS, + self._method, None, _determine_deadline(deadline), metadata, + None if credentials is None else credentials._credentials, (( + operations, + None, + ),), self._context) + event = call.next_event() + _handle_event(event, state, self._response_deserializer) + return state, call + + def __call__(self, + request, + timeout=None, + metadata=None, + credentials=None, + wait_for_ready=None, + compression=None): + state, call, = self._blocking(request, timeout, metadata, credentials, + wait_for_ready, compression) + return _end_unary_response_blocking(state, call, False, None) + + def with_call(self, + request, + timeout=None, + metadata=None, + credentials=None, + wait_for_ready=None, + compression=None): + state, call, = self._blocking(request, timeout, metadata, credentials, + wait_for_ready, compression) + return _end_unary_response_blocking(state, call, True, None) + + def future(self, + request, + timeout=None, + metadata=None, + credentials=None, + wait_for_ready=None, + compression=None): + state, operations, deadline, rendezvous = self._prepare( + request, timeout, metadata, wait_for_ready, compression) + if state is None: + raise rendezvous # pylint: disable-msg=raising-bad-type + else: + event_handler = _event_handler(state, self._response_deserializer) + call = self._managed_call( + cygrpc.PropagationConstants.GRPC_PROPAGATE_DEFAULTS, + self._method, None, deadline, metadata, + None if credentials is None else credentials._credentials, + (operations,), event_handler, self._context) + return _MultiThreadedRendezvous(state, call, + self._response_deserializer, + deadline) + + +class _SingleThreadedUnaryStreamMultiCallable(grpc.UnaryStreamMultiCallable): + + # pylint: disable=too-many-arguments + def __init__(self, channel, method, request_serializer, + response_deserializer): + self._channel = channel + self._method = method + self._request_serializer = request_serializer + self._response_deserializer = response_deserializer + self._context = cygrpc.build_census_context() + + def __call__( # pylint: disable=too-many-locals + self, + request, + timeout=None, + metadata=None, + credentials=None, + wait_for_ready=None, + compression=None): + deadline = _deadline(timeout) + serialized_request = _common.serialize(request, + self._request_serializer) + if serialized_request is None: + state = _RPCState((), (), (), grpc.StatusCode.INTERNAL, + 'Exception serializing request!') + raise _InactiveRpcError(state) + + state = _RPCState(_UNARY_STREAM_INITIAL_DUE, None, None, None, None) + call_credentials = None if credentials is None else credentials._credentials + initial_metadata_flags = _InitialMetadataFlags().with_wait_for_ready( + wait_for_ready) + augmented_metadata = _compression.augment_metadata( + metadata, compression) + operations = ( + (cygrpc.SendInitialMetadataOperation(augmented_metadata, + initial_metadata_flags), + cygrpc.SendMessageOperation(serialized_request, _EMPTY_FLAGS), + cygrpc.SendCloseFromClientOperation(_EMPTY_FLAGS)), + (cygrpc.ReceiveStatusOnClientOperation(_EMPTY_FLAGS),), + (cygrpc.ReceiveInitialMetadataOperation(_EMPTY_FLAGS),), + ) + operations_and_tags = tuple((ops, None) for ops in operations) + call = self._channel.segregated_call( + cygrpc.PropagationConstants.GRPC_PROPAGATE_DEFAULTS, self._method, + None, _determine_deadline(deadline), metadata, call_credentials, + operations_and_tags, self._context) + return _SingleThreadedRendezvous(state, call, + self._response_deserializer, deadline) + + +class _UnaryStreamMultiCallable(grpc.UnaryStreamMultiCallable): + + # pylint: disable=too-many-arguments + def __init__(self, channel, managed_call, method, request_serializer, + response_deserializer): + self._channel = channel + self._managed_call = managed_call + self._method = method + self._request_serializer = request_serializer + self._response_deserializer = response_deserializer + self._context = cygrpc.build_census_context() + + def __call__( # pylint: disable=too-many-locals + self, + request, + timeout=None, + metadata=None, + credentials=None, + wait_for_ready=None, + compression=None): + deadline, serialized_request, rendezvous = _start_unary_request( + request, timeout, self._request_serializer) + initial_metadata_flags = _InitialMetadataFlags().with_wait_for_ready( + wait_for_ready) + if serialized_request is None: + raise rendezvous # pylint: disable-msg=raising-bad-type + else: + augmented_metadata = _compression.augment_metadata( + metadata, compression) + state = _RPCState(_UNARY_STREAM_INITIAL_DUE, None, None, None, None) + operationses = ( + ( + cygrpc.SendInitialMetadataOperation(augmented_metadata, + initial_metadata_flags), + cygrpc.SendMessageOperation(serialized_request, + _EMPTY_FLAGS), + cygrpc.SendCloseFromClientOperation(_EMPTY_FLAGS), + cygrpc.ReceiveStatusOnClientOperation(_EMPTY_FLAGS), + ), + (cygrpc.ReceiveInitialMetadataOperation(_EMPTY_FLAGS),), + ) + call = self._managed_call( + cygrpc.PropagationConstants.GRPC_PROPAGATE_DEFAULTS, + self._method, None, _determine_deadline(deadline), metadata, + None if credentials is None else credentials._credentials, + operationses, _event_handler(state, + self._response_deserializer), + self._context) + return _MultiThreadedRendezvous(state, call, + self._response_deserializer, + deadline) + + +class _StreamUnaryMultiCallable(grpc.StreamUnaryMultiCallable): + + # pylint: disable=too-many-arguments + def __init__(self, channel, managed_call, method, request_serializer, + response_deserializer): + self._channel = channel + self._managed_call = managed_call + self._method = method + self._request_serializer = request_serializer + self._response_deserializer = response_deserializer + self._context = cygrpc.build_census_context() + + def _blocking(self, request_iterator, timeout, metadata, credentials, + wait_for_ready, compression): + deadline = _deadline(timeout) + state = _RPCState(_STREAM_UNARY_INITIAL_DUE, None, None, None, None) + initial_metadata_flags = _InitialMetadataFlags().with_wait_for_ready( + wait_for_ready) + augmented_metadata = _compression.augment_metadata( + metadata, compression) + call = self._channel.segregated_call( + cygrpc.PropagationConstants.GRPC_PROPAGATE_DEFAULTS, self._method, + None, _determine_deadline(deadline), augmented_metadata, + None if credentials is None else credentials._credentials, + _stream_unary_invocation_operationses_and_tags( + augmented_metadata, initial_metadata_flags), self._context) + _consume_request_iterator(request_iterator, state, call, + self._request_serializer, None) + while True: + event = call.next_event() + with state.condition: + _handle_event(event, state, self._response_deserializer) + state.condition.notify_all() + if not state.due: + break + return state, call + + def __call__(self, + request_iterator, + timeout=None, + metadata=None, + credentials=None, + wait_for_ready=None, + compression=None): + state, call, = self._blocking(request_iterator, timeout, metadata, + credentials, wait_for_ready, compression) + return _end_unary_response_blocking(state, call, False, None) + + def with_call(self, + request_iterator, + timeout=None, + metadata=None, + credentials=None, + wait_for_ready=None, + compression=None): + state, call, = self._blocking(request_iterator, timeout, metadata, + credentials, wait_for_ready, compression) + return _end_unary_response_blocking(state, call, True, None) + + def future(self, + request_iterator, + timeout=None, + metadata=None, + credentials=None, + wait_for_ready=None, + compression=None): + deadline = _deadline(timeout) + state = _RPCState(_STREAM_UNARY_INITIAL_DUE, None, None, None, None) + event_handler = _event_handler(state, self._response_deserializer) + initial_metadata_flags = _InitialMetadataFlags().with_wait_for_ready( + wait_for_ready) + augmented_metadata = _compression.augment_metadata( + metadata, compression) + call = self._managed_call( + cygrpc.PropagationConstants.GRPC_PROPAGATE_DEFAULTS, self._method, + None, deadline, augmented_metadata, + None if credentials is None else credentials._credentials, + _stream_unary_invocation_operationses(metadata, + initial_metadata_flags), + event_handler, self._context) + _consume_request_iterator(request_iterator, state, call, + self._request_serializer, event_handler) + return _MultiThreadedRendezvous(state, call, + self._response_deserializer, deadline) + + +class _StreamStreamMultiCallable(grpc.StreamStreamMultiCallable): + + # pylint: disable=too-many-arguments + def __init__(self, channel, managed_call, method, request_serializer, + response_deserializer): + self._channel = channel + self._managed_call = managed_call + self._method = method + self._request_serializer = request_serializer + self._response_deserializer = response_deserializer + self._context = cygrpc.build_census_context() + + def __call__(self, + request_iterator, + timeout=None, + metadata=None, + credentials=None, + wait_for_ready=None, + compression=None): + deadline = _deadline(timeout) + state = _RPCState(_STREAM_STREAM_INITIAL_DUE, None, None, None, None) + initial_metadata_flags = _InitialMetadataFlags().with_wait_for_ready( + wait_for_ready) + augmented_metadata = _compression.augment_metadata( + metadata, compression) + operationses = ( + ( + cygrpc.SendInitialMetadataOperation(augmented_metadata, + initial_metadata_flags), + cygrpc.ReceiveStatusOnClientOperation(_EMPTY_FLAGS), + ), + (cygrpc.ReceiveInitialMetadataOperation(_EMPTY_FLAGS),), + ) + event_handler = _event_handler(state, self._response_deserializer) + call = self._managed_call( + cygrpc.PropagationConstants.GRPC_PROPAGATE_DEFAULTS, self._method, + None, _determine_deadline(deadline), augmented_metadata, + None if credentials is None else credentials._credentials, + operationses, event_handler, self._context) + _consume_request_iterator(request_iterator, state, call, + self._request_serializer, event_handler) + return _MultiThreadedRendezvous(state, call, + self._response_deserializer, deadline) + + +class _InitialMetadataFlags(int): + """Stores immutable initial metadata flags""" + + def __new__(cls, value=_EMPTY_FLAGS): + value &= cygrpc.InitialMetadataFlags.used_mask + return super(_InitialMetadataFlags, cls).__new__(cls, value) + + def with_wait_for_ready(self, wait_for_ready): + if wait_for_ready is not None: + if wait_for_ready: + return self.__class__(self | cygrpc.InitialMetadataFlags.wait_for_ready | \ + cygrpc.InitialMetadataFlags.wait_for_ready_explicitly_set) + elif not wait_for_ready: + return self.__class__(self & ~cygrpc.InitialMetadataFlags.wait_for_ready | \ + cygrpc.InitialMetadataFlags.wait_for_ready_explicitly_set) + return self + + +class _ChannelCallState(object): + + def __init__(self, channel): + self.lock = threading.Lock() + self.channel = channel + self.managed_calls = 0 + self.threading = False + + def reset_postfork_child(self): + self.managed_calls = 0 + + def __del__(self): + try: + self.channel.close(cygrpc.StatusCode.cancelled, + 'Channel deallocated!') + except (TypeError, AttributeError): + pass + + +def _run_channel_spin_thread(state): + + def channel_spin(): + while True: + cygrpc.block_if_fork_in_progress(state) + event = state.channel.next_call_event() + if event.completion_type == cygrpc.CompletionType.queue_timeout: + continue + call_completed = event.tag(event) + if call_completed: + with state.lock: + state.managed_calls -= 1 + if state.managed_calls == 0: + return + + channel_spin_thread = cygrpc.ForkManagedThread(target=channel_spin) + channel_spin_thread.setDaemon(True) + channel_spin_thread.start() + + +def _channel_managed_call_management(state): + + # pylint: disable=too-many-arguments + def create(flags, method, host, deadline, metadata, credentials, + operationses, event_handler, context): + """Creates a cygrpc.IntegratedCall. + + Args: + flags: An integer bitfield of call flags. + method: The RPC method. + host: A host string for the created call. + deadline: A float to be the deadline of the created call or None if + the call is to have an infinite deadline. + metadata: The metadata for the call or None. + credentials: A cygrpc.CallCredentials or None. + operationses: An iterable of iterables of cygrpc.Operations to be + started on the call. + event_handler: A behavior to call to handle the events resultant from + the operations on the call. + context: Context object for distributed tracing. + Returns: + A cygrpc.IntegratedCall with which to conduct an RPC. + """ + operationses_and_tags = tuple(( + operations, + event_handler, + ) for operations in operationses) + with state.lock: + call = state.channel.integrated_call(flags, method, host, deadline, + metadata, credentials, + operationses_and_tags, context) + if state.managed_calls == 0: + state.managed_calls = 1 + _run_channel_spin_thread(state) + else: + state.managed_calls += 1 + return call + + return create + + +class _ChannelConnectivityState(object): + + def __init__(self, channel): + self.lock = threading.RLock() + self.channel = channel + self.polling = False + self.connectivity = None + self.try_to_connect = False + self.callbacks_and_connectivities = [] + self.delivering = False + + def reset_postfork_child(self): + self.polling = False + self.connectivity = None + self.try_to_connect = False + self.callbacks_and_connectivities = [] + self.delivering = False + + +def _deliveries(state): + callbacks_needing_update = [] + for callback_and_connectivity in state.callbacks_and_connectivities: + callback, callback_connectivity, = callback_and_connectivity + if callback_connectivity is not state.connectivity: + callbacks_needing_update.append(callback) + callback_and_connectivity[1] = state.connectivity + return callbacks_needing_update + + +def _deliver(state, initial_connectivity, initial_callbacks): + connectivity = initial_connectivity + callbacks = initial_callbacks + while True: + for callback in callbacks: + cygrpc.block_if_fork_in_progress(state) + try: + callback(connectivity) + except Exception: # pylint: disable=broad-except + _LOGGER.exception( + _CHANNEL_SUBSCRIPTION_CALLBACK_ERROR_LOG_MESSAGE) + with state.lock: + callbacks = _deliveries(state) + if callbacks: + connectivity = state.connectivity + else: + state.delivering = False + return + + +def _spawn_delivery(state, callbacks): + delivering_thread = cygrpc.ForkManagedThread(target=_deliver, + args=( + state, + state.connectivity, + callbacks, + )) + delivering_thread.setDaemon(True) + delivering_thread.start() + state.delivering = True + + +# NOTE(https://github.com/grpc/grpc/issues/3064): We'd rather not poll. +def _poll_connectivity(state, channel, initial_try_to_connect): + try_to_connect = initial_try_to_connect + connectivity = channel.check_connectivity_state(try_to_connect) + with state.lock: + state.connectivity = ( + _common. + CYGRPC_CONNECTIVITY_STATE_TO_CHANNEL_CONNECTIVITY[connectivity]) + callbacks = tuple( + callback for callback, unused_but_known_to_be_none_connectivity in + state.callbacks_and_connectivities) + for callback_and_connectivity in state.callbacks_and_connectivities: + callback_and_connectivity[1] = state.connectivity + if callbacks: + _spawn_delivery(state, callbacks) + while True: + event = channel.watch_connectivity_state(connectivity, + time.time() + 0.2) + cygrpc.block_if_fork_in_progress(state) + with state.lock: + if not state.callbacks_and_connectivities and not state.try_to_connect: + state.polling = False + state.connectivity = None + break + try_to_connect = state.try_to_connect + state.try_to_connect = False + if event.success or try_to_connect: + connectivity = channel.check_connectivity_state(try_to_connect) + with state.lock: + state.connectivity = ( + _common.CYGRPC_CONNECTIVITY_STATE_TO_CHANNEL_CONNECTIVITY[ + connectivity]) + if not state.delivering: + callbacks = _deliveries(state) + if callbacks: + _spawn_delivery(state, callbacks) + + +def _subscribe(state, callback, try_to_connect): + with state.lock: + if not state.callbacks_and_connectivities and not state.polling: + polling_thread = cygrpc.ForkManagedThread( + target=_poll_connectivity, + args=(state, state.channel, bool(try_to_connect))) + polling_thread.setDaemon(True) + polling_thread.start() + state.polling = True + state.callbacks_and_connectivities.append([callback, None]) + elif not state.delivering and state.connectivity is not None: + _spawn_delivery(state, (callback,)) + state.try_to_connect |= bool(try_to_connect) + state.callbacks_and_connectivities.append( + [callback, state.connectivity]) + else: + state.try_to_connect |= bool(try_to_connect) + state.callbacks_and_connectivities.append([callback, None]) + + +def _unsubscribe(state, callback): + with state.lock: + for index, (subscribed_callback, unused_connectivity) in enumerate( + state.callbacks_and_connectivities): + if callback == subscribed_callback: + state.callbacks_and_connectivities.pop(index) + break + + +def _augment_options(base_options, compression): + compression_option = _compression.create_channel_option(compression) + return tuple(base_options) + compression_option + (( + cygrpc.ChannelArgKey.primary_user_agent_string, + _USER_AGENT, + ),) + + +def _separate_channel_options(options): + """Separates core channel options from Python channel options.""" + core_options = [] + python_options = [] + for pair in options: + if pair[0] == grpc.experimental.ChannelOptions.SingleThreadedUnaryStream: + python_options.append(pair) + else: + core_options.append(pair) + return python_options, core_options + + +class Channel(grpc.Channel): + """A cygrpc.Channel-backed implementation of grpc.Channel.""" + + def __init__(self, target, options, credentials, compression): + """Constructor. + + Args: + target: The target to which to connect. + options: Configuration options for the channel. + credentials: A cygrpc.ChannelCredentials or None. + compression: An optional value indicating the compression method to be + used over the lifetime of the channel. + """ + python_options, core_options = _separate_channel_options(options) + self._single_threaded_unary_stream = _DEFAULT_SINGLE_THREADED_UNARY_STREAM + self._process_python_options(python_options) + self._channel = cygrpc.Channel( + _common.encode(target), _augment_options(core_options, compression), + credentials) + self._call_state = _ChannelCallState(self._channel) + self._connectivity_state = _ChannelConnectivityState(self._channel) + cygrpc.fork_register_channel(self) + if cygrpc.g_gevent_activated: + cygrpc.gevent_increment_channel_count() + + def _process_python_options(self, python_options): + """Sets channel attributes according to python-only channel options.""" + for pair in python_options: + if pair[0] == grpc.experimental.ChannelOptions.SingleThreadedUnaryStream: + self._single_threaded_unary_stream = True + + def subscribe(self, callback, try_to_connect=None): + _subscribe(self._connectivity_state, callback, try_to_connect) + + def unsubscribe(self, callback): + _unsubscribe(self._connectivity_state, callback) + + def unary_unary(self, + method, + request_serializer=None, + response_deserializer=None): + return _UnaryUnaryMultiCallable( + self._channel, _channel_managed_call_management(self._call_state), + _common.encode(method), request_serializer, response_deserializer) + + def unary_stream(self, + method, + request_serializer=None, + response_deserializer=None): + # NOTE(rbellevi): Benchmarks have shown that running a unary-stream RPC + # on a single Python thread results in an appreciable speed-up. However, + # due to slight differences in capability, the multi-threaded variant + # remains the default. + if self._single_threaded_unary_stream: + return _SingleThreadedUnaryStreamMultiCallable( + self._channel, _common.encode(method), request_serializer, + response_deserializer) + else: + return _UnaryStreamMultiCallable( + self._channel, + _channel_managed_call_management(self._call_state), + _common.encode(method), request_serializer, + response_deserializer) + + def stream_unary(self, + method, + request_serializer=None, + response_deserializer=None): + return _StreamUnaryMultiCallable( + self._channel, _channel_managed_call_management(self._call_state), + _common.encode(method), request_serializer, response_deserializer) + + def stream_stream(self, + method, + request_serializer=None, + response_deserializer=None): + return _StreamStreamMultiCallable( + self._channel, _channel_managed_call_management(self._call_state), + _common.encode(method), request_serializer, response_deserializer) + + def _unsubscribe_all(self): + state = self._connectivity_state + if state: + with state.lock: + del state.callbacks_and_connectivities[:] + + def _close(self): + self._unsubscribe_all() + self._channel.close(cygrpc.StatusCode.cancelled, 'Channel closed!') + cygrpc.fork_unregister_channel(self) + if cygrpc.g_gevent_activated: + cygrpc.gevent_decrement_channel_count() + + def _close_on_fork(self): + self._unsubscribe_all() + self._channel.close_on_fork(cygrpc.StatusCode.cancelled, + 'Channel closed due to fork') + + def __enter__(self): + return self + + def __exit__(self, exc_type, exc_val, exc_tb): + self._close() + return False + + def close(self): + self._close() + + def __del__(self): + # TODO(https://github.com/grpc/grpc/issues/12531): Several releases + # after 1.12 (1.16 or thereabouts?) add a "self._channel.close" call + # here (or more likely, call self._close() here). We don't do this today + # because many valid use cases today allow the channel to be deleted + # immediately after stubs are created. After a sufficient period of time + # has passed for all users to be trusted to freeze out to their channels + # for as long as they are in use and to close them after using them, + # then deletion of this grpc._channel.Channel instance can be made to + # effect closure of the underlying cygrpc.Channel instance. + try: + self._unsubscribe_all() + except: # pylint: disable=bare-except + # Exceptions in __del__ are ignored by Python anyway, but they can + # keep spamming logs. Just silence them. + pass diff --git a/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/grpc/_common.py b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/grpc/_common.py new file mode 100644 index 0000000000000000000000000000000000000000..d8f951456e41a03a6f33077aa7ed7706db62d289 --- /dev/null +++ b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/grpc/_common.py @@ -0,0 +1,168 @@ +# Copyright 2016 gRPC authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""Shared implementation.""" + +import logging +import time + +import grpc +from grpc._cython import cygrpc +import six + +_LOGGER = logging.getLogger(__name__) + +CYGRPC_CONNECTIVITY_STATE_TO_CHANNEL_CONNECTIVITY = { + cygrpc.ConnectivityState.idle: + grpc.ChannelConnectivity.IDLE, + cygrpc.ConnectivityState.connecting: + grpc.ChannelConnectivity.CONNECTING, + cygrpc.ConnectivityState.ready: + grpc.ChannelConnectivity.READY, + cygrpc.ConnectivityState.transient_failure: + grpc.ChannelConnectivity.TRANSIENT_FAILURE, + cygrpc.ConnectivityState.shutdown: + grpc.ChannelConnectivity.SHUTDOWN, +} + +CYGRPC_STATUS_CODE_TO_STATUS_CODE = { + cygrpc.StatusCode.ok: grpc.StatusCode.OK, + cygrpc.StatusCode.cancelled: grpc.StatusCode.CANCELLED, + cygrpc.StatusCode.unknown: grpc.StatusCode.UNKNOWN, + cygrpc.StatusCode.invalid_argument: grpc.StatusCode.INVALID_ARGUMENT, + cygrpc.StatusCode.deadline_exceeded: grpc.StatusCode.DEADLINE_EXCEEDED, + cygrpc.StatusCode.not_found: grpc.StatusCode.NOT_FOUND, + cygrpc.StatusCode.already_exists: grpc.StatusCode.ALREADY_EXISTS, + cygrpc.StatusCode.permission_denied: grpc.StatusCode.PERMISSION_DENIED, + cygrpc.StatusCode.unauthenticated: grpc.StatusCode.UNAUTHENTICATED, + cygrpc.StatusCode.resource_exhausted: grpc.StatusCode.RESOURCE_EXHAUSTED, + cygrpc.StatusCode.failed_precondition: grpc.StatusCode.FAILED_PRECONDITION, + cygrpc.StatusCode.aborted: grpc.StatusCode.ABORTED, + cygrpc.StatusCode.out_of_range: grpc.StatusCode.OUT_OF_RANGE, + cygrpc.StatusCode.unimplemented: grpc.StatusCode.UNIMPLEMENTED, + cygrpc.StatusCode.internal: grpc.StatusCode.INTERNAL, + cygrpc.StatusCode.unavailable: grpc.StatusCode.UNAVAILABLE, + cygrpc.StatusCode.data_loss: grpc.StatusCode.DATA_LOSS, +} +STATUS_CODE_TO_CYGRPC_STATUS_CODE = { + grpc_code: cygrpc_code for cygrpc_code, grpc_code in six.iteritems( + CYGRPC_STATUS_CODE_TO_STATUS_CODE) +} + +MAXIMUM_WAIT_TIMEOUT = 0.1 + +_ERROR_MESSAGE_PORT_BINDING_FAILED = 'Failed to bind to address %s; set ' \ + 'GRPC_VERBOSITY=debug environment variable to see detailed error message.' + + +def encode(s): + if isinstance(s, bytes): + return s + else: + return s.encode('utf8') + + +def decode(b): + if isinstance(b, bytes): + return b.decode('utf-8', 'replace') + return b + + +def _transform(message, transformer, exception_message): + if transformer is None: + return message + else: + try: + return transformer(message) + except Exception: # pylint: disable=broad-except + _LOGGER.exception(exception_message) + return None + + +def serialize(message, serializer): + return _transform(message, serializer, 'Exception serializing message!') + + +def deserialize(serialized_message, deserializer): + return _transform(serialized_message, deserializer, + 'Exception deserializing message!') + + +def fully_qualified_method(group, method): + return '/{}/{}'.format(group, method) + + +def _wait_once(wait_fn, timeout, spin_cb): + wait_fn(timeout=timeout) + if spin_cb is not None: + spin_cb() + + +def wait(wait_fn, wait_complete_fn, timeout=None, spin_cb=None): + """Blocks waiting for an event without blocking the thread indefinitely. + + See https://github.com/grpc/grpc/issues/19464 for full context. CPython's + `threading.Event.wait` and `threading.Condition.wait` methods, if invoked + without a timeout kwarg, may block the calling thread indefinitely. If the + call is made from the main thread, this means that signal handlers may not + run for an arbitrarily long period of time. + + This wrapper calls the supplied wait function with an arbitrary short + timeout to ensure that no signal handler has to wait longer than + MAXIMUM_WAIT_TIMEOUT before executing. + + Args: + wait_fn: A callable acceptable a single float-valued kwarg named + `timeout`. This function is expected to be one of `threading.Event.wait` + or `threading.Condition.wait`. + wait_complete_fn: A callable taking no arguments and returning a bool. + When this function returns true, it indicates that waiting should cease. + timeout: An optional float-valued number of seconds after which the wait + should cease. + spin_cb: An optional Callable taking no arguments and returning nothing. + This callback will be called on each iteration of the spin. This may be + used for, e.g. work related to forking. + + Returns: + True if a timeout was supplied and it was reached. False otherwise. + """ + if timeout is None: + while not wait_complete_fn(): + _wait_once(wait_fn, MAXIMUM_WAIT_TIMEOUT, spin_cb) + else: + end = time.time() + timeout + while not wait_complete_fn(): + remaining = min(end - time.time(), MAXIMUM_WAIT_TIMEOUT) + if remaining < 0: + return True + _wait_once(wait_fn, remaining, spin_cb) + return False + + +def validate_port_binding_result(address, port): + """Validates if the port binding succeed. + + If the port returned by Core is 0, the binding is failed. However, in that + case, the Core API doesn't return a detailed failing reason. The best we + can do is raising an exception to prevent further confusion. + + Args: + address: The address string to be bound. + port: An int returned by core + """ + if port == 0: + # The Core API doesn't return a failure message. The best we can do + # is raising an exception to prevent further confusion. + raise RuntimeError(_ERROR_MESSAGE_PORT_BINDING_FAILED % address) + else: + return port diff --git a/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/grpc/_compression.py b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/grpc/_compression.py new file mode 100644 index 0000000000000000000000000000000000000000..45339c3afe2a43fe3421bf6af549e43da1cdc901 --- /dev/null +++ b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/grpc/_compression.py @@ -0,0 +1,55 @@ +# Copyright 2019 The gRPC authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from grpc._cython import cygrpc + +NoCompression = cygrpc.CompressionAlgorithm.none +Deflate = cygrpc.CompressionAlgorithm.deflate +Gzip = cygrpc.CompressionAlgorithm.gzip + +_METADATA_STRING_MAPPING = { + NoCompression: 'identity', + Deflate: 'deflate', + Gzip: 'gzip', +} + + +def _compression_algorithm_to_metadata_value(compression): + return _METADATA_STRING_MAPPING[compression] + + +def compression_algorithm_to_metadata(compression): + return (cygrpc.GRPC_COMPRESSION_REQUEST_ALGORITHM_MD_KEY, + _compression_algorithm_to_metadata_value(compression)) + + +def create_channel_option(compression): + return ((cygrpc.GRPC_COMPRESSION_CHANNEL_DEFAULT_ALGORITHM, + int(compression)),) if compression else () + + +def augment_metadata(metadata, compression): + if not metadata and not compression: + return None + base_metadata = tuple(metadata) if metadata else () + compression_metadata = ( + compression_algorithm_to_metadata(compression),) if compression else () + return base_metadata + compression_metadata + + +__all__ = ( + "NoCompression", + "Deflate", + "Gzip", +) diff --git a/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/grpc/_grpcio_metadata.py b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/grpc/_grpcio_metadata.py new file mode 100644 index 0000000000000000000000000000000000000000..4d9e3e2c139eec8d104f7246a76de63c7f520111 --- /dev/null +++ b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/grpc/_grpcio_metadata.py @@ -0,0 +1 @@ +__version__ = """1.47.0""" \ No newline at end of file diff --git a/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/grpc/_interceptor.py b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/grpc/_interceptor.py new file mode 100644 index 0000000000000000000000000000000000000000..ee63cb31452aed46103e4bc8ca57e3b5e51031f2 --- /dev/null +++ b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/grpc/_interceptor.py @@ -0,0 +1,562 @@ +# Copyright 2017 gRPC authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""Implementation of gRPC Python interceptors.""" + +import collections +import sys + +import grpc + + +class _ServicePipeline(object): + + def __init__(self, interceptors): + self.interceptors = tuple(interceptors) + + def _continuation(self, thunk, index): + return lambda context: self._intercept_at(thunk, index, context) + + def _intercept_at(self, thunk, index, context): + if index < len(self.interceptors): + interceptor = self.interceptors[index] + thunk = self._continuation(thunk, index + 1) + return interceptor.intercept_service(thunk, context) + else: + return thunk(context) + + def execute(self, thunk, context): + return self._intercept_at(thunk, 0, context) + + +def service_pipeline(interceptors): + return _ServicePipeline(interceptors) if interceptors else None + + +class _ClientCallDetails( + collections.namedtuple('_ClientCallDetails', + ('method', 'timeout', 'metadata', 'credentials', + 'wait_for_ready', 'compression')), + grpc.ClientCallDetails): + pass + + +def _unwrap_client_call_details(call_details, default_details): + try: + method = call_details.method + except AttributeError: + method = default_details.method + + try: + timeout = call_details.timeout + except AttributeError: + timeout = default_details.timeout + + try: + metadata = call_details.metadata + except AttributeError: + metadata = default_details.metadata + + try: + credentials = call_details.credentials + except AttributeError: + credentials = default_details.credentials + + try: + wait_for_ready = call_details.wait_for_ready + except AttributeError: + wait_for_ready = default_details.wait_for_ready + + try: + compression = call_details.compression + except AttributeError: + compression = default_details.compression + + return method, timeout, metadata, credentials, wait_for_ready, compression + + +class _FailureOutcome(grpc.RpcError, grpc.Future, grpc.Call): # pylint: disable=too-many-ancestors + + def __init__(self, exception, traceback): + super(_FailureOutcome, self).__init__() + self._exception = exception + self._traceback = traceback + + def initial_metadata(self): + return None + + def trailing_metadata(self): + return None + + def code(self): + return grpc.StatusCode.INTERNAL + + def details(self): + return 'Exception raised while intercepting the RPC' + + def cancel(self): + return False + + def cancelled(self): + return False + + def is_active(self): + return False + + def time_remaining(self): + return None + + def running(self): + return False + + def done(self): + return True + + def result(self, ignored_timeout=None): + raise self._exception + + def exception(self, ignored_timeout=None): + return self._exception + + def traceback(self, ignored_timeout=None): + return self._traceback + + def add_callback(self, unused_callback): + return False + + def add_done_callback(self, fn): + fn(self) + + def __iter__(self): + return self + + def __next__(self): + raise self._exception + + def next(self): + return self.__next__() + + +class _UnaryOutcome(grpc.Call, grpc.Future): + + def __init__(self, response, call): + self._response = response + self._call = call + + def initial_metadata(self): + return self._call.initial_metadata() + + def trailing_metadata(self): + return self._call.trailing_metadata() + + def code(self): + return self._call.code() + + def details(self): + return self._call.details() + + def is_active(self): + return self._call.is_active() + + def time_remaining(self): + return self._call.time_remaining() + + def cancel(self): + return self._call.cancel() + + def add_callback(self, callback): + return self._call.add_callback(callback) + + def cancelled(self): + return False + + def running(self): + return False + + def done(self): + return True + + def result(self, ignored_timeout=None): + return self._response + + def exception(self, ignored_timeout=None): + return None + + def traceback(self, ignored_timeout=None): + return None + + def add_done_callback(self, fn): + fn(self) + + +class _UnaryUnaryMultiCallable(grpc.UnaryUnaryMultiCallable): + + def __init__(self, thunk, method, interceptor): + self._thunk = thunk + self._method = method + self._interceptor = interceptor + + def __call__(self, + request, + timeout=None, + metadata=None, + credentials=None, + wait_for_ready=None, + compression=None): + response, ignored_call = self._with_call(request, + timeout=timeout, + metadata=metadata, + credentials=credentials, + wait_for_ready=wait_for_ready, + compression=compression) + return response + + def _with_call(self, + request, + timeout=None, + metadata=None, + credentials=None, + wait_for_ready=None, + compression=None): + client_call_details = _ClientCallDetails(self._method, timeout, + metadata, credentials, + wait_for_ready, compression) + + def continuation(new_details, request): + (new_method, new_timeout, new_metadata, new_credentials, + new_wait_for_ready, + new_compression) = (_unwrap_client_call_details( + new_details, client_call_details)) + try: + response, call = self._thunk(new_method).with_call( + request, + timeout=new_timeout, + metadata=new_metadata, + credentials=new_credentials, + wait_for_ready=new_wait_for_ready, + compression=new_compression) + return _UnaryOutcome(response, call) + except grpc.RpcError as rpc_error: + return rpc_error + except Exception as exception: # pylint:disable=broad-except + return _FailureOutcome(exception, sys.exc_info()[2]) + + call = self._interceptor.intercept_unary_unary(continuation, + client_call_details, + request) + return call.result(), call + + def with_call(self, + request, + timeout=None, + metadata=None, + credentials=None, + wait_for_ready=None, + compression=None): + return self._with_call(request, + timeout=timeout, + metadata=metadata, + credentials=credentials, + wait_for_ready=wait_for_ready, + compression=compression) + + def future(self, + request, + timeout=None, + metadata=None, + credentials=None, + wait_for_ready=None, + compression=None): + client_call_details = _ClientCallDetails(self._method, timeout, + metadata, credentials, + wait_for_ready, compression) + + def continuation(new_details, request): + (new_method, new_timeout, new_metadata, new_credentials, + new_wait_for_ready, + new_compression) = (_unwrap_client_call_details( + new_details, client_call_details)) + return self._thunk(new_method).future( + request, + timeout=new_timeout, + metadata=new_metadata, + credentials=new_credentials, + wait_for_ready=new_wait_for_ready, + compression=new_compression) + + try: + return self._interceptor.intercept_unary_unary( + continuation, client_call_details, request) + except Exception as exception: # pylint:disable=broad-except + return _FailureOutcome(exception, sys.exc_info()[2]) + + +class _UnaryStreamMultiCallable(grpc.UnaryStreamMultiCallable): + + def __init__(self, thunk, method, interceptor): + self._thunk = thunk + self._method = method + self._interceptor = interceptor + + def __call__(self, + request, + timeout=None, + metadata=None, + credentials=None, + wait_for_ready=None, + compression=None): + client_call_details = _ClientCallDetails(self._method, timeout, + metadata, credentials, + wait_for_ready, compression) + + def continuation(new_details, request): + (new_method, new_timeout, new_metadata, new_credentials, + new_wait_for_ready, + new_compression) = (_unwrap_client_call_details( + new_details, client_call_details)) + return self._thunk(new_method)(request, + timeout=new_timeout, + metadata=new_metadata, + credentials=new_credentials, + wait_for_ready=new_wait_for_ready, + compression=new_compression) + + try: + return self._interceptor.intercept_unary_stream( + continuation, client_call_details, request) + except Exception as exception: # pylint:disable=broad-except + return _FailureOutcome(exception, sys.exc_info()[2]) + + +class _StreamUnaryMultiCallable(grpc.StreamUnaryMultiCallable): + + def __init__(self, thunk, method, interceptor): + self._thunk = thunk + self._method = method + self._interceptor = interceptor + + def __call__(self, + request_iterator, + timeout=None, + metadata=None, + credentials=None, + wait_for_ready=None, + compression=None): + response, ignored_call = self._with_call(request_iterator, + timeout=timeout, + metadata=metadata, + credentials=credentials, + wait_for_ready=wait_for_ready, + compression=compression) + return response + + def _with_call(self, + request_iterator, + timeout=None, + metadata=None, + credentials=None, + wait_for_ready=None, + compression=None): + client_call_details = _ClientCallDetails(self._method, timeout, + metadata, credentials, + wait_for_ready, compression) + + def continuation(new_details, request_iterator): + (new_method, new_timeout, new_metadata, new_credentials, + new_wait_for_ready, + new_compression) = (_unwrap_client_call_details( + new_details, client_call_details)) + try: + response, call = self._thunk(new_method).with_call( + request_iterator, + timeout=new_timeout, + metadata=new_metadata, + credentials=new_credentials, + wait_for_ready=new_wait_for_ready, + compression=new_compression) + return _UnaryOutcome(response, call) + except grpc.RpcError as rpc_error: + return rpc_error + except Exception as exception: # pylint:disable=broad-except + return _FailureOutcome(exception, sys.exc_info()[2]) + + call = self._interceptor.intercept_stream_unary(continuation, + client_call_details, + request_iterator) + return call.result(), call + + def with_call(self, + request_iterator, + timeout=None, + metadata=None, + credentials=None, + wait_for_ready=None, + compression=None): + return self._with_call(request_iterator, + timeout=timeout, + metadata=metadata, + credentials=credentials, + wait_for_ready=wait_for_ready, + compression=compression) + + def future(self, + request_iterator, + timeout=None, + metadata=None, + credentials=None, + wait_for_ready=None, + compression=None): + client_call_details = _ClientCallDetails(self._method, timeout, + metadata, credentials, + wait_for_ready, compression) + + def continuation(new_details, request_iterator): + (new_method, new_timeout, new_metadata, new_credentials, + new_wait_for_ready, + new_compression) = (_unwrap_client_call_details( + new_details, client_call_details)) + return self._thunk(new_method).future( + request_iterator, + timeout=new_timeout, + metadata=new_metadata, + credentials=new_credentials, + wait_for_ready=new_wait_for_ready, + compression=new_compression) + + try: + return self._interceptor.intercept_stream_unary( + continuation, client_call_details, request_iterator) + except Exception as exception: # pylint:disable=broad-except + return _FailureOutcome(exception, sys.exc_info()[2]) + + +class _StreamStreamMultiCallable(grpc.StreamStreamMultiCallable): + + def __init__(self, thunk, method, interceptor): + self._thunk = thunk + self._method = method + self._interceptor = interceptor + + def __call__(self, + request_iterator, + timeout=None, + metadata=None, + credentials=None, + wait_for_ready=None, + compression=None): + client_call_details = _ClientCallDetails(self._method, timeout, + metadata, credentials, + wait_for_ready, compression) + + def continuation(new_details, request_iterator): + (new_method, new_timeout, new_metadata, new_credentials, + new_wait_for_ready, + new_compression) = (_unwrap_client_call_details( + new_details, client_call_details)) + return self._thunk(new_method)(request_iterator, + timeout=new_timeout, + metadata=new_metadata, + credentials=new_credentials, + wait_for_ready=new_wait_for_ready, + compression=new_compression) + + try: + return self._interceptor.intercept_stream_stream( + continuation, client_call_details, request_iterator) + except Exception as exception: # pylint:disable=broad-except + return _FailureOutcome(exception, sys.exc_info()[2]) + + +class _Channel(grpc.Channel): + + def __init__(self, channel, interceptor): + self._channel = channel + self._interceptor = interceptor + + def subscribe(self, callback, try_to_connect=False): + self._channel.subscribe(callback, try_to_connect=try_to_connect) + + def unsubscribe(self, callback): + self._channel.unsubscribe(callback) + + def unary_unary(self, + method, + request_serializer=None, + response_deserializer=None): + thunk = lambda m: self._channel.unary_unary(m, request_serializer, + response_deserializer) + if isinstance(self._interceptor, grpc.UnaryUnaryClientInterceptor): + return _UnaryUnaryMultiCallable(thunk, method, self._interceptor) + else: + return thunk(method) + + def unary_stream(self, + method, + request_serializer=None, + response_deserializer=None): + thunk = lambda m: self._channel.unary_stream(m, request_serializer, + response_deserializer) + if isinstance(self._interceptor, grpc.UnaryStreamClientInterceptor): + return _UnaryStreamMultiCallable(thunk, method, self._interceptor) + else: + return thunk(method) + + def stream_unary(self, + method, + request_serializer=None, + response_deserializer=None): + thunk = lambda m: self._channel.stream_unary(m, request_serializer, + response_deserializer) + if isinstance(self._interceptor, grpc.StreamUnaryClientInterceptor): + return _StreamUnaryMultiCallable(thunk, method, self._interceptor) + else: + return thunk(method) + + def stream_stream(self, + method, + request_serializer=None, + response_deserializer=None): + thunk = lambda m: self._channel.stream_stream(m, request_serializer, + response_deserializer) + if isinstance(self._interceptor, grpc.StreamStreamClientInterceptor): + return _StreamStreamMultiCallable(thunk, method, self._interceptor) + else: + return thunk(method) + + def _close(self): + self._channel.close() + + def __enter__(self): + return self + + def __exit__(self, exc_type, exc_val, exc_tb): + self._close() + return False + + def close(self): + self._channel.close() + + +def intercept_channel(channel, *interceptors): + for interceptor in reversed(list(interceptors)): + if not isinstance(interceptor, grpc.UnaryUnaryClientInterceptor) and \ + not isinstance(interceptor, grpc.UnaryStreamClientInterceptor) and \ + not isinstance(interceptor, grpc.StreamUnaryClientInterceptor) and \ + not isinstance(interceptor, grpc.StreamStreamClientInterceptor): + raise TypeError('interceptor must be ' + 'grpc.UnaryUnaryClientInterceptor or ' + 'grpc.UnaryStreamClientInterceptor or ' + 'grpc.StreamUnaryClientInterceptor or ' + 'grpc.StreamStreamClientInterceptor or ') + channel = _Channel(channel, interceptor) + return channel diff --git a/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/grpc/_plugin_wrapping.py b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/grpc/_plugin_wrapping.py new file mode 100644 index 0000000000000000000000000000000000000000..ad74b256a371e952329fe87734d4d79598549f2e --- /dev/null +++ b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/grpc/_plugin_wrapping.py @@ -0,0 +1,113 @@ +# Copyright 2015 gRPC authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import collections +import logging +import threading + +import grpc +from grpc import _common +from grpc._cython import cygrpc + +_LOGGER = logging.getLogger(__name__) + + +class _AuthMetadataContext( + collections.namedtuple('AuthMetadataContext', ( + 'service_url', + 'method_name', + )), grpc.AuthMetadataContext): + pass + + +class _CallbackState(object): + + def __init__(self): + self.lock = threading.Lock() + self.called = False + self.exception = None + + +class _AuthMetadataPluginCallback(grpc.AuthMetadataPluginCallback): + + def __init__(self, state, callback): + self._state = state + self._callback = callback + + def __call__(self, metadata, error): + with self._state.lock: + if self._state.exception is None: + if self._state.called: + raise RuntimeError( + 'AuthMetadataPluginCallback invoked more than once!') + else: + self._state.called = True + else: + raise RuntimeError( + 'AuthMetadataPluginCallback raised exception "{}"!'.format( + self._state.exception)) + if error is None: + self._callback(metadata, cygrpc.StatusCode.ok, None) + else: + self._callback(None, cygrpc.StatusCode.internal, + _common.encode(str(error))) + + +class _Plugin(object): + + def __init__(self, metadata_plugin): + self._metadata_plugin = metadata_plugin + self._stored_ctx = None + + try: + import contextvars # pylint: disable=wrong-import-position + + # The plugin may be invoked on a thread created by Core, which will not + # have the context propagated. This context is stored and installed in + # the thread invoking the plugin. + self._stored_ctx = contextvars.copy_context() + except ImportError: + # Support versions predating contextvars. + pass + + def __call__(self, service_url, method_name, callback): + context = _AuthMetadataContext(_common.decode(service_url), + _common.decode(method_name)) + callback_state = _CallbackState() + try: + self._metadata_plugin( + context, _AuthMetadataPluginCallback(callback_state, callback)) + except Exception as exception: # pylint: disable=broad-except + _LOGGER.exception( + 'AuthMetadataPluginCallback "%s" raised exception!', + self._metadata_plugin) + with callback_state.lock: + callback_state.exception = exception + if callback_state.called: + return + callback(None, cygrpc.StatusCode.internal, + _common.encode(str(exception))) + + +def metadata_plugin_call_credentials(metadata_plugin, name): + if name is None: + try: + effective_name = metadata_plugin.__name__ + except AttributeError: + effective_name = metadata_plugin.__class__.__name__ + else: + effective_name = name + return grpc.CallCredentials( + cygrpc.MetadataPluginCallCredentials(_Plugin(metadata_plugin), + _common.encode(effective_name))) diff --git a/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/grpc/_runtime_protos.py b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/grpc/_runtime_protos.py new file mode 100644 index 0000000000000000000000000000000000000000..2a3e1d459a2230cff483c5b0d2427dd361455690 --- /dev/null +++ b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/grpc/_runtime_protos.py @@ -0,0 +1,155 @@ +# Copyright 2020 The gRPC authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import sys + +_REQUIRED_SYMBOLS = ("_protos", "_services", "_protos_and_services") +_MINIMUM_VERSION = (3, 5, 0) + +_UNINSTALLED_TEMPLATE = "Install the grpcio-tools package (1.32.0+) to use the {} function." +_VERSION_ERROR_TEMPLATE = "The {} function is only on available on Python 3.X interpreters." + + +def _has_runtime_proto_symbols(mod): + return all(hasattr(mod, sym) for sym in _REQUIRED_SYMBOLS) + + +def _is_grpc_tools_importable(): + try: + import grpc_tools # pylint: disable=unused-import + return True + except ImportError as e: + # NOTE: It's possible that we're encountering a transitive ImportError, so + # we check for that and re-raise if so. + if "grpc_tools" not in e.args[0]: + raise + return False + + +def _call_with_lazy_import(fn_name, protobuf_path): + """Calls one of the three functions, lazily importing grpc_tools. + + Args: + fn_name: The name of the function to import from grpc_tools.protoc. + protobuf_path: The path to import. + + Returns: + The appropriate module object. + """ + if sys.version_info < _MINIMUM_VERSION: + raise NotImplementedError(_VERSION_ERROR_TEMPLATE.format(fn_name)) + else: + if not _is_grpc_tools_importable(): + raise NotImplementedError(_UNINSTALLED_TEMPLATE.format(fn_name)) + import grpc_tools.protoc + if _has_runtime_proto_symbols(grpc_tools.protoc): + fn = getattr(grpc_tools.protoc, '_' + fn_name) + return fn(protobuf_path) + else: + raise NotImplementedError(_UNINSTALLED_TEMPLATE.format(fn_name)) + + +def protos(protobuf_path): # pylint: disable=unused-argument + """Returns a module generated by the indicated .proto file. + + THIS IS AN EXPERIMENTAL API. + + Use this function to retrieve classes corresponding to message + definitions in the .proto file. + + To inspect the contents of the returned module, use the dir function. + For example: + + ``` + protos = grpc.protos("foo.proto") + print(dir(protos)) + ``` + + The returned module object corresponds to the _pb2.py file generated + by protoc. The path is expected to be relative to an entry on sys.path + and all transitive dependencies of the file should also be resolveable + from an entry on sys.path. + + To completely disable the machinery behind this function, set the + GRPC_PYTHON_DISABLE_DYNAMIC_STUBS environment variable to "true". + + Args: + protobuf_path: The path to the .proto file on the filesystem. This path + must be resolveable from an entry on sys.path and so must all of its + transitive dependencies. + + Returns: + A module object corresponding to the message code for the indicated + .proto file. Equivalent to a generated _pb2.py file. + """ + return _call_with_lazy_import("protos", protobuf_path) + + +def services(protobuf_path): # pylint: disable=unused-argument + """Returns a module generated by the indicated .proto file. + + THIS IS AN EXPERIMENTAL API. + + Use this function to retrieve classes and functions corresponding to + service definitions in the .proto file, including both stub and servicer + definitions. + + To inspect the contents of the returned module, use the dir function. + For example: + + ``` + services = grpc.services("foo.proto") + print(dir(services)) + ``` + + The returned module object corresponds to the _pb2_grpc.py file generated + by protoc. The path is expected to be relative to an entry on sys.path + and all transitive dependencies of the file should also be resolveable + from an entry on sys.path. + + To completely disable the machinery behind this function, set the + GRPC_PYTHON_DISABLE_DYNAMIC_STUBS environment variable to "true". + + Args: + protobuf_path: The path to the .proto file on the filesystem. This path + must be resolveable from an entry on sys.path and so must all of its + transitive dependencies. + + Returns: + A module object corresponding to the stub/service code for the indicated + .proto file. Equivalent to a generated _pb2_grpc.py file. + """ + return _call_with_lazy_import("services", protobuf_path) + + +def protos_and_services(protobuf_path): # pylint: disable=unused-argument + """Returns a 2-tuple of modules corresponding to protos and services. + + THIS IS AN EXPERIMENTAL API. + + The return value of this function is equivalent to a call to protos and a + call to services. + + To completely disable the machinery behind this function, set the + GRPC_PYTHON_DISABLE_DYNAMIC_STUBS environment variable to "true". + + Args: + protobuf_path: The path to the .proto file on the filesystem. This path + must be resolveable from an entry on sys.path and so must all of its + transitive dependencies. + + Returns: + A 2-tuple of module objects corresponding to (protos(path), services(path)). + """ + return _call_with_lazy_import("protos_and_services", protobuf_path) diff --git a/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/grpc/_server.py b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/grpc/_server.py new file mode 100644 index 0000000000000000000000000000000000000000..58ab14feb3dc83dfe1504cea8389fbc51395d2e2 --- /dev/null +++ b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/grpc/_server.py @@ -0,0 +1,1003 @@ +# Copyright 2016 gRPC authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""Service-side implementation of gRPC Python.""" + +import collections +from concurrent import futures +import enum +import logging +import threading +import time + +import grpc +from grpc import _common +from grpc import _compression +from grpc import _interceptor +from grpc._cython import cygrpc +import six + +_LOGGER = logging.getLogger(__name__) + +_SHUTDOWN_TAG = 'shutdown' +_REQUEST_CALL_TAG = 'request_call' + +_RECEIVE_CLOSE_ON_SERVER_TOKEN = 'receive_close_on_server' +_SEND_INITIAL_METADATA_TOKEN = 'send_initial_metadata' +_RECEIVE_MESSAGE_TOKEN = 'receive_message' +_SEND_MESSAGE_TOKEN = 'send_message' +_SEND_INITIAL_METADATA_AND_SEND_MESSAGE_TOKEN = ( + 'send_initial_metadata * send_message') +_SEND_STATUS_FROM_SERVER_TOKEN = 'send_status_from_server' +_SEND_INITIAL_METADATA_AND_SEND_STATUS_FROM_SERVER_TOKEN = ( + 'send_initial_metadata * send_status_from_server') + +_OPEN = 'open' +_CLOSED = 'closed' +_CANCELLED = 'cancelled' + +_EMPTY_FLAGS = 0 + +_DEALLOCATED_SERVER_CHECK_PERIOD_S = 1.0 +_INF_TIMEOUT = 1e9 + + +def _serialized_request(request_event): + return request_event.batch_operations[0].message() + + +def _application_code(code): + cygrpc_code = _common.STATUS_CODE_TO_CYGRPC_STATUS_CODE.get(code) + return cygrpc.StatusCode.unknown if cygrpc_code is None else cygrpc_code + + +def _completion_code(state): + if state.code is None: + return cygrpc.StatusCode.ok + else: + return _application_code(state.code) + + +def _abortion_code(state, code): + if state.code is None: + return code + else: + return _application_code(state.code) + + +def _details(state): + return b'' if state.details is None else state.details + + +class _HandlerCallDetails( + collections.namedtuple('_HandlerCallDetails', ( + 'method', + 'invocation_metadata', + )), grpc.HandlerCallDetails): + pass + + +class _RPCState(object): + + def __init__(self): + self.condition = threading.Condition() + self.due = set() + self.request = None + self.client = _OPEN + self.initial_metadata_allowed = True + self.compression_algorithm = None + self.disable_next_compression = False + self.trailing_metadata = None + self.code = None + self.details = None + self.statused = False + self.rpc_errors = [] + self.callbacks = [] + self.aborted = False + + +def _raise_rpc_error(state): + rpc_error = grpc.RpcError() + state.rpc_errors.append(rpc_error) + raise rpc_error + + +def _possibly_finish_call(state, token): + state.due.remove(token) + if not _is_rpc_state_active(state) and not state.due: + callbacks = state.callbacks + state.callbacks = None + return state, callbacks + else: + return None, () + + +def _send_status_from_server(state, token): + + def send_status_from_server(unused_send_status_from_server_event): + with state.condition: + return _possibly_finish_call(state, token) + + return send_status_from_server + + +def _get_initial_metadata(state, metadata): + with state.condition: + if state.compression_algorithm: + compression_metadata = ( + _compression.compression_algorithm_to_metadata( + state.compression_algorithm),) + if metadata is None: + return compression_metadata + else: + return compression_metadata + tuple(metadata) + else: + return metadata + + +def _get_initial_metadata_operation(state, metadata): + operation = cygrpc.SendInitialMetadataOperation( + _get_initial_metadata(state, metadata), _EMPTY_FLAGS) + return operation + + +def _abort(state, call, code, details): + if state.client is not _CANCELLED: + effective_code = _abortion_code(state, code) + effective_details = details if state.details is None else state.details + if state.initial_metadata_allowed: + operations = ( + _get_initial_metadata_operation(state, None), + cygrpc.SendStatusFromServerOperation(state.trailing_metadata, + effective_code, + effective_details, + _EMPTY_FLAGS), + ) + token = _SEND_INITIAL_METADATA_AND_SEND_STATUS_FROM_SERVER_TOKEN + else: + operations = (cygrpc.SendStatusFromServerOperation( + state.trailing_metadata, effective_code, effective_details, + _EMPTY_FLAGS),) + token = _SEND_STATUS_FROM_SERVER_TOKEN + call.start_server_batch(operations, + _send_status_from_server(state, token)) + state.statused = True + state.due.add(token) + + +def _receive_close_on_server(state): + + def receive_close_on_server(receive_close_on_server_event): + with state.condition: + if receive_close_on_server_event.batch_operations[0].cancelled(): + state.client = _CANCELLED + elif state.client is _OPEN: + state.client = _CLOSED + state.condition.notify_all() + return _possibly_finish_call(state, _RECEIVE_CLOSE_ON_SERVER_TOKEN) + + return receive_close_on_server + + +def _receive_message(state, call, request_deserializer): + + def receive_message(receive_message_event): + serialized_request = _serialized_request(receive_message_event) + if serialized_request is None: + with state.condition: + if state.client is _OPEN: + state.client = _CLOSED + state.condition.notify_all() + return _possibly_finish_call(state, _RECEIVE_MESSAGE_TOKEN) + else: + request = _common.deserialize(serialized_request, + request_deserializer) + with state.condition: + if request is None: + _abort(state, call, cygrpc.StatusCode.internal, + b'Exception deserializing request!') + else: + state.request = request + state.condition.notify_all() + return _possibly_finish_call(state, _RECEIVE_MESSAGE_TOKEN) + + return receive_message + + +def _send_initial_metadata(state): + + def send_initial_metadata(unused_send_initial_metadata_event): + with state.condition: + return _possibly_finish_call(state, _SEND_INITIAL_METADATA_TOKEN) + + return send_initial_metadata + + +def _send_message(state, token): + + def send_message(unused_send_message_event): + with state.condition: + state.condition.notify_all() + return _possibly_finish_call(state, token) + + return send_message + + +class _Context(grpc.ServicerContext): + + def __init__(self, rpc_event, state, request_deserializer): + self._rpc_event = rpc_event + self._state = state + self._request_deserializer = request_deserializer + + def is_active(self): + with self._state.condition: + return _is_rpc_state_active(self._state) + + def time_remaining(self): + return max(self._rpc_event.call_details.deadline - time.time(), 0) + + def cancel(self): + self._rpc_event.call.cancel() + + def add_callback(self, callback): + with self._state.condition: + if self._state.callbacks is None: + return False + else: + self._state.callbacks.append(callback) + return True + + def disable_next_message_compression(self): + with self._state.condition: + self._state.disable_next_compression = True + + def invocation_metadata(self): + return self._rpc_event.invocation_metadata + + def peer(self): + return _common.decode(self._rpc_event.call.peer()) + + def peer_identities(self): + return cygrpc.peer_identities(self._rpc_event.call) + + def peer_identity_key(self): + id_key = cygrpc.peer_identity_key(self._rpc_event.call) + return id_key if id_key is None else _common.decode(id_key) + + def auth_context(self): + return { + _common.decode(key): value for key, value in six.iteritems( + cygrpc.auth_context(self._rpc_event.call)) + } + + def set_compression(self, compression): + with self._state.condition: + self._state.compression_algorithm = compression + + def send_initial_metadata(self, initial_metadata): + with self._state.condition: + if self._state.client is _CANCELLED: + _raise_rpc_error(self._state) + else: + if self._state.initial_metadata_allowed: + operation = _get_initial_metadata_operation( + self._state, initial_metadata) + self._rpc_event.call.start_server_batch( + (operation,), _send_initial_metadata(self._state)) + self._state.initial_metadata_allowed = False + self._state.due.add(_SEND_INITIAL_METADATA_TOKEN) + else: + raise ValueError('Initial metadata no longer allowed!') + + def set_trailing_metadata(self, trailing_metadata): + with self._state.condition: + self._state.trailing_metadata = trailing_metadata + + def trailing_metadata(self): + return self._state.trailing_metadata + + def abort(self, code, details): + # treat OK like other invalid arguments: fail the RPC + if code == grpc.StatusCode.OK: + _LOGGER.error( + 'abort() called with StatusCode.OK; returning UNKNOWN') + code = grpc.StatusCode.UNKNOWN + details = '' + with self._state.condition: + self._state.code = code + self._state.details = _common.encode(details) + self._state.aborted = True + raise Exception() + + def abort_with_status(self, status): + self._state.trailing_metadata = status.trailing_metadata + self.abort(status.code, status.details) + + def set_code(self, code): + with self._state.condition: + self._state.code = code + + def code(self): + return self._state.code + + def set_details(self, details): + with self._state.condition: + self._state.details = _common.encode(details) + + def details(self): + return self._state.details + + def _finalize_state(self): + pass + + +class _RequestIterator(object): + + def __init__(self, state, call, request_deserializer): + self._state = state + self._call = call + self._request_deserializer = request_deserializer + + def _raise_or_start_receive_message(self): + if self._state.client is _CANCELLED: + _raise_rpc_error(self._state) + elif not _is_rpc_state_active(self._state): + raise StopIteration() + else: + self._call.start_server_batch( + (cygrpc.ReceiveMessageOperation(_EMPTY_FLAGS),), + _receive_message(self._state, self._call, + self._request_deserializer)) + self._state.due.add(_RECEIVE_MESSAGE_TOKEN) + + def _look_for_request(self): + if self._state.client is _CANCELLED: + _raise_rpc_error(self._state) + elif (self._state.request is None and + _RECEIVE_MESSAGE_TOKEN not in self._state.due): + raise StopIteration() + else: + request = self._state.request + self._state.request = None + return request + + raise AssertionError() # should never run + + def _next(self): + with self._state.condition: + self._raise_or_start_receive_message() + while True: + self._state.condition.wait() + request = self._look_for_request() + if request is not None: + return request + + def __iter__(self): + return self + + def __next__(self): + return self._next() + + def next(self): + return self._next() + + +def _unary_request(rpc_event, state, request_deserializer): + + def unary_request(): + with state.condition: + if not _is_rpc_state_active(state): + return None + else: + rpc_event.call.start_server_batch( + (cygrpc.ReceiveMessageOperation(_EMPTY_FLAGS),), + _receive_message(state, rpc_event.call, + request_deserializer)) + state.due.add(_RECEIVE_MESSAGE_TOKEN) + while True: + state.condition.wait() + if state.request is None: + if state.client is _CLOSED: + details = '"{}" requires exactly one request message.'.format( + rpc_event.call_details.method) + _abort(state, rpc_event.call, + cygrpc.StatusCode.unimplemented, + _common.encode(details)) + return None + elif state.client is _CANCELLED: + return None + else: + request = state.request + state.request = None + return request + + return unary_request + + +def _call_behavior(rpc_event, + state, + behavior, + argument, + request_deserializer, + send_response_callback=None): + from grpc import _create_servicer_context + with _create_servicer_context(rpc_event, state, + request_deserializer) as context: + try: + response_or_iterator = None + if send_response_callback is not None: + response_or_iterator = behavior(argument, context, + send_response_callback) + else: + response_or_iterator = behavior(argument, context) + return response_or_iterator, True + except Exception as exception: # pylint: disable=broad-except + with state.condition: + if state.aborted: + _abort(state, rpc_event.call, cygrpc.StatusCode.unknown, + b'RPC Aborted') + elif exception not in state.rpc_errors: + details = 'Exception calling application: {}'.format( + exception) + _LOGGER.exception(details) + _abort(state, rpc_event.call, cygrpc.StatusCode.unknown, + _common.encode(details)) + return None, False + + +def _take_response_from_response_iterator(rpc_event, state, response_iterator): + try: + return next(response_iterator), True + except StopIteration: + return None, True + except Exception as exception: # pylint: disable=broad-except + with state.condition: + if state.aborted: + _abort(state, rpc_event.call, cygrpc.StatusCode.unknown, + b'RPC Aborted') + elif exception not in state.rpc_errors: + details = 'Exception iterating responses: {}'.format(exception) + _LOGGER.exception(details) + _abort(state, rpc_event.call, cygrpc.StatusCode.unknown, + _common.encode(details)) + return None, False + + +def _serialize_response(rpc_event, state, response, response_serializer): + serialized_response = _common.serialize(response, response_serializer) + if serialized_response is None: + with state.condition: + _abort(state, rpc_event.call, cygrpc.StatusCode.internal, + b'Failed to serialize response!') + return None + else: + return serialized_response + + +def _get_send_message_op_flags_from_state(state): + if state.disable_next_compression: + return cygrpc.WriteFlag.no_compress + else: + return _EMPTY_FLAGS + + +def _reset_per_message_state(state): + with state.condition: + state.disable_next_compression = False + + +def _send_response(rpc_event, state, serialized_response): + with state.condition: + if not _is_rpc_state_active(state): + return False + else: + if state.initial_metadata_allowed: + operations = ( + _get_initial_metadata_operation(state, None), + cygrpc.SendMessageOperation( + serialized_response, + _get_send_message_op_flags_from_state(state)), + ) + state.initial_metadata_allowed = False + token = _SEND_INITIAL_METADATA_AND_SEND_MESSAGE_TOKEN + else: + operations = (cygrpc.SendMessageOperation( + serialized_response, + _get_send_message_op_flags_from_state(state)),) + token = _SEND_MESSAGE_TOKEN + rpc_event.call.start_server_batch(operations, + _send_message(state, token)) + state.due.add(token) + _reset_per_message_state(state) + while True: + state.condition.wait() + if token not in state.due: + return _is_rpc_state_active(state) + + +def _status(rpc_event, state, serialized_response): + with state.condition: + if state.client is not _CANCELLED: + code = _completion_code(state) + details = _details(state) + operations = [ + cygrpc.SendStatusFromServerOperation(state.trailing_metadata, + code, details, + _EMPTY_FLAGS), + ] + if state.initial_metadata_allowed: + operations.append(_get_initial_metadata_operation(state, None)) + if serialized_response is not None: + operations.append( + cygrpc.SendMessageOperation( + serialized_response, + _get_send_message_op_flags_from_state(state))) + rpc_event.call.start_server_batch( + operations, + _send_status_from_server(state, _SEND_STATUS_FROM_SERVER_TOKEN)) + state.statused = True + _reset_per_message_state(state) + state.due.add(_SEND_STATUS_FROM_SERVER_TOKEN) + + +def _unary_response_in_pool(rpc_event, state, behavior, argument_thunk, + request_deserializer, response_serializer): + cygrpc.install_context_from_request_call_event(rpc_event) + try: + argument = argument_thunk() + if argument is not None: + response, proceed = _call_behavior(rpc_event, state, behavior, + argument, request_deserializer) + if proceed: + serialized_response = _serialize_response( + rpc_event, state, response, response_serializer) + if serialized_response is not None: + _status(rpc_event, state, serialized_response) + finally: + cygrpc.uninstall_context() + + +def _stream_response_in_pool(rpc_event, state, behavior, argument_thunk, + request_deserializer, response_serializer): + cygrpc.install_context_from_request_call_event(rpc_event) + + def send_response(response): + if response is None: + _status(rpc_event, state, None) + else: + serialized_response = _serialize_response(rpc_event, state, + response, + response_serializer) + if serialized_response is not None: + _send_response(rpc_event, state, serialized_response) + + try: + argument = argument_thunk() + if argument is not None: + if hasattr(behavior, 'experimental_non_blocking' + ) and behavior.experimental_non_blocking: + _call_behavior(rpc_event, + state, + behavior, + argument, + request_deserializer, + send_response_callback=send_response) + else: + response_iterator, proceed = _call_behavior( + rpc_event, state, behavior, argument, request_deserializer) + if proceed: + _send_message_callback_to_blocking_iterator_adapter( + rpc_event, state, send_response, response_iterator) + finally: + cygrpc.uninstall_context() + + +def _is_rpc_state_active(state): + return state.client is not _CANCELLED and not state.statused + + +def _send_message_callback_to_blocking_iterator_adapter(rpc_event, state, + send_response_callback, + response_iterator): + while True: + response, proceed = _take_response_from_response_iterator( + rpc_event, state, response_iterator) + if proceed: + send_response_callback(response) + if not _is_rpc_state_active(state): + break + else: + break + + +def _select_thread_pool_for_behavior(behavior, default_thread_pool): + if hasattr(behavior, 'experimental_thread_pool') and isinstance( + behavior.experimental_thread_pool, futures.ThreadPoolExecutor): + return behavior.experimental_thread_pool + else: + return default_thread_pool + + +def _handle_unary_unary(rpc_event, state, method_handler, default_thread_pool): + unary_request = _unary_request(rpc_event, state, + method_handler.request_deserializer) + thread_pool = _select_thread_pool_for_behavior(method_handler.unary_unary, + default_thread_pool) + return thread_pool.submit(_unary_response_in_pool, rpc_event, state, + method_handler.unary_unary, unary_request, + method_handler.request_deserializer, + method_handler.response_serializer) + + +def _handle_unary_stream(rpc_event, state, method_handler, default_thread_pool): + unary_request = _unary_request(rpc_event, state, + method_handler.request_deserializer) + thread_pool = _select_thread_pool_for_behavior(method_handler.unary_stream, + default_thread_pool) + return thread_pool.submit(_stream_response_in_pool, rpc_event, state, + method_handler.unary_stream, unary_request, + method_handler.request_deserializer, + method_handler.response_serializer) + + +def _handle_stream_unary(rpc_event, state, method_handler, default_thread_pool): + request_iterator = _RequestIterator(state, rpc_event.call, + method_handler.request_deserializer) + thread_pool = _select_thread_pool_for_behavior(method_handler.stream_unary, + default_thread_pool) + return thread_pool.submit(_unary_response_in_pool, rpc_event, state, + method_handler.stream_unary, + lambda: request_iterator, + method_handler.request_deserializer, + method_handler.response_serializer) + + +def _handle_stream_stream(rpc_event, state, method_handler, + default_thread_pool): + request_iterator = _RequestIterator(state, rpc_event.call, + method_handler.request_deserializer) + thread_pool = _select_thread_pool_for_behavior(method_handler.stream_stream, + default_thread_pool) + return thread_pool.submit(_stream_response_in_pool, rpc_event, state, + method_handler.stream_stream, + lambda: request_iterator, + method_handler.request_deserializer, + method_handler.response_serializer) + + +def _find_method_handler(rpc_event, generic_handlers, interceptor_pipeline): + + def query_handlers(handler_call_details): + for generic_handler in generic_handlers: + method_handler = generic_handler.service(handler_call_details) + if method_handler is not None: + return method_handler + return None + + handler_call_details = _HandlerCallDetails( + _common.decode(rpc_event.call_details.method), + rpc_event.invocation_metadata) + + if interceptor_pipeline is not None: + return interceptor_pipeline.execute(query_handlers, + handler_call_details) + else: + return query_handlers(handler_call_details) + + +def _reject_rpc(rpc_event, status, details): + rpc_state = _RPCState() + operations = ( + _get_initial_metadata_operation(rpc_state, None), + cygrpc.ReceiveCloseOnServerOperation(_EMPTY_FLAGS), + cygrpc.SendStatusFromServerOperation(None, status, details, + _EMPTY_FLAGS), + ) + rpc_event.call.start_server_batch(operations, lambda ignored_event: ( + rpc_state, + (), + )) + return rpc_state + + +def _handle_with_method_handler(rpc_event, method_handler, thread_pool): + state = _RPCState() + with state.condition: + rpc_event.call.start_server_batch( + (cygrpc.ReceiveCloseOnServerOperation(_EMPTY_FLAGS),), + _receive_close_on_server(state)) + state.due.add(_RECEIVE_CLOSE_ON_SERVER_TOKEN) + if method_handler.request_streaming: + if method_handler.response_streaming: + return state, _handle_stream_stream(rpc_event, state, + method_handler, thread_pool) + else: + return state, _handle_stream_unary(rpc_event, state, + method_handler, thread_pool) + else: + if method_handler.response_streaming: + return state, _handle_unary_stream(rpc_event, state, + method_handler, thread_pool) + else: + return state, _handle_unary_unary(rpc_event, state, + method_handler, thread_pool) + + +def _handle_call(rpc_event, generic_handlers, interceptor_pipeline, thread_pool, + concurrency_exceeded): + if not rpc_event.success: + return None, None + if rpc_event.call_details.method is not None: + try: + method_handler = _find_method_handler(rpc_event, generic_handlers, + interceptor_pipeline) + except Exception as exception: # pylint: disable=broad-except + details = 'Exception servicing handler: {}'.format(exception) + _LOGGER.exception(details) + return _reject_rpc(rpc_event, cygrpc.StatusCode.unknown, + b'Error in service handler!'), None + if method_handler is None: + return _reject_rpc(rpc_event, cygrpc.StatusCode.unimplemented, + b'Method not found!'), None + elif concurrency_exceeded: + return _reject_rpc(rpc_event, cygrpc.StatusCode.resource_exhausted, + b'Concurrent RPC limit exceeded!'), None + else: + return _handle_with_method_handler(rpc_event, method_handler, + thread_pool) + else: + return None, None + + +@enum.unique +class _ServerStage(enum.Enum): + STOPPED = 'stopped' + STARTED = 'started' + GRACE = 'grace' + + +class _ServerState(object): + + # pylint: disable=too-many-arguments + def __init__(self, completion_queue, server, generic_handlers, + interceptor_pipeline, thread_pool, maximum_concurrent_rpcs): + self.lock = threading.RLock() + self.completion_queue = completion_queue + self.server = server + self.generic_handlers = list(generic_handlers) + self.interceptor_pipeline = interceptor_pipeline + self.thread_pool = thread_pool + self.stage = _ServerStage.STOPPED + self.termination_event = threading.Event() + self.shutdown_events = [self.termination_event] + self.maximum_concurrent_rpcs = maximum_concurrent_rpcs + self.active_rpc_count = 0 + + # TODO(https://github.com/grpc/grpc/issues/6597): eliminate these fields. + self.rpc_states = set() + self.due = set() + + # A "volatile" flag to interrupt the daemon serving thread + self.server_deallocated = False + + +def _add_generic_handlers(state, generic_handlers): + with state.lock: + state.generic_handlers.extend(generic_handlers) + + +def _add_insecure_port(state, address): + with state.lock: + return state.server.add_http2_port(address) + + +def _add_secure_port(state, address, server_credentials): + with state.lock: + return state.server.add_http2_port(address, + server_credentials._credentials) + + +def _request_call(state): + state.server.request_call(state.completion_queue, state.completion_queue, + _REQUEST_CALL_TAG) + state.due.add(_REQUEST_CALL_TAG) + + +# TODO(https://github.com/grpc/grpc/issues/6597): delete this function. +def _stop_serving(state): + if not state.rpc_states and not state.due: + state.server.destroy() + for shutdown_event in state.shutdown_events: + shutdown_event.set() + state.stage = _ServerStage.STOPPED + return True + else: + return False + + +def _on_call_completed(state): + with state.lock: + state.active_rpc_count -= 1 + + +def _process_event_and_continue(state, event): + should_continue = True + if event.tag is _SHUTDOWN_TAG: + with state.lock: + state.due.remove(_SHUTDOWN_TAG) + if _stop_serving(state): + should_continue = False + elif event.tag is _REQUEST_CALL_TAG: + with state.lock: + state.due.remove(_REQUEST_CALL_TAG) + concurrency_exceeded = ( + state.maximum_concurrent_rpcs is not None and + state.active_rpc_count >= state.maximum_concurrent_rpcs) + rpc_state, rpc_future = _handle_call(event, state.generic_handlers, + state.interceptor_pipeline, + state.thread_pool, + concurrency_exceeded) + if rpc_state is not None: + state.rpc_states.add(rpc_state) + if rpc_future is not None: + state.active_rpc_count += 1 + rpc_future.add_done_callback( + lambda unused_future: _on_call_completed(state)) + if state.stage is _ServerStage.STARTED: + _request_call(state) + elif _stop_serving(state): + should_continue = False + else: + rpc_state, callbacks = event.tag(event) + for callback in callbacks: + try: + callback() + except Exception: # pylint: disable=broad-except + _LOGGER.exception('Exception calling callback!') + if rpc_state is not None: + with state.lock: + state.rpc_states.remove(rpc_state) + if _stop_serving(state): + should_continue = False + return should_continue + + +def _serve(state): + while True: + timeout = time.time() + _DEALLOCATED_SERVER_CHECK_PERIOD_S + event = state.completion_queue.poll(timeout) + if state.server_deallocated: + _begin_shutdown_once(state) + if event.completion_type != cygrpc.CompletionType.queue_timeout: + if not _process_event_and_continue(state, event): + return + # We want to force the deletion of the previous event + # ~before~ we poll again; if the event has a reference + # to a shutdown Call object, this can induce spinlock. + event = None + + +def _begin_shutdown_once(state): + with state.lock: + if state.stage is _ServerStage.STARTED: + state.server.shutdown(state.completion_queue, _SHUTDOWN_TAG) + state.stage = _ServerStage.GRACE + state.due.add(_SHUTDOWN_TAG) + + +def _stop(state, grace): + with state.lock: + if state.stage is _ServerStage.STOPPED: + shutdown_event = threading.Event() + shutdown_event.set() + return shutdown_event + else: + _begin_shutdown_once(state) + shutdown_event = threading.Event() + state.shutdown_events.append(shutdown_event) + if grace is None: + state.server.cancel_all_calls() + else: + + def cancel_all_calls_after_grace(): + shutdown_event.wait(timeout=grace) + with state.lock: + state.server.cancel_all_calls() + + thread = threading.Thread(target=cancel_all_calls_after_grace) + thread.start() + return shutdown_event + shutdown_event.wait() + return shutdown_event + + +def _start(state): + with state.lock: + if state.stage is not _ServerStage.STOPPED: + raise ValueError('Cannot start already-started server!') + state.server.start() + state.stage = _ServerStage.STARTED + _request_call(state) + + thread = threading.Thread(target=_serve, args=(state,)) + thread.daemon = True + thread.start() + + +def _validate_generic_rpc_handlers(generic_rpc_handlers): + for generic_rpc_handler in generic_rpc_handlers: + service_attribute = getattr(generic_rpc_handler, 'service', None) + if service_attribute is None: + raise AttributeError( + '"{}" must conform to grpc.GenericRpcHandler type but does ' + 'not have "service" method!'.format(generic_rpc_handler)) + + +def _augment_options(base_options, compression): + compression_option = _compression.create_channel_option(compression) + return tuple(base_options) + compression_option + + +class _Server(grpc.Server): + + # pylint: disable=too-many-arguments + def __init__(self, thread_pool, generic_handlers, interceptors, options, + maximum_concurrent_rpcs, compression, xds): + completion_queue = cygrpc.CompletionQueue() + server = cygrpc.Server(_augment_options(options, compression), xds) + server.register_completion_queue(completion_queue) + self._state = _ServerState(completion_queue, server, generic_handlers, + _interceptor.service_pipeline(interceptors), + thread_pool, maximum_concurrent_rpcs) + + def add_generic_rpc_handlers(self, generic_rpc_handlers): + _validate_generic_rpc_handlers(generic_rpc_handlers) + _add_generic_handlers(self._state, generic_rpc_handlers) + + def add_insecure_port(self, address): + return _common.validate_port_binding_result( + address, _add_insecure_port(self._state, _common.encode(address))) + + def add_secure_port(self, address, server_credentials): + return _common.validate_port_binding_result( + address, + _add_secure_port(self._state, _common.encode(address), + server_credentials)) + + def start(self): + _start(self._state) + + def wait_for_termination(self, timeout=None): + # NOTE(https://bugs.python.org/issue35935) + # Remove this workaround once threading.Event.wait() is working with + # CTRL+C across platforms. + return _common.wait(self._state.termination_event.wait, + self._state.termination_event.is_set, + timeout=timeout) + + def stop(self, grace): + return _stop(self._state, grace) + + def __del__(self): + if hasattr(self, '_state'): + # We can not grab a lock in __del__(), so set a flag to signal the + # serving daemon thread (if it exists) to initiate shutdown. + self._state.server_deallocated = True + + +def create_server(thread_pool, generic_rpc_handlers, interceptors, options, + maximum_concurrent_rpcs, compression, xds): + _validate_generic_rpc_handlers(generic_rpc_handlers) + return _Server(thread_pool, generic_rpc_handlers, interceptors, options, + maximum_concurrent_rpcs, compression, xds) diff --git a/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/grpc/_simple_stubs.py b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/grpc/_simple_stubs.py new file mode 100644 index 0000000000000000000000000000000000000000..54c2a2d5dbd7fd0f083bfc3489e29752fb0eedbe --- /dev/null +++ b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/grpc/_simple_stubs.py @@ -0,0 +1,486 @@ +# Copyright 2020 The gRPC authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""Functions that obviate explicit stubs and explicit channels.""" + +import collections +import datetime +import logging +import os +import threading +from typing import (Any, AnyStr, Callable, Dict, Iterator, Optional, Sequence, + Tuple, TypeVar, Union) + +import grpc +from grpc.experimental import experimental_api + +RequestType = TypeVar('RequestType') +ResponseType = TypeVar('ResponseType') + +OptionsType = Sequence[Tuple[str, str]] +CacheKey = Tuple[str, OptionsType, Optional[grpc.ChannelCredentials], + Optional[grpc.Compression]] + +_LOGGER = logging.getLogger(__name__) + +_EVICTION_PERIOD_KEY = "GRPC_PYTHON_MANAGED_CHANNEL_EVICTION_SECONDS" +if _EVICTION_PERIOD_KEY in os.environ: + _EVICTION_PERIOD = datetime.timedelta( + seconds=float(os.environ[_EVICTION_PERIOD_KEY])) + _LOGGER.debug("Setting managed channel eviction period to %s", + _EVICTION_PERIOD) +else: + _EVICTION_PERIOD = datetime.timedelta(minutes=10) + +_MAXIMUM_CHANNELS_KEY = "GRPC_PYTHON_MANAGED_CHANNEL_MAXIMUM" +if _MAXIMUM_CHANNELS_KEY in os.environ: + _MAXIMUM_CHANNELS = int(os.environ[_MAXIMUM_CHANNELS_KEY]) + _LOGGER.debug("Setting maximum managed channels to %d", _MAXIMUM_CHANNELS) +else: + _MAXIMUM_CHANNELS = 2**8 + +_DEFAULT_TIMEOUT_KEY = "GRPC_PYTHON_DEFAULT_TIMEOUT_SECONDS" +if _DEFAULT_TIMEOUT_KEY in os.environ: + _DEFAULT_TIMEOUT = float(os.environ[_DEFAULT_TIMEOUT_KEY]) + _LOGGER.debug("Setting default timeout seconds to %f", _DEFAULT_TIMEOUT) +else: + _DEFAULT_TIMEOUT = 60.0 + + +def _create_channel(target: str, options: Sequence[Tuple[str, str]], + channel_credentials: Optional[grpc.ChannelCredentials], + compression: Optional[grpc.Compression]) -> grpc.Channel: + _LOGGER.debug( + f"Creating secure channel with credentials '{channel_credentials}', " + + f"options '{options}' and compression '{compression}'") + return grpc.secure_channel(target, + credentials=channel_credentials, + options=options, + compression=compression) + + +class ChannelCache: + # NOTE(rbellevi): Untyped due to reference cycle. + _singleton = None + _lock: threading.RLock = threading.RLock() + _condition: threading.Condition = threading.Condition(lock=_lock) + _eviction_ready: threading.Event = threading.Event() + + _mapping: Dict[CacheKey, Tuple[grpc.Channel, datetime.datetime]] + _eviction_thread: threading.Thread + + def __init__(self): + self._mapping = collections.OrderedDict() + self._eviction_thread = threading.Thread( + target=ChannelCache._perform_evictions, daemon=True) + self._eviction_thread.start() + + @staticmethod + def get(): + with ChannelCache._lock: + if ChannelCache._singleton is None: + ChannelCache._singleton = ChannelCache() + ChannelCache._eviction_ready.wait() + return ChannelCache._singleton + + def _evict_locked(self, key: CacheKey): + channel, _ = self._mapping.pop(key) + _LOGGER.debug("Evicting channel %s with configuration %s.", channel, + key) + channel.close() + del channel + + @staticmethod + def _perform_evictions(): + while True: + with ChannelCache._lock: + ChannelCache._eviction_ready.set() + if not ChannelCache._singleton._mapping: + ChannelCache._condition.wait() + elif len(ChannelCache._singleton._mapping) > _MAXIMUM_CHANNELS: + key = next(iter(ChannelCache._singleton._mapping.keys())) + ChannelCache._singleton._evict_locked(key) + # And immediately reevaluate. + else: + key, (_, eviction_time) = next( + iter(ChannelCache._singleton._mapping.items())) + now = datetime.datetime.now() + if eviction_time <= now: + ChannelCache._singleton._evict_locked(key) + continue + else: + time_to_eviction = (eviction_time - now).total_seconds() + # NOTE: We aim to *eventually* coalesce to a state in + # which no overdue channels are in the cache and the + # length of the cache is longer than _MAXIMUM_CHANNELS. + # We tolerate momentary states in which these two + # criteria are not met. + ChannelCache._condition.wait(timeout=time_to_eviction) + + def get_channel(self, target: str, options: Sequence[Tuple[str, str]], + channel_credentials: Optional[grpc.ChannelCredentials], + insecure: bool, + compression: Optional[grpc.Compression]) -> grpc.Channel: + if insecure and channel_credentials: + raise ValueError("The insecure option is mutually exclusive with " + + "the channel_credentials option. Please use one " + + "or the other.") + if insecure: + channel_credentials = grpc.experimental.insecure_channel_credentials( + ) + elif channel_credentials is None: + _LOGGER.debug("Defaulting to SSL channel credentials.") + channel_credentials = grpc.ssl_channel_credentials() + key = (target, options, channel_credentials, compression) + with self._lock: + channel_data = self._mapping.get(key, None) + if channel_data is not None: + channel = channel_data[0] + self._mapping.pop(key) + self._mapping[key] = (channel, datetime.datetime.now() + + _EVICTION_PERIOD) + return channel + else: + channel = _create_channel(target, options, channel_credentials, + compression) + self._mapping[key] = (channel, datetime.datetime.now() + + _EVICTION_PERIOD) + if len(self._mapping) == 1 or len( + self._mapping) >= _MAXIMUM_CHANNELS: + self._condition.notify() + return channel + + def _test_only_channel_count(self) -> int: + with self._lock: + return len(self._mapping) + + +@experimental_api +def unary_unary( + request: RequestType, + target: str, + method: str, + request_serializer: Optional[Callable[[Any], bytes]] = None, + response_deserializer: Optional[Callable[[bytes], Any]] = None, + options: Sequence[Tuple[AnyStr, AnyStr]] = (), + channel_credentials: Optional[grpc.ChannelCredentials] = None, + insecure: bool = False, + call_credentials: Optional[grpc.CallCredentials] = None, + compression: Optional[grpc.Compression] = None, + wait_for_ready: Optional[bool] = None, + timeout: Optional[float] = _DEFAULT_TIMEOUT, + metadata: Optional[Sequence[Tuple[str, Union[str, bytes]]]] = None +) -> ResponseType: + """Invokes a unary-unary RPC without an explicitly specified channel. + + THIS IS AN EXPERIMENTAL API. + + This is backed by a per-process cache of channels. Channels are evicted + from the cache after a fixed period by a background. Channels will also be + evicted if more than a configured maximum accumulate. + + The default eviction period is 10 minutes. One may set the environment + variable "GRPC_PYTHON_MANAGED_CHANNEL_EVICTION_SECONDS" to configure this. + + The default maximum number of channels is 256. One may set the + environment variable "GRPC_PYTHON_MANAGED_CHANNEL_MAXIMUM" to configure + this. + + Args: + request: An iterator that yields request values for the RPC. + target: The server address. + method: The name of the RPC method. + request_serializer: Optional :term:`serializer` for serializing the request + message. Request goes unserialized in case None is passed. + response_deserializer: Optional :term:`deserializer` for deserializing the response + message. Response goes undeserialized in case None is passed. + options: An optional list of key-value pairs (:term:`channel_arguments` in gRPC Core + runtime) to configure the channel. + channel_credentials: A credential applied to the whole channel, e.g. the + return value of grpc.ssl_channel_credentials() or + grpc.insecure_channel_credentials(). + insecure: If True, specifies channel_credentials as + :term:`grpc.insecure_channel_credentials()`. This option is mutually + exclusive with the `channel_credentials` option. + call_credentials: A call credential applied to each call individually, + e.g. the output of grpc.metadata_call_credentials() or + grpc.access_token_call_credentials(). + compression: An optional value indicating the compression method to be + used over the lifetime of the channel, e.g. grpc.Compression.Gzip. + wait_for_ready: An optional flag indicating whether the RPC should fail + immediately if the connection is not ready at the time the RPC is + invoked, or if it should wait until the connection to the server + becomes ready. When using this option, the user will likely also want + to set a timeout. Defaults to True. + timeout: An optional duration of time in seconds to allow for the RPC, + after which an exception will be raised. If timeout is unspecified, + defaults to a timeout controlled by the + GRPC_PYTHON_DEFAULT_TIMEOUT_SECONDS environment variable. If that is + unset, defaults to 60 seconds. Supply a value of None to indicate that + no timeout should be enforced. + metadata: Optional metadata to send to the server. + + Returns: + The response to the RPC. + """ + channel = ChannelCache.get().get_channel(target, options, + channel_credentials, insecure, + compression) + multicallable = channel.unary_unary(method, request_serializer, + response_deserializer) + wait_for_ready = wait_for_ready if wait_for_ready is not None else True + return multicallable(request, + metadata=metadata, + wait_for_ready=wait_for_ready, + credentials=call_credentials, + timeout=timeout) + + +@experimental_api +def unary_stream( + request: RequestType, + target: str, + method: str, + request_serializer: Optional[Callable[[Any], bytes]] = None, + response_deserializer: Optional[Callable[[bytes], Any]] = None, + options: Sequence[Tuple[AnyStr, AnyStr]] = (), + channel_credentials: Optional[grpc.ChannelCredentials] = None, + insecure: bool = False, + call_credentials: Optional[grpc.CallCredentials] = None, + compression: Optional[grpc.Compression] = None, + wait_for_ready: Optional[bool] = None, + timeout: Optional[float] = _DEFAULT_TIMEOUT, + metadata: Optional[Sequence[Tuple[str, Union[str, bytes]]]] = None +) -> Iterator[ResponseType]: + """Invokes a unary-stream RPC without an explicitly specified channel. + + THIS IS AN EXPERIMENTAL API. + + This is backed by a per-process cache of channels. Channels are evicted + from the cache after a fixed period by a background. Channels will also be + evicted if more than a configured maximum accumulate. + + The default eviction period is 10 minutes. One may set the environment + variable "GRPC_PYTHON_MANAGED_CHANNEL_EVICTION_SECONDS" to configure this. + + The default maximum number of channels is 256. One may set the + environment variable "GRPC_PYTHON_MANAGED_CHANNEL_MAXIMUM" to configure + this. + + Args: + request: An iterator that yields request values for the RPC. + target: The server address. + method: The name of the RPC method. + request_serializer: Optional :term:`serializer` for serializing the request + message. Request goes unserialized in case None is passed. + response_deserializer: Optional :term:`deserializer` for deserializing the response + message. Response goes undeserialized in case None is passed. + options: An optional list of key-value pairs (:term:`channel_arguments` in gRPC Core + runtime) to configure the channel. + channel_credentials: A credential applied to the whole channel, e.g. the + return value of grpc.ssl_channel_credentials(). + insecure: If True, specifies channel_credentials as + :term:`grpc.insecure_channel_credentials()`. This option is mutually + exclusive with the `channel_credentials` option. + call_credentials: A call credential applied to each call individually, + e.g. the output of grpc.metadata_call_credentials() or + grpc.access_token_call_credentials(). + compression: An optional value indicating the compression method to be + used over the lifetime of the channel, e.g. grpc.Compression.Gzip. + wait_for_ready: An optional flag indicating whether the RPC should fail + immediately if the connection is not ready at the time the RPC is + invoked, or if it should wait until the connection to the server + becomes ready. When using this option, the user will likely also want + to set a timeout. Defaults to True. + timeout: An optional duration of time in seconds to allow for the RPC, + after which an exception will be raised. If timeout is unspecified, + defaults to a timeout controlled by the + GRPC_PYTHON_DEFAULT_TIMEOUT_SECONDS environment variable. If that is + unset, defaults to 60 seconds. Supply a value of None to indicate that + no timeout should be enforced. + metadata: Optional metadata to send to the server. + + Returns: + An iterator of responses. + """ + channel = ChannelCache.get().get_channel(target, options, + channel_credentials, insecure, + compression) + multicallable = channel.unary_stream(method, request_serializer, + response_deserializer) + wait_for_ready = wait_for_ready if wait_for_ready is not None else True + return multicallable(request, + metadata=metadata, + wait_for_ready=wait_for_ready, + credentials=call_credentials, + timeout=timeout) + + +@experimental_api +def stream_unary( + request_iterator: Iterator[RequestType], + target: str, + method: str, + request_serializer: Optional[Callable[[Any], bytes]] = None, + response_deserializer: Optional[Callable[[bytes], Any]] = None, + options: Sequence[Tuple[AnyStr, AnyStr]] = (), + channel_credentials: Optional[grpc.ChannelCredentials] = None, + insecure: bool = False, + call_credentials: Optional[grpc.CallCredentials] = None, + compression: Optional[grpc.Compression] = None, + wait_for_ready: Optional[bool] = None, + timeout: Optional[float] = _DEFAULT_TIMEOUT, + metadata: Optional[Sequence[Tuple[str, Union[str, bytes]]]] = None +) -> ResponseType: + """Invokes a stream-unary RPC without an explicitly specified channel. + + THIS IS AN EXPERIMENTAL API. + + This is backed by a per-process cache of channels. Channels are evicted + from the cache after a fixed period by a background. Channels will also be + evicted if more than a configured maximum accumulate. + + The default eviction period is 10 minutes. One may set the environment + variable "GRPC_PYTHON_MANAGED_CHANNEL_EVICTION_SECONDS" to configure this. + + The default maximum number of channels is 256. One may set the + environment variable "GRPC_PYTHON_MANAGED_CHANNEL_MAXIMUM" to configure + this. + + Args: + request_iterator: An iterator that yields request values for the RPC. + target: The server address. + method: The name of the RPC method. + request_serializer: Optional :term:`serializer` for serializing the request + message. Request goes unserialized in case None is passed. + response_deserializer: Optional :term:`deserializer` for deserializing the response + message. Response goes undeserialized in case None is passed. + options: An optional list of key-value pairs (:term:`channel_arguments` in gRPC Core + runtime) to configure the channel. + channel_credentials: A credential applied to the whole channel, e.g. the + return value of grpc.ssl_channel_credentials(). + call_credentials: A call credential applied to each call individually, + e.g. the output of grpc.metadata_call_credentials() or + grpc.access_token_call_credentials(). + insecure: If True, specifies channel_credentials as + :term:`grpc.insecure_channel_credentials()`. This option is mutually + exclusive with the `channel_credentials` option. + compression: An optional value indicating the compression method to be + used over the lifetime of the channel, e.g. grpc.Compression.Gzip. + wait_for_ready: An optional flag indicating whether the RPC should fail + immediately if the connection is not ready at the time the RPC is + invoked, or if it should wait until the connection to the server + becomes ready. When using this option, the user will likely also want + to set a timeout. Defaults to True. + timeout: An optional duration of time in seconds to allow for the RPC, + after which an exception will be raised. If timeout is unspecified, + defaults to a timeout controlled by the + GRPC_PYTHON_DEFAULT_TIMEOUT_SECONDS environment variable. If that is + unset, defaults to 60 seconds. Supply a value of None to indicate that + no timeout should be enforced. + metadata: Optional metadata to send to the server. + + Returns: + The response to the RPC. + """ + channel = ChannelCache.get().get_channel(target, options, + channel_credentials, insecure, + compression) + multicallable = channel.stream_unary(method, request_serializer, + response_deserializer) + wait_for_ready = wait_for_ready if wait_for_ready is not None else True + return multicallable(request_iterator, + metadata=metadata, + wait_for_ready=wait_for_ready, + credentials=call_credentials, + timeout=timeout) + + +@experimental_api +def stream_stream( + request_iterator: Iterator[RequestType], + target: str, + method: str, + request_serializer: Optional[Callable[[Any], bytes]] = None, + response_deserializer: Optional[Callable[[bytes], Any]] = None, + options: Sequence[Tuple[AnyStr, AnyStr]] = (), + channel_credentials: Optional[grpc.ChannelCredentials] = None, + insecure: bool = False, + call_credentials: Optional[grpc.CallCredentials] = None, + compression: Optional[grpc.Compression] = None, + wait_for_ready: Optional[bool] = None, + timeout: Optional[float] = _DEFAULT_TIMEOUT, + metadata: Optional[Sequence[Tuple[str, Union[str, bytes]]]] = None +) -> Iterator[ResponseType]: + """Invokes a stream-stream RPC without an explicitly specified channel. + + THIS IS AN EXPERIMENTAL API. + + This is backed by a per-process cache of channels. Channels are evicted + from the cache after a fixed period by a background. Channels will also be + evicted if more than a configured maximum accumulate. + + The default eviction period is 10 minutes. One may set the environment + variable "GRPC_PYTHON_MANAGED_CHANNEL_EVICTION_SECONDS" to configure this. + + The default maximum number of channels is 256. One may set the + environment variable "GRPC_PYTHON_MANAGED_CHANNEL_MAXIMUM" to configure + this. + + Args: + request_iterator: An iterator that yields request values for the RPC. + target: The server address. + method: The name of the RPC method. + request_serializer: Optional :term:`serializer` for serializing the request + message. Request goes unserialized in case None is passed. + response_deserializer: Optional :term:`deserializer` for deserializing the response + message. Response goes undeserialized in case None is passed. + options: An optional list of key-value pairs (:term:`channel_arguments` in gRPC Core + runtime) to configure the channel. + channel_credentials: A credential applied to the whole channel, e.g. the + return value of grpc.ssl_channel_credentials(). + call_credentials: A call credential applied to each call individually, + e.g. the output of grpc.metadata_call_credentials() or + grpc.access_token_call_credentials(). + insecure: If True, specifies channel_credentials as + :term:`grpc.insecure_channel_credentials()`. This option is mutually + exclusive with the `channel_credentials` option. + compression: An optional value indicating the compression method to be + used over the lifetime of the channel, e.g. grpc.Compression.Gzip. + wait_for_ready: An optional flag indicating whether the RPC should fail + immediately if the connection is not ready at the time the RPC is + invoked, or if it should wait until the connection to the server + becomes ready. When using this option, the user will likely also want + to set a timeout. Defaults to True. + timeout: An optional duration of time in seconds to allow for the RPC, + after which an exception will be raised. If timeout is unspecified, + defaults to a timeout controlled by the + GRPC_PYTHON_DEFAULT_TIMEOUT_SECONDS environment variable. If that is + unset, defaults to 60 seconds. Supply a value of None to indicate that + no timeout should be enforced. + metadata: Optional metadata to send to the server. + + Returns: + An iterator of responses. + """ + channel = ChannelCache.get().get_channel(target, options, + channel_credentials, insecure, + compression) + multicallable = channel.stream_stream(method, request_serializer, + response_deserializer) + wait_for_ready = wait_for_ready if wait_for_ready is not None else True + return multicallable(request_iterator, + metadata=metadata, + wait_for_ready=wait_for_ready, + credentials=call_credentials, + timeout=timeout) diff --git a/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/omegaconf/_impl.py b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/omegaconf/_impl.py new file mode 100644 index 0000000000000000000000000000000000000000..0c30ef6a239e65302c484b361773a00f85c70909 --- /dev/null +++ b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/omegaconf/_impl.py @@ -0,0 +1,101 @@ +from typing import Any + +from omegaconf import MISSING, Container, DictConfig, ListConfig, Node, ValueNode +from omegaconf.errors import ConfigTypeError, InterpolationToMissingValueError + +from ._utils import _DEFAULT_MARKER_, _get_value + + +def _resolve_container_value(cfg: Container, key: Any) -> None: + node = cfg._get_child(key) + assert isinstance(node, Node) + if node._is_interpolation(): + try: + resolved = node._dereference_node() + except InterpolationToMissingValueError: + node._set_value(MISSING) + else: + if isinstance(resolved, Container): + _resolve(resolved) + if isinstance(resolved, Container) and isinstance(node, ValueNode): + cfg[key] = resolved + else: + node._set_value(_get_value(resolved)) + else: + _resolve(node) + + +def _resolve(cfg: Node) -> Node: + assert isinstance(cfg, Node) + if cfg._is_interpolation(): + try: + resolved = cfg._dereference_node() + except InterpolationToMissingValueError: + cfg._set_value(MISSING) + else: + cfg._set_value(resolved._value()) + + if isinstance(cfg, DictConfig): + for k in cfg.keys(): + _resolve_container_value(cfg, k) + + elif isinstance(cfg, ListConfig): + for i in range(len(cfg)): + _resolve_container_value(cfg, i) + + return cfg + + +def select_value( + cfg: Container, + key: str, + *, + default: Any = _DEFAULT_MARKER_, + throw_on_resolution_failure: bool = True, + throw_on_missing: bool = False, + absolute_key: bool = False, +) -> Any: + node = select_node( + cfg=cfg, + key=key, + throw_on_resolution_failure=throw_on_resolution_failure, + throw_on_missing=throw_on_missing, + absolute_key=absolute_key, + ) + + node_not_found = node is None + if node_not_found or node._is_missing(): + if default is not _DEFAULT_MARKER_: + return default + else: + return None + + return _get_value(node) + + +def select_node( + cfg: Container, + key: str, + *, + throw_on_resolution_failure: bool = True, + throw_on_missing: bool = False, + absolute_key: bool = False, +) -> Any: + try: + # for non relative keys, the interpretation can be: + # 1. relative to cfg + # 2. relative to the config root + # This is controlled by the absolute_key flag. By default, such keys are relative to cfg. + if not absolute_key and not key.startswith("."): + key = f".{key}" + + cfg, key = cfg._resolve_key_and_root(key) + _root, _last_key, node = cfg._select_impl( + key, + throw_on_missing=throw_on_missing, + throw_on_resolution_failure=throw_on_resolution_failure, + ) + except ConfigTypeError: + return None + + return node diff --git a/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/omegaconf/errors.py b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/omegaconf/errors.py new file mode 100644 index 0000000000000000000000000000000000000000..60525ef3c62fb89093c0b5aa1147ae6f80b61062 --- /dev/null +++ b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/omegaconf/errors.py @@ -0,0 +1,141 @@ +from typing import Any, Optional, Type + + +class OmegaConfBaseException(Exception): + # would ideally be typed Optional[Node] + parent_node: Any + child_node: Any + key: Any + full_key: Optional[str] + value: Any + msg: Optional[str] + cause: Optional[Exception] + object_type: Optional[Type[Any]] + object_type_str: Optional[str] + ref_type: Optional[Type[Any]] + ref_type_str: Optional[str] + + _initialized: bool = False + + def __init__(self, *_args: Any, **_kwargs: Any) -> None: + self.parent_node = None + self.child_node = None + self.key = None + self.full_key = None + self.value = None + self.msg = None + self.object_type = None + self.ref_type = None + + +class MissingMandatoryValue(OmegaConfBaseException): + """Thrown when a variable flagged with '???' value is accessed to + indicate that the value was not set""" + + +class KeyValidationError(OmegaConfBaseException, ValueError): + """ + Thrown when an a key of invalid type is used + """ + + +class ValidationError(OmegaConfBaseException, ValueError): + """ + Thrown when a value fails validation + """ + + +class UnsupportedValueType(ValidationError, ValueError): + """ + Thrown when an input value is not of supported type + """ + + +class ReadonlyConfigError(OmegaConfBaseException): + """ + Thrown when someone tries to modify a frozen config + """ + + +class InterpolationResolutionError(OmegaConfBaseException, ValueError): + """ + Base class for exceptions raised when resolving an interpolation. + """ + + +class UnsupportedInterpolationType(InterpolationResolutionError): + """ + Thrown when an attempt to use an unregistered interpolation is made + """ + + +class InterpolationKeyError(InterpolationResolutionError): + """ + Thrown when a node does not exist when resolving an interpolation. + """ + + +class InterpolationToMissingValueError(InterpolationResolutionError): + """ + Thrown when a node interpolation points to a node that is set to ???. + """ + + +class InterpolationValidationError(InterpolationResolutionError, ValidationError): + """ + Thrown when the result of an interpolation fails the validation step. + """ + + +class ConfigKeyError(OmegaConfBaseException, KeyError): + """ + Thrown from DictConfig when a regular dict access would have caused a KeyError. + """ + + msg: str + + def __init__(self, msg: str) -> None: + super().__init__(msg) + self.msg = msg + + def __str__(self) -> str: + """ + Workaround to nasty KeyError quirk: https://bugs.python.org/issue2651 + """ + return self.msg + + +class ConfigAttributeError(OmegaConfBaseException, AttributeError): + """ + Thrown from a config object when a regular access would have caused an AttributeError. + """ + + +class ConfigTypeError(OmegaConfBaseException, TypeError): + """ + Thrown from a config object when a regular access would have caused a TypeError. + """ + + +class ConfigIndexError(OmegaConfBaseException, IndexError): + """ + Thrown from a config object when a regular access would have caused an IndexError. + """ + + +class ConfigValueError(OmegaConfBaseException, ValueError): + """ + Thrown from a config object when a regular access would have caused a ValueError. + """ + + +class ConfigCycleDetectedException(OmegaConfBaseException): + """ + Thrown when a cycle is detected in the graph made by config nodes. + """ + + +class GrammarParseError(OmegaConfBaseException): + """ + Thrown when failing to parse an expression according to the ANTLR grammar. + """ diff --git a/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/omegaconf/grammar_parser.py b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/omegaconf/grammar_parser.py new file mode 100644 index 0000000000000000000000000000000000000000..85a931154269c4f45645ef5c111d13068f646832 --- /dev/null +++ b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/omegaconf/grammar_parser.py @@ -0,0 +1,144 @@ +import re +import threading +from typing import Any + +from antlr4 import CommonTokenStream, InputStream, ParserRuleContext +from antlr4.error.ErrorListener import ErrorListener + +from .errors import GrammarParseError + +# Import from visitor in order to check the presence of generated grammar files +# files in a single place. +from .grammar_visitor import ( # type: ignore + OmegaConfGrammarLexer, + OmegaConfGrammarParser, +) + +# Used to cache grammar objects to avoid re-creating them on each call to `parse()`. +# We use a per-thread cache to make it thread-safe. +_grammar_cache = threading.local() + +# Build regex pattern to efficiently identify typical interpolations. +# See test `test_match_simple_interpolation_pattern` for examples. +_config_key = r"[$\w]+" # foo, $0, $bar, $foo_$bar123$ +_key_maybe_brackets = f"{_config_key}|\\[{_config_key}\\]" # foo, [foo], [$bar] +_node_access = f"\\.{_key_maybe_brackets}" # .foo, [foo], [$bar] +_node_path = f"(\\.)*({_key_maybe_brackets})({_node_access})*" # [foo].bar, .foo[bar] +_node_inter = f"\\${{\\s*{_node_path}\\s*}}" # node interpolation ${foo.bar} +_id = "[a-zA-Z_]\\w*" # foo, foo_bar, abc123 +_resolver_name = f"({_id}(\\.{_id})*)?" # foo, ns.bar3, ns_1.ns_2.b0z +_arg = r"[a-zA-Z_0-9/\-\+.$%*@?|]+" # string representing a resolver argument +_args = f"{_arg}(\\s*,\\s*{_arg})*" # list of resolver arguments +_resolver_inter = f"\\${{\\s*{_resolver_name}\\s*:\\s*{_args}?\\s*}}" # ${foo:bar} +_inter = f"({_node_inter}|{_resolver_inter})" # any kind of interpolation +_outer = "([^$]|\\$(?!{))+" # any character except $ (unless not followed by {) +SIMPLE_INTERPOLATION_PATTERN = re.compile( + f"({_outer})?({_inter}({_outer})?)+$", flags=re.ASCII +) +# NOTE: SIMPLE_INTERPOLATION_PATTERN must not generate false positive matches: +# it must not accept anything that isn't a valid interpolation (per the +# interpolation grammar defined in `omegaconf/grammar/*.g4`). + + +class OmegaConfErrorListener(ErrorListener): # type: ignore + def syntaxError( + self, + recognizer: Any, + offending_symbol: Any, + line: Any, + column: Any, + msg: Any, + e: Any, + ) -> None: + raise GrammarParseError(str(e) if msg is None else msg) from e + + def reportAmbiguity( + self, + recognizer: Any, + dfa: Any, + startIndex: Any, + stopIndex: Any, + exact: Any, + ambigAlts: Any, + configs: Any, + ) -> None: + raise GrammarParseError("ANTLR error: Ambiguity") # pragma: no cover + + def reportAttemptingFullContext( + self, + recognizer: Any, + dfa: Any, + startIndex: Any, + stopIndex: Any, + conflictingAlts: Any, + configs: Any, + ) -> None: + # Note: for now we raise an error to be safe. However this is mostly a + # performance warning, so in the future this may be relaxed if we need + # to change the grammar in such a way that this warning cannot be + # avoided (another option would be to switch to SLL parsing mode). + raise GrammarParseError( + "ANTLR error: Attempting Full Context" + ) # pragma: no cover + + def reportContextSensitivity( + self, + recognizer: Any, + dfa: Any, + startIndex: Any, + stopIndex: Any, + prediction: Any, + configs: Any, + ) -> None: + raise GrammarParseError("ANTLR error: ContextSensitivity") # pragma: no cover + + +def parse( + value: str, parser_rule: str = "configValue", lexer_mode: str = "DEFAULT_MODE" +) -> ParserRuleContext: + """ + Parse interpolated string `value` (and return the parse tree). + """ + l_mode = getattr(OmegaConfGrammarLexer, lexer_mode) + istream = InputStream(value) + + cached = getattr(_grammar_cache, "data", None) + if cached is None: + error_listener = OmegaConfErrorListener() + lexer = OmegaConfGrammarLexer(istream) + lexer.removeErrorListeners() + lexer.addErrorListener(error_listener) + lexer.mode(l_mode) + token_stream = CommonTokenStream(lexer) + parser = OmegaConfGrammarParser(token_stream) + parser.removeErrorListeners() + parser.addErrorListener(error_listener) + + # The two lines below could be enabled in the future if we decide to switch + # to SLL prediction mode. Warning though, it has not been fully tested yet! + # from antlr4 import PredictionMode + # parser._interp.predictionMode = PredictionMode.SLL + + # Note that although the input stream `istream` is implicitly cached within + # the lexer, it will be replaced by a new input next time the lexer is re-used. + _grammar_cache.data = lexer, token_stream, parser + + else: + lexer, token_stream, parser = cached + # Replace the old input stream with the new one. + lexer.inputStream = istream + # Initialize the lexer / token stream / parser to process the new input. + lexer.mode(l_mode) + token_stream.setTokenSource(lexer) + parser.reset() + + try: + return getattr(parser, parser_rule)() + except Exception as exc: + if type(exc) is Exception and str(exc) == "Empty Stack": + # This exception is raised by antlr when trying to pop a mode while + # no mode has been pushed. We convert it into an `GrammarParseError` + # to facilitate exception handling from the caller. + raise GrammarParseError("Empty Stack") + else: + raise diff --git a/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/omegaconf/version.py b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/omegaconf/version.py new file mode 100644 index 0000000000000000000000000000000000000000..5fc7a963794541bbf09c8b54635feeeb0f9b9347 --- /dev/null +++ b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/omegaconf/version.py @@ -0,0 +1,13 @@ +import sys # pragma: no cover + +__version__ = "2.2.3" + +msg = """OmegaConf 2.0 and above is compatible with Python 3.6 and newer. +You have the following options: +1. Upgrade to Python 3.6 or newer. + This is highly recommended. new features will not be added to OmegaConf 1.4. +2. Continue using OmegaConf 1.4: + You can pip install 'OmegaConf<1.5' to do that. +""" +if sys.version_info < (3, 6): + raise ImportError(msg) # pragma: no cover diff --git a/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/pyasn1_modules/rfc3114.py b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/pyasn1_modules/rfc3114.py new file mode 100644 index 0000000000000000000000000000000000000000..badcb1f2140383a12b286f7db1be1cf640df89ac --- /dev/null +++ b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/pyasn1_modules/rfc3114.py @@ -0,0 +1,77 @@ +# +# This file is part of pyasn1-modules software. +# +# Created by Russ Housley with assistance from asn1ate v.0.6.0. +# +# Copyright (c) 2019, Vigil Security, LLC +# License: http://snmplabs.com/pyasn1/license.html +# +# TEST Company Classification Policies +# +# ASN.1 source from: +# https://www.rfc-editor.org/rfc/rfc3114.txt +# + +from pyasn1.type import char +from pyasn1.type import namedval +from pyasn1.type import univ + +from pyasn1_modules import rfc5755 + + +id_smime = univ.ObjectIdentifier((1, 2, 840, 113549, 1, 9, 16, )) + +id_tsp = id_smime + (7, ) + +id_tsp_TEST_Amoco = id_tsp + (1, ) + +class Amoco_SecurityClassification(univ.Integer): + namedValues = namedval.NamedValues( + ('amoco-general', 6), + ('amoco-confidential', 7), + ('amoco-highly-confidential', 8) + ) + + +id_tsp_TEST_Caterpillar = id_tsp + (2, ) + +class Caterpillar_SecurityClassification(univ.Integer): + namedValues = namedval.NamedValues( + ('caterpillar-public', 6), + ('caterpillar-green', 7), + ('caterpillar-yellow', 8), + ('caterpillar-red', 9) + ) + + +id_tsp_TEST_Whirlpool = id_tsp + (3, ) + +class Whirlpool_SecurityClassification(univ.Integer): + namedValues = namedval.NamedValues( + ('whirlpool-public', 6), + ('whirlpool-internal', 7), + ('whirlpool-confidential', 8) + ) + + +id_tsp_TEST_Whirlpool_Categories = id_tsp + (4, ) + +class SecurityCategoryValues(univ.SequenceOf): + componentType = char.UTF8String() + +# Example SecurityCategoryValues: "LAW DEPARTMENT USE ONLY" +# Example SecurityCategoryValues: "HUMAN RESOURCES USE ONLY" + + +# Also, the privacy mark in the security label can contain a string, +# such as: "ATTORNEY-CLIENT PRIVILEGED INFORMATION" + + +# Map of security category type OIDs to security category added +# to the ones that are in rfc5755.py + +_securityCategoryMapUpdate = { + id_tsp_TEST_Whirlpool_Categories: SecurityCategoryValues(), +} + +rfc5755.securityCategoryMap.update(_securityCategoryMapUpdate) diff --git a/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/pyasn1_modules/rfc3281.py b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/pyasn1_modules/rfc3281.py new file mode 100644 index 0000000000000000000000000000000000000000..39ce82427cfd3a5b9a0d364b757a02df6dfef352 --- /dev/null +++ b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/pyasn1_modules/rfc3281.py @@ -0,0 +1,331 @@ +# coding: utf-8 +# +# This file is part of pyasn1-modules software. +# +# Created by Stanisław Pitucha with asn1ate tool. +# Copyright (c) 2005-2019, Ilya Etingof +# License: http://snmplabs.com/pyasn1/license.html +# +# An Internet Attribute Certificate Profile for Authorization +# +# ASN.1 source from: +# http://www.ietf.org/rfc/rfc3281.txt +# +from pyasn1.type import char +from pyasn1.type import constraint +from pyasn1.type import namedtype +from pyasn1.type import namedval +from pyasn1.type import tag +from pyasn1.type import univ +from pyasn1.type import useful + +from pyasn1_modules import rfc3280 + +MAX = float('inf') + + +def _buildOid(*components): + output = [] + for x in tuple(components): + if isinstance(x, univ.ObjectIdentifier): + output.extend(list(x)) + else: + output.append(int(x)) + + return univ.ObjectIdentifier(output) + + +class ObjectDigestInfo(univ.Sequence): + pass + + +ObjectDigestInfo.componentType = namedtype.NamedTypes( + namedtype.NamedType('digestedObjectType', univ.Enumerated( + namedValues=namedval.NamedValues(('publicKey', 0), ('publicKeyCert', 1), ('otherObjectTypes', 2)))), + namedtype.OptionalNamedType('otherObjectTypeID', univ.ObjectIdentifier()), + namedtype.NamedType('digestAlgorithm', rfc3280.AlgorithmIdentifier()), + namedtype.NamedType('objectDigest', univ.BitString()) +) + + +class IssuerSerial(univ.Sequence): + pass + + +IssuerSerial.componentType = namedtype.NamedTypes( + namedtype.NamedType('issuer', rfc3280.GeneralNames()), + namedtype.NamedType('serial', rfc3280.CertificateSerialNumber()), + namedtype.OptionalNamedType('issuerUID', rfc3280.UniqueIdentifier()) +) + + +class TargetCert(univ.Sequence): + pass + + +TargetCert.componentType = namedtype.NamedTypes( + namedtype.NamedType('targetCertificate', IssuerSerial()), + namedtype.OptionalNamedType('targetName', rfc3280.GeneralName()), + namedtype.OptionalNamedType('certDigestInfo', ObjectDigestInfo()) +) + + +class Target(univ.Choice): + pass + + +Target.componentType = namedtype.NamedTypes( + namedtype.NamedType('targetName', rfc3280.GeneralName().subtype( + implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0))), + namedtype.NamedType('targetGroup', rfc3280.GeneralName().subtype( + implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 1))), + namedtype.NamedType('targetCert', + TargetCert().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 2))) +) + + +class Targets(univ.SequenceOf): + pass + + +Targets.componentType = Target() + + +class ProxyInfo(univ.SequenceOf): + pass + + +ProxyInfo.componentType = Targets() + +id_at_role = _buildOid(rfc3280.id_at, 72) + +id_pe_aaControls = _buildOid(rfc3280.id_pe, 6) + +id_ce_targetInformation = _buildOid(rfc3280.id_ce, 55) + +id_pe_ac_auditIdentity = _buildOid(rfc3280.id_pe, 4) + + +class ClassList(univ.BitString): + pass + + +ClassList.namedValues = namedval.NamedValues( + ('unmarked', 0), + ('unclassified', 1), + ('restricted', 2), + ('confidential', 3), + ('secret', 4), + ('topSecret', 5) +) + + +class SecurityCategory(univ.Sequence): + pass + + +SecurityCategory.componentType = namedtype.NamedTypes( + namedtype.NamedType('type', univ.ObjectIdentifier().subtype( + implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0))), + namedtype.NamedType('value', univ.Any().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 1))) +) + + +class Clearance(univ.Sequence): + pass + + +Clearance.componentType = namedtype.NamedTypes( + namedtype.NamedType('policyId', univ.ObjectIdentifier().subtype( + implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0))), + namedtype.DefaultedNamedType('classList', + ClassList().subtype(implicitTag=tag.Tag(tag.tagClassContext, + tag.tagFormatSimple, 1)).subtype( + value="unclassified")), + namedtype.OptionalNamedType('securityCategories', univ.SetOf(componentType=SecurityCategory()).subtype( + implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 2))) +) + + +class AttCertVersion(univ.Integer): + pass + + +AttCertVersion.namedValues = namedval.NamedValues( + ('v2', 1) +) + +id_aca = _buildOid(rfc3280.id_pkix, 10) + +id_at_clearance = _buildOid(2, 5, 1, 5, 55) + + +class AttrSpec(univ.SequenceOf): + pass + + +AttrSpec.componentType = univ.ObjectIdentifier() + + +class AAControls(univ.Sequence): + pass + + +AAControls.componentType = namedtype.NamedTypes( + namedtype.OptionalNamedType('pathLenConstraint', + univ.Integer().subtype(subtypeSpec=constraint.ValueRangeConstraint(0, MAX))), + namedtype.OptionalNamedType('permittedAttrs', + AttrSpec().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0))), + namedtype.OptionalNamedType('excludedAttrs', + AttrSpec().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 1))), + namedtype.DefaultedNamedType('permitUnSpecified', univ.Boolean().subtype(value=1)) +) + + +class AttCertValidityPeriod(univ.Sequence): + pass + + +AttCertValidityPeriod.componentType = namedtype.NamedTypes( + namedtype.NamedType('notBeforeTime', useful.GeneralizedTime()), + namedtype.NamedType('notAfterTime', useful.GeneralizedTime()) +) + + +id_aca_authenticationInfo = _buildOid(id_aca, 1) + + +class V2Form(univ.Sequence): + pass + + +V2Form.componentType = namedtype.NamedTypes( + namedtype.OptionalNamedType('issuerName', rfc3280.GeneralNames()), + namedtype.OptionalNamedType('baseCertificateID', IssuerSerial().subtype( + implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 0))), + namedtype.OptionalNamedType('objectDigestInfo', ObjectDigestInfo().subtype( + implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 1))) +) + + +class AttCertIssuer(univ.Choice): + pass + + +AttCertIssuer.componentType = namedtype.NamedTypes( + namedtype.NamedType('v1Form', rfc3280.GeneralNames()), + namedtype.NamedType('v2Form', + V2Form().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 0))) +) + + +class Holder(univ.Sequence): + pass + + +Holder.componentType = namedtype.NamedTypes( + namedtype.OptionalNamedType('baseCertificateID', IssuerSerial().subtype( + implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 0))), + namedtype.OptionalNamedType('entityName', rfc3280.GeneralNames().subtype( + implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 1))), + namedtype.OptionalNamedType('objectDigestInfo', ObjectDigestInfo().subtype( + implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 2))) +) + + +class AttributeCertificateInfo(univ.Sequence): + pass + + +AttributeCertificateInfo.componentType = namedtype.NamedTypes( + namedtype.NamedType('version', AttCertVersion()), + namedtype.NamedType('holder', Holder()), + namedtype.NamedType('issuer', AttCertIssuer()), + namedtype.NamedType('signature', rfc3280.AlgorithmIdentifier()), + namedtype.NamedType('serialNumber', rfc3280.CertificateSerialNumber()), + namedtype.NamedType('attrCertValidityPeriod', AttCertValidityPeriod()), + namedtype.NamedType('attributes', univ.SequenceOf(componentType=rfc3280.Attribute())), + namedtype.OptionalNamedType('issuerUniqueID', rfc3280.UniqueIdentifier()), + namedtype.OptionalNamedType('extensions', rfc3280.Extensions()) +) + + +class AttributeCertificate(univ.Sequence): + pass + + +AttributeCertificate.componentType = namedtype.NamedTypes( + namedtype.NamedType('acinfo', AttributeCertificateInfo()), + namedtype.NamedType('signatureAlgorithm', rfc3280.AlgorithmIdentifier()), + namedtype.NamedType('signatureValue', univ.BitString()) +) + +id_mod = _buildOid(rfc3280.id_pkix, 0) + +id_mod_attribute_cert = _buildOid(id_mod, 12) + +id_aca_accessIdentity = _buildOid(id_aca, 2) + + +class RoleSyntax(univ.Sequence): + pass + + +RoleSyntax.componentType = namedtype.NamedTypes( + namedtype.OptionalNamedType('roleAuthority', rfc3280.GeneralNames().subtype( + implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0))), + namedtype.NamedType('roleName', + rfc3280.GeneralName().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 1))) +) + +id_aca_chargingIdentity = _buildOid(id_aca, 3) + + +class ACClearAttrs(univ.Sequence): + pass + + +ACClearAttrs.componentType = namedtype.NamedTypes( + namedtype.NamedType('acIssuer', rfc3280.GeneralName()), + namedtype.NamedType('acSerial', univ.Integer()), + namedtype.NamedType('attrs', univ.SequenceOf(componentType=rfc3280.Attribute())) +) + +id_aca_group = _buildOid(id_aca, 4) + +id_pe_ac_proxying = _buildOid(rfc3280.id_pe, 10) + + +class SvceAuthInfo(univ.Sequence): + pass + + +SvceAuthInfo.componentType = namedtype.NamedTypes( + namedtype.NamedType('service', rfc3280.GeneralName()), + namedtype.NamedType('ident', rfc3280.GeneralName()), + namedtype.OptionalNamedType('authInfo', univ.OctetString()) +) + + +class IetfAttrSyntax(univ.Sequence): + pass + + +IetfAttrSyntax.componentType = namedtype.NamedTypes( + namedtype.OptionalNamedType( + 'policyAuthority', rfc3280.GeneralNames().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0)) + ), + namedtype.NamedType( + 'values', univ.SequenceOf( + componentType=univ.Choice( + componentType=namedtype.NamedTypes( + namedtype.NamedType('octets', univ.OctetString()), + namedtype.NamedType('oid', univ.ObjectIdentifier()), + namedtype.NamedType('string', char.UTF8String()) + ) + ) + ) + ) +) + +id_aca_encAttrs = _buildOid(id_aca, 6) diff --git a/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/pyasn1_modules/rfc3779.py b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/pyasn1_modules/rfc3779.py new file mode 100644 index 0000000000000000000000000000000000000000..8e6eaa3e7b293d62a8a66077c7d7e64fa9157332 --- /dev/null +++ b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/pyasn1_modules/rfc3779.py @@ -0,0 +1,137 @@ +# +# This file is part of pyasn1-modules software. +# +# Created by Russ Housley with assistance from asn1ate v.0.6.0. +# Modified by Russ Housley to add maps for use with opentypes. +# +# Copyright (c) 2019, Vigil Security, LLC +# License: http://snmplabs.com/pyasn1/license.html +# +# X.509 Extensions for IP Addresses and AS Identifiers +# +# ASN.1 source from: +# https://www.rfc-editor.org/rfc/rfc3779.txt +# + +from pyasn1.type import constraint +from pyasn1.type import namedtype +from pyasn1.type import tag +from pyasn1.type import univ + +from pyasn1_modules import rfc5280 + + +# IP Address Delegation Extension + +id_pe_ipAddrBlocks = univ.ObjectIdentifier('1.3.6.1.5.5.7.1.7') + + +class IPAddress(univ.BitString): + pass + + +class IPAddressRange(univ.Sequence): + pass + +IPAddressRange.componentType = namedtype.NamedTypes( + namedtype.NamedType('min', IPAddress()), + namedtype.NamedType('max', IPAddress()) +) + + +class IPAddressOrRange(univ.Choice): + pass + +IPAddressOrRange.componentType = namedtype.NamedTypes( + namedtype.NamedType('addressPrefix', IPAddress()), + namedtype.NamedType('addressRange', IPAddressRange()) +) + + +class IPAddressChoice(univ.Choice): + pass + +IPAddressChoice.componentType = namedtype.NamedTypes( + namedtype.NamedType('inherit', univ.Null()), + namedtype.NamedType('addressesOrRanges', univ.SequenceOf( + componentType=IPAddressOrRange()) + ) +) + + +class IPAddressFamily(univ.Sequence): + pass + +IPAddressFamily.componentType = namedtype.NamedTypes( + namedtype.NamedType('addressFamily', univ.OctetString().subtype( + subtypeSpec=constraint.ValueSizeConstraint(2, 3))), + namedtype.NamedType('ipAddressChoice', IPAddressChoice()) +) + + +class IPAddrBlocks(univ.SequenceOf): + pass + +IPAddrBlocks.componentType = IPAddressFamily() + + +# Autonomous System Identifier Delegation Extension + +id_pe_autonomousSysIds = univ.ObjectIdentifier('1.3.6.1.5.5.7.1.8') + + +class ASId(univ.Integer): + pass + + +class ASRange(univ.Sequence): + pass + +ASRange.componentType = namedtype.NamedTypes( + namedtype.NamedType('min', ASId()), + namedtype.NamedType('max', ASId()) +) + + +class ASIdOrRange(univ.Choice): + pass + +ASIdOrRange.componentType = namedtype.NamedTypes( + namedtype.NamedType('id', ASId()), + namedtype.NamedType('range', ASRange()) +) + + +class ASIdentifierChoice(univ.Choice): + pass + +ASIdentifierChoice.componentType = namedtype.NamedTypes( + namedtype.NamedType('inherit', univ.Null()), + namedtype.NamedType('asIdsOrRanges', univ.SequenceOf( + componentType=ASIdOrRange()) + ) +) + + +class ASIdentifiers(univ.Sequence): + pass + +ASIdentifiers.componentType = namedtype.NamedTypes( + namedtype.OptionalNamedType('asnum', ASIdentifierChoice().subtype( + explicitTag=tag.Tag(tag.tagClassContext, + tag.tagFormatConstructed, 0))), + namedtype.OptionalNamedType('rdi', ASIdentifierChoice().subtype( + explicitTag=tag.Tag(tag.tagClassContext, + tag.tagFormatConstructed, 1))) +) + + +# Map of Certificate Extension OIDs to Extensions is added to the +# ones that are in rfc5280.py + +_certificateExtensionsMapUpdate = { + id_pe_ipAddrBlocks: IPAddrBlocks(), + id_pe_autonomousSysIds: ASIdentifiers(), +} + +rfc5280.certificateExtensionsMap.update(_certificateExtensionsMapUpdate) diff --git a/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/pyasn1_modules/rfc5917.py b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/pyasn1_modules/rfc5917.py new file mode 100644 index 0000000000000000000000000000000000000000..ed9af987db5e9250eb722e45d799994c0bce09a4 --- /dev/null +++ b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/pyasn1_modules/rfc5917.py @@ -0,0 +1,55 @@ +# +# This file is part of pyasn1-modules software. +# +# Created by Russ Housley. +# +# Copyright (c) 2019, Vigil Security, LLC +# License: http://snmplabs.com/pyasn1/license.html +# +# Clearance Sponsor Attribute +# +# ASN.1 source from: +# https://www.rfc-editor.org/rfc/rfc5917.txt +# https://www.rfc-editor.org/errata/eid4558 +# https://www.rfc-editor.org/errata/eid5883 +# + +from pyasn1.type import char +from pyasn1.type import constraint +from pyasn1.type import namedtype +from pyasn1.type import univ + +from pyasn1_modules import rfc5280 + + +# DirectoryString is the same as RFC 5280, except for two things: +# 1. the length is limited to 64; +# 2. only the 'utf8String' choice remains because the ASN.1 +# specification says: ( WITH COMPONENTS { utf8String PRESENT } ) + +class DirectoryString(univ.Choice): + componentType = namedtype.NamedTypes( + namedtype.NamedType('utf8String', char.UTF8String().subtype( + subtypeSpec=constraint.ValueSizeConstraint(1, 64))), + ) + + +# Clearance Sponsor Attribute + +id_clearanceSponsor = univ.ObjectIdentifier((2, 16, 840, 1, 101, 2, 1, 5, 68)) + +ub_clearance_sponsor = univ.Integer(64) + + +at_clearanceSponsor = rfc5280.Attribute() +at_clearanceSponsor['type'] = id_clearanceSponsor +at_clearanceSponsor['values'][0] = DirectoryString() + + +# Add to the map of Attribute Type OIDs to Attributes in rfc5280.py. + +_certificateAttributesMapUpdate = { + id_clearanceSponsor: DirectoryString(), +} + +rfc5280.certificateAttributesMap.update(_certificateAttributesMapUpdate) diff --git a/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/pyasn1_modules/rfc5934.py b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/pyasn1_modules/rfc5934.py new file mode 100644 index 0000000000000000000000000000000000000000..e3ad247aa07006fab85becd64fb34682cfebb402 --- /dev/null +++ b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/pyasn1_modules/rfc5934.py @@ -0,0 +1,786 @@ +# This file is being contributed to pyasn1-modules software. +# +# Created by Russ Housley with assistance from asn1ate v.0.6.0. +# +# Copyright (c) 2019, Vigil Security, LLC +# License: http://snmplabs.com/pyasn1/license.html +# +# Trust Anchor Format +# +# ASN.1 source from: +# https://www.rfc-editor.org/rfc/rfc5934.txt + +from pyasn1.type import univ, char, namedtype, namedval, tag, constraint, useful + +from pyasn1_modules import rfc2985 +from pyasn1_modules import rfc5280 +from pyasn1_modules import rfc5652 +from pyasn1_modules import rfc5914 + +MAX = float('inf') + + +def _OID(*components): + output = [] + for x in tuple(components): + if isinstance(x, univ.ObjectIdentifier): + output.extend(list(x)) + else: + output.append(int(x)) + return univ.ObjectIdentifier(output) + + +# Imports from RFC 2985 + +SingleAttribute = rfc2985.SingleAttribute + + +# Imports from RFC5914 + +CertPathControls = rfc5914.CertPathControls + +TrustAnchorChoice = rfc5914.TrustAnchorChoice + +TrustAnchorTitle = rfc5914.TrustAnchorTitle + + +# Imports from RFC 5280 + +AlgorithmIdentifier = rfc5280.AlgorithmIdentifier + +AnotherName = rfc5280.AnotherName + +Attribute = rfc5280.Attribute + +Certificate = rfc5280.Certificate + +CertificateSerialNumber = rfc5280.CertificateSerialNumber + +Extension = rfc5280.Extension + +Extensions = rfc5280.Extensions + +KeyIdentifier = rfc5280.KeyIdentifier + +Name = rfc5280.Name + +SubjectPublicKeyInfo = rfc5280.SubjectPublicKeyInfo + +TBSCertificate = rfc5280.TBSCertificate + +Validity = rfc5280.Validity + + +# Object Identifier Arc for TAMP Message Content Types + +id_tamp = univ.ObjectIdentifier('2.16.840.1.101.2.1.2.77') + + +# TAMP Status Query Message + +id_ct_TAMP_statusQuery = _OID(id_tamp, 1) + + +class TAMPVersion(univ.Integer): + pass + +TAMPVersion.namedValues = namedval.NamedValues( + ('v1', 1), + ('v2', 2) +) + + +class TerseOrVerbose(univ.Enumerated): + pass + +TerseOrVerbose.namedValues = namedval.NamedValues( + ('terse', 1), + ('verbose', 2) +) + + +class HardwareSerialEntry(univ.Choice): + pass + +HardwareSerialEntry.componentType = namedtype.NamedTypes( + namedtype.NamedType('all', univ.Null()), + namedtype.NamedType('single', univ.OctetString()), + namedtype.NamedType('block', univ.Sequence(componentType=namedtype.NamedTypes( + namedtype.NamedType('low', univ.OctetString()), + namedtype.NamedType('high', univ.OctetString()) + )) + ) +) + + +class HardwareModules(univ.Sequence): + pass + +HardwareModules.componentType = namedtype.NamedTypes( + namedtype.NamedType('hwType', univ.ObjectIdentifier()), + namedtype.NamedType('hwSerialEntries', univ.SequenceOf( + componentType=HardwareSerialEntry()).subtype( + subtypeSpec=constraint.ValueSizeConstraint(1, MAX))) +) + + +class HardwareModuleIdentifierList(univ.SequenceOf): + pass + +HardwareModuleIdentifierList.componentType = HardwareModules() +HardwareModuleIdentifierList.subtypeSpec=constraint.ValueSizeConstraint(1, MAX) + + +class Community(univ.ObjectIdentifier): + pass + + +class CommunityIdentifierList(univ.SequenceOf): + pass + +CommunityIdentifierList.componentType = Community() +CommunityIdentifierList.subtypeSpec=constraint.ValueSizeConstraint(0, MAX) + + +class TargetIdentifier(univ.Choice): + pass + +TargetIdentifier.componentType = namedtype.NamedTypes( + namedtype.NamedType('hwModules', HardwareModuleIdentifierList().subtype( + implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 1))), + namedtype.NamedType('communities', CommunityIdentifierList().subtype( + implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 2))), + namedtype.NamedType('allModules', univ.Null().subtype( + implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 3))), + namedtype.NamedType('uri', char.IA5String().subtype( + implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 4))), + namedtype.NamedType('otherName', AnotherName().subtype( + implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 5))) +) + + +class SeqNumber(univ.Integer): + pass + +SeqNumber.subtypeSpec = constraint.ValueRangeConstraint(0, 9223372036854775807) + + +class TAMPMsgRef(univ.Sequence): + pass + +TAMPMsgRef.componentType = namedtype.NamedTypes( + namedtype.NamedType('target', TargetIdentifier()), + namedtype.NamedType('seqNum', SeqNumber()) +) + + +class TAMPStatusQuery(univ.Sequence): + pass + +TAMPStatusQuery.componentType = namedtype.NamedTypes( + namedtype.DefaultedNamedType('version', TAMPVersion().subtype( + implicitTag=tag.Tag(tag.tagClassContext, + tag.tagFormatSimple, 0)).subtype(value='v2')), + namedtype.DefaultedNamedType('terse', TerseOrVerbose().subtype( + implicitTag=tag.Tag(tag.tagClassContext, + tag.tagFormatSimple, 1)).subtype(value='verbose')), + namedtype.NamedType('query', TAMPMsgRef()) +) + + +tamp_status_query = rfc5652.ContentInfo() +tamp_status_query['contentType'] = id_ct_TAMP_statusQuery +tamp_status_query['content'] = TAMPStatusQuery() + + +# TAMP Status Response Message + +id_ct_TAMP_statusResponse = _OID(id_tamp, 2) + + +class KeyIdentifiers(univ.SequenceOf): + pass + +KeyIdentifiers.componentType = KeyIdentifier() +KeyIdentifiers.subtypeSpec=constraint.ValueSizeConstraint(1, MAX) + + +class TrustAnchorChoiceList(univ.SequenceOf): + pass + +TrustAnchorChoiceList.componentType = TrustAnchorChoice() +TrustAnchorChoiceList.subtypeSpec=constraint.ValueSizeConstraint(1, MAX) + + +class TAMPSequenceNumber(univ.Sequence): + pass + +TAMPSequenceNumber.componentType = namedtype.NamedTypes( + namedtype.NamedType('keyId', KeyIdentifier()), + namedtype.NamedType('seqNumber', SeqNumber()) +) + + +class TAMPSequenceNumbers(univ.SequenceOf): + pass + +TAMPSequenceNumbers.componentType = TAMPSequenceNumber() +TAMPSequenceNumbers.subtypeSpec=constraint.ValueSizeConstraint(1, MAX) + + +class TerseStatusResponse(univ.Sequence): + pass + +TerseStatusResponse.componentType = namedtype.NamedTypes( + namedtype.NamedType('taKeyIds', KeyIdentifiers()), + namedtype.OptionalNamedType('communities', CommunityIdentifierList()) +) + + +class VerboseStatusResponse(univ.Sequence): + pass + +VerboseStatusResponse.componentType = namedtype.NamedTypes( + namedtype.NamedType('taInfo', TrustAnchorChoiceList()), + namedtype.OptionalNamedType('continPubKeyDecryptAlg', + AlgorithmIdentifier().subtype(implicitTag=tag.Tag( + tag.tagClassContext, tag.tagFormatSimple, 0))), + namedtype.OptionalNamedType('communities', + CommunityIdentifierList().subtype(implicitTag=tag.Tag( + tag.tagClassContext, tag.tagFormatSimple, 1))), + namedtype.OptionalNamedType('tampSeqNumbers', + TAMPSequenceNumbers().subtype(implicitTag=tag.Tag( + tag.tagClassContext, tag.tagFormatSimple, 2))) +) + + +class StatusResponse(univ.Choice): + pass + +StatusResponse.componentType = namedtype.NamedTypes( + namedtype.NamedType('terseResponse', TerseStatusResponse().subtype( + implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 0))), + namedtype.NamedType('verboseResponse', VerboseStatusResponse().subtype( + implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 1))) +) + + +class TAMPStatusResponse(univ.Sequence): + pass + +TAMPStatusResponse.componentType = namedtype.NamedTypes( + namedtype.DefaultedNamedType('version', TAMPVersion().subtype( + implicitTag=tag.Tag(tag.tagClassContext, + tag.tagFormatSimple, 0)).subtype(value='v2')), + namedtype.NamedType('query', TAMPMsgRef()), + namedtype.NamedType('response', StatusResponse()), + namedtype.DefaultedNamedType('usesApex', univ.Boolean().subtype(value=1)) +) + + +tamp_status_response = rfc5652.ContentInfo() +tamp_status_response['contentType'] = id_ct_TAMP_statusResponse +tamp_status_response['content'] = TAMPStatusResponse() + + +# Trust Anchor Update Message + +id_ct_TAMP_update = _OID(id_tamp, 3) + + +class TBSCertificateChangeInfo(univ.Sequence): + pass + +TBSCertificateChangeInfo.componentType = namedtype.NamedTypes( + namedtype.OptionalNamedType('serialNumber', CertificateSerialNumber()), + namedtype.OptionalNamedType('signature', AlgorithmIdentifier().subtype( + implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0))), + namedtype.OptionalNamedType('issuer', Name().subtype(implicitTag=tag.Tag( + tag.tagClassContext, tag.tagFormatSimple, 1))), + namedtype.OptionalNamedType('validity', Validity().subtype( + implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 2))), + namedtype.OptionalNamedType('subject', Name().subtype(implicitTag=tag.Tag( + tag.tagClassContext, tag.tagFormatSimple, 3))), + namedtype.NamedType('subjectPublicKeyInfo', SubjectPublicKeyInfo().subtype( + implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 4))), + namedtype.OptionalNamedType('exts', Extensions().subtype(explicitTag=tag.Tag( + tag.tagClassContext, tag.tagFormatSimple, 5))) +) + + +class TrustAnchorChangeInfo(univ.Sequence): + pass + +TrustAnchorChangeInfo.componentType = namedtype.NamedTypes( + namedtype.NamedType('pubKey', SubjectPublicKeyInfo()), + namedtype.OptionalNamedType('keyId', KeyIdentifier()), + namedtype.OptionalNamedType('taTitle', TrustAnchorTitle()), + namedtype.OptionalNamedType('certPath', CertPathControls()), + namedtype.OptionalNamedType('exts', Extensions().subtype( + implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 1))) +) + + +class TrustAnchorChangeInfoChoice(univ.Choice): + pass + +TrustAnchorChangeInfoChoice.componentType = namedtype.NamedTypes( + namedtype.NamedType('tbsCertChange', TBSCertificateChangeInfo().subtype( + implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 0))), + namedtype.NamedType('taChange', TrustAnchorChangeInfo().subtype( + implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 1))) +) + + +class TrustAnchorUpdate(univ.Choice): + pass + +TrustAnchorUpdate.componentType = namedtype.NamedTypes( + namedtype.NamedType('add', TrustAnchorChoice().subtype( + implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 1))), + namedtype.NamedType('remove', SubjectPublicKeyInfo().subtype( + implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 2))), + namedtype.NamedType('change', TrustAnchorChangeInfoChoice().subtype( + explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 3))) +) + + +class TAMPUpdate(univ.Sequence): + pass + +TAMPUpdate.componentType = namedtype.NamedTypes( + namedtype.DefaultedNamedType('version', + TAMPVersion().subtype(implicitTag=tag.Tag(tag.tagClassContext, + tag.tagFormatSimple, 0)).subtype(value='v2')), + namedtype.DefaultedNamedType('terse', + TerseOrVerbose().subtype(implicitTag=tag.Tag(tag.tagClassContext, + tag.tagFormatSimple, 1)).subtype(value='verbose')), + namedtype.NamedType('msgRef', TAMPMsgRef()), + namedtype.NamedType('updates', + univ.SequenceOf(componentType=TrustAnchorUpdate()).subtype( + subtypeSpec=constraint.ValueSizeConstraint(1, MAX))), + namedtype.OptionalNamedType('tampSeqNumbers', + TAMPSequenceNumbers().subtype(implicitTag=tag.Tag( + tag.tagClassContext, tag.tagFormatSimple, 2))) +) + + +tamp_update = rfc5652.ContentInfo() +tamp_update['contentType'] = id_ct_TAMP_update +tamp_update['content'] = TAMPUpdate() + + +# Trust Anchor Update Confirm Message + +id_ct_TAMP_updateConfirm = _OID(id_tamp, 4) + + +class StatusCode(univ.Enumerated): + pass + +StatusCode.namedValues = namedval.NamedValues( + ('success', 0), + ('decodeFailure', 1), + ('badContentInfo', 2), + ('badSignedData', 3), + ('badEncapContent', 4), + ('badCertificate', 5), + ('badSignerInfo', 6), + ('badSignedAttrs', 7), + ('badUnsignedAttrs', 8), + ('missingContent', 9), + ('noTrustAnchor', 10), + ('notAuthorized', 11), + ('badDigestAlgorithm', 12), + ('badSignatureAlgorithm', 13), + ('unsupportedKeySize', 14), + ('unsupportedParameters', 15), + ('signatureFailure', 16), + ('insufficientMemory', 17), + ('unsupportedTAMPMsgType', 18), + ('apexTAMPAnchor', 19), + ('improperTAAddition', 20), + ('seqNumFailure', 21), + ('contingencyPublicKeyDecrypt', 22), + ('incorrectTarget', 23), + ('communityUpdateFailed', 24), + ('trustAnchorNotFound', 25), + ('unsupportedTAAlgorithm', 26), + ('unsupportedTAKeySize', 27), + ('unsupportedContinPubKeyDecryptAlg', 28), + ('missingSignature', 29), + ('resourcesBusy', 30), + ('versionNumberMismatch', 31), + ('missingPolicySet', 32), + ('revokedCertificate', 33), + ('unsupportedTrustAnchorFormat', 34), + ('improperTAChange', 35), + ('malformed', 36), + ('cmsError', 37), + ('unsupportedTargetIdentifier', 38), + ('other', 127) +) + + +class StatusCodeList(univ.SequenceOf): + pass + +StatusCodeList.componentType = StatusCode() +StatusCodeList.subtypeSpec=constraint.ValueSizeConstraint(1, MAX) + + +class TerseUpdateConfirm(StatusCodeList): + pass + + +class VerboseUpdateConfirm(univ.Sequence): + pass + +VerboseUpdateConfirm.componentType = namedtype.NamedTypes( + namedtype.NamedType('status', StatusCodeList()), + namedtype.NamedType('taInfo', TrustAnchorChoiceList()), + namedtype.OptionalNamedType('tampSeqNumbers', TAMPSequenceNumbers()), + namedtype.DefaultedNamedType('usesApex', univ.Boolean().subtype(value=1)) +) + + +class UpdateConfirm(univ.Choice): + pass + +UpdateConfirm.componentType = namedtype.NamedTypes( + namedtype.NamedType('terseConfirm', TerseUpdateConfirm().subtype( + implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0))), + namedtype.NamedType('verboseConfirm', VerboseUpdateConfirm().subtype( + implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 1))) +) + + +class TAMPUpdateConfirm(univ.Sequence): + pass + +TAMPUpdateConfirm.componentType = namedtype.NamedTypes( + namedtype.DefaultedNamedType('version', TAMPVersion().subtype( + implicitTag=tag.Tag(tag.tagClassContext, + tag.tagFormatSimple, 0)).subtype(value='v2')), + namedtype.NamedType('update', TAMPMsgRef()), + namedtype.NamedType('confirm', UpdateConfirm()) +) + + +tamp_update_confirm = rfc5652.ContentInfo() +tamp_update_confirm['contentType'] = id_ct_TAMP_updateConfirm +tamp_update_confirm['content'] = TAMPUpdateConfirm() + + +# Apex Trust Anchor Update Message + +id_ct_TAMP_apexUpdate = _OID(id_tamp, 5) + + +class TAMPApexUpdate(univ.Sequence): + pass + +TAMPApexUpdate.componentType = namedtype.NamedTypes( + namedtype.DefaultedNamedType('version', + TAMPVersion().subtype(implicitTag=tag.Tag(tag.tagClassContext, + tag.tagFormatSimple, 0)).subtype(value='v2')), + namedtype.DefaultedNamedType('terse', + TerseOrVerbose().subtype(implicitTag=tag.Tag(tag.tagClassContext, + tag.tagFormatSimple, 1)).subtype(value='verbose')), + namedtype.NamedType('msgRef', TAMPMsgRef()), + namedtype.NamedType('clearTrustAnchors', univ.Boolean()), + namedtype.NamedType('clearCommunities', univ.Boolean()), + namedtype.OptionalNamedType('seqNumber', SeqNumber()), + namedtype.NamedType('apexTA', TrustAnchorChoice()) +) + + +tamp_apex_update = rfc5652.ContentInfo() +tamp_apex_update['contentType'] = id_ct_TAMP_apexUpdate +tamp_apex_update['content'] = TAMPApexUpdate() + + +# Apex Trust Anchor Update Confirm Message + +id_ct_TAMP_apexUpdateConfirm = _OID(id_tamp, 6) + + +class TerseApexUpdateConfirm(StatusCode): + pass + + +class VerboseApexUpdateConfirm(univ.Sequence): + pass + +VerboseApexUpdateConfirm.componentType = namedtype.NamedTypes( + namedtype.NamedType('status', StatusCode()), + namedtype.NamedType('taInfo', TrustAnchorChoiceList()), + namedtype.OptionalNamedType('communities', + CommunityIdentifierList().subtype(implicitTag=tag.Tag(tag.tagClassContext, + tag.tagFormatSimple, 0))), + namedtype.OptionalNamedType('tampSeqNumbers', + TAMPSequenceNumbers().subtype(implicitTag=tag.Tag(tag.tagClassContext, + tag.tagFormatSimple, 1))) +) + + +class ApexUpdateConfirm(univ.Choice): + pass + +ApexUpdateConfirm.componentType = namedtype.NamedTypes( + namedtype.NamedType('terseApexConfirm', + TerseApexUpdateConfirm().subtype(implicitTag=tag.Tag(tag.tagClassContext, + tag.tagFormatSimple, 0))), + namedtype.NamedType('verboseApexConfirm', + VerboseApexUpdateConfirm().subtype(implicitTag=tag.Tag(tag.tagClassContext, + tag.tagFormatConstructed, 1))) +) + + +class TAMPApexUpdateConfirm(univ.Sequence): + pass + +TAMPApexUpdateConfirm.componentType = namedtype.NamedTypes( + namedtype.DefaultedNamedType('version', + TAMPVersion().subtype(implicitTag=tag.Tag(tag.tagClassContext, + tag.tagFormatSimple, 0)).subtype(value='v2')), + namedtype.NamedType('apexReplace', TAMPMsgRef()), + namedtype.NamedType('apexConfirm', ApexUpdateConfirm()) +) + + +tamp_apex_update_confirm = rfc5652.ContentInfo() +tamp_apex_update_confirm['contentType'] = id_ct_TAMP_apexUpdateConfirm +tamp_apex_update_confirm['content'] = TAMPApexUpdateConfirm() + + +# Community Update Message + +id_ct_TAMP_communityUpdate = _OID(id_tamp, 7) + + +class CommunityUpdates(univ.Sequence): + pass + +CommunityUpdates.componentType = namedtype.NamedTypes( + namedtype.OptionalNamedType('remove', + CommunityIdentifierList().subtype(implicitTag=tag.Tag(tag.tagClassContext, + tag.tagFormatSimple, 1))), + namedtype.OptionalNamedType('add', + CommunityIdentifierList().subtype(implicitTag=tag.Tag(tag.tagClassContext, + tag.tagFormatSimple, 2))) +) + + +class TAMPCommunityUpdate(univ.Sequence): + pass + +TAMPCommunityUpdate.componentType = namedtype.NamedTypes( + namedtype.DefaultedNamedType('version', + TAMPVersion().subtype(implicitTag=tag.Tag(tag.tagClassContext, + tag.tagFormatSimple, 0)).subtype(value='v2')), + namedtype.DefaultedNamedType('terse', + TerseOrVerbose().subtype(implicitTag=tag.Tag(tag.tagClassContext, + tag.tagFormatSimple, 1)).subtype(value='verbose')), + namedtype.NamedType('msgRef', TAMPMsgRef()), + namedtype.NamedType('updates', CommunityUpdates()) +) + + +tamp_community_update = rfc5652.ContentInfo() +tamp_community_update['contentType'] = id_ct_TAMP_communityUpdate +tamp_community_update['content'] = TAMPCommunityUpdate() + + +# Community Update Confirm Message + +id_ct_TAMP_communityUpdateConfirm = _OID(id_tamp, 8) + + +class TerseCommunityConfirm(StatusCode): + pass + + +class VerboseCommunityConfirm(univ.Sequence): + pass + +VerboseCommunityConfirm.componentType = namedtype.NamedTypes( + namedtype.NamedType('status', StatusCode()), + namedtype.OptionalNamedType('communities', CommunityIdentifierList()) +) + + +class CommunityConfirm(univ.Choice): + pass + +CommunityConfirm.componentType = namedtype.NamedTypes( + namedtype.NamedType('terseCommConfirm', + TerseCommunityConfirm().subtype(implicitTag=tag.Tag(tag.tagClassContext, + tag.tagFormatSimple, 0))), + namedtype.NamedType('verboseCommConfirm', + VerboseCommunityConfirm().subtype(implicitTag=tag.Tag(tag.tagClassContext, + tag.tagFormatConstructed, 1))) +) + + +class TAMPCommunityUpdateConfirm(univ.Sequence): + pass + +TAMPCommunityUpdateConfirm.componentType = namedtype.NamedTypes( + namedtype.DefaultedNamedType('version', + TAMPVersion().subtype(implicitTag=tag.Tag(tag.tagClassContext, + tag.tagFormatSimple, 0)).subtype(value='v2')), + namedtype.NamedType('update', TAMPMsgRef()), + namedtype.NamedType('commConfirm', CommunityConfirm()) +) + + +tamp_community_update_confirm = rfc5652.ContentInfo() +tamp_community_update_confirm['contentType'] = id_ct_TAMP_communityUpdateConfirm +tamp_community_update_confirm['content'] = TAMPCommunityUpdateConfirm() + + +# Sequence Number Adjust Message + +id_ct_TAMP_seqNumAdjust = _OID(id_tamp, 10) + + + +class SequenceNumberAdjust(univ.Sequence): + pass + +SequenceNumberAdjust.componentType = namedtype.NamedTypes( + namedtype.DefaultedNamedType('version', + TAMPVersion().subtype(implicitTag=tag.Tag(tag.tagClassContext, + tag.tagFormatSimple, 0)).subtype(value='v2')), + namedtype.NamedType('msgRef', TAMPMsgRef()) +) + + +tamp_sequence_number_adjust = rfc5652.ContentInfo() +tamp_sequence_number_adjust['contentType'] = id_ct_TAMP_seqNumAdjust +tamp_sequence_number_adjust['content'] = SequenceNumberAdjust() + + +# Sequence Number Adjust Confirm Message + +id_ct_TAMP_seqNumAdjustConfirm = _OID(id_tamp, 11) + + +class SequenceNumberAdjustConfirm(univ.Sequence): + pass + +SequenceNumberAdjustConfirm.componentType = namedtype.NamedTypes( + namedtype.DefaultedNamedType('version', + TAMPVersion().subtype(implicitTag=tag.Tag(tag.tagClassContext, + tag.tagFormatSimple, 0)).subtype(value='v2')), + namedtype.NamedType('adjust', TAMPMsgRef()), + namedtype.NamedType('status', StatusCode()) +) + + +tamp_sequence_number_adjust_confirm = rfc5652.ContentInfo() +tamp_sequence_number_adjust_confirm['contentType'] = id_ct_TAMP_seqNumAdjustConfirm +tamp_sequence_number_adjust_confirm['content'] = SequenceNumberAdjustConfirm() + + +# TAMP Error Message + +id_ct_TAMP_error = _OID(id_tamp, 9) + + +class TAMPError(univ.Sequence): + pass + +TAMPError.componentType = namedtype.NamedTypes( + namedtype.DefaultedNamedType('version', + TAMPVersion().subtype(implicitTag=tag.Tag(tag.tagClassContext, + tag.tagFormatSimple, 0)).subtype(value='v2')), + namedtype.NamedType('msgType', univ.ObjectIdentifier()), + namedtype.NamedType('status', StatusCode()), + namedtype.OptionalNamedType('msgRef', TAMPMsgRef()) +) + + +tamp_error = rfc5652.ContentInfo() +tamp_error['contentType'] = id_ct_TAMP_error +tamp_error['content'] = TAMPError() + + +# Object Identifier Arc for Attributes + +id_attributes = univ.ObjectIdentifier('2.16.840.1.101.2.1.5') + + +# contingency-public-key-decrypt-key unsigned attribute + +id_aa_TAMP_contingencyPublicKeyDecryptKey = _OID(id_attributes, 63) + + +class PlaintextSymmetricKey(univ.OctetString): + pass + + +contingency_public_key_decrypt_key = Attribute() +contingency_public_key_decrypt_key['type'] = id_aa_TAMP_contingencyPublicKeyDecryptKey +contingency_public_key_decrypt_key['values'][0] = PlaintextSymmetricKey() + + +# id-pe-wrappedApexContinKey extension + +id_pe_wrappedApexContinKey =univ.ObjectIdentifier('1.3.6.1.5.5.7.1.20') + + +class ApexContingencyKey(univ.Sequence): + pass + +ApexContingencyKey.componentType = namedtype.NamedTypes( + namedtype.NamedType('wrapAlgorithm', AlgorithmIdentifier()), + namedtype.NamedType('wrappedContinPubKey', univ.OctetString()) +) + + +wrappedApexContinKey = Extension() +wrappedApexContinKey['extnID'] = id_pe_wrappedApexContinKey +wrappedApexContinKey['critical'] = 0 +wrappedApexContinKey['extnValue'] = univ.OctetString() + + +# Add to the map of CMS Content Type OIDs to Content Types in +# rfc5652.py + +_cmsContentTypesMapUpdate = { + id_ct_TAMP_statusQuery: TAMPStatusQuery(), + id_ct_TAMP_statusResponse: TAMPStatusResponse(), + id_ct_TAMP_update: TAMPUpdate(), + id_ct_TAMP_updateConfirm: TAMPUpdateConfirm(), + id_ct_TAMP_apexUpdate: TAMPApexUpdate(), + id_ct_TAMP_apexUpdateConfirm: TAMPApexUpdateConfirm(), + id_ct_TAMP_communityUpdate: TAMPCommunityUpdate(), + id_ct_TAMP_communityUpdateConfirm: TAMPCommunityUpdateConfirm(), + id_ct_TAMP_seqNumAdjust: SequenceNumberAdjust(), + id_ct_TAMP_seqNumAdjustConfirm: SequenceNumberAdjustConfirm(), + id_ct_TAMP_error: TAMPError(), +} + +rfc5652.cmsContentTypesMap.update(_cmsContentTypesMapUpdate) + + +# Add to the map of CMS Attribute OIDs to Attribute Values in +# rfc5652.py + +_cmsAttributesMapUpdate = { + id_aa_TAMP_contingencyPublicKeyDecryptKey: PlaintextSymmetricKey(), +} + +rfc5652.cmsAttributesMap.update(_cmsAttributesMapUpdate) + + +# Add to the map of Certificate Extension OIDs to Extensions in +# rfc5280.py + +_certificateExtensionsMap = { + id_pe_wrappedApexContinKey: ApexContingencyKey(), +} + +rfc5280.certificateExtensionsMap.update(_certificateExtensionsMap) diff --git a/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/pyasn1_modules/rfc5940.py b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/pyasn1_modules/rfc5940.py new file mode 100644 index 0000000000000000000000000000000000000000..e105923358b795b1547a1fae4aa29fffbbd80317 --- /dev/null +++ b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/pyasn1_modules/rfc5940.py @@ -0,0 +1,59 @@ +# +# This file is part of pyasn1-modules software. +# +# Created by Russ Housley with assistance from asn1ate v.0.6.0. +# Modified by Russ Housley to add map for use with opentypes. +# +# Copyright (c) 2019, Vigil Security, LLC +# License: http://snmplabs.com/pyasn1/license.html +# +# Additional CMS Revocation Information Choices +# +# ASN.1 source from: +# https://www.rfc-editor.org/rfc/rfc5940.txt +# + +from pyasn1.type import namedtype +from pyasn1.type import tag +from pyasn1.type import univ + +from pyasn1_modules import rfc2560 +from pyasn1_modules import rfc5652 + + +# RevocationInfoChoice for OCSP response: +# The OID is included in otherRevInfoFormat, and +# signed OCSPResponse is included in otherRevInfo + +id_ri_ocsp_response = univ.ObjectIdentifier('1.3.6.1.5.5.7.16.2') + +OCSPResponse = rfc2560.OCSPResponse + + +# RevocationInfoChoice for SCVP request/response: +# The OID is included in otherRevInfoFormat, and +# SCVPReqRes is included in otherRevInfo + +id_ri_scvp = univ.ObjectIdentifier('1.3.6.1.5.5.7.16.4') + +ContentInfo = rfc5652.ContentInfo + +class SCVPReqRes(univ.Sequence): + pass + +SCVPReqRes.componentType = namedtype.NamedTypes( + namedtype.OptionalNamedType('request', + ContentInfo().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0))), + namedtype.NamedType('response', ContentInfo()) +) + + +# Map of Revocation Info Format OIDs to Revocation Info Format +# is added to the ones that are in rfc5652.py + +_otherRevInfoFormatMapUpdate = { + id_ri_ocsp_response: OCSPResponse(), + id_ri_scvp: SCVPReqRes(), +} + +rfc5652.otherRevInfoFormatMap.update(_otherRevInfoFormatMapUpdate) diff --git a/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/pyasn1_modules/rfc6031.py b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/pyasn1_modules/rfc6031.py new file mode 100644 index 0000000000000000000000000000000000000000..6e1bb2261d57cc3f537814493a8a0c3c1b18ba29 --- /dev/null +++ b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/pyasn1_modules/rfc6031.py @@ -0,0 +1,469 @@ +# +# This file is part of pyasn1-modules software. +# +# Created by Russ Housley with assistance from asn1ate v.0.6.0. +# +# Copyright (c) 2019, Vigil Security, LLC +# License: http://snmplabs.com/pyasn1/license.html +# +# CMS Symmetric Key Package Content Type +# +# ASN.1 source from: +# https://www.rfc-editor.org/rfc/rfc6031.txt +# + +from pyasn1.type import char +from pyasn1.type import constraint +from pyasn1.type import namedtype +from pyasn1.type import namedval +from pyasn1.type import opentype +from pyasn1.type import tag +from pyasn1.type import univ +from pyasn1.type import useful + +from pyasn1_modules import rfc5652 +from pyasn1_modules import rfc6019 + + +def _OID(*components): + output = [] + for x in tuple(components): + if isinstance(x, univ.ObjectIdentifier): + output.extend(list(x)) + else: + output.append(int(x)) + return univ.ObjectIdentifier(output) + + +MAX = float('inf') + +id_pskc = univ.ObjectIdentifier('1.2.840.113549.1.9.16.12') + + +# Symmetric Key Package Attributes + +id_pskc_manufacturer = _OID(id_pskc, 1) + +class at_pskc_manufacturer(char.UTF8String): + pass + + +id_pskc_serialNo = _OID(id_pskc, 2) + +class at_pskc_serialNo(char.UTF8String): + pass + + +id_pskc_model = _OID(id_pskc, 3) + +class at_pskc_model(char.UTF8String): + pass + + +id_pskc_issueNo = _OID(id_pskc, 4) + +class at_pskc_issueNo(char.UTF8String): + pass + + +id_pskc_deviceBinding = _OID(id_pskc, 5) + +class at_pskc_deviceBinding(char.UTF8String): + pass + + +id_pskc_deviceStartDate = _OID(id_pskc, 6) + +class at_pskc_deviceStartDate(useful.GeneralizedTime): + pass + + +id_pskc_deviceExpiryDate = _OID(id_pskc, 7) + +class at_pskc_deviceExpiryDate(useful.GeneralizedTime): + pass + + +id_pskc_moduleId = _OID(id_pskc, 8) + +class at_pskc_moduleId(char.UTF8String): + pass + + +id_pskc_deviceUserId = _OID(id_pskc, 26) + +class at_pskc_deviceUserId(char.UTF8String): + pass + + +# Symmetric Key Attributes + +id_pskc_keyId = _OID(id_pskc, 9) + +class at_pskc_keyUserId(char.UTF8String): + pass + + +id_pskc_algorithm = _OID(id_pskc, 10) + +class at_pskc_algorithm(char.UTF8String): + pass + + +id_pskc_issuer = _OID(id_pskc, 11) + +class at_pskc_issuer(char.UTF8String): + pass + + +id_pskc_keyProfileId = _OID(id_pskc, 12) + +class at_pskc_keyProfileId(char.UTF8String): + pass + + +id_pskc_keyReference = _OID(id_pskc, 13) + +class at_pskc_keyReference(char.UTF8String): + pass + + +id_pskc_friendlyName = _OID(id_pskc, 14) + +class FriendlyName(univ.Sequence): + pass + +FriendlyName.componentType = namedtype.NamedTypes( + namedtype.NamedType('friendlyName', char.UTF8String()), + namedtype.OptionalNamedType('friendlyNameLangTag', char.UTF8String()) +) + +class at_pskc_friendlyName(FriendlyName): + pass + + +id_pskc_algorithmParameters = _OID(id_pskc, 15) + +class Encoding(char.UTF8String): + pass + +Encoding.namedValues = namedval.NamedValues( + ('dec', "DECIMAL"), + ('hex', "HEXADECIMAL"), + ('alpha', "ALPHANUMERIC"), + ('b64', "BASE64"), + ('bin', "BINARY") +) + +Encoding.subtypeSpec = constraint.SingleValueConstraint( + "DECIMAL", "HEXADECIMAL", "ALPHANUMERIC", "BASE64", "BINARY" ) + +class ChallengeFormat(univ.Sequence): + pass + +ChallengeFormat.componentType = namedtype.NamedTypes( + namedtype.NamedType('encoding', Encoding()), + namedtype.DefaultedNamedType('checkDigit', + univ.Boolean().subtype(value=0)), + namedtype.NamedType('min', univ.Integer().subtype( + subtypeSpec=constraint.ValueRangeConstraint(0, MAX))), + namedtype.NamedType('max', univ.Integer().subtype( + subtypeSpec=constraint.ValueRangeConstraint(0, MAX))) +) + +class ResponseFormat(univ.Sequence): + pass + +ResponseFormat.componentType = namedtype.NamedTypes( + namedtype.NamedType('encoding', Encoding()), + namedtype.NamedType('length', univ.Integer().subtype( + subtypeSpec=constraint.ValueRangeConstraint(0, MAX))), + namedtype.DefaultedNamedType('checkDigit', + univ.Boolean().subtype(value=0)) +) + +class PSKCAlgorithmParameters(univ.Choice): + pass + +PSKCAlgorithmParameters.componentType = namedtype.NamedTypes( + namedtype.NamedType('suite', char.UTF8String()), + namedtype.NamedType('challengeFormat', ChallengeFormat().subtype( + implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 0))), + namedtype.NamedType('responseFormat', ResponseFormat().subtype( + implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 1))) +) + +class at_pskc_algorithmParameters(PSKCAlgorithmParameters): + pass + + +id_pskc_counter = _OID(id_pskc, 16) + +class at_pskc_counter(univ.Integer): + pass + +at_pskc_counter.subtypeSpec = constraint.ValueRangeConstraint(0, MAX) + + +id_pskc_time = _OID(id_pskc, 17) + +class at_pskc_time(rfc6019.BinaryTime): + pass + + +id_pskc_timeInterval = _OID(id_pskc, 18) + +class at_pskc_timeInterval(univ.Integer): + pass + +at_pskc_timeInterval.subtypeSpec = constraint.ValueRangeConstraint(0, MAX) + + +id_pskc_timeDrift = _OID(id_pskc, 19) + +class at_pskc_timeDrift(univ.Integer): + pass + +at_pskc_timeDrift.subtypeSpec = constraint.ValueRangeConstraint(0, MAX) + + +id_pskc_valueMAC = _OID(id_pskc, 20) + +class ValueMac(univ.Sequence): + pass + +ValueMac.componentType = namedtype.NamedTypes( + namedtype.NamedType('macAlgorithm', char.UTF8String()), + namedtype.NamedType('mac', char.UTF8String()) +) + +class at_pskc_valueMAC(ValueMac): + pass + + +id_pskc_keyUserId = _OID(id_pskc, 27) + +class at_pskc_keyId(char.UTF8String): + pass + + +id_pskc_keyStartDate = _OID(id_pskc, 21) + +class at_pskc_keyStartDate(useful.GeneralizedTime): + pass + + +id_pskc_keyExpiryDate = _OID(id_pskc, 22) + +class at_pskc_keyExpiryDate(useful.GeneralizedTime): + pass + + +id_pskc_numberOfTransactions = _OID(id_pskc, 23) + +class at_pskc_numberOfTransactions(univ.Integer): + pass + +at_pskc_numberOfTransactions.subtypeSpec = constraint.ValueRangeConstraint(0, MAX) + + +id_pskc_keyUsages = _OID(id_pskc, 24) + +class PSKCKeyUsage(char.UTF8String): + pass + +PSKCKeyUsage.namedValues = namedval.NamedValues( + ('otp', "OTP"), + ('cr', "CR"), + ('encrypt', "Encrypt"), + ('integrity', "Integrity"), + ('verify', "Verify"), + ('unlock', "Unlock"), + ('decrypt', "Decrypt"), + ('keywrap', "KeyWrap"), + ('unwrap', "Unwrap"), + ('derive', "Derive"), + ('generate', "Generate") +) + +PSKCKeyUsage.subtypeSpec = constraint.SingleValueConstraint( + "OTP", "CR", "Encrypt", "Integrity", "Verify", "Unlock", + "Decrypt", "KeyWrap", "Unwrap", "Derive", "Generate" ) + +class PSKCKeyUsages(univ.SequenceOf): + pass + +PSKCKeyUsages.componentType = PSKCKeyUsage() + +class at_pskc_keyUsage(PSKCKeyUsages): + pass + + +id_pskc_pinPolicy = _OID(id_pskc, 25) + +class PINUsageMode(char.UTF8String): + pass + +PINUsageMode.namedValues = namedval.NamedValues( + ("local", "Local"), + ("prepend", "Prepend"), + ("append", "Append"), + ("algorithmic", "Algorithmic") +) + +PINUsageMode.subtypeSpec = constraint.SingleValueConstraint( + "Local", "Prepend", "Append", "Algorithmic" ) + +class PINPolicy(univ.Sequence): + pass + +PINPolicy.componentType = namedtype.NamedTypes( + namedtype.OptionalNamedType('pinKeyId', char.UTF8String().subtype( + implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0))), + namedtype.NamedType('pinUsageMode', PINUsageMode().subtype( + implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 1))), + namedtype.OptionalNamedType('maxFailedAttempts', univ.Integer().subtype( + subtypeSpec=constraint.ValueRangeConstraint(0, MAX)).subtype( + implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 2))), + namedtype.OptionalNamedType('minLength', univ.Integer().subtype( + subtypeSpec=constraint.ValueRangeConstraint(0, MAX)).subtype( + implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 3))), + namedtype.OptionalNamedType('maxLength', univ.Integer().subtype( + subtypeSpec=constraint.ValueRangeConstraint(0, MAX)).subtype( + implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 4))), + namedtype.OptionalNamedType('pinEncoding', Encoding().subtype( + implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 5))) +) + +class at_pskc_pinPolicy(PINPolicy): + pass + + +# Map of Symmetric Key Package Attribute OIDs to Attributes + +sKeyPkgAttributesMap = { + id_pskc_manufacturer: at_pskc_manufacturer(), + id_pskc_serialNo: at_pskc_serialNo(), + id_pskc_model: at_pskc_model(), + id_pskc_issueNo: at_pskc_issueNo(), + id_pskc_deviceBinding: at_pskc_deviceBinding(), + id_pskc_deviceStartDate: at_pskc_deviceStartDate(), + id_pskc_deviceExpiryDate: at_pskc_deviceExpiryDate(), + id_pskc_moduleId: at_pskc_moduleId(), + id_pskc_deviceUserId: at_pskc_deviceUserId(), +} + + +# Map of Symmetric Key Attribute OIDs to Attributes + +sKeyAttributesMap = { + id_pskc_keyId: at_pskc_keyId(), + id_pskc_algorithm: at_pskc_algorithm(), + id_pskc_issuer: at_pskc_issuer(), + id_pskc_keyProfileId: at_pskc_keyProfileId(), + id_pskc_keyReference: at_pskc_keyReference(), + id_pskc_friendlyName: at_pskc_friendlyName(), + id_pskc_algorithmParameters: at_pskc_algorithmParameters(), + id_pskc_counter: at_pskc_counter(), + id_pskc_time: at_pskc_time(), + id_pskc_timeInterval: at_pskc_timeInterval(), + id_pskc_timeDrift: at_pskc_timeDrift(), + id_pskc_valueMAC: at_pskc_valueMAC(), + id_pskc_keyUserId: at_pskc_keyUserId(), + id_pskc_keyStartDate: at_pskc_keyStartDate(), + id_pskc_keyExpiryDate: at_pskc_keyExpiryDate(), + id_pskc_numberOfTransactions: at_pskc_numberOfTransactions(), + id_pskc_keyUsages: at_pskc_keyUsage(), + id_pskc_pinPolicy: at_pskc_pinPolicy(), +} + + +# This definition replaces Attribute() from rfc5652.py; it is the same except +# that opentype is added with sKeyPkgAttributesMap and sKeyAttributesMap + +class AttributeType(univ.ObjectIdentifier): + pass + + +class AttributeValue(univ.Any): + pass + + +class SKeyAttribute(univ.Sequence): + pass + +SKeyAttribute.componentType = namedtype.NamedTypes( + namedtype.NamedType('attrType', AttributeType()), + namedtype.NamedType('attrValues', + univ.SetOf(componentType=AttributeValue()), + openType=opentype.OpenType('attrType', sKeyAttributesMap) + ) +) + + +class SKeyPkgAttribute(univ.Sequence): + pass + +SKeyPkgAttribute.componentType = namedtype.NamedTypes( + namedtype.NamedType('attrType', AttributeType()), + namedtype.NamedType('attrValues', + univ.SetOf(componentType=AttributeValue()), + openType=opentype.OpenType('attrType', sKeyPkgAttributesMap) + ) +) + + +# Symmetric Key Package Content Type + +id_ct_KP_sKeyPackage = univ.ObjectIdentifier('1.2.840.113549.1.9.16.1.25') + + +class KeyPkgVersion(univ.Integer): + pass + +KeyPkgVersion.namedValues = namedval.NamedValues( + ('v1', 1) +) + + +class OneSymmetricKey(univ.Sequence): + pass + +OneSymmetricKey.componentType = namedtype.NamedTypes( + namedtype.OptionalNamedType('sKeyAttrs', + univ.SequenceOf(componentType=SKeyAttribute()).subtype( + subtypeSpec=constraint.ValueSizeConstraint(1, MAX))), + namedtype.OptionalNamedType('sKey', univ.OctetString()) +) + +OneSymmetricKey.sizeSpec = univ.Sequence.sizeSpec + constraint.ValueSizeConstraint(1, 2) + + +class SymmetricKeys(univ.SequenceOf): + pass + +SymmetricKeys.componentType = OneSymmetricKey() +SymmetricKeys.subtypeSpec=constraint.ValueSizeConstraint(1, MAX) + + +class SymmetricKeyPackage(univ.Sequence): + pass + +SymmetricKeyPackage.componentType = namedtype.NamedTypes( + namedtype.DefaultedNamedType('version', KeyPkgVersion().subtype(value='v1')), + namedtype.OptionalNamedType('sKeyPkgAttrs', + univ.SequenceOf(componentType=SKeyPkgAttribute()).subtype( + subtypeSpec=constraint.ValueSizeConstraint(1, MAX), + implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0))), + namedtype.NamedType('sKeys', SymmetricKeys()) +) + + +# Map of Content Type OIDs to Content Types are +# added to the ones that are in rfc5652.py + +_cmsContentTypesMapUpdate = { + id_ct_KP_sKeyPackage: SymmetricKeyPackage(), +} + +rfc5652.cmsContentTypesMap.update(_cmsContentTypesMapUpdate) diff --git a/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/pyasn1_modules/rfc7229.py b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/pyasn1_modules/rfc7229.py new file mode 100644 index 0000000000000000000000000000000000000000..e9bce2d5b61e14fe6428b438fbf8b7cce06cf147 --- /dev/null +++ b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/pyasn1_modules/rfc7229.py @@ -0,0 +1,29 @@ +# +# This file is part of pyasn1-modules software. +# +# Created by Russ Housley. +# +# Copyright (c) 2019, Vigil Security, LLC +# License: http://snmplabs.com/pyasn1/license.html +# +# Object Identifiers for Test Certificate Policies +# +# ASN.1 source from: +# https://www.rfc-editor.org/rfc/rfc7229.txt +# + +from pyasn1.type import univ + + +id_pkix = univ.ObjectIdentifier('1.3.6.1.5.5.7') + +id_TEST = id_pkix + (13, ) + +id_TEST_certPolicyOne = id_TEST + (1, ) +id_TEST_certPolicyTwo = id_TEST + (2, ) +id_TEST_certPolicyThree = id_TEST + (3, ) +id_TEST_certPolicyFour = id_TEST + (4, ) +id_TEST_certPolicyFive = id_TEST + (5, ) +id_TEST_certPolicySix = id_TEST + (6, ) +id_TEST_certPolicySeven = id_TEST + (7, ) +id_TEST_certPolicyEight = id_TEST + (8, ) diff --git a/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/pyasn1_modules/rfc7585.py b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/pyasn1_modules/rfc7585.py new file mode 100644 index 0000000000000000000000000000000000000000..b3fd4a5bacab6a00a68b78620ff832b0852b5c43 --- /dev/null +++ b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/pyasn1_modules/rfc7585.py @@ -0,0 +1,50 @@ +# +# This file is part of pyasn1-modules software. +# +# Created by Russ Housley with some assistance from asn1ate v.0.6.0. +# +# Copyright (c) 2019, Vigil Security, LLC +# License: http://snmplabs.com/pyasn1/license.html +# +# Network Access Identifier (NAI) Realm Name for Certificates +# +# ASN.1 source from: +# https://www.rfc-editor.org/rfc/rfc7585.txt +# + +from pyasn1.type import char +from pyasn1.type import constraint +from pyasn1.type import univ + +from pyasn1_modules import rfc5280 + + +# NAI Realm Name for Certificates + +id_pkix = univ.ObjectIdentifier('1.3.6.1.5.5.7') + +id_on = id_pkix + (8, ) + +id_on_naiRealm = id_on + (8, ) + + +ub_naiRealm_length = univ.Integer(255) + + +class NAIRealm(char.UTF8String): + subtypeSpec = constraint.ValueSizeConstraint(1, ub_naiRealm_length) + + +naiRealm = rfc5280.AnotherName() +naiRealm['type-id'] = id_on_naiRealm +naiRealm['value'] = NAIRealm() + + +# Map of Other Name OIDs to Other Name is added to the +# ones that are in rfc5280.py + +_anotherNameMapUpdate = { + id_on_naiRealm: NAIRealm(), +} + +rfc5280.anotherNameMap.update(_anotherNameMapUpdate) diff --git a/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/pyasn1_modules/rfc7894.py b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/pyasn1_modules/rfc7894.py new file mode 100644 index 0000000000000000000000000000000000000000..41936433d14bf6e0ce074649931e826758251ade --- /dev/null +++ b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/pyasn1_modules/rfc7894.py @@ -0,0 +1,92 @@ +# +# This file is part of pyasn1-modules software. +# +# Created by Russ Housley. +# +# Copyright (c) 2019, Vigil Security, LLC +# License: http://snmplabs.com/pyasn1/license.html +# +# Alternative Challenge Password Attributes for EST +# +# ASN.1 source from: +# https://www.rfc-editor.org/rfc/rfc7894.txt +# + +from pyasn1.type import char +from pyasn1.type import constraint +from pyasn1.type import namedtype +from pyasn1.type import univ + +from pyasn1_modules import rfc5652 +from pyasn1_modules import rfc6402 +from pyasn1_modules import rfc7191 + + +# SingleAttribute is the same as Attribute in RFC 5652, except that the +# attrValues SET must have one and only one member + +Attribute = rfc7191.SingleAttribute + + +# DirectoryString is the same as RFC 5280, except the length is limited to 255 + +class DirectoryString(univ.Choice): + pass + +DirectoryString.componentType = namedtype.NamedTypes( + namedtype.NamedType('teletexString', char.TeletexString().subtype( + subtypeSpec=constraint.ValueSizeConstraint(1, 255))), + namedtype.NamedType('printableString', char.PrintableString().subtype( + subtypeSpec=constraint.ValueSizeConstraint(1, 255))), + namedtype.NamedType('universalString', char.UniversalString().subtype( + subtypeSpec=constraint.ValueSizeConstraint(1, 255))), + namedtype.NamedType('utf8String', char.UTF8String().subtype( + subtypeSpec=constraint.ValueSizeConstraint(1, 255))), + namedtype.NamedType('bmpString', char.BMPString().subtype( + subtypeSpec=constraint.ValueSizeConstraint(1, 255))) +) + + +# OTP Challenge Attribute + +id_aa_otpChallenge = univ.ObjectIdentifier('1.2.840.113549.1.9.16.2.56') + +ub_aa_otpChallenge = univ.Integer(255) + +otpChallenge = Attribute() +otpChallenge['attrType'] = id_aa_otpChallenge +otpChallenge['attrValues'][0] = DirectoryString() + + +# Revocation Challenge Attribute + +id_aa_revocationChallenge = univ.ObjectIdentifier('1.2.840.113549.1.9.16.2.57') + +ub_aa_revocationChallenge = univ.Integer(255) + +revocationChallenge = Attribute() +revocationChallenge['attrType'] = id_aa_revocationChallenge +revocationChallenge['attrValues'][0] = DirectoryString() + + +# EST Identity Linking Attribute + +id_aa_estIdentityLinking = univ.ObjectIdentifier('1.2.840.113549.1.9.16.2.58') + +ub_aa_est_identity_linking = univ.Integer(255) + +estIdentityLinking = Attribute() +estIdentityLinking['attrType'] = id_aa_estIdentityLinking +estIdentityLinking['attrValues'][0] = DirectoryString() + + +# Map of Attribute Type OIDs to Attributes added to the +# ones that are in rfc6402.py + +_cmcControlAttributesMapUpdate = { + id_aa_otpChallenge: DirectoryString(), + id_aa_revocationChallenge: DirectoryString(), + id_aa_estIdentityLinking: DirectoryString(), +} + +rfc6402.cmcControlAttributesMap.update(_cmcControlAttributesMapUpdate) diff --git a/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/pycodestyle-2.8.0.dist-info/INSTALLER b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/pycodestyle-2.8.0.dist-info/INSTALLER new file mode 100644 index 0000000000000000000000000000000000000000..a1b589e38a32041e49332e5e81c2d363dc418d68 --- /dev/null +++ b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/pycodestyle-2.8.0.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/pycodestyle-2.8.0.dist-info/LICENSE b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/pycodestyle-2.8.0.dist-info/LICENSE new file mode 100644 index 0000000000000000000000000000000000000000..72d9921cc18d8f473cea6c13842ebede4bb3b271 --- /dev/null +++ b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/pycodestyle-2.8.0.dist-info/LICENSE @@ -0,0 +1,25 @@ +Copyright © 2006-2009 Johann C. Rocholl +Copyright © 2009-2014 Florent Xicluna +Copyright © 2014-2020 Ian Lee + +Licensed under the terms of the Expat License + +Permission is hereby granted, free of charge, to any person +obtaining a copy of this software and associated documentation files +(the "Software"), to deal in the Software without restriction, +including without limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of the Software, +and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/pycodestyle-2.8.0.dist-info/METADATA b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/pycodestyle-2.8.0.dist-info/METADATA new file mode 100644 index 0000000000000000000000000000000000000000..91906880ed04b0241a40309e2fcef2a6399110d7 --- /dev/null +++ b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/pycodestyle-2.8.0.dist-info/METADATA @@ -0,0 +1,1063 @@ +Metadata-Version: 2.1 +Name: pycodestyle +Version: 2.8.0 +Summary: Python style guide checker +Home-page: https://pycodestyle.pycqa.org/ +Author: Johann C. Rocholl +Author-email: johann@rocholl.net +Maintainer: Ian Lee +Maintainer-email: IanLee1521@gmail.com +License: Expat license +Project-URL: Changes, https://pycodestyle.pycqa.org/en/latest/developer.html#changes +Keywords: pycodestyle,pep8,PEP 8,PEP-8,PEP8 +Platform: UNKNOWN +Classifier: Development Status :: 5 - Production/Stable +Classifier: Environment :: Console +Classifier: Intended Audience :: Developers +Classifier: License :: OSI Approved :: MIT License +Classifier: Operating System :: OS Independent +Classifier: Programming Language :: Python +Classifier: Programming Language :: Python :: 2 +Classifier: Programming Language :: Python :: 2.7 +Classifier: Programming Language :: Python :: 3 +Classifier: Programming Language :: Python :: 3.5 +Classifier: Programming Language :: Python :: 3.6 +Classifier: Programming Language :: Python :: 3.7 +Classifier: Programming Language :: Python :: 3.8 +Classifier: Programming Language :: Python :: Implementation :: CPython +Classifier: Programming Language :: Python :: Implementation :: PyPy +Classifier: Topic :: Software Development :: Libraries :: Python Modules +Requires-Python: >=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.* +License-File: LICENSE + +pycodestyle (formerly called pep8) - Python style guide checker +=============================================================== + +.. image:: https://github.com/PyCQA/pycodestyle/actions/workflows/main.yml/badge.svg + :target: https://github.com/PyCQA/pycodestyle/actions/workflows/main.yml + :alt: Build status + +.. image:: https://readthedocs.org/projects/pycodestyle/badge/?version=latest + :target: https://pycodestyle.pycqa.org + :alt: Documentation Status + +.. image:: https://img.shields.io/pypi/wheel/pycodestyle.svg + :target: https://pypi.org/project/pycodestyle/ + :alt: Wheel Status + +.. image:: https://badges.gitter.im/PyCQA/pycodestyle.svg + :alt: Join the chat at https://gitter.im/PyCQA/pycodestyle + :target: https://gitter.im/PyCQA/pycodestyle?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge + +pycodestyle is a tool to check your Python code against some of the style +conventions in `PEP 8`_. + +.. _PEP 8: http://www.python.org/dev/peps/pep-0008/ + +.. note:: + + This package used to be called ``pep8`` but was renamed to ``pycodestyle`` + to reduce confusion. Further discussion can be found `in the issue where + Guido requested this + change `_, or in the + lightning talk at PyCon 2016 by @IanLee1521: + `slides `_ + `video `_. + +Features +-------- + +* Plugin architecture: Adding new checks is easy. + +* Parseable output: Jump to error location in your editor. + +* Small: Just one Python file, requires only stdlib. You can use just + the ``pycodestyle.py`` file for this purpose. + +* Comes with a comprehensive test suite. + +Installation +------------ + +You can install, upgrade, and uninstall ``pycodestyle.py`` with these commands:: + + $ pip install pycodestyle + $ pip install --upgrade pycodestyle + $ pip uninstall pycodestyle + +There's also a package for Debian/Ubuntu, but it's not always the +latest version. + +Example usage and output +------------------------ + +:: + + $ pycodestyle --first optparse.py + optparse.py:69:11: E401 multiple imports on one line + optparse.py:77:1: E302 expected 2 blank lines, found 1 + optparse.py:88:5: E301 expected 1 blank line, found 0 + optparse.py:222:34: W602 deprecated form of raising exception + optparse.py:347:31: E211 whitespace before '(' + optparse.py:357:17: E201 whitespace after '{' + optparse.py:472:29: E221 multiple spaces before operator + optparse.py:544:21: W601 .has_key() is deprecated, use 'in' + +You can also make ``pycodestyle.py`` show the source code for each error, and +even the relevant text from PEP 8:: + + $ pycodestyle --show-source --show-pep8 testsuite/E40.py + testsuite/E40.py:2:10: E401 multiple imports on one line + import os, sys + ^ + Imports should usually be on separate lines. + + Okay: import os\nimport sys + E401: import sys, os + + +Or you can display how often each error was found:: + + $ pycodestyle --statistics -qq Python-2.5/Lib + 232 E201 whitespace after '[' + 599 E202 whitespace before ')' + 631 E203 whitespace before ',' + 842 E211 whitespace before '(' + 2531 E221 multiple spaces before operator + 4473 E301 expected 1 blank line, found 0 + 4006 E302 expected 2 blank lines, found 1 + 165 E303 too many blank lines (4) + 325 E401 multiple imports on one line + 3615 E501 line too long (82 characters) + 612 W601 .has_key() is deprecated, use 'in' + 1188 W602 deprecated form of raising exception + +Links +----- + +* `Read the documentation `_ + +* `Fork me on GitHub `_ + + +Changelog +========= + +2.8.0 (2021-10-10) +------------------ + +Changes: + +* Drop python 3.4. PR #982. +* E712: fix false negative with multiple comparisons. PR #987. +* E211: fix false positives with ``match``. PR #989. +* E772: improve performance of bare except check. PR #992. +* Backport tokenize performance improvement from python 3.10. PR #993. +* E225: fix for lambdas containing positional-only args. PR #1012. +* Remove ``indent_size_str`` "setting". PR #995. +* E402: allow ``__all__`` to be typed. PR #1019. +* E225: fix false positives for ``*`` in ``case``. PR #1003. +* E201: detect tabs as whitespace. PR #1015. + + +2.7.0 (2021-03-14) +------------------ + +Changes: + +* Fix physical checks (such as W191) at end of file. PR #961. +* Add ``--indent-size`` option (defaulting to ``4``). PR #970. +* W605: fix escaped crlf false positive on windows. PR #976. + + +2.6.0 (2020-05-11) +------------------ + +Announcements: + +* Anthony Sottile (@asottile) joined the team as a core developer. :tada: + +Changes: + +* E306: fix detection inside ``async def``. PR #929. +* E301: fix regression disallowing decorated one-liners. PR #927. +* E714: fix false positive with chained ``is not``. PR #931. + + +2.6.0a1 (2020-04-23) +-------------------- + +New checks: + +* E225: require whitespace around ``and`` ``in`` ``is`` and ``or``. PR #847. + +Changes: + +* E117: fix indentation using tabs by treating as 8-space indents. PR #837. +* E721: fix false positive with names containg ``istype``. PR #850. +* E741: allow ``l`` as a named argument in a function call. PR #853. +* E302: fix false-negative with decorated functions. PR #859. +* W504: ellipsis (``...``) is no longer treated as a binary operator. PR #875. +* E402: allow ``with``, ``if``, ``elif``, ``else`` to guard imports. PR #834. +* Add support for assignment expressions ``:=`` (PEP 572). PR #879. +* Add support for positional-only arguments ``/`` (PEP 570). PR #872, #918. +* Add support for python 3.8. +* Add support for matrix multiplication operator ``@`` (PEP 465). PR #897. +* Support visual indent for continuation lines for ``with`` / ``assert`` / + ``raise``. PR #912. +* E302: allow two blank lines after a block of one-liners. PR #913. +* E302: allow two-and-fewer newlines at the top of the file. PR #919. + + +2.5.0 (2019-01-29) +------------------ + +New checks: + +* E117: Over-indented code blocks +* W505: Maximum doc-string length only when configured with --max-doc-length + +Changes: + +* Remove support for EOL Python 2.6 and 3.3. PR #720. +* Add E117 error for over-indented code blocks. +* Allow W605 to be silenced by `# noqa` and fix the position reported by W605 +* Allow users to omit blank lines around one-liner definitions of classes and + functions +* Include the function return annotation (``->``) as requiring surrounding + whitespace only on Python 3 +* Verify that only names can follow ``await``. Previously we allowed numbers + and strings. +* Add support for Python 3.7 +* Fix detection of annotated argument defaults for E252 +* Correct the position reported by W504 + + +2.4.0 (2018-04-10) +------------------ + +New checks: + +* Add W504 warning for checking that a break doesn't happen after a binary + operator. This check is ignored by default. PR #502. +* Add W605 warning for invalid escape sequences in string literals. PR #676. +* Add W606 warning for 'async' and 'await' reserved keywords being introduced + in Python 3.7. PR #684. +* Add E252 error for missing whitespace around equal sign in type annotated + function arguments with defaults values. PR #717. + +Changes: + +* An internal bisect search has replaced a linear search in order to improve + efficiency. PR #648. +* pycodestyle now uses PyPI trove classifiers in order to document supported + python versions on PyPI. PR #654. +* 'setup.cfg' '[wheel]' section has been renamed to '[bdist_wheel]', as + the former is legacy. PR #653. +* pycodestyle now handles very long lines much more efficiently for python + 3.2+. Fixes #643. PR #644. +* You can now write 'pycodestyle.StyleGuide(verbose=True)' instead of + 'pycodestyle.StyleGuide(verbose=True, paths=['-v'])' in order to achieve + verbosity. PR #663. +* The distribution of pycodestyle now includes the license text in order to + comply with open source licenses which require this. PR #694. +* 'maximum_line_length' now ignores shebang ('#!') lines. PR #736. +* Add configuration option for the allowed number of blank lines. It is + implemented as a top level dictionary which can be easily overwritten. Fixes + #732. PR #733. + +Bugs: + +* Prevent a 'DeprecationWarning', and a 'SyntaxError' in future python, caused + by an invalid escape sequence. PR #625. +* Correctly report E501 when the first line of a docstring is too long. + Resolves #622. PR #630. +* Support variable annotation when variable start by a keyword, such as class + variable type annotations in python 3.6. PR #640. +* pycodestyle internals have been changed in order to allow 'python3 -m + cProfile' to report correct metrics. PR #647. +* Fix a spelling mistake in the description of E722. PR #697. +* 'pycodestyle --diff' now does not break if your 'gitconfig' enables + 'mnemonicprefix'. PR #706. + +2.3.1 (2017-01-31) +------------------ + +Bugs: + +* Fix regression in detection of E302 and E306; #618, #620 + +2.3.0 (2017-01-30) +------------------ + +New Checks: + +* Add E722 warning for bare ``except`` clauses +* Report E704 for async function definitions (``async def``) + +Bugs: + +* Fix another E305 false positive for variables beginning with "class" or + "def" +* Fix detection of multiple spaces between ``async`` and ``def`` +* Fix handling of variable annotations. Stop reporting E701 on Python 3.6 for + variable annotations. + +2.2.0 (2016-11-14) +------------------ + +Announcements: + +* Added Make target to obtain proper tarball file permissions; #599 + +Bugs: + +* Fixed E305 regression caused by #400; #593 + +2.1.0 (2016-11-04) +------------------ + +Announcements: + +* Change all references to the pep8 project to say pycodestyle; #530 + +Changes: + +* Report E302 for blank lines before an "async def"; #556 +* Update our list of tested and supported Python versions which are 2.6, 2.7, + 3.2, 3.3, 3.4 and 3.5 as well as the nightly Python build and PyPy. +* Report E742 and E743 for functions and classes badly named 'l', 'O', or 'I'. +* Report E741 on 'global' and 'nonlocal' statements, as well as prohibited + single-letter variables. +* Deprecated use of `[pep8]` section name in favor of `[pycodestyle]`; #591 +* Report E722 when bare except clause is used; #579 + +Bugs: + +* Fix opt_type AssertionError when using Flake8 2.6.2 and pycodestyle; #561 +* Require two blank lines after toplevel def, class; #536 +* Remove accidentally quadratic computation based on the number of colons. This + will make pycodestyle faster in some cases; #314 + +2.0.0 (2016-05-31) +------------------ + +Announcements: + +* Repository renamed to `pycodestyle`; Issue #466 / #481. +* Added joint Code of Conduct as member of PyCQA; #483 + +Changes: + +* Added tox test support for Python 3.5 and pypy3 +* Added check E275 for whitespace on `from ... import ...` lines; #489 / #491 +* Added W503 to the list of codes ignored by default ignore list; #498 +* Removed use of project level `.pep8` configuration file; #364 + +Bugs: + +* Fixed bug with treating `~` operator as binary; #383 / #384 +* Identify binary operators as unary; #484 / #485 + +1.7.0 (2016-01-12) +------------------ + +Announcements: + +* Repository moved to PyCQA Organization on GitHub: + https://github.com/pycqa/pep8 + +Changes: + +* Reverted the fix in #368, "options passed on command line are only ones + accepted" feature. This has many unintended consequences in pep8 and flake8 + and needs to be reworked when I have more time. +* Added support for Python 3.5. (Issue #420 & #459) +* Added support for multi-line config_file option parsing. (Issue #429) +* Improved parameter parsing. (Issues #420 & #456) + +Bugs: + +* Fixed BytesWarning on Python 3. (Issue #459) + +1.6.2 (2015-02-15) +------------------ + +Changes: + +* Added check for breaking around a binary operator. (Issue #197, Pull #305) + +Bugs: + +* Restored config_file parameter in process_options(). (Issue #380) + + +1.6.1 (2015-02-08) +------------------ + +Changes: + +* Assign variables before referenced. (Issue #287) + +Bugs: + +* Exception thrown due to unassigned ``local_dir`` variable. (Issue #377) + + +1.6.0 (2015-02-06) +------------------ + +News: + +* Ian Lee joined the project as a maintainer. + +Changes: + +* Report E731 for lambda assignment. (Issue #277) + +* Report E704 for one-liner def instead of E701. + Do not report this error in the default configuration. (Issue #277) + +* Replace codes E111, E112 and E113 with codes E114, E115 and E116 + for bad indentation of comments. (Issue #274) + +* Report E266 instead of E265 when the block comment starts with + multiple ``#``. (Issue #270) + +* Report E402 for import statements not at the top of the file. (Issue #264) + +* Do not enforce whitespaces around ``**`` operator. (Issue #292) + +* Strip whitespace from around paths during normalization. (Issue #339 / #343) + +* Update ``--format`` documentation. (Issue #198 / Pull Request #310) + +* Add ``.tox/`` to default excludes. (Issue #335) + +* Do not report E121 or E126 in the default configuration. (Issues #256 / #316) + +* Allow spaces around the equals sign in an annotated function. (Issue #357) + +* Allow trailing backslash if in an inline comment. (Issue #374) + +* If ``--config`` is used, only that configuration is processed. Otherwise, + merge the user and local configurations are merged. (Issue #368 / #369) + +Bug fixes: + +* Don't crash if Checker.build_tokens_line() returns None. (Issue #306) + +* Don't crash if os.path.expanduser() throws an ImportError. (Issue #297) + +* Missing space around keyword parameter equal not always reported, E251. + (Issue #323) + +* Fix false positive E711/E712/E713. (Issues #330 and #336) + +* Do not skip physical checks if the newline is escaped. (Issue #319) + +* Flush sys.stdout to avoid race conditions with printing. See flake8 bug: + https://gitlab.com/pycqa/flake8/issues/17 for more details. (Issue #363) + + +1.5.7 (2014-05-29) +------------------ + +Bug fixes: + +* Skip the traceback on "Broken pipe" signal. (Issue #275) + +* Do not exit when an option in ``setup.cfg`` or ``tox.ini`` + is not recognized. + +* Check the last line even if it does not end with a newline. (Issue #286) + +* Always open files in universal newlines mode in Python 2. (Issue #288) + + +1.5.6 (2014-04-14) +------------------ + +Bug fixes: + +* Check the last line even if it has no end-of-line. (Issue #273) + + +1.5.5 (2014-04-10) +------------------ + +Bug fixes: + +* Fix regression with E22 checks and inline comments. (Issue #271) + + +1.5.4 (2014-04-07) +------------------ + +Bug fixes: + +* Fix negative offset with E303 before a multi-line docstring. + (Issue #269) + + +1.5.3 (2014-04-04) +------------------ + +Bug fixes: + +* Fix wrong offset computation when error is on the last char + of a physical line. (Issue #268) + + +1.5.2 (2014-04-04) +------------------ + +Changes: + +* Distribute a universal wheel file. + +Bug fixes: + +* Report correct line number for E303 with comments. (Issue #60) + +* Do not allow newline after parameter equal. (Issue #252) + +* Fix line number reported for multi-line strings. (Issue #220) + +* Fix false positive E121/E126 with multi-line strings. (Issue #265) + +* Fix E501 not detected in comments with Python 2.5. + +* Fix caret position with ``--show-source`` when line contains tabs. + + +1.5.1 (2014-03-27) +------------------ + +Bug fixes: + +* Fix a crash with E125 on multi-line strings. (Issue #263) + + +1.5 (2014-03-26) +---------------- + +Changes: + +* Report E129 instead of E125 for visually indented line with same + indent as next logical line. (Issue #126) + +* Report E265 for space before block comment. (Issue #190) + +* Report E713 and E714 when operators ``not in`` and ``is not`` are + recommended. (Issue #236) + +* Allow long lines in multiline strings and comments if they cannot + be wrapped. (Issue #224). + +* Optionally disable physical line checks inside multiline strings, + using ``# noqa``. (Issue #242) + +* Change text for E121 to report "continuation line under-indented + for hanging indent" instead of indentation not being a + multiple of 4. + +* Report E131 instead of E121 / E126 if the hanging indent is not + consistent within the same continuation block. It helps when + error E121 or E126 is in the ``ignore`` list. + +* Report E126 instead of E121 when the continuation line is hanging + with extra indentation, even if indentation is not a multiple of 4. + +Bug fixes: + +* Allow the checkers to report errors on empty files. (Issue #240) + +* Fix ignoring too many checks when ``--select`` is used with codes + declared in a flake8 extension. (Issue #216) + +* Fix regression with multiple brackets. (Issue #214) + +* Fix ``StyleGuide`` to parse the local configuration if the + keyword argument ``paths`` is specified. (Issue #246) + +* Fix a false positive E124 for hanging indent. (Issue #254) + +* Fix a false positive E126 with embedded colon. (Issue #144) + +* Fix a false positive E126 when indenting with tabs. (Issue #204) + +* Fix behaviour when ``exclude`` is in the configuration file and + the current directory is not the project directory. (Issue #247) + +* The logical checks can return ``None`` instead of an empty iterator. + (Issue #250) + +* Do not report multiple E101 if only the first indentation starts + with a tab. (Issue #237) + +* Fix a rare false positive W602. (Issue #34) + + +1.4.6 (2013-07-02) +------------------ + +Changes: + +* Honor ``# noqa`` for errors E711 and E712. (Issue #180) + +* When both a ``tox.ini`` and a ``setup.cfg`` are present in the project + directory, merge their contents. The ``tox.ini`` file takes + precedence (same as before). (Issue #182) + +* Give priority to ``--select`` over ``--ignore``. (Issue #188) + +* Compare full path when excluding a file. (Issue #186) + +* New option ``--hang-closing`` to switch to the alternative style of + closing bracket indentation for hanging indent. Add error E133 for + closing bracket which is missing indentation. (Issue #103) + +* Accept both styles of closing bracket indentation for hanging indent. + Do not report error E123 in the default configuration. (Issue #103) + +Bug fixes: + +* Do not crash when running AST checks and the document contains null bytes. + (Issue #184) + +* Correctly report other E12 errors when E123 is ignored. (Issue #103) + +* Fix false positive E261/E262 when the file contains a BOM. (Issue #193) + +* Fix E701, E702 and E703 not detected sometimes. (Issue #196) + +* Fix E122 not detected in some cases. (Issue #201 and #208) + +* Fix false positive E121 with multiple brackets. (Issue #203) + + +1.4.5 (2013-03-06) +------------------ + +* When no path is specified, do not try to read from stdin. The feature + was added in 1.4.3, but it is not supported on Windows. Use ``-`` + filename argument to read from stdin. This usage is supported + since 1.3.4. (Issue #170) + +* Do not require ``setuptools`` in setup.py. It works around an issue + with ``pip`` and Python 3. (Issue #172) + +* Add ``__pycache__`` to the ignore list. + +* Change misleading message for E251. (Issue #171) + +* Do not report false E302 when the source file has a coding cookie or a + comment on the first line. (Issue #174) + +* Reorganize the tests and add tests for the API and for the command line + usage and options. (Issues #161 and #162) + +* Ignore all checks which are not explicitly selected when ``select`` is + passed to the ``StyleGuide`` constructor. + + +1.4.4 (2013-02-24) +------------------ + +* Report E227 or E228 instead of E225 for whitespace around bitwise, shift + or modulo operators. (Issue #166) + +* Change the message for E226 to make clear that it is about arithmetic + operators. + +* Fix a false positive E128 for continuation line indentation with tabs. + +* Fix regression with the ``--diff`` option. (Issue #169) + +* Fix the ``TestReport`` class to print the unexpected warnings and + errors. + + +1.4.3 (2013-02-22) +------------------ + +* Hide the ``--doctest`` and ``--testsuite`` options when installed. + +* Fix crash with AST checkers when the syntax is invalid. (Issue #160) + +* Read from standard input if no path is specified. + +* Initiate a graceful shutdown on ``Control+C``. + +* Allow changing the ``checker_class`` for the ``StyleGuide``. + + +1.4.2 (2013-02-10) +------------------ + +* Support AST checkers provided by third-party applications. + +* Register new checkers with ``register_check(func_or_cls, codes)``. + +* Allow constructing a ``StyleGuide`` with a custom parser. + +* Accept visual indentation without parenthesis after the ``if`` + statement. (Issue #151) + +* Fix UnboundLocalError when using ``# noqa`` with continued lines. + (Issue #158) + +* Re-order the lines for the ``StandardReport``. + +* Expand tabs when checking E12 continuation lines. (Issue #155) + +* Refactor the testing class ``TestReport`` and the specific test + functions into a separate test module. + + +1.4.1 (2013-01-18) +------------------ + +* Allow sphinx.ext.autodoc syntax for comments. (Issue #110) + +* Report E703 instead of E702 for the trailing semicolon. (Issue #117) + +* Honor ``# noqa`` in addition to ``# nopep8``. (Issue #149) + +* Expose the ``OptionParser`` factory for better extensibility. + + +1.4 (2012-12-22) +---------------- + +* Report E226 instead of E225 for optional whitespace around common + operators (``*``, ``**``, ``/``, ``+`` and ``-``). This new error + code is ignored in the default configuration because PEP 8 recommends + to "use your own judgement". (Issue #96) + +* Lines with a ``# nopep8`` at the end will not issue errors on line + length E501 or continuation line indentation E12*. (Issue #27) + +* Fix AssertionError when the source file contains an invalid line + ending ``"\r\r\n"``. (Issue #119) + +* Read the ``[pep8]`` section of ``tox.ini`` or ``setup.cfg`` if present. + (Issue #93 and #141) + +* Add the Sphinx-based documentation, and publish it + on https://pycodestyle.readthedocs.io/. (Issue #105) + + +1.3.4 (2012-12-18) +------------------ + +* Fix false positive E124 and E128 with comments. (Issue #100) + +* Fix error on stdin when running with bpython. (Issue #101) + +* Fix false positive E401. (Issue #104) + +* Report E231 for nested dictionary in list. (Issue #142) + +* Catch E271 at the beginning of the line. (Issue #133) + +* Fix false positive E126 for multi-line comments. (Issue #138) + +* Fix false positive E221 when operator is preceded by a comma. (Issue #135) + +* Fix ``--diff`` failing on one-line hunk. (Issue #137) + +* Fix the ``--exclude`` switch for directory paths. (Issue #111) + +* Use ``-`` filename to read from standard input. (Issue #128) + + +1.3.3 (2012-06-27) +------------------ + +* Fix regression with continuation line checker. (Issue #98) + + +1.3.2 (2012-06-26) +------------------ + +* Revert to the previous behaviour for ``--show-pep8``: + do not imply ``--first``. (Issue #89) + +* Add E902 for IO errors. (Issue #87) + +* Fix false positive for E121, and missed E124. (Issue #92) + +* Set a sensible default path for config file on Windows. (Issue #95) + +* Allow ``verbose`` in the configuration file. (Issue #91) + +* Show the enforced ``max-line-length`` in the error message. (Issue #86) + + +1.3.1 (2012-06-18) +------------------ + +* Explain which configuration options are expected. Accept and recommend + the options names with hyphen instead of underscore. (Issue #82) + +* Do not read the user configuration when used as a module + (except if ``config_file=True`` is passed to the ``StyleGuide`` constructor). + +* Fix wrong or missing cases for the E12 series. + +* Fix cases where E122 was missed. (Issue #81) + + +1.3 (2012-06-15) +---------------- + +.. warning:: + The internal API is backwards incompatible. + +* Remove global configuration and refactor the library around + a ``StyleGuide`` class; add the ability to configure various + reporters. (Issue #35 and #66) + +* Read user configuration from ``~/.config/pep8`` + and local configuration from ``./.pep8``. (Issue #22) + +* Fix E502 for backslash embedded in multi-line string. (Issue #68) + +* Fix E225 for Python 3 iterable unpacking (PEP 3132). (Issue #72) + +* Enable the new checkers from the E12 series in the default + configuration. + +* Suggest less error-prone alternatives for E712 errors. + +* Rewrite checkers to run faster (E22, E251, E27). + +* Fixed a crash when parsed code is invalid (too many + closing brackets). + +* Fix E127 and E128 for continuation line indentation. (Issue #74) + +* New option ``--format`` to customize the error format. (Issue #23) + +* New option ``--diff`` to check only modified code. The unified + diff is read from STDIN. Example: ``hg diff | pep8 --diff`` + (Issue #39) + +* Correctly report the count of failures and set the exit code to 1 + when the ``--doctest`` or the ``--testsuite`` fails. + +* Correctly detect the encoding in Python 3. (Issue #69) + +* Drop support for Python 2.3, 2.4 and 3.0. (Issue #78) + + +1.2 (2012-06-01) +---------------- + +* Add E121 through E128 for continuation line indentation. These + checks are disabled by default. If you want to force all checks, + use switch ``--select=E,W``. Patch by Sam Vilain. (Issue #64) + +* Add E721 for direct type comparisons. (Issue #47) + +* Add E711 and E712 for comparisons to singletons. (Issue #46) + +* Fix spurious E225 and E701 for function annotations. (Issue #29) + +* Add E502 for explicit line join between brackets. + +* Fix E901 when printing source with ``--show-source``. + +* Report all errors for each checker, instead of reporting only the + first occurrence for each line. + +* Option ``--show-pep8`` implies ``--first``. + + +1.1 (2012-05-24) +---------------- + +* Add E901 for syntax errors. (Issues #63 and #30) + +* Add E271, E272, E273 and E274 for extraneous whitespace around + keywords. (Issue #57) + +* Add ``tox.ini`` configuration file for tests. (Issue #61) + +* Add ``.travis.yml`` configuration file for continuous integration. + (Issue #62) + + +1.0.1 (2012-04-06) +------------------ + +* Fix inconsistent version numbers. + + +1.0 (2012-04-04) +---------------- + +* Fix W602 ``raise`` to handle multi-char names. (Issue #53) + + +0.7.0 (2012-03-26) +------------------ + +* Now ``--first`` prints only the first occurrence of each error. + The ``--repeat`` flag becomes obsolete because it is the default + behaviour. (Issue #6) + +* Allow specifying ``--max-line-length``. (Issue #36) + +* Make the shebang more flexible. (Issue #26) + +* Add testsuite to the bundle. (Issue #25) + +* Fixes for Jython. (Issue #49) + +* Add PyPI classifiers. (Issue #43) + +* Fix the ``--exclude`` option. (Issue #48) + +* Fix W602, accept ``raise`` with 3 arguments. (Issue #34) + +* Correctly select all tests if ``DEFAULT_IGNORE == ''``. + + +0.6.1 (2010-10-03) +------------------ + +* Fix inconsistent version numbers. (Issue #21) + + +0.6.0 (2010-09-19) +------------------ + +* Test suite reorganized and enhanced in order to check more failures + with fewer test files. Read the ``run_tests`` docstring for details + about the syntax. + +* Fix E225: accept ``print >>sys.stderr, "..."`` syntax. + +* Fix E501 for lines containing multibyte encoded characters. (Issue #7) + +* Fix E221, E222, E223, E224 not detected in some cases. (Issue #16) + +* Fix E211 to reject ``v = dic['a'] ['b']``. (Issue #17) + +* Exit code is always 1 if any error or warning is found. (Issue #10) + +* ``--ignore`` checks are now really ignored, especially in + conjunction with ``--count``. (Issue #8) + +* Blank lines with spaces yield W293 instead of W291: some developers + want to ignore this warning and indent the blank lines to paste their + code easily in the Python interpreter. + +* Fix E301: do not require a blank line before an indented block. (Issue #14) + +* Fix E203 to accept NumPy slice notation ``a[0, :]``. (Issue #13) + +* Performance improvements. + +* Fix decoding and checking non-UTF8 files in Python 3. + +* Fix E225: reject ``True+False`` when running on Python 3. + +* Fix an exception when the line starts with an operator. + +* Allow a new line before closing ``)``, ``}`` or ``]``. (Issue #5) + + +0.5.0 (2010-02-17) +------------------ + +* Changed the ``--count`` switch to print to sys.stderr and set + exit code to 1 if any error or warning is found. + +* E241 and E242 are removed from the standard checks. If you want to + include these checks, use switch ``--select=E,W``. (Issue #4) + +* Blank line is not mandatory before the first class method or nested + function definition, even if there's a docstring. (Issue #1) + +* Add the switch ``--version``. + +* Fix decoding errors with Python 3. (Issue #13 [1]_) + +* Add ``--select`` option which is mirror of ``--ignore``. + +* Add checks E261 and E262 for spaces before inline comments. + +* New check W604 warns about deprecated usage of backticks. + +* New check W603 warns about the deprecated operator ``<>``. + +* Performance improvement, due to rewriting of E225. + +* E225 now accepts: + + - no whitespace after unary operator or similar. (Issue #9 [1]_) + + - lambda function with argument unpacking or keyword defaults. + +* Reserve "2 blank lines" for module-level logical blocks. (E303) + +* Allow multi-line comments. (E302, issue #10 [1]_) + + +0.4.2 (2009-10-22) +------------------ + +* Decorators on classes and class methods are OK now. + + +0.4 (2009-10-20) +---------------- + +* Support for all versions of Python from 2.3 to 3.1. + +* New and greatly expanded self tests. + +* Added ``--count`` option to print the total number of errors and warnings. + +* Further improvements to the handling of comments and blank lines. + (Issue #1 [1]_ and others changes.) + +* Check all py files in directory when passed a directory (Issue + #2 [1]_). This also prevents an exception when traversing directories + with non ``*.py`` files. + +* E231 should allow commas to be followed by ``)``. (Issue #3 [1]_) + +* Spaces are no longer required around the equals sign for keyword + arguments or default parameter values. + + +.. [1] These issues refer to the `previous issue tracker`__. +.. __: http://github.com/cburroughs/pep8.py/issues + + +0.3.1 (2009-09-14) +------------------ + +* Fixes for comments: do not count them when checking for blank lines between + items. + +* Added setup.py for pypi upload and easy_installability. + + +0.2 (2007-10-16) +---------------- + +* Loads of fixes and improvements. + + +0.1 (2006-10-01) +---------------- + +* First release. + + diff --git a/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/pycodestyle-2.8.0.dist-info/RECORD b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/pycodestyle-2.8.0.dist-info/RECORD new file mode 100644 index 0000000000000000000000000000000000000000..6db1220ae4e84c20ba59bed6730802df912a03b5 --- /dev/null +++ b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/pycodestyle-2.8.0.dist-info/RECORD @@ -0,0 +1,12 @@ +../../../bin/pycodestyle,sha256=YqpyFg8K_Q6SXk7DJ80K4Q6wKmZU1G06Ti8XKbcJwAA,230 +__pycache__/pycodestyle.cpython-38.pyc,, +pycodestyle-2.8.0.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +pycodestyle-2.8.0.dist-info/LICENSE,sha256=93IpXoGvNHjTTojlLQdiACMOx91qOeEjvFyzWqZqva4,1254 +pycodestyle-2.8.0.dist-info/METADATA,sha256=jLxHgy1ywol0Yu2cxoVLIw4XMOlUaUUDZijfTUFV2uY,31230 +pycodestyle-2.8.0.dist-info/RECORD,, +pycodestyle-2.8.0.dist-info/REQUESTED,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +pycodestyle-2.8.0.dist-info/WHEEL,sha256=WzZ8cwjh8l0jtULNjYq1Hpr-WCqCRgPr--TX4P5I1Wo,110 +pycodestyle-2.8.0.dist-info/entry_points.txt,sha256=6JU_7SAppC93MBSQi1_QxDwEQUyg6cgK71ab9q_Hxco,51 +pycodestyle-2.8.0.dist-info/namespace_packages.txt,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1 +pycodestyle-2.8.0.dist-info/top_level.txt,sha256=rHbIEiXmvsJ016mFcLVcF_d-dKgP3VdfOB6CWbivZug,12 +pycodestyle.py,sha256=3-O2ixYLkFoim3-EN1XLtHL2-oJafe6BQKrY2nbkrA4,105016 diff --git a/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/pycodestyle-2.8.0.dist-info/REQUESTED b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/pycodestyle-2.8.0.dist-info/REQUESTED new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/pycodestyle-2.8.0.dist-info/WHEEL b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/pycodestyle-2.8.0.dist-info/WHEEL new file mode 100644 index 0000000000000000000000000000000000000000..b733a60d379c60aef4921d7e42a113fdc28300dc --- /dev/null +++ b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/pycodestyle-2.8.0.dist-info/WHEEL @@ -0,0 +1,6 @@ +Wheel-Version: 1.0 +Generator: bdist_wheel (0.37.0) +Root-Is-Purelib: true +Tag: py2-none-any +Tag: py3-none-any + diff --git a/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/pycodestyle-2.8.0.dist-info/entry_points.txt b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/pycodestyle-2.8.0.dist-info/entry_points.txt new file mode 100644 index 0000000000000000000000000000000000000000..71bd8850486e02ac3019610c2debeda0139077d5 --- /dev/null +++ b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/pycodestyle-2.8.0.dist-info/entry_points.txt @@ -0,0 +1,3 @@ +[console_scripts] +pycodestyle = pycodestyle:_main + diff --git a/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/pycodestyle-2.8.0.dist-info/namespace_packages.txt b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/pycodestyle-2.8.0.dist-info/namespace_packages.txt new file mode 100644 index 0000000000000000000000000000000000000000..8b137891791fe96927ad78e64b0aad7bded08bdc --- /dev/null +++ b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/pycodestyle-2.8.0.dist-info/namespace_packages.txt @@ -0,0 +1 @@ + diff --git a/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/pycodestyle-2.8.0.dist-info/top_level.txt b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/pycodestyle-2.8.0.dist-info/top_level.txt new file mode 100644 index 0000000000000000000000000000000000000000..282a93fbd7c6e15b2ae7357054c1d11ac7d5423f --- /dev/null +++ b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/pycodestyle-2.8.0.dist-info/top_level.txt @@ -0,0 +1 @@ +pycodestyle diff --git a/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/requests/__init__.py b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/requests/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..343e5082d367340ad6f83007484809bcd7f70c55 --- /dev/null +++ b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/requests/__init__.py @@ -0,0 +1,180 @@ +# __ +# /__) _ _ _ _ _/ _ +# / ( (- (/ (/ (- _) / _) +# / + +""" +Requests HTTP Library +~~~~~~~~~~~~~~~~~~~~~ + +Requests is an HTTP library, written in Python, for human beings. +Basic GET usage: + + >>> import requests + >>> r = requests.get('https://www.python.org') + >>> r.status_code + 200 + >>> b'Python is a programming language' in r.content + True + +... or POST: + + >>> payload = dict(key1='value1', key2='value2') + >>> r = requests.post('https://httpbin.org/post', data=payload) + >>> print(r.text) + { + ... + "form": { + "key1": "value1", + "key2": "value2" + }, + ... + } + +The other HTTP methods are supported - see `requests.api`. Full documentation +is at . + +:copyright: (c) 2017 by Kenneth Reitz. +:license: Apache 2.0, see LICENSE for more details. +""" + +import warnings + +import urllib3 + +from .exceptions import RequestsDependencyWarning + +try: + from charset_normalizer import __version__ as charset_normalizer_version +except ImportError: + charset_normalizer_version = None + +try: + from chardet import __version__ as chardet_version +except ImportError: + chardet_version = None + + +def check_compatibility(urllib3_version, chardet_version, charset_normalizer_version): + urllib3_version = urllib3_version.split(".") + assert urllib3_version != ["dev"] # Verify urllib3 isn't installed from git. + + # Sometimes, urllib3 only reports its version as 16.1. + if len(urllib3_version) == 2: + urllib3_version.append("0") + + # Check urllib3 for compatibility. + major, minor, patch = urllib3_version # noqa: F811 + major, minor, patch = int(major), int(minor), int(patch) + # urllib3 >= 1.21.1, <= 1.26 + assert major == 1 + assert minor >= 21 + assert minor <= 26 + + # Check charset_normalizer for compatibility. + if chardet_version: + major, minor, patch = chardet_version.split(".")[:3] + major, minor, patch = int(major), int(minor), int(patch) + # chardet_version >= 3.0.2, < 5.0.0 + assert (3, 0, 2) <= (major, minor, patch) < (5, 0, 0) + elif charset_normalizer_version: + major, minor, patch = charset_normalizer_version.split(".")[:3] + major, minor, patch = int(major), int(minor), int(patch) + # charset_normalizer >= 2.0.0 < 3.0.0 + assert (2, 0, 0) <= (major, minor, patch) < (3, 0, 0) + else: + raise Exception("You need either charset_normalizer or chardet installed") + + +def _check_cryptography(cryptography_version): + # cryptography < 1.3.4 + try: + cryptography_version = list(map(int, cryptography_version.split("."))) + except ValueError: + return + + if cryptography_version < [1, 3, 4]: + warning = "Old version of cryptography ({}) may cause slowdown.".format( + cryptography_version + ) + warnings.warn(warning, RequestsDependencyWarning) + + +# Check imported dependencies for compatibility. +try: + check_compatibility( + urllib3.__version__, chardet_version, charset_normalizer_version + ) +except (AssertionError, ValueError): + warnings.warn( + "urllib3 ({}) or chardet ({})/charset_normalizer ({}) doesn't match a supported " + "version!".format( + urllib3.__version__, chardet_version, charset_normalizer_version + ), + RequestsDependencyWarning, + ) + +# Attempt to enable urllib3's fallback for SNI support +# if the standard library doesn't support SNI or the +# 'ssl' library isn't available. +try: + try: + import ssl + except ImportError: + ssl = None + + if not getattr(ssl, "HAS_SNI", False): + from urllib3.contrib import pyopenssl + + pyopenssl.inject_into_urllib3() + + # Check cryptography version + from cryptography import __version__ as cryptography_version + + _check_cryptography(cryptography_version) +except ImportError: + pass + +# urllib3's DependencyWarnings should be silenced. +from urllib3.exceptions import DependencyWarning + +warnings.simplefilter("ignore", DependencyWarning) + +# Set default logging handler to avoid "No handler found" warnings. +import logging +from logging import NullHandler + +from . import packages, utils +from .__version__ import ( + __author__, + __author_email__, + __build__, + __cake__, + __copyright__, + __description__, + __license__, + __title__, + __url__, + __version__, +) +from .api import delete, get, head, options, patch, post, put, request +from .exceptions import ( + ConnectionError, + ConnectTimeout, + FileModeWarning, + HTTPError, + JSONDecodeError, + ReadTimeout, + RequestException, + Timeout, + TooManyRedirects, + URLRequired, +) +from .models import PreparedRequest, Request, Response +from .sessions import Session, session +from .status_codes import codes + +logging.getLogger(__name__).addHandler(NullHandler()) + +# FileModeWarnings go off per the default. +warnings.simplefilter("default", FileModeWarning, append=True) diff --git a/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/requests/__version__.py b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/requests/__version__.py new file mode 100644 index 0000000000000000000000000000000000000000..cbb5c5cfde4466fbea7633e98cd27fafee6a8538 --- /dev/null +++ b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/requests/__version__.py @@ -0,0 +1,14 @@ +# .-. .-. .-. . . .-. .-. .-. .-. +# |( |- |.| | | |- `-. | `-. +# ' ' `-' `-`.`-' `-' `-' ' `-' + +__title__ = "requests" +__description__ = "Python HTTP for Humans." +__url__ = "https://requests.readthedocs.io" +__version__ = "2.28.0" +__build__ = 0x022800 +__author__ = "Kenneth Reitz" +__author_email__ = "me@kennethreitz.org" +__license__ = "Apache 2.0" +__copyright__ = "Copyright 2022 Kenneth Reitz" +__cake__ = "\u2728 \U0001f370 \u2728" diff --git a/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/requests/_internal_utils.py b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/requests/_internal_utils.py new file mode 100644 index 0000000000000000000000000000000000000000..7dc9bc53360e95abfa99fe1ebd205a3d3ac620e6 --- /dev/null +++ b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/requests/_internal_utils.py @@ -0,0 +1,48 @@ +""" +requests._internal_utils +~~~~~~~~~~~~~~ + +Provides utility functions that are consumed internally by Requests +which depend on extremely few external helpers (such as compat) +""" +import re + +from .compat import builtin_str + +_VALID_HEADER_NAME_RE_BYTE = re.compile(rb"^[^:\s][^:\r\n]*$") +_VALID_HEADER_NAME_RE_STR = re.compile(r"^[^:\s][^:\r\n]*$") +_VALID_HEADER_VALUE_RE_BYTE = re.compile(rb"^\S[^\r\n]*$|^$") +_VALID_HEADER_VALUE_RE_STR = re.compile(r"^\S[^\r\n]*$|^$") + +HEADER_VALIDATORS = { + bytes: (_VALID_HEADER_NAME_RE_BYTE, _VALID_HEADER_VALUE_RE_BYTE), + str: (_VALID_HEADER_NAME_RE_STR, _VALID_HEADER_VALUE_RE_STR), +} + + +def to_native_string(string, encoding="ascii"): + """Given a string object, regardless of type, returns a representation of + that string in the native string type, encoding and decoding where + necessary. This assumes ASCII unless told otherwise. + """ + if isinstance(string, builtin_str): + out = string + else: + out = string.decode(encoding) + + return out + + +def unicode_is_ascii(u_string): + """Determine if unicode string only contains ASCII characters. + + :param str u_string: unicode string to check. Must be unicode + and not Python 2 `str`. + :rtype: bool + """ + assert isinstance(u_string, str) + try: + u_string.encode("ascii") + return True + except UnicodeEncodeError: + return False diff --git a/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/requests/adapters.py b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/requests/adapters.py new file mode 100644 index 0000000000000000000000000000000000000000..d3b2d5bb1e56f1293f79f70af4df2d429a347a21 --- /dev/null +++ b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/requests/adapters.py @@ -0,0 +1,584 @@ +""" +requests.adapters +~~~~~~~~~~~~~~~~~ + +This module contains the transport adapters that Requests uses to define +and maintain connections. +""" + +import os.path +import socket # noqa: F401 + +from urllib3.exceptions import ClosedPoolError, ConnectTimeoutError +from urllib3.exceptions import HTTPError as _HTTPError +from urllib3.exceptions import InvalidHeader as _InvalidHeader +from urllib3.exceptions import ( + LocationValueError, + MaxRetryError, + NewConnectionError, + ProtocolError, +) +from urllib3.exceptions import ProxyError as _ProxyError +from urllib3.exceptions import ReadTimeoutError, ResponseError +from urllib3.exceptions import SSLError as _SSLError +from urllib3.poolmanager import PoolManager, proxy_from_url +from urllib3.response import HTTPResponse +from urllib3.util import Timeout as TimeoutSauce +from urllib3.util import parse_url +from urllib3.util.retry import Retry + +from .auth import _basic_auth_str +from .compat import basestring, urlparse +from .cookies import extract_cookies_to_jar +from .exceptions import ( + ConnectionError, + ConnectTimeout, + InvalidHeader, + InvalidProxyURL, + InvalidSchema, + InvalidURL, + ProxyError, + ReadTimeout, + RetryError, + SSLError, +) +from .models import Response +from .structures import CaseInsensitiveDict +from .utils import ( + DEFAULT_CA_BUNDLE_PATH, + extract_zipped_paths, + get_auth_from_url, + get_encoding_from_headers, + prepend_scheme_if_needed, + select_proxy, + urldefragauth, +) + +try: + from urllib3.contrib.socks import SOCKSProxyManager +except ImportError: + + def SOCKSProxyManager(*args, **kwargs): + raise InvalidSchema("Missing dependencies for SOCKS support.") + + +DEFAULT_POOLBLOCK = False +DEFAULT_POOLSIZE = 10 +DEFAULT_RETRIES = 0 +DEFAULT_POOL_TIMEOUT = None + + +class BaseAdapter: + """The Base Transport Adapter""" + + def __init__(self): + super().__init__() + + def send( + self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None + ): + """Sends PreparedRequest object. Returns Response object. + + :param request: The :class:`PreparedRequest ` being sent. + :param stream: (optional) Whether to stream the request content. + :param timeout: (optional) How long to wait for the server to send + data before giving up, as a float, or a :ref:`(connect timeout, + read timeout) ` tuple. + :type timeout: float or tuple + :param verify: (optional) Either a boolean, in which case it controls whether we verify + the server's TLS certificate, or a string, in which case it must be a path + to a CA bundle to use + :param cert: (optional) Any user-provided SSL certificate to be trusted. + :param proxies: (optional) The proxies dictionary to apply to the request. + """ + raise NotImplementedError + + def close(self): + """Cleans up adapter specific items.""" + raise NotImplementedError + + +class HTTPAdapter(BaseAdapter): + """The built-in HTTP Adapter for urllib3. + + Provides a general-case interface for Requests sessions to contact HTTP and + HTTPS urls by implementing the Transport Adapter interface. This class will + usually be created by the :class:`Session ` class under the + covers. + + :param pool_connections: The number of urllib3 connection pools to cache. + :param pool_maxsize: The maximum number of connections to save in the pool. + :param max_retries: The maximum number of retries each connection + should attempt. Note, this applies only to failed DNS lookups, socket + connections and connection timeouts, never to requests where data has + made it to the server. By default, Requests does not retry failed + connections. If you need granular control over the conditions under + which we retry a request, import urllib3's ``Retry`` class and pass + that instead. + :param pool_block: Whether the connection pool should block for connections. + + Usage:: + + >>> import requests + >>> s = requests.Session() + >>> a = requests.adapters.HTTPAdapter(max_retries=3) + >>> s.mount('http://', a) + """ + + __attrs__ = [ + "max_retries", + "config", + "_pool_connections", + "_pool_maxsize", + "_pool_block", + ] + + def __init__( + self, + pool_connections=DEFAULT_POOLSIZE, + pool_maxsize=DEFAULT_POOLSIZE, + max_retries=DEFAULT_RETRIES, + pool_block=DEFAULT_POOLBLOCK, + ): + if max_retries == DEFAULT_RETRIES: + self.max_retries = Retry(0, read=False) + else: + self.max_retries = Retry.from_int(max_retries) + self.config = {} + self.proxy_manager = {} + + super().__init__() + + self._pool_connections = pool_connections + self._pool_maxsize = pool_maxsize + self._pool_block = pool_block + + self.init_poolmanager(pool_connections, pool_maxsize, block=pool_block) + + def __getstate__(self): + return {attr: getattr(self, attr, None) for attr in self.__attrs__} + + def __setstate__(self, state): + # Can't handle by adding 'proxy_manager' to self.__attrs__ because + # self.poolmanager uses a lambda function, which isn't pickleable. + self.proxy_manager = {} + self.config = {} + + for attr, value in state.items(): + setattr(self, attr, value) + + self.init_poolmanager( + self._pool_connections, self._pool_maxsize, block=self._pool_block + ) + + def init_poolmanager( + self, connections, maxsize, block=DEFAULT_POOLBLOCK, **pool_kwargs + ): + """Initializes a urllib3 PoolManager. + + This method should not be called from user code, and is only + exposed for use when subclassing the + :class:`HTTPAdapter `. + + :param connections: The number of urllib3 connection pools to cache. + :param maxsize: The maximum number of connections to save in the pool. + :param block: Block when no free connections are available. + :param pool_kwargs: Extra keyword arguments used to initialize the Pool Manager. + """ + # save these values for pickling + self._pool_connections = connections + self._pool_maxsize = maxsize + self._pool_block = block + + self.poolmanager = PoolManager( + num_pools=connections, + maxsize=maxsize, + block=block, + strict=True, + **pool_kwargs, + ) + + def proxy_manager_for(self, proxy, **proxy_kwargs): + """Return urllib3 ProxyManager for the given proxy. + + This method should not be called from user code, and is only + exposed for use when subclassing the + :class:`HTTPAdapter `. + + :param proxy: The proxy to return a urllib3 ProxyManager for. + :param proxy_kwargs: Extra keyword arguments used to configure the Proxy Manager. + :returns: ProxyManager + :rtype: urllib3.ProxyManager + """ + if proxy in self.proxy_manager: + manager = self.proxy_manager[proxy] + elif proxy.lower().startswith("socks"): + username, password = get_auth_from_url(proxy) + manager = self.proxy_manager[proxy] = SOCKSProxyManager( + proxy, + username=username, + password=password, + num_pools=self._pool_connections, + maxsize=self._pool_maxsize, + block=self._pool_block, + **proxy_kwargs, + ) + else: + proxy_headers = self.proxy_headers(proxy) + manager = self.proxy_manager[proxy] = proxy_from_url( + proxy, + proxy_headers=proxy_headers, + num_pools=self._pool_connections, + maxsize=self._pool_maxsize, + block=self._pool_block, + **proxy_kwargs, + ) + + return manager + + def cert_verify(self, conn, url, verify, cert): + """Verify a SSL certificate. This method should not be called from user + code, and is only exposed for use when subclassing the + :class:`HTTPAdapter `. + + :param conn: The urllib3 connection object associated with the cert. + :param url: The requested URL. + :param verify: Either a boolean, in which case it controls whether we verify + the server's TLS certificate, or a string, in which case it must be a path + to a CA bundle to use + :param cert: The SSL certificate to verify. + """ + if url.lower().startswith("https") and verify: + + cert_loc = None + + # Allow self-specified cert location. + if verify is not True: + cert_loc = verify + + if not cert_loc: + cert_loc = extract_zipped_paths(DEFAULT_CA_BUNDLE_PATH) + + if not cert_loc or not os.path.exists(cert_loc): + raise OSError( + f"Could not find a suitable TLS CA certificate bundle, " + f"invalid path: {cert_loc}" + ) + + conn.cert_reqs = "CERT_REQUIRED" + + if not os.path.isdir(cert_loc): + conn.ca_certs = cert_loc + else: + conn.ca_cert_dir = cert_loc + else: + conn.cert_reqs = "CERT_NONE" + conn.ca_certs = None + conn.ca_cert_dir = None + + if cert: + if not isinstance(cert, basestring): + conn.cert_file = cert[0] + conn.key_file = cert[1] + else: + conn.cert_file = cert + conn.key_file = None + if conn.cert_file and not os.path.exists(conn.cert_file): + raise OSError( + f"Could not find the TLS certificate file, " + f"invalid path: {conn.cert_file}" + ) + if conn.key_file and not os.path.exists(conn.key_file): + raise OSError( + f"Could not find the TLS key file, invalid path: {conn.key_file}" + ) + + def build_response(self, req, resp): + """Builds a :class:`Response ` object from a urllib3 + response. This should not be called from user code, and is only exposed + for use when subclassing the + :class:`HTTPAdapter ` + + :param req: The :class:`PreparedRequest ` used to generate the response. + :param resp: The urllib3 response object. + :rtype: requests.Response + """ + response = Response() + + # Fallback to None if there's no status_code, for whatever reason. + response.status_code = getattr(resp, "status", None) + + # Make headers case-insensitive. + response.headers = CaseInsensitiveDict(getattr(resp, "headers", {})) + + # Set encoding. + response.encoding = get_encoding_from_headers(response.headers) + response.raw = resp + response.reason = response.raw.reason + + if isinstance(req.url, bytes): + response.url = req.url.decode("utf-8") + else: + response.url = req.url + + # Add new cookies from the server. + extract_cookies_to_jar(response.cookies, req, resp) + + # Give the Response some context. + response.request = req + response.connection = self + + return response + + def get_connection(self, url, proxies=None): + """Returns a urllib3 connection for the given URL. This should not be + called from user code, and is only exposed for use when subclassing the + :class:`HTTPAdapter `. + + :param url: The URL to connect to. + :param proxies: (optional) A Requests-style dictionary of proxies used on this request. + :rtype: urllib3.ConnectionPool + """ + proxy = select_proxy(url, proxies) + + if proxy: + proxy = prepend_scheme_if_needed(proxy, "http") + proxy_url = parse_url(proxy) + if not proxy_url.host: + raise InvalidProxyURL( + "Please check proxy URL. It is malformed " + "and could be missing the host." + ) + proxy_manager = self.proxy_manager_for(proxy) + conn = proxy_manager.connection_from_url(url) + else: + # Only scheme should be lower case + parsed = urlparse(url) + url = parsed.geturl() + conn = self.poolmanager.connection_from_url(url) + + return conn + + def close(self): + """Disposes of any internal state. + + Currently, this closes the PoolManager and any active ProxyManager, + which closes any pooled connections. + """ + self.poolmanager.clear() + for proxy in self.proxy_manager.values(): + proxy.clear() + + def request_url(self, request, proxies): + """Obtain the url to use when making the final request. + + If the message is being sent through a HTTP proxy, the full URL has to + be used. Otherwise, we should only use the path portion of the URL. + + This should not be called from user code, and is only exposed for use + when subclassing the + :class:`HTTPAdapter `. + + :param request: The :class:`PreparedRequest ` being sent. + :param proxies: A dictionary of schemes or schemes and hosts to proxy URLs. + :rtype: str + """ + proxy = select_proxy(request.url, proxies) + scheme = urlparse(request.url).scheme + + is_proxied_http_request = proxy and scheme != "https" + using_socks_proxy = False + if proxy: + proxy_scheme = urlparse(proxy).scheme.lower() + using_socks_proxy = proxy_scheme.startswith("socks") + + url = request.path_url + if is_proxied_http_request and not using_socks_proxy: + url = urldefragauth(request.url) + + return url + + def add_headers(self, request, **kwargs): + """Add any headers needed by the connection. As of v2.0 this does + nothing by default, but is left for overriding by users that subclass + the :class:`HTTPAdapter `. + + This should not be called from user code, and is only exposed for use + when subclassing the + :class:`HTTPAdapter `. + + :param request: The :class:`PreparedRequest ` to add headers to. + :param kwargs: The keyword arguments from the call to send(). + """ + pass + + def proxy_headers(self, proxy): + """Returns a dictionary of the headers to add to any request sent + through a proxy. This works with urllib3 magic to ensure that they are + correctly sent to the proxy, rather than in a tunnelled request if + CONNECT is being used. + + This should not be called from user code, and is only exposed for use + when subclassing the + :class:`HTTPAdapter `. + + :param proxy: The url of the proxy being used for this request. + :rtype: dict + """ + headers = {} + username, password = get_auth_from_url(proxy) + + if username: + headers["Proxy-Authorization"] = _basic_auth_str(username, password) + + return headers + + def send( + self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None + ): + """Sends PreparedRequest object. Returns Response object. + + :param request: The :class:`PreparedRequest ` being sent. + :param stream: (optional) Whether to stream the request content. + :param timeout: (optional) How long to wait for the server to send + data before giving up, as a float, or a :ref:`(connect timeout, + read timeout) ` tuple. + :type timeout: float or tuple or urllib3 Timeout object + :param verify: (optional) Either a boolean, in which case it controls whether + we verify the server's TLS certificate, or a string, in which case it + must be a path to a CA bundle to use + :param cert: (optional) Any user-provided SSL certificate to be trusted. + :param proxies: (optional) The proxies dictionary to apply to the request. + :rtype: requests.Response + """ + + try: + conn = self.get_connection(request.url, proxies) + except LocationValueError as e: + raise InvalidURL(e, request=request) + + self.cert_verify(conn, request.url, verify, cert) + url = self.request_url(request, proxies) + self.add_headers( + request, + stream=stream, + timeout=timeout, + verify=verify, + cert=cert, + proxies=proxies, + ) + + chunked = not (request.body is None or "Content-Length" in request.headers) + + if isinstance(timeout, tuple): + try: + connect, read = timeout + timeout = TimeoutSauce(connect=connect, read=read) + except ValueError: + raise ValueError( + f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " + f"or a single float to set both timeouts to the same value." + ) + elif isinstance(timeout, TimeoutSauce): + pass + else: + timeout = TimeoutSauce(connect=timeout, read=timeout) + + try: + if not chunked: + resp = conn.urlopen( + method=request.method, + url=url, + body=request.body, + headers=request.headers, + redirect=False, + assert_same_host=False, + preload_content=False, + decode_content=False, + retries=self.max_retries, + timeout=timeout, + ) + + # Send the request. + else: + if hasattr(conn, "proxy_pool"): + conn = conn.proxy_pool + + low_conn = conn._get_conn(timeout=DEFAULT_POOL_TIMEOUT) + + try: + skip_host = "Host" in request.headers + low_conn.putrequest( + request.method, + url, + skip_accept_encoding=True, + skip_host=skip_host, + ) + + for header, value in request.headers.items(): + low_conn.putheader(header, value) + + low_conn.endheaders() + + for i in request.body: + low_conn.send(hex(len(i))[2:].encode("utf-8")) + low_conn.send(b"\r\n") + low_conn.send(i) + low_conn.send(b"\r\n") + low_conn.send(b"0\r\n\r\n") + + # Receive the response from the server + r = low_conn.getresponse() + + resp = HTTPResponse.from_httplib( + r, + pool=conn, + connection=low_conn, + preload_content=False, + decode_content=False, + ) + except Exception: + # If we hit any problems here, clean up the connection. + # Then, raise so that we can handle the actual exception. + low_conn.close() + raise + + except (ProtocolError, OSError) as err: + raise ConnectionError(err, request=request) + + except MaxRetryError as e: + if isinstance(e.reason, ConnectTimeoutError): + # TODO: Remove this in 3.0.0: see #2811 + if not isinstance(e.reason, NewConnectionError): + raise ConnectTimeout(e, request=request) + + if isinstance(e.reason, ResponseError): + raise RetryError(e, request=request) + + if isinstance(e.reason, _ProxyError): + raise ProxyError(e, request=request) + + if isinstance(e.reason, _SSLError): + # This branch is for urllib3 v1.22 and later. + raise SSLError(e, request=request) + + raise ConnectionError(e, request=request) + + except ClosedPoolError as e: + raise ConnectionError(e, request=request) + + except _ProxyError as e: + raise ProxyError(e) + + except (_SSLError, _HTTPError) as e: + if isinstance(e, _SSLError): + # This branch is for urllib3 versions earlier than v1.22 + raise SSLError(e, request=request) + elif isinstance(e, ReadTimeoutError): + raise ReadTimeout(e, request=request) + elif isinstance(e, _InvalidHeader): + raise InvalidHeader(e, request=request) + else: + raise + + return self.build_response(request, resp) diff --git a/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/requests/api.py b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/requests/api.py new file mode 100644 index 0000000000000000000000000000000000000000..2f71aaed1afc2f43ae5a58d951896b91e0327abc --- /dev/null +++ b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/requests/api.py @@ -0,0 +1,157 @@ +""" +requests.api +~~~~~~~~~~~~ + +This module implements the Requests API. + +:copyright: (c) 2012 by Kenneth Reitz. +:license: Apache2, see LICENSE for more details. +""" + +from . import sessions + + +def request(method, url, **kwargs): + """Constructs and sends a :class:`Request `. + + :param method: method for the new :class:`Request` object: ``GET``, ``OPTIONS``, ``HEAD``, ``POST``, ``PUT``, ``PATCH``, or ``DELETE``. + :param url: URL for the new :class:`Request` object. + :param params: (optional) Dictionary, list of tuples or bytes to send + in the query string for the :class:`Request`. + :param data: (optional) Dictionary, list of tuples, bytes, or file-like + object to send in the body of the :class:`Request`. + :param json: (optional) A JSON serializable Python object to send in the body of the :class:`Request`. + :param headers: (optional) Dictionary of HTTP Headers to send with the :class:`Request`. + :param cookies: (optional) Dict or CookieJar object to send with the :class:`Request`. + :param files: (optional) Dictionary of ``'name': file-like-objects`` (or ``{'name': file-tuple}``) for multipart encoding upload. + ``file-tuple`` can be a 2-tuple ``('filename', fileobj)``, 3-tuple ``('filename', fileobj, 'content_type')`` + or a 4-tuple ``('filename', fileobj, 'content_type', custom_headers)``, where ``'content-type'`` is a string + defining the content type of the given file and ``custom_headers`` a dict-like object containing additional headers + to add for the file. + :param auth: (optional) Auth tuple to enable Basic/Digest/Custom HTTP Auth. + :param timeout: (optional) How many seconds to wait for the server to send data + before giving up, as a float, or a :ref:`(connect timeout, read + timeout) ` tuple. + :type timeout: float or tuple + :param allow_redirects: (optional) Boolean. Enable/disable GET/OPTIONS/POST/PUT/PATCH/DELETE/HEAD redirection. Defaults to ``True``. + :type allow_redirects: bool + :param proxies: (optional) Dictionary mapping protocol to the URL of the proxy. + :param verify: (optional) Either a boolean, in which case it controls whether we verify + the server's TLS certificate, or a string, in which case it must be a path + to a CA bundle to use. Defaults to ``True``. + :param stream: (optional) if ``False``, the response content will be immediately downloaded. + :param cert: (optional) if String, path to ssl client cert file (.pem). If Tuple, ('cert', 'key') pair. + :return: :class:`Response ` object + :rtype: requests.Response + + Usage:: + + >>> import requests + >>> req = requests.request('GET', 'https://httpbin.org/get') + >>> req + + """ + + # By using the 'with' statement we are sure the session is closed, thus we + # avoid leaving sockets open which can trigger a ResourceWarning in some + # cases, and look like a memory leak in others. + with sessions.Session() as session: + return session.request(method=method, url=url, **kwargs) + + +def get(url, params=None, **kwargs): + r"""Sends a GET request. + + :param url: URL for the new :class:`Request` object. + :param params: (optional) Dictionary, list of tuples or bytes to send + in the query string for the :class:`Request`. + :param \*\*kwargs: Optional arguments that ``request`` takes. + :return: :class:`Response ` object + :rtype: requests.Response + """ + + return request("get", url, params=params, **kwargs) + + +def options(url, **kwargs): + r"""Sends an OPTIONS request. + + :param url: URL for the new :class:`Request` object. + :param \*\*kwargs: Optional arguments that ``request`` takes. + :return: :class:`Response ` object + :rtype: requests.Response + """ + + return request("options", url, **kwargs) + + +def head(url, **kwargs): + r"""Sends a HEAD request. + + :param url: URL for the new :class:`Request` object. + :param \*\*kwargs: Optional arguments that ``request`` takes. If + `allow_redirects` is not provided, it will be set to `False` (as + opposed to the default :meth:`request` behavior). + :return: :class:`Response ` object + :rtype: requests.Response + """ + + kwargs.setdefault("allow_redirects", False) + return request("head", url, **kwargs) + + +def post(url, data=None, json=None, **kwargs): + r"""Sends a POST request. + + :param url: URL for the new :class:`Request` object. + :param data: (optional) Dictionary, list of tuples, bytes, or file-like + object to send in the body of the :class:`Request`. + :param json: (optional) json data to send in the body of the :class:`Request`. + :param \*\*kwargs: Optional arguments that ``request`` takes. + :return: :class:`Response ` object + :rtype: requests.Response + """ + + return request("post", url, data=data, json=json, **kwargs) + + +def put(url, data=None, **kwargs): + r"""Sends a PUT request. + + :param url: URL for the new :class:`Request` object. + :param data: (optional) Dictionary, list of tuples, bytes, or file-like + object to send in the body of the :class:`Request`. + :param json: (optional) json data to send in the body of the :class:`Request`. + :param \*\*kwargs: Optional arguments that ``request`` takes. + :return: :class:`Response ` object + :rtype: requests.Response + """ + + return request("put", url, data=data, **kwargs) + + +def patch(url, data=None, **kwargs): + r"""Sends a PATCH request. + + :param url: URL for the new :class:`Request` object. + :param data: (optional) Dictionary, list of tuples, bytes, or file-like + object to send in the body of the :class:`Request`. + :param json: (optional) json data to send in the body of the :class:`Request`. + :param \*\*kwargs: Optional arguments that ``request`` takes. + :return: :class:`Response ` object + :rtype: requests.Response + """ + + return request("patch", url, data=data, **kwargs) + + +def delete(url, **kwargs): + r"""Sends a DELETE request. + + :param url: URL for the new :class:`Request` object. + :param \*\*kwargs: Optional arguments that ``request`` takes. + :return: :class:`Response ` object + :rtype: requests.Response + """ + + return request("delete", url, **kwargs) diff --git a/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/requests/certs.py b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/requests/certs.py new file mode 100644 index 0000000000000000000000000000000000000000..be422c3e91e43bacf60ff3302688df0b28742333 --- /dev/null +++ b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/requests/certs.py @@ -0,0 +1,17 @@ +#!/usr/bin/env python + +""" +requests.certs +~~~~~~~~~~~~~~ + +This module returns the preferred default CA certificate bundle. There is +only one — the one from the certifi package. + +If you are packaging Requests, e.g., for a Linux distribution or a managed +environment, you can change the definition of where() to return a separately +packaged CA bundle. +""" +from certifi import where + +if __name__ == "__main__": + print(where()) diff --git a/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/requests/compat.py b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/requests/compat.py new file mode 100644 index 0000000000000000000000000000000000000000..6776163c94f3d6f61b00d329d4061d6b02afeeb9 --- /dev/null +++ b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/requests/compat.py @@ -0,0 +1,79 @@ +""" +requests.compat +~~~~~~~~~~~~~~~ + +This module previously handled import compatibility issues +between Python 2 and Python 3. It remains for backwards +compatibility until the next major version. +""" + +try: + import chardet +except ImportError: + import charset_normalizer as chardet + +import sys + +# ------- +# Pythons +# ------- + +# Syntax sugar. +_ver = sys.version_info + +#: Python 2.x? +is_py2 = _ver[0] == 2 + +#: Python 3.x? +is_py3 = _ver[0] == 3 + +# json/simplejson module import resolution +has_simplejson = False +try: + import simplejson as json + + has_simplejson = True +except ImportError: + import json + +if has_simplejson: + from simplejson import JSONDecodeError +else: + from json import JSONDecodeError + +# Keep OrderedDict for backwards compatibility. +from collections import OrderedDict +from collections.abc import Callable, Mapping, MutableMapping +from http import cookiejar as cookielib +from http.cookies import Morsel +from io import StringIO + +# -------------- +# Legacy Imports +# -------------- +from urllib.parse import ( + quote, + quote_plus, + unquote, + unquote_plus, + urldefrag, + urlencode, + urljoin, + urlparse, + urlsplit, + urlunparse, +) +from urllib.request import ( + getproxies, + getproxies_environment, + parse_http_list, + proxy_bypass, + proxy_bypass_environment, +) + +builtin_str = str +str = str +bytes = bytes +basestring = (str, bytes) +numeric_types = (int, float) +integer_types = (int,) diff --git a/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/requests/cookies.py b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/requests/cookies.py new file mode 100644 index 0000000000000000000000000000000000000000..bf54ab237e410603061b8cec8fd195912d3cfb08 --- /dev/null +++ b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/requests/cookies.py @@ -0,0 +1,561 @@ +""" +requests.cookies +~~~~~~~~~~~~~~~~ + +Compatibility code to be able to use `cookielib.CookieJar` with requests. + +requests.utils imports from here, so be careful with imports. +""" + +import calendar +import copy +import time + +from ._internal_utils import to_native_string +from .compat import Morsel, MutableMapping, cookielib, urlparse, urlunparse + +try: + import threading +except ImportError: + import dummy_threading as threading + + +class MockRequest: + """Wraps a `requests.Request` to mimic a `urllib2.Request`. + + The code in `cookielib.CookieJar` expects this interface in order to correctly + manage cookie policies, i.e., determine whether a cookie can be set, given the + domains of the request and the cookie. + + The original request object is read-only. The client is responsible for collecting + the new headers via `get_new_headers()` and interpreting them appropriately. You + probably want `get_cookie_header`, defined below. + """ + + def __init__(self, request): + self._r = request + self._new_headers = {} + self.type = urlparse(self._r.url).scheme + + def get_type(self): + return self.type + + def get_host(self): + return urlparse(self._r.url).netloc + + def get_origin_req_host(self): + return self.get_host() + + def get_full_url(self): + # Only return the response's URL if the user hadn't set the Host + # header + if not self._r.headers.get("Host"): + return self._r.url + # If they did set it, retrieve it and reconstruct the expected domain + host = to_native_string(self._r.headers["Host"], encoding="utf-8") + parsed = urlparse(self._r.url) + # Reconstruct the URL as we expect it + return urlunparse( + [ + parsed.scheme, + host, + parsed.path, + parsed.params, + parsed.query, + parsed.fragment, + ] + ) + + def is_unverifiable(self): + return True + + def has_header(self, name): + return name in self._r.headers or name in self._new_headers + + def get_header(self, name, default=None): + return self._r.headers.get(name, self._new_headers.get(name, default)) + + def add_header(self, key, val): + """cookielib has no legitimate use for this method; add it back if you find one.""" + raise NotImplementedError( + "Cookie headers should be added with add_unredirected_header()" + ) + + def add_unredirected_header(self, name, value): + self._new_headers[name] = value + + def get_new_headers(self): + return self._new_headers + + @property + def unverifiable(self): + return self.is_unverifiable() + + @property + def origin_req_host(self): + return self.get_origin_req_host() + + @property + def host(self): + return self.get_host() + + +class MockResponse: + """Wraps a `httplib.HTTPMessage` to mimic a `urllib.addinfourl`. + + ...what? Basically, expose the parsed HTTP headers from the server response + the way `cookielib` expects to see them. + """ + + def __init__(self, headers): + """Make a MockResponse for `cookielib` to read. + + :param headers: a httplib.HTTPMessage or analogous carrying the headers + """ + self._headers = headers + + def info(self): + return self._headers + + def getheaders(self, name): + self._headers.getheaders(name) + + +def extract_cookies_to_jar(jar, request, response): + """Extract the cookies from the response into a CookieJar. + + :param jar: cookielib.CookieJar (not necessarily a RequestsCookieJar) + :param request: our own requests.Request object + :param response: urllib3.HTTPResponse object + """ + if not (hasattr(response, "_original_response") and response._original_response): + return + # the _original_response field is the wrapped httplib.HTTPResponse object, + req = MockRequest(request) + # pull out the HTTPMessage with the headers and put it in the mock: + res = MockResponse(response._original_response.msg) + jar.extract_cookies(res, req) + + +def get_cookie_header(jar, request): + """ + Produce an appropriate Cookie header string to be sent with `request`, or None. + + :rtype: str + """ + r = MockRequest(request) + jar.add_cookie_header(r) + return r.get_new_headers().get("Cookie") + + +def remove_cookie_by_name(cookiejar, name, domain=None, path=None): + """Unsets a cookie by name, by default over all domains and paths. + + Wraps CookieJar.clear(), is O(n). + """ + clearables = [] + for cookie in cookiejar: + if cookie.name != name: + continue + if domain is not None and domain != cookie.domain: + continue + if path is not None and path != cookie.path: + continue + clearables.append((cookie.domain, cookie.path, cookie.name)) + + for domain, path, name in clearables: + cookiejar.clear(domain, path, name) + + +class CookieConflictError(RuntimeError): + """There are two cookies that meet the criteria specified in the cookie jar. + Use .get and .set and include domain and path args in order to be more specific. + """ + + +class RequestsCookieJar(cookielib.CookieJar, MutableMapping): + """Compatibility class; is a cookielib.CookieJar, but exposes a dict + interface. + + This is the CookieJar we create by default for requests and sessions that + don't specify one, since some clients may expect response.cookies and + session.cookies to support dict operations. + + Requests does not use the dict interface internally; it's just for + compatibility with external client code. All requests code should work + out of the box with externally provided instances of ``CookieJar``, e.g. + ``LWPCookieJar`` and ``FileCookieJar``. + + Unlike a regular CookieJar, this class is pickleable. + + .. warning:: dictionary operations that are normally O(1) may be O(n). + """ + + def get(self, name, default=None, domain=None, path=None): + """Dict-like get() that also supports optional domain and path args in + order to resolve naming collisions from using one cookie jar over + multiple domains. + + .. warning:: operation is O(n), not O(1). + """ + try: + return self._find_no_duplicates(name, domain, path) + except KeyError: + return default + + def set(self, name, value, **kwargs): + """Dict-like set() that also supports optional domain and path args in + order to resolve naming collisions from using one cookie jar over + multiple domains. + """ + # support client code that unsets cookies by assignment of a None value: + if value is None: + remove_cookie_by_name( + self, name, domain=kwargs.get("domain"), path=kwargs.get("path") + ) + return + + if isinstance(value, Morsel): + c = morsel_to_cookie(value) + else: + c = create_cookie(name, value, **kwargs) + self.set_cookie(c) + return c + + def iterkeys(self): + """Dict-like iterkeys() that returns an iterator of names of cookies + from the jar. + + .. seealso:: itervalues() and iteritems(). + """ + for cookie in iter(self): + yield cookie.name + + def keys(self): + """Dict-like keys() that returns a list of names of cookies from the + jar. + + .. seealso:: values() and items(). + """ + return list(self.iterkeys()) + + def itervalues(self): + """Dict-like itervalues() that returns an iterator of values of cookies + from the jar. + + .. seealso:: iterkeys() and iteritems(). + """ + for cookie in iter(self): + yield cookie.value + + def values(self): + """Dict-like values() that returns a list of values of cookies from the + jar. + + .. seealso:: keys() and items(). + """ + return list(self.itervalues()) + + def iteritems(self): + """Dict-like iteritems() that returns an iterator of name-value tuples + from the jar. + + .. seealso:: iterkeys() and itervalues(). + """ + for cookie in iter(self): + yield cookie.name, cookie.value + + def items(self): + """Dict-like items() that returns a list of name-value tuples from the + jar. Allows client-code to call ``dict(RequestsCookieJar)`` and get a + vanilla python dict of key value pairs. + + .. seealso:: keys() and values(). + """ + return list(self.iteritems()) + + def list_domains(self): + """Utility method to list all the domains in the jar.""" + domains = [] + for cookie in iter(self): + if cookie.domain not in domains: + domains.append(cookie.domain) + return domains + + def list_paths(self): + """Utility method to list all the paths in the jar.""" + paths = [] + for cookie in iter(self): + if cookie.path not in paths: + paths.append(cookie.path) + return paths + + def multiple_domains(self): + """Returns True if there are multiple domains in the jar. + Returns False otherwise. + + :rtype: bool + """ + domains = [] + for cookie in iter(self): + if cookie.domain is not None and cookie.domain in domains: + return True + domains.append(cookie.domain) + return False # there is only one domain in jar + + def get_dict(self, domain=None, path=None): + """Takes as an argument an optional domain and path and returns a plain + old Python dict of name-value pairs of cookies that meet the + requirements. + + :rtype: dict + """ + dictionary = {} + for cookie in iter(self): + if (domain is None or cookie.domain == domain) and ( + path is None or cookie.path == path + ): + dictionary[cookie.name] = cookie.value + return dictionary + + def __contains__(self, name): + try: + return super().__contains__(name) + except CookieConflictError: + return True + + def __getitem__(self, name): + """Dict-like __getitem__() for compatibility with client code. Throws + exception if there are more than one cookie with name. In that case, + use the more explicit get() method instead. + + .. warning:: operation is O(n), not O(1). + """ + return self._find_no_duplicates(name) + + def __setitem__(self, name, value): + """Dict-like __setitem__ for compatibility with client code. Throws + exception if there is already a cookie of that name in the jar. In that + case, use the more explicit set() method instead. + """ + self.set(name, value) + + def __delitem__(self, name): + """Deletes a cookie given a name. Wraps ``cookielib.CookieJar``'s + ``remove_cookie_by_name()``. + """ + remove_cookie_by_name(self, name) + + def set_cookie(self, cookie, *args, **kwargs): + if ( + hasattr(cookie.value, "startswith") + and cookie.value.startswith('"') + and cookie.value.endswith('"') + ): + cookie.value = cookie.value.replace('\\"', "") + return super().set_cookie(cookie, *args, **kwargs) + + def update(self, other): + """Updates this jar with cookies from another CookieJar or dict-like""" + if isinstance(other, cookielib.CookieJar): + for cookie in other: + self.set_cookie(copy.copy(cookie)) + else: + super().update(other) + + def _find(self, name, domain=None, path=None): + """Requests uses this method internally to get cookie values. + + If there are conflicting cookies, _find arbitrarily chooses one. + See _find_no_duplicates if you want an exception thrown if there are + conflicting cookies. + + :param name: a string containing name of cookie + :param domain: (optional) string containing domain of cookie + :param path: (optional) string containing path of cookie + :return: cookie.value + """ + for cookie in iter(self): + if cookie.name == name: + if domain is None or cookie.domain == domain: + if path is None or cookie.path == path: + return cookie.value + + raise KeyError(f"name={name!r}, domain={domain!r}, path={path!r}") + + def _find_no_duplicates(self, name, domain=None, path=None): + """Both ``__get_item__`` and ``get`` call this function: it's never + used elsewhere in Requests. + + :param name: a string containing name of cookie + :param domain: (optional) string containing domain of cookie + :param path: (optional) string containing path of cookie + :raises KeyError: if cookie is not found + :raises CookieConflictError: if there are multiple cookies + that match name and optionally domain and path + :return: cookie.value + """ + toReturn = None + for cookie in iter(self): + if cookie.name == name: + if domain is None or cookie.domain == domain: + if path is None or cookie.path == path: + if toReturn is not None: + # if there are multiple cookies that meet passed in criteria + raise CookieConflictError( + f"There are multiple cookies with name, {name!r}" + ) + # we will eventually return this as long as no cookie conflict + toReturn = cookie.value + + if toReturn: + return toReturn + raise KeyError(f"name={name!r}, domain={domain!r}, path={path!r}") + + def __getstate__(self): + """Unlike a normal CookieJar, this class is pickleable.""" + state = self.__dict__.copy() + # remove the unpickleable RLock object + state.pop("_cookies_lock") + return state + + def __setstate__(self, state): + """Unlike a normal CookieJar, this class is pickleable.""" + self.__dict__.update(state) + if "_cookies_lock" not in self.__dict__: + self._cookies_lock = threading.RLock() + + def copy(self): + """Return a copy of this RequestsCookieJar.""" + new_cj = RequestsCookieJar() + new_cj.set_policy(self.get_policy()) + new_cj.update(self) + return new_cj + + def get_policy(self): + """Return the CookiePolicy instance used.""" + return self._policy + + +def _copy_cookie_jar(jar): + if jar is None: + return None + + if hasattr(jar, "copy"): + # We're dealing with an instance of RequestsCookieJar + return jar.copy() + # We're dealing with a generic CookieJar instance + new_jar = copy.copy(jar) + new_jar.clear() + for cookie in jar: + new_jar.set_cookie(copy.copy(cookie)) + return new_jar + + +def create_cookie(name, value, **kwargs): + """Make a cookie from underspecified parameters. + + By default, the pair of `name` and `value` will be set for the domain '' + and sent on every request (this is sometimes called a "supercookie"). + """ + result = { + "version": 0, + "name": name, + "value": value, + "port": None, + "domain": "", + "path": "/", + "secure": False, + "expires": None, + "discard": True, + "comment": None, + "comment_url": None, + "rest": {"HttpOnly": None}, + "rfc2109": False, + } + + badargs = set(kwargs) - set(result) + if badargs: + raise TypeError( + f"create_cookie() got unexpected keyword arguments: {list(badargs)}" + ) + + result.update(kwargs) + result["port_specified"] = bool(result["port"]) + result["domain_specified"] = bool(result["domain"]) + result["domain_initial_dot"] = result["domain"].startswith(".") + result["path_specified"] = bool(result["path"]) + + return cookielib.Cookie(**result) + + +def morsel_to_cookie(morsel): + """Convert a Morsel object into a Cookie containing the one k/v pair.""" + + expires = None + if morsel["max-age"]: + try: + expires = int(time.time() + int(morsel["max-age"])) + except ValueError: + raise TypeError(f"max-age: {morsel['max-age']} must be integer") + elif morsel["expires"]: + time_template = "%a, %d-%b-%Y %H:%M:%S GMT" + expires = calendar.timegm(time.strptime(morsel["expires"], time_template)) + return create_cookie( + comment=morsel["comment"], + comment_url=bool(morsel["comment"]), + discard=False, + domain=morsel["domain"], + expires=expires, + name=morsel.key, + path=morsel["path"], + port=None, + rest={"HttpOnly": morsel["httponly"]}, + rfc2109=False, + secure=bool(morsel["secure"]), + value=morsel.value, + version=morsel["version"] or 0, + ) + + +def cookiejar_from_dict(cookie_dict, cookiejar=None, overwrite=True): + """Returns a CookieJar from a key/value dictionary. + + :param cookie_dict: Dict of key/values to insert into CookieJar. + :param cookiejar: (optional) A cookiejar to add the cookies to. + :param overwrite: (optional) If False, will not replace cookies + already in the jar with new ones. + :rtype: CookieJar + """ + if cookiejar is None: + cookiejar = RequestsCookieJar() + + if cookie_dict is not None: + names_from_jar = [cookie.name for cookie in cookiejar] + for name in cookie_dict: + if overwrite or (name not in names_from_jar): + cookiejar.set_cookie(create_cookie(name, cookie_dict[name])) + + return cookiejar + + +def merge_cookies(cookiejar, cookies): + """Add cookies to cookiejar and returns a merged CookieJar. + + :param cookiejar: CookieJar object to add the cookies to. + :param cookies: Dictionary or CookieJar object to be added. + :rtype: CookieJar + """ + if not isinstance(cookiejar, cookielib.CookieJar): + raise ValueError("You can only merge into CookieJar") + + if isinstance(cookies, dict): + cookiejar = cookiejar_from_dict(cookies, cookiejar=cookiejar, overwrite=False) + elif isinstance(cookies, cookielib.CookieJar): + try: + cookiejar.update(cookies) + except AttributeError: + for cookie_in_jar in cookies: + cookiejar.set_cookie(cookie_in_jar) + + return cookiejar diff --git a/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/requests/exceptions.py b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/requests/exceptions.py new file mode 100644 index 0000000000000000000000000000000000000000..e1cedf883d3eadcbfda91967d36b7c59b8367e76 --- /dev/null +++ b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/requests/exceptions.py @@ -0,0 +1,141 @@ +""" +requests.exceptions +~~~~~~~~~~~~~~~~~~~ + +This module contains the set of Requests' exceptions. +""" +from urllib3.exceptions import HTTPError as BaseHTTPError + +from .compat import JSONDecodeError as CompatJSONDecodeError + + +class RequestException(IOError): + """There was an ambiguous exception that occurred while handling your + request. + """ + + def __init__(self, *args, **kwargs): + """Initialize RequestException with `request` and `response` objects.""" + response = kwargs.pop("response", None) + self.response = response + self.request = kwargs.pop("request", None) + if response is not None and not self.request and hasattr(response, "request"): + self.request = self.response.request + super().__init__(*args, **kwargs) + + +class InvalidJSONError(RequestException): + """A JSON error occurred.""" + + +class JSONDecodeError(InvalidJSONError, CompatJSONDecodeError): + """Couldn't decode the text into json""" + + def __init__(self, *args, **kwargs): + """ + Construct the JSONDecodeError instance first with all + args. Then use it's args to construct the IOError so that + the json specific args aren't used as IOError specific args + and the error message from JSONDecodeError is preserved. + """ + CompatJSONDecodeError.__init__(self, *args) + InvalidJSONError.__init__(self, *self.args, **kwargs) + + +class HTTPError(RequestException): + """An HTTP error occurred.""" + + +class ConnectionError(RequestException): + """A Connection error occurred.""" + + +class ProxyError(ConnectionError): + """A proxy error occurred.""" + + +class SSLError(ConnectionError): + """An SSL error occurred.""" + + +class Timeout(RequestException): + """The request timed out. + + Catching this error will catch both + :exc:`~requests.exceptions.ConnectTimeout` and + :exc:`~requests.exceptions.ReadTimeout` errors. + """ + + +class ConnectTimeout(ConnectionError, Timeout): + """The request timed out while trying to connect to the remote server. + + Requests that produced this error are safe to retry. + """ + + +class ReadTimeout(Timeout): + """The server did not send any data in the allotted amount of time.""" + + +class URLRequired(RequestException): + """A valid URL is required to make a request.""" + + +class TooManyRedirects(RequestException): + """Too many redirects.""" + + +class MissingSchema(RequestException, ValueError): + """The URL scheme (e.g. http or https) is missing.""" + + +class InvalidSchema(RequestException, ValueError): + """The URL scheme provided is either invalid or unsupported.""" + + +class InvalidURL(RequestException, ValueError): + """The URL provided was somehow invalid.""" + + +class InvalidHeader(RequestException, ValueError): + """The header value provided was somehow invalid.""" + + +class InvalidProxyURL(InvalidURL): + """The proxy URL provided is invalid.""" + + +class ChunkedEncodingError(RequestException): + """The server declared chunked encoding but sent an invalid chunk.""" + + +class ContentDecodingError(RequestException, BaseHTTPError): + """Failed to decode response content.""" + + +class StreamConsumedError(RequestException, TypeError): + """The content for this response was already consumed.""" + + +class RetryError(RequestException): + """Custom retries logic failed""" + + +class UnrewindableBodyError(RequestException): + """Requests encountered an error when trying to rewind a body.""" + + +# Warnings + + +class RequestsWarning(Warning): + """Base warning for Requests.""" + + +class FileModeWarning(RequestsWarning, DeprecationWarning): + """A file was opened in text mode, but Requests determined its binary length.""" + + +class RequestsDependencyWarning(RequestsWarning): + """An imported dependency doesn't match the expected version range.""" diff --git a/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/requests/help.py b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/requests/help.py new file mode 100644 index 0000000000000000000000000000000000000000..8fbcd6560a8fe2c8a07e3bd1441a81e0db9cb689 --- /dev/null +++ b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/requests/help.py @@ -0,0 +1,134 @@ +"""Module containing bug report helper(s).""" + +import json +import platform +import ssl +import sys + +import idna +import urllib3 + +from . import __version__ as requests_version + +try: + import charset_normalizer +except ImportError: + charset_normalizer = None + +try: + import chardet +except ImportError: + chardet = None + +try: + from urllib3.contrib import pyopenssl +except ImportError: + pyopenssl = None + OpenSSL = None + cryptography = None +else: + import cryptography + import OpenSSL + + +def _implementation(): + """Return a dict with the Python implementation and version. + + Provide both the name and the version of the Python implementation + currently running. For example, on CPython 3.10.3 it will return + {'name': 'CPython', 'version': '3.10.3'}. + + This function works best on CPython and PyPy: in particular, it probably + doesn't work for Jython or IronPython. Future investigation should be done + to work out the correct shape of the code for those platforms. + """ + implementation = platform.python_implementation() + + if implementation == "CPython": + implementation_version = platform.python_version() + elif implementation == "PyPy": + implementation_version = "{}.{}.{}".format( + sys.pypy_version_info.major, + sys.pypy_version_info.minor, + sys.pypy_version_info.micro, + ) + if sys.pypy_version_info.releaselevel != "final": + implementation_version = "".join( + [implementation_version, sys.pypy_version_info.releaselevel] + ) + elif implementation == "Jython": + implementation_version = platform.python_version() # Complete Guess + elif implementation == "IronPython": + implementation_version = platform.python_version() # Complete Guess + else: + implementation_version = "Unknown" + + return {"name": implementation, "version": implementation_version} + + +def info(): + """Generate information for a bug report.""" + try: + platform_info = { + "system": platform.system(), + "release": platform.release(), + } + except OSError: + platform_info = { + "system": "Unknown", + "release": "Unknown", + } + + implementation_info = _implementation() + urllib3_info = {"version": urllib3.__version__} + charset_normalizer_info = {"version": None} + chardet_info = {"version": None} + if charset_normalizer: + charset_normalizer_info = {"version": charset_normalizer.__version__} + if chardet: + chardet_info = {"version": chardet.__version__} + + pyopenssl_info = { + "version": None, + "openssl_version": "", + } + if OpenSSL: + pyopenssl_info = { + "version": OpenSSL.__version__, + "openssl_version": f"{OpenSSL.SSL.OPENSSL_VERSION_NUMBER:x}", + } + cryptography_info = { + "version": getattr(cryptography, "__version__", ""), + } + idna_info = { + "version": getattr(idna, "__version__", ""), + } + + system_ssl = ssl.OPENSSL_VERSION_NUMBER + system_ssl_info = {"version": f"{system_ssl:x}" if system_ssl is not None else ""} + + return { + "platform": platform_info, + "implementation": implementation_info, + "system_ssl": system_ssl_info, + "using_pyopenssl": pyopenssl is not None, + "using_charset_normalizer": chardet is None, + "pyOpenSSL": pyopenssl_info, + "urllib3": urllib3_info, + "chardet": chardet_info, + "charset_normalizer": charset_normalizer_info, + "cryptography": cryptography_info, + "idna": idna_info, + "requests": { + "version": requests_version, + }, + } + + +def main(): + """Pretty-print the bug information as JSON.""" + print(json.dumps(info(), sort_keys=True, indent=2)) + + +if __name__ == "__main__": + main() diff --git a/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/requests/hooks.py b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/requests/hooks.py new file mode 100644 index 0000000000000000000000000000000000000000..d181ba2ec2e55d274897315887b78fbdca757da8 --- /dev/null +++ b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/requests/hooks.py @@ -0,0 +1,33 @@ +""" +requests.hooks +~~~~~~~~~~~~~~ + +This module provides the capabilities for the Requests hooks system. + +Available hooks: + +``response``: + The response generated from a Request. +""" +HOOKS = ["response"] + + +def default_hooks(): + return {event: [] for event in HOOKS} + + +# TODO: response is the only one + + +def dispatch_hook(key, hooks, hook_data, **kwargs): + """Dispatches a hook dictionary on a given piece of data.""" + hooks = hooks or {} + hooks = hooks.get(key) + if hooks: + if hasattr(hooks, "__call__"): + hooks = [hooks] + for hook in hooks: + _hook_data = hook(hook_data, **kwargs) + if _hook_data is not None: + hook_data = _hook_data + return hook_data diff --git a/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/requests/models.py b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/requests/models.py new file mode 100644 index 0000000000000000000000000000000000000000..7e1522837fc895e0bffab045c6cec7bcc14dc8e2 --- /dev/null +++ b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/requests/models.py @@ -0,0 +1,1035 @@ +""" +requests.models +~~~~~~~~~~~~~~~ + +This module contains the primary objects that power Requests. +""" + +import datetime + +# Import encoding now, to avoid implicit import later. +# Implicit import within threads may cause LookupError when standard library is in a ZIP, +# such as in Embedded Python. See https://github.com/psf/requests/issues/3578. +import encodings.idna # noqa: F401 +from io import UnsupportedOperation + +from urllib3.exceptions import ( + DecodeError, + LocationParseError, + ProtocolError, + ReadTimeoutError, + SSLError, +) +from urllib3.fields import RequestField +from urllib3.filepost import encode_multipart_formdata +from urllib3.util import parse_url + +from ._internal_utils import to_native_string, unicode_is_ascii +from .auth import HTTPBasicAuth +from .compat import ( + Callable, + JSONDecodeError, + Mapping, + basestring, + builtin_str, + chardet, + cookielib, +) +from .compat import json as complexjson +from .compat import urlencode, urlsplit, urlunparse +from .cookies import _copy_cookie_jar, cookiejar_from_dict, get_cookie_header +from .exceptions import ( + ChunkedEncodingError, + ConnectionError, + ContentDecodingError, + HTTPError, + InvalidJSONError, + InvalidURL, +) +from .exceptions import JSONDecodeError as RequestsJSONDecodeError +from .exceptions import MissingSchema +from .exceptions import SSLError as RequestsSSLError +from .exceptions import StreamConsumedError +from .hooks import default_hooks +from .status_codes import codes +from .structures import CaseInsensitiveDict +from .utils import ( + check_header_validity, + get_auth_from_url, + guess_filename, + guess_json_utf, + iter_slices, + parse_header_links, + requote_uri, + stream_decode_response_unicode, + super_len, + to_key_val_list, +) + +#: The set of HTTP status codes that indicate an automatically +#: processable redirect. +REDIRECT_STATI = ( + codes.moved, # 301 + codes.found, # 302 + codes.other, # 303 + codes.temporary_redirect, # 307 + codes.permanent_redirect, # 308 +) + +DEFAULT_REDIRECT_LIMIT = 30 +CONTENT_CHUNK_SIZE = 10 * 1024 +ITER_CHUNK_SIZE = 512 + + +class RequestEncodingMixin: + @property + def path_url(self): + """Build the path URL to use.""" + + url = [] + + p = urlsplit(self.url) + + path = p.path + if not path: + path = "/" + + url.append(path) + + query = p.query + if query: + url.append("?") + url.append(query) + + return "".join(url) + + @staticmethod + def _encode_params(data): + """Encode parameters in a piece of data. + + Will successfully encode parameters when passed as a dict or a list of + 2-tuples. Order is retained if data is a list of 2-tuples but arbitrary + if parameters are supplied as a dict. + """ + + if isinstance(data, (str, bytes)): + return data + elif hasattr(data, "read"): + return data + elif hasattr(data, "__iter__"): + result = [] + for k, vs in to_key_val_list(data): + if isinstance(vs, basestring) or not hasattr(vs, "__iter__"): + vs = [vs] + for v in vs: + if v is not None: + result.append( + ( + k.encode("utf-8") if isinstance(k, str) else k, + v.encode("utf-8") if isinstance(v, str) else v, + ) + ) + return urlencode(result, doseq=True) + else: + return data + + @staticmethod + def _encode_files(files, data): + """Build the body for a multipart/form-data request. + + Will successfully encode files when passed as a dict or a list of + tuples. Order is retained if data is a list of tuples but arbitrary + if parameters are supplied as a dict. + The tuples may be 2-tuples (filename, fileobj), 3-tuples (filename, fileobj, contentype) + or 4-tuples (filename, fileobj, contentype, custom_headers). + """ + if not files: + raise ValueError("Files must be provided.") + elif isinstance(data, basestring): + raise ValueError("Data must not be a string.") + + new_fields = [] + fields = to_key_val_list(data or {}) + files = to_key_val_list(files or {}) + + for field, val in fields: + if isinstance(val, basestring) or not hasattr(val, "__iter__"): + val = [val] + for v in val: + if v is not None: + # Don't call str() on bytestrings: in Py3 it all goes wrong. + if not isinstance(v, bytes): + v = str(v) + + new_fields.append( + ( + field.decode("utf-8") + if isinstance(field, bytes) + else field, + v.encode("utf-8") if isinstance(v, str) else v, + ) + ) + + for (k, v) in files: + # support for explicit filename + ft = None + fh = None + if isinstance(v, (tuple, list)): + if len(v) == 2: + fn, fp = v + elif len(v) == 3: + fn, fp, ft = v + else: + fn, fp, ft, fh = v + else: + fn = guess_filename(v) or k + fp = v + + if isinstance(fp, (str, bytes, bytearray)): + fdata = fp + elif hasattr(fp, "read"): + fdata = fp.read() + elif fp is None: + continue + else: + fdata = fp + + rf = RequestField(name=k, data=fdata, filename=fn, headers=fh) + rf.make_multipart(content_type=ft) + new_fields.append(rf) + + body, content_type = encode_multipart_formdata(new_fields) + + return body, content_type + + +class RequestHooksMixin: + def register_hook(self, event, hook): + """Properly register a hook.""" + + if event not in self.hooks: + raise ValueError(f'Unsupported event specified, with event name "{event}"') + + if isinstance(hook, Callable): + self.hooks[event].append(hook) + elif hasattr(hook, "__iter__"): + self.hooks[event].extend(h for h in hook if isinstance(h, Callable)) + + def deregister_hook(self, event, hook): + """Deregister a previously registered hook. + Returns True if the hook existed, False if not. + """ + + try: + self.hooks[event].remove(hook) + return True + except ValueError: + return False + + +class Request(RequestHooksMixin): + """A user-created :class:`Request ` object. + + Used to prepare a :class:`PreparedRequest `, which is sent to the server. + + :param method: HTTP method to use. + :param url: URL to send. + :param headers: dictionary of headers to send. + :param files: dictionary of {filename: fileobject} files to multipart upload. + :param data: the body to attach to the request. If a dictionary or + list of tuples ``[(key, value)]`` is provided, form-encoding will + take place. + :param json: json for the body to attach to the request (if files or data is not specified). + :param params: URL parameters to append to the URL. If a dictionary or + list of tuples ``[(key, value)]`` is provided, form-encoding will + take place. + :param auth: Auth handler or (user, pass) tuple. + :param cookies: dictionary or CookieJar of cookies to attach to this request. + :param hooks: dictionary of callback hooks, for internal usage. + + Usage:: + + >>> import requests + >>> req = requests.Request('GET', 'https://httpbin.org/get') + >>> req.prepare() + + """ + + def __init__( + self, + method=None, + url=None, + headers=None, + files=None, + data=None, + params=None, + auth=None, + cookies=None, + hooks=None, + json=None, + ): + + # Default empty dicts for dict params. + data = [] if data is None else data + files = [] if files is None else files + headers = {} if headers is None else headers + params = {} if params is None else params + hooks = {} if hooks is None else hooks + + self.hooks = default_hooks() + for (k, v) in list(hooks.items()): + self.register_hook(event=k, hook=v) + + self.method = method + self.url = url + self.headers = headers + self.files = files + self.data = data + self.json = json + self.params = params + self.auth = auth + self.cookies = cookies + + def __repr__(self): + return f"" + + def prepare(self): + """Constructs a :class:`PreparedRequest ` for transmission and returns it.""" + p = PreparedRequest() + p.prepare( + method=self.method, + url=self.url, + headers=self.headers, + files=self.files, + data=self.data, + json=self.json, + params=self.params, + auth=self.auth, + cookies=self.cookies, + hooks=self.hooks, + ) + return p + + +class PreparedRequest(RequestEncodingMixin, RequestHooksMixin): + """The fully mutable :class:`PreparedRequest ` object, + containing the exact bytes that will be sent to the server. + + Instances are generated from a :class:`Request ` object, and + should not be instantiated manually; doing so may produce undesirable + effects. + + Usage:: + + >>> import requests + >>> req = requests.Request('GET', 'https://httpbin.org/get') + >>> r = req.prepare() + >>> r + + + >>> s = requests.Session() + >>> s.send(r) + + """ + + def __init__(self): + #: HTTP verb to send to the server. + self.method = None + #: HTTP URL to send the request to. + self.url = None + #: dictionary of HTTP headers. + self.headers = None + # The `CookieJar` used to create the Cookie header will be stored here + # after prepare_cookies is called + self._cookies = None + #: request body to send to the server. + self.body = None + #: dictionary of callback hooks, for internal usage. + self.hooks = default_hooks() + #: integer denoting starting position of a readable file-like body. + self._body_position = None + + def prepare( + self, + method=None, + url=None, + headers=None, + files=None, + data=None, + params=None, + auth=None, + cookies=None, + hooks=None, + json=None, + ): + """Prepares the entire request with the given parameters.""" + + self.prepare_method(method) + self.prepare_url(url, params) + self.prepare_headers(headers) + self.prepare_cookies(cookies) + self.prepare_body(data, files, json) + self.prepare_auth(auth, url) + + # Note that prepare_auth must be last to enable authentication schemes + # such as OAuth to work on a fully prepared request. + + # This MUST go after prepare_auth. Authenticators could add a hook + self.prepare_hooks(hooks) + + def __repr__(self): + return f"" + + def copy(self): + p = PreparedRequest() + p.method = self.method + p.url = self.url + p.headers = self.headers.copy() if self.headers is not None else None + p._cookies = _copy_cookie_jar(self._cookies) + p.body = self.body + p.hooks = self.hooks + p._body_position = self._body_position + return p + + def prepare_method(self, method): + """Prepares the given HTTP method.""" + self.method = method + if self.method is not None: + self.method = to_native_string(self.method.upper()) + + @staticmethod + def _get_idna_encoded_host(host): + import idna + + try: + host = idna.encode(host, uts46=True).decode("utf-8") + except idna.IDNAError: + raise UnicodeError + return host + + def prepare_url(self, url, params): + """Prepares the given HTTP URL.""" + #: Accept objects that have string representations. + #: We're unable to blindly call unicode/str functions + #: as this will include the bytestring indicator (b'') + #: on python 3.x. + #: https://github.com/psf/requests/pull/2238 + if isinstance(url, bytes): + url = url.decode("utf8") + else: + url = str(url) + + # Remove leading whitespaces from url + url = url.lstrip() + + # Don't do any URL preparation for non-HTTP schemes like `mailto`, + # `data` etc to work around exceptions from `url_parse`, which + # handles RFC 3986 only. + if ":" in url and not url.lower().startswith("http"): + self.url = url + return + + # Support for unicode domain names and paths. + try: + scheme, auth, host, port, path, query, fragment = parse_url(url) + except LocationParseError as e: + raise InvalidURL(*e.args) + + if not scheme: + raise MissingSchema( + f"Invalid URL {url!r}: No scheme supplied. " + f"Perhaps you meant http://{url}?" + ) + + if not host: + raise InvalidURL(f"Invalid URL {url!r}: No host supplied") + + # In general, we want to try IDNA encoding the hostname if the string contains + # non-ASCII characters. This allows users to automatically get the correct IDNA + # behaviour. For strings containing only ASCII characters, we need to also verify + # it doesn't start with a wildcard (*), before allowing the unencoded hostname. + if not unicode_is_ascii(host): + try: + host = self._get_idna_encoded_host(host) + except UnicodeError: + raise InvalidURL("URL has an invalid label.") + elif host.startswith(("*", ".")): + raise InvalidURL("URL has an invalid label.") + + # Carefully reconstruct the network location + netloc = auth or "" + if netloc: + netloc += "@" + netloc += host + if port: + netloc += f":{port}" + + # Bare domains aren't valid URLs. + if not path: + path = "/" + + if isinstance(params, (str, bytes)): + params = to_native_string(params) + + enc_params = self._encode_params(params) + if enc_params: + if query: + query = f"{query}&{enc_params}" + else: + query = enc_params + + url = requote_uri(urlunparse([scheme, netloc, path, None, query, fragment])) + self.url = url + + def prepare_headers(self, headers): + """Prepares the given HTTP headers.""" + + self.headers = CaseInsensitiveDict() + if headers: + for header in headers.items(): + # Raise exception on invalid header value. + check_header_validity(header) + name, value = header + self.headers[to_native_string(name)] = value + + def prepare_body(self, data, files, json=None): + """Prepares the given HTTP body data.""" + + # Check if file, fo, generator, iterator. + # If not, run through normal process. + + # Nottin' on you. + body = None + content_type = None + + if not data and json is not None: + # urllib3 requires a bytes-like body. Python 2's json.dumps + # provides this natively, but Python 3 gives a Unicode string. + content_type = "application/json" + + try: + body = complexjson.dumps(json, allow_nan=False) + except ValueError as ve: + raise InvalidJSONError(ve, request=self) + + if not isinstance(body, bytes): + body = body.encode("utf-8") + + is_stream = all( + [ + hasattr(data, "__iter__"), + not isinstance(data, (basestring, list, tuple, Mapping)), + ] + ) + + if is_stream: + try: + length = super_len(data) + except (TypeError, AttributeError, UnsupportedOperation): + length = None + + body = data + + if getattr(body, "tell", None) is not None: + # Record the current file position before reading. + # This will allow us to rewind a file in the event + # of a redirect. + try: + self._body_position = body.tell() + except OSError: + # This differentiates from None, allowing us to catch + # a failed `tell()` later when trying to rewind the body + self._body_position = object() + + if files: + raise NotImplementedError( + "Streamed bodies and files are mutually exclusive." + ) + + if length: + self.headers["Content-Length"] = builtin_str(length) + else: + self.headers["Transfer-Encoding"] = "chunked" + else: + # Multi-part file uploads. + if files: + (body, content_type) = self._encode_files(files, data) + else: + if data: + body = self._encode_params(data) + if isinstance(data, basestring) or hasattr(data, "read"): + content_type = None + else: + content_type = "application/x-www-form-urlencoded" + + self.prepare_content_length(body) + + # Add content-type if it wasn't explicitly provided. + if content_type and ("content-type" not in self.headers): + self.headers["Content-Type"] = content_type + + self.body = body + + def prepare_content_length(self, body): + """Prepare Content-Length header based on request method and body""" + if body is not None: + length = super_len(body) + if length: + # If length exists, set it. Otherwise, we fallback + # to Transfer-Encoding: chunked. + self.headers["Content-Length"] = builtin_str(length) + elif ( + self.method not in ("GET", "HEAD") + and self.headers.get("Content-Length") is None + ): + # Set Content-Length to 0 for methods that can have a body + # but don't provide one. (i.e. not GET or HEAD) + self.headers["Content-Length"] = "0" + + def prepare_auth(self, auth, url=""): + """Prepares the given HTTP auth data.""" + + # If no Auth is explicitly provided, extract it from the URL first. + if auth is None: + url_auth = get_auth_from_url(self.url) + auth = url_auth if any(url_auth) else None + + if auth: + if isinstance(auth, tuple) and len(auth) == 2: + # special-case basic HTTP auth + auth = HTTPBasicAuth(*auth) + + # Allow auth to make its changes. + r = auth(self) + + # Update self to reflect the auth changes. + self.__dict__.update(r.__dict__) + + # Recompute Content-Length + self.prepare_content_length(self.body) + + def prepare_cookies(self, cookies): + """Prepares the given HTTP cookie data. + + This function eventually generates a ``Cookie`` header from the + given cookies using cookielib. Due to cookielib's design, the header + will not be regenerated if it already exists, meaning this function + can only be called once for the life of the + :class:`PreparedRequest ` object. Any subsequent calls + to ``prepare_cookies`` will have no actual effect, unless the "Cookie" + header is removed beforehand. + """ + if isinstance(cookies, cookielib.CookieJar): + self._cookies = cookies + else: + self._cookies = cookiejar_from_dict(cookies) + + cookie_header = get_cookie_header(self._cookies, self) + if cookie_header is not None: + self.headers["Cookie"] = cookie_header + + def prepare_hooks(self, hooks): + """Prepares the given hooks.""" + # hooks can be passed as None to the prepare method and to this + # method. To prevent iterating over None, simply use an empty list + # if hooks is False-y + hooks = hooks or [] + for event in hooks: + self.register_hook(event, hooks[event]) + + +class Response: + """The :class:`Response ` object, which contains a + server's response to an HTTP request. + """ + + __attrs__ = [ + "_content", + "status_code", + "headers", + "url", + "history", + "encoding", + "reason", + "cookies", + "elapsed", + "request", + ] + + def __init__(self): + self._content = False + self._content_consumed = False + self._next = None + + #: Integer Code of responded HTTP Status, e.g. 404 or 200. + self.status_code = None + + #: Case-insensitive Dictionary of Response Headers. + #: For example, ``headers['content-encoding']`` will return the + #: value of a ``'Content-Encoding'`` response header. + self.headers = CaseInsensitiveDict() + + #: File-like object representation of response (for advanced usage). + #: Use of ``raw`` requires that ``stream=True`` be set on the request. + #: This requirement does not apply for use internally to Requests. + self.raw = None + + #: Final URL location of Response. + self.url = None + + #: Encoding to decode with when accessing r.text. + self.encoding = None + + #: A list of :class:`Response ` objects from + #: the history of the Request. Any redirect responses will end + #: up here. The list is sorted from the oldest to the most recent request. + self.history = [] + + #: Textual reason of responded HTTP Status, e.g. "Not Found" or "OK". + self.reason = None + + #: A CookieJar of Cookies the server sent back. + self.cookies = cookiejar_from_dict({}) + + #: The amount of time elapsed between sending the request + #: and the arrival of the response (as a timedelta). + #: This property specifically measures the time taken between sending + #: the first byte of the request and finishing parsing the headers. It + #: is therefore unaffected by consuming the response content or the + #: value of the ``stream`` keyword argument. + self.elapsed = datetime.timedelta(0) + + #: The :class:`PreparedRequest ` object to which this + #: is a response. + self.request = None + + def __enter__(self): + return self + + def __exit__(self, *args): + self.close() + + def __getstate__(self): + # Consume everything; accessing the content attribute makes + # sure the content has been fully read. + if not self._content_consumed: + self.content + + return {attr: getattr(self, attr, None) for attr in self.__attrs__} + + def __setstate__(self, state): + for name, value in state.items(): + setattr(self, name, value) + + # pickled objects do not have .raw + setattr(self, "_content_consumed", True) + setattr(self, "raw", None) + + def __repr__(self): + return f"" + + def __bool__(self): + """Returns True if :attr:`status_code` is less than 400. + + This attribute checks if the status code of the response is between + 400 and 600 to see if there was a client error or a server error. If + the status code, is between 200 and 400, this will return True. This + is **not** a check to see if the response code is ``200 OK``. + """ + return self.ok + + def __nonzero__(self): + """Returns True if :attr:`status_code` is less than 400. + + This attribute checks if the status code of the response is between + 400 and 600 to see if there was a client error or a server error. If + the status code, is between 200 and 400, this will return True. This + is **not** a check to see if the response code is ``200 OK``. + """ + return self.ok + + def __iter__(self): + """Allows you to use a response as an iterator.""" + return self.iter_content(128) + + @property + def ok(self): + """Returns True if :attr:`status_code` is less than 400, False if not. + + This attribute checks if the status code of the response is between + 400 and 600 to see if there was a client error or a server error. If + the status code is between 200 and 400, this will return True. This + is **not** a check to see if the response code is ``200 OK``. + """ + try: + self.raise_for_status() + except HTTPError: + return False + return True + + @property + def is_redirect(self): + """True if this Response is a well-formed HTTP redirect that could have + been processed automatically (by :meth:`Session.resolve_redirects`). + """ + return "location" in self.headers and self.status_code in REDIRECT_STATI + + @property + def is_permanent_redirect(self): + """True if this Response one of the permanent versions of redirect.""" + return "location" in self.headers and self.status_code in ( + codes.moved_permanently, + codes.permanent_redirect, + ) + + @property + def next(self): + """Returns a PreparedRequest for the next request in a redirect chain, if there is one.""" + return self._next + + @property + def apparent_encoding(self): + """The apparent encoding, provided by the charset_normalizer or chardet libraries.""" + return chardet.detect(self.content)["encoding"] + + def iter_content(self, chunk_size=1, decode_unicode=False): + """Iterates over the response data. When stream=True is set on the + request, this avoids reading the content at once into memory for + large responses. The chunk size is the number of bytes it should + read into memory. This is not necessarily the length of each item + returned as decoding can take place. + + chunk_size must be of type int or None. A value of None will + function differently depending on the value of `stream`. + stream=True will read data as it arrives in whatever size the + chunks are received. If stream=False, data is returned as + a single chunk. + + If decode_unicode is True, content will be decoded using the best + available encoding based on the response. + """ + + def generate(): + # Special case for urllib3. + if hasattr(self.raw, "stream"): + try: + for chunk in self.raw.stream(chunk_size, decode_content=True): + yield chunk + except ProtocolError as e: + raise ChunkedEncodingError(e) + except DecodeError as e: + raise ContentDecodingError(e) + except ReadTimeoutError as e: + raise ConnectionError(e) + except SSLError as e: + raise RequestsSSLError(e) + else: + # Standard file-like object. + while True: + chunk = self.raw.read(chunk_size) + if not chunk: + break + yield chunk + + self._content_consumed = True + + if self._content_consumed and isinstance(self._content, bool): + raise StreamConsumedError() + elif chunk_size is not None and not isinstance(chunk_size, int): + raise TypeError( + f"chunk_size must be an int, it is instead a {type(chunk_size)}." + ) + # simulate reading small chunks of the content + reused_chunks = iter_slices(self._content, chunk_size) + + stream_chunks = generate() + + chunks = reused_chunks if self._content_consumed else stream_chunks + + if decode_unicode: + chunks = stream_decode_response_unicode(chunks, self) + + return chunks + + def iter_lines( + self, chunk_size=ITER_CHUNK_SIZE, decode_unicode=False, delimiter=None + ): + """Iterates over the response data, one line at a time. When + stream=True is set on the request, this avoids reading the + content at once into memory for large responses. + + .. note:: This method is not reentrant safe. + """ + + pending = None + + for chunk in self.iter_content( + chunk_size=chunk_size, decode_unicode=decode_unicode + ): + + if pending is not None: + chunk = pending + chunk + + if delimiter: + lines = chunk.split(delimiter) + else: + lines = chunk.splitlines() + + if lines and lines[-1] and chunk and lines[-1][-1] == chunk[-1]: + pending = lines.pop() + else: + pending = None + + yield from lines + + if pending is not None: + yield pending + + @property + def content(self): + """Content of the response, in bytes.""" + + if self._content is False: + # Read the contents. + if self._content_consumed: + raise RuntimeError("The content for this response was already consumed") + + if self.status_code == 0 or self.raw is None: + self._content = None + else: + self._content = b"".join(self.iter_content(CONTENT_CHUNK_SIZE)) or b"" + + self._content_consumed = True + # don't need to release the connection; that's been handled by urllib3 + # since we exhausted the data. + return self._content + + @property + def text(self): + """Content of the response, in unicode. + + If Response.encoding is None, encoding will be guessed using + ``charset_normalizer`` or ``chardet``. + + The encoding of the response content is determined based solely on HTTP + headers, following RFC 2616 to the letter. If you can take advantage of + non-HTTP knowledge to make a better guess at the encoding, you should + set ``r.encoding`` appropriately before accessing this property. + """ + + # Try charset from content-type + content = None + encoding = self.encoding + + if not self.content: + return "" + + # Fallback to auto-detected encoding. + if self.encoding is None: + encoding = self.apparent_encoding + + # Decode unicode from given encoding. + try: + content = str(self.content, encoding, errors="replace") + except (LookupError, TypeError): + # A LookupError is raised if the encoding was not found which could + # indicate a misspelling or similar mistake. + # + # A TypeError can be raised if encoding is None + # + # So we try blindly encoding. + content = str(self.content, errors="replace") + + return content + + def json(self, **kwargs): + r"""Returns the json-encoded content of a response, if any. + + :param \*\*kwargs: Optional arguments that ``json.loads`` takes. + :raises requests.exceptions.JSONDecodeError: If the response body does not + contain valid json. + """ + + if not self.encoding and self.content and len(self.content) > 3: + # No encoding set. JSON RFC 4627 section 3 states we should expect + # UTF-8, -16 or -32. Detect which one to use; If the detection or + # decoding fails, fall back to `self.text` (using charset_normalizer to make + # a best guess). + encoding = guess_json_utf(self.content) + if encoding is not None: + try: + return complexjson.loads(self.content.decode(encoding), **kwargs) + except UnicodeDecodeError: + # Wrong UTF codec detected; usually because it's not UTF-8 + # but some other 8-bit codec. This is an RFC violation, + # and the server didn't bother to tell us what codec *was* + # used. + pass + except JSONDecodeError as e: + raise RequestsJSONDecodeError(e.msg, e.doc, e.pos) + + try: + return complexjson.loads(self.text, **kwargs) + except JSONDecodeError as e: + # Catch JSON-related errors and raise as requests.JSONDecodeError + # This aliases json.JSONDecodeError and simplejson.JSONDecodeError + raise RequestsJSONDecodeError(e.msg, e.doc, e.pos) + + @property + def links(self): + """Returns the parsed header links of the response, if any.""" + + header = self.headers.get("link") + + resolved_links = {} + + if header: + links = parse_header_links(header) + + for link in links: + key = link.get("rel") or link.get("url") + resolved_links[key] = link + + return resolved_links + + def raise_for_status(self): + """Raises :class:`HTTPError`, if one occurred.""" + + http_error_msg = "" + if isinstance(self.reason, bytes): + # We attempt to decode utf-8 first because some servers + # choose to localize their reason strings. If the string + # isn't utf-8, we fall back to iso-8859-1 for all other + # encodings. (See PR #3538) + try: + reason = self.reason.decode("utf-8") + except UnicodeDecodeError: + reason = self.reason.decode("iso-8859-1") + else: + reason = self.reason + + if 400 <= self.status_code < 500: + http_error_msg = ( + f"{self.status_code} Client Error: {reason} for url: {self.url}" + ) + + elif 500 <= self.status_code < 600: + http_error_msg = ( + f"{self.status_code} Server Error: {reason} for url: {self.url}" + ) + + if http_error_msg: + raise HTTPError(http_error_msg, response=self) + + def close(self): + """Releases the connection back to the pool. Once this method has been + called the underlying ``raw`` object must not be accessed again. + + *Note: Should not normally need to be called explicitly.* + """ + if not self._content_consumed: + self.raw.close() + + release_conn = getattr(self.raw, "release_conn", None) + if release_conn is not None: + release_conn() diff --git a/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/requests/packages.py b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/requests/packages.py new file mode 100644 index 0000000000000000000000000000000000000000..77c45c9e90cdf2bcd60eea3cac9c8cf56cca2c08 --- /dev/null +++ b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/requests/packages.py @@ -0,0 +1,28 @@ +import sys + +try: + import chardet +except ImportError: + import warnings + + import charset_normalizer as chardet + + warnings.filterwarnings("ignore", "Trying to detect", module="charset_normalizer") + +# This code exists for backwards compatibility reasons. +# I don't like it either. Just look the other way. :) + +for package in ("urllib3", "idna"): + locals()[package] = __import__(package) + # This traversal is apparently necessary such that the identities are + # preserved (requests.packages.urllib3.* is urllib3.*) + for mod in list(sys.modules): + if mod == package or mod.startswith(f"{package}."): + sys.modules[f"requests.packages.{mod}"] = sys.modules[mod] + +target = chardet.__name__ +for mod in list(sys.modules): + if mod == target or mod.startswith(f"{target}."): + target = target.replace(target, "chardet") + sys.modules[f"requests.packages.{target}"] = sys.modules[mod] +# Kinda cool, though, right? diff --git a/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/requests/sessions.py b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/requests/sessions.py new file mode 100644 index 0000000000000000000000000000000000000000..6cb3b4dae397930fba60e4c08b25b9444783b6f7 --- /dev/null +++ b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/requests/sessions.py @@ -0,0 +1,831 @@ +""" +requests.sessions +~~~~~~~~~~~~~~~~~ + +This module provides a Session object to manage and persist settings across +requests (cookies, auth, proxies). +""" +import os +import sys +import time +from collections import OrderedDict +from datetime import timedelta + +from ._internal_utils import to_native_string +from .adapters import HTTPAdapter +from .auth import _basic_auth_str +from .compat import Mapping, cookielib, urljoin, urlparse +from .cookies import ( + RequestsCookieJar, + cookiejar_from_dict, + extract_cookies_to_jar, + merge_cookies, +) +from .exceptions import ( + ChunkedEncodingError, + ContentDecodingError, + InvalidSchema, + TooManyRedirects, +) +from .hooks import default_hooks, dispatch_hook + +# formerly defined here, reexposed here for backward compatibility +from .models import ( # noqa: F401 + DEFAULT_REDIRECT_LIMIT, + REDIRECT_STATI, + PreparedRequest, + Request, +) +from .status_codes import codes +from .structures import CaseInsensitiveDict +from .utils import ( # noqa: F401 + DEFAULT_PORTS, + default_headers, + get_auth_from_url, + get_environ_proxies, + get_netrc_auth, + requote_uri, + resolve_proxies, + rewind_body, + should_bypass_proxies, + to_key_val_list, +) + +# Preferred clock, based on which one is more accurate on a given system. +if sys.platform == "win32": + preferred_clock = time.perf_counter +else: + preferred_clock = time.time + + +def merge_setting(request_setting, session_setting, dict_class=OrderedDict): + """Determines appropriate setting for a given request, taking into account + the explicit setting on that request, and the setting in the session. If a + setting is a dictionary, they will be merged together using `dict_class` + """ + + if session_setting is None: + return request_setting + + if request_setting is None: + return session_setting + + # Bypass if not a dictionary (e.g. verify) + if not ( + isinstance(session_setting, Mapping) and isinstance(request_setting, Mapping) + ): + return request_setting + + merged_setting = dict_class(to_key_val_list(session_setting)) + merged_setting.update(to_key_val_list(request_setting)) + + # Remove keys that are set to None. Extract keys first to avoid altering + # the dictionary during iteration. + none_keys = [k for (k, v) in merged_setting.items() if v is None] + for key in none_keys: + del merged_setting[key] + + return merged_setting + + +def merge_hooks(request_hooks, session_hooks, dict_class=OrderedDict): + """Properly merges both requests and session hooks. + + This is necessary because when request_hooks == {'response': []}, the + merge breaks Session hooks entirely. + """ + if session_hooks is None or session_hooks.get("response") == []: + return request_hooks + + if request_hooks is None or request_hooks.get("response") == []: + return session_hooks + + return merge_setting(request_hooks, session_hooks, dict_class) + + +class SessionRedirectMixin: + def get_redirect_target(self, resp): + """Receives a Response. Returns a redirect URI or ``None``""" + # Due to the nature of how requests processes redirects this method will + # be called at least once upon the original response and at least twice + # on each subsequent redirect response (if any). + # If a custom mixin is used to handle this logic, it may be advantageous + # to cache the redirect location onto the response object as a private + # attribute. + if resp.is_redirect: + location = resp.headers["location"] + # Currently the underlying http module on py3 decode headers + # in latin1, but empirical evidence suggests that latin1 is very + # rarely used with non-ASCII characters in HTTP headers. + # It is more likely to get UTF8 header rather than latin1. + # This causes incorrect handling of UTF8 encoded location headers. + # To solve this, we re-encode the location in latin1. + location = location.encode("latin1") + return to_native_string(location, "utf8") + return None + + def should_strip_auth(self, old_url, new_url): + """Decide whether Authorization header should be removed when redirecting""" + old_parsed = urlparse(old_url) + new_parsed = urlparse(new_url) + if old_parsed.hostname != new_parsed.hostname: + return True + # Special case: allow http -> https redirect when using the standard + # ports. This isn't specified by RFC 7235, but is kept to avoid + # breaking backwards compatibility with older versions of requests + # that allowed any redirects on the same host. + if ( + old_parsed.scheme == "http" + and old_parsed.port in (80, None) + and new_parsed.scheme == "https" + and new_parsed.port in (443, None) + ): + return False + + # Handle default port usage corresponding to scheme. + changed_port = old_parsed.port != new_parsed.port + changed_scheme = old_parsed.scheme != new_parsed.scheme + default_port = (DEFAULT_PORTS.get(old_parsed.scheme, None), None) + if ( + not changed_scheme + and old_parsed.port in default_port + and new_parsed.port in default_port + ): + return False + + # Standard case: root URI must match + return changed_port or changed_scheme + + def resolve_redirects( + self, + resp, + req, + stream=False, + timeout=None, + verify=True, + cert=None, + proxies=None, + yield_requests=False, + **adapter_kwargs, + ): + """Receives a Response. Returns a generator of Responses or Requests.""" + + hist = [] # keep track of history + + url = self.get_redirect_target(resp) + previous_fragment = urlparse(req.url).fragment + while url: + prepared_request = req.copy() + + # Update history and keep track of redirects. + # resp.history must ignore the original request in this loop + hist.append(resp) + resp.history = hist[1:] + + try: + resp.content # Consume socket so it can be released + except (ChunkedEncodingError, ContentDecodingError, RuntimeError): + resp.raw.read(decode_content=False) + + if len(resp.history) >= self.max_redirects: + raise TooManyRedirects( + f"Exceeded {self.max_redirects} redirects.", response=resp + ) + + # Release the connection back into the pool. + resp.close() + + # Handle redirection without scheme (see: RFC 1808 Section 4) + if url.startswith("//"): + parsed_rurl = urlparse(resp.url) + url = ":".join([to_native_string(parsed_rurl.scheme), url]) + + # Normalize url case and attach previous fragment if needed (RFC 7231 7.1.2) + parsed = urlparse(url) + if parsed.fragment == "" and previous_fragment: + parsed = parsed._replace(fragment=previous_fragment) + elif parsed.fragment: + previous_fragment = parsed.fragment + url = parsed.geturl() + + # Facilitate relative 'location' headers, as allowed by RFC 7231. + # (e.g. '/path/to/resource' instead of 'http://domain.tld/path/to/resource') + # Compliant with RFC3986, we percent encode the url. + if not parsed.netloc: + url = urljoin(resp.url, requote_uri(url)) + else: + url = requote_uri(url) + + prepared_request.url = to_native_string(url) + + self.rebuild_method(prepared_request, resp) + + # https://github.com/psf/requests/issues/1084 + if resp.status_code not in ( + codes.temporary_redirect, + codes.permanent_redirect, + ): + # https://github.com/psf/requests/issues/3490 + purged_headers = ("Content-Length", "Content-Type", "Transfer-Encoding") + for header in purged_headers: + prepared_request.headers.pop(header, None) + prepared_request.body = None + + headers = prepared_request.headers + headers.pop("Cookie", None) + + # Extract any cookies sent on the response to the cookiejar + # in the new request. Because we've mutated our copied prepared + # request, use the old one that we haven't yet touched. + extract_cookies_to_jar(prepared_request._cookies, req, resp.raw) + merge_cookies(prepared_request._cookies, self.cookies) + prepared_request.prepare_cookies(prepared_request._cookies) + + # Rebuild auth and proxy information. + proxies = self.rebuild_proxies(prepared_request, proxies) + self.rebuild_auth(prepared_request, resp) + + # A failed tell() sets `_body_position` to `object()`. This non-None + # value ensures `rewindable` will be True, allowing us to raise an + # UnrewindableBodyError, instead of hanging the connection. + rewindable = prepared_request._body_position is not None and ( + "Content-Length" in headers or "Transfer-Encoding" in headers + ) + + # Attempt to rewind consumed file-like object. + if rewindable: + rewind_body(prepared_request) + + # Override the original request. + req = prepared_request + + if yield_requests: + yield req + else: + + resp = self.send( + req, + stream=stream, + timeout=timeout, + verify=verify, + cert=cert, + proxies=proxies, + allow_redirects=False, + **adapter_kwargs, + ) + + extract_cookies_to_jar(self.cookies, prepared_request, resp.raw) + + # extract redirect url, if any, for the next loop + url = self.get_redirect_target(resp) + yield resp + + def rebuild_auth(self, prepared_request, response): + """When being redirected we may want to strip authentication from the + request to avoid leaking credentials. This method intelligently removes + and reapplies authentication where possible to avoid credential loss. + """ + headers = prepared_request.headers + url = prepared_request.url + + if "Authorization" in headers and self.should_strip_auth( + response.request.url, url + ): + # If we get redirected to a new host, we should strip out any + # authentication headers. + del headers["Authorization"] + + # .netrc might have more auth for us on our new host. + new_auth = get_netrc_auth(url) if self.trust_env else None + if new_auth is not None: + prepared_request.prepare_auth(new_auth) + + def rebuild_proxies(self, prepared_request, proxies): + """This method re-evaluates the proxy configuration by considering the + environment variables. If we are redirected to a URL covered by + NO_PROXY, we strip the proxy configuration. Otherwise, we set missing + proxy keys for this URL (in case they were stripped by a previous + redirect). + + This method also replaces the Proxy-Authorization header where + necessary. + + :rtype: dict + """ + headers = prepared_request.headers + scheme = urlparse(prepared_request.url).scheme + new_proxies = resolve_proxies(prepared_request, proxies, self.trust_env) + + if "Proxy-Authorization" in headers: + del headers["Proxy-Authorization"] + + try: + username, password = get_auth_from_url(new_proxies[scheme]) + except KeyError: + username, password = None, None + + if username and password: + headers["Proxy-Authorization"] = _basic_auth_str(username, password) + + return new_proxies + + def rebuild_method(self, prepared_request, response): + """When being redirected we may want to change the method of the request + based on certain specs or browser behavior. + """ + method = prepared_request.method + + # https://tools.ietf.org/html/rfc7231#section-6.4.4 + if response.status_code == codes.see_other and method != "HEAD": + method = "GET" + + # Do what the browsers do, despite standards... + # First, turn 302s into GETs. + if response.status_code == codes.found and method != "HEAD": + method = "GET" + + # Second, if a POST is responded to with a 301, turn it into a GET. + # This bizarre behaviour is explained in Issue 1704. + if response.status_code == codes.moved and method == "POST": + method = "GET" + + prepared_request.method = method + + +class Session(SessionRedirectMixin): + """A Requests session. + + Provides cookie persistence, connection-pooling, and configuration. + + Basic Usage:: + + >>> import requests + >>> s = requests.Session() + >>> s.get('https://httpbin.org/get') + + + Or as a context manager:: + + >>> with requests.Session() as s: + ... s.get('https://httpbin.org/get') + + """ + + __attrs__ = [ + "headers", + "cookies", + "auth", + "proxies", + "hooks", + "params", + "verify", + "cert", + "adapters", + "stream", + "trust_env", + "max_redirects", + ] + + def __init__(self): + + #: A case-insensitive dictionary of headers to be sent on each + #: :class:`Request ` sent from this + #: :class:`Session `. + self.headers = default_headers() + + #: Default Authentication tuple or object to attach to + #: :class:`Request `. + self.auth = None + + #: Dictionary mapping protocol or protocol and host to the URL of the proxy + #: (e.g. {'http': 'foo.bar:3128', 'http://host.name': 'foo.bar:4012'}) to + #: be used on each :class:`Request `. + self.proxies = {} + + #: Event-handling hooks. + self.hooks = default_hooks() + + #: Dictionary of querystring data to attach to each + #: :class:`Request `. The dictionary values may be lists for + #: representing multivalued query parameters. + self.params = {} + + #: Stream response content default. + self.stream = False + + #: SSL Verification default. + #: Defaults to `True`, requiring requests to verify the TLS certificate at the + #: remote end. + #: If verify is set to `False`, requests will accept any TLS certificate + #: presented by the server, and will ignore hostname mismatches and/or + #: expired certificates, which will make your application vulnerable to + #: man-in-the-middle (MitM) attacks. + #: Only set this to `False` for testing. + self.verify = True + + #: SSL client certificate default, if String, path to ssl client + #: cert file (.pem). If Tuple, ('cert', 'key') pair. + self.cert = None + + #: Maximum number of redirects allowed. If the request exceeds this + #: limit, a :class:`TooManyRedirects` exception is raised. + #: This defaults to requests.models.DEFAULT_REDIRECT_LIMIT, which is + #: 30. + self.max_redirects = DEFAULT_REDIRECT_LIMIT + + #: Trust environment settings for proxy configuration, default + #: authentication and similar. + self.trust_env = True + + #: A CookieJar containing all currently outstanding cookies set on this + #: session. By default it is a + #: :class:`RequestsCookieJar `, but + #: may be any other ``cookielib.CookieJar`` compatible object. + self.cookies = cookiejar_from_dict({}) + + # Default connection adapters. + self.adapters = OrderedDict() + self.mount("https://", HTTPAdapter()) + self.mount("http://", HTTPAdapter()) + + def __enter__(self): + return self + + def __exit__(self, *args): + self.close() + + def prepare_request(self, request): + """Constructs a :class:`PreparedRequest ` for + transmission and returns it. The :class:`PreparedRequest` has settings + merged from the :class:`Request ` instance and those of the + :class:`Session`. + + :param request: :class:`Request` instance to prepare with this + session's settings. + :rtype: requests.PreparedRequest + """ + cookies = request.cookies or {} + + # Bootstrap CookieJar. + if not isinstance(cookies, cookielib.CookieJar): + cookies = cookiejar_from_dict(cookies) + + # Merge with session cookies + merged_cookies = merge_cookies( + merge_cookies(RequestsCookieJar(), self.cookies), cookies + ) + + # Set environment's basic authentication if not explicitly set. + auth = request.auth + if self.trust_env and not auth and not self.auth: + auth = get_netrc_auth(request.url) + + p = PreparedRequest() + p.prepare( + method=request.method.upper(), + url=request.url, + files=request.files, + data=request.data, + json=request.json, + headers=merge_setting( + request.headers, self.headers, dict_class=CaseInsensitiveDict + ), + params=merge_setting(request.params, self.params), + auth=merge_setting(auth, self.auth), + cookies=merged_cookies, + hooks=merge_hooks(request.hooks, self.hooks), + ) + return p + + def request( + self, + method, + url, + params=None, + data=None, + headers=None, + cookies=None, + files=None, + auth=None, + timeout=None, + allow_redirects=True, + proxies=None, + hooks=None, + stream=None, + verify=None, + cert=None, + json=None, + ): + """Constructs a :class:`Request `, prepares it and sends it. + Returns :class:`Response ` object. + + :param method: method for the new :class:`Request` object. + :param url: URL for the new :class:`Request` object. + :param params: (optional) Dictionary or bytes to be sent in the query + string for the :class:`Request`. + :param data: (optional) Dictionary, list of tuples, bytes, or file-like + object to send in the body of the :class:`Request`. + :param json: (optional) json to send in the body of the + :class:`Request`. + :param headers: (optional) Dictionary of HTTP Headers to send with the + :class:`Request`. + :param cookies: (optional) Dict or CookieJar object to send with the + :class:`Request`. + :param files: (optional) Dictionary of ``'filename': file-like-objects`` + for multipart encoding upload. + :param auth: (optional) Auth tuple or callable to enable + Basic/Digest/Custom HTTP Auth. + :param timeout: (optional) How long to wait for the server to send + data before giving up, as a float, or a :ref:`(connect timeout, + read timeout) ` tuple. + :type timeout: float or tuple + :param allow_redirects: (optional) Set to True by default. + :type allow_redirects: bool + :param proxies: (optional) Dictionary mapping protocol or protocol and + hostname to the URL of the proxy. + :param stream: (optional) whether to immediately download the response + content. Defaults to ``False``. + :param verify: (optional) Either a boolean, in which case it controls whether we verify + the server's TLS certificate, or a string, in which case it must be a path + to a CA bundle to use. Defaults to ``True``. When set to + ``False``, requests will accept any TLS certificate presented by + the server, and will ignore hostname mismatches and/or expired + certificates, which will make your application vulnerable to + man-in-the-middle (MitM) attacks. Setting verify to ``False`` + may be useful during local development or testing. + :param cert: (optional) if String, path to ssl client cert file (.pem). + If Tuple, ('cert', 'key') pair. + :rtype: requests.Response + """ + # Create the Request. + req = Request( + method=method.upper(), + url=url, + headers=headers, + files=files, + data=data or {}, + json=json, + params=params or {}, + auth=auth, + cookies=cookies, + hooks=hooks, + ) + prep = self.prepare_request(req) + + proxies = proxies or {} + + settings = self.merge_environment_settings( + prep.url, proxies, stream, verify, cert + ) + + # Send the request. + send_kwargs = { + "timeout": timeout, + "allow_redirects": allow_redirects, + } + send_kwargs.update(settings) + resp = self.send(prep, **send_kwargs) + + return resp + + def get(self, url, **kwargs): + r"""Sends a GET request. Returns :class:`Response` object. + + :param url: URL for the new :class:`Request` object. + :param \*\*kwargs: Optional arguments that ``request`` takes. + :rtype: requests.Response + """ + + kwargs.setdefault("allow_redirects", True) + return self.request("GET", url, **kwargs) + + def options(self, url, **kwargs): + r"""Sends a OPTIONS request. Returns :class:`Response` object. + + :param url: URL for the new :class:`Request` object. + :param \*\*kwargs: Optional arguments that ``request`` takes. + :rtype: requests.Response + """ + + kwargs.setdefault("allow_redirects", True) + return self.request("OPTIONS", url, **kwargs) + + def head(self, url, **kwargs): + r"""Sends a HEAD request. Returns :class:`Response` object. + + :param url: URL for the new :class:`Request` object. + :param \*\*kwargs: Optional arguments that ``request`` takes. + :rtype: requests.Response + """ + + kwargs.setdefault("allow_redirects", False) + return self.request("HEAD", url, **kwargs) + + def post(self, url, data=None, json=None, **kwargs): + r"""Sends a POST request. Returns :class:`Response` object. + + :param url: URL for the new :class:`Request` object. + :param data: (optional) Dictionary, list of tuples, bytes, or file-like + object to send in the body of the :class:`Request`. + :param json: (optional) json to send in the body of the :class:`Request`. + :param \*\*kwargs: Optional arguments that ``request`` takes. + :rtype: requests.Response + """ + + return self.request("POST", url, data=data, json=json, **kwargs) + + def put(self, url, data=None, **kwargs): + r"""Sends a PUT request. Returns :class:`Response` object. + + :param url: URL for the new :class:`Request` object. + :param data: (optional) Dictionary, list of tuples, bytes, or file-like + object to send in the body of the :class:`Request`. + :param \*\*kwargs: Optional arguments that ``request`` takes. + :rtype: requests.Response + """ + + return self.request("PUT", url, data=data, **kwargs) + + def patch(self, url, data=None, **kwargs): + r"""Sends a PATCH request. Returns :class:`Response` object. + + :param url: URL for the new :class:`Request` object. + :param data: (optional) Dictionary, list of tuples, bytes, or file-like + object to send in the body of the :class:`Request`. + :param \*\*kwargs: Optional arguments that ``request`` takes. + :rtype: requests.Response + """ + + return self.request("PATCH", url, data=data, **kwargs) + + def delete(self, url, **kwargs): + r"""Sends a DELETE request. Returns :class:`Response` object. + + :param url: URL for the new :class:`Request` object. + :param \*\*kwargs: Optional arguments that ``request`` takes. + :rtype: requests.Response + """ + + return self.request("DELETE", url, **kwargs) + + def send(self, request, **kwargs): + """Send a given PreparedRequest. + + :rtype: requests.Response + """ + # Set defaults that the hooks can utilize to ensure they always have + # the correct parameters to reproduce the previous request. + kwargs.setdefault("stream", self.stream) + kwargs.setdefault("verify", self.verify) + kwargs.setdefault("cert", self.cert) + if "proxies" not in kwargs: + kwargs["proxies"] = resolve_proxies(request, self.proxies, self.trust_env) + + # It's possible that users might accidentally send a Request object. + # Guard against that specific failure case. + if isinstance(request, Request): + raise ValueError("You can only send PreparedRequests.") + + # Set up variables needed for resolve_redirects and dispatching of hooks + allow_redirects = kwargs.pop("allow_redirects", True) + stream = kwargs.get("stream") + hooks = request.hooks + + # Get the appropriate adapter to use + adapter = self.get_adapter(url=request.url) + + # Start time (approximately) of the request + start = preferred_clock() + + # Send the request + r = adapter.send(request, **kwargs) + + # Total elapsed time of the request (approximately) + elapsed = preferred_clock() - start + r.elapsed = timedelta(seconds=elapsed) + + # Response manipulation hooks + r = dispatch_hook("response", hooks, r, **kwargs) + + # Persist cookies + if r.history: + + # If the hooks create history then we want those cookies too + for resp in r.history: + extract_cookies_to_jar(self.cookies, resp.request, resp.raw) + + extract_cookies_to_jar(self.cookies, request, r.raw) + + # Resolve redirects if allowed. + if allow_redirects: + # Redirect resolving generator. + gen = self.resolve_redirects(r, request, **kwargs) + history = [resp for resp in gen] + else: + history = [] + + # Shuffle things around if there's history. + if history: + # Insert the first (original) request at the start + history.insert(0, r) + # Get the last request made + r = history.pop() + r.history = history + + # If redirects aren't being followed, store the response on the Request for Response.next(). + if not allow_redirects: + try: + r._next = next( + self.resolve_redirects(r, request, yield_requests=True, **kwargs) + ) + except StopIteration: + pass + + if not stream: + r.content + + return r + + def merge_environment_settings(self, url, proxies, stream, verify, cert): + """ + Check the environment and merge it with some settings. + + :rtype: dict + """ + # Gather clues from the surrounding environment. + if self.trust_env: + # Set environment's proxies. + no_proxy = proxies.get("no_proxy") if proxies is not None else None + env_proxies = get_environ_proxies(url, no_proxy=no_proxy) + for (k, v) in env_proxies.items(): + proxies.setdefault(k, v) + + # Look for requests environment configuration + # and be compatible with cURL. + if verify is True or verify is None: + verify = ( + os.environ.get("REQUESTS_CA_BUNDLE") + or os.environ.get("CURL_CA_BUNDLE") + or verify + ) + + # Merge all the kwargs. + proxies = merge_setting(proxies, self.proxies) + stream = merge_setting(stream, self.stream) + verify = merge_setting(verify, self.verify) + cert = merge_setting(cert, self.cert) + + return {"proxies": proxies, "stream": stream, "verify": verify, "cert": cert} + + def get_adapter(self, url): + """ + Returns the appropriate connection adapter for the given URL. + + :rtype: requests.adapters.BaseAdapter + """ + for (prefix, adapter) in self.adapters.items(): + + if url.lower().startswith(prefix.lower()): + return adapter + + # Nothing matches :-/ + raise InvalidSchema(f"No connection adapters were found for {url!r}") + + def close(self): + """Closes all adapters and as such the session""" + for v in self.adapters.values(): + v.close() + + def mount(self, prefix, adapter): + """Registers a connection adapter to a prefix. + + Adapters are sorted in descending order by prefix length. + """ + self.adapters[prefix] = adapter + keys_to_move = [k for k in self.adapters if len(k) < len(prefix)] + + for key in keys_to_move: + self.adapters[key] = self.adapters.pop(key) + + def __getstate__(self): + state = {attr: getattr(self, attr, None) for attr in self.__attrs__} + return state + + def __setstate__(self, state): + for attr, value in state.items(): + setattr(self, attr, value) + + +def session(): + """ + Returns a :class:`Session` for context-management. + + .. deprecated:: 1.0.0 + + This method has been deprecated since version 1.0.0 and is only kept for + backwards compatibility. New code should use :class:`~requests.sessions.Session` + to create a session. This may be removed at a future date. + + :rtype: Session + """ + return Session() diff --git a/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/requests/utils.py b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/requests/utils.py new file mode 100644 index 0000000000000000000000000000000000000000..ad5358381ab96bd6d426b4754f02d104505a1e9a --- /dev/null +++ b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/requests/utils.py @@ -0,0 +1,1086 @@ +""" +requests.utils +~~~~~~~~~~~~~~ + +This module provides utility functions that are used within Requests +that are also useful for external consumption. +""" + +import codecs +import contextlib +import io +import os +import re +import socket +import struct +import sys +import tempfile +import warnings +import zipfile +from collections import OrderedDict + +from urllib3.util import make_headers, parse_url + +from . import certs +from .__version__ import __version__ + +# to_native_string is unused here, but imported here for backwards compatibility +from ._internal_utils import HEADER_VALIDATORS, to_native_string # noqa: F401 +from .compat import ( + Mapping, + basestring, + bytes, + getproxies, + getproxies_environment, + integer_types, +) +from .compat import parse_http_list as _parse_list_header +from .compat import ( + proxy_bypass, + proxy_bypass_environment, + quote, + str, + unquote, + urlparse, + urlunparse, +) +from .cookies import cookiejar_from_dict +from .exceptions import ( + FileModeWarning, + InvalidHeader, + InvalidURL, + UnrewindableBodyError, +) +from .structures import CaseInsensitiveDict + +NETRC_FILES = (".netrc", "_netrc") + +DEFAULT_CA_BUNDLE_PATH = certs.where() + +DEFAULT_PORTS = {"http": 80, "https": 443} + +# Ensure that ', ' is used to preserve previous delimiter behavior. +DEFAULT_ACCEPT_ENCODING = ", ".join( + re.split(r",\s*", make_headers(accept_encoding=True)["accept-encoding"]) +) + + +if sys.platform == "win32": + # provide a proxy_bypass version on Windows without DNS lookups + + def proxy_bypass_registry(host): + try: + import winreg + except ImportError: + return False + + try: + internetSettings = winreg.OpenKey( + winreg.HKEY_CURRENT_USER, + r"Software\Microsoft\Windows\CurrentVersion\Internet Settings", + ) + # ProxyEnable could be REG_SZ or REG_DWORD, normalizing it + proxyEnable = int(winreg.QueryValueEx(internetSettings, "ProxyEnable")[0]) + # ProxyOverride is almost always a string + proxyOverride = winreg.QueryValueEx(internetSettings, "ProxyOverride")[0] + except (OSError, ValueError): + return False + if not proxyEnable or not proxyOverride: + return False + + # make a check value list from the registry entry: replace the + # '' string by the localhost entry and the corresponding + # canonical entry. + proxyOverride = proxyOverride.split(";") + # now check if we match one of the registry values. + for test in proxyOverride: + if test == "": + if "." not in host: + return True + test = test.replace(".", r"\.") # mask dots + test = test.replace("*", r".*") # change glob sequence + test = test.replace("?", r".") # change glob char + if re.match(test, host, re.I): + return True + return False + + def proxy_bypass(host): # noqa + """Return True, if the host should be bypassed. + + Checks proxy settings gathered from the environment, if specified, + or the registry. + """ + if getproxies_environment(): + return proxy_bypass_environment(host) + else: + return proxy_bypass_registry(host) + + +def dict_to_sequence(d): + """Returns an internal sequence dictionary update.""" + + if hasattr(d, "items"): + d = d.items() + + return d + + +def super_len(o): + total_length = None + current_position = 0 + + if hasattr(o, "__len__"): + total_length = len(o) + + elif hasattr(o, "len"): + total_length = o.len + + elif hasattr(o, "fileno"): + try: + fileno = o.fileno() + except (io.UnsupportedOperation, AttributeError): + # AttributeError is a surprising exception, seeing as how we've just checked + # that `hasattr(o, 'fileno')`. It happens for objects obtained via + # `Tarfile.extractfile()`, per issue 5229. + pass + else: + total_length = os.fstat(fileno).st_size + + # Having used fstat to determine the file length, we need to + # confirm that this file was opened up in binary mode. + if "b" not in o.mode: + warnings.warn( + ( + "Requests has determined the content-length for this " + "request using the binary size of the file: however, the " + "file has been opened in text mode (i.e. without the 'b' " + "flag in the mode). This may lead to an incorrect " + "content-length. In Requests 3.0, support will be removed " + "for files in text mode." + ), + FileModeWarning, + ) + + if hasattr(o, "tell"): + try: + current_position = o.tell() + except OSError: + # This can happen in some weird situations, such as when the file + # is actually a special file descriptor like stdin. In this + # instance, we don't know what the length is, so set it to zero and + # let requests chunk it instead. + if total_length is not None: + current_position = total_length + else: + if hasattr(o, "seek") and total_length is None: + # StringIO and BytesIO have seek but no usable fileno + try: + # seek to end of file + o.seek(0, 2) + total_length = o.tell() + + # seek back to current position to support + # partially read file-like objects + o.seek(current_position or 0) + except OSError: + total_length = 0 + + if total_length is None: + total_length = 0 + + return max(0, total_length - current_position) + + +def get_netrc_auth(url, raise_errors=False): + """Returns the Requests tuple auth for a given url from netrc.""" + + netrc_file = os.environ.get("NETRC") + if netrc_file is not None: + netrc_locations = (netrc_file,) + else: + netrc_locations = (f"~/{f}" for f in NETRC_FILES) + + try: + from netrc import NetrcParseError, netrc + + netrc_path = None + + for f in netrc_locations: + try: + loc = os.path.expanduser(f) + except KeyError: + # os.path.expanduser can fail when $HOME is undefined and + # getpwuid fails. See https://bugs.python.org/issue20164 & + # https://github.com/psf/requests/issues/1846 + return + + if os.path.exists(loc): + netrc_path = loc + break + + # Abort early if there isn't one. + if netrc_path is None: + return + + ri = urlparse(url) + + # Strip port numbers from netloc. This weird `if...encode`` dance is + # used for Python 3.2, which doesn't support unicode literals. + splitstr = b":" + if isinstance(url, str): + splitstr = splitstr.decode("ascii") + host = ri.netloc.split(splitstr)[0] + + try: + _netrc = netrc(netrc_path).authenticators(host) + if _netrc: + # Return with login / password + login_i = 0 if _netrc[0] else 1 + return (_netrc[login_i], _netrc[2]) + except (NetrcParseError, OSError): + # If there was a parsing error or a permissions issue reading the file, + # we'll just skip netrc auth unless explicitly asked to raise errors. + if raise_errors: + raise + + # App Engine hackiness. + except (ImportError, AttributeError): + pass + + +def guess_filename(obj): + """Tries to guess the filename of the given object.""" + name = getattr(obj, "name", None) + if name and isinstance(name, basestring) and name[0] != "<" and name[-1] != ">": + return os.path.basename(name) + + +def extract_zipped_paths(path): + """Replace nonexistent paths that look like they refer to a member of a zip + archive with the location of an extracted copy of the target, or else + just return the provided path unchanged. + """ + if os.path.exists(path): + # this is already a valid path, no need to do anything further + return path + + # find the first valid part of the provided path and treat that as a zip archive + # assume the rest of the path is the name of a member in the archive + archive, member = os.path.split(path) + while archive and not os.path.exists(archive): + archive, prefix = os.path.split(archive) + if not prefix: + # If we don't check for an empty prefix after the split (in other words, archive remains unchanged after the split), + # we _can_ end up in an infinite loop on a rare corner case affecting a small number of users + break + member = "/".join([prefix, member]) + + if not zipfile.is_zipfile(archive): + return path + + zip_file = zipfile.ZipFile(archive) + if member not in zip_file.namelist(): + return path + + # we have a valid zip archive and a valid member of that archive + tmp = tempfile.gettempdir() + extracted_path = os.path.join(tmp, member.split("/")[-1]) + if not os.path.exists(extracted_path): + # use read + write to avoid the creating nested folders, we only want the file, avoids mkdir racing condition + with atomic_open(extracted_path) as file_handler: + file_handler.write(zip_file.read(member)) + return extracted_path + + +@contextlib.contextmanager +def atomic_open(filename): + """Write a file to the disk in an atomic fashion""" + tmp_descriptor, tmp_name = tempfile.mkstemp(dir=os.path.dirname(filename)) + try: + with os.fdopen(tmp_descriptor, "wb") as tmp_handler: + yield tmp_handler + os.replace(tmp_name, filename) + except BaseException: + os.remove(tmp_name) + raise + + +def from_key_val_list(value): + """Take an object and test to see if it can be represented as a + dictionary. Unless it can not be represented as such, return an + OrderedDict, e.g., + + :: + + >>> from_key_val_list([('key', 'val')]) + OrderedDict([('key', 'val')]) + >>> from_key_val_list('string') + Traceback (most recent call last): + ... + ValueError: cannot encode objects that are not 2-tuples + >>> from_key_val_list({'key': 'val'}) + OrderedDict([('key', 'val')]) + + :rtype: OrderedDict + """ + if value is None: + return None + + if isinstance(value, (str, bytes, bool, int)): + raise ValueError("cannot encode objects that are not 2-tuples") + + return OrderedDict(value) + + +def to_key_val_list(value): + """Take an object and test to see if it can be represented as a + dictionary. If it can be, return a list of tuples, e.g., + + :: + + >>> to_key_val_list([('key', 'val')]) + [('key', 'val')] + >>> to_key_val_list({'key': 'val'}) + [('key', 'val')] + >>> to_key_val_list('string') + Traceback (most recent call last): + ... + ValueError: cannot encode objects that are not 2-tuples + + :rtype: list + """ + if value is None: + return None + + if isinstance(value, (str, bytes, bool, int)): + raise ValueError("cannot encode objects that are not 2-tuples") + + if isinstance(value, Mapping): + value = value.items() + + return list(value) + + +# From mitsuhiko/werkzeug (used with permission). +def parse_list_header(value): + """Parse lists as described by RFC 2068 Section 2. + + In particular, parse comma-separated lists where the elements of + the list may include quoted-strings. A quoted-string could + contain a comma. A non-quoted string could have quotes in the + middle. Quotes are removed automatically after parsing. + + It basically works like :func:`parse_set_header` just that items + may appear multiple times and case sensitivity is preserved. + + The return value is a standard :class:`list`: + + >>> parse_list_header('token, "quoted value"') + ['token', 'quoted value'] + + To create a header from the :class:`list` again, use the + :func:`dump_header` function. + + :param value: a string with a list header. + :return: :class:`list` + :rtype: list + """ + result = [] + for item in _parse_list_header(value): + if item[:1] == item[-1:] == '"': + item = unquote_header_value(item[1:-1]) + result.append(item) + return result + + +# From mitsuhiko/werkzeug (used with permission). +def parse_dict_header(value): + """Parse lists of key, value pairs as described by RFC 2068 Section 2 and + convert them into a python dict: + + >>> d = parse_dict_header('foo="is a fish", bar="as well"') + >>> type(d) is dict + True + >>> sorted(d.items()) + [('bar', 'as well'), ('foo', 'is a fish')] + + If there is no value for a key it will be `None`: + + >>> parse_dict_header('key_without_value') + {'key_without_value': None} + + To create a header from the :class:`dict` again, use the + :func:`dump_header` function. + + :param value: a string with a dict header. + :return: :class:`dict` + :rtype: dict + """ + result = {} + for item in _parse_list_header(value): + if "=" not in item: + result[item] = None + continue + name, value = item.split("=", 1) + if value[:1] == value[-1:] == '"': + value = unquote_header_value(value[1:-1]) + result[name] = value + return result + + +# From mitsuhiko/werkzeug (used with permission). +def unquote_header_value(value, is_filename=False): + r"""Unquotes a header value. (Reversal of :func:`quote_header_value`). + This does not use the real unquoting but what browsers are actually + using for quoting. + + :param value: the header value to unquote. + :rtype: str + """ + if value and value[0] == value[-1] == '"': + # this is not the real unquoting, but fixing this so that the + # RFC is met will result in bugs with internet explorer and + # probably some other browsers as well. IE for example is + # uploading files with "C:\foo\bar.txt" as filename + value = value[1:-1] + + # if this is a filename and the starting characters look like + # a UNC path, then just return the value without quotes. Using the + # replace sequence below on a UNC path has the effect of turning + # the leading double slash into a single slash and then + # _fix_ie_filename() doesn't work correctly. See #458. + if not is_filename or value[:2] != "\\\\": + return value.replace("\\\\", "\\").replace('\\"', '"') + return value + + +def dict_from_cookiejar(cj): + """Returns a key/value dictionary from a CookieJar. + + :param cj: CookieJar object to extract cookies from. + :rtype: dict + """ + + cookie_dict = {} + + for cookie in cj: + cookie_dict[cookie.name] = cookie.value + + return cookie_dict + + +def add_dict_to_cookiejar(cj, cookie_dict): + """Returns a CookieJar from a key/value dictionary. + + :param cj: CookieJar to insert cookies into. + :param cookie_dict: Dict of key/values to insert into CookieJar. + :rtype: CookieJar + """ + + return cookiejar_from_dict(cookie_dict, cj) + + +def get_encodings_from_content(content): + """Returns encodings from given content string. + + :param content: bytestring to extract encodings from. + """ + warnings.warn( + ( + "In requests 3.0, get_encodings_from_content will be removed. For " + "more information, please see the discussion on issue #2266. (This" + " warning should only appear once.)" + ), + DeprecationWarning, + ) + + charset_re = re.compile(r']', flags=re.I) + pragma_re = re.compile(r']', flags=re.I) + xml_re = re.compile(r'^<\?xml.*?encoding=["\']*(.+?)["\'>]') + + return ( + charset_re.findall(content) + + pragma_re.findall(content) + + xml_re.findall(content) + ) + + +def _parse_content_type_header(header): + """Returns content type and parameters from given header + + :param header: string + :return: tuple containing content type and dictionary of + parameters + """ + + tokens = header.split(";") + content_type, params = tokens[0].strip(), tokens[1:] + params_dict = {} + items_to_strip = "\"' " + + for param in params: + param = param.strip() + if param: + key, value = param, True + index_of_equals = param.find("=") + if index_of_equals != -1: + key = param[:index_of_equals].strip(items_to_strip) + value = param[index_of_equals + 1 :].strip(items_to_strip) + params_dict[key.lower()] = value + return content_type, params_dict + + +def get_encoding_from_headers(headers): + """Returns encodings from given HTTP Header Dict. + + :param headers: dictionary to extract encoding from. + :rtype: str + """ + + content_type = headers.get("content-type") + + if not content_type: + return None + + content_type, params = _parse_content_type_header(content_type) + + if "charset" in params: + return params["charset"].strip("'\"") + + if "text" in content_type: + return "ISO-8859-1" + + if "application/json" in content_type: + # Assume UTF-8 based on RFC 4627: https://www.ietf.org/rfc/rfc4627.txt since the charset was unset + return "utf-8" + + +def stream_decode_response_unicode(iterator, r): + """Stream decodes an iterator.""" + + if r.encoding is None: + yield from iterator + return + + decoder = codecs.getincrementaldecoder(r.encoding)(errors="replace") + for chunk in iterator: + rv = decoder.decode(chunk) + if rv: + yield rv + rv = decoder.decode(b"", final=True) + if rv: + yield rv + + +def iter_slices(string, slice_length): + """Iterate over slices of a string.""" + pos = 0 + if slice_length is None or slice_length <= 0: + slice_length = len(string) + while pos < len(string): + yield string[pos : pos + slice_length] + pos += slice_length + + +def get_unicode_from_response(r): + """Returns the requested content back in unicode. + + :param r: Response object to get unicode content from. + + Tried: + + 1. charset from content-type + 2. fall back and replace all unicode characters + + :rtype: str + """ + warnings.warn( + ( + "In requests 3.0, get_unicode_from_response will be removed. For " + "more information, please see the discussion on issue #2266. (This" + " warning should only appear once.)" + ), + DeprecationWarning, + ) + + tried_encodings = [] + + # Try charset from content-type + encoding = get_encoding_from_headers(r.headers) + + if encoding: + try: + return str(r.content, encoding) + except UnicodeError: + tried_encodings.append(encoding) + + # Fall back: + try: + return str(r.content, encoding, errors="replace") + except TypeError: + return r.content + + +# The unreserved URI characters (RFC 3986) +UNRESERVED_SET = frozenset( + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" + "0123456789-._~" +) + + +def unquote_unreserved(uri): + """Un-escape any percent-escape sequences in a URI that are unreserved + characters. This leaves all reserved, illegal and non-ASCII bytes encoded. + + :rtype: str + """ + parts = uri.split("%") + for i in range(1, len(parts)): + h = parts[i][0:2] + if len(h) == 2 and h.isalnum(): + try: + c = chr(int(h, 16)) + except ValueError: + raise InvalidURL(f"Invalid percent-escape sequence: '{h}'") + + if c in UNRESERVED_SET: + parts[i] = c + parts[i][2:] + else: + parts[i] = f"%{parts[i]}" + else: + parts[i] = f"%{parts[i]}" + return "".join(parts) + + +def requote_uri(uri): + """Re-quote the given URI. + + This function passes the given URI through an unquote/quote cycle to + ensure that it is fully and consistently quoted. + + :rtype: str + """ + safe_with_percent = "!#$%&'()*+,/:;=?@[]~" + safe_without_percent = "!#$&'()*+,/:;=?@[]~" + try: + # Unquote only the unreserved characters + # Then quote only illegal characters (do not quote reserved, + # unreserved, or '%') + return quote(unquote_unreserved(uri), safe=safe_with_percent) + except InvalidURL: + # We couldn't unquote the given URI, so let's try quoting it, but + # there may be unquoted '%'s in the URI. We need to make sure they're + # properly quoted so they do not cause issues elsewhere. + return quote(uri, safe=safe_without_percent) + + +def address_in_network(ip, net): + """This function allows you to check if an IP belongs to a network subnet + + Example: returns True if ip = 192.168.1.1 and net = 192.168.1.0/24 + returns False if ip = 192.168.1.1 and net = 192.168.100.0/24 + + :rtype: bool + """ + ipaddr = struct.unpack("=L", socket.inet_aton(ip))[0] + netaddr, bits = net.split("/") + netmask = struct.unpack("=L", socket.inet_aton(dotted_netmask(int(bits))))[0] + network = struct.unpack("=L", socket.inet_aton(netaddr))[0] & netmask + return (ipaddr & netmask) == (network & netmask) + + +def dotted_netmask(mask): + """Converts mask from /xx format to xxx.xxx.xxx.xxx + + Example: if mask is 24 function returns 255.255.255.0 + + :rtype: str + """ + bits = 0xFFFFFFFF ^ (1 << 32 - mask) - 1 + return socket.inet_ntoa(struct.pack(">I", bits)) + + +def is_ipv4_address(string_ip): + """ + :rtype: bool + """ + try: + socket.inet_aton(string_ip) + except OSError: + return False + return True + + +def is_valid_cidr(string_network): + """ + Very simple check of the cidr format in no_proxy variable. + + :rtype: bool + """ + if string_network.count("/") == 1: + try: + mask = int(string_network.split("/")[1]) + except ValueError: + return False + + if mask < 1 or mask > 32: + return False + + try: + socket.inet_aton(string_network.split("/")[0]) + except OSError: + return False + else: + return False + return True + + +@contextlib.contextmanager +def set_environ(env_name, value): + """Set the environment variable 'env_name' to 'value' + + Save previous value, yield, and then restore the previous value stored in + the environment variable 'env_name'. + + If 'value' is None, do nothing""" + value_changed = value is not None + if value_changed: + old_value = os.environ.get(env_name) + os.environ[env_name] = value + try: + yield + finally: + if value_changed: + if old_value is None: + del os.environ[env_name] + else: + os.environ[env_name] = old_value + + +def should_bypass_proxies(url, no_proxy): + """ + Returns whether we should bypass proxies or not. + + :rtype: bool + """ + # Prioritize lowercase environment variables over uppercase + # to keep a consistent behaviour with other http projects (curl, wget). + def get_proxy(key): + return os.environ.get(key) or os.environ.get(key.upper()) + + # First check whether no_proxy is defined. If it is, check that the URL + # we're getting isn't in the no_proxy list. + no_proxy_arg = no_proxy + if no_proxy is None: + no_proxy = get_proxy("no_proxy") + parsed = urlparse(url) + + if parsed.hostname is None: + # URLs don't always have hostnames, e.g. file:/// urls. + return True + + if no_proxy: + # We need to check whether we match here. We need to see if we match + # the end of the hostname, both with and without the port. + no_proxy = (host for host in no_proxy.replace(" ", "").split(",") if host) + + if is_ipv4_address(parsed.hostname): + for proxy_ip in no_proxy: + if is_valid_cidr(proxy_ip): + if address_in_network(parsed.hostname, proxy_ip): + return True + elif parsed.hostname == proxy_ip: + # If no_proxy ip was defined in plain IP notation instead of cidr notation & + # matches the IP of the index + return True + else: + host_with_port = parsed.hostname + if parsed.port: + host_with_port += f":{parsed.port}" + + for host in no_proxy: + if parsed.hostname.endswith(host) or host_with_port.endswith(host): + # The URL does match something in no_proxy, so we don't want + # to apply the proxies on this URL. + return True + + with set_environ("no_proxy", no_proxy_arg): + # parsed.hostname can be `None` in cases such as a file URI. + try: + bypass = proxy_bypass(parsed.hostname) + except (TypeError, socket.gaierror): + bypass = False + + if bypass: + return True + + return False + + +def get_environ_proxies(url, no_proxy=None): + """ + Return a dict of environment proxies. + + :rtype: dict + """ + if should_bypass_proxies(url, no_proxy=no_proxy): + return {} + else: + return getproxies() + + +def select_proxy(url, proxies): + """Select a proxy for the url, if applicable. + + :param url: The url being for the request + :param proxies: A dictionary of schemes or schemes and hosts to proxy URLs + """ + proxies = proxies or {} + urlparts = urlparse(url) + if urlparts.hostname is None: + return proxies.get(urlparts.scheme, proxies.get("all")) + + proxy_keys = [ + urlparts.scheme + "://" + urlparts.hostname, + urlparts.scheme, + "all://" + urlparts.hostname, + "all", + ] + proxy = None + for proxy_key in proxy_keys: + if proxy_key in proxies: + proxy = proxies[proxy_key] + break + + return proxy + + +def resolve_proxies(request, proxies, trust_env=True): + """This method takes proxy information from a request and configuration + input to resolve a mapping of target proxies. This will consider settings + such a NO_PROXY to strip proxy configurations. + + :param request: Request or PreparedRequest + :param proxies: A dictionary of schemes or schemes and hosts to proxy URLs + :param trust_env: Boolean declaring whether to trust environment configs + + :rtype: dict + """ + proxies = proxies if proxies is not None else {} + url = request.url + scheme = urlparse(url).scheme + no_proxy = proxies.get("no_proxy") + new_proxies = proxies.copy() + + if trust_env and not should_bypass_proxies(url, no_proxy=no_proxy): + environ_proxies = get_environ_proxies(url, no_proxy=no_proxy) + + proxy = environ_proxies.get(scheme, environ_proxies.get("all")) + + if proxy: + new_proxies.setdefault(scheme, proxy) + return new_proxies + + +def default_user_agent(name="python-requests"): + """ + Return a string representing the default user agent. + + :rtype: str + """ + return f"{name}/{__version__}" + + +def default_headers(): + """ + :rtype: requests.structures.CaseInsensitiveDict + """ + return CaseInsensitiveDict( + { + "User-Agent": default_user_agent(), + "Accept-Encoding": DEFAULT_ACCEPT_ENCODING, + "Accept": "*/*", + "Connection": "keep-alive", + } + ) + + +def parse_header_links(value): + """Return a list of parsed link headers proxies. + + i.e. Link: ; rel=front; type="image/jpeg",; rel=back;type="image/jpeg" + + :rtype: list + """ + + links = [] + + replace_chars = " '\"" + + value = value.strip(replace_chars) + if not value: + return links + + for val in re.split(", *<", value): + try: + url, params = val.split(";", 1) + except ValueError: + url, params = val, "" + + link = {"url": url.strip("<> '\"")} + + for param in params.split(";"): + try: + key, value = param.split("=") + except ValueError: + break + + link[key.strip(replace_chars)] = value.strip(replace_chars) + + links.append(link) + + return links + + +# Null bytes; no need to recreate these on each call to guess_json_utf +_null = "\x00".encode("ascii") # encoding to ASCII for Python 3 +_null2 = _null * 2 +_null3 = _null * 3 + + +def guess_json_utf(data): + """ + :rtype: str + """ + # JSON always starts with two ASCII characters, so detection is as + # easy as counting the nulls and from their location and count + # determine the encoding. Also detect a BOM, if present. + sample = data[:4] + if sample in (codecs.BOM_UTF32_LE, codecs.BOM_UTF32_BE): + return "utf-32" # BOM included + if sample[:3] == codecs.BOM_UTF8: + return "utf-8-sig" # BOM included, MS style (discouraged) + if sample[:2] in (codecs.BOM_UTF16_LE, codecs.BOM_UTF16_BE): + return "utf-16" # BOM included + nullcount = sample.count(_null) + if nullcount == 0: + return "utf-8" + if nullcount == 2: + if sample[::2] == _null2: # 1st and 3rd are null + return "utf-16-be" + if sample[1::2] == _null2: # 2nd and 4th are null + return "utf-16-le" + # Did not detect 2 valid UTF-16 ascii-range characters + if nullcount == 3: + if sample[:3] == _null3: + return "utf-32-be" + if sample[1:] == _null3: + return "utf-32-le" + # Did not detect a valid UTF-32 ascii-range character + return None + + +def prepend_scheme_if_needed(url, new_scheme): + """Given a URL that may or may not have a scheme, prepend the given scheme. + Does not replace a present scheme with the one provided as an argument. + + :rtype: str + """ + parsed = parse_url(url) + scheme, auth, host, port, path, query, fragment = parsed + + # A defect in urlparse determines that there isn't a netloc present in some + # urls. We previously assumed parsing was overly cautious, and swapped the + # netloc and path. Due to a lack of tests on the original defect, this is + # maintained with parse_url for backwards compatibility. + netloc = parsed.netloc + if not netloc: + netloc, path = path, netloc + + if auth: + # parse_url doesn't provide the netloc with auth + # so we'll add it ourselves. + netloc = "@".join([auth, netloc]) + if scheme is None: + scheme = new_scheme + if path is None: + path = "" + + return urlunparse((scheme, netloc, path, "", query, fragment)) + + +def get_auth_from_url(url): + """Given a url with authentication components, extract them into a tuple of + username,password. + + :rtype: (str,str) + """ + parsed = urlparse(url) + + try: + auth = (unquote(parsed.username), unquote(parsed.password)) + except (AttributeError, TypeError): + auth = ("", "") + + return auth + + +def check_header_validity(header): + """Verifies that header parts don't contain leading whitespace + reserved characters, or return characters. + + :param header: tuple, in the format (name, value). + """ + name, value = header + + for part in header: + if type(part) not in HEADER_VALIDATORS: + raise InvalidHeader( + f"Header part ({part!r}) from {{{name!r}: {value!r}}} must be " + f"of type str or bytes, not {type(part)}" + ) + + _validate_header_part(name, "name", HEADER_VALIDATORS[type(name)][0]) + _validate_header_part(value, "value", HEADER_VALIDATORS[type(value)][1]) + + +def _validate_header_part(header_part, header_kind, validator): + if not validator.match(header_part): + raise InvalidHeader( + f"Invalid leading whitespace, reserved character(s), or return" + f"character(s) in header {header_kind}: {header_part!r}" + ) + + +def urldefragauth(url): + """ + Given a url remove the fragment and the authentication part. + + :rtype: str + """ + scheme, netloc, path, params, query, fragment = urlparse(url) + + # see func:`prepend_scheme_if_needed` + if not netloc: + netloc, path = path, netloc + + netloc = netloc.rsplit("@", 1)[-1] + + return urlunparse((scheme, netloc, path, params, query, "")) + + +def rewind_body(prepared_request): + """Move file pointer back to its recorded starting position + so it can be read again on redirect. + """ + body_seek = getattr(prepared_request.body, "seek", None) + if body_seek is not None and isinstance( + prepared_request._body_position, integer_types + ): + try: + body_seek(prepared_request._body_position) + except OSError: + raise UnrewindableBodyError( + "An error occurred when rewinding request body for redirect." + ) + else: + raise UnrewindableBodyError("Unable to rewind request body for redirect.") diff --git a/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/ruamel_yaml/emitter.py b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/ruamel_yaml/emitter.py new file mode 100644 index 0000000000000000000000000000000000000000..3ae99a1e6c8bd6d258d3e2cfa76a2c803d5f3393 --- /dev/null +++ b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/ruamel_yaml/emitter.py @@ -0,0 +1,1657 @@ +# coding: utf-8 + +from __future__ import absolute_import +from __future__ import print_function + +# Emitter expects events obeying the following grammar: +# stream ::= STREAM-START document* STREAM-END +# document ::= DOCUMENT-START node DOCUMENT-END +# node ::= SCALAR | sequence | mapping +# sequence ::= SEQUENCE-START node* SEQUENCE-END +# mapping ::= MAPPING-START (node node)* MAPPING-END + +import sys +from ruamel_yaml.error import YAMLError, YAMLStreamError +from ruamel_yaml.events import * # NOQA + +# fmt: off +from ruamel_yaml.compat import utf8, text_type, PY2, nprint, dbg, DBG_EVENT, \ + check_anchorname_char +# fmt: on + +if False: # MYPY + from typing import Any, Dict, List, Union, Text, Tuple, Optional # NOQA + from ruamel_yaml.compat import StreamType # NOQA + +__all__ = ['Emitter', 'EmitterError'] + + +class EmitterError(YAMLError): + pass + + +class ScalarAnalysis(object): + def __init__( + self, + scalar, + empty, + multiline, + allow_flow_plain, + allow_block_plain, + allow_single_quoted, + allow_double_quoted, + allow_block, + ): + # type: (Any, Any, Any, bool, bool, bool, bool, bool) -> None + self.scalar = scalar + self.empty = empty + self.multiline = multiline + self.allow_flow_plain = allow_flow_plain + self.allow_block_plain = allow_block_plain + self.allow_single_quoted = allow_single_quoted + self.allow_double_quoted = allow_double_quoted + self.allow_block = allow_block + + +class Indents(object): + # replacement for the list based stack of None/int + def __init__(self): + # type: () -> None + self.values = [] # type: List[Tuple[int, bool]] + + def append(self, val, seq): + # type: (Any, Any) -> None + self.values.append((val, seq)) + + def pop(self): + # type: () -> Any + return self.values.pop()[0] + + def last_seq(self): + # type: () -> bool + # return the seq(uence) value for the element added before the last one + # in increase_indent() + try: + return self.values[-2][1] + except IndexError: + return False + + def seq_flow_align(self, seq_indent, column): + # type: (int, int) -> int + # extra spaces because of dash + if len(self.values) < 2 or not self.values[-1][1]: + return 0 + # -1 for the dash + base = self.values[-1][0] if self.values[-1][0] is not None else 0 + return base + seq_indent - column - 1 + + def __len__(self): + # type: () -> int + return len(self.values) + + +class Emitter(object): + # fmt: off + DEFAULT_TAG_PREFIXES = { + u'!': u'!', + u'tag:yaml.org,2002:': u'!!', + } + # fmt: on + + MAX_SIMPLE_KEY_LENGTH = 128 + + def __init__( + self, + stream, + canonical=None, + indent=None, + width=None, + allow_unicode=None, + line_break=None, + block_seq_indent=None, + top_level_colon_align=None, + prefix_colon=None, + brace_single_entry_mapping_in_flow_sequence=None, + dumper=None, + ): + # type: (StreamType, Any, Optional[int], Optional[int], Optional[bool], Any, Optional[int], Optional[bool], Any, Optional[bool], Any) -> None # NOQA + self.dumper = dumper + if self.dumper is not None and getattr(self.dumper, '_emitter', None) is None: + self.dumper._emitter = self + self.stream = stream + + # Encoding can be overriden by STREAM-START. + self.encoding = None # type: Optional[Text] + self.allow_space_break = None + + # Emitter is a state machine with a stack of states to handle nested + # structures. + self.states = [] # type: List[Any] + self.state = self.expect_stream_start # type: Any + + # Current event and the event queue. + self.events = [] # type: List[Any] + self.event = None # type: Any + + # The current indentation level and the stack of previous indents. + self.indents = Indents() + self.indent = None # type: Optional[int] + + # flow_context is an expanding/shrinking list consisting of '{' and '[' + # for each unclosed flow context. If empty list that means block context + self.flow_context = [] # type: List[Text] + + # Contexts. + self.root_context = False + self.sequence_context = False + self.mapping_context = False + self.simple_key_context = False + + # Characteristics of the last emitted character: + # - current position. + # - is it a whitespace? + # - is it an indention character + # (indentation space, '-', '?', or ':')? + self.line = 0 + self.column = 0 + self.whitespace = True + self.indention = True + self.compact_seq_seq = True # dash after dash + self.compact_seq_map = True # key after dash + # self.compact_ms = False # dash after key, only when excplicit key with ? + self.no_newline = None # type: Optional[bool] # set if directly after `- ` + + # Whether the document requires an explicit document indicator + self.open_ended = False + + # colon handling + self.colon = u':' + self.prefixed_colon = self.colon if prefix_colon is None else prefix_colon + self.colon + # single entry mappings in flow sequence + self.brace_single_entry_mapping_in_flow_sequence = ( + brace_single_entry_mapping_in_flow_sequence + ) # NOQA + + # Formatting details. + self.canonical = canonical + self.allow_unicode = allow_unicode + # set to False to get "\Uxxxxxxxx" for non-basic unicode like emojis + self.unicode_supplementary = sys.maxunicode > 0xffff + self.sequence_dash_offset = block_seq_indent if block_seq_indent else 0 + self.top_level_colon_align = top_level_colon_align + self.best_sequence_indent = 2 + self.requested_indent = indent # specific for literal zero indent + if indent and 1 < indent < 10: + self.best_sequence_indent = indent + self.best_map_indent = self.best_sequence_indent + # if self.best_sequence_indent < self.sequence_dash_offset + 1: + # self.best_sequence_indent = self.sequence_dash_offset + 1 + self.best_width = 80 + if width and width > self.best_sequence_indent * 2: + self.best_width = width + self.best_line_break = u'\n' # type: Any + if line_break in [u'\r', u'\n', u'\r\n']: + self.best_line_break = line_break + + # Tag prefixes. + self.tag_prefixes = None # type: Any + + # Prepared anchor and tag. + self.prepared_anchor = None # type: Any + self.prepared_tag = None # type: Any + + # Scalar analysis and style. + self.analysis = None # type: Any + self.style = None # type: Any + + @property + def stream(self): + # type: () -> Any + try: + return self._stream + except AttributeError: + raise YAMLStreamError('output stream needs to specified') + + @stream.setter + def stream(self, val): + # type: (Any) -> None + if val is None: + return + if not hasattr(val, 'write'): + raise YAMLStreamError('stream argument needs to have a write() method') + self._stream = val + + @property + def serializer(self): + # type: () -> Any + try: + if hasattr(self.dumper, 'typ'): + return self.dumper.serializer + return self.dumper._serializer + except AttributeError: + return self # cyaml + + @property + def flow_level(self): + # type: () -> int + return len(self.flow_context) + + def dispose(self): + # type: () -> None + # Reset the state attributes (to clear self-references) + self.states = [] # type: List[Any] + self.state = None + + def emit(self, event): + # type: (Any) -> None + if dbg(DBG_EVENT): + nprint(event) + self.events.append(event) + while not self.need_more_events(): + self.event = self.events.pop(0) + self.state() + self.event = None + + # In some cases, we wait for a few next events before emitting. + + def need_more_events(self): + # type: () -> bool + if not self.events: + return True + event = self.events[0] + if isinstance(event, DocumentStartEvent): + return self.need_events(1) + elif isinstance(event, SequenceStartEvent): + return self.need_events(2) + elif isinstance(event, MappingStartEvent): + return self.need_events(3) + else: + return False + + def need_events(self, count): + # type: (int) -> bool + level = 0 + for event in self.events[1:]: + if isinstance(event, (DocumentStartEvent, CollectionStartEvent)): + level += 1 + elif isinstance(event, (DocumentEndEvent, CollectionEndEvent)): + level -= 1 + elif isinstance(event, StreamEndEvent): + level = -1 + if level < 0: + return False + return len(self.events) < count + 1 + + def increase_indent(self, flow=False, sequence=None, indentless=False): + # type: (bool, Optional[bool], bool) -> None + self.indents.append(self.indent, sequence) + if self.indent is None: # top level + if flow: + # self.indent = self.best_sequence_indent if self.indents.last_seq() else \ + # self.best_map_indent + # self.indent = self.best_sequence_indent + self.indent = self.requested_indent + else: + self.indent = 0 + elif not indentless: + self.indent += ( + self.best_sequence_indent if self.indents.last_seq() else self.best_map_indent + ) + # if self.indents.last_seq(): + # if self.indent == 0: # top level block sequence + # self.indent = self.best_sequence_indent - self.sequence_dash_offset + # else: + # self.indent += self.best_sequence_indent + # else: + # self.indent += self.best_map_indent + + # States. + + # Stream handlers. + + def expect_stream_start(self): + # type: () -> None + if isinstance(self.event, StreamStartEvent): + if PY2: + if self.event.encoding and not getattr(self.stream, 'encoding', None): + self.encoding = self.event.encoding + else: + if self.event.encoding and not hasattr(self.stream, 'encoding'): + self.encoding = self.event.encoding + self.write_stream_start() + self.state = self.expect_first_document_start + else: + raise EmitterError('expected StreamStartEvent, but got %s' % self.event) + + def expect_nothing(self): + # type: () -> None + raise EmitterError('expected nothing, but got %s' % self.event) + + # Document handlers. + + def expect_first_document_start(self): + # type: () -> Any + return self.expect_document_start(first=True) + + def expect_document_start(self, first=False): + # type: (bool) -> None + if isinstance(self.event, DocumentStartEvent): + if (self.event.version or self.event.tags) and self.open_ended: + self.write_indicator(u'...', True) + self.write_indent() + if self.event.version: + version_text = self.prepare_version(self.event.version) + self.write_version_directive(version_text) + self.tag_prefixes = self.DEFAULT_TAG_PREFIXES.copy() + if self.event.tags: + handles = sorted(self.event.tags.keys()) + for handle in handles: + prefix = self.event.tags[handle] + self.tag_prefixes[prefix] = handle + handle_text = self.prepare_tag_handle(handle) + prefix_text = self.prepare_tag_prefix(prefix) + self.write_tag_directive(handle_text, prefix_text) + implicit = ( + first + and not self.event.explicit + and not self.canonical + and not self.event.version + and not self.event.tags + and not self.check_empty_document() + ) + if not implicit: + self.write_indent() + self.write_indicator(u'---', True) + if self.canonical: + self.write_indent() + self.state = self.expect_document_root + elif isinstance(self.event, StreamEndEvent): + if self.open_ended: + self.write_indicator(u'...', True) + self.write_indent() + self.write_stream_end() + self.state = self.expect_nothing + else: + raise EmitterError('expected DocumentStartEvent, but got %s' % self.event) + + def expect_document_end(self): + # type: () -> None + if isinstance(self.event, DocumentEndEvent): + self.write_indent() + if self.event.explicit: + self.write_indicator(u'...', True) + self.write_indent() + self.flush_stream() + self.state = self.expect_document_start + else: + raise EmitterError('expected DocumentEndEvent, but got %s' % self.event) + + def expect_document_root(self): + # type: () -> None + self.states.append(self.expect_document_end) + self.expect_node(root=True) + + # Node handlers. + + def expect_node(self, root=False, sequence=False, mapping=False, simple_key=False): + # type: (bool, bool, bool, bool) -> None + self.root_context = root + self.sequence_context = sequence # not used in PyYAML + self.mapping_context = mapping + self.simple_key_context = simple_key + if isinstance(self.event, AliasEvent): + self.expect_alias() + elif isinstance(self.event, (ScalarEvent, CollectionStartEvent)): + self.process_anchor(u'&') + self.process_tag() + if isinstance(self.event, ScalarEvent): + self.expect_scalar() + elif isinstance(self.event, SequenceStartEvent): + # nprintf('@', self.indention, self.no_newline, self.column) + i2, n2 = self.indention, self.no_newline # NOQA + if self.event.comment: + if self.event.flow_style is False and self.event.comment: + if self.write_post_comment(self.event): + self.indention = False + self.no_newline = True + if self.write_pre_comment(self.event): + pass + self.indention = i2 + self.no_newline = not self.indention + if ( + self.flow_level + or self.canonical + or self.event.flow_style + or self.check_empty_sequence() + ): + self.expect_flow_sequence() + else: + self.expect_block_sequence() + elif isinstance(self.event, MappingStartEvent): + if self.event.flow_style is False and self.event.comment: + self.write_post_comment(self.event) + if self.event.comment and self.event.comment[1]: + self.write_pre_comment(self.event) + if ( + self.flow_level + or self.canonical + or self.event.flow_style + or self.check_empty_mapping() + ): + self.expect_flow_mapping(single=self.event.nr_items == 1) + else: + self.expect_block_mapping() + else: + raise EmitterError('expected NodeEvent, but got %s' % self.event) + + def expect_alias(self): + # type: () -> None + if self.event.anchor is None: + raise EmitterError('anchor is not specified for alias') + self.process_anchor(u'*') + self.state = self.states.pop() + + def expect_scalar(self): + # type: () -> None + self.increase_indent(flow=True) + self.process_scalar() + self.indent = self.indents.pop() + self.state = self.states.pop() + + # Flow sequence handlers. + + def expect_flow_sequence(self): + # type: () -> None + ind = self.indents.seq_flow_align(self.best_sequence_indent, self.column) + self.write_indicator(u' ' * ind + u'[', True, whitespace=True) + self.increase_indent(flow=True, sequence=True) + self.flow_context.append('[') + self.state = self.expect_first_flow_sequence_item + + def expect_first_flow_sequence_item(self): + # type: () -> None + if isinstance(self.event, SequenceEndEvent): + self.indent = self.indents.pop() + popped = self.flow_context.pop() + assert popped == '[' + self.write_indicator(u']', False) + if self.event.comment and self.event.comment[0]: + # eol comment on empty flow sequence + self.write_post_comment(self.event) + elif self.flow_level == 0: + self.write_line_break() + self.state = self.states.pop() + else: + if self.canonical or self.column > self.best_width: + self.write_indent() + self.states.append(self.expect_flow_sequence_item) + self.expect_node(sequence=True) + + def expect_flow_sequence_item(self): + # type: () -> None + if isinstance(self.event, SequenceEndEvent): + self.indent = self.indents.pop() + popped = self.flow_context.pop() + assert popped == '[' + if self.canonical: + self.write_indicator(u',', False) + self.write_indent() + self.write_indicator(u']', False) + if self.event.comment and self.event.comment[0]: + # eol comment on flow sequence + self.write_post_comment(self.event) + else: + self.no_newline = False + self.state = self.states.pop() + else: + self.write_indicator(u',', False) + if self.canonical or self.column > self.best_width: + self.write_indent() + self.states.append(self.expect_flow_sequence_item) + self.expect_node(sequence=True) + + # Flow mapping handlers. + + def expect_flow_mapping(self, single=False): + # type: (Optional[bool]) -> None + ind = self.indents.seq_flow_align(self.best_sequence_indent, self.column) + map_init = u'{' + if ( + single + and self.flow_level + and self.flow_context[-1] == '[' + and not self.canonical + and not self.brace_single_entry_mapping_in_flow_sequence + ): + # single map item with flow context, no curly braces necessary + map_init = u'' + self.write_indicator(u' ' * ind + map_init, True, whitespace=True) + self.flow_context.append(map_init) + self.increase_indent(flow=True, sequence=False) + self.state = self.expect_first_flow_mapping_key + + def expect_first_flow_mapping_key(self): + # type: () -> None + if isinstance(self.event, MappingEndEvent): + self.indent = self.indents.pop() + popped = self.flow_context.pop() + assert popped == '{' # empty flow mapping + self.write_indicator(u'}', False) + if self.event.comment and self.event.comment[0]: + # eol comment on empty mapping + self.write_post_comment(self.event) + self.state = self.states.pop() + else: + if self.canonical or self.column > self.best_width: + self.write_indent() + if not self.canonical and self.check_simple_key(): + self.states.append(self.expect_flow_mapping_simple_value) + self.expect_node(mapping=True, simple_key=True) + else: + self.write_indicator(u'?', True) + self.states.append(self.expect_flow_mapping_value) + self.expect_node(mapping=True) + + def expect_flow_mapping_key(self): + # type: () -> None + if isinstance(self.event, MappingEndEvent): + # if self.event.comment and self.event.comment[1]: + # self.write_pre_comment(self.event) + self.indent = self.indents.pop() + popped = self.flow_context.pop() + assert popped in [u'{', u''] + if self.canonical: + self.write_indicator(u',', False) + self.write_indent() + if popped != u'': + self.write_indicator(u'}', False) + if self.event.comment and self.event.comment[0]: + # eol comment on flow mapping, never reached on empty mappings + self.write_post_comment(self.event) + self.state = self.states.pop() + else: + self.write_indicator(u',', False) + if self.canonical or self.column > self.best_width: + self.write_indent() + if not self.canonical and self.check_simple_key(): + self.states.append(self.expect_flow_mapping_simple_value) + self.expect_node(mapping=True, simple_key=True) + else: + self.write_indicator(u'?', True) + self.states.append(self.expect_flow_mapping_value) + self.expect_node(mapping=True) + + def expect_flow_mapping_simple_value(self): + # type: () -> None + self.write_indicator(self.prefixed_colon, False) + self.states.append(self.expect_flow_mapping_key) + self.expect_node(mapping=True) + + def expect_flow_mapping_value(self): + # type: () -> None + if self.canonical or self.column > self.best_width: + self.write_indent() + self.write_indicator(self.prefixed_colon, True) + self.states.append(self.expect_flow_mapping_key) + self.expect_node(mapping=True) + + # Block sequence handlers. + + def expect_block_sequence(self): + # type: () -> None + if self.mapping_context: + indentless = not self.indention + else: + indentless = False + if not self.compact_seq_seq and self.column != 0: + self.write_line_break() + self.increase_indent(flow=False, sequence=True, indentless=indentless) + self.state = self.expect_first_block_sequence_item + + def expect_first_block_sequence_item(self): + # type: () -> Any + return self.expect_block_sequence_item(first=True) + + def expect_block_sequence_item(self, first=False): + # type: (bool) -> None + if not first and isinstance(self.event, SequenceEndEvent): + if self.event.comment and self.event.comment[1]: + # final comments on a block list e.g. empty line + self.write_pre_comment(self.event) + self.indent = self.indents.pop() + self.state = self.states.pop() + self.no_newline = False + else: + if self.event.comment and self.event.comment[1]: + self.write_pre_comment(self.event) + nonl = self.no_newline if self.column == 0 else False + self.write_indent() + ind = self.sequence_dash_offset # if len(self.indents) > 1 else 0 + self.write_indicator(u' ' * ind + u'-', True, indention=True) + if nonl or self.sequence_dash_offset + 2 > self.best_sequence_indent: + self.no_newline = True + self.states.append(self.expect_block_sequence_item) + self.expect_node(sequence=True) + + # Block mapping handlers. + + def expect_block_mapping(self): + # type: () -> None + if not self.mapping_context and not (self.compact_seq_map or self.column == 0): + self.write_line_break() + self.increase_indent(flow=False, sequence=False) + self.state = self.expect_first_block_mapping_key + + def expect_first_block_mapping_key(self): + # type: () -> None + return self.expect_block_mapping_key(first=True) + + def expect_block_mapping_key(self, first=False): + # type: (Any) -> None + if not first and isinstance(self.event, MappingEndEvent): + if self.event.comment and self.event.comment[1]: + # final comments from a doc + self.write_pre_comment(self.event) + self.indent = self.indents.pop() + self.state = self.states.pop() + else: + if self.event.comment and self.event.comment[1]: + # final comments from a doc + self.write_pre_comment(self.event) + self.write_indent() + if self.check_simple_key(): + if not isinstance( + self.event, (SequenceStartEvent, MappingStartEvent) + ): # sequence keys + if self.event.style == '?': + self.write_indicator(u'?', True, indention=True) + self.states.append(self.expect_block_mapping_simple_value) + self.expect_node(mapping=True, simple_key=True) + else: + self.write_indicator(u'?', True, indention=True) + self.states.append(self.expect_block_mapping_value) + self.expect_node(mapping=True) + + def expect_block_mapping_simple_value(self): + # type: () -> None + if getattr(self.event, 'style', None) != '?': + # prefix = u'' + if self.indent == 0 and self.top_level_colon_align is not None: + # write non-prefixed colon + c = u' ' * (self.top_level_colon_align - self.column) + self.colon + else: + c = self.prefixed_colon + self.write_indicator(c, False) + self.states.append(self.expect_block_mapping_key) + self.expect_node(mapping=True) + + def expect_block_mapping_value(self): + # type: () -> None + self.write_indent() + self.write_indicator(self.prefixed_colon, True, indention=True) + self.states.append(self.expect_block_mapping_key) + self.expect_node(mapping=True) + + # Checkers. + + def check_empty_sequence(self): + # type: () -> bool + return ( + isinstance(self.event, SequenceStartEvent) + and bool(self.events) + and isinstance(self.events[0], SequenceEndEvent) + ) + + def check_empty_mapping(self): + # type: () -> bool + return ( + isinstance(self.event, MappingStartEvent) + and bool(self.events) + and isinstance(self.events[0], MappingEndEvent) + ) + + def check_empty_document(self): + # type: () -> bool + if not isinstance(self.event, DocumentStartEvent) or not self.events: + return False + event = self.events[0] + return ( + isinstance(event, ScalarEvent) + and event.anchor is None + and event.tag is None + and event.implicit + and event.value == "" + ) + + def check_simple_key(self): + # type: () -> bool + length = 0 + if isinstance(self.event, NodeEvent) and self.event.anchor is not None: + if self.prepared_anchor is None: + self.prepared_anchor = self.prepare_anchor(self.event.anchor) + length += len(self.prepared_anchor) + if ( + isinstance(self.event, (ScalarEvent, CollectionStartEvent)) + and self.event.tag is not None + ): + if self.prepared_tag is None: + self.prepared_tag = self.prepare_tag(self.event.tag) + length += len(self.prepared_tag) + if isinstance(self.event, ScalarEvent): + if self.analysis is None: + self.analysis = self.analyze_scalar(self.event.value) + length += len(self.analysis.scalar) + return length < self.MAX_SIMPLE_KEY_LENGTH and ( + isinstance(self.event, AliasEvent) + or (isinstance(self.event, SequenceStartEvent) and self.event.flow_style is True) + or (isinstance(self.event, MappingStartEvent) and self.event.flow_style is True) + or ( + isinstance(self.event, ScalarEvent) + and not self.analysis.empty + and not self.analysis.multiline + ) + or self.check_empty_sequence() + or self.check_empty_mapping() + ) + + # Anchor, Tag, and Scalar processors. + + def process_anchor(self, indicator): + # type: (Any) -> None + if self.event.anchor is None: + self.prepared_anchor = None + return + if self.prepared_anchor is None: + self.prepared_anchor = self.prepare_anchor(self.event.anchor) + if self.prepared_anchor: + self.write_indicator(indicator + self.prepared_anchor, True) + self.prepared_anchor = None + + def process_tag(self): + # type: () -> None + tag = self.event.tag + if isinstance(self.event, ScalarEvent): + if self.style is None: + self.style = self.choose_scalar_style() + if (not self.canonical or tag is None) and ( + (self.style == "" and self.event.implicit[0]) + or (self.style != "" and self.event.implicit[1]) + ): + self.prepared_tag = None + return + if self.event.implicit[0] and tag is None: + tag = u'!' + self.prepared_tag = None + else: + if (not self.canonical or tag is None) and self.event.implicit: + self.prepared_tag = None + return + if tag is None: + raise EmitterError('tag is not specified') + if self.prepared_tag is None: + self.prepared_tag = self.prepare_tag(tag) + if self.prepared_tag: + self.write_indicator(self.prepared_tag, True) + if ( + self.sequence_context + and not self.flow_level + and isinstance(self.event, ScalarEvent) + ): + self.no_newline = True + self.prepared_tag = None + + def choose_scalar_style(self): + # type: () -> Any + if self.analysis is None: + self.analysis = self.analyze_scalar(self.event.value) + if self.event.style == '"' or self.canonical: + return '"' + if (not self.event.style or self.event.style == '?') and ( + self.event.implicit[0] or not self.event.implicit[2] + ): + if not ( + self.simple_key_context and (self.analysis.empty or self.analysis.multiline) + ) and ( + self.flow_level + and self.analysis.allow_flow_plain + or (not self.flow_level and self.analysis.allow_block_plain) + ): + return "" + self.analysis.allow_block = True + if self.event.style and self.event.style in '|>': + if ( + not self.flow_level + and not self.simple_key_context + and self.analysis.allow_block + ): + return self.event.style + if not self.event.style and self.analysis.allow_double_quoted: + if "'" in self.event.value or '\n' in self.event.value: + return '"' + if not self.event.style or self.event.style == "'": + if self.analysis.allow_single_quoted and not ( + self.simple_key_context and self.analysis.multiline + ): + return "'" + return '"' + + def process_scalar(self): + # type: () -> None + if self.analysis is None: + self.analysis = self.analyze_scalar(self.event.value) + if self.style is None: + self.style = self.choose_scalar_style() + split = not self.simple_key_context + # if self.analysis.multiline and split \ + # and (not self.style or self.style in '\'\"'): + # self.write_indent() + if self.sequence_context and not self.flow_level: + self.write_indent() + if self.style == '"': + self.write_double_quoted(self.analysis.scalar, split) + elif self.style == "'": + self.write_single_quoted(self.analysis.scalar, split) + elif self.style == '>': + self.write_folded(self.analysis.scalar) + elif self.style == '|': + self.write_literal(self.analysis.scalar, self.event.comment) + else: + self.write_plain(self.analysis.scalar, split) + self.analysis = None + self.style = None + if self.event.comment: + self.write_post_comment(self.event) + + # Analyzers. + + def prepare_version(self, version): + # type: (Any) -> Any + major, minor = version + if major != 1: + raise EmitterError('unsupported YAML version: %d.%d' % (major, minor)) + return u'%d.%d' % (major, minor) + + def prepare_tag_handle(self, handle): + # type: (Any) -> Any + if not handle: + raise EmitterError('tag handle must not be empty') + if handle[0] != u'!' or handle[-1] != u'!': + raise EmitterError("tag handle must start and end with '!': %r" % (utf8(handle))) + for ch in handle[1:-1]: + if not ( + u'0' <= ch <= u'9' or u'A' <= ch <= u'Z' or u'a' <= ch <= u'z' or ch in u'-_' + ): + raise EmitterError( + 'invalid character %r in the tag handle: %r' % (utf8(ch), utf8(handle)) + ) + return handle + + def prepare_tag_prefix(self, prefix): + # type: (Any) -> Any + if not prefix: + raise EmitterError('tag prefix must not be empty') + chunks = [] # type: List[Any] + start = end = 0 + if prefix[0] == u'!': + end = 1 + while end < len(prefix): + ch = prefix[end] + if ( + u'0' <= ch <= u'9' + or u'A' <= ch <= u'Z' + or u'a' <= ch <= u'z' + or ch in u"-;/?!:@&=+$,_.~*'()[]" + ): + end += 1 + else: + if start < end: + chunks.append(prefix[start:end]) + start = end = end + 1 + data = utf8(ch) + for ch in data: + chunks.append(u'%%%02X' % ord(ch)) + if start < end: + chunks.append(prefix[start:end]) + return "".join(chunks) + + def prepare_tag(self, tag): + # type: (Any) -> Any + if not tag: + raise EmitterError('tag must not be empty') + if tag == u'!': + return tag + handle = None + suffix = tag + prefixes = sorted(self.tag_prefixes.keys()) + for prefix in prefixes: + if tag.startswith(prefix) and (prefix == u'!' or len(prefix) < len(tag)): + handle = self.tag_prefixes[prefix] + suffix = tag[len(prefix) :] + chunks = [] # type: List[Any] + start = end = 0 + while end < len(suffix): + ch = suffix[end] + if ( + u'0' <= ch <= u'9' + or u'A' <= ch <= u'Z' + or u'a' <= ch <= u'z' + or ch in u"-;/?:@&=+$,_.~*'()[]" + or (ch == u'!' and handle != u'!') + ): + end += 1 + else: + if start < end: + chunks.append(suffix[start:end]) + start = end = end + 1 + data = utf8(ch) + for ch in data: + chunks.append(u'%%%02X' % ord(ch)) + if start < end: + chunks.append(suffix[start:end]) + suffix_text = "".join(chunks) + if handle: + return u'%s%s' % (handle, suffix_text) + else: + return u'!<%s>' % suffix_text + + def prepare_anchor(self, anchor): + # type: (Any) -> Any + if not anchor: + raise EmitterError('anchor must not be empty') + for ch in anchor: + if not check_anchorname_char(ch): + raise EmitterError( + 'invalid character %r in the anchor: %r' % (utf8(ch), utf8(anchor)) + ) + return anchor + + def analyze_scalar(self, scalar): + # type: (Any) -> Any + # Empty scalar is a special case. + if not scalar: + return ScalarAnalysis( + scalar=scalar, + empty=True, + multiline=False, + allow_flow_plain=False, + allow_block_plain=True, + allow_single_quoted=True, + allow_double_quoted=True, + allow_block=False, + ) + + # Indicators and special characters. + block_indicators = False + flow_indicators = False + line_breaks = False + special_characters = False + + # Important whitespace combinations. + leading_space = False + leading_break = False + trailing_space = False + trailing_break = False + break_space = False + space_break = False + + # Check document indicators. + if scalar.startswith(u'---') or scalar.startswith(u'...'): + block_indicators = True + flow_indicators = True + + # First character or preceded by a whitespace. + preceeded_by_whitespace = True + + # Last character or followed by a whitespace. + followed_by_whitespace = len(scalar) == 1 or scalar[1] in u'\0 \t\r\n\x85\u2028\u2029' + + # The previous character is a space. + previous_space = False + + # The previous character is a break. + previous_break = False + + index = 0 + while index < len(scalar): + ch = scalar[index] + + # Check for indicators. + if index == 0: + # Leading indicators are special characters. + if ch in u'#,[]{}&*!|>\'"%@`': + flow_indicators = True + block_indicators = True + if ch in u'?:': # ToDo + if self.serializer.use_version == (1, 1): + flow_indicators = True + elif len(scalar) == 1: # single character + flow_indicators = True + if followed_by_whitespace: + block_indicators = True + if ch == u'-' and followed_by_whitespace: + flow_indicators = True + block_indicators = True + else: + # Some indicators cannot appear within a scalar as well. + if ch in u',[]{}': # http://yaml.org/spec/1.2/spec.html#id2788859 + flow_indicators = True + if ch == u'?' and self.serializer.use_version == (1, 1): + flow_indicators = True + if ch == u':': + if followed_by_whitespace: + flow_indicators = True + block_indicators = True + if ch == u'#' and preceeded_by_whitespace: + flow_indicators = True + block_indicators = True + + # Check for line breaks, special, and unicode characters. + if ch in u'\n\x85\u2028\u2029': + line_breaks = True + if not (ch == u'\n' or u'\x20' <= ch <= u'\x7E'): + if ( + ch == u'\x85' + or u'\xA0' <= ch <= u'\uD7FF' + or u'\uE000' <= ch <= u'\uFFFD' + or (self.unicode_supplementary and (u'\U00010000' <= ch <= u'\U0010FFFF')) + ) and ch != u'\uFEFF': + # unicode_characters = True + if not self.allow_unicode: + special_characters = True + else: + special_characters = True + + # Detect important whitespace combinations. + if ch == u' ': + if index == 0: + leading_space = True + if index == len(scalar) - 1: + trailing_space = True + if previous_break: + break_space = True + previous_space = True + previous_break = False + elif ch in u'\n\x85\u2028\u2029': + if index == 0: + leading_break = True + if index == len(scalar) - 1: + trailing_break = True + if previous_space: + space_break = True + previous_space = False + previous_break = True + else: + previous_space = False + previous_break = False + + # Prepare for the next character. + index += 1 + preceeded_by_whitespace = ch in u'\0 \t\r\n\x85\u2028\u2029' + followed_by_whitespace = ( + index + 1 >= len(scalar) or scalar[index + 1] in u'\0 \t\r\n\x85\u2028\u2029' + ) + + # Let's decide what styles are allowed. + allow_flow_plain = True + allow_block_plain = True + allow_single_quoted = True + allow_double_quoted = True + allow_block = True + + # Leading and trailing whitespaces are bad for plain scalars. + if leading_space or leading_break or trailing_space or trailing_break: + allow_flow_plain = allow_block_plain = False + + # We do not permit trailing spaces for block scalars. + if trailing_space: + allow_block = False + + # Spaces at the beginning of a new line are only acceptable for block + # scalars. + if break_space: + allow_flow_plain = allow_block_plain = allow_single_quoted = False + + # Spaces followed by breaks, as well as special character are only + # allowed for double quoted scalars. + if special_characters: + allow_flow_plain = allow_block_plain = allow_single_quoted = allow_block = False + elif space_break: + allow_flow_plain = allow_block_plain = allow_single_quoted = False + if not self.allow_space_break: + allow_block = False + + # Although the plain scalar writer supports breaks, we never emit + # multiline plain scalars. + if line_breaks: + allow_flow_plain = allow_block_plain = False + + # Flow indicators are forbidden for flow plain scalars. + if flow_indicators: + allow_flow_plain = False + + # Block indicators are forbidden for block plain scalars. + if block_indicators: + allow_block_plain = False + + return ScalarAnalysis( + scalar=scalar, + empty=False, + multiline=line_breaks, + allow_flow_plain=allow_flow_plain, + allow_block_plain=allow_block_plain, + allow_single_quoted=allow_single_quoted, + allow_double_quoted=allow_double_quoted, + allow_block=allow_block, + ) + + # Writers. + + def flush_stream(self): + # type: () -> None + if hasattr(self.stream, 'flush'): + self.stream.flush() + + def write_stream_start(self): + # type: () -> None + # Write BOM if needed. + if self.encoding and self.encoding.startswith('utf-16'): + self.stream.write(u'\uFEFF'.encode(self.encoding)) + + def write_stream_end(self): + # type: () -> None + self.flush_stream() + + def write_indicator(self, indicator, need_whitespace, whitespace=False, indention=False): + # type: (Any, Any, bool, bool) -> None + if self.whitespace or not need_whitespace: + data = indicator + else: + data = u' ' + indicator + self.whitespace = whitespace + self.indention = self.indention and indention + self.column += len(data) + self.open_ended = False + if bool(self.encoding): + data = data.encode(self.encoding) + self.stream.write(data) + + def write_indent(self): + # type: () -> None + indent = self.indent or 0 + if ( + not self.indention + or self.column > indent + or (self.column == indent and not self.whitespace) + ): + if bool(self.no_newline): + self.no_newline = False + else: + self.write_line_break() + if self.column < indent: + self.whitespace = True + data = u' ' * (indent - self.column) + self.column = indent + if self.encoding: + data = data.encode(self.encoding) + self.stream.write(data) + + def write_line_break(self, data=None): + # type: (Any) -> None + if data is None: + data = self.best_line_break + self.whitespace = True + self.indention = True + self.line += 1 + self.column = 0 + if bool(self.encoding): + data = data.encode(self.encoding) + self.stream.write(data) + + def write_version_directive(self, version_text): + # type: (Any) -> None + data = u'%%YAML %s' % version_text + if self.encoding: + data = data.encode(self.encoding) + self.stream.write(data) + self.write_line_break() + + def write_tag_directive(self, handle_text, prefix_text): + # type: (Any, Any) -> None + data = u'%%TAG %s %s' % (handle_text, prefix_text) + if self.encoding: + data = data.encode(self.encoding) + self.stream.write(data) + self.write_line_break() + + # Scalar streams. + + def write_single_quoted(self, text, split=True): + # type: (Any, Any) -> None + if self.root_context: + if self.requested_indent is not None: + self.write_line_break() + if self.requested_indent != 0: + self.write_indent() + self.write_indicator(u"'", True) + spaces = False + breaks = False + start = end = 0 + while end <= len(text): + ch = None + if end < len(text): + ch = text[end] + if spaces: + if ch is None or ch != u' ': + if ( + start + 1 == end + and self.column > self.best_width + and split + and start != 0 + and end != len(text) + ): + self.write_indent() + else: + data = text[start:end] + self.column += len(data) + if bool(self.encoding): + data = data.encode(self.encoding) + self.stream.write(data) + start = end + elif breaks: + if ch is None or ch not in u'\n\x85\u2028\u2029': + if text[start] == u'\n': + self.write_line_break() + for br in text[start:end]: + if br == u'\n': + self.write_line_break() + else: + self.write_line_break(br) + self.write_indent() + start = end + else: + if ch is None or ch in u' \n\x85\u2028\u2029' or ch == u"'": + if start < end: + data = text[start:end] + self.column += len(data) + if bool(self.encoding): + data = data.encode(self.encoding) + self.stream.write(data) + start = end + if ch == u"'": + data = u"''" + self.column += 2 + if bool(self.encoding): + data = data.encode(self.encoding) + self.stream.write(data) + start = end + 1 + if ch is not None: + spaces = ch == u' ' + breaks = ch in u'\n\x85\u2028\u2029' + end += 1 + self.write_indicator(u"'", False) + + ESCAPE_REPLACEMENTS = { + u'\0': u'0', + u'\x07': u'a', + u'\x08': u'b', + u'\x09': u't', + u'\x0A': u'n', + u'\x0B': u'v', + u'\x0C': u'f', + u'\x0D': u'r', + u'\x1B': u'e', + u'"': u'"', + u'\\': u'\\', + u'\x85': u'N', + u'\xA0': u'_', + u'\u2028': u'L', + u'\u2029': u'P', + } + + def write_double_quoted(self, text, split=True): + # type: (Any, Any) -> None + if self.root_context: + if self.requested_indent is not None: + self.write_line_break() + if self.requested_indent != 0: + self.write_indent() + self.write_indicator(u'"', True) + start = end = 0 + while end <= len(text): + ch = None + if end < len(text): + ch = text[end] + if ( + ch is None + or ch in u'"\\\x85\u2028\u2029\uFEFF' + or not ( + u'\x20' <= ch <= u'\x7E' + or ( + self.allow_unicode + and (u'\xA0' <= ch <= u'\uD7FF' or u'\uE000' <= ch <= u'\uFFFD') + ) + ) + ): + if start < end: + data = text[start:end] + self.column += len(data) + if bool(self.encoding): + data = data.encode(self.encoding) + self.stream.write(data) + start = end + if ch is not None: + if ch in self.ESCAPE_REPLACEMENTS: + data = u'\\' + self.ESCAPE_REPLACEMENTS[ch] + elif ch <= u'\xFF': + data = u'\\x%02X' % ord(ch) + elif ch <= u'\uFFFF': + data = u'\\u%04X' % ord(ch) + else: + data = u'\\U%08X' % ord(ch) + self.column += len(data) + if bool(self.encoding): + data = data.encode(self.encoding) + self.stream.write(data) + start = end + 1 + if ( + 0 < end < len(text) - 1 + and (ch == u' ' or start >= end) + and self.column + (end - start) > self.best_width + and split + ): + data = text[start:end] + u'\\' + if start < end: + start = end + self.column += len(data) + if bool(self.encoding): + data = data.encode(self.encoding) + self.stream.write(data) + self.write_indent() + self.whitespace = False + self.indention = False + if text[start] == u' ': + data = u'\\' + self.column += len(data) + if bool(self.encoding): + data = data.encode(self.encoding) + self.stream.write(data) + end += 1 + self.write_indicator(u'"', False) + + def determine_block_hints(self, text): + # type: (Any) -> Any + indent = 0 + indicator = u'' + hints = u'' + if text: + if text[0] in u' \n\x85\u2028\u2029': + indent = self.best_sequence_indent + hints += text_type(indent) + elif self.root_context: + for end in ['\n---', '\n...']: + pos = 0 + while True: + pos = text.find(end, pos) + if pos == -1: + break + try: + if text[pos + 4] in ' \r\n': + break + except IndexError: + pass + pos += 1 + if pos > -1: + break + if pos > 0: + indent = self.best_sequence_indent + if text[-1] not in u'\n\x85\u2028\u2029': + indicator = u'-' + elif len(text) == 1 or text[-2] in u'\n\x85\u2028\u2029': + indicator = u'+' + hints += indicator + return hints, indent, indicator + + def write_folded(self, text): + # type: (Any) -> None + hints, _indent, _indicator = self.determine_block_hints(text) + self.write_indicator(u'>' + hints, True) + if _indicator == u'+': + self.open_ended = True + self.write_line_break() + leading_space = True + spaces = False + breaks = True + start = end = 0 + while end <= len(text): + ch = None + if end < len(text): + ch = text[end] + if breaks: + if ch is None or ch not in u'\n\x85\u2028\u2029\a': + if ( + not leading_space + and ch is not None + and ch != u' ' + and text[start] == u'\n' + ): + self.write_line_break() + leading_space = ch == u' ' + for br in text[start:end]: + if br == u'\n': + self.write_line_break() + else: + self.write_line_break(br) + if ch is not None: + self.write_indent() + start = end + elif spaces: + if ch != u' ': + if start + 1 == end and self.column > self.best_width: + self.write_indent() + else: + data = text[start:end] + self.column += len(data) + if bool(self.encoding): + data = data.encode(self.encoding) + self.stream.write(data) + start = end + else: + if ch is None or ch in u' \n\x85\u2028\u2029\a': + data = text[start:end] + self.column += len(data) + if bool(self.encoding): + data = data.encode(self.encoding) + self.stream.write(data) + if ch == u'\a': + if end < (len(text) - 1) and not text[end + 2].isspace(): + self.write_line_break() + self.write_indent() + end += 2 # \a and the space that is inserted on the fold + else: + raise EmitterError('unexcpected fold indicator \\a before space') + if ch is None: + self.write_line_break() + start = end + if ch is not None: + breaks = ch in u'\n\x85\u2028\u2029' + spaces = ch == u' ' + end += 1 + + def write_literal(self, text, comment=None): + # type: (Any, Any) -> None + hints, _indent, _indicator = self.determine_block_hints(text) + self.write_indicator(u'|' + hints, True) + try: + comment = comment[1][0] + if comment: + self.stream.write(comment) + except (TypeError, IndexError): + pass + if _indicator == u'+': + self.open_ended = True + self.write_line_break() + breaks = True + start = end = 0 + while end <= len(text): + ch = None + if end < len(text): + ch = text[end] + if breaks: + if ch is None or ch not in u'\n\x85\u2028\u2029': + for br in text[start:end]: + if br == u'\n': + self.write_line_break() + else: + self.write_line_break(br) + if ch is not None: + if self.root_context: + idnx = self.indent if self.indent is not None else 0 + self.stream.write(u' ' * (_indent + idnx)) + else: + self.write_indent() + start = end + else: + if ch is None or ch in u'\n\x85\u2028\u2029': + data = text[start:end] + if bool(self.encoding): + data = data.encode(self.encoding) + self.stream.write(data) + if ch is None: + self.write_line_break() + start = end + if ch is not None: + breaks = ch in u'\n\x85\u2028\u2029' + end += 1 + + def write_plain(self, text, split=True): + # type: (Any, Any) -> None + if self.root_context: + if self.requested_indent is not None: + self.write_line_break() + if self.requested_indent != 0: + self.write_indent() + else: + self.open_ended = True + if not text: + return + if not self.whitespace: + data = u' ' + self.column += len(data) + if self.encoding: + data = data.encode(self.encoding) + self.stream.write(data) + self.whitespace = False + self.indention = False + spaces = False + breaks = False + start = end = 0 + while end <= len(text): + ch = None + if end < len(text): + ch = text[end] + if spaces: + if ch != u' ': + if start + 1 == end and self.column > self.best_width and split: + self.write_indent() + self.whitespace = False + self.indention = False + else: + data = text[start:end] + self.column += len(data) + if self.encoding: + data = data.encode(self.encoding) + self.stream.write(data) + start = end + elif breaks: + if ch not in u'\n\x85\u2028\u2029': + if text[start] == u'\n': + self.write_line_break() + for br in text[start:end]: + if br == u'\n': + self.write_line_break() + else: + self.write_line_break(br) + self.write_indent() + self.whitespace = False + self.indention = False + start = end + else: + if ch is None or ch in u' \n\x85\u2028\u2029': + data = text[start:end] + self.column += len(data) + if self.encoding: + data = data.encode(self.encoding) + try: + self.stream.write(data) + except: # NOQA + sys.stdout.write(repr(data) + '\n') + raise + start = end + if ch is not None: + spaces = ch == u' ' + breaks = ch in u'\n\x85\u2028\u2029' + end += 1 + + def write_comment(self, comment, pre=False): + # type: (Any, bool) -> None + value = comment.value + # nprintf('{:02d} {:02d} {!r}'.format(self.column, comment.start_mark.column, value)) + if not pre and value[-1] == '\n': + value = value[:-1] + try: + # get original column position + col = comment.start_mark.column + if comment.value and comment.value.startswith('\n'): + # never inject extra spaces if the comment starts with a newline + # and not a real comment (e.g. if you have an empty line following a key-value + col = self.column + elif col < self.column + 1: + ValueError + except ValueError: + col = self.column + 1 + # nprint('post_comment', self.line, self.column, value) + try: + # at least one space if the current column >= the start column of the comment + # but not at the start of a line + nr_spaces = col - self.column + if self.column and value.strip() and nr_spaces < 1: + nr_spaces = 1 + value = ' ' * nr_spaces + value + try: + if bool(self.encoding): + value = value.encode(self.encoding) + except UnicodeDecodeError: + pass + self.stream.write(value) + except TypeError: + raise + if not pre: + self.write_line_break() + + def write_pre_comment(self, event): + # type: (Any) -> bool + comments = event.comment[1] + if comments is None: + return False + try: + start_events = (MappingStartEvent, SequenceStartEvent) + for comment in comments: + if isinstance(event, start_events) and getattr(comment, 'pre_done', None): + continue + if self.column != 0: + self.write_line_break() + self.write_comment(comment, pre=True) + if isinstance(event, start_events): + comment.pre_done = True + except TypeError: + sys.stdout.write('eventtt {} {}'.format(type(event), event)) + raise + return True + + def write_post_comment(self, event): + # type: (Any) -> bool + if self.event.comment[0] is None: + return False + comment = event.comment[0] + self.write_comment(comment) + return True diff --git a/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/sentry_sdk-1.7.2.dist-info/LICENSE b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/sentry_sdk-1.7.2.dist-info/LICENSE new file mode 100644 index 0000000000000000000000000000000000000000..61555f192e520e334a559773f5ca316050d3c9ef --- /dev/null +++ b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/sentry_sdk-1.7.2.dist-info/LICENSE @@ -0,0 +1,9 @@ +Copyright (c) 2018 Sentry (https://sentry.io) and individual contributors. +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. +* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/sentry_sdk-1.7.2.dist-info/METADATA b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/sentry_sdk-1.7.2.dist-info/METADATA new file mode 100644 index 0000000000000000000000000000000000000000..befb89d779a15516d1b24846e7f75bdcd3a260f2 --- /dev/null +++ b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/sentry_sdk-1.7.2.dist-info/METADATA @@ -0,0 +1,173 @@ +Metadata-Version: 2.1 +Name: sentry-sdk +Version: 1.7.2 +Summary: Python client for Sentry (https://sentry.io) +Home-page: https://github.com/getsentry/sentry-python +Author: Sentry Team and Contributors +Author-email: hello@sentry.io +License: BSD +Project-URL: Documentation, https://docs.sentry.io/platforms/python/ +Project-URL: Changelog, https://github.com/getsentry/sentry-python/blob/master/CHANGELOG.md +Classifier: Development Status :: 5 - Production/Stable +Classifier: Environment :: Web Environment +Classifier: Intended Audience :: Developers +Classifier: License :: OSI Approved :: BSD License +Classifier: Operating System :: OS Independent +Classifier: Programming Language :: Python +Classifier: Programming Language :: Python :: 2 +Classifier: Programming Language :: Python :: 2.7 +Classifier: Programming Language :: Python :: 3 +Classifier: Programming Language :: Python :: 3.4 +Classifier: Programming Language :: Python :: 3.5 +Classifier: Programming Language :: Python :: 3.6 +Classifier: Programming Language :: Python :: 3.7 +Classifier: Programming Language :: Python :: 3.8 +Classifier: Programming Language :: Python :: 3.9 +Classifier: Programming Language :: Python :: 3.10 +Classifier: Topic :: Software Development :: Libraries :: Python Modules +Description-Content-Type: text/markdown +License-File: LICENSE +Requires-Dist: urllib3 (>=1.10.0) +Requires-Dist: certifi +Provides-Extra: aiohttp +Requires-Dist: aiohttp (>=3.5) ; extra == 'aiohttp' +Provides-Extra: beam +Requires-Dist: apache-beam (>=2.12) ; extra == 'beam' +Provides-Extra: bottle +Requires-Dist: bottle (>=0.12.13) ; extra == 'bottle' +Provides-Extra: celery +Requires-Dist: celery (>=3) ; extra == 'celery' +Provides-Extra: chalice +Requires-Dist: chalice (>=1.16.0) ; extra == 'chalice' +Provides-Extra: django +Requires-Dist: django (>=1.8) ; extra == 'django' +Provides-Extra: falcon +Requires-Dist: falcon (>=1.4) ; extra == 'falcon' +Provides-Extra: flask +Requires-Dist: flask (>=0.11) ; extra == 'flask' +Requires-Dist: blinker (>=1.1) ; extra == 'flask' +Provides-Extra: httpx +Requires-Dist: httpx (>=0.16.0) ; extra == 'httpx' +Provides-Extra: pure_eval +Requires-Dist: pure-eval ; extra == 'pure_eval' +Requires-Dist: executing ; extra == 'pure_eval' +Requires-Dist: asttokens ; extra == 'pure_eval' +Provides-Extra: pyspark +Requires-Dist: pyspark (>=2.4.4) ; extra == 'pyspark' +Provides-Extra: quart +Requires-Dist: quart (>=0.16.1) ; extra == 'quart' +Requires-Dist: blinker (>=1.1) ; extra == 'quart' +Provides-Extra: rq +Requires-Dist: rq (>=0.6) ; extra == 'rq' +Provides-Extra: sanic +Requires-Dist: sanic (>=0.8) ; extra == 'sanic' +Provides-Extra: sqlalchemy +Requires-Dist: sqlalchemy (>=1.2) ; extra == 'sqlalchemy' +Provides-Extra: tornado +Requires-Dist: tornado (>=5) ; extra == 'tornado' + +

+ + Sentry + +

+ +_Bad software is everywhere, and we're tired of it. Sentry is on a mission to help developers write better software faster, so we can get back to enjoying technology. If you want to join us [**Check out our open positions**](https://sentry.io/careers/)_ + +# Official Sentry SDK for Python + +[![Build Status](https://travis-ci.com/getsentry/sentry-python.svg?branch=master)](https://travis-ci.com/getsentry/sentry-python) +[![PyPi page link -- version](https://img.shields.io/pypi/v/sentry-sdk.svg)](https://pypi.python.org/pypi/sentry-sdk) +[![Discord](https://img.shields.io/discord/621778831602221064)](https://discord.gg/cWnMQeA) + +This is the official Python SDK for [Sentry](http://sentry.io/) + +--- + +## Getting Started + +### Install + +```bash +pip install --upgrade sentry-sdk +``` + +### Configuration + +```python +import sentry_sdk + +sentry_sdk.init( + "https://12927b5f211046b575ee51fd8b1ac34f@o1.ingest.sentry.io/1", + + # Set traces_sample_rate to 1.0 to capture 100% + # of transactions for performance monitoring. + # We recommend adjusting this value in production. + traces_sample_rate=1.0, +) +``` + +### Usage + +```python +from sentry_sdk import capture_message +capture_message("Hello World") # Will create an event in Sentry. + +raise ValueError() # Will also create an event in Sentry. +``` + +- To learn more about how to use the SDK [refer to our docs](https://docs.sentry.io/platforms/python/) +- Are you coming from raven-python? [Use this migration guide](https://docs.sentry.io/platforms/python/migration/) +- To learn about internals use the [API Reference](https://getsentry.github.io/sentry-python/) + +## Integrations + +(If you want to create a new integration have a look at the [Adding a new integration checklist](CONTRIBUTING.md#adding-a-new-integration-checklist).) + +- [Django](https://docs.sentry.io/platforms/python/guides/django/) +- [Flask](https://docs.sentry.io/platforms/python/guides/flask/) +- [Bottle](https://docs.sentry.io/platforms/python/guides/bottle/) +- [AWS Lambda](https://docs.sentry.io/platforms/python/guides/aws-lambda/) +- [Google Cloud Functions](https://docs.sentry.io/platforms/python/guides/gcp-functions/) +- [WSGI](https://docs.sentry.io/platforms/python/guides/wsgi/) +- [ASGI](https://docs.sentry.io/platforms/python/guides/asgi/) +- [AIOHTTP](https://docs.sentry.io/platforms/python/guides/aiohttp/) +- [RQ (Redis Queue)](https://docs.sentry.io/platforms/python/guides/rq/) +- [Celery](https://docs.sentry.io/platforms/python/guides/celery/) +- [Chalice](https://docs.sentry.io/platforms/python/guides/chalice/) +- [Falcon](https://docs.sentry.io/platforms/python/guides/falcon/) +- [Quart](https://docs.sentry.io/platforms/python/guides/quart/) +- [Sanic](https://docs.sentry.io/platforms/python/guides/sanic/) +- [Tornado](https://docs.sentry.io/platforms/python/guides/tornado/) +- [Tryton](https://docs.sentry.io/platforms/python/guides/tryton/) +- [Pyramid](https://docs.sentry.io/platforms/python/guides/pyramid/) +- [Logging](https://docs.sentry.io/platforms/python/guides/logging/) +- [Apache Airflow](https://docs.sentry.io/platforms/python/guides/airflow/) +- [Apache Beam](https://docs.sentry.io/platforms/python/guides/beam/) +- [Apache Spark](https://docs.sentry.io/platforms/python/guides/pyspark/) + +## Migrate From sentry-raven + +The old `raven-python` client has entered maintenance mode and was moved [here](https://github.com/getsentry/raven-python). + +If you're using `raven-python`, we recommend you to migrate to this new SDK. You can find the benefits of migrating and how to do it in our [migration guide](https://docs.sentry.io/platforms/python/migration/). + +## Contributing to the SDK + +Please refer to [CONTRIBUTING.md](CONTRIBUTING.md). + +## Getting help/support + +If you need help setting up or configuring the Python SDK (or anything else in the Sentry universe) please head over to the [Sentry Community on Discord](https://discord.com/invite/Ww9hbqr). There is a ton of great people in our Discord community ready to help you! + +## Resources + +- [![Documentation](https://img.shields.io/badge/documentation-sentry.io-green.svg)](https://docs.sentry.io/quickstart/) +- [![Forum](https://img.shields.io/badge/forum-sentry-green.svg)](https://forum.sentry.io/c/sdks) +- [![Discord](https://img.shields.io/discord/621778831602221064)](https://discord.gg/Ww9hbqr) +- [![Stack Overflow](https://img.shields.io/badge/stack%20overflow-sentry-green.svg)](http://stackoverflow.com/questions/tagged/sentry) +- [![Twitter Follow](https://img.shields.io/twitter/follow/getsentry?label=getsentry&style=social)](https://twitter.com/intent/follow?screen_name=getsentry) + +## License + +Licensed under the BSD license, see [`LICENSE`](LICENSE) diff --git a/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/sentry_sdk-1.7.2.dist-info/RECORD b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/sentry_sdk-1.7.2.dist-info/RECORD new file mode 100644 index 0000000000000000000000000000000000000000..64cfda3be16dd27b721b79ec7df4fff3242f3b4d --- /dev/null +++ b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/sentry_sdk-1.7.2.dist-info/RECORD @@ -0,0 +1,138 @@ +sentry_sdk-1.7.2.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +sentry_sdk-1.7.2.dist-info/LICENSE,sha256=WUBNTIVOV5CX1Bv8zVAGr96dbXDmRs9VB0zb_q1ezxw,1330 +sentry_sdk-1.7.2.dist-info/METADATA,sha256=rgOS0UEmRbew2ho4NWCHpdjtuVhBqsWquPhfb9GANJM,7681 +sentry_sdk-1.7.2.dist-info/RECORD,, +sentry_sdk-1.7.2.dist-info/REQUESTED,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +sentry_sdk-1.7.2.dist-info/WHEEL,sha256=z9j0xAa_JmUKMpmz72K0ZGALSM_n-wQVmGbleXx2VHg,110 +sentry_sdk-1.7.2.dist-info/top_level.txt,sha256=XrQz30XE9FKXSY_yGLrd9bsv2Rk390GTDJOSujYaMxI,11 +sentry_sdk/__init__.py,sha256=8evrZxpQEpYFejLKitW4GRgUybaFTgQXpCpswKROJv4,854 +sentry_sdk/__pycache__/__init__.cpython-38.pyc,, +sentry_sdk/__pycache__/_compat.cpython-38.pyc,, +sentry_sdk/__pycache__/_functools.cpython-38.pyc,, +sentry_sdk/__pycache__/_queue.cpython-38.pyc,, +sentry_sdk/__pycache__/_types.cpython-38.pyc,, +sentry_sdk/__pycache__/api.cpython-38.pyc,, +sentry_sdk/__pycache__/attachments.cpython-38.pyc,, +sentry_sdk/__pycache__/client.cpython-38.pyc,, +sentry_sdk/__pycache__/consts.cpython-38.pyc,, +sentry_sdk/__pycache__/debug.cpython-38.pyc,, +sentry_sdk/__pycache__/envelope.cpython-38.pyc,, +sentry_sdk/__pycache__/hub.cpython-38.pyc,, +sentry_sdk/__pycache__/scope.cpython-38.pyc,, +sentry_sdk/__pycache__/serializer.cpython-38.pyc,, +sentry_sdk/__pycache__/session.cpython-38.pyc,, +sentry_sdk/__pycache__/sessions.cpython-38.pyc,, +sentry_sdk/__pycache__/tracing.cpython-38.pyc,, +sentry_sdk/__pycache__/tracing_utils.cpython-38.pyc,, +sentry_sdk/__pycache__/transport.cpython-38.pyc,, +sentry_sdk/__pycache__/utils.cpython-38.pyc,, +sentry_sdk/__pycache__/worker.cpython-38.pyc,, +sentry_sdk/_compat.py,sha256=C1WlUTUpRK4EDGbBulXR3g_ZzWXJDAxcokbvMpdG7zU,2359 +sentry_sdk/_functools.py,sha256=D3F8E4wEAq74HDVyP9OmyUm9fvN-gQStlr9ptjcDBXU,2276 +sentry_sdk/_queue.py,sha256=DwhJZ5JCJNhUMe1L89snaiYc4iVzQhSUxqYD6qMPQ90,8475 +sentry_sdk/_types.py,sha256=8X2IdUNOK7F6kSyOO-ce4FSnPceamz8uGNwmUg6zViA,1958 +sentry_sdk/api.py,sha256=Z6nvirT3Lew2WSXdeNvPGlAmlrhHnY4FfYYhtgkNtrE,4784 +sentry_sdk/attachments.py,sha256=bn5BEhf6kuJ65ODROt8j6oufvJganN5srx55FQlDgS4,1793 +sentry_sdk/client.py,sha256=a_onpUxdFn-RUqX1_pBGa2a4KoMLuNd4i5BsTFd5bTY,16234 +sentry_sdk/consts.py,sha256=H4F8XQk3vgyK0KzYl16CfHzx3wC-ttUyTPgH8LrO6P8,3838 +sentry_sdk/debug.py,sha256=ZT-7VoCIA5TYhh7X-ZSaSzYZ4_MuoNvzi12gKgIKzm0,1132 +sentry_sdk/envelope.py,sha256=jlxsFV_5MWKa2dJX-YY7OQ3IItV26HLVruhhmMGgbP4,9169 +sentry_sdk/hub.py,sha256=oGrE4fFjG-83ywYgr4vjv1xDJ4ogaTizI22nKcrU9cE,22233 +sentry_sdk/integrations/__init__.py,sha256=Hs24Bf3COL7qvr8fAUVDEmTo3CPoW0O_o75f9lxh4KE,6635 +sentry_sdk/integrations/__pycache__/__init__.cpython-38.pyc,, +sentry_sdk/integrations/__pycache__/_wsgi_common.cpython-38.pyc,, +sentry_sdk/integrations/__pycache__/aiohttp.cpython-38.pyc,, +sentry_sdk/integrations/__pycache__/argv.cpython-38.pyc,, +sentry_sdk/integrations/__pycache__/asgi.cpython-38.pyc,, +sentry_sdk/integrations/__pycache__/atexit.cpython-38.pyc,, +sentry_sdk/integrations/__pycache__/aws_lambda.cpython-38.pyc,, +sentry_sdk/integrations/__pycache__/beam.cpython-38.pyc,, +sentry_sdk/integrations/__pycache__/boto3.cpython-38.pyc,, +sentry_sdk/integrations/__pycache__/bottle.cpython-38.pyc,, +sentry_sdk/integrations/__pycache__/celery.cpython-38.pyc,, +sentry_sdk/integrations/__pycache__/chalice.cpython-38.pyc,, +sentry_sdk/integrations/__pycache__/dedupe.cpython-38.pyc,, +sentry_sdk/integrations/__pycache__/excepthook.cpython-38.pyc,, +sentry_sdk/integrations/__pycache__/executing.cpython-38.pyc,, +sentry_sdk/integrations/__pycache__/falcon.cpython-38.pyc,, +sentry_sdk/integrations/__pycache__/flask.cpython-38.pyc,, +sentry_sdk/integrations/__pycache__/gcp.cpython-38.pyc,, +sentry_sdk/integrations/__pycache__/gnu_backtrace.cpython-38.pyc,, +sentry_sdk/integrations/__pycache__/httpx.cpython-38.pyc,, +sentry_sdk/integrations/__pycache__/logging.cpython-38.pyc,, +sentry_sdk/integrations/__pycache__/modules.cpython-38.pyc,, +sentry_sdk/integrations/__pycache__/pure_eval.cpython-38.pyc,, +sentry_sdk/integrations/__pycache__/pyramid.cpython-38.pyc,, +sentry_sdk/integrations/__pycache__/quart.cpython-38.pyc,, +sentry_sdk/integrations/__pycache__/redis.cpython-38.pyc,, +sentry_sdk/integrations/__pycache__/rq.cpython-38.pyc,, +sentry_sdk/integrations/__pycache__/sanic.cpython-38.pyc,, +sentry_sdk/integrations/__pycache__/serverless.cpython-38.pyc,, +sentry_sdk/integrations/__pycache__/sqlalchemy.cpython-38.pyc,, +sentry_sdk/integrations/__pycache__/stdlib.cpython-38.pyc,, +sentry_sdk/integrations/__pycache__/threading.cpython-38.pyc,, +sentry_sdk/integrations/__pycache__/tornado.cpython-38.pyc,, +sentry_sdk/integrations/__pycache__/trytond.cpython-38.pyc,, +sentry_sdk/integrations/__pycache__/wsgi.cpython-38.pyc,, +sentry_sdk/integrations/_wsgi_common.py,sha256=5Fh1uH2MMWocYW0yj2SvnI55GqzLHS9id1_jXzZEjYc,4781 +sentry_sdk/integrations/aiohttp.py,sha256=35XGiihwR3SvsiYHeCy6hwGWixhNngvbvUfWUs_3YA8,8098 +sentry_sdk/integrations/argv.py,sha256=X-RVfWNxuPObsOmuommDc4FcIhNSTKpGsD1cYbrqza4,945 +sentry_sdk/integrations/asgi.py,sha256=wCBc46zdntudaxX939Hf2TUE3AP32S7jI0EQ8IU1qMk,10922 +sentry_sdk/integrations/atexit.py,sha256=b75c2SBJPl_cS4ObiQT1SMKqeZG5Fqed61z2myHRKug,1837 +sentry_sdk/integrations/aws_lambda.py,sha256=5HWutBdXaoAQqI2WPXeShKi3qz9TQl666Urt2LmHE_U,15733 +sentry_sdk/integrations/beam.py,sha256=paAtKjku5mlMylTl8zIJnhLwJH7MwvJcXBNjXy1RIr0,5671 +sentry_sdk/integrations/boto3.py,sha256=uCUintB5Bwi11jGoln0QpIVbqAQ2RkInWM1-E8dRmZE,4145 +sentry_sdk/integrations/bottle.py,sha256=ILPmI1caLvWELAzXGaAIN_KV7VZKBuYXBFtHf--PM_w,6488 +sentry_sdk/integrations/celery.py,sha256=a_T4AMDOf3-RmtNzXxv4J_G0JxkgTVnBP8nRl2uYpHg,9746 +sentry_sdk/integrations/chalice.py,sha256=Qy5rUIOZ3KDApo-2SsQSLbA0cDt0JsX8hZ-GmszyH1A,4775 +sentry_sdk/integrations/dedupe.py,sha256=d3JaHlMJpeF9zqVmITSPcLPBEvr9aHRzIrlGyzqeNgs,1166 +sentry_sdk/integrations/django/__init__.py,sha256=s6Evj1NVVYQrrYNRk_sWJ7l97EeiJnPybdo12o3s5Jo,18714 +sentry_sdk/integrations/django/__pycache__/__init__.cpython-38.pyc,, +sentry_sdk/integrations/django/__pycache__/asgi.cpython-38.pyc,, +sentry_sdk/integrations/django/__pycache__/middleware.cpython-38.pyc,, +sentry_sdk/integrations/django/__pycache__/templates.cpython-38.pyc,, +sentry_sdk/integrations/django/__pycache__/transactions.cpython-38.pyc,, +sentry_sdk/integrations/django/__pycache__/views.cpython-38.pyc,, +sentry_sdk/integrations/django/asgi.py,sha256=IYz27X451teGOgiiXA_0GpLuQGeRBhUyJ5DjP7Qnljs,4796 +sentry_sdk/integrations/django/middleware.py,sha256=YqpgCZWrTKsf8hzMhTpafZtkIFUBKntrbqG45CmY_Wg,5916 +sentry_sdk/integrations/django/templates.py,sha256=k_mM5NPqhTn4TUuBRJWAab2hVOzSUNBlHpt6i0YJun0,5394 +sentry_sdk/integrations/django/transactions.py,sha256=MRgwFsE2KoKoXmXG7SUSgbOmItq4-6nvVIUckyKhX00,4159 +sentry_sdk/integrations/django/views.py,sha256=RsqKD4gN0yMvZBU1bdXf75XqvePhalFOYM1E2N1zPtI,2055 +sentry_sdk/integrations/excepthook.py,sha256=vyG87OGM2KYkFW_k9vzEgCbm3rnCwbqcALrDf3xg5H0,2242 +sentry_sdk/integrations/executing.py,sha256=nKkMDGp_FLzksaeRqUy_E3G-tbvoJkeYn6x_QCCwXuk,2023 +sentry_sdk/integrations/falcon.py,sha256=KhkJRqowvHf1QyqBdcUcj4SSOM5kIKGguEES0AvR5_E,7322 +sentry_sdk/integrations/flask.py,sha256=TQ7KBqu3T7gFKE-hUCQGXDTdup1xDW-U0Xj5-UIUL3s,8193 +sentry_sdk/integrations/gcp.py,sha256=d0NZ-IKKLqIkYtos31HA2wNHdhExYXnILryfi62xe-w,8130 +sentry_sdk/integrations/gnu_backtrace.py,sha256=VJU3zYY7GUybAgIOEGF_P7i4V2R_jOnlSgTCS7XNto0,2912 +sentry_sdk/integrations/httpx.py,sha256=yV6lT674WREfKoY4eNnePgaWqL8VrSzCJqMsYsYYvx0,3113 +sentry_sdk/integrations/logging.py,sha256=nS1ojhx1UDYPp9cJvIEqwbsjOOeb9rVaITjfKopv-u4,8656 +sentry_sdk/integrations/modules.py,sha256=tgl4abSudtR03NBOjXCWJ08dHY5KlxUveX3mPUNosYk,1393 +sentry_sdk/integrations/pure_eval.py,sha256=n9efUsWMSLrXKHSwpXzw2CsfyQT4BJz_qMksGThY7kY,4520 +sentry_sdk/integrations/pyramid.py,sha256=wjuKQigdjmmPM0ZSjguyvdKmuDqftCnpfcjGLD_dtJA,7424 +sentry_sdk/integrations/quart.py,sha256=g_NQ0WFz_QdD-QoXIVLyFIhCaN_wUaqcCdpgBfT_jO4,5919 +sentry_sdk/integrations/redis.py,sha256=a-dM6XJfFEGBdA9VtVdPT6SJD8DELxmxBoI-FKTKdOQ,3196 +sentry_sdk/integrations/rq.py,sha256=uvL7y5y_AlI0J2VR1sV2tuU9_DSAmZS8-yCB3AMXjTU,4954 +sentry_sdk/integrations/sanic.py,sha256=qKxlFZArWEcfzFTFwGnVJE5ugm6CIjkKPDJVRTpWFO4,11311 +sentry_sdk/integrations/serverless.py,sha256=sVIQewlLmF2QY5qiStRfMcbOiwh8OmNki6qIfb8sgEM,1971 +sentry_sdk/integrations/spark/__init__.py,sha256=oOewMErnZk2rzNvIlZO6URxQexu9bUJuSLM2m_zECy8,208 +sentry_sdk/integrations/spark/__pycache__/__init__.cpython-38.pyc,, +sentry_sdk/integrations/spark/__pycache__/spark_driver.cpython-38.pyc,, +sentry_sdk/integrations/spark/__pycache__/spark_worker.cpython-38.pyc,, +sentry_sdk/integrations/spark/spark_driver.py,sha256=CMyEe6_Qf8E9OSz3bcCumsOgO8eJ4egKOrazOYPcvX4,8465 +sentry_sdk/integrations/spark/spark_worker.py,sha256=VJmdo7titY08o-OQLEz7NIYaeTke8_aAgrGNC1nybmE,3980 +sentry_sdk/integrations/sqlalchemy.py,sha256=gGTAREVnlR2NQQX-Kmia-t1LK-ng2T5yCmEzNGNf_ZI,3117 +sentry_sdk/integrations/stdlib.py,sha256=AcNH4cEBOiroUc-ONWWL4JB1wkX2V0riLbSYScwKTR4,7620 +sentry_sdk/integrations/threading.py,sha256=saNhIfgvDmN0geKO_lqXx4f6K9Awuhm-uzQVBrCSfkU,2840 +sentry_sdk/integrations/tornado.py,sha256=e3xTOJbIB81ki0T_sP5saPIjE2dbg0xTdPiPPYI6KiI,7185 +sentry_sdk/integrations/trytond.py,sha256=cLpQ5CZrG1Wn5Cq3_Xosswu5Jt43KEV-ag_zrvcXwqo,1728 +sentry_sdk/integrations/wsgi.py,sha256=9av_TBwc-5lq-5FvY2CDEtlJfk9OGjA7xyVN3-sY_yI,11148 +sentry_sdk/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +sentry_sdk/scope.py,sha256=vWflwa07QZORtRB2sZLi8aOd_n9_LazpiRvIYL5Uwn0,16853 +sentry_sdk/serializer.py,sha256=qbLdF56D9On8pE-L59STWSOfNVnX0__2M9qBLsAjG9c,16443 +sentry_sdk/session.py,sha256=disp2HJF-Nm5TTJISaEWRIGa_qlKgNoX4Nwv-q6hNas,5543 +sentry_sdk/sessions.py,sha256=ZJqCq6oNAIriSlQN1xRii7ejnmkXVD4wtlY_N-wO7MY,5884 +sentry_sdk/tracing.py,sha256=2NhJAhg-IeZw7U4Z0wEr0Y5ifPhF1DOAwupuVb2059c,27816 +sentry_sdk/tracing_utils.py,sha256=pufNXhdXbm4h8w9byoi45hC1k18j5FgcNvivrs3OCtI,15210 +sentry_sdk/transport.py,sha256=KIZnIC3mufC9gyhDjfowVSlnpQhdyOTY1OoAstz7dnE,17126 +sentry_sdk/utils.py,sha256=FMnaFbMeFzmR7vCDCdBU3wXVH1LM50sc1tKVUepw2pA,28545 +sentry_sdk/worker.py,sha256=M6O_0H8M-gffjhqnFYYUFP_l_lW6vOY-AjirjsDPy_U,4154 diff --git a/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/sentry_sdk-1.7.2.dist-info/REQUESTED b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/sentry_sdk-1.7.2.dist-info/REQUESTED new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/sentry_sdk-1.7.2.dist-info/WHEEL b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/sentry_sdk-1.7.2.dist-info/WHEEL new file mode 100644 index 0000000000000000000000000000000000000000..0b18a281107a0448a9980396d9d324ea2aa7a7f8 --- /dev/null +++ b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/sentry_sdk-1.7.2.dist-info/WHEEL @@ -0,0 +1,6 @@ +Wheel-Version: 1.0 +Generator: bdist_wheel (0.37.1) +Root-Is-Purelib: true +Tag: py2-none-any +Tag: py3-none-any + diff --git a/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/sentry_sdk-1.7.2.dist-info/top_level.txt b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/sentry_sdk-1.7.2.dist-info/top_level.txt new file mode 100644 index 0000000000000000000000000000000000000000..5051901ecb46b7905ec9fcb8dfa5c2711d494b8d --- /dev/null +++ b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/sentry_sdk-1.7.2.dist-info/top_level.txt @@ -0,0 +1 @@ +sentry_sdk diff --git a/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/wrapt/__init__.py b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/wrapt/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..ee6539b774afe6e4dbfb5428e02a9dac3ffac76c --- /dev/null +++ b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/wrapt/__init__.py @@ -0,0 +1,27 @@ +__version_info__ = ('1', '14', '1') +__version__ = '.'.join(__version_info__) + +from .wrappers import (ObjectProxy, CallableObjectProxy, FunctionWrapper, + BoundFunctionWrapper, WeakFunctionProxy, PartialCallableObjectProxy, + resolve_path, apply_patch, wrap_object, wrap_object_attribute, + function_wrapper, wrap_function_wrapper, patch_function_wrapper, + transient_function_wrapper) + +from .decorators import (adapter_factory, AdapterFactory, decorator, + synchronized) + +from .importer import (register_post_import_hook, when_imported, + notify_module_loaded, discover_post_import_hooks) + +# Import of inspect.getcallargs() included for backward compatibility. An +# implementation of this was previously bundled and made available here for +# Python <2.7. Avoid using this in future. + +from inspect import getcallargs + +# Variant of inspect.formatargspec() included here for forward compatibility. +# This is being done because Python 3.11 dropped inspect.formatargspec() but +# code for handling signature changing decorators relied on it. Exposing the +# bundled implementation here in case any user of wrapt was also needing it. + +from .arguments import formatargspec diff --git a/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/wrapt/arguments.py b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/wrapt/arguments.py new file mode 100644 index 0000000000000000000000000000000000000000..032bc059e003c43b871d4dfe523ceb60881d2140 --- /dev/null +++ b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/wrapt/arguments.py @@ -0,0 +1,38 @@ +# The inspect.formatargspec() function was dropped in Python 3.11 but we need +# need it for when constructing signature changing decorators based on result of +# inspect.getargspec() or inspect.getfullargspec(). The code here implements +# inspect.formatargspec() base on Parameter and Signature from inspect module, +# which were added in Python 3.6. Thanks to Cyril Jouve for the implementation. + +try: + from inspect import Parameter, Signature +except ImportError: + from inspect import formatargspec +else: + def formatargspec(args, varargs=None, varkw=None, defaults=None, + kwonlyargs=(), kwonlydefaults={}, annotations={}): + if kwonlydefaults is None: + kwonlydefaults = {} + ndefaults = len(defaults) if defaults else 0 + parameters = [ + Parameter( + arg, + Parameter.POSITIONAL_OR_KEYWORD, + default=defaults[i] if i >= 0 else Parameter.empty, + annotation=annotations.get(arg, Parameter.empty), + ) for i, arg in enumerate(args, ndefaults - len(args)) + ] + if varargs: + parameters.append(Parameter(varargs, Parameter.VAR_POSITIONAL)) + parameters.extend( + Parameter( + kwonlyarg, + Parameter.KEYWORD_ONLY, + default=kwonlydefaults.get(kwonlyarg, Parameter.empty), + annotation=annotations.get(kwonlyarg, Parameter.empty), + ) for kwonlyarg in kwonlyargs + ) + if varkw: + parameters.append(Parameter(varkw, Parameter.VAR_KEYWORD)) + return_annotation = annotations.get('return', Signature.empty) + return str(Signature(parameters, return_annotation=return_annotation)) \ No newline at end of file diff --git a/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/wrapt/decorators.py b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/wrapt/decorators.py new file mode 100644 index 0000000000000000000000000000000000000000..c3f2547295a815f8e0b377bfdc90b3838de84726 --- /dev/null +++ b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/wrapt/decorators.py @@ -0,0 +1,541 @@ +"""This module implements decorators for implementing other decorators +as well as some commonly used decorators. + +""" + +import sys + +PY2 = sys.version_info[0] == 2 + +if PY2: + string_types = basestring, + + def exec_(_code_, _globs_=None, _locs_=None): + """Execute code in a namespace.""" + if _globs_ is None: + frame = sys._getframe(1) + _globs_ = frame.f_globals + if _locs_ is None: + _locs_ = frame.f_locals + del frame + elif _locs_ is None: + _locs_ = _globs_ + exec("""exec _code_ in _globs_, _locs_""") + +else: + string_types = str, + + import builtins + + exec_ = getattr(builtins, "exec") + del builtins + +from functools import partial +from inspect import isclass +from threading import Lock, RLock + +from .arguments import formatargspec + +try: + from inspect import signature +except ImportError: + pass + +from .wrappers import (FunctionWrapper, BoundFunctionWrapper, ObjectProxy, + CallableObjectProxy) + +# Adapter wrapper for the wrapped function which will overlay certain +# properties from the adapter function onto the wrapped function so that +# functions such as inspect.getargspec(), inspect.getfullargspec(), +# inspect.signature() and inspect.getsource() return the correct results +# one would expect. + +class _AdapterFunctionCode(CallableObjectProxy): + + def __init__(self, wrapped_code, adapter_code): + super(_AdapterFunctionCode, self).__init__(wrapped_code) + self._self_adapter_code = adapter_code + + @property + def co_argcount(self): + return self._self_adapter_code.co_argcount + + @property + def co_code(self): + return self._self_adapter_code.co_code + + @property + def co_flags(self): + return self._self_adapter_code.co_flags + + @property + def co_kwonlyargcount(self): + return self._self_adapter_code.co_kwonlyargcount + + @property + def co_varnames(self): + return self._self_adapter_code.co_varnames + +class _AdapterFunctionSurrogate(CallableObjectProxy): + + def __init__(self, wrapped, adapter): + super(_AdapterFunctionSurrogate, self).__init__(wrapped) + self._self_adapter = adapter + + @property + def __code__(self): + return _AdapterFunctionCode(self.__wrapped__.__code__, + self._self_adapter.__code__) + + @property + def __defaults__(self): + return self._self_adapter.__defaults__ + + @property + def __kwdefaults__(self): + return self._self_adapter.__kwdefaults__ + + @property + def __signature__(self): + if 'signature' not in globals(): + return self._self_adapter.__signature__ + else: + return signature(self._self_adapter) + + if PY2: + func_code = __code__ + func_defaults = __defaults__ + +class _BoundAdapterWrapper(BoundFunctionWrapper): + + @property + def __func__(self): + return _AdapterFunctionSurrogate(self.__wrapped__.__func__, + self._self_parent._self_adapter) + + @property + def __signature__(self): + if 'signature' not in globals(): + return self.__wrapped__.__signature__ + else: + return signature(self._self_parent._self_adapter) + + if PY2: + im_func = __func__ + +class AdapterWrapper(FunctionWrapper): + + __bound_function_wrapper__ = _BoundAdapterWrapper + + def __init__(self, *args, **kwargs): + adapter = kwargs.pop('adapter') + super(AdapterWrapper, self).__init__(*args, **kwargs) + self._self_surrogate = _AdapterFunctionSurrogate( + self.__wrapped__, adapter) + self._self_adapter = adapter + + @property + def __code__(self): + return self._self_surrogate.__code__ + + @property + def __defaults__(self): + return self._self_surrogate.__defaults__ + + @property + def __kwdefaults__(self): + return self._self_surrogate.__kwdefaults__ + + if PY2: + func_code = __code__ + func_defaults = __defaults__ + + @property + def __signature__(self): + return self._self_surrogate.__signature__ + +class AdapterFactory(object): + def __call__(self, wrapped): + raise NotImplementedError() + +class DelegatedAdapterFactory(AdapterFactory): + def __init__(self, factory): + super(DelegatedAdapterFactory, self).__init__() + self.factory = factory + def __call__(self, wrapped): + return self.factory(wrapped) + +adapter_factory = DelegatedAdapterFactory + +# Decorator for creating other decorators. This decorator and the +# wrappers which they use are designed to properly preserve any name +# attributes, function signatures etc, in addition to the wrappers +# themselves acting like a transparent proxy for the original wrapped +# function so the wrapper is effectively indistinguishable from the +# original wrapped function. + +def decorator(wrapper=None, enabled=None, adapter=None, proxy=FunctionWrapper): + # The decorator should be supplied with a single positional argument + # which is the wrapper function to be used to implement the + # decorator. This may be preceded by a step whereby the keyword + # arguments are supplied to customise the behaviour of the + # decorator. The 'adapter' argument is used to optionally denote a + # separate function which is notionally used by an adapter + # decorator. In that case parts of the function '__code__' and + # '__defaults__' attributes are used from the adapter function + # rather than those of the wrapped function. This allows for the + # argument specification from inspect.getfullargspec() and similar + # functions to be overridden with a prototype for a different + # function than what was wrapped. The 'enabled' argument provides a + # way to enable/disable the use of the decorator. If the type of + # 'enabled' is a boolean, then it is evaluated immediately and the + # wrapper not even applied if it is False. If not a boolean, it will + # be evaluated when the wrapper is called for an unbound wrapper, + # and when binding occurs for a bound wrapper. When being evaluated, + # if 'enabled' is callable it will be called to obtain the value to + # be checked. If False, the wrapper will not be called and instead + # the original wrapped function will be called directly instead. + # The 'proxy' argument provides a way of passing a custom version of + # the FunctionWrapper class used in decorating the function. + + if wrapper is not None: + # Helper function for creating wrapper of the appropriate + # time when we need it down below. + + def _build(wrapped, wrapper, enabled=None, adapter=None): + if adapter: + if isinstance(adapter, AdapterFactory): + adapter = adapter(wrapped) + + if not callable(adapter): + ns = {} + + # Check if the signature argument specification has + # annotations. If it does then we need to remember + # it but also drop it when attempting to manufacture + # a standin adapter function. This is necessary else + # it will try and look up any types referenced in + # the annotations in the empty namespace we use, + # which will fail. + + annotations = {} + + if not isinstance(adapter, string_types): + if len(adapter) == 7: + annotations = adapter[-1] + adapter = adapter[:-1] + adapter = formatargspec(*adapter) + + exec_('def adapter{}: pass'.format(adapter), ns, ns) + adapter = ns['adapter'] + + # Override the annotations for the manufactured + # adapter function so they match the original + # adapter signature argument specification. + + if annotations: + adapter.__annotations__ = annotations + + return AdapterWrapper(wrapped=wrapped, wrapper=wrapper, + enabled=enabled, adapter=adapter) + + return proxy(wrapped=wrapped, wrapper=wrapper, enabled=enabled) + + # The wrapper has been provided so return the final decorator. + # The decorator is itself one of our function wrappers so we + # can determine when it is applied to functions, instance methods + # or class methods. This allows us to bind the instance or class + # method so the appropriate self or cls attribute is supplied + # when it is finally called. + + def _wrapper(wrapped, instance, args, kwargs): + # We first check for the case where the decorator was applied + # to a class type. + # + # @decorator + # class mydecoratorclass(object): + # def __init__(self, arg=None): + # self.arg = arg + # def __call__(self, wrapped, instance, args, kwargs): + # return wrapped(*args, **kwargs) + # + # @mydecoratorclass(arg=1) + # def function(): + # pass + # + # In this case an instance of the class is to be used as the + # decorator wrapper function. If args was empty at this point, + # then it means that there were optional keyword arguments + # supplied to be used when creating an instance of the class + # to be used as the wrapper function. + + if instance is None and isclass(wrapped) and not args: + # We still need to be passed the target function to be + # wrapped as yet, so we need to return a further function + # to be able to capture it. + + def _capture(target_wrapped): + # Now have the target function to be wrapped and need + # to create an instance of the class which is to act + # as the decorator wrapper function. Before we do that, + # we need to first check that use of the decorator + # hadn't been disabled by a simple boolean. If it was, + # the target function to be wrapped is returned instead. + + _enabled = enabled + if type(_enabled) is bool: + if not _enabled: + return target_wrapped + _enabled = None + + # Now create an instance of the class which is to act + # as the decorator wrapper function. Any arguments had + # to be supplied as keyword only arguments so that is + # all we pass when creating it. + + target_wrapper = wrapped(**kwargs) + + # Finally build the wrapper itself and return it. + + return _build(target_wrapped, target_wrapper, + _enabled, adapter) + + return _capture + + # We should always have the target function to be wrapped at + # this point as the first (and only) value in args. + + target_wrapped = args[0] + + # Need to now check that use of the decorator hadn't been + # disabled by a simple boolean. If it was, then target + # function to be wrapped is returned instead. + + _enabled = enabled + if type(_enabled) is bool: + if not _enabled: + return target_wrapped + _enabled = None + + # We now need to build the wrapper, but there are a couple of + # different cases we need to consider. + + if instance is None: + if isclass(wrapped): + # In this case the decorator was applied to a class + # type but optional keyword arguments were not supplied + # for initialising an instance of the class to be used + # as the decorator wrapper function. + # + # @decorator + # class mydecoratorclass(object): + # def __init__(self, arg=None): + # self.arg = arg + # def __call__(self, wrapped, instance, + # args, kwargs): + # return wrapped(*args, **kwargs) + # + # @mydecoratorclass + # def function(): + # pass + # + # We still need to create an instance of the class to + # be used as the decorator wrapper function, but no + # arguments are pass. + + target_wrapper = wrapped() + + else: + # In this case the decorator was applied to a normal + # function, or possibly a static method of a class. + # + # @decorator + # def mydecoratorfuntion(wrapped, instance, + # args, kwargs): + # return wrapped(*args, **kwargs) + # + # @mydecoratorfunction + # def function(): + # pass + # + # That normal function becomes the decorator wrapper + # function. + + target_wrapper = wrapper + + else: + if isclass(instance): + # In this case the decorator was applied to a class + # method. + # + # class myclass(object): + # @decorator + # @classmethod + # def decoratorclassmethod(cls, wrapped, + # instance, args, kwargs): + # return wrapped(*args, **kwargs) + # + # instance = myclass() + # + # @instance.decoratorclassmethod + # def function(): + # pass + # + # This one is a bit strange because binding was actually + # performed on the wrapper created by our decorator + # factory. We need to apply that binding to the decorator + # wrapper function that the decorator factory + # was applied to. + + target_wrapper = wrapper.__get__(None, instance) + + else: + # In this case the decorator was applied to an instance + # method. + # + # class myclass(object): + # @decorator + # def decoratorclassmethod(self, wrapped, + # instance, args, kwargs): + # return wrapped(*args, **kwargs) + # + # instance = myclass() + # + # @instance.decoratorclassmethod + # def function(): + # pass + # + # This one is a bit strange because binding was actually + # performed on the wrapper created by our decorator + # factory. We need to apply that binding to the decorator + # wrapper function that the decorator factory + # was applied to. + + target_wrapper = wrapper.__get__(instance, type(instance)) + + # Finally build the wrapper itself and return it. + + return _build(target_wrapped, target_wrapper, _enabled, adapter) + + # We first return our magic function wrapper here so we can + # determine in what context the decorator factory was used. In + # other words, it is itself a universal decorator. The decorator + # function is used as the adapter so that linters see a signature + # corresponding to the decorator and not the wrapper it is being + # applied to. + + return _build(wrapper, _wrapper, adapter=decorator) + + else: + # The wrapper still has not been provided, so we are just + # collecting the optional keyword arguments. Return the + # decorator again wrapped in a partial using the collected + # arguments. + + return partial(decorator, enabled=enabled, adapter=adapter, + proxy=proxy) + +# Decorator for implementing thread synchronization. It can be used as a +# decorator, in which case the synchronization context is determined by +# what type of function is wrapped, or it can also be used as a context +# manager, where the user needs to supply the correct synchronization +# context. It is also possible to supply an object which appears to be a +# synchronization primitive of some sort, by virtue of having release() +# and acquire() methods. In that case that will be used directly as the +# synchronization primitive without creating a separate lock against the +# derived or supplied context. + +def synchronized(wrapped): + # Determine if being passed an object which is a synchronization + # primitive. We can't check by type for Lock, RLock, Semaphore etc, + # as the means of creating them isn't the type. Therefore use the + # existence of acquire() and release() methods. This is more + # extensible anyway as it allows custom synchronization mechanisms. + + if hasattr(wrapped, 'acquire') and hasattr(wrapped, 'release'): + # We remember what the original lock is and then return a new + # decorator which accesses and locks it. When returning the new + # decorator we wrap it with an object proxy so we can override + # the context manager methods in case it is being used to wrap + # synchronized statements with a 'with' statement. + + lock = wrapped + + @decorator + def _synchronized(wrapped, instance, args, kwargs): + # Execute the wrapped function while the original supplied + # lock is held. + + with lock: + return wrapped(*args, **kwargs) + + class _PartialDecorator(CallableObjectProxy): + + def __enter__(self): + lock.acquire() + return lock + + def __exit__(self, *args): + lock.release() + + return _PartialDecorator(wrapped=_synchronized) + + # Following only apply when the lock is being created automatically + # based on the context of what was supplied. In this case we supply + # a final decorator, but need to use FunctionWrapper directly as we + # want to derive from it to add context manager methods in case it is + # being used to wrap synchronized statements with a 'with' statement. + + def _synchronized_lock(context): + # Attempt to retrieve the lock for the specific context. + + lock = vars(context).get('_synchronized_lock', None) + + if lock is None: + # There is no existing lock defined for the context we + # are dealing with so we need to create one. This needs + # to be done in a way to guarantee there is only one + # created, even if multiple threads try and create it at + # the same time. We can't always use the setdefault() + # method on the __dict__ for the context. This is the + # case where the context is a class, as __dict__ is + # actually a dictproxy. What we therefore do is use a + # meta lock on this wrapper itself, to control the + # creation and assignment of the lock attribute against + # the context. + + with synchronized._synchronized_meta_lock: + # We need to check again for whether the lock we want + # exists in case two threads were trying to create it + # at the same time and were competing to create the + # meta lock. + + lock = vars(context).get('_synchronized_lock', None) + + if lock is None: + lock = RLock() + setattr(context, '_synchronized_lock', lock) + + return lock + + def _synchronized_wrapper(wrapped, instance, args, kwargs): + # Execute the wrapped function while the lock for the + # desired context is held. If instance is None then the + # wrapped function is used as the context. + + with _synchronized_lock(instance if instance is not None else wrapped): + return wrapped(*args, **kwargs) + + class _FinalDecorator(FunctionWrapper): + + def __enter__(self): + self._self_lock = _synchronized_lock(self.__wrapped__) + self._self_lock.acquire() + return self._self_lock + + def __exit__(self, *args): + self._self_lock.release() + + return _FinalDecorator(wrapped=wrapped, wrapper=_synchronized_wrapper) + +synchronized._synchronized_meta_lock = Lock() diff --git a/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/wrapt/importer.py b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/wrapt/importer.py new file mode 100644 index 0000000000000000000000000000000000000000..5c4d4cc66302362adfbb9da74f4b87f9cc158223 --- /dev/null +++ b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/wrapt/importer.py @@ -0,0 +1,286 @@ +"""This module implements a post import hook mechanism styled after what is +described in PEP-369. Note that it doesn't cope with modules being reloaded. + +""" + +import sys +import threading + +PY2 = sys.version_info[0] == 2 + +if PY2: + string_types = basestring, + find_spec = None +else: + string_types = str, + from importlib.util import find_spec + +from .decorators import synchronized + +# The dictionary registering any post import hooks to be triggered once +# the target module has been imported. Once a module has been imported +# and the hooks fired, the list of hooks recorded against the target +# module will be truncated but the list left in the dictionary. This +# acts as a flag to indicate that the module had already been imported. + +_post_import_hooks = {} +_post_import_hooks_init = False +_post_import_hooks_lock = threading.RLock() + +# Register a new post import hook for the target module name. This +# differs from the PEP-369 implementation in that it also allows the +# hook function to be specified as a string consisting of the name of +# the callback in the form 'module:function'. This will result in a +# proxy callback being registered which will defer loading of the +# specified module containing the callback function until required. + +def _create_import_hook_from_string(name): + def import_hook(module): + module_name, function = name.split(':') + attrs = function.split('.') + __import__(module_name) + callback = sys.modules[module_name] + for attr in attrs: + callback = getattr(callback, attr) + return callback(module) + return import_hook + +@synchronized(_post_import_hooks_lock) +def register_post_import_hook(hook, name): + # Create a deferred import hook if hook is a string name rather than + # a callable function. + + if isinstance(hook, string_types): + hook = _create_import_hook_from_string(hook) + + # Automatically install the import hook finder if it has not already + # been installed. + + global _post_import_hooks_init + + if not _post_import_hooks_init: + _post_import_hooks_init = True + sys.meta_path.insert(0, ImportHookFinder()) + + # Determine if any prior registration of a post import hook for + # the target modules has occurred and act appropriately. + + hooks = _post_import_hooks.get(name, None) + + if hooks is None: + # No prior registration of post import hooks for the target + # module. We need to check whether the module has already been + # imported. If it has we fire the hook immediately and add an + # empty list to the registry to indicate that the module has + # already been imported and hooks have fired. Otherwise add + # the post import hook to the registry. + + module = sys.modules.get(name, None) + + if module is not None: + _post_import_hooks[name] = [] + hook(module) + + else: + _post_import_hooks[name] = [hook] + + elif hooks == []: + # A prior registration of port import hooks for the target + # module was done and the hooks already fired. Fire the hook + # immediately. + + module = sys.modules[name] + hook(module) + + else: + # A prior registration of port import hooks for the target + # module was done but the module has not yet been imported. + + _post_import_hooks[name].append(hook) + +# Register post import hooks defined as package entry points. + +def _create_import_hook_from_entrypoint(entrypoint): + def import_hook(module): + __import__(entrypoint.module_name) + callback = sys.modules[entrypoint.module_name] + for attr in entrypoint.attrs: + callback = getattr(callback, attr) + return callback(module) + return import_hook + +def discover_post_import_hooks(group): + try: + import pkg_resources + except ImportError: + return + + for entrypoint in pkg_resources.iter_entry_points(group=group): + callback = _create_import_hook_from_entrypoint(entrypoint) + register_post_import_hook(callback, entrypoint.name) + +# Indicate that a module has been loaded. Any post import hooks which +# were registered against the target module will be invoked. If an +# exception is raised in any of the post import hooks, that will cause +# the import of the target module to fail. + +@synchronized(_post_import_hooks_lock) +def notify_module_loaded(module): + name = getattr(module, '__name__', None) + hooks = _post_import_hooks.get(name, None) + + if hooks: + _post_import_hooks[name] = [] + + for hook in hooks: + hook(module) + +# A custom module import finder. This intercepts attempts to import +# modules and watches out for attempts to import target modules of +# interest. When a module of interest is imported, then any post import +# hooks which are registered will be invoked. + +class _ImportHookLoader: + + def load_module(self, fullname): + module = sys.modules[fullname] + notify_module_loaded(module) + + return module + +class _ImportHookChainedLoader: + + def __init__(self, loader): + self.loader = loader + + if hasattr(loader, "load_module"): + self.load_module = self._load_module + if hasattr(loader, "create_module"): + self.create_module = self._create_module + if hasattr(loader, "exec_module"): + self.exec_module = self._exec_module + + def _load_module(self, fullname): + module = self.loader.load_module(fullname) + notify_module_loaded(module) + + return module + + # Python 3.4 introduced create_module() and exec_module() instead of + # load_module() alone. Splitting the two steps. + + def _create_module(self, spec): + return self.loader.create_module(spec) + + def _exec_module(self, module): + self.loader.exec_module(module) + notify_module_loaded(module) + +class ImportHookFinder: + + def __init__(self): + self.in_progress = {} + + @synchronized(_post_import_hooks_lock) + def find_module(self, fullname, path=None): + # If the module being imported is not one we have registered + # post import hooks for, we can return immediately. We will + # take no further part in the importing of this module. + + if not fullname in _post_import_hooks: + return None + + # When we are interested in a specific module, we will call back + # into the import system a second time to defer to the import + # finder that is supposed to handle the importing of the module. + # We set an in progress flag for the target module so that on + # the second time through we don't trigger another call back + # into the import system and cause a infinite loop. + + if fullname in self.in_progress: + return None + + self.in_progress[fullname] = True + + # Now call back into the import system again. + + try: + if not find_spec: + # For Python 2 we don't have much choice but to + # call back in to __import__(). This will + # actually cause the module to be imported. If no + # module could be found then ImportError will be + # raised. Otherwise we return a loader which + # returns the already loaded module and invokes + # the post import hooks. + + __import__(fullname) + + return _ImportHookLoader() + + else: + # For Python 3 we need to use find_spec().loader + # from the importlib.util module. It doesn't actually + # import the target module and only finds the + # loader. If a loader is found, we need to return + # our own loader which will then in turn call the + # real loader to import the module and invoke the + # post import hooks. + + loader = getattr(find_spec(fullname), "loader", None) + + if loader and not isinstance(loader, _ImportHookChainedLoader): + return _ImportHookChainedLoader(loader) + + finally: + del self.in_progress[fullname] + + def find_spec(self, fullname, path=None, target=None): + # Since Python 3.4, you are meant to implement find_spec() method + # instead of find_module() and since Python 3.10 you get deprecation + # warnings if you don't define find_spec(). + + # If the module being imported is not one we have registered + # post import hooks for, we can return immediately. We will + # take no further part in the importing of this module. + + if not fullname in _post_import_hooks: + return None + + # When we are interested in a specific module, we will call back + # into the import system a second time to defer to the import + # finder that is supposed to handle the importing of the module. + # We set an in progress flag for the target module so that on + # the second time through we don't trigger another call back + # into the import system and cause a infinite loop. + + if fullname in self.in_progress: + return None + + self.in_progress[fullname] = True + + # Now call back into the import system again. + + try: + # This should only be Python 3 so find_spec() should always + # exist so don't need to check. + + spec = find_spec(fullname) + loader = getattr(spec, "loader", None) + + if loader and not isinstance(loader, _ImportHookChainedLoader): + spec.loader = _ImportHookChainedLoader(loader) + + return spec + + finally: + del self.in_progress[fullname] + +# Decorator for marking that a function should be called as a post +# import hook when the target module is imported. + +def when_imported(name): + def register(hook): + register_post_import_hook(hook, name) + return hook + return register diff --git a/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/wrapt/wrappers.py b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/wrapt/wrappers.py new file mode 100644 index 0000000000000000000000000000000000000000..2716cd1da1a5fbb4f260b5344b3ec6c37ea2c6b2 --- /dev/null +++ b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/wrapt/wrappers.py @@ -0,0 +1,986 @@ +import os +import sys +import functools +import operator +import weakref +import inspect + +PY2 = sys.version_info[0] == 2 + +if PY2: + string_types = basestring, +else: + string_types = str, + +def with_metaclass(meta, *bases): + """Create a base class with a metaclass.""" + return meta("NewBase", bases, {}) + +class _ObjectProxyMethods(object): + + # We use properties to override the values of __module__ and + # __doc__. If we add these in ObjectProxy, the derived class + # __dict__ will still be setup to have string variants of these + # attributes and the rules of descriptors means that they appear to + # take precedence over the properties in the base class. To avoid + # that, we copy the properties into the derived class type itself + # via a meta class. In that way the properties will always take + # precedence. + + @property + def __module__(self): + return self.__wrapped__.__module__ + + @__module__.setter + def __module__(self, value): + self.__wrapped__.__module__ = value + + @property + def __doc__(self): + return self.__wrapped__.__doc__ + + @__doc__.setter + def __doc__(self, value): + self.__wrapped__.__doc__ = value + + # We similar use a property for __dict__. We need __dict__ to be + # explicit to ensure that vars() works as expected. + + @property + def __dict__(self): + return self.__wrapped__.__dict__ + + # Need to also propagate the special __weakref__ attribute for case + # where decorating classes which will define this. If do not define + # it and use a function like inspect.getmembers() on a decorator + # class it will fail. This can't be in the derived classes. + + @property + def __weakref__(self): + return self.__wrapped__.__weakref__ + +class _ObjectProxyMetaType(type): + def __new__(cls, name, bases, dictionary): + # Copy our special properties into the class so that they + # always take precedence over attributes of the same name added + # during construction of a derived class. This is to save + # duplicating the implementation for them in all derived classes. + + dictionary.update(vars(_ObjectProxyMethods)) + + return type.__new__(cls, name, bases, dictionary) + +class ObjectProxy(with_metaclass(_ObjectProxyMetaType)): + + __slots__ = '__wrapped__' + + def __init__(self, wrapped): + object.__setattr__(self, '__wrapped__', wrapped) + + # Python 3.2+ has the __qualname__ attribute, but it does not + # allow it to be overridden using a property and it must instead + # be an actual string object instead. + + try: + object.__setattr__(self, '__qualname__', wrapped.__qualname__) + except AttributeError: + pass + + # Python 3.10 onwards also does not allow itself to be overridden + # using a property and it must instead be set explicitly. + + try: + object.__setattr__(self, '__annotations__', wrapped.__annotations__) + except AttributeError: + pass + + @property + def __name__(self): + return self.__wrapped__.__name__ + + @__name__.setter + def __name__(self, value): + self.__wrapped__.__name__ = value + + @property + def __class__(self): + return self.__wrapped__.__class__ + + @__class__.setter + def __class__(self, value): + self.__wrapped__.__class__ = value + + def __dir__(self): + return dir(self.__wrapped__) + + def __str__(self): + return str(self.__wrapped__) + + if not PY2: + def __bytes__(self): + return bytes(self.__wrapped__) + + def __repr__(self): + return '<{} at 0x{:x} for {} at 0x{:x}>'.format( + type(self).__name__, id(self), + type(self.__wrapped__).__name__, + id(self.__wrapped__)) + + def __reversed__(self): + return reversed(self.__wrapped__) + + if not PY2: + def __round__(self): + return round(self.__wrapped__) + + if sys.hexversion >= 0x03070000: + def __mro_entries__(self, bases): + return (self.__wrapped__,) + + def __lt__(self, other): + return self.__wrapped__ < other + + def __le__(self, other): + return self.__wrapped__ <= other + + def __eq__(self, other): + return self.__wrapped__ == other + + def __ne__(self, other): + return self.__wrapped__ != other + + def __gt__(self, other): + return self.__wrapped__ > other + + def __ge__(self, other): + return self.__wrapped__ >= other + + def __hash__(self): + return hash(self.__wrapped__) + + def __nonzero__(self): + return bool(self.__wrapped__) + + def __bool__(self): + return bool(self.__wrapped__) + + def __setattr__(self, name, value): + if name.startswith('_self_'): + object.__setattr__(self, name, value) + + elif name == '__wrapped__': + object.__setattr__(self, name, value) + try: + object.__delattr__(self, '__qualname__') + except AttributeError: + pass + try: + object.__setattr__(self, '__qualname__', value.__qualname__) + except AttributeError: + pass + try: + object.__delattr__(self, '__annotations__') + except AttributeError: + pass + try: + object.__setattr__(self, '__annotations__', value.__annotations__) + except AttributeError: + pass + + elif name == '__qualname__': + setattr(self.__wrapped__, name, value) + object.__setattr__(self, name, value) + + elif name == '__annotations__': + setattr(self.__wrapped__, name, value) + object.__setattr__(self, name, value) + + elif hasattr(type(self), name): + object.__setattr__(self, name, value) + + else: + setattr(self.__wrapped__, name, value) + + def __getattr__(self, name): + # If we are being to lookup '__wrapped__' then the + # '__init__()' method cannot have been called. + + if name == '__wrapped__': + raise ValueError('wrapper has not been initialised') + + return getattr(self.__wrapped__, name) + + def __delattr__(self, name): + if name.startswith('_self_'): + object.__delattr__(self, name) + + elif name == '__wrapped__': + raise TypeError('__wrapped__ must be an object') + + elif name == '__qualname__': + object.__delattr__(self, name) + delattr(self.__wrapped__, name) + + elif hasattr(type(self), name): + object.__delattr__(self, name) + + else: + delattr(self.__wrapped__, name) + + def __add__(self, other): + return self.__wrapped__ + other + + def __sub__(self, other): + return self.__wrapped__ - other + + def __mul__(self, other): + return self.__wrapped__ * other + + def __div__(self, other): + return operator.div(self.__wrapped__, other) + + def __truediv__(self, other): + return operator.truediv(self.__wrapped__, other) + + def __floordiv__(self, other): + return self.__wrapped__ // other + + def __mod__(self, other): + return self.__wrapped__ % other + + def __divmod__(self, other): + return divmod(self.__wrapped__, other) + + def __pow__(self, other, *args): + return pow(self.__wrapped__, other, *args) + + def __lshift__(self, other): + return self.__wrapped__ << other + + def __rshift__(self, other): + return self.__wrapped__ >> other + + def __and__(self, other): + return self.__wrapped__ & other + + def __xor__(self, other): + return self.__wrapped__ ^ other + + def __or__(self, other): + return self.__wrapped__ | other + + def __radd__(self, other): + return other + self.__wrapped__ + + def __rsub__(self, other): + return other - self.__wrapped__ + + def __rmul__(self, other): + return other * self.__wrapped__ + + def __rdiv__(self, other): + return operator.div(other, self.__wrapped__) + + def __rtruediv__(self, other): + return operator.truediv(other, self.__wrapped__) + + def __rfloordiv__(self, other): + return other // self.__wrapped__ + + def __rmod__(self, other): + return other % self.__wrapped__ + + def __rdivmod__(self, other): + return divmod(other, self.__wrapped__) + + def __rpow__(self, other, *args): + return pow(other, self.__wrapped__, *args) + + def __rlshift__(self, other): + return other << self.__wrapped__ + + def __rrshift__(self, other): + return other >> self.__wrapped__ + + def __rand__(self, other): + return other & self.__wrapped__ + + def __rxor__(self, other): + return other ^ self.__wrapped__ + + def __ror__(self, other): + return other | self.__wrapped__ + + def __iadd__(self, other): + self.__wrapped__ += other + return self + + def __isub__(self, other): + self.__wrapped__ -= other + return self + + def __imul__(self, other): + self.__wrapped__ *= other + return self + + def __idiv__(self, other): + self.__wrapped__ = operator.idiv(self.__wrapped__, other) + return self + + def __itruediv__(self, other): + self.__wrapped__ = operator.itruediv(self.__wrapped__, other) + return self + + def __ifloordiv__(self, other): + self.__wrapped__ //= other + return self + + def __imod__(self, other): + self.__wrapped__ %= other + return self + + def __ipow__(self, other): + self.__wrapped__ **= other + return self + + def __ilshift__(self, other): + self.__wrapped__ <<= other + return self + + def __irshift__(self, other): + self.__wrapped__ >>= other + return self + + def __iand__(self, other): + self.__wrapped__ &= other + return self + + def __ixor__(self, other): + self.__wrapped__ ^= other + return self + + def __ior__(self, other): + self.__wrapped__ |= other + return self + + def __neg__(self): + return -self.__wrapped__ + + def __pos__(self): + return +self.__wrapped__ + + def __abs__(self): + return abs(self.__wrapped__) + + def __invert__(self): + return ~self.__wrapped__ + + def __int__(self): + return int(self.__wrapped__) + + def __long__(self): + return long(self.__wrapped__) + + def __float__(self): + return float(self.__wrapped__) + + def __complex__(self): + return complex(self.__wrapped__) + + def __oct__(self): + return oct(self.__wrapped__) + + def __hex__(self): + return hex(self.__wrapped__) + + def __index__(self): + return operator.index(self.__wrapped__) + + def __len__(self): + return len(self.__wrapped__) + + def __contains__(self, value): + return value in self.__wrapped__ + + def __getitem__(self, key): + return self.__wrapped__[key] + + def __setitem__(self, key, value): + self.__wrapped__[key] = value + + def __delitem__(self, key): + del self.__wrapped__[key] + + def __getslice__(self, i, j): + return self.__wrapped__[i:j] + + def __setslice__(self, i, j, value): + self.__wrapped__[i:j] = value + + def __delslice__(self, i, j): + del self.__wrapped__[i:j] + + def __enter__(self): + return self.__wrapped__.__enter__() + + def __exit__(self, *args, **kwargs): + return self.__wrapped__.__exit__(*args, **kwargs) + + def __iter__(self): + return iter(self.__wrapped__) + + def __copy__(self): + raise NotImplementedError('object proxy must define __copy__()') + + def __deepcopy__(self, memo): + raise NotImplementedError('object proxy must define __deepcopy__()') + + def __reduce__(self): + raise NotImplementedError( + 'object proxy must define __reduce_ex__()') + + def __reduce_ex__(self, protocol): + raise NotImplementedError( + 'object proxy must define __reduce_ex__()') + +class CallableObjectProxy(ObjectProxy): + + def __call__(self, *args, **kwargs): + return self.__wrapped__(*args, **kwargs) + +class PartialCallableObjectProxy(ObjectProxy): + + def __init__(self, *args, **kwargs): + if len(args) < 1: + raise TypeError('partial type takes at least one argument') + + wrapped, args = args[0], args[1:] + + if not callable(wrapped): + raise TypeError('the first argument must be callable') + + super(PartialCallableObjectProxy, self).__init__(wrapped) + + self._self_args = args + self._self_kwargs = kwargs + + def __call__(self, *args, **kwargs): + _args = self._self_args + args + + _kwargs = dict(self._self_kwargs) + _kwargs.update(kwargs) + + return self.__wrapped__(*_args, **_kwargs) + +class _FunctionWrapperBase(ObjectProxy): + + __slots__ = ('_self_instance', '_self_wrapper', '_self_enabled', + '_self_binding', '_self_parent') + + def __init__(self, wrapped, instance, wrapper, enabled=None, + binding='function', parent=None): + + super(_FunctionWrapperBase, self).__init__(wrapped) + + object.__setattr__(self, '_self_instance', instance) + object.__setattr__(self, '_self_wrapper', wrapper) + object.__setattr__(self, '_self_enabled', enabled) + object.__setattr__(self, '_self_binding', binding) + object.__setattr__(self, '_self_parent', parent) + + def __get__(self, instance, owner): + # This method is actually doing double duty for both unbound and + # bound derived wrapper classes. It should possibly be broken up + # and the distinct functionality moved into the derived classes. + # Can't do that straight away due to some legacy code which is + # relying on it being here in this base class. + # + # The distinguishing attribute which determines whether we are + # being called in an unbound or bound wrapper is the parent + # attribute. If binding has never occurred, then the parent will + # be None. + # + # First therefore, is if we are called in an unbound wrapper. In + # this case we perform the binding. + # + # We have one special case to worry about here. This is where we + # are decorating a nested class. In this case the wrapped class + # would not have a __get__() method to call. In that case we + # simply return self. + # + # Note that we otherwise still do binding even if instance is + # None and accessing an unbound instance method from a class. + # This is because we need to be able to later detect that + # specific case as we will need to extract the instance from the + # first argument of those passed in. + + if self._self_parent is None: + if not inspect.isclass(self.__wrapped__): + descriptor = self.__wrapped__.__get__(instance, owner) + + return self.__bound_function_wrapper__(descriptor, instance, + self._self_wrapper, self._self_enabled, + self._self_binding, self) + + return self + + # Now we have the case of binding occurring a second time on what + # was already a bound function. In this case we would usually + # return ourselves again. This mirrors what Python does. + # + # The special case this time is where we were originally bound + # with an instance of None and we were likely an instance + # method. In that case we rebind against the original wrapped + # function from the parent again. + + if self._self_instance is None and self._self_binding == 'function': + descriptor = self._self_parent.__wrapped__.__get__( + instance, owner) + + return self._self_parent.__bound_function_wrapper__( + descriptor, instance, self._self_wrapper, + self._self_enabled, self._self_binding, + self._self_parent) + + return self + + def __call__(self, *args, **kwargs): + # If enabled has been specified, then evaluate it at this point + # and if the wrapper is not to be executed, then simply return + # the bound function rather than a bound wrapper for the bound + # function. When evaluating enabled, if it is callable we call + # it, otherwise we evaluate it as a boolean. + + if self._self_enabled is not None: + if callable(self._self_enabled): + if not self._self_enabled(): + return self.__wrapped__(*args, **kwargs) + elif not self._self_enabled: + return self.__wrapped__(*args, **kwargs) + + # This can occur where initial function wrapper was applied to + # a function that was already bound to an instance. In that case + # we want to extract the instance from the function and use it. + + if self._self_binding in ('function', 'classmethod'): + if self._self_instance is None: + instance = getattr(self.__wrapped__, '__self__', None) + if instance is not None: + return self._self_wrapper(self.__wrapped__, instance, + args, kwargs) + + # This is generally invoked when the wrapped function is being + # called as a normal function and is not bound to a class as an + # instance method. This is also invoked in the case where the + # wrapped function was a method, but this wrapper was in turn + # wrapped using the staticmethod decorator. + + return self._self_wrapper(self.__wrapped__, self._self_instance, + args, kwargs) + + def __set_name__(self, owner, name): + # This is a special method use to supply information to + # descriptors about what the name of variable in a class + # definition is. Not wanting to add this to ObjectProxy as not + # sure of broader implications of doing that. Thus restrict to + # FunctionWrapper used by decorators. + + if hasattr(self.__wrapped__, "__set_name__"): + self.__wrapped__.__set_name__(owner, name) + + def __instancecheck__(self, instance): + # This is a special method used by isinstance() to make checks + # instance of the `__wrapped__`. + return isinstance(instance, self.__wrapped__) + + def __subclasscheck__(self, subclass): + # This is a special method used by issubclass() to make checks + # about inheritance of classes. We need to upwrap any object + # proxy. Not wanting to add this to ObjectProxy as not sure of + # broader implications of doing that. Thus restrict to + # FunctionWrapper used by decorators. + + if hasattr(subclass, "__wrapped__"): + return issubclass(subclass.__wrapped__, self.__wrapped__) + else: + return issubclass(subclass, self.__wrapped__) + +class BoundFunctionWrapper(_FunctionWrapperBase): + + def __call__(self, *args, **kwargs): + # If enabled has been specified, then evaluate it at this point + # and if the wrapper is not to be executed, then simply return + # the bound function rather than a bound wrapper for the bound + # function. When evaluating enabled, if it is callable we call + # it, otherwise we evaluate it as a boolean. + + if self._self_enabled is not None: + if callable(self._self_enabled): + if not self._self_enabled(): + return self.__wrapped__(*args, **kwargs) + elif not self._self_enabled: + return self.__wrapped__(*args, **kwargs) + + # We need to do things different depending on whether we are + # likely wrapping an instance method vs a static method or class + # method. + + if self._self_binding == 'function': + if self._self_instance is None: + # This situation can occur where someone is calling the + # instancemethod via the class type and passing the instance + # as the first argument. We need to shift the args before + # making the call to the wrapper and effectively bind the + # instance to the wrapped function using a partial so the + # wrapper doesn't see anything as being different. + + if not args: + raise TypeError('missing 1 required positional argument') + + instance, args = args[0], args[1:] + wrapped = PartialCallableObjectProxy(self.__wrapped__, instance) + return self._self_wrapper(wrapped, instance, args, kwargs) + + return self._self_wrapper(self.__wrapped__, self._self_instance, + args, kwargs) + + else: + # As in this case we would be dealing with a classmethod or + # staticmethod, then _self_instance will only tell us whether + # when calling the classmethod or staticmethod they did it via an + # instance of the class it is bound to and not the case where + # done by the class type itself. We thus ignore _self_instance + # and use the __self__ attribute of the bound function instead. + # For a classmethod, this means instance will be the class type + # and for a staticmethod it will be None. This is probably the + # more useful thing we can pass through even though we loose + # knowledge of whether they were called on the instance vs the + # class type, as it reflects what they have available in the + # decoratored function. + + instance = getattr(self.__wrapped__, '__self__', None) + + return self._self_wrapper(self.__wrapped__, instance, args, + kwargs) + +class FunctionWrapper(_FunctionWrapperBase): + + __bound_function_wrapper__ = BoundFunctionWrapper + + def __init__(self, wrapped, wrapper, enabled=None): + # What it is we are wrapping here could be anything. We need to + # try and detect specific cases though. In particular, we need + # to detect when we are given something that is a method of a + # class. Further, we need to know when it is likely an instance + # method, as opposed to a class or static method. This can + # become problematic though as there isn't strictly a fool proof + # method of knowing. + # + # The situations we could encounter when wrapping a method are: + # + # 1. The wrapper is being applied as part of a decorator which + # is a part of the class definition. In this case what we are + # given is the raw unbound function, classmethod or staticmethod + # wrapper objects. + # + # The problem here is that we will not know we are being applied + # in the context of the class being set up. This becomes + # important later for the case of an instance method, because in + # that case we just see it as a raw function and can't + # distinguish it from wrapping a normal function outside of + # a class context. + # + # 2. The wrapper is being applied when performing monkey + # patching of the class type afterwards and the method to be + # wrapped was retrieved direct from the __dict__ of the class + # type. This is effectively the same as (1) above. + # + # 3. The wrapper is being applied when performing monkey + # patching of the class type afterwards and the method to be + # wrapped was retrieved from the class type. In this case + # binding will have been performed where the instance against + # which the method is bound will be None at that point. + # + # This case is a problem because we can no longer tell if the + # method was a static method, plus if using Python3, we cannot + # tell if it was an instance method as the concept of an + # unnbound method no longer exists. + # + # 4. The wrapper is being applied when performing monkey + # patching of an instance of a class. In this case binding will + # have been perfomed where the instance was not None. + # + # This case is a problem because we can no longer tell if the + # method was a static method. + # + # Overall, the best we can do is look at the original type of the + # object which was wrapped prior to any binding being done and + # see if it is an instance of classmethod or staticmethod. In + # the case where other decorators are between us and them, if + # they do not propagate the __class__ attribute so that the + # isinstance() checks works, then likely this will do the wrong + # thing where classmethod and staticmethod are used. + # + # Since it is likely to be very rare that anyone even puts + # decorators around classmethod and staticmethod, likelihood of + # that being an issue is very small, so we accept it and suggest + # that those other decorators be fixed. It is also only an issue + # if a decorator wants to actually do things with the arguments. + # + # As to not being able to identify static methods properly, we + # just hope that that isn't something people are going to want + # to wrap, or if they do suggest they do it the correct way by + # ensuring that it is decorated in the class definition itself, + # or patch it in the __dict__ of the class type. + # + # So to get the best outcome we can, whenever we aren't sure what + # it is, we label it as a 'function'. If it was already bound and + # that is rebound later, we assume that it will be an instance + # method and try an cope with the possibility that the 'self' + # argument it being passed as an explicit argument and shuffle + # the arguments around to extract 'self' for use as the instance. + + if isinstance(wrapped, classmethod): + binding = 'classmethod' + + elif isinstance(wrapped, staticmethod): + binding = 'staticmethod' + + elif hasattr(wrapped, '__self__'): + if inspect.isclass(wrapped.__self__): + binding = 'classmethod' + else: + binding = 'function' + + else: + binding = 'function' + + super(FunctionWrapper, self).__init__(wrapped, None, wrapper, + enabled, binding) + +try: + if not os.environ.get('WRAPT_DISABLE_EXTENSIONS'): + from ._wrappers import (ObjectProxy, CallableObjectProxy, + PartialCallableObjectProxy, FunctionWrapper, + BoundFunctionWrapper, _FunctionWrapperBase) +except ImportError: + pass + +# Helper functions for applying wrappers to existing functions. + +def resolve_path(module, name): + if isinstance(module, string_types): + __import__(module) + module = sys.modules[module] + + parent = module + + path = name.split('.') + attribute = path[0] + + # We can't just always use getattr() because in doing + # that on a class it will cause binding to occur which + # will complicate things later and cause some things not + # to work. For the case of a class we therefore access + # the __dict__ directly. To cope though with the wrong + # class being given to us, or a method being moved into + # a base class, we need to walk the class hierarchy to + # work out exactly which __dict__ the method was defined + # in, as accessing it from __dict__ will fail if it was + # not actually on the class given. Fallback to using + # getattr() if we can't find it. If it truly doesn't + # exist, then that will fail. + + def lookup_attribute(parent, attribute): + if inspect.isclass(parent): + for cls in inspect.getmro(parent): + if attribute in vars(cls): + return vars(cls)[attribute] + else: + return getattr(parent, attribute) + else: + return getattr(parent, attribute) + + original = lookup_attribute(parent, attribute) + + for attribute in path[1:]: + parent = original + original = lookup_attribute(parent, attribute) + + return (parent, attribute, original) + +def apply_patch(parent, attribute, replacement): + setattr(parent, attribute, replacement) + +def wrap_object(module, name, factory, args=(), kwargs={}): + (parent, attribute, original) = resolve_path(module, name) + wrapper = factory(original, *args, **kwargs) + apply_patch(parent, attribute, wrapper) + return wrapper + +# Function for applying a proxy object to an attribute of a class +# instance. The wrapper works by defining an attribute of the same name +# on the class which is a descriptor and which intercepts access to the +# instance attribute. Note that this cannot be used on attributes which +# are themselves defined by a property object. + +class AttributeWrapper(object): + + def __init__(self, attribute, factory, args, kwargs): + self.attribute = attribute + self.factory = factory + self.args = args + self.kwargs = kwargs + + def __get__(self, instance, owner): + value = instance.__dict__[self.attribute] + return self.factory(value, *self.args, **self.kwargs) + + def __set__(self, instance, value): + instance.__dict__[self.attribute] = value + + def __delete__(self, instance): + del instance.__dict__[self.attribute] + +def wrap_object_attribute(module, name, factory, args=(), kwargs={}): + path, attribute = name.rsplit('.', 1) + parent = resolve_path(module, path)[2] + wrapper = AttributeWrapper(attribute, factory, args, kwargs) + apply_patch(parent, attribute, wrapper) + return wrapper + +# Functions for creating a simple decorator using a FunctionWrapper, +# plus short cut functions for applying wrappers to functions. These are +# for use when doing monkey patching. For a more featured way of +# creating decorators see the decorator decorator instead. + +def function_wrapper(wrapper): + def _wrapper(wrapped, instance, args, kwargs): + target_wrapped = args[0] + if instance is None: + target_wrapper = wrapper + elif inspect.isclass(instance): + target_wrapper = wrapper.__get__(None, instance) + else: + target_wrapper = wrapper.__get__(instance, type(instance)) + return FunctionWrapper(target_wrapped, target_wrapper) + return FunctionWrapper(wrapper, _wrapper) + +def wrap_function_wrapper(module, name, wrapper): + return wrap_object(module, name, FunctionWrapper, (wrapper,)) + +def patch_function_wrapper(module, name): + def _wrapper(wrapper): + return wrap_object(module, name, FunctionWrapper, (wrapper,)) + return _wrapper + +def transient_function_wrapper(module, name): + def _decorator(wrapper): + def _wrapper(wrapped, instance, args, kwargs): + target_wrapped = args[0] + if instance is None: + target_wrapper = wrapper + elif inspect.isclass(instance): + target_wrapper = wrapper.__get__(None, instance) + else: + target_wrapper = wrapper.__get__(instance, type(instance)) + def _execute(wrapped, instance, args, kwargs): + (parent, attribute, original) = resolve_path(module, name) + replacement = FunctionWrapper(original, target_wrapper) + setattr(parent, attribute, replacement) + try: + return wrapped(*args, **kwargs) + finally: + setattr(parent, attribute, original) + return FunctionWrapper(target_wrapped, _execute) + return FunctionWrapper(wrapper, _wrapper) + return _decorator + +# A weak function proxy. This will work on instance methods, class +# methods, static methods and regular functions. Special treatment is +# needed for the method types because the bound method is effectively a +# transient object and applying a weak reference to one will immediately +# result in it being destroyed and the weakref callback called. The weak +# reference is therefore applied to the instance the method is bound to +# and the original function. The function is then rebound at the point +# of a call via the weak function proxy. + +def _weak_function_proxy_callback(ref, proxy, callback): + if proxy._self_expired: + return + + proxy._self_expired = True + + # This could raise an exception. We let it propagate back and let + # the weakref.proxy() deal with it, at which point it generally + # prints out a short error message direct to stderr and keeps going. + + if callback is not None: + callback(proxy) + +class WeakFunctionProxy(ObjectProxy): + + __slots__ = ('_self_expired', '_self_instance') + + def __init__(self, wrapped, callback=None): + # We need to determine if the wrapped function is actually a + # bound method. In the case of a bound method, we need to keep a + # reference to the original unbound function and the instance. + # This is necessary because if we hold a reference to the bound + # function, it will be the only reference and given it is a + # temporary object, it will almost immediately expire and + # the weakref callback triggered. So what is done is that we + # hold a reference to the instance and unbound function and + # when called bind the function to the instance once again and + # then call it. Note that we avoid using a nested function for + # the callback here so as not to cause any odd reference cycles. + + _callback = callback and functools.partial( + _weak_function_proxy_callback, proxy=self, + callback=callback) + + self._self_expired = False + + if isinstance(wrapped, _FunctionWrapperBase): + self._self_instance = weakref.ref(wrapped._self_instance, + _callback) + + if wrapped._self_parent is not None: + super(WeakFunctionProxy, self).__init__( + weakref.proxy(wrapped._self_parent, _callback)) + + else: + super(WeakFunctionProxy, self).__init__( + weakref.proxy(wrapped, _callback)) + + return + + try: + self._self_instance = weakref.ref(wrapped.__self__, _callback) + + super(WeakFunctionProxy, self).__init__( + weakref.proxy(wrapped.__func__, _callback)) + + except AttributeError: + self._self_instance = None + + super(WeakFunctionProxy, self).__init__( + weakref.proxy(wrapped, _callback)) + + def __call__(self, *args, **kwargs): + # We perform a boolean check here on the instance and wrapped + # function as that will trigger the reference error prior to + # calling if the reference had expired. + + instance = self._self_instance and self._self_instance() + function = self.__wrapped__ and self.__wrapped__ + + # If the wrapped function was originally a bound function, for + # which we retained a reference to the instance and the unbound + # function we need to rebind the function and then call it. If + # not just called the wrapped function. + + if instance is None: + return self.__wrapped__(*args, **kwargs) + + return function.__get__(instance, type(instance))(*args, **kwargs) diff --git a/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/yaml/composer.py b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/yaml/composer.py new file mode 100644 index 0000000000000000000000000000000000000000..6d15cb40e3b4198819c91c6f8d8b32807fcf53b2 --- /dev/null +++ b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/yaml/composer.py @@ -0,0 +1,139 @@ + +__all__ = ['Composer', 'ComposerError'] + +from .error import MarkedYAMLError +from .events import * +from .nodes import * + +class ComposerError(MarkedYAMLError): + pass + +class Composer: + + def __init__(self): + self.anchors = {} + + def check_node(self): + # Drop the STREAM-START event. + if self.check_event(StreamStartEvent): + self.get_event() + + # If there are more documents available? + return not self.check_event(StreamEndEvent) + + def get_node(self): + # Get the root node of the next document. + if not self.check_event(StreamEndEvent): + return self.compose_document() + + def get_single_node(self): + # Drop the STREAM-START event. + self.get_event() + + # Compose a document if the stream is not empty. + document = None + if not self.check_event(StreamEndEvent): + document = self.compose_document() + + # Ensure that the stream contains no more documents. + if not self.check_event(StreamEndEvent): + event = self.get_event() + raise ComposerError("expected a single document in the stream", + document.start_mark, "but found another document", + event.start_mark) + + # Drop the STREAM-END event. + self.get_event() + + return document + + def compose_document(self): + # Drop the DOCUMENT-START event. + self.get_event() + + # Compose the root node. + node = self.compose_node(None, None) + + # Drop the DOCUMENT-END event. + self.get_event() + + self.anchors = {} + return node + + def compose_node(self, parent, index): + if self.check_event(AliasEvent): + event = self.get_event() + anchor = event.anchor + if anchor not in self.anchors: + raise ComposerError(None, None, "found undefined alias %r" + % anchor, event.start_mark) + return self.anchors[anchor] + event = self.peek_event() + anchor = event.anchor + if anchor is not None: + if anchor in self.anchors: + raise ComposerError("found duplicate anchor %r; first occurrence" + % anchor, self.anchors[anchor].start_mark, + "second occurrence", event.start_mark) + self.descend_resolver(parent, index) + if self.check_event(ScalarEvent): + node = self.compose_scalar_node(anchor) + elif self.check_event(SequenceStartEvent): + node = self.compose_sequence_node(anchor) + elif self.check_event(MappingStartEvent): + node = self.compose_mapping_node(anchor) + self.ascend_resolver() + return node + + def compose_scalar_node(self, anchor): + event = self.get_event() + tag = event.tag + if tag is None or tag == '!': + tag = self.resolve(ScalarNode, event.value, event.implicit) + node = ScalarNode(tag, event.value, + event.start_mark, event.end_mark, style=event.style) + if anchor is not None: + self.anchors[anchor] = node + return node + + def compose_sequence_node(self, anchor): + start_event = self.get_event() + tag = start_event.tag + if tag is None or tag == '!': + tag = self.resolve(SequenceNode, None, start_event.implicit) + node = SequenceNode(tag, [], + start_event.start_mark, None, + flow_style=start_event.flow_style) + if anchor is not None: + self.anchors[anchor] = node + index = 0 + while not self.check_event(SequenceEndEvent): + node.value.append(self.compose_node(node, index)) + index += 1 + end_event = self.get_event() + node.end_mark = end_event.end_mark + return node + + def compose_mapping_node(self, anchor): + start_event = self.get_event() + tag = start_event.tag + if tag is None or tag == '!': + tag = self.resolve(MappingNode, None, start_event.implicit) + node = MappingNode(tag, [], + start_event.start_mark, None, + flow_style=start_event.flow_style) + if anchor is not None: + self.anchors[anchor] = node + while not self.check_event(MappingEndEvent): + #key_event = self.peek_event() + item_key = self.compose_node(node, None) + #if item_key in node.value: + # raise ComposerError("while composing a mapping", start_event.start_mark, + # "found duplicate key", key_event.start_mark) + item_value = self.compose_node(node, item_key) + #node.value[item_key] = item_value + node.value.append((item_key, item_value)) + end_event = self.get_event() + node.end_mark = end_event.end_mark + return node + diff --git a/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/yaml/cyaml.py b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/yaml/cyaml.py new file mode 100644 index 0000000000000000000000000000000000000000..0c21345879b298bb8668201bebe7d289586b17f9 --- /dev/null +++ b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/yaml/cyaml.py @@ -0,0 +1,101 @@ + +__all__ = [ + 'CBaseLoader', 'CSafeLoader', 'CFullLoader', 'CUnsafeLoader', 'CLoader', + 'CBaseDumper', 'CSafeDumper', 'CDumper' +] + +from yaml._yaml import CParser, CEmitter + +from .constructor import * + +from .serializer import * +from .representer import * + +from .resolver import * + +class CBaseLoader(CParser, BaseConstructor, BaseResolver): + + def __init__(self, stream): + CParser.__init__(self, stream) + BaseConstructor.__init__(self) + BaseResolver.__init__(self) + +class CSafeLoader(CParser, SafeConstructor, Resolver): + + def __init__(self, stream): + CParser.__init__(self, stream) + SafeConstructor.__init__(self) + Resolver.__init__(self) + +class CFullLoader(CParser, FullConstructor, Resolver): + + def __init__(self, stream): + CParser.__init__(self, stream) + FullConstructor.__init__(self) + Resolver.__init__(self) + +class CUnsafeLoader(CParser, UnsafeConstructor, Resolver): + + def __init__(self, stream): + CParser.__init__(self, stream) + UnsafeConstructor.__init__(self) + Resolver.__init__(self) + +class CLoader(CParser, Constructor, Resolver): + + def __init__(self, stream): + CParser.__init__(self, stream) + Constructor.__init__(self) + Resolver.__init__(self) + +class CBaseDumper(CEmitter, BaseRepresenter, BaseResolver): + + def __init__(self, stream, + default_style=None, default_flow_style=False, + canonical=None, indent=None, width=None, + allow_unicode=None, line_break=None, + encoding=None, explicit_start=None, explicit_end=None, + version=None, tags=None, sort_keys=True): + CEmitter.__init__(self, stream, canonical=canonical, + indent=indent, width=width, encoding=encoding, + allow_unicode=allow_unicode, line_break=line_break, + explicit_start=explicit_start, explicit_end=explicit_end, + version=version, tags=tags) + Representer.__init__(self, default_style=default_style, + default_flow_style=default_flow_style, sort_keys=sort_keys) + Resolver.__init__(self) + +class CSafeDumper(CEmitter, SafeRepresenter, Resolver): + + def __init__(self, stream, + default_style=None, default_flow_style=False, + canonical=None, indent=None, width=None, + allow_unicode=None, line_break=None, + encoding=None, explicit_start=None, explicit_end=None, + version=None, tags=None, sort_keys=True): + CEmitter.__init__(self, stream, canonical=canonical, + indent=indent, width=width, encoding=encoding, + allow_unicode=allow_unicode, line_break=line_break, + explicit_start=explicit_start, explicit_end=explicit_end, + version=version, tags=tags) + SafeRepresenter.__init__(self, default_style=default_style, + default_flow_style=default_flow_style, sort_keys=sort_keys) + Resolver.__init__(self) + +class CDumper(CEmitter, Serializer, Representer, Resolver): + + def __init__(self, stream, + default_style=None, default_flow_style=False, + canonical=None, indent=None, width=None, + allow_unicode=None, line_break=None, + encoding=None, explicit_start=None, explicit_end=None, + version=None, tags=None, sort_keys=True): + CEmitter.__init__(self, stream, canonical=canonical, + indent=indent, width=width, encoding=encoding, + allow_unicode=allow_unicode, line_break=line_break, + explicit_start=explicit_start, explicit_end=explicit_end, + version=version, tags=tags) + Representer.__init__(self, default_style=default_style, + default_flow_style=default_flow_style, sort_keys=sort_keys) + Resolver.__init__(self) + diff --git a/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/yaml/emitter.py b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/yaml/emitter.py new file mode 100644 index 0000000000000000000000000000000000000000..a664d011162af69184df2f8e59ab7feec818f7c7 --- /dev/null +++ b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/yaml/emitter.py @@ -0,0 +1,1137 @@ + +# Emitter expects events obeying the following grammar: +# stream ::= STREAM-START document* STREAM-END +# document ::= DOCUMENT-START node DOCUMENT-END +# node ::= SCALAR | sequence | mapping +# sequence ::= SEQUENCE-START node* SEQUENCE-END +# mapping ::= MAPPING-START (node node)* MAPPING-END + +__all__ = ['Emitter', 'EmitterError'] + +from .error import YAMLError +from .events import * + +class EmitterError(YAMLError): + pass + +class ScalarAnalysis: + def __init__(self, scalar, empty, multiline, + allow_flow_plain, allow_block_plain, + allow_single_quoted, allow_double_quoted, + allow_block): + self.scalar = scalar + self.empty = empty + self.multiline = multiline + self.allow_flow_plain = allow_flow_plain + self.allow_block_plain = allow_block_plain + self.allow_single_quoted = allow_single_quoted + self.allow_double_quoted = allow_double_quoted + self.allow_block = allow_block + +class Emitter: + + DEFAULT_TAG_PREFIXES = { + '!' : '!', + 'tag:yaml.org,2002:' : '!!', + } + + def __init__(self, stream, canonical=None, indent=None, width=None, + allow_unicode=None, line_break=None): + + # The stream should have the methods `write` and possibly `flush`. + self.stream = stream + + # Encoding can be overridden by STREAM-START. + self.encoding = None + + # Emitter is a state machine with a stack of states to handle nested + # structures. + self.states = [] + self.state = self.expect_stream_start + + # Current event and the event queue. + self.events = [] + self.event = None + + # The current indentation level and the stack of previous indents. + self.indents = [] + self.indent = None + + # Flow level. + self.flow_level = 0 + + # Contexts. + self.root_context = False + self.sequence_context = False + self.mapping_context = False + self.simple_key_context = False + + # Characteristics of the last emitted character: + # - current position. + # - is it a whitespace? + # - is it an indention character + # (indentation space, '-', '?', or ':')? + self.line = 0 + self.column = 0 + self.whitespace = True + self.indention = True + + # Whether the document requires an explicit document indicator + self.open_ended = False + + # Formatting details. + self.canonical = canonical + self.allow_unicode = allow_unicode + self.best_indent = 2 + if indent and 1 < indent < 10: + self.best_indent = indent + self.best_width = 80 + if width and width > self.best_indent*2: + self.best_width = width + self.best_line_break = '\n' + if line_break in ['\r', '\n', '\r\n']: + self.best_line_break = line_break + + # Tag prefixes. + self.tag_prefixes = None + + # Prepared anchor and tag. + self.prepared_anchor = None + self.prepared_tag = None + + # Scalar analysis and style. + self.analysis = None + self.style = None + + def dispose(self): + # Reset the state attributes (to clear self-references) + self.states = [] + self.state = None + + def emit(self, event): + self.events.append(event) + while not self.need_more_events(): + self.event = self.events.pop(0) + self.state() + self.event = None + + # In some cases, we wait for a few next events before emitting. + + def need_more_events(self): + if not self.events: + return True + event = self.events[0] + if isinstance(event, DocumentStartEvent): + return self.need_events(1) + elif isinstance(event, SequenceStartEvent): + return self.need_events(2) + elif isinstance(event, MappingStartEvent): + return self.need_events(3) + else: + return False + + def need_events(self, count): + level = 0 + for event in self.events[1:]: + if isinstance(event, (DocumentStartEvent, CollectionStartEvent)): + level += 1 + elif isinstance(event, (DocumentEndEvent, CollectionEndEvent)): + level -= 1 + elif isinstance(event, StreamEndEvent): + level = -1 + if level < 0: + return False + return (len(self.events) < count+1) + + def increase_indent(self, flow=False, indentless=False): + self.indents.append(self.indent) + if self.indent is None: + if flow: + self.indent = self.best_indent + else: + self.indent = 0 + elif not indentless: + self.indent += self.best_indent + + # States. + + # Stream handlers. + + def expect_stream_start(self): + if isinstance(self.event, StreamStartEvent): + if self.event.encoding and not hasattr(self.stream, 'encoding'): + self.encoding = self.event.encoding + self.write_stream_start() + self.state = self.expect_first_document_start + else: + raise EmitterError("expected StreamStartEvent, but got %s" + % self.event) + + def expect_nothing(self): + raise EmitterError("expected nothing, but got %s" % self.event) + + # Document handlers. + + def expect_first_document_start(self): + return self.expect_document_start(first=True) + + def expect_document_start(self, first=False): + if isinstance(self.event, DocumentStartEvent): + if (self.event.version or self.event.tags) and self.open_ended: + self.write_indicator('...', True) + self.write_indent() + if self.event.version: + version_text = self.prepare_version(self.event.version) + self.write_version_directive(version_text) + self.tag_prefixes = self.DEFAULT_TAG_PREFIXES.copy() + if self.event.tags: + handles = sorted(self.event.tags.keys()) + for handle in handles: + prefix = self.event.tags[handle] + self.tag_prefixes[prefix] = handle + handle_text = self.prepare_tag_handle(handle) + prefix_text = self.prepare_tag_prefix(prefix) + self.write_tag_directive(handle_text, prefix_text) + implicit = (first and not self.event.explicit and not self.canonical + and not self.event.version and not self.event.tags + and not self.check_empty_document()) + if not implicit: + self.write_indent() + self.write_indicator('---', True) + if self.canonical: + self.write_indent() + self.state = self.expect_document_root + elif isinstance(self.event, StreamEndEvent): + if self.open_ended: + self.write_indicator('...', True) + self.write_indent() + self.write_stream_end() + self.state = self.expect_nothing + else: + raise EmitterError("expected DocumentStartEvent, but got %s" + % self.event) + + def expect_document_end(self): + if isinstance(self.event, DocumentEndEvent): + self.write_indent() + if self.event.explicit: + self.write_indicator('...', True) + self.write_indent() + self.flush_stream() + self.state = self.expect_document_start + else: + raise EmitterError("expected DocumentEndEvent, but got %s" + % self.event) + + def expect_document_root(self): + self.states.append(self.expect_document_end) + self.expect_node(root=True) + + # Node handlers. + + def expect_node(self, root=False, sequence=False, mapping=False, + simple_key=False): + self.root_context = root + self.sequence_context = sequence + self.mapping_context = mapping + self.simple_key_context = simple_key + if isinstance(self.event, AliasEvent): + self.expect_alias() + elif isinstance(self.event, (ScalarEvent, CollectionStartEvent)): + self.process_anchor('&') + self.process_tag() + if isinstance(self.event, ScalarEvent): + self.expect_scalar() + elif isinstance(self.event, SequenceStartEvent): + if self.flow_level or self.canonical or self.event.flow_style \ + or self.check_empty_sequence(): + self.expect_flow_sequence() + else: + self.expect_block_sequence() + elif isinstance(self.event, MappingStartEvent): + if self.flow_level or self.canonical or self.event.flow_style \ + or self.check_empty_mapping(): + self.expect_flow_mapping() + else: + self.expect_block_mapping() + else: + raise EmitterError("expected NodeEvent, but got %s" % self.event) + + def expect_alias(self): + if self.event.anchor is None: + raise EmitterError("anchor is not specified for alias") + self.process_anchor('*') + self.state = self.states.pop() + + def expect_scalar(self): + self.increase_indent(flow=True) + self.process_scalar() + self.indent = self.indents.pop() + self.state = self.states.pop() + + # Flow sequence handlers. + + def expect_flow_sequence(self): + self.write_indicator('[', True, whitespace=True) + self.flow_level += 1 + self.increase_indent(flow=True) + self.state = self.expect_first_flow_sequence_item + + def expect_first_flow_sequence_item(self): + if isinstance(self.event, SequenceEndEvent): + self.indent = self.indents.pop() + self.flow_level -= 1 + self.write_indicator(']', False) + self.state = self.states.pop() + else: + if self.canonical or self.column > self.best_width: + self.write_indent() + self.states.append(self.expect_flow_sequence_item) + self.expect_node(sequence=True) + + def expect_flow_sequence_item(self): + if isinstance(self.event, SequenceEndEvent): + self.indent = self.indents.pop() + self.flow_level -= 1 + if self.canonical: + self.write_indicator(',', False) + self.write_indent() + self.write_indicator(']', False) + self.state = self.states.pop() + else: + self.write_indicator(',', False) + if self.canonical or self.column > self.best_width: + self.write_indent() + self.states.append(self.expect_flow_sequence_item) + self.expect_node(sequence=True) + + # Flow mapping handlers. + + def expect_flow_mapping(self): + self.write_indicator('{', True, whitespace=True) + self.flow_level += 1 + self.increase_indent(flow=True) + self.state = self.expect_first_flow_mapping_key + + def expect_first_flow_mapping_key(self): + if isinstance(self.event, MappingEndEvent): + self.indent = self.indents.pop() + self.flow_level -= 1 + self.write_indicator('}', False) + self.state = self.states.pop() + else: + if self.canonical or self.column > self.best_width: + self.write_indent() + if not self.canonical and self.check_simple_key(): + self.states.append(self.expect_flow_mapping_simple_value) + self.expect_node(mapping=True, simple_key=True) + else: + self.write_indicator('?', True) + self.states.append(self.expect_flow_mapping_value) + self.expect_node(mapping=True) + + def expect_flow_mapping_key(self): + if isinstance(self.event, MappingEndEvent): + self.indent = self.indents.pop() + self.flow_level -= 1 + if self.canonical: + self.write_indicator(',', False) + self.write_indent() + self.write_indicator('}', False) + self.state = self.states.pop() + else: + self.write_indicator(',', False) + if self.canonical or self.column > self.best_width: + self.write_indent() + if not self.canonical and self.check_simple_key(): + self.states.append(self.expect_flow_mapping_simple_value) + self.expect_node(mapping=True, simple_key=True) + else: + self.write_indicator('?', True) + self.states.append(self.expect_flow_mapping_value) + self.expect_node(mapping=True) + + def expect_flow_mapping_simple_value(self): + self.write_indicator(':', False) + self.states.append(self.expect_flow_mapping_key) + self.expect_node(mapping=True) + + def expect_flow_mapping_value(self): + if self.canonical or self.column > self.best_width: + self.write_indent() + self.write_indicator(':', True) + self.states.append(self.expect_flow_mapping_key) + self.expect_node(mapping=True) + + # Block sequence handlers. + + def expect_block_sequence(self): + indentless = (self.mapping_context and not self.indention) + self.increase_indent(flow=False, indentless=indentless) + self.state = self.expect_first_block_sequence_item + + def expect_first_block_sequence_item(self): + return self.expect_block_sequence_item(first=True) + + def expect_block_sequence_item(self, first=False): + if not first and isinstance(self.event, SequenceEndEvent): + self.indent = self.indents.pop() + self.state = self.states.pop() + else: + self.write_indent() + self.write_indicator('-', True, indention=True) + self.states.append(self.expect_block_sequence_item) + self.expect_node(sequence=True) + + # Block mapping handlers. + + def expect_block_mapping(self): + self.increase_indent(flow=False) + self.state = self.expect_first_block_mapping_key + + def expect_first_block_mapping_key(self): + return self.expect_block_mapping_key(first=True) + + def expect_block_mapping_key(self, first=False): + if not first and isinstance(self.event, MappingEndEvent): + self.indent = self.indents.pop() + self.state = self.states.pop() + else: + self.write_indent() + if self.check_simple_key(): + self.states.append(self.expect_block_mapping_simple_value) + self.expect_node(mapping=True, simple_key=True) + else: + self.write_indicator('?', True, indention=True) + self.states.append(self.expect_block_mapping_value) + self.expect_node(mapping=True) + + def expect_block_mapping_simple_value(self): + self.write_indicator(':', False) + self.states.append(self.expect_block_mapping_key) + self.expect_node(mapping=True) + + def expect_block_mapping_value(self): + self.write_indent() + self.write_indicator(':', True, indention=True) + self.states.append(self.expect_block_mapping_key) + self.expect_node(mapping=True) + + # Checkers. + + def check_empty_sequence(self): + return (isinstance(self.event, SequenceStartEvent) and self.events + and isinstance(self.events[0], SequenceEndEvent)) + + def check_empty_mapping(self): + return (isinstance(self.event, MappingStartEvent) and self.events + and isinstance(self.events[0], MappingEndEvent)) + + def check_empty_document(self): + if not isinstance(self.event, DocumentStartEvent) or not self.events: + return False + event = self.events[0] + return (isinstance(event, ScalarEvent) and event.anchor is None + and event.tag is None and event.implicit and event.value == '') + + def check_simple_key(self): + length = 0 + if isinstance(self.event, NodeEvent) and self.event.anchor is not None: + if self.prepared_anchor is None: + self.prepared_anchor = self.prepare_anchor(self.event.anchor) + length += len(self.prepared_anchor) + if isinstance(self.event, (ScalarEvent, CollectionStartEvent)) \ + and self.event.tag is not None: + if self.prepared_tag is None: + self.prepared_tag = self.prepare_tag(self.event.tag) + length += len(self.prepared_tag) + if isinstance(self.event, ScalarEvent): + if self.analysis is None: + self.analysis = self.analyze_scalar(self.event.value) + length += len(self.analysis.scalar) + return (length < 128 and (isinstance(self.event, AliasEvent) + or (isinstance(self.event, ScalarEvent) + and not self.analysis.empty and not self.analysis.multiline) + or self.check_empty_sequence() or self.check_empty_mapping())) + + # Anchor, Tag, and Scalar processors. + + def process_anchor(self, indicator): + if self.event.anchor is None: + self.prepared_anchor = None + return + if self.prepared_anchor is None: + self.prepared_anchor = self.prepare_anchor(self.event.anchor) + if self.prepared_anchor: + self.write_indicator(indicator+self.prepared_anchor, True) + self.prepared_anchor = None + + def process_tag(self): + tag = self.event.tag + if isinstance(self.event, ScalarEvent): + if self.style is None: + self.style = self.choose_scalar_style() + if ((not self.canonical or tag is None) and + ((self.style == '' and self.event.implicit[0]) + or (self.style != '' and self.event.implicit[1]))): + self.prepared_tag = None + return + if self.event.implicit[0] and tag is None: + tag = '!' + self.prepared_tag = None + else: + if (not self.canonical or tag is None) and self.event.implicit: + self.prepared_tag = None + return + if tag is None: + raise EmitterError("tag is not specified") + if self.prepared_tag is None: + self.prepared_tag = self.prepare_tag(tag) + if self.prepared_tag: + self.write_indicator(self.prepared_tag, True) + self.prepared_tag = None + + def choose_scalar_style(self): + if self.analysis is None: + self.analysis = self.analyze_scalar(self.event.value) + if self.event.style == '"' or self.canonical: + return '"' + if not self.event.style and self.event.implicit[0]: + if (not (self.simple_key_context and + (self.analysis.empty or self.analysis.multiline)) + and (self.flow_level and self.analysis.allow_flow_plain + or (not self.flow_level and self.analysis.allow_block_plain))): + return '' + if self.event.style and self.event.style in '|>': + if (not self.flow_level and not self.simple_key_context + and self.analysis.allow_block): + return self.event.style + if not self.event.style or self.event.style == '\'': + if (self.analysis.allow_single_quoted and + not (self.simple_key_context and self.analysis.multiline)): + return '\'' + return '"' + + def process_scalar(self): + if self.analysis is None: + self.analysis = self.analyze_scalar(self.event.value) + if self.style is None: + self.style = self.choose_scalar_style() + split = (not self.simple_key_context) + #if self.analysis.multiline and split \ + # and (not self.style or self.style in '\'\"'): + # self.write_indent() + if self.style == '"': + self.write_double_quoted(self.analysis.scalar, split) + elif self.style == '\'': + self.write_single_quoted(self.analysis.scalar, split) + elif self.style == '>': + self.write_folded(self.analysis.scalar) + elif self.style == '|': + self.write_literal(self.analysis.scalar) + else: + self.write_plain(self.analysis.scalar, split) + self.analysis = None + self.style = None + + # Analyzers. + + def prepare_version(self, version): + major, minor = version + if major != 1: + raise EmitterError("unsupported YAML version: %d.%d" % (major, minor)) + return '%d.%d' % (major, minor) + + def prepare_tag_handle(self, handle): + if not handle: + raise EmitterError("tag handle must not be empty") + if handle[0] != '!' or handle[-1] != '!': + raise EmitterError("tag handle must start and end with '!': %r" % handle) + for ch in handle[1:-1]: + if not ('0' <= ch <= '9' or 'A' <= ch <= 'Z' or 'a' <= ch <= 'z' \ + or ch in '-_'): + raise EmitterError("invalid character %r in the tag handle: %r" + % (ch, handle)) + return handle + + def prepare_tag_prefix(self, prefix): + if not prefix: + raise EmitterError("tag prefix must not be empty") + chunks = [] + start = end = 0 + if prefix[0] == '!': + end = 1 + while end < len(prefix): + ch = prefix[end] + if '0' <= ch <= '9' or 'A' <= ch <= 'Z' or 'a' <= ch <= 'z' \ + or ch in '-;/?!:@&=+$,_.~*\'()[]': + end += 1 + else: + if start < end: + chunks.append(prefix[start:end]) + start = end = end+1 + data = ch.encode('utf-8') + for ch in data: + chunks.append('%%%02X' % ord(ch)) + if start < end: + chunks.append(prefix[start:end]) + return ''.join(chunks) + + def prepare_tag(self, tag): + if not tag: + raise EmitterError("tag must not be empty") + if tag == '!': + return tag + handle = None + suffix = tag + prefixes = sorted(self.tag_prefixes.keys()) + for prefix in prefixes: + if tag.startswith(prefix) \ + and (prefix == '!' or len(prefix) < len(tag)): + handle = self.tag_prefixes[prefix] + suffix = tag[len(prefix):] + chunks = [] + start = end = 0 + while end < len(suffix): + ch = suffix[end] + if '0' <= ch <= '9' or 'A' <= ch <= 'Z' or 'a' <= ch <= 'z' \ + or ch in '-;/?:@&=+$,_.~*\'()[]' \ + or (ch == '!' and handle != '!'): + end += 1 + else: + if start < end: + chunks.append(suffix[start:end]) + start = end = end+1 + data = ch.encode('utf-8') + for ch in data: + chunks.append('%%%02X' % ch) + if start < end: + chunks.append(suffix[start:end]) + suffix_text = ''.join(chunks) + if handle: + return '%s%s' % (handle, suffix_text) + else: + return '!<%s>' % suffix_text + + def prepare_anchor(self, anchor): + if not anchor: + raise EmitterError("anchor must not be empty") + for ch in anchor: + if not ('0' <= ch <= '9' or 'A' <= ch <= 'Z' or 'a' <= ch <= 'z' \ + or ch in '-_'): + raise EmitterError("invalid character %r in the anchor: %r" + % (ch, anchor)) + return anchor + + def analyze_scalar(self, scalar): + + # Empty scalar is a special case. + if not scalar: + return ScalarAnalysis(scalar=scalar, empty=True, multiline=False, + allow_flow_plain=False, allow_block_plain=True, + allow_single_quoted=True, allow_double_quoted=True, + allow_block=False) + + # Indicators and special characters. + block_indicators = False + flow_indicators = False + line_breaks = False + special_characters = False + + # Important whitespace combinations. + leading_space = False + leading_break = False + trailing_space = False + trailing_break = False + break_space = False + space_break = False + + # Check document indicators. + if scalar.startswith('---') or scalar.startswith('...'): + block_indicators = True + flow_indicators = True + + # First character or preceded by a whitespace. + preceded_by_whitespace = True + + # Last character or followed by a whitespace. + followed_by_whitespace = (len(scalar) == 1 or + scalar[1] in '\0 \t\r\n\x85\u2028\u2029') + + # The previous character is a space. + previous_space = False + + # The previous character is a break. + previous_break = False + + index = 0 + while index < len(scalar): + ch = scalar[index] + + # Check for indicators. + if index == 0: + # Leading indicators are special characters. + if ch in '#,[]{}&*!|>\'\"%@`': + flow_indicators = True + block_indicators = True + if ch in '?:': + flow_indicators = True + if followed_by_whitespace: + block_indicators = True + if ch == '-' and followed_by_whitespace: + flow_indicators = True + block_indicators = True + else: + # Some indicators cannot appear within a scalar as well. + if ch in ',?[]{}': + flow_indicators = True + if ch == ':': + flow_indicators = True + if followed_by_whitespace: + block_indicators = True + if ch == '#' and preceded_by_whitespace: + flow_indicators = True + block_indicators = True + + # Check for line breaks, special, and unicode characters. + if ch in '\n\x85\u2028\u2029': + line_breaks = True + if not (ch == '\n' or '\x20' <= ch <= '\x7E'): + if (ch == '\x85' or '\xA0' <= ch <= '\uD7FF' + or '\uE000' <= ch <= '\uFFFD' + or '\U00010000' <= ch < '\U0010ffff') and ch != '\uFEFF': + unicode_characters = True + if not self.allow_unicode: + special_characters = True + else: + special_characters = True + + # Detect important whitespace combinations. + if ch == ' ': + if index == 0: + leading_space = True + if index == len(scalar)-1: + trailing_space = True + if previous_break: + break_space = True + previous_space = True + previous_break = False + elif ch in '\n\x85\u2028\u2029': + if index == 0: + leading_break = True + if index == len(scalar)-1: + trailing_break = True + if previous_space: + space_break = True + previous_space = False + previous_break = True + else: + previous_space = False + previous_break = False + + # Prepare for the next character. + index += 1 + preceded_by_whitespace = (ch in '\0 \t\r\n\x85\u2028\u2029') + followed_by_whitespace = (index+1 >= len(scalar) or + scalar[index+1] in '\0 \t\r\n\x85\u2028\u2029') + + # Let's decide what styles are allowed. + allow_flow_plain = True + allow_block_plain = True + allow_single_quoted = True + allow_double_quoted = True + allow_block = True + + # Leading and trailing whitespaces are bad for plain scalars. + if (leading_space or leading_break + or trailing_space or trailing_break): + allow_flow_plain = allow_block_plain = False + + # We do not permit trailing spaces for block scalars. + if trailing_space: + allow_block = False + + # Spaces at the beginning of a new line are only acceptable for block + # scalars. + if break_space: + allow_flow_plain = allow_block_plain = allow_single_quoted = False + + # Spaces followed by breaks, as well as special character are only + # allowed for double quoted scalars. + if space_break or special_characters: + allow_flow_plain = allow_block_plain = \ + allow_single_quoted = allow_block = False + + # Although the plain scalar writer supports breaks, we never emit + # multiline plain scalars. + if line_breaks: + allow_flow_plain = allow_block_plain = False + + # Flow indicators are forbidden for flow plain scalars. + if flow_indicators: + allow_flow_plain = False + + # Block indicators are forbidden for block plain scalars. + if block_indicators: + allow_block_plain = False + + return ScalarAnalysis(scalar=scalar, + empty=False, multiline=line_breaks, + allow_flow_plain=allow_flow_plain, + allow_block_plain=allow_block_plain, + allow_single_quoted=allow_single_quoted, + allow_double_quoted=allow_double_quoted, + allow_block=allow_block) + + # Writers. + + def flush_stream(self): + if hasattr(self.stream, 'flush'): + self.stream.flush() + + def write_stream_start(self): + # Write BOM if needed. + if self.encoding and self.encoding.startswith('utf-16'): + self.stream.write('\uFEFF'.encode(self.encoding)) + + def write_stream_end(self): + self.flush_stream() + + def write_indicator(self, indicator, need_whitespace, + whitespace=False, indention=False): + if self.whitespace or not need_whitespace: + data = indicator + else: + data = ' '+indicator + self.whitespace = whitespace + self.indention = self.indention and indention + self.column += len(data) + self.open_ended = False + if self.encoding: + data = data.encode(self.encoding) + self.stream.write(data) + + def write_indent(self): + indent = self.indent or 0 + if not self.indention or self.column > indent \ + or (self.column == indent and not self.whitespace): + self.write_line_break() + if self.column < indent: + self.whitespace = True + data = ' '*(indent-self.column) + self.column = indent + if self.encoding: + data = data.encode(self.encoding) + self.stream.write(data) + + def write_line_break(self, data=None): + if data is None: + data = self.best_line_break + self.whitespace = True + self.indention = True + self.line += 1 + self.column = 0 + if self.encoding: + data = data.encode(self.encoding) + self.stream.write(data) + + def write_version_directive(self, version_text): + data = '%%YAML %s' % version_text + if self.encoding: + data = data.encode(self.encoding) + self.stream.write(data) + self.write_line_break() + + def write_tag_directive(self, handle_text, prefix_text): + data = '%%TAG %s %s' % (handle_text, prefix_text) + if self.encoding: + data = data.encode(self.encoding) + self.stream.write(data) + self.write_line_break() + + # Scalar streams. + + def write_single_quoted(self, text, split=True): + self.write_indicator('\'', True) + spaces = False + breaks = False + start = end = 0 + while end <= len(text): + ch = None + if end < len(text): + ch = text[end] + if spaces: + if ch is None or ch != ' ': + if start+1 == end and self.column > self.best_width and split \ + and start != 0 and end != len(text): + self.write_indent() + else: + data = text[start:end] + self.column += len(data) + if self.encoding: + data = data.encode(self.encoding) + self.stream.write(data) + start = end + elif breaks: + if ch is None or ch not in '\n\x85\u2028\u2029': + if text[start] == '\n': + self.write_line_break() + for br in text[start:end]: + if br == '\n': + self.write_line_break() + else: + self.write_line_break(br) + self.write_indent() + start = end + else: + if ch is None or ch in ' \n\x85\u2028\u2029' or ch == '\'': + if start < end: + data = text[start:end] + self.column += len(data) + if self.encoding: + data = data.encode(self.encoding) + self.stream.write(data) + start = end + if ch == '\'': + data = '\'\'' + self.column += 2 + if self.encoding: + data = data.encode(self.encoding) + self.stream.write(data) + start = end + 1 + if ch is not None: + spaces = (ch == ' ') + breaks = (ch in '\n\x85\u2028\u2029') + end += 1 + self.write_indicator('\'', False) + + ESCAPE_REPLACEMENTS = { + '\0': '0', + '\x07': 'a', + '\x08': 'b', + '\x09': 't', + '\x0A': 'n', + '\x0B': 'v', + '\x0C': 'f', + '\x0D': 'r', + '\x1B': 'e', + '\"': '\"', + '\\': '\\', + '\x85': 'N', + '\xA0': '_', + '\u2028': 'L', + '\u2029': 'P', + } + + def write_double_quoted(self, text, split=True): + self.write_indicator('"', True) + start = end = 0 + while end <= len(text): + ch = None + if end < len(text): + ch = text[end] + if ch is None or ch in '"\\\x85\u2028\u2029\uFEFF' \ + or not ('\x20' <= ch <= '\x7E' + or (self.allow_unicode + and ('\xA0' <= ch <= '\uD7FF' + or '\uE000' <= ch <= '\uFFFD'))): + if start < end: + data = text[start:end] + self.column += len(data) + if self.encoding: + data = data.encode(self.encoding) + self.stream.write(data) + start = end + if ch is not None: + if ch in self.ESCAPE_REPLACEMENTS: + data = '\\'+self.ESCAPE_REPLACEMENTS[ch] + elif ch <= '\xFF': + data = '\\x%02X' % ord(ch) + elif ch <= '\uFFFF': + data = '\\u%04X' % ord(ch) + else: + data = '\\U%08X' % ord(ch) + self.column += len(data) + if self.encoding: + data = data.encode(self.encoding) + self.stream.write(data) + start = end+1 + if 0 < end < len(text)-1 and (ch == ' ' or start >= end) \ + and self.column+(end-start) > self.best_width and split: + data = text[start:end]+'\\' + if start < end: + start = end + self.column += len(data) + if self.encoding: + data = data.encode(self.encoding) + self.stream.write(data) + self.write_indent() + self.whitespace = False + self.indention = False + if text[start] == ' ': + data = '\\' + self.column += len(data) + if self.encoding: + data = data.encode(self.encoding) + self.stream.write(data) + end += 1 + self.write_indicator('"', False) + + def determine_block_hints(self, text): + hints = '' + if text: + if text[0] in ' \n\x85\u2028\u2029': + hints += str(self.best_indent) + if text[-1] not in '\n\x85\u2028\u2029': + hints += '-' + elif len(text) == 1 or text[-2] in '\n\x85\u2028\u2029': + hints += '+' + return hints + + def write_folded(self, text): + hints = self.determine_block_hints(text) + self.write_indicator('>'+hints, True) + if hints[-1:] == '+': + self.open_ended = True + self.write_line_break() + leading_space = True + spaces = False + breaks = True + start = end = 0 + while end <= len(text): + ch = None + if end < len(text): + ch = text[end] + if breaks: + if ch is None or ch not in '\n\x85\u2028\u2029': + if not leading_space and ch is not None and ch != ' ' \ + and text[start] == '\n': + self.write_line_break() + leading_space = (ch == ' ') + for br in text[start:end]: + if br == '\n': + self.write_line_break() + else: + self.write_line_break(br) + if ch is not None: + self.write_indent() + start = end + elif spaces: + if ch != ' ': + if start+1 == end and self.column > self.best_width: + self.write_indent() + else: + data = text[start:end] + self.column += len(data) + if self.encoding: + data = data.encode(self.encoding) + self.stream.write(data) + start = end + else: + if ch is None or ch in ' \n\x85\u2028\u2029': + data = text[start:end] + self.column += len(data) + if self.encoding: + data = data.encode(self.encoding) + self.stream.write(data) + if ch is None: + self.write_line_break() + start = end + if ch is not None: + breaks = (ch in '\n\x85\u2028\u2029') + spaces = (ch == ' ') + end += 1 + + def write_literal(self, text): + hints = self.determine_block_hints(text) + self.write_indicator('|'+hints, True) + if hints[-1:] == '+': + self.open_ended = True + self.write_line_break() + breaks = True + start = end = 0 + while end <= len(text): + ch = None + if end < len(text): + ch = text[end] + if breaks: + if ch is None or ch not in '\n\x85\u2028\u2029': + for br in text[start:end]: + if br == '\n': + self.write_line_break() + else: + self.write_line_break(br) + if ch is not None: + self.write_indent() + start = end + else: + if ch is None or ch in '\n\x85\u2028\u2029': + data = text[start:end] + if self.encoding: + data = data.encode(self.encoding) + self.stream.write(data) + if ch is None: + self.write_line_break() + start = end + if ch is not None: + breaks = (ch in '\n\x85\u2028\u2029') + end += 1 + + def write_plain(self, text, split=True): + if self.root_context: + self.open_ended = True + if not text: + return + if not self.whitespace: + data = ' ' + self.column += len(data) + if self.encoding: + data = data.encode(self.encoding) + self.stream.write(data) + self.whitespace = False + self.indention = False + spaces = False + breaks = False + start = end = 0 + while end <= len(text): + ch = None + if end < len(text): + ch = text[end] + if spaces: + if ch != ' ': + if start+1 == end and self.column > self.best_width and split: + self.write_indent() + self.whitespace = False + self.indention = False + else: + data = text[start:end] + self.column += len(data) + if self.encoding: + data = data.encode(self.encoding) + self.stream.write(data) + start = end + elif breaks: + if ch not in '\n\x85\u2028\u2029': + if text[start] == '\n': + self.write_line_break() + for br in text[start:end]: + if br == '\n': + self.write_line_break() + else: + self.write_line_break(br) + self.write_indent() + self.whitespace = False + self.indention = False + start = end + else: + if ch is None or ch in ' \n\x85\u2028\u2029': + data = text[start:end] + self.column += len(data) + if self.encoding: + data = data.encode(self.encoding) + self.stream.write(data) + start = end + if ch is not None: + spaces = (ch == ' ') + breaks = (ch in '\n\x85\u2028\u2029') + end += 1 diff --git a/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/yaml/events.py b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/yaml/events.py new file mode 100644 index 0000000000000000000000000000000000000000..f79ad389cb6c9517e391dcd25534866bc9ccd36a --- /dev/null +++ b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/yaml/events.py @@ -0,0 +1,86 @@ + +# Abstract classes. + +class Event(object): + def __init__(self, start_mark=None, end_mark=None): + self.start_mark = start_mark + self.end_mark = end_mark + def __repr__(self): + attributes = [key for key in ['anchor', 'tag', 'implicit', 'value'] + if hasattr(self, key)] + arguments = ', '.join(['%s=%r' % (key, getattr(self, key)) + for key in attributes]) + return '%s(%s)' % (self.__class__.__name__, arguments) + +class NodeEvent(Event): + def __init__(self, anchor, start_mark=None, end_mark=None): + self.anchor = anchor + self.start_mark = start_mark + self.end_mark = end_mark + +class CollectionStartEvent(NodeEvent): + def __init__(self, anchor, tag, implicit, start_mark=None, end_mark=None, + flow_style=None): + self.anchor = anchor + self.tag = tag + self.implicit = implicit + self.start_mark = start_mark + self.end_mark = end_mark + self.flow_style = flow_style + +class CollectionEndEvent(Event): + pass + +# Implementations. + +class StreamStartEvent(Event): + def __init__(self, start_mark=None, end_mark=None, encoding=None): + self.start_mark = start_mark + self.end_mark = end_mark + self.encoding = encoding + +class StreamEndEvent(Event): + pass + +class DocumentStartEvent(Event): + def __init__(self, start_mark=None, end_mark=None, + explicit=None, version=None, tags=None): + self.start_mark = start_mark + self.end_mark = end_mark + self.explicit = explicit + self.version = version + self.tags = tags + +class DocumentEndEvent(Event): + def __init__(self, start_mark=None, end_mark=None, + explicit=None): + self.start_mark = start_mark + self.end_mark = end_mark + self.explicit = explicit + +class AliasEvent(NodeEvent): + pass + +class ScalarEvent(NodeEvent): + def __init__(self, anchor, tag, implicit, value, + start_mark=None, end_mark=None, style=None): + self.anchor = anchor + self.tag = tag + self.implicit = implicit + self.value = value + self.start_mark = start_mark + self.end_mark = end_mark + self.style = style + +class SequenceStartEvent(CollectionStartEvent): + pass + +class SequenceEndEvent(CollectionEndEvent): + pass + +class MappingStartEvent(CollectionStartEvent): + pass + +class MappingEndEvent(CollectionEndEvent): + pass + diff --git a/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/yaml/loader.py b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/yaml/loader.py new file mode 100644 index 0000000000000000000000000000000000000000..e90c11224c38e559cdf0cb205f0692ebd4fb8681 --- /dev/null +++ b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/yaml/loader.py @@ -0,0 +1,63 @@ + +__all__ = ['BaseLoader', 'FullLoader', 'SafeLoader', 'Loader', 'UnsafeLoader'] + +from .reader import * +from .scanner import * +from .parser import * +from .composer import * +from .constructor import * +from .resolver import * + +class BaseLoader(Reader, Scanner, Parser, Composer, BaseConstructor, BaseResolver): + + def __init__(self, stream): + Reader.__init__(self, stream) + Scanner.__init__(self) + Parser.__init__(self) + Composer.__init__(self) + BaseConstructor.__init__(self) + BaseResolver.__init__(self) + +class FullLoader(Reader, Scanner, Parser, Composer, FullConstructor, Resolver): + + def __init__(self, stream): + Reader.__init__(self, stream) + Scanner.__init__(self) + Parser.__init__(self) + Composer.__init__(self) + FullConstructor.__init__(self) + Resolver.__init__(self) + +class SafeLoader(Reader, Scanner, Parser, Composer, SafeConstructor, Resolver): + + def __init__(self, stream): + Reader.__init__(self, stream) + Scanner.__init__(self) + Parser.__init__(self) + Composer.__init__(self) + SafeConstructor.__init__(self) + Resolver.__init__(self) + +class Loader(Reader, Scanner, Parser, Composer, Constructor, Resolver): + + def __init__(self, stream): + Reader.__init__(self, stream) + Scanner.__init__(self) + Parser.__init__(self) + Composer.__init__(self) + Constructor.__init__(self) + Resolver.__init__(self) + +# UnsafeLoader is the same as Loader (which is and was always unsafe on +# untrusted input). Use of either Loader or UnsafeLoader should be rare, since +# FullLoad should be able to load almost all YAML safely. Loader is left intact +# to ensure backwards compatibility. +class UnsafeLoader(Reader, Scanner, Parser, Composer, Constructor, Resolver): + + def __init__(self, stream): + Reader.__init__(self, stream) + Scanner.__init__(self) + Parser.__init__(self) + Composer.__init__(self) + Constructor.__init__(self) + Resolver.__init__(self) diff --git a/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/yaml/nodes.py b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/yaml/nodes.py new file mode 100644 index 0000000000000000000000000000000000000000..c4f070c41e1fb1bc01af27d69329e92dded38908 --- /dev/null +++ b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/yaml/nodes.py @@ -0,0 +1,49 @@ + +class Node(object): + def __init__(self, tag, value, start_mark, end_mark): + self.tag = tag + self.value = value + self.start_mark = start_mark + self.end_mark = end_mark + def __repr__(self): + value = self.value + #if isinstance(value, list): + # if len(value) == 0: + # value = '' + # elif len(value) == 1: + # value = '<1 item>' + # else: + # value = '<%d items>' % len(value) + #else: + # if len(value) > 75: + # value = repr(value[:70]+u' ... ') + # else: + # value = repr(value) + value = repr(value) + return '%s(tag=%r, value=%s)' % (self.__class__.__name__, self.tag, value) + +class ScalarNode(Node): + id = 'scalar' + def __init__(self, tag, value, + start_mark=None, end_mark=None, style=None): + self.tag = tag + self.value = value + self.start_mark = start_mark + self.end_mark = end_mark + self.style = style + +class CollectionNode(Node): + def __init__(self, tag, value, + start_mark=None, end_mark=None, flow_style=None): + self.tag = tag + self.value = value + self.start_mark = start_mark + self.end_mark = end_mark + self.flow_style = flow_style + +class SequenceNode(CollectionNode): + id = 'sequence' + +class MappingNode(CollectionNode): + id = 'mapping' + diff --git a/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/yaml/reader.py b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/yaml/reader.py new file mode 100644 index 0000000000000000000000000000000000000000..774b0219b5932a0ee1c27e637371de5ba8d9cb16 --- /dev/null +++ b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/yaml/reader.py @@ -0,0 +1,185 @@ +# This module contains abstractions for the input stream. You don't have to +# looks further, there are no pretty code. +# +# We define two classes here. +# +# Mark(source, line, column) +# It's just a record and its only use is producing nice error messages. +# Parser does not use it for any other purposes. +# +# Reader(source, data) +# Reader determines the encoding of `data` and converts it to unicode. +# Reader provides the following methods and attributes: +# reader.peek(length=1) - return the next `length` characters +# reader.forward(length=1) - move the current position to `length` characters. +# reader.index - the number of the current character. +# reader.line, stream.column - the line and the column of the current character. + +__all__ = ['Reader', 'ReaderError'] + +from .error import YAMLError, Mark + +import codecs, re + +class ReaderError(YAMLError): + + def __init__(self, name, position, character, encoding, reason): + self.name = name + self.character = character + self.position = position + self.encoding = encoding + self.reason = reason + + def __str__(self): + if isinstance(self.character, bytes): + return "'%s' codec can't decode byte #x%02x: %s\n" \ + " in \"%s\", position %d" \ + % (self.encoding, ord(self.character), self.reason, + self.name, self.position) + else: + return "unacceptable character #x%04x: %s\n" \ + " in \"%s\", position %d" \ + % (self.character, self.reason, + self.name, self.position) + +class Reader(object): + # Reader: + # - determines the data encoding and converts it to a unicode string, + # - checks if characters are in allowed range, + # - adds '\0' to the end. + + # Reader accepts + # - a `bytes` object, + # - a `str` object, + # - a file-like object with its `read` method returning `str`, + # - a file-like object with its `read` method returning `unicode`. + + # Yeah, it's ugly and slow. + + def __init__(self, stream): + self.name = None + self.stream = None + self.stream_pointer = 0 + self.eof = True + self.buffer = '' + self.pointer = 0 + self.raw_buffer = None + self.raw_decode = None + self.encoding = None + self.index = 0 + self.line = 0 + self.column = 0 + if isinstance(stream, str): + self.name = "" + self.check_printable(stream) + self.buffer = stream+'\0' + elif isinstance(stream, bytes): + self.name = "" + self.raw_buffer = stream + self.determine_encoding() + else: + self.stream = stream + self.name = getattr(stream, 'name', "") + self.eof = False + self.raw_buffer = None + self.determine_encoding() + + def peek(self, index=0): + try: + return self.buffer[self.pointer+index] + except IndexError: + self.update(index+1) + return self.buffer[self.pointer+index] + + def prefix(self, length=1): + if self.pointer+length >= len(self.buffer): + self.update(length) + return self.buffer[self.pointer:self.pointer+length] + + def forward(self, length=1): + if self.pointer+length+1 >= len(self.buffer): + self.update(length+1) + while length: + ch = self.buffer[self.pointer] + self.pointer += 1 + self.index += 1 + if ch in '\n\x85\u2028\u2029' \ + or (ch == '\r' and self.buffer[self.pointer] != '\n'): + self.line += 1 + self.column = 0 + elif ch != '\uFEFF': + self.column += 1 + length -= 1 + + def get_mark(self): + if self.stream is None: + return Mark(self.name, self.index, self.line, self.column, + self.buffer, self.pointer) + else: + return Mark(self.name, self.index, self.line, self.column, + None, None) + + def determine_encoding(self): + while not self.eof and (self.raw_buffer is None or len(self.raw_buffer) < 2): + self.update_raw() + if isinstance(self.raw_buffer, bytes): + if self.raw_buffer.startswith(codecs.BOM_UTF16_LE): + self.raw_decode = codecs.utf_16_le_decode + self.encoding = 'utf-16-le' + elif self.raw_buffer.startswith(codecs.BOM_UTF16_BE): + self.raw_decode = codecs.utf_16_be_decode + self.encoding = 'utf-16-be' + else: + self.raw_decode = codecs.utf_8_decode + self.encoding = 'utf-8' + self.update(1) + + NON_PRINTABLE = re.compile('[^\x09\x0A\x0D\x20-\x7E\x85\xA0-\uD7FF\uE000-\uFFFD\U00010000-\U0010ffff]') + def check_printable(self, data): + match = self.NON_PRINTABLE.search(data) + if match: + character = match.group() + position = self.index+(len(self.buffer)-self.pointer)+match.start() + raise ReaderError(self.name, position, ord(character), + 'unicode', "special characters are not allowed") + + def update(self, length): + if self.raw_buffer is None: + return + self.buffer = self.buffer[self.pointer:] + self.pointer = 0 + while len(self.buffer) < length: + if not self.eof: + self.update_raw() + if self.raw_decode is not None: + try: + data, converted = self.raw_decode(self.raw_buffer, + 'strict', self.eof) + except UnicodeDecodeError as exc: + character = self.raw_buffer[exc.start] + if self.stream is not None: + position = self.stream_pointer-len(self.raw_buffer)+exc.start + else: + position = exc.start + raise ReaderError(self.name, position, character, + exc.encoding, exc.reason) + else: + data = self.raw_buffer + converted = len(data) + self.check_printable(data) + self.buffer += data + self.raw_buffer = self.raw_buffer[converted:] + if self.eof: + self.buffer += '\0' + self.raw_buffer = None + break + + def update_raw(self, size=4096): + data = self.stream.read(size) + if self.raw_buffer is None: + self.raw_buffer = data + else: + self.raw_buffer += data + self.stream_pointer += len(data) + if not data: + self.eof = True diff --git a/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/yaml/resolver.py b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/yaml/resolver.py new file mode 100644 index 0000000000000000000000000000000000000000..3522bdaaf6358110b608f4e6503b9d314c82d887 --- /dev/null +++ b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/yaml/resolver.py @@ -0,0 +1,227 @@ + +__all__ = ['BaseResolver', 'Resolver'] + +from .error import * +from .nodes import * + +import re + +class ResolverError(YAMLError): + pass + +class BaseResolver: + + DEFAULT_SCALAR_TAG = 'tag:yaml.org,2002:str' + DEFAULT_SEQUENCE_TAG = 'tag:yaml.org,2002:seq' + DEFAULT_MAPPING_TAG = 'tag:yaml.org,2002:map' + + yaml_implicit_resolvers = {} + yaml_path_resolvers = {} + + def __init__(self): + self.resolver_exact_paths = [] + self.resolver_prefix_paths = [] + + @classmethod + def add_implicit_resolver(cls, tag, regexp, first): + if not 'yaml_implicit_resolvers' in cls.__dict__: + implicit_resolvers = {} + for key in cls.yaml_implicit_resolvers: + implicit_resolvers[key] = cls.yaml_implicit_resolvers[key][:] + cls.yaml_implicit_resolvers = implicit_resolvers + if first is None: + first = [None] + for ch in first: + cls.yaml_implicit_resolvers.setdefault(ch, []).append((tag, regexp)) + + @classmethod + def add_path_resolver(cls, tag, path, kind=None): + # Note: `add_path_resolver` is experimental. The API could be changed. + # `new_path` is a pattern that is matched against the path from the + # root to the node that is being considered. `node_path` elements are + # tuples `(node_check, index_check)`. `node_check` is a node class: + # `ScalarNode`, `SequenceNode`, `MappingNode` or `None`. `None` + # matches any kind of a node. `index_check` could be `None`, a boolean + # value, a string value, or a number. `None` and `False` match against + # any _value_ of sequence and mapping nodes. `True` matches against + # any _key_ of a mapping node. A string `index_check` matches against + # a mapping value that corresponds to a scalar key which content is + # equal to the `index_check` value. An integer `index_check` matches + # against a sequence value with the index equal to `index_check`. + if not 'yaml_path_resolvers' in cls.__dict__: + cls.yaml_path_resolvers = cls.yaml_path_resolvers.copy() + new_path = [] + for element in path: + if isinstance(element, (list, tuple)): + if len(element) == 2: + node_check, index_check = element + elif len(element) == 1: + node_check = element[0] + index_check = True + else: + raise ResolverError("Invalid path element: %s" % element) + else: + node_check = None + index_check = element + if node_check is str: + node_check = ScalarNode + elif node_check is list: + node_check = SequenceNode + elif node_check is dict: + node_check = MappingNode + elif node_check not in [ScalarNode, SequenceNode, MappingNode] \ + and not isinstance(node_check, str) \ + and node_check is not None: + raise ResolverError("Invalid node checker: %s" % node_check) + if not isinstance(index_check, (str, int)) \ + and index_check is not None: + raise ResolverError("Invalid index checker: %s" % index_check) + new_path.append((node_check, index_check)) + if kind is str: + kind = ScalarNode + elif kind is list: + kind = SequenceNode + elif kind is dict: + kind = MappingNode + elif kind not in [ScalarNode, SequenceNode, MappingNode] \ + and kind is not None: + raise ResolverError("Invalid node kind: %s" % kind) + cls.yaml_path_resolvers[tuple(new_path), kind] = tag + + def descend_resolver(self, current_node, current_index): + if not self.yaml_path_resolvers: + return + exact_paths = {} + prefix_paths = [] + if current_node: + depth = len(self.resolver_prefix_paths) + for path, kind in self.resolver_prefix_paths[-1]: + if self.check_resolver_prefix(depth, path, kind, + current_node, current_index): + if len(path) > depth: + prefix_paths.append((path, kind)) + else: + exact_paths[kind] = self.yaml_path_resolvers[path, kind] + else: + for path, kind in self.yaml_path_resolvers: + if not path: + exact_paths[kind] = self.yaml_path_resolvers[path, kind] + else: + prefix_paths.append((path, kind)) + self.resolver_exact_paths.append(exact_paths) + self.resolver_prefix_paths.append(prefix_paths) + + def ascend_resolver(self): + if not self.yaml_path_resolvers: + return + self.resolver_exact_paths.pop() + self.resolver_prefix_paths.pop() + + def check_resolver_prefix(self, depth, path, kind, + current_node, current_index): + node_check, index_check = path[depth-1] + if isinstance(node_check, str): + if current_node.tag != node_check: + return + elif node_check is not None: + if not isinstance(current_node, node_check): + return + if index_check is True and current_index is not None: + return + if (index_check is False or index_check is None) \ + and current_index is None: + return + if isinstance(index_check, str): + if not (isinstance(current_index, ScalarNode) + and index_check == current_index.value): + return + elif isinstance(index_check, int) and not isinstance(index_check, bool): + if index_check != current_index: + return + return True + + def resolve(self, kind, value, implicit): + if kind is ScalarNode and implicit[0]: + if value == '': + resolvers = self.yaml_implicit_resolvers.get('', []) + else: + resolvers = self.yaml_implicit_resolvers.get(value[0], []) + wildcard_resolvers = self.yaml_implicit_resolvers.get(None, []) + for tag, regexp in resolvers + wildcard_resolvers: + if regexp.match(value): + return tag + implicit = implicit[1] + if self.yaml_path_resolvers: + exact_paths = self.resolver_exact_paths[-1] + if kind in exact_paths: + return exact_paths[kind] + if None in exact_paths: + return exact_paths[None] + if kind is ScalarNode: + return self.DEFAULT_SCALAR_TAG + elif kind is SequenceNode: + return self.DEFAULT_SEQUENCE_TAG + elif kind is MappingNode: + return self.DEFAULT_MAPPING_TAG + +class Resolver(BaseResolver): + pass + +Resolver.add_implicit_resolver( + 'tag:yaml.org,2002:bool', + re.compile(r'''^(?:yes|Yes|YES|no|No|NO + |true|True|TRUE|false|False|FALSE + |on|On|ON|off|Off|OFF)$''', re.X), + list('yYnNtTfFoO')) + +Resolver.add_implicit_resolver( + 'tag:yaml.org,2002:float', + re.compile(r'''^(?:[-+]?(?:[0-9][0-9_]*)\.[0-9_]*(?:[eE][-+][0-9]+)? + |\.[0-9][0-9_]*(?:[eE][-+][0-9]+)? + |[-+]?[0-9][0-9_]*(?::[0-5]?[0-9])+\.[0-9_]* + |[-+]?\.(?:inf|Inf|INF) + |\.(?:nan|NaN|NAN))$''', re.X), + list('-+0123456789.')) + +Resolver.add_implicit_resolver( + 'tag:yaml.org,2002:int', + re.compile(r'''^(?:[-+]?0b[0-1_]+ + |[-+]?0[0-7_]+ + |[-+]?(?:0|[1-9][0-9_]*) + |[-+]?0x[0-9a-fA-F_]+ + |[-+]?[1-9][0-9_]*(?::[0-5]?[0-9])+)$''', re.X), + list('-+0123456789')) + +Resolver.add_implicit_resolver( + 'tag:yaml.org,2002:merge', + re.compile(r'^(?:<<)$'), + ['<']) + +Resolver.add_implicit_resolver( + 'tag:yaml.org,2002:null', + re.compile(r'''^(?: ~ + |null|Null|NULL + | )$''', re.X), + ['~', 'n', 'N', '']) + +Resolver.add_implicit_resolver( + 'tag:yaml.org,2002:timestamp', + re.compile(r'''^(?:[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] + |[0-9][0-9][0-9][0-9] -[0-9][0-9]? -[0-9][0-9]? + (?:[Tt]|[ \t]+)[0-9][0-9]? + :[0-9][0-9] :[0-9][0-9] (?:\.[0-9]*)? + (?:[ \t]*(?:Z|[-+][0-9][0-9]?(?::[0-9][0-9])?))?)$''', re.X), + list('0123456789')) + +Resolver.add_implicit_resolver( + 'tag:yaml.org,2002:value', + re.compile(r'^(?:=)$'), + ['=']) + +# The following resolver is only for documentation purposes. It cannot work +# because plain scalars cannot start with '!', '&', or '*'. +Resolver.add_implicit_resolver( + 'tag:yaml.org,2002:yaml', + re.compile(r'^(?:!|&|\*)$'), + list('!&*')) + diff --git a/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/yaml/scanner.py b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/yaml/scanner.py new file mode 100644 index 0000000000000000000000000000000000000000..de925b07f1eaec33c9c305a8a69f9eb7ac5983c5 --- /dev/null +++ b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/yaml/scanner.py @@ -0,0 +1,1435 @@ + +# Scanner produces tokens of the following types: +# STREAM-START +# STREAM-END +# DIRECTIVE(name, value) +# DOCUMENT-START +# DOCUMENT-END +# BLOCK-SEQUENCE-START +# BLOCK-MAPPING-START +# BLOCK-END +# FLOW-SEQUENCE-START +# FLOW-MAPPING-START +# FLOW-SEQUENCE-END +# FLOW-MAPPING-END +# BLOCK-ENTRY +# FLOW-ENTRY +# KEY +# VALUE +# ALIAS(value) +# ANCHOR(value) +# TAG(value) +# SCALAR(value, plain, style) +# +# Read comments in the Scanner code for more details. +# + +__all__ = ['Scanner', 'ScannerError'] + +from .error import MarkedYAMLError +from .tokens import * + +class ScannerError(MarkedYAMLError): + pass + +class SimpleKey: + # See below simple keys treatment. + + def __init__(self, token_number, required, index, line, column, mark): + self.token_number = token_number + self.required = required + self.index = index + self.line = line + self.column = column + self.mark = mark + +class Scanner: + + def __init__(self): + """Initialize the scanner.""" + # It is assumed that Scanner and Reader will have a common descendant. + # Reader do the dirty work of checking for BOM and converting the + # input data to Unicode. It also adds NUL to the end. + # + # Reader supports the following methods + # self.peek(i=0) # peek the next i-th character + # self.prefix(l=1) # peek the next l characters + # self.forward(l=1) # read the next l characters and move the pointer. + + # Had we reached the end of the stream? + self.done = False + + # The number of unclosed '{' and '['. `flow_level == 0` means block + # context. + self.flow_level = 0 + + # List of processed tokens that are not yet emitted. + self.tokens = [] + + # Add the STREAM-START token. + self.fetch_stream_start() + + # Number of tokens that were emitted through the `get_token` method. + self.tokens_taken = 0 + + # The current indentation level. + self.indent = -1 + + # Past indentation levels. + self.indents = [] + + # Variables related to simple keys treatment. + + # A simple key is a key that is not denoted by the '?' indicator. + # Example of simple keys: + # --- + # block simple key: value + # ? not a simple key: + # : { flow simple key: value } + # We emit the KEY token before all keys, so when we find a potential + # simple key, we try to locate the corresponding ':' indicator. + # Simple keys should be limited to a single line and 1024 characters. + + # Can a simple key start at the current position? A simple key may + # start: + # - at the beginning of the line, not counting indentation spaces + # (in block context), + # - after '{', '[', ',' (in the flow context), + # - after '?', ':', '-' (in the block context). + # In the block context, this flag also signifies if a block collection + # may start at the current position. + self.allow_simple_key = True + + # Keep track of possible simple keys. This is a dictionary. The key + # is `flow_level`; there can be no more that one possible simple key + # for each level. The value is a SimpleKey record: + # (token_number, required, index, line, column, mark) + # A simple key may start with ALIAS, ANCHOR, TAG, SCALAR(flow), + # '[', or '{' tokens. + self.possible_simple_keys = {} + + # Public methods. + + def check_token(self, *choices): + # Check if the next token is one of the given types. + while self.need_more_tokens(): + self.fetch_more_tokens() + if self.tokens: + if not choices: + return True + for choice in choices: + if isinstance(self.tokens[0], choice): + return True + return False + + def peek_token(self): + # Return the next token, but do not delete if from the queue. + # Return None if no more tokens. + while self.need_more_tokens(): + self.fetch_more_tokens() + if self.tokens: + return self.tokens[0] + else: + return None + + def get_token(self): + # Return the next token. + while self.need_more_tokens(): + self.fetch_more_tokens() + if self.tokens: + self.tokens_taken += 1 + return self.tokens.pop(0) + + # Private methods. + + def need_more_tokens(self): + if self.done: + return False + if not self.tokens: + return True + # The current token may be a potential simple key, so we + # need to look further. + self.stale_possible_simple_keys() + if self.next_possible_simple_key() == self.tokens_taken: + return True + + def fetch_more_tokens(self): + + # Eat whitespaces and comments until we reach the next token. + self.scan_to_next_token() + + # Remove obsolete possible simple keys. + self.stale_possible_simple_keys() + + # Compare the current indentation and column. It may add some tokens + # and decrease the current indentation level. + self.unwind_indent(self.column) + + # Peek the next character. + ch = self.peek() + + # Is it the end of stream? + if ch == '\0': + return self.fetch_stream_end() + + # Is it a directive? + if ch == '%' and self.check_directive(): + return self.fetch_directive() + + # Is it the document start? + if ch == '-' and self.check_document_start(): + return self.fetch_document_start() + + # Is it the document end? + if ch == '.' and self.check_document_end(): + return self.fetch_document_end() + + # TODO: support for BOM within a stream. + #if ch == '\uFEFF': + # return self.fetch_bom() <-- issue BOMToken + + # Note: the order of the following checks is NOT significant. + + # Is it the flow sequence start indicator? + if ch == '[': + return self.fetch_flow_sequence_start() + + # Is it the flow mapping start indicator? + if ch == '{': + return self.fetch_flow_mapping_start() + + # Is it the flow sequence end indicator? + if ch == ']': + return self.fetch_flow_sequence_end() + + # Is it the flow mapping end indicator? + if ch == '}': + return self.fetch_flow_mapping_end() + + # Is it the flow entry indicator? + if ch == ',': + return self.fetch_flow_entry() + + # Is it the block entry indicator? + if ch == '-' and self.check_block_entry(): + return self.fetch_block_entry() + + # Is it the key indicator? + if ch == '?' and self.check_key(): + return self.fetch_key() + + # Is it the value indicator? + if ch == ':' and self.check_value(): + return self.fetch_value() + + # Is it an alias? + if ch == '*': + return self.fetch_alias() + + # Is it an anchor? + if ch == '&': + return self.fetch_anchor() + + # Is it a tag? + if ch == '!': + return self.fetch_tag() + + # Is it a literal scalar? + if ch == '|' and not self.flow_level: + return self.fetch_literal() + + # Is it a folded scalar? + if ch == '>' and not self.flow_level: + return self.fetch_folded() + + # Is it a single quoted scalar? + if ch == '\'': + return self.fetch_single() + + # Is it a double quoted scalar? + if ch == '\"': + return self.fetch_double() + + # It must be a plain scalar then. + if self.check_plain(): + return self.fetch_plain() + + # No? It's an error. Let's produce a nice error message. + raise ScannerError("while scanning for the next token", None, + "found character %r that cannot start any token" % ch, + self.get_mark()) + + # Simple keys treatment. + + def next_possible_simple_key(self): + # Return the number of the nearest possible simple key. Actually we + # don't need to loop through the whole dictionary. We may replace it + # with the following code: + # if not self.possible_simple_keys: + # return None + # return self.possible_simple_keys[ + # min(self.possible_simple_keys.keys())].token_number + min_token_number = None + for level in self.possible_simple_keys: + key = self.possible_simple_keys[level] + if min_token_number is None or key.token_number < min_token_number: + min_token_number = key.token_number + return min_token_number + + def stale_possible_simple_keys(self): + # Remove entries that are no longer possible simple keys. According to + # the YAML specification, simple keys + # - should be limited to a single line, + # - should be no longer than 1024 characters. + # Disabling this procedure will allow simple keys of any length and + # height (may cause problems if indentation is broken though). + for level in list(self.possible_simple_keys): + key = self.possible_simple_keys[level] + if key.line != self.line \ + or self.index-key.index > 1024: + if key.required: + raise ScannerError("while scanning a simple key", key.mark, + "could not find expected ':'", self.get_mark()) + del self.possible_simple_keys[level] + + def save_possible_simple_key(self): + # The next token may start a simple key. We check if it's possible + # and save its position. This function is called for + # ALIAS, ANCHOR, TAG, SCALAR(flow), '[', and '{'. + + # Check if a simple key is required at the current position. + required = not self.flow_level and self.indent == self.column + + # The next token might be a simple key. Let's save it's number and + # position. + if self.allow_simple_key: + self.remove_possible_simple_key() + token_number = self.tokens_taken+len(self.tokens) + key = SimpleKey(token_number, required, + self.index, self.line, self.column, self.get_mark()) + self.possible_simple_keys[self.flow_level] = key + + def remove_possible_simple_key(self): + # Remove the saved possible key position at the current flow level. + if self.flow_level in self.possible_simple_keys: + key = self.possible_simple_keys[self.flow_level] + + if key.required: + raise ScannerError("while scanning a simple key", key.mark, + "could not find expected ':'", self.get_mark()) + + del self.possible_simple_keys[self.flow_level] + + # Indentation functions. + + def unwind_indent(self, column): + + ## In flow context, tokens should respect indentation. + ## Actually the condition should be `self.indent >= column` according to + ## the spec. But this condition will prohibit intuitively correct + ## constructions such as + ## key : { + ## } + #if self.flow_level and self.indent > column: + # raise ScannerError(None, None, + # "invalid indentation or unclosed '[' or '{'", + # self.get_mark()) + + # In the flow context, indentation is ignored. We make the scanner less + # restrictive then specification requires. + if self.flow_level: + return + + # In block context, we may need to issue the BLOCK-END tokens. + while self.indent > column: + mark = self.get_mark() + self.indent = self.indents.pop() + self.tokens.append(BlockEndToken(mark, mark)) + + def add_indent(self, column): + # Check if we need to increase indentation. + if self.indent < column: + self.indents.append(self.indent) + self.indent = column + return True + return False + + # Fetchers. + + def fetch_stream_start(self): + # We always add STREAM-START as the first token and STREAM-END as the + # last token. + + # Read the token. + mark = self.get_mark() + + # Add STREAM-START. + self.tokens.append(StreamStartToken(mark, mark, + encoding=self.encoding)) + + + def fetch_stream_end(self): + + # Set the current indentation to -1. + self.unwind_indent(-1) + + # Reset simple keys. + self.remove_possible_simple_key() + self.allow_simple_key = False + self.possible_simple_keys = {} + + # Read the token. + mark = self.get_mark() + + # Add STREAM-END. + self.tokens.append(StreamEndToken(mark, mark)) + + # The steam is finished. + self.done = True + + def fetch_directive(self): + + # Set the current indentation to -1. + self.unwind_indent(-1) + + # Reset simple keys. + self.remove_possible_simple_key() + self.allow_simple_key = False + + # Scan and add DIRECTIVE. + self.tokens.append(self.scan_directive()) + + def fetch_document_start(self): + self.fetch_document_indicator(DocumentStartToken) + + def fetch_document_end(self): + self.fetch_document_indicator(DocumentEndToken) + + def fetch_document_indicator(self, TokenClass): + + # Set the current indentation to -1. + self.unwind_indent(-1) + + # Reset simple keys. Note that there could not be a block collection + # after '---'. + self.remove_possible_simple_key() + self.allow_simple_key = False + + # Add DOCUMENT-START or DOCUMENT-END. + start_mark = self.get_mark() + self.forward(3) + end_mark = self.get_mark() + self.tokens.append(TokenClass(start_mark, end_mark)) + + def fetch_flow_sequence_start(self): + self.fetch_flow_collection_start(FlowSequenceStartToken) + + def fetch_flow_mapping_start(self): + self.fetch_flow_collection_start(FlowMappingStartToken) + + def fetch_flow_collection_start(self, TokenClass): + + # '[' and '{' may start a simple key. + self.save_possible_simple_key() + + # Increase the flow level. + self.flow_level += 1 + + # Simple keys are allowed after '[' and '{'. + self.allow_simple_key = True + + # Add FLOW-SEQUENCE-START or FLOW-MAPPING-START. + start_mark = self.get_mark() + self.forward() + end_mark = self.get_mark() + self.tokens.append(TokenClass(start_mark, end_mark)) + + def fetch_flow_sequence_end(self): + self.fetch_flow_collection_end(FlowSequenceEndToken) + + def fetch_flow_mapping_end(self): + self.fetch_flow_collection_end(FlowMappingEndToken) + + def fetch_flow_collection_end(self, TokenClass): + + # Reset possible simple key on the current level. + self.remove_possible_simple_key() + + # Decrease the flow level. + self.flow_level -= 1 + + # No simple keys after ']' or '}'. + self.allow_simple_key = False + + # Add FLOW-SEQUENCE-END or FLOW-MAPPING-END. + start_mark = self.get_mark() + self.forward() + end_mark = self.get_mark() + self.tokens.append(TokenClass(start_mark, end_mark)) + + def fetch_flow_entry(self): + + # Simple keys are allowed after ','. + self.allow_simple_key = True + + # Reset possible simple key on the current level. + self.remove_possible_simple_key() + + # Add FLOW-ENTRY. + start_mark = self.get_mark() + self.forward() + end_mark = self.get_mark() + self.tokens.append(FlowEntryToken(start_mark, end_mark)) + + def fetch_block_entry(self): + + # Block context needs additional checks. + if not self.flow_level: + + # Are we allowed to start a new entry? + if not self.allow_simple_key: + raise ScannerError(None, None, + "sequence entries are not allowed here", + self.get_mark()) + + # We may need to add BLOCK-SEQUENCE-START. + if self.add_indent(self.column): + mark = self.get_mark() + self.tokens.append(BlockSequenceStartToken(mark, mark)) + + # It's an error for the block entry to occur in the flow context, + # but we let the parser detect this. + else: + pass + + # Simple keys are allowed after '-'. + self.allow_simple_key = True + + # Reset possible simple key on the current level. + self.remove_possible_simple_key() + + # Add BLOCK-ENTRY. + start_mark = self.get_mark() + self.forward() + end_mark = self.get_mark() + self.tokens.append(BlockEntryToken(start_mark, end_mark)) + + def fetch_key(self): + + # Block context needs additional checks. + if not self.flow_level: + + # Are we allowed to start a key (not necessary a simple)? + if not self.allow_simple_key: + raise ScannerError(None, None, + "mapping keys are not allowed here", + self.get_mark()) + + # We may need to add BLOCK-MAPPING-START. + if self.add_indent(self.column): + mark = self.get_mark() + self.tokens.append(BlockMappingStartToken(mark, mark)) + + # Simple keys are allowed after '?' in the block context. + self.allow_simple_key = not self.flow_level + + # Reset possible simple key on the current level. + self.remove_possible_simple_key() + + # Add KEY. + start_mark = self.get_mark() + self.forward() + end_mark = self.get_mark() + self.tokens.append(KeyToken(start_mark, end_mark)) + + def fetch_value(self): + + # Do we determine a simple key? + if self.flow_level in self.possible_simple_keys: + + # Add KEY. + key = self.possible_simple_keys[self.flow_level] + del self.possible_simple_keys[self.flow_level] + self.tokens.insert(key.token_number-self.tokens_taken, + KeyToken(key.mark, key.mark)) + + # If this key starts a new block mapping, we need to add + # BLOCK-MAPPING-START. + if not self.flow_level: + if self.add_indent(key.column): + self.tokens.insert(key.token_number-self.tokens_taken, + BlockMappingStartToken(key.mark, key.mark)) + + # There cannot be two simple keys one after another. + self.allow_simple_key = False + + # It must be a part of a complex key. + else: + + # Block context needs additional checks. + # (Do we really need them? They will be caught by the parser + # anyway.) + if not self.flow_level: + + # We are allowed to start a complex value if and only if + # we can start a simple key. + if not self.allow_simple_key: + raise ScannerError(None, None, + "mapping values are not allowed here", + self.get_mark()) + + # If this value starts a new block mapping, we need to add + # BLOCK-MAPPING-START. It will be detected as an error later by + # the parser. + if not self.flow_level: + if self.add_indent(self.column): + mark = self.get_mark() + self.tokens.append(BlockMappingStartToken(mark, mark)) + + # Simple keys are allowed after ':' in the block context. + self.allow_simple_key = not self.flow_level + + # Reset possible simple key on the current level. + self.remove_possible_simple_key() + + # Add VALUE. + start_mark = self.get_mark() + self.forward() + end_mark = self.get_mark() + self.tokens.append(ValueToken(start_mark, end_mark)) + + def fetch_alias(self): + + # ALIAS could be a simple key. + self.save_possible_simple_key() + + # No simple keys after ALIAS. + self.allow_simple_key = False + + # Scan and add ALIAS. + self.tokens.append(self.scan_anchor(AliasToken)) + + def fetch_anchor(self): + + # ANCHOR could start a simple key. + self.save_possible_simple_key() + + # No simple keys after ANCHOR. + self.allow_simple_key = False + + # Scan and add ANCHOR. + self.tokens.append(self.scan_anchor(AnchorToken)) + + def fetch_tag(self): + + # TAG could start a simple key. + self.save_possible_simple_key() + + # No simple keys after TAG. + self.allow_simple_key = False + + # Scan and add TAG. + self.tokens.append(self.scan_tag()) + + def fetch_literal(self): + self.fetch_block_scalar(style='|') + + def fetch_folded(self): + self.fetch_block_scalar(style='>') + + def fetch_block_scalar(self, style): + + # A simple key may follow a block scalar. + self.allow_simple_key = True + + # Reset possible simple key on the current level. + self.remove_possible_simple_key() + + # Scan and add SCALAR. + self.tokens.append(self.scan_block_scalar(style)) + + def fetch_single(self): + self.fetch_flow_scalar(style='\'') + + def fetch_double(self): + self.fetch_flow_scalar(style='"') + + def fetch_flow_scalar(self, style): + + # A flow scalar could be a simple key. + self.save_possible_simple_key() + + # No simple keys after flow scalars. + self.allow_simple_key = False + + # Scan and add SCALAR. + self.tokens.append(self.scan_flow_scalar(style)) + + def fetch_plain(self): + + # A plain scalar could be a simple key. + self.save_possible_simple_key() + + # No simple keys after plain scalars. But note that `scan_plain` will + # change this flag if the scan is finished at the beginning of the + # line. + self.allow_simple_key = False + + # Scan and add SCALAR. May change `allow_simple_key`. + self.tokens.append(self.scan_plain()) + + # Checkers. + + def check_directive(self): + + # DIRECTIVE: ^ '%' ... + # The '%' indicator is already checked. + if self.column == 0: + return True + + def check_document_start(self): + + # DOCUMENT-START: ^ '---' (' '|'\n') + if self.column == 0: + if self.prefix(3) == '---' \ + and self.peek(3) in '\0 \t\r\n\x85\u2028\u2029': + return True + + def check_document_end(self): + + # DOCUMENT-END: ^ '...' (' '|'\n') + if self.column == 0: + if self.prefix(3) == '...' \ + and self.peek(3) in '\0 \t\r\n\x85\u2028\u2029': + return True + + def check_block_entry(self): + + # BLOCK-ENTRY: '-' (' '|'\n') + return self.peek(1) in '\0 \t\r\n\x85\u2028\u2029' + + def check_key(self): + + # KEY(flow context): '?' + if self.flow_level: + return True + + # KEY(block context): '?' (' '|'\n') + else: + return self.peek(1) in '\0 \t\r\n\x85\u2028\u2029' + + def check_value(self): + + # VALUE(flow context): ':' + if self.flow_level: + return True + + # VALUE(block context): ':' (' '|'\n') + else: + return self.peek(1) in '\0 \t\r\n\x85\u2028\u2029' + + def check_plain(self): + + # A plain scalar may start with any non-space character except: + # '-', '?', ':', ',', '[', ']', '{', '}', + # '#', '&', '*', '!', '|', '>', '\'', '\"', + # '%', '@', '`'. + # + # It may also start with + # '-', '?', ':' + # if it is followed by a non-space character. + # + # Note that we limit the last rule to the block context (except the + # '-' character) because we want the flow context to be space + # independent. + ch = self.peek() + return ch not in '\0 \t\r\n\x85\u2028\u2029-?:,[]{}#&*!|>\'\"%@`' \ + or (self.peek(1) not in '\0 \t\r\n\x85\u2028\u2029' + and (ch == '-' or (not self.flow_level and ch in '?:'))) + + # Scanners. + + def scan_to_next_token(self): + # We ignore spaces, line breaks and comments. + # If we find a line break in the block context, we set the flag + # `allow_simple_key` on. + # The byte order mark is stripped if it's the first character in the + # stream. We do not yet support BOM inside the stream as the + # specification requires. Any such mark will be considered as a part + # of the document. + # + # TODO: We need to make tab handling rules more sane. A good rule is + # Tabs cannot precede tokens + # BLOCK-SEQUENCE-START, BLOCK-MAPPING-START, BLOCK-END, + # KEY(block), VALUE(block), BLOCK-ENTRY + # So the checking code is + # if : + # self.allow_simple_keys = False + # We also need to add the check for `allow_simple_keys == True` to + # `unwind_indent` before issuing BLOCK-END. + # Scanners for block, flow, and plain scalars need to be modified. + + if self.index == 0 and self.peek() == '\uFEFF': + self.forward() + found = False + while not found: + while self.peek() == ' ': + self.forward() + if self.peek() == '#': + while self.peek() not in '\0\r\n\x85\u2028\u2029': + self.forward() + if self.scan_line_break(): + if not self.flow_level: + self.allow_simple_key = True + else: + found = True + + def scan_directive(self): + # See the specification for details. + start_mark = self.get_mark() + self.forward() + name = self.scan_directive_name(start_mark) + value = None + if name == 'YAML': + value = self.scan_yaml_directive_value(start_mark) + end_mark = self.get_mark() + elif name == 'TAG': + value = self.scan_tag_directive_value(start_mark) + end_mark = self.get_mark() + else: + end_mark = self.get_mark() + while self.peek() not in '\0\r\n\x85\u2028\u2029': + self.forward() + self.scan_directive_ignored_line(start_mark) + return DirectiveToken(name, value, start_mark, end_mark) + + def scan_directive_name(self, start_mark): + # See the specification for details. + length = 0 + ch = self.peek(length) + while '0' <= ch <= '9' or 'A' <= ch <= 'Z' or 'a' <= ch <= 'z' \ + or ch in '-_': + length += 1 + ch = self.peek(length) + if not length: + raise ScannerError("while scanning a directive", start_mark, + "expected alphabetic or numeric character, but found %r" + % ch, self.get_mark()) + value = self.prefix(length) + self.forward(length) + ch = self.peek() + if ch not in '\0 \r\n\x85\u2028\u2029': + raise ScannerError("while scanning a directive", start_mark, + "expected alphabetic or numeric character, but found %r" + % ch, self.get_mark()) + return value + + def scan_yaml_directive_value(self, start_mark): + # See the specification for details. + while self.peek() == ' ': + self.forward() + major = self.scan_yaml_directive_number(start_mark) + if self.peek() != '.': + raise ScannerError("while scanning a directive", start_mark, + "expected a digit or '.', but found %r" % self.peek(), + self.get_mark()) + self.forward() + minor = self.scan_yaml_directive_number(start_mark) + if self.peek() not in '\0 \r\n\x85\u2028\u2029': + raise ScannerError("while scanning a directive", start_mark, + "expected a digit or ' ', but found %r" % self.peek(), + self.get_mark()) + return (major, minor) + + def scan_yaml_directive_number(self, start_mark): + # See the specification for details. + ch = self.peek() + if not ('0' <= ch <= '9'): + raise ScannerError("while scanning a directive", start_mark, + "expected a digit, but found %r" % ch, self.get_mark()) + length = 0 + while '0' <= self.peek(length) <= '9': + length += 1 + value = int(self.prefix(length)) + self.forward(length) + return value + + def scan_tag_directive_value(self, start_mark): + # See the specification for details. + while self.peek() == ' ': + self.forward() + handle = self.scan_tag_directive_handle(start_mark) + while self.peek() == ' ': + self.forward() + prefix = self.scan_tag_directive_prefix(start_mark) + return (handle, prefix) + + def scan_tag_directive_handle(self, start_mark): + # See the specification for details. + value = self.scan_tag_handle('directive', start_mark) + ch = self.peek() + if ch != ' ': + raise ScannerError("while scanning a directive", start_mark, + "expected ' ', but found %r" % ch, self.get_mark()) + return value + + def scan_tag_directive_prefix(self, start_mark): + # See the specification for details. + value = self.scan_tag_uri('directive', start_mark) + ch = self.peek() + if ch not in '\0 \r\n\x85\u2028\u2029': + raise ScannerError("while scanning a directive", start_mark, + "expected ' ', but found %r" % ch, self.get_mark()) + return value + + def scan_directive_ignored_line(self, start_mark): + # See the specification for details. + while self.peek() == ' ': + self.forward() + if self.peek() == '#': + while self.peek() not in '\0\r\n\x85\u2028\u2029': + self.forward() + ch = self.peek() + if ch not in '\0\r\n\x85\u2028\u2029': + raise ScannerError("while scanning a directive", start_mark, + "expected a comment or a line break, but found %r" + % ch, self.get_mark()) + self.scan_line_break() + + def scan_anchor(self, TokenClass): + # The specification does not restrict characters for anchors and + # aliases. This may lead to problems, for instance, the document: + # [ *alias, value ] + # can be interpreted in two ways, as + # [ "value" ] + # and + # [ *alias , "value" ] + # Therefore we restrict aliases to numbers and ASCII letters. + start_mark = self.get_mark() + indicator = self.peek() + if indicator == '*': + name = 'alias' + else: + name = 'anchor' + self.forward() + length = 0 + ch = self.peek(length) + while '0' <= ch <= '9' or 'A' <= ch <= 'Z' or 'a' <= ch <= 'z' \ + or ch in '-_': + length += 1 + ch = self.peek(length) + if not length: + raise ScannerError("while scanning an %s" % name, start_mark, + "expected alphabetic or numeric character, but found %r" + % ch, self.get_mark()) + value = self.prefix(length) + self.forward(length) + ch = self.peek() + if ch not in '\0 \t\r\n\x85\u2028\u2029?:,]}%@`': + raise ScannerError("while scanning an %s" % name, start_mark, + "expected alphabetic or numeric character, but found %r" + % ch, self.get_mark()) + end_mark = self.get_mark() + return TokenClass(value, start_mark, end_mark) + + def scan_tag(self): + # See the specification for details. + start_mark = self.get_mark() + ch = self.peek(1) + if ch == '<': + handle = None + self.forward(2) + suffix = self.scan_tag_uri('tag', start_mark) + if self.peek() != '>': + raise ScannerError("while parsing a tag", start_mark, + "expected '>', but found %r" % self.peek(), + self.get_mark()) + self.forward() + elif ch in '\0 \t\r\n\x85\u2028\u2029': + handle = None + suffix = '!' + self.forward() + else: + length = 1 + use_handle = False + while ch not in '\0 \r\n\x85\u2028\u2029': + if ch == '!': + use_handle = True + break + length += 1 + ch = self.peek(length) + handle = '!' + if use_handle: + handle = self.scan_tag_handle('tag', start_mark) + else: + handle = '!' + self.forward() + suffix = self.scan_tag_uri('tag', start_mark) + ch = self.peek() + if ch not in '\0 \r\n\x85\u2028\u2029': + raise ScannerError("while scanning a tag", start_mark, + "expected ' ', but found %r" % ch, self.get_mark()) + value = (handle, suffix) + end_mark = self.get_mark() + return TagToken(value, start_mark, end_mark) + + def scan_block_scalar(self, style): + # See the specification for details. + + if style == '>': + folded = True + else: + folded = False + + chunks = [] + start_mark = self.get_mark() + + # Scan the header. + self.forward() + chomping, increment = self.scan_block_scalar_indicators(start_mark) + self.scan_block_scalar_ignored_line(start_mark) + + # Determine the indentation level and go to the first non-empty line. + min_indent = self.indent+1 + if min_indent < 1: + min_indent = 1 + if increment is None: + breaks, max_indent, end_mark = self.scan_block_scalar_indentation() + indent = max(min_indent, max_indent) + else: + indent = min_indent+increment-1 + breaks, end_mark = self.scan_block_scalar_breaks(indent) + line_break = '' + + # Scan the inner part of the block scalar. + while self.column == indent and self.peek() != '\0': + chunks.extend(breaks) + leading_non_space = self.peek() not in ' \t' + length = 0 + while self.peek(length) not in '\0\r\n\x85\u2028\u2029': + length += 1 + chunks.append(self.prefix(length)) + self.forward(length) + line_break = self.scan_line_break() + breaks, end_mark = self.scan_block_scalar_breaks(indent) + if self.column == indent and self.peek() != '\0': + + # Unfortunately, folding rules are ambiguous. + # + # This is the folding according to the specification: + + if folded and line_break == '\n' \ + and leading_non_space and self.peek() not in ' \t': + if not breaks: + chunks.append(' ') + else: + chunks.append(line_break) + + # This is Clark Evans's interpretation (also in the spec + # examples): + # + #if folded and line_break == '\n': + # if not breaks: + # if self.peek() not in ' \t': + # chunks.append(' ') + # else: + # chunks.append(line_break) + #else: + # chunks.append(line_break) + else: + break + + # Chomp the tail. + if chomping is not False: + chunks.append(line_break) + if chomping is True: + chunks.extend(breaks) + + # We are done. + return ScalarToken(''.join(chunks), False, start_mark, end_mark, + style) + + def scan_block_scalar_indicators(self, start_mark): + # See the specification for details. + chomping = None + increment = None + ch = self.peek() + if ch in '+-': + if ch == '+': + chomping = True + else: + chomping = False + self.forward() + ch = self.peek() + if ch in '0123456789': + increment = int(ch) + if increment == 0: + raise ScannerError("while scanning a block scalar", start_mark, + "expected indentation indicator in the range 1-9, but found 0", + self.get_mark()) + self.forward() + elif ch in '0123456789': + increment = int(ch) + if increment == 0: + raise ScannerError("while scanning a block scalar", start_mark, + "expected indentation indicator in the range 1-9, but found 0", + self.get_mark()) + self.forward() + ch = self.peek() + if ch in '+-': + if ch == '+': + chomping = True + else: + chomping = False + self.forward() + ch = self.peek() + if ch not in '\0 \r\n\x85\u2028\u2029': + raise ScannerError("while scanning a block scalar", start_mark, + "expected chomping or indentation indicators, but found %r" + % ch, self.get_mark()) + return chomping, increment + + def scan_block_scalar_ignored_line(self, start_mark): + # See the specification for details. + while self.peek() == ' ': + self.forward() + if self.peek() == '#': + while self.peek() not in '\0\r\n\x85\u2028\u2029': + self.forward() + ch = self.peek() + if ch not in '\0\r\n\x85\u2028\u2029': + raise ScannerError("while scanning a block scalar", start_mark, + "expected a comment or a line break, but found %r" % ch, + self.get_mark()) + self.scan_line_break() + + def scan_block_scalar_indentation(self): + # See the specification for details. + chunks = [] + max_indent = 0 + end_mark = self.get_mark() + while self.peek() in ' \r\n\x85\u2028\u2029': + if self.peek() != ' ': + chunks.append(self.scan_line_break()) + end_mark = self.get_mark() + else: + self.forward() + if self.column > max_indent: + max_indent = self.column + return chunks, max_indent, end_mark + + def scan_block_scalar_breaks(self, indent): + # See the specification for details. + chunks = [] + end_mark = self.get_mark() + while self.column < indent and self.peek() == ' ': + self.forward() + while self.peek() in '\r\n\x85\u2028\u2029': + chunks.append(self.scan_line_break()) + end_mark = self.get_mark() + while self.column < indent and self.peek() == ' ': + self.forward() + return chunks, end_mark + + def scan_flow_scalar(self, style): + # See the specification for details. + # Note that we loose indentation rules for quoted scalars. Quoted + # scalars don't need to adhere indentation because " and ' clearly + # mark the beginning and the end of them. Therefore we are less + # restrictive then the specification requires. We only need to check + # that document separators are not included in scalars. + if style == '"': + double = True + else: + double = False + chunks = [] + start_mark = self.get_mark() + quote = self.peek() + self.forward() + chunks.extend(self.scan_flow_scalar_non_spaces(double, start_mark)) + while self.peek() != quote: + chunks.extend(self.scan_flow_scalar_spaces(double, start_mark)) + chunks.extend(self.scan_flow_scalar_non_spaces(double, start_mark)) + self.forward() + end_mark = self.get_mark() + return ScalarToken(''.join(chunks), False, start_mark, end_mark, + style) + + ESCAPE_REPLACEMENTS = { + '0': '\0', + 'a': '\x07', + 'b': '\x08', + 't': '\x09', + '\t': '\x09', + 'n': '\x0A', + 'v': '\x0B', + 'f': '\x0C', + 'r': '\x0D', + 'e': '\x1B', + ' ': '\x20', + '\"': '\"', + '\\': '\\', + '/': '/', + 'N': '\x85', + '_': '\xA0', + 'L': '\u2028', + 'P': '\u2029', + } + + ESCAPE_CODES = { + 'x': 2, + 'u': 4, + 'U': 8, + } + + def scan_flow_scalar_non_spaces(self, double, start_mark): + # See the specification for details. + chunks = [] + while True: + length = 0 + while self.peek(length) not in '\'\"\\\0 \t\r\n\x85\u2028\u2029': + length += 1 + if length: + chunks.append(self.prefix(length)) + self.forward(length) + ch = self.peek() + if not double and ch == '\'' and self.peek(1) == '\'': + chunks.append('\'') + self.forward(2) + elif (double and ch == '\'') or (not double and ch in '\"\\'): + chunks.append(ch) + self.forward() + elif double and ch == '\\': + self.forward() + ch = self.peek() + if ch in self.ESCAPE_REPLACEMENTS: + chunks.append(self.ESCAPE_REPLACEMENTS[ch]) + self.forward() + elif ch in self.ESCAPE_CODES: + length = self.ESCAPE_CODES[ch] + self.forward() + for k in range(length): + if self.peek(k) not in '0123456789ABCDEFabcdef': + raise ScannerError("while scanning a double-quoted scalar", start_mark, + "expected escape sequence of %d hexadecimal numbers, but found %r" % + (length, self.peek(k)), self.get_mark()) + code = int(self.prefix(length), 16) + chunks.append(chr(code)) + self.forward(length) + elif ch in '\r\n\x85\u2028\u2029': + self.scan_line_break() + chunks.extend(self.scan_flow_scalar_breaks(double, start_mark)) + else: + raise ScannerError("while scanning a double-quoted scalar", start_mark, + "found unknown escape character %r" % ch, self.get_mark()) + else: + return chunks + + def scan_flow_scalar_spaces(self, double, start_mark): + # See the specification for details. + chunks = [] + length = 0 + while self.peek(length) in ' \t': + length += 1 + whitespaces = self.prefix(length) + self.forward(length) + ch = self.peek() + if ch == '\0': + raise ScannerError("while scanning a quoted scalar", start_mark, + "found unexpected end of stream", self.get_mark()) + elif ch in '\r\n\x85\u2028\u2029': + line_break = self.scan_line_break() + breaks = self.scan_flow_scalar_breaks(double, start_mark) + if line_break != '\n': + chunks.append(line_break) + elif not breaks: + chunks.append(' ') + chunks.extend(breaks) + else: + chunks.append(whitespaces) + return chunks + + def scan_flow_scalar_breaks(self, double, start_mark): + # See the specification for details. + chunks = [] + while True: + # Instead of checking indentation, we check for document + # separators. + prefix = self.prefix(3) + if (prefix == '---' or prefix == '...') \ + and self.peek(3) in '\0 \t\r\n\x85\u2028\u2029': + raise ScannerError("while scanning a quoted scalar", start_mark, + "found unexpected document separator", self.get_mark()) + while self.peek() in ' \t': + self.forward() + if self.peek() in '\r\n\x85\u2028\u2029': + chunks.append(self.scan_line_break()) + else: + return chunks + + def scan_plain(self): + # See the specification for details. + # We add an additional restriction for the flow context: + # plain scalars in the flow context cannot contain ',' or '?'. + # We also keep track of the `allow_simple_key` flag here. + # Indentation rules are loosed for the flow context. + chunks = [] + start_mark = self.get_mark() + end_mark = start_mark + indent = self.indent+1 + # We allow zero indentation for scalars, but then we need to check for + # document separators at the beginning of the line. + #if indent == 0: + # indent = 1 + spaces = [] + while True: + length = 0 + if self.peek() == '#': + break + while True: + ch = self.peek(length) + if ch in '\0 \t\r\n\x85\u2028\u2029' \ + or (ch == ':' and + self.peek(length+1) in '\0 \t\r\n\x85\u2028\u2029' + + (u',[]{}' if self.flow_level else u''))\ + or (self.flow_level and ch in ',?[]{}'): + break + length += 1 + if length == 0: + break + self.allow_simple_key = False + chunks.extend(spaces) + chunks.append(self.prefix(length)) + self.forward(length) + end_mark = self.get_mark() + spaces = self.scan_plain_spaces(indent, start_mark) + if not spaces or self.peek() == '#' \ + or (not self.flow_level and self.column < indent): + break + return ScalarToken(''.join(chunks), True, start_mark, end_mark) + + def scan_plain_spaces(self, indent, start_mark): + # See the specification for details. + # The specification is really confusing about tabs in plain scalars. + # We just forbid them completely. Do not use tabs in YAML! + chunks = [] + length = 0 + while self.peek(length) in ' ': + length += 1 + whitespaces = self.prefix(length) + self.forward(length) + ch = self.peek() + if ch in '\r\n\x85\u2028\u2029': + line_break = self.scan_line_break() + self.allow_simple_key = True + prefix = self.prefix(3) + if (prefix == '---' or prefix == '...') \ + and self.peek(3) in '\0 \t\r\n\x85\u2028\u2029': + return + breaks = [] + while self.peek() in ' \r\n\x85\u2028\u2029': + if self.peek() == ' ': + self.forward() + else: + breaks.append(self.scan_line_break()) + prefix = self.prefix(3) + if (prefix == '---' or prefix == '...') \ + and self.peek(3) in '\0 \t\r\n\x85\u2028\u2029': + return + if line_break != '\n': + chunks.append(line_break) + elif not breaks: + chunks.append(' ') + chunks.extend(breaks) + elif whitespaces: + chunks.append(whitespaces) + return chunks + + def scan_tag_handle(self, name, start_mark): + # See the specification for details. + # For some strange reasons, the specification does not allow '_' in + # tag handles. I have allowed it anyway. + ch = self.peek() + if ch != '!': + raise ScannerError("while scanning a %s" % name, start_mark, + "expected '!', but found %r" % ch, self.get_mark()) + length = 1 + ch = self.peek(length) + if ch != ' ': + while '0' <= ch <= '9' or 'A' <= ch <= 'Z' or 'a' <= ch <= 'z' \ + or ch in '-_': + length += 1 + ch = self.peek(length) + if ch != '!': + self.forward(length) + raise ScannerError("while scanning a %s" % name, start_mark, + "expected '!', but found %r" % ch, self.get_mark()) + length += 1 + value = self.prefix(length) + self.forward(length) + return value + + def scan_tag_uri(self, name, start_mark): + # See the specification for details. + # Note: we do not check if URI is well-formed. + chunks = [] + length = 0 + ch = self.peek(length) + while '0' <= ch <= '9' or 'A' <= ch <= 'Z' or 'a' <= ch <= 'z' \ + or ch in '-;/?:@&=+$,_.!~*\'()[]%': + if ch == '%': + chunks.append(self.prefix(length)) + self.forward(length) + length = 0 + chunks.append(self.scan_uri_escapes(name, start_mark)) + else: + length += 1 + ch = self.peek(length) + if length: + chunks.append(self.prefix(length)) + self.forward(length) + length = 0 + if not chunks: + raise ScannerError("while parsing a %s" % name, start_mark, + "expected URI, but found %r" % ch, self.get_mark()) + return ''.join(chunks) + + def scan_uri_escapes(self, name, start_mark): + # See the specification for details. + codes = [] + mark = self.get_mark() + while self.peek() == '%': + self.forward() + for k in range(2): + if self.peek(k) not in '0123456789ABCDEFabcdef': + raise ScannerError("while scanning a %s" % name, start_mark, + "expected URI escape sequence of 2 hexadecimal numbers, but found %r" + % self.peek(k), self.get_mark()) + codes.append(int(self.prefix(2), 16)) + self.forward(2) + try: + value = bytes(codes).decode('utf-8') + except UnicodeDecodeError as exc: + raise ScannerError("while scanning a %s" % name, start_mark, str(exc), mark) + return value + + def scan_line_break(self): + # Transforms: + # '\r\n' : '\n' + # '\r' : '\n' + # '\n' : '\n' + # '\x85' : '\n' + # '\u2028' : '\u2028' + # '\u2029 : '\u2029' + # default : '' + ch = self.peek() + if ch in '\r\n\x85': + if self.prefix(2) == '\r\n': + self.forward(2) + else: + self.forward() + return '\n' + elif ch in '\u2028\u2029': + self.forward() + return ch + return '' diff --git a/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/yaml/tokens.py b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/yaml/tokens.py new file mode 100644 index 0000000000000000000000000000000000000000..4d0b48a394ac8c019b401516a12f688df361cf90 --- /dev/null +++ b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/yaml/tokens.py @@ -0,0 +1,104 @@ + +class Token(object): + def __init__(self, start_mark, end_mark): + self.start_mark = start_mark + self.end_mark = end_mark + def __repr__(self): + attributes = [key for key in self.__dict__ + if not key.endswith('_mark')] + attributes.sort() + arguments = ', '.join(['%s=%r' % (key, getattr(self, key)) + for key in attributes]) + return '%s(%s)' % (self.__class__.__name__, arguments) + +#class BOMToken(Token): +# id = '' + +class DirectiveToken(Token): + id = '' + def __init__(self, name, value, start_mark, end_mark): + self.name = name + self.value = value + self.start_mark = start_mark + self.end_mark = end_mark + +class DocumentStartToken(Token): + id = '' + +class DocumentEndToken(Token): + id = '' + +class StreamStartToken(Token): + id = '' + def __init__(self, start_mark=None, end_mark=None, + encoding=None): + self.start_mark = start_mark + self.end_mark = end_mark + self.encoding = encoding + +class StreamEndToken(Token): + id = '' + +class BlockSequenceStartToken(Token): + id = '' + +class BlockMappingStartToken(Token): + id = '' + +class BlockEndToken(Token): + id = '' + +class FlowSequenceStartToken(Token): + id = '[' + +class FlowMappingStartToken(Token): + id = '{' + +class FlowSequenceEndToken(Token): + id = ']' + +class FlowMappingEndToken(Token): + id = '}' + +class KeyToken(Token): + id = '?' + +class ValueToken(Token): + id = ':' + +class BlockEntryToken(Token): + id = '-' + +class FlowEntryToken(Token): + id = ',' + +class AliasToken(Token): + id = '' + def __init__(self, value, start_mark, end_mark): + self.value = value + self.start_mark = start_mark + self.end_mark = end_mark + +class AnchorToken(Token): + id = '' + def __init__(self, value, start_mark, end_mark): + self.value = value + self.start_mark = start_mark + self.end_mark = end_mark + +class TagToken(Token): + id = '' + def __init__(self, value, start_mark, end_mark): + self.value = value + self.start_mark = start_mark + self.end_mark = end_mark + +class ScalarToken(Token): + id = '' + def __init__(self, value, plain, start_mark, end_mark, style=None): + self.value = value + self.plain = plain + self.start_mark = start_mark + self.end_mark = end_mark + self.style = style + diff --git a/tmp_inputs/case00010.nii.gz b/tmp_inputs/case00010.nii.gz new file mode 100644 index 0000000000000000000000000000000000000000..11fae7ace0c855b3f7879ee4b364ad69f5bc5a1b --- /dev/null +++ b/tmp_inputs/case00010.nii.gz @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b20838bb51029ab9bc18163aec81fc3f9157b6f01dac6310cff412bba4929a2d +size 33575337