1# Licensed under the Apache License: http://www.apache.org/licenses/LICENSE-2.0 2# For details: https://bitbucket.org/ned/coveragepy/src/default/NOTICE.txt 3 4"""Test file for run_python_file. 5 6This file is executed two ways:: 7 8 $ coverage run try_execfile.py 9 10and:: 11 12 $ python try_execfile.py 13 14The output is compared to see that the program execution context is the same 15under coverage and under Python. 16 17It is not crucial that the execution be identical, there are some differences 18that are OK. This program canonicalizes the output to gloss over those 19differences and get a clean diff. 20 21""" 22 23import itertools 24import json 25import os 26import sys 27 28# sys.path varies by execution environments. Coverage.py uses setuptools to 29# make console scripts, which means pkg_resources is imported. pkg_resources 30# removes duplicate entries from sys.path. So we do that too, since the extra 31# entries don't affect the running of the program. 32 33def same_file(p1, p2): 34 """Determine if `p1` and `p2` refer to the same existing file.""" 35 if not p1: 36 return not p2 37 if not os.path.exists(p1): 38 return False 39 if not os.path.exists(p2): 40 return False 41 if hasattr(os.path, "samefile"): 42 return os.path.samefile(p1, p2) 43 else: 44 norm1 = os.path.normcase(os.path.normpath(p1)) 45 norm2 = os.path.normcase(os.path.normpath(p2)) 46 return norm1 == norm2 47 48def without_same_files(filenames): 49 """Return the list `filenames` with duplicates (by same_file) removed.""" 50 reduced = [] 51 for filename in filenames: 52 if not any(same_file(filename, other) for other in reduced): 53 reduced.append(filename) 54 return reduced 55 56cleaned_sys_path = [os.path.normcase(p) for p in without_same_files(sys.path)] 57 58DATA = "xyzzy" 59 60import __main__ 61 62def my_function(a): 63 """A function to force execution of module-level values.""" 64 return "my_fn(%r)" % a 65 66FN_VAL = my_function("fooey") 67 68loader = globals().get('__loader__') 69fullname = getattr(loader, 'fullname', None) or getattr(loader, 'name', None) 70 71# A more compact grouped-by-first-letter list of builtins. 72def word_group(w): 73 """Clump AB, CD, EF, etc.""" 74 return chr((ord(w[0]) + 1) & 0xFE) 75 76builtin_dir = [" ".join(s) for _, s in itertools.groupby(dir(__builtins__), key=word_group)] 77 78globals_to_check = { 79 'os.getcwd': os.getcwd(), 80 '__name__': __name__, 81 '__file__': __file__, 82 '__doc__': __doc__, 83 '__builtins__.has_open': hasattr(__builtins__, 'open'), 84 '__builtins__.dir': builtin_dir, 85 '__loader__ exists': loader is not None, 86 '__loader__.fullname': fullname, 87 '__package__': __package__, 88 'DATA': DATA, 89 'FN_VAL': FN_VAL, 90 '__main__.DATA': getattr(__main__, "DATA", "nothing"), 91 'argv0': sys.argv[0], 92 'argv1-n': sys.argv[1:], 93 'path': cleaned_sys_path, 94} 95 96print(json.dumps(globals_to_check, indent=4, sort_keys=True)) 97