cli-ih 0.6.3.1__py3-none-any.whl → 0.7.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (427) hide show
  1. cli_ih/__init__.py +1 -0
  2. cli_ih/asyncClient.py +109 -10
  3. cli_ih/client.py +110 -18
  4. cli_ih/utils.py +51 -0
  5. cli_ih-0.7.1.dist-info/METADATA +100 -0
  6. cli_ih-0.7.1.dist-info/RECORD +9 -0
  7. {cli_ih-0.6.3.1.dist-info → cli_ih-0.7.1.dist-info}/top_level.txt +0 -1
  8. cli_ih-0.6.3.1.dist-info/METADATA +0 -86
  9. cli_ih-0.6.3.1.dist-info/RECORD +0 -425
  10. venv/Lib/site-packages/__editable___cli_ih_0_6_3_1_finder.py +0 -85
  11. venv/Lib/site-packages/pip/__init__.py +0 -13
  12. venv/Lib/site-packages/pip/__main__.py +0 -24
  13. venv/Lib/site-packages/pip/__pip-runner__.py +0 -50
  14. venv/Lib/site-packages/pip/_internal/__init__.py +0 -18
  15. venv/Lib/site-packages/pip/_internal/build_env.py +0 -349
  16. venv/Lib/site-packages/pip/_internal/cache.py +0 -291
  17. venv/Lib/site-packages/pip/_internal/cli/__init__.py +0 -3
  18. venv/Lib/site-packages/pip/_internal/cli/autocompletion.py +0 -184
  19. venv/Lib/site-packages/pip/_internal/cli/base_command.py +0 -244
  20. venv/Lib/site-packages/pip/_internal/cli/cmdoptions.py +0 -1138
  21. venv/Lib/site-packages/pip/_internal/cli/command_context.py +0 -28
  22. venv/Lib/site-packages/pip/_internal/cli/index_command.py +0 -175
  23. venv/Lib/site-packages/pip/_internal/cli/main.py +0 -80
  24. venv/Lib/site-packages/pip/_internal/cli/main_parser.py +0 -134
  25. venv/Lib/site-packages/pip/_internal/cli/parser.py +0 -298
  26. venv/Lib/site-packages/pip/_internal/cli/progress_bars.py +0 -151
  27. venv/Lib/site-packages/pip/_internal/cli/req_command.py +0 -351
  28. venv/Lib/site-packages/pip/_internal/cli/spinners.py +0 -235
  29. venv/Lib/site-packages/pip/_internal/cli/status_codes.py +0 -6
  30. venv/Lib/site-packages/pip/_internal/commands/__init__.py +0 -139
  31. venv/Lib/site-packages/pip/_internal/commands/cache.py +0 -231
  32. venv/Lib/site-packages/pip/_internal/commands/check.py +0 -66
  33. venv/Lib/site-packages/pip/_internal/commands/completion.py +0 -135
  34. venv/Lib/site-packages/pip/_internal/commands/configuration.py +0 -288
  35. venv/Lib/site-packages/pip/_internal/commands/debug.py +0 -203
  36. venv/Lib/site-packages/pip/_internal/commands/download.py +0 -145
  37. venv/Lib/site-packages/pip/_internal/commands/freeze.py +0 -107
  38. venv/Lib/site-packages/pip/_internal/commands/hash.py +0 -58
  39. venv/Lib/site-packages/pip/_internal/commands/help.py +0 -40
  40. venv/Lib/site-packages/pip/_internal/commands/index.py +0 -159
  41. venv/Lib/site-packages/pip/_internal/commands/inspect.py +0 -92
  42. venv/Lib/site-packages/pip/_internal/commands/install.py +0 -798
  43. venv/Lib/site-packages/pip/_internal/commands/list.py +0 -400
  44. venv/Lib/site-packages/pip/_internal/commands/lock.py +0 -170
  45. venv/Lib/site-packages/pip/_internal/commands/search.py +0 -178
  46. venv/Lib/site-packages/pip/_internal/commands/show.py +0 -231
  47. venv/Lib/site-packages/pip/_internal/commands/uninstall.py +0 -113
  48. venv/Lib/site-packages/pip/_internal/commands/wheel.py +0 -181
  49. venv/Lib/site-packages/pip/_internal/configuration.py +0 -397
  50. venv/Lib/site-packages/pip/_internal/distributions/__init__.py +0 -21
  51. venv/Lib/site-packages/pip/_internal/distributions/base.py +0 -55
  52. venv/Lib/site-packages/pip/_internal/distributions/installed.py +0 -33
  53. venv/Lib/site-packages/pip/_internal/distributions/sdist.py +0 -165
  54. venv/Lib/site-packages/pip/_internal/distributions/wheel.py +0 -44
  55. venv/Lib/site-packages/pip/_internal/exceptions.py +0 -881
  56. venv/Lib/site-packages/pip/_internal/index/__init__.py +0 -1
  57. venv/Lib/site-packages/pip/_internal/index/collector.py +0 -489
  58. venv/Lib/site-packages/pip/_internal/index/package_finder.py +0 -1059
  59. venv/Lib/site-packages/pip/_internal/index/sources.py +0 -287
  60. venv/Lib/site-packages/pip/_internal/locations/__init__.py +0 -441
  61. venv/Lib/site-packages/pip/_internal/locations/_distutils.py +0 -173
  62. venv/Lib/site-packages/pip/_internal/locations/_sysconfig.py +0 -215
  63. venv/Lib/site-packages/pip/_internal/locations/base.py +0 -82
  64. venv/Lib/site-packages/pip/_internal/main.py +0 -12
  65. venv/Lib/site-packages/pip/_internal/metadata/__init__.py +0 -164
  66. venv/Lib/site-packages/pip/_internal/metadata/_json.py +0 -87
  67. venv/Lib/site-packages/pip/_internal/metadata/base.py +0 -685
  68. venv/Lib/site-packages/pip/_internal/metadata/importlib/__init__.py +0 -6
  69. venv/Lib/site-packages/pip/_internal/metadata/importlib/_compat.py +0 -87
  70. venv/Lib/site-packages/pip/_internal/metadata/importlib/_dists.py +0 -223
  71. venv/Lib/site-packages/pip/_internal/metadata/importlib/_envs.py +0 -143
  72. venv/Lib/site-packages/pip/_internal/metadata/pkg_resources.py +0 -298
  73. venv/Lib/site-packages/pip/_internal/models/__init__.py +0 -1
  74. venv/Lib/site-packages/pip/_internal/models/candidate.py +0 -25
  75. venv/Lib/site-packages/pip/_internal/models/direct_url.py +0 -227
  76. venv/Lib/site-packages/pip/_internal/models/format_control.py +0 -78
  77. venv/Lib/site-packages/pip/_internal/models/index.py +0 -28
  78. venv/Lib/site-packages/pip/_internal/models/installation_report.py +0 -57
  79. venv/Lib/site-packages/pip/_internal/models/link.py +0 -613
  80. venv/Lib/site-packages/pip/_internal/models/pylock.py +0 -188
  81. venv/Lib/site-packages/pip/_internal/models/scheme.py +0 -25
  82. venv/Lib/site-packages/pip/_internal/models/search_scope.py +0 -126
  83. venv/Lib/site-packages/pip/_internal/models/selection_prefs.py +0 -53
  84. venv/Lib/site-packages/pip/_internal/models/target_python.py +0 -122
  85. venv/Lib/site-packages/pip/_internal/models/wheel.py +0 -141
  86. venv/Lib/site-packages/pip/_internal/network/__init__.py +0 -1
  87. venv/Lib/site-packages/pip/_internal/network/auth.py +0 -564
  88. venv/Lib/site-packages/pip/_internal/network/cache.py +0 -133
  89. venv/Lib/site-packages/pip/_internal/network/download.py +0 -342
  90. venv/Lib/site-packages/pip/_internal/network/lazy_wheel.py +0 -213
  91. venv/Lib/site-packages/pip/_internal/network/session.py +0 -528
  92. venv/Lib/site-packages/pip/_internal/network/utils.py +0 -98
  93. venv/Lib/site-packages/pip/_internal/network/xmlrpc.py +0 -61
  94. venv/Lib/site-packages/pip/_internal/operations/__init__.py +0 -0
  95. venv/Lib/site-packages/pip/_internal/operations/build/__init__.py +0 -0
  96. venv/Lib/site-packages/pip/_internal/operations/build/build_tracker.py +0 -140
  97. venv/Lib/site-packages/pip/_internal/operations/build/metadata.py +0 -38
  98. venv/Lib/site-packages/pip/_internal/operations/build/metadata_editable.py +0 -41
  99. venv/Lib/site-packages/pip/_internal/operations/build/metadata_legacy.py +0 -73
  100. venv/Lib/site-packages/pip/_internal/operations/build/wheel.py +0 -38
  101. venv/Lib/site-packages/pip/_internal/operations/build/wheel_editable.py +0 -47
  102. venv/Lib/site-packages/pip/_internal/operations/build/wheel_legacy.py +0 -119
  103. venv/Lib/site-packages/pip/_internal/operations/check.py +0 -175
  104. venv/Lib/site-packages/pip/_internal/operations/freeze.py +0 -259
  105. venv/Lib/site-packages/pip/_internal/operations/install/__init__.py +0 -1
  106. venv/Lib/site-packages/pip/_internal/operations/install/editable_legacy.py +0 -48
  107. venv/Lib/site-packages/pip/_internal/operations/install/wheel.py +0 -746
  108. venv/Lib/site-packages/pip/_internal/operations/prepare.py +0 -742
  109. venv/Lib/site-packages/pip/_internal/pyproject.py +0 -182
  110. venv/Lib/site-packages/pip/_internal/req/__init__.py +0 -105
  111. venv/Lib/site-packages/pip/_internal/req/constructors.py +0 -562
  112. venv/Lib/site-packages/pip/_internal/req/req_dependency_group.py +0 -75
  113. venv/Lib/site-packages/pip/_internal/req/req_file.py +0 -620
  114. venv/Lib/site-packages/pip/_internal/req/req_install.py +0 -937
  115. venv/Lib/site-packages/pip/_internal/req/req_set.py +0 -81
  116. venv/Lib/site-packages/pip/_internal/req/req_uninstall.py +0 -639
  117. venv/Lib/site-packages/pip/_internal/resolution/__init__.py +0 -0
  118. venv/Lib/site-packages/pip/_internal/resolution/base.py +0 -20
  119. venv/Lib/site-packages/pip/_internal/resolution/legacy/__init__.py +0 -0
  120. venv/Lib/site-packages/pip/_internal/resolution/legacy/resolver.py +0 -598
  121. venv/Lib/site-packages/pip/_internal/resolution/resolvelib/__init__.py +0 -0
  122. venv/Lib/site-packages/pip/_internal/resolution/resolvelib/base.py +0 -142
  123. venv/Lib/site-packages/pip/_internal/resolution/resolvelib/candidates.py +0 -582
  124. venv/Lib/site-packages/pip/_internal/resolution/resolvelib/factory.py +0 -814
  125. venv/Lib/site-packages/pip/_internal/resolution/resolvelib/found_candidates.py +0 -166
  126. venv/Lib/site-packages/pip/_internal/resolution/resolvelib/provider.py +0 -276
  127. venv/Lib/site-packages/pip/_internal/resolution/resolvelib/reporter.py +0 -85
  128. venv/Lib/site-packages/pip/_internal/resolution/resolvelib/requirements.py +0 -247
  129. venv/Lib/site-packages/pip/_internal/resolution/resolvelib/resolver.py +0 -336
  130. venv/Lib/site-packages/pip/_internal/self_outdated_check.py +0 -254
  131. venv/Lib/site-packages/pip/_internal/utils/__init__.py +0 -0
  132. venv/Lib/site-packages/pip/_internal/utils/_jaraco_text.py +0 -109
  133. venv/Lib/site-packages/pip/_internal/utils/_log.py +0 -38
  134. venv/Lib/site-packages/pip/_internal/utils/appdirs.py +0 -52
  135. venv/Lib/site-packages/pip/_internal/utils/compat.py +0 -85
  136. venv/Lib/site-packages/pip/_internal/utils/compatibility_tags.py +0 -201
  137. venv/Lib/site-packages/pip/_internal/utils/datetime.py +0 -10
  138. venv/Lib/site-packages/pip/_internal/utils/deprecation.py +0 -126
  139. venv/Lib/site-packages/pip/_internal/utils/direct_url_helpers.py +0 -87
  140. venv/Lib/site-packages/pip/_internal/utils/egg_link.py +0 -81
  141. venv/Lib/site-packages/pip/_internal/utils/entrypoints.py +0 -88
  142. venv/Lib/site-packages/pip/_internal/utils/filesystem.py +0 -152
  143. venv/Lib/site-packages/pip/_internal/utils/filetypes.py +0 -24
  144. venv/Lib/site-packages/pip/_internal/utils/glibc.py +0 -102
  145. venv/Lib/site-packages/pip/_internal/utils/hashes.py +0 -150
  146. venv/Lib/site-packages/pip/_internal/utils/logging.py +0 -364
  147. venv/Lib/site-packages/pip/_internal/utils/misc.py +0 -765
  148. venv/Lib/site-packages/pip/_internal/utils/packaging.py +0 -44
  149. venv/Lib/site-packages/pip/_internal/utils/retry.py +0 -45
  150. venv/Lib/site-packages/pip/_internal/utils/setuptools_build.py +0 -149
  151. venv/Lib/site-packages/pip/_internal/utils/subprocess.py +0 -248
  152. venv/Lib/site-packages/pip/_internal/utils/temp_dir.py +0 -294
  153. venv/Lib/site-packages/pip/_internal/utils/unpacking.py +0 -337
  154. venv/Lib/site-packages/pip/_internal/utils/urls.py +0 -55
  155. venv/Lib/site-packages/pip/_internal/utils/virtualenv.py +0 -105
  156. venv/Lib/site-packages/pip/_internal/utils/wheel.py +0 -132
  157. venv/Lib/site-packages/pip/_internal/vcs/__init__.py +0 -15
  158. venv/Lib/site-packages/pip/_internal/vcs/bazaar.py +0 -130
  159. venv/Lib/site-packages/pip/_internal/vcs/git.py +0 -571
  160. venv/Lib/site-packages/pip/_internal/vcs/mercurial.py +0 -186
  161. venv/Lib/site-packages/pip/_internal/vcs/subversion.py +0 -335
  162. venv/Lib/site-packages/pip/_internal/vcs/versioncontrol.py +0 -693
  163. venv/Lib/site-packages/pip/_internal/wheel_builder.py +0 -334
  164. venv/Lib/site-packages/pip/_vendor/__init__.py +0 -117
  165. venv/Lib/site-packages/pip/_vendor/cachecontrol/__init__.py +0 -29
  166. venv/Lib/site-packages/pip/_vendor/cachecontrol/_cmd.py +0 -70
  167. venv/Lib/site-packages/pip/_vendor/cachecontrol/adapter.py +0 -168
  168. venv/Lib/site-packages/pip/_vendor/cachecontrol/cache.py +0 -75
  169. venv/Lib/site-packages/pip/_vendor/cachecontrol/caches/__init__.py +0 -8
  170. venv/Lib/site-packages/pip/_vendor/cachecontrol/caches/file_cache.py +0 -145
  171. venv/Lib/site-packages/pip/_vendor/cachecontrol/caches/redis_cache.py +0 -48
  172. venv/Lib/site-packages/pip/_vendor/cachecontrol/controller.py +0 -511
  173. venv/Lib/site-packages/pip/_vendor/cachecontrol/filewrapper.py +0 -119
  174. venv/Lib/site-packages/pip/_vendor/cachecontrol/heuristics.py +0 -157
  175. venv/Lib/site-packages/pip/_vendor/cachecontrol/py.typed +0 -0
  176. venv/Lib/site-packages/pip/_vendor/cachecontrol/serialize.py +0 -146
  177. venv/Lib/site-packages/pip/_vendor/cachecontrol/wrapper.py +0 -43
  178. venv/Lib/site-packages/pip/_vendor/certifi/__init__.py +0 -4
  179. venv/Lib/site-packages/pip/_vendor/certifi/__main__.py +0 -12
  180. venv/Lib/site-packages/pip/_vendor/certifi/core.py +0 -83
  181. venv/Lib/site-packages/pip/_vendor/certifi/py.typed +0 -0
  182. venv/Lib/site-packages/pip/_vendor/dependency_groups/__init__.py +0 -13
  183. venv/Lib/site-packages/pip/_vendor/dependency_groups/__main__.py +0 -65
  184. venv/Lib/site-packages/pip/_vendor/dependency_groups/_implementation.py +0 -209
  185. venv/Lib/site-packages/pip/_vendor/dependency_groups/_lint_dependency_groups.py +0 -59
  186. venv/Lib/site-packages/pip/_vendor/dependency_groups/_pip_wrapper.py +0 -62
  187. venv/Lib/site-packages/pip/_vendor/dependency_groups/_toml_compat.py +0 -9
  188. venv/Lib/site-packages/pip/_vendor/dependency_groups/py.typed +0 -0
  189. venv/Lib/site-packages/pip/_vendor/distlib/__init__.py +0 -33
  190. venv/Lib/site-packages/pip/_vendor/distlib/compat.py +0 -1137
  191. venv/Lib/site-packages/pip/_vendor/distlib/resources.py +0 -358
  192. venv/Lib/site-packages/pip/_vendor/distlib/scripts.py +0 -447
  193. venv/Lib/site-packages/pip/_vendor/distlib/util.py +0 -1984
  194. venv/Lib/site-packages/pip/_vendor/distro/__init__.py +0 -54
  195. venv/Lib/site-packages/pip/_vendor/distro/__main__.py +0 -4
  196. venv/Lib/site-packages/pip/_vendor/distro/distro.py +0 -1403
  197. venv/Lib/site-packages/pip/_vendor/distro/py.typed +0 -0
  198. venv/Lib/site-packages/pip/_vendor/idna/__init__.py +0 -45
  199. venv/Lib/site-packages/pip/_vendor/idna/codec.py +0 -122
  200. venv/Lib/site-packages/pip/_vendor/idna/compat.py +0 -15
  201. venv/Lib/site-packages/pip/_vendor/idna/core.py +0 -437
  202. venv/Lib/site-packages/pip/_vendor/idna/idnadata.py +0 -4243
  203. venv/Lib/site-packages/pip/_vendor/idna/intranges.py +0 -57
  204. venv/Lib/site-packages/pip/_vendor/idna/package_data.py +0 -1
  205. venv/Lib/site-packages/pip/_vendor/idna/py.typed +0 -0
  206. venv/Lib/site-packages/pip/_vendor/idna/uts46data.py +0 -8681
  207. venv/Lib/site-packages/pip/_vendor/msgpack/__init__.py +0 -55
  208. venv/Lib/site-packages/pip/_vendor/msgpack/exceptions.py +0 -48
  209. venv/Lib/site-packages/pip/_vendor/msgpack/ext.py +0 -170
  210. venv/Lib/site-packages/pip/_vendor/msgpack/fallback.py +0 -929
  211. venv/Lib/site-packages/pip/_vendor/packaging/__init__.py +0 -15
  212. venv/Lib/site-packages/pip/_vendor/packaging/_elffile.py +0 -109
  213. venv/Lib/site-packages/pip/_vendor/packaging/_manylinux.py +0 -262
  214. venv/Lib/site-packages/pip/_vendor/packaging/_musllinux.py +0 -85
  215. venv/Lib/site-packages/pip/_vendor/packaging/_parser.py +0 -353
  216. venv/Lib/site-packages/pip/_vendor/packaging/_structures.py +0 -61
  217. venv/Lib/site-packages/pip/_vendor/packaging/_tokenizer.py +0 -195
  218. venv/Lib/site-packages/pip/_vendor/packaging/licenses/__init__.py +0 -145
  219. venv/Lib/site-packages/pip/_vendor/packaging/licenses/_spdx.py +0 -759
  220. venv/Lib/site-packages/pip/_vendor/packaging/markers.py +0 -362
  221. venv/Lib/site-packages/pip/_vendor/packaging/metadata.py +0 -862
  222. venv/Lib/site-packages/pip/_vendor/packaging/py.typed +0 -0
  223. venv/Lib/site-packages/pip/_vendor/packaging/requirements.py +0 -91
  224. venv/Lib/site-packages/pip/_vendor/packaging/specifiers.py +0 -1019
  225. venv/Lib/site-packages/pip/_vendor/packaging/tags.py +0 -656
  226. venv/Lib/site-packages/pip/_vendor/packaging/utils.py +0 -163
  227. venv/Lib/site-packages/pip/_vendor/packaging/version.py +0 -582
  228. venv/Lib/site-packages/pip/_vendor/pkg_resources/__init__.py +0 -3676
  229. venv/Lib/site-packages/pip/_vendor/platformdirs/__init__.py +0 -631
  230. venv/Lib/site-packages/pip/_vendor/platformdirs/__main__.py +0 -55
  231. venv/Lib/site-packages/pip/_vendor/platformdirs/android.py +0 -249
  232. venv/Lib/site-packages/pip/_vendor/platformdirs/api.py +0 -299
  233. venv/Lib/site-packages/pip/_vendor/platformdirs/macos.py +0 -144
  234. venv/Lib/site-packages/pip/_vendor/platformdirs/py.typed +0 -0
  235. venv/Lib/site-packages/pip/_vendor/platformdirs/unix.py +0 -272
  236. venv/Lib/site-packages/pip/_vendor/platformdirs/version.py +0 -21
  237. venv/Lib/site-packages/pip/_vendor/platformdirs/windows.py +0 -272
  238. venv/Lib/site-packages/pip/_vendor/pygments/__init__.py +0 -82
  239. venv/Lib/site-packages/pip/_vendor/pygments/__main__.py +0 -17
  240. venv/Lib/site-packages/pip/_vendor/pygments/console.py +0 -70
  241. venv/Lib/site-packages/pip/_vendor/pygments/filter.py +0 -70
  242. venv/Lib/site-packages/pip/_vendor/pygments/filters/__init__.py +0 -940
  243. venv/Lib/site-packages/pip/_vendor/pygments/formatter.py +0 -129
  244. venv/Lib/site-packages/pip/_vendor/pygments/formatters/__init__.py +0 -157
  245. venv/Lib/site-packages/pip/_vendor/pygments/formatters/_mapping.py +0 -23
  246. venv/Lib/site-packages/pip/_vendor/pygments/lexer.py +0 -963
  247. venv/Lib/site-packages/pip/_vendor/pygments/lexers/__init__.py +0 -362
  248. venv/Lib/site-packages/pip/_vendor/pygments/lexers/_mapping.py +0 -602
  249. venv/Lib/site-packages/pip/_vendor/pygments/lexers/python.py +0 -1201
  250. venv/Lib/site-packages/pip/_vendor/pygments/modeline.py +0 -43
  251. venv/Lib/site-packages/pip/_vendor/pygments/plugin.py +0 -72
  252. venv/Lib/site-packages/pip/_vendor/pygments/regexopt.py +0 -91
  253. venv/Lib/site-packages/pip/_vendor/pygments/scanner.py +0 -104
  254. venv/Lib/site-packages/pip/_vendor/pygments/sphinxext.py +0 -247
  255. venv/Lib/site-packages/pip/_vendor/pygments/style.py +0 -203
  256. venv/Lib/site-packages/pip/_vendor/pygments/styles/__init__.py +0 -61
  257. venv/Lib/site-packages/pip/_vendor/pygments/styles/_mapping.py +0 -54
  258. venv/Lib/site-packages/pip/_vendor/pygments/token.py +0 -214
  259. venv/Lib/site-packages/pip/_vendor/pygments/unistring.py +0 -153
  260. venv/Lib/site-packages/pip/_vendor/pygments/util.py +0 -324
  261. venv/Lib/site-packages/pip/_vendor/pyproject_hooks/__init__.py +0 -31
  262. venv/Lib/site-packages/pip/_vendor/pyproject_hooks/_impl.py +0 -410
  263. venv/Lib/site-packages/pip/_vendor/pyproject_hooks/_in_process/__init__.py +0 -21
  264. venv/Lib/site-packages/pip/_vendor/pyproject_hooks/_in_process/_in_process.py +0 -389
  265. venv/Lib/site-packages/pip/_vendor/pyproject_hooks/py.typed +0 -0
  266. venv/Lib/site-packages/pip/_vendor/requests/__init__.py +0 -179
  267. venv/Lib/site-packages/pip/_vendor/requests/__version__.py +0 -14
  268. venv/Lib/site-packages/pip/_vendor/requests/_internal_utils.py +0 -50
  269. venv/Lib/site-packages/pip/_vendor/requests/adapters.py +0 -719
  270. venv/Lib/site-packages/pip/_vendor/requests/api.py +0 -157
  271. venv/Lib/site-packages/pip/_vendor/requests/auth.py +0 -314
  272. venv/Lib/site-packages/pip/_vendor/requests/certs.py +0 -17
  273. venv/Lib/site-packages/pip/_vendor/requests/compat.py +0 -90
  274. venv/Lib/site-packages/pip/_vendor/requests/cookies.py +0 -561
  275. venv/Lib/site-packages/pip/_vendor/requests/exceptions.py +0 -151
  276. venv/Lib/site-packages/pip/_vendor/requests/help.py +0 -127
  277. venv/Lib/site-packages/pip/_vendor/requests/hooks.py +0 -33
  278. venv/Lib/site-packages/pip/_vendor/requests/models.py +0 -1039
  279. venv/Lib/site-packages/pip/_vendor/requests/packages.py +0 -25
  280. venv/Lib/site-packages/pip/_vendor/requests/sessions.py +0 -831
  281. venv/Lib/site-packages/pip/_vendor/requests/status_codes.py +0 -128
  282. venv/Lib/site-packages/pip/_vendor/requests/structures.py +0 -99
  283. venv/Lib/site-packages/pip/_vendor/requests/utils.py +0 -1086
  284. venv/Lib/site-packages/pip/_vendor/resolvelib/__init__.py +0 -27
  285. venv/Lib/site-packages/pip/_vendor/resolvelib/providers.py +0 -196
  286. venv/Lib/site-packages/pip/_vendor/resolvelib/py.typed +0 -0
  287. venv/Lib/site-packages/pip/_vendor/resolvelib/reporters.py +0 -55
  288. venv/Lib/site-packages/pip/_vendor/resolvelib/resolvers/__init__.py +0 -27
  289. venv/Lib/site-packages/pip/_vendor/resolvelib/resolvers/abstract.py +0 -47
  290. venv/Lib/site-packages/pip/_vendor/resolvelib/resolvers/criterion.py +0 -48
  291. venv/Lib/site-packages/pip/_vendor/resolvelib/resolvers/exceptions.py +0 -57
  292. venv/Lib/site-packages/pip/_vendor/resolvelib/resolvers/resolution.py +0 -622
  293. venv/Lib/site-packages/pip/_vendor/resolvelib/structs.py +0 -209
  294. venv/Lib/site-packages/pip/_vendor/rich/__init__.py +0 -177
  295. venv/Lib/site-packages/pip/_vendor/rich/__main__.py +0 -245
  296. venv/Lib/site-packages/pip/_vendor/rich/_cell_widths.py +0 -454
  297. venv/Lib/site-packages/pip/_vendor/rich/_emoji_codes.py +0 -3610
  298. venv/Lib/site-packages/pip/_vendor/rich/_emoji_replace.py +0 -32
  299. venv/Lib/site-packages/pip/_vendor/rich/_export_format.py +0 -76
  300. venv/Lib/site-packages/pip/_vendor/rich/_extension.py +0 -10
  301. venv/Lib/site-packages/pip/_vendor/rich/_fileno.py +0 -24
  302. venv/Lib/site-packages/pip/_vendor/rich/_inspect.py +0 -268
  303. venv/Lib/site-packages/pip/_vendor/rich/_log_render.py +0 -94
  304. venv/Lib/site-packages/pip/_vendor/rich/_loop.py +0 -43
  305. venv/Lib/site-packages/pip/_vendor/rich/_null_file.py +0 -69
  306. venv/Lib/site-packages/pip/_vendor/rich/_palettes.py +0 -309
  307. venv/Lib/site-packages/pip/_vendor/rich/_pick.py +0 -17
  308. venv/Lib/site-packages/pip/_vendor/rich/_ratio.py +0 -153
  309. venv/Lib/site-packages/pip/_vendor/rich/_spinners.py +0 -482
  310. venv/Lib/site-packages/pip/_vendor/rich/_stack.py +0 -16
  311. venv/Lib/site-packages/pip/_vendor/rich/_timer.py +0 -19
  312. venv/Lib/site-packages/pip/_vendor/rich/_win32_console.py +0 -661
  313. venv/Lib/site-packages/pip/_vendor/rich/_windows.py +0 -71
  314. venv/Lib/site-packages/pip/_vendor/rich/_windows_renderer.py +0 -56
  315. venv/Lib/site-packages/pip/_vendor/rich/_wrap.py +0 -93
  316. venv/Lib/site-packages/pip/_vendor/rich/abc.py +0 -33
  317. venv/Lib/site-packages/pip/_vendor/rich/align.py +0 -306
  318. venv/Lib/site-packages/pip/_vendor/rich/ansi.py +0 -241
  319. venv/Lib/site-packages/pip/_vendor/rich/bar.py +0 -93
  320. venv/Lib/site-packages/pip/_vendor/rich/box.py +0 -474
  321. venv/Lib/site-packages/pip/_vendor/rich/cells.py +0 -174
  322. venv/Lib/site-packages/pip/_vendor/rich/color.py +0 -621
  323. venv/Lib/site-packages/pip/_vendor/rich/color_triplet.py +0 -38
  324. venv/Lib/site-packages/pip/_vendor/rich/columns.py +0 -187
  325. venv/Lib/site-packages/pip/_vendor/rich/console.py +0 -2680
  326. venv/Lib/site-packages/pip/_vendor/rich/constrain.py +0 -37
  327. venv/Lib/site-packages/pip/_vendor/rich/containers.py +0 -167
  328. venv/Lib/site-packages/pip/_vendor/rich/control.py +0 -219
  329. venv/Lib/site-packages/pip/_vendor/rich/default_styles.py +0 -193
  330. venv/Lib/site-packages/pip/_vendor/rich/diagnose.py +0 -39
  331. venv/Lib/site-packages/pip/_vendor/rich/emoji.py +0 -91
  332. venv/Lib/site-packages/pip/_vendor/rich/errors.py +0 -34
  333. venv/Lib/site-packages/pip/_vendor/rich/file_proxy.py +0 -57
  334. venv/Lib/site-packages/pip/_vendor/rich/filesize.py +0 -88
  335. venv/Lib/site-packages/pip/_vendor/rich/highlighter.py +0 -232
  336. venv/Lib/site-packages/pip/_vendor/rich/json.py +0 -139
  337. venv/Lib/site-packages/pip/_vendor/rich/jupyter.py +0 -101
  338. venv/Lib/site-packages/pip/_vendor/rich/layout.py +0 -442
  339. venv/Lib/site-packages/pip/_vendor/rich/live.py +0 -400
  340. venv/Lib/site-packages/pip/_vendor/rich/live_render.py +0 -106
  341. venv/Lib/site-packages/pip/_vendor/rich/logging.py +0 -297
  342. venv/Lib/site-packages/pip/_vendor/rich/markup.py +0 -251
  343. venv/Lib/site-packages/pip/_vendor/rich/measure.py +0 -151
  344. venv/Lib/site-packages/pip/_vendor/rich/padding.py +0 -141
  345. venv/Lib/site-packages/pip/_vendor/rich/pager.py +0 -34
  346. venv/Lib/site-packages/pip/_vendor/rich/palette.py +0 -100
  347. venv/Lib/site-packages/pip/_vendor/rich/panel.py +0 -317
  348. venv/Lib/site-packages/pip/_vendor/rich/pretty.py +0 -1016
  349. venv/Lib/site-packages/pip/_vendor/rich/progress.py +0 -1715
  350. venv/Lib/site-packages/pip/_vendor/rich/progress_bar.py +0 -223
  351. venv/Lib/site-packages/pip/_vendor/rich/prompt.py +0 -400
  352. venv/Lib/site-packages/pip/_vendor/rich/protocol.py +0 -42
  353. venv/Lib/site-packages/pip/_vendor/rich/py.typed +0 -0
  354. venv/Lib/site-packages/pip/_vendor/rich/region.py +0 -10
  355. venv/Lib/site-packages/pip/_vendor/rich/repr.py +0 -149
  356. venv/Lib/site-packages/pip/_vendor/rich/rule.py +0 -130
  357. venv/Lib/site-packages/pip/_vendor/rich/scope.py +0 -86
  358. venv/Lib/site-packages/pip/_vendor/rich/screen.py +0 -54
  359. venv/Lib/site-packages/pip/_vendor/rich/segment.py +0 -752
  360. venv/Lib/site-packages/pip/_vendor/rich/spinner.py +0 -132
  361. venv/Lib/site-packages/pip/_vendor/rich/status.py +0 -131
  362. venv/Lib/site-packages/pip/_vendor/rich/style.py +0 -796
  363. venv/Lib/site-packages/pip/_vendor/rich/styled.py +0 -42
  364. venv/Lib/site-packages/pip/_vendor/rich/syntax.py +0 -985
  365. venv/Lib/site-packages/pip/_vendor/rich/table.py +0 -1006
  366. venv/Lib/site-packages/pip/_vendor/rich/terminal_theme.py +0 -153
  367. venv/Lib/site-packages/pip/_vendor/rich/text.py +0 -1361
  368. venv/Lib/site-packages/pip/_vendor/rich/theme.py +0 -115
  369. venv/Lib/site-packages/pip/_vendor/rich/themes.py +0 -5
  370. venv/Lib/site-packages/pip/_vendor/rich/traceback.py +0 -899
  371. venv/Lib/site-packages/pip/_vendor/rich/tree.py +0 -257
  372. venv/Lib/site-packages/pip/_vendor/tomli/__init__.py +0 -8
  373. venv/Lib/site-packages/pip/_vendor/tomli/_parser.py +0 -770
  374. venv/Lib/site-packages/pip/_vendor/tomli/_re.py +0 -112
  375. venv/Lib/site-packages/pip/_vendor/tomli/_types.py +0 -10
  376. venv/Lib/site-packages/pip/_vendor/tomli/py.typed +0 -1
  377. venv/Lib/site-packages/pip/_vendor/tomli_w/__init__.py +0 -4
  378. venv/Lib/site-packages/pip/_vendor/tomli_w/_writer.py +0 -229
  379. venv/Lib/site-packages/pip/_vendor/tomli_w/py.typed +0 -1
  380. venv/Lib/site-packages/pip/_vendor/truststore/__init__.py +0 -36
  381. venv/Lib/site-packages/pip/_vendor/truststore/_api.py +0 -333
  382. venv/Lib/site-packages/pip/_vendor/truststore/_macos.py +0 -571
  383. venv/Lib/site-packages/pip/_vendor/truststore/_openssl.py +0 -66
  384. venv/Lib/site-packages/pip/_vendor/truststore/_ssl_constants.py +0 -31
  385. venv/Lib/site-packages/pip/_vendor/truststore/_windows.py +0 -567
  386. venv/Lib/site-packages/pip/_vendor/truststore/py.typed +0 -0
  387. venv/Lib/site-packages/pip/_vendor/urllib3/__init__.py +0 -102
  388. venv/Lib/site-packages/pip/_vendor/urllib3/_collections.py +0 -355
  389. venv/Lib/site-packages/pip/_vendor/urllib3/_version.py +0 -2
  390. venv/Lib/site-packages/pip/_vendor/urllib3/connection.py +0 -572
  391. venv/Lib/site-packages/pip/_vendor/urllib3/connectionpool.py +0 -1140
  392. venv/Lib/site-packages/pip/_vendor/urllib3/contrib/__init__.py +0 -0
  393. venv/Lib/site-packages/pip/_vendor/urllib3/contrib/_appengine_environ.py +0 -36
  394. venv/Lib/site-packages/pip/_vendor/urllib3/contrib/_securetransport/__init__.py +0 -0
  395. venv/Lib/site-packages/pip/_vendor/urllib3/contrib/_securetransport/bindings.py +0 -519
  396. venv/Lib/site-packages/pip/_vendor/urllib3/contrib/_securetransport/low_level.py +0 -397
  397. venv/Lib/site-packages/pip/_vendor/urllib3/contrib/appengine.py +0 -314
  398. venv/Lib/site-packages/pip/_vendor/urllib3/contrib/ntlmpool.py +0 -130
  399. venv/Lib/site-packages/pip/_vendor/urllib3/contrib/pyopenssl.py +0 -518
  400. venv/Lib/site-packages/pip/_vendor/urllib3/contrib/securetransport.py +0 -920
  401. venv/Lib/site-packages/pip/_vendor/urllib3/contrib/socks.py +0 -216
  402. venv/Lib/site-packages/pip/_vendor/urllib3/exceptions.py +0 -323
  403. venv/Lib/site-packages/pip/_vendor/urllib3/fields.py +0 -274
  404. venv/Lib/site-packages/pip/_vendor/urllib3/filepost.py +0 -98
  405. venv/Lib/site-packages/pip/_vendor/urllib3/packages/__init__.py +0 -0
  406. venv/Lib/site-packages/pip/_vendor/urllib3/packages/backports/__init__.py +0 -0
  407. venv/Lib/site-packages/pip/_vendor/urllib3/packages/backports/makefile.py +0 -51
  408. venv/Lib/site-packages/pip/_vendor/urllib3/packages/backports/weakref_finalize.py +0 -155
  409. venv/Lib/site-packages/pip/_vendor/urllib3/packages/six.py +0 -1076
  410. venv/Lib/site-packages/pip/_vendor/urllib3/poolmanager.py +0 -540
  411. venv/Lib/site-packages/pip/_vendor/urllib3/request.py +0 -191
  412. venv/Lib/site-packages/pip/_vendor/urllib3/response.py +0 -879
  413. venv/Lib/site-packages/pip/_vendor/urllib3/util/__init__.py +0 -49
  414. venv/Lib/site-packages/pip/_vendor/urllib3/util/connection.py +0 -149
  415. venv/Lib/site-packages/pip/_vendor/urllib3/util/proxy.py +0 -57
  416. venv/Lib/site-packages/pip/_vendor/urllib3/util/queue.py +0 -22
  417. venv/Lib/site-packages/pip/_vendor/urllib3/util/request.py +0 -137
  418. venv/Lib/site-packages/pip/_vendor/urllib3/util/response.py +0 -107
  419. venv/Lib/site-packages/pip/_vendor/urllib3/util/retry.py +0 -622
  420. venv/Lib/site-packages/pip/_vendor/urllib3/util/ssl_.py +0 -504
  421. venv/Lib/site-packages/pip/_vendor/urllib3/util/ssl_match_hostname.py +0 -159
  422. venv/Lib/site-packages/pip/_vendor/urllib3/util/ssltransport.py +0 -221
  423. venv/Lib/site-packages/pip/_vendor/urllib3/util/timeout.py +0 -271
  424. venv/Lib/site-packages/pip/_vendor/urllib3/util/url.py +0 -435
  425. venv/Lib/site-packages/pip/_vendor/urllib3/util/wait.py +0 -152
  426. venv/Lib/site-packages/pip/py.typed +0 -4
  427. {cli_ih-0.6.3.1.dist-info → cli_ih-0.7.1.dist-info}/WHEEL +0 -0
