Skip to content

Commit 3430494

Browse files
fix UnboundLocalError handling for env classes (#9)
1 parent 9c6e615 commit 3430494

4 files changed

Lines changed: 10 additions & 2 deletions

File tree

mypyc/codegen/emitfunc.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -419,7 +419,7 @@ def visit_get_attr(self, op: GetAttr) -> None:
419419
self.emitter.emit_line("}")
420420
if not merged_branch:
421421
var_name = op.attr.removeprefix(GENERATOR_ATTRIBUTE_PREFIX)
422-
if cl.is_generated:
422+
if cl.is_environment:
423423
# A generated class does not "exist" to the user, this is just an unbound
424424
# variable in their code, not a missing attribute on the generated class.
425425
exc_class = "PyExc_UnboundLocalError"
@@ -924,7 +924,7 @@ def emit_traceback(self, op: Branch) -> None:
924924
def emit_attribute_error(self, op: Branch, class_ir: ClassIR, attr: str) -> None:
925925
assert op.traceback_entry is not None
926926
globals_static = self.emitter.static_name("globals", self.module_name)
927-
if class_ir.is_generated:
927+
if class_ir.is_environment:
928928
self.emit_line(
929929
'CPy_UnboundLocalError("%s", "%s", "%s", %d, %s);'
930930
% (

mypyc/ir/class_ir.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ def __init__(
9191
module_name: str,
9292
is_trait: bool = False,
9393
is_generated: bool = False,
94+
is_environment: bool = False,
9495
is_abstract: bool = False,
9596
is_ext_class: bool = True,
9697
is_final_class: bool = False,
@@ -99,6 +100,8 @@ def __init__(
99100
self.module_name = module_name
100101
self.is_trait = is_trait
101102
self.is_generated = is_generated
103+
# True for env classes where attributes represent locals.
104+
self.is_environment = is_environment
102105
self.is_abstract = is_abstract
103106
self.is_ext_class = is_ext_class
104107
self.is_final_class = is_final_class
@@ -231,6 +234,7 @@ def __repr__(self) -> str:
231234
"ClassIR("
232235
"name={self.name}, module_name={self.module_name}, "
233236
"is_trait={self.is_trait}, is_generated={self.is_generated}, "
237+
"is_environment={self.is_environment}, "
234238
"is_abstract={self.is_abstract}, is_ext_class={self.is_ext_class}, "
235239
"is_final_class={self.is_final_class}"
236240
")".format(self=self)
@@ -380,6 +384,7 @@ def serialize(self) -> JsonDict:
380384
"is_ext_class": self.is_ext_class,
381385
"is_abstract": self.is_abstract,
382386
"is_generated": self.is_generated,
387+
"is_environment": self.is_environment,
383388
"is_augmented": self.is_augmented,
384389
"is_final_class": self.is_final_class,
385390
"inherits_python": self.inherits_python,
@@ -438,6 +443,7 @@ def deserialize(cls, data: JsonDict, ctx: DeserMaps) -> ClassIR:
438443

439444
ir.is_trait = data["is_trait"]
440445
ir.is_generated = data["is_generated"]
446+
ir.is_environment = data.get("is_environment", False)
441447
ir.is_abstract = data["is_abstract"]
442448
ir.is_ext_class = data["is_ext_class"]
443449
ir.is_augmented = data["is_augmented"]

mypyc/irbuild/env_class.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ class is generated, the function environment has not yet been
5454
is_generated=True,
5555
is_final_class=True,
5656
)
57+
env_class.is_environment = True
5758
env_class.reuse_freed_instance = True
5859
env_class.attributes[SELF_NAME] = RInstance(env_class)
5960
if builder.fn_info.is_nested:

mypyc/irbuild/generator.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,7 @@ def setup_generator_class(builder: IRBuilder) -> ClassIR:
164164
generator_class_ir = mapper.fdef_to_generator[builder.fn_info.fitem]
165165
if builder.fn_info.can_merge_generator_and_env_classes():
166166
builder.fn_info.env_class = generator_class_ir
167+
generator_class_ir.is_environment = True
167168
else:
168169
generator_class_ir.attributes[ENV_ATTR_NAME] = RInstance(builder.fn_info.env_class)
169170

0 commit comments

Comments
 (0)