Skip to content

utils.escape() raises TypeError for ASCII bytes #35

Description

@amol-

Goal

Make backlash.utils.escape handle bytes input on Python 3.

Done when: escape(b'hello') returns 'hello' instead of raising, and a test
covers both the ASCII and non-ASCII bytes cases.

Reproduction (reproduces on Python 3.9 through 3.14):

from backlash.utils import escape
escape(b'hello')

Current behaviour:

TypeError: a bytes-like object is required, not 'str'

Note that non-ASCII bytes work correctly (escape(b'caf\xc3\xa9') returns
'café'), which is why the failure went unnoticed - only the ASCII path is
broken.

Cause: the bytes branch calls s.decode('ascii') purely as a probe and discards
the result, so ASCII input stays bytes and then reaches
s.replace('&', '&') with str arguments. On Python 2 this was harmless
because bytes was str.

Suggested minimal fix: decode unconditionally with
s = s.decode('utf-8', 'replace') and drop the ASCII probe, since the
replacement decode already handles both cases.

Reachable from the interactive console, where a bogus traceback replaces the
real result:

from backlash.console import Console
Console({}, {}, None).eval("import sys; sys.stdout.write(b'hi')")

Why

escape is the single escaping helper used across traceback rendering and
console output, and HTMLStringO.write routes console writes through it. Any
code under debug that writes ASCII bytes to stdout produces a TypeError
traceback instead of its output, which is confusing precisely when the user is
trying to diagnose something else.

Verified as pre-existing rather than a regression: the same reproduction fails
identically on the commit preceding the recent modernization work.

References

  • backlash/utils.py (escape, the bytes branch)
  • backlash/tbtools.py (HTMLStringO.write) is the console path that reaches it
  • tests/test_utils.py may be a natural home for a regression test

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions