codekingpro/portable-devtools
114k
1import os2import subprocess3import sys4import unicodedata5from subprocess import PIPE as _PIPE, Popen as _Popen6 7import jaraco.envs8 9 10class VirtualEnv(jaraco.envs.VirtualEnv):11 name = '.env'12 # Some version of PyPy will import distutils on startup, implicitly13 # importing setuptools, and thus leading to BackendInvalid errors14 # when upgrading Setuptools. Bypass this behavior by avoiding the15 # early availability and need to upgrade.16 create_opts = ['--no-setuptools']17 18 def run(self, cmd, *args, **kwargs):19 cmd = [self.exe(cmd[0])] + cmd[1:]20 kwargs = {"cwd": self.root, "encoding": "utf-8", **kwargs} # Allow overriding21 # In some environments (eg. downstream distro packaging), where:22 # - tox isn't used to run tests and23 # - PYTHONPATH is set to point to a specific setuptools codebase and24 # - no custom env is explicitly set by a test25 # PYTHONPATH will leak into the spawned processes.26 # In that case tests look for module in the wrong place (on PYTHONPATH).27 # Unless the test sets its own special env, pass a copy of the existing28 # environment with removed PYTHONPATH to the subprocesses.29 if "env" not in kwargs:30 env = dict(os.environ)31 if "PYTHONPATH" in env:32 del env["PYTHONPATH"]33 kwargs["env"] = env34 return subprocess.check_output(cmd, *args, **kwargs)35 36 37def _which_dirs(cmd):38 result = set()39 for path in os.environ.get('PATH', '').split(os.pathsep):40 filename = os.path.join(path, cmd)41 if os.access(filename, os.X_OK):42 result.add(path)43 return result44 45 46def run_setup_py(cmd, pypath=None, path=None, data_stream=0, env=None):47 """48 Execution command for tests, separate from those used by the49 code directly to prevent accidental behavior issues50 """51 if env is None:52 env = dict()53 for envname in os.environ:54 env[envname] = os.environ[envname]55 56 # override the python path if needed57 if pypath is not None:58 env["PYTHONPATH"] = pypath59 60 # override the execution path if needed61 if path is not None:62 env["PATH"] = path63 if not env.get("PATH", ""):64 env["PATH"] = _which_dirs("tar").union(_which_dirs("gzip"))65 env["PATH"] = os.pathsep.join(env["PATH"])66 67 cmd = [sys.executable, "setup.py"] + list(cmd)68 69 # https://bugs.python.org/issue855770 shell = sys.platform == 'win32'71 72 try:73 proc = _Popen(74 cmd,75 stdout=_PIPE,76 stderr=_PIPE,77 shell=shell,78 env=env,79 encoding="utf-8",80 )81 82 if isinstance(data_stream, tuple):83 data_stream = slice(*data_stream)84 data = proc.communicate()[data_stream]85 except OSError:86 return 1, ''87 88 # decode the console string if needed89 if hasattr(data, "decode"):90 # use the default encoding91 data = data.decode()92 data = unicodedata.normalize('NFC', data)93 94 # communicate calls wait()95 return proc.returncode, data96 