0

I'm trying to write a python wrapper around the famous Go program GnuGo. My approach (and I'm not sure if this will work) has been to use the subprocess module's Popen to start GnuGo in GTP (go text protocol mode). In the interpreter it looks like this

>>> import subprocess
>>> game = subprocess.Popen(['gnugo', '--mode', 'gtp'])
>>>

The interpreter then hangs, but not completely. If I wait a while, I can get every third keystroke or so to appear on the command line. If I use the shell=True argument, then GnuGo starts in ASCII mode, which looks like this:

    A B C D E F G H J K L M N O P Q R S T
 19 . . . . . . . . . . . . . . . . . . . 19
 18 . . . . . . . . . . . . . . . . . . . 18
 17 . . . . . . . . . . . . . . . . . . . 17
 16 . . . + . . . . . + . . . . . + . . . 16
 15 . . . . . . . . . . . . . . . . . . . 15
 14 . . . . . . . . . . . . . . . . . . . 14
 13 . . . . . . . . . . . . . . . . . . . 13
 12 . . . . . . . . . . . . . . . . . . . 12
 11 . . . . . . . . . . . . . . . . . . . 11
 10 . . . + . . . . . + . . . . . + . . . 10
  9 . . . . . . . . . . . . . . . . . . .  9
  8 . . . . . . . . . . . . . . . . . . .  8
  7 . . . . . . . . . . . . . . . . . . .  7
  6 . . . . . . . . . . . . . . . . . . .  6
  5 . . . . . . . . . . . . . . . . . . .  5
  4 . . . + . . . . . + . . . . . + . . .  4
  3 . . . . . . . . . . . . . . . . . . .  3
  2 . . . . . . . . . . . . . . . . . . .  2
  1 . . . . . . . . . . . . . . . . . . .  1
    A B C D E F G H J K L M N O P Q R S T

black(1):

In GTP mode, GnuGo starts and waits for some input without printing anything to the terminal.

Can anyone shed some light on why this is happening?

castle-bravo
  • 1,389
  • 15
  • 34
  • both gnugo and python are trying to read from the same terminal. you should use `stdin=subprocess.PIPE` and write input to `game.stdin` – mata Mar 12 '15 at 18:38
  • @mata, you solved my problem. Thanks. If you write up an answer, I will accept it. – castle-bravo Mar 12 '15 at 18:44
  • if you want to pass control to `gnugo` until it ends then use `subprocess.check_call(['gnugo', '--mode', 'gtp'])`. If you want to [control `gnugo` child process programmatically then make sure to read `pexpect` faq](http://stackoverflow.com/questions/28616018/multiple-inputs-and-outputs-in-python-subprocess-communicate#comment45544447_28616018) – jfs Mar 12 '15 at 21:16

1 Answers1

1

The problem is that both gnugo and the python interpreter are trying to read from the same terminal.

You need to pass the stdin=subprocess.PIPE argument to the Popen call, then you can write the input for the program to its stdin:

import subprocess
game = subprocess.Popen(['gnugo', '--mode', 'gtp'], stdin=subprocess.PIPE)
game.stdin.write(b"...")
...
mata
  • 67,110
  • 10
  • 163
  • 162