1import os 2import sys 3import unicodedata 4 5from subprocess import Popen as _Popen, PIPE as _PIPE 6 7 8def _which_dirs(cmd): 9 result = set() 10 for path in os.environ.get('PATH', '').split(os.pathsep): 11 filename = os.path.join(path, cmd) 12 if os.access(filename, os.X_OK): 13 result.add(path) 14 return result 15 16 17def run_setup_py(cmd, pypath=None, path=None, 18 data_stream=0, env=None): 19 """ 20 Execution command for tests, separate from those used by the 21 code directly to prevent accidental behavior issues 22 """ 23 if env is None: 24 env = dict() 25 for envname in os.environ: 26 env[envname] = os.environ[envname] 27 28 # override the python path if needed 29 if pypath is not None: 30 env["PYTHONPATH"] = pypath 31 32 # overide the execution path if needed 33 if path is not None: 34 env["PATH"] = path 35 if not env.get("PATH", ""): 36 env["PATH"] = _which_dirs("tar").union(_which_dirs("gzip")) 37 env["PATH"] = os.pathsep.join(env["PATH"]) 38 39 cmd = [sys.executable, "setup.py"] + list(cmd) 40 41 # http://bugs.python.org/issue8557 42 shell = sys.platform == 'win32' 43 44 try: 45 proc = _Popen( 46 cmd, stdout=_PIPE, stderr=_PIPE, shell=shell, env=env, 47 ) 48 49 data = proc.communicate()[data_stream] 50 except OSError: 51 return 1, '' 52 53 # decode the console string if needed 54 if hasattr(data, "decode"): 55 # use the default encoding 56 data = data.decode() 57 data = unicodedata.normalize('NFC', data) 58 59 # communicate calls wait() 60 return proc.returncode, data 61