Skip to content

Commit 9e26f88

Browse files
committed
Avoid incentivizing multi-package distributions
1 parent 4dc0909 commit 9e26f88

File tree

1 file changed

+50
-38
lines changed

1 file changed

+50
-38
lines changed

docs/userguide/package_discovery.rst

Lines changed: 50 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -27,16 +27,17 @@ Normally, you would specify the packages to be included manually in the followin
2727
[options]
2828
#...
2929
packages =
30-
mypkg1
31-
mypkg2
30+
mypkg
31+
mypkg.subpkg1
32+
mypkg.subpkg2
3233
3334
.. tab:: setup.py
3435

3536
.. code-block:: python
3637
3738
setup(
3839
# ...
39-
packages=['mypkg1', 'mypkg2']
40+
packages=['mypkg', 'mypkg.subpkg1', 'mypkg.subpkg2']
4041
)
4142
4243
.. tab:: pyproject.toml (**EXPERIMENTAL**) [#experimental]_
@@ -45,12 +46,12 @@ Normally, you would specify the packages to be included manually in the followin
4546
4647
# ...
4748
[tool.setuptools]
48-
packages = ["mypkg1", "mypkg2"]
49+
packages = ["mypkg", "mypkg.subpkg1", "mypkg.subpkg2"]
4950
# ...
5051
5152
52-
If your packages are not in the root of the repository you also need to
53-
configure ``package_dir``:
53+
If your packages are not in the root of the repository or do not correspond
54+
exactly to the directory structure, you also need to configure ``package_dir``:
5455

5556
.. tab:: setup.cfg
5657

@@ -60,16 +61,16 @@ configure ``package_dir``:
6061
# ...
6162
package_dir =
6263
= src
63-
# directory containing all the packages (e.g. src/mypkg1, src/mypkg2)
64+
# directory containing all the packages (e.g. src/mypkg, src/mypkg/subpkg1, ...)
6465
# OR
6566
package_dir =
66-
mypkg1 = lib1
67-
# mypkg1.mod corresponds to lib1/mod.py
68-
# mypkg1.subpkg.mod corresponds to lib1/subpkg/mod.py
69-
mypkg2 = lib2
70-
# mypkg2.mod corresponds to lib2/mod.py
71-
mypkg2.subpkg = lib3
72-
# mypkg2.subpkg.mod corresponds to lib3/mod.py
67+
mypkg = lib
68+
# mypkg.module corresponds to lib/module.py
69+
mypkg.subpkg1 = lib1
70+
# mypkg.subpkg1.module1 corresponds to lib1/module1.py
71+
mypkg.subpkg2 = lib2
72+
# mypkg.subpkg2.module2 corresponds to lib2/module2.py
73+
# ...
7374
7475
.. tab:: setup.py
7576

@@ -78,18 +79,17 @@ configure ``package_dir``:
7879
setup(
7980
# ...
8081
package_dir = {"": "src"}
81-
# directory containing all the packages (e.g. src/mypkg1, src/mypkg2)
82+
# directory containing all the packages (e.g. src/mypkg, src/mypkg/subpkg1, ...)
8283
)
8384
8485
# OR
8586
8687
setup(
8788
# ...
8889
package_dir = {
89-
"mypkg1": "lib1", # mypkg1.mod corresponds to lib1/mod.py
90-
# mypkg1.subpkg.mod corresponds to lib1/subpkg/mod.py
91-
"mypkg2": "lib2", # mypkg2.mod corresponds to lib2/mod.py
92-
"mypkg2.subpkg": "lib3" # mypkg2.subpkg.mod corresponds to lib3/mod.py
90+
"mypkg": "lib", # mypkg.module corresponds to lib/mod.py
91+
"mypkg.subpkg1": "lib1", # mypkg.subpkg1.module1 corresponds to lib1/module1.py
92+
"mypkg.subpkg2": "lib2" # mypkg.subpkg2.module2 corresponds to lib2/module2.py
9393
# ...
9494
)
9595
@@ -105,19 +105,23 @@ configure ``package_dir``:
105105
# OR
106106
107107
[tool.setuptools.package-dir]
108-
mypkg1 = "lib1"
109-
# mypkg1.mod corresponds to lib1/mod.py
110-
# mypkg1.subpkg.mod corresponds to lib1/subpkg/mod.py
111-
mypkg2 = "lib2"
112-
# mypkg2.mod corresponds to lib2/mod.py
113-
"mypkg2.subpkg" = "lib3"
114-
# mypkg2.subpkg.mod corresponds to lib3/mod.py
108+
mypkg = "lib"
109+
# mypkg.module corresponds to lib/module.py
110+
"mypkg.subpkg1" = "lib1"
111+
# mypkg.subpkg1.module1 corresponds to lib1/module1.py
112+
"mypkg.subpkg2" = "lib2"
113+
# mypkg.subpkg2.module2 corresponds to lib2/module2.py
115114
# ...
116115
117116
This can get tiresome really quickly. To speed things up, you can rely on
118117
setuptools automatic discovery, or use the provided tools, as explained in
119118
the following sections.
120119
120+
.. important::
121+
Although ``setuptools`` allows developers to create a very complex mapping
122+
between directory names and package names, it is better to *keep it simple*
123+
and reflect the desired package hierarchy in the directory structure,
124+
preserving the same names.
121125
122126
.. _auto-discovery:
123127
@@ -158,14 +162,18 @@ directory::
158162
├── setup.cfg # or setup.py
159163
├── ...
160164
└── src/
161-
├── mypkg1/
162-
│   ├── __init__.py
163-
│   ├── ...
164-
│   └── mymodule1.py
165-
└── mypkg2/
165+
└── mypkg/
166166
├── __init__.py
167167
├── ...
168-
└── mymodule2.py
168+
├── module.py
169+
├── subpkg1/
170+
│   ├── __init__.py
171+
│   ├── ...
172+
│   └── module1.py
173+
└── subpkg2/
174+
├── __init__.py
175+
├── ...
176+
└── module2.py
169177
170178
This layout is very handy when you wish to use automatic discovery,
171179
since you don't have to worry about other Python files or folders in your
@@ -187,14 +195,18 @@ The package folder(s) are placed directly under the project root::
187195
├── pyproject.toml
188196
├── setup.cfg # or setup.py
189197
├── ...
190-
├── mypkg1/
191-
│   ├── __init__.py
192-
│   ├── ...
193-
│   └── mymodule1.py
194-
└── mypkg2/
198+
└── mypkg/
195199
├── __init__.py
196200
├── ...
197-
└── mymodule2.py
201+
├── module.py
202+
├── subpkg1/
203+
│   ├── __init__.py
204+
│   ├── ...
205+
│   └── module1.py
206+
└── subpkg2/
207+
├── __init__.py
208+
├── ...
209+
└── module2.py
198210
199211
This layout is very practical for using the REPL, but in some situations
200212
it can be more error-prone (e.g. during tests or if you have a bunch

0 commit comments

Comments
 (0)