Example #1
0
    def _s_customize(cls, **kwargs):
        """This function duplicates and customizes the class it belongs to. The
        original class remains unchanged.

        Not meant to be overridden.
        """

        cls_dict = odict({'__module__': cls.__module__})

        if getattr(cls, '__orig__', None) is None:
            cls_dict['__orig__'] = cls

        class Attributes(cls.Attributes):
            pass

        if cls.Attributes.translations is None:
            Attributes.translations = {}
        if cls.Attributes.sqla_column_args is None:
            Attributes.sqla_column_args = (), {}

        cls_dict['Attributes'] = Attributes

        # as nillable is a property, it gets reset everytime a new class is
        # defined. So we need to reinitialize it explicitly.
        Attributes.nillable = cls.Attributes.nillable

        class Annotations(cls.Annotations):
            pass

        cls_dict['Annotations'] = Annotations

        for k, v in kwargs.items():
            if k.startswith('_'):
                continue

            elif k in ("doc", "appinfo"):
                setattr(Annotations, k, v)

            elif k in ('primary_key', 'pk'):
                Attributes.sqla_column_args[-1]['primary_key'] = v

            elif k in ('prot_attrs', 'pa'):
                setattr(Attributes, 'prot_attrs', _decode_pa_dict(v))

            elif k in ('foreign_key', 'fk'):
                from sqlalchemy.schema import ForeignKey
                t, d = Attributes.sqla_column_args
                fkt = (ForeignKey(v), )
                Attributes.sqla_column_args = (t + fkt, d)

            elif k in ('autoincrement', 'onupdate', 'server_default'):
                Attributes.sqla_column_args[-1][k] = v

            elif k == 'max_occurs' and v in ('unbounded', 'inf', float('inf')):
                setattr(Attributes, k, Decimal('inf'))

            else:
                setattr(Attributes, k, v)

        return (cls.__name__, (cls, ), cls_dict)
Example #2
0
    def __init__(self, interface):
        InterfaceDocumentBase.__init__(self, interface)

        self.schema_dict = {}
        self.validation_schema = None
        self.namespaces = odict()
        self.complex_types = set()
Example #3
0
class Fault(Tr069ComplexModel):
    _type_info = odict()
    _type_info["FaultCode"] = UnsignedInteger
    _type_info["FaultString"] = String
    _type_info["SetParameterValuesFault"] = SetParameterValuesFault.customize(
        max_occurs='unbounded',
    )
Example #4
0
    def __init__(self, interface):
        InterfaceDocumentBase.__init__(self, interface)

        self.schema_dict = {}
        self.validation_schema = None
        self.namespaces = odict()
        self.complex_types = set()
Example #5
0
File: wsgi.py Project: plq/spyne
def _parse_qs(qs):
    pairs = (s2 for s1 in qs.split('&') for s2 in s1.split(';'))
    retval = odict()

    for name_value in pairs:
        if name_value is None or len(name_value) == 0:
            continue
        nv = name_value.split('=', 1)

        if len(nv) != 2:
            # Handle case of a control-name with no equal sign
            nv.append(None)

        name = unquote(nv[0].replace('+', ' '))

        value = None
        if nv[1] is not None:
            value = unquote(nv[1].replace('+', ' '))

        l = retval.get(name, None)
        if l is None:
            l = retval[name] = []
        l.append(value)

    return retval
Example #6
0
    def map(self, django_model, exclude=None, **kwargs):
        """Prepare dict of model fields mapped to spyne models.

        :param django_model: Django model class.
        :param exclude: list of fields excluded from mapping.
        :param kwargs: extra kwargs are passed to all field mappers

        :returns: dict mapping attribute names to spyne models
        :raises: :exc:`UnknownFieldMapperException`

        """
        field_map = odict()

        for field in self._get_fields(django_model, exclude):
            field_type = field.__class__.__name__

            try:
                field_mapper = self._registry[field_type]
            except KeyError:
                # mapper for this field is not registered
                if not (field.has_default() or field.null):
                    # field is required
                    raise self.UnknownFieldMapperException(
                        'No mapper for field type {0}'.format(field_type))
                else:
                    # skip this field
                    logger.info('Field {0} is skipped from mapping.')
                    continue

            attr_name, spyne_model = field_mapper.map(field, **kwargs)
            field_map[attr_name] = spyne_model

        return field_map
Example #7
0
class SetParameterAttributesStruct(Tr069ComplexModel):
    _type_info = odict()
    _type_info["Name"] = String(max_length=256)
    _type_info["NotificationChange"] = Boolean
    _type_info["Notification"] = Integer
    _type_info["AccessListChange"] = Boolean
    _type_info["AccessList"] = AccessList
Example #8
0
    def map(self, django_model, exclude=None, **kwargs):
        """Prepare dict of model fields mapped to spyne models.

        :param django_model: Django model class.
        :param exclude: list of fields excluded from mapping.
        :param kwargs: extra kwargs are passed to all field mappers

        :returns: dict mapping attribute names to spyne models
        :raises: :exc:`UnknownFieldMapperException`

        """
        field_map = odict()

        for field in self._get_fields(django_model, exclude):
            field_type = field.get_internal_type()
            try:
                field_mapper = self._registry[field_type]
            except KeyError:
                # mapper for this field is not registered
                if not (field.has_default() or field.null):
                    # field is required
                    raise self.UnknownFieldMapperException(
                        'No mapper for field type {0}'.format(field_type))
                else:
                    # skip this field
                    logger.info('Field {0} is skipped from mapping.')
                    continue

            attr_name, spyne_model = field_mapper.map(field, **kwargs)
            field_map[attr_name] = spyne_model

        return field_map
Example #9
0
class ID(Tr069ComplexModel):
    # Note: for some reason, XmlAttribute/XmlData pairs MUST be ordered, with
    # XmlAttribute coming first. This appears to be a spyne bug (something to do
    # with spyne.interface._base.add_class())
    _type_info = odict()
    _type_info["mustUnderstand"] = XmlAttribute(String, ns=SOAP_ENV)
    _type_info["Data"] = XmlData(String)
Example #10
0
File: wsgi.py Project: nareni/spyne
def _parse_qs(qs):
    pairs = (s2 for s1 in qs.split('&') for s2 in s1.split(';'))
    retval = odict()

    for name_value in pairs:
        if name_value is None or len(name_value) == 0:
            continue
        nv = name_value.split('=', 1)

        if len(nv) != 2:
            # Handle case of a control-name with no equal sign
            nv.append(None)

        name = unquote(nv[0].replace('+', ' '))

        value = None
        if nv[1] is not None:
            value = unquote(nv[1].replace('+', ' '))

        l = retval.get(name, None)
        if l is None:
            l = retval[name] = []
        l.append(value)

    return retval
