diff options
-rw-r--r-- | CHANGES.rst | 6 | ||||
-rw-r--r-- | docs/setuptools.txt | 18 | ||||
-rw-r--r-- | setuptools/dist.py | 10 | ||||
-rw-r--r-- | setuptools/tests/test_dist.py | 17 |
4 files changed, 44 insertions, 7 deletions
diff --git a/CHANGES.rst b/CHANGES.rst index 8c214db3..9d8e2e29 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -178,6 +178,12 @@ v28.7.0 of data files, re-aligning with the expectation of distutils and addressing #274 and #521. +v28.7.1 +------- + +* #97: Declaring a namespace package implicitly also + declares the package. + v28.6.1 ------- diff --git a/docs/setuptools.txt b/docs/setuptools.txt index 2a494fca..10bf7dc4 100644 --- a/docs/setuptools.txt +++ b/docs/setuptools.txt @@ -1352,9 +1352,12 @@ Namespace Packages ------------------ Sometimes, a large package is more useful if distributed as a collection of -smaller eggs. However, Python does not normally allow the contents of a -package to be retrieved from more than one location. "Namespace packages" -are a solution for this problem. When you declare a package to be a namespace +smaller packages. Traditionally, Python did not allow the contents of a +package to be retrieved from more than one location. "Namespace packages" +are a solution for this problem, and this feature is provided by +``pkg_resources`` for Python 3.2 and earlier and natively +supported by Python 3.3 and later per PEP 420. +When you declare a package to be a namespace package, it means that the package has no meaningful contents in its ``__init__.py``, and that it is merely a container for modules and subpackages. @@ -1369,7 +1372,7 @@ participates in. For example, the ZopeInterface project might do this:: setup( # ... - namespace_packages=['zope'] + namespace_packages=['zope'], ) because it contains a ``zope.interface`` package that lives in the ``zope`` @@ -1379,8 +1382,7 @@ installed and used, Python will see them both as part of a "virtual" ``zope`` package, even though they will be installed in different locations. Namespace packages don't have to be top-level packages. For example, Zope 3's -``zope.app`` package is a namespace package, and in the future PEAK's -``peak.util`` package will be too. +``zope.app`` package is a namespace package. Note, by the way, that your project's source tree must include the namespace packages' ``__init__.py`` files (and the ``__init__.py`` of any parent @@ -1405,6 +1407,10 @@ project's copy of ``__init__.py`` is loaded first. If the first loaded ``__init__.py`` doesn't declare it, it will never *be* declared, because no other copies will ever be loaded! +Packages that only support Python 3.3 and later may omit the ``__init__.py`` +altogether, but the namespace package must still be declared during +``setup()``. + TRANSITIONAL NOTE ~~~~~~~~~~~~~~~~~ diff --git a/setuptools/dist.py b/setuptools/dist.py index 159464be..60cf6d9d 100644 --- a/setuptools/dist.py +++ b/setuptools/dist.py @@ -106,9 +106,17 @@ def assert_string_list(dist, attr, value): def check_nsp(dist, attr, value): - """Verify that namespace packages are valid""" + """ + Verify that namespace packages are valid and ensure that any + namespace packages imply a package. + """ ns_packages = value assert_string_list(dist, attr, ns_packages) + dist.packages = dist.packages or [] + dist.packages.extend( + package for package in ns_packages + if package not in dist.packages + ) for nsp in ns_packages: if not dist.has_contents_for(nsp): raise DistutilsSetupError( diff --git a/setuptools/tests/test_dist.py b/setuptools/tests/test_dist.py new file mode 100644 index 00000000..aedd2de4 --- /dev/null +++ b/setuptools/tests/test_dist.py @@ -0,0 +1,17 @@ + + +from setuptools import dist as dist_mod + + +class TestCheckNSP: + def test_namespace_package_implies_package(self): + """ + When a namespace package is declared, that declaration + implies the package of the same name, so it should + ensure that the name appears in the list of packages. + """ + attrs = dict(namespace_packages=['foo']) + dist_ob = dist_mod.Distribution(attrs) + for attr, value in attrs.items(): + dist_mod.check_nsp(dist_ob, attr, value) + assert 'foo' in dist_ob.packages |