123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170 |
- """Tests for setuptools.find_packages()."""
- import os
- import sys
- import shutil
- import tempfile
- import platform
- import pytest
- import setuptools
- from setuptools import find_packages
- find_420_packages = setuptools.PEP420PackageFinder.find
- # modeled after CPython's test.support.can_symlink
- def can_symlink():
- TESTFN = tempfile.mktemp()
- symlink_path = TESTFN + "can_symlink"
- try:
- os.symlink(TESTFN, symlink_path)
- can = True
- except (OSError, NotImplementedError, AttributeError):
- can = False
- else:
- os.remove(symlink_path)
- globals().update(can_symlink=lambda: can)
- return can
- def has_symlink():
- bad_symlink = (
- # Windows symlink directory detection is broken on Python 3.2
- platform.system() == 'Windows' and sys.version_info[:2] == (3,2)
- )
- return can_symlink() and not bad_symlink
- class TestFindPackages:
- def setup_method(self, method):
- self.dist_dir = tempfile.mkdtemp()
- self._make_pkg_structure()
- def teardown_method(self, method):
- shutil.rmtree(self.dist_dir)
- def _make_pkg_structure(self):
- """Make basic package structure.
- dist/
- docs/
- conf.py
- pkg/
- __pycache__/
- nspkg/
- mod.py
- subpkg/
- assets/
- asset
- __init__.py
- setup.py
- """
- self.docs_dir = self._mkdir('docs', self.dist_dir)
- self._touch('conf.py', self.docs_dir)
- self.pkg_dir = self._mkdir('pkg', self.dist_dir)
- self._mkdir('__pycache__', self.pkg_dir)
- self.ns_pkg_dir = self._mkdir('nspkg', self.pkg_dir)
- self._touch('mod.py', self.ns_pkg_dir)
- self.sub_pkg_dir = self._mkdir('subpkg', self.pkg_dir)
- self.asset_dir = self._mkdir('assets', self.sub_pkg_dir)
- self._touch('asset', self.asset_dir)
- self._touch('__init__.py', self.sub_pkg_dir)
- self._touch('setup.py', self.dist_dir)
- def _mkdir(self, path, parent_dir=None):
- if parent_dir:
- path = os.path.join(parent_dir, path)
- os.mkdir(path)
- return path
- def _touch(self, path, dir_=None):
- if dir_:
- path = os.path.join(dir_, path)
- fp = open(path, 'w')
- fp.close()
- return path
- def test_regular_package(self):
- self._touch('__init__.py', self.pkg_dir)
- packages = find_packages(self.dist_dir)
- assert packages == ['pkg', 'pkg.subpkg']
- def test_exclude(self):
- self._touch('__init__.py', self.pkg_dir)
- packages = find_packages(self.dist_dir, exclude=('pkg.*',))
- assert packages == ['pkg']
- def test_include_excludes_other(self):
- """
- If include is specified, other packages should be excluded.
- """
- self._touch('__init__.py', self.pkg_dir)
- alt_dir = self._mkdir('other_pkg', self.dist_dir)
- self._touch('__init__.py', alt_dir)
- packages = find_packages(self.dist_dir, include=['other_pkg'])
- assert packages == ['other_pkg']
- def test_dir_with_dot_is_skipped(self):
- shutil.rmtree(os.path.join(self.dist_dir, 'pkg/subpkg/assets'))
- data_dir = self._mkdir('some.data', self.pkg_dir)
- self._touch('__init__.py', data_dir)
- self._touch('file.dat', data_dir)
- packages = find_packages(self.dist_dir)
- assert 'pkg.some.data' not in packages
- def test_dir_with_packages_in_subdir_is_excluded(self):
- """
- Ensure that a package in a non-package such as build/pkg/__init__.py
- is excluded.
- """
- build_dir = self._mkdir('build', self.dist_dir)
- build_pkg_dir = self._mkdir('pkg', build_dir)
- self._touch('__init__.py', build_pkg_dir)
- packages = find_packages(self.dist_dir)
- assert 'build.pkg' not in packages
- @pytest.mark.skipif(not has_symlink(), reason='Symlink support required')
- def test_symlinked_packages_are_included(self):
- """
- A symbolically-linked directory should be treated like any other
- directory when matched as a package.
- Create a link from lpkg -> pkg.
- """
- self._touch('__init__.py', self.pkg_dir)
- linked_pkg = os.path.join(self.dist_dir, 'lpkg')
- os.symlink('pkg', linked_pkg)
- assert os.path.isdir(linked_pkg)
- packages = find_packages(self.dist_dir)
- assert 'lpkg' in packages
- def _assert_packages(self, actual, expected):
- assert set(actual) == set(expected)
- def test_pep420_ns_package(self):
- packages = find_420_packages(
- self.dist_dir, include=['pkg*'], exclude=['pkg.subpkg.assets'])
- self._assert_packages(packages, ['pkg', 'pkg.nspkg', 'pkg.subpkg'])
- def test_pep420_ns_package_no_includes(self):
- packages = find_420_packages(
- self.dist_dir, exclude=['pkg.subpkg.assets'])
- self._assert_packages(packages, ['docs', 'pkg', 'pkg.nspkg', 'pkg.subpkg'])
- def test_pep420_ns_package_no_includes_or_excludes(self):
- packages = find_420_packages(self.dist_dir)
- expected = [
- 'docs', 'pkg', 'pkg.nspkg', 'pkg.subpkg', 'pkg.subpkg.assets']
- self._assert_packages(packages, expected)
- def test_regular_package_with_nested_pep420_ns_packages(self):
- self._touch('__init__.py', self.pkg_dir)
- packages = find_420_packages(
- self.dist_dir, exclude=['docs', 'pkg.subpkg.assets'])
- self._assert_packages(packages, ['pkg', 'pkg.nspkg', 'pkg.subpkg'])
- 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_420_packages(self.dist_dir)
- self._assert_packages(packages, ['pkg', 'pkg.nspkg', 'pkg.subpkg'])
|