Example #11
0
    def _s_customize(cls, **kwargs):
        """This function duplicates and customizes the class it belongs to. The
        original class remains unchanged.

        Not meant to be overridden.
        """

        cls_dict = odict({'__module__': cls.__module__})

        if getattr(cls, '__orig__', None) is None:
            cls_dict['__orig__'] = cls

        class Attributes(cls.Attributes):
            pass

        if cls.Attributes.translations is None:
            Attributes.translations = {}
        if cls.Attributes.sqla_column_args is None:
            Attributes.sqla_column_args = (), {}

        cls_dict['Attributes'] = Attributes

        # as nillable is a property, it gets reset everytime a new class is
        # defined. So we need to reinitialize it explicitly.
        Attributes.nillable = cls.Attributes.nillable

        class Annotations(cls.Annotations):
            pass
        cls_dict['Annotations'] = Annotations

        for k, v in kwargs.items():
            if k.startswith('_'):
                continue

            elif k in ("doc", "appinfo"):
                setattr(Annotations, k, v)

            elif k in ('primary_key', 'pk'):
                Attributes.sqla_column_args[-1]['primary_key'] = v

            elif k in ('prot_attrs', 'pa'):
                setattr(Attributes, 'prot_attrs', _decode_pa_dict(v))

            elif k in ('foreign_key', 'fk'):
                from sqlalchemy.schema import ForeignKey
                t, d = Attributes.sqla_column_args
                fkt = (ForeignKey(v),)
                Attributes.sqla_column_args = (t + fkt, d)

            elif k in ('autoincrement', 'onupdate', 'server_default'):
                Attributes.sqla_column_args[-1][k] = v

            elif k == 'max_occurs' and v in ('unbounded', 'inf', float('inf')):
                setattr(Attributes, k, Decimal('inf'))

            else:
                setattr(Attributes, k, v)

        return (cls.__name__, (cls,), cls_dict)
Example #12
0
    def produce(namespace, type_name, members):
        """Lets you create a class programmatically."""

        return ComplexModelMeta(type_name, (ComplexModel,), odict({
            '__namespace__': namespace,
            '__type_name__': type_name,
            '_type_info': TypeInfo(members),
        }))
Example #13
0
    def produce(namespace, type_name, members):
        """Lets you create a class programmatically."""

        return ComplexModelMeta(
            type_name,
            (ComplexModel,),
            odict({"__namespace__": namespace, "__type_name__": type_name, "_type_info": TypeInfo(members)}),
        )
Example #14
0
    def produce(namespace, type_name, members):
        """Lets you create a class programmatically."""

        return ComplexModelMeta(type_name, (ComplexModel,), odict({
            '__namespace__': namespace,
            '__type_name__': type_name,
            '_type_info': TypeInfo(members),
        }))
Example #15
0
class Inform(Tr069ComplexModel):
    _type_info = odict()
    _type_info["DeviceId"] = DeviceIdStruct
    _type_info["Event"] = EventList
    _type_info["MaxEnvelopes"] = UnsignedInteger
    _type_info["CurrentTime"] = DateTime
    _type_info["RetryCount"] = UnsignedInteger
    _type_info["ParameterList"] = ParameterValueList
Example #16
0
class Person(ComplexModel):
    __namespace__ = "http://xmlns.com/foaf/0.1/"

    _type_info = odict([
        ('name', String),
        #TO-DO Add atrribute
        ('mbox', String),
    ])
Example #17
0
class Release(ComplexModel):
    __namespace__ = "http://usefulinc.com/ns/doap#"

    _type_info = odict([
        ('about',
         RdfAbout(String, ns="http://www.w3.org/1999/02/22-rdf-syntax-ns#")),
        ('Version', Version),
    ])
Example #18
0
    def __init__(self, interface):
        InterfaceDocumentBase.__init__(self, interface)

        self.schema_dict = {}
        self.validation_schema = None

        pref = self.interface.prefmap[self.interface.app.tns]
        self.namespaces = odict({pref: SchemaInfo()})

        self.complex_types = set()
Example #19
0
File: _base.py Project: pxiol/spyne
    def __init__(self, interface):
        super(XmlSchema, self).__init__(interface)

        self.schema_dict = {}
        self.validation_schema = None

        pref = self.interface.prefmap[self.interface.app.tns]
        self.namespaces = odict({pref: SchemaInfo()})

        self.complex_types = set()
Example #20
0
    def __init__(self, interface):
        InterfaceDocumentBase.__init__(self, interface)

        self.schema_dict = {}
        self.validation_schema = None

        pref = self.interface.prefmap[self.interface.app.tns]
        self.namespaces = odict({pref: SchemaInfo()})

        self.complex_types = set()
Example #21
0
class anySimpleType(Tr069ComplexModel):
    """ Type used to transfer simple data of various types. Data type is
        defined in 'type' XML attribute. Data is handled as a string. """
    _type_info = odict()
    _type_info["type"] = XmlAttribute(String, ns=XSI_NS)
    _type_info["Data"] = XmlData(String)

    def __repr__(self):
        """For types we can't resolve only print the datum"""
        return self.Data
Example #22
0
File: _base.py Project: buldi/spyne
    def __init__(self, interface):
        super(XmlSchema, self).__init__(interface)

        self.schema_dict = {}
        self.validation_schema = None

        pref = self.interface.prefmap[self.interface.app.tns]
        self.namespaces = odict({pref: SchemaInfo()})

        self.complex_types = set()
Example #23
0
class Download(Tr069ComplexModel):
    _type_info = odict()
    _type_info["CommandKey"] = CommandKeyType
    _type_info["FileType"] = String(max_length=64)
    _type_info["URL"] = String(max_length=256)
    _type_info["Username"] = String(max_length=256)
    _type_info["Password"] = String(max_length=256)
    _type_info["FileSize"] = UnsignedInteger
    _type_info["TargetFileName"] = String(max_length=256)
    _type_info["DelaySeconds"] = UnsignedInteger
    _type_info["SuccessURL"] = String(max_length=256)
    _type_info["FailureURL"] = String(max_length=256)
Example #24
0
class Project(ComplexModel):
    __namespace__ = "http://usefulinc.com/ns/doap#"

    _type_info = odict([
        ('about',
         RdfAbout(String, ns="http://www.w3.org/1999/02/22-rdf-syntax-ns#")),
        ('name', String),
        ('created', Date),
        ('shortdesc', Unicode),
        ('homepage', String),
        ('developer', Developer),
        ('release', Release.customize(max_occurs=float('inf'))),
    ])
Example #25
0
class ParameterListUnion(Tr069ComplexModel):
    """ Union of structures that get instantiated as 'ParameterList' in ACS->CPE
        messages. This is required because AcsToCpeRequests can only have one
        parameter named 'ParameterList', so that must also be a union """
    _type_info = odict()

    # Fields from ParameterValueList
    _type_info["ParameterValueStruct"] = ParameterValueStruct.customize(
        max_occurs='unbounded')
    _type_info["arrayType"] = XmlAttribute(String, ns=SOAP_ENC)

    # Fields from SetParameterAttributesList
    _type_info["SetParameterAttributesStruct"] = \
        SetParameterAttributesStruct.customize(max_occurs='unbounded')
Example #26
0
class Version(ComplexModel):
    __namespace__ = "http://usefulinc.com/ns/doap#"

    _type_info = odict([
        ('name', String),
        ('created', Date),
        ('revision', String),
        #ns="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
        #TO-DO Add path#md5 -> rdf:resource as atrribute
        ('file-release', String),
        ("resource",
         RdfResource(String,
                     ns="http://www.w3.org/1999/02/22-rdf-syntax-ns#",
                     attribute_of="file-release")),
    ])
Example #27
0
class Download(Tr069ComplexModel):
    _type_info = odict()
    _type_info["CommandKey"] = CommandKeyType
    _type_info["FileType"] = String(max_length=64)
    _type_info["URL"] = String(max_length=256)
    _type_info["Username"] = String(max_length=256)
    _type_info["Password"] = String(max_length=256)
    _type_info["FileSize"] = UnsignedInteger
    _type_info["TargetFileName"] = String(max_length=256)
    _type_info["DelaySeconds"] = UnsignedInteger
    _type_info["SuccessURL"] = String(max_length=256)
    _type_info["FailureURL"] = String(max_length=256)
    # The following are extra aditions introduced for Baicells
    _type_info["Md5"] = String(max_length=32)
    _type_info["RawMode"] = Boolean
Example #28
0
def etree_to_dict(element, iterable=(list, list.append)):
    """Takes an xml root element and returns the corresponding dict. The second
    argument is a pair of iterable type and the function used to add elements to
    the iterable. The xml attributes are ignored.
    """

    if (element.text is None) or element.text.isspace():
        retval = odict()
        for elt in element:
            if not (elt.tag in retval):
                retval[elt.tag] = iterable[0]()
            iterable[1](retval[elt.tag], etree_to_dict(elt, iterable))

    else:
        retval = element.text

    return retval
Example #29
0
class AcsToCpeRequests(Tr069ComplexModel):
    """ Union of all ACS->CPE requests. Only fields for one request is populated
        per message instance """
    _type_info = odict()

    # Fields for SetParameterValues
    _type_info[
        "ParameterList"] = ParameterListUnion  # See ParameterListUnion for explanation
    _type_info["ParameterKey"] = ParameterKeyType

    # Fields for GetParameterValues
    # _type_info["ParameterList"] = ParameterValueList - Already covered above

    # Fields for GetParameterNames
    _type_info["ParameterPath"] = String.customize(max_length=256)
    _type_info["NextLevel"] = Boolean

    # Fields for SetParameterAttributes
    # _type_info["ParameterList"] = SetParameterAttributesList - Already covered above

    # Fields for GetParameterAttributes
    _type_info["ParameterNames"] = ParameterNames

    # Fields for AddObject
    _type_info["ObjectName"] = ObjectNameType
    _type_info["ParameterKey"] = ParameterKeyType

    # Fields for DeleteObject
    # _type_info["ObjectName"] = ObjectNameType - Already covered above
    # _type_info["ParameterKey"] = ParameterKeyType - Already covered above

    # Fields for Download
    _type_info["CommandKey"] = CommandKeyType
    _type_info["FileType"] = String(max_length=64)
    _type_info["URL"] = String(max_length=256)
    _type_info["Username"] = String(max_length=256)
    _type_info["Password"] = String(max_length=256)
    _type_info["FileSize"] = UnsignedInteger
    _type_info["TargetFileName"] = String(max_length=256)
    _type_info["DelaySeconds"] = UnsignedInteger
    _type_info["SuccessURL"] = String(max_length=256)
    _type_info["FailureURL"] = String(max_length=256)
    # Optional Baicells specific Download fields
    _type_info["Md5"] = String(max_length=32)
    _type_info["RawMode"] = Boolean
Example #30
0
class DeviceIdStruct(Tr069ComplexModel):
    _type_info = odict()
    _type_info["Manufacturer"] = String(max_length=64)
    _type_info["OUI"] = String(length=6)
    _type_info["ProductClass"] = String(max_length=64)
    _type_info["SerialNumber"] = String(max_length=64)

    def as_dict(self):
        """
        Overriding default implementation to fix memory leak. Can remove if
        or after https://github.com/arskom/spyne/pull/579 lands.

        Only patching it for this model because it's the only place in enodebd
        where we call this method.
        """
        flat_type_info = self.get_flat_type_info(self.__class__)
        return dict((
            (k, getattr(self, k)) for k in flat_type_info
            if getattr(self, k) is not None
        ))
Example #31
0
    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
Example #32
0
def parse_schema(ctx, elt):
    ctx.nsmap = nsmap = elt.nsmap
    ctx.prefmap = prefmap = dict([(v, k) for k, v in ctx.nsmap.items()])
    ctx.schema = schema = _prot.from_element(XmlSchema10, elt)

    ctx.pending_types = {}
    ctx.pending_elements = {}

    ctx.tns = tns = schema.target_namespace
    if tns in ctx.retval:
        return
    ctx.retval[tns] = _Schema()

    ctx.debug0("1 %s processing includes", M(tns))
    if schema.includes:
        for include in schema.includes:
            process_includes(ctx, include)

    if schema.elements:
        schema.elements = odict([(e.name, e) for e in schema.elements])
    if schema.complex_types:
        schema.complex_types = odict([(c.name, c)
                                      for c in schema.complex_types])
    if schema.simple_types:
        schema.simple_types = odict([(s.name, s) for s in schema.simple_types])
    if schema.attributes:
        schema.attributes = odict([(a.name, a) for a in schema.attributes])

    ctx.debug0("2 %s processing imports", R(tns))
    if schema.imports:
        for imp in schema.imports:
            if not imp.namespace in ctx.retval:
                ctx.debug1("%s importing %s", tns, imp.namespace)
                file_name = ctx.files[imp.namespace]
                parse_schema_file(ctx.clone(2, dirname(file_name)), file_name)
                ctx.retval[tns].imports.add(imp.namespace)

    ctx.debug0("3 %s processing attributes", G(tns))
    if schema.attributes:
        for s in schema.attributes.values():
            n, t = process_attribute(ctx, s)
            ctx.retval[ctx.tns].types[n] = t

    ctx.debug0("4 %s processing simple_types", G(tns))
    if schema.simple_types:
        for s in schema.simple_types.values():
            st = process_simple_type(ctx, s)
            ctx.retval[ctx.tns].types[s.name] = st

    ctx.debug0("5 %s processing complex_types", B(tns))
    if schema.complex_types:
        for c in schema.complex_types.values():
            process_complex_type(ctx, c)

    ctx.debug0("6 %s processing elements", Y(tns))
    if schema.elements:
        for e in schema.elements.values():
            process_schema_element(ctx, e)

    process_pending(ctx)

    if ctx.parent is None:  # for the top-most schema
        if ctx.children is not None:  # if it uses <include> or <import>
            # This is needed for schemas with circular imports
            for c in chain([ctx], ctx.children):
                print_pending(c)
            ctx.debug0('')

            for c in chain([ctx], ctx.children):
                process_pending(c)
            for c in chain([ctx], ctx.children):
                process_pending(c)
            ctx.debug0('')

            for c in chain([ctx], ctx.children):
                print_pending(c, fail=True)

    return ctx.retval
Example #33
0
class FaultStruct(Tr069ComplexModel):
    _type_info = odict()
    _type_info["FaultCode"] = Integer
    _type_info["FaultString"] = String(max_length=256)
Example #34
0
class MethodList(Tr069ComplexModel):
    _type_info = odict()
    _type_info["MethodList"] = String(max_length=64, max_occurs='unbounded')
    _type_info["arrayType"] = XmlAttribute(String, ns=SOAP_ENC)
Example #35
0
 def __prepare__(mcs, name, bases, **kwds):
     return odict()
Example #36
0
File: parser.py Project: hozn/spyne
    def parse_schema(self, elt):
        self.nsmap = dict(elt.nsmap.items())
        self.prefmap = dict([(v, k) for k, v in self.nsmap.items()])
        self.schema = schema = _prot.from_element(self, XmlSchema10, elt)

        self.pending_types = {}
        self.pending_elements = {}

        self.tns = tns = schema.target_namespace
        if self.tns is None:
            self.tns = tns = '__no_ns__'
        if tns in self.retval:
            return
        self.retval[tns] = _Schema()

        self.debug0("1 %s processing includes", MAG(tns))
        if schema.includes:
            for include in schema.includes:
                self.process_includes(include)

        if schema.elements:
            schema.elements = odict([(e.name, e) for e in schema.elements])
        if schema.complex_types:
            schema.complex_types = odict([(c.name, c)
                                                 for c in schema.complex_types])
        if schema.simple_types:
            schema.simple_types = odict([(s.name, s)
                                                 for s in schema.simple_types])
        if schema.attributes:
            schema.attributes = odict([(a.name, a) for a in schema.attributes])

        self.debug0("2 %s processing imports", R(tns))
        if schema.imports:
            for imp in schema.imports:
                if not imp.namespace in self.retval:
                    self.debug1("%s importing %s", tns, imp.namespace)
                    fname = self.files[imp.namespace]
                    self.clone(2, dirname(fname)).parse_schema_file(fname)
                    self.retval[tns].imports.add(imp.namespace)

        self.debug0("3 %s processing simple_types", G(tns))
        if schema.simple_types:
            for s in schema.simple_types.values():
                self.process_simple_type(s)

            # no simple types should have been left behind.
            assert sum((len(v) for v in self.pending_simple_types.values())) == 0, \
                                              self.pending_simple_types.values()

        self.debug0("4 %s processing attributes", G(tns))
        if schema.attributes:
            for s in schema.attributes.values():
                n, t = self.process_attribute(s)
                self.retval[self.tns].types[n] = t

        self.debug0("5 %s processing complex_types", B(tns))
        if schema.complex_types:
            for c in schema.complex_types.values():
                self.process_complex_type(c)

        self.debug0("6 %s processing elements", YEL(tns))
        if schema.elements:
            for e in schema.elements.values():
                self.process_schema_element(e)

        self.process_pending()

        if self.parent is None:  # for the top-most schema
            if self.children is not None:  # if it uses <include> or <import>
                # This is needed for schemas with circular imports
                for c in chain([self], self.children):
                    c.print_pending()
                self.debug0('')

                # FIXME: should put this in a while loop that loops until no
                # changes occur
                for c in chain([self], self.children):
                    c.process_pending()
                for c in chain([self], self.children):
                    c.process_pending()
                self.debug0('')

                for c in chain([self], self.children):
                    c.print_pending(fail=(not self.skip_errors))

        return self.retval
Example #37
0
    def _s_customize(cls, **kwargs):
        """This function duplicates and customizes the class it belongs to. The
        original class remains unchanged.

        Not meant to be overridden.
        """

        cls_dict = odict({"__module__": cls.__module__, "__doc__": cls.__doc__})

        if getattr(cls, "__orig__", None) is None:
            cls_dict["__orig__"] = cls
        else:
            cls_dict["__orig__"] = cls.__orig__

        class Attributes(cls.Attributes):
            pass

        if cls.Attributes.translations is None:
            Attributes.translations = {}
        if cls.Attributes.sqla_column_args is None:
            Attributes.sqla_column_args = (), {}
        cls_dict["Attributes"] = Attributes

        # properties get reset everytime a new class is defined. So we need
        # to reinitialize them explicitly.
        for k in ("nillable", "_xml_cloth", "_xml_root_cloth", "_html_cloth", "_html_root_cloth"):
            v = getattr(cls.Attributes, k)
            if v is not None:
                setattr(Attributes, k, v)

        class Annotations(cls.Annotations):
            pass

        cls_dict["Annotations"] = Annotations

        # get protocol attrs
        prot = kwargs.get("protocol", None)
        if prot is None:
            prot = kwargs.get("prot", None)
        if prot is None:
            prot = kwargs.get("p", None)
        if prot is not None and len(prot.type_attrs) > 0:
            # if there is a class customization from protocol, do it

            type_attrs = prot.type_attrs.copy()
            type_attrs.update(kwargs)
            logger.debug("%r: kwargs %r => %r from prot typeattr %r", cls, kwargs, type_attrs, prot.type_attrs)
            kwargs = type_attrs

        for k, v in kwargs.items():
            if k.startswith("_"):
                continue

            if k in ("protocol", "prot", "p"):
                setattr(Attributes, "prot", v)

            if k in ("doc", "appinfo"):
                setattr(Annotations, k, v)

            elif k in ("primary_key", "pk"):
                setattr(Attributes, "primary_key", v)
                Attributes.sqla_column_args[-1]["primary_key"] = v

            elif k in ("protocol_attrs", "prot_attrs", "pa"):
                setattr(Attributes, "prot_attrs", _decode_pa_dict(v))

            elif k in ("foreign_key", "fk"):
                from sqlalchemy.schema import ForeignKey

                t, d = Attributes.sqla_column_args
                fkt = (ForeignKey(v),)
                Attributes.sqla_column_args = (t + fkt, d)

            elif k in ("autoincrement", "onupdate", "server_default"):
                Attributes.sqla_column_args[-1][k] = v

            elif k == "values_dict":
                assert not "values" in v, "`values` and `values_dict` can't be" "specified at the same time"

                Attributes.values = v.keys()
                Attributes.values_dict = v

            elif k == "max_occurs" and v in ("unbounded", "inf", float("inf")):
                setattr(Attributes, k, Decimal("inf"))

            else:
                setattr(Attributes, k, v)

        return (cls.__name__, (cls,), cls_dict)
