Escape control characters in string constants as Python, not as Rust - #6397
Conversation
`Display for PyStaticExpr` rendered string constants with `{value:?}`,
which uses Rust's escaping rules. Rust writes an unprintable character
as `\u{1b}`; Python's `\u` escape takes exactly four hex digits, so that
form is a SyntaxError rather than an escape. Any string constant holding
a C0 control character other than NUL, tab, newline or carriage return
therefore rendered as invalid Python -- an ANSI sequence in a signature
default such as `"\x1b[0m"` is the realistic way to hit it.
The sibling renderer in `pyo3-introspection/src/stubs.rs` already gets
this right, writing `\x1b`. This mirrors its escape table so the two
agree.
The existing test covered `"\0\t\\\""`, the four characters whose Rust
and Python escapes happen to be identical, so the divergence did not
show up.
Merging this PR will degrade performance by 15.72%
|
| Benchmark | BASE |
HEAD |
Efficiency | |
|---|---|---|---|---|
| ❌ | into_biguint_zero |
1.1 µs | 1.4 µs | -21.57% |
| ❌ | into_biguint_small |
1.2 µs | 1.5 µs | -21.54% |
| ❌ | into_bigint_small |
2.6 µs | 3 µs | -12.59% |
| ❌ | critical_section_creation |
1.3 µs | 1.5 µs | -11.24% |
| ❌ | extract_bigint_small |
1.4 µs | 1.5 µs | -10.94% |
Tip
Investigate this regression by commenting @codspeedbot fix this regression on this PR, or directly use the CodSpeed MCP with your agent.
Comparing dylanpulver:fix-str-constant-escapes (99852a5) with main (fe2eb7a)
Footnotes
-
6 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports. ↩
Tpt
left a comment
There was a problem hiding this comment.
Thank you! That's a bit unfortunate to get this code duplicated but not sure setting up a way to get this code shared would be better
Head branch was pushed to by a user without write access
Display for PyStaticExprrenders string constants with{value:?}, which applies Rust's escaping rules. Rust writes an unprintable character as\u{1b}, and Python's\uescape takes exactly four hex digits, so that form is a SyntaxError rather than an escape.Any string constant holding a C0 control character other than NUL, tab, newline or carriage return therefore renders as invalid Python. A signature default such as
"\x1b[0m"is the realistic way to reach it.The sibling renderer in
pyo3-introspection/src/stubs.rsalready writes\x1bhere. This mirrors its escape table so the two agree. I noticed the split while reading both renderers after #6393.The existing test covers
"\0\t\\\"", the four characters whose Rust and Python escapes are identical, so the divergence did not show up.