def process_complex_type(self, c): def process_type(tn, name, wrapper=None, element=None, attribute=None): if wrapper is None: wrapper = lambda x: x else: assert issubclass(wrapper, XmlModifier), wrapper t = self.get_type(tn) key = (c.name, name) if t is None: self.pending_types[key] = c self.debug2("not found: %r(%s)", key, tn) return if key in self.pending_types: del self.pending_types[key] assert name is not None, (key, e) kwargs = {} if element is not None: if e.min_occurs != "0": # spyne default kwargs['min_occurs'] = int(e.min_occurs) if e.max_occurs == "unbounded": kwargs['max_occurs'] = e.max_occurs elif e.max_occurs != "1": kwargs['max_occurs'] = int(e.max_occurs) if e.nillable != True: # spyne default kwargs['nillable'] = e.nillable if e.default is not None: kwargs['default'] = _prot.from_string(t, e.default) if len(kwargs) > 0: t = t.customize(**kwargs) if attribute is not None: if attribute.default is not None: kwargs['default'] = _prot.from_string(t, a.default) if len(kwargs) > 0: t = t.customize(**kwargs) ti.append((name, wrapper(t))) self.debug2(" found: %r(%s), c: %r", key, tn, kwargs) def process_element(e): if e.ref is not None: tn = e.ref name = e.ref.split(":", 1)[-1] elif e.name is not None: tn = e.type name = e.name if tn is None: # According to http://www.w3.org/TR/2004/REC-xmlschema-1-20041028/structures.html#element-element # this means this element is now considered to be a # http://www.w3.org/TR/2004/REC-xmlschema-1-20041028/structures.html#ur-type-itself self.debug2(" skipped: %s ur-type", e.name) return else: raise Exception("dunno") process_type(tn, name, element=e) ti = [] base = ComplexModelBase if c.name in self.retval[self.tns].types: self.debug1("modifying existing %r", c.name) else: self.debug1("adding complex type: %s", c.name) if c.sequence is not None: if c.sequence.elements is not None: for e in c.sequence.elements: process_element(e) if c.sequence.choices is not None: for ch in c.sequence.choices: if ch.elements is not None: for e in ch.elements: process_element(e) if c.choice is not None: if c.choice.elements is not None: for e in c.choice.elements: process_element(e) if c.attributes is not None: for a in c.attributes: if a.name is None: continue if a.type is None: continue process_type(a.type, a.name, XmlAttribute, attribute=a) if c.simple_content is not None: sc = c.simple_content ext = sc.extension restr = sc.restriction if ext is not None: base_name = ext.base b = self.get_type(ext.base) if ext.attributes is not None: for a in ext.attributes: ti.append(self.process_attribute(a)) elif restr is not None: base_name = restr.base b = self.get_type(restr.base) if restr.attributes is not None: for a in restr.attributes: ti.append(self.process_attribute(a)) else: raise Exception("Invalid simpleContent tag: %r", sc) if issubclass(b, ComplexModelBase): base = b else: process_type(base_name, "_data", XmlData) if c.name in self.retval[self.tns].types: r = self.retval[self.tns].types[c.name] r._type_info.update(ti) else: cls_dict = odict({ '__type_name__': c.name, '__namespace__': self.tns, '_type_info': ti, }) if self.repr is not None: cls_dict['__repr__'] = self.repr r = ComplexModelMeta(str(c.name), (base, ), cls_dict) self.retval[self.tns].types[c.name] = r return r
def process_complex_type(self, c): def process_type(tn, name, wrapper=lambda x: x, element=None, attribute=None): t = self.get_type(tn) key = (c.name, name) if t is None: self.pending_types[key] = c self.debug2("not found: %r(%s)", key, tn) return if key in self.pending_types: del self.pending_types[key] assert name is not None, (key, e) kwargs = {} if element is not None: if e.min_occurs != "0": # spyne default kwargs['min_occurs'] = int(e.min_occurs) if e.max_occurs == "unbounded": kwargs['max_occurs'] = e.max_occurs elif e.max_occurs != "1": kwargs['max_occurs'] = int(e.max_occurs) if e.nillable != True: # spyne default kwargs['nillable'] = e.nillable if e.default is not None: kwargs['default'] = _prot.from_string(t, e.default) if len(kwargs) > 0: t = t.customize(**kwargs) if attribute is not None: if attribute.default is not None: kwargs['default'] = _prot.from_string(t, a.default) if len(kwargs) > 0: t = t.customize(**kwargs) ti.append((name, wrapper(t))) self.debug2(" found: %r(%s), c: %r", key, tn, kwargs) def process_element(e): if e.ref is not None: tn = e.ref name = e.ref.split(":", 1)[-1] elif e.name is not None: tn = e.type name = e.name else: raise Exception("dunno") process_type(tn, name, element=e) class L(list): def append(self, a): k, v = a assert isinstance(k, six.string_types), k super(L, self).append(a) ti = L() base = ComplexModelBase if c.name in self.retval[self.tns].types: self.debug1("modifying existing %r", c.name) else: self.debug1("adding complex type: %s", c.name) if c.sequence is not None: if c.sequence.elements is not None: for e in c.sequence.elements: process_element(e) if c.sequence.choices is not None: for ch in c.sequence.choices: if ch.elements is not None: for e in ch.elements: process_element(e) if c.choice is not None: if c.choice.elements is not None: for e in c.choice.elements: process_element(e) if c.attributes is not None: for a in c.attributes: if a.name is None: continue if a.type is None: continue process_type(a.type, a.name, XmlAttribute, attribute=a) if c.simple_content is not None: ext = c.simple_content.extension base_name = None if ext is not None: base_name = ext.base b = self.get_type(ext.base) if ext.attributes is not None: for a in ext.attributes: ti.append(self.process_attribute(a)) restr = c.simple_content.restriction if restr is not None: base_name = restr.base b = self.get_type(restr.base) if restr.attributes is not None: for a in restr.attributes: ti.append(self.process_attribute(a)) if issubclass(b, ComplexModelBase): base = b else: process_type(base_name, "_data", XmlData) if c.name in self.retval[self.tns].types: self.retval[self.tns].types[c.name]._type_info.update(ti) else: cls_dict = odict({ '__type_name__': c.name, '__namespace__': self.tns, '_type_info': ti, }) if self.repr is not None: cls_dict['__repr__'] = self.repr r = ComplexModelMeta(str(c.name), (base, ), cls_dict) self.retval[self.tns].types[c.name] = r