00001
00002
00003
00004
00005
00006 import pydoc, sys, warnings
00007 from ZSI import TC
00008
00009
00010 def _x(): return
00011 try:
00012 _x.func_name = '_y'
00013 except:
00014 raise RuntimeError,\
00015 'use python-2.4 or later, cannot set function names in python "%s"'\
00016 %sys.version
00017 del _x
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045 class pyclass_type(type):
00046 """Stability: Unstable
00047
00048 type for pyclasses used with typecodes. expects the typecode to
00049 be available in the classdict. creates python properties for accessing
00050 and setting the elements specified in the ofwhat list, and factory methods
00051 for constructing the elements.
00052
00053 Known Limitations:
00054 1)Uses XML Schema element names directly to create method names,
00055 using characters in this set will cause Syntax Errors:
00056
00057 (NCNAME)-(letter U digit U "_")
00058
00059 """
00060 def __new__(cls, classname, bases, classdict):
00061 """
00062 """
00063
00064 typecode = classdict.get('typecode')
00065 assert typecode is not None, 'MUST HAVE A TYPECODE.'
00066
00067
00068 if len(bases) > 0:
00069
00070 pass
00071
00072 else:
00073 assert hasattr(typecode, 'ofwhat'), 'typecode has no ofwhat list??'
00074 assert hasattr(typecode, 'attribute_typecode_dict'),\
00075 'typecode has no attribute_typecode_dict??'
00076
00077
00078
00079 if typecode.mixed:
00080 get,set = cls.__create_text_functions_from_what(typecode)
00081
00082 if classdict.has_key(get.__name__):
00083 raise AttributeError,\
00084 'attribute %s previously defined.' %get.__name__
00085
00086 if classdict.has_key(set.__name__):
00087 raise AttributeError,\
00088 'attribute %s previously defined.' %set.__name__
00089
00090 classdict[get.__name__] = get
00091 classdict[set.__name__] = set
00092
00093 for what in typecode.ofwhat:
00094 get,set,new_func = cls.__create_functions_from_what(what)
00095
00096 if classdict.has_key(get.__name__):
00097 raise AttributeError,\
00098 'attribute %s previously defined.' %get.__name__
00099
00100 classdict[get.__name__] = get
00101 if classdict.has_key(set.__name__):
00102 raise AttributeError,\
00103 'attribute %s previously defined.' %set.__name__
00104
00105 classdict[set.__name__] = set
00106 if new_func is not None:
00107 if classdict.has_key(new_func.__name__):
00108 raise AttributeError,\
00109 'attribute %s previously defined.' %new_func.__name__
00110
00111 classdict[new_func.__name__] = new_func
00112
00113 assert not classdict.has_key(what.pname),\
00114 'collision with pname="%s", bail..' %what.pname
00115
00116 pname = what.pname
00117 if pname is None and isinstance(what, TC.AnyElement): pname = 'any'
00118 assert pname is not None, 'Element with no name: %s' %what
00119
00120
00121
00122 pname = pname[0].upper() + pname[1:]
00123 assert not pydoc.Helper.keywords.has_key(pname), 'unexpected keyword: %s' %pname
00124
00125 classdict[pname] =\
00126 property(get, set, None,
00127 'property for element (%s,%s), minOccurs="%s" maxOccurs="%s" nillable="%s"'\
00128 %(what.nspname,what.pname,what.minOccurs,what.maxOccurs,what.nillable)
00129 )
00130
00131
00132
00133
00134
00135 if hasattr(typecode, 'attribute_typecode_dict'):
00136 attribute_typecode_dict = typecode.attribute_typecode_dict or {}
00137 for key,what in attribute_typecode_dict.items():
00138 get,set = cls.__create_attr_functions_from_what(key, what)
00139 if classdict.has_key(get.__name__):
00140 raise AttributeError,\
00141 'attribute %s previously defined.' %get.__name__
00142
00143 if classdict.has_key(set.__name__):
00144 raise AttributeError,\
00145 'attribute %s previously defined.' %set.__name__
00146
00147 classdict[get.__name__] = get
00148 classdict[set.__name__] = set
00149
00150 return type.__new__(cls,classname,bases,classdict)
00151
00152 def __create_functions_from_what(what):
00153 if not callable(what):
00154 def get(self):
00155 return getattr(self, what.aname)
00156
00157 if what.maxOccurs > 1:
00158 def set(self, value):
00159 if not (value is None or hasattr(value, '__iter__')):
00160 raise TypeError, 'expecting an iterable instance'
00161 setattr(self, what.aname, value)
00162 else:
00163 def set(self, value):
00164 setattr(self, what.aname, value)
00165 else:
00166 def get(self):
00167 return getattr(self, what().aname)
00168
00169 if what.maxOccurs > 1:
00170 def set(self, value):
00171 if not (value is None or hasattr(value, '__iter__')):
00172 raise TypeError, 'expecting an iterable instance'
00173 setattr(self, what().aname, value)
00174 else:
00175 def set(self, value):
00176 setattr(self, what().aname, value)
00177
00178
00179
00180
00181
00182 if not callable(what) and getattr(what, 'pyclass', None) is None:
00183 new_func = None
00184 elif (isinstance(what, TC.ComplexType) or
00185 isinstance(what, TC.Array)):
00186
00187 def new_func(self):
00188 '''returns a mutable type
00189 '''
00190 return what.pyclass()
00191
00192 elif not callable(what):
00193
00194 def new_func(self, value):
00195 '''value -- initialize value
00196 returns an immutable type
00197 '''
00198 return what.pyclass(value)
00199
00200 elif (issubclass(what.klass, TC.ComplexType) or
00201 issubclass(what.klass, TC.Array)):
00202
00203 def new_func(self):
00204 '''returns a mutable type or None (if no pyclass).
00205 '''
00206 p = what().pyclass
00207 if p is None: return
00208 return p()
00209
00210 else:
00211
00212 def new_func(self, value=None):
00213 '''if simpleType provide initialization value, else
00214 if complexType value should be left as None.
00215 Parameters:
00216 value -- initialize value or None
00217
00218 returns a mutable instance (value is None)
00219 or an immutable instance or None (if no pyclass)
00220 '''
00221 p = what().pyclass
00222 if p is None: return
00223 if value is None: return p()
00224 return p(value)
00225
00226
00227
00228 if new_func is not None:
00229 new_func.__name__ = 'new_%s' %what.pname
00230 get.func_name = 'get_element_%s' %what.pname
00231 set.func_name = 'set_element_%s' %what.pname
00232 return get,set,new_func
00233 __create_functions_from_what = staticmethod(__create_functions_from_what)
00234
00235 def __create_attr_functions_from_what(key, what):
00236
00237 def get(self):
00238 '''returns attribute value for attribute %s, else None.
00239 ''' %str(key)
00240 return getattr(self, what.attrs_aname, {}).get(key, None)
00241
00242 def set(self, value):
00243 '''set value for attribute %s.
00244 value -- initialize value, immutable type
00245 ''' %str(key)
00246 if not hasattr(self, what.attrs_aname):
00247 setattr(self, what.attrs_aname, {})
00248 getattr(self, what.attrs_aname)[key] = value
00249
00250
00251
00252 if type(key) in (tuple, list):
00253 get.__name__ = 'get_attribute_%s' %key[1]
00254 set.__name__ = 'set_attribute_%s' %key[1]
00255 else:
00256 get.__name__ = 'get_attribute_%s' %key
00257 set.__name__ = 'set_attribute_%s' %key
00258
00259 return get,set
00260 __create_attr_functions_from_what = \
00261 staticmethod(__create_attr_functions_from_what)
00262
00263 def __create_text_functions_from_what(what):
00264
00265 def get(self):
00266 '''returns text content, else None.
00267 '''
00268 return getattr(self, what.mixed_aname, None)
00269
00270 get.im_func = 'get_text'
00271
00272 def set(self, value):
00273 '''set text content.
00274 value -- initialize value, immutable type
00275 '''
00276 setattr(self, what.mixed_aname, value)
00277
00278 get.im_func = 'set_text'
00279
00280 return get,set
00281 __create_text_functions_from_what = \
00282 staticmethod(__create_text_functions_from_what)
00283
00284
00285