sourceforge just went off the air, so I'm posting this patch here, in order to distract you all from Christian's deque thread. this silly little patch changes the behaviour of the interpreter so that "quit" and "exit" actually exits the interpreter. it does this by installing a custom excepthook that looks for NameErrors at the top level, in interactive mode only. whaddya think? </F> Index: Lib/site.py =================================================================== --- Lib/site.py (revision 41831) +++ Lib/site.py (working copy) @@ -60,6 +60,7 @@ import sys import os import __builtin__ +import traceback def makepath(*paths): @@ -222,19 +223,20 @@ def setquit(): - """Define new built-ins 'quit' and 'exit'. - These are simply strings that display a hint on how to exit. + """Set default exception handler for the interactive mode.""" + def defaultexcepthook(exc_type, exc_value, exc_info): + if hasattr(sys, "ps1"): + # interactive mode + if isinstance(exc_value, NameError) and not exc_info.tb_next: + text = exc_value[0] + if (text == "name 'exit' is not defined" or + text == "name 'quit' is not defined"): + # XXX: print helpful "Use control-D etc" message here? + raise SystemExit + # XXX: add if text == "help" ? + traceback.print_exception(exc_type, exc_value, exc_info) + sys.excepthook = defaultexcepthook - """ - if os.sep == ':': - exit = 'Use Cmd-Q to quit.' - elif os.sep == '\\': - exit = 'Use Ctrl-Z plus Return to exit.' - else: - exit = 'Use Ctrl-D (i.e. EOF) to exit.' - __builtin__.quit = __builtin__.exit = exit - - class _Printer(object): """interactive prompt objects for printing the license text, a list of contributors and the copyright notice."""
Fredrik> whaddya think?
We're going to wind up with the same problem that spawned the atexit module:
multiple code sources wanting to fiddle with sys.excepthook step on one
another's toes. For example, I already use an excepthook in interactive
mode to try to resolve NameErrors:
% python
Python 2.5a0 (#2, Dec 10 2005, 14:05:27)
[GCC 3.3 20030304 (Apple Computer, Inc. build 1671)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> sys.excepthook
skip@pobox.com wrote:
Fredrik> whaddya think?
We're going to wind up with the same problem that spawned the atexit module: multiple code sources wanting to fiddle with sys.excepthook step on one another's toes.
in this case, I'm not sure it matters that much. if you add your own except- hook, you take responsibility. (it would be nice if it was possible to detect "interactive mode" when the site code runs, though. does anyone know if that's possible ?) </F>
Fredrik Lundh wrote:
(it would be nice if it was possible to detect "interactive mode" when the site code runs, though. does anyone know if that's possible ?)
I believe checking sys.argv==[''] is a nearly reliable test (the only other case where I could make it happen is when the script is read from stdin). Introducing a flag into InteractiveLoop would be an option, too. Regards, Martin
Fredrik Lundh wrote:
sourceforge just went off the air, so I'm posting this patch here, in order to distract you all from Christian's deque thread.
this silly little patch changes the behaviour of the interpreter so that "quit" and "exit" actually exits the interpreter. it does this by installing a custom excepthook that looks for NameErrors at the top level, in interactive mode only.
What is wrong with something like this:
class Quitter: ... def __repr__(self): raise SystemExit ... exit = quit = Quitter()
It could optionally check for top level too, of course. Reinhold -- Mail address is perfectly valid!
On 12/28/05, Reinhold Birkenfeld
Fredrik Lundh wrote:
sourceforge just went off the air, so I'm posting this patch here, in order to distract you all from Christian's deque thread.
this silly little patch changes the behaviour of the interpreter so that "quit" and "exit" actually exits the interpreter. it does this by installing a custom excepthook that looks for NameErrors at the top level, in interactive mode only.
What is wrong with something like this:
class Quitter: ... def __repr__(self): raise SystemExit ... exit = quit = Quitter()
It could optionally check for top level too, of course.
Not sure if this is what you mean by "check for top level too", but the obvious problem is that calling vars(__builtins__) (or similar) will cause your interpreter to exit. :) -- Twisted | Christopher Armstrong: International Man of Twistery Radix | -- http://radix.twistedmatrix.com | Release Manager, Twisted Project \\\V/// | -- http://twistedmatrix.com |o O| | w----v----w-+
On 27-dec-2005, at 14:55, Christopher Armstrong wrote:
On 12/28/05, Reinhold Birkenfeld
wrote: Fredrik Lundh wrote:
sourceforge just went off the air, so I'm posting this patch here, in order to distract you all from Christian's deque thread.
this silly little patch changes the behaviour of the interpreter so that "quit" and "exit" actually exits the interpreter. it does this by installing a custom excepthook that looks for NameErrors at the top level, in interactive mode only.
What is wrong with something like this:
class Quitter: ... def __repr__(self): raise SystemExit ... exit = quit = Quitter()
It could optionally check for top level too, of course.
Not sure if this is what you mean by "check for top level too", but the obvious problem is that calling vars(__builtins__) (or similar) will cause your interpreter to exit. :)
Why must quit and exit be so special in the first place? They could be plain functions, or even something like:: class _QuitOrExit: def __init__(self, name): self.name = name def __repr__(self): return "Use %(name)s() to exit."%(self.__dict__) def __call__(self): raise SystemExit quit = _QuitOrExit("quit") exit = _QuitOrExit("exit") Ronald
Ronald Oussoren wrote:
Why must quit and exit be so special in the first place? They could be plain functions, or even something like::
class _QuitOrExit: def __init__(self, name): self.name = name
def __repr__(self): return "Use %(name)s() to exit."%(self.__dict__)
def __call__(self): raise SystemExit
quit = _QuitOrExit("quit") exit = _QuitOrExit("exit")
but now we're back to today's situation: >>> quit 'Use Ctrl-Z plus Return to exit.' which violates the basic "if you know what I mean, why the /!"&/&!//%€ don't you do what I say" usability rule. </F>
On 27-dec-2005, at 16:39, Fredrik Lundh wrote:
Ronald Oussoren wrote:
Why must quit and exit be so special in the first place? They could be plain functions, or even something like::
class _QuitOrExit: def __init__(self, name): self.name = name
def __repr__(self): return "Use %(name)s() to exit."%(self.__dict__)
def __call__(self): raise SystemExit
quit = _QuitOrExit("quit") exit = _QuitOrExit("exit")
but now we're back to today's situation:
quit 'Use Ctrl-Z plus Return to exit.'
which violates the basic "if you know what I mean, why the /!"&/&!//%¤ don't you do what I say" usability rule.
I'd prefer 'def quit(): raise SystemExit', the class above just adds a message for someone that accidently got stuck in a python shell. I don't like the idea of making quit or exit special enough to cause side effects without parentheses, no other function does that. Anyone that knows how to program in Python should be able to guess that you have to use 'quit()' instead of 'quit'. BTW. I do agree that the current situation is stupid. Ronald
</F>
_______________________________________________ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/ ronaldoussoren%40mac.com
Ronald Oussoren wrote:
I'd prefer 'def quit(): raise SystemExit', the class above just adds a message for someone that accidently got stuck in a python shell. I don't like the idea of making quit or exit special enough to cause side effects without parentheses, no other function does that. Anyone that knows how to program in Python should be able to guess that you have to use 'quit()' instead of 'quit'.
The thing is there primarily for people who *don't* know how to program in Python. If they knew, they knew how to get out of it; they wouldn't type "quit()" but simply Ctrl-D. So if they do
quit
they are just as confused as if they got a name error. Regards, Martin
Martin> So if they do
>>> quit
It sounds to me like what is being proposed amounts to essentially
"promote sys.exit to a builtin". So why not do that?
I see two options. Either:
(a) Simply let __builtins__.exit = sys.exit. Then we get:
>>> exit
<built-in function exit>
which may be enough of a clue that you type "exit()" to exit.
(b) If more handholding seems like a good idea, then:
class ExitHatch:
def __call__(self): sys.exit()
def __repr__(self): return '
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Ka-Ping Yee wrote:
[...] (b) If more handholding seems like a good idea, then:
class ExitHatch: def __call__(self): sys.exit() def __repr__(self): return '
' __builtins__.exit = __builtins__.quit = ExitHatch()
That looks like a good compromise to me. - -- Gerhard -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.1 (GNU/Linux) Comment: Using GnuPG with Thunderbird - http://enigmail.mozdev.org iD8DBQFDsdPWdIO4ozGCH14RAsTyAKCW5mwCJ/cN+UbKICufXwmDIX9/tgCfQLJa LaEL4a4pV7Jhnh3ry/b+CrU= =/FQl -----END PGP SIGNATURE-----
On 12/27/05, Ka-Ping Yee
It sounds to me like what is being proposed amounts to essentially "promote sys.exit to a builtin". So why not do that?
I see two options. Either:
(a) Simply let __builtins__.exit = sys.exit. Then we get:
>>> exit <built-in function exit>
which may be enough of a clue that you type "exit()" to exit.
(b) If more handholding seems like a good idea, then:
class ExitHatch: def __call__(self): sys.exit() def __repr__(self): return '
' __builtins__.exit = __builtins__.quit = ExitHatch()
I prefer (b) since this does need to be newbie-friendly and thus self explaining. I would prefer the name ExitInterpreter for the class and including the keyboard shortcut in the message as well. And Tim had a good point about PDAs and such; how are they supposed to exit? What if someone picked up Python for their Nokia S60 phone and tried to exit from the interpreter? Unless Nokia has tweaked something I don't know how they would know to exit without knowing about sys.exit() or raising SystemExit since I wouldn't know how to do the equivalent Ctrl-D on a cell phone. -Brett
Brett Cannon wrote:
And Tim had a good point about PDAs and such; how are they supposed to exit? What if someone picked up Python for their Nokia S60 phone and tried to exit from the interpreter? Unless Nokia has tweaked something I don't know how they would know to exit without knowing about sys.exit() or raising SystemExit since I wouldn't know how to do the equivalent Ctrl-D on a cell phone.
The version of Python on my phone (2.2.2) doesn't recognize "quit" or "exit," but there is a soft key conveniently labeled "Exit" which drops out of the interactive console.
Fredrik> a quit/exit command that actually quits, instead of printing a Fredrik> "you didn't say please!" message. I like Fredrik's idea more and more. Without my Unix bifocals it wouldn't occur to me that Ctrl-D is the way to exit. Knowing Ctrl-Z is EOF on Windows, it wouldn't occur to me that I'd also have to hit Return. Without my Python shades I'd never guess to exit via "raise SystemExit". While the raise command is "one true way", it certainly won't occur to newbies. I have no idea how I'd exit from Pippy or from the interpreter prompt on a Nokia phone without it. In short, I think it makes a lot of sense to support a bare "exit" and/or "quit" as a completely intuitive platform-independent newbie-friendly way to exit the interpreter. Skip
skip@pobox.com wrote:
Fredrik> a quit/exit command that actually quits, instead of printing a Fredrik> "you didn't say please!" message.
I like Fredrik's idea more and more. Without my Unix bifocals it wouldn't occur to me that Ctrl-D is the way to exit. Knowing Ctrl-Z is EOF on Windows, it wouldn't occur to me that I'd also have to hit Return. Without my Python shades I'd never guess to exit via "raise SystemExit". While the raise command is "one true way", it certainly won't occur to newbies. I have no idea how I'd exit from Pippy or from the interpreter prompt on a Nokia phone without it.
In short, I think it makes a lot of sense to support a bare "exit" and/or "quit" as a completely intuitive platform-independent newbie-friendly way to exit the interpreter.
+1. Reinhold -- Mail address is perfectly valid!
skip@pobox.com wrote:
In short, I think it makes a lot of sense to support a bare "exit" and/or "quit" as a completely intuitive platform-independent newbie-friendly way to exit the interpreter.
I can readily agree to this part of Fredrik's proposal. What slightly bothers me is the hackish nature of the proposed implementation. Regards, Martin
Martin v. Löwis wrote:
In short, I think it makes a lot of sense to support a bare "exit" and/or "quit" as a completely intuitive platform-independent newbie-friendly way to exit the interpreter.
I can readily agree to this part of Fredrik's proposal. What slightly bothers me is the hackish nature of the proposed implementation.
here's my current proposal (see ping's post and my reply for background): if isinstance(exc_value, NameError) and not exc_info.tb_next: text = exc_value[0] name = ... extract name from nameerror string ... if sys.commandline.strip() == name: if name in ("exit", "quit"): raise SystemExit if name == "help": help() return ... any suggestions on how to improve this ? </F>
Fredrik Lundh wrote:
any suggestions on how to improve this ?
Introducing sys.commandline is fine; overriding sys.excepthook still worrisome. What's wrong with triggering this in some __repr__ implementation? If an excepthook must be installed, why couldn't the previous excepthook be preserved, and called in case the exception is not what you are looking for? Of course, even if this excepthook behaves friendly, some other package might overwrite excepthook without preserving yours, in which case people would "sometimes" get a NameError when they try to exit. Regards, Martin
Martin v. Löwis wrote:
Introducing sys.commandline is fine; overriding sys.excepthook still worrisome.
What's wrong with triggering this in some __repr__ implementation?
because simple introspection may exit your program. unexpected exits are a lot more annoying than unexpected non-exits.
If an excepthook must be installed, why couldn't the previous excepthook be preserved, and called in case the exception is not what you are looking for?
this is done in site.py, before sitecustomize is loaded. I'm not sure how anyone else would be able to squeeze in an excepthook at this point, even if they wanted...
Of course, even if this excepthook behaves friendly, some other package might overwrite excepthook without preserving yours, in which case people would "sometimes" get a NameError when they try to exit.
sure, but people may sometimes get another result if they rebind exit (e.g. from sys import *), plug in a broken displayhook, or other- wise mess up their system. as long the documentation mentions how this works, and urges excepthook developers to be careful, I don't really see this as a problem. </F>
Fredrik Lundh wrote:
this is done in site.py, before sitecustomize is loaded. I'm not sure how anyone else would be able to squeeze in an excepthook at this point, even if they wanted...
I see. Still, I think the Python code should give a good example. There *is* an excepthook installed at that point, anyway, so we should use it. Otherwise, I think the approach is fine. Regards, Martin
Fredrik> if isinstance(exc_value, NameError) and not exc_info.tb_next: Fredrik> text = exc_value[0] Fredrik> name = ... extract name from nameerror string ... Fredrik> if sys.commandline.strip() == name: Fredrik> if name in ("exit", "quit"): Fredrik> raise SystemExit Fredrik> if name == "help": Fredrik> help() Fredrik> return Fredrik> ... Fredrik> any suggestions on how to improve this ? I'd make it sys._last_input or something similar to make it clear that a) this is magic, don't mess with it, and that b) this is the last user input, not the raw command line. Skip
skip@pobox.com writes:
Fredrik> a quit/exit command that actually quits, instead of printing a Fredrik> "you didn't say please!" message.
I like Fredrik's idea more and more.
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. In other news, clever hacks with tb_next and so on also seem excessive. Why not have the equivalent of "if input.rstrip() == 'exit': sys.exit()" in the implementation of the interactive interpreter? Cheers, mwh -- My first thought was someone should offer Mr. Bush elocution lessons. But he'd probably say he knew how to work them chairs already. -- Internet Oracularity #1294-01
Michael Hudson wrote:
skip@pobox.com writes:
Fredrik> a quit/exit command that actually quits, instead of printing a Fredrik> "you didn't say please!" message.
I like Fredrik's idea more and more.
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.
also worth remarking is that is quite a FAQ at least for Jython, how to convince python to accept bare words (plus args) as function calls. So this magic is confusing and in the wrong direction from that point of view, given that we don't plan to support that at all.
In other news, clever hacks with tb_next and so on also seem excessive. Why not have the equivalent of "if input.rstrip() == 'exit': sys.exit()" in the implementation of the interactive interpreter?
Cheers, mwh
"Fredrik Lundh"
Michael Hudson wrote:
In other news, clever hacks with tb_next and so on also seem excessive. Why not have the equivalent of "if input.rstrip() == 'exit': sys.exit()" in the implementation of the interactive interpreter?
that would turn exit and quit into reserved keywords.
In what sense? Not in the sense of "things in single quotes in Grammar"... Cheers, mwh -- There are two kinds of large software systems: those that evolved from small systems and those that don't work. -- Seen on slashdot.org, then quoted by amk
Michael Hudson wrote:
that would turn exit and quit into reserved keywords.
In what sense? Not in the sense of "things in single quotes in Grammar"...
no, but in the sense of "names that can no longer be used in code" >>> def exit(): ... print "bye" >>> # what is it? >>> exit $ oops! the whole nameerror thing is there to avoid problems if you create your own exit variables/functions/classes/modules. </F>
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.
That would assume that the user knows that exit is a function: apparently, people expect it to be a statement (like print), or they are entirely unaware of the distinctions between statements, expressions, and functions. I often find that my students call them "commands" collectively (if they want to be more specific, they call the functions "methods"). Regards, Martin
"Martin" == Martin v Löwis
writes:
Martin> That would assume that the user knows that exit is a Martin> function: apparently, people expect it to be a statement Martin> (like print), Oh, the irony of that analogy!<wink> Martin> or they are entirely unaware of the distinctions between Martin> statements, expressions, and functions. Then there's little point to giving them access to the interpreter! Of course, Martin also mentioned "students". Python is not the only language in the world; we all know that, even if most of us much prefer programming in Python to any other environment. If you're teaching, why not use this as an opportunity to deliver a brief lecture on why Python does things differently, and why one should understand a _formal_ language in its own terms, not in terms of what you (the user/programmer) want it to be for momentary convenience? My feeling is that the current behavior of "exit" and "quit" is not "you didn't say please" but "excuse me, I don't speak BASIC; would you say that in Python or signal that the conversation is over (ie, EOF)?" For me, that's part of the Zen of Python. Probably I'm just missing something given the amount of support this idea is getting, from really respectable sources, too, but it just seems wrong to change this. What's wrong with having a distinctive personality? I suppose the current value of those variables sounds a bit rude. Why not fix the discourtesy, rather than what's not broken (IMHO)? exit = """\ The Python interpreter simply interprets a Python program. It provides no special interactive commands. The line editor is a thin front-end to the standard input stream. To exit your program, use one of the functions or exceptions provided for this purpose, or simply end the file (interactively this is signaled by Ctrl-D). This public service message brought to you by the global variable 'exit'.""" -- School of Systems and Information Engineering http://turnbull.sk.tsukuba.ac.jp University of Tsukuba Tennodai 1-1-1 Tsukuba 305-8573 JAPAN Ask not how you can "do" free software business; ask what your business can "do for" free software.
On Dec 28, 2005, at 3:24 AM, Michael Hudson wrote:
skip@pobox.com writes:
Fredrik> a quit/exit command that actually quits, instead of printing a Fredrik> "you didn't say please!" message.
I like Fredrik's idea more and more.
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()<enter>) 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;-). Alex
Alex Martelli wrote:
On Dec 28, 2005, at 3:24 AM, Michael Hudson wrote:
skip@pobox.com writes:
Fredrik> a quit/exit command that actually quits, instead of printing a Fredrik> "you didn't say please!" message.
I like Fredrik's idea more and more.
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]]
We have sys.displayhook and sys.excepthook. Why not add a sys.inputhook? sys.inputhook gets passed each line entered and may return True if it has processed the line inself and False if normal handling of the input should be done. This allows special treatment of "quit", "exit", "help" and it might make implementing alternative shells for Python easier (without having to subclass code.InteractiveConsole).
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()<enter>) while this would reduce it to two
What's wrong with <cursor up>, <return>?
(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;-).
Bye, Walter Dörwald
[Alex]
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]]
[Walter]
We have sys.displayhook and sys.excepthook. Why not add a sys.inputhook? sys.inputhook gets passed each line entered and may return True if it has processed the line inself and False if normal handling of the input should be done. This allows special treatment of "quit", "exit", "help" and it might make implementing alternative shells for Python easier (without having to subclass code.InteractiveConsole).
[Alex]
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()<enter>) while this would reduce it to two
Hmm. . . def default_inputhook(statement): try: aliased = sys.aliases[statement] except KeyError: return False else: aliased() return True sys.aliases = dict(exit=sys.exit, quit=sys.exit) sys.inputhook = default_inputhook I think Walter's idea may have merit (although I believe the input hook should be passed whole statements, rather than individual lines). Cheers, Nick. -- Nick Coghlan | ncoghlan@gmail.com | Brisbane, Australia --------------------------------------------------------------- http://www.boredomandlaziness.org
On 12/28/05, Walter Dörwald
We have sys.displayhook and sys.excepthook. Why not add a sys.inputhook?
Sure, particularly with Nick's suggestion for a default input hook it would be fine.
sessions in which I want to perform some action repeatedly, and currently the least typing is 4 characters (x()<enter>) while this would reduce it to two
What's wrong with <cursor up>, <return>?
The fact that there is no upper bound to the number of cursor-up keystrokes needed here -- by "perform some action repeatedly" I don't mean "half a dozen times right after each other with nothing in-between" (sorry for the ambiguous phrasing), but "numerous times, repeatedly in the course of an interactive interpreter session". Alex
Alex Martelli wrote:
On 12/28/05, Walter Dörwald
wrote: ... We have sys.displayhook and sys.excepthook. Why not add a sys.inputhook?
Sure, particularly with Nick's suggestion for a default input hook it would be fine.
I'd like the inputhook to be able to define the prompt. I'm not sure how this could be accomplished. Another API would be that the inputhook returns what line or command should be executed instead, e.g. def default_inputhook(statement): if statement.endswith("?"): return "help(%s)" % statement[:-1] etc.
sessions in which I want to perform some action repeatedly, and currently the least typing is 4 characters (x()<enter>) while this would reduce it to two
What's wrong with <cursor up>, <return>?
The fact that there is no upper bound to the number of cursor-up keystrokes needed here -- by "perform some action repeatedly" I don't mean "half a dozen times right after each other with nothing in-between" (sorry for the ambiguous phrasing), but "numerous times, repeatedly in the course of an interactive interpreter session".
OK, for that I've modified my .inputrc to map <page up> to incremental-search-backwards. With this it's: <x> <page up> <return> (and it even works when the input is x("averylonginputstring")). That's not as fast as <x> <return>, but it's close. Bye, Walter Dörwald
Walter Dörwald wrote:
Alex Martelli wrote:
On 12/28/05, Walter Dörwald
wrote: ... We have sys.displayhook and sys.excepthook. Why not add a sys.inputhook?
Sure, particularly with Nick's suggestion for a default input hook it would be fine.
I'd like the inputhook to be able to define the prompt. I'm not sure how this could be accomplished.
Another API would be that the inputhook returns what line or command should be executed instead, e.g.
def default_inputhook(statement): if statement.endswith("?"): return "help(%s)" % statement[:-1] etc.
And you're on your way to re-writing ipython:
In [1]: x='hello'
In [2]: x?
Type: str
Base Class:
Fernando Perez wrote:
In [1]: x='hello'
In [2]: x? /.../ Docstring: str(object) -> string
Return a nice string representation of the object. If the argument is a string, the return value is the same object.
I'm not sure what I find more confusing: a help system that claims that the variable x returns a nice string representation of an object, or that there's no help to be found for "hello".
x = "hello" help(x) no Python documentation found for 'hello'
</F>
Fredrik Lundh wrote:
Fernando Perez wrote:
In [1]: x='hello'
In [2]: x? /.../ Docstring: str(object) -> string
Return a nice string representation of the object. If the argument is a string, the return value is the same object.
I'm not sure what I find more confusing: a help system that claims that the variable x returns a nice string representation of an object, or that there's no help to be found for "hello".
Then, complain about docstrings: Python 2.3.4 (#1, Feb 2 2005, 12:11:53) [GCC 3.4.2 20041017 (Red Hat 3.4.2-6.fc3)] on linux2 Type "help", "copyright", "credits" or "license" for more information.
x='hello' print x.__doc__ str(object) -> string
Return a nice string representation of the object. If the argument is a string, the return value is the same object. ==== In ipython, '?' does the best it can to collect information about an object, making heavy use of python's introspection capabilities. It provides class and constructor docstrings, function call signatures (built from the function code object), and more. Using ?? gives even more details, including syntax-highlighted source when available. For example: In [5]: pydoc.ErrorDuringImport?? Type: classobj String Form: pydoc.ErrorDuringImport Namespace: Interactive File: /usr/lib/python2.3/pydoc.py Source: class ErrorDuringImport(Exception): """Errors that occurred while trying to import something to document it.""" def __init__(self, filename, (exc, value, tb)): self.filename = filename self.exc = exc self.value = value self.tb = tb def __str__(self): exc = self.exc if type(exc) is types.ClassType: exc = exc.__name__ return 'problem in %s - %s: %s' % (self.filename, exc, self.value) Constructor information: Definition: pydoc.ErrorDuringImport(self, filename, (exc, value, tb)) I'm sorry it can't provide the information you'd like to see. It is still found to be useful by many people, including myself. You are welcome to use it, and patches to improve it will be well received. Best, f
Walter Dörwald wrote:
We have sys.displayhook and sys.excepthook. Why not add a sys.inputhook? sys.inputhook gets passed each line entered and may return True if it has processed the line inself and False if normal handling of the input should be done. This allows special treatment of "quit", "exit", "help" /.../
so how would such a hook deal with the >>> def exit(): ... pass >>> exit case ? </F>
Fredrik Lundh wrote:
Walter Dörwald wrote:
We have sys.displayhook and sys.excepthook. Why not add a sys.inputhook? sys.inputhook gets passed each line entered and may return True if it has processed the line inself and False if normal handling of the input should be done. This allows special treatment of "quit", "exit", "help" /.../
so how would such a hook deal with the
>>> def exit(): ... pass >>> exit
case ?
In the inputhook one would have to check for "exit" being defined at interpreter level. Reinhold -- Mail address is perfectly valid!
Reinhold Birkenfeld wrote:
Fredrik Lundh wrote:
Walter Dörwald wrote:
We have sys.displayhook and sys.excepthook. Why not add a sys.inputhook? sys.inputhook gets passed each line entered and may return True if it has processed the line inself and False if normal handling of the input should be done. This allows special treatment of "quit", "exit", "help" /.../ so how would such a hook deal with the
>>> def exit(): ... pass >>> exit
case ?
In the inputhook one would have to check for "exit" being defined at interpreter level.
Which is fairly trivial given a slight change to my proposed default input hook: def default_inputhook(statement): if statement in vars(sys.modules["__main__"]): return False try: aliased = sys.alias[statement] except KeyError: return False else: aliased() return True That is, a real variable will always shadow an alias - you need to get rid of the real variable before the alias will start working again (or else change the name of the alias). Or you can give the alias a different name via: sys.alias["exit_"] = sys.alias["exit"] Cheers, Nick. -- Nick Coghlan | ncoghlan@gmail.com | Brisbane, Australia --------------------------------------------------------------- http://www.boredomandlaziness.org
Here's yet a different take on this: why not simply change the startup message? Whether we choose "quit" or "exit", someone will get it wrong unless there's an alias. Changing the message is free. Currently we have Type "help", "copyright", "credits" or "license" for more information. Let's add another line that says Type "quit()" to exit Defining it as "def quit(): raise SystemExit" should be fine. -- Aahz (aahz@pythoncraft.com) <*> http://www.pythoncraft.com/ "Given that C++ has pointers and typecasts, it's really hard to have a serious conversation about type safety with a C++ programmer and keep a straight face. It's kind of like having a guy who juggles chainsaws wearing body armor arguing with a guy who juggles rubber chickens wearing a T-shirt about who's in more danger." --Roy Smith
On 12/28/05, Aahz
Here's yet a different take on this: why not simply change the startup message? Whether we choose "quit" or "exit", someone will get it wrong unless there's an alias. Changing the message is free. Currently we have
Type "help", "copyright", "credits" or "license" for more information.
Let's add another line that says
Type "quit()" to exit
Defining it as "def quit(): raise SystemExit" should be fine. --
Just because people don't read unless it it thrown in their face. =) But that is still nice and simple and won't hurt. I would still suggest using a class so that the repr can give a useful message, though. -Brett
On Wed, Dec 28, 2005, Brett Cannon wrote:
On 12/28/05, Aahz
wrote: Here's yet a different take on this: why not simply change the startup message? Whether we choose "quit" or "exit", someone will get it wrong unless there's an alias. Changing the message is free. Currently we have
Type "help", "copyright", "credits" or "license" for more information.
Let's add another line that says
Type "quit()" to exit
Defining it as "def quit(): raise SystemExit" should be fine.
Just because people don't read unless it it thrown in their face. =) But that is still nice and simple and won't hurt. I would still suggest using a class so that the repr can give a useful message, though.
That's fine. I think the primary use case for this is someone who accidentally stumbles into the Python interpreter, in which case that message will be a life-saver. Anybody who is formally attempting to use the interpreter probably has ready access to docs that explain how to use it. -- Aahz (aahz@pythoncraft.com) <*> http://www.pythoncraft.com/ "Given that C++ has pointers and typecasts, it's really hard to have a serious conversation about type safety with a C++ programmer and keep a straight face. It's kind of like having a guy who juggles chainsaws wearing body armor arguing with a guy who juggles rubber chickens wearing a T-shirt about who's in more danger." --Roy Smith
Aahz wrote:
On Wed, Dec 28, 2005, Brett Cannon wrote:
On 12/28/05, Aahz
wrote: Here's yet a different take on this: .. change the startup message... Type "help", "copyright", "credits" or "license" for more information. Let's add another line that says Type "quit()" to exit ...
Or, perhaps: class _Quitter(str): def __call__(self): raise SystemExit quit = _Quitter('The quit command. Type "quit()" to exit') exit = _Quitter('The exit command. Type "exit()" to exit') --Scott David Daniels Scott.Daniels@Acm.Org
Scott David Daniels
Or, perhaps: class _Quitter(str): def __call__(self): raise SystemExit quit = _Quitter('The quit command. Type "quit()" to exit') exit = _Quitter('The exit command. Type "exit()" to exit')
FWIW, I like this kind of solution best. Something magical would be a mistake. I don't like the status quo because there is no cross-plaform way to indicate EOF (or more pedantically "push current line"). Maybe we can make everyone happy by making the 'quit' and 'exit' objects callable and changing the message to something like: Use quit() or Ctrl-D (i.e. EOF) to exit. Cheers, Neil
Neil Schemenauer wrote:
Scott David Daniels
wrote: Or, perhaps: class _Quitter(str): def __call__(self): raise SystemExit quit = _Quitter('The quit command. Type "quit()" to exit') exit = _Quitter('The exit command. Type "exit()" to exit')
FWIW, I like this kind of solution best. Something magical would be a mistake. I don't like the status quo because there is no cross-plaform way to indicate EOF (or more pedantically "push current line"). Maybe we can make everyone happy by making the 'quit' and 'exit' objects callable and changing the message to something like:
Use quit() or Ctrl-D (i.e. EOF) to exit.
Cheers,
This sounds pretty good actually (especially combined with the modifed startup banner which tells you how to exit). As Fernando pointed out, anything else means we'd be well on our way to re-inventing IPython (although I'd be interested to know if sys.inputhook would have made IPython easier to write). Cheers, Nick. -- Nick Coghlan | ncoghlan@gmail.com | Brisbane, Australia --------------------------------------------------------------- http://www.boredomandlaziness.org
Nick Coghlan wrote:
As Fernando pointed out, anything else means we'd be well on our way to re-inventing IPython (although I'd be interested to know if sys.inputhook would have made IPython easier to write).
[sorry if this drifts off-topic for python-dev. I'll try to provide useful info on interactive computing in python here, and will gladly answer further detailed discussion about ipython on the ipython-dev/user lists ] In my case, I don't think it would have made that much of a difference in the end, though initially it might have been tempting to use it. IPython started as my private collection of sys.ps{1,2} + sys.displayhook hacks in $PYTHONSTARTUP. I then discovered LazyPython, which had a great sys.excepthook, and IPP, which was a full-blown derivative of code.InteractiveConsole. I decided to join all three projects, and thus was ipython born. Given that IPP was the 'architecture', from the moment we had what is still today's ipython, it was based on code.InteractiveConsole, and at that point I doubt that having sys.inputhook would have mattered. Incidentally, just two days ago I removed the last connection to code.py: at this point I had overridden so many methods, that there was no point in keeping the inheritance relationship. All I had to do was copy _two_ remaining methods, and the main ipython class became standalone (this frees me for ongoing redesign work, so it was worth doing it). So in summary, while sys.inputhook would make it easy to do _lightweight_ interactive customizations, if you really want a more sophisticated and featureful system, it probably won't matter. Note that this is not an argument against sys.inputhook: exposing customizability here may indeed be useful. This will allow people to write, with minimal effort, systems which pre-process special syntaxes and ride on top of the python engine. IPython exposes the exact same thing as a customizable hook (called prefilter), and people have made some excellent use of this capability. The most notable one is SAGE: http://modular.ucsd.edu/sage a system for interactive mathematical computing (NSF funded). If anyone is in the San Diego area, the first SAGE meeting is in February: http://modular.ucsd.edu/sage/days1/ and I'll be giving a talk there about ipython, including some of its design and my plans for a more ambitious system for interactive computing (including distributed computing) based on Python. The prototypes of what we've done so far are briefly described here (the first was funded by Google as a summer of code project): http://ipython.scipy.org/misc/ipython-notebooks-scipy05.pdf http://ipython.scipy.org/misc/scipy05-parallel.pdf I hope this is of some use and interest. Regards, f
class _Quitter(str): def __call__(self): raise SystemExit quit = _Quitter('The quit command. Type "quit()" to exit') exit = _Quitter('The exit command. Type "exit()" to exit')
I think you meant class _Quitter(str): def __call__(self): raise SystemExit quit = _Quitter('The quit command. Type "quit()" to quit') exit = _Quitter('The exit command. Type "exit()" to exit') :-) -- g
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()<enter>) 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.p... 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.
[Alex Martelli]
On Dec 28, 2005, at 3:24 AM, Michael Hudson wrote:
skip@pobox.com writes:
Fredrik> a quit/exit command that actually quits, instead of Fredric> printing a "you didn't say please!" message.
I like Fredrik's idea more and more.
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.
Just brainstorming then! :-) The fact that dot notation is used both for accessing globals from a module, and attributes from a class or an instance, does not mean that modules are classes, but surely, they are instances of something, and maybe we could build more on the similarities despite the differences. Through __getattr__ (and also properties and more generally descriptors), it is possible to create instance attributes triggering functional behaviour. Maybe it could be useful creating some (vaguely) similar mechanism for modules' globals. Then, `quit' and `exit' could be mere cases of that mechanism. It is desirable, in my opinion, that interactive behaviour be as identical as possible as script behaviour: the automatic printing of interactive mode is already much magic that newcomers need to sort out. -- François Pinard http://pinard.progiciels-bpi.ca
On Wed, 28 Dec 2005, Fredrik Lundh wrote:
It sounds to me like what is being proposed amounts to essentially "promote sys.exit to a builtin". no, what's being proposed is what the subject says: a quit/exit command
Ka-Ping Yee wrote that actually quits, instead of printing a "you didn't say please!" message.
Okay, that would be fine. It's just that the solutions so far that work without parentheses are a bit too magical for me. Fredrik's NameError-based proposal (exit when there's an exception with no tb_next that says "name 'exit' is not defined") causes the interpreter to quit when you enter any expression involving 'exit'. print exit # seems surprising [3, 4, 5, exit] # seems surprising 'a' in 'xyz' or exit # desirable or undesirable? del exit # actually happened to me x = exit # seems surprising Reinhold's proposal (exit when sys._getframe(1).f_code.co_names is ("exit",)) causes the interpreter to quit whenever any function attempts to print out or represent 'exit', as long as it doesn't mention any other variables. print exit # seems surprising [3, 4, 5, exit] # seems surprising 'a' in 'xyz' or exit # desirable or undesirable? def foo(): print exit foo() # seems surprising I'd be happy with having Python exit when the user types just plain 'exit' without parentheses, but only in that case, not others. However, i'm starting to think that may be impossible to implement. I can't think of any way to make 'print exit' not exit, for example. ("'exit'" is a shorthand for "'exit' or 'quit'" above.) -- ?!ng
Ka-Ping Yee wrote:
Fredrik's NameError-based proposal (exit when there's an exception with no tb_next that says "name 'exit' is not defined") causes the interpreter to quit when you enter any expression involving 'exit'.
print exit # seems surprising [3, 4, 5, exit] # seems surprising 'a' in 'xyz' or exit # desirable or undesirable? del exit # actually happened to me x = exit # seems surprising
the easiest way to solve this that I can think of right now is to add a new sys variable that contains a copy of the most recent line read by the interactive prompt. if sys.commandline.strip() in ("exit", "quit"): sys.exit() </F>
Ka-Ping Yee wrote:
I'd be happy with having Python exit when the user types just plain 'exit' without parentheses, but only in that case, not others. However, i'm starting to think that may be impossible to implement. I can't think of any way to make 'print exit' not exit, for example.
OK, here's one: def quithook(obj, _exit=__builtins__.exit, _displayhook=sys.displayhook): if obj is _exit: raise SystemExit _displayhook(obj) sys.displayhook = quithook It does, however, fall into the whole issue of chaining that Skip brought up earlier. -- Jeremy Kloth Fourthought, Inc. http://fourthought.com/ http://4suite.org/
Jeremy Kloth wrote:
Ka-Ping Yee wrote:
I'd be happy with having Python exit when the user types just plain 'exit' without parentheses, but only in that case, not others. However, i'm starting to think that may be impossible to implement. I can't think of any way to make 'print exit' not exit, for example.
OK, here's one:
def quithook(obj, _exit=__builtins__.exit, _displayhook=sys.displayhook): if obj is _exit: raise SystemExit _displayhook(obj) sys.displayhook = quithook
It does, however, fall into the whole issue of chaining that Skip brought up earlier.
as well as various introspection-related issues: >>> import foo >>> cb = foo.getcallback() >>> # let's see what it is >>> cb $ (by the way, it's "__builtin__", not "__builtins__". the former is a module, the latter a CPython implementation detail) </F>
Martin v. Löwis wrote:
The thing is there primarily for people who *don't* know how to program in Python. If they knew, they knew how to get out of it; they wouldn't type "quit()" but simply Ctrl-D.
Except that on Windows, it's Ctrl-Z. This can be quite confusing when you regularly use Python on both Windows and Unix, and use the wrong key combination. Ctrl-D on Windows does not have the desired result, and Ctrl-Z on Unix suspends the process. (And if you use a GUI version, they often have their own rules... on IDLE for Windows, Ctrl-D works but Ctrl-Z doesn't; on PyCrust, neither one works.) Granted, it's not a big problem, but it *is* annoying. IMHO, it would be more useful if you could just type 'exit' or 'quit' (like in many other interpreters) and be done with it, rather than having to remember the correct key combination. (A key combination which has nothing to do with the Python language per se.) -- Hans Nowak http://zephyrfalcon.org/
Hans Nowak wrote:
Granted, it's not a big problem, but it *is* annoying. IMHO, it would be more useful if you could just type 'exit' or 'quit' (like in many other interpreters) and be done with it, rather than having to remember the correct key combination. (A key combination which has nothing to do with the Python language per se.)
If you want to type something consistently across platforms, you can currently do
raise SystemExit
Regards, Martin
Martin v. Löwis wrote:
If you want to type something consistently across platforms, you can currently do
raise SystemExit
I'm not sure what to say to that. Do you really want to type "raise SystemExit" every time you want to exit the interpreter? (Your answer would probably be something like "No -- that's why I use Ctrl-D". But that wouldn't really get us anywhere, would it?) My point is that there is currently no acceptable, universal way to exit the interpreter. Again, it's not that big of a deal... but it seems silly that something apparently trivial like that cannot be done right. -- Hans Nowak http://zephyrfalcon.org/
[Martin v. Löwis]
If you want to type something consistently across platforms, you can currently do
raise SystemExit
[Hans Nowak]
I'm not sure what to say to that. Do you really want to type "raise SystemExit" every time you want to exit the interpreter? (Your answer would probably be something like "No -- that's why I use Ctrl-D". But that wouldn't really get us anywhere, would it?)
My point is that there is currently no acceptable, universal way to exit the interpreter. ...
I haven't used Python on a PDA yet, but on everything from PCs to mainframes I get out of the interpreter just by pulling the power plug. Why on Earth would you want to exit Python while your machine was running? Aha! The light dawns. resolve-to-keep-python-running-24/7-in-2006-ly y'rs - tim
Hans Nowak wrote:
My point is that there is currently no acceptable, universal way to exit the interpreter. Again, it's not that big of a deal... but it seems silly that something apparently trivial like that cannot be done right.
it's the usual problem: getting enough developers to agree that this really is a problem is a lot more work than implementing it... oh, well. looks like SF is back up again. I'll post the patch over there when I find the time... </F>
Python 2.4.2 (#67, Sep 28 2005, 12:41:11) [MSC v.1310 32 bit (Intel)] on win32 Type "help", "copyright", "credits" or "license" for more information.
exit 'Use Ctrl-Z plus Return to exit.'
I've just tried Ctrl+Z (plus Return) and some variations on Win XP and it doesn't work! Ctrl+D does. Beside, it should be spelled Ctrl+Z and not Ctrl-Z (at least this is the Windows way). I think it's intuitive for exit/quit to exit the interactive interpreter. That's what I did the first time I've tried Python. In another one (I think CLISP, but I'm not sure) I couldn't figure out how to exit. And definatly in CLISP when trying simple things I always got stuck in some kind or different error mode (with a different prompt). That's why I gave up playing with it.
Adal Chiriliuc wrote:
Python 2.4.2 (#67, Sep 28 2005, 12:41:11) [MSC v.1310 32 bit (Intel)] on win32 Type "help", "copyright", "credits" or "license" for more information.
exit 'Use Ctrl-Z plus Return to exit.'
I've just tried Ctrl+Z (plus Return) and some variations on Win XP and it doesn't work! Ctrl+D does.
WinXP or WinXP+Cygwin ? here's what I get:
python Python 2.4.1 (#65, Mar 30 2005, 09:13:57) [MSC v.1310 32 bit (Intel)] on win32 Type "help", "copyright", "credits" or "license" for more information.
^Z
python Python 2.4.1 (#65, Mar 30 2005, 09:13:57) [MSC v.1310 32 bit (Intel)] on win32 Type "help", "copyright", "credits" or "license" for more information.
^D File "<stdin>", line 1 ? ^ SyntaxError: invalid syntax
</F>
On Wednesday, December 28, 2005 Fredrik Lundh wrote:
WinXP or WinXP+Cygwin ? here's what I get:
Normal WinXP, without Cygwin.
python Python 2.4.1 (#65, Mar 30 2005, 09:13:57) [MSC v.1310 32 bit (Intel)] on win32 Type "help", "copyright", "credits" or "license" for more information.
^Z
python Python 2.4.1 (#65, Mar 30 2005, 09:13:57) [MSC v.1310 32 bit (Intel)] on win32 Type "help", "copyright", "credits" or "license" for more information.
^D File "<stdin>", line 1 ? ^ SyntaxError: invalid syntax
I tracked this down to having IPython installed. I was able to get the exact behaviour you've got by disabling the "readline" package from "site-packages". I have a solution proposal (I have no idea if it's feasible): why not intercept "exit" and "quit" in the interpreter command line parser? A simple regexp should do. Is the interactive interpreter implemented in Python or on the C side?
Adal Chiriliuc wrote:
I have a solution proposal (I have no idea if it's feasible): why not intercept "exit" and "quit" in the interpreter command line parser? A simple regexp should do. Is the interactive interpreter implemented in Python or on the C side?
In short: it's not feasible. Please don't propose such things on python-dev without an implementation strategy in mind. Regards, Martin
Hans Nowak wrote:
I'm not sure what to say to that. Do you really want to type "raise SystemExit" every time you want to exit the interpreter? (Your answer would probably be something like "No -- that's why I use Ctrl-D". But that wouldn't really get us anywhere, would it?)
Well... I understand that you want "exit" to quit the interpreter, and I can understand why you want that. Fredrik's proposed change started that entire thread.
My point is that there is currently no acceptable, universal way to exit the interpreter.
That clearly depends on the definition of "acceptable". If "acceptable" means "using a four-letter keyword", then you are right, yes.
Again, it's not that big of a deal... but it seems silly that something apparently trivial like that cannot be done right.
It's silly only if you understand the background that leads to this state of affairs. Regards, Martin
On 12/27/05, Fredrik Lundh
but now we're back to today's situation:
>>> quit 'Use Ctrl-Z plus Return to exit.'
which violates the basic "if you know what I mean, why the /!"&/&!//%¤ don't you do what I say" usability rule.
What nonsense. Every Python programmer knows that the right way to exit Python is to enter a platform EOF. The quit and exit variables are compromises for non-programmers who have accidentally entered Python and who don't know how to get out of it (this is usually the same category of people who don't know how or don't dare to kill a program using heavy artillery). Rather than improving upon the quit/exit functionality a la /F's patch I'd get rid of the compromise. Now, for Py3K we could try to come up with a more intelligent interactive mode. Probably not implemented in C. Perhaps using ideas from ipython (which I've personally never used). We might provide a quit or exit command using a more sophisticated mechanism. But there are always costs (e.g. the violation of the primciple that typing a name shows its repr()). In the mean time I'm a strong believer in "it ain't broke so don't fix it" here. -- --Guido van Rossum (home page: http://www.python.org/~guido/)
Guido van Rossum wrote:
but now we're back to today's situation:
>>> quit 'Use Ctrl-Z plus Return to exit.'
which violates the basic "if you know what I mean, why the /!"&/&!//%€ don't you do what I say" usability rule.
What nonsense. Every Python programmer knows that the right way to exit Python is to enter a platform EOF. The quit and exit variables are compromises for non-programmers who have accidentally entered Python and who don't know how to get out of it
why is it that "non-pythoneers" are always referred to as "non-programmers" ? is the current user base so large so we no longer need to care about people moving in from other environments ? (for those who follow non-python forums, there's a meme going around out there that says that python developers are arrogant, and will always defend the existing design with "we're right, you're wrong" or a "we're right, you're stupid", and that the current "exit" non-design is an excellent example of this. my proposal was partially motivated by an urge to prove them wrong, but it seems as I accidentally proved them to be right...) </F>
>> (for those who follow non-python forums Fredrik> make that "those who don't follow" What might some of those non-python forums be? Skip
skip@pobox.com wrote:
Fredrik> make that "those who don't follow"
What might some of those non-python forums be?
assorted corners of the blogosphere, mostly. no time to dig up any explicit references, since I'm preparing for a 650 km trip through a major snowstorm, but searching backwards from bruce eckel's recent "The departure of the hyper-enthusiasts" might help you find some: http://www.artima.com/weblogs/viewpost.jsp?thread=141312 </F>
Guido van Rossum wrote:
On 12/27/05, Fredrik Lundh
wrote: but now we're back to today's situation:
quit 'Use Ctrl-Z plus Return to exit.'
which violates the basic "if you know what I mean, why the /!"&/&!//%¤ don't you do what I say" usability rule.
What nonsense. Every Python programmer knows that the right way to exit Python is to enter a platform EOF. The quit and exit variables are compromises for non-programmers who have accidentally entered Python and who don't know how to get out of it (this is usually the same category of people who don't know how or don't dare to kill a program using heavy artillery).
Except that if you have iPython installed on Windows you *don't* enter the platform EOF any more, you enter CTRL/D (which threw me for a while). Plus the standard Windows build requires a return after the CTRL/Z while the Pythonware versions (last time I looked) only required the CTRL/Z. So the situation is a little less black-and-white than it might be.
Rather than improving upon the quit/exit functionality a la /F's patch I'd get rid of the compromise.
I *have* been surprised by the amount on brainpower that's been expended on this discussion.
Now, for Py3K we could try to come up with a more intelligent interactive mode. Probably not implemented in C. Perhaps using ideas from ipython (which I've personally never used). We might provide a quit or exit command using a more sophisticated mechanism. But there are always costs (e.g. the violation of the primciple that typing a name shows its repr()).
In the mean time I'm a strong believer in "it ain't broke so don't fix it" here.
+1, with the proviso that we might add a description of how to exit to the interactive rubric (if anyone can work out exactly what that would be under all circumstances). regards Steve -- Steve Holden +44 150 684 7255 +1 800 494 3119 Holden Web LLC www.holdenweb.com PyCon TX 2006 www.python.org/pycon/
Steve Holden wrote:
Except that if you have iPython installed on Windows you *don't* enter the platform EOF any more, you enter CTRL/D (which threw me for a while).
To be fair, that's due to the win32 readline library used by ipython, which modifies console handling. IPython itself doesn't do anything to the EOF conventions, it's pure python code with no direct access to the console. Cheers, f
On Wed, Dec 28, 2005, Guido van Rossum wrote:
In the mean time I'm a strong believer in "it ain't broke so don't fix it" here.
Does that also include my suggestion about improving the startup message? -- Aahz (aahz@pythoncraft.com) <*> http://www.pythoncraft.com/ "Given that C++ has pointers and typecasts, it's really hard to have a serious conversation about type safety with a C++ programmer and keep a straight face. It's kind of like having a guy who juggles chainsaws wearing body armor arguing with a guy who juggles rubber chickens wearing a T-shirt about who's in more danger." --Roy Smith
On 12/29/05, Aahz
On Wed, Dec 28, 2005, Guido van Rossum wrote:
In the mean time I'm a strong believer in "it ain't broke so don't fix it" here.
Does that also include my suggestion about improving the startup message?
Nobody reads that; plus it looks like it's excruciatingly complex to get it right at all times; and getting it wrong is worse that not mentioning it at all. Regarding the meme floating about the arrogance of Pythoneers: bloggers (pretty much by definition) are actually the most arrogant species; don't confuse "bloggers say" with "most people think". -- --Guido van Rossum (home page: http://www.python.org/~guido/)
Guido van Rossum wrote:
Regarding the meme floating about the arrogance of Pythoneers: bloggers (pretty much by definition) are actually the most arrogant species; don't confuse "bloggers say" with "most people think".
Sure, but I'm not only talking about the mindless ranters here; it's also people that back their opinions with at least a few examples -- including exit (and its "it's good for you that you have to learn more than you want at a time when you're not interested" defenders), replies to "what's wrong with Python's floating point type" along the lines of "that you don't under- stand how floating point works", and so on. (fwiw, this meme has also appeared on comp.lang.python quite a few times lately -- and no, I'm not confusing "comp.lang.python" with "most people" either) I do think it's a problem that Python advocates suffer from a "everything's perfect all the time" attitude. "it ain't broke because we say so". I think it's a larger problem that Python developers suffer from the same attitude; in reality, some things are carefully thought out and craftily im- plemented, some things are engineering tradeoffs made at a certain time, and some things are just accidents -- but python-dev will happily defend the current solution with the same energy, no matter what it is. </F>
Aahz wrote:
Does that also include my suggestion about improving the startup message?
when newbies get to the point that they want to quit, chances are that the message have scrolled out of sight. and if they only skim the instructions, they'll probably get confused anyway... e.g. Python version gobbledidok gobbledidok gobbledidok gobbledidok Type "help", "copyright", "credits" or "license" for more information.
help Type help() for interactive help, or help(object) for help about object. help()
Welcome to Python 2.4! This is the online help utility. If this is your first time using Python, you should definitely check out the tutorial on the Internet at http://www.python.org/doc/tut/. Enter the name of any module, keyword, or topic to get help on writing Python programs and using Python modules. To quit this help utility and return to the interpreter, just type "quit". To get a list of available modules, keywords, or topics, type "modules", "keywords", or "topics". Each module also comes with a one-line summary of what it does; to list the modules whose summaries contain a given word such as "spam", type "modules spam". help> quit() no Python documentation found for 'quit()' help> quit You are now leaving help and returning to the Python interpreter. If you want to ask for help on a particular object directly from the interpreter, you can type "help(object)". Executing "help('string')" has the same effect as typing a particular string at the help> prompt.
quit 'Use Ctrl-Z plus Return to exit.' quit() Traceback (most recent call last): File "<stdin>", line 1, in ? TypeError: 'str' object is not callable help(quit) no Python documentation found for 'Use Ctrl-Z plus Return to exit.' help("quit") Help on str object:
quit = class str(basestring)
| str(object) -> string
|
| Return a nice string representation of the object.
| If the argument is a string, the return value is the same object.
|
| Method resolution order:
| str
| basestring
| object
|
| Methods defined here:
|
| __add__(...)
| x.__add__(y) <==> x+y
|
| __contains__(...)
| x.__contains__(y) <==> y in x
|
| __eq__(...)
| x.__eq__(y) <==> x==y
|
| __ge__(...)
| x.__ge__(y) <==> x>=y
|
| __getattribute__(...)
| x.__getattribute__('name') <==> x.name
|
| __getitem__(...)
| x.__getitem__(y) <==> x[y]
|
| __getnewargs__(...)
|
| __getslice__(...)
| x.__getslice__(i, j) <==> x[i:j]
|
| Use of negative indices is not supported.
|
| __gt__(...)
| x.__gt__(y) <==> x>y
|
| __hash__(...)
| x.__hash__() <==> hash(x)
|
| __le__(...)
| x.__le__(y) <==> x<=y
|
| __len__(...)
| x.__len__() <==> len(x)
|
| __lt__(...)
| x.__lt__(y) <==> x
Fredrik Lundh wrote:
Reinhold Birkenfeld wrote:
What is wrong with something like this:
class Quitter: ... def __repr__(self): raise SystemExit ... exit = quit = Quitter()
vars() # oops!
You're right.
class Quitter: ... def __repr__(self): ... n = sys._getframe(1).f_code.co_names ... if n == ("exit",) or n == ("quit",): ... raise SystemExit
better? ;) Reinhold -- Mail address is perfectly valid!
участники (28)
-
"Martin v. Löwis"
-
Aahz
-
Adal Chiriliuc
-
Alan McIntyre
-
Alex Martelli
-
Brett Cannon
-
Christopher Armstrong
-
Fernando Perez
-
François Pinard
-
Fredrik Lundh
-
Gareth McCaughan
-
Gerhard Häring
-
Guido van Rossum
-
Hans Nowak
-
Jeremy Kloth
-
Ka-Ping Yee
-
Michael Hudson
-
Neil Schemenauer
-
Nick Coghlan
-
Reinhold Birkenfeld
-
Ronald Oussoren
-
Samuele Pedroni
-
Scott David Daniels
-
skip@pobox.com
-
Stephen J. Turnbull
-
Steve Holden
-
Tim Peters
-
Walter Dörwald