However, we would probably not want to burden all loops with the
exception-handling machinery, so the compiler would have to do some
hacky backtracking (I doubt that the arbitrary lookahead needed to
handle "maybe we got some except clauses coming?" during parsing would
be acceptable) and fill that in *after* recognizing that there are
except clauses in this for statement.
Maybe you’re thinking of a “one-pass” compiler, like the original Pascal compiler, that generates code during parsing. That’s not how modern compilers work anymore. :-) The parser builds an AST, and the code generator uses the whole AST as input. It would not be “hacky” for the compiler to generate different code for the first half of a compound statement depending on how it ends.
(However, it *would* be hacky to vary based on whether a statement was followed by a certain other statement, as that would require going “up” in the AST.)