This is a simple piece of code that emits YAML (YamlAintMarkupLanguage) from Python:

   1 import types
   2 from types import DictType, ListType, TupleType, InstanceType
   3 import re
   4 
   5 def dump(data):
   6     return "---" + _dump(data,"\n") + "\n"
   7 
   8 def _dump(data, indent):
   9     if (data is None):
  10         return ' ~'
  11     if type(data) is DictType:
  12         return dumpDict(data, indent)
  13     elif type(data) in [ListType, TupleType]:
  14         return dumpList(data, indent)
  15     elif type(data) is InstanceType:
  16         if hasMethod(data, 'to_yaml'):
  17             return _dump(data.to_yaml(), indent)
  18         else:
  19             return dumpDict(data.__dict__, indent)
  20     else:
  21         return dumpScalar(data, indent)
  22 
  23 def dumpDict(data, indent):
  24     output = ""
  25     keys = data.keys()
  26     keys.sort()
  27     for key in keys:
  28         output += "%s%s:%s" % \
  29             (indent, quote(key), _dump(data[key], indent+"    "))
  30     return output
  31 
  32 def dumpList(data, indent):
  33     output = ""
  34     for item in data:
  35         output += "%s-%s" % \
  36             (indent, _dump(item, indent+"    "))
  37     return output
  38 
  39 def quote(data):
  40     single = "'"
  41     double = '"'
  42     quote = ''
  43     if (re.search(r"\t", data) or data[0] == single):
  44         data = `data`[1:-1]
  45         quote = double
  46     if (re.search(r'[-:]', data) or re.search(r'(\d\.){2}', data)):
  47         quote = single
  48     return "%s%s%s" % (quote, data, quote)
  49 
  50 def dumpScalar(data, indent):
  51     data = str(data)
  52     lines = data.splitlines()
  53     if len(lines) == 1:
  54         return " " + quote(data)
  55     return dumpMultiLineScalar(lines, indent)
  56 
  57 def dumpMultiLineScalar(lines, indent):
  58     output = " |"
  59     for line in lines:
  60         output += indent + line
  61     return output
  62 
  63 def hasMethod(object, method_name):
  64     klass = object.__class__
  65     if not hasattr(klass, method_name):
  66         return 0
  67     method = getattr(klass, method_name)
  68     if not callable(method):
  69         return 0
  70     return 1

Update on the code above--this code is somewhat alpha and isn't strictly YAML-compliant, but it should be usable for dumping typical Python objects and structures. If folks want to try it out, I'd love to get some feedback on it. You can grab the code by editing the Wiki page, then put the code somewhere in your Python path, and then try it out by calling the "dump" method on some Python object or variable. I think it can be a pretty nice debugging tool. -- SteveHowell

PythonYamlEmitter (last edited 2008-03-04 08:33:07 by localhost)