eliben / code-for-blog

Code samples from my blog
The Unlicense
1.6k stars 747 forks source link

Why python clears the cache of external programs? #69

Closed HackYardo closed 3 months ago

HackYardo commented 3 months ago

Hello there, your blog about python subprocess 2017 is pretty helpful! But here is a special use case:

I use python to interact with gnugo, a GoTextProtocl engine, to play the game of Go. In short, the gtp protocol follows:

In shell, it works fine:

$ gnugo --mode gtp --boardsize 2
play black a1
= 

genmove white
= B2

showboard
= 
   A B
 2 . O 2     WHITE (O) has captured 0 stones
 1 X . 1     BLACK (X) has captured 0 stones
   A B

quit
= 

The "X" and "O" stand for the pieces of player black and player white.

In python, it works weird?

$ path/to/venv/python gotextprotocol.py
play black a1
= 

genmove white
= A1

showboard
= 
   A B
 2 . . 2     WHITE (O) has captured 0 stones
 1 . . 1     BLACK (X) has captured 0 stones
   A B

quit
= 

Two players move at the same point "A1" and the board is empty. Why python clears the cache of external programes?

The gotextprotol.py:

import subprocess as sp

def bot_cmd():
    cmd = ["gnugo", "--mode", "gtp", "--boardsize", "2"]
    return cmd

def bot_run(cmd):
    proc = sp.Popen(cmd, stdin=sp.PIPE, stdout=sp.PIPE, stderr=sp.STDOUT, text=True, bufsize=1)
    return proc

def bot_end(proc):
    proc.wait()

def query(proc, word):
    word = word + '\n'
    proc.stdin.write(word)
    #proc.stdin.flush()

def reply(proc):
    paragraph = ""
    while True:
        sentence = proc.stdout.readline()
        if sentence == '\n':
            break
        paragraph = paragraph + sentence
    return paragraph

def gtp():  # GoTextProtocol
    while True:
        proc = bot_run(bot_cmd())
        word = input()
        query(proc, word)
        print(reply(proc))
        if word == "quit":
            bot_end(proc)
            break

gtp()
eliben commented 3 months ago

In your gtp function, should you really be launching a new bot_run every loop iteration?

HackYardo commented 3 months ago

Absolutely not. It shouldn't launch a new gtp session every loop iteration. Thank you so much, it blocks me for a week.