Example #38
0
    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
Example #39
0
    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
Example #40
0
    def _s_customize(cls, **kwargs):
        """This function duplicates and customizes the class it belongs to. The
        original class remains unchanged.

        Not meant to be overridden.
        """

        cls_dict = odict({'__module__': cls.__module__, '__doc__': cls.__doc__})

        if getattr(cls, '__orig__', None) is None:
            cls_dict['__orig__'] = cls

        class Attributes(cls.Attributes):
            pass

        if cls.Attributes.translations is None:
            Attributes.translations = {}
        if cls.Attributes.sqla_column_args is None:
            Attributes.sqla_column_args = (), {}
        cls_dict['Attributes'] = Attributes

        # properties get reset everytime a new class is defined. So we need
        # to reinitialize them explicitly.
        for k in ('nillable', '_xml_cloth', '_xml_root_cloth', '_html_cloth',
                                                            '_html_root_cloth'):
            v = getattr(cls.Attributes, k)
            if v is not None:
                setattr(Attributes, k, v)

        class Annotations(cls.Annotations):
            pass
        cls_dict['Annotations'] = Annotations

        # get protocol attrs
        prot = kwargs.get('protocol', None)
        if prot is None:
            prot = kwargs.get('prot', None)
        if prot is None:
            prot = kwargs.get('p', None)
        if prot is not None and len(prot.type_attrs) > 0:
            # if there is a class customization from protocol, do it

            type_attrs = prot.type_attrs.copy()
            type_attrs.update(kwargs)
            logger.debug("%r: kwargs %r => %r from prot typeattr %r",
                                       cls, kwargs, type_attrs, prot.type_attrs)
            kwargs = type_attrs

        for k, v in kwargs.items():
            if k.startswith('_'):
                continue

            if k in ('protocol', 'prot', 'p'):
                setattr(Attributes, 'prot', v)

            if k in ("doc", "appinfo"):
                setattr(Annotations, k, v)

            elif k in ('primary_key', 'pk'):
                setattr(Attributes, 'primary_key', v)
                Attributes.sqla_column_args[-1]['primary_key'] = v

            elif k in ('protocol_attrs', 'prot_attrs', 'pa'):
                setattr(Attributes, 'prot_attrs', _decode_pa_dict(v))

            elif k in ('foreign_key', 'fk'):
                from sqlalchemy.schema import ForeignKey
                t, d = Attributes.sqla_column_args
                fkt = (ForeignKey(v),)
                Attributes.sqla_column_args = (t + fkt, d)

            elif k in ('autoincrement', 'onupdate', 'server_default'):
                Attributes.sqla_column_args[-1][k] = v

            elif k == 'values_dict':
                assert not 'values' in v, "`values` and `values_dict` can't be" \
                                          "specified at the same time"

                Attributes.values = v.keys()
                Attributes.values_dict = v

            elif k == 'max_occurs' and v in ('unbounded', 'inf', float('inf')):
                setattr(Attributes, k, Decimal('inf'))

            else:
                setattr(Attributes, k, v)

        return (cls.__name__, (cls,), cls_dict)
Example #41
0
    def parse_schema(self, elt):
        self.nsmap = nsmap = elt.nsmap
        self.prefmap = prefmap = dict([(v,k) for k,v in self.nsmap.items()])
        self.schema = schema = _prot.from_element(self, XmlSchema10, elt)

        self.pending_types = {}
        self.pending_elements = {}

        self.tns = tns = schema.target_namespace
        if self.tns is None:
            self.tns = tns = '__no_ns__'
        if tns in self.retval:
            return
        self.retval[tns] = _Schema()

        self.debug0("1 %s processing includes", M(tns))
        if schema.includes:
            for include in schema.includes:
                self.process_includes(include)

        if schema.elements:
            schema.elements = odict([(e.name, e) for e in schema.elements])
        if schema.complex_types:
            schema.complex_types = odict([(c.name, c) for c in schema.complex_types])
        if schema.simple_types:
            schema.simple_types = odict([(s.name, s) for s in schema.simple_types])
        if schema.attributes:
            schema.attributes = odict([(a.name, a) for a in schema.attributes])

        self.debug0("2 %s processing imports", R(tns))
        if schema.imports:
            for imp in schema.imports:
                if not imp.namespace in self.retval:
                    self.debug1("%s importing %s", tns, imp.namespace)
                    file_name = self.files[imp.namespace]
                    self.clone(2, dirname(file_name)).parse_schema_file(file_name)
                    self.retval[tns].imports.add(imp.namespace)

        self.debug0("3 %s processing attributes", G(tns))
        if schema.attributes:
            for s in schema.attributes.values():
                n, t = self.process_attribute(s)
                self.retval[self.tns].types[n] = t

        self.debug0("4 %s processing simple_types", G(tns))
        if schema.simple_types:
            for s in schema.simple_types.values():
                st = self.process_simple_type(s)
                self.retval[self.tns].types[s.name] = st

        self.debug0("5 %s processing complex_types", B(tns))
        if schema.complex_types:
            for c in schema.complex_types.values():
                self.process_complex_type(c)

        self.debug0("6 %s processing elements", Y(tns))
        if schema.elements:
            for e in schema.elements.values():
                self.process_schema_element(e)

        self.process_pending()

        if self.parent is None: # for the top-most schema
            if self.children is not None: # if it uses <include> or <import>
                # This is needed for schemas with circular imports
                for c in chain([self], self.children):
                    c.print_pending()
                self.debug0('')

                # FIXME: This has no guarantee of working yet covers all the
                # schema files found in the wild so far.
                for c in chain([self], self.children):
                    c.process_pending()
                for c in chain([self], self.children):
                    c.process_pending()
                self.debug0('')

                for c in chain([self], self.children):
                    c.print_pending(fail=True)

        return self.retval
