- setuptools Quickstart¶
- Installation¶
- Python packaging at a glance¶
- Basic Use¶
- Automatic package discovery¶
- Entry points and automatic script creation¶
- Dependency management¶
- Including Data Files¶
- Development mode¶
- Uploading your package to PyPI¶
- Transitioning from setup.py to setup.cfg ¶
- Resources on Python packaging¶
- Installing pip/setuptools/wheel with Linux Package Managers¶
- Fedora¶
- CentOS/RHEL¶
- distutils, setuptools, pip — Python: Настройка окружения
- distutils и setuptools
- Packaging and distributing projects¶
- Requirements for packaging and distributing¶
- Configuring your project¶
- Initial files¶
- setup.py¶
- setup.cfg¶
- README.rst / README.md¶
- MANIFEST.in¶
- LICENSE.txt¶
- setup() args¶
- version ¶
- description ¶
- author ¶
- license ¶
- classifiers ¶
- keywords ¶
- project_urls ¶
- packages ¶
- py_modules ¶
- install_requires ¶
- python_requires ¶
- package_data ¶
- data_files ¶
- scripts ¶
- entry_points ¶
- Choosing a versioning scheme¶
- Standards compliance for interoperability¶
- Scheme choices¶
- Pre-release versioning¶
- Local version identifiers¶
- Working in “development mode”¶
- Packaging your project¶
setuptools Quickstart¶
Installation¶
To install the latest version of setuptools, use:
Python packaging at a glance¶
The landscape of Python packaging is shifting and Setuptools has evolved to only provide backend support, no longer being the de-facto packaging tool in the market. All python package must provide a pyproject.toml and specify the backend (build system) it wants to use. The distribution can then be generated with whatever tools that provides a build sdist -alike functionality. While this may appear cumbersome, given the added pieces, it in fact tremendously enhances the portability of your package. The change is driven under PEP 517. To learn more about Python packaging in general, navigate to the bottom of this page.
Basic Use¶
For basic use of setuptools, you will need a pyproject.toml with the exact following info, which declares you want to use setuptools to package your project:
Then, you will need a setup.cfg or setup.py to specify your package information, such as metadata, contents, dependencies, etc. Here we demonstrate the minimum
This is what your project would look like:
Then, you need an builder, such as PyPA build which you can obtain via pip install build . After downloading it, invoke the builder:
You now have your distribution ready (e.g. a tar.gz file and a .whl file in the dist directory), which you can upload to PyPI!
Of course, before you release your project to PyPI, you’ll want to add a bit more information to your setup script to help people find or learn about your project. And maybe your project will have grown by then to include a few dependencies, and perhaps some data files and scripts. In the next few sections, we will walk through those additional but essential information you need to specify to properly package your project.
Automatic package discovery¶
For simple projects, it’s usually easy enough to manually add packages to the packages keyword in setup.cfg . However, for very large projects , it can be a big burden to keep the package list updated. setuptools therefore provides two convenient tools to ease the burden: find: and find_namespace: . To use it in your project:
When you pass the above information, alongside other necessary ones, setuptools walks through the directory specified in where (omitted here as the package reside in current directory) and filters the packages it can find following the include (default to none), then remove those that match the exclude and return a list of Python packages. Note that each entry in the [options.packages.find] is optional. The above setup also allows you to adopt a src/ layout. For more details and advanced use, go to Package Discovery and Namespace Package
Entry points and automatic script creation¶
Setuptools support automatic creation of scripts upon installation, that runs code within your package if you specify them with the entry_points keyword. This is what allows you to run commands like pip install instead of having to type python -m pip install . To accomplish this, add the entry_points keyword in your setup.cfg :
When this project is installed, a main script will be installed and will invoke the some_func in the __init__.py file when called by the user. For detailed usage, including managing the additional or optional dependencies, go to Entry Points .
Dependency management¶
setuptools supports automatically installing dependencies when a package is installed. The simplest way to include requirement specifiers is to use the install_requires argument to setup.cfg . It takes a string or list of strings containing requirement specifiers (A version specifier is one of the operators , =, == or !=, followed by a version identifier):
When your project is installed, all of the dependencies not already installed will be located (via PyPI), downloaded, built (if necessary), and installed. This, of course, is a simplified scenarios. setuptools also provide additional keywords such as setup_requires that allows you to install dependencies before running the script, and extras_requires that take care of those needed by automatically generated scripts. It also provides mechanisms to handle dependencies that are not in PyPI. For more advanced use, see Dependencies Management in Setuptools
Including Data Files¶
The distutils have traditionally allowed installation of “data files”, which are placed in a platform-specific location. Setuptools offers three ways to specify data files to be included in your packages. For the simplest use, you can simply use the include_package_data keyword:
This tells setuptools to install any data files it finds in your packages. The data files must be specified via the distutils’ MANIFEST.in file. For more details, see Data Files Support
Development mode¶
setuptools allows you to install a package without copying any files to your interpreter directory (e.g. the site-packages directory). This allows you to modify your source code and have the changes take effect without you having to rebuild and reinstall. This is currently incompatible with PEP 517 and therefore it requires a setup.py script with the following content:
This creates a link file in your interpreter site package directory which associate with your source code. For more information, see “Development Mode” .
Uploading your package to PyPI¶
After generating the distribution files, next step would be to upload your distribution so others can use it. This functionality is provided by twine and we will only demonstrate the basic use here.
Transitioning from setup.py to setup.cfg ¶
To avoid executing arbitrary scripts and boilerplate code, we are transitioning into a full-fledged setup.cfg to declare your package information instead of running setup() . This inevitably brings challenges due to a different syntax. Here we provide a quick guide to understanding how setup.cfg is parsed by setuptool to ease the pain of transition.
Resources on Python packaging¶
Packaging in Python is hard. Here we provide a list of links for those that want to learn more.
Источник
Installing pip/setuptools/wheel with Linux Package Managers¶
This section covers how to install pip , setuptools , and wheel using Linux package managers.
If you’re using a Python that was downloaded from python.org, then this section does not apply. See the Requirements for Installing Packages section instead.
Note that it’s common for the versions of pip , setuptools , and wheel 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.
Fedora¶
To learn more about Python in Fedora, please visit the official Fedora docs, Python Classroom or Fedora Loves Python.
CentOS/RHEL¶
CentOS and RHEL don’t offer pip or wheel in their core repositories, although setuptools is installed by default.
To install pip and wheel for the system Python, there are two options:
Enable the EPEL repository using these instructions. On EPEL 7, you can install pip and wheel like so:
Since EPEL only offers extra, non-conflicting packages, EPEL does not offer setuptools, since it’s in the core repository.
Enable the PyPA Copr Repo using these instructions 1. You can install pip and wheel like so:
To additionally upgrade setuptools, run:
To install pip, wheel, and setuptools, in a parallel, non-system environment (using yum) then there are two options:
Use the “Software Collections” feature to enable a parallel collection that includes pip, setuptools, and wheel.
Be aware that collections may not contain the most recent versions.
Enable the IUS repository and install one of the parallel-installable Pythons, along with pip, setuptools, and wheel, which are kept fairly up to date.
For example, for Python 3.4 on CentOS7/RHEL7:
Источник
distutils, setuptools, pip — Python: Настройка окружения
На прошлом уроке мы познакомились с пакетами и индексами, давайте же узнаем, как устанавливать пакеты из индекса! Для установки, обновления и удаления пакетов часто применяются так называемые пакетные менеджеры (или менеджеры пакетов). Один такой мы рассмотрим, но сначала немного поговорим о фундаменте системы пакетирования Python.
distutils и setuptools
В поставку Python входит distutils, пакет, отвечающий за создание дистрибутивов — архивов кода, которые могут быть распакованы в целевом окружении и установлены так, чтобы интерпретатор Python «увидел» распакованный код. При создании пакета программист создаёт в корневой директории будущего пакета файл setup.py в котором импортирует из модуля distutils функцию setup и вызывает её. Таким образом каждый пакет содержит в себе программу для управления собой!
Подробнее о том, как работает distutils, можно почитать в официальной документации к пакету, а мы сразу двинемся дальше. Дело в том, что пакет distutils появился довольно давно и сейчас сам по себе не очень удобен в использовании. Гораздо чаще используется надстройка над distutils, пакет setuptools.
Пакеты, собранные с помощью setuptools, уже умеют предоставлять metadata: описание, версию, и самое главное — собственные зависимости! Пакеты, которые не зависят ни от чего, кроме самого Python, настолько редки, что без setuptools — можно сказать, «жизни нет». Про этот пакет стоит знать и со временем нужно будет научиться его использовать (опять же, с помощью документации), но в рамках этого курса мы будем рассматривать более простой инструмент для создания пакетов и загрузки их в индекс — poetry, с которым мы познакомимся попозже.
Источник
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 Installing Packages 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 in the setuptools 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.
Requirements for packaging and distributing¶
First, make sure you have already fulfilled the requirements for installing packages .
You’ll need this to upload your project distributions to PyPI (see below ).
Configuring your project¶
Initial files¶
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 in the PyPA sample project.
setup.py serves two primary functions:
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 the section below .
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 .
setup.cfg¶
setup.cfg is an ini file that contains option defaults for setup.py commands. For an example, see the setup.cfg in the PyPA sample project.
README.rst / README.md¶
All projects should contain a readme file that covers the goal of the project. The most common format is reStructuredText with an “rst” extension, although this is not a requirement; multiple variants of Markdown are supported as well (look at setup() ’s long_description_content_type argument).
Projects using setuptools 0.6.27+ have standard readme files ( README.rst , README.txt , or README ) included in source distributions by default. The built-in distutils library adopts this behavior beginning in Python 3.7. Additionally, setuptools 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.
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 “ Including files in source distributions with MANIFEST.in ”.
For an example, see the MANIFEST.in from the PyPA sample project.
MANIFEST.in does not affect binary distributions such as wheels.
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 or consult a lawyer.
For an example, see the LICENSE.txt from the PyPA sample project.
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 name as your project, or something very close.
For an example, see the sample package that’s included in the PyPA sample project.
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 contained in the PyPA sample project.
This is the name of your project, determining how your project is listed on PyPI . Per PEP 508, 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:
version ¶
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 PyPI for each release if you publish your project.
See Choosing a versioning scheme 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 “ Single-sourcing the package version ” Advanced Topics section.
description ¶
Give a short and long description for your project.
These values will be displayed on PyPI 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 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), and the Github-flavored Markdown dialect of Markdown respectively.
Give a homepage URL for your project.
author ¶
Provide details about the author.
license ¶
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.
classifiers ¶
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 python_requires argument.
keywords ¶
List keywords that describe your project.
project_urls ¶
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.
packages ¶
Set packages to a list of all packages 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.
py_modules ¶
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 setuptools aware of them.
install_requires ¶
“install_requires” should be used to specify what dependencies a project minimally needs to run. When the project is installed by pip , this is the specification that is used to install its dependencies.
python_requires ¶
If your project only runs on certain Python versions, setting the python_requires argument to the appropriate PEP 440 version specifier string will prevent pip from installing the project on other Python versions. For example, if your package is for Python 3+ only, write:
If your package is for Python 2.6, 2.7, and all versions of Python 3 starting with 3.3, write:
Support for this feature is relatively recent. Your project’s source distributions and wheels (see Packaging your project ) must be built using at least version 24.2.0 of setuptools 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 pip 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.
package_data ¶
Often, additional files need to be installed into a package . 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.
data_files ¶
Although configuring package_data is sufficient for most needs, in some cases you may need to place data files outside of your packages . 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), 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 .
When installing packages as egg, data_files is not supported. So, if your project uses setuptools , 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.
scripts ¶
Although setup() supports a scripts keyword for pointing to pre-made scripts to install, the recommended approach to achieve cross-platform compatibility is to use console_scripts entry points (see below).
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 from the setuptools docs.
The most commonly used entry point is “console_scripts” (see below).
console_scripts ¶
Use console_script entry points 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 distribution .
Choosing a versioning scheme¶
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 specified in PEP 440 in order to be supported in tools and libraries like pip and setuptools .
Here are some examples of compliant version numbers:
To further accommodate historical variations in approaches to version numbering, PEP 440 also defines a comprehensive technique for version normalisation that maps variant spellings of different version numbers to a standardised canonical form.
Scheme choices¶
Semantic versioning (preferred)¶
For new projects, the recommended versioning scheme is based on Semantic Versioning, 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:
MAJOR version when they make incompatible API changes,
MINOR version when they add functionality in a backwards-compatible manner, and
MAINTENANCE version when they make backwards-compatible bug fixes.
Adopting this approach as a project author allows users to make use of “compatible release” 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.
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 ).
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.
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.
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.
Local version identifiers¶
Public version identifiers are designed to support distribution via PyPI . Python’s software distribution tools also support the notion of a local version identifier, 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
version identifier>+ version label> . For example:
Working in “development mode”¶
You can install a project in “editable” or “develop” mode while you’re working on it. When installed as editable, a project can be edited in-place without reinstallation: changes to Python source files in projects installed as editable will be reflected the next time an interpreter process is started.
To install a Python package in “editable”/”development” mode Change directory to the root of the project directory and run:
The pip command-line flag -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.
You may 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:
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:
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 section in the pip docs. For more on VCS installs, see the VCS Support section of the pip docs.
Lastly, if you don’t want to install any dependencies at all, you can run:
For more information, see the Development Mode section of the setuptools docs .
Packaging your project¶
To have your project installable from a Package Index like PyPI , you’ll need to create a Distribution (aka “ Package ”) for your project.
Before you can build wheels and sdists for your project, you’ll need to install the build package:
Источник