summaryrefslogtreecommitdiff
path: root/docs/userguide
diff options
context:
space:
mode:
Diffstat (limited to 'docs/userguide')
-rw-r--r--docs/userguide/declarative_config.rst15
-rw-r--r--docs/userguide/dependency_management.rst248
-rw-r--r--docs/userguide/development_mode.rst6
-rw-r--r--docs/userguide/entry_point.rst4
-rw-r--r--docs/userguide/package_discovery.rst114
-rw-r--r--docs/userguide/quickstart.rst55
6 files changed, 261 insertions, 181 deletions
diff --git a/docs/userguide/declarative_config.rst b/docs/userguide/declarative_config.rst
index bc66869b..7c97ca1c 100644
--- a/docs/userguide/declarative_config.rst
+++ b/docs/userguide/declarative_config.rst
@@ -184,7 +184,7 @@ maintainer_email maintainer-email str
classifiers classifier file:, list-comma
license str
license_file str
-license_files list-comma
+license_files list-comma 42.0.0
description summary file:, str
long_description long-description file:, str
long_description_content_type str 38.6.0
@@ -243,6 +243,19 @@ data_files dict 40.6.0
**find_namespace directive** - The ``find_namespace:`` directive is supported since Python >=3.3.
+
Notes:
1. In the ``package_data`` section, a key named with a single asterisk (``*``)
refers to all packages, in lieu of the empty string used in ``setup.py``.
+
+2. In the ``extras_require`` section, values are parsed as ``list-semi``. This implies that in
+order to include markers, they **must** be *dangling*:
+
+.. code-block:: ini
+
+ [options.extras_require]
+ rest = docutils>=0.3; pack ==1.1, ==1.3
+ pdf =
+ ReportLab>=1.2
+ RXP
+ importlib-metadata; python_version < "3.8"
diff --git a/docs/userguide/dependency_management.rst b/docs/userguide/dependency_management.rst
index 354a9f8c..188083e0 100644
--- a/docs/userguide/dependency_management.rst
+++ b/docs/userguide/dependency_management.rst
@@ -3,7 +3,7 @@ Dependencies Management in Setuptools
=====================================
There are three types of dependency styles offered by setuptools:
-1) build system requirement, required dependency and 3) optional
+1) build system requirement, 2) required dependency and 3) optional
dependency.
.. Note::
@@ -19,8 +19,8 @@ Build system requirement
Package requirement
-------------------
After organizing all the scripts and files and getting ready for packaging,
-there needs to be a way to tell Python what programs it need to actually
-do the packgaging (in our case, ``setuptools`` of course). Usually,
+there needs to be a way to tell Python what programs it needs to actually
+do the packaging (in our case, ``setuptools`` of course). Usually,
you also need the ``wheel`` package as well since it is recommended that you
upload a ``.whl`` file to PyPI alongside your ``.tar.gz`` file. Unlike the
other two types of dependency keyword, this one is specified in your
@@ -47,32 +47,36 @@ Declaring required dependency
This is where a package declares its core dependencies, without which it won't
be able to run. ``setuptools`` support automatically download and install
these dependencies when the package is installed. Although there is more
-finess to it, let's start with a simple example.
+finesse to it, let's start with a simple example.
-.. code-block:: ini
+.. tab:: setup.cfg
- [options]
- #...
- install_requires =
- docutils
- BazSpam ==1.1
+ .. code-block:: ini
+
+ [options]
+ #...
+ install_requires =
+ docutils
+ BazSpam ==1.1
+
+.. tab:: setup.py
-.. code-block:: python
+ .. code-block:: python
- setup(
- #...,
- install_requires = [
- 'docutils',
- 'BazSpam ==1.1'
- ]
- )
+ setup(
+ #...,
+ install_requires = [
+ 'docutils',
+ 'BazSpam ==1.1'
+ ]
+ )
When your project is installed (e.g. using pip), all of the dependencies not
already installed will be located (via PyPI), downloaded, built (if necessary),
and installed and 2) Any scripts in your project will be installed with wrappers
that verify the availability of the specified dependencies at runtime.
-
+
Platform specific dependencies
------------------------------
@@ -82,41 +86,49 @@ specific dependencies. For example, the ``enum`` package was added in Python
3.4, therefore, package that depends on it can elect to install it only when
the Python version is older than 3.4. To accomplish this
-.. code-block:: ini
+.. tab:: setup.cfg
- [options]
- #...
- install_requires =
- enum34;python_version<'3.4'
+ .. code-block:: ini
-.. code-block:: python
-
- setup(
+ [options]
#...
- install_requires=[
- "enum34;python_version<'3.4'",]
- )
+ install_requires =
+ enum34;python_version<'3.4'
+
+.. tab:: setup.py
+
+ .. code-block:: python
+
+ setup(
+ #...
+ install_requires=[
+ "enum34;python_version<'3.4'",]
+ )
Similarly, if you also wish to declare ``pywin32`` with a minimal version of 1.0
and only install it if the user is using a Windows operating system:
-.. code-block:: ini
-
- [options]
- #...
- install_requires =
- enum34;python_version<'3.4'
- pywin32 >= 1.0;platform_system=='Windows'
+.. tab:: setup.cfg
-.. code-block:: python
+ .. code-block:: ini
- setup(
+ [options]
#...
- install_requires=[
- "enum34;python_version<'3.4'",
- "pywin32 >= 1.0;platform_system=='Windows'"
- ]
- )
+ install_requires =
+ enum34;python_version<'3.4'
+ pywin32 >= 1.0;platform_system=='Windows'
+
+.. tab:: setup.py
+
+ .. code-block:: python
+
+ setup(
+ #...
+ install_requires=[
+ "enum34;python_version<'3.4'",
+ "pywin32 >= 1.0;platform_system=='Windows'"
+ ]
+ )
The environmental markers that may be used for testing platform types are
detailed in `PEP 508 <https://www.python.org/dev/peps/pep-0508/>`_.
@@ -181,20 +193,24 @@ The ``dependency_links`` option takes the form of a list of URL strings. For
example, this will cause a search of the specified page for eggs or source
distributions, if the package's dependencies aren't already installed:
-.. code-block:: ini
-
- [options]
- #...
- dependency_links = http://peak.telecommunity.com/snapshots/
+.. tab:: setup.cfg
-.. code-block:: python
+ .. code-block:: ini
- setup(
+ [options]
#...
- dependency_links=[
- "http://peak.telecommunity.com/snapshots/"
- ],
- )
+ dependency_links = http://peak.telecommunity.com/snapshots/
+
+.. tab:: setup.py
+
+ .. code-block:: python
+
+ setup(
+ #...
+ dependency_links=[
+ "http://peak.telecommunity.com/snapshots/"
+ ],
+ )
Optional dependencies
@@ -202,7 +218,7 @@ Optional dependencies
Setuptools allows you to declare dependencies that only get installed under
specific circumstances. These dependencies are specified with ``extras_require``
keyword and are only installed if another package depends on it (either
-directly or indirectly) This makes it convenient to declare dependencies for
+directly or indirectly) This makes it convenient to declare dependencies for
ancillary functions such as "tests" and "docs".
.. note::
@@ -211,24 +227,28 @@ ancillary functions such as "tests" and "docs".
For example, Package-A offers optional PDF support and requires two other
dependencies for it to work:
-.. code-block:: ini
+.. tab:: setup.cfg
- [metadata]
- name = Package-A
+ .. code-block:: ini
- [options.extras_require]
- PDF = ReportLab>=1.2; RXP
+ [metadata]
+ name = Package-A
+ [options.extras_require]
+ PDF = ReportLab>=1.2; RXP
-.. code-block:: python
- setup(
- name="Project-A",
- #...
- extras_require={
- "PDF": ["ReportLab>=1.2", "RXP"],
- }
- )
+.. tab:: setup.py
+
+ .. code-block:: python
+
+ setup(
+ name="Project-A",
+ #...
+ extras_require={
+ "PDF": ["ReportLab>=1.2", "RXP"],
+ }
+ )
The name ``PDF`` is an arbitary identifier of such a list of dependencies, to
which other components can refer and have them installed. There are two common
@@ -236,57 +256,69 @@ use cases.
First is the console_scripts entry point:
-.. code-block:: ini
+.. tab:: setup.cfg
- [metadata]
- name = Project A
- #...
+ .. code-block:: ini
- [options]
- #...
- entry_points=
- [console_scripts]
- rst2pdf = project_a.tools.pdfgen [PDF]
- rst2html = project_a.tools.htmlgen
-
-.. code-block:: python
-
- setup(
- name = "Project-A"
- #...,
- entry_points={
- "console_scripts": [
- "rst2pdf = project_a.tools.pdfgen [PDF]",
- "rst2html = project_a.tools.htmlgen",
- ],
- }
- )
+ [metadata]
+ name = Project A
+ #...
-When the script ``rst2pdf`` is run, it will trigger the installation of
-the two dependencies ``PDF`` maps to.
+ [options]
+ #...
+ entry_points=
+ [console_scripts]
+ rst2pdf = project_a.tools.pdfgen [PDF]
+ rst2html = project_a.tools.htmlgen
+
+.. tab:: setup.py
+
+ .. code-block:: python
+
+ setup(
+ name = "Project-A"
+ #...,
+ entry_points={
+ "console_scripts": [
+ "rst2pdf = project_a.tools.pdfgen [PDF]",
+ "rst2html = project_a.tools.htmlgen",
+ ],
+ }
+ )
+
+This syntax indicates that the entry point (in this case a console script)
+is only valid when the PDF extra is installed. It is up to the installer
+to determine how to handle the situation where PDF was not indicated
+(e.g. omit the console script, provide a warning when attempting to load
+the entry point, assume the extras are present and let the implementation
+fail later).
The second use case is that other package can use this "extra" for their
own dependencies. For example, if "Project-B" needs "project A" with PDF support
installed, it might declare the dependency like this:
-.. code-block:: ini
+.. tab:: setup.cfg
- [metadata]
- name = Project-B
- #...
+ .. code-block:: ini
- [options]
- #...
- install_requires =
- Project-A[PDF]
+ [metadata]
+ name = Project-B
+ #...
+
+ [options]
+ #...
+ install_requires =
+ Project-A[PDF]
+
+.. tab:: setup.py
-.. code-block:: python
+ .. code-block:: python
- setup(
- name="Project-B",
- install_requires=["Project-A[PDF]"],
- ...
- )
+ setup(
+ name="Project-B",
+ install_requires=["Project-A[PDF]"],
+ ...
+ )
This will cause ReportLab to be installed along with project A, if project B is
installed -- even if project A was already installed. In this way, a project
diff --git a/docs/userguide/development_mode.rst b/docs/userguide/development_mode.rst
index bce724a7..3c477ec1 100644
--- a/docs/userguide/development_mode.rst
+++ b/docs/userguide/development_mode.rst
@@ -3,9 +3,9 @@
Under normal circumstances, the ``distutils`` assume that you are going to
build a distribution of your project, not use it in its "raw" or "unbuilt"
-form. If you were to use the ``distutils`` that way, you would have to rebuild
-and reinstall your project every time you made a change to it during
-development.
+form. However, if you were to use the ``distutils`` to build a distribution,
+you would have to rebuild and reinstall your project every time you made a
+change to it during development.
Another problem that sometimes comes up with the ``distutils`` is that you may
need to do development on two related projects at the same time. You may need
diff --git a/docs/userguide/entry_point.rst b/docs/userguide/entry_point.rst
index edab4465..63d30a48 100644
--- a/docs/userguide/entry_point.rst
+++ b/docs/userguide/entry_point.rst
@@ -28,7 +28,7 @@ with ``__init__.py`` as:
.. code-block:: python
- def helloworld():
+ def hello_world():
print("Hello world")
and ``__main__.py`` providing a hook:
@@ -64,7 +64,7 @@ After installing the package, a user may invoke that function by simply calling
The syntax for entry points is specified as follows:
-.. code-block::
+.. code-block:: ini
<name> = [<package>.[<subpackage>.]]<module>[:<object>.<object>]
diff --git a/docs/userguide/package_discovery.rst b/docs/userguide/package_discovery.rst
index de4ef668..0a8070ae 100644
--- a/docs/userguide/package_discovery.rst
+++ b/docs/userguide/package_discovery.rst
@@ -19,36 +19,44 @@ Package Discovery and Namespace Package
support for namespace package. Normally, you would specify the package to be
included manually in the following manner:
-.. code-block:: ini
-
- [options]
- #...
- packages =
- mypkg1
- mypkg2
+.. tab:: setup.cfg
-.. code-block:: python
+ .. code-block:: ini
- setup(
+ [options]
#...
- packages = ['mypkg1', 'mypkg2']
- )
+ packages =
+ mypkg1
+ mypkg2
+
+.. tab:: setup.py
+
+ .. code-block:: python
+
+ setup(
+ #...
+ packages = ['mypkg1', 'mypkg2']
+ )
This can get tiresome reallly quickly. To speed things up, we introduce two
functions provided by setuptools:
-.. code-block:: ini
+.. tab:: setup.cfg
- [options]
- packages = find:
- #or
- packages = find_namespace:
+ .. code-block:: ini
-.. code-block:: python
+ [options]
+ packages = find:
+ #or
+ packages = find_namespace:
+
+.. tab:: setup.py
- from setuptools import find_packages
- #or
- from setuptools import find_namespace_packages
+ .. code-block:: python
+
+ from setuptools import find_packages
+ #or
+ from setuptools import find_namespace_packages
Using ``find:`` or ``find_packages``
@@ -71,30 +79,34 @@ it, consider the following directory
To have your setup.cfg or setup.py to automatically include packages found
in ``src`` that starts with the name ``pkg`` and not ``additional``:
-.. code-block:: ini
+.. tab:: setup.cfg
- [options]
- packages = find:
- package_dir =
- =src
+ .. code-block:: ini
- [options.packages.find]
- where = src
- include = pkg*
- exclude = additional
+ [options]
+ packages = find:
+ package_dir =
+ =src
-.. code-block:: python
+ [options.packages.find]
+ where = src
+ include = pkg*
+ exclude = additional
- setup(
- #...
- packages = find_packages(
- where = 'src',
- include = ['pkg*',],
- exclude = ['additional',]
- ),
- package_dir = {"":"src"}
- #...
- )
+.. tab:: setup.py
+
+ .. code-block:: python
+
+ setup(
+ #...
+ packages = find_packages(
+ where = 'src',
+ include = ['pkg*',],
+ exclude = ['additional',]
+ ),
+ package_dir = {"":"src"}
+ #...
+ )
.. _Namespace Packages:
@@ -144,7 +156,7 @@ to use ``find_namespace:``:
=src
packages = find_namespace:
- [options.packages.find_namespace]
+ [options.packages.find]
where = src
When you install the zipped distribution, ``timmins.foo`` would become
@@ -195,17 +207,21 @@ following:
And the ``namespace_packages`` keyword in your ``setup.cfg`` or ``setup.py``:
-.. code-block:: ini
+.. tab:: setup.cfg
- [options]
- namespace_packages = timmins
+ .. code-block:: ini
-.. code-block:: python
+ [options]
+ namespace_packages = timmins
+
+.. tab:: setup.py
+
+ .. code-block:: python
- setup(
- # ...
- namespace_packages = ['timmins']
- )
+ setup(
+ # ...
+ namespace_packages = ['timmins']
+ )
And your directory should look like this
diff --git a/docs/userguide/quickstart.rst b/docs/userguide/quickstart.rst
index 697087ed..2807f59b 100644
--- a/docs/userguide/quickstart.rst
+++ b/docs/userguide/quickstart.rst
@@ -21,7 +21,7 @@ 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 <517#build-requirements>`. To learn more about Python packaging in general,
+change is driven under :pep:`PEP 517 <517#build-requirements>`. To learn more about Python packaging in general,
navigate to the `bottom <Resources on python packaging>`_ of this page.
@@ -37,33 +37,52 @@ package your project:
requires = ["setuptools", "wheel"]
build-backend = "setuptools.build_meta"
-Then, you will need a ``setup.cfg`` to specify your package information,
-such as metadata, contents, dependencies, etc. Here we demonstrate the minimum
+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
-.. code-block:: ini
+.. tab:: setup.cfg
- [metadata]
- name = "mypackage"
- version = 0.0.1
+ .. code-block:: ini
- [options]
- packages = "mypackage"
- install_requires =
- requests
- importlib; python_version == "2.6"
+ [metadata]
+ name = mypackage
+ version = 0.0.1
+
+ [options]
+ packages = mypackage
+ install_requires =
+ requests
+ importlib; python_version == "2.6"
+
+.. tab:: setup.py
+
+ .. code-block:: python
+
+ from setuptools import setup
+
+ setup(
+ name='mypackage',
+ version='0.0.1',
+ packages=['mypackage'],
+ install_requires=[
+ 'requests',
+ 'importlib; python_version == "2.6"',
+ ],
+ )
This is what your project would look like::
~/mypackage/
pyproject.toml
- setup.cfg
+ setup.cfg # or setup.py
mypackage/__init__.py
-Then, you need an installer, such as `pep517 <https://pypi.org/project/pep517/>`_
-which you can obtain via ``pip install pep517``. After downloading it, invoke
-the installer::
+Then, you need an builder, such as :std:doc:`PyPA build <pypa-build:index>`
+which you can obtain via ``pip install build``. After downloading it, invoke
+the builder::
- python -m pep517.build
+ python -m build
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!
@@ -71,7 +90,7 @@ 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 section,
+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.