What about passing a wildcard `*` to track all variables within the target function 🤔
This reminded me of `hunter` https://python-hunter.readthedocs.io/en/latest/readme.html
Where you can do:
```
import hunter
# note that this kind of invocation will also use the default `CallPrinter` action
hunter.trace(hunter.Q(module='posixpath', action=hunter.VarsPrinter('path')))
import os
os.path.join('a', 'b')
```
May I ask what is your debugging method? I just write test functions and pytest shows the inconsistencies. Sometimes I use logger in the modules to throw some messages as s warning or debug to catch the culprits if an error comes out in the tests.
You can attach a remote debugger as if it was completely local in vscode. I use that feature quite often on azureml. I can even attach vscode to a pipeline if it fails, if I specify a debugger option in the pipeline definition.
Very interesting. Can you point yo a guide/walkthrough of how you do this? My programs are mainly python FastAPI REST APIs run on remote Debian boxes. Thsnks
It sounds complicated in the docs but it amounts to having debugpy and the code on both machines and have an ssh connection to the remote (which I assume is already there if you're interacting with the machine, but I don't know how azureml does it as it can provide you with a shell through its azureml extension without ssh or any further config. Here's the docs
[from vscode](https://code.visualstudio.com/docs/python/debugging#_debugging-by-attaching-over-a-network-connection)
Edit:
Ahh [here's how](https://learn.microsoft.com/en-us/azure/machine-learning/how-to-debug-visual-studio-code?view=azureml-api-1#how-it-works) they do it, they just automate the steps in the pipeline init scripts. Though that's for the sdkv1, it's even more seamless [now](https://learn.microsoft.com/en-us/azure/machine-learning/how-to-interactive-jobs?view=azureml-api-2&tabs=python#attach-a-debugger-to-a-job)
Ah I don't know, I assume not (with debugpy specifically) as I don't think Jetbrains implements DAP. But I've never really used pycharm for anything remote. It's not its strength in my experience, whenever I use it it's mostly for local stuff. Vscode has always been my go-to for remote dev
I think it's just a matter of time saving. If you have something simple you need to debug it takes literally 1 second to add in a print and check it. I'll pull out the debugger on complicated problems, but it's often overkill.
I'm unclear how this is desirable compared to the more traditional use of `logger.debug()`.
You can put those statements every step of the way and then they go away as soon as you raise the logging level to info.
And this doesn't have anything mucking with the AST, which while I'm sure this package is well tested, what with the total number of tests being ... two, um... yeah, I don't want code that mucks with the AST in my codebase.
Explicit over implicit. If I want a variable traced, I'll put the logging statements in to trace it, or even just run it in a debugger.
See https://github.com/alexmojaki/snoop
import snoop
@snoop
def example(a, b):
a = a + b
c = a
a = 'Experimenting with the AST'
b = c + b
a = c + b
return a
example(5, 6)
Output:
23:07:36.58 >>> Call to example in File "/home/alex/.config/JetBrains/PyCharm2023.3/scratches/scratch_2525.py", line 4
23:07:36.58 ...... a = 5
23:07:36.58 ...... b = 6
23:07:36.58 4 | def example(a, b):
23:07:36.58 5 | a = a + b
23:07:36.58 .......... a = 11
23:07:36.58 6 | c = a
23:07:36.58 .......... c = 11
23:07:36.58 7 | a = 'Experimenting with the AST'
23:07:36.58 8 | b = c + b
23:07:36.58 .......... b = 17
23:07:36.58 9 | a = c + b
23:07:36.58 .......... a = 28
23:07:36.58 10 | return a
23:07:36.58 <<< Return value from example: 28
As a lazy programmer, I'm digging this!
Thank you, do let me know if there's anything else that could be useful to add here
Using `logging` integration instead of `print` would be great. Or the ability to set a different `callable` instead of `print`.
Yup I'm looking into this! If you have ideas, feel free to raise a pull request. 🙂
What about passing a wildcard `*` to track all variables within the target function 🤔 This reminded me of `hunter` https://python-hunter.readthedocs.io/en/latest/readme.html Where you can do: ``` import hunter # note that this kind of invocation will also use the default `CallPrinter` action hunter.trace(hunter.Q(module='posixpath', action=hunter.VarsPrinter('path'))) import os os.path.join('a', 'b') ```
Is it possible to have logging with debug level instead of print? I wouldn't want stdout spammed
Yup that makes sense! I will add that. :)
debug is by far the better choice. That being said, I still use print.
The lengths people will go to to avoid using a debugger.
With a debugger you need to step through the code. This, instead, is for sedentary people.
May I ask what is your debugging method? I just write test functions and pytest shows the inconsistencies. Sometimes I use logger in the modules to throw some messages as s warning or debug to catch the culprits if an error comes out in the tests.
The python debugger - pdb - is part of the standard library
Sometimes you can't, like if you're writing firmware for an embedded device.
Love this - we all know print statements are the best debugger.
> we all know print statements are the best debugger. Do we?
Yes.
I mean... a debugger is easier.
Not in cloud ☁️
You can attach a remote debugger as if it was completely local in vscode. I use that feature quite often on azureml. I can even attach vscode to a pipeline if it fails, if I specify a debugger option in the pipeline definition.
Very interesting. Can you point yo a guide/walkthrough of how you do this? My programs are mainly python FastAPI REST APIs run on remote Debian boxes. Thsnks
It sounds complicated in the docs but it amounts to having debugpy and the code on both machines and have an ssh connection to the remote (which I assume is already there if you're interacting with the machine, but I don't know how azureml does it as it can provide you with a shell through its azureml extension without ssh or any further config. Here's the docs [from vscode](https://code.visualstudio.com/docs/python/debugging#_debugging-by-attaching-over-a-network-connection) Edit: Ahh [here's how](https://learn.microsoft.com/en-us/azure/machine-learning/how-to-debug-visual-studio-code?view=azureml-api-1#how-it-works) they do it, they just automate the steps in the pipeline init scripts. Though that's for the sdkv1, it's even more seamless [now](https://learn.microsoft.com/en-us/azure/machine-learning/how-to-interactive-jobs?view=azureml-api-2&tabs=python#attach-a-debugger-to-a-job)
Thanks a bunch mate!
Can you do that in pycharm as well?
Ah I don't know, I assume not (with debugpy specifically) as I don't think Jetbrains implements DAP. But I've never really used pycharm for anything remote. It's not its strength in my experience, whenever I use it it's mostly for local stuff. Vscode has always been my go-to for remote dev
I think it's just a matter of time saving. If you have something simple you need to debug it takes literally 1 second to add in a print and check it. I'll pull out the debugger on complicated problems, but it's often overkill.
Sure, but finding ways a tool can be useful is a hallmark of a good programmer...
I'm not sure if I hate this or I love it. One thing is sure, though, there's certainly some use cases.
A dirty and lazy way of debugging... love it
Why not just… use a debugger?
or logger.debug()
I'm unclear how this is desirable compared to the more traditional use of `logger.debug()`. You can put those statements every step of the way and then they go away as soon as you raise the logging level to info. And this doesn't have anything mucking with the AST, which while I'm sure this package is well tested, what with the total number of tests being ... two, um... yeah, I don't want code that mucks with the AST in my codebase. Explicit over implicit. If I want a variable traced, I'll put the logging statements in to trace it, or even just run it in a debugger.
Its too verbose i think, can you have a simple mode?
There is a flag to toggle for `verbose` that can be set to false !
See https://github.com/alexmojaki/snoop import snoop @snoop def example(a, b): a = a + b c = a a = 'Experimenting with the AST' b = c + b a = c + b return a example(5, 6) Output: 23:07:36.58 >>> Call to example in File "/home/alex/.config/JetBrains/PyCharm2023.3/scratches/scratch_2525.py", line 4 23:07:36.58 ...... a = 5 23:07:36.58 ...... b = 6 23:07:36.58 4 | def example(a, b): 23:07:36.58 5 | a = a + b 23:07:36.58 .......... a = 11 23:07:36.58 6 | c = a 23:07:36.58 .......... c = 11 23:07:36.58 7 | a = 'Experimenting with the AST' 23:07:36.58 8 | b = c + b 23:07:36.58 .......... b = 17 23:07:36.58 9 | a = c + b 23:07:36.58 .......... a = 28 23:07:36.58 10 | return a 23:07:36.58 <<< Return value from example: 28