environment.py 1.7 KB

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