com.googler.python 1.0.7 → 1.0.9

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 (354) hide show
  1. package/package.json +4 -2
  2. package/python3.4.2/lib/python3.4/site-packages/pip/__init__.py +1 -277
  3. package/python3.4.2/lib/python3.4/site-packages/pip/__main__.py +19 -7
  4. package/python3.4.2/lib/python3.4/site-packages/pip/_internal/__init__.py +246 -0
  5. package/python3.4.2/lib/python3.4/site-packages/pip/_internal/basecommand.py +373 -0
  6. package/python3.4.2/lib/python3.4/site-packages/pip/{baseparser.py → _internal/baseparser.py} +240 -224
  7. package/python3.4.2/lib/python3.4/site-packages/pip/_internal/build_env.py +92 -0
  8. package/python3.4.2/lib/python3.4/site-packages/pip/_internal/cache.py +202 -0
  9. package/python3.4.2/lib/python3.4/site-packages/pip/_internal/cmdoptions.py +609 -0
  10. package/python3.4.2/lib/python3.4/site-packages/pip/_internal/commands/__init__.py +79 -0
  11. package/python3.4.2/lib/python3.4/site-packages/pip/_internal/commands/check.py +42 -0
  12. package/python3.4.2/lib/python3.4/site-packages/pip/_internal/commands/completion.py +94 -0
  13. package/python3.4.2/lib/python3.4/site-packages/pip/_internal/commands/configuration.py +227 -0
  14. package/python3.4.2/lib/python3.4/site-packages/pip/_internal/commands/download.py +233 -0
  15. package/python3.4.2/lib/python3.4/site-packages/pip/_internal/commands/freeze.py +96 -0
  16. package/python3.4.2/lib/python3.4/site-packages/pip/_internal/commands/hash.py +57 -0
  17. package/python3.4.2/lib/python3.4/site-packages/pip/{commands → _internal/commands}/help.py +36 -33
  18. package/python3.4.2/lib/python3.4/site-packages/pip/_internal/commands/install.py +477 -0
  19. package/python3.4.2/lib/python3.4/site-packages/pip/_internal/commands/list.py +343 -0
  20. package/python3.4.2/lib/python3.4/site-packages/pip/_internal/commands/search.py +135 -0
  21. package/python3.4.2/lib/python3.4/site-packages/pip/_internal/commands/show.py +164 -0
  22. package/python3.4.2/lib/python3.4/site-packages/pip/_internal/commands/uninstall.py +71 -0
  23. package/python3.4.2/lib/python3.4/site-packages/pip/_internal/commands/wheel.py +179 -0
  24. package/python3.4.2/lib/python3.4/site-packages/pip/_internal/compat.py +235 -0
  25. package/python3.4.2/lib/python3.4/site-packages/pip/_internal/configuration.py +378 -0
  26. package/python3.4.2/lib/python3.4/site-packages/pip/_internal/download.py +922 -0
  27. package/python3.4.2/lib/python3.4/site-packages/pip/_internal/exceptions.py +249 -0
  28. package/python3.4.2/lib/python3.4/site-packages/pip/_internal/index.py +1117 -0
  29. package/python3.4.2/lib/python3.4/site-packages/pip/_internal/locations.py +194 -0
  30. package/python3.4.2/lib/python3.4/site-packages/pip/_internal/models/__init__.py +4 -0
  31. package/python3.4.2/lib/python3.4/site-packages/pip/_internal/models/index.py +15 -0
  32. package/python3.4.2/lib/python3.4/site-packages/pip/{_vendor/requests/packages/urllib3/contrib → _internal/operations}/__init__.py +0 -0
  33. package/python3.4.2/lib/python3.4/site-packages/pip/_internal/operations/check.py +106 -0
  34. package/python3.4.2/lib/python3.4/site-packages/pip/_internal/operations/freeze.py +252 -0
  35. package/python3.4.2/lib/python3.4/site-packages/pip/_internal/operations/prepare.py +378 -0
  36. package/python3.4.2/lib/python3.4/site-packages/pip/_internal/pep425tags.py +317 -0
  37. package/python3.4.2/lib/python3.4/site-packages/pip/_internal/req/__init__.py +69 -0
  38. package/python3.4.2/lib/python3.4/site-packages/pip/_internal/req/req_file.py +338 -0
  39. package/python3.4.2/lib/python3.4/site-packages/pip/_internal/req/req_install.py +1115 -0
  40. package/python3.4.2/lib/python3.4/site-packages/pip/_internal/req/req_set.py +164 -0
  41. package/python3.4.2/lib/python3.4/site-packages/pip/_internal/req/req_uninstall.py +455 -0
  42. package/python3.4.2/lib/python3.4/site-packages/pip/_internal/resolve.py +354 -0
  43. package/python3.4.2/lib/python3.4/site-packages/pip/{status_codes.py → _internal/status_codes.py} +8 -6
  44. package/python3.4.2/lib/python3.4/site-packages/pip/_internal/utils/__init__.py +0 -0
  45. package/python3.4.2/lib/python3.4/site-packages/pip/_internal/utils/appdirs.py +258 -0
  46. package/python3.4.2/lib/python3.4/site-packages/pip/_internal/utils/deprecation.py +77 -0
  47. package/python3.4.2/lib/python3.4/site-packages/pip/_internal/utils/encoding.py +33 -0
  48. package/python3.4.2/lib/python3.4/site-packages/pip/_internal/utils/filesystem.py +28 -0
  49. package/python3.4.2/lib/python3.4/site-packages/pip/_internal/utils/glibc.py +84 -0
  50. package/python3.4.2/lib/python3.4/site-packages/pip/_internal/utils/hashes.py +94 -0
  51. package/python3.4.2/lib/python3.4/site-packages/pip/_internal/utils/logging.py +132 -0
  52. package/python3.4.2/lib/python3.4/site-packages/pip/_internal/utils/misc.py +851 -0
  53. package/python3.4.2/lib/python3.4/site-packages/pip/_internal/utils/outdated.py +163 -0
  54. package/python3.4.2/lib/python3.4/site-packages/pip/_internal/utils/packaging.py +70 -0
  55. package/python3.4.2/lib/python3.4/site-packages/pip/_internal/utils/setuptools_build.py +8 -0
  56. package/python3.4.2/lib/python3.4/site-packages/pip/_internal/utils/temp_dir.py +82 -0
  57. package/python3.4.2/lib/python3.4/site-packages/pip/_internal/utils/typing.py +29 -0
  58. package/python3.4.2/lib/python3.4/site-packages/pip/_internal/utils/ui.py +421 -0
  59. package/python3.4.2/lib/python3.4/site-packages/pip/_internal/vcs/__init__.py +471 -0
  60. package/python3.4.2/lib/python3.4/site-packages/pip/_internal/vcs/bazaar.py +113 -0
  61. package/python3.4.2/lib/python3.4/site-packages/pip/_internal/vcs/git.py +311 -0
  62. package/python3.4.2/lib/python3.4/site-packages/pip/_internal/vcs/mercurial.py +105 -0
  63. package/python3.4.2/lib/python3.4/site-packages/pip/_internal/vcs/subversion.py +271 -0
  64. package/python3.4.2/lib/python3.4/site-packages/pip/_internal/wheel.py +817 -0
  65. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/__init__.py +109 -8
  66. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/appdirs.py +604 -0
  67. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/cachecontrol/__init__.py +11 -0
  68. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/cachecontrol/_cmd.py +60 -0
  69. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/cachecontrol/adapter.py +134 -0
  70. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/cachecontrol/cache.py +39 -0
  71. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/cachecontrol/caches/__init__.py +2 -0
  72. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/cachecontrol/caches/file_cache.py +133 -0
  73. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/cachecontrol/caches/redis_cache.py +43 -0
  74. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/cachecontrol/compat.py +29 -0
  75. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/cachecontrol/controller.py +373 -0
  76. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/cachecontrol/filewrapper.py +78 -0
  77. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/cachecontrol/heuristics.py +138 -0
  78. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/cachecontrol/serialize.py +194 -0
  79. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/cachecontrol/wrapper.py +27 -0
  80. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/certifi/__init__.py +3 -0
  81. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/certifi/__main__.py +2 -0
  82. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/{requests → certifi}/cacert.pem +1765 -2358
  83. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/certifi/core.py +37 -0
  84. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/{requests/packages/chardet → chardet}/__init__.py +39 -32
  85. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/chardet/big5freq.py +386 -0
  86. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/{requests/packages/chardet → chardet}/big5prober.py +47 -42
  87. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/{requests/packages/chardet → chardet}/chardistribution.py +233 -231
  88. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/chardet/charsetgroupprober.py +106 -0
  89. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/chardet/charsetprober.py +145 -0
  90. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/chardet/cli/__init__.py +1 -0
  91. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/chardet/cli/chardetect.py +85 -0
  92. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/chardet/codingstatemachine.py +88 -0
  93. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/{requests/packages/chardet → chardet}/compat.py +34 -34
  94. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/{requests/packages/chardet → chardet}/cp949prober.py +49 -44
  95. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/chardet/enums.py +76 -0
  96. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/chardet/escprober.py +101 -0
  97. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/chardet/escsm.py +246 -0
  98. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/chardet/eucjpprober.py +92 -0
  99. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/chardet/euckrfreq.py +195 -0
  100. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/{requests/packages/chardet → chardet}/euckrprober.py +47 -42
  101. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/{requests/packages/chardet → chardet}/euctwfreq.py +387 -428
  102. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/{requests/packages/chardet → chardet}/euctwprober.py +46 -41
  103. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/{requests/packages/chardet → chardet}/gb2312freq.py +283 -472
  104. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/{requests/packages/chardet → chardet}/gb2312prober.py +46 -41
  105. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/{requests/packages/chardet → chardet}/hebrewprober.py +292 -283
  106. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/{requests/packages/chardet → chardet}/jisfreq.py +325 -569
  107. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/{requests/packages/chardet → chardet}/jpcntx.py +233 -219
  108. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/{requests/packages/chardet → chardet}/langbulgarianmodel.py +228 -229
  109. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/{requests/packages/chardet → chardet}/langcyrillicmodel.py +333 -329
  110. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/{requests/packages/chardet → chardet}/langgreekmodel.py +225 -225
  111. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/{requests/packages/chardet → chardet}/langhebrewmodel.py +200 -201
  112. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/{requests/packages/chardet → chardet}/langhungarianmodel.py +225 -225
  113. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/{requests/packages/chardet → chardet}/langthaimodel.py +199 -200
  114. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/chardet/langturkishmodel.py +193 -0
  115. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/{requests/packages/chardet → chardet}/latin1prober.py +145 -139
  116. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/chardet/mbcharsetprober.py +91 -0
  117. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/{requests/packages/chardet → chardet}/mbcsgroupprober.py +54 -54
  118. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/chardet/mbcssm.py +572 -0
  119. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/chardet/sbcharsetprober.py +132 -0
  120. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/{requests/packages/chardet → chardet}/sbcsgroupprober.py +73 -69
  121. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/chardet/sjisprober.py +92 -0
  122. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/chardet/universaldetector.py +286 -0
  123. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/{requests/packages/chardet → chardet}/utf8prober.py +82 -76
  124. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/chardet/version.py +9 -0
  125. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/colorama/__init__.py +7 -7
  126. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/colorama/ansi.py +102 -50
  127. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/colorama/ansitowin32.py +236 -190
  128. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/colorama/initialise.py +82 -56
  129. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/colorama/win32.py +156 -137
  130. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/colorama/winterm.py +162 -120
  131. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/distlib/__init__.py +23 -23
  132. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/distlib/_backport/__init__.py +6 -6
  133. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/distlib/_backport/misc.py +41 -41
  134. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/distlib/_backport/shutil.py +761 -761
  135. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/distlib/_backport/sysconfig.cfg +84 -84
  136. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/distlib/_backport/sysconfig.py +788 -788
  137. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/distlib/_backport/tarfile.py +2607 -2607
  138. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/distlib/compat.py +1117 -1064
  139. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/distlib/database.py +1318 -1301
  140. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/distlib/index.py +516 -488
  141. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/distlib/locators.py +1292 -1194
  142. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/distlib/manifest.py +393 -364
  143. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/distlib/markers.py +131 -190
  144. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/distlib/metadata.py +1068 -1026
  145. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/distlib/resources.py +355 -317
  146. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/distlib/scripts.py +415 -323
  147. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/distlib/t32.exe +0 -0
  148. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/distlib/t64.exe +0 -0
  149. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/distlib/util.py +1755 -1575
  150. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/distlib/version.py +736 -721
  151. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/distlib/w32.exe +0 -0
  152. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/distlib/w64.exe +0 -0
  153. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/distlib/wheel.py +984 -958
  154. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/distro.py +1104 -0
  155. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/html5lib/__init__.py +35 -23
  156. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/html5lib/{ihatexml.py → _ihatexml.py} +288 -285
  157. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/html5lib/{inputstream.py → _inputstream.py} +923 -881
  158. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/html5lib/{tokenizer.py → _tokenizer.py} +1721 -1731
  159. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/html5lib/{trie → _trie}/__init__.py +14 -12
  160. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/html5lib/{trie → _trie}/_base.py +37 -37
  161. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/html5lib/{trie → _trie}/datrie.py +44 -44
  162. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/html5lib/{trie → _trie}/py.py +67 -67
  163. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/html5lib/{utils.py → _utils.py} +124 -82
  164. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/html5lib/constants.py +2947 -3104
  165. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/html5lib/filters/alphabeticalattributes.py +29 -20
  166. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/html5lib/filters/{_base.py → base.py} +12 -12
  167. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/html5lib/filters/inject_meta_charset.py +73 -65
  168. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/html5lib/filters/lint.py +93 -93
  169. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/html5lib/filters/optionaltags.py +207 -205
  170. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/html5lib/filters/sanitizer.py +896 -12
  171. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/html5lib/filters/whitespace.py +38 -38
  172. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/html5lib/html5parser.py +2791 -2713
  173. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/html5lib/serializer.py +409 -0
  174. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/html5lib/treeadapters/__init__.py +30 -0
  175. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/html5lib/treeadapters/genshi.py +54 -0
  176. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/html5lib/treeadapters/sax.py +50 -44
  177. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/html5lib/treebuilders/__init__.py +88 -76
  178. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/html5lib/treebuilders/{_base.py → base.py} +417 -377
  179. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/html5lib/treebuilders/dom.py +236 -227
  180. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/html5lib/treebuilders/etree.py +340 -337
  181. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/html5lib/treebuilders/etree_lxml.py +366 -369
  182. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/html5lib/treewalkers/__init__.py +154 -57
  183. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/html5lib/treewalkers/{_base.py → base.py} +252 -200
  184. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/html5lib/treewalkers/dom.py +43 -46
  185. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/html5lib/treewalkers/etree.py +130 -138
  186. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/html5lib/treewalkers/{lxmletree.py → etree_lxml.py} +213 -208
  187. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/html5lib/treewalkers/{genshistream.py → genshi.py} +69 -69
  188. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/idna/__init__.py +2 -0
  189. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/idna/codec.py +118 -0
  190. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/idna/compat.py +12 -0
  191. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/idna/core.py +387 -0
  192. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/idna/idnadata.py +1585 -0
  193. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/idna/intranges.py +53 -0
  194. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/idna/package_data.py +2 -0
  195. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/idna/uts46data.py +7634 -0
  196. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/ipaddress.py +2419 -0
  197. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/lockfile/__init__.py +347 -0
  198. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/lockfile/linklockfile.py +73 -0
  199. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/lockfile/mkdirlockfile.py +84 -0
  200. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/lockfile/pidlockfile.py +190 -0
  201. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/lockfile/sqlitelockfile.py +156 -0
  202. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/lockfile/symlinklockfile.py +70 -0
  203. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/msgpack/__init__.py +66 -0
  204. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/msgpack/_version.py +1 -0
  205. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/msgpack/exceptions.py +41 -0
  206. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/msgpack/fallback.py +971 -0
  207. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/packaging/__about__.py +21 -0
  208. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/packaging/__init__.py +14 -0
  209. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/packaging/_compat.py +30 -0
  210. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/packaging/_structures.py +70 -0
  211. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/packaging/markers.py +301 -0
  212. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/packaging/requirements.py +130 -0
  213. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/packaging/specifiers.py +774 -0
  214. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/packaging/utils.py +63 -0
  215. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/packaging/version.py +441 -0
  216. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/{pkg_resources.py → pkg_resources/__init__.py} +3125 -2762
  217. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/pkg_resources/py31compat.py +22 -0
  218. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/progress/__init__.py +127 -0
  219. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/progress/bar.py +88 -0
  220. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/progress/counter.py +48 -0
  221. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/progress/helpers.py +91 -0
  222. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/progress/spinner.py +44 -0
  223. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/pyparsing.py +5720 -0
  224. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/pytoml/__init__.py +3 -0
  225. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/pytoml/core.py +13 -0
  226. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/pytoml/parser.py +374 -0
  227. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/pytoml/writer.py +127 -0
  228. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/requests/__init__.py +123 -77
  229. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/requests/__version__.py +14 -0
  230. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/requests/_internal_utils.py +42 -0
  231. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/requests/adapters.py +525 -388
  232. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/requests/api.py +152 -120
  233. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/requests/auth.py +293 -193
  234. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/requests/certs.py +18 -24
  235. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/requests/compat.py +73 -115
  236. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/requests/cookies.py +542 -454
  237. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/requests/exceptions.py +122 -75
  238. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/requests/help.py +120 -0
  239. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/requests/hooks.py +34 -45
  240. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/requests/models.py +948 -803
  241. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/requests/packages.py +16 -0
  242. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/requests/sessions.py +737 -637
  243. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/requests/status_codes.py +91 -88
  244. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/requests/structures.py +105 -127
  245. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/requests/utils.py +904 -673
  246. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/retrying.py +267 -0
  247. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/six.py +891 -646
  248. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/urllib3/__init__.py +97 -0
  249. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/urllib3/_collections.py +319 -0
  250. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/urllib3/connection.py +373 -0
  251. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/{requests/packages/urllib3 → urllib3}/connectionpool.py +905 -710
  252. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/urllib3/contrib/__init__.py +0 -0
  253. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/urllib3/contrib/_securetransport/__init__.py +0 -0
  254. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/urllib3/contrib/_securetransport/bindings.py +593 -0
  255. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/urllib3/contrib/_securetransport/low_level.py +343 -0
  256. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/urllib3/contrib/appengine.py +296 -0
  257. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/{requests/packages/urllib3 → urllib3}/contrib/ntlmpool.py +112 -120
  258. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/urllib3/contrib/pyopenssl.py +455 -0
  259. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/urllib3/contrib/securetransport.py +810 -0
  260. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/urllib3/contrib/socks.py +188 -0
  261. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/urllib3/exceptions.py +246 -0
  262. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/{requests/packages/urllib3 → urllib3}/fields.py +178 -177
  263. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/{requests/packages/urllib3 → urllib3}/filepost.py +94 -100
  264. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/{requests/packages/urllib3 → urllib3}/packages/__init__.py +5 -4
  265. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/urllib3/packages/backports/__init__.py +0 -0
  266. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/urllib3/packages/backports/makefile.py +53 -0
  267. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/{requests/packages/urllib3 → urllib3}/packages/ordered_dict.py +259 -260
  268. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/urllib3/packages/six.py +868 -0
  269. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/{requests/packages/urllib3 → urllib3}/packages/ssl_match_hostname/__init__.py +19 -13
  270. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/{requests/packages/urllib3 → urllib3}/packages/ssl_match_hostname/_implementation.py +157 -105
  271. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/urllib3/poolmanager.py +440 -0
  272. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/{requests/packages/urllib3 → urllib3}/request.py +148 -141
  273. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/urllib3/response.py +626 -0
  274. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/urllib3/util/__init__.py +54 -0
  275. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/urllib3/util/connection.py +130 -0
  276. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/urllib3/util/request.py +118 -0
  277. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/urllib3/util/response.py +81 -0
  278. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/urllib3/util/retry.py +401 -0
  279. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/urllib3/util/selectors.py +581 -0
  280. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/urllib3/util/ssl_.py +341 -0
  281. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/{requests/packages/urllib3 → urllib3}/util/timeout.py +242 -234
  282. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/{requests/packages/urllib3 → urllib3}/util/url.py +230 -162
  283. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/urllib3/util/wait.py +40 -0
  284. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/webencodings/__init__.py +342 -0
  285. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/webencodings/labels.py +231 -0
  286. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/webencodings/mklabels.py +59 -0
  287. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/webencodings/tests.py +153 -0
  288. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/webencodings/x_user_defined.py +325 -0
  289. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/_markerlib/__init__.py +0 -16
  290. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/_markerlib/markers.py +0 -119
  291. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/html5lib/sanitizer.py +0 -271
  292. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/html5lib/serializer/__init__.py +0 -16
  293. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/html5lib/serializer/htmlserializer.py +0 -320
  294. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/html5lib/treewalkers/pulldom.py +0 -63
  295. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/re-vendor.py +0 -34
  296. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/requests/packages/__init__.py +0 -3
  297. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/requests/packages/chardet/big5freq.py +0 -925
  298. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/requests/packages/chardet/chardetect.py +0 -46
  299. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/requests/packages/chardet/charsetgroupprober.py +0 -106
  300. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/requests/packages/chardet/charsetprober.py +0 -62
  301. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/requests/packages/chardet/codingstatemachine.py +0 -61
  302. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/requests/packages/chardet/constants.py +0 -39
  303. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/requests/packages/chardet/escprober.py +0 -86
  304. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/requests/packages/chardet/escsm.py +0 -242
  305. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/requests/packages/chardet/eucjpprober.py +0 -90
  306. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/requests/packages/chardet/euckrfreq.py +0 -596
  307. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/requests/packages/chardet/mbcharsetprober.py +0 -86
  308. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/requests/packages/chardet/mbcssm.py +0 -575
  309. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/requests/packages/chardet/sbcharsetprober.py +0 -120
  310. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/requests/packages/chardet/sjisprober.py +0 -91
  311. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/requests/packages/chardet/universaldetector.py +0 -170
  312. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/requests/packages/urllib3/__init__.py +0 -58
  313. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/requests/packages/urllib3/_collections.py +0 -205
  314. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/requests/packages/urllib3/connection.py +0 -204
  315. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/requests/packages/urllib3/contrib/pyopenssl.py +0 -422
  316. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/requests/packages/urllib3/exceptions.py +0 -126
  317. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/requests/packages/urllib3/packages/six.py +0 -385
  318. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/requests/packages/urllib3/poolmanager.py +0 -258
  319. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/requests/packages/urllib3/response.py +0 -308
  320. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/requests/packages/urllib3/util/__init__.py +0 -27
  321. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/requests/packages/urllib3/util/connection.py +0 -45
  322. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/requests/packages/urllib3/util/request.py +0 -68
  323. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/requests/packages/urllib3/util/response.py +0 -13
  324. package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/requests/packages/urllib3/util/ssl_.py +0 -133
  325. package/python3.4.2/lib/python3.4/site-packages/pip/backwardcompat/__init__.py +0 -138
  326. package/python3.4.2/lib/python3.4/site-packages/pip/basecommand.py +0 -201
  327. package/python3.4.2/lib/python3.4/site-packages/pip/cmdoptions.py +0 -371
  328. package/python3.4.2/lib/python3.4/site-packages/pip/commands/__init__.py +0 -88
  329. package/python3.4.2/lib/python3.4/site-packages/pip/commands/bundle.py +0 -42
  330. package/python3.4.2/lib/python3.4/site-packages/pip/commands/completion.py +0 -59
  331. package/python3.4.2/lib/python3.4/site-packages/pip/commands/freeze.py +0 -114
  332. package/python3.4.2/lib/python3.4/site-packages/pip/commands/install.py +0 -314
  333. package/python3.4.2/lib/python3.4/site-packages/pip/commands/list.py +0 -162
  334. package/python3.4.2/lib/python3.4/site-packages/pip/commands/search.py +0 -132
  335. package/python3.4.2/lib/python3.4/site-packages/pip/commands/show.py +0 -80
  336. package/python3.4.2/lib/python3.4/site-packages/pip/commands/uninstall.py +0 -59
  337. package/python3.4.2/lib/python3.4/site-packages/pip/commands/unzip.py +0 -7
  338. package/python3.4.2/lib/python3.4/site-packages/pip/commands/wheel.py +0 -195
  339. package/python3.4.2/lib/python3.4/site-packages/pip/commands/zip.py +0 -351
  340. package/python3.4.2/lib/python3.4/site-packages/pip/download.py +0 -644
  341. package/python3.4.2/lib/python3.4/site-packages/pip/exceptions.py +0 -46
  342. package/python3.4.2/lib/python3.4/site-packages/pip/index.py +0 -990
  343. package/python3.4.2/lib/python3.4/site-packages/pip/locations.py +0 -171
  344. package/python3.4.2/lib/python3.4/site-packages/pip/log.py +0 -276
  345. package/python3.4.2/lib/python3.4/site-packages/pip/pep425tags.py +0 -102
  346. package/python3.4.2/lib/python3.4/site-packages/pip/req.py +0 -1931
  347. package/python3.4.2/lib/python3.4/site-packages/pip/runner.py +0 -18
  348. package/python3.4.2/lib/python3.4/site-packages/pip/util.py +0 -720
  349. package/python3.4.2/lib/python3.4/site-packages/pip/vcs/__init__.py +0 -251
  350. package/python3.4.2/lib/python3.4/site-packages/pip/vcs/bazaar.py +0 -131
  351. package/python3.4.2/lib/python3.4/site-packages/pip/vcs/git.py +0 -194
  352. package/python3.4.2/lib/python3.4/site-packages/pip/vcs/mercurial.py +0 -151
  353. package/python3.4.2/lib/python3.4/site-packages/pip/vcs/subversion.py +0 -273
  354. package/python3.4.2/lib/python3.4/site-packages/pip/wheel.py +0 -560
