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 import itertools as _it
37
38 import sqlalchemy as _sa
39
40
41 -class Type(object):
42 """
43 Type container
44
45 :IVariables:
46 `_ctype` : SA type
47 Column type
48
49 `_dialect` : ``str``
50 Dialect name
51 """
52
53 - def __init__(self, ctype, dialect_name, symbols):
54 """
55 Initialization
56
57 :Parameters:
58 `ctype` : SA type
59 Column type
60
61 `dialect_name` : ``str``
62 Dialect name
63 """
64 self._ctype = ctype
65 self._dialect = dialect_name
66 self._symbols = symbols
67
68 @classmethod
70 """
71 Construct by SA column
72
73 :Parameters:
74 `column` : SA column
75 SA column
76
77 :Return: New Type instance
78 :Rtype: `Type`
79 """
80 return cls(
81 column.type,
82 column.table.metadata.bind.dialect.name,
83 symbols,
84 )
85
87 """
88 Make string representation
89
90 :Return: The string representation
91 :Rtype: ``str``
92 """
93 mod = self._symbols.types.resolve(self._ctype, self._dialect)
94 params = []
95 try:
96 spec = _inspect.getargspec(self._ctype.__init__)
97 except TypeError:
98 pass
99 else:
100 defaults = dict(_it.izip(spec[0][::-1], (spec[3] or ())[::-1]))
101 kwds = False
102 for arg in spec[0][1:]:
103 value = getattr(self._ctype, arg)
104 if arg in defaults and defaults[arg] == value:
105 kwds = True
106 continue
107 if isinstance(value, _sa.types.TypeEngine):
108 rvalue = repr(
109 self.__class__(value, self._dialect, self._symbols)
110 )
111 else:
112 rvalue = repr(value)
113 if kwds:
114 params.append('%s=%s' % (arg, rvalue))
115 else:
116 params.append(rvalue)
117 if not kwds and spec[1] is not None:
118 if _find_class(self._ctype, '__init__') is not \
119 _sa.types.TypeEngine:
120 params.extend(list(
121 _it.imap(repr, getattr(self._ctype, spec[1]))
122 ))
123
124 params = ', '.join(params)
125 if params:
126 params = "(%s)" % (params,)
127 return "%s.%s%s" % (mod, self._ctype.__class__.__name__, params)
128
131 """
132 Find class where a method is defined
133
134 :Parameters:
135 `first_cls` : type
136 Class to start with
137
138 `name` : ``str``
139 Method name
140
141 :Return: class or ``None``
142 :Rtype: ``type``
143 """
144 for cls in _inspect.getmro(first_cls):
145 if name in cls.__dict__:
146 return cls
147 return None
148