Fix Three Mako Template Bugs: AST Arg Visitor, Directory Lookup, Comment-Only Blocks

Read the full interview experience this question came from →

Quick Overview

A debugging exercise on Mako, the open-source Python template library, with three injected defects: an AST visitor missing its visit_arg method, a template lookup that fails on a directory path, and comment-only control blocks that do not compile. It tests NodeVisitor dispatch, reading generated code, minimal fixes and regression tests.

Fix Three Mako Template Bugs: AST Arg Visitor, Directory Lookup, Comment-Only Blocks

Company: Stripe

Role: Software Engineer

Category: Software Engineering Fundamentals

Difficulty: hard

Interview Round: Technical Screen

You are given a copy of Mako, the open-source Python template library, into which three defects have been introduced, together with the library's test suite. Find each defect, fix it with a minimal change, and add a regression test for it. Talk through your reasoning as you go. Background on the library: - Mako compiles each template into a Python module and renders the template by calling a function in that module. - A line whose first non-space character is `%` is a control line that becomes a Python statement, such as `% if user:` … `% endif` or `% for item in items:` … `% endfor`. - A line whose first non-space characters are `##` is a template comment. It produces no output. - `${...}` embeds a Python expression, and a tag such as `<%def name="greet(name, punct='!')">` declares a callable whose signature is written in Python syntax. The library parses this embedded Python with the standard `ast` module and walks the trees with `ast.NodeVisitor` subclasses. - A template lookup is configured with a list of directories and resolves a template name such as `/emails/welcome.txt` against them in order. ### Constraints and Clarifications - Exactly three defects are reported, one per Part below. When you are done, the full test suite should pass. - Keep each fix small and local, in the style of the surrounding code, and do not change behavior beyond the defect. - Part 1 gives you the defect and asks for its consequences; Parts 2 and 3 start from a symptom. ### Clarifying Questions - Does a failing test point at each defect, or must some be found from the symptoms alone? - Which Python versions must the fixes support? Syntax-tree node types differ between Python 2 and 3 and across 3.x releases. - When one lookup directory contains a folder with the requested name and a later directory contains a file with that name, which should win? - Should a block whose body is only comments behave exactly like an empty block, for every kind of control line? ### Part 1 — A missing argument handler in the AST code One of the library's `ast.NodeVisitor` subclasses no longer defines a `visit_arg` method. Explain which Python syntax produces `ast.arg` nodes, what the visitor does when it meets a node type it has no method for, and what goes wrong in the library as a result. Then restore the method and write a test that would have caught its removal. ```hint Read the dispatch Look at how NodeVisitor.visit chooses a method, and at which fields an argument node carries. Does anything raise when the method is missing? ``` #### What This Part Should Cover - How visitor dispatch works and why this failure is silent - Which constructs produce argument nodes, including every parameter kind - The concrete effect on the visitor's job and on templates that use such syntax - A test that exercises argument nodes directly and through a template ### Part 2 — A directory where a template file was expected Requesting a template whose name matches a directory rather than a file, for example `/emails` when `emails/` is a folder inside one of the lookup directories, fails with an operating-system error raised while opening that path, instead of the library's normal "template not found" error. Find the cause and fix it. ```hint Compare the predicates List what the code checks about a candidate path before it opens it, and which kinds of filesystem entries pass that check. ``` #### What This Part Should Cover - The faulty check and the exact predicate that should replace it - Behavior across several lookup directories, including a folder that shadows a real file - At least one alternative fix and why the chosen one is better - Tests that build the directory layout in a temporary folder ### Part 3 — A control block that contains only comments This template is valid, but compiling it fails with a Python syntax error reported inside the generated module: ```text % if show_banner: ## banner removed until the redesign ships % endif Welcome ``` Find out why, and fix it so that a control block whose body contains only comments compiles and renders. ```hint Read the generated code Print the module source the library generated and look at the lines around the error. Then compare the statements in that block with the lines of the template block. ``` #### What This Part Should Cover - Why the generated module is not valid Python - Where the generator decides that a block needs a placeholder statement, and which node types it must treat as producing nothing - Other control forms the same mistake breaks: `% else` branches, loops, nested blocks - Template-level regression tests ### What a Strong Answer Covers - A systematic workflow: run the suite, group the failures, reproduce each one in a few lines, and read tracebacks and generated code instead of guessing - Root causes explained precisely enough that each fix follows from them - Minimal, correct fixes that keep the library's existing conventions and public behavior - One regression test per defect, plus the neighboring cases the same mistake would break - Clear narration and sensible ordering under time pressure ### Follow-up Questions - How could the test suite catch a missing visitor method like the one in Part 1 automatically, before any template exercised it? - Instead of deciding when a block needs `pass`, the generator could emit it after every control line. What does each approach cost? - Template names sometimes come from user input. What should the lookup check beyond "is a regular file"? - Two of these defects surface far from their cause. How would you change error reporting so that a template author can diagnose them without reading generated code?

