classification
Title: IDLE - debugger steps into print and over rpc.py code
Type: behavior Stage: test needed
Components: IDLE Versions: Python 3.6
process
Status: open Resolution:
Dependencies: Superseder:
Assigned To: terry.reedy Nosy List: Al.Sweigart, loewis, roger.serwy, terry.reedy
Priority: normal Keywords:

Created on 2012-07-12 16:42 by roger.serwy, last changed 2017-10-25 19:28 by terry.reedy.

Messages (8)
msg165321 - (view) Author: Roger Serwy (roger.serwy) * (Python committer) Date: 2012-07-12 16:42
The IDLE debugger steps through the internals of _RPCFile.

To reproduce this bug, create a new .py file with a few print statements, enable the debugger, and then run the file. Stepping through the print statement enters into _RPCFile.
msg165324 - (view) Author: Roger Serwy (roger.serwy) * (Python committer) Date: 2012-07-12 17:18
Debugger.py has a method "in_rpc_code" which ultimately prevents stepping though code from rpc.py. (Presently an external file named "rpc.py" can not be debugged using IDLE.)

Adding "run.py" to the check would prevent run.py from being stepped, but it applies to *any* "run.py" in the filename string:

        elif frame.f_code.co_filename.count('run.py'):
            return True

Or, you could check the name:

        elif frame.f_globals.get('__name__','') == 'idlelib.run':
            return True

Any additional logic for "in_rpc_code" can slow down code performance when debugging.

Another possible approach is to move the _RPCFile into rpc.py add additional methods to RPCHandler, like "get_remote_stdout_proxy".
msg165325 - (view) Author: Martin v. Löwis (loewis) * (Python committer) Date: 2012-07-12 17:31
I suggest to add a decorator @Debugger.internal for all methods that the debugger should not step into. It should set a function attribute that the debugger then checks for.

OTOH, I fail to see the problem. Stepping through the standard library may be useful, and if you don't want to do that, you can choose to step over still.
msg165408 - (view) Author: Roger Serwy (roger.serwy) * (Python committer) Date: 2012-07-13 19:19
> I suggest to add a decorator @Debugger.internal for all methods that the debugger should not step into. It should set a function attribute that the debugger then checks for.


The decorator idea may work. I'll need to see how to make it work with the existing debugging code.


> OTOH, I fail to see the problem. Stepping through the standard library may be useful, and if you don't want to do that, you can choose to step over still.


I'm not sure why stepping through an IDE's internals is desirable when debugging one's own program. As it stands, the _RPCFile patch represents an unintended behavior change to the debugger. That needs to be either corrected or documented.
msg225248 - (view) Author: Terry J. Reedy (terry.reedy) * (Python committer) Date: 2014-08-13 00:11
Since there is currently no '_RPCFile' in idlelib, I presume it was the predecessor of PyShell.PseudoFile.  Was it in run.py rather than PyShell.py?  Stepping through print (only 1 is needed) steps through the two 'if's and 'return' statements of PyShell.PseudoOutputFile.write.

I agree with Martin that this is not a bug. [step] is supposed to step into python-coded functions and skip over non-python functions and that is what it is doing. Whether *any* stdlib function is coded in python, or something else, or something else and wrapped in python, and therefore whether it will be stepped into or over, is a matter of implementation, version, and local setup. In particular, 'print' was changed from statement keyword to builtin name partly so it could be wrapped or replaced.

However, I agree that stepping through .write is not especially desirable and would not mind if the class were moved from PyShell.py to rpc.py.  I think it fits there better anyway.  

I wrote a 'rpc.py', not in idlelib, and tried to debug it. Debugger silently ran the whole module and quit, as if I had hit [run] with no breakpoints. This, I think, *is* a bug; in_rpc_code() should only skip over idlelib.rpc code.
msg225249 - (view) Author: Terry J. Reedy (terry.reedy) * (Python committer) Date: 2014-08-13 00:25
FWIW: stepping into an import statement now steps into <frozen importlib._bootstrap> and for many more statements than the three for print/write. I am already aware that the debugger 'doc' needs to be expanded from
"Debugger (toggle) 
This feature is not complete and considered experimental. Run commands in the shell under the debugger "
msg271302 - (view) Author: Terry J. Reedy (terry.reedy) * (Python committer) Date: 2016-07-25 19:40
In #27615, which I will close as a duplicate of this, Al Sweigart wrote

"Currently if the user "steps into" a print(), input(), sys.stdout.write() or other stdio-related call with the Source checkbox checked, it brings up PyShell.py.

This is often confusing for beginner programmers (the target audience of IDLE) and most often not helpful for experienced developers who are stepping through their program. Comparing the cost/benefit, I'd be much more helpful for IDLE to not bring up PyShell.py and instead just treat every "step into" of a print()/input()/anything-that-goes-to-pyshell as a "step over" instead."

I have changed my opinion from what I wrote a couple of years ago and now agree.  Print and input are different from stdlib functions, such as, "import asyncio; loop = asyncio.get_event_loop", in that they are used by nearly all beginners, are not imported, and are normally C-coded builtins that cannot be stepped into.  If one debugs an import- free program, it is startling to be dropped into foreign code.

IDLE should execute and debug user code as transparently as possible.  I now think that the debugger should not step into any idlelib file unless this is explicitly requested in a separate check box ('for IDLE maintainers'.  I suspect a blanket no-idlelib or yes-idlelib policy will be faster than the current code, and would avoid the current bug of not stepping into user code.

I recently moved the Pseudofile definitions from pyshell to run so that run does not need to import pyshell.  I did not consider whether or how this would affect debugging and should not have to. I plan other refactorings and movements between files.

Whether to worry about stepping in <frozen importlib._bootstrap> is a different issue, and one not specific to IDLE.
msg305007 - (view) Author: Terry J. Reedy (terry.reedy) * (Python committer) Date: 2017-10-25 19:28
The debugger also steps into importlib, if one steps 'into' an import statement.  Most of the time, this is a nuisance.  If one is importing from one's own module, stepping over 'import mymod' is not a satisfactory way to avoid this.  Perhaps we should add '(X) Step past IDLE internals' and '(X) Step past Python internals', both on by default.  'python internals' would be builtin features that happen be implemented, at least in CPython, in python rather than the internal language. Other ideas: a drop down skip list with items checked.  Or a general policy of skipping Lib/* with a list of exceptions.
History
Date User Action Args
2017-10-25 19:28:41terry.reedysetmessages: + msg305007
2016-07-25 19:43:10terry.reedylinkissue27615 superseder
2016-07-25 19:40:57terry.reedysetversions: + Python 3.6, - Python 2.7, Python 3.4, Python 3.5
nosy: + Al.Sweigart

messages: + msg271302

assignee: terry.reedy
2014-08-13 00:25:19terry.reedysetmessages: + msg225249
2014-08-13 00:11:36terry.reedysettitle: IDLE - debugger steps through run.py internals -> IDLE - debugger steps into print and over rpc.py code
messages: + msg225248
stage: test needed
2014-07-27 22:46:03terry.reedysetversions: + Python 3.5, - Python 3.3
2013-06-15 19:05:38terry.reedysetversions: + Python 2.7, Python 3.3
2013-01-07 16:16:56serhiy.storchakasetnosy: - serhiy.storchaka

versions: + Python 3.4, - Python 3.3
2012-07-13 19:19:56roger.serwysetmessages: + msg165408
2012-07-12 17:31:31loewissetmessages: + msg165325
2012-07-12 17:18:22roger.serwysetmessages: + msg165324
2012-07-12 16:42:53roger.serwycreate