From c1e99112eede07f6f95d482f9eef388ea1ba459b Mon Sep 17 00:00:00 2001 From: Dan Ring Date: Thu, 17 Dec 2015 15:44:22 -0500 Subject: Add --workdir to override the 'toxworkdir' config option --- tox/config.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/tox/config.py b/tox/config.py index 079dff3..e071805 100644 --- a/tox/config.py +++ b/tox/config.py @@ -366,6 +366,9 @@ def tox_addoption(parser): help="override sitepackages setting to True in all envs") parser.add_argument("--skip-missing-interpreters", action="store_true", help="don't fail tests for missing interpreters") + parser.add_argument("--workdir", action="store", + dest="workdir", metavar="PATH", default=None, + help="tox working directory") parser.add_argument("args", nargs="*", help="additional arguments available to command positional substitution") @@ -664,7 +667,10 @@ class parseini: reader.addsubstitutions(toxinidir=config.toxinidir, homedir=config.homedir) - config.toxworkdir = reader.getpath("toxworkdir", "{toxinidir}/.tox") + if config.option.workdir is None: + config.toxworkdir = reader.getpath("toxworkdir", "{toxinidir}/.tox") + else: + config.toxworkdir = config.toxinidir.join(config.option.workdir, abs=True) config.minversion = reader.getstring("minversion", None) if not config.option.skip_missing_interpreters: -- cgit v1.2.1 From f3e6f8cda37e6fcb87992638ad52ef83eeaafa08 Mon Sep 17 00:00:00 2001 From: Dan Ring Date: Thu, 17 Dec 2015 15:44:52 -0500 Subject: Add test for --workdir command line option --- tests/test_config.py | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/tests/test_config.py b/tests/test_config.py index 6176641..5ce99f4 100644 --- a/tests/test_config.py +++ b/tests/test_config.py @@ -1837,6 +1837,23 @@ class TestCmdInvocation: "*ERROR*tox.ini*not*found*", ]) + def test_override_workdir(self, tmpdir, cmd, initproj): + baddir = "badworkdir-123" + gooddir = "overridden-234" + initproj("overrideworkdir-0.5", filedefs={ + 'tox.ini': ''' + [tox] + toxworkdir=%s + ''' % baddir, + }) + result = cmd.run("tox", "--workdir", gooddir, "--showconfig") + assert not result.ret + stdout = result.stdout.str() + assert gooddir in stdout + assert baddir not in stdout + assert py.path.local(gooddir).check() + assert not py.path.local(baddir).check() + def test_showconfig_with_force_dep_version(self, cmd, initproj): initproj('force_dep_version', filedefs={ 'tox.ini': ''' -- cgit v1.2.1 From b9e5e7fe4f721a1705b02fc16e891a451ac298a2 Mon Sep 17 00:00:00 2001 From: Piet Delport Date: Mon, 4 Jan 2016 15:58:50 +0200 Subject: Mark guarded "unicode" reference with noqa --- tox/_quickstart.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tox/_quickstart.py b/tox/_quickstart.py index a397cb1..59ee48e 100644 --- a/tox/_quickstart.py +++ b/tox/_quickstart.py @@ -119,7 +119,7 @@ def do_prompt(d, key, text, default=None, validator=nonempty): x = term_input(prompt) if default and not x: x = default - if sys.version_info < (3, ) and not isinstance(x, unicode): + if sys.version_info < (3, ) and not isinstance(x, unicode): # noqa # for Python 2.x, try to get a Unicode string out of it if x.decode('ascii', 'replace').encode('ascii', 'replace') != x: if TERM_ENCODING: -- cgit v1.2.1 From b5ded7a6bc0e7407c08813faa95b66a624d60f52 Mon Sep 17 00:00:00 2001 From: Piet Delport Date: Mon, 4 Jan 2016 16:09:18 +0200 Subject: Remove separating spaces in "print (...)" (pep8 E211) --- doc/_getdoctarget.py | 2 +- tests/test_interpreters.py | 2 +- tox/_pytestplugin.py | 6 +++--- tox/interpreters.py | 6 +++--- tox/result.py | 6 +++--- 5 files changed, 11 insertions(+), 11 deletions(-) diff --git a/doc/_getdoctarget.py b/doc/_getdoctarget.py index 1199221..f92e87b 100755 --- a/doc/_getdoctarget.py +++ b/doc/_getdoctarget.py @@ -13,4 +13,4 @@ def get_minor_version_string(): return ".".join(get_version_string().split(".")[:2]) if __name__ == "__main__": - print (get_minor_version_string()) + print(get_minor_version_string()) diff --git a/tests/test_interpreters.py b/tests/test_interpreters.py index d2cfa27..c658380 100644 --- a/tests/test_interpreters.py +++ b/tests/test_interpreters.py @@ -41,7 +41,7 @@ def test_tox_get_python_executable(): if sys.platform == "win32": pydir = "python%s" % ver.replace(".", "") x = py.path.local("c:\%s" % pydir) - print (x) + print(x) if not x.check(): continue else: diff --git a/tox/_pytestplugin.py b/tox/_pytestplugin.py index f15d2ec..b7693fc 100644 --- a/tox/_pytestplugin.py +++ b/tox/_pytestplugin.py @@ -68,12 +68,12 @@ class ReportExpectMock: def generic_report(*args, **kwargs): self._calls.append((name,) + args) - print ("%s" % (self._calls[-1], )) + print("%s" % (self._calls[-1], )) return generic_report def action(self, venv, msg, *args): self._calls.append(("action", venv, msg)) - print ("%s" % (self._calls[-1], )) + print("%s" % (self._calls[-1], )) return Action(self.session, venv, msg, args) def getnext(self, cat): @@ -316,7 +316,7 @@ def initproj(request, tmpdir): for p in base.visit(lambda x: x.check(file=1)): manifestlines.append("include %s" % p.relto(base)) create_files(base, {"MANIFEST.in": "\n".join(manifestlines)}) - print ("created project in %s" % (base,)) + print("created project in %s" % (base,)) base.chdir() return initproj diff --git a/tox/interpreters.py b/tox/interpreters.py index 66e6409..e049f1d 100644 --- a/tox/interpreters.py +++ b/tox/interpreters.py @@ -43,10 +43,10 @@ class Interpreters: try: res = exec_on_interpreter(info.executable, [inspect.getsource(sitepackagesdir), - "print (sitepackagesdir(%r))" % envdir]) + "print(sitepackagesdir(%r))" % envdir]) except ExecFailed: val = sys.exc_info()[1] - print ("execution failed: %s -- %s" % (val.out, val.err)) + print("execution failed: %s -- %s" % (val.out, val.err)) return "" else: return res["dir"] @@ -56,7 +56,7 @@ def run_and_get_interpreter_info(name, executable): assert executable try: result = exec_on_interpreter(executable, - [inspect.getsource(pyinfo), "print (pyinfo())"]) + [inspect.getsource(pyinfo), "print(pyinfo())"]) except ExecFailed: val = sys.exc_info()[1] return NoInterpreterInfo(name, executable=val.executable, diff --git a/tox/result.py b/tox/result.py index 96ac612..bad8cc3 100644 --- a/tox/result.py +++ b/tox/result.py @@ -47,9 +47,9 @@ class EnvLog: pythonexecutable = py.path.local(pythonexecutable) out = pythonexecutable.sysexec("-c", "import sys; " - "print (sys.executable);" - "print (list(sys.version_info)); " - "print (sys.version)") + "print(sys.executable);" + "print(list(sys.version_info)); " + "print(sys.version)") lines = out.splitlines() executable = lines.pop(0) version_info = eval(lines.pop(0)) -- cgit v1.2.1 From fc35dcd7521317f04f491f8135faea75f433e896 Mon Sep 17 00:00:00 2001 From: Nyiro Gergo Date: Thu, 14 Jan 2016 11:25:11 +0100 Subject: session.Reporter: delete _starttime at exit The __enter__ of with statement extend the action object with _starttime and assert if it had been already extended. Therefore the __exit__ should remove the extra attribute of the action. --- tox/session.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tox/session.py b/tox/session.py index ffb52d6..f97b365 100644 --- a/tox/session.py +++ b/tox/session.py @@ -252,6 +252,7 @@ class Reporter(object): # self.cumulated_time += duration self.verbosity2("%s finish: %s after %.2f seconds" % ( action.venvname, action.msg, duration), bold=True) + delattr(action, '_starttime') def startsummary(self): self.tw.sep("_", "summary") -- cgit v1.2.1 From 26370885293487883eb60cbedcff76a0c6dc938e Mon Sep 17 00:00:00 2001 From: Sachi King Date: Mon, 29 Feb 2016 15:45:11 +1100 Subject: Process minversion before all else Reading the tox.ini config file and processing it is done as one task, yet processing the minversion is done much later, as such if there is a bug fix in a newer version or a change that makes the tox.ini file incompatable with older versions tox will bail with a stack trace instead of a "Your tox is too old" message. This moves the version check as early as it can possibly be done, the very first value read out of tox.ini is minversion and it is immedeiatly compared to tox.__version__. --- tests/test_config.py | 4 ++-- tox/__init__.py | 6 ++++++ tox/config.py | 13 ++++++++++++- tox/session.py | 28 +++++++++++++++------------- 4 files changed, 35 insertions(+), 16 deletions(-) diff --git a/tests/test_config.py b/tests/test_config.py index 372cd4f..c54add9 100644 --- a/tests/test_config.py +++ b/tests/test_config.py @@ -1426,8 +1426,8 @@ class TestGlobalOptions: [tox] minversion = 3.0 """ - config = newconfig([], inisource) - assert config.minversion == "3.0" + with py.test.raises(tox.exception.MinVersionError): + config = newconfig([], inisource) def test_skip_missing_interpreters_true(self, tmpdir, newconfig, monkeypatch): inisource = """ diff --git a/tox/__init__.py b/tox/__init__.py index c17341d..6991c90 100644 --- a/tox/__init__.py +++ b/tox/__init__.py @@ -23,5 +23,11 @@ class exception: """ a directory did not exist. """ class MissingDependency(Error): """ a dependency could not be found or determined. """ + class MinVersionError(Error): + """ the installed tox version is lower than requested minversion. """ + + def __init__(self, message): + self.message = message + super(exception.MinVersionError, self).__init__(message) from tox.session import main as cmdline # noqa diff --git a/tox/config.py b/tox/config.py index 67454bc..78d070a 100644 --- a/tox/config.py +++ b/tox/config.py @@ -12,6 +12,7 @@ import pluggy import tox.interpreters from tox import hookspecs +from tox._verlib import NormalizedVersion import py @@ -664,8 +665,18 @@ class parseini: reader.addsubstitutions(toxinidir=config.toxinidir, homedir=config.homedir) - config.toxworkdir = reader.getpath("toxworkdir", "{toxinidir}/.tox") + # As older versions of tox may have bugs or incompatabilities that + # prevent parsing of tox.ini this must be the first thing checked. config.minversion = reader.getstring("minversion", None) + # Parse our compatability immediately + if config.minversion: + minversion = NormalizedVersion(self.config.minversion) + toxversion = NormalizedVersion(tox.__version__) + if toxversion < minversion: + raise tox.exception.MinVersionError( + "tox version is %s, required is at least %s" % ( + toxversion, minversion)) + config.toxworkdir = reader.getpath("toxworkdir", "{toxinidir}/.tox") if not config.option.skip_missing_interpreters: config.option.skip_missing_interpreters = \ diff --git a/tox/session.py b/tox/session.py index 93ef5d8..2ff4182 100644 --- a/tox/session.py +++ b/tox/session.py @@ -40,6 +40,10 @@ def main(args=None): raise SystemExit(retcode) except KeyboardInterrupt: raise SystemExit(2) + except tox.exception.MinVersionError as e: + r = Reporter(None) + r.error(e.message) + raise SystemExit(1) def show_help(config): @@ -233,6 +237,12 @@ class Reporter(object): self._reportedlines = [] # self.cumulated_time = 0.0 + def _get_verbosity(self): + if self.session: + return self.session.config.option.verbosity + else: + return 2 + def logpopen(self, popen, env): """ log information about the action.popen() created process. """ cmd = " ".join(map(str, popen.args)) @@ -257,11 +267,11 @@ class Reporter(object): self.tw.sep("_", "summary") def info(self, msg): - if self.session.config.option.verbosity >= 2: + if self._get_verbosity() >= 2: self.logline(msg) def using(self, msg): - if self.session.config.option.verbosity >= 1: + if self._get_verbosity() >= 1: self.logline("using %s" % (msg,), bold=True) def keyboard_interrupt(self): @@ -297,15 +307,15 @@ class Reporter(object): self.tw.line("%s" % msg, **opts) def verbosity0(self, msg, **opts): - if self.session.config.option.verbosity >= 0: + if self._get_verbosity() >= 0: self.logline("%s" % msg, **opts) def verbosity1(self, msg, **opts): - if self.session.config.option.verbosity >= 1: + if self._get_verbosity() >= 1: self.logline("%s" % msg, **opts) def verbosity2(self, msg, **opts): - if self.session.config.option.verbosity >= 2: + if self._get_verbosity() >= 2: self.logline("%s" % msg, **opts) # def log(self, msg): @@ -359,14 +369,6 @@ class Session: def runcommand(self): self.report.using("tox-%s from %s" % (tox.__version__, tox.__file__)) - if self.config.minversion: - minversion = NormalizedVersion(self.config.minversion) - toxversion = NormalizedVersion(tox.__version__) - if toxversion < minversion: - self.report.error( - "tox version is %s, required is at least %s" % ( - toxversion, minversion)) - raise SystemExit(1) if self.config.option.showconfig: self.showconfig() elif self.config.option.listenvs: -- cgit v1.2.1 From 453ecceeca7221a11c9fa8acf58095d5a729968c Mon Sep 17 00:00:00 2001 From: Dougal Matthews Date: Wed, 9 Mar 2016 13:58:01 +0000 Subject: Correct --force-deps to be --force-dep in the CHANGELOG. --- CHANGELOG | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 81a5803..c92527a 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -63,7 +63,7 @@ - fix issue99: the {env:...} substitution now properly uses environment settings from the ``setenv`` section. Thanks Itxaka Serrano. -- fix issue281: make --force-deps work when urls are present in +- fix issue281: make --force-dep work when urls are present in dependency configs. Thanks Glyph Lefkowitz for reporting. - fix issue174: add new ``ignore_outcome`` testenv attribute which @@ -182,7 +182,7 @@ 1.9.2 ----------- -- backout ability that --force-deps substitutes name/versions in +- backout ability that --force-dep substitutes name/versions in requirement files due to various issues. This fixes issue228, fixes issue230, fixes issue231 which popped up with 1.9.1. @@ -193,7 +193,7 @@ - use a file instead of a pipe for command output in "--result-json". Fixes some termination issues with python2.6. -- allow --force-deps to override dependencies in "-r" requirements +- allow --force-dep to override dependencies in "-r" requirements files. Thanks Sontek for the PR. - fix issue227: use "-m virtualenv" instead of "-mvirtualenv" to make -- cgit v1.2.1 From f580e1a594f220b974abe0a2de85339f479c0542 Mon Sep 17 00:00:00 2001 From: Walter Scheper Date: Thu, 10 Mar 2016 21:43:49 -0500 Subject: Support configuration through setup.cfg When the usual search for a config file fails, try loading setup.cfg with a section prefix of tox. Modeled on coverage's use of setup.cfg as an alternative config file. --- tests/test_config.py | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ tox/config.py | 23 ++++++++++++++++++----- 2 files changed, 67 insertions(+), 5 deletions(-) diff --git a/tests/test_config.py b/tests/test_config.py index 372cd4f..a7ddb12 100644 --- a/tests/test_config.py +++ b/tests/test_config.py @@ -632,6 +632,55 @@ class TestIniParser: py.test.raises(tox.exception.ConfigError, 'reader.getbool("key5")') +class TestIniParserPrefix: + def test_basic_section_access(self, tmpdir, newconfig): + config = newconfig(""" + [p:section] + key=value + """) + reader = SectionReader("section", config._cfg, prefix="p") + x = reader.getstring("key") + assert x == "value" + assert not reader.getstring("hello") + x = reader.getstring("hello", "world") + assert x == "world" + + def test_fallback_sections(self, tmpdir, newconfig): + config = newconfig(""" + [p:mydefault] + key2=value2 + [p:section] + key=value + """) + reader = SectionReader("section", config._cfg, prefix="p", + fallbacksections=['p:mydefault']) + x = reader.getstring("key2") + assert x == "value2" + x = reader.getstring("key3") + assert not x + x = reader.getstring("key3", "world") + assert x == "world" + + def test_value_matches_prefixed_section_substituion(self): + assert is_section_substitution("{[p:setup]commands}") + + def test_value_doesn_match_prefixed_section_substitution(self): + assert is_section_substitution("{[p: ]commands}") is None + assert is_section_substitution("{[p:setup]}") is None + assert is_section_substitution("{[p:setup] commands}") is None + + def test_other_section_substitution(self, newconfig): + config = newconfig(""" + [p:section] + key = rue + [p:testenv] + key = t{[p:section]key} + """) + reader = SectionReader("testenv", config._cfg, prefix="p") + x = reader.getstring("key") + assert x == "true" + + class TestConfigTestEnv: def test_commentchars_issue33(self, tmpdir, newconfig): config = newconfig(""" diff --git a/tox/config.py b/tox/config.py index 67454bc..aaca0ca 100644 --- a/tox/config.py +++ b/tox/config.py @@ -224,7 +224,10 @@ def parseconfig(args=None, plugins=()): if inipath.check(): break else: - feedback("toxini file %r not found" % (basename), sysexit=True) + inipath = py.path.local().join('setup.cfg') + if not inipath.check(): + feedback("toxini file %r not found" % (basename), sysexit=True) + try: parseini(config, inipath) except tox.exception.InterpreterNotFound: @@ -644,12 +647,18 @@ class parseini: self._cfg = py.iniconfig.IniConfig(config.toxinipath) config._cfg = self._cfg self.config = config + + if inipath.basename == 'setup.cfg': + prefix = 'tox' + else: + prefix = None ctxname = getcontextname() if ctxname == "jenkins": - reader = SectionReader("tox:jenkins", self._cfg, fallbacksections=['tox']) + reader = SectionReader("tox:jenkins", self._cfg, prefix=prefix, + fallbacksections=['tox']) distshare_default = "{toxworkdir}/distshare" elif not ctxname: - reader = SectionReader("tox", self._cfg) + reader = SectionReader("tox", self._cfg, prefix=prefix) distshare_default = "{homedir}/.tox/distshare" else: raise ValueError("invalid context") @@ -853,8 +862,12 @@ is_section_substitution = re.compile("{\[[^{}\s]+\]\S+?}").match class SectionReader: - def __init__(self, section_name, cfgparser, fallbacksections=None, factors=()): - self.section_name = section_name + def __init__(self, section_name, cfgparser, fallbacksections=None, + factors=(), prefix=None): + if prefix is None: + self.section_name = section_name + else: + self.section_name = "%s:%s" % (prefix, section_name) self._cfg = cfgparser self.fallbacksections = fallbacksections or [] self.factors = factors -- cgit v1.2.1 From fc73a70a79ec5f5ce8bdba70dd73bd61555ea277 Mon Sep 17 00:00:00 2001 From: Sachi King Date: Tue, 10 May 2016 13:16:44 +1000 Subject: Add test for issue #307 This adds a test to address the second example in issue #307, the first example is already addressed. Closes issue #307 --- tests/test_config.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/tests/test_config.py b/tests/test_config.py index 372cd4f..471e784 100644 --- a/tests/test_config.py +++ b/tests/test_config.py @@ -288,6 +288,20 @@ class TestIniParserAgainstCommandsKey: x = reader.getargvlist("commands") assert x == [['thing', 'argpos', 'arg2']] + def test_command_section_and_posargs_substitution(self, newconfig): + """Ensure subsitition from other section with posargs succeeds""" + config = newconfig(""" + [section] + key = thing arg1 + [testenv] + commands = + {[section]key} {posargs} endarg + """) + reader = SectionReader("testenv", config._cfg) + reader.addsubstitutions([r"argpos"]) + x = reader.getargvlist("commands") + assert x == [['thing', 'arg1', 'argpos', 'endarg']] + def test_command_env_substitution(self, newconfig): """Ensure referenced {env:key:default} values are substituted correctly.""" config = newconfig(""" -- cgit v1.2.1 From 1d9b5284bdc1d3a6f1cd67ef82e8b882299e5683 Mon Sep 17 00:00:00 2001 From: Peter Bittner Date: Tue, 14 Jun 2016 20:11:23 +0000 Subject: Remove invalid return value in tox.cmdline() example --- doc/example/basic.txt | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/doc/example/basic.txt b/doc/example/basic.txt index 64150f3..84fed34 100644 --- a/doc/example/basic.txt +++ b/doc/example/basic.txt @@ -260,8 +260,7 @@ a test run when ``python setup.py test`` is issued:: args = self.tox_args if args: args = shlex.split(self.tox_args) - errno = tox.cmdline(args=args) - sys.exit(errno) + tox.cmdline(args=args) setup( #..., -- cgit v1.2.1 From 23fb9dc068907bfcb4c5a4f40d31ab9c08258df4 Mon Sep 17 00:00:00 2001 From: Oliver Bestwalter Date: Mon, 20 Jun 2016 15:41:56 +0200 Subject: #317 raise minversion in test to avoid breakage on next major update --- tests/test_config.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_config.py b/tests/test_config.py index 59ab213..ffc8343 100644 --- a/tests/test_config.py +++ b/tests/test_config.py @@ -1438,7 +1438,7 @@ class TestGlobalOptions: def test_minversion(self, tmpdir, newconfig, monkeypatch): inisource = """ [tox] - minversion = 3.0 + minversion = 10.0 """ with py.test.raises(tox.exception.MinVersionError): config = newconfig([], inisource) -- cgit v1.2.1 From 7aa455aa8f8137c8987727d17c380ce1f4ec8990 Mon Sep 17 00:00:00 2001 From: Oliver Bestwalter Date: Mon, 20 Jun 2016 15:42:23 +0200 Subject: update CHANGELOG --- CHANGELOG | 88 ++++++++++++++++++++++++++++++++------------------------------- 1 file changed, 45 insertions(+), 43 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index c92527a..3ec0abd 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -6,6 +6,8 @@ - fix issue279: allow cross-section substitution when the value contains posargs. Thanks Sachi King for the PR. +- fix issue317: evaluate minversion before tox config is parsed completely. + Thanks Sachi King for the PR. 2.3.1 ----- @@ -20,8 +22,8 @@ devpi system for managing indexes for pip. - fix issue285: make setenv processing fully lazy to fix regressions - of tox-2.2.X and so that we can now have testenv attributes like - "basepython" depend on environment variables that are set in + of tox-2.2.X and so that we can now have testenv attributes like + "basepython" depend on environment variables that are set in a setenv section. Thanks Nelfin for some tests and initial work on a PR. @@ -34,11 +36,11 @@ - fix issue252: allow environment names with special characters. Thanks Julien Castets for initial PR and patience. -- introduce experimental tox_testenv_create(venv, action) and +- introduce experimental tox_testenv_create(venv, action) and tox_testenv_install_deps(venv, action) hooks to allow plugins to do additional work on creation or installing deps. These hooks are experimental mainly because of - the involved "venv" and session objects whose current public + the involved "venv" and session objects whose current public API is not fully guranteed. - internal: push some optional object creation into tests because @@ -57,7 +59,7 @@ because otherwise the python interpreter might not start up in certain configurations (redhat software collections). Thanks David Riddle. -- fix issue246: fix regression in config parsing by reordering +- fix issue246: fix regression in config parsing by reordering such that {envbindir} can be used again in tox.ini. Thanks Olli Walsh. - fix issue99: the {env:...} substitution now properly uses environment @@ -68,7 +70,7 @@ - fix issue174: add new ``ignore_outcome`` testenv attribute which can be set to True in which case it will produce a warning instead - of an error on a failed testenv command outcome. + of an error on a failed testenv command outcome. Thanks Rebecka Gulliksson for the PR. - fix issue280: properly skip missing interpreter if @@ -85,7 +87,7 @@ 2.1.0 ---------- -- fix issue258, fix issue248, fix issue253: for non-test commands +- fix issue258, fix issue248, fix issue253: for non-test commands (installation, venv creation) we pass in the full invocation environment. - remove experimental --set-home option which was hardly used and @@ -106,7 +108,7 @@ 2.0.2 ---------- -- fix issue247: tox now passes the LANG variable from the tox invocation +- fix issue247: tox now passes the LANG variable from the tox invocation environment to the test environment by default. - add SYSTEMDRIVE into default passenv on windows to allow pip6 to work. @@ -123,9 +125,9 @@ - (new) introduce environment variable isolation: tox now only passes the PATH and PIP_INDEX_URL variable from the tox - invocation environment to the test environment and on Windows + invocation environment to the test environment and on Windows also ``SYSTEMROOT``, ``PATHEXT``, ``TEMP`` and ``TMP`` whereas - on unix additionally ``TMPDIR`` is passed. If you need to pass + on unix additionally ``TMPDIR`` is passed. If you need to pass through further environment variables you can use the new ``passenv`` setting, a space-separated list of environment variable names. Each name can make use of fnmatch-style glob patterns. All environment @@ -136,9 +138,9 @@ their defaults. - (new) introduce a way to specify on which platform a testenvironment is to - execute: the new per-venv "platform" setting allows to specify + execute: the new per-venv "platform" setting allows to specify a regular expression which is matched against sys.platform. - If platform is set and doesn't match the platform spec in the test + If platform is set and doesn't match the platform spec in the test environment the test environment is ignored, no setup or tests are attempted. - (new) add per-venv "ignore_errors" setting, which defaults to False. @@ -169,7 +171,7 @@ See tox/hookspecs.py for the current hooks. - introduce parser.add_testenv_attribute() to register an ini-variable - for testenv sections. Can be used from plugins through the + for testenv sections. Can be used from plugins through the tox_add_option hook. - rename internal files -- tox offers no external API except for the @@ -208,7 +210,7 @@ dependencies. Use ``pip_pre = true`` in a testenv or the ``--pre`` command-line option to restore the previous behavior. -- fix issue199: fill resultlog structure ahead of virtualenv creation +- fix issue199: fill resultlog structure ahead of virtualenv creation - refine determination if we run from Jenkins, thanks Borge Lanes. @@ -266,7 +268,7 @@ - fix issue59: add a config variable ``skip-missing-interpreters`` as well as command line option ``--skip-missing-interpreters`` which won't fail the - build if Python interpreters listed in tox.ini are missing. Thanks + build if Python interpreters listed in tox.ini are missing. Thanks Alexandre Conrad for PR104. - fix issue164: better traceback info in case of failing test commands. @@ -284,29 +286,29 @@ - fix issue162: don't list python 2.5 as compatibiliy/supported - fix issue158 and fix issue155: windows/virtualenv properly works now: - call virtualenv through "python -m virtualenv" with the same + call virtualenv through "python -m virtualenv" with the same interpreter which invoked tox. Thanks Chris Withers, Ionel Maries Cristian. 1.7.0 --------- -- don't lookup "pip-script" anymore but rather just "pip" on windows - as this is a pip implementation detail and changed with pip-1.5. - It might mean that tox-1.7 is not able to install a different pip +- don't lookup "pip-script" anymore but rather just "pip" on windows + as this is a pip implementation detail and changed with pip-1.5. + It might mean that tox-1.7 is not able to install a different pip version into a virtualenv anymore. - drop Python2.5 compatibility because it became too hard due - to the setuptools-2.0 dropping support. tox now has no + to the setuptools-2.0 dropping support. tox now has no support for creating python2.5 based environments anymore and all internal special-handling has been removed. -- merged PR81: new option --force-dep which allows to +- merged PR81: new option --force-dep which allows to override tox.ini specified dependencies in setuptools-style. For example "--force-dep 'django<1.6'" will make sure - that any environment using "django" as a dependency will - get the latest 1.5 release. Thanks Bruno Oliveria for + that any environment using "django" as a dependency will + get the latest 1.5 release. Thanks Bruno Oliveria for the complete PR. - + - merged PR125: tox now sets "PYTHONHASHSEED" to a random value and offers a "--hashseed" option to repeat a test run with a specific seed. You can also use --hashsheed=noset to instruct tox to leave the value @@ -324,9 +326,9 @@ - fix issue130: you can now set install_command=easy_install {opts} {packages} and expect it to work for repeated tox runs (previously it only worked - when always recreating). Thanks jenisys for precise reporting. + when always recreating). Thanks jenisys for precise reporting. -- fix issue129: tox now uses Popen(..., universal_newlines=True) to force +- fix issue129: tox now uses Popen(..., universal_newlines=True) to force creation of unicode stdout/stderr streams. fixes a problem on specific platform configs when creating virtualenvs with Python3.3. Thanks Jorgen Schäfer or investigation and solution sketch. @@ -344,7 +346,7 @@ requiring networks - introduce --sitepackages to force sitepackages=True in all - environments. + environments. - fix issue105 -- don't depend on an existing HOME directory from tox tests. @@ -354,8 +356,8 @@ - fix issue119: {envsitepackagesdir} is now correctly computed and has a better test to prevent regression. -- fix issue116: make 1.6 introduced behaviour of changing to a - per-env HOME directory during install activities dependent +- fix issue116: make 1.6 introduced behaviour of changing to a + per-env HOME directory during install activities dependent on "--set-home" for now. Should re-establish the old behaviour when no option is given. @@ -365,9 +367,9 @@ - fix test runs on environments without a home directory (in this case we use toxinidir as the homedir) -- fix issue117: python2.5 fix: don't use ``--insecure`` option because +- fix issue117: python2.5 fix: don't use ``--insecure`` option because its very existence depends on presence of "ssl". If you - want to support python2.5/pip1.3.1 based test environments you need + want to support python2.5/pip1.3.1 based test environments you need to install ssl and/or use PIP_INSECURE=1 through ``setenv``. section. - fix issue102: change to {toxinidir} when installing dependencies. @@ -380,11 +382,11 @@ configure the installation command with options for dep/pkg install. Thanks Carl Meyer for the PR and docs. -- fix issue91: python2.5 support by vendoring the virtualenv-1.9.1 - script and forcing pip<1.4. Also the default [py25] environment +- fix issue91: python2.5 support by vendoring the virtualenv-1.9.1 + script and forcing pip<1.4. Also the default [py25] environment modifies the default installer_command (new config option) - to use pip without the "--pre" option which was introduced - with pip-1.4 and is now required if you want to install non-stable + to use pip without the "--pre" option which was introduced + with pip-1.4 and is now required if you want to install non-stable releases. (tox defaults to install with "--pre" everywhere). - during installation of dependencies HOME is now set to a pseudo @@ -421,7 +423,7 @@ - fix issue104: use setuptools by default, instead of distribute, now that setuptools has distribute merged. -- make sure test commands are searched first in the virtualenv +- make sure test commands are searched first in the virtualenv - re-fix issue2 - add whitelist_externals to be used in ``[testenv*]`` sections, allowing to avoid warnings for commands such as ``make``, @@ -432,12 +434,12 @@ - fix issue92 - fix {envsitepackagesdir} to actually work again -- show (test) command that is being executed, thanks +- show (test) command that is being executed, thanks Lukasz Balcerzak - re-license tox to MIT license -- depend on virtualenv-1.9.1 +- depend on virtualenv-1.9.1 - rename README.txt to README.rst to make bitbucket happier @@ -452,7 +454,7 @@ (thanks Lukasz Balcerzak) - fix downloadcache determination to work according to docs: Only - make pip use a download cache if PIP_DOWNLOAD_CACHE or a + make pip use a download cache if PIP_DOWNLOAD_CACHE or a downloadcache=PATH testenv setting is present. (The ENV setting takes precedence) @@ -476,7 +478,7 @@ - fix #48 - win32 detection of pypy and other interpreters that are on PATH (thanks Gustavo Picon) -- fix grouping of index servers, it is now done by name instead of +- fix grouping of index servers, it is now done by name instead of indexserver url, allowing to use it to separate dependencies into groups even if using the same default indexserver. @@ -512,7 +514,7 @@ which would formerly raise irritating errors because the ";" was considered a comment - tweak and improve reporting -- refactor reporting and virtualenv manipulation +- refactor reporting and virtualenv manipulation to be more accessible from 3rd party tools - support value substitution from other sections with the {[section]key} syntax @@ -527,8 +529,8 @@ 1.3 ----------------- -- fix: allow to specify wildcard filesystem paths when - specifying dependencies such that tox searches for +- fix: allow to specify wildcard filesystem paths when + specifying dependencies such that tox searches for the highest version - fix issue issue21: clear PIP_REQUIRES_VIRTUALENV which avoids -- cgit v1.2.1 From 6c44042ac2357850365c83e7f31be4d74dd2199f Mon Sep 17 00:00:00 2001 From: holger krekel Date: Mon, 20 Jun 2016 16:40:36 +0200 Subject: fix issue66 by introducing using default "python -m pip" and introducing list_dependencies_command. (Ted, Holger) --- CHANGELOG | 15 +++++++++++++++ doc/config.txt | 15 ++++++++++++++- setup.py | 2 +- tests/test_venv.py | 12 ++++++------ tox.ini | 7 +++++++ tox/__init__.py | 2 +- tox/_pytestplugin.py | 3 +++ tox/config.py | 9 ++++++++- tox/session.py | 5 +++-- 9 files changed, 58 insertions(+), 12 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 3ec0abd..3be2703 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,18 @@ +2.4.0 +----- + +- introduce per-venv list_dependencies_command which defaults + to "python -m pip freeze" to obtain the list of installed packages. + If you need to run python2.6 you need to configure it to + something like "pip freeze". Thanks Ted Shaw, Holger Krekel. + +- fix issue66, issue121: change install_command to use "python -m pip" + by default instead of "pip ..." directly which avoids long shebang + issues. If you need to run python2.6 you need to configure it to + something like "pip install {opts} {packages}". Thanks Ted Shaw, + Holger Krekel. + + 2.3.2 ----- diff --git a/doc/config.txt b/doc/config.txt index 205b22a..229f357 100644 --- a/doc/config.txt +++ b/doc/config.txt @@ -105,7 +105,20 @@ Complete list of settings that you can put into ``testenv*`` sections: **default**:: - pip install {opts} {packages} + python -m pip install {opts} {packages} + + +.. confval:: list_dependencies_command + + .. versionadded:: 2.4 + + the ``list_dependencies_command`` setting is used for listing + the packages installed into the virtual environment. + + **default**:: + + python -m pip freeze + .. confval:: ignore_errors=True|False(default) diff --git a/setup.py b/setup.py index 7662332..2cefdc8 100644 --- a/setup.py +++ b/setup.py @@ -48,7 +48,7 @@ def main(): description='virtualenv-based automation of test activities', long_description=open("README.rst").read(), url='http://tox.testrun.org/', - version='2.3.2', + version='2.4.0.dev1', license='http://opensource.org/licenses/MIT', platforms=['unix', 'linux', 'osx', 'cygwin', 'win32'], author='holger krekel', diff --git a/tests/test_venv.py b/tests/test_venv.py index 4ab3b06..30bdf3c 100644 --- a/tests/test_venv.py +++ b/tests/test_venv.py @@ -137,8 +137,8 @@ def test_install_deps_wildcard(newmocksession): assert len(l) == 2 args = l[-1].args assert l[-1].cwd == venv.envconfig.config.toxinidir - assert "pip" in str(args[0]) - assert args[1] == "install" + assert "pip" in str(args[2]) + assert args[3] == "install" # arg = "--download-cache=" + str(venv.envconfig.downloadcache) # assert arg in args[2:] args = [arg for arg in args if str(arg).endswith("dep1-1.1.zip")] @@ -167,8 +167,8 @@ def test_install_downloadcache(newmocksession, monkeypatch, tmpdir, envdc): assert len(l) == 2 args = l[-1].args assert l[-1].cwd == venv.envconfig.config.toxinidir - assert "pip" in str(args[0]) - assert args[1] == "install" + assert "pip" in str(args) + assert args[3] == "install" assert "dep1" in args assert "dep2" in args deps = list(filter(None, [x[1] for x in venv._getliveconfig().deps])) @@ -365,7 +365,7 @@ def test_install_python3(tmpdir, newmocksession): venv._install(["hello"], action=action) assert len(l) == 1 args = l[0].args - assert 'pip' in str(args[0]) + assert "pip" in [str(x) for x in args] for x in args: assert "--download-cache" not in args, args @@ -597,7 +597,7 @@ def test_run_install_command(newmocksession): venv.run_install_command(packages=["whatever"], action=action) l = mocksession._pcalls assert len(l) == 1 - assert 'pip' in l[0].args[0] + assert 'pip' in l[0].args[2] assert 'install' in l[0].args env = l[0].env assert env is not None diff --git a/tox.ini b/tox.ini index 17efc83..3dd30dc 100644 --- a/tox.ini +++ b/tox.ini @@ -13,6 +13,13 @@ deps=pytest>=2.3.5 [testenv:py26-bare] deps = commands = tox -h +install_command = pip install {opts} {packages} +list_dependencies_command = pip freeze + +[testenv:py26] +install_command = pip install {opts} {packages} +list_dependencies_command = pip freeze + [testenv:docs] basepython=python diff --git a/tox/__init__.py b/tox/__init__.py index 6991c90..baf651b 100644 --- a/tox/__init__.py +++ b/tox/__init__.py @@ -1,5 +1,5 @@ # -__version__ = '2.3.2' +__version__ = '2.4.0.dev1' from .hookspecs import hookspec, hookimpl # noqa diff --git a/tox/_pytestplugin.py b/tox/_pytestplugin.py index f15d2ec..d7bff0c 100644 --- a/tox/_pytestplugin.py +++ b/tox/_pytestplugin.py @@ -195,6 +195,9 @@ class Cmd: return py.std.subprocess.Popen(argv, stdout=stdout, stderr=stderr, **kw) def run(self, *argv): + if argv[0] == "tox" and sys.version_info[:2] < (2,7): + pytest.skip("can not run tests involving calling tox on python2.6. " + "(and python2.6 is about to be deprecated anyway)") argv = [str(x) for x in argv] assert py.path.local.sysfind(str(argv[0])), argv[0] p1 = self.tmpdir.join("stdout") diff --git a/tox/config.py b/tox/config.py index 78d070a..1fd702c 100644 --- a/tox/config.py +++ b/tox/config.py @@ -181,7 +181,7 @@ class PosargsOption: class InstallcmdOption: name = "install_command" type = "argv" - default = "pip install {opts} {packages}" + default = "python -m pip install {opts} {packages}" help = "install command for dependencies and package under test." def postprocess(self, testenv_config, value): @@ -518,6 +518,13 @@ def tox_addoption(parser): help="install package in develop/editable mode") parser.add_testenv_attribute_obj(InstallcmdOption()) + + parser.add_testenv_attribute( + name = "list_dependencies_command", + type = "argv", + default = "python -m pip freeze", + help = "list dependencies for a virtual environment") + parser.add_testenv_attribute_obj(DepOption()) parser.add_testenv_attribute( diff --git a/tox/session.py b/tox/session.py index 029b06b..1d51b92 100644 --- a/tox/session.py +++ b/tox/session.py @@ -537,8 +537,9 @@ class Session: # write out version dependency information action = self.newaction(venv, "envreport") with action: - pip = venv.getcommandpath("pip") - output = venv._pcall([str(pip), "freeze"], + python = venv.getcommandpath("python") + args = venv.envconfig.list_dependencies_command + output = venv._pcall(args, cwd=self.config.toxinidir, action=action) # the output contains a mime-header, skip it -- cgit v1.2.1 From 03dd843fba44bc2fad91da6f2f7bb828a98ab923 Mon Sep 17 00:00:00 2001 From: Oliver Bestwalter Date: Mon, 20 Jun 2016 17:18:50 +0200 Subject: make flakes pass --- tests/test_config.py | 2 +- tox.ini | 3 ++- tox/_pytestplugin.py | 2 +- tox/config.py | 8 ++++---- tox/session.py | 1 - 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/tests/test_config.py b/tests/test_config.py index ffc8343..82248d8 100644 --- a/tests/test_config.py +++ b/tests/test_config.py @@ -1441,7 +1441,7 @@ class TestGlobalOptions: minversion = 10.0 """ with py.test.raises(tox.exception.MinVersionError): - config = newconfig([], inisource) + newconfig([], inisource) def test_skip_missing_interpreters_true(self, tmpdir, newconfig, monkeypatch): inisource = """ diff --git a/tox.ini b/tox.ini index 3dd30dc..a2bbd96 100644 --- a/tox.ini +++ b/tox.ini @@ -34,7 +34,7 @@ platform=linux deps = pytest-flakes>=0.2 pytest-pep8 -commands = +commands = py.test --flakes -m flakes tox tests py.test --pep8 -m pep8 tox tests @@ -60,3 +60,4 @@ pep8maxlinelength = 99 # E731 - do not assign a lambda expression, use a def pep8ignore = *.py W503 E402 E731 +flakes-ignore = ImportStarUsage diff --git a/tox/_pytestplugin.py b/tox/_pytestplugin.py index 4dfc497..785070d 100644 --- a/tox/_pytestplugin.py +++ b/tox/_pytestplugin.py @@ -195,7 +195,7 @@ class Cmd: return py.std.subprocess.Popen(argv, stdout=stdout, stderr=stderr, **kw) def run(self, *argv): - if argv[0] == "tox" and sys.version_info[:2] < (2,7): + if argv[0] == "tox" and sys.version_info[:2] < (2, 7): pytest.skip("can not run tests involving calling tox on python2.6. " "(and python2.6 is about to be deprecated anyway)") argv = [str(x) for x in argv] diff --git a/tox/config.py b/tox/config.py index 1fd702c..f4c65dc 100644 --- a/tox/config.py +++ b/tox/config.py @@ -520,10 +520,10 @@ def tox_addoption(parser): parser.add_testenv_attribute_obj(InstallcmdOption()) parser.add_testenv_attribute( - name = "list_dependencies_command", - type = "argv", - default = "python -m pip freeze", - help = "list dependencies for a virtual environment") + name="list_dependencies_command", + type="argv", + default="python -m pip freeze", + help="list dependencies for a virtual environment") parser.add_testenv_attribute_obj(DepOption()) diff --git a/tox/session.py b/tox/session.py index 1d51b92..cb5cc66 100644 --- a/tox/session.py +++ b/tox/session.py @@ -537,7 +537,6 @@ class Session: # write out version dependency information action = self.newaction(venv, "envreport") with action: - python = venv.getcommandpath("python") args = venv.envconfig.list_dependencies_command output = venv._pcall(args, cwd=self.config.toxinidir, -- cgit v1.2.1 -- cgit v1.2.1