#NEWLINE# def _diff_( src , dst , ret = None , jp = None , exclude = [ ] , include = [ ] ) : #NEWLINE# #INDENT# " compare 2 dict/list, return a list containing\n    json-pointer indicating what's different, and what's diff exactly.\n\n    - list length diff: (jp, length of src, length of dst)\n    - dict key diff: (jp, None, None)\n    - when src is dict or list, and dst is not: (jp, type(src), type(dst))\n    - other: (jp, src, dst)\n    " #NEWLINE# def _dict_( src , dst , ret , jp ) : #NEWLINE# #INDENT# ( ss , sd ) = ( set ( src . keys ( ) ) , set ( dst . keys ( ) ) ) #NEWLINE# ( si , se ) = ( set ( ( include or [ ] ) ) , set ( ( exclude or [ ] ) ) ) #NEWLINE# ( ss , sd ) = ( ( ( ss & si ) , ( sd & si ) ) if si else ( ss , sd ) ) #NEWLINE# ( ss , sd ) = ( ( ( ss - se ) , ( sd - se ) ) if se else ( ss , sd ) ) #NEWLINE# for k in ( sd - ss ) : #NEWLINE# #INDENT# ret . append ( ( jp_compose ( k , base = jp ) , None , None ) ) #NEWLINE# #UNINDENT# for k in ( ss - sd ) : #NEWLINE# #INDENT# ret . append ( ( jp_compose ( k , base = jp ) , None , None ) ) #NEWLINE# #UNINDENT# for k in ( ss & sd ) : #NEWLINE# #INDENT# _diff_ ( src [ k ] , dst [ k ] , ret , jp_compose ( k , base = jp ) , exclude , include ) #NEWLINE# #UNINDENT# #UNINDENT# def _list_( src , dst , ret , jp ) : #NEWLINE# #INDENT# if ( len ( src ) < len ( dst ) ) : #NEWLINE# #INDENT# ret . append ( ( jp , len ( src ) , len ( dst ) ) ) #NEWLINE# #UNINDENT# else : #NEWLINE# #INDENT# if ( len ( src ) > len ( dst ) ) : #NEWLINE# #INDENT# ret . append ( ( jp , len ( src ) , len ( dst ) ) ) #NEWLINE# #UNINDENT# else : #NEWLINE# #INDENT# if ( len ( src ) == 0 ) : #NEWLINE# #INDENT# return #NEWLINE# #UNINDENT# def r( x , y ) : #NEWLINE# #INDENT# if ( type ( y ) != type ( x ) ) : #NEWLINE# #INDENT# raise ValueError ( 'different type: {0}, {1}' . format ( type ( y ) . __name__ , type ( x ) . __name__ ) ) #NEWLINE# #UNINDENT# return x #NEWLINE# #UNINDENT# ts = type ( functools . reduce ( r , src ) ) #NEWLINE# td = type ( functools . reduce ( r , dst ) ) #NEWLINE# while True : #NEWLINE# #INDENT# if ( issubclass ( ts , six . string_types ) and issubclass ( td , six . string_types ) ) : #NEWLINE# #INDENT# break #NEWLINE# #UNINDENT# if ( issubclass ( ts , six . integer_types ) and issubclass ( td , six . integer_types ) ) : #NEWLINE# #INDENT# break #NEWLINE# #UNINDENT# if ( ts == td ) : #NEWLINE# #INDENT# break #NEWLINE# #UNINDENT# ret . append ( ( jp , str ( ts ) , str ( td ) ) ) #NEWLINE# return #NEWLINE# #UNINDENT# if ( ts != dict ) : #NEWLINE# #INDENT# ( ss , sd ) = ( sorted ( src ) , sorted ( dst ) ) #NEWLINE# #UNINDENT# else : #NEWLINE# #INDENT# ( ss , sd ) = ( src , dst ) #NEWLINE# #UNINDENT# for ( idx , ( s , d ) ) in enumerate ( zip ( src , dst ) ) : #NEWLINE# #INDENT# _diff_ ( s , d , ret , jp_compose ( str ( idx ) , base = jp ) , exclude , include ) #NEWLINE# #UNINDENT# #UNINDENT# #UNINDENT# #UNINDENT# ret = ( [ ] if ( ret == None ) else ret ) #NEWLINE# jp = ( '' if ( jp == None ) else jp ) #NEWLINE# if isinstance ( src , dict ) : #NEWLINE# #INDENT# if ( not isinstance ( dst , dict ) ) : #NEWLINE# #INDENT# ret . append ( ( jp , type ( src ) . __name__ , type ( dst ) . __name__ ) ) #NEWLINE# #UNINDENT# else : #NEWLINE# #INDENT# _dict_ ( src , dst , ret , jp ) #NEWLINE# #UNINDENT# #UNINDENT# else : #NEWLINE# #INDENT# if isinstance ( src , list ) : #NEWLINE# #INDENT# if ( not isinstance ( dst , list ) ) : #NEWLINE# #INDENT# ret . append ( ( jp , type ( src ) . __name__ , type ( dst ) . __name__ ) ) #NEWLINE# #UNINDENT# else : #NEWLINE# #INDENT# _list_ ( src , dst , ret , jp ) #NEWLINE# #UNINDENT# #UNINDENT# else : #NEWLINE# #INDENT# if ( src != dst ) : #NEWLINE# #INDENT# ret . append ( ( jp , src , dst ) ) #NEWLINE# #UNINDENT# #UNINDENT# #UNINDENT# return ret