Package gensaschema :: Module _symbols
[frames] | no frames]

Source Code for Module gensaschema._symbols

  1  # -*- coding: ascii -*- 
  2  r""" 
  3  =================== 
  4   Symbol management 
  5  =================== 
  6   
  7  Symbol management. 
  8   
  9  :Copyright: 
 10   
 11   Copyright 2010 - 2017 
 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__:  # pragma: no branch 
 30      # pylint: disable = redefined-builtin 
 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 keyword as _keyword 
 36  import operator as _op 
 37  import weakref as _weakref 
 38   
 39  from . import _util 
 40   
 41   
42 -class SymbolException(Exception):
43 """ Symbol error """
44 45
46 -class Symbols(object):
47 """ 48 Symbol table 49 50 :IVariables: 51 `_symbols` : ``dict`` 52 Symbols 53 54 `imports` : `_Imports` 55 Import container 56 57 `types` : `_Types` 58 Type container 59 """ 60
61 - def __init__(self, symbols=None, imports=None):
62 """ 63 Initialization 64 65 :Parameters: 66 `symbols` : ``dict`` 67 Initial symbols 68 """ 69 self._symbols = {} 70 defaults = dict( 71 sa="_sa", # SQLAlchemy shortname 72 meta="m", # MetaData shortname 73 table="T", # Table shortname 74 type="t", # Type module shortname 75 column="C", # Column shortname 76 default="D", # DefaultClause shortname 77 pk="PrimaryKey", # PrimaryKey function name 78 fk="ForeignKey", # ForeignKey function name 79 uk="Unique", # UniqueKey function name 80 constraints=( # constraint function module 81 __name__.rsplit('.', 1)[0] + '.constraints' 82 ), 83 ) 84 self.imports = _Imports(imports=imports) 85 self.types = _Types(_weakref.proxy(self)) 86 if symbols is None: 87 symbols = {} 88 else: 89 symbols = dict(symbols) 90 for key, value in defaults.items(): 91 symbols.setdefault(key, value) 92 for name, symbol in dict(symbols).items(): 93 self[name] = symbol
94
95 - def __delitem__(self, name):
96 """ Remove symbol entry if available """ 97 try: 98 del self._symbols[name] 99 except KeyError: 100 pass
101
102 - def __setitem__(self, name, symbol):
103 """ 104 Set symbol table entry 105 106 :Parameters: 107 `name` : ``str`` 108 Symbol identifier 109 110 `symbol` : ``str`` 111 Symbol 112 113 :Exceptions: 114 - `SymbolException` : Symbol could not be set because of some 115 conflict 116 """ 117 if _util.py2 and not isinstance(name, unicode): # pragma: no cover 118 name = str(name).decode('ascii') 119 if _keyword.iskeyword(symbol): 120 raise SymbolException( 121 "Cannot use keyword %r as symbol" % (symbol,) 122 ) 123 elif symbol in list(self._symbols.values()): 124 if name in self._symbols and self._symbols[name] != symbol: 125 raise SymbolException("Symbol conflict: %r" % (symbol,)) 126 elif name in self._symbols and self._symbols[name] != symbol: 127 raise SymbolException("Symbol identifier conflict: %r" % (name,)) 128 self._symbols[name] = symbol
129
130 - def __getitem__(self, name):
131 """ 132 Get symbol table entry 133 134 :Parameters: 135 `name` : ``str`` 136 Symbol identifier 137 138 :Return: The symbol 139 :Rtype: ``str`` 140 141 :Exceptions: 142 - `KeyError` : Symbol not found 143 """ 144 if _util.py2 and not isinstance(name, unicode): 145 name = str(name).decode('ascii') 146 return self._symbols[name]
147
148 - def __contains__(self, name):
149 """ 150 Check symbol table entry 151 152 :Parameters: 153 `name` : ``str`` 154 Symbol identifier 155 156 :Return: The symbol 157 :Rtype: ``str`` 158 159 :Exceptions: 160 - `KeyError` : Symbol not found 161 """ 162 if _util.py2 and not isinstance(name, unicode): 163 name = str(name).decode('ascii') 164 return name in self._symbols
165
166 - def __iter__(self):
167 """ 168 Make item iterator 169 170 :Return: The iterator 171 :Rtype: iterable 172 """ 173 return iter(list(self._symbols.items()))
174 175
176 -class _Types(object):
177 """ 178 Type container 179 180 :IVariables: 181 `_types` : ``dict`` 182 Type map 183 184 `_symbols` : `Symbols` 185 Symbol table 186 """ 187
188 - def __init__(self, symbols):
189 """ 190 Initialization 191 192 :Parameters: 193 `symbols` : `Symbols` 194 Symbol table 195 """ 196 self._types = {} 197 self._symbols = symbols 198 self.instance_repr = {} 199 self.defines = []
200
201 - def __setitem__(self, class_, symbol):
202 """ 203 Set type 204 205 :Parameters: 206 `class_` : ``type`` 207 Type to match 208 209 `symbol` : ``str`` 210 Type module symbol 211 212 :Exceptions: 213 - `SymbolException` : Type conflict 214 """ 215 if class_ in self._types: 216 if self._types[class_] != symbol: 217 raise SymbolException("Type conflict: %r" % (symbol,)) 218 else: 219 self._types[class_] = symbol
220
221 - def resolve(self, type_, dialect):
222 """ 223 Resolve type to module symbol 224 225 :Parameters: 226 `type_` : ``object`` 227 Type to resolve 228 229 `dialect` : ``str`` 230 Dialect name 231 232 :Return: Resolved symbol 233 :Rtype: ``str`` 234 235 :Exceptions: 236 - `SymbolException` : Type could not be resolved 237 """ 238 if type_.__class__ in self._types: 239 return self._symbols[self._types[type_.__class__]] 240 for class_, symbol in self._types.items(): 241 if isinstance(type_, class_): 242 return self._symbols[symbol] 243 244 mod = type_.__module__ 245 if mod.startswith('sqlalchemy.'): 246 mod = '.'.join(mod.split('.')[:3]) 247 if mod == 'sqlalchemy.dialects.%s' % dialect: 248 return self._symbols['type'] 249 else: 250 try: 251 _load_dotted('sqlalchemy.dialects.%s.%s' % ( 252 dialect, type_.__class__.__name__ 253 )) 254 return self._symbols['type'] 255 except ImportError: 256 try: 257 _load_dotted('sqlalchemy.types.%s' % ( 258 type_.__class__.__name__, 259 )) 260 return "%s.types" % (self._symbols['sa'],) 261 except ImportError: 262 pass 263 raise SymbolException( 264 "Don't know how to address type %r" % (type_,) 265 )
266 267
268 -class _Imports(object):
269 """ 270 Import table 271 272 :IVariables: 273 `_imports` : ``list`` 274 Import list 275 """ 276
277 - def __init__(self, imports=None):
278 """ Initialization """ 279 self._imports = list(imports or ())
280
281 - def __contains__(self, name):
282 """ Check if name is in imports """ 283 for key, _ in self._imports: 284 if key == name: 285 return True 286 return False
287
288 - def __setitem__(self, name, import_):
289 """ 290 Set import 291 292 :Parameters: 293 `name` : ``str`` 294 Symbolic name (to support import uniqueness) 295 296 `import_` : ``str`` 297 Import statement 298 299 :Exceptions: 300 - `SymbolException` : Import conflict 301 """ 302 if _util.py2 and not isinstance(name, unicode): # pragma: no cover 303 name = str(name).decode('ascii') 304 imports = dict(self._imports) 305 if name in imports: 306 if imports[name] != import_: 307 raise SymbolException("Import conflict: %r: %r vs. %r" % ( 308 name, imports[name], import_ 309 )) 310 else: 311 self._imports.append((name, import_))
312
313 - def __iter__(self):
314 """ 315 Make iterator over the import statements 316 317 :Return: The iterator 318 :Rtype: iterable 319 """ 320 return iter(map(_op.itemgetter(1), self._imports))
321 322
323 -def _load_dotted(name):
324 """ 325 Load a dotted name 326 327 (Stolen from wtf-server) 328 329 The dotted name can be anything, which is passively resolvable 330 (i.e. without the invocation of a class to get their attributes or 331 the like). 332 333 :Parameters: 334 `name` : ``str`` 335 The dotted name to load 336 337 :Return: The loaded object 338 :Rtype: any 339 340 :Exceptions: 341 - `ImportError` : A module in the path could not be loaded 342 """ 343 components = name.split('.') 344 path = [components.pop(0)] 345 obj = __import__(path[0]) 346 while components: 347 comp = components.pop(0) 348 path.append(comp) 349 try: 350 obj = getattr(obj, comp) 351 except AttributeError: 352 __import__('.'.join(path)) 353 try: 354 obj = getattr(obj, comp) 355 except AttributeError: 356 raise ImportError('.'.join(path)) 357 return obj
358