[Python-Dev] a quit that actually quits (original) (raw)

Fernando Perez fperez.net at gmail.com
Wed Dec 28 19:36:35 CET 2005


Alex Martelli wrote:

On Dec 28, 2005, at 3:24 AM, Michael Hudson wrote:

The thing that bothers me about it is that the standard way you tell python to do something is "call a function" -- to me, a special case for exiting the interpreter seems out of proportion. Just brainstorming, but -- maybe this means we should generalize the idea? I.e., allow other cases in which "just mentioning X" means "call function Y [with the following arguments]", at least at the interactive prompt if not more generally. If /F's idea gets implemented by binding to names 'exit' and 'quit' the result of some factory-call with "function to be called" set to sys.exit and "arguments for it" set to () [[as opposed to specialcasing checks of last commandline for equality to 'exit' &c]] then the implementation of the generalization would be no harder. I do find myself in sessions in which I want to perform some action repeatedly, and currently the least typing is 4 characters (x()) while this would reduce it to two (iPython does allow such handy shortcuts, but I'm often using plain interactive interpreters). If this generalization means a complicated implementation, by all means let's scrap it, but if implementation is roughly as easy, it may be worth considering to avoid making a too-special "special case" (or maybe not, but brainstorming means never having to say you're sorry;-).

Allow me to add a few comments, here: as the ipython author, I happen to have thought an awful lot about all these issues.

First, your suggestion of incorporating 'autocalling' ( the automatic 'foo a' -> 'foo(a)' transformation) into the core python interpreter may not be a very good idea. The code that does this is precisely the most brittle, delicate part of ipython, a little regexp/eval/introspection dance that tries really, really hard to understand whether 'foo' is a string that will point to a callable once evaluated, but without eating generators, causing side effects, or anything else. I know it sounds silly, and perhaps it's just my limitations, but it has taken several years to flesh out all the corner cases where this code could fail (and in the past, a few really surprising failure cases have been found).

In ipython, this functionality can still be turned off (via %autocall) at any time, in case it is not working correctly. You are welcome to look at the code, it's the _prefilter method here:

http://projects.scipy.org/ipython/ipython/file/ipython/trunk/IPython/iplib.py

So while I think that this is extremely useful in a third-party library like ipython, it's probably a little too delicate for the core, official interpreter where reliability is so absolutely critical. In fact, my own standard is that I trust the CPython prompt as a test of 'doing the right thing', so I like that it remains simple and solid.

Now, on to the wider discussion started by the quit/exit debate: the problem is that we are here trying to make some particular words 'interactive commands' in a language that doesn't have such a notion to begin with. The tension of how best to implement it, the various low-level tricks proposed, etc, stems (I think) from this underlying fact.

In IPyhton, I've convinced myself that this is a problem whose proper solution requires an orthogonal command subsystem, the 'magics' (credit where credit is due: the magic system was already in IPP, Janko Hauser's library which was one of ipython's three original components; Janko understood the issue early on and got it right). This creates a separate namespace, controlled by a disambiguation character (the % prefix in ipython), and therefore allows you to cleanly offer the kind of behavior and semantics which are more convenient for command-line use (whitespace argument separation, --dashed-options) without colliding with the underlying language.

By having the 'magic' command system be separate, it is also trivially extensible by the users (see http://ipython.scipy.org/doc/manual/node6.html#SECTION00062000000000000000 for details). This means that instead of going into a never-ending rabbit-chase of special cases, you now have a well-defined API (IPython's is primitive but it works, and we're cleaning it up as part of a major rework) where users can add arbitrary command functionality which remains separate from the language itself.

The main point here is, I think, that any good interactive environment for a programming language requires at least TWO separate kinds of syntax:

  1. the language itself, perhaps with aids to economize typing at the command line (ipython offers many: auto-calling, auto-quoting, readline tricks, input history as a Python list, output caching, macros, and more).

  2. a set of control commands, meant to manipulate the environment itself. These can obviously be implemented in the underlying language, but there should be a way to keep them in a separate namespace (so they don't collide with user variables and can be always called).

I'll be glad to discuss this further, either here or on the ipython lists where this is probably more appropriate. But I wanted to give the python-devs some perspective on this, from having spent a lot of time dealing directly with the isues.

Finally, I'd like to provide a bit of a plea: I hope that python itself doesn't end up polluting the core sys namespace with too many special things for interactive use. I think that a proper interactive console is best implemented as a separate extension (ipython, pycrust, idle, etc). Putting all these special-case things into sys ends up propagating everywhere, and potentially colliding with such systems (ipython has its own sys.excepthook, for example). Please keep the core (sys is very much part of the core) as clean as possible, and let the interactive shell writers add the functionality outside.

Best,

f

ps - thanks to this thread, I've changed ipython from having the old-style quit/exit strings with the message, to being magics which exit. It had always had %Quit/%Exit for unconditional exit, but now (SVN) it also has %quit/%exit which honor the confirm_exit rc setting.



More information about the Python-Dev mailing list