New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

gevent.monkey.patch_sys breaks the arrow keys #274

Closed
bikeshedder opened this Issue May 15, 2013 · 3 comments

Comments

Projects
None yet
3 participants
@bikeshedder

bikeshedder commented May 15, 2013

I am using gevent in mushroom (https://bitbucket.org/terreon/mushroom) and would like to provide an interactive console using the Python cmd module. Using the new gevent.moneky.patch_sys breaks the arrow keys.


[Update] Shorter example showing the behavior:

from gevent import monkey
monkey.patch_sys()
input()

Example program making use of cli. Just start the application and try pressing theup- and down-arrow keys.

#!/usr/bin/env python2

import cmd

from gevent import monkey


class Cmd(cmd.Cmd):

    def do_exit(self, args):
        '''Exit the console.'''
        return 'exit'

    def do_EOF(self, args):
        '''You can exit the console by typing Ctrl+D.'''
        return 'EOF'

    def do_ping(self, args):
        '''Return "pong".'''
        print 'pong'


if __name__ == '__main__':
    monkey.patch_sys()
    cmd = Cmd()
    cmd.cmdloop()

Expected behaviour: It should be possible to pick a previous command from the history by using the arrow keys.
Actual behavior: It outputs ^[[A and ^[[B.

@Ivoz

This comment has been minimized.

Show comment
Hide comment
@Ivoz

Ivoz May 16, 2013

Contributor

I'm not on linux to try at the moment, but have you tried patching sys before importing cmd? i.e

from gevent import monkey
monkey.patch_sys()
import cmd
Contributor

Ivoz commented May 16, 2013

I'm not on linux to try at the moment, but have you tried patching sys before importing cmd? i.e

from gevent import monkey
monkey.patch_sys()
import cmd
@bikeshedder

This comment has been minimized.

Show comment
Hide comment
@bikeshedder

bikeshedder May 16, 2013

@Ivoz, changing the import order does not change the behavior. As far as I can tell the escape sequences generated by the arrow keys are not properly handled and therefore they are printed on the screen instead of being handled by cmd.

I just found a better example which does not require cmd at all. The builtin input function is affected as well:

from gevent import monkey
monkey.patch_sys()
input()

bikeshedder commented May 16, 2013

@Ivoz, changing the import order does not change the behavior. As far as I can tell the escape sequences generated by the arrow keys are not properly handled and therefore they are printed on the screen instead of being handled by cmd.

I just found a better example which does not require cmd at all. The builtin input function is affected as well:

from gevent import monkey
monkey.patch_sys()
input()
@jamadden

This comment has been minimized.

Show comment
Hide comment
@jamadden

jamadden Jul 7, 2015

Member

Unfortunately, the arrow key behaviour (and in general, integration with the readline module) is hardcoded in the C interpreter source code to only work with genuine file objects. Any type of wrapper around them throws off the use of the readline module, devolving instead into a simple call to the readline method.

Arrow keys and the like are kept behind this gate in the raw_input builtin function:

    if (PyFile_AsFile(fin) && PyFile_AsFile(fout)
        && isatty(fileno(PyFile_AsFile(fin)))
        && isatty(fileno(PyFile_AsFile(fout)))) {
       ...
       PyOS_Readline(PyFile_AsFile(fin), PyFile_AsFile(fout),
                          prompt);
       ...
    }
    else { // effectively
       return PyFile_GetLine(fin, -1); // fin.readline()
    }

All the magic happens in PyOS_Readline.

I don't see what gevent can do about this other than attempting to replace builtin functions, and that doesn't sound like a good idea to me, especially given that the functionality of patch_sys is removed altogether under Python 3 because of more low-level interpreter changes.

For now, I've documented this in patch_sys---consider it not-recommended. I would be willing to review a PR though, if somebody can come up with a patch that works in all cases and has no risk :)

Closing this to help with the triage for gevent 1.1. Please feel free to open another PR or comment on this one if you see another way.

Member

jamadden commented Jul 7, 2015

Unfortunately, the arrow key behaviour (and in general, integration with the readline module) is hardcoded in the C interpreter source code to only work with genuine file objects. Any type of wrapper around them throws off the use of the readline module, devolving instead into a simple call to the readline method.

Arrow keys and the like are kept behind this gate in the raw_input builtin function:

    if (PyFile_AsFile(fin) && PyFile_AsFile(fout)
        && isatty(fileno(PyFile_AsFile(fin)))
        && isatty(fileno(PyFile_AsFile(fout)))) {
       ...
       PyOS_Readline(PyFile_AsFile(fin), PyFile_AsFile(fout),
                          prompt);
       ...
    }
    else { // effectively
       return PyFile_GetLine(fin, -1); // fin.readline()
    }

All the magic happens in PyOS_Readline.

I don't see what gevent can do about this other than attempting to replace builtin functions, and that doesn't sound like a good idea to me, especially given that the functionality of patch_sys is removed altogether under Python 3 because of more low-level interpreter changes.

For now, I've documented this in patch_sys---consider it not-recommended. I would be willing to review a PR though, if somebody can come up with a patch that works in all cases and has no risk :)

Closing this to help with the triage for gevent 1.1. Please feel free to open another PR or comment on this one if you see another way.

@jamadden jamadden closed this Jul 7, 2015

@jamadden jamadden added the cantfix label Jul 7, 2015

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment