Fix real_patterns mutation targeting undeclared extension point#106
Conversation
|
@coderabbitai, full review. |
|
Tip For best results, initiate chat on the files or code changes. 🧩 Analysis chain🏁 Script executed: #!/bin/bash
# Get PR details
gh pr view 106 --repo cppalliance/cppa-weblate-plugin
echo "=== PR DIFF ==="
gh pr diff 106 --repo cppalliance/cppa-weblate-plugin
echo "=== ISSUE 101 ==="
gh issue view 101 --repo cppalliance/cppa-weblate-pluginLength of output: 19024
Overall AssessmentThe PR successfully addresses issue 🔴 Critical Bug —
|
📝 WalkthroughWalkthroughRefactors URL registration to a new adapter: BoostEndpointConfig.ready() delegates to register_boost_endpoint_urls(), which validates weblate.urls.real_patterns and Weblate version, appends an idempotent URLResolver, with tests and docs updated and packaging pinned. ChangesURL Registration Adapter Refactoring
Sequence Diagram(s)sequenceDiagram
participant BoostEndpointConfig
participant Adapter as register_boost_endpoint_urls
participant WeblateUrls as weblate.urls
participant Patterns as real_patterns
BoostEndpointConfig->>Adapter: call register_boost_endpoint_urls()
Adapter->>WeblateUrls: import weblate.urls
Adapter->>Adapter: validate layout and version
Adapter->>WeblateUrls: check for existing boost-endpoint/ resolver
Adapter->>Patterns: append URLResolver("boost-endpoint/") if missing
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related PRs
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 2❌ Failed checks (2 warnings)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (2)
src/boost_weblate/endpoint/weblate_urls_adapter.py (1)
72-80: ⚡ Quick winDocument that early-exit
Noneis cached whenweblate.urlsimport fails.The
lru_cachedecorator makes this function idempotent, but it also caches the earlyreturnat line 88 whenweblate.urlscannot be imported. This means if the module becomes importable later (e.g., after dynamic installation), subsequent calls will not retry. Callers who need to retry must explicitly callregister_boost_endpoint_urls.cache_clear().📝 Suggested docstring addition
`@lru_cache`(maxsize=1) def register_boost_endpoint_urls() -> None: """Append Boost endpoint routes to ``weblate.urls.real_patterns`` once. Weblate builds ``urlpatterns`` from module-level ``real_patterns``. Appending before the ``URL_PREFIX`` wrapper keeps routes under prefix configuration. Idempotent via ``lru_cache``; safe to call from ``AppConfig.ready()``. + + Note: If ``weblate.urls`` import fails on the first call, the function + caches the early-exit ``None`` and will not retry on subsequent calls. + Call ``register_boost_endpoint_urls.cache_clear()`` to force a retry + after the module becomes importable. """🤖 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 `@src/boost_weblate/endpoint/weblate_urls_adapter.py` around lines 72 - 80, The function register_boost_endpoint_urls is wrapped with `@lru_cache`(maxsize=1) so an early return (when importing weblate.urls fails) will be cached and future calls won't retry; update the docstring of register_boost_endpoint_urls to explicitly state that a failed import results in a cached None and callers that need to retry after the module becomes available must call register_boost_endpoint_urls.cache_clear() before re-invoking the function, and mention lru_cache(maxsize=1) so readers can locate the caching behavior.tests/endpoint/test_weblate_urls_adapter.py (1)
151-157: ⚡ Quick winTest environment sensitivity: Route resolution depends on Weblate configuration.
This test calls Django's
resolve()on/boost-endpoint/plugin-ping/, which requires that Django'sROOT_URLCONFis properly configured with Weblate's URL patterns. In test environments where Weblate is not fully configured or when running isolated unit tests, this may raiseResolver404.Consider marking this test as integration-sensitive or conditionally skipping it when Weblate is not configured.
🧪 Suggested approach: Mark test or add conditional skip
Option 1: Mark as integration test with pytest marker:
`@pytest.mark.integration` # or `@pytest.mark.django_db` if using pytest-django def test_plugin_ping_resolves_after_registration() -> None: ...Option 2: Add conditional skip:
def test_plugin_ping_resolves_after_registration() -> None: from django.urls import resolve, Resolver404 try: register_boost_endpoint_urls() match = resolve("/boost-endpoint/plugin-ping/") except Resolver404: pytest.skip("Weblate URL configuration not available in test environment") assert match.url_name == "plugin-ping" assert match.func.__name__ == "plugin_ping"🤖 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/endpoint/test_weblate_urls_adapter.py` around lines 151 - 157, The test test_plugin_ping_resolves_after_registration is fragile because resolving "/boost-endpoint/plugin-ping/" can raise Resolver404 when Weblate URL patterns aren't configured; update the test to either mark it as an integration/django_db test (e.g., add a pytest marker on test_plugin_ping_resolves_after_registration) or add a conditional skip by importing Resolver404 and pytest, wrapping the register_boost_endpoint_urls() + resolve(...) call in a try/except that catches Resolver404 and calls pytest.skip with a short reason; keep the existing assertions unchanged so they only run when route resolution succeeds.
🤖 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 `@tests/endpoint/test_apps.py`:
- Around line 14-29: Add an autouse pytest fixture to
tests/endpoint/test_apps.py that clears the LRU cache of the cached function
register_boost_endpoint_urls before each test so monkeypatched implementations
are exercised; specifically, create a fixture (e.g.,
clear_register_boost_endpoint_urls_cache) marked autouse that calls
register_boost_endpoint_urls.cache_clear() (or the equivalent cache-clear API)
so tests like test_register_plugin_urls_delegates_to_adapter and
test_register_plugin_urls_skips_when_weblate_urls_missing always run against the
fresh, un-cached function.
In `@tests/endpoint/test_weblate_urls_adapter.py`:
- Around line 75-82: Add a test ensuring _assert_weblate_url_layout raises
WeblateUrlLayoutError when _weblate_version() returns "unknown": monkeypatch
_weblate_version to return "unknown", create a fake module object with a
real_patterns attribute (e.g., empty list), and assert that calling
_assert_weblate_url_layout(fake) raises WeblateUrlLayoutError with a message
like "Cannot determine Weblate version"; this verifies the code path where
Version("unknown") is avoided and the explicit WeblateUrlLayoutError is raised.
---
Nitpick comments:
In `@src/boost_weblate/endpoint/weblate_urls_adapter.py`:
- Around line 72-80: The function register_boost_endpoint_urls is wrapped with
`@lru_cache`(maxsize=1) so an early return (when importing weblate.urls fails)
will be cached and future calls won't retry; update the docstring of
register_boost_endpoint_urls to explicitly state that a failed import results in
a cached None and callers that need to retry after the module becomes available
must call register_boost_endpoint_urls.cache_clear() before re-invoking the
function, and mention lru_cache(maxsize=1) so readers can locate the caching
behavior.
In `@tests/endpoint/test_weblate_urls_adapter.py`:
- Around line 151-157: The test test_plugin_ping_resolves_after_registration is
fragile because resolving "/boost-endpoint/plugin-ping/" can raise Resolver404
when Weblate URL patterns aren't configured; update the test to either mark it
as an integration/django_db test (e.g., add a pytest marker on
test_plugin_ping_resolves_after_registration) or add a conditional skip by
importing Resolver404 and pytest, wrapping the register_boost_endpoint_urls() +
resolve(...) call in a try/except that catches Resolver404 and calls pytest.skip
with a short reason; keep the existing assertions unchanged so they only run
when route resolution succeeds.
🪄 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: 87dd90cd-9925-4991-9d0a-5019cd7dfa0e
📒 Files selected for processing (6)
README.mddocs/boost-endpoint-api.mdsrc/boost_weblate/endpoint/apps.pysrc/boost_weblate/endpoint/weblate_urls_adapter.pytests/endpoint/test_apps.pytests/endpoint/test_weblate_urls_adapter.py
There was a problem hiding this comment.
🧹 Nitpick comments (1)
tests/endpoint/test_weblate_urls_adapter.py (1)
50-73: 💤 Low valueOptional: Consider adding a test for the
InvalidVersionexception path.The adapter wraps
Version(version)parsing in a try-except at lines 55-62 ofweblate_urls_adapter.pyto catchInvalidVersionand re-raise asWeblateUrlLayoutError. While the current tests cover"unknown"(lines 50-61) and too-low versions (lines 63-73), there's no test exercising theInvalidVersionexception path with a malformed version string (e.g.,"not.a.version!").This case is unlikely in practice since
importlib.metadata.version("Weblate")returns valid strings or raisesPackageNotFoundError, but a test would complete the coverage of the validation logic.🧪 Optional test case
def test_assert_layout_raises_when_version_malformed( monkeypatch: pytest.MonkeyPatch, ) -> None: """Verify malformed version strings raise WeblateUrlLayoutError.""" fake = types.ModuleType("weblate.urls") fake.real_patterns = [] monkeypatch.setattr( "boost_weblate.endpoint.weblate_urls_adapter._weblate_version", lambda: "not.a.version!", ) with pytest.raises( WeblateUrlLayoutError, match="could not be parsed", ): _assert_weblate_url_layout(fake)🤖 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/endpoint/test_weblate_urls_adapter.py` around lines 50 - 73, Add a test that exercises the InvalidVersion parsing path by monkeypatching boost_weblate.endpoint.weblate_urls_adapter._weblate_version to return a malformed string (e.g., "not.a.version!") and calling _assert_weblate_url_layout with a fake module whose real_patterns = []; assert it raises WeblateUrlLayoutError and matches the "could not be parsed" message so the Version(...) parsing exception path is covered (refer to _assert_weblate_url_layout, _weblate_version, and WeblateUrlLayoutError).
🤖 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.
Nitpick comments:
In `@tests/endpoint/test_weblate_urls_adapter.py`:
- Around line 50-73: Add a test that exercises the InvalidVersion parsing path
by monkeypatching boost_weblate.endpoint.weblate_urls_adapter._weblate_version
to return a malformed string (e.g., "not.a.version!") and calling
_assert_weblate_url_layout with a fake module whose real_patterns = []; assert
it raises WeblateUrlLayoutError and matches the "could not be parsed" message so
the Version(...) parsing exception path is covered (refer to
_assert_weblate_url_layout, _weblate_version, and WeblateUrlLayoutError).
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: d7800631-b3d7-4ba3-87eb-5ea78f05559e
⛔ Files ignored due to path filters (1)
uv.lockis excluded by!**/*.lock
📒 Files selected for processing (4)
pyproject.tomlsrc/boost_weblate/endpoint/weblate_urls_adapter.pytests/endpoint/test_apps.pytests/endpoint/test_weblate_urls_adapter.py
🚧 Files skipped from review as they are similar to previous changes (1)
- tests/endpoint/test_apps.py
Close #101.
Summary by CodeRabbit
Documentation
Refactor
Tests