Skip to content

Commit

Permalink
allow adding names to except*
Browse files Browse the repository at this point in the history
  • Loading branch information
cfbolz committed Mar 27, 2024
1 parent e18b9f1 commit 258eb95
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 14 deletions.
33 changes: 29 additions & 4 deletions pypy/interpreter/astcompiler/codegen.py
Original file line number Diff line number Diff line change
Expand Up @@ -1083,17 +1083,42 @@ def visit_TryStar(self, tr):
self.load_const(self.space.w_None)
self.emit_op(ops.IS_OP)
self.emit_jump(ops.POP_JUMP_IF_TRUE, pop_next_except)
if handler.name is None:
self.emit_op(ops.POP_TOP)
else:
assert 0, "implement me"

exception_in_exc_body = self.new_block() # R1 in comment above
cleanup_body = self.new_block()
if handler.name is not None:
self.name_op(handler.name, ast.Store, handler)
else:
self.emit_op(ops.POP_TOP)
## generate the equivalent of:
##
## try:
## < body >
## except* type as name:
## try:
## < body >
## name = None
## del name
## except:
## name = None
## del name
## continue with except* handling
#
self.emit_jump(ops.SETUP_EXCEPT, exception_in_exc_body)
self._visit_body(handler.body)
self.emit_op(ops.POP_BLOCK) # XXX missing in CPython comment
if handler.name:
self.load_const(self.space.w_None)
self.name_op(handler.name, ast.Store, handler)
self.name_op(handler.name, ast.Del, handler)
self.emit_jump(ops.JUMP_FORWARD, next_except_with_nop)

self.use_next_block(exception_in_exc_body)
if handler.name:
self.load_const(self.space.w_None)
self.name_op(handler.name, ast.Store, handler)
self.name_op(handler.name, ast.Del, handler)

self.emit_op(ops.POP_TOP) # get rid of type
self.emit_op_arg(ops.LIST_APPEND, 3)
self.emit_op(ops.POP_TOP)
Expand Down
33 changes: 24 additions & 9 deletions pypy/interpreter/astcompiler/test/apptest_exceptiongroup.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,19 +52,34 @@ def test_error_in_exception_handler():
assert 0, "an ExceptionGroup should be raised"

def test_name_except_star():
l = []
value = ValueError()
typ = TypeError()
try:
raise TypeError()
raise ExceptionGroup('abc', [value, typ])
except* TypeError as e1:
a = 1
assert e1 is exc
assert e1.exceptions[0] is typ
l.append(1)
except* ValueError as e2:
assert 0, "unreachable"
assert a == 1
assert e2.exceptions[0] is value
l.append(2)
print(l)
assert l == [1, 2]
with raises(UnboundLocalError):
e1
with raises(UnboundLocalError):
e2

def test_bare_except_star():
def test_try_star_name_raise_in_except_handler():
l = []
value = ValueError()
typ = TypeError()
try:
raise TypeError()
except*:
pass
try:
raise ExceptionGroup('abc', [value, typ])
except* TypeError as e1:
1 / 0
except Exception as e:
assert "ZeroDivisionError" in repr(e)
with raises(UnboundLocalError):
e1
1 change: 0 additions & 1 deletion pypy/interpreter/pyopcode.py
Original file line number Diff line number Diff line change
Expand Up @@ -1806,7 +1806,6 @@ def CHECK_EG_MATCH(self, oparg, next_instr):
self.pushvalue(w_match)

def PREP_RERAISE_STAR(self, oparg, next_instr):
# TODO: Implement
space = self.space
w_res = self.popvalue()
w_orig = self.popvalue()
Expand Down

0 comments on commit 258eb95

Please sign in to comment.