11.. _`package_discovery` :
22
33========================================
4- Package Discovery and Namespace Package
4+ Package Discovery and Namespace Packages
55========================================
66
77.. note ::
8- a full specification for the keyword supplied to ``setup.cfg `` or
8+ a full specification for the keywords supplied to ``setup.cfg `` or
99 ``setup.py `` can be found at :doc: `keywords reference </references/keywords >`
1010
1111.. note ::
@@ -15,10 +15,10 @@ Package Discovery and Namespace Package
1515 new to setuptools, the :doc: `quickstart section <quickstart >` is a good
1616 place to start.
1717
18- ``Setuptools `` provide powerful tools to handle package discovery, including
19- support for namespace package .
18+ ``Setuptools `` provides powerful tools to handle package discovery, including
19+ support for namespace packages .
2020
21- Normally, you would specify the package to be included manually in the following manner:
21+ Normally, you would specify the packages to be included manually in the following manner:
2222
2323.. tab :: setup.cfg
2424
@@ -27,16 +27,17 @@ Normally, you would specify the package to be included manually in the following
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 package to be included manually in the following
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
117116This can get tiresome really quickly. To speed things up, you can rely on
118117setuptools automatic discovery, or use the provided tools, as explained in
119118the 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
@@ -161,7 +165,15 @@ directory::
161165 └── mypkg/
162166 ├── __init__ .py
163167 ├── ...
164- └── mymodule.py
168+ ├── module.py
169+ ├── subpkg1/
170+ │ ├── __init__ .py
171+ │ ├── ...
172+ │ └── module1.py
173+ └── subpkg2/
174+ ├── __init__ .py
175+ ├── ...
176+ └── module2.py
165177
166178This layout is very handy when you wish to use automatic discovery,
167179since you don' t have to worry about other Python files or folders in your
@@ -186,11 +198,19 @@ The package folder(s) are placed directly under the project root::
186198 └── mypkg/
187199 ├── __init__ .py
188200 ├── ...
189- └── mymodule.py
201+ ├── module.py
202+ ├── subpkg1/
203+ │ ├── __init__ .py
204+ │ ├── ...
205+ │ └── module1.py
206+ └── subpkg2/
207+ ├── __init__ .py
208+ ├── ...
209+ └── module2.py
190210
191211This layout is very practical for using the REPL , but in some situations
192212it can be more error- prone (e.g. during tests or if you have a bunch
193- of folders or Python files hanging around your project root)
213+ of folders or Python files hanging around your project root).
194214
195215To avoid confusion, file and folder names that are used by popular tools (or
196216that correspond to well- known conventions, such as distributing documentation
@@ -271,7 +291,7 @@ Finding simple packages
271291---------------------- -
272292Let' s start with the first tool. ``find:`` (``find_packages()``) takes a source
273293directory and two lists of package name patterns to exclude and include, and
274- then return a list of `` str `` representing the packages it could find. To use
294+ then returns a list of `` str `` representing the packages it could find. To use
275295it, consider the following directory::
276296
277297 mypkg
@@ -281,14 +301,14 @@ it, consider the following directory::
281301 │ └── __init__ .py
282302 ├── pkg2
283303 │ └── __init__ .py
284- ├── aditional
304+ ├── additional
285305 │ └── __init__ .py
286306 └── pkg
287307 └── namespace
288308 └── __init__ .py
289309
290310To have setuptools to automatically include packages found
291- in `` src`` that starts with the name `` pkg`` and not `` additional`` :
311+ in `` src`` that start with the name `` pkg`` and not `` additional`` :
292312
293313.. tab:: setup.cfg
294314
@@ -364,8 +384,8 @@ in ``src`` that starts with the name ``pkg`` and not ``additional``:
364384
365385Finding namespace packages
366386--------------------------
367- `` setuptools`` provides the `` find_namespace:`` (`` find_namespace_packages()`` )
368- which behaves similarly to `` find:`` but works with namespace package .
387+ `` setuptools`` provides `` find_namespace:`` (`` find_namespace_packages()`` )
388+ which behaves similarly to `` find:`` but works with namespace packages .
369389
370390Before diving in , it is important to have a good understanding of what
371391:pep:`namespace packages < 420 > ` are. Here is a quick recap.
@@ -415,7 +435,7 @@ distribution, then you will need to specify:
415435 [options.packages.find]
416436 where = src
417437
418- `` find:`` won' t work because timmins doesn' t contain `` __init__ .py``
438+ `` find:`` won' t work because `` timmins`` doesn' t contain `` __init__ .py``
419439 directly, instead, you have to use `` find_namespace:`` .
420440
421441 You can think of `` find_namespace:`` as identical to `` find:`` except it
@@ -494,15 +514,15 @@ available to your interpreter.
494514
495515Legacy Namespace Packages
496516======================== =
497- The fact you can create namespace package so effortlessly above is credited
498- to `PEP 420 < https:// www.python.org/ dev/ peps/ pep- 0420 / > ` _. It use to be more
517+ The fact you can create namespace packages so effortlessly above is credited
518+ to `PEP 420 < https:// www.python.org/ dev/ peps/ pep- 0420 / > ` _. It used to be more
499519cumbersome to accomplish the same result. Historically, there were two methods
500520to create namespace packages. One is the `` pkg_resources`` style supported by
501521`` setuptools`` and the other one being `` pkgutils`` style offered by
502522`` pkgutils`` module in Python. Both are now considered deprecated despite the
503523fact they still linger in many existing packages. These two differ in many
504524subtle yet significant aspects and you can find out more on `Python packaging
505- user guide < https:// packaging.python.org/ guides/ packaging- namespace- packages/ > `_
525+ user guide < https:// packaging.python.org/ guides/ packaging- namespace- packages/ > `_.
506526
507527
508528`` pkg_resource`` style namespace package
0 commit comments