#NEWLINE# def merge( a , b ) : #NEWLINE# #INDENT# '\n    Recursively merge datasets of a and b together so that:\n\n    * Dicts are (recursively) merged\n    * Lists are appended together\n    * Other types take the value from b\n\n    A ValueError is raised when trying to merge two items of\n    a different type.\n    ' #NEWLINE# if ( type ( a ) != type ( b ) ) : #NEWLINE# #INDENT# raise ValueError ( 'Trying to merge two different types of data:\nValue A {a_type} = {a_value}\n\nValue B {b_type} = {b_value}\n' . format ( a_type = type ( a ) , a_value = a , b_type = type ( b ) , b_value = b ) ) #NEWLINE# #UNINDENT# result = None #NEWLINE# if isinstance ( b , list ) : #NEWLINE# #INDENT# result = list ( set ( ( a + b ) ) ) #NEWLINE# #UNINDENT# else : #NEWLINE# #INDENT# if isinstance ( b , dict ) : #NEWLINE# #INDENT# result = deepcopy ( a ) #NEWLINE# for ( k , v ) in b . items ( ) : #NEWLINE# #INDENT# if ( k in result ) : #NEWLINE# #INDENT# result [ k ] = merge ( result [ k ] , v ) #NEWLINE# #UNINDENT# else : #NEWLINE# #INDENT# result [ k ] = deepcopy ( v ) #NEWLINE# #UNINDENT# #UNINDENT# #UNINDENT# else : #NEWLINE# #INDENT# return b #NEWLINE# #UNINDENT# #UNINDENT# return result