should these be fixed for python 2.4?

Alexander Schmolck a.schmolck at
Fri Oct 1 18:53:51 CEST 2004

Two smallish things that have been bugging me; I'm not sure whether they're
actually broken or not, but anyway here it goes:

1. ``os.system`` (and co): Shouldn't ``os.system``'s signature really be
   ``os.system(cmd, arg1, arg2,...)`` rather than ``os.system(some_string)``?
   Otherwise ``some_string`` almost certainly will be constructed by something
   along the lines of ``os.system('convert %s %s' % (infile, outfile))`` which
   of course is broken (e.g. ``infile = "with space"``). 

   I don't think it's even possible to do the right thing
   platform-independently. I currently use the following hack (any improvement
   suggestions welcome):

   def _fixupCmdStr(cmd, args):
       escape = lambda s: '"%s"' % re.sub(r'\"$!', r'\\\1',s) #FIXME
       return " ".join([cmd] + map(escape, args))

   def system(cmd,*args):
       return os.system(_fixupCmdStr(cmd, args))

   So why not just allow ``os.system('convert',infile, outfile)`` as a
   backward compatible extension that "does the right thing"?

   BTW, if I'm not mistaken it's something that perl got right a long time

    > perl -e "system('touch', 'a b c', 'd')"
    > ll
    total 0
    -rw-r--r--    1 aschmolc phd             0 Oct  1 17:48 a b c
    -rw-r--r--    1 aschmolc phd             0 Oct  1 17:48 d

2. pydoc's handling of overriden methods without docstrings: I really think it
   should show the documentation of the method in the baseclass; the current
   behavior really sucks when working with things like backends.

   Even fixing up subclass docstrings by hand is not trivial::

    In [25]: class Bar(object):
       ....:     def meth(x):
       ....:         pass

    In [26]: Bar.meth.__doc__

    In [27]: Bar.meth.__doc__ = "abc"
    AttributeError                            Traceback (most recent call last)


    AttributeError: 'instancemethod' object attribute '__doc__' is read-only

   Going via dict will work (but that of course fails for the general case)::

    In [28]: Bar.__dict__['meth'].__doc__ = "abc"



P.S. speaking of running external processes -- I'm also unaware of a good,
platform-independent (or even just unix) way to run a process that possibly
accepts input, but will just continue on EOF from stdin and getting back
stdout and stderr (if supported) as strings and the exit status.

I currently use this to run e.g. latex, but it doesn't seem to work absolutely
reliably and is unix only. I'm pretty sure there must be a better way.

def readProcess(cmd, *args):
    r"""Like `os.popen3`, but returns 2 strings (stdin, stdout) and the exit
    code (unlike popen2, exit is 0 if no problems occured (for some bizzarre
    reason popen2 returns None... <sigh>). FIXME: only works for UNIX!"""

    cmdStr = _fixupCmdStr(cmd, args)
    popen = popen2.Popen3(cmdStr, capturestderr=True)
    popen.tochild.close() # XXX make sure we're not waiting forever
    exit = popen.wait()
    out, err = map(slurpIn, [popen.fromchild, popen.childerr])
    return out or "", err or "", exit

def slurpIn(file, binary=False):
    if isString(file):
        file = open(file, ("r", "rb")[bool(binary)])
        result =
        return result

More information about the Python-list mailing list