I'm trying to add formatting in a custom exception with rich
. The same string when printed as a string works (the carat becomes bold red), but as an exception it doesn't. It's stranger because the foo=123
gets highlighted automatically in both situations. What am I missing here?
In [7]: class InvalidSpec(ValueError):
...: def __init__(self, args):
...: loc = args.find("=")
...: hdr = "invalid spec: "
...: self.args = (f"{hdr}{args}\n[red][bold]{' ' * (len(hdr) + loc)}^", )
...:
In [8]: rich.print(InvalidSpec("foo=123").args[0])
invalid spec: foo=123
^
In [9]: rich.print(InvalidSpec("foo=123"))
invalid spec: foo=123
[red][bold] ^
Looks like the solution is to convert to string first. Not sure why:
In [102]: try:
...: raise InvalidSpec("foo=1")
...: except Exception as err:
...: c.print(err)
...: c.print(str(err))
...:
invalid spec: foo=1
[red][bold] ^
invalid spec: foo=1
^
Update: thanks to the comment by @InSync, I understand it. when it's not a str
already rich will only do some simple highlighting, not full console markup. For full markup, you have to implement __rich__
.
In [19]: class InvalidSpec(ValueError):
...: def __init__(self, args):
...: super().__init__(args)
...: hdr = "invalid spec: "
...: loc = len(hdr) + args.find("=")
...: self.args = (f"{hdr}{args}\n{' ' * loc}^", )
...: def __rich__(self):
...: loc = self.args[0].find("^")
...: return self.args[0][:loc] + "[red][bold]" + self.args[0][loc:]
...:
In [20]: pprint(InvalidSpec("foo=123"))
invalid spec: foo=123
^
In [21]: print(InvalidSpec("foo=123"))
invalid spec: foo=123
^