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