On Wed, Oct 3, 2018, 03:55 Eric V. Smith email@example.com wrote:
On 10/3/2018 1:40 AM, Nathaniel Smith wrote:
I think the way I'd do it would be:
Step 1: Take the current "lnotab" that lets us map bytecode offsets -> line numbers, and extend it with more detailed information, so that we can map e.g. a CALL operation to the exact start and end positions of that call expression in the source. This is free at runtime, and would allow more detailed tracebacks (see  for an example), and more detailed coverage information. It would definitely take some work to thread the necessary information through the compiler infrastructure, but I think this would be a worthwhile feature even without the debug() use case.
Step 2: Add a 'debug' helper function that exploits the detailed information to reconstruct its call, by peeking into the calling frame and finding the source for the call. Of course this would be a strange and ugly thing to do for a regular function, but for a debugging helper it's reasonable. So e.g. if you had the code:
total = debug(x) + debug(y / 10)
The output might be:
debug:myfile.py:10: 'x' is 3 debug:myfile.py:10: 'y / 10' is 7
I'm not positive, but isn't this what q does?
The difference is that without "step 1", there's no reliable way to figure out the value's source text. q does it by grabbing the source line and making some guesses based on heuristics, but e.g. in the example here it gets confused and prints:
0.0s <module>: x) + q(y / 10=3 0.0s <module>: x) + q(y / 10=7
So you can think of this idea as (1) make it possible to implement a reliable version of q, (2) add an built-in implementation.