__all__=['BaseRepresenter','SafeRepresenter','Representer','RepresenterError']from.errorimport*from.nodesimport*importdatetime,copyreg,types,base64,collectionsclassRepresenterError(YAMLError):passclassBaseRepresenter:yaml_representers={}yaml_multi_representers={}def__init__(self,default_style=None,default_flow_style=False,sort_keys=True):self.default_style=default_styleself.sort_keys=sort_keysself.default_flow_style=default_flow_styleself.represented_objects={}self.object_keeper=[]self.alias_key=Nonedefrepresent(self,data):node=self.represent_data(data)self.serialize(node)self.represented_objects={}self.object_keeper=[]self.alias_key=Nonedefrepresent_data(self,data):ifself.ignore_aliases(data):self.alias_key=Noneelse:self.alias_key=id(data)ifself.alias_keyisnotNone:ifself.alias_keyinself.represented_objects:node=self.represented_objects[self.alias_key]#if node is None:# raise RepresenterError("recursive objects are not allowed: %r" % data)returnnode#self.represented_objects[alias_key] = Noneself.object_keeper.append(data)data_types=type(data).__mro__ifdata_types[0]inself.yaml_representers:node=self.yaml_representers[data_types[0]](self,data)else:fordata_typeindata_types:ifdata_typeinself.yaml_multi_representers:node=self.yaml_multi_representers[data_type](self,data)breakelse:ifNoneinself.yaml_multi_representers:node=self.yaml_multi_representers[None](self,data)elifNoneinself.yaml_representers:node=self.yaml_representers[None](self,data)else:node=ScalarNode(None,str(data))#if alias_key is not None:# self.represented_objects[alias_key] = nodereturnnode@classmethoddefadd_representer(cls,data_type,representer):ifnot'yaml_representers'incls.__dict__:cls.yaml_representers=cls.yaml_representers.copy()cls.yaml_representers[data_type]=representer@classmethoddefadd_multi_representer(cls,data_type,representer):ifnot'yaml_multi_representers'incls.__dict__:cls.yaml_multi_representers=cls.yaml_multi_representers.copy()cls.yaml_multi_representers[data_type]=representerdefrepresent_scalar(self,tag,value,style=None):ifstyleisNone:style=self.default_stylenode=ScalarNode(tag,value,style=style)ifself.alias_keyisnotNone:self.represented_objects[self.alias_key]=nodereturnnodedefrepresent_sequence(self,tag,sequence,flow_style=None):value=[]node=SequenceNode(tag,value,flow_style=flow_style)ifself.alias_keyisnotNone:self.represented_objects[self.alias_key]=nodebest_style=Trueforiteminsequence:node_item=self.represent_data(item)ifnot(isinstance(node_item,ScalarNode)andnotnode_item.style):best_style=Falsevalue.append(node_item)ifflow_styleisNone:ifself.default_flow_styleisnotNone:node.flow_style=self.default_flow_styleelse:node.flow_style=best_stylereturnnodedefrepresent_mapping(self,tag,mapping,flow_style=None):value=[]node=MappingNode(tag,value,flow_style=flow_style)ifself.alias_keyisnotNone:self.represented_objects[self.alias_key]=nodebest_style=Trueifhasattr(mapping,'items'):mapping=list(mapping.items())ifself.sort_keys:try:mapping=sorted(mapping)exceptTypeError:passforitem_key,item_valueinmapping:node_key=self.represent_data(item_key)node_value=self.represent_data(item_value)ifnot(isinstance(node_key,ScalarNode)andnotnode_key.style):best_style=Falseifnot(isinstance(node_value,ScalarNode)andnotnode_value.style):best_style=Falsevalue.append((node_key,node_value))ifflow_styleisNone:ifself.default_flow_styleisnotNone:node.flow_style=self.default_flow_styleelse:node.flow_style=best_stylereturnnodedefignore_aliases(self,data):returnFalseclassSafeRepresenter(BaseRepresenter):defignore_aliases(self,data):ifdataisNone:returnTrueifisinstance(data,tuple)anddata==():returnTrueifisinstance(data,(str,bytes,bool,int,float)):returnTruedefrepresent_none(self,data):returnself.represent_scalar('tag:yaml.org,2002:null','null')defrepresent_str(self,data):returnself.represent_scalar('tag:yaml.org,2002:str',data)defrepresent_binary(self,data):ifhasattr(base64,'encodebytes'):data=base64.encodebytes(data).decode('ascii')else:data=base64.encodestring(data).decode('ascii')returnself.represent_scalar('tag:yaml.org,2002:binary',data,style='|')defrepresent_bool(self,data):ifdata:value='true'else:value='false'returnself.represent_scalar('tag:yaml.org,2002:bool',value)defrepresent_int(self,data):returnself.represent_scalar('tag:yaml.org,2002:int',str(data))inf_value=1e300whilerepr(inf_value)!=repr(inf_value*inf_value):inf_value*=inf_valuedefrepresent_float(self,data):ifdata!=dataor(data==0.0anddata==1.0):value='.nan'elifdata==self.inf_value:value='.inf'elifdata==-self.inf_value:value='-.inf'else:value=repr(data).lower()# Note that in some cases `repr(data)` represents a float number# without the decimal parts. For instance:# >>> repr(1e17)# '1e17'# Unfortunately, this is not a valid float representation according# to the definition of the `!!float` tag. We fix this by adding# '.0' before the 'e' symbol.if'.'notinvalueand'e'invalue:value=value.replace('e','.0e',1)returnself.represent_scalar('tag:yaml.org,2002:float',value)defrepresent_list(self,data):#pairs = (len(data) > 0 and isinstance(data, list))#if pairs:# for item in data:# if not isinstance(item, tuple) or len(item) != 2:# pairs = False# break#if not pairs:returnself.represent_sequence('tag:yaml.org,2002:seq',data)#value = []#for item_key, item_value in data:# value.append(self.represent_mapping(u'tag:yaml.org,2002:map',# [(item_key, item_value)]))#return SequenceNode(u'tag:yaml.org,2002:pairs', value)defrepresent_dict(self,data):returnself.represent_mapping('tag:yaml.org,2002:map',data)defrepresent_set(self,data):value={}forkeyindata:value[key]=Nonereturnself.represent_mapping('tag:yaml.org,2002:set',value)defrepresent_date(self,data):value=data.isoformat()returnself.represent_scalar('tag:yaml.org,2002:timestamp',value)defrepresent_datetime(self,data):value=data.isoformat(' ')returnself.represent_scalar('tag:yaml.org,2002:timestamp',value)defrepresent_yaml_object(self,tag,data,cls,flow_style=None):ifhasattr(data,'__getstate__'):state=data.__getstate__()else:state=data.__dict__.copy()returnself.represent_mapping(tag,state,flow_style=flow_style)defrepresent_undefined(self,data):raiseRepresenterError("cannot represent an object",data)SafeRepresenter.add_representer(type(None),SafeRepresenter.represent_none)SafeRepresenter.add_representer(str,SafeRepresenter.represent_str)SafeRepresenter.add_representer(bytes,SafeRepresenter.represent_binary)SafeRepresenter.add_representer(bool,SafeRepresenter.represent_bool)SafeRepresenter.add_representer(int,SafeRepresenter.represent_int)SafeRepresenter.add_representer(float,SafeRepresenter.represent_float)SafeRepresenter.add_representer(list,SafeRepresenter.represent_list)SafeRepresenter.add_representer(tuple,SafeRepresenter.represent_list)SafeRepresenter.add_representer(dict,SafeRepresenter.represent_dict)SafeRepresenter.add_representer(set,SafeRepresenter.represent_set)SafeRepresenter.add_representer(datetime.date,SafeRepresenter.represent_date)SafeRepresenter.add_representer(datetime.datetime,SafeRepresenter.represent_datetime)SafeRepresenter.add_representer(None,SafeRepresenter.represent_undefined)classRepresenter(SafeRepresenter):defrepresent_complex(self,data):ifdata.imag==0.0:data='%r'%data.realelifdata.real==0.0:data='%rj'%data.imagelifdata.imag>0:data='%r+%rj'%(data.real,data.imag)else:data='%r%rj'%(data.real,data.imag)returnself.represent_scalar('tag:yaml.org,2002:python/complex',data)defrepresent_tuple(self,data):returnself.represent_sequence('tag:yaml.org,2002:python/tuple',data)defrepresent_name(self,data):name='%s.%s'%(data.__module__,data.__name__)returnself.represent_scalar('tag:yaml.org,2002:python/name:'+name,'')defrepresent_module(self,data):returnself.represent_scalar('tag:yaml.org,2002:python/module:'+data.__name__,'')defrepresent_object(self,data):# We use __reduce__ API to save the data. data.__reduce__ returns# a tuple of length 2-5:# (function, args, state, listitems, dictitems)# For reconstructing, we calls function(*args), then set its state,# listitems, and dictitems if they are not None.# A special case is when function.__name__ == '__newobj__'. In this# case we create the object with args[0].__new__(*args).# Another special case is when __reduce__ returns a string - we don't# support it.# We produce a !!python/object, !!python/object/new or# !!python/object/apply node.cls=type(data)ifclsincopyreg.dispatch_table:reduce=copyreg.dispatch_table[cls](data)elifhasattr(data,'__reduce_ex__'):reduce=data.__reduce_ex__(2)elifhasattr(data,'__reduce__'):reduce=data.__reduce__()else:raiseRepresenterError("cannot represent an object",data)reduce=(list(reduce)+[None]*5)[:5]function,args,state,listitems,dictitems=reduceargs=list(args)ifstateisNone:state={}iflistitemsisnotNone:listitems=list(listitems)ifdictitemsisnotNone:dictitems=dict(dictitems)iffunction.__name__=='__newobj__':function=args[0]args=args[1:]tag='tag:yaml.org,2002:python/object/new:'newobj=Trueelse:tag='tag:yaml.org,2002:python/object/apply:'newobj=Falsefunction_name='%s.%s'%(function.__module__,function.__name__)ifnotargsandnotlistitemsandnotdictitems \andisinstance(state,dict)andnewobj:returnself.represent_mapping('tag:yaml.org,2002:python/object:'+function_name,state)ifnotlistitemsandnotdictitems \andisinstance(state,dict)andnotstate:returnself.represent_sequence(tag+function_name,args)value={}ifargs:value['args']=argsifstateornotisinstance(state,dict):value['state']=stateiflistitems:value['listitems']=listitemsifdictitems:value['dictitems']=dictitemsreturnself.represent_mapping(tag+function_name,value)defrepresent_ordered_dict(self,data):# Provide uniform representation across different Python versions.data_type=type(data)tag='tag:yaml.org,2002:python/object/apply:%s.%s' \%(data_type.__module__,data_type.__name__)items=[[key,value]forkey,valueindata.items()]returnself.represent_sequence(tag,[items])Representer.add_representer(complex,Representer.represent_complex)Representer.add_representer(tuple,Representer.represent_tuple)Representer.add_multi_representer(type,Representer.represent_name)Representer.add_representer(collections.OrderedDict,Representer.represent_ordered_dict)Representer.add_representer(types.FunctionType,Representer.represent_name)Representer.add_representer(types.BuiltinFunctionType,Representer.represent_name)Representer.add_representer(types.ModuleType,Representer.represent_module)Representer.add_multi_representer(object,Representer.represent_object)