[Python-Dev] Re: Proposal: get rid of compilerlike.py
Gordon McMillan
gmcm@hypernet.com
Sat, 1 Sep 2001 19:53:20 -0400
[Eric]
> Right...one of which completely misses the point by suggesting
> that this is a filter framework,
True. It's a tad more general than just a filter. How about
UnixishTextfileTransformFramework
since that captures it's most distinguishing feature (the fact
that it follows a popular unix convention). Also hints that it
would chew the hell out of a binary file on Windows.
[Guido]
> > - A framework like this should be structured as a class or set
> > of
> > related classes, not a bunch of functions with function
> > arguments.
[Eric]
> Yes, I thought of this. There's a reason I didn't do it that
> way. Method override would work just fine as a way to pass in the
> filename transformer, but not the data transformer.
>
> The problem is this: the driver or "go do it" method of your
> hypothetical class (the one you'd pass sys.argv[1:]) can't know
> which overriden method to call in advance, because which one is
> right would depend on the argument signature of the hook function
Who cares about signatures? Try the attached.
- Gordon
-------------- Enclosure number 1 ----------------
import sys, os
class UnixishFileTransformer:
def transformFile(self, infp, outfp):
raise NotImplementedError
def transformData(self, data):
raise NotImplementedError
def transformLine(self, line):
raise NotImplementedError
def transformFilename(self, nm):
raise NotImplementedError
def run(self, args):
if not args:
self.fnm = "stdin"
self._do_one(sys.stdin, sys.stdout)
else:
for fnm in args:
if fnm == '-':
infp = sys.stdin
self.fnm = "stdin"
else:
infp = open(fnm, 'r')
self.fnm = fnm
tempfile = file + ".~%s-%d~" % (name, os.getpid())
outfp = open(tempfile, "w")
try:
self._do_one(infp, outfp)
except:
os.remove(tempfile)
raise
infp.close()
outfp.close()
try:
newnm = self.transformFilename(self.fnm)
except NotImplementedError:
if filecmp.cmp(file, tempfile):
continue
newnm = self.fnm
os.remove(self.fnm)
os.rename(tempfile, newnm)
def _do_one(self, infp, outfp):
try:
self.transformFile(infp, outfp)
except NotImplementedError:
try:
while 1:
line = infp.readline()
if not line:
break
outfp.write(self.transformLine(line))
except NotImplementedError:
try:
lump = line + infp.read()
outfp.write(self.transformData(lump))
except NotImplementedError:
raise NotImplementedError, "no implementation of a transform method provided"
if __name__ == '__main__':
import getopt
class T1(UnixishFileTransformer):
def transformFilename(self, fnm):
return fnm+'.out'
def transformFile(self, infp, outfp):
while 1:
line = infp.readline()
if not line:
break
if line == "\n":
outfp.write("------------------------------------------\n")
outfp.write(line)
class T2(UnixishFileTransformer):
def transformFilename(self, fnm):
return fnm+'.out2'
def transformLine(self, line):
return "<" + line[:-1] + ">\n"
class T3(UnixishFileTransformer):
def transformFilename(self, fnm):
return fnm+'.foo'
def transformData(self, data):
lines = data.split("\n")
lines.reverse()
return "\n".join(lines)
(options, arguments) = getopt.getopt(sys.argv[1:], "fls")
for (switch, val) in options:
if switch == '-f':
t = T1()
t.run(arguments)
elif switch == '-l':
t = T2()
t.run(arguments)
elif switch == '-s':
t = T3()
t.run(arguments)
else:
print "Unknown option."