Skip to content

Commit

Permalink
Simplify package_dir in auto-discovery (#3249)
Browse files Browse the repository at this point in the history
  • Loading branch information
abravalheri committed Apr 6, 2022
2 parents db03453 + dc6b21b commit e5552d3
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 3 deletions.
1 change: 1 addition & 0 deletions changelog.d/3249.misc.rst
@@ -0,0 +1 @@
Simplified ``package_dir`` obtained via auto-discovery.
27 changes: 25 additions & 2 deletions setuptools/config/expand.py
Expand Up @@ -312,8 +312,12 @@ def find_packages(
where = kwargs.pop('where', ['.'])
packages: List[str] = []
fill_package_dir = {} if fill_package_dir is None else fill_package_dir
search = list(unique_everseen(always_iterable(where)))

for path in unique_everseen(always_iterable(where)):
if len(search) == 1 and all(not _same_path(search[0], x) for x in (".", root_dir)):
fill_package_dir.setdefault("", search[0])

for path in search:
package_path = _nest_path(root_dir, path)
pkgs = PackageFinder.find(package_path, **kwargs)
packages.extend(pkgs)
Expand All @@ -326,8 +330,27 @@ def find_packages(
return packages


def _same_path(p1: _Path, p2: _Path) -> bool:
"""Differs from os.path.samefile because it does not require paths to exist.
Purely string based (no comparison between i-nodes).
>>> _same_path("a/b", "./a/b")
True
>>> _same_path("a/b", "a/./b")
True
>>> _same_path("a/b", "././a/b")
True
>>> _same_path("a/b", "./a/b/c/..")
True
>>> _same_path("a/b", "../a/b/c")
False
>>> _same_path("a", "a/b")
False
"""
return os.path.normpath(p1) == os.path.normpath(p2)


def _nest_path(parent: _Path, path: _Path) -> str:
path = parent if path == "." else os.path.join(parent, path)
path = parent if path in {".", ""} else os.path.join(parent, path)
return os.path.normpath(path)


Expand Down
32 changes: 31 additions & 1 deletion setuptools/tests/config/test_expand.py
Expand Up @@ -130,7 +130,7 @@ def test_resolve_class(tmp_path, package_dir, file, module, return_value):
({}, {"pkg", "other", "dir1", "dir1.dir2"}), # default value for `namespaces`
]
)
def test_find_packages(tmp_path, monkeypatch, args, pkgs):
def test_find_packages(tmp_path, args, pkgs):
files = {
"pkg/__init__.py",
"other/__init__.py",
Expand All @@ -153,3 +153,33 @@ def test_find_packages(tmp_path, monkeypatch, args, pkgs):
]

assert set(expand.find_packages(where=where, **args)) == pkgs


@pytest.mark.parametrize(
"files, where, expected_package_dir",
[
(["pkg1/__init__.py", "pkg1/other.py"], ["."], {}),
(["pkg1/__init__.py", "pkg2/__init__.py"], ["."], {}),
(["src/pkg1/__init__.py", "src/pkg1/other.py"], ["src"], {"": "src"}),
(["src/pkg1/__init__.py", "src/pkg2/__init__.py"], ["src"], {"": "src"}),
(
["src1/pkg1/__init__.py", "src2/pkg2/__init__.py"],
["src1", "src2"],
{"pkg1": "src1/pkg1", "pkg2": "src2/pkg2"},
),
(
["src/pkg1/__init__.py", "pkg2/__init__.py"],
["src", "."],
{"pkg1": "src/pkg1"},
),
],
)
def test_fill_package_dir(tmp_path, files, where, expected_package_dir):
write_files({k: "" for k in files}, tmp_path)
pkg_dir = {}
kwargs = {"root_dir": tmp_path, "fill_package_dir": pkg_dir, "namespaces": False}
pkgs = expand.find_packages(where=where, **kwargs)
assert set(pkg_dir.items()) == set(expected_package_dir.items())
for pkg in pkgs:
pkg_path = find_package_path(pkg, pkg_dir, tmp_path)
assert os.path.exists(pkg_path)

0 comments on commit e5552d3

Please sign in to comment.