Example #42
0
    def parse_schema(self, elt):
        self.nsmap = nsmap = elt.nsmap
        self.prefmap = prefmap = dict([(v, k) for k, v in self.nsmap.items()])
        self.schema = schema = _prot.from_element(self, XmlSchema10, elt)

        self.pending_types = {}
        self.pending_elements = {}

        self.tns = tns = schema.target_namespace
        if self.tns is None:
            self.tns = tns = '__no_ns__'
        if tns in self.retval:
            return
        self.retval[tns] = _Schema()

        self.debug0("1 %s processing includes", M(tns))
        if schema.includes:
            for include in schema.includes:
                self.process_includes(include)

        if schema.elements:
            schema.elements = odict([(e.name, e) for e in schema.elements])
        if schema.complex_types:
            schema.complex_types = odict([(c.name, c)
                                          for c in schema.complex_types])
        if schema.simple_types:
            schema.simple_types = odict([(s.name, s)
                                         for s in schema.simple_types])
        if schema.attributes:
            schema.attributes = odict([(a.name, a) for a in schema.attributes])

        self.debug0("2 %s processing imports", R(tns))
        if schema.imports:
            for imp in schema.imports:
                if not imp.namespace in self.retval:
                    self.debug1("%s importing %s", tns, imp.namespace)
                    file_name = self.files[imp.namespace]
                    self.clone(2,
                               dirname(file_name)).parse_schema_file(file_name)
                    self.retval[tns].imports.add(imp.namespace)

        self.debug0("3 %s processing attributes", G(tns))
        if schema.attributes:
            for s in schema.attributes.values():
                n, t = self.process_attribute(s)
                self.retval[self.tns].types[n] = t

        self.debug0("4 %s processing simple_types", G(tns))
        if schema.simple_types:
            for s in schema.simple_types.values():
                st = self.process_simple_type(s)
                self.retval[self.tns].types[s.name] = st

        self.debug0("5 %s processing complex_types", B(tns))
        if schema.complex_types:
            for c in schema.complex_types.values():
                self.process_complex_type(c)

        self.debug0("6 %s processing elements", Y(tns))
        if schema.elements:
            for e in schema.elements.values():
                self.process_schema_element(e)

        self.process_pending()

        if self.parent is None:  # for the top-most schema
            if self.children is not None:  # if it uses <include> or <import>
                # This is needed for schemas with circular imports
                for c in chain([self], self.children):
                    c.print_pending()
                self.debug0('')

                # FIXME: This has no guarantee of working yet covers all the
                # schema files found in the wild so far.
                for c in chain([self], self.children):
                    c.process_pending()
                for c in chain([self], self.children):
                    c.process_pending()
                self.debug0('')

                for c in chain([self], self.children):
                    c.print_pending(fail=True)

        return self.retval
Example #43
0
def parse_schema(ctx, elt):
    ctx.nsmap = nsmap = elt.nsmap
    ctx.prefmap = prefmap = dict([(v,k) for k,v in ctx.nsmap.items()])
    ctx.schema = schema = _prot.from_element(ctx, XmlSchema10, elt)

    ctx.pending_types = {}
    ctx.pending_elements = {}

    ctx.tns = tns = schema.target_namespace
    if tns in ctx.retval:
        return
    ctx.retval[tns] = _Schema()

    ctx.debug0("1 %s processing includes", M(tns))
    if schema.includes:
        for include in schema.includes:
            process_includes(ctx, include)

    if schema.elements:
        schema.elements = odict([(e.name, e) for e in schema.elements])
    if schema.complex_types:
        schema.complex_types = odict([(c.name, c) for c in schema.complex_types])
    if schema.simple_types:
        schema.simple_types = odict([(s.name, s) for s in schema.simple_types])
    if schema.attributes:
        schema.attributes = odict([(a.name, a) for a in schema.attributes])

    ctx.debug0("2 %s processing imports", R(tns))
    if schema.imports:
        for imp in schema.imports:
            if not imp.namespace in ctx.retval:
                ctx.debug1("%s importing %s", tns, imp.namespace)
                file_name = ctx.files[imp.namespace]
                parse_schema_file(ctx.clone(2, dirname(file_name)), file_name)
                ctx.retval[tns].imports.add(imp.namespace)

    ctx.debug0("3 %s processing attributes", G(tns))
    if schema.attributes:
        for s in schema.attributes.values():
            n, t= process_attribute(ctx, s)
            ctx.retval[ctx.tns].types[n] = t

    ctx.debug0("4 %s processing simple_types", G(tns))
    if schema.simple_types:
        for s in schema.simple_types.values():
            st = process_simple_type(ctx, s)
            ctx.retval[ctx.tns].types[s.name] = st

    ctx.debug0("5 %s processing complex_types", B(tns))
    if schema.complex_types:
        for c in schema.complex_types.values():
            process_complex_type(ctx, c)

    ctx.debug0("6 %s processing elements", Y(tns))
    if schema.elements:
        for e in schema.elements.values():
            process_schema_element(ctx, e)

    process_pending(ctx)

    if ctx.parent is None: # for the top-most schema
        if ctx.children is not None: # if it uses <include> or <import>
            # This is needed for schemas with circular imports
            for c in chain([ctx], ctx.children):
                print_pending(c)
            ctx.debug0('')

            for c in chain([ctx], ctx.children):
                process_pending(c)
            for c in chain([ctx], ctx.children):
                process_pending(c)
            ctx.debug0('')

            for c in chain([ctx], ctx.children):
                print_pending(c, fail=True)

    return ctx.retval
