diff --git a/src/usethis/_integrations/project/packages.py b/src/usethis/_integrations/project/packages.py index 2d0563b7..47c58915 100644 --- a/src/usethis/_integrations/project/packages.py +++ b/src/usethis/_integrations/project/packages.py @@ -49,8 +49,8 @@ def _get_packages_in_dir(path: Path) -> set[str]: """Get the names of packages in the given directory.""" return { Path(module_name).name - for _, module_name, _ in pkgutil.iter_modules([path.as_posix()]) - if not _is_excluded(module_name) + for _, module_name, ispkg in pkgutil.iter_modules([path.as_posix()]) + if ispkg and not _is_excluded(module_name) } diff --git a/tests/usethis/_integrations/project/test_packages.py b/tests/usethis/_integrations/project/test_packages.py index f52d025b..5bef92c2 100644 --- a/tests/usethis/_integrations/project/test_packages.py +++ b/tests/usethis/_integrations/project/test_packages.py @@ -62,3 +62,39 @@ def test_multiple_namespace_packages(self, tmp_path: Path): with change_cwd(tmp_path): assert get_importable_packages() == {"foo", "bar"} + + def test_flat_layout_excludes_root_py_files(self, tmp_path: Path): + """Test that root-level .py files are excluded in a flat layout. + + In a flat layout (no src/ directory), standalone .py files like + setup.py or conftest.py should not be detected as importable packages. + Only directories with __init__.py should be included. + """ + (tmp_path / "foo").mkdir() + (tmp_path / "foo" / "__init__.py").touch() + (tmp_path / "foo" / "bar.py").touch() + # Root-level .py files that should be excluded + (tmp_path / "setup.py").touch() + (tmp_path / "conftest.py").touch() + + with change_cwd(tmp_path): + # Should only include "foo" package, not "setup" or "conftest" modules + assert get_importable_packages() == {"foo"} + + def test_src_layout_excludes_root_py_files(self, tmp_path: Path): + """Test that root-level .py files are excluded in a src/ layout. + + In a src/ layout, standalone .py files in src/ like __init__.py + (without a package directory) should not be detected as importable packages. + """ + (tmp_path / "src").mkdir() + (tmp_path / "src" / "foo").mkdir() + (tmp_path / "src" / "foo" / "__init__.py").touch() + (tmp_path / "src" / "foo" / "bar.py").touch() + # Root-level .py files in src/ that should be excluded + (tmp_path / "src" / "conftest.py").touch() + (tmp_path / "src" / "helper.py").touch() + + with change_cwd(tmp_path): + # Should only include "foo" package, not "conftest" or "helper" modules + assert get_importable_packages() == {"foo"}