How to use add_testenv_attribute method in tox

Best Python code snippet using tox_python

config.py

Source:config.py Github

copy

Full Screen

...46 """ add argument to command line parser. This takes the47 same arguments that ``argparse.ArgumentParser.add_argument``.48 """49 return self.argparser.add_argument(*args, **kwargs)50 def add_testenv_attribute(self, name, type, help, default=None, postprocess=None):51 """ add an ini-file variable for "testenv" section.52 Types are specified as strings like "bool", "line-list", "string", "argv", "path",53 "argvlist".54 The ``postprocess`` function will be called for each testenv55 like ``postprocess(testenv_config=testenv_config, value=value)``56 where ``value`` is the value as read from the ini (or the default value)57 and ``testenv_config`` is a :py:class:`tox.config.TestenvConfig` instance58 which will receive all ini-variables as object attributes.59 Any postprocess function must return a value which will then be set60 as the final value in the testenv section.61 """62 self._testenv_attr.append(VenvAttribute(name, type, default, help, postprocess))63 def add_testenv_attribute_obj(self, obj):64 """ add an ini-file variable as an object.65 This works as the ``add_testenv_attribute`` function but expects66 "name", "type", "help", and "postprocess" attributes on the object.67 """68 assert hasattr(obj, "name")69 assert hasattr(obj, "type")70 assert hasattr(obj, "help")71 assert hasattr(obj, "postprocess")72 self._testenv_attr.append(obj)73 def _parse_args(self, args):74 return self.argparser.parse_args(args)75 def _format_help(self):76 return self.argparser.format_help()77class VenvAttribute:78 def __init__(self, name, type, default, help, postprocess):79 self.name = name80 self.type = type81 self.default = default82 self.help = help83 self.postprocess = postprocess84class DepOption:85 name = "deps"86 type = "line-list"87 help = "each line specifies a dependency in pip/setuptools format."88 default = ()89 def postprocess(self, testenv_config, value):90 deps = []91 config = testenv_config.config92 for depline in value:93 m = re.match(r":(\w+):\s*(\S+)", depline)94 if m:95 iname, name = m.groups()96 ixserver = config.indexserver[iname]97 else:98 name = depline.strip()99 ixserver = None100 name = self._replace_forced_dep(name, config)101 deps.append(DepConfig(name, ixserver))102 return deps103 def _replace_forced_dep(self, name, config):104 """105 Override the given dependency config name taking --force-dep-version106 option into account.107 :param name: dep config, for example ["pkg==1.0", "other==2.0"].108 :param config: Config instance109 :return: the new dependency that should be used for virtual environments110 """111 if not config.option.force_dep:112 return name113 for forced_dep in config.option.force_dep:114 if self._is_same_dep(forced_dep, name):115 return forced_dep116 return name117 @classmethod118 def _is_same_dep(cls, dep1, dep2):119 """120 Returns True if both dependency definitions refer to the121 same package, even if versions differ.122 """123 dep1_name = pkg_resources.Requirement.parse(dep1).project_name124 try:125 dep2_name = pkg_resources.Requirement.parse(dep2).project_name126 except pkg_resources.RequirementParseError:127 # we couldn't parse a version, probably a URL128 return False129 return dep1_name == dep2_name130class PosargsOption:131 name = "args_are_paths"132 type = "bool"133 default = True134 help = "treat positional args in commands as paths"135 def postprocess(self, testenv_config, value):136 config = testenv_config.config137 args = config.option.args138 if args:139 if value:140 args = []141 for arg in config.option.args:142 if arg:143 origpath = config.invocationcwd.join(arg, abs=True)144 if origpath.check():145 arg = testenv_config.changedir.bestrelpath(origpath)146 args.append(arg)147 testenv_config._reader.addsubstitutions(args)148 return value149class InstallcmdOption:150 name = "install_command"151 type = "argv"152 default = "pip install {opts} {packages}"153 help = "install command for dependencies and package under test."154 def postprocess(self, testenv_config, value):155 if '{packages}' not in value:156 raise tox.exception.ConfigError(157 "'install_command' must contain '{packages}' substitution")158 return value159def parseconfig(args=None, plugins=()):160 """161 :param list[str] args: Optional list of arguments.162 :type pkg: str163 :rtype: :class:`Config`164 :raise SystemExit: toxinit file is not found165 """166 pm = get_plugin_manager(plugins)167 if args is None:168 args = sys.argv[1:]169 # prepare command line options170 parser = Parser()171 pm.hook.tox_addoption(parser=parser)172 # parse command line options173 option = parser._parse_args(args)174 interpreters = tox.interpreters.Interpreters(hook=pm.hook)175 config = Config(pluginmanager=pm, option=option, interpreters=interpreters)176 config._parser = parser177 config._testenv_attr = parser._testenv_attr178 # parse ini file179 basename = config.option.configfile180 if os.path.isfile(basename):181 inipath = py.path.local(basename)182 elif os.path.isdir(basename):183 # Assume 'tox.ini' filename if directory was passed184 inipath = py.path.local(os.path.join(basename, 'tox.ini'))185 else:186 for path in py.path.local().parts(reverse=True):187 inipath = path.join(basename)188 if inipath.check():189 break190 else:191 inipath = py.path.local().join('setup.cfg')192 if not inipath.check():193 helpoptions = option.help or option.helpini194 feedback("toxini file %r not found" % (basename),195 sysexit=not helpoptions)196 if helpoptions:197 return config198 try:199 parseini(config, inipath)200 except tox.exception.InterpreterNotFound:201 exn = sys.exc_info()[1]202 # Use stdout to match test expectations203 py.builtin.print_("ERROR: " + str(exn))204 # post process config object205 pm.hook.tox_configure(config=config)206 return config207def feedback(msg, sysexit=False):208 py.builtin.print_("ERROR: " + msg, file=sys.stderr)209 if sysexit:210 raise SystemExit(1)211class VersionAction(argparse.Action):212 def __call__(self, argparser, *args, **kwargs):213 version = tox.__version__214 py.builtin.print_("%s imported from %s" % (version, tox.__file__))215 raise SystemExit(0)216class SetenvDict:217 def __init__(self, dict, reader):218 self.reader = reader219 self.definitions = dict220 self.resolved = {}221 self._lookupstack = []222 def __contains__(self, name):223 return name in self.definitions224 def get(self, name, default=None):225 try:226 return self.resolved[name]227 except KeyError:228 try:229 if name in self._lookupstack:230 raise KeyError(name)231 val = self.definitions[name]232 except KeyError:233 return os.environ.get(name, default)234 self._lookupstack.append(name)235 try:236 self.resolved[name] = res = self.reader._replace(val)237 finally:238 self._lookupstack.pop()239 return res240 def __getitem__(self, name):241 x = self.get(name, _dummy)242 if x is _dummy:243 raise KeyError(name)244 return x245 def keys(self):246 return self.definitions.keys()247 def __setitem__(self, name, value):248 self.definitions[name] = value249 self.resolved[name] = value250@hookimpl251def tox_addoption(parser):252 # formatter_class=argparse.ArgumentDefaultsHelpFormatter)253 parser.add_argument("--version", nargs=0, action=VersionAction,254 dest="version",255 help="report version information to stdout.")256 parser.add_argument("-h", "--help", action="store_true", dest="help",257 help="show help about options")258 parser.add_argument("--help-ini", "--hi", action="store_true", dest="helpini",259 help="show help about ini-names")260 parser.add_argument("-v", action='count', dest="verbosity", default=0,261 help="increase verbosity of reporting output. -vv mode turns off "262 "output redirection for package installation")263 parser.add_argument("--showconfig", action="store_true",264 help="show configuration information for all environments. ")265 parser.add_argument("-l", "--listenvs", action="store_true",266 dest="listenvs", help="show list of test environments "267 "(with description if verbose)")268 parser.add_argument("-a", "--listenvs-all", action="store_true",269 dest="listenvs_all",270 help="show list of all defined environments"271 "(with description if verbose)")272 parser.add_argument("-c", action="store", default="tox.ini",273 dest="configfile",274 help="config file name or directory with 'tox.ini' file.")275 parser.add_argument("-e", action="append", dest="env",276 metavar="envlist",277 help="work against specified environments (ALL selects all).")278 parser.add_argument("--notest", action="store_true", dest="notest",279 help="skip invoking test commands.")280 parser.add_argument("--sdistonly", action="store_true", dest="sdistonly",281 help="only perform the sdist packaging activity.")282 parser.add_argument("--installpkg", action="store", default=None,283 metavar="PATH",284 help="use specified package for installation into venv, instead of "285 "creating an sdist.")286 parser.add_argument("--develop", action="store_true", dest="develop",287 help="install package in the venv using 'setup.py develop' via "288 "'pip -e .'")289 parser.add_argument('-i', action="append",290 dest="indexurl", metavar="URL",291 help="set indexserver url (if URL is of form name=url set the "292 "url for the 'name' indexserver, specifically)")293 parser.add_argument("--pre", action="store_true", dest="pre",294 help="install pre-releases and development versions of dependencies. "295 "This will pass the --pre option to install_command "296 "(pip by default).")297 parser.add_argument("-r", "--recreate", action="store_true",298 dest="recreate",299 help="force recreation of virtual environments")300 parser.add_argument("--result-json", action="store",301 dest="resultjson", metavar="PATH",302 help="write a json file with detailed information "303 "about all commands and results involved.")304 # We choose 1 to 4294967295 because it is the range of PYTHONHASHSEED.305 parser.add_argument("--hashseed", action="store",306 metavar="SEED", default=None,307 help="set PYTHONHASHSEED to SEED before running commands. "308 "Defaults to a random integer in the range [1, 4294967295] "309 "([1, 1024] on Windows). "310 "Passing 'noset' suppresses this behavior.")311 parser.add_argument("--force-dep", action="append",312 metavar="REQ", default=None,313 help="Forces a certain version of one of the dependencies "314 "when configuring the virtual environment. REQ Examples "315 "'pytest<2.7' or 'django>=1.6'.")316 parser.add_argument("--sitepackages", action="store_true",317 help="override sitepackages setting to True in all envs")318 parser.add_argument("--alwayscopy", action="store_true",319 help="override alwayscopy setting to True in all envs")320 parser.add_argument("--skip-missing-interpreters", action="store_true",321 help="don't fail tests for missing interpreters")322 parser.add_argument("--workdir", action="store",323 dest="workdir", metavar="PATH", default=None,324 help="tox working directory")325 parser.add_argument("args", nargs="*",326 help="additional arguments available to command positional substitution")327 parser.add_testenv_attribute(328 name="envdir", type="path", default="{toxworkdir}/{envname}",329 help="set venv directory -- be very careful when changing this as tox "330 "will remove this directory when recreating an environment")331 # add various core venv interpreter attributes332 def setenv(testenv_config, value):333 setenv = value334 config = testenv_config.config335 if "PYTHONHASHSEED" not in setenv and config.hashseed is not None:336 setenv['PYTHONHASHSEED'] = config.hashseed337 return setenv338 parser.add_testenv_attribute(339 name="setenv", type="dict_setenv", postprocess=setenv,340 help="list of X=Y lines with environment variable settings")341 def basepython_default(testenv_config, value):342 if value is None:343 for f in testenv_config.factors:344 if f in default_factors:345 return default_factors[f]346 return sys.executable347 return str(value)348 parser.add_testenv_attribute(349 name="basepython", type="string", default=None, postprocess=basepython_default,350 help="executable name or path of interpreter used to create a "351 "virtual test environment.")352 def merge_description(testenv_config, value):353 """the reader by default joins generated description with new line,354 replace new line with space"""355 return value.replace('\n', ' ')356 parser.add_testenv_attribute(357 name="description", type="string", default='', postprocess=merge_description,358 help="short description of this environment")359 parser.add_testenv_attribute(360 name="envtmpdir", type="path", default="{envdir}/tmp",361 help="venv temporary directory")362 parser.add_testenv_attribute(363 name="envlogdir", type="path", default="{envdir}/log",364 help="venv log directory")365 parser.add_testenv_attribute(366 name="downloadcache", type="string", default=None,367 help="(ignored) has no effect anymore, pip-8 uses local caching by default")368 parser.add_testenv_attribute(369 name="changedir", type="path", default="{toxinidir}",370 help="directory to change to when running commands")371 parser.add_testenv_attribute_obj(PosargsOption())372 parser.add_testenv_attribute(373 name="skip_install", type="bool", default=False,374 help="Do not install the current package. This can be used when "375 "you need the virtualenv management but do not want to install "376 "the current package")377 parser.add_testenv_attribute(378 name="ignore_errors", type="bool", default=False,379 help="if set to True all commands will be executed irrespective of their "380 "result error status.")381 def recreate(testenv_config, value):382 if testenv_config.config.option.recreate:383 return True384 return value385 parser.add_testenv_attribute(386 name="recreate", type="bool", default=False, postprocess=recreate,387 help="always recreate this test environment.")388 def passenv(testenv_config, value):389 # Flatten the list to deal with space-separated values.390 value = list(391 itertools.chain.from_iterable(392 [x.split(' ') for x in value]))393 passenv = set([394 "PATH", "PIP_INDEX_URL", "LANG", "LANGUAGE", "LD_LIBRARY_PATH"395 ])396 # read in global passenv settings397 p = os.environ.get("TOX_TESTENV_PASSENV", None)398 if p is not None:399 env_values = [x for x in p.split() if x]400 value.extend(env_values)401 # we ensure that tmp directory settings are passed on402 # we could also set it to the per-venv "envtmpdir"403 # but this leads to very long paths when run with jenkins404 # so we just pass it on by default for now.405 if sys.platform == "win32":406 passenv.add("SYSTEMDRIVE") # needed for pip6407 passenv.add("SYSTEMROOT") # needed for python's crypto module408 passenv.add("PATHEXT") # needed for discovering executables409 passenv.add("COMSPEC") # needed for distutils cygwincompiler410 passenv.add("TEMP")411 passenv.add("TMP")412 else:413 passenv.add("TMPDIR")414 for spec in value:415 for name in os.environ:416 if fnmatchcase(name.upper(), spec.upper()):417 passenv.add(name)418 return passenv419 parser.add_testenv_attribute(420 name="passenv", type="line-list", postprocess=passenv,421 help="environment variables needed during executing test commands "422 "(taken from invocation environment). Note that tox always "423 "passes through some basic environment variables which are "424 "needed for basic functioning of the Python system. "425 "See --showconfig for the eventual passenv setting.")426 parser.add_testenv_attribute(427 name="whitelist_externals", type="line-list",428 help="each lines specifies a path or basename for which tox will not warn "429 "about it coming from outside the test environment.")430 parser.add_testenv_attribute(431 name="platform", type="string", default=".*",432 help="regular expression which must match against ``sys.platform``. "433 "otherwise testenv will be skipped.")434 def sitepackages(testenv_config, value):435 return testenv_config.config.option.sitepackages or value436 def alwayscopy(testenv_config, value):437 return testenv_config.config.option.alwayscopy or value438 parser.add_testenv_attribute(439 name="sitepackages", type="bool", default=False, postprocess=sitepackages,440 help="Set to ``True`` if you want to create virtual environments that also "441 "have access to globally installed packages.")442 parser.add_testenv_attribute(443 name="alwayscopy", type="bool", default=False, postprocess=alwayscopy,444 help="Set to ``True`` if you want virtualenv to always copy files rather "445 "than symlinking.")446 def pip_pre(testenv_config, value):447 return testenv_config.config.option.pre or value448 parser.add_testenv_attribute(449 name="pip_pre", type="bool", default=False, postprocess=pip_pre,450 help="If ``True``, adds ``--pre`` to the ``opts`` passed to "451 "the install command. ")452 def develop(testenv_config, value):453 option = testenv_config.config.option454 return not option.installpkg and (value or option.develop)455 parser.add_testenv_attribute(456 name="usedevelop", type="bool", postprocess=develop, default=False,457 help="install package in develop/editable mode")458 parser.add_testenv_attribute_obj(InstallcmdOption())459 parser.add_testenv_attribute(460 name="list_dependencies_command",461 type="argv",462 default="pip freeze",463 help="list dependencies for a virtual environment")464 parser.add_testenv_attribute_obj(DepOption())465 parser.add_testenv_attribute(466 name="commands", type="argvlist", default="",467 help="each line specifies a test command and can use substitution.")468 parser.add_testenv_attribute(469 "ignore_outcome", type="bool", default=False,470 help="if set to True a failing result of this testenv will not make "471 "tox fail, only a warning will be produced")472 parser.add_testenv_attribute(473 "extras", type="line-list",474 help="list of extras to install with the source distribution or "475 "develop install")476class Config(object):477 """ Global Tox config object. """478 def __init__(self, pluginmanager, option, interpreters):479 #: dictionary containing envname to envconfig mappings480 self.envconfigs = {}481 self.invocationcwd = py.path.local()482 self.interpreters = interpreters483 self.pluginmanager = pluginmanager484 #: option namespace containing all parsed command line options485 self.option = option486 @property...

Full Screen

Full Screen

Automation Testing Tutorials

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.

LambdaTest Learning Hubs:

YouTube

You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.

Run tox automation tests on LambdaTest cloud grid

Perform automation testing on 3000+ real desktop and mobile devices online.

Try LambdaTest Now !!

Get 100 minutes of automation test minutes FREE!!

Next-Gen App & Browser Testing Cloud

Was this article helpful?

Helpful

NotHelpful