Raising exception on STDIN read

Michael Goerz newsgroup898sfie at 8439.e4ward.com
Wed Feb 27 15:07:49 EST 2008


Ian Clark wrote, on 02/27/2008 12:06 PM:
> On 2008-02-27, Michael Goerz <newsgroup898sfie at 8439.e4ward.com> wrote:
>> I would like to raise an exception any time a subprocess tries to read 
>> from STDIN:
>> latexprocess = subprocess.Popen( \
>>          'pdflatex' + " " \
>>           + 'test' + " 2>&1", \
>>          shell=True, \
>>          cwd=os.getcwd(), \
>>          env=os.environ, \
>>          stdin=StdinCatcher() # any ideas here?
>>      )
> How about with a file-like object? I haven't tested this with subprocess
> so you might want to read the manual on files if it doesn't work[1].
> 
> 	import sys 
> 	class ErrorFile(object):
> 		def _error(self, *args, **kwargs):
> 			raise AssertionError("Illegal Access")
> 
> 		def _noop(self, *args, **kwargs):
> 			pass
> 
> 		close = flush = seek = tell = _noop
> 		next = read = readline = readlines = xreadlines = tuncate = _error
> 		truncate = write = writelines = _error
> 
> 	sys.stdin = ErrorFile()
> 	print raw_input("? ")

I was already trying to do that sort of thing. While it works in your 
example code, for some reason it doesn't work in the subprocess. The 
first problem is that ErrorFile needs a fileno() methode (otherwise I 
get AttributeError: 'ErrorFile' object has no attribute 'fileno'). So, 
when I add
     def fileno(self):
         return 0
to ErrorFile, it runs, but it still doesn't work. The exception is never 
raised.

My specific example was running pdflatex on a file test.tex which looks 
like this:

     \documentclass[a4paper,10pt]{article}
     \usepackage{bogus}
     \begin{document}
       test
     \end{document}

When compiled, this should fail because of a missing 'bogus' package. 
The compiler will prompt for a replacement on STDIN, which I want to 
catch with an exception.

So, when I run my python script

     #!/usr/bin/python
     import subprocess
     import os
     import sys
     class ErrorFile(object):
         def _error(self, *args, **kwargs):
             raise AssertionError("Illegal Access")
         def _noop(self, *args, **kwargs):
             pass
         def fileno(self):
             return 0
         close = flush = seek = tell = _noop
         next = read = readline = readlines \
              = xreadlines = tuncate = _error
         truncate = write = writelines = _error
     latexprocess = subprocess.Popen( \
             'pdflatex' + " " \
              + 'test' + " 2>&1", \
             shell=True, \
             cwd=os.getcwd(), \
             env=os.environ, \
             stdin=ErrorFile()
         )

the  compiler notices that it doesn't get any input:
     Enter file name:
     ! Emergency stop.
     <read *>
but no exception is raised, and for some reason I have to press Enter to 
finish.

Michael





More information about the Python-list mailing list