Skip to content

ascii() discards str subclass type when repr result is already ASCII #7451

Description

@jseop-lim

Description

ascii() always creates a new plain str from the repr result, even when the repr is already ASCII. CPython's PyObject_ASCII returns the repr object directly when it's already ASCII, preserving str subclass types. This is a CPython compatibility issue.

Root Cause

builtin_ascii() unconditionally converts the repr result to a new AsciiString via to_ascii(), which then becomes a plain str through ToPyObject. The same pattern exists in PyObject::ascii().

CPython reference: object.c#L848-L849

// Key branch: return repr directly when it's already ASCII
if (PyUnicode_IS_ASCII(repr))
    return repr;

Fix

Add an ASCII check before to_ascii() — if the repr is already ASCII, return the repr object directly instead of creating a new string.

Reproduction

class MyStr(str):
    pass

class Foo:
    def __repr__(self):
        return MyStr('hello')

result = ascii(Foo())
print(type(result))

Output

RustPython:

<class 'str'>

CPython:

<class '__main__.MyStr'>

Environment

  • RustPython d248a04 (Python 3.14.0)
  • CPython 3.14.3
  • OS: Debian 12

Activity

  1. added
    C-compatA discrepancy between RustPython and CPython
    on Mar 17, 2026
  2. youknowone commented on Mar 19, 2026

    @youknowone
    Member

    Thank you so much!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

C-compatA discrepancy between RustPython and CPython

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions