From 4d6168b350d4d29976c0f5959b1ffeb27a59ca01 Mon Sep 17 00:00:00 2001 From: sgoudham Date: Tue, 30 Jun 2020 01:59:45 +0100 Subject: [PATCH] Installing wheels --- .../SOURCES.txt | 8 - .../dependency_links.txt | 1 - .../installed-files.txt | 7 - .../requires.txt | 1 - .../INSTALLER | 1 + .../LICENSE | 21 + .../METADATA} | 8 +- .../RECORD | 9 + .../WHEEL | 5 + .../direct_url.json | 1 + .../top_level.txt | 0 .../wheel-0.34.2.dist-info/INSTALLER | 1 + .../wheel-0.34.2.dist-info/LICENSE.txt | 22 + .../wheel-0.34.2.dist-info/METADATA | 66 +++ .../wheel-0.34.2.dist-info/RECORD | 38 ++ .../wheel-0.34.2.dist-info/WHEEL | 6 + .../wheel-0.34.2.dist-info/entry_points.txt | 6 + .../wheel-0.34.2.dist-info/top_level.txt | 1 + venv/Lib/site-packages/wheel/__init__.py | 1 + venv/Lib/site-packages/wheel/__main__.py | 19 + venv/Lib/site-packages/wheel/_version.py | 4 + venv/Lib/site-packages/wheel/bdist_wheel.py | 403 ++++++++++++++++++ venv/Lib/site-packages/wheel/cli/__init__.py | 88 ++++ venv/Lib/site-packages/wheel/cli/convert.py | 269 ++++++++++++ venv/Lib/site-packages/wheel/cli/install.py | 0 venv/Lib/site-packages/wheel/cli/pack.py | 79 ++++ venv/Lib/site-packages/wheel/cli/unpack.py | 25 ++ .../Lib/site-packages/wheel/macosx_libfile.py | 341 +++++++++++++++ venv/Lib/site-packages/wheel/metadata.py | 138 ++++++ venv/Lib/site-packages/wheel/pep425tags.py | 261 ++++++++++++ venv/Lib/site-packages/wheel/pkginfo.py | 43 ++ venv/Lib/site-packages/wheel/util.py | 46 ++ venv/Lib/site-packages/wheel/wheelfile.py | 169 ++++++++ venv/Scripts/wheel.exe | Bin 0 -> 106360 bytes 34 files changed, 2069 insertions(+), 19 deletions(-) delete mode 100644 venv/Lib/site-packages/discord_ext_menus-1.0.0a22+gcc108be-py3.6.egg-info/SOURCES.txt delete mode 100644 venv/Lib/site-packages/discord_ext_menus-1.0.0a22+gcc108be-py3.6.egg-info/dependency_links.txt delete mode 100644 venv/Lib/site-packages/discord_ext_menus-1.0.0a22+gcc108be-py3.6.egg-info/installed-files.txt delete mode 100644 venv/Lib/site-packages/discord_ext_menus-1.0.0a22+gcc108be-py3.6.egg-info/requires.txt create mode 100644 venv/Lib/site-packages/discord_ext_menus-1.0.0a22+gcc108be.dist-info/INSTALLER create mode 100644 venv/Lib/site-packages/discord_ext_menus-1.0.0a22+gcc108be.dist-info/LICENSE rename venv/Lib/site-packages/{discord_ext_menus-1.0.0a22+gcc108be-py3.6.egg-info/PKG-INFO => discord_ext_menus-1.0.0a22+gcc108be.dist-info/METADATA} (78%) create mode 100644 venv/Lib/site-packages/discord_ext_menus-1.0.0a22+gcc108be.dist-info/RECORD create mode 100644 venv/Lib/site-packages/discord_ext_menus-1.0.0a22+gcc108be.dist-info/WHEEL create mode 100644 venv/Lib/site-packages/discord_ext_menus-1.0.0a22+gcc108be.dist-info/direct_url.json rename venv/Lib/site-packages/{discord_ext_menus-1.0.0a22+gcc108be-py3.6.egg-info => discord_ext_menus-1.0.0a22+gcc108be.dist-info}/top_level.txt (100%) create mode 100644 venv/Lib/site-packages/wheel-0.34.2.dist-info/INSTALLER create mode 100644 venv/Lib/site-packages/wheel-0.34.2.dist-info/LICENSE.txt create mode 100644 venv/Lib/site-packages/wheel-0.34.2.dist-info/METADATA create mode 100644 venv/Lib/site-packages/wheel-0.34.2.dist-info/RECORD create mode 100644 venv/Lib/site-packages/wheel-0.34.2.dist-info/WHEEL create mode 100644 venv/Lib/site-packages/wheel-0.34.2.dist-info/entry_points.txt create mode 100644 venv/Lib/site-packages/wheel-0.34.2.dist-info/top_level.txt create mode 100644 venv/Lib/site-packages/wheel/__init__.py create mode 100644 venv/Lib/site-packages/wheel/__main__.py create mode 100644 venv/Lib/site-packages/wheel/_version.py create mode 100644 venv/Lib/site-packages/wheel/bdist_wheel.py create mode 100644 venv/Lib/site-packages/wheel/cli/__init__.py create mode 100644 venv/Lib/site-packages/wheel/cli/convert.py create mode 100644 venv/Lib/site-packages/wheel/cli/install.py create mode 100644 venv/Lib/site-packages/wheel/cli/pack.py create mode 100644 venv/Lib/site-packages/wheel/cli/unpack.py create mode 100644 venv/Lib/site-packages/wheel/macosx_libfile.py create mode 100644 venv/Lib/site-packages/wheel/metadata.py create mode 100644 venv/Lib/site-packages/wheel/pep425tags.py create mode 100644 venv/Lib/site-packages/wheel/pkginfo.py create mode 100644 venv/Lib/site-packages/wheel/util.py create mode 100644 venv/Lib/site-packages/wheel/wheelfile.py create mode 100644 venv/Scripts/wheel.exe diff --git a/venv/Lib/site-packages/discord_ext_menus-1.0.0a22+gcc108be-py3.6.egg-info/SOURCES.txt b/venv/Lib/site-packages/discord_ext_menus-1.0.0a22+gcc108be-py3.6.egg-info/SOURCES.txt deleted file mode 100644 index a1af9c76..00000000 --- a/venv/Lib/site-packages/discord_ext_menus-1.0.0a22+gcc108be-py3.6.egg-info/SOURCES.txt +++ /dev/null @@ -1,8 +0,0 @@ -README.md -setup.py -discord/ext/menus/__init__.py -discord_ext_menus.egg-info/PKG-INFO -discord_ext_menus.egg-info/SOURCES.txt -discord_ext_menus.egg-info/dependency_links.txt -discord_ext_menus.egg-info/requires.txt -discord_ext_menus.egg-info/top_level.txt \ No newline at end of file diff --git a/venv/Lib/site-packages/discord_ext_menus-1.0.0a22+gcc108be-py3.6.egg-info/dependency_links.txt b/venv/Lib/site-packages/discord_ext_menus-1.0.0a22+gcc108be-py3.6.egg-info/dependency_links.txt deleted file mode 100644 index 8b137891..00000000 --- a/venv/Lib/site-packages/discord_ext_menus-1.0.0a22+gcc108be-py3.6.egg-info/dependency_links.txt +++ /dev/null @@ -1 +0,0 @@ - diff --git a/venv/Lib/site-packages/discord_ext_menus-1.0.0a22+gcc108be-py3.6.egg-info/installed-files.txt b/venv/Lib/site-packages/discord_ext_menus-1.0.0a22+gcc108be-py3.6.egg-info/installed-files.txt deleted file mode 100644 index cdb97709..00000000 --- a/venv/Lib/site-packages/discord_ext_menus-1.0.0a22+gcc108be-py3.6.egg-info/installed-files.txt +++ /dev/null @@ -1,7 +0,0 @@ -..\discord\ext\menus\__init__.py -..\discord\ext\menus\__pycache__\__init__.cpython-36.pyc -PKG-INFO -SOURCES.txt -dependency_links.txt -requires.txt -top_level.txt diff --git a/venv/Lib/site-packages/discord_ext_menus-1.0.0a22+gcc108be-py3.6.egg-info/requires.txt b/venv/Lib/site-packages/discord_ext_menus-1.0.0a22+gcc108be-py3.6.egg-info/requires.txt deleted file mode 100644 index f488cea4..00000000 --- a/venv/Lib/site-packages/discord_ext_menus-1.0.0a22+gcc108be-py3.6.egg-info/requires.txt +++ /dev/null @@ -1 +0,0 @@ -discord.py>=1.2.5 diff --git a/venv/Lib/site-packages/discord_ext_menus-1.0.0a22+gcc108be.dist-info/INSTALLER b/venv/Lib/site-packages/discord_ext_menus-1.0.0a22+gcc108be.dist-info/INSTALLER new file mode 100644 index 00000000..a1b589e3 --- /dev/null +++ b/venv/Lib/site-packages/discord_ext_menus-1.0.0a22+gcc108be.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/venv/Lib/site-packages/discord_ext_menus-1.0.0a22+gcc108be.dist-info/LICENSE b/venv/Lib/site-packages/discord_ext_menus-1.0.0a22+gcc108be.dist-info/LICENSE new file mode 100644 index 00000000..b0d77891 --- /dev/null +++ b/venv/Lib/site-packages/discord_ext_menus-1.0.0a22+gcc108be.dist-info/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2015-2019 Danny Y. (Rapptz) + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +the rights to use, copy, modify, merge, publish, distribute, sublicense, +and/or sell copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. diff --git a/venv/Lib/site-packages/discord_ext_menus-1.0.0a22+gcc108be-py3.6.egg-info/PKG-INFO b/venv/Lib/site-packages/discord_ext_menus-1.0.0a22+gcc108be.dist-info/METADATA similarity index 78% rename from venv/Lib/site-packages/discord_ext_menus-1.0.0a22+gcc108be-py3.6.egg-info/PKG-INFO rename to venv/Lib/site-packages/discord_ext_menus-1.0.0a22+gcc108be.dist-info/METADATA index 0c0b0487..1beb348b 100644 --- a/venv/Lib/site-packages/discord_ext_menus-1.0.0a22+gcc108be-py3.6.egg-info/PKG-INFO +++ b/venv/Lib/site-packages/discord_ext_menus-1.0.0a22+gcc108be.dist-info/METADATA @@ -1,10 +1,14 @@ -Metadata-Version: 1.2 +Metadata-Version: 2.1 Name: discord-ext-menus Version: 1.0.0a22+gcc108be Summary: An extension module to make reaction based menus with discord.py Home-page: https://github.com/Rapptz/discord-ext-menus Author: Rapptz License: MIT -Description: UNKNOWN Platform: UNKNOWN Requires-Python: >=3.5.3 +Requires-Dist: discord.py (>=1.2.5) + +UNKNOWN + + diff --git a/venv/Lib/site-packages/discord_ext_menus-1.0.0a22+gcc108be.dist-info/RECORD b/venv/Lib/site-packages/discord_ext_menus-1.0.0a22+gcc108be.dist-info/RECORD new file mode 100644 index 00000000..31fd1654 --- /dev/null +++ b/venv/Lib/site-packages/discord_ext_menus-1.0.0a22+gcc108be.dist-info/RECORD @@ -0,0 +1,9 @@ +discord/ext/menus/__init__.py,sha256=V8ojHgCI1oH5fWiJF7ZbrOg95MbgH3PIbC8eK33uwVc,41686 +discord/ext/menus/__pycache__/__init__.cpython-36.pyc,, +discord_ext_menus-1.0.0a22+gcc108be.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +discord_ext_menus-1.0.0a22+gcc108be.dist-info/LICENSE,sha256=7BAmT4qZKQ2E3NZi8tfNGXQx6QSIJ-vbjhDH853-9Fc,1110 +discord_ext_menus-1.0.0a22+gcc108be.dist-info/METADATA,sha256=xr4yYqrPVCPgZ07VrN7oW5hHYdiMqI1wMPUGfJuOdHY,320 +discord_ext_menus-1.0.0a22+gcc108be.dist-info/RECORD,, +discord_ext_menus-1.0.0a22+gcc108be.dist-info/WHEEL,sha256=YUYzQ6UQdoqxXjimOitTqynltBCkwY6qlTfTh2IzqQU,97 +discord_ext_menus-1.0.0a22+gcc108be.dist-info/direct_url.json,sha256=Ltfp2x8uwSMUplapYkfSOJi86JJkX5gXUSMBuPxbqsM,139 +discord_ext_menus-1.0.0a22+gcc108be.dist-info/top_level.txt,sha256=fJkrNbR-_8ubMBUcDEJBcfkpECrvSEmMrNKgvLlQFoM,8 diff --git a/venv/Lib/site-packages/discord_ext_menus-1.0.0a22+gcc108be.dist-info/WHEEL b/venv/Lib/site-packages/discord_ext_menus-1.0.0a22+gcc108be.dist-info/WHEEL new file mode 100644 index 00000000..b552003f --- /dev/null +++ b/venv/Lib/site-packages/discord_ext_menus-1.0.0a22+gcc108be.dist-info/WHEEL @@ -0,0 +1,5 @@ +Wheel-Version: 1.0 +Generator: bdist_wheel (0.34.2) +Root-Is-Purelib: true +Tag: py3-none-any + diff --git a/venv/Lib/site-packages/discord_ext_menus-1.0.0a22+gcc108be.dist-info/direct_url.json b/venv/Lib/site-packages/discord_ext_menus-1.0.0a22+gcc108be.dist-info/direct_url.json new file mode 100644 index 00000000..8bf30df5 --- /dev/null +++ b/venv/Lib/site-packages/discord_ext_menus-1.0.0a22+gcc108be.dist-info/direct_url.json @@ -0,0 +1 @@ +{"url": "https://github.com/Rapptz/discord-ext-menus", "vcs_info": {"commit_id": "cc108bed812d0e481a628ca573c2eeeca9226b42", "vcs": "git"}} \ No newline at end of file diff --git a/venv/Lib/site-packages/discord_ext_menus-1.0.0a22+gcc108be-py3.6.egg-info/top_level.txt b/venv/Lib/site-packages/discord_ext_menus-1.0.0a22+gcc108be.dist-info/top_level.txt similarity index 100% rename from venv/Lib/site-packages/discord_ext_menus-1.0.0a22+gcc108be-py3.6.egg-info/top_level.txt rename to venv/Lib/site-packages/discord_ext_menus-1.0.0a22+gcc108be.dist-info/top_level.txt diff --git a/venv/Lib/site-packages/wheel-0.34.2.dist-info/INSTALLER b/venv/Lib/site-packages/wheel-0.34.2.dist-info/INSTALLER new file mode 100644 index 00000000..a1b589e3 --- /dev/null +++ b/venv/Lib/site-packages/wheel-0.34.2.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/venv/Lib/site-packages/wheel-0.34.2.dist-info/LICENSE.txt b/venv/Lib/site-packages/wheel-0.34.2.dist-info/LICENSE.txt new file mode 100644 index 00000000..c3441e6c --- /dev/null +++ b/venv/Lib/site-packages/wheel-0.34.2.dist-info/LICENSE.txt @@ -0,0 +1,22 @@ +"wheel" copyright (c) 2012-2014 Daniel Holth and +contributors. + +The MIT License + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +the rights to use, copy, modify, merge, publish, distribute, sublicense, +and/or sell copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. diff --git a/venv/Lib/site-packages/wheel-0.34.2.dist-info/METADATA b/venv/Lib/site-packages/wheel-0.34.2.dist-info/METADATA new file mode 100644 index 00000000..83953218 --- /dev/null +++ b/venv/Lib/site-packages/wheel-0.34.2.dist-info/METADATA @@ -0,0 +1,66 @@ +Metadata-Version: 2.1 +Name: wheel +Version: 0.34.2 +Summary: A built-package format for Python +Home-page: https://github.com/pypa/wheel +Author: Daniel Holth +Author-email: dholth@fastmail.fm +Maintainer: Alex Grönholm +Maintainer-email: alex.gronholm@nextday.fi +License: MIT +Project-URL: Documentation, https://wheel.readthedocs.io/ +Project-URL: Changelog, https://wheel.readthedocs.io/en/stable/news.html +Project-URL: Issue Tracker, https://github.com/pypa/wheel/issues +Keywords: wheel,packaging +Platform: UNKNOWN +Classifier: Development Status :: 5 - Production/Stable +Classifier: Intended Audience :: Developers +Classifier: Topic :: System :: Archiving :: Packaging +Classifier: License :: OSI Approved :: MIT License +Classifier: Programming Language :: Python +Classifier: Programming Language :: Python :: 2 +Classifier: Programming Language :: Python :: 2.7 +Classifier: Programming Language :: Python :: 3 +Classifier: Programming Language :: Python :: 3.5 +Classifier: Programming Language :: Python :: 3.6 +Classifier: Programming Language :: Python :: 3.7 +Classifier: Programming Language :: Python :: 3.8 +Requires-Python: >=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.* +Provides-Extra: test +Requires-Dist: pytest (>=3.0.0) ; extra == 'test' +Requires-Dist: pytest-cov ; extra == 'test' + +wheel +===== + +This library is the reference implementation of the Python wheel packaging +standard, as defined in `PEP 427`_. + +It has two different roles: + +#. A setuptools_ extension for building wheels that provides the + ``bdist_wheel`` setuptools command +#. A command line tool for working with wheel files + +It should be noted that wheel is **not** intended to be used as a library, and +as such there is no stable, public API. + +.. _PEP 427: https://www.python.org/dev/peps/pep-0427/ +.. _setuptools: https://pypi.org/project/setuptools/ + +Documentation +------------- + +The documentation_ can be found on Read The Docs. + +.. _documentation: https://wheel.readthedocs.io/ + +Code of Conduct +--------------- + +Everyone interacting in the wheel project's codebases, issue trackers, chat +rooms, and mailing lists is expected to follow the `PyPA Code of Conduct`_. + +.. _PyPA Code of Conduct: https://www.pypa.io/en/latest/code-of-conduct/ + + diff --git a/venv/Lib/site-packages/wheel-0.34.2.dist-info/RECORD b/venv/Lib/site-packages/wheel-0.34.2.dist-info/RECORD new file mode 100644 index 00000000..faae2867 --- /dev/null +++ b/venv/Lib/site-packages/wheel-0.34.2.dist-info/RECORD @@ -0,0 +1,38 @@ +../../Scripts/wheel.exe,sha256=GRuTq5C6yxuiPV2_3k1o9oJ62z2c5d9g9CNMvKft1iA,106360 +wheel-0.34.2.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +wheel-0.34.2.dist-info/LICENSE.txt,sha256=zKniDGrx_Pv2lAjzd3aShsvuvN7TNhAMm0o_NfvmNeQ,1125 +wheel-0.34.2.dist-info/METADATA,sha256=uizJLqT4WTszpXZTkDAoUn364lfXXMz-ha1TLIuQQbU,2219 +wheel-0.34.2.dist-info/RECORD,, +wheel-0.34.2.dist-info/WHEEL,sha256=kGT74LWyRUZrL4VgLh6_g12IeVl_9u9ZVhadrgXZUEY,110 +wheel-0.34.2.dist-info/entry_points.txt,sha256=N8HbYFST3yrNQYeB2wXWBEPUhFsEtKNRPaCFGJPyqyc,108 +wheel-0.34.2.dist-info/top_level.txt,sha256=HxSBIbgEstMPe4eFawhA66Mq-QYHMopXVoAncfjb_1c,6 +wheel/__init__.py,sha256=HnvQS9U0JqVi8rcO-9DbcHRmVtnblu7VwdzoKbMiZDQ,23 +wheel/__main__.py,sha256=lF-YLO4hdQmoWuh4eWZd8YL1U95RSdm76sNLBXa0vjE,417 +wheel/__pycache__/__init__.cpython-36.pyc,, +wheel/__pycache__/__main__.cpython-36.pyc,, +wheel/__pycache__/_version.cpython-36.pyc,, +wheel/__pycache__/bdist_wheel.cpython-36.pyc,, +wheel/__pycache__/macosx_libfile.cpython-36.pyc,, +wheel/__pycache__/metadata.cpython-36.pyc,, +wheel/__pycache__/pep425tags.cpython-36.pyc,, +wheel/__pycache__/pkginfo.cpython-36.pyc,, +wheel/__pycache__/util.cpython-36.pyc,, +wheel/__pycache__/wheelfile.cpython-36.pyc,, +wheel/_version.py,sha256=KiDEywHVTrXNxe6ojGe-7gEm6gUYge5r_fThX1den7Y,133 +wheel/bdist_wheel.py,sha256=fgVFnJ2cC3MkU5Wy0nNLCzbJoGorSzSrzM9PFq4HWj0,15840 +wheel/cli/__init__.py,sha256=GWSoGUpRabTf8bk3FsNTPrc5Fsr8YOv2dX55iY2W7eY,2572 +wheel/cli/__pycache__/__init__.cpython-36.pyc,, +wheel/cli/__pycache__/convert.cpython-36.pyc,, +wheel/cli/__pycache__/install.cpython-36.pyc,, +wheel/cli/__pycache__/pack.cpython-36.pyc,, +wheel/cli/__pycache__/unpack.cpython-36.pyc,, +wheel/cli/convert.py,sha256=7F4vj23A2OghDDWn9gX2V-_TeXMza1a5nIejmFGEUJM,9498 +wheel/cli/install.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +wheel/cli/pack.py,sha256=S-J1iIy1GPDTTDdn-_SwxGa7N729h4iZNI11EDFCqfA,3208 +wheel/cli/unpack.py,sha256=0VWzT7U_xyenTPwEVavxqvdee93GPvAFHnR3Uu91aRc,673 +wheel/macosx_libfile.py,sha256=NhNz1C3zF_78iMUd4ij0le1jVJNnz93tCAICSKXgYvg,11858 +wheel/metadata.py,sha256=siS-hs_DTT0ScpbzloYbQSGYXUDC_Tim10ixcYWSM-4,4517 +wheel/pep425tags.py,sha256=tuXvpyhYJHDcsXHgSRonny1X3kG3TSn7CN9nL9tZUMA,9071 +wheel/pkginfo.py,sha256=GR76kupQzn1x9sKDaXuE6B6FsZ4OkfRtG7pndlXPvQ4,1257 +wheel/util.py,sha256=mnNZkJCi9DHLI_q4lTudoD0mW97h_AoAWl7prNPLXJc,938 +wheel/wheelfile.py,sha256=WsWfD-OBgHxxeF7SxRi3OX6l_qxtP06b2ZK0NVhT_n0,7298 diff --git a/venv/Lib/site-packages/wheel-0.34.2.dist-info/WHEEL b/venv/Lib/site-packages/wheel-0.34.2.dist-info/WHEEL new file mode 100644 index 00000000..ef99c6cf --- /dev/null +++ b/venv/Lib/site-packages/wheel-0.34.2.dist-info/WHEEL @@ -0,0 +1,6 @@ +Wheel-Version: 1.0 +Generator: bdist_wheel (0.34.2) +Root-Is-Purelib: true +Tag: py2-none-any +Tag: py3-none-any + diff --git a/venv/Lib/site-packages/wheel-0.34.2.dist-info/entry_points.txt b/venv/Lib/site-packages/wheel-0.34.2.dist-info/entry_points.txt new file mode 100644 index 00000000..b27acadd --- /dev/null +++ b/venv/Lib/site-packages/wheel-0.34.2.dist-info/entry_points.txt @@ -0,0 +1,6 @@ +[console_scripts] +wheel = wheel.cli:main + +[distutils.commands] +bdist_wheel = wheel.bdist_wheel:bdist_wheel + diff --git a/venv/Lib/site-packages/wheel-0.34.2.dist-info/top_level.txt b/venv/Lib/site-packages/wheel-0.34.2.dist-info/top_level.txt new file mode 100644 index 00000000..2309722a --- /dev/null +++ b/venv/Lib/site-packages/wheel-0.34.2.dist-info/top_level.txt @@ -0,0 +1 @@ +wheel diff --git a/venv/Lib/site-packages/wheel/__init__.py b/venv/Lib/site-packages/wheel/__init__.py new file mode 100644 index 00000000..3c92ca22 --- /dev/null +++ b/venv/Lib/site-packages/wheel/__init__.py @@ -0,0 +1 @@ +__version__ = '0.34.2' diff --git a/venv/Lib/site-packages/wheel/__main__.py b/venv/Lib/site-packages/wheel/__main__.py new file mode 100644 index 00000000..b3773a20 --- /dev/null +++ b/venv/Lib/site-packages/wheel/__main__.py @@ -0,0 +1,19 @@ +""" +Wheel command line tool (enable python -m wheel syntax) +""" + +import sys + + +def main(): # needed for console script + if __package__ == '': + # To be able to run 'python wheel-0.9.whl/wheel': + import os.path + path = os.path.dirname(os.path.dirname(__file__)) + sys.path[0:0] = [path] + import wheel.cli + sys.exit(wheel.cli.main()) + + +if __name__ == "__main__": + sys.exit(main()) diff --git a/venv/Lib/site-packages/wheel/_version.py b/venv/Lib/site-packages/wheel/_version.py new file mode 100644 index 00000000..5f581f72 --- /dev/null +++ b/venv/Lib/site-packages/wheel/_version.py @@ -0,0 +1,4 @@ +# coding: utf-8 +# file generated by setuptools_scm +# don't change, don't track in version control +version = '0.33.6.post32+gd3d7a43' diff --git a/venv/Lib/site-packages/wheel/bdist_wheel.py b/venv/Lib/site-packages/wheel/bdist_wheel.py new file mode 100644 index 00000000..5cece1f2 --- /dev/null +++ b/venv/Lib/site-packages/wheel/bdist_wheel.py @@ -0,0 +1,403 @@ +""" +Create a wheel (.whl) distribution. + +A wheel is a built archive format. +""" + +import os +import shutil +import stat +import sys +import re +from collections import OrderedDict +from email.generator import Generator +from distutils.core import Command +from distutils.sysconfig import get_python_version +from distutils import log as logger +from glob import iglob +from shutil import rmtree +from warnings import warn +from zipfile import ZIP_DEFLATED, ZIP_STORED + +import pkg_resources + +from .pep425tags import get_abbr_impl, get_impl_ver, get_abi_tag, get_platform +from .pkginfo import write_pkg_info +from .metadata import pkginfo_to_metadata +from .wheelfile import WheelFile +from . import pep425tags +from . import __version__ as wheel_version + + +safe_name = pkg_resources.safe_name +safe_version = pkg_resources.safe_version + +PY_LIMITED_API_PATTERN = r'cp3\d' + + +def safer_name(name): + return safe_name(name).replace('-', '_') + + +def safer_version(version): + return safe_version(version).replace('-', '_') + + +def remove_readonly(func, path, excinfo): + print(str(excinfo[1])) + os.chmod(path, stat.S_IWRITE) + func(path) + + +class bdist_wheel(Command): + + description = 'create a wheel distribution' + + supported_compressions = OrderedDict([ + ('stored', ZIP_STORED), + ('deflated', ZIP_DEFLATED) + ]) + + user_options = [('bdist-dir=', 'b', + "temporary directory for creating the distribution"), + ('plat-name=', 'p', + "platform name to embed in generated filenames " + "(default: %s)" % get_platform(None)), + ('keep-temp', 'k', + "keep the pseudo-installation tree around after " + + "creating the distribution archive"), + ('dist-dir=', 'd', + "directory to put final built distributions in"), + ('skip-build', None, + "skip rebuilding everything (for testing/debugging)"), + ('relative', None, + "build the archive using relative paths " + "(default: false)"), + ('owner=', 'u', + "Owner name used when creating a tar file" + " [default: current user]"), + ('group=', 'g', + "Group name used when creating a tar file" + " [default: current group]"), + ('universal', None, + "make a universal wheel" + " (default: false)"), + ('compression=', None, + "zipfile compression (one of: {})" + " (default: 'deflated')" + .format(', '.join(supported_compressions))), + ('python-tag=', None, + "Python implementation compatibility tag" + " (default: py%s)" % get_impl_ver()[0]), + ('build-number=', None, + "Build number for this particular version. " + "As specified in PEP-0427, this must start with a digit. " + "[default: None]"), + ('py-limited-api=', None, + "Python tag (cp32|cp33|cpNN) for abi3 wheel tag" + " (default: false)"), + ] + + boolean_options = ['keep-temp', 'skip-build', 'relative', 'universal'] + + def initialize_options(self): + self.bdist_dir = None + self.data_dir = None + self.plat_name = None + self.plat_tag = None + self.format = 'zip' + self.keep_temp = False + self.dist_dir = None + self.egginfo_dir = None + self.root_is_pure = None + self.skip_build = None + self.relative = False + self.owner = None + self.group = None + self.universal = False + self.compression = 'deflated' + self.python_tag = 'py' + get_impl_ver()[0] + self.build_number = None + self.py_limited_api = False + self.plat_name_supplied = False + + def finalize_options(self): + if self.bdist_dir is None: + bdist_base = self.get_finalized_command('bdist').bdist_base + self.bdist_dir = os.path.join(bdist_base, 'wheel') + + self.data_dir = self.wheel_dist_name + '.data' + self.plat_name_supplied = self.plat_name is not None + + try: + self.compression = self.supported_compressions[self.compression] + except KeyError: + raise ValueError('Unsupported compression: {}'.format(self.compression)) + + need_options = ('dist_dir', 'plat_name', 'skip_build') + + self.set_undefined_options('bdist', + *zip(need_options, need_options)) + + self.root_is_pure = not (self.distribution.has_ext_modules() + or self.distribution.has_c_libraries()) + + if self.py_limited_api and not re.match(PY_LIMITED_API_PATTERN, self.py_limited_api): + raise ValueError("py-limited-api must match '%s'" % PY_LIMITED_API_PATTERN) + + # Support legacy [wheel] section for setting universal + wheel = self.distribution.get_option_dict('wheel') + if 'universal' in wheel: + # please don't define this in your global configs + logger.warn('The [wheel] section is deprecated. Use [bdist_wheel] instead.') + val = wheel['universal'][1].strip() + if val.lower() in ('1', 'true', 'yes'): + self.universal = True + + if self.build_number is not None and not self.build_number[:1].isdigit(): + raise ValueError("Build tag (build-number) must start with a digit.") + + @property + def wheel_dist_name(self): + """Return distribution full name with - replaced with _""" + components = (safer_name(self.distribution.get_name()), + safer_version(self.distribution.get_version())) + if self.build_number: + components += (self.build_number,) + return '-'.join(components) + + def get_tag(self): + # bdist sets self.plat_name if unset, we should only use it for purepy + # wheels if the user supplied it. + if self.plat_name_supplied: + plat_name = self.plat_name + elif self.root_is_pure: + plat_name = 'any' + else: + # macosx contains system version in platform name so need special handle + if self.plat_name and not self.plat_name.startswith("macosx"): + plat_name = self.plat_name + else: + plat_name = get_platform(self.bdist_dir) + + if plat_name in ('linux-x86_64', 'linux_x86_64') and sys.maxsize == 2147483647: + plat_name = 'linux_i686' + + plat_name = plat_name.replace('-', '_').replace('.', '_') + + if self.root_is_pure: + if self.universal: + impl = 'py2.py3' + else: + impl = self.python_tag + tag = (impl, 'none', plat_name) + else: + impl_name = get_abbr_impl() + impl_ver = get_impl_ver() + impl = impl_name + impl_ver + # We don't work on CPython 3.1, 3.0. + if self.py_limited_api and (impl_name + impl_ver).startswith('cp3'): + impl = self.py_limited_api + abi_tag = 'abi3' + else: + abi_tag = str(get_abi_tag()).lower() + tag = (impl, abi_tag, plat_name) + supported_tags = pep425tags.get_supported( + self.bdist_dir, + supplied_platform=plat_name if self.plat_name_supplied else None) + # XXX switch to this alternate implementation for non-pure: + if not self.py_limited_api: + assert tag == supported_tags[0], "%s != %s" % (tag, supported_tags[0]) + assert tag in supported_tags, "would build wheel with unsupported tag {}".format(tag) + return tag + + def run(self): + build_scripts = self.reinitialize_command('build_scripts') + build_scripts.executable = 'python' + build_scripts.force = True + + build_ext = self.reinitialize_command('build_ext') + build_ext.inplace = False + + if not self.skip_build: + self.run_command('build') + + install = self.reinitialize_command('install', + reinit_subcommands=True) + install.root = self.bdist_dir + install.compile = False + install.skip_build = self.skip_build + install.warn_dir = False + + # A wheel without setuptools scripts is more cross-platform. + # Use the (undocumented) `no_ep` option to setuptools' + # install_scripts command to avoid creating entry point scripts. + install_scripts = self.reinitialize_command('install_scripts') + install_scripts.no_ep = True + + # Use a custom scheme for the archive, because we have to decide + # at installation time which scheme to use. + for key in ('headers', 'scripts', 'data', 'purelib', 'platlib'): + setattr(install, + 'install_' + key, + os.path.join(self.data_dir, key)) + + basedir_observed = '' + + if os.name == 'nt': + # win32 barfs if any of these are ''; could be '.'? + # (distutils.command.install:change_roots bug) + basedir_observed = os.path.normpath(os.path.join(self.data_dir, '..')) + self.install_libbase = self.install_lib = basedir_observed + + setattr(install, + 'install_purelib' if self.root_is_pure else 'install_platlib', + basedir_observed) + + logger.info("installing to %s", self.bdist_dir) + + self.run_command('install') + + impl_tag, abi_tag, plat_tag = self.get_tag() + archive_basename = "{}-{}-{}-{}".format(self.wheel_dist_name, impl_tag, abi_tag, plat_tag) + if not self.relative: + archive_root = self.bdist_dir + else: + archive_root = os.path.join( + self.bdist_dir, + self._ensure_relative(install.install_base)) + + self.set_undefined_options('install_egg_info', ('target', 'egginfo_dir')) + distinfo_dirname = '{}-{}.dist-info'.format( + safer_name(self.distribution.get_name()), + safer_version(self.distribution.get_version())) + distinfo_dir = os.path.join(self.bdist_dir, distinfo_dirname) + self.egg2dist(self.egginfo_dir, distinfo_dir) + + self.write_wheelfile(distinfo_dir) + + # Make the archive + if not os.path.exists(self.dist_dir): + os.makedirs(self.dist_dir) + + wheel_path = os.path.join(self.dist_dir, archive_basename + '.whl') + with WheelFile(wheel_path, 'w', self.compression) as wf: + wf.write_files(archive_root) + + # Add to 'Distribution.dist_files' so that the "upload" command works + getattr(self.distribution, 'dist_files', []).append( + ('bdist_wheel', get_python_version(), wheel_path)) + + if not self.keep_temp: + logger.info('removing %s', self.bdist_dir) + if not self.dry_run: + rmtree(self.bdist_dir, onerror=remove_readonly) + + def write_wheelfile(self, wheelfile_base, generator='bdist_wheel (' + wheel_version + ')'): + from email.message import Message + msg = Message() + msg['Wheel-Version'] = '1.0' # of the spec + msg['Generator'] = generator + msg['Root-Is-Purelib'] = str(self.root_is_pure).lower() + if self.build_number is not None: + msg['Build'] = self.build_number + + # Doesn't work for bdist_wininst + impl_tag, abi_tag, plat_tag = self.get_tag() + for impl in impl_tag.split('.'): + for abi in abi_tag.split('.'): + for plat in plat_tag.split('.'): + msg['Tag'] = '-'.join((impl, abi, plat)) + + wheelfile_path = os.path.join(wheelfile_base, 'WHEEL') + logger.info('creating %s', wheelfile_path) + with open(wheelfile_path, 'w') as f: + Generator(f, maxheaderlen=0).flatten(msg) + + def _ensure_relative(self, path): + # copied from dir_util, deleted + drive, path = os.path.splitdrive(path) + if path[0:1] == os.sep: + path = drive + path[1:] + return path + + @property + def license_paths(self): + metadata = self.distribution.get_option_dict('metadata') + files = set() + patterns = sorted({ + option for option in metadata.get('license_files', ('', ''))[1].split() + }) + + if 'license_file' in metadata: + warn('The "license_file" option is deprecated. Use "license_files" instead.', + DeprecationWarning) + files.add(metadata['license_file'][1]) + + if 'license_file' not in metadata and 'license_files' not in metadata: + patterns = ('LICEN[CS]E*', 'COPYING*', 'NOTICE*', 'AUTHORS*') + + for pattern in patterns: + for path in iglob(pattern): + if path not in files and os.path.isfile(path): + logger.info('adding license file "%s" (matched pattern "%s")', path, pattern) + files.add(path) + + return files + + def egg2dist(self, egginfo_path, distinfo_path): + """Convert an .egg-info directory into a .dist-info directory""" + def adios(p): + """Appropriately delete directory, file or link.""" + if os.path.exists(p) and not os.path.islink(p) and os.path.isdir(p): + shutil.rmtree(p) + elif os.path.exists(p): + os.unlink(p) + + adios(distinfo_path) + + if not os.path.exists(egginfo_path): + # There is no egg-info. This is probably because the egg-info + # file/directory is not named matching the distribution name used + # to name the archive file. Check for this case and report + # accordingly. + import glob + pat = os.path.join(os.path.dirname(egginfo_path), '*.egg-info') + possible = glob.glob(pat) + err = "Egg metadata expected at %s but not found" % (egginfo_path,) + if possible: + alt = os.path.basename(possible[0]) + err += " (%s found - possible misnamed archive file?)" % (alt,) + + raise ValueError(err) + + if os.path.isfile(egginfo_path): + # .egg-info is a single file + pkginfo_path = egginfo_path + pkg_info = pkginfo_to_metadata(egginfo_path, egginfo_path) + os.mkdir(distinfo_path) + else: + # .egg-info is a directory + pkginfo_path = os.path.join(egginfo_path, 'PKG-INFO') + pkg_info = pkginfo_to_metadata(egginfo_path, pkginfo_path) + + # ignore common egg metadata that is useless to wheel + shutil.copytree(egginfo_path, distinfo_path, + ignore=lambda x, y: {'PKG-INFO', 'requires.txt', 'SOURCES.txt', + 'not-zip-safe'} + ) + + # delete dependency_links if it is only whitespace + dependency_links_path = os.path.join(distinfo_path, 'dependency_links.txt') + with open(dependency_links_path, 'r') as dependency_links_file: + dependency_links = dependency_links_file.read().strip() + if not dependency_links: + adios(dependency_links_path) + + write_pkg_info(os.path.join(distinfo_path, 'METADATA'), pkg_info) + + for license_path in self.license_paths: + filename = os.path.basename(license_path) + shutil.copy(license_path, os.path.join(distinfo_path, filename)) + + adios(egginfo_path) diff --git a/venv/Lib/site-packages/wheel/cli/__init__.py b/venv/Lib/site-packages/wheel/cli/__init__.py new file mode 100644 index 00000000..95740bfb --- /dev/null +++ b/venv/Lib/site-packages/wheel/cli/__init__.py @@ -0,0 +1,88 @@ +""" +Wheel command-line utility. +""" + +from __future__ import print_function + +import argparse +import os +import sys + + +def require_pkgresources(name): + try: + import pkg_resources # noqa: F401 + except ImportError: + raise RuntimeError("'{0}' needs pkg_resources (part of setuptools).".format(name)) + + +class WheelError(Exception): + pass + + +def unpack_f(args): + from .unpack import unpack + unpack(args.wheelfile, args.dest) + + +def pack_f(args): + from .pack import pack + pack(args.directory, args.dest_dir, args.build_number) + + +def convert_f(args): + from .convert import convert + convert(args.files, args.dest_dir, args.verbose) + + +def version_f(args): + from .. import __version__ + print("wheel %s" % __version__) + + +def parser(): + p = argparse.ArgumentParser() + s = p.add_subparsers(help="commands") + + unpack_parser = s.add_parser('unpack', help='Unpack wheel') + unpack_parser.add_argument('--dest', '-d', help='Destination directory', + default='.') + unpack_parser.add_argument('wheelfile', help='Wheel file') + unpack_parser.set_defaults(func=unpack_f) + + repack_parser = s.add_parser('pack', help='Repack wheel') + repack_parser.add_argument('directory', help='Root directory of the unpacked wheel') + repack_parser.add_argument('--dest-dir', '-d', default=os.path.curdir, + help="Directory to store the wheel (default %(default)s)") + repack_parser.add_argument('--build-number', help="Build tag to use in the wheel name") + repack_parser.set_defaults(func=pack_f) + + convert_parser = s.add_parser('convert', help='Convert egg or wininst to wheel') + convert_parser.add_argument('files', nargs='*', help='Files to convert') + convert_parser.add_argument('--dest-dir', '-d', default=os.path.curdir, + help="Directory to store wheels (default %(default)s)") + convert_parser.add_argument('--verbose', '-v', action='store_true') + convert_parser.set_defaults(func=convert_f) + + version_parser = s.add_parser('version', help='Print version and exit') + version_parser.set_defaults(func=version_f) + + help_parser = s.add_parser('help', help='Show this help') + help_parser.set_defaults(func=lambda args: p.print_help()) + + return p + + +def main(): + p = parser() + args = p.parse_args() + if not hasattr(args, 'func'): + p.print_help() + else: + try: + args.func(args) + return 0 + except WheelError as e: + print(e, file=sys.stderr) + + return 1 diff --git a/venv/Lib/site-packages/wheel/cli/convert.py b/venv/Lib/site-packages/wheel/cli/convert.py new file mode 100644 index 00000000..154f1b1e --- /dev/null +++ b/venv/Lib/site-packages/wheel/cli/convert.py @@ -0,0 +1,269 @@ +import os.path +import re +import shutil +import sys +import tempfile +import zipfile +from distutils import dist +from glob import iglob + +from ..bdist_wheel import bdist_wheel +from ..wheelfile import WheelFile +from . import WheelError, require_pkgresources + +egg_info_re = re.compile(r''' + (?P.+?)-(?P.+?) + (-(?Ppy\d\.\d+) + (-(?P.+?))? + )?.egg$''', re.VERBOSE) + + +class _bdist_wheel_tag(bdist_wheel): + # allow the client to override the default generated wheel tag + # The default bdist_wheel implementation uses python and abi tags + # of the running python process. This is not suitable for + # generating/repackaging prebuild binaries. + + full_tag_supplied = False + full_tag = None # None or a (pytag, soabitag, plattag) triple + + def get_tag(self): + if self.full_tag_supplied and self.full_tag is not None: + return self.full_tag + else: + return bdist_wheel.get_tag(self) + + +def egg2wheel(egg_path, dest_dir): + filename = os.path.basename(egg_path) + match = egg_info_re.match(filename) + if not match: + raise WheelError('Invalid egg file name: {}'.format(filename)) + + egg_info = match.groupdict() + dir = tempfile.mkdtemp(suffix="_e2w") + if os.path.isfile(egg_path): + # assume we have a bdist_egg otherwise + with zipfile.ZipFile(egg_path) as egg: + egg.extractall(dir) + else: + # support buildout-style installed eggs directories + for pth in os.listdir(egg_path): + src = os.path.join(egg_path, pth) + if os.path.isfile(src): + shutil.copy2(src, dir) + else: + shutil.copytree(src, os.path.join(dir, pth)) + + pyver = egg_info['pyver'] + if pyver: + pyver = egg_info['pyver'] = pyver.replace('.', '') + + arch = (egg_info['arch'] or 'any').replace('.', '_').replace('-', '_') + + # assume all binary eggs are for CPython + abi = 'cp' + pyver[2:] if arch != 'any' else 'none' + + root_is_purelib = egg_info['arch'] is None + if root_is_purelib: + bw = bdist_wheel(dist.Distribution()) + else: + bw = _bdist_wheel_tag(dist.Distribution()) + + bw.root_is_pure = root_is_purelib + bw.python_tag = pyver + bw.plat_name_supplied = True + bw.plat_name = egg_info['arch'] or 'any' + if not root_is_purelib: + bw.full_tag_supplied = True + bw.full_tag = (pyver, abi, arch) + + dist_info_dir = os.path.join(dir, '{name}-{ver}.dist-info'.format(**egg_info)) + bw.egg2dist(os.path.join(dir, 'EGG-INFO'), dist_info_dir) + bw.write_wheelfile(dist_info_dir, generator='egg2wheel') + wheel_name = '{name}-{ver}-{pyver}-{}-{}.whl'.format(abi, arch, **egg_info) + with WheelFile(os.path.join(dest_dir, wheel_name), 'w') as wf: + wf.write_files(dir) + + shutil.rmtree(dir) + + +def parse_wininst_info(wininfo_name, egginfo_name): + """Extract metadata from filenames. + + Extracts the 4 metadataitems needed (name, version, pyversion, arch) from + the installer filename and the name of the egg-info directory embedded in + the zipfile (if any). + + The egginfo filename has the format:: + + name-ver(-pyver)(-arch).egg-info + + The installer filename has the format:: + + name-ver.arch(-pyver).exe + + Some things to note: + + 1. The installer filename is not definitive. An installer can be renamed + and work perfectly well as an installer. So more reliable data should + be used whenever possible. + 2. The egg-info data should be preferred for the name and version, because + these come straight from the distutils metadata, and are mandatory. + 3. The pyver from the egg-info data should be ignored, as it is + constructed from the version of Python used to build the installer, + which is irrelevant - the installer filename is correct here (even to + the point that when it's not there, any version is implied). + 4. The architecture must be taken from the installer filename, as it is + not included in the egg-info data. + 5. Architecture-neutral installers still have an architecture because the + installer format itself (being executable) is architecture-specific. We + should therefore ignore the architecture if the content is pure-python. + """ + + egginfo = None + if egginfo_name: + egginfo = egg_info_re.search(egginfo_name) + if not egginfo: + raise ValueError("Egg info filename %s is not valid" % (egginfo_name,)) + + # Parse the wininst filename + # 1. Distribution name (up to the first '-') + w_name, sep, rest = wininfo_name.partition('-') + if not sep: + raise ValueError("Installer filename %s is not valid" % (wininfo_name,)) + + # Strip '.exe' + rest = rest[:-4] + # 2. Python version (from the last '-', must start with 'py') + rest2, sep, w_pyver = rest.rpartition('-') + if sep and w_pyver.startswith('py'): + rest = rest2 + w_pyver = w_pyver.replace('.', '') + else: + # Not version specific - use py2.py3. While it is possible that + # pure-Python code is not compatible with both Python 2 and 3, there + # is no way of knowing from the wininst format, so we assume the best + # here (the user can always manually rename the wheel to be more + # restrictive if needed). + w_pyver = 'py2.py3' + # 3. Version and architecture + w_ver, sep, w_arch = rest.rpartition('.') + if not sep: + raise ValueError("Installer filename %s is not valid" % (wininfo_name,)) + + if egginfo: + w_name = egginfo.group('name') + w_ver = egginfo.group('ver') + + return {'name': w_name, 'ver': w_ver, 'arch': w_arch, 'pyver': w_pyver} + + +def wininst2wheel(path, dest_dir): + with zipfile.ZipFile(path) as bdw: + # Search for egg-info in the archive + egginfo_name = None + for filename in bdw.namelist(): + if '.egg-info' in filename: + egginfo_name = filename + break + + info = parse_wininst_info(os.path.basename(path), egginfo_name) + + root_is_purelib = True + for zipinfo in bdw.infolist(): + if zipinfo.filename.startswith('PLATLIB'): + root_is_purelib = False + break + if root_is_purelib: + paths = {'purelib': ''} + else: + paths = {'platlib': ''} + + dist_info = "%(name)s-%(ver)s" % info + datadir = "%s.data/" % dist_info + + # rewrite paths to trick ZipFile into extracting an egg + # XXX grab wininst .ini - between .exe, padding, and first zip file. + members = [] + egginfo_name = '' + for zipinfo in bdw.infolist(): + key, basename = zipinfo.filename.split('/', 1) + key = key.lower() + basepath = paths.get(key, None) + if basepath is None: + basepath = datadir + key.lower() + '/' + oldname = zipinfo.filename + newname = basepath + basename + zipinfo.filename = newname + del bdw.NameToInfo[oldname] + bdw.NameToInfo[newname] = zipinfo + # Collect member names, but omit '' (from an entry like "PLATLIB/" + if newname: + members.append(newname) + # Remember egg-info name for the egg2dist call below + if not egginfo_name: + if newname.endswith('.egg-info'): + egginfo_name = newname + elif '.egg-info/' in newname: + egginfo_name, sep, _ = newname.rpartition('/') + dir = tempfile.mkdtemp(suffix="_b2w") + bdw.extractall(dir, members) + + # egg2wheel + abi = 'none' + pyver = info['pyver'] + arch = (info['arch'] or 'any').replace('.', '_').replace('-', '_') + # Wininst installers always have arch even if they are not + # architecture-specific (because the format itself is). + # So, assume the content is architecture-neutral if root is purelib. + if root_is_purelib: + arch = 'any' + # If the installer is architecture-specific, it's almost certainly also + # CPython-specific. + if arch != 'any': + pyver = pyver.replace('py', 'cp') + wheel_name = '-'.join((dist_info, pyver, abi, arch)) + if root_is_purelib: + bw = bdist_wheel(dist.Distribution()) + else: + bw = _bdist_wheel_tag(dist.Distribution()) + + bw.root_is_pure = root_is_purelib + bw.python_tag = pyver + bw.plat_name_supplied = True + bw.plat_name = info['arch'] or 'any' + + if not root_is_purelib: + bw.full_tag_supplied = True + bw.full_tag = (pyver, abi, arch) + + dist_info_dir = os.path.join(dir, '%s.dist-info' % dist_info) + bw.egg2dist(os.path.join(dir, egginfo_name), dist_info_dir) + bw.write_wheelfile(dist_info_dir, generator='wininst2wheel') + + wheel_path = os.path.join(dest_dir, wheel_name) + with WheelFile(wheel_path, 'w') as wf: + wf.write_files(dir) + + shutil.rmtree(dir) + + +def convert(files, dest_dir, verbose): + # Only support wheel convert if pkg_resources is present + require_pkgresources('wheel convert') + + for pat in files: + for installer in iglob(pat): + if os.path.splitext(installer)[1] == '.egg': + conv = egg2wheel + else: + conv = wininst2wheel + + if verbose: + print("{}... ".format(installer)) + sys.stdout.flush() + + conv(installer, dest_dir) + if verbose: + print("OK") diff --git a/venv/Lib/site-packages/wheel/cli/install.py b/venv/Lib/site-packages/wheel/cli/install.py new file mode 100644 index 00000000..e69de29b diff --git a/venv/Lib/site-packages/wheel/cli/pack.py b/venv/Lib/site-packages/wheel/cli/pack.py new file mode 100644 index 00000000..1e77fdbd --- /dev/null +++ b/venv/Lib/site-packages/wheel/cli/pack.py @@ -0,0 +1,79 @@ +from __future__ import print_function + +import os.path +import re +import sys + +from wheel.cli import WheelError +from wheel.wheelfile import WheelFile + +DIST_INFO_RE = re.compile(r"^(?P(?P.+?)-(?P\d.*?))\.dist-info$") +BUILD_NUM_RE = re.compile(br'Build: (\d\w*)$') + + +def pack(directory, dest_dir, build_number): + """Repack a previously unpacked wheel directory into a new wheel file. + + The .dist-info/WHEEL file must contain one or more tags so that the target + wheel file name can be determined. + + :param directory: The unpacked wheel directory + :param dest_dir: Destination directory (defaults to the current directory) + """ + # Find the .dist-info directory + dist_info_dirs = [fn for fn in os.listdir(directory) + if os.path.isdir(os.path.join(directory, fn)) and DIST_INFO_RE.match(fn)] + if len(dist_info_dirs) > 1: + raise WheelError('Multiple .dist-info directories found in {}'.format(directory)) + elif not dist_info_dirs: + raise WheelError('No .dist-info directories found in {}'.format(directory)) + + # Determine the target wheel filename + dist_info_dir = dist_info_dirs[0] + name_version = DIST_INFO_RE.match(dist_info_dir).group('namever') + + # Read the tags and the existing build number from .dist-info/WHEEL + existing_build_number = None + wheel_file_path = os.path.join(directory, dist_info_dir, 'WHEEL') + with open(wheel_file_path) as f: + tags = [] + for line in f: + if line.startswith('Tag: '): + tags.append(line.split(' ')[1].rstrip()) + elif line.startswith('Build: '): + existing_build_number = line.split(' ')[1].rstrip() + + if not tags: + raise WheelError('No tags present in {}/WHEEL; cannot determine target wheel filename' + .format(dist_info_dir)) + + # Set the wheel file name and add/replace/remove the Build tag in .dist-info/WHEEL + build_number = build_number if build_number is not None else existing_build_number + if build_number is not None: + if build_number: + name_version += '-' + build_number + + if build_number != existing_build_number: + replacement = ('Build: %s\r\n' % build_number).encode('ascii') if build_number else b'' + with open(wheel_file_path, 'rb+') as f: + wheel_file_content = f.read() + if not BUILD_NUM_RE.subn(replacement, wheel_file_content)[1]: + wheel_file_content += replacement + + f.truncate() + f.write(wheel_file_content) + + # Reassemble the tags for the wheel file + impls = sorted({tag.split('-')[0] for tag in tags}) + abivers = sorted({tag.split('-')[1] for tag in tags}) + platforms = sorted({tag.split('-')[2] for tag in tags}) + tagline = '-'.join(['.'.join(impls), '.'.join(abivers), '.'.join(platforms)]) + + # Repack the wheel + wheel_path = os.path.join(dest_dir, '{}-{}.whl'.format(name_version, tagline)) + with WheelFile(wheel_path, 'w') as wf: + print("Repacking wheel as {}...".format(wheel_path), end='') + sys.stdout.flush() + wf.write_files(directory) + + print('OK') diff --git a/venv/Lib/site-packages/wheel/cli/unpack.py b/venv/Lib/site-packages/wheel/cli/unpack.py new file mode 100644 index 00000000..2e9857a3 --- /dev/null +++ b/venv/Lib/site-packages/wheel/cli/unpack.py @@ -0,0 +1,25 @@ +from __future__ import print_function + +import os.path +import sys + +from ..wheelfile import WheelFile + + +def unpack(path, dest='.'): + """Unpack a wheel. + + Wheel content will be unpacked to {dest}/{name}-{ver}, where {name} + is the package name and {ver} its version. + + :param path: The path to the wheel. + :param dest: Destination directory (default to current directory). + """ + with WheelFile(path) as wf: + namever = wf.parsed_filename.group('namever') + destination = os.path.join(dest, namever) + print("Unpacking to: {}...".format(destination), end='') + sys.stdout.flush() + wf.extractall(destination) + + print('OK') diff --git a/venv/Lib/site-packages/wheel/macosx_libfile.py b/venv/Lib/site-packages/wheel/macosx_libfile.py new file mode 100644 index 00000000..a9036886 --- /dev/null +++ b/venv/Lib/site-packages/wheel/macosx_libfile.py @@ -0,0 +1,341 @@ +""" +This module contains function to analyse dynamic library +headers to extract system information + +Currently only for MacOSX + +Library file on macosx system starts with Mach-O or Fat field. +This can be distinguish by first 32 bites and it is called magic number. +Proper value of magic number is with suffix _MAGIC. Suffix _CIGAM means +reversed bytes order. +Both fields can occur in two types: 32 and 64 bytes. + +FAT field inform that this library contains few version of library +(typically for different types version). It contains +information where Mach-O headers starts. + +Each section started with Mach-O header contains one library +(So if file starts with this field it contains only one version). + +After filed Mach-O there are section fields. +Each of them starts with two fields: +cmd - magic number for this command +cmdsize - total size occupied by this section information. + +In this case only sections LC_VERSION_MIN_MACOSX (for macosx 10.13 and earlier) +and LC_BUILD_VERSION (for macosx 10.14 and newer) are interesting, +because them contains information about minimal system version. + +Important remarks: +- For fat files this implementation looks for maximum number version. + It not check if it is 32 or 64 and do not compare it with currently builded package. + So it is possible to false report higher version that needed. +- All structures signatures are taken form macosx header files. +- I think that binary format will be more stable than `otool` output. + and if apple introduce some changes both implementation will need to be updated. +""" + +import ctypes +import sys + +"""here the needed const and struct from mach-o header files""" + +FAT_MAGIC = 0xcafebabe +FAT_CIGAM = 0xbebafeca +FAT_MAGIC_64 = 0xcafebabf +FAT_CIGAM_64 = 0xbfbafeca +MH_MAGIC = 0xfeedface +MH_CIGAM = 0xcefaedfe +MH_MAGIC_64 = 0xfeedfacf +MH_CIGAM_64 = 0xcffaedfe + +LC_VERSION_MIN_MACOSX = 0x24 +LC_BUILD_VERSION = 0x32 + + +mach_header_fields = [ + ("magic", ctypes.c_uint32), ("cputype", ctypes.c_int), + ("cpusubtype", ctypes.c_int), ("filetype", ctypes.c_uint32), + ("ncmds", ctypes.c_uint32), ("sizeofcmds", ctypes.c_uint32), + ("flags", ctypes.c_uint32) + ] +""" +struct mach_header { + uint32_t magic; /* mach magic number identifier */ + cpu_type_t cputype; /* cpu specifier */ + cpu_subtype_t cpusubtype; /* machine specifier */ + uint32_t filetype; /* type of file */ + uint32_t ncmds; /* number of load commands */ + uint32_t sizeofcmds; /* the size of all the load commands */ + uint32_t flags; /* flags */ +}; +typedef integer_t cpu_type_t; +typedef integer_t cpu_subtype_t; +""" + +mach_header_fields_64 = mach_header_fields + [("reserved", ctypes.c_uint32)] +""" +struct mach_header_64 { + uint32_t magic; /* mach magic number identifier */ + cpu_type_t cputype; /* cpu specifier */ + cpu_subtype_t cpusubtype; /* machine specifier */ + uint32_t filetype; /* type of file */ + uint32_t ncmds; /* number of load commands */ + uint32_t sizeofcmds; /* the size of all the load commands */ + uint32_t flags; /* flags */ + uint32_t reserved; /* reserved */ +}; +""" + +fat_header_fields = [("magic", ctypes.c_uint32), ("nfat_arch", ctypes.c_uint32)] +""" +struct fat_header { + uint32_t magic; /* FAT_MAGIC or FAT_MAGIC_64 */ + uint32_t nfat_arch; /* number of structs that follow */ +}; +""" + +fat_arch_fields = [ + ("cputype", ctypes.c_int), ("cpusubtype", ctypes.c_int), + ("offset", ctypes.c_uint32), ("size", ctypes.c_uint32), + ("align", ctypes.c_uint32) +] +""" +struct fat_arch { + cpu_type_t cputype; /* cpu specifier (int) */ + cpu_subtype_t cpusubtype; /* machine specifier (int) */ + uint32_t offset; /* file offset to this object file */ + uint32_t size; /* size of this object file */ + uint32_t align; /* alignment as a power of 2 */ +}; +""" + +fat_arch_64_fields = [ + ("cputype", ctypes.c_int), ("cpusubtype", ctypes.c_int), + ("offset", ctypes.c_uint64), ("size", ctypes.c_uint64), + ("align", ctypes.c_uint32), ("reserved", ctypes.c_uint32) +] +""" +struct fat_arch_64 { + cpu_type_t cputype; /* cpu specifier (int) */ + cpu_subtype_t cpusubtype; /* machine specifier (int) */ + uint64_t offset; /* file offset to this object file */ + uint64_t size; /* size of this object file */ + uint32_t align; /* alignment as a power of 2 */ + uint32_t reserved; /* reserved */ +}; +""" + +segment_base_fields = [("cmd", ctypes.c_uint32), ("cmdsize", ctypes.c_uint32)] +"""base for reading segment info""" + +segment_command_fields = [ + ("cmd", ctypes.c_uint32), ("cmdsize", ctypes.c_uint32), + ("segname", ctypes.c_char * 16), ("vmaddr", ctypes.c_uint32), + ("vmsize", ctypes.c_uint32), ("fileoff", ctypes.c_uint32), + ("filesize", ctypes.c_uint32), ("maxprot", ctypes.c_int), + ("initprot", ctypes.c_int), ("nsects", ctypes.c_uint32), + ("flags", ctypes.c_uint32), + ] +""" +struct segment_command { /* for 32-bit architectures */ + uint32_t cmd; /* LC_SEGMENT */ + uint32_t cmdsize; /* includes sizeof section structs */ + char segname[16]; /* segment name */ + uint32_t vmaddr; /* memory address of this segment */ + uint32_t vmsize; /* memory size of this segment */ + uint32_t fileoff; /* file offset of this segment */ + uint32_t filesize; /* amount to map from the file */ + vm_prot_t maxprot; /* maximum VM protection */ + vm_prot_t initprot; /* initial VM protection */ + uint32_t nsects; /* number of sections in segment */ + uint32_t flags; /* flags */ +}; +typedef int vm_prot_t; +""" + +segment_command_fields_64 = [ + ("cmd", ctypes.c_uint32), ("cmdsize", ctypes.c_uint32), + ("segname", ctypes.c_char * 16), ("vmaddr", ctypes.c_uint64), + ("vmsize", ctypes.c_uint64), ("fileoff", ctypes.c_uint64), + ("filesize", ctypes.c_uint64), ("maxprot", ctypes.c_int), + ("initprot", ctypes.c_int), ("nsects", ctypes.c_uint32), + ("flags", ctypes.c_uint32), + ] +""" +struct segment_command_64 { /* for 64-bit architectures */ + uint32_t cmd; /* LC_SEGMENT_64 */ + uint32_t cmdsize; /* includes sizeof section_64 structs */ + char segname[16]; /* segment name */ + uint64_t vmaddr; /* memory address of this segment */ + uint64_t vmsize; /* memory size of this segment */ + uint64_t fileoff; /* file offset of this segment */ + uint64_t filesize; /* amount to map from the file */ + vm_prot_t maxprot; /* maximum VM protection */ + vm_prot_t initprot; /* initial VM protection */ + uint32_t nsects; /* number of sections in segment */ + uint32_t flags; /* flags */ +}; +""" + +version_min_command_fields = segment_base_fields + \ + [("version", ctypes.c_uint32), ("sdk", ctypes.c_uint32)] +""" +struct version_min_command { + uint32_t cmd; /* LC_VERSION_MIN_MACOSX or + LC_VERSION_MIN_IPHONEOS or + LC_VERSION_MIN_WATCHOS or + LC_VERSION_MIN_TVOS */ + uint32_t cmdsize; /* sizeof(struct min_version_command) */ + uint32_t version; /* X.Y.Z is encoded in nibbles xxxx.yy.zz */ + uint32_t sdk; /* X.Y.Z is encoded in nibbles xxxx.yy.zz */ +}; +""" + +build_version_command_fields = segment_base_fields + \ + [("platform", ctypes.c_uint32), ("minos", ctypes.c_uint32), + ("sdk", ctypes.c_uint32), ("ntools", ctypes.c_uint32)] +""" +struct build_version_command { + uint32_t cmd; /* LC_BUILD_VERSION */ + uint32_t cmdsize; /* sizeof(struct build_version_command) plus */ + /* ntools * sizeof(struct build_tool_version) */ + uint32_t platform; /* platform */ + uint32_t minos; /* X.Y.Z is encoded in nibbles xxxx.yy.zz */ + uint32_t sdk; /* X.Y.Z is encoded in nibbles xxxx.yy.zz */ + uint32_t ntools; /* number of tool entries following this */ +}; +""" + + +def swap32(x): + return (((x << 24) & 0xFF000000) | + ((x << 8) & 0x00FF0000) | + ((x >> 8) & 0x0000FF00) | + ((x >> 24) & 0x000000FF)) + + +def get_base_class_and_magic_number(lib_file, seek=None): + if seek is None: + seek = lib_file.tell() + else: + lib_file.seek(seek) + magic_number = ctypes.c_uint32.from_buffer_copy( + lib_file.read(ctypes.sizeof(ctypes.c_uint32))).value + + # Handle wrong byte order + if magic_number in [FAT_CIGAM, FAT_CIGAM_64, MH_CIGAM, MH_CIGAM_64]: + if sys.byteorder == "little": + BaseClass = ctypes.BigEndianStructure + else: + BaseClass = ctypes.LittleEndianStructure + + magic_number = swap32(magic_number) + else: + BaseClass = ctypes.Structure + + lib_file.seek(seek) + return BaseClass, magic_number + + +def read_data(struct_class, lib_file): + return struct_class.from_buffer_copy(lib_file.read( + ctypes.sizeof(struct_class))) + + +def extract_macosx_min_system_version(path_to_lib): + with open(path_to_lib, "rb") as lib_file: + BaseClass, magic_number = get_base_class_and_magic_number(lib_file, 0) + if magic_number not in [FAT_MAGIC, FAT_MAGIC_64, MH_MAGIC, MH_MAGIC_64]: + return + + if magic_number in [FAT_MAGIC, FAT_CIGAM_64]: + class FatHeader(BaseClass): + _fields_ = fat_header_fields + + fat_header = read_data(FatHeader, lib_file) + if magic_number == FAT_MAGIC: + + class FatArch(BaseClass): + _fields_ = fat_arch_fields + else: + + class FatArch(BaseClass): + _fields_ = fat_arch_64_fields + + fat_arch_list = [read_data(FatArch, lib_file) for _ in range(fat_header.nfat_arch)] + + versions_list = [] + for el in fat_arch_list: + try: + version = read_mach_header(lib_file, el.offset) + if version is not None: + versions_list.append(version) + except ValueError: + pass + + if len(versions_list) > 0: + return max(versions_list) + else: + return None + + else: + try: + return read_mach_header(lib_file, 0) + except ValueError: + """when some error during read library files""" + return None + + +def read_mach_header(lib_file, seek=None): + """ + This funcition parse mach-O header and extract + information about minimal system version + + :param lib_file: reference to opened library file with pointer + """ + if seek is not None: + lib_file.seek(seek) + base_class, magic_number = get_base_class_and_magic_number(lib_file) + arch = "32" if magic_number == MH_MAGIC else "64" + + class SegmentBase(base_class): + _fields_ = segment_base_fields + + if arch == "32": + + class MachHeader(base_class): + _fields_ = mach_header_fields + + else: + + class MachHeader(base_class): + _fields_ = mach_header_fields_64 + + mach_header = read_data(MachHeader, lib_file) + for _i in range(mach_header.ncmds): + pos = lib_file.tell() + segment_base = read_data(SegmentBase, lib_file) + lib_file.seek(pos) + if segment_base.cmd == LC_VERSION_MIN_MACOSX: + class VersionMinCommand(base_class): + _fields_ = version_min_command_fields + + version_info = read_data(VersionMinCommand, lib_file) + return parse_version(version_info.version) + elif segment_base.cmd == LC_BUILD_VERSION: + class VersionBuild(base_class): + _fields_ = build_version_command_fields + + version_info = read_data(VersionBuild, lib_file) + return parse_version(version_info.minos) + else: + lib_file.seek(pos + segment_base.cmdsize) + continue + + +def parse_version(version): + x = (version & 0xffff0000) >> 16 + y = (version & 0x0000ff00) >> 8 + z = (version & 0x000000ff) + return x, y, z diff --git a/venv/Lib/site-packages/wheel/metadata.py b/venv/Lib/site-packages/wheel/metadata.py new file mode 100644 index 00000000..bbf57a77 --- /dev/null +++ b/venv/Lib/site-packages/wheel/metadata.py @@ -0,0 +1,138 @@ +""" +Tools for converting old- to new-style metadata. +""" + +import os.path +import re +import textwrap + +import pkg_resources + +from .pkginfo import read_pkg_info + +# Support markers syntax with the extra at the end only +EXTRA_RE = re.compile( + r"""^(?P.*?)(;\s*(?P.*?)(extra == '(?P.*?)')?)$""") + + +def requires_to_requires_dist(requirement): + """Return the version specifier for a requirement in PEP 345/566 fashion.""" + if getattr(requirement, 'url', None): + return " @ " + requirement.url + + requires_dist = [] + for op, ver in requirement.specs: + requires_dist.append(op + ver) + if not requires_dist: + return '' + return " (%s)" % ','.join(sorted(requires_dist)) + + +def convert_requirements(requirements): + """Yield Requires-Dist: strings for parsed requirements strings.""" + for req in requirements: + parsed_requirement = pkg_resources.Requirement.parse(req) + spec = requires_to_requires_dist(parsed_requirement) + extras = ",".join(sorted(parsed_requirement.extras)) + if extras: + extras = "[%s]" % extras + yield (parsed_requirement.project_name + extras + spec) + + +def generate_requirements(extras_require): + """ + Convert requirements from a setup()-style dictionary to ('Requires-Dist', 'requirement') + and ('Provides-Extra', 'extra') tuples. + + extras_require is a dictionary of {extra: [requirements]} as passed to setup(), + using the empty extra {'': [requirements]} to hold install_requires. + """ + for extra, depends in extras_require.items(): + condition = '' + extra = extra or '' + if ':' in extra: # setuptools extra:condition syntax + extra, condition = extra.split(':', 1) + + extra = pkg_resources.safe_extra(extra) + if extra: + yield 'Provides-Extra', extra + if condition: + condition = "(" + condition + ") and " + condition += "extra == '%s'" % extra + + if condition: + condition = ' ; ' + condition + + for new_req in convert_requirements(depends): + yield 'Requires-Dist', new_req + condition + + +def pkginfo_to_metadata(egg_info_path, pkginfo_path): + """ + Convert .egg-info directory with PKG-INFO to the Metadata 2.1 format + """ + pkg_info = read_pkg_info(pkginfo_path) + pkg_info.replace_header('Metadata-Version', '2.1') + # Those will be regenerated from `requires.txt`. + del pkg_info['Provides-Extra'] + del pkg_info['Requires-Dist'] + requires_path = os.path.join(egg_info_path, 'requires.txt') + if os.path.exists(requires_path): + with open(requires_path) as requires_file: + requires = requires_file.read() + + parsed_requirements = sorted(pkg_resources.split_sections(requires), + key=lambda x: x[0] or '') + for extra, reqs in parsed_requirements: + for key, value in generate_requirements({extra: reqs}): + if (key, value) not in pkg_info.items(): + pkg_info[key] = value + + description = pkg_info['Description'] + if description: + pkg_info.set_payload(dedent_description(pkg_info)) + del pkg_info['Description'] + + return pkg_info + + +def pkginfo_unicode(pkg_info, field): + """Hack to coax Unicode out of an email Message() - Python 3.3+""" + text = pkg_info[field] + field = field.lower() + if not isinstance(text, str): + for item in pkg_info.raw_items(): + if item[0].lower() == field: + text = item[1].encode('ascii', 'surrogateescape') \ + .decode('utf-8') + break + + return text + + +def dedent_description(pkg_info): + """ + Dedent and convert pkg_info['Description'] to Unicode. + """ + description = pkg_info['Description'] + + # Python 3 Unicode handling, sorta. + surrogates = False + if not isinstance(description, str): + surrogates = True + description = pkginfo_unicode(pkg_info, 'Description') + + description_lines = description.splitlines() + description_dedent = '\n'.join( + # if the first line of long_description is blank, + # the first line here will be indented. + (description_lines[0].lstrip(), + textwrap.dedent('\n'.join(description_lines[1:])), + '\n')) + + if surrogates: + description_dedent = description_dedent \ + .encode("utf8") \ + .decode("ascii", "surrogateescape") + + return description_dedent diff --git a/venv/Lib/site-packages/wheel/pep425tags.py b/venv/Lib/site-packages/wheel/pep425tags.py new file mode 100644 index 00000000..0c257636 --- /dev/null +++ b/venv/Lib/site-packages/wheel/pep425tags.py @@ -0,0 +1,261 @@ +"""Generate and work with PEP 425 Compatibility Tags.""" + +import distutils.util +import platform +import sys +import os +import sysconfig +import warnings + +from .macosx_libfile import extract_macosx_min_system_version + + +try: + from importlib.machinery import all_suffixes as get_all_suffixes +except ImportError: + from imp import get_suffixes + + def get_all_suffixes(): + return [suffix[0] for suffix in get_suffixes()] + + +def get_config_var(var): + try: + return sysconfig.get_config_var(var) + except IOError as e: # pip Issue #1074 + warnings.warn("{0}".format(e), RuntimeWarning) + return None + + +def get_abbr_impl(): + """Return abbreviated implementation name.""" + impl = platform.python_implementation() + if impl == 'PyPy': + return 'pp' + elif impl == 'Jython': + return 'jy' + elif impl == 'IronPython': + return 'ip' + elif impl == 'CPython': + return 'cp' + + raise LookupError('Unknown Python implementation: ' + impl) + + +def get_impl_ver(): + """Return implementation version.""" + impl_ver = get_config_var("py_version_nodot") + if not impl_ver: + impl_ver = ''.join(map(str, get_impl_version_info())) + return impl_ver + + +def get_impl_version_info(): + """Return sys.version_info-like tuple for use in decrementing the minor + version.""" + return sys.version_info[0], sys.version_info[1] + + +def get_flag(var, fallback, expected=True, warn=True): + """Use a fallback method for determining SOABI flags if the needed config + var is unset or unavailable.""" + val = get_config_var(var) + if val is None: + if warn: + warnings.warn("Config variable '{0}' is unset, Python ABI tag may " + "be incorrect".format(var), RuntimeWarning, 2) + return fallback() + return val == expected + + +def get_abi_tag(): + """Return the ABI tag based on SOABI (if available) or emulate SOABI + (CPython 2, PyPy).""" + soabi = get_config_var('SOABI') + impl = get_abbr_impl() + if not soabi and impl in ('cp', 'pp') and hasattr(sys, 'maxunicode'): + d = '' + m = '' + u = '' + if get_flag('Py_DEBUG', + lambda: hasattr(sys, 'gettotalrefcount'), + warn=(impl == 'cp')): + d = 'd' + if get_flag('WITH_PYMALLOC', + lambda: impl == 'cp', + warn=(impl == 'cp' and + sys.version_info < (3, 8))) \ + and sys.version_info < (3, 8): + m = 'm' + if get_flag('Py_UNICODE_SIZE', + lambda: sys.maxunicode == 0x10ffff, + expected=4, + warn=(impl == 'cp' and + sys.version_info < (3, 3))) \ + and sys.version_info < (3, 3): + u = 'u' + abi = '%s%s%s%s%s' % (impl, get_impl_ver(), d, m, u) + elif soabi and soabi.startswith('cpython-'): + abi = 'cp' + soabi.split('-')[1] + elif soabi: + abi = soabi.replace('.', '_').replace('-', '_') + else: + abi = None + return abi + + +def calculate_macosx_platform_tag(archive_root, platform_tag): + """ + Calculate proper macosx platform tag basing on files which are included to wheel + + Example platform tag `macosx-10.14-x86_64` + """ + prefix, base_version, suffix = platform_tag.split('-') + base_version = tuple([int(x) for x in base_version.split(".")]) + if len(base_version) >= 2: + base_version = base_version[0:2] + + assert len(base_version) == 2 + if "MACOSX_DEPLOYMENT_TARGET" in os.environ: + deploy_target = tuple([int(x) for x in os.environ[ + "MACOSX_DEPLOYMENT_TARGET"].split(".")]) + if len(deploy_target) >= 2: + deploy_target = deploy_target[0:2] + if deploy_target < base_version: + sys.stderr.write( + "[WARNING] MACOSX_DEPLOYMENT_TARGET is set to a lower value ({}) than the " + "version on which the Python interpreter was compiled ({}), and will be " + "ignored.\n".format('.'.join(str(x) for x in deploy_target), + '.'.join(str(x) for x in base_version)) + ) + else: + base_version = deploy_target + + assert len(base_version) == 2 + start_version = base_version + versions_dict = {} + for (dirpath, dirnames, filenames) in os.walk(archive_root): + for filename in filenames: + if filename.endswith('.dylib') or filename.endswith('.so'): + lib_path = os.path.join(dirpath, filename) + min_ver = extract_macosx_min_system_version(lib_path) + if min_ver is not None: + versions_dict[lib_path] = min_ver[0:2] + + if len(versions_dict) > 0: + base_version = max(base_version, max(versions_dict.values())) + + # macosx platform tag do not support minor bugfix release + fin_base_version = "_".join([str(x) for x in base_version]) + if start_version < base_version: + problematic_files = [k for k, v in versions_dict.items() if v > start_version] + problematic_files = "\n".join(problematic_files) + if len(problematic_files) == 1: + files_form = "this file" + else: + files_form = "these files" + error_message = \ + "[WARNING] This wheel needs a higher macOS version than {} " \ + "To silence this warning, set MACOSX_DEPLOYMENT_TARGET to at least " +\ + fin_base_version + " or recreate " + files_form + " with lower " \ + "MACOSX_DEPLOYMENT_TARGET: \n" + problematic_files + + if "MACOSX_DEPLOYMENT_TARGET" in os.environ: + error_message = error_message.format("is set in MACOSX_DEPLOYMENT_TARGET variable.") + else: + error_message = error_message.format( + "the version your Python interpreter is compiled against.") + + sys.stderr.write(error_message) + + platform_tag = prefix + "_" + fin_base_version + "_" + suffix + return platform_tag + + +def get_platform(archive_root): + """Return our platform name 'win32', 'linux_x86_64'""" + # XXX remove distutils dependency + result = distutils.util.get_platform() + if result.startswith("macosx") and archive_root is not None: + result = calculate_macosx_platform_tag(archive_root, result) + result = result.replace('.', '_').replace('-', '_') + if result == "linux_x86_64" and sys.maxsize == 2147483647: + # pip pull request #3497 + result = "linux_i686" + + return result + + +def get_supported(archive_root, versions=None, supplied_platform=None): + """Return a list of supported tags for each version specified in + `versions`. + + :param versions: a list of string versions, of the form ["33", "32"], + or None. The first version will be assumed to support our ABI. + """ + supported = [] + + # Versions must be given with respect to the preference + if versions is None: + versions = [] + version_info = get_impl_version_info() + major = version_info[:-1] + # Support all previous minor Python versions. + for minor in range(version_info[-1], -1, -1): + versions.append(''.join(map(str, major + (minor,)))) + + impl = get_abbr_impl() + + abis = [] + + abi = get_abi_tag() + if abi: + abis[0:0] = [abi] + + abi3s = set() + for suffix in get_all_suffixes(): + if suffix.startswith('.abi'): + abi3s.add(suffix.split('.', 2)[1]) + + abis.extend(sorted(list(abi3s))) + + abis.append('none') + + platforms = [] + if supplied_platform: + platforms.append(supplied_platform) + platforms.append(get_platform(archive_root)) + + # Current version, current API (built specifically for our Python): + for abi in abis: + for arch in platforms: + supported.append(('%s%s' % (impl, versions[0]), abi, arch)) + + # abi3 modules compatible with older version of Python + for version in versions[1:]: + # abi3 was introduced in Python 3.2 + if version in ('31', '30'): + break + for abi in abi3s: # empty set if not Python 3 + for arch in platforms: + supported.append(("%s%s" % (impl, version), abi, arch)) + + # No abi / arch, but requires our implementation: + for i, version in enumerate(versions): + supported.append(('%s%s' % (impl, version), 'none', 'any')) + if i == 0: + # Tagged specifically as being cross-version compatible + # (with just the major version specified) + supported.append(('%s%s' % (impl, versions[0][0]), 'none', 'any')) + + # Major Python version + platform; e.g. binaries not using the Python API + for arch in platforms: + supported.append(('py%s' % (versions[0][0]), 'none', arch)) + + # No abi / arch, generic Python + for i, version in enumerate(versions): + supported.append(('py%s' % (version,), 'none', 'any')) + if i == 0: + supported.append(('py%s' % (version[0]), 'none', 'any')) + + return supported diff --git a/venv/Lib/site-packages/wheel/pkginfo.py b/venv/Lib/site-packages/wheel/pkginfo.py new file mode 100644 index 00000000..115be45b --- /dev/null +++ b/venv/Lib/site-packages/wheel/pkginfo.py @@ -0,0 +1,43 @@ +"""Tools for reading and writing PKG-INFO / METADATA without caring +about the encoding.""" + +from email.parser import Parser + +try: + unicode + _PY3 = False +except NameError: + _PY3 = True + +if not _PY3: + from email.generator import Generator + + def read_pkg_info_bytes(bytestr): + return Parser().parsestr(bytestr) + + def read_pkg_info(path): + with open(path, "r") as headers: + message = Parser().parse(headers) + return message + + def write_pkg_info(path, message): + with open(path, 'w') as metadata: + Generator(metadata, mangle_from_=False, maxheaderlen=0).flatten(message) +else: + from email.generator import BytesGenerator + + def read_pkg_info_bytes(bytestr): + headers = bytestr.decode(encoding="ascii", errors="surrogateescape") + message = Parser().parsestr(headers) + return message + + def read_pkg_info(path): + with open(path, "r", + encoding="ascii", + errors="surrogateescape") as headers: + message = Parser().parse(headers) + return message + + def write_pkg_info(path, message): + with open(path, "wb") as out: + BytesGenerator(out, mangle_from_=False, maxheaderlen=0).flatten(message) diff --git a/venv/Lib/site-packages/wheel/util.py b/venv/Lib/site-packages/wheel/util.py new file mode 100644 index 00000000..3ae2b445 --- /dev/null +++ b/venv/Lib/site-packages/wheel/util.py @@ -0,0 +1,46 @@ +import base64 +import io +import sys + + +if sys.version_info[0] < 3: + text_type = unicode # noqa: F821 + + StringIO = io.BytesIO + + def native(s, encoding='utf-8'): + if isinstance(s, unicode): # noqa: F821 + return s.encode(encoding) + return s +else: + text_type = str + + StringIO = io.StringIO + + def native(s, encoding='utf-8'): + if isinstance(s, bytes): + return s.decode(encoding) + return s + + +def urlsafe_b64encode(data): + """urlsafe_b64encode without padding""" + return base64.urlsafe_b64encode(data).rstrip(b'=') + + +def urlsafe_b64decode(data): + """urlsafe_b64decode without padding""" + pad = b'=' * (4 - (len(data) & 3)) + return base64.urlsafe_b64decode(data + pad) + + +def as_unicode(s): + if isinstance(s, bytes): + return s.decode('utf-8') + return s + + +def as_bytes(s): + if isinstance(s, text_type): + return s.encode('utf-8') + return s diff --git a/venv/Lib/site-packages/wheel/wheelfile.py b/venv/Lib/site-packages/wheel/wheelfile.py new file mode 100644 index 00000000..acc5dab5 --- /dev/null +++ b/venv/Lib/site-packages/wheel/wheelfile.py @@ -0,0 +1,169 @@ +from __future__ import print_function + +import csv +import hashlib +import os.path +import re +import stat +import time +from collections import OrderedDict +from distutils import log as logger +from zipfile import ZIP_DEFLATED, ZipInfo, ZipFile + +from wheel.cli import WheelError +from wheel.util import urlsafe_b64decode, as_unicode, native, urlsafe_b64encode, as_bytes, StringIO + +# Non-greedy matching of an optional build number may be too clever (more +# invalid wheel filenames will match). Separate regex for .dist-info? +WHEEL_INFO_RE = re.compile( + r"""^(?P(?P.+?)-(?P.+?))(-(?P\d[^-]*))? + -(?P.+?)-(?P.+?)-(?P.+?)\.whl$""", + re.VERBOSE) + + +def get_zipinfo_datetime(timestamp=None): + # Some applications need reproducible .whl files, but they can't do this without forcing + # the timestamp of the individual ZipInfo objects. See issue #143. + timestamp = int(os.environ.get('SOURCE_DATE_EPOCH', timestamp or time.time())) + return time.gmtime(timestamp)[0:6] + + +class WheelFile(ZipFile): + """A ZipFile derivative class that also reads SHA-256 hashes from + .dist-info/RECORD and checks any read files against those. + """ + + _default_algorithm = hashlib.sha256 + + def __init__(self, file, mode='r', compression=ZIP_DEFLATED): + basename = os.path.basename(file) + self.parsed_filename = WHEEL_INFO_RE.match(basename) + if not basename.endswith('.whl') or self.parsed_filename is None: + raise WheelError("Bad wheel filename {!r}".format(basename)) + + ZipFile.__init__(self, file, mode, compression=compression, allowZip64=True) + + self.dist_info_path = '{}.dist-info'.format(self.parsed_filename.group('namever')) + self.record_path = self.dist_info_path + '/RECORD' + self._file_hashes = OrderedDict() + self._file_sizes = {} + if mode == 'r': + # Ignore RECORD and any embedded wheel signatures + self._file_hashes[self.record_path] = None, None + self._file_hashes[self.record_path + '.jws'] = None, None + self._file_hashes[self.record_path + '.p7s'] = None, None + + # Fill in the expected hashes by reading them from RECORD + try: + record = self.open(self.record_path) + except KeyError: + raise WheelError('Missing {} file'.format(self.record_path)) + + with record: + for line in record: + line = line.decode('utf-8') + path, hash_sum, size = line.rsplit(u',', 2) + if hash_sum: + algorithm, hash_sum = hash_sum.split(u'=') + try: + hashlib.new(algorithm) + except ValueError: + raise WheelError('Unsupported hash algorithm: {}'.format(algorithm)) + + if algorithm.lower() in {'md5', 'sha1'}: + raise WheelError( + 'Weak hash algorithm ({}) is not permitted by PEP 427' + .format(algorithm)) + + self._file_hashes[path] = ( + algorithm, urlsafe_b64decode(hash_sum.encode('ascii'))) + + def open(self, name_or_info, mode="r", pwd=None): + def _update_crc(newdata, eof=None): + if eof is None: + eof = ef._eof + update_crc_orig(newdata) + else: # Python 2 + update_crc_orig(newdata, eof) + + running_hash.update(newdata) + if eof and running_hash.digest() != expected_hash: + raise WheelError("Hash mismatch for file '{}'".format(native(ef_name))) + + ef = ZipFile.open(self, name_or_info, mode, pwd) + ef_name = as_unicode(name_or_info.filename if isinstance(name_or_info, ZipInfo) + else name_or_info) + if mode == 'r' and not ef_name.endswith('/'): + if ef_name not in self._file_hashes: + raise WheelError("No hash found for file '{}'".format(native(ef_name))) + + algorithm, expected_hash = self._file_hashes[ef_name] + if expected_hash is not None: + # Monkey patch the _update_crc method to also check for the hash from RECORD + running_hash = hashlib.new(algorithm) + update_crc_orig, ef._update_crc = ef._update_crc, _update_crc + + return ef + + def write_files(self, base_dir): + logger.info("creating '%s' and adding '%s' to it", self.filename, base_dir) + deferred = [] + for root, dirnames, filenames in os.walk(base_dir): + # Sort the directory names so that `os.walk` will walk them in a + # defined order on the next iteration. + dirnames.sort() + for name in sorted(filenames): + path = os.path.normpath(os.path.join(root, name)) + if os.path.isfile(path): + arcname = os.path.relpath(path, base_dir).replace(os.path.sep, '/') + if arcname == self.record_path: + pass + elif root.endswith('.dist-info'): + deferred.append((path, arcname)) + else: + self.write(path, arcname) + + deferred.sort() + for path, arcname in deferred: + self.write(path, arcname) + + def write(self, filename, arcname=None, compress_type=None): + with open(filename, 'rb') as f: + st = os.fstat(f.fileno()) + data = f.read() + + zinfo = ZipInfo(arcname or filename, date_time=get_zipinfo_datetime(st.st_mtime)) + zinfo.external_attr = (stat.S_IMODE(st.st_mode) | stat.S_IFMT(st.st_mode)) << 16 + zinfo.compress_type = compress_type or self.compression + self.writestr(zinfo, data, compress_type) + + def writestr(self, zinfo_or_arcname, bytes, compress_type=None): + ZipFile.writestr(self, zinfo_or_arcname, bytes, compress_type) + fname = (zinfo_or_arcname.filename if isinstance(zinfo_or_arcname, ZipInfo) + else zinfo_or_arcname) + logger.info("adding '%s'", fname) + if fname != self.record_path: + hash_ = self._default_algorithm(bytes) + self._file_hashes[fname] = hash_.name, native(urlsafe_b64encode(hash_.digest())) + self._file_sizes[fname] = len(bytes) + + def close(self): + # Write RECORD + if self.fp is not None and self.mode == 'w' and self._file_hashes: + data = StringIO() + writer = csv.writer(data, delimiter=',', quotechar='"', lineterminator='\n') + writer.writerows(( + ( + fname, + algorithm + "=" + hash_, + self._file_sizes[fname] + ) + for fname, (algorithm, hash_) in self._file_hashes.items() + )) + writer.writerow((format(self.record_path), "", "")) + zinfo = ZipInfo(native(self.record_path), date_time=get_zipinfo_datetime()) + zinfo.compress_type = self.compression + zinfo.external_attr = 0o664 << 16 + self.writestr(zinfo, as_bytes(data.getvalue())) + + ZipFile.close(self) diff --git a/venv/Scripts/wheel.exe b/venv/Scripts/wheel.exe new file mode 100644 index 0000000000000000000000000000000000000000..8b1d28860293b89bb69030c4e62c75ba8cdef593 GIT binary patch literal 106360 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 AE&u=k literal 0 HcmV?d00001