-
-
Notifications
You must be signed in to change notification settings - Fork 3.1k
[mypyc] Generate __setattr__ wrapper #19937
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -42,6 +42,7 @@ | |
| Integer, | ||
| RaiseStandardError, | ||
| Register, | ||
| SetAttr, | ||
| Truncate, | ||
| Unreachable, | ||
| Value, | ||
|
|
@@ -97,6 +98,7 @@ | |
| isinstance_dict, | ||
| ) | ||
| from mypyc.primitives.float_ops import isinstance_float | ||
| from mypyc.primitives.generic_ops import generic_setattr | ||
| from mypyc.primitives.int_ops import isinstance_int | ||
| from mypyc.primitives.list_ops import isinstance_list, new_list_set_item_op | ||
| from mypyc.primitives.misc_ops import isinstance_bool | ||
|
|
@@ -1007,19 +1009,28 @@ def translate_ord(builder: IRBuilder, expr: CallExpr, callee: RefExpr) -> Value | |
| return None | ||
|
|
||
|
|
||
| @specialize_function("__new__", object_rprimitive) | ||
| def translate_object_new(builder: IRBuilder, expr: CallExpr, callee: RefExpr) -> Value | None: | ||
| fn = builder.fn_info | ||
| if fn.name != "__new__": | ||
| return None | ||
|
|
||
| is_super_new = isinstance(expr.callee, SuperExpr) | ||
| is_object_new = ( | ||
| def is_object(callee: RefExpr) -> bool: | ||
| """ | ||
| Returns True for object.<name> calls | ||
| """ | ||
| return ( | ||
| isinstance(callee, MemberExpr) | ||
| and isinstance(callee.expr, NameExpr) | ||
| and callee.expr.fullname == "builtins.object" | ||
| ) | ||
| if not (is_super_new or is_object_new): | ||
|
|
||
|
|
||
| def is_super_or_object(expr: CallExpr, callee: RefExpr) -> bool: | ||
| """ | ||
| Returns True for super().<name> or object.<name> calls. | ||
| """ | ||
| return isinstance(expr.callee, SuperExpr) or is_object(callee) | ||
|
|
||
|
|
||
| @specialize_function("__new__", object_rprimitive) | ||
| def translate_object_new(builder: IRBuilder, expr: CallExpr, callee: RefExpr) -> Value | None: | ||
| fn = builder.fn_info | ||
| if fn.name != "__new__" or not is_super_or_object(expr, callee): | ||
| return None | ||
|
|
||
| ir = builder.get_current_class_ir() | ||
|
|
@@ -1046,3 +1057,28 @@ def translate_object_new(builder: IRBuilder, expr: CallExpr, callee: RefExpr) -> | |
| return builder.add(Call(ir.setup, [subtype], expr.line)) | ||
|
|
||
| return None | ||
|
|
||
|
|
||
| @specialize_function("__setattr__", object_rprimitive) | ||
| def translate_object_setattr(builder: IRBuilder, expr: CallExpr, callee: RefExpr) -> Value | None: | ||
| is_super = isinstance(expr.callee, SuperExpr) | ||
| is_object_callee = is_object(callee) | ||
| if not ((is_super and len(expr.args) >= 2) or (is_object_callee and len(expr.args) >= 3)): | ||
| return None | ||
|
|
||
| self_reg = builder.accept(expr.args[0]) if is_object_callee else builder.self() | ||
| ir = builder.get_current_class_ir() | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What if this is a non-native class? Do we need to anything different?
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
nevermind, the translation doesn't play well with the fact that the non-native class is really a couple of python objects. |
||
| # Need to offset by 1 for super().__setattr__ calls because there is no self arg in this case. | ||
| name_idx = 0 if is_super else 1 | ||
| value_idx = 1 if is_super else 2 | ||
| attr_name = expr.args[name_idx] | ||
| attr_value = expr.args[value_idx] | ||
| value = builder.accept(attr_value) | ||
|
|
||
| if isinstance(attr_name, StrExpr) and ir and ir.has_attr(attr_name.value): | ||
| name = attr_name.value | ||
| value = builder.coerce(value, ir.attributes[name], expr.line) | ||
| return builder.add(SetAttr(self_reg, name, value, expr.line)) | ||
|
|
||
| name_reg = builder.accept(attr_name) | ||
| return builder.call_c(generic_setattr, [self_reg, name_reg, value], expr.line) | ||
Uh oh!
There was an error while loading. Please reload this page.