Example #44
0
    def _s_customize(cls, **kwargs):
        """This function duplicates and customizes the class it belongs to. The
        original class remains unchanged.

        Not meant to be overridden.
        """

        def _log_debug(s, *args):
            logger.debug("\t%s: %s" % (cls.get_type_name(), s), *args)

        cls_dict = odict({'__module__': cls.__module__, '__doc__': cls.__doc__})

        if getattr(cls, '__orig__', None) is None:
            cls_dict['__orig__'] = cls
        else:
            cls_dict['__orig__'] = cls.__orig__

        class Attributes(cls.Attributes):
            _explicit_type_name = False

        if cls.Attributes.translations is None:
            Attributes.translations = {}
        if cls.Attributes.sqla_column_args is None:
            Attributes.sqla_column_args = (), {}
        else:
            Attributes.sqla_column_args = deepcopy(
                                                cls.Attributes.sqla_column_args)

        cls_dict['Attributes'] = Attributes

        # properties get reset every time a new class is defined. So we need
        # to reinitialize them explicitly.
        for k in ('nillable', '_xml_cloth', '_xml_root_cloth', '_html_cloth',
                                                            '_html_root_cloth'):
            v = getattr(cls.Attributes, k)
            if v is not None:
                setattr(Attributes, k, v)

        class Annotations(cls.Annotations):
            pass
        cls_dict['Annotations'] = Annotations

        # get protocol attrs
        prot = kwargs.get('protocol', None)
        if prot is None:
            prot = kwargs.get('prot', None)
        if prot is None:
            prot = kwargs.get('p', None)
        if prot is not None and len(prot.type_attrs) > 0:
            # if there is a class customization from protocol, do it

            type_attrs = prot.type_attrs.copy()
            type_attrs.update(kwargs)
            _log_debug("kwargs %r => %r from prot typeattr %r",
                                            kwargs, type_attrs, prot.type_attrs)
            kwargs = type_attrs

        for k, v in kwargs.items():
            if k.startswith('_'):
                _log_debug("ignoring '%s' because of leading underscore", k)
                continue

            if k in ('protocol', 'prot', 'p'):
                Attributes.prot = v
                _log_debug("setting prot=%r", v)

            elif k in ('voa', 'validate_on_assignment'):
                Attributes.validate_on_assignment = v
                _log_debug("setting voa=%r", v)

            elif k in ('parser', 'cast'):
                setattr(Attributes, k, staticmethod(v))
                _log_debug("setting %s=%r", k, v)

            elif k in ("doc", "appinfo"):
                setattr(Annotations, k, v)
                _log_debug("setting Annotations.%s=%r", k, v)

            elif k in ('primary_key', 'pk'):
                setattr(Attributes, 'primary_key', v)
                Attributes.sqla_column_args[-1]['primary_key'] = v
                _log_debug("setting primary_key=%r", v)

            elif k in ('protocol_attrs', 'prot_attrs', 'pa'):
                setattr(Attributes, 'prot_attrs', _decode_pa_dict(v))
                _log_debug("setting prot_attrs=%r", v)

            elif k in ('foreign_key', 'fk'):
                from sqlalchemy.schema import ForeignKey
                t, d = Attributes.sqla_column_args
                fkt = (ForeignKey(v),)
                new_v = (t + fkt, d)
                Attributes.sqla_column_args = new_v
                _log_debug("setting sqla_column_args=%r", new_v)

            elif k in ('autoincrement', 'onupdate', 'server_default'):
                Attributes.sqla_column_args[-1][k] = v
                _log_debug("adding %s=%r to Attributes.sqla_column_args", k, v)

            elif k == 'values_dict':
                assert not 'values' in v, "`values` and `values_dict` can't be" \
                                          "specified at the same time"

                if not isinstance(v, dict):
                    # our odict has one nasty implicit behaviour: setitem on
                    # int keys is treated as array indexes, not dict keys. so
                    # dicts with int indexes can't work with odict. so we use
                    # the one from stdlib
                    v = OrderedDict(v)

                Attributes.values = v.keys()
                Attributes.values_dict = v
                _log_debug("setting values=%r, values_dict=%r",
                                      Attributes.values, Attributes.values_dict)

            elif k == 'exc_table':
                Attributes.exc_table = v
                Attributes.exc_db = v
                _log_debug("setting exc_table=%r, exc_db=%r", v, v)

            elif k == 'max_occurs' and v in ('unbounded', 'inf', float('inf')):
                new_v = decimal.Decimal('inf')
                setattr(Attributes, k, new_v)
                _log_debug("setting max_occurs=%r", new_v)

            elif k == 'type_name':
                Attributes._explicit_type_name = True
                _log_debug("setting _explicit_type_name=True because "
                                                          "we have 'type_name'")

            else:
                setattr(Attributes, k, v)
                _log_debug("setting %s=%r", k, v)

        return (cls.__name__, (cls,), cls_dict)
Example #45
0
 def __prepare__(mcs, name, bases, **kwds):
     return odict((("__class__", mcs),))
Example #46
0
File: parser.py Project: hozn/spyne
    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
Example #47
0
    def parse_schema(self, elt):
        self.nsmap = dict(elt.nsmap.items())
        self.prefmap = dict([(v, k) for k, v in self.nsmap.items()])
        self.schema = schema = _prot.from_element(self, XmlSchema10, elt)

        self.pending_types = {}
        self.pending_elements = {}

        self.tns = tns = schema.target_namespace
        if self.tns is None:
            self.tns = tns = '__no_ns__'
        if tns in self.retval:
            return
        self.retval[tns] = _Schema()

        self.debug0("1 %s processing includes", MAG(tns))
        if schema.includes:
            for include in schema.includes:
                self.process_includes(include)

        if schema.elements:
            schema.elements = odict([(e.name, e) for e in schema.elements])
        if schema.complex_types:
            schema.complex_types = odict([(c.name, c)
                                          for c in schema.complex_types])
        if schema.simple_types:
            schema.simple_types = odict([(s.name, s)
                                         for s in schema.simple_types])
        if schema.attributes:
            schema.attributes = odict([(a.name, a) for a in schema.attributes])

        self.debug0("2 %s processing imports", R(tns))
        if schema.imports:
            for imp in schema.imports:
                if not imp.namespace in self.retval:
                    self.debug1("%s importing %s", tns, imp.namespace)
                    fname = self.files[imp.namespace]
                    self.clone(2, dirname(fname)).parse_schema_file(fname)
                    self.retval[tns].imports.add(imp.namespace)

        self.debug0("3 %s processing simple_types", G(tns))
        if schema.simple_types:
            for s in schema.simple_types.values():
                self.process_simple_type(s)

            # no simple types should have been left behind.
            assert sum((len(v) for v in self.pending_simple_types.values())) == 0, \
                                              self.pending_simple_types.values()

        self.debug0("4 %s processing attributes", G(tns))
        if schema.attributes:
            for s in schema.attributes.values():
                n, t = self.process_attribute(s)
                self.retval[self.tns].types[n] = t

        self.debug0("5 %s processing complex_types", B(tns))
        if schema.complex_types:
            for c in schema.complex_types.values():
                self.process_complex_type(c)

        self.debug0("6 %s processing elements", YEL(tns))
        if schema.elements:
            for e in schema.elements.values():
                self.process_schema_element(e)

        self.process_pending()

        if self.parent is None:  # for the top-most schema
            if self.children is not None:  # if it uses <include> or <import>
                # This is needed for schemas with circular imports
                for c in chain([self], self.children):
                    c.print_pending()
                self.debug0('')

                # FIXME: should put this in a while loop that loops until no
                # changes occur
                for c in chain([self], self.children):
                    c.process_pending()
                for c in chain([self], self.children):
                    c.process_pending()
                self.debug0('')

                for c in chain([self], self.children):
                    c.print_pending(fail=(not self.skip_errors))

        return self.retval
