Package Bio :: Package EUtils :: Module sourcegen
[hide private]
[frames] | no frames]

Source Code for Module Bio.EUtils.sourcegen

  1  #!/usr/bin/env python 
  2   
  3  """ 
  4  This module can be used to generate python source code. It has an interface 
  5  similar to the "new" module. 
  6   
  7  """ 
  8   
  9  import sys, os 
 10  import string 
 11   
 12  BANGLINE = "#!/usr/bin/env python\n" 
 13   
14 -def _tuplestr(tup):
15 return string.join(map(str, tup), ", ")
16 17 # These functions resembled the "new" module interface, but with different 18 # names. This is the function interface. There are also generator object 19 # interfaces below. 20
21 -def genClass(klassname, parents, attribs=None, doc=None, methods=None):
22 """genClass(name, parents, [attribs, [doc, [methods]]]) 23 Return a string of Python source code defineing a class object. 24 Where: 25 name = class name (string) 26 parents = tuple of parent class objects or strings. 27 attribs = class-global attributes to define, contained in a dictionary. 28 doc = a doc string (optional) 29 methods = list of methods strings. 30 """ 31 s = [] 32 if parents: 33 s.append( "class %s(%s):" % (klassname, _tuplestr(parents)) ) 34 else: 35 s.append( "class %s:" % (klassname) ) 36 if doc: 37 s.append('\t"""%s"""' % doc) 38 if attribs: 39 for key, val in attribs.items(): 40 s.append( "\t%s = %r" % (key, val) ) 41 if methods is not None: 42 s.extend(map(str, list(methods))) 43 if len(s) == 1: 44 s.append("\tpass") 45 s.append("\n") 46 return string.join(s, "\n")
47
48 -def genFunc(funcname, params, body=None, globals=None, doc=None):
49 s = [] 50 s.append( "def %s(%s):" % (funcname, _tuplestr(params)) ) 51 if doc: 52 s.append('\t"""%s"""' % doc) 53 if globals is not None: 54 s.append("\tglobal %s" % _tuplestr(globals)) 55 if body is None: 56 s.append("\tpass") 57 else: 58 s.append(body) 59 s.append("\n") 60 return string.join(s, "\n")
61
62 -def genMethod(funcname, params, body=None, globals=None, doc=None):
63 s = [] 64 s.append( "def %s(self, %s):" % (funcname, _tuplestr(params)) ) 65 if doc: 66 s.append('\t"""%s"""' % doc) 67 if globals is not None: 68 s.append("\tglobal %s" % _tuplestr(globals)) 69 if body is None: 70 s.append("\tpass") 71 elif type(body) is str: 72 s.extend( map(lambda l: "\t%s"%l, string.split(body, "\n")) ) 73 elif type(body) is list or type(body) is tuple: 74 s.extend( map(lambda l: "\t%s"%l, body) ) 75 else: 76 raise TypeError, "invalid type for body text" 77 s.append("\n") 78 # insert a tab in the front of each line and return lines joined with newlines. 79 return string.join(map(lambda l: "\t%s"%l, s), "\n")
80
81 -def genComment(text):
82 lines = text.split("\n") 83 lines = map(lambda l: "# %s" % l, lines) 84 return string.join(lines, "\n")
85
86 -def genImport(module, obj=None, indent=0):
87 if type(module) is type(sys): # a module type 88 module = module.__name__ 89 if obj: 90 if type(obj) is tuple or type(obj) is list: 91 obj = _tuplestr(obj) 92 return "%sfrom %s import %s\n" % ("\t"*indent, module, obj) 93 else: 94 return "%simport %s\n" % ("\t"*indent, module)
95 96 97 # a Python source producer object
98 -class SourceGen:
99 """SourceGen(outfile, [bangline]) 100 An instance of this SourceGen class is a factory for generating python 101 source code, by writing to a file object. 102 103 """
104 - def __init__(self, outfile, bangline=None):
105 self.outfile = outfile 106 bangline = bangline or BANGLINE 107 self.outfile.write(bangline)
108
109 - def genClass(self, klassname, parents=None, attribs=None, doc=None, methods=None):
110 self.outfile.write( genClass(klassname, parents, attribs, doc, methods) )
111
112 - def genFunc(self, funcname, params, attribs=None, doc=None):
113 self.outfile.write( genFunc(funcname, params, attribs, doc) )
114
115 - def genMethod(self, funcname, params, body=None, globals=None, doc=None):
116 self.outfile.write( genMethod(funcname, params, body, globals, doc) )
117
118 - def genComment(self, text):
119 self.outfile.write( genComment(text) )
120
121 - def genImport(self, module, obj=None):
122 self.outfile.write( genImport(module, obj) )
123
124 - def genBlank(self):
125 self.outfile.write("\n")
126
127 - def write(self, obj):
128 self.outfile.write( str(obj) )
129
130 - def writeln(self, obj):
131 self.write(obj) 132 self.write("\n")
133 134 135 # factory functions. 136 # Returns a source generator ready to write to a file (or filename).
137 -def get_generator(outfile):
138 if type(outfile) is str: 139 outfile = open(outfile, "w") 140 return SourceGen(outfile)
141 142 # return a SourceFile object.
143 -def get_sourcefile(outfile=None, bangline=None):
144 if type(outfile) is str: 145 outfile = open(outfile, "w") 146 return SourceFile(outfile, bangline)
147 148 149 # object holder interface
150 -class FunctionHolder:
151 - def __init__(self, funcname, params=None, attributes=None, doc=None):
152 self.name = funcname 153 self.params = params or () 154 self.attributes = attributes or {} 155 self.doc = doc
156 - def __str__(self):
157 return genFunc(self.name, self.params, self.attributes, self.doc)
158 - def add_attribute(self, name, value):
159 self.attributes[name] = value
160 set_attribute = add_attribute
161 - def get_attribute(self, name):
162 return self.attributes[name]
163 - def del_attribute(self, name):
164 del self.attributes[name]
165 166
167 -class MethodHolder:
168 - def __init__(self, funcname, params=None, body=None, globals=None, doc=None):
169 self.name = funcname 170 self.params = params or () 171 self.body = body 172 self.globals = globals 173 self.doc = doc
174
175 - def __str__(self):
176 return genMethod(self.name, self.params, self.body, self.globals, self.doc)
177 178
179 -class ClassHolder:
180 - def __init__(self, klassname, parents=None, attributes=None, doc=None, methods=None):
181 self.classname = klassname 182 self.parents = parents or () 183 self.attributes = attributes or {} 184 self.methods = methods or [] 185 self.doc = doc
186 - def __str__(self):
187 return genClass(self.classname, self.parents, self.attributes, self.doc, self.methods)
188
189 - def add_method(self, funcname, params, body=None, globals=None, doc=None):
190 mh = MethodHolder(funcname, params, body, globals, doc) 191 self.methods.append(mh) 192 return mh
193
194 - def add_attribute(self, name, value):
195 self.attributes[name] = value
196 set_attribute = add_attribute
197 - def get_attribute(self, name):
198 return self.attributes[name]
199 - def del_attribute(self, name):
200 del self.attributes[name]
201 202 203 # this is only good for small file generation
204 -class SourceFile:
205 - def __init__(self, fo=None, bangline=None):
206 print "Writing to", fo 207 self.fo = fo 208 self.elements = [] 209 self.docstring = None 210 self.bangline = bangline or BANGLINE
211 - def __str__(self):
212 s = [self.bangline] 213 if self.docstring: 214 s.append('"""\n%s\n"""\n\n' % (self.docstring)) 215 s.extend(map(str, self.elements)) 216 return "\n".join(s)
217
218 - def add_doc(self, docstring):
219 self.docstring = docstring
220 - def add_comment(self, text):
222 - def add_import(self, module, obj=None):
223 self.elements.append(genImport(module, obj))
224 - def add_blank(self):
225 self.elements.append("\n")
226
227 - def add_function(self, funcname, params, attribs=None, doc=None):
228 fh = FunctionHolder(funcname, params, attribs, doc) 229 self.elements.append(fh) 230 return fh
231
232 - def add_class(self, klassname, parents, attributes=None, doc=None, methods=None):
233 ch = ClassHolder(klassname, parents, attributes, doc, methods) 234 self.elements.append(ch) 235 return ch
236
237 - def append(self, holder):
238 self.elements.append(holder)
239
240 - def write(self, fo=None):
241 fo = fo or self.fo 242 fo.write(str(self))
243 - def writefile(self, filename=None):
244 filename = filename or self.filename 245 if filename: 246 fo = open(filename, "w") 247 self.write(fo) 248 else: 249 raise ValueError, "SourceFile: no filename given to write to!"
250 251 252 253 if __name__ == "__main__":
254 - class SUBCLASS:
255 pass
256 print "generated classes" 257 print "-----------------" 258 print genComment(__doc__) 259 print genClass("test1", (), {}) 260 print genClass("test2", ("sub1",), {}) 261 print genClass("test3", ("sub1","sub2"), {}) 262 print genClass("test4", (SUBCLASS,), {}) 263 print genClass("test5", (), {"attr1": 1}) 264 print genClass("test6", (), {}, "One docstring") 265 print genClass("test7", (), {"attr1": 1}, "another docstring") 266 267 print "Holder classes" 268 print "--------------" 269 print genImport(sys.modules[__name__]) 270 print genImport(sys) 271 print genImport(sys, "open") 272 ch = ClassHolder("holdclass", ("sub1",)) 273 print ch 274 print "--------------" 275 ch.add_method("holdmethod1", ("param1",)) 276 print ch 277 print "--------------" 278 ch.add_method("holdmethod2", ("hm2p1",), "print 'body code'", doc="Some docstring") 279 print ch 280 print "--------------" 281 ch.doc = "Documentation for holdclass." 282 print ch 283 print "--------------" 284 sf = SourceFile() 285 sf.add_doc("Testing the generator.") 286 sf.add_import(sys) 287 sf.append(ch) 288 sf.write(sys.stdout) 289