Skip to content

Avoid incentivizing multi-package distributions #1

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

Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
88 changes: 50 additions & 38 deletions docs/userguide/package_discovery.rst
Original file line number Diff line number Diff line change
Expand Up @@ -27,16 +27,17 @@ Normally, you would specify the packages to be included manually in the followin
[options]
#...
packages =
mypkg1
mypkg2
mypkg
mypkg.subpkg1
mypkg.subpkg2

.. tab:: setup.py

.. code-block:: python

setup(
# ...
packages=['mypkg1', 'mypkg2']
packages=['mypkg', 'mypkg.subpkg1', 'mypkg.subpkg2']
)

.. tab:: pyproject.toml (**EXPERIMENTAL**) [#experimental]_
Expand All @@ -45,12 +46,12 @@ Normally, you would specify the packages to be included manually in the followin

# ...
[tool.setuptools]
packages = ["mypkg1", "mypkg2"]
packages = ["mypkg", "mypkg.subpkg1", "mypkg.subpkg2"]
# ...


If your packages are not in the root of the repository you also need to
configure ``package_dir``:
If your packages are not in the root of the repository or do not correspond
exactly to the directory structure, you also need to configure ``package_dir``:

.. tab:: setup.cfg

Expand All @@ -60,16 +61,16 @@ configure ``package_dir``:
# ...
package_dir =
= src
# directory containing all the packages (e.g. src/mypkg1, src/mypkg2)
# directory containing all the packages (e.g. src/mypkg, src/mypkg/subpkg1, ...)
# OR
package_dir =
mypkg1 = lib1
# mypkg1.mod corresponds to lib1/mod.py
# mypkg1.subpkg.mod corresponds to lib1/subpkg/mod.py
mypkg2 = lib2
# mypkg2.mod corresponds to lib2/mod.py
mypkg2.subpkg = lib3
# mypkg2.subpkg.mod corresponds to lib3/mod.py
mypkg = lib
# mypkg.module corresponds to lib/module.py
mypkg.subpkg1 = lib1
# mypkg.subpkg1.module1 corresponds to lib1/module1.py
mypkg.subpkg2 = lib2
# mypkg.subpkg2.module2 corresponds to lib2/module2.py
# ...

.. tab:: setup.py

Expand All @@ -78,18 +79,17 @@ configure ``package_dir``:
setup(
# ...
package_dir = {"": "src"}
# directory containing all the packages (e.g. src/mypkg1, src/mypkg2)
# directory containing all the packages (e.g. src/mypkg, src/mypkg/subpkg1, ...)
)

# OR

setup(
# ...
package_dir = {
"mypkg1": "lib1", # mypkg1.mod corresponds to lib1/mod.py
# mypkg1.subpkg.mod corresponds to lib1/subpkg/mod.py
"mypkg2": "lib2", # mypkg2.mod corresponds to lib2/mod.py
"mypkg2.subpkg": "lib3" # mypkg2.subpkg.mod corresponds to lib3/mod.py
"mypkg": "lib", # mypkg.module corresponds to lib/mod.py
"mypkg.subpkg1": "lib1", # mypkg.subpkg1.module1 corresponds to lib1/module1.py
"mypkg.subpkg2": "lib2" # mypkg.subpkg2.module2 corresponds to lib2/module2.py
# ...
)

Expand All @@ -105,19 +105,23 @@ configure ``package_dir``:
# OR

[tool.setuptools.package-dir]
mypkg1 = "lib1"
# mypkg1.mod corresponds to lib1/mod.py
# mypkg1.subpkg.mod corresponds to lib1/subpkg/mod.py
mypkg2 = "lib2"
# mypkg2.mod corresponds to lib2/mod.py
"mypkg2.subpkg" = "lib3"
# mypkg2.subpkg.mod corresponds to lib3/mod.py
mypkg = "lib"
# mypkg.module corresponds to lib/module.py
"mypkg.subpkg1" = "lib1"
# mypkg.subpkg1.module1 corresponds to lib1/module1.py
"mypkg.subpkg2" = "lib2"
# mypkg.subpkg2.module2 corresponds to lib2/module2.py
# ...

This can get tiresome really quickly. To speed things up, you can rely on
setuptools automatic discovery, or use the provided tools, as explained in
the following sections.

.. important::
Although ``setuptools`` allows developers to create a very complex mapping
between directory names and package names, it is better to *keep it simple*
and reflect the desired package hierarchy in the directory structure,
preserving the same names.

.. _auto-discovery:

Expand Down Expand Up @@ -158,14 +162,18 @@ directory::
├── setup.cfg # or setup.py
├── ...
└── src/
├── mypkg1/
│   ├── __init__.py
│   ├── ...
│   └── mymodule1.py
└── mypkg2/
└── mypkg/
├── __init__.py
├── ...
└── mymodule2.py
├── module.py
├── subpkg1/
│   ├── __init__.py
│   ├── ...
│   └── module1.py
└── subpkg2/
├── __init__.py
├── ...
└── module2.py

This layout is very handy when you wish to use automatic discovery,
since you don't have to worry about other Python files or folders in your
Expand All @@ -187,14 +195,18 @@ The package folder(s) are placed directly under the project root::
├── pyproject.toml
├── setup.cfg # or setup.py
├── ...
├── mypkg1/
│   ├── __init__.py
│   ├── ...
│   └── mymodule1.py
└── mypkg2/
└── mypkg/
├── __init__.py
├── ...
└── mymodule2.py
├── module.py
├── subpkg1/
│   ├── __init__.py
│   ├── ...
│   └── module1.py
└── subpkg2/
├── __init__.py
├── ...
└── module2.py

This layout is very practical for using the REPL, but in some situations
it can be more error-prone (e.g. during tests or if you have a bunch
Expand Down