Skip to content

Commit 997a12f

Browse files
Rebase temp/patch-20 on patch-20 (#23)
* Rebase temp/patch-20 onto patch-20 (emitfunc) * Rebase temp/patch-20 onto patch-20 (class_ir) * Rebase temp/patch-20 onto patch-20 (function)
1 parent 3430494 commit 997a12f

3 files changed

Lines changed: 6 additions & 8 deletions

File tree

mypyc/codegen/emitfunc.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -420,8 +420,7 @@ def visit_get_attr(self, op: GetAttr) -> None:
420420
if not merged_branch:
421421
var_name = op.attr.removeprefix(GENERATOR_ATTRIBUTE_PREFIX)
422422
if cl.is_environment:
423-
# A generated class does not "exist" to the user, this is just an unbound
424-
# variable in their code, not a missing attribute on the generated class.
423+
# Environment classes represent locals, so missing attrs are unbound vars.
425424
exc_class = "PyExc_UnboundLocalError"
426425
exc_msg = f"local variable {var_name!r} referenced before assignment"
427426
else:

mypyc/ir/class_ir.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ def __init__(
100100
self.module_name = module_name
101101
self.is_trait = is_trait
102102
self.is_generated = is_generated
103-
# True for env classes where attributes represent locals.
103+
# Environment classes represent locals and should emit UnboundLocalError for missing vars.
104104
self.is_environment = is_environment
105105
self.is_abstract = is_abstract
106106
self.is_ext_class = is_ext_class

mypyc/irbuild/function.py

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -251,6 +251,8 @@ def c() -> None:
251251
assert isinstance(fitem, FuncDef), fitem
252252
generator_class_ir = builder.mapper.fdef_to_generator[fitem]
253253
builder.fn_info.generator_class = GeneratorClass(generator_class_ir)
254+
if builder.fn_info.can_merge_generator_and_env_classes():
255+
builder.fn_info.generator_class.ir.is_environment = True
254256

255257
# Functions that contain nested functions need an environment class to store variables that
256258
# are free in their nested functions. Generator functions need an environment class to
@@ -959,7 +961,6 @@ def gen_native_func_call_and_return(fdef: FuncDef) -> None:
959961
typ, src = builtin_names["builtins.int"]
960962
int_type_obj = builder.add(LoadAddress(typ, src, line))
961963
is_int = builder.builder.type_is_op(impl_to_use, int_type_obj, line)
962-
963964
native_call, non_native_call = BasicBlock(), BasicBlock()
964965
builder.add_bool_branch(is_int, native_call, non_native_call)
965966
builder.activate_block(native_call)
@@ -1092,8 +1093,7 @@ def maybe_insert_into_registry_dict(builder: IRBuilder, fitem: FuncDef) -> None:
10921093

10931094
dispatch_func_obj = builder.load_global_str(fitem.name, line)
10941095
builder.primitive_op(
1095-
py_setattr_op, [dispatch_func_obj, builder.load_str("registry"), registry_dict], line
1096-
)
1096+
py_setattr_op, [dispatch_func_obj, builder.load_str("registry"), registry_dict], line)
10971097

10981098
for singledispatch_func, types in to_register.items():
10991099
# TODO: avoid recomputing the native IDs for all the functions every time we find a new
@@ -1107,8 +1107,7 @@ def maybe_insert_into_registry_dict(builder: IRBuilder, fitem: FuncDef) -> None:
11071107
to_insert = builder.add(load_literal)
11081108
# TODO: avoid reloading the registry here if we just created it
11091109
dispatch_func_obj = load_func(
1110-
builder, singledispatch_func.name, singledispatch_func.fullname, line
1111-
)
1110+
builder, singledispatch_func.name, singledispatch_func.fullname, line)
11121111
registry = load_singledispatch_registry(builder, dispatch_func_obj, line)
11131112
for typ in types:
11141113
loaded_type = load_type(builder, typ, None, line)

0 commit comments

Comments
 (0)