Op donderdag 17-06-2010 om 15:16 uur [tijdzone -0700], schreef Stephen Hansen: > On 6/17/10 3:06 PM, Laurent Verweijen wrote: > >> > >> In your other thread you include an actual traceback: > >> > >> Traceback (most recent call last): > >> File "subchronous_test.py", line 5, in <module> > >> send_all(str(p), n) > >> File "/home/Somelauw/asynchronous.py", line 145, in send_all > >> while len(data): > >> TypeError: object of type 'int' has no len() > >> > >> The first argumetn to send_all should be the actual Popen subclass. The > >> second should be a string to send. I think that line really is intended > >> to be: > >> > >> send_all(p, str(n)) # assuming 'n' is say, the number 5. > >> > > > > You are right, I swapped the parameters, but even if I correct it, it > > still gives the second error. > > > > General rule of thumb: its best to never use the word "still" when it > comes to debugging Python and exceptions, unless you are absolutely > certain the exception is precisely the same. > > I don't doubt that you may still get an exception on send_all; but there > is no way you're getting the *same* exception (that specific type error: > attempting to call len() on an integer) if you corrected your arguments. > > You're getting the EOFError, because you're never sending anything to > the subprocess. You're not getting anything from the subprocess because > it never receives anything to send back. And apparently there's an error > on send, which is causing that problem, but that error is...? > My last post, contains the output after I fixed swapping the parameters and everything you said.
I think there is still a problem with output that gets blocked. Couldn't it be just that the output which gets blocked is causing this error? Anyway here is the output again: python subchronous_test.py Traceback (most recent call last): File "increment.py", line 8, in <module> n = int(raw_input(str(n))) + 1 EOFError: EOF when reading a line close failed in file object destructor: Error in sys.excepthook: Original exception was: And here are all 3 files concatenated: # subchronous_test import sys from asynchronous import * p = Popen(["python", "increment.py"], stdin=PIPE, stdout=PIPE, stderr = sys.stderr) for n in [5, 7, 10, 4]: send_all(p, str(n)) print(recv_some(p)) # increment.py import sys, traceback try: n = 0 while True: n = int(raw_input(str(n))) + 1 except: print >>sys.stderr, traceback.format_exc() # asynchronous.py ## {{{ http://code.activestate.com/recipes/440554/ (r10) import os import subprocess import errno import time import sys PIPE = subprocess.PIPE if subprocess.mswindows: from win32file import ReadFile, WriteFile from win32pipe import PeekNamedPipe import msvcrt else: import select import fcntl class Popen(subprocess.Popen): def recv(self, maxsize=None): return self._recv('stdout', maxsize) def recv_err(self, maxsize=None): return self._recv('stderr', maxsize) def send_recv(self, input='', maxsize=None): return self.send(input), self.recv(maxsize), self.recv_err(maxsize) def get_conn_maxsize(self, which, maxsize): if maxsize is None: maxsize = 1024 elif maxsize < 1: maxsize = 1 return getattr(self, which), maxsize def _close(self, which): getattr(self, which).close() setattr(self, which, None) if subprocess.mswindows: def send(self, input): if not self.stdin: return None try: x = msvcrt.get_osfhandle(self.stdin.fileno()) (errCode, written) = WriteFile(x, input) except ValueError: return self._close('stdin') except (subprocess.pywintypes.error, Exception), why: if why[0] in (109, errno.ESHUTDOWN): return self._close('stdin') raise return written def _recv(self, which, maxsize): conn, maxsize = self.get_conn_maxsize(which, maxsize) if conn is None: return None try: x = msvcrt.get_osfhandle(conn.fileno()) (read, nAvail, nMessage) = PeekNamedPipe(x, 0) if maxsize < nAvail: nAvail = maxsize if nAvail > 0: (errCode, read) = ReadFile(x, nAvail, None) except ValueError: return self._close(which) except (subprocess.pywintypes.error, Exception), why: if why[0] in (109, errno.ESHUTDOWN): return self._close(which) raise if self.universal_newlines: read = self._translate_newlines(read) return read else: def send(self, input): if not self.stdin: return None if not select.select([], [self.stdin], [], 0)[1]: return 0 try: written = os.write(self.stdin.fileno(), input) except OSError, why: if why[0] == errno.EPIPE: #broken pipe return self._close('stdin') raise return written def _recv(self, which, maxsize): conn, maxsize = self.get_conn_maxsize(which, maxsize) if conn is None: return None flags = fcntl.fcntl(conn, fcntl.F_GETFL) if not conn.closed: fcntl.fcntl(conn, fcntl.F_SETFL, flags| os.O_NONBLOCK) try: if not select.select([conn], [], [], 0)[0]: return '' r = conn.read(maxsize) if not r: return self._close(which) if self.universal_newlines: r = self._translate_newlines(r) return r finally: if not conn.closed: fcntl.fcntl(conn, fcntl.F_SETFL, flags) message = "Other end disconnected!" def recv_some(p, t=.1, e=1, tr=5, stderr=0): if tr < 1: tr = 1 x = time.time()+t y = [] r = '' pr = p.recv if stderr: pr = p.recv_err while time.time() < x or r: r = pr() if r is None: if e: raise Exception(message) else: break elif r: y.append(r) else: time.sleep(max((x-time.time())/tr, 0)) return ''.join(y) def send_all(p, data): while len(data): sent = p.send(data) if sent is None: raise Exception(message) data = buffer(data, sent) if __name__ == '__main__': if sys.platform == 'win32': shell, commands, tail = ('cmd', ('dir /w', 'echo HELLO WORLD'), '\r\n') else: shell, commands, tail = ('sh', ('ls', 'echo HELLO WORLD'), '\n') a = Popen(shell, stdin=PIPE, stdout=PIPE) print recv_some(a), for cmd in commands: send_all(a, cmd + tail) print recv_some(a), send_all(a, 'exit' + tail) print recv_some(a, e=0) a.wait() ## end of http://code.activestate.com/recipes/440554/ }}} -- http://mail.python.org/mailman/listinfo/python-list