Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Clarify the package_dir configuration #3358

Merged
merged 7 commits into from Jun 11, 2022
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions changelog.d/3358.doc.rst
@@ -0,0 +1 @@
Clarify the role of the ``package_dir`` configuration.
41 changes: 40 additions & 1 deletion docs/references/keywords.rst
Expand Up @@ -194,7 +194,46 @@ extensions).
.. _keyword/package_dir:

``package_dir``
A dictionary providing a mapping of package to directory names.
A dictionary that maps package names (as the developer wishes they would be
abravalheri marked this conversation as resolved.
Show resolved Hide resolved
imported by the end-users) into directory paths (that actually exist in the
project's source tree). This configuration can be used with 2 main purposes:
abravalheri marked this conversation as resolved.
Show resolved Hide resolved
abravalheri marked this conversation as resolved.
Show resolved Hide resolved

1. To effectively "rename" paths when building your package.
For example, ``package_dir={"mypkg": "dir1/dir2/code_for_mypkg"}``
will instruct setuptools to copy the ``dir1/dir2/code_for_mypkg/...`` files
as ``mypkg/...`` when building the final :term:`wheel distribution <Wheel>`.

.. attention::
While it is *possible* to specify arbitrary mappings, developers are
**STRONGLY ADVISED AGAINST** that. They should try as much as possible
to keep the directory names and hierarchy identical to as they would
abravalheri marked this conversation as resolved.
Show resolved Hide resolved
appear in the final wheel, only deviating when absolutely necessary.

2. To indicate that the relevant code is entirely contained inside
a specific directory (instead of directly placed under the project's root).
In this case, a special key is required (the empty string, ``""``),
for example: ``package_dir={"": "<name of the container directory>"}``.
All the directories inside the container directory will be copied
directly into the final :term:`wheel distribution <Wheel>`, but the
container directory itself will not.

This practice is very common in the community, to help separating the
abravalheri marked this conversation as resolved.
Show resolved Hide resolved
package implementation from auxiliary files (e.g. CI configuration files),
and is referred as :ref:`src-layout`, because traditionally the
abravalheri marked this conversation as resolved.
Show resolved Hide resolved
container directory is named ``src``.

All paths in ``package_dir`` must be relative to the project root directory
and use a forward slash (``/``) as path separator (regardless of the
operating system).
abravalheri marked this conversation as resolved.
Show resolved Hide resolved

.. tip::
When using :doc:`package discovery </userguide/package_discovery>`
together with :doc:`setup.cfg </userguide/declarative_config>` or
:doc:`pyproject.toml </userguide/pyproject_config>`, it is very likely
that you don't need to specify a value for ``package_dir``. Please have
a look on the definitions of :ref:`src-layout` and :ref:`flat-layout` to
abravalheri marked this conversation as resolved.
Show resolved Hide resolved
learn common practices on how to design a project's directory structure
and minimise the amount of configuration that is needed.

.. _keyword/requires:

Expand Down
37 changes: 28 additions & 9 deletions docs/userguide/declarative_config.rst
Expand Up @@ -62,8 +62,8 @@ boilerplate code in some cases.

Metadata and options are set in the config sections of the same name.

* Keys are the same as the keyword arguments one provides to the ``setup()``
function.
* Keys are the same as the :doc:`keyword arguments </references/keywords>` one
provides to the ``setup()`` function.

* Complex values can be written comma-separated or placed one per line
in *dangling* config values. The following are equivalent:
Expand All @@ -90,7 +90,7 @@ Metadata and options are set in the config sections of the same name.
Using a ``src/`` layout
=======================

One commonly used package configuration has all the module source code in a
One commonly used configuration has all the Python source code in a
subdirectory (often called the ``src/`` layout), like this::

├── src
Expand All @@ -101,7 +101,7 @@ subdirectory (often called the ``src/`` layout), like this::
└── setup.cfg

You can set up your ``setup.cfg`` to automatically find all your packages in
the subdirectory like this:
the subdirectory, using :ref:`package_dir <keyword/package_dir>`, like this:

.. code-block:: ini

Expand All @@ -116,6 +116,22 @@ the subdirectory like this:
[options.packages.find]
where=src

In this example, the value for the :ref:`package_dir <keyword/package_dir>`
configuration (i.e. ``=src``) is parsed as ``{"": "src"}``.
The ``""`` key has a special meaning in this context, and indicates that all the
packages are contained inside the given directory.
Also note that the value for ``[options.packages.find] where`` matches to the
abravalheri marked this conversation as resolved.
Show resolved Hide resolved
abravalheri marked this conversation as resolved.
Show resolved Hide resolved
value associated with ``""`` in the ``package_dir`` dictionary.

..
TODO: Add the following tip once the auto-discovery is no longer experimental:

Starting in version 61, ``setuptools`` can automatically infer the
configurations for both ``packages`` and ``package_dir`` for projects using
a ``src/`` layout (as long as no value is specified for ``py_modules``).
Please see :doc:`package discovery </userguide/package_discovery>` for more
details.

Specifying values
=================

Expand All @@ -127,7 +143,10 @@ Type names used below:
* ``list-comma`` - dangling list or string of comma-separated values
* ``list-semi`` - dangling list or string of semicolon-separated values
* ``bool`` - ``True`` is 1, yes, true
* ``dict`` - list-comma where keys are separated from values by ``=``
* ``dict`` - list-comma where each entry corresponds to a key/value pair,
with keys separated from values by ``=``.
If an entry starts with ``=``, the key is assumed to be an empty string
(e.g. ``=src`` is parsed into ``{"": "src"}``).
abravalheri marked this conversation as resolved.
Show resolved Hide resolved
* ``section`` - values are read from a dedicated (sub)section


Expand All @@ -143,15 +162,15 @@ Special directives:

* ``file:`` - Value is read from a list of files and then concatenated

.. note::
The ``file:`` directive is sandboxed and won't reach anything outside
the directory containing ``setup.py``.
.. important::
The ``file:`` directive is sandboxed and won't reach anything outside the
project directory (i.e. the directory containing ``setup.cfg``/``pyproject.toml``).


Metadata
--------

.. note::
.. attention::
The aliases given below are supported for compatibility reasons,
but their use is not advised.

Expand Down