On Fri, Apr 27, 2018 at 9:27 PM, Steven D'Aprano firstname.lastname@example.org wrote:
Obviously dp() would have to be magic. There's no way that I know of for a Python function to see the source code of its own arguments. I have no idea what sort of deep voodoo would be required to make this work. But if it could work, wow, that would really be useful. And not just for beginners.
It's a debugging function. It's okay if the magic has some restrictions on it. How about:
1) The dp() function is CPython-specific. Other Pythons may or may not include it, and may or may not have this magic.
2) For the magic to work, the calling module must have source code available. Otherwise, dp() will do as much as it can, but it might not be able to do everything.
3) The magic may not work if you use any name other than "dp" to call the function.
Then, the function can be written much more plausibly. It can use sys._getframe to find the calling function, fetch up the source code from disk, and look at the corresponding line of code. The hardest part will be figuring out code like this:
x = dp(spam) if qq else dp(ham)
In theory, frm.f_lasti (the last bytecode instruction executed) should be able to help with this, but I'm not sure how well you could parse through that to figure out which of multiple dp() calls we're in.
At this point, it's DEFINITELY too large for an instructor to dictate to a beginner as part of a lesson on debugging, but it could be a great addition to the 'inspect' module. You could teach students to add "from inspect import dp" to their imports, and the rest would 'just work'.
I don't think this needs any specific compiler magic or making 'dp' a reserved name, but it might well be a lot easier to write if there were some compiler features provided to _all_ functions. For instance, column positions are currently available in SyntaxErrors, but not other exceptions:
x = 1 print("spam" + x)
Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: can only concatenate str (not "int") to str
print("spam" : x)
File "<stdin>", line 1 print("spam" : x) ^ SyntaxError: invalid syntax
Imagine if the TypeError could show a caret, pointing to the plus sign. That would require that a function store column positions, not just line numbers. I'm not sure how much overhead it would add, nor how much benefit you'd really get from those markers, but it would then be the same mechanic for exception tracebacks and for semi-magical functions like this.