[HN Gopher] Implementing Rust's dbg! in Python ___________________________________________________________________ Implementing Rust's dbg! in Python Author : soopurman Score : 89 points Date : 2020-12-11 14:47 UTC (8 hours ago) (HTM) web link (rtpg.co) (TXT) w3m dump (rtpg.co) | mmastrac wrote: | Title should definitely have `dbg!` in it rather than "Dbg" | dang wrote: | Fixed now. | codetrotter wrote: | 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: | | Implementing Rust's dbg macro in Python | | Or less preferably to set the title to: | | Implementing Rust's debug macro in Python | penagwin wrote: | @dang we are in great need | orf wrote: | Python 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 wrote: | For anyone else wondering why we get a syntax error, this seems | to be new in 3.8. :) | giancarlostoro wrote: | 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. | Drdrdrq wrote: | Just use pyenv (careful with spelling), then you can use | any version you like. | tpoacher wrote: | I 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- | cur...) | | not to mention you can run via pdb and display or stop at points | of interest. | | what am I missing? | CJefferson wrote: | dbg! also prints out both the value of the expression, and the | expression itself, so dbg!(x+y) prints 'x+y=3' | okl wrote: | Here's a lib with similar functionality: | https://github.com/alexmojaki/snoop | jlmorton wrote: | While 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. | [deleted] | JackC wrote: | Rust'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-a... | lock-free wrote: | I've been using it in C/C++ projects going back at least 15 | years, I thought it was commonplace for every language | dagmx wrote: | Do you have an example of using it in C or C++? | lock-free wrote: | https://stackoverflow.com/questions/1644868/define-macro- | for... | dagmx wrote: | Like Steve said, what you're talking about is quite a bit | different than what the rust dbg macro does. | CyberDildonics wrote: | 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. | steveklabnik wrote: | 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. | digikata wrote: | You can use dbg inline within an expression!? How did I | miss that? | steveklabnik wrote: | You can even use it inside itself. I've written | let c = dbg!(dbg!(a) + dbg!(b)); | | one time... | jrimbault wrote: | I've written a 3 nested dbg! line for a complex boolean | expression... I should have just written a truth table... | brodie wrote: | Maybe you should write a truth table/source code macro! | CJefferson wrote: | After I saw this in Rust, I had to implement it in C++: | #include <iostream> #include <string> | template<typename T> T print_dbg(T val, | std::string exp, std::string file, int line) { | std::cerr << exp << " = " << val << " @ " << file << ":" | << line << "\n"; return val; } | #define dbg(x) print_dbg(x,#x,__FILE__,__LINE__) | aftbit wrote: | Typo 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 wrote: | I think that's the extra opening square bracket. | | Should be: print(eval("foo['bar']")) | azkae wrote: | I use icecream [1] for the same purpose while debugging. It's | really handy. | | [1] https://github.com/gruns/icecream | memco wrote: | 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. | da39a3ee wrote: | 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). | drewm1980 wrote: | 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. | brundolf wrote: | 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. | damnyou wrote: | printf debugging (i.e. listing code execution traces) is better | than a breakpoint-based debugger in most situations, in my | opinion. | breuleux wrote: | 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. | colejohnson66 wrote: | Would this make sense in a logging situation? | [deleted] | The_rationalist wrote: | I created a similar macro in C++, it had the ability to show the | function name in addition to the file name | db48x wrote: | But did it return the value being printed? That's the thing | most implementations miss. | The_rationalist wrote: | Oh never thought about that use case but I imagine it would | have been simple to add ___________________________________________________________________ (page generated 2020-12-11 23:01 UTC)