~gt-launchpad/ladon/test

« back to all changes in this revision

Viewing changes to frameworks/python/src/ladon/types/typemanager.py

  • Committer: Tamás Gulácsi
  • Date: 2012-03-03 20:27:17 UTC
  • mfrom: (40.1.35 ladon)
  • Revision ID: gt-dev-ladon@gthomas.eu-20120303202717-w0nal1tximalllmj
merged upstream

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# vim: se noet:
2
1
import inspect,copy
3
2
from ladon.exceptions.types import *
4
3
from ladon.types.ladontype import LadonType
5
4
from ladon.types.attachment import attachment
 
5
from ladon.compat import PORTABLE_STRING_TYPES
6
6
 
7
7
def get_userdef_class_attributes(cls,exclude_methods=True):
8
8
        base_attrs = dir(type('dummy', (object,), {}))
22
22
        service depends on. It also keeps track of the parse order so it is possible
23
23
        to create service type descriptors in the right order. This will prevent that
24
24
        an array of some type is not defined before the type itself.
25
 
 
 
25
        
26
26
                type_dict: holds all the parsed class-types that are derived from LadonType
27
27
                type_order: holds all parsed types in the correct parse order
28
28
                primitive_list: A list of all the primitive types a service depends on
29
 
 
 
29
        
30
30
        Primitive types are defined as all classes that don't inherit LadonType
31
31
        """
32
 
 
 
32
        
33
33
        global_type_dict = {}
34
 
 
 
34
        
35
35
        def __init__(self):
36
36
                self.type_dict = {}
37
37
                self.type_order = []
40
40
                self.has_dicts = False
41
41
                self.type_parse_order = 0
42
42
 
43
 
 
 
43
        
44
44
        def add_primitive_type(self,prim):
45
45
                if not self.primitive_list.count(prim):
46
46
                        self.primitive_list += [prim]
47
 
 
 
47
        
48
48
        def analyze_class(self,cls):
49
49
                try:
50
50
                        inspect.getmro(cls).count(LadonType)
61
61
                type_container = self.type_dict[type_key]
62
62
                class_attrs = get_userdef_class_attributes(cls)
63
63
                for attr in class_attrs:
64
 
                        if '__slots__' == attr:
65
 
                                continue
66
64
                        attr_val = getattr(cls,attr)
67
65
                        array_attr = False
 
66
                        attr_props = {}
68
67
                        if type(attr_val)==list and len(attr_val)==1:
69
68
                                attr_val = attr_val[0]
70
69
                                array_attr = True
71
70
                                self.has_lists = True
72
 
                        if type(attr_val)!=type:
73
 
                                raise NeedToDefineParseTimeException("class attributes on LadonTypes must be defined as types, lists or arrays (%r %s)" % (attr_val, type(attr_val)))
 
71
                        elif type(attr_val)==dict:
 
72
                                # Dictionary type definitions for LadonTypes
 
73
                                # New feature in Ladon 0.6.6
 
74
                                try:
 
75
                                        temp_attr_val = attr_val['type']
 
76
                                except AttributeError:
 
77
                                        raise NeedToDefineParseTimeException('Dictionary type definitions must contain the "type" key.\nclass: %s\nattr: %s' % (cls.__name__,attr))
 
78
                                ok_default_types = []
 
79
                                if 'nullable' in attr_val:
 
80
                                        if type(attr_val['nullable'])!=bool:
 
81
                                                raise NeedToDefineParseTimeException('Dictionary type definition nullable must be a boolean value.\nclass: %s\nattr: %s' % (cls.__name__,attr))
 
82
                                        attr_props['nullable'] = attr_val['nullable']
 
83
                                        if attr_props['nullable']:
 
84
                                                ok_default_types += [type(None)]
 
85
                                                
 
86
                                if 'doc' in attr_val:
 
87
                                        temp_doc = attr_val['doc']
 
88
                                        if type(temp_doc) in PORTABLE_STRING_TYPES:
 
89
                                                attr_props['doc'] = [temp_doc]
 
90
                                        elif type(temp_doc)==list:
 
91
                                                attr_props['doc'] = []
 
92
                                                for doc_line in temp_doc:
 
93
                                                        if type(doc_line) in PORTABLE_STRING_TYPES:
 
94
                                                                attr_props['doc'] += [doc_line]
 
95
                                                                
 
96
                                if 'default' in attr_val:
 
97
                                        ok_default_types += [temp_attr_val]
 
98
                                        if type(attr_val['default']) not in ok_default_types:
 
99
                                                raise NeedToDefineParseTimeException('Default value does not match the attribute type.\nclass: %s\nattr: %s' % (cls.__name__,attr))
 
100
                                        attr_props['default'] = attr_val['default']
 
101
                                        has_default = True
 
102
                                        
 
103
                                if 'filters' in attr_val:
 
104
                                        filters = attr_val['filters']
 
105
                                        for filter_type in ['incoming_raw','incoming','outgoing','outgoing_raw']:
 
106
                                                if filter_type in filters and hasattr(filters[filter_type],'__iter__') and len(filters[filter_type]):
 
107
                                                        # Add attribute filter functions
 
108
                                                        if 'filters' not in attr_props:
 
109
                                                                attr_props['filters'] = {}
 
110
                                                        attr_props['filters'][filter_type] = list(attr_val['filters'][filter_type])
 
111
                                                        
 
112
                                attr_val = temp_attr_val
 
113
                        elif type(attr_val)!=type:
 
114
                                raise NeedToDefineParseTimeException("class attributes on LadonTypes must be defined as types, lists.\nclass: %s\nattr: %s" % (cls.__name__,attr))
74
115
                        if inspect.getmro(attr_val).count(LadonType):
75
116
                                self.analyze_class(attr_val)
76
117
                        else:
82
123
                                if not self.type_order.count([attr_val]):
83
124
                                        self.type_order += [[attr_val]]
84
125
                                attr_val = [attr_val]
85
 
                        type_container['attributes'] += [(attr,attr_val)]
 
126
                        attr_props['type'] = attr_val
 
127
                        type_container['attributes'] += [(attr,attr_val,attr_props)]
86
128
                if not type_key in self.global_type_dict:
87
129
                        self.global_type_dict[type_key] = copy.deepcopy(type_container)
88
130
                type_container['parse_order'] = self.type_parse_order
98
140
                                raise NeedToDefineParseTimeException("Only one element is allowed when defining ladon arrays")
99
141
                        if type(param[0])!=type:
100
142
                                raise NeedToDefineParseTimeException("Only types are allowed as list-element when defining an array")
101
 
 
 
143
                        
102
144
                        if inspect.getmro(param[0]).count(LadonType):
103
145
                                self.analyze_class(param[0])
104
146
                        else: