prasb commited on
Commit
100ad59
·
verified ·
1 Parent(s): f83de80

Add files using upload-large-folder tool

Browse files
This view is limited to 50 files because it contains too many changes.   See raw diff
Files changed (50) hide show
  1. .gitattributes +6 -0
  2. my_container_sandbox/workspace/anaconda3/bin/x86_64-conda_cos6-linux-gnu-ld +3 -0
  3. my_container_sandbox/workspace/anaconda3/lib/python3.8/lib-dynload/_csv.cpython-38-x86_64-linux-gnu.so +3 -0
  4. my_container_sandbox/workspace/anaconda3/lib/python3.8/lib-dynload/_tkinter.cpython-38-x86_64-linux-gnu.so +3 -0
  5. my_container_sandbox/workspace/anaconda3/lib/python3.8/lib-dynload/math.cpython-38-x86_64-linux-gnu.so +3 -0
  6. my_container_sandbox/workspace/anaconda3/lib/python3.8/lib-dynload/mmap.cpython-38-x86_64-linux-gnu.so +3 -0
  7. my_container_sandbox/workspace/anaconda3/lib/python3.8/lib-dynload/unicodedata.cpython-38-x86_64-linux-gnu.so +3 -0
  8. my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/attrs-21.4.0.dist-info/METADATA +232 -0
  9. my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/attrs-21.4.0.dist-info/RECORD +57 -0
  10. my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/attrs-21.4.0.dist-info/WHEEL +6 -0
  11. my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/attrs-21.4.0.dist-info/top_level.txt +2 -0
  12. my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/click/_termui_impl.py +717 -0
  13. my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/google_auth-2.9.0-py3.10-nspkg.pth +3 -0
  14. my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/grpc/__init__.py +2190 -0
  15. my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/grpc/_channel.py +1585 -0
  16. my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/grpc/_common.py +168 -0
  17. my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/grpc/_compression.py +55 -0
  18. my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/grpc/_grpcio_metadata.py +1 -0
  19. my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/grpc/_interceptor.py +562 -0
  20. my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/grpc/_plugin_wrapping.py +113 -0
  21. my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/grpc/_runtime_protos.py +155 -0
  22. my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/grpc/_server.py +1003 -0
  23. my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/grpc/_simple_stubs.py +486 -0
  24. my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/omegaconf/_impl.py +101 -0
  25. my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/omegaconf/errors.py +141 -0
  26. my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/omegaconf/grammar_parser.py +144 -0
  27. my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/omegaconf/version.py +13 -0
  28. my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/pyasn1_modules/rfc3114.py +77 -0
  29. my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/pyasn1_modules/rfc3281.py +331 -0
  30. my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/pyasn1_modules/rfc3779.py +137 -0
  31. my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/pyasn1_modules/rfc5917.py +55 -0
  32. my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/pyasn1_modules/rfc5934.py +786 -0
  33. my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/pyasn1_modules/rfc5940.py +59 -0
  34. my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/pyasn1_modules/rfc6031.py +469 -0
  35. my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/pyasn1_modules/rfc7229.py +29 -0
  36. my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/pyasn1_modules/rfc7585.py +50 -0
  37. my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/pyasn1_modules/rfc7894.py +92 -0
  38. my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/pycodestyle-2.8.0.dist-info/INSTALLER +1 -0
  39. my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/pycodestyle-2.8.0.dist-info/LICENSE +25 -0
  40. my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/pycodestyle-2.8.0.dist-info/METADATA +1063 -0
  41. my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/pycodestyle-2.8.0.dist-info/RECORD +12 -0
  42. my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/pycodestyle-2.8.0.dist-info/REQUESTED +0 -0
  43. my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/pycodestyle-2.8.0.dist-info/WHEEL +6 -0
  44. my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/pycodestyle-2.8.0.dist-info/entry_points.txt +3 -0
  45. my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/pycodestyle-2.8.0.dist-info/namespace_packages.txt +1 -0
  46. my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/pycodestyle-2.8.0.dist-info/top_level.txt +1 -0
  47. my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/requests/__init__.py +180 -0
  48. my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/requests/__version__.py +14 -0
  49. my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/requests/_internal_utils.py +48 -0
  50. my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/requests/adapters.py +584 -0
.gitattributes CHANGED
@@ -226,3 +226,9 @@ my_container_sandbox/workspace/anaconda3/lib/python3.8/lib-dynload/_sha3.cpython
226
  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
227
  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
228
  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
 
 
 
 
 
 
 
226
  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
227
  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
228
  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
229
+ 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
230
+ 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
231
+ 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
232
+ 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
233
+ 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
234
+ my_container_sandbox/workspace/anaconda3/bin/x86_64-conda_cos6-linux-gnu-ld filter=lfs diff=lfs merge=lfs -text
my_container_sandbox/workspace/anaconda3/bin/x86_64-conda_cos6-linux-gnu-ld ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:db98363adc9b1f3f785009e63bc77617093f5841ce0736b0407fc4bf66a30ab9
3
+ size 2568888
my_container_sandbox/workspace/anaconda3/lib/python3.8/lib-dynload/_csv.cpython-38-x86_64-linux-gnu.so ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:b589b745b5e75b99f3e76ced322e018482546477129c6a26ab08d1634b2b2cfe
3
+ size 121936
my_container_sandbox/workspace/anaconda3/lib/python3.8/lib-dynload/_tkinter.cpython-38-x86_64-linux-gnu.so ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:832b13f4e094686c809adb072054d79139f80531479ab8dd90efe991c76d1691
3
+ size 221992
my_container_sandbox/workspace/anaconda3/lib/python3.8/lib-dynload/math.cpython-38-x86_64-linux-gnu.so ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:6788eb7b2bc17778d5694e2d0100dd6c74e955f0740c55f48f8da2c997ba2420
3
+ size 253424
my_container_sandbox/workspace/anaconda3/lib/python3.8/lib-dynload/mmap.cpython-38-x86_64-linux-gnu.so ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:58be3da0f728647b97e53afa534e95e42ac7731b8cb014371d0f53eee118ac3f
3
+ size 104664
my_container_sandbox/workspace/anaconda3/lib/python3.8/lib-dynload/unicodedata.cpython-38-x86_64-linux-gnu.so ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:a4a47c7a22336b3de31509eaa3e60a65daf3d486a1deef81610fc2f3d163eb0c
3
+ size 1170032
my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/attrs-21.4.0.dist-info/METADATA ADDED
@@ -0,0 +1,232 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ Metadata-Version: 2.1
2
+ Name: attrs
3
+ Version: 21.4.0
4
+ Summary: Classes Without Boilerplate
5
+ Home-page: https://www.attrs.org/
6
+ Author: Hynek Schlawack
7
+ Author-email: hs@ox.cx
8
+ Maintainer: Hynek Schlawack
9
+ Maintainer-email: hs@ox.cx
10
+ License: MIT
11
+ Project-URL: Documentation, https://www.attrs.org/
12
+ Project-URL: Changelog, https://www.attrs.org/en/stable/changelog.html
13
+ Project-URL: Bug Tracker, https://github.com/python-attrs/attrs/issues
14
+ Project-URL: Source Code, https://github.com/python-attrs/attrs
15
+ Project-URL: Funding, https://github.com/sponsors/hynek
16
+ Project-URL: Tidelift, https://tidelift.com/subscription/pkg/pypi-attrs?utm_source=pypi-attrs&utm_medium=pypi
17
+ Project-URL: Ko-fi, https://ko-fi.com/the_hynek
18
+ Keywords: class,attribute,boilerplate
19
+ Platform: UNKNOWN
20
+ Classifier: Development Status :: 5 - Production/Stable
21
+ Classifier: Intended Audience :: Developers
22
+ Classifier: Natural Language :: English
23
+ Classifier: License :: OSI Approved :: MIT License
24
+ Classifier: Operating System :: OS Independent
25
+ Classifier: Programming Language :: Python
26
+ Classifier: Programming Language :: Python :: 2
27
+ Classifier: Programming Language :: Python :: 2.7
28
+ Classifier: Programming Language :: Python :: 3
29
+ Classifier: Programming Language :: Python :: 3.5
30
+ Classifier: Programming Language :: Python :: 3.6
31
+ Classifier: Programming Language :: Python :: 3.7
32
+ Classifier: Programming Language :: Python :: 3.8
33
+ Classifier: Programming Language :: Python :: 3.9
34
+ Classifier: Programming Language :: Python :: 3.10
35
+ Classifier: Programming Language :: Python :: Implementation :: CPython
36
+ Classifier: Programming Language :: Python :: Implementation :: PyPy
37
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
38
+ Requires-Python: >=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*
39
+ Description-Content-Type: text/x-rst
40
+ License-File: LICENSE
41
+ License-File: AUTHORS.rst
42
+ Provides-Extra: dev
43
+ Requires-Dist: coverage[toml] (>=5.0.2) ; extra == 'dev'
44
+ Requires-Dist: hypothesis ; extra == 'dev'
45
+ Requires-Dist: pympler ; extra == 'dev'
46
+ Requires-Dist: pytest (>=4.3.0) ; extra == 'dev'
47
+ Requires-Dist: six ; extra == 'dev'
48
+ Requires-Dist: mypy ; extra == 'dev'
49
+ Requires-Dist: pytest-mypy-plugins ; extra == 'dev'
50
+ Requires-Dist: zope.interface ; extra == 'dev'
51
+ Requires-Dist: furo ; extra == 'dev'
52
+ Requires-Dist: sphinx ; extra == 'dev'
53
+ Requires-Dist: sphinx-notfound-page ; extra == 'dev'
54
+ Requires-Dist: pre-commit ; extra == 'dev'
55
+ Requires-Dist: cloudpickle ; (platform_python_implementation == "CPython") and extra == 'dev'
56
+ Provides-Extra: docs
57
+ Requires-Dist: furo ; extra == 'docs'
58
+ Requires-Dist: sphinx ; extra == 'docs'
59
+ Requires-Dist: zope.interface ; extra == 'docs'
60
+ Requires-Dist: sphinx-notfound-page ; extra == 'docs'
61
+ Provides-Extra: tests
62
+ Requires-Dist: coverage[toml] (>=5.0.2) ; extra == 'tests'
63
+ Requires-Dist: hypothesis ; extra == 'tests'
64
+ Requires-Dist: pympler ; extra == 'tests'
65
+ Requires-Dist: pytest (>=4.3.0) ; extra == 'tests'
66
+ Requires-Dist: six ; extra == 'tests'
67
+ Requires-Dist: mypy ; extra == 'tests'
68
+ Requires-Dist: pytest-mypy-plugins ; extra == 'tests'
69
+ Requires-Dist: zope.interface ; extra == 'tests'
70
+ Requires-Dist: cloudpickle ; (platform_python_implementation == "CPython") and extra == 'tests'
71
+ Provides-Extra: tests_no_zope
72
+ Requires-Dist: coverage[toml] (>=5.0.2) ; extra == 'tests_no_zope'
73
+ Requires-Dist: hypothesis ; extra == 'tests_no_zope'
74
+ Requires-Dist: pympler ; extra == 'tests_no_zope'
75
+ Requires-Dist: pytest (>=4.3.0) ; extra == 'tests_no_zope'
76
+ Requires-Dist: six ; extra == 'tests_no_zope'
77
+ Requires-Dist: mypy ; extra == 'tests_no_zope'
78
+ Requires-Dist: pytest-mypy-plugins ; extra == 'tests_no_zope'
79
+ Requires-Dist: cloudpickle ; (platform_python_implementation == "CPython") and extra == 'tests_no_zope'
80
+
81
+
82
+ .. image:: https://www.attrs.org/en/stable/_static/attrs_logo.png
83
+ :alt: attrs logo
84
+ :align: center
85
+
86
+
87
+ ``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 <https://www.attrs.org/en/latest/glossary.html#term-dunder-methods>`_).
88
+ `Trusted by NASA <https://docs.github.com/en/account-and-profile/setting-up-and-managing-your-github-profile/customizing-your-profile/personalizing-your-profile#list-of-qualifying-repositories-for-mars-2020-helicopter-contributor-badge>`_ for Mars missions since 2020!
89
+
90
+ Its main goal is to help you to write **concise** and **correct** software without slowing down your code.
91
+
92
+ .. teaser-end
93
+
94
+ For that, it gives you a class decorator and a way to declaratively define the attributes on that class:
95
+
96
+ .. -code-begin-
97
+
98
+ .. code-block:: pycon
99
+
100
+ >>> from attrs import asdict, define, make_class, Factory
101
+
102
+ >>> @define
103
+ ... class SomeClass:
104
+ ... a_number: int = 42
105
+ ... list_of_numbers: list[int] = Factory(list)
106
+ ...
107
+ ... def hard_math(self, another_number):
108
+ ... return self.a_number + sum(self.list_of_numbers) * another_number
109
+
110
+
111
+ >>> sc = SomeClass(1, [1, 2, 3])
112
+ >>> sc
113
+ SomeClass(a_number=1, list_of_numbers=[1, 2, 3])
114
+
115
+ >>> sc.hard_math(3)
116
+ 19
117
+ >>> sc == SomeClass(1, [1, 2, 3])
118
+ True
119
+ >>> sc != SomeClass(2, [3, 2, 1])
120
+ True
121
+
122
+ >>> asdict(sc)
123
+ {'a_number': 1, 'list_of_numbers': [1, 2, 3]}
124
+
125
+ >>> SomeClass()
126
+ SomeClass(a_number=42, list_of_numbers=[])
127
+
128
+ >>> C = make_class("C", ["a", "b"])
129
+ >>> C("foo", "bar")
130
+ C(a='foo', b='bar')
131
+
132
+
133
+ After *declaring* your attributes ``attrs`` gives you:
134
+
135
+ - a concise and explicit overview of the class's attributes,
136
+ - a nice human-readable ``__repr__``,
137
+ - a equality-checking methods,
138
+ - an initializer,
139
+ - and much more,
140
+
141
+ *without* writing dull boilerplate code again and again and *without* runtime performance penalties.
142
+
143
+ **Hate type annotations**!?
144
+ No problem!
145
+ Types are entirely **optional** with ``attrs``.
146
+ Simply assign ``attrs.field()`` to the attributes instead of annotating them with types.
147
+
148
+ ----
149
+
150
+ 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.
151
+ The classic APIs (``@attr.s``, ``attr.ib``, plus their serious business aliases) and the ``attr`` package import name will remain **indefinitely**.
152
+
153
+ Please check out `On The Core API Names <https://www.attrs.org/en/latest/names.html>`_ for a more in-depth explanation.
154
+
155
+
156
+ Data Classes
157
+ ============
158
+
159
+ On the tin, ``attrs`` might remind you of ``dataclasses`` (and indeed, ``dataclasses`` are a descendant of ``attrs``).
160
+ In practice it does a lot more and is more flexible.
161
+ For instance it allows you to define `special handling of NumPy arrays for equality checks <https://www.attrs.org/en/stable/comparison.html#customization>`_, or allows more ways to `plug into the initialization process <https://www.attrs.org/en/stable/init.html#hooking-yourself-into-initialization>`_.
162
+
163
+ For more details, please refer to our `comparison page <https://www.attrs.org/en/stable/why.html#data-classes>`_.
164
+
165
+
166
+ .. -getting-help-
167
+
168
+ Getting Help
169
+ ============
170
+
171
+ Please use the ``python-attrs`` tag on `Stack Overflow <https://stackoverflow.com/questions/tagged/python-attrs>`_ to get help.
172
+
173
+ Answering questions of your fellow developers is also a great way to help the project!
174
+
175
+
176
+ .. -project-information-
177
+
178
+ Project Information
179
+ ===================
180
+
181
+ ``attrs`` is released under the `MIT <https://choosealicense.com/licenses/mit/>`_ license,
182
+ its documentation lives at `Read the Docs <https://www.attrs.org/>`_,
183
+ the code on `GitHub <https://github.com/python-attrs/attrs>`_,
184
+ and the latest release on `PyPI <https://pypi.org/project/attrs/>`_.
185
+ It’s rigorously tested on Python 2.7, 3.5+, and PyPy.
186
+
187
+ We collect information on **third-party extensions** in our `wiki <https://github.com/python-attrs/attrs/wiki/Extensions-to-attrs>`_.
188
+ Feel free to browse and add your own!
189
+
190
+ If you'd like to contribute to ``attrs`` you're most welcome and we've written `a little guide <https://github.com/python-attrs/attrs/blob/main/.github/CONTRIBUTING.md>`_ to get you started!
191
+
192
+
193
+ ``attrs`` for Enterprise
194
+ ------------------------
195
+
196
+ Available as part of the Tidelift Subscription.
197
+
198
+ 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.
199
+ Save time, reduce risk, and improve code health, while paying the maintainers of the exact packages you use.
200
+ `Learn more. <https://tidelift.com/subscription/pkg/pypi-attrs?utm_source=pypi-attrs&utm_medium=referral&utm_campaign=enterprise&utm_term=repo>`_
201
+
202
+
203
+ Release Information
204
+ ===================
205
+
206
+ 21.4.0 (2021-12-29)
207
+ -------------------
208
+
209
+ Changes
210
+ ^^^^^^^
211
+
212
+ - Fixed the test suite on PyPy3.8 where ``cloudpickle`` does not work.
213
+ `#892 <https://github.com/python-attrs/attrs/issues/892>`_
214
+ - Fixed ``coverage report`` for projects that use ``attrs`` and don't set a ``--source``.
215
+ `#895 <https://github.com/python-attrs/attrs/issues/895>`_,
216
+ `#896 <https://github.com/python-attrs/attrs/issues/896>`_
217
+
218
+ `Full changelog <https://www.attrs.org/en/stable/changelog.html>`_.
219
+
220
+ Credits
221
+ =======
222
+
223
+ ``attrs`` is written and maintained by `Hynek Schlawack <https://hynek.me/>`_.
224
+
225
+ The development is kindly supported by `Variomedia AG <https://www.variomedia.de/>`_.
226
+
227
+ A full list of contributors can be found in `GitHub's overview <https://github.com/python-attrs/attrs/graphs/contributors>`_.
228
+
229
+ It’s the spiritual successor of `characteristic <https://characteristic.readthedocs.io/>`_ and aspires to fix some of it clunkiness and unfortunate decisions.
230
+ Both were inspired by Twisted’s `FancyEqMixin <https://twistedmatrix.com/documents/current/api/twisted.python.util.FancyEqMixin.html>`_ but both are implemented using class decorators because `subclassing is bad for you <https://www.youtube.com/watch?v=3MNVP9-hglc>`_, m’kay?
231
+
232
+
my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/attrs-21.4.0.dist-info/RECORD ADDED
@@ -0,0 +1,57 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ attr/__init__.py,sha256=_zhJ4O8Q5KR5gaIrjX73vkR5nA6NjfpMGXQChEdNljI,1667
2
+ attr/__init__.pyi,sha256=ubRkstoRHPpQN17iA0OCh8waIwZ5NeJgbz0lwI8XUjY,15100
3
+ attr/__pycache__/__init__.cpython-38.pyc,,
4
+ attr/__pycache__/_cmp.cpython-38.pyc,,
5
+ attr/__pycache__/_compat.cpython-38.pyc,,
6
+ attr/__pycache__/_config.cpython-38.pyc,,
7
+ attr/__pycache__/_funcs.cpython-38.pyc,,
8
+ attr/__pycache__/_make.cpython-38.pyc,,
9
+ attr/__pycache__/_next_gen.cpython-38.pyc,,
10
+ attr/__pycache__/_version_info.cpython-38.pyc,,
11
+ attr/__pycache__/converters.cpython-38.pyc,,
12
+ attr/__pycache__/exceptions.cpython-38.pyc,,
13
+ attr/__pycache__/filters.cpython-38.pyc,,
14
+ attr/__pycache__/setters.cpython-38.pyc,,
15
+ attr/__pycache__/validators.cpython-38.pyc,,
16
+ attr/_cmp.py,sha256=JP0N7OIyTqIR3prUDfMZOR4DV4tlV_xXf39-bQg7xOo,4165
17
+ attr/_cmp.pyi,sha256=oyjJVytrwwkUJOoe332IiYzp6pCVZEKKcKveH-ev604,317
18
+ attr/_compat.py,sha256=i8u27AAK_4SzQnmTf3aliGV27UdYbJxdZ-O0tOHbLU8,8396
19
+ attr/_config.py,sha256=aj1Lh8t2CuVa5nSxgCrLQtg_ZSdO8ZKeNJQd6RvpIp8,892
20
+ attr/_funcs.py,sha256=sm_D12y2IyRW_bCnR7M-O7U5qHaieXr0BzINwJ7_K38,14753
21
+ attr/_make.py,sha256=D05j0_ckcVIRFn2xHch5SPUCwh3t7WpeFj-3Ku9SocQ,102736
22
+ attr/_next_gen.py,sha256=s5jCsVEQ4IhOjAykP4N0ETaWpg0RsgQttMvEZErUrhQ,5752
23
+ attr/_version_info.py,sha256=sxD9yNai0jGbur_-RGEQHbgV2YX5_5G9PhrhBA5pA54,2194
24
+ attr/_version_info.pyi,sha256=x_M3L3WuB7r_ULXAWjx959udKQ4HLB8l-hsc1FDGNvk,209
25
+ attr/converters.py,sha256=uiiWTz8GLJe8I1Ty7UICK1DegVUnqHTXbOSnar7g7Nk,4078
26
+ attr/converters.pyi,sha256=MQo7iEzPNVoFpKqD30sVwgVpdNoIeSCF2nsXvoxLZ-Y,416
27
+ attr/exceptions.py,sha256=BMg7AljkJnvG-irMwL2TBHYlaLBXhSKnzoEWo4e42Zw,1981
28
+ attr/exceptions.pyi,sha256=zZq8bCUnKAy9mDtBEw42ZhPhAUIHoTKedDQInJD883M,539
29
+ attr/filters.py,sha256=JGZgvPGkdOfttkoL6XhXS6ZCoaVV5nZ8GCYeZNUN_mE,1124
30
+ attr/filters.pyi,sha256=_Sm80jGySETX_Clzdkon5NHVjQWRl3Y3liQKZX1czXc,215
31
+ attr/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
32
+ attr/setters.py,sha256=rH_UtQuHgQEC7hfZyMO_SJW0R1Gus7-a83U8igZfqs8,1466
33
+ attr/setters.pyi,sha256=7dM10rqpQVDW0y-iJUnq8rabdO5Wx2Sbo5LwNa0IXl0,573
34
+ attr/validators.py,sha256=jVE9roaSOmTf0dJNSLHNaQNilkrlzc3pNNBKmv0g7pk,15966
35
+ attr/validators.pyi,sha256=adn6rNbIXmRXlg_FKrTmWj0dOX0vKTsGG82Jd3YcJbQ,2268
36
+ attrs-21.4.0.dist-info/AUTHORS.rst,sha256=wsqCNbGz_mklcJrt54APIZHZpoTIJLkXqEhhn4Nd8hc,752
37
+ attrs-21.4.0.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4
38
+ attrs-21.4.0.dist-info/LICENSE,sha256=v2WaKLSSQGAvVrvfSQy-LsUJsVuY-Z17GaUsdA4yeGM,1082
39
+ attrs-21.4.0.dist-info/METADATA,sha256=WwgR4MfxE55PpGGv21UOEOEtXZGCqwekfXYg-JgA5HY,9810
40
+ attrs-21.4.0.dist-info/RECORD,,
41
+ attrs-21.4.0.dist-info/REQUESTED,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
42
+ attrs-21.4.0.dist-info/WHEEL,sha256=z9j0xAa_JmUKMpmz72K0ZGALSM_n-wQVmGbleXx2VHg,110
43
+ attrs-21.4.0.dist-info/top_level.txt,sha256=AGbmKnOtYpdkLRsDRQVSBIwfL32pAQ6BSo1mt-BxI7M,11
44
+ attrs/__init__.py,sha256=CeyxLGVViAEKKsLOLaif8vF3vs1a28vsrRVLv7eMEgM,1109
45
+ attrs/__init__.pyi,sha256=57aCxUJukK9lZlrUgk9RuWiBiPY5DzDKJAJkhbrStYw,1982
46
+ attrs/__pycache__/__init__.cpython-38.pyc,,
47
+ attrs/__pycache__/converters.cpython-38.pyc,,
48
+ attrs/__pycache__/exceptions.cpython-38.pyc,,
49
+ attrs/__pycache__/filters.cpython-38.pyc,,
50
+ attrs/__pycache__/setters.cpython-38.pyc,,
51
+ attrs/__pycache__/validators.cpython-38.pyc,,
52
+ attrs/converters.py,sha256=fCBEdlYWcmI3sCnpUk2pz22GYtXzqTkp6NeOpdI64PY,70
53
+ attrs/exceptions.py,sha256=SlDli6AY77f6ny-H7oy98OkQjsrw-D_supEuErIVYkE,70
54
+ attrs/filters.py,sha256=dc_dNey29kH6KLU1mT2Dakq7tZ3kBfzEGwzOmDzw1F8,67
55
+ attrs/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
56
+ attrs/setters.py,sha256=oKw51C72Hh45wTwYvDHJP9kbicxiMhMR4Y5GvdpKdHQ,67
57
+ attrs/validators.py,sha256=4ag1SyVD2Hm3PYKiNG_NOtR_e7f81Hr6GiNl4YvXo4Q,70
my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/attrs-21.4.0.dist-info/WHEEL ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ Wheel-Version: 1.0
2
+ Generator: bdist_wheel (0.37.1)
3
+ Root-Is-Purelib: true
4
+ Tag: py2-none-any
5
+ Tag: py3-none-any
6
+
my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/attrs-21.4.0.dist-info/top_level.txt ADDED
@@ -0,0 +1,2 @@
 
 
 
1
+ attr
2
+ attrs
my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/click/_termui_impl.py ADDED
@@ -0,0 +1,717 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ This module contains implementations for the termui module. To keep the
3
+ import time of Click down, some infrequently used functionality is
4
+ placed in this module and only imported as needed.
5
+ """
6
+ import contextlib
7
+ import math
8
+ import os
9
+ import sys
10
+ import time
11
+ import typing as t
12
+ from gettext import gettext as _
13
+
14
+ from ._compat import _default_text_stdout
15
+ from ._compat import CYGWIN
16
+ from ._compat import get_best_encoding
17
+ from ._compat import isatty
18
+ from ._compat import open_stream
19
+ from ._compat import strip_ansi
20
+ from ._compat import term_len
21
+ from ._compat import WIN
22
+ from .exceptions import ClickException
23
+ from .utils import echo
24
+
25
+ V = t.TypeVar("V")
26
+
27
+ if os.name == "nt":
28
+ BEFORE_BAR = "\r"
29
+ AFTER_BAR = "\n"
30
+ else:
31
+ BEFORE_BAR = "\r\033[?25l"
32
+ AFTER_BAR = "\033[?25h\n"
33
+
34
+
35
+ class ProgressBar(t.Generic[V]):
36
+ def __init__(
37
+ self,
38
+ iterable: t.Optional[t.Iterable[V]],
39
+ length: t.Optional[int] = None,
40
+ fill_char: str = "#",
41
+ empty_char: str = " ",
42
+ bar_template: str = "%(bar)s",
43
+ info_sep: str = " ",
44
+ show_eta: bool = True,
45
+ show_percent: t.Optional[bool] = None,
46
+ show_pos: bool = False,
47
+ item_show_func: t.Optional[t.Callable[[t.Optional[V]], t.Optional[str]]] = None,
48
+ label: t.Optional[str] = None,
49
+ file: t.Optional[t.TextIO] = None,
50
+ color: t.Optional[bool] = None,
51
+ update_min_steps: int = 1,
52
+ width: int = 30,
53
+ ) -> None:
54
+ self.fill_char = fill_char
55
+ self.empty_char = empty_char
56
+ self.bar_template = bar_template
57
+ self.info_sep = info_sep
58
+ self.show_eta = show_eta
59
+ self.show_percent = show_percent
60
+ self.show_pos = show_pos
61
+ self.item_show_func = item_show_func
62
+ self.label = label or ""
63
+ if file is None:
64
+ file = _default_text_stdout()
65
+ self.file = file
66
+ self.color = color
67
+ self.update_min_steps = update_min_steps
68
+ self._completed_intervals = 0
69
+ self.width = width
70
+ self.autowidth = width == 0
71
+
72
+ if length is None:
73
+ from operator import length_hint
74
+
75
+ length = length_hint(iterable, -1)
76
+
77
+ if length == -1:
78
+ length = None
79
+ if iterable is None:
80
+ if length is None:
81
+ raise TypeError("iterable or length is required")
82
+ iterable = t.cast(t.Iterable[V], range(length))
83
+ self.iter = iter(iterable)
84
+ self.length = length
85
+ self.pos = 0
86
+ self.avg: t.List[float] = []
87
+ self.start = self.last_eta = time.time()
88
+ self.eta_known = False
89
+ self.finished = False
90
+ self.max_width: t.Optional[int] = None
91
+ self.entered = False
92
+ self.current_item: t.Optional[V] = None
93
+ self.is_hidden = not isatty(self.file)
94
+ self._last_line: t.Optional[str] = None
95
+
96
+ def __enter__(self) -> "ProgressBar":
97
+ self.entered = True
98
+ self.render_progress()
99
+ return self
100
+
101
+ def __exit__(self, exc_type, exc_value, tb): # type: ignore
102
+ self.render_finish()
103
+
104
+ def __iter__(self) -> t.Iterator[V]:
105
+ if not self.entered:
106
+ raise RuntimeError("You need to use progress bars in a with block.")
107
+ self.render_progress()
108
+ return self.generator()
109
+
110
+ def __next__(self) -> V:
111
+ # Iteration is defined in terms of a generator function,
112
+ # returned by iter(self); use that to define next(). This works
113
+ # because `self.iter` is an iterable consumed by that generator,
114
+ # so it is re-entry safe. Calling `next(self.generator())`
115
+ # twice works and does "what you want".
116
+ return next(iter(self))
117
+
118
+ def render_finish(self) -> None:
119
+ if self.is_hidden:
120
+ return
121
+ self.file.write(AFTER_BAR)
122
+ self.file.flush()
123
+
124
+ @property
125
+ def pct(self) -> float:
126
+ if self.finished:
127
+ return 1.0
128
+ return min(self.pos / (float(self.length or 1) or 1), 1.0)
129
+
130
+ @property
131
+ def time_per_iteration(self) -> float:
132
+ if not self.avg:
133
+ return 0.0
134
+ return sum(self.avg) / float(len(self.avg))
135
+
136
+ @property
137
+ def eta(self) -> float:
138
+ if self.length is not None and not self.finished:
139
+ return self.time_per_iteration * (self.length - self.pos)
140
+ return 0.0
141
+
142
+ def format_eta(self) -> str:
143
+ if self.eta_known:
144
+ t = int(self.eta)
145
+ seconds = t % 60
146
+ t //= 60
147
+ minutes = t % 60
148
+ t //= 60
149
+ hours = t % 24
150
+ t //= 24
151
+ if t > 0:
152
+ return f"{t}d {hours:02}:{minutes:02}:{seconds:02}"
153
+ else:
154
+ return f"{hours:02}:{minutes:02}:{seconds:02}"
155
+ return ""
156
+
157
+ def format_pos(self) -> str:
158
+ pos = str(self.pos)
159
+ if self.length is not None:
160
+ pos += f"/{self.length}"
161
+ return pos
162
+
163
+ def format_pct(self) -> str:
164
+ return f"{int(self.pct * 100): 4}%"[1:]
165
+
166
+ def format_bar(self) -> str:
167
+ if self.length is not None:
168
+ bar_length = int(self.pct * self.width)
169
+ bar = self.fill_char * bar_length
170
+ bar += self.empty_char * (self.width - bar_length)
171
+ elif self.finished:
172
+ bar = self.fill_char * self.width
173
+ else:
174
+ chars = list(self.empty_char * (self.width or 1))
175
+ if self.time_per_iteration != 0:
176
+ chars[
177
+ int(
178
+ (math.cos(self.pos * self.time_per_iteration) / 2.0 + 0.5)
179
+ * self.width
180
+ )
181
+ ] = self.fill_char
182
+ bar = "".join(chars)
183
+ return bar
184
+
185
+ def format_progress_line(self) -> str:
186
+ show_percent = self.show_percent
187
+
188
+ info_bits = []
189
+ if self.length is not None and show_percent is None:
190
+ show_percent = not self.show_pos
191
+
192
+ if self.show_pos:
193
+ info_bits.append(self.format_pos())
194
+ if show_percent:
195
+ info_bits.append(self.format_pct())
196
+ if self.show_eta and self.eta_known and not self.finished:
197
+ info_bits.append(self.format_eta())
198
+ if self.item_show_func is not None:
199
+ item_info = self.item_show_func(self.current_item)
200
+ if item_info is not None:
201
+ info_bits.append(item_info)
202
+
203
+ return (
204
+ self.bar_template
205
+ % {
206
+ "label": self.label,
207
+ "bar": self.format_bar(),
208
+ "info": self.info_sep.join(info_bits),
209
+ }
210
+ ).rstrip()
211
+
212
+ def render_progress(self) -> None:
213
+ import shutil
214
+
215
+ if self.is_hidden:
216
+ # Only output the label as it changes if the output is not a
217
+ # TTY. Use file=stderr if you expect to be piping stdout.
218
+ if self._last_line != self.label:
219
+ self._last_line = self.label
220
+ echo(self.label, file=self.file, color=self.color)
221
+
222
+ return
223
+
224
+ buf = []
225
+ # Update width in case the terminal has been resized
226
+ if self.autowidth:
227
+ old_width = self.width
228
+ self.width = 0
229
+ clutter_length = term_len(self.format_progress_line())
230
+ new_width = max(0, shutil.get_terminal_size().columns - clutter_length)
231
+ if new_width < old_width:
232
+ buf.append(BEFORE_BAR)
233
+ buf.append(" " * self.max_width) # type: ignore
234
+ self.max_width = new_width
235
+ self.width = new_width
236
+
237
+ clear_width = self.width
238
+ if self.max_width is not None:
239
+ clear_width = self.max_width
240
+
241
+ buf.append(BEFORE_BAR)
242
+ line = self.format_progress_line()
243
+ line_len = term_len(line)
244
+ if self.max_width is None or self.max_width < line_len:
245
+ self.max_width = line_len
246
+
247
+ buf.append(line)
248
+ buf.append(" " * (clear_width - line_len))
249
+ line = "".join(buf)
250
+ # Render the line only if it changed.
251
+
252
+ if line != self._last_line:
253
+ self._last_line = line
254
+ echo(line, file=self.file, color=self.color, nl=False)
255
+ self.file.flush()
256
+
257
+ def make_step(self, n_steps: int) -> None:
258
+ self.pos += n_steps
259
+ if self.length is not None and self.pos >= self.length:
260
+ self.finished = True
261
+
262
+ if (time.time() - self.last_eta) < 1.0:
263
+ return
264
+
265
+ self.last_eta = time.time()
266
+
267
+ # self.avg is a rolling list of length <= 7 of steps where steps are
268
+ # defined as time elapsed divided by the total progress through
269
+ # self.length.
270
+ if self.pos:
271
+ step = (time.time() - self.start) / self.pos
272
+ else:
273
+ step = time.time() - self.start
274
+
275
+ self.avg = self.avg[-6:] + [step]
276
+
277
+ self.eta_known = self.length is not None
278
+
279
+ def update(self, n_steps: int, current_item: t.Optional[V] = None) -> None:
280
+ """Update the progress bar by advancing a specified number of
281
+ steps, and optionally set the ``current_item`` for this new
282
+ position.
283
+
284
+ :param n_steps: Number of steps to advance.
285
+ :param current_item: Optional item to set as ``current_item``
286
+ for the updated position.
287
+
288
+ .. versionchanged:: 8.0
289
+ Added the ``current_item`` optional parameter.
290
+
291
+ .. versionchanged:: 8.0
292
+ Only render when the number of steps meets the
293
+ ``update_min_steps`` threshold.
294
+ """
295
+ if current_item is not None:
296
+ self.current_item = current_item
297
+
298
+ self._completed_intervals += n_steps
299
+
300
+ if self._completed_intervals >= self.update_min_steps:
301
+ self.make_step(self._completed_intervals)
302
+ self.render_progress()
303
+ self._completed_intervals = 0
304
+
305
+ def finish(self) -> None:
306
+ self.eta_known = False
307
+ self.current_item = None
308
+ self.finished = True
309
+
310
+ def generator(self) -> t.Iterator[V]:
311
+ """Return a generator which yields the items added to the bar
312
+ during construction, and updates the progress bar *after* the
313
+ yielded block returns.
314
+ """
315
+ # WARNING: the iterator interface for `ProgressBar` relies on
316
+ # this and only works because this is a simple generator which
317
+ # doesn't create or manage additional state. If this function
318
+ # changes, the impact should be evaluated both against
319
+ # `iter(bar)` and `next(bar)`. `next()` in particular may call
320
+ # `self.generator()` repeatedly, and this must remain safe in
321
+ # order for that interface to work.
322
+ if not self.entered:
323
+ raise RuntimeError("You need to use progress bars in a with block.")
324
+
325
+ if self.is_hidden:
326
+ yield from self.iter
327
+ else:
328
+ for rv in self.iter:
329
+ self.current_item = rv
330
+
331
+ # This allows show_item_func to be updated before the
332
+ # item is processed. Only trigger at the beginning of
333
+ # the update interval.
334
+ if self._completed_intervals == 0:
335
+ self.render_progress()
336
+
337
+ yield rv
338
+ self.update(1)
339
+
340
+ self.finish()
341
+ self.render_progress()
342
+
343
+
344
+ def pager(generator: t.Iterable[str], color: t.Optional[bool] = None) -> None:
345
+ """Decide what method to use for paging through text."""
346
+ stdout = _default_text_stdout()
347
+ if not isatty(sys.stdin) or not isatty(stdout):
348
+ return _nullpager(stdout, generator, color)
349
+ pager_cmd = (os.environ.get("PAGER", None) or "").strip()
350
+ if pager_cmd:
351
+ if WIN:
352
+ return _tempfilepager(generator, pager_cmd, color)
353
+ return _pipepager(generator, pager_cmd, color)
354
+ if os.environ.get("TERM") in ("dumb", "emacs"):
355
+ return _nullpager(stdout, generator, color)
356
+ if WIN or sys.platform.startswith("os2"):
357
+ return _tempfilepager(generator, "more <", color)
358
+ if hasattr(os, "system") and os.system("(less) 2>/dev/null") == 0:
359
+ return _pipepager(generator, "less", color)
360
+
361
+ import tempfile
362
+
363
+ fd, filename = tempfile.mkstemp()
364
+ os.close(fd)
365
+ try:
366
+ if hasattr(os, "system") and os.system(f'more "{filename}"') == 0:
367
+ return _pipepager(generator, "more", color)
368
+ return _nullpager(stdout, generator, color)
369
+ finally:
370
+ os.unlink(filename)
371
+
372
+
373
+ def _pipepager(generator: t.Iterable[str], cmd: str, color: t.Optional[bool]) -> None:
374
+ """Page through text by feeding it to another program. Invoking a
375
+ pager through this might support colors.
376
+ """
377
+ import subprocess
378
+
379
+ env = dict(os.environ)
380
+
381
+ # If we're piping to less we might support colors under the
382
+ # condition that
383
+ cmd_detail = cmd.rsplit("/", 1)[-1].split()
384
+ if color is None and cmd_detail[0] == "less":
385
+ less_flags = f"{os.environ.get('LESS', '')}{' '.join(cmd_detail[1:])}"
386
+ if not less_flags:
387
+ env["LESS"] = "-R"
388
+ color = True
389
+ elif "r" in less_flags or "R" in less_flags:
390
+ color = True
391
+
392
+ c = subprocess.Popen(cmd, shell=True, stdin=subprocess.PIPE, env=env)
393
+ stdin = t.cast(t.BinaryIO, c.stdin)
394
+ encoding = get_best_encoding(stdin)
395
+ try:
396
+ for text in generator:
397
+ if not color:
398
+ text = strip_ansi(text)
399
+
400
+ stdin.write(text.encode(encoding, "replace"))
401
+ except (OSError, KeyboardInterrupt):
402
+ pass
403
+ else:
404
+ stdin.close()
405
+
406
+ # Less doesn't respect ^C, but catches it for its own UI purposes (aborting
407
+ # search or other commands inside less).
408
+ #
409
+ # That means when the user hits ^C, the parent process (click) terminates,
410
+ # but less is still alive, paging the output and messing up the terminal.
411
+ #
412
+ # If the user wants to make the pager exit on ^C, they should set
413
+ # `LESS='-K'`. It's not our decision to make.
414
+ while True:
415
+ try:
416
+ c.wait()
417
+ except KeyboardInterrupt:
418
+ pass
419
+ else:
420
+ break
421
+
422
+
423
+ def _tempfilepager(
424
+ generator: t.Iterable[str], cmd: str, color: t.Optional[bool]
425
+ ) -> None:
426
+ """Page through text by invoking a program on a temporary file."""
427
+ import tempfile
428
+
429
+ fd, filename = tempfile.mkstemp()
430
+ # TODO: This never terminates if the passed generator never terminates.
431
+ text = "".join(generator)
432
+ if not color:
433
+ text = strip_ansi(text)
434
+ encoding = get_best_encoding(sys.stdout)
435
+ with open_stream(filename, "wb")[0] as f:
436
+ f.write(text.encode(encoding))
437
+ try:
438
+ os.system(f'{cmd} "{filename}"')
439
+ finally:
440
+ os.close(fd)
441
+ os.unlink(filename)
442
+
443
+
444
+ def _nullpager(
445
+ stream: t.TextIO, generator: t.Iterable[str], color: t.Optional[bool]
446
+ ) -> None:
447
+ """Simply print unformatted text. This is the ultimate fallback."""
448
+ for text in generator:
449
+ if not color:
450
+ text = strip_ansi(text)
451
+ stream.write(text)
452
+
453
+
454
+ class Editor:
455
+ def __init__(
456
+ self,
457
+ editor: t.Optional[str] = None,
458
+ env: t.Optional[t.Mapping[str, str]] = None,
459
+ require_save: bool = True,
460
+ extension: str = ".txt",
461
+ ) -> None:
462
+ self.editor = editor
463
+ self.env = env
464
+ self.require_save = require_save
465
+ self.extension = extension
466
+
467
+ def get_editor(self) -> str:
468
+ if self.editor is not None:
469
+ return self.editor
470
+ for key in "VISUAL", "EDITOR":
471
+ rv = os.environ.get(key)
472
+ if rv:
473
+ return rv
474
+ if WIN:
475
+ return "notepad"
476
+ for editor in "sensible-editor", "vim", "nano":
477
+ if os.system(f"which {editor} >/dev/null 2>&1") == 0:
478
+ return editor
479
+ return "vi"
480
+
481
+ def edit_file(self, filename: str) -> None:
482
+ import subprocess
483
+
484
+ editor = self.get_editor()
485
+ environ: t.Optional[t.Dict[str, str]] = None
486
+
487
+ if self.env:
488
+ environ = os.environ.copy()
489
+ environ.update(self.env)
490
+
491
+ try:
492
+ c = subprocess.Popen(f'{editor} "{filename}"', env=environ, shell=True)
493
+ exit_code = c.wait()
494
+ if exit_code != 0:
495
+ raise ClickException(
496
+ _("{editor}: Editing failed").format(editor=editor)
497
+ )
498
+ except OSError as e:
499
+ raise ClickException(
500
+ _("{editor}: Editing failed: {e}").format(editor=editor, e=e)
501
+ ) from e
502
+
503
+ def edit(self, text: t.Optional[t.AnyStr]) -> t.Optional[t.AnyStr]:
504
+ import tempfile
505
+
506
+ if not text:
507
+ data = b""
508
+ elif isinstance(text, (bytes, bytearray)):
509
+ data = text
510
+ else:
511
+ if text and not text.endswith("\n"):
512
+ text += "\n"
513
+
514
+ if WIN:
515
+ data = text.replace("\n", "\r\n").encode("utf-8-sig")
516
+ else:
517
+ data = text.encode("utf-8")
518
+
519
+ fd, name = tempfile.mkstemp(prefix="editor-", suffix=self.extension)
520
+ f: t.BinaryIO
521
+
522
+ try:
523
+ with os.fdopen(fd, "wb") as f:
524
+ f.write(data)
525
+
526
+ # If the filesystem resolution is 1 second, like Mac OS
527
+ # 10.12 Extended, or 2 seconds, like FAT32, and the editor
528
+ # closes very fast, require_save can fail. Set the modified
529
+ # time to be 2 seconds in the past to work around this.
530
+ os.utime(name, (os.path.getatime(name), os.path.getmtime(name) - 2))
531
+ # Depending on the resolution, the exact value might not be
532
+ # recorded, so get the new recorded value.
533
+ timestamp = os.path.getmtime(name)
534
+
535
+ self.edit_file(name)
536
+
537
+ if self.require_save and os.path.getmtime(name) == timestamp:
538
+ return None
539
+
540
+ with open(name, "rb") as f:
541
+ rv = f.read()
542
+
543
+ if isinstance(text, (bytes, bytearray)):
544
+ return rv
545
+
546
+ return rv.decode("utf-8-sig").replace("\r\n", "\n") # type: ignore
547
+ finally:
548
+ os.unlink(name)
549
+
550
+
551
+ def open_url(url: str, wait: bool = False, locate: bool = False) -> int:
552
+ import subprocess
553
+
554
+ def _unquote_file(url: str) -> str:
555
+ from urllib.parse import unquote
556
+
557
+ if url.startswith("file://"):
558
+ url = unquote(url[7:])
559
+
560
+ return url
561
+
562
+ if sys.platform == "darwin":
563
+ args = ["open"]
564
+ if wait:
565
+ args.append("-W")
566
+ if locate:
567
+ args.append("-R")
568
+ args.append(_unquote_file(url))
569
+ null = open("/dev/null", "w")
570
+ try:
571
+ return subprocess.Popen(args, stderr=null).wait()
572
+ finally:
573
+ null.close()
574
+ elif WIN:
575
+ if locate:
576
+ url = _unquote_file(url.replace('"', ""))
577
+ args = f'explorer /select,"{url}"'
578
+ else:
579
+ url = url.replace('"', "")
580
+ wait_str = "/WAIT" if wait else ""
581
+ args = f'start {wait_str} "" "{url}"'
582
+ return os.system(args)
583
+ elif CYGWIN:
584
+ if locate:
585
+ url = os.path.dirname(_unquote_file(url).replace('"', ""))
586
+ args = f'cygstart "{url}"'
587
+ else:
588
+ url = url.replace('"', "")
589
+ wait_str = "-w" if wait else ""
590
+ args = f'cygstart {wait_str} "{url}"'
591
+ return os.system(args)
592
+
593
+ try:
594
+ if locate:
595
+ url = os.path.dirname(_unquote_file(url)) or "."
596
+ else:
597
+ url = _unquote_file(url)
598
+ c = subprocess.Popen(["xdg-open", url])
599
+ if wait:
600
+ return c.wait()
601
+ return 0
602
+ except OSError:
603
+ if url.startswith(("http://", "https://")) and not locate and not wait:
604
+ import webbrowser
605
+
606
+ webbrowser.open(url)
607
+ return 0
608
+ return 1
609
+
610
+
611
+ def _translate_ch_to_exc(ch: str) -> t.Optional[BaseException]:
612
+ if ch == "\x03":
613
+ raise KeyboardInterrupt()
614
+
615
+ if ch == "\x04" and not WIN: # Unix-like, Ctrl+D
616
+ raise EOFError()
617
+
618
+ if ch == "\x1a" and WIN: # Windows, Ctrl+Z
619
+ raise EOFError()
620
+
621
+ return None
622
+
623
+
624
+ if WIN:
625
+ import msvcrt
626
+
627
+ @contextlib.contextmanager
628
+ def raw_terminal() -> t.Iterator[int]:
629
+ yield -1
630
+
631
+ def getchar(echo: bool) -> str:
632
+ # The function `getch` will return a bytes object corresponding to
633
+ # the pressed character. Since Windows 10 build 1803, it will also
634
+ # return \x00 when called a second time after pressing a regular key.
635
+ #
636
+ # `getwch` does not share this probably-bugged behavior. Moreover, it
637
+ # returns a Unicode object by default, which is what we want.
638
+ #
639
+ # Either of these functions will return \x00 or \xe0 to indicate
640
+ # a special key, and you need to call the same function again to get
641
+ # the "rest" of the code. The fun part is that \u00e0 is
642
+ # "latin small letter a with grave", so if you type that on a French
643
+ # keyboard, you _also_ get a \xe0.
644
+ # E.g., consider the Up arrow. This returns \xe0 and then \x48. The
645
+ # resulting Unicode string reads as "a with grave" + "capital H".
646
+ # This is indistinguishable from when the user actually types
647
+ # "a with grave" and then "capital H".
648
+ #
649
+ # When \xe0 is returned, we assume it's part of a special-key sequence
650
+ # and call `getwch` again, but that means that when the user types
651
+ # the \u00e0 character, `getchar` doesn't return until a second
652
+ # character is typed.
653
+ # The alternative is returning immediately, but that would mess up
654
+ # cross-platform handling of arrow keys and others that start with
655
+ # \xe0. Another option is using `getch`, but then we can't reliably
656
+ # read non-ASCII characters, because return values of `getch` are
657
+ # limited to the current 8-bit codepage.
658
+ #
659
+ # Anyway, Click doesn't claim to do this Right(tm), and using `getwch`
660
+ # is doing the right thing in more situations than with `getch`.
661
+ func: t.Callable[[], str]
662
+
663
+ if echo:
664
+ func = msvcrt.getwche # type: ignore
665
+ else:
666
+ func = msvcrt.getwch # type: ignore
667
+
668
+ rv = func()
669
+
670
+ if rv in ("\x00", "\xe0"):
671
+ # \x00 and \xe0 are control characters that indicate special key,
672
+ # see above.
673
+ rv += func()
674
+
675
+ _translate_ch_to_exc(rv)
676
+ return rv
677
+
678
+ else:
679
+ import tty
680
+ import termios
681
+
682
+ @contextlib.contextmanager
683
+ def raw_terminal() -> t.Iterator[int]:
684
+ f: t.Optional[t.TextIO]
685
+ fd: int
686
+
687
+ if not isatty(sys.stdin):
688
+ f = open("/dev/tty")
689
+ fd = f.fileno()
690
+ else:
691
+ fd = sys.stdin.fileno()
692
+ f = None
693
+
694
+ try:
695
+ old_settings = termios.tcgetattr(fd)
696
+
697
+ try:
698
+ tty.setraw(fd)
699
+ yield fd
700
+ finally:
701
+ termios.tcsetattr(fd, termios.TCSADRAIN, old_settings)
702
+ sys.stdout.flush()
703
+
704
+ if f is not None:
705
+ f.close()
706
+ except termios.error:
707
+ pass
708
+
709
+ def getchar(echo: bool) -> str:
710
+ with raw_terminal() as fd:
711
+ ch = os.read(fd, 32).decode(get_best_encoding(sys.stdin), "replace")
712
+
713
+ if echo and isatty(sys.stdout):
714
+ sys.stdout.write(ch)
715
+
716
+ _translate_ch_to_exc(ch)
717
+ return ch
my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/google_auth-2.9.0-py3.10-nspkg.pth ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:c47e604f1738522a583f7aab6cffb80821cd18157dede051e10aa185e0af065e
3
+ size 539
my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/grpc/__init__.py ADDED
@@ -0,0 +1,2190 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2015-2016 gRPC authors.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+ """gRPC's Python API."""
15
+
16
+ import abc
17
+ import contextlib
18
+ import enum
19
+ import logging
20
+ import sys
21
+
22
+ from grpc import _compression
23
+ from grpc._cython import cygrpc as _cygrpc
24
+ from grpc._runtime_protos import protos
25
+ from grpc._runtime_protos import protos_and_services
26
+ from grpc._runtime_protos import services
27
+ import six
28
+
29
+ logging.getLogger(__name__).addHandler(logging.NullHandler())
30
+
31
+ try:
32
+ # pylint: disable=ungrouped-imports
33
+ from grpc._grpcio_metadata import __version__
34
+ except ImportError:
35
+ __version__ = "dev0"
36
+
37
+ ############################## Future Interface ###############################
38
+
39
+
40
+ class FutureTimeoutError(Exception):
41
+ """Indicates that a method call on a Future timed out."""
42
+
43
+
44
+ class FutureCancelledError(Exception):
45
+ """Indicates that the computation underlying a Future was cancelled."""
46
+
47
+
48
+ class Future(six.with_metaclass(abc.ABCMeta)):
49
+ """A representation of a computation in another control flow.
50
+
51
+ Computations represented by a Future may be yet to be begun,
52
+ may be ongoing, or may have already completed.
53
+ """
54
+
55
+ @abc.abstractmethod
56
+ def cancel(self):
57
+ """Attempts to cancel the computation.
58
+
59
+ This method does not block.
60
+
61
+ Returns:
62
+ bool:
63
+ Returns True if the computation was canceled.
64
+
65
+ Returns False under all other circumstances, for example:
66
+
67
+ 1. computation has begun and could not be canceled.
68
+ 2. computation has finished
69
+ 3. computation is scheduled for execution and it is impossible
70
+ to determine its state without blocking.
71
+ """
72
+ raise NotImplementedError()
73
+
74
+ @abc.abstractmethod
75
+ def cancelled(self):
76
+ """Describes whether the computation was cancelled.
77
+
78
+ This method does not block.
79
+
80
+ Returns:
81
+ bool:
82
+ Returns True if the computation was cancelled before its result became
83
+ available.
84
+
85
+ Returns False under all other circumstances, for example:
86
+
87
+ 1. computation was not cancelled.
88
+ 2. computation's result is available.
89
+ """
90
+ raise NotImplementedError()
91
+
92
+ @abc.abstractmethod
93
+ def running(self):
94
+ """Describes whether the computation is taking place.
95
+
96
+ This method does not block.
97
+
98
+ Returns:
99
+ Returns True if the computation is scheduled for execution or
100
+ currently executing.
101
+
102
+ Returns False if the computation already executed or was cancelled.
103
+ """
104
+ raise NotImplementedError()
105
+
106
+ @abc.abstractmethod
107
+ def done(self):
108
+ """Describes whether the computation has taken place.
109
+
110
+ This method does not block.
111
+
112
+ Returns:
113
+ bool:
114
+ Returns True if the computation already executed or was cancelled.
115
+ Returns False if the computation is scheduled for execution or
116
+ currently executing.
117
+ This is exactly opposite of the running() method's result.
118
+ """
119
+ raise NotImplementedError()
120
+
121
+ @abc.abstractmethod
122
+ def result(self, timeout=None):
123
+ """Returns the result of the computation or raises its exception.
124
+
125
+ This method may return immediately or may block.
126
+
127
+ Args:
128
+ timeout: The length of time in seconds to wait for the computation to
129
+ finish or be cancelled. If None, the call will block until the
130
+ computations's termination.
131
+
132
+ Returns:
133
+ The return value of the computation.
134
+
135
+ Raises:
136
+ FutureTimeoutError: If a timeout value is passed and the computation
137
+ does not terminate within the allotted time.
138
+ FutureCancelledError: If the computation was cancelled.
139
+ Exception: If the computation raised an exception, this call will
140
+ raise the same exception.
141
+ """
142
+ raise NotImplementedError()
143
+
144
+ @abc.abstractmethod
145
+ def exception(self, timeout=None):
146
+ """Return the exception raised by the computation.
147
+
148
+ This method may return immediately or may block.
149
+
150
+ Args:
151
+ timeout: The length of time in seconds to wait for the computation to
152
+ terminate or be cancelled. If None, the call will block until the
153
+ computations's termination.
154
+
155
+ Returns:
156
+ The exception raised by the computation, or None if the computation
157
+ did not raise an exception.
158
+
159
+ Raises:
160
+ FutureTimeoutError: If a timeout value is passed and the computation
161
+ does not terminate within the allotted time.
162
+ FutureCancelledError: If the computation was cancelled.
163
+ """
164
+ raise NotImplementedError()
165
+
166
+ @abc.abstractmethod
167
+ def traceback(self, timeout=None):
168
+ """Access the traceback of the exception raised by the computation.
169
+
170
+ This method may return immediately or may block.
171
+
172
+ Args:
173
+ timeout: The length of time in seconds to wait for the computation
174
+ to terminate or be cancelled. If None, the call will block until
175
+ the computation's termination.
176
+
177
+ Returns:
178
+ The traceback of the exception raised by the computation, or None
179
+ if the computation did not raise an exception.
180
+
181
+ Raises:
182
+ FutureTimeoutError: If a timeout value is passed and the computation
183
+ does not terminate within the allotted time.
184
+ FutureCancelledError: If the computation was cancelled.
185
+ """
186
+ raise NotImplementedError()
187
+
188
+ @abc.abstractmethod
189
+ def add_done_callback(self, fn):
190
+ """Adds a function to be called at completion of the computation.
191
+
192
+ The callback will be passed this Future object describing the outcome
193
+ of the computation. Callbacks will be invoked after the future is
194
+ terminated, whether successfully or not.
195
+
196
+ If the computation has already completed, the callback will be called
197
+ immediately.
198
+
199
+ Exceptions raised in the callback will be logged at ERROR level, but
200
+ will not terminate any threads of execution.
201
+
202
+ Args:
203
+ fn: A callable taking this Future object as its single parameter.
204
+ """
205
+ raise NotImplementedError()
206
+
207
+
208
+ ################################ gRPC Enums ##################################
209
+
210
+
211
+ @enum.unique
212
+ class ChannelConnectivity(enum.Enum):
213
+ """Mirrors grpc_connectivity_state in the gRPC Core.
214
+
215
+ Attributes:
216
+ IDLE: The channel is idle.
217
+ CONNECTING: The channel is connecting.
218
+ READY: The channel is ready to conduct RPCs.
219
+ TRANSIENT_FAILURE: The channel has seen a failure from which it expects
220
+ to recover.
221
+ SHUTDOWN: The channel has seen a failure from which it cannot recover.
222
+ """
223
+ IDLE = (_cygrpc.ConnectivityState.idle, 'idle')
224
+ CONNECTING = (_cygrpc.ConnectivityState.connecting, 'connecting')
225
+ READY = (_cygrpc.ConnectivityState.ready, 'ready')
226
+ TRANSIENT_FAILURE = (_cygrpc.ConnectivityState.transient_failure,
227
+ 'transient failure')
228
+ SHUTDOWN = (_cygrpc.ConnectivityState.shutdown, 'shutdown')
229
+
230
+
231
+ @enum.unique
232
+ class StatusCode(enum.Enum):
233
+ """Mirrors grpc_status_code in the gRPC Core.
234
+
235
+ Attributes:
236
+ OK: Not an error; returned on success
237
+ CANCELLED: The operation was cancelled (typically by the caller).
238
+ UNKNOWN: Unknown error.
239
+ INVALID_ARGUMENT: Client specified an invalid argument.
240
+ DEADLINE_EXCEEDED: Deadline expired before operation could complete.
241
+ NOT_FOUND: Some requested entity (e.g., file or directory) was not found.
242
+ ALREADY_EXISTS: Some entity that we attempted to create (e.g., file or directory)
243
+ already exists.
244
+ PERMISSION_DENIED: The caller does not have permission to execute the specified
245
+ operation.
246
+ UNAUTHENTICATED: The request does not have valid authentication credentials for the
247
+ operation.
248
+ RESOURCE_EXHAUSTED: Some resource has been exhausted, perhaps a per-user quota, or
249
+ perhaps the entire file system is out of space.
250
+ FAILED_PRECONDITION: Operation was rejected because the system is not in a state
251
+ required for the operation's execution.
252
+ ABORTED: The operation was aborted, typically due to a concurrency issue
253
+ like sequencer check failures, transaction aborts, etc.
254
+ UNIMPLEMENTED: Operation is not implemented or not supported/enabled in this service.
255
+ INTERNAL: Internal errors. Means some invariants expected by underlying
256
+ system has been broken.
257
+ UNAVAILABLE: The service is currently unavailable.
258
+ DATA_LOSS: Unrecoverable data loss or corruption.
259
+ """
260
+ OK = (_cygrpc.StatusCode.ok, 'ok')
261
+ CANCELLED = (_cygrpc.StatusCode.cancelled, 'cancelled')
262
+ UNKNOWN = (_cygrpc.StatusCode.unknown, 'unknown')
263
+ INVALID_ARGUMENT = (_cygrpc.StatusCode.invalid_argument, 'invalid argument')
264
+ DEADLINE_EXCEEDED = (_cygrpc.StatusCode.deadline_exceeded,
265
+ 'deadline exceeded')
266
+ NOT_FOUND = (_cygrpc.StatusCode.not_found, 'not found')
267
+ ALREADY_EXISTS = (_cygrpc.StatusCode.already_exists, 'already exists')
268
+ PERMISSION_DENIED = (_cygrpc.StatusCode.permission_denied,
269
+ 'permission denied')
270
+ RESOURCE_EXHAUSTED = (_cygrpc.StatusCode.resource_exhausted,
271
+ 'resource exhausted')
272
+ FAILED_PRECONDITION = (_cygrpc.StatusCode.failed_precondition,
273
+ 'failed precondition')
274
+ ABORTED = (_cygrpc.StatusCode.aborted, 'aborted')
275
+ OUT_OF_RANGE = (_cygrpc.StatusCode.out_of_range, 'out of range')
276
+ UNIMPLEMENTED = (_cygrpc.StatusCode.unimplemented, 'unimplemented')
277
+ INTERNAL = (_cygrpc.StatusCode.internal, 'internal')
278
+ UNAVAILABLE = (_cygrpc.StatusCode.unavailable, 'unavailable')
279
+ DATA_LOSS = (_cygrpc.StatusCode.data_loss, 'data loss')
280
+ UNAUTHENTICATED = (_cygrpc.StatusCode.unauthenticated, 'unauthenticated')
281
+
282
+
283
+ ############################# gRPC Status ################################
284
+
285
+
286
+ class Status(six.with_metaclass(abc.ABCMeta)):
287
+ """Describes the status of an RPC.
288
+
289
+ This is an EXPERIMENTAL API.
290
+
291
+ Attributes:
292
+ code: A StatusCode object to be sent to the client.
293
+ details: A UTF-8-encodable string to be sent to the client upon
294
+ termination of the RPC.
295
+ trailing_metadata: The trailing :term:`metadata` in the RPC.
296
+ """
297
+
298
+
299
+ ############################# gRPC Exceptions ################################
300
+
301
+
302
+ class RpcError(Exception):
303
+ """Raised by the gRPC library to indicate non-OK-status RPC termination."""
304
+
305
+
306
+ ############################## Shared Context ################################
307
+
308
+
309
+ class RpcContext(six.with_metaclass(abc.ABCMeta)):
310
+ """Provides RPC-related information and action."""
311
+
312
+ @abc.abstractmethod
313
+ def is_active(self):
314
+ """Describes whether the RPC is active or has terminated.
315
+
316
+ Returns:
317
+ bool:
318
+ True if RPC is active, False otherwise.
319
+ """
320
+ raise NotImplementedError()
321
+
322
+ @abc.abstractmethod
323
+ def time_remaining(self):
324
+ """Describes the length of allowed time remaining for the RPC.
325
+
326
+ Returns:
327
+ A nonnegative float indicating the length of allowed time in seconds
328
+ remaining for the RPC to complete before it is considered to have
329
+ timed out, or None if no deadline was specified for the RPC.
330
+ """
331
+ raise NotImplementedError()
332
+
333
+ @abc.abstractmethod
334
+ def cancel(self):
335
+ """Cancels the RPC.
336
+
337
+ Idempotent and has no effect if the RPC has already terminated.
338
+ """
339
+ raise NotImplementedError()
340
+
341
+ @abc.abstractmethod
342
+ def add_callback(self, callback):
343
+ """Registers a callback to be called on RPC termination.
344
+
345
+ Args:
346
+ callback: A no-parameter callable to be called on RPC termination.
347
+
348
+ Returns:
349
+ True if the callback was added and will be called later; False if
350
+ the callback was not added and will not be called (because the RPC
351
+ already terminated or some other reason).
352
+ """
353
+ raise NotImplementedError()
354
+
355
+
356
+ ######################### Invocation-Side Context ############################
357
+
358
+
359
+ class Call(six.with_metaclass(abc.ABCMeta, RpcContext)):
360
+ """Invocation-side utility object for an RPC."""
361
+
362
+ @abc.abstractmethod
363
+ def initial_metadata(self):
364
+ """Accesses the initial metadata sent by the server.
365
+
366
+ This method blocks until the value is available.
367
+
368
+ Returns:
369
+ The initial :term:`metadata`.
370
+ """
371
+ raise NotImplementedError()
372
+
373
+ @abc.abstractmethod
374
+ def trailing_metadata(self):
375
+ """Accesses the trailing metadata sent by the server.
376
+
377
+ This method blocks until the value is available.
378
+
379
+ Returns:
380
+ The trailing :term:`metadata`.
381
+ """
382
+ raise NotImplementedError()
383
+
384
+ @abc.abstractmethod
385
+ def code(self):
386
+ """Accesses the status code sent by the server.
387
+
388
+ This method blocks until the value is available.
389
+
390
+ Returns:
391
+ The StatusCode value for the RPC.
392
+ """
393
+ raise NotImplementedError()
394
+
395
+ @abc.abstractmethod
396
+ def details(self):
397
+ """Accesses the details sent by the server.
398
+
399
+ This method blocks until the value is available.
400
+
401
+ Returns:
402
+ The details string of the RPC.
403
+ """
404
+ raise NotImplementedError()
405
+
406
+
407
+ ############## Invocation-Side Interceptor Interfaces & Classes ##############
408
+
409
+
410
+ class ClientCallDetails(six.with_metaclass(abc.ABCMeta)):
411
+ """Describes an RPC to be invoked.
412
+
413
+ Attributes:
414
+ method: The method name of the RPC.
415
+ timeout: An optional duration of time in seconds to allow for the RPC.
416
+ metadata: Optional :term:`metadata` to be transmitted to
417
+ the service-side of the RPC.
418
+ credentials: An optional CallCredentials for the RPC.
419
+ wait_for_ready: This is an EXPERIMENTAL argument. An optional
420
+ flag to enable :term:`wait_for_ready` mechanism.
421
+ compression: An element of grpc.compression, e.g.
422
+ grpc.compression.Gzip. This is an EXPERIMENTAL option.
423
+ """
424
+
425
+
426
+ class UnaryUnaryClientInterceptor(six.with_metaclass(abc.ABCMeta)):
427
+ """Affords intercepting unary-unary invocations."""
428
+
429
+ @abc.abstractmethod
430
+ def intercept_unary_unary(self, continuation, client_call_details, request):
431
+ """Intercepts a unary-unary invocation asynchronously.
432
+
433
+ Args:
434
+ continuation: A function that proceeds with the invocation by
435
+ executing the next interceptor in chain or invoking the
436
+ actual RPC on the underlying Channel. It is the interceptor's
437
+ responsibility to call it if it decides to move the RPC forward.
438
+ The interceptor can use
439
+ `response_future = continuation(client_call_details, request)`
440
+ to continue with the RPC. `continuation` returns an object that is
441
+ both a Call for the RPC and a Future. In the event of RPC
442
+ completion, the return Call-Future's result value will be
443
+ the response message of the RPC. Should the event terminate
444
+ with non-OK status, the returned Call-Future's exception value
445
+ will be an RpcError.
446
+ client_call_details: A ClientCallDetails object describing the
447
+ outgoing RPC.
448
+ request: The request value for the RPC.
449
+
450
+ Returns:
451
+ An object that is both a Call for the RPC and a Future.
452
+ In the event of RPC completion, the return Call-Future's
453
+ result value will be the response message of the RPC.
454
+ Should the event terminate with non-OK status, the returned
455
+ Call-Future's exception value will be an RpcError.
456
+ """
457
+ raise NotImplementedError()
458
+
459
+
460
+ class UnaryStreamClientInterceptor(six.with_metaclass(abc.ABCMeta)):
461
+ """Affords intercepting unary-stream invocations."""
462
+
463
+ @abc.abstractmethod
464
+ def intercept_unary_stream(self, continuation, client_call_details,
465
+ request):
466
+ """Intercepts a unary-stream invocation.
467
+
468
+ Args:
469
+ continuation: A function that proceeds with the invocation by
470
+ executing the next interceptor in chain or invoking the
471
+ actual RPC on the underlying Channel. It is the interceptor's
472
+ responsibility to call it if it decides to move the RPC forward.
473
+ The interceptor can use
474
+ `response_iterator = continuation(client_call_details, request)`
475
+ to continue with the RPC. `continuation` returns an object that is
476
+ both a Call for the RPC and an iterator for response values.
477
+ Drawing response values from the returned Call-iterator may
478
+ raise RpcError indicating termination of the RPC with non-OK
479
+ status.
480
+ client_call_details: A ClientCallDetails object describing the
481
+ outgoing RPC.
482
+ request: The request value for the RPC.
483
+
484
+ Returns:
485
+ An object that is both a Call for the RPC and an iterator of
486
+ response values. Drawing response values from the returned
487
+ Call-iterator may raise RpcError indicating termination of
488
+ the RPC with non-OK status. This object *should* also fulfill the
489
+ Future interface, though it may not.
490
+ """
491
+ raise NotImplementedError()
492
+
493
+
494
+ class StreamUnaryClientInterceptor(six.with_metaclass(abc.ABCMeta)):
495
+ """Affords intercepting stream-unary invocations."""
496
+
497
+ @abc.abstractmethod
498
+ def intercept_stream_unary(self, continuation, client_call_details,
499
+ request_iterator):
500
+ """Intercepts a stream-unary invocation asynchronously.
501
+
502
+ Args:
503
+ continuation: A function that proceeds with the invocation by
504
+ executing the next interceptor in chain or invoking the
505
+ actual RPC on the underlying Channel. It is the interceptor's
506
+ responsibility to call it if it decides to move the RPC forward.
507
+ The interceptor can use
508
+ `response_future = continuation(client_call_details, request_iterator)`
509
+ to continue with the RPC. `continuation` returns an object that is
510
+ both a Call for the RPC and a Future. In the event of RPC completion,
511
+ the return Call-Future's result value will be the response message
512
+ of the RPC. Should the event terminate with non-OK status, the
513
+ returned Call-Future's exception value will be an RpcError.
514
+ client_call_details: A ClientCallDetails object describing the
515
+ outgoing RPC.
516
+ request_iterator: An iterator that yields request values for the RPC.
517
+
518
+ Returns:
519
+ An object that is both a Call for the RPC and a Future.
520
+ In the event of RPC completion, the return Call-Future's
521
+ result value will be the response message of the RPC.
522
+ Should the event terminate with non-OK status, the returned
523
+ Call-Future's exception value will be an RpcError.
524
+ """
525
+ raise NotImplementedError()
526
+
527
+
528
+ class StreamStreamClientInterceptor(six.with_metaclass(abc.ABCMeta)):
529
+ """Affords intercepting stream-stream invocations."""
530
+
531
+ @abc.abstractmethod
532
+ def intercept_stream_stream(self, continuation, client_call_details,
533
+ request_iterator):
534
+ """Intercepts a stream-stream invocation.
535
+
536
+ Args:
537
+ continuation: A function that proceeds with the invocation by
538
+ executing the next interceptor in chain or invoking the
539
+ actual RPC on the underlying Channel. It is the interceptor's
540
+ responsibility to call it if it decides to move the RPC forward.
541
+ The interceptor can use
542
+ `response_iterator = continuation(client_call_details, request_iterator)`
543
+ to continue with the RPC. `continuation` returns an object that is
544
+ both a Call for the RPC and an iterator for response values.
545
+ Drawing response values from the returned Call-iterator may
546
+ raise RpcError indicating termination of the RPC with non-OK
547
+ status.
548
+ client_call_details: A ClientCallDetails object describing the
549
+ outgoing RPC.
550
+ request_iterator: An iterator that yields request values for the RPC.
551
+
552
+ Returns:
553
+ An object that is both a Call for the RPC and an iterator of
554
+ response values. Drawing response values from the returned
555
+ Call-iterator may raise RpcError indicating termination of
556
+ the RPC with non-OK status. This object *should* also fulfill the
557
+ Future interface, though it may not.
558
+ """
559
+ raise NotImplementedError()
560
+
561
+
562
+ ############ Authentication & Authorization Interfaces & Classes #############
563
+
564
+
565
+ class ChannelCredentials(object):
566
+ """An encapsulation of the data required to create a secure Channel.
567
+
568
+ This class has no supported interface - it exists to define the type of its
569
+ instances and its instances exist to be passed to other functions. For
570
+ example, ssl_channel_credentials returns an instance of this class and
571
+ secure_channel requires an instance of this class.
572
+ """
573
+
574
+ def __init__(self, credentials):
575
+ self._credentials = credentials
576
+
577
+
578
+ class CallCredentials(object):
579
+ """An encapsulation of the data required to assert an identity over a call.
580
+
581
+ A CallCredentials has to be used with secure Channel, otherwise the
582
+ metadata will not be transmitted to the server.
583
+
584
+ A CallCredentials may be composed with ChannelCredentials to always assert
585
+ identity for every call over that Channel.
586
+
587
+ This class has no supported interface - it exists to define the type of its
588
+ instances and its instances exist to be passed to other functions.
589
+ """
590
+
591
+ def __init__(self, credentials):
592
+ self._credentials = credentials
593
+
594
+
595
+ class AuthMetadataContext(six.with_metaclass(abc.ABCMeta)):
596
+ """Provides information to call credentials metadata plugins.
597
+
598
+ Attributes:
599
+ service_url: A string URL of the service being called into.
600
+ method_name: A string of the fully qualified method name being called.
601
+ """
602
+
603
+
604
+ class AuthMetadataPluginCallback(six.with_metaclass(abc.ABCMeta)):
605
+ """Callback object received by a metadata plugin."""
606
+
607
+ def __call__(self, metadata, error):
608
+ """Passes to the gRPC runtime authentication metadata for an RPC.
609
+
610
+ Args:
611
+ metadata: The :term:`metadata` used to construct the CallCredentials.
612
+ error: An Exception to indicate error or None to indicate success.
613
+ """
614
+ raise NotImplementedError()
615
+
616
+
617
+ class AuthMetadataPlugin(six.with_metaclass(abc.ABCMeta)):
618
+ """A specification for custom authentication."""
619
+
620
+ def __call__(self, context, callback):
621
+ """Implements authentication by passing metadata to a callback.
622
+
623
+ This method will be invoked asynchronously in a separate thread.
624
+
625
+ Args:
626
+ context: An AuthMetadataContext providing information on the RPC that
627
+ the plugin is being called to authenticate.
628
+ callback: An AuthMetadataPluginCallback to be invoked either
629
+ synchronously or asynchronously.
630
+ """
631
+ raise NotImplementedError()
632
+
633
+
634
+ class ServerCredentials(object):
635
+ """An encapsulation of the data required to open a secure port on a Server.
636
+
637
+ This class has no supported interface - it exists to define the type of its
638
+ instances and its instances exist to be passed to other functions.
639
+ """
640
+
641
+ def __init__(self, credentials):
642
+ self._credentials = credentials
643
+
644
+
645
+ class ServerCertificateConfiguration(object):
646
+ """A certificate configuration for use with an SSL-enabled Server.
647
+
648
+ Instances of this class can be returned in the certificate configuration
649
+ fetching callback.
650
+
651
+ This class has no supported interface -- it exists to define the
652
+ type of its instances and its instances exist to be passed to
653
+ other functions.
654
+ """
655
+
656
+ def __init__(self, certificate_configuration):
657
+ self._certificate_configuration = certificate_configuration
658
+
659
+
660
+ ######################## Multi-Callable Interfaces ###########################
661
+
662
+
663
+ class UnaryUnaryMultiCallable(six.with_metaclass(abc.ABCMeta)):
664
+ """Affords invoking a unary-unary RPC from client-side."""
665
+
666
+ @abc.abstractmethod
667
+ def __call__(self,
668
+ request,
669
+ timeout=None,
670
+ metadata=None,
671
+ credentials=None,
672
+ wait_for_ready=None,
673
+ compression=None):
674
+ """Synchronously invokes the underlying RPC.
675
+
676
+ Args:
677
+ request: The request value for the RPC.
678
+ timeout: An optional duration of time in seconds to allow
679
+ for the RPC.
680
+ metadata: Optional :term:`metadata` to be transmitted to the
681
+ service-side of the RPC.
682
+ credentials: An optional CallCredentials for the RPC. Only valid for
683
+ secure Channel.
684
+ wait_for_ready: This is an EXPERIMENTAL argument. An optional
685
+ flag to enable :term:`wait_for_ready` mechanism.
686
+ compression: An element of grpc.compression, e.g.
687
+ grpc.compression.Gzip. This is an EXPERIMENTAL option.
688
+
689
+ Returns:
690
+ The response value for the RPC.
691
+
692
+ Raises:
693
+ RpcError: Indicating that the RPC terminated with non-OK status. The
694
+ raised RpcError will also be a Call for the RPC affording the RPC's
695
+ metadata, status code, and details.
696
+ """
697
+ raise NotImplementedError()
698
+
699
+ @abc.abstractmethod
700
+ def with_call(self,
701
+ request,
702
+ timeout=None,
703
+ metadata=None,
704
+ credentials=None,
705
+ wait_for_ready=None,
706
+ compression=None):
707
+ """Synchronously invokes the underlying RPC.
708
+
709
+ Args:
710
+ request: The request value for the RPC.
711
+ timeout: An optional durating of time in seconds to allow for
712
+ the RPC.
713
+ metadata: Optional :term:`metadata` to be transmitted to the
714
+ service-side of the RPC.
715
+ credentials: An optional CallCredentials for the RPC. Only valid for
716
+ secure Channel.
717
+ wait_for_ready: This is an EXPERIMENTAL argument. An optional
718
+ flag to enable :term:`wait_for_ready` mechanism.
719
+ compression: An element of grpc.compression, e.g.
720
+ grpc.compression.Gzip. This is an EXPERIMENTAL option.
721
+
722
+ Returns:
723
+ The response value for the RPC and a Call value for the RPC.
724
+
725
+ Raises:
726
+ RpcError: Indicating that the RPC terminated with non-OK status. The
727
+ raised RpcError will also be a Call for the RPC affording the RPC's
728
+ metadata, status code, and details.
729
+ """
730
+ raise NotImplementedError()
731
+
732
+ @abc.abstractmethod
733
+ def future(self,
734
+ request,
735
+ timeout=None,
736
+ metadata=None,
737
+ credentials=None,
738
+ wait_for_ready=None,
739
+ compression=None):
740
+ """Asynchronously invokes the underlying RPC.
741
+
742
+ Args:
743
+ request: The request value for the RPC.
744
+ timeout: An optional duration of time in seconds to allow for
745
+ the RPC.
746
+ metadata: Optional :term:`metadata` to be transmitted to the
747
+ service-side of the RPC.
748
+ credentials: An optional CallCredentials for the RPC. Only valid for
749
+ secure Channel.
750
+ wait_for_ready: This is an EXPERIMENTAL argument. An optional
751
+ flag to enable :term:`wait_for_ready` mechanism.
752
+ compression: An element of grpc.compression, e.g.
753
+ grpc.compression.Gzip. This is an EXPERIMENTAL option.
754
+
755
+ Returns:
756
+ An object that is both a Call for the RPC and a Future.
757
+ In the event of RPC completion, the return Call-Future's result
758
+ value will be the response message of the RPC.
759
+ Should the event terminate with non-OK status,
760
+ the returned Call-Future's exception value will be an RpcError.
761
+ """
762
+ raise NotImplementedError()
763
+
764
+
765
+ class UnaryStreamMultiCallable(six.with_metaclass(abc.ABCMeta)):
766
+ """Affords invoking a unary-stream RPC from client-side."""
767
+
768
+ @abc.abstractmethod
769
+ def __call__(self,
770
+ request,
771
+ timeout=None,
772
+ metadata=None,
773
+ credentials=None,
774
+ wait_for_ready=None,
775
+ compression=None):
776
+ """Invokes the underlying RPC.
777
+
778
+ Args:
779
+ request: The request value for the RPC.
780
+ timeout: An optional duration of time in seconds to allow for
781
+ the RPC. If None, the timeout is considered infinite.
782
+ metadata: An optional :term:`metadata` to be transmitted to the
783
+ service-side of the RPC.
784
+ credentials: An optional CallCredentials for the RPC. Only valid for
785
+ secure Channel.
786
+ wait_for_ready: This is an EXPERIMENTAL argument. An optional
787
+ flag to enable :term:`wait_for_ready` mechanism.
788
+ compression: An element of grpc.compression, e.g.
789
+ grpc.compression.Gzip. This is an EXPERIMENTAL option.
790
+
791
+ Returns:
792
+ An object that is a Call for the RPC, an iterator of response
793
+ values, and a Future for the RPC. Drawing response values from the
794
+ returned Call-iterator may raise RpcError indicating termination of
795
+ the RPC with non-OK status.
796
+ """
797
+ raise NotImplementedError()
798
+
799
+
800
+ class StreamUnaryMultiCallable(six.with_metaclass(abc.ABCMeta)):
801
+ """Affords invoking a stream-unary RPC from client-side."""
802
+
803
+ @abc.abstractmethod
804
+ def __call__(self,
805
+ request_iterator,
806
+ timeout=None,
807
+ metadata=None,
808
+ credentials=None,
809
+ wait_for_ready=None,
810
+ compression=None):
811
+ """Synchronously invokes the underlying RPC.
812
+
813
+ Args:
814
+ request_iterator: An iterator that yields request values for
815
+ the RPC.
816
+ timeout: An optional duration of time in seconds to allow for
817
+ the RPC. If None, the timeout is considered infinite.
818
+ metadata: Optional :term:`metadata` to be transmitted to the
819
+ service-side of the RPC.
820
+ credentials: An optional CallCredentials for the RPC. Only valid for
821
+ secure Channel.
822
+ wait_for_ready: This is an EXPERIMENTAL argument. An optional
823
+ flag to enable :term:`wait_for_ready` mechanism.
824
+ compression: An element of grpc.compression, e.g.
825
+ grpc.compression.Gzip. This is an EXPERIMENTAL option.
826
+
827
+ Returns:
828
+ The response value for the RPC.
829
+
830
+ Raises:
831
+ RpcError: Indicating that the RPC terminated with non-OK status. The
832
+ raised RpcError will also implement grpc.Call, affording methods
833
+ such as metadata, code, and details.
834
+ """
835
+ raise NotImplementedError()
836
+
837
+ @abc.abstractmethod
838
+ def with_call(self,
839
+ request_iterator,
840
+ timeout=None,
841
+ metadata=None,
842
+ credentials=None,
843
+ wait_for_ready=None,
844
+ compression=None):
845
+ """Synchronously invokes the underlying RPC on the client.
846
+
847
+ Args:
848
+ request_iterator: An iterator that yields request values for
849
+ the RPC.
850
+ timeout: An optional duration of time in seconds to allow for
851
+ the RPC. If None, the timeout is considered infinite.
852
+ metadata: Optional :term:`metadata` to be transmitted to the
853
+ service-side of the RPC.
854
+ credentials: An optional CallCredentials for the RPC. Only valid for
855
+ secure Channel.
856
+ wait_for_ready: This is an EXPERIMENTAL argument. An optional
857
+ flag to enable :term:`wait_for_ready` mechanism.
858
+ compression: An element of grpc.compression, e.g.
859
+ grpc.compression.Gzip. This is an EXPERIMENTAL option.
860
+
861
+ Returns:
862
+ The response value for the RPC and a Call object for the RPC.
863
+
864
+ Raises:
865
+ RpcError: Indicating that the RPC terminated with non-OK status. The
866
+ raised RpcError will also be a Call for the RPC affording the RPC's
867
+ metadata, status code, and details.
868
+ """
869
+ raise NotImplementedError()
870
+
871
+ @abc.abstractmethod
872
+ def future(self,
873
+ request_iterator,
874
+ timeout=None,
875
+ metadata=None,
876
+ credentials=None,
877
+ wait_for_ready=None,
878
+ compression=None):
879
+ """Asynchronously invokes the underlying RPC on the client.
880
+
881
+ Args:
882
+ request_iterator: An iterator that yields request values for the RPC.
883
+ timeout: An optional duration of time in seconds to allow for
884
+ the RPC. If None, the timeout is considered infinite.
885
+ metadata: Optional :term:`metadata` to be transmitted to the
886
+ service-side of the RPC.
887
+ credentials: An optional CallCredentials for the RPC. Only valid for
888
+ secure Channel.
889
+ wait_for_ready: This is an EXPERIMENTAL argument. An optional
890
+ flag to enable :term:`wait_for_ready` mechanism.
891
+ compression: An element of grpc.compression, e.g.
892
+ grpc.compression.Gzip. This is an EXPERIMENTAL option.
893
+
894
+ Returns:
895
+ An object that is both a Call for the RPC and a Future.
896
+ In the event of RPC completion, the return Call-Future's result value
897
+ will be the response message of the RPC. Should the event terminate
898
+ with non-OK status, the returned Call-Future's exception value will
899
+ be an RpcError.
900
+ """
901
+ raise NotImplementedError()
902
+
903
+
904
+ class StreamStreamMultiCallable(six.with_metaclass(abc.ABCMeta)):
905
+ """Affords invoking a stream-stream RPC on client-side."""
906
+
907
+ @abc.abstractmethod
908
+ def __call__(self,
909
+ request_iterator,
910
+ timeout=None,
911
+ metadata=None,
912
+ credentials=None,
913
+ wait_for_ready=None,
914
+ compression=None):
915
+ """Invokes the underlying RPC on the client.
916
+
917
+ Args:
918
+ request_iterator: An iterator that yields request values for the RPC.
919
+ timeout: An optional duration of time in seconds to allow for
920
+ the RPC. If not specified, the timeout is considered infinite.
921
+ metadata: Optional :term:`metadata` to be transmitted to the
922
+ service-side of the RPC.
923
+ credentials: An optional CallCredentials for the RPC. Only valid for
924
+ secure Channel.
925
+ wait_for_ready: This is an EXPERIMENTAL argument. An optional
926
+ flag to enable :term:`wait_for_ready` mechanism.
927
+ compression: An element of grpc.compression, e.g.
928
+ grpc.compression.Gzip. This is an EXPERIMENTAL option.
929
+
930
+ Returns:
931
+ An object that is a Call for the RPC, an iterator of response
932
+ values, and a Future for the RPC. Drawing response values from the
933
+ returned Call-iterator may raise RpcError indicating termination of
934
+ the RPC with non-OK status.
935
+ """
936
+ raise NotImplementedError()
937
+
938
+
939
+ ############################# Channel Interface ##############################
940
+
941
+
942
+ class Channel(six.with_metaclass(abc.ABCMeta)):
943
+ """Affords RPC invocation via generic methods on client-side.
944
+
945
+ Channel objects implement the Context Manager type, although they need not
946
+ support being entered and exited multiple times.
947
+ """
948
+
949
+ @abc.abstractmethod
950
+ def subscribe(self, callback, try_to_connect=False):
951
+ """Subscribe to this Channel's connectivity state machine.
952
+
953
+ A Channel may be in any of the states described by ChannelConnectivity.
954
+ This method allows application to monitor the state transitions.
955
+ The typical use case is to debug or gain better visibility into gRPC
956
+ runtime's state.
957
+
958
+ Args:
959
+ callback: A callable to be invoked with ChannelConnectivity argument.
960
+ ChannelConnectivity describes current state of the channel.
961
+ The callable will be invoked immediately upon subscription
962
+ and again for every change to ChannelConnectivity until it
963
+ is unsubscribed or this Channel object goes out of scope.
964
+ try_to_connect: A boolean indicating whether or not this Channel
965
+ should attempt to connect immediately. If set to False, gRPC
966
+ runtime decides when to connect.
967
+ """
968
+ raise NotImplementedError()
969
+
970
+ @abc.abstractmethod
971
+ def unsubscribe(self, callback):
972
+ """Unsubscribes a subscribed callback from this Channel's connectivity.
973
+
974
+ Args:
975
+ callback: A callable previously registered with this Channel from
976
+ having been passed to its "subscribe" method.
977
+ """
978
+ raise NotImplementedError()
979
+
980
+ @abc.abstractmethod
981
+ def unary_unary(self,
982
+ method,
983
+ request_serializer=None,
984
+ response_deserializer=None):
985
+ """Creates a UnaryUnaryMultiCallable for a unary-unary method.
986
+
987
+ Args:
988
+ method: The name of the RPC method.
989
+ request_serializer: Optional :term:`serializer` for serializing the request
990
+ message. Request goes unserialized in case None is passed.
991
+ response_deserializer: Optional :term:`deserializer` for deserializing the
992
+ response message. Response goes undeserialized in case None
993
+ is passed.
994
+
995
+ Returns:
996
+ A UnaryUnaryMultiCallable value for the named unary-unary method.
997
+ """
998
+ raise NotImplementedError()
999
+
1000
+ @abc.abstractmethod
1001
+ def unary_stream(self,
1002
+ method,
1003
+ request_serializer=None,
1004
+ response_deserializer=None):
1005
+ """Creates a UnaryStreamMultiCallable for a unary-stream method.
1006
+
1007
+ Args:
1008
+ method: The name of the RPC method.
1009
+ request_serializer: Optional :term:`serializer` for serializing the request
1010
+ message. Request goes unserialized in case None is passed.
1011
+ response_deserializer: Optional :term:`deserializer` for deserializing the
1012
+ response message. Response goes undeserialized in case None is
1013
+ passed.
1014
+
1015
+ Returns:
1016
+ A UnaryStreamMultiCallable value for the name unary-stream method.
1017
+ """
1018
+ raise NotImplementedError()
1019
+
1020
+ @abc.abstractmethod
1021
+ def stream_unary(self,
1022
+ method,
1023
+ request_serializer=None,
1024
+ response_deserializer=None):
1025
+ """Creates a StreamUnaryMultiCallable for a stream-unary method.
1026
+
1027
+ Args:
1028
+ method: The name of the RPC method.
1029
+ request_serializer: Optional :term:`serializer` for serializing the request
1030
+ message. Request goes unserialized in case None is passed.
1031
+ response_deserializer: Optional :term:`deserializer` for deserializing the
1032
+ response message. Response goes undeserialized in case None is
1033
+ passed.
1034
+
1035
+ Returns:
1036
+ A StreamUnaryMultiCallable value for the named stream-unary method.
1037
+ """
1038
+ raise NotImplementedError()
1039
+
1040
+ @abc.abstractmethod
1041
+ def stream_stream(self,
1042
+ method,
1043
+ request_serializer=None,
1044
+ response_deserializer=None):
1045
+ """Creates a StreamStreamMultiCallable for a stream-stream method.
1046
+
1047
+ Args:
1048
+ method: The name of the RPC method.
1049
+ request_serializer: Optional :term:`serializer` for serializing the request
1050
+ message. Request goes unserialized in case None is passed.
1051
+ response_deserializer: Optional :term:`deserializer` for deserializing the
1052
+ response message. Response goes undeserialized in case None
1053
+ is passed.
1054
+
1055
+ Returns:
1056
+ A StreamStreamMultiCallable value for the named stream-stream method.
1057
+ """
1058
+ raise NotImplementedError()
1059
+
1060
+ @abc.abstractmethod
1061
+ def close(self):
1062
+ """Closes this Channel and releases all resources held by it.
1063
+
1064
+ Closing the Channel will immediately terminate all RPCs active with the
1065
+ Channel and it is not valid to invoke new RPCs with the Channel.
1066
+
1067
+ This method is idempotent.
1068
+ """
1069
+ raise NotImplementedError()
1070
+
1071
+ def __enter__(self):
1072
+ """Enters the runtime context related to the channel object."""
1073
+ raise NotImplementedError()
1074
+
1075
+ def __exit__(self, exc_type, exc_val, exc_tb):
1076
+ """Exits the runtime context related to the channel object."""
1077
+ raise NotImplementedError()
1078
+
1079
+
1080
+ ########################## Service-Side Context ##############################
1081
+
1082
+
1083
+ class ServicerContext(six.with_metaclass(abc.ABCMeta, RpcContext)):
1084
+ """A context object passed to method implementations."""
1085
+
1086
+ @abc.abstractmethod
1087
+ def invocation_metadata(self):
1088
+ """Accesses the metadata from the sent by the client.
1089
+
1090
+ Returns:
1091
+ The invocation :term:`metadata`.
1092
+ """
1093
+ raise NotImplementedError()
1094
+
1095
+ @abc.abstractmethod
1096
+ def peer(self):
1097
+ """Identifies the peer that invoked the RPC being serviced.
1098
+
1099
+ Returns:
1100
+ A string identifying the peer that invoked the RPC being serviced.
1101
+ The string format is determined by gRPC runtime.
1102
+ """
1103
+ raise NotImplementedError()
1104
+
1105
+ @abc.abstractmethod
1106
+ def peer_identities(self):
1107
+ """Gets one or more peer identity(s).
1108
+
1109
+ Equivalent to
1110
+ servicer_context.auth_context().get(servicer_context.peer_identity_key())
1111
+
1112
+ Returns:
1113
+ An iterable of the identities, or None if the call is not
1114
+ authenticated. Each identity is returned as a raw bytes type.
1115
+ """
1116
+ raise NotImplementedError()
1117
+
1118
+ @abc.abstractmethod
1119
+ def peer_identity_key(self):
1120
+ """The auth property used to identify the peer.
1121
+
1122
+ For example, "x509_common_name" or "x509_subject_alternative_name" are
1123
+ used to identify an SSL peer.
1124
+
1125
+ Returns:
1126
+ The auth property (string) that indicates the
1127
+ peer identity, or None if the call is not authenticated.
1128
+ """
1129
+ raise NotImplementedError()
1130
+
1131
+ @abc.abstractmethod
1132
+ def auth_context(self):
1133
+ """Gets the auth context for the call.
1134
+
1135
+ Returns:
1136
+ A map of strings to an iterable of bytes for each auth property.
1137
+ """
1138
+ raise NotImplementedError()
1139
+
1140
+ def set_compression(self, compression):
1141
+ """Set the compression algorithm to be used for the entire call.
1142
+
1143
+ This is an EXPERIMENTAL method.
1144
+
1145
+ Args:
1146
+ compression: An element of grpc.compression, e.g.
1147
+ grpc.compression.Gzip.
1148
+ """
1149
+ raise NotImplementedError()
1150
+
1151
+ @abc.abstractmethod
1152
+ def send_initial_metadata(self, initial_metadata):
1153
+ """Sends the initial metadata value to the client.
1154
+
1155
+ This method need not be called by implementations if they have no
1156
+ metadata to add to what the gRPC runtime will transmit.
1157
+
1158
+ Args:
1159
+ initial_metadata: The initial :term:`metadata`.
1160
+ """
1161
+ raise NotImplementedError()
1162
+
1163
+ @abc.abstractmethod
1164
+ def set_trailing_metadata(self, trailing_metadata):
1165
+ """Sets the trailing metadata for the RPC.
1166
+
1167
+ Sets the trailing metadata to be sent upon completion of the RPC.
1168
+
1169
+ If this method is invoked multiple times throughout the lifetime of an
1170
+ RPC, the value supplied in the final invocation will be the value sent
1171
+ over the wire.
1172
+
1173
+ This method need not be called by implementations if they have no
1174
+ metadata to add to what the gRPC runtime will transmit.
1175
+
1176
+ Args:
1177
+ trailing_metadata: The trailing :term:`metadata`.
1178
+ """
1179
+ raise NotImplementedError()
1180
+
1181
+ def trailing_metadata(self):
1182
+ """Access value to be used as trailing metadata upon RPC completion.
1183
+
1184
+ This is an EXPERIMENTAL API.
1185
+
1186
+ Returns:
1187
+ The trailing :term:`metadata` for the RPC.
1188
+ """
1189
+ raise NotImplementedError()
1190
+
1191
+ @abc.abstractmethod
1192
+ def abort(self, code, details):
1193
+ """Raises an exception to terminate the RPC with a non-OK status.
1194
+
1195
+ The code and details passed as arguments will supercede any existing
1196
+ ones.
1197
+
1198
+ Args:
1199
+ code: A StatusCode object to be sent to the client.
1200
+ It must not be StatusCode.OK.
1201
+ details: A UTF-8-encodable string to be sent to the client upon
1202
+ termination of the RPC.
1203
+
1204
+ Raises:
1205
+ Exception: An exception is always raised to signal the abortion the
1206
+ RPC to the gRPC runtime.
1207
+ """
1208
+ raise NotImplementedError()
1209
+
1210
+ @abc.abstractmethod
1211
+ def abort_with_status(self, status):
1212
+ """Raises an exception to terminate the RPC with a non-OK status.
1213
+
1214
+ The status passed as argument will supercede any existing status code,
1215
+ status message and trailing metadata.
1216
+
1217
+ This is an EXPERIMENTAL API.
1218
+
1219
+ Args:
1220
+ status: A grpc.Status object. The status code in it must not be
1221
+ StatusCode.OK.
1222
+
1223
+ Raises:
1224
+ Exception: An exception is always raised to signal the abortion the
1225
+ RPC to the gRPC runtime.
1226
+ """
1227
+ raise NotImplementedError()
1228
+
1229
+ @abc.abstractmethod
1230
+ def set_code(self, code):
1231
+ """Sets the value to be used as status code upon RPC completion.
1232
+
1233
+ This method need not be called by method implementations if they wish
1234
+ the gRPC runtime to determine the status code of the RPC.
1235
+
1236
+ Args:
1237
+ code: A StatusCode object to be sent to the client.
1238
+ """
1239
+ raise NotImplementedError()
1240
+
1241
+ @abc.abstractmethod
1242
+ def set_details(self, details):
1243
+ """Sets the value to be used as detail string upon RPC completion.
1244
+
1245
+ This method need not be called by method implementations if they have
1246
+ no details to transmit.
1247
+
1248
+ Args:
1249
+ details: A UTF-8-encodable string to be sent to the client upon
1250
+ termination of the RPC.
1251
+ """
1252
+ raise NotImplementedError()
1253
+
1254
+ def code(self):
1255
+ """Accesses the value to be used as status code upon RPC completion.
1256
+
1257
+ This is an EXPERIMENTAL API.
1258
+
1259
+ Returns:
1260
+ The StatusCode value for the RPC.
1261
+ """
1262
+ raise NotImplementedError()
1263
+
1264
+ def details(self):
1265
+ """Accesses the value to be used as detail string upon RPC completion.
1266
+
1267
+ This is an EXPERIMENTAL API.
1268
+
1269
+ Returns:
1270
+ The details string of the RPC.
1271
+ """
1272
+ raise NotImplementedError()
1273
+
1274
+ def disable_next_message_compression(self):
1275
+ """Disables compression for the next response message.
1276
+
1277
+ This is an EXPERIMENTAL method.
1278
+
1279
+ This method will override any compression configuration set during
1280
+ server creation or set on the call.
1281
+ """
1282
+ raise NotImplementedError()
1283
+
1284
+
1285
+ ##################### Service-Side Handler Interfaces ########################
1286
+
1287
+
1288
+ class RpcMethodHandler(six.with_metaclass(abc.ABCMeta)):
1289
+ """An implementation of a single RPC method.
1290
+
1291
+ Attributes:
1292
+ request_streaming: Whether the RPC supports exactly one request message
1293
+ or any arbitrary number of request messages.
1294
+ response_streaming: Whether the RPC supports exactly one response message
1295
+ or any arbitrary number of response messages.
1296
+ request_deserializer: A callable :term:`deserializer` that accepts a byte string and
1297
+ returns an object suitable to be passed to this object's business
1298
+ logic, or None to indicate that this object's business logic should be
1299
+ passed the raw request bytes.
1300
+ response_serializer: A callable :term:`serializer` that accepts an object produced
1301
+ by this object's business logic and returns a byte string, or None to
1302
+ indicate that the byte strings produced by this object's business logic
1303
+ should be transmitted on the wire as they are.
1304
+ unary_unary: This object's application-specific business logic as a
1305
+ callable value that takes a request value and a ServicerContext object
1306
+ and returns a response value. Only non-None if both request_streaming
1307
+ and response_streaming are False.
1308
+ unary_stream: This object's application-specific business logic as a
1309
+ callable value that takes a request value and a ServicerContext object
1310
+ and returns an iterator of response values. Only non-None if
1311
+ request_streaming is False and response_streaming is True.
1312
+ stream_unary: This object's application-specific business logic as a
1313
+ callable value that takes an iterator of request values and a
1314
+ ServicerContext object and returns a response value. Only non-None if
1315
+ request_streaming is True and response_streaming is False.
1316
+ stream_stream: This object's application-specific business logic as a
1317
+ callable value that takes an iterator of request values and a
1318
+ ServicerContext object and returns an iterator of response values.
1319
+ Only non-None if request_streaming and response_streaming are both
1320
+ True.
1321
+ """
1322
+
1323
+
1324
+ class HandlerCallDetails(six.with_metaclass(abc.ABCMeta)):
1325
+ """Describes an RPC that has just arrived for service.
1326
+
1327
+ Attributes:
1328
+ method: The method name of the RPC.
1329
+ invocation_metadata: The :term:`metadata` sent by the client.
1330
+ """
1331
+
1332
+
1333
+ class GenericRpcHandler(six.with_metaclass(abc.ABCMeta)):
1334
+ """An implementation of arbitrarily many RPC methods."""
1335
+
1336
+ @abc.abstractmethod
1337
+ def service(self, handler_call_details):
1338
+ """Returns the handler for servicing the RPC.
1339
+
1340
+ Args:
1341
+ handler_call_details: A HandlerCallDetails describing the RPC.
1342
+
1343
+ Returns:
1344
+ An RpcMethodHandler with which the RPC may be serviced if the
1345
+ implementation chooses to service this RPC, or None otherwise.
1346
+ """
1347
+ raise NotImplementedError()
1348
+
1349
+
1350
+ class ServiceRpcHandler(six.with_metaclass(abc.ABCMeta, GenericRpcHandler)):
1351
+ """An implementation of RPC methods belonging to a service.
1352
+
1353
+ A service handles RPC methods with structured names of the form
1354
+ '/Service.Name/Service.Method', where 'Service.Name' is the value
1355
+ returned by service_name(), and 'Service.Method' is the method
1356
+ name. A service can have multiple method names, but only a single
1357
+ service name.
1358
+ """
1359
+
1360
+ @abc.abstractmethod
1361
+ def service_name(self):
1362
+ """Returns this service's name.
1363
+
1364
+ Returns:
1365
+ The service name.
1366
+ """
1367
+ raise NotImplementedError()
1368
+
1369
+
1370
+ #################### Service-Side Interceptor Interfaces #####################
1371
+
1372
+
1373
+ class ServerInterceptor(six.with_metaclass(abc.ABCMeta)):
1374
+ """Affords intercepting incoming RPCs on the service-side."""
1375
+
1376
+ @abc.abstractmethod
1377
+ def intercept_service(self, continuation, handler_call_details):
1378
+ """Intercepts incoming RPCs before handing them over to a handler.
1379
+
1380
+ Args:
1381
+ continuation: A function that takes a HandlerCallDetails and
1382
+ proceeds to invoke the next interceptor in the chain, if any,
1383
+ or the RPC handler lookup logic, with the call details passed
1384
+ as an argument, and returns an RpcMethodHandler instance if
1385
+ the RPC is considered serviced, or None otherwise.
1386
+ handler_call_details: A HandlerCallDetails describing the RPC.
1387
+
1388
+ Returns:
1389
+ An RpcMethodHandler with which the RPC may be serviced if the
1390
+ interceptor chooses to service this RPC, or None otherwise.
1391
+ """
1392
+ raise NotImplementedError()
1393
+
1394
+
1395
+ ############################# Server Interface ###############################
1396
+
1397
+
1398
+ class Server(six.with_metaclass(abc.ABCMeta)):
1399
+ """Services RPCs."""
1400
+
1401
+ @abc.abstractmethod
1402
+ def add_generic_rpc_handlers(self, generic_rpc_handlers):
1403
+ """Registers GenericRpcHandlers with this Server.
1404
+
1405
+ This method is only safe to call before the server is started.
1406
+
1407
+ Args:
1408
+ generic_rpc_handlers: An iterable of GenericRpcHandlers that will be
1409
+ used to service RPCs.
1410
+ """
1411
+ raise NotImplementedError()
1412
+
1413
+ @abc.abstractmethod
1414
+ def add_insecure_port(self, address):
1415
+ """Opens an insecure port for accepting RPCs.
1416
+
1417
+ This method may only be called before starting the server.
1418
+
1419
+ Args:
1420
+ address: The address for which to open a port. If the port is 0,
1421
+ or not specified in the address, then gRPC runtime will choose a port.
1422
+
1423
+ Returns:
1424
+ An integer port on which server will accept RPC requests.
1425
+ """
1426
+ raise NotImplementedError()
1427
+
1428
+ @abc.abstractmethod
1429
+ def add_secure_port(self, address, server_credentials):
1430
+ """Opens a secure port for accepting RPCs.
1431
+
1432
+ This method may only be called before starting the server.
1433
+
1434
+ Args:
1435
+ address: The address for which to open a port.
1436
+ if the port is 0, or not specified in the address, then gRPC
1437
+ runtime will choose a port.
1438
+ server_credentials: A ServerCredentials object.
1439
+
1440
+ Returns:
1441
+ An integer port on which server will accept RPC requests.
1442
+ """
1443
+ raise NotImplementedError()
1444
+
1445
+ @abc.abstractmethod
1446
+ def start(self):
1447
+ """Starts this Server.
1448
+
1449
+ This method may only be called once. (i.e. it is not idempotent).
1450
+ """
1451
+ raise NotImplementedError()
1452
+
1453
+ @abc.abstractmethod
1454
+ def stop(self, grace):
1455
+ """Stops this Server.
1456
+
1457
+ This method immediately stop service of new RPCs in all cases.
1458
+
1459
+ If a grace period is specified, this method returns immediately
1460
+ and all RPCs active at the end of the grace period are aborted.
1461
+ If a grace period is not specified (by passing None for `grace`),
1462
+ all existing RPCs are aborted immediately and this method
1463
+ blocks until the last RPC handler terminates.
1464
+
1465
+ This method is idempotent and may be called at any time.
1466
+ Passing a smaller grace value in a subsequent call will have
1467
+ the effect of stopping the Server sooner (passing None will
1468
+ have the effect of stopping the server immediately). Passing
1469
+ a larger grace value in a subsequent call *will not* have the
1470
+ effect of stopping the server later (i.e. the most restrictive
1471
+ grace value is used).
1472
+
1473
+ Args:
1474
+ grace: A duration of time in seconds or None.
1475
+
1476
+ Returns:
1477
+ A threading.Event that will be set when this Server has completely
1478
+ stopped, i.e. when running RPCs either complete or are aborted and
1479
+ all handlers have terminated.
1480
+ """
1481
+ raise NotImplementedError()
1482
+
1483
+ def wait_for_termination(self, timeout=None):
1484
+ """Block current thread until the server stops.
1485
+
1486
+ This is an EXPERIMENTAL API.
1487
+
1488
+ The wait will not consume computational resources during blocking, and
1489
+ it will block until one of the two following conditions are met:
1490
+
1491
+ 1) The server is stopped or terminated;
1492
+ 2) A timeout occurs if timeout is not `None`.
1493
+
1494
+ The timeout argument works in the same way as `threading.Event.wait()`.
1495
+ https://docs.python.org/3/library/threading.html#threading.Event.wait
1496
+
1497
+ Args:
1498
+ timeout: A floating point number specifying a timeout for the
1499
+ operation in seconds.
1500
+
1501
+ Returns:
1502
+ A bool indicates if the operation times out.
1503
+ """
1504
+ raise NotImplementedError()
1505
+
1506
+
1507
+ ################################# Functions ################################
1508
+
1509
+
1510
+ def unary_unary_rpc_method_handler(behavior,
1511
+ request_deserializer=None,
1512
+ response_serializer=None):
1513
+ """Creates an RpcMethodHandler for a unary-unary RPC method.
1514
+
1515
+ Args:
1516
+ behavior: The implementation of an RPC that accepts one request
1517
+ and returns one response.
1518
+ request_deserializer: An optional :term:`deserializer` for request deserialization.
1519
+ response_serializer: An optional :term:`serializer` for response serialization.
1520
+
1521
+ Returns:
1522
+ An RpcMethodHandler object that is typically used by grpc.Server.
1523
+ """
1524
+ from grpc import _utilities # pylint: disable=cyclic-import
1525
+ return _utilities.RpcMethodHandler(False, False, request_deserializer,
1526
+ response_serializer, behavior, None,
1527
+ None, None)
1528
+
1529
+
1530
+ def unary_stream_rpc_method_handler(behavior,
1531
+ request_deserializer=None,
1532
+ response_serializer=None):
1533
+ """Creates an RpcMethodHandler for a unary-stream RPC method.
1534
+
1535
+ Args:
1536
+ behavior: The implementation of an RPC that accepts one request
1537
+ and returns an iterator of response values.
1538
+ request_deserializer: An optional :term:`deserializer` for request deserialization.
1539
+ response_serializer: An optional :term:`serializer` for response serialization.
1540
+
1541
+ Returns:
1542
+ An RpcMethodHandler object that is typically used by grpc.Server.
1543
+ """
1544
+ from grpc import _utilities # pylint: disable=cyclic-import
1545
+ return _utilities.RpcMethodHandler(False, True, request_deserializer,
1546
+ response_serializer, None, behavior,
1547
+ None, None)
1548
+
1549
+
1550
+ def stream_unary_rpc_method_handler(behavior,
1551
+ request_deserializer=None,
1552
+ response_serializer=None):
1553
+ """Creates an RpcMethodHandler for a stream-unary RPC method.
1554
+
1555
+ Args:
1556
+ behavior: The implementation of an RPC that accepts an iterator of
1557
+ request values and returns a single response value.
1558
+ request_deserializer: An optional :term:`deserializer` for request deserialization.
1559
+ response_serializer: An optional :term:`serializer` for response serialization.
1560
+
1561
+ Returns:
1562
+ An RpcMethodHandler object that is typically used by grpc.Server.
1563
+ """
1564
+ from grpc import _utilities # pylint: disable=cyclic-import
1565
+ return _utilities.RpcMethodHandler(True, False, request_deserializer,
1566
+ response_serializer, None, None,
1567
+ behavior, None)
1568
+
1569
+
1570
+ def stream_stream_rpc_method_handler(behavior,
1571
+ request_deserializer=None,
1572
+ response_serializer=None):
1573
+ """Creates an RpcMethodHandler for a stream-stream RPC method.
1574
+
1575
+ Args:
1576
+ behavior: The implementation of an RPC that accepts an iterator of
1577
+ request values and returns an iterator of response values.
1578
+ request_deserializer: An optional :term:`deserializer` for request deserialization.
1579
+ response_serializer: An optional :term:`serializer` for response serialization.
1580
+
1581
+ Returns:
1582
+ An RpcMethodHandler object that is typically used by grpc.Server.
1583
+ """
1584
+ from grpc import _utilities # pylint: disable=cyclic-import
1585
+ return _utilities.RpcMethodHandler(True, True, request_deserializer,
1586
+ response_serializer, None, None, None,
1587
+ behavior)
1588
+
1589
+
1590
+ def method_handlers_generic_handler(service, method_handlers):
1591
+ """Creates a GenericRpcHandler from RpcMethodHandlers.
1592
+
1593
+ Args:
1594
+ service: The name of the service that is implemented by the
1595
+ method_handlers.
1596
+ method_handlers: A dictionary that maps method names to corresponding
1597
+ RpcMethodHandler.
1598
+
1599
+ Returns:
1600
+ A GenericRpcHandler. This is typically added to the grpc.Server object
1601
+ with add_generic_rpc_handlers() before starting the server.
1602
+ """
1603
+ from grpc import _utilities # pylint: disable=cyclic-import
1604
+ return _utilities.DictionaryGenericHandler(service, method_handlers)
1605
+
1606
+
1607
+ def ssl_channel_credentials(root_certificates=None,
1608
+ private_key=None,
1609
+ certificate_chain=None):
1610
+ """Creates a ChannelCredentials for use with an SSL-enabled Channel.
1611
+
1612
+ Args:
1613
+ root_certificates: The PEM-encoded root certificates as a byte string,
1614
+ or None to retrieve them from a default location chosen by gRPC
1615
+ runtime.
1616
+ private_key: The PEM-encoded private key as a byte string, or None if no
1617
+ private key should be used.
1618
+ certificate_chain: The PEM-encoded certificate chain as a byte string
1619
+ to use or None if no certificate chain should be used.
1620
+
1621
+ Returns:
1622
+ A ChannelCredentials for use with an SSL-enabled Channel.
1623
+ """
1624
+ return ChannelCredentials(
1625
+ _cygrpc.SSLChannelCredentials(root_certificates, private_key,
1626
+ certificate_chain))
1627
+
1628
+
1629
+ def xds_channel_credentials(fallback_credentials=None):
1630
+ """Creates a ChannelCredentials for use with xDS. This is an EXPERIMENTAL
1631
+ API.
1632
+
1633
+ Args:
1634
+ fallback_credentials: Credentials to use in case it is not possible to
1635
+ establish a secure connection via xDS. If no fallback_credentials
1636
+ argument is supplied, a default SSLChannelCredentials is used.
1637
+ """
1638
+ fallback_credentials = ssl_channel_credentials(
1639
+ ) if fallback_credentials is None else fallback_credentials
1640
+ return ChannelCredentials(
1641
+ _cygrpc.XDSChannelCredentials(fallback_credentials._credentials))
1642
+
1643
+
1644
+ def metadata_call_credentials(metadata_plugin, name=None):
1645
+ """Construct CallCredentials from an AuthMetadataPlugin.
1646
+
1647
+ Args:
1648
+ metadata_plugin: An AuthMetadataPlugin to use for authentication.
1649
+ name: An optional name for the plugin.
1650
+
1651
+ Returns:
1652
+ A CallCredentials.
1653
+ """
1654
+ from grpc import _plugin_wrapping # pylint: disable=cyclic-import
1655
+ return _plugin_wrapping.metadata_plugin_call_credentials(
1656
+ metadata_plugin, name)
1657
+
1658
+
1659
+ def access_token_call_credentials(access_token):
1660
+ """Construct CallCredentials from an access token.
1661
+
1662
+ Args:
1663
+ access_token: A string to place directly in the http request
1664
+ authorization header, for example
1665
+ "authorization: Bearer <access_token>".
1666
+
1667
+ Returns:
1668
+ A CallCredentials.
1669
+ """
1670
+ from grpc import _auth # pylint: disable=cyclic-import
1671
+ from grpc import _plugin_wrapping # pylint: disable=cyclic-import
1672
+ return _plugin_wrapping.metadata_plugin_call_credentials(
1673
+ _auth.AccessTokenAuthMetadataPlugin(access_token), None)
1674
+
1675
+
1676
+ def composite_call_credentials(*call_credentials):
1677
+ """Compose multiple CallCredentials to make a new CallCredentials.
1678
+
1679
+ Args:
1680
+ *call_credentials: At least two CallCredentials objects.
1681
+
1682
+ Returns:
1683
+ A CallCredentials object composed of the given CallCredentials objects.
1684
+ """
1685
+ return CallCredentials(
1686
+ _cygrpc.CompositeCallCredentials(
1687
+ tuple(single_call_credentials._credentials
1688
+ for single_call_credentials in call_credentials)))
1689
+
1690
+
1691
+ def composite_channel_credentials(channel_credentials, *call_credentials):
1692
+ """Compose a ChannelCredentials and one or more CallCredentials objects.
1693
+
1694
+ Args:
1695
+ channel_credentials: A ChannelCredentials object.
1696
+ *call_credentials: One or more CallCredentials objects.
1697
+
1698
+ Returns:
1699
+ A ChannelCredentials composed of the given ChannelCredentials and
1700
+ CallCredentials objects.
1701
+ """
1702
+ return ChannelCredentials(
1703
+ _cygrpc.CompositeChannelCredentials(
1704
+ tuple(single_call_credentials._credentials
1705
+ for single_call_credentials in call_credentials),
1706
+ channel_credentials._credentials))
1707
+
1708
+
1709
+ def ssl_server_credentials(private_key_certificate_chain_pairs,
1710
+ root_certificates=None,
1711
+ require_client_auth=False):
1712
+ """Creates a ServerCredentials for use with an SSL-enabled Server.
1713
+
1714
+ Args:
1715
+ private_key_certificate_chain_pairs: A list of pairs of the form
1716
+ [PEM-encoded private key, PEM-encoded certificate chain].
1717
+ root_certificates: An optional byte string of PEM-encoded client root
1718
+ certificates that the server will use to verify client authentication.
1719
+ If omitted, require_client_auth must also be False.
1720
+ require_client_auth: A boolean indicating whether or not to require
1721
+ clients to be authenticated. May only be True if root_certificates
1722
+ is not None.
1723
+
1724
+ Returns:
1725
+ A ServerCredentials for use with an SSL-enabled Server. Typically, this
1726
+ object is an argument to add_secure_port() method during server setup.
1727
+ """
1728
+ if not private_key_certificate_chain_pairs:
1729
+ raise ValueError(
1730
+ 'At least one private key-certificate chain pair is required!')
1731
+ elif require_client_auth and root_certificates is None:
1732
+ raise ValueError(
1733
+ 'Illegal to require client auth without providing root certificates!'
1734
+ )
1735
+ else:
1736
+ return ServerCredentials(
1737
+ _cygrpc.server_credentials_ssl(root_certificates, [
1738
+ _cygrpc.SslPemKeyCertPair(key, pem)
1739
+ for key, pem in private_key_certificate_chain_pairs
1740
+ ], require_client_auth))
1741
+
1742
+
1743
+ def xds_server_credentials(fallback_credentials):
1744
+ """Creates a ServerCredentials for use with xDS. This is an EXPERIMENTAL
1745
+ API.
1746
+
1747
+ Args:
1748
+ fallback_credentials: Credentials to use in case it is not possible to
1749
+ establish a secure connection via xDS. No default value is provided.
1750
+ """
1751
+ return ServerCredentials(
1752
+ _cygrpc.xds_server_credentials(fallback_credentials._credentials))
1753
+
1754
+
1755
+ def insecure_server_credentials():
1756
+ """Creates a credentials object directing the server to use no credentials.
1757
+ This is an EXPERIMENTAL API.
1758
+
1759
+ This object cannot be used directly in a call to `add_secure_port`.
1760
+ Instead, it should be used to construct other credentials objects, e.g.
1761
+ with xds_server_credentials.
1762
+ """
1763
+ return ServerCredentials(_cygrpc.insecure_server_credentials())
1764
+
1765
+
1766
+ def ssl_server_certificate_configuration(private_key_certificate_chain_pairs,
1767
+ root_certificates=None):
1768
+ """Creates a ServerCertificateConfiguration for use with a Server.
1769
+
1770
+ Args:
1771
+ private_key_certificate_chain_pairs: A collection of pairs of
1772
+ the form [PEM-encoded private key, PEM-encoded certificate
1773
+ chain].
1774
+ root_certificates: An optional byte string of PEM-encoded client root
1775
+ certificates that the server will use to verify client authentication.
1776
+
1777
+ Returns:
1778
+ A ServerCertificateConfiguration that can be returned in the certificate
1779
+ configuration fetching callback.
1780
+ """
1781
+ if private_key_certificate_chain_pairs:
1782
+ return ServerCertificateConfiguration(
1783
+ _cygrpc.server_certificate_config_ssl(root_certificates, [
1784
+ _cygrpc.SslPemKeyCertPair(key, pem)
1785
+ for key, pem in private_key_certificate_chain_pairs
1786
+ ]))
1787
+ else:
1788
+ raise ValueError(
1789
+ 'At least one private key-certificate chain pair is required!')
1790
+
1791
+
1792
+ def dynamic_ssl_server_credentials(initial_certificate_configuration,
1793
+ certificate_configuration_fetcher,
1794
+ require_client_authentication=False):
1795
+ """Creates a ServerCredentials for use with an SSL-enabled Server.
1796
+
1797
+ Args:
1798
+ initial_certificate_configuration (ServerCertificateConfiguration): The
1799
+ certificate configuration with which the server will be initialized.
1800
+ certificate_configuration_fetcher (callable): A callable that takes no
1801
+ arguments and should return a ServerCertificateConfiguration to
1802
+ replace the server's current certificate, or None for no change
1803
+ (i.e., the server will continue its current certificate
1804
+ config). The library will call this callback on *every* new
1805
+ client connection before starting the TLS handshake with the
1806
+ client, thus allowing the user application to optionally
1807
+ return a new ServerCertificateConfiguration that the server will then
1808
+ use for the handshake.
1809
+ require_client_authentication: A boolean indicating whether or not to
1810
+ require clients to be authenticated.
1811
+
1812
+ Returns:
1813
+ A ServerCredentials.
1814
+ """
1815
+ return ServerCredentials(
1816
+ _cygrpc.server_credentials_ssl_dynamic_cert_config(
1817
+ initial_certificate_configuration,
1818
+ certificate_configuration_fetcher, require_client_authentication))
1819
+
1820
+
1821
+ @enum.unique
1822
+ class LocalConnectionType(enum.Enum):
1823
+ """Types of local connection for local credential creation.
1824
+
1825
+ Attributes:
1826
+ UDS: Unix domain socket connections
1827
+ LOCAL_TCP: Local TCP connections.
1828
+ """
1829
+ UDS = _cygrpc.LocalConnectionType.uds
1830
+ LOCAL_TCP = _cygrpc.LocalConnectionType.local_tcp
1831
+
1832
+
1833
+ def local_channel_credentials(local_connect_type=LocalConnectionType.LOCAL_TCP):
1834
+ """Creates a local ChannelCredentials used for local connections.
1835
+
1836
+ This is an EXPERIMENTAL API.
1837
+
1838
+ Local credentials are used by local TCP endpoints (e.g. localhost:10000)
1839
+ also UDS connections.
1840
+
1841
+ The connections created by local channel credentials are not
1842
+ encrypted, but will be checked if they are local or not.
1843
+ The UDS connections are considered secure by providing peer authentication
1844
+ and data confidentiality while TCP connections are considered insecure.
1845
+
1846
+ It is allowed to transmit call credentials over connections created by
1847
+ local channel credentials.
1848
+
1849
+ Local channel credentials are useful for 1) eliminating insecure_channel usage;
1850
+ 2) enable unit testing for call credentials without setting up secrets.
1851
+
1852
+ Args:
1853
+ local_connect_type: Local connection type (either
1854
+ grpc.LocalConnectionType.UDS or grpc.LocalConnectionType.LOCAL_TCP)
1855
+
1856
+ Returns:
1857
+ A ChannelCredentials for use with a local Channel
1858
+ """
1859
+ return ChannelCredentials(
1860
+ _cygrpc.channel_credentials_local(local_connect_type.value))
1861
+
1862
+
1863
+ def local_server_credentials(local_connect_type=LocalConnectionType.LOCAL_TCP):
1864
+ """Creates a local ServerCredentials used for local connections.
1865
+
1866
+ This is an EXPERIMENTAL API.
1867
+
1868
+ Local credentials are used by local TCP endpoints (e.g. localhost:10000)
1869
+ also UDS connections.
1870
+
1871
+ The connections created by local server credentials are not
1872
+ encrypted, but will be checked if they are local or not.
1873
+ The UDS connections are considered secure by providing peer authentication
1874
+ and data confidentiality while TCP connections are considered insecure.
1875
+
1876
+ It is allowed to transmit call credentials over connections created by local
1877
+ server credentials.
1878
+
1879
+ Local server credentials are useful for 1) eliminating insecure_channel usage;
1880
+ 2) enable unit testing for call credentials without setting up secrets.
1881
+
1882
+ Args:
1883
+ local_connect_type: Local connection type (either
1884
+ grpc.LocalConnectionType.UDS or grpc.LocalConnectionType.LOCAL_TCP)
1885
+
1886
+ Returns:
1887
+ A ServerCredentials for use with a local Server
1888
+ """
1889
+ return ServerCredentials(
1890
+ _cygrpc.server_credentials_local(local_connect_type.value))
1891
+
1892
+
1893
+ def alts_channel_credentials(service_accounts=None):
1894
+ """Creates a ChannelCredentials for use with an ALTS-enabled Channel.
1895
+
1896
+ This is an EXPERIMENTAL API.
1897
+ ALTS credentials API can only be used in GCP environment as it relies on
1898
+ handshaker service being available. For more info about ALTS see
1899
+ https://cloud.google.com/security/encryption-in-transit/application-layer-transport-security
1900
+
1901
+ Args:
1902
+ service_accounts: A list of server identities accepted by the client.
1903
+ If target service accounts are provided and none of them matches the
1904
+ peer identity of the server, handshake will fail. The arg can be empty
1905
+ if the client does not have any information about trusted server
1906
+ identity.
1907
+ Returns:
1908
+ A ChannelCredentials for use with an ALTS-enabled Channel
1909
+ """
1910
+ return ChannelCredentials(
1911
+ _cygrpc.channel_credentials_alts(service_accounts or []))
1912
+
1913
+
1914
+ def alts_server_credentials():
1915
+ """Creates a ServerCredentials for use with an ALTS-enabled connection.
1916
+
1917
+ This is an EXPERIMENTAL API.
1918
+ ALTS credentials API can only be used in GCP environment as it relies on
1919
+ handshaker service being available. For more info about ALTS see
1920
+ https://cloud.google.com/security/encryption-in-transit/application-layer-transport-security
1921
+
1922
+ Returns:
1923
+ A ServerCredentials for use with an ALTS-enabled Server
1924
+ """
1925
+ return ServerCredentials(_cygrpc.server_credentials_alts())
1926
+
1927
+
1928
+ def compute_engine_channel_credentials(call_credentials):
1929
+ """Creates a compute engine channel credential.
1930
+
1931
+ This credential can only be used in a GCP environment as it relies on
1932
+ a handshaker service. For more info about ALTS, see
1933
+ https://cloud.google.com/security/encryption-in-transit/application-layer-transport-security
1934
+
1935
+ This channel credential is expected to be used as part of a composite
1936
+ credential in conjunction with a call credentials that authenticates the
1937
+ VM's default service account. If used with any other sort of call
1938
+ credential, the connection may suddenly and unexpectedly begin failing RPCs.
1939
+ """
1940
+ return ChannelCredentials(
1941
+ _cygrpc.channel_credentials_compute_engine(
1942
+ call_credentials._credentials))
1943
+
1944
+
1945
+ def channel_ready_future(channel):
1946
+ """Creates a Future that tracks when a Channel is ready.
1947
+
1948
+ Cancelling the Future does not affect the channel's state machine.
1949
+ It merely decouples the Future from channel state machine.
1950
+
1951
+ Args:
1952
+ channel: A Channel object.
1953
+
1954
+ Returns:
1955
+ A Future object that matures when the channel connectivity is
1956
+ ChannelConnectivity.READY.
1957
+ """
1958
+ from grpc import _utilities # pylint: disable=cyclic-import
1959
+ return _utilities.channel_ready_future(channel)
1960
+
1961
+
1962
+ def insecure_channel(target, options=None, compression=None):
1963
+ """Creates an insecure Channel to a server.
1964
+
1965
+ The returned Channel is thread-safe.
1966
+
1967
+ Args:
1968
+ target: The server address
1969
+ options: An optional list of key-value pairs (:term:`channel_arguments`
1970
+ in gRPC Core runtime) to configure the channel.
1971
+ compression: An optional value indicating the compression method to be
1972
+ used over the lifetime of the channel. This is an EXPERIMENTAL option.
1973
+
1974
+ Returns:
1975
+ A Channel.
1976
+ """
1977
+ from grpc import _channel # pylint: disable=cyclic-import
1978
+ return _channel.Channel(target, () if options is None else options, None,
1979
+ compression)
1980
+
1981
+
1982
+ def secure_channel(target, credentials, options=None, compression=None):
1983
+ """Creates a secure Channel to a server.
1984
+
1985
+ The returned Channel is thread-safe.
1986
+
1987
+ Args:
1988
+ target: The server address.
1989
+ credentials: A ChannelCredentials instance.
1990
+ options: An optional list of key-value pairs (:term:`channel_arguments`
1991
+ in gRPC Core runtime) to configure the channel.
1992
+ compression: An optional value indicating the compression method to be
1993
+ used over the lifetime of the channel. This is an EXPERIMENTAL option.
1994
+
1995
+ Returns:
1996
+ A Channel.
1997
+ """
1998
+ from grpc import _channel # pylint: disable=cyclic-import
1999
+ from grpc.experimental import _insecure_channel_credentials
2000
+ if credentials._credentials is _insecure_channel_credentials:
2001
+ raise ValueError(
2002
+ "secure_channel cannot be called with insecure credentials." +
2003
+ " Call insecure_channel instead.")
2004
+ return _channel.Channel(target, () if options is None else options,
2005
+ credentials._credentials, compression)
2006
+
2007
+
2008
+ def intercept_channel(channel, *interceptors):
2009
+ """Intercepts a channel through a set of interceptors.
2010
+
2011
+ Args:
2012
+ channel: A Channel.
2013
+ interceptors: Zero or more objects of type
2014
+ UnaryUnaryClientInterceptor,
2015
+ UnaryStreamClientInterceptor,
2016
+ StreamUnaryClientInterceptor, or
2017
+ StreamStreamClientInterceptor.
2018
+ Interceptors are given control in the order they are listed.
2019
+
2020
+ Returns:
2021
+ A Channel that intercepts each invocation via the provided interceptors.
2022
+
2023
+ Raises:
2024
+ TypeError: If interceptor does not derive from any of
2025
+ UnaryUnaryClientInterceptor,
2026
+ UnaryStreamClientInterceptor,
2027
+ StreamUnaryClientInterceptor, or
2028
+ StreamStreamClientInterceptor.
2029
+ """
2030
+ from grpc import _interceptor # pylint: disable=cyclic-import
2031
+ return _interceptor.intercept_channel(channel, *interceptors)
2032
+
2033
+
2034
+ def server(thread_pool,
2035
+ handlers=None,
2036
+ interceptors=None,
2037
+ options=None,
2038
+ maximum_concurrent_rpcs=None,
2039
+ compression=None,
2040
+ xds=False):
2041
+ """Creates a Server with which RPCs can be serviced.
2042
+
2043
+ Args:
2044
+ thread_pool: A futures.ThreadPoolExecutor to be used by the Server
2045
+ to execute RPC handlers.
2046
+ handlers: An optional list of GenericRpcHandlers used for executing RPCs.
2047
+ More handlers may be added by calling add_generic_rpc_handlers any time
2048
+ before the server is started.
2049
+ interceptors: An optional list of ServerInterceptor objects that observe
2050
+ and optionally manipulate the incoming RPCs before handing them over to
2051
+ handlers. The interceptors are given control in the order they are
2052
+ specified. This is an EXPERIMENTAL API.
2053
+ options: An optional list of key-value pairs (:term:`channel_arguments` in gRPC runtime)
2054
+ to configure the channel.
2055
+ maximum_concurrent_rpcs: The maximum number of concurrent RPCs this server
2056
+ will service before returning RESOURCE_EXHAUSTED status, or None to
2057
+ indicate no limit.
2058
+ compression: An element of grpc.compression, e.g.
2059
+ grpc.compression.Gzip. This compression algorithm will be used for the
2060
+ lifetime of the server unless overridden. This is an EXPERIMENTAL option.
2061
+ xds: If set to true, retrieves server configuration via xDS. This is an
2062
+ EXPERIMENTAL option.
2063
+
2064
+ Returns:
2065
+ A Server object.
2066
+ """
2067
+ from grpc import _server # pylint: disable=cyclic-import
2068
+ return _server.create_server(thread_pool,
2069
+ () if handlers is None else handlers,
2070
+ () if interceptors is None else interceptors,
2071
+ () if options is None else options,
2072
+ maximum_concurrent_rpcs, compression, xds)
2073
+
2074
+
2075
+ @contextlib.contextmanager
2076
+ def _create_servicer_context(rpc_event, state, request_deserializer):
2077
+ from grpc import _server # pylint: disable=cyclic-import
2078
+ context = _server._Context(rpc_event, state, request_deserializer)
2079
+ yield context
2080
+ context._finalize_state() # pylint: disable=protected-access
2081
+
2082
+
2083
+ @enum.unique
2084
+ class Compression(enum.IntEnum):
2085
+ """Indicates the compression method to be used for an RPC.
2086
+
2087
+ This enumeration is part of an EXPERIMENTAL API.
2088
+
2089
+ Attributes:
2090
+ NoCompression: Do not use compression algorithm.
2091
+ Deflate: Use "Deflate" compression algorithm.
2092
+ Gzip: Use "Gzip" compression algorithm.
2093
+ """
2094
+ NoCompression = _compression.NoCompression
2095
+ Deflate = _compression.Deflate
2096
+ Gzip = _compression.Gzip
2097
+
2098
+
2099
+ ################################### __all__ #################################
2100
+
2101
+ __all__ = (
2102
+ 'FutureTimeoutError',
2103
+ 'FutureCancelledError',
2104
+ 'Future',
2105
+ 'ChannelConnectivity',
2106
+ 'StatusCode',
2107
+ 'Status',
2108
+ 'RpcError',
2109
+ 'RpcContext',
2110
+ 'Call',
2111
+ 'ChannelCredentials',
2112
+ 'CallCredentials',
2113
+ 'AuthMetadataContext',
2114
+ 'AuthMetadataPluginCallback',
2115
+ 'AuthMetadataPlugin',
2116
+ 'Compression',
2117
+ 'ClientCallDetails',
2118
+ 'ServerCertificateConfiguration',
2119
+ 'ServerCredentials',
2120
+ 'LocalConnectionType',
2121
+ 'UnaryUnaryMultiCallable',
2122
+ 'UnaryStreamMultiCallable',
2123
+ 'StreamUnaryMultiCallable',
2124
+ 'StreamStreamMultiCallable',
2125
+ 'UnaryUnaryClientInterceptor',
2126
+ 'UnaryStreamClientInterceptor',
2127
+ 'StreamUnaryClientInterceptor',
2128
+ 'StreamStreamClientInterceptor',
2129
+ 'Channel',
2130
+ 'ServicerContext',
2131
+ 'RpcMethodHandler',
2132
+ 'HandlerCallDetails',
2133
+ 'GenericRpcHandler',
2134
+ 'ServiceRpcHandler',
2135
+ 'Server',
2136
+ 'ServerInterceptor',
2137
+ 'unary_unary_rpc_method_handler',
2138
+ 'unary_stream_rpc_method_handler',
2139
+ 'stream_unary_rpc_method_handler',
2140
+ 'stream_stream_rpc_method_handler',
2141
+ 'method_handlers_generic_handler',
2142
+ 'ssl_channel_credentials',
2143
+ 'metadata_call_credentials',
2144
+ 'access_token_call_credentials',
2145
+ 'composite_call_credentials',
2146
+ 'composite_channel_credentials',
2147
+ 'compute_engine_channel_credentials',
2148
+ 'local_channel_credentials',
2149
+ 'local_server_credentials',
2150
+ 'alts_channel_credentials',
2151
+ 'alts_server_credentials',
2152
+ 'ssl_server_credentials',
2153
+ 'ssl_server_certificate_configuration',
2154
+ 'dynamic_ssl_server_credentials',
2155
+ 'channel_ready_future',
2156
+ 'insecure_channel',
2157
+ 'secure_channel',
2158
+ 'intercept_channel',
2159
+ 'server',
2160
+ 'protos',
2161
+ 'services',
2162
+ 'protos_and_services',
2163
+ 'xds_channel_credentials',
2164
+ 'xds_server_credentials',
2165
+ 'insecure_server_credentials',
2166
+ )
2167
+
2168
+ ############################### Extension Shims ################################
2169
+
2170
+ # Here to maintain backwards compatibility; avoid using these in new code!
2171
+ try:
2172
+ import grpc_tools
2173
+ sys.modules.update({'grpc.tools': grpc_tools})
2174
+ except ImportError:
2175
+ pass
2176
+ try:
2177
+ import grpc_health
2178
+ sys.modules.update({'grpc.health': grpc_health})
2179
+ except ImportError:
2180
+ pass
2181
+ try:
2182
+ import grpc_reflection
2183
+ sys.modules.update({'grpc.reflection': grpc_reflection})
2184
+ except ImportError:
2185
+ pass
2186
+
2187
+ # Prevents import order issue in the case of renamed path.
2188
+ if sys.version_info >= (3, 6) and __name__ == "grpc":
2189
+ from grpc import aio # pylint: disable=ungrouped-imports
2190
+ sys.modules.update({'grpc.aio': aio})
my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/grpc/_channel.py ADDED
@@ -0,0 +1,1585 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2016 gRPC authors.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+ """Invocation-side implementation of gRPC Python."""
15
+
16
+ import copy
17
+ import functools
18
+ import logging
19
+ import os
20
+ import sys
21
+ import threading
22
+ import time
23
+
24
+ import grpc
25
+ from grpc import _common
26
+ from grpc import _compression
27
+ from grpc import _grpcio_metadata
28
+ from grpc._cython import cygrpc
29
+ import grpc.experimental
30
+
31
+ _LOGGER = logging.getLogger(__name__)
32
+
33
+ _USER_AGENT = 'grpc-python/{}'.format(_grpcio_metadata.__version__)
34
+
35
+ _EMPTY_FLAGS = 0
36
+
37
+ # NOTE(rbellevi): No guarantees are given about the maintenance of this
38
+ # environment variable.
39
+ _DEFAULT_SINGLE_THREADED_UNARY_STREAM = os.getenv(
40
+ "GRPC_SINGLE_THREADED_UNARY_STREAM") is not None
41
+
42
+ _UNARY_UNARY_INITIAL_DUE = (
43
+ cygrpc.OperationType.send_initial_metadata,
44
+ cygrpc.OperationType.send_message,
45
+ cygrpc.OperationType.send_close_from_client,
46
+ cygrpc.OperationType.receive_initial_metadata,
47
+ cygrpc.OperationType.receive_message,
48
+ cygrpc.OperationType.receive_status_on_client,
49
+ )
50
+ _UNARY_STREAM_INITIAL_DUE = (
51
+ cygrpc.OperationType.send_initial_metadata,
52
+ cygrpc.OperationType.send_message,
53
+ cygrpc.OperationType.send_close_from_client,
54
+ cygrpc.OperationType.receive_initial_metadata,
55
+ cygrpc.OperationType.receive_status_on_client,
56
+ )
57
+ _STREAM_UNARY_INITIAL_DUE = (
58
+ cygrpc.OperationType.send_initial_metadata,
59
+ cygrpc.OperationType.receive_initial_metadata,
60
+ cygrpc.OperationType.receive_message,
61
+ cygrpc.OperationType.receive_status_on_client,
62
+ )
63
+ _STREAM_STREAM_INITIAL_DUE = (
64
+ cygrpc.OperationType.send_initial_metadata,
65
+ cygrpc.OperationType.receive_initial_metadata,
66
+ cygrpc.OperationType.receive_status_on_client,
67
+ )
68
+
69
+ _CHANNEL_SUBSCRIPTION_CALLBACK_ERROR_LOG_MESSAGE = (
70
+ 'Exception calling channel subscription callback!')
71
+
72
+ _OK_RENDEZVOUS_REPR_FORMAT = ('<{} of RPC that terminated with:\n'
73
+ '\tstatus = {}\n'
74
+ '\tdetails = "{}"\n'
75
+ '>')
76
+
77
+ _NON_OK_RENDEZVOUS_REPR_FORMAT = ('<{} of RPC that terminated with:\n'
78
+ '\tstatus = {}\n'
79
+ '\tdetails = "{}"\n'
80
+ '\tdebug_error_string = "{}"\n'
81
+ '>')
82
+
83
+
84
+ def _deadline(timeout):
85
+ return None if timeout is None else time.time() + timeout
86
+
87
+
88
+ def _unknown_code_details(unknown_cygrpc_code, details):
89
+ return 'Server sent unknown code {} and details "{}"'.format(
90
+ unknown_cygrpc_code, details)
91
+
92
+
93
+ class _RPCState(object):
94
+
95
+ def __init__(self, due, initial_metadata, trailing_metadata, code, details):
96
+ # `condition` guards all members of _RPCState. `notify_all` is called on
97
+ # `condition` when the state of the RPC has changed.
98
+ self.condition = threading.Condition()
99
+
100
+ # The cygrpc.OperationType objects representing events due from the RPC's
101
+ # completion queue. If an operation is in `due`, it is guaranteed that
102
+ # `operate()` has been called on a corresponding operation. But the
103
+ # converse is not true. That is, in the case of failed `operate()`
104
+ # calls, there may briefly be events in `due` that do not correspond to
105
+ # operations submitted to Core.
106
+ self.due = set(due)
107
+ self.initial_metadata = initial_metadata
108
+ self.response = None
109
+ self.trailing_metadata = trailing_metadata
110
+ self.code = code
111
+ self.details = details
112
+ self.debug_error_string = None
113
+
114
+ # The semantics of grpc.Future.cancel and grpc.Future.cancelled are
115
+ # slightly wonky, so they have to be tracked separately from the rest of the
116
+ # result of the RPC. This field tracks whether cancellation was requested
117
+ # prior to termination of the RPC.
118
+ self.cancelled = False
119
+ self.callbacks = []
120
+ self.fork_epoch = cygrpc.get_fork_epoch()
121
+
122
+ def reset_postfork_child(self):
123
+ self.condition = threading.Condition()
124
+
125
+
126
+ def _abort(state, code, details):
127
+ if state.code is None:
128
+ state.code = code
129
+ state.details = details
130
+ if state.initial_metadata is None:
131
+ state.initial_metadata = ()
132
+ state.trailing_metadata = ()
133
+
134
+
135
+ def _handle_event(event, state, response_deserializer):
136
+ callbacks = []
137
+ for batch_operation in event.batch_operations:
138
+ operation_type = batch_operation.type()
139
+ state.due.remove(operation_type)
140
+ if operation_type == cygrpc.OperationType.receive_initial_metadata:
141
+ state.initial_metadata = batch_operation.initial_metadata()
142
+ elif operation_type == cygrpc.OperationType.receive_message:
143
+ serialized_response = batch_operation.message()
144
+ if serialized_response is not None:
145
+ response = _common.deserialize(serialized_response,
146
+ response_deserializer)
147
+ if response is None:
148
+ details = 'Exception deserializing response!'
149
+ _abort(state, grpc.StatusCode.INTERNAL, details)
150
+ else:
151
+ state.response = response
152
+ elif operation_type == cygrpc.OperationType.receive_status_on_client:
153
+ state.trailing_metadata = batch_operation.trailing_metadata()
154
+ if state.code is None:
155
+ code = _common.CYGRPC_STATUS_CODE_TO_STATUS_CODE.get(
156
+ batch_operation.code())
157
+ if code is None:
158
+ state.code = grpc.StatusCode.UNKNOWN
159
+ state.details = _unknown_code_details(
160
+ code, batch_operation.details())
161
+ else:
162
+ state.code = code
163
+ state.details = batch_operation.details()
164
+ state.debug_error_string = batch_operation.error_string()
165
+ callbacks.extend(state.callbacks)
166
+ state.callbacks = None
167
+ return callbacks
168
+
169
+
170
+ def _event_handler(state, response_deserializer):
171
+
172
+ def handle_event(event):
173
+ with state.condition:
174
+ callbacks = _handle_event(event, state, response_deserializer)
175
+ state.condition.notify_all()
176
+ done = not state.due
177
+ for callback in callbacks:
178
+ try:
179
+ callback()
180
+ except Exception as e: # pylint: disable=broad-except
181
+ # NOTE(rbellevi): We suppress but log errors here so as not to
182
+ # kill the channel spin thread.
183
+ logging.error('Exception in callback %s: %s',
184
+ repr(callback.func), repr(e))
185
+ return done and state.fork_epoch >= cygrpc.get_fork_epoch()
186
+
187
+ return handle_event
188
+
189
+
190
+ #pylint: disable=too-many-statements
191
+ def _consume_request_iterator(request_iterator, state, call, request_serializer,
192
+ event_handler):
193
+ """Consume a request iterator supplied by the user."""
194
+
195
+ def consume_request_iterator(): # pylint: disable=too-many-branches
196
+ # Iterate over the request iterator until it is exhausted or an error
197
+ # condition is encountered.
198
+ while True:
199
+ return_from_user_request_generator_invoked = False
200
+ try:
201
+ # The thread may die in user-code. Do not block fork for this.
202
+ cygrpc.enter_user_request_generator()
203
+ request = next(request_iterator)
204
+ except StopIteration:
205
+ break
206
+ except Exception: # pylint: disable=broad-except
207
+ cygrpc.return_from_user_request_generator()
208
+ return_from_user_request_generator_invoked = True
209
+ code = grpc.StatusCode.UNKNOWN
210
+ details = 'Exception iterating requests!'
211
+ _LOGGER.exception(details)
212
+ call.cancel(_common.STATUS_CODE_TO_CYGRPC_STATUS_CODE[code],
213
+ details)
214
+ _abort(state, code, details)
215
+ return
216
+ finally:
217
+ if not return_from_user_request_generator_invoked:
218
+ cygrpc.return_from_user_request_generator()
219
+ serialized_request = _common.serialize(request, request_serializer)
220
+ with state.condition:
221
+ if state.code is None and not state.cancelled:
222
+ if serialized_request is None:
223
+ code = grpc.StatusCode.INTERNAL
224
+ details = 'Exception serializing request!'
225
+ call.cancel(
226
+ _common.STATUS_CODE_TO_CYGRPC_STATUS_CODE[code],
227
+ details)
228
+ _abort(state, code, details)
229
+ return
230
+ else:
231
+ state.due.add(cygrpc.OperationType.send_message)
232
+ operations = (cygrpc.SendMessageOperation(
233
+ serialized_request, _EMPTY_FLAGS),)
234
+ operating = call.operate(operations, event_handler)
235
+ if not operating:
236
+ state.due.remove(cygrpc.OperationType.send_message)
237
+ return
238
+
239
+ def _done():
240
+ return (state.code is not None or
241
+ cygrpc.OperationType.send_message
242
+ not in state.due)
243
+
244
+ _common.wait(state.condition.wait,
245
+ _done,
246
+ spin_cb=functools.partial(
247
+ cygrpc.block_if_fork_in_progress,
248
+ state))
249
+ if state.code is not None:
250
+ return
251
+ else:
252
+ return
253
+ with state.condition:
254
+ if state.code is None:
255
+ state.due.add(cygrpc.OperationType.send_close_from_client)
256
+ operations = (
257
+ cygrpc.SendCloseFromClientOperation(_EMPTY_FLAGS),)
258
+ operating = call.operate(operations, event_handler)
259
+ if not operating:
260
+ state.due.remove(
261
+ cygrpc.OperationType.send_close_from_client)
262
+
263
+ consumption_thread = cygrpc.ForkManagedThread(
264
+ target=consume_request_iterator)
265
+ consumption_thread.setDaemon(True)
266
+ consumption_thread.start()
267
+
268
+
269
+ def _rpc_state_string(class_name, rpc_state):
270
+ """Calculates error string for RPC."""
271
+ with rpc_state.condition:
272
+ if rpc_state.code is None:
273
+ return '<{} object>'.format(class_name)
274
+ elif rpc_state.code is grpc.StatusCode.OK:
275
+ return _OK_RENDEZVOUS_REPR_FORMAT.format(class_name, rpc_state.code,
276
+ rpc_state.details)
277
+ else:
278
+ return _NON_OK_RENDEZVOUS_REPR_FORMAT.format(
279
+ class_name, rpc_state.code, rpc_state.details,
280
+ rpc_state.debug_error_string)
281
+
282
+
283
+ class _InactiveRpcError(grpc.RpcError, grpc.Call, grpc.Future):
284
+ """An RPC error not tied to the execution of a particular RPC.
285
+
286
+ The RPC represented by the state object must not be in-progress or
287
+ cancelled.
288
+
289
+ Attributes:
290
+ _state: An instance of _RPCState.
291
+ """
292
+
293
+ def __init__(self, state):
294
+ with state.condition:
295
+ self._state = _RPCState((), copy.deepcopy(state.initial_metadata),
296
+ copy.deepcopy(state.trailing_metadata),
297
+ state.code, copy.deepcopy(state.details))
298
+ self._state.response = copy.copy(state.response)
299
+ self._state.debug_error_string = copy.copy(state.debug_error_string)
300
+
301
+ def initial_metadata(self):
302
+ return self._state.initial_metadata
303
+
304
+ def trailing_metadata(self):
305
+ return self._state.trailing_metadata
306
+
307
+ def code(self):
308
+ return self._state.code
309
+
310
+ def details(self):
311
+ return _common.decode(self._state.details)
312
+
313
+ def debug_error_string(self):
314
+ return _common.decode(self._state.debug_error_string)
315
+
316
+ def _repr(self):
317
+ return _rpc_state_string(self.__class__.__name__, self._state)
318
+
319
+ def __repr__(self):
320
+ return self._repr()
321
+
322
+ def __str__(self):
323
+ return self._repr()
324
+
325
+ def cancel(self):
326
+ """See grpc.Future.cancel."""
327
+ return False
328
+
329
+ def cancelled(self):
330
+ """See grpc.Future.cancelled."""
331
+ return False
332
+
333
+ def running(self):
334
+ """See grpc.Future.running."""
335
+ return False
336
+
337
+ def done(self):
338
+ """See grpc.Future.done."""
339
+ return True
340
+
341
+ def result(self, timeout=None): # pylint: disable=unused-argument
342
+ """See grpc.Future.result."""
343
+ raise self
344
+
345
+ def exception(self, timeout=None): # pylint: disable=unused-argument
346
+ """See grpc.Future.exception."""
347
+ return self
348
+
349
+ def traceback(self, timeout=None): # pylint: disable=unused-argument
350
+ """See grpc.Future.traceback."""
351
+ try:
352
+ raise self
353
+ except grpc.RpcError:
354
+ return sys.exc_info()[2]
355
+
356
+ def add_done_callback(self, fn, timeout=None): # pylint: disable=unused-argument
357
+ """See grpc.Future.add_done_callback."""
358
+ fn(self)
359
+
360
+
361
+ class _Rendezvous(grpc.RpcError, grpc.RpcContext):
362
+ """An RPC iterator.
363
+
364
+ Attributes:
365
+ _state: An instance of _RPCState.
366
+ _call: An instance of SegregatedCall or IntegratedCall.
367
+ In either case, the _call object is expected to have operate, cancel,
368
+ and next_event methods.
369
+ _response_deserializer: A callable taking bytes and return a Python
370
+ object.
371
+ _deadline: A float representing the deadline of the RPC in seconds. Or
372
+ possibly None, to represent an RPC with no deadline at all.
373
+ """
374
+
375
+ def __init__(self, state, call, response_deserializer, deadline):
376
+ super(_Rendezvous, self).__init__()
377
+ self._state = state
378
+ self._call = call
379
+ self._response_deserializer = response_deserializer
380
+ self._deadline = deadline
381
+
382
+ def is_active(self):
383
+ """See grpc.RpcContext.is_active"""
384
+ with self._state.condition:
385
+ return self._state.code is None
386
+
387
+ def time_remaining(self):
388
+ """See grpc.RpcContext.time_remaining"""
389
+ with self._state.condition:
390
+ if self._deadline is None:
391
+ return None
392
+ else:
393
+ return max(self._deadline - time.time(), 0)
394
+
395
+ def cancel(self):
396
+ """See grpc.RpcContext.cancel"""
397
+ with self._state.condition:
398
+ if self._state.code is None:
399
+ code = grpc.StatusCode.CANCELLED
400
+ details = 'Locally cancelled by application!'
401
+ self._call.cancel(
402
+ _common.STATUS_CODE_TO_CYGRPC_STATUS_CODE[code], details)
403
+ self._state.cancelled = True
404
+ _abort(self._state, code, details)
405
+ self._state.condition.notify_all()
406
+ return True
407
+ else:
408
+ return False
409
+
410
+ def add_callback(self, callback):
411
+ """See grpc.RpcContext.add_callback"""
412
+ with self._state.condition:
413
+ if self._state.callbacks is None:
414
+ return False
415
+ else:
416
+ self._state.callbacks.append(callback)
417
+ return True
418
+
419
+ def __iter__(self):
420
+ return self
421
+
422
+ def next(self):
423
+ return self._next()
424
+
425
+ def __next__(self):
426
+ return self._next()
427
+
428
+ def _next(self):
429
+ raise NotImplementedError()
430
+
431
+ def debug_error_string(self):
432
+ raise NotImplementedError()
433
+
434
+ def _repr(self):
435
+ return _rpc_state_string(self.__class__.__name__, self._state)
436
+
437
+ def __repr__(self):
438
+ return self._repr()
439
+
440
+ def __str__(self):
441
+ return self._repr()
442
+
443
+ def __del__(self):
444
+ with self._state.condition:
445
+ if self._state.code is None:
446
+ self._state.code = grpc.StatusCode.CANCELLED
447
+ self._state.details = 'Cancelled upon garbage collection!'
448
+ self._state.cancelled = True
449
+ self._call.cancel(
450
+ _common.STATUS_CODE_TO_CYGRPC_STATUS_CODE[self._state.code],
451
+ self._state.details)
452
+ self._state.condition.notify_all()
453
+
454
+
455
+ class _SingleThreadedRendezvous(_Rendezvous, grpc.Call, grpc.Future): # pylint: disable=too-many-ancestors
456
+ """An RPC iterator operating entirely on a single thread.
457
+
458
+ The __next__ method of _SingleThreadedRendezvous does not depend on the
459
+ existence of any other thread, including the "channel spin thread".
460
+ However, this means that its interface is entirely synchronous. So this
461
+ class cannot completely fulfill the grpc.Future interface. The result,
462
+ exception, and traceback methods will never block and will instead raise
463
+ an exception if calling the method would result in blocking.
464
+
465
+ This means that these methods are safe to call from add_done_callback
466
+ handlers.
467
+ """
468
+
469
+ def _is_complete(self):
470
+ return self._state.code is not None
471
+
472
+ def cancelled(self):
473
+ with self._state.condition:
474
+ return self._state.cancelled
475
+
476
+ def running(self):
477
+ with self._state.condition:
478
+ return self._state.code is None
479
+
480
+ def done(self):
481
+ with self._state.condition:
482
+ return self._state.code is not None
483
+
484
+ def result(self, timeout=None):
485
+ """Returns the result of the computation or raises its exception.
486
+
487
+ This method will never block. Instead, it will raise an exception
488
+ if calling this method would otherwise result in blocking.
489
+
490
+ Since this method will never block, any `timeout` argument passed will
491
+ be ignored.
492
+ """
493
+ del timeout
494
+ with self._state.condition:
495
+ if not self._is_complete():
496
+ raise grpc.experimental.UsageError(
497
+ "_SingleThreadedRendezvous only supports result() when the RPC is complete."
498
+ )
499
+ if self._state.code is grpc.StatusCode.OK:
500
+ return self._state.response
501
+ elif self._state.cancelled:
502
+ raise grpc.FutureCancelledError()
503
+ else:
504
+ raise self
505
+
506
+ def exception(self, timeout=None):
507
+ """Return the exception raised by the computation.
508
+
509
+ This method will never block. Instead, it will raise an exception
510
+ if calling this method would otherwise result in blocking.
511
+
512
+ Since this method will never block, any `timeout` argument passed will
513
+ be ignored.
514
+ """
515
+ del timeout
516
+ with self._state.condition:
517
+ if not self._is_complete():
518
+ raise grpc.experimental.UsageError(
519
+ "_SingleThreadedRendezvous only supports exception() when the RPC is complete."
520
+ )
521
+ if self._state.code is grpc.StatusCode.OK:
522
+ return None
523
+ elif self._state.cancelled:
524
+ raise grpc.FutureCancelledError()
525
+ else:
526
+ return self
527
+
528
+ def traceback(self, timeout=None):
529
+ """Access the traceback of the exception raised by the computation.
530
+
531
+ This method will never block. Instead, it will raise an exception
532
+ if calling this method would otherwise result in blocking.
533
+
534
+ Since this method will never block, any `timeout` argument passed will
535
+ be ignored.
536
+ """
537
+ del timeout
538
+ with self._state.condition:
539
+ if not self._is_complete():
540
+ raise grpc.experimental.UsageError(
541
+ "_SingleThreadedRendezvous only supports traceback() when the RPC is complete."
542
+ )
543
+ if self._state.code is grpc.StatusCode.OK:
544
+ return None
545
+ elif self._state.cancelled:
546
+ raise grpc.FutureCancelledError()
547
+ else:
548
+ try:
549
+ raise self
550
+ except grpc.RpcError:
551
+ return sys.exc_info()[2]
552
+
553
+ def add_done_callback(self, fn):
554
+ with self._state.condition:
555
+ if self._state.code is None:
556
+ self._state.callbacks.append(functools.partial(fn, self))
557
+ return
558
+
559
+ fn(self)
560
+
561
+ def initial_metadata(self):
562
+ """See grpc.Call.initial_metadata"""
563
+ with self._state.condition:
564
+ # NOTE(gnossen): Based on our initial call batch, we are guaranteed
565
+ # to receive initial metadata before any messages.
566
+ while self._state.initial_metadata is None:
567
+ self._consume_next_event()
568
+ return self._state.initial_metadata
569
+
570
+ def trailing_metadata(self):
571
+ """See grpc.Call.trailing_metadata"""
572
+ with self._state.condition:
573
+ if self._state.trailing_metadata is None:
574
+ raise grpc.experimental.UsageError(
575
+ "Cannot get trailing metadata until RPC is completed.")
576
+ return self._state.trailing_metadata
577
+
578
+ def code(self):
579
+ """See grpc.Call.code"""
580
+ with self._state.condition:
581
+ if self._state.code is None:
582
+ raise grpc.experimental.UsageError(
583
+ "Cannot get code until RPC is completed.")
584
+ return self._state.code
585
+
586
+ def details(self):
587
+ """See grpc.Call.details"""
588
+ with self._state.condition:
589
+ if self._state.details is None:
590
+ raise grpc.experimental.UsageError(
591
+ "Cannot get details until RPC is completed.")
592
+ return _common.decode(self._state.details)
593
+
594
+ def _consume_next_event(self):
595
+ event = self._call.next_event()
596
+ with self._state.condition:
597
+ callbacks = _handle_event(event, self._state,
598
+ self._response_deserializer)
599
+ for callback in callbacks:
600
+ # NOTE(gnossen): We intentionally allow exceptions to bubble up
601
+ # to the user when running on a single thread.
602
+ callback()
603
+ return event
604
+
605
+ def _next_response(self):
606
+ while True:
607
+ self._consume_next_event()
608
+ with self._state.condition:
609
+ if self._state.response is not None:
610
+ response = self._state.response
611
+ self._state.response = None
612
+ return response
613
+ elif cygrpc.OperationType.receive_message not in self._state.due:
614
+ if self._state.code is grpc.StatusCode.OK:
615
+ raise StopIteration()
616
+ elif self._state.code is not None:
617
+ raise self
618
+
619
+ def _next(self):
620
+ with self._state.condition:
621
+ if self._state.code is None:
622
+ # We tentatively add the operation as expected and remove
623
+ # it if the enqueue operation fails. This allows us to guarantee that
624
+ # if an event has been submitted to the core completion queue,
625
+ # it is in `due`. If we waited until after a successful
626
+ # enqueue operation then a signal could interrupt this
627
+ # thread between the enqueue operation and the addition of the
628
+ # operation to `due`. This would cause an exception on the
629
+ # channel spin thread when the operation completes and no
630
+ # corresponding operation would be present in state.due.
631
+ # Note that, since `condition` is held through this block, there is
632
+ # no data race on `due`.
633
+ self._state.due.add(cygrpc.OperationType.receive_message)
634
+ operating = self._call.operate(
635
+ (cygrpc.ReceiveMessageOperation(_EMPTY_FLAGS),), None)
636
+ if not operating:
637
+ self._state.due.remove(cygrpc.OperationType.receive_message)
638
+ elif self._state.code is grpc.StatusCode.OK:
639
+ raise StopIteration()
640
+ else:
641
+ raise self
642
+ return self._next_response()
643
+
644
+ def debug_error_string(self):
645
+ with self._state.condition:
646
+ if self._state.debug_error_string is None:
647
+ raise grpc.experimental.UsageError(
648
+ "Cannot get debug error string until RPC is completed.")
649
+ return _common.decode(self._state.debug_error_string)
650
+
651
+
652
+ class _MultiThreadedRendezvous(_Rendezvous, grpc.Call, grpc.Future): # pylint: disable=too-many-ancestors
653
+ """An RPC iterator that depends on a channel spin thread.
654
+
655
+ This iterator relies upon a per-channel thread running in the background,
656
+ dequeueing events from the completion queue, and notifying threads waiting
657
+ on the threading.Condition object in the _RPCState object.
658
+
659
+ This extra thread allows _MultiThreadedRendezvous to fulfill the grpc.Future interface
660
+ and to mediate a bidirection streaming RPC.
661
+ """
662
+
663
+ def initial_metadata(self):
664
+ """See grpc.Call.initial_metadata"""
665
+ with self._state.condition:
666
+
667
+ def _done():
668
+ return self._state.initial_metadata is not None
669
+
670
+ _common.wait(self._state.condition.wait, _done)
671
+ return self._state.initial_metadata
672
+
673
+ def trailing_metadata(self):
674
+ """See grpc.Call.trailing_metadata"""
675
+ with self._state.condition:
676
+
677
+ def _done():
678
+ return self._state.trailing_metadata is not None
679
+
680
+ _common.wait(self._state.condition.wait, _done)
681
+ return self._state.trailing_metadata
682
+
683
+ def code(self):
684
+ """See grpc.Call.code"""
685
+ with self._state.condition:
686
+
687
+ def _done():
688
+ return self._state.code is not None
689
+
690
+ _common.wait(self._state.condition.wait, _done)
691
+ return self._state.code
692
+
693
+ def details(self):
694
+ """See grpc.Call.details"""
695
+ with self._state.condition:
696
+
697
+ def _done():
698
+ return self._state.details is not None
699
+
700
+ _common.wait(self._state.condition.wait, _done)
701
+ return _common.decode(self._state.details)
702
+
703
+ def debug_error_string(self):
704
+ with self._state.condition:
705
+
706
+ def _done():
707
+ return self._state.debug_error_string is not None
708
+
709
+ _common.wait(self._state.condition.wait, _done)
710
+ return _common.decode(self._state.debug_error_string)
711
+
712
+ def cancelled(self):
713
+ with self._state.condition:
714
+ return self._state.cancelled
715
+
716
+ def running(self):
717
+ with self._state.condition:
718
+ return self._state.code is None
719
+
720
+ def done(self):
721
+ with self._state.condition:
722
+ return self._state.code is not None
723
+
724
+ def _is_complete(self):
725
+ return self._state.code is not None
726
+
727
+ def result(self, timeout=None):
728
+ """Returns the result of the computation or raises its exception.
729
+
730
+ See grpc.Future.result for the full API contract.
731
+ """
732
+ with self._state.condition:
733
+ timed_out = _common.wait(self._state.condition.wait,
734
+ self._is_complete,
735
+ timeout=timeout)
736
+ if timed_out:
737
+ raise grpc.FutureTimeoutError()
738
+ else:
739
+ if self._state.code is grpc.StatusCode.OK:
740
+ return self._state.response
741
+ elif self._state.cancelled:
742
+ raise grpc.FutureCancelledError()
743
+ else:
744
+ raise self
745
+
746
+ def exception(self, timeout=None):
747
+ """Return the exception raised by the computation.
748
+
749
+ See grpc.Future.exception for the full API contract.
750
+ """
751
+ with self._state.condition:
752
+ timed_out = _common.wait(self._state.condition.wait,
753
+ self._is_complete,
754
+ timeout=timeout)
755
+ if timed_out:
756
+ raise grpc.FutureTimeoutError()
757
+ else:
758
+ if self._state.code is grpc.StatusCode.OK:
759
+ return None
760
+ elif self._state.cancelled:
761
+ raise grpc.FutureCancelledError()
762
+ else:
763
+ return self
764
+
765
+ def traceback(self, timeout=None):
766
+ """Access the traceback of the exception raised by the computation.
767
+
768
+ See grpc.future.traceback for the full API contract.
769
+ """
770
+ with self._state.condition:
771
+ timed_out = _common.wait(self._state.condition.wait,
772
+ self._is_complete,
773
+ timeout=timeout)
774
+ if timed_out:
775
+ raise grpc.FutureTimeoutError()
776
+ else:
777
+ if self._state.code is grpc.StatusCode.OK:
778
+ return None
779
+ elif self._state.cancelled:
780
+ raise grpc.FutureCancelledError()
781
+ else:
782
+ try:
783
+ raise self
784
+ except grpc.RpcError:
785
+ return sys.exc_info()[2]
786
+
787
+ def add_done_callback(self, fn):
788
+ with self._state.condition:
789
+ if self._state.code is None:
790
+ self._state.callbacks.append(functools.partial(fn, self))
791
+ return
792
+
793
+ fn(self)
794
+
795
+ def _next(self):
796
+ with self._state.condition:
797
+ if self._state.code is None:
798
+ event_handler = _event_handler(self._state,
799
+ self._response_deserializer)
800
+ self._state.due.add(cygrpc.OperationType.receive_message)
801
+ operating = self._call.operate(
802
+ (cygrpc.ReceiveMessageOperation(_EMPTY_FLAGS),),
803
+ event_handler)
804
+ if not operating:
805
+ self._state.due.remove(cygrpc.OperationType.receive_message)
806
+ elif self._state.code is grpc.StatusCode.OK:
807
+ raise StopIteration()
808
+ else:
809
+ raise self
810
+
811
+ def _response_ready():
812
+ return (self._state.response is not None or
813
+ (cygrpc.OperationType.receive_message
814
+ not in self._state.due and
815
+ self._state.code is not None))
816
+
817
+ _common.wait(self._state.condition.wait, _response_ready)
818
+ if self._state.response is not None:
819
+ response = self._state.response
820
+ self._state.response = None
821
+ return response
822
+ elif cygrpc.OperationType.receive_message not in self._state.due:
823
+ if self._state.code is grpc.StatusCode.OK:
824
+ raise StopIteration()
825
+ elif self._state.code is not None:
826
+ raise self
827
+
828
+
829
+ def _start_unary_request(request, timeout, request_serializer):
830
+ deadline = _deadline(timeout)
831
+ serialized_request = _common.serialize(request, request_serializer)
832
+ if serialized_request is None:
833
+ state = _RPCState((), (), (), grpc.StatusCode.INTERNAL,
834
+ 'Exception serializing request!')
835
+ error = _InactiveRpcError(state)
836
+ return deadline, None, error
837
+ else:
838
+ return deadline, serialized_request, None
839
+
840
+
841
+ def _end_unary_response_blocking(state, call, with_call, deadline):
842
+ if state.code is grpc.StatusCode.OK:
843
+ if with_call:
844
+ rendezvous = _MultiThreadedRendezvous(state, call, None, deadline)
845
+ return state.response, rendezvous
846
+ else:
847
+ return state.response
848
+ else:
849
+ raise _InactiveRpcError(state)
850
+
851
+
852
+ def _stream_unary_invocation_operationses(metadata, initial_metadata_flags):
853
+ return (
854
+ (
855
+ cygrpc.SendInitialMetadataOperation(metadata,
856
+ initial_metadata_flags),
857
+ cygrpc.ReceiveMessageOperation(_EMPTY_FLAGS),
858
+ cygrpc.ReceiveStatusOnClientOperation(_EMPTY_FLAGS),
859
+ ),
860
+ (cygrpc.ReceiveInitialMetadataOperation(_EMPTY_FLAGS),),
861
+ )
862
+
863
+
864
+ def _stream_unary_invocation_operationses_and_tags(metadata,
865
+ initial_metadata_flags):
866
+ return tuple((
867
+ operations,
868
+ None,
869
+ ) for operations in _stream_unary_invocation_operationses(
870
+ metadata, initial_metadata_flags))
871
+
872
+
873
+ def _determine_deadline(user_deadline):
874
+ parent_deadline = cygrpc.get_deadline_from_context()
875
+ if parent_deadline is None and user_deadline is None:
876
+ return None
877
+ elif parent_deadline is not None and user_deadline is None:
878
+ return parent_deadline
879
+ elif user_deadline is not None and parent_deadline is None:
880
+ return user_deadline
881
+ else:
882
+ return min(parent_deadline, user_deadline)
883
+
884
+
885
+ class _UnaryUnaryMultiCallable(grpc.UnaryUnaryMultiCallable):
886
+
887
+ # pylint: disable=too-many-arguments
888
+ def __init__(self, channel, managed_call, method, request_serializer,
889
+ response_deserializer):
890
+ self._channel = channel
891
+ self._managed_call = managed_call
892
+ self._method = method
893
+ self._request_serializer = request_serializer
894
+ self._response_deserializer = response_deserializer
895
+ self._context = cygrpc.build_census_context()
896
+
897
+ def _prepare(self, request, timeout, metadata, wait_for_ready, compression):
898
+ deadline, serialized_request, rendezvous = _start_unary_request(
899
+ request, timeout, self._request_serializer)
900
+ initial_metadata_flags = _InitialMetadataFlags().with_wait_for_ready(
901
+ wait_for_ready)
902
+ augmented_metadata = _compression.augment_metadata(
903
+ metadata, compression)
904
+ if serialized_request is None:
905
+ return None, None, None, rendezvous
906
+ else:
907
+ state = _RPCState(_UNARY_UNARY_INITIAL_DUE, None, None, None, None)
908
+ operations = (
909
+ cygrpc.SendInitialMetadataOperation(augmented_metadata,
910
+ initial_metadata_flags),
911
+ cygrpc.SendMessageOperation(serialized_request, _EMPTY_FLAGS),
912
+ cygrpc.SendCloseFromClientOperation(_EMPTY_FLAGS),
913
+ cygrpc.ReceiveInitialMetadataOperation(_EMPTY_FLAGS),
914
+ cygrpc.ReceiveMessageOperation(_EMPTY_FLAGS),
915
+ cygrpc.ReceiveStatusOnClientOperation(_EMPTY_FLAGS),
916
+ )
917
+ return state, operations, deadline, None
918
+
919
+ def _blocking(self, request, timeout, metadata, credentials, wait_for_ready,
920
+ compression):
921
+ state, operations, deadline, rendezvous = self._prepare(
922
+ request, timeout, metadata, wait_for_ready, compression)
923
+ if state is None:
924
+ raise rendezvous # pylint: disable-msg=raising-bad-type
925
+ else:
926
+ call = self._channel.segregated_call(
927
+ cygrpc.PropagationConstants.GRPC_PROPAGATE_DEFAULTS,
928
+ self._method, None, _determine_deadline(deadline), metadata,
929
+ None if credentials is None else credentials._credentials, ((
930
+ operations,
931
+ None,
932
+ ),), self._context)
933
+ event = call.next_event()
934
+ _handle_event(event, state, self._response_deserializer)
935
+ return state, call
936
+
937
+ def __call__(self,
938
+ request,
939
+ timeout=None,
940
+ metadata=None,
941
+ credentials=None,
942
+ wait_for_ready=None,
943
+ compression=None):
944
+ state, call, = self._blocking(request, timeout, metadata, credentials,
945
+ wait_for_ready, compression)
946
+ return _end_unary_response_blocking(state, call, False, None)
947
+
948
+ def with_call(self,
949
+ request,
950
+ timeout=None,
951
+ metadata=None,
952
+ credentials=None,
953
+ wait_for_ready=None,
954
+ compression=None):
955
+ state, call, = self._blocking(request, timeout, metadata, credentials,
956
+ wait_for_ready, compression)
957
+ return _end_unary_response_blocking(state, call, True, None)
958
+
959
+ def future(self,
960
+ request,
961
+ timeout=None,
962
+ metadata=None,
963
+ credentials=None,
964
+ wait_for_ready=None,
965
+ compression=None):
966
+ state, operations, deadline, rendezvous = self._prepare(
967
+ request, timeout, metadata, wait_for_ready, compression)
968
+ if state is None:
969
+ raise rendezvous # pylint: disable-msg=raising-bad-type
970
+ else:
971
+ event_handler = _event_handler(state, self._response_deserializer)
972
+ call = self._managed_call(
973
+ cygrpc.PropagationConstants.GRPC_PROPAGATE_DEFAULTS,
974
+ self._method, None, deadline, metadata,
975
+ None if credentials is None else credentials._credentials,
976
+ (operations,), event_handler, self._context)
977
+ return _MultiThreadedRendezvous(state, call,
978
+ self._response_deserializer,
979
+ deadline)
980
+
981
+
982
+ class _SingleThreadedUnaryStreamMultiCallable(grpc.UnaryStreamMultiCallable):
983
+
984
+ # pylint: disable=too-many-arguments
985
+ def __init__(self, channel, method, request_serializer,
986
+ response_deserializer):
987
+ self._channel = channel
988
+ self._method = method
989
+ self._request_serializer = request_serializer
990
+ self._response_deserializer = response_deserializer
991
+ self._context = cygrpc.build_census_context()
992
+
993
+ def __call__( # pylint: disable=too-many-locals
994
+ self,
995
+ request,
996
+ timeout=None,
997
+ metadata=None,
998
+ credentials=None,
999
+ wait_for_ready=None,
1000
+ compression=None):
1001
+ deadline = _deadline(timeout)
1002
+ serialized_request = _common.serialize(request,
1003
+ self._request_serializer)
1004
+ if serialized_request is None:
1005
+ state = _RPCState((), (), (), grpc.StatusCode.INTERNAL,
1006
+ 'Exception serializing request!')
1007
+ raise _InactiveRpcError(state)
1008
+
1009
+ state = _RPCState(_UNARY_STREAM_INITIAL_DUE, None, None, None, None)
1010
+ call_credentials = None if credentials is None else credentials._credentials
1011
+ initial_metadata_flags = _InitialMetadataFlags().with_wait_for_ready(
1012
+ wait_for_ready)
1013
+ augmented_metadata = _compression.augment_metadata(
1014
+ metadata, compression)
1015
+ operations = (
1016
+ (cygrpc.SendInitialMetadataOperation(augmented_metadata,
1017
+ initial_metadata_flags),
1018
+ cygrpc.SendMessageOperation(serialized_request, _EMPTY_FLAGS),
1019
+ cygrpc.SendCloseFromClientOperation(_EMPTY_FLAGS)),
1020
+ (cygrpc.ReceiveStatusOnClientOperation(_EMPTY_FLAGS),),
1021
+ (cygrpc.ReceiveInitialMetadataOperation(_EMPTY_FLAGS),),
1022
+ )
1023
+ operations_and_tags = tuple((ops, None) for ops in operations)
1024
+ call = self._channel.segregated_call(
1025
+ cygrpc.PropagationConstants.GRPC_PROPAGATE_DEFAULTS, self._method,
1026
+ None, _determine_deadline(deadline), metadata, call_credentials,
1027
+ operations_and_tags, self._context)
1028
+ return _SingleThreadedRendezvous(state, call,
1029
+ self._response_deserializer, deadline)
1030
+
1031
+
1032
+ class _UnaryStreamMultiCallable(grpc.UnaryStreamMultiCallable):
1033
+
1034
+ # pylint: disable=too-many-arguments
1035
+ def __init__(self, channel, managed_call, method, request_serializer,
1036
+ response_deserializer):
1037
+ self._channel = channel
1038
+ self._managed_call = managed_call
1039
+ self._method = method
1040
+ self._request_serializer = request_serializer
1041
+ self._response_deserializer = response_deserializer
1042
+ self._context = cygrpc.build_census_context()
1043
+
1044
+ def __call__( # pylint: disable=too-many-locals
1045
+ self,
1046
+ request,
1047
+ timeout=None,
1048
+ metadata=None,
1049
+ credentials=None,
1050
+ wait_for_ready=None,
1051
+ compression=None):
1052
+ deadline, serialized_request, rendezvous = _start_unary_request(
1053
+ request, timeout, self._request_serializer)
1054
+ initial_metadata_flags = _InitialMetadataFlags().with_wait_for_ready(
1055
+ wait_for_ready)
1056
+ if serialized_request is None:
1057
+ raise rendezvous # pylint: disable-msg=raising-bad-type
1058
+ else:
1059
+ augmented_metadata = _compression.augment_metadata(
1060
+ metadata, compression)
1061
+ state = _RPCState(_UNARY_STREAM_INITIAL_DUE, None, None, None, None)
1062
+ operationses = (
1063
+ (
1064
+ cygrpc.SendInitialMetadataOperation(augmented_metadata,
1065
+ initial_metadata_flags),
1066
+ cygrpc.SendMessageOperation(serialized_request,
1067
+ _EMPTY_FLAGS),
1068
+ cygrpc.SendCloseFromClientOperation(_EMPTY_FLAGS),
1069
+ cygrpc.ReceiveStatusOnClientOperation(_EMPTY_FLAGS),
1070
+ ),
1071
+ (cygrpc.ReceiveInitialMetadataOperation(_EMPTY_FLAGS),),
1072
+ )
1073
+ call = self._managed_call(
1074
+ cygrpc.PropagationConstants.GRPC_PROPAGATE_DEFAULTS,
1075
+ self._method, None, _determine_deadline(deadline), metadata,
1076
+ None if credentials is None else credentials._credentials,
1077
+ operationses, _event_handler(state,
1078
+ self._response_deserializer),
1079
+ self._context)
1080
+ return _MultiThreadedRendezvous(state, call,
1081
+ self._response_deserializer,
1082
+ deadline)
1083
+
1084
+
1085
+ class _StreamUnaryMultiCallable(grpc.StreamUnaryMultiCallable):
1086
+
1087
+ # pylint: disable=too-many-arguments
1088
+ def __init__(self, channel, managed_call, method, request_serializer,
1089
+ response_deserializer):
1090
+ self._channel = channel
1091
+ self._managed_call = managed_call
1092
+ self._method = method
1093
+ self._request_serializer = request_serializer
1094
+ self._response_deserializer = response_deserializer
1095
+ self._context = cygrpc.build_census_context()
1096
+
1097
+ def _blocking(self, request_iterator, timeout, metadata, credentials,
1098
+ wait_for_ready, compression):
1099
+ deadline = _deadline(timeout)
1100
+ state = _RPCState(_STREAM_UNARY_INITIAL_DUE, None, None, None, None)
1101
+ initial_metadata_flags = _InitialMetadataFlags().with_wait_for_ready(
1102
+ wait_for_ready)
1103
+ augmented_metadata = _compression.augment_metadata(
1104
+ metadata, compression)
1105
+ call = self._channel.segregated_call(
1106
+ cygrpc.PropagationConstants.GRPC_PROPAGATE_DEFAULTS, self._method,
1107
+ None, _determine_deadline(deadline), augmented_metadata,
1108
+ None if credentials is None else credentials._credentials,
1109
+ _stream_unary_invocation_operationses_and_tags(
1110
+ augmented_metadata, initial_metadata_flags), self._context)
1111
+ _consume_request_iterator(request_iterator, state, call,
1112
+ self._request_serializer, None)
1113
+ while True:
1114
+ event = call.next_event()
1115
+ with state.condition:
1116
+ _handle_event(event, state, self._response_deserializer)
1117
+ state.condition.notify_all()
1118
+ if not state.due:
1119
+ break
1120
+ return state, call
1121
+
1122
+ def __call__(self,
1123
+ request_iterator,
1124
+ timeout=None,
1125
+ metadata=None,
1126
+ credentials=None,
1127
+ wait_for_ready=None,
1128
+ compression=None):
1129
+ state, call, = self._blocking(request_iterator, timeout, metadata,
1130
+ credentials, wait_for_ready, compression)
1131
+ return _end_unary_response_blocking(state, call, False, None)
1132
+
1133
+ def with_call(self,
1134
+ request_iterator,
1135
+ timeout=None,
1136
+ metadata=None,
1137
+ credentials=None,
1138
+ wait_for_ready=None,
1139
+ compression=None):
1140
+ state, call, = self._blocking(request_iterator, timeout, metadata,
1141
+ credentials, wait_for_ready, compression)
1142
+ return _end_unary_response_blocking(state, call, True, None)
1143
+
1144
+ def future(self,
1145
+ request_iterator,
1146
+ timeout=None,
1147
+ metadata=None,
1148
+ credentials=None,
1149
+ wait_for_ready=None,
1150
+ compression=None):
1151
+ deadline = _deadline(timeout)
1152
+ state = _RPCState(_STREAM_UNARY_INITIAL_DUE, None, None, None, None)
1153
+ event_handler = _event_handler(state, self._response_deserializer)
1154
+ initial_metadata_flags = _InitialMetadataFlags().with_wait_for_ready(
1155
+ wait_for_ready)
1156
+ augmented_metadata = _compression.augment_metadata(
1157
+ metadata, compression)
1158
+ call = self._managed_call(
1159
+ cygrpc.PropagationConstants.GRPC_PROPAGATE_DEFAULTS, self._method,
1160
+ None, deadline, augmented_metadata,
1161
+ None if credentials is None else credentials._credentials,
1162
+ _stream_unary_invocation_operationses(metadata,
1163
+ initial_metadata_flags),
1164
+ event_handler, self._context)
1165
+ _consume_request_iterator(request_iterator, state, call,
1166
+ self._request_serializer, event_handler)
1167
+ return _MultiThreadedRendezvous(state, call,
1168
+ self._response_deserializer, deadline)
1169
+
1170
+
1171
+ class _StreamStreamMultiCallable(grpc.StreamStreamMultiCallable):
1172
+
1173
+ # pylint: disable=too-many-arguments
1174
+ def __init__(self, channel, managed_call, method, request_serializer,
1175
+ response_deserializer):
1176
+ self._channel = channel
1177
+ self._managed_call = managed_call
1178
+ self._method = method
1179
+ self._request_serializer = request_serializer
1180
+ self._response_deserializer = response_deserializer
1181
+ self._context = cygrpc.build_census_context()
1182
+
1183
+ def __call__(self,
1184
+ request_iterator,
1185
+ timeout=None,
1186
+ metadata=None,
1187
+ credentials=None,
1188
+ wait_for_ready=None,
1189
+ compression=None):
1190
+ deadline = _deadline(timeout)
1191
+ state = _RPCState(_STREAM_STREAM_INITIAL_DUE, None, None, None, None)
1192
+ initial_metadata_flags = _InitialMetadataFlags().with_wait_for_ready(
1193
+ wait_for_ready)
1194
+ augmented_metadata = _compression.augment_metadata(
1195
+ metadata, compression)
1196
+ operationses = (
1197
+ (
1198
+ cygrpc.SendInitialMetadataOperation(augmented_metadata,
1199
+ initial_metadata_flags),
1200
+ cygrpc.ReceiveStatusOnClientOperation(_EMPTY_FLAGS),
1201
+ ),
1202
+ (cygrpc.ReceiveInitialMetadataOperation(_EMPTY_FLAGS),),
1203
+ )
1204
+ event_handler = _event_handler(state, self._response_deserializer)
1205
+ call = self._managed_call(
1206
+ cygrpc.PropagationConstants.GRPC_PROPAGATE_DEFAULTS, self._method,
1207
+ None, _determine_deadline(deadline), augmented_metadata,
1208
+ None if credentials is None else credentials._credentials,
1209
+ operationses, event_handler, self._context)
1210
+ _consume_request_iterator(request_iterator, state, call,
1211
+ self._request_serializer, event_handler)
1212
+ return _MultiThreadedRendezvous(state, call,
1213
+ self._response_deserializer, deadline)
1214
+
1215
+
1216
+ class _InitialMetadataFlags(int):
1217
+ """Stores immutable initial metadata flags"""
1218
+
1219
+ def __new__(cls, value=_EMPTY_FLAGS):
1220
+ value &= cygrpc.InitialMetadataFlags.used_mask
1221
+ return super(_InitialMetadataFlags, cls).__new__(cls, value)
1222
+
1223
+ def with_wait_for_ready(self, wait_for_ready):
1224
+ if wait_for_ready is not None:
1225
+ if wait_for_ready:
1226
+ return self.__class__(self | cygrpc.InitialMetadataFlags.wait_for_ready | \
1227
+ cygrpc.InitialMetadataFlags.wait_for_ready_explicitly_set)
1228
+ elif not wait_for_ready:
1229
+ return self.__class__(self & ~cygrpc.InitialMetadataFlags.wait_for_ready | \
1230
+ cygrpc.InitialMetadataFlags.wait_for_ready_explicitly_set)
1231
+ return self
1232
+
1233
+
1234
+ class _ChannelCallState(object):
1235
+
1236
+ def __init__(self, channel):
1237
+ self.lock = threading.Lock()
1238
+ self.channel = channel
1239
+ self.managed_calls = 0
1240
+ self.threading = False
1241
+
1242
+ def reset_postfork_child(self):
1243
+ self.managed_calls = 0
1244
+
1245
+ def __del__(self):
1246
+ try:
1247
+ self.channel.close(cygrpc.StatusCode.cancelled,
1248
+ 'Channel deallocated!')
1249
+ except (TypeError, AttributeError):
1250
+ pass
1251
+
1252
+
1253
+ def _run_channel_spin_thread(state):
1254
+
1255
+ def channel_spin():
1256
+ while True:
1257
+ cygrpc.block_if_fork_in_progress(state)
1258
+ event = state.channel.next_call_event()
1259
+ if event.completion_type == cygrpc.CompletionType.queue_timeout:
1260
+ continue
1261
+ call_completed = event.tag(event)
1262
+ if call_completed:
1263
+ with state.lock:
1264
+ state.managed_calls -= 1
1265
+ if state.managed_calls == 0:
1266
+ return
1267
+
1268
+ channel_spin_thread = cygrpc.ForkManagedThread(target=channel_spin)
1269
+ channel_spin_thread.setDaemon(True)
1270
+ channel_spin_thread.start()
1271
+
1272
+
1273
+ def _channel_managed_call_management(state):
1274
+
1275
+ # pylint: disable=too-many-arguments
1276
+ def create(flags, method, host, deadline, metadata, credentials,
1277
+ operationses, event_handler, context):
1278
+ """Creates a cygrpc.IntegratedCall.
1279
+
1280
+ Args:
1281
+ flags: An integer bitfield of call flags.
1282
+ method: The RPC method.
1283
+ host: A host string for the created call.
1284
+ deadline: A float to be the deadline of the created call or None if
1285
+ the call is to have an infinite deadline.
1286
+ metadata: The metadata for the call or None.
1287
+ credentials: A cygrpc.CallCredentials or None.
1288
+ operationses: An iterable of iterables of cygrpc.Operations to be
1289
+ started on the call.
1290
+ event_handler: A behavior to call to handle the events resultant from
1291
+ the operations on the call.
1292
+ context: Context object for distributed tracing.
1293
+ Returns:
1294
+ A cygrpc.IntegratedCall with which to conduct an RPC.
1295
+ """
1296
+ operationses_and_tags = tuple((
1297
+ operations,
1298
+ event_handler,
1299
+ ) for operations in operationses)
1300
+ with state.lock:
1301
+ call = state.channel.integrated_call(flags, method, host, deadline,
1302
+ metadata, credentials,
1303
+ operationses_and_tags, context)
1304
+ if state.managed_calls == 0:
1305
+ state.managed_calls = 1
1306
+ _run_channel_spin_thread(state)
1307
+ else:
1308
+ state.managed_calls += 1
1309
+ return call
1310
+
1311
+ return create
1312
+
1313
+
1314
+ class _ChannelConnectivityState(object):
1315
+
1316
+ def __init__(self, channel):
1317
+ self.lock = threading.RLock()
1318
+ self.channel = channel
1319
+ self.polling = False
1320
+ self.connectivity = None
1321
+ self.try_to_connect = False
1322
+ self.callbacks_and_connectivities = []
1323
+ self.delivering = False
1324
+
1325
+ def reset_postfork_child(self):
1326
+ self.polling = False
1327
+ self.connectivity = None
1328
+ self.try_to_connect = False
1329
+ self.callbacks_and_connectivities = []
1330
+ self.delivering = False
1331
+
1332
+
1333
+ def _deliveries(state):
1334
+ callbacks_needing_update = []
1335
+ for callback_and_connectivity in state.callbacks_and_connectivities:
1336
+ callback, callback_connectivity, = callback_and_connectivity
1337
+ if callback_connectivity is not state.connectivity:
1338
+ callbacks_needing_update.append(callback)
1339
+ callback_and_connectivity[1] = state.connectivity
1340
+ return callbacks_needing_update
1341
+
1342
+
1343
+ def _deliver(state, initial_connectivity, initial_callbacks):
1344
+ connectivity = initial_connectivity
1345
+ callbacks = initial_callbacks
1346
+ while True:
1347
+ for callback in callbacks:
1348
+ cygrpc.block_if_fork_in_progress(state)
1349
+ try:
1350
+ callback(connectivity)
1351
+ except Exception: # pylint: disable=broad-except
1352
+ _LOGGER.exception(
1353
+ _CHANNEL_SUBSCRIPTION_CALLBACK_ERROR_LOG_MESSAGE)
1354
+ with state.lock:
1355
+ callbacks = _deliveries(state)
1356
+ if callbacks:
1357
+ connectivity = state.connectivity
1358
+ else:
1359
+ state.delivering = False
1360
+ return
1361
+
1362
+
1363
+ def _spawn_delivery(state, callbacks):
1364
+ delivering_thread = cygrpc.ForkManagedThread(target=_deliver,
1365
+ args=(
1366
+ state,
1367
+ state.connectivity,
1368
+ callbacks,
1369
+ ))
1370
+ delivering_thread.setDaemon(True)
1371
+ delivering_thread.start()
1372
+ state.delivering = True
1373
+
1374
+
1375
+ # NOTE(https://github.com/grpc/grpc/issues/3064): We'd rather not poll.
1376
+ def _poll_connectivity(state, channel, initial_try_to_connect):
1377
+ try_to_connect = initial_try_to_connect
1378
+ connectivity = channel.check_connectivity_state(try_to_connect)
1379
+ with state.lock:
1380
+ state.connectivity = (
1381
+ _common.
1382
+ CYGRPC_CONNECTIVITY_STATE_TO_CHANNEL_CONNECTIVITY[connectivity])
1383
+ callbacks = tuple(
1384
+ callback for callback, unused_but_known_to_be_none_connectivity in
1385
+ state.callbacks_and_connectivities)
1386
+ for callback_and_connectivity in state.callbacks_and_connectivities:
1387
+ callback_and_connectivity[1] = state.connectivity
1388
+ if callbacks:
1389
+ _spawn_delivery(state, callbacks)
1390
+ while True:
1391
+ event = channel.watch_connectivity_state(connectivity,
1392
+ time.time() + 0.2)
1393
+ cygrpc.block_if_fork_in_progress(state)
1394
+ with state.lock:
1395
+ if not state.callbacks_and_connectivities and not state.try_to_connect:
1396
+ state.polling = False
1397
+ state.connectivity = None
1398
+ break
1399
+ try_to_connect = state.try_to_connect
1400
+ state.try_to_connect = False
1401
+ if event.success or try_to_connect:
1402
+ connectivity = channel.check_connectivity_state(try_to_connect)
1403
+ with state.lock:
1404
+ state.connectivity = (
1405
+ _common.CYGRPC_CONNECTIVITY_STATE_TO_CHANNEL_CONNECTIVITY[
1406
+ connectivity])
1407
+ if not state.delivering:
1408
+ callbacks = _deliveries(state)
1409
+ if callbacks:
1410
+ _spawn_delivery(state, callbacks)
1411
+
1412
+
1413
+ def _subscribe(state, callback, try_to_connect):
1414
+ with state.lock:
1415
+ if not state.callbacks_and_connectivities and not state.polling:
1416
+ polling_thread = cygrpc.ForkManagedThread(
1417
+ target=_poll_connectivity,
1418
+ args=(state, state.channel, bool(try_to_connect)))
1419
+ polling_thread.setDaemon(True)
1420
+ polling_thread.start()
1421
+ state.polling = True
1422
+ state.callbacks_and_connectivities.append([callback, None])
1423
+ elif not state.delivering and state.connectivity is not None:
1424
+ _spawn_delivery(state, (callback,))
1425
+ state.try_to_connect |= bool(try_to_connect)
1426
+ state.callbacks_and_connectivities.append(
1427
+ [callback, state.connectivity])
1428
+ else:
1429
+ state.try_to_connect |= bool(try_to_connect)
1430
+ state.callbacks_and_connectivities.append([callback, None])
1431
+
1432
+
1433
+ def _unsubscribe(state, callback):
1434
+ with state.lock:
1435
+ for index, (subscribed_callback, unused_connectivity) in enumerate(
1436
+ state.callbacks_and_connectivities):
1437
+ if callback == subscribed_callback:
1438
+ state.callbacks_and_connectivities.pop(index)
1439
+ break
1440
+
1441
+
1442
+ def _augment_options(base_options, compression):
1443
+ compression_option = _compression.create_channel_option(compression)
1444
+ return tuple(base_options) + compression_option + ((
1445
+ cygrpc.ChannelArgKey.primary_user_agent_string,
1446
+ _USER_AGENT,
1447
+ ),)
1448
+
1449
+
1450
+ def _separate_channel_options(options):
1451
+ """Separates core channel options from Python channel options."""
1452
+ core_options = []
1453
+ python_options = []
1454
+ for pair in options:
1455
+ if pair[0] == grpc.experimental.ChannelOptions.SingleThreadedUnaryStream:
1456
+ python_options.append(pair)
1457
+ else:
1458
+ core_options.append(pair)
1459
+ return python_options, core_options
1460
+
1461
+
1462
+ class Channel(grpc.Channel):
1463
+ """A cygrpc.Channel-backed implementation of grpc.Channel."""
1464
+
1465
+ def __init__(self, target, options, credentials, compression):
1466
+ """Constructor.
1467
+
1468
+ Args:
1469
+ target: The target to which to connect.
1470
+ options: Configuration options for the channel.
1471
+ credentials: A cygrpc.ChannelCredentials or None.
1472
+ compression: An optional value indicating the compression method to be
1473
+ used over the lifetime of the channel.
1474
+ """
1475
+ python_options, core_options = _separate_channel_options(options)
1476
+ self._single_threaded_unary_stream = _DEFAULT_SINGLE_THREADED_UNARY_STREAM
1477
+ self._process_python_options(python_options)
1478
+ self._channel = cygrpc.Channel(
1479
+ _common.encode(target), _augment_options(core_options, compression),
1480
+ credentials)
1481
+ self._call_state = _ChannelCallState(self._channel)
1482
+ self._connectivity_state = _ChannelConnectivityState(self._channel)
1483
+ cygrpc.fork_register_channel(self)
1484
+ if cygrpc.g_gevent_activated:
1485
+ cygrpc.gevent_increment_channel_count()
1486
+
1487
+ def _process_python_options(self, python_options):
1488
+ """Sets channel attributes according to python-only channel options."""
1489
+ for pair in python_options:
1490
+ if pair[0] == grpc.experimental.ChannelOptions.SingleThreadedUnaryStream:
1491
+ self._single_threaded_unary_stream = True
1492
+
1493
+ def subscribe(self, callback, try_to_connect=None):
1494
+ _subscribe(self._connectivity_state, callback, try_to_connect)
1495
+
1496
+ def unsubscribe(self, callback):
1497
+ _unsubscribe(self._connectivity_state, callback)
1498
+
1499
+ def unary_unary(self,
1500
+ method,
1501
+ request_serializer=None,
1502
+ response_deserializer=None):
1503
+ return _UnaryUnaryMultiCallable(
1504
+ self._channel, _channel_managed_call_management(self._call_state),
1505
+ _common.encode(method), request_serializer, response_deserializer)
1506
+
1507
+ def unary_stream(self,
1508
+ method,
1509
+ request_serializer=None,
1510
+ response_deserializer=None):
1511
+ # NOTE(rbellevi): Benchmarks have shown that running a unary-stream RPC
1512
+ # on a single Python thread results in an appreciable speed-up. However,
1513
+ # due to slight differences in capability, the multi-threaded variant
1514
+ # remains the default.
1515
+ if self._single_threaded_unary_stream:
1516
+ return _SingleThreadedUnaryStreamMultiCallable(
1517
+ self._channel, _common.encode(method), request_serializer,
1518
+ response_deserializer)
1519
+ else:
1520
+ return _UnaryStreamMultiCallable(
1521
+ self._channel,
1522
+ _channel_managed_call_management(self._call_state),
1523
+ _common.encode(method), request_serializer,
1524
+ response_deserializer)
1525
+
1526
+ def stream_unary(self,
1527
+ method,
1528
+ request_serializer=None,
1529
+ response_deserializer=None):
1530
+ return _StreamUnaryMultiCallable(
1531
+ self._channel, _channel_managed_call_management(self._call_state),
1532
+ _common.encode(method), request_serializer, response_deserializer)
1533
+
1534
+ def stream_stream(self,
1535
+ method,
1536
+ request_serializer=None,
1537
+ response_deserializer=None):
1538
+ return _StreamStreamMultiCallable(
1539
+ self._channel, _channel_managed_call_management(self._call_state),
1540
+ _common.encode(method), request_serializer, response_deserializer)
1541
+
1542
+ def _unsubscribe_all(self):
1543
+ state = self._connectivity_state
1544
+ if state:
1545
+ with state.lock:
1546
+ del state.callbacks_and_connectivities[:]
1547
+
1548
+ def _close(self):
1549
+ self._unsubscribe_all()
1550
+ self._channel.close(cygrpc.StatusCode.cancelled, 'Channel closed!')
1551
+ cygrpc.fork_unregister_channel(self)
1552
+ if cygrpc.g_gevent_activated:
1553
+ cygrpc.gevent_decrement_channel_count()
1554
+
1555
+ def _close_on_fork(self):
1556
+ self._unsubscribe_all()
1557
+ self._channel.close_on_fork(cygrpc.StatusCode.cancelled,
1558
+ 'Channel closed due to fork')
1559
+
1560
+ def __enter__(self):
1561
+ return self
1562
+
1563
+ def __exit__(self, exc_type, exc_val, exc_tb):
1564
+ self._close()
1565
+ return False
1566
+
1567
+ def close(self):
1568
+ self._close()
1569
+
1570
+ def __del__(self):
1571
+ # TODO(https://github.com/grpc/grpc/issues/12531): Several releases
1572
+ # after 1.12 (1.16 or thereabouts?) add a "self._channel.close" call
1573
+ # here (or more likely, call self._close() here). We don't do this today
1574
+ # because many valid use cases today allow the channel to be deleted
1575
+ # immediately after stubs are created. After a sufficient period of time
1576
+ # has passed for all users to be trusted to freeze out to their channels
1577
+ # for as long as they are in use and to close them after using them,
1578
+ # then deletion of this grpc._channel.Channel instance can be made to
1579
+ # effect closure of the underlying cygrpc.Channel instance.
1580
+ try:
1581
+ self._unsubscribe_all()
1582
+ except: # pylint: disable=bare-except
1583
+ # Exceptions in __del__ are ignored by Python anyway, but they can
1584
+ # keep spamming logs. Just silence them.
1585
+ pass
my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/grpc/_common.py ADDED
@@ -0,0 +1,168 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2016 gRPC authors.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+ """Shared implementation."""
15
+
16
+ import logging
17
+ import time
18
+
19
+ import grpc
20
+ from grpc._cython import cygrpc
21
+ import six
22
+
23
+ _LOGGER = logging.getLogger(__name__)
24
+
25
+ CYGRPC_CONNECTIVITY_STATE_TO_CHANNEL_CONNECTIVITY = {
26
+ cygrpc.ConnectivityState.idle:
27
+ grpc.ChannelConnectivity.IDLE,
28
+ cygrpc.ConnectivityState.connecting:
29
+ grpc.ChannelConnectivity.CONNECTING,
30
+ cygrpc.ConnectivityState.ready:
31
+ grpc.ChannelConnectivity.READY,
32
+ cygrpc.ConnectivityState.transient_failure:
33
+ grpc.ChannelConnectivity.TRANSIENT_FAILURE,
34
+ cygrpc.ConnectivityState.shutdown:
35
+ grpc.ChannelConnectivity.SHUTDOWN,
36
+ }
37
+
38
+ CYGRPC_STATUS_CODE_TO_STATUS_CODE = {
39
+ cygrpc.StatusCode.ok: grpc.StatusCode.OK,
40
+ cygrpc.StatusCode.cancelled: grpc.StatusCode.CANCELLED,
41
+ cygrpc.StatusCode.unknown: grpc.StatusCode.UNKNOWN,
42
+ cygrpc.StatusCode.invalid_argument: grpc.StatusCode.INVALID_ARGUMENT,
43
+ cygrpc.StatusCode.deadline_exceeded: grpc.StatusCode.DEADLINE_EXCEEDED,
44
+ cygrpc.StatusCode.not_found: grpc.StatusCode.NOT_FOUND,
45
+ cygrpc.StatusCode.already_exists: grpc.StatusCode.ALREADY_EXISTS,
46
+ cygrpc.StatusCode.permission_denied: grpc.StatusCode.PERMISSION_DENIED,
47
+ cygrpc.StatusCode.unauthenticated: grpc.StatusCode.UNAUTHENTICATED,
48
+ cygrpc.StatusCode.resource_exhausted: grpc.StatusCode.RESOURCE_EXHAUSTED,
49
+ cygrpc.StatusCode.failed_precondition: grpc.StatusCode.FAILED_PRECONDITION,
50
+ cygrpc.StatusCode.aborted: grpc.StatusCode.ABORTED,
51
+ cygrpc.StatusCode.out_of_range: grpc.StatusCode.OUT_OF_RANGE,
52
+ cygrpc.StatusCode.unimplemented: grpc.StatusCode.UNIMPLEMENTED,
53
+ cygrpc.StatusCode.internal: grpc.StatusCode.INTERNAL,
54
+ cygrpc.StatusCode.unavailable: grpc.StatusCode.UNAVAILABLE,
55
+ cygrpc.StatusCode.data_loss: grpc.StatusCode.DATA_LOSS,
56
+ }
57
+ STATUS_CODE_TO_CYGRPC_STATUS_CODE = {
58
+ grpc_code: cygrpc_code for cygrpc_code, grpc_code in six.iteritems(
59
+ CYGRPC_STATUS_CODE_TO_STATUS_CODE)
60
+ }
61
+
62
+ MAXIMUM_WAIT_TIMEOUT = 0.1
63
+
64
+ _ERROR_MESSAGE_PORT_BINDING_FAILED = 'Failed to bind to address %s; set ' \
65
+ 'GRPC_VERBOSITY=debug environment variable to see detailed error message.'
66
+
67
+
68
+ def encode(s):
69
+ if isinstance(s, bytes):
70
+ return s
71
+ else:
72
+ return s.encode('utf8')
73
+
74
+
75
+ def decode(b):
76
+ if isinstance(b, bytes):
77
+ return b.decode('utf-8', 'replace')
78
+ return b
79
+
80
+
81
+ def _transform(message, transformer, exception_message):
82
+ if transformer is None:
83
+ return message
84
+ else:
85
+ try:
86
+ return transformer(message)
87
+ except Exception: # pylint: disable=broad-except
88
+ _LOGGER.exception(exception_message)
89
+ return None
90
+
91
+
92
+ def serialize(message, serializer):
93
+ return _transform(message, serializer, 'Exception serializing message!')
94
+
95
+
96
+ def deserialize(serialized_message, deserializer):
97
+ return _transform(serialized_message, deserializer,
98
+ 'Exception deserializing message!')
99
+
100
+
101
+ def fully_qualified_method(group, method):
102
+ return '/{}/{}'.format(group, method)
103
+
104
+
105
+ def _wait_once(wait_fn, timeout, spin_cb):
106
+ wait_fn(timeout=timeout)
107
+ if spin_cb is not None:
108
+ spin_cb()
109
+
110
+
111
+ def wait(wait_fn, wait_complete_fn, timeout=None, spin_cb=None):
112
+ """Blocks waiting for an event without blocking the thread indefinitely.
113
+
114
+ See https://github.com/grpc/grpc/issues/19464 for full context. CPython's
115
+ `threading.Event.wait` and `threading.Condition.wait` methods, if invoked
116
+ without a timeout kwarg, may block the calling thread indefinitely. If the
117
+ call is made from the main thread, this means that signal handlers may not
118
+ run for an arbitrarily long period of time.
119
+
120
+ This wrapper calls the supplied wait function with an arbitrary short
121
+ timeout to ensure that no signal handler has to wait longer than
122
+ MAXIMUM_WAIT_TIMEOUT before executing.
123
+
124
+ Args:
125
+ wait_fn: A callable acceptable a single float-valued kwarg named
126
+ `timeout`. This function is expected to be one of `threading.Event.wait`
127
+ or `threading.Condition.wait`.
128
+ wait_complete_fn: A callable taking no arguments and returning a bool.
129
+ When this function returns true, it indicates that waiting should cease.
130
+ timeout: An optional float-valued number of seconds after which the wait
131
+ should cease.
132
+ spin_cb: An optional Callable taking no arguments and returning nothing.
133
+ This callback will be called on each iteration of the spin. This may be
134
+ used for, e.g. work related to forking.
135
+
136
+ Returns:
137
+ True if a timeout was supplied and it was reached. False otherwise.
138
+ """
139
+ if timeout is None:
140
+ while not wait_complete_fn():
141
+ _wait_once(wait_fn, MAXIMUM_WAIT_TIMEOUT, spin_cb)
142
+ else:
143
+ end = time.time() + timeout
144
+ while not wait_complete_fn():
145
+ remaining = min(end - time.time(), MAXIMUM_WAIT_TIMEOUT)
146
+ if remaining < 0:
147
+ return True
148
+ _wait_once(wait_fn, remaining, spin_cb)
149
+ return False
150
+
151
+
152
+ def validate_port_binding_result(address, port):
153
+ """Validates if the port binding succeed.
154
+
155
+ If the port returned by Core is 0, the binding is failed. However, in that
156
+ case, the Core API doesn't return a detailed failing reason. The best we
157
+ can do is raising an exception to prevent further confusion.
158
+
159
+ Args:
160
+ address: The address string to be bound.
161
+ port: An int returned by core
162
+ """
163
+ if port == 0:
164
+ # The Core API doesn't return a failure message. The best we can do
165
+ # is raising an exception to prevent further confusion.
166
+ raise RuntimeError(_ERROR_MESSAGE_PORT_BINDING_FAILED % address)
167
+ else:
168
+ return port
my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/grpc/_compression.py ADDED
@@ -0,0 +1,55 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2019 The gRPC authors.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ from grpc._cython import cygrpc
16
+
17
+ NoCompression = cygrpc.CompressionAlgorithm.none
18
+ Deflate = cygrpc.CompressionAlgorithm.deflate
19
+ Gzip = cygrpc.CompressionAlgorithm.gzip
20
+
21
+ _METADATA_STRING_MAPPING = {
22
+ NoCompression: 'identity',
23
+ Deflate: 'deflate',
24
+ Gzip: 'gzip',
25
+ }
26
+
27
+
28
+ def _compression_algorithm_to_metadata_value(compression):
29
+ return _METADATA_STRING_MAPPING[compression]
30
+
31
+
32
+ def compression_algorithm_to_metadata(compression):
33
+ return (cygrpc.GRPC_COMPRESSION_REQUEST_ALGORITHM_MD_KEY,
34
+ _compression_algorithm_to_metadata_value(compression))
35
+
36
+
37
+ def create_channel_option(compression):
38
+ return ((cygrpc.GRPC_COMPRESSION_CHANNEL_DEFAULT_ALGORITHM,
39
+ int(compression)),) if compression else ()
40
+
41
+
42
+ def augment_metadata(metadata, compression):
43
+ if not metadata and not compression:
44
+ return None
45
+ base_metadata = tuple(metadata) if metadata else ()
46
+ compression_metadata = (
47
+ compression_algorithm_to_metadata(compression),) if compression else ()
48
+ return base_metadata + compression_metadata
49
+
50
+
51
+ __all__ = (
52
+ "NoCompression",
53
+ "Deflate",
54
+ "Gzip",
55
+ )
my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/grpc/_grpcio_metadata.py ADDED
@@ -0,0 +1 @@
 
 
1
+ __version__ = """1.47.0"""
my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/grpc/_interceptor.py ADDED
@@ -0,0 +1,562 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2017 gRPC authors.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+ """Implementation of gRPC Python interceptors."""
15
+
16
+ import collections
17
+ import sys
18
+
19
+ import grpc
20
+
21
+
22
+ class _ServicePipeline(object):
23
+
24
+ def __init__(self, interceptors):
25
+ self.interceptors = tuple(interceptors)
26
+
27
+ def _continuation(self, thunk, index):
28
+ return lambda context: self._intercept_at(thunk, index, context)
29
+
30
+ def _intercept_at(self, thunk, index, context):
31
+ if index < len(self.interceptors):
32
+ interceptor = self.interceptors[index]
33
+ thunk = self._continuation(thunk, index + 1)
34
+ return interceptor.intercept_service(thunk, context)
35
+ else:
36
+ return thunk(context)
37
+
38
+ def execute(self, thunk, context):
39
+ return self._intercept_at(thunk, 0, context)
40
+
41
+
42
+ def service_pipeline(interceptors):
43
+ return _ServicePipeline(interceptors) if interceptors else None
44
+
45
+
46
+ class _ClientCallDetails(
47
+ collections.namedtuple('_ClientCallDetails',
48
+ ('method', 'timeout', 'metadata', 'credentials',
49
+ 'wait_for_ready', 'compression')),
50
+ grpc.ClientCallDetails):
51
+ pass
52
+
53
+
54
+ def _unwrap_client_call_details(call_details, default_details):
55
+ try:
56
+ method = call_details.method
57
+ except AttributeError:
58
+ method = default_details.method
59
+
60
+ try:
61
+ timeout = call_details.timeout
62
+ except AttributeError:
63
+ timeout = default_details.timeout
64
+
65
+ try:
66
+ metadata = call_details.metadata
67
+ except AttributeError:
68
+ metadata = default_details.metadata
69
+
70
+ try:
71
+ credentials = call_details.credentials
72
+ except AttributeError:
73
+ credentials = default_details.credentials
74
+
75
+ try:
76
+ wait_for_ready = call_details.wait_for_ready
77
+ except AttributeError:
78
+ wait_for_ready = default_details.wait_for_ready
79
+
80
+ try:
81
+ compression = call_details.compression
82
+ except AttributeError:
83
+ compression = default_details.compression
84
+
85
+ return method, timeout, metadata, credentials, wait_for_ready, compression
86
+
87
+
88
+ class _FailureOutcome(grpc.RpcError, grpc.Future, grpc.Call): # pylint: disable=too-many-ancestors
89
+
90
+ def __init__(self, exception, traceback):
91
+ super(_FailureOutcome, self).__init__()
92
+ self._exception = exception
93
+ self._traceback = traceback
94
+
95
+ def initial_metadata(self):
96
+ return None
97
+
98
+ def trailing_metadata(self):
99
+ return None
100
+
101
+ def code(self):
102
+ return grpc.StatusCode.INTERNAL
103
+
104
+ def details(self):
105
+ return 'Exception raised while intercepting the RPC'
106
+
107
+ def cancel(self):
108
+ return False
109
+
110
+ def cancelled(self):
111
+ return False
112
+
113
+ def is_active(self):
114
+ return False
115
+
116
+ def time_remaining(self):
117
+ return None
118
+
119
+ def running(self):
120
+ return False
121
+
122
+ def done(self):
123
+ return True
124
+
125
+ def result(self, ignored_timeout=None):
126
+ raise self._exception
127
+
128
+ def exception(self, ignored_timeout=None):
129
+ return self._exception
130
+
131
+ def traceback(self, ignored_timeout=None):
132
+ return self._traceback
133
+
134
+ def add_callback(self, unused_callback):
135
+ return False
136
+
137
+ def add_done_callback(self, fn):
138
+ fn(self)
139
+
140
+ def __iter__(self):
141
+ return self
142
+
143
+ def __next__(self):
144
+ raise self._exception
145
+
146
+ def next(self):
147
+ return self.__next__()
148
+
149
+
150
+ class _UnaryOutcome(grpc.Call, grpc.Future):
151
+
152
+ def __init__(self, response, call):
153
+ self._response = response
154
+ self._call = call
155
+
156
+ def initial_metadata(self):
157
+ return self._call.initial_metadata()
158
+
159
+ def trailing_metadata(self):
160
+ return self._call.trailing_metadata()
161
+
162
+ def code(self):
163
+ return self._call.code()
164
+
165
+ def details(self):
166
+ return self._call.details()
167
+
168
+ def is_active(self):
169
+ return self._call.is_active()
170
+
171
+ def time_remaining(self):
172
+ return self._call.time_remaining()
173
+
174
+ def cancel(self):
175
+ return self._call.cancel()
176
+
177
+ def add_callback(self, callback):
178
+ return self._call.add_callback(callback)
179
+
180
+ def cancelled(self):
181
+ return False
182
+
183
+ def running(self):
184
+ return False
185
+
186
+ def done(self):
187
+ return True
188
+
189
+ def result(self, ignored_timeout=None):
190
+ return self._response
191
+
192
+ def exception(self, ignored_timeout=None):
193
+ return None
194
+
195
+ def traceback(self, ignored_timeout=None):
196
+ return None
197
+
198
+ def add_done_callback(self, fn):
199
+ fn(self)
200
+
201
+
202
+ class _UnaryUnaryMultiCallable(grpc.UnaryUnaryMultiCallable):
203
+
204
+ def __init__(self, thunk, method, interceptor):
205
+ self._thunk = thunk
206
+ self._method = method
207
+ self._interceptor = interceptor
208
+
209
+ def __call__(self,
210
+ request,
211
+ timeout=None,
212
+ metadata=None,
213
+ credentials=None,
214
+ wait_for_ready=None,
215
+ compression=None):
216
+ response, ignored_call = self._with_call(request,
217
+ timeout=timeout,
218
+ metadata=metadata,
219
+ credentials=credentials,
220
+ wait_for_ready=wait_for_ready,
221
+ compression=compression)
222
+ return response
223
+
224
+ def _with_call(self,
225
+ request,
226
+ timeout=None,
227
+ metadata=None,
228
+ credentials=None,
229
+ wait_for_ready=None,
230
+ compression=None):
231
+ client_call_details = _ClientCallDetails(self._method, timeout,
232
+ metadata, credentials,
233
+ wait_for_ready, compression)
234
+
235
+ def continuation(new_details, request):
236
+ (new_method, new_timeout, new_metadata, new_credentials,
237
+ new_wait_for_ready,
238
+ new_compression) = (_unwrap_client_call_details(
239
+ new_details, client_call_details))
240
+ try:
241
+ response, call = self._thunk(new_method).with_call(
242
+ request,
243
+ timeout=new_timeout,
244
+ metadata=new_metadata,
245
+ credentials=new_credentials,
246
+ wait_for_ready=new_wait_for_ready,
247
+ compression=new_compression)
248
+ return _UnaryOutcome(response, call)
249
+ except grpc.RpcError as rpc_error:
250
+ return rpc_error
251
+ except Exception as exception: # pylint:disable=broad-except
252
+ return _FailureOutcome(exception, sys.exc_info()[2])
253
+
254
+ call = self._interceptor.intercept_unary_unary(continuation,
255
+ client_call_details,
256
+ request)
257
+ return call.result(), call
258
+
259
+ def with_call(self,
260
+ request,
261
+ timeout=None,
262
+ metadata=None,
263
+ credentials=None,
264
+ wait_for_ready=None,
265
+ compression=None):
266
+ return self._with_call(request,
267
+ timeout=timeout,
268
+ metadata=metadata,
269
+ credentials=credentials,
270
+ wait_for_ready=wait_for_ready,
271
+ compression=compression)
272
+
273
+ def future(self,
274
+ request,
275
+ timeout=None,
276
+ metadata=None,
277
+ credentials=None,
278
+ wait_for_ready=None,
279
+ compression=None):
280
+ client_call_details = _ClientCallDetails(self._method, timeout,
281
+ metadata, credentials,
282
+ wait_for_ready, compression)
283
+
284
+ def continuation(new_details, request):
285
+ (new_method, new_timeout, new_metadata, new_credentials,
286
+ new_wait_for_ready,
287
+ new_compression) = (_unwrap_client_call_details(
288
+ new_details, client_call_details))
289
+ return self._thunk(new_method).future(
290
+ request,
291
+ timeout=new_timeout,
292
+ metadata=new_metadata,
293
+ credentials=new_credentials,
294
+ wait_for_ready=new_wait_for_ready,
295
+ compression=new_compression)
296
+
297
+ try:
298
+ return self._interceptor.intercept_unary_unary(
299
+ continuation, client_call_details, request)
300
+ except Exception as exception: # pylint:disable=broad-except
301
+ return _FailureOutcome(exception, sys.exc_info()[2])
302
+
303
+
304
+ class _UnaryStreamMultiCallable(grpc.UnaryStreamMultiCallable):
305
+
306
+ def __init__(self, thunk, method, interceptor):
307
+ self._thunk = thunk
308
+ self._method = method
309
+ self._interceptor = interceptor
310
+
311
+ def __call__(self,
312
+ request,
313
+ timeout=None,
314
+ metadata=None,
315
+ credentials=None,
316
+ wait_for_ready=None,
317
+ compression=None):
318
+ client_call_details = _ClientCallDetails(self._method, timeout,
319
+ metadata, credentials,
320
+ wait_for_ready, compression)
321
+
322
+ def continuation(new_details, request):
323
+ (new_method, new_timeout, new_metadata, new_credentials,
324
+ new_wait_for_ready,
325
+ new_compression) = (_unwrap_client_call_details(
326
+ new_details, client_call_details))
327
+ return self._thunk(new_method)(request,
328
+ timeout=new_timeout,
329
+ metadata=new_metadata,
330
+ credentials=new_credentials,
331
+ wait_for_ready=new_wait_for_ready,
332
+ compression=new_compression)
333
+
334
+ try:
335
+ return self._interceptor.intercept_unary_stream(
336
+ continuation, client_call_details, request)
337
+ except Exception as exception: # pylint:disable=broad-except
338
+ return _FailureOutcome(exception, sys.exc_info()[2])
339
+
340
+
341
+ class _StreamUnaryMultiCallable(grpc.StreamUnaryMultiCallable):
342
+
343
+ def __init__(self, thunk, method, interceptor):
344
+ self._thunk = thunk
345
+ self._method = method
346
+ self._interceptor = interceptor
347
+
348
+ def __call__(self,
349
+ request_iterator,
350
+ timeout=None,
351
+ metadata=None,
352
+ credentials=None,
353
+ wait_for_ready=None,
354
+ compression=None):
355
+ response, ignored_call = self._with_call(request_iterator,
356
+ timeout=timeout,
357
+ metadata=metadata,
358
+ credentials=credentials,
359
+ wait_for_ready=wait_for_ready,
360
+ compression=compression)
361
+ return response
362
+
363
+ def _with_call(self,
364
+ request_iterator,
365
+ timeout=None,
366
+ metadata=None,
367
+ credentials=None,
368
+ wait_for_ready=None,
369
+ compression=None):
370
+ client_call_details = _ClientCallDetails(self._method, timeout,
371
+ metadata, credentials,
372
+ wait_for_ready, compression)
373
+
374
+ def continuation(new_details, request_iterator):
375
+ (new_method, new_timeout, new_metadata, new_credentials,
376
+ new_wait_for_ready,
377
+ new_compression) = (_unwrap_client_call_details(
378
+ new_details, client_call_details))
379
+ try:
380
+ response, call = self._thunk(new_method).with_call(
381
+ request_iterator,
382
+ timeout=new_timeout,
383
+ metadata=new_metadata,
384
+ credentials=new_credentials,
385
+ wait_for_ready=new_wait_for_ready,
386
+ compression=new_compression)
387
+ return _UnaryOutcome(response, call)
388
+ except grpc.RpcError as rpc_error:
389
+ return rpc_error
390
+ except Exception as exception: # pylint:disable=broad-except
391
+ return _FailureOutcome(exception, sys.exc_info()[2])
392
+
393
+ call = self._interceptor.intercept_stream_unary(continuation,
394
+ client_call_details,
395
+ request_iterator)
396
+ return call.result(), call
397
+
398
+ def with_call(self,
399
+ request_iterator,
400
+ timeout=None,
401
+ metadata=None,
402
+ credentials=None,
403
+ wait_for_ready=None,
404
+ compression=None):
405
+ return self._with_call(request_iterator,
406
+ timeout=timeout,
407
+ metadata=metadata,
408
+ credentials=credentials,
409
+ wait_for_ready=wait_for_ready,
410
+ compression=compression)
411
+
412
+ def future(self,
413
+ request_iterator,
414
+ timeout=None,
415
+ metadata=None,
416
+ credentials=None,
417
+ wait_for_ready=None,
418
+ compression=None):
419
+ client_call_details = _ClientCallDetails(self._method, timeout,
420
+ metadata, credentials,
421
+ wait_for_ready, compression)
422
+
423
+ def continuation(new_details, request_iterator):
424
+ (new_method, new_timeout, new_metadata, new_credentials,
425
+ new_wait_for_ready,
426
+ new_compression) = (_unwrap_client_call_details(
427
+ new_details, client_call_details))
428
+ return self._thunk(new_method).future(
429
+ request_iterator,
430
+ timeout=new_timeout,
431
+ metadata=new_metadata,
432
+ credentials=new_credentials,
433
+ wait_for_ready=new_wait_for_ready,
434
+ compression=new_compression)
435
+
436
+ try:
437
+ return self._interceptor.intercept_stream_unary(
438
+ continuation, client_call_details, request_iterator)
439
+ except Exception as exception: # pylint:disable=broad-except
440
+ return _FailureOutcome(exception, sys.exc_info()[2])
441
+
442
+
443
+ class _StreamStreamMultiCallable(grpc.StreamStreamMultiCallable):
444
+
445
+ def __init__(self, thunk, method, interceptor):
446
+ self._thunk = thunk
447
+ self._method = method
448
+ self._interceptor = interceptor
449
+
450
+ def __call__(self,
451
+ request_iterator,
452
+ timeout=None,
453
+ metadata=None,
454
+ credentials=None,
455
+ wait_for_ready=None,
456
+ compression=None):
457
+ client_call_details = _ClientCallDetails(self._method, timeout,
458
+ metadata, credentials,
459
+ wait_for_ready, compression)
460
+
461
+ def continuation(new_details, request_iterator):
462
+ (new_method, new_timeout, new_metadata, new_credentials,
463
+ new_wait_for_ready,
464
+ new_compression) = (_unwrap_client_call_details(
465
+ new_details, client_call_details))
466
+ return self._thunk(new_method)(request_iterator,
467
+ timeout=new_timeout,
468
+ metadata=new_metadata,
469
+ credentials=new_credentials,
470
+ wait_for_ready=new_wait_for_ready,
471
+ compression=new_compression)
472
+
473
+ try:
474
+ return self._interceptor.intercept_stream_stream(
475
+ continuation, client_call_details, request_iterator)
476
+ except Exception as exception: # pylint:disable=broad-except
477
+ return _FailureOutcome(exception, sys.exc_info()[2])
478
+
479
+
480
+ class _Channel(grpc.Channel):
481
+
482
+ def __init__(self, channel, interceptor):
483
+ self._channel = channel
484
+ self._interceptor = interceptor
485
+
486
+ def subscribe(self, callback, try_to_connect=False):
487
+ self._channel.subscribe(callback, try_to_connect=try_to_connect)
488
+
489
+ def unsubscribe(self, callback):
490
+ self._channel.unsubscribe(callback)
491
+
492
+ def unary_unary(self,
493
+ method,
494
+ request_serializer=None,
495
+ response_deserializer=None):
496
+ thunk = lambda m: self._channel.unary_unary(m, request_serializer,
497
+ response_deserializer)
498
+ if isinstance(self._interceptor, grpc.UnaryUnaryClientInterceptor):
499
+ return _UnaryUnaryMultiCallable(thunk, method, self._interceptor)
500
+ else:
501
+ return thunk(method)
502
+
503
+ def unary_stream(self,
504
+ method,
505
+ request_serializer=None,
506
+ response_deserializer=None):
507
+ thunk = lambda m: self._channel.unary_stream(m, request_serializer,
508
+ response_deserializer)
509
+ if isinstance(self._interceptor, grpc.UnaryStreamClientInterceptor):
510
+ return _UnaryStreamMultiCallable(thunk, method, self._interceptor)
511
+ else:
512
+ return thunk(method)
513
+
514
+ def stream_unary(self,
515
+ method,
516
+ request_serializer=None,
517
+ response_deserializer=None):
518
+ thunk = lambda m: self._channel.stream_unary(m, request_serializer,
519
+ response_deserializer)
520
+ if isinstance(self._interceptor, grpc.StreamUnaryClientInterceptor):
521
+ return _StreamUnaryMultiCallable(thunk, method, self._interceptor)
522
+ else:
523
+ return thunk(method)
524
+
525
+ def stream_stream(self,
526
+ method,
527
+ request_serializer=None,
528
+ response_deserializer=None):
529
+ thunk = lambda m: self._channel.stream_stream(m, request_serializer,
530
+ response_deserializer)
531
+ if isinstance(self._interceptor, grpc.StreamStreamClientInterceptor):
532
+ return _StreamStreamMultiCallable(thunk, method, self._interceptor)
533
+ else:
534
+ return thunk(method)
535
+
536
+ def _close(self):
537
+ self._channel.close()
538
+
539
+ def __enter__(self):
540
+ return self
541
+
542
+ def __exit__(self, exc_type, exc_val, exc_tb):
543
+ self._close()
544
+ return False
545
+
546
+ def close(self):
547
+ self._channel.close()
548
+
549
+
550
+ def intercept_channel(channel, *interceptors):
551
+ for interceptor in reversed(list(interceptors)):
552
+ if not isinstance(interceptor, grpc.UnaryUnaryClientInterceptor) and \
553
+ not isinstance(interceptor, grpc.UnaryStreamClientInterceptor) and \
554
+ not isinstance(interceptor, grpc.StreamUnaryClientInterceptor) and \
555
+ not isinstance(interceptor, grpc.StreamStreamClientInterceptor):
556
+ raise TypeError('interceptor must be '
557
+ 'grpc.UnaryUnaryClientInterceptor or '
558
+ 'grpc.UnaryStreamClientInterceptor or '
559
+ 'grpc.StreamUnaryClientInterceptor or '
560
+ 'grpc.StreamStreamClientInterceptor or ')
561
+ channel = _Channel(channel, interceptor)
562
+ return channel
my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/grpc/_plugin_wrapping.py ADDED
@@ -0,0 +1,113 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2015 gRPC authors.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ import collections
16
+ import logging
17
+ import threading
18
+
19
+ import grpc
20
+ from grpc import _common
21
+ from grpc._cython import cygrpc
22
+
23
+ _LOGGER = logging.getLogger(__name__)
24
+
25
+
26
+ class _AuthMetadataContext(
27
+ collections.namedtuple('AuthMetadataContext', (
28
+ 'service_url',
29
+ 'method_name',
30
+ )), grpc.AuthMetadataContext):
31
+ pass
32
+
33
+
34
+ class _CallbackState(object):
35
+
36
+ def __init__(self):
37
+ self.lock = threading.Lock()
38
+ self.called = False
39
+ self.exception = None
40
+
41
+
42
+ class _AuthMetadataPluginCallback(grpc.AuthMetadataPluginCallback):
43
+
44
+ def __init__(self, state, callback):
45
+ self._state = state
46
+ self._callback = callback
47
+
48
+ def __call__(self, metadata, error):
49
+ with self._state.lock:
50
+ if self._state.exception is None:
51
+ if self._state.called:
52
+ raise RuntimeError(
53
+ 'AuthMetadataPluginCallback invoked more than once!')
54
+ else:
55
+ self._state.called = True
56
+ else:
57
+ raise RuntimeError(
58
+ 'AuthMetadataPluginCallback raised exception "{}"!'.format(
59
+ self._state.exception))
60
+ if error is None:
61
+ self._callback(metadata, cygrpc.StatusCode.ok, None)
62
+ else:
63
+ self._callback(None, cygrpc.StatusCode.internal,
64
+ _common.encode(str(error)))
65
+
66
+
67
+ class _Plugin(object):
68
+
69
+ def __init__(self, metadata_plugin):
70
+ self._metadata_plugin = metadata_plugin
71
+ self._stored_ctx = None
72
+
73
+ try:
74
+ import contextvars # pylint: disable=wrong-import-position
75
+
76
+ # The plugin may be invoked on a thread created by Core, which will not
77
+ # have the context propagated. This context is stored and installed in
78
+ # the thread invoking the plugin.
79
+ self._stored_ctx = contextvars.copy_context()
80
+ except ImportError:
81
+ # Support versions predating contextvars.
82
+ pass
83
+
84
+ def __call__(self, service_url, method_name, callback):
85
+ context = _AuthMetadataContext(_common.decode(service_url),
86
+ _common.decode(method_name))
87
+ callback_state = _CallbackState()
88
+ try:
89
+ self._metadata_plugin(
90
+ context, _AuthMetadataPluginCallback(callback_state, callback))
91
+ except Exception as exception: # pylint: disable=broad-except
92
+ _LOGGER.exception(
93
+ 'AuthMetadataPluginCallback "%s" raised exception!',
94
+ self._metadata_plugin)
95
+ with callback_state.lock:
96
+ callback_state.exception = exception
97
+ if callback_state.called:
98
+ return
99
+ callback(None, cygrpc.StatusCode.internal,
100
+ _common.encode(str(exception)))
101
+
102
+
103
+ def metadata_plugin_call_credentials(metadata_plugin, name):
104
+ if name is None:
105
+ try:
106
+ effective_name = metadata_plugin.__name__
107
+ except AttributeError:
108
+ effective_name = metadata_plugin.__class__.__name__
109
+ else:
110
+ effective_name = name
111
+ return grpc.CallCredentials(
112
+ cygrpc.MetadataPluginCallCredentials(_Plugin(metadata_plugin),
113
+ _common.encode(effective_name)))
my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/grpc/_runtime_protos.py ADDED
@@ -0,0 +1,155 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2020 The gRPC authors.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ import sys
16
+
17
+ _REQUIRED_SYMBOLS = ("_protos", "_services", "_protos_and_services")
18
+ _MINIMUM_VERSION = (3, 5, 0)
19
+
20
+ _UNINSTALLED_TEMPLATE = "Install the grpcio-tools package (1.32.0+) to use the {} function."
21
+ _VERSION_ERROR_TEMPLATE = "The {} function is only on available on Python 3.X interpreters."
22
+
23
+
24
+ def _has_runtime_proto_symbols(mod):
25
+ return all(hasattr(mod, sym) for sym in _REQUIRED_SYMBOLS)
26
+
27
+
28
+ def _is_grpc_tools_importable():
29
+ try:
30
+ import grpc_tools # pylint: disable=unused-import
31
+ return True
32
+ except ImportError as e:
33
+ # NOTE: It's possible that we're encountering a transitive ImportError, so
34
+ # we check for that and re-raise if so.
35
+ if "grpc_tools" not in e.args[0]:
36
+ raise
37
+ return False
38
+
39
+
40
+ def _call_with_lazy_import(fn_name, protobuf_path):
41
+ """Calls one of the three functions, lazily importing grpc_tools.
42
+
43
+ Args:
44
+ fn_name: The name of the function to import from grpc_tools.protoc.
45
+ protobuf_path: The path to import.
46
+
47
+ Returns:
48
+ The appropriate module object.
49
+ """
50
+ if sys.version_info < _MINIMUM_VERSION:
51
+ raise NotImplementedError(_VERSION_ERROR_TEMPLATE.format(fn_name))
52
+ else:
53
+ if not _is_grpc_tools_importable():
54
+ raise NotImplementedError(_UNINSTALLED_TEMPLATE.format(fn_name))
55
+ import grpc_tools.protoc
56
+ if _has_runtime_proto_symbols(grpc_tools.protoc):
57
+ fn = getattr(grpc_tools.protoc, '_' + fn_name)
58
+ return fn(protobuf_path)
59
+ else:
60
+ raise NotImplementedError(_UNINSTALLED_TEMPLATE.format(fn_name))
61
+
62
+
63
+ def protos(protobuf_path): # pylint: disable=unused-argument
64
+ """Returns a module generated by the indicated .proto file.
65
+
66
+ THIS IS AN EXPERIMENTAL API.
67
+
68
+ Use this function to retrieve classes corresponding to message
69
+ definitions in the .proto file.
70
+
71
+ To inspect the contents of the returned module, use the dir function.
72
+ For example:
73
+
74
+ ```
75
+ protos = grpc.protos("foo.proto")
76
+ print(dir(protos))
77
+ ```
78
+
79
+ The returned module object corresponds to the _pb2.py file generated
80
+ by protoc. The path is expected to be relative to an entry on sys.path
81
+ and all transitive dependencies of the file should also be resolveable
82
+ from an entry on sys.path.
83
+
84
+ To completely disable the machinery behind this function, set the
85
+ GRPC_PYTHON_DISABLE_DYNAMIC_STUBS environment variable to "true".
86
+
87
+ Args:
88
+ protobuf_path: The path to the .proto file on the filesystem. This path
89
+ must be resolveable from an entry on sys.path and so must all of its
90
+ transitive dependencies.
91
+
92
+ Returns:
93
+ A module object corresponding to the message code for the indicated
94
+ .proto file. Equivalent to a generated _pb2.py file.
95
+ """
96
+ return _call_with_lazy_import("protos", protobuf_path)
97
+
98
+
99
+ def services(protobuf_path): # pylint: disable=unused-argument
100
+ """Returns a module generated by the indicated .proto file.
101
+
102
+ THIS IS AN EXPERIMENTAL API.
103
+
104
+ Use this function to retrieve classes and functions corresponding to
105
+ service definitions in the .proto file, including both stub and servicer
106
+ definitions.
107
+
108
+ To inspect the contents of the returned module, use the dir function.
109
+ For example:
110
+
111
+ ```
112
+ services = grpc.services("foo.proto")
113
+ print(dir(services))
114
+ ```
115
+
116
+ The returned module object corresponds to the _pb2_grpc.py file generated
117
+ by protoc. The path is expected to be relative to an entry on sys.path
118
+ and all transitive dependencies of the file should also be resolveable
119
+ from an entry on sys.path.
120
+
121
+ To completely disable the machinery behind this function, set the
122
+ GRPC_PYTHON_DISABLE_DYNAMIC_STUBS environment variable to "true".
123
+
124
+ Args:
125
+ protobuf_path: The path to the .proto file on the filesystem. This path
126
+ must be resolveable from an entry on sys.path and so must all of its
127
+ transitive dependencies.
128
+
129
+ Returns:
130
+ A module object corresponding to the stub/service code for the indicated
131
+ .proto file. Equivalent to a generated _pb2_grpc.py file.
132
+ """
133
+ return _call_with_lazy_import("services", protobuf_path)
134
+
135
+
136
+ def protos_and_services(protobuf_path): # pylint: disable=unused-argument
137
+ """Returns a 2-tuple of modules corresponding to protos and services.
138
+
139
+ THIS IS AN EXPERIMENTAL API.
140
+
141
+ The return value of this function is equivalent to a call to protos and a
142
+ call to services.
143
+
144
+ To completely disable the machinery behind this function, set the
145
+ GRPC_PYTHON_DISABLE_DYNAMIC_STUBS environment variable to "true".
146
+
147
+ Args:
148
+ protobuf_path: The path to the .proto file on the filesystem. This path
149
+ must be resolveable from an entry on sys.path and so must all of its
150
+ transitive dependencies.
151
+
152
+ Returns:
153
+ A 2-tuple of module objects corresponding to (protos(path), services(path)).
154
+ """
155
+ return _call_with_lazy_import("protos_and_services", protobuf_path)
my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/grpc/_server.py ADDED
@@ -0,0 +1,1003 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2016 gRPC authors.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+ """Service-side implementation of gRPC Python."""
15
+
16
+ import collections
17
+ from concurrent import futures
18
+ import enum
19
+ import logging
20
+ import threading
21
+ import time
22
+
23
+ import grpc
24
+ from grpc import _common
25
+ from grpc import _compression
26
+ from grpc import _interceptor
27
+ from grpc._cython import cygrpc
28
+ import six
29
+
30
+ _LOGGER = logging.getLogger(__name__)
31
+
32
+ _SHUTDOWN_TAG = 'shutdown'
33
+ _REQUEST_CALL_TAG = 'request_call'
34
+
35
+ _RECEIVE_CLOSE_ON_SERVER_TOKEN = 'receive_close_on_server'
36
+ _SEND_INITIAL_METADATA_TOKEN = 'send_initial_metadata'
37
+ _RECEIVE_MESSAGE_TOKEN = 'receive_message'
38
+ _SEND_MESSAGE_TOKEN = 'send_message'
39
+ _SEND_INITIAL_METADATA_AND_SEND_MESSAGE_TOKEN = (
40
+ 'send_initial_metadata * send_message')
41
+ _SEND_STATUS_FROM_SERVER_TOKEN = 'send_status_from_server'
42
+ _SEND_INITIAL_METADATA_AND_SEND_STATUS_FROM_SERVER_TOKEN = (
43
+ 'send_initial_metadata * send_status_from_server')
44
+
45
+ _OPEN = 'open'
46
+ _CLOSED = 'closed'
47
+ _CANCELLED = 'cancelled'
48
+
49
+ _EMPTY_FLAGS = 0
50
+
51
+ _DEALLOCATED_SERVER_CHECK_PERIOD_S = 1.0
52
+ _INF_TIMEOUT = 1e9
53
+
54
+
55
+ def _serialized_request(request_event):
56
+ return request_event.batch_operations[0].message()
57
+
58
+
59
+ def _application_code(code):
60
+ cygrpc_code = _common.STATUS_CODE_TO_CYGRPC_STATUS_CODE.get(code)
61
+ return cygrpc.StatusCode.unknown if cygrpc_code is None else cygrpc_code
62
+
63
+
64
+ def _completion_code(state):
65
+ if state.code is None:
66
+ return cygrpc.StatusCode.ok
67
+ else:
68
+ return _application_code(state.code)
69
+
70
+
71
+ def _abortion_code(state, code):
72
+ if state.code is None:
73
+ return code
74
+ else:
75
+ return _application_code(state.code)
76
+
77
+
78
+ def _details(state):
79
+ return b'' if state.details is None else state.details
80
+
81
+
82
+ class _HandlerCallDetails(
83
+ collections.namedtuple('_HandlerCallDetails', (
84
+ 'method',
85
+ 'invocation_metadata',
86
+ )), grpc.HandlerCallDetails):
87
+ pass
88
+
89
+
90
+ class _RPCState(object):
91
+
92
+ def __init__(self):
93
+ self.condition = threading.Condition()
94
+ self.due = set()
95
+ self.request = None
96
+ self.client = _OPEN
97
+ self.initial_metadata_allowed = True
98
+ self.compression_algorithm = None
99
+ self.disable_next_compression = False
100
+ self.trailing_metadata = None
101
+ self.code = None
102
+ self.details = None
103
+ self.statused = False
104
+ self.rpc_errors = []
105
+ self.callbacks = []
106
+ self.aborted = False
107
+
108
+
109
+ def _raise_rpc_error(state):
110
+ rpc_error = grpc.RpcError()
111
+ state.rpc_errors.append(rpc_error)
112
+ raise rpc_error
113
+
114
+
115
+ def _possibly_finish_call(state, token):
116
+ state.due.remove(token)
117
+ if not _is_rpc_state_active(state) and not state.due:
118
+ callbacks = state.callbacks
119
+ state.callbacks = None
120
+ return state, callbacks
121
+ else:
122
+ return None, ()
123
+
124
+
125
+ def _send_status_from_server(state, token):
126
+
127
+ def send_status_from_server(unused_send_status_from_server_event):
128
+ with state.condition:
129
+ return _possibly_finish_call(state, token)
130
+
131
+ return send_status_from_server
132
+
133
+
134
+ def _get_initial_metadata(state, metadata):
135
+ with state.condition:
136
+ if state.compression_algorithm:
137
+ compression_metadata = (
138
+ _compression.compression_algorithm_to_metadata(
139
+ state.compression_algorithm),)
140
+ if metadata is None:
141
+ return compression_metadata
142
+ else:
143
+ return compression_metadata + tuple(metadata)
144
+ else:
145
+ return metadata
146
+
147
+
148
+ def _get_initial_metadata_operation(state, metadata):
149
+ operation = cygrpc.SendInitialMetadataOperation(
150
+ _get_initial_metadata(state, metadata), _EMPTY_FLAGS)
151
+ return operation
152
+
153
+
154
+ def _abort(state, call, code, details):
155
+ if state.client is not _CANCELLED:
156
+ effective_code = _abortion_code(state, code)
157
+ effective_details = details if state.details is None else state.details
158
+ if state.initial_metadata_allowed:
159
+ operations = (
160
+ _get_initial_metadata_operation(state, None),
161
+ cygrpc.SendStatusFromServerOperation(state.trailing_metadata,
162
+ effective_code,
163
+ effective_details,
164
+ _EMPTY_FLAGS),
165
+ )
166
+ token = _SEND_INITIAL_METADATA_AND_SEND_STATUS_FROM_SERVER_TOKEN
167
+ else:
168
+ operations = (cygrpc.SendStatusFromServerOperation(
169
+ state.trailing_metadata, effective_code, effective_details,
170
+ _EMPTY_FLAGS),)
171
+ token = _SEND_STATUS_FROM_SERVER_TOKEN
172
+ call.start_server_batch(operations,
173
+ _send_status_from_server(state, token))
174
+ state.statused = True
175
+ state.due.add(token)
176
+
177
+
178
+ def _receive_close_on_server(state):
179
+
180
+ def receive_close_on_server(receive_close_on_server_event):
181
+ with state.condition:
182
+ if receive_close_on_server_event.batch_operations[0].cancelled():
183
+ state.client = _CANCELLED
184
+ elif state.client is _OPEN:
185
+ state.client = _CLOSED
186
+ state.condition.notify_all()
187
+ return _possibly_finish_call(state, _RECEIVE_CLOSE_ON_SERVER_TOKEN)
188
+
189
+ return receive_close_on_server
190
+
191
+
192
+ def _receive_message(state, call, request_deserializer):
193
+
194
+ def receive_message(receive_message_event):
195
+ serialized_request = _serialized_request(receive_message_event)
196
+ if serialized_request is None:
197
+ with state.condition:
198
+ if state.client is _OPEN:
199
+ state.client = _CLOSED
200
+ state.condition.notify_all()
201
+ return _possibly_finish_call(state, _RECEIVE_MESSAGE_TOKEN)
202
+ else:
203
+ request = _common.deserialize(serialized_request,
204
+ request_deserializer)
205
+ with state.condition:
206
+ if request is None:
207
+ _abort(state, call, cygrpc.StatusCode.internal,
208
+ b'Exception deserializing request!')
209
+ else:
210
+ state.request = request
211
+ state.condition.notify_all()
212
+ return _possibly_finish_call(state, _RECEIVE_MESSAGE_TOKEN)
213
+
214
+ return receive_message
215
+
216
+
217
+ def _send_initial_metadata(state):
218
+
219
+ def send_initial_metadata(unused_send_initial_metadata_event):
220
+ with state.condition:
221
+ return _possibly_finish_call(state, _SEND_INITIAL_METADATA_TOKEN)
222
+
223
+ return send_initial_metadata
224
+
225
+
226
+ def _send_message(state, token):
227
+
228
+ def send_message(unused_send_message_event):
229
+ with state.condition:
230
+ state.condition.notify_all()
231
+ return _possibly_finish_call(state, token)
232
+
233
+ return send_message
234
+
235
+
236
+ class _Context(grpc.ServicerContext):
237
+
238
+ def __init__(self, rpc_event, state, request_deserializer):
239
+ self._rpc_event = rpc_event
240
+ self._state = state
241
+ self._request_deserializer = request_deserializer
242
+
243
+ def is_active(self):
244
+ with self._state.condition:
245
+ return _is_rpc_state_active(self._state)
246
+
247
+ def time_remaining(self):
248
+ return max(self._rpc_event.call_details.deadline - time.time(), 0)
249
+
250
+ def cancel(self):
251
+ self._rpc_event.call.cancel()
252
+
253
+ def add_callback(self, callback):
254
+ with self._state.condition:
255
+ if self._state.callbacks is None:
256
+ return False
257
+ else:
258
+ self._state.callbacks.append(callback)
259
+ return True
260
+
261
+ def disable_next_message_compression(self):
262
+ with self._state.condition:
263
+ self._state.disable_next_compression = True
264
+
265
+ def invocation_metadata(self):
266
+ return self._rpc_event.invocation_metadata
267
+
268
+ def peer(self):
269
+ return _common.decode(self._rpc_event.call.peer())
270
+
271
+ def peer_identities(self):
272
+ return cygrpc.peer_identities(self._rpc_event.call)
273
+
274
+ def peer_identity_key(self):
275
+ id_key = cygrpc.peer_identity_key(self._rpc_event.call)
276
+ return id_key if id_key is None else _common.decode(id_key)
277
+
278
+ def auth_context(self):
279
+ return {
280
+ _common.decode(key): value for key, value in six.iteritems(
281
+ cygrpc.auth_context(self._rpc_event.call))
282
+ }
283
+
284
+ def set_compression(self, compression):
285
+ with self._state.condition:
286
+ self._state.compression_algorithm = compression
287
+
288
+ def send_initial_metadata(self, initial_metadata):
289
+ with self._state.condition:
290
+ if self._state.client is _CANCELLED:
291
+ _raise_rpc_error(self._state)
292
+ else:
293
+ if self._state.initial_metadata_allowed:
294
+ operation = _get_initial_metadata_operation(
295
+ self._state, initial_metadata)
296
+ self._rpc_event.call.start_server_batch(
297
+ (operation,), _send_initial_metadata(self._state))
298
+ self._state.initial_metadata_allowed = False
299
+ self._state.due.add(_SEND_INITIAL_METADATA_TOKEN)
300
+ else:
301
+ raise ValueError('Initial metadata no longer allowed!')
302
+
303
+ def set_trailing_metadata(self, trailing_metadata):
304
+ with self._state.condition:
305
+ self._state.trailing_metadata = trailing_metadata
306
+
307
+ def trailing_metadata(self):
308
+ return self._state.trailing_metadata
309
+
310
+ def abort(self, code, details):
311
+ # treat OK like other invalid arguments: fail the RPC
312
+ if code == grpc.StatusCode.OK:
313
+ _LOGGER.error(
314
+ 'abort() called with StatusCode.OK; returning UNKNOWN')
315
+ code = grpc.StatusCode.UNKNOWN
316
+ details = ''
317
+ with self._state.condition:
318
+ self._state.code = code
319
+ self._state.details = _common.encode(details)
320
+ self._state.aborted = True
321
+ raise Exception()
322
+
323
+ def abort_with_status(self, status):
324
+ self._state.trailing_metadata = status.trailing_metadata
325
+ self.abort(status.code, status.details)
326
+
327
+ def set_code(self, code):
328
+ with self._state.condition:
329
+ self._state.code = code
330
+
331
+ def code(self):
332
+ return self._state.code
333
+
334
+ def set_details(self, details):
335
+ with self._state.condition:
336
+ self._state.details = _common.encode(details)
337
+
338
+ def details(self):
339
+ return self._state.details
340
+
341
+ def _finalize_state(self):
342
+ pass
343
+
344
+
345
+ class _RequestIterator(object):
346
+
347
+ def __init__(self, state, call, request_deserializer):
348
+ self._state = state
349
+ self._call = call
350
+ self._request_deserializer = request_deserializer
351
+
352
+ def _raise_or_start_receive_message(self):
353
+ if self._state.client is _CANCELLED:
354
+ _raise_rpc_error(self._state)
355
+ elif not _is_rpc_state_active(self._state):
356
+ raise StopIteration()
357
+ else:
358
+ self._call.start_server_batch(
359
+ (cygrpc.ReceiveMessageOperation(_EMPTY_FLAGS),),
360
+ _receive_message(self._state, self._call,
361
+ self._request_deserializer))
362
+ self._state.due.add(_RECEIVE_MESSAGE_TOKEN)
363
+
364
+ def _look_for_request(self):
365
+ if self._state.client is _CANCELLED:
366
+ _raise_rpc_error(self._state)
367
+ elif (self._state.request is None and
368
+ _RECEIVE_MESSAGE_TOKEN not in self._state.due):
369
+ raise StopIteration()
370
+ else:
371
+ request = self._state.request
372
+ self._state.request = None
373
+ return request
374
+
375
+ raise AssertionError() # should never run
376
+
377
+ def _next(self):
378
+ with self._state.condition:
379
+ self._raise_or_start_receive_message()
380
+ while True:
381
+ self._state.condition.wait()
382
+ request = self._look_for_request()
383
+ if request is not None:
384
+ return request
385
+
386
+ def __iter__(self):
387
+ return self
388
+
389
+ def __next__(self):
390
+ return self._next()
391
+
392
+ def next(self):
393
+ return self._next()
394
+
395
+
396
+ def _unary_request(rpc_event, state, request_deserializer):
397
+
398
+ def unary_request():
399
+ with state.condition:
400
+ if not _is_rpc_state_active(state):
401
+ return None
402
+ else:
403
+ rpc_event.call.start_server_batch(
404
+ (cygrpc.ReceiveMessageOperation(_EMPTY_FLAGS),),
405
+ _receive_message(state, rpc_event.call,
406
+ request_deserializer))
407
+ state.due.add(_RECEIVE_MESSAGE_TOKEN)
408
+ while True:
409
+ state.condition.wait()
410
+ if state.request is None:
411
+ if state.client is _CLOSED:
412
+ details = '"{}" requires exactly one request message.'.format(
413
+ rpc_event.call_details.method)
414
+ _abort(state, rpc_event.call,
415
+ cygrpc.StatusCode.unimplemented,
416
+ _common.encode(details))
417
+ return None
418
+ elif state.client is _CANCELLED:
419
+ return None
420
+ else:
421
+ request = state.request
422
+ state.request = None
423
+ return request
424
+
425
+ return unary_request
426
+
427
+
428
+ def _call_behavior(rpc_event,
429
+ state,
430
+ behavior,
431
+ argument,
432
+ request_deserializer,
433
+ send_response_callback=None):
434
+ from grpc import _create_servicer_context
435
+ with _create_servicer_context(rpc_event, state,
436
+ request_deserializer) as context:
437
+ try:
438
+ response_or_iterator = None
439
+ if send_response_callback is not None:
440
+ response_or_iterator = behavior(argument, context,
441
+ send_response_callback)
442
+ else:
443
+ response_or_iterator = behavior(argument, context)
444
+ return response_or_iterator, True
445
+ except Exception as exception: # pylint: disable=broad-except
446
+ with state.condition:
447
+ if state.aborted:
448
+ _abort(state, rpc_event.call, cygrpc.StatusCode.unknown,
449
+ b'RPC Aborted')
450
+ elif exception not in state.rpc_errors:
451
+ details = 'Exception calling application: {}'.format(
452
+ exception)
453
+ _LOGGER.exception(details)
454
+ _abort(state, rpc_event.call, cygrpc.StatusCode.unknown,
455
+ _common.encode(details))
456
+ return None, False
457
+
458
+
459
+ def _take_response_from_response_iterator(rpc_event, state, response_iterator):
460
+ try:
461
+ return next(response_iterator), True
462
+ except StopIteration:
463
+ return None, True
464
+ except Exception as exception: # pylint: disable=broad-except
465
+ with state.condition:
466
+ if state.aborted:
467
+ _abort(state, rpc_event.call, cygrpc.StatusCode.unknown,
468
+ b'RPC Aborted')
469
+ elif exception not in state.rpc_errors:
470
+ details = 'Exception iterating responses: {}'.format(exception)
471
+ _LOGGER.exception(details)
472
+ _abort(state, rpc_event.call, cygrpc.StatusCode.unknown,
473
+ _common.encode(details))
474
+ return None, False
475
+
476
+
477
+ def _serialize_response(rpc_event, state, response, response_serializer):
478
+ serialized_response = _common.serialize(response, response_serializer)
479
+ if serialized_response is None:
480
+ with state.condition:
481
+ _abort(state, rpc_event.call, cygrpc.StatusCode.internal,
482
+ b'Failed to serialize response!')
483
+ return None
484
+ else:
485
+ return serialized_response
486
+
487
+
488
+ def _get_send_message_op_flags_from_state(state):
489
+ if state.disable_next_compression:
490
+ return cygrpc.WriteFlag.no_compress
491
+ else:
492
+ return _EMPTY_FLAGS
493
+
494
+
495
+ def _reset_per_message_state(state):
496
+ with state.condition:
497
+ state.disable_next_compression = False
498
+
499
+
500
+ def _send_response(rpc_event, state, serialized_response):
501
+ with state.condition:
502
+ if not _is_rpc_state_active(state):
503
+ return False
504
+ else:
505
+ if state.initial_metadata_allowed:
506
+ operations = (
507
+ _get_initial_metadata_operation(state, None),
508
+ cygrpc.SendMessageOperation(
509
+ serialized_response,
510
+ _get_send_message_op_flags_from_state(state)),
511
+ )
512
+ state.initial_metadata_allowed = False
513
+ token = _SEND_INITIAL_METADATA_AND_SEND_MESSAGE_TOKEN
514
+ else:
515
+ operations = (cygrpc.SendMessageOperation(
516
+ serialized_response,
517
+ _get_send_message_op_flags_from_state(state)),)
518
+ token = _SEND_MESSAGE_TOKEN
519
+ rpc_event.call.start_server_batch(operations,
520
+ _send_message(state, token))
521
+ state.due.add(token)
522
+ _reset_per_message_state(state)
523
+ while True:
524
+ state.condition.wait()
525
+ if token not in state.due:
526
+ return _is_rpc_state_active(state)
527
+
528
+
529
+ def _status(rpc_event, state, serialized_response):
530
+ with state.condition:
531
+ if state.client is not _CANCELLED:
532
+ code = _completion_code(state)
533
+ details = _details(state)
534
+ operations = [
535
+ cygrpc.SendStatusFromServerOperation(state.trailing_metadata,
536
+ code, details,
537
+ _EMPTY_FLAGS),
538
+ ]
539
+ if state.initial_metadata_allowed:
540
+ operations.append(_get_initial_metadata_operation(state, None))
541
+ if serialized_response is not None:
542
+ operations.append(
543
+ cygrpc.SendMessageOperation(
544
+ serialized_response,
545
+ _get_send_message_op_flags_from_state(state)))
546
+ rpc_event.call.start_server_batch(
547
+ operations,
548
+ _send_status_from_server(state, _SEND_STATUS_FROM_SERVER_TOKEN))
549
+ state.statused = True
550
+ _reset_per_message_state(state)
551
+ state.due.add(_SEND_STATUS_FROM_SERVER_TOKEN)
552
+
553
+
554
+ def _unary_response_in_pool(rpc_event, state, behavior, argument_thunk,
555
+ request_deserializer, response_serializer):
556
+ cygrpc.install_context_from_request_call_event(rpc_event)
557
+ try:
558
+ argument = argument_thunk()
559
+ if argument is not None:
560
+ response, proceed = _call_behavior(rpc_event, state, behavior,
561
+ argument, request_deserializer)
562
+ if proceed:
563
+ serialized_response = _serialize_response(
564
+ rpc_event, state, response, response_serializer)
565
+ if serialized_response is not None:
566
+ _status(rpc_event, state, serialized_response)
567
+ finally:
568
+ cygrpc.uninstall_context()
569
+
570
+
571
+ def _stream_response_in_pool(rpc_event, state, behavior, argument_thunk,
572
+ request_deserializer, response_serializer):
573
+ cygrpc.install_context_from_request_call_event(rpc_event)
574
+
575
+ def send_response(response):
576
+ if response is None:
577
+ _status(rpc_event, state, None)
578
+ else:
579
+ serialized_response = _serialize_response(rpc_event, state,
580
+ response,
581
+ response_serializer)
582
+ if serialized_response is not None:
583
+ _send_response(rpc_event, state, serialized_response)
584
+
585
+ try:
586
+ argument = argument_thunk()
587
+ if argument is not None:
588
+ if hasattr(behavior, 'experimental_non_blocking'
589
+ ) and behavior.experimental_non_blocking:
590
+ _call_behavior(rpc_event,
591
+ state,
592
+ behavior,
593
+ argument,
594
+ request_deserializer,
595
+ send_response_callback=send_response)
596
+ else:
597
+ response_iterator, proceed = _call_behavior(
598
+ rpc_event, state, behavior, argument, request_deserializer)
599
+ if proceed:
600
+ _send_message_callback_to_blocking_iterator_adapter(
601
+ rpc_event, state, send_response, response_iterator)
602
+ finally:
603
+ cygrpc.uninstall_context()
604
+
605
+
606
+ def _is_rpc_state_active(state):
607
+ return state.client is not _CANCELLED and not state.statused
608
+
609
+
610
+ def _send_message_callback_to_blocking_iterator_adapter(rpc_event, state,
611
+ send_response_callback,
612
+ response_iterator):
613
+ while True:
614
+ response, proceed = _take_response_from_response_iterator(
615
+ rpc_event, state, response_iterator)
616
+ if proceed:
617
+ send_response_callback(response)
618
+ if not _is_rpc_state_active(state):
619
+ break
620
+ else:
621
+ break
622
+
623
+
624
+ def _select_thread_pool_for_behavior(behavior, default_thread_pool):
625
+ if hasattr(behavior, 'experimental_thread_pool') and isinstance(
626
+ behavior.experimental_thread_pool, futures.ThreadPoolExecutor):
627
+ return behavior.experimental_thread_pool
628
+ else:
629
+ return default_thread_pool
630
+
631
+
632
+ def _handle_unary_unary(rpc_event, state, method_handler, default_thread_pool):
633
+ unary_request = _unary_request(rpc_event, state,
634
+ method_handler.request_deserializer)
635
+ thread_pool = _select_thread_pool_for_behavior(method_handler.unary_unary,
636
+ default_thread_pool)
637
+ return thread_pool.submit(_unary_response_in_pool, rpc_event, state,
638
+ method_handler.unary_unary, unary_request,
639
+ method_handler.request_deserializer,
640
+ method_handler.response_serializer)
641
+
642
+
643
+ def _handle_unary_stream(rpc_event, state, method_handler, default_thread_pool):
644
+ unary_request = _unary_request(rpc_event, state,
645
+ method_handler.request_deserializer)
646
+ thread_pool = _select_thread_pool_for_behavior(method_handler.unary_stream,
647
+ default_thread_pool)
648
+ return thread_pool.submit(_stream_response_in_pool, rpc_event, state,
649
+ method_handler.unary_stream, unary_request,
650
+ method_handler.request_deserializer,
651
+ method_handler.response_serializer)
652
+
653
+
654
+ def _handle_stream_unary(rpc_event, state, method_handler, default_thread_pool):
655
+ request_iterator = _RequestIterator(state, rpc_event.call,
656
+ method_handler.request_deserializer)
657
+ thread_pool = _select_thread_pool_for_behavior(method_handler.stream_unary,
658
+ default_thread_pool)
659
+ return thread_pool.submit(_unary_response_in_pool, rpc_event, state,
660
+ method_handler.stream_unary,
661
+ lambda: request_iterator,
662
+ method_handler.request_deserializer,
663
+ method_handler.response_serializer)
664
+
665
+
666
+ def _handle_stream_stream(rpc_event, state, method_handler,
667
+ default_thread_pool):
668
+ request_iterator = _RequestIterator(state, rpc_event.call,
669
+ method_handler.request_deserializer)
670
+ thread_pool = _select_thread_pool_for_behavior(method_handler.stream_stream,
671
+ default_thread_pool)
672
+ return thread_pool.submit(_stream_response_in_pool, rpc_event, state,
673
+ method_handler.stream_stream,
674
+ lambda: request_iterator,
675
+ method_handler.request_deserializer,
676
+ method_handler.response_serializer)
677
+
678
+
679
+ def _find_method_handler(rpc_event, generic_handlers, interceptor_pipeline):
680
+
681
+ def query_handlers(handler_call_details):
682
+ for generic_handler in generic_handlers:
683
+ method_handler = generic_handler.service(handler_call_details)
684
+ if method_handler is not None:
685
+ return method_handler
686
+ return None
687
+
688
+ handler_call_details = _HandlerCallDetails(
689
+ _common.decode(rpc_event.call_details.method),
690
+ rpc_event.invocation_metadata)
691
+
692
+ if interceptor_pipeline is not None:
693
+ return interceptor_pipeline.execute(query_handlers,
694
+ handler_call_details)
695
+ else:
696
+ return query_handlers(handler_call_details)
697
+
698
+
699
+ def _reject_rpc(rpc_event, status, details):
700
+ rpc_state = _RPCState()
701
+ operations = (
702
+ _get_initial_metadata_operation(rpc_state, None),
703
+ cygrpc.ReceiveCloseOnServerOperation(_EMPTY_FLAGS),
704
+ cygrpc.SendStatusFromServerOperation(None, status, details,
705
+ _EMPTY_FLAGS),
706
+ )
707
+ rpc_event.call.start_server_batch(operations, lambda ignored_event: (
708
+ rpc_state,
709
+ (),
710
+ ))
711
+ return rpc_state
712
+
713
+
714
+ def _handle_with_method_handler(rpc_event, method_handler, thread_pool):
715
+ state = _RPCState()
716
+ with state.condition:
717
+ rpc_event.call.start_server_batch(
718
+ (cygrpc.ReceiveCloseOnServerOperation(_EMPTY_FLAGS),),
719
+ _receive_close_on_server(state))
720
+ state.due.add(_RECEIVE_CLOSE_ON_SERVER_TOKEN)
721
+ if method_handler.request_streaming:
722
+ if method_handler.response_streaming:
723
+ return state, _handle_stream_stream(rpc_event, state,
724
+ method_handler, thread_pool)
725
+ else:
726
+ return state, _handle_stream_unary(rpc_event, state,
727
+ method_handler, thread_pool)
728
+ else:
729
+ if method_handler.response_streaming:
730
+ return state, _handle_unary_stream(rpc_event, state,
731
+ method_handler, thread_pool)
732
+ else:
733
+ return state, _handle_unary_unary(rpc_event, state,
734
+ method_handler, thread_pool)
735
+
736
+
737
+ def _handle_call(rpc_event, generic_handlers, interceptor_pipeline, thread_pool,
738
+ concurrency_exceeded):
739
+ if not rpc_event.success:
740
+ return None, None
741
+ if rpc_event.call_details.method is not None:
742
+ try:
743
+ method_handler = _find_method_handler(rpc_event, generic_handlers,
744
+ interceptor_pipeline)
745
+ except Exception as exception: # pylint: disable=broad-except
746
+ details = 'Exception servicing handler: {}'.format(exception)
747
+ _LOGGER.exception(details)
748
+ return _reject_rpc(rpc_event, cygrpc.StatusCode.unknown,
749
+ b'Error in service handler!'), None
750
+ if method_handler is None:
751
+ return _reject_rpc(rpc_event, cygrpc.StatusCode.unimplemented,
752
+ b'Method not found!'), None
753
+ elif concurrency_exceeded:
754
+ return _reject_rpc(rpc_event, cygrpc.StatusCode.resource_exhausted,
755
+ b'Concurrent RPC limit exceeded!'), None
756
+ else:
757
+ return _handle_with_method_handler(rpc_event, method_handler,
758
+ thread_pool)
759
+ else:
760
+ return None, None
761
+
762
+
763
+ @enum.unique
764
+ class _ServerStage(enum.Enum):
765
+ STOPPED = 'stopped'
766
+ STARTED = 'started'
767
+ GRACE = 'grace'
768
+
769
+
770
+ class _ServerState(object):
771
+
772
+ # pylint: disable=too-many-arguments
773
+ def __init__(self, completion_queue, server, generic_handlers,
774
+ interceptor_pipeline, thread_pool, maximum_concurrent_rpcs):
775
+ self.lock = threading.RLock()
776
+ self.completion_queue = completion_queue
777
+ self.server = server
778
+ self.generic_handlers = list(generic_handlers)
779
+ self.interceptor_pipeline = interceptor_pipeline
780
+ self.thread_pool = thread_pool
781
+ self.stage = _ServerStage.STOPPED
782
+ self.termination_event = threading.Event()
783
+ self.shutdown_events = [self.termination_event]
784
+ self.maximum_concurrent_rpcs = maximum_concurrent_rpcs
785
+ self.active_rpc_count = 0
786
+
787
+ # TODO(https://github.com/grpc/grpc/issues/6597): eliminate these fields.
788
+ self.rpc_states = set()
789
+ self.due = set()
790
+
791
+ # A "volatile" flag to interrupt the daemon serving thread
792
+ self.server_deallocated = False
793
+
794
+
795
+ def _add_generic_handlers(state, generic_handlers):
796
+ with state.lock:
797
+ state.generic_handlers.extend(generic_handlers)
798
+
799
+
800
+ def _add_insecure_port(state, address):
801
+ with state.lock:
802
+ return state.server.add_http2_port(address)
803
+
804
+
805
+ def _add_secure_port(state, address, server_credentials):
806
+ with state.lock:
807
+ return state.server.add_http2_port(address,
808
+ server_credentials._credentials)
809
+
810
+
811
+ def _request_call(state):
812
+ state.server.request_call(state.completion_queue, state.completion_queue,
813
+ _REQUEST_CALL_TAG)
814
+ state.due.add(_REQUEST_CALL_TAG)
815
+
816
+
817
+ # TODO(https://github.com/grpc/grpc/issues/6597): delete this function.
818
+ def _stop_serving(state):
819
+ if not state.rpc_states and not state.due:
820
+ state.server.destroy()
821
+ for shutdown_event in state.shutdown_events:
822
+ shutdown_event.set()
823
+ state.stage = _ServerStage.STOPPED
824
+ return True
825
+ else:
826
+ return False
827
+
828
+
829
+ def _on_call_completed(state):
830
+ with state.lock:
831
+ state.active_rpc_count -= 1
832
+
833
+
834
+ def _process_event_and_continue(state, event):
835
+ should_continue = True
836
+ if event.tag is _SHUTDOWN_TAG:
837
+ with state.lock:
838
+ state.due.remove(_SHUTDOWN_TAG)
839
+ if _stop_serving(state):
840
+ should_continue = False
841
+ elif event.tag is _REQUEST_CALL_TAG:
842
+ with state.lock:
843
+ state.due.remove(_REQUEST_CALL_TAG)
844
+ concurrency_exceeded = (
845
+ state.maximum_concurrent_rpcs is not None and
846
+ state.active_rpc_count >= state.maximum_concurrent_rpcs)
847
+ rpc_state, rpc_future = _handle_call(event, state.generic_handlers,
848
+ state.interceptor_pipeline,
849
+ state.thread_pool,
850
+ concurrency_exceeded)
851
+ if rpc_state is not None:
852
+ state.rpc_states.add(rpc_state)
853
+ if rpc_future is not None:
854
+ state.active_rpc_count += 1
855
+ rpc_future.add_done_callback(
856
+ lambda unused_future: _on_call_completed(state))
857
+ if state.stage is _ServerStage.STARTED:
858
+ _request_call(state)
859
+ elif _stop_serving(state):
860
+ should_continue = False
861
+ else:
862
+ rpc_state, callbacks = event.tag(event)
863
+ for callback in callbacks:
864
+ try:
865
+ callback()
866
+ except Exception: # pylint: disable=broad-except
867
+ _LOGGER.exception('Exception calling callback!')
868
+ if rpc_state is not None:
869
+ with state.lock:
870
+ state.rpc_states.remove(rpc_state)
871
+ if _stop_serving(state):
872
+ should_continue = False
873
+ return should_continue
874
+
875
+
876
+ def _serve(state):
877
+ while True:
878
+ timeout = time.time() + _DEALLOCATED_SERVER_CHECK_PERIOD_S
879
+ event = state.completion_queue.poll(timeout)
880
+ if state.server_deallocated:
881
+ _begin_shutdown_once(state)
882
+ if event.completion_type != cygrpc.CompletionType.queue_timeout:
883
+ if not _process_event_and_continue(state, event):
884
+ return
885
+ # We want to force the deletion of the previous event
886
+ # ~before~ we poll again; if the event has a reference
887
+ # to a shutdown Call object, this can induce spinlock.
888
+ event = None
889
+
890
+
891
+ def _begin_shutdown_once(state):
892
+ with state.lock:
893
+ if state.stage is _ServerStage.STARTED:
894
+ state.server.shutdown(state.completion_queue, _SHUTDOWN_TAG)
895
+ state.stage = _ServerStage.GRACE
896
+ state.due.add(_SHUTDOWN_TAG)
897
+
898
+
899
+ def _stop(state, grace):
900
+ with state.lock:
901
+ if state.stage is _ServerStage.STOPPED:
902
+ shutdown_event = threading.Event()
903
+ shutdown_event.set()
904
+ return shutdown_event
905
+ else:
906
+ _begin_shutdown_once(state)
907
+ shutdown_event = threading.Event()
908
+ state.shutdown_events.append(shutdown_event)
909
+ if grace is None:
910
+ state.server.cancel_all_calls()
911
+ else:
912
+
913
+ def cancel_all_calls_after_grace():
914
+ shutdown_event.wait(timeout=grace)
915
+ with state.lock:
916
+ state.server.cancel_all_calls()
917
+
918
+ thread = threading.Thread(target=cancel_all_calls_after_grace)
919
+ thread.start()
920
+ return shutdown_event
921
+ shutdown_event.wait()
922
+ return shutdown_event
923
+
924
+
925
+ def _start(state):
926
+ with state.lock:
927
+ if state.stage is not _ServerStage.STOPPED:
928
+ raise ValueError('Cannot start already-started server!')
929
+ state.server.start()
930
+ state.stage = _ServerStage.STARTED
931
+ _request_call(state)
932
+
933
+ thread = threading.Thread(target=_serve, args=(state,))
934
+ thread.daemon = True
935
+ thread.start()
936
+
937
+
938
+ def _validate_generic_rpc_handlers(generic_rpc_handlers):
939
+ for generic_rpc_handler in generic_rpc_handlers:
940
+ service_attribute = getattr(generic_rpc_handler, 'service', None)
941
+ if service_attribute is None:
942
+ raise AttributeError(
943
+ '"{}" must conform to grpc.GenericRpcHandler type but does '
944
+ 'not have "service" method!'.format(generic_rpc_handler))
945
+
946
+
947
+ def _augment_options(base_options, compression):
948
+ compression_option = _compression.create_channel_option(compression)
949
+ return tuple(base_options) + compression_option
950
+
951
+
952
+ class _Server(grpc.Server):
953
+
954
+ # pylint: disable=too-many-arguments
955
+ def __init__(self, thread_pool, generic_handlers, interceptors, options,
956
+ maximum_concurrent_rpcs, compression, xds):
957
+ completion_queue = cygrpc.CompletionQueue()
958
+ server = cygrpc.Server(_augment_options(options, compression), xds)
959
+ server.register_completion_queue(completion_queue)
960
+ self._state = _ServerState(completion_queue, server, generic_handlers,
961
+ _interceptor.service_pipeline(interceptors),
962
+ thread_pool, maximum_concurrent_rpcs)
963
+
964
+ def add_generic_rpc_handlers(self, generic_rpc_handlers):
965
+ _validate_generic_rpc_handlers(generic_rpc_handlers)
966
+ _add_generic_handlers(self._state, generic_rpc_handlers)
967
+
968
+ def add_insecure_port(self, address):
969
+ return _common.validate_port_binding_result(
970
+ address, _add_insecure_port(self._state, _common.encode(address)))
971
+
972
+ def add_secure_port(self, address, server_credentials):
973
+ return _common.validate_port_binding_result(
974
+ address,
975
+ _add_secure_port(self._state, _common.encode(address),
976
+ server_credentials))
977
+
978
+ def start(self):
979
+ _start(self._state)
980
+
981
+ def wait_for_termination(self, timeout=None):
982
+ # NOTE(https://bugs.python.org/issue35935)
983
+ # Remove this workaround once threading.Event.wait() is working with
984
+ # CTRL+C across platforms.
985
+ return _common.wait(self._state.termination_event.wait,
986
+ self._state.termination_event.is_set,
987
+ timeout=timeout)
988
+
989
+ def stop(self, grace):
990
+ return _stop(self._state, grace)
991
+
992
+ def __del__(self):
993
+ if hasattr(self, '_state'):
994
+ # We can not grab a lock in __del__(), so set a flag to signal the
995
+ # serving daemon thread (if it exists) to initiate shutdown.
996
+ self._state.server_deallocated = True
997
+
998
+
999
+ def create_server(thread_pool, generic_rpc_handlers, interceptors, options,
1000
+ maximum_concurrent_rpcs, compression, xds):
1001
+ _validate_generic_rpc_handlers(generic_rpc_handlers)
1002
+ return _Server(thread_pool, generic_rpc_handlers, interceptors, options,
1003
+ maximum_concurrent_rpcs, compression, xds)
my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/grpc/_simple_stubs.py ADDED
@@ -0,0 +1,486 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2020 The gRPC authors.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+ """Functions that obviate explicit stubs and explicit channels."""
15
+
16
+ import collections
17
+ import datetime
18
+ import logging
19
+ import os
20
+ import threading
21
+ from typing import (Any, AnyStr, Callable, Dict, Iterator, Optional, Sequence,
22
+ Tuple, TypeVar, Union)
23
+
24
+ import grpc
25
+ from grpc.experimental import experimental_api
26
+
27
+ RequestType = TypeVar('RequestType')
28
+ ResponseType = TypeVar('ResponseType')
29
+
30
+ OptionsType = Sequence[Tuple[str, str]]
31
+ CacheKey = Tuple[str, OptionsType, Optional[grpc.ChannelCredentials],
32
+ Optional[grpc.Compression]]
33
+
34
+ _LOGGER = logging.getLogger(__name__)
35
+
36
+ _EVICTION_PERIOD_KEY = "GRPC_PYTHON_MANAGED_CHANNEL_EVICTION_SECONDS"
37
+ if _EVICTION_PERIOD_KEY in os.environ:
38
+ _EVICTION_PERIOD = datetime.timedelta(
39
+ seconds=float(os.environ[_EVICTION_PERIOD_KEY]))
40
+ _LOGGER.debug("Setting managed channel eviction period to %s",
41
+ _EVICTION_PERIOD)
42
+ else:
43
+ _EVICTION_PERIOD = datetime.timedelta(minutes=10)
44
+
45
+ _MAXIMUM_CHANNELS_KEY = "GRPC_PYTHON_MANAGED_CHANNEL_MAXIMUM"
46
+ if _MAXIMUM_CHANNELS_KEY in os.environ:
47
+ _MAXIMUM_CHANNELS = int(os.environ[_MAXIMUM_CHANNELS_KEY])
48
+ _LOGGER.debug("Setting maximum managed channels to %d", _MAXIMUM_CHANNELS)
49
+ else:
50
+ _MAXIMUM_CHANNELS = 2**8
51
+
52
+ _DEFAULT_TIMEOUT_KEY = "GRPC_PYTHON_DEFAULT_TIMEOUT_SECONDS"
53
+ if _DEFAULT_TIMEOUT_KEY in os.environ:
54
+ _DEFAULT_TIMEOUT = float(os.environ[_DEFAULT_TIMEOUT_KEY])
55
+ _LOGGER.debug("Setting default timeout seconds to %f", _DEFAULT_TIMEOUT)
56
+ else:
57
+ _DEFAULT_TIMEOUT = 60.0
58
+
59
+
60
+ def _create_channel(target: str, options: Sequence[Tuple[str, str]],
61
+ channel_credentials: Optional[grpc.ChannelCredentials],
62
+ compression: Optional[grpc.Compression]) -> grpc.Channel:
63
+ _LOGGER.debug(
64
+ f"Creating secure channel with credentials '{channel_credentials}', " +
65
+ f"options '{options}' and compression '{compression}'")
66
+ return grpc.secure_channel(target,
67
+ credentials=channel_credentials,
68
+ options=options,
69
+ compression=compression)
70
+
71
+
72
+ class ChannelCache:
73
+ # NOTE(rbellevi): Untyped due to reference cycle.
74
+ _singleton = None
75
+ _lock: threading.RLock = threading.RLock()
76
+ _condition: threading.Condition = threading.Condition(lock=_lock)
77
+ _eviction_ready: threading.Event = threading.Event()
78
+
79
+ _mapping: Dict[CacheKey, Tuple[grpc.Channel, datetime.datetime]]
80
+ _eviction_thread: threading.Thread
81
+
82
+ def __init__(self):
83
+ self._mapping = collections.OrderedDict()
84
+ self._eviction_thread = threading.Thread(
85
+ target=ChannelCache._perform_evictions, daemon=True)
86
+ self._eviction_thread.start()
87
+
88
+ @staticmethod
89
+ def get():
90
+ with ChannelCache._lock:
91
+ if ChannelCache._singleton is None:
92
+ ChannelCache._singleton = ChannelCache()
93
+ ChannelCache._eviction_ready.wait()
94
+ return ChannelCache._singleton
95
+
96
+ def _evict_locked(self, key: CacheKey):
97
+ channel, _ = self._mapping.pop(key)
98
+ _LOGGER.debug("Evicting channel %s with configuration %s.", channel,
99
+ key)
100
+ channel.close()
101
+ del channel
102
+
103
+ @staticmethod
104
+ def _perform_evictions():
105
+ while True:
106
+ with ChannelCache._lock:
107
+ ChannelCache._eviction_ready.set()
108
+ if not ChannelCache._singleton._mapping:
109
+ ChannelCache._condition.wait()
110
+ elif len(ChannelCache._singleton._mapping) > _MAXIMUM_CHANNELS:
111
+ key = next(iter(ChannelCache._singleton._mapping.keys()))
112
+ ChannelCache._singleton._evict_locked(key)
113
+ # And immediately reevaluate.
114
+ else:
115
+ key, (_, eviction_time) = next(
116
+ iter(ChannelCache._singleton._mapping.items()))
117
+ now = datetime.datetime.now()
118
+ if eviction_time <= now:
119
+ ChannelCache._singleton._evict_locked(key)
120
+ continue
121
+ else:
122
+ time_to_eviction = (eviction_time - now).total_seconds()
123
+ # NOTE: We aim to *eventually* coalesce to a state in
124
+ # which no overdue channels are in the cache and the
125
+ # length of the cache is longer than _MAXIMUM_CHANNELS.
126
+ # We tolerate momentary states in which these two
127
+ # criteria are not met.
128
+ ChannelCache._condition.wait(timeout=time_to_eviction)
129
+
130
+ def get_channel(self, target: str, options: Sequence[Tuple[str, str]],
131
+ channel_credentials: Optional[grpc.ChannelCredentials],
132
+ insecure: bool,
133
+ compression: Optional[grpc.Compression]) -> grpc.Channel:
134
+ if insecure and channel_credentials:
135
+ raise ValueError("The insecure option is mutually exclusive with " +
136
+ "the channel_credentials option. Please use one " +
137
+ "or the other.")
138
+ if insecure:
139
+ channel_credentials = grpc.experimental.insecure_channel_credentials(
140
+ )
141
+ elif channel_credentials is None:
142
+ _LOGGER.debug("Defaulting to SSL channel credentials.")
143
+ channel_credentials = grpc.ssl_channel_credentials()
144
+ key = (target, options, channel_credentials, compression)
145
+ with self._lock:
146
+ channel_data = self._mapping.get(key, None)
147
+ if channel_data is not None:
148
+ channel = channel_data[0]
149
+ self._mapping.pop(key)
150
+ self._mapping[key] = (channel, datetime.datetime.now() +
151
+ _EVICTION_PERIOD)
152
+ return channel
153
+ else:
154
+ channel = _create_channel(target, options, channel_credentials,
155
+ compression)
156
+ self._mapping[key] = (channel, datetime.datetime.now() +
157
+ _EVICTION_PERIOD)
158
+ if len(self._mapping) == 1 or len(
159
+ self._mapping) >= _MAXIMUM_CHANNELS:
160
+ self._condition.notify()
161
+ return channel
162
+
163
+ def _test_only_channel_count(self) -> int:
164
+ with self._lock:
165
+ return len(self._mapping)
166
+
167
+
168
+ @experimental_api
169
+ def unary_unary(
170
+ request: RequestType,
171
+ target: str,
172
+ method: str,
173
+ request_serializer: Optional[Callable[[Any], bytes]] = None,
174
+ response_deserializer: Optional[Callable[[bytes], Any]] = None,
175
+ options: Sequence[Tuple[AnyStr, AnyStr]] = (),
176
+ channel_credentials: Optional[grpc.ChannelCredentials] = None,
177
+ insecure: bool = False,
178
+ call_credentials: Optional[grpc.CallCredentials] = None,
179
+ compression: Optional[grpc.Compression] = None,
180
+ wait_for_ready: Optional[bool] = None,
181
+ timeout: Optional[float] = _DEFAULT_TIMEOUT,
182
+ metadata: Optional[Sequence[Tuple[str, Union[str, bytes]]]] = None
183
+ ) -> ResponseType:
184
+ """Invokes a unary-unary RPC without an explicitly specified channel.
185
+
186
+ THIS IS AN EXPERIMENTAL API.
187
+
188
+ This is backed by a per-process cache of channels. Channels are evicted
189
+ from the cache after a fixed period by a background. Channels will also be
190
+ evicted if more than a configured maximum accumulate.
191
+
192
+ The default eviction period is 10 minutes. One may set the environment
193
+ variable "GRPC_PYTHON_MANAGED_CHANNEL_EVICTION_SECONDS" to configure this.
194
+
195
+ The default maximum number of channels is 256. One may set the
196
+ environment variable "GRPC_PYTHON_MANAGED_CHANNEL_MAXIMUM" to configure
197
+ this.
198
+
199
+ Args:
200
+ request: An iterator that yields request values for the RPC.
201
+ target: The server address.
202
+ method: The name of the RPC method.
203
+ request_serializer: Optional :term:`serializer` for serializing the request
204
+ message. Request goes unserialized in case None is passed.
205
+ response_deserializer: Optional :term:`deserializer` for deserializing the response
206
+ message. Response goes undeserialized in case None is passed.
207
+ options: An optional list of key-value pairs (:term:`channel_arguments` in gRPC Core
208
+ runtime) to configure the channel.
209
+ channel_credentials: A credential applied to the whole channel, e.g. the
210
+ return value of grpc.ssl_channel_credentials() or
211
+ grpc.insecure_channel_credentials().
212
+ insecure: If True, specifies channel_credentials as
213
+ :term:`grpc.insecure_channel_credentials()`. This option is mutually
214
+ exclusive with the `channel_credentials` option.
215
+ call_credentials: A call credential applied to each call individually,
216
+ e.g. the output of grpc.metadata_call_credentials() or
217
+ grpc.access_token_call_credentials().
218
+ compression: An optional value indicating the compression method to be
219
+ used over the lifetime of the channel, e.g. grpc.Compression.Gzip.
220
+ wait_for_ready: An optional flag indicating whether the RPC should fail
221
+ immediately if the connection is not ready at the time the RPC is
222
+ invoked, or if it should wait until the connection to the server
223
+ becomes ready. When using this option, the user will likely also want
224
+ to set a timeout. Defaults to True.
225
+ timeout: An optional duration of time in seconds to allow for the RPC,
226
+ after which an exception will be raised. If timeout is unspecified,
227
+ defaults to a timeout controlled by the
228
+ GRPC_PYTHON_DEFAULT_TIMEOUT_SECONDS environment variable. If that is
229
+ unset, defaults to 60 seconds. Supply a value of None to indicate that
230
+ no timeout should be enforced.
231
+ metadata: Optional metadata to send to the server.
232
+
233
+ Returns:
234
+ The response to the RPC.
235
+ """
236
+ channel = ChannelCache.get().get_channel(target, options,
237
+ channel_credentials, insecure,
238
+ compression)
239
+ multicallable = channel.unary_unary(method, request_serializer,
240
+ response_deserializer)
241
+ wait_for_ready = wait_for_ready if wait_for_ready is not None else True
242
+ return multicallable(request,
243
+ metadata=metadata,
244
+ wait_for_ready=wait_for_ready,
245
+ credentials=call_credentials,
246
+ timeout=timeout)
247
+
248
+
249
+ @experimental_api
250
+ def unary_stream(
251
+ request: RequestType,
252
+ target: str,
253
+ method: str,
254
+ request_serializer: Optional[Callable[[Any], bytes]] = None,
255
+ response_deserializer: Optional[Callable[[bytes], Any]] = None,
256
+ options: Sequence[Tuple[AnyStr, AnyStr]] = (),
257
+ channel_credentials: Optional[grpc.ChannelCredentials] = None,
258
+ insecure: bool = False,
259
+ call_credentials: Optional[grpc.CallCredentials] = None,
260
+ compression: Optional[grpc.Compression] = None,
261
+ wait_for_ready: Optional[bool] = None,
262
+ timeout: Optional[float] = _DEFAULT_TIMEOUT,
263
+ metadata: Optional[Sequence[Tuple[str, Union[str, bytes]]]] = None
264
+ ) -> Iterator[ResponseType]:
265
+ """Invokes a unary-stream RPC without an explicitly specified channel.
266
+
267
+ THIS IS AN EXPERIMENTAL API.
268
+
269
+ This is backed by a per-process cache of channels. Channels are evicted
270
+ from the cache after a fixed period by a background. Channels will also be
271
+ evicted if more than a configured maximum accumulate.
272
+
273
+ The default eviction period is 10 minutes. One may set the environment
274
+ variable "GRPC_PYTHON_MANAGED_CHANNEL_EVICTION_SECONDS" to configure this.
275
+
276
+ The default maximum number of channels is 256. One may set the
277
+ environment variable "GRPC_PYTHON_MANAGED_CHANNEL_MAXIMUM" to configure
278
+ this.
279
+
280
+ Args:
281
+ request: An iterator that yields request values for the RPC.
282
+ target: The server address.
283
+ method: The name of the RPC method.
284
+ request_serializer: Optional :term:`serializer` for serializing the request
285
+ message. Request goes unserialized in case None is passed.
286
+ response_deserializer: Optional :term:`deserializer` for deserializing the response
287
+ message. Response goes undeserialized in case None is passed.
288
+ options: An optional list of key-value pairs (:term:`channel_arguments` in gRPC Core
289
+ runtime) to configure the channel.
290
+ channel_credentials: A credential applied to the whole channel, e.g. the
291
+ return value of grpc.ssl_channel_credentials().
292
+ insecure: If True, specifies channel_credentials as
293
+ :term:`grpc.insecure_channel_credentials()`. This option is mutually
294
+ exclusive with the `channel_credentials` option.
295
+ call_credentials: A call credential applied to each call individually,
296
+ e.g. the output of grpc.metadata_call_credentials() or
297
+ grpc.access_token_call_credentials().
298
+ compression: An optional value indicating the compression method to be
299
+ used over the lifetime of the channel, e.g. grpc.Compression.Gzip.
300
+ wait_for_ready: An optional flag indicating whether the RPC should fail
301
+ immediately if the connection is not ready at the time the RPC is
302
+ invoked, or if it should wait until the connection to the server
303
+ becomes ready. When using this option, the user will likely also want
304
+ to set a timeout. Defaults to True.
305
+ timeout: An optional duration of time in seconds to allow for the RPC,
306
+ after which an exception will be raised. If timeout is unspecified,
307
+ defaults to a timeout controlled by the
308
+ GRPC_PYTHON_DEFAULT_TIMEOUT_SECONDS environment variable. If that is
309
+ unset, defaults to 60 seconds. Supply a value of None to indicate that
310
+ no timeout should be enforced.
311
+ metadata: Optional metadata to send to the server.
312
+
313
+ Returns:
314
+ An iterator of responses.
315
+ """
316
+ channel = ChannelCache.get().get_channel(target, options,
317
+ channel_credentials, insecure,
318
+ compression)
319
+ multicallable = channel.unary_stream(method, request_serializer,
320
+ response_deserializer)
321
+ wait_for_ready = wait_for_ready if wait_for_ready is not None else True
322
+ return multicallable(request,
323
+ metadata=metadata,
324
+ wait_for_ready=wait_for_ready,
325
+ credentials=call_credentials,
326
+ timeout=timeout)
327
+
328
+
329
+ @experimental_api
330
+ def stream_unary(
331
+ request_iterator: Iterator[RequestType],
332
+ target: str,
333
+ method: str,
334
+ request_serializer: Optional[Callable[[Any], bytes]] = None,
335
+ response_deserializer: Optional[Callable[[bytes], Any]] = None,
336
+ options: Sequence[Tuple[AnyStr, AnyStr]] = (),
337
+ channel_credentials: Optional[grpc.ChannelCredentials] = None,
338
+ insecure: bool = False,
339
+ call_credentials: Optional[grpc.CallCredentials] = None,
340
+ compression: Optional[grpc.Compression] = None,
341
+ wait_for_ready: Optional[bool] = None,
342
+ timeout: Optional[float] = _DEFAULT_TIMEOUT,
343
+ metadata: Optional[Sequence[Tuple[str, Union[str, bytes]]]] = None
344
+ ) -> ResponseType:
345
+ """Invokes a stream-unary RPC without an explicitly specified channel.
346
+
347
+ THIS IS AN EXPERIMENTAL API.
348
+
349
+ This is backed by a per-process cache of channels. Channels are evicted
350
+ from the cache after a fixed period by a background. Channels will also be
351
+ evicted if more than a configured maximum accumulate.
352
+
353
+ The default eviction period is 10 minutes. One may set the environment
354
+ variable "GRPC_PYTHON_MANAGED_CHANNEL_EVICTION_SECONDS" to configure this.
355
+
356
+ The default maximum number of channels is 256. One may set the
357
+ environment variable "GRPC_PYTHON_MANAGED_CHANNEL_MAXIMUM" to configure
358
+ this.
359
+
360
+ Args:
361
+ request_iterator: An iterator that yields request values for the RPC.
362
+ target: The server address.
363
+ method: The name of the RPC method.
364
+ request_serializer: Optional :term:`serializer` for serializing the request
365
+ message. Request goes unserialized in case None is passed.
366
+ response_deserializer: Optional :term:`deserializer` for deserializing the response
367
+ message. Response goes undeserialized in case None is passed.
368
+ options: An optional list of key-value pairs (:term:`channel_arguments` in gRPC Core
369
+ runtime) to configure the channel.
370
+ channel_credentials: A credential applied to the whole channel, e.g. the
371
+ return value of grpc.ssl_channel_credentials().
372
+ call_credentials: A call credential applied to each call individually,
373
+ e.g. the output of grpc.metadata_call_credentials() or
374
+ grpc.access_token_call_credentials().
375
+ insecure: If True, specifies channel_credentials as
376
+ :term:`grpc.insecure_channel_credentials()`. This option is mutually
377
+ exclusive with the `channel_credentials` option.
378
+ compression: An optional value indicating the compression method to be
379
+ used over the lifetime of the channel, e.g. grpc.Compression.Gzip.
380
+ wait_for_ready: An optional flag indicating whether the RPC should fail
381
+ immediately if the connection is not ready at the time the RPC is
382
+ invoked, or if it should wait until the connection to the server
383
+ becomes ready. When using this option, the user will likely also want
384
+ to set a timeout. Defaults to True.
385
+ timeout: An optional duration of time in seconds to allow for the RPC,
386
+ after which an exception will be raised. If timeout is unspecified,
387
+ defaults to a timeout controlled by the
388
+ GRPC_PYTHON_DEFAULT_TIMEOUT_SECONDS environment variable. If that is
389
+ unset, defaults to 60 seconds. Supply a value of None to indicate that
390
+ no timeout should be enforced.
391
+ metadata: Optional metadata to send to the server.
392
+
393
+ Returns:
394
+ The response to the RPC.
395
+ """
396
+ channel = ChannelCache.get().get_channel(target, options,
397
+ channel_credentials, insecure,
398
+ compression)
399
+ multicallable = channel.stream_unary(method, request_serializer,
400
+ response_deserializer)
401
+ wait_for_ready = wait_for_ready if wait_for_ready is not None else True
402
+ return multicallable(request_iterator,
403
+ metadata=metadata,
404
+ wait_for_ready=wait_for_ready,
405
+ credentials=call_credentials,
406
+ timeout=timeout)
407
+
408
+
409
+ @experimental_api
410
+ def stream_stream(
411
+ request_iterator: Iterator[RequestType],
412
+ target: str,
413
+ method: str,
414
+ request_serializer: Optional[Callable[[Any], bytes]] = None,
415
+ response_deserializer: Optional[Callable[[bytes], Any]] = None,
416
+ options: Sequence[Tuple[AnyStr, AnyStr]] = (),
417
+ channel_credentials: Optional[grpc.ChannelCredentials] = None,
418
+ insecure: bool = False,
419
+ call_credentials: Optional[grpc.CallCredentials] = None,
420
+ compression: Optional[grpc.Compression] = None,
421
+ wait_for_ready: Optional[bool] = None,
422
+ timeout: Optional[float] = _DEFAULT_TIMEOUT,
423
+ metadata: Optional[Sequence[Tuple[str, Union[str, bytes]]]] = None
424
+ ) -> Iterator[ResponseType]:
425
+ """Invokes a stream-stream RPC without an explicitly specified channel.
426
+
427
+ THIS IS AN EXPERIMENTAL API.
428
+
429
+ This is backed by a per-process cache of channels. Channels are evicted
430
+ from the cache after a fixed period by a background. Channels will also be
431
+ evicted if more than a configured maximum accumulate.
432
+
433
+ The default eviction period is 10 minutes. One may set the environment
434
+ variable "GRPC_PYTHON_MANAGED_CHANNEL_EVICTION_SECONDS" to configure this.
435
+
436
+ The default maximum number of channels is 256. One may set the
437
+ environment variable "GRPC_PYTHON_MANAGED_CHANNEL_MAXIMUM" to configure
438
+ this.
439
+
440
+ Args:
441
+ request_iterator: An iterator that yields request values for the RPC.
442
+ target: The server address.
443
+ method: The name of the RPC method.
444
+ request_serializer: Optional :term:`serializer` for serializing the request
445
+ message. Request goes unserialized in case None is passed.
446
+ response_deserializer: Optional :term:`deserializer` for deserializing the response
447
+ message. Response goes undeserialized in case None is passed.
448
+ options: An optional list of key-value pairs (:term:`channel_arguments` in gRPC Core
449
+ runtime) to configure the channel.
450
+ channel_credentials: A credential applied to the whole channel, e.g. the
451
+ return value of grpc.ssl_channel_credentials().
452
+ call_credentials: A call credential applied to each call individually,
453
+ e.g. the output of grpc.metadata_call_credentials() or
454
+ grpc.access_token_call_credentials().
455
+ insecure: If True, specifies channel_credentials as
456
+ :term:`grpc.insecure_channel_credentials()`. This option is mutually
457
+ exclusive with the `channel_credentials` option.
458
+ compression: An optional value indicating the compression method to be
459
+ used over the lifetime of the channel, e.g. grpc.Compression.Gzip.
460
+ wait_for_ready: An optional flag indicating whether the RPC should fail
461
+ immediately if the connection is not ready at the time the RPC is
462
+ invoked, or if it should wait until the connection to the server
463
+ becomes ready. When using this option, the user will likely also want
464
+ to set a timeout. Defaults to True.
465
+ timeout: An optional duration of time in seconds to allow for the RPC,
466
+ after which an exception will be raised. If timeout is unspecified,
467
+ defaults to a timeout controlled by the
468
+ GRPC_PYTHON_DEFAULT_TIMEOUT_SECONDS environment variable. If that is
469
+ unset, defaults to 60 seconds. Supply a value of None to indicate that
470
+ no timeout should be enforced.
471
+ metadata: Optional metadata to send to the server.
472
+
473
+ Returns:
474
+ An iterator of responses.
475
+ """
476
+ channel = ChannelCache.get().get_channel(target, options,
477
+ channel_credentials, insecure,
478
+ compression)
479
+ multicallable = channel.stream_stream(method, request_serializer,
480
+ response_deserializer)
481
+ wait_for_ready = wait_for_ready if wait_for_ready is not None else True
482
+ return multicallable(request_iterator,
483
+ metadata=metadata,
484
+ wait_for_ready=wait_for_ready,
485
+ credentials=call_credentials,
486
+ timeout=timeout)
my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/omegaconf/_impl.py ADDED
@@ -0,0 +1,101 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from typing import Any
2
+
3
+ from omegaconf import MISSING, Container, DictConfig, ListConfig, Node, ValueNode
4
+ from omegaconf.errors import ConfigTypeError, InterpolationToMissingValueError
5
+
6
+ from ._utils import _DEFAULT_MARKER_, _get_value
7
+
8
+
9
+ def _resolve_container_value(cfg: Container, key: Any) -> None:
10
+ node = cfg._get_child(key)
11
+ assert isinstance(node, Node)
12
+ if node._is_interpolation():
13
+ try:
14
+ resolved = node._dereference_node()
15
+ except InterpolationToMissingValueError:
16
+ node._set_value(MISSING)
17
+ else:
18
+ if isinstance(resolved, Container):
19
+ _resolve(resolved)
20
+ if isinstance(resolved, Container) and isinstance(node, ValueNode):
21
+ cfg[key] = resolved
22
+ else:
23
+ node._set_value(_get_value(resolved))
24
+ else:
25
+ _resolve(node)
26
+
27
+
28
+ def _resolve(cfg: Node) -> Node:
29
+ assert isinstance(cfg, Node)
30
+ if cfg._is_interpolation():
31
+ try:
32
+ resolved = cfg._dereference_node()
33
+ except InterpolationToMissingValueError:
34
+ cfg._set_value(MISSING)
35
+ else:
36
+ cfg._set_value(resolved._value())
37
+
38
+ if isinstance(cfg, DictConfig):
39
+ for k in cfg.keys():
40
+ _resolve_container_value(cfg, k)
41
+
42
+ elif isinstance(cfg, ListConfig):
43
+ for i in range(len(cfg)):
44
+ _resolve_container_value(cfg, i)
45
+
46
+ return cfg
47
+
48
+
49
+ def select_value(
50
+ cfg: Container,
51
+ key: str,
52
+ *,
53
+ default: Any = _DEFAULT_MARKER_,
54
+ throw_on_resolution_failure: bool = True,
55
+ throw_on_missing: bool = False,
56
+ absolute_key: bool = False,
57
+ ) -> Any:
58
+ node = select_node(
59
+ cfg=cfg,
60
+ key=key,
61
+ throw_on_resolution_failure=throw_on_resolution_failure,
62
+ throw_on_missing=throw_on_missing,
63
+ absolute_key=absolute_key,
64
+ )
65
+
66
+ node_not_found = node is None
67
+ if node_not_found or node._is_missing():
68
+ if default is not _DEFAULT_MARKER_:
69
+ return default
70
+ else:
71
+ return None
72
+
73
+ return _get_value(node)
74
+
75
+
76
+ def select_node(
77
+ cfg: Container,
78
+ key: str,
79
+ *,
80
+ throw_on_resolution_failure: bool = True,
81
+ throw_on_missing: bool = False,
82
+ absolute_key: bool = False,
83
+ ) -> Any:
84
+ try:
85
+ # for non relative keys, the interpretation can be:
86
+ # 1. relative to cfg
87
+ # 2. relative to the config root
88
+ # This is controlled by the absolute_key flag. By default, such keys are relative to cfg.
89
+ if not absolute_key and not key.startswith("."):
90
+ key = f".{key}"
91
+
92
+ cfg, key = cfg._resolve_key_and_root(key)
93
+ _root, _last_key, node = cfg._select_impl(
94
+ key,
95
+ throw_on_missing=throw_on_missing,
96
+ throw_on_resolution_failure=throw_on_resolution_failure,
97
+ )
98
+ except ConfigTypeError:
99
+ return None
100
+
101
+ return node
my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/omegaconf/errors.py ADDED
@@ -0,0 +1,141 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from typing import Any, Optional, Type
2
+
3
+
4
+ class OmegaConfBaseException(Exception):
5
+ # would ideally be typed Optional[Node]
6
+ parent_node: Any
7
+ child_node: Any
8
+ key: Any
9
+ full_key: Optional[str]
10
+ value: Any
11
+ msg: Optional[str]
12
+ cause: Optional[Exception]
13
+ object_type: Optional[Type[Any]]
14
+ object_type_str: Optional[str]
15
+ ref_type: Optional[Type[Any]]
16
+ ref_type_str: Optional[str]
17
+
18
+ _initialized: bool = False
19
+
20
+ def __init__(self, *_args: Any, **_kwargs: Any) -> None:
21
+ self.parent_node = None
22
+ self.child_node = None
23
+ self.key = None
24
+ self.full_key = None
25
+ self.value = None
26
+ self.msg = None
27
+ self.object_type = None
28
+ self.ref_type = None
29
+
30
+
31
+ class MissingMandatoryValue(OmegaConfBaseException):
32
+ """Thrown when a variable flagged with '???' value is accessed to
33
+ indicate that the value was not set"""
34
+
35
+
36
+ class KeyValidationError(OmegaConfBaseException, ValueError):
37
+ """
38
+ Thrown when an a key of invalid type is used
39
+ """
40
+
41
+
42
+ class ValidationError(OmegaConfBaseException, ValueError):
43
+ """
44
+ Thrown when a value fails validation
45
+ """
46
+
47
+
48
+ class UnsupportedValueType(ValidationError, ValueError):
49
+ """
50
+ Thrown when an input value is not of supported type
51
+ """
52
+
53
+
54
+ class ReadonlyConfigError(OmegaConfBaseException):
55
+ """
56
+ Thrown when someone tries to modify a frozen config
57
+ """
58
+
59
+
60
+ class InterpolationResolutionError(OmegaConfBaseException, ValueError):
61
+ """
62
+ Base class for exceptions raised when resolving an interpolation.
63
+ """
64
+
65
+
66
+ class UnsupportedInterpolationType(InterpolationResolutionError):
67
+ """
68
+ Thrown when an attempt to use an unregistered interpolation is made
69
+ """
70
+
71
+
72
+ class InterpolationKeyError(InterpolationResolutionError):
73
+ """
74
+ Thrown when a node does not exist when resolving an interpolation.
75
+ """
76
+
77
+
78
+ class InterpolationToMissingValueError(InterpolationResolutionError):
79
+ """
80
+ Thrown when a node interpolation points to a node that is set to ???.
81
+ """
82
+
83
+
84
+ class InterpolationValidationError(InterpolationResolutionError, ValidationError):
85
+ """
86
+ Thrown when the result of an interpolation fails the validation step.
87
+ """
88
+
89
+
90
+ class ConfigKeyError(OmegaConfBaseException, KeyError):
91
+ """
92
+ Thrown from DictConfig when a regular dict access would have caused a KeyError.
93
+ """
94
+
95
+ msg: str
96
+
97
+ def __init__(self, msg: str) -> None:
98
+ super().__init__(msg)
99
+ self.msg = msg
100
+
101
+ def __str__(self) -> str:
102
+ """
103
+ Workaround to nasty KeyError quirk: https://bugs.python.org/issue2651
104
+ """
105
+ return self.msg
106
+
107
+
108
+ class ConfigAttributeError(OmegaConfBaseException, AttributeError):
109
+ """
110
+ Thrown from a config object when a regular access would have caused an AttributeError.
111
+ """
112
+
113
+
114
+ class ConfigTypeError(OmegaConfBaseException, TypeError):
115
+ """
116
+ Thrown from a config object when a regular access would have caused a TypeError.
117
+ """
118
+
119
+
120
+ class ConfigIndexError(OmegaConfBaseException, IndexError):
121
+ """
122
+ Thrown from a config object when a regular access would have caused an IndexError.
123
+ """
124
+
125
+
126
+ class ConfigValueError(OmegaConfBaseException, ValueError):
127
+ """
128
+ Thrown from a config object when a regular access would have caused a ValueError.
129
+ """
130
+
131
+
132
+ class ConfigCycleDetectedException(OmegaConfBaseException):
133
+ """
134
+ Thrown when a cycle is detected in the graph made by config nodes.
135
+ """
136
+
137
+
138
+ class GrammarParseError(OmegaConfBaseException):
139
+ """
140
+ Thrown when failing to parse an expression according to the ANTLR grammar.
141
+ """
my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/omegaconf/grammar_parser.py ADDED
@@ -0,0 +1,144 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import re
2
+ import threading
3
+ from typing import Any
4
+
5
+ from antlr4 import CommonTokenStream, InputStream, ParserRuleContext
6
+ from antlr4.error.ErrorListener import ErrorListener
7
+
8
+ from .errors import GrammarParseError
9
+
10
+ # Import from visitor in order to check the presence of generated grammar files
11
+ # files in a single place.
12
+ from .grammar_visitor import ( # type: ignore
13
+ OmegaConfGrammarLexer,
14
+ OmegaConfGrammarParser,
15
+ )
16
+
17
+ # Used to cache grammar objects to avoid re-creating them on each call to `parse()`.
18
+ # We use a per-thread cache to make it thread-safe.
19
+ _grammar_cache = threading.local()
20
+
21
+ # Build regex pattern to efficiently identify typical interpolations.
22
+ # See test `test_match_simple_interpolation_pattern` for examples.
23
+ _config_key = r"[$\w]+" # foo, $0, $bar, $foo_$bar123$
24
+ _key_maybe_brackets = f"{_config_key}|\\[{_config_key}\\]" # foo, [foo], [$bar]
25
+ _node_access = f"\\.{_key_maybe_brackets}" # .foo, [foo], [$bar]
26
+ _node_path = f"(\\.)*({_key_maybe_brackets})({_node_access})*" # [foo].bar, .foo[bar]
27
+ _node_inter = f"\\${{\\s*{_node_path}\\s*}}" # node interpolation ${foo.bar}
28
+ _id = "[a-zA-Z_]\\w*" # foo, foo_bar, abc123
29
+ _resolver_name = f"({_id}(\\.{_id})*)?" # foo, ns.bar3, ns_1.ns_2.b0z
30
+ _arg = r"[a-zA-Z_0-9/\-\+.$%*@?|]+" # string representing a resolver argument
31
+ _args = f"{_arg}(\\s*,\\s*{_arg})*" # list of resolver arguments
32
+ _resolver_inter = f"\\${{\\s*{_resolver_name}\\s*:\\s*{_args}?\\s*}}" # ${foo:bar}
33
+ _inter = f"({_node_inter}|{_resolver_inter})" # any kind of interpolation
34
+ _outer = "([^$]|\\$(?!{))+" # any character except $ (unless not followed by {)
35
+ SIMPLE_INTERPOLATION_PATTERN = re.compile(
36
+ f"({_outer})?({_inter}({_outer})?)+$", flags=re.ASCII
37
+ )
38
+ # NOTE: SIMPLE_INTERPOLATION_PATTERN must not generate false positive matches:
39
+ # it must not accept anything that isn't a valid interpolation (per the
40
+ # interpolation grammar defined in `omegaconf/grammar/*.g4`).
41
+
42
+
43
+ class OmegaConfErrorListener(ErrorListener): # type: ignore
44
+ def syntaxError(
45
+ self,
46
+ recognizer: Any,
47
+ offending_symbol: Any,
48
+ line: Any,
49
+ column: Any,
50
+ msg: Any,
51
+ e: Any,
52
+ ) -> None:
53
+ raise GrammarParseError(str(e) if msg is None else msg) from e
54
+
55
+ def reportAmbiguity(
56
+ self,
57
+ recognizer: Any,
58
+ dfa: Any,
59
+ startIndex: Any,
60
+ stopIndex: Any,
61
+ exact: Any,
62
+ ambigAlts: Any,
63
+ configs: Any,
64
+ ) -> None:
65
+ raise GrammarParseError("ANTLR error: Ambiguity") # pragma: no cover
66
+
67
+ def reportAttemptingFullContext(
68
+ self,
69
+ recognizer: Any,
70
+ dfa: Any,
71
+ startIndex: Any,
72
+ stopIndex: Any,
73
+ conflictingAlts: Any,
74
+ configs: Any,
75
+ ) -> None:
76
+ # Note: for now we raise an error to be safe. However this is mostly a
77
+ # performance warning, so in the future this may be relaxed if we need
78
+ # to change the grammar in such a way that this warning cannot be
79
+ # avoided (another option would be to switch to SLL parsing mode).
80
+ raise GrammarParseError(
81
+ "ANTLR error: Attempting Full Context"
82
+ ) # pragma: no cover
83
+
84
+ def reportContextSensitivity(
85
+ self,
86
+ recognizer: Any,
87
+ dfa: Any,
88
+ startIndex: Any,
89
+ stopIndex: Any,
90
+ prediction: Any,
91
+ configs: Any,
92
+ ) -> None:
93
+ raise GrammarParseError("ANTLR error: ContextSensitivity") # pragma: no cover
94
+
95
+
96
+ def parse(
97
+ value: str, parser_rule: str = "configValue", lexer_mode: str = "DEFAULT_MODE"
98
+ ) -> ParserRuleContext:
99
+ """
100
+ Parse interpolated string `value` (and return the parse tree).
101
+ """
102
+ l_mode = getattr(OmegaConfGrammarLexer, lexer_mode)
103
+ istream = InputStream(value)
104
+
105
+ cached = getattr(_grammar_cache, "data", None)
106
+ if cached is None:
107
+ error_listener = OmegaConfErrorListener()
108
+ lexer = OmegaConfGrammarLexer(istream)
109
+ lexer.removeErrorListeners()
110
+ lexer.addErrorListener(error_listener)
111
+ lexer.mode(l_mode)
112
+ token_stream = CommonTokenStream(lexer)
113
+ parser = OmegaConfGrammarParser(token_stream)
114
+ parser.removeErrorListeners()
115
+ parser.addErrorListener(error_listener)
116
+
117
+ # The two lines below could be enabled in the future if we decide to switch
118
+ # to SLL prediction mode. Warning though, it has not been fully tested yet!
119
+ # from antlr4 import PredictionMode
120
+ # parser._interp.predictionMode = PredictionMode.SLL
121
+
122
+ # Note that although the input stream `istream` is implicitly cached within
123
+ # the lexer, it will be replaced by a new input next time the lexer is re-used.
124
+ _grammar_cache.data = lexer, token_stream, parser
125
+
126
+ else:
127
+ lexer, token_stream, parser = cached
128
+ # Replace the old input stream with the new one.
129
+ lexer.inputStream = istream
130
+ # Initialize the lexer / token stream / parser to process the new input.
131
+ lexer.mode(l_mode)
132
+ token_stream.setTokenSource(lexer)
133
+ parser.reset()
134
+
135
+ try:
136
+ return getattr(parser, parser_rule)()
137
+ except Exception as exc:
138
+ if type(exc) is Exception and str(exc) == "Empty Stack":
139
+ # This exception is raised by antlr when trying to pop a mode while
140
+ # no mode has been pushed. We convert it into an `GrammarParseError`
141
+ # to facilitate exception handling from the caller.
142
+ raise GrammarParseError("Empty Stack")
143
+ else:
144
+ raise
my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/omegaconf/version.py ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import sys # pragma: no cover
2
+
3
+ __version__ = "2.2.3"
4
+
5
+ msg = """OmegaConf 2.0 and above is compatible with Python 3.6 and newer.
6
+ You have the following options:
7
+ 1. Upgrade to Python 3.6 or newer.
8
+ This is highly recommended. new features will not be added to OmegaConf 1.4.
9
+ 2. Continue using OmegaConf 1.4:
10
+ You can pip install 'OmegaConf<1.5' to do that.
11
+ """
12
+ if sys.version_info < (3, 6):
13
+ raise ImportError(msg) # pragma: no cover
my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/pyasn1_modules/rfc3114.py ADDED
@@ -0,0 +1,77 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #
2
+ # This file is part of pyasn1-modules software.
3
+ #
4
+ # Created by Russ Housley with assistance from asn1ate v.0.6.0.
5
+ #
6
+ # Copyright (c) 2019, Vigil Security, LLC
7
+ # License: http://snmplabs.com/pyasn1/license.html
8
+ #
9
+ # TEST Company Classification Policies
10
+ #
11
+ # ASN.1 source from:
12
+ # https://www.rfc-editor.org/rfc/rfc3114.txt
13
+ #
14
+
15
+ from pyasn1.type import char
16
+ from pyasn1.type import namedval
17
+ from pyasn1.type import univ
18
+
19
+ from pyasn1_modules import rfc5755
20
+
21
+
22
+ id_smime = univ.ObjectIdentifier((1, 2, 840, 113549, 1, 9, 16, ))
23
+
24
+ id_tsp = id_smime + (7, )
25
+
26
+ id_tsp_TEST_Amoco = id_tsp + (1, )
27
+
28
+ class Amoco_SecurityClassification(univ.Integer):
29
+ namedValues = namedval.NamedValues(
30
+ ('amoco-general', 6),
31
+ ('amoco-confidential', 7),
32
+ ('amoco-highly-confidential', 8)
33
+ )
34
+
35
+
36
+ id_tsp_TEST_Caterpillar = id_tsp + (2, )
37
+
38
+ class Caterpillar_SecurityClassification(univ.Integer):
39
+ namedValues = namedval.NamedValues(
40
+ ('caterpillar-public', 6),
41
+ ('caterpillar-green', 7),
42
+ ('caterpillar-yellow', 8),
43
+ ('caterpillar-red', 9)
44
+ )
45
+
46
+
47
+ id_tsp_TEST_Whirlpool = id_tsp + (3, )
48
+
49
+ class Whirlpool_SecurityClassification(univ.Integer):
50
+ namedValues = namedval.NamedValues(
51
+ ('whirlpool-public', 6),
52
+ ('whirlpool-internal', 7),
53
+ ('whirlpool-confidential', 8)
54
+ )
55
+
56
+
57
+ id_tsp_TEST_Whirlpool_Categories = id_tsp + (4, )
58
+
59
+ class SecurityCategoryValues(univ.SequenceOf):
60
+ componentType = char.UTF8String()
61
+
62
+ # Example SecurityCategoryValues: "LAW DEPARTMENT USE ONLY"
63
+ # Example SecurityCategoryValues: "HUMAN RESOURCES USE ONLY"
64
+
65
+
66
+ # Also, the privacy mark in the security label can contain a string,
67
+ # such as: "ATTORNEY-CLIENT PRIVILEGED INFORMATION"
68
+
69
+
70
+ # Map of security category type OIDs to security category added
71
+ # to the ones that are in rfc5755.py
72
+
73
+ _securityCategoryMapUpdate = {
74
+ id_tsp_TEST_Whirlpool_Categories: SecurityCategoryValues(),
75
+ }
76
+
77
+ rfc5755.securityCategoryMap.update(_securityCategoryMapUpdate)
my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/pyasn1_modules/rfc3281.py ADDED
@@ -0,0 +1,331 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # coding: utf-8
2
+ #
3
+ # This file is part of pyasn1-modules software.
4
+ #
5
+ # Created by Stanisław Pitucha with asn1ate tool.
6
+ # Copyright (c) 2005-2019, Ilya Etingof <etingof@gmail.com>
7
+ # License: http://snmplabs.com/pyasn1/license.html
8
+ #
9
+ # An Internet Attribute Certificate Profile for Authorization
10
+ #
11
+ # ASN.1 source from:
12
+ # http://www.ietf.org/rfc/rfc3281.txt
13
+ #
14
+ from pyasn1.type import char
15
+ from pyasn1.type import constraint
16
+ from pyasn1.type import namedtype
17
+ from pyasn1.type import namedval
18
+ from pyasn1.type import tag
19
+ from pyasn1.type import univ
20
+ from pyasn1.type import useful
21
+
22
+ from pyasn1_modules import rfc3280
23
+
24
+ MAX = float('inf')
25
+
26
+
27
+ def _buildOid(*components):
28
+ output = []
29
+ for x in tuple(components):
30
+ if isinstance(x, univ.ObjectIdentifier):
31
+ output.extend(list(x))
32
+ else:
33
+ output.append(int(x))
34
+
35
+ return univ.ObjectIdentifier(output)
36
+
37
+
38
+ class ObjectDigestInfo(univ.Sequence):
39
+ pass
40
+
41
+
42
+ ObjectDigestInfo.componentType = namedtype.NamedTypes(
43
+ namedtype.NamedType('digestedObjectType', univ.Enumerated(
44
+ namedValues=namedval.NamedValues(('publicKey', 0), ('publicKeyCert', 1), ('otherObjectTypes', 2)))),
45
+ namedtype.OptionalNamedType('otherObjectTypeID', univ.ObjectIdentifier()),
46
+ namedtype.NamedType('digestAlgorithm', rfc3280.AlgorithmIdentifier()),
47
+ namedtype.NamedType('objectDigest', univ.BitString())
48
+ )
49
+
50
+
51
+ class IssuerSerial(univ.Sequence):
52
+ pass
53
+
54
+
55
+ IssuerSerial.componentType = namedtype.NamedTypes(
56
+ namedtype.NamedType('issuer', rfc3280.GeneralNames()),
57
+ namedtype.NamedType('serial', rfc3280.CertificateSerialNumber()),
58
+ namedtype.OptionalNamedType('issuerUID', rfc3280.UniqueIdentifier())
59
+ )
60
+
61
+
62
+ class TargetCert(univ.Sequence):
63
+ pass
64
+
65
+
66
+ TargetCert.componentType = namedtype.NamedTypes(
67
+ namedtype.NamedType('targetCertificate', IssuerSerial()),
68
+ namedtype.OptionalNamedType('targetName', rfc3280.GeneralName()),
69
+ namedtype.OptionalNamedType('certDigestInfo', ObjectDigestInfo())
70
+ )
71
+
72
+
73
+ class Target(univ.Choice):
74
+ pass
75
+
76
+
77
+ Target.componentType = namedtype.NamedTypes(
78
+ namedtype.NamedType('targetName', rfc3280.GeneralName().subtype(
79
+ implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0))),
80
+ namedtype.NamedType('targetGroup', rfc3280.GeneralName().subtype(
81
+ implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 1))),
82
+ namedtype.NamedType('targetCert',
83
+ TargetCert().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 2)))
84
+ )
85
+
86
+
87
+ class Targets(univ.SequenceOf):
88
+ pass
89
+
90
+
91
+ Targets.componentType = Target()
92
+
93
+
94
+ class ProxyInfo(univ.SequenceOf):
95
+ pass
96
+
97
+
98
+ ProxyInfo.componentType = Targets()
99
+
100
+ id_at_role = _buildOid(rfc3280.id_at, 72)
101
+
102
+ id_pe_aaControls = _buildOid(rfc3280.id_pe, 6)
103
+
104
+ id_ce_targetInformation = _buildOid(rfc3280.id_ce, 55)
105
+
106
+ id_pe_ac_auditIdentity = _buildOid(rfc3280.id_pe, 4)
107
+
108
+
109
+ class ClassList(univ.BitString):
110
+ pass
111
+
112
+
113
+ ClassList.namedValues = namedval.NamedValues(
114
+ ('unmarked', 0),
115
+ ('unclassified', 1),
116
+ ('restricted', 2),
117
+ ('confidential', 3),
118
+ ('secret', 4),
119
+ ('topSecret', 5)
120
+ )
121
+
122
+
123
+ class SecurityCategory(univ.Sequence):
124
+ pass
125
+
126
+
127
+ SecurityCategory.componentType = namedtype.NamedTypes(
128
+ namedtype.NamedType('type', univ.ObjectIdentifier().subtype(
129
+ implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0))),
130
+ namedtype.NamedType('value', univ.Any().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 1)))
131
+ )
132
+
133
+
134
+ class Clearance(univ.Sequence):
135
+ pass
136
+
137
+
138
+ Clearance.componentType = namedtype.NamedTypes(
139
+ namedtype.NamedType('policyId', univ.ObjectIdentifier().subtype(
140
+ implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0))),
141
+ namedtype.DefaultedNamedType('classList',
142
+ ClassList().subtype(implicitTag=tag.Tag(tag.tagClassContext,
143
+ tag.tagFormatSimple, 1)).subtype(
144
+ value="unclassified")),
145
+ namedtype.OptionalNamedType('securityCategories', univ.SetOf(componentType=SecurityCategory()).subtype(
146
+ implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 2)))
147
+ )
148
+
149
+
150
+ class AttCertVersion(univ.Integer):
151
+ pass
152
+
153
+
154
+ AttCertVersion.namedValues = namedval.NamedValues(
155
+ ('v2', 1)
156
+ )
157
+
158
+ id_aca = _buildOid(rfc3280.id_pkix, 10)
159
+
160
+ id_at_clearance = _buildOid(2, 5, 1, 5, 55)
161
+
162
+
163
+ class AttrSpec(univ.SequenceOf):
164
+ pass
165
+
166
+
167
+ AttrSpec.componentType = univ.ObjectIdentifier()
168
+
169
+
170
+ class AAControls(univ.Sequence):
171
+ pass
172
+
173
+
174
+ AAControls.componentType = namedtype.NamedTypes(
175
+ namedtype.OptionalNamedType('pathLenConstraint',
176
+ univ.Integer().subtype(subtypeSpec=constraint.ValueRangeConstraint(0, MAX))),
177
+ namedtype.OptionalNamedType('permittedAttrs',
178
+ AttrSpec().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0))),
179
+ namedtype.OptionalNamedType('excludedAttrs',
180
+ AttrSpec().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 1))),
181
+ namedtype.DefaultedNamedType('permitUnSpecified', univ.Boolean().subtype(value=1))
182
+ )
183
+
184
+
185
+ class AttCertValidityPeriod(univ.Sequence):
186
+ pass
187
+
188
+
189
+ AttCertValidityPeriod.componentType = namedtype.NamedTypes(
190
+ namedtype.NamedType('notBeforeTime', useful.GeneralizedTime()),
191
+ namedtype.NamedType('notAfterTime', useful.GeneralizedTime())
192
+ )
193
+
194
+
195
+ id_aca_authenticationInfo = _buildOid(id_aca, 1)
196
+
197
+
198
+ class V2Form(univ.Sequence):
199
+ pass
200
+
201
+
202
+ V2Form.componentType = namedtype.NamedTypes(
203
+ namedtype.OptionalNamedType('issuerName', rfc3280.GeneralNames()),
204
+ namedtype.OptionalNamedType('baseCertificateID', IssuerSerial().subtype(
205
+ implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 0))),
206
+ namedtype.OptionalNamedType('objectDigestInfo', ObjectDigestInfo().subtype(
207
+ implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 1)))
208
+ )
209
+
210
+
211
+ class AttCertIssuer(univ.Choice):
212
+ pass
213
+
214
+
215
+ AttCertIssuer.componentType = namedtype.NamedTypes(
216
+ namedtype.NamedType('v1Form', rfc3280.GeneralNames()),
217
+ namedtype.NamedType('v2Form',
218
+ V2Form().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 0)))
219
+ )
220
+
221
+
222
+ class Holder(univ.Sequence):
223
+ pass
224
+
225
+
226
+ Holder.componentType = namedtype.NamedTypes(
227
+ namedtype.OptionalNamedType('baseCertificateID', IssuerSerial().subtype(
228
+ implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 0))),
229
+ namedtype.OptionalNamedType('entityName', rfc3280.GeneralNames().subtype(
230
+ implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 1))),
231
+ namedtype.OptionalNamedType('objectDigestInfo', ObjectDigestInfo().subtype(
232
+ implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 2)))
233
+ )
234
+
235
+
236
+ class AttributeCertificateInfo(univ.Sequence):
237
+ pass
238
+
239
+
240
+ AttributeCertificateInfo.componentType = namedtype.NamedTypes(
241
+ namedtype.NamedType('version', AttCertVersion()),
242
+ namedtype.NamedType('holder', Holder()),
243
+ namedtype.NamedType('issuer', AttCertIssuer()),
244
+ namedtype.NamedType('signature', rfc3280.AlgorithmIdentifier()),
245
+ namedtype.NamedType('serialNumber', rfc3280.CertificateSerialNumber()),
246
+ namedtype.NamedType('attrCertValidityPeriod', AttCertValidityPeriod()),
247
+ namedtype.NamedType('attributes', univ.SequenceOf(componentType=rfc3280.Attribute())),
248
+ namedtype.OptionalNamedType('issuerUniqueID', rfc3280.UniqueIdentifier()),
249
+ namedtype.OptionalNamedType('extensions', rfc3280.Extensions())
250
+ )
251
+
252
+
253
+ class AttributeCertificate(univ.Sequence):
254
+ pass
255
+
256
+
257
+ AttributeCertificate.componentType = namedtype.NamedTypes(
258
+ namedtype.NamedType('acinfo', AttributeCertificateInfo()),
259
+ namedtype.NamedType('signatureAlgorithm', rfc3280.AlgorithmIdentifier()),
260
+ namedtype.NamedType('signatureValue', univ.BitString())
261
+ )
262
+
263
+ id_mod = _buildOid(rfc3280.id_pkix, 0)
264
+
265
+ id_mod_attribute_cert = _buildOid(id_mod, 12)
266
+
267
+ id_aca_accessIdentity = _buildOid(id_aca, 2)
268
+
269
+
270
+ class RoleSyntax(univ.Sequence):
271
+ pass
272
+
273
+
274
+ RoleSyntax.componentType = namedtype.NamedTypes(
275
+ namedtype.OptionalNamedType('roleAuthority', rfc3280.GeneralNames().subtype(
276
+ implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0))),
277
+ namedtype.NamedType('roleName',
278
+ rfc3280.GeneralName().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 1)))
279
+ )
280
+
281
+ id_aca_chargingIdentity = _buildOid(id_aca, 3)
282
+
283
+
284
+ class ACClearAttrs(univ.Sequence):
285
+ pass
286
+
287
+
288
+ ACClearAttrs.componentType = namedtype.NamedTypes(
289
+ namedtype.NamedType('acIssuer', rfc3280.GeneralName()),
290
+ namedtype.NamedType('acSerial', univ.Integer()),
291
+ namedtype.NamedType('attrs', univ.SequenceOf(componentType=rfc3280.Attribute()))
292
+ )
293
+
294
+ id_aca_group = _buildOid(id_aca, 4)
295
+
296
+ id_pe_ac_proxying = _buildOid(rfc3280.id_pe, 10)
297
+
298
+
299
+ class SvceAuthInfo(univ.Sequence):
300
+ pass
301
+
302
+
303
+ SvceAuthInfo.componentType = namedtype.NamedTypes(
304
+ namedtype.NamedType('service', rfc3280.GeneralName()),
305
+ namedtype.NamedType('ident', rfc3280.GeneralName()),
306
+ namedtype.OptionalNamedType('authInfo', univ.OctetString())
307
+ )
308
+
309
+
310
+ class IetfAttrSyntax(univ.Sequence):
311
+ pass
312
+
313
+
314
+ IetfAttrSyntax.componentType = namedtype.NamedTypes(
315
+ namedtype.OptionalNamedType(
316
+ 'policyAuthority', rfc3280.GeneralNames().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0))
317
+ ),
318
+ namedtype.NamedType(
319
+ 'values', univ.SequenceOf(
320
+ componentType=univ.Choice(
321
+ componentType=namedtype.NamedTypes(
322
+ namedtype.NamedType('octets', univ.OctetString()),
323
+ namedtype.NamedType('oid', univ.ObjectIdentifier()),
324
+ namedtype.NamedType('string', char.UTF8String())
325
+ )
326
+ )
327
+ )
328
+ )
329
+ )
330
+
331
+ id_aca_encAttrs = _buildOid(id_aca, 6)
my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/pyasn1_modules/rfc3779.py ADDED
@@ -0,0 +1,137 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #
2
+ # This file is part of pyasn1-modules software.
3
+ #
4
+ # Created by Russ Housley with assistance from asn1ate v.0.6.0.
5
+ # Modified by Russ Housley to add maps for use with opentypes.
6
+ #
7
+ # Copyright (c) 2019, Vigil Security, LLC
8
+ # License: http://snmplabs.com/pyasn1/license.html
9
+ #
10
+ # X.509 Extensions for IP Addresses and AS Identifiers
11
+ #
12
+ # ASN.1 source from:
13
+ # https://www.rfc-editor.org/rfc/rfc3779.txt
14
+ #
15
+
16
+ from pyasn1.type import constraint
17
+ from pyasn1.type import namedtype
18
+ from pyasn1.type import tag
19
+ from pyasn1.type import univ
20
+
21
+ from pyasn1_modules import rfc5280
22
+
23
+
24
+ # IP Address Delegation Extension
25
+
26
+ id_pe_ipAddrBlocks = univ.ObjectIdentifier('1.3.6.1.5.5.7.1.7')
27
+
28
+
29
+ class IPAddress(univ.BitString):
30
+ pass
31
+
32
+
33
+ class IPAddressRange(univ.Sequence):
34
+ pass
35
+
36
+ IPAddressRange.componentType = namedtype.NamedTypes(
37
+ namedtype.NamedType('min', IPAddress()),
38
+ namedtype.NamedType('max', IPAddress())
39
+ )
40
+
41
+
42
+ class IPAddressOrRange(univ.Choice):
43
+ pass
44
+
45
+ IPAddressOrRange.componentType = namedtype.NamedTypes(
46
+ namedtype.NamedType('addressPrefix', IPAddress()),
47
+ namedtype.NamedType('addressRange', IPAddressRange())
48
+ )
49
+
50
+
51
+ class IPAddressChoice(univ.Choice):
52
+ pass
53
+
54
+ IPAddressChoice.componentType = namedtype.NamedTypes(
55
+ namedtype.NamedType('inherit', univ.Null()),
56
+ namedtype.NamedType('addressesOrRanges', univ.SequenceOf(
57
+ componentType=IPAddressOrRange())
58
+ )
59
+ )
60
+
61
+
62
+ class IPAddressFamily(univ.Sequence):
63
+ pass
64
+
65
+ IPAddressFamily.componentType = namedtype.NamedTypes(
66
+ namedtype.NamedType('addressFamily', univ.OctetString().subtype(
67
+ subtypeSpec=constraint.ValueSizeConstraint(2, 3))),
68
+ namedtype.NamedType('ipAddressChoice', IPAddressChoice())
69
+ )
70
+
71
+
72
+ class IPAddrBlocks(univ.SequenceOf):
73
+ pass
74
+
75
+ IPAddrBlocks.componentType = IPAddressFamily()
76
+
77
+
78
+ # Autonomous System Identifier Delegation Extension
79
+
80
+ id_pe_autonomousSysIds = univ.ObjectIdentifier('1.3.6.1.5.5.7.1.8')
81
+
82
+
83
+ class ASId(univ.Integer):
84
+ pass
85
+
86
+
87
+ class ASRange(univ.Sequence):
88
+ pass
89
+
90
+ ASRange.componentType = namedtype.NamedTypes(
91
+ namedtype.NamedType('min', ASId()),
92
+ namedtype.NamedType('max', ASId())
93
+ )
94
+
95
+
96
+ class ASIdOrRange(univ.Choice):
97
+ pass
98
+
99
+ ASIdOrRange.componentType = namedtype.NamedTypes(
100
+ namedtype.NamedType('id', ASId()),
101
+ namedtype.NamedType('range', ASRange())
102
+ )
103
+
104
+
105
+ class ASIdentifierChoice(univ.Choice):
106
+ pass
107
+
108
+ ASIdentifierChoice.componentType = namedtype.NamedTypes(
109
+ namedtype.NamedType('inherit', univ.Null()),
110
+ namedtype.NamedType('asIdsOrRanges', univ.SequenceOf(
111
+ componentType=ASIdOrRange())
112
+ )
113
+ )
114
+
115
+
116
+ class ASIdentifiers(univ.Sequence):
117
+ pass
118
+
119
+ ASIdentifiers.componentType = namedtype.NamedTypes(
120
+ namedtype.OptionalNamedType('asnum', ASIdentifierChoice().subtype(
121
+ explicitTag=tag.Tag(tag.tagClassContext,
122
+ tag.tagFormatConstructed, 0))),
123
+ namedtype.OptionalNamedType('rdi', ASIdentifierChoice().subtype(
124
+ explicitTag=tag.Tag(tag.tagClassContext,
125
+ tag.tagFormatConstructed, 1)))
126
+ )
127
+
128
+
129
+ # Map of Certificate Extension OIDs to Extensions is added to the
130
+ # ones that are in rfc5280.py
131
+
132
+ _certificateExtensionsMapUpdate = {
133
+ id_pe_ipAddrBlocks: IPAddrBlocks(),
134
+ id_pe_autonomousSysIds: ASIdentifiers(),
135
+ }
136
+
137
+ rfc5280.certificateExtensionsMap.update(_certificateExtensionsMapUpdate)
my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/pyasn1_modules/rfc5917.py ADDED
@@ -0,0 +1,55 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #
2
+ # This file is part of pyasn1-modules software.
3
+ #
4
+ # Created by Russ Housley.
5
+ #
6
+ # Copyright (c) 2019, Vigil Security, LLC
7
+ # License: http://snmplabs.com/pyasn1/license.html
8
+ #
9
+ # Clearance Sponsor Attribute
10
+ #
11
+ # ASN.1 source from:
12
+ # https://www.rfc-editor.org/rfc/rfc5917.txt
13
+ # https://www.rfc-editor.org/errata/eid4558
14
+ # https://www.rfc-editor.org/errata/eid5883
15
+ #
16
+
17
+ from pyasn1.type import char
18
+ from pyasn1.type import constraint
19
+ from pyasn1.type import namedtype
20
+ from pyasn1.type import univ
21
+
22
+ from pyasn1_modules import rfc5280
23
+
24
+
25
+ # DirectoryString is the same as RFC 5280, except for two things:
26
+ # 1. the length is limited to 64;
27
+ # 2. only the 'utf8String' choice remains because the ASN.1
28
+ # specification says: ( WITH COMPONENTS { utf8String PRESENT } )
29
+
30
+ class DirectoryString(univ.Choice):
31
+ componentType = namedtype.NamedTypes(
32
+ namedtype.NamedType('utf8String', char.UTF8String().subtype(
33
+ subtypeSpec=constraint.ValueSizeConstraint(1, 64))),
34
+ )
35
+
36
+
37
+ # Clearance Sponsor Attribute
38
+
39
+ id_clearanceSponsor = univ.ObjectIdentifier((2, 16, 840, 1, 101, 2, 1, 5, 68))
40
+
41
+ ub_clearance_sponsor = univ.Integer(64)
42
+
43
+
44
+ at_clearanceSponsor = rfc5280.Attribute()
45
+ at_clearanceSponsor['type'] = id_clearanceSponsor
46
+ at_clearanceSponsor['values'][0] = DirectoryString()
47
+
48
+
49
+ # Add to the map of Attribute Type OIDs to Attributes in rfc5280.py.
50
+
51
+ _certificateAttributesMapUpdate = {
52
+ id_clearanceSponsor: DirectoryString(),
53
+ }
54
+
55
+ rfc5280.certificateAttributesMap.update(_certificateAttributesMapUpdate)
my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/pyasn1_modules/rfc5934.py ADDED
@@ -0,0 +1,786 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # This file is being contributed to pyasn1-modules software.
2
+ #
3
+ # Created by Russ Housley with assistance from asn1ate v.0.6.0.
4
+ #
5
+ # Copyright (c) 2019, Vigil Security, LLC
6
+ # License: http://snmplabs.com/pyasn1/license.html
7
+ #
8
+ # Trust Anchor Format
9
+ #
10
+ # ASN.1 source from:
11
+ # https://www.rfc-editor.org/rfc/rfc5934.txt
12
+
13
+ from pyasn1.type import univ, char, namedtype, namedval, tag, constraint, useful
14
+
15
+ from pyasn1_modules import rfc2985
16
+ from pyasn1_modules import rfc5280
17
+ from pyasn1_modules import rfc5652
18
+ from pyasn1_modules import rfc5914
19
+
20
+ MAX = float('inf')
21
+
22
+
23
+ def _OID(*components):
24
+ output = []
25
+ for x in tuple(components):
26
+ if isinstance(x, univ.ObjectIdentifier):
27
+ output.extend(list(x))
28
+ else:
29
+ output.append(int(x))
30
+ return univ.ObjectIdentifier(output)
31
+
32
+
33
+ # Imports from RFC 2985
34
+
35
+ SingleAttribute = rfc2985.SingleAttribute
36
+
37
+
38
+ # Imports from RFC5914
39
+
40
+ CertPathControls = rfc5914.CertPathControls
41
+
42
+ TrustAnchorChoice = rfc5914.TrustAnchorChoice
43
+
44
+ TrustAnchorTitle = rfc5914.TrustAnchorTitle
45
+
46
+
47
+ # Imports from RFC 5280
48
+
49
+ AlgorithmIdentifier = rfc5280.AlgorithmIdentifier
50
+
51
+ AnotherName = rfc5280.AnotherName
52
+
53
+ Attribute = rfc5280.Attribute
54
+
55
+ Certificate = rfc5280.Certificate
56
+
57
+ CertificateSerialNumber = rfc5280.CertificateSerialNumber
58
+
59
+ Extension = rfc5280.Extension
60
+
61
+ Extensions = rfc5280.Extensions
62
+
63
+ KeyIdentifier = rfc5280.KeyIdentifier
64
+
65
+ Name = rfc5280.Name
66
+
67
+ SubjectPublicKeyInfo = rfc5280.SubjectPublicKeyInfo
68
+
69
+ TBSCertificate = rfc5280.TBSCertificate
70
+
71
+ Validity = rfc5280.Validity
72
+
73
+
74
+ # Object Identifier Arc for TAMP Message Content Types
75
+
76
+ id_tamp = univ.ObjectIdentifier('2.16.840.1.101.2.1.2.77')
77
+
78
+
79
+ # TAMP Status Query Message
80
+
81
+ id_ct_TAMP_statusQuery = _OID(id_tamp, 1)
82
+
83
+
84
+ class TAMPVersion(univ.Integer):
85
+ pass
86
+
87
+ TAMPVersion.namedValues = namedval.NamedValues(
88
+ ('v1', 1),
89
+ ('v2', 2)
90
+ )
91
+
92
+
93
+ class TerseOrVerbose(univ.Enumerated):
94
+ pass
95
+
96
+ TerseOrVerbose.namedValues = namedval.NamedValues(
97
+ ('terse', 1),
98
+ ('verbose', 2)
99
+ )
100
+
101
+
102
+ class HardwareSerialEntry(univ.Choice):
103
+ pass
104
+
105
+ HardwareSerialEntry.componentType = namedtype.NamedTypes(
106
+ namedtype.NamedType('all', univ.Null()),
107
+ namedtype.NamedType('single', univ.OctetString()),
108
+ namedtype.NamedType('block', univ.Sequence(componentType=namedtype.NamedTypes(
109
+ namedtype.NamedType('low', univ.OctetString()),
110
+ namedtype.NamedType('high', univ.OctetString())
111
+ ))
112
+ )
113
+ )
114
+
115
+
116
+ class HardwareModules(univ.Sequence):
117
+ pass
118
+
119
+ HardwareModules.componentType = namedtype.NamedTypes(
120
+ namedtype.NamedType('hwType', univ.ObjectIdentifier()),
121
+ namedtype.NamedType('hwSerialEntries', univ.SequenceOf(
122
+ componentType=HardwareSerialEntry()).subtype(
123
+ subtypeSpec=constraint.ValueSizeConstraint(1, MAX)))
124
+ )
125
+
126
+
127
+ class HardwareModuleIdentifierList(univ.SequenceOf):
128
+ pass
129
+
130
+ HardwareModuleIdentifierList.componentType = HardwareModules()
131
+ HardwareModuleIdentifierList.subtypeSpec=constraint.ValueSizeConstraint(1, MAX)
132
+
133
+
134
+ class Community(univ.ObjectIdentifier):
135
+ pass
136
+
137
+
138
+ class CommunityIdentifierList(univ.SequenceOf):
139
+ pass
140
+
141
+ CommunityIdentifierList.componentType = Community()
142
+ CommunityIdentifierList.subtypeSpec=constraint.ValueSizeConstraint(0, MAX)
143
+
144
+
145
+ class TargetIdentifier(univ.Choice):
146
+ pass
147
+
148
+ TargetIdentifier.componentType = namedtype.NamedTypes(
149
+ namedtype.NamedType('hwModules', HardwareModuleIdentifierList().subtype(
150
+ implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 1))),
151
+ namedtype.NamedType('communities', CommunityIdentifierList().subtype(
152
+ implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 2))),
153
+ namedtype.NamedType('allModules', univ.Null().subtype(
154
+ implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 3))),
155
+ namedtype.NamedType('uri', char.IA5String().subtype(
156
+ implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 4))),
157
+ namedtype.NamedType('otherName', AnotherName().subtype(
158
+ implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 5)))
159
+ )
160
+
161
+
162
+ class SeqNumber(univ.Integer):
163
+ pass
164
+
165
+ SeqNumber.subtypeSpec = constraint.ValueRangeConstraint(0, 9223372036854775807)
166
+
167
+
168
+ class TAMPMsgRef(univ.Sequence):
169
+ pass
170
+
171
+ TAMPMsgRef.componentType = namedtype.NamedTypes(
172
+ namedtype.NamedType('target', TargetIdentifier()),
173
+ namedtype.NamedType('seqNum', SeqNumber())
174
+ )
175
+
176
+
177
+ class TAMPStatusQuery(univ.Sequence):
178
+ pass
179
+
180
+ TAMPStatusQuery.componentType = namedtype.NamedTypes(
181
+ namedtype.DefaultedNamedType('version', TAMPVersion().subtype(
182
+ implicitTag=tag.Tag(tag.tagClassContext,
183
+ tag.tagFormatSimple, 0)).subtype(value='v2')),
184
+ namedtype.DefaultedNamedType('terse', TerseOrVerbose().subtype(
185
+ implicitTag=tag.Tag(tag.tagClassContext,
186
+ tag.tagFormatSimple, 1)).subtype(value='verbose')),
187
+ namedtype.NamedType('query', TAMPMsgRef())
188
+ )
189
+
190
+
191
+ tamp_status_query = rfc5652.ContentInfo()
192
+ tamp_status_query['contentType'] = id_ct_TAMP_statusQuery
193
+ tamp_status_query['content'] = TAMPStatusQuery()
194
+
195
+
196
+ # TAMP Status Response Message
197
+
198
+ id_ct_TAMP_statusResponse = _OID(id_tamp, 2)
199
+
200
+
201
+ class KeyIdentifiers(univ.SequenceOf):
202
+ pass
203
+
204
+ KeyIdentifiers.componentType = KeyIdentifier()
205
+ KeyIdentifiers.subtypeSpec=constraint.ValueSizeConstraint(1, MAX)
206
+
207
+
208
+ class TrustAnchorChoiceList(univ.SequenceOf):
209
+ pass
210
+
211
+ TrustAnchorChoiceList.componentType = TrustAnchorChoice()
212
+ TrustAnchorChoiceList.subtypeSpec=constraint.ValueSizeConstraint(1, MAX)
213
+
214
+
215
+ class TAMPSequenceNumber(univ.Sequence):
216
+ pass
217
+
218
+ TAMPSequenceNumber.componentType = namedtype.NamedTypes(
219
+ namedtype.NamedType('keyId', KeyIdentifier()),
220
+ namedtype.NamedType('seqNumber', SeqNumber())
221
+ )
222
+
223
+
224
+ class TAMPSequenceNumbers(univ.SequenceOf):
225
+ pass
226
+
227
+ TAMPSequenceNumbers.componentType = TAMPSequenceNumber()
228
+ TAMPSequenceNumbers.subtypeSpec=constraint.ValueSizeConstraint(1, MAX)
229
+
230
+
231
+ class TerseStatusResponse(univ.Sequence):
232
+ pass
233
+
234
+ TerseStatusResponse.componentType = namedtype.NamedTypes(
235
+ namedtype.NamedType('taKeyIds', KeyIdentifiers()),
236
+ namedtype.OptionalNamedType('communities', CommunityIdentifierList())
237
+ )
238
+
239
+
240
+ class VerboseStatusResponse(univ.Sequence):
241
+ pass
242
+
243
+ VerboseStatusResponse.componentType = namedtype.NamedTypes(
244
+ namedtype.NamedType('taInfo', TrustAnchorChoiceList()),
245
+ namedtype.OptionalNamedType('continPubKeyDecryptAlg',
246
+ AlgorithmIdentifier().subtype(implicitTag=tag.Tag(
247
+ tag.tagClassContext, tag.tagFormatSimple, 0))),
248
+ namedtype.OptionalNamedType('communities',
249
+ CommunityIdentifierList().subtype(implicitTag=tag.Tag(
250
+ tag.tagClassContext, tag.tagFormatSimple, 1))),
251
+ namedtype.OptionalNamedType('tampSeqNumbers',
252
+ TAMPSequenceNumbers().subtype(implicitTag=tag.Tag(
253
+ tag.tagClassContext, tag.tagFormatSimple, 2)))
254
+ )
255
+
256
+
257
+ class StatusResponse(univ.Choice):
258
+ pass
259
+
260
+ StatusResponse.componentType = namedtype.NamedTypes(
261
+ namedtype.NamedType('terseResponse', TerseStatusResponse().subtype(
262
+ implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 0))),
263
+ namedtype.NamedType('verboseResponse', VerboseStatusResponse().subtype(
264
+ implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 1)))
265
+ )
266
+
267
+
268
+ class TAMPStatusResponse(univ.Sequence):
269
+ pass
270
+
271
+ TAMPStatusResponse.componentType = namedtype.NamedTypes(
272
+ namedtype.DefaultedNamedType('version', TAMPVersion().subtype(
273
+ implicitTag=tag.Tag(tag.tagClassContext,
274
+ tag.tagFormatSimple, 0)).subtype(value='v2')),
275
+ namedtype.NamedType('query', TAMPMsgRef()),
276
+ namedtype.NamedType('response', StatusResponse()),
277
+ namedtype.DefaultedNamedType('usesApex', univ.Boolean().subtype(value=1))
278
+ )
279
+
280
+
281
+ tamp_status_response = rfc5652.ContentInfo()
282
+ tamp_status_response['contentType'] = id_ct_TAMP_statusResponse
283
+ tamp_status_response['content'] = TAMPStatusResponse()
284
+
285
+
286
+ # Trust Anchor Update Message
287
+
288
+ id_ct_TAMP_update = _OID(id_tamp, 3)
289
+
290
+
291
+ class TBSCertificateChangeInfo(univ.Sequence):
292
+ pass
293
+
294
+ TBSCertificateChangeInfo.componentType = namedtype.NamedTypes(
295
+ namedtype.OptionalNamedType('serialNumber', CertificateSerialNumber()),
296
+ namedtype.OptionalNamedType('signature', AlgorithmIdentifier().subtype(
297
+ implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0))),
298
+ namedtype.OptionalNamedType('issuer', Name().subtype(implicitTag=tag.Tag(
299
+ tag.tagClassContext, tag.tagFormatSimple, 1))),
300
+ namedtype.OptionalNamedType('validity', Validity().subtype(
301
+ implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 2))),
302
+ namedtype.OptionalNamedType('subject', Name().subtype(implicitTag=tag.Tag(
303
+ tag.tagClassContext, tag.tagFormatSimple, 3))),
304
+ namedtype.NamedType('subjectPublicKeyInfo', SubjectPublicKeyInfo().subtype(
305
+ implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 4))),
306
+ namedtype.OptionalNamedType('exts', Extensions().subtype(explicitTag=tag.Tag(
307
+ tag.tagClassContext, tag.tagFormatSimple, 5)))
308
+ )
309
+
310
+
311
+ class TrustAnchorChangeInfo(univ.Sequence):
312
+ pass
313
+
314
+ TrustAnchorChangeInfo.componentType = namedtype.NamedTypes(
315
+ namedtype.NamedType('pubKey', SubjectPublicKeyInfo()),
316
+ namedtype.OptionalNamedType('keyId', KeyIdentifier()),
317
+ namedtype.OptionalNamedType('taTitle', TrustAnchorTitle()),
318
+ namedtype.OptionalNamedType('certPath', CertPathControls()),
319
+ namedtype.OptionalNamedType('exts', Extensions().subtype(
320
+ implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 1)))
321
+ )
322
+
323
+
324
+ class TrustAnchorChangeInfoChoice(univ.Choice):
325
+ pass
326
+
327
+ TrustAnchorChangeInfoChoice.componentType = namedtype.NamedTypes(
328
+ namedtype.NamedType('tbsCertChange', TBSCertificateChangeInfo().subtype(
329
+ implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 0))),
330
+ namedtype.NamedType('taChange', TrustAnchorChangeInfo().subtype(
331
+ implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 1)))
332
+ )
333
+
334
+
335
+ class TrustAnchorUpdate(univ.Choice):
336
+ pass
337
+
338
+ TrustAnchorUpdate.componentType = namedtype.NamedTypes(
339
+ namedtype.NamedType('add', TrustAnchorChoice().subtype(
340
+ implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 1))),
341
+ namedtype.NamedType('remove', SubjectPublicKeyInfo().subtype(
342
+ implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 2))),
343
+ namedtype.NamedType('change', TrustAnchorChangeInfoChoice().subtype(
344
+ explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 3)))
345
+ )
346
+
347
+
348
+ class TAMPUpdate(univ.Sequence):
349
+ pass
350
+
351
+ TAMPUpdate.componentType = namedtype.NamedTypes(
352
+ namedtype.DefaultedNamedType('version',
353
+ TAMPVersion().subtype(implicitTag=tag.Tag(tag.tagClassContext,
354
+ tag.tagFormatSimple, 0)).subtype(value='v2')),
355
+ namedtype.DefaultedNamedType('terse',
356
+ TerseOrVerbose().subtype(implicitTag=tag.Tag(tag.tagClassContext,
357
+ tag.tagFormatSimple, 1)).subtype(value='verbose')),
358
+ namedtype.NamedType('msgRef', TAMPMsgRef()),
359
+ namedtype.NamedType('updates',
360
+ univ.SequenceOf(componentType=TrustAnchorUpdate()).subtype(
361
+ subtypeSpec=constraint.ValueSizeConstraint(1, MAX))),
362
+ namedtype.OptionalNamedType('tampSeqNumbers',
363
+ TAMPSequenceNumbers().subtype(implicitTag=tag.Tag(
364
+ tag.tagClassContext, tag.tagFormatSimple, 2)))
365
+ )
366
+
367
+
368
+ tamp_update = rfc5652.ContentInfo()
369
+ tamp_update['contentType'] = id_ct_TAMP_update
370
+ tamp_update['content'] = TAMPUpdate()
371
+
372
+
373
+ # Trust Anchor Update Confirm Message
374
+
375
+ id_ct_TAMP_updateConfirm = _OID(id_tamp, 4)
376
+
377
+
378
+ class StatusCode(univ.Enumerated):
379
+ pass
380
+
381
+ StatusCode.namedValues = namedval.NamedValues(
382
+ ('success', 0),
383
+ ('decodeFailure', 1),
384
+ ('badContentInfo', 2),
385
+ ('badSignedData', 3),
386
+ ('badEncapContent', 4),
387
+ ('badCertificate', 5),
388
+ ('badSignerInfo', 6),
389
+ ('badSignedAttrs', 7),
390
+ ('badUnsignedAttrs', 8),
391
+ ('missingContent', 9),
392
+ ('noTrustAnchor', 10),
393
+ ('notAuthorized', 11),
394
+ ('badDigestAlgorithm', 12),
395
+ ('badSignatureAlgorithm', 13),
396
+ ('unsupportedKeySize', 14),
397
+ ('unsupportedParameters', 15),
398
+ ('signatureFailure', 16),
399
+ ('insufficientMemory', 17),
400
+ ('unsupportedTAMPMsgType', 18),
401
+ ('apexTAMPAnchor', 19),
402
+ ('improperTAAddition', 20),
403
+ ('seqNumFailure', 21),
404
+ ('contingencyPublicKeyDecrypt', 22),
405
+ ('incorrectTarget', 23),
406
+ ('communityUpdateFailed', 24),
407
+ ('trustAnchorNotFound', 25),
408
+ ('unsupportedTAAlgorithm', 26),
409
+ ('unsupportedTAKeySize', 27),
410
+ ('unsupportedContinPubKeyDecryptAlg', 28),
411
+ ('missingSignature', 29),
412
+ ('resourcesBusy', 30),
413
+ ('versionNumberMismatch', 31),
414
+ ('missingPolicySet', 32),
415
+ ('revokedCertificate', 33),
416
+ ('unsupportedTrustAnchorFormat', 34),
417
+ ('improperTAChange', 35),
418
+ ('malformed', 36),
419
+ ('cmsError', 37),
420
+ ('unsupportedTargetIdentifier', 38),
421
+ ('other', 127)
422
+ )
423
+
424
+
425
+ class StatusCodeList(univ.SequenceOf):
426
+ pass
427
+
428
+ StatusCodeList.componentType = StatusCode()
429
+ StatusCodeList.subtypeSpec=constraint.ValueSizeConstraint(1, MAX)
430
+
431
+
432
+ class TerseUpdateConfirm(StatusCodeList):
433
+ pass
434
+
435
+
436
+ class VerboseUpdateConfirm(univ.Sequence):
437
+ pass
438
+
439
+ VerboseUpdateConfirm.componentType = namedtype.NamedTypes(
440
+ namedtype.NamedType('status', StatusCodeList()),
441
+ namedtype.NamedType('taInfo', TrustAnchorChoiceList()),
442
+ namedtype.OptionalNamedType('tampSeqNumbers', TAMPSequenceNumbers()),
443
+ namedtype.DefaultedNamedType('usesApex', univ.Boolean().subtype(value=1))
444
+ )
445
+
446
+
447
+ class UpdateConfirm(univ.Choice):
448
+ pass
449
+
450
+ UpdateConfirm.componentType = namedtype.NamedTypes(
451
+ namedtype.NamedType('terseConfirm', TerseUpdateConfirm().subtype(
452
+ implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0))),
453
+ namedtype.NamedType('verboseConfirm', VerboseUpdateConfirm().subtype(
454
+ implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 1)))
455
+ )
456
+
457
+
458
+ class TAMPUpdateConfirm(univ.Sequence):
459
+ pass
460
+
461
+ TAMPUpdateConfirm.componentType = namedtype.NamedTypes(
462
+ namedtype.DefaultedNamedType('version', TAMPVersion().subtype(
463
+ implicitTag=tag.Tag(tag.tagClassContext,
464
+ tag.tagFormatSimple, 0)).subtype(value='v2')),
465
+ namedtype.NamedType('update', TAMPMsgRef()),
466
+ namedtype.NamedType('confirm', UpdateConfirm())
467
+ )
468
+
469
+
470
+ tamp_update_confirm = rfc5652.ContentInfo()
471
+ tamp_update_confirm['contentType'] = id_ct_TAMP_updateConfirm
472
+ tamp_update_confirm['content'] = TAMPUpdateConfirm()
473
+
474
+
475
+ # Apex Trust Anchor Update Message
476
+
477
+ id_ct_TAMP_apexUpdate = _OID(id_tamp, 5)
478
+
479
+
480
+ class TAMPApexUpdate(univ.Sequence):
481
+ pass
482
+
483
+ TAMPApexUpdate.componentType = namedtype.NamedTypes(
484
+ namedtype.DefaultedNamedType('version',
485
+ TAMPVersion().subtype(implicitTag=tag.Tag(tag.tagClassContext,
486
+ tag.tagFormatSimple, 0)).subtype(value='v2')),
487
+ namedtype.DefaultedNamedType('terse',
488
+ TerseOrVerbose().subtype(implicitTag=tag.Tag(tag.tagClassContext,
489
+ tag.tagFormatSimple, 1)).subtype(value='verbose')),
490
+ namedtype.NamedType('msgRef', TAMPMsgRef()),
491
+ namedtype.NamedType('clearTrustAnchors', univ.Boolean()),
492
+ namedtype.NamedType('clearCommunities', univ.Boolean()),
493
+ namedtype.OptionalNamedType('seqNumber', SeqNumber()),
494
+ namedtype.NamedType('apexTA', TrustAnchorChoice())
495
+ )
496
+
497
+
498
+ tamp_apex_update = rfc5652.ContentInfo()
499
+ tamp_apex_update['contentType'] = id_ct_TAMP_apexUpdate
500
+ tamp_apex_update['content'] = TAMPApexUpdate()
501
+
502
+
503
+ # Apex Trust Anchor Update Confirm Message
504
+
505
+ id_ct_TAMP_apexUpdateConfirm = _OID(id_tamp, 6)
506
+
507
+
508
+ class TerseApexUpdateConfirm(StatusCode):
509
+ pass
510
+
511
+
512
+ class VerboseApexUpdateConfirm(univ.Sequence):
513
+ pass
514
+
515
+ VerboseApexUpdateConfirm.componentType = namedtype.NamedTypes(
516
+ namedtype.NamedType('status', StatusCode()),
517
+ namedtype.NamedType('taInfo', TrustAnchorChoiceList()),
518
+ namedtype.OptionalNamedType('communities',
519
+ CommunityIdentifierList().subtype(implicitTag=tag.Tag(tag.tagClassContext,
520
+ tag.tagFormatSimple, 0))),
521
+ namedtype.OptionalNamedType('tampSeqNumbers',
522
+ TAMPSequenceNumbers().subtype(implicitTag=tag.Tag(tag.tagClassContext,
523
+ tag.tagFormatSimple, 1)))
524
+ )
525
+
526
+
527
+ class ApexUpdateConfirm(univ.Choice):
528
+ pass
529
+
530
+ ApexUpdateConfirm.componentType = namedtype.NamedTypes(
531
+ namedtype.NamedType('terseApexConfirm',
532
+ TerseApexUpdateConfirm().subtype(implicitTag=tag.Tag(tag.tagClassContext,
533
+ tag.tagFormatSimple, 0))),
534
+ namedtype.NamedType('verboseApexConfirm',
535
+ VerboseApexUpdateConfirm().subtype(implicitTag=tag.Tag(tag.tagClassContext,
536
+ tag.tagFormatConstructed, 1)))
537
+ )
538
+
539
+
540
+ class TAMPApexUpdateConfirm(univ.Sequence):
541
+ pass
542
+
543
+ TAMPApexUpdateConfirm.componentType = namedtype.NamedTypes(
544
+ namedtype.DefaultedNamedType('version',
545
+ TAMPVersion().subtype(implicitTag=tag.Tag(tag.tagClassContext,
546
+ tag.tagFormatSimple, 0)).subtype(value='v2')),
547
+ namedtype.NamedType('apexReplace', TAMPMsgRef()),
548
+ namedtype.NamedType('apexConfirm', ApexUpdateConfirm())
549
+ )
550
+
551
+
552
+ tamp_apex_update_confirm = rfc5652.ContentInfo()
553
+ tamp_apex_update_confirm['contentType'] = id_ct_TAMP_apexUpdateConfirm
554
+ tamp_apex_update_confirm['content'] = TAMPApexUpdateConfirm()
555
+
556
+
557
+ # Community Update Message
558
+
559
+ id_ct_TAMP_communityUpdate = _OID(id_tamp, 7)
560
+
561
+
562
+ class CommunityUpdates(univ.Sequence):
563
+ pass
564
+
565
+ CommunityUpdates.componentType = namedtype.NamedTypes(
566
+ namedtype.OptionalNamedType('remove',
567
+ CommunityIdentifierList().subtype(implicitTag=tag.Tag(tag.tagClassContext,
568
+ tag.tagFormatSimple, 1))),
569
+ namedtype.OptionalNamedType('add',
570
+ CommunityIdentifierList().subtype(implicitTag=tag.Tag(tag.tagClassContext,
571
+ tag.tagFormatSimple, 2)))
572
+ )
573
+
574
+
575
+ class TAMPCommunityUpdate(univ.Sequence):
576
+ pass
577
+
578
+ TAMPCommunityUpdate.componentType = namedtype.NamedTypes(
579
+ namedtype.DefaultedNamedType('version',
580
+ TAMPVersion().subtype(implicitTag=tag.Tag(tag.tagClassContext,
581
+ tag.tagFormatSimple, 0)).subtype(value='v2')),
582
+ namedtype.DefaultedNamedType('terse',
583
+ TerseOrVerbose().subtype(implicitTag=tag.Tag(tag.tagClassContext,
584
+ tag.tagFormatSimple, 1)).subtype(value='verbose')),
585
+ namedtype.NamedType('msgRef', TAMPMsgRef()),
586
+ namedtype.NamedType('updates', CommunityUpdates())
587
+ )
588
+
589
+
590
+ tamp_community_update = rfc5652.ContentInfo()
591
+ tamp_community_update['contentType'] = id_ct_TAMP_communityUpdate
592
+ tamp_community_update['content'] = TAMPCommunityUpdate()
593
+
594
+
595
+ # Community Update Confirm Message
596
+
597
+ id_ct_TAMP_communityUpdateConfirm = _OID(id_tamp, 8)
598
+
599
+
600
+ class TerseCommunityConfirm(StatusCode):
601
+ pass
602
+
603
+
604
+ class VerboseCommunityConfirm(univ.Sequence):
605
+ pass
606
+
607
+ VerboseCommunityConfirm.componentType = namedtype.NamedTypes(
608
+ namedtype.NamedType('status', StatusCode()),
609
+ namedtype.OptionalNamedType('communities', CommunityIdentifierList())
610
+ )
611
+
612
+
613
+ class CommunityConfirm(univ.Choice):
614
+ pass
615
+
616
+ CommunityConfirm.componentType = namedtype.NamedTypes(
617
+ namedtype.NamedType('terseCommConfirm',
618
+ TerseCommunityConfirm().subtype(implicitTag=tag.Tag(tag.tagClassContext,
619
+ tag.tagFormatSimple, 0))),
620
+ namedtype.NamedType('verboseCommConfirm',
621
+ VerboseCommunityConfirm().subtype(implicitTag=tag.Tag(tag.tagClassContext,
622
+ tag.tagFormatConstructed, 1)))
623
+ )
624
+
625
+
626
+ class TAMPCommunityUpdateConfirm(univ.Sequence):
627
+ pass
628
+
629
+ TAMPCommunityUpdateConfirm.componentType = namedtype.NamedTypes(
630
+ namedtype.DefaultedNamedType('version',
631
+ TAMPVersion().subtype(implicitTag=tag.Tag(tag.tagClassContext,
632
+ tag.tagFormatSimple, 0)).subtype(value='v2')),
633
+ namedtype.NamedType('update', TAMPMsgRef()),
634
+ namedtype.NamedType('commConfirm', CommunityConfirm())
635
+ )
636
+
637
+
638
+ tamp_community_update_confirm = rfc5652.ContentInfo()
639
+ tamp_community_update_confirm['contentType'] = id_ct_TAMP_communityUpdateConfirm
640
+ tamp_community_update_confirm['content'] = TAMPCommunityUpdateConfirm()
641
+
642
+
643
+ # Sequence Number Adjust Message
644
+
645
+ id_ct_TAMP_seqNumAdjust = _OID(id_tamp, 10)
646
+
647
+
648
+
649
+ class SequenceNumberAdjust(univ.Sequence):
650
+ pass
651
+
652
+ SequenceNumberAdjust.componentType = namedtype.NamedTypes(
653
+ namedtype.DefaultedNamedType('version',
654
+ TAMPVersion().subtype(implicitTag=tag.Tag(tag.tagClassContext,
655
+ tag.tagFormatSimple, 0)).subtype(value='v2')),
656
+ namedtype.NamedType('msgRef', TAMPMsgRef())
657
+ )
658
+
659
+
660
+ tamp_sequence_number_adjust = rfc5652.ContentInfo()
661
+ tamp_sequence_number_adjust['contentType'] = id_ct_TAMP_seqNumAdjust
662
+ tamp_sequence_number_adjust['content'] = SequenceNumberAdjust()
663
+
664
+
665
+ # Sequence Number Adjust Confirm Message
666
+
667
+ id_ct_TAMP_seqNumAdjustConfirm = _OID(id_tamp, 11)
668
+
669
+
670
+ class SequenceNumberAdjustConfirm(univ.Sequence):
671
+ pass
672
+
673
+ SequenceNumberAdjustConfirm.componentType = namedtype.NamedTypes(
674
+ namedtype.DefaultedNamedType('version',
675
+ TAMPVersion().subtype(implicitTag=tag.Tag(tag.tagClassContext,
676
+ tag.tagFormatSimple, 0)).subtype(value='v2')),
677
+ namedtype.NamedType('adjust', TAMPMsgRef()),
678
+ namedtype.NamedType('status', StatusCode())
679
+ )
680
+
681
+
682
+ tamp_sequence_number_adjust_confirm = rfc5652.ContentInfo()
683
+ tamp_sequence_number_adjust_confirm['contentType'] = id_ct_TAMP_seqNumAdjustConfirm
684
+ tamp_sequence_number_adjust_confirm['content'] = SequenceNumberAdjustConfirm()
685
+
686
+
687
+ # TAMP Error Message
688
+
689
+ id_ct_TAMP_error = _OID(id_tamp, 9)
690
+
691
+
692
+ class TAMPError(univ.Sequence):
693
+ pass
694
+
695
+ TAMPError.componentType = namedtype.NamedTypes(
696
+ namedtype.DefaultedNamedType('version',
697
+ TAMPVersion().subtype(implicitTag=tag.Tag(tag.tagClassContext,
698
+ tag.tagFormatSimple, 0)).subtype(value='v2')),
699
+ namedtype.NamedType('msgType', univ.ObjectIdentifier()),
700
+ namedtype.NamedType('status', StatusCode()),
701
+ namedtype.OptionalNamedType('msgRef', TAMPMsgRef())
702
+ )
703
+
704
+
705
+ tamp_error = rfc5652.ContentInfo()
706
+ tamp_error['contentType'] = id_ct_TAMP_error
707
+ tamp_error['content'] = TAMPError()
708
+
709
+
710
+ # Object Identifier Arc for Attributes
711
+
712
+ id_attributes = univ.ObjectIdentifier('2.16.840.1.101.2.1.5')
713
+
714
+
715
+ # contingency-public-key-decrypt-key unsigned attribute
716
+
717
+ id_aa_TAMP_contingencyPublicKeyDecryptKey = _OID(id_attributes, 63)
718
+
719
+
720
+ class PlaintextSymmetricKey(univ.OctetString):
721
+ pass
722
+
723
+
724
+ contingency_public_key_decrypt_key = Attribute()
725
+ contingency_public_key_decrypt_key['type'] = id_aa_TAMP_contingencyPublicKeyDecryptKey
726
+ contingency_public_key_decrypt_key['values'][0] = PlaintextSymmetricKey()
727
+
728
+
729
+ # id-pe-wrappedApexContinKey extension
730
+
731
+ id_pe_wrappedApexContinKey =univ.ObjectIdentifier('1.3.6.1.5.5.7.1.20')
732
+
733
+
734
+ class ApexContingencyKey(univ.Sequence):
735
+ pass
736
+
737
+ ApexContingencyKey.componentType = namedtype.NamedTypes(
738
+ namedtype.NamedType('wrapAlgorithm', AlgorithmIdentifier()),
739
+ namedtype.NamedType('wrappedContinPubKey', univ.OctetString())
740
+ )
741
+
742
+
743
+ wrappedApexContinKey = Extension()
744
+ wrappedApexContinKey['extnID'] = id_pe_wrappedApexContinKey
745
+ wrappedApexContinKey['critical'] = 0
746
+ wrappedApexContinKey['extnValue'] = univ.OctetString()
747
+
748
+
749
+ # Add to the map of CMS Content Type OIDs to Content Types in
750
+ # rfc5652.py
751
+
752
+ _cmsContentTypesMapUpdate = {
753
+ id_ct_TAMP_statusQuery: TAMPStatusQuery(),
754
+ id_ct_TAMP_statusResponse: TAMPStatusResponse(),
755
+ id_ct_TAMP_update: TAMPUpdate(),
756
+ id_ct_TAMP_updateConfirm: TAMPUpdateConfirm(),
757
+ id_ct_TAMP_apexUpdate: TAMPApexUpdate(),
758
+ id_ct_TAMP_apexUpdateConfirm: TAMPApexUpdateConfirm(),
759
+ id_ct_TAMP_communityUpdate: TAMPCommunityUpdate(),
760
+ id_ct_TAMP_communityUpdateConfirm: TAMPCommunityUpdateConfirm(),
761
+ id_ct_TAMP_seqNumAdjust: SequenceNumberAdjust(),
762
+ id_ct_TAMP_seqNumAdjustConfirm: SequenceNumberAdjustConfirm(),
763
+ id_ct_TAMP_error: TAMPError(),
764
+ }
765
+
766
+ rfc5652.cmsContentTypesMap.update(_cmsContentTypesMapUpdate)
767
+
768
+
769
+ # Add to the map of CMS Attribute OIDs to Attribute Values in
770
+ # rfc5652.py
771
+
772
+ _cmsAttributesMapUpdate = {
773
+ id_aa_TAMP_contingencyPublicKeyDecryptKey: PlaintextSymmetricKey(),
774
+ }
775
+
776
+ rfc5652.cmsAttributesMap.update(_cmsAttributesMapUpdate)
777
+
778
+
779
+ # Add to the map of Certificate Extension OIDs to Extensions in
780
+ # rfc5280.py
781
+
782
+ _certificateExtensionsMap = {
783
+ id_pe_wrappedApexContinKey: ApexContingencyKey(),
784
+ }
785
+
786
+ rfc5280.certificateExtensionsMap.update(_certificateExtensionsMap)
my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/pyasn1_modules/rfc5940.py ADDED
@@ -0,0 +1,59 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #
2
+ # This file is part of pyasn1-modules software.
3
+ #
4
+ # Created by Russ Housley with assistance from asn1ate v.0.6.0.
5
+ # Modified by Russ Housley to add map for use with opentypes.
6
+ #
7
+ # Copyright (c) 2019, Vigil Security, LLC
8
+ # License: http://snmplabs.com/pyasn1/license.html
9
+ #
10
+ # Additional CMS Revocation Information Choices
11
+ #
12
+ # ASN.1 source from:
13
+ # https://www.rfc-editor.org/rfc/rfc5940.txt
14
+ #
15
+
16
+ from pyasn1.type import namedtype
17
+ from pyasn1.type import tag
18
+ from pyasn1.type import univ
19
+
20
+ from pyasn1_modules import rfc2560
21
+ from pyasn1_modules import rfc5652
22
+
23
+
24
+ # RevocationInfoChoice for OCSP response:
25
+ # The OID is included in otherRevInfoFormat, and
26
+ # signed OCSPResponse is included in otherRevInfo
27
+
28
+ id_ri_ocsp_response = univ.ObjectIdentifier('1.3.6.1.5.5.7.16.2')
29
+
30
+ OCSPResponse = rfc2560.OCSPResponse
31
+
32
+
33
+ # RevocationInfoChoice for SCVP request/response:
34
+ # The OID is included in otherRevInfoFormat, and
35
+ # SCVPReqRes is included in otherRevInfo
36
+
37
+ id_ri_scvp = univ.ObjectIdentifier('1.3.6.1.5.5.7.16.4')
38
+
39
+ ContentInfo = rfc5652.ContentInfo
40
+
41
+ class SCVPReqRes(univ.Sequence):
42
+ pass
43
+
44
+ SCVPReqRes.componentType = namedtype.NamedTypes(
45
+ namedtype.OptionalNamedType('request',
46
+ ContentInfo().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0))),
47
+ namedtype.NamedType('response', ContentInfo())
48
+ )
49
+
50
+
51
+ # Map of Revocation Info Format OIDs to Revocation Info Format
52
+ # is added to the ones that are in rfc5652.py
53
+
54
+ _otherRevInfoFormatMapUpdate = {
55
+ id_ri_ocsp_response: OCSPResponse(),
56
+ id_ri_scvp: SCVPReqRes(),
57
+ }
58
+
59
+ rfc5652.otherRevInfoFormatMap.update(_otherRevInfoFormatMapUpdate)
my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/pyasn1_modules/rfc6031.py ADDED
@@ -0,0 +1,469 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #
2
+ # This file is part of pyasn1-modules software.
3
+ #
4
+ # Created by Russ Housley with assistance from asn1ate v.0.6.0.
5
+ #
6
+ # Copyright (c) 2019, Vigil Security, LLC
7
+ # License: http://snmplabs.com/pyasn1/license.html
8
+ #
9
+ # CMS Symmetric Key Package Content Type
10
+ #
11
+ # ASN.1 source from:
12
+ # https://www.rfc-editor.org/rfc/rfc6031.txt
13
+ #
14
+
15
+ from pyasn1.type import char
16
+ from pyasn1.type import constraint
17
+ from pyasn1.type import namedtype
18
+ from pyasn1.type import namedval
19
+ from pyasn1.type import opentype
20
+ from pyasn1.type import tag
21
+ from pyasn1.type import univ
22
+ from pyasn1.type import useful
23
+
24
+ from pyasn1_modules import rfc5652
25
+ from pyasn1_modules import rfc6019
26
+
27
+
28
+ def _OID(*components):
29
+ output = []
30
+ for x in tuple(components):
31
+ if isinstance(x, univ.ObjectIdentifier):
32
+ output.extend(list(x))
33
+ else:
34
+ output.append(int(x))
35
+ return univ.ObjectIdentifier(output)
36
+
37
+
38
+ MAX = float('inf')
39
+
40
+ id_pskc = univ.ObjectIdentifier('1.2.840.113549.1.9.16.12')
41
+
42
+
43
+ # Symmetric Key Package Attributes
44
+
45
+ id_pskc_manufacturer = _OID(id_pskc, 1)
46
+
47
+ class at_pskc_manufacturer(char.UTF8String):
48
+ pass
49
+
50
+
51
+ id_pskc_serialNo = _OID(id_pskc, 2)
52
+
53
+ class at_pskc_serialNo(char.UTF8String):
54
+ pass
55
+
56
+
57
+ id_pskc_model = _OID(id_pskc, 3)
58
+
59
+ class at_pskc_model(char.UTF8String):
60
+ pass
61
+
62
+
63
+ id_pskc_issueNo = _OID(id_pskc, 4)
64
+
65
+ class at_pskc_issueNo(char.UTF8String):
66
+ pass
67
+
68
+
69
+ id_pskc_deviceBinding = _OID(id_pskc, 5)
70
+
71
+ class at_pskc_deviceBinding(char.UTF8String):
72
+ pass
73
+
74
+
75
+ id_pskc_deviceStartDate = _OID(id_pskc, 6)
76
+
77
+ class at_pskc_deviceStartDate(useful.GeneralizedTime):
78
+ pass
79
+
80
+
81
+ id_pskc_deviceExpiryDate = _OID(id_pskc, 7)
82
+
83
+ class at_pskc_deviceExpiryDate(useful.GeneralizedTime):
84
+ pass
85
+
86
+
87
+ id_pskc_moduleId = _OID(id_pskc, 8)
88
+
89
+ class at_pskc_moduleId(char.UTF8String):
90
+ pass
91
+
92
+
93
+ id_pskc_deviceUserId = _OID(id_pskc, 26)
94
+
95
+ class at_pskc_deviceUserId(char.UTF8String):
96
+ pass
97
+
98
+
99
+ # Symmetric Key Attributes
100
+
101
+ id_pskc_keyId = _OID(id_pskc, 9)
102
+
103
+ class at_pskc_keyUserId(char.UTF8String):
104
+ pass
105
+
106
+
107
+ id_pskc_algorithm = _OID(id_pskc, 10)
108
+
109
+ class at_pskc_algorithm(char.UTF8String):
110
+ pass
111
+
112
+
113
+ id_pskc_issuer = _OID(id_pskc, 11)
114
+
115
+ class at_pskc_issuer(char.UTF8String):
116
+ pass
117
+
118
+
119
+ id_pskc_keyProfileId = _OID(id_pskc, 12)
120
+
121
+ class at_pskc_keyProfileId(char.UTF8String):
122
+ pass
123
+
124
+
125
+ id_pskc_keyReference = _OID(id_pskc, 13)
126
+
127
+ class at_pskc_keyReference(char.UTF8String):
128
+ pass
129
+
130
+
131
+ id_pskc_friendlyName = _OID(id_pskc, 14)
132
+
133
+ class FriendlyName(univ.Sequence):
134
+ pass
135
+
136
+ FriendlyName.componentType = namedtype.NamedTypes(
137
+ namedtype.NamedType('friendlyName', char.UTF8String()),
138
+ namedtype.OptionalNamedType('friendlyNameLangTag', char.UTF8String())
139
+ )
140
+
141
+ class at_pskc_friendlyName(FriendlyName):
142
+ pass
143
+
144
+
145
+ id_pskc_algorithmParameters = _OID(id_pskc, 15)
146
+
147
+ class Encoding(char.UTF8String):
148
+ pass
149
+
150
+ Encoding.namedValues = namedval.NamedValues(
151
+ ('dec', "DECIMAL"),
152
+ ('hex', "HEXADECIMAL"),
153
+ ('alpha', "ALPHANUMERIC"),
154
+ ('b64', "BASE64"),
155
+ ('bin', "BINARY")
156
+ )
157
+
158
+ Encoding.subtypeSpec = constraint.SingleValueConstraint(
159
+ "DECIMAL", "HEXADECIMAL", "ALPHANUMERIC", "BASE64", "BINARY" )
160
+
161
+ class ChallengeFormat(univ.Sequence):
162
+ pass
163
+
164
+ ChallengeFormat.componentType = namedtype.NamedTypes(
165
+ namedtype.NamedType('encoding', Encoding()),
166
+ namedtype.DefaultedNamedType('checkDigit',
167
+ univ.Boolean().subtype(value=0)),
168
+ namedtype.NamedType('min', univ.Integer().subtype(
169
+ subtypeSpec=constraint.ValueRangeConstraint(0, MAX))),
170
+ namedtype.NamedType('max', univ.Integer().subtype(
171
+ subtypeSpec=constraint.ValueRangeConstraint(0, MAX)))
172
+ )
173
+
174
+ class ResponseFormat(univ.Sequence):
175
+ pass
176
+
177
+ ResponseFormat.componentType = namedtype.NamedTypes(
178
+ namedtype.NamedType('encoding', Encoding()),
179
+ namedtype.NamedType('length', univ.Integer().subtype(
180
+ subtypeSpec=constraint.ValueRangeConstraint(0, MAX))),
181
+ namedtype.DefaultedNamedType('checkDigit',
182
+ univ.Boolean().subtype(value=0))
183
+ )
184
+
185
+ class PSKCAlgorithmParameters(univ.Choice):
186
+ pass
187
+
188
+ PSKCAlgorithmParameters.componentType = namedtype.NamedTypes(
189
+ namedtype.NamedType('suite', char.UTF8String()),
190
+ namedtype.NamedType('challengeFormat', ChallengeFormat().subtype(
191
+ implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 0))),
192
+ namedtype.NamedType('responseFormat', ResponseFormat().subtype(
193
+ implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 1)))
194
+ )
195
+
196
+ class at_pskc_algorithmParameters(PSKCAlgorithmParameters):
197
+ pass
198
+
199
+
200
+ id_pskc_counter = _OID(id_pskc, 16)
201
+
202
+ class at_pskc_counter(univ.Integer):
203
+ pass
204
+
205
+ at_pskc_counter.subtypeSpec = constraint.ValueRangeConstraint(0, MAX)
206
+
207
+
208
+ id_pskc_time = _OID(id_pskc, 17)
209
+
210
+ class at_pskc_time(rfc6019.BinaryTime):
211
+ pass
212
+
213
+
214
+ id_pskc_timeInterval = _OID(id_pskc, 18)
215
+
216
+ class at_pskc_timeInterval(univ.Integer):
217
+ pass
218
+
219
+ at_pskc_timeInterval.subtypeSpec = constraint.ValueRangeConstraint(0, MAX)
220
+
221
+
222
+ id_pskc_timeDrift = _OID(id_pskc, 19)
223
+
224
+ class at_pskc_timeDrift(univ.Integer):
225
+ pass
226
+
227
+ at_pskc_timeDrift.subtypeSpec = constraint.ValueRangeConstraint(0, MAX)
228
+
229
+
230
+ id_pskc_valueMAC = _OID(id_pskc, 20)
231
+
232
+ class ValueMac(univ.Sequence):
233
+ pass
234
+
235
+ ValueMac.componentType = namedtype.NamedTypes(
236
+ namedtype.NamedType('macAlgorithm', char.UTF8String()),
237
+ namedtype.NamedType('mac', char.UTF8String())
238
+ )
239
+
240
+ class at_pskc_valueMAC(ValueMac):
241
+ pass
242
+
243
+
244
+ id_pskc_keyUserId = _OID(id_pskc, 27)
245
+
246
+ class at_pskc_keyId(char.UTF8String):
247
+ pass
248
+
249
+
250
+ id_pskc_keyStartDate = _OID(id_pskc, 21)
251
+
252
+ class at_pskc_keyStartDate(useful.GeneralizedTime):
253
+ pass
254
+
255
+
256
+ id_pskc_keyExpiryDate = _OID(id_pskc, 22)
257
+
258
+ class at_pskc_keyExpiryDate(useful.GeneralizedTime):
259
+ pass
260
+
261
+
262
+ id_pskc_numberOfTransactions = _OID(id_pskc, 23)
263
+
264
+ class at_pskc_numberOfTransactions(univ.Integer):
265
+ pass
266
+
267
+ at_pskc_numberOfTransactions.subtypeSpec = constraint.ValueRangeConstraint(0, MAX)
268
+
269
+
270
+ id_pskc_keyUsages = _OID(id_pskc, 24)
271
+
272
+ class PSKCKeyUsage(char.UTF8String):
273
+ pass
274
+
275
+ PSKCKeyUsage.namedValues = namedval.NamedValues(
276
+ ('otp', "OTP"),
277
+ ('cr', "CR"),
278
+ ('encrypt', "Encrypt"),
279
+ ('integrity', "Integrity"),
280
+ ('verify', "Verify"),
281
+ ('unlock', "Unlock"),
282
+ ('decrypt', "Decrypt"),
283
+ ('keywrap', "KeyWrap"),
284
+ ('unwrap', "Unwrap"),
285
+ ('derive', "Derive"),
286
+ ('generate', "Generate")
287
+ )
288
+
289
+ PSKCKeyUsage.subtypeSpec = constraint.SingleValueConstraint(
290
+ "OTP", "CR", "Encrypt", "Integrity", "Verify", "Unlock",
291
+ "Decrypt", "KeyWrap", "Unwrap", "Derive", "Generate" )
292
+
293
+ class PSKCKeyUsages(univ.SequenceOf):
294
+ pass
295
+
296
+ PSKCKeyUsages.componentType = PSKCKeyUsage()
297
+
298
+ class at_pskc_keyUsage(PSKCKeyUsages):
299
+ pass
300
+
301
+
302
+ id_pskc_pinPolicy = _OID(id_pskc, 25)
303
+
304
+ class PINUsageMode(char.UTF8String):
305
+ pass
306
+
307
+ PINUsageMode.namedValues = namedval.NamedValues(
308
+ ("local", "Local"),
309
+ ("prepend", "Prepend"),
310
+ ("append", "Append"),
311
+ ("algorithmic", "Algorithmic")
312
+ )
313
+
314
+ PINUsageMode.subtypeSpec = constraint.SingleValueConstraint(
315
+ "Local", "Prepend", "Append", "Algorithmic" )
316
+
317
+ class PINPolicy(univ.Sequence):
318
+ pass
319
+
320
+ PINPolicy.componentType = namedtype.NamedTypes(
321
+ namedtype.OptionalNamedType('pinKeyId', char.UTF8String().subtype(
322
+ implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0))),
323
+ namedtype.NamedType('pinUsageMode', PINUsageMode().subtype(
324
+ implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 1))),
325
+ namedtype.OptionalNamedType('maxFailedAttempts', univ.Integer().subtype(
326
+ subtypeSpec=constraint.ValueRangeConstraint(0, MAX)).subtype(
327
+ implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 2))),
328
+ namedtype.OptionalNamedType('minLength', univ.Integer().subtype(
329
+ subtypeSpec=constraint.ValueRangeConstraint(0, MAX)).subtype(
330
+ implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 3))),
331
+ namedtype.OptionalNamedType('maxLength', univ.Integer().subtype(
332
+ subtypeSpec=constraint.ValueRangeConstraint(0, MAX)).subtype(
333
+ implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 4))),
334
+ namedtype.OptionalNamedType('pinEncoding', Encoding().subtype(
335
+ implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 5)))
336
+ )
337
+
338
+ class at_pskc_pinPolicy(PINPolicy):
339
+ pass
340
+
341
+
342
+ # Map of Symmetric Key Package Attribute OIDs to Attributes
343
+
344
+ sKeyPkgAttributesMap = {
345
+ id_pskc_manufacturer: at_pskc_manufacturer(),
346
+ id_pskc_serialNo: at_pskc_serialNo(),
347
+ id_pskc_model: at_pskc_model(),
348
+ id_pskc_issueNo: at_pskc_issueNo(),
349
+ id_pskc_deviceBinding: at_pskc_deviceBinding(),
350
+ id_pskc_deviceStartDate: at_pskc_deviceStartDate(),
351
+ id_pskc_deviceExpiryDate: at_pskc_deviceExpiryDate(),
352
+ id_pskc_moduleId: at_pskc_moduleId(),
353
+ id_pskc_deviceUserId: at_pskc_deviceUserId(),
354
+ }
355
+
356
+
357
+ # Map of Symmetric Key Attribute OIDs to Attributes
358
+
359
+ sKeyAttributesMap = {
360
+ id_pskc_keyId: at_pskc_keyId(),
361
+ id_pskc_algorithm: at_pskc_algorithm(),
362
+ id_pskc_issuer: at_pskc_issuer(),
363
+ id_pskc_keyProfileId: at_pskc_keyProfileId(),
364
+ id_pskc_keyReference: at_pskc_keyReference(),
365
+ id_pskc_friendlyName: at_pskc_friendlyName(),
366
+ id_pskc_algorithmParameters: at_pskc_algorithmParameters(),
367
+ id_pskc_counter: at_pskc_counter(),
368
+ id_pskc_time: at_pskc_time(),
369
+ id_pskc_timeInterval: at_pskc_timeInterval(),
370
+ id_pskc_timeDrift: at_pskc_timeDrift(),
371
+ id_pskc_valueMAC: at_pskc_valueMAC(),
372
+ id_pskc_keyUserId: at_pskc_keyUserId(),
373
+ id_pskc_keyStartDate: at_pskc_keyStartDate(),
374
+ id_pskc_keyExpiryDate: at_pskc_keyExpiryDate(),
375
+ id_pskc_numberOfTransactions: at_pskc_numberOfTransactions(),
376
+ id_pskc_keyUsages: at_pskc_keyUsage(),
377
+ id_pskc_pinPolicy: at_pskc_pinPolicy(),
378
+ }
379
+
380
+
381
+ # This definition replaces Attribute() from rfc5652.py; it is the same except
382
+ # that opentype is added with sKeyPkgAttributesMap and sKeyAttributesMap
383
+
384
+ class AttributeType(univ.ObjectIdentifier):
385
+ pass
386
+
387
+
388
+ class AttributeValue(univ.Any):
389
+ pass
390
+
391
+
392
+ class SKeyAttribute(univ.Sequence):
393
+ pass
394
+
395
+ SKeyAttribute.componentType = namedtype.NamedTypes(
396
+ namedtype.NamedType('attrType', AttributeType()),
397
+ namedtype.NamedType('attrValues',
398
+ univ.SetOf(componentType=AttributeValue()),
399
+ openType=opentype.OpenType('attrType', sKeyAttributesMap)
400
+ )
401
+ )
402
+
403
+
404
+ class SKeyPkgAttribute(univ.Sequence):
405
+ pass
406
+
407
+ SKeyPkgAttribute.componentType = namedtype.NamedTypes(
408
+ namedtype.NamedType('attrType', AttributeType()),
409
+ namedtype.NamedType('attrValues',
410
+ univ.SetOf(componentType=AttributeValue()),
411
+ openType=opentype.OpenType('attrType', sKeyPkgAttributesMap)
412
+ )
413
+ )
414
+
415
+
416
+ # Symmetric Key Package Content Type
417
+
418
+ id_ct_KP_sKeyPackage = univ.ObjectIdentifier('1.2.840.113549.1.9.16.1.25')
419
+
420
+
421
+ class KeyPkgVersion(univ.Integer):
422
+ pass
423
+
424
+ KeyPkgVersion.namedValues = namedval.NamedValues(
425
+ ('v1', 1)
426
+ )
427
+
428
+
429
+ class OneSymmetricKey(univ.Sequence):
430
+ pass
431
+
432
+ OneSymmetricKey.componentType = namedtype.NamedTypes(
433
+ namedtype.OptionalNamedType('sKeyAttrs',
434
+ univ.SequenceOf(componentType=SKeyAttribute()).subtype(
435
+ subtypeSpec=constraint.ValueSizeConstraint(1, MAX))),
436
+ namedtype.OptionalNamedType('sKey', univ.OctetString())
437
+ )
438
+
439
+ OneSymmetricKey.sizeSpec = univ.Sequence.sizeSpec + constraint.ValueSizeConstraint(1, 2)
440
+
441
+
442
+ class SymmetricKeys(univ.SequenceOf):
443
+ pass
444
+
445
+ SymmetricKeys.componentType = OneSymmetricKey()
446
+ SymmetricKeys.subtypeSpec=constraint.ValueSizeConstraint(1, MAX)
447
+
448
+
449
+ class SymmetricKeyPackage(univ.Sequence):
450
+ pass
451
+
452
+ SymmetricKeyPackage.componentType = namedtype.NamedTypes(
453
+ namedtype.DefaultedNamedType('version', KeyPkgVersion().subtype(value='v1')),
454
+ namedtype.OptionalNamedType('sKeyPkgAttrs',
455
+ univ.SequenceOf(componentType=SKeyPkgAttribute()).subtype(
456
+ subtypeSpec=constraint.ValueSizeConstraint(1, MAX),
457
+ implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0))),
458
+ namedtype.NamedType('sKeys', SymmetricKeys())
459
+ )
460
+
461
+
462
+ # Map of Content Type OIDs to Content Types are
463
+ # added to the ones that are in rfc5652.py
464
+
465
+ _cmsContentTypesMapUpdate = {
466
+ id_ct_KP_sKeyPackage: SymmetricKeyPackage(),
467
+ }
468
+
469
+ rfc5652.cmsContentTypesMap.update(_cmsContentTypesMapUpdate)
my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/pyasn1_modules/rfc7229.py ADDED
@@ -0,0 +1,29 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #
2
+ # This file is part of pyasn1-modules software.
3
+ #
4
+ # Created by Russ Housley.
5
+ #
6
+ # Copyright (c) 2019, Vigil Security, LLC
7
+ # License: http://snmplabs.com/pyasn1/license.html
8
+ #
9
+ # Object Identifiers for Test Certificate Policies
10
+ #
11
+ # ASN.1 source from:
12
+ # https://www.rfc-editor.org/rfc/rfc7229.txt
13
+ #
14
+
15
+ from pyasn1.type import univ
16
+
17
+
18
+ id_pkix = univ.ObjectIdentifier('1.3.6.1.5.5.7')
19
+
20
+ id_TEST = id_pkix + (13, )
21
+
22
+ id_TEST_certPolicyOne = id_TEST + (1, )
23
+ id_TEST_certPolicyTwo = id_TEST + (2, )
24
+ id_TEST_certPolicyThree = id_TEST + (3, )
25
+ id_TEST_certPolicyFour = id_TEST + (4, )
26
+ id_TEST_certPolicyFive = id_TEST + (5, )
27
+ id_TEST_certPolicySix = id_TEST + (6, )
28
+ id_TEST_certPolicySeven = id_TEST + (7, )
29
+ id_TEST_certPolicyEight = id_TEST + (8, )
my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/pyasn1_modules/rfc7585.py ADDED
@@ -0,0 +1,50 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #
2
+ # This file is part of pyasn1-modules software.
3
+ #
4
+ # Created by Russ Housley with some assistance from asn1ate v.0.6.0.
5
+ #
6
+ # Copyright (c) 2019, Vigil Security, LLC
7
+ # License: http://snmplabs.com/pyasn1/license.html
8
+ #
9
+ # Network Access Identifier (NAI) Realm Name for Certificates
10
+ #
11
+ # ASN.1 source from:
12
+ # https://www.rfc-editor.org/rfc/rfc7585.txt
13
+ #
14
+
15
+ from pyasn1.type import char
16
+ from pyasn1.type import constraint
17
+ from pyasn1.type import univ
18
+
19
+ from pyasn1_modules import rfc5280
20
+
21
+
22
+ # NAI Realm Name for Certificates
23
+
24
+ id_pkix = univ.ObjectIdentifier('1.3.6.1.5.5.7')
25
+
26
+ id_on = id_pkix + (8, )
27
+
28
+ id_on_naiRealm = id_on + (8, )
29
+
30
+
31
+ ub_naiRealm_length = univ.Integer(255)
32
+
33
+
34
+ class NAIRealm(char.UTF8String):
35
+ subtypeSpec = constraint.ValueSizeConstraint(1, ub_naiRealm_length)
36
+
37
+
38
+ naiRealm = rfc5280.AnotherName()
39
+ naiRealm['type-id'] = id_on_naiRealm
40
+ naiRealm['value'] = NAIRealm()
41
+
42
+
43
+ # Map of Other Name OIDs to Other Name is added to the
44
+ # ones that are in rfc5280.py
45
+
46
+ _anotherNameMapUpdate = {
47
+ id_on_naiRealm: NAIRealm(),
48
+ }
49
+
50
+ rfc5280.anotherNameMap.update(_anotherNameMapUpdate)
my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/pyasn1_modules/rfc7894.py ADDED
@@ -0,0 +1,92 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #
2
+ # This file is part of pyasn1-modules software.
3
+ #
4
+ # Created by Russ Housley.
5
+ #
6
+ # Copyright (c) 2019, Vigil Security, LLC
7
+ # License: http://snmplabs.com/pyasn1/license.html
8
+ #
9
+ # Alternative Challenge Password Attributes for EST
10
+ #
11
+ # ASN.1 source from:
12
+ # https://www.rfc-editor.org/rfc/rfc7894.txt
13
+ #
14
+
15
+ from pyasn1.type import char
16
+ from pyasn1.type import constraint
17
+ from pyasn1.type import namedtype
18
+ from pyasn1.type import univ
19
+
20
+ from pyasn1_modules import rfc5652
21
+ from pyasn1_modules import rfc6402
22
+ from pyasn1_modules import rfc7191
23
+
24
+
25
+ # SingleAttribute is the same as Attribute in RFC 5652, except that the
26
+ # attrValues SET must have one and only one member
27
+
28
+ Attribute = rfc7191.SingleAttribute
29
+
30
+
31
+ # DirectoryString is the same as RFC 5280, except the length is limited to 255
32
+
33
+ class DirectoryString(univ.Choice):
34
+ pass
35
+
36
+ DirectoryString.componentType = namedtype.NamedTypes(
37
+ namedtype.NamedType('teletexString', char.TeletexString().subtype(
38
+ subtypeSpec=constraint.ValueSizeConstraint(1, 255))),
39
+ namedtype.NamedType('printableString', char.PrintableString().subtype(
40
+ subtypeSpec=constraint.ValueSizeConstraint(1, 255))),
41
+ namedtype.NamedType('universalString', char.UniversalString().subtype(
42
+ subtypeSpec=constraint.ValueSizeConstraint(1, 255))),
43
+ namedtype.NamedType('utf8String', char.UTF8String().subtype(
44
+ subtypeSpec=constraint.ValueSizeConstraint(1, 255))),
45
+ namedtype.NamedType('bmpString', char.BMPString().subtype(
46
+ subtypeSpec=constraint.ValueSizeConstraint(1, 255)))
47
+ )
48
+
49
+
50
+ # OTP Challenge Attribute
51
+
52
+ id_aa_otpChallenge = univ.ObjectIdentifier('1.2.840.113549.1.9.16.2.56')
53
+
54
+ ub_aa_otpChallenge = univ.Integer(255)
55
+
56
+ otpChallenge = Attribute()
57
+ otpChallenge['attrType'] = id_aa_otpChallenge
58
+ otpChallenge['attrValues'][0] = DirectoryString()
59
+
60
+
61
+ # Revocation Challenge Attribute
62
+
63
+ id_aa_revocationChallenge = univ.ObjectIdentifier('1.2.840.113549.1.9.16.2.57')
64
+
65
+ ub_aa_revocationChallenge = univ.Integer(255)
66
+
67
+ revocationChallenge = Attribute()
68
+ revocationChallenge['attrType'] = id_aa_revocationChallenge
69
+ revocationChallenge['attrValues'][0] = DirectoryString()
70
+
71
+
72
+ # EST Identity Linking Attribute
73
+
74
+ id_aa_estIdentityLinking = univ.ObjectIdentifier('1.2.840.113549.1.9.16.2.58')
75
+
76
+ ub_aa_est_identity_linking = univ.Integer(255)
77
+
78
+ estIdentityLinking = Attribute()
79
+ estIdentityLinking['attrType'] = id_aa_estIdentityLinking
80
+ estIdentityLinking['attrValues'][0] = DirectoryString()
81
+
82
+
83
+ # Map of Attribute Type OIDs to Attributes added to the
84
+ # ones that are in rfc6402.py
85
+
86
+ _cmcControlAttributesMapUpdate = {
87
+ id_aa_otpChallenge: DirectoryString(),
88
+ id_aa_revocationChallenge: DirectoryString(),
89
+ id_aa_estIdentityLinking: DirectoryString(),
90
+ }
91
+
92
+ rfc6402.cmcControlAttributesMap.update(_cmcControlAttributesMapUpdate)
my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/pycodestyle-2.8.0.dist-info/INSTALLER ADDED
@@ -0,0 +1 @@
 
 
1
+ pip
my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/pycodestyle-2.8.0.dist-info/LICENSE ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ Copyright © 2006-2009 Johann C. Rocholl <johann@rocholl.net>
2
+ Copyright © 2009-2014 Florent Xicluna <florent.xicluna@gmail.com>
3
+ Copyright © 2014-2020 Ian Lee <IanLee1521@gmail.com>
4
+
5
+ Licensed under the terms of the Expat License
6
+
7
+ Permission is hereby granted, free of charge, to any person
8
+ obtaining a copy of this software and associated documentation files
9
+ (the "Software"), to deal in the Software without restriction,
10
+ including without limitation the rights to use, copy, modify, merge,
11
+ publish, distribute, sublicense, and/or sell copies of the Software,
12
+ and to permit persons to whom the Software is furnished to do so,
13
+ subject to the following conditions:
14
+
15
+ The above copyright notice and this permission notice shall be
16
+ included in all copies or substantial portions of the Software.
17
+
18
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
21
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
22
+ BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
23
+ ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
24
+ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25
+ SOFTWARE.
my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/pycodestyle-2.8.0.dist-info/METADATA ADDED
@@ -0,0 +1,1063 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ Metadata-Version: 2.1
2
+ Name: pycodestyle
3
+ Version: 2.8.0
4
+ Summary: Python style guide checker
5
+ Home-page: https://pycodestyle.pycqa.org/
6
+ Author: Johann C. Rocholl
7
+ Author-email: johann@rocholl.net
8
+ Maintainer: Ian Lee
9
+ Maintainer-email: IanLee1521@gmail.com
10
+ License: Expat license
11
+ Project-URL: Changes, https://pycodestyle.pycqa.org/en/latest/developer.html#changes
12
+ Keywords: pycodestyle,pep8,PEP 8,PEP-8,PEP8
13
+ Platform: UNKNOWN
14
+ Classifier: Development Status :: 5 - Production/Stable
15
+ Classifier: Environment :: Console
16
+ Classifier: Intended Audience :: Developers
17
+ Classifier: License :: OSI Approved :: MIT License
18
+ Classifier: Operating System :: OS Independent
19
+ Classifier: Programming Language :: Python
20
+ Classifier: Programming Language :: Python :: 2
21
+ Classifier: Programming Language :: Python :: 2.7
22
+ Classifier: Programming Language :: Python :: 3
23
+ Classifier: Programming Language :: Python :: 3.5
24
+ Classifier: Programming Language :: Python :: 3.6
25
+ Classifier: Programming Language :: Python :: 3.7
26
+ Classifier: Programming Language :: Python :: 3.8
27
+ Classifier: Programming Language :: Python :: Implementation :: CPython
28
+ Classifier: Programming Language :: Python :: Implementation :: PyPy
29
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
30
+ Requires-Python: >=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*
31
+ License-File: LICENSE
32
+
33
+ pycodestyle (formerly called pep8) - Python style guide checker
34
+ ===============================================================
35
+
36
+ .. image:: https://github.com/PyCQA/pycodestyle/actions/workflows/main.yml/badge.svg
37
+ :target: https://github.com/PyCQA/pycodestyle/actions/workflows/main.yml
38
+ :alt: Build status
39
+
40
+ .. image:: https://readthedocs.org/projects/pycodestyle/badge/?version=latest
41
+ :target: https://pycodestyle.pycqa.org
42
+ :alt: Documentation Status
43
+
44
+ .. image:: https://img.shields.io/pypi/wheel/pycodestyle.svg
45
+ :target: https://pypi.org/project/pycodestyle/
46
+ :alt: Wheel Status
47
+
48
+ .. image:: https://badges.gitter.im/PyCQA/pycodestyle.svg
49
+ :alt: Join the chat at https://gitter.im/PyCQA/pycodestyle
50
+ :target: https://gitter.im/PyCQA/pycodestyle?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge
51
+
52
+ pycodestyle is a tool to check your Python code against some of the style
53
+ conventions in `PEP 8`_.
54
+
55
+ .. _PEP 8: http://www.python.org/dev/peps/pep-0008/
56
+
57
+ .. note::
58
+
59
+ This package used to be called ``pep8`` but was renamed to ``pycodestyle``
60
+ to reduce confusion. Further discussion can be found `in the issue where
61
+ Guido requested this
62
+ change <https://github.com/PyCQA/pycodestyle/issues/466>`_, or in the
63
+ lightning talk at PyCon 2016 by @IanLee1521:
64
+ `slides <https://speakerdeck.com/ianlee1521/pep8-vs-pep-8>`_
65
+ `video <https://youtu.be/PulzIT8KYLk?t=36m>`_.
66
+
67
+ Features
68
+ --------
69
+
70
+ * Plugin architecture: Adding new checks is easy.
71
+
72
+ * Parseable output: Jump to error location in your editor.
73
+
74
+ * Small: Just one Python file, requires only stdlib. You can use just
75
+ the ``pycodestyle.py`` file for this purpose.
76
+
77
+ * Comes with a comprehensive test suite.
78
+
79
+ Installation
80
+ ------------
81
+
82
+ You can install, upgrade, and uninstall ``pycodestyle.py`` with these commands::
83
+
84
+ $ pip install pycodestyle
85
+ $ pip install --upgrade pycodestyle
86
+ $ pip uninstall pycodestyle
87
+
88
+ There's also a package for Debian/Ubuntu, but it's not always the
89
+ latest version.
90
+
91
+ Example usage and output
92
+ ------------------------
93
+
94
+ ::
95
+
96
+ $ pycodestyle --first optparse.py
97
+ optparse.py:69:11: E401 multiple imports on one line
98
+ optparse.py:77:1: E302 expected 2 blank lines, found 1
99
+ optparse.py:88:5: E301 expected 1 blank line, found 0
100
+ optparse.py:222:34: W602 deprecated form of raising exception
101
+ optparse.py:347:31: E211 whitespace before '('
102
+ optparse.py:357:17: E201 whitespace after '{'
103
+ optparse.py:472:29: E221 multiple spaces before operator
104
+ optparse.py:544:21: W601 .has_key() is deprecated, use 'in'
105
+
106
+ You can also make ``pycodestyle.py`` show the source code for each error, and
107
+ even the relevant text from PEP 8::
108
+
109
+ $ pycodestyle --show-source --show-pep8 testsuite/E40.py
110
+ testsuite/E40.py:2:10: E401 multiple imports on one line
111
+ import os, sys
112
+ ^
113
+ Imports should usually be on separate lines.
114
+
115
+ Okay: import os\nimport sys
116
+ E401: import sys, os
117
+
118
+
119
+ Or you can display how often each error was found::
120
+
121
+ $ pycodestyle --statistics -qq Python-2.5/Lib
122
+ 232 E201 whitespace after '['
123
+ 599 E202 whitespace before ')'
124
+ 631 E203 whitespace before ','
125
+ 842 E211 whitespace before '('
126
+ 2531 E221 multiple spaces before operator
127
+ 4473 E301 expected 1 blank line, found 0
128
+ 4006 E302 expected 2 blank lines, found 1
129
+ 165 E303 too many blank lines (4)
130
+ 325 E401 multiple imports on one line
131
+ 3615 E501 line too long (82 characters)
132
+ 612 W601 .has_key() is deprecated, use 'in'
133
+ 1188 W602 deprecated form of raising exception
134
+
135
+ Links
136
+ -----
137
+
138
+ * `Read the documentation <https://pycodestyle.pycqa.org/>`_
139
+
140
+ * `Fork me on GitHub <http://github.com/PyCQA/pycodestyle>`_
141
+
142
+
143
+ Changelog
144
+ =========
145
+
146
+ 2.8.0 (2021-10-10)
147
+ ------------------
148
+
149
+ Changes:
150
+
151
+ * Drop python 3.4. PR #982.
152
+ * E712: fix false negative with multiple comparisons. PR #987.
153
+ * E211: fix false positives with ``match``. PR #989.
154
+ * E772: improve performance of bare except check. PR #992.
155
+ * Backport tokenize performance improvement from python 3.10. PR #993.
156
+ * E225: fix for lambdas containing positional-only args. PR #1012.
157
+ * Remove ``indent_size_str`` "setting". PR #995.
158
+ * E402: allow ``__all__`` to be typed. PR #1019.
159
+ * E225: fix false positives for ``*`` in ``case``. PR #1003.
160
+ * E201: detect tabs as whitespace. PR #1015.
161
+
162
+
163
+ 2.7.0 (2021-03-14)
164
+ ------------------
165
+
166
+ Changes:
167
+
168
+ * Fix physical checks (such as W191) at end of file. PR #961.
169
+ * Add ``--indent-size`` option (defaulting to ``4``). PR #970.
170
+ * W605: fix escaped crlf false positive on windows. PR #976.
171
+
172
+
173
+ 2.6.0 (2020-05-11)
174
+ ------------------
175
+
176
+ Announcements:
177
+
178
+ * Anthony Sottile (@asottile) joined the team as a core developer. :tada:
179
+
180
+ Changes:
181
+
182
+ * E306: fix detection inside ``async def``. PR #929.
183
+ * E301: fix regression disallowing decorated one-liners. PR #927.
184
+ * E714: fix false positive with chained ``is not``. PR #931.
185
+
186
+
187
+ 2.6.0a1 (2020-04-23)
188
+ --------------------
189
+
190
+ New checks:
191
+
192
+ * E225: require whitespace around ``and`` ``in`` ``is`` and ``or``. PR #847.
193
+
194
+ Changes:
195
+
196
+ * E117: fix indentation using tabs by treating as 8-space indents. PR #837.
197
+ * E721: fix false positive with names containg ``istype``. PR #850.
198
+ * E741: allow ``l`` as a named argument in a function call. PR #853.
199
+ * E302: fix false-negative with decorated functions. PR #859.
200
+ * W504: ellipsis (``...``) is no longer treated as a binary operator. PR #875.
201
+ * E402: allow ``with``, ``if``, ``elif``, ``else`` to guard imports. PR #834.
202
+ * Add support for assignment expressions ``:=`` (PEP 572). PR #879.
203
+ * Add support for positional-only arguments ``/`` (PEP 570). PR #872, #918.
204
+ * Add support for python 3.8.
205
+ * Add support for matrix multiplication operator ``@`` (PEP 465). PR #897.
206
+ * Support visual indent for continuation lines for ``with`` / ``assert`` /
207
+ ``raise``. PR #912.
208
+ * E302: allow two blank lines after a block of one-liners. PR #913.
209
+ * E302: allow two-and-fewer newlines at the top of the file. PR #919.
210
+
211
+
212
+ 2.5.0 (2019-01-29)
213
+ ------------------
214
+
215
+ New checks:
216
+
217
+ * E117: Over-indented code blocks
218
+ * W505: Maximum doc-string length only when configured with --max-doc-length
219
+
220
+ Changes:
221
+
222
+ * Remove support for EOL Python 2.6 and 3.3. PR #720.
223
+ * Add E117 error for over-indented code blocks.
224
+ * Allow W605 to be silenced by `# noqa` and fix the position reported by W605
225
+ * Allow users to omit blank lines around one-liner definitions of classes and
226
+ functions
227
+ * Include the function return annotation (``->``) as requiring surrounding
228
+ whitespace only on Python 3
229
+ * Verify that only names can follow ``await``. Previously we allowed numbers
230
+ and strings.
231
+ * Add support for Python 3.7
232
+ * Fix detection of annotated argument defaults for E252
233
+ * Correct the position reported by W504
234
+
235
+
236
+ 2.4.0 (2018-04-10)
237
+ ------------------
238
+
239
+ New checks:
240
+
241
+ * Add W504 warning for checking that a break doesn't happen after a binary
242
+ operator. This check is ignored by default. PR #502.
243
+ * Add W605 warning for invalid escape sequences in string literals. PR #676.
244
+ * Add W606 warning for 'async' and 'await' reserved keywords being introduced
245
+ in Python 3.7. PR #684.
246
+ * Add E252 error for missing whitespace around equal sign in type annotated
247
+ function arguments with defaults values. PR #717.
248
+
249
+ Changes:
250
+
251
+ * An internal bisect search has replaced a linear search in order to improve
252
+ efficiency. PR #648.
253
+ * pycodestyle now uses PyPI trove classifiers in order to document supported
254
+ python versions on PyPI. PR #654.
255
+ * 'setup.cfg' '[wheel]' section has been renamed to '[bdist_wheel]', as
256
+ the former is legacy. PR #653.
257
+ * pycodestyle now handles very long lines much more efficiently for python
258
+ 3.2+. Fixes #643. PR #644.
259
+ * You can now write 'pycodestyle.StyleGuide(verbose=True)' instead of
260
+ 'pycodestyle.StyleGuide(verbose=True, paths=['-v'])' in order to achieve
261
+ verbosity. PR #663.
262
+ * The distribution of pycodestyle now includes the license text in order to
263
+ comply with open source licenses which require this. PR #694.
264
+ * 'maximum_line_length' now ignores shebang ('#!') lines. PR #736.
265
+ * Add configuration option for the allowed number of blank lines. It is
266
+ implemented as a top level dictionary which can be easily overwritten. Fixes
267
+ #732. PR #733.
268
+
269
+ Bugs:
270
+
271
+ * Prevent a 'DeprecationWarning', and a 'SyntaxError' in future python, caused
272
+ by an invalid escape sequence. PR #625.
273
+ * Correctly report E501 when the first line of a docstring is too long.
274
+ Resolves #622. PR #630.
275
+ * Support variable annotation when variable start by a keyword, such as class
276
+ variable type annotations in python 3.6. PR #640.
277
+ * pycodestyle internals have been changed in order to allow 'python3 -m
278
+ cProfile' to report correct metrics. PR #647.
279
+ * Fix a spelling mistake in the description of E722. PR #697.
280
+ * 'pycodestyle --diff' now does not break if your 'gitconfig' enables
281
+ 'mnemonicprefix'. PR #706.
282
+
283
+ 2.3.1 (2017-01-31)
284
+ ------------------
285
+
286
+ Bugs:
287
+
288
+ * Fix regression in detection of E302 and E306; #618, #620
289
+
290
+ 2.3.0 (2017-01-30)
291
+ ------------------
292
+
293
+ New Checks:
294
+
295
+ * Add E722 warning for bare ``except`` clauses
296
+ * Report E704 for async function definitions (``async def``)
297
+
298
+ Bugs:
299
+
300
+ * Fix another E305 false positive for variables beginning with "class" or
301
+ "def"
302
+ * Fix detection of multiple spaces between ``async`` and ``def``
303
+ * Fix handling of variable annotations. Stop reporting E701 on Python 3.6 for
304
+ variable annotations.
305
+
306
+ 2.2.0 (2016-11-14)
307
+ ------------------
308
+
309
+ Announcements:
310
+
311
+ * Added Make target to obtain proper tarball file permissions; #599
312
+
313
+ Bugs:
314
+
315
+ * Fixed E305 regression caused by #400; #593
316
+
317
+ 2.1.0 (2016-11-04)
318
+ ------------------
319
+
320
+ Announcements:
321
+
322
+ * Change all references to the pep8 project to say pycodestyle; #530
323
+
324
+ Changes:
325
+
326
+ * Report E302 for blank lines before an "async def"; #556
327
+ * Update our list of tested and supported Python versions which are 2.6, 2.7,
328
+ 3.2, 3.3, 3.4 and 3.5 as well as the nightly Python build and PyPy.
329
+ * Report E742 and E743 for functions and classes badly named 'l', 'O', or 'I'.
330
+ * Report E741 on 'global' and 'nonlocal' statements, as well as prohibited
331
+ single-letter variables.
332
+ * Deprecated use of `[pep8]` section name in favor of `[pycodestyle]`; #591
333
+ * Report E722 when bare except clause is used; #579
334
+
335
+ Bugs:
336
+
337
+ * Fix opt_type AssertionError when using Flake8 2.6.2 and pycodestyle; #561
338
+ * Require two blank lines after toplevel def, class; #536
339
+ * Remove accidentally quadratic computation based on the number of colons. This
340
+ will make pycodestyle faster in some cases; #314
341
+
342
+ 2.0.0 (2016-05-31)
343
+ ------------------
344
+
345
+ Announcements:
346
+
347
+ * Repository renamed to `pycodestyle`; Issue #466 / #481.
348
+ * Added joint Code of Conduct as member of PyCQA; #483
349
+
350
+ Changes:
351
+
352
+ * Added tox test support for Python 3.5 and pypy3
353
+ * Added check E275 for whitespace on `from ... import ...` lines; #489 / #491
354
+ * Added W503 to the list of codes ignored by default ignore list; #498
355
+ * Removed use of project level `.pep8` configuration file; #364
356
+
357
+ Bugs:
358
+
359
+ * Fixed bug with treating `~` operator as binary; #383 / #384
360
+ * Identify binary operators as unary; #484 / #485
361
+
362
+ 1.7.0 (2016-01-12)
363
+ ------------------
364
+
365
+ Announcements:
366
+
367
+ * Repository moved to PyCQA Organization on GitHub:
368
+ https://github.com/pycqa/pep8
369
+
370
+ Changes:
371
+
372
+ * Reverted the fix in #368, "options passed on command line are only ones
373
+ accepted" feature. This has many unintended consequences in pep8 and flake8
374
+ and needs to be reworked when I have more time.
375
+ * Added support for Python 3.5. (Issue #420 & #459)
376
+ * Added support for multi-line config_file option parsing. (Issue #429)
377
+ * Improved parameter parsing. (Issues #420 & #456)
378
+
379
+ Bugs:
380
+
381
+ * Fixed BytesWarning on Python 3. (Issue #459)
382
+
383
+ 1.6.2 (2015-02-15)
384
+ ------------------
385
+
386
+ Changes:
387
+
388
+ * Added check for breaking around a binary operator. (Issue #197, Pull #305)
389
+
390
+ Bugs:
391
+
392
+ * Restored config_file parameter in process_options(). (Issue #380)
393
+
394
+
395
+ 1.6.1 (2015-02-08)
396
+ ------------------
397
+
398
+ Changes:
399
+
400
+ * Assign variables before referenced. (Issue #287)
401
+
402
+ Bugs:
403
+
404
+ * Exception thrown due to unassigned ``local_dir`` variable. (Issue #377)
405
+
406
+
407
+ 1.6.0 (2015-02-06)
408
+ ------------------
409
+
410
+ News:
411
+
412
+ * Ian Lee <ianlee1521@gmail.com> joined the project as a maintainer.
413
+
414
+ Changes:
415
+
416
+ * Report E731 for lambda assignment. (Issue #277)
417
+
418
+ * Report E704 for one-liner def instead of E701.
419
+ Do not report this error in the default configuration. (Issue #277)
420
+
421
+ * Replace codes E111, E112 and E113 with codes E114, E115 and E116
422
+ for bad indentation of comments. (Issue #274)
423
+
424
+ * Report E266 instead of E265 when the block comment starts with
425
+ multiple ``#``. (Issue #270)
426
+
427
+ * Report E402 for import statements not at the top of the file. (Issue #264)
428
+
429
+ * Do not enforce whitespaces around ``**`` operator. (Issue #292)
430
+
431
+ * Strip whitespace from around paths during normalization. (Issue #339 / #343)
432
+
433
+ * Update ``--format`` documentation. (Issue #198 / Pull Request #310)
434
+
435
+ * Add ``.tox/`` to default excludes. (Issue #335)
436
+
437
+ * Do not report E121 or E126 in the default configuration. (Issues #256 / #316)
438
+
439
+ * Allow spaces around the equals sign in an annotated function. (Issue #357)
440
+
441
+ * Allow trailing backslash if in an inline comment. (Issue #374)
442
+
443
+ * If ``--config`` is used, only that configuration is processed. Otherwise,
444
+ merge the user and local configurations are merged. (Issue #368 / #369)
445
+
446
+ Bug fixes:
447
+
448
+ * Don't crash if Checker.build_tokens_line() returns None. (Issue #306)
449
+
450
+ * Don't crash if os.path.expanduser() throws an ImportError. (Issue #297)
451
+
452
+ * Missing space around keyword parameter equal not always reported, E251.
453
+ (Issue #323)
454
+
455
+ * Fix false positive E711/E712/E713. (Issues #330 and #336)
456
+
457
+ * Do not skip physical checks if the newline is escaped. (Issue #319)
458
+
459
+ * Flush sys.stdout to avoid race conditions with printing. See flake8 bug:
460
+ https://gitlab.com/pycqa/flake8/issues/17 for more details. (Issue #363)
461
+
462
+
463
+ 1.5.7 (2014-05-29)
464
+ ------------------
465
+
466
+ Bug fixes:
467
+
468
+ * Skip the traceback on "Broken pipe" signal. (Issue #275)
469
+
470
+ * Do not exit when an option in ``setup.cfg`` or ``tox.ini``
471
+ is not recognized.
472
+
473
+ * Check the last line even if it does not end with a newline. (Issue #286)
474
+
475
+ * Always open files in universal newlines mode in Python 2. (Issue #288)
476
+
477
+
478
+ 1.5.6 (2014-04-14)
479
+ ------------------
480
+
481
+ Bug fixes:
482
+
483
+ * Check the last line even if it has no end-of-line. (Issue #273)
484
+
485
+
486
+ 1.5.5 (2014-04-10)
487
+ ------------------
488
+
489
+ Bug fixes:
490
+
491
+ * Fix regression with E22 checks and inline comments. (Issue #271)
492
+
493
+
494
+ 1.5.4 (2014-04-07)
495
+ ------------------
496
+
497
+ Bug fixes:
498
+
499
+ * Fix negative offset with E303 before a multi-line docstring.
500
+ (Issue #269)
501
+
502
+
503
+ 1.5.3 (2014-04-04)
504
+ ------------------
505
+
506
+ Bug fixes:
507
+
508
+ * Fix wrong offset computation when error is on the last char
509
+ of a physical line. (Issue #268)
510
+
511
+
512
+ 1.5.2 (2014-04-04)
513
+ ------------------
514
+
515
+ Changes:
516
+
517
+ * Distribute a universal wheel file.
518
+
519
+ Bug fixes:
520
+
521
+ * Report correct line number for E303 with comments. (Issue #60)
522
+
523
+ * Do not allow newline after parameter equal. (Issue #252)
524
+
525
+ * Fix line number reported for multi-line strings. (Issue #220)
526
+
527
+ * Fix false positive E121/E126 with multi-line strings. (Issue #265)
528
+
529
+ * Fix E501 not detected in comments with Python 2.5.
530
+
531
+ * Fix caret position with ``--show-source`` when line contains tabs.
532
+
533
+
534
+ 1.5.1 (2014-03-27)
535
+ ------------------
536
+
537
+ Bug fixes:
538
+
539
+ * Fix a crash with E125 on multi-line strings. (Issue #263)
540
+
541
+
542
+ 1.5 (2014-03-26)
543
+ ----------------
544
+
545
+ Changes:
546
+
547
+ * Report E129 instead of E125 for visually indented line with same
548
+ indent as next logical line. (Issue #126)
549
+
550
+ * Report E265 for space before block comment. (Issue #190)
551
+
552
+ * Report E713 and E714 when operators ``not in`` and ``is not`` are
553
+ recommended. (Issue #236)
554
+
555
+ * Allow long lines in multiline strings and comments if they cannot
556
+ be wrapped. (Issue #224).
557
+
558
+ * Optionally disable physical line checks inside multiline strings,
559
+ using ``# noqa``. (Issue #242)
560
+
561
+ * Change text for E121 to report "continuation line under-indented
562
+ for hanging indent" instead of indentation not being a
563
+ multiple of 4.
564
+
565
+ * Report E131 instead of E121 / E126 if the hanging indent is not
566
+ consistent within the same continuation block. It helps when
567
+ error E121 or E126 is in the ``ignore`` list.
568
+
569
+ * Report E126 instead of E121 when the continuation line is hanging
570
+ with extra indentation, even if indentation is not a multiple of 4.
571
+
572
+ Bug fixes:
573
+
574
+ * Allow the checkers to report errors on empty files. (Issue #240)
575
+
576
+ * Fix ignoring too many checks when ``--select`` is used with codes
577
+ declared in a flake8 extension. (Issue #216)
578
+
579
+ * Fix regression with multiple brackets. (Issue #214)
580
+
581
+ * Fix ``StyleGuide`` to parse the local configuration if the
582
+ keyword argument ``paths`` is specified. (Issue #246)
583
+
584
+ * Fix a false positive E124 for hanging indent. (Issue #254)
585
+
586
+ * Fix a false positive E126 with embedded colon. (Issue #144)
587
+
588
+ * Fix a false positive E126 when indenting with tabs. (Issue #204)
589
+
590
+ * Fix behaviour when ``exclude`` is in the configuration file and
591
+ the current directory is not the project directory. (Issue #247)
592
+
593
+ * The logical checks can return ``None`` instead of an empty iterator.
594
+ (Issue #250)
595
+
596
+ * Do not report multiple E101 if only the first indentation starts
597
+ with a tab. (Issue #237)
598
+
599
+ * Fix a rare false positive W602. (Issue #34)
600
+
601
+
602
+ 1.4.6 (2013-07-02)
603
+ ------------------
604
+
605
+ Changes:
606
+
607
+ * Honor ``# noqa`` for errors E711 and E712. (Issue #180)
608
+
609
+ * When both a ``tox.ini`` and a ``setup.cfg`` are present in the project
610
+ directory, merge their contents. The ``tox.ini`` file takes
611
+ precedence (same as before). (Issue #182)
612
+
613
+ * Give priority to ``--select`` over ``--ignore``. (Issue #188)
614
+
615
+ * Compare full path when excluding a file. (Issue #186)
616
+
617
+ * New option ``--hang-closing`` to switch to the alternative style of
618
+ closing bracket indentation for hanging indent. Add error E133 for
619
+ closing bracket which is missing indentation. (Issue #103)
620
+
621
+ * Accept both styles of closing bracket indentation for hanging indent.
622
+ Do not report error E123 in the default configuration. (Issue #103)
623
+
624
+ Bug fixes:
625
+
626
+ * Do not crash when running AST checks and the document contains null bytes.
627
+ (Issue #184)
628
+
629
+ * Correctly report other E12 errors when E123 is ignored. (Issue #103)
630
+
631
+ * Fix false positive E261/E262 when the file contains a BOM. (Issue #193)
632
+
633
+ * Fix E701, E702 and E703 not detected sometimes. (Issue #196)
634
+
635
+ * Fix E122 not detected in some cases. (Issue #201 and #208)
636
+
637
+ * Fix false positive E121 with multiple brackets. (Issue #203)
638
+
639
+
640
+ 1.4.5 (2013-03-06)
641
+ ------------------
642
+
643
+ * When no path is specified, do not try to read from stdin. The feature
644
+ was added in 1.4.3, but it is not supported on Windows. Use ``-``
645
+ filename argument to read from stdin. This usage is supported
646
+ since 1.3.4. (Issue #170)
647
+
648
+ * Do not require ``setuptools`` in setup.py. It works around an issue
649
+ with ``pip`` and Python 3. (Issue #172)
650
+
651
+ * Add ``__pycache__`` to the ignore list.
652
+
653
+ * Change misleading message for E251. (Issue #171)
654
+
655
+ * Do not report false E302 when the source file has a coding cookie or a
656
+ comment on the first line. (Issue #174)
657
+
658
+ * Reorganize the tests and add tests for the API and for the command line
659
+ usage and options. (Issues #161 and #162)
660
+
661
+ * Ignore all checks which are not explicitly selected when ``select`` is
662
+ passed to the ``StyleGuide`` constructor.
663
+
664
+
665
+ 1.4.4 (2013-02-24)
666
+ ------------------
667
+
668
+ * Report E227 or E228 instead of E225 for whitespace around bitwise, shift
669
+ or modulo operators. (Issue #166)
670
+
671
+ * Change the message for E226 to make clear that it is about arithmetic
672
+ operators.
673
+
674
+ * Fix a false positive E128 for continuation line indentation with tabs.
675
+
676
+ * Fix regression with the ``--diff`` option. (Issue #169)
677
+
678
+ * Fix the ``TestReport`` class to print the unexpected warnings and
679
+ errors.
680
+
681
+
682
+ 1.4.3 (2013-02-22)
683
+ ------------------
684
+
685
+ * Hide the ``--doctest`` and ``--testsuite`` options when installed.
686
+
687
+ * Fix crash with AST checkers when the syntax is invalid. (Issue #160)
688
+
689
+ * Read from standard input if no path is specified.
690
+
691
+ * Initiate a graceful shutdown on ``Control+C``.
692
+
693
+ * Allow changing the ``checker_class`` for the ``StyleGuide``.
694
+
695
+
696
+ 1.4.2 (2013-02-10)
697
+ ------------------
698
+
699
+ * Support AST checkers provided by third-party applications.
700
+
701
+ * Register new checkers with ``register_check(func_or_cls, codes)``.
702
+
703
+ * Allow constructing a ``StyleGuide`` with a custom parser.
704
+
705
+ * Accept visual indentation without parenthesis after the ``if``
706
+ statement. (Issue #151)
707
+
708
+ * Fix UnboundLocalError when using ``# noqa`` with continued lines.
709
+ (Issue #158)
710
+
711
+ * Re-order the lines for the ``StandardReport``.
712
+
713
+ * Expand tabs when checking E12 continuation lines. (Issue #155)
714
+
715
+ * Refactor the testing class ``TestReport`` and the specific test
716
+ functions into a separate test module.
717
+
718
+
719
+ 1.4.1 (2013-01-18)
720
+ ------------------
721
+
722
+ * Allow sphinx.ext.autodoc syntax for comments. (Issue #110)
723
+
724
+ * Report E703 instead of E702 for the trailing semicolon. (Issue #117)
725
+
726
+ * Honor ``# noqa`` in addition to ``# nopep8``. (Issue #149)
727
+
728
+ * Expose the ``OptionParser`` factory for better extensibility.
729
+
730
+
731
+ 1.4 (2012-12-22)
732
+ ----------------
733
+
734
+ * Report E226 instead of E225 for optional whitespace around common
735
+ operators (``*``, ``**``, ``/``, ``+`` and ``-``). This new error
736
+ code is ignored in the default configuration because PEP 8 recommends
737
+ to "use your own judgement". (Issue #96)
738
+
739
+ * Lines with a ``# nopep8`` at the end will not issue errors on line
740
+ length E501 or continuation line indentation E12*. (Issue #27)
741
+
742
+ * Fix AssertionError when the source file contains an invalid line
743
+ ending ``"\r\r\n"``. (Issue #119)
744
+
745
+ * Read the ``[pep8]`` section of ``tox.ini`` or ``setup.cfg`` if present.
746
+ (Issue #93 and #141)
747
+
748
+ * Add the Sphinx-based documentation, and publish it
749
+ on https://pycodestyle.readthedocs.io/. (Issue #105)
750
+
751
+
752
+ 1.3.4 (2012-12-18)
753
+ ------------------
754
+
755
+ * Fix false positive E124 and E128 with comments. (Issue #100)
756
+
757
+ * Fix error on stdin when running with bpython. (Issue #101)
758
+
759
+ * Fix false positive E401. (Issue #104)
760
+
761
+ * Report E231 for nested dictionary in list. (Issue #142)
762
+
763
+ * Catch E271 at the beginning of the line. (Issue #133)
764
+
765
+ * Fix false positive E126 for multi-line comments. (Issue #138)
766
+
767
+ * Fix false positive E221 when operator is preceded by a comma. (Issue #135)
768
+
769
+ * Fix ``--diff`` failing on one-line hunk. (Issue #137)
770
+
771
+ * Fix the ``--exclude`` switch for directory paths. (Issue #111)
772
+
773
+ * Use ``-`` filename to read from standard input. (Issue #128)
774
+
775
+
776
+ 1.3.3 (2012-06-27)
777
+ ------------------
778
+
779
+ * Fix regression with continuation line checker. (Issue #98)
780
+
781
+
782
+ 1.3.2 (2012-06-26)
783
+ ------------------
784
+
785
+ * Revert to the previous behaviour for ``--show-pep8``:
786
+ do not imply ``--first``. (Issue #89)
787
+
788
+ * Add E902 for IO errors. (Issue #87)
789
+
790
+ * Fix false positive for E121, and missed E124. (Issue #92)
791
+
792
+ * Set a sensible default path for config file on Windows. (Issue #95)
793
+
794
+ * Allow ``verbose`` in the configuration file. (Issue #91)
795
+
796
+ * Show the enforced ``max-line-length`` in the error message. (Issue #86)
797
+
798
+
799
+ 1.3.1 (2012-06-18)
800
+ ------------------
801
+
802
+ * Explain which configuration options are expected. Accept and recommend
803
+ the options names with hyphen instead of underscore. (Issue #82)
804
+
805
+ * Do not read the user configuration when used as a module
806
+ (except if ``config_file=True`` is passed to the ``StyleGuide`` constructor).
807
+
808
+ * Fix wrong or missing cases for the E12 series.
809
+
810
+ * Fix cases where E122 was missed. (Issue #81)
811
+
812
+
813
+ 1.3 (2012-06-15)
814
+ ----------------
815
+
816
+ .. warning::
817
+ The internal API is backwards incompatible.
818
+
819
+ * Remove global configuration and refactor the library around
820
+ a ``StyleGuide`` class; add the ability to configure various
821
+ reporters. (Issue #35 and #66)
822
+
823
+ * Read user configuration from ``~/.config/pep8``
824
+ and local configuration from ``./.pep8``. (Issue #22)
825
+
826
+ * Fix E502 for backslash embedded in multi-line string. (Issue #68)
827
+
828
+ * Fix E225 for Python 3 iterable unpacking (PEP 3132). (Issue #72)
829
+
830
+ * Enable the new checkers from the E12 series in the default
831
+ configuration.
832
+
833
+ * Suggest less error-prone alternatives for E712 errors.
834
+
835
+ * Rewrite checkers to run faster (E22, E251, E27).
836
+
837
+ * Fixed a crash when parsed code is invalid (too many
838
+ closing brackets).
839
+
840
+ * Fix E127 and E128 for continuation line indentation. (Issue #74)
841
+
842
+ * New option ``--format`` to customize the error format. (Issue #23)
843
+
844
+ * New option ``--diff`` to check only modified code. The unified
845
+ diff is read from STDIN. Example: ``hg diff | pep8 --diff``
846
+ (Issue #39)
847
+
848
+ * Correctly report the count of failures and set the exit code to 1
849
+ when the ``--doctest`` or the ``--testsuite`` fails.
850
+
851
+ * Correctly detect the encoding in Python 3. (Issue #69)
852
+
853
+ * Drop support for Python 2.3, 2.4 and 3.0. (Issue #78)
854
+
855
+
856
+ 1.2 (2012-06-01)
857
+ ----------------
858
+
859
+ * Add E121 through E128 for continuation line indentation. These
860
+ checks are disabled by default. If you want to force all checks,
861
+ use switch ``--select=E,W``. Patch by Sam Vilain. (Issue #64)
862
+
863
+ * Add E721 for direct type comparisons. (Issue #47)
864
+
865
+ * Add E711 and E712 for comparisons to singletons. (Issue #46)
866
+
867
+ * Fix spurious E225 and E701 for function annotations. (Issue #29)
868
+
869
+ * Add E502 for explicit line join between brackets.
870
+
871
+ * Fix E901 when printing source with ``--show-source``.
872
+
873
+ * Report all errors for each checker, instead of reporting only the
874
+ first occurrence for each line.
875
+
876
+ * Option ``--show-pep8`` implies ``--first``.
877
+
878
+
879
+ 1.1 (2012-05-24)
880
+ ----------------
881
+
882
+ * Add E901 for syntax errors. (Issues #63 and #30)
883
+
884
+ * Add E271, E272, E273 and E274 for extraneous whitespace around
885
+ keywords. (Issue #57)
886
+
887
+ * Add ``tox.ini`` configuration file for tests. (Issue #61)
888
+
889
+ * Add ``.travis.yml`` configuration file for continuous integration.
890
+ (Issue #62)
891
+
892
+
893
+ 1.0.1 (2012-04-06)
894
+ ------------------
895
+
896
+ * Fix inconsistent version numbers.
897
+
898
+
899
+ 1.0 (2012-04-04)
900
+ ----------------
901
+
902
+ * Fix W602 ``raise`` to handle multi-char names. (Issue #53)
903
+
904
+
905
+ 0.7.0 (2012-03-26)
906
+ ------------------
907
+
908
+ * Now ``--first`` prints only the first occurrence of each error.
909
+ The ``--repeat`` flag becomes obsolete because it is the default
910
+ behaviour. (Issue #6)
911
+
912
+ * Allow specifying ``--max-line-length``. (Issue #36)
913
+
914
+ * Make the shebang more flexible. (Issue #26)
915
+
916
+ * Add testsuite to the bundle. (Issue #25)
917
+
918
+ * Fixes for Jython. (Issue #49)
919
+
920
+ * Add PyPI classifiers. (Issue #43)
921
+
922
+ * Fix the ``--exclude`` option. (Issue #48)
923
+
924
+ * Fix W602, accept ``raise`` with 3 arguments. (Issue #34)
925
+
926
+ * Correctly select all tests if ``DEFAULT_IGNORE == ''``.
927
+
928
+
929
+ 0.6.1 (2010-10-03)
930
+ ------------------
931
+
932
+ * Fix inconsistent version numbers. (Issue #21)
933
+
934
+
935
+ 0.6.0 (2010-09-19)
936
+ ------------------
937
+
938
+ * Test suite reorganized and enhanced in order to check more failures
939
+ with fewer test files. Read the ``run_tests`` docstring for details
940
+ about the syntax.
941
+
942
+ * Fix E225: accept ``print >>sys.stderr, "..."`` syntax.
943
+
944
+ * Fix E501 for lines containing multibyte encoded characters. (Issue #7)
945
+
946
+ * Fix E221, E222, E223, E224 not detected in some cases. (Issue #16)
947
+
948
+ * Fix E211 to reject ``v = dic['a'] ['b']``. (Issue #17)
949
+
950
+ * Exit code is always 1 if any error or warning is found. (Issue #10)
951
+
952
+ * ``--ignore`` checks are now really ignored, especially in
953
+ conjunction with ``--count``. (Issue #8)
954
+
955
+ * Blank lines with spaces yield W293 instead of W291: some developers
956
+ want to ignore this warning and indent the blank lines to paste their
957
+ code easily in the Python interpreter.
958
+
959
+ * Fix E301: do not require a blank line before an indented block. (Issue #14)
960
+
961
+ * Fix E203 to accept NumPy slice notation ``a[0, :]``. (Issue #13)
962
+
963
+ * Performance improvements.
964
+
965
+ * Fix decoding and checking non-UTF8 files in Python 3.
966
+
967
+ * Fix E225: reject ``True+False`` when running on Python 3.
968
+
969
+ * Fix an exception when the line starts with an operator.
970
+
971
+ * Allow a new line before closing ``)``, ``}`` or ``]``. (Issue #5)
972
+
973
+
974
+ 0.5.0 (2010-02-17)
975
+ ------------------
976
+
977
+ * Changed the ``--count`` switch to print to sys.stderr and set
978
+ exit code to 1 if any error or warning is found.
979
+
980
+ * E241 and E242 are removed from the standard checks. If you want to
981
+ include these checks, use switch ``--select=E,W``. (Issue #4)
982
+
983
+ * Blank line is not mandatory before the first class method or nested
984
+ function definition, even if there's a docstring. (Issue #1)
985
+
986
+ * Add the switch ``--version``.
987
+
988
+ * Fix decoding errors with Python 3. (Issue #13 [1]_)
989
+
990
+ * Add ``--select`` option which is mirror of ``--ignore``.
991
+
992
+ * Add checks E261 and E262 for spaces before inline comments.
993
+
994
+ * New check W604 warns about deprecated usage of backticks.
995
+
996
+ * New check W603 warns about the deprecated operator ``<>``.
997
+
998
+ * Performance improvement, due to rewriting of E225.
999
+
1000
+ * E225 now accepts:
1001
+
1002
+ - no whitespace after unary operator or similar. (Issue #9 [1]_)
1003
+
1004
+ - lambda function with argument unpacking or keyword defaults.
1005
+
1006
+ * Reserve "2 blank lines" for module-level logical blocks. (E303)
1007
+
1008
+ * Allow multi-line comments. (E302, issue #10 [1]_)
1009
+
1010
+
1011
+ 0.4.2 (2009-10-22)
1012
+ ------------------
1013
+
1014
+ * Decorators on classes and class methods are OK now.
1015
+
1016
+
1017
+ 0.4 (2009-10-20)
1018
+ ----------------
1019
+
1020
+ * Support for all versions of Python from 2.3 to 3.1.
1021
+
1022
+ * New and greatly expanded self tests.
1023
+
1024
+ * Added ``--count`` option to print the total number of errors and warnings.
1025
+
1026
+ * Further improvements to the handling of comments and blank lines.
1027
+ (Issue #1 [1]_ and others changes.)
1028
+
1029
+ * Check all py files in directory when passed a directory (Issue
1030
+ #2 [1]_). This also prevents an exception when traversing directories
1031
+ with non ``*.py`` files.
1032
+
1033
+ * E231 should allow commas to be followed by ``)``. (Issue #3 [1]_)
1034
+
1035
+ * Spaces are no longer required around the equals sign for keyword
1036
+ arguments or default parameter values.
1037
+
1038
+
1039
+ .. [1] These issues refer to the `previous issue tracker`__.
1040
+ .. __: http://github.com/cburroughs/pep8.py/issues
1041
+
1042
+
1043
+ 0.3.1 (2009-09-14)
1044
+ ------------------
1045
+
1046
+ * Fixes for comments: do not count them when checking for blank lines between
1047
+ items.
1048
+
1049
+ * Added setup.py for pypi upload and easy_installability.
1050
+
1051
+
1052
+ 0.2 (2007-10-16)
1053
+ ----------------
1054
+
1055
+ * Loads of fixes and improvements.
1056
+
1057
+
1058
+ 0.1 (2006-10-01)
1059
+ ----------------
1060
+
1061
+ * First release.
1062
+
1063
+
my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/pycodestyle-2.8.0.dist-info/RECORD ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ../../../bin/pycodestyle,sha256=YqpyFg8K_Q6SXk7DJ80K4Q6wKmZU1G06Ti8XKbcJwAA,230
2
+ __pycache__/pycodestyle.cpython-38.pyc,,
3
+ pycodestyle-2.8.0.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4
4
+ pycodestyle-2.8.0.dist-info/LICENSE,sha256=93IpXoGvNHjTTojlLQdiACMOx91qOeEjvFyzWqZqva4,1254
5
+ pycodestyle-2.8.0.dist-info/METADATA,sha256=jLxHgy1ywol0Yu2cxoVLIw4XMOlUaUUDZijfTUFV2uY,31230
6
+ pycodestyle-2.8.0.dist-info/RECORD,,
7
+ pycodestyle-2.8.0.dist-info/REQUESTED,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
8
+ pycodestyle-2.8.0.dist-info/WHEEL,sha256=WzZ8cwjh8l0jtULNjYq1Hpr-WCqCRgPr--TX4P5I1Wo,110
9
+ pycodestyle-2.8.0.dist-info/entry_points.txt,sha256=6JU_7SAppC93MBSQi1_QxDwEQUyg6cgK71ab9q_Hxco,51
10
+ pycodestyle-2.8.0.dist-info/namespace_packages.txt,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
11
+ pycodestyle-2.8.0.dist-info/top_level.txt,sha256=rHbIEiXmvsJ016mFcLVcF_d-dKgP3VdfOB6CWbivZug,12
12
+ pycodestyle.py,sha256=3-O2ixYLkFoim3-EN1XLtHL2-oJafe6BQKrY2nbkrA4,105016
my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/pycodestyle-2.8.0.dist-info/REQUESTED ADDED
File without changes
my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/pycodestyle-2.8.0.dist-info/WHEEL ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ Wheel-Version: 1.0
2
+ Generator: bdist_wheel (0.37.0)
3
+ Root-Is-Purelib: true
4
+ Tag: py2-none-any
5
+ Tag: py3-none-any
6
+
my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/pycodestyle-2.8.0.dist-info/entry_points.txt ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ [console_scripts]
2
+ pycodestyle = pycodestyle:_main
3
+
my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/pycodestyle-2.8.0.dist-info/namespace_packages.txt ADDED
@@ -0,0 +1 @@
 
 
1
+
my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/pycodestyle-2.8.0.dist-info/top_level.txt ADDED
@@ -0,0 +1 @@
 
 
1
+ pycodestyle
my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/requests/__init__.py ADDED
@@ -0,0 +1,180 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # __
2
+ # /__) _ _ _ _ _/ _
3
+ # / ( (- (/ (/ (- _) / _)
4
+ # /
5
+
6
+ """
7
+ Requests HTTP Library
8
+ ~~~~~~~~~~~~~~~~~~~~~
9
+
10
+ Requests is an HTTP library, written in Python, for human beings.
11
+ Basic GET usage:
12
+
13
+ >>> import requests
14
+ >>> r = requests.get('https://www.python.org')
15
+ >>> r.status_code
16
+ 200
17
+ >>> b'Python is a programming language' in r.content
18
+ True
19
+
20
+ ... or POST:
21
+
22
+ >>> payload = dict(key1='value1', key2='value2')
23
+ >>> r = requests.post('https://httpbin.org/post', data=payload)
24
+ >>> print(r.text)
25
+ {
26
+ ...
27
+ "form": {
28
+ "key1": "value1",
29
+ "key2": "value2"
30
+ },
31
+ ...
32
+ }
33
+
34
+ The other HTTP methods are supported - see `requests.api`. Full documentation
35
+ is at <https://requests.readthedocs.io>.
36
+
37
+ :copyright: (c) 2017 by Kenneth Reitz.
38
+ :license: Apache 2.0, see LICENSE for more details.
39
+ """
40
+
41
+ import warnings
42
+
43
+ import urllib3
44
+
45
+ from .exceptions import RequestsDependencyWarning
46
+
47
+ try:
48
+ from charset_normalizer import __version__ as charset_normalizer_version
49
+ except ImportError:
50
+ charset_normalizer_version = None
51
+
52
+ try:
53
+ from chardet import __version__ as chardet_version
54
+ except ImportError:
55
+ chardet_version = None
56
+
57
+
58
+ def check_compatibility(urllib3_version, chardet_version, charset_normalizer_version):
59
+ urllib3_version = urllib3_version.split(".")
60
+ assert urllib3_version != ["dev"] # Verify urllib3 isn't installed from git.
61
+
62
+ # Sometimes, urllib3 only reports its version as 16.1.
63
+ if len(urllib3_version) == 2:
64
+ urllib3_version.append("0")
65
+
66
+ # Check urllib3 for compatibility.
67
+ major, minor, patch = urllib3_version # noqa: F811
68
+ major, minor, patch = int(major), int(minor), int(patch)
69
+ # urllib3 >= 1.21.1, <= 1.26
70
+ assert major == 1
71
+ assert minor >= 21
72
+ assert minor <= 26
73
+
74
+ # Check charset_normalizer for compatibility.
75
+ if chardet_version:
76
+ major, minor, patch = chardet_version.split(".")[:3]
77
+ major, minor, patch = int(major), int(minor), int(patch)
78
+ # chardet_version >= 3.0.2, < 5.0.0
79
+ assert (3, 0, 2) <= (major, minor, patch) < (5, 0, 0)
80
+ elif charset_normalizer_version:
81
+ major, minor, patch = charset_normalizer_version.split(".")[:3]
82
+ major, minor, patch = int(major), int(minor), int(patch)
83
+ # charset_normalizer >= 2.0.0 < 3.0.0
84
+ assert (2, 0, 0) <= (major, minor, patch) < (3, 0, 0)
85
+ else:
86
+ raise Exception("You need either charset_normalizer or chardet installed")
87
+
88
+
89
+ def _check_cryptography(cryptography_version):
90
+ # cryptography < 1.3.4
91
+ try:
92
+ cryptography_version = list(map(int, cryptography_version.split(".")))
93
+ except ValueError:
94
+ return
95
+
96
+ if cryptography_version < [1, 3, 4]:
97
+ warning = "Old version of cryptography ({}) may cause slowdown.".format(
98
+ cryptography_version
99
+ )
100
+ warnings.warn(warning, RequestsDependencyWarning)
101
+
102
+
103
+ # Check imported dependencies for compatibility.
104
+ try:
105
+ check_compatibility(
106
+ urllib3.__version__, chardet_version, charset_normalizer_version
107
+ )
108
+ except (AssertionError, ValueError):
109
+ warnings.warn(
110
+ "urllib3 ({}) or chardet ({})/charset_normalizer ({}) doesn't match a supported "
111
+ "version!".format(
112
+ urllib3.__version__, chardet_version, charset_normalizer_version
113
+ ),
114
+ RequestsDependencyWarning,
115
+ )
116
+
117
+ # Attempt to enable urllib3's fallback for SNI support
118
+ # if the standard library doesn't support SNI or the
119
+ # 'ssl' library isn't available.
120
+ try:
121
+ try:
122
+ import ssl
123
+ except ImportError:
124
+ ssl = None
125
+
126
+ if not getattr(ssl, "HAS_SNI", False):
127
+ from urllib3.contrib import pyopenssl
128
+
129
+ pyopenssl.inject_into_urllib3()
130
+
131
+ # Check cryptography version
132
+ from cryptography import __version__ as cryptography_version
133
+
134
+ _check_cryptography(cryptography_version)
135
+ except ImportError:
136
+ pass
137
+
138
+ # urllib3's DependencyWarnings should be silenced.
139
+ from urllib3.exceptions import DependencyWarning
140
+
141
+ warnings.simplefilter("ignore", DependencyWarning)
142
+
143
+ # Set default logging handler to avoid "No handler found" warnings.
144
+ import logging
145
+ from logging import NullHandler
146
+
147
+ from . import packages, utils
148
+ from .__version__ import (
149
+ __author__,
150
+ __author_email__,
151
+ __build__,
152
+ __cake__,
153
+ __copyright__,
154
+ __description__,
155
+ __license__,
156
+ __title__,
157
+ __url__,
158
+ __version__,
159
+ )
160
+ from .api import delete, get, head, options, patch, post, put, request
161
+ from .exceptions import (
162
+ ConnectionError,
163
+ ConnectTimeout,
164
+ FileModeWarning,
165
+ HTTPError,
166
+ JSONDecodeError,
167
+ ReadTimeout,
168
+ RequestException,
169
+ Timeout,
170
+ TooManyRedirects,
171
+ URLRequired,
172
+ )
173
+ from .models import PreparedRequest, Request, Response
174
+ from .sessions import Session, session
175
+ from .status_codes import codes
176
+
177
+ logging.getLogger(__name__).addHandler(NullHandler())
178
+
179
+ # FileModeWarnings go off per the default.
180
+ warnings.simplefilter("default", FileModeWarning, append=True)
my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/requests/__version__.py ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # .-. .-. .-. . . .-. .-. .-. .-.
2
+ # |( |- |.| | | |- `-. | `-.
3
+ # ' ' `-' `-`.`-' `-' `-' ' `-'
4
+
5
+ __title__ = "requests"
6
+ __description__ = "Python HTTP for Humans."
7
+ __url__ = "https://requests.readthedocs.io"
8
+ __version__ = "2.28.0"
9
+ __build__ = 0x022800
10
+ __author__ = "Kenneth Reitz"
11
+ __author_email__ = "me@kennethreitz.org"
12
+ __license__ = "Apache 2.0"
13
+ __copyright__ = "Copyright 2022 Kenneth Reitz"
14
+ __cake__ = "\u2728 \U0001f370 \u2728"
my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/requests/_internal_utils.py ADDED
@@ -0,0 +1,48 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ requests._internal_utils
3
+ ~~~~~~~~~~~~~~
4
+
5
+ Provides utility functions that are consumed internally by Requests
6
+ which depend on extremely few external helpers (such as compat)
7
+ """
8
+ import re
9
+
10
+ from .compat import builtin_str
11
+
12
+ _VALID_HEADER_NAME_RE_BYTE = re.compile(rb"^[^:\s][^:\r\n]*$")
13
+ _VALID_HEADER_NAME_RE_STR = re.compile(r"^[^:\s][^:\r\n]*$")
14
+ _VALID_HEADER_VALUE_RE_BYTE = re.compile(rb"^\S[^\r\n]*$|^$")
15
+ _VALID_HEADER_VALUE_RE_STR = re.compile(r"^\S[^\r\n]*$|^$")
16
+
17
+ HEADER_VALIDATORS = {
18
+ bytes: (_VALID_HEADER_NAME_RE_BYTE, _VALID_HEADER_VALUE_RE_BYTE),
19
+ str: (_VALID_HEADER_NAME_RE_STR, _VALID_HEADER_VALUE_RE_STR),
20
+ }
21
+
22
+
23
+ def to_native_string(string, encoding="ascii"):
24
+ """Given a string object, regardless of type, returns a representation of
25
+ that string in the native string type, encoding and decoding where
26
+ necessary. This assumes ASCII unless told otherwise.
27
+ """
28
+ if isinstance(string, builtin_str):
29
+ out = string
30
+ else:
31
+ out = string.decode(encoding)
32
+
33
+ return out
34
+
35
+
36
+ def unicode_is_ascii(u_string):
37
+ """Determine if unicode string only contains ASCII characters.
38
+
39
+ :param str u_string: unicode string to check. Must be unicode
40
+ and not Python 2 `str`.
41
+ :rtype: bool
42
+ """
43
+ assert isinstance(u_string, str)
44
+ try:
45
+ u_string.encode("ascii")
46
+ return True
47
+ except UnicodeEncodeError:
48
+ return False
my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/requests/adapters.py ADDED
@@ -0,0 +1,584 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ requests.adapters
3
+ ~~~~~~~~~~~~~~~~~
4
+
5
+ This module contains the transport adapters that Requests uses to define
6
+ and maintain connections.
7
+ """
8
+
9
+ import os.path
10
+ import socket # noqa: F401
11
+
12
+ from urllib3.exceptions import ClosedPoolError, ConnectTimeoutError
13
+ from urllib3.exceptions import HTTPError as _HTTPError
14
+ from urllib3.exceptions import InvalidHeader as _InvalidHeader
15
+ from urllib3.exceptions import (
16
+ LocationValueError,
17
+ MaxRetryError,
18
+ NewConnectionError,
19
+ ProtocolError,
20
+ )
21
+ from urllib3.exceptions import ProxyError as _ProxyError
22
+ from urllib3.exceptions import ReadTimeoutError, ResponseError
23
+ from urllib3.exceptions import SSLError as _SSLError
24
+ from urllib3.poolmanager import PoolManager, proxy_from_url
25
+ from urllib3.response import HTTPResponse
26
+ from urllib3.util import Timeout as TimeoutSauce
27
+ from urllib3.util import parse_url
28
+ from urllib3.util.retry import Retry
29
+
30
+ from .auth import _basic_auth_str
31
+ from .compat import basestring, urlparse
32
+ from .cookies import extract_cookies_to_jar
33
+ from .exceptions import (
34
+ ConnectionError,
35
+ ConnectTimeout,
36
+ InvalidHeader,
37
+ InvalidProxyURL,
38
+ InvalidSchema,
39
+ InvalidURL,
40
+ ProxyError,
41
+ ReadTimeout,
42
+ RetryError,
43
+ SSLError,
44
+ )
45
+ from .models import Response
46
+ from .structures import CaseInsensitiveDict
47
+ from .utils import (
48
+ DEFAULT_CA_BUNDLE_PATH,
49
+ extract_zipped_paths,
50
+ get_auth_from_url,
51
+ get_encoding_from_headers,
52
+ prepend_scheme_if_needed,
53
+ select_proxy,
54
+ urldefragauth,
55
+ )
56
+
57
+ try:
58
+ from urllib3.contrib.socks import SOCKSProxyManager
59
+ except ImportError:
60
+
61
+ def SOCKSProxyManager(*args, **kwargs):
62
+ raise InvalidSchema("Missing dependencies for SOCKS support.")
63
+
64
+
65
+ DEFAULT_POOLBLOCK = False
66
+ DEFAULT_POOLSIZE = 10
67
+ DEFAULT_RETRIES = 0
68
+ DEFAULT_POOL_TIMEOUT = None
69
+
70
+
71
+ class BaseAdapter:
72
+ """The Base Transport Adapter"""
73
+
74
+ def __init__(self):
75
+ super().__init__()
76
+
77
+ def send(
78
+ self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None
79
+ ):
80
+ """Sends PreparedRequest object. Returns Response object.
81
+
82
+ :param request: The :class:`PreparedRequest <PreparedRequest>` being sent.
83
+ :param stream: (optional) Whether to stream the request content.
84
+ :param timeout: (optional) How long to wait for the server to send
85
+ data before giving up, as a float, or a :ref:`(connect timeout,
86
+ read timeout) <timeouts>` tuple.
87
+ :type timeout: float or tuple
88
+ :param verify: (optional) Either a boolean, in which case it controls whether we verify
89
+ the server's TLS certificate, or a string, in which case it must be a path
90
+ to a CA bundle to use
91
+ :param cert: (optional) Any user-provided SSL certificate to be trusted.
92
+ :param proxies: (optional) The proxies dictionary to apply to the request.
93
+ """
94
+ raise NotImplementedError
95
+
96
+ def close(self):
97
+ """Cleans up adapter specific items."""
98
+ raise NotImplementedError
99
+
100
+
101
+ class HTTPAdapter(BaseAdapter):
102
+ """The built-in HTTP Adapter for urllib3.
103
+
104
+ Provides a general-case interface for Requests sessions to contact HTTP and
105
+ HTTPS urls by implementing the Transport Adapter interface. This class will
106
+ usually be created by the :class:`Session <Session>` class under the
107
+ covers.
108
+
109
+ :param pool_connections: The number of urllib3 connection pools to cache.
110
+ :param pool_maxsize: The maximum number of connections to save in the pool.
111
+ :param max_retries: The maximum number of retries each connection
112
+ should attempt. Note, this applies only to failed DNS lookups, socket
113
+ connections and connection timeouts, never to requests where data has
114
+ made it to the server. By default, Requests does not retry failed
115
+ connections. If you need granular control over the conditions under
116
+ which we retry a request, import urllib3's ``Retry`` class and pass
117
+ that instead.
118
+ :param pool_block: Whether the connection pool should block for connections.
119
+
120
+ Usage::
121
+
122
+ >>> import requests
123
+ >>> s = requests.Session()
124
+ >>> a = requests.adapters.HTTPAdapter(max_retries=3)
125
+ >>> s.mount('http://', a)
126
+ """
127
+
128
+ __attrs__ = [
129
+ "max_retries",
130
+ "config",
131
+ "_pool_connections",
132
+ "_pool_maxsize",
133
+ "_pool_block",
134
+ ]
135
+
136
+ def __init__(
137
+ self,
138
+ pool_connections=DEFAULT_POOLSIZE,
139
+ pool_maxsize=DEFAULT_POOLSIZE,
140
+ max_retries=DEFAULT_RETRIES,
141
+ pool_block=DEFAULT_POOLBLOCK,
142
+ ):
143
+ if max_retries == DEFAULT_RETRIES:
144
+ self.max_retries = Retry(0, read=False)
145
+ else:
146
+ self.max_retries = Retry.from_int(max_retries)
147
+ self.config = {}
148
+ self.proxy_manager = {}
149
+
150
+ super().__init__()
151
+
152
+ self._pool_connections = pool_connections
153
+ self._pool_maxsize = pool_maxsize
154
+ self._pool_block = pool_block
155
+
156
+ self.init_poolmanager(pool_connections, pool_maxsize, block=pool_block)
157
+
158
+ def __getstate__(self):
159
+ return {attr: getattr(self, attr, None) for attr in self.__attrs__}
160
+
161
+ def __setstate__(self, state):
162
+ # Can't handle by adding 'proxy_manager' to self.__attrs__ because
163
+ # self.poolmanager uses a lambda function, which isn't pickleable.
164
+ self.proxy_manager = {}
165
+ self.config = {}
166
+
167
+ for attr, value in state.items():
168
+ setattr(self, attr, value)
169
+
170
+ self.init_poolmanager(
171
+ self._pool_connections, self._pool_maxsize, block=self._pool_block
172
+ )
173
+
174
+ def init_poolmanager(
175
+ self, connections, maxsize, block=DEFAULT_POOLBLOCK, **pool_kwargs
176
+ ):
177
+ """Initializes a urllib3 PoolManager.
178
+
179
+ This method should not be called from user code, and is only
180
+ exposed for use when subclassing the
181
+ :class:`HTTPAdapter <requests.adapters.HTTPAdapter>`.
182
+
183
+ :param connections: The number of urllib3 connection pools to cache.
184
+ :param maxsize: The maximum number of connections to save in the pool.
185
+ :param block: Block when no free connections are available.
186
+ :param pool_kwargs: Extra keyword arguments used to initialize the Pool Manager.
187
+ """
188
+ # save these values for pickling
189
+ self._pool_connections = connections
190
+ self._pool_maxsize = maxsize
191
+ self._pool_block = block
192
+
193
+ self.poolmanager = PoolManager(
194
+ num_pools=connections,
195
+ maxsize=maxsize,
196
+ block=block,
197
+ strict=True,
198
+ **pool_kwargs,
199
+ )
200
+
201
+ def proxy_manager_for(self, proxy, **proxy_kwargs):
202
+ """Return urllib3 ProxyManager for the given proxy.
203
+
204
+ This method should not be called from user code, and is only
205
+ exposed for use when subclassing the
206
+ :class:`HTTPAdapter <requests.adapters.HTTPAdapter>`.
207
+
208
+ :param proxy: The proxy to return a urllib3 ProxyManager for.
209
+ :param proxy_kwargs: Extra keyword arguments used to configure the Proxy Manager.
210
+ :returns: ProxyManager
211
+ :rtype: urllib3.ProxyManager
212
+ """
213
+ if proxy in self.proxy_manager:
214
+ manager = self.proxy_manager[proxy]
215
+ elif proxy.lower().startswith("socks"):
216
+ username, password = get_auth_from_url(proxy)
217
+ manager = self.proxy_manager[proxy] = SOCKSProxyManager(
218
+ proxy,
219
+ username=username,
220
+ password=password,
221
+ num_pools=self._pool_connections,
222
+ maxsize=self._pool_maxsize,
223
+ block=self._pool_block,
224
+ **proxy_kwargs,
225
+ )
226
+ else:
227
+ proxy_headers = self.proxy_headers(proxy)
228
+ manager = self.proxy_manager[proxy] = proxy_from_url(
229
+ proxy,
230
+ proxy_headers=proxy_headers,
231
+ num_pools=self._pool_connections,
232
+ maxsize=self._pool_maxsize,
233
+ block=self._pool_block,
234
+ **proxy_kwargs,
235
+ )
236
+
237
+ return manager
238
+
239
+ def cert_verify(self, conn, url, verify, cert):
240
+ """Verify a SSL certificate. This method should not be called from user
241
+ code, and is only exposed for use when subclassing the
242
+ :class:`HTTPAdapter <requests.adapters.HTTPAdapter>`.
243
+
244
+ :param conn: The urllib3 connection object associated with the cert.
245
+ :param url: The requested URL.
246
+ :param verify: Either a boolean, in which case it controls whether we verify
247
+ the server's TLS certificate, or a string, in which case it must be a path
248
+ to a CA bundle to use
249
+ :param cert: The SSL certificate to verify.
250
+ """
251
+ if url.lower().startswith("https") and verify:
252
+
253
+ cert_loc = None
254
+
255
+ # Allow self-specified cert location.
256
+ if verify is not True:
257
+ cert_loc = verify
258
+
259
+ if not cert_loc:
260
+ cert_loc = extract_zipped_paths(DEFAULT_CA_BUNDLE_PATH)
261
+
262
+ if not cert_loc or not os.path.exists(cert_loc):
263
+ raise OSError(
264
+ f"Could not find a suitable TLS CA certificate bundle, "
265
+ f"invalid path: {cert_loc}"
266
+ )
267
+
268
+ conn.cert_reqs = "CERT_REQUIRED"
269
+
270
+ if not os.path.isdir(cert_loc):
271
+ conn.ca_certs = cert_loc
272
+ else:
273
+ conn.ca_cert_dir = cert_loc
274
+ else:
275
+ conn.cert_reqs = "CERT_NONE"
276
+ conn.ca_certs = None
277
+ conn.ca_cert_dir = None
278
+
279
+ if cert:
280
+ if not isinstance(cert, basestring):
281
+ conn.cert_file = cert[0]
282
+ conn.key_file = cert[1]
283
+ else:
284
+ conn.cert_file = cert
285
+ conn.key_file = None
286
+ if conn.cert_file and not os.path.exists(conn.cert_file):
287
+ raise OSError(
288
+ f"Could not find the TLS certificate file, "
289
+ f"invalid path: {conn.cert_file}"
290
+ )
291
+ if conn.key_file and not os.path.exists(conn.key_file):
292
+ raise OSError(
293
+ f"Could not find the TLS key file, invalid path: {conn.key_file}"
294
+ )
295
+
296
+ def build_response(self, req, resp):
297
+ """Builds a :class:`Response <requests.Response>` object from a urllib3
298
+ response. This should not be called from user code, and is only exposed
299
+ for use when subclassing the
300
+ :class:`HTTPAdapter <requests.adapters.HTTPAdapter>`
301
+
302
+ :param req: The :class:`PreparedRequest <PreparedRequest>` used to generate the response.
303
+ :param resp: The urllib3 response object.
304
+ :rtype: requests.Response
305
+ """
306
+ response = Response()
307
+
308
+ # Fallback to None if there's no status_code, for whatever reason.
309
+ response.status_code = getattr(resp, "status", None)
310
+
311
+ # Make headers case-insensitive.
312
+ response.headers = CaseInsensitiveDict(getattr(resp, "headers", {}))
313
+
314
+ # Set encoding.
315
+ response.encoding = get_encoding_from_headers(response.headers)
316
+ response.raw = resp
317
+ response.reason = response.raw.reason
318
+
319
+ if isinstance(req.url, bytes):
320
+ response.url = req.url.decode("utf-8")
321
+ else:
322
+ response.url = req.url
323
+
324
+ # Add new cookies from the server.
325
+ extract_cookies_to_jar(response.cookies, req, resp)
326
+
327
+ # Give the Response some context.
328
+ response.request = req
329
+ response.connection = self
330
+
331
+ return response
332
+
333
+ def get_connection(self, url, proxies=None):
334
+ """Returns a urllib3 connection for the given URL. This should not be
335
+ called from user code, and is only exposed for use when subclassing the
336
+ :class:`HTTPAdapter <requests.adapters.HTTPAdapter>`.
337
+
338
+ :param url: The URL to connect to.
339
+ :param proxies: (optional) A Requests-style dictionary of proxies used on this request.
340
+ :rtype: urllib3.ConnectionPool
341
+ """
342
+ proxy = select_proxy(url, proxies)
343
+
344
+ if proxy:
345
+ proxy = prepend_scheme_if_needed(proxy, "http")
346
+ proxy_url = parse_url(proxy)
347
+ if not proxy_url.host:
348
+ raise InvalidProxyURL(
349
+ "Please check proxy URL. It is malformed "
350
+ "and could be missing the host."
351
+ )
352
+ proxy_manager = self.proxy_manager_for(proxy)
353
+ conn = proxy_manager.connection_from_url(url)
354
+ else:
355
+ # Only scheme should be lower case
356
+ parsed = urlparse(url)
357
+ url = parsed.geturl()
358
+ conn = self.poolmanager.connection_from_url(url)
359
+
360
+ return conn
361
+
362
+ def close(self):
363
+ """Disposes of any internal state.
364
+
365
+ Currently, this closes the PoolManager and any active ProxyManager,
366
+ which closes any pooled connections.
367
+ """
368
+ self.poolmanager.clear()
369
+ for proxy in self.proxy_manager.values():
370
+ proxy.clear()
371
+
372
+ def request_url(self, request, proxies):
373
+ """Obtain the url to use when making the final request.
374
+
375
+ If the message is being sent through a HTTP proxy, the full URL has to
376
+ be used. Otherwise, we should only use the path portion of the URL.
377
+
378
+ This should not be called from user code, and is only exposed for use
379
+ when subclassing the
380
+ :class:`HTTPAdapter <requests.adapters.HTTPAdapter>`.
381
+
382
+ :param request: The :class:`PreparedRequest <PreparedRequest>` being sent.
383
+ :param proxies: A dictionary of schemes or schemes and hosts to proxy URLs.
384
+ :rtype: str
385
+ """
386
+ proxy = select_proxy(request.url, proxies)
387
+ scheme = urlparse(request.url).scheme
388
+
389
+ is_proxied_http_request = proxy and scheme != "https"
390
+ using_socks_proxy = False
391
+ if proxy:
392
+ proxy_scheme = urlparse(proxy).scheme.lower()
393
+ using_socks_proxy = proxy_scheme.startswith("socks")
394
+
395
+ url = request.path_url
396
+ if is_proxied_http_request and not using_socks_proxy:
397
+ url = urldefragauth(request.url)
398
+
399
+ return url
400
+
401
+ def add_headers(self, request, **kwargs):
402
+ """Add any headers needed by the connection. As of v2.0 this does
403
+ nothing by default, but is left for overriding by users that subclass
404
+ the :class:`HTTPAdapter <requests.adapters.HTTPAdapter>`.
405
+
406
+ This should not be called from user code, and is only exposed for use
407
+ when subclassing the
408
+ :class:`HTTPAdapter <requests.adapters.HTTPAdapter>`.
409
+
410
+ :param request: The :class:`PreparedRequest <PreparedRequest>` to add headers to.
411
+ :param kwargs: The keyword arguments from the call to send().
412
+ """
413
+ pass
414
+
415
+ def proxy_headers(self, proxy):
416
+ """Returns a dictionary of the headers to add to any request sent
417
+ through a proxy. This works with urllib3 magic to ensure that they are
418
+ correctly sent to the proxy, rather than in a tunnelled request if
419
+ CONNECT is being used.
420
+
421
+ This should not be called from user code, and is only exposed for use
422
+ when subclassing the
423
+ :class:`HTTPAdapter <requests.adapters.HTTPAdapter>`.
424
+
425
+ :param proxy: The url of the proxy being used for this request.
426
+ :rtype: dict
427
+ """
428
+ headers = {}
429
+ username, password = get_auth_from_url(proxy)
430
+
431
+ if username:
432
+ headers["Proxy-Authorization"] = _basic_auth_str(username, password)
433
+
434
+ return headers
435
+
436
+ def send(
437
+ self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None
438
+ ):
439
+ """Sends PreparedRequest object. Returns Response object.
440
+
441
+ :param request: The :class:`PreparedRequest <PreparedRequest>` being sent.
442
+ :param stream: (optional) Whether to stream the request content.
443
+ :param timeout: (optional) How long to wait for the server to send
444
+ data before giving up, as a float, or a :ref:`(connect timeout,
445
+ read timeout) <timeouts>` tuple.
446
+ :type timeout: float or tuple or urllib3 Timeout object
447
+ :param verify: (optional) Either a boolean, in which case it controls whether
448
+ we verify the server's TLS certificate, or a string, in which case it
449
+ must be a path to a CA bundle to use
450
+ :param cert: (optional) Any user-provided SSL certificate to be trusted.
451
+ :param proxies: (optional) The proxies dictionary to apply to the request.
452
+ :rtype: requests.Response
453
+ """
454
+
455
+ try:
456
+ conn = self.get_connection(request.url, proxies)
457
+ except LocationValueError as e:
458
+ raise InvalidURL(e, request=request)
459
+
460
+ self.cert_verify(conn, request.url, verify, cert)
461
+ url = self.request_url(request, proxies)
462
+ self.add_headers(
463
+ request,
464
+ stream=stream,
465
+ timeout=timeout,
466
+ verify=verify,
467
+ cert=cert,
468
+ proxies=proxies,
469
+ )
470
+
471
+ chunked = not (request.body is None or "Content-Length" in request.headers)
472
+
473
+ if isinstance(timeout, tuple):
474
+ try:
475
+ connect, read = timeout
476
+ timeout = TimeoutSauce(connect=connect, read=read)
477
+ except ValueError:
478
+ raise ValueError(
479
+ f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, "
480
+ f"or a single float to set both timeouts to the same value."
481
+ )
482
+ elif isinstance(timeout, TimeoutSauce):
483
+ pass
484
+ else:
485
+ timeout = TimeoutSauce(connect=timeout, read=timeout)
486
+
487
+ try:
488
+ if not chunked:
489
+ resp = conn.urlopen(
490
+ method=request.method,
491
+ url=url,
492
+ body=request.body,
493
+ headers=request.headers,
494
+ redirect=False,
495
+ assert_same_host=False,
496
+ preload_content=False,
497
+ decode_content=False,
498
+ retries=self.max_retries,
499
+ timeout=timeout,
500
+ )
501
+
502
+ # Send the request.
503
+ else:
504
+ if hasattr(conn, "proxy_pool"):
505
+ conn = conn.proxy_pool
506
+
507
+ low_conn = conn._get_conn(timeout=DEFAULT_POOL_TIMEOUT)
508
+
509
+ try:
510
+ skip_host = "Host" in request.headers
511
+ low_conn.putrequest(
512
+ request.method,
513
+ url,
514
+ skip_accept_encoding=True,
515
+ skip_host=skip_host,
516
+ )
517
+
518
+ for header, value in request.headers.items():
519
+ low_conn.putheader(header, value)
520
+
521
+ low_conn.endheaders()
522
+
523
+ for i in request.body:
524
+ low_conn.send(hex(len(i))[2:].encode("utf-8"))
525
+ low_conn.send(b"\r\n")
526
+ low_conn.send(i)
527
+ low_conn.send(b"\r\n")
528
+ low_conn.send(b"0\r\n\r\n")
529
+
530
+ # Receive the response from the server
531
+ r = low_conn.getresponse()
532
+
533
+ resp = HTTPResponse.from_httplib(
534
+ r,
535
+ pool=conn,
536
+ connection=low_conn,
537
+ preload_content=False,
538
+ decode_content=False,
539
+ )
540
+ except Exception:
541
+ # If we hit any problems here, clean up the connection.
542
+ # Then, raise so that we can handle the actual exception.
543
+ low_conn.close()
544
+ raise
545
+
546
+ except (ProtocolError, OSError) as err:
547
+ raise ConnectionError(err, request=request)
548
+
549
+ except MaxRetryError as e:
550
+ if isinstance(e.reason, ConnectTimeoutError):
551
+ # TODO: Remove this in 3.0.0: see #2811
552
+ if not isinstance(e.reason, NewConnectionError):
553
+ raise ConnectTimeout(e, request=request)
554
+
555
+ if isinstance(e.reason, ResponseError):
556
+ raise RetryError(e, request=request)
557
+
558
+ if isinstance(e.reason, _ProxyError):
559
+ raise ProxyError(e, request=request)
560
+
561
+ if isinstance(e.reason, _SSLError):
562
+ # This branch is for urllib3 v1.22 and later.
563
+ raise SSLError(e, request=request)
564
+
565
+ raise ConnectionError(e, request=request)
566
+
567
+ except ClosedPoolError as e:
568
+ raise ConnectionError(e, request=request)
569
+
570
+ except _ProxyError as e:
571
+ raise ProxyError(e)
572
+
573
+ except (_SSLError, _HTTPError) as e:
574
+ if isinstance(e, _SSLError):
575
+ # This branch is for urllib3 versions earlier than v1.22
576
+ raise SSLError(e, request=request)
577
+ elif isinstance(e, ReadTimeoutError):
578
+ raise ReadTimeout(e, request=request)
579
+ elif isinstance(e, _InvalidHeader):
580
+ raise InvalidHeader(e, request=request)
581
+ else:
582
+ raise
583
+
584
+ return self.build_response(request, resp)