-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Open
Labels
C-compatA discrepancy between RustPython and CPythonA discrepancy between RustPython and CPython
Description
Description
str() on an object whose __repr__ returns a str subclass instance incorrectly returns a plain str, discarding the subclass type. CPython preserves the subclass type as-is. This is a CPython compatibility issue.
Root Cause
PyStr::py_new calls input.str(vm) which correctly resolves to the __repr__ return value (a str subclass instance), but then extracts only the raw string data via Self::from(s.as_wtf8().to_owned()) and creates a new plain PyStr, discarding the subclass type.
CPython reference:
unicodeobject.c#L15575-L15596// Key branch: only convert when type is a str subclass if (unicode != NULL && type != &PyUnicode_Type) { Py_SETREF(unicode, unicode_subtype_new(type, unicode)); } return unicode; // when type is exactly str → return PyObject_Str result as-isWhen
type == &PyUnicode_Type(plainstr()call),unicode_new_implreturns thePyObject_Strresult without conversion, preserving the subclass type.
Reproduction
class MyStr(str):
pass
class Foo:
def __repr__(self):
return MyStr('hello')
result = str(Foo())
print(result)
print(type(result))Output
RustPython:
hello
<class 'str'>
CPython:
hello
<class '__main__.MyStr'>
Environment
- RustPython d248a04 (Python 3.14.0)
- CPython 3.14.3
- OS: Debian 12
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
C-compatA discrepancy between RustPython and CPythonA discrepancy between RustPython and CPython