Skip to content

Commit

Permalink
Update quickstart to make it more streamline (#3378)
Browse files Browse the repository at this point in the history
  • Loading branch information
abravalheri committed Jun 16, 2022
2 parents 92ba2c8 + 8e9d323 commit d9e2390
Show file tree
Hide file tree
Showing 3 changed files with 109 additions and 63 deletions.
1 change: 1 addition & 0 deletions changelog.d/3378.doc.rst
@@ -0,0 +1 @@
Updated ``Quickstart`` docs to make it easier to follow for beginners.
16 changes: 8 additions & 8 deletions docs/conf.py
Expand Up @@ -92,7 +92,14 @@
}

intersphinx_mapping.update({
'pypa-build': ('https://pypa-build.readthedocs.io/en/latest/', None)
'pip': ('https://pip.pypa.io/en/latest', None),
'build': ('https://pypa-build.readthedocs.io/en/latest', None),
'PyPUG': ('https://packaging.python.org/en/latest/', None),
'packaging': ('https://packaging.pypa.io/en/latest/', None),
'twine': ('https://twine.readthedocs.io/en/stable/', None),
'importlib-resources': (
'https://importlib-resources.readthedocs.io/en/latest', None
),
})

# Add support for linking usernames
Expand Down Expand Up @@ -212,10 +219,3 @@
},
# rel="apple-touch-icon" does not support SVG yet
]

intersphinx_mapping['pip'] = 'https://pip.pypa.io/en/latest', None
intersphinx_mapping['PyPUG'] = ('https://packaging.python.org/en/latest/', None)
intersphinx_mapping['packaging'] = ('https://packaging.pypa.io/en/latest/', None)
intersphinx_mapping['importlib-resources'] = (
'https://importlib-resources.readthedocs.io/en/latest', None
)
155 changes: 100 additions & 55 deletions docs/userguide/quickstart.rst
Expand Up @@ -5,44 +5,66 @@ Quickstart
Installation
============

To install the latest version of setuptools, use::
You can install the latest version of ``setuptools`` using :pypi:`pip`::

pip install --upgrade setuptools

Most of the times, however, you don't have to...

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. Every python package must provide a ``pyproject.toml`` and specify
Instead, when creating new Python packages, it is recommended to use
a command line tool called :pypi:`build`. This tool will automatically download
``setuptools`` and any other build-time dependencies that your project might
have. You just need to specify them in a ``pyproject.toml`` file at the root of
your package, as indicated in the :ref:`following section <basic-use>`.

.. _install-build:

You can also :doc:`install build <build:installation>` using :pypi:`pip`::

pip install --upgrade build

This will allow you to run the command: ``python -m build``.

.. important::
Please note that some operating systems might be equipped with
the ``python3`` and ``pip3`` commands instead of ``python`` and ``pip``
(but they should be equivalent).
If you don't have ``pip`` or ``pip3`` available in your system, please
check out :doc:`pip installation docs <pip:installation>`.


Every 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 tool that provides a ``build sdist``-like
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:`PEP 517 <517#build-requirements>`. To learn more about Python packaging in general,
navigate to the :ref:`bottom <packaging-resources>` of this page.
functionality.


.. _basic-use:

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:

When creating a Python package, you must provide a ``pyproject.toml`` file
containing a ``build-system`` section similar to the example below:

.. code-block:: toml
[build-system]
requires = ["setuptools"]
build-backend = "setuptools.build_meta"
Then, you will need to specify your package information such as metadata,
contents, dependencies, etc.
This section declares what are your build system dependencies, and which
library will be used to actually do the packaging.

Setuptools currently supports configurations from either ``setup.cfg``,
``setup.py`` or ``pyproject.toml`` [#experimental]_ files, however, configuring new
projects via ``setup.py`` is discouraged [#setup.py]_.
In addition to specifying a build system, you also will need to add
some package information such as metadata, contents, dependencies, etc.
This can be done in the same ``pyproject.toml`` [#experimental]_ file,
or in a separated one: ``setup.cfg`` or ``setup.py`` (please note however
that configuring new projects via ``setup.py`` is discouraged [#setup.py]_).

The following example demonstrates a minimum configuration:
The following example demonstrates a minimum configuration
(which assumes the project depends on :pypi:`requests` and
:pypi:`importlib-metadata` to be able to run):

.. tab:: setup.cfg

Expand All @@ -53,7 +75,6 @@ The following example demonstrates a minimum configuration:
version = 0.0.1
[options]
packages = mypackage
install_requires =
requests
importlib-metadata; python_version < "3.8"
Expand All @@ -69,7 +90,6 @@ The following example demonstrates a minimum configuration:
setup(
name='mypackage',
version='0.0.1',
packages=['mypackage'],
install_requires=[
'requests',
'importlib-metadata; python_version == "3.8"',
Expand All @@ -92,37 +112,59 @@ The following example demonstrates a minimum configuration:
See :doc:`/userguide/pyproject_config` for more information.

This is what your project would look like::
Finally, you will need to organize your Python code to make it ready for
distributing into something that looks like the following
(optional files marked with ``#``)::

~/mypackage/
pyproject.toml
setup.cfg # or setup.py
mypackage/__init__.py
mypackage
├── pyproject.toml
| # setup.cfg or setup.py (depending on the confuguration method)
| # README.rst or README.md (a nice description of your package)
| # LICENCE (properly chosen license information, e.g. MIT, BSD-3, GPL-3, MPL-2, etc...)
└── mypackage
├── __init__.py
└── ... (other Python files)

Then, you need a builder, such as :std:doc:`PyPA build <pypa-build:index>`
which you can obtain via ``pip install build``. After downloading it, invoke
the builder::
With :ref:`build installed in you system <install-build>`, you can then run::

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!
You now have your distribution ready (e.g. a ``tar.gz`` file and a ``.whl`` file
in the ``dist`` directory), which you can :doc:`upload <twine:index>` 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
Of course, before you release your project to PyPI_, you'll want to add a bit
more information 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 the 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.
Therefore, ``setuptools`` provides a convenient way to automatically list all
the packages in your project directory:
..
TODO: A previous generation of this document included a section called
"Python packaging at a glance". This is a nice title, but the content
removed because it assumed the reader had familiarity with the history of
setuptools and PEP 517. We should take advantage of this nice title and add
this section back, but use it to explain important concepts of the
ecosystem, such as "sdist", "wheel", "index". It would also be nice if we
could have a diagram for that (explaining for example that "wheels" are
built from "sdists" not the source tree).

Overview
========

Package discovery
-----------------
For projects that follow a simple directory structure, ``setuptools`` should be
able to automatically detect all :term:`packages <package>` and
:term:`namespaces <namespace>`. However, complex projects might include
additional folders and supporting files that not necessarily should be
distributed (or that can confuse ``setuptools`` auto discovery algorithm).

Therefore, ``setuptools`` provides a convenient way to customize
which packages should be distributed and in which directory they should be
found, as shown in the example below:

.. tab:: setup.cfg

Expand Down Expand Up @@ -172,28 +214,29 @@ the packages in your project directory:
When you pass the above information, alongside other necessary information,
``setuptools`` walks through the directory specified in ``where`` (omitted
here as the package resides in the current directory) and filters the packages
it can find following the ``include`` (defaults to none), then removes
those that match the ``exclude`` and returns a list of Python packages. The above
setup also allows you to adopt a ``src/`` layout. For more details and advanced
use, go to :ref:`package_discovery`.
it can find following the ``include`` patterns (defaults to ``*``), then it removes
those that match the ``exclude`` patterns and returns a list of Python packages.

For more details and advanced use, go to :ref:`package_discovery`.

.. tip::
Starting with version 61.0.0, setuptools' automatic discovery capabilities
have been improved to detect popular project layouts (such as the
:ref:`flat-layout` and :ref:`src-layout`) without requiring any
special configuration. Check out our :ref:`reference docs <package_discovery>`
for more information, but please keep in mind that this functionality is
still considered **experimental** and might change (or even be removed) in
future releases.
still considered **experimental** and might change in future releases.


Entry points and automatic script creation
===========================================
Setuptools supports automatic creation of scripts upon installation, that runs
-------------------------------------------
Setuptools supports automatic creation of scripts upon installation, that run
code within your package if you specify them as :doc:`entry points
<PyPUG:specifications/entry-points>`.
This is what allows you to run commands like ``pip install`` instead of having
An example of how this feature can be used in ``pip``:
it allows you to run commands like ``pip install`` instead of having
to type ``python -m pip install``.

The following configuration examples show how to accomplish this:

.. tab:: setup.cfg
Expand Down Expand Up @@ -233,7 +276,7 @@ For detailed usage, go to :doc:`entry_point`.


Dependency management
=====================
---------------------
Packages built with ``setuptools`` can specify dependencies to be automatically
installed when the package itself is installed.
The example below show how to configure this kind of dependencies:
Expand Down Expand Up @@ -285,7 +328,7 @@ For more advanced use, see :doc:`dependency_management`.
.. _Including Data Files:

Including Data Files
====================
--------------------
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:

Expand Down Expand Up @@ -324,7 +367,7 @@ For more details, see :doc:`datafiles`.


Development mode
================
----------------

``setuptools`` allows you to install a package without copying any files
to your interpreter directory (e.g. the ``site-packages`` directory).
Expand Down Expand Up @@ -361,15 +404,15 @@ associate with your source code. For more information, see :doc:`development_mod


Uploading your package to PyPI
==============================
------------------------------
After generating the distribution files, the next step would be to upload your
distribution so others can use it. This functionality is provided by
:pypi:`twine` and is documented in the :doc:`Python packaging tutorial
<PyPUG:tutorials/packaging-projects>`.


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
Expand Down Expand Up @@ -410,3 +453,5 @@ up-to-date references that can help you when it is time to distribute your work.
options via the ``[project]`` and ``[tool.setuptools]`` tables is still
experimental and might change in future releases.
See :doc:`/userguide/pyproject_config`.
.. _PyPI: https://pypi.org

0 comments on commit d9e2390

Please sign in to comment.