Best Python code snippet using tox_python
venv.py
Source:venv.py
1import ast2import codecs3import os4import re5import sys6import py7import tox8from .config import DepConfig9from .config import hookimpl10class CreationConfig:11 def __init__(self, md5, python, version, sitepackages,12 usedevelop, deps, alwayscopy):13 self.md5 = md514 self.python = python15 self.version = version16 self.sitepackages = sitepackages17 self.usedevelop = usedevelop18 self.alwayscopy = alwayscopy19 self.deps = deps20 def writeconfig(self, path):21 lines = ["%s %s" % (self.md5, self.python)]22 lines.append("%s %d %d %d" % (self.version, self.sitepackages,23 self.usedevelop, self.alwayscopy))24 for dep in self.deps:25 lines.append("%s %s" % dep)26 path.ensure()27 path.write("\n".join(lines))28 @classmethod29 def readconfig(cls, path):30 try:31 lines = path.readlines(cr=0)32 value = lines.pop(0).split(None, 1)33 md5, python = value34 version, sitepackages, usedevelop, alwayscopy = lines.pop(0).split(None, 4)35 sitepackages = bool(int(sitepackages))36 usedevelop = bool(int(usedevelop))37 alwayscopy = bool(int(alwayscopy))38 deps = []39 for line in lines:40 md5, depstring = line.split(None, 1)41 deps.append((md5, depstring))42 return CreationConfig(md5, python, version, sitepackages, usedevelop, deps, alwayscopy)43 except Exception:44 return None45 def matches(self, other):46 return (other and self.md5 == other.md5 and47 self.python == other.python and48 self.version == other.version and49 self.sitepackages == other.sitepackages and50 self.usedevelop == other.usedevelop and51 self.alwayscopy == other.alwayscopy and52 self.deps == other.deps)53class VirtualEnv(object):54 def __init__(self, envconfig=None, session=None):55 self.envconfig = envconfig56 self.session = session57 @property58 def hook(self):59 return self.envconfig.config.pluginmanager.hook60 @property61 def path(self):62 """ Path to environment base dir. """63 return self.envconfig.envdir64 @property65 def path_config(self):66 return self.path.join(".tox-config1")67 @property68 def name(self):69 """ test environment name. """70 return self.envconfig.envname71 def __repr__(self):72 return "<VirtualEnv at %r>" % (self.path)73 def getcommandpath(self, name, venv=True, cwd=None):74 """ Return absolute path (str or localpath) for specified command name.75 - If it's a local path we will rewrite it as as a relative path.76 - If venv is True we will check if the command is coming from the venv77 or is whitelisted to come from external.78 """79 name = str(name)80 if os.path.isabs(name):81 return name82 if os.path.split(name)[0] == ".":83 path = cwd.join(name)84 if path.check():85 return str(path)86 if venv:87 path = self._venv_lookup_and_check_external_whitelist(name)88 else:89 path = self._normal_lookup(name)90 if path is None:91 raise tox.exception.InvocationError(92 "could not find executable %r" % (name,))93 return str(path) # will not be rewritten for reporting94 def _venv_lookup_and_check_external_whitelist(self, name):95 path = self._venv_lookup(name)96 if path is None:97 path = self._normal_lookup(name)98 if path is not None:99 self._check_external_allowed_and_warn(path)100 return path101 def _venv_lookup(self, name):102 return py.path.local.sysfind(name, paths=[self.envconfig.envbindir])103 def _normal_lookup(self, name):104 return py.path.local.sysfind(name)105 def _check_external_allowed_and_warn(self, path):106 if not self.is_allowed_external(path):107 self.session.report.warning(108 "test command found but not installed in testenv\n"109 " cmd: %s\n"110 " env: %s\n"111 "Maybe you forgot to specify a dependency? "112 "See also the whitelist_externals envconfig setting." % (113 path, self.envconfig.envdir))114 def is_allowed_external(self, p):115 tryadd = [""]116 if sys.platform == "win32":117 tryadd += [118 os.path.normcase(x)119 for x in os.environ['PATHEXT'].split(os.pathsep)120 ]121 p = py.path.local(os.path.normcase(str(p)))122 for x in self.envconfig.whitelist_externals:123 for add in tryadd:124 if p.fnmatch(x + add):125 return True126 return False127 def update(self, action):128 """ return status string for updating actual venv to match configuration.129 if status string is empty, all is ok.130 """131 rconfig = CreationConfig.readconfig(self.path_config)132 if not self.envconfig.recreate and rconfig and \133 rconfig.matches(self._getliveconfig()):134 action.info("reusing", self.envconfig.envdir)135 return136 if rconfig is None:137 action.setactivity("create", self.envconfig.envdir)138 else:139 action.setactivity("recreate", self.envconfig.envdir)140 try:141 self.hook.tox_testenv_create(action=action, venv=self)142 self.just_created = True143 except tox.exception.UnsupportedInterpreter:144 return sys.exc_info()[1]145 try:146 self.hook.tox_testenv_install_deps(action=action, venv=self)147 except tox.exception.InvocationError:148 v = sys.exc_info()[1]149 return "could not install deps %s; v = %r" % (150 self.envconfig.deps, v)151 def _getliveconfig(self):152 python = self.envconfig.python_info.executable153 md5 = getdigest(python)154 version = tox.__version__155 sitepackages = self.envconfig.sitepackages156 develop = self.envconfig.usedevelop157 alwayscopy = self.envconfig.alwayscopy158 deps = []159 for dep in self._getresolvedeps():160 raw_dep = dep.name161 md5 = getdigest(raw_dep)162 deps.append((md5, raw_dep))163 return CreationConfig(md5, python, version,164 sitepackages, develop, deps, alwayscopy)165 def _getresolvedeps(self):166 deps = []167 for dep in self.envconfig.deps:168 if dep.indexserver is None:169 res = self.session._resolve_pkg(dep.name)170 if res != dep.name:171 dep = dep.__class__(res)172 deps.append(dep)173 return deps174 def getsupportedinterpreter(self):175 return self.envconfig.getsupportedinterpreter()176 def matching_platform(self):177 return re.match(self.envconfig.platform, sys.platform)178 def finish(self):179 self._getliveconfig().writeconfig(self.path_config)180 def _needs_reinstall(self, setupdir, action):181 setup_py = setupdir.join('setup.py')182 setup_cfg = setupdir.join('setup.cfg')183 args = [self.envconfig.envpython, str(setup_py), '--name']184 env = self._getenv()185 output = action.popen(args, cwd=setupdir, redirect=False,186 returnout=True, env=env)187 name = output.strip()188 args = [self.envconfig.envpython, '-c', 'import sys; print(sys.path)']189 out = action.popen(args, redirect=False, returnout=True, env=env)190 try:191 sys_path = ast.literal_eval(out.strip())192 except SyntaxError:193 sys_path = []194 egg_info_fname = '.'.join((name, 'egg-info'))195 for d in reversed(sys_path):196 egg_info = py.path.local(d).join(egg_info_fname)197 if egg_info.check():198 break199 else:200 return True201 return any(202 conf_file.check() and conf_file.mtime() > egg_info.mtime()203 for conf_file in (setup_py, setup_cfg)204 )205 def developpkg(self, setupdir, action):206 assert action is not None207 if getattr(self, 'just_created', False):208 action.setactivity("develop-inst", setupdir)209 self.finish()210 extraopts = []211 else:212 if not self._needs_reinstall(setupdir, action):213 action.setactivity("develop-inst-noop", setupdir)214 return215 action.setactivity("develop-inst-nodeps", setupdir)216 extraopts = ['--no-deps']217 if action.venv.envconfig.extras:218 setupdir += '[%s]' % ','.join(action.venv.envconfig.extras)219 self._install(['-e', setupdir], extraopts=extraopts, action=action)220 def installpkg(self, sdistpath, action):221 assert action is not None222 if getattr(self, 'just_created', False):223 action.setactivity("inst", sdistpath)224 self.finish()225 extraopts = []226 else:227 action.setactivity("inst-nodeps", sdistpath)228 extraopts = ['-U', '--no-deps']229 if action.venv.envconfig.extras:230 sdistpath += '[%s]' % ','.join(action.venv.envconfig.extras)231 self._install([sdistpath], extraopts=extraopts, action=action)232 def _installopts(self, indexserver):233 options = []234 if indexserver:235 options += ["-i", indexserver]236 if self.envconfig.pip_pre:237 options.append("--pre")238 return options239 def run_install_command(self, packages, action, options=()):240 argv = self.envconfig.install_command[:]241 i = argv.index('{packages}')242 argv[i:i + 1] = packages243 if '{opts}' in argv:244 i = argv.index('{opts}')245 argv[i:i + 1] = list(options)246 for x in ('PIP_RESPECT_VIRTUALENV', 'PIP_REQUIRE_VIRTUALENV',247 '__PYVENV_LAUNCHER__'):248 os.environ.pop(x, None)249 if 'PYTHONPATH' not in self.envconfig.passenv:250 # If PYTHONPATH not explicitly asked for, remove it.251 if 'PYTHONPATH' in os.environ:252 self.session.report.warning(253 "Discarding $PYTHONPATH from environment, to override "254 "specify PYTHONPATH in 'passenv' in your configuration."255 )256 os.environ.pop('PYTHONPATH')257 old_stdout = sys.stdout258 sys.stdout = codecs.getwriter('utf8')(sys.stdout)259 try:260 self._pcall(argv, cwd=self.envconfig.config.toxinidir,261 action=action, redirect=self.session.report.verbosity < 2)262 finally:263 sys.stdout = old_stdout264 def _install(self, deps, extraopts=None, action=None):265 if not deps:266 return267 d = {}268 ixservers = []269 for dep in deps:270 if isinstance(dep, (str, py.path.local)):271 dep = DepConfig(str(dep), None)272 assert isinstance(dep, DepConfig), dep273 if dep.indexserver is None:274 ixserver = self.envconfig.config.indexserver['default']275 else:276 ixserver = dep.indexserver277 d.setdefault(ixserver, []).append(dep.name)278 if ixserver not in ixservers:279 ixservers.append(ixserver)280 assert ixserver.url is None or isinstance(ixserver.url, str)281 for ixserver in ixservers:282 packages = d[ixserver]283 options = self._installopts(ixserver.url)284 if extraopts:285 options.extend(extraopts)286 self.run_install_command(packages=packages, options=options,287 action=action)288 def _getenv(self, testcommand=False):289 if testcommand:290 # for executing tests we construct a clean environment291 env = {}292 for envname in self.envconfig.passenv:293 if envname in os.environ:294 env[envname] = os.environ[envname]295 else:296 # for executing non-test commands we use the full297 # invocation environment298 env = os.environ.copy()299 # in any case we honor per-testenv setenv configuration300 env.update(self.envconfig.setenv)301 env['VIRTUAL_ENV'] = str(self.path)302 return env303 def test(self, redirect=False):304 action = self.session.newaction(self, "runtests")305 with action:306 self.status = 0307 self.session.make_emptydir(self.envconfig.envtmpdir)308 self.envconfig.envtmpdir.ensure(dir=1)309 cwd = self.envconfig.changedir310 env = self._getenv(testcommand=True)311 # Display PYTHONHASHSEED to assist with reproducibility.312 action.setactivity("runtests", "PYTHONHASHSEED=%r" % env.get('PYTHONHASHSEED'))313 for i, argv in enumerate(self.envconfig.commands):314 # have to make strings as _pcall changes argv[0] to a local()315 # happens if the same environment is invoked twice316 message = "commands[%s] | %s" % (i, ' '.join(317 [str(x) for x in argv]))318 action.setactivity("runtests", message)319 # check to see if we need to ignore the return code320 # if so, we need to alter the command line arguments321 if argv[0].startswith("-"):322 ignore_ret = True323 if argv[0] == "-":324 del argv[0]325 else:326 argv[0] = argv[0].lstrip("-")327 else:328 ignore_ret = False329 try:330 self._pcall(argv, cwd=cwd, action=action, redirect=redirect,331 ignore_ret=ignore_ret, testcommand=True)332 except tox.exception.InvocationError as err:333 if self.envconfig.ignore_outcome:334 self.session.report.warning(335 "command failed but result from testenv is ignored\n"336 " cmd: %s" % (str(err),))337 self.status = "ignored failed command"338 continue # keep processing commands339 self.session.report.error(str(err))340 self.status = "commands failed"341 if not self.envconfig.ignore_errors:342 break # Don't process remaining commands343 except KeyboardInterrupt:344 self.status = "keyboardinterrupt"345 self.session.report.error(self.status)346 raise347 def _pcall(self, args, cwd, venv=True, testcommand=False,348 action=None, redirect=True, ignore_ret=False):349 os.environ.pop('VIRTUALENV_PYTHON', None)350 cwd.ensure(dir=1)351 args[0] = self.getcommandpath(args[0], venv, cwd)352 env = self._getenv(testcommand=testcommand)353 bindir = str(self.envconfig.envbindir)354 env['PATH'] = p = os.pathsep.join([bindir, os.environ["PATH"]])355 self.session.report.verbosity2("setting PATH=%s" % p)356 return action.popen(args, cwd=cwd, env=env,357 redirect=redirect, ignore_ret=ignore_ret)358def getdigest(path):359 path = py.path.local(path)360 if not path.check(file=1):361 return "0" * 32362 return path.computehash()363@hookimpl364def tox_testenv_create(venv, action):365 # if self.getcommandpath("activate").dirpath().check():366 # return367 config_interpreter = venv.getsupportedinterpreter()368 args = [sys.executable, '-m', 'virtualenv']369 if venv.envconfig.sitepackages:370 args.append('--system-site-packages')371 if venv.envconfig.alwayscopy:372 args.append('--always-copy')373 # add interpreter explicitly, to prevent using374 # default (virtualenv.ini)375 args.extend(['--python', str(config_interpreter)])376 # if sys.platform == "win32":377 # f, path, _ = imp.find_module("virtualenv")378 # f.close()379 # args[:1] = [str(config_interpreter), str(path)]380 # else:381 venv.session.make_emptydir(venv.path)382 basepath = venv.path.dirpath()383 basepath.ensure(dir=1)384 args.append(venv.path.basename)385 venv._pcall(args, venv=False, action=action, cwd=basepath)386 # Return non-None to indicate the plugin has completed387 return True388@hookimpl389def tox_testenv_install_deps(venv, action):390 deps = venv._getresolvedeps()391 if deps:392 depinfo = ", ".join(map(str, deps))393 action.setactivity("installdeps", "%s" % depinfo)394 venv._install(deps, action=action)395 # Return non-None to indicate the plugin has completed396 return True397@hookimpl398def tox_runtest(venv, redirect):399 venv.test(redirect=redirect)400 # Return non-None to indicate the plugin has completed401 return True402@hookimpl403def tox_runenvreport(venv, action):404 # write out version dependency information405 args = venv.envconfig.list_dependencies_command406 output = venv._pcall(args,407 cwd=venv.envconfig.config.toxinidir,408 action=action)409 # the output contains a mime-header, skip it410 output = output.split("\n\n")[-1]411 packages = output.strip().split("\n")412 # Return non-None to indicate the plugin has completed...
Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.
You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.
Get 100 minutes of automation test minutes FREE!!