8 ms·
Implementing Rust's dbg! in Python
- deleted 6y ago[deleted]
- azkae 6y agoI use icecream [1] for the same purpose while debugging. It's really handy. [1] https://github.com/gruns/icecream https://github.com/gruns/icecream
- memco 6y agoThanks 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.
- mmastrac 6y agoTitle should definitely have `dbg!` in it rather than "Dbg"
- codetrotter 6y agoProbably 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: Implementing Rust's dbg macro in Python Or less preferably to set the title to: Implementing Rust's debug macro in Python
- penagwin 6y ago@dang we are in great need
- dang 6y agoFixed now.
- JackC 6y agoRust's dbg! is one of those ideas that felt obvious and beautiful once I saw it. 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-art https://rust-lang.github.io/rfcs/2361-dbg-macro.html#prior-a...
- lock-free 6y agoI've been using it in C/C++ projects going back at least 15 years, I thought it was commonplace for every language
- dagmx 6y agoDo you have an example of using it in C or C++?
- lock-free 6y agohttps://stackoverflow.com/questions/1644868/define-macro-for-debug-printing-in-c https://stackoverflow.com/questions/1644868/define-macro-for...
- steveklabnik 6y agoThere'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.
- digikata 6y agoYou can use dbg inline within an expression!? How did I miss that?
- deleted 6y ago[deleted]
- okl 6y agoHere's a lib with similar functionality: https://github.com/alexmojaki/snoop https://github.com/alexmojaki/snoop
- orf 6y agoPython now as a semi-shortcut for this (just add = to the end of any f-string expression): 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.
- gknoy 6y agoFor anyone else wondering why we get a syntax error, this seems to be new in 3.8. :)
- giancarlostoro 6y agoSo 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.
- Drdrdrq 6y agoJust use pyenv (careful with spelling), then you can use any version you like.
- giancarlostoro 6y agoDefinitely will have to check it out with two endorsements, I've heard of a few other options, but this might be something I'm actually okay with.
- 0x008 6y agoWhat alternatives are there for pyenv besides conda?
- Nullabillity 6y agoNix?
- drewm1980 6y agoMight 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.
- brundolf 6y agoFor 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.
- 0x008 6y agoYou can set a breakpoint and also watch expressions, so there is not more work involved than hitting 2 keyboard shortcuts usually.
- deleted 6y ago[deleted]
- damnyou 6y agoprintf debugging (i.e. listing code execution traces) is better than a breakpoint-based debugger in most situations, in my opinion.
- breuleux 6y agoFor what it's worth, I made a Python package that lets you combine both approaches: https://github.com/breuleux/breakword 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.
- a_t48 6y ago
- da39a3ee 6y agoThe 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 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).
- The_rationalist 6y agoI created a similar macro in C++, it had the ability to show the function name in addition to the file name
- db48x 6y agoBut did it return the value being printed? That's the thing most implementations miss.
- The_rationalist 6y agoOh never thought about that use case but I imagine it would have been simple to add
- tpoacher 6y agoI dont get, isn't this just grabbing the filename (which has a built-in double underscore file variable), and the line number (e.g. https://code.activestate.com/recipes/145297-grabbing-the-current-line-number-easily/ https://code.activestate.com/recipes/145297-grabbing-the-cur...) not to mention you can run via pdb and display or stop at points of interest. what am I missing?
- CJefferson 6y agodbg! also prints out both the value of the expression, and the expression itself, so dbg!(x+y) prints 'x+y=3'
- jlmorton 6y agoWhile I realize we don't always have a logger wired up, it's also easy to implement this in standard logging. %(filename_lineno)s will give you the filename and line.
- kortex 6y agoLoguru is a great package for "I just want a nicely formatted logger out of the box"
- aftbit 6y agoTypo in your first eval example: >>> foo = { ... 'bar': 3 ... } >>> print(eval("foo['bar'[]")) Traceback (most recent call last): File "<stdin>", line 1, in <module> File "<string>", line 1 foo['bar'[] ^ SyntaxError: unexpected EOF while parsing
- __lazybyte 6y agoI think that's the extra opening square bracket. Should be: print(eval("foo['bar']"))
- dathinab 6y agoMy 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).
- jfrunyon 6y agoYou don't need IPython for startup scripts... https://docs.python.org/3/library/site.html https://docs.python.org/3/library/site.html
- auscompgeek 6y agoAnother somewhat similar Python library, but logs to a /tmp file: https://github.com/zestyping/q https://github.com/zestyping/q