A
Alexander Schmolck
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
ago.
-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)
/auto/home/black4/aschmolc/PhD/Bayes/<console>
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"
cheers,
'as
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)])
try:
result = file.read()
return result
finally:
file.close()
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
ago.
total 0> perl -e "system('touch', 'a b c', 'd')"
> ll
-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)
/auto/home/black4/aschmolc/PhD/Bayes/<console>
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"
cheers,
'as
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)])
try:
result = file.read()
return result
finally:
file.close()