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

Reply via email to