Overview: A debugging exercise on Mako, the open-source Python template library, with three injected defects: an AST visitor missing its visit_arg method, a template lookup that fails on a directory path, and comment-only control blocks that do not compile. It tests NodeVisitor dispatch, reading generated code, minimal fixes and regression tests.

Read the full Stripe Software Engineer interview experience this question came from

|Home/Software Engineering Fundamentals/Stripe
Stripe logo
Stripe
Aug 14, 2026
hardSoftware EngineerTechnical ScreenSoftware Engineering Fundamentals
1
0

You are given a copy of Mako, the open-source Python template library, into which three defects have been introduced, together with the library's test suite. Find each defect, fix it with a minimal change, and add a regression test for it. Talk through your reasoning as you go.

Background on the library:

  • Mako compiles each template into a Python module and renders the template by calling a function in that module.
  • A line whose first non-space character is % is a control line that becomes a Python statement, such as % if user: … % endif or % for item in items: … % endfor .
  • A line whose first non-space characters are ## is a template comment. It produces no output.
  • ${...} embeds a Python expression, and a tag such as <%def name="greet(name, punct='!')"> declares a callable whose signature is written in Python syntax. The library parses this embedded Python with the standard ast module and walks the trees with ast.NodeVisitor subclasses.
  • A template lookup is configured with a list of directories and resolves a template name such as /emails/welcome.txt against them in order.

Constraints and Clarifications

  • Exactly three defects are reported, one per Part below. When you are done, the full test suite should pass.
  • Keep each fix small and local, in the style of the surrounding code, and do not change behavior beyond the defect.
  • Part 1 gives you the defect and asks for its consequences; Parts 2 and 3 start from a symptom.

Clarifying Questions Guidance

  • Does a failing test point at each defect, or must some be found from the symptoms alone?
  • Which Python versions must the fixes support? Syntax-tree node types differ between Python 2 and 3 and across 3.x releases.
  • When one lookup directory contains a folder with the requested name and a later directory contains a file with that name, which should win?
  • Should a block whose body is only comments behave exactly like an empty block, for every kind of control line?

Part 1 — A missing argument handler in the AST code

One of the library's ast.NodeVisitor subclasses no longer defines a visit_arg method. Explain which Python syntax produces ast.arg nodes, what the visitor does when it meets a node type it has no method for, and what goes wrong in the library as a result. Then restore the method and write a test that would have caught its removal.

What This Part Should Cover Guidance

  • How visitor dispatch works and why this failure is silent
  • Which constructs produce argument nodes, including every parameter kind
  • The concrete effect on the visitor's job and on templates that use such syntax
  • A test that exercises argument nodes directly and through a template

Part 2 — A directory where a template file was expected

Requesting a template whose name matches a directory rather than a file, for example /emails when emails/ is a folder inside one of the lookup directories, fails with an operating-system error raised while opening that path, instead of the library's normal "template not found" error. Find the cause and fix it.

What This Part Should Cover Guidance

  • The faulty check and the exact predicate that should replace it
  • Behavior across several lookup directories, including a folder that shadows a real file
  • At least one alternative fix and why the chosen one is better
  • Tests that build the directory layout in a temporary folder

Part 3 — A control block that contains only comments

This template is valid, but compiling it fails with a Python syntax error reported inside the generated module:

% if show_banner:
    ## banner removed until the redesign ships
% endif
Welcome

Find out why, and fix it so that a control block whose body contains only comments compiles and renders.

What This Part Should Cover Guidance

  • Why the generated module is not valid Python
  • Where the generator decides that a block needs a placeholder statement, and which node types it must treat as producing nothing
  • Other control forms the same mistake breaks: % else branches, loops, nested blocks
  • Template-level regression tests

What a Strong Answer Covers Guidance

  • A systematic workflow: run the suite, group the failures, reproduce each one in a few lines, and read tracebacks and generated code instead of guessing
  • Root causes explained precisely enough that each fix follows from them
  • Minimal, correct fixes that keep the library's existing conventions and public behavior
  • One regression test per defect, plus the neighboring cases the same mistake would break
  • Clear narration and sensible ordering under time pressure

Follow-up Questions Guidance

  • How could the test suite catch a missing visitor method like the one in Part 1 automatically, before any template exercised it?
  • Instead of deciding when a block needs pass , the generator could emit it after every control line. What does each approach cost?
  • Template names sometimes come from user input. What should the lookup check beyond "is a regular file"?
  • Two of these defects surface far from their cause. How would you change error reporting so that a template author can diagnose them without reading generated code?