Skip to content
This repository was archived by the owner on Mar 2, 2022. It is now read-only.

Commit df17014

Browse files
committed
Match 3.7's try/except code generation
Summary: Python 3.7 made some minor changes to it's generation of the except blocks by moving where the POP_EXCEPT occurs. This just overrides the behavior in the 3.7 compiler to match. Test Plan: ./python -m test.test_compiler
1 parent 7af0f7a commit df17014

File tree

2 files changed

+36
-0
lines changed

2 files changed

+36
-0
lines changed

compiler/pycodegen.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2091,6 +2091,26 @@ def visitAsyncWith(self, node):
20912091

20922092
return super().visitAsyncWith(node)
20932093

2094+
def visitTryFinally(self, node, except_protect=False):
2095+
body = self.newBlock()
2096+
final = self.newBlock()
2097+
self.emit('SETUP_FINALLY', final)
2098+
self.nextBlock(body)
2099+
self.setups.push((TRY_FINALLY, body))
2100+
if node.handlers:
2101+
self.visitTryExcept(node)
2102+
else:
2103+
self.visit(node.body)
2104+
self.emit('POP_BLOCK')
2105+
self.setups.pop()
2106+
self.emit('LOAD_CONST', None)
2107+
self.nextBlock(final)
2108+
self.setups.push((END_FINALLY, final))
2109+
self.visit(node.finalbody)
2110+
self.emit('END_FINALLY')
2111+
if except_protect:
2112+
self.emit('POP_EXCEPT')
2113+
self.setups.pop()
20942114

20952115
def get_default_generator():
20962116
if sys.version_info >= (3, 7):

test_compiler/test_py37.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,22 @@ async def f():
8484
saw_aiter = True
8585
break
8686

87+
def test_try_except_pop_except(self):
88+
"""POP_EXCEPT moved after END_FINALLY in Python 3.7"""
89+
for generator in (Python37CodeGenerator, CodeGenerator):
90+
graph = self.to_graph("""
91+
try:
92+
pass
93+
except Exception as e:
94+
pass
95+
""", generator)
96+
prev_instr = None
97+
for instr in self.graph_to_instrs(graph):
98+
if instr.opname == "POP_EXCEPT":
99+
self.assertEqual(prev_instr.opname == "END_FINALLY", generator is Python37CodeGenerator, prev_instr.opname)
100+
prev_instr = instr
101+
102+
87103
def test_future_annotations(self):
88104
annotations = ["42"]
89105
for annotation in annotations:

0 commit comments

Comments
 (0)