You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

96 rivejä
3.0 KiB

  1. import os
  2. import subprocess
  3. import sys
  4. import unicodedata
  5. from subprocess import PIPE as _PIPE, Popen as _Popen
  6. import jaraco.envs
  7. class VirtualEnv(jaraco.envs.VirtualEnv):
  8. name = '.env'
  9. # Some version of PyPy will import distutils on startup, implicitly
  10. # importing setuptools, and thus leading to BackendInvalid errors
  11. # when upgrading Setuptools. Bypass this behavior by avoiding the
  12. # early availability and need to upgrade.
  13. create_opts = ['--no-setuptools']
  14. def run(self, cmd, *args, **kwargs):
  15. cmd = [self.exe(cmd[0])] + cmd[1:]
  16. kwargs = {"cwd": self.root, "encoding": "utf-8", **kwargs} # Allow overriding
  17. # In some environments (eg. downstream distro packaging), where:
  18. # - tox isn't used to run tests and
  19. # - PYTHONPATH is set to point to a specific setuptools codebase and
  20. # - no custom env is explicitly set by a test
  21. # PYTHONPATH will leak into the spawned processes.
  22. # In that case tests look for module in the wrong place (on PYTHONPATH).
  23. # Unless the test sets its own special env, pass a copy of the existing
  24. # environment with removed PYTHONPATH to the subprocesses.
  25. if "env" not in kwargs:
  26. env = dict(os.environ)
  27. if "PYTHONPATH" in env:
  28. del env["PYTHONPATH"]
  29. kwargs["env"] = env
  30. return subprocess.check_output(cmd, *args, **kwargs)
  31. def _which_dirs(cmd):
  32. result = set()
  33. for path in os.environ.get('PATH', '').split(os.pathsep):
  34. filename = os.path.join(path, cmd)
  35. if os.access(filename, os.X_OK):
  36. result.add(path)
  37. return result
  38. def run_setup_py(cmd, pypath=None, path=None, data_stream=0, env=None):
  39. """
  40. Execution command for tests, separate from those used by the
  41. code directly to prevent accidental behavior issues
  42. """
  43. if env is None:
  44. env = dict()
  45. for envname in os.environ:
  46. env[envname] = os.environ[envname]
  47. # override the python path if needed
  48. if pypath is not None:
  49. env["PYTHONPATH"] = pypath
  50. # override the execution path if needed
  51. if path is not None:
  52. env["PATH"] = path
  53. if not env.get("PATH", ""):
  54. env["PATH"] = _which_dirs("tar").union(_which_dirs("gzip"))
  55. env["PATH"] = os.pathsep.join(env["PATH"])
  56. cmd = [sys.executable, "setup.py"] + list(cmd)
  57. # https://bugs.python.org/issue8557
  58. shell = sys.platform == 'win32'
  59. try:
  60. proc = _Popen(
  61. cmd,
  62. stdout=_PIPE,
  63. stderr=_PIPE,
  64. shell=shell,
  65. env=env,
  66. encoding="utf-8",
  67. )
  68. if isinstance(data_stream, tuple):
  69. data_stream = slice(*data_stream)
  70. data = proc.communicate()[data_stream]
  71. except OSError:
  72. return 1, ''
  73. # decode the console string if needed
  74. if hasattr(data, "decode"):
  75. # use the default encoding
  76. data = data.decode()
  77. data = unicodedata.normalize('NFC', data)
  78. # communicate calls wait()
  79. return proc.returncode, data