Hacker News new | ask | show | jobs
by dmurray 899 days ago
It should print the first to stdout and the second to stderr. That's completely consistent with how stdout and stderr are usually used.

The regular Python REPL doesn't distinguish between stdout and stderr (perhaps it should!), but you can embed it in things like Jupyter notebooks that do.

1 comments

> It should print the first to stdout and the second to stderr. That's completely consistent with how stdout and stderr are usually used.

That makes sense from a unix tool perspective, but not from a python repl perspective. The repl's behavior is to print the result from the last executed statement. For the exit function, the __repr__ method was overwriten to print the message. That way when you type in "exit", the last value would be exit (the function), and the overwritten __repr__ method causes the help message to be printed. There's no way to have it print to both without adding in some repl specific hacks.

    >>> exit
    Use exit() or Ctrl-Z plus Return to exit
    >>> exit.__repr__()
    'Use exit() or Ctrl-Z plus Return to exit'
How about

    def __repr__(self):
        import warnings
        warnings.warn("Use exit() or Ctrl-Z plus Return to exit")
        return super().repr()
What if you aren't in the REPL? Using __repr__ at all seems like an abstraction violation. It should be the REPL's job to layer on special casing for exit.
The actual behavior is indeed a bit ridiculous:

    >>> print('%r' % str)
    <class 'str'>
    >>> def whatisit(x):
    ...     print('It is %r' % x)
    ... 
    >>> whatisit(min)
    It is <built-in function min>
    >>> whatisit(exit)
    It is Use exit() or Ctrl-D (i.e. EOF) to exit
Excuse me?

IMO if the REPL wanted a friendly feature like this, it should be a generic REPL feature, not a hack applied to the function exit.

Also a bit funny:

    >>> def get_function():
    ...     return exit
    ... 
    >>> a = get_function()
    >>> a
    Use exit() or Ctrl-D (i.e. EOF) to exit
You could use the same pattern as DeprecationWarning. It's suppressed by default and test runners like pytest enable it. A new ReplWarning could be enabled by interactive tools only.

I think I agree though: what you really want to special case is the situation where the user types precisely 'exit<cr>' at a REPL prompt, and that hack needs to exist further up the stack than in the implementation of __repr__.

Thanks for this, it never occurred to me it used __repr__ for the message. I just added this to my .pythonrc

    exit.__class__.__repr__ = lambda _: exit()
    quit = exit
Edit, you also need this in your bashrc:

    export PYTHONSTARTUP=~/.pythonrc