You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
repr() does not preserve str subclass type returned by __repr__ #18942
When __repr__ returns an instance of a str subclass, repr() discards the subclass type and returns a plain str. CPython preserves the original subclass type. This is a CPython compatibility issue.
Root Cause
mp_builtin_repr() serializes the __repr__ result into a text buffer (vstr) via mp_obj_print_helper(), then constructs a new plain str from that buffer using mp_obj_new_str_from_utf8_vstr(), which hardcodes &mp_type_str as the type. This discards the original str subclass type.
// CPython returns the __repr__ result directly, preserving str subclass typeres= (*Py_TYPE(v)->tp_repr)(v);
if (!PyUnicode_Check(res)) { // PyUnicode_Check accepts str subclasses// raise TypeError...
}
returnres; // original object returned as-is
Fix
Document this as a known difference in tests/cpydiff/ (similar to the existing int subclass entry "No int conversion for int-derived types available"), or change mp_builtin_repr() to return the __repr__ result object directly when it is a str (or subclass) instead of serializing through a buffer.
In my opinion this is a minor discrepancy with CPython and should only be fixed if it can be done at zero cost (no code size change). Fixing it would require a bit of a refactor of how repr and str work.
Agreed, @dpgeorge. Fixing this properly would require a non-trivial refactor, so I understand it can't be addressed right away.
I've added a cpydiff entry for this difference in PR #18955. Since str() is a core builtin and overriding __str__ is common in practice, I used str() as the example rather than repr(). It also covers a related case where the same root cause causes a discrepancy:
Activity
dpgeorge commentedon Mar 18, 2026
Thanks for the report.
In my opinion this is a minor discrepancy with CPython and should only be fixed if it can be done at zero cost (no code size change). Fixing it would require a bit of a refactor of how
reprandstrwork.jseop-lim commentedon Mar 20, 2026
Agreed, @dpgeorge. Fixing this properly would require a non-trivial refactor, so I understand it can't be addressed right away.
I've added a cpydiff entry for this difference in PR #18955. Since
str()is a core builtin and overriding__str__is common in practice, I usedstr()as the example rather thanrepr(). It also covers a related case where the same root cause causes a discrepancy:<class 'str'><class '__main__.MyStr'>Would appreciate a review.
tests/cpydiff: Add two tests for user __str__ return type difference.
dpgeorge commentedon May 14, 2026
Documented in 3ef656a
tests/cpydiff: Add two tests for user __str__ return type difference.