[Python-Dev] PEP 553

Terry Reedy tjreedy at udel.edu
Mon Oct 2 02:15:45 EDT 2017

On 10/2/2017 12:44 AM, Guido van Rossum wrote:

> - There's no rationale for the *args, **kwds part of the breakpoint() 
> signature. (I vaguely recall someone on the mailing list asking for it 
> but it seemed far-fetched at best.)

If IDLE's event-driven GUI debugger were rewritten to run in the user 
process, people wanting to debug a tkinter program should be able to 
pass in their root, with its mainloop, rather than having the debugger 
create its own, as it normally would.  Something else could come up.

> - The explanation of the relationship between sys.breakpoint() and 
> sys.__breakpointhook__ was unclear to me -- I had to go to the docs for 
> __displayhook__ 
> (https://docs.python.org/3/library/sys.html#sys.__displayhook__) to 
> understand that sys.__breakpointhook__ is simply initialized to the same 
> function as sys.breakpointhook, and the idea is that if you screw up you 
> can restore sys.breakpointhook from the other rather than having to 
> restart your process. Is that in fact it? The text 
> "``sys.__breakpointhook__`` then stashes the default value of 
> ``sys.breakpointhook()`` to make it easy to reset" seems to imply some 
> action that would happen... when? how?
> - Some pseudo-code would be nice. It seems that it's like this:

This will be helpful to anyone implementing their own breakpointhook.

> # in builtins
> def breakpoint(*args, **kwds):
>      import sys
>      return sys.breakpointhook(*args, **kwds)
> # in sys
> def breakpointhook(*args, **kwds):
>      import os
>      hook = os.getenv('PYTHONBREAKPOINT')
>      if hook == '0':
>          return None
>      if not hook:
>          import pdb
>          return pdb.set_trace(*args, **kwds)
>      if '.' not in hook:
>          import builtins
>          mod = builtins
>          funcname = hook
>      else:
>          modname, funcname = hook.rsplit('.', 1)
>          __import__(modname)
>          import sys
>          mod = sys.modules[modname]
>      func = getattr(mod, funcname)
>      return func(*args, **kwds)
> __breakpointhook__ = breakpointhook
> Except that the error handling should be a bit better. (In particular 
> the PEP specifies a try/except around most of the code in 
> sys.breakpointhook() that issues a RuntimeWarning and returns None.)
> - Not sure what the PEP's language around evaluation of PYTHONBREAKPOINT 
> means for the above pseudo code. I *think* the PEP author's opinion is 
> that the above pseudo-code is fine. Since programs can mutate their own 
> environment, I think something like `os.environ['PYTHONBREAKPOINT'] = 
> 'foo.bar.baz'; breakpoint()` should result in foo.bar.baz() being 
> imported and called, right?
> - I'm not quite sure what sort of fast-tracking for PYTHONBREAKPOINT=0 
> you had in mind beyond putting it first in the code above.
> - Did you get confirmation from other debuggers? E.g. does it work for 
> IDLE, Wing IDE, PyCharm, and VS 2015?
> - I'm not sure what the point would be of making a call to breakpoint() 
> a special opcode (it seems a lot of work for something of this nature). 
> ISTM that if some IDE modifies bytecode it can do whatever it well 
> please without a PEP.
> - I don't see the point of calling `pdb.pm <http://pdb.pm>()` at 
> breakpoint time. But it could be done using the PEP with `import pdb; 
> sys.breakpointhook = pdb.pm <http://pdb.pm>` right? So this hardly 
> deserves an open issue.
> - I haven't read the actual implementation in the PR. A PEP should not 
> depend on the actual proposed implementation for disambiguation of its 
> specification (hence my proposal to add pseudo-code to the PEP).

Terry Jan Reedy

More information about the Python-Dev mailing list