pex 2.54.2__py2.py3-none-any.whl → 2.69.0__py2.py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of pex might be problematic. Click here for more details.

Files changed (180) hide show
  1. pex/auth.py +1 -1
  2. pex/bin/pex.py +15 -2
  3. pex/build_backend/configuration.py +5 -5
  4. pex/build_backend/wrap.py +27 -23
  5. pex/build_system/pep_517.py +4 -1
  6. pex/cache/dirs.py +17 -12
  7. pex/cli/commands/lock.py +302 -165
  8. pex/cli/commands/pip/core.py +4 -12
  9. pex/cli/commands/pip/wheel.py +1 -1
  10. pex/cli/commands/run.py +13 -20
  11. pex/cli/commands/venv.py +85 -16
  12. pex/cli/pex.py +11 -4
  13. pex/common.py +57 -7
  14. pex/compatibility.py +1 -1
  15. pex/dependency_configuration.py +87 -15
  16. pex/dist_metadata.py +143 -25
  17. pex/docs/html/_pagefind/fragment/en_4250138.pf_fragment +0 -0
  18. pex/docs/html/_pagefind/fragment/en_7125dad.pf_fragment +0 -0
  19. pex/docs/html/_pagefind/fragment/en_785d562.pf_fragment +0 -0
  20. pex/docs/html/_pagefind/fragment/en_8e94bb8.pf_fragment +0 -0
  21. pex/docs/html/_pagefind/fragment/en_a0396bb.pf_fragment +0 -0
  22. pex/docs/html/_pagefind/fragment/en_a8a3588.pf_fragment +0 -0
  23. pex/docs/html/_pagefind/fragment/en_c07d988.pf_fragment +0 -0
  24. pex/docs/html/_pagefind/fragment/en_d718411.pf_fragment +0 -0
  25. pex/docs/html/_pagefind/index/en_a2e3c5e.pf_index +0 -0
  26. pex/docs/html/_pagefind/pagefind-entry.json +1 -1
  27. pex/docs/html/_pagefind/pagefind.en_4ce1afa9e3.pf_meta +0 -0
  28. pex/docs/html/_static/documentation_options.js +1 -1
  29. pex/docs/html/_static/pygments.css +164 -146
  30. pex/docs/html/_static/styles/furo.css +1 -1
  31. pex/docs/html/_static/styles/furo.css.map +1 -1
  32. pex/docs/html/api/vars.html +25 -34
  33. pex/docs/html/buildingpex.html +25 -34
  34. pex/docs/html/genindex.html +24 -33
  35. pex/docs/html/index.html +25 -34
  36. pex/docs/html/recipes.html +25 -34
  37. pex/docs/html/scie.html +25 -34
  38. pex/docs/html/search.html +24 -33
  39. pex/docs/html/whatispex.html +25 -34
  40. pex/entry_points_txt.py +98 -0
  41. pex/environment.py +54 -33
  42. pex/finders.py +1 -1
  43. pex/hashing.py +71 -9
  44. pex/installed_wheel.py +141 -0
  45. pex/interpreter.py +41 -38
  46. pex/interpreter_constraints.py +25 -25
  47. pex/interpreter_implementation.py +40 -0
  48. pex/jobs.py +13 -6
  49. pex/pep_376.py +68 -384
  50. pex/pep_425.py +11 -2
  51. pex/pep_427.py +937 -205
  52. pex/pep_508.py +4 -5
  53. pex/pex_builder.py +5 -8
  54. pex/pex_info.py +14 -9
  55. pex/pip/dependencies/__init__.py +85 -13
  56. pex/pip/dependencies/requires.py +38 -3
  57. pex/pip/foreign_platform/__init__.py +4 -3
  58. pex/pip/installation.py +2 -2
  59. pex/pip/local_project.py +6 -14
  60. pex/pip/package_repositories/__init__.py +78 -0
  61. pex/pip/package_repositories/link_collector.py +96 -0
  62. pex/pip/tool.py +139 -33
  63. pex/pip/vcs.py +109 -43
  64. pex/pip/version.py +8 -1
  65. pex/requirements.py +121 -16
  66. pex/resolve/config.py +5 -1
  67. pex/resolve/configured_resolve.py +32 -10
  68. pex/resolve/configured_resolver.py +10 -39
  69. pex/resolve/downloads.py +4 -3
  70. pex/resolve/lock_downloader.py +16 -23
  71. pex/resolve/lock_resolver.py +41 -51
  72. pex/resolve/locked_resolve.py +89 -32
  73. pex/resolve/locker.py +145 -101
  74. pex/resolve/locker_patches.py +123 -197
  75. pex/resolve/lockfile/create.py +232 -87
  76. pex/resolve/lockfile/download_manager.py +5 -1
  77. pex/resolve/lockfile/json_codec.py +103 -28
  78. pex/resolve/lockfile/model.py +13 -35
  79. pex/resolve/lockfile/pep_751.py +117 -98
  80. pex/resolve/lockfile/requires_dist.py +17 -262
  81. pex/resolve/lockfile/subset.py +11 -0
  82. pex/resolve/lockfile/targets.py +445 -0
  83. pex/resolve/lockfile/updater.py +22 -10
  84. pex/resolve/package_repository.py +406 -0
  85. pex/resolve/pex_repository_resolver.py +1 -1
  86. pex/resolve/pre_resolved_resolver.py +19 -16
  87. pex/resolve/project.py +233 -47
  88. pex/resolve/requirement_configuration.py +28 -10
  89. pex/resolve/resolver_configuration.py +18 -32
  90. pex/resolve/resolver_options.py +234 -28
  91. pex/resolve/resolvers.py +3 -12
  92. pex/resolve/target_options.py +18 -2
  93. pex/resolve/target_system.py +908 -0
  94. pex/resolve/venv_resolver.py +670 -0
  95. pex/resolver.py +673 -209
  96. pex/scie/__init__.py +40 -1
  97. pex/scie/model.py +2 -0
  98. pex/scie/science.py +25 -3
  99. pex/sdist.py +219 -0
  100. pex/sh_boot.py +24 -21
  101. pex/sysconfig.py +5 -3
  102. pex/targets.py +31 -10
  103. pex/third_party/__init__.py +1 -1
  104. pex/tools/commands/repository.py +48 -25
  105. pex/vendor/__init__.py +4 -9
  106. pex/vendor/__main__.py +65 -41
  107. pex/vendor/_vendored/ansicolors/.layout.json +1 -1
  108. pex/vendor/_vendored/ansicolors/ansicolors-1.1.8.dist-info/RECORD +11 -0
  109. pex/vendor/_vendored/ansicolors/ansicolors-1.1.8.pex-info/original-whl-info.json +1 -0
  110. pex/vendor/_vendored/appdirs/.layout.json +1 -1
  111. pex/vendor/_vendored/appdirs/appdirs-1.4.4.dist-info/RECORD +7 -0
  112. pex/vendor/_vendored/appdirs/appdirs-1.4.4.pex-info/original-whl-info.json +1 -0
  113. pex/vendor/_vendored/attrs/.layout.json +1 -1
  114. pex/vendor/_vendored/attrs/attrs-21.5.0.dev0.dist-info/RECORD +37 -0
  115. pex/vendor/_vendored/attrs/attrs-21.5.0.dev0.pex-info/original-whl-info.json +1 -0
  116. pex/vendor/_vendored/packaging_20_9/.layout.json +1 -1
  117. pex/vendor/_vendored/packaging_20_9/packaging-20.9.dist-info/RECORD +20 -0
  118. pex/vendor/_vendored/packaging_20_9/packaging-20.9.pex-info/original-whl-info.json +1 -0
  119. pex/vendor/_vendored/packaging_20_9/pyparsing-2.4.7.dist-info/RECORD +7 -0
  120. pex/vendor/_vendored/packaging_20_9/pyparsing-2.4.7.pex-info/original-whl-info.json +1 -0
  121. pex/vendor/_vendored/packaging_21_3/.layout.json +1 -1
  122. pex/vendor/_vendored/packaging_21_3/packaging-21.3.dist-info/RECORD +20 -0
  123. pex/vendor/_vendored/packaging_21_3/packaging-21.3.pex-info/original-whl-info.json +1 -0
  124. pex/vendor/_vendored/packaging_21_3/pyparsing-3.0.7.dist-info/RECORD +18 -0
  125. pex/vendor/_vendored/packaging_21_3/pyparsing-3.0.7.pex-info/original-whl-info.json +1 -0
  126. pex/vendor/_vendored/packaging_24_0/.layout.json +1 -1
  127. pex/vendor/_vendored/packaging_24_0/packaging-24.0.dist-info/RECORD +22 -0
  128. pex/vendor/_vendored/packaging_24_0/packaging-24.0.pex-info/original-whl-info.json +1 -0
  129. pex/vendor/_vendored/packaging_25_0/.layout.json +1 -1
  130. pex/vendor/_vendored/packaging_25_0/packaging-25.0.dist-info/RECORD +24 -0
  131. pex/vendor/_vendored/packaging_25_0/packaging-25.0.pex-info/original-whl-info.json +1 -0
  132. pex/vendor/_vendored/pip/.layout.json +1 -1
  133. pex/vendor/_vendored/pip/pip/_vendor/certifi/cacert.pem +63 -1
  134. pex/vendor/_vendored/pip/pip-20.3.4.dist-info/RECORD +388 -0
  135. pex/vendor/_vendored/pip/pip-20.3.4.pex-info/original-whl-info.json +1 -0
  136. pex/vendor/_vendored/setuptools/.layout.json +1 -1
  137. pex/vendor/_vendored/setuptools/setuptools-44.0.0+3acb925dd708430aeaf197ea53ac8a752f7c1863.dist-info/RECORD +107 -0
  138. pex/vendor/_vendored/setuptools/setuptools-44.0.0+3acb925dd708430aeaf197ea53ac8a752f7c1863.pex-info/original-whl-info.json +1 -0
  139. pex/vendor/_vendored/toml/.layout.json +1 -1
  140. pex/vendor/_vendored/toml/toml-0.10.2.dist-info/RECORD +11 -0
  141. pex/vendor/_vendored/toml/toml-0.10.2.pex-info/original-whl-info.json +1 -0
  142. pex/vendor/_vendored/tomli/.layout.json +1 -1
  143. pex/vendor/_vendored/tomli/tomli-2.0.1.dist-info/RECORD +10 -0
  144. pex/vendor/_vendored/tomli/tomli-2.0.1.pex-info/original-whl-info.json +1 -0
  145. pex/venv/installer.py +46 -19
  146. pex/venv/venv_pex.py +6 -3
  147. pex/version.py +1 -1
  148. pex/wheel.py +188 -40
  149. pex/whl.py +67 -0
  150. pex/windows/__init__.py +14 -11
  151. {pex-2.54.2.dist-info → pex-2.69.0.dist-info}/METADATA +6 -5
  152. {pex-2.54.2.dist-info → pex-2.69.0.dist-info}/RECORD +157 -133
  153. {pex-2.54.2.dist-info → pex-2.69.0.dist-info}/entry_points.txt +1 -0
  154. {pex-2.54.2.dist-info → pex-2.69.0.dist-info}/pylock/pylock.toml +1 -1
  155. pex/docs/html/_pagefind/fragment/en_42c9d8c.pf_fragment +0 -0
  156. pex/docs/html/_pagefind/fragment/en_45dd5a2.pf_fragment +0 -0
  157. pex/docs/html/_pagefind/fragment/en_4ca74d2.pf_fragment +0 -0
  158. pex/docs/html/_pagefind/fragment/en_77273d5.pf_fragment +0 -0
  159. pex/docs/html/_pagefind/fragment/en_87a59c5.pf_fragment +0 -0
  160. pex/docs/html/_pagefind/fragment/en_8dc89b5.pf_fragment +0 -0
  161. pex/docs/html/_pagefind/fragment/en_9d1319b.pf_fragment +0 -0
  162. pex/docs/html/_pagefind/fragment/en_e55df9d.pf_fragment +0 -0
  163. pex/docs/html/_pagefind/index/en_1e98c6f.pf_index +0 -0
  164. pex/docs/html/_pagefind/pagefind.en_d1c488ecae.pf_meta +0 -0
  165. pex/vendor/_vendored/ansicolors/ansicolors-1.1.8.dist-info/INSTALLER +0 -1
  166. pex/vendor/_vendored/appdirs/appdirs-1.4.4.dist-info/INSTALLER +0 -1
  167. pex/vendor/_vendored/attrs/attrs-21.5.0.dev0.dist-info/INSTALLER +0 -1
  168. pex/vendor/_vendored/packaging_20_9/packaging-20.9.dist-info/INSTALLER +0 -1
  169. pex/vendor/_vendored/packaging_20_9/pyparsing-2.4.7.dist-info/INSTALLER +0 -1
  170. pex/vendor/_vendored/packaging_21_3/packaging-21.3.dist-info/INSTALLER +0 -1
  171. pex/vendor/_vendored/packaging_21_3/pyparsing-3.0.7.dist-info/INSTALLER +0 -1
  172. pex/vendor/_vendored/packaging_24_0/packaging-24.0.dist-info/INSTALLER +0 -1
  173. pex/vendor/_vendored/packaging_25_0/packaging-25.0.dist-info/INSTALLER +0 -1
  174. pex/vendor/_vendored/pip/pip-20.3.4.dist-info/INSTALLER +0 -1
  175. pex/vendor/_vendored/setuptools/setuptools-44.0.0+3acb925dd708430aeaf197ea53ac8a752f7c1863.dist-info/INSTALLER +0 -1
  176. pex/vendor/_vendored/toml/toml-0.10.2.dist-info/INSTALLER +0 -1
  177. pex/vendor/_vendored/tomli/tomli-2.0.1.dist-info/INSTALLER +0 -1
  178. {pex-2.54.2.dist-info → pex-2.69.0.dist-info}/WHEEL +0 -0
  179. {pex-2.54.2.dist-info → pex-2.69.0.dist-info}/licenses/LICENSE +0 -0
  180. {pex-2.54.2.dist-info → pex-2.69.0.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,107 @@
1
+ easy_install.py,sha256=KmUyF4ULoa4KKPBmNIgrhxSm6THkvc-0olDNVQ97dJs,308
2
+ pkg_resources/__init__.py,sha256=jC9RTTj6Z0a9J4xMMIxispKIDOxbSzG88Z5ehFVRTfw,109721
3
+ pkg_resources/py31compat.py,sha256=-WQ0e4c3RG_acdhwC3gLiXhP_lg4G5q7XYkZkQg0gxU,558
4
+ pkg_resources/_vendor/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
5
+ pkg_resources/_vendor/appdirs.py,sha256=MievUEuv3l_mQISH5SF0shDk_BNhHHzYiAPrT3ITN4I,24701
6
+ pkg_resources/_vendor/pyparsing.py,sha256=tmrp-lu-qO1i75ZzIN5A12nKRRD1Cm4Vpk-5LR9rims,232055
7
+ pkg_resources/_vendor/six.py,sha256=A6hdJZVjI3t_geebZ9BzUvwRrIXo0lfwzQlM2LcKyas,30098
8
+ pkg_resources/_vendor/packaging/__about__.py,sha256=zkcCPTN_6TcLW0Nrlg0176-R1QQ_WVPTm8sz1R4-HjM,720
9
+ pkg_resources/_vendor/packaging/__init__.py,sha256=_vNac5TrzwsrzbOFIbF-5cHqc_Y2aPT2D7zrIR06BOo,513
10
+ pkg_resources/_vendor/packaging/_compat.py,sha256=Vi_A0rAQeHbU-a9X0tt1yQm9RqkgQbDSxzRw8WlU9kA,860
11
+ pkg_resources/_vendor/packaging/_structures.py,sha256=RImECJ4c_wTlaTYYwZYLHEiebDMaAJmK1oPARhw1T5o,1416
12
+ pkg_resources/_vendor/packaging/markers.py,sha256=Hu2KTHSVDw5TouLFIAlTF8VJG6FB7edt82AEv3Y4U5A,8847
13
+ pkg_resources/_vendor/packaging/requirements.py,sha256=kW33jVL1licHp04f2mlX-WvYJerGIIpvwYB_UZ6t5tk,5148
14
+ pkg_resources/_vendor/packaging/specifiers.py,sha256=SAMRerzO3fK2IkFZCaZkuwZaL_EGqHNOz4pni4vhnN0,28025
15
+ pkg_resources/_vendor/packaging/utils.py,sha256=3m6WvPm6NNxE8rkTGmn0r75B_GZSGg7ikafxHsBN1WA,421
16
+ pkg_resources/_vendor/packaging/version.py,sha256=OwGnxYfr2ghNzYx59qWIBkrK3SnB6n-Zfd1XaLpnnM0,11556
17
+ pkg_resources/extern/__init__.py,sha256=cHiEfHuLmm6rs5Ve_ztBfMI7Lr31vss-D4wkqF5xzlI,2498
18
+ setuptools/__init__.py,sha256=Uuh_WcZ0TRLLCFViihlbT9Ua0Lux7z7Bp20LKTEDNYw,8289
19
+ setuptools/_deprecation_warning.py,sha256=jU9-dtfv6cKmtQJOXN8nP1mm7gONw5kKEtiPtbwnZyI,218
20
+ setuptools/_imp.py,sha256=jloslOkxrTKbobgemfP94YII0nhqiJzE1bRmCTZ1a5I,2223
21
+ setuptools/archive_util.py,sha256=XexyqeTFmMuHRY_xuQabc4Q6Wi6pO0lEJDg9vpQTYUk,6756
22
+ setuptools/build_meta.py,sha256=dfrceySHiu4U0aED-WU0NKP4ghCW7P7AVRpH_sBM5u4,10257
23
+ setuptools/cli-32.exe,sha256=dfEuovMNnA2HLa3jRfMPVi5tk4R7alCbpTvuxtCyw0Y,65536
24
+ setuptools/cli-64.exe,sha256=KLABu5pyrnokJCv6skjXZ6GsXeyYHGcqOUT3oHI3Xpo,74752
25
+ setuptools/cli.exe,sha256=dfEuovMNnA2HLa3jRfMPVi5tk4R7alCbpTvuxtCyw0Y,65536
26
+ setuptools/config.py,sha256=zRnI8kZPk18-1QgPyzab9Rwi7CtuBZMwQqLn5jltfqU,21727
27
+ setuptools/dep_util.py,sha256=fgixvC1R7sH3r13ktyf7N0FALoqEXL1cBarmNpSEoWg,935
28
+ setuptools/depends.py,sha256=qt2RWllArRvhnm8lxsyRpcthEZYp4GHQgREl1q0LkFw,5517
29
+ setuptools/dist.py,sha256=YcPMXMT6H4w1Z1R7JcsycT2mXTvgkhh5FCPNUWYjY_I,52087
30
+ setuptools/errors.py,sha256=MVOcv381HNSajDgEUWzOQ4J6B5BHCBMSjHfaWcEwA1o,524
31
+ setuptools/extension.py,sha256=0WXnVGwooazqD2LEs78uPNGzVWMIzaUatnRqmkRng2U,1894
32
+ setuptools/glob.py,sha256=o75cHrOxYsvn854thSxE0x9k8JrKDuhP_rRXlVB00Q4,5084
33
+ setuptools/gui-32.exe,sha256=XBr0bHMA6Hpz2s9s9Bzjl-PwXfa9nH4ie0rFn4V2kWA,65536
34
+ setuptools/gui-64.exe,sha256=aYKMhX1IJLn4ULHgWX0sE0yREUt6B3TEHf_jOw6yNyE,75264
35
+ setuptools/gui.exe,sha256=XBr0bHMA6Hpz2s9s9Bzjl-PwXfa9nH4ie0rFn4V2kWA,65536
36
+ setuptools/installer.py,sha256=1xI9rP5aEgdx1OaUZHvQj0zb6hc83AKgXTC85GPMxm0,5985
37
+ setuptools/launch.py,sha256=sd7ejwhBocCDx_wG9rIs0OaZ8HtmmFU8ZC6IR_S0Lvg,787
38
+ setuptools/lib2to3_ex.py,sha256=Io05v90REA2PxHwOHlPS9eJro51OFUWNXHEHcN5y3Jc,2166
39
+ setuptools/monkey.py,sha256=2QsnbSxUqVdzzAwGZ43Kp5-2Gb9wovE2-DLK_kNalM0,5572
40
+ setuptools/msvc.py,sha256=cMTBhLLMH0HW6nZgm3hwqoc5KpQJnajxuJ61KpYcDB4,47287
41
+ setuptools/namespaces.py,sha256=2noPXS--lCOyu502TtSo82IQfDO6Ay52ZyVxlUUrDZg,3364
42
+ setuptools/package_index.py,sha256=er2zuCiMV-rdJ2JkKTmGEByllSnhyK85nWZ86YFN8ew,42324
43
+ setuptools/py27compat.py,sha256=GNzhD1cFG0gPge9jtHyS7l8LJfQyi5MnfBLKPWPB71k,1651
44
+ setuptools/py31compat.py,sha256=h2rtZghOfwoGYd8sQ0-auaKiF3TcL3qX0bX3VessqcE,838
45
+ setuptools/py33compat.py,sha256=8Y5fKcoonFLZ2cE4xRVjA8txoBk40PLnWxH5OPVHqJs,1658
46
+ setuptools/py34compat.py,sha256=KYOd6ybRxjBW8NJmYD8t_UyyVmysppFXqHpFLdslGXU,245
47
+ setuptools/sandbox.py,sha256=gMAXGebq6f-0Iz2PbY8h0WSuXTQg5HZZ1LF870CMv7s,15606
48
+ setuptools/script (dev).tmpl,sha256=RUzQzCQUaXtwdLtYHWYbIQmOaES5Brqq1FvUA_tu-5I,218
49
+ setuptools/script.tmpl,sha256=WGTt5piezO27c-Dbx6l5Q4T3Ff20A5z7872hv3aAhYY,138
50
+ setuptools/site-patch.py,sha256=OumkIHMuoSenRSW1382kKWI1VAwxNE86E5W8iDd34FY,2302
51
+ setuptools/ssl_support.py,sha256=FruiFl4qaRtN7MLcCbjvmvk9g6-q1F3IunTulwbbrYc,8867
52
+ setuptools/unicode_utils.py,sha256=43e8tF6LD0F7Pfs1RNtFEJ0VKYYiLpMi45C3MLNGPhI,1151
53
+ setuptools/version.py,sha256=VdCoXTpi0KtLcobgKjQ7oPgwHaLWbnQRyKo4Phc5tl4,303
54
+ setuptools/wheel.py,sha256=Kx7MtrWi7Muo3ZekSn6_l9fDxsxFvjSHdUS17RFZ9Rk,9627
55
+ setuptools/windows_support.py,sha256=5GrfqSP2-dLGJoZTq2g6dCKkyQxxa2n5IQiXlJCoYEE,714
56
+ setuptools/_vendor/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
57
+ setuptools/_vendor/ordered_set.py,sha256=dbaCcs27dyN9gnMWGF5nA_BrVn6Q-NrjKYJpV9_fgBs,15130
58
+ setuptools/_vendor/pyparsing.py,sha256=tmrp-lu-qO1i75ZzIN5A12nKRRD1Cm4Vpk-5LR9rims,232055
59
+ setuptools/_vendor/six.py,sha256=A6hdJZVjI3t_geebZ9BzUvwRrIXo0lfwzQlM2LcKyas,30098
60
+ setuptools/_vendor/packaging/__about__.py,sha256=CpuMSyh1V7adw8QMjWKkY3LtdqRUkRX4MgJ6nF4stM0,744
61
+ setuptools/_vendor/packaging/__init__.py,sha256=6enbp5XgRfjBjsI9-bn00HjHf5TH21PDMOKkJW8xw-w,562
62
+ setuptools/_vendor/packaging/_compat.py,sha256=Ugdm-qcneSchW25JrtMIKgUxfEEBcCAz6WrEeXeqz9o,865
63
+ setuptools/_vendor/packaging/_structures.py,sha256=pVd90XcXRGwpZRB_qdFuVEibhCHpX_bL5zYr9-N0mc8,1416
64
+ setuptools/_vendor/packaging/markers.py,sha256=dcGCz4lgFcrJ2gdAD9O9nxMu4bbpaPM7sDEyAbMjQHA,8858
65
+ setuptools/_vendor/packaging/requirements.py,sha256=3VNhQZIQJ5gp5yX2s5HQ5QIlnBxFLWhS1vjDTMtHdcA,5523
66
+ setuptools/_vendor/packaging/specifiers.py,sha256=0ZzQpcUnvrQ6LjR-mQRLzMr8G6hdRv-mY0VSf_amFtI,27778
67
+ setuptools/_vendor/packaging/tags.py,sha256=EPLXhO6GTD7_oiWEO1U0l0PkfR8R_xivpMDHXnsTlts,12933
68
+ setuptools/_vendor/packaging/utils.py,sha256=VaTC0Ei7zO2xl9ARiWmz2YFLFt89PuuhLbAlXMyAGms,1520
69
+ setuptools/_vendor/packaging/version.py,sha256=Npdwnb8OHedj_2L86yiUqscujb7w_i5gmSK1PhOAFzg,11978
70
+ setuptools/command/__init__.py,sha256=AKflHeDUOP4is4ei1qbHofQKcwRcSyfINONhZ033D48,736
71
+ setuptools/command/alias.py,sha256=pz07W_jSsI7IS_aL-jtTQ3L6RjCSP4CMuhGO9JpNL2E,2788
72
+ setuptools/command/bdist_egg.py,sha256=mfNDhWYfXk5LcNHJBuyMoNsEiWP9qs7NZDGZNZ_LN7o,19010
73
+ setuptools/command/bdist_rpm.py,sha256=B7l0TnzCGb-0nLlm6rS00jWLkojASwVmdhW2w5Qz_Ak,1508
74
+ setuptools/command/bdist_wininst.py,sha256=_6dz3lpB1tY200LxKPLM7qgwTCceOMgaWFF-jW2-pm0,637
75
+ setuptools/command/build_clib.py,sha256=c8E-1vI7D_Mj_d8vMTZZ_ELNiyL96z3Io62xnRjH5ws,4658
76
+ setuptools/command/build_ext.py,sha256=e0tiGPVj2uGY-7mcitC3wJy95fxlDcuXJu6NGJkvwMQ,13336
77
+ setuptools/command/build_py.py,sha256=GSt0nPHc49dAdYbvWOEqagd5WsIGd5KbynzppGiheu0,10114
78
+ setuptools/command/develop.py,sha256=xz2QxiSZpNreRBl83_7oJErT96Wf4TuKGQrPZbW2U6Y,8984
79
+ setuptools/command/dist_info.py,sha256=5t6kOfrdgALT-P3ogss6PF9k-Leyesueycuk3dUyZnI,960
80
+ setuptools/command/easy_install.py,sha256=EnGUyalpoTuvnGu9m-3ow5rwQzaCcjrKTEug_6JUsZs,90509
81
+ setuptools/command/egg_info.py,sha256=bwlBZr098bERbOyuoJ-Z3YK9b_Eo53NVTBlqHy7w1qY,27642
82
+ setuptools/command/install.py,sha256=9liesUQ1k4BEQSEhLqLENxvUo9rMEOu49TKy6qVpt98,4858
83
+ setuptools/command/install_egg_info.py,sha256=N8jEtbO-sbVgocH_UaxpXJr8hQHLJzlA6Wzket9K-xk,2841
84
+ setuptools/command/install_lib.py,sha256=6MtjU2yWIz_s9Nf0C2i_W5SzNzp-Osi1EC5_TvOrt3s,4060
85
+ setuptools/command/install_scripts.py,sha256=hQoU7y-avHBmMWIf7aItNwtOuD8BXpzNgYR7kwBNG_I,3183
86
+ setuptools/command/launcher manifest.xml,sha256=xlLbjWrB01tKC0-hlVkOKkiSPbzMml2eOPtJ_ucCnbE,628
87
+ setuptools/command/py36compat.py,sha256=qT-JswbG5zAwE2J8MjBLLul0dhPw3N0nJlX86Ohk7QE,5154
88
+ setuptools/command/register.py,sha256=gVnecx-SrrwluacsjTVBZdw4TMe3zG2NhlRr-O9p2ls,639
89
+ setuptools/command/rotate.py,sha256=mmrpsrTocbiWVSHqtR1cYkfL3vHwzoApCMeUPv60Wkg,2471
90
+ setuptools/command/saveopts.py,sha256=205RP_EjM2azFiW85SaZbVWMOnbdym4SmJxiY0symC4,842
91
+ setuptools/command/sdist.py,sha256=AV18vNYnPx789DEdrmZIgfO8hJp8b-WjamAsBOrvVi8,8415
92
+ setuptools/command/setopt.py,sha256=viOJ884FpXaVyV2ObW-7zm477elxO4yGG7Va7HHeDBk,5411
93
+ setuptools/command/test.py,sha256=KTtsCAupub1RUGbNgfIqOybLpgpPFJY3Ntle3TJpEpM,10432
94
+ setuptools/command/upload.py,sha256=ltCvw8pEG6uTsOVvm0JeJAuW3AsVlFFxnpYvbu2VK9A,633
95
+ setuptools/command/upload_docs.py,sha256=Zb1pqfPBqDrDDWXCmgBXe0Su8Ad4ucZhbIytJnTQpY4,7812
96
+ setuptools/extern/__init__.py,sha256=4q9gtShB1XFP6CisltsyPqtcfTO6ZM9Lu1QBl3l-qmo,2514
97
+ setuptools-44.0.0+3acb925dd708430aeaf197ea53ac8a752f7c1863.dist-info/LICENSE,sha256=wyo6w5WvYyHv0ovnPQagDw22q4h9HCHU_sRhKNIFbVo,1078
98
+ setuptools-44.0.0+3acb925dd708430aeaf197ea53ac8a752f7c1863.dist-info/METADATA,sha256=bCBVNmPt47gDwba_WAZOXBBpg-tCVPKptY8uN8GEljU,3745
99
+ setuptools-44.0.0+3acb925dd708430aeaf197ea53ac8a752f7c1863.dist-info/WHEEL,sha256=ADKeyaGyKF5DwBNE0sRE5pvW-bSkFMJfBuhzZ3rceP4,110
100
+ setuptools-44.0.0+3acb925dd708430aeaf197ea53ac8a752f7c1863.dist-info/dependency_links.txt,sha256=HlkCFkoK5TbZ5EMLbLKYhLcY_E31kBWD8TqW2EgmatQ,239
101
+ setuptools-44.0.0+3acb925dd708430aeaf197ea53ac8a752f7c1863.dist-info/entry_points.txt,sha256=W9P2rmG1eAT0rV3ZZUgfE9wjmBgZ8ZAMAMxTB5ustPA,3206
102
+ setuptools-44.0.0+3acb925dd708430aeaf197ea53ac8a752f7c1863.dist-info/top_level.txt,sha256=2HUXVVwA4Pff1xgTFr3GsTXXKaPaO6vlG6oNJ_4u4Tg,38
103
+ setuptools-44.0.0+3acb925dd708430aeaf197ea53ac8a752f7c1863.dist-info/zip-safe,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
104
+ setuptools-44.0.0+3acb925dd708430aeaf197ea53ac8a752f7c1863.dist-info/RECORD,,
105
+ .prefix/bin/easy_install,sha256=4mDn0ktXXNhpTn4bmLk-6hWTwdNNGKcVL3-STaSD7wo,470
106
+ .prefix/bin/easy_install-3.9,sha256=4mDn0ktXXNhpTn4bmLk-6hWTwdNNGKcVL3-STaSD7wo,470
107
+ setuptools-44.0.0+3acb925dd708430aeaf197ea53ac8a752f7c1863.pex-info/original-whl-info.json,sha256=cjYUbQtgEMJQC9n_4TXC9xXCU2dW82EFb7w2JvZ2LtA,7000
@@ -0,0 +1 @@
1
+ {"entries":[["easy_install.py",[1980,1,1,0,0,0],2175008768],["pkg_resources/__init__.py",[1980,1,1,0,0,0],2175008768],["pkg_resources/py31compat.py",[1980,1,1,0,0,0],2175008768],["pkg_resources/_vendor/__init__.py",[1980,1,1,0,0,0],2175008768],["pkg_resources/_vendor/appdirs.py",[1980,1,1,0,0,0],2175008768],["pkg_resources/_vendor/pyparsing.py",[1980,1,1,0,0,0],2175008768],["pkg_resources/_vendor/six.py",[1980,1,1,0,0,0],2175008768],["pkg_resources/_vendor/packaging/__about__.py",[1980,1,1,0,0,0],2175008768],["pkg_resources/_vendor/packaging/__init__.py",[1980,1,1,0,0,0],2175008768],["pkg_resources/_vendor/packaging/_compat.py",[1980,1,1,0,0,0],2175008768],["pkg_resources/_vendor/packaging/_structures.py",[1980,1,1,0,0,0],2175008768],["pkg_resources/_vendor/packaging/markers.py",[1980,1,1,0,0,0],2175008768],["pkg_resources/_vendor/packaging/requirements.py",[1980,1,1,0,0,0],2175008768],["pkg_resources/_vendor/packaging/specifiers.py",[1980,1,1,0,0,0],2175008768],["pkg_resources/_vendor/packaging/utils.py",[1980,1,1,0,0,0],2175008768],["pkg_resources/_vendor/packaging/version.py",[1980,1,1,0,0,0],2175008768],["pkg_resources/extern/__init__.py",[1980,1,1,0,0,0],2175008768],["setuptools/__init__.py",[1980,1,1,0,0,0],2175008768],["setuptools/_deprecation_warning.py",[1980,1,1,0,0,0],2175008768],["setuptools/_imp.py",[1980,1,1,0,0,0],2175008768],["setuptools/archive_util.py",[1980,1,1,0,0,0],2175008768],["setuptools/build_meta.py",[1980,1,1,0,0,0],2175008768],["setuptools/cli-32.exe",[1980,1,1,0,0,0],2175008768],["setuptools/cli-64.exe",[1980,1,1,0,0,0],2175008768],["setuptools/cli.exe",[1980,1,1,0,0,0],2175008768],["setuptools/config.py",[1980,1,1,0,0,0],2175008768],["setuptools/dep_util.py",[1980,1,1,0,0,0],2175008768],["setuptools/depends.py",[1980,1,1,0,0,0],2175008768],["setuptools/dist.py",[1980,1,1,0,0,0],2175008768],["setuptools/errors.py",[1980,1,1,0,0,0],2175008768],["setuptools/extension.py",[1980,1,1,0,0,0],2175008768],["setuptools/glob.py",[1980,1,1,0,0,0],2175008768],["setuptools/gui-32.exe",[1980,1,1,0,0,0],2175008768],["setuptools/gui-64.exe",[1980,1,1,0,0,0],2175008768],["setuptools/gui.exe",[1980,1,1,0,0,0],2175008768],["setuptools/installer.py",[1980,1,1,0,0,0],2175008768],["setuptools/launch.py",[1980,1,1,0,0,0],2175008768],["setuptools/lib2to3_ex.py",[1980,1,1,0,0,0],2175008768],["setuptools/monkey.py",[1980,1,1,0,0,0],2175008768],["setuptools/msvc.py",[1980,1,1,0,0,0],2175008768],["setuptools/namespaces.py",[1980,1,1,0,0,0],2175008768],["setuptools/package_index.py",[1980,1,1,0,0,0],2175008768],["setuptools/py27compat.py",[1980,1,1,0,0,0],2175008768],["setuptools/py31compat.py",[1980,1,1,0,0,0],2175008768],["setuptools/py33compat.py",[1980,1,1,0,0,0],2175008768],["setuptools/py34compat.py",[1980,1,1,0,0,0],2175008768],["setuptools/sandbox.py",[1980,1,1,0,0,0],2175008768],["setuptools/script (dev).tmpl",[1980,1,1,0,0,0],2175008768],["setuptools/script.tmpl",[1980,1,1,0,0,0],2175008768],["setuptools/site-patch.py",[1980,1,1,0,0,0],2175008768],["setuptools/ssl_support.py",[1980,1,1,0,0,0],2175008768],["setuptools/unicode_utils.py",[1980,1,1,0,0,0],2175008768],["setuptools/version.py",[1980,1,1,0,0,0],2175008768],["setuptools/wheel.py",[1980,1,1,0,0,0],2175008768],["setuptools/windows_support.py",[1980,1,1,0,0,0],2175008768],["setuptools/_vendor/__init__.py",[1980,1,1,0,0,0],2175008768],["setuptools/_vendor/ordered_set.py",[1980,1,1,0,0,0],2175008768],["setuptools/_vendor/pyparsing.py",[1980,1,1,0,0,0],2175008768],["setuptools/_vendor/six.py",[1980,1,1,0,0,0],2175008768],["setuptools/_vendor/packaging/__about__.py",[1980,1,1,0,0,0],2175008768],["setuptools/_vendor/packaging/__init__.py",[1980,1,1,0,0,0],2175008768],["setuptools/_vendor/packaging/_compat.py",[1980,1,1,0,0,0],2175008768],["setuptools/_vendor/packaging/_structures.py",[1980,1,1,0,0,0],2175008768],["setuptools/_vendor/packaging/markers.py",[1980,1,1,0,0,0],2175008768],["setuptools/_vendor/packaging/requirements.py",[1980,1,1,0,0,0],2175008768],["setuptools/_vendor/packaging/specifiers.py",[1980,1,1,0,0,0],2175008768],["setuptools/_vendor/packaging/tags.py",[1980,1,1,0,0,0],2175008768],["setuptools/_vendor/packaging/utils.py",[1980,1,1,0,0,0],2175008768],["setuptools/_vendor/packaging/version.py",[1980,1,1,0,0,0],2175008768],["setuptools/command/__init__.py",[1980,1,1,0,0,0],2175008768],["setuptools/command/alias.py",[1980,1,1,0,0,0],2175008768],["setuptools/command/bdist_egg.py",[1980,1,1,0,0,0],2175008768],["setuptools/command/bdist_rpm.py",[1980,1,1,0,0,0],2175008768],["setuptools/command/bdist_wininst.py",[1980,1,1,0,0,0],2175008768],["setuptools/command/build_clib.py",[1980,1,1,0,0,0],2175008768],["setuptools/command/build_ext.py",[1980,1,1,0,0,0],2175008768],["setuptools/command/build_py.py",[1980,1,1,0,0,0],2175008768],["setuptools/command/develop.py",[1980,1,1,0,0,0],2175008768],["setuptools/command/dist_info.py",[1980,1,1,0,0,0],2175008768],["setuptools/command/easy_install.py",[1980,1,1,0,0,0],2175008768],["setuptools/command/egg_info.py",[1980,1,1,0,0,0],2175008768],["setuptools/command/install.py",[1980,1,1,0,0,0],2175008768],["setuptools/command/install_egg_info.py",[1980,1,1,0,0,0],2175008768],["setuptools/command/install_lib.py",[1980,1,1,0,0,0],2175008768],["setuptools/command/install_scripts.py",[1980,1,1,0,0,0],2175008768],["setuptools/command/launcher manifest.xml",[1980,1,1,0,0,0],2175008768],["setuptools/command/py36compat.py",[1980,1,1,0,0,0],2175008768],["setuptools/command/register.py",[1980,1,1,0,0,0],2175008768],["setuptools/command/rotate.py",[1980,1,1,0,0,0],2175008768],["setuptools/command/saveopts.py",[1980,1,1,0,0,0],2175008768],["setuptools/command/sdist.py",[1980,1,1,0,0,0],2175008768],["setuptools/command/setopt.py",[1980,1,1,0,0,0],2175008768],["setuptools/command/test.py",[1980,1,1,0,0,0],2175008768],["setuptools/command/upload.py",[1980,1,1,0,0,0],2175008768],["setuptools/command/upload_docs.py",[1980,1,1,0,0,0],2175008768],["setuptools/extern/__init__.py",[1980,1,1,0,0,0],2175008768],["setuptools-44.0.0+3acb925dd708430aeaf197ea53ac8a752f7c1863.dist-info/LICENSE",[1980,1,1,0,0,0],2175008768],["setuptools-44.0.0+3acb925dd708430aeaf197ea53ac8a752f7c1863.dist-info/METADATA",[1980,1,1,0,0,0],2175008768],["setuptools-44.0.0+3acb925dd708430aeaf197ea53ac8a752f7c1863.dist-info/WHEEL",[1980,1,1,0,0,0],2175008768],["setuptools-44.0.0+3acb925dd708430aeaf197ea53ac8a752f7c1863.dist-info/dependency_links.txt",[1980,1,1,0,0,0],2175008768],["setuptools-44.0.0+3acb925dd708430aeaf197ea53ac8a752f7c1863.dist-info/entry_points.txt",[1980,1,1,0,0,0],2175008768],["setuptools-44.0.0+3acb925dd708430aeaf197ea53ac8a752f7c1863.dist-info/top_level.txt",[1980,1,1,0,0,0],2175008768],["setuptools-44.0.0+3acb925dd708430aeaf197ea53ac8a752f7c1863.dist-info/zip-safe",[1980,1,1,0,0,0],2175008768],["setuptools-44.0.0+3acb925dd708430aeaf197ea53ac8a752f7c1863.dist-info/RECORD",[1980,1,1,0,0,0],28573696]],"filename":"setuptools-44.0.0+3acb925dd708430aeaf197ea53ac8a752f7c1863-py2.py3-none-any.whl"}
@@ -1 +1 @@
1
- {"fingerprint": "3fd281547bbc087c77a8de1a2ccdd19711d62164aa3edef5a801f8092650db08", "record_relpath": "toml-0.10.2.dist-info/RECORD", "root_is_purelib": true, "stash_dir": ".prefix"}
1
+ {"fingerprint":"e022215e30b009ca1018a9255f6812d150469e3f6ff12687dd93459dd5a5274d","record_relpath":"toml-0.10.2.dist-info/RECORD","root_is_purelib":true,"stash_dir":".prefix","sys_path_entries":["."]}
@@ -0,0 +1,11 @@
1
+ toml/__init__.py,sha256=OAi77F_oThE00nGyd1z7JgtG_PKq6XKQxLfThnETzcU,1003
2
+ toml/decoder.py,sha256=NT-RGTEh0vBksVd2WaYorMu5-K350_ymWiDggVUXefM,39084
3
+ toml/encoder.py,sha256=KWnqyK3VROUobm8d3dOKckXMEh4d_yOQGPWvPNCj5xI,10273
4
+ toml/ordered.py,sha256=-0iAss5NfnsyIjhzsyjtztFiCgVINlW7dGXmgdBcLvA,642
5
+ toml/tz.py,sha256=-5vg8wkg_atnVi2TnEveexIVE7T_FxBVr_-2WVfO1oA,701
6
+ toml-0.10.2.dist-info/LICENSE,sha256=LZKUgj32yJNXyL5JJ_znk2HWVh5e51MtWSbmOTmqpTY,1252
7
+ toml-0.10.2.dist-info/METADATA,sha256=n_YkspvEihd_QXLIZZ50WVSFz3rZ_k7jQP-OU1WUpWY,7142
8
+ toml-0.10.2.dist-info/WHEEL,sha256=ADKeyaGyKF5DwBNE0sRE5pvW-bSkFMJfBuhzZ3rceP4,110
9
+ toml-0.10.2.dist-info/top_level.txt,sha256=2BO8ZRNnvJWgXyiQv66LBb_v87qBzcoUtEBefA75Ouk,5
10
+ toml-0.10.2.dist-info/RECORD,,
11
+ toml-0.10.2.pex-info/original-whl-info.json,sha256=63hjg_RvL2dX1x8O7tNS3P_oW9o1e5CHUfZ0MIyKehM,636
@@ -0,0 +1 @@
1
+ {"entries":[["toml/__init__.py",[2020,11,1,1,37,2],2175008768],["toml/decoder.py",[2020,10,31,3,20,8],2175008768],["toml/encoder.py",[2020,10,31,3,20,8],2175008768],["toml/ordered.py",[2018,4,1,16,33,32],2175008768],["toml/tz.py",[2020,10,31,3,20,8],2175008768],["toml-0.10.2.dist-info/LICENSE",[2020,11,1,1,37,14],2175008768],["toml-0.10.2.dist-info/METADATA",[2020,11,1,1,37,14],2175008768],["toml-0.10.2.dist-info/WHEEL",[2020,11,1,1,37,14],2175008768],["toml-0.10.2.dist-info/top_level.txt",[2020,11,1,1,37,14],2175008768],["toml-0.10.2.dist-info/RECORD",[2020,11,1,1,37,14],28573696]],"filename":"toml-0.10.2-py2.py3-none-any.whl"}
@@ -1 +1 @@
1
- {"fingerprint": "0454d05ff5986998a7ace56edd25253452f464fd365f7ab4295edba84b58162f", "record_relpath": "tomli-2.0.1.dist-info/RECORD", "root_is_purelib": true, "stash_dir": ".prefix"}
1
+ {"fingerprint":"bbe9219bfe424168417563a7c481eeed73fbb39ef7458e0e8ba636276afb2822","record_relpath":"tomli-2.0.1.dist-info/RECORD","root_is_purelib":true,"stash_dir":".prefix","sys_path_entries":["."]}
@@ -0,0 +1,10 @@
1
+ tomli/__init__.py,sha256=JhUwV66DB1g4Hvt1UQCVMdfCu-IgAV8FXmvDU9onxd4,396
2
+ tomli/_parser.py,sha256=g9-ENaALS-B8dokYpCuzUFalWlog7T-SIYMjLZSWrtM,22633
3
+ tomli/_re.py,sha256=dbjg5ChZT23Ka9z9DHOXfdtSpPwUfdgMXnj8NOoly-w,2943
4
+ tomli/_types.py,sha256=-GTG2VUqkpxwMqzmVO4F7ybKddIbAnuAHXfmWQcTi3Q,254
5
+ tomli/py.typed,sha256=8PjyZ1aVoQpRVvt71muvuq5qE-jTFZkK-GLHkhdebmc,26
6
+ tomli-2.0.1.dist-info/LICENSE,sha256=uAgWsNUwuKzLTCIReDeQmEpuO2GSLCte6S8zcqsnQv4,1072
7
+ tomli-2.0.1.dist-info/WHEEL,sha256=jPMR_Dzkc4X4icQtmz81lnNY_kAsfog7ry7qoRvYLXw,81
8
+ tomli-2.0.1.dist-info/METADATA,sha256=zPDceKmPwJGLWtZykrHixL7WVXWmJGzZ1jyRT5lCoPI,8875
9
+ tomli-2.0.1.dist-info/RECORD,,
10
+ tomli-2.0.1.pex-info/original-whl-info.json,sha256=_Iy0aZfe20sZ7ZM6ou1a246HfctfLCZeq4YrNIc7k_I,552
@@ -0,0 +1 @@
1
+ {"entries":[["tomli/__init__.py",[2022,2,8,10,53,42],2175008768],["tomli/_parser.py",[2022,2,8,10,53,42],2175008768],["tomli/_re.py",[2022,2,8,10,53,42],2175008768],["tomli/_types.py",[2022,2,8,10,53,42],2175008768],["tomli/py.typed",[2022,2,8,10,53,42],2175008768],["tomli-2.0.1.dist-info/LICENSE",[2022,2,8,10,53,42],2175008768],["tomli-2.0.1.dist-info/WHEEL",[2016,1,1,0,0,0],27525120],["tomli-2.0.1.dist-info/METADATA",[2016,1,1,0,0,0],27525120],["tomli-2.0.1.dist-info/RECORD",[2016,1,1,0,0,0],27525120]],"filename":"tomli-2.0.1-py3-none-any.whl"}
pex/venv/installer.py CHANGED
@@ -17,12 +17,14 @@ from pex.dist_metadata import Distribution
17
17
  from pex.environment import PEXEnvironment
18
18
  from pex.executables import chmod_plus_x
19
19
  from pex.fs import safe_symlink
20
+ from pex.installed_wheel import InstalledWheel
20
21
  from pex.orderedset import OrderedSet
21
22
  from pex.os import WINDOWS
22
- from pex.pep_376 import InstalledWheel
23
+ from pex.pep_427 import reinstall_flat, reinstall_venv
23
24
  from pex.pep_440 import Version
24
25
  from pex.pep_503 import ProjectName
25
26
  from pex.pex import PEX
27
+ from pex.pex_info import PexInfo
26
28
  from pex.result import Error
27
29
  from pex.sysconfig import SCRIPT_DIR
28
30
  from pex.tracer import TRACER
@@ -43,6 +45,7 @@ if TYPE_CHECKING:
43
45
  Iterator,
44
46
  List,
45
47
  Optional,
48
+ Sequence,
46
49
  Text,
47
50
  Tuple,
48
51
  Union,
@@ -268,8 +271,8 @@ def _populate_flat_deps(
268
271
  for dist in distributions:
269
272
  try:
270
273
  installed_wheel = InstalledWheel.load(dist.location)
271
- for src, dst in installed_wheel.reinstall_flat(
272
- target_dir=dest_dir, copy_mode=copy_mode
274
+ for src, dst in reinstall_flat(
275
+ installed_wheel=installed_wheel, target_dir=dest_dir, copy_mode=copy_mode
273
276
  ):
274
277
  yield src, dst
275
278
  except InstalledWheel.LoadError:
@@ -482,8 +485,11 @@ def _populate_venv_deps(
482
485
 
483
486
  try:
484
487
  installed_wheel = InstalledWheel.load(dist.location)
485
- for src, dst in installed_wheel.reinstall_venv(
486
- venv, copy_mode=copy_mode, rel_extra_path=rel_extra_path
488
+ for src, dst in reinstall_venv(
489
+ installed_wheel=installed_wheel,
490
+ venv=venv,
491
+ copy_mode=copy_mode,
492
+ rel_extra_path=rel_extra_path,
487
493
  ):
488
494
  yield src, dst
489
495
  except InstalledWheel.LoadError:
@@ -570,24 +576,16 @@ def _populate_sources(
570
576
  yield src, dest
571
577
 
572
578
 
573
- def _populate_first_party(
579
+ def install_pex_main(
574
580
  target_dir, # type: str
575
581
  venv, # type: Virtualenv
576
- pex, # type: PEX
582
+ pex_info, # type: PexInfo
583
+ activated_dists, # type: Sequence[Distribution]
577
584
  shebang, # type: str
578
585
  venv_python, # type: str
579
586
  bin_path, # type: BinPath.Value
580
587
  ):
581
- # type: (...) -> Iterator[Tuple[Text, Text]]
582
-
583
- # We want the venv at rest to reflect the PEX it was created from at rest; as such we use the
584
- # PEX's at-rest PEX-INFO to perform the layout. The venv can then be executed with various PEX
585
- # environment variables in-play that it respects (e.g.: PEX_EXTRA_SYS_PATH, PEX_INTERPRETER,
586
- # PEX_MODULE, etc.).
587
- pex_info = pex.pex_info(include_env_overrides=False)
588
-
589
- for src, dst in _populate_sources(pex=pex, dst=venv.site_packages_dir):
590
- yield src, dst
588
+ # type: (...) -> None
591
589
 
592
590
  with open(os.path.join(venv.site_packages_dir, "PEX_EXTRA_SYS_PATH.pth"), "w") as fp:
593
591
  # N.B.: .pth import lines must be single lines: https://docs.python.org/3/library/site.html
@@ -603,7 +601,7 @@ def _populate_first_party(
603
601
  with open(os.path.join(venv.venv_dir, pex_info.PATH), "w") as fp:
604
602
  fp.write(pex_info.dump())
605
603
 
606
- # 2. Add a __main__ to the root of the venv for running the venv dir like a loose PEX dir
604
+ # Add a __main__ to the root of the venv for running the venv dir like a loose PEX dir
607
605
  # and a main.py for running as a script.
608
606
  with open(venv.join_path("__main__.py"), "w") as fp:
609
607
  fp.write(
@@ -656,9 +654,38 @@ def _populate_first_party(
656
654
  repl.create_pex_repl_exe(
657
655
  shebang=shebang,
658
656
  pex_info=pex_info,
659
- activated_dists=tuple(pex.resolve()),
657
+ activated_dists=activated_dists,
660
658
  pex=os.path.join(target_dir, "pex"),
661
659
  venv=True,
662
660
  )
663
661
  )
664
662
  chmod_plus_x(fp.name)
663
+
664
+
665
+ def _populate_first_party(
666
+ target_dir, # type: str
667
+ venv, # type: Virtualenv
668
+ pex, # type: PEX
669
+ shebang, # type: str
670
+ venv_python, # type: str
671
+ bin_path, # type: BinPath.Value
672
+ ):
673
+ # type: (...) -> Iterator[Tuple[Text, Text]]
674
+
675
+ for src, dst in _populate_sources(pex=pex, dst=venv.site_packages_dir):
676
+ yield src, dst
677
+
678
+ # We want the venv at rest to reflect the PEX it was created from at rest; as such we use the
679
+ # PEX's at-rest PEX-INFO to perform the layout. The venv can then be executed with various PEX
680
+ # environment variables in-play that it respects (e.g.: PEX_EXTRA_SYS_PATH, PEX_INTERPRETER,
681
+ # PEX_MODULE, etc.).
682
+ pex_info = pex.pex_info(include_env_overrides=False)
683
+ install_pex_main(
684
+ target_dir=target_dir,
685
+ venv=venv,
686
+ pex_info=pex_info,
687
+ activated_dists=tuple(pex.resolve()),
688
+ shebang=shebang,
689
+ venv_python=venv_python,
690
+ bin_path=bin_path,
691
+ )
pex/venv/venv_pex.py CHANGED
@@ -179,15 +179,18 @@ def boot(
179
179
  "_PEX_USE_PIP_CONFIG",
180
180
  # This is used by Pex's Pip to inject runtime patches dynamically.
181
181
  "_PEX_PIP_RUNTIME_PATCHES_PACKAGE",
182
- # These are used by Pex's Pip venv to provide foreign platform support and work
183
- # around https://github.com/pypa/pip/issues/10050.
182
+ # These are used by Pex's Pip venv to provide foreign platform support, universal lock
183
+ # support and work around https://github.com/pypa/pip/issues/10050.
184
+ "_PEX_INTERPRETER_IMPLEMENTATION",
184
185
  "_PEX_PATCHED_MARKERS_FILE",
185
186
  "_PEX_PATCHED_TAGS_FILE",
186
187
  # These are used by Pex's Pip venv to implement universal locks.
187
188
  "_PEX_PYTHON_VERSIONS_FILE",
188
- "_PEX_TARGET_SYSTEMS_FILE",
189
+ "_PEX_UNIVERSAL_TARGET_FILE",
189
190
  # This is used to implement Pex --exclude and --override support.
190
191
  "_PEX_DEP_CONFIG_FILE",
192
+ # This is used to implement --source support.
193
+ "_PEX_REPOS_CONFIG_FILE",
191
194
  # This is used as an experiment knob for atomic_directory locking.
192
195
  "_PEX_FILE_LOCK_STYLE",
193
196
  # This is used in the scie binding command for ZIPAPP PEXes.
pex/version.py CHANGED
@@ -1,4 +1,4 @@
1
1
  # Copyright 2015 Pex project contributors.
2
2
  # Licensed under the Apache License, Version 2.0 (see LICENSE).
3
3
 
4
- __version__ = "2.54.2"
4
+ __version__ = "2.69.0"
pex/wheel.py CHANGED
@@ -10,24 +10,27 @@ from email.message import Message
10
10
 
11
11
  from pex.dist_metadata import (
12
12
  DistMetadata,
13
+ Distribution,
13
14
  MetadataFiles,
14
15
  MetadataType,
15
16
  load_metadata,
16
17
  parse_message,
17
18
  )
18
19
  from pex.orderedset import OrderedSet
20
+ from pex.pep_440 import Version
21
+ from pex.pep_503 import ProjectName
19
22
  from pex.third_party.packaging import tags
20
23
  from pex.typing import TYPE_CHECKING, cast
21
24
 
22
25
  if TYPE_CHECKING:
23
- from typing import Dict, Text, Tuple
26
+ from typing import Dict, Iterator, List, Optional, Text, Tuple
24
27
 
25
28
  import attr # vendor:skip
26
29
  else:
27
30
  from pex.third_party import attr
28
31
 
29
32
 
30
- class WheelMetadataLoadError(Exception):
33
+ class WheelMetadataLoadError(ValueError):
31
34
  """Indicates an error loading WHEEL metadata."""
32
35
 
33
36
 
@@ -38,27 +41,62 @@ class WHEEL(object):
38
41
  See item 6 here for the WHEEL file contents: https://peps.python.org/pep-0427/#file-contents
39
42
  """
40
43
 
41
- _CACHE = {} # type: Dict[Text, WHEEL]
44
+ @classmethod
45
+ def from_metadata_files(cls, metadata_files):
46
+ # type: (MetadataFiles) -> WHEEL
47
+
48
+ metadata_bytes = metadata_files.read("WHEEL")
49
+ if not metadata_bytes:
50
+ raise WheelMetadataLoadError(
51
+ "Could not find WHEEL metadata in {wheel}.".format(
52
+ wheel=metadata_files.render_description(metadata_file_name="WHEEL")
53
+ )
54
+ )
55
+
56
+ # Some WHEEL metadata in the wild has blank lines in between headers when it should not.
57
+ # Since WHEEL metadata, unlike METADATA, does not use the message body to convey metadata,
58
+ # this should be safe.
59
+ #
60
+ # See here for initial discovery case:
61
+ # https://github.com/pex-tool/pex/issues/2998#issuecomment-3492998265
62
+ normalized_metadata = b"".join(
63
+ line for line in metadata_bytes.splitlines(True) if line.strip()
64
+ )
65
+
66
+ metadata = parse_message(normalized_metadata)
67
+ return cls(files=metadata_files, metadata=metadata)
68
+
69
+ _CACHE = {} # type: Dict[Tuple[Text, Optional[ProjectName]], WHEEL]
42
70
 
43
71
  @classmethod
44
- def load(cls, location):
45
- # type: (Text) -> WHEEL
46
- wheel = cls._CACHE.get(location)
72
+ def load(
73
+ cls,
74
+ location, # type: Text
75
+ project_name=None, # type: Optional[ProjectName]
76
+ ):
77
+ # type: (...) -> WHEEL
78
+ wheel = cls._CACHE.get((location, project_name))
47
79
  if not wheel:
48
- metadata_files = load_metadata(location, restrict_types_to=(MetadataType.DIST_INFO,))
80
+ metadata_files = load_metadata(
81
+ location, project_name=project_name, restrict_types_to=(MetadataType.DIST_INFO,)
82
+ )
49
83
  if not metadata_files:
50
84
  raise WheelMetadataLoadError(
51
85
  "Could not find any metadata in {wheel}.".format(wheel=location)
52
86
  )
87
+ wheel = cls.from_metadata_files(metadata_files)
88
+ cls._CACHE[(location, project_name)] = wheel
89
+ return wheel
53
90
 
54
- metadata_bytes = metadata_files.read("WHEEL")
55
- if not metadata_bytes:
56
- raise WheelMetadataLoadError(
57
- "Could not find WHEEL metadata in {wheel}.".format(wheel=location)
58
- )
59
- metadata = parse_message(metadata_bytes)
60
- wheel = cls(files=metadata_files, metadata=metadata)
61
- cls._CACHE[location] = wheel
91
+ @classmethod
92
+ def from_distribution(cls, distribution):
93
+ # type: (Distribution) -> WHEEL
94
+ location = distribution.metadata.files.metadata.path
95
+ project_name = distribution.metadata.project_name
96
+ wheel = cls._CACHE.get((location, project_name))
97
+ if not wheel:
98
+ wheel = cls.from_metadata_files(distribution.metadata.files)
99
+ cls._CACHE[(location, project_name)] = wheel
62
100
  return wheel
63
101
 
64
102
  files = attr.ib() # type: MetadataFiles
@@ -69,7 +107,16 @@ class WHEEL(object):
69
107
  # type: () -> Tuple[tags.Tag, ...]
70
108
  return tuple(
71
109
  itertools.chain.from_iterable(
72
- tags.parse_tag(tag) for tag in self.metadata.get_all("Tag", ())
110
+ # N.B.: There should be just 1 tag per Tag entry per items 7 and 11 in
111
+ # https://packaging.python.org/en/latest/specifications/binary-distribution-format/#file-contents
112
+ # There are wheels in the wild though with WHEEL metadata Tag entries that contain
113
+ # compressed tags instead of having the tags expanded to 1 per Tag. Although
114
+ # `tags.parse_tag` handles expansion of the compressed tags, it collects them in
115
+ # a frozenset with unstable order which can cause issues when attempting to
116
+ # construct stable wheel names from these tags; as such, we do the sort here as a
117
+ # defense against this style of bad WHEEL Tag metadata.
118
+ sorted(tags.parse_tag(tag), key=lambda tag: str(tag))
119
+ for tag in self.metadata.get_all("Tag", ())
73
120
  )
74
121
  )
75
122
 
@@ -84,26 +131,42 @@ class WHEEL(object):
84
131
 
85
132
  @attr.s(frozen=True)
86
133
  class Wheel(object):
87
- @classmethod
88
- def load(cls, wheel_path):
89
- # type: (str) -> Wheel
90
-
91
- metadata = WHEEL.load(wheel_path)
92
-
93
- metadata_path = metadata.files.metadata_file_rel_path("WHEEL")
94
- if not metadata_path:
95
- raise WheelMetadataLoadError(
96
- "Could not find WHEEL metadata in {wheel}.".format(wheel=wheel_path)
97
- )
134
+ @staticmethod
135
+ def _source(
136
+ location, # type: str
137
+ metadata_files, # type: MetadataFiles
138
+ ):
139
+ # type: (...) -> str
140
+ return "{project_name} {version} at {location}".format(
141
+ project_name=metadata_files.metadata.project_name,
142
+ version=metadata_files.metadata.version,
143
+ location=location,
144
+ )
98
145
 
99
- wheel_metadata_dir = os.path.dirname(metadata_path)
146
+ @classmethod
147
+ def _from_metadata_files(
148
+ cls,
149
+ location, # type: str
150
+ metadata_files, # type: MetadataFiles
151
+ wheel=None, # type: Optional[WHEEL]
152
+ ):
153
+ # type: (...) -> Wheel
154
+
155
+ if wheel:
156
+ metadata = wheel
157
+ else:
158
+ metadata = WHEEL.from_metadata_files(metadata_files)
159
+
160
+ wheel_metadata_dir = os.path.dirname(metadata_files.metadata.rel_path)
100
161
  if not wheel_metadata_dir.endswith(".dist-info"):
101
162
  raise WheelMetadataLoadError(
102
- "Expected WHEEL metadata for {wheel} to be housed in a .dist-info directory, but was "
103
- "found at {wheel_metadata_path}.".format(
104
- wheel=wheel_path, wheel_metadata_path=metadata_path
163
+ "Expected METADATA file for {source} to be housed in a .dist-info directory, but "
164
+ "was found at {wheel_metadata_path}.".format(
165
+ source=cls._source(location, metadata_files),
166
+ wheel_metadata_path=metadata_files.metadata.rel_path,
105
167
  )
106
168
  )
169
+
107
170
  # Although not crisply defined, all PEPs lead to PEP-508 which restricts project names
108
171
  # to ASCII: https://peps.python.org/pep-0508/#names. Likewise, version numbers are also
109
172
  # restricted to ASCII: https://peps.python.org/pep-0440/. Since the `.dist-info` dir
@@ -113,13 +176,35 @@ class Wheel(object):
113
176
  metadata_dir = str(wheel_metadata_dir)
114
177
 
115
178
  data_dir = re.sub(r"\.dist-info$", ".data", metadata_dir)
179
+ pex_metadata_dir = re.sub(r"\.dist-info$", ".pex-info", metadata_dir)
116
180
 
117
181
  return cls(
118
- location=wheel_path,
182
+ location=location,
119
183
  metadata_dir=metadata_dir,
120
- metadata_files=metadata.files,
184
+ metadata_files=metadata_files,
121
185
  metadata=metadata,
122
186
  data_dir=data_dir,
187
+ pex_metadata_dir=pex_metadata_dir,
188
+ )
189
+
190
+ @classmethod
191
+ def load(
192
+ cls,
193
+ wheel_path, # type: str
194
+ project_name=None, # type: Optional[ProjectName]
195
+ ):
196
+ # type: (...) -> Wheel
197
+
198
+ wheel = WHEEL.load(wheel_path, project_name=project_name)
199
+ return cls._from_metadata_files(
200
+ location=wheel_path, metadata_files=wheel.files, wheel=wheel
201
+ )
202
+
203
+ @classmethod
204
+ def from_distribution(cls, distribution):
205
+ # type: (Distribution) -> Wheel
206
+ return cls._from_metadata_files(
207
+ location=distribution.location, metadata_files=distribution.metadata.files
123
208
  )
124
209
 
125
210
  location = attr.ib() # type: str
@@ -127,6 +212,34 @@ class Wheel(object):
127
212
  metadata_files = attr.ib() # type: MetadataFiles
128
213
  metadata = attr.ib() # type: WHEEL
129
214
  data_dir = attr.ib() # type: str
215
+ pex_metadata_dir = attr.ib() # type: str
216
+
217
+ @property
218
+ def source(self):
219
+ # type: () -> str
220
+ return self._source(self.location, self.metadata_files)
221
+
222
+ @property
223
+ def project_name(self):
224
+ # type: () -> ProjectName
225
+ return self.metadata_files.metadata.project_name
226
+
227
+ @property
228
+ def version(self):
229
+ # type: () -> Version
230
+ return self.metadata_files.metadata.version
231
+
232
+ @property
233
+ def wheel_prefix(self):
234
+ # type: () -> str
235
+
236
+ # N.B.: We don't use the canonical form since it goes to lowercase.
237
+ project_name = re.sub(r"[-_.]+", "_", self.project_name.raw)
238
+
239
+ # N.B.: We don't use the canonical form since it drop trailing zero segments.
240
+ version = self.version.raw.replace("-", "_")
241
+
242
+ return "{project_name}-{version}".format(project_name=project_name, version=version)
130
243
 
131
244
  @property
132
245
  def wheel_file_name(self):
@@ -142,12 +255,29 @@ class Wheel(object):
142
255
  tag = "{interpreters}-{abis}-{platforms}".format(
143
256
  interpreters=".".join(interpreters), abis=".".join(abis), platforms=".".join(platforms)
144
257
  )
258
+ return "{wheel_prefix}-{tag}.whl".format(wheel_prefix=self.wheel_prefix, tag=tag)
145
259
 
146
- return "{project_name}-{version}-{tag}.whl".format(
147
- project_name=self.metadata_files.metadata.project_name.raw,
148
- version=self.metadata_files.metadata.version.raw,
149
- tag=tag,
150
- )
260
+ def iter_compatible_python_versions(self):
261
+ # type: () -> Iterator[Tuple[int, ...]]
262
+
263
+ for tag in self.metadata.tags:
264
+ match = re.search(r"\d+(?:_\d+)*", tag.interpreter)
265
+ if not match:
266
+ raise WheelMetadataLoadError(
267
+ "Invalid interpreter tag for wheel {whl} at {location}: {tag}".format(
268
+ whl=self.wheel_file_name, location=self.location, tag=tag.interpreter
269
+ )
270
+ )
271
+ components = match.group().split("_")
272
+ version = [] # type: List[int]
273
+ if len(components) == 1:
274
+ py_version_nodot = components[0]
275
+ version.append(int(py_version_nodot[0]))
276
+ if len(py_version_nodot) > 1:
277
+ version.append(int(py_version_nodot[1:]))
278
+ else:
279
+ version.extend(int(component) for component in components)
280
+ yield tuple(version)
151
281
 
152
282
  @property
153
283
  def root_is_purelib(self):
@@ -159,9 +289,27 @@ class Wheel(object):
159
289
  return DistMetadata.from_metadata_files(self.metadata_files)
160
290
 
161
291
  def metadata_path(self, *components):
162
- # typ: (*str) -> str
292
+ # type: (*str) -> str
293
+ if not components:
294
+ return self.metadata_dir
163
295
  return os.path.join(self.metadata_dir, *components)
164
296
 
165
297
  def data_path(self, *components):
166
- # typ: (*str) -> str
298
+ # type: (*str) -> str
167
299
  return os.path.join(self.data_dir, *components)
300
+
301
+ def pex_metadata_path(self, *components):
302
+ # type: (*str) -> str
303
+ if not components:
304
+ return self.pex_metadata_dir
305
+ return os.path.join(self.pex_metadata_dir, *components)
306
+
307
+ def read_pex_metadata(self, *components):
308
+ # type: (*str) -> Optional[bytes]
309
+
310
+ location = os.path.join(self.location, self.pex_metadata_path(*components))
311
+ if not os.path.exists(location):
312
+ return None
313
+
314
+ with open(location, "rb") as fp:
315
+ return fp.read()