Skip to content

Commit b4ffccd

Browse files
committed
Improve namespace packaging guide
1 parent 6c27b1f commit b4ffccd

File tree

1 file changed

+58
-26
lines changed

1 file changed

+58
-26
lines changed

source/guides/packaging-namespace-packages.rst

Lines changed: 58 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -57,24 +57,15 @@ import object short).
5757
Creating a namespace package
5858
============================
5959

60-
There are currently three different approaches to creating namespace packages:
60+
There are currently two different approaches to creating namespace packages,
61+
from which the latter is discouraged:
6162

6263
#. Use `native namespace packages`_. This type of namespace package is defined
6364
in :pep:`420` and is available in Python 3.3 and later. This is recommended if
6465
packages in your namespace only ever need to support Python 3 and
6566
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.
67+
#. Use `legacy namespace packages`_. This comprises `pkgutil-style namespace packages`_
68+
and `pkg_resources-style namespace packages`_.
7869

7970
Native namespace packages
8071
-------------------------
@@ -86,13 +77,14 @@ structure:
8677

8778
.. code-block:: text
8879
89-
setup.py
90-
mynamespace/
80+
mynamespace-subpackage-a/
81+
setup.py # AND/OR pyproject.toml, setup.cfg
82+
mynamespace/ # namespace package
9183
# No __init__.py here.
92-
subpackage_a/
93-
# Sub-packages have __init__.py.
94-
__init__.py
95-
module.py
84+
subpackage_a/
85+
# Sub-packages have an __init__.py.
86+
__init__.py
87+
module.py
9688
9789
It is extremely important that every distribution that uses the namespace
9890
package omits the :file:`__init__.py` or uses a pkgutil-style
@@ -112,8 +104,31 @@ list all packages in your :file:`setup.py`. For example:
112104
name='mynamespace-subpackage-a',
113105
...
114106
packages=find_namespace_packages(include=['mynamespace.*'])
107+
# or list a single package explicitly:
108+
# packages=['mynamespace.subpackage_a'],
115109
)
116110
111+
The same can be accomplished by replacing the :file:`setup.py` in the
112+
namespace packages' parent directory with a :file:`pyproject.toml`,
113+
with the following contents:
114+
115+
.. code-block:: toml
116+
117+
[build-system]
118+
requires = ["setuptools", "setuptools-scm"]
119+
build-backend = "setuptools.build_meta"
120+
121+
[tool.setuptools.packages.find]
122+
where = ["."]
123+
include = ["mynamespace.*"]
124+
125+
[project]
126+
name = "mynamespace-subpackage-a"
127+
...
128+
129+
:ref:`setuptools` will search the directory structure for implicit namespace
130+
packages by default.
131+
117132
A complete working example of two native namespace packages can be found in
118133
the `native namespace package example project`_.
119134

@@ -125,8 +140,25 @@ the `native namespace package example project`_.
125140
only support Python 3 and pkgutil-style namespace packages in the
126141
distributions that need to support Python 2 and 3.
127142

143+
144+
Legacy namespace packages
145+
-------------------------
146+
147+
These to methods, that were used to create namespace packages prior to :pep:`420`,
148+
are now considered to be obsolete and should not be used unless you need compatibility
149+
with packages already using this method. Also, :doc:`pkg_resources <setuptools:pkg_resources>`
150+
has been deprecated.
151+
152+
To migrate an existing package, all packages sharing the namespace must be migrated simultaneously.
153+
154+
.. warning:: While native namespace packages and pkgutil-style namespace
155+
packages are largely compatible, pkg_resources-style namespace packages
156+
are not compatible with the other methods. It's inadvisable to use
157+
different methods in different distributions that provide packages to the
158+
same namespace.
159+
128160
pkgutil-style namespace packages
129-
--------------------------------
161+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
130162

131163
Python 2.3 introduced the :doc:`pkgutil <python:library/pkgutil>` module and the
132164
:py:func:`python:pkgutil.extend_path` function. This can be used to declare namespace
@@ -138,22 +170,22 @@ To create a pkgutil-style namespace package, you need to provide an
138170

139171
.. code-block:: text
140172
141-
setup.py
173+
setup.py # AND/OR pyproject.toml, setup.cfg
142174
mynamespace/
143175
__init__.py # Namespace package __init__.py
144176
subpackage_a/
145177
__init__.py # Sub-package __init__.py
146178
module.py
147179
148180
The :file:`__init__.py` file for the namespace package needs to contain
149-
**only** the following:
181+
the following:
150182

151183
.. code-block:: python
152184
153185
__path__ = __import__('pkgutil').extend_path(__path__, __name__)
154186
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
187+
**Every** distribution that uses the namespace package must include such
188+
an :file:`__init__.py`. If any distribution does not, it will cause the
157189
namespace logic to fail and the other sub-packages will not be importable. Any
158190
additional code in :file:`__init__.py` will be inaccessible.
159191

@@ -167,7 +199,7 @@ in the `pkgutil namespace example project`_.
167199

168200

169201
pkg_resources-style namespace packages
170-
--------------------------------------
202+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
171203

172204
:doc:`Setuptools <setuptools:index>` provides the `pkg_resources.declare_namespace`_ function and
173205
the ``namespace_packages`` argument to :func:`~setuptools.setup`. Together
@@ -183,7 +215,7 @@ To create a pkg_resources-style namespace package, you need to provide an
183215

184216
.. code-block:: text
185217
186-
setup.py
218+
setup.py # AND/OR pyproject.toml, setup.cfg
187219
mynamespace/
188220
__init__.py # Namespace package __init__.py
189221
subpackage_a/

0 commit comments

Comments
 (0)