Fix the side effect lister for a code summary

Review the AI's codeMedium15 min

Your task

An AI summarized an order-processing function as "validates, charges, returns a confirmation", which made it look safe to reuse. It left out the inventory update, the cache invalidation and an emitted event. You are writing a tool that reads a function body and lists every side effect, so a summary can be checked against it.

An assistant wrote list_side_effects(body_lines). It is in the editor. It has a bug. Find it and fix it.

Input and output:

  • body_lines: the function's source lines, in order.
  • Return the side effects found, in source order: "mutates:<receiver>.<method>" or "event:<name>".

Rules the tests check:

  • Trim whitespace from both ends of each line. Skip an empty line and a line that starts with #.
  • Skip a line with no (. Otherwise take the text before the first (. If it contains =, keep only what follows the last =. Trim it, then keep only what follows the last space or tab. This is the call name, so return db.execute gives db.execute.
  • If the call name is exactly emit_event, the event name is the text between the first two " characters after the (. Report "event:<name>". If there are not two " characters there, report nothing.
  • Otherwise split the call name at its last . into a receiver and a method. Report nothing when there is no . or either part is empty.
  • Report "mutates:<receiver>.<method>" only when the method is one of: charge, commit, delete, execute, insert, invalidate, publish, save, send, set, update, write.
  • Report every finding, including repeats: two identical calls are two side effects.

Examples

list_side_effects(body_lines: list[str]) -> list[str]
Example 1
Inputlist_side_effects(["def process_order(order):", " validate(order)", " charge = gateway.charge(order.card, order.total)", " db.execute(\"UPDATE inventory SET qty = qty - %s WHERE sku = %s\", (order.qty, order.sku))", " cache.invalidate(f\"product:{order.sku}\")", " emit_event(\"order.completed\", order.id)", " return Confirmation(charge.id)"])
Output["mutates:gateway.charge", "mutates:db.execute", "mutates:cache.invalidate", "event:order.completed"]
Example 2
Inputlist_side_effects(["def order_total(order):", " subtotal = sum(order.lines)", " return subtotal * 1.08"])
Output[]