"""Robot library providing helpers for inline Python scripts.""" from __future__ import annotations def fix_python_indentation(script: str) -> str: """Reconstruct indentation lost when Robot strips leading spaces. Args: script: Source code with indentation removed from the start of each line. Returns: Script with indentation restored so Python can execute it. """ lines = script.split("\n") result: list[str] = [] indent_level = 0 block_stack: list[str] = [] for line in lines: stripped = line.strip() if not stripped: result.append("") continue is_dedenting = stripped.startswith( ("else:", "elif ", "except:", "except ", "finally:") ) # Check if we should dedent from a class/function body back to module level # This happens when we see import, class, or a top-level statement after a class is_module_level_statement = False # If we're inside a class and see an import, we need to dedent if ( indent_level > 0 and block_stack and ( stripped.startswith(("import ", "from ")) or (stripped.startswith("class ") and block_stack[-1] == "class") ) ): is_module_level_statement = True if is_dedenting and block_stack: if stripped.startswith(("except:", "except ", "finally:")): dedent_levels = 0 for block in reversed(block_stack): dedent_levels += 1 if block == "try": break indent_level = max(0, indent_level - dedent_levels) else: indent_level = max(0, indent_level - 1) elif is_module_level_statement: # Dedent back to module level indent_level = 0 block_stack.clear() current_indent = indent_level result.append(" " * current_indent + stripped) if stripped.startswith("try:"): block_stack.append("try") indent_level += 1 elif stripped.startswith(("except:", "except ", "finally:")): while block_stack and block_stack[-1] != "try": block_stack.pop() if ( stripped.startswith("finally:") and block_stack and block_stack[-1] == "try" ): block_stack.pop() indent_level += 1 elif stripped.endswith(":") and not is_dedenting: if stripped.startswith("class "): block_stack.append("class") else: block_stack.append("other") indent_level += 1 elif is_dedenting and stripped.endswith(":"): indent_level += 1 return "\n".join(result)