Port, board and/or hardware
Unix port, Linux
MicroPython version
v1.27.0
Reproduction
class Foo:
def __repr__(self):
return True
print(repr(Foo()))
Expected behaviour
CPython v3.11.15:
TypeError: __repr__ returned non-string (type bool)
Observed behaviour
MicroPython v1.27.0:
Additional Information
repr() does not raise TypeError when a user-defined __repr__ method returns a non-string value. Instead, MicroPython silently converts and returns the value as a string. This is a CPython compatibility issue.
Root Cause
instance_print in objtype.c calls the user-defined __repr__ method via mp_call_function_1 and passes the result directly to mp_obj_print_helper without validating that the return value is a string.
CPython reference: Objects/object.c#L439-L445
// CPython validates that __repr__ returns a string, raises TypeError otherwise
if (!PyUnicode_Check(res)) {
_PyErr_Format(tstate, PyExc_TypeError,
"__repr__ returned non-string (type %.200s)",
Py_TYPE(res)->tp_name);
Py_DECREF(res);
return NULL;
}
Fix
Add a mp_obj_is_str(r) check after calling the __repr__ method in instance_print, and raise TypeError if the return value is not a string.
Code of Conduct
Yes, I agree
Port, board and/or hardware
Unix port, Linux
MicroPython version
v1.27.0
Reproduction
Expected behaviour
CPython v3.11.15:
Observed behaviour
MicroPython v1.27.0:
Additional Information
repr()does not raiseTypeErrorwhen a user-defined__repr__method returns a non-string value. Instead, MicroPython silently converts and returns the value as a string. This is a CPython compatibility issue.Root Cause
instance_printinobjtype.ccalls the user-defined__repr__method viamp_call_function_1and passes the result directly tomp_obj_print_helperwithout validating that the return value is a string.Fix
Add a
mp_obj_is_str(r)check after calling the__repr__method ininstance_print, and raiseTypeErrorif the return value is not a string.Code of Conduct
Yes, I agree