As you can see, using “locals()” function seems to duplicate both variables (argument_A & argumentB), which is infortunate since after that, I don’t know which version of the same variable is being modified and/or used. Is there a way to avoid this duplication?
Looks like this is a leaky abstraction in IronPython being revealed by the debugger. I don’t see the same behavior in CPython, but I do see it in plain IronPython outside Rhino. (I’m running your script in the REPL, breaking in pdb at the same place as you, and asking pdb to print(locals()).) I don’t think there is much that can be done in Rhino if this is how pdb works in IronPython. Maybe @Alain knows more about this?
The good news is that you only see these new ClosureCell type variables when in the debugger, and in both a normal run and in the debugger everything works as if they were not there. In the function scope, and when the function returns, argument_A/B have their values modified as written (try a print(argument_A) or print(locals()) before your breakpoint). Even when running in the debugger, the function scope cannot access argument_A1.
It’s only in the variables preview of the debugger that these ClosureCell type variables temporarily “replace” the initial arguments.
Why do you need to work with locals() in the debugger?
The of locals() is not specific to debug mode; I would like it to work principally in non-debug. Ive made a simplified example here, where locals() has no use.
I use it to dodge another issue, as shown here: "Who called me" Issue
You said that the function scope cannot access argument_A1. That is true if I try to reach it directly using the debugger. However, line 4 of my example did modify argument_A1 (ClosureCell), and did not modify argument_A (int).
That is infortunate because I need the modified version of argument_A. And in use, i’ve seen both modified and unmodified version of argument_A, at line 7. Do you have an idea how I could solve it? I think making a copy of all input arguments (and use those copies thereafter in the function) may solve the case but it is ugly (and much harder to read) as hell!
Here, if I run the test code I provided, I get “Argument value: (1, ‘False’)”, as expected. The bug is hard to reproduce in a simplified case: If I succeed to do so, I’m posting it here.
Of course, solving the initial issue (‘Who calls me issue’) would be even better; making the use of locals() irrelevant.
That seems perfectly normal to me and there’s no need to know about the ClosureCell variables implementation details. argument_A value shows its current value at all times.
It is true that when stopping in the debugger and looking at the printout of the variables, you will get new temporary variables that seem to hold the current values of the function arguments, while the original variables do not reflect the changes made to them. Am I correct in understanding that this is only a display issue and that no code relies on accessing these hidden ClosureCell variables?
Removing locals() gets me back to the normal stuff. This gets me back to my original question :), is it possible to remove it in your code?
If not, I would really look into the function decorator I mentioned in the other thread. It won’t print the “current” value of the arguments as they are inside the function body, but I think you could modify it to print these before and after the function runs.
If you really need debug prints of the variables inside the function, I think logging.debug(locals()) is what you need, and the CallerInfo function (or the decorator) can have the role of just printing the variables as they are when entering the function call. Would that work?