Changes in / [20:30]


Ignore:
Location:
/trunk
Files:
6 added
13 edited

Legend:

Unmodified
Added
Removed
  • /trunk/tests/test_loader.py

    r20 r23  
    136136""" 
    137137 
     138MUTABLE_KEY = """ 
     139? [] 
     140: [] 
     141""" 
     142 
    138143class TestDocuments(test_parser.TestDocuments): 
    139144 
     
    181186 
    182187    def _testFileValues(self, (source, structure)): 
    183         filename = os.tempnam('/tmp', '_syck_test_') 
    184         file(filename, 'wb').write(source) 
    185         try: 
    186             self.assertEqualStructure(syck.parse(file(filename)), structure) 
    187             self.assertEqual(syck.load(file(filename)), structure) 
    188         except: 
    189             os.remove(filename) 
    190             raise 
     188        tempfile = os.tmpfile() 
     189        tempfile.write(source) 
     190        tempfile.seek(0) 
     191        self.assertEqualStructure(syck.parse(tempfile), structure) 
     192        tempfile.seek(0) 
     193        self.assertEqual(syck.load(tempfile), structure) 
     194        tempfile.seek(0) 
    191195 
    192196class TestImplicitScalars(unittest.TestCase): 
     
    202206 
    203207    def testFloat(self): 
    204         self.assertAlmostEqual(syck.load('6.8523015e+5'), 685230.15) 
     208        self.assertEqual(syck.load('6.8523015e+5'), 685230.15) 
    205209        # Syck does not understand '_'. 
    206210        #self.assertAlmostEqual(syck.load('685.230_15e+03'), 685230.15) 
    207211        #self.assertAlmostEqual(syck.load('685_230.15'), 685230.15) 
    208         self.assertAlmostEqual(syck.load('685.23015e+03'), 685230.15) 
    209         self.assertAlmostEqual(syck.load('685230.15'), 685230.15) 
    210         self.assertAlmostEqual(syck.load('190:20:30.15'), 685230.15) 
    211         self.assertEqual(syck.load('-.inf'), -INF) 
    212         self.assertEqual(syck.load('.nan'), NAN) 
     212        self.assertEqual(syck.load('685.23015e+03'), 685230.15) 
     213        self.assertEqual(syck.load('685230.15'), 685230.15) 
     214        self.assertEqual(syck.load('190:20:30.15'), 685230.15) 
     215        self.assertEqual(repr(syck.load('-.inf')), repr(-INF)) 
     216        self.assertEqual(repr(syck.load('.nan')), repr(NAN)) 
    213217 
    214218    def testInteger(self): 
     
    268272        node = syck.parse(ALIASES) 
    269273        values = node.value.values() 
    270         print values 
    271         print id(values[0]) 
    272         print id(values[1]) 
    273274        self.assert_(values[0] is values[1]) 
    274275 
     
    277278        self.assert_(document['foo'] is document['bar']) 
    278279 
     280class TestMutableKey(unittest.TestCase): 
     281 
     282    def testMutableKey(self): 
     283        document = syck.load(MUTABLE_KEY) 
     284        self.assertEqual(type(document), list) 
     285        self.assertEqual(len(document), 1) 
     286        self.assertEqual(type(document[0]), tuple) 
     287        self.assertEqual(len(document[0]), 2) 
     288        self.assertEqual(document[0][0], document[0][1]) 
  • /trunk/tests/test_emitter.py

    r17 r23  
    163163        emitter = _syck.Emitter(StringIO.StringIO(), headless=False) 
    164164        emitter.emit(CYCLE) 
    165         self.assert_('---' in emitter.output.getvalue()) 
     165        self.assert_(emitter.output.getvalue().find('---') != -1) 
    166166        emitter = _syck.Emitter(StringIO.StringIO(), headless=True) 
    167167        emitter.emit(CYCLE) 
    168         self.assert_('---' not in emitter.output.getvalue()) 
     168        self.assert_(emitter.output.getvalue().find('---') == -1) 
    169169 
    170170    def testUseHeader(self): 
    171171        emitter = _syck.Emitter(StringIO.StringIO(), headless=True) 
    172172        emitter.emit(EXAMPLE) 
    173         self.assert_('---' not in emitter.output.getvalue()) 
     173        self.assert_(emitter.output.getvalue().find('---') == -1) 
    174174        emitter = _syck.Emitter(StringIO.StringIO(), use_header=True) 
    175175        emitter.emit(EXAMPLE) 
    176         self.assert_('---' in emitter.output.getvalue()) 
     176        self.assert_(emitter.output.getvalue().find('---') != -1) 
    177177 
    178178    def testExplicitTyping(self): 
     
    235235        document = parser.parse() 
    236236        self.assertEqual(len(document.value), len(TAGS)) 
    237         for index, node in enumerate(document.value): 
     237        for index in range(len(document.value)): 
     238            node = document.value[index] 
    238239            self.assertEqual(node.tag, TAGS[index]) 
    239240 
     
    282283 
    283284 
    284 class TestSyckBugWithTrailingSpace(unittest.TestCase): 
    285  
    286     def testSyckBugWithTrailingSpace(self): 
    287         emitter = _syck.Emitter(StringIO.StringIO()) 
    288         emitter.emit(_syck.Scalar('foo ', tag="tag:yaml.org,2002:str")) 
    289         parser = _syck.Parser(emitter.output.getvalue()) 
    290         self.assertEqual(parser.parse().value, 'foo ') 
    291  
    292  
     285#class TestSyckBugWithTrailingSpace(unittest.TestCase): 
     286# 
     287#    def testSyckBugWithTrailingSpace(self): 
     288#        emitter = _syck.Emitter(StringIO.StringIO()) 
     289#        emitter.emit(_syck.Scalar('foo ', tag="tag:yaml.org,2002:str")) 
     290#        parser = _syck.Parser(emitter.output.getvalue()) 
     291#        self.assertEqual(parser.parse().value, 'foo ') 
     292 
     293 
  • /trunk/tests/test_syck.py

    r20 r21  
    22import unittest 
    33 
    4 #from test_node import * 
     4from test_node import * 
    55from test_parser import * 
    66from test_loader import * 
    77from test_emitter import * 
    88from test_dumper import * 
     9from test_pickle import * 
    910 
    1011def main(module='__main__'): 
  • /trunk/tests/test_dumper.py

    r20 r23  
     1 
     2from __future__ import generators 
    13 
    24import unittest 
    35import syck 
    4 import StringIO, datetime, sets 
     6import StringIO 
    57import test_emitter 
     8 
     9try: 
     10    import datetime 
     11except: 
     12    class _datetime: 
     13        def datetime(self, *args): 
     14            return args 
     15    datetime = _datetime() 
     16 
     17try: 
     18    import sets 
     19except: 
     20    class _sets: 
     21        def Set(self, items): 
     22            set = {} 
     23            for items in items: 
     24                set[items] = None 
     25            return set 
     26    sets = _sets() 
     27 
    628 
    729EXAMPLE = { 
     
    136158        for a, b in zip(scalars, SCALARS): 
    137159            self.assertEqual(type(a), type(b)) 
    138             self.assertEqual(a, b) 
     160            if type(a) is float: 
     161                self.assertEqual(repr(a), repr(b)) 
     162            else: 
     163                self.assertEqual(a, b) 
    139164 
    140165class TestCollectionTypes(unittest.TestCase): 
  • /trunk/tests/test_parser.py

    r20 r23  
    227227            self.assertEqual(type(structure), list) 
    228228            self.assertEqual(len(node.value), len(structure)) 
    229             for i, item in enumerate(node.value): 
     229            for i in range(len(node.value)): 
     230                item = node.value[i] 
    230231                self.assertEqualStructure(item, structure[i]) 
    231232        elif node.kind == 'map': 
  • /trunk/lib/syck/loaders.py

    r18 r25  
     1""" 
     2syck.loaders is a high-level wrapper for the Syck YAML parser. 
     3Do not use it directly, use the module 'syck' instead. 
     4""" 
    15 
    26# Python 2.2 compatibility 
     
    2125import _syck 
    2226 
    23 import re 
     27import sys, re 
    2428 
    2529__all__ = ['GenericLoader', 'Loader', 
     
    2731 
    2832class GenericLoader(_syck.Parser): 
     33    """ 
     34    GenericLoader constructs primitive Python objects from YAML documents. 
     35    """ 
    2936 
    3037    def load(self): 
     38        """ 
     39        Loads a YAML document from the source and return a native Python 
     40        object. On EOF, returns None and set the eof attribute on. 
     41        """ 
    3142        node = self.parse() 
    3243        if self.eof: 
     
    5061                value_object = self._convert(node.value[key_node], 
    5162                        node_to_object) 
    52                 if key_object in value: 
    53                     value = None 
    54                     break 
    5563                try: 
     64                    if key_object in value: 
     65                        value = None 
     66                        break 
    5667                    value[key_object] = value_object 
    5768                except TypeError: 
     
    6172                value = [] 
    6273                for key_node in node.value: 
    63                     key_object = self_convert(key_node, node_to_object) 
     74                    key_object = self._convert(key_node, node_to_object) 
    6475                    value_object = self._convert(node.value[key_node], 
    6576                            node_to_object) 
     
    7182 
    7283    def construct(self, node): 
     84        """Constructs a Python object by the given node.""" 
    7385        return node.value 
    7486 
    7587class Merge: 
     88    """Represents the merge key '<<'.""" 
    7689    pass 
    7790 
    7891class Default: 
     92    """Represents the default key '='.""" 
    7993    pass 
    8094 
    8195class Loader(GenericLoader): 
     96    """ 
     97    Loader constructs native Python objects from YAML documents. 
     98    """ 
    8299 
    83100    inf_value = 1e300000 
    84101    nan_value = inf_value/inf_value 
    85102 
    86     ymd_expr = re.compile(r'(?P<year>\d\d\d\d)-(?P<month>\d\d)-(?P<day>\d\d)') 
    87103    timestamp_expr = re.compile(r'(?P<year>\d\d\d\d)-(?P<month>\d\d)-(?P<day>\d\d)' 
    88104            r'(?:' 
     
    95111    default_key = Default() 
    96112 
    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 
     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() 
    141162 
    142163    def construct(self, node): 
     164        """Constructs a Python object by the given node.""" 
    143165        if node.kind == 'map' and self.merge_key in node.value: 
    144166            self.merge_maps(node) 
    145         if node.tag in self.tags: 
    146             constructor = self.tags[node.tag] 
    147             if isinstance(constructor, str): 
    148                 constructor = getattr(self, constructor) 
     167        constructor = self.find_constructor(node) 
     168        if constructor: 
    149169            return constructor(node) 
    150170        else: 
    151171            return node.value 
    152172 
    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): 
     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): 
    160183        digits = [num_type(part) for part in node.value.split(':')] 
    161184        digits.reverse() 
     
    166189            base *= 60 
    167190        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_float 
     207    construct_float_exp = construct_float 
     208 
     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_value 
     214 
     215    def construct_float_neginf(self, node): 
     216        return -self.inf_value 
     217 
     218    def construct_float_nan(self, node): 
     219        return self.nan_value 
     220 
     221    def construct_binary(self, node): 
     222        return node.value.decode('base64') 
    168223 
    169224    def construct_timestamp(self, node): 
     
    183238        diff = datetime.timedelta(hours=values['zhour'], minutes=values['zminute']) 
    184239        return stamp-diff 
     240    construct_timestamp_ymd = construct_timestamp 
     241    construct_timestamp_iso8601 = construct_timestamp 
     242    construct_timestamp_spaced = construct_timestamp 
    185243 
    186244    def construct_merge(self, node): 
     
    217275        return sets.Set(node.value) 
    218276 
    219 def parse(source): 
     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 
     376def parse(source, Loader=Loader, **parameters): 
    220377    """Parses 'source' and returns the root of the 'Node' graph.""" 
    221     loader = Loader(source) 
     378    loader = Loader(source, **parameters) 
    222379    return loader.parse() 
    223380 
    224 def load(source): 
     381def load(source, Loader=Loader, **parameters): 
    225382    """Parses 'source' and returns the root object.""" 
    226     loader = Loader(source) 
     383    loader = Loader(source, **parameters) 
    227384    return loader.load() 
    228385 
    229 def parse_documents(source): 
    230     """Iterates over 'source' and yields the root node of each document.""" 
    231     loader = Loader(source) 
     386def parse_documents(source, Loader=Loader, **parameters): 
     387    """Iterates over 'source' and yields the root 'Node' for each document.""" 
     388    loader = Loader(source, **parameters) 
    232389    while True: 
    233390        node = loader.parse() 
     
    236393        yield node 
    237394 
    238 def load_documents(source): 
    239     """Iterates over 'source' and yields the root object of each document.""" 
    240     loader = Loader(source) 
     395def load_documents(source, Loader=Loader, **parameters): 
     396    """Iterates over 'source' and yields the root object for each document.""" 
     397    loader = Loader(source, **parameters) 
    241398    while True: 
    242399        object = loader.load() 
  • /trunk/lib/syck/__init__.py

    r19 r25  
     1""" 
     2YAML is a data serialization format designed for human readability and 
     3interaction with scripting languages. 
     4 
     5Syck is an extension for reading and writing YAML in scripting languages. 
     6 
     7PySyck provides Python bindings for Syck YAML parser and emitter. 
     8 
     9To start working with PySyck, import the package 'syck': 
     10>>> from syck import * 
     11 
     12To parse a YAML document into a Python object, use the function 'load()': 
     13>>> load(''' 
     14... - Mark McGwire 
     15... - Sammy Sosa 
     16... - Ken Griffey 
     17... ''') 
     18['Mark McGwire', 'Sammy Sosa', 'Ken Griffey'] 
     19 
     20To emit a Python object into a YAML document, use the function 'dump()': 
     21>>> print dump(['Mark McGwire', 'Sammy Sosa', 'Ken Griffey']) 
     22--- 
     23- Mark McGwire 
     24- Sammy Sosa 
     25- Ken Griffey 
     26 
     27You may get access to the YAML parser tree using the function 'parse()': 
     28>>> root_node = parse(''' 
     29... - Mark McGwire 
     30... - Sammy Sosa 
     31... - Ken Griffey 
     32... ''') 
     33>>> root_node 
     34<_syck.Seq object at 0xb7a1f874> 
     35>>> root_node.kind 
     36'seq' 
     37>>> root_node.value 
     38[<_syck.Scalar object at 0xb7a1e5fc>, <_syck.Scalar object at 0xb7a1e65c>, <_syck.Scalar object at 0xb7a1e6bc>] 
     39 
     40You may now use the function 'emit()' to obtain the YAML document again: 
     41>>> print emit(root_node) 
     42--- 
     43- Mark McGwire 
     44- Sammy Sosa 
     45- Ken Griffey 
     46 
     47What do you get if you apply the function 'dump()' to root_node? Let's try it: 
     48>>> print dump(root_node) 
     49--- !python/object:_syck.Seq 
     50value: 
     51- !python/object:_syck.Scalar 
     52  value: Mark McGwire 
     53  tag: tag:yaml.org,2002:str 
     54- !python/object:_syck.Scalar 
     55  value: Sammy Sosa 
     56  tag: tag:yaml.org,2002:str 
     57- !python/object:_syck.Scalar 
     58  value: Ken Griffey 
     59  tag: tag:yaml.org,2002:str 
     60 
     61As you can see, PySyck allow you to represent complex Python objects. 
     62 
     63You can also dump the generated YAML output into any file-like object: 
     64>>> import os 
     65>>> stream = os.tmpfile() 
     66>>> object = ['foo', 'bar', ['baz']] 
     67>>> dump(object, stream) 
     68>>> stream.seek(0) 
     69>>> print stream.read() 
     70--- 
     71- foo 
     72- bar 
     73- - baz 
     74 
     75To load several documents from a single YAML stream, use the function 
     76'load_documents()': 
     77>>> source = ''' 
     78... --- 
     79... american: 
     80...   - Boston Red Sox 
     81...   - Detroit Tigers 
     82...   - New York Yankees 
     83... national: 
     84...   - New York Mets 
     85...   - Chicago Cubs 
     86...   - Atlanta Braves 
     87... --- 
     88... - [name        , hr, avg  ] 
     89... - [Mark McGwire, 65, 0.278] 
     90... - [Sammy Sosa  , 63, 0.288] 
     91... ''' 
     92>>> for document in load_documents(source): 
     93...     print document 
     94... 
     95{'national': ['New York Mets', 'Chicago Cubs', 'Atlanta Braves'], 'american': ['Boston Red Sox', 'Detroit Tigers', 'New York Yankees']} 
     96[['name', 'hr', 'avg'], ['Mark McGwire', 65, 0.27800000000000002], ['Sammy Sosa', 63, 0.28799999999999998]] 
     97 
     98See the source code for more details. 
     99""" 
     100 
    1101 
    2102from _syck import * 
  • /trunk/lib/syck/dumpers.py

    r20 r25  
     1""" 
     2syck.dumpers is a high-level wrapper for the Syck YAML emitter. 
     3Do not use it directly, use the module 'syck' instead. 
     4""" 
    15 
    26import _syck 
     
    1014    'emit', 'dump', 'emit_documents', 'dump_documents'] 
    1115 
    12 INF = 1e300000 
    13 NEGINF = -INF 
    14 NAN = INF/INF 
    15  
    16  
    1716class GenericDumper(_syck.Emitter): 
     17    """ 
     18    GenericDumper dumps native Python objects into YAML documents. 
     19    """ 
    1820 
    1921    def dump(self, object): 
     22        """Dumps the given Python object as a YAML document.""" 
    2023        self.emit(self._convert(object, {})) 
    2124 
    2225    def _convert(self, object, object_to_node): 
    2326        if id(object) in object_to_node and self.allow_aliases(object): 
    24             return object_to_node[id(object)] 
     27            return object_to_node[id(object)][1] 
    2528        node = self.represent(object) 
    26         object_to_node[id(object)] = node 
     29        object_to_node[id(object)] = object, node 
    2730        if node.kind == 'seq': 
    28             for index, item in enumerate(node.value): 
     31            for index in range(len(node.value)): 
     32                item = node.value[index] 
    2933                node.value[index] = self._convert(item, object_to_node) 
    3034        elif node.kind == 'map': 
    31             for key in node.value.keys(): 
    32                 value = node.value[key] 
    33                 del node.value[key] 
    34                 node.value[self._convert(key, object_to_node)] =    \ 
    35                         self._convert(value, object_to_node) 
     35            if isinstance(node.value, dict): 
     36                for key in node.value.keys(): 
     37                    value = node.value[key] 
     38                    del node.value[key] 
     39                    node.value[self._convert(key, object_to_node)] =    \ 
     40                            self._convert(value, object_to_node) 
     41            elif isinstance(node.value, list): 
     42                for index in range(len(node.value)): 
     43                    key, value = node.value[index] 
     44                    node.value[index] = (self._convert(key, object_to_node), 
     45                            self._convert(value, object_to_node)) 
    3646#        # Workaround against a Syck bug: 
    3747#        if node.kind == 'scalar' and node.style not in ['1quote', '2quote'] \ 
     
    4151 
    4252    def represent(self, object): 
     53        """Represents the given Python object as a 'Node'.""" 
    4354        if isinstance(object, dict): 
    4455            return _syck.Map(object.copy(), tag="tag:yaml.org,2002:map") 
     
    4960 
    5061    def allow_aliases(self, object): 
     62        """Checks whether the given object can be aliased.""" 
    5163        return True 
    5264 
    5365class Dumper(GenericDumper): 
    54  
    55     def __init__(self, *args, **kwds): 
    56         super(Dumper, self).__init__(*args, **kwds) 
    57  
    58     def represent(self, object): 
     66    """ 
     67    Dumper dumps native Python objects into YAML documents. 
     68    """ 
     69 
     70    INF = 1e300000 
     71    inf_value = repr(INF) 
     72    neginf_value = repr(-INF) 
     73    nan_value = repr(INF/INF) 
     74 
     75    def find_representer(self, object): 
     76        """ 
     77        For the given object, find a method that can represent it as a 'Node' 
     78        object. 
     79 
     80        If the type of the object has the form 'package.module.type', 
     81        find_representer() returns the method 'represent_package_module_type'. 
     82        If this method does not exist, it checks the base types. 
     83        """ 
    5984        for object_type in type(object).__mro__: 
    6085            if object_type.__module__ == '__builtin__': 
     
    6287            else: 
    6388                name = '%s.%s' % (object_type.__module__, object_type.__name__) 
    64             method = 'represent_%s' % name.replace('.', '_') 
     89            method = 'represent_' + name.replace('.', '_') 
    6590            if hasattr(self, method): 
    66                 return getattr(self, method)(object) 
    67         return super(Dumper, self).represent(object) 
     91                return getattr(self, method) 
     92 
     93    def represent(self, object): 
     94        """Represents the given Python object as a 'Node'.""" 
     95        representer = self.find_representer(object) 
     96        if representer: 
     97            return representer(object) 
     98        else: 
     99            return super(Dumper, self).represent(object) 
    68100 
    69101    def represent_object(self, object): 
     
    88120        return _syck.Scalar(repr(object), tag="tag:yaml.org,2002:int") 
    89121 
    90     def represent_int(self, object): 
    91         return _syck.Scalar(repr(object), tag="tag:yaml.org,2002:int") 
    92  
    93122    def represent_float(self, object): 
    94123        value = repr(object) 
    95         if value == repr(INF): 
     124        if value == self.inf_value: 
    96125            value = '.inf' 
    97         elif value == repr(NEGINF): 
     126        elif value == self.neginf_value: 
    98127            value = '-.inf' 
    99         elif value == repr(NAN): 
     128        elif value == self.nan_value: 
    100129            value = '.nan' 
    101130        return _syck.Scalar(value, tag="tag:yaml.org,2002:float") 
     
    103132    def represent_sets_Set(self, object): 
    104133        return _syck.Seq(list(object), tag="tag:yaml.org,2002:set") 
     134    represent_set = represent_sets_Set 
    105135 
    106136    def represent_datetime_datetime(self, object): 
    107137        return _syck.Scalar(object.isoformat(), tag="tag:yaml.org,2002:timestamp") 
    108138 
     139    def represent_long(self, object): 
     140        return _syck.Scalar(repr(object), tag="tag:python.yaml.org,2002:long") 
     141 
     142    def represent_unicode(self, object): 
     143        return _syck.Scalar(object.encode('utf-8'), tag="tag:python.yaml.org,2002:unicode") 
     144 
     145    def represent_tuple(self, object): 
     146        return _syck.Seq(list(object), tag="tag:python.yaml.org,2002:tuple") 
     147 
     148    def represent_type(self, object): 
     149        name = '%s.%s' % (object.__module__, object.__name__) 
     150        return _syck.Scalar('', tag="tag:python.yaml.org,2002:name:"+name) 
     151    represent_classobj = represent_type 
     152    represent_class = represent_type 
     153    # TODO: Python 2.2 does not provide the module name of a function 
     154    represent_function = represent_type 
     155    represent_builtin_function_or_method = represent_type 
     156 
     157    def represent_instance(self, object): 
     158        cls = object.__class__ 
     159        class_name = '%s.%s' % (cls.__module__, cls.__name__) 
     160        args = () 
     161        state = {} 
     162        if hasattr(object, '__getinitargs__'): 
     163            args = object.__getinitargs__() 
     164        if hasattr(object, '__getstate__'): 
     165            state = object.__getstate__() 
     166        elif not hasattr(object, '__getinitargs__'): 
     167            state = object.__dict__.copy() 
     168        if not args and isinstance(state, dict): 
     169            return _syck.Map(state.copy(), 
     170                    tag="tag:python.yaml.org,2002:object:"+class_name) 
     171        value = {} 
     172        if args: 
     173            value['args'] = list(args) 
     174        if state or not isinstance(state, dict): 
     175            value['state'] = state 
     176        return _syck.Map(value, 
     177                tag="tag:python.yaml.org,2002:new:"+class_name) 
     178 
     179    def represent_object(self, object): # Do you understand this? I don't. 
     180        cls = type(object) 
     181        class_name = '%s.%s' % (cls.__module__, cls.__name__) 
     182        args = () 
     183        state = {} 
     184        if cls.__reduce__ is type.__reduce__: 
     185            if hasattr(object, '__reduce_ex__'): 
     186                reduce = object.__reduce_ex__(2) 
     187                args = reduce[1][1:] 
     188            else: 
     189                reduce = object.__reduce__() 
     190            if len(reduce) > 2: 
     191                state = reduce[2] 
     192            if state is None: 
     193                state = {} 
     194            if not args and isinstance(state, dict): 
     195                return _syck.Map(state.copy(), 
     196                        tag="tag:python.yaml.org,2002:object:"+class_name) 
     197            if not state and isinstance(state, dict): 
     198                return _syck.Seq(list(args), 
     199                        tag="tag:python.yaml.org,2002:new:"+class_name) 
     200            value = {} 
     201            if args: 
     202                value['args'] = list(args) 
     203            if state or not isinstance(state, dict): 
     204                value['state'] = state 
     205            return _syck.Map(value, 
     206                    tag="tag:python.yaml.org,2002:new:"+class_name) 
     207        else: 
     208            reduce = object.__reduce__() 
     209            cls = reduce[0] 
     210            class_name = '%s.%s' % (cls.__module__, cls.__name__) 
     211            args = reduce[1] 
     212            state = None 
     213            if len(reduce) > 2: 
     214                state = reduce[2] 
     215            if state is None: 
     216                state = {} 
     217            if not state and isinstance(state, dict): 
     218                return _syck.Seq(list(args), 
     219                        tag="tag:python.yaml.org,2002:apply:"+class_name) 
     220            value = {} 
     221            if args: 
     222                value['args'] = list(args) 
     223            if state or not isinstance(state, dict): 
     224                value['state'] = state 
     225            return _syck.Map(value, 
     226                    tag="tag:python.yaml.org,2002:apply:"+class_name) 
     227 
     228    def represent__syck_Node(self, object): 
     229        object_type = type(object) 
     230        type_name = '%s.%s' % (object_type.__module__, object_type.__name__) 
     231        state = [] 
     232        if hasattr(object_type, '__slotnames__'): 
     233            for name in object_type.__slotnames__: 
     234                value = getattr(object, name) 
     235                if value: 
     236                    state.append((name, value)) 
     237        return _syck.Map(state, 
     238                tag="tag:python.yaml.org,2002:object:"+type_name) 
     239 
    109240    def allow_aliases(self, object): 
     241        """Checks whether the given object can be aliased.""" 
    110242        if object is None or type(object) in [int, bool, float]: 
    111243            return False 
    112244        if type(object) is str and (not object or object.isalnum()): 
    113245            return False 
     246        if type(object) is tuple and not object: 
     247            return False 
    114248        return True 
    115249 
    116 def emit(node, output=None, **parameters): 
     250def emit(node, output=None, Dumper=Dumper, **parameters): 
     251    """ 
     252    Emits the given node to the output. 
     253 
     254    If output is None, returns the produced YAML document. 
     255    """ 
    117256    if output is None: 
    118257        dumper = Dumper(StringIO.StringIO(), **parameters) 
     
    123262        return dumper.output.getvalue() 
    124263 
    125 def dump(object, output=None, **parameters): 
     264def dump(object, output=None, Dumper=Dumper, **parameters): 
     265    """ 
     266    Dumps the given object to the output. 
     267 
     268    If output is None, returns the produced YAML document. 
     269    """ 
    126270    if output is None: 
    127271        dumper = Dumper(StringIO.StringIO(), **parameters) 
     
    132276        return dumper.output.getvalue() 
    133277 
    134 def emit_documents(nodes, output=None, **parameters): 
     278def emit_documents(nodes, output=None, Dumper=Dumper, **parameters): 
     279    """ 
     280    Emits the list of nodes to the output. 
     281     
     282    If output is None, returns the produced YAML document. 
     283    """ 
    135284    if output is None: 
    136285        dumper = Dumper(StringIO.StringIO(), **parameters) 
     
    142291        return dumper.output.getvalue() 
    143292 
    144 def dump_documents(objects, output=None, **parameters): 
     293def dump_documents(objects, output=None, Dumper=Dumper, **parameters): 
     294    """ 
     295    Dumps the list of objects to the output. 
     296     
     297    If output is None, returns the produced YAML document. 
     298    """ 
    145299    if output is None: 
    146300        dumper = Dumper(StringIO.StringIO(), **parameters) 
  • /trunk/setup.py

    r3 r27  
     1 
     2NAME = 'PySyck' 
     3VERSION = '0.55.1' 
     4DESCRIPTION = "Python bindings for the Syck YAML parser and emitter" 
     5LONG_DESCRIPTION = """\ 
     6YAML is a data serialization format designed for human readability 
     7and interaction with scripting languages. Syck is an extension for 
     8reading and writing YAML in scripting languages. PySyck is aimed to 
     9update the current Python bindings for Syck.""" 
     10AUTHOR = "Kirill Simonov" 
     11AUTHOR_EMAIL = 'xi@resolvent.net' 
     12LICENSE = "BSD" 
     13PLATFORMS = "Any" 
     14URL = "http://xitology.org/pysyck/" 
     15DOWNLOAD_URL = URL + "%s-%s.tar.gz" % (NAME, VERSION) 
     16CLASSIFIERS = [ 
     17    "Development Status :: 3 - Alpha", 
     18    "Intended Audience :: Developers", 
     19    "License :: OSI Approved :: BSD License", 
     20    "Programming Language :: Python", 
     21    "Topic :: Software Development :: Libraries :: Python Modules", 
     22    "Topic :: Text Processing :: Markup", 
     23] 
    124 
    225from distutils.core import setup, Extension 
     
    1235 
    1336setup( 
    14     name='Syck', 
    15     version='0.55.1', 
     37    name=NAME, 
     38    version=VERSION, 
     39    description=DESCRIPTION, 
     40    long_description=LONG_DESCRIPTION, 
     41    author=AUTHOR, 
     42    author_email=AUTHOR_EMAIL, 
     43    license=LICENSE, 
     44    platforms=PLATFORMS, 
     45    url=URL, 
     46    download_url=DOWNLOAD_URL, 
     47    classifiers=CLASSIFIERS, 
     48 
    1649    package_dir={'': 'lib'}, 
    1750    packages=['syck'], 
     
    2356        ), 
    2457    ], 
    25     description="Python bindings for the Syck YAML parser", 
    26     author="Kirill Simonov", 
    27     author_email="xi@resolvent.net", 
    28     license="BSD", 
    29     url="http://xitology.org/python-syck/", 
    30     download_url="http://xitology.org/*FIXME*", 
    31     classifiers=[ 
    32         "Development Status :: 2 - Pre-Alpha", 
    33         "Intended Audience :: Developers", 
    34         "License :: OSI Approved :: BSD License", 
    35         "Programming Language :: Python", 
    36         "Topic :: Software Development :: Libraries :: Python Modules", 
    37         "Topic :: Text Processing :: Markup", 
    38     ], 
    3958) 
    4059 
  • /trunk/Makefile

    r4 r29  
    11 
    2 .PHONY: default build force install test clean 
     2.PHONY: default build force install test clean  \ 
     3        dist-src dist-win dist-win-2.2 dist-win-2.3 dist-win-2.4 
    34 
    45PYTHON=/usr/bin/python 
     6REST2HTML=/usr/bin/rest2html --embed-stylesheet --stylesheet-path=/usr/share/python-docutils/stylesheets/default.css 
    57TEST= 
     8PARAMETERS= 
    69 
    7 default: build 
     10default: build README.html 
    811 
    912build: 
    10         ${PYTHON} setup.py build 
     13        ${PYTHON} setup.py build ${PARAMETERS} 
    1114 
    1215force: 
    13         ${PYTHON} setup.py build -f 
     16        ${PYTHON} setup.py build -f ${PARAMETERS} 
    1417 
    1518install: build 
    16         ${PYTHON} setup.py install 
     19        ${PYTHON} setup.py install ${PARAMETERS} 
    1720 
    1821test: build 
     
    2225        ${PYTHON} setup.py clean -a 
    2326 
     27dist-src: 
     28        ${PYTHON} setup.py sdist --formats=zip,gztar 
     29 
     30dist-win: dist-win-2.2 dist-win-2.3 dist-win-2.4 
     31 
     32dist-win-2.2: PYTHON=/c/Python22/python 
     33dist-win-2.2: PARAMETERS=--compiler=mingw32 
     34dist-win-2.2: 
     35        ${PYTHON} setup.py build ${PARAMETERS} 
     36        ${PYTHON} setup.py bdist_wininst 
     37 
     38dist-win-2.3: PYTHON=/c/Python23/python 
     39dist-win-2.3: PARAMETERS=--compiler=mingw32 
     40dist-win-2.3: 
     41        ${PYTHON} setup.py build ${PARAMETERS} 
     42        ${PYTHON} setup.py bdist_wininst --skip-build --target-version=2.3 
     43 
     44dist-win-2.4: PYTHON=/c/Python24/python 
     45dist-win-2.4: PARAMETERS=--compiler=mingw32 
     46dist-win-2.4: 
     47        ${PYTHON} setup.py build ${PARAMETERS} 
     48        ${PYTHON} setup.py bdist_wininst --skip-build --target-version=2.4 
     49 
     50README.html: README.txt 
     51        ${REST2HTML} README.txt README.html 
     52 
  • /trunk/sandbox/emit-it/emit-it.c

    r17 r25  
    1616{ 
    1717    switch (id) { 
     18/* 
    1819        case 1: 
    1920            syck_emit_seq(e, "tag:domainmyseq.tld,2002:zz", seq_none); 
     
    2122            syck_emit_item(e, 3); 
    2223            syck_emit_item(e, 4); 
    23 /*            syck_emit_item(e, 2); 
    24             syck_emit_item(e, 1);*/ 
    2524            syck_emit_end(e); 
    2625            break; 
     
    3433            syck_emit_scalar(e, "x-private:myowntype", scalar_none, 0, 0, 0, "Ken Griffey", strlen("Ken Griffey")); 
    3534            break; 
     35*/ 
     36 
     37        case 1: 
     38            syck_emit_map(e, NULL, map_none); 
     39            syck_emit_item(e, 2); 
     40            syck_emit_item(e, 3); 
     41            syck_emit_end(e); 
     42            break; 
     43 
     44        case 2: 
     45            syck_emit_map(e, "x-private:key", map_none); 
     46            syck_emit_item(e, 4); 
     47            syck_emit_item(e, 5); 
     48            syck_emit_end(e); 
     49            break; 
     50 
     51        case 3: 
     52        case 4: 
     53        case 5: 
     54            syck_emit_scalar(e, NULL, scalar_none, 0, 0, 0, "foo", 3); 
     55            break; 
    3656    } 
     57         
    3758} 
    3859 
     
    4869    syck_emitter_mark_node(e, 3); 
    4970    syck_emitter_mark_node(e, 4); 
     71    syck_emitter_mark_node(e, 5); 
    5072/*    syck_emitter_mark_node(e, 2); 
    5173    syck_emitter_mark_node(e, 1);*/ 
  • /trunk/sandbox/emit-it/Makefile

    r11 r25  
     1 
     2ALL = emit-it complex-key-bug trailing-space-bug 
    13 
    24.PHONY: default clean 
    35 
    4 default: emit-it 
     6default: $(ALL) 
    57 
    68clean: 
    7         rm -f emit-it 
    8         rm -f emit-it.o 
     9        rm -f *.o 
     10        rm -f $(ALL) 
    911 
    10 emit-it: emit-it.o 
    11         gcc emit-it.o -o emit-it -lsyck -L${HOME}/lib -Wall -Wstrict-prototypes 
     12%.o: %.c 
     13        gcc -c $< -o $@ -Wall -Wstrict-prototypes -I${HOME}/include 
    1214 
    13 emit-it.o: emit-it.c 
    14         gcc -c emit-it.c -o emit-it.o -I${HOME}/include 
    15  
     15$(ALL): %: %.o 
     16        gcc $< -o $@ -lsyck -L${HOME}/lib -Wall -Wstrict-prototypes 
  • /trunk/ext/_syckmodule.c

    r20 r25  
    4343PyDoc_STRVAR(PySyckNode_doc, 
    4444    "_syck.Node() -> TypeError\n\n" 
    45     "_syck.Node is an abstract type. It is a base type for _syck.Scalar,\n" 
     45    "_syck.Node is an abstract type. It is the base type for _syck.Scalar,\n" 
    4646    "_syck.Seq, and _syck.Map. You cannot create an instance of _syck.Node\n" 
    4747    "directly. You may use _syck.Node for type checking or subclassing.\n"); 
     
    220220    "      -> a Scalar node\n\n" 
    221221    "_syck.Scalar represents a scalar node in Syck parser and emitter\n" 
    222     "graphs. A scalar node points to a single string value.\n"); 
     222    "trees. A scalar node points to a single string value.\n"); 
    223223 
    224224typedef struct { 
     
    549549    "Seq(value=[], tag=None, inline=False) -> a Seq node\n\n" 
    550550    "_syck.Seq represents a sequence node in Syck parser and emitter\n" 
    551     "graphs. A sequence node points to an ordered set of subnodes.\n"); 
     551    "trees. A sequence node points to an ordered set of subnodes.\n"); 
    552552 
    553553typedef struct { 
     
    718718 
    719719PyDoc_STRVAR(PySyckMap_doc, 
    720     "Map(value='', tag=None, inline=False) -> a Map node\n\n" 
     720    "Map(value={}, tag=None, inline=False) -> a Map node\n\n" 
    721721    "_syck.Map represents a mapping node in Syck parser and emitter\n" 
    722     "graphs. A mapping node points to an unordered collections of pairs.\n"); 
     722    "trees. A mapping node points to an unordered collections of pairs.\n"); 
    723723 
    724724typedef struct { 
     
    833833        PyDoc_STR("the node kind, always 'map', read-only"), &PySyck_MapKind}, 
    834834    {"value", (getter)PySyckNode_getvalue, (setter)PySyckMap_setvalue, 
    835         PyDoc_STR("the node value, a mapping"), NULL}, 
     835        PyDoc_STR("the node value, a list of pairs or a dictionary"), NULL}, 
    836836    {"tag", (getter)PySyckNode_gettag, (setter)PySyckNode_settag, 
    837837        PyDoc_STR("the node tag, a string or None"), NULL}, 
     
    893893    "      -> a Parser object\n\n" 
    894894    "_syck.Parser is a low-lever wrapper of the Syck parser. It parses\n" 
    895     "a YAML stream and produces a graph of Nodes.\n"); 
     895    "a YAML stream and produces a tree of Nodes.\n"); 
    896896 
    897897typedef struct { 
     
    10171017static PyGetSetDef PySyckParser_getsetters[] = { 
    10181018    {"source", (getter)PySyckParser_getsource, NULL, 
    1019         PyDoc_STR("IO source, a string or file-like object"), NULL}, 
     1019        PyDoc_STR("IO source, a string or a file-like object"), NULL}, 
    10201020    {"implicit_typing", (getter)PySyckParser_getimplicit_typing, NULL, 
    10211021        PyDoc_STR("implicit typing of builtin YAML types"), NULL}, 
     
    12531253 
    12541254    if (self->parsing) { 
    1255         PyErr_SetString(PyExc_RuntimeError, "do not call Parser.parse while it is already parsing"); 
     1255        PyErr_SetString(PyExc_RuntimeError, 
     1256                "do not call Parser.parse while it is already running"); 
    12561257        return NULL; 
    12571258    } 
     
    12921293PyDoc_STRVAR(PySyckParser_parse_doc, 
    12931294    "parse() -> the root Node object\n\n" 
    1294     "Parses the source and returns the next document. On EOF, returns None\n" 
    1295     "and sets the 'eof' attribute on.\n"); 
     1295    "Parses the source and returns the root of the Node tree. Call it\n" 
     1296    "several times to retrieve all documents from the source. On EOF,\n" 
     1297    "returns None and sets the 'eof' attribute on.\n"); 
    12961298 
    12971299static PyMethodDef PySyckParser_methods[] = { 
     
    13481350 
    13491351PyDoc_STRVAR(PySyckEmitter_doc, 
    1350     "Emitter(output, headless=False, use_header=True, explicit_typing=True," 
    1351     "        style=None, best_width=80, indent=2) -> an Emitter object\n\n" 
    1352     "_syck.Emitter is a low-lever wrapper of the Syck emitter. It emit\n" 
     1352    "Emitter(output, headless=False, use_header=False, use_version=False,\n" 
     1353    "        explicit_typing=True, style=None, best_width=80, indent=2)\n" 
     1354    "                -> an Emitter object\n\n" 
     1355    "_syck.Emitter is a low-lever wrapper of the Syck emitter. It emits\n" 
    13531356    "a tree of Nodes into a YAML stream.\n"); 
    13541357 
     
    15301533        PyDoc_STR("headerless document flag"), NULL}, 
    15311534    {"use_header", (getter)PySyckEmitter_getuse_header, NULL, 
    1532         PyDoc_STR("force header"), NULL}, 
     1535        PyDoc_STR("force header flag"), NULL}, 
    15331536    {"use_version", (getter)PySyckEmitter_getuse_version, NULL, 
    1534         PyDoc_STR("force version"), NULL}, 
     1537        PyDoc_STR("force version flag"), NULL}, 
    15351538    {"explicit_typing", (getter)PySyckEmitter_getexplicit_typing, NULL, 
    15361539        PyDoc_STR("explicit typing for all collections"), NULL}, 
     
    17521755    Py_INCREF(output); 
    17531756    self->output = output; 
    1754  
    1755 /* 
    1756     self->emitter = syck_new_emitter(); 
    1757     self->emitter->bonus = self; 
    1758     self->emitter->headless = self->headless; 
    1759     self->emitter->use_header = use_header; 
    1760     self->emitter->use_version = use_version; 
    1761     self->emitter->explicit_typing = explicit_typing; 
    1762     self->emitter->style = self->style; 
    1763     self->emitter->best_width = self->best_width; 
    1764     self->emitter->indent = self->indent; 
    1765  
    1766     syck_emitter_handler(self->emitter, PySyckEmitter_node_handler); 
    1767     syck_output_handler(self->emitter, PySyckEmitter_write_handler); 
    1768 */ 
    17691757 
    17701758    self->emitting = 0; 
     
    19741962PyDoc_STRVAR(PySyckEmitter_emit_doc, 
    19751963    "emit(root_node) -> None\n\n" 
    1976     "Emit the Node tree to the output.\n"); 
     1964    "Emits the Node tree to the output.\n"); 
    19771965 
    19781966static PyMethodDef PySyckEmitter_methods[] = { 
     
    20332021 
    20342022PyDoc_STRVAR(PySyck_doc, 
    2035     "low-level wrapper for the Syck YAML parser and emitter"); 
     2023    "_syck is a low-level wrapper for the Syck YAML parser and emitter.\n" 
     2024    "Do not use it directly, use the module 'syck' instead.\n"); 
     2025 
     2026static int 
     2027add_slotnames(PyTypeObject *type) 
     2028{ 
     2029    PyObject *slotnames; 
     2030    PyObject *name; 
     2031    PyGetSetDef *getsetter; 
     2032 
     2033    if (!type->tp_getset) return 0; 
     2034    if (!type->tp_dict) return 0; 
     2035 
     2036    slotnames = PyList_New(0); 
     2037    if (!slotnames) return -1; 
     2038 
     2039    for (getsetter = type->tp_getset; getsetter->name; getsetter++) { 
     2040        if (!getsetter->set) continue; 
     2041        name = PyString_FromString(getsetter->name); 
     2042        if (!name) { 
     2043           Py_DECREF(slotnames); 
     2044           return -1; 
     2045        } 
     2046        if (PyList_Append(slotnames, name) < 0) { 
     2047            Py_DECREF(name); 
     2048            Py_DECREF(slotnames); 
     2049            return -1; 
     2050        } 
     2051        Py_DECREF(name); 
     2052    } 
     2053 
     2054    if (PyDict_SetItemString(type->tp_dict, "__slotnames__", slotnames) < 0) { 
     2055        Py_DECREF(slotnames); 
     2056        return -1; 
     2057    } 
     2058 
     2059    Py_DECREF(slotnames); 
     2060    return 0; 
     2061} 
    20362062 
    20372063PyMODINIT_FUNC 
     
    20442070    if (PyType_Ready(&PySyckScalar_Type) < 0) 
    20452071        return; 
     2072    if (add_slotnames(&PySyckScalar_Type) < 0) 
     2073        return; 
    20462074    if (PyType_Ready(&PySyckSeq_Type) < 0) 
    20472075        return; 
     2076    if (add_slotnames(&PySyckSeq_Type) < 0) 
     2077        return; 
    20482078    if (PyType_Ready(&PySyckMap_Type) < 0) 
     2079        return; 
     2080    if (add_slotnames(&PySyckMap_Type) < 0) 
    20492081        return; 
    20502082    if (PyType_Ready(&PySyckParser_Type) < 0) 
Note: See TracChangeset for help on using the changeset viewer.