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,958 +1,984 @@
1
- # -*- coding: utf-8 -*-
2
- #
3
- # Copyright (C) 2013-2014 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 unicode_literals
8
-
9
- import base64
10
- import codecs
11
- import datetime
12
- import distutils.util
13
- from email import message_from_file
14
- import hashlib
15
- import imp
16
- import json
17
- import logging
18
- import os
19
- import posixpath
20
- import re
21
- import shutil
22
- import sys
23
- import tempfile
24
- import zipfile
25
-
26
- from . import __version__, DistlibException
27
- from .compat import sysconfig, ZipFile, fsdecode, text_type, filter
28
- from .database import InstalledDistribution
29
- from .metadata import Metadata, METADATA_FILENAME
30
- from .util import (FileOperator, convert_path, CSVReader, CSVWriter, Cache,
31
- cached_property, get_cache_base, read_exports, tempdir)
32
- from .version import NormalizedVersion, UnsupportedVersionError
33
-
34
- logger = logging.getLogger(__name__)
35
-
36
- cache = None # created when needed
37
-
38
- if hasattr(sys, 'pypy_version_info'):
39
- IMP_PREFIX = 'pp'
40
- elif sys.platform.startswith('java'):
41
- IMP_PREFIX = 'jy'
42
- elif sys.platform == 'cli':
43
- IMP_PREFIX = 'ip'
44
- else:
45
- IMP_PREFIX = 'cp'
46
-
47
- VER_SUFFIX = sysconfig.get_config_var('py_version_nodot')
48
- if not VER_SUFFIX: # pragma: no cover
49
- VER_SUFFIX = '%s%s' % sys.version_info[:2]
50
- PYVER = 'py' + VER_SUFFIX
51
- IMPVER = IMP_PREFIX + VER_SUFFIX
52
-
53
- ARCH = distutils.util.get_platform().replace('-', '_').replace('.', '_')
54
-
55
- ABI = sysconfig.get_config_var('SOABI')
56
- if ABI and ABI.startswith('cpython-'):
57
- ABI = ABI.replace('cpython-', 'cp')
58
- else:
59
- def _derive_abi():
60
- parts = ['cp', VER_SUFFIX]
61
- if sysconfig.get_config_var('Py_DEBUG'):
62
- parts.append('d')
63
- if sysconfig.get_config_var('WITH_PYMALLOC'):
64
- parts.append('m')
65
- if sysconfig.get_config_var('Py_UNICODE_SIZE') == 4:
66
- parts.append('u')
67
- return ''.join(parts)
68
- ABI = _derive_abi()
69
- del _derive_abi
70
-
71
- FILENAME_RE = re.compile(r'''
72
- (?P<nm>[^-]+)
73
- -(?P<vn>\d+[^-]*)
74
- (-(?P<bn>\d+[^-]*))?
75
- -(?P<py>\w+\d+(\.\w+\d+)*)
76
- -(?P<bi>\w+)
77
- -(?P<ar>\w+)
78
- \.whl$
79
- ''', re.IGNORECASE | re.VERBOSE)
80
-
81
- NAME_VERSION_RE = re.compile(r'''
82
- (?P<nm>[^-]+)
83
- -(?P<vn>\d+[^-]*)
84
- (-(?P<bn>\d+[^-]*))?$
85
- ''', re.IGNORECASE | re.VERBOSE)
86
-
87
- SHEBANG_RE = re.compile(br'\s*#![^\r\n]*')
88
-
89
- if os.sep == '/':
90
- to_posix = lambda o: o
91
- else:
92
- to_posix = lambda o: o.replace(os.sep, '/')
93
-
94
-
95
- class Mounter(object):
96
- def __init__(self):
97
- self.impure_wheels = {}
98
- self.libs = {}
99
-
100
- def add(self, pathname, extensions):
101
- self.impure_wheels[pathname] = extensions
102
- self.libs.update(extensions)
103
-
104
- def remove(self, pathname):
105
- extensions = self.impure_wheels.pop(pathname)
106
- for k, v in extensions:
107
- if k in self.libs:
108
- del self.libs[k]
109
-
110
- def find_module(self, fullname, path=None):
111
- if fullname in self.libs:
112
- result = self
113
- else:
114
- result = None
115
- return result
116
-
117
- def load_module(self, fullname):
118
- if fullname in sys.modules:
119
- result = sys.modules[fullname]
120
- else:
121
- if fullname not in self.libs:
122
- raise ImportError('unable to find extension for %s' % fullname)
123
- result = imp.load_dynamic(fullname, self.libs[fullname])
124
- result.__loader__ = self
125
- parts = fullname.rsplit('.', 1)
126
- if len(parts) > 1:
127
- result.__package__ = parts[0]
128
- return result
129
-
130
- _hook = Mounter()
131
-
132
-
133
- class Wheel(object):
134
- """
135
- Class to build and install from Wheel files (PEP 427).
136
- """
137
-
138
- wheel_version = (1, 1)
139
- hash_kind = 'sha256'
140
-
141
- def __init__(self, filename=None, sign=False, verify=False):
142
- """
143
- Initialise an instance using a (valid) filename.
144
- """
145
- self.sign = sign
146
- self.should_verify = verify
147
- self.buildver = ''
148
- self.pyver = [PYVER]
149
- self.abi = ['none']
150
- self.arch = ['any']
151
- self.dirname = os.getcwd()
152
- if filename is None:
153
- self.name = 'dummy'
154
- self.version = '0.1'
155
- self._filename = self.filename
156
- else:
157
- m = NAME_VERSION_RE.match(filename)
158
- if m:
159
- info = m.groupdict('')
160
- self.name = info['nm']
161
- # Reinstate the local version separator
162
- self.version = info['vn'].replace('_', '-')
163
- self.buildver = info['bn']
164
- self._filename = self.filename
165
- else:
166
- dirname, filename = os.path.split(filename)
167
- m = FILENAME_RE.match(filename)
168
- if not m:
169
- raise DistlibException('Invalid name or '
170
- 'filename: %r' % filename)
171
- if dirname:
172
- self.dirname = os.path.abspath(dirname)
173
- self._filename = filename
174
- info = m.groupdict('')
175
- self.name = info['nm']
176
- self.version = info['vn']
177
- self.buildver = info['bn']
178
- self.pyver = info['py'].split('.')
179
- self.abi = info['bi'].split('.')
180
- self.arch = info['ar'].split('.')
181
-
182
- @property
183
- def filename(self):
184
- """
185
- Build and return a filename from the various components.
186
- """
187
- if self.buildver:
188
- buildver = '-' + self.buildver
189
- else:
190
- buildver = ''
191
- pyver = '.'.join(self.pyver)
192
- abi = '.'.join(self.abi)
193
- arch = '.'.join(self.arch)
194
- # replace - with _ as a local version separator
195
- version = self.version.replace('-', '_')
196
- return '%s-%s%s-%s-%s-%s.whl' % (self.name, version, buildver,
197
- pyver, abi, arch)
198
-
199
- @property
200
- def exists(self):
201
- path = os.path.join(self.dirname, self.filename)
202
- return os.path.isfile(path)
203
-
204
- @property
205
- def tags(self):
206
- for pyver in self.pyver:
207
- for abi in self.abi:
208
- for arch in self.arch:
209
- yield pyver, abi, arch
210
-
211
- @cached_property
212
- def metadata(self):
213
- pathname = os.path.join(self.dirname, self.filename)
214
- name_ver = '%s-%s' % (self.name, self.version)
215
- info_dir = '%s.dist-info' % name_ver
216
- wrapper = codecs.getreader('utf-8')
217
- with ZipFile(pathname, 'r') as zf:
218
- wheel_metadata = self.get_wheel_metadata(zf)
219
- wv = wheel_metadata['Wheel-Version'].split('.', 1)
220
- file_version = tuple([int(i) for i in wv])
221
- if file_version < (1, 1):
222
- fn = 'METADATA'
223
- else:
224
- fn = METADATA_FILENAME
225
- try:
226
- metadata_filename = posixpath.join(info_dir, fn)
227
- with zf.open(metadata_filename) as bf:
228
- wf = wrapper(bf)
229
- result = Metadata(fileobj=wf)
230
- except KeyError:
231
- raise ValueError('Invalid wheel, because %s is '
232
- 'missing' % fn)
233
- return result
234
-
235
- def get_wheel_metadata(self, zf):
236
- name_ver = '%s-%s' % (self.name, self.version)
237
- info_dir = '%s.dist-info' % name_ver
238
- metadata_filename = posixpath.join(info_dir, 'WHEEL')
239
- with zf.open(metadata_filename) as bf:
240
- wf = codecs.getreader('utf-8')(bf)
241
- message = message_from_file(wf)
242
- return dict(message)
243
-
244
- @cached_property
245
- def info(self):
246
- pathname = os.path.join(self.dirname, self.filename)
247
- with ZipFile(pathname, 'r') as zf:
248
- result = self.get_wheel_metadata(zf)
249
- return result
250
-
251
- def process_shebang(self, data):
252
- m = SHEBANG_RE.match(data)
253
- if m:
254
- data = b'#!python' + data[m.end():]
255
- else:
256
- cr = data.find(b'\r')
257
- lf = data.find(b'\n')
258
- if cr < 0 or cr > lf:
259
- term = b'\n'
260
- else:
261
- if data[cr:cr + 2] == b'\r\n':
262
- term = b'\r\n'
263
- else:
264
- term = b'\r'
265
- data = b'#!python' + term + data
266
- return data
267
-
268
- def get_hash(self, data, hash_kind=None):
269
- if hash_kind is None:
270
- hash_kind = self.hash_kind
271
- try:
272
- hasher = getattr(hashlib, hash_kind)
273
- except AttributeError:
274
- raise DistlibException('Unsupported hash algorithm: %r' % hash_kind)
275
- result = hasher(data).digest()
276
- result = base64.urlsafe_b64encode(result).rstrip(b'=').decode('ascii')
277
- return hash_kind, result
278
-
279
- def write_record(self, records, record_path, base):
280
- with CSVWriter(record_path) as writer:
281
- for row in records:
282
- writer.writerow(row)
283
- p = to_posix(os.path.relpath(record_path, base))
284
- writer.writerow((p, '', ''))
285
-
286
- def write_records(self, info, libdir, archive_paths):
287
- records = []
288
- distinfo, info_dir = info
289
- hasher = getattr(hashlib, self.hash_kind)
290
- for ap, p in archive_paths:
291
- with open(p, 'rb') as f:
292
- data = f.read()
293
- digest = '%s=%s' % self.get_hash(data)
294
- size = os.path.getsize(p)
295
- records.append((ap, digest, size))
296
-
297
- p = os.path.join(distinfo, 'RECORD')
298
- self.write_record(records, p, libdir)
299
- ap = to_posix(os.path.join(info_dir, 'RECORD'))
300
- archive_paths.append((ap, p))
301
-
302
- def build_zip(self, pathname, archive_paths):
303
- with ZipFile(pathname, 'w', zipfile.ZIP_DEFLATED) as zf:
304
- for ap, p in archive_paths:
305
- logger.debug('Wrote %s to %s in wheel', p, ap)
306
- zf.write(p, ap)
307
-
308
- def build(self, paths, tags=None, wheel_version=None):
309
- """
310
- Build a wheel from files in specified paths, and use any specified tags
311
- when determining the name of the wheel.
312
- """
313
- if tags is None:
314
- tags = {}
315
-
316
- libkey = list(filter(lambda o: o in paths, ('purelib', 'platlib')))[0]
317
- if libkey == 'platlib':
318
- is_pure = 'false'
319
- default_pyver = [IMPVER]
320
- default_abi = [ABI]
321
- default_arch = [ARCH]
322
- else:
323
- is_pure = 'true'
324
- default_pyver = [PYVER]
325
- default_abi = ['none']
326
- default_arch = ['any']
327
-
328
- self.pyver = tags.get('pyver', default_pyver)
329
- self.abi = tags.get('abi', default_abi)
330
- self.arch = tags.get('arch', default_arch)
331
-
332
- libdir = paths[libkey]
333
-
334
- name_ver = '%s-%s' % (self.name, self.version)
335
- data_dir = '%s.data' % name_ver
336
- info_dir = '%s.dist-info' % name_ver
337
-
338
- archive_paths = []
339
-
340
- # First, stuff which is not in site-packages
341
- for key in ('data', 'headers', 'scripts'):
342
- if key not in paths:
343
- continue
344
- path = paths[key]
345
- if os.path.isdir(path):
346
- for root, dirs, files in os.walk(path):
347
- for fn in files:
348
- p = fsdecode(os.path.join(root, fn))
349
- rp = os.path.relpath(p, path)
350
- ap = to_posix(os.path.join(data_dir, key, rp))
351
- archive_paths.append((ap, p))
352
- if key == 'scripts' and not p.endswith('.exe'):
353
- with open(p, 'rb') as f:
354
- data = f.read()
355
- data = self.process_shebang(data)
356
- with open(p, 'wb') as f:
357
- f.write(data)
358
-
359
- # Now, stuff which is in site-packages, other than the
360
- # distinfo stuff.
361
- path = libdir
362
- distinfo = None
363
- for root, dirs, files in os.walk(path):
364
- if root == path:
365
- # At the top level only, save distinfo for later
366
- # and skip it for now
367
- for i, dn in enumerate(dirs):
368
- dn = fsdecode(dn)
369
- if dn.endswith('.dist-info'):
370
- distinfo = os.path.join(root, dn)
371
- del dirs[i]
372
- break
373
- assert distinfo, '.dist-info directory expected, not found'
374
-
375
- for fn in files:
376
- # comment out next suite to leave .pyc files in
377
- if fsdecode(fn).endswith(('.pyc', '.pyo')):
378
- continue
379
- p = os.path.join(root, fn)
380
- rp = to_posix(os.path.relpath(p, path))
381
- archive_paths.append((rp, p))
382
-
383
- # Now distinfo. Assumed to be flat, i.e. os.listdir is enough.
384
- files = os.listdir(distinfo)
385
- for fn in files:
386
- if fn not in ('RECORD', 'INSTALLER', 'SHARED'):
387
- p = fsdecode(os.path.join(distinfo, fn))
388
- ap = to_posix(os.path.join(info_dir, fn))
389
- archive_paths.append((ap, p))
390
-
391
- wheel_metadata = [
392
- 'Wheel-Version: %d.%d' % (wheel_version or self.wheel_version),
393
- 'Generator: distlib %s' % __version__,
394
- 'Root-Is-Purelib: %s' % is_pure,
395
- ]
396
- for pyver, abi, arch in self.tags:
397
- wheel_metadata.append('Tag: %s-%s-%s' % (pyver, abi, arch))
398
- p = os.path.join(distinfo, 'WHEEL')
399
- with open(p, 'w') as f:
400
- f.write('\n'.join(wheel_metadata))
401
- ap = to_posix(os.path.join(info_dir, 'WHEEL'))
402
- archive_paths.append((ap, p))
403
-
404
- # Now, at last, RECORD.
405
- # Paths in here are archive paths - nothing else makes sense.
406
- self.write_records((distinfo, info_dir), libdir, archive_paths)
407
- # Now, ready to build the zip file
408
- pathname = os.path.join(self.dirname, self.filename)
409
- self.build_zip(pathname, archive_paths)
410
- return pathname
411
-
412
- def install(self, paths, maker, **kwargs):
413
- """
414
- Install a wheel to the specified paths. If kwarg ``warner`` is
415
- specified, it should be a callable, which will be called with two
416
- tuples indicating the wheel version of this software and the wheel
417
- version in the file, if there is a discrepancy in the versions.
418
- This can be used to issue any warnings to raise any exceptions.
419
- If kwarg ``lib_only`` is True, only the purelib/platlib files are
420
- installed, and the headers, scripts, data and dist-info metadata are
421
- not written.
422
-
423
- The return value is a :class:`InstalledDistribution` instance unless
424
- ``options.lib_only`` is True, in which case the return value is ``None``.
425
- """
426
-
427
- dry_run = maker.dry_run
428
- warner = kwargs.get('warner')
429
- lib_only = kwargs.get('lib_only', False)
430
-
431
- pathname = os.path.join(self.dirname, self.filename)
432
- name_ver = '%s-%s' % (self.name, self.version)
433
- data_dir = '%s.data' % name_ver
434
- info_dir = '%s.dist-info' % name_ver
435
-
436
- metadata_name = posixpath.join(info_dir, METADATA_FILENAME)
437
- wheel_metadata_name = posixpath.join(info_dir, 'WHEEL')
438
- record_name = posixpath.join(info_dir, 'RECORD')
439
-
440
- wrapper = codecs.getreader('utf-8')
441
-
442
- with ZipFile(pathname, 'r') as zf:
443
- with zf.open(wheel_metadata_name) as bwf:
444
- wf = wrapper(bwf)
445
- message = message_from_file(wf)
446
- wv = message['Wheel-Version'].split('.', 1)
447
- file_version = tuple([int(i) for i in wv])
448
- if (file_version != self.wheel_version) and warner:
449
- warner(self.wheel_version, file_version)
450
-
451
- if message['Root-Is-Purelib'] == 'true':
452
- libdir = paths['purelib']
453
- else:
454
- libdir = paths['platlib']
455
-
456
- records = {}
457
- with zf.open(record_name) as bf:
458
- with CSVReader(stream=bf) as reader:
459
- for row in reader:
460
- p = row[0]
461
- records[p] = row
462
-
463
- data_pfx = posixpath.join(data_dir, '')
464
- info_pfx = posixpath.join(info_dir, '')
465
- script_pfx = posixpath.join(data_dir, 'scripts', '')
466
-
467
- # make a new instance rather than a copy of maker's,
468
- # as we mutate it
469
- fileop = FileOperator(dry_run=dry_run)
470
- fileop.record = True # so we can rollback if needed
471
-
472
- bc = not sys.dont_write_bytecode # Double negatives. Lovely!
473
-
474
- outfiles = [] # for RECORD writing
475
-
476
- # for script copying/shebang processing
477
- workdir = tempfile.mkdtemp()
478
- # set target dir later
479
- # we default add_launchers to False, as the
480
- # Python Launcher should be used instead
481
- maker.source_dir = workdir
482
- maker.target_dir = None
483
- try:
484
- for zinfo in zf.infolist():
485
- arcname = zinfo.filename
486
- if isinstance(arcname, text_type):
487
- u_arcname = arcname
488
- else:
489
- u_arcname = arcname.decode('utf-8')
490
- # The signature file won't be in RECORD,
491
- # and we don't currently don't do anything with it
492
- if u_arcname.endswith('/RECORD.jws'):
493
- continue
494
- row = records[u_arcname]
495
- if row[2] and str(zinfo.file_size) != row[2]:
496
- raise DistlibException('size mismatch for '
497
- '%s' % u_arcname)
498
- if row[1]:
499
- kind, value = row[1].split('=', 1)
500
- with zf.open(arcname) as bf:
501
- data = bf.read()
502
- _, digest = self.get_hash(data, kind)
503
- if digest != value:
504
- raise DistlibException('digest mismatch for '
505
- '%s' % arcname)
506
-
507
- if lib_only and u_arcname.startswith((info_pfx, data_pfx)):
508
- logger.debug('lib_only: skipping %s', u_arcname)
509
- continue
510
- is_script = (u_arcname.startswith(script_pfx)
511
- and not u_arcname.endswith('.exe'))
512
-
513
- if u_arcname.startswith(data_pfx):
514
- _, where, rp = u_arcname.split('/', 2)
515
- outfile = os.path.join(paths[where], convert_path(rp))
516
- else:
517
- # meant for site-packages.
518
- if u_arcname in (wheel_metadata_name, record_name):
519
- continue
520
- outfile = os.path.join(libdir, convert_path(u_arcname))
521
- if not is_script:
522
- with zf.open(arcname) as bf:
523
- fileop.copy_stream(bf, outfile)
524
- outfiles.append(outfile)
525
- # Double check the digest of the written file
526
- if not dry_run and row[1]:
527
- with open(outfile, 'rb') as bf:
528
- data = bf.read()
529
- _, newdigest = self.get_hash(data, kind)
530
- if newdigest != digest:
531
- raise DistlibException('digest mismatch '
532
- 'on write for '
533
- '%s' % outfile)
534
- if bc and outfile.endswith('.py'):
535
- try:
536
- pyc = fileop.byte_compile(outfile)
537
- outfiles.append(pyc)
538
- except Exception:
539
- # Don't give up if byte-compilation fails,
540
- # but log it and perhaps warn the user
541
- logger.warning('Byte-compilation failed',
542
- exc_info=True)
543
- else:
544
- fn = os.path.basename(convert_path(arcname))
545
- workname = os.path.join(workdir, fn)
546
- with zf.open(arcname) as bf:
547
- fileop.copy_stream(bf, workname)
548
-
549
- dn, fn = os.path.split(outfile)
550
- maker.target_dir = dn
551
- filenames = maker.make(fn)
552
- fileop.set_executable_mode(filenames)
553
- outfiles.extend(filenames)
554
-
555
- if lib_only:
556
- logger.debug('lib_only: returning None')
557
- dist = None
558
- else:
559
- # Generate scripts
560
-
561
- # Try to get pydist.json so we can see if there are
562
- # any commands to generate. If this fails (e.g. because
563
- # of a legacy wheel), log a warning but don't give up.
564
- commands = None
565
- file_version = self.info['Wheel-Version']
566
- if file_version == '1.0':
567
- # Use legacy info
568
- ep = posixpath.join(info_dir, 'entry_points.txt')
569
- try:
570
- with zf.open(ep) as bwf:
571
- epdata = read_exports(bwf)
572
- commands = {}
573
- for key in ('console', 'gui'):
574
- k = '%s_scripts' % key
575
- if k in epdata:
576
- commands['wrap_%s' % key] = d = {}
577
- for v in epdata[k].values():
578
- s = '%s:%s' % (v.prefix, v.suffix)
579
- if v.flags:
580
- s += ' %s' % v.flags
581
- d[v.name] = s
582
- except Exception:
583
- logger.warning('Unable to read legacy script '
584
- 'metadata, so cannot generate '
585
- 'scripts')
586
- else:
587
- try:
588
- with zf.open(metadata_name) as bwf:
589
- wf = wrapper(bwf)
590
- commands = json.load(wf).get('commands')
591
- except Exception:
592
- logger.warning('Unable to read JSON metadata, so '
593
- 'cannot generate scripts')
594
- if commands:
595
- console_scripts = commands.get('wrap_console', {})
596
- gui_scripts = commands.get('wrap_gui', {})
597
- if console_scripts or gui_scripts:
598
- script_dir = paths.get('scripts', '')
599
- if not os.path.isdir(script_dir):
600
- raise ValueError('Valid script path not '
601
- 'specified')
602
- maker.target_dir = script_dir
603
- for k, v in console_scripts.items():
604
- script = '%s = %s' % (k, v)
605
- filenames = maker.make(script)
606
- fileop.set_executable_mode(filenames)
607
-
608
- if gui_scripts:
609
- options = {'gui': True }
610
- for k, v in gui_scripts.items():
611
- script = '%s = %s' % (k, v)
612
- filenames = maker.make(script, options)
613
- fileop.set_executable_mode(filenames)
614
-
615
- p = os.path.join(libdir, info_dir)
616
- dist = InstalledDistribution(p)
617
-
618
- # Write SHARED
619
- paths = dict(paths) # don't change passed in dict
620
- del paths['purelib']
621
- del paths['platlib']
622
- paths['lib'] = libdir
623
- p = dist.write_shared_locations(paths, dry_run)
624
- if p:
625
- outfiles.append(p)
626
-
627
- # Write RECORD
628
- dist.write_installed_files(outfiles, paths['prefix'],
629
- dry_run)
630
- return dist
631
- except Exception: # pragma: no cover
632
- logger.exception('installation failed.')
633
- fileop.rollback()
634
- raise
635
- finally:
636
- shutil.rmtree(workdir)
637
-
638
- def _get_dylib_cache(self):
639
- global cache
640
- if cache is None:
641
- # Use native string to avoid issues on 2.x: see Python #20140.
642
- base = os.path.join(get_cache_base(), str('dylib-cache'),
643
- sys.version[:3])
644
- cache = Cache(base)
645
- return cache
646
-
647
- def _get_extensions(self):
648
- pathname = os.path.join(self.dirname, self.filename)
649
- name_ver = '%s-%s' % (self.name, self.version)
650
- info_dir = '%s.dist-info' % name_ver
651
- arcname = posixpath.join(info_dir, 'EXTENSIONS')
652
- wrapper = codecs.getreader('utf-8')
653
- result = []
654
- with ZipFile(pathname, 'r') as zf:
655
- try:
656
- with zf.open(arcname) as bf:
657
- wf = wrapper(bf)
658
- extensions = json.load(wf)
659
- cache = self._get_dylib_cache()
660
- prefix = cache.prefix_to_dir(pathname)
661
- cache_base = os.path.join(cache.base, prefix)
662
- if not os.path.isdir(cache_base):
663
- os.makedirs(cache_base)
664
- for name, relpath in extensions.items():
665
- dest = os.path.join(cache_base, convert_path(relpath))
666
- if not os.path.exists(dest):
667
- extract = True
668
- else:
669
- file_time = os.stat(dest).st_mtime
670
- file_time = datetime.datetime.fromtimestamp(file_time)
671
- info = zf.getinfo(relpath)
672
- wheel_time = datetime.datetime(*info.date_time)
673
- extract = wheel_time > file_time
674
- if extract:
675
- zf.extract(relpath, cache_base)
676
- result.append((name, dest))
677
- except KeyError:
678
- pass
679
- return result
680
-
681
- def is_compatible(self):
682
- """
683
- Determine if a wheel is compatible with the running system.
684
- """
685
- return is_compatible(self)
686
-
687
- def is_mountable(self):
688
- """
689
- Determine if a wheel is asserted as mountable by its metadata.
690
- """
691
- return True # for now - metadata details TBD
692
-
693
- def mount(self, append=False):
694
- pathname = os.path.abspath(os.path.join(self.dirname, self.filename))
695
- if not self.is_compatible():
696
- msg = 'Wheel %s not compatible with this Python.' % pathname
697
- raise DistlibException(msg)
698
- if not self.is_mountable():
699
- msg = 'Wheel %s is marked as not mountable.' % pathname
700
- raise DistlibException(msg)
701
- if pathname in sys.path:
702
- logger.debug('%s already in path', pathname)
703
- else:
704
- if append:
705
- sys.path.append(pathname)
706
- else:
707
- sys.path.insert(0, pathname)
708
- extensions = self._get_extensions()
709
- if extensions:
710
- if _hook not in sys.meta_path:
711
- sys.meta_path.append(_hook)
712
- _hook.add(pathname, extensions)
713
-
714
- def unmount(self):
715
- pathname = os.path.abspath(os.path.join(self.dirname, self.filename))
716
- if pathname not in sys.path:
717
- logger.debug('%s not in path', pathname)
718
- else:
719
- sys.path.remove(pathname)
720
- if pathname in _hook.impure_wheels:
721
- _hook.remove(pathname)
722
- if not _hook.impure_wheels:
723
- if _hook in sys.meta_path:
724
- sys.meta_path.remove(_hook)
725
-
726
- def verify(self):
727
- pathname = os.path.join(self.dirname, self.filename)
728
- name_ver = '%s-%s' % (self.name, self.version)
729
- data_dir = '%s.data' % name_ver
730
- info_dir = '%s.dist-info' % name_ver
731
-
732
- metadata_name = posixpath.join(info_dir, METADATA_FILENAME)
733
- wheel_metadata_name = posixpath.join(info_dir, 'WHEEL')
734
- record_name = posixpath.join(info_dir, 'RECORD')
735
-
736
- wrapper = codecs.getreader('utf-8')
737
-
738
- with ZipFile(pathname, 'r') as zf:
739
- with zf.open(wheel_metadata_name) as bwf:
740
- wf = wrapper(bwf)
741
- message = message_from_file(wf)
742
- wv = message['Wheel-Version'].split('.', 1)
743
- file_version = tuple([int(i) for i in wv])
744
- # TODO version verification
745
-
746
- records = {}
747
- with zf.open(record_name) as bf:
748
- with CSVReader(stream=bf) as reader:
749
- for row in reader:
750
- p = row[0]
751
- records[p] = row
752
-
753
- for zinfo in zf.infolist():
754
- arcname = zinfo.filename
755
- if isinstance(arcname, text_type):
756
- u_arcname = arcname
757
- else:
758
- u_arcname = arcname.decode('utf-8')
759
- if '..' in u_arcname:
760
- raise DistlibException('invalid entry in '
761
- 'wheel: %r' % u_arcname)
762
-
763
- # The signature file won't be in RECORD,
764
- # and we don't currently don't do anything with it
765
- if u_arcname.endswith('/RECORD.jws'):
766
- continue
767
- row = records[u_arcname]
768
- if row[2] and str(zinfo.file_size) != row[2]:
769
- raise DistlibException('size mismatch for '
770
- '%s' % u_arcname)
771
- if row[1]:
772
- kind, value = row[1].split('=', 1)
773
- with zf.open(arcname) as bf:
774
- data = bf.read()
775
- _, digest = self.get_hash(data, kind)
776
- if digest != value:
777
- raise DistlibException('digest mismatch for '
778
- '%s' % arcname)
779
-
780
- def update(self, modifier, dest_dir=None, **kwargs):
781
- """
782
- Update the contents of a wheel in a generic way. The modifier should
783
- be a callable which expects a dictionary argument: its keys are
784
- archive-entry paths, and its values are absolute filesystem paths
785
- where the contents the corresponding archive entries can be found. The
786
- modifier is free to change the contents of the files pointed to, add
787
- new entries and remove entries, before returning. This method will
788
- extract the entire contents of the wheel to a temporary location, call
789
- the modifier, and then use the passed (and possibly updated)
790
- dictionary to write a new wheel. If ``dest_dir`` is specified, the new
791
- wheel is written there -- otherwise, the original wheel is overwritten.
792
-
793
- The modifier should return True if it updated the wheel, else False.
794
- This method returns the same value the modifier returns.
795
- """
796
-
797
- def get_version(path_map, info_dir):
798
- version = path = None
799
- key = '%s/%s' % (info_dir, METADATA_FILENAME)
800
- if key not in path_map:
801
- key = '%s/PKG-INFO' % info_dir
802
- if key in path_map:
803
- path = path_map[key]
804
- version = Metadata(path=path).version
805
- return version, path
806
-
807
- def update_version(version, path):
808
- updated = None
809
- try:
810
- v = NormalizedVersion(version)
811
- i = version.find('-')
812
- if i < 0:
813
- updated = '%s-1' % version
814
- else:
815
- parts = [int(s) for s in version[i + 1:].split('.')]
816
- parts[-1] += 1
817
- updated = '%s-%s' % (version[:i],
818
- '.'.join(str(i) for i in parts))
819
- except UnsupportedVersionError:
820
- logger.debug('Cannot update non-compliant (PEP-440) '
821
- 'version %r', version)
822
- if updated:
823
- md = Metadata(path=path)
824
- md.version = updated
825
- legacy = not path.endswith(METADATA_FILENAME)
826
- md.write(path=path, legacy=legacy)
827
- logger.debug('Version updated from %r to %r', version,
828
- updated)
829
-
830
- pathname = os.path.join(self.dirname, self.filename)
831
- name_ver = '%s-%s' % (self.name, self.version)
832
- info_dir = '%s.dist-info' % name_ver
833
- record_name = posixpath.join(info_dir, 'RECORD')
834
- with tempdir() as workdir:
835
- with ZipFile(pathname, 'r') as zf:
836
- path_map = {}
837
- for zinfo in zf.infolist():
838
- arcname = zinfo.filename
839
- if isinstance(arcname, text_type):
840
- u_arcname = arcname
841
- else:
842
- u_arcname = arcname.decode('utf-8')
843
- if u_arcname == record_name:
844
- continue
845
- if '..' in u_arcname:
846
- raise DistlibException('invalid entry in '
847
- 'wheel: %r' % u_arcname)
848
- zf.extract(zinfo, workdir)
849
- path = os.path.join(workdir, convert_path(u_arcname))
850
- path_map[u_arcname] = path
851
-
852
- # Remember the version.
853
- original_version, _ = get_version(path_map, info_dir)
854
- # Files extracted. Call the modifier.
855
- modified = modifier(path_map, **kwargs)
856
- if modified:
857
- # Something changed - need to build a new wheel.
858
- current_version, path = get_version(path_map, info_dir)
859
- if current_version and (current_version == original_version):
860
- # Add or update local version to signify changes.
861
- update_version(current_version, path)
862
- # Decide where the new wheel goes.
863
- if dest_dir is None:
864
- fd, newpath = tempfile.mkstemp(suffix='.whl',
865
- prefix='wheel-update-',
866
- dir=workdir)
867
- os.close(fd)
868
- else:
869
- if not os.path.isdir(dest_dir):
870
- raise DistlibException('Not a directory: %r' % dest_dir)
871
- newpath = os.path.join(dest_dir, self.filename)
872
- archive_paths = list(path_map.items())
873
- distinfo = os.path.join(workdir, info_dir)
874
- info = distinfo, info_dir
875
- self.write_records(info, workdir, archive_paths)
876
- self.build_zip(newpath, archive_paths)
877
- if dest_dir is None:
878
- shutil.copyfile(newpath, pathname)
879
- return modified
880
-
881
- def compatible_tags():
882
- """
883
- Return (pyver, abi, arch) tuples compatible with this Python.
884
- """
885
- versions = [VER_SUFFIX]
886
- major = VER_SUFFIX[0]
887
- for minor in range(sys.version_info[1] - 1, - 1, -1):
888
- versions.append(''.join([major, str(minor)]))
889
-
890
- abis = []
891
- for suffix, _, _ in imp.get_suffixes():
892
- if suffix.startswith('.abi'):
893
- abis.append(suffix.split('.', 2)[1])
894
- abis.sort()
895
- if ABI != 'none':
896
- abis.insert(0, ABI)
897
- abis.append('none')
898
- result = []
899
-
900
- arches = [ARCH]
901
- if sys.platform == 'darwin':
902
- m = re.match('(\w+)_(\d+)_(\d+)_(\w+)$', ARCH)
903
- if m:
904
- name, major, minor, arch = m.groups()
905
- minor = int(minor)
906
- matches = [arch]
907
- if arch in ('i386', 'ppc'):
908
- matches.append('fat')
909
- if arch in ('i386', 'ppc', 'x86_64'):
910
- matches.append('fat3')
911
- if arch in ('ppc64', 'x86_64'):
912
- matches.append('fat64')
913
- if arch in ('i386', 'x86_64'):
914
- matches.append('intel')
915
- if arch in ('i386', 'x86_64', 'intel', 'ppc', 'ppc64'):
916
- matches.append('universal')
917
- while minor >= 0:
918
- for match in matches:
919
- s = '%s_%s_%s_%s' % (name, major, minor, match)
920
- if s != ARCH: # already there
921
- arches.append(s)
922
- minor -= 1
923
-
924
- # Most specific - our Python version, ABI and arch
925
- for abi in abis:
926
- for arch in arches:
927
- result.append((''.join((IMP_PREFIX, versions[0])), abi, arch))
928
-
929
- # where no ABI / arch dependency, but IMP_PREFIX dependency
930
- for i, version in enumerate(versions):
931
- result.append((''.join((IMP_PREFIX, version)), 'none', 'any'))
932
- if i == 0:
933
- result.append((''.join((IMP_PREFIX, version[0])), 'none', 'any'))
934
-
935
- # no IMP_PREFIX, ABI or arch dependency
936
- for i, version in enumerate(versions):
937
- result.append((''.join(('py', version)), 'none', 'any'))
938
- if i == 0:
939
- result.append((''.join(('py', version[0])), 'none', 'any'))
940
- return set(result)
941
-
942
-
943
- COMPATIBLE_TAGS = compatible_tags()
944
-
945
- del compatible_tags
946
-
947
-
948
- def is_compatible(wheel, tags=None):
949
- if not isinstance(wheel, Wheel):
950
- wheel = Wheel(wheel) # assume it's a filename
951
- result = False
952
- if tags is None:
953
- tags = COMPATIBLE_TAGS
954
- for ver, abi, arch in tags:
955
- if ver in wheel.pyver and abi in wheel.abi and arch in wheel.arch:
956
- result = True
957
- break
958
- return result
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 unicode_literals
8
+
9
+ import base64
10
+ import codecs
11
+ import datetime
12
+ import distutils.util
13
+ from email import message_from_file
14
+ import hashlib
15
+ import imp
16
+ import json
17
+ import logging
18
+ import os
19
+ import posixpath
20
+ import re
21
+ import shutil
22
+ import sys
23
+ import tempfile
24
+ import zipfile
25
+
26
+ from . import __version__, DistlibException
27
+ from .compat import sysconfig, ZipFile, fsdecode, text_type, filter
28
+ from .database import InstalledDistribution
29
+ from .metadata import Metadata, METADATA_FILENAME, WHEEL_METADATA_FILENAME
30
+ from .util import (FileOperator, convert_path, CSVReader, CSVWriter, Cache,
31
+ cached_property, get_cache_base, read_exports, tempdir)
32
+ from .version import NormalizedVersion, UnsupportedVersionError
33
+
34
+ logger = logging.getLogger(__name__)
35
+
36
+ cache = None # created when needed
37
+
38
+ if hasattr(sys, 'pypy_version_info'): # pragma: no cover
39
+ IMP_PREFIX = 'pp'
40
+ elif sys.platform.startswith('java'): # pragma: no cover
41
+ IMP_PREFIX = 'jy'
42
+ elif sys.platform == 'cli': # pragma: no cover
43
+ IMP_PREFIX = 'ip'
44
+ else:
45
+ IMP_PREFIX = 'cp'
46
+
47
+ VER_SUFFIX = sysconfig.get_config_var('py_version_nodot')
48
+ if not VER_SUFFIX: # pragma: no cover
49
+ VER_SUFFIX = '%s%s' % sys.version_info[:2]
50
+ PYVER = 'py' + VER_SUFFIX
51
+ IMPVER = IMP_PREFIX + VER_SUFFIX
52
+
53
+ ARCH = distutils.util.get_platform().replace('-', '_').replace('.', '_')
54
+
55
+ ABI = sysconfig.get_config_var('SOABI')
56
+ if ABI and ABI.startswith('cpython-'):
57
+ ABI = ABI.replace('cpython-', 'cp')
58
+ else:
59
+ def _derive_abi():
60
+ parts = ['cp', VER_SUFFIX]
61
+ if sysconfig.get_config_var('Py_DEBUG'):
62
+ parts.append('d')
63
+ if sysconfig.get_config_var('WITH_PYMALLOC'):
64
+ parts.append('m')
65
+ if sysconfig.get_config_var('Py_UNICODE_SIZE') == 4:
66
+ parts.append('u')
67
+ return ''.join(parts)
68
+ ABI = _derive_abi()
69
+ del _derive_abi
70
+
71
+ FILENAME_RE = re.compile(r'''
72
+ (?P<nm>[^-]+)
73
+ -(?P<vn>\d+[^-]*)
74
+ (-(?P<bn>\d+[^-]*))?
75
+ -(?P<py>\w+\d+(\.\w+\d+)*)
76
+ -(?P<bi>\w+)
77
+ -(?P<ar>\w+(\.\w+)*)
78
+ \.whl$
79
+ ''', re.IGNORECASE | re.VERBOSE)
80
+
81
+ NAME_VERSION_RE = re.compile(r'''
82
+ (?P<nm>[^-]+)
83
+ -(?P<vn>\d+[^-]*)
84
+ (-(?P<bn>\d+[^-]*))?$
85
+ ''', re.IGNORECASE | re.VERBOSE)
86
+
87
+ SHEBANG_RE = re.compile(br'\s*#![^\r\n]*')
88
+ SHEBANG_DETAIL_RE = re.compile(br'^(\s*#!("[^"]+"|\S+))\s+(.*)$')
89
+ SHEBANG_PYTHON = b'#!python'
90
+ SHEBANG_PYTHONW = b'#!pythonw'
91
+
92
+ if os.sep == '/':
93
+ to_posix = lambda o: o
94
+ else:
95
+ to_posix = lambda o: o.replace(os.sep, '/')
96
+
97
+
98
+ class Mounter(object):
99
+ def __init__(self):
100
+ self.impure_wheels = {}
101
+ self.libs = {}
102
+
103
+ def add(self, pathname, extensions):
104
+ self.impure_wheels[pathname] = extensions
105
+ self.libs.update(extensions)
106
+
107
+ def remove(self, pathname):
108
+ extensions = self.impure_wheels.pop(pathname)
109
+ for k, v in extensions:
110
+ if k in self.libs:
111
+ del self.libs[k]
112
+
113
+ def find_module(self, fullname, path=None):
114
+ if fullname in self.libs:
115
+ result = self
116
+ else:
117
+ result = None
118
+ return result
119
+
120
+ def load_module(self, fullname):
121
+ if fullname in sys.modules:
122
+ result = sys.modules[fullname]
123
+ else:
124
+ if fullname not in self.libs:
125
+ raise ImportError('unable to find extension for %s' % fullname)
126
+ result = imp.load_dynamic(fullname, self.libs[fullname])
127
+ result.__loader__ = self
128
+ parts = fullname.rsplit('.', 1)
129
+ if len(parts) > 1:
130
+ result.__package__ = parts[0]
131
+ return result
132
+
133
+ _hook = Mounter()
134
+
135
+
136
+ class Wheel(object):
137
+ """
138
+ Class to build and install from Wheel files (PEP 427).
139
+ """
140
+
141
+ wheel_version = (1, 1)
142
+ hash_kind = 'sha256'
143
+
144
+ def __init__(self, filename=None, sign=False, verify=False):
145
+ """
146
+ Initialise an instance using a (valid) filename.
147
+ """
148
+ self.sign = sign
149
+ self.should_verify = verify
150
+ self.buildver = ''
151
+ self.pyver = [PYVER]
152
+ self.abi = ['none']
153
+ self.arch = ['any']
154
+ self.dirname = os.getcwd()
155
+ if filename is None:
156
+ self.name = 'dummy'
157
+ self.version = '0.1'
158
+ self._filename = self.filename
159
+ else:
160
+ m = NAME_VERSION_RE.match(filename)
161
+ if m:
162
+ info = m.groupdict('')
163
+ self.name = info['nm']
164
+ # Reinstate the local version separator
165
+ self.version = info['vn'].replace('_', '-')
166
+ self.buildver = info['bn']
167
+ self._filename = self.filename
168
+ else:
169
+ dirname, filename = os.path.split(filename)
170
+ m = FILENAME_RE.match(filename)
171
+ if not m:
172
+ raise DistlibException('Invalid name or '
173
+ 'filename: %r' % filename)
174
+ if dirname:
175
+ self.dirname = os.path.abspath(dirname)
176
+ self._filename = filename
177
+ info = m.groupdict('')
178
+ self.name = info['nm']
179
+ self.version = info['vn']
180
+ self.buildver = info['bn']
181
+ self.pyver = info['py'].split('.')
182
+ self.abi = info['bi'].split('.')
183
+ self.arch = info['ar'].split('.')
184
+
185
+ @property
186
+ def filename(self):
187
+ """
188
+ Build and return a filename from the various components.
189
+ """
190
+ if self.buildver:
191
+ buildver = '-' + self.buildver
192
+ else:
193
+ buildver = ''
194
+ pyver = '.'.join(self.pyver)
195
+ abi = '.'.join(self.abi)
196
+ arch = '.'.join(self.arch)
197
+ # replace - with _ as a local version separator
198
+ version = self.version.replace('-', '_')
199
+ return '%s-%s%s-%s-%s-%s.whl' % (self.name, version, buildver,
200
+ pyver, abi, arch)
201
+
202
+ @property
203
+ def exists(self):
204
+ path = os.path.join(self.dirname, self.filename)
205
+ return os.path.isfile(path)
206
+
207
+ @property
208
+ def tags(self):
209
+ for pyver in self.pyver:
210
+ for abi in self.abi:
211
+ for arch in self.arch:
212
+ yield pyver, abi, arch
213
+
214
+ @cached_property
215
+ def metadata(self):
216
+ pathname = os.path.join(self.dirname, self.filename)
217
+ name_ver = '%s-%s' % (self.name, self.version)
218
+ info_dir = '%s.dist-info' % name_ver
219
+ wrapper = codecs.getreader('utf-8')
220
+ with ZipFile(pathname, 'r') as zf:
221
+ wheel_metadata = self.get_wheel_metadata(zf)
222
+ wv = wheel_metadata['Wheel-Version'].split('.', 1)
223
+ file_version = tuple([int(i) for i in wv])
224
+ if file_version < (1, 1):
225
+ fns = [WHEEL_METADATA_FILENAME, METADATA_FILENAME, 'METADATA']
226
+ else:
227
+ fns = [WHEEL_METADATA_FILENAME, METADATA_FILENAME]
228
+ result = None
229
+ for fn in fns:
230
+ try:
231
+ metadata_filename = posixpath.join(info_dir, fn)
232
+ with zf.open(metadata_filename) as bf:
233
+ wf = wrapper(bf)
234
+ result = Metadata(fileobj=wf)
235
+ if result:
236
+ break
237
+ except KeyError:
238
+ pass
239
+ if not result:
240
+ raise ValueError('Invalid wheel, because metadata is '
241
+ 'missing: looked in %s' % ', '.join(fns))
242
+ return result
243
+
244
+ def get_wheel_metadata(self, zf):
245
+ name_ver = '%s-%s' % (self.name, self.version)
246
+ info_dir = '%s.dist-info' % name_ver
247
+ metadata_filename = posixpath.join(info_dir, 'WHEEL')
248
+ with zf.open(metadata_filename) as bf:
249
+ wf = codecs.getreader('utf-8')(bf)
250
+ message = message_from_file(wf)
251
+ return dict(message)
252
+
253
+ @cached_property
254
+ def info(self):
255
+ pathname = os.path.join(self.dirname, self.filename)
256
+ with ZipFile(pathname, 'r') as zf:
257
+ result = self.get_wheel_metadata(zf)
258
+ return result
259
+
260
+ def process_shebang(self, data):
261
+ m = SHEBANG_RE.match(data)
262
+ if m:
263
+ end = m.end()
264
+ shebang, data_after_shebang = data[:end], data[end:]
265
+ # Preserve any arguments after the interpreter
266
+ if b'pythonw' in shebang.lower():
267
+ shebang_python = SHEBANG_PYTHONW
268
+ else:
269
+ shebang_python = SHEBANG_PYTHON
270
+ m = SHEBANG_DETAIL_RE.match(shebang)
271
+ if m:
272
+ args = b' ' + m.groups()[-1]
273
+ else:
274
+ args = b''
275
+ shebang = shebang_python + args
276
+ data = shebang + data_after_shebang
277
+ else:
278
+ cr = data.find(b'\r')
279
+ lf = data.find(b'\n')
280
+ if cr < 0 or cr > lf:
281
+ term = b'\n'
282
+ else:
283
+ if data[cr:cr + 2] == b'\r\n':
284
+ term = b'\r\n'
285
+ else:
286
+ term = b'\r'
287
+ data = SHEBANG_PYTHON + term + data
288
+ return data
289
+
290
+ def get_hash(self, data, hash_kind=None):
291
+ if hash_kind is None:
292
+ hash_kind = self.hash_kind
293
+ try:
294
+ hasher = getattr(hashlib, hash_kind)
295
+ except AttributeError:
296
+ raise DistlibException('Unsupported hash algorithm: %r' % hash_kind)
297
+ result = hasher(data).digest()
298
+ result = base64.urlsafe_b64encode(result).rstrip(b'=').decode('ascii')
299
+ return hash_kind, result
300
+
301
+ def write_record(self, records, record_path, base):
302
+ records = list(records) # make a copy for sorting
303
+ p = to_posix(os.path.relpath(record_path, base))
304
+ records.append((p, '', ''))
305
+ records.sort()
306
+ with CSVWriter(record_path) as writer:
307
+ for row in records:
308
+ writer.writerow(row)
309
+
310
+ def write_records(self, info, libdir, archive_paths):
311
+ records = []
312
+ distinfo, info_dir = info
313
+ hasher = getattr(hashlib, self.hash_kind)
314
+ for ap, p in archive_paths:
315
+ with open(p, 'rb') as f:
316
+ data = f.read()
317
+ digest = '%s=%s' % self.get_hash(data)
318
+ size = os.path.getsize(p)
319
+ records.append((ap, digest, size))
320
+
321
+ p = os.path.join(distinfo, 'RECORD')
322
+ self.write_record(records, p, libdir)
323
+ ap = to_posix(os.path.join(info_dir, 'RECORD'))
324
+ archive_paths.append((ap, p))
325
+
326
+ def build_zip(self, pathname, archive_paths):
327
+ with ZipFile(pathname, 'w', zipfile.ZIP_DEFLATED) as zf:
328
+ for ap, p in archive_paths:
329
+ logger.debug('Wrote %s to %s in wheel', p, ap)
330
+ zf.write(p, ap)
331
+
332
+ def build(self, paths, tags=None, wheel_version=None):
333
+ """
334
+ Build a wheel from files in specified paths, and use any specified tags
335
+ when determining the name of the wheel.
336
+ """
337
+ if tags is None:
338
+ tags = {}
339
+
340
+ libkey = list(filter(lambda o: o in paths, ('purelib', 'platlib')))[0]
341
+ if libkey == 'platlib':
342
+ is_pure = 'false'
343
+ default_pyver = [IMPVER]
344
+ default_abi = [ABI]
345
+ default_arch = [ARCH]
346
+ else:
347
+ is_pure = 'true'
348
+ default_pyver = [PYVER]
349
+ default_abi = ['none']
350
+ default_arch = ['any']
351
+
352
+ self.pyver = tags.get('pyver', default_pyver)
353
+ self.abi = tags.get('abi', default_abi)
354
+ self.arch = tags.get('arch', default_arch)
355
+
356
+ libdir = paths[libkey]
357
+
358
+ name_ver = '%s-%s' % (self.name, self.version)
359
+ data_dir = '%s.data' % name_ver
360
+ info_dir = '%s.dist-info' % name_ver
361
+
362
+ archive_paths = []
363
+
364
+ # First, stuff which is not in site-packages
365
+ for key in ('data', 'headers', 'scripts'):
366
+ if key not in paths:
367
+ continue
368
+ path = paths[key]
369
+ if os.path.isdir(path):
370
+ for root, dirs, files in os.walk(path):
371
+ for fn in files:
372
+ p = fsdecode(os.path.join(root, fn))
373
+ rp = os.path.relpath(p, path)
374
+ ap = to_posix(os.path.join(data_dir, key, rp))
375
+ archive_paths.append((ap, p))
376
+ if key == 'scripts' and not p.endswith('.exe'):
377
+ with open(p, 'rb') as f:
378
+ data = f.read()
379
+ data = self.process_shebang(data)
380
+ with open(p, 'wb') as f:
381
+ f.write(data)
382
+
383
+ # Now, stuff which is in site-packages, other than the
384
+ # distinfo stuff.
385
+ path = libdir
386
+ distinfo = None
387
+ for root, dirs, files in os.walk(path):
388
+ if root == path:
389
+ # At the top level only, save distinfo for later
390
+ # and skip it for now
391
+ for i, dn in enumerate(dirs):
392
+ dn = fsdecode(dn)
393
+ if dn.endswith('.dist-info'):
394
+ distinfo = os.path.join(root, dn)
395
+ del dirs[i]
396
+ break
397
+ assert distinfo, '.dist-info directory expected, not found'
398
+
399
+ for fn in files:
400
+ # comment out next suite to leave .pyc files in
401
+ if fsdecode(fn).endswith(('.pyc', '.pyo')):
402
+ continue
403
+ p = os.path.join(root, fn)
404
+ rp = to_posix(os.path.relpath(p, path))
405
+ archive_paths.append((rp, p))
406
+
407
+ # Now distinfo. Assumed to be flat, i.e. os.listdir is enough.
408
+ files = os.listdir(distinfo)
409
+ for fn in files:
410
+ if fn not in ('RECORD', 'INSTALLER', 'SHARED', 'WHEEL'):
411
+ p = fsdecode(os.path.join(distinfo, fn))
412
+ ap = to_posix(os.path.join(info_dir, fn))
413
+ archive_paths.append((ap, p))
414
+
415
+ wheel_metadata = [
416
+ 'Wheel-Version: %d.%d' % (wheel_version or self.wheel_version),
417
+ 'Generator: distlib %s' % __version__,
418
+ 'Root-Is-Purelib: %s' % is_pure,
419
+ ]
420
+ for pyver, abi, arch in self.tags:
421
+ wheel_metadata.append('Tag: %s-%s-%s' % (pyver, abi, arch))
422
+ p = os.path.join(distinfo, 'WHEEL')
423
+ with open(p, 'w') as f:
424
+ f.write('\n'.join(wheel_metadata))
425
+ ap = to_posix(os.path.join(info_dir, 'WHEEL'))
426
+ archive_paths.append((ap, p))
427
+
428
+ # Now, at last, RECORD.
429
+ # Paths in here are archive paths - nothing else makes sense.
430
+ self.write_records((distinfo, info_dir), libdir, archive_paths)
431
+ # Now, ready to build the zip file
432
+ pathname = os.path.join(self.dirname, self.filename)
433
+ self.build_zip(pathname, archive_paths)
434
+ return pathname
435
+
436
+ def install(self, paths, maker, **kwargs):
437
+ """
438
+ Install a wheel to the specified paths. If kwarg ``warner`` is
439
+ specified, it should be a callable, which will be called with two
440
+ tuples indicating the wheel version of this software and the wheel
441
+ version in the file, if there is a discrepancy in the versions.
442
+ This can be used to issue any warnings to raise any exceptions.
443
+ If kwarg ``lib_only`` is True, only the purelib/platlib files are
444
+ installed, and the headers, scripts, data and dist-info metadata are
445
+ not written.
446
+
447
+ The return value is a :class:`InstalledDistribution` instance unless
448
+ ``options.lib_only`` is True, in which case the return value is ``None``.
449
+ """
450
+
451
+ dry_run = maker.dry_run
452
+ warner = kwargs.get('warner')
453
+ lib_only = kwargs.get('lib_only', False)
454
+
455
+ pathname = os.path.join(self.dirname, self.filename)
456
+ name_ver = '%s-%s' % (self.name, self.version)
457
+ data_dir = '%s.data' % name_ver
458
+ info_dir = '%s.dist-info' % name_ver
459
+
460
+ metadata_name = posixpath.join(info_dir, METADATA_FILENAME)
461
+ wheel_metadata_name = posixpath.join(info_dir, 'WHEEL')
462
+ record_name = posixpath.join(info_dir, 'RECORD')
463
+
464
+ wrapper = codecs.getreader('utf-8')
465
+
466
+ with ZipFile(pathname, 'r') as zf:
467
+ with zf.open(wheel_metadata_name) as bwf:
468
+ wf = wrapper(bwf)
469
+ message = message_from_file(wf)
470
+ wv = message['Wheel-Version'].split('.', 1)
471
+ file_version = tuple([int(i) for i in wv])
472
+ if (file_version != self.wheel_version) and warner:
473
+ warner(self.wheel_version, file_version)
474
+
475
+ if message['Root-Is-Purelib'] == 'true':
476
+ libdir = paths['purelib']
477
+ else:
478
+ libdir = paths['platlib']
479
+
480
+ records = {}
481
+ with zf.open(record_name) as bf:
482
+ with CSVReader(stream=bf) as reader:
483
+ for row in reader:
484
+ p = row[0]
485
+ records[p] = row
486
+
487
+ data_pfx = posixpath.join(data_dir, '')
488
+ info_pfx = posixpath.join(info_dir, '')
489
+ script_pfx = posixpath.join(data_dir, 'scripts', '')
490
+
491
+ # make a new instance rather than a copy of maker's,
492
+ # as we mutate it
493
+ fileop = FileOperator(dry_run=dry_run)
494
+ fileop.record = True # so we can rollback if needed
495
+
496
+ bc = not sys.dont_write_bytecode # Double negatives. Lovely!
497
+
498
+ outfiles = [] # for RECORD writing
499
+
500
+ # for script copying/shebang processing
501
+ workdir = tempfile.mkdtemp()
502
+ # set target dir later
503
+ # we default add_launchers to False, as the
504
+ # Python Launcher should be used instead
505
+ maker.source_dir = workdir
506
+ maker.target_dir = None
507
+ try:
508
+ for zinfo in zf.infolist():
509
+ arcname = zinfo.filename
510
+ if isinstance(arcname, text_type):
511
+ u_arcname = arcname
512
+ else:
513
+ u_arcname = arcname.decode('utf-8')
514
+ # The signature file won't be in RECORD,
515
+ # and we don't currently don't do anything with it
516
+ if u_arcname.endswith('/RECORD.jws'):
517
+ continue
518
+ row = records[u_arcname]
519
+ if row[2] and str(zinfo.file_size) != row[2]:
520
+ raise DistlibException('size mismatch for '
521
+ '%s' % u_arcname)
522
+ if row[1]:
523
+ kind, value = row[1].split('=', 1)
524
+ with zf.open(arcname) as bf:
525
+ data = bf.read()
526
+ _, digest = self.get_hash(data, kind)
527
+ if digest != value:
528
+ raise DistlibException('digest mismatch for '
529
+ '%s' % arcname)
530
+
531
+ if lib_only and u_arcname.startswith((info_pfx, data_pfx)):
532
+ logger.debug('lib_only: skipping %s', u_arcname)
533
+ continue
534
+ is_script = (u_arcname.startswith(script_pfx)
535
+ and not u_arcname.endswith('.exe'))
536
+
537
+ if u_arcname.startswith(data_pfx):
538
+ _, where, rp = u_arcname.split('/', 2)
539
+ outfile = os.path.join(paths[where], convert_path(rp))
540
+ else:
541
+ # meant for site-packages.
542
+ if u_arcname in (wheel_metadata_name, record_name):
543
+ continue
544
+ outfile = os.path.join(libdir, convert_path(u_arcname))
545
+ if not is_script:
546
+ with zf.open(arcname) as bf:
547
+ fileop.copy_stream(bf, outfile)
548
+ outfiles.append(outfile)
549
+ # Double check the digest of the written file
550
+ if not dry_run and row[1]:
551
+ with open(outfile, 'rb') as bf:
552
+ data = bf.read()
553
+ _, newdigest = self.get_hash(data, kind)
554
+ if newdigest != digest:
555
+ raise DistlibException('digest mismatch '
556
+ 'on write for '
557
+ '%s' % outfile)
558
+ if bc and outfile.endswith('.py'):
559
+ try:
560
+ pyc = fileop.byte_compile(outfile)
561
+ outfiles.append(pyc)
562
+ except Exception:
563
+ # Don't give up if byte-compilation fails,
564
+ # but log it and perhaps warn the user
565
+ logger.warning('Byte-compilation failed',
566
+ exc_info=True)
567
+ else:
568
+ fn = os.path.basename(convert_path(arcname))
569
+ workname = os.path.join(workdir, fn)
570
+ with zf.open(arcname) as bf:
571
+ fileop.copy_stream(bf, workname)
572
+
573
+ dn, fn = os.path.split(outfile)
574
+ maker.target_dir = dn
575
+ filenames = maker.make(fn)
576
+ fileop.set_executable_mode(filenames)
577
+ outfiles.extend(filenames)
578
+
579
+ if lib_only:
580
+ logger.debug('lib_only: returning None')
581
+ dist = None
582
+ else:
583
+ # Generate scripts
584
+
585
+ # Try to get pydist.json so we can see if there are
586
+ # any commands to generate. If this fails (e.g. because
587
+ # of a legacy wheel), log a warning but don't give up.
588
+ commands = None
589
+ file_version = self.info['Wheel-Version']
590
+ if file_version == '1.0':
591
+ # Use legacy info
592
+ ep = posixpath.join(info_dir, 'entry_points.txt')
593
+ try:
594
+ with zf.open(ep) as bwf:
595
+ epdata = read_exports(bwf)
596
+ commands = {}
597
+ for key in ('console', 'gui'):
598
+ k = '%s_scripts' % key
599
+ if k in epdata:
600
+ commands['wrap_%s' % key] = d = {}
601
+ for v in epdata[k].values():
602
+ s = '%s:%s' % (v.prefix, v.suffix)
603
+ if v.flags:
604
+ s += ' %s' % v.flags
605
+ d[v.name] = s
606
+ except Exception:
607
+ logger.warning('Unable to read legacy script '
608
+ 'metadata, so cannot generate '
609
+ 'scripts')
610
+ else:
611
+ try:
612
+ with zf.open(metadata_name) as bwf:
613
+ wf = wrapper(bwf)
614
+ commands = json.load(wf).get('extensions')
615
+ if commands:
616
+ commands = commands.get('python.commands')
617
+ except Exception:
618
+ logger.warning('Unable to read JSON metadata, so '
619
+ 'cannot generate scripts')
620
+ if commands:
621
+ console_scripts = commands.get('wrap_console', {})
622
+ gui_scripts = commands.get('wrap_gui', {})
623
+ if console_scripts or gui_scripts:
624
+ script_dir = paths.get('scripts', '')
625
+ if not os.path.isdir(script_dir):
626
+ raise ValueError('Valid script path not '
627
+ 'specified')
628
+ maker.target_dir = script_dir
629
+ for k, v in console_scripts.items():
630
+ script = '%s = %s' % (k, v)
631
+ filenames = maker.make(script)
632
+ fileop.set_executable_mode(filenames)
633
+
634
+ if gui_scripts:
635
+ options = {'gui': True }
636
+ for k, v in gui_scripts.items():
637
+ script = '%s = %s' % (k, v)
638
+ filenames = maker.make(script, options)
639
+ fileop.set_executable_mode(filenames)
640
+
641
+ p = os.path.join(libdir, info_dir)
642
+ dist = InstalledDistribution(p)
643
+
644
+ # Write SHARED
645
+ paths = dict(paths) # don't change passed in dict
646
+ del paths['purelib']
647
+ del paths['platlib']
648
+ paths['lib'] = libdir
649
+ p = dist.write_shared_locations(paths, dry_run)
650
+ if p:
651
+ outfiles.append(p)
652
+
653
+ # Write RECORD
654
+ dist.write_installed_files(outfiles, paths['prefix'],
655
+ dry_run)
656
+ return dist
657
+ except Exception: # pragma: no cover
658
+ logger.exception('installation failed.')
659
+ fileop.rollback()
660
+ raise
661
+ finally:
662
+ shutil.rmtree(workdir)
663
+
664
+ def _get_dylib_cache(self):
665
+ global cache
666
+ if cache is None:
667
+ # Use native string to avoid issues on 2.x: see Python #20140.
668
+ base = os.path.join(get_cache_base(), str('dylib-cache'),
669
+ sys.version[:3])
670
+ cache = Cache(base)
671
+ return cache
672
+
673
+ def _get_extensions(self):
674
+ pathname = os.path.join(self.dirname, self.filename)
675
+ name_ver = '%s-%s' % (self.name, self.version)
676
+ info_dir = '%s.dist-info' % name_ver
677
+ arcname = posixpath.join(info_dir, 'EXTENSIONS')
678
+ wrapper = codecs.getreader('utf-8')
679
+ result = []
680
+ with ZipFile(pathname, 'r') as zf:
681
+ try:
682
+ with zf.open(arcname) as bf:
683
+ wf = wrapper(bf)
684
+ extensions = json.load(wf)
685
+ cache = self._get_dylib_cache()
686
+ prefix = cache.prefix_to_dir(pathname)
687
+ cache_base = os.path.join(cache.base, prefix)
688
+ if not os.path.isdir(cache_base):
689
+ os.makedirs(cache_base)
690
+ for name, relpath in extensions.items():
691
+ dest = os.path.join(cache_base, convert_path(relpath))
692
+ if not os.path.exists(dest):
693
+ extract = True
694
+ else:
695
+ file_time = os.stat(dest).st_mtime
696
+ file_time = datetime.datetime.fromtimestamp(file_time)
697
+ info = zf.getinfo(relpath)
698
+ wheel_time = datetime.datetime(*info.date_time)
699
+ extract = wheel_time > file_time
700
+ if extract:
701
+ zf.extract(relpath, cache_base)
702
+ result.append((name, dest))
703
+ except KeyError:
704
+ pass
705
+ return result
706
+
707
+ def is_compatible(self):
708
+ """
709
+ Determine if a wheel is compatible with the running system.
710
+ """
711
+ return is_compatible(self)
712
+
713
+ def is_mountable(self):
714
+ """
715
+ Determine if a wheel is asserted as mountable by its metadata.
716
+ """
717
+ return True # for now - metadata details TBD
718
+
719
+ def mount(self, append=False):
720
+ pathname = os.path.abspath(os.path.join(self.dirname, self.filename))
721
+ if not self.is_compatible():
722
+ msg = 'Wheel %s not compatible with this Python.' % pathname
723
+ raise DistlibException(msg)
724
+ if not self.is_mountable():
725
+ msg = 'Wheel %s is marked as not mountable.' % pathname
726
+ raise DistlibException(msg)
727
+ if pathname in sys.path:
728
+ logger.debug('%s already in path', pathname)
729
+ else:
730
+ if append:
731
+ sys.path.append(pathname)
732
+ else:
733
+ sys.path.insert(0, pathname)
734
+ extensions = self._get_extensions()
735
+ if extensions:
736
+ if _hook not in sys.meta_path:
737
+ sys.meta_path.append(_hook)
738
+ _hook.add(pathname, extensions)
739
+
740
+ def unmount(self):
741
+ pathname = os.path.abspath(os.path.join(self.dirname, self.filename))
742
+ if pathname not in sys.path:
743
+ logger.debug('%s not in path', pathname)
744
+ else:
745
+ sys.path.remove(pathname)
746
+ if pathname in _hook.impure_wheels:
747
+ _hook.remove(pathname)
748
+ if not _hook.impure_wheels:
749
+ if _hook in sys.meta_path:
750
+ sys.meta_path.remove(_hook)
751
+
752
+ def verify(self):
753
+ pathname = os.path.join(self.dirname, self.filename)
754
+ name_ver = '%s-%s' % (self.name, self.version)
755
+ data_dir = '%s.data' % name_ver
756
+ info_dir = '%s.dist-info' % name_ver
757
+
758
+ metadata_name = posixpath.join(info_dir, METADATA_FILENAME)
759
+ wheel_metadata_name = posixpath.join(info_dir, 'WHEEL')
760
+ record_name = posixpath.join(info_dir, 'RECORD')
761
+
762
+ wrapper = codecs.getreader('utf-8')
763
+
764
+ with ZipFile(pathname, 'r') as zf:
765
+ with zf.open(wheel_metadata_name) as bwf:
766
+ wf = wrapper(bwf)
767
+ message = message_from_file(wf)
768
+ wv = message['Wheel-Version'].split('.', 1)
769
+ file_version = tuple([int(i) for i in wv])
770
+ # TODO version verification
771
+
772
+ records = {}
773
+ with zf.open(record_name) as bf:
774
+ with CSVReader(stream=bf) as reader:
775
+ for row in reader:
776
+ p = row[0]
777
+ records[p] = row
778
+
779
+ for zinfo in zf.infolist():
780
+ arcname = zinfo.filename
781
+ if isinstance(arcname, text_type):
782
+ u_arcname = arcname
783
+ else:
784
+ u_arcname = arcname.decode('utf-8')
785
+ if '..' in u_arcname:
786
+ raise DistlibException('invalid entry in '
787
+ 'wheel: %r' % u_arcname)
788
+
789
+ # The signature file won't be in RECORD,
790
+ # and we don't currently don't do anything with it
791
+ if u_arcname.endswith('/RECORD.jws'):
792
+ continue
793
+ row = records[u_arcname]
794
+ if row[2] and str(zinfo.file_size) != row[2]:
795
+ raise DistlibException('size mismatch for '
796
+ '%s' % u_arcname)
797
+ if row[1]:
798
+ kind, value = row[1].split('=', 1)
799
+ with zf.open(arcname) as bf:
800
+ data = bf.read()
801
+ _, digest = self.get_hash(data, kind)
802
+ if digest != value:
803
+ raise DistlibException('digest mismatch for '
804
+ '%s' % arcname)
805
+
806
+ def update(self, modifier, dest_dir=None, **kwargs):
807
+ """
808
+ Update the contents of a wheel in a generic way. The modifier should
809
+ be a callable which expects a dictionary argument: its keys are
810
+ archive-entry paths, and its values are absolute filesystem paths
811
+ where the contents the corresponding archive entries can be found. The
812
+ modifier is free to change the contents of the files pointed to, add
813
+ new entries and remove entries, before returning. This method will
814
+ extract the entire contents of the wheel to a temporary location, call
815
+ the modifier, and then use the passed (and possibly updated)
816
+ dictionary to write a new wheel. If ``dest_dir`` is specified, the new
817
+ wheel is written there -- otherwise, the original wheel is overwritten.
818
+
819
+ The modifier should return True if it updated the wheel, else False.
820
+ This method returns the same value the modifier returns.
821
+ """
822
+
823
+ def get_version(path_map, info_dir):
824
+ version = path = None
825
+ key = '%s/%s' % (info_dir, METADATA_FILENAME)
826
+ if key not in path_map:
827
+ key = '%s/PKG-INFO' % info_dir
828
+ if key in path_map:
829
+ path = path_map[key]
830
+ version = Metadata(path=path).version
831
+ return version, path
832
+
833
+ def update_version(version, path):
834
+ updated = None
835
+ try:
836
+ v = NormalizedVersion(version)
837
+ i = version.find('-')
838
+ if i < 0:
839
+ updated = '%s+1' % version
840
+ else:
841
+ parts = [int(s) for s in version[i + 1:].split('.')]
842
+ parts[-1] += 1
843
+ updated = '%s+%s' % (version[:i],
844
+ '.'.join(str(i) for i in parts))
845
+ except UnsupportedVersionError:
846
+ logger.debug('Cannot update non-compliant (PEP-440) '
847
+ 'version %r', version)
848
+ if updated:
849
+ md = Metadata(path=path)
850
+ md.version = updated
851
+ legacy = not path.endswith(METADATA_FILENAME)
852
+ md.write(path=path, legacy=legacy)
853
+ logger.debug('Version updated from %r to %r', version,
854
+ updated)
855
+
856
+ pathname = os.path.join(self.dirname, self.filename)
857
+ name_ver = '%s-%s' % (self.name, self.version)
858
+ info_dir = '%s.dist-info' % name_ver
859
+ record_name = posixpath.join(info_dir, 'RECORD')
860
+ with tempdir() as workdir:
861
+ with ZipFile(pathname, 'r') as zf:
862
+ path_map = {}
863
+ for zinfo in zf.infolist():
864
+ arcname = zinfo.filename
865
+ if isinstance(arcname, text_type):
866
+ u_arcname = arcname
867
+ else:
868
+ u_arcname = arcname.decode('utf-8')
869
+ if u_arcname == record_name:
870
+ continue
871
+ if '..' in u_arcname:
872
+ raise DistlibException('invalid entry in '
873
+ 'wheel: %r' % u_arcname)
874
+ zf.extract(zinfo, workdir)
875
+ path = os.path.join(workdir, convert_path(u_arcname))
876
+ path_map[u_arcname] = path
877
+
878
+ # Remember the version.
879
+ original_version, _ = get_version(path_map, info_dir)
880
+ # Files extracted. Call the modifier.
881
+ modified = modifier(path_map, **kwargs)
882
+ if modified:
883
+ # Something changed - need to build a new wheel.
884
+ current_version, path = get_version(path_map, info_dir)
885
+ if current_version and (current_version == original_version):
886
+ # Add or update local version to signify changes.
887
+ update_version(current_version, path)
888
+ # Decide where the new wheel goes.
889
+ if dest_dir is None:
890
+ fd, newpath = tempfile.mkstemp(suffix='.whl',
891
+ prefix='wheel-update-',
892
+ dir=workdir)
893
+ os.close(fd)
894
+ else:
895
+ if not os.path.isdir(dest_dir):
896
+ raise DistlibException('Not a directory: %r' % dest_dir)
897
+ newpath = os.path.join(dest_dir, self.filename)
898
+ archive_paths = list(path_map.items())
899
+ distinfo = os.path.join(workdir, info_dir)
900
+ info = distinfo, info_dir
901
+ self.write_records(info, workdir, archive_paths)
902
+ self.build_zip(newpath, archive_paths)
903
+ if dest_dir is None:
904
+ shutil.copyfile(newpath, pathname)
905
+ return modified
906
+
907
+ def compatible_tags():
908
+ """
909
+ Return (pyver, abi, arch) tuples compatible with this Python.
910
+ """
911
+ versions = [VER_SUFFIX]
912
+ major = VER_SUFFIX[0]
913
+ for minor in range(sys.version_info[1] - 1, - 1, -1):
914
+ versions.append(''.join([major, str(minor)]))
915
+
916
+ abis = []
917
+ for suffix, _, _ in imp.get_suffixes():
918
+ if suffix.startswith('.abi'):
919
+ abis.append(suffix.split('.', 2)[1])
920
+ abis.sort()
921
+ if ABI != 'none':
922
+ abis.insert(0, ABI)
923
+ abis.append('none')
924
+ result = []
925
+
926
+ arches = [ARCH]
927
+ if sys.platform == 'darwin':
928
+ m = re.match(r'(\w+)_(\d+)_(\d+)_(\w+)$', ARCH)
929
+ if m:
930
+ name, major, minor, arch = m.groups()
931
+ minor = int(minor)
932
+ matches = [arch]
933
+ if arch in ('i386', 'ppc'):
934
+ matches.append('fat')
935
+ if arch in ('i386', 'ppc', 'x86_64'):
936
+ matches.append('fat3')
937
+ if arch in ('ppc64', 'x86_64'):
938
+ matches.append('fat64')
939
+ if arch in ('i386', 'x86_64'):
940
+ matches.append('intel')
941
+ if arch in ('i386', 'x86_64', 'intel', 'ppc', 'ppc64'):
942
+ matches.append('universal')
943
+ while minor >= 0:
944
+ for match in matches:
945
+ s = '%s_%s_%s_%s' % (name, major, minor, match)
946
+ if s != ARCH: # already there
947
+ arches.append(s)
948
+ minor -= 1
949
+
950
+ # Most specific - our Python version, ABI and arch
951
+ for abi in abis:
952
+ for arch in arches:
953
+ result.append((''.join((IMP_PREFIX, versions[0])), abi, arch))
954
+
955
+ # where no ABI / arch dependency, but IMP_PREFIX dependency
956
+ for i, version in enumerate(versions):
957
+ result.append((''.join((IMP_PREFIX, version)), 'none', 'any'))
958
+ if i == 0:
959
+ result.append((''.join((IMP_PREFIX, version[0])), 'none', 'any'))
960
+
961
+ # no IMP_PREFIX, ABI or arch dependency
962
+ for i, version in enumerate(versions):
963
+ result.append((''.join(('py', version)), 'none', 'any'))
964
+ if i == 0:
965
+ result.append((''.join(('py', version[0])), 'none', 'any'))
966
+ return set(result)
967
+
968
+
969
+ COMPATIBLE_TAGS = compatible_tags()
970
+
971
+ del compatible_tags
972
+
973
+
974
+ def is_compatible(wheel, tags=None):
975
+ if not isinstance(wheel, Wheel):
976
+ wheel = Wheel(wheel) # assume it's a filename
977
+ result = False
978
+ if tags is None:
979
+ tags = COMPATIBLE_TAGS
980
+ for ver, abi, arch in tags:
981
+ if ver in wheel.pyver and abi in wheel.abi and arch in wheel.arch:
982
+ result = True
983
+ break
984
+ return result