Dave Kuhlman <[EMAIL PROTECTED]> writes: > > Benny Zilberstein <benny.zilberstein <at> ...> writes: > > > > > > > How hard will it be to add a __eq__ method to the generated > > classes, one that will just compare all the members (also the value of the > > class, if it exists) and return true/false accordingly? > > > > Benny - > > This sounds like a very interesting idea. >
[snip] I apologize for being a bit slow. Here is a proposal that I'm hoping will satisfy Benny's requirements and some additional ones as well. Any suggestions are welcome. Dave ====================== User Defined Methods ====================== Goals ===== - Enable users of generateDS.py to define methods that will automatically be added to selected classes generated by generateDS.py. - Enable user to specify *which* classes a defined method will be added to. - Allow some automatic customization. Examples: - Insert (interpolate) class name into method body. - Provide data possibly needed by user defined methods. Examples: - List of member data items in the class (name, data type, list/non-list). Proposal ======== 1. User creates a file containing a data structure that is a list of method specifications (definitions). Each method specification is an instance class MethodSpec. The constructor for MethodSpec is as follows:: m = MethodSpec(name, prototype, body, class_names) where: - name (a string) is the method name. - source (a string) is the method source code. Indentation will be preserved. This value is inserted in the class body as is. - class_names (a string) is class name or a regular expression that matches class names to which the method will be attached. The re module in the Python standard library is used for this test. Examples:: - "^Carrot$|^Tomato$|^Eggplant$" -- Attach method to classes Carrot, Tomato, and Eggplant. - ".*Truck$|.*Boat$" -- Attach method to all classes whose names names end with "Truck" or "Boat". - ".*" -- Attach method to all classes. See example file below. 2. User runs generateDS.py with command line flag "user-methods", giving the name of the file containing the specifications.. Example:: python generateDS.py --user-methods=myusermethods.py \ -o out.py -s out_subs.py test.xsd 3. User methods can access class variable _member_specs in each generated class that contains a list of member data items (name, data type, list/non-list). Additional notes: - Before inserting the method's source code into the class, the method MethodSpec.get_interpolated_source is called to perform string formatting on the source code. This method may be customized. The default is:: def get_interpolated_source(self, source_dict): source = self.source % (source_dict, ) return source : where source_dict is a dictionary containing the following keys: - "class_name" -- The name of the class into which the method is being inserted. Therefore, you can insert the class name using the following in your method source:: ... %(class_name)s ... Questions ========= 1. Do we need a "prototype" member variable in the MethodSpec class? Would that have a use at some time in the future? 2. Is there other information that the generated classes could provide (in addition to the list of member variable names) for use by user methods? 3. Are there other values that would be useful in the source_dict in addition to class_name? Sample Specification File ========================= Here is an example file containing specification of two user defined methods:: ------------------------------------------------------------------- #!/usr/bin/env python # -*- mode: pymode; coding: latin1; -*- import sys import re # # You must include the following class definition at the top of # your method specification file. # class MethodSpec: def __init__(self, name='', source='', class_names='', class_names_compiled=None): """MethodSpec -- A specification of a method. Member variables: name -- The method name source -- The source code for the method. Must be indented to fit in a class definition. class_names -- A regular expression that must match the class names in which the method is to be inserted. class_names_compiled -- The compiled class names. generateDS.py will do this compile for you. """ self.name = name self.source = source if class_names is None: self.class_names = ('.*', ) else: self.class_names = class_names if class_names_compiled is None: print '(__init__) class_names: %s' % self.class_names self.class_names_compiled = re.compile(self.class_names) else: self.class_names_compiled = class_names_compiled def get_name(self): return self.name def set_name(self, name): self.name = name def get_source(self): return self.source def set_source(self, source): self.source = source def get_class_names(self): return self.class_names def set_class_names(self, class_names): self.class_names = class_names self.class_names_compiled = re.compile(class_names) def get_class_names_compiled(self): return self.class_names_compiled def set_class_names_compiled(self, class_names_compiled): self.class_names_compiled = class_names_compiled def match(self, name): return self.class_names_compiled.search(name) def get_interpolated_source(self, dict): source = self.source % (dict, ) return source def show(self): print 'specification:' print ' name: %s' % (self.name, ) print self.source print ' class_names: %s' % (self.class_names, ) print ' names pat : %s' % (self.class_names_compiled.pattern, ) # # Provide one or more method specification such as the following. # Notes: # - Each generated class contains a class variable "member_specs". # This variable contains a list of tuples. Each tuple # contains: (1) the member variable name, (2) the member data type, # (3) a boolean indicating whether the member contains a list. # # Replace the following method specifications with your own. # # Sample method specification #1 # method1 = MethodSpec(name='method1', source='''\ def method1(self, max): if self.max > max: return False else: return True ''', class_names=r'^Employee$|^[a-zA-Z]*Dependent$', ) # # Sample method specification #2 # method2 = MethodSpec(name='method2', source='''\ def method2(self, max): if self.max > max: return False else: return True ''', class_names=r'^Truck$|^Boat$', ) # # Provide a list of your method specifications with the following # name. # METHOD_SPECS = ( method1, method2, ) def test(): for spec in METHOD_SPECS: spec.show() def main(): test() if __name__ == '__main__': main() ------------------------------------------------------------------- ------------------------------------------------------------------------- This SF.net email is sponsored by DB2 Express Download DB2 Express C - the FREE version of DB2 express and take control of your XML. No limits. Just data. Click to get it now. http://sourceforge.net/powerbar/db2/ _______________________________________________ generateds-users mailing list generateds-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/generateds-users