Skip to content

Give FormatsConf.FORMATS AST parsing a strategy layer#162

Open
whisper67265 wants to merge 2 commits into
cppalliance:developfrom
whisper67265:fix/ast-strategy-layer
Open

Give FormatsConf.FORMATS AST parsing a strategy layer#162
whisper67265 wants to merge 2 commits into
cppalliance:developfrom
whisper67265:fix/ast-strategy-layer

Conversation

@whisper67265

@whisper67265 whisper67265 commented Jul 6, 2026

Copy link
Copy Markdown
Collaborator

Close #158.

Summary by CodeRabbit

  • New Features

    • Improved Weblate format detection, including plugin formats, for more reliable compatibility.
  • Bug Fixes

    • Made Weblate format resolution more robust when upstream format definitions change.
    • Improved error reporting when format resolution fails, including clearer version and source details.
    • Added coverage for edge cases to prevent regressions in format loading behavior.

@coderabbitai

coderabbitai Bot commented Jul 6, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 7571627b-2614-40d8-b315-c8ea949253d8

📥 Commits

Reviewing files that changed from the base of the PR and between 9aa801b and 9b34cb2.

📒 Files selected for processing (4)
  • src/boost_weblate/formats/formats_source.py
  • src/boost_weblate/settings_override.py
  • tests/formats/test_weblate_formats_source.py
  • tests/test_weblate_internal_contract.py
🚧 Files skipped from review as they are similar to previous changes (2)
  • tests/test_weblate_internal_contract.py
  • src/boost_weblate/settings_override.py

📝 Walkthrough

Walkthrough

Core WEBLATE_FORMATS path resolution logic is extracted from settings_override.py into a new module formats_source.py, introducing a FormatsSource protocol, AstFormatsConfSource implementation, structured FormatsSourceResolutionError, and resolve_core_weblate_formats(). Tests and internal contract test imports are updated accordingly.

Changes

FormatsConf resolution extraction

Layer / File(s) Summary
Error type and protocol contract
src/boost_weblate/formats/formats_source.py
Defines FormatsSourceResolutionError and the FormatsSource protocol with core_format_paths(), plus helpers for upstream version and file path lookup.
AST parsing and source implementation
src/boost_weblate/formats/formats_source.py
Adds parse_formatsconf_formats_ast() to extract FormatsConf.FORMATS from source text, implements AstFormatsConfSource.core_format_paths() with error wrapping, and exposes resolve_core_weblate_formats() as the public entry point with version-enriched RuntimeError.
settings_override.py refactor
src/boost_weblate/settings_override.py
Removes local AST/file-reading helpers and replaces them with imports from formats_source; keeps _parse_formatsconf_formats_ast as a backward-compatible alias; weblate_formats_with_plugin_formats() now delegates core-path resolution to resolve_core_weblate_formats().
New module tests
tests/formats/test_weblate_formats_source.py
Adds tests validating AstFormatsConfSource output against direct AST parsing, RuntimeError content on resolution failure (including version), and correct handling of an explicit falsy FormatsSource.
Contract test import update
tests/test_weblate_internal_contract.py
Updates the import of parse_formatsconf_formats_ast to come from formats_source, aliased to the previous private name.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Sequence Diagram(s)

sequenceDiagram
  participant settings_override
  participant resolve_core_weblate_formats
  participant AstFormatsConfSource
  participant models_py as "weblate formats/models.py"

  settings_override->>resolve_core_weblate_formats: call resolve_core_weblate_formats()
  resolve_core_weblate_formats->>AstFormatsConfSource: core_format_paths()
  AstFormatsConfSource->>models_py: read source file
  models_py-->>AstFormatsConfSource: FormatsConf.FORMATS text
  AstFormatsConfSource-->>resolve_core_weblate_formats: parsed format paths or FormatsSourceResolutionError
  resolve_core_weblate_formats-->>settings_override: tuple of format paths or RuntimeError
Loading

Possibly related PRs

  • cppalliance/cppa-weblate-plugin#107: Both PRs replace prior AST-based extraction of FormatsConf.FORMATS in settings_override.py, with this PR refactoring that logic into formats_source.py.
  • cppalliance/cppa-weblate-plugin#122: Both PRs modify the same WEBLATE_FORMATS bootstrap path that parses upstream FormatsConf.FORMATS via AST and extends it with plugin registry paths.

Suggested reviewers: henry0816191, wpak-ai

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main change: introducing a strategy layer for FormatsConf.FORMATS AST parsing.
Linked Issues check ✅ Passed The changes align with #158: strategy module added, falsy sources are honored, error messages include version/detail/source, and contract tests were updated.
Out of Scope Changes check ✅ Passed All changes support the strategy-layer refactor and its tests; no unrelated functionality was introduced.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
tests/formats/test_weblate_formats_source.py (1)

51-53: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

Escape version string before using as regex pattern.

match=weblate_version treats the version string as a regex. If the installed Weblate version contains regex metacharacters (e.g. + in a dev/pre-release tag), the match could silently behave differently than intended. Use re.escape() for a precise, robust check.

🔧 Proposed fix
+import re
+
     weblate_version = importlib.metadata.version("Weblate")
-    with pytest.raises(RuntimeError, match=weblate_version) as exc_info:
+    with pytest.raises(RuntimeError, match=re.escape(weblate_version)) as exc_info:
         resolve_core_weblate_formats()
🤖 Prompt for 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.

In `@tests/formats/test_weblate_formats_source.py` around lines 51 - 53, The test
in resolve_core_weblate_formats uses the Weblate version string directly as the
pytest.raises match pattern, which can be interpreted as a regex. Update the
assertion to escape the imported version from
importlib.metadata.version("Weblate") before passing it to match, so the check
is exact and robust even when the version contains regex metacharacters. Use the
existing resolve_core_weblate_formats and weblate_version symbols to locate the
change.
🤖 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 `@src/boost_weblate/formats/weblate_formats_source.py`:
- Line 121: The source selection in the formats resolver is treating any falsy
value as missing, so explicitly provided strategy objects that implement
__bool__ or __len__ can be incorrectly replaced. Update the source
initialization in the relevant resolver (where resolved is assigned from source
and AstFormatsConfSource) to default only when source is None, preserving any
caller-provided falsy strategy instance.

---

Nitpick comments:
In `@tests/formats/test_weblate_formats_source.py`:
- Around line 51-53: The test in resolve_core_weblate_formats uses the Weblate
version string directly as the pytest.raises match pattern, which can be
interpreted as a regex. Update the assertion to escape the imported version from
importlib.metadata.version("Weblate") before passing it to match, so the check
is exact and robust even when the version contains regex metacharacters. Use the
existing resolve_core_weblate_formats and weblate_version symbols to locate the
change.
🪄 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: defaults

Review profile: CHILL

Plan: Pro

Run ID: b68a8f05-f843-47c0-b3c7-8c5371a0ed46

📥 Commits

Reviewing files that changed from the base of the PR and between 1d5983c and 9aa801b.

📒 Files selected for processing (4)
  • src/boost_weblate/formats/weblate_formats_source.py
  • src/boost_weblate/settings_override.py
  • tests/formats/test_weblate_formats_source.py
  • tests/test_weblate_internal_contract.py

Comment thread src/boost_weblate/formats/weblate_formats_source.py Outdated
@whisper67265 whisper67265 requested a review from henry0816191 July 6, 2026 19:36

@henry0816191 henry0816191 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm

@henry0816191 henry0816191 requested a review from wpak-ai July 6, 2026 21:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

FormatsConf AST strategy layer + graceful fallback

2 participants