Ignore:
Timestamp:
04/22/06 16:40:43 (9 years ago)
Author:
xi
Message:

Add support for pickling/unpickling python objects.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • pyyaml/trunk/lib/yaml/constructor.py

    r146 r147  
    493493        return self.find_python_module(suffix, node.start_mark) 
    494494 
     495    class classobj: pass 
     496 
     497    def make_python_instance(self, suffix, node, 
     498            args=None, kwds=None, newobj=False): 
     499        if not args: 
     500            args = [] 
     501        if not kwds: 
     502            kwds = {} 
     503        cls = self.find_python_name(suffix, node.start_mark) 
     504        if newobj and isinstance(cls, type(self.classobj))  \ 
     505                and not args and not kwds: 
     506            instance = self.classobj() 
     507            instance.__class__ = cls 
     508            return instance 
     509        elif newobj and isinstance(cls, type): 
     510            return cls.__new__(cls, *args, **kwds) 
     511        else: 
     512            return cls(*args, **kwds) 
     513 
     514    def set_python_instance_state(self, instance, state): 
     515        if hasattr(instance, '__setstate__'): 
     516            instance.__setstate__(state) 
     517        else: 
     518            slotstate = {} 
     519            if isinstance(state, tuple) and len(state) == 2: 
     520                state, slotstate = state 
     521            if hasattr(instance, '__dict__'): 
     522                instance.__dict__.update(state) 
     523            elif state: 
     524                slotstate.update(state) 
     525            for key, value in slotstate.items(): 
     526                setattr(object, key, value) 
     527 
     528    def construct_python_object(self, suffix, node): 
     529        # Format: 
     530        #   !!python/object:module.name { ... state ... } 
     531        instance = self.make_python_instance(suffix, node, newobj=True) 
     532        state = self.construct_mapping(node) 
     533        self.set_python_instance_state(instance, state) 
     534        return instance 
     535 
     536    def construct_python_object_apply(self, suffix, node, newobj=False): 
     537        # Format: 
     538        #   !!python/object/apply       # (or !!python/object/new) 
     539        #   args: [ ... arguments ... ] 
     540        #   kwds: { ... keywords ... } 
     541        #   state: ... state ... 
     542        #   listitems: [ ... listitems ... ] 
     543        #   dictitems: { ... dictitems ... } 
     544        # or short format: 
     545        #   !!python/object/apply [ ... arguments ... ] 
     546        # The difference between !!python/object/apply and !!python/object/new 
     547        # is how an object is created, check make_python_instance for details. 
     548        if isinstance(node, SequenceNode): 
     549            args = self.construct_sequence(node) 
     550            kwds = {} 
     551            state = {} 
     552            listitems = [] 
     553            dictitems = {} 
     554        else: 
     555            value = self.construct_mapping(node) 
     556            args = value.get('args', []) 
     557            kwds = value.get('kwds', {}) 
     558            state = value.get('state', {}) 
     559            listitems = value.get('listitems', []) 
     560            dictitems = value.get('dictitems', {}) 
     561        instance = self.make_python_instance(suffix, node, args, kwds, newobj) 
     562        if state: 
     563            self.set_python_instance_state(instance, state) 
     564        if listitems: 
     565            instance.extend(listitems) 
     566        if dictitems: 
     567            for key in dictitems: 
     568                instance[key] = dictitems[key] 
     569        return instance 
     570 
     571    def construct_python_object_new(self, suffix, node): 
     572        return self.construct_python_object_apply(suffix, node, newobj=True) 
     573 
     574 
    495575Constructor.add_constructor( 
    496576    u'tag:yaml.org,2002:python/none', 
     
    545625    Constructor.construct_python_module) 
    546626 
     627Constructor.add_multi_constructor( 
     628    u'tag:yaml.org,2002:python/object:', 
     629    Constructor.construct_python_object) 
     630 
     631Constructor.add_multi_constructor( 
     632    u'tag:yaml.org,2002:python/object/apply:', 
     633    Constructor.construct_python_object_apply) 
     634 
     635Constructor.add_multi_constructor( 
     636    u'tag:yaml.org,2002:python/object/new:', 
     637    Constructor.construct_python_object_new) 
     638 
Note: See TracChangeset for help on using the changeset viewer.