Duplicate-definition gate cannot see definitions inside module-level control flow or same-name closures in one parent - #321
Duplicate-definition gate cannot see definitions inside module-level control flow or same-name closures in one parent#321jaylfc wants to merge 1 commit into
Conversation
…parent closures - Definitions inside module-level if/try/for/while/with now share module scope - Same-name closures inside one parent function are reported - Same-name closures in different parents stay legal - try/except ImportError fallback pattern stays silent - Added tests for all four new behaviours
|
ⓘ Qodo reviews are paused because your trial has ended. Ask your workspace admin to add credits to resume reviews. Manage billing |
|
Warning Review limit reached
Next review available in: 19 minutes Limit details: You’ve used all 1 included review currently available under your plan. You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (3)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
| return False | ||
| try_body_defs = [d for d in defs if not d.in_import_error_except] | ||
| import_error_defs = [d for d in defs if d.in_import_error_except] | ||
| return len(try_body_defs) == 1 and len(import_error_defs) == 1 |
There was a problem hiding this comment.
WARNING: _is_try_import_error_fallback does not account for definitions in else or finally blocks
_collect_definitions recurses into node.orelse (line 208) and node.finalbody (line 218) with in_try=True, so those definitions are included in try_body_defs (line 105). The fallback check requires exactly one try-body-side definition, but a legitimate try/except ImportError pattern with a same-named definition in the else block (or finally block) will have two try-body-side definitions and be incorrectly reported as a duplicate.
For example, the following valid import-fallback pattern would be flagged:
try:
from foo import bar
except ImportError:
from foo import baz as bar
else:
def bar(): # same name, different purpose
..._is_try_import_error_fallback should exclude else/finally definitions from the try-body count, or explicitly check that no extra definitions exist in those blocks.
Reply with @kilocode-bot fix it to have Kilo Code address this issue.
Code Review SummaryStatus: 1 Issue Found | Recommendation: Address before merge Overview
Issue Details (click to expand)WARNING
Files Reviewed (3 files)
Fix these issues in Kilo Cloud Reviewed by step-3.7-flash · Input: 47.3K · Output: 9.9K · Cached: 412.2K |
Review: BLOCKReviewed at Suite on the trial merge: 1485 passed, 12 skipped (master baseline 1479/12). That is +6 against 8 new tests, and the difference is accounted for: The card's work items are done, and proven RED firstMaster's gate and this branch's gate over the same inputs, required to disagree: Swapping master's gate under this branch's new tests: 6 of the 8 fail. The 2 that pass on both are Standing control BLOCKER 1 —
|
|
Revision card is |
…class scanning, and pin every scope with a parity corpus (#333) Fourth pass over this gate and the first where every blocker moved. All ten cases from card tsk-2ohqj4's table now give the required verdict, re-measured by importing each gate version by path and calling _duplicate_definitions directly: CASE master #328 #333 WANTS CTRL+ modlevel def then def in if-body silent FIRES FIRES FIRES CTRL+ plain module duplicate FIRES FIRES FIRES FIRES CTRL- closures in DIFFERENT parents silent silent silent silent CTRL- ImportError fallback silent silent silent silent B1 platform if/else arms silent FIRES silent silent B1 elif chain arms silent FIRES silent silent B1 try/except/else sibling arms silent FIRES silent silent B2 ModuleNotFoundError fallback silent FIRES silent silent B2 ModuleNotFoundError in a tuple silent FIRES silent silent B3 nested-class duplicate methods FIRES silent FIRES FIRES The master and #328 columns reproduce the card's recorded table exactly, which is what shows the instrument is sound rather than agreeing with itself. Sibling arms are tracked by (statement id, arm); a definition with no arm tracker always collides. So module-level def still collides with def in an if body, while if and else arms do not collide with each other, which is the binding truth the rule encodes. Nested classes are scanned at any depth with the correct class Outer.Inner scope string. The tests discriminate: this PR's test file scores 44 passed against the shipped gate and 6 failed / 38 passed against #328's gate. test_scope_parity_ corpus is among the failures. It asserts the full verdict tuple (scope, name, exact lines) from literals rather than recomputed logic, so a scope that silently stops firing fails loudly. That is what neither #316 nor #321 had and is the systemic ask of the card. Standing control exec/tsk-v53vta still exits 1 naming all three shadowed tests at [624,1162] [648,1188] [670,1210]. Real tree clean, exit 0. rev-list --merges is 0. The gate blob changed from 0cbab67 to 9ffd023, which is the check #328 failed. Suite 1539 passed, 12 skipped = the 1522 baseline plus exactly the 17 net new tests. Three defects found and carded as tsk-w2ugkt rather than blocked, none a behaviour regression: 1. in_import_error_except is dead code. _is_import_error_handler sets a flag threaded through eleven sites that _duplicate_definitions never reads; the dedup branches only on arm_tracker. Patching it to return False changes no verdict on any constructible input and the full 44-test file still passes. It went dead because this PR's general sibling-arm rule subsumes the special case #321 added. 2. The three exception-spelling tests have zero power: each fixture holds one def and no duplicate at all, so the result is [] on every gate ever written. Same for the corresponding corpus case. 3. changelog.d/tsk-xhvo4a-duplicate-definition-gate-scope.md was deleted while the widening it describes still ships, so that change lands with no changelog line. Carded rather than blocked because the behaviour finding 2 nominally protects is genuinely pinned by the sibling-arm tests, which do fail against #328's gate. A test that passes with its feature deleted is normally blocking here; it is not blocking this time only because the feature it names turned out to be dead, so the test documents a mechanism rather than guarding one. Supersedes #328 and #321. Card: tsk-2ohqj4. Follow-up: tsk-w2ugkt.
CARD TITLE (intent, not commit subject): Duplicate-definition gate cannot see definitions inside module-level control flow or same-name closures in one parent
Autonomous build of board card tsk-xhvo4a.
Files:
.../tsk-xhvo4a-duplicate-definition-gate-scope.md | 2 +
scripts/normalise_handle_gate.py | 178 ++++++++++++++++++---
tests/test_normalise_handle_gate.py | 111 ++++++++++++-
3 files changed, 269 insertions(+), 22 deletions(-)