CINXE.COM

Package Formats - Python Packaging User Guide

<!doctype html> <html class="no-js" lang="en" data-content_root="../../"> <head><meta charset="utf-8"/> <meta name="viewport" content="width=device-width,initial-scale=1"/> <meta name="color-scheme" content="light dark"><meta name="viewport" content="width=device-width, initial-scale=1" /> <link rel="index" title="Index" href="../../genindex/" /><link rel="search" title="Search" href="../../search/" /><link rel="next" title="src layout vs flat layout" href="../src-layout-vs-flat-layout/" /><link rel="prev" title="Distribution package vs. import package" href="../distribution-package-vs-import-package/" /> <link rel="shortcut icon" href="../../_static/py.png"/><!-- Generated with Sphinx 7.2.6 and Furo 2023.09.10 --> <title>Package Formats - Python Packaging User Guide</title> <link rel="stylesheet" type="text/css" href="../../_static/pygments.css?v=a746c00c" /> <link rel="stylesheet" type="text/css" href="../../_static/styles/furo.css?v=135e06be" /> <link rel="stylesheet" type="text/css" href="../../_static/tabs.css?v=4c969af8" /> <link rel="stylesheet" type="text/css" href="../../_static/copybutton.css?v=76b2166b" /> <link rel="stylesheet" type="text/css" href="../../_static/styles/furo-extensions.css?v=36a5483c" /> <style> body { --color-code-background: #f8f8f8; --color-code-foreground: black; } @media not print { body[data-theme="dark"] { --color-code-background: #202020; --color-code-foreground: #d0d0d0; } @media (prefers-color-scheme: dark) { body:not([data-theme="light"]) { --color-code-background: #202020; --color-code-foreground: #d0d0d0; } } } </style><script async type="text/javascript" src="/_/static/javascript/readthedocs-addons.js"></script><meta name="readthedocs-project-slug" content="python-packaging-user-guide" /><meta name="readthedocs-version-slug" content="latest" /><meta name="readthedocs-resolver-filename" content="/discussions/package-formats/" /><meta name="readthedocs-http-status" content="200" /></head> <body> <script> document.body.dataset.theme = localStorage.getItem("theme") || "auto"; </script> <svg xmlns="http://www.w3.org/2000/svg" style="display: none;"> <symbol id="svg-toc" viewBox="0 0 24 24"> <title>Contents</title> <svg stroke="currentColor" fill="currentColor" stroke-width="0" viewBox="0 0 1024 1024"> <path d="M408 442h480c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8H408c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8zm-8 204c0 4.4 3.6 8 8 8h480c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8H408c-4.4 0-8 3.6-8 8v56zm504-486H120c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8zm0 632H120c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8zM115.4 518.9L271.7 642c5.8 4.6 14.4.5 14.4-6.9V388.9c0-7.4-8.5-11.5-14.4-6.9L115.4 505.1a8.74 8.74 0 0 0 0 13.8z"/> </svg> </symbol> <symbol id="svg-menu" viewBox="0 0 24 24"> <title>Menu</title> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather-menu"> <line x1="3" y1="12" x2="21" y2="12"></line> <line x1="3" y1="6" x2="21" y2="6"></line> <line x1="3" y1="18" x2="21" y2="18"></line> </svg> </symbol> <symbol id="svg-arrow-right" viewBox="0 0 24 24"> <title>Expand</title> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather-chevron-right"> <polyline points="9 18 15 12 9 6"></polyline> </svg> </symbol> <symbol id="svg-sun" viewBox="0 0 24 24"> <title>Light mode</title> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" class="feather-sun"> <circle cx="12" cy="12" r="5"></circle> <line x1="12" y1="1" x2="12" y2="3"></line> <line x1="12" y1="21" x2="12" y2="23"></line> <line x1="4.22" y1="4.22" x2="5.64" y2="5.64"></line> <line x1="18.36" y1="18.36" x2="19.78" y2="19.78"></line> <line x1="1" y1="12" x2="3" y2="12"></line> <line x1="21" y1="12" x2="23" y2="12"></line> <line x1="4.22" y1="19.78" x2="5.64" y2="18.36"></line> <line x1="18.36" y1="5.64" x2="19.78" y2="4.22"></line> </svg> </symbol> <symbol id="svg-moon" viewBox="0 0 24 24"> <title>Dark mode</title> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" class="icon-tabler-moon"> <path stroke="none" d="M0 0h24v24H0z" fill="none" /> <path d="M12 3c.132 0 .263 0 .393 0a7.5 7.5 0 0 0 7.92 12.446a9 9 0 1 1 -8.313 -12.454z" /> </svg> </symbol> <symbol id="svg-sun-half" viewBox="0 0 24 24"> <title>Auto light/dark mode</title> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" class="icon-tabler-shadow"> <path stroke="none" d="M0 0h24v24H0z" fill="none"/> <circle cx="12" cy="12" r="9" /> <path d="M13 12h5" /> <path d="M13 15h4" /> <path d="M13 18h1" /> <path d="M13 9h4" /> <path d="M13 6h1" /> </svg> </symbol> </svg> <input type="checkbox" class="sidebar-toggle" name="__navigation" id="__navigation"> <input type="checkbox" class="sidebar-toggle" name="__toc" id="__toc"> <label class="overlay sidebar-overlay" for="__navigation"> <div class="visually-hidden">Hide navigation sidebar</div> </label> <label class="overlay toc-overlay" for="__toc"> <div class="visually-hidden">Hide table of contents sidebar</div> </label> <div class="page"> <header class="mobile-header"> <div class="header-left"> <label class="nav-overlay-icon" for="__navigation"> <div class="visually-hidden">Toggle site navigation sidebar</div> <i class="icon"><svg><use href="#svg-menu"></use></svg></i> </label> </div> <div class="header-center"> <a href="../../"><div class="brand">Python Packaging User Guide</div></a> </div> <div class="header-right"> <div class="theme-toggle-container theme-toggle-header"> <button class="theme-toggle"> <div class="visually-hidden">Toggle Light / Dark / Auto color theme</div> <svg class="theme-icon-when-auto"><use href="#svg-sun-half"></use></svg> <svg class="theme-icon-when-dark"><use href="#svg-moon"></use></svg> <svg class="theme-icon-when-light"><use href="#svg-sun"></use></svg> </button> </div> <label class="toc-overlay-icon toc-header-icon" for="__toc"> <div class="visually-hidden">Toggle table of contents sidebar</div> <i class="icon"><svg><use href="#svg-toc"></use></svg></i> </label> </div> </header> <aside class="sidebar-drawer"> <div class="sidebar-container"> <div class="sidebar-sticky"><a class="sidebar-brand" href="../../"> <span class="sidebar-brand-text">Python Packaging User Guide</span> </a><form class="sidebar-search-container" method="get" action="../../search/" role="search"> <input class="sidebar-search" placeholder="Search" name="q" aria-label="Search"> <input type="hidden" name="check_keywords" value="yes"> <input type="hidden" name="area" value="default"> </form> <div id="searchbox"></div><div class="sidebar-scroll"><div class="sidebar-tree"> <ul class="current"> <li class="toctree-l1"><a class="reference internal" href="../../overview/">Overview of Python Packaging</a></li> <li class="toctree-l1"><a class="reference internal" href="../../flow/">The Packaging Flow</a></li> <li class="toctree-l1 has-children"><a class="reference internal" href="../../tutorials/">Tutorials</a><input class="toctree-checkbox" id="toctree-checkbox-1" name="toctree-checkbox-1" role="switch" type="checkbox"/><label for="toctree-checkbox-1"><div class="visually-hidden">Toggle navigation of Tutorials</div><i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i></label><ul> <li class="toctree-l2"><a class="reference internal" href="../../tutorials/installing-packages/">Installing Packages</a></li> <li class="toctree-l2"><a class="reference internal" href="../../tutorials/managing-dependencies/">Managing Application Dependencies</a></li> <li class="toctree-l2"><a class="reference internal" href="../../tutorials/packaging-projects/">Packaging Python Projects</a></li> </ul> </li> <li class="toctree-l1 has-children"><a class="reference internal" href="../../guides/">Guides</a><input class="toctree-checkbox" id="toctree-checkbox-2" name="toctree-checkbox-2" role="switch" type="checkbox"/><label for="toctree-checkbox-2"><div class="visually-hidden">Toggle navigation of Guides</div><i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i></label><ul> <li class="toctree-l2 has-children"><a class="reference internal" href="../../guides/section-install/">Installation</a><input class="toctree-checkbox" id="toctree-checkbox-3" name="toctree-checkbox-3" role="switch" type="checkbox"/><label for="toctree-checkbox-3"><div class="visually-hidden">Toggle navigation of Installation</div><i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i></label><ul> <li class="toctree-l3"><a class="reference internal" href="../../guides/installing-using-pip-and-virtual-environments/">Install packages in a virtual environment using pip and venv</a></li> <li class="toctree-l3"><a class="reference internal" href="../../guides/installing-using-virtualenv/">Installing packages using virtualenv</a></li> <li class="toctree-l3"><a class="reference internal" href="../../guides/installing-stand-alone-command-line-tools/">Installing stand alone command line tools</a></li> <li class="toctree-l3"><a class="reference internal" href="../../guides/installing-using-linux-tools/">Installing pip/setuptools/wheel with Linux Package Managers</a></li> <li class="toctree-l3"><a class="reference internal" href="../../guides/installing-scientific-packages/">Installing scientific packages</a></li> </ul> </li> <li class="toctree-l2 has-children"><a class="reference internal" href="../../guides/section-build-and-publish/">Building and Publishing</a><input class="toctree-checkbox" id="toctree-checkbox-4" name="toctree-checkbox-4" role="switch" type="checkbox"/><label for="toctree-checkbox-4"><div class="visually-hidden">Toggle navigation of Building and Publishing</div><i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i></label><ul> <li class="toctree-l3"><a class="reference internal" href="../../guides/writing-pyproject-toml/">Writing your <code class="docutils literal notranslate"><span class="pre">pyproject.toml</span></code></a></li> <li class="toctree-l3"><a class="reference internal" href="../../guides/distributing-packages-using-setuptools/">Packaging and distributing projects</a></li> <li class="toctree-l3"><a class="reference internal" href="../../guides/dropping-older-python-versions/">Dropping support for older Python versions</a></li> <li class="toctree-l3"><a class="reference internal" href="../../guides/packaging-binary-extensions/">Packaging binary extensions</a></li> <li class="toctree-l3"><a class="reference internal" href="../../guides/packaging-namespace-packages/">Packaging namespace packages</a></li> <li class="toctree-l3"><a class="reference internal" href="../../guides/creating-command-line-tools/">Creating and packaging command-line tools</a></li> <li class="toctree-l3"><a class="reference internal" href="../../guides/creating-and-discovering-plugins/">Creating and discovering plugins</a></li> <li class="toctree-l3"><a class="reference internal" href="../../guides/using-testpypi/">Using TestPyPI</a></li> <li class="toctree-l3"><a class="reference internal" href="../../guides/making-a-pypi-friendly-readme/">Making a PyPI-friendly README</a></li> <li class="toctree-l3"><a class="reference internal" href="../../guides/publishing-package-distribution-releases-using-github-actions-ci-cd-workflows/">Publishing package distribution releases using GitHub Actions CI/CD workflows</a></li> <li class="toctree-l3"><a class="reference internal" href="../../guides/modernize-setup-py-project/">How to modernize a <code class="docutils literal notranslate"><span class="pre">setup.py</span></code> based project?</a></li> </ul> </li> <li class="toctree-l2 has-children"><a class="reference internal" href="../../guides/section-hosting/">Hosting</a><input class="toctree-checkbox" id="toctree-checkbox-5" name="toctree-checkbox-5" role="switch" type="checkbox"/><label for="toctree-checkbox-5"><div class="visually-hidden">Toggle navigation of Hosting</div><i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i></label><ul> <li class="toctree-l3"><a class="reference internal" href="../../guides/index-mirrors-and-caches/">Package index mirrors and caches</a></li> <li class="toctree-l3"><a class="reference internal" href="../../guides/hosting-your-own-index/">Hosting your own simple repository</a></li> </ul> </li> <li class="toctree-l2"><a class="reference internal" href="../../guides/tool-recommendations/">Tool recommendations</a></li> <li class="toctree-l2"><a class="reference internal" href="../../guides/analyzing-pypi-package-downloads/">Analyzing PyPI package downloads</a></li> </ul> </li> <li class="toctree-l1 current has-children"><a class="reference internal" href="../">Discussions</a><input checked="" class="toctree-checkbox" id="toctree-checkbox-6" name="toctree-checkbox-6" role="switch" type="checkbox"/><label for="toctree-checkbox-6"><div class="visually-hidden">Toggle navigation of Discussions</div><i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i></label><ul class="current"> <li class="toctree-l2"><a class="reference internal" href="../versioning/">Versioning</a></li> <li class="toctree-l2"><a class="reference internal" href="../deploying-python-applications/">Deploying Python applications</a></li> <li class="toctree-l2"><a class="reference internal" href="../pip-vs-easy-install/">pip vs easy_install</a></li> <li class="toctree-l2"><a class="reference internal" href="../install-requires-vs-requirements/">install_requires vs requirements files</a></li> <li class="toctree-l2"><a class="reference internal" href="../distribution-package-vs-import-package/">Distribution package vs. import package</a></li> <li class="toctree-l2 current current-page"><a class="current reference internal" href="#">Package Formats</a></li> <li class="toctree-l2"><a class="reference internal" href="../src-layout-vs-flat-layout/">src layout vs flat layout</a></li> <li class="toctree-l2"><a class="reference internal" href="../setup-py-deprecated/">Is <code class="docutils literal notranslate"><span class="pre">setup.py</span></code> deprecated?</a></li> <li class="toctree-l2"><a class="reference internal" href="../single-source-version/">Single-sourcing the Project Version</a></li> </ul> </li> <li class="toctree-l1 has-children"><a class="reference internal" href="../../specifications/">PyPA specifications</a><input class="toctree-checkbox" id="toctree-checkbox-7" name="toctree-checkbox-7" role="switch" type="checkbox"/><label for="toctree-checkbox-7"><div class="visually-hidden">Toggle navigation of PyPA specifications</div><i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i></label><ul> <li class="toctree-l2 has-children"><a class="reference internal" href="../../specifications/section-distribution-metadata/">Package Distribution Metadata</a><input class="toctree-checkbox" id="toctree-checkbox-8" name="toctree-checkbox-8" role="switch" type="checkbox"/><label for="toctree-checkbox-8"><div class="visually-hidden">Toggle navigation of Package Distribution Metadata</div><i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i></label><ul> <li class="toctree-l3"><a class="reference internal" href="../../specifications/name-normalization/">Names and normalization</a></li> <li class="toctree-l3"><a class="reference internal" href="../../specifications/core-metadata/">Core metadata specifications</a></li> <li class="toctree-l3"><a class="reference internal" href="../../specifications/version-specifiers/">Version specifiers</a></li> <li class="toctree-l3"><a class="reference internal" href="../../specifications/dependency-specifiers/">Dependency specifiers</a></li> <li class="toctree-l3"><a class="reference internal" href="../../specifications/pyproject-toml/"><code class="docutils literal notranslate"><span class="pre">pyproject.toml</span></code> specification</a></li> <li class="toctree-l3"><a class="reference internal" href="../../specifications/inline-script-metadata/">Inline script metadata</a></li> <li class="toctree-l3"><a class="reference internal" href="../../specifications/platform-compatibility-tags/">Platform compatibility tags</a></li> <li class="toctree-l3"><a class="reference internal" href="../../specifications/well-known-project-urls/">Well-known Project URLs in Metadata</a></li> </ul> </li> <li class="toctree-l2 has-children"><a class="reference internal" href="../../specifications/section-installation-metadata/">Package Installation Metadata</a><input class="toctree-checkbox" id="toctree-checkbox-9" name="toctree-checkbox-9" role="switch" type="checkbox"/><label for="toctree-checkbox-9"><div class="visually-hidden">Toggle navigation of Package Installation Metadata</div><i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i></label><ul> <li class="toctree-l3"><a class="reference internal" href="../../specifications/recording-installed-packages/">Recording installed projects</a></li> <li class="toctree-l3"><a class="reference internal" href="../../specifications/entry-points/">Entry points specification</a></li> <li class="toctree-l3"><a class="reference internal" href="../../specifications/direct-url/">Recording the Direct URL Origin of installed distributions</a></li> <li class="toctree-l3"><a class="reference internal" href="../../specifications/direct-url-data-structure/">Direct URL Data Structure</a></li> <li class="toctree-l3"><a class="reference internal" href="../../specifications/virtual-environments/">Python Virtual Environments</a></li> <li class="toctree-l3"><a class="reference internal" href="../../specifications/externally-managed-environments/">Externally Managed Environments</a></li> </ul> </li> <li class="toctree-l2 has-children"><a class="reference internal" href="../../specifications/section-distribution-formats/">Package Distribution File Formats</a><input class="toctree-checkbox" id="toctree-checkbox-10" name="toctree-checkbox-10" role="switch" type="checkbox"/><label for="toctree-checkbox-10"><div class="visually-hidden">Toggle navigation of Package Distribution File Formats</div><i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i></label><ul> <li class="toctree-l3"><a class="reference internal" href="../../specifications/source-distribution-format/">Source distribution format</a></li> <li class="toctree-l3"><a class="reference internal" href="../../specifications/binary-distribution-format/">Binary distribution format</a></li> </ul> </li> <li class="toctree-l2 has-children"><a class="reference internal" href="../../specifications/section-package-indices/">Package Index Interfaces</a><input class="toctree-checkbox" id="toctree-checkbox-11" name="toctree-checkbox-11" role="switch" type="checkbox"/><label for="toctree-checkbox-11"><div class="visually-hidden">Toggle navigation of Package Index Interfaces</div><i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i></label><ul> <li class="toctree-l3"><a class="reference internal" href="../../specifications/pypirc/">The <code class="file docutils literal notranslate"><span class="pre">.pypirc</span></code> file</a></li> <li class="toctree-l3"><a class="reference internal" href="../../specifications/simple-repository-api/">Simple repository API</a></li> </ul> </li> </ul> </li> <li class="toctree-l1"><a class="reference internal" href="../../key_projects/">Project Summaries</a></li> <li class="toctree-l1"><a class="reference internal" href="../../glossary/">Glossary</a></li> <li class="toctree-l1"><a class="reference internal" href="../../support/">How to Get Support</a></li> <li class="toctree-l1"><a class="reference internal" href="../../contribute/">Contribute to this guide</a></li> <li class="toctree-l1"><a class="reference internal" href="../../news/">News</a></li> </ul> </div> </div> </div> </div> </aside> <div class="main"> <div class="content"> <div class="article-container"> <a href="#" class="back-to-top muted-link"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"> <path d="M13 20h-2V8l-5.5 5.5-1.42-1.42L12 4.16l7.92 7.92-1.42 1.42L13 8v12z"></path> </svg> <span>Back to top</span> </a> <div class="content-icon-container"> <div class="theme-toggle-container theme-toggle-content"> <button class="theme-toggle"> <div class="visually-hidden">Toggle Light / Dark / Auto color theme</div> <svg class="theme-icon-when-auto"><use href="#svg-sun-half"></use></svg> <svg class="theme-icon-when-dark"><use href="#svg-moon"></use></svg> <svg class="theme-icon-when-light"><use href="#svg-sun"></use></svg> </button> </div> <label class="toc-overlay-icon toc-content-icon" for="__toc"> <div class="visually-hidden">Toggle table of contents sidebar</div> <i class="icon"><svg><use href="#svg-toc"></use></svg></i> </label> </div> <article role="main"> <section id="package-formats"> <span id="id1"></span><h1>Package Formats<a class="headerlink" href="#package-formats" title="Link to this heading">#</a></h1> <p>This page discusses the file formats that are used to distribute Python packages and the differences between them.</p> <p>You will find files in two formats on package indices such as <a class="reference external" href="https://pypi.org">PyPI</a>: <strong>source distributions</strong>, or <strong>sdists</strong> for short, and <strong>binary distributions</strong>, commonly called <strong>wheels</strong>. For example, the <a class="reference external" href="https://pypi.org/project/pip/23.3.1/#files">PyPI page for pip 23.3.1</a> lets you download two files, <code class="docutils literal notranslate"><span class="pre">pip-23.3.1.tar.gz</span></code> and <code class="docutils literal notranslate"><span class="pre">pip-23.3.1-py3-none-any.whl</span></code>. The former is an sdist, the latter is a wheel. As explained below, these serve different purposes. When publishing a package on PyPI (or elsewhere), you should always upload both an sdist and one or more wheel.</p> <section id="what-is-a-source-distribution"> <h2>What is a source distribution?<a class="headerlink" href="#what-is-a-source-distribution" title="Link to this heading">#</a></h2> <p>Conceptually, a source distribution is an archive of the source code in raw form. Concretely, an sdist is a <code class="docutils literal notranslate"><span class="pre">.tar.gz</span></code> archive containing the source code plus an additional special file called <code class="docutils literal notranslate"><span class="pre">PKG-INFO</span></code>, which holds the project metadata. The presence of this file helps packaging tools to be more efficient by not needing to compute the metadata themselves. The <code class="docutils literal notranslate"><span class="pre">PKG-INFO</span></code> file follows the format specified in <a class="reference internal" href="../../specifications/core-metadata/#core-metadata"><span class="std std-ref">Core metadata specifications</span></a> and is not intended to be written by hand <a class="footnote-reference brackets" href="#core-metadata-format" id="id2" role="doc-noteref"><span class="fn-bracket">[</span>1<span class="fn-bracket">]</span></a>.</p> <p>You can thus inspect the contents of an sdist by unpacking it using standard tools to work with tar archives, such as <code class="docutils literal notranslate"><span class="pre">tar</span> <span class="pre">-xvf</span></code> on UNIX platforms (like Linux and macOS), or <a class="reference external" href="https://docs.python.org/3/library/tarfile.html#tarfile-commandline" title="(in Python v3.13)"><span class="xref std std-ref">the command line interface of Python’s tarfile module</span></a> on any platform.</p> <p>Sdists serve several purposes in the packaging ecosystem. When <a class="reference internal" href="../../key_projects/#pip"><span class="std std-ref">pip</span></a>, the standard Python package installer, cannot find a wheel to install, it will fall back on downloading a source distribution, compiling a wheel from it, and installing the wheel. Furthermore, sdists are often used as the package source by downstream packagers (such as Linux distributions, Conda, Homebrew and MacPorts on macOS, …), who, for various reasons, may prefer them over, e.g., pulling from a Git repository.</p> <p>A source distribution is recognized by its file name, which has the form <code class="samp docutils literal notranslate"><em><span class="pre">package_name</span></em><span class="pre">-</span><em><span class="pre">version</span></em><span class="pre">.tar.gz</span></code>, e.g., <code class="docutils literal notranslate"><span class="pre">pip-23.3.1.tar.gz</span></code>.</p> <p>If you want technical details on the sdist format, read the <a class="reference internal" href="../../specifications/source-distribution-format/#source-distribution-format"><span class="std std-ref">sdist specification</span></a>.</p> </section> <section id="what-is-a-wheel"> <h2>What is a wheel?<a class="headerlink" href="#what-is-a-wheel" title="Link to this heading">#</a></h2> <p>Conceptually, a wheel contains exactly the files that need to be copied when installing the package.</p> <p>There is a big difference between sdists and wheels for packages with <a class="reference internal" href="../../glossary/#term-Extension-Module"><span class="xref std std-term">extension modules</span></a>, written in compiled languages like C, C++ and Rust, which need to be compiled into platform-dependent machine code. With these packages, wheels do not contain source code (like C source files) but compiled, executable code (like <code class="docutils literal notranslate"><span class="pre">.so</span></code> files on Linux or DLLs on Windows).</p> <p>Furthermore, while there is only one sdist per version of a project, there may be many wheels. Again, this is most relevant in the context of extension modules. The compiled code of an extension module is tied to an operating system and processor architecture, and often also to the version of the Python interpreter (unless the <a class="reference internal" href="../../guides/packaging-binary-extensions/#cpython-stable-abi"><span class="std std-ref">Python stable ABI</span></a> is used).</p> <p>For pure-Python packages, the difference between sdists and wheels is less marked. There is normally one single wheel, for all platforms and Python versions. Python is an interpreted language, which does not need ahead-of-time compilation, so wheels contain <code class="docutils literal notranslate"><span class="pre">.py</span></code> files just like sdists.</p> <p>If you are wondering about <code class="docutils literal notranslate"><span class="pre">.pyc</span></code> bytecode files: they are not included in wheels, since they are cheap to generate, and including them would unnecessarily force a huge number of packages to distribute one wheel per Python version instead of one single wheel. Instead, installers like <a class="reference internal" href="../../key_projects/#pip"><span class="std std-ref">pip</span></a> generate them while installing the package.</p> <p>With that being said, there are still important differences between sdists and wheels, even for pure Python projects. Wheels are meant to contain exactly what is to be installed, and nothing more. In particular, wheels should never include tests and documentation, while sdists commonly do. Also, the wheel format is more complex than sdist. For example, it includes a special file – called <code class="docutils literal notranslate"><span class="pre">RECORD</span></code> – that lists all files in the wheel along with a hash of their content, as a safety check of the download’s integrity.</p> <p>At a glance, you might wonder if wheels are really needed for “plain and basic” pure Python projects. Keep in mind that due to the flexibility of sdists, installers like pip cannot install from sdists directly – they need to first build a wheel, by invoking the <a class="reference internal" href="../../glossary/#term-Build-Backend"><span class="xref std std-term">build backend</span></a> that the sdist specifies (the build backend may do all sorts of transformations while building the wheel, such as compiling C extensions). For this reason, even for a pure Python project, you should always upload <em>both</em> an sdist and a wheel to PyPI or other package indices. This makes installation much faster for your users, since a wheel is directly installable. By only including files that must be installed, wheels also make for smaller downloads.</p> <p>On the technical level, a wheel is a ZIP archive (unlike sdists which are TAR archives). You can inspect its contents by unpacking it as a normal ZIP archive, e.g., using <code class="docutils literal notranslate"><span class="pre">unzip</span></code> on UNIX platforms like Linux and macOS, <code class="docutils literal notranslate"><span class="pre">Expand-Archive</span></code> in Powershell on Windows, or <a class="reference external" href="https://docs.python.org/3/library/zipfile.html#zipfile-commandline" title="(in Python v3.13)"><span class="xref std std-ref">the command line interface of Python’s zipfile module</span></a>. This can be very useful to check that the wheel includes all the files you need it to.</p> <p>Inside a wheel, you will find the package’s files, plus an additional directory called <code class="samp docutils literal notranslate"><em><span class="pre">package_name</span></em><span class="pre">-</span><em><span class="pre">version</span></em><span class="pre">.dist-info</span></code>. This directory contains various files, including a <code class="docutils literal notranslate"><span class="pre">METADATA</span></code> file which is the equivalent of <code class="docutils literal notranslate"><span class="pre">PKG-INFO</span></code> in sdists, as well as <code class="docutils literal notranslate"><span class="pre">RECORD</span></code>. This can be useful to ensure no files are missing from your wheels.</p> <p>The file name of a wheel (ignoring some rarely used features) looks like this: <code class="samp docutils literal notranslate"><em><span class="pre">package_name</span></em><span class="pre">-</span><em><span class="pre">version</span></em><span class="pre">-</span><em><span class="pre">python_tag</span></em><span class="pre">-</span><em><span class="pre">abi_tag</span></em><span class="pre">-</span><em><span class="pre">platform_tag</span></em><span class="pre">.whl</span></code>. This naming convention identifies which platforms and Python versions the wheel is compatible with. For example, the name <code class="docutils literal notranslate"><span class="pre">pip-23.3.1-py3-none-any.whl</span></code> means that:</p> <ul class="simple"> <li><p>(<code class="docutils literal notranslate"><span class="pre">py3</span></code>) This wheel can be installed on any implementation of Python 3, whether CPython, the most widely used Python implementation, or an alternative implementation like <a class="reference external" href="https://pypy.org">PyPy</a>;</p></li> <li><p>(<code class="docutils literal notranslate"><span class="pre">none</span></code>) It does not depend on the Python version;</p></li> <li><p>(<code class="docutils literal notranslate"><span class="pre">any</span></code>) It does not depend on the platform.</p></li> </ul> <p>The pattern <code class="docutils literal notranslate"><span class="pre">py3-none-any</span></code> is common for pure Python projects. Packages with extension modules typically ship multiple wheels with more complex tags.</p> <p>All technical details on the wheel format can be found in the <a class="reference internal" href="../../specifications/binary-distribution-format/#binary-distribution-format"><span class="std std-ref">wheel specification</span></a>.</p> </section> <section id="what-about-eggs"> <span id="wheel-vs-egg"></span><span id="egg-format"></span><h2>What about eggs?<a class="headerlink" href="#what-about-eggs" title="Link to this heading">#</a></h2> <p>“Egg” is an old package format that has been replaced with the wheel format. It should not be used anymore. Since August 2023, PyPI <a class="reference external" href="https://blog.pypi.org/posts/2023-06-26-deprecate-egg-uploads/">rejects egg uploads</a>.</p> <p>Here’s a breakdown of the important differences between wheel and egg.</p> <ul class="simple"> <li><p>The egg format was introduced by <a class="reference internal" href="../../key_projects/#setuptools"><span class="std std-ref">Setuptools</span></a> in 2004, whereas the wheel format was introduced by <span class="target" id="index-0"></span><a class="pep reference external" href="https://peps.python.org/pep-0427/"><strong>PEP 427</strong></a> in 2012.</p></li> <li><p>Wheel has an <a class="reference internal" href="../../specifications/binary-distribution-format/"><span class="doc">official standard specification</span></a>. Egg did not.</p></li> <li><p>Wheel is a <a class="reference internal" href="../../glossary/#term-Distribution-Package"><span class="xref std std-term">distribution</span></a> format, i.e a packaging format. <a class="footnote-reference brackets" href="#wheel-importable" id="id3" role="doc-noteref"><span class="fn-bracket">[</span>2<span class="fn-bracket">]</span></a> Egg was both a distribution format and a runtime installation format (if left zipped), and was designed to be importable.</p></li> <li><p>Wheel archives do not include <code class="docutils literal notranslate"><span class="pre">.pyc</span></code> files. Therefore, when the distribution only contains Python files (i.e. no compiled extensions), and is compatible with Python 2 and 3, it’s possible for a wheel to be “universal”, similar to an <a class="reference internal" href="../../glossary/#term-Source-Distribution-or-sdist"><span class="xref std std-term">sdist</span></a>.</p></li> <li><p>Wheel uses standard <a class="reference internal" href="../../specifications/recording-installed-packages/#recording-installed-packages"><span class="std std-ref">.dist-info directories</span></a>. Egg used <code class="docutils literal notranslate"><span class="pre">.egg-info</span></code>.</p></li> <li><p>Wheel has a <a class="reference internal" href="../../specifications/binary-distribution-format/#wheel-file-name-spec"><span class="std std-ref">richer file naming convention</span></a>. A single wheel archive can indicate its compatibility with a number of Python language versions and implementations, ABIs, and system architectures.</p></li> <li><p>Wheel is versioned. Every wheel file contains the version of the wheel specification and the implementation that packaged it.</p></li> <li><p>Wheel is internally organized by <a class="reference external" href="https://docs.python.org/2/library/sysconfig.html#installation-paths">sysconfig path type</a>, therefore making it easier to convert to other formats.</p></li> </ul> <hr class="docutils" /> <aside class="footnote-list brackets"> <aside class="footnote brackets" id="core-metadata-format" role="doc-footnote"> <span class="label"><span class="fn-bracket">[</span><a role="doc-backlink" href="#id2">1</a><span class="fn-bracket">]</span></span> <p>This format is email-based. Although this would be unlikely to be chosen today, backwards compatibility considerations lead to it being kept as the canonical format. From the user point of view, this is mostly invisible, since the metadata is specified by the user in a way understood by the build backend, typically <code class="docutils literal notranslate"><span class="pre">[project]</span></code> in <code class="docutils literal notranslate"><span class="pre">pyproject.toml</span></code>, and translated by the build backend into <code class="docutils literal notranslate"><span class="pre">PKG-INFO</span></code>.</p> </aside> <aside class="footnote brackets" id="wheel-importable" role="doc-footnote"> <span class="label"><span class="fn-bracket">[</span><a role="doc-backlink" href="#id3">2</a><span class="fn-bracket">]</span></span> <p>Circumstantially, in some cases, wheels can be used as an importable runtime format, although <a class="reference internal" href="../../specifications/binary-distribution-format/#binary-distribution-format-import-wheel"><span class="std std-ref">this is not officially supported at this time</span></a>.</p> </aside> </aside> </section> </section> </article> </div> <footer> <div class="related-pages"> <a class="next-page" href="../src-layout-vs-flat-layout/"> <div class="page-info"> <div class="context"> <span>Next</span> </div> <div class="title">src layout vs flat layout</div> </div> <svg class="furo-related-icon"><use href="#svg-arrow-right"></use></svg> </a> <a class="prev-page" href="../distribution-package-vs-import-package/"> <svg class="furo-related-icon"><use href="#svg-arrow-right"></use></svg> <div class="page-info"> <div class="context"> <span>Previous</span> </div> <div class="title">Distribution package vs. import package</div> </div> </a> </div> <div class="bottom-of-page"> <div class="left-details"> <div class="copyright"> Copyright &#169; 2013–2020, PyPA </div> Made with <a href="https://www.sphinx-doc.org/">Sphinx</a> and <a class="muted-link" href="https://pradyunsg.me">@pradyunsg</a>'s <a href="https://github.com/pradyunsg/furo">Furo</a> <div class="last-updated"> Last updated on Nov 24, 2024</div> </div> <div class="right-details"> </div> </div> </footer> </div> <aside class="toc-drawer"> <div class="toc-sticky toc-scroll"> <div class="toc-title-container"> <span class="toc-title"> On this page </span> </div> <div class="toc-tree-container"> <div class="toc-tree"> <ul> <li><a class="reference internal" href="#">Package Formats</a><ul> <li><a class="reference internal" href="#what-is-a-source-distribution">What is a source distribution?</a></li> <li><a class="reference internal" href="#what-is-a-wheel">What is a wheel?</a></li> <li><a class="reference internal" href="#what-about-eggs">What about eggs?</a></li> </ul> </li> </ul> </div> </div> </div> </aside> </div> </div><script src="../../_static/documentation_options.js?v=187304be"></script> <script src="../../_static/doctools.js?v=888ff710"></script> <script src="../../_static/sphinx_highlight.js?v=dc90522c"></script> <script src="../../_static/scripts/furo.js?v=32e29ea5"></script> <script src="../../_static/tabs.js?v=3ee01567"></script> <script src="../../_static/clipboard.min.js?v=a7894cd8"></script> <script src="../../_static/copybutton.js?v=cb5fb026"></script> <script data-domain="packaging.python.org" defer="defer" src="https://plausible.io/js/script.js"></script> </body> </html>

Pages: 1 2 3 4 5 6 7 8 9 10