wheel-0.34.2/0000775000175000017500000000000013614653447012627 5ustar alexalex00000000000000wheel-0.34.2/.github/0000775000175000017500000000000013614653447014167 5ustar alexalex00000000000000wheel-0.34.2/.github/workflows/0000775000175000017500000000000013614653447016224 5ustar alexalex00000000000000wheel-0.34.2/.github/workflows/codeqa-test-tag.yml0000644000175000017500000000415113614653234021722 0ustar alexalex00000000000000name: Python codeqa/test/tag on: [push] jobs: flake8: runs-on: ubuntu-latest steps: - uses: actions/checkout@v1 - name: Check code style with Flake8 uses: TrueBrain/actions-flake8@v1.2 with: path: src tests test: needs: [flake8] strategy: fail-fast: false matrix: os: [ubuntu-latest, macos-latest, windows-latest] python-version: [2.7, 3.5, 3.6, 3.8, pypy3] exclude: - os: ubuntu-latest python-version: 3.6 - os: macos-latest python-version: 3.6 - os: macos-latest python-version: pypy3 - os: windows-latest python-version: 2.7 - os: windows-latest python-version: 3.5 - os: windows-latest python-version: pypy3 runs-on: ${{ matrix.os }} steps: - uses: actions/checkout@v1 - name: Set up Python ${{ matrix.python-version }} uses: actions/setup-python@v1 with: python-version: ${{ matrix.python-version }} - name: Upgrade setuptools run: pip install "setuptools >= 40.9" - name: Install the project run: "pip install --no-binary=:all: ." - name: Install test dependencies run: pip install .[test] - name: Test with pytest run: pytest tag: runs-on: ubuntu-latest needs: test if: github.ref == 'refs/heads/master' steps: - uses: actions/checkout@v1 - uses: agronholm/action-general-autotag@regexnofail id: create-tag with: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} source_file: docs/news.rst extraction_regex: "\\*\\*(\\d+\\.\\d+\\.\\d+(?:(?:a|b|rc)\\d+)?) " - name: Set up Python uses: actions/setup-python@v1 if: steps.create-tag.outputs.tagname with: python-version: 3.7 - name: Install dependencies run: | pip install "setuptools >= 40.9" pip install . - name: Create packages run: python setup.py sdist bdist_wheel - name: Upload packages uses: pypa/gh-action-pypi-publish@v1.0.0a0 with: password: ${{ secrets.pypi_password }} wheel-0.34.2/.gitignore0000664000175000017500000000023613613340346014606 0ustar alexalex00000000000000*.egg-info *.dist-info *.pyc build dist docs/_build src/wheel/_version.py __pycache__ .coverage .pytest_cache .tox .idea .cache .eggs .pre-commit-config.yaml wheel-0.34.2/LICENSE.txt0000664000175000017500000000214513135733074014445 0ustar alexalex00000000000000"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. wheel-0.34.2/MANIFEST.in0000664000175000017500000000047213613642044014356 0ustar alexalex00000000000000recursive-include src *.py recursive-include tests *.py *.h *.txt *.c *.dynlib recursive-include docs *.py *.rst make.bat Makefile include tests/testdata/test-1.0-py2.py3-none-any.whl include tox.ini include manpages/*.rst prune tests/testdata/*/build prune tests/testdata/*/dist prune tests/testdata/*/*.egg-info wheel-0.34.2/PKG-INFO0000664000175000017500000000453013614653447013726 0ustar alexalex00000000000000Metadata-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 Description: 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/ 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 wheel-0.34.2/README.rst0000664000175000017500000000164013613340346014305 0ustar alexalex00000000000000wheel ===== 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/ wheel-0.34.2/docs/0000775000175000017500000000000013614653447013557 5ustar alexalex00000000000000wheel-0.34.2/docs/Makefile0000664000175000017500000001267013135733074015216 0ustar alexalex00000000000000# Makefile for Sphinx documentation # # You can set these variables from the command line. SPHINXOPTS = SPHINXBUILD = sphinx-build PAPER = BUILDDIR = _build # Internal variables. PAPEROPT_a4 = -D latex_paper_size=a4 PAPEROPT_letter = -D latex_paper_size=letter ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . # the i18n builder cannot share the environment and doctrees with the others I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . .PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest gettext help: @echo "Please use \`make ' where is one of" @echo " html to make standalone HTML files" @echo " dirhtml to make HTML files named index.html in directories" @echo " singlehtml to make a single large HTML file" @echo " pickle to make pickle files" @echo " json to make JSON files" @echo " htmlhelp to make HTML files and a HTML help project" @echo " qthelp to make HTML files and a qthelp project" @echo " devhelp to make HTML files and a Devhelp project" @echo " epub to make an epub" @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" @echo " latexpdf to make LaTeX files and run them through pdflatex" @echo " text to make text files" @echo " man to make manual pages" @echo " texinfo to make Texinfo files" @echo " info to make Texinfo files and run them through makeinfo" @echo " gettext to make PO message catalogs" @echo " changes to make an overview of all changed/added/deprecated items" @echo " linkcheck to check all external links for integrity" @echo " doctest to run all doctests embedded in the documentation (if enabled)" clean: -rm -rf $(BUILDDIR)/* html: $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html @echo @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." dirhtml: $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml @echo @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml." singlehtml: $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml @echo @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml." pickle: $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle @echo @echo "Build finished; now you can process the pickle files." json: $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json @echo @echo "Build finished; now you can process the JSON files." htmlhelp: $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp @echo @echo "Build finished; now you can run HTML Help Workshop with the" \ ".hhp project file in $(BUILDDIR)/htmlhelp." qthelp: $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp @echo @echo "Build finished; now you can run "qcollectiongenerator" with the" \ ".qhcp project file in $(BUILDDIR)/qthelp, like this:" @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/wheel.qhcp" @echo "To view the help file:" @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/wheel.qhc" devhelp: $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp @echo @echo "Build finished." @echo "To view the help file:" @echo "# mkdir -p $$HOME/.local/share/devhelp/wheel" @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/wheel" @echo "# devhelp" epub: $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub @echo @echo "Build finished. The epub file is in $(BUILDDIR)/epub." latex: $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex @echo @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex." @echo "Run \`make' in that directory to run these through (pdf)latex" \ "(use \`make latexpdf' here to do that automatically)." latexpdf: $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex @echo "Running LaTeX files through pdflatex..." $(MAKE) -C $(BUILDDIR)/latex all-pdf @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." text: $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text @echo @echo "Build finished. The text files are in $(BUILDDIR)/text." man: $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man @echo @echo "Build finished. The manual pages are in $(BUILDDIR)/man." texinfo: $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo @echo @echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo." @echo "Run \`make' in that directory to run these through makeinfo" \ "(use \`make info' here to do that automatically)." info: $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo @echo "Running Texinfo files through makeinfo..." make -C $(BUILDDIR)/texinfo info @echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo." gettext: $(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale @echo @echo "Build finished. The message catalogs are in $(BUILDDIR)/locale." changes: $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes @echo @echo "The overview file is in $(BUILDDIR)/changes." linkcheck: $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck @echo @echo "Link check complete; look for any errors in the above output " \ "or in $(BUILDDIR)/linkcheck/output.txt." doctest: $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest @echo "Testing of doctests in the sources finished, look at the " \ "results in $(BUILDDIR)/doctest/output.txt." wheel-0.34.2/docs/conf.py0000664000175000017500000001772113414074275015060 0ustar alexalex00000000000000# -*- coding: utf-8 -*- # # wheel documentation build configuration file, created by # sphinx-quickstart on Thu Jul 12 00:14:09 2012. # # This file is execfile()d with the current directory set to its containing dir. # # Note that not all possible configuration values are present in this # autogenerated file. # # All configuration values have a default; values that are commented out # serve to show the default. import io import os import re # If extensions (or modules to document with autodoc) are in another directory, # add these directories to sys.path here. If the directory is relative to the # documentation root, use os.path.abspath to make it absolute, like shown here. #sys.path.insert(0, os.path.abspath('.')) # -- General configuration ----------------------------------------------------- # If your documentation needs a minimal Sphinx version, state it here. #needs_sphinx = '1.0' # Add any Sphinx extension module names here, as strings. They can be extensions # coming with Sphinx (named 'sphinx.ext.*') or your custom ones. extensions = ['sphinx.ext.intersphinx'] # Add any paths that contain templates here, relative to this directory. templates_path = ['_templates'] # The suffix of source filenames. source_suffix = '.rst' # The encoding of source files. #source_encoding = 'utf-8-sig' # The master toctree document. master_doc = 'index' # General information about the project. project = u'wheel' copyright = u'2012, Daniel Holth' # The version info for the project you're documenting, acts as replacement for # |version| and |release|, also used in various other places throughout the # built documents. # here = os.path.abspath(os.path.dirname(__file__)) with io.open(os.path.join(here, '..', 'wheel', '__init__.py'), encoding='utf8') as version_file: match = re.search(r'__version__ = "((\d+\.\d+\.\d+).*)"', version_file.read()) # The short X.Y version. version = match.group(2) # The full version, including alpha/beta/rc tags. release = match.group(1) # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. #language = None # There are two options for replacing |today|: either, you set today to some # non-false value, then it is used: #today = '' # Else, today_fmt is used as the format for a strftime call. #today_fmt = '%B %d, %Y' # List of patterns, relative to source directory, that match files and # directories to ignore when looking for source files. exclude_patterns = ['_build'] # The reST default role (used for this markup: `text`) to use for all documents. #default_role = None # If true, '()' will be appended to :func: etc. cross-reference text. #add_function_parentheses = True # If true, the current module name will be prepended to all description # unit titles (such as .. function::). #add_module_names = True # If true, sectionauthor and moduleauthor directives will be shown in the # output. They are ignored by default. #show_authors = False # The name of the Pygments (syntax highlighting) style to use. pygments_style = 'sphinx' highlight_language = 'bash' # A list of ignored prefixes for module index sorting. #modindex_common_prefix = [] intersphinx_mapping = { 'python': ('https://docs.python.org/', None) } # -- Options for HTML output --------------------------------------------------- # The theme to use for HTML and HTML Help pages. See the documentation for # a list of builtin themes. html_theme = 'default' # Theme options are theme-specific and customize the look and feel of a theme # further. For a list of options available for each theme, see the # documentation. #html_theme_options = {} # Add any paths that contain custom themes here, relative to this directory. #html_theme_path = [] # The name for this set of Sphinx documents. If None, it defaults to # " v documentation". #html_title = None # A shorter title for the navigation bar. Default is the same as html_title. #html_short_title = None # The name of an image file (relative to this directory) to place at the top # of the sidebar. #html_logo = None # The name of an image file (within the static path) to use as favicon of the # docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 # pixels large. #html_favicon = None # Add any paths that contain custom static files (such as style sheets) here, # relative to this directory. They are copied after the builtin static files, # so a file named "default.css" will overwrite the builtin "default.css". #html_static_path = ['_static'] # If not '', a 'Last updated on:' timestamp is inserted at every page bottom, # using the given strftime format. #html_last_updated_fmt = '%b %d, %Y' # If true, SmartyPants will be used to convert quotes and dashes to # typographically correct entities. #html_use_smartypants = True # Custom sidebar templates, maps document names to template names. #html_sidebars = {} # Additional templates that should be rendered to pages, maps page names to # template names. #html_additional_pages = {} # If false, no module index is generated. #html_domain_indices = True # If false, no index is generated. #html_use_index = True # If true, the index is split into individual pages for each letter. #html_split_index = False # If true, links to the reST sources are added to the pages. #html_show_sourcelink = True # If true, "Created using Sphinx" is shown in the HTML footer. Default is True. #html_show_sphinx = True # If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. #html_show_copyright = True # If true, an OpenSearch description file will be output, and all pages will # contain a tag referring to it. The value of this option must be the # base URL from which the finished HTML is served. #html_use_opensearch = '' # This is the file name suffix for HTML files (e.g. ".xhtml"). #html_file_suffix = None # Output file base name for HTML help builder. htmlhelp_basename = 'wheeldoc' # -- Options for LaTeX output -------------------------------------------------- latex_elements = { # The paper size ('letterpaper' or 'a4paper'). #'papersize': 'letterpaper', # The font size ('10pt', '11pt' or '12pt'). #'pointsize': '10pt', # Additional stuff for the LaTeX preamble. #'preamble': '', } # Grouping the document tree into LaTeX files. List of tuples # (source start file, target name, title, author, documentclass [howto/manual]). latex_documents = [ ('index', 'wheel.tex', u'wheel Documentation', u'Daniel Holth', 'manual'), ] # The name of an image file (relative to this directory) to place at the top of # the title page. #latex_logo = None # For "manual" documents, if this is true, then toplevel headings are parts, # not chapters. #latex_use_parts = False # If true, show page references after internal links. #latex_show_pagerefs = False # If true, show URL addresses after external links. #latex_show_urls = False # Documents to append as an appendix to all manuals. #latex_appendices = [] # If false, no module index is generated. #latex_domain_indices = True # -- Options for manual page output -------------------------------------------- # One entry per manual page. List of tuples # (source start file, name, description, authors, manual section). man_pages = [ ('index', 'wheel', u'wheel Documentation', [u'Daniel Holth'], 1) ] # If true, show URL addresses after external links. #man_show_urls = False # -- Options for Texinfo output ------------------------------------------------ # Grouping the document tree into Texinfo files. List of tuples # (source start file, target name, title, author, # dir menu entry, description, category) texinfo_documents = [ ('index', 'wheel', u'wheel Documentation', u'Daniel Holth', 'wheel', 'One line description of project.', 'Miscellaneous'), ] # Documents to append as an appendix to all manuals. #texinfo_appendices = [] # If false, no module index is generated. #texinfo_domain_indices = True # How to display URL addresses: 'footnote', 'no', or 'inline'. #texinfo_show_urls = 'footnote' wheel-0.34.2/docs/development.rst0000664000175000017500000000564313613642044016631 0ustar alexalex00000000000000Development =========== Pull Requests ------------- - Submit Pull Requests against the ``master`` branch. - Provide a good description of what you're doing and why. - Provide tests that cover your changes and try to run the tests locally first. **Example**. Assuming you set up GitHub account, forked wheel repository from https://github.com/pypa/wheel to your own page via web interface, and your fork is located at https://github.com/yourname/wheel :: $ git clone git@github.com:pypa/wheel.git $ cd wheel # ... $ git diff $ git add ... $ git status $ git commit You may reference relevant issues in commit messages (like #1259) to make GitHub link issues and commits together, and with phrase like "fixes #1259" you can even close relevant issues automatically. Now push the changes to your fork:: $ git push git@github.com:yourname/wheel.git Open Pull Requests page at https://github.com/yourname/wheel/pulls and click "New pull request". That's it. Automated Testing ----------------- All pull requests and merges to 'master' branch are tested in `Github Actions`_ based on the workflows in the ``.github`` directory. The only way to trigger the test suite to run again for a pull request is to submit another change to the pull branch. .. _Github Actions: https://github.com/actions Running Tests Locally --------------------- Python requirements: tox_ or pytest_ To run the tests via tox against all matching interpreters:: $ tox To run the tests via tox against a specific environment:: $ tox -e py35 Alternatively, you can run the tests via pytest using your default interpreter:: $ pip install -e .[test] # Installs the test dependencies $ pytest # Runs the tests with the current interpreter The above pip install command will replace the current interpreter's installed wheel package with the development package being tested. If you use this workflow, it is recommended to run it under a virtualenv_. .. _tox: https://pypi.org/project/tox/ .. _pytest: https://pypi.org/project/pytest/ .. _virtualenv: https://pypi.org/project/virtualenv/ Getting Involved ---------------- The wheel project welcomes help in the following ways: - Making Pull Requests for code, tests, or docs. - Commenting on open issues and pull requests. - Helping to answer questions on the `mailing list`_. .. _`mailing list`: https://mail.python.org/mailman/listinfo/distutils-sig Release Process --------------- To make a new release: #. Edit ``docs/news.rst`` and replace ``**UNRELEASED**`` with a release version and date, like ``**X.Y.Z (20XX-YY-ZZ)**``. #. Replace the ``__version__`` attribute in ``src/wheel/__init__.py`` with the same version number as above (without the date of course). The github workflow will pick up the new version from ``news.rst`` and create a new tag, which will then trigger the release workflow which will package the project and publish the resulting artifacts to PyPI. wheel-0.34.2/docs/index.rst0000664000175000017500000000141113414074275015407 0ustar alexalex00000000000000wheel ===== `User list `_ | `Dev list `_ | `Github `_ | `PyPI `_ | User IRC: #pypa | Dev IRC: #pypa-dev 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 .. _PEP 427: https://www.python.org/dev/peps/pep-0427/ .. _setuptools: https://pypi.org/project/setuptools/ .. toctree:: :maxdepth: 2 quickstart installing user_guide reference/index development newswheel-0.34.2/docs/installing.rst0000664000175000017500000000126013414074275016446 0ustar alexalex00000000000000Installation ============ You can use pip_ to install wheel:: pip install wheel If you do not have pip_ installed, see its documentation for `installation instructions`_. If you prefer using your system package manager to install Python packages, you can typically find the wheel package under one of the following package names: * python-wheel * python2-wheel * python3-wheel .. _pip: https://pip.pypa.io/en/stable/ .. _installation instructions: https://pip.pypa.io/en/stable/installing/ Python and OS Compatibility --------------------------- wheel should work on any Python implementation and operating system and is compatible with Python version 2.7 and upwards of 3.4. wheel-0.34.2/docs/make.bat0000664000175000017500000001174613135733074015166 0ustar alexalex00000000000000@ECHO OFF REM Command file for Sphinx documentation if "%SPHINXBUILD%" == "" ( set SPHINXBUILD=sphinx-build ) set BUILDDIR=_build set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% . set I18NSPHINXOPTS=%SPHINXOPTS% . if NOT "%PAPER%" == "" ( set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS% set I18NSPHINXOPTS=-D latex_paper_size=%PAPER% %I18NSPHINXOPTS% ) if "%1" == "" goto help if "%1" == "help" ( :help echo.Please use `make ^` where ^ is one of echo. html to make standalone HTML files echo. dirhtml to make HTML files named index.html in directories echo. singlehtml to make a single large HTML file echo. pickle to make pickle files echo. json to make JSON files echo. htmlhelp to make HTML files and a HTML help project echo. qthelp to make HTML files and a qthelp project echo. devhelp to make HTML files and a Devhelp project echo. epub to make an epub echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter echo. text to make text files echo. man to make manual pages echo. texinfo to make Texinfo files echo. gettext to make PO message catalogs echo. changes to make an overview over all changed/added/deprecated items echo. linkcheck to check all external links for integrity echo. doctest to run all doctests embedded in the documentation if enabled goto end ) if "%1" == "clean" ( for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i del /q /s %BUILDDIR%\* goto end ) if "%1" == "html" ( %SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html if errorlevel 1 exit /b 1 echo. echo.Build finished. The HTML pages are in %BUILDDIR%/html. goto end ) if "%1" == "dirhtml" ( %SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml if errorlevel 1 exit /b 1 echo. echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml. goto end ) if "%1" == "singlehtml" ( %SPHINXBUILD% -b singlehtml %ALLSPHINXOPTS% %BUILDDIR%/singlehtml if errorlevel 1 exit /b 1 echo. echo.Build finished. The HTML pages are in %BUILDDIR%/singlehtml. goto end ) if "%1" == "pickle" ( %SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle if errorlevel 1 exit /b 1 echo. echo.Build finished; now you can process the pickle files. goto end ) if "%1" == "json" ( %SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json if errorlevel 1 exit /b 1 echo. echo.Build finished; now you can process the JSON files. goto end ) if "%1" == "htmlhelp" ( %SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp if errorlevel 1 exit /b 1 echo. echo.Build finished; now you can run HTML Help Workshop with the ^ .hhp project file in %BUILDDIR%/htmlhelp. goto end ) if "%1" == "qthelp" ( %SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp if errorlevel 1 exit /b 1 echo. echo.Build finished; now you can run "qcollectiongenerator" with the ^ .qhcp project file in %BUILDDIR%/qthelp, like this: echo.^> qcollectiongenerator %BUILDDIR%\qthelp\wheel.qhcp echo.To view the help file: echo.^> assistant -collectionFile %BUILDDIR%\qthelp\wheel.ghc goto end ) if "%1" == "devhelp" ( %SPHINXBUILD% -b devhelp %ALLSPHINXOPTS% %BUILDDIR%/devhelp if errorlevel 1 exit /b 1 echo. echo.Build finished. goto end ) if "%1" == "epub" ( %SPHINXBUILD% -b epub %ALLSPHINXOPTS% %BUILDDIR%/epub if errorlevel 1 exit /b 1 echo. echo.Build finished. The epub file is in %BUILDDIR%/epub. goto end ) if "%1" == "latex" ( %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex if errorlevel 1 exit /b 1 echo. echo.Build finished; the LaTeX files are in %BUILDDIR%/latex. goto end ) if "%1" == "text" ( %SPHINXBUILD% -b text %ALLSPHINXOPTS% %BUILDDIR%/text if errorlevel 1 exit /b 1 echo. echo.Build finished. The text files are in %BUILDDIR%/text. goto end ) if "%1" == "man" ( %SPHINXBUILD% -b man %ALLSPHINXOPTS% %BUILDDIR%/man if errorlevel 1 exit /b 1 echo. echo.Build finished. The manual pages are in %BUILDDIR%/man. goto end ) if "%1" == "texinfo" ( %SPHINXBUILD% -b texinfo %ALLSPHINXOPTS% %BUILDDIR%/texinfo if errorlevel 1 exit /b 1 echo. echo.Build finished. The Texinfo files are in %BUILDDIR%/texinfo. goto end ) if "%1" == "gettext" ( %SPHINXBUILD% -b gettext %I18NSPHINXOPTS% %BUILDDIR%/locale if errorlevel 1 exit /b 1 echo. echo.Build finished. The message catalogs are in %BUILDDIR%/locale. goto end ) if "%1" == "changes" ( %SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes if errorlevel 1 exit /b 1 echo. echo.The overview file is in %BUILDDIR%/changes. goto end ) if "%1" == "linkcheck" ( %SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck if errorlevel 1 exit /b 1 echo. echo.Link check complete; look for any errors in the above output ^ or in %BUILDDIR%/linkcheck/output.txt. goto end ) if "%1" == "doctest" ( %SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest if errorlevel 1 exit /b 1 echo. echo.Testing of doctests in the sources finished, look at the ^ results in %BUILDDIR%/doctest/output.txt. goto end ) :end wheel-0.34.2/docs/news.rst0000664000175000017500000003242313614633011015252 0ustar alexalex00000000000000Release Notes ============= **0.34.2 (2020-01-30)** - Fixed installation of ``wheel`` from sdist on environments without Unicode file name support **0.34.1 (2020-01-27)** - Fixed installation of ``wheel`` from sdist which was broken due to a chicken and egg problem with PEP 517 and setuptools_scm **0.34.0 (2020-01-27)** - Dropped Python 3.4 support - Added automatic platform tag detection for macOS binary wheels (PR by Grzegorz Bokota) - Added the ``--compression=`` option to the ``bdist_wheel`` command - Fixed PyPy tag generation to work with the updated semantics (#328) - Updated project packaging and testing configuration for :pep:`517` - Moved the contents of setup.py to setup.cfg - Fixed duplicate RECORD file when using ``wheel pack`` on Windows - Fixed bdist_wheel failing at cleanup on Windows with a read-only source tree - Fixed ``wheel pack`` not respecting the existing build tag in ``WHEEL`` - Switched the project to use the "src" layout - Switched to setuptools_scm_ for versioning .. _setuptools_scm: https://github.com/pypa/setuptools_scm/ **0.33.6 (2019-08-18)** - Fixed regression from 0.33.5 that broke building binary wheels against the limited ABI - Fixed egg2wheel compatibility with the future release of Python 3.10 (PR by Anthony Sottile) **0.33.5 (2019-08-17)** - Don't add the ``m`` ABI flag to wheel names on Python 3.8 (PR by rdb) - Updated ``MANIFEST.in`` to include many previously omitted files in the sdist **0.33.4 (2019-05-12)** - Reverted PR #289 (adding directory entries to the wheel file) due to incompatibility with ``distlib.wheel`` **0.33.3 (2019-05-10)** (redacted release) - Fixed wheel build failures on some systems due to all attributes being preserved (PR by Matt Wozniski) **0.33.2 (2019-05-08)** (redacted release) - Fixed empty directories missing from the wheel (PR by Jason R. Coombs) **0.33.1 (2019-02-19)** - Fixed the ``--build-number`` option for ``wheel pack`` not being applied **0.33.0 (2019-02-11)** - Added the ``--build-number`` option to the ``wheel pack`` command - Fixed bad shebangs sneaking into wheels - Fixed documentation issue with ``wheel pack`` erroneously being called ``wheel repack`` - Fixed filenames with "bad" characters (like commas) not being quoted in ``RECORD`` (PR by Paul Moore) - Sort requirements extras to ensure deterministic builds (PR by PoncinMatthieu) - Forced ``inplace = False`` when building a C extension for the wheel **0.32.3 (2018-11-18)** - Fixed compatibility with Python 2.7.0 – 2.7.3 - Fixed handling of direct URL requirements with markers (PR by Benoit Pierre) **0.32.2 (2018-10-20)** - Fixed build number appearing in the ``.dist-info`` directory name - Made wheel file name parsing more permissive - Fixed wrong Python tag in wheels converted from eggs (PR by John T. Wodder II) **0.32.1 (2018-10-03)** - Fixed ``AttributeError: 'Requirement' object has no attribute 'url'`` on setuptools/pkg_resources versions older than 18.8 (PR by Benoit Pierre) - Fixed ``AttributeError: 'module' object has no attribute 'algorithms_available'`` on Python < 2.7.9 (PR by Benoit Pierre) - Fixed permissions on the generated ``.dist-info/RECORD`` file **0.32.0 (2018-09-29)** - Removed wheel signing and verifying features - Removed the "wheel install" and "wheel installscripts" commands - Added the ``wheel pack`` command - Allowed multiple license files to be specified using the ``license_files`` option - Deprecated the ``license_file`` option - Eliminated duplicate lines from generated requirements in ``.dist-info/METADATA`` (thanks to Wim Glenn for the contribution) - Fixed handling of direct URL specifiers in requirements (PR by Benoit Pierre) - Fixed canonicalization of extras (PR by Benoit Pierre) - Warn when the deprecated ``[wheel]`` section is used in ``setup.cfg`` (PR by Jon Dufresne) **0.31.1 (2018-05-13)** - Fixed arch as ``None`` when converting eggs to wheels **0.31.0 (2018-04-01)** - Fixed displaying of errors on Python 3 - Fixed single digit versions in wheel files not being properly recognized - Fixed wrong character encodings being used (instead of UTF-8) to read and write ``RECORD`` (this sometimes crashed bdist_wheel too) - Enabled Zip64 support in wheels by default - Metadata-Version is now 2.1 - Dropped DESCRIPTION.rst and metadata.json from the list of generated files - Dropped support for the non-standard, undocumented ``provides-extra`` and ``requires-dist`` keywords in setup.cfg metadata - Deprecated all wheel signing and signature verification commands - Removed the (already defunct) ``tool`` extras from setup.py **0.30.0 (2017-09-10)** - Added py-limited-api {cp32|cp33|cp34|...} flag to produce cpNN.abi3.{arch} tags on CPython 3. - Documented the ``license_file`` metadata key - Improved Python, abi tagging for ``wheel convert``. Thanks Ales Erjavec. - Fixed ``>`` being prepended to lines starting with "From" in the long description - Added support for specifying a build number (as per PEP 427). Thanks Ian Cordasco. - Made the order of files in generated ZIP files deterministic. Thanks Matthias Bach. - Made the order of requirements in metadata deterministic. Thanks Chris Lamb. - Fixed ``wheel install`` clobbering existing files - Improved the error message when trying to verify an unsigned wheel file - Removed support for Python 2.6, 3.2 and 3.3. **0.29.0 (2016-02-06)** - Fix compression type of files in archive (Issue #155, Pull Request #62, thanks Xavier Fernandez) **0.28.0 (2016-02-05)** - Fix file modes in archive (Issue #154) **0.27.0 (2016-02-05)** - Support forcing a platform tag using ``--plat-name`` on pure-Python wheels, as well as nonstandard platform tags on non-pure wheels (Pull Request #60, Issue #144, thanks Andrés Díaz) - Add SOABI tags to platform-specific wheels built for Python 2.X (Pull Request #55, Issue #63, Issue #101) - Support reproducible wheel files, wheels that can be rebuilt and will hash to the same values as previous builds (Pull Request #52, Issue #143, thanks Barry Warsaw) - Support for changes in keyring >= 8.0 (Pull Request #61, thanks Jason R. Coombs) - Use the file context manager when checking if dependency_links.txt is empty, fixes problems building wheels under PyPy on Windows (Issue #150, thanks Cosimo Lupo) - Don't attempt to (recursively) create a build directory ending with ``..`` (invalid on all platforms, but code was only executed on Windows) (Issue #91) - Added the PyPA Code of Conduct (Pull Request #56) **0.26.0 (2015-09-18)** - Fix multiple entrypoint comparison failure on Python 3 (Issue #148) **0.25.0 (2015-09-16)** - Add Python 3.5 to tox configuration - Deterministic (sorted) metadata - Fix tagging for Python 3.5 compatibility - Support py2-none-'arch' and py3-none-'arch' tags - Treat data-only wheels as pure - Write to temporary file and rename when using wheel install --force **0.24.0 (2014-07-06)** - The python tag used for pure-python packages is now .pyN (major version only). This change actually occurred in 0.23.0 when the --python-tag option was added, but was not explicitly mentioned in the changelog then. - wininst2wheel and egg2wheel removed. Use "wheel convert [archive]" instead. - Wheel now supports setuptools style conditional requirements via the extras_require={} syntax. Separate 'extra' names from conditions using the : character. Wheel's own setup.py does this. (The empty-string extra is the same as install_requires.) These conditional requirements should work the same whether the package is installed by wheel or by setup.py. **0.23.0 (2014-03-31)** - Compatibility tag flags added to the bdist_wheel command - sdist should include files necessary for tests - 'wheel convert' can now also convert unpacked eggs to wheel - Rename pydist.json to metadata.json to avoid stepping on the PEP - The --skip-scripts option has been removed, and not generating scripts is now the default. The option was a temporary approach until installers could generate scripts themselves. That is now the case with pip 1.5 and later. Note that using pip 1.4 to install a wheel without scripts will leave the installation without entry-point wrappers. The "wheel install-scripts" command can be used to generate the scripts in such cases. - Thank you contributors **0.22.0 (2013-09-15)** - Include entry_points.txt, scripts a.k.a. commands, in experimental pydist.json - Improved test_requires parsing - Python 2.6 fixes, "wheel version" command courtesy pombredanne **0.21.0 (2013-07-20)** - Pregenerated scripts are the default again. - "setup.py bdist_wheel --skip-scripts" turns them off. - setuptools is no longer a listed requirement for the 'wheel' package. It is of course still required in order for bdist_wheel to work. - "python -m wheel" avoids importing pkg_resources until it's necessary. **0.20.0** - No longer include console_scripts in wheels. Ordinary scripts (shell files, standalone Python files) are included as usual. - Include new command "python -m wheel install-scripts [distribution [distribution ...]]" to install the console_scripts (setuptools-style scripts using pkg_resources) for a distribution. **0.19.0 (2013-07-19)** - pymeta.json becomes pydist.json **0.18.0 (2013-07-04)** - Python 3 Unicode improvements **0.17.0 (2013-06-23)** - Support latest PEP-426 "pymeta.json" (json-format metadata) **0.16.0 (2013-04-29)** - Python 2.6 compatibility bugfix (thanks John McFarlane) - Bugfix for C-extension tags for CPython 3.3 (using SOABI) - Bugfix for bdist_wininst converter "wheel convert" - Bugfix for dists where "is pure" is None instead of True or False - Python 3 fix for moving Unicode Description to metadata body - Include rudimentary API documentation in Sphinx (thanks Kevin Horn) **0.15.0 (2013-01-14)** - Various improvements **0.14.0 (2012-10-27)** - Changed the signature format to better comply with the current JWS spec. Breaks all existing signatures. - Include ``wheel unsign`` command to remove RECORD.jws from an archive. - Put the description in the newly allowed payload section of PKG-INFO (METADATA) files. **0.13.0 (2012-10-17)** - Use distutils instead of sysconfig to get installation paths; can install headers. - Improve WheelFile() sort. - Allow bootstrap installs without any pkg_resources. **0.12.0 (2012-10-06)** - Unit test for wheel.tool.install **0.11.0 (2012-10-17)** - API cleanup **0.10.3 (2012-10-03)** - Scripts fixer fix **0.10.2 (2012-10-02)** - Fix keygen **0.10.1 (2012-09-30)** - Preserve attributes on install. **0.10.0 (2012-09-30)** - Include a copy of pkg_resources. Wheel can now install into a virtualenv that does not have distribute (though most packages still require pkg_resources to actually work; wheel install distribute) - Define a new setup.cfg section [wheel]. universal=1 will apply the py2.py3-none-any tag for pure python wheels. **0.9.7 (2012-09-20)** - Only import dirspec when needed. dirspec is only needed to find the configuration for keygen/signing operations. **0.9.6 (2012-09-19)** - requires-dist from setup.cfg overwrites any requirements from setup.py Care must be taken that the requirements are the same in both cases, or just always install from wheel. - drop dirspec requirement on win32 - improved command line utility, adds 'wheel convert [egg or wininst]' to convert legacy binary formats to wheel **0.9.5 (2012-09-15)** - Wheel's own wheel file can be executed by Python, and can install itself: ``python wheel-0.9.5-py27-none-any/wheel install ...`` - Use argparse; basic ``wheel install`` command should run with only stdlib dependencies. - Allow requires_dist in setup.cfg's [metadata] section. In addition to dependencies in setup.py, but will only be interpreted when installing from wheel, not from sdist. Can be qualified with environment markers. **0.9.4 (2012-09-11)** - Fix wheel.signatures in sdist **0.9.3 (2012-09-10)** - Integrated digital signatures support without C extensions. - Integrated "wheel install" command (single package, no dependency resolution) including compatibility check. - Support Python 3.3 - Use Metadata 1.3 (PEP 426) **0.9.2 (2012-08-29)** - Automatic signing if WHEEL_TOOL points to the wheel binary - Even more Python 3 fixes **0.9.1 (2012-08-28)** - 'wheel sign' uses the keys generated by 'wheel keygen' (instead of generating a new key at random each time) - Python 2/3 encoding/decoding fixes - Run tests on Python 2.6 (without signature verification) **0.9 (2012-08-22)** - Updated digital signatures scheme - Python 3 support for digital signatures - Always verify RECORD hashes on extract - "wheel" command line tool to sign, verify, unpack wheel files **0.8 (2012-08-17)** - none/any draft pep tags update - improved wininst2wheel script - doc changes and other improvements **0.7 (2012-07-28)** - sort .dist-info at end of wheel archive - Windows & Python 3 fixes from Paul Moore - pep8 - scripts to convert wininst & egg to wheel **0.6 (2012-07-23)** - require distribute >= 0.6.28 - stop using verlib **0.5 (2012-07-17)** - working pretty well **0.4.2 (2012-07-12)** - hyphenated name fix **0.4 (2012-07-11)** - improve test coverage - improve Windows compatibility - include tox.ini courtesy of Marc Abramowitz - draft hmac sha-256 signing function **0.3 (2012-07-04)** - prototype egg2wheel conversion script **0.2 (2012-07-03)** - Python 3 compatibility **0.1 (2012-06-30)** - Initial version wheel-0.34.2/docs/quickstart.rst0000664000175000017500000000104313414074275016473 0ustar alexalex00000000000000Quickstart ========== To build a wheel for your setuptools based project:: python setup.py bdist_wheel The wheel will go to ``dist/yourproject-.whl``. If you want to make universal (Python 2/3 compatible, pure Python) wheels, add the following section to your ``setup.cfg``:: [bdist_wheel] universal = 1 To convert an ``.egg`` or file to a wheel:: wheel convert youreggfile.egg Similarly, to convert a Windows installer (made using ``python setup.py bdist_wininst``) to a wheel:: wheel convert yourinstaller.exe wheel-0.34.2/docs/reference/0000775000175000017500000000000013614653447015515 5ustar alexalex00000000000000wheel-0.34.2/docs/reference/index.rst0000664000175000017500000000015613414074275017352 0ustar alexalex00000000000000Reference Guide =============== .. toctree:: :maxdepth: 2 wheel_convert wheel_unpack wheel_pack wheel-0.34.2/docs/reference/wheel_convert.rst0000664000175000017500000000161413414074275021107 0ustar alexalex00000000000000wheel convert ============= Usage ----- :: wheel convert [options] [egg_file_or_directory...] Description ----------- Convert one or more eggs (``.egg``; made with ``bdist_egg``) or Windows installers (``.exe``; made with ``bdist_wininst``) into wheels. Egg names must match the standard format: * ``--pyX.Y`` for pure Python wheels * ``--pyX.Y-`` for binary wheels Options ------- .. option:: -d, --dest-dir Directory to store the generated wheels in (defaults to current directory). Examples -------- * Convert a single egg file:: $ wheel convert foobar-1.2.3-py2.7.egg $ ls *.whl foobar-1.2.3-py27-none.whl * If the egg file name is invalid:: $ wheel convert pycharm-debug.egg "pycharm-debug.egg" is not a valid egg name (must match at least name-version-pyX.Y.egg) $ echo $? 1 wheel-0.34.2/docs/reference/wheel_pack.rst0000664000175000017500000000166113430035726020343 0ustar alexalex00000000000000wheel pack ========== Usage ----- :: wheel pack Description ----------- Repack a previously unpacked wheel file. This command can be used to repack a wheel file after its contents have been modified. This is the equivalent of ``zip -r `` except that it regenerates the ``RECORD`` file which contains hashes of all included files. Options ------- .. option:: -d, --dest-dir Directory to put the new wheel file into. .. option:: --build-number Override the build tag in the new wheel file name Examples -------- * Unpack a wheel, add a dummy module and then repack it (with a new build number):: $ wheel unpack someproject-1.5.0-py2-py3-none.whl Unpacking to: ./someproject-1.5.0 $ touch someproject-1.5.0/somepackage/module.py $ wheel pack --build-number 2 someproject-1.5.0 Repacking wheel as ./someproject-1.5.0-2-py2-py3-none.whl...OK wheel-0.34.2/docs/reference/wheel_unpack.rst0000664000175000017500000000146313414074275020712 0ustar alexalex00000000000000wheel unpack ============ Usage ----- :: wheel unpack Description ----------- Unpack the given wheel file. This is the equivalent of ``unzip ``, except that it also checks that the hashes and file sizes match with those in ``RECORD`` and exits with an error if it encounters a mismatch. Options ------- .. option:: -d, --dest-dir Directory to unpack the wheel into. Examples -------- * Unpack a wheel:: $ wheel unpack someproject-1.5.0-py2-py3-none.whl Unpacking to: ./someproject-1.5.0 * If a file's hash does not match:: $ wheel unpack someproject-1.5.0-py2-py3-none.whl Unpacking to: ./someproject-1.5.0 Traceback (most recent call last): ... wheel.install.BadWheelFile: Bad hash for file 'mypackage/module.py' $ echo $? 1 wheel-0.34.2/docs/story.rst0000664000175000017500000000754513414074275015476 0ustar alexalex00000000000000The Story of Wheel ================== I was impressed with Tarek’s packaging talk at PyCon 2010, and I admire PEP 345 (Metadata for Python Software Packages 1.2) and PEP 376 (Database of Installed Python Distributions) which standardize a richer metadata format and show how distributions should be installed on disk. So naturally with all the hubbub about `packaging` in Python 3.3, I decided to try it to reap the benefits of a more standardized and predictable Python packaging experience. I began by converting `cryptacular`, a password hashing package which has a simple C extension, to use setup.cfg. I downloaded the Python 3.3 source, struggled with the difference between setup.py and setup.cfg syntax, fixed the `define_macros` feature, stopped using the missing `extras` functionality, and several hours later I was able to generate my `METADATA` from `setup.cfg`. I rejoiced at my newfound freedom from the tyranny of arbitrary code execution during the build and install process. It was a lot of work. The package is worse off than before, and it can’t be built or installed without patching the Python source code itself. It was about that time that distutils-sig had a discussion about the need to include a generated setup.cfg from setup.cfg because setup.cfg wasn’t static enough. Wait, what? Of course there is a different way to massively simplify the install process. It’s called built or binary packages. You never have to run `setup.py` because there is no `setup.py`. There is only METADATA aka PKG-INFO. Installation has two steps: ‘build package’; ‘install package’, and you can skip the first step, have someone else do it for you, do it on another machine, or install the build system from a binary package and let the build system handle the building. The build is still complicated, but installation is simple. With the binary package strategy people who want to install use a simple, compatible installer, and people who want to package use whatever is convenient for them for as long as it meets their needs. No one has to rewrite `setup.py` for their own or the 20k+ other packages on PyPI unless a different build system does a better job. Wheel is my attempt to benefit from the excellent distutils-sig work without having to fix the intractable `distutils` software itself. Like METADATA and .dist-info directories but unlike Extension(), it’s simple enough that there really could be alternate implementations; the simplest (but less than ideal) installer is nothing more than “unzip archive.whl” somewhere on sys.path. If you’ve made it this far you probably wonder whether I’ve heard of eggs. Some comparisons: * Wheel is an installation format; egg is importable. Wheel archives do not need to include .pyc and are less tied to a specific Python version or implementation. Wheel can install (pure Python) packages built with previous versions of Python so you don’t always have to wait for the packager to catch up. * Wheel uses .dist-info directories; egg uses .egg-info. Wheel is compatible with the new world of Python `packaging` and the new concepts it brings. * Wheel has a richer file naming convention for today’s multi-implementation world. A single wheel archive can indicate its compatibility with a number of Python language versions and implementations, ABIs, and system architectures. Historically the ABI has been specific to a CPython release, but when we get a longer-term ABI, wheel will be ready. * Wheel is lossless. The first wheel implementation `bdist_wheel` always generates `egg-info`, and then converts it to a `.whl`. Later tools will allow for the conversion of existing eggs and bdist_wininst distributions. * Wheel is versioned. Every wheel file contains the version of the wheel specification and the implementation that packaged it. Hopefully the next migration can simply be to Wheel 2.0. I hope you will benefit from wheel. wheel-0.34.2/docs/user_guide.rst0000664000175000017500000000614613613340346016441 0ustar alexalex00000000000000User Guide ========== Building Wheels --------------- Building wheels from a setuptools_ based project is simple:: python setup.py bdist_wheel This will build any C extensions in the project and then package those and the pure Python code into a ``.whl`` file in the ``dist`` directory. If your project contains no C extensions and is expected to work on both Python 2 and 3, you will want to tell wheel to produce universal wheels by adding this to your ``setup.cfg`` file: .. code-block:: ini [bdist_wheel] universal = 1 .. _setuptools: https://pypi.org/project/setuptools/ Including license files in the generated wheel file --------------------------------------------------- Several open source licenses require the license text to be included in every distributable artifact of the project. By default, ``wheel`` conveniently includes files matching the following glob_ patterns in the ``.dist-info`` directory: * ``AUTHORS*`` * ``COPYING*`` * ``LICEN[CS]E*`` * ``NOTICE*`` This can be overridden by setting the ``license_files`` option in the ``[metadata]`` section of the project's ``setup.cfg``. For example: .. code-block:: cfg [metadata] license_files = license.txt 3rdparty/*.txt No matter the path, all the matching license files are written in the wheel in the ``.dist-info`` directory based on their file name only. By specifying an empty ``license_files`` option, you can disable this functionality entirely. .. note:: There used to be an option called ``license_file`` (singular). As of wheel v0.32, this option has been deprecated in favor of the more versatile ``license_files`` option. .. _glob: https://docs.python.org/library/glob.html Converting Eggs to Wheels ------------------------- The wheel tool is capable of converting eggs to the wheel format. It works on both ``.egg`` files and ``.egg`` directories, and you can convert multiple eggs with a single command:: wheel convert blah-1.2.3-py2.7.egg foo-2.0b1-py3.5.egg The command supports wildcard expansion as well (via :func:`~glob.iglob`) to accommodate shells that do not do such expansion natively:: wheel convert *.egg By default, the resulting wheels are written to the current working directory. This can be changed with the ``--dest-dir`` option:: wheel convert --dest-dir /tmp blah-1.2.3-py2.7.egg Installing Wheels ----------------- .. note:: The ``wheel install`` command is merely a Proof-Of-Concept implementation and lacks many features provided by pip_. It is meant only as an example for implementors of packaging tools. End users should use ``pip install`` instead. To install a wheel file in ``site-packages``:: $ wheel install someproject-1.5.0-py2-py3-none.whl This will unpack the archive in your current site packages directory and install any console scripts contained in the wheel. You can accomplish the same in two separate steps (with ```` being the path to your ``site-packages`` directory:: $ wheel unpack -d someproject-X.Y.Z-py2-py3-none.whl $ wheel install-scripts someproject .. _pip: https://pypi.org/project/pip/ wheel-0.34.2/manpages/0000775000175000017500000000000013614653447014422 5ustar alexalex00000000000000wheel-0.34.2/manpages/wheel.rst0000664000175000017500000000114613414074275016254 0ustar alexalex00000000000000:orphan: wheel manual page ================= Synopsis -------- **wheel** [*command*] [*options*] Description ----------- :program:`wheel` installs and operates on `PEP 427`_ format binary wheels. Commands -------- ``unpack`` Unpack wheel ``pack`` Repack a previously unpacked wheel ``convert`` Convert egg or wininst to wheel ``version`` Print version and exit ``help`` Show this help Try ``wheel --help`` for more information. Options ------- -h, --help show this help message and exit .. _`PEP 427`: https://www.python.org/dev/peps/pep-0427/ wheel-0.34.2/setup.cfg0000664000175000017500000000314313614653447014451 0ustar alexalex00000000000000[metadata] name = wheel version = attr: wheel.__version__ description = A built-package format for Python long_description = file: README.rst classifiers = Development Status :: 5 - Production/Stable Intended Audience :: Developers Topic :: System :: Archiving :: Packaging License :: OSI Approved :: MIT License Programming Language :: Python Programming Language :: Python :: 2 Programming Language :: Python :: 2.7 Programming Language :: Python :: 3 Programming Language :: Python :: 3.5 Programming Language :: Python :: 3.6 Programming Language :: Python :: 3.7 Programming Language :: Python :: 3.8 author = Daniel Holth author_email = dholth@fastmail.fm maintainer = Alex Gronholm maintainer_email = alex.gronholm@nextday.fi url = https://github.com/pypa/wheel project_urls = Documentation = https://wheel.readthedocs.io/ Changelog = https://wheel.readthedocs.io/en/stable/news.html Issue Tracker = https://github.com/pypa/wheel/issues keywords = wheel, packaging license = MIT [options] package_dir = = src packages = find: python_requires = >=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.* setup_requires = setuptools >= 40.9.0 zip_safe = False [options.packages.find] where = src [options.extras_require] test = pytest >= 3.0.0 pytest-cov [options.entry_points] console_scripts = wheel = wheel.cli:main distutils.commands = bdist_wheel = wheel.bdist_wheel:bdist_wheel [tool:pytest] addopts = --cov=wheel testpaths = tests [coverage:run] source = wheel [coverage:report] show_missing = true [flake8] max-line-length = 99 [bdist_wheel] universal = 1 [egg_info] tag_build = tag_date = 0 wheel-0.34.2/setup.py0000664000175000017500000000012213614045217014322 0ustar alexalex00000000000000# coding: utf-8 from setuptools import setup setup(maintainer=u'Alex Grönholm') wheel-0.34.2/src/0000775000175000017500000000000013614653447013416 5ustar alexalex00000000000000wheel-0.34.2/src/wheel/0000775000175000017500000000000013614653447014522 5ustar alexalex00000000000000wheel-0.34.2/src/wheel/__init__.py0000664000175000017500000000002713614653207016624 0ustar alexalex00000000000000__version__ = '0.34.2' wheel-0.34.2/src/wheel/__main__.py0000664000175000017500000000064113613340346016603 0ustar alexalex00000000000000""" 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()) wheel-0.34.2/src/wheel/_version.py0000664000175000017500000000020513613340525016702 0ustar alexalex00000000000000# coding: utf-8 # file generated by setuptools_scm # don't change, don't track in version control version = '0.33.6.post32+gd3d7a43' wheel-0.34.2/src/wheel/bdist_wheel.py0000664000175000017500000003674013613513321017360 0ustar alexalex00000000000000""" 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) wheel-0.34.2/src/wheel/cli/0000775000175000017500000000000013614653447015271 5ustar alexalex00000000000000wheel-0.34.2/src/wheel/cli/__init__.py0000664000175000017500000000501413613340346017370 0ustar alexalex00000000000000""" 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 wheel-0.34.2/src/wheel/cli/convert.py0000775000175000017500000002243213613340346017317 0ustar alexalex00000000000000import 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") wheel-0.34.2/src/wheel/cli/pack.py0000664000175000017500000000621013613340346016546 0ustar alexalex00000000000000from __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') wheel-0.34.2/src/wheel/cli/unpack.py0000664000175000017500000000124113613340346017110 0ustar alexalex00000000000000from __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') wheel-0.34.2/src/wheel/macosx_libfile.py0000664000175000017500000002712213613340346020046 0ustar alexalex00000000000000""" 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 wheel-0.34.2/src/wheel/metadata.py0000664000175000017500000001064513613340346016650 0ustar alexalex00000000000000""" 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 wheel-0.34.2/src/wheel/pep425tags.py0000664000175000017500000002155713613642044016772 0ustar alexalex00000000000000"""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 wheel-0.34.2/src/wheel/pkginfo.py0000664000175000017500000000235113613340346016520 0ustar alexalex00000000000000"""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) wheel-0.34.2/src/wheel/util.py0000664000175000017500000000165213613340346016043 0ustar alexalex00000000000000import 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 wheel-0.34.2/src/wheel/wheelfile.py0000664000175000017500000001620213613513321017022 0ustar alexalex00000000000000from __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) wheel-0.34.2/src/wheel.egg-info/0000775000175000017500000000000013614653447016214 5ustar alexalex00000000000000wheel-0.34.2/src/wheel.egg-info/PKG-INFO0000664000175000017500000000453013614653447017313 0ustar alexalex00000000000000Metadata-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 Description: 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/ 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 wheel-0.34.2/src/wheel.egg-info/SOURCES.txt0000664000175000017500000000542613614653447020107 0ustar alexalex00000000000000.gitignore LICENSE.txt MANIFEST.in README.rst setup.cfg setup.py tox.ini .github/workflows/codeqa-test-tag.yml docs/Makefile docs/conf.py docs/development.rst docs/index.rst docs/installing.rst docs/make.bat docs/news.rst docs/quickstart.rst docs/story.rst docs/user_guide.rst docs/reference/index.rst docs/reference/wheel_convert.rst docs/reference/wheel_pack.rst docs/reference/wheel_unpack.rst manpages/wheel.rst src/wheel/__init__.py src/wheel/__main__.py src/wheel/_version.py src/wheel/bdist_wheel.py src/wheel/macosx_libfile.py src/wheel/metadata.py src/wheel/pep425tags.py src/wheel/pkginfo.py src/wheel/util.py src/wheel/wheelfile.py src/wheel.egg-info/PKG-INFO src/wheel.egg-info/SOURCES.txt src/wheel.egg-info/dependency_links.txt src/wheel.egg-info/entry_points.txt src/wheel.egg-info/not-zip-safe src/wheel.egg-info/requires.txt src/wheel.egg-info/top_level.txt src/wheel/cli/__init__.py src/wheel/cli/convert.py src/wheel/cli/pack.py src/wheel/cli/unpack.py tests/conftest.py tests/test_bdist_wheel.py tests/test_macosx_libfile.py tests/test_metadata.py tests/test_pkginfo.py tests/test_tagopt.py tests/test_wheelfile.py tests/cli/eggnames.txt tests/cli/test_convert.py tests/cli/test_pack.py tests/cli/test_unpack.py tests/testdata/test-1.0-py2.py3-none-any.whl tests/testdata/abi3extension.dist/extension.c tests/testdata/abi3extension.dist/setup.cfg tests/testdata/abi3extension.dist/setup.py tests/testdata/complex-dist/setup.py tests/testdata/complex-dist/complexdist/__init__.py tests/testdata/extension.dist/extension.c tests/testdata/extension.dist/setup.py tests/testdata/headers.dist/header.h tests/testdata/headers.dist/headersdist.py tests/testdata/headers.dist/setup.cfg tests/testdata/headers.dist/setup.py tests/testdata/macosx_minimal_system_version/libb.dylib tests/testdata/macosx_minimal_system_version/test_lib.c tests/testdata/macosx_minimal_system_version/test_lib_10_10.dylib tests/testdata/macosx_minimal_system_version/test_lib_10_10_10.dylib tests/testdata/macosx_minimal_system_version/test_lib_10_10_386.dylib tests/testdata/macosx_minimal_system_version/test_lib_10_10_fat.dylib tests/testdata/macosx_minimal_system_version/test_lib_10_14.dylib tests/testdata/macosx_minimal_system_version/test_lib_10_14_386.dylib tests/testdata/macosx_minimal_system_version/test_lib_10_14_fat.dylib tests/testdata/macosx_minimal_system_version/test_lib_10_6.dylib tests/testdata/macosx_minimal_system_version/test_lib_10_6_386.dylib tests/testdata/macosx_minimal_system_version/test_lib_10_6_fat.dylib tests/testdata/macosx_minimal_system_version/test_lib_multiple_fat.dylib tests/testdata/simple.dist/setup.py tests/testdata/simple.dist/simpledist/__init__.py tests/testdata/unicode.dist/setup.py tests/testdata/unicode.dist/unicodedist/__init__.py tests/testdata/unicode.dist/unicodedist/åäö_日本語.pywheel-0.34.2/src/wheel.egg-info/dependency_links.txt0000664000175000017500000000000113614653447022262 0ustar alexalex00000000000000 wheel-0.34.2/src/wheel.egg-info/entry_points.txt0000664000175000017500000000015413614653447021512 0ustar alexalex00000000000000[console_scripts] wheel = wheel.cli:main [distutils.commands] bdist_wheel = wheel.bdist_wheel:bdist_wheel wheel-0.34.2/src/wheel.egg-info/not-zip-safe0000664000175000017500000000000113611674406020435 0ustar alexalex00000000000000 wheel-0.34.2/src/wheel.egg-info/requires.txt0000664000175000017500000000004113614653447020607 0ustar alexalex00000000000000 [test] pytest>=3.0.0 pytest-cov wheel-0.34.2/src/wheel.egg-info/top_level.txt0000664000175000017500000000000613614653447020742 0ustar alexalex00000000000000wheel wheel-0.34.2/tests/0000775000175000017500000000000013614653447013771 5ustar alexalex00000000000000wheel-0.34.2/tests/cli/0000775000175000017500000000000013614653447014540 5ustar alexalex00000000000000wheel-0.34.2/tests/cli/eggnames.txt0000664000175000017500000000467213414074275017072 0ustar alexalex00000000000000vcard-0.7.8-py2.7.egg qtalchemy-0.7.1-py2.7.egg AMQPDeliver-0.1-py2.7.egg infi.registry-0.1.1-py2.7.egg infi.instruct-0.5.5-py2.7.egg infi.devicemanager-0.1.2-py2.7.egg TracTixSummary-1.0-py2.7.egg ToscaWidgets-0.9.12-py2.7.egg archipel_agent_iphone_notification-0.5.0beta-py2.7.egg archipel_agent_action_scheduler-0.5.0beta-py2.7.egg ao.social-1.0.2-py2.7.egg apgl-0.7-py2.7.egg satchmo_payment_payworld-0.1.1-py2.7.egg snmpsim-0.1.3-py2.7.egg sshim-0.2-py2.7.egg shove-0.3.4-py2.7.egg simpleavro-0.3.0-py2.7.egg wkhtmltopdf-0.2-py2.7.egg wokkel-0.7.0-py2.7.egg jmbo_social-0.0.6-py2.7.egg jmbo_post-0.0.6-py2.7.egg jcrack-0.0.2-py2.7.egg riak-1.4.0-py2.7.egg restclient-0.10.2-py2.7.egg Sutekh-0.8.1-py2.7.egg trayify-0.0.1-py2.7.egg tweepy-1.9-py2.7.egg topzootools-0.2.1-py2.7.egg haystack-0.16-py2.7.egg zope.interface-4.0.1-py2.7-win32.egg neuroshare-0.8.5-py2.7-macosx-10.7-intel.egg ndg_httpsclient-0.2.0-py2.7.egg libtele-0.3-py2.7.egg litex.cxpool-1.0.2-py2.7.egg obspy.iris-0.5.1-py2.7.egg obspy.mseed-0.6.1-py2.7-win32.egg obspy.core-0.6.2-py2.7.egg CorePost-0.0.3-py2.7.egg fnordstalk-0.0.3-py2.7.egg Persistence-2.13.2-py2.7-win32.egg Pydap-3.1.RC1-py2.7.egg PyExecJS-1.0.4-py2.7.egg Wally-0.7.2-py2.7.egg ExtensionClass-4.0a1-py2.7-win32.egg Feedjack-0.9.16-py2.7.egg Mars24-0.3.9-py2.7.egg HalWeb-0.6.0-py2.7.egg DARE-0.7.140-py2.7.egg macholib-1.3-py2.7.egg marrow.wsgi.egress.compression-1.1-py2.7.egg mcs-0.3.7-py2.7.egg Kook-0.6.0-py2.7.egg er-0.1-py2.7.egg evasion_director-1.1.4-py2.7.egg djquery-0.1a-py2.7.egg django_factory-0.7-py2.7.egg django_gizmo-0.0.3-py2.7.egg django_category-0.1-py2.7.egg dbwrap-0.3.2-py2.7.egg django_supergeneric-1.0-py2.7.egg django_dynamo-0.25-py2.7.egg django_acollabauth-0.1-py2.7.egg django_qrlink-0.1.0-py2.7.egg django_addons-0.6.6-py2.7.egg cover_grabber-1.1.2-py2.7.egg chem-1.1-py2.7.egg crud-0.1-py2.7.egg bongo-0.1-py2.7.egg bytecodehacks-April2000-py2.7.egg greenlet-0.3.4-py2.7-win32.egg ginvoke-0.3.1-py2.7.egg pyobjc_framework_ScriptingBridge-2.3-py2.7.egg pecan-0.2.0a-py2.7.egg pyress-0.2.0-py2.7.egg pyobjc_framework_PubSub-2.3-py2.7.egg pyobjc_framework_ExceptionHandling-2.3-py2.7.egg pywps-trunk-py2.7.egg pyobjc_framework_CFNetwork-2.3-py2.7-macosx-10.6-fat.egg py.saunter-0.40-py2.7.egg pyfnordmetric-0.0.1-py2.7.egg pyws-1.1.1-py2.7.egg prestapyt-0.4.0-py2.7.egg passlib-1.5.3-py2.7.egg pyga-2.1-py2.7.egg pygithub3-0.3-py2.7.egg pyobjc_framework_OpenDirectory-2.3-py2.7.egg yaposib-0.2.75-py2.7-linux-x86_64.egg wheel-0.34.2/tests/cli/test_convert.py0000664000175000017500000000150613414074275017625 0ustar alexalex00000000000000import os.path import re from wheel.cli.convert import convert, egg_info_re from wheel.wheelfile import WHEEL_INFO_RE def test_egg_re(): """Make sure egg_info_re matches.""" egg_names_path = os.path.join(os.path.dirname(__file__), 'eggnames.txt') with open(egg_names_path) as egg_names: for line in egg_names: line = line.strip() if line: assert egg_info_re.match(line), line def test_convert_egg(egg_paths, tmpdir): convert(egg_paths, str(tmpdir), verbose=False) wheel_names = [path.basename for path in tmpdir.listdir()] assert len(wheel_names) == len(egg_paths) assert all(WHEEL_INFO_RE.match(filename) for filename in wheel_names) assert all(re.match(r'^[\w\d.]+-\d\.\d-\w+\d+-[\w\d]+-[\w\d]+\.whl$', fname) for fname in wheel_names) wheel-0.34.2/tests/cli/test_pack.py0000664000175000017500000000430013613340346017052 0ustar alexalex00000000000000import os from zipfile import ZipFile import pytest from wheel.cli.pack import pack THISDIR = os.path.dirname(__file__) TESTWHEEL_NAME = 'test-1.0-py2.py3-none-any.whl' TESTWHEEL_PATH = os.path.join(THISDIR, '..', 'testdata', TESTWHEEL_NAME) @pytest.mark.filterwarnings('error:Duplicate name') @pytest.mark.parametrize('build_tag_arg, existing_build_tag, filename', [ (None, None, 'test-1.0-py2.py3-none-any.whl'), ('2b', None, 'test-1.0-2b-py2.py3-none-any.whl'), (None, '3', 'test-1.0-3-py2.py3-none-any.whl'), ('', '3', 'test-1.0-py2.py3-none-any.whl'), ], ids=['nobuildnum', 'newbuildarg', 'oldbuildnum', 'erasebuildnum']) def test_pack(tmpdir_factory, tmpdir, build_tag_arg, existing_build_tag, filename): unpack_dir = tmpdir_factory.mktemp('wheeldir') with ZipFile(TESTWHEEL_PATH) as zf: old_record = zf.read('test-1.0.dist-info/RECORD') old_record_lines = sorted(line.rstrip() for line in old_record.split(b'\n') if line and not line.startswith(b'test-1.0.dist-info/WHEEL,')) zf.extractall(str(unpack_dir)) if existing_build_tag: # Add the build number to WHEEL wheel_file_path = unpack_dir.join('test-1.0.dist-info').join('WHEEL') wheel_file_content = wheel_file_path.read_binary() assert b'Build' not in wheel_file_content wheel_file_content += b'Build: 3\r\n' wheel_file_path.write_binary(wheel_file_content) pack(str(unpack_dir), str(tmpdir), build_tag_arg) new_wheel_path = tmpdir.join(filename) assert new_wheel_path.isfile() with ZipFile(str(new_wheel_path)) as zf: new_record = zf.read('test-1.0.dist-info/RECORD') new_record_lines = sorted(line.rstrip() for line in new_record.split(b'\n') if line and not line.startswith(b'test-1.0.dist-info/WHEEL,')) new_wheel_file_content = zf.read('test-1.0.dist-info/WHEEL') assert new_record_lines == old_record_lines expected_build_num = build_tag_arg or existing_build_tag if expected_build_num: assert ('Build: %s\r\n' % expected_build_num).encode() in new_wheel_file_content else: assert b'Build: ' not in new_wheel_file_content wheel-0.34.2/tests/cli/test_unpack.py0000664000175000017500000000041413414074275017423 0ustar alexalex00000000000000from wheel.cli.unpack import unpack def test_unpack(wheel_paths, tmpdir): """ Make sure 'wheel unpack' works. This also verifies the integrity of our testing wheel files. """ for wheel_path in wheel_paths: unpack(wheel_path, str(tmpdir)) wheel-0.34.2/tests/conftest.py0000664000175000017500000000300513613340346016154 0ustar alexalex00000000000000""" pytest local configuration plug-in """ import os.path import subprocess import sys import pytest @pytest.fixture(scope='session') def wheels_and_eggs(tmpdir_factory): """Build wheels and eggs from test distributions.""" test_distributions = "complex-dist", "simple.dist", "headers.dist" if sys.version_info >= (3, 6): # Only Python 3.6+ can handle packaging unicode file names reliably # across different platforms test_distributions += ("unicode.dist",) if sys.platform != 'win32': # ABI3 extensions don't really work on Windows test_distributions += ("abi3extension.dist",) pwd = os.path.abspath(os.curdir) this_dir = os.path.dirname(__file__) build_dir = tmpdir_factory.mktemp('build') dist_dir = tmpdir_factory.mktemp('dist') for dist in test_distributions: os.chdir(os.path.join(this_dir, 'testdata', dist)) subprocess.check_call([sys.executable, 'setup.py', 'bdist_egg', '-b', str(build_dir), '-d', str(dist_dir), 'bdist_wheel', '-b', str(build_dir), '-d', str(dist_dir)]) os.chdir(pwd) return sorted(str(fname) for fname in dist_dir.listdir() if fname.ext in ('.whl', '.egg')) @pytest.fixture(scope='session') def wheel_paths(wheels_and_eggs): return [fname for fname in wheels_and_eggs if fname.endswith('.whl')] @pytest.fixture(scope='session') def egg_paths(wheels_and_eggs): return [fname for fname in wheels_and_eggs if fname.endswith('.egg')] wheel-0.34.2/tests/test_bdist_wheel.py0000664000175000017500000001330213613513321017653 0ustar alexalex00000000000000# coding: utf-8 import os.path import shutil import stat import subprocess import sys from zipfile import ZipFile import pytest from wheel.bdist_wheel import bdist_wheel from wheel.wheelfile import WheelFile DEFAULT_FILES = { 'dummy_dist-1.0.dist-info/top_level.txt', 'dummy_dist-1.0.dist-info/METADATA', 'dummy_dist-1.0.dist-info/WHEEL', 'dummy_dist-1.0.dist-info/RECORD' } DEFAULT_LICENSE_FILES = { 'LICENSE', 'LICENSE.txt', 'LICENCE', 'LICENCE.txt', 'COPYING', 'COPYING.md', 'NOTICE', 'NOTICE.rst', 'AUTHORS', 'AUTHORS.txt' } @pytest.fixture def dummy_dist(tmpdir_factory): basedir = tmpdir_factory.mktemp('dummy_dist') basedir.join('setup.py').write("""\ from setuptools import setup setup( name='dummy_dist', version='1.0' ) """) for fname in DEFAULT_LICENSE_FILES: basedir.join(fname).write('') basedir.join('licenses').mkdir().join('DUMMYFILE').write('') return basedir def test_no_scripts(wheel_paths): """Make sure entry point scripts are not generated.""" path = next(path for path in wheel_paths if 'complex_dist' in path) for entry in ZipFile(path).infolist(): assert '.data/scripts/' not in entry.filename @pytest.mark.skipif(sys.version_info < (3, 6), reason='Packaging unicode file names only works reliably on Python 3.6+') def test_unicode_record(wheel_paths): path = next(path for path in wheel_paths if 'unicode.dist' in path) with ZipFile(path) as zf: record = zf.read('unicode.dist-0.1.dist-info/RECORD') assert u'åäö_日本語.py'.encode('utf-8') in record def test_licenses_default(dummy_dist, monkeypatch, tmpdir): monkeypatch.chdir(dummy_dist) subprocess.check_call([sys.executable, 'setup.py', 'bdist_wheel', '-b', str(tmpdir), '--universal']) with WheelFile('dist/dummy_dist-1.0-py2.py3-none-any.whl') as wf: license_files = {'dummy_dist-1.0.dist-info/' + fname for fname in DEFAULT_LICENSE_FILES} assert set(wf.namelist()) == DEFAULT_FILES | license_files def test_licenses_deprecated(dummy_dist, monkeypatch, tmpdir): dummy_dist.join('setup.cfg').write('[metadata]\nlicense_file=licenses/DUMMYFILE') monkeypatch.chdir(dummy_dist) subprocess.check_call([sys.executable, 'setup.py', 'bdist_wheel', '-b', str(tmpdir), '--universal']) with WheelFile('dist/dummy_dist-1.0-py2.py3-none-any.whl') as wf: license_files = {'dummy_dist-1.0.dist-info/DUMMYFILE'} assert set(wf.namelist()) == DEFAULT_FILES | license_files def test_licenses_override(dummy_dist, monkeypatch, tmpdir): dummy_dist.join('setup.cfg').write('[metadata]\nlicense_files=licenses/*\n LICENSE') monkeypatch.chdir(dummy_dist) subprocess.check_call([sys.executable, 'setup.py', 'bdist_wheel', '-b', str(tmpdir), '--universal']) with WheelFile('dist/dummy_dist-1.0-py2.py3-none-any.whl') as wf: license_files = {'dummy_dist-1.0.dist-info/' + fname for fname in {'DUMMYFILE', 'LICENSE'}} assert set(wf.namelist()) == DEFAULT_FILES | license_files def test_licenses_disabled(dummy_dist, monkeypatch, tmpdir): dummy_dist.join('setup.cfg').write('[metadata]\nlicense_files=\n') monkeypatch.chdir(dummy_dist) subprocess.check_call([sys.executable, 'setup.py', 'bdist_wheel', '-b', str(tmpdir), '--universal']) with WheelFile('dist/dummy_dist-1.0-py2.py3-none-any.whl') as wf: assert set(wf.namelist()) == DEFAULT_FILES def test_build_number(dummy_dist, monkeypatch, tmpdir): monkeypatch.chdir(dummy_dist) subprocess.check_call([sys.executable, 'setup.py', 'bdist_wheel', '-b', str(tmpdir), '--universal', '--build-number=2']) with WheelFile('dist/dummy_dist-1.0-2-py2.py3-none-any.whl') as wf: filenames = set(wf.namelist()) assert 'dummy_dist-1.0.dist-info/RECORD' in filenames assert 'dummy_dist-1.0.dist-info/METADATA' in filenames @pytest.mark.skipif(sys.version_info[0] < 3, reason='The limited ABI only works on Python 3+') def test_limited_abi(monkeypatch, tmpdir): """Test that building a binary wheel with the limited ABI works.""" this_dir = os.path.dirname(__file__) source_dir = os.path.join(this_dir, 'testdata', 'extension.dist') build_dir = tmpdir.join('build') dist_dir = tmpdir.join('dist') monkeypatch.chdir(source_dir) subprocess.check_call([sys.executable, 'setup.py', 'bdist_wheel', '-b', str(build_dir), '-d', str(dist_dir)]) def test_build_from_readonly_tree(dummy_dist, monkeypatch, tmpdir): basedir = str(tmpdir.join('dummy')) shutil.copytree(str(dummy_dist), basedir) monkeypatch.chdir(basedir) # Make the tree read-only for root, dirs, files in os.walk(basedir): for fname in files: os.chmod(os.path.join(root, fname), stat.S_IREAD) subprocess.check_call([sys.executable, 'setup.py', 'bdist_wheel']) @pytest.mark.parametrize('option, compress_type', list(bdist_wheel.supported_compressions.items()), ids=list(bdist_wheel.supported_compressions)) def test_compression(dummy_dist, monkeypatch, tmpdir, option, compress_type): monkeypatch.chdir(dummy_dist) subprocess.check_call([sys.executable, 'setup.py', 'bdist_wheel', '-b', str(tmpdir), '--universal', '--compression={}'.format(option)]) with WheelFile('dist/dummy_dist-1.0-py2.py3-none-any.whl') as wf: filenames = set(wf.namelist()) assert 'dummy_dist-1.0.dist-info/RECORD' in filenames assert 'dummy_dist-1.0.dist-info/METADATA' in filenames for zinfo in wf.filelist: assert zinfo.compress_type == compress_type wheel-0.34.2/tests/test_macosx_libfile.py0000664000175000017500000001461013613340346020352 0ustar alexalex00000000000000import os import sys import distutils.util from wheel.macosx_libfile import extract_macosx_min_system_version from wheel.pep425tags import get_platform def test_read_from_dylib(): dirname = os.path.dirname(__file__) dylib_dir = os.path.join(dirname, "testdata", "macosx_minimal_system_version") versions = [ ("test_lib_10_6_fat.dylib", "10.6.0"), ("test_lib_10_10_fat.dylib", "10.10.0"), ("test_lib_10_14_fat.dylib", "10.14.0"), ("test_lib_10_6.dylib", "10.6.0"), ("test_lib_10_10.dylib", "10.10.0"), ("test_lib_10_14.dylib", "10.14.0"), ("test_lib_10_6_386.dylib", "10.6.0"), ("test_lib_10_10_386.dylib", "10.10.0"), ("test_lib_10_14_386.dylib", "10.14.0"), ("test_lib_multiple_fat.dylib", "10.14.0"), ("test_lib_10_10_10.dylib", "10.10.10") ] for file_name, ver in versions: extracted = extract_macosx_min_system_version( os.path.join(dylib_dir, file_name) ) str_ver = ".".join([str(x) for x in extracted]) assert str_ver == ver assert extract_macosx_min_system_version( os.path.join(dylib_dir, "test_lib.c") ) is None assert extract_macosx_min_system_version( os.path.join(dylib_dir, "libb.dylib") ) is None def return_factory(return_val): def fun(*args, **kwargs): return return_val return fun class TestGetPlatformMacosx: def test_simple(self, monkeypatch): dirname = os.path.dirname(__file__) dylib_dir = os.path.join(dirname, "testdata", "macosx_minimal_system_version") monkeypatch.setattr(distutils.util, "get_platform", return_factory("macosx-10.14-x86_64")) assert get_platform(dylib_dir) == "macosx_10_14_x86_64" def test_version_bump(self, monkeypatch, capsys): dirname = os.path.dirname(__file__) dylib_dir = os.path.join(dirname, "testdata", "macosx_minimal_system_version") monkeypatch.setattr(distutils.util, "get_platform", return_factory("macosx-10.9-x86_64")) assert get_platform(dylib_dir) == "macosx_10_14_x86_64" captured = capsys.readouterr() assert "[WARNING] This wheel needs a higher macOS version than" in captured.err def test_information_about_problematic_files_python_version(self, monkeypatch, capsys): dirname = os.path.dirname(__file__) dylib_dir = os.path.join(dirname, "testdata", "macosx_minimal_system_version") monkeypatch.setattr(distutils.util, "get_platform", return_factory("macosx-10.9-x86_64")) monkeypatch.setattr(os, "walk", return_factory( [(dylib_dir, [], ["test_lib_10_6.dylib", "test_lib_10_10_fat.dylib"])] )) assert get_platform(dylib_dir) == "macosx_10_10_x86_64" captured = capsys.readouterr() assert "[WARNING] This wheel needs a higher macOS version than" in captured.err assert "the version your Python interpreter is compiled against." in captured.err assert "test_lib_10_10_fat.dylib" in captured.err def test_information_about_problematic_files_env_variable(self, monkeypatch, capsys): dirname = os.path.dirname(__file__) dylib_dir = os.path.join(dirname, "testdata", "macosx_minimal_system_version") monkeypatch.setattr(distutils.util, "get_platform", return_factory("macosx-10.9-x86_64")) monkeypatch.setenv("MACOSX_DEPLOYMENT_TARGET", "10.8") monkeypatch.setattr(os, "walk", return_factory( [(dylib_dir, [], ["test_lib_10_6.dylib", "test_lib_10_10_fat.dylib"])] )) assert get_platform(dylib_dir) == "macosx_10_10_x86_64" captured = capsys.readouterr() assert "[WARNING] This wheel needs a higher macOS version than" in captured.err assert "is set in MACOSX_DEPLOYMENT_TARGET variable." in captured.err assert "test_lib_10_10_fat.dylib" in captured.err def test_bump_platform_tag_by_env_variable(self, monkeypatch, capsys): dirname = os.path.dirname(__file__) dylib_dir = os.path.join(dirname, "testdata", "macosx_minimal_system_version") monkeypatch.setattr(distutils.util, "get_platform", return_factory("macosx-10.9-x86_64")) monkeypatch.setattr(os, "walk", return_factory( [(dylib_dir, [], ["test_lib_10_6.dylib", "test_lib_10_6_fat.dylib"])] )) assert get_platform(dylib_dir) == "macosx_10_9_x86_64" monkeypatch.setenv("MACOSX_DEPLOYMENT_TARGET", "10.10") assert get_platform(dylib_dir) == "macosx_10_10_x86_64" captured = capsys.readouterr() assert captured.err == "" def test_bugfix_release_platform_tag(self, monkeypatch, capsys): dirname = os.path.dirname(__file__) dylib_dir = os.path.join(dirname, "testdata", "macosx_minimal_system_version") monkeypatch.setattr(distutils.util, "get_platform", return_factory("macosx-10.9-x86_64")) monkeypatch.setattr(os, "walk", return_factory( [(dylib_dir, [], ["test_lib_10_6.dylib", "test_lib_10_6_fat.dylib", "test_lib_10_10_10.dylib"])] )) assert get_platform(dylib_dir) == "macosx_10_10_x86_64" captured = capsys.readouterr() assert "This wheel needs a higher macOS version than" in captured.err monkeypatch.setenv("MACOSX_DEPLOYMENT_TARGET", "10.9") assert get_platform(dylib_dir) == "macosx_10_10_x86_64" captured = capsys.readouterr() assert "This wheel needs a higher macOS version than" in captured.err def test_warning_on_to_low_env_variable(self, monkeypatch, capsys): dirname = os.path.dirname(__file__) dylib_dir = os.path.join(dirname, "testdata", "macosx_minimal_system_version") monkeypatch.setattr(distutils.util, "get_platform", return_factory("macosx-10.9-x86_64")) monkeypatch.setenv("MACOSX_DEPLOYMENT_TARGET", "10.8") monkeypatch.setattr(os, "walk", return_factory( [(dylib_dir, [], ["test_lib_10_6.dylib", "test_lib_10_6_fat.dylib"])] )) assert get_platform(dylib_dir) == "macosx_10_9_x86_64" captured = capsys.readouterr() assert "MACOSX_DEPLOYMENT_TARGET is set to a lower value (10.8) than the" in captured.err def test_get_platform_linux(monkeypatch): monkeypatch.setattr(distutils.util, "get_platform", return_factory("linux_x86_64")) monkeypatch.setattr(sys, "maxsize", 2147483647) assert get_platform(None) == "linux_i686" wheel-0.34.2/tests/test_metadata.py0000664000175000017500000000403713414074275017160 0ustar alexalex00000000000000from wheel.metadata import pkginfo_to_metadata def test_pkginfo_to_metadata(tmpdir): expected_metadata = [ ('Metadata-Version', '2.1'), ('Name', 'spam'), ('Version', '0.1'), ('Requires-Dist', "pip @ https://github.com/pypa/pip/archive/1.3.1.zip"), ('Requires-Dist', 'pywin32 ; sys_platform=="win32"'), ('Requires-Dist', 'foo @ http://host/foo.zip ; sys_platform=="win32"'), ('Provides-Extra', 'signatures'), ('Requires-Dist', 'pyxdg ; (sys_platform!="win32") and extra == \'signatures\''), ('Provides-Extra', 'empty_extra'), ('Provides-Extra', 'extra'), ('Requires-Dist', 'bar @ http://host/bar.zip ; extra == \'extra\''), ('Provides-Extra', 'faster-signatures'), ('Requires-Dist', "ed25519ll ; extra == 'faster-signatures'"), ('Provides-Extra', 'rest'), ('Requires-Dist', "docutils (>=0.8) ; extra == 'rest'"), ('Requires-Dist', "keyring ; extra == 'signatures'"), ('Requires-Dist', "keyrings.alt ; extra == 'signatures'"), ('Provides-Extra', 'test'), ('Requires-Dist', "pytest (>=3.0.0) ; extra == 'test'"), ('Requires-Dist', "pytest-cov ; extra == 'test'"), ] pkg_info = tmpdir.join('PKG-INFO') pkg_info.write("""\ Metadata-Version: 0.0 Name: spam Version: 0.1 Provides-Extra: empty+extra Provides-Extra: test Provides-Extra: reST Provides-Extra: signatures Provides-Extra: Signatures Provides-Extra: faster-signatures""") egg_info_dir = tmpdir.ensure_dir('test.egg-info') egg_info_dir.join('requires.txt').write("""\ pip@https://github.com/pypa/pip/archive/1.3.1.zip [extra] bar @ http://host/bar.zip [empty+extra] [:sys_platform=="win32"] pywin32 foo @http://host/foo.zip [faster-signatures] ed25519ll [reST] docutils>=0.8 [signatures] keyring keyrings.alt [Signatures:sys_platform!="win32"] pyxdg [test] pytest>=3.0.0 pytest-cov""") message = pkginfo_to_metadata(egg_info_path=str(egg_info_dir), pkginfo_path=str(pkg_info)) assert message.items() == expected_metadata wheel-0.34.2/tests/test_pkginfo.py0000664000175000017500000000073713414074275017040 0ustar alexalex00000000000000from email.parser import Parser from wheel.pkginfo import write_pkg_info def test_pkginfo_mangle_from(tmpdir): """Test that write_pkginfo() will not prepend a ">" to a line starting with "From".""" metadata = """\ Metadata-Version: 2.1 Name: foo From blahblah ==== Test ==== """ message = Parser().parsestr(metadata) pkginfo_file = tmpdir.join('PKGINFO') write_pkg_info(str(pkginfo_file), message) assert pkginfo_file.read_text('ascii') == metadata wheel-0.34.2/tests/test_tagopt.py0000664000175000017500000001412513526216564016700 0ustar alexalex00000000000000""" Tests for the bdist_wheel tag options (--python-tag, --universal, and --plat-name) """ import subprocess import sys import pytest SETUP_PY = """\ from setuptools import setup, Extension setup( name="Test", version="1.0", author_email="author@example.com", py_modules=["test"], {ext_modules} ) """ EXT_MODULES = "ext_modules=[Extension('_test', sources=['test.c'])]," @pytest.fixture def temp_pkg(request, tmpdir): tmpdir.join('test.py').write('print("Hello, world")') ext = getattr(request, 'param', False) if ext: tmpdir.join('test.c').write('#include ') setup_py = SETUP_PY.format(ext_modules=EXT_MODULES) else: setup_py = SETUP_PY.format(ext_modules='') tmpdir.join('setup.py').write(setup_py) return tmpdir def test_default_tag(temp_pkg): subprocess.check_call([sys.executable, 'setup.py', 'bdist_wheel'], cwd=str(temp_pkg)) dist_dir = temp_pkg.join('dist') assert dist_dir.check(dir=1) wheels = dist_dir.listdir() assert len(wheels) == 1 assert wheels[0].basename == 'Test-1.0-py%s-none-any.whl' % (sys.version_info[0],) assert wheels[0].ext == '.whl' def test_build_number(temp_pkg): subprocess.check_call([sys.executable, 'setup.py', 'bdist_wheel', '--build-number=1'], cwd=str(temp_pkg)) dist_dir = temp_pkg.join('dist') assert dist_dir.check(dir=1) wheels = dist_dir.listdir() assert len(wheels) == 1 assert (wheels[0].basename == 'Test-1.0-1-py%s-none-any.whl' % (sys.version_info[0],)) assert wheels[0].ext == '.whl' def test_explicit_tag(temp_pkg): subprocess.check_call( [sys.executable, 'setup.py', 'bdist_wheel', '--python-tag=py32'], cwd=str(temp_pkg)) dist_dir = temp_pkg.join('dist') assert dist_dir.check(dir=1) wheels = dist_dir.listdir() assert len(wheels) == 1 assert wheels[0].basename.startswith('Test-1.0-py32-') assert wheels[0].ext == '.whl' def test_universal_tag(temp_pkg): subprocess.check_call( [sys.executable, 'setup.py', 'bdist_wheel', '--universal'], cwd=str(temp_pkg)) dist_dir = temp_pkg.join('dist') assert dist_dir.check(dir=1) wheels = dist_dir.listdir() assert len(wheels) == 1 assert wheels[0].basename.startswith('Test-1.0-py2.py3-') assert wheels[0].ext == '.whl' def test_universal_beats_explicit_tag(temp_pkg): subprocess.check_call( [sys.executable, 'setup.py', 'bdist_wheel', '--universal', '--python-tag=py32'], cwd=str(temp_pkg)) dist_dir = temp_pkg.join('dist') assert dist_dir.check(dir=1) wheels = dist_dir.listdir() assert len(wheels) == 1 assert wheels[0].basename.startswith('Test-1.0-py2.py3-') assert wheels[0].ext == '.whl' def test_universal_in_setup_cfg(temp_pkg): temp_pkg.join('setup.cfg').write('[bdist_wheel]\nuniversal=1') subprocess.check_call( [sys.executable, 'setup.py', 'bdist_wheel'], cwd=str(temp_pkg)) dist_dir = temp_pkg.join('dist') assert dist_dir.check(dir=1) wheels = dist_dir.listdir() assert len(wheels) == 1 assert wheels[0].basename.startswith('Test-1.0-py2.py3-') assert wheels[0].ext == '.whl' def test_pythontag_in_setup_cfg(temp_pkg): temp_pkg.join('setup.cfg').write('[bdist_wheel]\npython_tag=py32') subprocess.check_call( [sys.executable, 'setup.py', 'bdist_wheel'], cwd=str(temp_pkg)) dist_dir = temp_pkg.join('dist') assert dist_dir.check(dir=1) wheels = dist_dir.listdir() assert len(wheels) == 1 assert wheels[0].basename.startswith('Test-1.0-py32-') assert wheels[0].ext == '.whl' def test_legacy_wheel_section_in_setup_cfg(temp_pkg): temp_pkg.join('setup.cfg').write('[wheel]\nuniversal=1') subprocess.check_call( [sys.executable, 'setup.py', 'bdist_wheel'], cwd=str(temp_pkg)) dist_dir = temp_pkg.join('dist') assert dist_dir.check(dir=1) wheels = dist_dir.listdir() assert len(wheels) == 1 assert wheels[0].basename.startswith('Test-1.0-py2.py3-') assert wheels[0].ext == '.whl' def test_plat_name_purepy(temp_pkg): subprocess.check_call( [sys.executable, 'setup.py', 'bdist_wheel', '--plat-name=testplat.pure'], cwd=str(temp_pkg)) dist_dir = temp_pkg.join('dist') assert dist_dir.check(dir=1) wheels = dist_dir.listdir() assert len(wheels) == 1 assert wheels[0].basename.endswith('-testplat_pure.whl') assert wheels[0].ext == '.whl' @pytest.mark.parametrize('temp_pkg', [True], indirect=['temp_pkg']) def test_plat_name_ext(temp_pkg): try: subprocess.check_call( [sys.executable, 'setup.py', 'bdist_wheel', '--plat-name=testplat.arch'], cwd=str(temp_pkg)) except subprocess.CalledProcessError: pytest.skip("Cannot compile C Extensions") dist_dir = temp_pkg.join('dist') assert dist_dir.check(dir=1) wheels = dist_dir.listdir() assert len(wheels) == 1 assert wheels[0].basename.endswith('-testplat_arch.whl') assert wheels[0].ext == '.whl' def test_plat_name_purepy_in_setupcfg(temp_pkg): temp_pkg.join('setup.cfg').write('[bdist_wheel]\nplat_name=testplat.pure') subprocess.check_call( [sys.executable, 'setup.py', 'bdist_wheel'], cwd=str(temp_pkg)) dist_dir = temp_pkg.join('dist') assert dist_dir.check(dir=1) wheels = dist_dir.listdir() assert len(wheels) == 1 assert wheels[0].basename.endswith('-testplat_pure.whl') assert wheels[0].ext == '.whl' @pytest.mark.parametrize('temp_pkg', [True], indirect=['temp_pkg']) def test_plat_name_ext_in_setupcfg(temp_pkg): temp_pkg.join('setup.cfg').write('[bdist_wheel]\nplat_name=testplat.arch') try: subprocess.check_call( [sys.executable, 'setup.py', 'bdist_wheel'], cwd=str(temp_pkg)) except subprocess.CalledProcessError: pytest.skip("Cannot compile C Extensions") dist_dir = temp_pkg.join('dist') assert dist_dir.check(dir=1) wheels = dist_dir.listdir() assert len(wheels) == 1 assert wheels[0].basename.endswith('-testplat_arch.whl') assert wheels[0].ext == '.whl' wheel-0.34.2/tests/test_wheelfile.py0000664000175000017500000001473113465636402017350 0ustar alexalex00000000000000# coding: utf-8 from __future__ import unicode_literals import sys from zipfile import ZipFile, ZIP_DEFLATED import pytest from wheel.cli import WheelError from wheel.util import native, as_bytes from wheel.wheelfile import WheelFile @pytest.fixture def wheel_path(tmpdir): return str(tmpdir.join('test-1.0-py2.py3-none-any.whl')) def test_wheelfile_re(tmpdir): # Regression test for #208 path = tmpdir.join('foo-2-py3-none-any.whl') with WheelFile(str(path), 'w') as wf: assert wf.parsed_filename.group('namever') == 'foo-2' @pytest.mark.parametrize('filename', [ 'test.whl', 'test-1.0.whl', 'test-1.0-py2.whl', 'test-1.0-py2-none.whl', 'test-1.0-py2-none-any' ]) def test_bad_wheel_filename(filename): exc = pytest.raises(WheelError, WheelFile, filename) exc.match('^Bad wheel filename {!r}$'.format(filename)) def test_missing_record(wheel_path): with ZipFile(wheel_path, 'w') as zf: zf.writestr(native('hello/héllö.py'), as_bytes('print("Héllö, w0rld!")\n')) exc = pytest.raises(WheelError, WheelFile, wheel_path) exc.match("^Missing test-1.0.dist-info/RECORD file$") def test_unsupported_hash_algorithm(wheel_path): with ZipFile(wheel_path, 'w') as zf: zf.writestr(native('hello/héllö.py'), as_bytes('print("Héllö, w0rld!")\n')) zf.writestr( 'test-1.0.dist-info/RECORD', as_bytes('hello/héllö.py,sha000=bv-QV3RciQC2v3zL8Uvhd_arp40J5A9xmyubN34OVwo,25')) exc = pytest.raises(WheelError, WheelFile, wheel_path) exc.match("^Unsupported hash algorithm: sha000$") @pytest.mark.parametrize('algorithm, digest', [ ('md5', '4J-scNa2qvSgy07rS4at-Q'), ('sha1', 'QjCnGu5Qucb6-vir1a6BVptvOA4') ], ids=['md5', 'sha1']) def test_weak_hash_algorithm(wheel_path, algorithm, digest): hash_string = '{}={}'.format(algorithm, digest) with ZipFile(wheel_path, 'w') as zf: zf.writestr(native('hello/héllö.py'), as_bytes('print("Héllö, w0rld!")\n')) zf.writestr('test-1.0.dist-info/RECORD', as_bytes('hello/héllö.py,{},25'.format(hash_string))) exc = pytest.raises(WheelError, WheelFile, wheel_path) exc.match(r"^Weak hash algorithm \({}\) is not permitted by PEP 427$".format(algorithm)) @pytest.mark.parametrize('algorithm, digest', [ ('sha256', 'bv-QV3RciQC2v3zL8Uvhd_arp40J5A9xmyubN34OVwo'), ('sha384', 'cDXriAy_7i02kBeDkN0m2RIDz85w6pwuHkt2PZ4VmT2PQc1TZs8Ebvf6eKDFcD_S'), ('sha512', 'kdX9CQlwNt4FfOpOKO_X0pn_v1opQuksE40SrWtMyP1NqooWVWpzCE3myZTfpy8g2azZON_' 'iLNpWVxTwuDWqBQ') ], ids=['sha256', 'sha384', 'sha512']) def test_testzip(wheel_path, algorithm, digest): hash_string = '{}={}'.format(algorithm, digest) with ZipFile(wheel_path, 'w') as zf: zf.writestr(native('hello/héllö.py'), as_bytes('print("Héllö, world!")\n')) zf.writestr('test-1.0.dist-info/RECORD', as_bytes('hello/héllö.py,{},25'.format(hash_string))) with WheelFile(wheel_path) as wf: wf.testzip() def test_testzip_missing_hash(wheel_path): with ZipFile(wheel_path, 'w') as zf: zf.writestr(native('hello/héllö.py'), as_bytes('print("Héllö, world!")\n')) zf.writestr('test-1.0.dist-info/RECORD', '') with WheelFile(wheel_path) as wf: exc = pytest.raises(WheelError, wf.testzip) exc.match(native("^No hash found for file 'hello/héllö.py'$")) def test_testzip_bad_hash(wheel_path): with ZipFile(wheel_path, 'w') as zf: zf.writestr(native('hello/héllö.py'), as_bytes('print("Héllö, w0rld!")\n')) zf.writestr( 'test-1.0.dist-info/RECORD', as_bytes('hello/héllö.py,sha256=bv-QV3RciQC2v3zL8Uvhd_arp40J5A9xmyubN34OVwo,25')) with WheelFile(wheel_path) as wf: exc = pytest.raises(WheelError, wf.testzip) exc.match(native("^Hash mismatch for file 'hello/héllö.py'$")) def test_write_str(wheel_path): with WheelFile(wheel_path, 'w') as wf: wf.writestr(native('hello/héllö.py'), as_bytes('print("Héllö, world!")\n')) wf.writestr(native('hello/h,ll,.py'), as_bytes('print("Héllö, world!")\n')) with ZipFile(wheel_path, 'r') as zf: infolist = zf.infolist() assert len(infolist) == 3 assert infolist[0].filename == native('hello/héllö.py') assert infolist[0].file_size == 25 assert infolist[1].filename == native('hello/h,ll,.py') assert infolist[1].file_size == 25 assert infolist[2].filename == 'test-1.0.dist-info/RECORD' record = zf.read('test-1.0.dist-info/RECORD') assert record == as_bytes( 'hello/héllö.py,sha256=bv-QV3RciQC2v3zL8Uvhd_arp40J5A9xmyubN34OVwo,25\n' '"hello/h,ll,.py",sha256=bv-QV3RciQC2v3zL8Uvhd_arp40J5A9xmyubN34OVwo,25\n' 'test-1.0.dist-info/RECORD,,\n') def test_timestamp(tmpdir_factory, wheel_path, monkeypatch): # An environment variable can be used to influence the timestamp on # TarInfo objects inside the zip. See issue #143. build_dir = tmpdir_factory.mktemp('build') for filename in ('one', 'two', 'three'): build_dir.join(filename).write(filename + '\n') # The earliest date representable in TarInfos, 1980-01-01 monkeypatch.setenv(native('SOURCE_DATE_EPOCH'), native('315576060')) with WheelFile(wheel_path, 'w') as wf: wf.write_files(str(build_dir)) with ZipFile(wheel_path, 'r') as zf: for info in zf.infolist(): assert info.date_time[:3] == (1980, 1, 1) assert info.compress_type == ZIP_DEFLATED @pytest.mark.skipif(sys.platform == 'win32', reason='Windows does not support UNIX-like permissions') def test_attributes(tmpdir_factory, wheel_path): # With the change from ZipFile.write() to .writestr(), we need to manually # set member attributes. build_dir = tmpdir_factory.mktemp('build') files = (('foo', 0o644), ('bar', 0o755)) for filename, mode in files: path = build_dir.join(filename) path.write(filename + '\n') path.chmod(mode) with WheelFile(wheel_path, 'w') as wf: wf.write_files(str(build_dir)) with ZipFile(wheel_path, 'r') as zf: for filename, mode in files: info = zf.getinfo(filename) assert info.external_attr == (mode | 0o100000) << 16 assert info.compress_type == ZIP_DEFLATED info = zf.getinfo('test-1.0.dist-info/RECORD') permissions = (info.external_attr >> 16) & 0o777 assert permissions == 0o664 wheel-0.34.2/tests/testdata/0000775000175000017500000000000013614653447015602 5ustar alexalex00000000000000wheel-0.34.2/tests/testdata/abi3extension.dist/0000775000175000017500000000000013614653447021317 5ustar alexalex00000000000000wheel-0.34.2/tests/testdata/abi3extension.dist/extension.c0000664000175000017500000000006613613340346023467 0ustar alexalex00000000000000#define Py_LIMITED_API 0x03020000 #include wheel-0.34.2/tests/testdata/abi3extension.dist/setup.cfg0000664000175000017500000000004213613340346023122 0ustar alexalex00000000000000[bdist_wheel] py_limited_api=cp32 wheel-0.34.2/tests/testdata/abi3extension.dist/setup.py0000664000175000017500000000047113613340346023021 0ustar alexalex00000000000000from setuptools import setup, Extension setup(name='extension.dist', version='0.1', description=u'A testing distribution \N{SNOWMAN}', ext_modules=[ Extension(name='extension', sources=['extension.c'], py_limited_api=True) ], ) wheel-0.34.2/tests/testdata/complex-dist/0000775000175000017500000000000013614653447020212 5ustar alexalex00000000000000wheel-0.34.2/tests/testdata/complex-dist/complexdist/0000775000175000017500000000000013614653447022545 5ustar alexalex00000000000000wheel-0.34.2/tests/testdata/complex-dist/complexdist/__init__.py0000664000175000017500000000002713414074275024647 0ustar alexalex00000000000000def main(): return wheel-0.34.2/tests/testdata/complex-dist/setup.py0000664000175000017500000000132413414074275021716 0ustar alexalex00000000000000from setuptools import setup setup(name='complex-dist', version='0.1', description=u'Another testing distribution \N{SNOWMAN}', long_description=u'Another testing distribution \N{SNOWMAN}', author="Illustrious Author", author_email="illustrious@example.org", url="http://example.org/exemplary", packages=['complexdist'], setup_requires=["wheel", "setuptools"], install_requires=["quux", "splort"], extras_require={'simple': ['simple.dist']}, tests_require=["foo", "bar>=10.0.0"], entry_points={ 'console_scripts': [ 'complex-dist=complexdist:main', 'complex-dist2=complexdist:main', ], }, ) wheel-0.34.2/tests/testdata/extension.dist/0000775000175000017500000000000013614653447020560 5ustar alexalex00000000000000wheel-0.34.2/tests/testdata/extension.dist/extension.c0000664000175000017500000000043713613340346022732 0ustar alexalex00000000000000#include static PyMethodDef methods[] = { { NULL, NULL, 0, NULL } }; static struct PyModuleDef module_def = { PyModuleDef_HEAD_INIT, "extension", "Dummy extension module", -1, methods }; PyMODINIT_FUNC PyInit_extension(void) { return PyModule_Create(&module_def); } wheel-0.34.2/tests/testdata/extension.dist/setup.py0000664000175000017500000000042013613340346022254 0ustar alexalex00000000000000from setuptools import setup, Extension setup(name='extension.dist', version='0.1', description=u'A testing distribution \N{SNOWMAN}', ext_modules=[ Extension(name='extension', sources=['extension.c']) ], ) wheel-0.34.2/tests/testdata/headers.dist/0000775000175000017500000000000013614653447020157 5ustar alexalex00000000000000wheel-0.34.2/tests/testdata/headers.dist/header.h0000664000175000017500000000000013414074275021540 0ustar alexalex00000000000000wheel-0.34.2/tests/testdata/headers.dist/headersdist.py0000664000175000017500000000000013414074275023010 0ustar alexalex00000000000000wheel-0.34.2/tests/testdata/headers.dist/setup.cfg0000664000175000017500000000003213430467231021761 0ustar alexalex00000000000000[bdist_wheel] universal=1 wheel-0.34.2/tests/testdata/headers.dist/setup.py0000664000175000017500000000024313414074275021662 0ustar alexalex00000000000000from setuptools import setup setup(name='headers.dist', version='0.1', description=u'A distribution with headers', headers=['header.h'] ) wheel-0.34.2/tests/testdata/macosx_minimal_system_version/0000775000175000017500000000000013614653447023753 5ustar alexalex00000000000000wheel-0.34.2/tests/testdata/macosx_minimal_system_version/libb.dylib0000664000175000017500000002251013613340346025676 0ustar alexalex00000000000000 h(__TEXT__text__TEXT  __symbol_stub1__TEXT 6 __cstring__TEXT  __stub_helper__TEXT ` __unwind_info__TEXTPhP__eh_frame__TEXT@ `__DATA__mod_init_func__DATA __nl_symbol_ptr__DATA( __la_symbol_ptr__DATA0H0__bss__DATAxH__LINKEDIT  H (libb.dylib&"9[E$|6F1"0  !0!h# P # (liba.dylib 8 /usr/lib/libstdc++.6.dylib 8 }/usr/lib/libSystem.B.dylibUHH}u}u-}u$H=HH=UHUHSHXH}HuHUH}~HHEHEHHEHuH}}HHEHEHEEHE+HuH};HEHE8EHMHEHEH;Es/}u'HuH}HEHE8EHMH}t}uHEHE~2]H}HEHE8!؅EEHX[UHH5H=HH5kTUHH}HuHEHHEHH9s HEHEHEHEHEUHHH}H=!%t%v%x%z%|%~%%%b()L1AS%!h4h"h hhhhkhL$(@@@ $  7  zPRxN ,$7 ,T ,C , , ,g-   F<d 2(!p(Y@__ZSt4coutQq@__ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_@___gxx_personality_v0@dyld_stub_binder@__ZSt3minImERKT_S2_S2_Qq`q0@__Z1avq8@__ZNKSs4sizeEvq@@__ZNKSsixEmqH@__ZNSolsEPFRSoS_EqP@__ZNSt8ios_base4InitC1EvqX@__ZNSt8ios_base4InitD1Evqh@__ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKcqp@___cxa_atexit__Z1bv#St3minImERKT_S2_S2_( E W y   x7 d  $/k @@  __mh_dylib_header__Z41__static_initialization_and_destruction_0ii__GLOBAL__I__Z1bv__ZStL17__verify_groupingPKcmRKSs___tcf_0 stub helpers__ZStL8__ioinit__Z1bv__ZSt3minImERKT_S2_S2___Z1av__ZNKSs4sizeEv__ZNKSsixEm__ZNSolsEPFRSoS_E__ZNSt8ios_base4InitC1Ev__ZNSt8ios_base4InitD1Ev__ZSt4cout__ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6___ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc___cxa_atexit___gxx_personality_v0dyld_stub_binderwheel-0.34.2/tests/testdata/macosx_minimal_system_version/test_lib.c0000664000175000017500000000043513554342444025721 0ustar alexalex00000000000000int num_of_letters(char* text){ int num = 0; char * lett = text; while (lett != 0){ if (*lett >= 'a' && *lett <= 'z'){ num += 1; } else if (*lett >= 'A' && *lett <= 'Z'){ num += 1; } lett += 1; } return num; }wheel-0.34.2/tests/testdata/macosx_minimal_system_version/test_lib_10_10.dylib0000664000175000017500000000136413613340346027377 0ustar alexalex00000000000000 8__text__TEXT__compact_unwind__LD h__eh_frame__TEXT@ h$   PUHH}EH}H}H}mHEaHEzEE.HEAHEZ EEHEHHEE]zRx $(AC _num_of_letterswheel-0.34.2/tests/testdata/macosx_minimal_system_version/test_lib_10_10_10.dylib0000664000175000017500000000136413613340346027677 0ustar alexalex00000000000000 8__text__TEXT__compact_unwind__LD h__eh_frame__TEXT@ h$   PUHH}EH}H}H}mHEaHEzEE.HEAHEZ EEHEHHEE]zRx $(AC _num_of_letterswheel-0.34.2/tests/testdata/macosx_minimal_system_version/test_lib_10_10_386.dylib0000664000175000017500000000123413613340346027773 0ustar alexalex00000000000000| __text__TEXT__compact_unwind__LD,t__eh_frame__TEXT4@ h$  | PU EEMME}fEaEzEE,EAEZ EEEEE ]zR| 8AB _num_of_letterswheel-0.34.2/tests/testdata/macosx_minimal_system_version/test_lib_10_10_fat.dylib0000664000175000017500000002136413613340346030233 0ustar alexalex00000000000000   | __text__TEXT__compact_unwind__LD,t__eh_frame__TEXT4@ h$  | PU EEMME}fEaEzEE,EAEZ EEEEE ]zR| 8AB _num_of_letters 8__text__TEXT__compact_unwind__LD h__eh_frame__TEXT@ h$   PUHH}EH}H}H}mHEaHEzEE.HEAHEZ EEHEHHEE]zRx $(AC _num_of_letterswheel-0.34.2/tests/testdata/macosx_minimal_system_version/test_lib_10_14.dylib0000664000175000017500000000137413613340346027404 0ustar alexalex00000000000000 8__text__TEXT__compact_unwind__LD p__eh_frame__TEXT@ h2   PUHH}EH}H}H}mHEaHEzEE.HEAHEZ EEHEHHEE]zRx $(AC _num_of_letterswheel-0.34.2/tests/testdata/macosx_minimal_system_version/test_lib_10_14_386.dylib0000664000175000017500000000124413613340346030000 0ustar alexalex00000000000000 __text__TEXT__compact_unwind__LD4|__eh_frame__TEXT4H h2   PU EEMME}fEaEzEE,EAEZ EEEEE ]zR| 8AB _num_of_letterswheel-0.34.2/tests/testdata/macosx_minimal_system_version/test_lib_10_14_fat.dylib0000664000175000017500000002137413613340346030240 0ustar alexalex00000000000000    __text__TEXT__compact_unwind__LD4|__eh_frame__TEXT4H h2   PU EEMME}fEaEzEE,EAEZ EEEEE ]zR| 8AB _num_of_letters 8__text__TEXT__compact_unwind__LD p__eh_frame__TEXT@ h2   PUHH}EH}H}H}mHEaHEzEE.HEAHEZ EEHEHHEE]zRx $(AC _num_of_letterswheel-0.34.2/tests/testdata/macosx_minimal_system_version/test_lib_10_6.dylib0000664000175000017500000000136413613340346027324 0ustar alexalex00000000000000 8__text__TEXT__compact_unwind__LD h__eh_frame__TEXT@ h$   PUHH}EH}H}H}mHEaHEzEE.HEAHEZ EEHEHHEE]zRx $(AC _num_of_letterswheel-0.34.2/tests/testdata/macosx_minimal_system_version/test_lib_10_6_386.dylib0000664000175000017500000000123413613340346027720 0ustar alexalex00000000000000| __text__TEXT__compact_unwind__LD,t__eh_frame__TEXT4@ h$  | PU EEMME}fEaEzEE,EAEZ EEEEE ]zR| 8AB _num_of_letterswheel-0.34.2/tests/testdata/macosx_minimal_system_version/test_lib_10_6_fat.dylib0000664000175000017500000002136413613340346030160 0ustar alexalex00000000000000   | __text__TEXT__compact_unwind__LD,t__eh_frame__TEXT4@ h$  | PU EEMME}fEaEzEE,EAEZ EEEEE ]zR| 8AB _num_of_letters 8__text__TEXT__compact_unwind__LD h__eh_frame__TEXT@ h$   PUHH}EH}H}H}mHEaHEzEE.HEAHEZ EEHEHHEE]zRx $(AC _num_of_letterswheel-0.34.2/tests/testdata/macosx_minimal_system_version/test_lib_multiple_fat.dylib0000664000175000017500000002137413613340346031347 0ustar alexalex00000000000000   | __text__TEXT__compact_unwind__LD,t__eh_frame__TEXT4@ h$  | PU EEMME}fEaEzEE,EAEZ EEEEE ]zR| 8AB _num_of_letters 8__text__TEXT__compact_unwind__LD p__eh_frame__TEXT@ h2   PUHH}EH}H}H}mHEaHEzEE.HEAHEZ EEHEHHEE]zRx $(AC _num_of_letterswheel-0.34.2/tests/testdata/simple.dist/0000775000175000017500000000000013614653447020035 5ustar alexalex00000000000000wheel-0.34.2/tests/testdata/simple.dist/setup.py0000664000175000017500000000033613414074275021543 0ustar alexalex00000000000000from setuptools import setup setup(name='simple.dist', version='0.1', description=u'A testing distribution \N{SNOWMAN}', packages=['simpledist'], extras_require={'voting': ['beaglevote']}, ) wheel-0.34.2/tests/testdata/simple.dist/simpledist/0000775000175000017500000000000013614653447022212 5ustar alexalex00000000000000wheel-0.34.2/tests/testdata/simple.dist/simpledist/__init__.py0000664000175000017500000000000013414074275024303 0ustar alexalex00000000000000wheel-0.34.2/tests/testdata/test-1.0-py2.py3-none-any.whl0000664000175000017500000001457113414074275022537 0ustar alexalex00000000000000PK XfLhello/UT xI[xI[ux PKٝM?7(*hello/hello.pyUT NxI[ux KIMSHдR̼ %By~QN&/PK ʰT@hello/__init__.pyUT BOmI[ux PKT@K  hello.pydUT ,BOxI[ux X P\%Yª5!ZC>\$ #,e{a-M}bLNǎFѶijRSu0$ *̔PݔTQ-%$ig=sϹ&@iDH.)+^\f_UZ~c Țh' |H$ʙbGLzc)Ņ·:^|$v ڷĎHUF$ Iil Km[)s5թ5~c7KTY-^: @&ihjʜt%IZhȇ5(>ZhU/Ŀ7]G0}|1{8h?) Z,2Ōy jeZRح,ah9A!yd12>Z_@CQrVpyp˿PB]_S+VQȰI4>dB/kCAAS(j2EÒHbG!$wIM[4rDctZ[rm0`&++Qj=P`*RIVk m[eN=L; ƾ\.f6][D~!ЫJV ԻA yRd 57c񻓙N=I=:w\V׊T-xa-`jZ[ ʃ |vCZDde,)U[ MjqtdIuE׀R@N:=o=8Ao9Wujf֩b_*!#`8 KzP-DŽi!]_خg##"drE8pNˌDyZV+JlLpMLJe.-s긽 !':azi׋n.)]ı&˜3έrvCzeC ׅ-:&֣ L>7I?_P{A(gףN(eªkwABM5w!^R [pѾsT_E& r/ࢴA'd%\jdN"[[zATD&=8%[9$6 IAجO- u+7PIm0&CҲdg.GVg&; 7\#rꥸ qL\Cv_թT ,gEJ>?yC֚-ٯſLfaq2!jq4>q\`>I(A-12&ֺ;i2o=%*"}H8ete>vMyƑ}rrݷzZw.v]/3YB.m_U1&eMBr_Nu!h!pg윶 1Q 2n .ou&<,qKHBeԊqkʟ&jZaQ!Rj+~KJT#bd@QT+ՍMk >KJBS8|pܰd*QBlKm{ER˥&X6OgtwYh e 1{qRx%'I]qꎇBQюHMY=N LA ̐q(ki3yZ"8C'8YNPT p$LsDꞂhDi@.U_<4),qۨ#x` E db=4$fnS^qڀjh@7;܆4Hcj]Q8Me. ^p7 x#fl_4F]*.Č'nC%u-H4b:140F/ΕVE^ς1Td[C12^ Bˢƌz3ntD7UQ^bN5}$Bϩ`\3 pZ?9\7aF2p1X'&=Z[@(p~4_Z#C8eSQӀ+TײJ fA)˹i.iK[&8{HS @p%g0lrqw#1> ŋ7ag"&.M,6E;LAULpmaO҆`N p8BG?8&!S0#xɖ,knT#*sTC*@ h|9ZWҳ7r/P'[{᠏n5jypq\`%؁Y 3$k* T&S9@Oj`&}<z1p|VcptbvV8W쁩$Mp L!RWxH, 3&>Gnok\aEkl|%k-_3FIKGn?$,3JqIS=r;PK XfLtest-1.0.data/UT xI[xI[ux PK XfLtest-1.0.data/scripts/UT xI[xI[ux PK T@)jtest-1.0.data/scripts/hello.shUT BOxI[ux #!/bin/sh python hello.py PK XfLtest-1.0.data/data/UT xI[xI[ux PK ذT@ljtest-1.0.data/data/hello.datUT اBOxI[ux Hello! PK XfLtest-1.0.data/headers/UT xI[xI[ux PK ذT@ljtest-1.0.data/headers/hello.datUT اBOxI[ux Hello! PKy(Ad;5Utest-1.0.dist-info/METADATAUT 6KPxI[ux MN0>\ b]Ѧia=$4d;ܞqAB|o)b7Fb)J$!RbV5Qž@vP$a)F'< B-sz  zJiqMߐ -0]~e%B{/K{/E0׿'!Ǟ8ךΤd"@Jx *S6I+w&idJ$Ƌ0)&}^js2VnS.`圷g#;6gMA=HʲYK.e0gC߉%MfUc PV$(ZIgnTƨaVfmQ$;mzz4a@^[ @%ѾSj>kabH6Z?}ݎWAKn@'f~njqF 6:{ڠ E_j MwI]4ϱ;Z8%я$R3ddOO:脈apq@dwżi3\*<ʢJdٜqJ&@Mxzɇ+gI,xI=!>F|PK XfLAhello/UTxI[ux PKٝM?7(*@hello/hello.pyUTNux PK ʰT@hello/__init__.pyUTBOux PKT@K  hello.pydUT,BOux PK XfLA test-1.0.data/UTxI[ux PK XfLA+test-1.0.data/scripts/UTxI[ux PK T@)j{test-1.0.data/scripts/hello.shUTBOux PK XfLAtest-1.0.data/data/UTxI[ux PK ذT@lj>test-1.0.data/data/hello.datUTاBOux PK XfLAtest-1.0.data/headers/UTxI[ux PK ذT@ljtest-1.0.data/headers/hello.datUTاBOux PKy(Ad;5UMtest-1.0.dist-info/METADATAUT6KPux PKPhLuucstest-1.0.dist-info/WHEELUT7I[ux PK xL] Gtest-1.0.dist-info/RECORDUTI[ux PKowheel-0.34.2/tests/testdata/unicode.dist/0000775000175000017500000000000013614653447020172 5ustar alexalex00000000000000wheel-0.34.2/tests/testdata/unicode.dist/setup.py0000664000175000017500000000027613414074275021703 0ustar alexalex00000000000000# coding: utf-8 from setuptools import setup setup(name='unicode.dist', version='0.1', description=u'A testing distribution \N{SNOWMAN}', packages=['unicodedist'] ) wheel-0.34.2/tests/testdata/unicode.dist/unicodedist/0000775000175000017500000000000013614653447022504 5ustar alexalex00000000000000wheel-0.34.2/tests/testdata/unicode.dist/unicodedist/__init__.py0000664000175000017500000000000013414074275024575 0ustar alexalex00000000000000wheel-0.34.2/tests/testdata/unicode.dist/unicodedist/åäö_日本語.py0000664000175000017500000000000013414074275030564 0ustar alexalex00000000000000wheel-0.34.2/tox.ini0000664000175000017500000000100313613642044014122 0ustar alexalex00000000000000# Tox (http://tox.testrun.org/) is a tool for running tests # in multiple virtualenvs. This configuration file will run the # test suite on all supported python versions. To use it, "pip install tox" # and then run "tox" from this directory. [tox] envlist = py27, py35, py36, py37, py38, pypy, pypy3, flake8 minversion = 3.3.0 skip_missing_interpreters = true [testenv] commands = pytest {posargs} extras = test [testenv:flake8] basepython = python3 deps = flake8 commands = flake8 src tests skip_install = true