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: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ and Base versions are tracked in the repo-root `VERSION` file.
- Batched branch and worktree GitHub PR-state verification through one
paginated REST read per prune invocation, avoiding one GraphQL query per
branch and failing the scan closed when that read is unavailable.
- Suppressed the redundant `BASE-P142` `pyproject.toml` dependency warning for
projects that explicitly delegate Python dependency synchronization to uv.

## [1.8.0] - 2026-08-15

Expand Down
2 changes: 1 addition & 1 deletion cli/python/base_setup/pyproject.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ def check_pyproject(manifest: BaseManifest) -> tuple[ArtifactCheck, ...]:
return (pyproject_readability_warning(pyproject_path, error),)

checks: list[ArtifactCheck] = [pyproject_metadata_check(data)]
if has_dependency_metadata(data):
if has_dependency_metadata(data) and manifest.python.manager != "uv":
checks.append(pyproject_dependency_warning())
if has_tool_base(data):
checks.append(pyproject_tool_base_warning())
Expand Down
35 changes: 35 additions & 0 deletions cli/python/base_setup/tests/test_diagnostics.py
Original file line number Diff line number Diff line change
Expand Up @@ -813,3 +813,38 @@ def test_doctor_text_reports_ide_fix_guidance(self) -> None:
self.assertIn("github.copilot", error_output)
self.assertIn("Cursor setting: editor.formatOnSave", error_output)
self.assertIn("Fix:", error_output)


def test_check_json_omits_redundant_pyproject_warning_for_uv_project() -> None:
with tempfile.TemporaryDirectory() as tmpdir:
root = Path(tmpdir)
manifest_path = root / "base_manifest.yaml"
manifest_path.write_text(
"project:\n name: demo\npython:\n manager: uv\nartifacts: []\n",
encoding="utf-8",
)
(root / "pyproject.toml").write_text(
"[project]\nname = \"demo-python\"\ndependencies = [\"requests\"]\n",
encoding="utf-8",
)
default_manifest = BaseManifest(
path=Path("default_manifest.yaml"),
project_name="base-defaults",
brewfile=None,
artifacts=(),
)
manifest = read_manifest(manifest_path)

with redirect_stdout(io.StringIO()) as stdout:
status = engine.check_manifest(
fake_context(),
default_manifest,
manifest,
output_format="json",
)

payload = json.loads(stdout.getvalue())
finding_ids = [check["id"] for check in payload["checks"]]
assert status == 0
assert "BASE-P142" not in finding_ids
assert "BASE-P150" in finding_ids
18 changes: 17 additions & 1 deletion cli/python/base_setup/tests/test_pyproject.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,17 @@
from pathlib import Path

from base_setup.manifest import BaseManifest
from base_setup.manifest_model import PythonConfig
from base_setup.pyproject import check_pyproject


def manifest_at(path: Path) -> BaseManifest:
def manifest_at(path: Path, *, python_manager: str | None = None) -> BaseManifest:
return BaseManifest(
path=path,
project_name="demo",
brewfile=None,
artifacts=(),
python=PythonConfig(manager=python_manager),
)


Expand Down Expand Up @@ -95,6 +97,20 @@ def test_dependency_metadata_warns_without_listing_values(self) -> None:
self.assertNotIn("secret", dependency_check.message)
self.assertNotIn("example.invalid", dependency_check.message)

def test_dependency_metadata_is_managed_by_explicit_uv_project_manager(self) -> None:
with tempfile.TemporaryDirectory() as tmpdir:
root = Path(tmpdir)
(root / "pyproject.toml").write_text(
"[project]\nname = \"demo\"\ndependencies = [\"requests\"]\n",
encoding="utf-8",
)
manifest = manifest_at(root / "base_manifest.yaml", python_manager="uv")

checks = check_pyproject(manifest)

self.assertEqual([check.finding_id for check in checks], ["BASE-P140"])
self.assertTrue(checks[0].ok)

def test_tool_base_warns_as_unsupported(self) -> None:
with tempfile.TemporaryDirectory() as tmpdir:
root = Path(tmpdir)
Expand Down
9 changes: 6 additions & 3 deletions docs/doctor-findings.md
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@ Doctor commands use the same diagnostic item fields. The top-level
| `BASE-P132` | IDE CLI PATH status |
| `BASE-P140` | `pyproject.toml` presence and metadata summary |
| `BASE-P141` | `pyproject.toml` readability |
| `BASE-P142` | `pyproject.toml` dependency metadata observed but not reconciled |
| `BASE-P142` | `pyproject.toml` dependency metadata observed without an explicit supported Python manager |
| `BASE-P143` | Unsupported `[tool.base]` configuration |
| `BASE-P150` | uv CLI availability for uv-managed projects or uv command runners |
| `BASE-P151` | uv-managed project `pyproject.toml` presence |
Expand All @@ -198,8 +198,11 @@ as a guarantee that every project dependency import succeeds.
Base only inspects the `pyproject.toml` file beside the active
`base_manifest.yaml`. These findings do not make `pyproject.toml` a Base
configuration source and do not cause Base to install Python dependencies.
Warnings in this range should guide users toward a valid Python project file
without failing the Base manifest check by themselves.
`BASE-P142` applies when dependency metadata is present without an explicit
supported Python manager; projects declaring `python.manager: uv` use the
dedicated uv diagnostics instead. Warnings in this range should guide users
toward a valid Python project file without failing the Base manifest check by
themselves.

`BASE-P150` through `BASE-P155` are uv support diagnostics. They are warnings
when uv tooling or expected uv project files are missing, because check/doctor
Expand Down
7 changes: 5 additions & 2 deletions docs/python-manifest.md
Original file line number Diff line number Diff line change
Expand Up @@ -238,8 +238,11 @@ when you only need to inspect the resolved invocation.

`pyproject.toml` remains the Python project's packaging contract. Base observes
a same-directory `pyproject.toml` during diagnostics, reports whether it is
readable, summarizes standard `[project]` metadata, and warns when dependency
metadata or unsupported `[tool.base]` configuration is present.
readable, and summarizes standard `[project]` metadata. For projects without
an explicit supported Python manager, Base warns when dependency metadata or
unsupported `[tool.base]` configuration is present. When `python.manager: uv`
is declared, uv owns Python dependency synchronization and the dedicated uv
diagnostics report project-file, environment, and lockfile readiness instead.

Base does not treat `pyproject.toml` as an alternate Base manifest. It does not
solve dependencies, execute build backend hooks, generate lockfiles, or install
Expand Down
Loading