#!/usr/bin/env python suba = 'subA' subb = 'subB' subc = 'subC' main_script=r""" import foo try: print foo.function() except: import sys,traceback traceback.print_exc(file=sys.stdout) raise """ foo_script=""" import bar def function(): return bar.bar_func() """ bar_script=r""" def bar_func(): raise 'failure' """ import os,shutil,sys shutil.rmtree(suba, 1) shutil.rmtree(subb, 1) shutil.rmtree(subc, 1) os.mkdir(suba) m = open(os.path.join(suba, 'main.py'), 'w') m.write(main_script) m.close() f = open(os.path.join(suba, 'foo.py'), 'w') f.write(foo_script) f.close() f = open(os.path.join(suba, 'bar.py'), 'w') f.write(bar_script) f.close() origdir = os.getcwd() def cmp_errs(err_and_dir_1, err_and_dir_2): err1, dir1 = err_and_dir_1 err2, dir2 = err_and_dir_2 mismatches=[] for i in range(len(err1)): if err1[i] != err2[i].replace(dir2,dir1): mismatches.append(i) mismatches.extend(range(len(err1),len(err2))) if mismatches: print '-- Error: output mismatch (beyond dirname change): --' for i in range(len(err1)): if i in mismatches: print '1-',err1[i][:-1] else: print '1 ',err1[i][:-1] for i in range(len(err2)): if i in mismatches: print '2+',err2[i][:-1] else: print '2 ',err1[i][:-1] else: print '++ Output identical (accounting for dirname change)' ## First run to get the foo.pyc files in each dir try: os.chdir(suba) inp,out,err = os.popen3('python main.py') out1 = out.readlines() err1 = err.readlines() finally: os.chdir(origdir) print '====== Comparing print_tb to interpreter stacktrace ======' cmp_errs( (out1,suba), (err1,suba) ) ## Move the directory and run the test again, then compare the ## results. Note that when the original directory doesn't exist, this ## is detected and the traceback is regenerated with the appropriate ## current directory names. print print '#'*56 print '## Renamed; previous directory does not exist' os.rename(suba, subb) try: os.chdir(subb) inp,out,err = os.popen3('python main.py') out2 = out.readlines() err2 = err.readlines() finally: os.chdir(origdir) print '====== Comparing print_tb to interpreter stacktrace ======' cmp_errs( (out2,subb), (err2,subb) ) print '====== Comparing old stderr to new stderr ======' cmp_errs( (err1, suba), (err2, subb) ) ## Move the directory again, but make sure the old directory is still ## valid (although empty). Run the test and observe that in this ## case, the old directory name is used in the traceback, and the file ## contents lines in the traceback are "None" print print '#'*56 print '## Renamed; previous directory does exist but .py files differ' os.mkdir(suba) m = open(os.path.join(suba, 'main.py'), 'w') m.write('empty main\n') m.close() f = open(os.path.join(suba, 'foo.py'), 'w') f.write('empty foo\n') f.close() f = open(os.path.join(suba, 'bar.py'), 'w') f.write('empty bar\n') f.close() try: os.chdir(subb) inp,out,err = os.popen3('python main.py') out3 = out.readlines() err3 = err.readlines() finally: os.chdir(origdir) print '====== Comparing print_tb to interpreter stacktrace ======' cmp_errs( (out3,subb), (err3,subb) ) print '====== Comparing old stderr to new stderr ======' cmp_errs( (err1, suba), (err3, subb) ) ## Try that again, but instead of non-existent lines in the new .py ## files (in the old location), put nonsense there. Watch it get ## echoed. print print '#'*56 print '## Renamed; nonsense .py files in old location' m = open(os.path.join(suba, 'main.py'), 'w') m.write("""\ mary had a little lamb whose fleece was white as snow and everywhere that mary went that lamb was sure to go """) m.close() f = open(os.path.join(suba, 'foo.py'), 'w') f.write("""\ row row row your boat gently down the stream merrily merrily merrily merrily life is but a dream """) f.close() f = open(os.path.join(suba, 'bar.py'), 'w') f.write(""" Twas brillig, and the slithy toves Did gyre and gimble in the wabe: All mimsy were the borogoves, And the mome raths outgrabe. """) f.close() try: os.chdir(subb) inp,out,err = os.popen3('python main.py') out3 = out.readlines() err3 = err.readlines() finally: os.chdir(origdir) print '====== Comparing print_tb to interpreter stacktrace ======' cmp_errs( (out3,subb), (err3,subb) ) print '====== Comparing old stderr to new stderr ======' cmp_errs( (err1, suba), (err3, subb) )