← index #18941PR #18955
Related · high · value 3.129
QUERY · ISSUE

`repr()` does not raise TypeError when `__repr__` returns a non-string

openby jseop-limopened 2026-03-17updated 2026-03-20
bug

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:

True

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

CANDIDATE · PULL REQUEST

tests/cpydiff: Add str return type and subclass preservation differences.

openby jseop-limopened 2026-03-20updated 2026-03-21
tests

Summary

Document two str()-related CPython compatibility differences in tests/cpydiff/:

  1. types_str_strrettype.py: __str__/__repr__ returning a non-string type does not raise TypeError. MicroPython silently converts and prints the value.
    Relates to #18941.

  2. types_str_subclassret.py: str() does not preserve str subclass type from __str__/__repr__ return value. MicroPython always returns a plain str instance.
    Relates to #18942.

Testing

Verified that each test produces different output between CPython and MicroPython:

  • types_str_strrettype.py: CPython raises TypeError, MicroPython prints True.
  • types_str_subclassret.py: CPython prints <class '__main__.MyStr'>, MicroPython prints <class 'str'>.

Tested on unix port, Linux.

Generative AI

I used generative AI tools when creating this PR, but a human has checked the code and is responsible for the code and the description above.

Keyboard

j / / n
next pair
k / / p
previous pair
1 / / h
show query pane
2 / / l
show candidate pane
c
copy suggested comment
r
toggle reasoning
g i
go to index
?
show this help
esc
close overlays

press ? or esc to close

copied