On Wed, 19 Jan 2005, Marilyn Davis wrote:
> class Exim: > def __init__(self): > self.fdin = None > self.err_flush = [] > self.stdout, self.stdin, self.stderr = popen2.popen3('%s -t' % > MAILER) > self.fdin = self.stdin.fileno() > self.fdout = self.stdout.fileno() > self.fderr = self.stderr.fileno() Hi Marilyn, You probably don't need to explicitly use the file descriptors here. I see that you're using them because of the use of select() later on: ### sel = select.select(self.outlist, [], [], 1) ### but, although select.select() can use file descriptor numbers, it can also take file-like objects. See: http://www.python.org/doc/lib/module-select.html So you can simplify this code to: ### sel = select.select([self.stdout, self.stderr], [], [], 1) ### The upside to this is that you don't need to use the low-level os.read() or os.close() functions at all. I suspect that some silliness with file descriptors is causing your bug, as the following: ### >>> os.close(42) Traceback (most recent call last): File "<stdin>", line 1, in ? OSError: [Errno 9] Bad file descriptor ### shows that if we feed os.close() a nonsense file descriptor, it'll throw out a error message that you may be familiar with. The error can happen if we close the same file descriptor twice: ### >>> myin, myout, myerr = popen2.popen3('cat') >>> os.close(myin.fileno()) >>> os.close(myin.fileno()) Traceback (most recent call last): File "<stdin>", line 1, in ? OSError: [Errno 9] Bad file descriptor ### Here is another particular case that might really be relevant: ### >>> myin, myout, myerr = popen2.popen3('cat') >>> os.close(myin.fileno()) >>> myin.close() Traceback (most recent call last): File "<stdin>", line 1, in ? IOError: [Errno 9] Bad file descriptor ### We're getting an IOError here for exactly the same reasons: the high-level 'myin' object has no knowledge that its underlying file descriptor was closed. This is exactly why we've been saying not to mix file-descriptor stuff with high-level file-like object manipulation: it breaks the assumptions that the API expects to see. > However, all that said, I do dimly remember that poplib perhaps had some > extra processing that maybe is not needed -- but I could be wrong. Ok; I'll try to remember to look into poplib later and see if there's anything silly in there. > if __name__ == '__main__': > msg = '''To: %s > > xx''' % TO_WHOM > > p = Exim() > p.write(msg) > del p Instead of using __del__ implicitely, drop the __del__ method and try calling Exim.close_up() explicitely: ### p = Exim() p.write(msg) p.close_up() ### > Are you well yet? A lot of sick people around these days! Feeling better. _______________________________________________ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor