def rewrite_setattr(func, env): """ Resolve missing attributes through __setattr__ """ context = env['flypy.typing.context'] b = Builder(func) for op in func.ops: if op.opcode == 'setfield': obj, attr, value = op.args obj_type = context[obj] attr_type = types.String[()] if attr not in obj_type.fields and attr not in obj_type.layout: assert SETATTR in obj_type.fields, attr b.position_after(op) # Construct attribute string attr_string = OConst(attr) # call(getfield(obj, '__setattr__'), ['attr', value]) method_type = make_method(obj_type, SETATTR) method = b.getfield(ptypes.Opaque, obj, SETATTR) call = b.call(ptypes.Opaque, method, [attr_string, value]) op.delete() # Update context del context[op] context[method] = method_type context[call] = types.Void[()] context[attr_string] = attr_type