1
2 r"""
3 ====================================
4 Type inspection and representation
5 ====================================
6
7 Type inspection and representation.
8
9 :Copyright:
10
11 Copyright 2010 - 2016
12 Andr\xe9 Malo or his licensors, as applicable
13
14 :License:
15
16 Licensed under the Apache License, Version 2.0 (the "License");
17 you may not use this file except in compliance with the License.
18 You may obtain a copy of the License at
19
20 http://www.apache.org/licenses/LICENSE-2.0
21
22 Unless required by applicable law or agreed to in writing, software
23 distributed under the License is distributed on an "AS IS" BASIS,
24 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
25 See the License for the specific language governing permissions and
26 limitations under the License.
27
28 """
29 if __doc__:
30
31 __doc__ = __doc__.encode('ascii').decode('unicode_escape')
32 __author__ = r"Andr\xe9 Malo".encode('ascii').decode('unicode_escape')
33 __docformat__ = "restructuredtext en"
34
35 import inspect as _inspect
36
37 import sqlalchemy as _sa
38
39
40 -class Type(object):
41 """
42 Type container
43
44 :IVariables:
45 `_ctype` : SA type
46 Column type
47
48 `_dialect` : ``str``
49 Dialect name
50
51 `_symbols` : ``Symbols``
52 Symbol table
53 """
54
55 - def __init__(self, ctype, dialect_name, symbols):
56 """
57 Initialization
58
59 :Parameters:
60 `ctype` : SA type
61 Column type
62
63 `dialect_name` : ``str``
64 Dialect name
65
66 `symbols` : ``Symbols``
67 Symbol table
68 """
69 self._ctype = ctype
70 self._dialect = dialect_name
71 self._symbols = symbols
72
73 @classmethod
75 """
76 Construct by SA column
77
78 :Parameters:
79 `column` : SA column
80 SA column
81
82 :Return: New Type instance
83 :Rtype: `Type`
84 """
85 return cls(
86 column.type,
87 column.table.metadata.bind.dialect.name,
88 symbols,
89 )
90
92 """
93 Make string representation
94
95 :Return: The string representation
96 :Rtype: ``str``
97 """
98 mod = self._symbols.types.resolve(self._ctype, self._dialect)
99 params = []
100 try:
101 spec = _inspect.getargspec(self._ctype.__init__)
102 except TypeError:
103 pass
104 else:
105 defaults = dict(zip(spec[0][::-1], (spec[3] or ())[::-1]))
106 kwds = False
107 for arg in spec[0][1:]:
108 value = getattr(self._ctype, arg)
109 if arg in defaults and defaults[arg] == value:
110 kwds = True
111 continue
112 if isinstance(value, _sa.types.TypeEngine):
113 rvalue = repr(
114 self.__class__(value, self._dialect, self._symbols)
115 )
116 else:
117 rvalue = repr(value)
118 if kwds:
119 params.append('%s=%s' % (arg, rvalue))
120 else:
121 params.append(rvalue)
122 if not kwds and spec[1] is not None:
123 if _find_class(self._ctype, '__init__') is not \
124 _sa.types.TypeEngine:
125 params.extend(list(
126 map(repr, getattr(self._ctype, spec[1]))
127 ))
128
129 params = ', '.join(params)
130 if params:
131 params = "(%s)" % (params,)
132 return "%s.%s%s" % (mod, self._ctype.__class__.__name__, params)
133
136 """
137 Find class where a method is defined
138
139 :Parameters:
140 `first_cls` : type
141 Class to start with
142
143 `name` : ``str``
144 Method name
145
146 :Return: class or ``None``
147 :Rtype: ``type``
148 """
149 if not isinstance(first_cls, type):
150 first_cls = first_cls.__class__
151
152 for cls in _inspect.getmro(first_cls):
153 if name in cls.__dict__:
154 return cls
155 return None
156