TurboGears / TurboGears/backlash
Compiled regex patterns are rendered incorrectly in debug_repr output
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 13
- Forks
- 13
- PR merge metrics
- No merged PRs in 30d
Description
Goal
Render compiled regex patterns correctly in debug_repr output: escape the
pattern for HTML and restore the quoting that repr() provides.
Done when: debug_repr(re.compile(...)) renders the pattern as readable text
for any pattern content, and a test covers a pattern containing markup
characters and a bytes pattern.
Reproduction (reproduces on Python 3.9 through 3.14):
import re
from backlash.repr import debug_repr
print(debug_repr(re.compile('<img src=x>')))
print(debug_repr(re.compile(b'a&b')))
print(debug_repr(re.compile('\n')))
Current output:
re.compile(<span class="string regex">r'<img src=x>'</span>)
re.compile(<span class="string regex">r'b'a&b''</span>)
re.compile(<span class="string regex">r'
'</span>)
Three separate defects, all from the same expression:
- The pattern is not passed through
escape(), so<img src=x>is emitted as
raw markup and the browser consumes it as a tag instead of displaying it. The
user sees the pattern silently disappear from the console output. - A bytes pattern renders as the nonsense
r'b'a&b'', becausestr()is
applied to the bytes object and then wrapped in another set of quotes. - A pattern containing a newline emits a literal newline inside the quotes,
breaking the single-line rendering the<span>is styled for.
Cause: backlash/repr.py builds the markup with
're.compile(<span class="string regex">r\'%s\'</span>)' % obj.pattern, using
the raw pattern with neither escape() nor repr().
Suggested minimal fix: render escape(repr(obj.pattern)) instead, which
restores quoting and escapes the markup in one step, and matches how the
sibling methods in the same class already handle strings.
Why
debug_repr is what the interactive console prints, so a regex in scope is
displayed wrongly or not at all. A pattern is exactly the kind of value someone
inspects while debugging a matching problem, and silently dropping part of it
(or showing r'b'a&b'') actively misleads.
The other repr methods in the same class already escape their output, so this is
an inconsistency within one class rather than a design choice.
Reachability note: debug_repr is only called from backlash/console.py, so
this affects the interactive console rather than the plain traceback page.
Verified as pre-existing rather than a regression: the pre-modernization code
had separate Python 2 and Python 3 branches here, and only the Python 2 branch
applied repr(); the Python 3 branch never escaped either.
References
backlash/repr.py(DebugReprGenerator.regex_repr;py3_text_reprand
py3_binary_reprin the same class show the escaping pattern used elsewhere)backlash/console.py(_ConsoleFrame/stream write path that callsdebug_repr)backlash/utils.py(escape)tests/test_repr.pymay be a natural home for a regression test
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start in backlash/repr.py at DebugReprGenerator.regex_repr, comparing py3_text_repr and py3_binary_repr with the escape helper in backlash/utils.py. Update the regex representation so compiled text and bytes patterns preserve repr() quoting, escape markup, and keep newlines on one rendered line. Add regression coverage in tests/test_repr.py for markup characters and a bytes pattern, then run that test file.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- devtools
- Issue type
- Bug
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Activity status
- Quiet
- Clarity
- Clearly specified
- Newbie friendliness
- 88/100