""compare all subdirectories and files in two directory treesuses binary files to prevent unicode decoding and endline transformsas trees might contain arbitrary binary files as well as arbitrary textmay need bytes listdir arg for undecodable filenames on some platforms ""compare file name lists print('- names os listdir(dir names os listdir(dir if not dirdiff comparedirs(dir dir names names )diffs append('unique files at % % (dir dir )print('comparing contents'common intersect(names names missed common[:compare contents of files in common for name in commonpath os path join(dir namepath os path join(dir nameif os path isfile(path and os path isfile(path )missed remove(namefile open(path 'rb'file open(path 'rb'while truebytes file read(blocksizebytes file read(blocksizeif (not bytes and (not bytes )if verboseprint(name'matches'break if bytes !bytes diffs append('files differ at % % (path path )print(name'differs'break recur to compare directories in common for name in commonpath os path join(dir namepath os path join(dir nameif os path isdir(path and os path isdir(path )missed remove(namecomparetrees(path path diffsverbosesame name but not both files or dirsfor name in misseddiffs append('files missed at % % % (dir dir name)print(name'differs'if __name__ ='__main__'dir dir dirdiff getargs(diffs [ complete system programs