Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -237,7 +237,7 @@ plugins = [
]

[tool.setuptools.packages.find]
include = ["agent", "agent.*", "tools", "tools.*", "hermes_cli", "gateway", "gateway.*", "tui_gateway", "tui_gateway.*", "cron", "acp_adapter", "plugins", "plugins.*", "providers", "providers.*"]
include = ["agent", "agent.*", "tools", "tools.*", "hermes_cli", "hermes_cli.*", "gateway", "gateway.*", "tui_gateway", "tui_gateway.*", "cron", "acp_adapter", "plugins", "plugins.*", "providers", "providers.*"]

[tool.pytest.ini_options]
testpaths = ["tests"]
Expand Down
49 changes: 49 additions & 0 deletions tests/test_packaging_metadata.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,59 @@
from pathlib import Path
import tomllib

from setuptools import find_packages


REPO_ROOT = Path(__file__).resolve().parents[1]


def _packages_find_include():
data = tomllib.loads((REPO_ROOT / "pyproject.toml").read_text(encoding="utf-8"))
return data["tool"]["setuptools"]["packages"]["find"]["include"]


def test_every_on_disk_subpackage_is_covered_by_packages_find():
"""Regression test for #34701 (and the bug class behind #34034 / #28149).

``[tool.setuptools.packages.find]`` ``include`` is hand-maintained. Every
top-level package is listed twice — bare (``hermes_cli``) for the package
itself and ``hermes_cli.*`` for its subpackages — EXCEPT when someone
forgets the wildcard. v0.15.x listed ``hermes_cli`` without ``hermes_cli.*``,
so the wheel shipped ``hermes_cli/*.py`` but dropped the ``dashboard_auth``
and ``proxy`` subpackages. The dashboard then died on every install with
``ModuleNotFoundError: No module named 'hermes_cli.dashboard_auth'``.

This drives setuptools' own discovery against the live tree: every package
that exists on disk and would be found by a permissive ``<name>.*`` scan
must also be found by the actual ``include`` list. A subpackage added under
any listed package without the matching wildcard fails here instead of in a
user's container.
"""
include = _packages_find_include()

# What the real include list actually selects.
selected = set(find_packages(where=str(REPO_ROOT), include=include))

# Top-level packages we ship (bare names in the include list, no wildcard).
top_level = sorted({name for name in include if "." not in name})

# For each shipped top-level package, every on-disk subpackage must be
# covered by the include list.
expected = set(
find_packages(
where=str(REPO_ROOT),
include=[pattern for name in top_level for pattern in (name, f"{name}.*")],
)
)

missing = sorted(expected - selected)
assert not missing, (
"These packages exist on disk but are dropped from the wheel because "
"[tool.setuptools.packages.find] include is missing a wildcard. Add the "
f"matching '<name>.*' entry in pyproject.toml: {missing}"
)


def test_faster_whisper_is_not_a_base_dependency():
data = tomllib.loads((REPO_ROOT / "pyproject.toml").read_text(encoding="utf-8"))
deps = data["project"]["dependencies"]
Expand Down
Loading