Remove backwards-compat shims guarding private symbols (#163) - #164
Conversation
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
WalkthroughRemove private compatibility aliases and wrappers, route publish pre-flight calls and tests to canonical modules, export publish-plan helpers, standardize bump logging, migrate TOML helper usage, and update developer documentation. ChangesShim removal and canonical-target migration
Possibly related issues
Possibly related PRs
Suggested labels: Suggested reviewers: Poem
Caution Pre-merge checks failedPlease resolve all errors before merging. Addressing warnings is optional.
❌ Failed checks (1 error, 2 warnings)
✅ Passed checks (17 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
5122240 to
9bbce55
Compare
…actors main independently landed this branch's bundled #95/#96/#97, refactored bump.py (new `_CrateManifestOutcome` flow) and publish.py (#73/#96), and re-split the bump tests into differently-named modules. This reconciles the #108 extraction onto main's current tree as a single squashed change (the original 22 commits are preserved on backup/issue-108-pre-rebase2-7df1480). Landed cleanly (all now under the 400-line guideline): - `lading/toml_coerce/` package (scalar/sequence/mapping coercers with structural pattern matching and numpy docstrings) + `config.py` (441->334) and `workspace/models.py` (576->194) consuming it via `functools.partial`. - `lading/workspace/_coercion.py` + `graph_build.py` (builders out of `models`); `cli_options.py` (cyclopts args out of `cli.py`, 449->389); `bump_docs.py` condensed (402->393). - `bump_manifests.py` re-derived against main's bump.py: the low-level manifest helpers, `_WORKSPACE_SELECTORS`, and `_BumpContext` move here; main's `_apply_crate_manifest_update`/`_CrateManifestOutcome` flow stays in `bump` and imports them. `bump.py` 552->427 (further trim is follow-up). Test reconciliation: main's bump-test split is authoritative; this drops the branch's parallel split modules and keeps main's plus the unique `test_toml_coerce.py`. Per the no-compat-alias convention (#164), `test_dependency_sections` now reads `_DEPENDENCY_SECTION_BY_KIND` from `bump_manifests`. Deferred: `publish.py` (741) extraction. main's #73/#96 refactored the extracted pipeline functions and its tests patch `publish._*` seams; extracting now requires rewriting many `monkeypatch.setattr` targets to `publish_pipeline` (no-compat), which needs a focused full-context pass. publish.py is taken from main unchanged; the orphaned `publish_pipeline.py` is removed. Validated: check-fmt, lint (10.00/10), typecheck, test (717 passed, 70 snapshots), markdownlint, nixie — all green. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* Rebase issue-108 onto main; reconcile #108 extraction with main's refactors main independently landed this branch's bundled #95/#96/#97, refactored bump.py (new `_CrateManifestOutcome` flow) and publish.py (#73/#96), and re-split the bump tests into differently-named modules. This reconciles the #108 extraction onto main's current tree as a single squashed change (the original 22 commits are preserved on backup/issue-108-pre-rebase2-7df1480). Landed cleanly (all now under the 400-line guideline): - `lading/toml_coerce/` package (scalar/sequence/mapping coercers with structural pattern matching and numpy docstrings) + `config.py` (441->334) and `workspace/models.py` (576->194) consuming it via `functools.partial`. - `lading/workspace/_coercion.py` + `graph_build.py` (builders out of `models`); `cli_options.py` (cyclopts args out of `cli.py`, 449->389); `bump_docs.py` condensed (402->393). - `bump_manifests.py` re-derived against main's bump.py: the low-level manifest helpers, `_WORKSPACE_SELECTORS`, and `_BumpContext` move here; main's `_apply_crate_manifest_update`/`_CrateManifestOutcome` flow stays in `bump` and imports them. `bump.py` 552->427 (further trim is follow-up). Test reconciliation: main's bump-test split is authoritative; this drops the branch's parallel split modules and keeps main's plus the unique `test_toml_coerce.py`. Per the no-compat-alias convention (#164), `test_dependency_sections` now reads `_DEPENDENCY_SECTION_BY_KIND` from `bump_manifests`. Deferred: `publish.py` (741) extraction. main's #73/#96 refactored the extracted pipeline functions and its tests patch `publish._*` seams; extracting now requires rewriting many `monkeypatch.setattr` targets to `publish_pipeline` (no-compat), which needs a focused full-context pass. publish.py is taken from main unchanged; the orphaned `publish_pipeline.py` is removed. Validated: check-fmt, lint (10.00/10), typecheck, test (717 passed, 70 snapshots), markdownlint, nixie — all green. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * Route coercion errors through _reject; fix stale docstring cross-refs Centralise the canonical error-message shape in the toml_coerce helpers: - `non_negative_int` type/parse-failure arms now raise `_reject(value, field_name, "an integer", error)` (identical message, so the snapshot is unchanged); the `str` arm preserves `from exc` chaining. The negative-value message stays a plain value error (the `"; received {type}."` type-shape does not fit it). - `expect_sequence`'s None-disallowed branch and both `string_matrix` failure arms now route through `_reject`, so they carry the canonical `"; received {type}."` suffix. Regenerated the `preflight.aux_build` line of the `test_coercion_error_messages_are_stable` snapshot accordingly. Docstrings: `_BumpContext` now points at `bump._apply_crate_manifest_update` (the current consumer; `_update_crate_manifest` was removed), and `graph_build`'s module docstring points coercion bindings at `lading.workspace._coercion` rather than `models`. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * Lock down canonical coercion-message contracts in tests Address the "canonical-message branches unguarded" review finding by asserting exact error wording (not just the raised type) on the branches that recently moved to `_reject`, and by covering the `expect_mapping` success path: - `test_expect_sequence_handles_none` now asserts the disallowed-None message `"f must be a sequence; received NoneType."`. - `test_string_matrix_rejects_non_sequence_values` asserts the top-level `"... must be a sequence of string sequences; received <type>."` shape. - `test_string_matrix_rejects_non_string_rows` asserts the row-level `"demo.matrix[1] must be a sequence of strings; received <type>."` shape. - `test_mapping_helpers_reject_non_mappings` becomes `test_mapping_helpers_accept_and_reject_mappings`, adding a passthrough assertion that a valid mapping is returned unchanged. Tests are strengthened in place (no new methods) to stay within the `TestTomlCoerce` PLR0904 public-method cap. The graph_build module-docstring finding was already fixed in the prior commit. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * Dedup coercion rejection-assert tail via a shared helper Resolve the CodeScene "Code Duplication" finding across the four rejection tests. Extract the common raise/capture/assert-substring/assert-type-name tail into a generic `_assert_rejection(call, expected_prefix, bad_value, error)` helper. `_assert_rejects_indexed_non_string` now builds the indexed input and delegates to it, and the two `string_matrix` rejection tests call it directly instead of repeating the tail inline. The `string_tuple` and `validate_string_sequence` rejection tests are unchanged — they already route through `_assert_rejects_indexed_non_string`. All four tests stay distinct, independently discoverable methods; assertion semantics and field-name literals are unchanged. (The helper's summary docstring is wrapped to keep it within the line-length limit.) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> --------- Co-authored-by: leynos <leynos@rohga> Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
525dff0 to
e178994
Compare
|
@coderabbitai resume |
✅ Action performedReviews resumed. |
|
@coderabbitai Have the following now been resolved? lading/commands/bump.py (1)
🤖 Detailed instructionsVerify each finding against current code. Fix only still-valid issues, skip the In lading/commands/publish_plan.py (1)
def append_section[T](...):
...
lines.extend(f"- {formatter(item)}" for item in items)
+ returnAs per coding guidelines and path instructions, public interfaces require NumPy-format docstrings and explicit returns. 🤖 Detailed instructionsVerify each finding against current code. Fix only still-valid issues, skip the In Sources: Coding guidelines, Path instructions |
|
@coderabbitai Have the following now been resolved? lading/commands/bump.py (1)
🤖 Detailed instructionsVerify each finding against current code. Fix only still-valid issues, skip the In lading/commands/publish_plan.py (1)
🤖 Detailed instructionsVerify each finding against current code. Fix only still-valid issues, skip the In Sources: Coding guidelines, Path instructions |
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as resolved.
|
@coderabbitai the rules prohibit implicit return only if the function may return a value. R501 — Avoid Explicit
|
|
@coderabbitai resume |
✅ Action performedReviews resumed. |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@docs/developers-guide.md`:
- Around line 544-554: Add a concise caption immediately before the shim
inventory table in the developers guide, using wording such as “Shim inventory.”
Preserve the table content and formatting unchanged.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: edff1c1d-662e-49a2-abdf-8534b66194cc
📒 Files selected for processing (4)
docs/developers-guide.mdlading/commands/publish_plan.pytests/unit/test_publish_planning.pytypos.toml
🔗 Linked repositories identified
CodeRabbit considers these linked repositories for cross-repo context during reviews:
leynos/cmd-mox(auto-detected)leynos/cuprum(auto-detected)leynos/shared-actions(auto-detected)
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@lading/commands/publish_plan.py`:
- Around line 274-284: Update the PublishPlan doctest in format_plan to
construct workspace_root with Path("ws") instead of an absolute Path("/ws"), and
change the expected “Publish plan for” output to “ws” so the example is
platform-neutral.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: 7981516c-30cc-4d20-bdfd-2c7b1bbfb30d
📒 Files selected for processing (1)
lading/commands/publish_plan.py
🔗 Linked repositories identified
CodeRabbit considers these linked repositories for cross-repo context during reviews:
leynos/cmd-mox(auto-detected)leynos/cuprum(auto-detected)leynos/shared-actions(auto-detected)
`publish_plan` defined `_append_section` and `_format_plan` privately and then re-bound them to public aliases; every consumer used the public names. Rename the definitions to `append_section` and `format_plan`, drop the aliases, and remove the underscore variants (plus the internal `_format_crates_section`) from `__all__`. `publish_execution` carried a `split_command` wrapper over `lading.runtime.subprocess_runner.split_command` whose only purpose was mapping `ValueError` to `PublishPreflightError`. Nothing in production code called it — `cmd_mox_runner` uses the runtime helper directly — so remove the wrapper, its alias, and its only test. Refresh the publish-flow diagram in `docs/lading-design.md`, which still showed `split_command` and the cmd-mox helpers under `publish_execution`; those moved to `lading.testing.cmd_mox_runner` in #76.
Delete the backwards-compatibility layer that `publish.py` kept for test patches after the pre-flight helpers moved to `publish_preflight` (#96, #123): - Drop the eleven bare aliases (`_preflight_argument_sets`, `_CargoPreflightOptions`, `_run_cargo_preflight`, and friends). - Drop the thin `_run_preflight_checks` wrapper that resolved an optional `configuration`; `run()` already resolves configuration before the call, so it now invokes `publish_preflight._run_preflight_checks` directly. - Drop the unused `_append_section`, `_format_plan`, `metadata_module`, `StripPatchesSetting`, and `PublishPlanError` re-bindings. Private symbols carry no stability contract and lading is the only consumer of its own internals, so tests now patch and call the canonical module: conftest fixtures stub `publish_preflight._run_preflight_checks`, the preflight suites target `publish_preflight` directly, and the plan-validation tests raise `publish_plan.PublishPlanError`. The two tests that pinned the wrapper's aliasing behaviour are removed with the wrapper.
Drop the six module-level re-exports (`_parse_manifest`, `_select_table`, `_assign_version`, `_value_matches`, `_update_dependency_sections`, `_update_dependency_table`) that `bump.py` kept solely so existing tests could keep patching the old names. The TOML helper tests now exercise `bump_toml` directly. Also fold the redundant `_log = LOGGER` alias into a single `LOGGER` name; the README-transposition failure path now logs via `LOGGER.exception`, matching the logging convention enforced by lint for handlers that re-raise.
Record in the developers' guide that private symbols carry no stability contract: when a helper moves to a new canonical module, update call sites and test patch targets in the same change instead of leaving aliases or thin wrappers behind. Point recurring churn at an explicit port (as with `CommandRunner`) rather than ad hoc shims. Rewrite the pre-flight validation section, which still described the `publish.py` re-exports and optional-configuration wrapper removed in this branch.
The shim sweep removed `PublishPlanError` from `publish.py` alongside the private compatibility aliases. That exception is public API, however: the still-exported `publish.plan_publication()` raises it, so callers catching `except publish.PublishPlanError` began failing with `AttributeError`. Re-export it explicitly with `PublishPlanError as PublishPlanError` so the public entry point and the exception it raises stay catchable from the same module. The no-alias convention in the developers' guide is clarified to scope it to private, underscore-prefixed symbols, and a regression test asserts `publish.PublishPlanError` remains the canonical class and catches planning failures.
Address review feedback on the compatibility-shim sweep. Expand the "Internal APIs carry no compatibility aliases" section of the developers' guide with a repository-wide inventory mapping every removed private alias, wrapper, and re-export to its canonical replacement, plus a "Retained boundaries" subsection recording why `publish._invoke`, the public `publish.PublishPlanError` re-export, and the `CommandRunner` port are kept. This gives issue #163 an explicit audit trail. Give the now-public `append_section` and `format_plan` helpers full NumPy-style `Parameters`/`Returns` docstrings, and tighten `test_publish_reexports_plan_error_for_public_callers` with a diagnostic assertion message and a `match="dependency cycle"` constraint on the raised `PublishPlanError`.
The markdownlint gate runs `scripts/typos_rollout.py`, which regenerates `typos.toml` from its upstream authority. The tracked file had drifted behind the authority, so the gate refreshed it, adding the `polymerize` word family. Commit the deterministic regeneration to keep the working tree clean; the content is generated, not hand-authored, and unrelated to the shim sweep.
Address review feedback asking the public `append_section` and `format_plan` helpers to demonstrate representative usage. Add NumPy-style `Examples` sections with executable `>>>` doctests, matching the house style used by helpers such as `command_detail`. The `append_section` example shows both the append and the empty-items no-op; the `format_plan` example renders an empty plan. Both doctests pass under `python -m doctest`. Existing `Parameters` and `Returns` sections are unchanged.
Address two review nits on the compatibility-shim documentation.
Add a `#### Shim inventory` subheading before the inventory table in the
developers' guide so the table is captioned, consistent with the sibling
`#### Retained boundaries` heading. A heading is used rather than bold text
because markdownlint MD036 (emphasis-as-heading) is active.
Construct the `format_plan` doctest with a relative `Path("ws")` instead of
an absolute `Path("/ws")` so the rendered "Publish plan for ws" line is
platform-neutral (an absolute path renders differently on Windows). The
doctest still passes.
1c320e2 to
e314b60
Compare
There was a problem hiding this comment.
Our agent can fix these. Install it.
Gates Passed
6 Quality Gates Passed
Absence of Expected Change Pattern
- lading/lading/commands/bump.py is usually changed with: lading/tests/unit/test_cli.py
- lading/lading/commands/publish.py is usually changed with: lading/tests/bdd/steps/test_publish_steps.py
Quality Gate Profile: Pay Down Tech Debt
Install CodeScene MCP: safeguard and uplift AI-generated code. Catch issues early with our IDE extension and CLI tool.
|
@coderabbitai review |
✅ Action performedReview finished.
|
|
@coderabbitai Have the following now been resolved? lading/commands/bump.py (1)
🤖 Detailed instructionsVerify each finding against current code. Fix only still-valid issues, skip the In |
|
Tip For best results, initiate chat on the files or code changes. 🧩 Analysis chain🏁 Script executed: #!/bin/bash
set -euo pipefail
printf '%s\n' '== bump.py import and compatibility-alias regions =='
sed -n '30,58p' lading/commands/bump.py
tail -n 80 lading/commands/bump.py
printf '%s\n' '== Any former private TOML alias assignments in bump.py =='
rg -n -C 3 \
'^\s*_(parse_manifest|select_table|assign_version|value_matches|update_dependency_sections|update_dependency_table)\s*=' \
lading/commands/bump.py || true
printf '%s\n' '== Current bump_toml import/references in bump.py =='
rg -n -C 2 '\bbump_toml\b' lading/commands/bump.py || true
printf '%s\n' '== Production/test callers of the former bump private helpers =='
rg -n -C 2 \
'\bbump\._(parse_manifest|select_table|assign_version|value_matches|update_dependency_sections|update_dependency_table)\b|from\s+lading\.commands\.bump\s+import\s+.*_(parse_manifest|select_table|assign_version|value_matches|update_dependency_sections|update_dependency_table)\b' \
lading tests || true
printf '%s\n' '== PR-head diff for bump-related files =='
git status --short
git diff -- lading/commands/bump.py lading/commands/bump_toml.py tests/unit/test_bump_toml_helpers.py tests/unit/test_bump_manifest_writing.py
git diff --cached -- lading/commands/bump.py lading/commands/bump_toml.py tests/unit/test_bump_toml_helpers.py tests/unit/test_bump_manifest_writing.pyLength of output: 5078
The reported import-time |
Summary
This branch sweeps
lading/for backwards-compatibility shims, aliases, and wrappers guarding private (underscore-prefixed) symbols and removes those serving no genuine external-compatibility need. Private symbols carry no API stability contract, andlading's application code is the only consumer of its own internals, so the ad hoc compatibility layers kept solely so old test patches would keep resolving have been deleted, with the dependent tests retargeted at the canonical implementations.Closes #163.
Inventory and disposition
lading/commands/publish.pypublish_preflightprivates (_preflight_argument_sets,_CargoPreflightOptions,_run_cargo_preflight, and friends)publish_preflightdirectlylading/commands/publish.py_run_preflight_checksthin wrapper preserving the optional-configurationcontractrun()resolves configuration itself and callspublish_preflight._run_preflight_checksdirectlylading/commands/publish.py_append_section,_format_plan,metadata_module,StripPatchesSetting,PublishPlanErrorpublish_plan.PublishPlanErrorlading/commands/bump.pybump_tomlhelpers kept "to maintain backward compatibility", plus the redundant_log = LOGGERaliasbump_tomldirectlylading/commands/publish_plan.py_append_section/_format_planre-bound to the public names every consumer used__all__entries droppedlading/commands/publish_execution.pysplit_commandwrapper (plus_split_command) over the runtime helper, with no production callerscmd_mox_runneralready useslading.runtime.subprocess_runner.split_commandlading/commands/publish.py_invokeimportrun()uses it as the defaultCommandRunner, and tests stub it to intercept subprocess executionNo new port/adapter seam proved necessary: the churn that motivated the shims was a one-off module extraction (#96/#123), and the existing
CommandRunnerprotocol inlading.runtimealready provides the stable boundary for execution concerns.Review walkthrough
run()callingpublish_preflight._run_preflight_checksdirectly.Validation
make check-fmt: passed (137 files already formatted)make lint: passed (ruff clean, interrogate 100%, pylint 10.00/10)make typecheck: passed (ty check, all checks passed)make test: passed (691 passed, 67 snapshots passed)make markdownlint: passed (21 files, 0 errors)make nixie: passed (all diagrams validated)coderabbit review --agent: completed with 0 findingsReferences