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
[email protected]
https://lists.sourceforge.net/lists/listinfo/generateds-users