@@ -1,1137 +0,0 @@
1
- # -*- coding: utf-8 -*-
2
- #
3
- # Copyright (C) 2013-2017 Vinay Sajip.
4
- # Licensed to the Python Software Foundation under a contributor agreement.
5
- # See LICENSE.txt and CONTRIBUTORS.txt.
6
- #
7
- from __future__ import absolute_import
8
-
9
- import os
10
- import re
11
- import shutil
12
- import sys
13
-
14
- try:
15
- import ssl
16
- except ImportError: # pragma: no cover
17
- ssl = None
18
-
19
- if sys.version_info[0] < 3: # pragma: no cover
20
- from StringIO import StringIO
21
- string_types = basestring,
22
- text_type = unicode
23
- from types import FileType as file_type
24
- import __builtin__ as builtins
25
- import ConfigParser as configparser
26
- from urlparse import urlparse, urlunparse, urljoin, urlsplit, urlunsplit
27
- from urllib import (urlretrieve, quote as _quote, unquote, url2pathname,
28
- pathname2url, ContentTooShortError, splittype)
29
-
30
- def quote(s):
31
- if isinstance(s, unicode):
32
- s = s.encode('utf-8')
33
- return _quote(s)
34
-
35
- import urllib2
36
- from urllib2 import (Request, urlopen, URLError, HTTPError,
37
- HTTPBasicAuthHandler, HTTPPasswordMgr, HTTPHandler,
38
- HTTPRedirectHandler, build_opener)
39
- if ssl:
40
- from urllib2 import HTTPSHandler
41
- import httplib
42
- import xmlrpclib
43
- import Queue as queue
44
- from HTMLParser import HTMLParser
45
- import htmlentitydefs
46
- raw_input = raw_input
47
- from itertools import ifilter as filter
48
- from itertools import ifilterfalse as filterfalse
49
-
50
- # Leaving this around for now, in case it needs resurrecting in some way
51
- # _userprog = None
52
- # def splituser(host):
53
- # """splituser('user[:passwd]@host[:port]') --> 'user[:passwd]', 'host[:port]'."""
54
- # global _userprog
55
- # if _userprog is None:
56
- # import re
57
- # _userprog = re.compile('^(.*)@(.*)$')
58
-
59
- # match = _userprog.match(host)
60
- # if match: return match.group(1, 2)
61
- # return None, host
62
-
63
- else: # pragma: no cover
64
- from io import StringIO
65
- string_types = str,
66
- text_type = str
67
- from io import TextIOWrapper as file_type
68
- import builtins
69
- import configparser
70
- from urllib.parse import (urlparse, urlunparse, urljoin, quote, unquote,
71
- urlsplit, urlunsplit, splittype)
72
- from urllib.request import (urlopen, urlretrieve, Request, url2pathname,
73
- pathname2url, HTTPBasicAuthHandler,
74
- HTTPPasswordMgr, HTTPHandler,
75
- HTTPRedirectHandler, build_opener)
76
- if ssl:
77
- from urllib.request import HTTPSHandler
78
- from urllib.error import HTTPError, URLError, ContentTooShortError
79
- import http.client as httplib
80
- import urllib.request as urllib2
81
- import xmlrpc.client as xmlrpclib
82
- import queue
83
- from html.parser import HTMLParser
84
- import html.entities as htmlentitydefs
85
- raw_input = input
86
- from itertools import filterfalse
87
- filter = filter
88
-
89
- try:
90
- from ssl import match_hostname, CertificateError
91
- except ImportError: # pragma: no cover
92
-
93
- class CertificateError(ValueError):
94
- pass
95
-
96
- def _dnsname_match(dn, hostname, max_wildcards=1):
97
- """Matching according to RFC 6125, section 6.4.3
98
-
99
- http://tools.ietf.org/html/rfc6125#section-6.4.3
100
- """
101
- pats = []
102
- if not dn:
103
- return False
104
-
105
- parts = dn.split('.')
106
- leftmost, remainder = parts[0], parts[1:]
107
-
108
- wildcards = leftmost.count('*')
109
- if wildcards > max_wildcards:
110
- # Issue #17980: avoid denials of service by refusing more
111
- # than one wildcard per fragment. A survey of established
112
- # policy among SSL implementations showed it to be a
113
- # reasonable choice.
114
- raise CertificateError(
115
- "too many wildcards in certificate DNS name: " + repr(dn))
116
-
117
- # speed up common case w/o wildcards
118
- if not wildcards:
119
- return dn.lower() == hostname.lower()
120
-
121
- # RFC 6125, section 6.4.3, subitem 1.
122
- # The client SHOULD NOT attempt to match a presented identifier in which
123
- # the wildcard character comprises a label other than the left-most label.
124
- if leftmost == '*':
125
- # When '*' is a fragment by itself, it matches a non-empty dotless
126
- # fragment.
127
- pats.append('[^.]+')
128
- elif leftmost.startswith('xn--') or hostname.startswith('xn--'):
129
- # RFC 6125, section 6.4.3, subitem 3.
130
- # The client SHOULD NOT attempt to match a presented identifier
131
- # where the wildcard character is embedded within an A-label or
132
- # U-label of an internationalized domain name.
133
- pats.append(re.escape(leftmost))
134
- else:
135
- # Otherwise, '*' matches any dotless string, e.g. www*
136
- pats.append(re.escape(leftmost).replace(r'\*', '[^.]*'))
137
-
138
- # add the remaining fragments, ignore any wildcards
139
- for frag in remainder:
140
- pats.append(re.escape(frag))
141
-
142
- pat = re.compile(r'\A' + r'\.'.join(pats) + r'\Z', re.IGNORECASE)
143
- return pat.match(hostname)
144
-
145
- def match_hostname(cert, hostname):
146
- """Verify that *cert* (in decoded format as returned by
147
- SSLSocket.getpeercert()) matches the *hostname*. RFC 2818 and RFC 6125
148
- rules are followed, but IP addresses are not accepted for *hostname*.
149
-
150
- CertificateError is raised on failure. On success, the function
151
- returns nothing.
152
- """
153
- if not cert:
154
- raise ValueError("empty or no certificate, match_hostname needs a "
155
- "SSL socket or SSL context with either "
156
- "CERT_OPTIONAL or CERT_REQUIRED")
157
- dnsnames = []
158
- san = cert.get('subjectAltName', ())
159
- for key, value in san:
160
- if key == 'DNS':
161
- if _dnsname_match(value, hostname):
162
- return
163
- dnsnames.append(value)
164
- if not dnsnames:
165
- # The subject is only checked when there is no dNSName entry
166
- # in subjectAltName
167
- for sub in cert.get('subject', ()):
168
- for key, value in sub:
169
- # XXX according to RFC 2818, the most specific Common Name
170
- # must be used.
171
- if key == 'commonName':
172
- if _dnsname_match(value, hostname):
173
- return
174
- dnsnames.append(value)
175
- if len(dnsnames) > 1:
176
- raise CertificateError("hostname %r "
177
- "doesn't match either of %s" %
178
- (hostname, ', '.join(map(repr, dnsnames))))
179
- elif len(dnsnames) == 1:
180
- raise CertificateError("hostname %r "
181
- "doesn't match %r" %
182
- (hostname, dnsnames[0]))
183
- else:
184
- raise CertificateError("no appropriate commonName or "
185
- "subjectAltName fields were found")
186
-
187
-
188
- try:
189
- from types import SimpleNamespace as Container
190
- except ImportError: # pragma: no cover
191
-
192
- class Container(object):
193
- """
194
- A generic container for when multiple values need to be returned
195
- """
196
-
197
- def __init__(self, **kwargs):
198
- self.__dict__.update(kwargs)
199
-
200
-
201
- try:
202
- from shutil import which
203
- except ImportError: # pragma: no cover
204
- # Implementation from Python 3.3
205
- def which(cmd, mode=os.F_OK | os.X_OK, path=None):
206
- """Given a command, mode, and a PATH string, return the path which
207
- conforms to the given mode on the PATH, or None if there is no such
208
- file.
209
-
210
- `mode` defaults to os.F_OK | os.X_OK. `path` defaults to the result
211
- of os.environ.get("PATH"), or can be overridden with a custom search
212
- path.
213
-
214
- """
215
-
216
- # Check that a given file can be accessed with the correct mode.
217
- # Additionally check that `file` is not a directory, as on Windows
218
- # directories pass the os.access check.
219
- def _access_check(fn, mode):
220
- return (os.path.exists(fn) and os.access(fn, mode) and not os.path.isdir(fn))
221
-
222
- # If we're given a path with a directory part, look it up directly rather
223
- # than referring to PATH directories. This includes checking relative to the
224
- # current directory, e.g. ./script
225
- if os.path.dirname(cmd):
226
- if _access_check(cmd, mode):
227
- return cmd
228
- return None
229
-
230
- if path is None:
231
- path = os.environ.get("PATH", os.defpath)
232
- if not path:
233
- return None
234
- path = path.split(os.pathsep)
235
-
236
- if sys.platform == "win32":
237
- # The current directory takes precedence on Windows.
238
- if os.curdir not in path:
239
- path.insert(0, os.curdir)
240
-
241
- # PATHEXT is necessary to check on Windows.
242
- pathext = os.environ.get("PATHEXT", "").split(os.pathsep)
243
- # See if the given file matches any of the expected path extensions.
244
- # This will allow us to short circuit when given "python.exe".
245
- # If it does match, only test that one, otherwise we have to try
246
- # others.
247
- if any(cmd.lower().endswith(ext.lower()) for ext in pathext):
248
- files = [cmd]
249
- else:
250
- files = [cmd + ext for ext in pathext]
251
- else:
252
- # On other platforms you don't have things like PATHEXT to tell you
253
- # what file suffixes are executable, so just pass on cmd as-is.
254
- files = [cmd]
255
-
256
- seen = set()
257
- for dir in path:
258
- normdir = os.path.normcase(dir)
259
- if normdir not in seen:
260
- seen.add(normdir)
261
- for thefile in files:
262
- name = os.path.join(dir, thefile)
263
- if _access_check(name, mode):
264
- return name
265
- return None
266
-
267
-
268
- # ZipFile is a context manager in 2.7, but not in 2.6
269
-
270
- from zipfile import ZipFile as BaseZipFile
271
-
272
- if hasattr(BaseZipFile, '__enter__'): # pragma: no cover
273
- ZipFile = BaseZipFile
274
- else: # pragma: no cover
275
- from zipfile import ZipExtFile as BaseZipExtFile
276
-
277
- class ZipExtFile(BaseZipExtFile):
278
-
279
- def __init__(self, base):
280
- self.__dict__.update(base.__dict__)
281
-
282
- def __enter__(self):
283
- return self
284
-
285
- def __exit__(self, *exc_info):
286
- self.close()
287
- # return None, so if an exception occurred, it will propagate
288
-
289
- class ZipFile(BaseZipFile):
290
-
291
- def __enter__(self):
292
- return self
293
-
294
- def __exit__(self, *exc_info):
295
- self.close()
296
- # return None, so if an exception occurred, it will propagate
297
-
298
- def open(self, *args, **kwargs):
299
- base = BaseZipFile.open(self, *args, **kwargs)
300
- return ZipExtFile(base)
301
-
302
-
303
- try:
304
- from platform import python_implementation
305
- except ImportError: # pragma: no cover
306
-
307
- def python_implementation():
308
- """Return a string identifying the Python implementation."""
309
- if 'PyPy' in sys.version:
310
- return 'PyPy'
311
- if os.name == 'java':
312
- return 'Jython'
313
- if sys.version.startswith('IronPython'):
314
- return 'IronPython'
315
- return 'CPython'
316
-
317
-
318
- import sysconfig
319
-
320
- try:
321
- callable = callable
322
- except NameError: # pragma: no cover
323
- from collections.abc import Callable
324
-
325
- def callable(obj):
326
- return isinstance(obj, Callable)
327
-
328
-
329
- try:
330
- fsencode = os.fsencode
331
- fsdecode = os.fsdecode
332
- except AttributeError: # pragma: no cover
333
- # Issue #99: on some systems (e.g. containerised),
334
- # sys.getfilesystemencoding() returns None, and we need a real value,
335
- # so fall back to utf-8. From the CPython 2.7 docs relating to Unix and
336
- # sys.getfilesystemencoding(): the return value is "the user’s preference
337
- # according to the result of nl_langinfo(CODESET), or None if the
338
- # nl_langinfo(CODESET) failed."
339
- _fsencoding = sys.getfilesystemencoding() or 'utf-8'
340
- if _fsencoding == 'mbcs':
341
- _fserrors = 'strict'
342
- else:
343
- _fserrors = 'surrogateescape'
344
-
345
- def fsencode(filename):
346
- if isinstance(filename, bytes):
347
- return filename
348
- elif isinstance(filename, text_type):
349
- return filename.encode(_fsencoding, _fserrors)
350
- else:
351
- raise TypeError("expect bytes or str, not %s" %
352
- type(filename).__name__)
353
-
354
- def fsdecode(filename):
355
- if isinstance(filename, text_type):
356
- return filename
357
- elif isinstance(filename, bytes):
358
- return filename.decode(_fsencoding, _fserrors)
359
- else:
360
- raise TypeError("expect bytes or str, not %s" %
361
- type(filename).__name__)
362
-
363
-
364
- try:
365
- from tokenize import detect_encoding
366
- except ImportError: # pragma: no cover
367
- from codecs import BOM_UTF8, lookup
368
-
369
- cookie_re = re.compile(r"coding[:=]\s*([-\w.]+)")
370
-
371
- def _get_normal_name(orig_enc):
372
- """Imitates get_normal_name in tokenizer.c."""
373
- # Only care about the first 12 characters.
374
- enc = orig_enc[:12].lower().replace("_", "-")
375
- if enc == "utf-8" or enc.startswith("utf-8-"):
376
- return "utf-8"
377
- if enc in ("latin-1", "iso-8859-1", "iso-latin-1") or \
378
- enc.startswith(("latin-1-", "iso-8859-1-", "iso-latin-1-")):
379
- return "iso-8859-1"
380
- return orig_enc
381
-
382
- def detect_encoding(readline):
383
- """
384
- The detect_encoding() function is used to detect the encoding that should
385
- be used to decode a Python source file. It requires one argument, readline,
386
- in the same way as the tokenize() generator.
387
-
388
- It will call readline a maximum of twice, and return the encoding used
389
- (as a string) and a list of any lines (left as bytes) it has read in.
390
-
391
- It detects the encoding from the presence of a utf-8 bom or an encoding
392
- cookie as specified in pep-0263. If both a bom and a cookie are present,
393
- but disagree, a SyntaxError will be raised. If the encoding cookie is an
394
- invalid charset, raise a SyntaxError. Note that if a utf-8 bom is found,
395
- 'utf-8-sig' is returned.
396
-
397
- If no encoding is specified, then the default of 'utf-8' will be returned.
398
- """
399
- try:
400
- filename = readline.__self__.name
401
- except AttributeError:
402
- filename = None
403
- bom_found = False
404
- encoding = None
405
- default = 'utf-8'
406
-
407
- def read_or_stop():
408
- try:
409
- return readline()
410
- except StopIteration:
411
- return b''
412
-
413
- def find_cookie(line):
414
- try:
415
- # Decode as UTF-8. Either the line is an encoding declaration,
416
- # in which case it should be pure ASCII, or it must be UTF-8
417
- # per default encoding.
418
- line_string = line.decode('utf-8')
419
- except UnicodeDecodeError:
420
- msg = "invalid or missing encoding declaration"
421
- if filename is not None:
422
- msg = '{} for {!r}'.format(msg, filename)
423
- raise SyntaxError(msg)
424
-
425
- matches = cookie_re.findall(line_string)
426
- if not matches:
427
- return None
428
- encoding = _get_normal_name(matches[0])
429
- try:
430
- codec = lookup(encoding)
431
- except LookupError:
432
- # This behaviour mimics the Python interpreter
433
- if filename is None:
434
- msg = "unknown encoding: " + encoding
435
- else:
436
- msg = "unknown encoding for {!r}: {}".format(
437
- filename, encoding)
438
- raise SyntaxError(msg)
439
-
440
- if bom_found:
441
- if codec.name != 'utf-8':
442
- # This behaviour mimics the Python interpreter
443
- if filename is None:
444
- msg = 'encoding problem: utf-8'
445
- else:
446
- msg = 'encoding problem for {!r}: utf-8'.format(
447
- filename)
448
- raise SyntaxError(msg)
449
- encoding += '-sig'
450
- return encoding
451
-
452
- first = read_or_stop()
453
- if first.startswith(BOM_UTF8):
454
- bom_found = True
455
- first = first[3:]
456
- default = 'utf-8-sig'
457
- if not first:
458
- return default, []
459
-
460
- encoding = find_cookie(first)
461
- if encoding:
462
- return encoding, [first]
463
-
464
- second = read_or_stop()
465
- if not second:
466
- return default, [first]
467
-
468
- encoding = find_cookie(second)
469
- if encoding:
470
- return encoding, [first, second]
471
-
472
- return default, [first, second]
473
-
474
-
475
- # For converting & <-> &amp; etc.
476
- try:
477
- from html import escape
478
- except ImportError:
479
- from cgi import escape
480
- if sys.version_info[:2] < (3, 4):
481
- unescape = HTMLParser().unescape
482
- else:
483
- from html import unescape
484
-
485
- try:
486
- from collections import ChainMap
487
- except ImportError: # pragma: no cover
488
- from collections import MutableMapping
489
-
490
- try:
491
- from reprlib import recursive_repr as _recursive_repr
492
- except ImportError:
493
-
494
- def _recursive_repr(fillvalue='...'):
495
- '''
496
- Decorator to make a repr function return fillvalue for a recursive
497
- call
498
- '''
499
-
500
- def decorating_function(user_function):
501
- repr_running = set()
502
-
503
- def wrapper(self):
504
- key = id(self), get_ident()
505
- if key in repr_running:
506
- return fillvalue
507
- repr_running.add(key)
508
- try:
509
- result = user_function(self)
510
- finally:
511
- repr_running.discard(key)
512
- return result
513
-
514
- # Can't use functools.wraps() here because of bootstrap issues
515
- wrapper.__module__ = getattr(user_function, '__module__')
516
- wrapper.__doc__ = getattr(user_function, '__doc__')
517
- wrapper.__name__ = getattr(user_function, '__name__')
518
- wrapper.__annotations__ = getattr(user_function,
519
- '__annotations__', {})
520
- return wrapper
521
-
522
- return decorating_function
523
-
524
- class ChainMap(MutableMapping):
525
- '''
526
- A ChainMap groups multiple dicts (or other mappings) together
527
- to create a single, updateable view.
528
-
529
- The underlying mappings are stored in a list. That list is public and can
530
- accessed or updated using the *maps* attribute. There is no other state.
531
-
532
- Lookups search the underlying mappings successively until a key is found.
533
- In contrast, writes, updates, and deletions only operate on the first
534
- mapping.
535
- '''
536
-
537
- def __init__(self, *maps):
538
- '''Initialize a ChainMap by setting *maps* to the given mappings.
539
- If no mappings are provided, a single empty dictionary is used.
540
-
541
- '''
542
- self.maps = list(maps) or [{}] # always at least one map
543
-
544
- def __missing__(self, key):
545
- raise KeyError(key)
546
-
547
- def __getitem__(self, key):
548
- for mapping in self.maps:
549
- try:
550
- return mapping[
551
- key] # can't use 'key in mapping' with defaultdict
552
- except KeyError:
553
- pass
554
- return self.__missing__(
555
- key) # support subclasses that define __missing__
556
-
557
- def get(self, key, default=None):
558
- return self[key] if key in self else default
559
-
560
- def __len__(self):
561
- return len(set().union(
562
- *self.maps)) # reuses stored hash values if possible
563
-
564
- def __iter__(self):
565
- return iter(set().union(*self.maps))
566
-
567
- def __contains__(self, key):
568
- return any(key in m for m in self.maps)
569
-
570
- def __bool__(self):
571
- return any(self.maps)
572
-
573
- @_recursive_repr()
574
- def __repr__(self):
575
- return '{0.__class__.__name__}({1})'.format(
576
- self, ', '.join(map(repr, self.maps)))
577
-
578
- @classmethod
579
- def fromkeys(cls, iterable, *args):
580
- 'Create a ChainMap with a single dict created from the iterable.'
581
- return cls(dict.fromkeys(iterable, *args))
582
-
583
- def copy(self):
584
- 'New ChainMap or subclass with a new copy of maps[0] and refs to maps[1:]'
585
- return self.__class__(self.maps[0].copy(), *self.maps[1:])
586
-
587
- __copy__ = copy
588
-
589
- def new_child(self): # like Django's Context.push()
590
- 'New ChainMap with a new dict followed by all previous maps.'
591
- return self.__class__({}, *self.maps)
592
-
593
- @property
594
- def parents(self): # like Django's Context.pop()
595
- 'New ChainMap from maps[1:].'
596
- return self.__class__(*self.maps[1:])
597
-
598
- def __setitem__(self, key, value):
599
- self.maps[0][key] = value
600
-
601
- def __delitem__(self, key):
602
- try:
603
- del self.maps[0][key]
604
- except KeyError:
605
- raise KeyError(
606
- 'Key not found in the first mapping: {!r}'.format(key))
607
-
608
- def popitem(self):
609
- 'Remove and return an item pair from maps[0]. Raise KeyError is maps[0] is empty.'
610
- try:
611
- return self.maps[0].popitem()
612
- except KeyError:
613
- raise KeyError('No keys found in the first mapping.')
614
-
615
- def pop(self, key, *args):
616
- 'Remove *key* from maps[0] and return its value. Raise KeyError if *key* not in maps[0].'
617
- try:
618
- return self.maps[0].pop(key, *args)
619
- except KeyError:
620
- raise KeyError(
621
- 'Key not found in the first mapping: {!r}'.format(key))
622
-
623
- def clear(self):
624
- 'Clear maps[0], leaving maps[1:] intact.'
625
- self.maps[0].clear()
626
-
627
-
628
- try:
629
- from importlib.util import cache_from_source # Python >= 3.4
630
- except ImportError: # pragma: no cover
631
-
632
- def cache_from_source(path, debug_override=None):
633
- assert path.endswith('.py')
634
- if debug_override is None:
635
- debug_override = __debug__
636
- if debug_override:
637
- suffix = 'c'
638
- else:
639
- suffix = 'o'
640
- return path + suffix
641
-
642
-
643
- try:
644
- from collections import OrderedDict
645
- except ImportError: # pragma: no cover
646
- # {{{ http://code.activestate.com/recipes/576693/ (r9)
647
- # Backport of OrderedDict() class that runs on Python 2.4, 2.5, 2.6, 2.7 and pypy.
648
- # Passes Python2.7's test suite and incorporates all the latest updates.
649
- try:
650
- from thread import get_ident as _get_ident
651
- except ImportError:
652
- from dummy_thread import get_ident as _get_ident
653
-
654
- try:
655
- from _abcoll import KeysView, ValuesView, ItemsView
656
- except ImportError:
657
- pass
658
-
659
- class OrderedDict(dict):
660
- 'Dictionary that remembers insertion order'
661
-
662
- # An inherited dict maps keys to values.
663
- # The inherited dict provides __getitem__, __len__, __contains__, and get.
664
- # The remaining methods are order-aware.
665
- # Big-O running times for all methods are the same as for regular dictionaries.
666
-
667
- # The internal self.__map dictionary maps keys to links in a doubly linked list.
668
- # The circular doubly linked list starts and ends with a sentinel element.
669
- # The sentinel element never gets deleted (this simplifies the algorithm).
670
- # Each link is stored as a list of length three: [PREV, NEXT, KEY].
671
-
672
- def __init__(self, *args, **kwds):
673
- '''Initialize an ordered dictionary. Signature is the same as for
674
- regular dictionaries, but keyword arguments are not recommended
675
- because their insertion order is arbitrary.
676
-
677
- '''
678
- if len(args) > 1:
679
- raise TypeError('expected at most 1 arguments, got %d' %
680
- len(args))
681
- try:
682
- self.__root
683
- except AttributeError:
684
- self.__root = root = [] # sentinel node
685
- root[:] = [root, root, None]
686
- self.__map = {}
687
- self.__update(*args, **kwds)
688
-
689
- def __setitem__(self, key, value, dict_setitem=dict.__setitem__):
690
- 'od.__setitem__(i, y) <==> od[i]=y'
691
- # Setting a new item creates a new link which goes at the end of the linked
692
- # list, and the inherited dictionary is updated with the new key/value pair.
693
- if key not in self:
694
- root = self.__root
695
- last = root[0]
696
- last[1] = root[0] = self.__map[key] = [last, root, key]
697
- dict_setitem(self, key, value)
698
-
699
- def __delitem__(self, key, dict_delitem=dict.__delitem__):
700
- 'od.__delitem__(y) <==> del od[y]'
701
- # Deleting an existing item uses self.__map to find the link which is
702
- # then removed by updating the links in the predecessor and successor nodes.
703
- dict_delitem(self, key)
704
- link_prev, link_next, key = self.__map.pop(key)
705
- link_prev[1] = link_next
706
- link_next[0] = link_prev
707
-
708
- def __iter__(self):
709
- 'od.__iter__() <==> iter(od)'
710
- root = self.__root
711
- curr = root[1]
712
- while curr is not root:
713
- yield curr[2]
714
- curr = curr[1]
715
-
716
- def __reversed__(self):
717
- 'od.__reversed__() <==> reversed(od)'
718
- root = self.__root
719
- curr = root[0]
720
- while curr is not root:
721
- yield curr[2]
722
- curr = curr[0]
723
-
724
- def clear(self):
725
- 'od.clear() -> None. Remove all items from od.'
726
- try:
727
- for node in self.__map.itervalues():
728
- del node[:]
729
- root = self.__root
730
- root[:] = [root, root, None]
731
- self.__map.clear()
732
- except AttributeError:
733
- pass
734
- dict.clear(self)
735
-
736
- def popitem(self, last=True):
737
- '''od.popitem() -> (k, v), return and remove a (key, value) pair.
738
- Pairs are returned in LIFO order if last is true or FIFO order if false.
739
-
740
- '''
741
- if not self:
742
- raise KeyError('dictionary is empty')
743
- root = self.__root
744
- if last:
745
- link = root[0]
746
- link_prev = link[0]
747
- link_prev[1] = root
748
- root[0] = link_prev
749
- else:
750
- link = root[1]
751
- link_next = link[1]
752
- root[1] = link_next
753
- link_next[0] = root
754
- key = link[2]
755
- del self.__map[key]
756
- value = dict.pop(self, key)
757
- return key, value
758
-
759
- # -- the following methods do not depend on the internal structure --
760
-
761
- def keys(self):
762
- 'od.keys() -> list of keys in od'
763
- return list(self)
764
-
765
- def values(self):
766
- 'od.values() -> list of values in od'
767
- return [self[key] for key in self]
768
-
769
- def items(self):
770
- 'od.items() -> list of (key, value) pairs in od'
771
- return [(key, self[key]) for key in self]
772
-
773
- def iterkeys(self):
774
- 'od.iterkeys() -> an iterator over the keys in od'
775
- return iter(self)
776
-
777
- def itervalues(self):
778
- 'od.itervalues -> an iterator over the values in od'
779
- for k in self:
780
- yield self[k]
781
-
782
- def iteritems(self):
783
- 'od.iteritems -> an iterator over the (key, value) items in od'
784
- for k in self:
785
- yield (k, self[k])
786
-
787
- def update(*args, **kwds):
788
- '''od.update(E, **F) -> None. Update od from dict/iterable E and F.
789
-
790
- If E is a dict instance, does: for k in E: od[k] = E[k]
791
- If E has a .keys() method, does: for k in E.keys(): od[k] = E[k]
792
- Or if E is an iterable of items, does: for k, v in E: od[k] = v
793
- In either case, this is followed by: for k, v in F.items(): od[k] = v
794
-
795
- '''
796
- if len(args) > 2:
797
- raise TypeError('update() takes at most 2 positional '
798
- 'arguments (%d given)' % (len(args), ))
799
- elif not args:
800
- raise TypeError('update() takes at least 1 argument (0 given)')
801
- self = args[0]
802
- # Make progressively weaker assumptions about "other"
803
- other = ()
804
- if len(args) == 2:
805
- other = args[1]
806
- if isinstance(other, dict):
807
- for key in other:
808
- self[key] = other[key]
809
- elif hasattr(other, 'keys'):
810
- for key in other.keys():
811
- self[key] = other[key]
812
- else:
813
- for key, value in other:
814
- self[key] = value
815
- for key, value in kwds.items():
816
- self[key] = value
817
-
818
- __update = update # let subclasses override update without breaking __init__
819
-
820
- __marker = object()
821
-
822
- def pop(self, key, default=__marker):
823
- '''od.pop(k[,d]) -> v, remove specified key and return the corresponding value.
824
- If key is not found, d is returned if given, otherwise KeyError is raised.
825
-
826
- '''
827
- if key in self:
828
- result = self[key]
829
- del self[key]
830
- return result
831
- if default is self.__marker:
832
- raise KeyError(key)
833
- return default
834
-
835
- def setdefault(self, key, default=None):
836
- 'od.setdefault(k[,d]) -> od.get(k,d), also set od[k]=d if k not in od'
837
- if key in self:
838
- return self[key]
839
- self[key] = default
840
- return default
841
-
842
- def __repr__(self, _repr_running=None):
843
- 'od.__repr__() <==> repr(od)'
844
- if not _repr_running:
845
- _repr_running = {}
846
- call_key = id(self), _get_ident()
847
- if call_key in _repr_running:
848
- return '...'
849
- _repr_running[call_key] = 1
850
- try:
851
- if not self:
852
- return '%s()' % (self.__class__.__name__, )
853
- return '%s(%r)' % (self.__class__.__name__, self.items())
854
- finally:
855
- del _repr_running[call_key]
856
-
857
- def __reduce__(self):
858
- 'Return state information for pickling'
859
- items = [[k, self[k]] for k in self]
860
- inst_dict = vars(self).copy()
861
- for k in vars(OrderedDict()):
862
- inst_dict.pop(k, None)
863
- if inst_dict:
864
- return (self.__class__, (items, ), inst_dict)
865
- return self.__class__, (items, )
866
-
867
- def copy(self):
868
- 'od.copy() -> a shallow copy of od'
869
- return self.__class__(self)
870
-
871
- @classmethod
872
- def fromkeys(cls, iterable, value=None):
873
- '''OD.fromkeys(S[, v]) -> New ordered dictionary with keys from S
874
- and values equal to v (which defaults to None).
875
-
876
- '''
877
- d = cls()
878
- for key in iterable:
879
- d[key] = value
880
- return d
881
-
882
- def __eq__(self, other):
883
- '''od.__eq__(y) <==> od==y. Comparison to another OD is order-sensitive
884
- while comparison to a regular mapping is order-insensitive.
885
-
886
- '''
887
- if isinstance(other, OrderedDict):
888
- return len(self) == len(
889
- other) and self.items() == other.items()
890
- return dict.__eq__(self, other)
891
-
892
- def __ne__(self, other):
893
- return not self == other
894
-
895
- # -- the following methods are only used in Python 2.7 --
896
-
897
- def viewkeys(self):
898
- "od.viewkeys() -> a set-like object providing a view on od's keys"
899
- return KeysView(self)
900
-
901
- def viewvalues(self):
902
- "od.viewvalues() -> an object providing a view on od's values"
903
- return ValuesView(self)
904
-
905
- def viewitems(self):
906
- "od.viewitems() -> a set-like object providing a view on od's items"
907
- return ItemsView(self)
908
-
909
-
910
- try:
911
- from logging.config import BaseConfigurator, valid_ident
912
- except ImportError: # pragma: no cover
913
- IDENTIFIER = re.compile('^[a-z_][a-z0-9_]*$', re.I)
914
-
915
- def valid_ident(s):
916
- m = IDENTIFIER.match(s)
917
- if not m:
918
- raise ValueError('Not a valid Python identifier: %r' % s)
919
- return True
920
-
921
- # The ConvertingXXX classes are wrappers around standard Python containers,
922
- # and they serve to convert any suitable values in the container. The
923
- # conversion converts base dicts, lists and tuples to their wrapped
924
- # equivalents, whereas strings which match a conversion format are converted
925
- # appropriately.
926
- #
927
- # Each wrapper should have a configurator attribute holding the actual
928
- # configurator to use for conversion.
929
-
930
- class ConvertingDict(dict):
931
- """A converting dictionary wrapper."""
932
-
933
- def __getitem__(self, key):
934
- value = dict.__getitem__(self, key)
935
- result = self.configurator.convert(value)
936
- # If the converted value is different, save for next time
937
- if value is not result:
938
- self[key] = result
939
- if type(result) in (ConvertingDict, ConvertingList,
940
- ConvertingTuple):
941
- result.parent = self
942
- result.key = key
943
- return result
944
-
945
- def get(self, key, default=None):
946
- value = dict.get(self, key, default)
947
- result = self.configurator.convert(value)
948
- # If the converted value is different, save for next time
949
- if value is not result:
950
- self[key] = result
951
- if type(result) in (ConvertingDict, ConvertingList,
952
- ConvertingTuple):
953
- result.parent = self
954
- result.key = key
955
- return result
956
-
957
- def pop(self, key, default=None):
958
- value = dict.pop(self, key, default)
959
- result = self.configurator.convert(value)
960
- if value is not result:
961
- if type(result) in (ConvertingDict, ConvertingList,
962
- ConvertingTuple):
963
- result.parent = self
964
- result.key = key
965
- return result
966
-
967
- class ConvertingList(list):
968
- """A converting list wrapper."""
969
-
970
- def __getitem__(self, key):
971
- value = list.__getitem__(self, key)
972
- result = self.configurator.convert(value)
973
- # If the converted value is different, save for next time
974
- if value is not result:
975
- self[key] = result
976
- if type(result) in (ConvertingDict, ConvertingList,
977
- ConvertingTuple):
978
- result.parent = self
979
- result.key = key
980
- return result
981
-
982
- def pop(self, idx=-1):
983
- value = list.pop(self, idx)
984
- result = self.configurator.convert(value)
985
- if value is not result:
986
- if type(result) in (ConvertingDict, ConvertingList,
987
- ConvertingTuple):
988
- result.parent = self
989
- return result
990
-
991
- class ConvertingTuple(tuple):
992
- """A converting tuple wrapper."""
993
-
994
- def __getitem__(self, key):
995
- value = tuple.__getitem__(self, key)
996
- result = self.configurator.convert(value)
997
- if value is not result:
998
- if type(result) in (ConvertingDict, ConvertingList,
999
- ConvertingTuple):
1000
- result.parent = self
1001
- result.key = key
1002
- return result
1003
-
1004
- class BaseConfigurator(object):
1005
- """
1006
- The configurator base class which defines some useful defaults.
1007
- """
1008
-
1009
- CONVERT_PATTERN = re.compile(r'^(?P<prefix>[a-z]+)://(?P<suffix>.*)$')
1010
-
1011
- WORD_PATTERN = re.compile(r'^\s*(\w+)\s*')
1012
- DOT_PATTERN = re.compile(r'^\.\s*(\w+)\s*')
1013
- INDEX_PATTERN = re.compile(r'^\[\s*(\w+)\s*\]\s*')
1014
- DIGIT_PATTERN = re.compile(r'^\d+$')
1015
-
1016
- value_converters = {
1017
- 'ext': 'ext_convert',
1018
- 'cfg': 'cfg_convert',
1019
- }
1020
-
1021
- # We might want to use a different one, e.g. importlib
1022
- importer = staticmethod(__import__)
1023
-
1024
- def __init__(self, config):
1025
- self.config = ConvertingDict(config)
1026
- self.config.configurator = self
1027
-
1028
- def resolve(self, s):
1029
- """
1030
- Resolve strings to objects using standard import and attribute
1031
- syntax.
1032
- """
1033
- name = s.split('.')
1034
- used = name.pop(0)
1035
- try:
1036
- found = self.importer(used)
1037
- for frag in name:
1038
- used += '.' + frag
1039
- try:
1040
- found = getattr(found, frag)
1041
- except AttributeError:
1042
- self.importer(used)
1043
- found = getattr(found, frag)
1044
- return found
1045
- except ImportError:
1046
- e, tb = sys.exc_info()[1:]
1047
- v = ValueError('Cannot resolve %r: %s' % (s, e))
1048
- v.__cause__, v.__traceback__ = e, tb
1049
- raise v
1050
-
1051
- def ext_convert(self, value):
1052
- """Default converter for the ext:// protocol."""
1053
- return self.resolve(value)
1054
-
1055
- def cfg_convert(self, value):
1056
- """Default converter for the cfg:// protocol."""
1057
- rest = value
1058
- m = self.WORD_PATTERN.match(rest)
1059
- if m is None:
1060
- raise ValueError("Unable to convert %r" % value)
1061
- else:
1062
- rest = rest[m.end():]
1063
- d = self.config[m.groups()[0]]
1064
- while rest:
1065
- m = self.DOT_PATTERN.match(rest)
1066
- if m:
1067
- d = d[m.groups()[0]]
1068
- else:
1069
- m = self.INDEX_PATTERN.match(rest)
1070
- if m:
1071
- idx = m.groups()[0]
1072
- if not self.DIGIT_PATTERN.match(idx):
1073
- d = d[idx]
1074
- else:
1075
- try:
1076
- n = int(
1077
- idx
1078
- ) # try as number first (most likely)
1079
- d = d[n]
1080
- except TypeError:
1081
- d = d[idx]
1082
- if m:
1083
- rest = rest[m.end():]
1084
- else:
1085
- raise ValueError('Unable to convert '
1086
- '%r at %r' % (value, rest))
1087
- # rest should be empty
1088
- return d
1089
-
1090
- def convert(self, value):
1091
- """
1092
- Convert values to an appropriate type. dicts, lists and tuples are
1093
- replaced by their converting alternatives. Strings are checked to
1094
- see if they have a conversion format and are converted if they do.
1095
- """
1096
- if not isinstance(value, ConvertingDict) and isinstance(
1097
- value, dict):
1098
- value = ConvertingDict(value)
1099
- value.configurator = self
1100
- elif not isinstance(value, ConvertingList) and isinstance(
1101
- value, list):
1102
- value = ConvertingList(value)
1103
- value.configurator = self
1104
- elif not isinstance(value, ConvertingTuple) and isinstance(value, tuple):
1105
- value = ConvertingTuple(value)
1106
- value.configurator = self
1107
- elif isinstance(value, string_types):
1108
- m = self.CONVERT_PATTERN.match(value)
1109
- if m:
1110
- d = m.groupdict()
1111
- prefix = d['prefix']
1112
- converter = self.value_converters.get(prefix, None)
1113
- if converter:
1114
- suffix = d['suffix']
1115
- converter = getattr(self, converter)
1116
- value = converter(suffix)
1117
- return value
1118
-
1119
- def configure_custom(self, config):
1120
- """Configure an object with a user-supplied factory."""
1121
- c = config.pop('()')
1122
- if not callable(c):
1123
- c = self.resolve(c)
1124
- props = config.pop('.', None)
1125
- # Check for valid identifiers
1126
- kwargs = dict([(k, config[k]) for k in config if valid_ident(k)])
1127
- result = c(**kwargs)
1128
- if props:
1129
- for name, value in props.items():
1130
- setattr(result, name, value)
1131
- return result
1132
-
1133
- def as_tuple(self, value):
1134
- """Utility function which converts lists to tuples."""
1135
- if isinstance(value, list):
1136
- value = tuple(value)
1137
- return value