Commit 80fc5b6d authored by Wyatt Lee Baldwin's avatar Wyatt Lee Baldwin

Add support for PEP 420 namespace packages to find_packages()

On Python 3.3+, `find_packages()` now considers any subdirectory of the
start directory that's not a regular package (i.e., that doesn't have an
`__init__.py`) to be a namespace package.

The other way this supports PEP 420 is by making sure `__pycache__`
directories are never added to the list of packages.

Fixes issue #97
parent c74177b8
......@@ -2,6 +2,15 @@
CHANGES
=======
---
4.0
---
* Issue #97: ``find_packages()`` now supports PEP 420 namespace packages. It
does so by considering all subdirectories of the start directory that
aren't regular packages to be PEP 420 namespace packages (on Python 3.3+
only).
---
3.3
---
......
[setuptools.installation]
eggsecutable = setuptools.command.easy_install:bootstrap
[distutils.setup_keywords]
packages = setuptools.dist:check_packages
entry_points = setuptools.dist:check_entry_points
test_suite = setuptools.dist:check_test_suite
include_package_data = setuptools.dist:assert_bool
exclude_package_data = setuptools.dist:check_package_data
convert_2to3_doctests = setuptools.dist:assert_string_list
extras_require = setuptools.dist:check_extras
install_requires = setuptools.dist:check_requirements
use_2to3_fixers = setuptools.dist:assert_string_list
zip_safe = setuptools.dist:assert_bool
namespace_packages = setuptools.dist:check_nsp
test_loader = setuptools.dist:check_importable
use_2to3 = setuptools.dist:assert_bool
eager_resources = setuptools.dist:assert_string_list
dependency_links = setuptools.dist:assert_string_list
tests_require = setuptools.dist:check_requirements
package_data = setuptools.dist:check_package_data
use_2to3_exclude_fixers = setuptools.dist:assert_string_list
[setuptools.file_finders]
svn_cvs = setuptools.command.sdist:_default_revctrl
[distutils.commands]
setopt = setuptools.command.setopt:setopt
easy_install = setuptools.command.easy_install:easy_install
bdist_wininst = setuptools.command.bdist_wininst:bdist_wininst
register = setuptools.command.register:register
test = setuptools.command.test:test
install_scripts = setuptools.command.install_scripts:install_scripts
install = setuptools.command.install:install
alias = setuptools.command.alias:alias
bdist_egg = setuptools.command.bdist_egg:bdist_egg
build_py = setuptools.command.build_py:build_py
install_lib = setuptools.command.install_lib:install_lib
rotate = setuptools.command.rotate:rotate
bdist_rpm = setuptools.command.bdist_rpm:bdist_rpm
egg_info = setuptools.command.egg_info:egg_info
develop = setuptools.command.develop:develop
install_egg_info = setuptools.command.install_egg_info:install_egg_info
build_ext = setuptools.command.build_ext:build_ext
sdist = setuptools.command.sdist:sdist
saveopts = setuptools.command.saveopts:saveopts
upload_docs = setuptools.command.upload_docs:upload_docs
[egg_info.writers]
namespace_packages.txt = setuptools.command.egg_info:overwrite_arg
eager_resources.txt = setuptools.command.egg_info:overwrite_arg
entry_points.txt = setuptools.command.egg_info:write_entries
PKG-INFO = setuptools.command.egg_info:write_pkg_info
depends.txt = setuptools.command.egg_info:warn_depends_obsolete
dependency_links.txt = setuptools.command.egg_info:overwrite_arg
top_level.txt = setuptools.command.egg_info:write_toplevel_names
requires.txt = setuptools.command.egg_info:write_requirements
[console_scripts]
easy_install = setuptools.command.easy_install:main
easy_install-3.4 = setuptools.command.easy_install:main
[setuptools.installation]
eggsecutable = setuptools.command.easy_install:bootstrap
[egg_info.writers]
entry_points.txt = setuptools.command.egg_info:write_entries
dependency_links.txt = setuptools.command.egg_info:overwrite_arg
eager_resources.txt = setuptools.command.egg_info:overwrite_arg
top_level.txt = setuptools.command.egg_info:write_toplevel_names
namespace_packages.txt = setuptools.command.egg_info:overwrite_arg
depends.txt = setuptools.command.egg_info:warn_depends_obsolete
requires.txt = setuptools.command.egg_info:write_requirements
PKG-INFO = setuptools.command.egg_info:write_pkg_info
[setuptools.file_finders]
svn_cvs = setuptools.command.sdist:_default_revctrl
[console_scripts]
easy_install-3.4 = setuptools.command.easy_install:main
easy_install = setuptools.command.easy_install:main
[distutils.setup_keywords]
use_2to3_fixers = setuptools.dist:assert_string_list
dependency_links = setuptools.dist:assert_string_list
packages = setuptools.dist:check_packages
use_2to3_exclude_fixers = setuptools.dist:assert_string_list
convert_2to3_doctests = setuptools.dist:assert_string_list
use_2to3 = setuptools.dist:assert_bool
exclude_package_data = setuptools.dist:check_package_data
entry_points = setuptools.dist:check_entry_points
test_loader = setuptools.dist:check_importable
namespace_packages = setuptools.dist:check_nsp
zip_safe = setuptools.dist:assert_bool
extras_require = setuptools.dist:check_extras
eager_resources = setuptools.dist:assert_string_list
tests_require = setuptools.dist:check_requirements
package_data = setuptools.dist:check_package_data
test_suite = setuptools.dist:check_test_suite
include_package_data = setuptools.dist:assert_bool
install_requires = setuptools.dist:check_requirements
[distutils.commands]
upload_docs = setuptools.command.upload_docs:upload_docs
egg_info = setuptools.command.egg_info:egg_info
install_scripts = setuptools.command.install_scripts:install_scripts
saveopts = setuptools.command.saveopts:saveopts
bdist_rpm = setuptools.command.bdist_rpm:bdist_rpm
rotate = setuptools.command.rotate:rotate
install = setuptools.command.install:install
bdist_egg = setuptools.command.bdist_egg:bdist_egg
test = setuptools.command.test:test
install_egg_info = setuptools.command.install_egg_info:install_egg_info
install_lib = setuptools.command.install_lib:install_lib
sdist = setuptools.command.sdist:sdist
register = setuptools.command.register:register
develop = setuptools.command.develop:develop
build_py = setuptools.command.build_py:build_py
setopt = setuptools.command.setopt:setopt
build_ext = setuptools.command.build_ext:build_ext
alias = setuptools.command.alias:alias
easy_install = setuptools.command.easy_install:easy_install
bdist_wininst = setuptools.command.bdist_wininst:bdist_wininst
[ssl:sys_platform=='win32']
wincertstore==0.2
[certs]
certifi==1.0.1
\ No newline at end of file
certifi==1.0.1
[ssl:sys_platform=='win32']
wincertstore==0.2
\ No newline at end of file
......@@ -56,7 +56,10 @@ def find_packages(where='.', exclude=(), include=()):
looks_like_package = (
'.' not in name
and os.path.isdir(fn)
and os.path.isfile(os.path.join(fn, '__init__.py'))
and (
os.path.isfile(os.path.join(fn, '__init__.py'))
or sys.version_info[:2] >= (3, 3) # PEP 420
)
)
if looks_like_package:
pkg_name = prefix + name
......
"""Tests for setuptools.find_packages()."""
import os
import shutil
import sys
import tempfile
import unittest
from setuptools import find_packages
PEP420 = sys.version_info[:2] >= (3, 3)
class TestFindPackages(unittest.TestCase):
def setUp(self):
......@@ -58,6 +62,7 @@ class TestFindPackages(unittest.TestCase):
fp.close()
return path
@unittest.skipIf(PEP420, 'Not a PEP 420 env')
def test_regular_package(self):
self._touch('__init__.py', self.pkg_dir)
packages = find_packages(self.dist_dir)
......@@ -80,3 +85,36 @@ class TestFindPackages(unittest.TestCase):
self._touch('file.dat', data_dir)
packages = find_packages(self.dist_dir)
self.assertTrue('pkg.some.data' not in packages)
@unittest.skipIf(not PEP420, 'PEP 420 only')
def test_pep420_ns_package(self):
packages = find_packages(
self.dist_dir, include=['pkg*'], exclude=['pkg.subpkg.assets'])
self.assertEqual(packages, ['pkg', 'pkg.nspkg', 'pkg.subpkg'])
@unittest.skipIf(not PEP420, 'PEP 420 only')
def test_pep420_ns_package_no_includes(self):
packages = find_packages(
self.dist_dir, exclude=['pkg.subpkg.assets'])
self.assertEqual(packages, ['docs', 'pkg', 'pkg.nspkg', 'pkg.subpkg'])
@unittest.skipIf(not PEP420, 'PEP 420 only')
def test_pep420_ns_package_no_includes_or_excludes(self):
packages = find_packages(self.dist_dir)
expected = [
'docs', 'pkg', 'pkg.nspkg', 'pkg.subpkg', 'pkg.subpkg.assets']
self.assertEqual(packages, expected)
@unittest.skipIf(not PEP420, 'PEP 420 only')
def test_regular_package_with_nested_pep420_ns_packages(self):
self._touch('__init__.py', self.pkg_dir)
packages = find_packages(
self.dist_dir, exclude=['docs', 'pkg.subpkg.assets'])
self.assertEqual(packages, ['pkg', 'pkg.nspkg', 'pkg.subpkg'])
@unittest.skipIf(not PEP420, 'PEP 420 only')
def test_pep420_ns_package_no_non_package_dirs(self):
shutil.rmtree(self.docs_dir)
shutil.rmtree(os.path.join(self.dist_dir, 'pkg/subpkg/assets'))
packages = find_packages(self.dist_dir)
self.assertEqual(packages, ['pkg', 'pkg.nspkg', 'pkg.subpkg'])
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment