debian-zeep/src/zeep/xsd/elements/attribute.py

93 lines
2.7 KiB
Python

import logging
from lxml import etree
from zeep import exceptions
from zeep.xsd.const import NotSet
from zeep.xsd.elements.element import Element
logger = logging.getLogger(__name__)
__all__ = ['Attribute', 'AttributeGroup']
class Attribute(Element):
def __init__(self, name, type_=None, required=False, default=None):
super(Attribute, self).__init__(name=name, type_=type_, default=default)
self.required = required
self.array_type = None
def parse(self, value):
try:
return self.type.pythonvalue(value)
except (TypeError, ValueError):
logger.exception("Error during xml -> python translation")
return None
def render(self, parent, value, render_path=None):
if value in (None, NotSet) and not self.required:
return
self.validate(value, render_path)
value = self.type.xmlvalue(value)
parent.set(self.qname, value)
def validate(self, value, render_path):
try:
self.type.validate(value, required=self.required)
except exceptions.ValidationError as exc:
raise exceptions.ValidationError(
"The attribute %s is not valid: %s" % (self.qname, exc.message),
path=render_path)
def clone(self, *args, **kwargs):
array_type = kwargs.pop('array_type', None)
new = super(Attribute, self).clone(*args, **kwargs)
new.array_type = array_type
return new
def resolve(self):
retval = super(Attribute, self).resolve()
self.type = self.type.resolve()
if self.array_type:
retval.array_type = self.array_type.resolve()
return retval
class AttributeGroup(object):
def __init__(self, name, attributes):
if not isinstance(name, etree.QName):
name = etree.QName(name)
self.name = name.localname
self.qname = name
self.type = None
self._attributes = attributes
self.is_global = True
@property
def attributes(self):
result = []
for attr in self._attributes:
if isinstance(attr, AttributeGroup):
result.extend(attr.attributes)
else:
result.append(attr)
return result
def resolve(self):
resolved = []
for attribute in self._attributes:
value = attribute.resolve()
assert value is not None
if isinstance(value, list):
resolved.extend(value)
else:
resolved.append(value)
self._attributes = resolved
return self
def signature(self, schema=None, standalone=True):
return ', '.join(attr.signature(schema) for attr in self._attributes)