question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

[Feature Request] `beartype.BeartypeConf.is_color` option to avoid embedding ANSI escape sequences in type-checking violation exception messages

See original GitHub issue

Long time no speak! First of all, awesome work on the recent improvements to BearType, this library really is the gift that keeps on giving.

The Problem

For some reason, BearType colourized exception messages do not play nicely with libraries such as Python Rich, which have their own traceback colourizing system. As you can see from the below image, some of the ANSI codes are not properly escaped.

image

Workaround

Currently I’ve had to work around this issue by using the strip_text_ansi function to replace the exception args before calling the traceback handler.

from beartype import beartype
from beartype.roar import BeartypeException
from beartype._util.text.utiltextcolour import strip_text_ansi
from rich.console import Console

console = Console()

try:
    return func(*args, **kwargs)

except BeartypeException as exc:
    # Beartype applies automatic colouring of exception messages, however this
    # collides with automatic traceback handlers such as `python-rich`. So we
    # strip out the colour codes.
    exc.args = (strip_text_ansi(exc.args[0]),)
    console.print_exception(show_locals=False)

except Exception as exc:
    console.print_exception(show_locals=False)   

This results in a much cleaner message;

image

Proposed Solution

How would you feel about having a flag which makes message colouring in BearType exception messages optional?

Or perhaps a section in the README which has a quick copy/paste monkeypatch which sets all the beartype ANSI variables to empty strings?

Certainly open to other ideas here too, including pushing this problem upstream, although one may argue that the ability to disable colour without relying on tty detection could be useful for beartype users.

Issue Analytics

  • State:closed
  • Created a year ago
  • Reactions:3
  • Comments:5 (3 by maintainers)

github_iconTop GitHub Comments

2reactions
leyceccommented, Oct 6, 2022

Aww. It’s inspirational to hear from long-time users. Thanks for all those kind words! 🤗

Of course… you are totally right. You always are, @foxx. To improve integration with ANSI-unfriendly tooling, …so, most tooling the upcoming patch release of beartype 0.11.1 will expose an option to conditionally disable this on a granular basis.

Let’s dig deeper.

The Man with a Plan: It’s @leycec

Thankfully, we already have an undocumented configuration API. We just need to stuff a new tri-state is_color parameter into that API (always fun!) and then actually document everything (…never fun). In this case, “tri-state” means:

  • If is_color is False, then @beartype will emit no ANSI colours in violation messages from the decorated callable.
  • If is_color is True, then @beartype will always emit ANSI colours in violation messages from the decorated callable – even when standard output is not attached to an interactive terminal.
  • If is_color is None (i.e., the default), then @beartype will conditionally emit ANSI colours in violation messages from the decorated callable when standard output attached to an interactive terminal. This is the current behaviour and the sanest default, really.

Sneak peak or it didn’t happen:

from beartype import beartype, BeartypeConf

@beartype(conf=BeartypeConf(is_color=False))
def monochrome_dreams() -> None:
    return 'A beautiful bluebird came flying down'

# @beartype will now raise a monochrome violation message. \o/
monochrome_dreams()

If We Believe, It Can Happen

I was wondering when the other shoe would drop and somebody would notice that their custom logging and exception handlers were now spewing incomprehensible ANSI escape codes everywhere. Thanks for keeping us honest, @foxx. 😅

1reaction
leyceccommented, Oct 25, 2022

Oh, you’re most welcome. I’m currently putting the finishing touches on public documentation for beartype’s configuration API – including both is_color and a comparable new is_pep484_tower setting. Once finalized, I’ll happily push out a new beartype 0.12.0 release.

Let’s see if this magic happens by Halloween. The Pumpkin King is optimistic. 🎃

Read more comments on GitHub >

github_iconTop Results From Across the Web

option for ignoring terminal escape sequences (eg color codes)?
Feature request : option for ignoring terminal escape sequences (eg color codes); useful for cases where logs contain color codes ...
Read more >
Don't Trust This Title: Abusing Terminal Emulators with ANSI ...
When a user reads the data with the injected ANSI escape characters, it executes the injected commands — in my case, changing the...
Read more >
ANSI escape code - Wikipedia
ANSI escape sequences are a standard for in-band signaling to control cursor location, color, font styling, and other options on video ... ASCII...
Read more >
ANSIColor - Color screen output using ANSI escape sequences
If a program mixes colored output to standard output with output to standard error, this can result in the standard error text having...
Read more >
How can I remove the ANSI escape sequences from a string in ...
Delete them with a regular expression: import re # 7-bit C1 ANSI sequences ansi_escape = re.compile(r''' \x1B # ESC (?: # 7-bit C1...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found