Upgrade to setuptools 61.1.0
This fixes Python 3.10 compat, but does remove Python2 compat.
Test: treehugger
Change-Id: I8e19ad8dec6b34482bfbe996413d3f793ada276c
diff --git a/docs/userguide/quickstart.rst b/docs/userguide/quickstart.rst
new file mode 100644
index 0000000..5be1078
--- /dev/null
+++ b/docs/userguide/quickstart.rst
@@ -0,0 +1,414 @@
+==========================
+``setuptools`` Quickstart
+==========================
+
+Installation
+============
+
+To install the latest version of setuptools, use::
+
+ pip install --upgrade setuptools
+
+
+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
+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.
+
+
+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:
+
+.. 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.
+
+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]_.
+
+The following example demonstrates a minimum configuration:
+
+.. tab:: setup.cfg
+
+ .. code-block:: ini
+
+ [metadata]
+ name = mypackage
+ version = 0.0.1
+
+ [options]
+ packages = mypackage
+ install_requires =
+ requests
+ importlib-metadata; python_version < "3.8"
+
+ See :doc:`/userguide/declarative_config` for more information.
+
+.. tab:: setup.py [#setup.py]_
+
+ .. code-block:: python
+
+ from setuptools import setup
+
+ setup(
+ name='mypackage',
+ version='0.0.1',
+ packages=['mypackage'],
+ install_requires=[
+ 'requests',
+ 'importlib-metadata; python_version == "3.8"',
+ ],
+ )
+
+ See :doc:`/references/keywords` for more information.
+
+.. tab:: pyproject.toml (**EXPERIMENTAL**) [#experimental]_
+
+ .. code-block:: toml
+
+ [project]
+ name = "mypackage"
+ version = "0.0.1"
+ dependencies = [
+ "requests",
+ 'importlib-metadata; python_version<"3.8"',
+ ]
+
+ See :doc:`/userguide/pyproject_config` for more information.
+
+This is what your project would look like::
+
+ ~/mypackage/
+ pyproject.toml
+ setup.cfg # or setup.py
+ mypackage/__init__.py
+
+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::
+
+ 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!
+
+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 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, ``setuptoops`` provides a convenient way to automatically list all
+the packages in your project directory:
+
+.. tab:: setup.cfg
+
+ .. code-block:: ini
+
+ [options]
+ packages = find: # OR `find_namespaces:` if you want to use namespaces
+
+ [options.packages.find] (always `find` even if `find_namespaces:` was used before)
+ # This section is optional
+ # Each entry in this section is optional, and if not specified, the default values are:
+ # `where=.`, `include=*` and `exclude=` (empty).
+ include=mypackage*
+ exclude=mypackage.tests*
+
+.. tab:: setup.py [#setup.py]_
+
+ .. code-block:: python
+
+ from setuptools import find_packages # or find_namespace_packages
+
+ setup(
+ # ...
+ packages=find_packages(
+ where='.',
+ include=['mypackage*'], # ["*"] by default
+ exclude=['mypackage.tests'], # empty by default
+ ),
+ # ...
+ )
+
+.. tab:: pyproject.toml (**EXPERIMENTAL**) [#experimental]_
+
+ .. code-block:: toml
+
+ # ...
+ [tool.setuptools.packages]
+ find = {} # Scan the project directory with the default parameters
+
+ # OR
+ [tool.setuptools.packages.find]
+ where = ["src"] # ["."] by default
+ include = ["mypackage*"] # ["*"] by default
+ exclude = ["mypackage.tests*"] # empty by default
+ namespaces = false # true by default
+
+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`.
+
+.. 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.
+
+
+Entry points and automatic script creation
+===========================================
+Setuptools supports automatic creation of scripts upon installation, that runs
+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
+to type ``python -m pip install``.
+The following configuration examples show how to accomplish this:
+
+.. tab:: setup.cfg
+
+ .. code-block:: ini
+
+ [options.entry_points]
+ console_scripts =
+ cli-name = mypkg.mymodule:some_func
+
+.. tab:: setup.py [#setup.py]_
+
+ .. code-block:: python
+
+ setup(
+ # ...
+ entry_points={
+ 'console_scripts': [
+ 'cli-name = mypkg.mymodule:some_func',
+ ]
+ }
+ )
+
+.. tab:: pyproject.toml (**EXPERIMENTAL**) [#experimental]_
+
+ .. code-block:: toml
+
+ [project.scripts]
+ cli-name = mypkg.mymodule:some_func
+
+When this project is installed, a ``cli-name`` executable will be created.
+``cli-name`` will invoke the function ``some_func`` in the
+``mypkg/mymodule.py`` file when called by the user.
+Note that you can also use the ``entry-points`` mechanism to advertise
+components between installed packages and implement plugin systems.
+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:
+
+.. tab:: setup.cfg
+
+ .. code-block:: ini
+
+ [options]
+ install_requires =
+ docutils
+ requests <= 0.4
+
+.. tab:: setup.py [#setup.py]_
+
+ .. code-block:: python
+
+ setup(
+ # ...
+ install_requires=["docutils", "requests <= 0.4"],
+ # ...
+ )
+
+.. tab:: pyproject.toml (**EXPERIMENTAL**) [#experimental]_
+
+ .. code-block:: toml
+
+ [project]
+ # ...
+ dependencies = [
+ "docutils",
+ "requires <= 0.4",
+ ]
+ # ...
+
+Each dependency is represented by a string that can optionally contain version requirements
+(e.g. one of the operators <, >, <=, >=, == or !=, followed by a version identifier),
+and/or conditional environment markers, e.g. ``sys_platform == "win32"``
+(see :doc:`PyPUG:specifications/version-specifiers` for more information).
+
+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 scenario. You can also specify groups of
+extra dependencies that are not strictly required by your package to work, but
+that will provide additional functionalities.
+For more advanced use, see :doc:`dependency_management`.
+
+
+.. _Including Data Files:
+
+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:
+
+.. tab:: setup.cfg
+
+ .. code-block:: ini
+
+ [options]
+ include_package_data = True
+
+.. tab:: setup.py [#setup.py]_
+
+ .. code-block:: python
+
+ setup(
+ # ...
+ include_package_data=True,
+ # ...
+ )
+
+.. tab:: pyproject.toml (**EXPERIMENTAL**) [#experimental]_
+
+ .. code-block:: toml
+
+ [tool.setuptools]
+ include-package-data = true
+ # This is already the default behaviour if your are using
+ # pyproject.toml to configure your build.
+ # You can deactivate that with `include-package-data = false`
+
+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
+or automatically added by a :ref:`Revision Control System plugin
+<Adding Support for Revision Control Systems>`.
+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).
+This allows you to modify your source code and have the changes take
+effect without you having to rebuild and reinstall.
+Here's how to do it::
+
+ pip install --editable .
+
+This creates a link file in your interpreter site package directory which
+associate with your source code. For more information, see :doc:`development_mode`.
+
+.. tip::
+
+ Prior to :ref:`pip v21.1 <pip:v21-1>`, a ``setup.py`` script was
+ required to be compatible with development mode. With late
+ versions of pip, ``setup.cfg``-only projects may be installed in this mode.
+
+ If you are experimenting with :doc:`configuration using <pyproject_config>`,
+ or have version of ``pip`` older than v21.1, you might need to keep a
+ ``setup.py`` file in file in your repository if you want to use editable
+ installs (for the time being).
+
+ A simple script will suffice, for example:
+
+ .. code-block:: python
+
+ from setuptools import setup
+
+ setup()
+
+ You can still keep all the configuration in :doc:`setup.cfg </userguide/declarative_config>`
+ (or :doc:`pyproject.toml </userguide/pyproject_config>`).
+
+
+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
+syntax. :doc:`Here </userguide/declarative_config>` we provide a quick guide to
+understanding how ``setup.cfg`` is parsed by ``setuptools`` to ease the pain of
+transition.
+
+.. _packaging-resources:
+
+Resources on Python packaging
+=============================
+Packaging in Python can be hard and is constantly evolving.
+`Python Packaging User Guide <https://packaging.python.org>`_ has tutorials and
+up-to-date references that can help you when it is time to distribute your work.
+
+
+.. |MANIFEST.in| replace:: ``MANIFEST.in``
+.. _MANIFEST.in: https://packaging.python.org/en/latest/guides/using-manifest-in/
+
+
+----
+
+.. rubric:: Notes
+
+.. [#setup.py]
+ The ``setup.py`` file should be used only when custom scripting during the
+ build is necessary.
+ Examples are kept in this document to help people interested in maintaining or
+ contributing to existing packages that use ``setup.py``.
+ Note that you can still keep most of configuration declarative in
+ :doc:`setup.cfg <declarative_config>` or :doc:`pyproject.toml
+ <pyproject_config>` and use ``setup.py`` only for the parts not
+ supported in those files (e.g. C extensions).
+
+.. [#experimental]
+ While the ``[build-system]`` table should always be specified in the
+ ``pyproject.toml`` file, support for adding package metadata and build configuration
+ options via the ``[project]`` and ``[tool.setuptools]`` tables is still
+ experimental and might change (or be completely removed) in future releases.
+ See :doc:`/userguide/pyproject_config`.