Files
freemo e0336379f5 fix(robot): correct dedent logic for try...except...finally in indentation_library
Rewrites the block_stack management in fix_python_indentation to correctly
handle try...except...finally blocks in all configurations:

- Single except clause
- Multiple except clauses for the same try
- try...except...finally
- Nested try blocks with outer except
- Nested try with inner finally followed by outer except (critical regression)

Root cause: The original implementation stored only keyword strings in
block_stack (e.g. 'try', 'class', 'other'). Two bugs existed:

1. When 'finally:' was encountered, the code popped the 'try' from the
   stack. This meant subsequent 'except:' clauses for an outer try could
   not find their matching try, producing syntactically invalid Python.

2. The dedent calculation for 'except'/'finally' counted all stack entries
   up to the first 'try', but did not account for nested try blocks where
   the inner try's except/finally had already been processed.

Fix: Replace the flat string stack with a tuple stack of
(keyword, base_indent, has_seen_except_finally). The new logic:

- 'finally:' always belongs to the innermost try. Pop non-try entries,
  set indent to that try's base_indent, then pop the try itself (finally
  closes the block). The outer try remains on the stack.

- 'except:' belongs to the innermost try. If the innermost try has already
  seen an except/finally AND there is an outer try, the inner try is done:
  pop it and use the outer try instead. Otherwise use the innermost try
  and mark it as having seen an except/finally clause.

Adds a Behave BDD feature (tdd_indentation_library_try_except.feature)
with 6 scenarios covering all acceptance criteria from issue #2845.

ISSUES CLOSED: #2845
2026-04-05 07:39:57 +00:00
..