Example #48
0
def parse_schema(ctx, elt):
    ctx.nsmap = nsmap = elt.nsmap
    ctx.prefmap = prefmap = dict([(v,k) for k,v in ctx.nsmap.items()])
    ctx.schema = schema = XmlDocument().from_element(XmlSchema, elt)

    ctx.pending_types = {}
    ctx.pending_elements = {}

    ctx.tns = tns = schema.target_namespace
    if tns in ctx.retval:
        return
    ctx.retval[tns] = _Schema()

    debug("%s1 %s processing includes", ctx.i0(), m(tns))
    if schema.includes:
        for include in schema.includes:
            process_includes(ctx, include)

    if schema.elements:
        schema.elements = odict([(e.name, e) for e in schema.elements])
    if schema.complex_types:
        schema.complex_types = odict([(c.name, c) for c in schema.complex_types])
    if schema.simple_types:
        schema.simple_types = odict([(s.name, s) for s in schema.simple_types])

    debug("%s2 %s processing imports", ctx.i0(), r(tns))
    if schema.imports:
        for imp in schema.imports:
            if not imp.namespace in ctx.retval:
                debug("%s %s importing %s", ctx.i1(), tns, imp.namespace)
                file_name = ctx.files[imp.namespace]
                parse_schema_file(ctx.clone(2, dirname(file_name)), file_name)

    debug("%s3 %s processing simple_types", ctx.i0(), g(tns))
    if schema.simple_types:
        for s in schema.simple_types.values():
            process_simple_type(ctx, s)

    debug("%s4 %s processing complex_types", ctx.i0(), b(tns))
    if schema.complex_types:
        for c in schema.complex_types.values():
            process_complex_type(ctx, c)

    debug("%s5 %s processing elements", ctx.i0(), y(tns))
    if schema.elements:
        for e in schema.elements.values():
            process_element(ctx, e)

    process_pending(ctx)

    if ctx.parent is None: # for the top-most schema
        if ctx.children is not None: # # if it uses <include> or <import>
            # This is needed for schemas with circular imports
            for c in chain([ctx], ctx.children):
                print_pending(c)
            debug('')

            for c in chain([ctx], ctx.children):
                process_pending(c)
            for c in chain([ctx], ctx.children):
                process_pending(c)
            debug('')
            for c in chain([ctx], ctx.children):
                print_pending(c)

    return ctx.retval
Example #49
0
    def _s_customize(cls, **kwargs):
        """Sanitizes customization parameters of the class it belongs to.
        Doesn't perform any actual customization.
        """
        def _log_debug(s, *args):
            logger.debug("\t%s: %s" % (cls.get_type_name(), s), *args)

        cls_dict = odict({
            '__module__': cls.__module__,
            '__doc__': cls.__doc__
        })

        if getattr(cls, '__orig__', None) is None:
            cls_dict['__orig__'] = cls
        else:
            cls_dict['__orig__'] = cls.__orig__

        class Attributes(cls.Attributes):
            _explicit_type_name = False

        if cls.Attributes.translations is None:
            Attributes.translations = {}

        if cls.Attributes.sqla_column_args is None:
            Attributes.sqla_column_args = (), {}
        else:
            Attributes.sqla_column_args = deepcopy(
                cls.Attributes.sqla_column_args)

        cls_dict['Attributes'] = Attributes

        # properties get reset every time a new class is defined. So we need
        # to reinitialize them explicitly.
        for k in ('nillable', '_xml_cloth', '_xml_root_cloth', '_html_cloth',
                  '_html_root_cloth'):
            v = getattr(cls.Attributes, k)
            if v is not None:
                setattr(Attributes, k, v)

        class Annotations(cls.Annotations):
            pass

        cls_dict['Annotations'] = Annotations

        # get protocol attrs
        prot = kwargs.get('protocol', None)
        if prot is None:
            prot = kwargs.get('prot', None)

        if prot is None:
            prot = kwargs.get('p', None)

        if prot is not None and len(prot.type_attrs) > 0:
            # if there is a class customization from protocol, do it

            type_attrs = prot.type_attrs.copy()
            type_attrs.update(kwargs)
            _log_debug("kwargs %r => %r from prot typeattr %r", kwargs,
                       type_attrs, prot.type_attrs)
            kwargs = type_attrs

        for k, v in kwargs.items():
            if k.startswith('_'):
                _log_debug("ignoring '%s' because of leading underscore", k)
                continue

            if k in ('protocol', 'prot', 'p'):
                Attributes.prot = v
                _log_debug("setting prot=%r", v)

            elif k in ('voa', 'validate_on_assignment'):
                Attributes.validate_on_assignment = v
                _log_debug("setting voa=%r", v)

            elif k in ('parser', 'cast'):
                setattr(Attributes, k, staticmethod(v))
                _log_debug("setting %s=%r", k, v)

            elif k in ('sanitize', 'sanitizer'):
                setattr(Attributes, 'sanitizer', staticmethod(v))
                _log_debug("setting %s=%r as sanitizer=%r", k, v, v)

            elif k in ("doc", "appinfo"):
                setattr(Annotations, k, v)
                _log_debug("setting Annotations.%s=%r", k, v)

            elif k in ('primary_key', 'pk'):
                setattr(Attributes, 'primary_key', v)
                Attributes.sqla_column_args[-1]['primary_key'] = v
                _log_debug("setting primary_key=%r", v)

            elif k in ('protocol_attrs', 'prot_attrs', 'pa'):
                setattr(Attributes, 'prot_attrs', _decode_pa_dict(v))
                _log_debug("setting prot_attrs=%r", v)

            elif k in ('foreign_key', 'fk'):
                from sqlalchemy.schema import ForeignKey
                t, d = Attributes.sqla_column_args
                fkt = (ForeignKey(v), )
                new_v = (t + fkt, d)
                Attributes.sqla_column_args = new_v
                _log_debug("setting sqla_column_args=%r", new_v)

            elif k in ('autoincrement', 'onupdate', 'server_default'):
                Attributes.sqla_column_args[-1][k] = v
                _log_debug("adding %s=%r to Attributes.sqla_column_args", k, v)

            elif k == 'values_dict':
                assert not 'values' in v, "`values` and `values_dict` can't be" \
                                          "specified at the same time"

                if not isinstance(v, dict):
                    # our odict has one nasty implicit behaviour: setitem on
                    # int keys is treated as array indexes, not dict keys. so
                    # dicts with int indexes can't work with odict. so we use
                    # the one from stdlib
                    v = OrderedDict(v)

                Attributes.values = v.keys()
                Attributes.values_dict = v
                _log_debug("setting values=%r, values_dict=%r",
                           Attributes.values, Attributes.values_dict)

            elif k == 'exc_table':
                Attributes.exc_table = v
                Attributes.exc_db = v
                _log_debug("setting exc_table=%r, exc_db=%r", v, v)

            elif k == 'max_occurs' and v in ('unbounded', 'inf', float('inf')):
                new_v = decimal.Decimal('inf')
                setattr(Attributes, k, new_v)
                _log_debug("setting max_occurs=%r", new_v)

            elif k == 'type_name':
                Attributes._explicit_type_name = True
                _log_debug("setting _explicit_type_name=True because "
                           "we have 'type_name'")

            else:
                setattr(Attributes, k, v)
                _log_debug("setting %s=%r", k, v)

        return (cls.__name__, (cls, ), cls_dict)
Example #50
0
 def __init__(self):
     self.elements = odict()
     self.types = odict()