@@ -1,488 +1,516 @@
1
- # -*- coding: utf-8 -*-
2
- #
3
- # Copyright (C) 2013 Vinay Sajip.
4
- # Licensed to the Python Software Foundation under a contributor agreement.
5
- # See LICENSE.txt and CONTRIBUTORS.txt.
6
- #
7
- import hashlib
8
- import logging
9
- import os
10
- import shutil
11
- import subprocess
12
- import tempfile
13
- try:
14
- from threading import Thread
15
- except ImportError:
16
- from dummy_threading import Thread
17
-
18
- from . import DistlibException
19
- from .compat import (HTTPBasicAuthHandler, Request, HTTPPasswordMgr,
20
- urlparse, build_opener, string_types)
21
- from .util import cached_property, zip_dir, ServerProxy
22
-
23
- logger = logging.getLogger(__name__)
24
-
25
- DEFAULT_INDEX = 'https://pypi.python.org/pypi'
26
- DEFAULT_REALM = 'pypi'
27
-
28
- class PackageIndex(object):
29
- """
30
- This class represents a package index compatible with PyPI, the Python
31
- Package Index.
32
- """
33
-
34
- boundary = b'----------ThIs_Is_tHe_distlib_index_bouNdaRY_$'
35
-
36
- def __init__(self, url=None):
37
- """
38
- Initialise an instance.
39
-
40
- :param url: The URL of the index. If not specified, the URL for PyPI is
41
- used.
42
- """
43
- self.url = url or DEFAULT_INDEX
44
- self.read_configuration()
45
- scheme, netloc, path, params, query, frag = urlparse(self.url)
46
- if params or query or frag or scheme not in ('http', 'https'):
47
- raise DistlibException('invalid repository: %s' % self.url)
48
- self.password_handler = None
49
- self.ssl_verifier = None
50
- self.gpg = None
51
- self.gpg_home = None
52
- self.rpc_proxy = None
53
- with open(os.devnull, 'w') as sink:
54
- for s in ('gpg2', 'gpg'):
55
- try:
56
- rc = subprocess.check_call([s, '--version'], stdout=sink,
57
- stderr=sink)
58
- if rc == 0:
59
- self.gpg = s
60
- break
61
- except OSError:
62
- pass
63
-
64
- def _get_pypirc_command(self):
65
- """
66
- Get the distutils command for interacting with PyPI configurations.
67
- :return: the command.
68
- """
69
- from distutils.core import Distribution
70
- from distutils.config import PyPIRCCommand
71
- d = Distribution()
72
- return PyPIRCCommand(d)
73
-
74
- def read_configuration(self):
75
- """
76
- Read the PyPI access configuration as supported by distutils, getting
77
- PyPI to do the acutal work. This populates ``username``, ``password``,
78
- ``realm`` and ``url`` attributes from the configuration.
79
- """
80
- # get distutils to do the work
81
- c = self._get_pypirc_command()
82
- c.repository = self.url
83
- cfg = c._read_pypirc()
84
- self.username = cfg.get('username')
85
- self.password = cfg.get('password')
86
- self.realm = cfg.get('realm', 'pypi')
87
- self.url = cfg.get('repository', self.url)
88
-
89
- def save_configuration(self):
90
- """
91
- Save the PyPI access configuration. You must have set ``username`` and
92
- ``password`` attributes before calling this method.
93
-
94
- Again, distutils is used to do the actual work.
95
- """
96
- self.check_credentials()
97
- # get distutils to do the work
98
- c = self._get_pypirc_command()
99
- c._store_pypirc(self.username, self.password)
100
-
101
- def check_credentials(self):
102
- """
103
- Check that ``username`` and ``password`` have been set, and raise an
104
- exception if not.
105
- """
106
- if self.username is None or self.password is None:
107
- raise DistlibException('username and password must be set')
108
- pm = HTTPPasswordMgr()
109
- _, netloc, _, _, _, _ = urlparse(self.url)
110
- pm.add_password(self.realm, netloc, self.username, self.password)
111
- self.password_handler = HTTPBasicAuthHandler(pm)
112
-
113
- def register(self, metadata):
114
- """
115
- Register a distribution on PyPI, using the provided metadata.
116
-
117
- :param metadata: A :class:`Metadata` instance defining at least a name
118
- and version number for the distribution to be
119
- registered.
120
- :return: The HTTP response received from PyPI upon submission of the
121
- request.
122
- """
123
- self.check_credentials()
124
- metadata.validate()
125
- d = metadata.todict()
126
- d[':action'] = 'verify'
127
- request = self.encode_request(d.items(), [])
128
- response = self.send_request(request)
129
- d[':action'] = 'submit'
130
- request = self.encode_request(d.items(), [])
131
- return self.send_request(request)
132
-
133
- def _reader(self, name, stream, outbuf):
134
- """
135
- Thread runner for reading lines of from a subprocess into a buffer.
136
-
137
- :param name: The logical name of the stream (used for logging only).
138
- :param stream: The stream to read from. This will typically a pipe
139
- connected to the output stream of a subprocess.
140
- :param outbuf: The list to append the read lines to.
141
- """
142
- while True:
143
- s = stream.readline()
144
- if not s:
145
- break
146
- s = s.decode('utf-8').rstrip()
147
- outbuf.append(s)
148
- logger.debug('%s: %s' % (name, s))
149
- stream.close()
150
-
151
- def get_sign_command(self, filename, signer, sign_password):
152
- """
153
- Return a suitable command for signing a file.
154
-
155
- :param filename: The pathname to the file to be signed.
156
- :param signer: The identifier of the signer of the file.
157
- :param sign_password: The passphrase for the signer's
158
- private key used for signing.
159
- :return: The signing command as a list suitable to be
160
- passed to :class:`subprocess.Popen`.
161
- """
162
- cmd = [self.gpg, '--status-fd', '2', '--no-tty']
163
- if self.gpg_home:
164
- cmd.extend(['--homedir', self.gpg_home])
165
- if sign_password is not None:
166
- cmd.extend(['--batch', '--passphrase-fd', '0'])
167
- td = tempfile.mkdtemp()
168
- sf = os.path.join(td, os.path.basename(filename) + '.asc')
169
- cmd.extend(['--detach-sign', '--armor', '--local-user',
170
- signer, '--output', sf, filename])
171
- logger.debug('invoking: %s', ' '.join(cmd))
172
- return cmd, sf
173
-
174
- def run_command(self, cmd, input_data=None):
175
- """
176
- Run a command in a child process , passing it any input data specified.
177
-
178
- :param cmd: The command to run.
179
- :param input_data: If specified, this must be a byte string containing
180
- data to be sent to the child process.
181
- :return: A tuple consisting of the subprocess' exit code, a list of
182
- lines read from the subprocess' ``stdout``, and a list of
183
- lines read from the subprocess' ``stderr``.
184
- """
185
- kwargs = {
186
- 'stdout': subprocess.PIPE,
187
- 'stderr': subprocess.PIPE,
188
- }
189
- if input_data is not None:
190
- kwargs['stdin'] = subprocess.PIPE
191
- stdout = []
192
- stderr = []
193
- p = subprocess.Popen(cmd, **kwargs)
194
- # We don't use communicate() here because we may need to
195
- # get clever with interacting with the command
196
- t1 = Thread(target=self._reader, args=('stdout', p.stdout, stdout))
197
- t1.start()
198
- t2 = Thread(target=self._reader, args=('stderr', p.stderr, stderr))
199
- t2.start()
200
- if input_data is not None:
201
- p.stdin.write(input_data)
202
- p.stdin.close()
203
-
204
- p.wait()
205
- t1.join()
206
- t2.join()
207
- return p.returncode, stdout, stderr
208
-
209
- def sign_file(self, filename, signer, sign_password):
210
- """
211
- Sign a file.
212
-
213
- :param filename: The pathname to the file to be signed.
214
- :param signer: The identifier of the signer of the file.
215
- :param sign_password: The passphrase for the signer's
216
- private key used for signing.
217
- :return: The absolute pathname of the file where the signature is
218
- stored.
219
- """
220
- cmd, sig_file = self.get_sign_command(filename, signer, sign_password)
221
- rc, stdout, stderr = self.run_command(cmd,
222
- sign_password.encode('utf-8'))
223
- if rc != 0:
224
- raise DistlibException('sign command failed with error '
225
- 'code %s' % rc)
226
- return sig_file
227
-
228
- def upload_file(self, metadata, filename, signer=None, sign_password=None,
229
- filetype='sdist', pyversion='source'):
230
- """
231
- Upload a release file to the index.
232
-
233
- :param metadata: A :class:`Metadata` instance defining at least a name
234
- and version number for the file to be uploaded.
235
- :param filename: The pathname of the file to be uploaded.
236
- :param signer: The identifier of the signer of the file.
237
- :param sign_password: The passphrase for the signer's
238
- private key used for signing.
239
- :param filetype: The type of the file being uploaded. This is the
240
- distutils command which produced that file, e.g.
241
- ``sdist`` or ``bdist_wheel``.
242
- :param pyversion: The version of Python which the release relates
243
- to. For code compatible with any Python, this would
244
- be ``source``, otherwise it would be e.g. ``3.2``.
245
- :return: The HTTP response received from PyPI upon submission of the
246
- request.
247
- """
248
- self.check_credentials()
249
- if not os.path.exists(filename):
250
- raise DistlibException('not found: %s' % filename)
251
- metadata.validate()
252
- d = metadata.todict()
253
- sig_file = None
254
- if signer:
255
- if not self.gpg:
256
- logger.warning('no signing program available - not signed')
257
- else:
258
- sig_file = self.sign_file(filename, signer, sign_password)
259
- with open(filename, 'rb') as f:
260
- file_data = f.read()
261
- md5_digest = hashlib.md5(file_data).hexdigest()
262
- sha256_digest = hashlib.sha256(file_data).hexdigest()
263
- d.update({
264
- ':action': 'file_upload',
265
- 'protcol_version': '1',
266
- 'filetype': filetype,
267
- 'pyversion': pyversion,
268
- 'md5_digest': md5_digest,
269
- 'sha256_digest': sha256_digest,
270
- })
271
- files = [('content', os.path.basename(filename), file_data)]
272
- if sig_file:
273
- with open(sig_file, 'rb') as f:
274
- sig_data = f.read()
275
- files.append(('gpg_signature', os.path.basename(sig_file),
276
- sig_data))
277
- shutil.rmtree(os.path.dirname(sig_file))
278
- request = self.encode_request(d.items(), files)
279
- return self.send_request(request)
280
-
281
- def upload_documentation(self, metadata, doc_dir):
282
- """
283
- Upload documentation to the index.
284
-
285
- :param metadata: A :class:`Metadata` instance defining at least a name
286
- and version number for the documentation to be
287
- uploaded.
288
- :param doc_dir: The pathname of the directory which contains the
289
- documentation. This should be the directory that
290
- contains the ``index.html`` for the documentation.
291
- :return: The HTTP response received from PyPI upon submission of the
292
- request.
293
- """
294
- self.check_credentials()
295
- if not os.path.isdir(doc_dir):
296
- raise DistlibException('not a directory: %r' % doc_dir)
297
- fn = os.path.join(doc_dir, 'index.html')
298
- if not os.path.exists(fn):
299
- raise DistlibException('not found: %r' % fn)
300
- metadata.validate()
301
- name, version = metadata.name, metadata.version
302
- zip_data = zip_dir(doc_dir).getvalue()
303
- fields = [(':action', 'doc_upload'),
304
- ('name', name), ('version', version)]
305
- files = [('content', name, zip_data)]
306
- request = self.encode_request(fields, files)
307
- return self.send_request(request)
308
-
309
- def get_verify_command(self, signature_filename, data_filename):
310
- """
311
- Return a suitable command for verifying a file.
312
-
313
- :param signature_filename: The pathname to the file containing the
314
- signature.
315
- :param data_filename: The pathname to the file containing the
316
- signed data.
317
- :return: The verifying command as a list suitable to be
318
- passed to :class:`subprocess.Popen`.
319
- """
320
- cmd = [self.gpg, '--status-fd', '2', '--no-tty']
321
- if self.gpg_home:
322
- cmd.extend(['--homedir', self.gpg_home])
323
- cmd.extend(['--verify', signature_filename, data_filename])
324
- logger.debug('invoking: %s', ' '.join(cmd))
325
- return cmd
326
-
327
- def verify_signature(self, signature_filename, data_filename):
328
- """
329
- Verify a signature for a file.
330
-
331
- :param signature_filename: The pathname to the file containing the
332
- signature.
333
- :param data_filename: The pathname to the file containing the
334
- signed data.
335
- :return: True if the signature was verified, else False.
336
- """
337
- if not self.gpg:
338
- raise DistlibException('verification unavailable because gpg '
339
- 'unavailable')
340
- cmd = self.get_verify_command(signature_filename, data_filename)
341
- rc, stdout, stderr = self.run_command(cmd)
342
- if rc not in (0, 1):
343
- raise DistlibException('verify command failed with error '
344
- 'code %s' % rc)
345
- return rc == 0
346
-
347
- def download_file(self, url, destfile, digest=None, reporthook=None):
348
- """
349
- This is a convenience method for downloading a file from an URL.
350
- Normally, this will be a file from the index, though currently
351
- no check is made for this (i.e. a file can be downloaded from
352
- anywhere).
353
-
354
- The method is just like the :func:`urlretrieve` function in the
355
- standard library, except that it allows digest computation to be
356
- done during download and checking that the downloaded data
357
- matched any expected value.
358
-
359
- :param url: The URL of the file to be downloaded (assumed to be
360
- available via an HTTP GET request).
361
- :param destfile: The pathname where the downloaded file is to be
362
- saved.
363
- :param digest: If specified, this must be a (hasher, value)
364
- tuple, where hasher is the algorithm used (e.g.
365
- ``'md5'``) and ``value`` is the expected value.
366
- :param reporthook: The same as for :func:`urlretrieve` in the
367
- standard library.
368
- """
369
- if digest is None:
370
- digester = None
371
- logger.debug('No digest specified')
372
- else:
373
- if isinstance(digest, (list, tuple)):
374
- hasher, digest = digest
375
- else:
376
- hasher = 'md5'
377
- digester = getattr(hashlib, hasher)()
378
- logger.debug('Digest specified: %s' % digest)
379
- # The following code is equivalent to urlretrieve.
380
- # We need to do it this way so that we can compute the
381
- # digest of the file as we go.
382
- with open(destfile, 'wb') as dfp:
383
- # addinfourl is not a context manager on 2.x
384
- # so we have to use try/finally
385
- sfp = self.send_request(Request(url))
386
- try:
387
- headers = sfp.info()
388
- blocksize = 8192
389
- size = -1
390
- read = 0
391
- blocknum = 0
392
- if "content-length" in headers:
393
- size = int(headers["Content-Length"])
394
- if reporthook:
395
- reporthook(blocknum, blocksize, size)
396
- while True:
397
- block = sfp.read(blocksize)
398
- if not block:
399
- break
400
- read += len(block)
401
- dfp.write(block)
402
- if digester:
403
- digester.update(block)
404
- blocknum += 1
405
- if reporthook:
406
- reporthook(blocknum, blocksize, size)
407
- finally:
408
- sfp.close()
409
-
410
- # check that we got the whole file, if we can
411
- if size >= 0 and read < size:
412
- raise DistlibException(
413
- 'retrieval incomplete: got only %d out of %d bytes'
414
- % (read, size))
415
- # if we have a digest, it must match.
416
- if digester:
417
- actual = digester.hexdigest()
418
- if digest != actual:
419
- raise DistlibException('%s digest mismatch for %s: expected '
420
- '%s, got %s' % (hasher, destfile,
421
- digest, actual))
422
- logger.debug('Digest verified: %s', digest)
423
-
424
- def send_request(self, req):
425
- """
426
- Send a standard library :class:`Request` to PyPI and return its
427
- response.
428
-
429
- :param req: The request to send.
430
- :return: The HTTP response from PyPI (a standard library HTTPResponse).
431
- """
432
- handlers = []
433
- if self.password_handler:
434
- handlers.append(self.password_handler)
435
- if self.ssl_verifier:
436
- handlers.append(self.ssl_verifier)
437
- opener = build_opener(*handlers)
438
- return opener.open(req)
439
-
440
- def encode_request(self, fields, files):
441
- """
442
- Encode fields and files for posting to an HTTP server.
443
-
444
- :param fields: The fields to send as a list of (fieldname, value)
445
- tuples.
446
- :param files: The files to send as a list of (fieldname, filename,
447
- file_bytes) tuple.
448
- """
449
- # Adapted from packaging, which in turn was adapted from
450
- # http://code.activestate.com/recipes/146306
451
-
452
- parts = []
453
- boundary = self.boundary
454
- for k, values in fields:
455
- if not isinstance(values, (list, tuple)):
456
- values = [values]
457
-
458
- for v in values:
459
- parts.extend((
460
- b'--' + boundary,
461
- ('Content-Disposition: form-data; name="%s"' %
462
- k).encode('utf-8'),
463
- b'',
464
- v.encode('utf-8')))
465
- for key, filename, value in files:
466
- parts.extend((
467
- b'--' + boundary,
468
- ('Content-Disposition: form-data; name="%s"; filename="%s"' %
469
- (key, filename)).encode('utf-8'),
470
- b'',
471
- value))
472
-
473
- parts.extend((b'--' + boundary + b'--', b''))
474
-
475
- body = b'\r\n'.join(parts)
476
- ct = b'multipart/form-data; boundary=' + boundary
477
- headers = {
478
- 'Content-type': ct,
479
- 'Content-length': str(len(body))
480
- }
481
- return Request(self.url, body, headers)
482
-
483
- def search(self, terms, operator=None):
484
- if isinstance(terms, string_types):
485
- terms = {'name': terms}
486
- if self.rpc_proxy is None:
487
- self.rpc_proxy = ServerProxy(self.url, timeout=3.0)
488
- return self.rpc_proxy.search(terms, operator or 'and')
1
+ # -*- coding: utf-8 -*-
2
+ #
3
+ # Copyright (C) 2013 Vinay Sajip.
4
+ # Licensed to the Python Software Foundation under a contributor agreement.
5
+ # See LICENSE.txt and CONTRIBUTORS.txt.
6
+ #
7
+ import hashlib
8
+ import logging
9
+ import os
10
+ import shutil
11
+ import subprocess
12
+ import tempfile
13
+ try:
14
+ from threading import Thread
15
+ except ImportError:
16
+ from dummy_threading import Thread
17
+
18
+ from . import DistlibException
19
+ from .compat import (HTTPBasicAuthHandler, Request, HTTPPasswordMgr,
20
+ urlparse, build_opener, string_types)
21
+ from .util import cached_property, zip_dir, ServerProxy
22
+
23
+ logger = logging.getLogger(__name__)
24
+
25
+ DEFAULT_INDEX = 'https://pypi.python.org/pypi'
26
+ DEFAULT_REALM = 'pypi'
27
+
28
+ class PackageIndex(object):
29
+ """
30
+ This class represents a package index compatible with PyPI, the Python
31
+ Package Index.
32
+ """
33
+
34
+ boundary = b'----------ThIs_Is_tHe_distlib_index_bouNdaRY_$'
35
+
36
+ def __init__(self, url=None):
37
+ """
38
+ Initialise an instance.
39
+
40
+ :param url: The URL of the index. If not specified, the URL for PyPI is
41
+ used.
42
+ """
43
+ self.url = url or DEFAULT_INDEX
44
+ self.read_configuration()
45
+ scheme, netloc, path, params, query, frag = urlparse(self.url)
46
+ if params or query or frag or scheme not in ('http', 'https'):
47
+ raise DistlibException('invalid repository: %s' % self.url)
48
+ self.password_handler = None
49
+ self.ssl_verifier = None
50
+ self.gpg = None
51
+ self.gpg_home = None
52
+ with open(os.devnull, 'w') as sink:
53
+ # Use gpg by default rather than gpg2, as gpg2 insists on
54
+ # prompting for passwords
55
+ for s in ('gpg', 'gpg2'):
56
+ try:
57
+ rc = subprocess.check_call([s, '--version'], stdout=sink,
58
+ stderr=sink)
59
+ if rc == 0:
60
+ self.gpg = s
61
+ break
62
+ except OSError:
63
+ pass
64
+
65
+ def _get_pypirc_command(self):
66
+ """
67
+ Get the distutils command for interacting with PyPI configurations.
68
+ :return: the command.
69
+ """
70
+ from distutils.core import Distribution
71
+ from distutils.config import PyPIRCCommand
72
+ d = Distribution()
73
+ return PyPIRCCommand(d)
74
+
75
+ def read_configuration(self):
76
+ """
77
+ Read the PyPI access configuration as supported by distutils, getting
78
+ PyPI to do the actual work. This populates ``username``, ``password``,
79
+ ``realm`` and ``url`` attributes from the configuration.
80
+ """
81
+ # get distutils to do the work
82
+ c = self._get_pypirc_command()
83
+ c.repository = self.url
84
+ cfg = c._read_pypirc()
85
+ self.username = cfg.get('username')
86
+ self.password = cfg.get('password')
87
+ self.realm = cfg.get('realm', 'pypi')
88
+ self.url = cfg.get('repository', self.url)
89
+
90
+ def save_configuration(self):
91
+ """
92
+ Save the PyPI access configuration. You must have set ``username`` and
93
+ ``password`` attributes before calling this method.
94
+
95
+ Again, distutils is used to do the actual work.
96
+ """
97
+ self.check_credentials()
98
+ # get distutils to do the work
99
+ c = self._get_pypirc_command()
100
+ c._store_pypirc(self.username, self.password)
101
+
102
+ def check_credentials(self):
103
+ """
104
+ Check that ``username`` and ``password`` have been set, and raise an
105
+ exception if not.
106
+ """
107
+ if self.username is None or self.password is None:
108
+ raise DistlibException('username and password must be set')
109
+ pm = HTTPPasswordMgr()
110
+ _, netloc, _, _, _, _ = urlparse(self.url)
111
+ pm.add_password(self.realm, netloc, self.username, self.password)
112
+ self.password_handler = HTTPBasicAuthHandler(pm)
113
+
114
+ def register(self, metadata):
115
+ """
116
+ Register a distribution on PyPI, using the provided metadata.
117
+
118
+ :param metadata: A :class:`Metadata` instance defining at least a name
119
+ and version number for the distribution to be
120
+ registered.
121
+ :return: The HTTP response received from PyPI upon submission of the
122
+ request.
123
+ """
124
+ self.check_credentials()
125
+ metadata.validate()
126
+ d = metadata.todict()
127
+ d[':action'] = 'verify'
128
+ request = self.encode_request(d.items(), [])
129
+ response = self.send_request(request)
130
+ d[':action'] = 'submit'
131
+ request = self.encode_request(d.items(), [])
132
+ return self.send_request(request)
133
+
134
+ def _reader(self, name, stream, outbuf):
135
+ """
136
+ Thread runner for reading lines of from a subprocess into a buffer.
137
+
138
+ :param name: The logical name of the stream (used for logging only).
139
+ :param stream: The stream to read from. This will typically a pipe
140
+ connected to the output stream of a subprocess.
141
+ :param outbuf: The list to append the read lines to.
142
+ """
143
+ while True:
144
+ s = stream.readline()
145
+ if not s:
146
+ break
147
+ s = s.decode('utf-8').rstrip()
148
+ outbuf.append(s)
149
+ logger.debug('%s: %s' % (name, s))
150
+ stream.close()
151
+
152
+ def get_sign_command(self, filename, signer, sign_password,
153
+ keystore=None):
154
+ """
155
+ Return a suitable command for signing a file.
156
+
157
+ :param filename: The pathname to the file to be signed.
158
+ :param signer: The identifier of the signer of the file.
159
+ :param sign_password: The passphrase for the signer's
160
+ private key used for signing.
161
+ :param keystore: The path to a directory which contains the keys
162
+ used in verification. If not specified, the
163
+ instance's ``gpg_home`` attribute is used instead.
164
+ :return: The signing command as a list suitable to be
165
+ passed to :class:`subprocess.Popen`.
166
+ """
167
+ cmd = [self.gpg, '--status-fd', '2', '--no-tty']
168
+ if keystore is None:
169
+ keystore = self.gpg_home
170
+ if keystore:
171
+ cmd.extend(['--homedir', keystore])
172
+ if sign_password is not None:
173
+ cmd.extend(['--batch', '--passphrase-fd', '0'])
174
+ td = tempfile.mkdtemp()
175
+ sf = os.path.join(td, os.path.basename(filename) + '.asc')
176
+ cmd.extend(['--detach-sign', '--armor', '--local-user',
177
+ signer, '--output', sf, filename])
178
+ logger.debug('invoking: %s', ' '.join(cmd))
179
+ return cmd, sf
180
+
181
+ def run_command(self, cmd, input_data=None):
182
+ """
183
+ Run a command in a child process , passing it any input data specified.
184
+
185
+ :param cmd: The command to run.
186
+ :param input_data: If specified, this must be a byte string containing
187
+ data to be sent to the child process.
188
+ :return: A tuple consisting of the subprocess' exit code, a list of
189
+ lines read from the subprocess' ``stdout``, and a list of
190
+ lines read from the subprocess' ``stderr``.
191
+ """
192
+ kwargs = {
193
+ 'stdout': subprocess.PIPE,
194
+ 'stderr': subprocess.PIPE,
195
+ }
196
+ if input_data is not None:
197
+ kwargs['stdin'] = subprocess.PIPE
198
+ stdout = []
199
+ stderr = []
200
+ p = subprocess.Popen(cmd, **kwargs)
201
+ # We don't use communicate() here because we may need to
202
+ # get clever with interacting with the command
203
+ t1 = Thread(target=self._reader, args=('stdout', p.stdout, stdout))
204
+ t1.start()
205
+ t2 = Thread(target=self._reader, args=('stderr', p.stderr, stderr))
206
+ t2.start()
207
+ if input_data is not None:
208
+ p.stdin.write(input_data)
209
+ p.stdin.close()
210
+
211
+ p.wait()
212
+ t1.join()
213
+ t2.join()
214
+ return p.returncode, stdout, stderr
215
+
216
+ def sign_file(self, filename, signer, sign_password, keystore=None):
217
+ """
218
+ Sign a file.
219
+
220
+ :param filename: The pathname to the file to be signed.
221
+ :param signer: The identifier of the signer of the file.
222
+ :param sign_password: The passphrase for the signer's
223
+ private key used for signing.
224
+ :param keystore: The path to a directory which contains the keys
225
+ used in signing. If not specified, the instance's
226
+ ``gpg_home`` attribute is used instead.
227
+ :return: The absolute pathname of the file where the signature is
228
+ stored.
229
+ """
230
+ cmd, sig_file = self.get_sign_command(filename, signer, sign_password,
231
+ keystore)
232
+ rc, stdout, stderr = self.run_command(cmd,
233
+ sign_password.encode('utf-8'))
234
+ if rc != 0:
235
+ raise DistlibException('sign command failed with error '
236
+ 'code %s' % rc)
237
+ return sig_file
238
+
239
+ def upload_file(self, metadata, filename, signer=None, sign_password=None,
240
+ filetype='sdist', pyversion='source', keystore=None):
241
+ """
242
+ Upload a release file to the index.
243
+
244
+ :param metadata: A :class:`Metadata` instance defining at least a name
245
+ and version number for the file to be uploaded.
246
+ :param filename: The pathname of the file to be uploaded.
247
+ :param signer: The identifier of the signer of the file.
248
+ :param sign_password: The passphrase for the signer's
249
+ private key used for signing.
250
+ :param filetype: The type of the file being uploaded. This is the
251
+ distutils command which produced that file, e.g.
252
+ ``sdist`` or ``bdist_wheel``.
253
+ :param pyversion: The version of Python which the release relates
254
+ to. For code compatible with any Python, this would
255
+ be ``source``, otherwise it would be e.g. ``3.2``.
256
+ :param keystore: The path to a directory which contains the keys
257
+ used in signing. If not specified, the instance's
258
+ ``gpg_home`` attribute is used instead.
259
+ :return: The HTTP response received from PyPI upon submission of the
260
+ request.
261
+ """
262
+ self.check_credentials()
263
+ if not os.path.exists(filename):
264
+ raise DistlibException('not found: %s' % filename)
265
+ metadata.validate()
266
+ d = metadata.todict()
267
+ sig_file = None
268
+ if signer:
269
+ if not self.gpg:
270
+ logger.warning('no signing program available - not signed')
271
+ else:
272
+ sig_file = self.sign_file(filename, signer, sign_password,
273
+ keystore)
274
+ with open(filename, 'rb') as f:
275
+ file_data = f.read()
276
+ md5_digest = hashlib.md5(file_data).hexdigest()
277
+ sha256_digest = hashlib.sha256(file_data).hexdigest()
278
+ d.update({
279
+ ':action': 'file_upload',
280
+ 'protocol_version': '1',
281
+ 'filetype': filetype,
282
+ 'pyversion': pyversion,
283
+ 'md5_digest': md5_digest,
284
+ 'sha256_digest': sha256_digest,
285
+ })
286
+ files = [('content', os.path.basename(filename), file_data)]
287
+ if sig_file:
288
+ with open(sig_file, 'rb') as f:
289
+ sig_data = f.read()
290
+ files.append(('gpg_signature', os.path.basename(sig_file),
291
+ sig_data))
292
+ shutil.rmtree(os.path.dirname(sig_file))
293
+ request = self.encode_request(d.items(), files)
294
+ return self.send_request(request)
295
+
296
+ def upload_documentation(self, metadata, doc_dir):
297
+ """
298
+ Upload documentation to the index.
299
+
300
+ :param metadata: A :class:`Metadata` instance defining at least a name
301
+ and version number for the documentation to be
302
+ uploaded.
303
+ :param doc_dir: The pathname of the directory which contains the
304
+ documentation. This should be the directory that
305
+ contains the ``index.html`` for the documentation.
306
+ :return: The HTTP response received from PyPI upon submission of the
307
+ request.
308
+ """
309
+ self.check_credentials()
310
+ if not os.path.isdir(doc_dir):
311
+ raise DistlibException('not a directory: %r' % doc_dir)
312
+ fn = os.path.join(doc_dir, 'index.html')
313
+ if not os.path.exists(fn):
314
+ raise DistlibException('not found: %r' % fn)
315
+ metadata.validate()
316
+ name, version = metadata.name, metadata.version
317
+ zip_data = zip_dir(doc_dir).getvalue()
318
+ fields = [(':action', 'doc_upload'),
319
+ ('name', name), ('version', version)]
320
+ files = [('content', name, zip_data)]
321
+ request = self.encode_request(fields, files)
322
+ return self.send_request(request)
323
+
324
+ def get_verify_command(self, signature_filename, data_filename,
325
+ keystore=None):
326
+ """
327
+ Return a suitable command for verifying a file.
328
+
329
+ :param signature_filename: The pathname to the file containing the
330
+ signature.
331
+ :param data_filename: The pathname to the file containing the
332
+ signed data.
333
+ :param keystore: The path to a directory which contains the keys
334
+ used in verification. If not specified, the
335
+ instance's ``gpg_home`` attribute is used instead.
336
+ :return: The verifying command as a list suitable to be
337
+ passed to :class:`subprocess.Popen`.
338
+ """
339
+ cmd = [self.gpg, '--status-fd', '2', '--no-tty']
340
+ if keystore is None:
341
+ keystore = self.gpg_home
342
+ if keystore:
343
+ cmd.extend(['--homedir', keystore])
344
+ cmd.extend(['--verify', signature_filename, data_filename])
345
+ logger.debug('invoking: %s', ' '.join(cmd))
346
+ return cmd
347
+
348
+ def verify_signature(self, signature_filename, data_filename,
349
+ keystore=None):
350
+ """
351
+ Verify a signature for a file.
352
+
353
+ :param signature_filename: The pathname to the file containing the
354
+ signature.
355
+ :param data_filename: The pathname to the file containing the
356
+ signed data.
357
+ :param keystore: The path to a directory which contains the keys
358
+ used in verification. If not specified, the
359
+ instance's ``gpg_home`` attribute is used instead.
360
+ :return: True if the signature was verified, else False.
361
+ """
362
+ if not self.gpg:
363
+ raise DistlibException('verification unavailable because gpg '
364
+ 'unavailable')
365
+ cmd = self.get_verify_command(signature_filename, data_filename,
366
+ keystore)
367
+ rc, stdout, stderr = self.run_command(cmd)
368
+ if rc not in (0, 1):
369
+ raise DistlibException('verify command failed with error '
370
+ 'code %s' % rc)
371
+ return rc == 0
372
+
373
+ def download_file(self, url, destfile, digest=None, reporthook=None):
374
+ """
375
+ This is a convenience method for downloading a file from an URL.
376
+ Normally, this will be a file from the index, though currently
377
+ no check is made for this (i.e. a file can be downloaded from
378
+ anywhere).
379
+
380
+ The method is just like the :func:`urlretrieve` function in the
381
+ standard library, except that it allows digest computation to be
382
+ done during download and checking that the downloaded data
383
+ matched any expected value.
384
+
385
+ :param url: The URL of the file to be downloaded (assumed to be
386
+ available via an HTTP GET request).
387
+ :param destfile: The pathname where the downloaded file is to be
388
+ saved.
389
+ :param digest: If specified, this must be a (hasher, value)
390
+ tuple, where hasher is the algorithm used (e.g.
391
+ ``'md5'``) and ``value`` is the expected value.
392
+ :param reporthook: The same as for :func:`urlretrieve` in the
393
+ standard library.
394
+ """
395
+ if digest is None:
396
+ digester = None
397
+ logger.debug('No digest specified')
398
+ else:
399
+ if isinstance(digest, (list, tuple)):
400
+ hasher, digest = digest
401
+ else:
402
+ hasher = 'md5'
403
+ digester = getattr(hashlib, hasher)()
404
+ logger.debug('Digest specified: %s' % digest)
405
+ # The following code is equivalent to urlretrieve.
406
+ # We need to do it this way so that we can compute the
407
+ # digest of the file as we go.
408
+ with open(destfile, 'wb') as dfp:
409
+ # addinfourl is not a context manager on 2.x
410
+ # so we have to use try/finally
411
+ sfp = self.send_request(Request(url))
412
+ try:
413
+ headers = sfp.info()
414
+ blocksize = 8192
415
+ size = -1
416
+ read = 0
417
+ blocknum = 0
418
+ if "content-length" in headers:
419
+ size = int(headers["Content-Length"])
420
+ if reporthook:
421
+ reporthook(blocknum, blocksize, size)
422
+ while True:
423
+ block = sfp.read(blocksize)
424
+ if not block:
425
+ break
426
+ read += len(block)
427
+ dfp.write(block)
428
+ if digester:
429
+ digester.update(block)
430
+ blocknum += 1
431
+ if reporthook:
432
+ reporthook(blocknum, blocksize, size)
433
+ finally:
434
+ sfp.close()
435
+
436
+ # check that we got the whole file, if we can
437
+ if size >= 0 and read < size:
438
+ raise DistlibException(
439
+ 'retrieval incomplete: got only %d out of %d bytes'
440
+ % (read, size))
441
+ # if we have a digest, it must match.
442
+ if digester:
443
+ actual = digester.hexdigest()
444
+ if digest != actual:
445
+ raise DistlibException('%s digest mismatch for %s: expected '
446
+ '%s, got %s' % (hasher, destfile,
447
+ digest, actual))
448
+ logger.debug('Digest verified: %s', digest)
449
+
450
+ def send_request(self, req):
451
+ """
452
+ Send a standard library :class:`Request` to PyPI and return its
453
+ response.
454
+
455
+ :param req: The request to send.
456
+ :return: The HTTP response from PyPI (a standard library HTTPResponse).
457
+ """
458
+ handlers = []
459
+ if self.password_handler:
460
+ handlers.append(self.password_handler)
461
+ if self.ssl_verifier:
462
+ handlers.append(self.ssl_verifier)
463
+ opener = build_opener(*handlers)
464
+ return opener.open(req)
465
+
466
+ def encode_request(self, fields, files):
467
+ """
468
+ Encode fields and files for posting to an HTTP server.
469
+
470
+ :param fields: The fields to send as a list of (fieldname, value)
471
+ tuples.
472
+ :param files: The files to send as a list of (fieldname, filename,
473
+ file_bytes) tuple.
474
+ """
475
+ # Adapted from packaging, which in turn was adapted from
476
+ # http://code.activestate.com/recipes/146306
477
+
478
+ parts = []
479
+ boundary = self.boundary
480
+ for k, values in fields:
481
+ if not isinstance(values, (list, tuple)):
482
+ values = [values]
483
+
484
+ for v in values:
485
+ parts.extend((
486
+ b'--' + boundary,
487
+ ('Content-Disposition: form-data; name="%s"' %
488
+ k).encode('utf-8'),
489
+ b'',
490
+ v.encode('utf-8')))
491
+ for key, filename, value in files:
492
+ parts.extend((
493
+ b'--' + boundary,
494
+ ('Content-Disposition: form-data; name="%s"; filename="%s"' %
495
+ (key, filename)).encode('utf-8'),
496
+ b'',
497
+ value))
498
+
499
+ parts.extend((b'--' + boundary + b'--', b''))
500
+
501
+ body = b'\r\n'.join(parts)
502
+ ct = b'multipart/form-data; boundary=' + boundary
503
+ headers = {
504
+ 'Content-type': ct,
505
+ 'Content-length': str(len(body))
506
+ }
507
+ return Request(self.url, body, headers)
508
+
509
+ def search(self, terms, operator=None):
510
+ if isinstance(terms, string_types):
511
+ terms = {'name': terms}
512
+ rpc_proxy = ServerProxy(self.url, timeout=3.0)
513
+ try:
514
+ return rpc_proxy.search(terms, operator or 'and')
515
+ finally:
516
+ rpc_proxy('close')()