Skip to content

_splice_methods regex corrupts definition.py when class has helper methods or inconsistent spacing #20

@AK11105

Description

@AK11105

What happened?

_splice_methods in fix.py uses a regex substitution to replace load() and predict() in the scaffold file. It has three failure modes:

  1. Wrong indentation prefix. load_body from the LLM already includes def load(self): and its indented body. Prepending " " to load_body.strip() puts the def line at 4-space indent but leaves the body at 8-space indent. The file becomes syntactically broken.

  2. Lookahead requires a blank line. (?=\n def ) never matches when the LLM returns methods with no blank line separator. Both load_body and predict_body then contain both methods. Validation may pass (predict runs correctly) but load is silently wrong — self._model is never set.

  3. Helper methods break the splice. Any __init__ or private helper between load and predict causes the lookahead to fire on the helper, truncating load early.

Steps to reproduce

  1. Run inference-engine fix on a model whose class has a __init__ or helper method
  2. Observe the resulting definition.py has broken indentation or a truncated load() body
  3. Server loads the model; self._model is None; first prediction crashes

Expected behavior

Use AST to locate exact line ranges of load and predict, then replace by line index in reverse order. Verify the result parses before returning.

def _splice_methods(source: str, load_body: str, predict_body: str) -> str:
    tree = ast.parse(source)
    lines = source.splitlines(keepends=True)
    cls = next(n for n in ast.walk(tree)
               if isinstance(n, ast.ClassDef) and n.name == "_GeneratedModel")
    replacements = {}
    for node in cls.body:
        if isinstance(node, ast.FunctionDef):
            if node.name == "load":
                replacements["load"] = (node.lineno - 1, node.end_lineno, load_body)
            elif node.name == "predict":
                replacements["predict"] = (node.lineno - 1, node.end_lineno, predict_body)
    for _, (start, end, body) in sorted(replacements.items(), key=lambda x: -x[1][0]):
        lines[start:end] = [textwrap.indent(body, "    ") + "\n"]
    result = "".join(lines)
    ast.parse(result)  # verify before returning
    return result

Environment

  • Area: app/cli/commands/fix.py
  • Phase: 8 (fix before Phase 9 begins)
  • Priority: High

Relevant logs or error output

IndentationError: unexpected indent
# or silently: self._model is None at prediction time

Metadata

Metadata

Assignees

Labels

bugSomething isn't working

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions