Icecream: Never use print() to debug again in Python
141–150 of 271 posts
Re: Icecream: Never use print() to debug again in Python
#142This looks cool and all, but why is it called Icecream? I know naming abstract stuff is hard but it feels like this lends itself to a more descriptive name. "ic()" tells me nothing about what the function does.
I think it's a (confusing) two-layer pun. When read phonetically as letter names, the name "ic" sounds like "I see". "ic" also is an initialism for "ice cream". Everyone loves ice cream, and so another low-meaning cutesy-poo pun-ishment of a name was born. I think. Pure speculation here.
Re: Icecream: Never use print() to debug again in Python
#143(Not suggesting it as a replacement for this tool - but if you’re a pyhacker and don’t know about this it’s handy)
Re: Icecream: Never use print() to debug again in Python
#144Imagine using a language in this day and age where you have to litter your code with debugging statements.
Re: Icecream: Never use print() to debug again in Python
#145Earlier quoted context omitted.
Absolutely, I don't understand why using print() or its equivalent in other languages is looked down upon. It's quick way to narrow down the "area of search" before bringing in the big guns.
How is changing code simpler than literally clicking on the line number to set a breakpoint?
Re: Icecream: Never use print() to debug again in Python
#146Earlier quoted context omitted.
In the docs you can look up breakpoint, it has a lot of features amongst other things you can register a custom handler. I use it in selenium tests so I can either debug on error or just print the error message and continue
Could you provide a concrete example? It's still unclear to me why one wants a custom breakpoint() handler.
__init__.py
os.environ.setdefault('PYTHONBREAKPOINT', 'tests.utils.raise_or_debug')
tests.utils.raise_or_debug def raise_or_debug(msg=''):
if settings.BREAKPOINT_ON_ERROR:
extype, value, tb = sys.exc_info()
if getattr(sys, 'last_traceback', None):
pdb.pm()
elif tb:
pdb.post_mortem(tb)
else:
pdb.set_trace()
elif msg:
raise AssertionError(msg)
else:
pdb.set_trace()
The reason is so we can leave breakpoints in the tests, and then depending on context run the tests in a context where debug is possible, or simply raise the failure again.Selenium can be very flaky, so this has really sped up iteration and improvements. Standard functions with retries, and smart assertions and timeouts can then be fixed and resumed in dev - and give a good message on fail (for example headless chrome runner on CI).
Re: Icecream: Never use print() to debug again in Python
#147Earlier quoted context omitted.
This is actually really cool. I was going to say that so many people miss the point of print debugging and as a consequence forget to shorten the import line as much as possible. from icecream import ic;ic() is 28 characters import q;q() is 12 characters print() is 7 characters
Why would the amount of characters possibly matter?
This is also important to me because I am very cautious of not doing a file-level import (I don't want to commit a file with the dependency). The fewer characters it takes, the easier it is for me to write it all in a single line and remove it afterward.
Re: Icecream: Never use print() to debug again in Python
#148I am always going to use print to debug in every programming language I can until the day I die.
I had an emacs macro that would help. Simplified it was:
(defun add-printf ()
(interactive)
(let ((s (word-near-point)))
(when s
(beginning-of-line)
(insert "printf(\"@@@ %s:%d "
s
": 0x%x\\n\", __FUNCTION__, __LINE__,"
s
");\n")
(forward-line -1)
(indent-for-tab-command)
(end-of-line)
(search-backward " \\n" nil t))))
(global-set-key [f8] 'add-printf)
I had lots of variants (crafted while recompiling) with prompts, or marked regions or lots more throwaway printf sillinessRe: Icecream: Never use print() to debug again in Python
#149Earlier quoted context omitted.
WHAT... Why ain't anybody talking about this? Brilliant!
In this case, it would seem it took a little reinvention in order to let the wheel's discovery be known.
Re: Icecream: Never use print() to debug again in Python
#150Earlier quoted context omitted.
Could you provide a concrete example? It's still unclear to me why one wants a custom breakpoint() handler.
This is how we use it in my testing repo: __init__.py os.environ.setdefault('PYTHONBREAKPOINT', 'tests.utils.raise_or_debug') tests.utils.raise_or_debug def raise_or_debug(msg=''): if settings.BREAKPOINT_ON_ERROR: extype, value, tb = sys.exc_info() if getattr(sys, 'last_traceback', None): pdb.pm() elif tb: pdb.post_mortem(tb) else: pdb.set_trace() elif msg: raise AssertionError(msg) else: pdb.set_trace() The reason i…
We have manually overwritten the breakpoint handler to a custom handler that in default mode does this:
- `breakpoint()` calls trigger `pdb.set_trace()` as per usual
- `breakpoint()` calls trigger AssertionError to fail tests
When `BREAKPOINT_ON_ERROR=TRUE` is turned on:
- `breakpoint()` calls trigger `pdb.set_trace()` as per usual
- `breakpoint()` call `pdb.set_trace()` so you can try to manually work out how the code is functioning
- if you call `breakpoint()` from an `except` block it will open the debugger at the position of the exception
Usage example: try:
WebDriverWait(self.driver, 10).until(
EC.element_to_be_clickable((By.ID, 'desktop-apply')))
except TimeoutException:
breakpoint('Was not able to click apply button.')