Thanks for sharing! I like that ic includes a hook for logging, which I think is an advantage over calling print directly. I realize for a lot of examples, they’re quick and dirty but I almost always end up setting up a logger with an stderr or stdout handler so that other handlers can also send it to a file if desired. This makes it easier to run these in production on daemons and such where your code might not have an stdout to print to.
Probably was submitted with the correct title and then rewritten by the HN title modification ruleset.
I think submitters are able to correct the title for a while and that when they do it might(?) override some or all of the rules in the filter. But the time window for doing so has probably been passed now.
Mods could still change the title though.
Either to the original:
Implementing Rust's dbg! in Python
Or if they want to help out those unfamiliar with Rust syntax they might make the title be:
Implementing Rust's dbg! macro in Python
And if they are opposed to use the bang even in this context it would then be fine IMO to either preferably set the title to:
There's a few significant differences here. This is a printf that only happens in debug mode; dbg is something that takes an expression, returns that expression, and will print out its filename, line number, and a pretty-printed version of the value.
For an example of how this plays out, I had some code:
let x = y + z;
I wasn't sure what y was, so I was able to
let x = dbg!(y) + z;
this is much easier to insert into (and remove from) existing code. Plus, you don't need to write the formatting code.
Basically, what you posted is in the same genre of thing, but is very different in a lot of meaningful ways.
It isn't really that different, it can just be used in inline expressions. Having the macro do nothing or just evaluating to the expression in debug mode is trivial, since a debug symbol would be defined.
So anyone using Ubuntu or Debian, maybe for the next major release you can try it out. I love Debian but I hate that I cant just install the latest of Python system wide without potentially breaking system level scripts.
Might be worth mentioning that you do not have to resort to printf debugging in Rust or python; both languages have good ide debugger support. I use python and rust together professionally.
For something quick, it's often more ergonomic to just print a thing out than step through. Also, most debuggers also won't be very helpful for embedded expressions; you have to break it out into a local variable.
For what it's worth, I made a Python package that lets you combine both approaches: https://github.com/breuleux/breakword. You run your program once to print out what's going on, but it also displays a unique word next to each line and on a second run you can set a breakpoint at any of these words to investigate deeper. It's pretty handy when you spot an issue at the hundredth invocation of some function deep in the program's execution.
The one thing I wasn't sure that I liked with rust's dbg! is that I was typically passing the argument by value, but that sometimes works and sometimes fails the borrow checker. But now reading https://github.com/rust-lang/rust/issues/59943 I see that this is a feature -- I hadn't been taking advantage of the fact that you can use dbg! inline; I'd just been adding extra dbg!(foo) lines to the code. So I should probably (a) pass by reference always and (b) look our for where inline dbg! might be useful (probably lots).
My personal experience is that doing println/dbg based debugging in python is most times a bad idea and does wast time.
Ironically my experience with rust is the opposite, i.e. not using println/dbg debugging is most times does wast time. (Except if you do certain thinks with unsafe code).
The difference is I guess that in rust I normally encode much more simple invariant in the type system and as such most times a bug happens I often can pin-down it's rough position by the way it appears (i.e. panics/errors not subtle timing bugs). In turn I just need to get a nice formatted printout of this one or two values. Instead of having to consider all the other ways things might have cone wrong in python which can't happen in rust (through python3's type annotation + linting can help).
53 comments
[ 10.1 ms ] story [ 1652 ms ] thread[1] https://github.com/gruns/icecream
I think submitters are able to correct the title for a while and that when they do it might(?) override some or all of the rules in the filter. But the time window for doing so has probably been passed now.
Mods could still change the title though.
Either to the original:
Implementing Rust's dbg! in Python
Or if they want to help out those unfamiliar with Rust syntax they might make the title be:
Implementing Rust's dbg! macro in Python
And if they are opposed to use the bang even in this context it would then be fine IMO to either preferably set the title to:
Implementing Rust's dbg macro in Python
Or less preferably to set the title to:
Implementing Rust's debug macro in Python
Apparently it's inspired by Haskell.[0] I'd love to see it officially picked up in other languages.
[0] https://rust-lang.github.io/rfcs/2361-dbg-macro.html#prior-a...
For an example of how this plays out, I had some code:
I wasn't sure what y was, so I was able to this is much easier to insert into (and remove from) existing code. Plus, you don't need to write the formatting code.Basically, what you posted is in the same genre of thing, but is very different in a lot of meaningful ways.
If I could I would probably want to write
but that of course doesn't work.In [8]: print(f'{foo.bar[1]=}') foo.bar[1]='2'
You can do more complex expressions:
In [9]: f'{1+1=}' Out[9]: '1+1=2'
It's not quite as fluid as dbg!(), but it's nice.
And then, sometimes, you need to debug the debugger...
not to mention you can run via pdb and display or stop at points of interest.
what am I missing?
%(filename_lineno)s will give you the filename and line.
Should be: print(eval("foo['bar']"))
Ironically my experience with rust is the opposite, i.e. not using println/dbg debugging is most times does wast time. (Except if you do certain thinks with unsafe code).
The difference is I guess that in rust I normally encode much more simple invariant in the type system and as such most times a bug happens I often can pin-down it's rough position by the way it appears (i.e. panics/errors not subtle timing bugs). In turn I just need to get a nice formatted printout of this one or two values. Instead of having to consider all the other ways things might have cone wrong in python which can't happen in rust (through python3's type annotation + linting can help).