summaryrefslogtreecommitdiff
path: root/docs/userguide
diff options
context:
space:
mode:
authorAnderson Bravalheri <andersonbravalheri@gmail.com>2022-06-12 23:08:37 +0100
committerAnderson Bravalheri <andersonbravalheri@gmail.com>2022-06-12 23:08:37 +0100
commit44b34b8534db84946874315d87a55e68570a5f20 (patch)
treed42862618e4abb1dedc8f9636ad543e49341e331 /docs/userguide
parent471fd706d0a20d24ff8a2fd146eb0bb647044933 (diff)
downloadpython-setuptools-git-44b34b8534db84946874315d87a55e68570a5f20.tar.gz
Update userguide on `miscellaneous` and `extension`
This is a continuation of the update effort to de-emphasize `distutils` and make the documentation more consistent. The main targets of the changes are the files `docs/userguide/miscellaneous` and `docs/userguide/extension`. Changes: - Extracted text about automatic resource extraction and the zip-safe flag from `userguide/miscellaneous` to `deprecated/resource_extraction` and `deprecated/zip_safe`. - These configuration parameters are commonly associated with ``eggs``/``easy_install``/``pkg_resources``, and therefore are obsolete. Leaving them around in the main parts of the documentation just confuses users. - The text in the new files were updated. - Extracted text about additional metadata from `userguide/miscellaneous` into the existing `userguide/extension` document. - Updated `userguide/extension` to better reflect the status of the setuptools project. The text was also changed to explain a little bit more what is the relationship between ``setuptools`` and ``distutils``. - Removed `userguide/functionalities_rewrite`. This file was virtually empty and not bringing any extra value to the docs.
Diffstat (limited to 'docs/userguide')
-rw-r--r--docs/userguide/extension.rst185
-rw-r--r--docs/userguide/functionalities_rewrite.rst9
-rw-r--r--docs/userguide/miscellaneous.rst100
3 files changed, 117 insertions, 177 deletions
diff --git a/docs/userguide/extension.rst b/docs/userguide/extension.rst
index 21fb05b6..4ecfc3ee 100644
--- a/docs/userguide/extension.rst
+++ b/docs/userguide/extension.rst
@@ -1,60 +1,73 @@
.. _Creating ``distutils`` Extensions:
-Creating ``distutils`` Extensions
-=================================
+Extending or Customizing Setuptools
+===================================
-It can be hard to add new commands or setup arguments to the distutils. But
-the ``setuptools`` package makes it a bit easier, by allowing you to distribute
-a distutils extension as a separate project, and then have projects that need
-the extension just refer to it in their ``setup_requires`` argument.
+Setuptools design is based on the distutils_ package originally distributed
+as part of Python's standard library, effectively serving as its successor
+(as established in :pep:`632`).
-With ``setuptools``, your distutils extension projects can hook in new
+This means that ``setuptools`` strives to honour the extension mechanisms
+provided by ``distutils``, and allows developers to create third party packages
+that modify or augment the build process behaviour.
+
+A simple way of doing that is to hook in new or existing
commands and ``setup()`` arguments just by defining "entry points". These
are mappings from command or argument names to a specification of where to
import a handler from. (See the section on :ref:`Dynamic Discovery of
Services and Plugins` above for some more background on entry points.)
+The following sections describe the most common procedures for extending
+the ``distutils`` functionality used by ``setuptools``.
-Adding Commands
----------------
+Customizing Commands
+--------------------
-You can add new ``setup`` commands by defining entry points in the
-``distutils.commands`` group. For example, if you wanted to add a ``foo``
-command, you might add something like this to your distutils extension
-project's setup script::
+Both ``setuptools`` and ``distutils`` are structured around the *command design
+pattern*. This means that each main action executed when building a
+distribution package (such as creating a :term:`sdist <Source Distribution (or "sdist")>`
+or :term:`wheel`) correspond to the implementation of a Python class.
- setup(
- # ...
- entry_points={
- "distutils.commands": [
- "foo = mypackage.some_module:foo",
- ],
- },
- )
+Originally in ``distutils``, these commands would correspond to actual CLI
+arguments that could be passed to the ``setup.py`` script to trigger a
+different aspect of the build. In ``setuptools``, however, these command
+objects are just a design abstraction that encapsulate logic and help to
+organise the code.
+
+You can overwrite exiting commands (or add new ones) by defining entry
+points in the ``distutils.commands`` group. For example, if you wanted to add
+a ``foo`` command, you might add something like this to your project:
+
+.. code-block:: ini
+
+ # setup.cfg
+ ...
+ [options.entry_points]
+ distutils.commands =
+ foo = mypackage.some_module:foo
(Assuming, of course, that the ``foo`` class in ``mypackage.some_module`` is
a ``setuptools.Command`` subclass.)
Once a project containing such entry points has been activated on ``sys.path``,
-(e.g. by running "install" or "develop" with a site-packages installation
-directory) the command(s) will be available to any ``setuptools``-based setup
-scripts. It is not necessary to use the ``--command-packages`` option or
-to monkeypatch the ``distutils.command`` package to install your commands;
-``setuptools`` automatically adds a wrapper to the distutils to search for
-entry points in the active distributions on ``sys.path``. In fact, this is
+(e.g. by running ``pip install``) the command(s) will be available to any
+``setuptools``-based project. In fact, this is
how setuptools' own commands are installed: the setuptools project's setup
script defines entry points for them!
-.. note::
- When creating commands, and specially when defining custom ways of building
- compiled extensions (for example via ``build_ext``), consider
- handling exceptions such as ``CompileError``, ``LinkError``, ``LibError``,
- among others. These exceptions are available in the ``setuptools.errors``
- module.
+The commands ``sdist``, ``build_py`` and ``build_ext`` are specially useful
+to customize ``setuptools`` builds. Note however that when overwriting existing
+commands you should be very careful to maintain API compatibility.
+Custom commands should try to replicate the same overall behaviour as the
+original classes, and when possible, even inherit from them.
+You should also consider handling exceptions such as ``CompileError``,
+``LinkError``, ``LibError``, among others. These exceptions are available in
+the ``setuptools.errors`` module.
-Adding ``setup()`` Arguments
-----------------------------
+
+Adding Arguments
+----------------
.. warning:: Adding arguments to setup is discouraged as such arguments
are only supported through imperative execution and not supported through
@@ -64,19 +77,17 @@ Sometimes, your commands may need additional arguments to the ``setup()``
call. You can enable this by defining entry points in the
``distutils.setup_keywords`` group. For example, if you wanted a ``setup()``
argument called ``bar_baz``, you might add something like this to your
-distutils extension project's setup script::
+extension project:
- setup(
- # ...
- entry_points={
- "distutils.commands": [
- "foo = mypackage.some_module:foo",
- ],
- "distutils.setup_keywords": [
- "bar_baz = mypackage.some_module:validate_bar_baz",
- ],
- },
- )
+.. code-block:: ini
+
+ # setup.cfg
+ ...
+ [options.entry_points]
+ distutils.commands =
+ foo = mypackage.some_module:foo
+ distutils.setup_keywords =
+ bar_baz = mypackage.some_module:validate_bar_baz
The idea here is that the entry point defines a function that will be called
to validate the ``setup()`` argument, if it's supplied. The ``Distribution``
@@ -93,7 +104,7 @@ a non-None value. Here's an example validation function::
Your function should accept three arguments: the ``Distribution`` object,
the attribute name, and the attribute value. It should raise a
-``DistutilsSetupError`` (from the ``distutils.errors`` module) if the argument
+``SetupError`` (from the ``setuptools.errors`` module) if the argument
is invalid. Remember, your function will only be called with non-None values,
and the default value of arguments defined this way is always None. So, your
commands should always be prepared for the possibility that the attribute will
@@ -101,15 +112,9 @@ be ``None`` when they access it later.
If more than one active distribution defines an entry point for the same
``setup()`` argument, *all* of them will be called. This allows multiple
-distutils extensions to define a common argument, as long as they agree on
+extensions to define a common argument, as long as they agree on
what values of that argument are valid.
-Also note that as with commands, it is not necessary to subclass or monkeypatch
-the distutils ``Distribution`` class in order to add your arguments; it is
-sufficient to define the entry points in your extension, as long as any setup
-script using your extension lists your project in its ``setup_requires``
-argument.
-
Customizing Distribution Options
--------------------------------
@@ -130,22 +135,36 @@ plugin is encouraged to load the configuration/settings for their behavior
independently.
+Defining Additional Metadata
+----------------------------
+
+Some extensible applications and frameworks may need to define their own kinds
+of metadata, which they can then access using the :mod:`importlib.metadata` APIs.
+Ordinarily, this is done by having plugin
+developers include additional files in their ``ProjectName.egg-info``
+directory. However, since it can be tedious to create such files by hand, you
+may want to create an extension that will create the necessary files
+from arguments to ``setup()``, in much the same way that ``setuptools`` does
+for many of the ``setup()`` arguments it adds. See the section below for more
+details.
+
+
.. _Adding new EGG-INFO Files:
Adding new EGG-INFO Files
--------------------------
+~~~~~~~~~~~~~~~~~~~~~~~~~
Some extensible applications or frameworks may want to allow third parties to
develop plugins with application or framework-specific metadata included in
the plugins' EGG-INFO directory, for easy access via the ``pkg_resources``
-metadata API. The easiest way to allow this is to create a distutils extension
+metadata API. The easiest way to allow this is to create an extension
to be used from the plugin projects' setup scripts (via ``setup_requires``)
that defines a new setup keyword, and then uses that data to write an EGG-INFO
file when the ``egg_info`` command is run.
The ``egg_info`` command looks for extension points in an ``egg_info.writers``
-group, and calls them to write the files. Here's a simple example of a
-distutils extension defining a setup argument ``foo_bar``, which is a list of
+group, and calls them to write the files. Here's a simple example of an
+extension defining a setup argument ``foo_bar``, which is a list of
lines that will be written to ``foo_bar.txt`` in the EGG-INFO directory of any
project that uses the argument::
@@ -161,6 +180,16 @@ project that uses the argument::
},
)
+.. code-block:: ini
+
+ # setup.cfg
+ ...
+ [options.entry_points]
+ distutils.setup_keywords =
+ foo_bar = setuptools.dist:assert_string_list
+ egg_info.writers =
+ foo_bar.txt = setuptools.command.egg_info:write_arg
+
This simple example makes use of two utility functions defined by setuptools
for its own use: a routine to validate that a setup keyword is a sequence of
strings, and another one that looks up a setup argument and writes it to
@@ -179,11 +208,11 @@ write (e.g. ``foo_bar.txt``), and the actual full filename that should be
written to.
In general, writer functions should honor the command object's ``dry_run``
-setting when writing files, and use the ``distutils.log`` object to do any
-console output. The easiest way to conform to this requirement is to use
+setting when writing files, and use ``logging`` to do any console output.
+The easiest way to conform to this requirement is to use
the ``cmd`` object's ``write_file()``, ``delete_file()``, and
-``write_or_delete_file()`` methods exclusively for your file operations. See
-those methods' docstrings for more details.
+``write_or_delete_file()`` methods exclusively for your file operations.
+See those methods' docstrings for more details.
.. _Adding Support for Revision Control Systems:
@@ -212,13 +241,16 @@ called "foobar", you would write a function something like this:
def find_files_for_foobar(dirname):
... # loop to yield paths that start with `dirname`
-And you would register it in a setup script using something like this::
+And you would register it in a setup script using something like this:
+
+.. code-block:: ini
+
+ # setup.cfg
+ ...
- entry_points={
- "setuptools.file_finders": [
- "foobar = my_foobar_module:find_files_for_foobar",
- ]
- }
+ [options.entry_points]
+ setuptools.file_finders =
+ foobar = my_foobar_module:find_files_for_foobar
Then, anyone who wants to use your plugin can simply install it, and their
local setuptools installation will be able to find the necessary files.
@@ -248,3 +280,18 @@ A few important points for writing revision control file finders:
with the absence of needed programs (i.e., ones belonging to the revision
control system itself. It *may*, however, use ``distutils.log.warn()`` to
inform the user of the missing program(s).
+
+
+.. _distutils: https://docs.python.org/3.9/library/distutils.html
+
+
+Final Remarks
+-------------
+
+* To use a ``setuptools`` plugin, your users will need to add your package as a
+ build requirement to their build-system configuration. Please check out our
+ guides on :doc:`/userguide/dependency_management` for more information.
+
+* Directly calling ``python setup.py ...`` is considered a **deprecated** practice.
+ You should not add new commands to ``setuptools`` expecting them to be run
+ via this interface.
diff --git a/docs/userguide/functionalities_rewrite.rst b/docs/userguide/functionalities_rewrite.rst
deleted file mode 100644
index d0997ca6..00000000
--- a/docs/userguide/functionalities_rewrite.rst
+++ /dev/null
@@ -1,9 +0,0 @@
-========================================================
-Using setuptools to package and distribute your project
-========================================================
-
-``setuptools`` offers a variety of functionalities that make it easy to
-build and distribute your python package. Here we provide an overview on
-the commonly used ones.
-
-
diff --git a/docs/userguide/miscellaneous.rst b/docs/userguide/miscellaneous.rst
index 5fd2f0a8..776f12f6 100644
--- a/docs/userguide/miscellaneous.rst
+++ b/docs/userguide/miscellaneous.rst
@@ -1,105 +1,7 @@
-.. _Automatic Resource Extraction:
-
-Automatic Resource Extraction
------------------------------
-
-If you are using tools that expect your resources to be "real" files, or your
-project includes non-extension native libraries or other files that your C
-extensions expect to be able to access, you may need to list those files in
-the ``eager_resources`` argument to ``setup()``, so that the files will be
-extracted together, whenever a C extension in the project is imported.
-
-This is especially important if your project includes shared libraries *other*
-than distutils-built C extensions, and those shared libraries use file
-extensions other than ``.dll``, ``.so``, or ``.dylib``, which are the
-extensions that setuptools 0.6a8 and higher automatically detects as shared
-libraries and adds to the ``native_libs.txt`` file for you. Any shared
-libraries whose names do not end with one of those extensions should be listed
-as ``eager_resources``, because they need to be present in the filesystem when
-he C extensions that link to them are used.
-
-The ``pkg_resources`` runtime for compressed packages will automatically
-extract *all* C extensions and ``eager_resources`` at the same time, whenever
-*any* C extension or eager resource is requested via the ``resource_filename()``
-API. (C extensions are imported using ``resource_filename()`` internally.)
-This ensures that C extensions will see all of the "real" files that they
-expect to see.
-
-Note also that you can list directory resource names in ``eager_resources`` as
-well, in which case the directory's contents (including subdirectories) will be
-extracted whenever any C extension or eager resource is requested.
-
-Please note that if you're not sure whether you need to use this argument, you
-don't! It's really intended to support projects with lots of non-Python
-dependencies and as a last resort for crufty projects that can't otherwise
-handle being compressed. If your package is pure Python, Python plus data
-files, or Python plus C, you really don't need this. You've got to be using
-either C or an external program that needs "real" files in your project before
-there's any possibility of ``eager_resources`` being relevant to your project.
-
-Defining Additional Metadata
-----------------------------
-
-Some extensible applications and frameworks may need to define their own kinds
-of metadata to include in eggs, which they can then access using the
-``pkg_resources`` metadata APIs. Ordinarily, this is done by having plugin
-developers include additional files in their ``ProjectName.egg-info``
-directory. However, since it can be tedious to create such files by hand, you
-may want to create a distutils extension that will create the necessary files
-from arguments to ``setup()``, in much the same way that ``setuptools`` does
-for many of the ``setup()`` arguments it adds. See the section below on
-:ref:`Creating ``distutils\`\` Extensions` for more details, especially the
-subsection on :ref:`Adding new EGG-INFO Files`.
-
-Setting the ``zip_safe`` flag
------------------------------
-
-For some use cases (such as bundling as part of a larger application), Python
-packages may be run directly from a zip file.
-Not all packages, however, are capable of running in compressed form, because
-they may expect to be able to access either source code or data files as
-normal operating system files. So, ``setuptools`` can install your project
-as a zipfile or a directory, and its default choice is determined by the
-project's ``zip_safe`` flag.
-
-You can pass a True or False value for the ``zip_safe`` argument to the
-``setup()`` function, or you can omit it. If you omit it, the ``bdist_egg``
-command will analyze your project's contents to see if it can detect any
-conditions that would prevent it from working in a zipfile. It will output
-notices to the console about any such conditions that it finds.
-
-Currently, this analysis is extremely conservative: it will consider the
-project unsafe if it contains any C extensions or datafiles whatsoever. This
-does *not* mean that the project can't or won't work as a zipfile! It just
-means that the ``bdist_egg`` authors aren't yet comfortable asserting that
-the project *will* work. If the project contains no C or data files, and does
-no ``__file__`` or ``__path__`` introspection or source code manipulation, then
-there is an extremely solid chance the project will work when installed as a
-zipfile. (And if the project uses ``pkg_resources`` for all its data file
-access, then C extensions and other data files shouldn't be a problem at all.
-See the :ref:`Accessing Data Files at Runtime` section above for more information.)
-
-However, if ``bdist_egg`` can't be *sure* that your package will work, but
-you've checked over all the warnings it issued, and you are either satisfied it
-*will* work (or if you want to try it for yourself), then you should set
-``zip_safe`` to ``True`` in your ``setup()`` call. If it turns out that it
-doesn't work, you can always change it to ``False``, which will force
-``setuptools`` to install your project as a directory rather than as a zipfile.
-
-In the future, as we gain more experience with different packages and become
-more satisfied with the robustness of the ``pkg_resources`` runtime, the
-"zip safety" analysis may become less conservative. However, we strongly
-recommend that you determine for yourself whether your project functions
-correctly when installed as a zipfile, correct any problems if you can, and
-then make an explicit declaration of ``True`` or ``False`` for the ``zip_safe``
-flag, so that it will not be necessary for ``bdist_egg`` to try to guess
-whether your project can work as a zipfile.
-
-
.. _Controlling files in the distribution:
Controlling files in the distribution
--------------------------------------
+=====================================
For the most common use cases, ``setuptools`` will automatically find out which
files are necessary for distributing the package.