Team Ai
Datasetpublic

codekingpro/portable-devtools

sourceHugging Faceupdated 5mo agoView on Hugging Face
1likes14kdownloads
test_find_packages.py219 linesDownload Raw Back to tests
1"""Tests for automatic package discovery"""2 3import os4import shutil5import tempfile6 7import pytest8 9from setuptools import find_namespace_packages, find_packages10from setuptools.discovery import FlatLayoutPackageFinder11 12from .compat.py39 import os_helper13 14 15class TestFindPackages:16    def setup_method(self, method):17        self.dist_dir = tempfile.mkdtemp()18        self._make_pkg_structure()19 20    def teardown_method(self, method):21        shutil.rmtree(self.dist_dir)22 23    def _make_pkg_structure(self):24        """Make basic package structure.25 26        dist/27            docs/28                conf.py29            pkg/30                __pycache__/31                nspkg/32                    mod.py33                subpkg/34                    assets/35                        asset36                    __init__.py37            setup.py38 39        """40        self.docs_dir = self._mkdir('docs', self.dist_dir)41        self._touch('conf.py', self.docs_dir)42        self.pkg_dir = self._mkdir('pkg', self.dist_dir)43        self._mkdir('__pycache__', self.pkg_dir)44        self.ns_pkg_dir = self._mkdir('nspkg', self.pkg_dir)45        self._touch('mod.py', self.ns_pkg_dir)46        self.sub_pkg_dir = self._mkdir('subpkg', self.pkg_dir)47        self.asset_dir = self._mkdir('assets', self.sub_pkg_dir)48        self._touch('asset', self.asset_dir)49        self._touch('__init__.py', self.sub_pkg_dir)50        self._touch('setup.py', self.dist_dir)51 52    def _mkdir(self, path, parent_dir=None):53        if parent_dir:54            path = os.path.join(parent_dir, path)55        os.mkdir(path)56        return path57 58    def _touch(self, path, dir_=None):59        if dir_:60            path = os.path.join(dir_, path)61        open(path, 'wb').close()62        return path63 64    def test_regular_package(self):65        self._touch('__init__.py', self.pkg_dir)66        packages = find_packages(self.dist_dir)67        assert packages == ['pkg', 'pkg.subpkg']68 69    def test_exclude(self):70        self._touch('__init__.py', self.pkg_dir)71        packages = find_packages(self.dist_dir, exclude=('pkg.*',))72        assert packages == ['pkg']73 74    def test_exclude_recursive(self):75        """76        Excluding a parent package should not exclude child packages as well.77        """78        self._touch('__init__.py', self.pkg_dir)79        self._touch('__init__.py', self.sub_pkg_dir)80        packages = find_packages(self.dist_dir, exclude=('pkg',))81        assert packages == ['pkg.subpkg']82 83    def test_include_excludes_other(self):84        """85        If include is specified, other packages should be excluded.86        """87        self._touch('__init__.py', self.pkg_dir)88        alt_dir = self._mkdir('other_pkg', self.dist_dir)89        self._touch('__init__.py', alt_dir)90        packages = find_packages(self.dist_dir, include=['other_pkg'])91        assert packages == ['other_pkg']92 93    def test_dir_with_dot_is_skipped(self):94        shutil.rmtree(os.path.join(self.dist_dir, 'pkg/subpkg/assets'))95        data_dir = self._mkdir('some.data', self.pkg_dir)96        self._touch('__init__.py', data_dir)97        self._touch('file.dat', data_dir)98        packages = find_packages(self.dist_dir)99        assert 'pkg.some.data' not in packages100 101    def test_dir_with_packages_in_subdir_is_excluded(self):102        """103        Ensure that a package in a non-package such as build/pkg/__init__.py104        is excluded.105        """106        build_dir = self._mkdir('build', self.dist_dir)107        build_pkg_dir = self._mkdir('pkg', build_dir)108        self._touch('__init__.py', build_pkg_dir)109        packages = find_packages(self.dist_dir)110        assert 'build.pkg' not in packages111 112    @pytest.mark.skipif(not os_helper.can_symlink(), reason='Symlink support required')113    def test_symlinked_packages_are_included(self):114        """115        A symbolically-linked directory should be treated like any other116        directory when matched as a package.117 118        Create a link from lpkg -> pkg.119        """120        self._touch('__init__.py', self.pkg_dir)121        linked_pkg = os.path.join(self.dist_dir, 'lpkg')122        os.symlink('pkg', linked_pkg)123        assert os.path.isdir(linked_pkg)124        packages = find_packages(self.dist_dir)125        assert 'lpkg' in packages126 127    def _assert_packages(self, actual, expected):128        assert set(actual) == set(expected)129 130    def test_pep420_ns_package(self):131        packages = find_namespace_packages(132            self.dist_dir, include=['pkg*'], exclude=['pkg.subpkg.assets']133        )134        self._assert_packages(packages, ['pkg', 'pkg.nspkg', 'pkg.subpkg'])135 136    def test_pep420_ns_package_no_includes(self):137        packages = find_namespace_packages(self.dist_dir, exclude=['pkg.subpkg.assets'])138        self._assert_packages(packages, ['docs', 'pkg', 'pkg.nspkg', 'pkg.subpkg'])139 140    def test_pep420_ns_package_no_includes_or_excludes(self):141        packages = find_namespace_packages(self.dist_dir)142        expected = ['docs', 'pkg', 'pkg.nspkg', 'pkg.subpkg', 'pkg.subpkg.assets']143        self._assert_packages(packages, expected)144 145    def test_regular_package_with_nested_pep420_ns_packages(self):146        self._touch('__init__.py', self.pkg_dir)147        packages = find_namespace_packages(148            self.dist_dir, exclude=['docs', 'pkg.subpkg.assets']149        )150        self._assert_packages(packages, ['pkg', 'pkg.nspkg', 'pkg.subpkg'])151 152    def test_pep420_ns_package_no_non_package_dirs(self):153        shutil.rmtree(self.docs_dir)154        shutil.rmtree(os.path.join(self.dist_dir, 'pkg/subpkg/assets'))155        packages = find_namespace_packages(self.dist_dir)156        self._assert_packages(packages, ['pkg', 'pkg.nspkg', 'pkg.subpkg'])157 158 159class TestFlatLayoutPackageFinder:160    EXAMPLES = {161        "hidden-folders": (162            [".pkg/__init__.py", "pkg/__init__.py", "pkg/nested/file.txt"],163            ["pkg", "pkg.nested"],164        ),165        "private-packages": (166            ["_pkg/__init__.py", "pkg/_private/__init__.py"],167            ["pkg", "pkg._private"],168        ),169        "invalid-name": (170            ["invalid-pkg/__init__.py", "other.pkg/__init__.py", "yet,another/file.py"],171            [],172        ),173        "docs": (["pkg/__init__.py", "docs/conf.py", "docs/readme.rst"], ["pkg"]),174        "tests": (175            ["pkg/__init__.py", "tests/test_pkg.py", "tests/__init__.py"],176            ["pkg"],177        ),178        "examples": (179            [180                "pkg/__init__.py",181                "examples/__init__.py",182                "examples/file.py",183                "example/other_file.py",184                # Sub-packages should always be fine185                "pkg/example/__init__.py",186                "pkg/examples/__init__.py",187            ],188            ["pkg", "pkg.examples", "pkg.example"],189        ),190        "tool-specific": (191            [192                "htmlcov/index.html",193                "pkg/__init__.py",194                "tasks/__init__.py",195                "tasks/subpackage/__init__.py",196                "fabfile/__init__.py",197                "fabfile/subpackage/__init__.py",198                # Sub-packages should always be fine199                "pkg/tasks/__init__.py",200                "pkg/fabfile/__init__.py",201            ],202            ["pkg", "pkg.tasks", "pkg.fabfile"],203        ),204    }205 206    @pytest.mark.parametrize("example", EXAMPLES.keys())207    def test_unwanted_directories_not_included(self, tmp_path, example):208        files, expected_packages = self.EXAMPLES[example]209        ensure_files(tmp_path, files)210        found_packages = FlatLayoutPackageFinder.find(str(tmp_path))211        assert set(found_packages) == set(expected_packages)212 213 214def ensure_files(root_path, files):215    for file in files:216        path = root_path / file217        path.parent.mkdir(parents=True, exist_ok=True)218        path.touch()219 
codekingpro/portable-devtools · Team Ai