@@ -19,7 +19,7 @@ have the following package structure:
19
19
__init__.py
20
20
...
21
21
module_b.py
22
- setup.py
22
+ pyproject.toml
23
23
24
24
And you use this package in your code like so::
25
25
@@ -31,17 +31,19 @@ Then you can break these sub-packages into two separate distributions:
31
31
.. code-block :: text
32
32
33
33
mynamespace-subpackage-a/
34
- setup.py
35
- mynamespace/
36
- subpackage_a/
37
- __init__.py
34
+ pyproject.toml
35
+ src/
36
+ mynamespace/
37
+ subpackage_a/
38
+ __init__.py
38
39
39
40
mynamespace-subpackage-b/
40
- setup.py
41
- mynamespace/
42
- subpackage_b/
43
- __init__.py
44
- module_b.py
41
+ pyproject.toml
42
+ src/
43
+ mynamespace/
44
+ subpackage_b/
45
+ __init__.py
46
+ module_b.py
45
47
46
48
Each sub-package can now be separately installed, used, and versioned.
47
49
@@ -57,52 +59,72 @@ import object short).
57
59
Creating a namespace package
58
60
============================
59
61
60
- There are currently three different approaches to creating namespace packages:
62
+ There are currently two different approaches to creating namespace packages,
63
+ from which the latter is discouraged:
61
64
62
65
#. Use `native namespace packages `_. This type of namespace package is defined
63
66
in :pep: `420 ` and is available in Python 3.3 and later. This is recommended if
64
67
packages in your namespace only ever need to support Python 3 and
65
68
installation via ``pip ``.
66
- #. Use `pkgutil-style namespace packages `_. This is recommended for new
67
- packages that need to support Python 2 and 3 and installation via both
68
- ``pip `` and ``python setup.py install ``.
69
- #. Use `pkg_resources-style namespace packages `_. This method is recommended if
70
- you need compatibility with packages already using this method or if your
71
- package needs to be zip-safe.
72
-
73
- .. warning :: While native namespace packages and pkgutil-style namespace
74
- packages are largely compatible, pkg_resources-style namespace packages
75
- are not compatible with the other methods. It's inadvisable to use
76
- different methods in different distributions that provide packages to the
77
- same namespace.
69
+ #. Use `legacy namespace packages `_. This comprises `pkgutil-style namespace packages `_
70
+ and `pkg_resources-style namespace packages `_.
78
71
79
72
Native namespace packages
80
73
-------------------------
81
74
82
75
Python 3.3 added **implicit ** namespace packages from :pep: `420 `. All that is
83
76
required to create a native namespace package is that you just omit
84
77
:file: `__init__.py ` from the namespace package directory. An example file
85
- structure:
78
+ structure (following :ref: ` src-layout < setuptools:src-layout >`) :
86
79
87
80
.. code-block :: text
88
81
89
- setup.py
90
- mynamespace/
91
- # No __init__.py here.
92
- subpackage_a/
93
- # Sub-packages have __init__.py.
94
- __init__.py
95
- module.py
82
+ mynamespace-subpackage-a/
83
+ pyproject.toml # AND/OR setup.py, setup.cfg
84
+ src/
85
+ mynamespace/ # namespace package
86
+ # No __init__.py here.
87
+ subpackage_a/
88
+ # Regular import packages have an __init__.py.
89
+ __init__.py
90
+ module.py
96
91
97
92
It is extremely important that every distribution that uses the namespace
98
93
package omits the :file: `__init__.py ` or uses a pkgutil-style
99
94
:file: `__init__.py `. If any distribution does not, it will cause the namespace
100
95
logic to fail and the other sub-packages will not be importable.
101
96
102
- Because ``mynamespace `` doesn't contain an :file: `__init__.py `,
103
- :func: `setuptools.find_packages ` won't find the sub-package. You must
104
- use :func: `setuptools.find_namespace_packages ` instead or explicitly
105
- list all packages in your :file: `setup.py `. For example:
97
+ The ``src-layout `` directory structure allows automatic discovery of packages
98
+ by most :term: `build backends <Build Backend> `. See :ref: `src-layout-vs-flat-layout `
99
+ for more information. If however you want to manage exclusions or inclusions of packages
100
+ yourself, this is possible to be configured in the top-level :file: `pyproject.toml `:
101
+
102
+ .. code-block :: toml
103
+
104
+ [build-system]
105
+ ...
106
+
107
+ [tool.setuptools.packages.find]
108
+ where = ["src/"]
109
+ include = ["mynamespace.subpackage_a"]
110
+
111
+ [project]
112
+ name = "mynamespace-subpackage-a"
113
+ ...
114
+
115
+ The same can be accomplished with a :file: `setup.cfg `:
116
+
117
+ .. code-block :: ini
118
+
119
+ [options]
120
+ package_dir =
121
+ =src
122
+ packages = find_namespace:
123
+
124
+ [options.packages.find]
125
+ where = src
126
+
127
+ Or :file: `setup.py `:
106
128
107
129
.. code-block :: python
108
130
@@ -111,9 +133,13 @@ list all packages in your :file:`setup.py`. For example:
111
133
setup(
112
134
name = ' mynamespace-subpackage-a' ,
113
135
...
114
- packages = find_namespace_packages(include = [' mynamespace.*' ])
136
+ packages = find_namespace_packages(where = ' src/' , include = [' mynamespace.subpackage_a' ]),
137
+ package_dir = {' ' : ' src' },
115
138
)
116
139
140
+ :ref: `setuptools ` will search the directory structure for implicit namespace
141
+ packages by default.
142
+
117
143
A complete working example of two native namespace packages can be found in
118
144
the `native namespace package example project `_.
119
145
@@ -125,8 +151,25 @@ the `native namespace package example project`_.
125
151
only support Python 3 and pkgutil-style namespace packages in the
126
152
distributions that need to support Python 2 and 3.
127
153
154
+
155
+ Legacy namespace packages
156
+ -------------------------
157
+
158
+ These two methods, that were used to create namespace packages prior to :pep: `420 `,
159
+ are now considered to be obsolete and should not be used unless you need compatibility
160
+ with packages already using this method. Also, :doc: `pkg_resources <setuptools:pkg_resources >`
161
+ has been deprecated.
162
+
163
+ To migrate an existing package, all packages sharing the namespace must be migrated simultaneously.
164
+
165
+ .. warning :: While native namespace packages and pkgutil-style namespace
166
+ packages are largely compatible, pkg_resources-style namespace packages
167
+ are not compatible with the other methods. It's inadvisable to use
168
+ different methods in different distributions that provide packages to the
169
+ same namespace.
170
+
128
171
pkgutil-style namespace packages
129
- --------------------------------
172
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
130
173
131
174
Python 2.3 introduced the :doc: `pkgutil <python:library/pkgutil >` module and the
132
175
:py:func: `python:pkgutil.extend_path ` function. This can be used to declare namespace
@@ -138,22 +181,24 @@ To create a pkgutil-style namespace package, you need to provide an
138
181
139
182
.. code-block :: text
140
183
141
- setup.py
142
- mynamespace/
143
- __init__.py # Namespace package __init__.py
144
- subpackage_a/
145
- __init__.py # Sub-package __init__.py
146
- module.py
184
+ mynamespace-subpackage-a/
185
+ src/
186
+ pyproject.toml # AND/OR setup.cfg, setup.py
187
+ mynamespace/
188
+ __init__.py # Namespace package __init__.py
189
+ subpackage_a/
190
+ __init__.py # Regular package __init__.py
191
+ module.py
147
192
148
193
The :file: `__init__.py ` file for the namespace package needs to contain
149
- ** only ** the following:
194
+ the following:
150
195
151
196
.. code-block :: python
152
197
153
198
__path__ = __import__ (' pkgutil' ).extend_path(__path__ , __name__ )
154
199
155
- **Every ** distribution that uses the namespace package must include an
156
- identical :file: `__init__.py `. If any distribution does not, it will cause the
200
+ **Every ** distribution that uses the namespace package must include such
201
+ an :file: `__init__.py `. If any distribution does not, it will cause the
157
202
namespace logic to fail and the other sub-packages will not be importable. Any
158
203
additional code in :file: `__init__.py ` will be inaccessible.
159
204
@@ -167,7 +212,7 @@ in the `pkgutil namespace example project`_.
167
212
168
213
169
214
pkg_resources-style namespace packages
170
- --------------------------------------
215
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
171
216
172
217
:doc: `Setuptools <setuptools:index >` provides the `pkg_resources.declare_namespace `_ function and
173
218
the ``namespace_packages `` argument to :func: `~setuptools.setup `. Together
@@ -183,22 +228,24 @@ To create a pkg_resources-style namespace package, you need to provide an
183
228
184
229
.. code-block :: text
185
230
186
- setup.py
187
- mynamespace/
188
- __init__.py # Namespace package __init__.py
189
- subpackage_a/
190
- __init__.py # Sub-package __init__.py
191
- module.py
231
+ mynamespace-subpackage-a/
232
+ src/
233
+ pyproject.toml # AND/OR setup.cfg, setup.py
234
+ mynamespace/
235
+ __init__.py # Namespace package __init__.py
236
+ subpackage_a/
237
+ __init__.py # Regular package __init__.py
238
+ module.py
192
239
193
240
The :file: `__init__.py ` file for the namespace package needs to contain
194
- ** only ** the following:
241
+ the following:
195
242
196
243
.. code-block :: python
197
244
198
245
__import__ (' pkg_resources' ).declare_namespace(__name__ )
199
246
200
- **Every ** distribution that uses the namespace package must include an
201
- identical :file: `__init__.py `. If any distribution does not, it will cause the
247
+ **Every ** distribution that uses the namespace package must include such an
248
+ :file: `__init__.py `. If any distribution does not, it will cause the
202
249
namespace logic to fail and the other sub-packages will not be importable. Any
203
250
additional code in :file: `__init__.py ` will be inaccessible.
204
251
0 commit comments