summaryrefslogtreecommitdiff
path: root/assets/info/pythonpackagingguide.info
diff options
context:
space:
mode:
authorCraig Jennings <c@cjennings.net>2024-04-07 13:41:34 -0500
committerCraig Jennings <c@cjennings.net>2024-04-07 13:41:34 -0500
commit754bbf7a25a8dda49b5d08ef0d0443bbf5af0e36 (patch)
treef1190704f78f04a2b0b4c977d20fe96a828377f1 /assets/info/pythonpackagingguide.info
new repository
Diffstat (limited to 'assets/info/pythonpackagingguide.info')
-rw-r--r--assets/info/pythonpackagingguide.info15961
1 files changed, 15961 insertions, 0 deletions
diff --git a/assets/info/pythonpackagingguide.info b/assets/info/pythonpackagingguide.info
new file mode 100644
index 00000000..625983df
--- /dev/null
+++ b/assets/info/pythonpackagingguide.info
@@ -0,0 +1,15961 @@
+This is pythonpackagingguide.info, produced by makeinfo version 6.5 from
+pythonpackagingguide.texi.
+
+ Python Packaging User Guide , Dec 04, 2020
+
+ Python Packaging Authority
+
+ Copyright © 2013–2020, PyPA
+
+INFO-DIR-SECTION Miscellaneous
+START-INFO-DIR-ENTRY
+* pythonpackagingguide: (pythonpackagingguide.info). One line description of project.
+END-INFO-DIR-ENTRY
+
+
+ Generated by Sphinx 2.3.1.
+
+
+File: pythonpackagingguide.info, Node: Top, Next: An Overview of Packaging for Python, Up: (dir)
+
+Python Packaging User Guide
+***************************
+
+ Python Packaging User Guide , Dec 04, 2020
+
+ Python Packaging Authority
+
+ Copyright © 2013–2020, PyPA
+
+* Menu:
+
+* An Overview of Packaging for Python::
+* Tutorials::
+* Guides::
+* Discussions::
+* PyPA specifications::
+* Project Summaries::
+* Glossary::
+* How to Get Support::
+* Contribute to this guide::
+* News::
+* Get started::
+* Learn more::
+* Index::
+
+ — The Detailed Node Listing —
+
+An Overview of Packaging for Python
+
+* Thinking about deployment::
+* Packaging Python libraries and tools::
+* Packaging Python applications::
+* What about…::
+* Wrap up::
+
+Packaging Python libraries and tools
+
+* Python modules::
+* Python source distributions::
+* Python binary distributions::
+
+Packaging Python applications
+
+* Depending on a framework::
+* Depending on a pre-installed Python::
+* Depending on a separate software distribution ecosystem::
+* Bringing your own Python executable::
+* Bringing your own userspace::
+* Bringing your own kernel::
+* Bringing your own hardware::
+
+Depending on a framework
+
+* Service platforms::
+* Web browsers and mobile applications::
+
+What about…
+
+* Operating system packages::
+* virtualenv::
+* Security::
+
+Tutorials
+
+* Installing Packages::
+* Managing Application Dependencies::
+* Packaging Python Projects::
+* Creating Documentation::
+
+Installing Packages
+
+* Requirements for Installing Packages::
+* Creating Virtual Environments::
+* Use pip for Installing::
+* Installing from PyPI::
+* Source Distributions vs Wheels::
+* Upgrading packages::
+* Installing to the User Site::
+* Requirements files::
+* Installing from VCS::
+* Installing from other Indexes::
+* Installing from a local src tree::
+* Installing from local archives::
+* Installing from other sources::
+* Installing Prereleases::
+* Installing Setuptools “Extras”::
+
+Requirements for Installing Packages
+
+* Ensure you can run Python from the command line::
+* Ensure you can run pip from the command line::
+* Ensure pip, setuptools, and wheel are up to date: Ensure pip setuptools and wheel are up to date.
+* Optionally, create a virtual environment: Optionally create a virtual environment.
+
+Managing Application Dependencies
+
+* Installing Pipenv::
+* Installing packages for your project::
+* Using installed packages::
+* Next steps::
+* Other Tools for Application Dependency Management::
+
+Packaging Python Projects
+
+* A simple project::
+* Creating the package files::
+* Creating a test folder::
+* Creating setup.py: Creating setup py.
+* Creating README.md: Creating README md.
+* Creating a LICENSE::
+* Generating distribution archives::
+* Uploading the distribution archives::
+* Installing your newly uploaded package::
+* Next steps: Next steps<2>.
+
+Creating Documentation
+
+* Installing Sphinx::
+* Getting Started With Sphinx::
+* Other Sources::
+
+Guides
+
+* Tool recommendations::
+* Installing packages using pip and virtual environments::
+* Installing stand alone command line tools::
+* Installing pip/setuptools/wheel with Linux Package Managers::
+* Installing scientific packages::
+* Multi-version installs::
+* Packaging and distributing projects::
+* Including files in source distributions with MANIFEST.in: Including files in source distributions with MANIFEST in.
+* Single-sourcing the package version::
+* Supporting multiple Python versions::
+* Dropping support for older Python versions::
+* Packaging binary extensions::
+* Supporting Windows using Appveyor::
+* Packaging namespace packages::
+* Creating and discovering plugins::
+* Analyzing PyPI package downloads::
+* Package index mirrors and caches::
+* Hosting your own simple repository::
+* Migrating to PyPI.org: Migrating to PyPI org.
+* Using TestPyPI: Using TestPyPI<2>.
+* Making a PyPI-friendly README::
+* Publishing package distribution releases using GitHub Actions CI/CD workflows::
+
+Tool recommendations
+
+* Application dependency management::
+* Installation tool recommendations::
+* Packaging tool recommendations::
+* Publishing platform migration::
+
+Installing packages using pip and virtual environments
+
+* Installing pip::
+* Installing virtualenv::
+* Creating a virtual environment::
+* Activating a virtual environment::
+* Leaving the virtual environment::
+* Installing packages::
+* Installing specific versions::
+* Installing extras::
+* Installing from source::
+* Installing from version control systems::
+* Installing from local archives: Installing from local archives<2>.
+* Using other package indexes::
+* Upgrading packages: Upgrading packages<2>.
+* Using requirements files::
+* Freezing dependencies::
+
+Installing pip
+
+* Windows::
+* Linux and macOS::
+
+Installing pip/setuptools/wheel with Linux Package Managers
+
+* Fedora::
+* CentOS/RHEL::
+* openSUSE::
+* Debian/Ubuntu::
+* Arch Linux::
+
+Installing scientific packages
+
+* Building from source::
+* Linux distribution packages::
+* Windows installers::
+* macOS installers and package managers::
+* SciPy distributions::
+* Spack::
+* The conda cross-platform package manager::
+
+Packaging and distributing projects
+
+* Requirements for packaging and distributing::
+* Configuring your project::
+* Working in “development mode”::
+* Packaging your project::
+* Uploading your Project to PyPI::
+
+Configuring your project
+
+* Initial files::
+* setup() args: setup args.
+* Choosing a versioning scheme::
+
+Initial files
+
+* setup.py: setup py.
+* setup.cfg: setup cfg.
+* README.rst / README.md: README rst / README md.
+* MANIFEST.in: MANIFEST in.
+* LICENSE.txt: LICENSE txt.
+* <your package>::
+
+setup() args
+
+* name::
+* version::
+* description::
+* url::
+* author::
+* license::
+* classifiers::
+* keywords::
+* project_urls::
+* packages::
+* py_modules::
+* install_requires::
+* python_requires::
+* package_data::
+* data_files::
+* scripts::
+* entry_points::
+
+entry_points
+
+* console_scripts::
+
+Choosing a versioning scheme
+
+* Standards compliance for interoperability::
+* Scheme choices::
+* Pre-release versioning::
+* Local version identifiers::
+
+Scheme choices
+
+* Semantic versioning (preferred): Semantic versioning preferred.
+* Date based versioning::
+* Serial versioning::
+* Hybrid schemes::
+
+Packaging your project
+
+* Source distributions::
+* Wheels::
+
+Wheels
+
+* Universal Wheels::
+* Pure Python Wheels::
+* Platform Wheels::
+
+Uploading your Project to PyPI
+
+* Create an account::
+* Upload your distributions::
+
+Including files in source distributions with MANIFEST.in
+
+* How files are included in an sdist::
+* MANIFEST.in commands: MANIFEST in commands.
+
+Supporting multiple Python versions
+
+* Automated testing and continuous integration::
+* Tools for single-source Python packages::
+* What’s in which Python?::
+
+Dropping support for older Python versions
+
+* Requirements::
+* Defining the Python version required::
+* Dropping a Python release::
+
+Defining the Python version required
+
+* 1. Download the newest version of Setuptools: 1 Download the newest version of Setuptools.
+* 2. Specify the version ranges for supported Python distributions: 2 Specify the version ranges for supported Python distributions.
+* 3. Validating the Metadata before publishing: 3 Validating the Metadata before publishing.
+* 4. Using Twine to publish: 4 Using Twine to publish.
+
+Packaging binary extensions
+
+* An overview of binary extensions::
+* Implementing binary extensions::
+* Building binary extensions::
+* Publishing binary extensions::
+* Additional resources::
+
+An overview of binary extensions
+
+* Use cases::
+* Disadvantages::
+* Alternatives to handcoded accelerator modules::
+* Alternatives to handcoded wrapper modules::
+* Alternatives for low level system access::
+
+Building binary extensions
+
+* Binary extensions for Windows::
+* Binary extensions for Linux::
+* Binary extensions for macOS::
+
+Additional resources
+
+* Cross-platform wheel generation with scikit-build::
+* Introduction to C/C++ extension modules::
+
+Supporting Windows using Appveyor
+
+* Background::
+* Setting up::
+* Adding Appveyor support to your project::
+* Additional notes::
+
+Adding Appveyor support to your project
+
+* appveyor.yml: appveyor yml.
+* Support script::
+* Access to the built wheels::
+
+Additional notes
+
+* Testing with tox::
+* Automatically uploading wheels::
+* External dependencies::
+* Support scripts::
+
+Packaging namespace packages
+
+* Creating a namespace package::
+
+Creating a namespace package
+
+* Native namespace packages::
+* pkgutil-style namespace packages::
+* pkg_resources-style namespace packages::
+
+Creating and discovering plugins
+
+* Using naming convention::
+* Using namespace packages::
+* Using package metadata::
+
+Analyzing PyPI package downloads
+
+* Background: Background<2>.
+* Public dataset::
+* Caveats::
+* Additional tools::
+* References::
+
+Public dataset
+
+* Getting set up::
+* Data schema::
+* Useful queries::
+
+Useful queries
+
+* Counting package downloads::
+* Package downloads over time::
+* Python versions over time::
+
+Additional tools
+
+* google-cloud-bigquery::
+* pypinfo::
+* pandas-gbq::
+
+Package index mirrors and caches
+
+* Caching with pip::
+* Caching with devpi::
+* Complete mirror with bandersnatch::
+
+Hosting your own simple repository
+
+* “Manual” repository::
+
+Migrating to PyPI.org
+
+* Publishing releases::
+* Registering package names & metadata::
+* Using TestPyPI::
+* Registering new user accounts::
+* Browsing packages::
+* Downloading packages::
+* Managing published packages and releases::
+
+Using TestPyPI
+
+* Registering your account::
+* Using TestPyPI with Twine::
+* Using TestPyPI with pip::
+* Setting up TestPyPI in .pypirc: Setting up TestPyPI in pypirc.
+
+Making a PyPI-friendly README
+
+* Creating a README file::
+* Including your README in your package’s metadata::
+* Validating reStructuredText markup::
+
+Publishing package distribution releases using GitHub Actions CI/CD workflows
+
+* Saving credentials on GitHub::
+* Creating a workflow definition::
+* Defining a workflow job environment::
+* Checking out the project and building distributions::
+* Publishing the distribution to PyPI and TestPyPI::
+* That’s all, folks!: That’s all folks!.
+
+Discussions
+
+* Deploying Python applications::
+* pip vs easy_install::
+* install_requires vs requirements files::
+* Wheel vs Egg::
+
+Deploying Python applications
+
+* Overview::
+* OS packaging & installers::
+* Application bundles::
+* Configuration management::
+
+Overview
+
+* Supporting multiple hardware platforms::
+
+OS packaging & installers
+
+* Windows: Windows<2>.
+
+Windows
+
+* Pynsist::
+
+install_requires vs requirements files
+
+* install_requires: install_requires<2>.
+* Requirements files: Requirements files<2>.
+
+PyPA specifications
+
+* Package Distribution Metadata::
+* Package Index Interfaces::
+
+Package Distribution Metadata
+
+* Core metadata specifications::
+* Version specifiers::
+* Dependency specifiers::
+* Declaring build system dependencies::
+* Declaring project metadata::
+* Distribution formats::
+* Platform compatibility tags::
+* Recording installed projects::
+* Entry points specification::
+
+Core metadata specifications
+
+* Metadata-Version::
+* Name::
+* Version::
+* Platform (multiple use): Platform multiple use.
+* Supported-Platform (multiple use): Supported-Platform multiple use.
+* Summary::
+* Description::
+* Description-Content-Type::
+* Keywords::
+* Home-page::
+* Download-URL::
+* Author::
+* Author-email::
+* Maintainer::
+* Maintainer-email::
+* License::
+* Classifier (multiple use): Classifier multiple use.
+* Requires-Dist (multiple use): Requires-Dist multiple use.
+* Requires-Python::
+* Requires-External (multiple use): Requires-External multiple use.
+* Project-URL (multiple-use): Project-URL multiple-use.
+* Provides-Extra (multiple use): Provides-Extra multiple use.
+* Rarely Used Fields::
+
+Rarely Used Fields
+
+* Provides-Dist (multiple use): Provides-Dist multiple use.
+* Obsoletes-Dist (multiple use): Obsoletes-Dist multiple use.
+
+Declaring project metadata
+
+* name: name<2>.
+* version: version<2>.
+* description: description<2>.
+* readme::
+* requires-python::
+* license: license<2>.
+* authors/maintainers::
+* keywords: keywords<2>.
+* classifiers: classifiers<2>.
+* urls::
+* Entry points::
+* dependencies/optional-dependencies::
+* dynamic::
+
+Distribution formats
+
+* Source distribution format::
+* Binary distribution format::
+
+Platform compatibility tags
+
+* Platform tags for Windows::
+* Platform tags for macOS (Mac OS X): Platform tags for macOS Mac OS X.
+* Platform tags for common Linux distributions::
+* Platform tags for other *nix platforms::
+
+Platform tags for common Linux distributions
+
+* Manylinux compatibility support::
+
+Recording installed projects
+
+* History and change workflow::
+* The .dist-info directory: The dist-info directory.
+* The METADATA file::
+* The RECORD file::
+* The INSTALLER file::
+
+Entry points specification
+
+* Data model::
+* File format::
+* Use for scripts::
+
+Package Index Interfaces
+
+* The .pypirc file: The pypirc file.
+* Simple repository API::
+
+The .pypirc file
+
+* Common configurations::
+
+Common configurations
+
+* Using a PyPI token::
+* Using another package index::
+
+Project Summaries
+
+* PyPA Projects::
+* Non-PyPA Projects::
+* Standard Library Projects::
+
+PyPA Projects
+
+* bandersnatch::
+* build::
+* distlib::
+* packaging::
+* pip::
+* Pipenv::
+* Pipfile::
+* Python Packaging User Guide: Python Packaging User Guide<2>.
+* readme_renderer::
+* setuptools::
+* trove-classifiers::
+* twine::
+* virtualenv: virtualenv<2>.
+* Warehouse::
+* wheel::
+
+Non-PyPA Projects
+
+* bento::
+* buildout::
+* conda::
+* devpi::
+* flit::
+* enscons::
+* Hashdist::
+* hatch::
+* pex::
+* pipx::
+* pip-tools::
+* piwheels::
+* poetry::
+* pypiserver::
+* scikit-build::
+* shiv::
+* Spack: Spack<2>.
+* zest.releaser: zest releaser.
+
+Standard Library Projects
+
+* ensurepip::
+* distutils::
+* venv::
+
+Contribute to this guide
+
+* Documentation types::
+* Building the guide locally::
+* Where the guide is deployed::
+* Style guide::
+
+Documentation types
+
+* Tutorials: Tutorials<2>.
+* Guides: Guides<2>.
+* Discussions: Discussions<2>.
+* Specifications::
+
+Style guide
+
+* Purpose::
+* Scope::
+* Audience::
+* Voice and tone::
+* Conventions and mechanics::
+
+News
+
+* September 2019::
+* August 2019::
+* July 2019::
+* June 2019::
+* May 2019::
+* April 2019::
+* March 2019::
+* February 2019::
+* January 2019::
+* December 2018::
+* November 2018::
+* October 2018::
+* September 2018::
+* August 2018::
+* July 2018::
+* June 2018::
+* May 2018::
+* April 2018::
+* March 2018::
+* February 2018::
+* January 2018::
+* December 2017::
+* November 2017::
+* October 2017::
+* September 2017::
+* August 2017::
+* July 2017::
+* June 2017::
+* May 2017::
+* April 2017::
+* March 2017::
+* February 2017::
+
+
+
+File: pythonpackagingguide.info, Node: An Overview of Packaging for Python, Next: Tutorials, Prev: Top, Up: Top
+
+1 An Overview of Packaging for Python
+*************************************
+
+As a general-purpose programming language, Python is designed to be used
+in many ways. You can build web sites or industrial robots or a game
+for your friends to play, and much more, all using the same core
+technology.
+
+Python’s flexibility is why the first step in every Python project must
+be to think about the project’s audience and the corresponding
+environment where the project will run. It might seem strange to think
+about packaging before writing code, but this process does wonders for
+avoiding future headaches.
+
+This overview provides a general-purpose decision tree for reasoning
+about Python’s plethora of packaging options. Read on to choose the
+best technology for your next project.
+
+* Menu:
+
+* Thinking about deployment::
+* Packaging Python libraries and tools::
+* Packaging Python applications::
+* What about…::
+* Wrap up::
+
+
+File: pythonpackagingguide.info, Node: Thinking about deployment, Next: Packaging Python libraries and tools, Up: An Overview of Packaging for Python
+
+1.1 Thinking about deployment
+=============================
+
+Packages exist to be installed (or `deployed'), so before you package
+anything, you’ll want to have some answers to the deployment questions
+below:
+
+ * Who are your software’s users? Will your software be installed by
+ other developers doing software development, operations people in a
+ datacenter, or a less software-savvy group?
+
+ * Is your software intended to run on servers, desktops, mobile
+ clients (phones, tablets, etc.), or embedded in dedicated devices?
+
+ * Is your software installed individually, or in large deployment
+ batches?
+
+Packaging is all about target environment and deployment experience.
+There are many answers to the questions above and each combination of
+circumstances has its own solutions. With this information, the
+following overview will guide you to the packaging technologies best
+suited to your project.
+
+
+File: pythonpackagingguide.info, Node: Packaging Python libraries and tools, Next: Packaging Python applications, Prev: Thinking about deployment, Up: An Overview of Packaging for Python
+
+1.2 Packaging Python libraries and tools
+========================================
+
+You may have heard about PyPI, ‘setup.py’, and ‘wheel’ files. These are
+just a few of the tools Python’s ecosystem provides for distributing
+Python code to developers, which you can read about in *note Packaging
+and distributing projects: 6.
+
+The following approaches to packaging are meant for libraries and tools
+used by technical audience in a development setting. If you’re looking
+for ways to package Python for a non-technical audience and/or a
+production setting, skip ahead to *note Packaging Python applications:
+7.
+
+* Menu:
+
+* Python modules::
+* Python source distributions::
+* Python binary distributions::
+
+
+File: pythonpackagingguide.info, Node: Python modules, Next: Python source distributions, Up: Packaging Python libraries and tools
+
+1.2.1 Python modules
+--------------------
+
+A Python file, provided it only relies on the standard library, can be
+redistributed and reused. You will also need to ensure it’s written for
+the right version of Python, and only relies on the standard library.
+
+This is great for sharing simple scripts and snippets between people who
+both have compatible Python versions (such as via email, StackOverflow,
+or GitHub gists). There are even some entire Python libraries that
+offer this as an option, such as bottle.py(1) and boltons(2).
+
+However, this pattern won’t scale for projects that consist of multiple
+files, need additional libraries, or need a specific version of Python,
+hence the options below.
+
+ ---------- Footnotes ----------
+
+ (1) https://bottlepy.org/docs/dev/
+
+ (2)
+http://boltons.readthedocs.io/en/latest/architecture.html#architecture
+
+
+File: pythonpackagingguide.info, Node: Python source distributions, Next: Python binary distributions, Prev: Python modules, Up: Packaging Python libraries and tools
+
+1.2.2 Python source distributions
+---------------------------------
+
+If your code consists of multiple Python files, it’s usually organized
+into a directory structure. Any directory containing Python files can
+comprise an *note Import Package: a.
+
+Because packages consist of multiple files, they are harder to
+distribute. Most protocols support transferring only one file at a time
+(when was the last time you clicked a link and it downloaded multiple
+files?). It’s easier to get incomplete transfers, and harder to
+guarantee code integrity at the destination.
+
+So long as your code contains nothing but pure Python code, and you know
+your deployment environment supports your version of Python, then you
+can use Python’s native packaging tools to create a `source' *note
+Distribution Package: b, or `sdist' for short.
+
+Python’s `sdists' are compressed archives (‘.tar.gz’ files) containing
+one or more packages or modules. If your code is pure-Python, and you
+only depend on other Python packages, you can go here to learn more(1).
+
+If you rely on any non-Python code, or non-Python packages (such as
+libxml2(2) in the case of lxml(3), or BLAS libraries in the case of
+numpy(4)), you will need to use the format detailed in the next section,
+which also has many advantages for pure-Python libraries.
+
+ Note: Python and PyPI support multiple distributions providing
+ different implementations of the same package. For instance the
+ unmaintained-but-seminal PIL distribution(5) provides the PIL
+ package, and so does Pillow(6), an actively-maintained fork of PIL!
+
+ This Python packaging superpower makes it possible for Pillow to be
+ a drop-in replacement for PIL, just by changing your project’s
+ ‘install_requires’ or ‘requirements.txt’.
+
+ ---------- Footnotes ----------
+
+ (1) https://docs.python.org/3/distutils/sourcedist.html
+
+ (2) https://en.wikipedia.org/wiki/Libxml2
+
+ (3) https://pypi.org/project/lxml/
+
+ (4) https://pypi.org/project/numpy
+
+ (5) https://pypi.org/project/PIL/
+
+ (6) https://pypi.org/project/Pillow/
+
+
+File: pythonpackagingguide.info, Node: Python binary distributions, Prev: Python source distributions, Up: Packaging Python libraries and tools
+
+1.2.3 Python binary distributions
+---------------------------------
+
+So much of Python’s practical power comes from its ability to integrate
+with the software ecosystem, in particular libraries written in C, C++,
+Fortran, Rust, and other languages.
+
+Not all developers have the right tools or experiences to build these
+components written in these compiled languages, so Python created the
+*note Wheel: d, a package format designed to ship libraries with
+compiled artifacts. In fact, Python’s package installer, ‘pip’, always
+prefers wheels because installation is always faster, so even
+pure-Python packages work better with wheels.
+
+Binary distributions are best when they come with source distributions
+to match. Even if you don’t upload wheels of your code for every
+operating system, by uploading the sdist, you’re enabling users of other
+platforms to still build it for themselves. Default to publishing both
+sdist and wheel archives together, `unless' you’re creating artifacts
+for a very specific use case where you know the recipient only needs one
+or the other.
+
+Python and PyPI make it easy to upload both wheels and sdists together.
+Just follow the *note Packaging Python Projects: e. tutorial.
+
+[A summary of Python's packaging capabilities for tools and libraries.]
+Figure: Python’s recommended built-in library and tool packaging
+technologies. Excerpted from The Packaging Gradient (2017)(1).
+
+ ---------- Footnotes ----------
+
+ (1) https://www.youtube.com/watch?v=iLVNWfPWAC8
+
+
+File: pythonpackagingguide.info, Node: Packaging Python applications, Next: What about…, Prev: Packaging Python libraries and tools, Up: An Overview of Packaging for Python
+
+1.3 Packaging Python applications
+=================================
+
+So far we’ve only discussed Python’s native distribution tools. Based
+on our introduction, you would be correct to infer these built-in
+approaches only target environments which have Python, and an audience
+who knows how to install Python packages.
+
+With the variety of operating systems, configurations, and people out
+there, this assumption is only safe when targeting a developer audience.
+
+Python’s native packaging is mostly built for distributing reusable
+code, called libraries, between developers. You can piggyback `tools',
+or basic applications for developers, on top of Python’s library
+packaging, using technologies like setuptools entry_points(1).
+
+Libraries are building blocks, not complete applications. For
+distributing applications, there’s a whole new world of technologies out
+there.
+
+The next few sections organize these application packaging options
+according to their dependencies on the target environment, so you can
+choose the right one for your project.
+
+* Menu:
+
+* Depending on a framework::
+* Depending on a pre-installed Python::
+* Depending on a separate software distribution ecosystem::
+* Bringing your own Python executable::
+* Bringing your own userspace::
+* Bringing your own kernel::
+* Bringing your own hardware::
+
+ ---------- Footnotes ----------
+
+ (1)
+https://setuptools.readthedocs.io/en/latest/userguide/entry_point.html
+
+
+File: pythonpackagingguide.info, Node: Depending on a framework, Next: Depending on a pre-installed Python, Up: Packaging Python applications
+
+1.3.1 Depending on a framework
+------------------------------
+
+Some types of Python applications, like web site backends and other
+network services, are common enough that they have frameworks to enable
+their development and packaging. Other types of applications, like
+dynamic web frontends and mobile clients, are complex enough to target
+that a framework becomes more than a convenience.
+
+In all these cases, it makes sense to work backwards, from the
+framework’s packaging and deployment story. Some frameworks include a
+deployment system which wraps the technologies outlined in the rest of
+the guide. In these cases, you’ll want to defer to your framework’s
+packaging guide for the easiest and most reliable production experience.
+
+If you ever wonder how these platforms and frameworks work under the
+hood, you can always read the sections beyond.
+
+* Menu:
+
+* Service platforms::
+* Web browsers and mobile applications::
+
+
+File: pythonpackagingguide.info, Node: Service platforms, Next: Web browsers and mobile applications, Up: Depending on a framework
+
+1.3.1.1 Service platforms
+.........................
+
+If you’re developing for a “Platform-as-a-Service” or “PaaS” like Heroku
+or Google App Engine, you are going to want to follow their respective
+packaging guides.
+
+ * Heroku(1)
+
+ * Google App Engine(2)
+
+ * PythonAnywhere(3)
+
+ * OpenShift(4)
+
+ * “Serverless” frameworks like Zappa(5)
+
+In all these setups, the platform takes care of packaging and
+deployment, as long as you follow their patterns. Most software does
+not fit one of these templates, hence the existence of all the other
+options below.
+
+If you’re developing software that will be deployed to machines you own,
+users’ personal computers, or any other arrangement, read on.
+
+ ---------- Footnotes ----------
+
+ (1) https://devcenter.heroku.com/articles/getting-started-with-python
+
+ (2) https://cloud.google.com/appengine/docs/python/
+
+ (3) https://www.pythonanywhere.com/
+
+ (4) https://blog.openshift.com/getting-started-python/
+
+ (5) https://www.zappa.io/
+
+
+File: pythonpackagingguide.info, Node: Web browsers and mobile applications, Prev: Service platforms, Up: Depending on a framework
+
+1.3.1.2 Web browsers and mobile applications
+............................................
+
+Python’s steady advances are leading it into new spaces. These days you
+can write a mobile app or web application frontend in Python. While the
+language may be familiar, the packaging and deployment practices are
+brand new.
+
+If you’re planning on releasing to these new frontiers, you’ll want to
+check out the following frameworks, and refer to their packaging guides:
+
+ * Kivy(1)
+
+ * Beeware(2)
+
+ * Brython(3)
+
+ * Flexx(4)
+
+If you are `not' interested in using a framework or platform, or just
+wonder about some of the technologies and techniques utilized by the
+frameworks above, continue reading below.
+
+ ---------- Footnotes ----------
+
+ (1) https://kivy.org/#home
+
+ (2) https://pybee.org/
+
+ (3) https://brython.info/
+
+ (4) http://flexx.readthedocs.io/en/latest/
+
+
+File: pythonpackagingguide.info, Node: Depending on a pre-installed Python, Next: Depending on a separate software distribution ecosystem, Prev: Depending on a framework, Up: Packaging Python applications
+
+1.3.2 Depending on a pre-installed Python
+-----------------------------------------
+
+Pick an arbitrary computer, and depending on the context, there’s a very
+good chance Python is already installed. Included by default in most
+Linux and Mac operating systems for many years now, you can reasonably
+depend on Python preexisting in your data centers or on the personal
+machines of developers and data scientists.
+
+Technologies which support this model:
+
+ * PEX(1) (Python EXecutable)
+
+ * zipapp(2) (does not help manage dependencies, requires Python 3.5+)
+
+ * shiv(3) (requires Python 3)
+
+ Note: Of all the approaches here, depending on a pre-installed
+ Python relies the most on the target environment. Of course, this
+ also makes for the smallest package, as small as single-digit
+ megabytes, or even kilobytes.
+
+ In general, decreasing the dependency on the target system
+ increases the size of our package, so the solutions here are
+ roughly arranged by increasing size of output.
+
+ ---------- Footnotes ----------
+
+ (1) https://github.com/pantsbuild/pex#pex
+
+ (2) https://docs.python.org/3/library/zipapp.html
+
+ (3) https://github.com/linkedin/shiv#shiv
+
+
+File: pythonpackagingguide.info, Node: Depending on a separate software distribution ecosystem, Next: Bringing your own Python executable, Prev: Depending on a pre-installed Python, Up: Packaging Python applications
+
+1.3.3 Depending on a separate software distribution ecosystem
+-------------------------------------------------------------
+
+For a long time many operating systems, including Mac and Windows,
+lacked built-in package management. Only recently did these OSes gain
+so-called “app stores”, but even those focus on consumer applications
+and offer little for developers.
+
+Developers long sought remedies, and in this struggle, emerged with
+their own package management solutions, such as Homebrew(1). The most
+relevant alternative for Python developers is a package ecosystem called
+Anaconda(2). Anaconda is built around Python and is increasingly common
+in academic, analytical, and other data-oriented environments, even
+making its way into server-oriented environments(3).
+
+Instructions on building and publishing for the Anaconda ecosystem:
+
+ * Building libraries and applications with conda(4)
+
+ * Transitioning a native Python package to Anaconda(5)
+
+A similar model involves installing an alternative Python distribution,
+but does not support arbitrary operating system-level packages:
+
+ * Enthought Canopy(6)
+
+ * ActiveState ActivePython(7)
+
+ * WinPython(8)
+
+ ---------- Footnotes ----------
+
+ (1) https://brew.sh/
+
+ (2) https://en.wikipedia.org/wiki/Anaconda_(Python_distribution)
+
+ (3)
+https://www.paypal-engineering.com/2016/09/07/python-packaging-at-paypal/
+
+ (4) https://conda.io/docs/user-guide/tutorials/index.html
+
+ (5)
+https://conda.io/docs/user-guide/tutorials/build-pkgs-skeleton.html
+
+ (6) https://www.enthought.com/product/canopy/
+
+ (7) https://www.activestate.com/activepython
+
+ (8) http://winpython.github.io/
+
+
+File: pythonpackagingguide.info, Node: Bringing your own Python executable, Next: Bringing your own userspace, Prev: Depending on a separate software distribution ecosystem, Up: Packaging Python applications
+
+1.3.4 Bringing your own Python executable
+-----------------------------------------
+
+Computing as we know it is defined by the ability to execute programs.
+Every operating system natively supports one or more formats of program
+they can natively execute.
+
+There are many techniques and technologies which turn your Python
+program into one of these formats, most of which involve embedding the
+Python interpreter and any other dependencies into a single executable
+file.
+
+This approach, called `freezing', offers wide compatibility and seamless
+user experience, though often requires multiple technologies, and a good
+amount of effort.
+
+A selection of Python freezers:
+
+ * pyInstaller(1) - Cross-platform
+
+ * cx_Freeze(2) - Cross-platform
+
+ * constructor(3) - For command-line installers
+
+ * py2exe(4) - Windows only
+
+ * py2app(5) - Mac only
+
+ * bbFreeze(6) - Windows, Linux, Python 2 only
+
+ * osnap(7) - Windows and Mac
+
+ * pynsist(8) - Windows only
+
+Most of the above imply single-user deployments. For multi-component
+server applications, see Chef Omnibus(9).
+
+ ---------- Footnotes ----------
+
+ (1) http://www.pyinstaller.org/
+
+ (2) https://marcelotduarte.github.io/cx_Freeze/
+
+ (3) https://github.com/conda/constructor
+
+ (4) http://www.py2exe.org/
+
+ (5) https://py2app.readthedocs.io/en/latest/
+
+ (6) https://pypi.org/project/bbfreeze
+
+ (7) https://github.com/jamesabel/osnap
+
+ (8) https://pypi.org/project/pynsist/
+
+ (9) https://github.com/chef/omnibus#-omnibus
+
+
+File: pythonpackagingguide.info, Node: Bringing your own userspace, Next: Bringing your own kernel, Prev: Bringing your own Python executable, Up: Packaging Python applications
+
+1.3.5 Bringing your own userspace
+---------------------------------
+
+An increasing number of operating systems – including Linux, Mac OS, and
+Windows – can be set up to run applications packaged as lightweight
+images, using a relatively modern arrangement often referred to as
+operating-system-level virtualization(1), or `containerization'.
+
+These techniques are mostly Python agnostic, because they package whole
+OS filesystems, not just Python or Python packages.
+
+Adoption is most extensive among Linux servers, where the technology
+originated and where the technologies below work best:
+
+ * AppImage(2)
+
+ * Docker(3)
+
+ * Flatpak(4)
+
+ * Snapcraft(5)
+
+ ---------- Footnotes ----------
+
+ (1)
+https://en.wikipedia.org/wiki/Operating-system-level_virtualization
+
+ (2) https://appimage.org/
+
+ (3) https://www.fullstackpython.com/docker.html
+
+ (4) https://flatpak.org/
+
+ (5) https://snapcraft.io/
+
+
+File: pythonpackagingguide.info, Node: Bringing your own kernel, Next: Bringing your own hardware, Prev: Bringing your own userspace, Up: Packaging Python applications
+
+1.3.6 Bringing your own kernel
+------------------------------
+
+Most operating systems support some form of classical virtualization,
+running applications packaged as images containing a full operating
+system of their own. Running these virtual machines, or VMs, is a
+mature approach, widespread in data center environments.
+
+These techniques are mostly reserved for larger scale deployments in
+data centers, though certain complex applications can benefit from this
+packaging. Technologies are Python agnostic, and include:
+
+ * Vagrant(1)
+
+ * VHD(2), AMI(3), and other formats(4)
+
+ * OpenStack(5) - A cloud management system in Python, with extensive
+ VM support
+
+ ---------- Footnotes ----------
+
+ (1) https://www.vagrantup.com/
+
+ (2) https://en.wikipedia.org/wiki/VHD_(file_format)
+
+ (3) https://en.wikipedia.org/wiki/Amazon_Machine_Image
+
+ (4) https://docs.openstack.org/image-guide/image-formats.html
+
+ (5) https://www.redhat.com/en/topics/openstack
+
+
+File: pythonpackagingguide.info, Node: Bringing your own hardware, Prev: Bringing your own kernel, Up: Packaging Python applications
+
+1.3.7 Bringing your own hardware
+--------------------------------
+
+The most all-encompassing way to ship your software would be to ship it
+already-installed on some hardware. This way, your software’s user
+would require only electricity.
+
+Whereas the virtual machines described above are primarily reserved for
+the tech-savvy, you can find hardware appliances being used by everyone
+from the most advanced data centers to the youngest children.
+
+Embed your code on an Adafruit(1), MicroPython(2), or more-powerful
+hardware running Python, then ship it to the datacenter or your users’
+homes. They plug and play, and you can call it a day.
+
+[A summary of technologies used to package Python applications.]
+Figure: The simplified gamut of technologies used to package Python
+applications.
+
+ ---------- Footnotes ----------
+
+ (1) https://github.com/adafruit/circuitpython#adafruit-circuitpython
+
+ (2) https://micropython.org/
+
+
+File: pythonpackagingguide.info, Node: What about…, Next: Wrap up, Prev: Packaging Python applications, Up: An Overview of Packaging for Python
+
+1.4 What about…
+===============
+
+The sections above can only summarize so much, and you might be
+wondering about some of the more conspicuous gaps.
+
+* Menu:
+
+* Operating system packages::
+* virtualenv::
+* Security::
+
+
+File: pythonpackagingguide.info, Node: Operating system packages, Next: virtualenv, Up: What about…
+
+1.4.1 Operating system packages
+-------------------------------
+
+As mentioned in *note Depending on a separate software distribution
+ecosystem: 14. above, some operating systems have package managers of
+their own. If you’re very sure of the operating system you’re
+targeting, you can depend directly on a format like deb(1) (for Debian,
+Ubuntu, etc.) or RPM(2) (for Red Hat, Fedora, etc.), and use that
+built-in package manager to take care of installation, and even
+deployment. You can even use FPM(3) to generate both deb and RPMs from
+the same source.
+
+In most deployment pipelines, the OS package manager is just one piece
+of the puzzle.
+
+ ---------- Footnotes ----------
+
+ (1) https://en.wikipedia.org/wiki/Deb_(file_format)
+
+ (2) https://en.wikipedia.org/wiki/RPM_Package_Manager
+
+ (3) https://fpm.readthedocs.io/en/latest/source/virtualenv.html
+
+
+File: pythonpackagingguide.info, Node: virtualenv, Next: Security, Prev: Operating system packages, Up: What about…
+
+1.4.2 virtualenv
+----------------
+
+Virtualenvs(1) have been an indispensible tool for multiple generations
+of Python developer, but are slowly fading from view, as they are being
+wrapped by higher-level tools. With packaging in particular,
+virtualenvs are used as a primitive in the dh-virtualenv tool(2) and
+osnap(3), both of which wrap virtualenvs in a self-contained way.
+
+For production deployments, do not rely on running ‘pip install’ from
+the Internet into a virtualenv, as one might do in a development
+environment. The overview above is full of much better solutions.
+
+ ---------- Footnotes ----------
+
+ (1) http://python-guide.readthedocs.io/en/latest/dev/virtualenvs/
+
+ (2) http://dh-virtualenv.readthedocs.io/en/1.0/tutorial.html
+
+ (3) https://github.com/jamesabel/osnap
+
+
+File: pythonpackagingguide.info, Node: Security, Prev: virtualenv, Up: What about…
+
+1.4.3 Security
+--------------
+
+The further down the gradient you come, the harder it gets to update
+components of your package. Everything is more tightly bound together.
+
+For example, if a kernel security issue emerges, and you’re deploying
+containers, the host system’s kernel can be updated without requiring a
+new build on behalf of the application. If you deploy VM images, you’ll
+need a new build. Whether or not this dynamic makes one option more
+secure is still a bit of an old debate, going back to the
+still-unsettled matter of static versus dynamic linking(1).
+
+ ---------- Footnotes ----------
+
+ (1)
+https://www.google.com/search?channel=fs&q=static+vs+dynamic+linking
+
+
+File: pythonpackagingguide.info, Node: Wrap up, Prev: What about…, Up: An Overview of Packaging for Python
+
+1.5 Wrap up
+===========
+
+Packaging in Python has a bit of a reputation for being a bumpy ride.
+This impression is mostly a byproduct of Python’s versatility. Once you
+understand the natural boundaries between each packaging solution, you
+begin to realize that the varied landscape is a small price Python
+programmers pay for using one of the most balanced, flexible language
+available.
+
+
+File: pythonpackagingguide.info, Node: Tutorials, Next: Guides, Prev: An Overview of Packaging for Python, Up: Top
+
+2 Tutorials
+***********
+
+`Tutorials' are opinionated step-by-step guides to help you get familiar
+with packaging concepts. For more detailed information on specific
+packaging topics, see *note Guides: 22.
+
+* Menu:
+
+* Installing Packages::
+* Managing Application Dependencies::
+* Packaging Python Projects::
+* Creating Documentation::
+
+
+File: pythonpackagingguide.info, Node: Installing Packages, Next: Managing Application Dependencies, Up: Tutorials
+
+2.1 Installing Packages
+=======================
+
+This section covers the basics of how to install Python *note packages:
+b.
+
+It’s important to note that the term “package” in this context is being
+used as a synonym for a *note distribution: b. (i.e. a bundle of
+software to be installed), not to refer to the kind of *note package: a.
+that you import in your Python source code (i.e. a container of
+modules). It is common in the Python community to refer to a *note
+distribution: b. using the term “package”. Using the term
+“distribution” is often not preferred, because it can easily be confused
+with a Linux distribution, or another larger software distribution like
+Python itself.
+
+* Menu:
+
+* Requirements for Installing Packages::
+* Creating Virtual Environments::
+* Use pip for Installing::
+* Installing from PyPI::
+* Source Distributions vs Wheels::
+* Upgrading packages::
+* Installing to the User Site::
+* Requirements files::
+* Installing from VCS::
+* Installing from other Indexes::
+* Installing from a local src tree::
+* Installing from local archives::
+* Installing from other sources::
+* Installing Prereleases::
+* Installing Setuptools “Extras”::
+
+
+File: pythonpackagingguide.info, Node: Requirements for Installing Packages, Next: Creating Virtual Environments, Up: Installing Packages
+
+2.1.1 Requirements for Installing Packages
+------------------------------------------
+
+This section describes the steps to follow before installing other
+Python packages.
+
+* Menu:
+
+* Ensure you can run Python from the command line::
+* Ensure you can run pip from the command line::
+* Ensure pip, setuptools, and wheel are up to date: Ensure pip setuptools and wheel are up to date.
+* Optionally, create a virtual environment: Optionally create a virtual environment.
+
+
+File: pythonpackagingguide.info, Node: Ensure you can run Python from the command line, Next: Ensure you can run pip from the command line, Up: Requirements for Installing Packages
+
+2.1.1.1 Ensure you can run Python from the command line
+.......................................................
+
+Before you go any further, make sure you have Python and that the
+expected version is available from your command line. You can check
+this by running:
+
+ python --version
+
+You should get some output like ‘Python 3.6.3’. If you do not have
+Python, please install the latest 3.x version from python.org(1) or
+refer to the Installing Python(2) section of the Hitchhiker’s Guide to
+Python.
+
+ Note: If you’re a newcomer and you get an error like this:
+
+ >>> python --version
+ Traceback (most recent call last):
+ File "<stdin>", line 1, in <module>
+ NameError: name 'python' is not defined
+
+ It’s because this command and other suggested commands in this
+ tutorial are intended to be run in a `shell' (also called a
+ `terminal' or `console'). See the Python for Beginners getting
+ started tutorial(3) for an introduction to using your operating
+ system’s shell and interacting with Python.
+
+ Note: If you’re using an enhanced shell like IPython or the Jupyter
+ notebook, you can run system commands like those in this tutorial
+ by prefacing them with a ‘!’ character:
+
+ In [1]: import sys
+ !{sys.executable} --version
+ Python 3.6.3
+
+ It’s recommended to write ‘{sys.executable}’ rather than plain
+ ‘python’ in order to ensure that commands are run in the Python
+ installation matching the currently running notebook (which may not
+ be the same Python installation that the ‘python’ command refers
+ to).
+
+ Note: Due to the way most Linux distributions are handling the
+ Python 3 migration, Linux users using the system Python without
+ creating a virtual environment first should replace the ‘python’
+ command in this tutorial with ‘python3’ and the ‘pip’ command with
+ ‘pip3 --user’. Do `not' run any of the commands in this tutorial
+ with ‘sudo’: if you get a permissions error, come back to the
+ section on creating virtual environments, set one up, and then
+ continue with the tutorial as written.
+
+ ---------- Footnotes ----------
+
+ (1) https://python.org
+
+ (2) http://docs.python-guide.org/en/latest/starting/installation/
+
+ (3)
+https://opentechschool.github.io/python-beginners/en/getting_started.html#what-is-python-exactly
+
+
+File: pythonpackagingguide.info, Node: Ensure you can run pip from the command line, Next: Ensure pip setuptools and wheel are up to date, Prev: Ensure you can run Python from the command line, Up: Requirements for Installing Packages
+
+2.1.1.2 Ensure you can run pip from the command line
+....................................................
+
+Additionally, you’ll need to make sure you have *note pip: 2b.
+available. You can check this by running:
+
+ pip --version
+
+If you installed Python from source, with an installer from
+python.org(1), or via Homebrew(2) you should already have pip. If
+you’re on Linux and installed using your OS package manager, you may
+have to install pip separately, see *note Installing
+pip/setuptools/wheel with Linux Package Managers: 2c.
+
+If ‘pip’ isn’t already installed, then first try to bootstrap it from
+the standard library:
+
+ python -m ensurepip --default-pip
+
+If that still doesn’t allow you to run ‘pip’:
+
+ * Securely Download get-pip.py(3) (4)
+
+ * Run ‘python get-pip.py’. (5) This will install or upgrade
+ pip. Additionally, it will install *note setuptools: 2d. and
+ *note wheel: 2e. if they’re not installed already.
+
+ Warning: Be cautious if you’re using a Python install
+ that’s managed by your operating system or another
+ package manager. get-pip.py does not coordinate with
+ those tools, and may leave your system in an inconsistent
+ state. You can use ‘python get-pip.py
+ --prefix=/usr/local/’ to install in ‘/usr/local’ which is
+ designed for locally-installed software.
+
+ ---------- Footnotes ----------
+
+ (1) https://python.org
+
+ (2) https://brew.sh
+
+ (3) https://bootstrap.pypa.io/get-pip.py
+
+ (4) (1) “Secure” in this context means using a modern browser or a
+tool like ‘curl’ that verifies SSL certificates when downloading from
+https URLs.
+
+ (5) (2) Depending on your platform, this may require root or
+Administrator access. *note pip: 2b. is currently considering changing
+this by making user installs the default behavior
+(https://github.com/pypa/pip/issues/1668).
+
+
+File: pythonpackagingguide.info, Node: Ensure pip setuptools and wheel are up to date, Next: Optionally create a virtual environment, Prev: Ensure you can run pip from the command line, Up: Requirements for Installing Packages
+
+2.1.1.3 Ensure pip, setuptools, and wheel are up to date
+........................................................
+
+While ‘pip’ alone is sufficient to install from pre-built binary
+archives, up to date copies of the ‘setuptools’ and ‘wheel’ projects are
+useful to ensure you can also install from source archives:
+
+ python -m pip install --upgrade pip setuptools wheel
+
+
+File: pythonpackagingguide.info, Node: Optionally create a virtual environment, Prev: Ensure pip setuptools and wheel are up to date, Up: Requirements for Installing Packages
+
+2.1.1.4 Optionally, create a virtual environment
+................................................
+
+See *note section below: 31. for details, but here’s the basic venv(1)
+(2) command to use on a typical Linux system:
+
+ python3 -m venv tutorial_env
+ source tutorial_env/bin/activate
+
+This will create a new virtual environment in the ‘tutorial_env’
+subdirectory, and configure the current shell to use it as the default
+‘python’ environment.
+
+ ---------- Footnotes ----------
+
+ (1) https://docs.python.org/3/library/venv.html
+
+ (2) (3) Beginning with Python 3.4, ‘venv’ (a stdlib alternative to
+*note virtualenv: 32.) will create virtualenv environments with ‘pip’
+pre-installed, thereby making it an equal alternative to *note
+virtualenv: 32.
+
+
+File: pythonpackagingguide.info, Node: Creating Virtual Environments, Next: Use pip for Installing, Prev: Requirements for Installing Packages, Up: Installing Packages
+
+2.1.2 Creating Virtual Environments
+-----------------------------------
+
+Python “Virtual Environments” allow Python *note packages: b. to be
+installed in an isolated location for a particular application, rather
+than being installed globally. If you are looking to safely install
+global command line tools, see *note Installing stand alone command line
+tools: 34.
+
+Imagine you have an application that needs version 1 of LibFoo, but
+another application requires version 2. How can you use both these
+applications? If you install everything into
+/usr/lib/python3.6/site-packages (or whatever your platform’s standard
+location is), it’s easy to end up in a situation where you
+unintentionally upgrade an application that shouldn’t be upgraded.
+
+Or more generally, what if you want to install an application and leave
+it be? If an application works, any change in its libraries or the
+versions of those libraries can break the application.
+
+Also, what if you can’t install *note packages: b. into the global
+site-packages directory? For instance, on a shared host.
+
+In all these cases, virtual environments can help you. They have their
+own installation directories and they don’t share libraries with other
+virtual environments.
+
+Currently, there are two common tools for creating Python virtual
+environments:
+
+ * venv(1) is available by default in Python 3.3 and later, and
+ installs *note pip: 2b. and *note setuptools: 2d. into created
+ virtual environments in Python 3.4 and later.
+
+ * *note virtualenv: 32. needs to be installed separately, but
+ supports Python 2.7+ and Python 3.3+, and *note pip: 2b, *note
+ setuptools: 2d. and *note wheel: 2e. are always installed into
+ created virtual environments by default (regardless of Python
+ version).
+
+The basic usage is like so:
+
+Using venv(2):
+
+ python3 -m venv <DIR>
+ source <DIR>/bin/activate
+
+Using *note virtualenv: 32.:
+
+ virtualenv <DIR>
+ source <DIR>/bin/activate
+
+For more information, see the venv(3) docs or the virtualenv(4) docs.
+
+The use of ‘source’ under Unix shells ensures that the virtual
+environment’s variables are set within the current shell, and not in a
+subprocess (which then disappears, having no useful effect).
+
+In both of the above cases, Windows users should _not_ use the ‘source’
+command, but should rather run the ‘activate’ script directly from the
+command shell like so:
+
+ <DIR>\Scripts\activate
+
+Managing multiple virtual environments directly can become tedious, so
+the *note dependency management tutorial: 35. introduces a higher level
+tool, *note Pipenv: 36, that automatically manages a separate virtual
+environment for each project and application that you work on.
+
+ ---------- Footnotes ----------
+
+ (1) https://docs.python.org/3/library/venv.html
+
+ (2) https://docs.python.org/3/library/venv.html
+
+ (3) https://docs.python.org/3/library/venv.html
+
+ (4) http://virtualenv.pypa.io
+
+
+File: pythonpackagingguide.info, Node: Use pip for Installing, Next: Installing from PyPI, Prev: Creating Virtual Environments, Up: Installing Packages
+
+2.1.3 Use pip for Installing
+----------------------------
+
+*note pip: 2b. is the recommended installer. Below, we’ll cover the
+most common usage scenarios. For more detail, see the pip docs(1),
+which includes a complete Reference Guide(2).
+
+ ---------- Footnotes ----------
+
+ (1) https://pip.pypa.io
+
+ (2) https://pip.pypa.io/en/latest/reference/index.html
+
+
+File: pythonpackagingguide.info, Node: Installing from PyPI, Next: Source Distributions vs Wheels, Prev: Use pip for Installing, Up: Installing Packages
+
+2.1.4 Installing from PyPI
+--------------------------
+
+The most common usage of *note pip: 2b. is to install from the *note
+Python Package Index: 39. using a *note requirement specifier: 3a.
+Generally speaking, a requirement specifier is composed of a project
+name followed by an optional *note version specifier: 3b. PEP 440(1)
+contains a full specification(2) of the currently supported specifiers.
+Below are some examples.
+
+To install the latest version of “SomeProject”:
+
+ pip install "SomeProject"
+
+To install a specific version:
+
+ pip install "SomeProject==1.4"
+
+To install greater than or equal to one version and less than another:
+
+ pip install "SomeProject>=1,<2"
+
+To install a version that’s “compatible”(3) with a certain version: (4)
+
+ pip install "SomeProject~=1.4.2"
+
+In this case, this means to install any version “==1.4.*” version that’s
+also “>=1.4.2”.
+
+ ---------- Footnotes ----------
+
+ (1) https://www.python.org/dev/peps/pep-0440
+
+ (2) https://www.python.org/dev/peps/pep-0440#version-specifiers
+
+ (3) https://www.python.org/dev/peps/pep-0440#compatible-release
+
+ (4) (4) The compatible release specifier was accepted in PEP 440
+(https://www.python.org/dev/peps/pep-0440) and support was released in
+*note setuptools: 2d. v8.0 and *note pip: 2b. v6.0
+
+
+File: pythonpackagingguide.info, Node: Source Distributions vs Wheels, Next: Upgrading packages, Prev: Installing from PyPI, Up: Installing Packages
+
+2.1.5 Source Distributions vs Wheels
+------------------------------------
+
+*note pip: 2b. can install from either *note Source Distributions
+(sdist): 3d. or *note Wheels: d, but if both are present on PyPI, pip
+will prefer a compatible *note wheel: d.
+
+*note Wheels: d. are a pre-built *note distribution: b. format that
+provides faster installation compared to *note Source Distributions
+(sdist): 3d, especially when a project contains compiled extensions.
+
+If *note pip: 2b. does not find a wheel to install, it will locally
+build a wheel and cache it for future installs, instead of rebuilding
+the source distribution in the future.
+
+
+File: pythonpackagingguide.info, Node: Upgrading packages, Next: Installing to the User Site, Prev: Source Distributions vs Wheels, Up: Installing Packages
+
+2.1.6 Upgrading packages
+------------------------
+
+Upgrade an already installed ‘SomeProject’ to the latest from PyPI.
+
+ pip install --upgrade SomeProject
+
+
+File: pythonpackagingguide.info, Node: Installing to the User Site, Next: Requirements files, Prev: Upgrading packages, Up: Installing Packages
+
+2.1.7 Installing to the User Site
+---------------------------------
+
+To install *note packages: b. that are isolated to the current user, use
+the ‘--user’ flag:
+
+ pip install --user SomeProject
+
+For more information see the User Installs(1) section from the pip docs.
+
+Note that the ‘--user’ flag has no effect when inside a virtual
+environment - all installation commands will affect the virtual
+environment.
+
+If ‘SomeProject’ defines any command-line scripts or console entry
+points, ‘--user’ will cause them to be installed inside the user
+base(2)’s binary directory, which may or may not already be present in
+your shell’s ‘PATH’. (Starting in version 10, pip displays a warning
+when installing any scripts to a directory outside ‘PATH’.) If the
+scripts are not available in your shell after installation, you’ll need
+to add the directory to your ‘PATH’:
+
+ - On Linux and macOS you can find the user base binary directory by
+ running ‘python -m site --user-base’ and adding ‘bin’ to the end.
+ For example, this will typically print ‘~/.local’ (with ‘~’
+ expanded to the absolute path to your home directory) so you’ll
+ need to add ‘~/.local/bin’ to your ‘PATH’. You can set your ‘PATH’
+ permanently by modifying ~/.profile(3).
+
+ - On Windows you can find the user base binary directory by running
+ ‘py -m site --user-site’ and replacing ‘site-packages’ with
+ ‘Scripts’. For example, this could return
+ ‘C:\Users\Username\AppData\Roaming\Python36\site-packages’ so you
+ would need to set your ‘PATH’ to include
+ ‘C:\Users\Username\AppData\Roaming\Python36\Scripts’. You can set
+ your user ‘PATH’ permanently in the Control Panel(4). You may need
+ to log out for the ‘PATH’ changes to take effect.
+
+ ---------- Footnotes ----------
+
+ (1)
+https://pip.readthedocs.io/en/latest/user_guide.html#user-installs
+
+ (2) https://docs.python.org/3/library/site.html#site.USER_BASE
+
+ (3) https://stackoverflow.com/a/14638025
+
+ (4)
+https://msdn.microsoft.com/en-us/library/windows/desktop/bb776899(v=vs.85).aspx
+
+
+File: pythonpackagingguide.info, Node: Requirements files, Next: Installing from VCS, Prev: Installing to the User Site, Up: Installing Packages
+
+2.1.8 Requirements files
+------------------------
+
+Install a list of requirements specified in a Requirements File(1).
+
+ pip install -r requirements.txt
+
+ ---------- Footnotes ----------
+
+ (1) https://pip.pypa.io/en/latest/user_guide/#requirements-files
+
+
+File: pythonpackagingguide.info, Node: Installing from VCS, Next: Installing from other Indexes, Prev: Requirements files, Up: Installing Packages
+
+2.1.9 Installing from VCS
+-------------------------
+
+Install a project from VCS in “editable” mode. For a full breakdown of
+the syntax, see pip’s section on VCS Support(1).
+
+ pip install -e git+https://git.repo/some_pkg.git#egg=SomeProject # from git
+ pip install -e hg+https://hg.repo/some_pkg#egg=SomeProject # from mercurial
+ pip install -e svn+svn://svn.repo/some_pkg/trunk/#egg=SomeProject # from svn
+ pip install -e git+https://git.repo/some_pkg.git@feature#egg=SomeProject # from a branch
+
+ ---------- Footnotes ----------
+
+ (1) https://pip.pypa.io/en/latest/reference/pip_install/#vcs-support
+
+
+File: pythonpackagingguide.info, Node: Installing from other Indexes, Next: Installing from a local src tree, Prev: Installing from VCS, Up: Installing Packages
+
+2.1.10 Installing from other Indexes
+------------------------------------
+
+Install from an alternate index
+
+ pip install --index-url http://my.package.repo/simple/ SomeProject
+
+Search an additional index during install, in addition to *note PyPI:
+39.
+
+ pip install --extra-index-url http://my.package.repo/simple SomeProject
+
+
+File: pythonpackagingguide.info, Node: Installing from a local src tree, Next: Installing from local archives, Prev: Installing from other Indexes, Up: Installing Packages
+
+2.1.11 Installing from a local src tree
+---------------------------------------
+
+Installing from local src in Development Mode(1), i.e. in such a way
+that the project appears to be installed, but yet is still editable from
+the src tree.
+
+ pip install -e <path>
+
+You can also install normally from src
+
+ pip install <path>
+
+ ---------- Footnotes ----------
+
+ (1)
+https://setuptools.readthedocs.io/en/latest/setuptools.html#development-mode
+
+
+File: pythonpackagingguide.info, Node: Installing from local archives, Next: Installing from other sources, Prev: Installing from a local src tree, Up: Installing Packages
+
+2.1.12 Installing from local archives
+-------------------------------------
+
+Install a particular source archive file.
+
+ pip install ./downloads/SomeProject-1.0.4.tar.gz
+
+Install from a local directory containing archives (and don’t check
+*note PyPI: 39.)
+
+ pip install --no-index --find-links=file:///local/dir/ SomeProject
+ pip install --no-index --find-links=/local/dir/ SomeProject
+ pip install --no-index --find-links=relative/dir/ SomeProject
+
+
+File: pythonpackagingguide.info, Node: Installing from other sources, Next: Installing Prereleases, Prev: Installing from local archives, Up: Installing Packages
+
+2.1.13 Installing from other sources
+------------------------------------
+
+To install from other data sources (for example Amazon S3 storage) you
+can create a helper application that presents the data in a PEP 503(1)
+compliant index format, and use the ‘--extra-index-url’ flag to direct
+pip to use that index.
+
+ ./s3helper --port=7777
+ pip install --extra-index-url http://localhost:7777 SomeProject
+
+ ---------- Footnotes ----------
+
+ (1) https://www.python.org/dev/peps/pep-0503
+
+
+File: pythonpackagingguide.info, Node: Installing Prereleases, Next: Installing Setuptools “Extras”, Prev: Installing from other sources, Up: Installing Packages
+
+2.1.14 Installing Prereleases
+-----------------------------
+
+Find pre-release and development versions, in addition to stable
+versions. By default, pip only finds stable versions.
+
+ pip install --pre SomeProject
+
+
+File: pythonpackagingguide.info, Node: Installing Setuptools “Extras”, Prev: Installing Prereleases, Up: Installing Packages
+
+2.1.15 Installing Setuptools “Extras”
+-------------------------------------
+
+Install setuptools extras(1).
+
+ $ pip install SomePackage[PDF]
+ $ pip install SomePackage[PDF]==3.0
+ $ pip install -e .[PDF]==3.0 # editable project in current directory
+
+__________________________________________________________________
+
+ ---------- Footnotes ----------
+
+ (1)
+https://setuptools.readthedocs.io/en/latest/setuptools.html#declaring-extras-optional-features-with-their-own-dependencies
+
+
+File: pythonpackagingguide.info, Node: Managing Application Dependencies, Next: Packaging Python Projects, Prev: Installing Packages, Up: Tutorials
+
+2.2 Managing Application Dependencies
+=====================================
+
+The *note package installation tutorial: 25. covered the basics of
+getting set up to install and update Python packages.
+
+However, running these commands interactively can get tedious even for
+your own personal projects, and things get even more difficult when
+trying to set up development environments automatically for projects
+with multiple contributors.
+
+This tutorial walks you through the use of *note Pipenv: 36. to manage
+dependencies for an application. It will show you how to install and
+use the necessary tools and make strong recommendations on best
+practices.
+
+Keep in mind that Python is used for a great many different purposes,
+and precisely how you want to manage your dependencies may change based
+on how you decide to publish your software. The guidance presented here
+is most directly applicable to the development and deployment of network
+services (including web applications), but is also very well suited to
+managing development and testing environments for any kind of project.
+
+Developers of Python libraries, or of applications that support
+distribution as Python libraries, should also consider the poetry(1)
+project as an alternative dependency management solution.
+
+* Menu:
+
+* Installing Pipenv::
+* Installing packages for your project::
+* Using installed packages::
+* Next steps::
+* Other Tools for Application Dependency Management::
+
+ ---------- Footnotes ----------
+
+ (1) https://github.com/python-poetry/poetry
+
+
+File: pythonpackagingguide.info, Node: Installing Pipenv, Next: Installing packages for your project, Up: Managing Application Dependencies
+
+2.2.1 Installing Pipenv
+-----------------------
+
+*note Pipenv: 36. is a dependency manager for Python projects. If
+you’re familiar with Node.js’ npm(1) or Ruby’s bundler(2), it is similar
+in spirit to those tools. While *note pip: 2b. alone is often
+sufficient for personal use, Pipenv is recommended for collaborative
+projects as it’s a higher-level tool that simplifies dependency
+management for common use cases.
+
+Use ‘pip’ to install Pipenv:
+
+ pip install --user pipenv
+ Note: This does a user installation(3) to prevent breaking any
+ system-wide packages. If ‘pipenv’ isn’t available in your shell
+ after installation, you’ll need to add the user base(4)’s binary
+ directory to your ‘PATH’. See *note Installing to the User Site:
+ 40. for more information.
+
+ ---------- Footnotes ----------
+
+ (1) https://www.npmjs.com/
+
+ (2) http://bundler.io/
+
+ (3) https://pip.pypa.io/en/stable/user_guide/#user-installs
+
+ (4) https://docs.python.org/3/library/site.html#site.USER_BASE
+
+
+File: pythonpackagingguide.info, Node: Installing packages for your project, Next: Using installed packages, Prev: Installing Pipenv, Up: Managing Application Dependencies
+
+2.2.2 Installing packages for your project
+------------------------------------------
+
+Pipenv manages dependencies on a per-project basis. To install
+packages, change into your project’s directory (or just an empty
+directory for this tutorial) and run:
+
+ cd myproject
+ pipenv install requests
+
+Pipenv will install the Requests(1) library and create a ‘Pipfile’ for
+you in your project’s directory. The *note Pipfile: 51. is used to
+track which dependencies your project needs in case you need to
+re-install them, such as when you share your project with others. You
+should get output similar to this (although the exact paths shown will
+vary):
+
+ Creating a Pipfile for this project...
+ Creating a virtualenv for this project...
+ Using base prefix '/usr/local/Cellar/python3/3.6.2/Frameworks/Python.framework/Versions/3.6'
+ New python executable in ~/.local/share/virtualenvs/tmp-agwWamBd/bin/python3.6
+ Also creating executable in ~/.local/share/virtualenvs/tmp-agwWamBd/bin/python
+ Installing setuptools, pip, wheel...done.
+
+ Virtualenv location: ~/.local/share/virtualenvs/tmp-agwWamBd
+ Installing requests...
+ Collecting requests
+ Using cached requests-2.18.4-py2.py3-none-any.whl
+ Collecting idna<2.7,>=2.5 (from requests)
+ Using cached idna-2.6-py2.py3-none-any.whl
+ Collecting urllib3<1.23,>=1.21.1 (from requests)
+ Using cached urllib3-1.22-py2.py3-none-any.whl
+ Collecting chardet<3.1.0,>=3.0.2 (from requests)
+ Using cached chardet-3.0.4-py2.py3-none-any.whl
+ Collecting certifi>=2017.4.17 (from requests)
+ Using cached certifi-2017.7.27.1-py2.py3-none-any.whl
+ Installing collected packages: idna, urllib3, chardet, certifi, requests
+ Successfully installed certifi-2017.7.27.1 chardet-3.0.4 idna-2.6 requests-2.18.4 urllib3-1.22
+
+ Adding requests to Pipfile's [packages]...
+
+ ---------- Footnotes ----------
+
+ (1) https://pypi.org/project/requests/
+
+
+File: pythonpackagingguide.info, Node: Using installed packages, Next: Next steps, Prev: Installing packages for your project, Up: Managing Application Dependencies
+
+2.2.3 Using installed packages
+------------------------------
+
+Now that Requests is installed you can create a simple ‘main.py’ file to
+use it:
+
+ import requests
+
+ response = requests.get('https://httpbin.org/ip')
+
+ print('Your IP is {0}'.format(response.json()['origin']))
+
+Then you can run this script using ‘pipenv run’:
+
+ pipenv run python main.py
+
+You should get output similar to this:
+
+ Your IP is 8.8.8.8
+
+Using ‘pipenv run’ ensures that your installed packages are available to
+your script. It’s also possible to spawn a new shell that ensures all
+commands have access to your installed packages with ‘pipenv shell’.
+
+
+File: pythonpackagingguide.info, Node: Next steps, Next: Other Tools for Application Dependency Management, Prev: Using installed packages, Up: Managing Application Dependencies
+
+2.2.4 Next steps
+----------------
+
+Congratulations, you now know how to effectively manage dependencies and
+development environments on a collaborative Python project! ✨ 🍰 ✨
+
+If you’re interested in creating and distributing your own Python
+packages, see the *note tutorial on packaging and distributing packages:
+55.
+
+Note that when your application includes definitions of Python source
+packages, they (and their dependencies) can be added to your ‘pipenv’
+environment with ‘pipenv install -e <relative-path-to-source-directory>’
+(e.g. ‘pipenv install -e .’ or ‘pipenv install -e src’).
+
+
+File: pythonpackagingguide.info, Node: Other Tools for Application Dependency Management, Prev: Next steps, Up: Managing Application Dependencies
+
+2.2.5 Other Tools for Application Dependency Management
+-------------------------------------------------------
+
+If you find this particular approach to managing application
+dependencies isn’t working well for you or your use case, you may want
+to explore these other tools and techniques to see if one of them is a
+better fit:
+
+ * poetry(1) for a tool comparable in scope to ‘pipenv’ that focuses
+ more directly on use cases where the repository being managed is
+ structured as a Python project with a valid ‘pyproject.toml’ file
+ (by contrast, ‘pipenv’ explicitly avoids making the assumption that
+ the application being worked on that’s depending on components from
+ PyPI will itself support distribution as a ‘pip’-installable Python
+ package).
+
+ * hatch(2) for opinionated coverage of even more steps in the project
+ management workflow (such as incrementing versions, tagging
+ releases, and creating new skeleton projects from project
+ templates)
+
+ * pip-tools(3) to build your own custom workflow from lower level
+ pieces like ‘pip-compile’ and ‘pip-sync’
+
+ * micropipenv(4) is a lightweight wrapper for pip to support
+ requirements.txt, Pipenv and Poetry lock files or converting them
+ to pip-tools compatible output. Designed for containerized Python
+ applications but not limited to them.
+
+ ---------- Footnotes ----------
+
+ (1) https://github.com/python-poetry/poetry
+
+ (2) https://github.com/ofek/hatch
+
+ (3) https://github.com/jazzband/pip-tools
+
+ (4) https://github.com/thoth-station/micropipenv
+
+
+File: pythonpackagingguide.info, Node: Packaging Python Projects, Next: Creating Documentation, Prev: Managing Application Dependencies, Up: Tutorials
+
+2.3 Packaging Python Projects
+=============================
+
+This tutorial walks you through how to package a simple Python project.
+It will show you how to add the necessary files and structure to create
+the package, how to build the package, and how to upload it to the
+Python Package Index.
+
+* Menu:
+
+* A simple project::
+* Creating the package files::
+* Creating a test folder::
+* Creating setup.py: Creating setup py.
+* Creating README.md: Creating README md.
+* Creating a LICENSE::
+* Generating distribution archives::
+* Uploading the distribution archives::
+* Installing your newly uploaded package::
+* Next steps: Next steps<2>.
+
+
+File: pythonpackagingguide.info, Node: A simple project, Next: Creating the package files, Up: Packaging Python Projects
+
+2.3.1 A simple project
+----------------------
+
+This tutorial uses a simple project named ‘example_pkg’. If you are
+unfamiliar with Python’s modules and *note import packages: a, take a
+few minutes to read over the Python documentation for packages and
+modules(1). Even if you already have a project that you want to package
+up, we recommend following this tutorial as-is using this example
+package and then trying with your own package.
+
+To create this project locally, create the following file structure:
+
+ packaging_tutorial
+ └── example_pkg
+    └── __init__.py
+
+Once you create this structure, you’ll want to run all of the commands
+in this tutorial within the top-level folder - so be sure to ‘cd
+packaging_tutorial’.
+
+‘example_pkg/__init__.py’ is required to import the directory as a
+package, and can simply be an empty file.
+
+ ---------- Footnotes ----------
+
+ (1) https://docs.python.org/3/tutorial/modules.html#packages
+
+
+File: pythonpackagingguide.info, Node: Creating the package files, Next: Creating a test folder, Prev: A simple project, Up: Packaging Python Projects
+
+2.3.2 Creating the package files
+--------------------------------
+
+You will now create a handful of files to package up this project and
+prepare it for distribution. Create the new files listed below and
+place them in the project’s root directory - you will add content to
+them in the following steps.
+
+ packaging_tutorial
+ ├── LICENSE
+ ├── README.md
+ ├── example_pkg
+ │   └── __init__.py
+ ├── setup.py
+ └── tests
+
+
+File: pythonpackagingguide.info, Node: Creating a test folder, Next: Creating setup py, Prev: Creating the package files, Up: Packaging Python Projects
+
+2.3.3 Creating a test folder
+----------------------------
+
+‘tests/’ is a placeholder for unit test files. Leave it empty for now.
+
+
+File: pythonpackagingguide.info, Node: Creating setup py, Next: Creating README md, Prev: Creating a test folder, Up: Packaging Python Projects
+
+2.3.4 Creating setup.py
+-----------------------
+
+‘setup.py’ is the build script for *note setuptools: 2d. It tells
+setuptools about your package (such as the name and version) as well as
+which code files to include.
+
+Open ‘setup.py’ and enter the following content. Update the package
+name to include your username (for example, ‘example-pkg-theacodes’),
+this ensures that you have a unique package name and that your package
+doesn’t conflict with packages uploaded by other people following this
+tutorial.
+
+ import setuptools
+
+ with open("README.md", "r") as fh:
+ long_description = fh.read()
+
+ setuptools.setup(
+ name="example-pkg-YOUR-USERNAME-HERE", # Replace with your own username
+ version="0.0.1",
+ author="Example Author",
+ author_email="author@example.com",
+ description="A small example package",
+ long_description=long_description,
+ long_description_content_type="text/markdown",
+ url="https://github.com/pypa/sampleproject",
+ packages=setuptools.find_packages(),
+ classifiers=[
+ "Programming Language :: Python :: 3",
+ "License :: OSI Approved :: MIT License",
+ "Operating System :: OS Independent",
+ ],
+ python_requires='>=3.6',
+ )
+
+‘setup()’ takes several arguments. This example package uses a
+relatively minimal set:
+
+ - ‘name’ is the `distribution name' of your package. This can be any
+ name as long as only contains letters, numbers, ‘_’ , and ‘-’. It
+ also must not already be taken on pypi.org. `Be sure to update
+ this with your username,' as this ensures you won’t try to upload a
+ package with the same name as one which already exists when you
+ upload the package.
+
+ - ‘version’ is the package version see PEP 440(1) for more details on
+ versions.
+
+ - ‘author’ and ‘author_email’ are used to identify the author of the
+ package.
+
+ - ‘description’ is a short, one-sentence summary of the package.
+
+ - ‘long_description’ is a detailed description of the package. This
+ is shown on the package detail package on the Python Package Index.
+ In this case, the long description is loaded from ‘README.md’ which
+ is a common pattern.
+
+ - ‘long_description_content_type’ tells the index what type of markup
+ is used for the long description. In this case, it’s Markdown.
+
+ - ‘url’ is the URL for the homepage of the project. For many
+ projects, this will just be a link to GitHub, GitLab, Bitbucket, or
+ similar code hosting service.
+
+ - ‘packages’ is a list of all Python *note import packages: a. that
+ should be included in the *note Distribution Package: b. Instead
+ of listing each package manually, we can use ‘find_packages()’ to
+ automatically discover all packages and subpackages. In this case,
+ the list of packages will be ‘example_pkg’ as that’s the only
+ package present.
+
+ - ‘classifiers’ gives the index and *note pip: 2b. some additional
+ metadata about your package. In this case, the package is only
+ compatible with Python 3, is licensed under the MIT license, and is
+ OS-independent. You should always include at least which
+ version(s) of Python your package works on, which license your
+ package is available under, and which operating systems your
+ package will work on. For a complete list of classifiers, see
+ ‘https://pypi.org/classifiers/’.
+
+There are many more than the ones mentioned here. See *note Packaging
+and distributing projects: 6. for more details.
+
+ ---------- Footnotes ----------
+
+ (1) https://www.python.org/dev/peps/pep-0440
+
+
+File: pythonpackagingguide.info, Node: Creating README md, Next: Creating a LICENSE, Prev: Creating setup py, Up: Packaging Python Projects
+
+2.3.5 Creating README.md
+------------------------
+
+Open ‘README.md’ and enter the following content. You can customize
+this if you’d like.
+
+ # Example Package
+
+ This is a simple example package. You can use
+ [Github-flavored Markdown](https://guides.github.com/features/mastering-markdown/)
+ to write your content.
+
+
+File: pythonpackagingguide.info, Node: Creating a LICENSE, Next: Generating distribution archives, Prev: Creating README md, Up: Packaging Python Projects
+
+2.3.6 Creating a LICENSE
+------------------------
+
+It’s important for every package uploaded to the Python Package Index to
+include a license. This tells users who install your package the terms
+under which they can use your package. For help picking a license, see
+‘https://choosealicense.com/’. Once you have chosen a license, open
+‘LICENSE’ and enter the license text. For example, if you had chosen
+the MIT license:
+
+ Copyright (c) 2018 The Python Packaging Authority
+
+ 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.
+
+
+File: pythonpackagingguide.info, Node: Generating distribution archives, Next: Uploading the distribution archives, Prev: Creating a LICENSE, Up: Packaging Python Projects
+
+2.3.7 Generating distribution archives
+--------------------------------------
+
+The next step is to generate *note distribution packages: b. for the
+package. These are archives that are uploaded to the Package Index and
+can be installed by *note pip: 2b.
+
+Make sure you have the latest versions of ‘setuptools’ and ‘wheel’
+installed:
+
+ python3 -m pip install --user --upgrade setuptools wheel
+
+ Tip: IF you have trouble installing these, see the *note Installing
+ Packages: 23. tutorial.
+
+Now run this command from the same directory where ‘setup.py’ is
+located:
+
+ python3 setup.py sdist bdist_wheel
+
+This command should output a lot of text and once completed should
+generate two files in the ‘dist’ directory:
+
+ dist/
+ example_pkg_YOUR_USERNAME_HERE-0.0.1-py3-none-any.whl
+ example_pkg_YOUR_USERNAME_HERE-0.0.1.tar.gz
+
+ Note: If you run into trouble here, please copy the output and file
+ an issue over on packaging problems(1) and we’ll do our best to
+ help you!
+
+The ‘tar.gz’ file is a *note Source Archive: 62. whereas the ‘.whl’ file
+is a *note Built Distribution: 63. Newer *note pip: 2b. versions
+preferentially install built distributions, but will fall back to source
+archives if needed. You should always upload a source archive and
+provide built archives for the platforms your project is compatible
+with. In this case, our example package is compatible with Python on
+any platform so only one built distribution is needed.
+
+ ---------- Footnotes ----------
+
+ (1)
+https://github.com/pypa/packaging-problems/issues/new?title=Trouble+following+packaging+libraries+tutorial
+
+
+File: pythonpackagingguide.info, Node: Uploading the distribution archives, Next: Installing your newly uploaded package, Prev: Generating distribution archives, Up: Packaging Python Projects
+
+2.3.8 Uploading the distribution archives
+-----------------------------------------
+
+Finally, it’s time to upload your package to the Python Package Index!
+
+The first thing you’ll need to do is register an account on ‘Test PyPI’.
+Test PyPI is a separate instance of the package index intended for
+testing and experimentation. It’s great for things like this tutorial
+where we don’t necessarily want to upload to the real index. To
+register an account, go to ‘https://test.pypi.org/account/register/’ and
+complete the steps on that page. You will also need to verify your
+email address before you’re able to upload any packages. For more
+details on Test PyPI, see *note Using TestPyPI: 65.
+
+Now you’ll create a PyPI API token(1) so you will be able to securely
+upload your project.
+
+Go to ‘https://test.pypi.org/manage/account/#api-tokens’ and create a
+new API token(2); don’t limit its scope to a particular project, since
+you are creating a new project.
+
+`Don’t close the page until you have copied and saved the token — you
+won’t see that token again.'
+
+Now that you are registered, you can use *note twine: 66. to upload the
+distribution packages. You’ll need to install Twine:
+
+ python3 -m pip install --user --upgrade twine
+
+Once installed, run Twine to upload all of the archives under ‘dist’:
+
+ python3 -m twine upload --repository testpypi dist/*
+
+You will be prompted for a username and password. For the username, use
+‘__token__’. For the password, use the token value, including the
+‘pypi-’ prefix.
+
+After the command completes, you should see output similar to this:
+
+ Uploading distributions to https://test.pypi.org/legacy/
+ Enter your username: [your username]
+ Enter your password:
+ Uploading example_pkg_YOUR_USERNAME_HERE-0.0.1-py3-none-any.whl
+ 100%|█████████████████████| 4.65k/4.65k [00:01<00:00, 2.88kB/s]
+ Uploading example_pkg_YOUR_USERNAME_HERE-0.0.1.tar.gz
+ 100%|█████████████████████| 4.25k/4.25k [00:01<00:00, 3.05kB/s]
+
+Once uploaded your package should be viewable on TestPyPI, for example,
+‘https://test.pypi.org/project/example-pkg-YOUR-USERNAME-HERE’
+
+ ---------- Footnotes ----------
+
+ (1) https://test.pypi.org/help/#apitoken
+
+ (2) https://test.pypi.org/help/#apitoken
+
+
+File: pythonpackagingguide.info, Node: Installing your newly uploaded package, Next: Next steps<2>, Prev: Uploading the distribution archives, Up: Packaging Python Projects
+
+2.3.9 Installing your newly uploaded package
+--------------------------------------------
+
+You can use *note pip: 2b. to install your package and verify that it
+works. Create a new *note virtualenv: 32. (see *note Installing
+Packages: 23. for detailed instructions) and install your package from
+TestPyPI:
+
+ python3 -m pip install --index-url https://test.pypi.org/simple/ --no-deps example-pkg-YOUR-USERNAME-HERE
+
+Make sure to specify your username in the package name!
+
+pip should install the package from Test PyPI and the output should look
+something like this:
+
+ Collecting example-pkg-YOUR-USERNAME-HERE
+ Downloading https://test-files.pythonhosted.org/packages/.../example-pkg-YOUR-USERNAME-HERE-0.0.1-py3-none-any.whl
+ Installing collected packages: example-pkg-YOUR-USERNAME-HERE
+ Successfully installed example-pkg-YOUR-USERNAME-HERE-0.0.1
+
+ Note: This example uses ‘--index-url’ flag to specify TestPyPI
+ instead of live PyPI. Additionally, it specifies ‘--no-deps’.
+ Since TestPyPI doesn’t have the same packages as the live PyPI,
+ it’s possible that attempting to install dependencies may fail or
+ install something unexpected. While our example package doesn’t
+ have any dependencies, it’s a good practice to avoid installing
+ dependencies when using TestPyPI.
+
+You can test that it was installed correctly by importing the package.
+Run the Python interpreter (make sure you’re still in your virtualenv):
+
+ python
+
+and from the interpreter shell import the package:
+
+ >>> import example_pkg
+
+Note that the *note Import Package: a. is ‘example_pkg’ regardless of
+what name you gave your *note Distribution Package: b. in ‘setup.py’ (in
+this case, ‘example-pkg-YOUR-USERNAME-HERE’).
+
+
+File: pythonpackagingguide.info, Node: Next steps<2>, Prev: Installing your newly uploaded package, Up: Packaging Python Projects
+
+2.3.10 Next steps
+-----------------
+
+`Congratulations, you’ve packaged and distributed a Python project!' ✨
+🍰 ✨
+
+Keep in mind that this tutorial showed you how to upload your package to
+Test PyPI, which isn’t a permanent storage. The Test system
+occasionally deletes packages and accounts. It is best to use Test PyPI
+for testing and experiments like this tutorial.
+
+When you are ready to upload a real package to the Python Package Index
+you can do much the same as you did in this tutorial, but with these
+important differences:
+
+ * Choose a memorable and unique name for your package. You don’t
+ have to append your username as you did in the tutorial.
+
+ * Register an account on ‘https://pypi.org’ - note that these are two
+ separate servers and the login details from the test server are not
+ shared with the main server.
+
+ * Use ‘twine upload dist/*’ to upload your package and enter your
+ credentials for the account you registered on the real PyPI. Now
+ that you’re uploading the package in production, you don’t need to
+ specify ‘--repository’; the package will upload to
+ ‘https://pypi.org/’ by default.
+
+ * Install your package from the real PyPI using ‘pip install
+ [your-package]’.
+
+At this point if you want to read more on packaging Python libraries
+here are some things you can do:
+
+ * Read more about using *note setuptools: 2d. to package libraries in
+ *note Packaging and distributing projects: 6.
+
+ * Read about *note Packaging binary extensions: 69.
+
+ * Consider alternatives to *note setuptools: 2d. such as *note flit:
+ 6a, hatch(1), and poetry(2).
+
+ ---------- Footnotes ----------
+
+ (1) https://github.com/ofek/hatch
+
+ (2) https://github.com/python-poetry/poetry
+
+
+File: pythonpackagingguide.info, Node: Creating Documentation, Prev: Packaging Python Projects, Up: Tutorials
+
+2.4 Creating Documentation
+==========================
+
+This section covers the basics of how to create documentation using
+Sphinx(1) and host the documentation for free in Read The Docs(2).
+
+* Menu:
+
+* Installing Sphinx::
+* Getting Started With Sphinx::
+* Other Sources::
+
+ ---------- Footnotes ----------
+
+ (1) http://sphinx-doc.org/
+
+ (2) https://readthedocs.org/
+
+
+File: pythonpackagingguide.info, Node: Installing Sphinx, Next: Getting Started With Sphinx, Up: Creating Documentation
+
+2.4.1 Installing Sphinx
+-----------------------
+
+Use ‘pip’ to install Sphinx:
+
+ pip install -U sphinx
+
+For other installation methods, see this installation guide(1) by
+Sphinx.
+
+ ---------- Footnotes ----------
+
+ (1) http://www.sphinx-doc.org/en/master/usage/installation.html
+
+
+File: pythonpackagingguide.info, Node: Getting Started With Sphinx, Next: Other Sources, Prev: Installing Sphinx, Up: Creating Documentation
+
+2.4.2 Getting Started With Sphinx
+---------------------------------
+
+Create a ‘docs’ directory inside your project to hold your
+documentation:
+
+ cd /path/to/project
+ mkdir docs
+
+Run ‘sphinx-quickstart’ inside the ‘docs’ directory:
+
+ cd docs
+ sphinx-quickstart
+
+This sets up a source directory, walks you through some basic
+configurations, and creates an ‘index.rst’ file as well as a ‘conf.py’
+file.
+
+You can add some information about your project in ‘index.rst’, then
+build them:
+
+ make html
+
+For more details on the build process, see this guide(1) by Read The
+Docs.
+
+ ---------- Footnotes ----------
+
+ (1) https://docs.readthedocs.io/en/latest/intro/import-guide.html
+
+
+File: pythonpackagingguide.info, Node: Other Sources, Prev: Getting Started With Sphinx, Up: Creating Documentation
+
+2.4.3 Other Sources
+-------------------
+
+For a more detailed guide on how to use Sphinx and reStructuredText,
+please see this documentation tutorial(1) on Hitchhiker’s Guide to
+Python.
+
+ ---------- Footnotes ----------
+
+ (1) https://docs.python-guide.org/writing/documentation/
+
+
+File: pythonpackagingguide.info, Node: Guides, Next: Discussions, Prev: Tutorials, Up: Top
+
+3 Guides
+********
+
+`Guides' are focused on accomplishing a specific task and assume that
+you are already familiar with the basics of Python packaging. If you’re
+looking for an introduction to packaging, see *note Tutorials: 20.
+
+* Menu:
+
+* Tool recommendations::
+* Installing packages using pip and virtual environments::
+* Installing stand alone command line tools::
+* Installing pip/setuptools/wheel with Linux Package Managers::
+* Installing scientific packages::
+* Multi-version installs::
+* Packaging and distributing projects::
+* Including files in source distributions with MANIFEST.in: Including files in source distributions with MANIFEST in.
+* Single-sourcing the package version::
+* Supporting multiple Python versions::
+* Dropping support for older Python versions::
+* Packaging binary extensions::
+* Supporting Windows using Appveyor::
+* Packaging namespace packages::
+* Creating and discovering plugins::
+* Analyzing PyPI package downloads::
+* Package index mirrors and caches::
+* Hosting your own simple repository::
+* Migrating to PyPI.org: Migrating to PyPI org.
+* Using TestPyPI: Using TestPyPI<2>.
+* Making a PyPI-friendly README::
+* Publishing package distribution releases using GitHub Actions CI/CD workflows::
+
+
+File: pythonpackagingguide.info, Node: Tool recommendations, Next: Installing packages using pip and virtual environments, Up: Guides
+
+3.1 Tool recommendations
+========================
+
+If you’re familiar with Python packaging and installation, and just want
+to know what tools are currently recommended, then here it is.
+
+* Menu:
+
+* Application dependency management::
+* Installation tool recommendations::
+* Packaging tool recommendations::
+* Publishing platform migration::
+
+
+File: pythonpackagingguide.info, Node: Application dependency management, Next: Installation tool recommendations, Up: Tool recommendations
+
+3.1.1 Application dependency management
+---------------------------------------
+
+Use *note Pipenv: 36. to manage library dependencies when developing
+Python applications. See *note Managing Application Dependencies: 4a.
+for more details on using ‘pipenv’.
+
+When ‘pipenv’ does not meet your use case, consider other tools like:
+
+ * *note pip: 2b.
+
+ * pip-tools(1)
+
+ * Poetry(2)
+
+ ---------- Footnotes ----------
+
+ (1) https://github.com/jazzband/pip-tools
+
+ (2) https://python-poetry.org/
+
+
+File: pythonpackagingguide.info, Node: Installation tool recommendations, Next: Packaging tool recommendations, Prev: Application dependency management, Up: Tool recommendations
+
+3.1.2 Installation tool recommendations
+---------------------------------------
+
+ * Use *note pip: 2b. to install Python *note packages: b. from *note
+ PyPI: 39. (1) (2) Depending on how *note pip: 2b. is installed,
+ you may need to also install *note wheel: 2e. to get the benefit of
+ wheel caching. (3)
+
+ * Use *note virtualenv: 32, or venv(4) to isolate application
+ specific dependencies from a shared Python installation. (5)
+
+ * If you’re looking for management of fully integrated cross-platform
+ software stacks, consider:
+
+ * *note buildout: 80.: primarily focused on the web development
+ community
+
+ * *note Spack: 81, *note Hashdist: 82, or *note conda: 83.:
+ primarily focused on the scientific community.
+
+ ---------- Footnotes ----------
+
+ (1) (1) There are some cases where you might choose to use
+‘easy_install’ (from *note setuptools: 2d.), e.g. if you need to
+install from *note Eggs: 7c. (which pip doesn’t support). For a
+detailed breakdown, see *note pip vs easy_install: 7d.
+
+ (2) (2) The acceptance of PEP 453
+(https://www.python.org/dev/peps/pep-0453) means that *note pip: 2b.
+will be available by default in most installations of Python 3.4 or
+later. See the rationale section
+(https://www.python.org/dev/peps/pep-0453#rationale) from PEP 453
+(https://www.python.org/dev/peps/pep-0453) as for why pip was chosen.
+
+ (3) (3) get-pip.py
+(https://pip.pypa.io/en/latest/installing/#get-pip) and *note
+virtualenv: 32. install *note wheel: 2e, whereas *note ensurepip: 7e.
+and *note venv: 7f. do not currently. Also, the common “python-pip”
+package that’s found in various linux distros, does not depend on
+“python-wheel” currently.
+
+ (4) https://docs.python.org/3/library/venv.html
+
+ (5) (4) Beginning with Python 3.4, ‘venv’ will create virtualenv
+environments with ‘pip’ installed, thereby making it an equal
+alternative to *note virtualenv: 32. However, using *note virtualenv:
+32. will still be recommended for users that need cross-version
+consistency.
+
+
+File: pythonpackagingguide.info, Node: Packaging tool recommendations, Next: Publishing platform migration, Prev: Installation tool recommendations, Up: Tool recommendations
+
+3.1.3 Packaging tool recommendations
+------------------------------------
+
+ * Use *note setuptools: 2d. to define projects and create *note
+ Source Distributions: 3d. (1) (2)
+
+ * Use the ‘bdist_wheel’ *note setuptools: 2d. extension available
+ from the *note wheel project: 2e. to create *note wheels: d. This
+ is especially beneficial, if your project contains binary
+ extensions.
+
+ * Use twine(3) for uploading distributions to *note PyPI: 39.
+
+ ---------- Footnotes ----------
+
+ (1) (5) Although you can use pure ‘distutils’ for many projects, it
+does not support defining dependencies on other projects and is missing
+several convenience utilities for automatically populating distribution
+metadata correctly that are provided by ‘setuptools’. Being outside the
+standard library, ‘setuptools’ also offers a more consistent feature set
+across different versions of Python, and (unlike ‘distutils’), recent
+versions of ‘setuptools’ support all of the modern metadata fields
+described in *note Core metadata specifications: 85.
+
+Even for projects that do choose to use ‘distutils’, when *note pip: 2b.
+installs such projects directly from source (rather than installing from
+a prebuilt *note wheel: d. file), it will actually build your project
+using *note setuptools: 2d. instead.
+
+ (2) (6) distribute (https://pypi.org/project/distribute) (a fork of
+setuptools) was merged back into *note setuptools: 2d. in June 2013,
+thereby making setuptools the default choice for packaging.
+
+ (3) https://pypi.org/project/twine
+
+
+File: pythonpackagingguide.info, Node: Publishing platform migration, Prev: Packaging tool recommendations, Up: Tool recommendations
+
+3.1.4 Publishing platform migration
+-----------------------------------
+
+The original Python Package Index implementation (previously hosted at
+pypi.python.org(1)) has been phased out in favour of an updated
+implementation hosted at pypi.org(2).
+
+See *note Migrating to PyPI.org: 87. for more information on the status
+of the migration, and what settings to change in your clients.
+
+__________________________________________________________________
+
+ ---------- Footnotes ----------
+
+ (1) https://pypi.python.org
+
+ (2) https://pypi.org
+
+
+File: pythonpackagingguide.info, Node: Installing packages using pip and virtual environments, Next: Installing stand alone command line tools, Prev: Tool recommendations, Up: Guides
+
+3.2 Installing packages using pip and virtual environments
+==========================================================
+
+This guide discusses how to install packages using *note pip: 2b. and a
+virtual environment manager: either *note venv: 7f. for Python 3 or
+*note virtualenv: 32. for Python 2. These are the lowest-level tools
+for managing Python packages and are recommended if higher-level tools
+do not suit your needs.
+
+ Note: This doc uses the term `package' to refer to a *note
+ Distribution Package: b. which is different from a *note Import
+ Package: a. that which is used to import modules in your Python
+ source code.
+
+* Menu:
+
+* Installing pip::
+* Installing virtualenv::
+* Creating a virtual environment::
+* Activating a virtual environment::
+* Leaving the virtual environment::
+* Installing packages::
+* Installing specific versions::
+* Installing extras::
+* Installing from source::
+* Installing from version control systems::
+* Installing from local archives: Installing from local archives<2>.
+* Using other package indexes::
+* Upgrading packages: Upgrading packages<2>.
+* Using requirements files::
+* Freezing dependencies::
+
+
+File: pythonpackagingguide.info, Node: Installing pip, Next: Installing virtualenv, Up: Installing packages using pip and virtual environments
+
+3.2.1 Installing pip
+--------------------
+
+*note pip: 2b. is the reference Python package manager. It’s used to
+install and update packages. You’ll need to make sure you have the
+latest version of pip installed.
+
+* Menu:
+
+* Windows::
+* Linux and macOS::
+
+
+File: pythonpackagingguide.info, Node: Windows, Next: Linux and macOS, Up: Installing pip
+
+3.2.1.1 Windows
+...............
+
+The Python installers for Windows include pip. You should be able to
+access pip using:
+
+ py -m pip --version
+ pip 9.0.1 from c:\python36\lib\site-packages (Python 3.6.1)
+
+You can make sure that pip is up-to-date by running:
+
+ py -m pip install --upgrade pip
+
+
+File: pythonpackagingguide.info, Node: Linux and macOS, Prev: Windows, Up: Installing pip
+
+3.2.1.2 Linux and macOS
+.......................
+
+Debian and most other distributions include a python-pip(1) package, if
+you want to use the Linux distribution-provided versions of pip see
+*note Installing pip/setuptools/wheel with Linux Package Managers: 2c.
+
+You can also install pip yourself to ensure you have the latest version.
+It’s recommended to use the system pip to bootstrap a user installation
+of pip:
+
+ python3 -m pip install --user --upgrade pip
+
+Afterwards, you should have the newest pip installed in your user site:
+
+ python3 -m pip --version
+ pip 9.0.1 from $HOME/.local/lib/python3.6/site-packages (python 3.6)
+
+ ---------- Footnotes ----------
+
+ (1) https://packages.debian.org/stable/python-pip
+
+
+File: pythonpackagingguide.info, Node: Installing virtualenv, Next: Creating a virtual environment, Prev: Installing pip, Up: Installing packages using pip and virtual environments
+
+3.2.2 Installing virtualenv
+---------------------------
+
+ Note: If you are using Python 3.3 or newer, the venv(1) module is
+ the preferred way to create and manage virtual environments. venv
+ is included in the Python standard library and requires no
+ additional installation. If you are using venv, you may skip this
+ section.
+
+*note virtualenv: 32. is used to manage Python packages for different
+projects. Using virtualenv allows you to avoid installing Python
+packages globally which could break system tools or other projects. You
+can install virtualenv using pip.
+
+On macOS and Linux:
+
+ python3 -m pip install --user virtualenv
+
+On Windows:
+
+ py -m pip install --user virtualenv
+
+ ---------- Footnotes ----------
+
+ (1) https://docs.python.org/3/library/venv.html#module-venv
+
+
+File: pythonpackagingguide.info, Node: Creating a virtual environment, Next: Activating a virtual environment, Prev: Installing virtualenv, Up: Installing packages using pip and virtual environments
+
+3.2.3 Creating a virtual environment
+------------------------------------
+
+*note venv: 7f. (for Python 3) and *note virtualenv: 32. (for Python 2)
+allow you to manage separate package installations for different
+projects. They essentially allow you to create a “virtual” isolated
+Python installation and install packages into that virtual installation.
+When you switch projects, you can simply create a new virtual
+environment and not have to worry about breaking the packages installed
+in the other environments. It is always recommended to use a virtual
+environment while developing Python applications.
+
+To create a virtual environment, go to your project’s directory and run
+venv. If you are using Python 2, replace ‘venv’ with ‘virtualenv’ in
+the below commands.
+
+On macOS and Linux:
+
+ python3 -m venv env
+
+On Windows:
+
+ py -m venv env
+
+The second argument is the location to create the virtual environment.
+Generally, you can just create this in your project and call it ‘env’.
+
+venv will create a virtual Python installation in the ‘env’ folder.
+
+ Note: You should exclude your virtual environment directory from
+ your version control system using ‘.gitignore’ or similar.
+
+
+File: pythonpackagingguide.info, Node: Activating a virtual environment, Next: Leaving the virtual environment, Prev: Creating a virtual environment, Up: Installing packages using pip and virtual environments
+
+3.2.4 Activating a virtual environment
+--------------------------------------
+
+Before you can start installing or using packages in your virtual
+environment you’ll need to `activate' it. Activating a virtual
+environment will put the virtual environment-specific ‘python’ and ‘pip’
+executables into your shell’s ‘PATH’.
+
+On macOS and Linux:
+
+ source env/bin/activate
+
+On Windows:
+
+ .\env\Scripts\activate
+
+You can confirm you’re in the virtual environment by checking the
+location of your Python interpreter, it should point to the ‘env’
+directory.
+
+On macOS and Linux:
+
+ which python
+ .../env/bin/python
+
+On Windows:
+
+ where python
+ .../env/bin/python.exe
+
+As long as your virtual environment is activated pip will install
+packages into that specific environment and you’ll be able to import and
+use packages in your Python application.
+
+
+File: pythonpackagingguide.info, Node: Leaving the virtual environment, Next: Installing packages, Prev: Activating a virtual environment, Up: Installing packages using pip and virtual environments
+
+3.2.5 Leaving the virtual environment
+-------------------------------------
+
+If you want to switch projects or otherwise leave your virtual
+environment, simply run:
+
+ deactivate
+
+If you want to re-enter the virtual environment just follow the same
+instructions above about activating a virtual environment. There’s no
+need to re-create the virtual environment.
+
+
+File: pythonpackagingguide.info, Node: Installing packages, Next: Installing specific versions, Prev: Leaving the virtual environment, Up: Installing packages using pip and virtual environments
+
+3.2.6 Installing packages
+-------------------------
+
+Now that you’re in your virtual environment you can install packages.
+Let’s install the Requests(1) library from the *note Python Package
+Index (PyPI): 39.:
+
+ pip install requests
+
+pip should download requests and all of its dependencies and install
+them:
+
+ Collecting requests
+ Using cached requests-2.18.4-py2.py3-none-any.whl
+ Collecting chardet<3.1.0,>=3.0.2 (from requests)
+ Using cached chardet-3.0.4-py2.py3-none-any.whl
+ Collecting urllib3<1.23,>=1.21.1 (from requests)
+ Using cached urllib3-1.22-py2.py3-none-any.whl
+ Collecting certifi>=2017.4.17 (from requests)
+ Using cached certifi-2017.7.27.1-py2.py3-none-any.whl
+ Collecting idna<2.7,>=2.5 (from requests)
+ Using cached idna-2.6-py2.py3-none-any.whl
+ Installing collected packages: chardet, urllib3, certifi, idna, requests
+ Successfully installed certifi-2017.7.27.1 chardet-3.0.4 idna-2.6 requests-2.18.4 urllib3-1.22
+
+ ---------- Footnotes ----------
+
+ (1) https://pypi.org/project/requests/
+
+
+File: pythonpackagingguide.info, Node: Installing specific versions, Next: Installing extras, Prev: Installing packages, Up: Installing packages using pip and virtual environments
+
+3.2.7 Installing specific versions
+----------------------------------
+
+pip allows you to specify which version of a package to install using
+*note version specifiers: 3b. For example, to install a specific
+version of ‘requests’:
+
+ pip install requests==2.18.4
+
+To install the latest ‘2.x’ release of requests:
+
+ pip install requests>=2.0.0,<3.0.0
+
+To install pre-release versions of packages, use the ‘--pre’ flag:
+
+ pip install --pre requests
+
+
+File: pythonpackagingguide.info, Node: Installing extras, Next: Installing from source, Prev: Installing specific versions, Up: Installing packages using pip and virtual environments
+
+3.2.8 Installing extras
+-----------------------
+
+Some packages have optional extras(1). You can tell pip to install
+these by specifying the extra in brackets:
+
+ pip install requests[security]
+
+ ---------- Footnotes ----------
+
+ (1)
+https://setuptools.readthedocs.io/en/latest/setuptools.html#declaring-extras-optional-features-with-their-own-dependencies
+
+
+File: pythonpackagingguide.info, Node: Installing from source, Next: Installing from version control systems, Prev: Installing extras, Up: Installing packages using pip and virtual environments
+
+3.2.9 Installing from source
+----------------------------
+
+pip can install a package directly from source, for example:
+
+ cd google-auth
+ pip install .
+
+Additionally, pip can install packages from source in development
+mode(1), meaning that changes to the source directory will immediately
+affect the installed package without needing to re-install:
+
+ pip install --editable .
+
+ ---------- Footnotes ----------
+
+ (1)
+https://setuptools.readthedocs.io/en/latest/setuptools.html#development-mode
+
+
+File: pythonpackagingguide.info, Node: Installing from version control systems, Next: Installing from local archives<2>, Prev: Installing from source, Up: Installing packages using pip and virtual environments
+
+3.2.10 Installing from version control systems
+----------------------------------------------
+
+pip can install packages directly from their version control system.
+For example, you can install directly from a git repository:
+
+ git+https://github.com/GoogleCloudPlatform/google-auth-library-python.git#egg=google-auth
+
+For more information on supported version control systems and syntax,
+see pip’s documentation on VCS Support(1).
+
+ ---------- Footnotes ----------
+
+ (1) https://pip.pypa.io/en/latest/reference/pip_install/#vcs-support
+
+
+File: pythonpackagingguide.info, Node: Installing from local archives<2>, Next: Using other package indexes, Prev: Installing from version control systems, Up: Installing packages using pip and virtual environments
+
+3.2.11 Installing from local archives
+-------------------------------------
+
+If you have a local copy of a *note Distribution Package: b.’s archive
+(a zip, wheel, or tar file) you can install it directly with pip:
+
+ pip install requests-2.18.4.tar.gz
+
+If you have a directory containing archives of multiple packages, you
+can tell pip to look for packages there and not to use the *note Python
+Package Index (PyPI): 39. at all:
+
+ pip install --no-index --find-links=/local/dir/ requests
+
+This is useful if you are installing packages on a system with limited
+connectivity or if you want to strictly control the origin of
+distribution packages.
+
+
+File: pythonpackagingguide.info, Node: Using other package indexes, Next: Upgrading packages<2>, Prev: Installing from local archives<2>, Up: Installing packages using pip and virtual environments
+
+3.2.12 Using other package indexes
+----------------------------------
+
+If you want to download packages from a different index than the *note
+Python Package Index (PyPI): 39, you can use the ‘--index-url’ flag:
+
+ pip install --index-url http://index.example.com/simple/ SomeProject
+
+If you want to allow packages from both the *note Python Package Index
+(PyPI): 39. and a separate index, you can use the ‘--extra-index-url’
+flag instead:
+
+ pip install --extra-index-url http://index.example.com/simple/ SomeProject
+
+
+File: pythonpackagingguide.info, Node: Upgrading packages<2>, Next: Using requirements files, Prev: Using other package indexes, Up: Installing packages using pip and virtual environments
+
+3.2.13 Upgrading packages
+-------------------------
+
+pip can upgrade packages in-place using the ‘--upgrade’ flag. For
+example, to install the latest version of ‘requests’ and all of its
+dependencies:
+
+ pip install --upgrade requests
+
+
+File: pythonpackagingguide.info, Node: Using requirements files, Next: Freezing dependencies, Prev: Upgrading packages<2>, Up: Installing packages using pip and virtual environments
+
+3.2.14 Using requirements files
+-------------------------------
+
+Instead of installing packages individually, pip allows you to declare
+all dependencies in a Requirements File(1). For example you could
+create a ‘requirements.txt’ file containing:
+
+ requests==2.18.4
+ google-auth==1.1.0
+
+And tell pip to install all of the packages in this file using the ‘-r’
+flag:
+
+ pip install -r requirements.txt
+
+ ---------- Footnotes ----------
+
+ (1) https://pip.pypa.io/en/latest/user_guide/#requirements-files
+
+
+File: pythonpackagingguide.info, Node: Freezing dependencies, Prev: Using requirements files, Up: Installing packages using pip and virtual environments
+
+3.2.15 Freezing dependencies
+----------------------------
+
+Pip can export a list of all installed packages and their versions using
+the ‘freeze’ command:
+
+ pip freeze
+
+Which will output a list of package specifiers such as:
+
+ cachetools==2.0.1
+ certifi==2017.7.27.1
+ chardet==3.0.4
+ google-auth==1.1.1
+ idna==2.6
+ pyasn1==0.3.6
+ pyasn1-modules==0.1.4
+ requests==2.18.4
+ rsa==3.4.2
+ six==1.11.0
+ urllib3==1.22
+
+This is useful for creating Requirements Files(1) that can re-create the
+exact versions of all packages installed in an environment.
+
+ ---------- Footnotes ----------
+
+ (1) https://pip.pypa.io/en/latest/user_guide/#requirements-files
+
+
+File: pythonpackagingguide.info, Node: Installing stand alone command line tools, Next: Installing pip/setuptools/wheel with Linux Package Managers, Prev: Installing packages using pip and virtual environments, Up: Guides
+
+3.3 Installing stand alone command line tools
+=============================================
+
+Many packages have command line entry points. Examples of this type of
+application are mypy(1), flake8(2), pipenv(3),and black(4).
+
+Usually you want to be able to access these from anywhere, but
+installing packages and their dependencies to the same global
+environment can cause version conflicts and break dependencies the
+operating system has on Python packages.
+
+pipx(5) solves this by creating a virtual environment for each package,
+while also ensuring that package’s applications are accessible through a
+directory that is on your ‘$PATH’. This allows each package to be
+upgraded or uninstalled without causing conflicts with other packages,
+and allows you to safely run the program from anywhere.
+
+ Note: pipx only works with Python 3.6+.
+
+‘pipx’ is installed with ‘pip’:
+
+ $ python3 -m pip install --user pipx
+ $ python3 -m pipx ensurepath # ensures the path of the CLI application directory is on your $PATH
+
+ Note: You may need to restart your terminal for the path updates to
+ take effect.
+
+Now you can install packages with ‘pipx install’ and access the
+package’s entry point(s) from anywhere.
+
+ $ pipx install PACKAGE
+ $ ENTRYPOINT_OF_PACKAGE [ARGS]
+
+For example
+
+ $ pipx install cowsay
+ installed package cowsay 2.0, Python 3.6.2+
+ These binaries are now globally available
+ - cowsay
+ done! ✨ 🌟 ✨
+ $ cowsay moo
+ ___
+ < moo >
+ ===
+ \
+ \
+ ^__^
+ (oo)\_______
+ (__)\ )\/ ||----w |
+ || ||
+
+To see a list of packages installed with pipx and which CLI applications
+are available, use ‘pipx list’.
+
+ $ pipx list
+ venvs are in /Users/user/.local/pipx/venvs
+ symlinks to binaries are in /Users/user/.local/bin
+ package black 18.9b0, Python 3.6.2+
+ - black
+ - blackd
+ package cowsay 2.0, Python 3.6.2+
+ - cowsay
+ package mypy 0.660, Python 3.6.2+
+ - dmypy
+ - mypy
+ - stubgen
+ package nox 2018.10.17, Python 3.6.2+
+ - nox
+ - tox-to-nox
+
+To upgrade or uninstall the package
+
+ $ pipx upgrade PACKAGE
+ $ pipx uninstall PACKAGE
+
+‘pipx’ can be upgraded or uninstalled with pip
+
+ $ pip install -U pipx
+ $ pip uninstall pipx
+
+‘pipx’ also allows you to install and run the latest version of a cli
+tool in a temporary, ephemeral environment.
+
+ $ pipx run PACKAGE [ARGS]
+
+For example
+
+ $ pipx run cowsay moooo
+
+To see the full list of commands ‘pipx’ offers, run
+
+ $ pipx --help
+
+You can learn more about ‘pipx’ at its homepage,
+‘https://github.com/pipxproject/pipx’.
+
+ ---------- Footnotes ----------
+
+ (1) https://github.com/python/mypy
+
+ (2) https://github.com/PyCQA/flake8
+
+ (3) https://github.com/pypa/pipenv
+
+ (4) https://github.com/ambv/black
+
+ (5) https://github.com/pipxproject/pipx
+
+
+File: pythonpackagingguide.info, Node: Installing pip/setuptools/wheel with Linux Package Managers, Next: Installing scientific packages, Prev: Installing stand alone command line tools, Up: Guides
+
+3.4 Installing pip/setuptools/wheel with Linux Package Managers
+===============================================================
+
+
+Page Status: Incomplete
+
+
+Last Reviewed: 2015-09-17
+
+This section covers how to install *note pip: 2b, *note setuptools: 2d,
+and *note wheel: 2e. using Linux package managers.
+
+If you’re using a Python that was downloaded from python.org(1), then
+this section does not apply. See the *note Requirements for Installing
+Packages: 26. section instead.
+
+Note that it’s common for the versions of *note pip: 2b, *note
+setuptools: 2d, and *note wheel: 2e. supported by a specific Linux
+Distribution to be outdated by the time it’s released to the public, and
+updates generally only occur for security reasons, not for feature
+updates. For certain Distributions, there are additional repositories
+that can be enabled to provide newer versions. The repositories we know
+about are explained below.
+
+Also note that it’s somewhat common for Distributions to apply patches
+for the sake of security and normalization to their own standards. In
+some cases, this can lead to bugs or unexpected behaviors that vary from
+the original unpatched versions. When this is known, we will make note
+of it below.
+
+* Menu:
+
+* Fedora::
+* CentOS/RHEL::
+* openSUSE::
+* Debian/Ubuntu::
+* Arch Linux::
+
+ ---------- Footnotes ----------
+
+ (1) https://www.python.org
+
+
+File: pythonpackagingguide.info, Node: Fedora, Next: CentOS/RHEL, Up: Installing pip/setuptools/wheel with Linux Package Managers
+
+3.4.1 Fedora
+------------
+
+ * Fedora 21:
+
+ * Python 2:
+
+ sudo yum upgrade python-setuptools
+ sudo yum install python-pip python-wheel
+
+ * Python 3: ‘sudo yum install python3 python3-wheel’
+
+ * Fedora 22:
+
+ * Python 2:
+
+ sudo dnf upgrade python-setuptools
+ sudo dnf install python-pip python-wheel
+
+ * Python 3: ‘sudo dnf install python3 python3-wheel’
+
+To get newer versions of pip, setuptools, and wheel for Python 2, you
+can enable the PyPA Copr Repo(1) using the Copr Repo instructions(2),
+and then run:
+
+ sudo yum|dnf upgrade python-setuptools
+ sudo yum|dnf install python-pip python-wheel
+
+ ---------- Footnotes ----------
+
+ (1) https://copr.fedoraproject.org/coprs/pypa/pypa/
+
+ (2) https://fedorahosted.org/copr/wiki/HowToEnableRepo
+
+
+File: pythonpackagingguide.info, Node: CentOS/RHEL, Next: openSUSE, Prev: Fedora, Up: Installing pip/setuptools/wheel with Linux Package Managers
+
+3.4.2 CentOS/RHEL
+-----------------
+
+CentOS and RHEL don’t offer *note pip: 2b. or *note wheel: 2e. in their
+core repositories, although *note setuptools: 2d. is installed by
+default.
+
+To install pip and wheel for the system Python, there are two options:
+
+ 1. Enable the EPEL repository(1) using these instructions(2). On EPEL
+ 6 and EPEL7, you can install pip like so:
+
+ sudo yum install python-pip
+
+ On EPEL 7 (but not EPEL 6), you can install wheel like so:
+
+ sudo yum install python-wheel
+
+ Since EPEL only offers extra, non-conflicting packages, EPEL does
+ not offer setuptools, since it’s in the core repository.
+
+ 2. Enable the PyPA Copr Repo(3) using these instructions(4) (5). You
+ can install pip and wheel like so:
+
+ sudo yum install python-pip python-wheel
+
+ To additionally upgrade setuptools, run:
+
+ sudo yum upgrade python-setuptools
+
+To install pip, wheel, and setuptools, in a parallel, non-system
+environment (using yum) then there are two options:
+
+ 1. Use the “Sofware Collections” feature to enable a parallel
+ collection that includes pip, setuptools, and wheel.
+
+ * For Redhat, see here:
+ ‘http://developers.redhat.com/products/softwarecollections/overview/’
+
+ * For CentOS, see here:
+ ‘https://www.softwarecollections.org/en/’
+
+ Be aware that collections may not contain the most recent versions.
+
+ 2. Enable the IUS repository(6) and install one of the
+ parallel-installable(7) Pythons, along with pip, setuptools, and
+ wheel, which are kept fairly up to date.
+
+ For example, for Python 3.4 on CentOS7/RHEL7:
+
+ sudo yum install python34u python34u-wheel
+
+ ---------- Footnotes ----------
+
+ (1) https://fedoraproject.org/wiki/EPEL
+
+ (2)
+https://fedoraproject.org/wiki/EPEL#How_can_I_use_these_extra_packages.3F
+
+ (3) https://copr.fedoraproject.org/coprs/pypa/pypa/
+
+ (4) https://fedorahosted.org/copr/wiki/HowToEnableRepo
+
+ (5) (1) Currently, there is no “copr” yum plugin available for
+CentOS/RHEL, so the only option is to manually place the repo files as
+described.
+
+ (6) https://ius.io/GettingStarted/
+
+ (7) https://ius.io/SafeRepo/#parallel-installable-package
+
+
+File: pythonpackagingguide.info, Node: openSUSE, Next: Debian/Ubuntu, Prev: CentOS/RHEL, Up: Installing pip/setuptools/wheel with Linux Package Managers
+
+3.4.3 openSUSE
+--------------
+
+ * Python 2:
+
+ sudo zypper install python-pip python-setuptools python-wheel
+
+ * Python 3:
+
+ sudo zypper install python3-pip python3-setuptools python3-wheel
+
+
+File: pythonpackagingguide.info, Node: Debian/Ubuntu, Next: Arch Linux, Prev: openSUSE, Up: Installing pip/setuptools/wheel with Linux Package Managers
+
+3.4.4 Debian/Ubuntu
+-------------------
+
+ * Python 2:
+
+ sudo apt install python-pip
+
+ * Python 3:
+
+ sudo apt install python3-venv python3-pip
+
+ Warning: Recent Debian/Ubuntu versions have modified pip to use the
+ "User Scheme"(1) by default, which is a significant behavior change
+ that can be surprising to some users.
+
+ ---------- Footnotes ----------
+
+ (1) https://pip.pypa.io/en/stable/user_guide/#user-installs
+
+
+File: pythonpackagingguide.info, Node: Arch Linux, Prev: Debian/Ubuntu, Up: Installing pip/setuptools/wheel with Linux Package Managers
+
+3.4.5 Arch Linux
+----------------
+
+ * Python 2:
+
+ sudo pacman -S python2-pip
+
+ * Python 3:
+
+ sudo pacman -S python-pip
+
+__________________________________________________________________
+
+
+File: pythonpackagingguide.info, Node: Installing scientific packages, Next: Multi-version installs, Prev: Installing pip/setuptools/wheel with Linux Package Managers, Up: Guides
+
+3.5 Installing scientific packages
+==================================
+
+Scientific software tends to have more complex dependencies than most,
+and it will often have multiple build options to take advantage of
+different kinds of hardware, or to interoperate with different pieces of
+external software.
+
+In particular, NumPy(1), which provides the basis for most of the
+software in the scientific Python stack(2) can be configured to
+interoperate with different FORTRAN libraries, and can take advantage of
+different levels of vectorised instructions available in modern CPUs.
+
+Starting with version 1.10.4 of NumPy and version 1.0.0 of SciPy,
+pre-built 32-bit and 64-bit binaries in the ‘wheel’ format are available
+for all major operating systems (Windows, macOS, and Linux) on PyPI.
+Note, however, that on Windows, NumPy binaries are linked against the
+ATLAS(3) BLAS/LAPACK library, restricted to SSE2 instructions, so they
+may not provide optimal linear algebra performance.
+
+There are a number of alternative options for obtaining scientific
+Python libraries (or any other Python libraries that require a
+compilation environment to install from source and don’t provide
+pre-built wheel files on PyPI).
+
+* Menu:
+
+* Building from source::
+* Linux distribution packages::
+* Windows installers::
+* macOS installers and package managers::
+* SciPy distributions::
+* Spack::
+* The conda cross-platform package manager::
+
+ ---------- Footnotes ----------
+
+ (1) http://www.numpy.org/
+
+ (2) http://www.scipy.org/stackspec.html#stackspec
+
+ (3) http://www.netlib.org/atlas/
+
+
+File: pythonpackagingguide.info, Node: Building from source, Next: Linux distribution packages, Up: Installing scientific packages
+
+3.5.1 Building from source
+--------------------------
+
+The same complexity which makes it difficult to distribute NumPy (and
+many of the projects that depend on it) as wheel files also make them
+difficult to build from source yourself. However, for intrepid folks
+that are willing to spend the time wrangling compilers and linkers for
+both C and FORTRAN, building from source is always an option.
+
+
+File: pythonpackagingguide.info, Node: Linux distribution packages, Next: Windows installers, Prev: Building from source, Up: Installing scientific packages
+
+3.5.2 Linux distribution packages
+---------------------------------
+
+For Linux users, the system package manager will often have pre-compiled
+versions of various pieces of scientific software, including NumPy and
+other parts of the scientific Python stack.
+
+If using versions which may be several months old is acceptable, then
+this is likely to be a good option (just make sure to allow access to
+distributions installed into the system Python when using virtual
+environments).
+
+
+File: pythonpackagingguide.info, Node: Windows installers, Next: macOS installers and package managers, Prev: Linux distribution packages, Up: Installing scientific packages
+
+3.5.3 Windows installers
+------------------------
+
+Many Python projects that don’t (or can’t) currently publish wheel files
+at least publish Windows installers, either on PyPI or on their project
+download page. Using these installers allows users to avoid the need to
+set up a suitable environment to build extensions locally.
+
+The extensions provided in these installers are typically compatible
+with the CPython Windows installers published on python.org.
+
+For projects which don’t provide their own Windows installers (and even
+some which do), Christoph Gohlke at the University of California
+provides a collection of Windows installers(1). Many Python users on
+Windows have reported a positive experience with these prebuilt
+versions.
+
+As with Linux system packages, the Windows installers will only install
+into a system Python installation - they do not support installation in
+virtual environments. Allowing access to distributions installed into
+the system Python when using virtual environments is a common approach
+to working around this limitation.
+
+The *note Wheel: d. project also provides a ‘wheel convert’ subcommand
+that can convert a Windows ‘bdist_wininst’ installer to a wheel.
+
+ ---------- Footnotes ----------
+
+ (1) http://www.lfd.uci.edu/~gohlke/pythonlibs/
+
+
+File: pythonpackagingguide.info, Node: macOS installers and package managers, Next: SciPy distributions, Prev: Windows installers, Up: Installing scientific packages
+
+3.5.4 macOS installers and package managers
+-------------------------------------------
+
+Similar to the situation on Windows, many projects (including NumPy)
+publish macOS installers that are compatible with the macOS CPython
+binaries published on python.org.
+
+macOS users also have access to Linux distribution style package
+managers such as ‘MacPorts’. The SciPy site has more details on using
+MacPorts to install the scientific Python stack(1)
+
+ ---------- Footnotes ----------
+
+ (1) http://www.scipy.org/install.html#mac-packages
+
+
+File: pythonpackagingguide.info, Node: SciPy distributions, Next: Spack, Prev: macOS installers and package managers, Up: Installing scientific packages
+
+3.5.5 SciPy distributions
+-------------------------
+
+The SciPy site lists several distributions(1) that provide the full
+SciPy stack to end users in an easy to use and update format.
+
+Some of these distributions may not be compatible with the standard
+‘pip’ and ‘virtualenv’ based toolchain.
+
+ ---------- Footnotes ----------
+
+ (1) http://www.scipy.org/install.html
+
+
+File: pythonpackagingguide.info, Node: Spack, Next: The conda cross-platform package manager, Prev: SciPy distributions, Up: Installing scientific packages
+
+3.5.6 Spack
+-----------
+
+Spack(1) is a flexible package manager designed to support multiple
+versions, configurations, platforms, and compilers. It was built to
+support the needs of large supercomputing centers and scientific
+application teams, who must often build software many different ways.
+Spack is not limited to Python; it can install packages for ‘C’, ‘C++’,
+‘Fortran’, ‘R’, and other languages. It is non-destructive; installing
+a new version of one package does not break existing installations, so
+many configurations can coexist on the same system.
+
+Spack offers a simple but powerful syntax that allows users to specify
+versions and configuration options concisely. Package files are written
+in pure Python, and they are templated so that it is easy to swap
+compilers, dependency implementations (like MPI), versions, and build
+options with a single package file. Spack also generates `module' files
+so that packages can be loaded and unloaded from the user’s environment.
+
+ ---------- Footnotes ----------
+
+ (1) https://github.com/LLNL/spack/
+
+
+File: pythonpackagingguide.info, Node: The conda cross-platform package manager, Prev: Spack, Up: Installing scientific packages
+
+3.5.7 The conda cross-platform package manager
+----------------------------------------------
+
+Anaconda(1) is a Python distribution published by Anaconda, Inc. It is
+a stable collection of Open Source packages for big data and scientific
+use. As of the 5.0 release of Anaconda, about 200 packages are
+installed by default, and a total of 400-500 can be installed and
+updated from the Anaconda repository.
+
+‘conda’ is an open source (BSD licensed) package management system and
+environment management system included in Anaconda that allows users to
+install multiple versions of binary software packages and their
+dependencies, and easily switch between them. It is a cross-platform
+tool working on Windows, macOS, and Linux. Conda can be used to package
+up and distribute all kinds of packages, it is not limited to just
+Python packages. It has full support for native virtual environments.
+Conda makes environments first-class citizens, making it easy to create
+independent environments even for C libraries. It is written in Python,
+but is Python-agnostic. Conda manages Python itself as a package, so
+that ‘conda update python’ is possible, in contrast to pip, which only
+manages Python packages. Conda is available in Anaconda and Miniconda
+(an easy-to-install download with just Python and conda).
+
+ ---------- Footnotes ----------
+
+ (1) https://www.anaconda.com/download/
+
+
+File: pythonpackagingguide.info, Node: Multi-version installs, Next: Packaging and distributing projects, Prev: Installing scientific packages, Up: Guides
+
+3.6 Multi-version installs
+==========================
+
+easy_install allows simultaneous installation of different versions of
+the same project into a single environment shared by multiple programs
+which must ‘require’ the appropriate version of the project at run time
+(using ‘pkg_resources’).
+
+For many use cases, virtual environments address this need without the
+complication of the ‘require’ directive. However, the advantage of
+parallel installations within the same environment is that it works for
+an environment shared by multiple applications, such as the system
+Python in a Linux distribution.
+
+The major limitation of ‘pkg_resources’ based parallel installation is
+that as soon as you import ‘pkg_resources’ it locks in the `default'
+version of everything which is already available on sys.path. This can
+cause problems, since ‘setuptools’ created command line scripts use
+‘pkg_resources’ to find the entry point to execute. This means that,
+for example, you can’t use ‘require’ tests invoked through ‘nose’ or a
+WSGI application invoked through ‘gunicorn’ if your application needs a
+non-default version of anything that is available on the standard
+‘sys.path’ - the script wrapper for the main application will lock in
+the version that is available by default, so the subsequent ‘require’
+call in your own code fails with a spurious version conflict.
+
+This can be worked around by setting all dependencies in
+‘__main__.__requires__’ before importing ‘pkg_resources’ for the first
+time, but that approach does mean that standard command line invocations
+of the affected tools can’t be used - it’s necessary to write a custom
+wrapper script or use ‘python -c '<commmand>'’ to invoke the
+application’s main entry point directly.
+
+Refer to the pkg_resources documentation(1) for more details.
+
+ ---------- Footnotes ----------
+
+ (1)
+https://setuptools.readthedocs.io/en/latest/pkg_resources.html#workingset-objects
+
+
+File: pythonpackagingguide.info, Node: Packaging and distributing projects, Next: Including files in source distributions with MANIFEST in, Prev: Multi-version installs, Up: Guides
+
+3.7 Packaging and distributing projects
+=======================================
+
+This section covers the basics of how to configure, package and
+distribute your own Python projects. It assumes that you are already
+familiar with the contents of the *note Installing Packages: 23. page.
+
+The section does `not' aim to cover best practices for Python project
+development as a whole. For example, it does not provide guidance or
+tool recommendations for version control, documentation, or testing.
+
+For more reference material, see Building and Distributing Packages(1)
+in the *note setuptools: 2d. docs, but note that some advisory content
+there may be outdated. In the event of conflicts, prefer the advice in
+the Python Packaging User Guide.
+
+* Menu:
+
+* Requirements for packaging and distributing::
+* Configuring your project::
+* Working in “development mode”::
+* Packaging your project::
+* Uploading your Project to PyPI::
+
+ ---------- Footnotes ----------
+
+ (1) https://setuptools.readthedocs.io/en/latest/setuptools.html
+
+
+File: pythonpackagingguide.info, Node: Requirements for packaging and distributing, Next: Configuring your project, Up: Packaging and distributing projects
+
+3.7.1 Requirements for packaging and distributing
+-------------------------------------------------
+
+ 1. First, make sure you have already fulfilled the *note requirements
+ for installing packages: 26.
+
+ 2. Install “twine” (1):
+
+ pip install twine
+
+ You’ll need this to upload your project *note distributions: b. to
+ *note PyPI: 39. (see *note below: b8.).
+
+ ---------- Footnotes ----------
+
+ (1) (1) Depending on your platform, this may require root or
+Administrator access. *note pip: 2b. is currently considering changing
+this by making user installs the default behavior
+(https://github.com/pypa/pip/issues/1668).
+
+
+File: pythonpackagingguide.info, Node: Configuring your project, Next: Working in “development mode”, Prev: Requirements for packaging and distributing, Up: Packaging and distributing projects
+
+3.7.2 Configuring your project
+------------------------------
+
+* Menu:
+
+* Initial files::
+* setup() args: setup args.
+* Choosing a versioning scheme::
+
+
+File: pythonpackagingguide.info, Node: Initial files, Next: setup args, Up: Configuring your project
+
+3.7.2.1 Initial files
+.....................
+
+* Menu:
+
+* setup.py: setup py.
+* setup.cfg: setup cfg.
+* README.rst / README.md: README rst / README md.
+* MANIFEST.in: MANIFEST in.
+* LICENSE.txt: LICENSE txt.
+* <your package>::
+
+
+File: pythonpackagingguide.info, Node: setup py, Next: setup cfg, Up: Initial files
+
+3.7.2.2 setup.py
+................
+
+The most important file is ‘setup.py’ which exists at the root of your
+project directory. For an example, see the setup.py(1) in the PyPA
+sample project(2).
+
+‘setup.py’ serves two primary functions:
+
+ 1. It’s the file where various aspects of your project are configured.
+ The primary feature of ‘setup.py’ is that it contains a global
+ ‘setup()’ function. The keyword arguments to this function are how
+ specific details of your project are defined. The most relevant
+ arguments are explained in *note the section below: bc.
+
+ 2. It’s the command line interface for running various commands that
+ relate to packaging tasks. To get a listing of available commands,
+ run ‘python setup.py --help-commands’.
+
+ ---------- Footnotes ----------
+
+ (1) https://github.com/pypa/sampleproject/blob/master/setup.py
+
+ (2) https://github.com/pypa/sampleproject
+
+
+File: pythonpackagingguide.info, Node: setup cfg, Next: README rst / README md, Prev: setup py, Up: Initial files
+
+3.7.2.3 setup.cfg
+.................
+
+‘setup.cfg’ is an ini file that contains option defaults for ‘setup.py’
+commands. For an example, see the setup.cfg(1) in the PyPA sample
+project(2).
+
+ ---------- Footnotes ----------
+
+ (1) https://github.com/pypa/sampleproject/blob/master/setup.cfg
+
+ (2) https://github.com/pypa/sampleproject
+
+
+File: pythonpackagingguide.info, Node: README rst / README md, Next: MANIFEST in, Prev: setup cfg, Up: Initial files
+
+3.7.2.4 README.rst / README.md
+..............................
+
+All projects should contain a readme file that covers the goal of the
+project. The most common format is reStructuredText(1) with an “rst”
+extension, although this is not a requirement; multiple variants of
+Markdown(2) are supported as well (look at ‘setup()’’s *note
+long_description_content_type: bf. argument).
+
+For an example, see README.md(3) from the PyPA sample project(4).
+
+ Note: Projects using *note setuptools: 2d. 0.6.27+ have standard
+ readme files (‘README.rst’, ‘README.txt’, or ‘README’) included in
+ source distributions by default. The built-in *note distutils: c0.
+ library adopts this behavior beginning in Python 3.7.
+ Additionally, *note setuptools: 2d. 36.4.0+ will include a
+ ‘README.md’ if found. If you are using setuptools, you don’t need
+ to list your readme file in ‘MANIFEST.in’. Otherwise, include it
+ to be explicit.
+
+ ---------- Footnotes ----------
+
+ (1) http://docutils.sourceforge.net/rst.html
+
+ (2) https://daringfireball.net/projects/markdown/
+
+ (3) https://github.com/pypa/sampleproject/blob/master/README.md
+
+ (4) https://github.com/pypa/sampleproject
+
+
+File: pythonpackagingguide.info, Node: MANIFEST in, Next: LICENSE txt, Prev: README rst / README md, Up: Initial files
+
+3.7.2.5 MANIFEST.in
+...................
+
+A ‘MANIFEST.in’ is needed when you need to package additional files that
+are not automatically included in a source distribution. For details on
+writing a ‘MANIFEST.in’ file, including a list of what’s included by
+default, see “*note Including files in source distributions with
+MANIFEST.in: c2.”.
+
+For an example, see the MANIFEST.in(1) from the PyPA sample project(2).
+
+ Note: ‘MANIFEST.in’ does not affect binary distributions such as
+ wheels.
+
+ ---------- Footnotes ----------
+
+ (1) https://github.com/pypa/sampleproject/blob/master/MANIFEST.in
+
+ (2) https://github.com/pypa/sampleproject
+
+
+File: pythonpackagingguide.info, Node: LICENSE txt, Next: <your package>, Prev: MANIFEST in, Up: Initial files
+
+3.7.2.6 LICENSE.txt
+...................
+
+Every package should include a license file detailing the terms of
+distribution. In many jurisdictions, packages without an explicit
+license can not be legally used or distributed by anyone other than the
+copyright holder. If you’re unsure which license to choose, you can use
+resources such as GitHub’s Choose a License(1) or consult a lawyer.
+
+For an example, see the LICENSE.txt(2) from the PyPA sample project(3).
+
+ ---------- Footnotes ----------
+
+ (1) https://choosealicense.com/
+
+ (2) https://github.com/pypa/sampleproject/blob/master/LICENSE.txt
+
+ (3) https://github.com/pypa/sampleproject
+
+
+File: pythonpackagingguide.info, Node: <your package>, Prev: LICENSE txt, Up: Initial files
+
+3.7.2.7 <your package>
+......................
+
+Although it’s not required, the most common practice is to include your
+Python modules and packages under a single top-level package that has
+the same *note name: c5. as your project, or something very close.
+
+For an example, see the sample(1) package that’s included in the PyPA
+sample project(2).
+
+ ---------- Footnotes ----------
+
+ (1) https://github.com/pypa/sampleproject/tree/master/src/sample
+
+ (2) https://github.com/pypa/sampleproject
+
+
+File: pythonpackagingguide.info, Node: setup args, Next: Choosing a versioning scheme, Prev: Initial files, Up: Configuring your project
+
+3.7.2.8 setup() args
+....................
+
+As mentioned above, the primary feature of ‘setup.py’ is that it
+contains a global ‘setup()’ function. The keyword arguments to this
+function are how specific details of your project are defined.
+
+The most relevant arguments are explained below. Most of the snippets
+given are taken from the setup.py(1) contained in the PyPA sample
+project(2).
+
+* Menu:
+
+* name::
+* version::
+* description::
+* url::
+* author::
+* license::
+* classifiers::
+* keywords::
+* project_urls::
+* packages::
+* py_modules::
+* install_requires::
+* python_requires::
+* package_data::
+* data_files::
+* scripts::
+* entry_points::
+
+ ---------- Footnotes ----------
+
+ (1) https://github.com/pypa/sampleproject/blob/master/setup.py
+
+ (2) https://github.com/pypa/sampleproject
+
+
+File: pythonpackagingguide.info, Node: name, Next: version, Up: setup args
+
+3.7.2.9 name
+............
+
+ name='sample',
+
+This is the name of your project, determining how your project is listed
+on *note PyPI: 39. Per PEP 508(1), valid project names must:
+
+ - Consist only of ASCII letters, digits, underscores (‘_’), hyphens
+ (‘-’), and/or periods (‘.’), and
+
+ - Start & end with an ASCII letter or digit.
+
+Comparison of project names is case insensitive and treats
+arbitrarily-long runs of underscores, hyphens, and/or periods as equal.
+For example, if you register a project named ‘cool-stuff’, users will be
+able to download it or declare a dependency on it using any of the
+following spellings:
+
+ Cool-Stuff
+ cool.stuff
+ COOL_STUFF
+ CoOl__-.-__sTuFF
+
+ ---------- Footnotes ----------
+
+ (1) https://www.python.org/dev/peps/pep-0508
+
+
+File: pythonpackagingguide.info, Node: version, Next: description, Prev: name, Up: setup args
+
+3.7.2.10 version
+................
+
+ version='1.2.0',
+
+This is the current version of your project, allowing your users to
+determine whether or not they have the latest version, and to indicate
+which specific versions they’ve tested their own software against.
+
+Versions are displayed on *note PyPI: 39. for each release if you
+publish your project.
+
+See *note Choosing a versioning scheme: c9. for more information on ways
+to use versions to convey compatibility information to your users.
+
+If the project code itself needs run-time access to the version, the
+simplest way is to keep the version in both ‘setup.py’ and your code.
+If you’d rather not duplicate the value, there are a few ways to manage
+this. See the “*note Single-sourcing the package version: ca.” Advanced
+Topics section.
+
+
+File: pythonpackagingguide.info, Node: description, Next: url, Prev: version, Up: setup args
+
+3.7.2.11 description
+....................
+
+ description='A sample Python project',
+ long_description=long_description,
+ long_description_content_type='text/x-rst',
+
+Give a short and long description for your project.
+
+These values will be displayed on *note PyPI: 39. if you publish your
+project. On ‘pypi.org’, the user interface displays ‘description’ in
+the grey banner and ‘long_description’ in the section named “Project
+Description”.
+
+‘description’ is also displayed in lists of projects. For example, it’s
+visible in the search results pages such as
+‘https://pypi.org/search/?q=jupyter’, the front-page lists of trending
+projects and new releases, and the list of projects you maintain within
+your account profile (such as ‘https://pypi.org/user/jaraco/’).
+
+A content type(1) can be specified with the
+‘long_description_content_type’ argument, which can be one of
+‘text/plain’, ‘text/x-rst’, or ‘text/markdown’, corresponding to no
+formatting, reStructuredText (reST)(2), and the Github-flavored Markdown
+dialect of Markdown(3) respectively.
+
+ ---------- Footnotes ----------
+
+ (1)
+https://packaging.python.org/specifications/core-metadata/#description-content-type-optional
+
+ (2)
+http://docutils.sourceforge.net/docs/ref/rst/restructuredtext.html#reference-names
+
+ (3) https://daringfireball.net/projects/markdown/
+
+
+File: pythonpackagingguide.info, Node: url, Next: author, Prev: description, Up: setup args
+
+3.7.2.12 url
+............
+
+ url='https://github.com/pypa/sampleproject',
+
+Give a homepage URL for your project.
+
+
+File: pythonpackagingguide.info, Node: author, Next: license, Prev: url, Up: setup args
+
+3.7.2.13 author
+...............
+
+ author='A. Random Developer',
+ author_email='author@example.com',
+
+Provide details about the author.
+
+
+File: pythonpackagingguide.info, Node: license, Next: classifiers, Prev: author, Up: setup args
+
+3.7.2.14 license
+................
+
+ license='MIT',
+
+The ‘license’ argument doesn’t have to indicate the license under which
+your package is being released, although you may optionally do so if you
+want. If you’re using a standard, well-known license, then your main
+indication can and should be via the ‘classifiers’ argument.
+Classifiers exist for all major open-source licenses.
+
+The “license” argument is more typically used to indicate differences
+from well-known licenses, or to include your own, unique license. As a
+general rule, it’s a good idea to use a standard, well-known license,
+both to avoid confusion and because some organizations avoid software
+whose license is unapproved.
+
+
+File: pythonpackagingguide.info, Node: classifiers, Next: keywords, Prev: license, Up: setup args
+
+3.7.2.15 classifiers
+....................
+
+ classifiers=[
+ # How mature is this project? Common values are
+ # 3 - Alpha
+ # 4 - Beta
+ # 5 - Production/Stable
+ 'Development Status :: 3 - Alpha',
+
+ # Indicate who your project is intended for
+ 'Intended Audience :: Developers',
+ 'Topic :: Software Development :: Build Tools',
+
+ # Pick your license as you wish (should match "license" above)
+ 'License :: OSI Approved :: MIT License',
+
+ # Specify the Python versions you support here. In particular, ensure
+ # that you indicate whether you support Python 2, Python 3 or both.
+ 'Programming Language :: Python :: 2',
+ 'Programming Language :: Python :: 2.6',
+ 'Programming Language :: Python :: 2.7',
+ 'Programming Language :: Python :: 3',
+ 'Programming Language :: Python :: 3.2',
+ 'Programming Language :: Python :: 3.3',
+ 'Programming Language :: Python :: 3.4',
+ ],
+
+Provide a list of classifiers that categorize your project. For a full
+listing, see ‘https://pypi.org/classifiers/’.
+
+Although the list of classifiers is often used to declare what Python
+versions a project supports, this information is only used for searching
+& browsing projects on PyPI, not for installing projects. To actually
+restrict what Python versions a project can be installed on, use the
+*note python_requires: d0. argument.
+
+
+File: pythonpackagingguide.info, Node: keywords, Next: project_urls, Prev: classifiers, Up: setup args
+
+3.7.2.16 keywords
+.................
+
+ keywords='sample setuptools development',
+
+List keywords that describe your project.
+
+
+File: pythonpackagingguide.info, Node: project_urls, Next: packages, Prev: keywords, Up: setup args
+
+3.7.2.17 project_urls
+.....................
+
+ project_urls={
+ 'Documentation': 'https://packaging.python.org/tutorials/distributing-packages/',
+ 'Funding': 'https://donate.pypi.org',
+ 'Say Thanks!': 'http://saythanks.io/to/example',
+ 'Source': 'https://github.com/pypa/sampleproject/',
+ 'Tracker': 'https://github.com/pypa/sampleproject/issues',
+ },
+
+List additional relevant URLs about your project. This is the place to
+link to bug trackers, source repositories, or where to support package
+development. The string of the key is the exact text that will be
+displayed on PyPI.
+
+
+File: pythonpackagingguide.info, Node: packages, Next: py_modules, Prev: project_urls, Up: setup args
+
+3.7.2.18 packages
+.................
+
+ packages=find_packages(include=['sample', 'sample.*']),
+
+Set ‘packages’ to a list of all *note packages: a. in your project,
+including their subpackages, sub-subpackages, etc. Although the
+packages can be listed manually, ‘setuptools.find_packages()’ finds them
+automatically. Use the ‘include’ keyword argument to find only the
+given packages. Use the ‘exclude’ keyword argument to omit packages
+that are not intended to be released and installed.
+
+
+File: pythonpackagingguide.info, Node: py_modules, Next: install_requires, Prev: packages, Up: setup args
+
+3.7.2.19 py_modules
+...................
+
+ py_modules=["six"],
+
+If your project contains any single-file Python modules that aren’t part
+of a package, set ‘py_modules’ to a list of the names of the modules
+(minus the ‘.py’ extension) in order to make *note setuptools: 2d. aware
+of them.
+
+
+File: pythonpackagingguide.info, Node: install_requires, Next: python_requires, Prev: py_modules, Up: setup args
+
+3.7.2.20 install_requires
+.........................
+
+ install_requires=['peppercorn'],
+
+“install_requires” should be used to specify what dependencies a project
+minimally needs to run. When the project is installed by *note pip: 2b,
+this is the specification that is used to install its dependencies.
+
+For more on using “install_requires” see *note install_requires vs
+requirements files: d6.
+
+
+File: pythonpackagingguide.info, Node: python_requires, Next: package_data, Prev: install_requires, Up: setup args
+
+3.7.2.21 python_requires
+........................
+
+If your project only runs on certain Python versions, setting the
+‘python_requires’ argument to the appropriate PEP 440(1) version
+specifier string will prevent *note pip: 2b. from installing the project
+on other Python versions. For example, if your package is for Python 3+
+only, write:
+
+ python_requires='>=3',
+
+If your package is for Python 3.3 and up but you’re not willing to
+commit to Python 4 support yet, write:
+
+ python_requires='~=3.3',
+
+If your package is for Python 2.6, 2.7, and all versions of Python 3
+starting with 3.3, write:
+
+ python_requires='>=2.6, !=3.0.*, !=3.1.*, !=3.2.*, <4',
+
+And so on.
+
+ Note: Support for this feature is relatively recent. Your
+ project’s source distributions and wheels (see *note Packaging your
+ project: d8.) must be built using at least version 24.2.0 of *note
+ setuptools: 2d. in order for the ‘python_requires’ argument to be
+ recognized and the appropriate metadata generated.
+
+ In addition, only versions 9.0.0 and higher of *note pip: 2b.
+ recognize the ‘python_requires’ metadata. Users with earlier
+ versions of pip will be able to download & install projects on any
+ Python version regardless of the projects’ ‘python_requires’
+ values.
+
+ ---------- Footnotes ----------
+
+ (1) https://www.python.org/dev/peps/pep-0440
+
+
+File: pythonpackagingguide.info, Node: package_data, Next: data_files, Prev: python_requires, Up: setup args
+
+3.7.2.22 package_data
+.....................
+
+ package_data={
+ 'sample': ['package_data.dat'],
+ },
+
+Often, additional files need to be installed into a *note package: a.
+These files are often data that’s closely related to the package’s
+implementation, or text files containing documentation that might be of
+interest to programmers using the package. These files are called
+“package data”.
+
+The value must be a mapping from package name to a list of relative path
+names that should be copied into the package. The paths are interpreted
+as relative to the directory containing the package.
+
+For more information, see Including Data Files(1) from the setuptools
+docs(2).
+
+ ---------- Footnotes ----------
+
+ (1)
+https://setuptools.readthedocs.io/en/latest/setuptools.html#including-data-files
+
+ (2) https://setuptools.readthedocs.io
+
+
+File: pythonpackagingguide.info, Node: data_files, Next: scripts, Prev: package_data, Up: setup args
+
+3.7.2.23 data_files
+...................
+
+ data_files=[('my_data', ['data/data_file'])],
+
+Although configuring *note package_data: da. is sufficient for most
+needs, in some cases you may need to place data files `outside' of your
+*note packages: a. The ‘data_files’ directive allows you to do that.
+It is mostly useful if you need to install files which are used by other
+programs, which may be unaware of Python packages.
+
+Each ‘(directory, files)’ pair in the sequence specifies the
+installation directory and the files to install there. The ‘directory’
+must be a relative path (although this may change in the future, see
+wheel Issue #92(1)). and it is interpreted relative to the installation
+prefix (Python’s ‘sys.prefix’ for a default installation;
+‘site.USER_BASE’ for a user installation). Each file name in ‘files’ is
+interpreted relative to the ‘setup.py’ script at the top of the project
+source distribution.
+
+For more information see the distutils section on Installing Additional
+Files(2).
+
+ Note: When installing packages as egg, ‘data_files’ is not
+ supported. So, if your project uses *note setuptools: 2d, you must
+ use ‘pip’ to install it. Alternatively, if you must use ‘python
+ setup.py’, then you need to pass the ‘--old-and-unmanageable’
+ option.
+
+ ---------- Footnotes ----------
+
+ (1) https://github.com/pypa/wheel/issues/92
+
+ (2)
+http://docs.python.org/3/distutils/setupscript.html#installing-additional-files
+
+
+File: pythonpackagingguide.info, Node: scripts, Next: entry_points, Prev: data_files, Up: setup args
+
+3.7.2.24 scripts
+................
+
+Although ‘setup()’ supports a scripts(1) keyword for pointing to
+pre-made scripts to install, the recommended approach to achieve
+cross-platform compatibility is to use *note console_scripts: de. entry
+points (see below).
+
+ ---------- Footnotes ----------
+
+ (1)
+http://docs.python.org/3/distutils/setupscript.html#installing-scripts
+
+
+File: pythonpackagingguide.info, Node: entry_points, Prev: scripts, Up: setup args
+
+3.7.2.25 entry_points
+.....................
+
+ entry_points={
+ ...
+ },
+
+Use this keyword to specify any plugins that your project provides for
+any named entry points that may be defined by your project or others
+that you depend on.
+
+For more information, see the section on Advertising Behavior(1) from
+the *note setuptools: 2d. docs.
+
+The most commonly used entry point is “console_scripts” (see below).
+
+* Menu:
+
+* console_scripts::
+
+ ---------- Footnotes ----------
+
+ (1)
+https://setuptools.readthedocs.io/en/latest/userguide/entry_point.html#dynamic-discovery-of-services-and-plugins
+
+
+File: pythonpackagingguide.info, Node: console_scripts, Up: entry_points
+
+3.7.2.26 console_scripts
+........................
+
+ entry_points={
+ 'console_scripts': [
+ 'sample=sample:main',
+ ],
+ },
+
+Use “console_script” entry points(1) to register your script interfaces.
+You can then let the toolchain handle the work of turning these
+interfaces into actual scripts (2). The scripts will be generated
+during the install of your *note distribution: b.
+
+For more information, see Automatic Script Creation(3) from the
+setuptools docs(4).
+
+ ---------- Footnotes ----------
+
+ (1)
+https://setuptools.readthedocs.io/en/latest/setuptools.html#dynamic-discovery-of-services-and-plugins
+
+ (2) (2) Specifically, the “console_script” approach generates ‘.exe’
+files on Windows, which are necessary because the OS special-cases
+‘.exe’ files. Script-execution features like ‘PATHEXT’ and the Python
+Launcher for Windows (https://www.python.org/dev/peps/pep-0397) allow
+scripts to be used in many cases, but not all.
+
+ (3)
+https://setuptools.readthedocs.io/en/latest/setuptools.html#automatic-script-creation
+
+ (4) https://setuptools.readthedocs.io
+
+
+File: pythonpackagingguide.info, Node: Choosing a versioning scheme, Prev: setup args, Up: Configuring your project
+
+3.7.2.27 Choosing a versioning scheme
+.....................................
+
+* Menu:
+
+* Standards compliance for interoperability::
+* Scheme choices::
+* Pre-release versioning::
+* Local version identifiers::
+
+
+File: pythonpackagingguide.info, Node: Standards compliance for interoperability, Next: Scheme choices, Up: Choosing a versioning scheme
+
+3.7.2.28 Standards compliance for interoperability
+..................................................
+
+Different Python projects may use different versioning schemes based on
+the needs of that particular project, but all of them are required to
+comply with the flexible public version scheme(1) specified in PEP
+440(2) in order to be supported in tools and libraries like ‘pip’ and
+‘setuptools’.
+
+Here are some examples of compliant version numbers:
+
+ 1.2.0.dev1 # Development release
+ 1.2.0a1 # Alpha Release
+ 1.2.0b1 # Beta Release
+ 1.2.0rc1 # Release Candidate
+ 1.2.0 # Final Release
+ 1.2.0.post1 # Post Release
+ 15.10 # Date based release
+ 23 # Serial release
+
+To further accommodate historical variations in approaches to version
+numbering, PEP 440(3) also defines a comprehensive technique for version
+normalisation(4) that maps variant spellings of different version
+numbers to a standardised canonical form.
+
+ ---------- Footnotes ----------
+
+ (1)
+https://www.python.org/dev/peps/pep-0440#public-version-identifiers
+
+ (2) https://www.python.org/dev/peps/pep-0440
+
+ (3) https://www.python.org/dev/peps/pep-0440
+
+ (4) https://www.python.org/dev/peps/pep-0440#normalization
+
+
+File: pythonpackagingguide.info, Node: Scheme choices, Next: Pre-release versioning, Prev: Standards compliance for interoperability, Up: Choosing a versioning scheme
+
+3.7.2.29 Scheme choices
+.......................
+
+* Menu:
+
+* Semantic versioning (preferred): Semantic versioning preferred.
+* Date based versioning::
+* Serial versioning::
+* Hybrid schemes::
+
+
+File: pythonpackagingguide.info, Node: Semantic versioning preferred, Next: Date based versioning, Up: Scheme choices
+
+3.7.2.30 Semantic versioning (preferred)
+........................................
+
+For new projects, the recommended versioning scheme is based on Semantic
+Versioning(1), but adopts a different approach to handling pre-releases
+and build metadata.
+
+The essence of semantic versioning is a 3-part MAJOR.MINOR.MAINTENANCE
+numbering scheme, where the project author increments:
+
+ 1. MAJOR version when they make incompatible API changes,
+
+ 2. MINOR version when they add functionality in a backwards-compatible
+ manner, and
+
+ 3. MAINTENANCE version when they make backwards-compatible bug fixes.
+
+Adopting this approach as a project author allows users to make use of
+“compatible release”(2) specifiers, where ‘name ~= X.Y’ requires at
+least release X.Y, but also allows any later release with a matching
+MAJOR version.
+
+Python projects adopting semantic versioning should abide by clauses 1-8
+of the Semantic Versioning 2.0.0 specification(3).
+
+ ---------- Footnotes ----------
+
+ (1) http://semver.org
+
+ (2) https://www.python.org/dev/peps/pep-0440#compatible-release
+
+ (3) http://semver.org
+
+
+File: pythonpackagingguide.info, Node: Date based versioning, Next: Serial versioning, Prev: Semantic versioning preferred, Up: Scheme choices
+
+3.7.2.31 Date based versioning
+..............................
+
+Semantic versioning is not a suitable choice for all projects, such as
+those with a regular time based release cadence and a deprecation
+process that provides warnings for a number of releases prior to removal
+of a feature.
+
+A key advantage of date based versioning is that it is straightforward
+to tell how old the base feature set of a particular release is given
+just the version number.
+
+Version numbers for date based projects typically take the form of
+YEAR.MONTH (for example, ‘12.04’, ‘15.10’).
+
+
+File: pythonpackagingguide.info, Node: Serial versioning, Next: Hybrid schemes, Prev: Date based versioning, Up: Scheme choices
+
+3.7.2.32 Serial versioning
+..........................
+
+This is the simplest possible versioning scheme, and consists of a
+single number which is incremented every release.
+
+While serial versioning is very easy to manage as a developer, it is the
+hardest to track as an end user, as serial version numbers convey little
+or no information regarding API backwards compatibility.
+
+
+File: pythonpackagingguide.info, Node: Hybrid schemes, Prev: Serial versioning, Up: Scheme choices
+
+3.7.2.33 Hybrid schemes
+.......................
+
+Combinations of the above schemes are possible. For example, a project
+may combine date based versioning with serial versioning to create a
+YEAR.SERIAL numbering scheme that readily conveys the approximate age of
+a release, but doesn’t otherwise commit to a particular release cadence
+within the year.
+
+
+File: pythonpackagingguide.info, Node: Pre-release versioning, Next: Local version identifiers, Prev: Scheme choices, Up: Choosing a versioning scheme
+
+3.7.2.34 Pre-release versioning
+...............................
+
+Regardless of the base versioning scheme, pre-releases for a given final
+release may be published as:
+
+ * zero or more dev releases (denoted with a “.devN” suffix)
+
+ * zero or more alpha releases (denoted with a “.aN” suffix)
+
+ * zero or more beta releases (denoted with a “.bN” suffix)
+
+ * zero or more release candidates (denoted with a “.rcN” suffix)
+
+‘pip’ and other modern Python package installers ignore pre-releases by
+default when deciding which versions of dependencies to install.
+
+
+File: pythonpackagingguide.info, Node: Local version identifiers, Prev: Pre-release versioning, Up: Choosing a versioning scheme
+
+3.7.2.35 Local version identifiers
+..................................
+
+Public version identifiers are designed to support distribution via
+*note PyPI: 39. Python’s software distribution tools also support the
+notion of a local version identifier(1), which can be used to identify
+local development builds not intended for publication, or modified
+variants of a release maintained by a redistributor.
+
+A local version identifier takes the form ‘<public version
+identifier>+<local version label>’. For example:
+
+ 1.2.0.dev1+hg.5.b11e5e6f0b0b # 5th VCS commmit since 1.2.0.dev1 release
+ 1.2.1+fedora.4 # Package with downstream Fedora patches applied
+
+ ---------- Footnotes ----------
+
+ (1)
+https://www.python.org/dev/peps/pep-0440#local-version-identifiers
+
+
+File: pythonpackagingguide.info, Node: Working in “development mode”, Next: Packaging your project, Prev: Configuring your project, Up: Packaging and distributing projects
+
+3.7.3 Working in “development mode”
+-----------------------------------
+
+Although not required, it’s common to locally install your project in
+“editable” or “develop” mode while you’re working on it. This allows
+your project to be both installed and editable in project form.
+
+Assuming you’re in the root of your project directory, then run:
+
+ pip install -e .
+
+Although somewhat cryptic, ‘-e’ is short for ‘--editable’, and ‘.’
+refers to the current working directory, so together, it means to
+install the current directory (i.e. your project) in editable mode.
+This will also install any dependencies declared with “install_requires”
+and any scripts declared with “console_scripts”. Dependencies will be
+installed in the usual, non-editable mode.
+
+It’s fairly common to also want to install some of your dependencies in
+editable mode as well. For example, supposing your project requires
+“foo” and “bar”, but you want “bar” installed from VCS in editable mode,
+then you could construct a requirements file like so:
+
+ -e .
+ -e git+https://somerepo/bar.git#egg=bar
+
+The first line says to install your project and any dependencies. The
+second line overrides the “bar” dependency, such that it’s fulfilled
+from VCS, not PyPI.
+
+If, however, you want “bar” installed from a local directory in editable
+mode, the requirements file should look like this, with the local paths
+at the top of the file:
+
+ -e /path/to/project/bar
+ -e .
+
+Otherwise, the dependency will be fulfilled from PyPI, due to the
+installation order of the requirements file. For more on requirements
+files, see the Requirements File(1) section in the pip docs. For more
+on VCS installs, see the VCS Support(2) section of the pip docs.
+
+Lastly, if you don’t want to install any dependencies at all, you can
+run:
+
+ pip install -e . --no-deps
+
+For more information, see the Development Mode(3) section of the
+setuptools docs(4).
+
+ ---------- Footnotes ----------
+
+ (1) https://pip.pypa.io/en/latest/user_guide/#requirements-files
+
+ (2) https://pip.pypa.io/en/latest/reference/pip_install/#vcs-support
+
+ (3)
+https://setuptools.readthedocs.io/en/latest/setuptools.html#development-mode
+
+ (4) https://setuptools.readthedocs.io
+
+
+File: pythonpackagingguide.info, Node: Packaging your project, Next: Uploading your Project to PyPI, Prev: Working in “development mode”, Up: Packaging and distributing projects
+
+3.7.4 Packaging your project
+----------------------------
+
+To have your project installable from a *note Package Index: ec. like
+*note PyPI: 39, you’ll need to create a *note Distribution: b. (aka
+“*note Package: b.”) for your project.
+
+* Menu:
+
+* Source distributions::
+* Wheels::
+
+
+File: pythonpackagingguide.info, Node: Source distributions, Next: Wheels, Up: Packaging your project
+
+3.7.4.1 Source distributions
+............................
+
+Minimally, you should create a *note Source Distribution: 3d.:
+
+ python setup.py sdist
+
+A “source distribution” is unbuilt (i.e. it’s not a *note Built
+Distribution: 63.), and requires a build step when installed by pip.
+Even if the distribution is pure Python (i.e. contains no extensions),
+it still involves a build step to build out the installation metadata
+from ‘setup.py’.
+
+
+File: pythonpackagingguide.info, Node: Wheels, Prev: Source distributions, Up: Packaging your project
+
+3.7.4.2 Wheels
+..............
+
+You should also create a wheel for your project. A wheel is a *note
+built package: 63. that can be installed without needing to go through
+the “build” process. Installing wheels is substantially faster for the
+end user than installing from a source distribution.
+
+If your project is pure Python (i.e. contains no compiled extensions)
+and natively supports both Python 2 and 3, then you’ll be creating
+what’s called a *note *Universal Wheel* (see section below): ef.
+
+If your project is pure Python but does not natively support both Python
+2 and 3, then you’ll be creating a *note “Pure Python Wheel” (see
+section below): f0.
+
+If your project contains compiled extensions, then you’ll be creating
+what’s called a *note *Platform Wheel* (see section below): f1.
+
+Before you can build wheels for your project, you’ll need to install the
+‘wheel’ package:
+
+ pip install wheel
+
+* Menu:
+
+* Universal Wheels::
+* Pure Python Wheels::
+* Platform Wheels::
+
+
+File: pythonpackagingguide.info, Node: Universal Wheels, Next: Pure Python Wheels, Up: Wheels
+
+3.7.4.3 Universal Wheels
+........................
+
+`Universal Wheels' are wheels that are pure Python (i.e. contain no
+compiled extensions) and support Python 2 and 3. This is a wheel that
+can be installed anywhere by *note pip: 2b.
+
+To build the wheel:
+
+ python setup.py bdist_wheel --universal
+
+You can also permanently set the ‘--universal’ flag in ‘setup.cfg’:
+
+ [bdist_wheel]
+ universal=1
+
+Only use the ‘--universal’ setting, if:
+
+ 1. Your project runs on Python 2 and 3 with no changes (i.e. it does
+ not require 2to3).
+
+ 2. Your project does not have any C extensions.
+
+Beware that ‘bdist_wheel’ does not currently have any checks to warn if
+you use the setting inappropriately.
+
+If your project has optional C extensions, it is recommended not to
+publish a universal wheel, because pip will prefer the wheel over a
+source installation, and prevent the possibility of building the
+extension.
+
+
+File: pythonpackagingguide.info, Node: Pure Python Wheels, Next: Platform Wheels, Prev: Universal Wheels, Up: Wheels
+
+3.7.4.4 Pure Python Wheels
+..........................
+
+`Pure Python Wheels' that are not “universal” are wheels that are pure
+Python (i.e. contain no compiled extensions), but don’t natively
+support both Python 2 and 3.
+
+To build the wheel:
+
+ python setup.py bdist_wheel
+
+‘bdist_wheel’ will detect that the code is pure Python, and build a
+wheel that’s named such that it’s usable on any Python installation with
+the same major version (Python 2 or Python 3) as the version you used to
+build the wheel. For details on the naming of wheel files, see PEP
+425(1).
+
+If your code supports both Python 2 and 3, but with different code
+(e.g., you use "2to3"(2)) you can run ‘setup.py bdist_wheel’ twice, once
+with Python 2 and once with Python 3. This will produce wheels for each
+version.
+
+ ---------- Footnotes ----------
+
+ (1) https://www.python.org/dev/peps/pep-0425
+
+ (2) https://docs.python.org/2/library/2to3.html
+
+
+File: pythonpackagingguide.info, Node: Platform Wheels, Prev: Pure Python Wheels, Up: Wheels
+
+3.7.4.5 Platform Wheels
+.......................
+
+`Platform Wheels' are wheels that are specific to a certain platform
+like Linux, macOS, or Windows, usually due to containing compiled
+extensions.
+
+To build the wheel:
+
+ python setup.py bdist_wheel
+
+‘bdist_wheel’ will detect that the code is not pure Python, and build a
+wheel that’s named such that it’s only usable on the platform that it
+was built on. For details on the naming of wheel files, see PEP 425(1).
+
+ Note: *note PyPI: 39. currently supports uploads of platform wheels
+ for Windows, macOS, and the multi-distro ‘manylinux1’ ABI. Details
+ of the latter are defined in PEP 513(2).
+
+ ---------- Footnotes ----------
+
+ (1) https://www.python.org/dev/peps/pep-0425
+
+ (2) https://www.python.org/dev/peps/pep-0513
+
+
+File: pythonpackagingguide.info, Node: Uploading your Project to PyPI, Prev: Packaging your project, Up: Packaging and distributing projects
+
+3.7.5 Uploading your Project to PyPI
+------------------------------------
+
+When you ran the command to create your distribution, a new directory
+‘dist/’ was created under your project’s root directory. That’s where
+you’ll find your distribution file(s) to upload.
+
+ Note: These files are only created when you run the command to
+ create your distribution. This means that any time you change the
+ source of your project or the configuration in your ‘setup.py’
+ file, you will need to rebuild these files again before you can
+ distribute the changes to PyPI.
+
+ Note: Before releasing on main PyPI repo, you might prefer training
+ with the PyPI test site(1) which is cleaned on a semi regular
+ basis. See *note Using TestPyPI: f6. on how to setup your
+ configuration in order to use it.
+
+ Warning: In other resources you may encounter references to using
+ ‘python setup.py register’ and ‘python setup.py upload’. These
+ methods of registering and uploading a package are `strongly
+ discouraged' as it may use a plaintext HTTP or unverified HTTPS
+ connection on some Python versions, allowing your username and
+ password to be intercepted during transmission.
+
+ Tip: The reStructuredText parser used on PyPI is `not' Sphinx!
+ Furthermore, to ensure safety of all users, certain kinds of URLs
+ and directives are forbidden or stripped out (e.g., the ‘.. raw::’
+ directive). `Before' trying to upload your distribution, you
+ should check to see if your brief / long descriptions provided in
+ ‘setup.py’ are valid. You can do this by following the
+ instructions for the pypa/readme_renderer(2) tool.
+
+* Menu:
+
+* Create an account::
+* Upload your distributions::
+
+ ---------- Footnotes ----------
+
+ (1) https://test.pypi.org/
+
+ (2) https://github.com/pypa/readme_renderer
+
+
+File: pythonpackagingguide.info, Node: Create an account, Next: Upload your distributions, Up: Uploading your Project to PyPI
+
+3.7.5.1 Create an account
+.........................
+
+First, you need a *note PyPI: 39. user account. You can create an
+account using the form on the PyPI website(1).
+
+Now you’ll create a PyPI API token(2) so you will be able to securely
+upload your project.
+
+Go to ‘https://pypi.org/manage/account/#api-tokens’ and create a new API
+token(3); don’t limit its scope to a particular project, since you are
+creating a new project.
+
+`Don’t close the page until you have copied and saved the token — you
+won’t see that token again.'
+
+ Note: To avoid having to copy and paste the token every time you
+ upload, you can create a ‘$HOME/.pypirc’ file:
+
+ [pypi]
+ username = __token__
+ password = <the token value, including the `pypi-` prefix>
+
+ `Be aware that this stores your token in plaintext.'
+
+ For more details, see the *note specification: f8. for ‘.pypirc’.
+
+ ---------- Footnotes ----------
+
+ (1) https://pypi.org/account/register/
+
+ (2) https://pypi.org/help/#apitoken
+
+ (3) https://pypi.org/help/#apitoken
+
+
+File: pythonpackagingguide.info, Node: Upload your distributions, Prev: Create an account, Up: Uploading your Project to PyPI
+
+3.7.5.2 Upload your distributions
+.................................
+
+Once you have an account you can upload your distributions to *note
+PyPI: 39. using *note twine: 66.
+
+The process for uploading a release is the same regardless of whether or
+not the project already exists on PyPI - if it doesn’t exist yet, it
+will be automatically created when the first release is uploaded.
+
+For the second and subsequent releases, PyPI only requires that the
+version number of the new release differ from any previous releases.
+
+ twine upload dist/*
+
+You can see if your package has successfully uploaded by navigating to
+the URL ‘https://pypi.org/project/<sampleproject>’ where ‘sampleproject’
+is the name of your project that you uploaded. It may take a minute or
+two for your project to appear on the site.
+
+__________________________________________________________________
+
+
+File: pythonpackagingguide.info, Node: Including files in source distributions with MANIFEST in, Next: Single-sourcing the package version, Prev: Packaging and distributing projects, Up: Guides
+
+3.8 Including files in source distributions with ‘MANIFEST.in’
+==============================================================
+
+When building a *note source distribution: 3d. for your package, by
+default only a minimal set of files are included. You may find yourself
+wanting to include extra files in the source distribution, such as an
+authors/contributors file, a ‘docs/’ directory, or a directory of data
+files used for testing purposes. There may even be extra files that you
+`need' to include; for example, if your ‘setup.py’ computes your
+project’s ‘long_description’ by reading from both a README and a
+changelog file, you’ll need to include both those files in the sdist so
+that people that build or install from the sdist get the correct
+results.
+
+Adding & removing files to & from the source distribution is done by
+writing a ‘MANIFEST.in’ file at the project root.
+
+* Menu:
+
+* How files are included in an sdist::
+* MANIFEST.in commands: MANIFEST in commands.
+
+
+File: pythonpackagingguide.info, Node: How files are included in an sdist, Next: MANIFEST in commands, Up: Including files in source distributions with MANIFEST in
+
+3.8.1 How files are included in an sdist
+----------------------------------------
+
+The following files are included in a source distribution by default:
+
+ - all Python source files implied by the ‘py_modules’ and ‘packages’
+ ‘setup()’ arguments
+
+ - all C source files mentioned in the ‘ext_modules’ or ‘libraries’
+ ‘setup()’ arguments
+
+ - scripts specified by the ‘scripts’ ‘setup()’ argument
+
+ - all files specified by the ‘package_data’ and ‘data_files’
+ ‘setup()’ arguments
+
+ - the file specified by the ‘license_file’ option in ‘setup.cfg’
+ (setuptools 40.8.0+)
+
+ - all files specified by the ‘license_files’ option in ‘setup.cfg’
+ (setuptools 42.0.0+)
+
+ - all files matching the pattern ‘test/test*.py’
+
+ - ‘setup.py’ (or whatever you called your setup script)
+
+ - ‘setup.cfg’
+
+ - ‘README’
+
+ - ‘README.txt’
+
+ - ‘README.rst’ (Python 3.7+ or setuptools 0.6.27+)
+
+ - ‘README.md’ (setuptools 36.4.0+)
+
+ - ‘pyproject.toml’ (setuptools 43.0.0+)
+
+ - ‘MANIFEST.in’
+
+After adding the above files to the sdist, the commands in ‘MANIFEST.in’
+(if such a file exists) are executed in order to add and remove further
+files to & from the sdist. Default files can even be removed from the
+sdist with the appropriate ‘MANIFEST.in’ command.
+
+After processing the ‘MANIFEST.in’ file, setuptools removes the ‘build/’
+directory as well as any directories named ‘RCS’, ‘CVS’, or ‘.svn’ from
+the sdist, and it adds a ‘PKG-INFO’ file and an ‘*.egg-info’ directory.
+This behavior cannot be changed with ‘MANIFEST.in’.
+
+
+File: pythonpackagingguide.info, Node: MANIFEST in commands, Prev: How files are included in an sdist, Up: Including files in source distributions with MANIFEST in
+
+3.8.2 ‘MANIFEST.in’ commands
+----------------------------
+
+A ‘MANIFEST.in’ file consists of commands, one per line, instructing
+setuptools to add or remove some set of files from the sdist. The
+commands are:
+
+Command Description
+
+-----------------------------------------------------------------------------------------------------------------------------------------------------------
+
+‘include pat1 pat2 ...’ Include all files matching any of the listed patterns
+
+
+‘exclude pat1 pat2 ...’ Exclude all files matching any of the listed patterns
+
+
+‘recursive-include dir-pattern pat1 pat2 ...’ Include all files under directories matching ‘dir-pattern’ that match any of the listed patterns
+
+
+‘recursive-exclude dir-pattern pat1 pat2 ...’ Exclude all files under directories matching ‘dir-pattern’ that match any of the listed patterns
+
+
+‘global-include pat1 pat2 ...’ Include all files anywhere in the source tree matching any of the listed patterns
+
+
+‘global-exclude pat1 pat2 ...’ Exclude all files anywhere in the source tree matching any of the listed patterns
+
+
+‘graft dir-pattern’ Include all files under directories matching ‘dir-pattern’
+
+
+‘prune dir-pattern’ Exclude all files under directories matching ‘dir-pattern’
+
+
+The patterns here are glob-style patterns: ‘*’ matches zero or more
+regular filename characters (on Unix, everything except forward slash;
+on Windows, everything except backslash and colon); ‘?’ matches a single
+regular filename character, and ‘[chars]’ matches any one of the
+characters between the square brackets (which may contain character
+ranges, e.g., ‘[a-z]’ or ‘[a-fA-F0-9]’). Setuptools also has
+undocumented support for ‘**’ matching zero or more characters including
+forward slash, backslash, and colon.
+
+Directory patterns are relative to the root of the project directory;
+e.g., ‘graft example*’ will include a directory named ‘examples’ in the
+project root but will not include ‘docs/examples/’.
+
+File & directory names in ‘MANIFEST.in’ should be ‘/’-separated;
+setuptools will automatically convert the slashes to the local
+platform’s appropriate directory separator.
+
+Commands are processed in the order they appear in the ‘MANIFEST.in’
+file. For example, given the commands:
+
+ graft tests
+ global-exclude *.py[cod]
+
+the contents of the directory tree ‘tests’ will first be added to the
+sdist, and then after that all files in the sdist with a ‘.pyc’, ‘.pyo’,
+or ‘.pyd’ extension will be removed from the sdist. If the commands
+were in the opposite order, then ‘*.pyc’ files etc. would be only be
+removed from what was already in the sdist before adding ‘tests’, and if
+‘tests’ happened to contain any ‘*.pyc’ files, they would end up
+included in the sdist because the exclusion happened before they were
+included.
+
+
+File: pythonpackagingguide.info, Node: Single-sourcing the package version, Next: Supporting multiple Python versions, Prev: Including files in source distributions with MANIFEST in, Up: Guides
+
+3.9 Single-sourcing the package version
+=======================================
+
+There are many techniques to maintain a single source of truth for the
+version number of your project:
+
+ 1. Read the file in ‘setup.py’ and get the version. Example (from pip
+ setup.py(1)):
+
+ import codecs
+ import os.path
+
+ def read(rel_path):
+ here = os.path.abspath(os.path.dirname(__file__))
+ with codecs.open(os.path.join(here, rel_path), 'r') as fp:
+ return fp.read()
+
+ def get_version(rel_path):
+ for line in read(rel_path).splitlines():
+ if line.startswith('__version__'):
+ delim = '"' if '"' in line else "'"
+ return line.split(delim)[1]
+ else:
+ raise RuntimeError("Unable to find version string.")
+
+ setup(
+ ...
+ version=get_version("package/__init__.py")
+ ...
+ )
+
+ Note: As of the release of setuptools 46.4.0, one can
+ accomplish the same thing by instead placing the following in
+ the project’s ‘setup.cfg’ file (replacing “package” with the
+ import name of the package):
+
+ [metadata]
+ version = attr: package.__version__
+
+ Earlier versions of setuptools implemented the ‘attr:’
+ directive by importing the module, but setuptools 46.4.0 added
+ rudimentary AST analysis so that ‘attr:’ can function without
+ having to import any of the package’s dependencies.
+
+ 2. Use an external build tool that either manages updating both
+ locations, or offers an API that both locations can use.
+
+ Few tools you could use, in no particular order, and not
+ necessarily complete: bump2version(2), changes(3),
+ zest.releaser(4).
+
+ 3. Set the value to a ‘__version__’ global variable in a dedicated
+ module in your project (e.g. ‘version.py’), then have ‘setup.py’
+ read and ‘exec’ the value into a variable.
+
+ version = {}
+ with open("...sample/version.py") as fp:
+ exec(fp.read(), version)
+ # later on we use: version['__version__']
+
+ Example using this technique: warehouse(5).
+
+ 4. Place the value in a simple ‘VERSION’ text file and have both
+ ‘setup.py’ and the project code read it.
+
+ with open(os.path.join(mypackage_root_dir, 'VERSION')) as version_file:
+ version = version_file.read().strip()
+
+ An advantage with this technique is that it’s not specific to
+ Python. Any tool can read the version.
+
+ Warning: With this approach you must make sure that the
+ ‘VERSION’ file is included in all your source and binary
+ distributions (e.g. add ‘include VERSION’ to your
+ ‘MANIFEST.in’).
+
+ 5. Set the value in ‘setup.py’, and have the project code use the
+ ‘importlib.metadata’ API to fetch the value at runtime.
+ (‘importlib.metadata’ was introduced in Python 3.8 and is available
+ to older versions as the ‘importlib-metadata’ project.) An
+ installed project’s version can be fetched with the API as follows:
+
+ try:
+ from importlib import metadata
+ except ImportError:
+ # Running on pre-3.8 Python; use importlib-metadata package
+ import importlib_metadata as metadata
+
+ assert metadata.version('pip') == '1.2.0'
+
+ Be aware that the ‘importlib.metadata’ API only knows about what’s
+ in the installation metadata, which is not necessarily the code
+ that’s currently imported.
+
+ If a project uses this method to fetch its version at runtime, then
+ its ‘install_requires’ value needs to be edited to install
+ ‘importlib-metadata’ on pre-3.8 versions of Python like so:
+
+ setup(
+ ...
+ install_requires=[
+ ...
+ 'importlib-metadata ~= 1.0 ; python_version < "3.8"',
+ ...
+ ],
+ ...
+ )
+
+ An older (and less efficient) alternative to ‘importlib.metadata’
+ is the ‘pkg_resources’ API provided by ‘setuptools’:
+
+ import pkg_resources
+ assert pkg_resources.get_distribution('pip').version == '1.2.0'
+
+ If a project uses ‘pkg_resources’ to fetch its own version at
+ runtime, then ‘setuptools’ must be added to the project’s
+ ‘install_requires’ list.
+
+ Example using this technique: setuptools(6).
+
+ 6. Set the value to ‘__version__’ in ‘sample/__init__.py’ and import
+ ‘sample’ in ‘setup.py’.
+
+ import sample
+ setup(
+ ...
+ version=sample.__version__
+ ...
+ )
+
+ Warning: Although this technique is common, beware that it
+ will fail if ‘sample/__init__.py’ imports packages from
+ ‘install_requires’ dependencies, which will very likely not be
+ installed yet when ‘setup.py’ is run.
+
+ 7. Keep the version number in the tags of a version control system
+ (Git, Mercurial, etc) instead of in the code, and automatically
+ extract it from there using setuptools_scm(7).
+
+ ---------- Footnotes ----------
+
+ (1) https://github.com/pypa/pip/blob/master/setup.py#L11
+
+ (2) https://pypi.org/project/bump2version
+
+ (3) https://pypi.org/project/changes
+
+ (4) https://pypi.org/project/zest.releaser
+
+ (5)
+https://github.com/pypa/warehouse/blob/64ca42e42d5613c8339b3ec5e1cb7765c6b23083/warehouse/__about__.py
+
+ (6)
+https://github.com/pypa/setuptools/blob/master/setuptools/version.py
+
+ (7) https://pypi.org/project/setuptools_scm
+
+
+File: pythonpackagingguide.info, Node: Supporting multiple Python versions, Next: Dropping support for older Python versions, Prev: Single-sourcing the package version, Up: Guides
+
+3.10 Supporting multiple Python versions
+========================================
+
+
+Page Status: Incomplete
+
+
+Last Reviewed: 2014-12-24
+
+ FIXME
+
+ Useful projects/resources to reference:
+
+ - DONE six
+ - DONE python-future (http://python-future.org)
+ - tox
+ - DONE Travis and Shining Panda CI (Shining Panda no longer available)
+ - DONE Appveyor
+ - DONE Ned Batchelder's "What's in Which Python"
+ - http://nedbatchelder.com/blog/201310/whats_in_which_python_3.html
+ - http://nedbatchelder.com/blog/201109/whats_in_which_python.html
+ - Lennart Regebro's "Porting to Python 3"
+ - Greg Hewgill's script to identify the minimum version of Python
+ required to run a particular script:
+ https://github.com/ghewgill/pyqver
+ - the Python 3 porting how to in the main docs
+ - cross reference to the stable ABI discussion
+ in the binary extensions topic (once that exists)
+ - mention version classifiers for distribution metadata
+
+In addition to the work required to create a Python package, it is often
+necessary that the package must be made available on different versions
+of Python. Different Python versions may contain different (or renamed)
+standard library packages, and the changes between Python versions 2.x
+and 3.x include changes in the language syntax.
+
+Performed manually, all the testing required to ensure that the package
+works correctly on all the target Python versions (and OSs!) could be
+very time-consuming. Fortunately, several tools are available for
+dealing with this, and these will briefly be discussed here.
+
+* Menu:
+
+* Automated testing and continuous integration::
+* Tools for single-source Python packages::
+* What’s in which Python?::
+
+
+File: pythonpackagingguide.info, Node: Automated testing and continuous integration, Next: Tools for single-source Python packages, Up: Supporting multiple Python versions
+
+3.10.1 Automated testing and continuous integration
+---------------------------------------------------
+
+Several hosted services for automated testing are available. These
+services will typically monitor your source code repository (e.g. at
+Github(1) or Bitbucket(2)) and run your project’s test suite every time
+a new commit is made.
+
+These services also offer facilities to run your project’s test suite on
+`multiple versions of Python', giving rapid feedback about whether the
+code will work, without the developer having to perform such tests
+themselves.
+
+Wikipedia has an extensive comparison(3) of many continuous-integration
+systems. There are two hosted services which when used in conjunction
+provide automated testing across Linux, Mac and Windows:
+
+ - Travis CI(4) provides both a Linux and a macOS environment.
+ The Linux environment is Ubuntu 12.04 LTS Server Edition 64
+ bit while the macOS is 10.9.2 at the time of writing.
+
+ - Appveyor(5) provides a Windows environment (Windows Server
+ 2012).
+
+ TODO Either link to or provide example .yml files for these two
+ services.
+
+ TODO How do we keep the Travis Linux and macOS versions up-to-date in this
+ document?
+
+Both Travis CI(6) and Appveyor(7) require a YAML(8)-formatted file as
+specification for the instructions for testing. If any tests fail, the
+output log for that specific configuration can be inspected.
+
+For Python projects that are intended to be deployed on both Python 2
+and 3 with a single-source strategy, there are a number of options.
+
+ ---------- Footnotes ----------
+
+ (1) https://github.com
+
+ (2) https://bitbucket.org
+
+ (3)
+http://en.wikipedia.org/wiki/Comparison_of_continuous_integration_software
+
+ (4) https://travis-ci.org
+
+ (5) http://www.appveyor.com
+
+ (6) https://travis-ci.org
+
+ (7) http://www.appveyor.com
+
+ (8) http://www.yaml.org
+
+
+File: pythonpackagingguide.info, Node: Tools for single-source Python packages, Next: What’s in which Python?, Prev: Automated testing and continuous integration, Up: Supporting multiple Python versions
+
+3.10.2 Tools for single-source Python packages
+----------------------------------------------
+
+six(1) is a tool developed by Benjamin Peterson for wrapping over the
+differences between Python 2 and Python 3. The six(2) package has
+enjoyed widespread use and may be regarded as a reliable way to write a
+single-source Python module that can be use in both Python 2 and 3. The
+six(3) module can be used from as early as Python 2.5. A tool called
+modernize(4), developed by Armin Ronacher, can be used to automatically
+apply the code modifications provided by six(5).
+
+Similar to six(6), python-future(7) is a package that provides a
+compatibility layer between Python 2 and Python 3 source code; however,
+unlike six(8), this package aims to provide interoperability between
+Python 2 and Python 3 with a language syntax that matches one of the two
+Python versions: one may use
+
+ - a Python 2 (by syntax) module in a Python 3 project.
+
+ - a Python 3 (by syntax) module in a `Python 2' project.
+
+Because of the bi-directionality, python-future(9) offers a pathway to
+converting a Python 2 package to Python 3 syntax module-by-module.
+However, in contrast to six(10), python-future(11) is supported only
+from Python 2.6. Similar to modernize(12) for six(13),
+python-future(14) comes with two scripts called ‘futurize’ and
+‘pasteurize’ that can be applied to either a Python 2 module or a Python
+3 module respectively.
+
+Use of six(15) or python-future(16) adds an additional runtime
+dependency to your package: with python-future(17), the ‘futurize’
+script can be called with the ‘--stage1’ option to apply only the
+changes that Python 2.6+ already provides for forward-compatibility to
+Python 3. Any remaining compatibility problems would require manual
+changes.
+
+ ---------- Footnotes ----------
+
+ (1) http://pythonhosted.org/six/
+
+ (2) http://pythonhosted.org/six/
+
+ (3) http://pythonhosted.org/six/
+
+ (4) https://pypi.org/project/modernize
+
+ (5) http://pythonhosted.org/six/
+
+ (6) http://pythonhosted.org/six/
+
+ (7) http://python-future.org/overview.html
+
+ (8) http://pythonhosted.org/six/
+
+ (9) http://python-future.org/overview.html
+
+ (10) http://pythonhosted.org/six/
+
+ (11) http://python-future.org/overview.html
+
+ (12) https://pypi.org/project/modernize
+
+ (13) http://pythonhosted.org/six/
+
+ (14) http://python-future.org/overview.html
+
+ (15) http://pythonhosted.org/six/
+
+ (16) http://python-future.org/overview.html
+
+ (17) http://python-future.org/overview.html
+
+
+File: pythonpackagingguide.info, Node: What’s in which Python?, Prev: Tools for single-source Python packages, Up: Supporting multiple Python versions
+
+3.10.3 What’s in which Python?
+------------------------------
+
+Ned Batchelder provides a list of changes in each Python release for
+Python 2(1), Python 3.0-3.3(2) and Python 3.4-3.6(3). These lists may
+be used to check whether any changes between Python versions may affect
+your package.
+
+ TODO These lists should be reproduced here (with permission).
+
+ TODO The py3 list should be updated to include 3.4
+
+ ---------- Footnotes ----------
+
+ (1) https://nedbatchelder.com/blog/201109/whats_in_which_python.html
+
+ (2)
+https://nedbatchelder.com/blog/201310/whats_in_which_python_3.html
+
+ (3)
+https://nedbatchelder.com/blog/201803/whats_in_which_python_3436.html
+
+
+File: pythonpackagingguide.info, Node: Dropping support for older Python versions, Next: Packaging binary extensions, Prev: Supporting multiple Python versions, Up: Guides
+
+3.11 Dropping support for older Python versions
+===============================================
+
+Dropping support for older Python versions is supported by the standard
+*note Core metadata specifications: 85. 1.2 specification via a
+“Requires-Python” attribute.
+
+Metadata 1.2+ clients, such as Pip 9.0+, will adhere to this
+specification by matching the current Python runtime and comparing it
+with the required version in the package metadata. If they do not
+match, it will attempt to install the last package distribution that
+supported that Python runtime.
+
+This mechanism can be used to drop support for older Python versions, by
+amending the “Requires-Python” attribute in the package metadata.
+
+This guide is specifically for users of *note setuptools: 2d, other
+packaging tools such as ‘flit’ may offer similar functionality but users
+will need to consult relevant documentation.
+
+* Menu:
+
+* Requirements::
+* Defining the Python version required::
+* Dropping a Python release::
+
+
+File: pythonpackagingguide.info, Node: Requirements, Next: Defining the Python version required, Up: Dropping support for older Python versions
+
+3.11.1 Requirements
+-------------------
+
+This workflow requires that:
+
+ 1. The publisher is using the latest version of *note setuptools: 2d,
+
+ 2. The latest version of *note twine: 66. is used to upload the
+ package,
+
+ 3. The user installing the package has at least Pip 9.0, or a client
+ that supports the Metadata 1.2 specification.
+
+
+File: pythonpackagingguide.info, Node: Defining the Python version required, Next: Dropping a Python release, Prev: Requirements, Up: Dropping support for older Python versions
+
+3.11.2 Defining the Python version required
+-------------------------------------------
+
+* Menu:
+
+* 1. Download the newest version of Setuptools: 1 Download the newest version of Setuptools.
+* 2. Specify the version ranges for supported Python distributions: 2 Specify the version ranges for supported Python distributions.
+* 3. Validating the Metadata before publishing: 3 Validating the Metadata before publishing.
+* 4. Using Twine to publish: 4 Using Twine to publish.
+
+
+File: pythonpackagingguide.info, Node: 1 Download the newest version of Setuptools, Next: 2 Specify the version ranges for supported Python distributions, Up: Defining the Python version required
+
+3.11.2.1 1. Download the newest version of Setuptools
+.....................................................
+
+Ensure that before you generate source distributions or binary
+distributions, you update Setuptools and install twine.
+
+Steps:
+
+ pip install --upgrade setuptools twine
+
+*note setuptools: 2d. version should be above 24.0.0.
+
+
+File: pythonpackagingguide.info, Node: 2 Specify the version ranges for supported Python distributions, Next: 3 Validating the Metadata before publishing, Prev: 1 Download the newest version of Setuptools, Up: Defining the Python version required
+
+3.11.2.2 2. Specify the version ranges for supported Python distributions
+.........................................................................
+
+You can specify version ranges and exclusion rules, such as at least
+Python 3. Or, Python 2.7, 3.4 and beyond.
+
+Examples:
+
+ Requires-Python: ">=3"
+ Requires-Python: ">2.7,!=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
+
+The way to set those values is within the call to ‘setup’ within your
+‘setup.py’ script. This will insert the ‘Requires-Python’ metadata
+values based on the argument you provide in ‘python_requires’.
+
+ from setuptools import setup
+
+
+ setup(
+ # Your setup arguments
+ python_requires='>=2.7', # Your supported Python ranges
+ )
+
+
+File: pythonpackagingguide.info, Node: 3 Validating the Metadata before publishing, Next: 4 Using Twine to publish, Prev: 2 Specify the version ranges for supported Python distributions, Up: Defining the Python version required
+
+3.11.2.3 3. Validating the Metadata before publishing
+.....................................................
+
+Within a Python source package (the zip or the tar-gz file you download)
+is a text file called PKG-INFO.
+
+This file is generated by Distutils or *note setuptools: 2d. when it
+generates the source package. The file contains a set of keys and
+values, the list of keys is part of the PyPa standard metadata format.
+
+You can see the contents of the generated file like this:
+
+ tar xfO dist/my-package-1.0.0.tar.gz my-package-1.0.0/PKG-INFO
+
+Validate that the following is in place, before publishing the package:
+
+ - If you have upgraded correctly, the Metadata-Version value should
+ be 1.2 or higher.
+
+ - The Requires-Python field is set and matches your specification in
+ setup.py.
+
+
+File: pythonpackagingguide.info, Node: 4 Using Twine to publish, Prev: 3 Validating the Metadata before publishing, Up: Defining the Python version required
+
+3.11.2.4 4. Using Twine to publish
+..................................
+
+Twine has a number of advantages, apart from being faster it is now the
+supported method for publishing packages.
+
+Make sure you are using the newest version of Twine, at least 1.9.
+
+
+File: pythonpackagingguide.info, Node: Dropping a Python release, Prev: Defining the Python version required, Up: Dropping support for older Python versions
+
+3.11.3 Dropping a Python release
+--------------------------------
+
+Once you have published a package with the Requires-Python metadata, you
+can then make a further update removing that Python runtime from
+support.
+
+It must be done in this order for the automated fallback to work.
+
+For example, you published the Requires-Python: “>=2.7” as version 1.0.0
+of your package.
+
+If you were then to update the version string to “>=3.5”, and publish a
+new version 2.0.0 of your package, any users running Pip 9.0+ from
+version 2.7 will have version 1.0.0 of the package installed, and any
+>=3.5 users will receive version 2.0.0.
+
+
+File: pythonpackagingguide.info, Node: Packaging binary extensions, Next: Supporting Windows using Appveyor, Prev: Dropping support for older Python versions, Up: Guides
+
+3.12 Packaging binary extensions
+================================
+
+
+Page Status: Incomplete
+
+
+Last Reviewed: 2013-12-08
+
+One of the features of the CPython reference interpreter is that, in
+addition to allowing the execution of Python code, it also exposes a
+rich C API for use by other software. One of the most common uses of
+this C API is to create importable C extensions that allow things which
+aren’t always easy to achieve in pure Python code.
+
+* Menu:
+
+* An overview of binary extensions::
+* Implementing binary extensions::
+* Building binary extensions::
+* Publishing binary extensions::
+* Additional resources::
+
+
+File: pythonpackagingguide.info, Node: An overview of binary extensions, Next: Implementing binary extensions, Up: Packaging binary extensions
+
+3.12.1 An overview of binary extensions
+---------------------------------------
+
+* Menu:
+
+* Use cases::
+* Disadvantages::
+* Alternatives to handcoded accelerator modules::
+* Alternatives to handcoded wrapper modules::
+* Alternatives for low level system access::
+
+
+File: pythonpackagingguide.info, Node: Use cases, Next: Disadvantages, Up: An overview of binary extensions
+
+3.12.1.1 Use cases
+..................
+
+The typical use cases for binary extensions break down into just three
+conventional categories:
+
+ * `accelerator modules': these modules are completely self-contained,
+ and are created solely to run faster than the equivalent pure
+ Python code runs in CPython. Ideally, accelerator modules will
+ always have a pure Python equivalent to use as a fallback if the
+ accelerated version isn’t available on a given system. The CPython
+ standard library makes extensive use of accelerator modules.
+ `Example': When importing ‘datetime’, Python falls back to the
+ datetime.py(1) module if the C implementation (
+ _datetimemodule.c(2)) is not available.
+
+ * `wrapper modules': these modules are created to expose existing C
+ interfaces to Python code. They may either expose the underlying C
+ interface directly, or else expose a more “Pythonic” API that makes
+ use of Python language features to make the API easier to use. The
+ CPython standard library makes extensive use of wrapper modules.
+ `Example': functools.py(3) is a Python module wrapper for
+ _functoolsmodule.c(4).
+
+ * `low-level system access': these modules are created to access
+ lower level features of the CPython runtime, the operating system,
+ or the underlying hardware. Through platform specific code,
+ extension modules may achieve things that aren’t possible in pure
+ Python code. A number of CPython standard library modules are
+ written in C in order to access interpreter internals that aren’t
+ exposed at the language level. `Example': ‘sys’, which comes from
+ sysmodule.c(5).
+
+ One particularly notable feature of C extensions is that, when they
+ don’t need to call back into the interpreter runtime, they can
+ release CPython’s global interpreter lock around long-running
+ operations (regardless of whether those operations are CPU or IO
+ bound).
+
+Not all extension modules will fit neatly into the above categories.
+The extension modules included with NumPy, for example, span all three
+use cases - they move inner loops to C for speed reasons, wrap external
+libraries written in C, FORTRAN and other languages, and use low level
+system interfaces for both CPython and the underlying operation system
+to support concurrent execution of vectorised operations and to tightly
+control the exact memory layout of created objects.
+
+ ---------- Footnotes ----------
+
+ (1) https://github.com/python/cpython/blob/master/Lib/datetime.py
+
+ (2)
+https://github.com/python/cpython/blob/master/Modules/_datetimemodule.c
+
+ (3) https://github.com/python/cpython/blob/master/Lib/functools.py
+
+ (4)
+https://github.com/python/cpython/blob/master/Modules/_functoolsmodule.c
+
+ (5) https://github.com/python/cpython/blob/master/Python/sysmodule.c
+
+
+File: pythonpackagingguide.info, Node: Disadvantages, Next: Alternatives to handcoded accelerator modules, Prev: Use cases, Up: An overview of binary extensions
+
+3.12.1.2 Disadvantages
+......................
+
+The main disadvantage of using binary extensions is the fact that it
+makes subsequent distribution of the software more difficult. One of
+the advantages of using Python is that it is largely cross platform, and
+the languages used to write extension modules (typically C or C++, but
+really any language that can bind to the CPython C API) typically
+require that custom binaries be created for different platforms.
+
+This means that binary extensions:
+
+ * require that end users be able to either build them from source, or
+ else that someone publish pre-built binaries for common platforms
+
+ * may not be compatible with different builds of the CPython
+ reference interpreter
+
+ * often will not work correctly with alternative interpreters such as
+ PyPy, IronPython or Jython
+
+ * if handcoded, make maintenance more difficult by requiring that
+ maintainers be familiar not only with Python, but also with the
+ language used to create the binary extension, as well as with the
+ details of the CPython C API.
+
+ * if a pure Python fallback implementation is provided, make
+ maintenance more difficult by requiring that changes be implemented
+ in two places, and introducing additional complexity in the test
+ suite to ensure both versions are always executed.
+
+Another disadvantage of relying on binary extensions is that alternative
+import mechanisms (such as the ability to import modules directly from
+zipfiles) often won’t work for extension modules (as the dynamic loading
+mechanisms on most platforms can only load libraries from disk).
+
+
+File: pythonpackagingguide.info, Node: Alternatives to handcoded accelerator modules, Next: Alternatives to handcoded wrapper modules, Prev: Disadvantages, Up: An overview of binary extensions
+
+3.12.1.3 Alternatives to handcoded accelerator modules
+......................................................
+
+When extension modules are just being used to make code run faster
+(after profiling has identified the code where the speed increase is
+worth additional maintenance effort), a number of other alternatives
+should also be considered:
+
+ * look for existing optimised alternatives. The CPython standard
+ libary includes a number of optimised data structures and
+ algorithms (especially in the builtins and the ‘collections’ and
+ ‘itertools’ modules). The Python Package Index also offers
+ additional alternatives. Sometimes, the appropriate choice of
+ standard library or third party module can avoid the need to create
+ your own accelerator module.
+
+ * for long running applications, the JIT compiled PyPy interpreter(1)
+ may offer a suitable alternative to the standard CPython runtime.
+ The main barrier to adopting PyPy is typically reliance on other
+ binary extension modules - while PyPy does emulate the CPython C
+ API, modules that rely on that cause problems for the PyPy JIT, and
+ the emulation layer can often expose latent defects in extension
+ modules that CPython currently tolerates (frequently around
+ reference counting errors - an object having one live reference
+ instead of two often won’t break anything, but no references
+ instead of one is a major problem).
+
+ * Cython(2) is a mature static compiler that can compile most Python
+ code to C extension modules. The initial compilation provides some
+ speed increases (by bypassing the CPython interpreter layer), and
+ Cython’s optional static typing features can offer additional
+ opportunities for speed increases. Using Cython still has the
+ disadvantage of increasing the complexity of distributing the
+ resulting application, but has the benefit of having a reduced
+ barrier to entry for Python programmers (relative to other
+ languages like C or C++).
+
+ * Numba(3) is a newer tool, created by members of the scientific
+ Python community, that aims to leverage LLVM to allow selective
+ compilation of pieces of a Python application to native machine
+ code at runtime. It requires that LLVM be available on the system
+ where the code is running, but can provide significant speed
+ increases, especially for operations that are amenable to
+ vectorisation.
+
+ ---------- Footnotes ----------
+
+ (1) http://pypy.org/
+
+ (2) http://cython.org/
+
+ (3) http://numba.pydata.org/
+
+
+File: pythonpackagingguide.info, Node: Alternatives to handcoded wrapper modules, Next: Alternatives for low level system access, Prev: Alternatives to handcoded accelerator modules, Up: An overview of binary extensions
+
+3.12.1.4 Alternatives to handcoded wrapper modules
+..................................................
+
+The C ABI (Application Binary Interface) is a common standard for
+sharing functionality between multiple applications. One of the
+strengths of the CPython C API (Application Programming Interface) is
+allowing Python users to tap into that functionality. However, wrapping
+modules by hand is quite tedious, so a number of other alternative
+approaches should be considered.
+
+The approaches described below don’t simplify the distribution case at
+all, but they `can' significantly reduce the maintenance burden of
+keeping wrapper modules up to date.
+
+ * In addition to being useful for the creation of accelerator
+ modules, Cython(1) is also useful for creating wrapper modules. It
+ still involves wrapping the interfaces by hand, however, so may not
+ be a good choice for wrapping large APIs.
+
+ * cffi(2) is a project created by some of the PyPy developers to make
+ it straightforward for developers that already know both Python and
+ C to expose their C modules to Python applications. It also makes
+ it relatively straightforward to wrap a C module based on its
+ header files, even if you don’t know C yourself.
+
+ One of the key advantages of ‘cffi’ is that it is compatible with
+ the PyPy JIT, allowing CFFI wrapper modules to participate fully in
+ PyPy’s tracing JIT optimisations.
+
+ * SWIG(3) is a wrapper interface generator that allows a variety of
+ programming languages, including Python, to interface with C `and
+ C++' code.
+
+ * The standard library’s ‘ctypes’ module, while useful for getting
+ access to C level interfaces when header information isn’t
+ available, suffers from the fact that it operates solely at the C
+ ABI level, and thus has no automatic consistency checking between
+ the interface actually being exported by the library and the one
+ declared in the Python code. By contrast, the above alternatives
+ are all able to operate at the C `API' level, using C header files
+ to ensure consistency between the interface exported by the library
+ being wrapped and the one expected by the Python wrapper module.
+ While ‘cffi’ `can' operate directly at the C ABI level, it suffers
+ from the same interface inconsistency problems as ‘ctypes’ when it
+ is used that way.
+
+ ---------- Footnotes ----------
+
+ (1) http://cython.org/
+
+ (2) https://cffi.readthedocs.io/
+
+ (3) http://www.swig.org/
+
+
+File: pythonpackagingguide.info, Node: Alternatives for low level system access, Prev: Alternatives to handcoded wrapper modules, Up: An overview of binary extensions
+
+3.12.1.5 Alternatives for low level system access
+.................................................
+
+For applications that need low level system access (regardless of the
+reason), a binary extension module often `is' the best way to go about
+it. This is particularly true for low level access to the CPython
+runtime itself, since some operations (like releasing the Global
+Interpreter Lock) are simply invalid when the interpreter is running
+code, even if a module like ‘ctypes’ or ‘cffi’ is used to obtain access
+to the relevant C API interfaces.
+
+For cases where the extension module is manipulating the underlying
+operating system or hardware (rather than the CPython runtime), it may
+sometimes be better to just write an ordinary C library (or a library in
+another systems programming language like C++ or Rust that can export a
+C compatible ABI), and then use one of the wrapping techniques described
+above to make the interface available as an importable Python module.
+
+
+File: pythonpackagingguide.info, Node: Implementing binary extensions, Next: Building binary extensions, Prev: An overview of binary extensions, Up: Packaging binary extensions
+
+3.12.2 Implementing binary extensions
+-------------------------------------
+
+The CPython Extending and Embedding(1) guide includes an introduction to
+writing a custom extension module in C(2).
+
+ mention the stable ABI (3.2+, link to the CPython C API docs)
+ mention the module lifecycle
+ mention the challenges of shared static state and subinterpreters
+ mention the implications of the GIL for extension modules
+ mention the memory allocation APIs in 3.4+
+
+ mention again that all this is one of the reasons why you probably
+ *don't* want to handcode your extension modules :)
+
+ ---------- Footnotes ----------
+
+ (1) https://docs.python.org/3/extending/
+
+ (2) https://docs.python.org/3/extending/extending.html
+
+
+File: pythonpackagingguide.info, Node: Building binary extensions, Next: Publishing binary extensions, Prev: Implementing binary extensions, Up: Packaging binary extensions
+
+3.12.3 Building binary extensions
+---------------------------------
+
+* Menu:
+
+* Binary extensions for Windows::
+* Binary extensions for Linux::
+* Binary extensions for macOS::
+
+
+File: pythonpackagingguide.info, Node: Binary extensions for Windows, Next: Binary extensions for Linux, Up: Building binary extensions
+
+3.12.3.1 Binary extensions for Windows
+......................................
+
+Before it is possible to build a binary extension, it is necessary to
+ensure that you have a suitable compiler available. On Windows, Visual
+C is used to build the official CPython interpreter, and should be used
+to build compatible binary extensions.
+
+Python 2.7 used Visual Studio 2008, Python 3.3 and 3.4 used Visual
+Studio 2010, and Python 3.5+ uses Visual Studio 2015 or later.
+Unfortunately, older versions of Visual Studio are no longer easily
+available from Microsoft, so for versions of Python prior to 3.5, the
+compilers must be obtained differently if you do not already have a copy
+of the relevant version of Visual Studio.
+
+To set up a build environment for binary extensions, the steps are as
+follows:
+
+ For Python 2.7
+
+ 1. Install “Visual C++ Compiler Package for Python 2.7”,
+ which is available from Microsoft’s website(1).
+
+ 2. Use (a recent version of) setuptools in your setup.py
+ (pip will do this for you, in any case).
+
+ 3. Done.
+
+ For Python 3.4
+
+ 1. Install “Windows SDK for Windows 7 and .NET Framework 4”
+ (v7.1), which is available from Microsoft’s website(2).
+
+ 2. Work from an SDK command prompt (with the environment
+ variables set, and the SDK on PATH).
+
+ 3. Set DISTUTILS_USE_SDK=1
+
+ 4. Done.
+
+ For Python 3.5
+
+ 1. Install Visual Studio 2015 Community Edition(3) (or any
+ later version, when these are released).
+
+ 2. Done.
+
+Note that from Python 3.5 onwards, Visual Studio works in a backward
+compatible way, which means that any future version of Visual Studio
+will be able to build Python extensions for all Python versions from 3.5
+onwards.
+
+Building with the recommended compiler on Windows ensures that a
+compatible C library is used throughout the Python process.
+
+ ---------- Footnotes ----------
+
+ (1) https://www.microsoft.com/en-gb/download/details.aspx?id=44266
+
+ (2) https://www.microsoft.com/en-gb/download/details.aspx?id=8279
+
+ (3)
+https://www.visualstudio.com/en-us/downloads/download-visual-studio-vs.aspx
+
+
+File: pythonpackagingguide.info, Node: Binary extensions for Linux, Next: Binary extensions for macOS, Prev: Binary extensions for Windows, Up: Building binary extensions
+
+3.12.3.2 Binary extensions for Linux
+....................................
+
+Linux binaries must use a sufficiently old glibc to be compatible with
+older distributions. The manylinux(1) Docker images provide a build
+environment with a glibc old enough to support most current Linux
+distributions on common architectures.
+
+ ---------- Footnotes ----------
+
+ (1) https://github.com/pypa/manylinux
+
+
+File: pythonpackagingguide.info, Node: Binary extensions for macOS, Prev: Binary extensions for Linux, Up: Building binary extensions
+
+3.12.3.3 Binary extensions for macOS
+....................................
+
+Binary compatibility on macOS is determined by the target minimum
+deployment system, e.g. `10.9', which is often specified with the
+‘MACOSX_DEPLOYMENT_TARGET’ environmental variable when building binaries
+on macOS. When building with setuptools / distutils, the deployment
+target is specified with the flag ‘--plat-name’, e.g.
+‘macosx-10.9-x86_64’. For common deployment targets for macOS Python
+distributions, see the MacPython Spinning Wheels wiki(1).
+
+ ---------- Footnotes ----------
+
+ (1) https://github.com/MacPython/wiki/wiki/Spinning-wheels
+
+
+File: pythonpackagingguide.info, Node: Publishing binary extensions, Next: Additional resources, Prev: Building binary extensions, Up: Packaging binary extensions
+
+3.12.4 Publishing binary extensions
+-----------------------------------
+
+For interim guidance on this topic, see the discussion in this issue(1).
+
+ FIXME
+
+ cover publishing as wheel files on PyPI or a custom index server
+ cover creation of Windows and macOS installers
+ cover weak linking
+ mention the fact that Linux distros have a requirement to build from
+ source in their own build systems, so binary-only releases are strongly
+ discouraged
+
+ ---------- Footnotes ----------
+
+ (1) https://github.com/pypa/python-packaging-user-guide/issues/284
+
+
+File: pythonpackagingguide.info, Node: Additional resources, Prev: Publishing binary extensions, Up: Packaging binary extensions
+
+3.12.5 Additional resources
+---------------------------
+
+Cross-platform development and distribution of extension modules is a
+complex topic, so this guide focuses primarily on providing pointers to
+various tools that automate dealing with the underlying technical
+challenges. The additional resources in this section are instead
+intended for developers looking to understand more about the underlying
+binary interfaces that those systems rely on at runtime.
+
+* Menu:
+
+* Cross-platform wheel generation with scikit-build::
+* Introduction to C/C++ extension modules::
+
+
+File: pythonpackagingguide.info, Node: Cross-platform wheel generation with scikit-build, Next: Introduction to C/C++ extension modules, Up: Additional resources
+
+3.12.5.1 Cross-platform wheel generation with scikit-build
+..........................................................
+
+The scikit-build(1) package helps abstract cross-platform build
+operations and provides additional capabilities when creating binary
+extension packages. Additional documentation is also available on the C
+runtime, compiler, and build system generator(2) for Python binary
+extension modules.
+
+ ---------- Footnotes ----------
+
+ (1) https://scikit-build.readthedocs.io/en/latest/
+
+ (2) https://scikit-build.readthedocs.io/en/latest/generators.html
+
+
+File: pythonpackagingguide.info, Node: Introduction to C/C++ extension modules, Prev: Cross-platform wheel generation with scikit-build, Up: Additional resources
+
+3.12.5.2 Introduction to C/C++ extension modules
+................................................
+
+For a more in depth explanation of how extension modules are used by
+CPython on a Debian system, see the following articles:
+
+ * What are (c)python extension modules?(1)
+
+ * Releasing the gil(2)
+
+ * Writing cpython extension modules using C++(3)
+
+ ---------- Footnotes ----------
+
+ (1) https://thomasnyberg.com/what_are_extension_modules.html
+
+ (2) https://thomasnyberg.com/releasing_the_gil.html
+
+ (3) https://thomasnyberg.com/cpp_extension_modules.html
+
+
+File: pythonpackagingguide.info, Node: Supporting Windows using Appveyor, Next: Packaging namespace packages, Prev: Packaging binary extensions, Up: Guides
+
+3.13 Supporting Windows using Appveyor
+======================================
+
+
+Page Status: Incomplete
+
+
+Last Reviewed: 2015-12-03
+
+This section covers how to use the free Appveyor(1) continuous
+integration service to provide Windows support for your project. This
+includes testing the code on Windows, and building Windows-targeted
+binaries for projects that use C extensions.
+
+* Menu:
+
+* Background::
+* Setting up::
+* Adding Appveyor support to your project::
+* Additional notes::
+
+ ---------- Footnotes ----------
+
+ (1) http://www.appveyor.com/
+
+
+File: pythonpackagingguide.info, Node: Background, Next: Setting up, Up: Supporting Windows using Appveyor
+
+3.13.1 Background
+-----------------
+
+Many projects are developed on Unix by default, and providing Windows
+support can be a challenge, because setting up a suitable Windows test
+environment is non-trivial, and may require buying software licenses.
+
+The Appveyor service is a continuous integration service, much like the
+better-known Travis(1) service that is commonly used for testing by
+projects hosted on Github(2). However, unlike Travis, the build workers
+on Appveyor are Windows hosts and have the necessary compilers installed
+to build Python extensions.
+
+Windows users typically do not have access to a C compiler, and
+therefore are reliant on projects that use C extensions distributing
+binary wheels on PyPI in order for the distribution to be installable
+via ‘pip install <dist>’. By using Appveyor as a build service (even if
+not using it for testing) it is possible for projects without a
+dedicated Windows environment to provide Windows-targeted binaries.
+
+ ---------- Footnotes ----------
+
+ (1) https://travis-ci.org/
+
+ (2) https://github.org/
+
+
+File: pythonpackagingguide.info, Node: Setting up, Next: Adding Appveyor support to your project, Prev: Background, Up: Supporting Windows using Appveyor
+
+3.13.2 Setting up
+-----------------
+
+In order to use Appveyor to build Windows wheels for your project, you
+must have an account on the service. Instructions on setting up an
+account are given in the Appveyor documentation(1). The free tier of
+account is perfectly adequate for open source projects.
+
+Appveyor provides integration with Github(2) and Bitbucket(3), so as
+long as your project is hosted on one of those two services, setting up
+Appveyor integration is straightforward.
+
+Once you have set up your Appveyor account and added your project,
+Appveyor will automatically build your project each time a commit
+occurs. This behaviour will be familiar to users of Travis.
+
+ ---------- Footnotes ----------
+
+ (1) http://www.appveyor.com/docs
+
+ (2) https://github.org/
+
+ (3) https://bitbucket.org/
+
+
+File: pythonpackagingguide.info, Node: Adding Appveyor support to your project, Next: Additional notes, Prev: Setting up, Up: Supporting Windows using Appveyor
+
+3.13.3 Adding Appveyor support to your project
+----------------------------------------------
+
+In order to define how Appveyor should build your project, you need to
+add an ‘appveyor.yml’ file to your project. The full details of what
+can be included in the file are covered in the Appveyor documentation.
+This guide will provide the details necessary to set up wheel builds.
+
+Appveyor includes by default all of the compiler toolchains needed to
+build extensions for Python. For Python 2.7, 3.5+ and 32-bit versions
+of 3.3 and 3.4, the tools work out of the box. But for 64-bit versions
+of Python 3.3 and 3.4, there is a small amount of additional
+configuration needed to let distutils know where to find the 64-bit
+compilers. (From 3.5 onwards, the version of Visual Studio used
+includes 64-bit compilers with no additional setup).
+
+* Menu:
+
+* appveyor.yml: appveyor yml.
+* Support script::
+* Access to the built wheels::
+
+
+File: pythonpackagingguide.info, Node: appveyor yml, Next: Support script, Up: Adding Appveyor support to your project
+
+3.13.3.1 appveyor.yml
+.....................
+
+ environment:
+
+ matrix:
+
+ # For Python versions available on Appveyor, see
+ # https://www.appveyor.com/docs/windows-images-software/#python
+ # The list here is complete (excluding Python 2.6, which
+ # isn't covered by this document) at the time of writing.
+
+ - PYTHON: "C:\\Python27"
+ - PYTHON: "C:\\Python33"
+ - PYTHON: "C:\\Python34"
+ - PYTHON: "C:\\Python35"
+ - PYTHON: "C:\\Python27-x64"
+ - PYTHON: "C:\\Python33-x64"
+ DISTUTILS_USE_SDK: "1"
+ - PYTHON: "C:\\Python34-x64"
+ DISTUTILS_USE_SDK: "1"
+ - PYTHON: "C:\\Python35-x64"
+ - PYTHON: "C:\\Python36-x64"
+
+ install:
+ # We need wheel installed to build wheels
+ - "%PYTHON%\\python.exe -m pip install wheel"
+
+ build: off
+
+ test_script:
+ # Put your test command here.
+ # If you don't need to build C extensions on 64-bit Python 3.3 or 3.4,
+ # you can remove "build.cmd" from the front of the command, as it's
+ # only needed to support those cases.
+ # Note that you must use the environment variable %PYTHON% to refer to
+ # the interpreter you're using - Appveyor does not do anything special
+ # to put the Python version you want to use on PATH.
+ - "build.cmd %PYTHON%\\python.exe setup.py test"
+
+ after_test:
+ # This step builds your wheels.
+ # Again, you only need build.cmd if you're building C extensions for
+ # 64-bit Python 3.3/3.4. And you need to use %PYTHON% to get the correct
+ # interpreter
+ - "build.cmd %PYTHON%\\python.exe setup.py bdist_wheel"
+
+ artifacts:
+ # bdist_wheel puts your built wheel in the dist directory
+ - path: dist\*
+
+ #on_success:
+ # You can use this step to upload your artifacts to a public website.
+ # See Appveyor's documentation for more details. Or you can simply
+ # access your wheels from the Appveyor "artifacts" tab for your build.
+
+This file can be downloaded from here(1).
+
+The ‘appveyor.yml’ file must be located in the root directory of your
+project. It is in ‘YAML’ format, and consists of a number of sections.
+
+The ‘environment’ section is the key to defining the Python versions for
+which your wheels will be created. Appveyor comes with Python 2.6, 2.7,
+3.3, 3.4 and 3.5 installed, in both 32-bit and 64-bit builds. The
+example file builds for all of these environments except Python 2.6.
+Installing for Python 2.6 is more complex, as it does not come with pip
+included. We don’t support 2.6 in this document (as Windows users still
+using Python 2 are generally able to move to Python 2.7 without too much
+difficulty).
+
+The ‘install’ section uses pip to install any additional software that
+the project may require. The only requirement for building wheels is
+the ‘wheel’ project, but projects may wish to customise this code in
+certain circumstances (for example, to install additional build packages
+such as ‘Cython’, or test tools such as ‘tox’).
+
+The ‘build’ section simply switches off builds - there is no build step
+needed for Python, unlike languages like ‘C#’.
+
+The main sections that will need to be tailored to your project are
+‘test_script’ and ‘after_test’.
+
+The ‘test_script’ section is where you will run your project’s tests.
+The supplied file runs your test suite using ‘setup.py test’. If you
+are only interested in building wheels, and not in running your tests on
+Windows, you can replace this section with a dummy command such as ‘echo
+Skipped Tests’. You may wish to use another test tool, such as ‘nose’
+or ‘py.test’. Or you may wish to use a test driver like ‘tox’ - however
+if you are using ‘tox’ there are some additional configuration changes
+you will need to consider, which are described below.
+
+The ‘after_test’ runs once your tests have completed, and so is where
+the wheels should be built. Assuming your project uses the recommended
+tools (specifically, ‘setuptools’) then the ‘setup.py bdist_wheel’
+command will build your wheels.
+
+Note that wheels will only be built if your tests succeed. If you
+expect your tests to fail on Windows, you can skip them as described
+above.
+
+ ---------- Footnotes ----------
+
+ (1)
+https://raw.githubusercontent.com/pypa/python-packaging-user-guide/master/source/guides/appveyor-sample/appveyor.yml
+
+
+File: pythonpackagingguide.info, Node: Support script, Next: Access to the built wheels, Prev: appveyor yml, Up: Adding Appveyor support to your project
+
+3.13.3.2 Support script
+.......................
+
+The ‘appveyor.yml’ file relies on a single support script, which sets up
+the environment to use the SDK compiler for 64-bit builds on Python 3.3
+and 3.4. For projects which do not need a compiler, or which don’t
+support 3.3 or 3.4 on 64-bit Windows, only the ‘appveyor.yml’ file is
+needed.
+
+build.cmd(1) is a Windows batch script that runs a single command in an
+environment with the appropriate compiler for the selected Python
+version. All you need to do is to set the single environment variable
+‘DISTUTILS_USE_SDK’ to a value of ‘1’ and the script does the rest. It
+sets up the SDK needed for 64-bit builds of Python 3.3 or 3.4, so don’t
+set the environment variable for any other builds.
+
+You can simply download the batch file and include it in your project
+unchanged.
+
+ ---------- Footnotes ----------
+
+ (1)
+https://raw.githubusercontent.com/pypa/python-packaging-user-guide/master/source/guides/appveyor-sample/build.cmd
+
+
+File: pythonpackagingguide.info, Node: Access to the built wheels, Prev: Support script, Up: Adding Appveyor support to your project
+
+3.13.3.3 Access to the built wheels
+...................................
+
+When your build completes, the built wheels will be available from the
+Appveyor control panel for your project. They can be found by going to
+the build status page for each build in turn. At the top of the build
+output there is a series of links, one of which is “Artifacts”. That
+page will include a list of links to the wheels for that Python version
+/ architecture. You can download those wheels and upload them to PyPI
+as part of your release process.
+
+
+File: pythonpackagingguide.info, Node: Additional notes, Prev: Adding Appveyor support to your project, Up: Supporting Windows using Appveyor
+
+3.13.4 Additional notes
+-----------------------
+
+* Menu:
+
+* Testing with tox::
+* Automatically uploading wheels::
+* External dependencies::
+* Support scripts::
+
+
+File: pythonpackagingguide.info, Node: Testing with tox, Next: Automatically uploading wheels, Up: Additional notes
+
+3.13.4.1 Testing with tox
+.........................
+
+Many projects use the Tox(1) tool to run their tests. It ensures that
+tests are run in an isolated environment using the exact files that will
+be distributed by the project.
+
+In order to use ‘tox’ on Appveyor there are a couple of additional
+considerations (in actual fact, these issues are not specific to
+Appveyor, and may well affect other CI systems).
+
+ 1. By default, ‘tox’ only passes a chosen subset of environment
+ variables to the test processes. Because ‘distutils’ uses
+ environment variables to control the compiler, this “test
+ isolation” feature will cause the tests to use the wrong compiler
+ by default.
+
+ To force ‘tox’ to pass the necessary environment variables to the
+ subprocess, you need to set the ‘tox’ configuration option
+ ‘passenv’ to list the additional environment variables to be passed
+ to the subprocess. For the SDK compilers, you need
+
+ - ‘DISTUTILS_USE_SDK’
+
+ - ‘MSSdk’
+
+ - ‘INCLUDE’
+
+ - ‘LIB’
+
+ The ‘passenv’ option can be set in your ‘tox.ini’, or if you
+ prefer to avoid adding Windows-specific settings to your
+ general project files, it can be set by setting the
+ ‘TOX_TESTENV_PASSENV’ environment variable. The supplied
+ ‘build.cmd’ script does this by default whenever
+ ‘DISTUTILS_USE_SDK’ is set.
+
+ 2. When used interactively, ‘tox’ allows you to run your tests against
+ multiple environments (often, this means multiple Python versions).
+ This feature is not as useful in a CI environment like Travis or
+ Appveyor, where all tests are run in isolated environments for each
+ configuration. As a result, projects often supply an argument ‘-e
+ ENVNAME’ to ‘tox’ to specify which environment to use (there are
+ default environments for most versions of Python).
+
+ However, this does `not' work well with a Windows CI system
+ like Appveyor, where there are (for example) two installations
+ of Python 3.4 (32-bit and 64-bit) available, but only one
+ ‘py34’ environment in ‘tox’.
+
+ In order to run tests using ‘tox’, therefore, projects should
+ probably use the default ‘py’ environment in ‘tox’, which uses
+ the Python interpreter that was used to run ‘tox’. This will
+ ensure that when Appveyor runs the tests, they will be run
+ with the configured interpreter.
+
+ In order to support running under the ‘py’ environment, it is
+ possible that projects with complex ‘tox’ configurations might
+ need to modify their ‘tox.ini’ file. Doing so is, however,
+ outside the scope of this document.
+
+ ---------- Footnotes ----------
+
+ (1) http://tox.testrun.org
+
+
+File: pythonpackagingguide.info, Node: Automatically uploading wheels, Next: External dependencies, Prev: Testing with tox, Up: Additional notes
+
+3.13.4.2 Automatically uploading wheels
+.......................................
+
+It is possible to request Appveyor to automatically upload wheels.
+There is a ‘deployment’ step available in ‘appveyor.yml’ that can be
+used to (for example) copy the built artifacts to a FTP site, or an
+Amazon S3 instance. Documentation on how to do this is included in the
+Appveyor guides.
+
+Alternatively, it would be possible to add a ‘twine upload’ step to the
+build. The supplied ‘appveyor.yml’ does not do this, as it is not clear
+that uploading new wheels after every commit is desirable (although some
+projects may wish to do this).
+
+
+File: pythonpackagingguide.info, Node: External dependencies, Next: Support scripts, Prev: Automatically uploading wheels, Up: Additional notes
+
+3.13.4.3 External dependencies
+..............................
+
+The supplied scripts will successfully build any distribution that does
+not rely on 3rd party external libraries for the build.
+
+It is possible to add steps to the ‘appveyor.yml’ configuration
+(typically in the “install” section) to download and/or build external
+libraries needed by the distribution. And if needed, it is possible to
+add extra configuration for the build to supply the location of these
+libraries to the compiler. However, this level of configuration is
+beyond the scope of this document.
+
+
+File: pythonpackagingguide.info, Node: Support scripts, Prev: External dependencies, Up: Additional notes
+
+3.13.4.4 Support scripts
+........................
+
+For reference, the SDK setup support script is listed here:
+
+‘appveyor-sample/build.cmd’
+
+ @echo off
+ :: To build extensions for 64 bit Python 3, we need to configure environment
+ :: variables to use the MSVC 2010 C++ compilers from GRMSDKX_EN_DVD.iso of:
+ :: MS Windows SDK for Windows 7 and .NET Framework 4
+ ::
+ :: More details at:
+ :: https://github.com/cython/cython/wiki/CythonExtensionsOnWindows
+
+ IF "%DISTUTILS_USE_SDK%"=="1" (
+ ECHO Configuring environment to build with MSVC on a 64bit architecture
+ ECHO Using Windows SDK 7.1
+ "C:\Program Files\Microsoft SDKs\Windows\v7.1\Setup\WindowsSdkVer.exe" -q -version:v7.1
+ CALL "C:\Program Files\Microsoft SDKs\Windows\v7.1\Bin\SetEnv.cmd" /x64 /release
+ SET MSSdk=1
+ REM Need the following to allow tox to see the SDK compiler
+ SET TOX_TESTENV_PASSENV=DISTUTILS_USE_SDK MSSdk INCLUDE LIB
+ ) ELSE (
+ ECHO Using default MSVC build environment
+ )
+
+ CALL %*
+
+
+File: pythonpackagingguide.info, Node: Packaging namespace packages, Next: Creating and discovering plugins, Prev: Supporting Windows using Appveyor, Up: Guides
+
+3.14 Packaging namespace packages
+=================================
+
+Namespace packages allow you to split the sub-packages and modules
+within a single *note package: a. across multiple, separate *note
+distribution packages: b. (referred to as `distributions' in this
+document to avoid ambiguity). For example, if you have the following
+package structure:
+
+ mynamespace/
+ __init__.py
+ subpackage_a/
+ __init__.py
+ ...
+ subpackage_b/
+ __init__.py
+ ...
+ module_b.py
+ setup.py
+
+And you use this package in your code like so:
+
+ from mynamespace import subpackage_a
+ from mynamespace import subpackage_b
+
+Then you can break these sub-packages into two separate distributions:
+
+ mynamespace-subpackage-a/
+ setup.py
+ mynamespace/
+ subpackage_a/
+ __init__.py
+
+ mynamespace-subpackage-b/
+ setup.py
+ mynamespace/
+ subpackage_b/
+ __init__.py
+ module_b.py
+
+Each sub-package can now be separately installed, used, and versioned.
+
+Namespace packages can be useful for a large collection of
+loosely-related packages (such as a large corpus of client libraries for
+multiple products from a single company). However, namespace packages
+come with several caveats and are not appropriate in all cases. A
+simple alternative is to use a prefix on all of your distributions such
+as ‘import mynamespace_subpackage_a’ (you could even use ‘import
+mynamespace_subpackage_a as subpackage_a’ to keep the import object
+short).
+
+* Menu:
+
+* Creating a namespace package::
+
+
+File: pythonpackagingguide.info, Node: Creating a namespace package, Up: Packaging namespace packages
+
+3.14.1 Creating a namespace package
+-----------------------------------
+
+There are currently three different approaches to creating namespace
+packages:
+
+ 1. Use *note native namespace packages: 134. This type of namespace
+ package is defined in PEP 420(1) and is available in Python 3.3 and
+ later. This is recommended if packages in your namespace only ever
+ need to support Python 3 and installation via ‘pip’.
+
+ 2. Use *note pkgutil-style namespace packages: 135. This is
+ recommended for new packages that need to support Python 2 and 3
+ and installation via both ‘pip’ and ‘python setup.py install’.
+
+ 3. Use *note pkg_resources-style namespace packages: 136. This method
+ is recommended if you need compatibility with packages already
+ using this method or if your package needs to be zip-safe.
+
+ Warning: While native namespace packages and pkgutil-style
+ namespace packages are largely compatible, pkg_resources-style
+ namespace packages are not compatible with the other methods. It’s
+ inadvisable to use different methods in different distributions
+ that provide packages to the same namespace.
+
+* Menu:
+
+* Native namespace packages::
+* pkgutil-style namespace packages::
+* pkg_resources-style namespace packages::
+
+ ---------- Footnotes ----------
+
+ (1) https://www.python.org/dev/peps/pep-0420
+
+
+File: pythonpackagingguide.info, Node: Native namespace packages, Next: pkgutil-style namespace packages, Up: Creating a namespace package
+
+3.14.1.1 Native namespace packages
+..................................
+
+Python 3.3 added `implicit' namespace packages from PEP 420(1). All
+that is required to create a native namespace package is that you just
+omit ‘__init__.py’ from the namespace package directory. An example
+file structure:
+
+ setup.py
+ mynamespace/
+ # No __init__.py here.
+ subpackage_a/
+ # Sub-packages have __init__.py.
+ __init__.py
+ module.py
+
+It is extremely important that every distribution that uses the
+namespace package omits the ‘__init__.py’ or uses a pkgutil-style
+‘__init__.py’. If any distribution does not, it will cause the
+namespace logic to fail and the other sub-packages will not be
+importable.
+
+Because ‘mynamespace’ doesn’t contain an ‘__init__.py’,
+‘setuptools.find_packages()’ won’t find the sub-package. You must use
+‘setuptools.find_namespace_packages()’ instead or explicitly list all
+packages in your ‘setup.py’. For example:
+
+ from setuptools import setup, find_namespace_packages
+
+ setup(
+ name='mynamespace-subpackage-a',
+ ...
+ packages=find_namespace_packages(include=['mynamespace.*'])
+ )
+
+A complete working example of two native namespace packages can be found
+in the native namespace package example project(2).
+
+ Note: Because native and pkgutil-style namespace packages are
+ largely compatible, you can use native namespace packages in the
+ distributions that only support Python 3 and pkgutil-style
+ namespace packages in the distributions that need to support Python
+ 2 and 3.
+
+ ---------- Footnotes ----------
+
+ (1) https://www.python.org/dev/peps/pep-0420
+
+ (2)
+https://github.com/pypa/sample-namespace-packages/tree/master/native
+
+
+File: pythonpackagingguide.info, Node: pkgutil-style namespace packages, Next: pkg_resources-style namespace packages, Prev: Native namespace packages, Up: Creating a namespace package
+
+3.14.1.2 pkgutil-style namespace packages
+.........................................
+
+Python 2.3 introduced the pkgutil(1) module and the extend_path(2)
+function. This can be used to declare namespace packages that need to
+be compatible with both Python 2.3+ and Python 3. This is the
+recommended approach for the highest level of compatibility.
+
+To create a pkgutil-style namespace package, you need to provide an
+‘__init__.py’ file for the namespace package:
+
+ setup.py
+ mynamespace/
+ __init__.py # Namespace package __init__.py
+ subpackage_a/
+ __init__.py # Sub-package __init__.py
+ module.py
+
+The ‘__init__.py’ file for the namespace package needs to contain `only'
+the following:
+
+ __path__ = __import__('pkgutil').extend_path(__path__, __name__)
+
+`Every' distribution that uses the namespace package must include an
+identical ‘__init__.py’. If any distribution does not, it will cause
+the namespace logic to fail and the other sub-packages will not be
+importable. Any additional code in ‘__init__.py’ will be inaccessible.
+
+A complete working example of two pkgutil-style namespace packages can
+be found in the pkgutil namespace example project(3).
+
+ ---------- Footnotes ----------
+
+ (1) https://docs.python.org/3/library/pkgutil.html
+
+ (2)
+https://docs.python.org/3/library/pkgutil.html#pkgutil.extend_path
+
+ (3)
+https://github.com/pypa/sample-namespace-packages/tree/master/pkgutil
+
+
+File: pythonpackagingguide.info, Node: pkg_resources-style namespace packages, Prev: pkgutil-style namespace packages, Up: Creating a namespace package
+
+3.14.1.3 pkg_resources-style namespace packages
+...............................................
+
+Setuptools(1) provides the pkg_resources.declare_namespace(2) function
+and the ‘namespace_packages’ argument to ‘setup()’. Together these can
+be used to declare namespace packages. While this approach is no longer
+recommended, it is widely present in most existing namespace packages.
+If you are creating a new distribution within an existing namespace
+package that uses this method then it’s recommended to continue using
+this as the different methods are not cross-compatible and it’s not
+advisable to try to migrate an existing package.
+
+To create a pkg_resources-style namespace package, you need to provide
+an ‘__init__.py’ file for the namespace package:
+
+ setup.py
+ mynamespace/
+ __init__.py # Namespace package __init__.py
+ subpackage_a/
+ __init__.py # Sub-package __init__.py
+ module.py
+
+The ‘__init__.py’ file for the namespace package needs to contain `only'
+the following:
+
+ __import__('pkg_resources').declare_namespace(__name__)
+
+`Every' distribution that uses the namespace package must include an
+identical ‘__init__.py’. If any distribution does not, it will cause
+the namespace logic to fail and the other sub-packages will not be
+importable. Any additional code in ‘__init__.py’ will be inaccessible.
+
+ Note: Some older recommendations advise the following in the
+ namespace package ‘__init__.py’:
+
+ try:
+ __import__('pkg_resources').declare_namespace(__name__)
+ except ImportError:
+ __path__ = __import__('pkgutil').extend_path(__path__, __name__)
+
+ The idea behind this was that in the rare case that setuptools
+ isn’t available packages would fall-back to the pkgutil-style
+ packages. This isn’t advisable because pkgutil and
+ pkg_resources-style namespace packages are not cross-compatible.
+ If the presence of setuptools is a concern then the package should
+ just explicitly depend on setuptools via ‘install_requires’.
+
+Finally, every distribution must provide the ‘namespace_packages’
+argument to ‘setup()’ in ‘setup.py’. For example:
+
+ from setuptools import find_packages, setup
+
+ setup(
+ name='mynamespace-subpackage-a',
+ ...
+ packages=find_packages()
+ namespace_packages=['mynamespace']
+ )
+
+A complete working example of two pkg_resources-style namespace packages
+can be found in the pkg_resources namespace example project(3).
+
+ ---------- Footnotes ----------
+
+ (1) https://setuptools.readthedocs.io
+
+ (2)
+https://setuptools.readthedocs.io/en/latest/setuptools.html#namespace-packages
+
+ (3)
+https://github.com/pypa/sample-namespace-packages/tree/master/pkg_resources
+
+
+File: pythonpackagingguide.info, Node: Creating and discovering plugins, Next: Analyzing PyPI package downloads, Prev: Packaging namespace packages, Up: Guides
+
+3.15 Creating and discovering plugins
+=====================================
+
+Often when creating a Python application or library you’ll want the
+ability to provide customizations or extra features via `plugins'.
+Because Python packages can be separately distributed, your application
+or library may want to automatically `discover' all of the plugins
+available.
+
+There are three major approaches to doing automatic plugin discovery:
+
+ 1. *note Using naming convention: 13b.
+
+ 2. *note Using namespace packages: 13c.
+
+ 3. *note Using package metadata: 13d.
+
+* Menu:
+
+* Using naming convention::
+* Using namespace packages::
+* Using package metadata::
+
+
+File: pythonpackagingguide.info, Node: Using naming convention, Next: Using namespace packages, Up: Creating and discovering plugins
+
+3.15.1 Using naming convention
+------------------------------
+
+If all of the plugins for your application follow the same naming
+convention, you can use pkgutil.iter_modules()(1) to discover all of the
+top-level modules that match the naming convention. For example,
+Flask(2) uses the naming convention ‘flask_{plugin_name}’. If you
+wanted to automatically discover all of the Flask plugins installed:
+
+ import importlib
+ import pkgutil
+
+ discovered_plugins = {
+ name: importlib.import_module(name)
+ for finder, name, ispkg
+ in pkgutil.iter_modules()
+ if name.startswith('flask_')
+ }
+
+If you had both the Flask-SQLAlchemy(3) and Flask-Talisman(4) plugins
+installed then ‘discovered_plugins’ would be:
+
+ {
+ 'flask_sqlachemy': <module: 'flask_sqlalchemy'>,
+ 'flask_talisman': <module: 'flask_talisman'>,
+ }
+
+Using naming convention for plugins also allows you to query the Python
+Package Index’s simple API(5) for all packages that conform to your
+naming convention.
+
+ ---------- Footnotes ----------
+
+ (1)
+https://docs.python.org/2/library/pkgutil.html#pkgutil.iter_modules
+
+ (2) https://pypi.org/project/Flask/
+
+ (3) https://pypi.org/project/Flask-SQLAlchemy/
+
+ (4) https://pypi.org/project/flask-talisman
+
+ (5) https://www.python.org/dev/peps/pep-0503/#specification
+
+
+File: pythonpackagingguide.info, Node: Using namespace packages, Next: Using package metadata, Prev: Using naming convention, Up: Creating and discovering plugins
+
+3.15.2 Using namespace packages
+-------------------------------
+
+*note Namespace packages: 130. can be used to provide a convention for
+where to place plugins and also provides a way to perform discovery.
+For example, if you make the sub-package ‘myapp.plugins’ a namespace
+package then other *note distributions: b. can provide modules and
+packages to that namespace. Once installed, you can use
+pkgutil.iter_modules()(1) to discover all modules and packages installed
+under that namespace:
+
+ import importlib
+ import pkgutil
+
+ import myapp.plugins
+
+ def iter_namespace(ns_pkg):
+ # Specifying the second argument (prefix) to iter_modules makes the
+ # returned name an absolute name instead of a relative one. This allows
+ # import_module to work without having to do additional modification to
+ # the name.
+ return pkgutil.iter_modules(ns_pkg.__path__, ns_pkg.__name__ + ".")
+
+ discovered_plugins = {
+ name: importlib.import_module(name)
+ for finder, name, ispkg
+ in iter_namespace(myapp.plugins)
+ }
+
+Specifying ‘myapp.plugins.__path__’ to iter_modules()(2) causes it to
+only look for the modules directly under that namespace. For example,
+if you have installed distributions that provide the modules
+‘myapp.plugins.a’ and ‘myapp.plugins.b’ then ‘discovered_plugins’ in
+this case would be:
+
+ {
+ 'a': <module: 'myapp.plugins.a'>,
+ 'b': <module: 'myapp.plugins.b'>,
+ }
+
+This sample uses a sub-package as the namespace package
+(‘myapp.plugins’), but it’s also possible to use a top-level package for
+this purpose (such as ‘myapp_plugins’). How to pick the namespace to
+use is a matter of preference, but it’s not recommended to make your
+project’s main top-level package (‘myapp’ in this case) a namespace
+package for the purpose of plugins, as one bad plugin could cause the
+entire namespace to break which would in turn make your project
+unimportable. For the “namespace sub-package” approach to work, the
+plugin packages must omit the ‘__init__.py’ for your top-level package
+directory (‘myapp’ in this case) and include the namespace-package style
+‘__init__.py’ in the namespace sub-package directory (‘myapp/plugins’).
+This also means that plugins will need to explicitly pass a list of
+packages to ‘setup()’’s ‘packages’ argument instead of using
+‘setuptools.find_packages()’.
+
+ Warning: Namespace packages are a complex feature and there are
+ several different ways to create them. It’s highly recommended to
+ read the *note Packaging namespace packages: 130. documentation and
+ clearly document which approach is preferred for plugins to your
+ project.
+
+ ---------- Footnotes ----------
+
+ (1)
+https://docs.python.org/2/library/pkgutil.html#pkgutil.iter_modules
+
+ (2)
+https://docs.python.org/2/library/pkgutil.html#pkgutil.iter_modules
+
+
+File: pythonpackagingguide.info, Node: Using package metadata, Prev: Using namespace packages, Up: Creating and discovering plugins
+
+3.15.3 Using package metadata
+-----------------------------
+
+Setuptools(1) provides special support(2) for plugins. By providing the
+‘entry_points’ argument to ‘setup()’ in ‘setup.py’ plugins can register
+themselves for discovery.
+
+For example if you have a package named ‘myapp-plugin-a’ and it includes
+in its ‘setup.py’:
+
+ setup(
+ ...
+ entry_points={'myapp.plugins': 'a = myapp_plugin_a'},
+ ...
+ )
+
+Then you can discover and load all of the registered entry points by
+using ‘pkg_resources.iter_entry_points()’:
+
+ import pkg_resources
+
+ discovered_plugins = {
+ entry_point.name: entry_point.load()
+ for entry_point
+ in pkg_resources.iter_entry_points('myapp.plugins')
+ }
+
+In this example, ‘discovered_plugins’ would be:
+
+ {
+ 'a': <module: 'myapp_plugin_a'>,
+ }
+
+ Note: The ‘entry_point’ specification in ‘setup.py’ is fairly
+ flexible and has a lot of options. It’s recommended to read over
+ the entire section on entry points(3).
+
+ ---------- Footnotes ----------
+
+ (1) http://setuptools.readthedocs.io
+
+ (2)
+http://setuptools.readthedocs.io/en/latest/setuptools.html#dynamic-discovery-of-services-and-plugins
+
+ (3)
+http://setuptools.readthedocs.io/en/latest/setuptools.html#dynamic-discovery-of-services-and-plugins
+
+
+File: pythonpackagingguide.info, Node: Analyzing PyPI package downloads, Next: Package index mirrors and caches, Prev: Creating and discovering plugins, Up: Guides
+
+3.16 Analyzing PyPI package downloads
+=====================================
+
+This section covers how to use the public PyPI download statistics
+dataset to learn more about downloads of a package (or packages) hosted
+on PyPI. For example, you can use it to discover the distribution of
+Python versions used to download a package.
+
+* Menu:
+
+* Background: Background<2>.
+* Public dataset::
+* Caveats::
+* Additional tools::
+* References::
+
+
+File: pythonpackagingguide.info, Node: Background<2>, Next: Public dataset, Up: Analyzing PyPI package downloads
+
+3.16.1 Background
+-----------------
+
+PyPI does not display download statistics for a number of reasons: (1)
+
+ - `Inefficient to make work with a Content Distribution Network
+ (CDN):' Download statistics change constantly. Including them in
+ project pages, which are heavily cached, would require invalidating
+ the cache more often, and reduce the overall effectiveness of the
+ cache.
+
+ - `Highly inaccurate:' A number of things prevent the download counts
+ from being accurate, some of which include:
+
+ - ‘pip’’s download cache (lowers download counts)
+
+ - Internal or unofficial mirrors (can both raise or lower
+ download counts)
+
+ - Packages not hosted on PyPI (for comparisons sake)
+
+ - Unofficial scripts or attempts at download count inflation
+ (raises download counts)
+
+ - Known historical data quality issues (lowers download counts)
+
+ - `Not particularly useful:' Just because a project has been
+ downloaded a lot doesn’t mean it’s good; Similarly just because a
+ project hasn’t been downloaded a lot doesn’t mean it’s bad!
+
+In short, because it’s value is low for various reasons, and the
+tradeoffs required to make it work are high, it has been not an
+effective use of limited resources.
+
+ ---------- Footnotes ----------
+
+ (1) (1) PyPI Download Counts deprecation email
+(https://mail.python.org/pipermail/distutils-sig/2013-May/020855.html)
+
+
+File: pythonpackagingguide.info, Node: Public dataset, Next: Caveats, Prev: Background<2>, Up: Analyzing PyPI package downloads
+
+3.16.2 Public dataset
+---------------------
+
+As an alternative, the Linehaul project(1) streams download logs from
+PyPI to Google BigQuery(2) (3), where they are stored as a public
+dataset.
+
+* Menu:
+
+* Getting set up::
+* Data schema::
+* Useful queries::
+
+ ---------- Footnotes ----------
+
+ (1) https://github.com/pypa/linehaul
+
+ (2) https://cloud.google.com/bigquery
+
+ (3) (2) PyPI BigQuery dataset announcement email
+(https://mail.python.org/pipermail/distutils-sig/2016-May/028986.html)
+
+
+File: pythonpackagingguide.info, Node: Getting set up, Next: Data schema, Up: Public dataset
+
+3.16.2.1 Getting set up
+.......................
+
+In order to use Google BigQuery(1) to query the public PyPI download
+statistics dataset(2), you’ll need a Google account and to enable the
+BigQuery API on a Google Cloud Platform project. You can run the up to
+1TB of queries per month using the BigQuery free tier without a credit
+card(3)
+
+ - Navigate to the BigQuery web UI(4).
+
+ - Create a new project.
+
+ - Enable the BigQuery API(5).
+
+For more detailed instructions on how to get started with BigQuery,
+check out the BigQuery quickstart guide(6).
+
+ ---------- Footnotes ----------
+
+ (1) https://cloud.google.com/bigquery
+
+ (2)
+https://console.cloud.google.com/bigquery?p=the-psf&d=pypi&page=dataset
+
+ (3)
+https://cloud.google.com/blog/big-data/2017/01/how-to-run-a-terabyte-of-google-bigquery-queries-each-month-without-a-credit-card
+
+ (4) https://console.cloud.google.com/bigquery
+
+ (5)
+https://console.developers.google.com/apis/library/bigquery-json.googleapis.com
+
+ (6)
+https://cloud.google.com/bigquery/docs/quickstarts/quickstart-web-ui
+
+
+File: pythonpackagingguide.info, Node: Data schema, Next: Useful queries, Prev: Getting set up, Up: Public dataset
+
+3.16.2.2 Data schema
+....................
+
+Linehaul writes an entry in a ‘the-psf.pypi.file_downloads’ table for
+each download. The table contains information about what file was
+downloaded and how it was downloaded. Some useful columns from the
+table schema(1) include:
+
+Column Description Examples
+
+-------------------------------------------------------------------------------------
+
+timestamp Date and time ‘2020-03-09 00:33:03 UTC’
+
+
+file.project Project name ‘pipenv’, ‘nose’
+
+
+file.version Package version ‘0.1.6’, ‘1.4.2’
+
+
+details.installer.name Installer pip, bandersnatch(2)
+
+
+details.python Python version ‘2.7.12’, ‘3.6.4’
+
+
+ ---------- Footnotes ----------
+
+ (1)
+https://console.cloud.google.com/bigquery?pli=1&p=the-psf&d=pypi&t=file_downloads&page=table
+
+ (2) /key_projects/#bandersnatch
+
+
+File: pythonpackagingguide.info, Node: Useful queries, Prev: Data schema, Up: Public dataset
+
+3.16.2.3 Useful queries
+.......................
+
+Run queries in the BigQuery web UI(1) by clicking the “Compose query”
+button.
+
+Note that the rows are stored in a partitioned, which helps limit the
+cost of queries. These example queries analyze downloads from recent
+history by filtering on the ‘timestamp’ column.
+
+* Menu:
+
+* Counting package downloads::
+* Package downloads over time::
+* Python versions over time::
+
+ ---------- Footnotes ----------
+
+ (1) https://console.cloud.google.com/bigquery
+
+
+File: pythonpackagingguide.info, Node: Counting package downloads, Next: Package downloads over time, Up: Useful queries
+
+3.16.2.4 Counting package downloads
+...................................
+
+The following query counts the total number of downloads for the project
+“pytest”.
+
+ #standardSQL
+ SELECT COUNT(*) AS num_downloads
+ FROM `the-psf.pypi.file_downloads`
+ WHERE file.project = 'pytest'
+ -- Only query the last 30 days of history
+ AND DATE(timestamp)
+ BETWEEN DATE_SUB(CURRENT_DATE(), INTERVAL 30 DAY)
+ AND CURRENT_DATE()
+
+num_downloads
+
+--------------------
+
+20531925
+
+To only count downloads from pip, filter on the ‘details.installer.name’
+column.
+
+ #standardSQL
+ SELECT COUNT(*) AS num_downloads
+ FROM `the-psf.pypi.file_downloads`
+ WHERE file.project = 'pytest'
+ AND details.installer.name = 'pip'
+ -- Only query the last 30 days of history
+ AND DATE(timestamp)
+ BETWEEN DATE_SUB(CURRENT_DATE(), INTERVAL 30 DAY)
+ AND CURRENT_DATE()
+
+num_downloads
+
+--------------------
+
+19391645
+
+
+File: pythonpackagingguide.info, Node: Package downloads over time, Next: Python versions over time, Prev: Counting package downloads, Up: Useful queries
+
+3.16.2.5 Package downloads over time
+....................................
+
+To group by monthly downloads, use the ‘TIMESTAMP_TRUNC’ function. Also
+filtering by this column reduces corresponding costs.
+
+ #standardSQL
+ SELECT
+ COUNT(*) AS num_downloads,
+ DATE_TRUNC(DATE(timestamp), MONTH) AS `month`
+ FROM `the-psf.pypi.file_downloads`
+ WHERE
+ file.project = 'pytest'
+ -- Only query the last 6 months of history
+ AND DATE(timestamp)
+ BETWEEN DATE_TRUNC(DATE_SUB(CURRENT_DATE(), INTERVAL 6 MONTH), MONTH)
+ AND CURRENT_DATE()
+ GROUP BY `month`
+ ORDER BY `month` DESC
+
+num_downloads month
+
+-------------------------------------
+
+1956741 2018-01-01
+
+
+2344692 2017-12-01
+
+
+1730398 2017-11-01
+
+
+2047310 2017-10-01
+
+
+1744443 2017-09-01
+
+
+1916952 2017-08-01
+
+
+
+File: pythonpackagingguide.info, Node: Python versions over time, Prev: Package downloads over time, Up: Useful queries
+
+3.16.2.6 Python versions over time
+..................................
+
+Extract the Python version from the ‘details.python’ column. Warning:
+This query processes over 500 GB of data.
+
+ #standardSQL
+ SELECT
+ REGEXP_EXTRACT(details.python, r"[0-9]+\.[0-9]+") AS python_version,
+ COUNT(*) AS num_downloads,
+ FROM `the-psf.pypi.file_downloads`
+ WHERE
+ -- Only query the last 6 months of history
+ DATE(timestamp)
+ BETWEEN DATE_TRUNC(DATE_SUB(CURRENT_DATE(), INTERVAL 6 MONTH), MONTH)
+ AND CURRENT_DATE()
+ GROUP BY `python_version`
+ ORDER BY `num_downloads` DESC
+
+python num_downloads
+
+---------------------------------
+
+3.7 12990683561
+
+
+3.6 9035598511
+
+
+2.7 8467785320
+
+
+3.8 4581627740
+
+
+3.5 2412533601
+
+
+null 1641456718
+
+
+
+File: pythonpackagingguide.info, Node: Caveats, Next: Additional tools, Prev: Public dataset, Up: Analyzing PyPI package downloads
+
+3.16.3 Caveats
+--------------
+
+In addition to the caveats listed in the background above, Linehaul
+suffered from a bug which caused it to significantly under-report
+download statistics prior to July 26, 2018. Downloads before this date
+are proportionally accurate (e.g. the percentage of Python 2 vs.
+Python 3 downloads) but total numbers are lower than actual by an order
+of magnitude.
+
+
+File: pythonpackagingguide.info, Node: Additional tools, Next: References, Prev: Caveats, Up: Analyzing PyPI package downloads
+
+3.16.4 Additional tools
+-----------------------
+
+Besides using the BigQuery console, there are some additional tools
+which may be useful when analyzing download statistics.
+
+* Menu:
+
+* google-cloud-bigquery::
+* pypinfo::
+* pandas-gbq::
+
+
+File: pythonpackagingguide.info, Node: google-cloud-bigquery, Next: pypinfo, Up: Additional tools
+
+3.16.4.1 ‘google-cloud-bigquery’
+................................
+
+You can also access the public PyPI download statistics dataset
+programmatically via the BigQuery API and the google-cloud-bigquery(1)
+project, the official Python client library for BigQuery.
+
+ from google.cloud import bigquery
+
+ # Note: depending on where this code is being run, you may require
+ # additional authentication. See:
+ # https://cloud.google.com/bigquery/docs/authentication/
+ client = bigquery.Client()
+
+ query_job = client.query("""
+ SELECT COUNT(*) AS num_downloads
+ FROM `the-psf.pypi.file_downloads`
+ WHERE file.project = 'pytest'
+ -- Only query the last 30 days of history
+ AND DATE(timestamp)
+ BETWEEN DATE_SUB(CURRENT_DATE(), INTERVAL 30 DAY)
+ AND CURRENT_DATE()""")
+
+ results = query_job.result() # Waits for job to complete.
+ for row in results:
+ print("{} downloads".format(row.num_downloads))
+
+ ---------- Footnotes ----------
+
+ (1) https://cloud.google.com/bigquery/docs/reference/libraries
+
+
+File: pythonpackagingguide.info, Node: pypinfo, Next: pandas-gbq, Prev: google-cloud-bigquery, Up: Additional tools
+
+3.16.4.2 ‘pypinfo’
+..................
+
+pypinfo(1) is a command-line tool which provides access to the dataset
+and can generate several useful queries. For example, you can query the
+total number of download for a package with the command ‘pypinfo
+package_name’.
+
+Install pypinfo(2) using pip.
+
+ pip install pypinfo
+
+Usage:
+
+ $ pypinfo requests
+ Served from cache: False
+ Data processed: 6.87 GiB
+ Data billed: 6.87 GiB
+ Estimated cost: $0.04
+
+ | download_count |
+ | -------------- |
+ | 9,316,415 |
+
+ ---------- Footnotes ----------
+
+ (1) https://github.com/ofek/pypinfo/blob/master/README.rst
+
+ (2) https://github.com/ofek/pypinfo/blob/master/README.rst
+
+
+File: pythonpackagingguide.info, Node: pandas-gbq, Prev: pypinfo, Up: Additional tools
+
+3.16.4.3 ‘pandas-gbq’
+.....................
+
+The pandas-gbq(1) project allows for accessing query results via
+Pandas(2).
+
+ ---------- Footnotes ----------
+
+ (1) https://pandas-gbq.readthedocs.io/en/latest/
+
+ (2) https://pandas.pydata.org/
+
+
+File: pythonpackagingguide.info, Node: References, Prev: Additional tools, Up: Analyzing PyPI package downloads
+
+3.16.5 References
+-----------------
+
+
+File: pythonpackagingguide.info, Node: Package index mirrors and caches, Next: Hosting your own simple repository, Prev: Analyzing PyPI package downloads, Up: Guides
+
+3.17 Package index mirrors and caches
+=====================================
+
+
+Page Status: Incomplete
+
+
+Last Reviewed: 2014-12-24
+
+Mirroring or caching of PyPI can be used to speed up local package
+installation, allow offline work, handle corporate firewalls or just
+plain Internet flakiness.
+
+Three options are available in this area:
+
+ 1. pip provides local caching options,
+
+ 2. devpi provides higher-level caching option, potentially shared
+ amongst many users or machines, and
+
+ 3. bandersnatch provides a local complete mirror of all PyPI *note
+ packages: b.
+
+* Menu:
+
+* Caching with pip::
+* Caching with devpi::
+* Complete mirror with bandersnatch::
+
+
+File: pythonpackagingguide.info, Node: Caching with pip, Next: Caching with devpi, Up: Package index mirrors and caches
+
+3.17.1 Caching with pip
+-----------------------
+
+pip provides a number of facilities for speeding up installation by
+using local cached copies of *note packages: b.:
+
+ 1. Fast & local installs(1) by downloading all the requirements for a
+ project and then pointing pip at those downloaded files instead of
+ going to PyPI.
+
+ 2. A variation on the above which pre-builds the installation files
+ for the requirements using pip wheel(2):
+
+ $ pip wheel --wheel-dir=/tmp/wheelhouse SomeProject
+ $ pip install --no-index --find-links=/tmp/wheelhouse SomeProject
+
+ ---------- Footnotes ----------
+
+ (1)
+https://pip.pypa.io/en/latest/user_guide/#installing-from-local-packages
+
+ (2) https://pip.readthedocs.io/en/latest/reference/pip_wheel.html
+
+
+File: pythonpackagingguide.info, Node: Caching with devpi, Next: Complete mirror with bandersnatch, Prev: Caching with pip, Up: Package index mirrors and caches
+
+3.17.2 Caching with devpi
+-------------------------
+
+devpi is a caching proxy server which you run on your laptop, or some
+other machine you know will always be available to you. See the devpi
+documentation for getting started(1).
+
+ ---------- Footnotes ----------
+
+ (1) http://doc.devpi.net/latest/quickstart-pypimirror.html
+
+
+File: pythonpackagingguide.info, Node: Complete mirror with bandersnatch, Prev: Caching with devpi, Up: Package index mirrors and caches
+
+3.17.3 Complete mirror with bandersnatch
+----------------------------------------
+
+bandersnatch will set up a complete local mirror of all PyPI *note
+packages: b. (externally-hosted packages are not mirrored). See the
+bandersnatch documentation for getting that going(1).
+
+A benefit of devpi is that it will create a mirror which includes *note
+packages: b. that are external to PyPI, unlike bandersnatch which will
+only cache *note packages: b. hosted on PyPI.
+
+ ---------- Footnotes ----------
+
+ (1) https://github.com/pypa/bandersnatch/
+
+
+File: pythonpackagingguide.info, Node: Hosting your own simple repository, Next: Migrating to PyPI org, Prev: Package index mirrors and caches, Up: Guides
+
+3.18 Hosting your own simple repository
+=======================================
+
+If you wish to host your own simple repository (1), you can either use a
+software package like devpi(2) or you can use simply create the proper
+directory structure and use any web server that can serve static files
+and generate an autoindex.
+
+In either case, since you’ll be hosting a repository that is likely not
+in your user’s default repositories, you should instruct them in your
+project’s description to configure their installer appropriately. For
+example with pip:
+
+ pip install --extra-index-url https://python.example.com/ foobar
+
+In addition, it is `highly' recommended that you serve your repository
+with valid HTTPS. At this time, the security of your user’s
+installations depends on all repositories using a valid HTTPS setup.
+
+* Menu:
+
+* “Manual” repository::
+
+ ---------- Footnotes ----------
+
+ (1) (1) For complete documentation of the simple repository protocol,
+see PEP 503.
+
+ (2) http://doc.devpi.net/latest/
+
+
+File: pythonpackagingguide.info, Node: “Manual” repository, Up: Hosting your own simple repository
+
+3.18.1 “Manual” repository
+--------------------------
+
+The directory layout is fairly simple, within a root directory you need
+to create a directory for each project. This directory should be the
+normalized name (as defined by PEP 503) of the project. Within each of
+these directories simply place each of the downloadable files. If you
+have the projects “Foo” (with the versions 1.0 and 2.0) and “bar” (with
+the version 0.1) You should end up with a structure that looks like:
+
+ .
+ ├── bar
+ │   └── bar-0.1.tar.gz
+ └── foo
+ ├── Foo-1.0.tar.gz
+ └── Foo-2.0.tar.gz
+
+Once you have this layout, simply configure your webserver to serve the
+root directory with autoindex enabled. For an example using the built
+in Web server in Twisted(1), you would simply run ‘twistd -n web --path
+.’ and then instruct users to add the URL to their installer’s
+configuration.
+
+__________________________________________________________________
+
+ ---------- Footnotes ----------
+
+ (1) https://twistedmatrix.com/
+
+
+File: pythonpackagingguide.info, Node: Migrating to PyPI org, Next: Using TestPyPI<2>, Prev: Hosting your own simple repository, Up: Guides
+
+3.19 Migrating to PyPI.org
+==========================
+
+*note pypi.org: 161. is the new, rewritten version of PyPI that has
+replaced the legacy PyPI code base. It is the default version of PyPI
+that people are expected to use. These are the tools and processes that
+people will need to interact with ‘PyPI.org’.
+
+* Menu:
+
+* Publishing releases::
+* Registering package names & metadata::
+* Using TestPyPI::
+* Registering new user accounts::
+* Browsing packages::
+* Downloading packages::
+* Managing published packages and releases::
+
+
+File: pythonpackagingguide.info, Node: Publishing releases, Next: Registering package names & metadata, Up: Migrating to PyPI org
+
+3.19.1 Publishing releases
+--------------------------
+
+‘pypi.org’ is the default upload platform as of September 2016.
+
+Uploads through ‘pypi.python.org’ were `switched off' on `July 3, 2017'.
+As of April 13th, 2018, ‘pypi.org’ is the URL for PyPI.
+
+The recommended way to migrate to PyPI.org for uploading is to ensure
+that you are using a new enough version of your upload tool.
+
+The default upload settings switched to ‘pypi.org’ in the following
+versions:
+
+ * ‘twine’ 1.8.0
+
+ * ‘setuptools’ 27.0.0
+
+ * Python 2.7.13 (‘distutils’ update)
+
+ * Python 3.4.6 (‘distutils’ update)
+
+ * Python 3.5.3 (‘distutils’ update)
+
+ * Python 3.6.0 (‘distutils’ update)
+
+In addition to ensuring you’re on a new enough version of the tool for
+the tool’s default to have switched, you must also make sure that you
+have not configured the tool to override its default upload URL.
+Typically this is configured in a file located at ‘$HOME/.pypirc’. If
+you see a file like:
+
+ [distutils]
+ index-servers =
+ pypi
+
+ [pypi]
+ repository = https://pypi.python.org/pypi
+ username = <your PyPI username>
+ password = <your PyPI username>
+
+Then simply delete the line starting with ‘repository’ and you will use
+your upload tool’s default URL.
+
+If for some reason you’re unable to upgrade the version of your tool to
+a version that defaults to using PyPI.org, then you may edit
+‘$HOME/.pypirc’ and include the ‘repository:’ line, but use the value
+‘https://upload.pypi.org/legacy/’ instead:
+
+ [distutils]
+ index-servers =
+ pypi
+
+ [pypi]
+ repository = https://upload.pypi.org/legacy/
+ username = <your PyPI username>
+ password = <your PyPI password>
+
+(‘legacy’ in this URL refers to the fact that this is the new server
+implementation’s emulation of the legacy server implementation’s upload
+API.)
+
+For more details, see the *note specification: f8. for ‘.pypirc’.
+
+
+File: pythonpackagingguide.info, Node: Registering package names & metadata, Next: Using TestPyPI, Prev: Publishing releases, Up: Migrating to PyPI org
+
+3.19.2 Registering package names & metadata
+-------------------------------------------
+
+Explicit pre-registration of package names with the ‘setup.py register’
+command prior to the first upload is no longer required, and is not
+currently supported by the legacy upload API emulation on PyPI.org.
+
+As a result, attempting explicit registration after switching to using
+PyPI.org for uploads will give the following error message:
+
+ Server response (410): This API is no longer supported, instead simply upload the file.
+
+The solution is to skip the registration step, and proceed directly to
+uploading artifacts.
+
+
+File: pythonpackagingguide.info, Node: Using TestPyPI, Next: Registering new user accounts, Prev: Registering package names & metadata, Up: Migrating to PyPI org
+
+3.19.3 Using TestPyPI
+---------------------
+
+Legacy TestPyPI (testpypi.python.org) is no longer available; use
+test.pypi.org(1) instead. If you use TestPyPI, you must update your
+‘$HOME/.pypirc’ to handle TestPyPI’s new location, by replacing
+‘https://testpypi.python.org/pypi’ with ‘https://test.pypi.org/legacy/’,
+for example:
+
+ [distutils]
+ index-servers=
+ pypi
+ testpypi
+
+ [testpypi]
+ repository = https://test.pypi.org/legacy/
+ username = <your TestPyPI username>
+ password = <your TestPyPI password>
+
+For more details, see the *note specification: f8. for ‘.pypirc’.
+
+ ---------- Footnotes ----------
+
+ (1) https://test.pypi.org
+
+
+File: pythonpackagingguide.info, Node: Registering new user accounts, Next: Browsing packages, Prev: Using TestPyPI, Up: Migrating to PyPI org
+
+3.19.4 Registering new user accounts
+------------------------------------
+
+In order to help mitigate spam attacks against PyPI, new user
+registration through ‘pypi.python.org’ was `switched off' on `February
+20, 2018'. New user registrations at ‘pypi.org’ are open.
+
+
+File: pythonpackagingguide.info, Node: Browsing packages, Next: Downloading packages, Prev: Registering new user accounts, Up: Migrating to PyPI org
+
+3.19.5 Browsing packages
+------------------------
+
+While ‘pypi.python.org’ is may still be used in links from other PyPA
+documentation, etc, the default interface for browsing packages is
+‘pypi.org’. The domain pypi.python.org now redirects to pypi.org, and
+may be disabled sometime in the future.
+
+
+File: pythonpackagingguide.info, Node: Downloading packages, Next: Managing published packages and releases, Prev: Browsing packages, Up: Migrating to PyPI org
+
+3.19.6 Downloading packages
+---------------------------
+
+‘pypi.org’ is the default host for downloading packages.
+
+
+File: pythonpackagingguide.info, Node: Managing published packages and releases, Prev: Downloading packages, Up: Migrating to PyPI org
+
+3.19.7 Managing published packages and releases
+-----------------------------------------------
+
+‘pypi.org’ provides a fully functional interface for logged in users to
+manage their published packages and releases.
+
+
+File: pythonpackagingguide.info, Node: Using TestPyPI<2>, Next: Making a PyPI-friendly README, Prev: Migrating to PyPI org, Up: Guides
+
+3.20 Using TestPyPI
+===================
+
+‘TestPyPI’ is a separate instance of the *note Python Package Index
+(PyPI): 39. that allows you to try out the distribution tools and
+process without worrying about affecting the real index. TestPyPI is
+hosted at test.pypi.org(1)
+
+* Menu:
+
+* Registering your account::
+* Using TestPyPI with Twine::
+* Using TestPyPI with pip::
+* Setting up TestPyPI in .pypirc: Setting up TestPyPI in pypirc.
+
+ ---------- Footnotes ----------
+
+ (1) https://test.pypi.org
+
+
+File: pythonpackagingguide.info, Node: Registering your account, Next: Using TestPyPI with Twine, Up: Using TestPyPI<2>
+
+3.20.1 Registering your account
+-------------------------------
+
+Because TestPyPI has a separate database from the live PyPI, you’ll need
+a separate user account for specifically for TestPyPI. Go to
+‘https://test.pypi.org/account/register/’ to register your account.
+
+ Note: The database for TestPyPI may be periodically pruned, so it
+ is not unusual for user accounts to be deleted.
+
+
+File: pythonpackagingguide.info, Node: Using TestPyPI with Twine, Next: Using TestPyPI with pip, Prev: Registering your account, Up: Using TestPyPI<2>
+
+3.20.2 Using TestPyPI with Twine
+--------------------------------
+
+You can upload your distributions to TestPyPI using *note twine: 66. by
+specifying the ‘--repository’ flag
+
+ $ twine upload --repository testpypi dist/*
+
+You can see if your package has successfully uploaded by navigating to
+the URL ‘https://test.pypi.org/project/<sampleproject>’ where
+‘sampleproject’ is the name of your project that you uploaded. It may
+take a minute or two for your project to appear on the site.
+
+
+File: pythonpackagingguide.info, Node: Using TestPyPI with pip, Next: Setting up TestPyPI in pypirc, Prev: Using TestPyPI with Twine, Up: Using TestPyPI<2>
+
+3.20.3 Using TestPyPI with pip
+------------------------------
+
+You can tell pip to download packages from TestPyPI instead of PyPI by
+specifying the ‘--index-url’ flag
+
+ $ pip install --index-url https://test.pypi.org/simple/ your-package
+
+If you want to allow pip to also pull other packages from PyPI you can
+specify ‘--extra-index-url’ to point to PyPI. This is useful when the
+package you’re testing has dependencies:
+
+ pip install --index-url https://test.pypi.org/simple/ --extra-index-url https://pypi.org/simple your-package
+
+
+File: pythonpackagingguide.info, Node: Setting up TestPyPI in pypirc, Prev: Using TestPyPI with pip, Up: Using TestPyPI<2>
+
+3.20.4 Setting up TestPyPI in ‘.pypirc’
+---------------------------------------
+
+If you want to avoid entering your username, you can configure TestPyPI
+in your ‘$HOME/.pypirc’:
+
+ [testpypi]
+ username = <your TestPyPI username>
+
+For more details, see the *note specification: f8. for ‘.pypirc’.
+
+
+File: pythonpackagingguide.info, Node: Making a PyPI-friendly README, Next: Publishing package distribution releases using GitHub Actions CI/CD workflows, Prev: Using TestPyPI<2>, Up: Guides
+
+3.21 Making a PyPI-friendly README
+==================================
+
+README files can help your users understand your project and can be used
+to set your project’s description on PyPI. This guide helps you create a
+README in a PyPI-friendly format and include your README in your package
+so it appears on PyPI.
+
+* Menu:
+
+* Creating a README file::
+* Including your README in your package’s metadata::
+* Validating reStructuredText markup::
+
+
+File: pythonpackagingguide.info, Node: Creating a README file, Next: Including your README in your package’s metadata, Up: Making a PyPI-friendly README
+
+3.21.1 Creating a README file
+-----------------------------
+
+README files for Python projects are often named ‘README’, ‘README.txt’,
+‘README.rst’, or ‘README.md’.
+
+For your README to display properly on PyPI, choose a markup language
+supported by PyPI. Formats supported by PyPI’s README renderer(1) are:
+
+ * plain text
+
+ * reStructuredText(2) (without Sphinx extensions)
+
+ * Markdown (GitHub Flavored Markdown(3) by default, or CommonMark(4))
+
+It’s customary to save your README file in the root of your project, in
+the same directory as your ‘setup.py’ file.
+
+ ---------- Footnotes ----------
+
+ (1) https://github.com/pypa/readme_renderer
+
+ (2) http://docutils.sourceforge.net/rst.html
+
+ (3) https://github.github.com/gfm/
+
+ (4) http://commonmark.org/
+
+
+File: pythonpackagingguide.info, Node: Including your README in your package’s metadata, Next: Validating reStructuredText markup, Prev: Creating a README file, Up: Making a PyPI-friendly README
+
+3.21.2 Including your README in your package’s metadata
+-------------------------------------------------------
+
+To include your README’s contents as your package description, set your
+project’s ‘Description’ and ‘Description-Content-Type’ metadata,
+typically in your project’s ‘setup.py’ file.
+
+See also
+........
+
+ * *note Description: 172.
+
+ * *note Description-Content-Type: 173.
+
+For example, to set these values in a package’s ‘setup.py’ file, use
+‘setup()’’s ‘long_description’ and ‘long_description_content_type’.
+
+Set the value of ‘long_description’ to the contents (not the path) of
+the README file itself. Set the ‘long_description_content_type’ to an
+accepted ‘Content-Type’-style value for your README file’s markup, such
+as ‘text/plain’, ‘text/x-rst’ (for reStructuredText), or
+‘text/markdown’.
+
+ Note: If you’re using GitHub-flavored Markdown to write a project’s
+ description, ensure you upgrade the following tools:
+
+ python3 -m pip install --user --upgrade setuptools wheel twine
+
+ The minimum required versions of the respective tools are:
+
+ - ‘setuptools >= 38.6.0’
+
+ - ‘wheel >= 0.31.0’
+
+ - ‘twine >= 1.11.0’
+
+ It’s recommended that you use ‘twine’ to upload the project’s
+ distribution packages:
+
+ twine upload dist/*
+
+For example, see this ‘setup.py’ file, which reads the contents of
+‘README.md’ as ‘long_description’ and identifies the markup as
+GitHub-flavored Markdown:
+
+ from setuptools import setup
+
+ # read the contents of your README file
+ from os import path
+ this_directory = path.abspath(path.dirname(__file__))
+ with open(path.join(this_directory, 'README.md'), encoding='utf-8') as f:
+ long_description = f.read()
+
+ setup(
+ name='an_example_package',
+ # other arguments omitted
+ long_description=long_description,
+ long_description_content_type='text/markdown'
+ )
+
+
+File: pythonpackagingguide.info, Node: Validating reStructuredText markup, Prev: Including your README in your package’s metadata, Up: Making a PyPI-friendly README
+
+3.21.3 Validating reStructuredText markup
+-----------------------------------------
+
+If your README is written in reStructuredText, any invalid markup will
+prevent it from rendering, causing PyPI to instead just show the
+README’s raw source.
+
+Note that Sphinx extensions used in docstrings, such as directives and
+roles(1) (e.g., “‘:py:func:`getattr`’” or
+“‘:ref:`my-reference-label`’”), are not allowed here and will result in
+error messages like “‘Error: Unknown interpreted text role "py:func".’”.
+
+You can check your README for markup errors before uploading as follows:
+
+ 1. Install the latest version of twine(2); version 1.12.0 or higher is
+ required:
+
+ pip install --upgrade twine
+
+ 2. Build the sdist and wheel for your project as described under *note
+ Packaging your project: d8.
+
+ 3. Run ‘twine check’ on the sdist and wheel:
+
+ twine check dist/*
+
+ This command will report any problems rendering your README. If
+ your markup renders fine, the command will output ‘Checking
+ distribution FILENAME: Passed’.
+
+ ---------- Footnotes ----------
+
+ (1)
+http://www.sphinx-doc.org/en/master/usage/restructuredtext/index.html
+
+ (2) https://github.com/pypa/twine
+
+
+File: pythonpackagingguide.info, Node: Publishing package distribution releases using GitHub Actions CI/CD workflows, Prev: Making a PyPI-friendly README, Up: Guides
+
+3.22 Publishing package distribution releases using GitHub Actions CI/CD workflows
+==================================================================================
+
+GitHub Actions CI/CD(1) allows you to run a series of commands whenever
+an event occurs on the GitHub platform. One popular choice is having a
+workflow that’s triggered by a ‘push’ event. This guide shows you how
+to publish a Python distribution whenever a tagged commit is pushed. It
+will use the pypa/gh-action-pypi-publish GitHub Action(2).
+
+ Attention: This guide `assumes' that you already have a project
+ that you know how to build distributions for and `it lives on
+ GitHub'.
+
+* Menu:
+
+* Saving credentials on GitHub::
+* Creating a workflow definition::
+* Defining a workflow job environment::
+* Checking out the project and building distributions::
+* Publishing the distribution to PyPI and TestPyPI::
+* That’s all, folks!: That’s all folks!.
+
+ ---------- Footnotes ----------
+
+ (1) https://github.com/features/actions
+
+ (2) https://github.com/marketplace/actions/pypi-publish
+
+
+File: pythonpackagingguide.info, Node: Saving credentials on GitHub, Next: Creating a workflow definition, Up: Publishing package distribution releases using GitHub Actions CI/CD workflows
+
+3.22.1 Saving credentials on GitHub
+-----------------------------------
+
+In this guide, we’ll demonstrate uploading to both PyPI and TestPyPI,
+meaning that we’ll have two separate sets of credentials. And we’ll
+need to save them in the GitHub repository settings.
+
+Let’s begin! 🚀
+
+ 1. Go to ‘https://pypi.org/manage/account/#api-tokens’ and create a
+ new API token(1). If you have the project on PyPI already, limit
+ the token scope to just that project. You can call it something
+ like ‘GitHub Actions CI/CD — project-org/project-repo’ in order for
+ it to be easily distinguishable in the token list. `Don’t close
+ the page just yet — you won’t see that token again.'
+
+ 2. In a separate browser tab or window, go to the ‘Settings’ tab of
+ your target repository and then click on Secrets(2) in the left
+ sidebar.
+
+ 3. Create a new secret called ‘pypi_password’ and copy-paste the token
+ from the fist step.
+
+ 4. Now, go to ‘https://test.pypi.org/manage/account/#api-tokens’ and
+ repeat the steps. Save that TestPyPI token on GitHub as
+ ‘test_pypi_password’.
+
+ Attention: If you don’t have a TestPyPI account, you’ll need
+ to create it. It’s not the same as a regular PyPI account.
+
+ ---------- Footnotes ----------
+
+ (1) https://pypi.org/help/#apitoken
+
+ (2)
+https://help.github.com/en/articles/virtual-environments-for-github-actions#creating-and-using-secrets-encrypted-variables
+
+
+File: pythonpackagingguide.info, Node: Creating a workflow definition, Next: Defining a workflow job environment, Prev: Saving credentials on GitHub, Up: Publishing package distribution releases using GitHub Actions CI/CD workflows
+
+3.22.2 Creating a workflow definition
+-------------------------------------
+
+GitHub CI/CD workflows are declared in YAML files stored in the
+‘.github/workflows/’ directory of your repository.
+
+Let’s create a ‘.github/workflows/publish-to-test-pypi.yml’ file.
+
+Start it with a meaningful name and define the event that should make
+GitHub run this workflow:
+
+ name: Publish Python 🐍 distributions 📦 to PyPI and TestPyPI
+
+ on: push
+
+
+
+File: pythonpackagingguide.info, Node: Defining a workflow job environment, Next: Checking out the project and building distributions, Prev: Creating a workflow definition, Up: Publishing package distribution releases using GitHub Actions CI/CD workflows
+
+3.22.3 Defining a workflow job environment
+------------------------------------------
+
+Now, let’s add initial setup for our job. It’s a process that will
+execute commands that we’ll define later. In this guide, we’ll use
+Ubuntu 18.04:
+
+
+ jobs:
+ build-n-publish:
+ name: Build and publish Python 🐍 distributions 📦 to PyPI and TestPyPI
+ runs-on: ubuntu-18.04
+
+
+
+File: pythonpackagingguide.info, Node: Checking out the project and building distributions, Next: Publishing the distribution to PyPI and TestPyPI, Prev: Defining a workflow job environment, Up: Publishing package distribution releases using GitHub Actions CI/CD workflows
+
+3.22.4 Checking out the project and building distributions
+----------------------------------------------------------
+
+Then, add the following under the ‘build-n-publish’ section:
+
+
+ steps:
+ - uses: actions/checkout@master
+ - name: Set up Python 3.7
+ uses: actions/setup-python@v1
+ with:
+ python-version: 3.7
+
+This will download your repository into the CI runner and then install
+and activate Python 3.7.
+
+And now we can build dists from source. In this example, we’ll use
+‘build’ package, assuming that your project has a ‘pyproject.toml’
+properly set up (see PEP 517(1)/ PEP 518(2)).
+
+ Tip: You can use any other method for building distributions as
+ long as it produces ready-to-upload artifacts saved into the
+ ‘dist/’ folder.
+
+So add this to the steps list:
+
+ - name: Install pypa/build
+ run: >-
+ python -m
+ pip install
+ build
+ --user
+ - name: Build a binary wheel and a source tarball
+ run: >-
+ python -m
+ build
+ --sdist
+ --wheel
+ --outdir dist/
+ .
+
+ ---------- Footnotes ----------
+
+ (1) https://www.python.org/dev/peps/pep-0517
+
+ (2) https://www.python.org/dev/peps/pep-0518
+
+
+File: pythonpackagingguide.info, Node: Publishing the distribution to PyPI and TestPyPI, Next: That’s all folks!, Prev: Checking out the project and building distributions, Up: Publishing package distribution releases using GitHub Actions CI/CD workflows
+
+3.22.5 Publishing the distribution to PyPI and TestPyPI
+-------------------------------------------------------
+
+Finally, add the following steps at the end:
+
+ - name: Publish distribution 📦 to Test PyPI
+ uses: pypa/gh-action-pypi-publish@master
+ with:
+ password: ${{ secrets.test_pypi_password }}
+ repository_url: https://test.pypi.org/legacy/
+ - name: Publish distribution 📦 to PyPI
+ if: startsWith(github.ref, 'refs/tags')
+ uses: pypa/gh-action-pypi-publish@master
+ with:
+ password: ${{ secrets.pypi_password }}
+
+These two steps use the pypa/gh-action-pypi-publish(1) GitHub Action:
+the first one uploads contents of the ‘dist/’ folder into TestPyPI
+unconditionally and the second does that to PyPI, but only if the
+current commit is tagged.
+
+ ---------- Footnotes ----------
+
+ (1) https://github.com/pypa/gh-action-pypi-publish
+
+
+File: pythonpackagingguide.info, Node: That’s all folks!, Prev: Publishing the distribution to PyPI and TestPyPI, Up: Publishing package distribution releases using GitHub Actions CI/CD workflows
+
+3.22.6 That’s all, folks!
+-------------------------
+
+Now, whenever you push a tagged commit to your Git repository remote on
+GitHub, this workflow will publish it to PyPI. And it’ll publish any
+push to TestPyPI which is useful for providing test builds to your alpha
+users as well as making sure that your release pipeline remains healthy!
+
+
+File: pythonpackagingguide.info, Node: Discussions, Next: PyPA specifications, Prev: Guides, Up: Top
+
+4 Discussions
+*************
+
+`Discussions' are focused on providing comprehensive information about a
+specific topic. If you’re just trying to get stuff done, see *note
+Guides: 22.
+
+* Menu:
+
+* Deploying Python applications::
+* pip vs easy_install::
+* install_requires vs requirements files::
+* Wheel vs Egg::
+
+
+File: pythonpackagingguide.info, Node: Deploying Python applications, Next: pip vs easy_install, Up: Discussions
+
+4.1 Deploying Python applications
+=================================
+
+
+Page Status: Incomplete
+
+
+Last Reviewed: 2014-11-11
+
+* Menu:
+
+* Overview::
+* OS packaging & installers::
+* Application bundles::
+* Configuration management::
+
+
+File: pythonpackagingguide.info, Node: Overview, Next: OS packaging & installers, Up: Deploying Python applications
+
+4.1.1 Overview
+--------------
+
+* Menu:
+
+* Supporting multiple hardware platforms::
+
+
+File: pythonpackagingguide.info, Node: Supporting multiple hardware platforms, Up: Overview
+
+4.1.1.1 Supporting multiple hardware platforms
+..............................................
+
+ FIXME
+
+ Meaning: x86, x64, ARM, others?
+
+ For Python-only distributions, it *should* be straightforward to deploy on all
+ platforms where Python can run.
+
+ For distributions with binary extensions, deployment is major headache. Not only
+ must the extensions be built on all the combinations of operating system and
+ hardware platform, but they must also be tested, preferably on continuous
+ integration platforms. The issues are similar to the "multiple Python
+ versions" section above, not sure whether this should be a separate section.
+ Even on Windows x64, both the 32 bit and 64 bit versions of Python enjoy
+ significant usage.
+
+
+File: pythonpackagingguide.info, Node: OS packaging & installers, Next: Application bundles, Prev: Overview, Up: Deploying Python applications
+
+4.1.2 OS packaging & installers
+-------------------------------
+
+ FIXME
+
+ - Building rpm/debs for projects
+ - Building rpms/debs for whole virtualenvs
+ - Building macOS installers for Python projects
+ - Building Android APKs with Kivy+P4A or P4A & Buildozer
+
+* Menu:
+
+* Windows: Windows<2>.
+
+
+File: pythonpackagingguide.info, Node: Windows<2>, Up: OS packaging & installers
+
+4.1.2.1 Windows
+...............
+
+ FIXME
+
+ - Building Windows installers for Python projects
+
+* Menu:
+
+* Pynsist::
+
+
+File: pythonpackagingguide.info, Node: Pynsist, Up: Windows<2>
+
+4.1.2.2 Pynsist
+...............
+
+Pynsist(1) is a tool that bundles Python programs together with the
+Python-interpreter into a single installer based on NSIS. In most cases,
+packaging only requires the user to choose a version of the
+Python-interpreter and declare the dependencies of the program. The
+tool downloads the specified Python-interpreter for Windows and packages
+it with all the dependencies in a single Windows-executable installer.
+
+The installed program can be started from a shortcut that the installer
+adds to the start-menu. It uses a Python interpreter installed within
+its application directory, independent of any other Python installation
+on the computer.
+
+A big advantage of Pynsist is that the Windows packages can be built on
+Linux. There are several examples for different kinds of programs
+(console, GUI) in the documentation(2). The tool is released under the
+MIT-licence.
+
+ ---------- Footnotes ----------
+
+ (1) https://pypi.org/project/pynsist
+
+ (2) https://pynsist.readthedocs.io
+
+
+File: pythonpackagingguide.info, Node: Application bundles, Next: Configuration management, Prev: OS packaging & installers, Up: Deploying Python applications
+
+4.1.3 Application bundles
+-------------------------
+
+ FIXME
+
+ - py2exe/py2app/PEX
+ - wheels kinda/sorta
+
+
+File: pythonpackagingguide.info, Node: Configuration management, Prev: Application bundles, Up: Deploying Python applications
+
+4.1.4 Configuration management
+------------------------------
+
+ FIXME
+
+ puppet
+ salt
+ chef
+ ansible
+ fabric
+
+
+File: pythonpackagingguide.info, Node: pip vs easy_install, Next: install_requires vs requirements files, Prev: Deploying Python applications, Up: Discussions
+
+4.2 pip vs easy_install
+=======================
+
+*note setuptools: 18b. was released in 2004, as part of *note
+setuptools: 2d. It was notable at the time for installing *note
+packages: b. from *note PyPI: 39. using requirement specifiers, and
+automatically installing dependencies.
+
+*note pip: 2b. came later in 2008, as alternative to *note setuptools:
+18b, although still largely built on top of *note setuptools: 2d.
+components. It was notable at the time for `not' installing packages as
+*note Eggs: 7c. or from *note Eggs: 7c. (but rather simply as ‘flat’
+packages from *note sdists: 3d.), and introducing the idea of
+Requirements Files(1), which gave users the power to easily replicate
+environments.
+
+Here’s a breakdown of the important differences between pip and
+easy_install now:
+
+ `pip' `easy_install'
+
+
+Installs from *note Wheels: d. Yes No
+
+
+Uninstall Packages Yes (‘pip uninstall’) No
+
+
+Dependency Overrides Yes (Requirements Files(2)) No
+
+
+List Installed Packages Yes (‘pip list’ and ‘pip freeze’) No
+
+
+PEP 438(3) Support Yes No
+
+
+Installation format ‘Flat’ packages with ‘egg-info’ Encapsulated Egg format
+ metadata.
+
+
+sys.path modification No Yes
+
+
+Installs from *note Eggs: 7c. No Yes
+
+
+pylauncher support(4) No Yes (5)
+
+
+*note Multi-version installs: b5. No Yes
+
+
+Exclude scripts during install No Yes
+
+
+per project index Only in virtualenv Yes, via setup.cfg
+
+
+__________________________________________________________________
+
+ ---------- Footnotes ----------
+
+ (1) https://pip.pypa.io/en/latest/user_guide/#requirements-files
+
+ (2) https://pip.pypa.io/en/latest/user_guide/#requirements-files
+
+ (3) https://www.python.org/dev/peps/pep-0438
+
+ (4) https://bitbucket.org/vinay.sajip/pylauncher
+
+ (5) (1)
+‘https://setuptools.readthedocs.io/en/latest/easy_install.html#natural-script-launcher’
+
+
+File: pythonpackagingguide.info, Node: install_requires vs requirements files, Next: Wheel vs Egg, Prev: pip vs easy_install, Up: Discussions
+
+4.3 install_requires vs requirements files
+==========================================
+
+* Menu:
+
+* install_requires: install_requires<2>.
+* Requirements files: Requirements files<2>.
+
+
+File: pythonpackagingguide.info, Node: install_requires<2>, Next: Requirements files<2>, Up: install_requires vs requirements files
+
+4.3.1 install_requires
+----------------------
+
+‘install_requires’ is a *note setuptools: 2d. ‘setup.py’ keyword that
+should be used to specify what a project `minimally' needs to run
+correctly. When the project is installed by *note pip: 2b, this is the
+specification that is used to install its dependencies.
+
+For example, if the project requires A and B, your ‘install_requires’
+would be like so:
+
+ install_requires=[
+ 'A',
+ 'B'
+ ]
+
+Additionally, it’s best practice to indicate any known lower or upper
+bounds.
+
+For example, it may be known, that your project requires at least v1 of
+‘A’, and v2 of ‘B’, so it would be like so:
+
+ install_requires=[
+ 'A>=1',
+ 'B>=2'
+ ]
+
+It may also be known that project A follows semantic versioning, and
+that v2 of ‘A’ will indicate a break in compatibility, so it makes sense
+to not allow v2:
+
+ install_requires=[
+ 'A>=1,<2',
+ 'B>=2'
+ ]
+
+It is not considered best practice to use ‘install_requires’ to pin
+dependencies to specific versions, or to specify sub-dependencies (i.e.
+dependencies of your dependencies). This is overly-restrictive, and
+prevents the user from gaining the benefit of dependency upgrades.
+
+Lastly, it’s important to understand that ‘install_requires’ is a
+listing of “Abstract” requirements, i.e just names and version
+restrictions that don’t determine where the dependencies will be
+fulfilled from (i.e. from what index or source). The where (i.e. how
+they are to be made “Concrete”) is to be determined at install time
+using *note pip: 2b. options. (1)
+
+ ---------- Footnotes ----------
+
+ (1) (1) For more on “Abstract” vs “Concrete” requirements, see
+‘https://caremad.io/2013/07/setup-vs-requirement/’.
+
+
+File: pythonpackagingguide.info, Node: Requirements files<2>, Prev: install_requires<2>, Up: install_requires vs requirements files
+
+4.3.2 Requirements files
+------------------------
+
+Requirements Files(1) described most simply, are just a list of pip
+install(2) arguments placed into a file.
+
+Whereas ‘install_requires’ defines the dependencies for a single
+project, Requirements Files(3) are often used to define the requirements
+for a complete Python environment.
+
+Whereas ‘install_requires’ requirements are minimal, requirements files
+often contain an exhaustive listing of pinned versions for the purpose
+of achieving repeatable installations(4) of a complete environment.
+
+Whereas ‘install_requires’ requirements are “Abstract”, i.e. not
+associated with any particular index, requirements files often contain
+pip options like ‘--index-url’ or ‘--find-links’ to make requirements
+“Concrete”, i.e. associated with a particular index or directory of
+packages. (5)
+
+Whereas ‘install_requires’ metadata is automatically analyzed by pip
+during an install, requirements files are not, and only are used when a
+user specifically installs them using ‘pip install -r’.
+
+__________________________________________________________________
+
+ ---------- Footnotes ----------
+
+ (1) https://pip.pypa.io/en/latest/user_guide/#requirements-files
+
+ (2) https://pip.pypa.io/en/latest/reference/pip_install/#pip-install
+
+ (3) https://pip.pypa.io/en/latest/user_guide/#requirements-files
+
+ (4) https://pip.pypa.io/en/latest/user_guide/#repeatability
+
+ (5) (1) For more on “Abstract” vs “Concrete” requirements, see
+‘https://caremad.io/2013/07/setup-vs-requirement/’.
+
+
+File: pythonpackagingguide.info, Node: Wheel vs Egg, Prev: install_requires vs requirements files, Up: Discussions
+
+4.4 Wheel vs Egg
+================
+
+*note Wheel: d. and *note Egg: 7c. are both packaging formats that aim
+to support the use case of needing an install artifact that doesn’t
+require building or compilation, which can be costly in testing and
+production workflows.
+
+The *note Egg: 7c. format was introduced by *note setuptools: 2d. in
+2004, whereas the *note Wheel: d. format was introduced by PEP 427(1) in
+2012.
+
+*note Wheel: d. is currently considered the standard for *note built:
+63. and *note binary: 194. packaging for Python.
+
+Here’s a breakdown of the important differences between *note Wheel: d.
+and *note Egg: 7c.
+
+ * *note Wheel: d. has an official PEP(2). *note Egg: 7c. did not.
+
+ * *note Wheel: d. is a *note distribution: b. format, i.e a packaging
+ format. (3) *note Egg: 7c. was both a distribution format and a
+ runtime installation format (if left zipped), and was designed to
+ be importable.
+
+ * *note Wheel: d. archives do not include .pyc 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 *note sdist: 3d.
+
+ * *note Wheel: d. uses PEP376-compliant(4) ‘.dist-info’ directories.
+ Egg used ‘.egg-info’.
+
+ * *note Wheel: d. has a richer file naming convention(5). A single
+ wheel archive can indicate its compatibility with a number of
+ Python language versions and implementations, ABIs, and system
+ architectures.
+
+ * *note Wheel: d. is versioned. Every wheel file contains the
+ version of the wheel specification and the implementation that
+ packaged it.
+
+ * *note Wheel: d. is internally organized by sysconfig path type(6),
+ therefore making it easier to convert to other formats.
+
+__________________________________________________________________
+
+ ---------- Footnotes ----------
+
+ (1) https://www.python.org/dev/peps/pep-0427
+
+ (2) https://www.python.org/dev/peps/pep-0427
+
+ (3) (1) Circumstantially, in some cases, wheels can be used as an
+importable runtime format, although this is not officially supported at
+this time
+(https://www.python.org/dev/peps/pep-0427#is-it-possible-to-import-python-code-directly-from-a-wheel-file).
+
+ (4) https://www.python.org/dev/peps/pep-0376
+
+ (5) https://www.python.org/dev/peps/pep-0425
+
+ (6)
+http://docs.python.org/2/library/sysconfig.html#installation-paths
+
+
+File: pythonpackagingguide.info, Node: PyPA specifications, Next: Project Summaries, Prev: Discussions, Up: Top
+
+5 PyPA specifications
+*********************
+
+This is a list of currently active interoperability specifications
+maintained by the Python Packaging Authority. The process for updating
+these standards, and for proposing new ones, is documented on
+pypa.io(1).
+
+* Menu:
+
+* Package Distribution Metadata::
+* Package Index Interfaces::
+
+ ---------- Footnotes ----------
+
+ (1) https://www.pypa.io/en/latest/specifications/
+
+
+File: pythonpackagingguide.info, Node: Package Distribution Metadata, Next: Package Index Interfaces, Up: PyPA specifications
+
+5.1 Package Distribution Metadata
+=================================
+
+* Menu:
+
+* Core metadata specifications::
+* Version specifiers::
+* Dependency specifiers::
+* Declaring build system dependencies::
+* Declaring project metadata::
+* Distribution formats::
+* Platform compatibility tags::
+* Recording installed projects::
+* Entry points specification::
+
+
+File: pythonpackagingguide.info, Node: Core metadata specifications, Next: Version specifiers, Up: Package Distribution Metadata
+
+5.1.1 Core metadata specifications
+----------------------------------
+
+The current core metadata file format, version 2.1, is specified in PEP
+566(1). It defines the following specification as the canonical source
+for the core metadata file format.
+
+Fields defined in the following specification should be considered
+valid, complete and not subject to change. The required fields are:
+
+ - ‘Metadata-Version’
+
+ - ‘Name’
+
+ - ‘Version’
+
+All the other fields are optional.
+
+ Note: `Interpreting old metadata:' In PEP 566(2), the version
+ specifier field format specification was relaxed to accept the
+ syntax used by popular publishing tools (namely to remove the
+ requirement that version specifiers must be surrounded by
+ parentheses). Metadata consumers may want to use the more relaxed
+ formatting rules even for metadata files that are nominally less
+ than version 2.1.
+
+* Menu:
+
+* Metadata-Version::
+* Name::
+* Version::
+* Platform (multiple use): Platform multiple use.
+* Supported-Platform (multiple use): Supported-Platform multiple use.
+* Summary::
+* Description::
+* Description-Content-Type::
+* Keywords::
+* Home-page::
+* Download-URL::
+* Author::
+* Author-email::
+* Maintainer::
+* Maintainer-email::
+* License::
+* Classifier (multiple use): Classifier multiple use.
+* Requires-Dist (multiple use): Requires-Dist multiple use.
+* Requires-Python::
+* Requires-External (multiple use): Requires-External multiple use.
+* Project-URL (multiple-use): Project-URL multiple-use.
+* Provides-Extra (multiple use): Provides-Extra multiple use.
+* Rarely Used Fields::
+
+ ---------- Footnotes ----------
+
+ (1) https://www.python.org/dev/peps/pep-0566
+
+ (2) https://www.python.org/dev/peps/pep-0566
+
+
+File: pythonpackagingguide.info, Node: Metadata-Version, Next: Name, Up: Core metadata specifications
+
+5.1.1.1 Metadata-Version
+........................
+
+New in version 1.0.
+
+Version of the file format; legal values are “1.0”, “1.1”, “1.2” and
+“2.1”.
+
+Automated tools consuming metadata SHOULD warn if ‘metadata_version’ is
+greater than the highest version they support, and MUST fail if
+‘metadata_version’ has a greater major version than the highest version
+they support (as described in PEP 440(1), the major version is the value
+before the first dot).
+
+For broader compatibility, build tools MAY choose to produce
+distribution metadata using the lowest metadata version that includes
+all of the needed fields.
+
+Example:
+
+ Metadata-Version: 2.1
+
+ ---------- Footnotes ----------
+
+ (1) https://www.python.org/dev/peps/pep-0440
+
+
+File: pythonpackagingguide.info, Node: Name, Next: Version, Prev: Metadata-Version, Up: Core metadata specifications
+
+5.1.1.2 Name
+............
+
+New in version 1.0.
+
+Changed in version 2.1: Added additional restrictions on format from PEP
+508(1)
+
+The name of the distribution. The name field is the primary identifier
+for a distribution. A valid name consists only of ASCII letters and
+numbers, period, underscore and hyphen. It must start and end with a
+letter or number. Distribution names are limited to those which match
+the following regex (run with ‘re.IGNORECASE’):
+
+ ^([A-Z0-9]|[A-Z0-9][A-Z0-9._-]*[A-Z0-9])$
+
+Example:
+
+ Name: BeagleVote
+
+ ---------- Footnotes ----------
+
+ (1) https://www.python.org/dev/peps/pep-0508
+
+
+File: pythonpackagingguide.info, Node: Version, Next: Platform multiple use, Prev: Name, Up: Core metadata specifications
+
+5.1.1.3 Version
+...............
+
+New in version 1.0.
+
+A string containing the distribution’s version number. This field must
+be in the format specified in PEP 440(1).
+
+Example:
+
+ Version: 1.0a2
+
+ ---------- Footnotes ----------
+
+ (1) https://www.python.org/dev/peps/pep-0440
+
+
+File: pythonpackagingguide.info, Node: Platform multiple use, Next: Supported-Platform multiple use, Prev: Version, Up: Core metadata specifications
+
+5.1.1.4 Platform (multiple use)
+...............................
+
+New in version 1.0.
+
+A Platform specification describing an operating system supported by the
+distribution which is not listed in the “Operating System” Trove
+classifiers. See “Classifier” below.
+
+Examples:
+
+ Platform: ObscureUnix
+ Platform: RareDOS
+
+
+File: pythonpackagingguide.info, Node: Supported-Platform multiple use, Next: Summary, Prev: Platform multiple use, Up: Core metadata specifications
+
+5.1.1.5 Supported-Platform (multiple use)
+.........................................
+
+New in version 1.1.
+
+Binary distributions containing a PKG-INFO file will use the
+Supported-Platform field in their metadata to specify the OS and CPU for
+which the binary distribution was compiled. The semantics of the
+Supported-Platform field are not specified in this PEP.
+
+Example:
+
+ Supported-Platform: RedHat 7.2
+ Supported-Platform: i386-win32-2791
+
+
+File: pythonpackagingguide.info, Node: Summary, Next: Description, Prev: Supported-Platform multiple use, Up: Core metadata specifications
+
+5.1.1.6 Summary
+...............
+
+New in version 1.0.
+
+A one-line summary of what the distribution does.
+
+Example:
+
+ Summary: A module for collecting votes from beagles.
+
+
+File: pythonpackagingguide.info, Node: Description, Next: Description-Content-Type, Prev: Summary, Up: Core metadata specifications
+
+5.1.1.7 Description
+...................
+
+New in version 1.0.
+
+Changed in version 2.1: This field may be specified in the message body
+instead.
+
+A longer description of the distribution that can run to several
+paragraphs. Software that deals with metadata should not assume any
+maximum size for this field, though people shouldn’t include their
+instruction manual as the description.
+
+The contents of this field can be written using reStructuredText markup
+(1). For programs that work with the metadata, supporting markup is
+optional; programs can also display the contents of the field as-is.
+This means that authors should be conservative in the markup they use.
+
+To support empty lines and lines with indentation with respect to the
+RFC 822 format, any CRLF character has to be suffixed by 7 spaces
+followed by a pipe (“|”) char. As a result, the Description field is
+encoded into a folded field that can be interpreted by RFC822 parser
+(2).
+
+Example:
+
+ Description: This project provides powerful math functions
+ |For example, you can use `sum()` to sum numbers:
+ |
+ |Example::
+ |
+ | >>> sum(1, 2)
+ | 3
+ |
+
+This encoding implies that any occurrences of a CRLF followed by 7
+spaces and a pipe char have to be replaced by a single CRLF when the
+field is unfolded using a RFC822 reader.
+
+Alternatively, the distribution’s description may instead be provided in
+the message body (i.e., after a completely blank line following the
+headers, with no indentation or other special formatting necessary).
+
+ ---------- Footnotes ----------
+
+ (1) (1) reStructuredText markup: ‘http://docutils.sourceforge.net/’
+
+ (2) (2) RFC 822 Long Header Fields:
+‘http://www.freesoft.org/CIE/RFC/822/7.htm’
+
+
+File: pythonpackagingguide.info, Node: Description-Content-Type, Next: Keywords, Prev: Description, Up: Core metadata specifications
+
+5.1.1.8 Description-Content-Type
+................................
+
+New in version 2.1.
+
+A string stating the markup syntax (if any) used in the distribution’s
+description, so that tools can intelligently render the description.
+
+Historically, PyPI supported descriptions in plain text and
+reStructuredText (reST)(1), and could render reST into HTML. However, it
+is common for distribution authors to write the description in
+Markdown(2) (RFC 7763(3)) as many code hosting sites render Markdown
+READMEs, and authors would reuse the file for the description. PyPI
+didn’t recognize the format and so could not render the description
+correctly. This resulted in many packages on PyPI with poorly-rendered
+descriptions when Markdown is left as plain text, or worse, was
+attempted to be rendered as reST. This field allows the distribution
+author to specify the format of their description, opening up the
+possibility for PyPI and other tools to be able to render Markdown and
+other formats.
+
+The format of this field is the same as the ‘Content-Type’ header in
+HTTP (i.e.: RFC 1341(4)). Briefly, this means that it has a
+‘type/subtype’ part and then it can optionally have a number of
+parameters:
+
+Format:
+
+ Description-Content-Type: <type>/<subtype>; charset=<charset>[; <param_name>=<param value> ...]
+
+The ‘type/subtype’ part has only a few legal values:
+
+ - ‘text/plain’
+
+ - ‘text/x-rst’
+
+ - ‘text/markdown’
+
+The ‘charset’ parameter can be used to specify the character encoding of
+the description. The only legal value is ‘UTF-8’. If omitted, it is
+assumed to be ‘UTF-8’.
+
+Other parameters might be specific to the chosen subtype. For example,
+for the ‘markdown’ subtype, there is an optional ‘variant’ parameter
+that allows specifying the variant of Markdown in use (defaults to ‘GFM’
+if not specified). Currently, two variants are recognized:
+
+ - ‘GFM’ for Github-flavored Markdown(5)
+
+ - ‘CommonMark’ for CommonMark(6)
+
+Example:
+
+ Description-Content-Type: text/plain; charset=UTF-8
+
+Example:
+
+ Description-Content-Type: text/x-rst; charset=UTF-8
+
+Example:
+
+ Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM
+
+Example:
+
+ Description-Content-Type: text/markdown
+
+If a ‘Description-Content-Type’ is not specified, then applications
+should attempt to render it as ‘text/x-rst; charset=UTF-8’ and fall back
+to ‘text/plain’ if it is not valid rst.
+
+If a ‘Description-Content-Type’ is an unrecognized value, then the
+assumed content type is ‘text/plain’ (Although PyPI will probably reject
+anything with an unrecognized value).
+
+If the ‘Description-Content-Type’ is ‘text/markdown’ and ‘variant’ is
+not specified or is set to an unrecognized value, then the assumed
+‘variant’ is ‘GFM’.
+
+So for the last example above, the ‘charset’ defaults to ‘UTF-8’ and the
+‘variant’ defaults to ‘GFM’ and thus it is equivalent to the example
+before it.
+
+ ---------- Footnotes ----------
+
+ (1)
+http://docutils.sourceforge.net/docs/ref/rst/restructuredtext.html
+
+ (2) https://daringfireball.net/projects/markdown/
+
+ (3) https://tools.ietf.org/html/rfc7763
+
+ (4) https://www.w3.org/Protocols/rfc1341/4_Content-Type.html
+
+ (5) https://tools.ietf.org/html/rfc7764#section-3.2
+
+ (6) https://tools.ietf.org/html/rfc7764#section-3.5
+
+
+File: pythonpackagingguide.info, Node: Keywords, Next: Home-page, Prev: Description-Content-Type, Up: Core metadata specifications
+
+5.1.1.9 Keywords
+................
+
+New in version 1.0.
+
+A list of additional keywords, separated by commas, to be used to assist
+searching for the distribution in a larger catalog.
+
+Example:
+
+ Keywords: dog,puppy,voting,election
+
+ Note: The specification previously showed keywords separated by
+ spaces, but distutils and setuptools implemented it with commas.
+ These tools have been very widely used for many years, so it was
+ easier to update the specification to match the de facto standard.
+
+
+File: pythonpackagingguide.info, Node: Home-page, Next: Download-URL, Prev: Keywords, Up: Core metadata specifications
+
+5.1.1.10 Home-page
+..................
+
+New in version 1.0.
+
+A string containing the URL for the distribution’s home page.
+
+Example:
+
+ Home-page: http://www.example.com/~cschultz/bvote/
+
+
+File: pythonpackagingguide.info, Node: Download-URL, Next: Author, Prev: Home-page, Up: Core metadata specifications
+
+5.1.1.11 Download-URL
+.....................
+
+New in version 1.1.
+
+A string containing the URL from which this version of the distribution
+can be downloaded. (This means that the URL can’t be something like
+“…/BeagleVote-latest.tgz”, but instead must be “…/BeagleVote-0.45.tgz”.)
+
+
+File: pythonpackagingguide.info, Node: Author, Next: Author-email, Prev: Download-URL, Up: Core metadata specifications
+
+5.1.1.12 Author
+...............
+
+New in version 1.0.
+
+A string containing the author’s name at a minimum; additional contact
+information may be provided.
+
+Example:
+
+ Author: C. Schultz, Universal Features Syndicate,
+ Los Angeles, CA <cschultz@peanuts.example.com>
+
+
+File: pythonpackagingguide.info, Node: Author-email, Next: Maintainer, Prev: Author, Up: Core metadata specifications
+
+5.1.1.13 Author-email
+.....................
+
+New in version 1.0.
+
+A string containing the author’s e-mail address. It can contain a name
+and e-mail address in the legal forms for a RFC-822 ‘From:’ header.
+
+Example:
+
+ Author-email: "C. Schultz" <cschultz@example.com>
+
+Per RFC-822, this field may contain multiple comma-separated e-mail
+addresses:
+
+ Author-email: cschultz@example.com, snoopy@peanuts.com
+
+
+File: pythonpackagingguide.info, Node: Maintainer, Next: Maintainer-email, Prev: Author-email, Up: Core metadata specifications
+
+5.1.1.14 Maintainer
+...................
+
+New in version 1.2.
+
+A string containing the maintainer’s name at a minimum; additional
+contact information may be provided.
+
+Note that this field is intended for use when a project is being
+maintained by someone other than the original author: it should be
+omitted if it is identical to ‘Author’.
+
+Example:
+
+ Maintainer: C. Schultz, Universal Features Syndicate,
+ Los Angeles, CA <cschultz@peanuts.example.com>
+
+
+File: pythonpackagingguide.info, Node: Maintainer-email, Next: License, Prev: Maintainer, Up: Core metadata specifications
+
+5.1.1.15 Maintainer-email
+.........................
+
+New in version 1.2.
+
+A string containing the maintainer’s e-mail address. It can contain a
+name and e-mail address in the legal forms for a RFC-822 ‘From:’ header.
+
+Note that this field is intended for use when a project is being
+maintained by someone other than the original author: it should be
+omitted if it is identical to ‘Author-email’.
+
+Example:
+
+ Maintainer-email: "C. Schultz" <cschultz@example.com>
+
+Per RFC-822, this field may contain multiple comma-separated e-mail
+addresses:
+
+ Maintainer-email: cschultz@example.com, snoopy@peanuts.com
+
+
+File: pythonpackagingguide.info, Node: License, Next: Classifier multiple use, Prev: Maintainer-email, Up: Core metadata specifications
+
+5.1.1.16 License
+................
+
+New in version 1.0.
+
+Text indicating the license covering the distribution where the license
+is not a selection from the “License” Trove classifiers. See *note
+“Classifier”: 1bd. below. This field may also be used to specify a
+particular version of a license which is named via the ‘Classifier’
+field, or to indicate a variation or exception to such a license.
+
+Examples:
+
+ License: This software may only be obtained by sending the
+ author a postcard, and then the user promises not
+ to redistribute it.
+
+ License: GPL version 3, excluding DRM provisions
+
+
+File: pythonpackagingguide.info, Node: Classifier multiple use, Next: Requires-Dist multiple use, Prev: License, Up: Core metadata specifications
+
+5.1.1.17 Classifier (multiple use)
+..................................
+
+New in version 1.1.
+
+Each entry is a string giving a single classification value for the
+distribution. Classifiers are described in PEP 301(1), and the Python
+Package Index publishes a dynamic list of currently defined
+classifiers(2).
+
+This field may be followed by an environment marker after a semicolon.
+
+Examples:
+
+ Classifier: Development Status :: 4 - Beta
+ Classifier: Environment :: Console (Text Based)
+
+ ---------- Footnotes ----------
+
+ (1) https://www.python.org/dev/peps/pep-0301
+
+ (2) https://pypi.org/classifiers/
+
+
+File: pythonpackagingguide.info, Node: Requires-Dist multiple use, Next: Requires-Python, Prev: Classifier multiple use, Up: Core metadata specifications
+
+5.1.1.18 Requires-Dist (multiple use)
+.....................................
+
+New in version 1.2.
+
+Changed in version 2.1: The field format specification was relaxed to
+accept the syntax used by popular publishing tools.
+
+Each entry contains a string naming some other distutils project
+required by this distribution.
+
+The format of a requirement string contains from one to four parts:
+
+ * A project name, in the same format as the ‘Name:’ field. The only
+ mandatory part.
+
+ * A comma-separated list of ‘extra’ names. These are defined by the
+ required project, referring to specific features which may need
+ extra dependencies.
+
+ * A version specifier. Tools parsing the format should accept
+ optional parentheses around this, but tools generating it should
+ not use parentheses.
+
+ * An environment marker after a semicolon. This means that the
+ requirement is only needed in the specified conditions.
+
+See PEP 508(1) for full details of the allowed format.
+
+The project names should correspond to names as found on the Python
+Package Index(2).
+
+Version specifiers must follow the rules described in *note Version
+specifiers: 1c2.
+
+Examples:
+
+ Requires-Dist: pkginfo
+ Requires-Dist: PasteDeploy
+ Requires-Dist: zope.interface (>3.5.0)
+ Requires-Dist: pywin32 >1.0; sys_platform == 'win32'
+
+ ---------- Footnotes ----------
+
+ (1) https://www.python.org/dev/peps/pep-0508
+
+ (2) http://pypi.org/
+
+
+File: pythonpackagingguide.info, Node: Requires-Python, Next: Requires-External multiple use, Prev: Requires-Dist multiple use, Up: Core metadata specifications
+
+5.1.1.19 Requires-Python
+........................
+
+New in version 1.2.
+
+This field specifies the Python version(s) that the distribution is
+guaranteed to be compatible with. Installation tools may look at this
+when picking which version of a project to install.
+
+The value must be in the format specified in *note Version specifiers:
+1c2.
+
+This field cannot be followed by an environment marker.
+
+Examples:
+
+ Requires-Python: >=3
+ Requires-Python: >2.6,!=3.0.*,!=3.1.*
+ Requires-Python: ~=2.6
+
+
+File: pythonpackagingguide.info, Node: Requires-External multiple use, Next: Project-URL multiple-use, Prev: Requires-Python, Up: Core metadata specifications
+
+5.1.1.20 Requires-External (multiple use)
+.........................................
+
+New in version 1.2.
+
+Changed in version 2.1: The field format specification was relaxed to
+accept the syntax used by popular publishing tools.
+
+Each entry contains a string describing some dependency in the system
+that the distribution is to be used. This field is intended to serve as
+a hint to downstream project maintainers, and has no semantics which are
+meaningful to the ‘distutils’ distribution.
+
+The format of a requirement string is a name of an external dependency,
+optionally followed by a version declaration within parentheses.
+
+This field may be followed by an environment marker after a semicolon.
+
+Because they refer to non-Python software releases, version numbers for
+this field are `not' required to conform to the format specified in PEP
+440(1): they should correspond to the version scheme used by the
+external dependency.
+
+Notice that there is no particular rule on the strings to be used.
+
+Examples:
+
+ Requires-External: C
+ Requires-External: libpng (>=1.5)
+ Requires-External: make; sys_platform != "win32"
+
+ ---------- Footnotes ----------
+
+ (1) https://www.python.org/dev/peps/pep-0440
+
+
+File: pythonpackagingguide.info, Node: Project-URL multiple-use, Next: Provides-Extra multiple use, Prev: Requires-External multiple use, Up: Core metadata specifications
+
+5.1.1.21 Project-URL (multiple-use)
+...................................
+
+New in version 1.2.
+
+A string containing a browsable URL for the project and a label for it,
+separated by a comma.
+
+Example:
+
+ Project-URL: Bug Tracker, http://bitbucket.org/tarek/distribute/issues/
+
+The label is free text limited to 32 characters.
+
+
+File: pythonpackagingguide.info, Node: Provides-Extra multiple use, Next: Rarely Used Fields, Prev: Project-URL multiple-use, Up: Core metadata specifications
+
+5.1.1.22 Provides-Extra (multiple use)
+......................................
+
+New in version 2.1.
+
+A string containing the name of an optional feature. Must be a valid
+Python identifier. May be used to make a dependency conditional on
+whether the optional feature has been requested.
+
+Example:
+
+ Provides-Extra: pdf
+ Requires-Dist: reportlab; extra == 'pdf'
+
+A second distribution requires an optional dependency by placing it
+inside square brackets, and can request multiple features by separating
+them with a comma (,). The requirements are evaluated for each
+requested feature and added to the set of requirements for the
+distribution.
+
+Example:
+
+ Requires-Dist: beaglevote[pdf]
+ Requires-Dist: libexample[test, doc]
+
+Two feature names ‘test’ and ‘doc’ are reserved to mark dependencies
+that are needed for running automated tests and generating
+documentation, respectively.
+
+It is legal to specify ‘Provides-Extra:’ without referencing it in any
+‘Requires-Dist:’.
+
+
+File: pythonpackagingguide.info, Node: Rarely Used Fields, Prev: Provides-Extra multiple use, Up: Core metadata specifications
+
+5.1.1.23 Rarely Used Fields
+...........................
+
+The fields in this section are currently rarely used, as their design
+was inspired by comparable mechanisms in Linux package management
+systems, and it isn’t at all clear how tools should interpret them in
+the context of an open index server such as PyPI(1).
+
+As a result, popular installation tools ignore them completely, which in
+turn means there is little incentive for package publishers to set them
+appropriately. However, they’re retained in the metadata specification,
+as they’re still potentially useful for informational purposes, and can
+also be used for their originally intended purpose in combination with a
+curated package repository.
+
+* Menu:
+
+* Provides-Dist (multiple use): Provides-Dist multiple use.
+* Obsoletes-Dist (multiple use): Obsoletes-Dist multiple use.
+
+ ---------- Footnotes ----------
+
+ (1) https://pypi.org
+
+
+File: pythonpackagingguide.info, Node: Provides-Dist multiple use, Next: Obsoletes-Dist multiple use, Up: Rarely Used Fields
+
+5.1.1.24 Provides-Dist (multiple use)
+.....................................
+
+New in version 1.2.
+
+Changed in version 2.1: The field format specification was relaxed to
+accept the syntax used by popular publishing tools.
+
+Each entry contains a string naming a Distutils project which is
+contained within this distribution. This field `must' include the
+project identified in the ‘Name’ field, followed by the version : Name
+(Version).
+
+A distribution may provide additional names, e.g. to indicate that
+multiple projects have been bundled together. For instance, source
+distributions of the ‘ZODB’ project have historically included the
+‘transaction’ project, which is now available as a separate
+distribution. Installing such a source distribution satisfies
+requirements for both ‘ZODB’ and ‘transaction’.
+
+A distribution may also provide a “virtual” project name, which does not
+correspond to any separately-distributed project: such a name might be
+used to indicate an abstract capability which could be supplied by one
+of multiple projects. E.g., multiple projects might supply RDBMS
+bindings for use by a given ORM: each project might declare that it
+provides ‘ORM-bindings’, allowing other projects to depend only on
+having at most one of them installed.
+
+A version declaration may be supplied and must follow the rules
+described in *note Version specifiers: 1c2. The distribution’s version
+number will be implied if none is specified.
+
+This field may be followed by an environment marker after a semicolon.
+
+Examples:
+
+ Provides-Dist: OtherProject
+ Provides-Dist: AnotherProject (3.4)
+ Provides-Dist: virtual_package; python_version >= "3.4"
+
+
+File: pythonpackagingguide.info, Node: Obsoletes-Dist multiple use, Prev: Provides-Dist multiple use, Up: Rarely Used Fields
+
+5.1.1.25 Obsoletes-Dist (multiple use)
+......................................
+
+New in version 1.2.
+
+Changed in version 2.1: The field format specification was relaxed to
+accept the syntax used by popular publishing tools.
+
+Each entry contains a string describing a distutils project’s
+distribution which this distribution renders obsolete, meaning that the
+two projects should not be installed at the same time.
+
+Version declarations can be supplied. Version numbers must be in the
+format specified in *note Version specifiers: 1c2.
+
+This field may be followed by an environment marker after a semicolon.
+
+The most common use of this field will be in case a project name
+changes, e.g. Gorgon 2.3 gets subsumed into Torqued Python 1.0. When
+you install Torqued Python, the Gorgon distribution should be removed.
+
+Examples:
+
+ Obsoletes-Dist: Gorgon
+ Obsoletes-Dist: OtherProject (<3.0)
+ Obsoletes-Dist: Foo; os_name == "posix"
+
+__________________________________________________________________
+
+
+File: pythonpackagingguide.info, Node: Version specifiers, Next: Dependency specifiers, Prev: Core metadata specifications, Up: Package Distribution Metadata
+
+5.1.2 Version specifiers
+------------------------
+
+Version numbering requirements and the semantics for specifying
+comparisons between versions are defined in PEP 440(1).
+
+The version specifiers section in this PEP supersedes the version
+specifiers section in PEP 345(2).
+
+ ---------- Footnotes ----------
+
+ (1) https://www.python.org/dev/peps/pep-0440
+
+ (2) https://www.python.org/dev/peps/pep-0345
+
+
+File: pythonpackagingguide.info, Node: Dependency specifiers, Next: Declaring build system dependencies, Prev: Version specifiers, Up: Package Distribution Metadata
+
+5.1.3 Dependency specifiers
+---------------------------
+
+The dependency specifier format used to declare a dependency on another
+component is defined in PEP 508(1).
+
+The environment markers section in this PEP supersedes the environment
+markers section in PEP 345(2).
+
+ ---------- Footnotes ----------
+
+ (1) https://www.python.org/dev/peps/pep-0508
+
+ (2) https://www.python.org/dev/peps/pep-0345
+
+
+File: pythonpackagingguide.info, Node: Declaring build system dependencies, Next: Declaring project metadata, Prev: Dependency specifiers, Up: Package Distribution Metadata
+
+5.1.4 Declaring build system dependencies
+-----------------------------------------
+
+*note pyproject.toml: 1d7. is a build system independent file format
+defined in PEP 518(1) that projects may provide in order to declare any
+Python level dependencies that must be installed in order to run the
+project’s build system successfully.
+
+ ---------- Footnotes ----------
+
+ (1) https://www.python.org/dev/peps/pep-0518
+
+
+File: pythonpackagingguide.info, Node: Declaring project metadata, Next: Distribution formats, Prev: Declaring build system dependencies, Up: Package Distribution Metadata
+
+5.1.5 Declaring project metadata
+--------------------------------
+
+PEP 621(1) specifies how to write a project’s *note core metadata: 85.
+in a ‘pyproject.toml’ file for packaging-related tools to consume. It
+defines the following specification as the canonical source for the
+format used.
+
+There are two kinds of metadata: `static' and `dynamic'. Static
+metadata is specified in the ‘pyproject.toml’ file directly and cannot
+be specified or changed by a tool. Dynamic metadata is listed via the
+‘dynamic’ field (defined later in this specification) and represents
+metadata that a tool will later provide.
+
+The fields defined in this specification MUST be in a table named
+‘[project]’ in ‘pyproject.toml’. No tools may add fields to this table
+which are not defined by this specification. For tools wishing to store
+their own settings in ‘pyproject.toml’, they may use the ‘[tool]’ table
+as defined in the *note build dependency decleration specification: 1d5.
+The lack of a ‘[project]’ table implicitly means the build back-end will
+dynamically provide all fields.
+
+The only fields required to be statically defined are:
+
+ - ‘name’
+
+The fields which are required but may be specified `either' statically
+or listed as dynamic are:
+
+ - ‘version’
+
+All other fields are considered optional and my be specified statically,
+listed as dynamic, or left unspecified.
+
+* Menu:
+
+* name: name<2>.
+* version: version<2>.
+* description: description<2>.
+* readme::
+* requires-python::
+* license: license<2>.
+* authors/maintainers::
+* keywords: keywords<2>.
+* classifiers: classifiers<2>.
+* urls::
+* Entry points::
+* dependencies/optional-dependencies::
+* dynamic::
+
+ ---------- Footnotes ----------
+
+ (1) https://www.python.org/dev/peps/pep-0621
+
+
+File: pythonpackagingguide.info, Node: name<2>, Next: version<2>, Up: Declaring project metadata
+
+5.1.5.1 ‘name’
+..............
+
+ - TOML(1) type: string
+
+ - Corresponding *note core metadata: 85. field: *note Name: 19c.
+
+The name of the project.
+
+Tools SHOULD normalize this name, as specified by PEP 503(2), as soon as
+it is read for internal consistency.
+
+ ---------- Footnotes ----------
+
+ (1) https://toml.io/
+
+ (2) https://www.python.org/dev/peps/pep-0503
+
+
+File: pythonpackagingguide.info, Node: version<2>, Next: description<2>, Prev: name<2>, Up: Declaring project metadata
+
+5.1.5.2 ‘version’
+.................
+
+ - TOML(1) type: string
+
+ - Corresponding *note core metadata: 85. field: *note Version: 19e.
+
+The version of the project as supported by PEP 440(2).
+
+Users SHOULD prefer to specify already-normalized versions.
+
+ ---------- Footnotes ----------
+
+ (1) https://toml.io/
+
+ (2) https://www.python.org/dev/peps/pep-0440
+
+
+File: pythonpackagingguide.info, Node: description<2>, Next: readme, Prev: version<2>, Up: Declaring project metadata
+
+5.1.5.3 ‘description’
+.....................
+
+ - TOML(1) type: string
+
+ - Corresponding *note core metadata: 85. field: *note Summary: 1a2.
+
+The summary description of the project.
+
+ ---------- Footnotes ----------
+
+ (1) https://toml.io/
+
+
+File: pythonpackagingguide.info, Node: readme, Next: requires-python, Prev: description<2>, Up: Declaring project metadata
+
+5.1.5.4 ‘readme’
+................
+
+ - TOML(1) type: string or table
+
+ - Corresponding *note core metadata: 85. field: *note Description:
+ 1a4. and *note Description-Content-Type: 1a6.
+
+The full description of the project (i.e. the README).
+
+The field accepts either a string or a table. If it is a string then it
+is a path relative to ‘pyproject.toml’ to a text file containing the
+full description. Tools MUST assume the file’s encoding is UTF-8. If
+the file path ends in a case-insensitive ‘.md’ suffix, then tools MUST
+assume the content-type is ‘text/markdown’. If the file path ends in a
+case-insensitive ‘.rst’, then tools MUST assume the content-type is
+‘text/x-rst’. If a tool recognizes more extensions than this PEP, they
+MAY infer the content-type for the user without specifying this field as
+‘dynamic’. For all unrecognized suffixes when a content-type is not
+provided, tools MUST raise an error.
+
+The ‘readme’ field may also take a table. The ‘file’ key has a string
+value representing a path relative to ‘pyproject.toml’ to a file
+containing the full description. The ‘text’ key has a string value
+which is the full description. These keys are mutually-exclusive, thus
+tools MUST raise an error if the metadata specifies both keys.
+
+A table specified in the ‘readme’ field also has a ‘content-type’ field
+which takes a string specifying the content-type of the full
+description. A tool MUST raise an error if the metadata does not
+specify this field in the table. If the metadata does not specify the
+‘charset’ parameter, then it is assumed to be UTF-8. Tools MAY support
+other encodings if they choose to. Tools MAY support alternative
+content-types which they can transform to a content-type as supported by
+the *note core metadata: 85. Otherwise tools MUST raise an error for
+unsupported content-types.
+
+ ---------- Footnotes ----------
+
+ (1) https://toml.io/
+
+
+File: pythonpackagingguide.info, Node: requires-python, Next: license<2>, Prev: readme, Up: Declaring project metadata
+
+5.1.5.5 ‘requires-python’
+.........................
+
+ - TOML(1) type: string
+
+ - Corresponding *note core metadata: 85. field: *note
+ Requires-Python: 1c3.
+
+The Python version requirements of the project.
+
+ ---------- Footnotes ----------
+
+ (1) https://toml.io/
+
+
+File: pythonpackagingguide.info, Node: license<2>, Next: authors/maintainers, Prev: requires-python, Up: Declaring project metadata
+
+5.1.5.6 ‘license’
+.................
+
+ - TOML(1) type: table
+
+ - Corresponding *note core metadata: 85. field: *note License: 1bb.
+
+The table may have one of two keys. The ‘file’ key has a string value
+that is a file path relative to ‘pyproject.toml’ to the file which
+contains the license for the project. Tools MUST assume the file’s
+encoding is UTF-8. The ‘text’ key has a string value which is the
+license of the project. These keys are mutually exclusive, so a tool
+MUST raise an error if the metadata specifies both keys.
+
+ ---------- Footnotes ----------
+
+ (1) https://toml.io/
+
+
+File: pythonpackagingguide.info, Node: authors/maintainers, Next: keywords<2>, Prev: license<2>, Up: Declaring project metadata
+
+5.1.5.7 ‘authors’/‘maintainers’
+...............................
+
+ - TOML(1) type: Array of inline tables with string keys and values
+
+ - Corresponding *note core metadata: 85. field: *note Author: 1b0,
+ *note Author-email: 1b3, *note Maintainer: 1b5, and *note
+ Maintainer-email: 1b8.
+
+The people or organizations considered to be the “authors” of the
+project. The exact meaning is open to interpretation — it may list the
+original or primary authors, current maintainers, or owners of the
+package.
+
+The “maintainers” field is similar to “authors” in that its exact
+meaning is open to interpretation.
+
+These fields accept an array of tables with 2 keys: ‘name’ and ‘email’.
+Both values must be strings. The ‘name’ value MUST be a valid email
+name (i.e. whatever can be put as a name, before an email, in RFC
+822(2)) and not contain commas. The ‘email’ value MUST be a valid email
+address. Both keys are optional.
+
+Using the data to fill in *note core metadata: 85. is as follows:
+
+ 1. If only ‘name’ is provided, the value goes in *note Author: 1b0. or
+ *note Maintainer: 1b5. as appropriate.
+
+ 2. If only ‘email’ is provided, the value goes in *note Author-email:
+ 1b3. or *note Maintainer-email: 1b8. as appropriate.
+
+ 3. If both ‘email’ and ‘name’ are provided, the value goes in *note
+ Author-email: 1b3. or *note Maintainer-email: 1b8. as appropriate,
+ with the format ‘{name} <{email}>’.
+
+ 4. Multiple values should be separated by commas.
+
+ ---------- Footnotes ----------
+
+ (1) https://toml.io/
+
+ (2) https://tools.ietf.org/html/rfc822
+
+
+File: pythonpackagingguide.info, Node: keywords<2>, Next: classifiers<2>, Prev: authors/maintainers, Up: Declaring project metadata
+
+5.1.5.8 ‘keywords’
+..................
+
+ - TOML(1) type: array of strings
+
+ - Corresponding *note core metadata: 85. field: *note Keywords: 1a9.
+
+The keywords for the project.
+
+ ---------- Footnotes ----------
+
+ (1) https://toml.io/
+
+
+File: pythonpackagingguide.info, Node: classifiers<2>, Next: urls, Prev: keywords<2>, Up: Declaring project metadata
+
+5.1.5.9 ‘classifiers’
+.....................
+
+ - TOML(1) type: array of strings
+
+ - Corresponding *note core metadata: 85. field: *note Classifier:
+ 1bf.
+
+Trove classifiers which apply to the project.
+
+ ---------- Footnotes ----------
+
+ (1) https://toml.io/
+
+
+File: pythonpackagingguide.info, Node: urls, Next: Entry points, Prev: classifiers<2>, Up: Declaring project metadata
+
+5.1.5.10 ‘urls’
+...............
+
+ - TOML(1) type: table with keys and values of strings
+
+ - Corresponding *note core metadata: 85. field: *note Project-URL:
+ 1c6.
+
+A table of URLs where the key is the URL label and the value is the URL
+itself.
+
+ ---------- Footnotes ----------
+
+ (1) https://toml.io/
+
+
+File: pythonpackagingguide.info, Node: Entry points, Next: dependencies/optional-dependencies, Prev: urls, Up: Declaring project metadata
+
+5.1.5.11 Entry points
+.....................
+
+ - TOML(1) type: table (‘[project.scripts]’, ‘[project.gui-scripts]’,
+ and ‘[project.entry-points]’)
+
+ - *note Entry points specification: 1e6.
+
+There are three tables related to entry points. The ‘[project.scripts]’
+table corresponds to the ‘console_scripts’ group in the *note entry
+points specification: 1e6. The key of the table is the name of the
+entry point and the value is the object reference.
+
+The ‘[project.gui-scripts]’ table corresponds to the ‘gui_scripts’ group
+in the *note entry points specification: 1e6. Its format is the same as
+‘[project.scripts]’.
+
+The ‘[project.entry-points]’ table is a collection of tables. Each
+sub-table’s name is an entry point group. The key and value semantics
+are the same as ‘[project.scripts]’. Users MUST NOT create nested
+sub-tables but instead keep the entry point groups to only one level
+deep.
+
+Build back-ends MUST raise an error if the metadata defines a
+‘[project.entry-points.console_scripts]’ or
+‘[project.entry-points.gui_scripts]’ table, as they would be ambiguous
+in the face of ‘[project.scripts]’ and ‘[project.gui-scripts]’,
+respectively.
+
+ ---------- Footnotes ----------
+
+ (1) https://toml.io/
+
+
+File: pythonpackagingguide.info, Node: dependencies/optional-dependencies, Next: dynamic, Prev: Entry points, Up: Declaring project metadata
+
+5.1.5.12 ‘dependencies’/‘optional-dependencies’
+...............................................
+
+ - TOML(1) type: Array of PEP 508(2) strings (‘dependencies’), and a
+ table with values of arrays of PEP 508(3) strings
+ (‘optional-dependencies’)
+
+ - Corresponding *note core metadata: 85. field: *note Requires-Dist:
+ 1c0. and *note Provides-Extra: 1c9.
+
+The (optional) dependencies of the project.
+
+For ‘dependencies’, it is a key whose value is an array of strings.
+Each string represents a dependency of the project and MUST be formatted
+as a valid PEP 508(4) string. Each string maps directly to a *note
+Requires-Dist: 1c0. entry.
+
+For ‘optional-dependencies’, it is a table where each key specifies an
+extra and whose value is an array of strings. The strings of the arrays
+must be valid PEP 508(5) strings. The keys MUST be valid values for
+*note Provides-Extra: 1c9. Each value in the array thus becomes a
+corresponding *note Requires-Dist: 1c0. entry for the matching *note
+Provides-Extra: 1c9. metadata.
+
+ ---------- Footnotes ----------
+
+ (1) https://toml.io/
+
+ (2) https://www.python.org/dev/peps/pep-0508
+
+ (3) https://www.python.org/dev/peps/pep-0508
+
+ (4) https://www.python.org/dev/peps/pep-0508
+
+ (5) https://www.python.org/dev/peps/pep-0508
+
+
+File: pythonpackagingguide.info, Node: dynamic, Prev: dependencies/optional-dependencies, Up: Declaring project metadata
+
+5.1.5.13 ‘dynamic’
+..................
+
+ - TOML(1) type: array of string
+
+ - A corresponding *note core metadata: 85. field does not exist
+
+Specifies which fields listed by this PEP were intentionally unspecified
+so another tool can/will provide such metadata dynamically. This
+clearly delineates which metadata is purposefully unspecified and
+expected to stay unspecified compared to being provided via tooling
+later on.
+
+ - A build back-end MUST honour statically-specified metadata (which
+ means the metadata did not list the field in ‘dynamic’).
+
+ - A build back-end MUST raise an error if the metadata specifies
+ ‘name’ in ‘dynamic’.
+
+ - If the *note core metadata: 85. specification lists a field as
+ “Required”, then the metadata MUST specify the field statically or
+ list it in ‘dynamic’ (build back-ends MUST raise an error
+ otherwise, i.e. it should not be possible for a required field to
+ not be listed somehow in the ‘[project]’ table).
+
+ - If the *note core metadata: 85. specification lists a field as
+ “Optional”, the metadata MAY list it in ‘dynamic’ if the
+ expectation is a build back-end will provide the data for the field
+ later.
+
+ - Build back-ends MUST raise an error if the metadata specifies a
+ field statically as well as being listed in ‘dynamic’.
+
+ - If the metadata does not list a field in ‘dynamic’, then a build
+ back-end CANNOT fill in the requisite metadata on behalf of the
+ user (i.e. ‘dynamic’ is the only way to allow a tool to fill in
+ metadata and the user must opt into the filling in).
+
+ - Build back-ends MUST raise an error if the metadata specifies a
+ field in ‘dynamic’ but the build back-end was unable to determine
+ the data for it (omitting the data, if determined to be the
+ accurate value, is acceptable).
+
+ ---------- Footnotes ----------
+
+ (1) https://toml.io/
+
+
+File: pythonpackagingguide.info, Node: Distribution formats, Next: Platform compatibility tags, Prev: Declaring project metadata, Up: Package Distribution Metadata
+
+5.1.6 Distribution formats
+--------------------------
+
+* Menu:
+
+* Source distribution format::
+* Binary distribution format::
+
+
+File: pythonpackagingguide.info, Node: Source distribution format, Next: Binary distribution format, Up: Distribution formats
+
+5.1.6.1 Source distribution format
+..................................
+
+The accepted style of source distribution format based on
+‘pyproject.toml’, defined in PEP 518(1) and adopted by PEP 517(2) has
+not been implemented yet.
+
+There is also the legacy source distribution format, implicitly defined
+by the behaviour of ‘distutils’ module in the standard library, when
+executing ‘setup.py sdist’.
+
+ ---------- Footnotes ----------
+
+ (1) https://www.python.org/dev/peps/pep-0518
+
+ (2) https://www.python.org/dev/peps/pep-0517
+
+
+File: pythonpackagingguide.info, Node: Binary distribution format, Prev: Source distribution format, Up: Distribution formats
+
+5.1.6.2 Binary distribution format
+..................................
+
+The binary distribution format (‘wheel’) is defined in PEP 427(1).
+
+ ---------- Footnotes ----------
+
+ (1) https://www.python.org/dev/peps/pep-0427
+
+
+File: pythonpackagingguide.info, Node: Platform compatibility tags, Next: Recording installed projects, Prev: Distribution formats, Up: Package Distribution Metadata
+
+5.1.7 Platform compatibility tags
+---------------------------------
+
+Platform compatibility tags allow build tools to mark distributions as
+being compatible with specific platforms, and allows installers to
+understand which distributions are compatible with the system they are
+running on.
+
+The platform compatibility tagging model used for the ‘wheel’
+distribution format is defined in PEP 425(1).
+
+* Menu:
+
+* Platform tags for Windows::
+* Platform tags for macOS (Mac OS X): Platform tags for macOS Mac OS X.
+* Platform tags for common Linux distributions::
+* Platform tags for other *nix platforms::
+
+ ---------- Footnotes ----------
+
+ (1) https://www.python.org/dev/peps/pep-0425
+
+
+File: pythonpackagingguide.info, Node: Platform tags for Windows, Next: Platform tags for macOS Mac OS X, Up: Platform compatibility tags
+
+5.1.7.1 Platform tags for Windows
+.................................
+
+The scheme defined in PEP 425(1) covers public distribution of wheel
+files to systems running Windows.
+
+ ---------- Footnotes ----------
+
+ (1) https://www.python.org/dev/peps/pep-0425
+
+
+File: pythonpackagingguide.info, Node: Platform tags for macOS Mac OS X, Next: Platform tags for common Linux distributions, Prev: Platform tags for Windows, Up: Platform compatibility tags
+
+5.1.7.2 Platform tags for macOS (Mac OS X)
+..........................................
+
+The scheme defined in PEP 425(1) covers public distribution of wheel
+files to systems running macOS (previously known as Mac OS X).
+
+ ---------- Footnotes ----------
+
+ (1) https://www.python.org/dev/peps/pep-0425
+
+
+File: pythonpackagingguide.info, Node: Platform tags for common Linux distributions, Next: Platform tags for other *nix platforms, Prev: Platform tags for macOS Mac OS X, Up: Platform compatibility tags
+
+5.1.7.3 Platform tags for common Linux distributions
+....................................................
+
+The scheme defined in PEP 425(1) is insufficient for public distribution
+of wheel files (and *nix wheel files in general) to Linux platforms, due
+to the large ecosystem of Linux platforms and subtle differences between
+them.
+
+Instead, PEP 513(2) defines the ‘manylinux’ standard, which represents a
+common subset of Linux platforms, and allows building wheels tagged with
+the ‘manylinux’ platform tag which can be used across most common Linux
+distributions.
+
+There are multiple iterations of the ‘manylinux’ specification, each
+representing the common subset of Linux platforms at a given point in
+time:
+
+ * ‘manylinux1’ ( PEP 513(3)) supports ‘x86_64’ and ‘i686’
+ architectures, and is based on a compatible Linux platform from
+ 2007.
+
+ * ‘manylinux2010’ ( PEP 571(4)) supports ‘x86_64’ and ‘i686’
+ architectures. and updates the previous specification to be based
+ on a compatible Linux platform from 2010 instead.
+
+ * ‘manylinux2014’ ( PEP 599(5)) adds support for a number of
+ additional architectures (‘aarch64’, ‘armv7l’, ‘ppc64’, ‘ppc64le’,
+ and ‘s390x’) and updates the base platform to a compatible Linux
+ platform from 2014.
+
+In general, distributions built for older versions of the specification
+are forwards-compatible (meaning that ‘manylinux1’ distributions should
+continue to work on modern systems) but not backwards-compatible
+(meaning that ‘manylinux2010’ distributions are not expected to work on
+platforms that existed before 2010).
+
+Package maintainers should attempt to target the most compatible
+specification possible, with the caveat that the provided build
+environment for ‘manylinux1’ has reached end-of-life, and the build
+environment for ‘manylinux2010’ will reach end-of-life in November 2020
+(6), meaning that these images will no longer receive security updates.
+
+* Menu:
+
+* Manylinux compatibility support::
+
+ ---------- Footnotes ----------
+
+ (1) https://www.python.org/dev/peps/pep-0425
+
+ (2) https://www.python.org/dev/peps/pep-0513
+
+ (3) https://www.python.org/dev/peps/pep-0513
+
+ (4) https://www.python.org/dev/peps/pep-0571
+
+ (5) https://www.python.org/dev/peps/pep-0599
+
+ (6) (1) ‘https://wiki.centos.org/About/Product’
+
+
+File: pythonpackagingguide.info, Node: Manylinux compatibility support, Up: Platform tags for common Linux distributions
+
+5.1.7.4 Manylinux compatibility support
+.......................................
+
+ Note: The ‘manylinux2014’ specification is relatively new and is
+ not yet widely recognised by install tools.
+
+The following table shows the minimum versions of relevant projects to
+support the various ‘manylinux’ standards:
+
+Tool ‘manylinux1’ ‘manylinux2010’ ‘manylinux2014’
+
+------------------------------------------------------------------------------
+
+pip ‘>=8.1.0’ ‘>=19.0’ ‘>=19.3’
+
+
+auditwheel ‘>=1.0.0’ ‘>=2.0.0’ ‘>=3.0.0’
+
+
+
+File: pythonpackagingguide.info, Node: Platform tags for other *nix platforms, Prev: Platform tags for common Linux distributions, Up: Platform compatibility tags
+
+5.1.7.5 Platform tags for other *nix platforms
+..............................................
+
+The scheme defined in PEP 425(1) is not generally sufficient for public
+distribution of wheel files to other *nix platforms. Efforts are
+currently (albeit intermittently) under way to define improved
+compatibility tagging schemes for AIX and for Alpine Linux.
+
+ ---------- Footnotes ----------
+
+ (1) https://www.python.org/dev/peps/pep-0425
+
+
+File: pythonpackagingguide.info, Node: Recording installed projects, Next: Entry points specification, Prev: Platform compatibility tags, Up: Package Distribution Metadata
+
+5.1.8 Recording installed projects
+----------------------------------
+
+This document specifies a common format of recording information about
+Python *note projects: 1fc. installed in an environment. A common
+metadata format allows tools to query, manage or uninstall projects,
+regardless of how they were installed.
+
+Almost all information is optional. This allows tools outside the
+Python ecosystem, such as Linux package managers, to integrate with
+Python tooling as much as possible. For example, even if an installer
+cannot easily provide a list of installed files in a format specific to
+Python tooling, it should still record the name and version of the
+installed project.
+
+* Menu:
+
+* History and change workflow::
+* The .dist-info directory: The dist-info directory.
+* The METADATA file::
+* The RECORD file::
+* The INSTALLER file::
+
+
+File: pythonpackagingguide.info, Node: History and change workflow, Next: The dist-info directory, Up: Recording installed projects
+
+5.1.8.1 History and change workflow
+...................................
+
+The metadata described here was first specified in PEP 376(1), and later
+ammended in PEP 627(2). It was formerly known as `Database of Installed
+Python Distributions'. Further amendments (except trivial language or
+typography fixes) must be made through the PEP process (see PEP 1(3)).
+
+While this document is the normative specification, these PEPs that
+introduce changes to it may include additional information such as
+rationales and backwards compatibility considerations.
+
+ ---------- Footnotes ----------
+
+ (1) https://www.python.org/dev/peps/pep-0376
+
+ (2) https://www.python.org/dev/peps/pep-0627
+
+ (3) https://www.python.org/dev/peps/pep-0001
+
+
+File: pythonpackagingguide.info, Node: The dist-info directory, Next: The METADATA file, Prev: History and change workflow, Up: Recording installed projects
+
+5.1.8.2 The .dist-info directory
+................................
+
+Each project installed from a distribution must, in addition to files,
+install a “‘.dist-info’” directory located alongside importable modules
+and packages (commonly, the ‘site-packages’ directory).
+
+This directory is named as ‘{name}-{version}.dist-info’, with name(1)
+and Distribution versions(2) fields corresponding to *note Core metadata
+specifications: 85. The name field must be in normalized form (see PEP
+503(3) for the definition of normalization).
+
+This ‘.dist-info’ directory can contain these files, described in detail
+below:
+
+ * ‘METADATA’: contains project metadata
+
+ * ‘RECORD’: records the list of installed files.
+
+ * ‘INSTALLER’: records the name of the tool used to install the
+ project.
+
+The ‘METADATA’ file is mandatory. All other files may be omitted at the
+installing tool’s discretion. Additional installer-specific files may
+be present.
+
+ Note: The *note Binary distribution format: 1ee. specification
+ describes additional files that may appear in the ‘.dist-info’
+ directory of a *note Wheel: d. Such files may be copied to the
+ ‘.dist-info’ directory of an installed project.
+
+The previous versions of this specification also specified a ‘REQUESTED’
+file. This file is now considered a tool-specific extension, but may be
+standardized again in the future. See PEP 376(4) for its original
+meaning.
+
+ ---------- Footnotes ----------
+
+ (1)
+https://docs.python.org/2/reference/simple_stmts.html#grammar-token-name
+
+ (2) https://docs.python.org/3/library/importlib.metadata.html#version
+
+ (3) https://www.python.org/dev/peps/pep-0503/#normalized-names
+
+ (4) https://www.python.org/dev/peps/pep-0376/#requested
+
+
+File: pythonpackagingguide.info, Node: The METADATA file, Next: The RECORD file, Prev: The dist-info directory, Up: Recording installed projects
+
+5.1.8.3 The METADATA file
+.........................
+
+The ‘METADATA’ file contains metadata as described in the *note Core
+metadata specifications: 85. specification, version 1.1 or greater.
+
+The ‘METADATA’ file is mandatory. If it cannot be created, or if
+required core metadata is not available, installers must report an error
+and fail to install the project.
+
+
+File: pythonpackagingguide.info, Node: The RECORD file, Next: The INSTALLER file, Prev: The METADATA file, Up: Recording installed projects
+
+5.1.8.4 The RECORD file
+.......................
+
+The ‘RECORD’ file holds the list of installed files. It is a CSV file
+containing one record (line) per installed file.
+
+The CSV dialect must be readable with the default ‘reader’ of Python’s
+‘csv’ module:
+
+ * field delimiter: ‘,’ (comma),
+
+ * quoting char: ‘"’ (straight double quote),
+
+ * line terminator: either ‘\r\n’ or ‘\n’.
+
+Each record is composed of three elements: the file’s `path', the `hash'
+of the contents, and its `size'.
+
+The `path' may be either absolute, or relative to the directory
+containing the ‘.dist-info’ directory (commonly, the ‘site-packages’
+directory). On Windows, directories may be separated either by forward-
+or backslashes (‘/’ or ‘\’).
+
+The `hash' is either an empty string or the name of a hash algorithm
+from ‘hashlib.algorithms_guaranteed’, followed by the equals character
+‘=’ and the digest of the file’s contents, encoded with the
+urlsafe-base64-nopad encoding (‘base64.urlsafe_b64encode(digest)’ with
+trailing ‘=’ removed).
+
+The `size' is either the empty string, or file’s size in bytes, as a
+base 10 integer.
+
+For any file, either or both of the `hash' and `size' fields may be left
+empty. Commonly, entries for ‘.pyc’ files and the ‘RECORD’ file itself
+have empty `hash' and `size'. For other files, leaving the information
+out is discouraged, as it prevents verifying the integrity of the
+installed project.
+
+If the ‘RECORD’ file is present, it must list all installed files of the
+project, except ‘.pyc’ files corresponding to ‘.py’ files listed in
+‘RECORD’, which are optional. Notably, the contents of the ‘.dist-info’
+directory (including the ‘RECORD’ file itself) must be listed.
+Directories should not be listed.
+
+To completely uninstall a package, a tool needs to remove all files
+listed in ‘RECORD’, all ‘.pyc’ files (of all optimization levels)
+corresponding to removed ‘.py’ files, and any directories emptied by the
+uninstallation.
+
+Here is an example snippet of a possible ‘RECORD’ file:
+
+ /usr/bin/black,sha256=iFlOnL32lIa-RKk-MDihcbJ37wxmRbE4xk6eVYVTTeU,220
+ ../../../bin/blackd,sha256=lCadt4mcU-B67O1gkQVh7-vsKgLpx6ny1le34Jz6UVo,221
+ __pycache__/black.cpython-38.pyc,,
+ __pycache__/blackd.cpython-38.pyc,,
+ black-19.10b0.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4
+ black-19.10b0.dist-info/LICENSE,sha256=nAQo8MO0d5hQz1vZbhGqqK_HLUqG1KNiI9erouWNbgA,1080
+ black-19.10b0.dist-info/METADATA,sha256=UN40nGoVVTSpvLrTBwNsXgZdZIwoKFSrrDDHP6B7-A0,58841
+ black-19.10b0.dist-info/RECORD,,
+ black.py,sha256=45IF72OgNfF8WpeNHnxV2QGfbCLubV5Xjl55cI65kYs,140161
+ blackd.py,sha256=JCxaK4hLkMRwVfZMj8FRpRRYC0172-juKqbN22bISLE,6672
+ blib2to3/__init__.py,sha256=9_8wL9Scv8_Cs8HJyJHGvx1vwXErsuvlsAqNZLcJQR0,8
+ blib2to3/__pycache__/__init__.cpython-38.pyc,,
+ blib2to3/__pycache__/pygram.cpython-38.pyc,sha256=zpXgX4FHDuoeIQKO_v0sRsB-RzQFsuoKoBYvraAdoJw,1512
+ blib2to3/__pycache__/pytree.cpython-38.pyc,sha256=LYLplXtG578ZjaFeoVuoX8rmxHn-BMAamCOsJMU1b9I,24910
+ blib2to3/pygram.py,sha256=mXpQPqHcamFwch0RkyJsb92Wd0kUP3TW7d-u9dWhCGY,2085
+ blib2to3/pytree.py,sha256=RWj3IL4U-Ljhkn4laN0C3p7IRdfvT3aIRjTV-x9hK1c,28530
+
+If the ‘RECORD’ file is missing, tools that rely on ‘.dist-info’ must
+not atempt to uninstall or upgrade the package. (This does not apply to
+tools that rely on other sources of information, such as system package
+managers in Linux distros.)
+
+
+File: pythonpackagingguide.info, Node: The INSTALLER file, Prev: The RECORD file, Up: Recording installed projects
+
+5.1.8.5 The INSTALLER file
+..........................
+
+If present, ‘INSTALLER’ is a single-line text file naming the tool used
+to install the project. If the installer is executable from the command
+line, ‘INSTALLER’ should contain the command name. Otherwise, it should
+contain a printable ASCII string.
+
+The file can be terminated by zero or more ASCII whitespace characters.
+
+Here are examples of two possible ‘INSTALLER’ files:
+
+ pip
+
+ MegaCorp Cloud Install-O-Matic
+
+This value should be used for informational purposes only. For example,
+if a tool is asked to uninstall a project but finds no ‘RECORD’ file, it
+may suggest that the tool named in ‘INSTALLER’ may be able to do the
+uninstallation.
+
+
+File: pythonpackagingguide.info, Node: Entry points specification, Prev: Recording installed projects, Up: Package Distribution Metadata
+
+5.1.9 Entry points specification
+--------------------------------
+
+`Entry points' are a mechanism for an installed distribution to
+advertise components it provides to be discovered and used by other
+code. For example:
+
+ - Distributions can specify ‘console_scripts’ entry points, each
+ referring to a function. When `pip' (or another console_scripts
+ aware installer) installs the distribution, it will create a
+ command-line wrapper for each entry point.
+
+ - Applications can use entry points to load plugins; e.g. Pygments
+ (a syntax highlighting tool) can use additional lexers and styles
+ from separately installed packages. For more about this, see *note
+ Creating and discovering plugins: 138.
+
+The entry point file format was originally developed to allow packages
+built with setuptools to provide integration point metadata that would
+be read at runtime with ‘pkg_resources’. It is now defined as a PyPA
+interoperability specification in order to allow build tools other than
+setuptools to publish ‘pkg_resources’ compatible entry point metadata,
+and runtime libraries other than ‘pkg_resources’ to portably read
+published entry point metadata (potentially with different caching and
+conflict resolution strategies).
+
+* Menu:
+
+* Data model::
+* File format::
+* Use for scripts::
+
+
+File: pythonpackagingguide.info, Node: Data model, Next: File format, Up: Entry points specification
+
+5.1.9.1 Data model
+..................
+
+Conceptually, an entry point is defined by three required properties:
+
+ - The `group' that an entry point belongs to indicates what sort of
+ object it provides. For instance, the group ‘console_scripts’ is
+ for entry points referring to functions which can be used as a
+ command, while ‘pygments.styles’ is the group for classes defining
+ pygments styles. The consumer typically defines the expected
+ interface. To avoid clashes, consumers defining a new group should
+ use names starting with a PyPI name owned by the consumer project,
+ followed by ‘.’. Group names must be one or more groups of
+ letters, numbers and underscores, separated by dots (regex
+ ‘^\w+(\.\w+)*$’).
+
+ - The `name' identifies this entry point within its group. The
+ precise meaning of this is up to the consumer. For console
+ scripts, the name of the entry point is the command that will be
+ used to launch it. Within a distribution, entry point names should
+ be unique. If different distributions provide the same name, the
+ consumer decides how to handle such conflicts. The name may
+ contain any characters except ‘=’, but it cannot start or end with
+ any whitespace character, or start with ‘[’. For new entry points,
+ it is recommended to use only letters, numbers, underscores, dots
+ and dashes (regex ‘[\w.-]+’).
+
+ - The `object reference' points to a Python object. It is either in
+ the form ‘importable.module’, or ‘importable.module:object.attr’.
+ Each of the parts delimited by dots and the colon is a valid Python
+ identifier. It is intended to be looked up like this:
+
+ import importlib
+ modname, qualname_separator, qualname = object_ref.partition(':')
+ obj = importlib.import_module(modname)
+ if qualname_separator:
+ for attr in qualname.split('.'):
+ obj = getattr(obj, attr)
+
+ Note: Some tools call this kind of object reference by itself an
+ ‘entry point’, for want of a better term, especially where it
+ points to a function to launch a program.
+
+There is also an optional property: the `extras' are a set of strings
+identifying optional features of the distribution providing the entry
+point. If these are specified, the entry point requires the
+dependencies of those ‘extras’. See the metadata field *note
+Provides-Extra (multiple use): 1c8.
+
+Using extras for an entry point is no longer recommended. Consumers
+should support parsing them from existing distributions, but may then
+ignore them. New publishing tools need not support specifying extras.
+The functionality of handling extras was tied to setuptools’ model of
+managing ‘egg’ packages, but newer tools such as pip and virtualenv use
+a different model.
+
+
+File: pythonpackagingguide.info, Node: File format, Next: Use for scripts, Prev: Data model, Up: Entry points specification
+
+5.1.9.2 File format
+...................
+
+Entry points are defined in a file called ‘entry_points.txt’ in the
+‘*.dist-info’ directory of the distribution. This is the directory
+described in PEP 376(1) for installed distributions, and in PEP 427(2)
+for wheels. The file uses the UTF-8 character encoding.
+
+The file contents are in INI format, as read by Python’s configparser(3)
+module. However, configparser treats names as case-insensitive by
+default, whereas entry point names are case sensitive. A case-sensitive
+config parser can be made like this:
+
+ import configparser
+
+ class CaseSensitiveConfigParser(configparser.ConfigParser):
+ optionxform = staticmethod(str)
+
+The entry points file must always use ‘=’ to delimit names from values
+(whereas configparser also allows using ‘:’).
+
+The sections of the config file represent entry point groups, the names
+are names, and the values encode both the object reference and the
+optional extras. If extras are used, they are a comma-separated list
+inside square brackets.
+
+Within a value, readers must accept and ignore spaces (including
+multiple consecutive spaces) before or after the colon, between the
+object reference and the left square bracket, between the extra names
+and the square brackets and colons delimiting them, and after the right
+square bracket. The syntax for extras is formally specified as part of
+PEP 508(4) (as ‘extras’). For tools writing the file, it is recommended
+only to insert a space between the object reference and the left square
+bracket.
+
+For example:
+
+ [console_scripts]
+ foo = foomod:main
+ # One which depends on extras:
+ foobar = foomod:main_bar [bar,baz]
+
+ # pytest plugins refer to a module, so there is no ':obj'
+ [pytest11]
+ nbval = nbval.plugin
+
+ ---------- Footnotes ----------
+
+ (1) https://www.python.org/dev/peps/pep-0376
+
+ (2) https://www.python.org/dev/peps/pep-0427
+
+ (3)
+https://docs.python.org/3/library/configparser.html#module-configparser
+
+ (4) https://www.python.org/dev/peps/pep-0508
+
+
+File: pythonpackagingguide.info, Node: Use for scripts, Prev: File format, Up: Entry points specification
+
+5.1.9.3 Use for scripts
+.......................
+
+Two groups of entry points have special significance in packaging:
+‘console_scripts’ and ‘gui_scripts’. In both groups, the name of the
+entry point should be usable as a command in a system shell after the
+package is installed. The object reference points to a function which
+will be called with no arguments when this command is run. The function
+may return an integer to be used as a process exit code, and returning
+‘None’ is equivalent to returning ‘0’.
+
+For instance, the entry point ‘mycmd = mymod:main’ would create a
+command ‘mycmd’ launching a script like this:
+
+ import sys
+ from mymod import main
+ sys.exit(main())
+
+The difference between ‘console_scripts’ and ‘gui_scripts’ only affects
+Windows systems. ‘console_scripts’ are wrapped in a console executable,
+so they are attached to a console and can use ‘sys.stdin’, ‘sys.stdout’
+and ‘sys.stderr’ for input and output. ‘gui_scripts’ are wrapped in a
+GUI executable, so they can be started without a console, but cannot use
+standard streams unless application code redirects them. Other
+platforms do not have the same distinction.
+
+Install tools are expected to set up wrappers for both ‘console_scripts’
+and ‘gui_scripts’ in the scripts directory of the install scheme. They
+are not responsible for putting this directory in the ‘PATH’ environment
+variable which defines where command-line tools are found.
+
+As files are created from the names, and some filesystems are
+case-insensitive, packages should avoid using names in these groups
+which differ only in case. The behaviour of install tools when names
+differ only in case is undefined.
+
+
+File: pythonpackagingguide.info, Node: Package Index Interfaces, Prev: Package Distribution Metadata, Up: PyPA specifications
+
+5.2 Package Index Interfaces
+============================
+
+* Menu:
+
+* The .pypirc file: The pypirc file.
+* Simple repository API::
+
+
+File: pythonpackagingguide.info, Node: The pypirc file, Next: Simple repository API, Up: Package Index Interfaces
+
+5.2.1 The ‘.pypirc’ file
+------------------------
+
+A ‘.pypirc’ file allows you to define the configuration for *note
+package indexes: ec. (referred to here as “repositories”), so that you
+don’t have to enter the URL, username, or password whenever you upload a
+package with *note twine: 66. or *note flit: 6a.
+
+The format (originally defined by the *note distutils: c0. package) is:
+
+ [distutils]
+ index-servers =
+ first-repository
+ second-repository
+
+ [first-repository]
+ repository = <first-repository URL>
+ username = <first-repository username>
+ password = <first-repository password>
+
+ [second-repository]
+ repository = <second-repository URL>
+ username = <second-repository username>
+ password = <second-repository password>
+
+The ‘distutils’ section defines an ‘index-servers’ field that lists the
+name of all sections describing a repository.
+
+Each section describing a repository defines three fields:
+
+ - ‘repository’: The URL of the repository.
+
+ - ‘username’: The registered username on the repository.
+
+ - ‘password’: The password that will used to authenticate the
+ username.
+
+ Warning: Be aware that this stores your password in plain text.
+ For better security, consider an alternative like keyring(1),
+ setting environment variables, or providing the password on the
+ command line.
+
+ Otherwise, set the permissions on ‘.pypirc’ so that only you can
+ view or modify it. For example, on Linux or macOS, run:
+
+ chmod 600 ~/.pypirc
+
+* Menu:
+
+* Common configurations::
+
+ ---------- Footnotes ----------
+
+ (1) https://pypi.org/project/keyring/
+
+
+File: pythonpackagingguide.info, Node: Common configurations, Up: The pypirc file
+
+5.2.1.1 Common configurations
+.............................
+
+ Note: These examples apply to *note twine: 66, and projects like
+ *note hatch: 20c. that use it under the hood. Other projects (e.g.
+ *note flit: 6a.) also use ‘.pypirc’, but with different defaults.
+ Please refer to each project’s documentation for more details and
+ usage instructions.
+
+Twine’s default configuration mimics a ‘.pypirc’ with repository
+sections for PyPI and TestPyPI:
+
+ [distutils]
+ index-servers =
+ pypi
+ testpypi
+
+ [pypi]
+ repository = https://upload.pypi.org/legacy/
+
+ [testpypi]
+ repository = https://test.pypi.org/legacy/
+
+Twine will add additional configuration from ‘$HOME/.pypirc’, the
+command line, and environment variables to this default configuration.
+
+* Menu:
+
+* Using a PyPI token::
+* Using another package index::
+
+
+File: pythonpackagingguide.info, Node: Using a PyPI token, Next: Using another package index, Up: Common configurations
+
+5.2.1.2 Using a PyPI token
+..........................
+
+To set your API token(1) for PyPI, you can create a ‘$HOME/.pypirc’
+similar to:
+
+ [pypi]
+ username = __token__
+ password = <PyPI token>
+
+For *note TestPyPI: f6, add a ‘[testpypi]’ section, using the API token
+from your TestPyPI account.
+
+ ---------- Footnotes ----------
+
+ (1) https://pypi.org/help/#apitoken
+
+
+File: pythonpackagingguide.info, Node: Using another package index, Prev: Using a PyPI token, Up: Common configurations
+
+5.2.1.3 Using another package index
+...................................
+
+To configure an additional repository, you’ll need to redefine the
+‘index-servers’ field to include the repository name. Here is a
+complete example of a ‘$HOME/.pypirc’ for PyPI, TestPyPI, and a private
+repository:
+
+ [distutils]
+ index-servers =
+ pypi
+ testpypi
+ private-repository
+
+ [pypi]
+ username = __token__
+ password = <PyPI token>
+
+ [testpypi]
+ username = __token__
+ password = <TestPyPI token>
+
+ [private-repository]
+ repository = <private-repository URL>
+ username = <private-repository username>
+ password = <private-repository password>
+
+ Warning: Instead of using the ‘password’ field, consider saving
+ your API tokens and passwords securely using keyring(1) (which is
+ installed by Twine):
+
+ keyring set https://upload.pypi.org/legacy/ __token__
+ keyring set https://test.pypi.org/legacy/ __token__
+ keyring set <private-repository URL> <private-repository username>
+
+ ---------- Footnotes ----------
+
+ (1) https://pypi.org/project/keyring/
+
+
+File: pythonpackagingguide.info, Node: Simple repository API, Prev: The pypirc file, Up: Package Index Interfaces
+
+5.2.2 Simple repository API
+---------------------------
+
+The current interface for querying available package versions and
+retrieving packages from an index server is defined in PEP 503(1), with
+the addition of “yank” support (allowing a kind of file deletion) as
+defined in PEP 592(2).
+
+ ---------- Footnotes ----------
+
+ (1) https://www.python.org/dev/peps/pep-0503
+
+ (2) https://www.python.org/dev/peps/pep-0592
+
+
+File: pythonpackagingguide.info, Node: Project Summaries, Next: Glossary, Prev: PyPA specifications, Up: Top
+
+6 Project Summaries
+*******************
+
+Summaries and links for the most relevant projects in the space of
+Python installation and packaging.
+
+* Menu:
+
+* PyPA Projects::
+* Non-PyPA Projects::
+* Standard Library Projects::
+
+
+File: pythonpackagingguide.info, Node: PyPA Projects, Next: Non-PyPA Projects, Up: Project Summaries
+
+6.1 PyPA Projects
+=================
+
+* Menu:
+
+* bandersnatch::
+* build::
+* distlib::
+* packaging::
+* pip::
+* Pipenv::
+* Pipfile::
+* Python Packaging User Guide: Python Packaging User Guide<2>.
+* readme_renderer::
+* setuptools::
+* trove-classifiers::
+* twine::
+* virtualenv: virtualenv<2>.
+* Warehouse::
+* wheel::
+
+
+File: pythonpackagingguide.info, Node: bandersnatch, Next: build, Up: PyPA Projects
+
+6.1.1 bandersnatch
+------------------
+
+Mailing list(1) (2) | Issues(3) | GitHub(4) | PyPI(5) | Dev
+IRC:#bandersnatch(6)
+
+‘bandersnatch’ is a PyPI mirroring client designed to efficiently create
+a complete mirror of the contents of PyPI. Organizations thus save
+bandwidth and latency on package downloads (especially in the context of
+automated tests) and to prevent heavily loading PyPI’s Content Delivery
+Network (CDN).
+
+ ---------- Footnotes ----------
+
+ (1) http://mail.python.org/mailman/listinfo/distutils-sig
+
+ (2) (2) Multiple projects reuse the distutils-sig mailing list as
+their user list.
+
+ (3) https://github.com/pypa/bandersnatch/issues
+
+ (4) https://github.com/pypa/bandersnatch
+
+ (5) https://pypi.org/project/bandersnatch
+
+ (6) https://webchat.freenode.net/?channels=%23bandersnatch
+
+
+File: pythonpackagingguide.info, Node: build, Next: distlib, Prev: bandersnatch, Up: PyPA Projects
+
+6.1.2 build
+-----------
+
+Docs(1) | Issues(2) | GitHub(3) | PyPI(4) | User IRC:#pypa(5) | Dev
+IRC:#pypa-dev(6)
+
+‘build’ is a PEP-517 compatible Python package builder. It provides a
+CLI to build packages, as well as a Python API.
+
+ ---------- Footnotes ----------
+
+ (1) https://pypa-build.readthedocs.io/
+
+ (2) https://github.com/pypa/build/issues
+
+ (3) https://github.com/pypa/build
+
+ (4) https://pypi.org/project/build
+
+ (5) https://webchat.freenode.net/?channels=%23pypa
+
+ (6) https://webchat.freenode.net/?channels=%23pypa-dev
+
+
+File: pythonpackagingguide.info, Node: distlib, Next: packaging, Prev: build, Up: PyPA Projects
+
+6.1.3 distlib
+-------------
+
+Docs(1) | Mailing list(2) (3) | Issues(4) | Bitbucket(5) | PyPI(6)
+
+‘distlib’ is a library which implements low-level functions that relate
+to packaging and distribution of Python software. ‘distlib’ implements
+several relevant PEPs (Python Enhancement Proposal standards) and is
+useful for developers of third-party packaging tools to make and upload
+binary and source *note distributions: b, achieve interoperability,
+resolve dependencies, manage package resources, and do other similar
+functions.
+
+Unlike the stricter *note packaging: 21e. project (below), which
+specifically implements modern Python packaging interoperability
+standards, ‘distlib’ also attempts to provide reasonable fallback
+behaviours when asked to handle legacy packages and metadata that
+predate the modern interoperability standards and fall into the subset
+of packages that are incompatible with those standards.
+
+ ---------- Footnotes ----------
+
+ (1) http://pythonhosted.org/distlib/
+
+ (2) http://mail.python.org/mailman/listinfo/distutils-sig
+
+ (3) (2) Multiple projects reuse the distutils-sig mailing list as
+their user list.
+
+ (4) https://bitbucket.org/pypa/distlib/issues?status=new&status=open
+
+ (5) https://bitbucket.org/pypa/distlib
+
+ (6) https://pypi.org/project/distlib
+
+
+File: pythonpackagingguide.info, Node: packaging, Next: pip, Prev: distlib, Up: PyPA Projects
+
+6.1.4 packaging
+---------------
+
+Docs(1) | Dev list(2) | Issues(3) | GitHub(4) | PyPI(5) | User
+IRC:#pypa(6) | Dev IRC:#pypa-dev(7)
+
+Core utilities for Python packaging used by *note pip: 2b. and *note
+setuptools: 2d.
+
+The core utilities in the packaging library handle version handling,
+specifiers, markers, requirements, tags, and similar attributes and
+tasks for Python packages. Most Python users rely on this library
+without needing to explicitly call it; developers of the other Python
+packaging, distribution, and installation tools listed here often use
+its functionality to parse, discover, and otherwise handle dependency
+attributes.
+
+This project specifically focuses on implementing the modern Python
+packaging interoperability standards defined at *note PyPA
+specifications: 196, and will report errors for sufficiently old legacy
+packages that are incompatible with those standards. In contrast, the
+*note distlib: 21c. project is a more permissive library that attempts
+to provide a plausible reading of ambiguous metadata in cases where
+*note packaging: 21e. will instead report on error.
+
+ ---------- Footnotes ----------
+
+ (1) https://packaging.pypa.io
+
+ (2) https://mail.python.org/mailman3/lists/distutils-sig.python.org/
+
+ (3) https://github.com/pypa/packaging/issues
+
+ (4) https://github.com/pypa/packaging
+
+ (5) https://pypi.org/project/packaging
+
+ (6) https://webchat.freenode.net/?channels=%23pypa
+
+ (7) https://webchat.freenode.net/?channels=%23pypa-dev
+
+
+File: pythonpackagingguide.info, Node: pip, Next: Pipenv, Prev: packaging, Up: PyPA Projects
+
+6.1.5 pip
+---------
+
+Docs(1) | User list(2) (3) | Dev list(4) | Issues(5) | GitHub(6) |
+PyPI(7) | User IRC:#pypa(8) | Dev IRC:#pypa-dev(9)
+
+The most popular tool for installing Python packages, and the one
+included with modern versions of Python.
+
+It provides the essential core features for finding, downloading, and
+installing packages from PyPI and other Python package indexes, and can
+be incorporated into a wide range of development workflows via its
+command-line interface (CLI).
+
+ ---------- Footnotes ----------
+
+ (1) https://pip.pypa.io/en/stable/
+
+ (2) http://groups.google.com/group/python-virtualenv
+
+ (3) (1) pip was created by the same developer as virtualenv, and
+early on adopted the virtualenv mailing list, and it’s stuck ever since.
+
+ (4) https://mail.python.org/mailman3/lists/distutils-sig.python.org/
+
+ (5) https://github.com/pypa/pip/issues
+
+ (6) https://github.com/pypa/pip
+
+ (7) https://pypi.org/project/pip/
+
+ (8) https://webchat.freenode.net/?channels=%23pypa
+
+ (9) https://webchat.freenode.net/?channels=%23pypa-dev
+
+
+File: pythonpackagingguide.info, Node: Pipenv, Next: Pipfile, Prev: pip, Up: PyPA Projects
+
+6.1.6 Pipenv
+------------
+
+Docs(1) | Source(2) | Issues(3) | PyPI(4)
+
+Pipenv is a project that aims to bring the best of all packaging worlds
+to the Python world. It harnesses *note Pipfile: 51, *note pip: 2b, and
+*note virtualenv: 32. into one single toolchain. It features very
+pretty terminal colors.
+
+Pipenv aims to help users manage environments, dependencies, and
+imported packages on the command line. It also works well on Windows
+(which other tools often underserve), makes and checkes file hashes, to
+ensure compliance with hash-locked dependency specifiers, and eases
+uninstallation of packages and dependencies. It is used by Python users
+and system administrators, but has been less maintained since late 2018.
+
+ ---------- Footnotes ----------
+
+ (1) https://pipenv.pypa.io/
+
+ (2) https://github.com/pypa/pipenv
+
+ (3) https://github.com/pypa/pipenv/issues
+
+ (4) https://pypi.org/project/pipenv
+
+
+File: pythonpackagingguide.info, Node: Pipfile, Next: Python Packaging User Guide<2>, Prev: Pipenv, Up: PyPA Projects
+
+6.1.7 Pipfile
+-------------
+
+Source(1)
+
+‘Pipfile’ and its sister ‘Pipfile.lock’ are a higher-level
+application-centric alternative to *note pip: 2b.’s lower-level
+‘requirements.txt’ file.
+
+ ---------- Footnotes ----------
+
+ (1) https://github.com/pypa/pipfile
+
+
+File: pythonpackagingguide.info, Node: Python Packaging User Guide<2>, Next: readme_renderer, Prev: Pipfile, Up: PyPA Projects
+
+6.1.8 Python Packaging User Guide
+---------------------------------
+
+Docs(1) | Mailing list(2) | Issues(3) | GitHub(4) | User IRC:#pypa(5) |
+Dev IRC:#pypa-dev(6)
+
+This guide!
+
+ ---------- Footnotes ----------
+
+ (1) https://packaging.python.org/en/latest/
+
+ (2) http://mail.python.org/mailman/listinfo/distutils-sig
+
+ (3) https://github.com/pypa/python-packaging-user-guide/issues
+
+ (4) https://github.com/pypa/python-packaging-user-guide
+
+ (5) https://webchat.freenode.net/?channels=%23pypa
+
+ (6) https://webchat.freenode.net/?channels=%23pypa-dev
+
+
+File: pythonpackagingguide.info, Node: readme_renderer, Next: setuptools, Prev: Python Packaging User Guide<2>, Up: PyPA Projects
+
+6.1.9 readme_renderer
+---------------------
+
+GitHub and docs(1) | PyPI(2)
+
+‘readme_renderer’ is a library that package developers use to render
+their user documentation (README) files into HTML from markup languages
+such as Markdown or reStructuredText. Developers call it on its own or
+via *note twine: 66, as part of their release management process, to
+check that their package descriptions will properly display on PyPI.
+
+ ---------- Footnotes ----------
+
+ (1) https://github.com/pypa/readme_renderer/
+
+ (2) https://pypi.org/project/readme_renderer/
+
+
+File: pythonpackagingguide.info, Node: setuptools, Next: trove-classifiers, Prev: readme_renderer, Up: PyPA Projects
+
+6.1.10 setuptools
+-----------------
+
+Docs(1) | User list(2) (3) | Dev list(4) | Issues(5) | GitHub(6) |
+PyPI(7) | User IRC:#pypa(8) | Dev IRC:#pypa-dev(9)
+
+setuptools (which includes ‘easy_install’) is a collection of
+enhancements to the Python distutils that allow you to more easily build
+and distribute Python *note distributions: b, especially ones that have
+dependencies on other packages.
+
+distribute(10) was a fork of setuptools that was merged back into
+setuptools (in v0.7), thereby making setuptools the primary choice for
+Python packaging.
+
+ ---------- Footnotes ----------
+
+ (1) https://setuptools.readthedocs.io/en/latest/
+
+ (2) http://mail.python.org/mailman/listinfo/distutils-sig
+
+ (3) (2) Multiple projects reuse the distutils-sig mailing list as
+their user list.
+
+ (4) https://mail.python.org/mailman3/lists/distutils-sig.python.org/
+
+ (5) https://github.com/pypa/setuptools/issues
+
+ (6) https://github.com/pypa/setuptools
+
+ (7) https://pypi.org/project/setuptools
+
+ (8) https://webchat.freenode.net/?channels=%23pypa
+
+ (9) https://webchat.freenode.net/?channels=%23pypa-dev
+
+ (10) https://pypi.org/project/distribute
+
+
+File: pythonpackagingguide.info, Node: trove-classifiers, Next: twine, Prev: setuptools, Up: PyPA Projects
+
+6.1.11 trove-classifiers
+------------------------
+
+Issues(1) | GitHub(2) | PyPI(3)
+
+trove-classifiers is the canonical source for classifiers on PyPI(4),
+which project maintainers use to systematically describe their
+projects(5) so that users can better find projects that match their
+needs on the PyPI.
+
+The trove-classifiers package contains a list of valid classifiers and
+deprecated classifiers (which are paired with the classifiers that
+replace them). Use this package to validate classifiers used in
+packages intended for uploading to PyPI. As this list of classifiers is
+published as code, you can install and import it, giving you a more
+convenient workflow compared to referring to the list published on
+PyPI(6). The issue tracker(7) for the project hosts discussions on
+proposed classifiers and requests for new classifiers.
+
+ ---------- Footnotes ----------
+
+ (1) https://github.com/pypa/trove-classifiers/issues
+
+ (2) https://github.com/pypa/trove-classifiers
+
+ (3) https://pypi.org/project/trove-classifiers/
+
+ (4) https://pypi.org/classifiers/
+
+ (5)
+https://packaging.python.org/specifications/core-metadata/#classifier-multiple-use
+
+ (6) https://pypi.org/classifiers/
+
+ (7) https://github.com/pypa/trove-classifiers/issues
+
+
+File: pythonpackagingguide.info, Node: twine, Next: virtualenv<2>, Prev: trove-classifiers, Up: PyPA Projects
+
+6.1.12 twine
+------------
+
+Docs(1) | Mailing list(2) (3) | Issues(4) | GitHub(5) | PyPI(6)
+
+Twine is the primary tool developers use to upload packages to the
+Python Package Index or other Python package indexes. It is a
+command-line program that passes program files and metadata to a web
+API. Developers use it because it’s the official PyPI upload tool, it’s
+fast and secure, it’s maintained, and it reliably works.
+
+ ---------- Footnotes ----------
+
+ (1) https://twine.readthedocs.io/en/latest/
+
+ (2) http://mail.python.org/mailman/listinfo/distutils-sig
+
+ (3) (2) Multiple projects reuse the distutils-sig mailing list as
+their user list.
+
+ (4) https://github.com/pypa/twine/issues
+
+ (5) https://github.com/pypa/twine
+
+ (6) https://pypi.org/project/twine
+
+
+File: pythonpackagingguide.info, Node: virtualenv<2>, Next: Warehouse, Prev: twine, Up: PyPA Projects
+
+6.1.13 virtualenv
+-----------------
+
+Docs(1) | User list(2) | Dev list(3) | Issues(4) | GitHub(5) | PyPI(6) |
+User IRC:#pypa(7) | Dev IRC:#pypa-dev(8)
+
+virtualenv is a tool which uses the command-line path environment
+variable to create isolated Python *note Virtual Environments: 22b, much
+as *note venv: 7f. does. virtualenv provides additional functionality,
+compared to *note venv: 7f, by supporting Python 2.7 and by providing
+convenient features for configuring, maintaining, duplicating, and
+troubleshooting the virtual environments. For more information, see the
+section on *note Creating Virtual Environments: 31.
+
+ ---------- Footnotes ----------
+
+ (1) https://virtualenv.pypa.io/en/stable/
+
+ (2) http://groups.google.com/group/python-virtualenv
+
+ (3) https://mail.python.org/mailman3/lists/distutils-sig.python.org/
+
+ (4) https://github.com/pypa/virtualenv/issues
+
+ (5) https://github.com/pypa/virtualenv
+
+ (6) https://pypi.org/project/virtualenv/
+
+ (7) https://webchat.freenode.net/?channels=%23pypa
+
+ (8) https://webchat.freenode.net/?channels=%23pypa-dev
+
+
+File: pythonpackagingguide.info, Node: Warehouse, Next: wheel, Prev: virtualenv<2>, Up: PyPA Projects
+
+6.1.14 Warehouse
+----------------
+
+Docs(1) | Mailing list(2) (3) | Issues(4) | GitHub(5) | Dev
+IRC:#pypa-dev(6)
+
+The current codebase powering the *note Python Package Index (PyPI): 39.
+It is hosted at pypi.org(7). The default source for *note pip: 2b.
+downloads.
+
+ ---------- Footnotes ----------
+
+ (1) https://warehouse.pypa.io/
+
+ (2) http://mail.python.org/mailman/listinfo/distutils-sig
+
+ (3) (2) Multiple projects reuse the distutils-sig mailing list as
+their user list.
+
+ (4) https://github.com/pypa/warehouse/issues
+
+ (5) https://github.com/pypa/warehouse
+
+ (6) https://webchat.freenode.net/?channels=%23pypa-dev
+
+ (7) https://pypi.org/
+
+
+File: pythonpackagingguide.info, Node: wheel, Prev: Warehouse, Up: PyPA Projects
+
+6.1.15 wheel
+------------
+
+Docs(1) | Mailing list(2) (3) | Issues(4) | GitHub(5) | PyPI(6) | User
+IRC:#pypa(7) | Dev IRC:#pypa-dev(8)
+
+Primarily, the wheel project offers the ‘bdist_wheel’ *note setuptools:
+2d. extension for creating *note wheel distributions: d. Additionally,
+it offers its own command line utility for creating and installing
+wheels.
+
+See also auditwheel(9), a tool that package developers use to check and
+fix Python packages they are making in the binary wheel format. It
+provides functionality to discover dependencies, check metadata for
+compliance, and repair the wheel and metadata to properly link and
+include external shared libraries in a package.
+
+ ---------- Footnotes ----------
+
+ (1) https://wheel.readthedocs.io/en/latest/
+
+ (2) http://mail.python.org/mailman/listinfo/distutils-sig
+
+ (3) (2) Multiple projects reuse the distutils-sig mailing list as
+their user list.
+
+ (4) https://github.com/pypa/wheel/issues
+
+ (5) https://github.com/pypa/wheel
+
+ (6) https://pypi.org/project/wheel
+
+ (7) https://webchat.freenode.net/?channels=%23pypa
+
+ (8) https://webchat.freenode.net/?channels=%23pypa-dev
+
+ (9) https://github.com/pypa/auditwheel
+
+
+File: pythonpackagingguide.info, Node: Non-PyPA Projects, Next: Standard Library Projects, Prev: PyPA Projects, Up: Project Summaries
+
+6.2 Non-PyPA Projects
+=====================
+
+* Menu:
+
+* bento::
+* buildout::
+* conda::
+* devpi::
+* flit::
+* enscons::
+* Hashdist::
+* hatch::
+* pex::
+* pipx::
+* pip-tools::
+* piwheels::
+* poetry::
+* pypiserver::
+* scikit-build::
+* shiv::
+* Spack: Spack<2>.
+* zest.releaser: zest releaser.
+
+
+File: pythonpackagingguide.info, Node: bento, Next: buildout, Up: Non-PyPA Projects
+
+6.2.1 bento
+-----------
+
+Docs(1) | Mailing list(2) | Issues(3) | GitHub(4) | PyPI(5)
+
+Bento is a packaging tool solution for Python software, targeted as an
+alternative to *note distutils: c0, *note setuptools: 2d, etc…. Bento’s
+philosophy is reproducibility, extensibility and simplicity (in that
+order).
+
+ ---------- Footnotes ----------
+
+ (1) http://cournape.github.io/Bento/
+
+ (2) http://librelist.com/browser/bento
+
+ (3) https://github.com/cournape/Bento/issues
+
+ (4) https://github.com/cournape/Bento
+
+ (5) https://pypi.org/project/bento
+
+
+File: pythonpackagingguide.info, Node: buildout, Next: conda, Prev: bento, Up: Non-PyPA Projects
+
+6.2.2 buildout
+--------------
+
+Docs(1) | Mailing list(2) (3) | Issues(4) | PyPI(5) | GitHub(6) |
+IRC:#buildout(7)
+
+Buildout is a Python-based build system for creating, assembling and
+deploying applications from multiple parts, some of which may be
+non-Python-based. It lets you create a buildout configuration and
+reproduce the same software later.
+
+ ---------- Footnotes ----------
+
+ (1) http://www.buildout.org/en/latest/
+
+ (2) http://mail.python.org/mailman/listinfo/distutils-sig
+
+ (3) (2) Multiple projects reuse the distutils-sig mailing list as
+their user list.
+
+ (4) https://bugs.launchpad.net/zc.buildout
+
+ (5) https://pypi.org/project/zc.buildout
+
+ (6) https://github.com/buildout/buildout/
+
+ (7) https://webchat.freenode.net/?channels=%23buildout
+
+
+File: pythonpackagingguide.info, Node: conda, Next: devpi, Prev: buildout, Up: Non-PyPA Projects
+
+6.2.3 conda
+-----------
+
+Docs(1)
+
+conda is the package management tool for Anaconda(2) Python
+installations. Anaconda Python is a distribution from Anaconda, Inc(3)
+specifically aimed at the scientific community, and in particular on
+Windows where the installation of binary extensions is often difficult.
+
+Conda is a completely separate tool from *note pip: 2b, virtualenv and
+wheel, but provides many of their combined features in terms of package
+management, virtual environment management and deployment of binary
+extensions.
+
+Conda does not install packages from PyPI and can install only from the
+official Anaconda repositories, or anaconda.org (a place for
+user-contributed `conda' packages), or a local (e.g. intranet) package
+server. However, note that *note pip: 2b. can be installed into, and
+work side-by-side with conda for managing *note distributions: b. from
+PyPI. Also, conda skeleton(4) is a tool to make Python packages
+installable by conda by first fetching them from PyPI and modifying
+their metadata.
+
+ ---------- Footnotes ----------
+
+ (1) http://conda.pydata.org/docs/
+
+ (2) https://docs.anaconda.com/anaconda/
+
+ (3) https://www.anaconda.com/download
+
+ (4)
+https://docs.conda.io/projects/conda-build/en/latest/user-guide/tutorials/build-pkgs-skeleton.html
+
+
+File: pythonpackagingguide.info, Node: devpi, Next: flit, Prev: conda, Up: Non-PyPA Projects
+
+6.2.4 devpi
+-----------
+
+Docs(1) | Mailing List(2) | Issues(3) | PyPI(4)
+
+devpi features a powerful PyPI-compatible server and PyPI proxy cache
+with a complementary command line tool to drive packaging, testing and
+release activities with Python. devpi also provides a browsable and
+searchable web interface.
+
+ ---------- Footnotes ----------
+
+ (1) http://doc.devpi.net/latest/
+
+ (2) https://groups.google.com/forum/#!forum/devpi-dev
+
+ (3) https://bitbucket.org/hpk42/devpi/issues
+
+ (4) https://pypi.org/project/devpi
+
+
+File: pythonpackagingguide.info, Node: flit, Next: enscons, Prev: devpi, Up: Non-PyPA Projects
+
+6.2.5 flit
+----------
+
+Docs(1) | Issues(2) | PyPI(3)
+
+Flit provides a simple way to upload pure Python packages and modules to
+PyPI. It focuses on making the easy things easy(4) for packaging. Flit
+can generate a configuration file to quickly set up a simple project,
+build source distributions and wheels, and upload them to PyPI.
+
+Flit uses ‘pyproject.toml’ to configure a project. Flit does not rely
+on tools such as *note setuptools: 2d. to build distributions, or *note
+twine: 66. to upload them to PyPI. Flit requires Python 3, but you can
+use it to distribute modules for Python 2, so long as they can be
+imported on Python 3.
+
+ ---------- Footnotes ----------
+
+ (1) https://flit.readthedocs.io/en/latest/
+
+ (2) https://github.com/takluyver/flit/issues
+
+ (3) https://pypi.org/project/flit
+
+ (4) https://flit.readthedocs.io/en/latest/rationale.html
+
+
+File: pythonpackagingguide.info, Node: enscons, Next: Hashdist, Prev: flit, Up: Non-PyPA Projects
+
+6.2.6 enscons
+-------------
+
+Source(1) | Issues(2) | PyPI(3)
+
+Enscons is a Python packaging tool based on SCons(4). It builds *note
+pip: 2b.-compatible source distributions and wheels without using
+distutils or setuptools, including distributions with C extensions.
+Enscons has a different architecture and philosophy than *note
+distutils: c0. Rather than adding build features to a Python packaging
+system, enscons adds Python packaging to a general purpose build system.
+Enscons helps you to build sdists that can be automatically built by
+*note pip: 2b, and wheels that are independent of enscons.
+
+ ---------- Footnotes ----------
+
+ (1) https://bitbucket.org/dholth/enscons/src
+
+ (2) https://bitbucket.org/dholth/enscons/issues
+
+ (3) https://pypi.org/project/enscons
+
+ (4) http://scons.org/
+
+
+File: pythonpackagingguide.info, Node: Hashdist, Next: hatch, Prev: enscons, Up: Non-PyPA Projects
+
+6.2.7 Hashdist
+--------------
+
+Docs(1) | GitHub(2)
+
+Hashdist is a library for building non-root software distributions.
+Hashdist is trying to be “the Debian of choice for cases where Debian
+technology doesn’t work”. The best way for Pythonistas to think about
+Hashdist may be a more powerful hybrid of *note virtualenv: 32. and
+*note buildout: 80. It is aimed at solving the problem of installing
+scientific software, and making package distribution stateless, cached,
+and branchable. It is used by some researchers but has been lacking in
+maintenance since 2016.
+
+ ---------- Footnotes ----------
+
+ (1) https://hashdist.readthedocs.io/en/latest/
+
+ (2) https://github.com/hashdist/hashdist/
+
+
+File: pythonpackagingguide.info, Node: hatch, Next: pex, Prev: Hashdist, Up: Non-PyPA Projects
+
+6.2.8 hatch
+-----------
+
+GitHub and Docs(1) | PyPI(2)
+
+Hatch is a unified command-line tool meant to conveniently manage
+dependencies and environment isolation for Python developers. Python
+package developers use Hatch to configure, version, specify dependencies
+for, and publish packages to PyPI. Under the hood, it uses *note twine:
+66. to upload packages to PyPI, and *note pip: 2b. to download and
+install packages.
+
+ ---------- Footnotes ----------
+
+ (1) https://github.com/ofek/hatch
+
+ (2) https://pypi.org/project/hatch
+
+
+File: pythonpackagingguide.info, Node: pex, Next: pipx, Prev: hatch, Up: Non-PyPA Projects
+
+6.2.9 pex
+---------
+
+Docs(1) | GitHub(2) | PyPI(3)
+
+pex is both a library and tool for generating ‘.pex’ (Python EXecutable)
+files, standalone Python environments in the spirit of *note virtualenv:
+32. ‘.pex’ files are just carefully constructed zip files with a
+‘#!/usr/bin/env python’ and special ‘__main__.py’, and are designed to
+make deployment of Python applications as simple as ‘cp’.
+
+ ---------- Footnotes ----------
+
+ (1) https://pex.readthedocs.io/en/latest/
+
+ (2) https://github.com/pantsbuild/pex/
+
+ (3) https://pypi.org/project/pex
+
+
+File: pythonpackagingguide.info, Node: pipx, Next: pip-tools, Prev: pex, Up: Non-PyPA Projects
+
+6.2.10 pipx
+-----------
+
+Docs(1) | GitHub(2) | PyPI(3)
+
+pipx is a tool to safely install and run Python CLI applications
+globally.
+
+ ---------- Footnotes ----------
+
+ (1) https://pipxproject.github.io/pipx/
+
+ (2) https://github.com/pipxproject/pipx
+
+ (3) https://pypi.org/project/pipx/
+
+
+File: pythonpackagingguide.info, Node: pip-tools, Next: piwheels, Prev: pipx, Up: Non-PyPA Projects
+
+6.2.11 pip-tools
+----------------
+
+GitHub and Docs(1) | PyPI(2)
+
+pip-tools is a suite of tools meant for Python system administrators and
+release managers who particularly want to keep their builds
+deterministic yet stay up to date with new versions of their
+dependencies. Users can specify particular release of their
+dependencies via hash, conveniently make a properly formatted list of
+requirements from information in other parts of their program, update
+all dependencies (a feature *note pip: 2b. currently does not provide),
+and create layers of constraints for the program to obey.
+
+ ---------- Footnotes ----------
+
+ (1) https://github.com/jazzband/pip-tools/
+
+ (2) https://pypi.org/project/pip-tools/
+
+
+File: pythonpackagingguide.info, Node: piwheels, Next: poetry, Prev: pip-tools, Up: Non-PyPA Projects
+
+6.2.12 piwheels
+---------------
+
+Website(1) | Docs(2) | GitHub(3)
+
+piwheels is a website, and software underpinning it, that fetches source
+code distribution packages from PyPI and compiles them into binary
+wheels that are optimized for installation onto Raspberry Pi computers.
+Raspberry Pi OS pre-configures pip to use piwheels.org as an additional
+index to PyPI.
+
+ ---------- Footnotes ----------
+
+ (1) https://www.piwheels.org/
+
+ (2) https://piwheels.readthedocs.io/
+
+ (3) https://github.com/piwheels/piwheels/
+
+
+File: pythonpackagingguide.info, Node: poetry, Next: pypiserver, Prev: piwheels, Up: Non-PyPA Projects
+
+6.2.13 poetry
+-------------
+
+Docs(1) | GitHub(2) | PyPI(3)
+
+poetry is a command-line tool to handle dependency installation and
+isolation as well as building and packaging of Python packages. It uses
+‘pyproject.toml’ and, instead of depending on the resolver functionality
+within *note pip: 2b, provides its own dependency resolver. It attempts
+to speed users’ experience of installation and dependency resolution by
+locally caching metadata about dependencies.
+
+ ---------- Footnotes ----------
+
+ (1) https://python-poetry.org/
+
+ (2) https://github.com/python-poetry/poetry
+
+ (3) https://pypi.org/project/poetry/
+
+
+File: pythonpackagingguide.info, Node: pypiserver, Next: scikit-build, Prev: poetry, Up: Non-PyPA Projects
+
+6.2.14 pypiserver
+-----------------
+
+Docs(1) | GitHub(2) | PyPI(3)
+
+pypiserver is a minimalist application that serves as a private Python
+package index within organizations, implementing a simple API and
+browser interface. You can upload private packages using standard
+upload tools, and users can download and install them with *note pip:
+2b, without publishing them publicly. Organizations who use pypiserver
+usually download packages both from pypiserver and from PyPI.
+
+ ---------- Footnotes ----------
+
+ (1) https://github.com/pypiserver/pypiserver/blob/master/README.rst
+
+ (2) https://github.com/pypiserver/pypiserver
+
+ (3) https://pypi.org/project/pypiserver/
+
+
+File: pythonpackagingguide.info, Node: scikit-build, Next: shiv, Prev: pypiserver, Up: Non-PyPA Projects
+
+6.2.15 scikit-build
+-------------------
+
+Docs(1) | Mailing list(2) | GitHub(3) | PyPI(4)
+
+Scikit-build is an improved build system generator for CPython
+C/C++/Fortran/Cython extensions that integrates with *note setuptools:
+2d, *note wheel: 2e. and *note pip: 2b. It internally uses cmake(5)
+(available on PyPI) to provide better support for additional compilers,
+build systems, cross compilation, and locating dependencies and their
+associated build requirements. To speed up and parallelize the build of
+large projects, the user can install ninja(6) (also available on PyPI).
+
+ ---------- Footnotes ----------
+
+ (1) https://scikit-build.readthedocs.io/en/latest/
+
+ (2) https://groups.google.com/forum/#!forum/scikit-build
+
+ (3) https://github.com/scikit-build/scikit-build/
+
+ (4) https://pypi.org/project/scikit-build
+
+ (5) https://pypi.org/project/cmake
+
+ (6) https://pypi.org/project/ninja
+
+
+File: pythonpackagingguide.info, Node: shiv, Next: Spack<2>, Prev: scikit-build, Up: Non-PyPA Projects
+
+6.2.16 shiv
+-----------
+
+Docs(1) | GitHub(2) | PyPI(3)
+
+shiv is a command line utility for building fully self contained Python
+zipapps as outlined in PEP 441(4), but with all their dependencies
+included. Its primary goal is making distributing Python applications
+and command line tools fast & easy.
+
+ ---------- Footnotes ----------
+
+ (1) https://shiv.readthedocs.io/en/latest/
+
+ (2) https://github.com/linkedin/shiv
+
+ (3) https://pypi.org/project/shiv/
+
+ (4) https://www.python.org/dev/peps/pep-0441
+
+
+File: pythonpackagingguide.info, Node: Spack<2>, Next: zest releaser, Prev: shiv, Up: Non-PyPA Projects
+
+6.2.17 Spack
+------------
+
+Docs(1) | GitHub(2) | Paper(3) | Slides(4)
+
+A flexible package manager designed to support multiple versions,
+configurations, platforms, and compilers. Spack is like Homebrew, but
+packages are written in Python and parameterized to allow easy swapping
+of compilers, library versions, build options, etc. Arbitrarily many
+versions of packages can coexist on the same system. Spack was designed
+for rapidly building high performance scientific applications on
+clusters and supercomputers.
+
+Spack is not in PyPI (yet), but it requires no installation and can be
+used immediately after cloning from GitHub.
+
+ ---------- Footnotes ----------
+
+ (1) https://spack.readthedocs.io/
+
+ (2) https://github.com/llnl/spack/
+
+ (3)
+http://www.computer.org/csdl/proceedings/sc/2015/3723/00/2807623.pdf
+
+ (4) https://tgamblin.github.io/files/Gamblin-Spack-SC15-Talk.pdf
+
+
+File: pythonpackagingguide.info, Node: zest releaser, Prev: Spack<2>, Up: Non-PyPA Projects
+
+6.2.18 zest.releaser
+--------------------
+
+Docs(1) | GitHub(2) | PyPI(3)
+
+‘zest.releaser’ is a Python package release tool providing an
+abstraction layer on top of *note twine: 66. Python developers use
+‘zest.releaser’ to automate incrementing package version numbers,
+updating changelogs, tagging releases in source control, and uploading
+new packages to PyPI.
+
+ ---------- Footnotes ----------
+
+ (1) https://zestreleaser.readthedocs.io/en/latest/
+
+ (2) https://github.com/zestsoftware/zest.releaser/
+
+ (3) https://pypi.org/project/zest.releaser/
+
+
+File: pythonpackagingguide.info, Node: Standard Library Projects, Prev: Non-PyPA Projects, Up: Project Summaries
+
+6.3 Standard Library Projects
+=============================
+
+* Menu:
+
+* ensurepip::
+* distutils::
+* venv::
+
+
+File: pythonpackagingguide.info, Node: ensurepip, Next: distutils, Up: Standard Library Projects
+
+6.3.1 ensurepip
+---------------
+
+Docs(1) | Issues(2)
+
+A package in the Python Standard Library that provides support for
+bootstrapping *note pip: 2b. into an existing Python installation or
+virtual environment. In most cases, end users won’t use this module,
+but rather it will be used during the build of the Python distribution.
+
+ ---------- Footnotes ----------
+
+ (1) https://docs.python.org/3/library/ensurepip.html
+
+ (2) http://bugs.python.org
+
+
+File: pythonpackagingguide.info, Node: distutils, Next: venv, Prev: ensurepip, Up: Standard Library Projects
+
+6.3.2 distutils
+---------------
+
+Docs(1) | User list(2) (3) | Issues(4) | User IRC:#pypa(5) | Dev
+IRC:#pypa-dev(6)
+
+The original Python packaging system, added to the standard library in
+Python 2.0.
+
+Due to the challenges of maintaining a packaging system where feature
+updates are tightly coupled to language runtime updates, direct usage of
+*note distutils: c0. is now actively discouraged, with *note setuptools:
+2d. being the preferred replacement. *note setuptools: 2d. not only
+provides features that plain *note distutils: c0. doesn’t offer (such as
+dependency declarations and entry point declarations), it also provides
+a consistent build interface and feature set across all supported Python
+versions.
+
+ ---------- Footnotes ----------
+
+ (1) https://docs.python.org/3/library/distutils.html
+
+ (2) http://mail.python.org/mailman/listinfo/distutils-sig
+
+ (3) (2) Multiple projects reuse the distutils-sig mailing list as
+their user list.
+
+ (4) http://bugs.python.org
+
+ (5) https://webchat.freenode.net/?channels=%23pypa
+
+ (6) https://webchat.freenode.net/?channels=%23pypa-dev
+
+
+File: pythonpackagingguide.info, Node: venv, Prev: distutils, Up: Standard Library Projects
+
+6.3.3 venv
+----------
+
+Docs(1) | Issues(2)
+
+A package in the Python Standard Library (starting with Python 3.3) for
+creating *note Virtual Environments: 22b. For more information, see the
+section on *note Creating Virtual Environments: 31.
+
+__________________________________________________________________
+
+ ---------- Footnotes ----------
+
+ (1) https://docs.python.org/3/library/venv.html
+
+ (2) http://bugs.python.org
+
+
+File: pythonpackagingguide.info, Node: Glossary, Next: How to Get Support, Prev: Project Summaries, Up: Top
+
+7 Glossary
+**********
+
+Binary Distribution
+
+ A specific kind of *note Built Distribution: 63. that contains
+ compiled extensions.
+
+Built Distribution
+
+ A *note Distribution: b. format containing files and metadata that
+ only need to be moved to the correct location on the target system,
+ to be installed. *note Wheel: d. is such a format, whereas
+ distutil’s *note Source Distribution: 3d. is not, in that it
+ requires a build step before it can be installed. This format does
+ not imply that Python files have to be precompiled (*note Wheel: d.
+ intentionally does not include compiled Python files).
+
+Distribution Package
+
+ A versioned archive file that contains Python *note packages: a,
+ *note modules: 255, and other resource files that are used to
+ distribute a *note Release: 256. The archive file is what an
+ end-user will download from the internet and install.
+
+ A distribution package is more commonly referred to with the single
+ words “package” or “distribution”, but this guide may use the
+ expanded term when more clarity is needed to prevent confusion with
+ an *note Import Package: a. (which is also commonly called a
+ “package”) or another kind of distribution (e.g. a Linux
+ distribution or the Python language distribution), which are often
+ referred to with the single term “distribution”.
+
+Egg
+
+ A *note Built Distribution: 63. format introduced by *note
+ setuptools: 2d, which is being replaced by *note Wheel: d. For
+ details, see The Internal Structure of Python Eggs(1) and Python
+ Eggs(2)
+
+Extension Module
+
+ A *note Module: 255. written in the low-level language of the
+ Python implementation: C/C++ for Python, Java for Jython.
+ Typically contained in a single dynamically loadable pre-compiled
+ file, e.g. a shared object (.so) file for Python extensions on
+ Unix, a DLL (given the .pyd extension) for Python extensions on
+ Windows, or a Java class file for Jython extensions.
+
+Known Good Set (KGS)
+
+ A set of distributions at specified versions which are compatible
+ with each other. Typically a test suite will be run which passes
+ all tests before a specific set of packages is declared a known
+ good set. This term is commonly used by frameworks and toolkits
+ which are comprised of multiple individual distributions.
+
+Import Package
+
+ A Python module which can contain other modules or recursively,
+ other packages.
+
+ An import package is more commonly referred to with the single word
+ “package”, but this guide will use the expanded term when more
+ clarity is needed to prevent confusion with a *note Distribution
+ Package: b. which is also commonly called a “package”.
+
+Module
+
+ The basic unit of code reusability in Python, existing in one of
+ two types: *note Pure Module: 259, or *note Extension Module: 257.
+
+Package Index
+
+ A repository of distributions with a web interface to automate
+ *note package: b. discovery and consumption.
+
+Per Project Index
+
+ A private or other non-canonical *note Package Index: ec. indicated
+ by a specific *note Project: 1fc. as the index preferred or
+ required to resolve dependencies of that project.
+
+Project
+
+ A library, framework, script, plugin, application, or collection of
+ data or other resources, or some combination thereof that is
+ intended to be packaged into a *note Distribution: b.
+
+ Since most projects create *note Distributions: b. using either PEP
+ 518(3) ‘build-system’, *note distutils: c0. or *note setuptools:
+ 2d, another practical way to define projects currently is something
+ that contains a *note pyproject.toml: 1d7, *note setup.py: 25b, or
+ *note setup.cfg: 25c. file at the root of the project source
+ directory.
+
+ Python projects must have unique names, which are registered on
+ *note PyPI: 39. Each project will then contain one or more *note
+ Releases: 256, and each release may comprise one or more *note
+ distributions: b.
+
+ Note that there is a strong convention to name a project after the
+ name of the package that is imported to run that project. However,
+ this doesn’t have to hold true. It’s possible to install a
+ distribution from the project ‘foo’ and have it provide a package
+ importable only as ‘bar’.
+
+Pure Module
+
+ A *note Module: 255. written in Python and contained in a single
+ ‘.py’ file (and possibly associated ‘.pyc’ and/or ‘.pyo’ files).
+
+Python Packaging Authority (PyPA)
+
+ PyPA is a working group that maintains many of the relevant
+ projects in Python packaging. They maintain a site at
+ ‘https://www.pypa.io’, host projects on GitHub(4) and Bitbucket(5),
+ and discuss issues on the distutils-sig mailing list(6) and the
+ Python Discourse forum(7).
+
+Python Package Index (PyPI)
+
+ PyPI(8) is the default *note Package Index: ec. for the Python
+ community. It is open to all Python developers to consume and
+ distribute their distributions.
+
+pypi.org
+
+ pypi.org(9) is the domain name for the *note Python Package Index
+ (PyPI): 39. It replaced the legacy index domain name,
+ ‘pypi.python.org’, in 2017. It is powered by *note Warehouse: 22d.
+
+pyproject.toml
+
+ The tool-agnostic *note Project: 1fc. specification file. Defined
+ in PEP 518(10).
+
+Release
+
+ A snapshot of a *note Project: 1fc. at a particular point in time,
+ denoted by a version identifier.
+
+ Making a release may entail the publishing of multiple *note
+ Distributions: b. For example, if version 1.0 of a project was
+ released, it could be available in both a source distribution
+ format and a Windows installer distribution format.
+
+Requirement
+
+ A specification for a *note package: b. to be installed. *note
+ pip: 2b, the *note PYPA: 25d. recommended installer, allows various
+ forms of specification that can all be considered a “requirement”.
+ For more information, see the pip install(11) reference.
+
+Requirement Specifier
+
+ A format used by *note pip: 2b. to install packages from a *note
+ Package Index: ec. For an EBNF diagram of the format, see the
+ pkg_resources.Requirement(12) entry in the *note setuptools: 2d.
+ docs. For example, “foo>=1.3” is a requirement specifier, where
+ “foo” is the project name, and the “>=1.3” portion is the *note
+ Version Specifier: 3b.
+
+Requirements File
+
+ A file containing a list of *note Requirements: 25e. that can be
+ installed using *note pip: 2b. For more information, see the *note
+ pip: 2b. docs on Requirements Files(13).
+
+setup.py
+
+setup.cfg
+
+ The project specification files for *note distutils: c0. and *note
+ setuptools: 2d. See also *note pyproject.toml: 1d7.
+
+Source Archive
+
+ An archive containing the raw source code for a *note Release: 256,
+ prior to creation of a *note Source Distribution: 3d. or *note
+ Built Distribution: 63.
+
+Source Distribution (or “sdist”)
+
+ A *note distribution: b. format (usually generated using ‘python
+ setup.py sdist’) that provides metadata and the essential source
+ files needed for installing by a tool like *note pip: 2b, or for
+ generating a *note Built Distribution: 63.
+
+System Package
+
+ A package provided in a format native to the operating system, e.g.
+ an rpm or dpkg file.
+
+Version Specifier
+
+ The version component of a *note Requirement Specifier: 3a. For
+ example, the “>=1.3” portion of “foo>=1.3”. PEP 440(14) contains a
+ full specification(15) of the specifiers that Python packaging
+ currently supports. Support for PEP440 was implemented in *note
+ setuptools: 2d. v8.0 and *note pip: 2b. v6.0.
+
+Virtual Environment
+
+ An isolated Python environment that allows packages to be installed
+ for use by a particular application, rather than being installed
+ system wide. For more information, see the section on *note
+ Creating Virtual Environments: 31.
+
+Wheel
+
+ A *note Built Distribution: 63. format introduced by PEP 427(16),
+ which is intended to replace the *note Egg: 7c. format. Wheel is
+ currently supported by *note pip: 2b.
+
+Working Set
+
+ A collection of *note distributions: b. available for importing.
+ These are the distributions that are on the sys.path(17) variable.
+ At most, one *note Distribution: b. for a project is possible in a
+ working set.
+
+ ---------- Footnotes ----------
+
+ (1)
+https://setuptools.readthedocs.io/en/latest/deprecated/python_eggs.html
+
+ (2) http://peak.telecommunity.com/DevCenter/PythonEggs
+
+ (3) https://www.python.org/dev/peps/pep-0518
+
+ (4) https://github.com/pypa
+
+ (5) https://bitbucket.org/pypa
+
+ (6) https://mail.python.org/mailman3/lists/distutils-sig.python.org/
+
+ (7) https://discuss.python.org/c/packaging
+
+ (8) https://pypi.org
+
+ (9) https://pypi.org
+
+ (10) https://www.python.org/dev/peps/pep-0518
+
+ (11) https://pip.pypa.io/en/latest/reference/pip_install/#pip-install
+
+ (12)
+https://setuptools.readthedocs.io/en/latest/pkg_resources.html#requirement-objects
+
+ (13) https://pip.pypa.io/en/latest/user_guide/#requirements-files
+
+ (14) https://www.python.org/dev/peps/pep-0440
+
+ (15) https://www.python.org/dev/peps/pep-0440#version-specifiers
+
+ (16) https://www.python.org/dev/peps/pep-0427
+
+ (17) https://docs.python.org/2/library/sys.html#sys.path
+
+
+File: pythonpackagingguide.info, Node: How to Get Support, Next: Contribute to this guide, Prev: Glossary, Up: Top
+
+8 How to Get Support
+********************
+
+For support related to a specific project, see the links on the *note
+Projects: 213. page.
+
+For something more general, or when you’re just not sure, use the
+distutils-sig(1) list.
+
+ ---------- Footnotes ----------
+
+ (1) http://mail.python.org/mailman/listinfo/distutils-sig
+
+
+File: pythonpackagingguide.info, Node: Contribute to this guide, Next: News, Prev: How to Get Support, Up: Top
+
+9 Contribute to this guide
+**************************
+
+The Python Packaging User Guide welcomes contributors! There are lots
+of ways to help out, including:
+
+ * Reading the guide and giving feedback
+
+ * Reviewing new contributions
+
+ * Revising existing content
+
+ * Writing new content
+
+Most of the work on the Python Packaging User Guide takes place on the
+project’s GitHub repository(1). To get started, check out the list of
+open issues(2) and pull requests(3). If you’re planning to write or
+edit the guide, please read the *note style guide: 266.
+
+By contributing to the Python Packaging User Guide, you’re expected to
+follow the PSF’s Code of Conduct(4).
+
+* Menu:
+
+* Documentation types::
+* Building the guide locally::
+* Where the guide is deployed::
+* Style guide::
+
+ ---------- Footnotes ----------
+
+ (1) https://github.com/pypa/python-packaging-user-guide/
+
+ (2) https://github.com/pypa/python-packaging-user-guide/issues
+
+ (3) https://github.com/pypa/python-packaging-user-guide/pulls
+
+ (4) https://github.com/pypa/.github/blob/main/CODE_OF_CONDUCT.md
+
+
+File: pythonpackagingguide.info, Node: Documentation types, Next: Building the guide locally, Up: Contribute to this guide
+
+9.1 Documentation types
+=======================
+
+This project consists of four distinct documentation types with specific
+purposes. When proposing new additions to the project please pick the
+appropriate documentation type.
+
+* Menu:
+
+* Tutorials: Tutorials<2>.
+* Guides: Guides<2>.
+* Discussions: Discussions<2>.
+* Specifications::
+
+
+File: pythonpackagingguide.info, Node: Tutorials<2>, Next: Guides<2>, Up: Documentation types
+
+9.1.1 Tutorials
+---------------
+
+Tutorials are focused on teaching the reader new concepts by
+accomplishing a goal. They are opinionated step-by-step guides. They
+do not include extraneous warnings or information. example
+tutorial-style document(1).
+
+ ---------- Footnotes ----------
+
+ (1) https://docs.djangoproject.com/en/1.11/intro/
+
+
+File: pythonpackagingguide.info, Node: Guides<2>, Next: Discussions<2>, Prev: Tutorials<2>, Up: Documentation types
+
+9.1.2 Guides
+------------
+
+Guides are focused on accomplishing a specific task and can assume some
+level of pre-requisite knowledge. These are similar to tutorials, but
+have a narrow and clear focus and can provide lots of caveats and
+additional information as needed. They may also discuss multiple
+approaches to accomplishing the task. *note example guide-style
+document: 130.
+
+
+File: pythonpackagingguide.info, Node: Discussions<2>, Next: Specifications, Prev: Guides<2>, Up: Documentation types
+
+9.1.3 Discussions
+-----------------
+
+Discussions are focused on understanding and information. These explore
+a specific topic without a specific goal in mind. *note example
+discussion-style document: 18c.
+
+
+File: pythonpackagingguide.info, Node: Specifications, Prev: Discussions<2>, Up: Documentation types
+
+9.1.4 Specifications
+--------------------
+
+Specifications are reference documention focused on comprehensively
+documenting an agreed-upon interface for interoperability between
+packaging tools. *note example specification-style document: 199.
+
+
+File: pythonpackagingguide.info, Node: Building the guide locally, Next: Where the guide is deployed, Prev: Documentation types, Up: Contribute to this guide
+
+9.2 Building the guide locally
+==============================
+
+Though not required to contribute, it may be useful to build this guide
+locally in order to test your changes. In order to build this guide
+locally, you’ll need:
+
+ 1. Nox(1). You can install or upgrade nox using ‘pip’:
+
+ pip install --user nox
+
+ 2. Python 3.6. Our build scripts are designed to work with Python 3.6
+ only. See the Hitchhiker’s Guide to Python installation
+ instructions(2) to install Python 3.6 on your operating system.
+
+To build the guide, run the following bash command in the source folder:
+
+ nox -s build
+
+After the process has completed you can find the HTML output in the
+‘./build/html’ directory. You can open the ‘index.html’ file to view
+the guide in web browser, but it’s recommended to serve the guide using
+an HTTP server.
+
+You can build the guide and serve it via an HTTP server using the
+following command:
+
+ nox -s preview
+
+The guide will be browsable via ‘http://localhost:8000’.
+
+ ---------- Footnotes ----------
+
+ (1) https://nox.readthedocs.io/en/latest/
+
+ (2) http://docs.python-guide.org/en/latest/starting/installation/
+
+
+File: pythonpackagingguide.info, Node: Where the guide is deployed, Next: Style guide, Prev: Building the guide locally, Up: Contribute to this guide
+
+9.3 Where the guide is deployed
+===============================
+
+The guide is deployed via ReadTheDocs and the configuration lives at
+‘https://readthedocs.org/projects/python-packaging-user-guide/’. It’s
+served from a custom domain and fronted by Fast.ly.
+
+
+File: pythonpackagingguide.info, Node: Style guide, Prev: Where the guide is deployed, Up: Contribute to this guide
+
+9.4 Style guide
+===============
+
+This style guide has recommendations for how you should write the Python
+Packaging User Guide. Before you start writing, please review it. By
+following the style guide, your contributions will help add to a
+cohesive whole and make it easier for your contributions to be accepted
+into the project.
+
+* Menu:
+
+* Purpose::
+* Scope::
+* Audience::
+* Voice and tone::
+* Conventions and mechanics::
+
+
+File: pythonpackagingguide.info, Node: Purpose, Next: Scope, Up: Style guide
+
+9.4.1 Purpose
+-------------
+
+The purpose of the Python Packaging User Guide is to be the
+authoritative resource on how to package, publish, and install Python
+projects using current tools.
+
+
+File: pythonpackagingguide.info, Node: Scope, Next: Audience, Prev: Purpose, Up: Style guide
+
+9.4.2 Scope
+-----------
+
+The guide is meant to answer questions and solve problems with accurate
+and focused recommendations.
+
+The guide isn’t meant to be comprehensive and it’s not meant to replace
+individual projects’ documentation. For example, pip has dozens of
+commands, options, and settings. The pip documentation describes each
+of them in detail, while this guide describes only the parts of pip that
+are needed to complete the specific tasks described in this guide.
+
+
+File: pythonpackagingguide.info, Node: Audience, Next: Voice and tone, Prev: Scope, Up: Style guide
+
+9.4.3 Audience
+--------------
+
+The audience of this guide is anyone who uses Python with packages.
+
+Don’t forget that the Python community is big and welcoming. Readers
+may not share your age, gender, education, culture, and more, but they
+deserve to learn about packaging just as much as you do.
+
+In particular, keep in mind that not all people who use Python see
+themselves as programmers. The audience of this guide includes
+astronomers or painters or students as well as professional software
+developers.
+
+
+File: pythonpackagingguide.info, Node: Voice and tone, Next: Conventions and mechanics, Prev: Audience, Up: Style guide
+
+9.4.4 Voice and tone
+--------------------
+
+When writing this guide, strive to write with a voice that’s
+approachable and humble, even if you have all the answers.
+
+Imagine you’re working on a Python project with someone you know to be
+smart and skilled. You like working with them and they like working
+with you. That person has asked you a question and you know the answer.
+How do you respond? `That' is how you should write this guide.
+
+Here’s a quick check: try reading aloud to get a sense for your
+writing’s voice and tone. Does it sound like something you would say or
+does it sound like you’re acting out a part or giving a speech? Feel
+free to use contractions and don’t worry about sticking to fussy grammar
+rules. You are hereby granted permission to end a sentence in a
+preposition, if that’s what you want to end it with.
+
+When writing the guide, adjust your tone for the seriousness and
+difficulty of the topic. If you’re writing an introductory tutorial,
+it’s OK to make a joke, but if you’re covering a sensitive security
+recommendation, you might want to avoid jokes altogether.
+
+
+File: pythonpackagingguide.info, Node: Conventions and mechanics, Prev: Voice and tone, Up: Style guide
+
+9.4.5 Conventions and mechanics
+-------------------------------
+
+`Write to the reader'
+
+ When giving recommendations or steps to take, address the reader as
+ `you' or use the imperative mood.
+
+ Wrong: To install it, the user runs…
+ Right: You can install it by running…
+ Right: To install it, run…
+
+`State assumptions'
+
+ Avoid making unstated assumptions. Reading on the web means that
+ any page of the guide may be the first page of the guide that the
+ reader ever sees. If you’re going to make assumptions, then say
+ what assumptions that you’re going to make.
+
+`Cross-reference generously'
+
+ The first time you mention a tool or practice, link to the part of
+ the guide that covers it, or link to a relevant document elsewhere.
+ Save the reader a search.
+
+`Respect naming practices'
+
+ When naming tools, sites, people, and other proper nouns, use their
+ preferred capitalization.
+
+ Wrong: Pip uses…
+ Right: pip uses…
+
+ Wrong: …hosted on github.
+ Right: …hosted on GitHub.
+
+`Use a gender-neutral style'
+
+ Often, you’ll address the reader directly with `you', `your' and
+ `yours'. Otherwise, use gender-neutral pronouns `they', `their',
+ and `theirs' or avoid pronouns entirely.
+
+ Wrong: A maintainer uploads the file. Then he…
+ Right: A maintainer uploads the file. Then they…
+ Right: A maintainer uploads the file. Then the maintainer…
+
+`Headings'
+
+ Write headings that use words the reader is searching for. A good
+ way to do this is to have your heading complete an implied
+ question. For example, a reader might want to know `How do I
+ install MyLibrary?' so a good heading might be `Install
+ MyLibrary'.
+
+ In section headings, use sentence case. In other words, write
+ headings as you would write a typical sentence.
+
+ Wrong: Things You Should Know About Python
+ Right: Things you should know about Python
+
+`Numbers'
+
+ In body text, write numbers one through nine as words. For other
+ numbers or numbers in tables, use numerals.
+
+
+File: pythonpackagingguide.info, Node: News, Next: Get started, Prev: Contribute to this guide, Up: Top
+
+10 News
+*******
+
+* Menu:
+
+* September 2019::
+* August 2019::
+* July 2019::
+* June 2019::
+* May 2019::
+* April 2019::
+* March 2019::
+* February 2019::
+* January 2019::
+* December 2018::
+* November 2018::
+* October 2018::
+* September 2018::
+* August 2018::
+* July 2018::
+* June 2018::
+* May 2018::
+* April 2018::
+* March 2018::
+* February 2018::
+* January 2018::
+* December 2017::
+* November 2017::
+* October 2017::
+* September 2017::
+* August 2017::
+* July 2017::
+* June 2017::
+* May 2017::
+* April 2017::
+* March 2017::
+* February 2017::
+
+
+File: pythonpackagingguide.info, Node: September 2019, Next: August 2019, Up: News
+
+10.1 September 2019
+===================
+
+ - Added a guide about publishing dists via GitHub Actions. (PR
+ #647(1))
+
+ ---------- Footnotes ----------
+
+ (1) https://github.com/pypa/packaging.python.org/pull/647
+
+
+File: pythonpackagingguide.info, Node: August 2019, Next: July 2019, Prev: September 2019, Up: News
+
+10.2 August 2019
+================
+
+ - Updated to use ‘python3 -m’ when installing pipx. (PR #631(1))
+
+ ---------- Footnotes ----------
+
+ (1) https://github.com/pypa/packaging.python.org/pull/631
+
+
+File: pythonpackagingguide.info, Node: July 2019, Next: June 2019, Prev: August 2019, Up: News
+
+10.3 July 2019
+==============
+
+ - Marked all PEP numbers with the :pep: role. (PR #629(1))
+
+ - Upgraded Sphinx version and removed pypa.io intersphinx. (PR
+ #625(2))
+
+ - Mentioned ‘find_namespace_packages’. (PR #622(3))
+
+ - Updated directory layout examples for consistency. (PR #611(4))
+
+ - Updated Bandersnatch link to GitHub. (PR #623(5))
+
+ ---------- Footnotes ----------
+
+ (1) https://github.com/pypa/packaging.python.org/pull/629
+
+ (2) https://github.com/pypa/packaging.python.org/pull/625
+
+ (3) https://github.com/pypa/packaging.python.org/pull/622
+
+ (4) https://github.com/pypa/packaging.python.org/pull/611
+
+ (5) https://github.com/pypa/packaging.python.org/pull/623
+
+
+File: pythonpackagingguide.info, Node: June 2019, Next: May 2019, Prev: July 2019, Up: News
+
+10.4 June 2019
+==============
+
+ - Fixed some typos. (PR #620(1))
+
+ ---------- Footnotes ----------
+
+ (1) https://github.com/pypa/packaging.python.org/pull/620
+
+
+File: pythonpackagingguide.info, Node: May 2019, Next: April 2019, Prev: June 2019, Up: News
+
+10.5 May 2019
+=============
+
+ - Added ‘python_requires’ usage to packaging tutorial. (PR #613(1))
+
+ - Added a MANIFEST.in guide page. (PR #609(2))
+
+ ---------- Footnotes ----------
+
+ (1) https://github.com/pypa/packaging.python.org/pull/613
+
+ (2) https://github.com/pypa/packaging.python.org/pull/609
+
+
+File: pythonpackagingguide.info, Node: April 2019, Next: March 2019, Prev: May 2019, Up: News
+
+10.6 April 2019
+===============
+
+ - Added a mention for ‘shiv’ in the key projects section. (PR
+ #608(1))
+
+ - Reduced emphasis on virtualenv. (PR #606(2))
+
+ ---------- Footnotes ----------
+
+ (1) https://github.com/pypa/packaging.python.org/pull/608
+
+ (2) https://github.com/pypa/packaging.python.org/pull/606
+
+
+File: pythonpackagingguide.info, Node: March 2019, Next: February 2019, Prev: April 2019, Up: News
+
+10.7 March 2019
+===============
+
+ - Moved single-sourcing guide version option to Python 3. (PR
+ #605(1))
+
+ - Covered RTD details for contributing. (PR #600(2))
+
+ ---------- Footnotes ----------
+
+ (1) https://github.com/pypa/packaging.python.org/pull/605
+
+ (2) https://github.com/pypa/packaging.python.org/pull/600
+
+
+File: pythonpackagingguide.info, Node: February 2019, Next: January 2019, Prev: March 2019, Up: News
+
+10.8 February 2019
+==================
+
+ - Elaborate upon the differences between the tutorial and the real
+ packaging process. (PR #602(1))
+
+ - Added instructions to install Python CLI applications. (PR
+ #594(2))
+
+ ---------- Footnotes ----------
+
+ (1) https://github.com/pypa/packaging.python.org/pull/602
+
+ (2) https://github.com/pypa/packaging.python.org/pull/594
+
+
+File: pythonpackagingguide.info, Node: January 2019, Next: December 2018, Prev: February 2019, Up: News
+
+10.9 January 2019
+=================
+
+ - Added ‘--no-deps’ to the packaging tutorial. (PR #593(1))
+
+ - Updated Sphinx and Nox. (PR #591(2))
+
+ - Referenced Twine from Python3. (PR #581(3))
+
+ ---------- Footnotes ----------
+
+ (1) https://github.com/pypa/packaging.python.org/pull/593
+
+ (2) https://github.com/pypa/packaging.python.org/pull/591
+
+ (3) https://github.com/pypa/packaging.python.org/pull/581
+
+
+File: pythonpackagingguide.info, Node: December 2018, Next: November 2018, Prev: January 2019, Up: News
+
+10.10 December 2018
+===================
+
+ - No programmers in the office!
+
+
+File: pythonpackagingguide.info, Node: November 2018, Next: October 2018, Prev: December 2018, Up: News
+
+10.11 November 2018
+===================
+
+ - Removed landing page link to PyPI migration guide. (PR #575(1))
+
+ - Changed bumpversion to bump2version. (PR #572(2))
+
+ - Added single-sourcing package version example. (PR #573(3))
+
+ - Added a guide for creating documentation. (PR #568(4))
+
+ ---------- Footnotes ----------
+
+ (1) https://github.com/pypa/packaging.python.org/pull/575
+
+ (2) https://github.com/pypa/packaging.python.org/pull/572
+
+ (3) https://github.com/pypa/packaging.python.org/pull/573
+
+ (4) https://github.com/pypa/packaging.python.org/pull/568
+
+
+File: pythonpackagingguide.info, Node: October 2018, Next: September 2018, Prev: November 2018, Up: News
+
+10.12 October 2018
+==================
+
+ - Updated Nox package name. (PR #566(1))
+
+ - Mentioned Sphinx extensions in guides. (PR #562(2))
+
+ ---------- Footnotes ----------
+
+ (1) https://github.com/pypa/packaging.python.org/pull/566
+
+ (2) https://github.com/pypa/packaging.python.org/pull/562
+
+
+File: pythonpackagingguide.info, Node: September 2018, Next: August 2018, Prev: October 2018, Up: News
+
+10.13 September 2018
+====================
+
+ - Added a section on checking RST markup. (PR #554(1))
+
+ - Updated user installs page. (PR #558(2))
+
+ - Updated Google BigQuery urls. (PR #556(3))
+
+ - Replaced tar command with working command. (PR #552(4))
+
+ - Changed to double quotes in the pip install SomeProject==1.4. (PR
+ #550(5))
+
+ ---------- Footnotes ----------
+
+ (1) https://github.com/pypa/packaging.python.org/pull/554
+
+ (2) https://github.com/pypa/packaging.python.org/pull/558
+
+ (3) https://github.com/pypa/packaging.python.org/pull/556
+
+ (4) https://github.com/pypa/packaging.python.org/pull/552
+
+ (5) https://github.com/pypa/packaging.python.org/pull/550
+
+
+File: pythonpackagingguide.info, Node: August 2018, Next: July 2018, Prev: September 2018, Up: News
+
+10.14 August 2018
+=================
+
+ - Removed the recommendation to store passwords in cleartext. (PR
+ #546(1))
+
+ - Moved the Overview to a task based lead in along with the others.
+ (PR #540(2))
+
+ - Updated Python version supported by virtualenv. (PR #538(3))
+
+ - Added outline/rough draft of new Overview page. (PR #519(4))
+
+ ---------- Footnotes ----------
+
+ (1) https://github.com/pypa/packaging.python.org/pull/546
+
+ (2) https://github.com/pypa/packaging.python.org/pull/540
+
+ (3) https://github.com/pypa/packaging.python.org/pull/538
+
+ (4) https://github.com/pypa/packaging.python.org/pull/519
+
+
+File: pythonpackagingguide.info, Node: July 2018, Next: June 2018, Prev: August 2018, Up: News
+
+10.15 July 2018
+===============
+
+ - Improved binary extension docs. (PR #531(1))
+
+ - Added scikit-build to key projects. (PR #530(2))
+
+ ---------- Footnotes ----------
+
+ (1) https://github.com/pypa/packaging.python.org/pull/531
+
+ (2) https://github.com/pypa/packaging.python.org/pull/530
+
+
+File: pythonpackagingguide.info, Node: June 2018, Next: May 2018, Prev: July 2018, Up: News
+
+10.16 June 2018
+===============
+
+ - Fixed categories of interop PEP for pypa.io. (PR #527(1))
+
+ - Updated Markdown descriptions explanation. (PR #522(2))
+
+ ---------- Footnotes ----------
+
+ (1) https://github.com/pypa/packaging.python.org/pull/527
+
+ (2) https://github.com/pypa/packaging.python.org/pull/522
+
+
+File: pythonpackagingguide.info, Node: May 2018, Next: April 2018, Prev: June 2018, Up: News
+
+10.17 May 2018
+==============
+
+ - Noted issues with Provides-Dist and Obsoletes-Dist. (PR #513(1))
+
+ - Removed outdated warning about Python version mixing with Pipenv.
+ (PR #501(2))
+
+ - Simplified packaging tutorial. (PR #498(3))
+
+ - Updated Windows users instructions for clarity. (PR #493(4))
+
+ - Updated the license section description for completeness. (PR
+ #492(5))
+
+ - Added specification-style document to contributing section. (PR
+ #489(6))
+
+ - Added documentation types to contributing guide. (PR #485(7))
+
+ ---------- Footnotes ----------
+
+ (1) https://github.com/pypa/packaging.python.org/pull/513
+
+ (2) https://github.com/pypa/packaging.python.org/pull/501
+
+ (3) https://github.com/pypa/packaging.python.org/pull/498
+
+ (4) https://github.com/pypa/packaging.python.org/pull/493
+
+ (5) https://github.com/pypa/packaging.python.org/pull/492
+
+ (6) https://github.com/pypa/packaging.python.org/pull/489
+
+ (7) https://github.com/pypa/packaging.python.org/pull/485
+
+
+File: pythonpackagingguide.info, Node: April 2018, Next: March 2018, Prev: May 2018, Up: News
+
+10.18 April 2018
+================
+
+ - Added README guide. (PR #461(1))
+
+ - Updated instructions and status for PyPI launch. (PR #475(2))
+
+ - Added instructions for Warehouse. (PR #471(3))
+
+ - Removed GPG references from publishing tutorial. (PR #466(4))
+
+ - Added ‘What’s in which Python 3.4–3.6?’. (PR #468(5))
+
+ - Added a guide for phasing out Python versions. (PR #459(6))
+
+ - Made default Description-Content-Type variant GFM. (PR #462(7))
+
+ ---------- Footnotes ----------
+
+ (1) https://github.com/pypa/packaging.python.org/pull/461
+
+ (2) https://github.com/pypa/packaging.python.org/pull/475
+
+ (3) https://github.com/pypa/packaging.python.org/pull/471
+
+ (4) https://github.com/pypa/packaging.python.org/pull/466
+
+ (5) https://github.com/pypa/packaging.python.org/pull/468
+
+ (6) https://github.com/pypa/packaging.python.org/pull/459
+
+ (7) https://github.com/pypa/packaging.python.org/pull/462
+
+
+File: pythonpackagingguide.info, Node: March 2018, Next: February 2018, Prev: April 2018, Up: News
+
+10.19 March 2018
+================
+
+ - Updated “installing scientific packages”. (PR #455(1))
+
+ - Added ‘long_description_content_type’ to follow PEP 556. (PR
+ #457(2))
+
+ - Clarified a long description classifier on pypi.org. (PR #456(3))
+
+ - Updated Core Metadata spec to follw PEP 556. (PR #412(4))
+
+ ---------- Footnotes ----------
+
+ (1) https://github.com/pypa/packaging.python.org/pull/455
+
+ (2) https://github.com/pypa/packaging.python.org/pull/457
+
+ (3) https://github.com/pypa/packaging.python.org/pull/456
+
+ (4) https://github.com/pypa/packaging.python.org/pull/412
+
+
+File: pythonpackagingguide.info, Node: February 2018, Next: January 2018, Prev: March 2018, Up: News
+
+10.20 February 2018
+===================
+
+ - Added python3-venv and python3-pip to Debian installation
+ instructions. (PR #445(1))
+
+ - Updated PyPI migration info. (PR #439(2))
+
+ - Added a warning about managing multiple versions with pipenv. (PR
+ #430(3))
+
+ - Added example of multiple emails to Core Metadata. (PR #429(4))
+
+ - Added explanation of “legacy” in test.pypi.org/legacy. (PR
+ #426(5))
+
+ ---------- Footnotes ----------
+
+ (1) https://github.com/pypa/packaging.python.org/pull/445
+
+ (2) https://github.com/pypa/packaging.python.org/pull/439
+
+ (3) https://github.com/pypa/packaging.python.org/pull/430
+
+ (4) https://github.com/pypa/packaging.python.org/pull/429
+
+ (5) https://github.com/pypa/packaging.python.org/pull/426
+
+
+File: pythonpackagingguide.info, Node: January 2018, Next: December 2017, Prev: February 2018, Up: News
+
+10.21 January 2018
+==================
+
+ - Added a link to PyPI’s list of classifiers. (PR #425(1))
+
+ - Updated README.rst explanation. (PR #419(2))
+
+ ---------- Footnotes ----------
+
+ (1) https://github.com/pypa/packaging.python.org/pull/425
+
+ (2) https://github.com/pypa/packaging.python.org/pull/419
+
+
+File: pythonpackagingguide.info, Node: December 2017, Next: November 2017, Prev: January 2018, Up: News
+
+10.22 December 2017
+===================
+
+ - Replaced ‘~’ with ‘$HOME’ in guides and tutorials. (PR #418(1))
+
+ - Noted which fields can be used with environment markers. (PR
+ #416(2))
+
+ - Updated Requires-Python section. (PR #414(3))
+
+ - Added news page. (PR #404(4))
+
+ ---------- Footnotes ----------
+
+ (1) https://github.com/pypa/packaging.python.org/pull/418
+
+ (2) https://github.com/pypa/packaging.python.org/pull/416
+
+ (3) https://github.com/pypa/packaging.python.org/pull/414
+
+ (4) https://github.com/pypa/packaging.python.org/pull/404
+
+
+File: pythonpackagingguide.info, Node: November 2017, Next: October 2017, Prev: December 2017, Up: News
+
+10.23 November 2017
+===================
+
+ - Introduced a new dependency management tutorial based on Pipenv.
+ (PR #402(1))
+
+ - Updated the `Single Sourcing Package Version' tutorial to reflect
+ pip’s current strategy. (PR #400(2))
+
+ - Added documentation about the ‘py_modules’ argument to ‘setup’.
+ (PR #398(3))
+
+ - Simplified the wording for the ‘manifest.in’ section. (PR #395(4))
+
+ ---------- Footnotes ----------
+
+ (1) https://github.com/pypa/packaging.python.org/pull/402
+
+ (2) https://github.com/pypa/packaging.python.org/pull/400
+
+ (3) https://github.com/pypa/packaging.python.org/pull/398
+
+ (4) https://github.com/pypa/packaging.python.org/pull/395
+
+
+File: pythonpackagingguide.info, Node: October 2017, Next: September 2017, Prev: November 2017, Up: News
+
+10.24 October 2017
+==================
+
+ - Added a specification for the ‘entry_points.txt’ file. (PR
+ #398(1))
+
+ - Created a new guide for managing packages using ‘pip’ and
+ ‘virtualenv’. (PR #385(2))
+
+ - Split the specifications page into multiple pages. (PR #386(3))
+
+ ---------- Footnotes ----------
+
+ (1) https://github.com/pypa/packaging.python.org/pull/398
+
+ (2) https://github.com/pypa/packaging.python.org/pull/385
+
+ (3) https://github.com/pypa/packaging.python.org/pull/386
+
+
+File: pythonpackagingguide.info, Node: September 2017, Next: August 2017, Prev: October 2017, Up: News
+
+10.25 September 2017
+====================
+
+ - Encouraged using ‘readme_renderer’ to validate ‘README.rst’. (PR
+ #379(1))
+
+ - Recommended using the ‘--user-base’ option. (PR #374(2))
+
+ ---------- Footnotes ----------
+
+ (1) https://github.com/pypa/packaging.python.org/pull/379
+
+ (2) https://github.com/pypa/packaging.python.org/pull/374
+
+
+File: pythonpackagingguide.info, Node: August 2017, Next: July 2017, Prev: September 2017, Up: News
+
+10.26 August 2017
+=================
+
+ - Added a new, experimental tutorial on installing packages using
+ ‘Pipenv’. (PR #369(1))
+
+ - Added a new guide on how to use ‘TestPyPI’. (PR #366(2))
+
+ - Added ‘pypi.org’ as a term. (PR #365(3))
+
+ ---------- Footnotes ----------
+
+ (1) https://github.com/pypa/packaging.python.org/pull/369
+
+ (2) https://github.com/pypa/packaging.python.org/pull/366
+
+ (3) https://github.com/pypa/packaging.python.org/pull/365
+
+
+File: pythonpackagingguide.info, Node: July 2017, Next: June 2017, Prev: August 2017, Up: News
+
+10.27 July 2017
+===============
+
+ - Added ‘flit’ to the key projects list. (PR #358(1))
+
+ - Added ‘enscons’ to the list of key projects. (PR #357(2))
+
+ - Updated this guide’s ‘readme’ with instructions on how to build the
+ guide locally. (PR #356(3))
+
+ - Made the new ‘TestPyPI’ URL more visible, adding note to homepage
+ about pypi.org. (PR #354(4))
+
+ - Added a note about the removal of the explicit registration API.
+ (PR #347(5))
+
+ ---------- Footnotes ----------
+
+ (1) https://github.com/pypa/packaging.python.org/pull/358
+
+ (2) https://github.com/pypa/packaging.python.org/pull/357
+
+ (3) https://github.com/pypa/packaging.python.org/pull/356
+
+ (4) https://github.com/pypa/packaging.python.org/pull/354
+
+ (5) https://github.com/pypa/packaging.python.org/pull/347
+
+
+File: pythonpackagingguide.info, Node: June 2017, Next: May 2017, Prev: July 2017, Up: News
+
+10.28 June 2017
+===============
+
+ - Added a document on migrating uploads to ‘PyPI.org’. (PR #339(1))
+
+ - Added documentation for ‘python_requires’. (PR #338(2))
+
+ - Added a note about PyPI migration in the `Tool Recommendations'
+ tutorial. (PR #335(3))
+
+ - Added a note that ‘manifest.in’ does not affect wheels. (PR
+ #332(4))
+
+ - Added a license section to the distributing guide. (PR #331(5))
+
+ - Expanded the section on the ‘name’ argument. (PR #329(6))
+
+ - Adjusted the landing page. (PR #327(7), PR #326(8), PR #324(9))
+
+ - Updated to Sphinx 1.6.2. (PR #323(10))
+
+ - Switched to the PyPA theme. (PR #305(11))
+
+ - Re-organized the documentation into the new structure. (PR
+ #318(12))
+
+ ---------- Footnotes ----------
+
+ (1) https://github.com/pypa/packaging.python.org/pull/339
+
+ (2) https://github.com/pypa/packaging.python.org/pull/338
+
+ (3) https://github.com/pypa/packaging.python.org/pull/335
+
+ (4) https://github.com/pypa/packaging.python.org/pull/332
+
+ (5) https://github.com/pypa/packaging.python.org/pull/331
+
+ (6) https://github.com/pypa/packaging.python.org/pull/329
+
+ (7) https://github.com/pypa/packaging.python.org/pull/327
+
+ (8) https://github.com/pypa/packaging.python.org/pull/326
+
+ (9) https://github.com/pypa/packaging.python.org/pull/324
+
+ (10) https://github.com/pypa/packaging.python.org/pull/323
+
+ (11) https://github.com/pypa/packaging.python.org/pull/305
+
+ (12) https://github.com/pypa/packaging.python.org/pull/318
+
+
+File: pythonpackagingguide.info, Node: May 2017, Next: April 2017, Prev: June 2017, Up: News
+
+10.29 May 2017
+==============
+
+ - Added documentation for the ‘Description-Content-Type’ field. (PR
+ #258(1))
+
+ - Added contributor and style guide. (PR #307(2))
+
+ - Documented ‘pip’ and ‘easy_install’’s differences for per-project
+ indexes. (PR #233(3))
+
+ ---------- Footnotes ----------
+
+ (1) https://github.com/pypa/packaging.python.org/pull/258
+
+ (2) https://github.com/pypa/packaging.python.org/pull/307
+
+ (3) https://github.com/pypa/packaging.python.org/pull/233
+
+
+File: pythonpackagingguide.info, Node: April 2017, Next: March 2017, Prev: May 2017, Up: News
+
+10.30 April 2017
+================
+
+ - Added travis configuration for testing pull requests. (PR #300(1))
+
+ - Mentioned the requirement of the ‘wheel’ package for creating
+ wheels (PR #299(2))
+
+ - Removed the ‘twine register’ reference in the `Distributing
+ Packages' tutorial. (PR #271(3))
+
+ - Added a topic on plugin discovery. (PR #294(4), PR #296(5))
+
+ - Added a topic on namespace packages. (PR #290(6))
+
+ - Added documentation explaining prominently how to install ‘pip’ in
+ ‘/usr/local’. (PR #230(7))
+
+ - Updated development mode documentation to mention that order of
+ local packages matters. (PR #208(8))
+
+ - Convert readthedocs link for their ‘.org’ -> ‘.io’ migration for
+ hosted projects (PR #239(9))
+
+ - Swaped order of ‘setup.py’ arguments for the upload command, as
+ order is significant. (PR #260(10))
+
+ - Explained how to install from unsupported sources using a helper
+ application. (PR #289(11))
+
+ ---------- Footnotes ----------
+
+ (1) https://github.com/pypa/packaging.python.org/pull/300
+
+ (2) https://github.com/pypa/packaging.python.org/pull/299
+
+ (3) https://github.com/pypa/packaging.python.org/pull/271
+
+ (4) https://github.com/pypa/packaging.python.org/pull/294
+
+ (5) https://github.com/pypa/packaging.python.org/pull/296
+
+ (6) https://github.com/pypa/packaging.python.org/pull/290
+
+ (7) https://github.com/pypa/packaging.python.org/pull/230
+
+ (8) https://github.com/pypa/packaging.python.org/pull/208
+
+ (9) https://github.com/pypa/packaging.python.org/pull/239
+
+ (10) https://github.com/pypa/packaging.python.org/pull/260
+
+ (11) https://github.com/pypa/packaging.python.org/pull/289
+
+
+File: pythonpackagingguide.info, Node: March 2017, Next: February 2017, Prev: April 2017, Up: News
+
+10.31 March 2017
+================
+
+ - Covered ‘manylinux1’ in `Platform Wheels'. (PR #283(1))
+
+ ---------- Footnotes ----------
+
+ (1) https://github.com/pypa/packaging.python.org/pull/283
+
+
+File: pythonpackagingguide.info, Node: February 2017, Prev: March 2017, Up: News
+
+10.32 February 2017
+===================
+
+ - Added PEP 518(1). (PR #281(2))
+
+Welcome to the `Python Packaging User Guide', a collection of tutorials
+and references to help you distribute and install Python packages with
+modern tools.
+
+This guide is maintained on GitHub(3) by the Python Packaging
+Authority(4). We happily accept any *note contributions and feedback:
+264. 😊
+
+ ---------- Footnotes ----------
+
+ (1) https://www.python.org/dev/peps/pep-0518
+
+ (2) https://github.com/pypa/packaging.python.org/pull/281
+
+ (3) https://github.com/pypa/python-packaging-user-guide
+
+ (4) https://pypa.io
+
+
+File: pythonpackagingguide.info, Node: Get started, Next: Learn more, Prev: News, Up: Top
+
+11 Get started
+**************
+
+Essential tools and concepts for working within the Python development
+ecosystem are covered in our *note Tutorials: 20. section:
+
+ * to learn how to install packages, see the *note tutorial on
+ installing packages: 23.
+
+ * to learn how to manage dependencies in a version controlled
+ project, see the *note tutorial on managing application
+ dependencies: 4a.
+
+ * to learn how to package and distribute your projects, see the *note
+ tutorial on packaging and distributing: e.
+
+ * to get an overview of packaging options for Python libraries and
+ applications, see the *note Overview of Python Packaging: 1.
+
+
+File: pythonpackagingguide.info, Node: Learn more, Next: Index, Prev: Get started, Up: Top
+
+12 Learn more
+*************
+
+Beyond our *note Tutorials: 20, this guide has several other resources:
+
+ * the *note Guides: 22. section for walk throughs, such as *note
+ Installing pip/setuptools/wheel with Linux Package Managers: 2c. or
+ *note Packaging binary extensions: 69.
+
+ * the *note Discussions: 17d. section for in-depth references on
+ topics such as *note Deploying Python applications: 180. or *note
+ pip vs easy_install: 189.
+
+ * the *note PyPA specifications: 195. section for packaging
+ interoperability specifications
+
+Additionally, there is a list of *note other projects: 213. maintained
+by members of the Python Packaging Authority.
+
+
+File: pythonpackagingguide.info, Node: Index, Prev: Learn more, Up: Top
+
+Index
+*****
+
+
+* Menu:
+
+* Binary Distribution: Glossary. (line 6)
+* Built Distribution: Glossary. (line 9)
+* Distribution Package: Glossary. (line 19)
+* Egg: Glossary. (line 34)
+* environment variable; PATH: Installing to the User Site.
+ (line 20)
+* environment variable; PATH <1>: Installing to the User Site.
+ (line 21)
+* environment variable; PATH <2>: Installing to the User Site.
+ (line 23)
+* Extension Module: Glossary. (line 41)
+* Import Package: Glossary. (line 58)
+* Known Good Set (KGS): Glossary. (line 50)
+* Module: Glossary. (line 68)
+* Package Index: Glossary. (line 73)
+* PATH: Installing to the User Site.
+ (line 20)
+* PATH <1>: Installing to the User Site.
+ (line 21)
+* PATH <2>: Installing to the User Site.
+ (line 23)
+* Per Project Index: Glossary. (line 78)
+* Project: Glossary. (line 84)
+* Pure Module: Glossary. (line 108)
+* pypi.org: Glossary. (line 127)
+* pyproject.toml: Glossary. (line 134)
+* Python Enhancement Proposals; PEP 1: History and change workflow.
+ (line 9)
+* Python Enhancement Proposals; PEP 301: Classifier multiple use.
+ (line 9)
+* Python Enhancement Proposals; PEP 345: Version specifiers. (line 10)
+* Python Enhancement Proposals; PEP 345 <1>: Dependency specifiers.
+ (line 10)
+* Python Enhancement Proposals; PEP 376: Wheel vs Egg. (line 33)
+* Python Enhancement Proposals; PEP 376 <1>: History and change workflow.
+ (line 6)
+* Python Enhancement Proposals; PEP 376 <2>: File format. (line 8)
+* Python Enhancement Proposals; PEP 397: console_scripts. (line 27)
+* Python Enhancement Proposals; PEP 420: Creating a namespace package.
+ (line 10)
+* Python Enhancement Proposals; PEP 420 <1>: Native namespace packages.
+ (line 6)
+* Python Enhancement Proposals; PEP 425: Pure Python Wheels. (line 17)
+* Python Enhancement Proposals; PEP 425 <1>: Platform Wheels. (line 16)
+* Python Enhancement Proposals; PEP 425 <2>: Wheel vs Egg. (line 36)
+* Python Enhancement Proposals; PEP 425 <3>: Platform compatibility tags.
+ (line 12)
+* Python Enhancement Proposals; PEP 425 <4>: Platform tags for Windows.
+ (line 6)
+* Python Enhancement Proposals; PEP 425 <5>: Platform tags for macOS Mac OS X.
+ (line 6)
+* Python Enhancement Proposals; PEP 425 <6>: Platform tags for common Linux distributions.
+ (line 6)
+* Python Enhancement Proposals; PEP 425 <7>: Platform tags for other *nix platforms.
+ (line 6)
+* Python Enhancement Proposals; PEP 427: Wheel vs Egg. (line 12)
+* Python Enhancement Proposals; PEP 427 <1>: Wheel vs Egg. (line 21)
+* Python Enhancement Proposals; PEP 427 <2>: Binary distribution format.
+ (line 6)
+* Python Enhancement Proposals; PEP 427 <3>: File format. (line 8)
+* Python Enhancement Proposals; PEP 427 <4>: Glossary. (line 214)
+* Python Enhancement Proposals; PEP 427#is-it-possible-to-import-python-code-directly-from-a-wheel-file: Wheel vs Egg.
+ (line 57)
+* Python Enhancement Proposals; PEP 438: pip vs easy_install. (line 37)
+* Python Enhancement Proposals; PEP 440: Installing from PyPI.
+ (line 9)
+* Python Enhancement Proposals; PEP 440 <1>: Installing from PyPI.
+ (line 40)
+* Python Enhancement Proposals; PEP 440 <2>: Creating setup py.
+ (line 49)
+* Python Enhancement Proposals; PEP 440 <3>: python_requires. (line 7)
+* Python Enhancement Proposals; PEP 440 <4>: Standards compliance for interoperability.
+ (line 8)
+* Python Enhancement Proposals; PEP 440 <5>: Standards compliance for interoperability.
+ (line 24)
+* Python Enhancement Proposals; PEP 440 <6>: Metadata-Version.
+ (line 14)
+* Python Enhancement Proposals; PEP 440 <7>: Version. (line 9)
+* Python Enhancement Proposals; PEP 440 <8>: Requires-External multiple use.
+ (line 22)
+* Python Enhancement Proposals; PEP 440 <9>: Version specifiers.
+ (line 7)
+* Python Enhancement Proposals; PEP 440 <10>: version<2>. (line 10)
+* Python Enhancement Proposals; PEP 440 <11>: Glossary. (line 200)
+* Python Enhancement Proposals; PEP 440#compatible-release: Installing from PyPI.
+ (line 25)
+* Python Enhancement Proposals; PEP 440#compatible-release <1>: Semantic versioning preferred.
+ (line 20)
+* Python Enhancement Proposals; PEP 440#local-version-identifiers: Local version identifiers.
+ (line 8)
+* Python Enhancement Proposals; PEP 440#normalization: Standards compliance for interoperability.
+ (line 24)
+* Python Enhancement Proposals; PEP 440#public-version-identifiers: Standards compliance for interoperability.
+ (line 8)
+* Python Enhancement Proposals; PEP 440#version-specifiers: Installing from PyPI.
+ (line 10)
+* Python Enhancement Proposals; PEP 440#version-specifiers <1>: Glossary.
+ (line 201)
+* Python Enhancement Proposals; PEP 441: shiv. (line 9)
+* Python Enhancement Proposals; PEP 453: Installation tool recommendations.
+ (line 30)
+* Python Enhancement Proposals; PEP 453 <1>: Installation tool recommendations.
+ (line 34)
+* Python Enhancement Proposals; PEP 453#rationale: Installation tool recommendations.
+ (line 33)
+* Python Enhancement Proposals; PEP 503: Installing from other sources.
+ (line 7)
+* Python Enhancement Proposals; PEP 503 <1>: name<2>. (line 12)
+* Python Enhancement Proposals; PEP 503 <2>: Simple repository API.
+ (line 7)
+* Python Enhancement Proposals; PEP 508: name. (line 9)
+* Python Enhancement Proposals; PEP 508 <1>: Name. (line 8)
+* Python Enhancement Proposals; PEP 508 <2>: Requires-Dist multiple use.
+ (line 30)
+* Python Enhancement Proposals; PEP 508 <3>: Dependency specifiers.
+ (line 7)
+* Python Enhancement Proposals; PEP 508 <4>: dependencies/optional-dependencies.
+ (line 6)
+* Python Enhancement Proposals; PEP 508 <5>: dependencies/optional-dependencies.
+ (line 7)
+* Python Enhancement Proposals; PEP 508 <6>: dependencies/optional-dependencies.
+ (line 17)
+* Python Enhancement Proposals; PEP 508 <7>: dependencies/optional-dependencies.
+ (line 22)
+* Python Enhancement Proposals; PEP 508 <8>: File format. (line 33)
+* Python Enhancement Proposals; PEP 513: Platform Wheels. (line 20)
+* Python Enhancement Proposals; PEP 513 <1>: Platform tags for common Linux distributions.
+ (line 11)
+* Python Enhancement Proposals; PEP 513 <2>: Platform tags for common Linux distributions.
+ (line 20)
+* Python Enhancement Proposals; PEP 517: Checking out the project and building distributions.
+ (line 21)
+* Python Enhancement Proposals; PEP 517 <1>: Source distribution format.
+ (line 7)
+* Python Enhancement Proposals; PEP 518: Checking out the project and building distributions.
+ (line 21)
+* Python Enhancement Proposals; PEP 518 <1>: Declaring build system dependencies.
+ (line 7)
+* Python Enhancement Proposals; PEP 518 <2>: Source distribution format.
+ (line 7)
+* Python Enhancement Proposals; PEP 518 <3>: Glossary. (line 92)
+* Python Enhancement Proposals; PEP 518 <4>: Glossary. (line 138)
+* Python Enhancement Proposals; PEP 518 <5>: February 2017. (line 6)
+* Python Enhancement Proposals; PEP 566: Core metadata specifications.
+ (line 6)
+* Python Enhancement Proposals; PEP 566 <1>: Core metadata specifications.
+ (line 21)
+* Python Enhancement Proposals; PEP 571: Platform tags for common Linux distributions.
+ (line 24)
+* Python Enhancement Proposals; PEP 592: Simple repository API.
+ (line 9)
+* Python Enhancement Proposals; PEP 599: Platform tags for common Linux distributions.
+ (line 28)
+* Python Enhancement Proposals; PEP 621: Declaring project metadata.
+ (line 6)
+* Python Enhancement Proposals; PEP 627: History and change workflow.
+ (line 7)
+* Python Package Index (PyPI): Glossary. (line 121)
+* Python Packaging Authority (PyPA): Glossary. (line 113)
+* Release: Glossary. (line 138)
+* Requirement: Glossary. (line 148)
+* Requirement Specifier: Glossary. (line 155)
+* Requirements File: Glossary. (line 164)
+* setup.cfg: Glossary. (line 173)
+* setup.py: Glossary. (line 170)
+* Source Archive: Glossary. (line 177)
+* Source Distribution (or "sdist"): Glossary. (line 183)
+* System Package: Glossary. (line 190)
+* Version Specifier: Glossary. (line 195)
+* Virtual Environment: Glossary. (line 203)
+* Wheel: Glossary. (line 210)
+* Working Set: Glossary. (line 216)
+
+
+
+Tag Table:
+Node: Top410
+Ref: index doc689
+Ref: 0689
+Node: An Overview of Packaging for Python14966
+Ref: overview doc15085
+Ref: 115085
+Ref: overview an-overview-of-packaging-for-python15085
+Ref: 215085
+Ref: overview python-packaging-user-guide15085
+Ref: 315085
+Node: Thinking about deployment16018
+Ref: overview thinking-about-deployment16174
+Ref: 416174
+Node: Packaging Python libraries and tools17105
+Ref: overview packaging-python-libraries-and-tools17299
+Ref: 517299
+Node: Python modules18015
+Ref: overview python-modules18152
+Ref: 818152
+Ref: Python modules-Footnote-118896
+Ref: Python modules-Footnote-218935
+Node: Python source distributions19015
+Ref: overview python-source-distributions19188
+Ref: 919188
+Ref: Python source distributions-Footnote-121021
+Ref: Python source distributions-Footnote-221081
+Ref: Python source distributions-Footnote-321127
+Ref: Python source distributions-Footnote-421166
+Ref: Python source distributions-Footnote-521205
+Ref: Python source distributions-Footnote-621243
+Node: Python binary distributions21284
+Ref: overview python-binary-distributions21434
+Ref: c21434
+Ref: Python binary distributions-Footnote-122899
+Node: Packaging Python applications22951
+Ref: overview packaging-applications23133
+Ref: 723133
+Ref: overview packaging-python-applications23133
+Ref: f23133
+Ref: Packaging Python applications-Footnote-124504
+Node: Depending on a framework24584
+Ref: overview depending-on-a-framework24732
+Ref: 1024732
+Node: Service platforms25669
+Ref: overview service-platforms25806
+Ref: 1125806
+Ref: Service platforms-Footnote-126559
+Ref: Service platforms-Footnote-226633
+Ref: Service platforms-Footnote-326689
+Ref: Service platforms-Footnote-426729
+Ref: Service platforms-Footnote-526788
+Node: Web browsers and mobile applications26818
+Ref: overview web-browsers-and-mobile-applications26955
+Ref: 1226955
+Ref: Web browsers and mobile applications-Footnote-127705
+Ref: Web browsers and mobile applications-Footnote-227736
+Ref: Web browsers and mobile applications-Footnote-327763
+Ref: Web browsers and mobile applications-Footnote-427793
+Node: Depending on a pre-installed Python27840
+Ref: overview depending-on-a-pre-installed-python28052
+Ref: 1328052
+Ref: Depending on a pre-installed Python-Footnote-129110
+Ref: Depending on a pre-installed Python-Footnote-229156
+Ref: Depending on a pre-installed Python-Footnote-329210
+Node: Depending on a separate software distribution ecosystem29256
+Ref: overview depending-on-a-separate-ecosystem29479
+Ref: 1429479
+Ref: overview depending-on-a-separate-software-distribution-ecosystem29479
+Ref: 1529479
+Ref: Depending on a separate software distribution ecosystem-Footnote-130693
+Ref: Depending on a separate software distribution ecosystem-Footnote-230718
+Ref: Depending on a separate software distribution ecosystem-Footnote-330787
+Ref: Depending on a separate software distribution ecosystem-Footnote-430870
+Ref: Depending on a separate software distribution ecosystem-Footnote-530932
+Ref: Depending on a separate software distribution ecosystem-Footnote-631009
+Ref: Depending on a separate software distribution ecosystem-Footnote-731059
+Ref: Depending on a separate software distribution ecosystem-Footnote-831108
+Node: Bringing your own Python executable31144
+Ref: overview bringing-your-own-python31359
+Ref: 1631359
+Ref: overview bringing-your-own-python-executable31359
+Ref: 1731359
+Ref: Bringing your own Python executable-Footnote-132475
+Ref: Bringing your own Python executable-Footnote-232511
+Ref: Bringing your own Python executable-Footnote-332563
+Ref: Bringing your own Python executable-Footnote-432608
+Ref: Bringing your own Python executable-Footnote-532639
+Ref: Bringing your own Python executable-Footnote-632688
+Ref: Bringing your own Python executable-Footnote-732730
+Ref: Bringing your own Python executable-Footnote-832773
+Ref: Bringing your own Python executable-Footnote-932815
+Node: Bringing your own userspace32864
+Ref: overview bringing-your-own-userspace33048
+Ref: 1833048
+Ref: Bringing your own userspace-Footnote-133751
+Ref: Bringing your own userspace-Footnote-233828
+Ref: Bringing your own userspace-Footnote-333858
+Ref: Bringing your own userspace-Footnote-433910
+Ref: Bringing your own userspace-Footnote-533939
+Node: Bringing your own kernel33969
+Ref: overview bringing-your-own-kernel34144
+Ref: 1934144
+Ref: Bringing your own kernel-Footnote-134856
+Ref: Bringing your own kernel-Footnote-234891
+Ref: Bringing your own kernel-Footnote-334947
+Ref: Bringing your own kernel-Footnote-435006
+Ref: Bringing your own kernel-Footnote-535072
+Node: Bringing your own hardware35123
+Ref: overview bringing-your-own-hardware35262
+Ref: 1a35262
+Ref: Bringing your own hardware-Footnote-136092
+Ref: Bringing your own hardware-Footnote-236165
+Node: What about…36198
+Ref: overview what-about36351
+Ref: 1b36351
+Node: Operating system packages36570
+Ref: overview operating-system-packages36678
+Ref: 1c36678
+Ref: Operating system packages-Footnote-137364
+Ref: Operating system packages-Footnote-237420
+Ref: Operating system packages-Footnote-337478
+Node: virtualenv37546
+Ref: overview virtualenv37671
+Ref: 1d37671
+Ref: virtualenv-Footnote-138291
+Ref: virtualenv-Footnote-238361
+Ref: virtualenv-Footnote-338426
+Node: Security38469
+Ref: overview security38560
+Ref: 1e38560
+Ref: Security-Footnote-139178
+Node: Wrap up39256
+Ref: overview wrap-up39371
+Ref: 1f39371
+Node: Tutorials39761
+Ref: tutorials/index doc39883
+Ref: 2039883
+Ref: tutorials/index tutorials39883
+Ref: 2139883
+Node: Installing Packages40219
+Ref: tutorials/installing-packages doc40340
+Ref: 2340340
+Ref: tutorials/installing-packages id140340
+Ref: 2440340
+Ref: tutorials/installing-packages installing-packages40340
+Ref: 2540340
+Node: Requirements for Installing Packages41523
+Ref: tutorials/installing-packages installing-requirements41667
+Ref: 2641667
+Ref: tutorials/installing-packages requirements-for-installing-packages41667
+Ref: 2741667
+Node: Ensure you can run Python from the command line42135
+Ref: tutorials/installing-packages ensure-you-can-run-python-from-the-command-line42322
+Ref: 2842322
+Ref: Ensure you can run Python from the command line-Footnote-144601
+Ref: Ensure you can run Python from the command line-Footnote-244628
+Ref: Ensure you can run Python from the command line-Footnote-344698
+Node: Ensure you can run pip from the command line44804
+Ref: tutorials/installing-packages ensure-you-can-run-pip-from-the-command-line45046
+Ref: 2945046
+Ref: tutorials/installing-packages python-org45046
+Ref: 2a45046
+Ref: Ensure you can run pip from the command line-Footnote-146545
+Ref: Ensure you can run pip from the command line-Footnote-246572
+Ref: Ensure you can run pip from the command line-Footnote-346596
+Ref: Ensure you can run pip from the command line-Footnote-446641
+Ref: Ensure you can run pip from the command line-Footnote-546802
+Node: Ensure pip setuptools and wheel are up to date47032
+Ref: tutorials/installing-packages ensure-pip-setuptools-and-wheel-are-up-to-date47266
+Ref: 2f47266
+Node: Optionally create a virtual environment47651
+Ref: tutorials/installing-packages optionally-create-a-virtual-environment47832
+Ref: 3047832
+Ref: Optionally create a virtual environment-Footnote-148327
+Ref: Optionally create a virtual environment-Footnote-248379
+Node: Creating Virtual Environments48607
+Ref: tutorials/installing-packages creating-and-using-virtual-environments48782
+Ref: 3148782
+Ref: tutorials/installing-packages creating-virtual-environments48782
+Ref: 3348782
+Ref: Creating Virtual Environments-Footnote-151559
+Ref: Creating Virtual Environments-Footnote-251611
+Ref: Creating Virtual Environments-Footnote-351663
+Ref: Creating Virtual Environments-Footnote-451715
+Node: Use pip for Installing51749
+Ref: tutorials/installing-packages use-pip-for-installing51908
+Ref: 3751908
+Ref: Use pip for Installing-Footnote-152189
+Ref: Use pip for Installing-Footnote-252217
+Node: Installing from PyPI52276
+Ref: tutorials/installing-packages installing-from-pypi52436
+Ref: 3852436
+Ref: Installing from PyPI-Footnote-153382
+Ref: Installing from PyPI-Footnote-253431
+Ref: Installing from PyPI-Footnote-353499
+Ref: Installing from PyPI-Footnote-453567
+Node: Source Distributions vs Wheels53758
+Ref: tutorials/installing-packages source-distributions-vs-wheels53914
+Ref: 3c53914
+Node: Upgrading packages54551
+Ref: tutorials/installing-packages upgrading-packages54714
+Ref: 3e54714
+Node: Installing to the User Site54878
+Ref: tutorials/installing-packages id655029
+Ref: 3f55029
+Ref: tutorials/installing-packages installing-to-the-user-site55029
+Ref: 4055029
+Ref: Installing to the User Site-Footnote-156924
+Ref: Installing to the User Site-Footnote-257000
+Ref: Installing to the User Site-Footnote-357067
+Ref: Installing to the User Site-Footnote-457112
+Node: Requirements files57201
+Ref: tutorials/installing-packages control-panel57353
+Ref: 4157353
+Ref: tutorials/installing-packages requirements-files57353
+Ref: 4257353
+Ref: Requirements files-Footnote-157547
+Node: Installing from VCS57616
+Ref: tutorials/installing-packages installing-from-vcs57770
+Ref: 4357770
+Ref: Installing from VCS-Footnote-158359
+Node: Installing from other Indexes58432
+Ref: tutorials/installing-packages installing-from-other-indexes58600
+Ref: 4458600
+Node: Installing from a local src tree58934
+Ref: tutorials/installing-packages installing-from-a-local-src-tree59113
+Ref: 4559113
+Ref: Installing from a local src tree-Footnote-159481
+Node: Installing from local archives59567
+Ref: tutorials/installing-packages installing-from-local-archives59746
+Ref: 4659746
+Node: Installing from other sources60214
+Ref: tutorials/installing-packages installing-from-other-sources60383
+Ref: 4760383
+Ref: Installing from other sources-Footnote-160833
+Node: Installing Prereleases60882
+Ref: tutorials/installing-packages installing-prereleases61055
+Ref: 4861055
+Node: Installing Setuptools “Extras”61273
+Ref: tutorials/installing-packages installing-setuptools-extras61408
+Ref: 4961408
+Ref: Installing Setuptools “Extras”-Footnote-161777
+Node: Managing Application Dependencies61909
+Ref: tutorials/managing-dependencies doc62064
+Ref: 4a62064
+Ref: tutorials/managing-dependencies managing-application-dependencies62064
+Ref: 4b62064
+Ref: tutorials/managing-dependencies managing-dependencies62064
+Ref: 3562064
+Ref: tutorials/managing-dependencies setuptools-extras62064
+Ref: 4c62064
+Ref: Managing Application Dependencies-Footnote-163547
+Node: Installing Pipenv63595
+Ref: tutorials/managing-dependencies installing-pipenv63741
+Ref: 4d63741
+Ref: tutorials/managing-dependencies pipenv-user-base64233
+Ref: 4e64233
+Ref: Installing Pipenv-Footnote-164594
+Ref: Installing Pipenv-Footnote-264625
+Ref: Installing Pipenv-Footnote-364652
+Ref: Installing Pipenv-Footnote-464716
+Node: Installing packages for your project64783
+Ref: tutorials/managing-dependencies installing-packages-for-your-project64962
+Ref: 4f64962
+Ref: tutorials/managing-dependencies user-installation64962
+Ref: 5064962
+Ref: Installing packages for your project-Footnote-166897
+Node: Using installed packages66940
+Ref: tutorials/managing-dependencies requests67112
+Ref: 5267112
+Ref: tutorials/managing-dependencies using-installed-packages67112
+Ref: 5367112
+Node: Next steps67778
+Ref: tutorials/managing-dependencies next-steps67963
+Ref: 5467963
+Node: Other Tools for Application Dependency Management68579
+Ref: tutorials/managing-dependencies other-dependency-management-tools68731
+Ref: 5668731
+Ref: tutorials/managing-dependencies other-tools-for-application-dependency-management68731
+Ref: 5768731
+Ref: Other Tools for Application Dependency Management-Footnote-170156
+Ref: Other Tools for Application Dependency Management-Footnote-270204
+Ref: Other Tools for Application Dependency Management-Footnote-370242
+Ref: Other Tools for Application Dependency Management-Footnote-470288
+Node: Packaging Python Projects70341
+Ref: tutorials/packaging-projects doc70499
+Ref: e70499
+Ref: tutorials/packaging-projects packaging-python-projects70499
+Ref: 5870499
+Node: A simple project71137
+Ref: tutorials/packaging-projects a-simple-project71264
+Ref: 5971264
+Ref: A simple project-Footnote-172179
+Node: Creating the package files72244
+Ref: tutorials/packaging-projects creating-the-package-files72402
+Ref: 5a72402
+Ref: tutorials/packaging-projects python-documentation-for-packages-and-modules72402
+Ref: 5b72402
+Node: Creating a test folder72888
+Ref: tutorials/packaging-projects creating-a-test-folder73047
+Ref: 5c73047
+Node: Creating setup py73183
+Ref: tutorials/packaging-projects creating-setup-py73334
+Ref: 5d73334
+Ref: Creating setup py-Footnote-177052
+Node: Creating README md77101
+Ref: tutorials/packaging-projects creating-readme-md77248
+Ref: 5e77248
+Node: Creating a LICENSE77587
+Ref: tutorials/packaging-projects creating-a-license77749
+Ref: 5f77749
+Node: Generating distribution archives79339
+Ref: tutorials/packaging-projects generating-archives79518
+Ref: 6079518
+Ref: tutorials/packaging-projects generating-distribution-archives79518
+Ref: 6179518
+Ref: Generating distribution archives-Footnote-181064
+Node: Uploading the distribution archives81180
+Ref: tutorials/packaging-projects uploading-the-distribution-archives81379
+Ref: 6481379
+Ref: Uploading the distribution archives-Footnote-183677
+Ref: Uploading the distribution archives-Footnote-283722
+Node: Installing your newly uploaded package83767
+Ref: tutorials/packaging-projects installing-your-newly-uploaded-package83947
+Ref: 6783947
+Node: Next steps<2>85733
+Ref: tutorials/packaging-projects next-steps85869
+Ref: 6885869
+Ref: Next steps<2>-Footnote-187572
+Ref: Next steps<2>-Footnote-287610
+Node: Creating Documentation87658
+Ref: tutorials/creating-documentation doc87774
+Ref: 6b87774
+Ref: tutorials/creating-documentation creating-documentation87774
+Ref: 6c87774
+Ref: tutorials/creating-documentation id187774
+Ref: 6d87774
+Ref: tutorials/creating-documentation poetry87774
+Ref: 6e87774
+Ref: Creating Documentation-Footnote-188083
+Ref: Creating Documentation-Footnote-288114
+Node: Installing Sphinx88147
+Ref: tutorials/creating-documentation installing-sphinx88273
+Ref: 6f88273
+Ref: tutorials/creating-documentation read-the-docs88273
+Ref: 7088273
+Ref: Installing Sphinx-Footnote-188495
+Node: Getting Started With Sphinx88563
+Ref: tutorials/creating-documentation getting-started-with-sphinx88711
+Ref: 7188711
+Ref: tutorials/creating-documentation installation-guide88711
+Ref: 7288711
+Ref: Getting Started With Sphinx-Footnote-189362
+Node: Other Sources89432
+Ref: tutorials/creating-documentation guide89554
+Ref: 7389554
+Ref: tutorials/creating-documentation other-sources89554
+Ref: 7489554
+Ref: Other Sources-Footnote-189778
+Node: Guides89839
+Ref: guides/index doc89937
+Ref: 2289937
+Ref: guides/index documentation-tutorial89937
+Ref: 7589937
+Ref: guides/index guides89937
+Ref: 7689937
+Node: Tool recommendations91174
+Ref: guides/tool-recommendations doc91314
+Ref: 7791314
+Ref: guides/tool-recommendations id191314
+Ref: 7891314
+Ref: guides/tool-recommendations tool-recommendations91314
+Ref: 7991314
+Node: Application dependency management91659
+Ref: guides/tool-recommendations application-dependency-management91805
+Ref: 7a91805
+Ref: Application dependency management-Footnote-192234
+Ref: Application dependency management-Footnote-292280
+Node: Installation tool recommendations92315
+Ref: guides/tool-recommendations installation-tool-recommendations92500
+Ref: 7b92500
+Ref: Installation tool recommendations-Footnote-193318
+Ref: Installation tool recommendations-Footnote-293573
+Ref: Installation tool recommendations-Footnote-393918
+Ref: Installation tool recommendations-Footnote-494244
+Ref: Installation tool recommendations-Footnote-594296
+Node: Packaging tool recommendations94583
+Ref: guides/tool-recommendations packaging-tool-recommendations94764
+Ref: 8494764
+Ref: Packaging tool recommendations-Footnote-195275
+Ref: Packaging tool recommendations-Footnote-296105
+Ref: Packaging tool recommendations-Footnote-396306
+Node: Publishing platform migration96345
+Ref: guides/tool-recommendations publishing-platform-migration96484
+Ref: 8696484
+Ref: Publishing platform migration-Footnote-196971
+Ref: Publishing platform migration-Footnote-297003
+Node: Installing packages using pip and virtual environments97028
+Ref: guides/installing-using-pip-and-virtual-environments doc97218
+Ref: 8897218
+Ref: guides/installing-using-pip-and-virtual-environments installing-packages-using-pip-and-virtual-environments97218
+Ref: 8997218
+Ref: guides/installing-using-pip-and-virtual-environments venv97218
+Ref: 8a97218
+Node: Installing pip98378
+Ref: guides/installing-using-pip-and-virtual-environments installing-pip98527
+Ref: 8b98527
+Node: Windows98788
+Ref: guides/installing-using-pip-and-virtual-environments windows98884
+Ref: 8c98884
+Node: Linux and macOS99189
+Ref: guides/installing-using-pip-and-virtual-environments linux-and-macos99285
+Ref: 8d99285
+Ref: Linux and macOS-Footnote-199966
+Node: Installing virtualenv100020
+Ref: guides/installing-using-pip-and-virtual-environments installing-virtualenv100208
+Ref: 8e100208
+Ref: guides/installing-using-pip-and-virtual-environments python-pip100208
+Ref: 8f100208
+Ref: Installing virtualenv-Footnote-1100962
+Node: Creating a virtual environment101026
+Ref: guides/installing-using-pip-and-virtual-environments creating-a-virtual-environment101232
+Ref: 90101232
+Node: Activating a virtual environment102458
+Ref: guides/installing-using-pip-and-virtual-environments activating-a-virtual-environment102674
+Ref: 91102674
+Node: Leaving the virtual environment103561
+Ref: guides/installing-using-pip-and-virtual-environments leaving-the-virtual-environment103766
+Ref: 92103766
+Node: Installing packages104135
+Ref: guides/installing-using-pip-and-virtual-environments installing-packages104336
+Ref: 93104336
+Ref: Installing packages-Footnote-1105377
+Node: Installing specific versions105420
+Ref: guides/installing-using-pip-and-virtual-environments installing-specific-versions105607
+Ref: 94105607
+Ref: guides/installing-using-pip-and-virtual-environments requests105607
+Ref: 95105607
+Node: Installing extras106077
+Ref: guides/installing-using-pip-and-virtual-environments installing-extras106267
+Ref: 96106267
+Ref: Installing extras-Footnote-1106501
+Node: Installing from source106633
+Ref: guides/installing-using-pip-and-virtual-environments extras106834
+Ref: 97106834
+Ref: guides/installing-using-pip-and-virtual-environments installing-from-source106834
+Ref: 98106834
+Ref: Installing from source-Footnote-1107260
+Node: Installing from version control systems107346
+Ref: guides/installing-using-pip-and-virtual-environments development-mode107563
+Ref: 99107563
+Ref: guides/installing-using-pip-and-virtual-environments installing-from-version-control-systems107563
+Ref: 9a107563
+Ref: Installing from version control systems-Footnote-1108037
+Node: Installing from local archives<2>108110
+Ref: guides/installing-using-pip-and-virtual-environments installing-from-local-archives108332
+Ref: 9b108332
+Node: Using other package indexes108987
+Ref: guides/installing-using-pip-and-virtual-environments using-other-package-indexes109191
+Ref: 9c109191
+Node: Upgrading packages<2>109723
+Ref: guides/installing-using-pip-and-virtual-environments upgrading-packages109918
+Ref: 9d109918
+Node: Using requirements files110166
+Ref: guides/installing-using-pip-and-virtual-environments using-requirements-files110355
+Ref: 9e110355
+Ref: Using requirements files-Footnote-1110812
+Node: Freezing dependencies110881
+Ref: guides/installing-using-pip-and-virtual-environments freezing-dependencies111040
+Ref: 9f111040
+Ref: Freezing dependencies-Footnote-1111672
+Node: Installing stand alone command line tools111741
+Ref: guides/installing-stand-alone-command-line-tools doc111970
+Ref: 34111970
+Ref: guides/installing-stand-alone-command-line-tools installing-stand-alone-command-line-tools111970
+Ref: a0111970
+Ref: Installing stand alone command line tools-Footnote-1114827
+Ref: Installing stand alone command line tools-Footnote-2114866
+Ref: Installing stand alone command line tools-Footnote-3114906
+Ref: Installing stand alone command line tools-Footnote-4114945
+Ref: Installing stand alone command line tools-Footnote-5114983
+Node: Installing pip/setuptools/wheel with Linux Package Managers115027
+Ref: guides/installing-using-linux-tools doc115232
+Ref: 2c115232
+Ref: guides/installing-using-linux-tools id1115232
+Ref: a1115232
+Ref: guides/installing-using-linux-tools installing-pip-setuptools-wheel-with-linux-package-managers115232
+Ref: a2115232
+Ref: Installing pip/setuptools/wheel with Linux Package Managers-Footnote-1116583
+Node: Fedora116614
+Ref: guides/installing-using-linux-tools fedora116750
+Ref: a3116750
+Ref: Fedora-Footnote-1117485
+Ref: Fedora-Footnote-2117541
+Node: CentOS/RHEL117600
+Ref: guides/installing-using-linux-tools centos-rhel117753
+Ref: a4117753
+Ref: CentOS/RHEL-Footnote-1119513
+Ref: CentOS/RHEL-Footnote-2119557
+Ref: CentOS/RHEL-Footnote-3119640
+Ref: CentOS/RHEL-Footnote-4119696
+Ref: CentOS/RHEL-Footnote-5119755
+Ref: CentOS/RHEL-Footnote-6119908
+Ref: CentOS/RHEL-Footnote-7119947
+Node: openSUSE120009
+Ref: guides/installing-using-linux-tools opensuse120169
+Ref: a5120169
+Node: Debian/Ubuntu120381
+Ref: guides/installing-using-linux-tools debian-ubuntu120540
+Ref: a6120540
+Ref: Debian/Ubuntu-Footnote-1120931
+Node: Arch Linux120995
+Ref: guides/installing-using-linux-tools arch-linux121137
+Ref: a7121137
+Node: Installing scientific packages121347
+Ref: guides/installing-scientific-packages doc121533
+Ref: a8121533
+Ref: guides/installing-scientific-packages installing-scientific-packages121533
+Ref: a9121533
+Ref: guides/installing-scientific-packages numpy-and-the-science-stack121533
+Ref: aa121533
+Ref: Installing scientific packages-Footnote-1122992
+Ref: Installing scientific packages-Footnote-2123022
+Ref: Installing scientific packages-Footnote-3123076
+Node: Building from source123113
+Ref: guides/installing-scientific-packages building-from-source123250
+Ref: ab123250
+Node: Linux distribution packages123649
+Ref: guides/installing-scientific-packages linux-distribution-packages123813
+Ref: ac123813
+Node: Windows installers124293
+Ref: guides/installing-scientific-packages windows-installers124474
+Ref: ad124474
+Ref: Windows installers-Footnote-1125725
+Node: macOS installers and package managers125776
+Ref: guides/installing-scientific-packages mac-os-x-installers-and-package-managers125949
+Ref: ae125949
+Ref: guides/installing-scientific-packages macos-installers-and-package-managers125949
+Ref: af125949
+Ref: macOS installers and package managers-Footnote-1126438
+Node: SciPy distributions126493
+Ref: guides/installing-scientific-packages scipy-distributions126653
+Ref: b0126653
+Ref: SciPy distributions-Footnote-1126990
+Node: Spack127032
+Ref: guides/installing-scientific-packages spack127195
+Ref: b1127195
+Ref: Spack-Footnote-1128241
+Node: The conda cross-platform package manager128280
+Ref: guides/installing-scientific-packages the-conda-cross-platform-package-manager128415
+Ref: b2128415
+Ref: The conda cross-platform package manager-Footnote-1129771
+Node: Multi-version installs129814
+Ref: guides/multi-version-installs doc129976
+Ref: b3129976
+Ref: guides/multi-version-installs id1129976
+Ref: b4129976
+Ref: guides/multi-version-installs multi-version-installs129976
+Ref: b5129976
+Ref: Multi-version installs-Footnote-1131886
+Node: Packaging and distributing projects131977
+Ref: guides/distributing-packages-using-setuptools doc132165
+Ref: 6132165
+Ref: guides/distributing-packages-using-setuptools distributing-packages132165
+Ref: 55132165
+Ref: guides/distributing-packages-using-setuptools packaging-and-distributing-projects132165
+Ref: b6132165
+Ref: Packaging and distributing projects-Footnote-1133133
+Node: Requirements for packaging and distributing133201
+Ref: guides/distributing-packages-using-setuptools requirements-for-packaging-and-distributing133363
+Ref: b7133363
+Ref: Requirements for packaging and distributing-Footnote-1133787
+Node: Configuring your project134017
+Ref: guides/distributing-packages-using-setuptools configuring-your-project134221
+Ref: b9134221
+Node: Initial files134373
+Ref: guides/distributing-packages-using-setuptools initial-files134480
+Ref: ba134480
+Node: setup py134706
+Ref: guides/distributing-packages-using-setuptools setup-py134796
+Ref: bb134796
+Ref: setup py-Footnote-1135627
+Ref: setup py-Footnote-2135694
+Node: setup cfg135740
+Ref: guides/distributing-packages-using-setuptools setup-cfg135861
+Ref: bd135861
+Ref: setup cfg-Footnote-1136094
+Ref: setup cfg-Footnote-2136162
+Node: README rst / README md136208
+Ref: guides/distributing-packages-using-setuptools readme-rst-readme-md136332
+Ref: be136332
+Ref: README rst / README md-Footnote-1137349
+Ref: README rst / README md-Footnote-2137398
+Ref: README rst / README md-Footnote-3137452
+Ref: README rst / README md-Footnote-4137520
+Node: MANIFEST in137566
+Ref: guides/distributing-packages-using-setuptools manifest-in137692
+Ref: c1137692
+Ref: MANIFEST in-Footnote-1138244
+Ref: MANIFEST in-Footnote-2138314
+Node: LICENSE txt138360
+Ref: guides/distributing-packages-using-setuptools license-txt138478
+Ref: c3138478
+Ref: LICENSE txt-Footnote-1138980
+Ref: LICENSE txt-Footnote-2139016
+Ref: LICENSE txt-Footnote-3139086
+Node: <your package>139132
+Ref: guides/distributing-packages-using-setuptools your-package139230
+Ref: c4139230
+Ref: <your package>-Footnote-1139617
+Ref: <your package>-Footnote-2139686
+Node: setup args139732
+Ref: guides/distributing-packages-using-setuptools id11139876
+Ref: c6139876
+Ref: guides/distributing-packages-using-setuptools setup-args139876
+Ref: bc139876
+Ref: setup args-Footnote-1140565
+Ref: setup args-Footnote-2140632
+Node: name140678
+Ref: guides/distributing-packages-using-setuptools name140759
+Ref: c7140759
+Ref: guides/distributing-packages-using-setuptools setup-name140759
+Ref: c5140759
+Ref: name-Footnote-1141518
+Node: version141567
+Ref: guides/distributing-packages-using-setuptools version141668
+Ref: c8141668
+Node: description142476
+Ref: guides/distributing-packages-using-setuptools description142576
+Ref: bf142576
+Ref: guides/distributing-packages-using-setuptools id14142576
+Ref: cb142576
+Ref: description-Footnote-1143722
+Ref: description-Footnote-2143824
+Ref: description-Footnote-3143916
+Node: url143970
+Ref: guides/distributing-packages-using-setuptools url144069
+Ref: cc144069
+Node: author144186
+Ref: guides/distributing-packages-using-setuptools author144281
+Ref: cd144281
+Node: license144425
+Ref: guides/distributing-packages-using-setuptools license144528
+Ref: ce144528
+Node: classifiers145245
+Ref: guides/distributing-packages-using-setuptools classifiers145350
+Ref: cf145350
+Node: keywords146829
+Ref: guides/distributing-packages-using-setuptools keywords146939
+Ref: d1146939
+Node: project_urls147067
+Ref: guides/distributing-packages-using-setuptools project-urls147174
+Ref: d2147174
+Node: packages147803
+Ref: guides/distributing-packages-using-setuptools packages147912
+Ref: d3147912
+Node: py_modules148423
+Ref: guides/distributing-packages-using-setuptools py-modules148536
+Ref: d4148536
+Node: install_requires148838
+Ref: guides/distributing-packages-using-setuptools install-requires148958
+Ref: d5148958
+Node: python_requires149365
+Ref: guides/distributing-packages-using-setuptools id16149487
+Ref: d7149487
+Ref: guides/distributing-packages-using-setuptools python-requires149487
+Ref: d0149487
+Ref: python_requires-Footnote-1150847
+Node: package_data150896
+Ref: guides/distributing-packages-using-setuptools id17151012
+Ref: d9151012
+Ref: guides/distributing-packages-using-setuptools package-data151012
+Ref: da151012
+Ref: package_data-Footnote-1151744
+Ref: package_data-Footnote-2151834
+Node: data_files151876
+Ref: guides/distributing-packages-using-setuptools data-files151984
+Ref: db151984
+Ref: guides/distributing-packages-using-setuptools id18151984
+Ref: dc151984
+Ref: data_files-Footnote-1153365
+Ref: data_files-Footnote-2153413
+Node: scripts153502
+Ref: guides/distributing-packages-using-setuptools scripts153610
+Ref: dd153610
+Ref: scripts-Footnote-1153908
+Node: entry_points153988
+Ref: guides/distributing-packages-using-setuptools entry-points154077
+Ref: df154077
+Ref: entry_points-Footnote-1154566
+Node: console_scripts154688
+Ref: guides/distributing-packages-using-setuptools console-scripts154766
+Ref: de154766
+Ref: guides/distributing-packages-using-setuptools id20154766
+Ref: e0154766
+Ref: console_scripts-Footnote-1155303
+Ref: console_scripts-Footnote-2155414
+Ref: console_scripts-Footnote-3155758
+Ref: console_scripts-Footnote-4155853
+Node: Choosing a versioning scheme155895
+Ref: guides/distributing-packages-using-setuptools choosing-a-versioning-scheme156017
+Ref: c9156017
+Ref: guides/distributing-packages-using-setuptools id24156017
+Ref: e1156017
+Node: Standards compliance for interoperability156226
+Ref: guides/distributing-packages-using-setuptools standards-compliance-for-interoperability156369
+Ref: e2156369
+Ref: Standards compliance for interoperability-Footnote-1157395
+Ref: Standards compliance for interoperability-Footnote-2157472
+Ref: Standards compliance for interoperability-Footnote-3157521
+Ref: Standards compliance for interoperability-Footnote-4157570
+Node: Scheme choices157633
+Ref: guides/distributing-packages-using-setuptools scheme-choices157807
+Ref: e3157807
+Node: Semantic versioning preferred157999
+Ref: guides/distributing-packages-using-setuptools semantic-versioning-preferred158123
+Ref: e4158123
+Ref: Semantic versioning preferred-Footnote-1159117
+Ref: Semantic versioning preferred-Footnote-2159143
+Ref: Semantic versioning preferred-Footnote-3159211
+Node: Date based versioning159237
+Ref: guides/distributing-packages-using-setuptools date-based-versioning159387
+Ref: e5159387
+Node: Serial versioning159962
+Ref: guides/distributing-packages-using-setuptools serial-versioning160097
+Ref: e6160097
+Node: Hybrid schemes160474
+Ref: guides/distributing-packages-using-setuptools hybrid-schemes160579
+Ref: e7160579
+Node: Pre-release versioning160934
+Ref: guides/distributing-packages-using-setuptools pre-release-versioning161092
+Ref: e8161092
+Node: Local version identifiers161678
+Ref: guides/distributing-packages-using-setuptools local-version-identifiers161813
+Ref: e9161813
+Ref: Local version identifiers-Footnote-1162530
+Node: Working in “development mode”162606
+Ref: guides/distributing-packages-using-setuptools working-in-development-mode162789
+Ref: ea162789
+Ref: Working in “development mode”-Footnote-1164811
+Ref: Working in “development mode”-Footnote-2164880
+Ref: Working in “development mode”-Footnote-3164953
+Ref: Working in “development mode”-Footnote-4165039
+Node: Packaging your project165081
+Ref: guides/distributing-packages-using-setuptools id26165270
+Ref: eb165270
+Ref: guides/distributing-packages-using-setuptools packaging-your-project165270
+Ref: d8165270
+Node: Source distributions165559
+Ref: guides/distributing-packages-using-setuptools source-distributions165667
+Ref: ed165667
+Node: Wheels166122
+Ref: guides/distributing-packages-using-setuptools wheels166230
+Ref: ee166230
+Node: Universal Wheels167239
+Ref: guides/distributing-packages-using-setuptools id27167339
+Ref: f2167339
+Ref: guides/distributing-packages-using-setuptools universal-wheels167339
+Ref: ef167339
+Node: Pure Python Wheels168276
+Ref: guides/distributing-packages-using-setuptools id28168400
+Ref: f3168400
+Ref: guides/distributing-packages-using-setuptools pure-python-wheels168400
+Ref: f0168400
+Ref: Pure Python Wheels-Footnote-1169245
+Ref: Pure Python Wheels-Footnote-2169294
+Node: Platform Wheels169346
+Ref: guides/distributing-packages-using-setuptools id29169445
+Ref: f4169445
+Ref: guides/distributing-packages-using-setuptools platform-wheels169445
+Ref: f1169445
+Ref: Platform Wheels-Footnote-1170153
+Ref: Platform Wheels-Footnote-2170202
+Node: Uploading your Project to PyPI170251
+Ref: guides/distributing-packages-using-setuptools id30170398
+Ref: f5170398
+Ref: guides/distributing-packages-using-setuptools uploading-your-project-to-pypi170398
+Ref: b8170398
+Ref: Uploading your Project to PyPI-Footnote-1172215
+Ref: Uploading your Project to PyPI-Footnote-2172246
+Node: Create an account172294
+Ref: guides/distributing-packages-using-setuptools create-an-account172426
+Ref: f7172426
+Ref: guides/distributing-packages-using-setuptools register-your-project173348
+Ref: f9173348
+Ref: Create an account-Footnote-1173385
+Ref: Create an account-Footnote-2173428
+Ref: Create an account-Footnote-3173468
+Node: Upload your distributions173508
+Ref: guides/distributing-packages-using-setuptools api-token173640
+Ref: fa173640
+Ref: guides/distributing-packages-using-setuptools upload-your-distributions173640
+Ref: fb173640
+Node: Including files in source distributions with MANIFEST in174523
+Ref: guides/using-manifest-in doc174724
+Ref: fc174724
+Ref: guides/using-manifest-in including-files-in-source-distributions-with-manifest-in174724
+Ref: fd174724
+Ref: guides/using-manifest-in using-manifest-in174724
+Ref: c2174724
+Node: How files are included in an sdist175722
+Ref: guides/using-manifest-in how-files-are-included-in-an-sdist175892
+Ref: fe175892
+Node: MANIFEST in commands177578
+Ref: guides/using-manifest-in manifest-in-commands177748
+Ref: ff177748
+Node: Single-sourcing the package version181763
+Ref: guides/single-sourcing-package-version doc181964
+Ref: 100181964
+Ref: guides/single-sourcing-package-version single-sourcing-the-package-version181964
+Ref: 101181964
+Ref: guides/single-sourcing-package-version single-sourcing-the-version181964
+Ref: ca181964
+Ref: Single-sourcing the package version-Footnote-1187351
+Ref: Single-sourcing the package version-Footnote-2187412
+Ref: Single-sourcing the package version-Footnote-3187458
+Ref: Single-sourcing the package version-Footnote-4187499
+Ref: Single-sourcing the package version-Footnote-5187546
+Ref: Single-sourcing the package version-Footnote-6187658
+Ref: Single-sourcing the package version-Footnote-7187736
+Node: Supporting multiple Python versions187784
+Ref: guides/supporting-multiple-python-versions doc187971
+Ref: 102187971
+Ref: guides/supporting-multiple-python-versions id1187971
+Ref: 103187971
+Ref: guides/supporting-multiple-python-versions supporting-multiple-python-versions187971
+Ref: 104187971
+Node: Automated testing and continuous integration189717
+Ref: guides/supporting-multiple-python-versions automated-testing-and-continuous-integration189895
+Ref: 105189895
+Ref: Automated testing and continuous integration-Footnote-1191514
+Ref: Automated testing and continuous integration-Footnote-2191541
+Ref: Automated testing and continuous integration-Footnote-3191571
+Ref: Automated testing and continuous integration-Footnote-4191655
+Ref: Automated testing and continuous integration-Footnote-5191685
+Ref: Automated testing and continuous integration-Footnote-6191717
+Ref: Automated testing and continuous integration-Footnote-7191747
+Ref: Automated testing and continuous integration-Footnote-8191779
+Node: Tools for single-source Python packages191807
+Ref: guides/supporting-multiple-python-versions tools-for-single-source-python-packages192019
+Ref: 106192019
+Ref: Tools for single-source Python packages-Footnote-1193848
+Ref: Tools for single-source Python packages-Footnote-2193885
+Ref: Tools for single-source Python packages-Footnote-3193922
+Ref: Tools for single-source Python packages-Footnote-4193959
+Ref: Tools for single-source Python packages-Footnote-5194002
+Ref: Tools for single-source Python packages-Footnote-6194039
+Ref: Tools for single-source Python packages-Footnote-7194076
+Ref: Tools for single-source Python packages-Footnote-8194123
+Ref: Tools for single-source Python packages-Footnote-9194160
+Ref: Tools for single-source Python packages-Footnote-10194207
+Ref: Tools for single-source Python packages-Footnote-11194245
+Ref: Tools for single-source Python packages-Footnote-12194293
+Ref: Tools for single-source Python packages-Footnote-13194337
+Ref: Tools for single-source Python packages-Footnote-14194375
+Ref: Tools for single-source Python packages-Footnote-15194423
+Ref: Tools for single-source Python packages-Footnote-16194461
+Ref: Tools for single-source Python packages-Footnote-17194509
+Node: What’s in which Python?194557
+Ref: guides/supporting-multiple-python-versions what-s-in-which-python194716
+Ref: 107194716
+Ref: What’s in which Python?-Footnote-1195169
+Ref: What’s in which Python?-Footnote-2195242
+Ref: What’s in which Python?-Footnote-3195318
+Node: Dropping support for older Python versions195397
+Ref: guides/dropping-older-python-versions doc195576
+Ref: 108195576
+Ref: guides/dropping-older-python-versions dropping-support-for-older-python-versions195576
+Ref: 109195576
+Ref: guides/dropping-older-python-versions id1195576
+Ref: 10a195576
+Node: Requirements196575
+Ref: guides/dropping-older-python-versions requirements196725
+Ref: 10b196725
+Node: Defining the Python version required197073
+Ref: guides/dropping-older-python-versions defining-the-python-version-required197257
+Ref: 10c197257
+Node: 1 Download the newest version of Setuptools197730
+Ref: guides/dropping-older-python-versions download-the-newest-version-of-setuptools197932
+Ref: 10d197932
+Node: 2 Specify the version ranges for supported Python distributions198271
+Ref: guides/dropping-older-python-versions specify-the-version-ranges-for-supported-python-distributions198525
+Ref: 10e198525
+Node: 3 Validating the Metadata before publishing199263
+Ref: guides/dropping-older-python-versions validating-the-metadata-before-publishing199498
+Ref: 10f199498
+Node: 4 Using Twine to publish200305
+Ref: guides/dropping-older-python-versions using-twine-to-publish200468
+Ref: 110200468
+Node: Dropping a Python release200722
+Ref: guides/dropping-older-python-versions dropping-a-python-release200885
+Ref: 111200885
+Node: Packaging binary extensions201516
+Ref: guides/packaging-binary-extensions doc201693
+Ref: 69201693
+Ref: guides/packaging-binary-extensions binary-extensions201693
+Ref: 112201693
+Ref: guides/packaging-binary-extensions packaging-binary-extensions201693
+Ref: 113201693
+Node: An overview of binary extensions202319
+Ref: guides/packaging-binary-extensions an-overview-of-binary-extensions202468
+Ref: 114202468
+Node: Use cases202732
+Ref: guides/packaging-binary-extensions use-cases202846
+Ref: 115202846
+Ref: Use cases-Footnote-1205358
+Ref: Use cases-Footnote-2205428
+Ref: Use cases-Footnote-3205509
+Ref: Use cases-Footnote-4205580
+Ref: Use cases-Footnote-5205662
+Node: Disadvantages205735
+Ref: guides/packaging-binary-extensions disadvantages205903
+Ref: 116205903
+Node: Alternatives to handcoded accelerator modules207538
+Ref: guides/packaging-binary-extensions alternatives-to-handcoded-accelerator-modules207738
+Ref: 117207738
+Ref: Alternatives to handcoded accelerator modules-Footnote-1210252
+Ref: Alternatives to handcoded accelerator modules-Footnote-2210277
+Ref: Alternatives to handcoded accelerator modules-Footnote-3210304
+Node: Alternatives to handcoded wrapper modules210337
+Ref: guides/packaging-binary-extensions alternatives-to-handcoded-wrapper-modules210564
+Ref: 118210564
+Ref: Alternatives to handcoded wrapper modules-Footnote-1213021
+Ref: Alternatives to handcoded wrapper modules-Footnote-2213048
+Ref: Alternatives to handcoded wrapper modules-Footnote-3213085
+Node: Alternatives for low level system access213114
+Ref: guides/packaging-binary-extensions alternatives-for-low-level-system-access213287
+Ref: 119213287
+Node: Implementing binary extensions214273
+Ref: guides/packaging-binary-extensions implementing-binary-extensions214457
+Ref: 11a214457
+Ref: Implementing binary extensions-Footnote-1215100
+Ref: Implementing binary extensions-Footnote-2215145
+Node: Building binary extensions215204
+Ref: guides/packaging-binary-extensions building-binary-extensions215384
+Ref: 11b215384
+Node: Binary extensions for Windows215561
+Ref: guides/packaging-binary-extensions binary-extensions-for-windows215703
+Ref: 11c215703
+Ref: Binary extensions for Windows-Footnote-1217717
+Ref: Binary extensions for Windows-Footnote-2217788
+Ref: Binary extensions for Windows-Footnote-3217858
+Node: Binary extensions for Linux217943
+Ref: guides/packaging-binary-extensions binary-extensions-for-linux218121
+Ref: 11d218121
+Ref: Binary extensions for Linux-Footnote-1218478
+Node: Binary extensions for macOS218520
+Ref: guides/packaging-binary-extensions binary-extensions-for-macos218660
+Ref: 11e218660
+Ref: Binary extensions for macOS-Footnote-1219240
+Node: Publishing binary extensions219303
+Ref: guides/packaging-binary-extensions publishing-binary-extensions219473
+Ref: 11f219473
+Ref: Publishing binary extensions-Footnote-1219983
+Node: Additional resources220054
+Ref: guides/packaging-binary-extensions additional-resources220189
+Ref: 120220189
+Node: Cross-platform wheel generation with scikit-build220758
+Ref: guides/packaging-binary-extensions cross-platform-wheel-generation-with-scikit-build220926
+Ref: 121220926
+Ref: Cross-platform wheel generation with scikit-build-Footnote-1221374
+Ref: Cross-platform wheel generation with scikit-build-Footnote-2221429
+Node: Introduction to C/C++ extension modules221499
+Ref: guides/packaging-binary-extensions introduction-to-c-c-extension-modules221667
+Ref: 122221667
+Ref: Introduction to C/C++ extension modules-Footnote-1222055
+Ref: Introduction to C/C++ extension modules-Footnote-2222120
+Ref: Introduction to C/C++ extension modules-Footnote-3222176
+Node: Supporting Windows using Appveyor222236
+Ref: guides/supporting-windows-using-appveyor doc222399
+Ref: 123222399
+Ref: guides/supporting-windows-using-appveyor supporting-windows-using-appveyor222399
+Ref: 124222399
+Ref: Supporting Windows using Appveyor-Footnote-1222921
+Node: Background222954
+Ref: guides/supporting-windows-using-appveyor background223067
+Ref: 125223067
+Ref: Background-Footnote-1224080
+Ref: Background-Footnote-2224111
+Node: Setting up224139
+Ref: guides/supporting-windows-using-appveyor setting-up224300
+Ref: 126224300
+Ref: Setting up-Footnote-1225017
+Ref: Setting up-Footnote-2225054
+Ref: Setting up-Footnote-3225082
+Node: Adding Appveyor support to your project225113
+Ref: guides/supporting-windows-using-appveyor adding-appveyor-support-to-your-project225280
+Ref: 127225280
+Node: appveyor yml226213
+Ref: guides/supporting-windows-using-appveyor appveyor-yml226338
+Ref: 128226338
+Ref: appveyor yml-Footnote-1230703
+Node: Support script230829
+Ref: guides/supporting-windows-using-appveyor support-script230989
+Ref: 129230989
+Ref: Support script-Footnote-1231873
+Node: Access to the built wheels231996
+Ref: guides/supporting-windows-using-appveyor access-to-the-built-wheels232135
+Ref: 12a232135
+Node: Additional notes232673
+Ref: guides/supporting-windows-using-appveyor additional-notes232821
+Ref: 12b232821
+Node: Testing with tox232982
+Ref: guides/supporting-windows-using-appveyor testing-with-tox233104
+Ref: 12c233104
+Ref: Testing with tox-Footnote-1236036
+Node: Automatically uploading wheels236067
+Ref: guides/supporting-windows-using-appveyor automatically-uploading-wheels236219
+Ref: 12d236219
+Node: External dependencies236860
+Ref: guides/supporting-windows-using-appveyor external-dependencies237011
+Ref: 12e237011
+Node: Support scripts237592
+Ref: guides/supporting-windows-using-appveyor support-scripts237704
+Ref: 12f237704
+Node: Packaging namespace packages238778
+Ref: guides/packaging-namespace-packages doc238946
+Ref: 130238946
+Ref: guides/packaging-namespace-packages packaging-namespace-packages238946
+Ref: 131238946
+Ref: guides/packaging-namespace-packages tox238946
+Ref: 132238946
+Node: Creating a namespace package240602
+Ref: guides/packaging-namespace-packages creating-a-namespace-package240709
+Ref: 133240709
+Ref: Creating a namespace package-Footnote-1242041
+Node: Native namespace packages242090
+Ref: guides/packaging-namespace-packages native-namespace-packages242235
+Ref: 134242235
+Ref: Native namespace packages-Footnote-1243916
+Ref: Native namespace packages-Footnote-2243965
+Node: pkgutil-style namespace packages244043
+Ref: guides/packaging-namespace-packages pkgutil-style-namespace-packages244235
+Ref: 135244235
+Ref: pkgutil-style namespace packages-Footnote-1245500
+Ref: pkgutil-style namespace packages-Footnote-2245555
+Ref: pkgutil-style namespace packages-Footnote-3245631
+Node: pkg_resources-style namespace packages245710
+Ref: guides/packaging-namespace-packages pkg-resources-style-namespace-packages245868
+Ref: 136245868
+Ref: guides/packaging-namespace-packages pkgutil-namespace-example-project245868
+Ref: 137245868
+Ref: pkg_resources-style namespace packages-Footnote-1248492
+Ref: pkg_resources-style namespace packages-Footnote-2248534
+Ref: pkg_resources-style namespace packages-Footnote-3248622
+Node: Creating and discovering plugins248707
+Ref: guides/creating-and-discovering-plugins doc248874
+Ref: 138248874
+Ref: guides/creating-and-discovering-plugins creating-and-discovering-plugins248874
+Ref: 139248874
+Ref: guides/creating-and-discovering-plugins pkg-resources-namespace-example-project248874
+Ref: 13a248874
+Node: Using naming convention249530
+Ref: guides/creating-and-discovering-plugins using-naming-convention249669
+Ref: 13b249669
+Ref: Using naming convention-Footnote-1250755
+Ref: Using naming convention-Footnote-2250832
+Ref: Using naming convention-Footnote-3250872
+Ref: Using naming convention-Footnote-4250923
+Ref: Using naming convention-Footnote-5250971
+Node: Using namespace packages251035
+Ref: guides/creating-and-discovering-plugins simple-api251205
+Ref: 13e251205
+Ref: guides/creating-and-discovering-plugins using-namespace-packages251205
+Ref: 13c251205
+Ref: Using namespace packages-Footnote-1254013
+Ref: Using namespace packages-Footnote-2254090
+Node: Using package metadata254167
+Ref: guides/creating-and-discovering-plugins using-package-metadata254305
+Ref: 13d254305
+Ref: guides/creating-and-discovering-plugins special-support255374
+Ref: 13f255374
+Ref: Using package metadata-Footnote-1255411
+Ref: Using package metadata-Footnote-2255452
+Ref: Using package metadata-Footnote-3255562
+Node: Analyzing PyPI package downloads255672
+Ref: guides/analyzing-pypi-package-downloads doc255843
+Ref: 140255843
+Ref: guides/analyzing-pypi-package-downloads analyzing-pypi-package-downloads255843
+Ref: 141255843
+Ref: guides/analyzing-pypi-package-downloads entry-points255843
+Ref: 142255843
+Ref: guides/analyzing-pypi-package-downloads special-support255843
+Ref: 143255843
+Node: Background<2>256279
+Ref: guides/analyzing-pypi-package-downloads background256398
+Ref: 144256398
+Ref: Background<2>-Footnote-1257739
+Node: Public dataset257861
+Ref: guides/analyzing-pypi-package-downloads public-dataset257996
+Ref: 145257996
+Ref: Public dataset-Footnote-1258287
+Ref: Public dataset-Footnote-2258328
+Ref: Public dataset-Footnote-3258370
+Node: Getting set up258494
+Ref: guides/analyzing-pypi-package-downloads getting-set-up258593
+Ref: 146258593
+Ref: Getting set up-Footnote-1259188
+Ref: Getting set up-Footnote-2259230
+Ref: Getting set up-Footnote-3259311
+Ref: Getting set up-Footnote-4259449
+Ref: Getting set up-Footnote-5259499
+Ref: Getting set up-Footnote-6259588
+Node: Data schema259666
+Ref: guides/analyzing-pypi-package-downloads data-schema259788
+Ref: 147259788
+Ref: Data schema-Footnote-1261203
+Ref: Data schema-Footnote-2261305
+Node: Useful queries261341
+Ref: guides/analyzing-pypi-package-downloads useful-queries261440
+Ref: 148261440
+Ref: Useful queries-Footnote-1261904
+Node: Counting package downloads261954
+Ref: guides/analyzing-pypi-package-downloads counting-package-downloads262081
+Ref: 149262081
+Node: Package downloads over time263054
+Ref: guides/analyzing-pypi-package-downloads package-downloads-over-time263215
+Ref: 14a263215
+Node: Python versions over time264379
+Ref: guides/analyzing-pypi-package-downloads python-versions-over-time264505
+Ref: 14b264505
+Node: Caveats265521
+Ref: guides/analyzing-pypi-package-downloads caveats265659
+Ref: 14c265659
+Node: Additional tools266049
+Ref: guides/analyzing-pypi-package-downloads additional-tools266183
+Ref: 14d266183
+Node: google-cloud-bigquery266420
+Ref: guides/analyzing-pypi-package-downloads google-cloud-bigquery266524
+Ref: 14e266524
+Ref: google-cloud-bigquery-Footnote-1267533
+Node: pypinfo267600
+Ref: guides/analyzing-pypi-package-downloads pypinfo267723
+Ref: 14f267723
+Ref: pypinfo-Footnote-1268308
+Ref: pypinfo-Footnote-2268371
+Node: pandas-gbq268434
+Ref: guides/analyzing-pypi-package-downloads pandas-gbq268527
+Ref: 150268527
+Ref: pandas-gbq-Footnote-1268689
+Ref: pandas-gbq-Footnote-2268742
+Node: References268777
+Ref: guides/analyzing-pypi-package-downloads references268895
+Ref: 151268895
+Node: Package index mirrors and caches268932
+Ref: guides/index-mirrors-and-caches doc269105
+Ref: 152269105
+Ref: guides/index-mirrors-and-caches package-index-mirrors-and-caches269105
+Ref: 153269105
+Ref: guides/index-mirrors-and-caches pandas269105
+Ref: 154269105
+Ref: guides/index-mirrors-and-caches pypi-mirrors-and-caches269105
+Ref: 155269105
+Node: Caching with pip269774
+Ref: guides/index-mirrors-and-caches caching-with-pip269900
+Ref: 156269900
+Ref: Caching with pip-Footnote-1270524
+Ref: Caching with pip-Footnote-2270606
+Node: Caching with devpi270676
+Ref: guides/index-mirrors-and-caches caching-with-devpi270844
+Ref: 157270844
+Ref: Caching with devpi-Footnote-1271113
+Node: Complete mirror with bandersnatch271176
+Ref: guides/index-mirrors-and-caches complete-mirror-with-bandersnatch271319
+Ref: 158271319
+Ref: guides/index-mirrors-and-caches id1271319
+Ref: 159271319
+Ref: Complete mirror with bandersnatch-Footnote-1271819
+Node: Hosting your own simple repository271865
+Ref: guides/hosting-your-own-index doc272027
+Ref: 15a272027
+Ref: guides/hosting-your-own-index hosting-your-own-simple-repository272027
+Ref: 15b272027
+Ref: guides/hosting-your-own-index id1272027
+Ref: 15c272027
+Ref: Hosting your own simple repository-Footnote-1272937
+Ref: Hosting your own simple repository-Footnote-2273024
+Node: “Manual” repository273061
+Ref: guides/hosting-your-own-index manual-repository273169
+Ref: 15d273169
+Ref: “Manual” repository-Footnote-1274219
+Node: Migrating to PyPI org274254
+Ref: guides/migrating-to-pypi-org doc274401
+Ref: 15e274401
+Ref: guides/migrating-to-pypi-org id1274401
+Ref: 15f274401
+Ref: guides/migrating-to-pypi-org migrating-to-pypi-org274401
+Ref: 87274401
+Ref: guides/migrating-to-pypi-org twisted274401
+Ref: 160274401
+Node: Publishing releases274939
+Ref: guides/migrating-to-pypi-org publishing-releases275075
+Ref: 162275075
+Node: Registering package names & metadata277066
+Ref: guides/migrating-to-pypi-org registering-package-names-metadata277225
+Ref: 163277225
+Node: Using TestPyPI277846
+Ref: guides/migrating-to-pypi-org using-testpypi278015
+Ref: 164278015
+Ref: Using TestPyPI-Footnote-1278684
+Node: Registering new user accounts278714
+Ref: guides/migrating-to-pypi-org registering-new-user-accounts278864
+Ref: 165278864
+Node: Browsing packages279140
+Ref: guides/migrating-to-pypi-org browsing-packages279296
+Ref: 166279296
+Node: Downloading packages279604
+Ref: guides/migrating-to-pypi-org downloading-packages279771
+Ref: 167279771
+Node: Managing published packages and releases279890
+Ref: guides/migrating-to-pypi-org managing-published-packages-and-releases280031
+Ref: 168280031
+Node: Using TestPyPI<2>280251
+Ref: guides/using-testpypi doc280393
+Ref: 65280393
+Ref: guides/using-testpypi using-test-pypi280393
+Ref: f6280393
+Ref: guides/using-testpypi using-testpypi280393
+Ref: 169280393
+Ref: Using TestPyPI<2>-Footnote-1280868
+Node: Registering your account280898
+Ref: guides/using-testpypi registering-your-account281024
+Ref: 16a281024
+Node: Using TestPyPI with Twine281423
+Ref: guides/using-testpypi using-testpypi-with-twine281581
+Ref: 16b281581
+Node: Using TestPyPI with pip282084
+Ref: guides/using-testpypi using-testpypi-with-pip282247
+Ref: 16c282247
+Node: Setting up TestPyPI in pypirc282799
+Ref: guides/using-testpypi setting-up-testpypi-in-pypirc282928
+Ref: 16d282928
+Node: Making a PyPI-friendly README283244
+Ref: guides/making-a-pypi-friendly-readme doc283442
+Ref: 16e283442
+Ref: guides/making-a-pypi-friendly-readme making-a-pypi-friendly-readme283442
+Ref: 16f283442
+Node: Creating a README file283889
+Ref: guides/making-a-pypi-friendly-readme creating-a-readme-file284050
+Ref: 170284050
+Ref: Creating a README file-Footnote-1284679
+Ref: Creating a README file-Footnote-2284727
+Ref: Creating a README file-Footnote-3284776
+Ref: Creating a README file-Footnote-4284815
+Node: Including your README in your package’s metadata284846
+Ref: guides/making-a-pypi-friendly-readme including-your-readme-in-your-package-s-metadata285050
+Ref: 171285050
+Node: Validating reStructuredText markup287099
+Ref: guides/making-a-pypi-friendly-readme validating-restructuredtext-markup287272
+Ref: 174287272
+Ref: Validating reStructuredText markup-Footnote-1288403
+Ref: Validating reStructuredText markup-Footnote-2288482
+Node: Publishing package distribution releases using GitHub Actions CI/CD workflows288520
+Ref: guides/publishing-package-distribution-releases-using-github-actions-ci-cd-workflows doc288692
+Ref: 175288692
+Ref: guides/publishing-package-distribution-releases-using-github-actions-ci-cd-workflows publishing-package-distribution-releases-using-github-actions-ci-cd-workflows288692
+Ref: 176288692
+Ref: Publishing package distribution releases using GitHub Actions CI/CD workflows-Footnote-1289672
+Ref: Publishing package distribution releases using GitHub Actions CI/CD workflows-Footnote-2289716
+Node: Saving credentials on GitHub289776
+Ref: guides/publishing-package-distribution-releases-using-github-actions-ci-cd-workflows saving-credentials-on-github289971
+Ref: 177289971
+Ref: Saving credentials on GitHub-Footnote-1291307
+Ref: Saving credentials on GitHub-Footnote-2291347
+Node: Creating a workflow definition291479
+Ref: guides/publishing-package-distribution-releases-using-github-actions-ci-cd-workflows creating-a-workflow-definition291718
+Ref: 178291718
+Node: Defining a workflow job environment292173
+Ref: guides/publishing-package-distribution-releases-using-github-actions-ci-cd-workflows defining-a-workflow-job-environment292435
+Ref: 179292435
+Node: Checking out the project and building distributions292835
+Ref: guides/publishing-package-distribution-releases-using-github-actions-ci-cd-workflows checking-out-the-project-and-building-distributions293115
+Ref: 17a293115
+Ref: Checking out the project and building distributions-Footnote-1294351
+Ref: Checking out the project and building distributions-Footnote-2294400
+Node: Publishing the distribution to PyPI and TestPyPI294449
+Ref: guides/publishing-package-distribution-releases-using-github-actions-ci-cd-workflows publishing-the-distribution-to-pypi-and-testpypi294713
+Ref: 17b294713
+Ref: Publishing the distribution to PyPI and TestPyPI-Footnote-1295607
+Node: That’s all folks!295662
+Ref: guides/publishing-package-distribution-releases-using-github-actions-ci-cd-workflows that-s-all-folks295866
+Ref: 17c295866
+Node: Discussions296211
+Ref: discussions/index doc296319
+Ref: 17d296319
+Ref: discussions/index discussions296319
+Ref: 17e296319
+Ref: discussions/index secrets296319
+Ref: 17f296319
+Node: Deploying Python applications296632
+Ref: discussions/deploying-python-applications doc296751
+Ref: 180296751
+Ref: discussions/deploying-python-applications deploying-python-applications296751
+Ref: 181296751
+Node: Overview296980
+Ref: discussions/deploying-python-applications overview297102
+Ref: 182297102
+Node: Supporting multiple hardware platforms297186
+Ref: discussions/deploying-python-applications supporting-multiple-hardware-platforms297283
+Ref: 183297283
+Node: OS packaging & installers298059
+Ref: discussions/deploying-python-applications os-packaging-installers298209
+Ref: 184298209
+Node: Windows<2>298521
+Ref: discussions/deploying-python-applications windows298607
+Ref: 185298607
+Node: Pynsist298730
+Ref: discussions/deploying-python-applications pynsist298798
+Ref: 186298798
+Ref: Pynsist-Footnote-1299740
+Ref: Pynsist-Footnote-2299781
+Node: Application bundles299820
+Ref: discussions/deploying-python-applications application-bundles299986
+Ref: 187299986
+Node: Configuration management300103
+Ref: discussions/deploying-python-applications configuration-management300235
+Ref: 188300235
+Node: pip vs easy_install300368
+Ref: discussions/pip-vs-easy-install doc300534
+Ref: 189300534
+Ref: discussions/pip-vs-easy-install id1300534
+Ref: 18a300534
+Ref: discussions/pip-vs-easy-install pip-vs-easy-install300534
+Ref: 7d300534
+Ref: pip vs easy_install-Footnote-1304580
+Ref: pip vs easy_install-Footnote-2304649
+Ref: pip vs easy_install-Footnote-3304718
+Ref: pip vs easy_install-Footnote-4304767
+Ref: pip vs easy_install-Footnote-5304820
+Node: install_requires vs requirements files304924
+Ref: discussions/install-requires-vs-requirements doc305073
+Ref: 18c305073
+Ref: discussions/install-requires-vs-requirements id1305073
+Ref: 18d305073
+Ref: discussions/install-requires-vs-requirements install-requires-vs-requirements-files305073
+Ref: d6305073
+Ref: discussions/install-requires-vs-requirements pylauncher-support305073
+Ref: 18e305073
+Node: install_requires<2>305256
+Ref: discussions/install-requires-vs-requirements install-requires305394
+Ref: 18f305394
+Ref: install_requires<2>-Footnote-1307066
+Node: Requirements files<2>307197
+Ref: discussions/install-requires-vs-requirements requirements-files307335
+Ref: 190307335
+Ref: Requirements files<2>-Footnote-1308512
+Ref: Requirements files<2>-Footnote-2308581
+Ref: Requirements files<2>-Footnote-3308654
+Ref: Requirements files<2>-Footnote-4308723
+Ref: Requirements files<2>-Footnote-5308787
+Node: Wheel vs Egg308918
+Ref: discussions/wheel-vs-egg doc309039
+Ref: 191309039
+Ref: discussions/wheel-vs-egg id1309039
+Ref: 192309039
+Ref: discussions/wheel-vs-egg wheel-vs-egg309039
+Ref: 193309039
+Ref: Wheel vs Egg-Footnote-1310987
+Ref: Wheel vs Egg-Footnote-2311036
+Ref: Wheel vs Egg-Footnote-3311085
+Ref: Wheel vs Egg-Footnote-4311345
+Ref: Wheel vs Egg-Footnote-5311394
+Ref: Wheel vs Egg-Footnote-6311443
+Node: PyPA specifications311519
+Ref: specifications/index doc311638
+Ref: 195311638
+Ref: specifications/index packaging-specifications311638
+Ref: 196311638
+Ref: specifications/index pypa-specifications311638
+Ref: 197311638
+Ref: PyPA specifications-Footnote-1312006
+Node: Package Distribution Metadata312060
+Ref: specifications/index package-distribution-metadata312192
+Ref: 198312192
+Node: Core metadata specifications312545
+Ref: specifications/core-metadata doc312680
+Ref: 199312680
+Ref: specifications/core-metadata core-metadata312680
+Ref: 85312680
+Ref: specifications/core-metadata core-metadata-specifications312680
+Ref: 19a312680
+Ref: Core metadata specifications-Footnote-1314329
+Ref: Core metadata specifications-Footnote-2314378
+Node: Metadata-Version314427
+Ref: specifications/core-metadata metadata-version314535
+Ref: 19b314535
+Ref: Metadata-Version-Footnote-1315245
+Node: Name315294
+Ref: specifications/core-metadata core-metadata-name315418
+Ref: 19c315418
+Ref: specifications/core-metadata name315418
+Ref: 19d315418
+Ref: Name-Footnote-1315999
+Node: Version316048
+Ref: specifications/core-metadata core-metadata-version316177
+Ref: 19e316177
+Ref: specifications/core-metadata version316177
+Ref: 19f316177
+Ref: Version-Footnote-1316415
+Node: Platform multiple use316464
+Ref: specifications/core-metadata platform-multiple-use316620
+Ref: 1a0316620
+Node: Supported-Platform multiple use316953
+Ref: specifications/core-metadata supported-platform-multiple-use317109
+Ref: 1a1317109
+Node: Summary317560
+Ref: specifications/core-metadata core-metadata-summary317706
+Ref: 1a2317706
+Ref: specifications/core-metadata summary317706
+Ref: 1a3317706
+Ref: specifications/core-metadata description-optional317880
+Ref: 172317880
+Node: Description317880
+Ref: specifications/core-metadata core-metadata-description318019
+Ref: 1a4318019
+Ref: specifications/core-metadata description318019
+Ref: 1a5318019
+Ref: specifications/core-metadata description-content-type-optional319621
+Ref: 173319621
+Ref: Description-Footnote-1319659
+Ref: Description-Footnote-2319735
+Node: Description-Content-Type319823
+Ref: specifications/core-metadata core-metadata-description-content-type319963
+Ref: 1a6319963
+Ref: specifications/core-metadata description-content-type319963
+Ref: 1a7319963
+Ref: specifications/core-metadata keywords-optional322970
+Ref: 1a8322970
+Ref: Description-Content-Type-Footnote-1323008
+Ref: Description-Content-Type-Footnote-2323084
+Ref: Description-Content-Type-Footnote-3323138
+Ref: Description-Content-Type-Footnote-4323182
+Ref: Description-Content-Type-Footnote-5323247
+Ref: Description-Content-Type-Footnote-6323303
+Node: Keywords323359
+Ref: specifications/core-metadata core-metadata-keywords323497
+Ref: 1a9323497
+Ref: specifications/core-metadata keywords323497
+Ref: 1aa323497
+Node: Home-page324013
+Ref: specifications/core-metadata home-page324139
+Ref: 1ab324139
+Ref: specifications/core-metadata home-page-optional324139
+Ref: 1ac324139
+Node: Download-URL324331
+Ref: specifications/core-metadata download-url324455
+Ref: 1ad324455
+Ref: specifications/core-metadata author-optional324749
+Ref: 1ae324749
+Node: Author324750
+Ref: specifications/core-metadata author324877
+Ref: 1af324877
+Ref: specifications/core-metadata core-metadata-author324877
+Ref: 1b0324877
+Ref: specifications/core-metadata author-email-optional325159
+Ref: 1b1325159
+Node: Author-email325160
+Ref: specifications/core-metadata author-email325285
+Ref: 1b2325285
+Ref: specifications/core-metadata core-metadata-author-email325285
+Ref: 1b3325285
+Ref: specifications/core-metadata maintainer-optional325704
+Ref: 1b4325704
+Node: Maintainer325705
+Ref: specifications/core-metadata core-metadata-maintainer325840
+Ref: 1b5325840
+Ref: specifications/core-metadata maintainer325840
+Ref: 1b6325840
+Ref: specifications/core-metadata maintainer-email-optional326315
+Ref: 1b7326315
+Node: Maintainer-email326316
+Ref: specifications/core-metadata core-metadata-maintainer-email326446
+Ref: 1b8326446
+Ref: specifications/core-metadata maintainer-email326446
+Ref: 1b9326446
+Ref: specifications/core-metadata license-optional327068
+Ref: 1ba327068
+Node: License327069
+Ref: specifications/core-metadata core-metadata-license327212
+Ref: 1bb327212
+Ref: specifications/core-metadata license327212
+Ref: 1bc327212
+Ref: specifications/core-metadata metadata-classifier327849
+Ref: 1bd327849
+Node: Classifier multiple use327850
+Ref: specifications/core-metadata classifier-multiple-use328003
+Ref: 1be328003
+Ref: specifications/core-metadata core-metadata-classifier328003
+Ref: 1bf328003
+Ref: Classifier multiple use-Footnote-1328532
+Ref: Classifier multiple use-Footnote-2328581
+Node: Requires-Dist multiple use328619
+Ref: specifications/core-metadata core-metadata-requires-dist328780
+Ref: 1c0328780
+Ref: specifications/core-metadata requires-dist-multiple-use328780
+Ref: 1c1328780
+Ref: Requires-Dist multiple use-Footnote-1330167
+Ref: Requires-Dist multiple use-Footnote-2330216
+Node: Requires-Python330241
+Ref: specifications/core-metadata core-metadata-requires-python330409
+Ref: 1c3330409
+Ref: specifications/core-metadata requires-python330409
+Ref: 1c4330409
+Node: Requires-External multiple use330916
+Ref: specifications/core-metadata requires-external-multiple-use331082
+Ref: 1c5331082
+Ref: Requires-External multiple use-Footnote-1332252
+Node: Project-URL multiple-use332301
+Ref: specifications/core-metadata core-metadata-project-url332479
+Ref: 1c6332479
+Ref: specifications/core-metadata project-url-multiple-use332479
+Ref: 1c7332479
+Ref: specifications/core-metadata metadata-provides-extra332804
+Ref: 1c8332804
+Ref: specifications/core-metadata core-metadata-provides-extra332804
+Ref: 1c9332804
+Node: Provides-Extra multiple use332806
+Ref: specifications/core-metadata provides-extra-multiple-use332972
+Ref: 1ca332972
+Ref: specifications/core-metadata provides-extra-optional-multiple-use332972
+Ref: 1cb332972
+Node: Rarely Used Fields333977
+Ref: specifications/core-metadata rarely-used-fields334110
+Ref: 1cc334110
+Ref: Rarely Used Fields-Footnote-1334993
+Node: Provides-Dist multiple use335018
+Ref: specifications/core-metadata provides-dist-multiple-use335149
+Ref: 1cd335149
+Node: Obsoletes-Dist multiple use336846
+Ref: specifications/core-metadata obsoletes-dist-multiple-use336977
+Ref: 1ce336977
+Node: Version specifiers337988
+Ref: specifications/version-specifiers doc338153
+Ref: 1c2338153
+Ref: specifications/version-specifiers id1338153
+Ref: 1cf338153
+Ref: specifications/version-specifiers version-specifiers338153
+Ref: 1d0338153
+Ref: Version specifiers-Footnote-1338462
+Ref: Version specifiers-Footnote-2338511
+Node: Dependency specifiers338560
+Ref: specifications/dependency-specifiers doc338732
+Ref: 1d1338732
+Ref: specifications/dependency-specifiers dependency-specifiers338732
+Ref: 1d2338732
+Ref: specifications/dependency-specifiers id1338732
+Ref: 1d3338732
+Ref: Dependency specifiers-Footnote-1339037
+Ref: Dependency specifiers-Footnote-2339086
+Node: Declaring build system dependencies339135
+Ref: specifications/declaring-build-dependencies doc339315
+Ref: 1d4339315
+Ref: specifications/declaring-build-dependencies declaring-build-dependencies339315
+Ref: 1d5339315
+Ref: specifications/declaring-build-dependencies declaring-build-system-dependencies339315
+Ref: 1d6339315
+Ref: Declaring build system dependencies-Footnote-1339686
+Node: Declaring project metadata339735
+Ref: specifications/declaring-project-metadata doc339914
+Ref: 1d8339914
+Ref: specifications/declaring-project-metadata declaring-project-metadata339914
+Ref: 1d9339914
+Ref: specifications/declaring-project-metadata id1339914
+Ref: 1da339914
+Ref: Declaring project metadata-Footnote-1341652
+Node: name<2>341701
+Ref: specifications/declaring-project-metadata name341804
+Ref: 1db341804
+Ref: name<2>-Footnote-1342108
+Ref: name<2>-Footnote-2342133
+Node: version<2>342182
+Ref: specifications/declaring-project-metadata version342308
+Ref: 1dc342308
+Ref: version<2>-Footnote-1342601
+Ref: version<2>-Footnote-2342626
+Node: description<2>342675
+Ref: specifications/declaring-project-metadata description342800
+Ref: 1dd342800
+Ref: description<2>-Footnote-1343025
+Node: readme343050
+Ref: specifications/declaring-project-metadata readme343180
+Ref: 1de343180
+Ref: readme-Footnote-1345119
+Node: requires-python345144
+Ref: specifications/declaring-project-metadata requires-python345270
+Ref: 1df345270
+Ref: requires-python-Footnote-1345524
+Node: license<2>345549
+Ref: specifications/declaring-project-metadata license345688
+Ref: 1e0345688
+Ref: license<2>-Footnote-1346278
+Node: authors/maintainers346303
+Ref: specifications/declaring-project-metadata authors-maintainers346438
+Ref: 1e1346438
+Ref: authors/maintainers-Footnote-1348016
+Ref: authors/maintainers-Footnote-2348041
+Node: keywords<2>348084
+Ref: specifications/declaring-project-metadata keywords348223
+Ref: 1e2348223
+Ref: keywords<2>-Footnote-1348443
+Node: classifiers<2>348468
+Ref: specifications/declaring-project-metadata classifiers348592
+Ref: 1e3348592
+Ref: classifiers<2>-Footnote-1348841
+Node: urls348866
+Ref: specifications/declaring-project-metadata urls348991
+Ref: 1e4348991
+Ref: urls-Footnote-1349284
+Node: Entry points349309
+Ref: specifications/declaring-project-metadata entry-points349454
+Ref: 1e5349454
+Ref: Entry points-Footnote-1350713
+Node: dependencies/optional-dependencies350738
+Ref: specifications/declaring-project-metadata dependencies-optional-dependencies350886
+Ref: 1e7350886
+Ref: dependencies/optional-dependencies-Footnote-1351978
+Ref: dependencies/optional-dependencies-Footnote-2352003
+Ref: dependencies/optional-dependencies-Footnote-3352052
+Ref: dependencies/optional-dependencies-Footnote-4352101
+Ref: dependencies/optional-dependencies-Footnote-5352150
+Node: dynamic352199
+Ref: specifications/declaring-project-metadata dynamic352326
+Ref: 1e8352326
+Ref: dynamic-Footnote-1354257
+Node: Distribution formats354282
+Ref: specifications/distribution-formats doc354453
+Ref: 1e9354453
+Ref: specifications/distribution-formats distribution-formats354453
+Ref: 1ea354453
+Ref: specifications/distribution-formats id1354453
+Ref: 1eb354453
+Ref: specifications/distribution-formats toml354453
+Ref: 1ec354453
+Node: Source distribution format354580
+Ref: specifications/distribution-formats source-distribution-format354712
+Ref: 1ed354712
+Ref: Source distribution format-Footnote-1355156
+Ref: Source distribution format-Footnote-2355205
+Node: Binary distribution format355254
+Ref: specifications/distribution-formats binary-distribution-format355386
+Ref: 1ee355386
+Ref: specifications/distribution-formats id2355386
+Ref: 1ef355386
+Ref: Binary distribution format-Footnote-1355565
+Node: Platform compatibility tags355614
+Ref: specifications/platform-compatibility-tags doc355787
+Ref: 1f0355787
+Ref: specifications/platform-compatibility-tags id1355787
+Ref: 1f1355787
+Ref: specifications/platform-compatibility-tags platform-compatibility-tags355787
+Ref: 1f2355787
+Ref: Platform compatibility tags-Footnote-1356431
+Node: Platform tags for Windows356480
+Ref: specifications/platform-compatibility-tags platform-tags-for-windows356624
+Ref: 1f3356624
+Ref: Platform tags for Windows-Footnote-1356833
+Node: Platform tags for macOS Mac OS X356882
+Ref: specifications/platform-compatibility-tags platform-tags-for-macos-mac-os-x357079
+Ref: 1f4357079
+Ref: Platform tags for macOS Mac OS X-Footnote-1357335
+Node: Platform tags for common Linux distributions357384
+Ref: specifications/platform-compatibility-tags platform-tags-for-common-linux-distributions357594
+Ref: 1f5357594
+Ref: specifications/platform-compatibility-tags manylinux357701
+Ref: 1f6357701
+Ref: Platform tags for common Linux distributions-Footnote-1359692
+Ref: Platform tags for common Linux distributions-Footnote-2359741
+Ref: Platform tags for common Linux distributions-Footnote-3359790
+Ref: Platform tags for common Linux distributions-Footnote-4359839
+Ref: Platform tags for common Linux distributions-Footnote-5359888
+Ref: Platform tags for common Linux distributions-Footnote-6359937
+Node: Manylinux compatibility support359993
+Ref: specifications/platform-compatibility-tags manylinux-compatibility-support360119
+Ref: 1f7360119
+Node: Platform tags for other *nix platforms361047
+Ref: specifications/platform-compatibility-tags platform-tags-for-other-nix-platforms361216
+Ref: 1f8361216
+Ref: Platform tags for other *nix platforms-Footnote-1361609
+Node: Recording installed projects361658
+Ref: specifications/recording-installed-packages doc361837
+Ref: 1f9361837
+Ref: specifications/recording-installed-packages recording-installed-packages361837
+Ref: 1fa361837
+Ref: specifications/recording-installed-packages recording-installed-projects361837
+Ref: 1fb361837
+Node: History and change workflow362680
+Ref: specifications/recording-installed-packages history-and-change-workflow362818
+Ref: 1fd362818
+Ref: History and change workflow-Footnote-1363407
+Ref: History and change workflow-Footnote-2363456
+Ref: History and change workflow-Footnote-3363505
+Node: The dist-info directory363554
+Ref: specifications/recording-installed-packages the-dist-info-directory363718
+Ref: 1fe363718
+Ref: The dist-info directory-Footnote-1365231
+Ref: The dist-info directory-Footnote-2365313
+Ref: The dist-info directory-Footnote-3365387
+Ref: The dist-info directory-Footnote-4365454
+Node: The METADATA file365514
+Ref: specifications/recording-installed-packages the-metadata-file365666
+Ref: 1ff365666
+Node: The RECORD file366038
+Ref: specifications/recording-installed-packages the-record-file366185
+Ref: 200366185
+Node: The INSTALLER file369760
+Ref: specifications/recording-installed-packages the-installer-file369881
+Ref: 201369881
+Node: Entry points specification370615
+Ref: specifications/entry-points doc370758
+Ref: 202370758
+Ref: specifications/entry-points entry-points370758
+Ref: 1e6370758
+Ref: specifications/entry-points entry-points-specification370758
+Ref: 203370758
+Node: Data model372094
+Ref: specifications/entry-points data-model372201
+Ref: 204372201
+Node: File format375082
+Ref: specifications/entry-points file-format375213
+Ref: 205375213
+Ref: File format-Footnote-1377058
+Ref: File format-Footnote-2377107
+Ref: File format-Footnote-3377156
+Ref: File format-Footnote-4377237
+Node: Use for scripts377286
+Ref: specifications/entry-points use-for-scripts377398
+Ref: 206377398
+Node: Package Index Interfaces379136
+Ref: specifications/index package-index-interfaces379268
+Ref: 207379268
+Node: The pypirc file379400
+Ref: specifications/pypirc doc379520
+Ref: 208379520
+Ref: specifications/pypirc pypirc379520
+Ref: f8379520
+Ref: specifications/pypirc the-pypirc-file379520
+Ref: 209379520
+Ref: The pypirc file-Footnote-1381175
+Node: Common configurations381217
+Ref: specifications/pypirc common-configurations381304
+Ref: 20a381304
+Ref: specifications/pypirc keyring381304
+Ref: 20b381304
+Node: Using a PyPI token382192
+Ref: specifications/pypirc using-a-pypi-token382318
+Ref: 20d382318
+Ref: Using a PyPI token-Footnote-1382667
+Node: Using another package index382707
+Ref: specifications/pypirc api-token382833
+Ref: 20e382833
+Ref: specifications/pypirc using-another-package-index382833
+Ref: 20f382833
+Ref: Using another package index-Footnote-1383949
+Node: Simple repository API383991
+Ref: specifications/simple-repository-api doc384111
+Ref: 210384111
+Ref: specifications/simple-repository-api id1384111
+Ref: 211384111
+Ref: specifications/simple-repository-api simple-repository-api384111
+Ref: 212384111
+Ref: Simple repository API-Footnote-1384439
+Ref: Simple repository API-Footnote-2384488
+Node: Project Summaries384537
+Ref: key_projects doc384653
+Ref: 213384653
+Ref: key_projects project-summaries384653
+Ref: 214384653
+Ref: key_projects projects384653
+Ref: 215384653
+Node: PyPA Projects384877
+Ref: key_projects id1384984
+Ref: 216384984
+Ref: key_projects pypa-projects384984
+Ref: 217384984
+Node: bandersnatch385298
+Ref: key_projects bandersnatch385388
+Ref: 218385388
+Ref: key_projects id2385388
+Ref: 219385388
+Ref: bandersnatch-Footnote-1385852
+Ref: bandersnatch-Footnote-2385914
+Ref: bandersnatch-Footnote-3386001
+Ref: bandersnatch-Footnote-4386053
+Ref: bandersnatch-Footnote-5386098
+Ref: bandersnatch-Footnote-6386144
+Node: build386207
+Ref: key_projects build386313
+Ref: 21a386313
+Ref: key_projects id4386313
+Ref: 21b386313
+Ref: build-Footnote-1386584
+Ref: build-Footnote-2386627
+Ref: build-Footnote-3386672
+Ref: build-Footnote-4386710
+Ref: build-Footnote-5386749
+Ref: build-Footnote-6386804
+Node: distlib386863
+Ref: key_projects distlib386966
+Ref: 21c386966
+Ref: key_projects id5386966
+Ref: 21d386966
+Ref: distlib-Footnote-1387935
+Ref: distlib-Footnote-2387976
+Ref: distlib-Footnote-3388038
+Ref: distlib-Footnote-4388125
+Ref: distlib-Footnote-5388198
+Ref: distlib-Footnote-6388241
+Node: packaging388282
+Ref: key_projects id7388383
+Ref: 21f388383
+Ref: key_projects packaging388383
+Ref: 21e388383
+Ref: packaging-Footnote-1389527
+Ref: packaging-Footnote-2389561
+Ref: packaging-Footnote-3389634
+Ref: packaging-Footnote-4389683
+Ref: packaging-Footnote-5389725
+Ref: packaging-Footnote-6389768
+Ref: packaging-Footnote-7389823
+Node: pip389882
+Ref: key_projects id8389982
+Ref: 220389982
+Ref: key_projects pip389982
+Ref: 2b389982
+Ref: pip-Footnote-1390506
+Ref: pip-Footnote-2390545
+Ref: pip-Footnote-3390602
+Ref: pip-Footnote-4390746
+Ref: pip-Footnote-5390819
+Ref: pip-Footnote-6390862
+Ref: pip-Footnote-7390898
+Ref: pip-Footnote-8390936
+Ref: pip-Footnote-9390991
+Node: Pipenv391050
+Ref: key_projects id10391148
+Ref: 221391148
+Ref: key_projects pipenv391148
+Ref: 36391148
+Ref: Pipenv-Footnote-1391913
+Ref: Pipenv-Footnote-2391945
+Ref: Pipenv-Footnote-3391984
+Ref: Pipenv-Footnote-4392030
+Node: Pipfile392070
+Ref: key_projects id11392195
+Ref: 222392195
+Ref: key_projects pipfile392195
+Ref: 51392195
+Ref: Pipfile-Footnote-1392434
+Node: Python Packaging User Guide<2>392474
+Ref: key_projects python-packaging-user-guide392608
+Ref: 223392608
+Ref: Python Packaging User Guide<2>-Footnote-1392820
+Ref: Python Packaging User Guide<2>-Footnote-2392868
+Ref: Python Packaging User Guide<2>-Footnote-3392930
+Ref: Python Packaging User Guide<2>-Footnote-4392997
+Ref: Python Packaging User Guide<2>-Footnote-5393057
+Ref: Python Packaging User Guide<2>-Footnote-6393112
+Node: readme_renderer393171
+Ref: key_projects id12393308
+Ref: 224393308
+Ref: key_projects readme-renderer393308
+Ref: 225393308
+Ref: key_projects setuptools393737
+Ref: 2d393737
+Ref: readme_renderer-Footnote-1393775
+Ref: readme_renderer-Footnote-2393824
+Node: setuptools393874
+Ref: key_projects easy-install393998
+Ref: 18b393998
+Ref: key_projects id13393998
+Ref: 226393998
+Ref: setuptools-Footnote-1394590
+Ref: setuptools-Footnote-2394643
+Ref: setuptools-Footnote-3394705
+Ref: setuptools-Footnote-4394792
+Ref: setuptools-Footnote-5394865
+Ref: setuptools-Footnote-6394915
+Ref: setuptools-Footnote-7394958
+Ref: setuptools-Footnote-8395002
+Ref: setuptools-Footnote-9395057
+Ref: setuptools-Footnote-10395116
+Node: trove-classifiers395161
+Ref: key_projects id15395275
+Ref: 227395275
+Ref: key_projects trove-classifiers395275
+Ref: 228395275
+Ref: trove-classifiers-Footnote-1396149
+Ref: trove-classifiers-Footnote-2396206
+Ref: trove-classifiers-Footnote-3396256
+Ref: trove-classifiers-Footnote-4396308
+Ref: trove-classifiers-Footnote-5396346
+Ref: trove-classifiers-Footnote-6396438
+Ref: trove-classifiers-Footnote-7396476
+Node: twine396533
+Ref: key_projects id16396650
+Ref: 229396650
+Ref: key_projects twine396650
+Ref: 66396650
+Ref: twine-Footnote-1397113
+Ref: twine-Footnote-2397161
+Ref: twine-Footnote-3397223
+Ref: twine-Footnote-4397310
+Ref: twine-Footnote-5397355
+Ref: twine-Footnote-6397393
+Node: virtualenv<2>397432
+Ref: key_projects id18397541
+Ref: 22a397541
+Ref: key_projects virtualenv397541
+Ref: 32397541
+Ref: virtualenv<2>-Footnote-1398203
+Ref: virtualenv<2>-Footnote-2398249
+Ref: virtualenv<2>-Footnote-3398306
+Ref: virtualenv<2>-Footnote-4398379
+Ref: virtualenv<2>-Footnote-5398429
+Ref: virtualenv<2>-Footnote-6398472
+Ref: virtualenv<2>-Footnote-7398517
+Ref: virtualenv<2>-Footnote-8398572
+Node: Warehouse398631
+Ref: key_projects id19398740
+Ref: 22c398740
+Ref: key_projects warehouse398740
+Ref: 22d398740
+Ref: Warehouse-Footnote-1399042
+Ref: Warehouse-Footnote-2399077
+Ref: Warehouse-Footnote-3399139
+Ref: Warehouse-Footnote-4399226
+Ref: Warehouse-Footnote-5399275
+Ref: Warehouse-Footnote-6399317
+Ref: Warehouse-Footnote-7399376
+Node: wheel399402
+Ref: key_projects id21399489
+Ref: 22e399489
+Ref: key_projects wheel399489
+Ref: 2e399489
+Ref: wheel-Footnote-1400208
+Ref: wheel-Footnote-2400256
+Ref: wheel-Footnote-3400318
+Ref: wheel-Footnote-4400405
+Ref: wheel-Footnote-5400450
+Ref: wheel-Footnote-6400488
+Ref: wheel-Footnote-7400527
+Ref: wheel-Footnote-8400582
+Ref: wheel-Footnote-9400641
+Node: Non-PyPA Projects400684
+Ref: key_projects non-pypa-projects400825
+Ref: 22f400825
+Node: bento401114
+Ref: key_projects bento401204
+Ref: 230401204
+Ref: key_projects id23401204
+Ref: 231401204
+Ref: bento-Footnote-1401552
+Ref: bento-Footnote-2401593
+Ref: bento-Footnote-3401636
+Ref: bento-Footnote-4401685
+Ref: bento-Footnote-5401727
+Node: buildout401766
+Ref: key_projects buildout401870
+Ref: 80401870
+Ref: key_projects id24401870
+Ref: 232401870
+Ref: buildout-Footnote-1402258
+Ref: buildout-Footnote-2402301
+Ref: buildout-Footnote-3402363
+Ref: buildout-Footnote-4402450
+Ref: buildout-Footnote-5402497
+Ref: buildout-Footnote-6402542
+Ref: buildout-Footnote-7402588
+Node: conda402647
+Ref: key_projects conda402751
+Ref: 83402751
+Ref: key_projects id26402751
+Ref: 233402751
+Ref: conda-Footnote-1403814
+Ref: conda-Footnote-2403852
+Ref: conda-Footnote-3403896
+Ref: conda-Footnote-4403938
+Node: devpi404046
+Ref: key_projects devpi404146
+Ref: 234404146
+Ref: key_projects id27404146
+Ref: 235404146
+Ref: devpi-Footnote-1404493
+Ref: devpi-Footnote-2404530
+Ref: devpi-Footnote-3404588
+Ref: devpi-Footnote-4404637
+Node: flit404676
+Ref: key_projects flit404778
+Ref: 6a404778
+Ref: key_projects id28404778
+Ref: 236404778
+Ref: flit-Footnote-1405455
+Ref: flit-Footnote-2405502
+Ref: flit-Footnote-3405551
+Ref: flit-Footnote-4405589
+Node: enscons405650
+Ref: key_projects enscons405755
+Ref: 237405755
+Ref: key_projects id29405755
+Ref: 238405755
+Ref: enscons-Footnote-1406395
+Ref: enscons-Footnote-2406444
+Ref: enscons-Footnote-3406496
+Ref: enscons-Footnote-4406537
+Node: Hashdist406563
+Ref: key_projects hashdist406669
+Ref: 82406669
+Ref: key_projects id30406669
+Ref: 239406669
+Ref: Hashdist-Footnote-1407279
+Ref: Hashdist-Footnote-2407330
+Node: hatch407376
+Ref: key_projects hatch407478
+Ref: 20c407478
+Ref: key_projects id31407478
+Ref: 23a407478
+Ref: hatch-Footnote-1407936
+Ref: hatch-Footnote-2407974
+Node: pex408013
+Ref: key_projects id32408111
+Ref: 23b408111
+Ref: key_projects pex408111
+Ref: 23c408111
+Ref: pex-Footnote-1408561
+Ref: pex-Footnote-2408607
+Ref: pex-Footnote-3408650
+Node: pipx408687
+Ref: key_projects id33408789
+Ref: 23d408789
+Ref: key_projects pipx408789
+Ref: 23e408789
+Ref: pipx-Footnote-1408957
+Ref: pipx-Footnote-2409001
+Ref: pipx-Footnote-3409045
+Node: pip-tools409084
+Ref: key_projects id34409191
+Ref: 23f409191
+Ref: key_projects pip-tools409191
+Ref: 240409191
+Ref: pip-tools-Footnote-1409818
+Ref: pip-tools-Footnote-2409865
+Node: piwheels409909
+Ref: key_projects id35410018
+Ref: 241410018
+Ref: key_projects piwheels410018
+Ref: 242410018
+Ref: piwheels-Footnote-1410421
+Ref: piwheels-Footnote-2410455
+Ref: piwheels-Footnote-3410496
+Node: poetry410542
+Ref: key_projects id36410652
+Ref: 243410652
+Ref: key_projects poetry410652
+Ref: 244410652
+Ref: poetry-Footnote-1411159
+Ref: poetry-Footnote-2411194
+Ref: poetry-Footnote-3411242
+Node: pypiserver411283
+Ref: key_projects id37411397
+Ref: 245411397
+Ref: key_projects pypiserver411397
+Ref: 246411397
+Ref: pypiserver-Footnote-1411910
+Ref: pypiserver-Footnote-2411982
+Ref: pypiserver-Footnote-3412031
+Node: scikit-build412076
+Ref: key_projects id38412188
+Ref: 247412188
+Ref: key_projects scikit-build412188
+Ref: 248412188
+Ref: scikit-build-Footnote-1412805
+Ref: scikit-build-Footnote-2412860
+Ref: scikit-build-Footnote-3412921
+Ref: scikit-build-Footnote-4412975
+Ref: scikit-build-Footnote-5413021
+Ref: scikit-build-Footnote-6413060
+Node: shiv413099
+Ref: key_projects id39413209
+Ref: 249413209
+Ref: key_projects shiv413209
+Ref: 24a413209
+Ref: shiv-Footnote-1413548
+Ref: shiv-Footnote-2413595
+Ref: shiv-Footnote-3413636
+Ref: shiv-Footnote-4413675
+Node: Spack<2>413724
+Ref: key_projects id40413835
+Ref: 24b413835
+Ref: key_projects spack413835
+Ref: 81413835
+Ref: Spack<2>-Footnote-1414505
+Ref: Spack<2>-Footnote-2414543
+Ref: Spack<2>-Footnote-3414582
+Ref: Spack<2>-Footnote-4414660
+Node: zest releaser414729
+Ref: key_projects zest-releaser414827
+Ref: 24c414827
+Ref: key_projects zestreleaser414827
+Ref: 24d414827
+Ref: zest releaser-Footnote-1415235
+Ref: zest releaser-Footnote-2415290
+Ref: zest releaser-Footnote-3415345
+Node: Standard Library Projects415393
+Ref: key_projects standard-library-projects415512
+Ref: 24e415512
+Node: ensurepip415620
+Ref: key_projects ensurepip415723
+Ref: 7e415723
+Ref: key_projects id41415723
+Ref: 24f415723
+Ref: ensurepip-Footnote-1416094
+Ref: ensurepip-Footnote-2416151
+Node: distutils416182
+Ref: key_projects distutils416298
+Ref: c0416298
+Ref: key_projects id42416298
+Ref: 250416298
+Ref: distutils-Footnote-1417050
+Ref: distutils-Footnote-2417107
+Ref: distutils-Footnote-3417169
+Ref: distutils-Footnote-4417256
+Ref: distutils-Footnote-5417287
+Ref: distutils-Footnote-6417342
+Node: venv417401
+Ref: key_projects id44417499
+Ref: 251417499
+Ref: key_projects venv417499
+Ref: 7f417499
+Ref: venv-Footnote-1417845
+Ref: venv-Footnote-2417897
+Node: Glossary417928
+Ref: glossary doc418043
+Ref: 252418043
+Ref: glossary distribute418043
+Ref: 253418043
+Ref: glossary glossary418043
+Ref: 254418043
+Ref: glossary term-binary-distribution418066
+Ref: 194418066
+Ref: glossary term-built-distribution418180
+Ref: 63418180
+Ref: glossary term-distribution-package418685
+Ref: b418685
+Ref: glossary term-egg419456
+Ref: 7c419456
+Ref: glossary term-extension-module419678
+Ref: 257419678
+Ref: glossary term-known-good-set-kgs420094
+Ref: 258420094
+Ref: glossary term-import-package420461
+Ref: a420461
+Ref: glossary term-module420848
+Ref: 255420848
+Ref: glossary term-package-index420999
+Ref: ec420999
+Ref: glossary term-per-project-index421133
+Ref: 25a421133
+Ref: glossary term-project421346
+Ref: 1fc421346
+Ref: glossary term-pure-module422486
+Ref: 259422486
+Ref: glossary term-python-packaging-authority-pypa422652
+Ref: 25d422652
+Ref: glossary term-python-package-index-pypi422991
+Ref: 39422991
+Ref: glossary term-pypi-org423194
+Ref: 161423194
+Ref: glossary term-pyproject-toml423414
+Ref: 1d7423414
+Ref: glossary term-release423523
+Ref: 256423523
+Ref: glossary term-requirement423903
+Ref: 25e423903
+Ref: glossary term-requirement-specifier424197
+Ref: 3a424197
+Ref: glossary term-requirements-file424608
+Ref: 25f424608
+Ref: glossary term-setup-py424817
+Ref: 25b424817
+Ref: glossary term-setup-cfg424827
+Ref: 25c424827
+Ref: glossary term-source-archive424969
+Ref: 62424969
+Ref: glossary term-source-distribution-or-sdist425156
+Ref: 3d425156
+Ref: glossary term-system-package425457
+Ref: 260425457
+Ref: glossary term-version-specifier425573
+Ref: 3b425573
+Ref: glossary term-virtual-environment425933
+Ref: 22b425933
+Ref: glossary term-wheel426204
+Ref: d426204
+Ref: glossary term-working-set426397
+Ref: 261426397
+Ref: Glossary-Footnote-1426681
+Ref: Glossary-Footnote-2426762
+Ref: Glossary-Footnote-3426821
+Ref: Glossary-Footnote-4426870
+Ref: Glossary-Footnote-5426902
+Ref: Glossary-Footnote-6426937
+Ref: Glossary-Footnote-7427010
+Ref: Glossary-Footnote-8427057
+Ref: Glossary-Footnote-9427082
+Ref: Glossary-Footnote-10427107
+Ref: Glossary-Footnote-11427157
+Ref: Glossary-Footnote-12427231
+Ref: Glossary-Footnote-13427324
+Ref: Glossary-Footnote-14427394
+Ref: Glossary-Footnote-15427444
+Ref: Glossary-Footnote-16427513
+Ref: Glossary-Footnote-17427563
+Node: How to Get Support427624
+Ref: support doc427746
+Ref: 262427746
+Ref: support how-to-get-support427746
+Ref: 263427746
+Ref: How to Get Support-Footnote-1428009
+Node: Contribute to this guide428071
+Ref: contribute doc428189
+Ref: 264428189
+Ref: contribute contribute-to-this-guide428189
+Ref: 265428189
+Ref: Contribute to this guide-Footnote-1429018
+Ref: Contribute to this guide-Footnote-2429079
+Ref: Contribute to this guide-Footnote-3429146
+Ref: Contribute to this guide-Footnote-4429212
+Node: Documentation types429281
+Ref: contribute documentation-types429410
+Ref: 267429410
+Ref: contribute id4429410
+Ref: 268429410
+Node: Tutorials<2>429744
+Ref: contribute tutorials429844
+Ref: 269429844
+Ref: Tutorials<2>-Footnote-1430134
+Node: Guides<2>430188
+Ref: contribute example-tutorial-style-document430311
+Ref: 26a430311
+Ref: contribute guides430311
+Ref: 26b430311
+Node: Discussions<2>430694
+Ref: contribute discussions430819
+Ref: 26c430819
+Node: Specifications431027
+Ref: contribute specifications431134
+Ref: 26d431134
+Node: Building the guide locally431379
+Ref: contribute building-the-guide-locally431544
+Ref: 26e431544
+Ref: Building the guide locally-Footnote-1432612
+Ref: Building the guide locally-Footnote-2432658
+Node: Where the guide is deployed432728
+Ref: contribute where-the-guide-is-deployed432885
+Ref: 26f432885
+Node: Style guide433149
+Ref: contribute contributing-style-guide433271
+Ref: 266433271
+Ref: contribute style-guide433271
+Ref: 270433271
+Node: Purpose433698
+Ref: contribute purpose433781
+Ref: 271433781
+Node: Scope433971
+Ref: contribute scope434071
+Ref: 272434071
+Node: Audience434556
+Ref: contribute audience434663
+Ref: 273434663
+Node: Voice and tone435177
+Ref: contribute voice-and-tone435304
+Ref: 274435304
+Node: Conventions and mechanics436427
+Ref: contribute conventions-and-mechanics436537
+Ref: 275436537
+Node: News438731
+Ref: news doc438842
+Ref: 276438842
+Ref: news news438842
+Ref: 277438842
+Node: September 2019439381
+Ref: news september-2019439470
+Ref: 278439470
+Ref: September 2019-Footnote-1439629
+Node: August 2019439691
+Ref: news august-2019439798
+Ref: 279439798
+Ref: August 2019-Footnote-1439943
+Node: July 2019440005
+Ref: news july-2019440107
+Ref: 27a440107
+Ref: July 2019-Footnote-1440509
+Ref: July 2019-Footnote-2440571
+Ref: July 2019-Footnote-3440633
+Ref: July 2019-Footnote-4440695
+Ref: July 2019-Footnote-5440757
+Node: June 2019440819
+Ref: news june-2019440918
+Ref: 27b440918
+Ref: June 2019-Footnote-1441023
+Node: May 2019441085
+Ref: news may-2019441185
+Ref: 27c441185
+Ref: May 2019-Footnote-1441379
+Ref: May 2019-Footnote-2441441
+Node: April 2019441503
+Ref: news april-2019441604
+Ref: 27d441604
+Ref: April 2019-Footnote-1441810
+Ref: April 2019-Footnote-2441872
+Node: March 2019441934
+Ref: news march-2019442040
+Ref: 27e442040
+Ref: March 2019-Footnote-1442248
+Ref: March 2019-Footnote-2442310
+Node: February 2019442372
+Ref: news february-2019442480
+Ref: 27f442480
+Ref: February 2019-Footnote-1442744
+Ref: February 2019-Footnote-2442806
+Node: January 2019442868
+Ref: news january-2019442979
+Ref: 280442979
+Ref: January 2019-Footnote-1443216
+Ref: January 2019-Footnote-2443278
+Ref: January 2019-Footnote-3443340
+Node: December 2018443402
+Ref: news december-2018443513
+Ref: 281443513
+Node: November 2018443590
+Ref: news november-2018443701
+Ref: 282443701
+Ref: November 2018-Footnote-1444035
+Ref: November 2018-Footnote-2444097
+Ref: November 2018-Footnote-3444159
+Ref: November 2018-Footnote-4444221
+Node: October 2018444283
+Ref: news october-2018444395
+Ref: 283444395
+Ref: October 2018-Footnote-1444575
+Ref: October 2018-Footnote-2444637
+Node: September 2018444699
+Ref: news september-2018444809
+Ref: 284444809
+Ref: September 2018-Footnote-1445196
+Ref: September 2018-Footnote-2445258
+Ref: September 2018-Footnote-3445320
+Ref: September 2018-Footnote-4445382
+Ref: September 2018-Footnote-5445444
+Node: August 2018445506
+Ref: news august-2018445613
+Ref: 285445613
+Ref: August 2018-Footnote-1445997
+Ref: August 2018-Footnote-2446059
+Ref: August 2018-Footnote-3446121
+Ref: August 2018-Footnote-4446183
+Node: July 2018446245
+Ref: news july-2018446347
+Ref: 286446347
+Ref: July 2018-Footnote-1446524
+Ref: July 2018-Footnote-2446586
+Node: June 2018446648
+Ref: news june-2018446747
+Ref: 287446747
+Ref: June 2018-Footnote-1446944
+Ref: June 2018-Footnote-2447006
+Node: May 2018447068
+Ref: news may-2018447168
+Ref: 288447168
+Ref: May 2018-Footnote-1447753
+Ref: May 2018-Footnote-2447815
+Ref: May 2018-Footnote-3447877
+Ref: May 2018-Footnote-4447939
+Ref: May 2018-Footnote-5448001
+Ref: May 2018-Footnote-6448063
+Ref: May 2018-Footnote-7448125
+Node: April 2018448187
+Ref: news april-2018448288
+Ref: 289448288
+Ref: April 2018-Footnote-1448797
+Ref: April 2018-Footnote-2448859
+Ref: April 2018-Footnote-3448921
+Ref: April 2018-Footnote-4448983
+Ref: April 2018-Footnote-5449045
+Ref: April 2018-Footnote-6449107
+Ref: April 2018-Footnote-7449169
+Node: March 2018449231
+Ref: news march-2018449337
+Ref: 28a449337
+Ref: March 2018-Footnote-1449698
+Ref: March 2018-Footnote-2449760
+Ref: March 2018-Footnote-3449822
+Ref: March 2018-Footnote-4449884
+Node: February 2018449946
+Ref: news february-2018450054
+Ref: 28b450054
+Ref: February 2018-Footnote-1450519
+Ref: February 2018-Footnote-2450581
+Ref: February 2018-Footnote-3450643
+Ref: February 2018-Footnote-4450705
+Ref: February 2018-Footnote-5450767
+Node: January 2018450829
+Ref: news january-2018450940
+Ref: 28c450940
+Ref: January 2018-Footnote-1451133
+Ref: January 2018-Footnote-2451195
+Node: December 2017451257
+Ref: news december-2017451368
+Ref: 28d451368
+Ref: December 2017-Footnote-1451696
+Ref: December 2017-Footnote-2451758
+Ref: December 2017-Footnote-3451820
+Ref: December 2017-Footnote-4451882
+Node: November 2017451944
+Ref: news november-2017452055
+Ref: 28e452055
+Ref: November 2017-Footnote-1452512
+Ref: November 2017-Footnote-2452574
+Ref: November 2017-Footnote-3452636
+Ref: November 2017-Footnote-4452698
+Node: October 2017452760
+Ref: news october-2017452872
+Ref: 28f452872
+Ref: October 2017-Footnote-1453207
+Ref: October 2017-Footnote-2453269
+Ref: October 2017-Footnote-3453331
+Node: September 2017453393
+Ref: news september-2017453503
+Ref: 290453503
+Ref: September 2017-Footnote-1453744
+Ref: September 2017-Footnote-2453806
+Node: August 2017453868
+Ref: news august-2017453975
+Ref: 291453975
+Ref: August 2017-Footnote-1454271
+Ref: August 2017-Footnote-2454333
+Ref: August 2017-Footnote-3454395
+Node: July 2017454457
+Ref: news july-2017454559
+Ref: 292454559
+Ref: July 2017-Footnote-1455074
+Ref: July 2017-Footnote-2455136
+Ref: July 2017-Footnote-3455198
+Ref: July 2017-Footnote-4455260
+Ref: July 2017-Footnote-5455322
+Node: June 2017455384
+Ref: news june-2017455483
+Ref: 293455483
+Ref: June 2017-Footnote-1456267
+Ref: June 2017-Footnote-2456329
+Ref: June 2017-Footnote-3456391
+Ref: June 2017-Footnote-4456453
+Ref: June 2017-Footnote-5456515
+Ref: June 2017-Footnote-6456577
+Ref: June 2017-Footnote-7456639
+Ref: June 2017-Footnote-8456701
+Ref: June 2017-Footnote-9456763
+Ref: June 2017-Footnote-10456825
+Ref: June 2017-Footnote-11456888
+Ref: June 2017-Footnote-12456951
+Node: May 2017457014
+Ref: news may-2017457114
+Ref: 294457114
+Ref: May 2017-Footnote-1457437
+Ref: May 2017-Footnote-2457499
+Ref: May 2017-Footnote-3457561
+Node: April 2017457623
+Ref: news april-2017457724
+Ref: 295457724
+Ref: April 2017-Footnote-1458759
+Ref: April 2017-Footnote-2458821
+Ref: April 2017-Footnote-3458883
+Ref: April 2017-Footnote-4458945
+Ref: April 2017-Footnote-5459007
+Ref: April 2017-Footnote-6459069
+Ref: April 2017-Footnote-7459131
+Ref: April 2017-Footnote-8459193
+Ref: April 2017-Footnote-9459255
+Ref: April 2017-Footnote-10459317
+Ref: April 2017-Footnote-11459380
+Node: March 2017459443
+Ref: news march-2017459549
+Ref: 296459549
+Ref: March 2017-Footnote-1459687
+Node: February 2017459749
+Ref: news february-2017459836
+Ref: 297459836
+Ref: February 2017-Footnote-1460253
+Ref: February 2017-Footnote-2460302
+Ref: February 2017-Footnote-3460364
+Ref: February 2017-Footnote-4460424
+Node: Get started460448
+Ref: index get-started460545
+Ref: 298460545
+Ref: index python-packaging-authority460545
+Ref: 299460545
+Node: Learn more461212
+Ref: index learn-more461310
+Ref: 29a461310
+Node: Index461988
+
+End Tag Table
+
+
+Local Variables:
+coding: utf-8
+End: