blob: 28d5e9d13bef34514d64df7d95044e356a272839 [file] [log] [blame]
Nick Coghlan260bd3e2009-11-16 06:49:25 +00001# Common utility functions used by various script execution tests
2# e.g. test_cmd_line, test_cmd_line_script and test_runpy
3
4import sys
5import os
6import os.path
7import tempfile
8import subprocess
9import py_compile
10import contextlib
11import shutil
12import zipfile
13
Barry Warsaw28a691b2010-04-17 00:19:56 +000014from imp import source_from_cache
15from test.support import make_legacy_pyc
16
Nick Coghlan260bd3e2009-11-16 06:49:25 +000017# Executing the interpreter in a subprocess
18def python_exit_code(*args):
19 cmd_line = [sys.executable, '-E']
20 cmd_line.extend(args)
21 with open(os.devnull, 'w') as devnull:
22 return subprocess.call(cmd_line, stdout=devnull,
23 stderr=subprocess.STDOUT)
24
25def spawn_python(*args):
26 cmd_line = [sys.executable, '-E']
27 cmd_line.extend(args)
28 return subprocess.Popen(cmd_line, stdin=subprocess.PIPE,
29 stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
30
31def kill_python(p):
32 p.stdin.close()
33 data = p.stdout.read()
34 p.stdout.close()
35 # try to cleanup the child so we don't appear to leak when running
Antoine Pitrou4e7dc5f2009-12-08 19:27:24 +000036 # with regrtest -R.
37 p.wait()
Nick Coghlan260bd3e2009-11-16 06:49:25 +000038 subprocess._cleanup()
39 return data
40
41def run_python(*args):
42 if __debug__:
43 p = spawn_python(*args)
44 else:
45 p = spawn_python('-O', *args)
46 stdout_data = kill_python(p)
47 return p.wait(), stdout_data
48
49# Script creation utilities
50@contextlib.contextmanager
51def temp_dir():
52 dirname = tempfile.mkdtemp()
53 dirname = os.path.realpath(dirname)
54 try:
55 yield dirname
56 finally:
57 shutil.rmtree(dirname)
58
59def make_script(script_dir, script_basename, source):
60 script_filename = script_basename+os.extsep+'py'
61 script_name = os.path.join(script_dir, script_filename)
Florent Xicluna8de42e22010-02-27 16:12:22 +000062 # The script should be encoded to UTF-8, the default string encoding
63 script_file = open(script_name, 'w', encoding='utf-8')
Nick Coghlan260bd3e2009-11-16 06:49:25 +000064 script_file.write(source)
65 script_file.close()
66 return script_name
67
Nick Coghlan260bd3e2009-11-16 06:49:25 +000068def make_zip_script(zip_dir, zip_basename, script_name, name_in_zip=None):
69 zip_filename = zip_basename+os.extsep+'zip'
70 zip_name = os.path.join(zip_dir, zip_filename)
71 zip_file = zipfile.ZipFile(zip_name, 'w')
72 if name_in_zip is None:
Barry Warsaw28a691b2010-04-17 00:19:56 +000073 parts = script_name.split(os.sep)
74 if len(parts) >= 2 and parts[-2] == '__pycache__':
75 legacy_pyc = make_legacy_pyc(source_from_cache(script_name))
76 name_in_zip = os.path.basename(legacy_pyc)
77 script_name = legacy_pyc
78 else:
79 name_in_zip = os.path.basename(script_name)
Nick Coghlan260bd3e2009-11-16 06:49:25 +000080 zip_file.write(script_name, name_in_zip)
81 zip_file.close()
Florent Xicluna02ea12b22010-07-28 16:39:41 +000082 #if test.support.verbose:
Nick Coghlan260bd3e2009-11-16 06:49:25 +000083 # zip_file = zipfile.ZipFile(zip_name, 'r')
84 # print 'Contents of %r:' % zip_name
85 # zip_file.printdir()
86 # zip_file.close()
87 return zip_name, os.path.join(zip_name, name_in_zip)
88
89def make_pkg(pkg_dir):
90 os.mkdir(pkg_dir)
91 make_script(pkg_dir, '__init__', '')
92
93def make_zip_pkg(zip_dir, zip_basename, pkg_name, script_basename,
94 source, depth=1, compiled=False):
95 unlink = []
96 init_name = make_script(zip_dir, '__init__', '')
97 unlink.append(init_name)
98 init_basename = os.path.basename(init_name)
99 script_name = make_script(zip_dir, script_basename, source)
100 unlink.append(script_name)
101 if compiled:
Barry Warsaw28a691b2010-04-17 00:19:56 +0000102 init_name = py_compile(init_name, doraise=True)
103 script_name = py_compile(script_name, doraise=True)
Nick Coghlan260bd3e2009-11-16 06:49:25 +0000104 unlink.extend((init_name, script_name))
105 pkg_names = [os.sep.join([pkg_name]*i) for i in range(1, depth+1)]
106 script_name_in_zip = os.path.join(pkg_names[-1], os.path.basename(script_name))
107 zip_filename = zip_basename+os.extsep+'zip'
108 zip_name = os.path.join(zip_dir, zip_filename)
109 zip_file = zipfile.ZipFile(zip_name, 'w')
110 for name in pkg_names:
111 init_name_in_zip = os.path.join(name, init_basename)
112 zip_file.write(init_name, init_name_in_zip)
113 zip_file.write(script_name, script_name_in_zip)
114 zip_file.close()
115 for name in unlink:
116 os.unlink(name)
Florent Xicluna02ea12b22010-07-28 16:39:41 +0000117 #if test.support.verbose:
Nick Coghlan260bd3e2009-11-16 06:49:25 +0000118 # zip_file = zipfile.ZipFile(zip_name, 'r')
119 # print 'Contents of %r:' % zip_name
120 # zip_file.printdir()
121 # zip_file.close()
122 return zip_name, os.path.join(zip_name, script_name_in_zip)