Changes in trunk/lib/syck/loaders.py [25:18]
- File:
-
- 1 edited
-
trunk/lib/syck/loaders.py (modified) (11 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/lib/syck/loaders.py
r25 r18 1 """2 syck.loaders is a high-level wrapper for the Syck YAML parser.3 Do not use it directly, use the module 'syck' instead.4 """5 1 6 2 # Python 2.2 compatibility … … 25 21 import _syck 26 22 27 import sys,re23 import re 28 24 29 25 __all__ = ['GenericLoader', 'Loader', … … 31 27 32 28 class GenericLoader(_syck.Parser): 33 """34 GenericLoader constructs primitive Python objects from YAML documents.35 """36 29 37 30 def load(self): 38 """39 Loads a YAML document from the source and return a native Python40 object. On EOF, returns None and set the eof attribute on.41 """42 31 node = self.parse() 43 32 if self.eof: … … 61 50 value_object = self._convert(node.value[key_node], 62 51 node_to_object) 52 if key_object in value: 53 value = None 54 break 63 55 try: 64 if key_object in value:65 value = None66 break67 56 value[key_object] = value_object 68 57 except TypeError: … … 72 61 value = [] 73 62 for key_node in node.value: 74 key_object = self ._convert(key_node, node_to_object)63 key_object = self_convert(key_node, node_to_object) 75 64 value_object = self._convert(node.value[key_node], 76 65 node_to_object) … … 82 71 83 72 def construct(self, node): 84 """Constructs a Python object by the given node."""85 73 return node.value 86 74 87 75 class Merge: 88 """Represents the merge key '<<'."""89 76 pass 90 77 91 78 class Default: 92 """Represents the default key '='."""93 79 pass 94 80 95 81 class Loader(GenericLoader): 96 """97 Loader constructs native Python objects from YAML documents.98 """99 82 100 83 inf_value = 1e300000 101 84 nan_value = inf_value/inf_value 102 85 86 ymd_expr = re.compile(r'(?P<year>\d\d\d\d)-(?P<month>\d\d)-(?P<day>\d\d)') 103 87 timestamp_expr = re.compile(r'(?P<year>\d\d\d\d)-(?P<month>\d\d)-(?P<day>\d\d)' 104 88 r'(?:' … … 111 95 default_key = Default() 112 96 113 non_ascii = [] 114 for i in range(256): 115 ch = chr(i) 116 if ch.isalnum(): 117 non_ascii.append(ch) 118 else: 119 non_ascii.append('_') 120 non_ascii = ''.join(non_ascii) 121 122 python_bools = {'True': True, 'False': False} 123 124 class python_class: 125 pass 126 127 def find_constructor(self, node): 128 """ 129 Returns the contructor for generating a Python object for the given 130 node. 131 132 The node tags are mapped to constructors by the following rule: 133 134 Tag Constructor 135 --- ----------- 136 tag:yaml.org,2002:type construct_type 137 tag:python.yaml.org,2002:type construct_python_type 138 x-private:type construct_private_type 139 tag:domain.tld,2002:type construct_domain_tld_2002_type 140 141 See the method code for more details. 142 """ 143 parts = [] 144 if node.tag: 145 parts = node.tag.split(':') 146 if parts: 147 if parts[0] == 'tag': 148 parts.pop(0) 149 if parts: 150 if parts[0] == 'yaml.org,2002': 151 parts.pop(0) 152 elif parts[0] == 'python.yaml.org,2002': 153 parts[0] = 'python' 154 elif parts[0] == 'x-private': 155 parts[0] = 'private' 156 parts = [part.translate(self.non_ascii) for part in parts] 157 while parts: 158 method = 'construct_'+'_'.join(parts) 159 if hasattr(self, method): 160 return getattr(self, method) 161 parts.pop() 97 def __init__(self, *args, **kwds): 98 super(Loader, self).__init__(*args, **kwds) 99 self.tags = {} 100 self.add_builtin_types() 101 102 def add_builtin_types(self): 103 self.add_builtin_type('null', lambda node: None) 104 self.add_builtin_type('bool#yes', lambda node: True) 105 self.add_builtin_type('bool#no', lambda node: False) 106 self.add_builtin_type('float#fix', lambda node: float(node.value)) 107 self.add_builtin_type('float#exp', lambda node: float(node.value)) 108 self.add_builtin_type('float#base60', 'construct_base60_float') 109 self.add_builtin_type('float#inf', lambda node: self.inf_value) 110 self.add_builtin_type('float#neginf', lambda node: -self.inf_value) 111 self.add_builtin_type('float#nan', lambda node: self.nan_value) 112 self.add_builtin_type('int', lambda node: int(node.value)) 113 self.add_builtin_type('int#hex', lambda node: int(node.value, 16)) 114 self.add_builtin_type('int#oct', lambda node: int(node.value, 8)) 115 self.add_builtin_type('int#base60', 'construct_base60_int') 116 self.add_builtin_type('binary', lambda node: node.value.decode('base64')) 117 self.add_builtin_type('timestamp#ymd', 'construct_timestamp') 118 self.add_builtin_type('timestamp#iso8601', 'construct_timestamp') 119 self.add_builtin_type('timestamp#spaced', 'construct_timestamp') 120 self.add_builtin_type('timestamp', 'construct_timestamp') 121 self.add_builtin_type('merge', 'construct_merge') 122 self.add_builtin_type('default', 'construct_default') 123 self.add_builtin_type('omap', 'construct_omap') 124 self.add_builtin_type('pairs', 'construct_pairs') 125 self.add_builtin_type('set', 'construct_set') 126 127 def add_type(self, type_tag, constuctor): 128 self.tags[type_tag] = constructor 129 130 def add_domain_type(self, domain, type_tag, constructor): 131 self.tags['tag:%s:%s' % (domain, type_tag)] = constructor 132 133 def add_builtin_type(self, type_tag, constructor): 134 self.tags['tag:yaml.org,2002:'+type_tag] = constructor 135 136 def add_python_type(self, type_tag, constructor): 137 self.tags['tag:python.yaml.org,2002:'+type_tag] = constructor 138 139 def add_private_type(self, type_tag, constructor): 140 self.tags['x-private:'+type_tag] = constructor 162 141 163 142 def construct(self, node): 164 """Constructs a Python object by the given node."""165 143 if node.kind == 'map' and self.merge_key in node.value: 166 144 self.merge_maps(node) 167 constructor = self.find_constructor(node) 168 if constructor: 145 if node.tag in self.tags: 146 constructor = self.tags[node.tag] 147 if isinstance(constructor, str): 148 constructor = getattr(self, constructor) 169 149 return constructor(node) 170 150 else: 171 151 return node.value 172 152 173 def construct_null(self, node): 174 return None 175 176 def construct_bool_yes(self, node): 177 return True 178 179 def construct_bool_no(self, node): 180 return False 181 182 def construct_numeric_base60(self, num_type, node): 153 def construct_base60_float(self, node): 154 return self.construct_base60(float, node) 155 156 def construct_base60_int(self, node): 157 return self.construct_base60(int, node) 158 159 def construct_base60(self, num_type, node): 183 160 digits = [num_type(part) for part in node.value.split(':')] 184 161 digits.reverse() … … 189 166 base *= 60 190 167 return value 191 192 def construct_int(self, node):193 return int(node.value)194 195 def construct_int_hex(self, node):196 return int(node.value, 16)197 198 def construct_int_oct(self, node):199 return int(node.value, 8)200 201 def construct_int_base60(self, node):202 return self.construct_numeric_base60(int, node)203 204 def construct_float(self, node):205 return float(node.value)206 construct_float_fix = construct_float207 construct_float_exp = construct_float208 209 def construct_float_base60(self, node):210 return self.construct_numeric_base60(float, node)211 212 def construct_float_inf(self, node):213 return self.inf_value214 215 def construct_float_neginf(self, node):216 return -self.inf_value217 218 def construct_float_nan(self, node):219 return self.nan_value220 221 def construct_binary(self, node):222 return node.value.decode('base64')223 168 224 169 def construct_timestamp(self, node): … … 238 183 diff = datetime.timedelta(hours=values['zhour'], minutes=values['zminute']) 239 184 return stamp-diff 240 construct_timestamp_ymd = construct_timestamp241 construct_timestamp_iso8601 = construct_timestamp242 construct_timestamp_spaced = construct_timestamp243 185 244 186 def construct_merge(self, node): … … 275 217 return sets.Set(node.value) 276 218 277 def construct_python_none(self, node): 278 return None 279 280 def construct_python_bool(self, node): 281 return self.python_bools[node.value] 282 283 def construct_python_int(self, node): 284 return int(node.value) 285 286 def construct_python_long(self, node): 287 return long(node.value) 288 289 def construct_python_float(self, node): 290 return float(node.value) 291 292 def construct_python_str(self, node): 293 return str(node.value) 294 295 def construct_python_unicode(self, node): 296 return unicode(node.value, 'utf-8') 297 298 def construct_python_list(self, node): 299 return node.value 300 301 def construct_python_tuple(self, node): 302 return tuple(node.value) 303 304 def construct_python_dict(self, node): 305 return node.value 306 307 def find_python_object(self, node): 308 full_name = node.tag.split(':')[3] 309 parts = full_name.split('.') 310 object_name = parts.pop() 311 module_name = '.'.join(parts) 312 if not module_name: 313 module_name = '__builtin__' 314 else: 315 __import__(module_name) 316 return getattr(sys.modules[module_name], object_name) 317 318 def find_python_state(self, node): 319 if node.kind == 'seq': 320 args = node.value 321 kwds = {} 322 state = {} 323 else: 324 args = node.value.get('args', []) 325 kwds = node.value.get('kwds', {}) 326 state = node.value.get('state', {}) 327 return args, kwds, state 328 329 def set_python_state(self, object, state): 330 if hasattr(object, '__setstate__'): 331 object.__setstate__(state) 332 else: 333 slotstate = {} 334 if isinstance(state, tuple) and len(state) == 2: 335 state, slotstate = state 336 if hasattr(object, '__dict__'): 337 object.__dict__.update(state) 338 elif state: 339 slotstate.update(state) 340 for key, value in slotstate.items(): 341 setattr(object, key, value) 342 343 def construct_python_name(self, node): 344 return self.find_python_object(node) 345 346 def construct_python_object(self, node): 347 cls = self.find_python_object(node) 348 if type(cls) is type(self.python_class): 349 if hasattr(cls, '__getnewargs__'): 350 object = cls() 351 else: 352 object = self.python_class() 353 object.__class__ = cls 354 else: 355 object = cls.__new__(cls) 356 self.set_python_state(object, node.value) 357 return object 358 359 def construct_python_new(self, node): 360 cls = self.find_python_object(node) 361 args, kwds, state = self.find_python_state(node) 362 if type(cls) is type(self.python_class): 363 object = cls(*args, **kwds) 364 else: 365 object = cls.__new__(cls, *args, **kwds) 366 self.set_python_state(object, state) 367 return object 368 369 def construct_python_apply(self, node): 370 constructor = self.find_python_object(node) 371 args, kwds, state = self.find_python_state(node) 372 object = constructor(*args, **kwds) 373 self.set_python_state(object, state) 374 return object 375 376 def parse(source, Loader=Loader, **parameters): 219 def parse(source): 377 220 """Parses 'source' and returns the root of the 'Node' graph.""" 378 loader = Loader(source , **parameters)221 loader = Loader(source) 379 222 return loader.parse() 380 223 381 def load(source , Loader=Loader, **parameters):224 def load(source): 382 225 """Parses 'source' and returns the root object.""" 383 loader = Loader(source , **parameters)226 loader = Loader(source) 384 227 return loader.load() 385 228 386 def parse_documents(source , Loader=Loader, **parameters):387 """Iterates over 'source' and yields the root 'Node' foreach document."""388 loader = Loader(source , **parameters)229 def parse_documents(source): 230 """Iterates over 'source' and yields the root node of each document.""" 231 loader = Loader(source) 389 232 while True: 390 233 node = loader.parse() … … 393 236 yield node 394 237 395 def load_documents(source , Loader=Loader, **parameters):396 """Iterates over 'source' and yields the root object foreach document."""397 loader = Loader(source , **parameters)238 def load_documents(source): 239 """Iterates over 'source' and yields the root object of each document.""" 240 loader = Loader(source) 398 241 while True: 399 242 object = loader.load()
Note: See TracChangeset
for help on using the changeset viewer.
