I am trying to troubleshoot why program receiving one set of parameters works (call it v1), while another call with almost the same parameters fails (call that v2).
So I want to diff some complex nested data structures. Trying a yaml dump resulted in errors (there are weakrefs and SQL connection objects). So I used rich.inspect
in the pdb debugger and found some issues - rich is smart enough not to get itself in trouble. So now, I want to dump this out to a text file instead.
Is there a more elegant way than redirecting sys.stdout
? The code below works, but it's fairly ugly near with open("capture2.txt","w") as sys.stdout:
.
cat capture2.txt
prints substantially the same output as the rich.inspect, including the colors. So, that's good, but is there a cleaner way to send rich.inspect to a file? The console
argument looks like it might, but then again it looks more like a way to specify color and terminal behavior, rather than allowing for redirection.
from rich import inspect
import sys
#just a simple way to get some complexity cheap
from types import SimpleNamespace
foo = SimpleNamespace(
a = 1,
name = "Foo",
bar = SimpleNamespace(b=2, name="Bar!", di = dict(a=1,b=2,c=[1,2,3]))
)
#OK, simple prints to screen
inspect(foo)
# is there a better way here 👇
print("redirect stdout")
#save stdout
bup = sys.stdout
with open("capture2.txt","w") as sys.stdout:
inspect(foo)
# restore stdout
sys.stdout = bup
#if I don't restore `sys.stdout` from `bup` => IOError
print("coucou")
p.s. To make diffing easier I did get rid of some of the terminal codes (color and font-related) by using rich.inspect(x,console = Console(force_terminal=False))
.
There are a lot of parameters for Console
. I managed to miss file
:
class Console:
"""A high level console interface.
Args:
color_system (str, optional): The color system supported by your terminal,
either ``"standard"``, ``"256"`` or ``"truecolor"``. Leave as ``"auto"`` to autodetect.
force_terminal (Optional[bool], optional): Enable/disable terminal control codes, or None to auto-detect terminal. Defaults to None.
...
👉file (IO, optional): A file object where the console should write to. Defaults to stdout.
quiet (bool, Optional): Boolean to suppress all output. Defaults to False.
So...
with open("capture2.txt","w") as fo:
console = Console(force_terminal=False,file=fo)
inspect(foo,console=console)
I'll leave that out, hopefully someone will find it useful later.